@korajs/store 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/better-sqlite3.cjs +166 -0
- package/dist/adapters/better-sqlite3.cjs.map +1 -0
- package/dist/adapters/better-sqlite3.d.cts +31 -0
- package/dist/adapters/better-sqlite3.d.ts +31 -0
- package/dist/adapters/better-sqlite3.js +117 -0
- package/dist/adapters/better-sqlite3.js.map +1 -0
- package/dist/adapters/indexeddb.cjs +550 -0
- package/dist/adapters/indexeddb.cjs.map +1 -0
- package/dist/adapters/indexeddb.d.cts +52 -0
- package/dist/adapters/indexeddb.d.ts +52 -0
- package/dist/adapters/indexeddb.js +205 -0
- package/dist/adapters/indexeddb.js.map +1 -0
- package/dist/adapters/sqlite-wasm-worker.cjs +215 -0
- package/dist/adapters/sqlite-wasm-worker.cjs.map +1 -0
- package/dist/adapters/sqlite-wasm-worker.d.cts +2 -0
- package/dist/adapters/sqlite-wasm-worker.d.ts +2 -0
- package/dist/adapters/sqlite-wasm-worker.js +191 -0
- package/dist/adapters/sqlite-wasm-worker.js.map +1 -0
- package/dist/adapters/sqlite-wasm.cjs +354 -0
- package/dist/adapters/sqlite-wasm.cjs.map +1 -0
- package/dist/adapters/sqlite-wasm.d.cts +68 -0
- package/dist/adapters/sqlite-wasm.d.ts +68 -0
- package/dist/adapters/sqlite-wasm.js +14 -0
- package/dist/adapters/sqlite-wasm.js.map +1 -0
- package/dist/chunk-DXKLAQ6P.js +111 -0
- package/dist/chunk-DXKLAQ6P.js.map +1 -0
- package/dist/chunk-LAWV6CFH.js +62 -0
- package/dist/chunk-LAWV6CFH.js.map +1 -0
- package/dist/chunk-ZP5AXQ3Z.js +179 -0
- package/dist/chunk-ZP5AXQ3Z.js.map +1 -0
- package/dist/index.cjs +1288 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +376 -0
- package/dist/index.d.ts +376 -0
- package/dist/index.js +1194 -0
- package/dist/index.js.map +1 -0
- package/dist/sqlite-wasm-channel-46AOWNPM.js +10 -0
- package/dist/sqlite-wasm-channel-46AOWNPM.js.map +1 -0
- package/dist/sqlite-wasm-channel-Lakjuk2E.d.cts +104 -0
- package/dist/sqlite-wasm-channel-Lakjuk2E.d.ts +104 -0
- package/dist/types-DF-KDSK1.d.cts +106 -0
- package/dist/types-DF-KDSK1.d.ts +106 -0
- package/package.json +95 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// src/adapters/sqlite-wasm-worker.ts
|
|
2
|
+
var db = null;
|
|
3
|
+
var sqlite3Api = null;
|
|
4
|
+
function sendResponse(response) {
|
|
5
|
+
self.postMessage(response);
|
|
6
|
+
}
|
|
7
|
+
function handleExecute(id, sql, params) {
|
|
8
|
+
if (!db) {
|
|
9
|
+
sendResponse({ id, type: "error", message: "Database is not open", code: "DB_NOT_OPEN" });
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
db.exec({ sql, bind: params });
|
|
14
|
+
sendResponse({ id, type: "success" });
|
|
15
|
+
} catch (error) {
|
|
16
|
+
sendResponse({ id, type: "error", message: error.message, code: "EXEC_ERROR" });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function handleQuery(id, sql, params) {
|
|
20
|
+
if (!db) {
|
|
21
|
+
sendResponse({ id, type: "error", message: "Database is not open", code: "DB_NOT_OPEN" });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const rows = [];
|
|
26
|
+
db.exec({
|
|
27
|
+
sql,
|
|
28
|
+
bind: params,
|
|
29
|
+
rowMode: "object",
|
|
30
|
+
callback: (row) => {
|
|
31
|
+
rows.push({ ...row });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
sendResponse({ id, type: "success", data: rows });
|
|
35
|
+
} catch (error) {
|
|
36
|
+
sendResponse({ id, type: "error", message: error.message, code: "QUERY_ERROR" });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function handleOpen(id, ddlStatements) {
|
|
40
|
+
try {
|
|
41
|
+
const sqlite3InitModule = (await import("@sqlite.org/sqlite-wasm")).default;
|
|
42
|
+
const sqlite3 = await sqlite3InitModule();
|
|
43
|
+
sqlite3Api = sqlite3;
|
|
44
|
+
let useOpfs = false;
|
|
45
|
+
if (sqlite3.installOpfsSAHPoolVfs) {
|
|
46
|
+
try {
|
|
47
|
+
const pool = await sqlite3.installOpfsSAHPoolVfs({ name: "kora-opfs" });
|
|
48
|
+
db = new pool.OpfsSAHPoolDb("kora.db");
|
|
49
|
+
useOpfs = true;
|
|
50
|
+
} catch {
|
|
51
|
+
console.warn("[kora] OPFS unavailable, falling back to in-memory SQLite");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (!useOpfs) {
|
|
55
|
+
db = new sqlite3.oo1.DB({ filename: ":memory:" });
|
|
56
|
+
}
|
|
57
|
+
db?.exec({ sql: "PRAGMA journal_mode = WAL" });
|
|
58
|
+
db?.exec({ sql: "PRAGMA foreign_keys = ON" });
|
|
59
|
+
for (const sql of ddlStatements) {
|
|
60
|
+
db?.exec({ sql });
|
|
61
|
+
}
|
|
62
|
+
sendResponse({ id, type: "success" });
|
|
63
|
+
} catch (error) {
|
|
64
|
+
sendResponse({
|
|
65
|
+
id,
|
|
66
|
+
type: "error",
|
|
67
|
+
message: error.message,
|
|
68
|
+
code: "INIT_ERROR"
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function handleClose(id) {
|
|
73
|
+
if (db) {
|
|
74
|
+
db.close();
|
|
75
|
+
db = null;
|
|
76
|
+
}
|
|
77
|
+
sendResponse({ id, type: "success" });
|
|
78
|
+
}
|
|
79
|
+
function handleImport(id, data) {
|
|
80
|
+
if (!db) {
|
|
81
|
+
sendResponse({ id, type: "error", message: "Database is not open", code: "DB_NOT_OPEN" });
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const dbWithDeserialize = db;
|
|
85
|
+
if (typeof dbWithDeserialize.deserialize === "function") {
|
|
86
|
+
try {
|
|
87
|
+
dbWithDeserialize.deserialize(data);
|
|
88
|
+
sendResponse({ id, type: "success" });
|
|
89
|
+
return;
|
|
90
|
+
} catch (error) {
|
|
91
|
+
sendResponse({ id, type: "error", message: error.message, code: "IMPORT_ERROR" });
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const sqlite3 = sqlite3Api;
|
|
96
|
+
if (!sqlite3 || typeof sqlite3.capi?.sqlite3_deserialize === "undefined") {
|
|
97
|
+
sendResponse({
|
|
98
|
+
id,
|
|
99
|
+
type: "error",
|
|
100
|
+
message: "Import not supported in this SQLite WASM runtime",
|
|
101
|
+
code: "IMPORT_NOT_SUPPORTED"
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
sendResponse({
|
|
106
|
+
id,
|
|
107
|
+
type: "error",
|
|
108
|
+
message: "Import requires runtime-specific deserialize wiring and is unavailable in this worker build",
|
|
109
|
+
code: "IMPORT_NOT_SUPPORTED"
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function handleMessage(request) {
|
|
113
|
+
try {
|
|
114
|
+
switch (request.type) {
|
|
115
|
+
case "open":
|
|
116
|
+
handleOpen(request.id, request.ddlStatements);
|
|
117
|
+
return;
|
|
118
|
+
case "close":
|
|
119
|
+
handleClose(request.id);
|
|
120
|
+
return;
|
|
121
|
+
case "execute":
|
|
122
|
+
handleExecute(request.id, request.sql, request.params);
|
|
123
|
+
return;
|
|
124
|
+
case "query":
|
|
125
|
+
handleQuery(request.id, request.sql, request.params);
|
|
126
|
+
return;
|
|
127
|
+
case "begin":
|
|
128
|
+
handleExecute(request.id, "BEGIN");
|
|
129
|
+
return;
|
|
130
|
+
case "commit":
|
|
131
|
+
handleExecute(request.id, "COMMIT");
|
|
132
|
+
return;
|
|
133
|
+
case "rollback":
|
|
134
|
+
handleExecute(request.id, "ROLLBACK");
|
|
135
|
+
return;
|
|
136
|
+
case "migrate":
|
|
137
|
+
if (!db) {
|
|
138
|
+
sendResponse({
|
|
139
|
+
id: request.id,
|
|
140
|
+
type: "error",
|
|
141
|
+
message: "Database is not open",
|
|
142
|
+
code: "DB_NOT_OPEN"
|
|
143
|
+
});
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
for (const sql of request.statements) {
|
|
148
|
+
db.exec({ sql });
|
|
149
|
+
}
|
|
150
|
+
sendResponse({ id: request.id, type: "success" });
|
|
151
|
+
} catch (error) {
|
|
152
|
+
sendResponse({
|
|
153
|
+
id: request.id,
|
|
154
|
+
type: "error",
|
|
155
|
+
message: error.message,
|
|
156
|
+
code: "MIGRATE_ERROR"
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
160
|
+
case "export":
|
|
161
|
+
sendResponse({
|
|
162
|
+
id: request.id,
|
|
163
|
+
type: "error",
|
|
164
|
+
message: "Export not yet supported in browser worker",
|
|
165
|
+
code: "EXPORT_NOT_SUPPORTED"
|
|
166
|
+
});
|
|
167
|
+
return;
|
|
168
|
+
case "import":
|
|
169
|
+
handleImport(request.id, request.data);
|
|
170
|
+
return;
|
|
171
|
+
default:
|
|
172
|
+
sendResponse({
|
|
173
|
+
id: request.id,
|
|
174
|
+
type: "error",
|
|
175
|
+
message: "Unknown request type",
|
|
176
|
+
code: "UNKNOWN_REQUEST"
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
} catch (error) {
|
|
180
|
+
sendResponse({
|
|
181
|
+
id: request.id,
|
|
182
|
+
type: "error",
|
|
183
|
+
message: error.message,
|
|
184
|
+
code: "WORKER_ERROR"
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
self.onmessage = (event) => {
|
|
189
|
+
handleMessage(event.data);
|
|
190
|
+
};
|
|
191
|
+
//# sourceMappingURL=sqlite-wasm-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/sqlite-wasm-worker.ts"],"sourcesContent":["/// <reference lib=\"webworker\" />\n/**\n * Web Worker script for running SQLite WASM.\n *\n * This file is intended to run inside a Web Worker in browsers.\n * It loads @sqlite.org/sqlite-wasm, initializes SQLite with OPFS persistence\n * (falling back to in-memory if unavailable), and processes messages from\n * the main thread via the WorkerRequest/WorkerResponse protocol.\n *\n * This script cannot be tested in Node.js — it is validated in E2E browser tests.\n */\n\nimport type { WorkerRequest, WorkerResponse } from './sqlite-wasm-channel'\n\ninterface SqliteDb {\n\texec(opts: {\n\t\tsql: string\n\t\tbind?: unknown[]\n\t\treturnValue?: string\n\t\trowMode?: string\n\t\tcallback?: (row: Record<string, unknown>) => void\n\t}): void\n\tclose(): void\n\tdeserialize?: (data: Uint8Array) => void\n}\n\ndeclare const self: DedicatedWorkerGlobalScope\n\nlet db: SqliteDb | null = null\nlet sqlite3Api: unknown = null\n\nfunction sendResponse(response: WorkerResponse): void {\n\tself.postMessage(response)\n}\n\nfunction handleExecute(id: number, sql: string, params?: unknown[]): void {\n\tif (!db) {\n\t\tsendResponse({ id, type: 'error', message: 'Database is not open', code: 'DB_NOT_OPEN' })\n\t\treturn\n\t}\n\ttry {\n\t\tdb.exec({ sql, bind: params })\n\t\tsendResponse({ id, type: 'success' })\n\t} catch (error) {\n\t\tsendResponse({ id, type: 'error', message: (error as Error).message, code: 'EXEC_ERROR' })\n\t}\n}\n\nfunction handleQuery(id: number, sql: string, params?: unknown[]): void {\n\tif (!db) {\n\t\tsendResponse({ id, type: 'error', message: 'Database is not open', code: 'DB_NOT_OPEN' })\n\t\treturn\n\t}\n\ttry {\n\t\tconst rows: Record<string, unknown>[] = []\n\t\tdb.exec({\n\t\t\tsql,\n\t\t\tbind: params,\n\t\t\trowMode: 'object',\n\t\t\tcallback: (row: Record<string, unknown>) => {\n\t\t\t\trows.push({ ...row })\n\t\t\t},\n\t\t})\n\t\tsendResponse({ id, type: 'success', data: rows })\n\t} catch (error) {\n\t\tsendResponse({ id, type: 'error', message: (error as Error).message, code: 'QUERY_ERROR' })\n\t}\n}\n\nasync function handleOpen(id: number, ddlStatements: string[]): Promise<void> {\n\ttry {\n\t\tconst sqlite3InitModule = (await import('@sqlite.org/sqlite-wasm')).default\n\t\tconst sqlite3 = await sqlite3InitModule()\n\t\tsqlite3Api = sqlite3\n\n\t\t// Try OPFS persistence first\n\t\tlet useOpfs = false\n\t\tif (sqlite3.installOpfsSAHPoolVfs) {\n\t\t\ttry {\n\t\t\t\tconst pool = await sqlite3.installOpfsSAHPoolVfs({ name: 'kora-opfs' })\n\t\t\t\tdb = new pool.OpfsSAHPoolDb('kora.db')\n\t\t\t\tuseOpfs = true\n\t\t\t} catch {\n\t\t\t\t// OPFS unavailable, fall back to in-memory\n\t\t\t\tconsole.warn('[kora] OPFS unavailable, falling back to in-memory SQLite')\n\t\t\t}\n\t\t}\n\n\t\tif (!useOpfs) {\n\t\t\tdb = new sqlite3.oo1.DB({ filename: ':memory:' })\n\t\t}\n\n\t\t// Set pragmas\n\t\tdb?.exec({ sql: 'PRAGMA journal_mode = WAL' })\n\t\tdb?.exec({ sql: 'PRAGMA foreign_keys = ON' })\n\n\t\t// Execute DDL statements\n\t\tfor (const sql of ddlStatements) {\n\t\t\tdb?.exec({ sql })\n\t\t}\n\n\t\tsendResponse({ id, type: 'success' })\n\t} catch (error) {\n\t\tsendResponse({\n\t\t\tid,\n\t\t\ttype: 'error',\n\t\t\tmessage: (error as Error).message,\n\t\t\tcode: 'INIT_ERROR',\n\t\t})\n\t}\n}\n\nfunction handleClose(id: number): void {\n\tif (db) {\n\t\tdb.close()\n\t\tdb = null\n\t}\n\tsendResponse({ id, type: 'success' })\n}\n\nfunction handleImport(id: number, data: Uint8Array): void {\n\tif (!db) {\n\t\tsendResponse({ id, type: 'error', message: 'Database is not open', code: 'DB_NOT_OPEN' })\n\t\treturn\n\t}\n\n\tconst dbWithDeserialize = db as SqliteDb & { deserialize?: (bytes: Uint8Array) => void }\n\tif (typeof dbWithDeserialize.deserialize === 'function') {\n\t\ttry {\n\t\t\tdbWithDeserialize.deserialize(data)\n\t\t\tsendResponse({ id, type: 'success' })\n\t\t\treturn\n\t\t} catch (error) {\n\t\t\tsendResponse({ id, type: 'error', message: (error as Error).message, code: 'IMPORT_ERROR' })\n\t\t\treturn\n\t\t}\n\t}\n\n\tconst sqlite3 = sqlite3Api as\n\t\t| {\n\t\t\t\too1?: { DB?: new (...args: unknown[]) => SqliteDb }\n\t\t\t\tcapi?: { sqlite3_deserialize?: unknown }\n\t\t\t}\n\t\t| null\n\n\tif (!sqlite3 || typeof sqlite3.capi?.sqlite3_deserialize === 'undefined') {\n\t\tsendResponse({\n\t\t\tid,\n\t\t\ttype: 'error',\n\t\t\tmessage: 'Import not supported in this SQLite WASM runtime',\n\t\t\tcode: 'IMPORT_NOT_SUPPORTED',\n\t\t})\n\t\treturn\n\t}\n\n\tsendResponse({\n\t\tid,\n\t\ttype: 'error',\n\t\tmessage: 'Import requires runtime-specific deserialize wiring and is unavailable in this worker build',\n\t\tcode: 'IMPORT_NOT_SUPPORTED',\n\t})\n}\n\nfunction handleMessage(request: WorkerRequest): void {\n\ttry {\n\t\tswitch (request.type) {\n\t\t\tcase 'open':\n\t\t\t\t// open is async due to WASM loading\n\t\t\t\thandleOpen(request.id, request.ddlStatements)\n\t\t\t\treturn\n\t\t\tcase 'close':\n\t\t\t\thandleClose(request.id)\n\t\t\t\treturn\n\t\t\tcase 'execute':\n\t\t\t\thandleExecute(request.id, request.sql, request.params)\n\t\t\t\treturn\n\t\t\tcase 'query':\n\t\t\t\thandleQuery(request.id, request.sql, request.params)\n\t\t\t\treturn\n\t\t\tcase 'begin':\n\t\t\t\thandleExecute(request.id, 'BEGIN')\n\t\t\t\treturn\n\t\t\tcase 'commit':\n\t\t\t\thandleExecute(request.id, 'COMMIT')\n\t\t\t\treturn\n\t\t\tcase 'rollback':\n\t\t\t\thandleExecute(request.id, 'ROLLBACK')\n\t\t\t\treturn\n\t\t\tcase 'migrate':\n\t\t\t\tif (!db) {\n\t\t\t\t\tsendResponse({\n\t\t\t\t\t\tid: request.id,\n\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\tmessage: 'Database is not open',\n\t\t\t\t\t\tcode: 'DB_NOT_OPEN',\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tfor (const sql of request.statements) {\n\t\t\t\t\t\tdb.exec({ sql })\n\t\t\t\t\t}\n\t\t\t\t\tsendResponse({ id: request.id, type: 'success' })\n\t\t\t\t} catch (error) {\n\t\t\t\t\tsendResponse({\n\t\t\t\t\t\tid: request.id,\n\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\tmessage: (error as Error).message,\n\t\t\t\t\t\tcode: 'MIGRATE_ERROR',\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\tcase 'export':\n\t\t\t\t// Export is not trivially supported via the oo1 API in the browser.\n\t\t\t\t// In a real implementation, we'd use the C API's sqlite3_serialize.\n\t\t\t\tsendResponse({\n\t\t\t\t\tid: request.id,\n\t\t\t\t\ttype: 'error',\n\t\t\t\t\tmessage: 'Export not yet supported in browser worker',\n\t\t\t\t\tcode: 'EXPORT_NOT_SUPPORTED',\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\tcase 'import':\n\t\t\t\thandleImport(request.id, request.data)\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\tsendResponse({\n\t\t\t\t\tid: (request as WorkerRequest).id,\n\t\t\t\t\ttype: 'error',\n\t\t\t\t\tmessage: 'Unknown request type',\n\t\t\t\t\tcode: 'UNKNOWN_REQUEST',\n\t\t\t\t})\n\t\t}\n\t} catch (error) {\n\t\tsendResponse({\n\t\t\tid: request.id,\n\t\t\ttype: 'error',\n\t\t\tmessage: (error as Error).message,\n\t\t\tcode: 'WORKER_ERROR',\n\t\t})\n\t}\n}\n\n// Listen for messages from the main thread\nself.onmessage = (event: MessageEvent<WorkerRequest>) => {\n\thandleMessage(event.data)\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res) => function __init() {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
};
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
|
|
23
|
+
// src/errors.ts
|
|
24
|
+
var import_core, AdapterError, StoreNotOpenError, WorkerTimeoutError;
|
|
25
|
+
var init_errors = __esm({
|
|
26
|
+
"src/errors.ts"() {
|
|
27
|
+
"use strict";
|
|
28
|
+
import_core = require("@korajs/core");
|
|
29
|
+
AdapterError = class extends import_core.KoraError {
|
|
30
|
+
constructor(message, context) {
|
|
31
|
+
super(message, "ADAPTER_ERROR", context);
|
|
32
|
+
this.name = "AdapterError";
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
StoreNotOpenError = class extends import_core.KoraError {
|
|
36
|
+
constructor() {
|
|
37
|
+
super("Store is not open. Call store.open() before performing operations.", "STORE_NOT_OPEN");
|
|
38
|
+
this.name = "StoreNotOpenError";
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
WorkerTimeoutError = class extends import_core.KoraError {
|
|
42
|
+
constructor(operation, timeoutMs) {
|
|
43
|
+
super(
|
|
44
|
+
`Worker did not respond within ${timeoutMs}ms for operation "${operation}"`,
|
|
45
|
+
"WORKER_TIMEOUT",
|
|
46
|
+
{ operation, timeoutMs }
|
|
47
|
+
);
|
|
48
|
+
this.name = "WorkerTimeoutError";
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// src/adapters/sqlite-wasm-channel.ts
|
|
55
|
+
var sqlite_wasm_channel_exports = {};
|
|
56
|
+
__export(sqlite_wasm_channel_exports, {
|
|
57
|
+
Mutex: () => Mutex,
|
|
58
|
+
WebWorkerBridge: () => WebWorkerBridge
|
|
59
|
+
});
|
|
60
|
+
var Mutex, WebWorkerBridge;
|
|
61
|
+
var init_sqlite_wasm_channel = __esm({
|
|
62
|
+
"src/adapters/sqlite-wasm-channel.ts"() {
|
|
63
|
+
"use strict";
|
|
64
|
+
init_errors();
|
|
65
|
+
Mutex = class {
|
|
66
|
+
locked = false;
|
|
67
|
+
waiters = [];
|
|
68
|
+
/**
|
|
69
|
+
* Acquire the mutex. Returns a release function.
|
|
70
|
+
* If the mutex is already held, the caller waits until it's released.
|
|
71
|
+
*/
|
|
72
|
+
async acquire() {
|
|
73
|
+
if (!this.locked) {
|
|
74
|
+
this.locked = true;
|
|
75
|
+
return this.createRelease();
|
|
76
|
+
}
|
|
77
|
+
return new Promise((resolve) => {
|
|
78
|
+
this.waiters.push(() => {
|
|
79
|
+
resolve(this.createRelease());
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
createRelease() {
|
|
84
|
+
let released = false;
|
|
85
|
+
return () => {
|
|
86
|
+
if (released) return;
|
|
87
|
+
released = true;
|
|
88
|
+
const next = this.waiters.shift();
|
|
89
|
+
if (next) {
|
|
90
|
+
next();
|
|
91
|
+
} else {
|
|
92
|
+
this.locked = false;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
WebWorkerBridge = class {
|
|
98
|
+
worker;
|
|
99
|
+
pending = /* @__PURE__ */ new Map();
|
|
100
|
+
nextId = 1;
|
|
101
|
+
terminated = false;
|
|
102
|
+
timeoutMs;
|
|
103
|
+
/**
|
|
104
|
+
* @param workerUrl - URL to the sqlite-wasm-worker script
|
|
105
|
+
* @param timeoutMs - Timeout for worker responses in milliseconds (default: 30000)
|
|
106
|
+
*/
|
|
107
|
+
constructor(workerUrl, timeoutMs = 3e4) {
|
|
108
|
+
this.timeoutMs = timeoutMs;
|
|
109
|
+
this.worker = new Worker(workerUrl, { type: "module" });
|
|
110
|
+
this.worker.onmessage = (event) => {
|
|
111
|
+
const response = event.data;
|
|
112
|
+
const entry = this.pending.get(response.id);
|
|
113
|
+
if (entry) {
|
|
114
|
+
this.pending.delete(response.id);
|
|
115
|
+
entry.resolve(response);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
this.worker.onerror = (event) => {
|
|
119
|
+
const error = new Error(`Worker error: ${event.message}`);
|
|
120
|
+
for (const [id, entry] of this.pending) {
|
|
121
|
+
this.pending.delete(id);
|
|
122
|
+
entry.reject(error);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
async send(request) {
|
|
127
|
+
if (this.terminated) {
|
|
128
|
+
return {
|
|
129
|
+
id: request.id,
|
|
130
|
+
type: "error",
|
|
131
|
+
message: "Worker has been terminated",
|
|
132
|
+
code: "WORKER_TERMINATED"
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const id = this.nextId++;
|
|
136
|
+
const req = { ...request, id };
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
const timer = setTimeout(() => {
|
|
139
|
+
this.pending.delete(id);
|
|
140
|
+
reject(new WorkerTimeoutError(req.type, this.timeoutMs));
|
|
141
|
+
}, this.timeoutMs);
|
|
142
|
+
this.pending.set(id, {
|
|
143
|
+
resolve: (response) => {
|
|
144
|
+
clearTimeout(timer);
|
|
145
|
+
resolve(response);
|
|
146
|
+
},
|
|
147
|
+
reject: (error) => {
|
|
148
|
+
clearTimeout(timer);
|
|
149
|
+
reject(error);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
this.worker.postMessage(req);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
terminate() {
|
|
156
|
+
if (this.terminated) return;
|
|
157
|
+
this.terminated = true;
|
|
158
|
+
this.worker.terminate();
|
|
159
|
+
for (const [id, entry] of this.pending) {
|
|
160
|
+
this.pending.delete(id);
|
|
161
|
+
entry.reject(new Error("Worker terminated"));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// src/adapters/sqlite-wasm.ts
|
|
169
|
+
var sqlite_wasm_exports = {};
|
|
170
|
+
__export(sqlite_wasm_exports, {
|
|
171
|
+
Mutex: () => Mutex,
|
|
172
|
+
SqliteWasmAdapter: () => SqliteWasmAdapter,
|
|
173
|
+
WebWorkerBridge: () => WebWorkerBridge
|
|
174
|
+
});
|
|
175
|
+
module.exports = __toCommonJS(sqlite_wasm_exports);
|
|
176
|
+
|
|
177
|
+
// src/adapters/sqlite-wasm-adapter.ts
|
|
178
|
+
var import_core2 = require("@korajs/core");
|
|
179
|
+
init_errors();
|
|
180
|
+
init_sqlite_wasm_channel();
|
|
181
|
+
var SqliteWasmAdapter = class {
|
|
182
|
+
bridge = null;
|
|
183
|
+
opened = false;
|
|
184
|
+
mutex = new Mutex();
|
|
185
|
+
injectedBridge;
|
|
186
|
+
workerUrl;
|
|
187
|
+
dbName;
|
|
188
|
+
constructor(options = {}) {
|
|
189
|
+
this.injectedBridge = options.bridge;
|
|
190
|
+
this.workerUrl = options.workerUrl;
|
|
191
|
+
this.dbName = options.dbName ?? "kora-db";
|
|
192
|
+
}
|
|
193
|
+
async open(schema) {
|
|
194
|
+
if (this.opened) return;
|
|
195
|
+
if (this.injectedBridge) {
|
|
196
|
+
this.bridge = this.injectedBridge;
|
|
197
|
+
} else if (this.workerUrl) {
|
|
198
|
+
const { WebWorkerBridge: WebWorkerBridge2 } = await Promise.resolve().then(() => (init_sqlite_wasm_channel(), sqlite_wasm_channel_exports));
|
|
199
|
+
this.bridge = new WebWorkerBridge2(this.workerUrl);
|
|
200
|
+
} else {
|
|
201
|
+
throw new AdapterError(
|
|
202
|
+
'SqliteWasmAdapter requires either a bridge (for testing) or a workerUrl (for browsers). Pass { bridge: new MockWorkerBridge() } for tests, or { workerUrl: "/worker.js" } for browsers.'
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
const ddlStatements = (0, import_core2.generateFullDDL)(schema);
|
|
206
|
+
const response = await this.sendRequest({ id: 0, type: "open", ddlStatements });
|
|
207
|
+
if (response.type === "error") {
|
|
208
|
+
throw new AdapterError(`Failed to open database: ${response.message}`, {
|
|
209
|
+
code: response.code,
|
|
210
|
+
dbName: this.dbName
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
this.opened = true;
|
|
214
|
+
}
|
|
215
|
+
async close() {
|
|
216
|
+
if (!this.bridge) return;
|
|
217
|
+
try {
|
|
218
|
+
await this.sendRequest({ id: 0, type: "close" });
|
|
219
|
+
} finally {
|
|
220
|
+
this.bridge.terminate();
|
|
221
|
+
this.bridge = null;
|
|
222
|
+
this.opened = false;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async execute(sql, params) {
|
|
226
|
+
this.guardOpen();
|
|
227
|
+
const response = await this.sendRequest({ id: 0, type: "execute", sql, params });
|
|
228
|
+
if (response.type === "error") {
|
|
229
|
+
throw new AdapterError(`Execute failed: ${response.message}`, { sql, params });
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async query(sql, params) {
|
|
233
|
+
this.guardOpen();
|
|
234
|
+
const response = await this.sendRequest({ id: 0, type: "query", sql, params });
|
|
235
|
+
if (response.type === "error") {
|
|
236
|
+
throw new AdapterError(`Query failed: ${response.message}`, { sql, params });
|
|
237
|
+
}
|
|
238
|
+
return response.data ?? [];
|
|
239
|
+
}
|
|
240
|
+
async transaction(fn) {
|
|
241
|
+
this.guardOpen();
|
|
242
|
+
const release = await this.mutex.acquire();
|
|
243
|
+
try {
|
|
244
|
+
await this.sendChecked({ id: 0, type: "begin" }, "BEGIN transaction");
|
|
245
|
+
const tx = {
|
|
246
|
+
execute: async (sql, params) => {
|
|
247
|
+
const response = await this.sendRequest({ id: 0, type: "execute", sql, params });
|
|
248
|
+
if (response.type === "error") {
|
|
249
|
+
throw new AdapterError(`Transaction execute failed: ${response.message}`, {
|
|
250
|
+
sql,
|
|
251
|
+
params
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
query: async (sql, params) => {
|
|
256
|
+
const response = await this.sendRequest({ id: 0, type: "query", sql, params });
|
|
257
|
+
if (response.type === "error") {
|
|
258
|
+
throw new AdapterError(`Transaction query failed: ${response.message}`, { sql, params });
|
|
259
|
+
}
|
|
260
|
+
return response.data ?? [];
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
await fn(tx);
|
|
264
|
+
await this.sendChecked({ id: 0, type: "commit" }, "COMMIT transaction");
|
|
265
|
+
} catch (error) {
|
|
266
|
+
try {
|
|
267
|
+
await this.sendRequest({ id: 0, type: "rollback" });
|
|
268
|
+
} catch {
|
|
269
|
+
}
|
|
270
|
+
throw error;
|
|
271
|
+
} finally {
|
|
272
|
+
release();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
async migrate(from, to, migration) {
|
|
276
|
+
this.guardOpen();
|
|
277
|
+
const release = await this.mutex.acquire();
|
|
278
|
+
try {
|
|
279
|
+
await this.sendChecked({ id: 0, type: "begin" }, "BEGIN migration");
|
|
280
|
+
for (const sql of migration.statements) {
|
|
281
|
+
const response = await this.sendRequest({ id: 0, type: "execute", sql });
|
|
282
|
+
if (response.type === "error") {
|
|
283
|
+
throw new AdapterError(`Migration from v${from} to v${to} failed: ${response.message}`, {
|
|
284
|
+
from,
|
|
285
|
+
to
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
await this.sendChecked({ id: 0, type: "commit" }, "COMMIT migration");
|
|
290
|
+
} catch (error) {
|
|
291
|
+
try {
|
|
292
|
+
await this.sendRequest({ id: 0, type: "rollback" });
|
|
293
|
+
} catch {
|
|
294
|
+
}
|
|
295
|
+
if (error instanceof AdapterError) throw error;
|
|
296
|
+
throw new AdapterError(
|
|
297
|
+
`Migration from v${from} to v${to} failed: ${error.message}`,
|
|
298
|
+
{ from, to }
|
|
299
|
+
);
|
|
300
|
+
} finally {
|
|
301
|
+
release();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Export the database as a Uint8Array (for IndexedDB persistence).
|
|
306
|
+
* Only available when the database is open.
|
|
307
|
+
*/
|
|
308
|
+
async exportDatabase() {
|
|
309
|
+
this.guardOpen();
|
|
310
|
+
const response = await this.sendRequest({ id: 0, type: "export" });
|
|
311
|
+
if (response.type === "error") {
|
|
312
|
+
throw new AdapterError(`Export failed: ${response.message}`);
|
|
313
|
+
}
|
|
314
|
+
return response.data;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Import a serialized database snapshot.
|
|
318
|
+
*/
|
|
319
|
+
async importDatabase(data) {
|
|
320
|
+
this.guardOpen();
|
|
321
|
+
const response = await this.sendRequest({ id: 0, type: "import", data });
|
|
322
|
+
if (response.type === "error") {
|
|
323
|
+
throw new AdapterError(`Import failed: ${response.message}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
guardOpen() {
|
|
327
|
+
if (!this.opened || !this.bridge) {
|
|
328
|
+
throw new StoreNotOpenError();
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
async sendRequest(request) {
|
|
332
|
+
const bridge = this.bridge;
|
|
333
|
+
if (!bridge) {
|
|
334
|
+
throw new StoreNotOpenError();
|
|
335
|
+
}
|
|
336
|
+
return bridge.send(request);
|
|
337
|
+
}
|
|
338
|
+
async sendChecked(request, description) {
|
|
339
|
+
const response = await this.sendRequest(request);
|
|
340
|
+
if (response.type === "error") {
|
|
341
|
+
throw new AdapterError(`${description} failed: ${response.message}`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
// src/adapters/sqlite-wasm.ts
|
|
347
|
+
init_sqlite_wasm_channel();
|
|
348
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
349
|
+
0 && (module.exports = {
|
|
350
|
+
Mutex,
|
|
351
|
+
SqliteWasmAdapter,
|
|
352
|
+
WebWorkerBridge
|
|
353
|
+
});
|
|
354
|
+
//# sourceMappingURL=sqlite-wasm.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/errors.ts","../../src/adapters/sqlite-wasm-channel.ts","../../src/adapters/sqlite-wasm.ts","../../src/adapters/sqlite-wasm-adapter.ts"],"sourcesContent":["import { KoraError } from '@korajs/core'\n\n/**\n * Thrown when a query is invalid (bad field names, invalid operators, etc.).\n */\nexport class QueryError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'QUERY_ERROR', context)\n\t\tthis.name = 'QueryError'\n\t}\n}\n\n/**\n * Thrown when a record is not found by ID (findById, update, delete on missing record).\n */\nexport class RecordNotFoundError extends KoraError {\n\tconstructor(collection: string, recordId: string) {\n\t\tsuper(`Record \"${recordId}\" not found in collection \"${collection}\"`, 'RECORD_NOT_FOUND', {\n\t\t\tcollection,\n\t\t\trecordId,\n\t\t})\n\t\tthis.name = 'RecordNotFoundError'\n\t}\n}\n\n/**\n * Thrown when a storage adapter operation fails.\n */\nexport class AdapterError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'ADAPTER_ERROR', context)\n\t\tthis.name = 'AdapterError'\n\t}\n}\n\n/**\n * Thrown when an operation is attempted on a store that has not been opened.\n */\nexport class StoreNotOpenError extends KoraError {\n\tconstructor() {\n\t\tsuper('Store is not open. Call store.open() before performing operations.', 'STORE_NOT_OPEN')\n\t\tthis.name = 'StoreNotOpenError'\n\t}\n}\n\n/**\n * Thrown when the Web Worker fails to initialize (WASM load failure, OPFS unavailable, etc.).\n */\nexport class WorkerInitError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(`Worker initialization failed: ${message}`, 'WORKER_INIT_ERROR', context)\n\t\tthis.name = 'WorkerInitError'\n\t}\n}\n\n/**\n * Thrown when the Web Worker does not respond within the configured timeout.\n */\nexport class WorkerTimeoutError extends KoraError {\n\tconstructor(operation: string, timeoutMs: number) {\n\t\tsuper(\n\t\t\t`Worker did not respond within ${timeoutMs}ms for operation \"${operation}\"`,\n\t\t\t'WORKER_TIMEOUT',\n\t\t\t{ operation, timeoutMs },\n\t\t)\n\t\tthis.name = 'WorkerTimeoutError'\n\t}\n}\n\n/**\n * Thrown when IndexedDB persistence operations fail (serialize/deserialize).\n */\nexport class PersistenceError extends KoraError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(`Persistence error: ${message}`, 'PERSISTENCE_ERROR', context)\n\t\tthis.name = 'PersistenceError'\n\t}\n}\n","/// <reference lib=\"dom\" />\nimport { WorkerTimeoutError } from '../errors'\n\n// === Message Protocol ===\n\n/**\n * Request message sent from the main thread to the SQLite WASM worker.\n * Each request carries a unique `id` for response correlation.\n */\nexport type WorkerRequest =\n\t| { id: number; type: 'open'; ddlStatements: string[] }\n\t| { id: number; type: 'close' }\n\t| { id: number; type: 'execute'; sql: string; params?: unknown[] }\n\t| { id: number; type: 'query'; sql: string; params?: unknown[] }\n\t| { id: number; type: 'begin' }\n\t| { id: number; type: 'commit' }\n\t| { id: number; type: 'rollback' }\n\t| { id: number; type: 'migrate'; from: number; to: number; statements: string[] }\n\t| { id: number; type: 'export' }\n\t| { id: number; type: 'import'; data: Uint8Array }\n\n/**\n * Response message sent from the worker back to the main thread.\n * Matches the request `id` for correlation.\n */\nexport type WorkerResponse =\n\t| { id: number; type: 'success'; data?: unknown }\n\t| { id: number; type: 'error'; message: string; code: string; context?: Record<string, unknown> }\n\n// === WorkerBridge Interface ===\n\n/**\n * Abstraction over the communication channel with the SQLite WASM worker.\n * In browsers, this is backed by a real Web Worker via MessagePort.\n * In Node.js tests, this is backed by better-sqlite3 via MockWorkerBridge.\n */\nexport interface WorkerBridge {\n\t/** Send a request to the worker and wait for a response. */\n\tsend(request: WorkerRequest): Promise<WorkerResponse>\n\n\t/** Terminate the worker. Safe to call multiple times. */\n\tterminate(): void\n}\n\n// === Mutex ===\n\n/**\n * Async mutex for serializing transaction access across the async worker boundary.\n * Only one transaction may be active at a time.\n */\nexport class Mutex {\n\tprivate locked = false\n\tprivate waiters: Array<() => void> = []\n\n\t/**\n\t * Acquire the mutex. Returns a release function.\n\t * If the mutex is already held, the caller waits until it's released.\n\t */\n\tasync acquire(): Promise<() => void> {\n\t\tif (!this.locked) {\n\t\t\tthis.locked = true\n\t\t\treturn this.createRelease()\n\t\t}\n\n\t\treturn new Promise<() => void>((resolve) => {\n\t\t\tthis.waiters.push(() => {\n\t\t\t\tresolve(this.createRelease())\n\t\t\t})\n\t\t})\n\t}\n\n\tprivate createRelease(): () => void {\n\t\tlet released = false\n\t\treturn () => {\n\t\t\tif (released) return\n\t\t\treleased = true\n\t\t\tconst next = this.waiters.shift()\n\t\t\tif (next) {\n\t\t\t\tnext()\n\t\t\t} else {\n\t\t\t\tthis.locked = false\n\t\t\t}\n\t\t}\n\t}\n}\n\n// === WebWorkerBridge ===\n\n/**\n * WorkerBridge implementation for browser environments.\n * Communicates with an actual Web Worker running SQLite WASM.\n */\nexport class WebWorkerBridge implements WorkerBridge {\n\tprivate worker: Worker\n\tprivate pending = new Map<\n\t\tnumber,\n\t\t{ resolve: (r: WorkerResponse) => void; reject: (e: Error) => void }\n\t>()\n\tprivate nextId = 1\n\tprivate terminated = false\n\tprivate timeoutMs: number\n\n\t/**\n\t * @param workerUrl - URL to the sqlite-wasm-worker script\n\t * @param timeoutMs - Timeout for worker responses in milliseconds (default: 30000)\n\t */\n\tconstructor(workerUrl: string | URL, timeoutMs = 30000) {\n\t\tthis.timeoutMs = timeoutMs\n\t\tthis.worker = new Worker(workerUrl, { type: 'module' })\n\t\tthis.worker.onmessage = (event: MessageEvent<WorkerResponse>) => {\n\t\t\tconst response = event.data\n\t\t\tconst entry = this.pending.get(response.id)\n\t\t\tif (entry) {\n\t\t\t\tthis.pending.delete(response.id)\n\t\t\t\tentry.resolve(response)\n\t\t\t}\n\t\t}\n\t\tthis.worker.onerror = (event) => {\n\t\t\t// Reject all pending requests on worker error\n\t\t\tconst error = new Error(`Worker error: ${event.message}`)\n\t\t\tfor (const [id, entry] of this.pending) {\n\t\t\t\tthis.pending.delete(id)\n\t\t\t\tentry.reject(error)\n\t\t\t}\n\t\t}\n\t}\n\n\tasync send(request: WorkerRequest): Promise<WorkerResponse> {\n\t\tif (this.terminated) {\n\t\t\treturn {\n\t\t\t\tid: request.id,\n\t\t\t\ttype: 'error',\n\t\t\t\tmessage: 'Worker has been terminated',\n\t\t\t\tcode: 'WORKER_TERMINATED',\n\t\t\t}\n\t\t}\n\n\t\tconst id = this.nextId++\n\t\tconst req = { ...request, id }\n\n\t\treturn new Promise<WorkerResponse>((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.pending.delete(id)\n\t\t\t\treject(new WorkerTimeoutError(req.type, this.timeoutMs))\n\t\t\t}, this.timeoutMs)\n\n\t\t\tthis.pending.set(id, {\n\t\t\t\tresolve: (response) => {\n\t\t\t\t\tclearTimeout(timer)\n\t\t\t\t\tresolve(response)\n\t\t\t\t},\n\t\t\t\treject: (error) => {\n\t\t\t\t\tclearTimeout(timer)\n\t\t\t\t\treject(error)\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tthis.worker.postMessage(req)\n\t\t})\n\t}\n\n\tterminate(): void {\n\t\tif (this.terminated) return\n\t\tthis.terminated = true\n\t\tthis.worker.terminate()\n\t\t// Reject any pending requests\n\t\tfor (const [id, entry] of this.pending) {\n\t\t\tthis.pending.delete(id)\n\t\t\tentry.reject(new Error('Worker terminated'))\n\t\t}\n\t}\n}\n","// Entry point for @korajs/store/sqlite-wasm\nexport { SqliteWasmAdapter } from './sqlite-wasm-adapter'\nexport type { SqliteWasmAdapterOptions } from './sqlite-wasm-adapter'\nexport { WebWorkerBridge, Mutex } from './sqlite-wasm-channel'\nexport type { WorkerBridge, WorkerRequest, WorkerResponse } from './sqlite-wasm-channel'\n","import { generateFullDDL } from '@korajs/core'\nimport type { SchemaDefinition } from '@korajs/core'\nimport { AdapterError, StoreNotOpenError } from '../errors'\nimport type { MigrationPlan, StorageAdapter, Transaction } from '../types'\nimport { Mutex } from './sqlite-wasm-channel'\nimport type { WorkerBridge, WorkerRequest, WorkerResponse } from './sqlite-wasm-channel'\n\n/**\n * Options for creating a SqliteWasmAdapter.\n */\nexport interface SqliteWasmAdapterOptions {\n\t/**\n\t * Injected WorkerBridge for testing. If omitted, a WebWorkerBridge is created\n\t * in browser environments.\n\t */\n\tbridge?: WorkerBridge\n\n\t/**\n\t * Database name for persistence. Used as the OPFS file name or IDB key.\n\t */\n\tdbName?: string\n\n\t/**\n\t * URL to the sqlite-wasm-worker script. Required in browsers if no bridge is provided.\n\t */\n\tworkerUrl?: string | URL\n}\n\n/**\n * SQLite WASM adapter that communicates with a SQLite instance through a WorkerBridge.\n *\n * In browsers, the bridge is backed by a Web Worker running SQLite WASM with OPFS persistence.\n * In Node.js tests, the bridge is backed by MockWorkerBridge wrapping better-sqlite3.\n *\n * @example\n * ```typescript\n * // Browser usage\n * const adapter = new SqliteWasmAdapter({ workerUrl: '/sqlite-wasm-worker.js' })\n *\n * // Test usage with MockWorkerBridge\n * import { MockWorkerBridge } from './sqlite-wasm-mock-bridge'\n * const adapter = new SqliteWasmAdapter({ bridge: new MockWorkerBridge() })\n * ```\n */\nexport class SqliteWasmAdapter implements StorageAdapter {\n\tprivate bridge: WorkerBridge | null = null\n\tprivate opened = false\n\tprivate readonly mutex = new Mutex()\n\tprivate readonly injectedBridge: WorkerBridge | undefined\n\tprivate readonly workerUrl: string | URL | undefined\n\tprivate readonly dbName: string\n\n\tconstructor(options: SqliteWasmAdapterOptions = {}) {\n\t\tthis.injectedBridge = options.bridge\n\t\tthis.workerUrl = options.workerUrl\n\t\tthis.dbName = options.dbName ?? 'kora-db'\n\t}\n\n\tasync open(schema: SchemaDefinition): Promise<void> {\n\t\tif (this.opened) return\n\n\t\tif (this.injectedBridge) {\n\t\t\tthis.bridge = this.injectedBridge\n\t\t} else if (this.workerUrl) {\n\t\t\t// Dynamic import to avoid loading WebWorkerBridge in Node.js\n\t\t\tconst { WebWorkerBridge } = await import('./sqlite-wasm-channel')\n\t\t\tthis.bridge = new WebWorkerBridge(this.workerUrl)\n\t\t} else {\n\t\t\tthrow new AdapterError(\n\t\t\t\t'SqliteWasmAdapter requires either a bridge (for testing) or a workerUrl (for browsers). ' +\n\t\t\t\t\t'Pass { bridge: new MockWorkerBridge() } for tests, or { workerUrl: \"/worker.js\" } for browsers.',\n\t\t\t)\n\t\t}\n\n\t\tconst ddlStatements = generateFullDDL(schema)\n\t\tconst response = await this.sendRequest({ id: 0, type: 'open', ddlStatements })\n\t\tif (response.type === 'error') {\n\t\t\tthrow new AdapterError(`Failed to open database: ${response.message}`, {\n\t\t\t\tcode: response.code,\n\t\t\t\tdbName: this.dbName,\n\t\t\t})\n\t\t}\n\t\tthis.opened = true\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (!this.bridge) return\n\n\t\ttry {\n\t\t\tawait this.sendRequest({ id: 0, type: 'close' })\n\t\t} finally {\n\t\t\tthis.bridge.terminate()\n\t\t\tthis.bridge = null\n\t\t\tthis.opened = false\n\t\t}\n\t}\n\n\tasync execute(sql: string, params?: unknown[]): Promise<void> {\n\t\tthis.guardOpen()\n\t\tconst response = await this.sendRequest({ id: 0, type: 'execute', sql, params })\n\t\tif (response.type === 'error') {\n\t\t\tthrow new AdapterError(`Execute failed: ${response.message}`, { sql, params })\n\t\t}\n\t}\n\n\tasync query<T>(sql: string, params?: unknown[]): Promise<T[]> {\n\t\tthis.guardOpen()\n\t\tconst response = await this.sendRequest({ id: 0, type: 'query', sql, params })\n\t\tif (response.type === 'error') {\n\t\t\tthrow new AdapterError(`Query failed: ${response.message}`, { sql, params })\n\t\t}\n\t\treturn (response.data as T[]) ?? []\n\t}\n\n\tasync transaction(fn: (tx: Transaction) => Promise<void>): Promise<void> {\n\t\tthis.guardOpen()\n\n\t\tconst release = await this.mutex.acquire()\n\t\ttry {\n\t\t\tawait this.sendChecked({ id: 0, type: 'begin' }, 'BEGIN transaction')\n\n\t\t\tconst tx: Transaction = {\n\t\t\t\texecute: async (sql: string, params?: unknown[]): Promise<void> => {\n\t\t\t\t\tconst response = await this.sendRequest({ id: 0, type: 'execute', sql, params })\n\t\t\t\t\tif (response.type === 'error') {\n\t\t\t\t\t\tthrow new AdapterError(`Transaction execute failed: ${response.message}`, {\n\t\t\t\t\t\t\tsql,\n\t\t\t\t\t\t\tparams,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tquery: async <T>(sql: string, params?: unknown[]): Promise<T[]> => {\n\t\t\t\t\tconst response = await this.sendRequest({ id: 0, type: 'query', sql, params })\n\t\t\t\t\tif (response.type === 'error') {\n\t\t\t\t\t\tthrow new AdapterError(`Transaction query failed: ${response.message}`, { sql, params })\n\t\t\t\t\t}\n\t\t\t\t\treturn (response.data as T[]) ?? []\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tawait fn(tx)\n\t\t\tawait this.sendChecked({ id: 0, type: 'commit' }, 'COMMIT transaction')\n\t\t} catch (error) {\n\t\t\t// Attempt rollback, but don't mask the original error\n\t\t\ttry {\n\t\t\t\tawait this.sendRequest({ id: 0, type: 'rollback' })\n\t\t\t} catch {\n\t\t\t\t// Rollback failure is secondary to the original error\n\t\t\t}\n\t\t\tthrow error\n\t\t} finally {\n\t\t\trelease()\n\t\t}\n\t}\n\n\tasync migrate(from: number, to: number, migration: MigrationPlan): Promise<void> {\n\t\tthis.guardOpen()\n\n\t\tconst release = await this.mutex.acquire()\n\t\ttry {\n\t\t\tawait this.sendChecked({ id: 0, type: 'begin' }, 'BEGIN migration')\n\n\t\t\tfor (const sql of migration.statements) {\n\t\t\t\tconst response = await this.sendRequest({ id: 0, type: 'execute', sql })\n\t\t\t\tif (response.type === 'error') {\n\t\t\t\t\tthrow new AdapterError(`Migration from v${from} to v${to} failed: ${response.message}`, {\n\t\t\t\t\t\tfrom,\n\t\t\t\t\t\tto,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait this.sendChecked({ id: 0, type: 'commit' }, 'COMMIT migration')\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait this.sendRequest({ id: 0, type: 'rollback' })\n\t\t\t} catch {\n\t\t\t\t// Rollback failure is secondary\n\t\t\t}\n\t\t\tif (error instanceof AdapterError) throw error\n\t\t\tthrow new AdapterError(\n\t\t\t\t`Migration from v${from} to v${to} failed: ${(error as Error).message}`,\n\t\t\t\t{ from, to },\n\t\t\t)\n\t\t} finally {\n\t\t\trelease()\n\t\t}\n\t}\n\n\t/**\n\t * Export the database as a Uint8Array (for IndexedDB persistence).\n\t * Only available when the database is open.\n\t */\n\tasync exportDatabase(): Promise<Uint8Array> {\n\t\tthis.guardOpen()\n\t\tconst response = await this.sendRequest({ id: 0, type: 'export' })\n\t\tif (response.type === 'error') {\n\t\t\tthrow new AdapterError(`Export failed: ${response.message}`)\n\t\t}\n\t\treturn response.data as Uint8Array\n\t}\n\n\t/**\n\t * Import a serialized database snapshot.\n\t */\n\tasync importDatabase(data: Uint8Array): Promise<void> {\n\t\tthis.guardOpen()\n\t\tconst response = await this.sendRequest({ id: 0, type: 'import', data })\n\t\tif (response.type === 'error') {\n\t\t\tthrow new AdapterError(`Import failed: ${response.message}`)\n\t\t}\n\t}\n\n\tprivate guardOpen(): void {\n\t\tif (!this.opened || !this.bridge) {\n\t\t\tthrow new StoreNotOpenError()\n\t\t}\n\t}\n\n\tprivate async sendRequest(request: WorkerRequest): Promise<WorkerResponse> {\n\t\t// guardOpen() is always called before sendRequest, so bridge is guaranteed non-null\n\t\tconst bridge = this.bridge\n\t\tif (!bridge) {\n\t\t\tthrow new StoreNotOpenError()\n\t\t}\n\t\treturn bridge.send(request)\n\t}\n\n\tprivate async sendChecked(request: WorkerRequest, description: string): Promise<void> {\n\t\tconst response = await this.sendRequest(request)\n\t\tif (response.type === 'error') {\n\t\t\tthrow new AdapterError(`${description} failed: ${response.message}`)\n\t\t}\n\t}\n}\n"],"mappings":"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","names":["import_core","WebWorkerBridge"]}
|