@@ -19,8 +19,8 @@ This app queries a 282 MB Parquet file directly in your browser using DuckDB-WAS
1919
2020``` {ojs}
2121//| code-fold: true
22- // Imports
23- import { DuckDBClient } from "https://cdn.jsdelivr.net/npm/@observablehq /duckdb@0.7.1 /+esm"
22+ // Imports - use dynamic import to avoid CORS issues
23+ duckdbModule = import( "https://cdn.jsdelivr.net/npm/@duckdb /duckdb-wasm@1.28.0 /+esm")
2424```
2525
2626``` {ojs}
@@ -221,12 +221,45 @@ html`<div style="margin-bottom: 16px;">
221221
222222``` {ojs}
223223//| code-fold: true
224- // Initialize DuckDB
224+ // Initialize DuckDB-WASM
225225db = {
226- const instance = await DuckDBClient.of();
227- await instance.query(`CREATE VIEW samples AS SELECT * FROM read_parquet('${parquet_url}')`);
226+ const bundle = await duckdbModule.selectBundle(duckdbModule.getJsDelivrBundles());
227+
228+ const worker_url = URL.createObjectURL(
229+ new Blob([`importScripts("${bundle.mainWorker}");`], {type: 'text/javascript'})
230+ );
231+ const worker = new Worker(worker_url);
232+ const logger = new duckdbModule.ConsoleLogger(duckdbModule.LogLevel.WARNING);
233+
234+ const instance = new duckdbModule.AsyncDuckDB(logger, worker);
235+ await instance.instantiate(bundle.mainModule, bundle.pthreadWorker);
236+ URL.revokeObjectURL(worker_url);
237+
238+ // Create view for convenience
239+ const conn = await instance.connect();
240+ await conn.query(`CREATE VIEW samples AS SELECT * FROM read_parquet('${parquet_url}')`);
241+ await conn.close();
242+
228243 return instance;
229244}
245+
246+ // Helper function to run queries
247+ async function runQuery(sql) {
248+ const conn = await db.connect();
249+ try {
250+ const result = await conn.query(sql);
251+ return result.toArray().map(row => {
252+ const obj = row.toJSON();
253+ // Convert BigInt to Number
254+ for (const key in obj) {
255+ if (typeof obj[key] === 'bigint') obj[key] = Number(obj[key]);
256+ }
257+ return obj;
258+ });
259+ } finally {
260+ await conn.close();
261+ }
262+ }
230263```
231264
232265``` {ojs}
@@ -283,8 +316,7 @@ sourceCounts = {
283316 `;
284317
285318 try {
286- const result = await db.query(query);
287- return Array.from(result);
319+ return await runQuery(query);
288320 } catch (e) {
289321 console.error("Facet query error:", e);
290322 return [];
@@ -298,8 +330,7 @@ sourceCounts = {
298330totalCount = {
299331 const query = `SELECT COUNT(*) as count FROM samples WHERE ${whereClause}`;
300332 try {
301- const result = await db.query(query);
302- const rows = Array.from(result);
333+ const rows = await runQuery(query);
303334 return rows[0]?.count || 0;
304335 } catch (e) {
305336 return 0;
@@ -334,8 +365,7 @@ sampleData = {
334365 LIMIT ${maxSamples}
335366 `;
336367
337- const result = await db.query(query);
338- const data = Array.from(result);
368+ const data = await runQuery(query);
339369
340370 if (statusDiv) {
341371 statusDiv.textContent = `Loaded ${data.length.toLocaleString()} samples`;
0 commit comments