Skip to content

KoliStat/bedevere-wise

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

433 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@kolistat/bedevere-wise

Embeddable browser components for DuckDB-WASM-backed data exploration:

  • SpreadsheetVisualizer — canvas-rendered grid; virtually scrolled, HiDPI-sharp.
  • ColumnStatsVisualizer — per-column summary stats + value-filter UI.
  • ChartVisualizer — Vega-Lite renderer for stats_duck's VISUALIZE … DRAW output.
  • EmbedSqlEditor — slim CodeMirror SQL editor with Bedevere's PostgreSQL-extended dialect.
  • DuckDBService + DuckDBDataProvider — DuckDB-WASM runtime wrapper + bridge to the UI components.

These are the same components that compose the standalone web app at bedeverewise.app. Also consumed by tlf-studio for clinical-trial pipeline inspection.

Status: pre-1.0. Shipping on the @next dist-tag while the embedding API settles. Breaking changes are possible between 0.x minor versions (the CHANGELOG flags them). Pin to an exact version in production.

Install

bun add @kolistat/bedevere-wise@next

# Peer dependencies — install one shared copy of each in your tree:
bun add @duckdb/duckdb-wasm \
  @codemirror/autocomplete @codemirror/commands @codemirror/lang-sql \
  @codemirror/language @codemirror/search @codemirror/state \
  @codemirror/view @lezer/highlight codemirror \
  vega-embed

All peer deps are required if you import from the package's main entry today. See Bundler compatibility for the rationale and the WASM-free entry split (/ui, /app, /ipc).

Quick start

import {
  DuckDBService,
  DuckDBDataProvider,
  SpreadsheetVisualizer,
  ColumnStatsVisualizerFocusable,
} from "@kolistat/bedevere-wise";
import "@kolistat/bedevere-wise/style.css";

const duck = new DuckDBService();
await duck.initialize();

// Point DuckDB at a remote dataset; the host must serve permissive CORS.
await duck.registerFileURL("adsl.parquet", "https://example.org/adsl.parquet");
await duck.executeQuery(
  `CREATE OR REPLACE TABLE adsl AS SELECT * FROM read_parquet('adsl.parquet')`,
);

const provider = new DuckDBDataProvider(duck, "adsl", "adsl.parquet");

// One shared stats panel, mounted next to the spreadsheet:
const stats = new ColumnStatsVisualizerFocusable(
  document.querySelector("#stats")!,
  null,
);

const grid = new SpreadsheetVisualizer(
  document.querySelector("#grid")!,
  provider,
  { minHeight: 240, minWidth: 320 },
  stats,
  "my-app-grid",
);
await grid.initialize();

Embedding surface

The package ships two tiers of exports.

Embedding tier — recommended

Components in this tier accept their dependencies via constructor; no module-level singleton reach-through. Safe to mount inside any host app.

Export Purpose
DuckDBService DuckDB-WASM runtime wrapper. One instance per app.
DuckDBDataProvider Implements DataProvider over a DuckDB table.
DataProvider (interface) The per-dataset integration boundary. Implement your own to feed rows from anywhere — HTTP, IPC, a server.
Backend (interface) The SQL-engine boundary. Implement to point BedevereApp at a non-WASM engine (native IPC, remote relay). Optional exportTable(opts) writes a whole table to Parquet / JSON / SAS / SPSS — ExportFormat, ExportTableOptions, ExportResult, and EXPORT_FORMATS are exported for it.
SpreadsheetVisualizer Canvas-rendered spreadsheet.
ColumnStatsVisualizer / ColumnStatsVisualizerFocusable Column stats + filter panel; share one across many spreadsheets.
ChartVisualizer Renders Vega-Lite specs produced by stats_duck's VISUALIZE … DRAW.
EmbedSqlEditor Slim CodeMirror SQL editor with the Bedevere dialect + tokyonight palette.
Type helpers (isNumericType, normalizeDuckDBType, dataTypeCategory, …) For consumers writing custom DataProviders.

The UI components (SpreadsheetVisualizer, ColumnStatsVisualizer, ChartVisualizer, EmbedSqlEditor) have no hard dependency on DuckDB-WASM — they consume the DataProvider interface and Vega specs respectively. A consumer can ignore DuckDBService / DuckDBDataProvider entirely and supply their own DataProvider over an alternative backend (HTTP API, native IPC, an in-memory pipeline, …).

