import { AsyncDuckDB, AsyncDuckDBConnection } from "@duckdb/duckdb-wasm" import getExtension from "../helpers/getExtension.js" import mergeOptions from "../helpers/mergeOptions.js" import SimpleWebTable from "../class/SimpleWebTable.js" import { prettyDuration } from "journalism" export default async function fetchDataBrowser( simpleWebTable: SimpleWebTable, table: string, url: string, options: { fileType?: "csv" | "dsv" | "json" | "parquet" autoDetect?: boolean // csv options header?: boolean delim?: string skip?: number } = {} ) { simpleWebTable.debug && console.log("\nloadData()") simpleWebTable.debug && console.log("parameters:", { table, url, options }) let start if (simpleWebTable.debug) { start = Date.now() } if (simpleWebTable.db === undefined) { await simpleWebTable.sdb.start() simpleWebTable.db = simpleWebTable.sdb.db simpleWebTable.connection = simpleWebTable.sdb.connection } if (await simpleWebTable.sdb.hasTable(table)) { await simpleWebTable.sdb.customQuery(`DROP TABLE ${table};`) } const fileExtension = getExtension(url) const filename = url.split("/")[url.split("/").length - 1] if ( options.fileType === "csv" || fileExtension === "csv" || options.fileType === "dsv" || typeof options.delim === "string" ) { // await import to make duckdb-wasm optional const { DuckDBDataProtocol } = await import("@duckdb/duckdb-wasm") await (simpleWebTable.db as AsyncDuckDB).registerFileURL( filename, url, DuckDBDataProtocol.HTTP, false ) await ( simpleWebTable.connection as AsyncDuckDBConnection ).insertCSVFromPath(filename, { name: table, detect: options.autoDetect ?? true, header: options.header ?? true, delimiter: options.delim ?? ",", skip: options.skip, }) } else if (options.fileType === "json" || fileExtension === "json") { const res = await fetch(url) await (simpleWebTable.db as AsyncDuckDB).registerFileText( filename, await res.text() ) await ( simpleWebTable.connection as AsyncDuckDBConnection ).insertJSONFromPath(filename, { name: table, }) } else if (options.fileType === "parquet" || fileExtension === "parquet") { // await import to make duckdb-wasm optional const { DuckDBDataProtocol } = await import("@duckdb/duckdb-wasm") await (simpleWebTable.db as AsyncDuckDB).registerFileURL( filename, url, DuckDBDataProtocol.HTTP, false ) await simpleWebTable.runQuery( `CREATE OR REPLACE TABLE ${table} AS SELECT * FROM parquet_scan('${filename}')`, simpleWebTable.connection, false, mergeOptions(simpleWebTable, { table: null, method: null, parameters: null, }) ) } else { throw new Error( `Unknown options.fileType ${options.fileType} or fileExtension ${fileExtension}` ) } if (start) { console.log(`Done in ${prettyDuration(start)}`) } if (simpleWebTable.debug) { await simpleWebTable.logTable() } }