Lattice Grid Buy a licence

demo D232

Live pushdown to DuckDB, query by query

Every sort, filter and page becomes one SQL statement DuckDB answers, with only the window coming back and the generated SQL and timing on screen

createPushdownSource · duckdbAdapter · lastPlan()

Building…
Loading a live grid…

The configuration

'pushdown-duckdb-live': () => ({
  rows: [], config: {},
  foot: ['a hundred thousand rows in a 1.4 MB Parquet file, queried in the browser, no server', "DuckDB is the caller's engine, loaded from a CDN; the grid imports none of it", 'the SQL below is what the adapter generated; filter or sort to see it change'],
  mount: (el: HTMLElement, LG: any) => {
    el.textContent = '';
    el.style.cssText = 'display:flex;flex-direction:column;gap:12px;height:640px';
    const statusEl = document.createElement('div');
    statusEl.style.cssText = 'font-size:13px;color:var(--ink-2);line-height:1.5';
    statusEl.textContent = 'Starting DuckDB-Wasm in the browser…';
    const sqlEl = document.createElement('pre');
    sqlEl.style.cssText = 'margin:0;font-family:var(--mono);font-size:11.5px;color:var(--ink-2);background:#0f1420;color:#cfe0f0;border-radius:8px;padding:10px 13px;overflow-x:auto;white-space:pre;min-height:40px';
    sqlEl.textContent = '-- the generated SQL and timing appear here';
    const gridEl = document.createElement('div');
    gridEl.style.cssText = 'flex:1;min-height:0';
    el.append(statusEl, sqlEl, gridEl);
    let grid: any, connection: any, worker: any;
    let disposed = false;
    (async () => {
      try {
        statusEl.textContent = 'Loading DuckDB-Wasm from jsDelivr…';
        const duckdb: any = await import( 'https://cdn.jsdelivr.net/npm/@duckdb/duckdb-wasm@1.29.0/+esm');
        const bundle = await duckdb.selectBundle(duckdb.getJsDelivrBundles());
        worker = await duckdb.createWorker(bundle.mainWorker);
        const db = new duckdb.AsyncDuckDB(new duckdb.ConsoleLogger(duckdb.LogLevel.ERROR), worker);
        await db.instantiate(bundle.mainModule, bundle.pthreadWorker);
        if (disposed) return;
        connection = await db.connect();
        const FILE = new URL('/demo-data/readings.parquet', location.origin).href;
        const adapter = LG.duckdbAdapter({ connection, from: `read_parquet('${FILE}')` });
        const source = LG.createPushdownSource({ adapter, compute: LG, pageSize: 200 });
        const inner = adapter.execute.bind(adapter);
        adapter.execute = async (query: any, request: any) => {
          const started = performance.now();
          const result = await inner(query, request);
          const ms = Math.round(performance.now() - started);
          let head = '';
          try {
            const f = adapter.sqlFor(query);
            head = f.params?.length ? `${f.sql}\n-- bound: ${JSON.stringify(f.params)}\n` : `${f.sql}\n`;
          } catch {  }
          sqlEl.textContent = `${head}-- ${ms} ms · ${result.rows.length} rows shown of ${result.total ?? '?'}`;
          return result;
        };
        grid = LG.createGrid(gridEl, {
          rowKey: 'reading_id', theme: 'light',
          toolPanel: { side: 'left', panels: ['filters', 'columns'] },
          columns: [
            { field: 'reading_id', title: '#', type: 'number', layout: { width: 110 } },
            { field: 'plant', title: 'Plant', filter: { type: 'set' } },
            { field: 'line', title: 'Line', filter: { type: 'set' } },
            { field: 'product', title: 'Product' },
            { field: 'bore_mm', title: 'Bore', type: 'millimetres', spec: { lower: 9.95, upper: 10.05, target: 10 } },
            { field: 'cycle_seconds', title: 'Cycle', type: 'seconds' },
            { field: 'in_spec', title: 'In spec', type: 'boolean' },
            { field: 'taken_at', title: 'Taken', type: 'dateString' },
          ],
          source,
        });
        statusEl.innerHTML = '<b>100,000 rows</b> in a Parquet file, queried in the tab. Filter a plant or a line, or sort a column; DuckDB answers the whole query and only the page comes back.';
      } catch (err) {
        console.error('[pushdown-duckdb-live]', err);
        statusEl.textContent = 'DuckDB-Wasm could not start here. It loads from a CDN and needs a browser with WebAssembly and cross-origin isolation.';
      }
    })();
    return () => { disposed = true; grid?.destroy?.(); try { connection?.close?.(); } catch {  } try { worker?.terminate?.(); } catch {  } };
  },
})