App-shell tier — @kolistat/bedevere-wise/app

The full standalone-app shell as composable pieces: BedevereApp, TabManager, ControlPanel, StatusBar, CommandBar, plus the PersistenceService singleton. BedevereApp is backend-agnostic — pass options.backend (there is no built-in default), so importing from /app pulls no DuckDB-WASM. Pair it with /duckdb for the in-browser engine, or hand it an IpcBackend / remote relay (this is exactly how bedevere-desktop drives the same UI against native DuckDB):

import { BedevereApp } from "@kolistat/bedevere-wise/app";
import { DuckDBService } from "@kolistat/bedevere-wise/duckdb";
import "@kolistat/bedevere-wise/style.css";

const backend = new DuckDBService();
await backend.initialize();
const app = new BedevereApp(document.getElementById("app")!, "1.0.0", { backend });
await app.initAsync();

These shells assume module-level singletons (CommandRegistry, EnvironmentService, KeymapService, PersistenceService) and expect one BedevereApp per page. If you only need a piece of the UI rather than the whole shell, prefer the component tier above.

Theming

The package ships four themes as CSS custom-property sets, selected by a single body class — exactly one is applied at a time:

Body class Theme
theme-dark GitHub-Dark — the default dark
theme-light Light (warm-neutral)
theme-classic-dark Tokyonight Storm
theme-classic-light Tokyonight Day

Override the tokens in your own stylesheet, after importing the package CSS (see dist/style.css for the full token list):

body.theme-dark {
  --bg: #1f1f1f;
  --fg: #e1e4e8;
  /* ... */
}

Switching the body class re-renders theme-sensitive canvas surfaces (the spreadsheet repaints; the chart re-embeds with a matching Vega palette). BedevereApp manages this class for you and exposes setTheme().

Bundler compatibility

The package is browser-only and currently Vite-friendly. DuckDB-WASM, which DuckDBService depends on, ships its worker scripts as separate JS files referenced via Vite's ?url import syntax. The compiled bundle (dist/index.es.js) preserves these ?url imports verbatim; resolving them is your bundler's job.

Bundler Status
Vite Works out of the box. This is the supported path.
webpack 5 Works with asset/resource rules for the worker URLs. See the DuckDB-WASM docs for setup.
Bun bundler / esbuild / Parcel The ?url suffix isn't resolved natively; needs custom plugins or loader config. Untested.
SSR / Node / Bun runtime Not supported. The DuckDB worker code requires browser APIs at module load.

The ?url worker chain lives only behind the /duckdb entry. If your bundler can't resolve ?url (or you simply don't want DuckDB-WASM in your bundle), import from the WASM-free entries instead and bring your own engine:

Entry Pulls DuckDB-WASM? Use for
@kolistat/bedevere-wise/ui No Individual UI components over your own DataProvider.
@kolistat/bedevere-wise/app No The full app shell (BedevereApp) with an injected Backend.
@kolistat/bedevere-wise/duckdb Yes The in-browser DuckDBService engine (the ?url chain).
@kolistat/bedevere-wise/ipc No IpcBackend for a native/remote DuckDB over WebSocket.
@kolistat/bedevere-wise (root) Yes Back-compat barrel; re-exports /duckdb, so it pulls the chain.

Local development against this package

The package's source lives in bedevere-wise (active development happens on the current dev-X.Y branch). To hack on both this and a consumer at once:

# in bedevere-wise/
bun run build:lib    # produces dist/
bun link             # registers @kolistat/bedevere-wise locally

# in your consumer app/
bun link @kolistat/bedevere-wise

After source changes in bedevere-wise, re-run bun run build:lib to refresh the linked dist/. The consumer's Vite dev server picks up the new code on next reload.

Source + standalone app

Source code: github.com/KoliStat/bedevere-wise. The standalone web app at bedeverewise.app is built from the same source. End-user docs and screenshots live on the Bedevere Wise app site (it's a desktop-only browser app; mobile isn't supported yet).

License

MIT — see LICENSE.

About

In-browser SQL data viewer for SAS, SPSS, Stata, Parquet, Excel, and CSV files. Query with DuckDB-WASM, plot with VISUALIZE … DRAW. Local-first — your data never leaves the device. No install, no upload.

Topics

Resources

License

Stars

3 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors