@firtoz/drizzle-sqlite-wasm 1.0.5 → 1.1.2
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/CHANGELOG.md +34 -0
- package/README.md +9 -1
- package/dist/chunk-6LNYKOKR.js +24 -0
- package/dist/chunk-6LNYKOKR.js.map +1 -0
- package/dist/chunk-7JJHY44Q.js +19 -0
- package/dist/chunk-7JJHY44Q.js.map +1 -0
- package/dist/chunk-AEYHRJVN.js +130 -0
- package/dist/chunk-AEYHRJVN.js.map +1 -0
- package/dist/chunk-AGMKOHXO.js +238 -0
- package/dist/chunk-AGMKOHXO.js.map +1 -0
- package/dist/chunk-BJDPMGFF.js +87 -0
- package/dist/chunk-BJDPMGFF.js.map +1 -0
- package/dist/chunk-BZVMUTJ7.js +49 -0
- package/dist/chunk-BZVMUTJ7.js.map +1 -0
- package/dist/chunk-FIVEPVOM.js +43 -0
- package/dist/chunk-FIVEPVOM.js.map +1 -0
- package/dist/chunk-FRONXNEA.js +123 -0
- package/dist/chunk-FRONXNEA.js.map +1 -0
- package/dist/chunk-GVUNHU6J.js +85 -0
- package/dist/chunk-GVUNHU6J.js.map +1 -0
- package/dist/chunk-H2F2HZ2A.js +22 -0
- package/dist/chunk-H2F2HZ2A.js.map +1 -0
- package/dist/chunk-NSPVPJKE.js +117 -0
- package/dist/chunk-NSPVPJKE.js.map +1 -0
- package/dist/chunk-TZP4AIBR.js +22 -0
- package/dist/chunk-TZP4AIBR.js.map +1 -0
- package/dist/chunk-WFFFP6DB.js +124 -0
- package/dist/chunk-WFFFP6DB.js.map +1 -0
- package/dist/collections/sqlite-collection.d.ts +40 -0
- package/dist/collections/sqlite-collection.js +3 -0
- package/dist/collections/sqlite-collection.js.map +1 -0
- package/dist/collections/synced-sqlite-collection.d.ts +19 -0
- package/dist/collections/synced-sqlite-collection.js +4 -0
- package/dist/collections/synced-sqlite-collection.js.map +1 -0
- package/dist/collections/websocket-collection.d.ts +18 -0
- package/dist/collections/websocket-collection.js +185 -0
- package/dist/collections/websocket-collection.js.map +1 -0
- package/dist/context/DrizzleSqliteProvider.d.ts +50 -0
- package/dist/context/DrizzleSqliteProvider.js +11 -0
- package/dist/context/DrizzleSqliteProvider.js.map +1 -0
- package/dist/context/useDrizzleSqlite.d.ts +23 -0
- package/dist/context/useDrizzleSqlite.js +12 -0
- package/dist/context/useDrizzleSqlite.js.map +1 -0
- package/dist/drizzle/direct.d.ts +8 -0
- package/dist/drizzle/direct.js +4 -0
- package/dist/drizzle/direct.js.map +1 -0
- package/dist/drizzle/handle-callback.d.ts +15 -0
- package/dist/drizzle/handle-callback.js +3 -0
- package/dist/drizzle/handle-callback.js.map +1 -0
- package/dist/drizzle/worker.d.ts +15 -0
- package/dist/drizzle/worker.js +3 -0
- package/dist/drizzle/worker.js.map +1 -0
- package/dist/hooks/useDrizzleSqliteDb.d.ts +24 -0
- package/dist/hooks/useDrizzleSqliteDb.js +9 -0
- package/dist/hooks/useDrizzleSqliteDb.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/migration/migrator.d.ts +7 -0
- package/dist/migration/migrator.js +3 -0
- package/dist/migration/migrator.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/worker/client.d.ts +12 -0
- package/dist/worker/client.js +3 -0
- package/dist/worker/client.js.map +1 -0
- package/dist/worker/global-manager.d.ts +36 -0
- package/dist/worker/global-manager.js +6 -0
- package/dist/worker/global-manager.js.map +1 -0
- package/dist/worker/manager.d.ts +71 -0
- package/dist/worker/manager.js +5 -0
- package/dist/worker/manager.js.map +1 -0
- package/dist/worker/schema.d.ts +125 -0
- package/dist/worker/schema.js +4 -0
- package/dist/worker/schema.js.map +1 -0
- package/dist/worker/sqlite-open-options.d.ts +45 -0
- package/dist/worker/sqlite-open-options.js +3 -0
- package/dist/worker/sqlite-open-options.js.map +1 -0
- package/dist/worker/sqlite.worker.d.ts +2 -0
- package/dist/worker/sqlite.worker.js +196 -0
- package/dist/worker/sqlite.worker.js.map +1 -0
- package/package.json +27 -27
- package/src/collections/sqlite-collection.ts +4 -4
- package/src/hooks/useDrizzleSqliteDb.ts +2 -2
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { SqliteWorkerClientMessageSchema, sqliteWorkerServerMessage, DbIdSchema } from '../chunk-GVUNHU6J.js';
|
|
2
|
+
import '../chunk-6LNYKOKR.js';
|
|
3
|
+
import { handleRemoteCallback } from '../chunk-BJDPMGFF.js';
|
|
4
|
+
import { WorkerHelper } from '@firtoz/worker-helper';
|
|
5
|
+
import { exhaustiveGuard } from '@firtoz/maybe-error';
|
|
6
|
+
|
|
7
|
+
var SqliteWorkerHelper = class extends WorkerHelper {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(self, SqliteWorkerClientMessageSchema, sqliteWorkerServerMessage, {
|
|
10
|
+
handleMessage: (data) => {
|
|
11
|
+
this._handleMessage(data);
|
|
12
|
+
},
|
|
13
|
+
handleInputValidationError: (error, originalData) => {
|
|
14
|
+
console.error("Input validation error", { error, originalData });
|
|
15
|
+
throw new Error(`Invalid input: ${error.message}`);
|
|
16
|
+
},
|
|
17
|
+
handleOutputValidationError: (error, originalData) => {
|
|
18
|
+
console.error("Output validation error", { error, originalData });
|
|
19
|
+
throw new Error(`Invalid output: ${error.message}`);
|
|
20
|
+
},
|
|
21
|
+
handleProcessingError: (error, validatedData) => {
|
|
22
|
+
console.error("Processing error", { error, validatedData });
|
|
23
|
+
throw new Error(`Processing error: ${String(error)}`);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
this.databases = /* @__PURE__ */ new Map();
|
|
27
|
+
this.initPromise = import('@sqlite.org/sqlite-wasm').then(
|
|
28
|
+
async ({ default: sqlite3InitModule }) => {
|
|
29
|
+
const result = await sqlite3InitModule();
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
this.send({
|
|
34
|
+
type: "ready" /* Ready */
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
log(...args) {
|
|
38
|
+
console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}]`, ...args);
|
|
39
|
+
}
|
|
40
|
+
error(...args) {
|
|
41
|
+
console.error(`[${(/* @__PURE__ */ new Date()).toISOString()}]`, ...args);
|
|
42
|
+
}
|
|
43
|
+
// Helper method to process remote callback requests
|
|
44
|
+
async processRemoteCallbackRequest(data, sqliteDb) {
|
|
45
|
+
const result = await handleRemoteCallback({
|
|
46
|
+
sqliteDb,
|
|
47
|
+
sql: data.sql,
|
|
48
|
+
params: data.params,
|
|
49
|
+
method: data.method
|
|
50
|
+
});
|
|
51
|
+
if (result.success) {
|
|
52
|
+
this.send({
|
|
53
|
+
type: "remote-callback-response" /* RemoteCallbackResponse */,
|
|
54
|
+
id: data.id,
|
|
55
|
+
rows: result.result.rows
|
|
56
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
console.error("Error handling remote callback", result.error);
|
|
59
|
+
this.send({
|
|
60
|
+
type: "remote-callback-error" /* RemoteCallbackError */,
|
|
61
|
+
id: data.id,
|
|
62
|
+
error: result.error
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Helper method to checkpoint the database (flush WAL to main DB file)
|
|
67
|
+
async processCheckpointRequest(data, sqliteDb) {
|
|
68
|
+
try {
|
|
69
|
+
sqliteDb.exec({
|
|
70
|
+
sql: "PRAGMA wal_checkpoint(TRUNCATE);",
|
|
71
|
+
callback: () => {
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
this.send({
|
|
75
|
+
type: "checkpoint-complete" /* CheckpointComplete */,
|
|
76
|
+
id: data.id
|
|
77
|
+
});
|
|
78
|
+
} catch (e) {
|
|
79
|
+
const errorMsg = e instanceof Error ? e.message : String(e);
|
|
80
|
+
this.error("Error checkpointing database:", errorMsg);
|
|
81
|
+
this.send({
|
|
82
|
+
type: "checkpoint-error" /* CheckpointError */,
|
|
83
|
+
id: data.id,
|
|
84
|
+
error: errorMsg
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
applyOpenPragmas(db, openOptions) {
|
|
89
|
+
const journalMode = openOptions?.journalMode ?? "WAL";
|
|
90
|
+
const synchronous = openOptions?.synchronous ?? "FULL";
|
|
91
|
+
try {
|
|
92
|
+
db.exec(`PRAGMA journal_mode=${journalMode};`);
|
|
93
|
+
db.exec(`PRAGMA synchronous=${synchronous};`);
|
|
94
|
+
this.log(
|
|
95
|
+
"PRAGMA journal_mode=",
|
|
96
|
+
journalMode,
|
|
97
|
+
"synchronous=",
|
|
98
|
+
synchronous
|
|
99
|
+
);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
this.error("Error applying open pragmas:", e);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async startDatabase(sqlite3, dbName, requestId, openOptions) {
|
|
105
|
+
const dbId = DbIdSchema.parse(crypto.randomUUID());
|
|
106
|
+
const dbFileName = `${dbName}.sqlite3`;
|
|
107
|
+
let db;
|
|
108
|
+
if ("opfs" in sqlite3) {
|
|
109
|
+
db = new sqlite3.oo1.OpfsDb(dbFileName);
|
|
110
|
+
this.log("OPFS database created:", db.filename);
|
|
111
|
+
this.applyOpenPragmas(db, openOptions);
|
|
112
|
+
} else {
|
|
113
|
+
db = new sqlite3.oo1.DB(dbFileName, "c");
|
|
114
|
+
this.log(
|
|
115
|
+
"OPFS is not available, created transient database",
|
|
116
|
+
db.filename
|
|
117
|
+
);
|
|
118
|
+
this.applyOpenPragmas(db, openOptions);
|
|
119
|
+
}
|
|
120
|
+
this.databases.set(dbId, { db, initialized: true });
|
|
121
|
+
this.send({
|
|
122
|
+
type: "started" /* Started */,
|
|
123
|
+
requestId,
|
|
124
|
+
dbId
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async _handleMessage(data) {
|
|
128
|
+
const { type } = data;
|
|
129
|
+
switch (type) {
|
|
130
|
+
case "start" /* Start */:
|
|
131
|
+
{
|
|
132
|
+
const sqlite3 = await this.initPromise;
|
|
133
|
+
await this.startDatabase(
|
|
134
|
+
sqlite3,
|
|
135
|
+
data.dbName,
|
|
136
|
+
data.requestId,
|
|
137
|
+
data.openOptions
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
case "remote-callback-request" /* RemoteCallbackRequest */:
|
|
142
|
+
{
|
|
143
|
+
const dbEntry = this.databases.get(data.dbId);
|
|
144
|
+
if (!dbEntry) {
|
|
145
|
+
this.error(`Database not found for dbId: ${data.dbId}`);
|
|
146
|
+
this.send({
|
|
147
|
+
type: "remote-callback-error" /* RemoteCallbackError */,
|
|
148
|
+
id: data.id,
|
|
149
|
+
error: `Database not found: ${data.dbId}`
|
|
150
|
+
});
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (!dbEntry.initialized) {
|
|
154
|
+
this.error(`Database not initialized for dbId: ${data.dbId}`);
|
|
155
|
+
this.send({
|
|
156
|
+
type: "remote-callback-error" /* RemoteCallbackError */,
|
|
157
|
+
id: data.id,
|
|
158
|
+
error: `Database not initialized: ${data.dbId}`
|
|
159
|
+
});
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
await this.processRemoteCallbackRequest(data, dbEntry.db);
|
|
163
|
+
}
|
|
164
|
+
break;
|
|
165
|
+
case "checkpoint" /* Checkpoint */:
|
|
166
|
+
{
|
|
167
|
+
const dbEntry = this.databases.get(data.dbId);
|
|
168
|
+
if (!dbEntry) {
|
|
169
|
+
this.error(`Database not found for dbId: ${data.dbId}`);
|
|
170
|
+
this.send({
|
|
171
|
+
type: "checkpoint-error" /* CheckpointError */,
|
|
172
|
+
id: data.id,
|
|
173
|
+
error: `Database not found: ${data.dbId}`
|
|
174
|
+
});
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (!dbEntry.initialized) {
|
|
178
|
+
this.error(`Database not initialized for dbId: ${data.dbId}`);
|
|
179
|
+
this.send({
|
|
180
|
+
type: "checkpoint-error" /* CheckpointError */,
|
|
181
|
+
id: data.id,
|
|
182
|
+
error: `Database not initialized: ${data.dbId}`
|
|
183
|
+
});
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
await this.processCheckpointRequest(data, dbEntry.db);
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
default:
|
|
190
|
+
return exhaustiveGuard(type);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
new SqliteWorkerHelper();
|
|
195
|
+
//# sourceMappingURL=sqlite.worker.js.map
|
|
196
|
+
//# sourceMappingURL=sqlite.worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/worker/sqlite.worker.ts"],"names":[],"mappings":"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","file":"sqlite.worker.js","sourcesContent":["import { WorkerHelper } from \"@firtoz/worker-helper\";\nimport {\n\tSqliteWorkerClientMessageSchema,\n\tSqliteWorkerClientMessageType,\n\tsqliteWorkerServerMessage,\n\tSqliteWorkerServerMessageType,\n\ttype SqliteWorkerClientMessage,\n\ttype SqliteWorkerServerMessage,\n\ttype StartRequestId,\n\tDbIdSchema,\n\ttype DbId,\n} from \"./schema\";\nimport { handleRemoteCallback } from \"../drizzle/handle-callback\";\nimport { exhaustiveGuard } from \"@firtoz/maybe-error\";\nimport type { SqliteWasmWorkerOpenOptions } from \"./sqlite-open-options\";\nimport type { Sqlite3Static, Database } from \"../types\";\n\n// Declare self as DedicatedWorkerGlobalScope for TypeScript\ndeclare var self: DedicatedWorkerGlobalScope;\n\nclass SqliteWorkerHelper extends WorkerHelper<\n\tSqliteWorkerClientMessage,\n\tSqliteWorkerServerMessage\n> {\n\tprivate initPromise: Promise<Sqlite3Static>;\n\tprivate databases = new Map<\n\t\tDbId,\n\t\t{\n\t\t\tdb: Database;\n\t\t\tinitialized: boolean;\n\t\t}\n\t>();\n\n\tconstructor() {\n\t\tsuper(self, SqliteWorkerClientMessageSchema, sqliteWorkerServerMessage, {\n\t\t\thandleMessage: (data) => {\n\t\t\t\tthis._handleMessage(data);\n\t\t\t},\n\t\t\thandleInputValidationError: (error, originalData) => {\n\t\t\t\tconsole.error(\"Input validation error\", { error, originalData });\n\t\t\t\tthrow new Error(`Invalid input: ${error.message}`);\n\t\t\t},\n\t\t\thandleOutputValidationError: (error, originalData) => {\n\t\t\t\tconsole.error(\"Output validation error\", { error, originalData });\n\t\t\t\tthrow new Error(`Invalid output: ${error.message}`);\n\t\t\t},\n\t\t\thandleProcessingError: (error, validatedData) => {\n\t\t\t\tconsole.error(\"Processing error\", { error, validatedData });\n\t\t\t\tthrow new Error(`Processing error: ${String(error)}`);\n\t\t\t},\n\t\t});\n\n\t\tthis.initPromise = import(\"@sqlite.org/sqlite-wasm\").then(\n\t\t\tasync ({ default: sqlite3InitModule }) => {\n\t\t\t\tconst result = await sqlite3InitModule();\n\n\t\t\t\treturn result;\n\t\t\t},\n\t\t);\n\n\t\tthis.send({\n\t\t\ttype: SqliteWorkerServerMessageType.Ready,\n\t\t});\n\t}\n\n\tprivate log(...args: unknown[]) {\n\t\tconsole.log(`[${new Date().toISOString()}]`, ...args);\n\t}\n\n\tprivate error(...args: unknown[]) {\n\t\tconsole.error(`[${new Date().toISOString()}]`, ...args);\n\t}\n\n\t// Helper method to process remote callback requests\n\tprivate async processRemoteCallbackRequest(\n\t\tdata: Extract<\n\t\t\tSqliteWorkerClientMessage,\n\t\t\t{ type: SqliteWorkerClientMessageType.RemoteCallbackRequest }\n\t\t>,\n\t\tsqliteDb: Database,\n\t): Promise<void> {\n\t\tconst result = await handleRemoteCallback({\n\t\t\tsqliteDb,\n\t\t\tsql: data.sql,\n\t\t\tparams: data.params,\n\t\t\tmethod: data.method,\n\t\t});\n\n\t\tif (result.success) {\n\t\t\tthis.send({\n\t\t\t\ttype: SqliteWorkerServerMessageType.RemoteCallbackResponse,\n\t\t\t\tid: data.id,\n\t\t\t\trows: result.result.rows,\n\t\t\t});\n\t\t} else {\n\t\t\tconsole.error(\"Error handling remote callback\", result.error);\n\t\t\tthis.send({\n\t\t\t\ttype: SqliteWorkerServerMessageType.RemoteCallbackError,\n\t\t\t\tid: data.id,\n\t\t\t\terror: result.error,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Helper method to checkpoint the database (flush WAL to main DB file)\n\tprivate async processCheckpointRequest(\n\t\tdata: Extract<\n\t\t\tSqliteWorkerClientMessage,\n\t\t\t{ type: SqliteWorkerClientMessageType.Checkpoint }\n\t\t>,\n\t\tsqliteDb: Database,\n\t): Promise<void> {\n\t\ttry {\n\t\t\t// Execute PRAGMA wal_checkpoint(TRUNCATE) to ensure all WAL data\n\t\t\t// is written to the main database file and the WAL is truncated.\n\t\t\t// This ensures persistence to OPFS before page reload.\n\t\t\tsqliteDb.exec({\n\t\t\t\tsql: \"PRAGMA wal_checkpoint(TRUNCATE);\",\n\t\t\t\tcallback: () => {},\n\t\t\t});\n\n\t\t\tthis.send({\n\t\t\t\ttype: SqliteWorkerServerMessageType.CheckpointComplete,\n\t\t\t\tid: data.id,\n\t\t\t});\n\t\t} catch (e: unknown) {\n\t\t\tconst errorMsg = e instanceof Error ? e.message : String(e);\n\t\t\tthis.error(\"Error checkpointing database:\", errorMsg);\n\t\t\tthis.send({\n\t\t\t\ttype: SqliteWorkerServerMessageType.CheckpointError,\n\t\t\t\tid: data.id,\n\t\t\t\terror: errorMsg,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate applyOpenPragmas(\n\t\tdb: Database,\n\t\topenOptions?: SqliteWasmWorkerOpenOptions,\n\t) {\n\t\tconst journalMode = openOptions?.journalMode ?? \"WAL\";\n\t\tconst synchronous = openOptions?.synchronous ?? \"FULL\";\n\t\ttry {\n\t\t\tdb.exec(`PRAGMA journal_mode=${journalMode};`);\n\t\t\tdb.exec(`PRAGMA synchronous=${synchronous};`);\n\t\t\tthis.log(\n\t\t\t\t\"PRAGMA journal_mode=\",\n\t\t\t\tjournalMode,\n\t\t\t\t\"synchronous=\",\n\t\t\t\tsynchronous,\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthis.error(\"Error applying open pragmas:\", e);\n\t\t}\n\t}\n\n\tprivate async startDatabase(\n\t\tsqlite3: Sqlite3Static,\n\t\tdbName: string,\n\t\trequestId: StartRequestId,\n\t\topenOptions?: SqliteWasmWorkerOpenOptions,\n\t) {\n\t\tconst dbId = DbIdSchema.parse(crypto.randomUUID());\n\n\t\tconst dbFileName = `${dbName}.sqlite3`;\n\t\tlet db: Database;\n\n\t\tif (\"opfs\" in sqlite3) {\n\t\t\tdb = new sqlite3.oo1.OpfsDb(dbFileName);\n\t\t\tthis.log(\"OPFS database created:\", db.filename);\n\t\t\tthis.applyOpenPragmas(db, openOptions);\n\t\t} else {\n\t\t\tdb = new sqlite3.oo1.DB(dbFileName, \"c\");\n\t\t\tthis.log(\n\t\t\t\t\"OPFS is not available, created transient database\",\n\t\t\t\tdb.filename,\n\t\t\t);\n\t\t\tthis.applyOpenPragmas(db, openOptions);\n\t\t}\n\n\t\t// Store database with initialized flag\n\t\tthis.databases.set(dbId, { db, initialized: true });\n\n\t\t// Send Started message with dbId and requestId\n\t\tthis.send({\n\t\t\ttype: SqliteWorkerServerMessageType.Started,\n\t\t\trequestId,\n\t\t\tdbId,\n\t\t});\n\t}\n\n\tprivate async _handleMessage(data: SqliteWorkerClientMessage) {\n\t\tconst { type } = data;\n\t\tswitch (type) {\n\t\t\tcase SqliteWorkerClientMessageType.Start:\n\t\t\t\t{\n\t\t\t\t\tconst sqlite3 = await this.initPromise;\n\t\t\t\t\tawait this.startDatabase(\n\t\t\t\t\t\tsqlite3,\n\t\t\t\t\t\tdata.dbName,\n\t\t\t\t\t\tdata.requestId,\n\t\t\t\t\t\tdata.openOptions,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SqliteWorkerClientMessageType.RemoteCallbackRequest:\n\t\t\t\t{\n\t\t\t\t\t// Get the database for this request\n\t\t\t\t\tconst dbEntry = this.databases.get(data.dbId);\n\t\t\t\t\tif (!dbEntry) {\n\t\t\t\t\t\tthis.error(`Database not found for dbId: ${data.dbId}`);\n\t\t\t\t\t\tthis.send({\n\t\t\t\t\t\t\ttype: SqliteWorkerServerMessageType.RemoteCallbackError,\n\t\t\t\t\t\t\tid: data.id,\n\t\t\t\t\t\t\terror: `Database not found: ${data.dbId}`,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!dbEntry.initialized) {\n\t\t\t\t\t\tthis.error(`Database not initialized for dbId: ${data.dbId}`);\n\t\t\t\t\t\tthis.send({\n\t\t\t\t\t\t\ttype: SqliteWorkerServerMessageType.RemoteCallbackError,\n\t\t\t\t\t\t\tid: data.id,\n\t\t\t\t\t\t\terror: `Database not initialized: ${data.dbId}`,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Process the request with the correct database\n\t\t\t\t\tawait this.processRemoteCallbackRequest(data, dbEntry.db);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SqliteWorkerClientMessageType.Checkpoint:\n\t\t\t\t{\n\t\t\t\t\t// Get the database for this request\n\t\t\t\t\tconst dbEntry = this.databases.get(data.dbId);\n\t\t\t\t\tif (!dbEntry) {\n\t\t\t\t\t\tthis.error(`Database not found for dbId: ${data.dbId}`);\n\t\t\t\t\t\tthis.send({\n\t\t\t\t\t\t\ttype: SqliteWorkerServerMessageType.CheckpointError,\n\t\t\t\t\t\t\tid: data.id,\n\t\t\t\t\t\t\terror: `Database not found: ${data.dbId}`,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!dbEntry.initialized) {\n\t\t\t\t\t\tthis.error(`Database not initialized for dbId: ${data.dbId}`);\n\t\t\t\t\t\tthis.send({\n\t\t\t\t\t\t\ttype: SqliteWorkerServerMessageType.CheckpointError,\n\t\t\t\t\t\t\tid: data.id,\n\t\t\t\t\t\t\terror: `Database not initialized: ${data.dbId}`,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Process the checkpoint request\n\t\t\t\t\tawait this.processCheckpointRequest(data, dbEntry.db);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn exhaustiveGuard(type);\n\t\t}\n\t}\n}\n\nnew SqliteWorkerHelper();\n"]}
|
package/package.json
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firtoz/drizzle-sqlite-wasm",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Drizzle SQLite WASM bindings",
|
|
5
|
-
"main": "./
|
|
6
|
-
"module": "./
|
|
7
|
-
"types": "./
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"types": "./
|
|
12
|
-
"import": "./
|
|
13
|
-
"require": "./src/index.ts"
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
14
13
|
},
|
|
15
14
|
"./drizzle-sqlite-wasm-worker": {
|
|
16
|
-
"types": "./
|
|
17
|
-
"import": "./
|
|
18
|
-
"require": "./src/drizzle/worker.ts"
|
|
15
|
+
"types": "./dist/drizzle/worker.d.ts",
|
|
16
|
+
"import": "./dist/drizzle/worker.js"
|
|
19
17
|
},
|
|
20
18
|
"./sqlite-wasm-migrator": {
|
|
21
|
-
"types": "./
|
|
22
|
-
"import": "./
|
|
23
|
-
"require": "./src/migration/migrator.ts"
|
|
19
|
+
"types": "./dist/migration/migrator.d.ts",
|
|
20
|
+
"import": "./dist/migration/migrator.js"
|
|
24
21
|
},
|
|
25
22
|
"./drizzleCollectionOptions": {
|
|
26
|
-
"types": "./
|
|
27
|
-
"import": "./
|
|
28
|
-
"require": "./src/collections/sqlite-collection.ts"
|
|
23
|
+
"types": "./dist/collections/sqlite-collection.d.ts",
|
|
24
|
+
"import": "./dist/collections/sqlite-collection.js"
|
|
29
25
|
},
|
|
30
26
|
"./*": {
|
|
31
|
-
"types": "./
|
|
32
|
-
"import": "./
|
|
33
|
-
"require": "./src/*.ts"
|
|
27
|
+
"types": "./dist/*.d.ts",
|
|
28
|
+
"import": "./dist/*.js"
|
|
34
29
|
}
|
|
35
30
|
},
|
|
36
31
|
"files": [
|
|
32
|
+
"dist/**/*.js",
|
|
33
|
+
"dist/**/*.js.map",
|
|
34
|
+
"dist/**/*.d.ts",
|
|
37
35
|
"src/**/*.ts",
|
|
38
36
|
"!src/**/*.test.ts",
|
|
39
37
|
"README.md",
|
|
40
38
|
"CHANGELOG.md"
|
|
41
39
|
],
|
|
42
40
|
"scripts": {
|
|
41
|
+
"build": "tsup",
|
|
42
|
+
"prepack": "bun run build",
|
|
43
43
|
"typecheck": "tsgo --noEmit -p ./tsconfig.json",
|
|
44
44
|
"lint": "biome check --write src",
|
|
45
45
|
"lint:ci": "biome ci src",
|
|
@@ -69,16 +69,16 @@
|
|
|
69
69
|
"access": "public"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@firtoz/collection-sync": "^
|
|
73
|
-
"@firtoz/db-helpers": "^2.
|
|
74
|
-
"@firtoz/drizzle-utils": "^1.
|
|
75
|
-
"@firtoz/maybe-error": "^1.
|
|
76
|
-
"@firtoz/worker-helper": "^1.
|
|
77
|
-
"@sqlite.org/sqlite-wasm": "^3.51.2-
|
|
78
|
-
"@tanstack/db": "^0.6.
|
|
72
|
+
"@firtoz/collection-sync": "^6.0.1",
|
|
73
|
+
"@firtoz/db-helpers": "^2.2.1",
|
|
74
|
+
"@firtoz/drizzle-utils": "^1.3.1",
|
|
75
|
+
"@firtoz/maybe-error": "^1.6.1",
|
|
76
|
+
"@firtoz/worker-helper": "^1.6.1",
|
|
77
|
+
"@sqlite.org/sqlite-wasm": "^3.51.2-build9",
|
|
78
|
+
"@tanstack/db": "^0.6.5",
|
|
79
79
|
"drizzle-orm": "^0.45.2",
|
|
80
80
|
"drizzle-valibot": "^0.4.2",
|
|
81
|
-
"react": "^19.2.
|
|
81
|
+
"react": "^19.2.5",
|
|
82
82
|
"valibot": "^1.3.1",
|
|
83
83
|
"zod": "^4.3.6"
|
|
84
84
|
},
|
|
@@ -16,7 +16,6 @@ import type {
|
|
|
16
16
|
import {
|
|
17
17
|
createSyncFunction,
|
|
18
18
|
createInsertSchemaWithIdDefault,
|
|
19
|
-
createGetKeyFunction,
|
|
20
19
|
createCollectionConfig,
|
|
21
20
|
createSqliteTableSyncBackend,
|
|
22
21
|
type SQLOperation,
|
|
@@ -90,8 +89,9 @@ export function sqliteCollectionOptions<
|
|
|
90
89
|
|
|
91
90
|
const table = config.drizzle?._.fullSchema[tableName] as TTable;
|
|
92
91
|
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
const getKey = (
|
|
93
|
+
item: InferSchemaOutput<SelectSchema<TTable>>,
|
|
94
|
+
): IdOf<TTable> => (item as { id: IdOf<TTable> }).id;
|
|
95
95
|
|
|
96
96
|
const backend = createSqliteTableSyncBackend({
|
|
97
97
|
drizzle: config.drizzle,
|
|
@@ -108,7 +108,7 @@ export function sqliteCollectionOptions<
|
|
|
108
108
|
readyPromise: config.readyPromise,
|
|
109
109
|
syncMode: config.syncMode,
|
|
110
110
|
debug: config.debug,
|
|
111
|
-
getSyncPersistKey: (item
|
|
111
|
+
getSyncPersistKey: (item) => String(getKey(item)),
|
|
112
112
|
};
|
|
113
113
|
|
|
114
114
|
const syncResult = createSyncFunction(baseSyncConfig, backend);
|
|
@@ -2,11 +2,11 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
|
|
2
2
|
import {
|
|
3
3
|
customSqliteMigrate,
|
|
4
4
|
type DurableSqliteMigrationConfig,
|
|
5
|
-
} from "
|
|
5
|
+
} from "../migration/migrator";
|
|
6
6
|
import {
|
|
7
7
|
drizzleSqliteWasmWorker,
|
|
8
8
|
createInstrumentedDrizzle,
|
|
9
|
-
} from "
|
|
9
|
+
} from "../drizzle/worker";
|
|
10
10
|
import type { ISqliteWorkerClient } from "../worker/manager";
|
|
11
11
|
import {
|
|
12
12
|
initializeSqliteWorker,
|