UNPKG

@duckdb/duckdb-wasm

Version:
4 lines 137 kB
{ "version": 3, "sources": ["../../web-worker/cjs/node.js", "../src/targets/duckdb.ts", "../src/bindings/config.ts", "../src/bindings/tokens.ts", "../src/log.ts", "../src/status.ts", "../src/parallel/async_connection.ts", "../src/parallel/worker_request.ts", "../src/json_typedef.ts", "../src/parallel/async_bindings.ts", "../src/bindings/runtime.ts", "../src/parallel/worker_dispatcher.ts", "../../wasm-feature-detect/dist/esm/index.js", "../package.json", "../src/version.ts", "../src/platform.ts", "../src/worker.ts"], "sourcesContent": ["/**\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nconst URL = require('url');\n\nconst VM = require('vm');\n\nconst threads = require('worker_threads');\n\nconst WORKER = Symbol.for('worker');\nconst EVENTS = Symbol.for('events');\n\nclass EventTarget {\n constructor() {\n Object.defineProperty(this, EVENTS, {\n value: new Map()\n });\n }\n\n dispatchEvent(event) {\n event.target = event.currentTarget = this;\n\n if (this['on' + event.type]) {\n try {\n this['on' + event.type](event);\n } catch (err) {\n console.error(err);\n }\n }\n\n const list = this[EVENTS].get(event.type);\n if (list == null) return;\n list.forEach(handler => {\n try {\n handler.call(this, event);\n } catch (err) {\n console.error(err);\n }\n });\n }\n\n addEventListener(type, fn) {\n let events = this[EVENTS].get(type);\n if (!events) this[EVENTS].set(type, events = []);\n events.push(fn);\n }\n\n removeEventListener(type, fn) {\n let events = this[EVENTS].get(type);\n\n if (events) {\n const index = events.indexOf(fn);\n if (index !== -1) events.splice(index, 1);\n }\n }\n\n}\n\nfunction Event(type, target) {\n this.type = type;\n this.timeStamp = Date.now();\n this.target = this.currentTarget = this.data = null;\n} // this module is used self-referentially on both sides of the\n// thread boundary, but behaves differently in each context.\n\n\nmodule.exports = threads.isMainThread ? mainThread() : workerThread();\nconst baseUrl = URL.pathToFileURL(process.cwd() + '/');\n\nfunction mainThread() {\n /**\n * A web-compatible Worker implementation atop Node's worker_threads.\n * - uses DOM-style events (Event.data, Event.type, etc)\n * - supports event handler properties (worker.onmessage)\n * - Worker() constructor accepts a module URL\n * - accepts the {type:'module'} option\n * - emulates WorkerGlobalScope within the worker\n * @param {string} url The URL or module specifier to load\n * @param {object} [options] Worker construction options\n * @param {string} [options.name] Available as `self.name` within the Worker\n * @param {string} [options.type=\"classic\"] Pass \"module\" to create a Module Worker.\n */\n class Worker extends EventTarget {\n constructor(url, options) {\n super();\n const {\n name,\n type\n } = options || {};\n url += '';\n let mod;\n\n if (/^data:/.test(url)) {\n mod = url;\n } else {\n mod = URL.fileURLToPath(new URL.URL(url, baseUrl));\n }\n\n const worker = new threads.Worker(__filename, {\n workerData: {\n mod,\n name,\n type\n }\n });\n Object.defineProperty(this, WORKER, {\n value: worker\n });\n worker.on('message', data => {\n const event = new Event('message');\n event.data = data;\n this.dispatchEvent(event);\n });\n worker.on('error', error => {\n error.type = 'error';\n this.dispatchEvent(error);\n });\n worker.on('exit', () => {\n this.dispatchEvent(new Event('close'));\n });\n }\n\n postMessage(data, transferList) {\n this[WORKER].postMessage(data, transferList);\n }\n\n terminate() {\n this[WORKER].terminate();\n }\n\n }\n\n Worker.prototype.onmessage = Worker.prototype.onerror = Worker.prototype.onclose = null;\n return Worker;\n}\n\nfunction workerThread() {\n let {\n mod,\n name,\n type\n } = threads.workerData; // turn global into a mock WorkerGlobalScope\n\n const self = global.self = global; // enqueue messages to dispatch after modules are loaded\n\n let q = [];\n\n function flush() {\n const buffered = q;\n q = null;\n buffered.forEach(event => {\n self.dispatchEvent(event);\n });\n }\n\n threads.parentPort.on('message', data => {\n const event = new Event('message');\n event.data = data;\n if (q == null) self.dispatchEvent(event);else q.push(event);\n });\n threads.parentPort.on('error', err => {\n err.type = 'Error';\n self.dispatchEvent(err);\n });\n\n class WorkerGlobalScope extends EventTarget {\n postMessage(data, transferList) {\n threads.parentPort.postMessage(data, transferList);\n } // Emulates https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope/close\n\n\n close() {\n process.exit();\n }\n\n }\n\n let proto = Object.getPrototypeOf(global);\n delete proto.constructor;\n Object.defineProperties(WorkerGlobalScope.prototype, proto);\n proto = Object.setPrototypeOf(global, new WorkerGlobalScope());\n ['postMessage', 'addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(fn => {\n proto[fn] = proto[fn].bind(global);\n });\n global.name = name;\n const isDataUrl = /^data:/.test(mod);\n\n if (type === 'module') {\n import(mod).catch(err => {\n if (isDataUrl && err.message === 'Not supported') {\n console.warn('Worker(): Importing data: URLs requires Node 12.10+. Falling back to classic worker.');\n return evaluateDataUrl(mod, name);\n }\n\n console.error(err);\n }).then(flush);\n } else {\n try {\n if (/^data:/.test(mod)) {\n evaluateDataUrl(mod, name);\n } else {\n require(mod);\n }\n } catch (err) {\n console.error(err);\n }\n\n Promise.resolve().then(flush);\n }\n}\n\nfunction evaluateDataUrl(url, name) {\n const {\n data\n } = parseDataUrl(url);\n return VM.runInThisContext(data, {\n filename: 'worker.<' + (name || 'data:') + '>'\n });\n}\n\nfunction parseDataUrl(url) {\n let [m, type, encoding, data] = url.match(/^data: *([^;,]*)(?: *; *([^,]*))? *,(.*)$/) || [];\n if (!m) throw Error('Invalid Data URL.');\n if (encoding) switch (encoding.toLowerCase()) {\n case 'base64':\n data = Buffer.from(data, 'base64').toString();\n break;\n\n default:\n throw Error('Unknown Data URL encoding \"' + encoding + '\"');\n }\n return {\n type,\n data\n };\n}", "export * from '../bindings/config';\nexport * from '../bindings/tokens';\nexport * from '../log';\nexport * from '../status';\nexport * from '../parallel';\nexport * from '../platform';\nexport * from '../version';\nexport * from '../worker';\n\nexport { InstantiationProgress, InstantiationProgressHandler, DuckDBDataProtocol, WebFile } from '../bindings';\n", "export interface DuckDBQueryConfig {\n /**\n * The polling interval for queries\n */\n queryPollingInterval?: number;\n /**\n * Cast BigInt to Double?\n */\n castBigIntToDouble?: boolean;\n /**\n * Cast Timestamp to Date64?\n */\n castTimestampToDate?: boolean;\n /**\n * Cast Timestamp to Date64?\n */\n castDurationToTime64?: boolean;\n /**\n * Cast Decimal to Double?\n */\n castDecimalToDouble?: boolean;\n}\n\nexport interface DuckDBFilesystemConfig {\n /**\n * Allow falling back to full HTTP reads if the server does not support range requests.\n */\n reliableHeadRequests?: boolean;\n allowFullHTTPReads?: boolean;\n}\n\nexport enum DuckDBAccessMode {\n UNDEFINED = 0,\n AUTOMATIC = 1,\n READ_ONLY = 2,\n READ_WRITE = 3,\n}\n\nexport interface DuckDBConfig {\n /**\n * The database path\n */\n path?: string;\n /**\n * The access mode\n */\n accessMode?: DuckDBAccessMode;\n /**\n * The maximum number of threads.\n * Note that this will only work with cross-origin isolated sites since it requires SharedArrayBuffers.\n */\n maximumThreads?: number;\n /**\n * The direct io flag\n */\n useDirectIO?: boolean;\n /**\n * The query config\n */\n query?: DuckDBQueryConfig;\n /**\n * The filesystem config\n */\n filesystem?: DuckDBFilesystemConfig;\n /**\n * Whether to allow unsigned extensions\n */\n allowUnsignedExtensions?: boolean;\n /**\n * Custom user agent string\n */\n customUserAgent?: string;\n}\n", "export enum TokenType {\n IDENTIFIER = 0,\n NUMERIC_CONSTANT = 1,\n STRING_CONSTANT = 2,\n OPERATOR = 3,\n KEYWORD = 4,\n COMMENT = 5,\n}\n\nexport interface ScriptTokens {\n offsets: number[];\n types: TokenType[];\n}\n", "export enum LogLevel {\n NONE = 0,\n DEBUG = 1,\n INFO = 2,\n WARNING = 3,\n ERROR = 4,\n}\n\nexport enum LogTopic {\n NONE = 0,\n CONNECT = 1,\n DISCONNECT = 2,\n OPEN = 3,\n QUERY = 4,\n INSTANTIATE = 5,\n}\n\nexport enum LogEvent {\n NONE = 0,\n OK = 1,\n ERROR = 2,\n START = 3,\n RUN = 4,\n CAPTURE = 5,\n}\n\nexport enum LogOrigin {\n NONE = 0,\n WEB_WORKER = 1,\n NODE_WORKER = 2,\n BINDINGS = 3,\n ASYNC_DUCKDB = 4,\n}\n\nexport type LogEntry<O, T, E, V> = {\n readonly timestamp: Date;\n readonly level: LogLevel;\n readonly origin: O;\n readonly topic: T;\n readonly event: E;\n readonly value: V;\n};\n\nexport type ProgressEntry = {\n readonly status: string;\n readonly percentage: string;\n readonly repetitions: string;\n}\n\n/** An execution progress handler */\nexport type ExecutionProgressHandler = (p: ProgressEntry) => void;\n\nexport type LogEntryVariant =\n | LogEntry<LogOrigin.BINDINGS, LogTopic.INSTANTIATE, LogEvent.ERROR, string>\n | LogEntry<LogOrigin.BINDINGS, LogTopic.QUERY, LogEvent.START, void>\n | LogEntry<LogOrigin.BINDINGS, LogTopic.QUERY, LogEvent.OK, void>\n | LogEntry<LogOrigin.BINDINGS, LogTopic.QUERY, LogEvent.ERROR, void>\n | LogEntry<LogOrigin.BINDINGS, LogTopic.CONNECT, LogEvent.OK, void>\n | LogEntry<LogOrigin.BINDINGS, LogTopic.CONNECT, LogEvent.ERROR, void>\n | LogEntry<LogOrigin.BINDINGS, LogTopic.DISCONNECT, LogEvent.OK, void>\n | LogEntry<LogOrigin.BINDINGS, LogTopic.DISCONNECT, LogEvent.ERROR, void>\n | LogEntry<LogOrigin.BINDINGS, LogTopic.OPEN, LogEvent.START, void>\n | LogEntry<LogOrigin.BINDINGS, LogTopic.OPEN, LogEvent.OK, void>\n | LogEntry<LogOrigin.BINDINGS, LogTopic.OPEN, LogEvent.ERROR, void>\n | LogEntry<LogOrigin.ASYNC_DUCKDB, LogTopic.QUERY, LogEvent.RUN, string>;\n\nexport interface Logger {\n log(entry: LogEntryVariant): void;\n}\n\nexport class VoidLogger implements Logger {\n public log(_entry: LogEntryVariant): void {}\n}\n\nexport class ConsoleLogger implements Logger {\n constructor(protected level: LogLevel = LogLevel.INFO) {}\n public log(entry: LogEntryVariant): void {\n if (entry.level >= this.level) {\n console.log(entry);\n }\n }\n}\n\nexport function getLogLevelLabel(level: LogLevel): string {\n switch (level) {\n case LogLevel.NONE:\n return 'NONE';\n case LogLevel.DEBUG:\n return 'DEBUG';\n case LogLevel.INFO:\n return 'INFO';\n case LogLevel.WARNING:\n return 'WARNING';\n case LogLevel.ERROR:\n return 'ERROR';\n default:\n return '?';\n }\n}\n\nexport function getLogEventLabel(event: LogEvent): string {\n switch (event) {\n case LogEvent.NONE:\n return 'NONE';\n case LogEvent.OK:\n return 'OK';\n case LogEvent.ERROR:\n return 'ERROR';\n case LogEvent.START:\n return 'START';\n case LogEvent.RUN:\n return 'RUN';\n case LogEvent.CAPTURE:\n return 'CAPTURE';\n default:\n return '?';\n }\n}\n\nexport function getLogTopicLabel(topic: LogTopic): string {\n switch (topic) {\n case LogTopic.CONNECT:\n return 'CONNECT';\n case LogTopic.DISCONNECT:\n return 'DISCONNECT';\n case LogTopic.INSTANTIATE:\n return 'INSTANTIATE';\n case LogTopic.OPEN:\n return 'OPEN';\n case LogTopic.QUERY:\n return 'QUERY';\n default:\n return '?';\n }\n}\n\nexport function getLogOriginLabel(origin: LogOrigin): string {\n switch (origin) {\n case LogOrigin.NONE:\n return 'NONE';\n case LogOrigin.WEB_WORKER:\n return 'WEB WORKER';\n case LogOrigin.NODE_WORKER:\n return 'NODE WORKER';\n case LogOrigin.BINDINGS:\n return 'DUCKDB BINDINGS';\n case LogOrigin.ASYNC_DUCKDB:\n return 'DUCKDB';\n default:\n return '?';\n }\n}\n", "export enum StatusCode {\n SUCCESS = 0,\n}\n", "import * as arrow from 'apache-arrow';\nimport { AsyncDuckDB } from './async_bindings';\nimport { LogLevel, LogTopic, LogOrigin, LogEvent } from '../log';\nimport { ArrowInsertOptions, CSVInsertOptions, JSONInsertOptions } from '../bindings/insert_options';\n\n/** A thin helper to memoize the connection id */\nexport class AsyncDuckDBConnection {\n /** The async duckdb */\n protected readonly _bindings: AsyncDuckDB;\n /** The conn handle */\n protected readonly _conn: number;\n\n constructor(bindings: AsyncDuckDB, conn: number) {\n this._bindings = bindings;\n this._conn = conn;\n }\n\n /** Access the database bindings */\n public get bindings(): AsyncDuckDB {\n return this._bindings;\n }\n\n /** Disconnect from the database */\n public async close(): Promise<void> {\n return this._bindings.disconnect(this._conn);\n }\n\n /** Brave souls may use this function to consume the underlying connection id */\n public useUnsafe<R>(callback: (bindings: AsyncDuckDB, conn: number) => R) {\n return callback(this._bindings, this._conn);\n }\n\n /** Run a query */\n public async query<T extends { [key: string]: arrow.DataType } = any>(text: string): Promise<arrow.Table<T>> {\n this._bindings.logger.log({\n timestamp: new Date(),\n level: LogLevel.INFO,\n origin: LogOrigin.ASYNC_DUCKDB,\n topic: LogTopic.QUERY,\n event: LogEvent.RUN,\n value: text,\n });\n const buffer = await this._bindings.runQuery(this._conn, text);\n const reader = arrow.RecordBatchReader.from<T>(buffer);\n console.assert(reader.isSync(), \"Reader is not sync\");\n console.assert(reader.isFile(), \"Reader is not file\");\n return new arrow.Table(reader as arrow.RecordBatchFileReader);\n }\n\n /** Send a query */\n public async send<T extends { [key: string]: arrow.DataType } = any>(\n text: string,\n allowStreamResult: boolean = false,\n ): Promise<arrow.AsyncRecordBatchStreamReader<T>> {\n this._bindings.logger.log({\n timestamp: new Date(),\n level: LogLevel.INFO,\n origin: LogOrigin.ASYNC_DUCKDB,\n topic: LogTopic.QUERY,\n event: LogEvent.RUN,\n value: text,\n });\n let header = await this._bindings.startPendingQuery(this._conn, text, allowStreamResult);\n while (header == null) {\n header = await this._bindings.pollPendingQuery(this._conn);\n }\n const iter = new AsyncResultStreamIterator(this._bindings, this._conn, header);\n const reader = await arrow.RecordBatchReader.from<T>(iter);\n console.assert(reader.isAsync());\n console.assert(reader.isStream());\n return reader as unknown as arrow.AsyncRecordBatchStreamReader<T>; // XXX\n }\n\n /** Cancel a query that was sent earlier */\n public async cancelSent(): Promise<boolean> {\n return await this._bindings.cancelPendingQuery(this._conn);\n }\n\n /** Get table names */\n public async getTableNames(query: string): Promise<string[]> {\n return await this._bindings.getTableNames(this._conn, query);\n }\n\n /** Create a prepared statement */\n public async prepare<T extends { [key: string]: arrow.DataType } = any>(\n text: string,\n ): Promise<AsyncPreparedStatement<T>> {\n const stmt = await this._bindings.createPrepared(this._conn, text);\n return new AsyncPreparedStatement<T>(this._bindings, this._conn, stmt);\n }\n\n /** Insert an arrow table */\n public async insertArrowTable(table: arrow.Table, options: ArrowInsertOptions): Promise<void> {\n const buffer = arrow.tableToIPC(table, 'stream');\n await this.insertArrowFromIPCStream(buffer, options);\n }\n /** Insert an arrow table from an ipc stream */\n public async insertArrowFromIPCStream(buffer: Uint8Array, options: ArrowInsertOptions): Promise<void> {\n await this._bindings.insertArrowFromIPCStream(this._conn, buffer, options);\n }\n /** Insert csv file from path */\n public async insertCSVFromPath(text: string, options: CSVInsertOptions): Promise<void> {\n await this._bindings.insertCSVFromPath(this._conn, text, options);\n }\n /** Insert json file from path */\n public async insertJSONFromPath(text: string, options: JSONInsertOptions): Promise<void> {\n await this._bindings.insertJSONFromPath(this._conn, text, options);\n }\n}\n\n/** An async result stream iterator */\nexport class AsyncResultStreamIterator implements AsyncIterable<Uint8Array> {\n /** First chunk? */\n protected _first: boolean;\n /** Reached end of stream? */\n protected _depleted: boolean;\n /** In-flight */\n protected _inFlight: Promise<Uint8Array> | null;\n\n constructor(\n protected readonly db: AsyncDuckDB,\n protected readonly conn: number,\n protected readonly header: Uint8Array,\n ) {\n this._first = true;\n this._depleted = false;\n this._inFlight = null;\n }\n\n async next(): Promise<IteratorResult<Uint8Array>> {\n if (this._first) {\n this._first = false;\n return { done: false, value: this.header };\n }\n if (this._depleted) {\n return { done: true, value: null };\n }\n let buffer: Uint8Array;\n if (this._inFlight != null) {\n buffer = await this._inFlight;\n this._inFlight = null;\n } else {\n buffer = await this.db.fetchQueryResults(this.conn);\n }\n this._depleted = buffer.length == 0;\n if (!this._depleted) {\n this._inFlight = this.db.fetchQueryResults(this.conn);\n }\n return {\n done: this._depleted,\n value: buffer,\n };\n }\n\n [Symbol.asyncIterator]() {\n return this;\n }\n}\n\n/** A thin helper to bind the prepared statement id */\nexport class AsyncPreparedStatement<T extends { [key: string]: arrow.DataType } = any> {\n /** The bindings */\n protected readonly bindings: AsyncDuckDB;\n /** The connection id */\n protected readonly connectionId: number;\n /** The statement id */\n protected readonly statementId: number;\n\n /** Constructor */\n constructor(bindings: AsyncDuckDB, connectionId: number, statementId: number) {\n this.bindings = bindings;\n this.connectionId = connectionId;\n this.statementId = statementId;\n }\n\n /** Close a prepared statement */\n public async close() {\n await this.bindings.closePrepared(this.connectionId, this.statementId);\n }\n\n /** Run a prepared statement */\n public async query(...params: any[]): Promise<arrow.Table<T>> {\n const buffer = await this.bindings.runPrepared(this.connectionId, this.statementId, params);\n const reader = arrow.RecordBatchReader.from<T>(buffer);\n console.assert(reader.isSync());\n console.assert(reader.isFile());\n return new arrow.Table(reader as arrow.RecordBatchFileReader);\n }\n\n /** Send a prepared statement */\n public async send(...params: any[]): Promise<arrow.AsyncRecordBatchStreamReader<T>> {\n const header = await this.bindings.sendPrepared(this.connectionId, this.statementId, params);\n const iter = new AsyncResultStreamIterator(this.bindings, this.connectionId, header);\n const reader = await arrow.RecordBatchReader.from<T>(iter);\n console.assert(reader.isAsync());\n console.assert(reader.isStream());\n return reader as unknown as arrow.AsyncRecordBatchStreamReader<T>; // XXX\n }\n}\n", "import { CSVInsertOptions, JSONInsertOptions, ArrowInsertOptions } from '../bindings/insert_options';\nimport { LogEntryVariant, ProgressEntry } from '../log';\nimport { ScriptTokens } from '../bindings/tokens';\nimport { FileStatistics } from '../bindings/file_stats';\nimport { DuckDBConfig } from '../bindings/config';\nimport { WebFile } from '../bindings/web_file';\nimport { InstantiationProgress } from '../bindings/progress';\nimport { DuckDBDataProtocol } from '../bindings';\n\nexport type ConnectionID = number;\nexport type StatementID = number;\n\nexport enum WorkerRequestType {\n CANCEL_PENDING_QUERY = 'CANCEL_PENDING_QUERY',\n CLOSE_PREPARED = 'CLOSE_PREPARED',\n COLLECT_FILE_STATISTICS = 'COLLECT_FILE_STATISTICS',\n REGISTER_OPFS_FILE_NAME = 'REGISTER_OPFS_FILE_NAME',\n CONNECT = 'CONNECT',\n COPY_FILE_TO_BUFFER = 'COPY_FILE_TO_BUFFER',\n COPY_FILE_TO_PATH = 'COPY_FILE_TO_PATH',\n CREATE_PREPARED = 'CREATE_PREPARED',\n DISCONNECT = 'DISCONNECT',\n DROP_FILE = 'DROP_FILE',\n DROP_FILES = 'DROP_FILES',\n EXPORT_FILE_STATISTICS = 'EXPORT_FILE_STATISTICS',\n FETCH_QUERY_RESULTS = 'FETCH_QUERY_RESULTS',\n FLUSH_FILES = 'FLUSH_FILES',\n GET_FEATURE_FLAGS = 'GET_FEATURE_FLAGS',\n GET_TABLE_NAMES = 'GET_TABLE_NAMES',\n GET_VERSION = 'GET_VERSION',\n GLOB_FILE_INFOS = 'GLOB_FILE_INFOS',\n INSERT_ARROW_FROM_IPC_STREAM = 'INSERT_ARROW_FROM_IPC_STREAM',\n INSERT_CSV_FROM_PATH = 'IMPORT_CSV_FROM_PATH',\n INSERT_JSON_FROM_PATH = 'IMPORT_JSON_FROM_PATH',\n INSTANTIATE = 'INSTANTIATE',\n OPEN = 'OPEN',\n PING = 'PING',\n POLL_PENDING_QUERY = 'POLL_PENDING_QUERY',\n REGISTER_FILE_BUFFER = 'REGISTER_FILE_BUFFER',\n REGISTER_FILE_HANDLE = 'REGISTER_FILE_HANDLE',\n REGISTER_FILE_URL = 'REGISTER_FILE_URL',\n RESET = 'RESET',\n RUN_PREPARED = 'RUN_PREPARED',\n RUN_QUERY = 'RUN_QUERY',\n SEND_PREPARED = 'SEND_PREPARED',\n START_PENDING_QUERY = 'START_PENDING_QUERY',\n TOKENIZE = 'TOKENIZE',\n}\n\nexport enum WorkerResponseType {\n CONNECTION_INFO = 'CONNECTION_INFO',\n ERROR = 'ERROR',\n FEATURE_FLAGS = 'FEATURE_FLAGS',\n FILE_BUFFER = 'FILE_BUFFER',\n FILE_INFOS = 'FILE_INFOS',\n FILE_SIZE = 'FILE_SIZE',\n FILE_STATISTICS = 'FILE_STATISTICS',\n INSTANTIATE_PROGRESS = 'INSTANTIATE_PROGRESS',\n LOG = 'LOG',\n PROGRESS_UPDATE = 'PROGRESS_UPDATE',\n OK = 'OK',\n PREPARED_STATEMENT_ID = 'PREPARED_STATEMENT_ID',\n QUERY_PLAN = 'QUERY_PLAN',\n QUERY_RESULT = 'QUERY_RESULT',\n QUERY_RESULT_CHUNK = 'QUERY_RESULT_CHUNK',\n QUERY_RESULT_HEADER = 'QUERY_RESULT_HEADER',\n QUERY_RESULT_HEADER_OR_NULL = 'QUERY_RESULT_HEADER_OR_NULL',\n REGISTERED_FILE = 'REGISTERED_FILE',\n SCRIPT_TOKENS = 'SCRIPT_TOKENS',\n SUCCESS = 'SUCCESS',\n TABLE_NAMES = 'TABLE_NAMES',\n VERSION_STRING = 'VERSION_STRING',\n}\n\nexport type WorkerRequest<T, P> = {\n readonly messageId: number;\n readonly type: T;\n readonly data: P;\n};\n\nexport type WorkerResponse<T, P> = {\n readonly messageId: number;\n readonly requestId: number;\n readonly type: T;\n readonly data: P;\n};\n\nexport type WorkerTaskReturnType<T extends WorkerTaskVariant> = T extends WorkerTask<any, any, infer P> ? P : never;\n\nexport class WorkerTask<T, D, P> {\n readonly type: T;\n readonly data: D;\n promise: Promise<P>;\n promiseResolver: (value: P | PromiseLike<P>) => void = () => {};\n promiseRejecter: (value: any) => void = () => {};\n\n constructor(type: T, data: D) {\n this.type = type;\n this.data = data;\n this.promise = new Promise<P>(\n (resolve: (value: P | PromiseLike<P>) => void, reject: (reason?: void) => void) => {\n this.promiseResolver = resolve;\n this.promiseRejecter = reject;\n },\n );\n }\n}\n\nexport type WorkerRequestVariant =\n | WorkerRequest<WorkerRequestType.CLOSE_PREPARED, [ConnectionID, StatementID]>\n | WorkerRequest<WorkerRequestType.CANCEL_PENDING_QUERY, number>\n | WorkerRequest<WorkerRequestType.COLLECT_FILE_STATISTICS, [string, boolean]>\n | WorkerRequest<WorkerRequestType.REGISTER_OPFS_FILE_NAME, [string]>\n | WorkerRequest<WorkerRequestType.CONNECT, null>\n | WorkerRequest<WorkerRequestType.COPY_FILE_TO_BUFFER, string>\n | WorkerRequest<WorkerRequestType.COPY_FILE_TO_PATH, [string, string]>\n | WorkerRequest<WorkerRequestType.CREATE_PREPARED, [ConnectionID, string]>\n | WorkerRequest<WorkerRequestType.DISCONNECT, number>\n | WorkerRequest<WorkerRequestType.DROP_FILE, string>\n | WorkerRequest<WorkerRequestType.DROP_FILES, null>\n | WorkerRequest<WorkerRequestType.EXPORT_FILE_STATISTICS, string>\n | WorkerRequest<WorkerRequestType.FETCH_QUERY_RESULTS, number>\n | WorkerRequest<WorkerRequestType.FLUSH_FILES, null>\n | WorkerRequest<WorkerRequestType.GET_FEATURE_FLAGS, null>\n | WorkerRequest<WorkerRequestType.GET_TABLE_NAMES, [number, string]>\n | WorkerRequest<WorkerRequestType.GET_VERSION, null>\n | WorkerRequest<WorkerRequestType.GLOB_FILE_INFOS, string>\n | WorkerRequest<\n WorkerRequestType.INSERT_ARROW_FROM_IPC_STREAM,\n [number, Uint8Array, ArrowInsertOptions | undefined]\n >\n | WorkerRequest<WorkerRequestType.INSERT_CSV_FROM_PATH, [number, string, CSVInsertOptions]>\n | WorkerRequest<WorkerRequestType.INSERT_JSON_FROM_PATH, [number, string, JSONInsertOptions]>\n | WorkerRequest<WorkerRequestType.INSTANTIATE, [string, string | null]>\n | WorkerRequest<WorkerRequestType.OPEN, DuckDBConfig>\n | WorkerRequest<WorkerRequestType.PING, null>\n | WorkerRequest<WorkerRequestType.POLL_PENDING_QUERY, number>\n | WorkerRequest<WorkerRequestType.REGISTER_FILE_BUFFER, [string, Uint8Array]>\n | WorkerRequest<WorkerRequestType.REGISTER_FILE_HANDLE, [string, any, DuckDBDataProtocol, boolean]>\n | WorkerRequest<WorkerRequestType.REGISTER_FILE_URL, [string, string, DuckDBDataProtocol, boolean]>\n | WorkerRequest<WorkerRequestType.RESET, null>\n | WorkerRequest<WorkerRequestType.RUN_PREPARED, [number, number, any[]]>\n | WorkerRequest<WorkerRequestType.RUN_QUERY, [number, string]>\n | WorkerRequest<WorkerRequestType.SEND_PREPARED, [number, number, any[]]>\n | WorkerRequest<WorkerRequestType.START_PENDING_QUERY, [number, string, boolean]>\n | WorkerRequest<WorkerRequestType.TOKENIZE, string>;\n\nexport type WorkerResponseVariant =\n | WorkerResponse<WorkerResponseType.CONNECTION_INFO, number>\n | WorkerResponse<WorkerResponseType.ERROR, any>\n | WorkerResponse<WorkerResponseType.FEATURE_FLAGS, number>\n | WorkerResponse<WorkerResponseType.FILE_BUFFER, Uint8Array>\n | WorkerResponse<WorkerResponseType.FILE_INFOS, WebFile[]>\n | WorkerResponse<WorkerResponseType.FILE_SIZE, number>\n | WorkerResponse<WorkerResponseType.FILE_STATISTICS, FileStatistics>\n | WorkerResponse<WorkerResponseType.INSTANTIATE_PROGRESS, InstantiationProgress>\n | WorkerResponse<WorkerResponseType.LOG, LogEntryVariant>\n | WorkerResponse<WorkerResponseType.PROGRESS_UPDATE, ProgressEntry>\n | WorkerResponse<WorkerResponseType.OK, null>\n | WorkerResponse<WorkerResponseType.PREPARED_STATEMENT_ID, number>\n | WorkerResponse<WorkerResponseType.QUERY_PLAN, Uint8Array>\n | WorkerResponse<WorkerResponseType.QUERY_RESULT, Uint8Array>\n | WorkerResponse<WorkerResponseType.QUERY_RESULT_CHUNK, Uint8Array>\n | WorkerResponse<WorkerResponseType.QUERY_RESULT_HEADER, Uint8Array>\n | WorkerResponse<WorkerResponseType.QUERY_RESULT_HEADER_OR_NULL, Uint8Array | null>\n | WorkerResponse<WorkerResponseType.SCRIPT_TOKENS, ScriptTokens>\n | WorkerResponse<WorkerResponseType.SUCCESS, boolean>\n | WorkerResponse<WorkerResponseType.TABLE_NAMES, string[]>\n | WorkerResponse<WorkerResponseType.VERSION_STRING, string>;\n\nexport type WorkerTaskVariant =\n | WorkerTask<WorkerRequestType.COLLECT_FILE_STATISTICS, [string, boolean], null>\n | WorkerTask<WorkerRequestType.REGISTER_OPFS_FILE_NAME, [string], null>\n | WorkerTask<WorkerRequestType.CLOSE_PREPARED, [number, number], null>\n | WorkerTask<WorkerRequestType.CONNECT, null, ConnectionID>\n | WorkerTask<WorkerRequestType.COPY_FILE_TO_BUFFER, string, Uint8Array>\n | WorkerTask<WorkerRequestType.COPY_FILE_TO_PATH, [string, string], null>\n | WorkerTask<WorkerRequestType.CREATE_PREPARED, [number, string], number>\n | WorkerTask<WorkerRequestType.DISCONNECT, ConnectionID, null>\n | WorkerTask<WorkerRequestType.DROP_FILE, string, null>\n | WorkerTask<WorkerRequestType.DROP_FILES, null, null>\n | WorkerTask<WorkerRequestType.EXPORT_FILE_STATISTICS, string, FileStatistics>\n | WorkerTask<WorkerRequestType.FETCH_QUERY_RESULTS, ConnectionID, Uint8Array>\n | WorkerTask<WorkerRequestType.FLUSH_FILES, null, null>\n | WorkerTask<WorkerRequestType.GET_FEATURE_FLAGS, null, number>\n | WorkerTask<WorkerRequestType.GET_TABLE_NAMES, [number, string], string[]>\n | WorkerTask<WorkerRequestType.GET_VERSION, null, string>\n | WorkerTask<\n WorkerRequestType.INSERT_ARROW_FROM_IPC_STREAM,\n [number, Uint8Array, ArrowInsertOptions | undefined],\n null\n >\n | WorkerTask<WorkerRequestType.INSERT_CSV_FROM_PATH, [number, string, CSVInsertOptions], null>\n | WorkerTask<WorkerRequestType.INSERT_JSON_FROM_PATH, [number, string, JSONInsertOptions], null>\n | WorkerTask<WorkerRequestType.INSTANTIATE, [string, string | null], null>\n | WorkerTask<WorkerRequestType.OPEN, DuckDBConfig, null>\n | WorkerTask<WorkerRequestType.PING, null, null>\n | WorkerTask<WorkerRequestType.REGISTER_FILE_BUFFER, [string, Uint8Array], null>\n | WorkerTask<WorkerRequestType.REGISTER_FILE_HANDLE, [string, any, DuckDBDataProtocol, boolean], null>\n | WorkerTask<WorkerRequestType.REGISTER_FILE_URL, [string, string, DuckDBDataProtocol, boolean], null>\n | WorkerTask<WorkerRequestType.GLOB_FILE_INFOS, string, WebFile[]>\n | WorkerTask<WorkerRequestType.RESET, null, null>\n | WorkerTask<WorkerRequestType.RUN_PREPARED, [number, number, any[]], Uint8Array>\n | WorkerTask<WorkerRequestType.RUN_QUERY, [ConnectionID, string], Uint8Array>\n | WorkerTask<WorkerRequestType.SEND_PREPARED, [number, number, any[]], Uint8Array>\n | WorkerTask<WorkerRequestType.START_PENDING_QUERY, [ConnectionID, string, boolean], Uint8Array | null>\n | WorkerTask<WorkerRequestType.POLL_PENDING_QUERY, ConnectionID, Uint8Array | null>\n | WorkerTask<WorkerRequestType.CANCEL_PENDING_QUERY, ConnectionID, boolean>\n | WorkerTask<WorkerRequestType.TOKENIZE, string, ScriptTokens>;\n", "import * as arrow from 'apache-arrow';\n\nexport interface SQLType {\n /// The sql type\n sqlType: string;\n /// Is nullable?\n nullable?: boolean;\n /// Decimal precision\n precision?: number;\n /// Decimal scaling\n scale?: number;\n /// Timezone\n timezone?: string;\n /// Byte width (FixedSizeBinary)\n byteWidth?: number;\n /// Key type\n keyType?: SQLType;\n /// Value type\n valueType?: SQLType;\n /// Fields\n fields?: SQLField[];\n}\n\nexport function arrowToSQLType(type: arrow.DataType): SQLType {\n switch (type.typeId) {\n case arrow.Type.Binary:\n return { sqlType: 'binary' };\n case arrow.Type.Bool:\n return { sqlType: 'bool' };\n case arrow.Type.Date:\n return { sqlType: 'date' };\n case arrow.Type.DateDay:\n return { sqlType: 'date32[d]' };\n case arrow.Type.DateMillisecond:\n return { sqlType: 'date64[ms]' };\n case arrow.Type.Decimal: {\n const dec = type as arrow.Decimal;\n return { sqlType: 'decimal', precision: dec.precision, scale: dec.scale };\n }\n case arrow.Type.Float:\n return { sqlType: 'float' };\n case arrow.Type.Float16:\n return { sqlType: 'float16' };\n case arrow.Type.Float32:\n return { sqlType: 'float32' };\n case arrow.Type.Float64:\n return { sqlType: 'float64' };\n case arrow.Type.Int:\n return { sqlType: 'int32' };\n case arrow.Type.Int16:\n return { sqlType: 'int16' };\n case arrow.Type.Int32:\n return { sqlType: 'int32' };\n case arrow.Type.Int64:\n return { sqlType: 'int64' };\n case arrow.Type.Uint16:\n return { sqlType: 'uint16' };\n case arrow.Type.Uint32:\n return { sqlType: 'uint32' };\n case arrow.Type.Uint64:\n return { sqlType: 'uint64' };\n case arrow.Type.Uint8:\n return { sqlType: 'uint8' };\n case arrow.Type.IntervalDayTime:\n return { sqlType: 'interval[dt]' };\n case arrow.Type.IntervalYearMonth:\n return { sqlType: 'interval[m]' };\n case arrow.Type.List: {\n const list = type as arrow.List;\n return {\n sqlType: 'list',\n valueType: arrowToSQLType(list.valueType),\n };\n }\n case arrow.Type.FixedSizeBinary: {\n const bin = type as arrow.FixedSizeBinary;\n return { sqlType: 'fixedsizebinary', byteWidth: bin.byteWidth };\n }\n case arrow.Type.Null:\n return { sqlType: 'null' };\n case arrow.Type.Utf8:\n return { sqlType: 'utf8' };\n case arrow.Type.Struct: {\n const struct_ = type as arrow.Struct;\n return {\n sqlType: 'struct',\n fields: struct_.children.map(c => arrowToSQLField(c.name, c.type)),\n };\n }\n case arrow.Type.Map: {\n const map_ = type as arrow.Map_;\n return {\n sqlType: 'map',\n keyType: arrowToSQLType(map_.keyType),\n valueType: arrowToSQLType(map_.valueType),\n };\n }\n case arrow.Type.Time:\n return { sqlType: 'time[s]' };\n case arrow.Type.TimeMicrosecond:\n return { sqlType: 'time[us]' };\n case arrow.Type.TimeMillisecond:\n return { sqlType: 'time[ms]' };\n case arrow.Type.TimeNanosecond:\n return { sqlType: 'time[ns]' };\n case arrow.Type.TimeSecond:\n return { sqlType: 'time[s]' };\n case arrow.Type.Timestamp: {\n const ts = type as arrow.Timestamp;\n return { sqlType: 'timestamp', timezone: ts.timezone || undefined };\n }\n case arrow.Type.TimestampSecond: {\n const ts = type as arrow.TimestampSecond;\n return { sqlType: 'timestamp[s]', timezone: ts.timezone || undefined };\n }\n case arrow.Type.TimestampMicrosecond: {\n const ts = type as arrow.TimestampMicrosecond;\n return { sqlType: 'timestamp[us]', timezone: ts.timezone || undefined };\n }\n case arrow.Type.TimestampNanosecond: {\n const ts = type as arrow.TimestampNanosecond;\n return { sqlType: 'timestamp[ns]', timezone: ts.timezone || undefined };\n }\n case arrow.Type.TimestampMillisecond: {\n const ts = type as arrow.TimestampMillisecond;\n return { sqlType: 'timestamp[ms]', timezone: ts.timezone || undefined };\n }\n }\n throw new Error(`unsupported arrow type: ${type.toString()}`);\n}\n\nexport type SQLField = SQLType & { name: string };\n\nexport function arrowToSQLField(name: string, type: arrow.DataType): SQLField {\n const t = arrowToSQLType(type) as SQLField;\n t.name = name;\n return t;\n}\n", "import {\n WorkerRequestType,\n WorkerResponseType,\n WorkerResponseVariant,\n WorkerTaskVariant,\n WorkerTask,\n ConnectionID,\n WorkerTaskReturnType,\n} from './worker_request';\nimport { AsyncDuckDBBindings } from './async_bindings_interface';\nimport { Logger } from '../log';\nimport { AsyncDuckDBConnection } from './async_connection';\nimport { CSVInsertOptions, JSONInsertOptions, ArrowInsertOptions } from '../bindings/insert_options';\nimport { ScriptTokens } from '../bindings/tokens';\nimport { FileStatistics } from '../bindings/file_stats';\nimport { DuckDBConfig } from '../bindings/config';\nimport { InstantiationProgress } from '../bindings/progress';\nimport { arrowToSQLField } from '../json_typedef';\nimport { WebFile } from '../bindings/web_file';\nimport { DuckDBDataProtocol } from '../bindings';\nimport { ProgressEntry } from '../log';\n\nconst TEXT_ENCODER = new TextEncoder();\n\nexport class AsyncDuckDB implements AsyncDuckDBBindings {\n /** The message handler */\n protected readonly _onMessageHandler: (event: MessageEvent) => void;\n /** The error handler */\n protected readonly _onErrorHandler: (event: ErrorEvent) => void;\n /** The close handler */\n protected readonly _onCloseHandler: () => void;\n\n /** Instantiate the module */\n protected _onInstantiationProgress: ((p: InstantiationProgress) => void)[] = [];\n\n /** Progress callbacks */\n protected _onExecutionProgress: ((p: ProgressEntry) => void)[] = [];\n\n /** The logger */\n protected readonly _logger: Logger;\n /** The worker */\n protected _worker: Worker | null = null;\n /** The promise for the worker shutdown */\n protected _workerShutdownPromise: Promise<null> | null = null;\n /** Make the worker as terminated */\n protected _workerShutdownResolver: (value: PromiseLike<null> | null) => void = () => {};\n\n /** The next message id */\n protected _nextMessageId = 0;\n /** The pending requests */\n protected _pendingRequests: Map<number, WorkerTaskVariant> = new Map();\n\n constructor(logger: Logger, worker: Worker | null = null) {\n this._logger = logger;\n this._onMessageHandler = this.onMessage.bind(this);\n this._onErrorHandler = this.onError.bind(this);\n this._onCloseHandler = this.onClose.bind(this);\n if (worker != null) this.attach(worker);\n }\n\n /** Get the logger */\n public get logger(): Logger {\n return this._logger;\n }\n\n /** Attach to worker */\n protected attach(worker: Worker): void {\n this._worker = worker;\n this._worker.addEventListener('message', this._onMessageHandler);\n this._worker.addEventListener('error', this._onErrorHandler);\n this._worker.addEventListener('close', this._onCloseHandler);\n this._workerShutdownPromise = new Promise<null>(\n (resolve: (value: PromiseLike<null> | null) => void, _reject: (reason?: void) => void) => {\n this._workerShutdownResolver = resolve;\n },\n );\n }\n\n /** Detach from worker */\n public detach(): void {\n if (!this._worker) return;\n this._worker.removeEventListener('message', this._onMessageHandler);\n this._worker.removeEventListener('error', this._onErrorHandler);\n this._worker.removeEventListener('close', this._onCloseHandler);\n this._worker = null;\n this._workerShutdownResolver(null);\n this._workerShutdownPromise = null;\n this._workerShutdownResolver = () => {};\n }\n\n /** Kill the worker */\n public async terminate(): Promise<void> {\n if (!this._worker) return;\n this._worker.terminate();\n //await this._workerShutdownPromise; TODO deadlocking in karma?\n this._worker = null;\n this._workerShutdownPromise = null;\n this._workerShutdownResolver = () => {};\n }\n\n /** Post a task */\n protected async postTask<W extends WorkerTaskVariant>(\n task: W,\n transfer: ArrayBuffer[] = [],\n ): Promise<WorkerTaskReturnType<W>> {\n if (!this._worker) {\n console.error('cannot send a message since the worker is not set!');\n return undefined as any;\n }\n const mid = this._nextMessageId++;\n this._pendingRequests.set(mid, task);\n this._worker.postMessage(\n {\n messageId: mid,\n type: task.type,\n data: task.data,\n },\n transfer,\n );\n return (await task.promise) as WorkerTaskReturnType<W>;\n }\n\n /** Received a message */\n protected onMessage(event: MessageEvent): void {\n // Unassociated responses?\n const response = event.data as WorkerResponseVariant;\n switch (response.type) {\n // Request failed?\n case WorkerResponseType.PROGRESS_UPDATE: {\n for (const p of this._onExecutionProgress) {\n p(response.data);\n\t\t}\n return;\n }\n case WorkerResponseType.LOG: {\n this._logger.log(response.data);\n return;\n }\n // Call progress callback\n case WorkerResponseType.INSTANTIATE_PROGRESS: {\n for (const p of this._onInstantiationProgress) {\n p(response.data);\n }\n return;\n }\n }\n\n // Get associated task\n const task = this._pendingRequests.get(response.requestId);\n if (!task) {\n console.warn(`unassociated response: [${response.requestId}, ${response.type.toString()}]`);\n return;\n }\n this._pendingRequests.delete(response.requestId);\n\n // Request failed?\n if (response.type == WorkerResponseType.ERROR) {\n // Workaround for Firefox not being able to perform structured-clone on Native Errors\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1556604\n const e = new Error(response.data.message);\n e.name = response.data.name;\n if (Object.getOwnPropertyDescriptor(e, 'stack')?.writable) {\n e.stack = response.data.stack;\n }\n task.promiseRejecter(e);\n return;\n }\n\n // Otherwise differentiate between the tasks first\n switch (task.type) {\n case WorkerRequestType.CLOSE_PREPARED:\n case WorkerRequestType.COLLECT_FILE_STATISTICS:\n case WorkerRequestType.REGISTER_OPFS_FILE_NAME:\n case WorkerRequestType.COPY_FILE_TO_PATH:\n case WorkerRequestType.DISCONNECT:\n case WorkerRequestType.DROP_FILE:\n case WorkerRequestType.DROP_FILES:\n case WorkerRequestType.FLUSH_FILES:\n case WorkerRequestType.INSERT_ARROW_FROM_IPC_STREAM:\n case WorkerRequestType.INSERT_CSV_FROM_PATH:\n case WorkerRequestType.INSERT_JSON_FROM_PATH:\n case WorkerRequestType.OPEN:\n case WorkerRequestType.PING:\n case WorkerRequestType.REGISTER_FILE_BUFFER:\n case WorkerRequestType.REGISTER_FILE_HANDLE:\n case WorkerRequestType.REGISTER_FILE_URL:\n case WorkerRequestType.RESET:\n if (response.type == WorkerResponseType.OK) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.INSTANTIATE:\n this._onInstantiationProgress = [];\n if (response.type == WorkerResponseType.OK) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.GLOB_FILE_INFOS:\n if (response.type == WorkerResponseType.FILE_INFOS) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.GET_VERSION:\n if (response.type == WorkerResponseType.VERSION_STRING) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.GET_FEATURE_FLAGS:\n if (response.type == WorkerResponseType.FEATURE_FLAGS) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.GET_TABLE_NAMES:\n if (response.type == WorkerResponseType.TABLE_NAMES) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.TOKENIZE:\n if (response.type == WorkerResponseType.SCRIPT_TOKENS) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.COPY_FILE_TO_BUFFER:\n if (response.type == WorkerResponseType.FILE_BUFFER) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.EXPORT_FILE_STATISTICS:\n if (response.type == WorkerResponseType.FILE_STATISTICS) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.CONNECT:\n if (response.type == WorkerResponseType.CONNECTION_INFO) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.RUN_PREPARED:\n case WorkerRequestType.RUN_QUERY:\n if (response.type == WorkerResponseType.QUERY_RESULT) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.SEND_PREPARED:\n if (response.type == WorkerResponseType.QUERY_RESULT_HEADER) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.START_PENDING_QUERY:\n if (response.type == WorkerResponseType.QUERY_RESULT_HEADER_OR_NULL) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.POLL_PENDING_QUERY:\n if (response.type == WorkerResponseType.QUERY_RESULT_HEADER_OR_NULL) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.CANCEL_PENDING_QUERY:\n this._onInstantiationProgress = [];\n if (response.type == WorkerResponseType.SUCCESS) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.FETCH_QUERY_RESULTS:\n if (response.type == WorkerResponseType.QUERY_RESULT_CHUNK) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n case WorkerRequestType.CREATE_PREPARED:\n if (response.type == WorkerResponseType.PREPARED_STATEMENT_ID) {\n task.promiseResolver(response.data);\n return;\n }\n break;\n }\n task.promiseRejecter(new Error(`unexpected response type: ${response.type.toString()}`));\n }\n\n /** Received an error */\n protected onError(event: ErrorEvent): void {\n console.error(event);\n console.error(`error in duckdb worker: ${event.message}`);\n this._pendingRequests.clear();\n }\n\n /** The worker was closed */\n protected onClose(): void {\n this._workerShutdownResolver(null);\n if (this._pendingRequests.size != 0) {\n console.warn(`worker terminated with ${this._pendingRequests.size} pending requests`);\n return;\n }\n this._pendingRequests.clear();\n }\n\n /** Reset the duckdb */\n public async reset(): Promise<null> {\n const task = new WorkerTask<WorkerRequestType.RESET, null, null>