UNPKG

godot-sqlite-kysely

Version:

Kysely dialect for godot-sqlite. Adds SQLite support to Godot/GodotJS.

142 lines (141 loc) 5.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GodotSQLiteKyselyWorkerConnection = void 0; const godot_worker_1 = require("godot.worker"); class GodotSQLiteKyselyWorkerConnection { #nestedTransactionIndex = 0; #queryCallbacks = new Map(); #queryIndex = 0; #transferParameters = false; #worker; #workerPromise; #postRequest(message) { if (this.#transferParameters && message.type === 'query') { this.#worker.postMessage(message, Array.isArray(message.parameters) ? message.parameters : [message.parameters]); } else { this.#worker.postMessage(message); } } constructor(config, workerModule) { this.#transferParameters = config.transferQueries ?? false; this.#worker = new godot_worker_1.JSWorker(workerModule); this.#workerPromise = new Promise((resolve, reject) => { this.#worker.onmessage = (response) => { switch (response.type) { case 'initializationError': console.error(`Worker SQLite connection error: ${response}`); this.#workerPromise = null; reject(new Error(response.message)); break; case 'initialized': this.#workerPromise = null; resolve(); break; case 'queryError': { const { id, message } = response; const callback = this.#queryCallbacks.get(id); if (!callback) { console.error(`Received query error for unknown query index: ${id}`); break; } callback(message); break; } case 'queryResult': { const { id, result } = response; const callback = this.#queryCallbacks.get(id); if (!callback) { console.error(`Received query result for unknown query index: ${id}`); break; } callback(result); break; } case 'terminated': break; default: console.error('Unhandled worker response: ' + JSON.stringify(response, null, 2)); break; } }; this.#worker.onready = () => { this.#postRequest({ type: 'initialize', config, }); }; }); } close() { return new Promise((resolve, reject) => { const previousOnMessage = this.#worker.onmessage; this.#worker.onmessage = (response) => { if (response.type === 'terminated') { try { this.#worker.terminate(); resolve(); } catch (e) { reject(e); } } else { previousOnMessage?.(response); } }; this.#postRequest({ type: 'terminate', }); }); } async #postQuery(query, parameters) { if (this.#workerPromise) { await this.#workerPromise; } const queryIndex = this.#queryIndex++; return await new Promise((resolve, reject) => { this.#queryCallbacks.set(queryIndex, (result) => { this.#queryCallbacks.delete(queryIndex); if (typeof result === 'string') { const params = Array.isArray(parameters) ? parameters : [...parameters.proxy()]; reject(new Error(`${result}. Query: ${query} (${params.join(', ')}). `)); } else { resolve(result); } }); this.#postRequest({ type: 'query', id: queryIndex, query, parameters, }); }); } executeQuery(compiledQuery) { return this.#postQuery(compiledQuery.sql, compiledQuery.parameters); } streamQuery(_compiledQuery, _chunkSize) { throw new Error('Streaming is not supported with SQLite3'); } async beginTransaction() { const savepointName = `sp${this.#nestedTransactionIndex++}`; this.#postQuery(`savepoint ${savepointName}`, []); } async commitTransaction() { if (this.#nestedTransactionIndex <= 0) { throw new Error('No transactions in progress'); } const savepointName = `sp${--this.#nestedTransactionIndex}`; this.#postQuery(`release savepoint ${savepointName}`, []); } async rollbackTransaction() { if (this.#nestedTransactionIndex <= 0) { throw new Error('No transactions in progress'); } const savepointName = `sp${--this.#nestedTransactionIndex}`; this.#postQuery(`rollback to savepoint ${savepointName}`, []); } } exports.GodotSQLiteKyselyWorkerConnection = GodotSQLiteKyselyWorkerConnection;