@duckdb/duckdb-wasm
Version:
DuckDB powered by WebAssembly
4 lines • 133 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../web-worker/cjs/browser.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/utils/opfs_util.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 */\nmodule.exports = Worker;", "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 reliableHeadRequests?: boolean;\n /**\n * Allow falling back to full HTTP reads if the server does not support range requests.\n */\n allowFullHTTPReads?: boolean;\n /**\n * Force use of full HTTP reads, suppressing range requests.\n */\n forceFullHTTPReads?: boolean;\n}\n\nexport interface DuckDBOPFSConfig {\n /**\n * Defines how `opfs://` files are handled during SQL execution.\n * - \"auto\": Automatically register `opfs://` files and drop them after execution.\n * - \"manual\": Files must be manually registered and dropped.\n */\n fileHandling?: \"auto\" | \"manual\";\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 * Whether to use alternate Arrow conversion that preserves full range and precision of data.\n */\n arrowLosslessConversion?: boolean;\n /**\n * Custom user agent string\n */\n customUserAgent?: string;\n /**\n * opfs string\n */\n opfs?: DuckDBOPFSConfig;\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 MAX_ARROW_ERROR = 255,\n DUCKDB_WASM_RETRY = 256,\n}\n\nexport function IsArrowBuffer(status: StatusCode): boolean {\n return status <= StatusCode.MAX_ARROW_ERROR;\n}\n\nexport function IsDuckDBWasmRetry(status: StatusCode): boolean {\n return status === StatusCode.DUCKDB_WASM_RETRY;\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 // Avoid infinite loop on detached state\n if (this._bindings.isDetached()) {\n console.error('cannot send a message since the worker is not set!');\n return undefined as any;\n }\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> | 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 | null = null;\n if (this._inFlight != null) {\n buffer = await this._inFlight;\n this._inFlight = null;\n }\n\n while (buffer == null) {\n buffer = await this.db.fetchQueryResults(this.conn);\n }\n\n this._depleted = buffer.length == 0;\n if (!this._depleted) {\n this._inFlight = this.db.fetchQueryResults(this.conn);\n }\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, string[] | undefined>\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 | null>\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, string[] | undefined, null>\n | WorkerTask<WorkerRequestType.EXPORT_FILE_STATISTICS, string, FileStatistics>\n | WorkerTask<WorkerRequestType.FETCH_QUERY_RESULTS, ConnectionID, Uint8Array | null>\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", "export const REGEX_OPFS_FILE = /'(opfs:\\/\\/\\S*?)'/g;\nexport const REGEX_OPFS_PROTOCOL = /(opfs:\\/\\/\\S*?)/g;\n\nexport function isOPFSProtocol(path: string): boolean {\n return path.search(REGEX_OPFS_PROTOCOL) > -1;\n}\n\nexport function searchOPFSFiles(text: string) {\n return [...text.matchAll(REGEX_OPFS_FILE)].map(match => match[1]);\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 { searchOPFSFiles, isOPFSProtocol } from \"../utils/opfs_util\";\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 /** The DuckDBConfig */\n protected _config: DuckDBConfig = {};\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 /** Get the logger */\n public get config(): DuckDBConfig {\n return this._config;\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!:' + task.type+\",\" + task.data);\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 }\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 /** Is in detached state, no worker defined */\n public isDetached(): boolean {\n return !this._worker;\n }\n\n /** Reset the duckdb */\n public async reset(): Promise<null> {\n const task = new WorkerTask<WorkerRequestType.RESET, null, null>(WorkerRequestType.RESET, null);\n return await this.postTask(task);\n }\n\n /** Ping the worker thread */\n public async ping(): Promise<any> {\n const task = new WorkerTask<WorkerRequestType.PING, null, null>(WorkerRequestType.PING, null);\n await this.postTask(task);\n }\n /** Try to drop a file */\n public async dropFile(name: string): Promise<null> {\n const task = new WorkerTask<WorkerRequestType.DROP_FILE, string, null>(WorkerRequestType.DROP_FILE, name);\n return await this.postTask(task);\n }\n /** Try to drop files */\n public async dropFiles(names?: string[]): Promise<null> {\n const task = new WorkerTask<WorkerRequestType.DROP_FILES, string[] | undefined, null>(WorkerRequestType.DROP_FILES, names);\n return await this.postTask(task);\n }\n /** Flush all files */\n public async flushFiles(): Promise<null> {\n const task = new WorkerTask<WorkerRequestType.FLUSH_FILES, null, null>(WorkerRequestType.FLUSH_FILES, null);\n return await this.postTask(task);\n }\n\n /** Open the database */\n public async instantiate(\n mainModuleURL: string,\n pthreadWorkerURL: string | null = null,\n progress: (progress: InstantiationProgress) => void = _p => {},\n ): Promise<null> {\n this._onInstantiationProgress.push(progress);\n const task = new WorkerTask<WorkerRequestType.INSTANTIATE, [string, string | null], null>(\n WorkerRequestType.INSTANTIATE,\n [mainModuleURL, pthreadWorkerURL],\n );\n return await this.postTask(task);\n }\n\n /** Get the version */\n public async getVersion(): Promise<string> {\n const task = new WorkerTask<WorkerRequestType.GET_VERSION, null, string>(WorkerRequestType.GET_VERSION, null);\n const version = await this.postTask(task);\n return version;\n }\n\n /** Get the feature flags */\n public async getFeatureFlags(): Promise<number> {\n const task = new WorkerTask<WorkerRequestType.GET_FEATURE_FLAGS, null, number>(\n WorkerRequestType.GET_FEATURE_FLAGS,\n null,\n );\n const feature = await this.postTask(task);\n return feature;\n }\n\n /** Open a new database */\n public async open(config: DuckDBConfig): Promise<void> {\n this._config = config;\n const task = new WorkerTask<WorkerRequestType.OPEN, DuckDBConfig, null>(WorkerRequestType.OPEN, config);\n await this.postTask(task);\n }\n\n /** Tokenize a script text */\n public async tokenize(text: string): Promise<ScriptTokens> {\n const task = new WorkerTask<WorkerRequestType.TOKENIZE, string, ScriptTokens>(WorkerRequestType.TOKENIZE, text);\n const tokens = await this.postTask(task);\n return tokens;\n }\n\n /** Connect to the database */\n public async connectInternal(): Promise<number> {\n const task = new WorkerTask<WorkerRequestType.CONNECT, null, ConnectionID>(WorkerRequestType.CONNECT, null);\n return await this.postTask(task);\n }\n\n /** Connect to the database */\n public async connect(): Promise<AsyncDuckDBConnection> {\n const cid = await this.connectInternal();\n return new AsyncDuckDBConnection(this, cid);\n }\n\n /** Disconnect from the database */\n public async disconnect(conn: ConnectionID): Promise<void> {\n const task = new WorkerTask<WorkerRequestType.DISCONNECT, ConnectionID, null>(\n WorkerRequestType.DISCONNECT,\n conn,\n );\n await this.postTask(task);\n }\n\n /** Run a query */\n public async runQuery(conn: ConnectionID, text: string): Promise<Uint8Array> {\n if( this.shouldOPFSFileHandling() ){\n const files = await this.registerOPFSFileFromSQL(text);\n try {\n return await thi