@sqlite-sync/core 0.12.3 → 0.13.1
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/{reset-state-t0tTGqoh.js → crdt-sync-producer-BY-WobgO.js} +55 -241
- package/dist/crdt-sync-producer-BY-WobgO.js.map +1 -0
- package/dist/{crdt-sync-remote-source-CPXzmSIS.js → crdt-sync-remote-source-yeTEkOjH.js} +344 -12
- package/dist/crdt-sync-remote-source-yeTEkOjH.js.map +1 -0
- package/dist/{crdt-table-schema-BRm_WdcW.js → crdt-table-schema-D6Yf61Ex.js} +37 -13
- package/dist/crdt-table-schema-D6Yf61Ex.js.map +1 -0
- package/dist/{index-BHsKLqcK.d.ts → index-CH4lf3iX.d.ts} +166 -72
- package/dist/index.common-C8W9VKSY.js +276 -0
- package/dist/index.common-C8W9VKSY.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +20 -677
- package/dist/index.js.map +1 -1
- package/dist/index.native.d.ts +2 -0
- package/dist/index.native.js +9 -0
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +2 -2
- package/dist/local.d.ts +48 -0
- package/dist/local.js +255 -0
- package/dist/local.js.map +1 -0
- package/dist/{make-crdt-table-C6l0F-o_.js → make-crdt-table-DYCXOYB7.js} +13 -14
- package/dist/make-crdt-table-DYCXOYB7.js.map +1 -0
- package/dist/reset-state-CPOi_45B.js +220 -0
- package/dist/reset-state-CPOi_45B.js.map +1 -0
- package/dist/server.d.ts +8 -3
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/sqlite-reactive-db-DLS1xRZp.js +296 -0
- package/dist/sqlite-reactive-db-DLS1xRZp.js.map +1 -0
- package/dist/synced-db-database-B5M7MrBD.js +81 -0
- package/dist/synced-db-database-B5M7MrBD.js.map +1 -0
- package/dist/{system-schema-Dvl_BLId.js → system-schema-CXf3FmxN.js} +142 -58
- package/dist/system-schema-CXf3FmxN.js.map +1 -0
- package/dist/worker.d.ts +2 -10
- package/dist/worker.js +11 -177
- package/dist/worker.js.map +1 -1
- package/dist/ws-remote-source-BbPWrHB6.js +161 -0
- package/dist/ws-remote-source-BbPWrHB6.js.map +1 -0
- package/dist/ws-remote-source-DFBhDc6Z.d.ts +12 -0
- package/package.json +9 -1
- package/dist/crdt-sync-remote-source-CPXzmSIS.js.map +0 -1
- package/dist/crdt-table-schema-BRm_WdcW.js.map +0 -1
- package/dist/make-crdt-table-C6l0F-o_.js.map +0 -1
- package/dist/reset-state-t0tTGqoh.js.map +0 -1
- package/dist/system-schema-Dvl_BLId.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as parseTableName, t as CRDT_EVENT_NO_OP_PAYLOAD } from "./crdt-table-schema-
|
|
1
|
+
import { f as parseTableName, p as quoteId, t as CRDT_EVENT_NO_OP_PAYLOAD } from "./crdt-table-schema-D6Yf61Ex.js";
|
|
2
2
|
import { DummyDriver, Kysely, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler, sql } from "kysely";
|
|
3
3
|
//#region src/dummy-kysely.ts
|
|
4
4
|
const dummyKysely = new Kysely({ dialect: {
|
|
@@ -75,27 +75,68 @@ const startPerformanceLogger = (logger, level = "info") => {
|
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
77
|
//#endregion
|
|
78
|
+
//#region src/bound-map.ts
|
|
79
|
+
var BoundMap = class {
|
|
80
|
+
map = /* @__PURE__ */ new Map();
|
|
81
|
+
maxSize;
|
|
82
|
+
onRemove;
|
|
83
|
+
constructor(opts) {
|
|
84
|
+
this.maxSize = opts.maxSize;
|
|
85
|
+
this.onRemove = opts.onRemove;
|
|
86
|
+
}
|
|
87
|
+
set = (key, value) => {
|
|
88
|
+
if (this.onRemove && this.map.has(key)) {
|
|
89
|
+
const old = this.map.get(key);
|
|
90
|
+
this.map.set(key, value);
|
|
91
|
+
this.onRemove(key, old);
|
|
92
|
+
} else this.map.set(key, value);
|
|
93
|
+
if (this.map.size > this.maxSize) {
|
|
94
|
+
const firstKey = this.map.keys().next().value;
|
|
95
|
+
this.delete(firstKey);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
get = (key) => {
|
|
99
|
+
return this.map.get(key);
|
|
100
|
+
};
|
|
101
|
+
delete = (key) => {
|
|
102
|
+
if (this.onRemove && this.map.has(key)) {
|
|
103
|
+
const value = this.map.get(key);
|
|
104
|
+
this.map.delete(key);
|
|
105
|
+
this.onRemove(key, value);
|
|
106
|
+
} else this.map.delete(key);
|
|
107
|
+
};
|
|
108
|
+
clear = () => {
|
|
109
|
+
const onRemove = this.onRemove;
|
|
110
|
+
if (onRemove) this.map.forEach((value, key) => {
|
|
111
|
+
onRemove(key, value);
|
|
112
|
+
});
|
|
113
|
+
this.map.clear();
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
//#endregion
|
|
78
117
|
//#region src/sqlite-db-wrapper.ts
|
|
118
|
+
const TRANSACTION_CONTROL_PATTERN = /^(?:\s|--[^\n]*\n|\/\*[\s\S]*?\*\/)*(?:begin|commit|end|rollback|savepoint|release)\b/i;
|
|
79
119
|
var SQLiteDbWrapper = class {
|
|
80
|
-
|
|
81
|
-
sqlite3;
|
|
120
|
+
driver;
|
|
82
121
|
logger;
|
|
83
122
|
loggerPrefix;
|
|
84
123
|
loadedDbSchema = null;
|
|
85
|
-
dataPointers = [];
|
|
86
124
|
preparedStatements = [];
|
|
87
125
|
preparedStatementsMap = /* @__PURE__ */ new Map();
|
|
88
126
|
preparedRawStatementsMap = /* @__PURE__ */ new Map();
|
|
127
|
+
readonlyStatementCache = new BoundMap({
|
|
128
|
+
maxSize: 500,
|
|
129
|
+
onRemove: void 0
|
|
130
|
+
});
|
|
89
131
|
afterMutatingStatement = null;
|
|
90
132
|
constructor(opts) {
|
|
91
|
-
this.
|
|
92
|
-
this.sqlite3 = opts.sqlite3;
|
|
133
|
+
this.driver = opts.driver;
|
|
93
134
|
this.logger = opts.logger;
|
|
94
135
|
this.loggerPrefix = opts.loggerPrefix;
|
|
95
136
|
}
|
|
96
|
-
get
|
|
97
|
-
if (!this.
|
|
98
|
-
return this.
|
|
137
|
+
get ensureDriver() {
|
|
138
|
+
if (!this.driver) throw new Error("Database is already closed");
|
|
139
|
+
return this.driver;
|
|
99
140
|
}
|
|
100
141
|
get dbSchema() {
|
|
101
142
|
if (!this.loadedDbSchema) this.loadedDbSchema = introspectDb(this);
|
|
@@ -103,31 +144,21 @@ var SQLiteDbWrapper = class {
|
|
|
103
144
|
}
|
|
104
145
|
executeSql(sql, bind, loggerLevel, skipAfterMutatingStatement) {
|
|
105
146
|
const perf = startPerformanceLogger(this.logger, loggerLevel);
|
|
106
|
-
const
|
|
147
|
+
const driver = this.ensureDriver;
|
|
148
|
+
const statement = driver.prepare(sql);
|
|
107
149
|
let transaction;
|
|
108
150
|
try {
|
|
109
|
-
const
|
|
110
|
-
if (!statementPointer) throw new Error("Prepared statement is already finalized");
|
|
111
|
-
const afterMutatingStatement = !skipAfterMutatingStatement && this.afterMutatingStatement && this.sqlite3.capi.sqlite3_stmt_readonly(statementPointer) === 0 ? this.afterMutatingStatement : null;
|
|
151
|
+
const afterMutatingStatement = !skipAfterMutatingStatement && this.afterMutatingStatement && !this.isReadonlyStatement(statement, sql) ? this.afterMutatingStatement : null;
|
|
112
152
|
let totalChangesBefore = 0;
|
|
113
153
|
if (afterMutatingStatement) {
|
|
114
154
|
transaction = this.beginStatementTransaction();
|
|
115
|
-
totalChangesBefore =
|
|
116
|
-
}
|
|
117
|
-
if (bind && bind.length > 0) statement.bind(bind);
|
|
118
|
-
const rows = [];
|
|
119
|
-
let columnNames;
|
|
120
|
-
while (statement.step()) {
|
|
121
|
-
columnNames ??= statement.getColumnNames([]);
|
|
122
|
-
const values = statement.get([]);
|
|
123
|
-
const row = Object.create(null);
|
|
124
|
-
for (let index = 0; index < columnNames.length; index++) row[columnNames[index]] = values[index];
|
|
125
|
-
rows.push(row);
|
|
155
|
+
totalChangesBefore = driver.totalChanges();
|
|
126
156
|
}
|
|
157
|
+
const rows = toRowObjects(statement.run(bind ?? []), () => Object.create(null));
|
|
127
158
|
statement.finalize();
|
|
128
159
|
perf.logEnd(`${this.loggerPrefix ?? ""}:query`, sql, loggerLevel);
|
|
129
160
|
if (transaction) {
|
|
130
|
-
if (
|
|
161
|
+
if (driver.totalChanges() !== totalChangesBefore) afterMutatingStatement?.(this);
|
|
131
162
|
transaction.commit();
|
|
132
163
|
}
|
|
133
164
|
return { rows };
|
|
@@ -137,6 +168,24 @@ var SQLiteDbWrapper = class {
|
|
|
137
168
|
throw error;
|
|
138
169
|
}
|
|
139
170
|
}
|
|
171
|
+
isReadonlyStatement(statement, sql) {
|
|
172
|
+
if (statement.readonly !== void 0) return statement.readonly;
|
|
173
|
+
let readonly = this.readonlyStatementCache.get(sql);
|
|
174
|
+
if (readonly === void 0) {
|
|
175
|
+
readonly = TRANSACTION_CONTROL_PATTERN.test(sql) || this.isReadonlyByTablesUsed(sql);
|
|
176
|
+
this.readonlyStatementCache.set(sql, readonly);
|
|
177
|
+
}
|
|
178
|
+
return readonly;
|
|
179
|
+
}
|
|
180
|
+
isReadonlyByTablesUsed(sql) {
|
|
181
|
+
const tables = this.executePreparedRaw({
|
|
182
|
+
key: "$tables-used-writes",
|
|
183
|
+
sql: `select "wr" from tables_used(?)`,
|
|
184
|
+
params: [sql],
|
|
185
|
+
meta: { loggerLevel: "system" }
|
|
186
|
+
});
|
|
187
|
+
return tables.length > 0 && tables.every((table) => !table.wr);
|
|
188
|
+
}
|
|
140
189
|
execute(opts, options) {
|
|
141
190
|
const sql = typeof opts === "string" ? opts : opts.sql;
|
|
142
191
|
const bind = typeof opts === "string" ? void 0 : opts.parameters;
|
|
@@ -157,9 +206,6 @@ var SQLiteDbWrapper = class {
|
|
|
157
206
|
throw error;
|
|
158
207
|
}
|
|
159
208
|
}
|
|
160
|
-
isInTransaction() {
|
|
161
|
-
return this.sqlite3.capi.sqlite3_get_autocommit(this.ensureDb) === 0;
|
|
162
|
-
}
|
|
163
209
|
beginTransaction() {
|
|
164
210
|
this.executePreparedRaw({
|
|
165
211
|
key: "$begin-transaction",
|
|
@@ -184,7 +230,6 @@ var SQLiteDbWrapper = class {
|
|
|
184
230
|
};
|
|
185
231
|
}
|
|
186
232
|
beginStatementTransaction() {
|
|
187
|
-
if (!this.isInTransaction()) return this.beginTransaction();
|
|
188
233
|
this.executePreparedRaw({
|
|
189
234
|
key: "$begin-statement-savepoint",
|
|
190
235
|
sql: "savepoint sqlite_sync_statement",
|
|
@@ -214,26 +259,15 @@ var SQLiteDbWrapper = class {
|
|
|
214
259
|
}
|
|
215
260
|
prepare(sql, opts) {
|
|
216
261
|
const perf = startPerformanceLogger(this.logger, opts?.loggerLevel);
|
|
217
|
-
const stmt = this.
|
|
262
|
+
const stmt = this.ensureDriver.prepare(sql);
|
|
218
263
|
perf.logEnd(`${this.loggerPrefix ?? ""}:prepare`, sql, opts?.loggerLevel);
|
|
219
264
|
let isFinalized = false;
|
|
220
265
|
const execute = (params) => {
|
|
221
266
|
if (isFinalized) throw new Error("Statement is finalized");
|
|
222
267
|
const perf = startPerformanceLogger(this.logger, opts?.loggerLevel);
|
|
223
268
|
try {
|
|
224
|
-
|
|
225
|
-
const results = [];
|
|
226
|
-
let columnNames;
|
|
227
|
-
while (stmt.step()) {
|
|
228
|
-
columnNames ??= stmt.getColumnNames([]);
|
|
229
|
-
const values = stmt.get([]);
|
|
230
|
-
const row = {};
|
|
231
|
-
for (let index = 0; index < columnNames.length; index++) row[columnNames[index]] = values[index];
|
|
232
|
-
results.push(row);
|
|
233
|
-
}
|
|
234
|
-
return results;
|
|
269
|
+
return toRowObjects(stmt.run(params), () => ({}));
|
|
235
270
|
} finally {
|
|
236
|
-
stmt.reset(true);
|
|
237
271
|
perf.logEnd(`${this.loggerPrefix ?? ""}:prepare-execute`, sql, opts?.loggerLevel);
|
|
238
272
|
}
|
|
239
273
|
};
|
|
@@ -289,11 +323,11 @@ var SQLiteDbWrapper = class {
|
|
|
289
323
|
});
|
|
290
324
|
}
|
|
291
325
|
createScalarFunction({ name, callback, deterministic, directOnly, innocuous }) {
|
|
292
|
-
|
|
326
|
+
const driver = this.ensureDriver;
|
|
327
|
+
if (!driver.createScalarFunction) throw new Error("This SQLite driver does not support scalar functions");
|
|
328
|
+
driver.createScalarFunction({
|
|
293
329
|
name,
|
|
294
|
-
|
|
295
|
-
return callback(...args);
|
|
296
|
-
},
|
|
330
|
+
callback: (...args) => callback(...args),
|
|
297
331
|
arity: callback.length,
|
|
298
332
|
deterministic,
|
|
299
333
|
directOnly,
|
|
@@ -302,15 +336,16 @@ var SQLiteDbWrapper = class {
|
|
|
302
336
|
}
|
|
303
337
|
useSnapshot(snapshot) {
|
|
304
338
|
const perf = startPerformanceLogger(this.logger, "system");
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
this.ensureDb.checkRc(resultCode);
|
|
339
|
+
const driver = this.ensureDriver;
|
|
340
|
+
if (!driver.deserialize) throw new Error("This SQLite driver does not support snapshots");
|
|
341
|
+
driver.deserialize(snapshot);
|
|
309
342
|
this.invalidateDbSchema();
|
|
310
343
|
perf.logEnd("useSnapshot", "success", "system");
|
|
311
344
|
}
|
|
312
345
|
createSnapshot() {
|
|
313
|
-
|
|
346
|
+
const driver = this.ensureDriver;
|
|
347
|
+
if (!driver.serialize) throw new Error("This SQLite driver does not support snapshots");
|
|
348
|
+
return driver.serialize();
|
|
314
349
|
}
|
|
315
350
|
invalidateDbSchema() {
|
|
316
351
|
this.loadedDbSchema = null;
|
|
@@ -322,13 +357,23 @@ var SQLiteDbWrapper = class {
|
|
|
322
357
|
this.preparedStatements.splice(0);
|
|
323
358
|
this.preparedStatementsMap.clear();
|
|
324
359
|
this.preparedRawStatementsMap.clear();
|
|
360
|
+
this.readonlyStatementCache.clear();
|
|
325
361
|
}
|
|
326
362
|
close() {
|
|
327
363
|
this.cleanup();
|
|
328
|
-
this.
|
|
329
|
-
this.
|
|
364
|
+
this.driver?.close();
|
|
365
|
+
this.driver = null;
|
|
330
366
|
}
|
|
331
367
|
};
|
|
368
|
+
function toRowObjects({ columns, rows }, createRow) {
|
|
369
|
+
const result = [];
|
|
370
|
+
for (const values of rows) {
|
|
371
|
+
const row = createRow();
|
|
372
|
+
for (let index = 0; index < columns.length; index++) row[columns[index]] = values[index];
|
|
373
|
+
result.push(row);
|
|
374
|
+
}
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
332
377
|
function compileKyselyStatement(factory) {
|
|
333
378
|
const parameterKeys = /* @__PURE__ */ new Map();
|
|
334
379
|
const query = factory(dummyKysely, (key) => {
|
|
@@ -401,6 +446,13 @@ function createSQLiteKvStore({ db, metaTableName }) {
|
|
|
401
446
|
})
|
|
402
447
|
};
|
|
403
448
|
}
|
|
449
|
+
const STATE_HASH_KV_KEY = "crdt.consistency.state_hash.v1";
|
|
450
|
+
function createKvStateHashStore(kvStore) {
|
|
451
|
+
return {
|
|
452
|
+
read: () => kvStore.get(STATE_HASH_KV_KEY),
|
|
453
|
+
write: (value) => kvStore.set(STATE_HASH_KV_KEY, value)
|
|
454
|
+
};
|
|
455
|
+
}
|
|
404
456
|
//#endregion
|
|
405
457
|
//#region src/migrations/system-schema.ts
|
|
406
458
|
function createSystemDbConfig({ eventsTableName, updateLogTableName }) {
|
|
@@ -413,6 +465,11 @@ const workerDbConfig = createSystemDbConfig({
|
|
|
413
465
|
eventsTableName: "worker.crdt_events",
|
|
414
466
|
updateLogTableName: "crdt_update_log"
|
|
415
467
|
});
|
|
468
|
+
const localDbConfig = createSystemDbConfig({
|
|
469
|
+
eventsTableName: "crdt_events",
|
|
470
|
+
updateLogTableName: "crdt_update_log"
|
|
471
|
+
});
|
|
472
|
+
const LOCAL_KV_TABLE_NAME = "sync_kv";
|
|
416
473
|
const memoryDbConfig = createSystemDbConfig({
|
|
417
474
|
eventsTableName: "persisted_crdt_events",
|
|
418
475
|
updateLogTableName: "crdt_update_log"
|
|
@@ -467,6 +524,21 @@ const baseSystemMigrations = [
|
|
|
467
524
|
const indexName = `${ctx.eventsTable.table}_dataset_item_id_non_no_op_idx`;
|
|
468
525
|
ctx.execute(`CREATE INDEX IF NOT EXISTS ${ctx.eventsTable.schema}.${indexName} ON ${ctx.eventsTable.table} ("dataset", "item_id") WHERE ${nonNoOpEventPredicate}`);
|
|
469
526
|
}
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
version: 5,
|
|
530
|
+
up: (ctx) => {
|
|
531
|
+
ctx.execute(`UPDATE ${quoteId(ctx.updateLogTable.fullIdentifier)} AS "log"
|
|
532
|
+
SET "payload" = json_set("log"."payload", '$.id', "latest"."timestamp")
|
|
533
|
+
FROM (
|
|
534
|
+
SELECT "dataset", "item_id", max("timestamp") AS "timestamp"
|
|
535
|
+
FROM ${quoteId(ctx.eventsTable.fullIdentifier)}
|
|
536
|
+
WHERE "type" = 'item-created' AND "status" = 'applied' AND ${nonNoOpEventPredicate}
|
|
537
|
+
GROUP BY "dataset", "item_id"
|
|
538
|
+
) AS "latest"
|
|
539
|
+
WHERE "latest"."dataset" = "log"."dataset" AND "latest"."item_id" = "log"."item_id"
|
|
540
|
+
AND "latest"."timestamp" > coalesce(json_extract("log"."payload", '$.id'), '')`);
|
|
541
|
+
}
|
|
470
542
|
}
|
|
471
543
|
];
|
|
472
544
|
function runSystemMigrations(opts) {
|
|
@@ -480,15 +552,27 @@ function runSystemMigrations(opts) {
|
|
|
480
552
|
});
|
|
481
553
|
}
|
|
482
554
|
function applyWorkerDbSchema(db) {
|
|
483
|
-
|
|
555
|
+
return applySystemDbSchema(db, {
|
|
556
|
+
kvTableName: "worker.kv",
|
|
557
|
+
dbConfig: workerDbConfig
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
function applyLocalDbSchema(db) {
|
|
561
|
+
return applySystemDbSchema(db, {
|
|
562
|
+
kvTableName: LOCAL_KV_TABLE_NAME,
|
|
563
|
+
dbConfig: localDbConfig
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
function applySystemDbSchema(db, { kvTableName, dbConfig }) {
|
|
567
|
+
db.executeKysely((kysely) => createKvStoreTableQuery(kysely.schema, kvTableName), { loggerLevel: "system" });
|
|
484
568
|
const kvStore = createSQLiteKvStore({
|
|
485
569
|
db,
|
|
486
|
-
metaTableName:
|
|
570
|
+
metaTableName: kvTableName
|
|
487
571
|
});
|
|
488
572
|
runSystemMigrations({
|
|
489
573
|
migrations: baseSystemMigrations,
|
|
490
574
|
version: kvStore.createNumberStoredValue("internal-schema-version", -1),
|
|
491
|
-
dbConfig
|
|
575
|
+
dbConfig,
|
|
492
576
|
execute: (sql) => db.execute(sql, { loggerLevel: "system" }),
|
|
493
577
|
transaction: (callback) => db.executeTransaction(callback)
|
|
494
578
|
});
|
|
@@ -518,6 +602,6 @@ function applyMemoryDbSchema(db) {
|
|
|
518
602
|
)`, { loggerLevel: "system" });
|
|
519
603
|
}
|
|
520
604
|
//#endregion
|
|
521
|
-
export {
|
|
605
|
+
export { BoundMap as _, baseSystemMigrations as a, dummyKysely as b, memoryDbConfig as c, createKvStateHashStore as d, createKvStoreTableQuery as f, compileKyselyStatement as g, SQLiteDbWrapper as h, applyWorkerDbSchema as i, runSystemMigrations as l, createStoredValue as m, applyLocalDbSchema as n, createSystemDbConfig as o, createSQLiteKvStore as p, applyMemoryDbSchema as r, localDbConfig as s, LOCAL_KV_TABLE_NAME as t, workerDbConfig as u, startPerformanceLogger as v, introspectDb as y };
|
|
522
606
|
|
|
523
|
-
//# sourceMappingURL=system-schema-
|
|
607
|
+
//# sourceMappingURL=system-schema-CXf3FmxN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-schema-CXf3FmxN.js","names":[],"sources":["../src/dummy-kysely.ts","../src/introspection.ts","../src/logger.ts","../src/bound-map.ts","../src/sqlite-db-wrapper.ts","../src/sqlite-crdt/stored-value.ts","../src/sqlite-kv-store.ts","../src/migrations/system-schema.ts"],"sourcesContent":["import { DummyDriver, Kysely, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler } from \"kysely\";\n\nexport const dummyKysely: Kysely<any> = new Kysely({\n dialect: {\n createAdapter: () => new SqliteAdapter(),\n createDriver: () => new DummyDriver(),\n createQueryCompiler: () => new SqliteQueryCompiler(),\n createIntrospector: (db) => new SqliteIntrospector(db),\n },\n});\n","import type { Kysely, QueryCreator } from \"kysely\";\nimport { sql } from \"kysely\";\nimport type { SQLiteDbWrapper } from \"./sqlite-db-wrapper\";\n\ninterface SqliteSystemDatabase {\n // https://www.sqlite.org/schematab.html#alternative_names\n sqlite_master: SQliteMasterTable;\n}\n\n// https://www.sqlite.org/schematab.html#interpretation_of_the_schema_table\ninterface SQliteMasterTable {\n name: string;\n rootpage: number | null;\n sql: string;\n tbl_name: string;\n type: \"index\" | \"table\" | \"trigger\" | \"view\";\n}\n\n// https://www.sqlite.org/pragma.html#pragma_table_info\ninterface PragmaTableInfo {\n cid: number;\n dflt_value: unknown;\n name: string;\n notnull: 0 | 1;\n pk: number;\n type: string;\n}\n\nfunction tablesQuery(qb: QueryCreator<SqliteSystemDatabase> | Kysely<SqliteSystemDatabase>) {\n return qb\n .selectFrom(\"sqlite_master\")\n .where(\"type\", \"in\", [\"table\", \"view\"])\n .where(\"name\", \"not like\", \"sqlite_%\")\n .select([\"name\", \"sql\", \"type\"])\n .orderBy(\"name\");\n}\n\nexport type TableMetadata = {\n name: string;\n isView: boolean;\n columns: ColumnMetadata[];\n};\n\nexport type DatabaseIntrospection = Record<string, TableMetadata>;\n\nexport type ColumnMetadata = {\n name: string;\n dataType: string;\n isNullable: boolean;\n isAutoIncrementing: boolean;\n hasDefaultValue: boolean;\n defaultValueSql: string | null;\n isPrimaryKey: boolean;\n comment: undefined;\n};\n\nexport function introspectDb<BaseDatabase>(_db: SQLiteDbWrapper<BaseDatabase>): DatabaseIntrospection {\n const db = _db as unknown as SQLiteDbWrapper<SqliteSystemDatabase>;\n const tables = db.executeKysely((db) => tablesQuery(db as unknown as Kysely<SqliteSystemDatabase>), {\n loggerLevel: \"system\",\n }).rows;\n\n const tablesMetadata = db.executeKysely(\n (db) =>\n db\n .with(\"table_list\", (qb) => tablesQuery(qb as unknown as Kysely<SqliteSystemDatabase>))\n .selectFrom([\"table_list as tl\", sql<PragmaTableInfo>`pragma_table_info(tl.name)`.as(\"p\")])\n .select([\"tl.name as table\", \"p.cid\", \"p.name\", \"p.type\", \"p.notnull\", \"p.dflt_value\", \"p.pk\"])\n .orderBy(\"tl.name\")\n .orderBy(\"p.cid\"),\n { loggerLevel: \"system\" },\n ).rows;\n\n const columnsByTable: Record<string, typeof tablesMetadata> = {};\n for (const row of tablesMetadata) {\n columnsByTable[row.table] ??= [];\n columnsByTable[row.table].push(row);\n }\n\n return Object.fromEntries(\n tables.map(({ name, sql, type }) => {\n // Try to find the name of the column that has `autoincrement`\n let autoIncrementCol = sql\n ?.split(/[(),]/)\n ?.find((it) => it.toLowerCase().includes(\"autoincrement\"))\n ?.trimStart()\n ?.split(/\\s+/)?.[0]\n ?.replace(/[\"`]/g, \"\");\n\n const columns = columnsByTable[name] ?? [];\n\n // Otherwise, check for an INTEGER PRIMARY KEY\n // https://www.sqlite.org/autoinc.html\n if (!autoIncrementCol) {\n const pkCols = columns.filter((r) => r.pk > 0);\n if (pkCols.length === 1 && pkCols[0].type.toLowerCase() === \"integer\") {\n autoIncrementCol = pkCols[0].name;\n }\n }\n\n return [\n name,\n {\n name: name,\n isView: type === \"view\",\n columns: columns.map((col) => ({\n name: col.name,\n dataType: col.type,\n isNullable: !col.notnull,\n isAutoIncrementing: col.name === autoIncrementCol,\n hasDefaultValue: col.dflt_value != null,\n defaultValueSql: col.dflt_value == null ? null : String(col.dflt_value),\n isPrimaryKey: col.pk > 0,\n comment: undefined,\n })),\n },\n ];\n }),\n );\n}\n","export type LogLevel = \"info\" | \"warning\" | \"error\" | \"trace\" | \"system\";\n\nexport type Logger = (type: string, message: string, level?: LogLevel) => void;\n\nexport type PerformanceLogger = {\n restart: () => void;\n logEnd: (type: string, message: string, level?: LogLevel) => void;\n};\n\nconst noopPerformanceLogger: PerformanceLogger = {\n restart() {},\n logEnd() {},\n};\n\nexport const startPerformanceLogger = (logger: Logger | undefined, level: LogLevel = \"info\"): PerformanceLogger => {\n if (!logger || level === \"system\") {\n return noopPerformanceLogger;\n }\n\n let startTime = performance.now();\n\n return {\n restart: () => {\n startTime = performance.now();\n },\n logEnd: (type: string, message: string, logLevel: LogLevel = level) => {\n const elapsed = performance.now() - startTime;\n\n logger(type, `${elapsed.toFixed(2)}ms - ${message}`, logLevel);\n },\n };\n};\n","interface BoundMapOptions<K, V> {\n maxSize: number;\n onRemove: ((key: K, value: V) => void) | undefined;\n}\n\nexport class BoundMap<K, V> {\n private map = new Map<K, V>();\n private maxSize: number;\n private onRemove: ((key: K, value: V) => void) | undefined;\n\n constructor(opts: BoundMapOptions<K, V>) {\n this.maxSize = opts.maxSize;\n this.onRemove = opts.onRemove;\n }\n\n set = (key: K, value: V) => {\n if (this.onRemove && this.map.has(key)) {\n const old = this.map.get(key) as V;\n this.map.set(key, value);\n this.onRemove(key, old);\n } else {\n this.map.set(key, value);\n }\n if (this.map.size > this.maxSize) {\n const firstKey = this.map.keys().next().value as K;\n this.delete(firstKey);\n }\n };\n\n get = (key: K): V | undefined => {\n return this.map.get(key);\n };\n\n delete = (key: K) => {\n if (this.onRemove && this.map.has(key)) {\n const value = this.map.get(key) as V;\n this.map.delete(key);\n this.onRemove(key, value);\n } else {\n this.map.delete(key);\n }\n };\n\n clear = () => {\n const onRemove = this.onRemove;\n if (onRemove) {\n this.map.forEach((value, key) => {\n onRemove(key, value);\n });\n }\n this.map.clear();\n };\n}\n","import type { Compilable, CompiledQuery, Kysely } from \"kysely\";\nimport { BoundMap } from \"./bound-map\";\nimport { dummyKysely } from \"./dummy-kysely\";\nimport { type DatabaseIntrospection, introspectDb } from \"./introspection\";\nimport { type Logger, startPerformanceLogger } from \"./logger\";\nimport type { SqliteDriver, SqliteDriverStatement, SqliteDriverValue } from \"./sqlite-driver\";\n\nexport type ExecuteParams = {\n sql: string;\n parameters: readonly unknown[];\n};\n\nexport type ExecuteResult<T> = {\n rows: T[];\n};\n\nexport type PreparedStatement<TParams extends unknown[], TResult> = {\n execute: (parameters: TParams) => TResult[];\n finalize: () => void;\n isFinalized: boolean;\n};\n\ntype ScalarFunctionOptions<\n TArgs extends readonly SqliteDriverValue[],\n TResult extends SqliteDriverValue | undefined,\n> = {\n name: string;\n callback: (...args: TArgs) => TResult;\n deterministic?: boolean;\n directOnly?: boolean;\n innocuous?: boolean;\n};\n\ntype SqliteWrapperOptions = {\n logger?: Logger;\n loggerPrefix?: string;\n driver: SqliteDriver;\n};\n\nexport type SQLiteTransactionWrapper<TDatabase = unknown> = Pick<\n SQLiteDbWrapper<TDatabase>,\n \"sql\" | \"execute\" | \"executePrepared\" | \"executePreparedRaw\" | \"executeKysely\"\n>;\n\nexport type InternalSQLiteTransactionWrapper<TDatabase = unknown> = Pick<\n SQLiteDbWrapper<TDatabase>,\n \"executePrepared\" | \"executePreparedRaw\"\n>;\n\nexport type InternalSQLiteWrapper<TDatabase = unknown> = InternalSQLiteTransactionWrapper<TDatabase> & {\n executeTransaction: (callback: (db: InternalSQLiteTransactionWrapper<TDatabase>) => void) => void;\n};\n\ntype QueryMetaOpts = {\n loggerLevel?: \"info\" | \"system\";\n};\n\n/** Runs after user SQL succeeds, before its transaction or savepoint is committed. */\ntype AfterMutatingStatement<TDatabase> = (db: InternalSQLiteTransactionWrapper<TDatabase>) => void;\n\ntype ExecuteOptions = QueryMetaOpts & {\n /** For internal mutations whose effects must not be processed by afterMutatingStatement. */\n skipAfterMutatingStatement?: boolean;\n};\n\n// sqlite3_stmt_readonly reports transaction control statements as read-only.\nconst TRANSACTION_CONTROL_PATTERN =\n /^(?:\\s|--[^\\n]*\\n|\\/\\*[\\s\\S]*?\\*\\/)*(?:begin|commit|end|rollback|savepoint|release)\\b/i;\n\nexport class SQLiteDbWrapper<TDatabase = unknown> {\n private driver: SqliteDriver | null;\n private logger?: Logger;\n private loggerPrefix?: string;\n\n private loadedDbSchema: DatabaseIntrospection | null = null;\n\n private preparedStatements: PreparedStatement<SqliteDriverValue[], unknown>[] = [];\n private preparedStatementsMap = new Map<string, TypedStatement<Record<string, unknown>, unknown>>();\n private preparedRawStatementsMap = new Map<string, PreparedStatement<SqliteDriverValue[], unknown>>();\n private readonlyStatementCache = new BoundMap<string, boolean>({ maxSize: 500, onRemove: undefined });\n private afterMutatingStatement: AfterMutatingStatement<TDatabase> | null = null;\n\n constructor(opts: SqliteWrapperOptions) {\n this.driver = opts.driver;\n this.logger = opts.logger;\n this.loggerPrefix = opts.loggerPrefix;\n }\n\n get ensureDriver() {\n if (!this.driver) {\n throw new Error(\"Database is already closed\");\n }\n return this.driver;\n }\n\n get dbSchema() {\n if (!this.loadedDbSchema) {\n this.loadedDbSchema = introspectDb(this);\n }\n return this.loadedDbSchema;\n }\n\n private executeSql<T>(\n sql: string,\n bind: readonly unknown[] | undefined,\n loggerLevel: QueryMetaOpts[\"loggerLevel\"],\n skipAfterMutatingStatement: boolean,\n ): ExecuteResult<T> {\n const perf = startPerformanceLogger(this.logger, loggerLevel);\n const driver = this.ensureDriver;\n const statement = driver.prepare(sql);\n let transaction: { commit: () => void; rollback: () => void } | undefined;\n\n try {\n const afterMutatingStatement =\n !skipAfterMutatingStatement && this.afterMutatingStatement && !this.isReadonlyStatement(statement, sql)\n ? this.afterMutatingStatement\n : null;\n\n let totalChangesBefore = 0;\n if (afterMutatingStatement) {\n transaction = this.beginStatementTransaction();\n totalChangesBefore = driver.totalChanges();\n }\n\n const rows = toRowObjects<T>(statement.run(bind ?? []), () => Object.create(null));\n statement.finalize();\n perf.logEnd(`${this.loggerPrefix ?? \"\"}:query`, sql, loggerLevel);\n\n if (transaction) {\n // Nothing was written, so the statement cannot have produced any work for the callback.\n if (driver.totalChanges() !== totalChangesBefore) {\n afterMutatingStatement?.(this);\n }\n transaction.commit();\n }\n\n return { rows };\n } catch (error) {\n statement.finalize();\n transaction?.rollback();\n throw error;\n }\n }\n\n private isReadonlyStatement(statement: SqliteDriverStatement, sql: string) {\n if (statement.readonly !== undefined) {\n return statement.readonly;\n }\n\n let readonly = this.readonlyStatementCache.get(sql);\n if (readonly === undefined) {\n readonly = TRANSACTION_CONTROL_PATTERN.test(sql) || this.isReadonlyByTablesUsed(sql);\n this.readonlyStatementCache.set(sql, readonly);\n }\n return readonly;\n }\n\n private isReadonlyByTablesUsed(sql: string) {\n // Statements that open no b-tree (PRAGMAs, table-less selects, full-table deletes)\n // are reported with no rows, so they are treated as writes.\n const tables = this.executePreparedRaw<[string], { wr: number }>({\n key: \"$tables-used-writes\",\n sql: `select \"wr\" from tables_used(?)`,\n params: [sql],\n meta: { loggerLevel: \"system\" },\n });\n return tables.length > 0 && tables.every((table) => !table.wr);\n }\n\n execute<T = unknown>(opts: ExecuteParams | string | CompiledQuery<T>, options?: ExecuteOptions): ExecuteResult<T> {\n const sql = typeof opts === \"string\" ? opts : opts.sql;\n const bind = typeof opts === \"string\" ? undefined : opts.parameters;\n\n return this.executeSql<T>(sql, bind, options?.loggerLevel, options?.skipAfterMutatingStatement ?? false);\n }\n\n setAfterMutatingStatement(callback: AfterMutatingStatement<TDatabase>) {\n if (this.afterMutatingStatement) {\n throw new Error(\"An afterMutatingStatement callback is already registered\");\n }\n this.afterMutatingStatement = callback;\n }\n\n executeTransaction<T>(callback: (db: SQLiteTransactionWrapper<TDatabase>) => T): T {\n const transaction = this.beginTransaction();\n try {\n const result = callback(this);\n transaction.commit();\n return result;\n } catch (error) {\n transaction.rollback();\n throw error;\n }\n }\n\n beginTransaction() {\n this.executePreparedRaw({\n key: \"$begin-transaction\",\n sql: \"begin\",\n meta: {\n loggerLevel: \"system\",\n },\n });\n\n return {\n commit: () => {\n this.executePreparedRaw({\n key: \"$commit-transaction\",\n sql: \"commit\",\n meta: {\n loggerLevel: \"system\",\n },\n });\n },\n rollback: () => {\n this.executePreparedRaw({\n key: \"$rollback-transaction\",\n sql: \"rollback\",\n meta: {\n loggerLevel: \"system\",\n },\n });\n },\n };\n }\n\n // A savepoint opens a transaction when none is active, so this nests inside user transactions too.\n private beginStatementTransaction() {\n this.executePreparedRaw({\n key: \"$begin-statement-savepoint\",\n sql: \"savepoint sqlite_sync_statement\",\n meta: { loggerLevel: \"system\" },\n });\n\n return {\n commit: () => {\n this.executePreparedRaw({\n key: \"$commit-statement-savepoint\",\n sql: \"release savepoint sqlite_sync_statement\",\n meta: { loggerLevel: \"system\" },\n });\n },\n rollback: () => {\n this.executePreparedRaw({\n key: \"$rollback-statement-savepoint\",\n sql: \"rollback to savepoint sqlite_sync_statement\",\n meta: { loggerLevel: \"system\" },\n });\n this.executePreparedRaw({\n key: \"$release-rolled-back-statement-savepoint\",\n sql: \"release savepoint sqlite_sync_statement\",\n meta: { loggerLevel: \"system\" },\n });\n },\n };\n }\n\n prepare<TParams extends unknown[], TResult>(sql: string, opts?: QueryMetaOpts) {\n const perf = startPerformanceLogger(this.logger, opts?.loggerLevel);\n const stmt = this.ensureDriver.prepare(sql);\n perf.logEnd(`${this.loggerPrefix ?? \"\"}:prepare`, sql, opts?.loggerLevel);\n\n let isFinalized = false;\n\n const execute = (params: TParams) => {\n if (isFinalized) {\n throw new Error(\"Statement is finalized\");\n }\n\n const perf = startPerformanceLogger(this.logger, opts?.loggerLevel);\n try {\n return toRowObjects<TResult>(stmt.run(params), () => ({}));\n } finally {\n perf.logEnd(`${this.loggerPrefix ?? \"\"}:prepare-execute`, sql, opts?.loggerLevel);\n }\n };\n\n const finalize = () => {\n isFinalized = true;\n stmt.finalize();\n };\n\n const preparedStatement: PreparedStatement<TParams, TResult> = {\n execute,\n finalize,\n get isFinalized() {\n return isFinalized;\n },\n };\n\n this.preparedStatements.push(preparedStatement as PreparedStatement<SqliteDriverValue[], unknown>);\n\n return preparedStatement;\n }\n\n prepareKysely<TParams extends Record<string, unknown>>(opts?: QueryMetaOpts) {\n return <TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>>(\n factory: KyselyStatementFactory<TParams, TDatabase, TQuery, TResult>,\n ): TypedStatement<TParams, TResult> => {\n const query = compileKyselyStatement(factory);\n const statement = this.prepare<SqliteDriverValue[], TResult>(query.sql, opts);\n\n return {\n execute: (parameters) => statement.execute(query.bindParameters(parameters) as SqliteDriverValue[]),\n };\n };\n }\n\n executeKysely<TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>>(\n factory: KyselyQueryFactory<TDatabase, TQuery, TResult>,\n options?: ExecuteOptions,\n ) {\n const query = factory(dummyKysely).compile();\n return this.execute(query, options);\n }\n\n executePrepared<\n TParams extends Record<string, unknown>,\n TQuery extends Compilable<TResult>,\n TResult = QueryBuilderOutput<TQuery>,\n >(\n key: string,\n params: TParams,\n factory: KyselyStatementFactory<TParams, TDatabase, TQuery, TResult>,\n meta?: QueryMetaOpts,\n ) {\n let statement = this.preparedStatementsMap.get(key) as TypedStatement<TParams, TResult> | undefined;\n if (!statement) {\n statement = this.prepareKysely<TParams>(meta)(factory);\n this.preparedStatementsMap.set(key, statement as TypedStatement<Record<string, unknown>, unknown>);\n }\n\n return statement.execute(params);\n }\n\n executePreparedRaw<TParams extends unknown[], TResult>({\n key,\n sql,\n params,\n meta,\n }: {\n key: string;\n sql: string;\n params?: TParams;\n meta?: QueryMetaOpts;\n }) {\n let statement = this.preparedRawStatementsMap.get(key) as PreparedStatement<TParams, TResult> | undefined;\n if (!statement) {\n statement = this.prepare(sql, meta);\n this.preparedRawStatementsMap.set(key, statement as PreparedStatement<any[], unknown>);\n }\n\n return statement.execute((params ?? []) as TParams);\n }\n\n sql<T = unknown>(templateOrString: TemplateStringsArray | string, ...parameters: unknown[]) {\n if (typeof templateOrString === \"string\") {\n return this.execute<T>({\n sql: templateOrString,\n parameters,\n });\n }\n return this.execute<T>({\n sql: templateOrString.join(\"?\"),\n parameters,\n });\n }\n\n createScalarFunction<TArgs extends SqliteDriverValue[], TResult extends SqliteDriverValue | undefined>({\n name,\n callback,\n deterministic,\n directOnly,\n innocuous,\n }: ScalarFunctionOptions<TArgs, TResult>) {\n const driver = this.ensureDriver;\n if (!driver.createScalarFunction) {\n throw new Error(\"This SQLite driver does not support scalar functions\");\n }\n driver.createScalarFunction({\n name,\n callback: (...args) => callback(...(args as TArgs)),\n arity: callback.length,\n deterministic,\n directOnly,\n innocuous,\n });\n }\n\n useSnapshot(snapshot: Uint8Array<ArrayBufferLike>) {\n const perf = startPerformanceLogger(this.logger, \"system\");\n const driver = this.ensureDriver;\n if (!driver.deserialize) {\n throw new Error(\"This SQLite driver does not support snapshots\");\n }\n driver.deserialize(snapshot);\n\n this.invalidateDbSchema();\n\n perf.logEnd(\"useSnapshot\", \"success\", \"system\");\n }\n\n createSnapshot() {\n const driver = this.ensureDriver;\n if (!driver.serialize) {\n throw new Error(\"This SQLite driver does not support snapshots\");\n }\n return driver.serialize();\n }\n\n invalidateDbSchema() {\n this.loadedDbSchema = null;\n }\n\n cleanup() {\n this.preparedStatements.forEach((stmt) => {\n stmt.finalize();\n });\n this.preparedStatements.splice(0);\n this.preparedStatementsMap.clear();\n this.preparedRawStatementsMap.clear();\n this.readonlyStatementCache.clear();\n }\n\n close() {\n this.cleanup();\n\n this.driver?.close();\n this.driver = null;\n }\n}\n\nfunction toRowObjects<T>(\n { columns, rows }: { columns: string[]; rows: SqliteDriverValue[][] },\n createRow: () => Record<string, unknown>,\n): T[] {\n const result: T[] = [];\n for (const values of rows) {\n const row = createRow();\n for (let index = 0; index < columns.length; index++) {\n row[columns[index]] = values[index];\n }\n result.push(row as T);\n }\n return result;\n}\n\nexport type QueryBuilderOutput<QB> = QB extends Compilable<infer O> ? O : never;\ntype ParamsGetter<TParams> = <TKey extends keyof TParams>(key: TKey) => TParams[TKey];\n\ntype TypedStatement<TParams extends Record<string, unknown>, TResult> = {\n execute: (parameters: TParams) => TResult[];\n};\nexport type KyselyStatementFactory<\n TParams extends Record<string, unknown>,\n TDatabase,\n TQuery extends Compilable<TResult>,\n TResult = QueryBuilderOutput<TQuery>,\n> = (kysely: Kysely<TDatabase>, params: ParamsGetter<TParams>) => TQuery;\nexport type KyselyQueryFactory<TDatabase, TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>> = (\n kysely: Kysely<TDatabase>,\n) => TQuery;\n\nexport function compileKyselyStatement<TParams extends Record<string, unknown>, TDatabase>(\n factory: KyselyStatementFactory<TParams, TDatabase, Compilable<unknown>>,\n) {\n const parameterKeys = new Map<unknown, keyof TParams>();\n const query = factory(dummyKysely, (key) => {\n const token = {};\n parameterKeys.set(token, key);\n return token as TParams[typeof key];\n }).compile();\n\n return {\n sql: query.sql,\n bindParameters: (parameters: TParams) =>\n query.parameters.map((value) => {\n const key = parameterKeys.get(value);\n return key === undefined ? value : parameters[key];\n }),\n };\n}\n","export type StoredValue<T> = {\n get current(): T;\n set current(newValue: T);\n};\n\nexport function createStoredValue<T>({\n initialValue,\n saveToStorage,\n}: {\n initialValue: T;\n saveToStorage?: (value: T) => void;\n}): StoredValue<T> {\n let currentValue = initialValue;\n\n return {\n get current() {\n return currentValue;\n },\n set current(newValue: T) {\n saveToStorage?.(newValue);\n currentValue = newValue;\n },\n };\n}\n","import { type SchemaModule, sql } from \"kysely\";\nimport type { StateHashStore } from \"./sqlite-crdt/state-hash\";\nimport { createStoredValue } from \"./sqlite-crdt/stored-value\";\nimport type { InternalSQLiteWrapper } from \"./sqlite-db-wrapper\";\n\nexport type KvStoreItem = {\n key: string;\n value: string;\n};\n\nexport function createKvStoreTableQuery(schema: SchemaModule, tableName: string) {\n return schema\n .createTable(tableName)\n .ifNotExists()\n .addColumn(\"key\", \"text\", (col) => col.notNull().primaryKey())\n .addColumn(\"value\", \"text\", (col) => col.notNull())\n .modifyEnd(sql`without rowid`);\n}\n\nexport function createSQLiteKvStore({ db, metaTableName }: { db: InternalSQLiteWrapper<any>; metaTableName: string }) {\n const metaDb = db as InternalSQLiteWrapper<{\n meta: KvStoreItem;\n }>;\n\n const get = (key: string): string | null => {\n const [result] = metaDb.executePrepared(\n \"get-meta-value\",\n { key },\n (db, params) =>\n db\n .selectFrom(metaTableName as \"meta\")\n .where(\"key\", \"=\", params(\"key\"))\n .select(\"value\")\n .limit((eb) => eb.lit(1)),\n { loggerLevel: \"system\" },\n );\n\n return result?.value ?? null;\n };\n\n const set = (key: string, value: string) => {\n metaDb.executePrepared(\n \"set-meta-value\",\n { key, value },\n (db, params) =>\n db\n .insertInto(metaTableName as \"meta\")\n .values({ key: params(\"key\"), value: params(\"value\") })\n .onConflict((oc) => oc.doUpdateSet({ value: params(\"value\") })),\n { loggerLevel: \"system\" },\n );\n };\n\n const remove = (key: string) => {\n metaDb.executePrepared(\n \"remove-meta-value\",\n { key },\n (db, params) => db.deleteFrom(metaTableName as \"meta\").where(\"key\", \"=\", params(\"key\")),\n { loggerLevel: \"system\" },\n );\n };\n\n const getNumberOrDefault = <T>(key: string, defaultValue: T): T | number => {\n const value = get(key);\n if (!value) return defaultValue;\n const parsedValue = Number.parseInt(value, 10);\n return Number.isNaN(parsedValue) ? defaultValue : parsedValue;\n };\n\n return {\n get,\n set,\n remove,\n createStringStoredValue: (key: string, defaultValue: string) =>\n createStoredValue<string>({\n initialValue: get(key) ?? defaultValue,\n saveToStorage: (val) => set(key, val),\n }),\n createNumberStoredValue: (key: string, defaultValue: number) =>\n createStoredValue<number>({\n initialValue: getNumberOrDefault(key, defaultValue),\n saveToStorage: (val) => set(key, val.toString()),\n }),\n };\n}\n\nexport type KvStore = ReturnType<typeof createSQLiteKvStore>;\n\nexport const STATE_HASH_KV_KEY = \"crdt.consistency.state_hash.v1\";\n\nexport function createKvStateHashStore(kvStore: Pick<KvStore, \"get\" | \"set\">): StateHashStore {\n return {\n read: () => kvStore.get(STATE_HASH_KV_KEY),\n write: (value) => kvStore.set(STATE_HASH_KV_KEY, value),\n };\n}\n","import {\n CRDT_EVENT_NO_OP_PAYLOAD,\n type CrdtUpdateLogItem,\n type PersistedCrdtEvent,\n} from \"../sqlite-crdt/crdt-table-schema\";\nimport type { StoredValue } from \"../sqlite-crdt/stored-value\";\nimport type { SQLiteDbWrapper } from \"../sqlite-db-wrapper\";\nimport { createKvStoreTableQuery, createSQLiteKvStore, type KvStoreItem } from \"../sqlite-kv-store\";\nimport { type ParsedTableName, parseTableName, quoteId } from \"../utils\";\n\nexport type SystemDbConfig = {\n eventsTable: ParsedTableName;\n updateLogTable: ParsedTableName;\n};\n\nexport function createSystemDbConfig({\n eventsTableName,\n updateLogTableName,\n}: {\n eventsTableName: string;\n updateLogTableName: string;\n}): SystemDbConfig {\n return {\n eventsTable: parseTableName(eventsTableName),\n updateLogTable: parseTableName(updateLogTableName),\n };\n}\n\nexport type WorkerDbSchema = {\n crdt_update_log: CrdtUpdateLogItem;\n \"worker.kv\": KvStoreItem;\n \"worker.crdt_events\": PersistedCrdtEvent;\n};\n\nexport const workerDbConfig = createSystemDbConfig({\n eventsTableName: \"worker.crdt_events\",\n updateLogTableName: \"crdt_update_log\",\n});\n\nexport type LocalDbSchema = {\n crdt_update_log: CrdtUpdateLogItem;\n crdt_events: PersistedCrdtEvent;\n sync_kv: KvStoreItem;\n};\n\nexport const localDbConfig = createSystemDbConfig({\n eventsTableName: \"crdt_events\",\n updateLogTableName: \"crdt_update_log\",\n});\n\nexport const LOCAL_KV_TABLE_NAME = \"sync_kv\";\n\nexport type MemoryDbSchema = {\n crdt_update_log: CrdtUpdateLogItem;\n persisted_crdt_events: PersistedCrdtEvent;\n};\n\nexport const memoryDbConfig = createSystemDbConfig({\n eventsTableName: \"persisted_crdt_events\",\n updateLogTableName: \"crdt_update_log\",\n});\n\nexport type SystemMigrationContext = SystemDbConfig & {\n execute: (sql: string) => void;\n};\n\nexport type SystemMigration = {\n version: number;\n up: (ctx: SystemMigrationContext) => void;\n};\n\nconst nonNoOpEventPredicate = `\"payload\" <> '${CRDT_EVENT_NO_OP_PAYLOAD}'`;\n\nexport const baseSystemMigrations: SystemMigration[] = [\n {\n version: 0,\n up: (ctx: SystemMigrationContext) => {\n ctx.execute(`CREATE TABLE IF NOT EXISTS ${ctx.eventsTable.fullIdentifier} (\n \"sync_id\" integer NOT NULL PRIMARY KEY,\n \"schema_version\" integer NOT NULL,\n \"status\" text NOT NULL,\n \"type\" text NOT NULL,\n \"timestamp\" text NOT NULL,\n \"origin\" text NOT NULL,\n \"dataset\" text NOT NULL,\n \"item_id\" text NOT NULL,\n \"payload\" text NOT NULL\n )`);\n ctx.execute(`CREATE TABLE IF NOT EXISTS ${ctx.updateLogTable.fullIdentifier} (\n \"dataset\" text NOT NULL,\n \"item_id\" text NOT NULL,\n \"payload\" text NOT NULL,\n PRIMARY KEY (\"item_id\", \"dataset\")\n )`);\n },\n },\n {\n version: 1,\n up: (ctx: SystemMigrationContext) => {\n ctx.execute(`ALTER TABLE ${ctx.eventsTable.fullIdentifier} ADD COLUMN \"source_node_id\" TEXT NOT NULL DEFAULT ''`);\n },\n },\n {\n version: 2,\n up: (ctx: SystemMigrationContext) => {\n const indexName = `${ctx.eventsTable.table}_status_sync_id_idx`;\n ctx.execute(\n `CREATE INDEX IF NOT EXISTS ${ctx.eventsTable.schema}.${indexName} ON ${ctx.eventsTable.table} (\"status\", \"sync_id\")`,\n );\n },\n },\n {\n version: 3,\n up: (ctx: SystemMigrationContext) => {\n const indexName = `${ctx.eventsTable.table}_timestamp_status_sync_id_idx`;\n ctx.execute(\n `CREATE INDEX IF NOT EXISTS ${ctx.eventsTable.schema}.${indexName} ON ${ctx.eventsTable.table} (\"timestamp\", \"status\", \"sync_id\")`,\n );\n },\n },\n {\n version: 4,\n up: (ctx: SystemMigrationContext) => {\n const indexName = `${ctx.eventsTable.table}_dataset_item_id_non_no_op_idx`;\n ctx.execute(\n `CREATE INDEX IF NOT EXISTS ${ctx.eventsTable.schema}.${indexName} ON ${ctx.eventsTable.table} (\"dataset\", \"item_id\") WHERE ${nonNoOpEventPredicate}`,\n );\n },\n },\n {\n // Older builds kept an item's first create under `id` in its update log. The state hash\n // reads missing cells as written by the latest create, so lift `id` to the latest one\n // the event log still has. Applying a create that is no longer in the log fixes the rest.\n version: 5,\n up: (ctx: SystemMigrationContext) => {\n ctx.execute(`UPDATE ${quoteId(ctx.updateLogTable.fullIdentifier)} AS \"log\"\nSET \"payload\" = json_set(\"log\".\"payload\", '$.id', \"latest\".\"timestamp\")\nFROM (\n SELECT \"dataset\", \"item_id\", max(\"timestamp\") AS \"timestamp\"\n FROM ${quoteId(ctx.eventsTable.fullIdentifier)}\n WHERE \"type\" = 'item-created' AND \"status\" = 'applied' AND ${nonNoOpEventPredicate}\n GROUP BY \"dataset\", \"item_id\"\n) AS \"latest\"\nWHERE \"latest\".\"dataset\" = \"log\".\"dataset\" AND \"latest\".\"item_id\" = \"log\".\"item_id\"\n AND \"latest\".\"timestamp\" > coalesce(json_extract(\"log\".\"payload\", '$.id'), '')`);\n },\n },\n];\n\nexport function runSystemMigrations(opts: {\n version: StoredValue<number>;\n migrations: SystemMigration[];\n dbConfig: SystemDbConfig;\n execute: (sql: string) => void;\n transaction: (callback: () => void) => void;\n}): void {\n const ctx: SystemMigrationContext = {\n ...opts.dbConfig,\n execute: opts.execute,\n };\n for (const migration of opts.migrations) {\n if (migration.version > opts.version.current) {\n opts.transaction(() => {\n migration.up(ctx);\n opts.version.current = migration.version;\n });\n }\n }\n}\n\nexport function applyWorkerDbSchema(db: SQLiteDbWrapper<any>) {\n return applySystemDbSchema(db, { kvTableName: \"worker.kv\", dbConfig: workerDbConfig });\n}\n\nexport function applyLocalDbSchema(db: SQLiteDbWrapper<any>) {\n return applySystemDbSchema(db, { kvTableName: LOCAL_KV_TABLE_NAME, dbConfig: localDbConfig });\n}\n\nfunction applySystemDbSchema(\n db: SQLiteDbWrapper<any>,\n { kvTableName, dbConfig }: { kvTableName: string; dbConfig: SystemDbConfig },\n) {\n // KV table stays separate — needed before system migrations for version tracking\n db.executeKysely((kysely) => createKvStoreTableQuery(kysely.schema, kvTableName), { loggerLevel: \"system\" });\n\n // System schema migrations (each in its own transaction)\n const kvStore = createSQLiteKvStore({ db, metaTableName: kvTableName });\n runSystemMigrations({\n migrations: baseSystemMigrations,\n version: kvStore.createNumberStoredValue(\"internal-schema-version\", -1),\n dbConfig,\n execute: (sql) => db.execute(sql, { loggerLevel: \"system\" }),\n transaction: (callback) => db.executeTransaction(callback),\n });\n\n return { kvStore };\n}\n\nexport function applyMemoryDbSchema(db: SQLiteDbWrapper<any>) {\n db.execute(\n `CREATE TABLE IF NOT EXISTS ${memoryDbConfig.eventsTable.fullIdentifier} (\n \"sync_id\" integer NOT NULL PRIMARY KEY,\n \"schema_version\" integer NOT NULL,\n \"status\" text NOT NULL,\n \"type\" text NOT NULL,\n \"timestamp\" text NOT NULL,\n \"origin\" text NOT NULL,\n \"source_node_id\" text NOT NULL DEFAULT '',\n \"dataset\" text NOT NULL,\n \"item_id\" text NOT NULL,\n \"payload\" text NOT NULL\n )`,\n { loggerLevel: \"system\" },\n );\n db.execute(\n `CREATE INDEX IF NOT EXISTS ${memoryDbConfig.eventsTable.table}_status_sync_id_idx ON ${memoryDbConfig.eventsTable.table} (\"status\", \"sync_id\")`,\n {\n loggerLevel: \"system\",\n },\n );\n db.execute(\n `CREATE INDEX IF NOT EXISTS ${memoryDbConfig.eventsTable.table}_timestamp_status_sync_id_idx ON ${memoryDbConfig.eventsTable.table} (\"timestamp\", \"status\", \"sync_id\")`,\n {\n loggerLevel: \"system\",\n },\n );\n db.execute(\n `CREATE INDEX IF NOT EXISTS ${memoryDbConfig.eventsTable.table}_dataset_item_id_non_no_op_idx ON ${memoryDbConfig.eventsTable.table} (\"dataset\", \"item_id\") WHERE ${nonNoOpEventPredicate}`,\n {\n loggerLevel: \"system\",\n },\n );\n db.execute(\n `CREATE TABLE IF NOT EXISTS ${memoryDbConfig.updateLogTable.fullIdentifier} (\n \"dataset\" text NOT NULL,\n \"item_id\" text NOT NULL,\n \"payload\" text NOT NULL,\n PRIMARY KEY (\"item_id\", \"dataset\")\n)`,\n { loggerLevel: \"system\" },\n );\n}\n"],"mappings":";;;AAEA,MAAa,cAA2B,IAAI,OAAO,EACjD,SAAS;CACP,qBAAqB,IAAI,cAAc;CACvC,oBAAoB,IAAI,YAAY;CACpC,2BAA2B,IAAI,oBAAoB;CACnD,qBAAqB,OAAO,IAAI,mBAAmB,EAAE;AACvD,EACF,CAAC;;;ACmBD,SAAS,YAAY,IAAuE;CAC1F,OAAO,GACJ,WAAW,eAAe,CAAC,CAC3B,MAAM,QAAQ,MAAM,CAAC,SAAS,MAAM,CAAC,CAAC,CACtC,MAAM,QAAQ,YAAY,UAAU,CAAC,CACrC,OAAO;EAAC;EAAQ;EAAO;CAAM,CAAC,CAAC,CAC/B,QAAQ,MAAM;AACnB;AAqBA,SAAgB,aAA2B,KAA2D;CACpG,MAAM,KAAK;CACX,MAAM,SAAS,GAAG,eAAe,OAAO,YAAY,EAA6C,GAAG,EAClG,aAAa,SACf,CAAC,CAAC,CAAC;CAEH,MAAM,iBAAiB,GAAG,eACvB,OACC,GACG,KAAK,eAAe,OAAO,YAAY,EAA6C,CAAC,CAAC,CACtF,WAAW,CAAC,oBAAoB,GAAoB,6BAA6B,GAAG,GAAG,CAAC,CAAC,CAAC,CAC1F,OAAO;EAAC;EAAoB;EAAS;EAAU;EAAU;EAAa;EAAgB;CAAM,CAAC,CAAC,CAC9F,QAAQ,SAAS,CAAC,CAClB,QAAQ,OAAO,GACpB,EAAE,aAAa,SAAS,CAC1B,CAAC,CAAC;CAEF,MAAM,iBAAwD,CAAC;CAC/D,KAAK,MAAM,OAAO,gBAAgB;EAChC,eAAe,IAAI,WAAW,CAAC;EAC/B,eAAe,IAAI,MAAM,CAAC,KAAK,GAAG;CACpC;CAEA,OAAO,OAAO,YACZ,OAAO,KAAK,EAAE,MAAM,KAAK,WAAW;EAElC,IAAI,mBAAmB,KACnB,MAAM,OAAO,CAAC,EACd,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,SAAS,eAAe,CAAC,CAAC,EACxD,UAAU,CAAC,EACX,MAAM,KAAK,CAAC,GAAG,EAAE,EACjB,QAAQ,SAAS,EAAE;EAEvB,MAAM,UAAU,eAAe,SAAS,CAAC;EAIzC,IAAI,CAAC,kBAAkB;GACrB,MAAM,SAAS,QAAQ,QAAQ,MAAM,EAAE,KAAK,CAAC;GAC7C,IAAI,OAAO,WAAW,KAAK,OAAO,EAAE,CAAC,KAAK,YAAY,MAAM,WAC1D,mBAAmB,OAAO,EAAE,CAAC;EAEjC;EAEA,OAAO,CACL,MACA;GACQ;GACN,QAAQ,SAAS;GACjB,SAAS,QAAQ,KAAK,SAAS;IAC7B,MAAM,IAAI;IACV,UAAU,IAAI;IACd,YAAY,CAAC,IAAI;IACjB,oBAAoB,IAAI,SAAS;IACjC,iBAAiB,IAAI,cAAc;IACnC,iBAAiB,IAAI,cAAc,OAAO,OAAO,OAAO,IAAI,UAAU;IACtE,cAAc,IAAI,KAAK;IACvB,SAAS,KAAA;GACX,EAAE;EACJ,CACF;CACF,CAAC,CACH;AACF;;;AC9GA,MAAM,wBAA2C;CAC/C,UAAU,CAAC;CACX,SAAS,CAAC;AACZ;AAEA,MAAa,0BAA0B,QAA4B,QAAkB,WAA8B;CACjH,IAAI,CAAC,UAAU,UAAU,UACvB,OAAO;CAGT,IAAI,YAAY,YAAY,IAAI;CAEhC,OAAO;EACL,eAAe;GACb,YAAY,YAAY,IAAI;EAC9B;EACA,SAAS,MAAc,SAAiB,WAAqB,UAAU;GAGrE,OAAO,MAAM,IAFG,YAAY,IAAI,IAAI,UAAA,CAEZ,QAAQ,CAAC,EAAE,OAAO,WAAW,QAAQ;EAC/D;CACF;AACF;;;AC1BA,IAAa,WAAb,MAA4B;CAC1B,sBAAc,IAAI,IAAU;CAC5B;CACA;CAEA,YAAY,MAA6B;EACvC,KAAK,UAAU,KAAK;EACpB,KAAK,WAAW,KAAK;CACvB;CAEA,OAAO,KAAQ,UAAa;EAC1B,IAAI,KAAK,YAAY,KAAK,IAAI,IAAI,GAAG,GAAG;GACtC,MAAM,MAAM,KAAK,IAAI,IAAI,GAAG;GAC5B,KAAK,IAAI,IAAI,KAAK,KAAK;GACvB,KAAK,SAAS,KAAK,GAAG;EACxB,OACE,KAAK,IAAI,IAAI,KAAK,KAAK;EAEzB,IAAI,KAAK,IAAI,OAAO,KAAK,SAAS;GAChC,MAAM,WAAW,KAAK,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;GACxC,KAAK,OAAO,QAAQ;EACtB;CACF;CAEA,OAAO,QAA0B;EAC/B,OAAO,KAAK,IAAI,IAAI,GAAG;CACzB;CAEA,UAAU,QAAW;EACnB,IAAI,KAAK,YAAY,KAAK,IAAI,IAAI,GAAG,GAAG;GACtC,MAAM,QAAQ,KAAK,IAAI,IAAI,GAAG;GAC9B,KAAK,IAAI,OAAO,GAAG;GACnB,KAAK,SAAS,KAAK,KAAK;EAC1B,OACE,KAAK,IAAI,OAAO,GAAG;CAEvB;CAEA,cAAc;EACZ,MAAM,WAAW,KAAK;EACtB,IAAI,UACF,KAAK,IAAI,SAAS,OAAO,QAAQ;GAC/B,SAAS,KAAK,KAAK;EACrB,CAAC;EAEH,KAAK,IAAI,MAAM;CACjB;AACF;;;ACcA,MAAM,8BACJ;AAEF,IAAa,kBAAb,MAAkD;CAChD;CACA;CACA;CAEA,iBAAuD;CAEvD,qBAAgF,CAAC;CACjF,wCAAgC,IAAI,IAA8D;CAClG,2CAAmC,IAAI,IAA6D;CACpG,yBAAiC,IAAI,SAA0B;EAAE,SAAS;EAAK,UAAU,KAAA;CAAU,CAAC;CACpG,yBAA2E;CAE3E,YAAY,MAA4B;EACtC,KAAK,SAAS,KAAK;EACnB,KAAK,SAAS,KAAK;EACnB,KAAK,eAAe,KAAK;CAC3B;CAEA,IAAI,eAAe;EACjB,IAAI,CAAC,KAAK,QACR,MAAM,IAAI,MAAM,4BAA4B;EAE9C,OAAO,KAAK;CACd;CAEA,IAAI,WAAW;EACb,IAAI,CAAC,KAAK,gBACR,KAAK,iBAAiB,aAAa,IAAI;EAEzC,OAAO,KAAK;CACd;CAEA,WACE,KACA,MACA,aACA,4BACkB;EAClB,MAAM,OAAO,uBAAuB,KAAK,QAAQ,WAAW;EAC5D,MAAM,SAAS,KAAK;EACpB,MAAM,YAAY,OAAO,QAAQ,GAAG;EACpC,IAAI;EAEJ,IAAI;GACF,MAAM,yBACJ,CAAC,8BAA8B,KAAK,0BAA0B,CAAC,KAAK,oBAAoB,WAAW,GAAG,IAClG,KAAK,yBACL;GAEN,IAAI,qBAAqB;GACzB,IAAI,wBAAwB;IAC1B,cAAc,KAAK,0BAA0B;IAC7C,qBAAqB,OAAO,aAAa;GAC3C;GAEA,MAAM,OAAO,aAAgB,UAAU,IAAI,QAAQ,CAAC,CAAC,SAAS,OAAO,OAAO,IAAI,CAAC;GACjF,UAAU,SAAS;GACnB,KAAK,OAAO,GAAG,KAAK,gBAAgB,GAAG,SAAS,KAAK,WAAW;GAEhE,IAAI,aAAa;IAEf,IAAI,OAAO,aAAa,MAAM,oBAC5B,yBAAyB,IAAI;IAE/B,YAAY,OAAO;GACrB;GAEA,OAAO,EAAE,KAAK;EAChB,SAAS,OAAO;GACd,UAAU,SAAS;GACnB,aAAa,SAAS;GACtB,MAAM;EACR;CACF;CAEA,oBAA4B,WAAkC,KAAa;EACzE,IAAI,UAAU,aAAa,KAAA,GACzB,OAAO,UAAU;EAGnB,IAAI,WAAW,KAAK,uBAAuB,IAAI,GAAG;EAClD,IAAI,aAAa,KAAA,GAAW;GAC1B,WAAW,4BAA4B,KAAK,GAAG,KAAK,KAAK,uBAAuB,GAAG;GACnF,KAAK,uBAAuB,IAAI,KAAK,QAAQ;EAC/C;EACA,OAAO;CACT;CAEA,uBAA+B,KAAa;EAG1C,MAAM,SAAS,KAAK,mBAA6C;GAC/D,KAAK;GACL,KAAK;GACL,QAAQ,CAAC,GAAG;GACZ,MAAM,EAAE,aAAa,SAAS;EAChC,CAAC;EACD,OAAO,OAAO,SAAS,KAAK,OAAO,OAAO,UAAU,CAAC,MAAM,EAAE;CAC/D;CAEA,QAAqB,MAAiD,SAA4C;EAChH,MAAM,MAAM,OAAO,SAAS,WAAW,OAAO,KAAK;EACnD,MAAM,OAAO,OAAO,SAAS,WAAW,KAAA,IAAY,KAAK;EAEzD,OAAO,KAAK,WAAc,KAAK,MAAM,SAAS,aAAa,SAAS,8BAA8B,KAAK;CACzG;CAEA,0BAA0B,UAA6C;EACrE,IAAI,KAAK,wBACP,MAAM,IAAI,MAAM,0DAA0D;EAE5E,KAAK,yBAAyB;CAChC;CAEA,mBAAsB,UAA6D;EACjF,MAAM,cAAc,KAAK,iBAAiB;EAC1C,IAAI;GACF,MAAM,SAAS,SAAS,IAAI;GAC5B,YAAY,OAAO;GACnB,OAAO;EACT,SAAS,OAAO;GACd,YAAY,SAAS;GACrB,MAAM;EACR;CACF;CAEA,mBAAmB;EACjB,KAAK,mBAAmB;GACtB,KAAK;GACL,KAAK;GACL,MAAM,EACJ,aAAa,SACf;EACF,CAAC;EAED,OAAO;GACL,cAAc;IACZ,KAAK,mBAAmB;KACtB,KAAK;KACL,KAAK;KACL,MAAM,EACJ,aAAa,SACf;IACF,CAAC;GACH;GACA,gBAAgB;IACd,KAAK,mBAAmB;KACtB,KAAK;KACL,KAAK;KACL,MAAM,EACJ,aAAa,SACf;IACF,CAAC;GACH;EACF;CACF;CAGA,4BAAoC;EAClC,KAAK,mBAAmB;GACtB,KAAK;GACL,KAAK;GACL,MAAM,EAAE,aAAa,SAAS;EAChC,CAAC;EAED,OAAO;GACL,cAAc;IACZ,KAAK,mBAAmB;KACtB,KAAK;KACL,KAAK;KACL,MAAM,EAAE,aAAa,SAAS;IAChC,CAAC;GACH;GACA,gBAAgB;IACd,KAAK,mBAAmB;KACtB,KAAK;KACL,KAAK;KACL,MAAM,EAAE,aAAa,SAAS;IAChC,CAAC;IACD,KAAK,mBAAmB;KACtB,KAAK;KACL,KAAK;KACL,MAAM,EAAE,aAAa,SAAS;IAChC,CAAC;GACH;EACF;CACF;CAEA,QAA4C,KAAa,MAAsB;EAC7E,MAAM,OAAO,uBAAuB,KAAK,QAAQ,MAAM,WAAW;EAClE,MAAM,OAAO,KAAK,aAAa,QAAQ,GAAG;EAC1C,KAAK,OAAO,GAAG,KAAK,gBAAgB,GAAG,WAAW,KAAK,MAAM,WAAW;EAExE,IAAI,cAAc;EAElB,MAAM,WAAW,WAAoB;GACnC,IAAI,aACF,MAAM,IAAI,MAAM,wBAAwB;GAG1C,MAAM,OAAO,uBAAuB,KAAK,QAAQ,MAAM,WAAW;GAClE,IAAI;IACF,OAAO,aAAsB,KAAK,IAAI,MAAM,UAAU,CAAC,EAAE;GAC3D,UAAU;IACR,KAAK,OAAO,GAAG,KAAK,gBAAgB,GAAG,mBAAmB,KAAK,MAAM,WAAW;GAClF;EACF;EAEA,MAAM,iBAAiB;GACrB,cAAc;GACd,KAAK,SAAS;EAChB;EAEA,MAAM,oBAAyD;GAC7D;GACA;GACA,IAAI,cAAc;IAChB,OAAO;GACT;EACF;EAEA,KAAK,mBAAmB,KAAK,iBAAoE;EAEjG,OAAO;CACT;CAEA,cAAuD,MAAsB;EAC3E,QACE,YACqC;GACrC,MAAM,QAAQ,uBAAuB,OAAO;GAC5C,MAAM,YAAY,KAAK,QAAsC,MAAM,KAAK,IAAI;GAE5E,OAAO,EACL,UAAU,eAAe,UAAU,QAAQ,MAAM,eAAe,UAAU,CAAwB,EACpG;EACF;CACF;CAEA,cACE,SACA,SACA;EACA,MAAM,QAAQ,QAAQ,WAAW,CAAC,CAAC,QAAQ;EAC3C,OAAO,KAAK,QAAQ,OAAO,OAAO;CACpC;CAEA,gBAKE,KACA,QACA,SACA,MACA;EACA,IAAI,YAAY,KAAK,sBAAsB,IAAI,GAAG;EAClD,IAAI,CAAC,WAAW;GACd,YAAY,KAAK,cAAuB,IAAI,CAAC,CAAC,OAAO;GACrD,KAAK,sBAAsB,IAAI,KAAK,SAA6D;EACnG;EAEA,OAAO,UAAU,QAAQ,MAAM;CACjC;CAEA,mBAAuD,EACrD,KACA,KACA,QACA,QAMC;EACD,IAAI,YAAY,KAAK,yBAAyB,IAAI,GAAG;EACrD,IAAI,CAAC,WAAW;GACd,YAAY,KAAK,QAAQ,KAAK,IAAI;GAClC,KAAK,yBAAyB,IAAI,KAAK,SAA8C;EACvF;EAEA,OAAO,UAAU,QAAS,UAAU,CAAC,CAAa;CACpD;CAEA,IAAiB,kBAAiD,GAAG,YAAuB;EAC1F,IAAI,OAAO,qBAAqB,UAC9B,OAAO,KAAK,QAAW;GACrB,KAAK;GACL;EACF,CAAC;EAEH,OAAO,KAAK,QAAW;GACrB,KAAK,iBAAiB,KAAK,GAAG;GAC9B;EACF,CAAC;CACH;CAEA,qBAAuG,EACrG,MACA,UACA,eACA,YACA,aACwC;EACxC,MAAM,SAAS,KAAK;EACpB,IAAI,CAAC,OAAO,sBACV,MAAM,IAAI,MAAM,sDAAsD;EAExE,OAAO,qBAAqB;GAC1B;GACA,WAAW,GAAG,SAAS,SAAS,GAAI,IAAc;GAClD,OAAO,SAAS;GAChB;GACA;GACA;EACF,CAAC;CACH;CAEA,YAAY,UAAuC;EACjD,MAAM,OAAO,uBAAuB,KAAK,QAAQ,QAAQ;EACzD,MAAM,SAAS,KAAK;EACpB,IAAI,CAAC,OAAO,aACV,MAAM,IAAI,MAAM,+CAA+C;EAEjE,OAAO,YAAY,QAAQ;EAE3B,KAAK,mBAAmB;EAExB,KAAK,OAAO,eAAe,WAAW,QAAQ;CAChD;CAEA,iBAAiB;EACf,MAAM,SAAS,KAAK;EACpB,IAAI,CAAC,OAAO,WACV,MAAM,IAAI,MAAM,+CAA+C;EAEjE,OAAO,OAAO,UAAU;CAC1B;CAEA,qBAAqB;EACnB,KAAK,iBAAiB;CACxB;CAEA,UAAU;EACR,KAAK,mBAAmB,SAAS,SAAS;GACxC,KAAK,SAAS;EAChB,CAAC;EACD,KAAK,mBAAmB,OAAO,CAAC;EAChC,KAAK,sBAAsB,MAAM;EACjC,KAAK,yBAAyB,MAAM;EACpC,KAAK,uBAAuB,MAAM;CACpC;CAEA,QAAQ;EACN,KAAK,QAAQ;EAEb,KAAK,QAAQ,MAAM;EACnB,KAAK,SAAS;CAChB;AACF;AAEA,SAAS,aACP,EAAE,SAAS,QACX,WACK;CACL,MAAM,SAAc,CAAC;CACrB,KAAK,MAAM,UAAU,MAAM;EACzB,MAAM,MAAM,UAAU;EACtB,KAAK,IAAI,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAC1C,IAAI,QAAQ,UAAU,OAAO;EAE/B,OAAO,KAAK,GAAQ;CACtB;CACA,OAAO;AACT;AAkBA,SAAgB,uBACd,SACA;CACA,MAAM,gCAAgB,IAAI,IAA4B;CACtD,MAAM,QAAQ,QAAQ,cAAc,QAAQ;EAC1C,MAAM,QAAQ,CAAC;EACf,cAAc,IAAI,OAAO,GAAG;EAC5B,OAAO;CACT,CAAC,CAAC,CAAC,QAAQ;CAEX,OAAO;EACL,KAAK,MAAM;EACX,iBAAiB,eACf,MAAM,WAAW,KAAK,UAAU;GAC9B,MAAM,MAAM,cAAc,IAAI,KAAK;GACnC,OAAO,QAAQ,KAAA,IAAY,QAAQ,WAAW;EAChD,CAAC;CACL;AACF;;;AC7dA,SAAgB,kBAAqB,EACnC,cACA,iBAIiB;CACjB,IAAI,eAAe;CAEnB,OAAO;EACL,IAAI,UAAU;GACZ,OAAO;EACT;EACA,IAAI,QAAQ,UAAa;GACvB,gBAAgB,QAAQ;GACxB,eAAe;EACjB;CACF;AACF;;;ACbA,SAAgB,wBAAwB,QAAsB,WAAmB;CAC/E,OAAO,OACJ,YAAY,SAAS,CAAC,CACtB,YAAY,CAAC,CACb,UAAU,OAAO,SAAS,QAAQ,IAAI,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,CAC7D,UAAU,SAAS,SAAS,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAClD,UAAU,GAAG,eAAe;AACjC;AAEA,SAAgB,oBAAoB,EAAE,IAAI,iBAA4E;CACpH,MAAM,SAAS;CAIf,MAAM,OAAO,QAA+B;EAC1C,MAAM,CAAC,UAAU,OAAO,gBACtB,kBACA,EAAE,IAAI,IACL,IAAI,WACH,GACG,WAAW,aAAuB,CAAC,CACnC,MAAM,OAAO,KAAK,OAAO,KAAK,CAAC,CAAC,CAChC,OAAO,OAAO,CAAC,CACf,OAAO,OAAO,GAAG,IAAI,CAAC,CAAC,GAC5B,EAAE,aAAa,SAAS,CAC1B;EAEA,OAAO,QAAQ,SAAS;CAC1B;CAEA,MAAM,OAAO,KAAa,UAAkB;EAC1C,OAAO,gBACL,kBACA;GAAE;GAAK;EAAM,IACZ,IAAI,WACH,GACG,WAAW,aAAuB,CAAC,CACnC,OAAO;GAAE,KAAK,OAAO,KAAK;GAAG,OAAO,OAAO,OAAO;EAAE,CAAC,CAAC,CACtD,YAAY,OAAO,GAAG,YAAY,EAAE,OAAO,OAAO,OAAO,EAAE,CAAC,CAAC,GAClE,EAAE,aAAa,SAAS,CAC1B;CACF;CAEA,MAAM,UAAU,QAAgB;EAC9B,OAAO,gBACL,qBACA,EAAE,IAAI,IACL,IAAI,WAAW,GAAG,WAAW,aAAuB,CAAC,CAAC,MAAM,OAAO,KAAK,OAAO,KAAK,CAAC,GACtF,EAAE,aAAa,SAAS,CAC1B;CACF;CAEA,MAAM,sBAAyB,KAAa,iBAAgC;EAC1E,MAAM,QAAQ,IAAI,GAAG;EACrB,IAAI,CAAC,OAAO,OAAO;EACnB,MAAM,cAAc,OAAO,SAAS,OAAO,EAAE;EAC7C,OAAO,OAAO,MAAM,WAAW,IAAI,eAAe;CACpD;CAEA,OAAO;EACL;EACA;EACA;EACA,0BAA0B,KAAa,iBACrC,kBAA0B;GACxB,cAAc,IAAI,GAAG,KAAK;GAC1B,gBAAgB,QAAQ,IAAI,KAAK,GAAG;EACtC,CAAC;EACH,0BAA0B,KAAa,iBACrC,kBAA0B;GACxB,cAAc,mBAAmB,KAAK,YAAY;GAClD,gBAAgB,QAAQ,IAAI,KAAK,IAAI,SAAS,CAAC;EACjD,CAAC;CACL;AACF;AAIA,MAAa,oBAAoB;AAEjC,SAAgB,uBAAuB,SAAuD;CAC5F,OAAO;EACL,YAAY,QAAQ,IAAI,iBAAiB;EACzC,QAAQ,UAAU,QAAQ,IAAI,mBAAmB,KAAK;CACxD;AACF;;;AChFA,SAAgB,qBAAqB,EACnC,iBACA,sBAIiB;CACjB,OAAO;EACL,aAAa,eAAe,eAAe;EAC3C,gBAAgB,eAAe,kBAAkB;CACnD;AACF;AAQA,MAAa,iBAAiB,qBAAqB;CACjD,iBAAiB;CACjB,oBAAoB;AACtB,CAAC;AAQD,MAAa,gBAAgB,qBAAqB;CAChD,iBAAiB;CACjB,oBAAoB;AACtB,CAAC;AAED,MAAa,sBAAsB;AAOnC,MAAa,iBAAiB,qBAAqB;CACjD,iBAAiB;CACjB,oBAAoB;AACtB,CAAC;AAWD,MAAM,wBAAwB,iBAAiB,yBAAyB;AAExE,MAAa,uBAA0C;CACrD;EACE,SAAS;EACT,KAAK,QAAgC;GACnC,IAAI,QAAQ,8BAA8B,IAAI,YAAY,eAAe;;;;;;;;;;QAUvE;GACF,IAAI,QAAQ,8BAA8B,IAAI,eAAe,eAAe;;;;;QAK1E;EACJ;CACF;CACA;EACE,SAAS;EACT,KAAK,QAAgC;GACnC,IAAI,QAAQ,eAAe,IAAI,YAAY,eAAe,sDAAsD;EAClH;CACF;CACA;EACE,SAAS;EACT,KAAK,QAAgC;GACnC,MAAM,YAAY,GAAG,IAAI,YAAY,MAAM;GAC3C,IAAI,QACF,8BAA8B,IAAI,YAAY,OAAO,GAAG,UAAU,MAAM,IAAI,YAAY,MAAM,uBAChG;EACF;CACF;CACA;EACE,SAAS;EACT,KAAK,QAAgC;GACnC,MAAM,YAAY,GAAG,IAAI,YAAY,MAAM;GAC3C,IAAI,QACF,8BAA8B,IAAI,YAAY,OAAO,GAAG,UAAU,MAAM,IAAI,YAAY,MAAM,oCAChG;EACF;CACF;CACA;EACE,SAAS;EACT,KAAK,QAAgC;GACnC,MAAM,YAAY,GAAG,IAAI,YAAY,MAAM;GAC3C,IAAI,QACF,8BAA8B,IAAI,YAAY,OAAO,GAAG,UAAU,MAAM,IAAI,YAAY,MAAM,gCAAgC,uBAChI;EACF;CACF;CACA;EAIE,SAAS;EACT,KAAK,QAAgC;GACnC,IAAI,QAAQ,UAAU,QAAQ,IAAI,eAAe,cAAc,EAAE;;;;SAI9D,QAAQ,IAAI,YAAY,cAAc,EAAE;+DACc,sBAAsB;;;;iFAIJ;EAC7E;CACF;AACF;AAEA,SAAgB,oBAAoB,MAM3B;CACP,MAAM,MAA8B;EAClC,GAAG,KAAK;EACR,SAAS,KAAK;CAChB;CACA,KAAK,MAAM,aAAa,KAAK,YAC3B,IAAI,UAAU,UAAU,KAAK,QAAQ,SACnC,KAAK,kBAAkB;EACrB,UAAU,GAAG,GAAG;EAChB,KAAK,QAAQ,UAAU,UAAU;CACnC,CAAC;AAGP;AAEA,SAAgB,oBAAoB,IAA0B;CAC5D,OAAO,oBAAoB,IAAI;EAAE,aAAa;EAAa,UAAU;CAAe,CAAC;AACvF;AAEA,SAAgB,mBAAmB,IAA0B;CAC3D,OAAO,oBAAoB,IAAI;EAAE,aAAa;EAAqB,UAAU;CAAc,CAAC;AAC9F;AAEA,SAAS,oBACP,IACA,EAAE,aAAa,YACf;CAEA,GAAG,eAAe,WAAW,wBAAwB,OAAO,QAAQ,WAAW,GAAG,EAAE,aAAa,SAAS,CAAC;CAG3G,MAAM,UAAU,oBAAoB;EAAE;EAAI,eAAe;CAAY,CAAC;CACtE,oBAAoB;EAClB,YAAY;EACZ,SAAS,QAAQ,wBAAwB,2BAA2B,EAAE;EACtE;EACA,UAAU,QAAQ,GAAG,QAAQ,KAAK,EAAE,aAAa,SAAS,CAAC;EAC3D,cAAc,aAAa,GAAG,mBAAmB,QAAQ;CAC3D,CAAC;CAED,OAAO,EAAE,QAAQ;AACnB;AAEA,SAAgB,oBAAoB,IAA0B;CAC5D,GAAG,QACD,8BAA8B,eAAe,YAAY,eAAe;;;;;;;;;;;MAYxE,EAAE,aAAa,SAAS,CAC1B;CACA,GAAG,QACD,8BAA8B,eAAe,YAAY,MAAM,yBAAyB,eAAe,YAAY,MAAM,yBACzH,EACE,aAAa,SACf,CACF;CACA,GAAG,QACD,8BAA8B,eAAe,YAAY,MAAM,mCAAmC,eAAe,YAAY,MAAM,sCACnI,EACE,aAAa,SACf,CACF;CACA,GAAG,QACD,8BAA8B,eAAe,YAAY,MAAM,oCAAoC,eAAe,YAAY,MAAM,gCAAgC,yBACpK,EACE,aAAa,SACf,CACF;CACA,GAAG,QACD,8BAA8B,eAAe,eAAe,eAAe;;;;;IAM3E,EAAE,aAAa,SAAS,CAC1B;AACF"}
|
package/dist/worker.d.ts
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
import { C as
|
|
2
|
-
|
|
3
|
-
type WsRemoteSourceConfig = {
|
|
4
|
-
createWebSocket: () => Pick<WebSocket, "onmessage" | "close" | "addEventListener" | "removeEventListener"> & {
|
|
5
|
-
readyState: number;
|
|
6
|
-
send: (data: string) => void;
|
|
7
|
-
};
|
|
8
|
-
};
|
|
9
|
-
declare const createWsRemoteSource: ({ createWebSocket }: WsRemoteSourceConfig) => CreateRemoteSourceFactory;
|
|
10
|
-
//#endregion
|
|
1
|
+
import { C as EventsPullRequest, O as WorkerConfig, S as CreateRemoteSourceFactory, T as EventsPushResponse, Zt as Logger, c as ResetStore, ct as GetEventsBatch, un as SyncDbSchema, w as EventsPushRequest } from "./index-CH4lf3iX.js";
|
|
2
|
+
import { t as createWsRemoteSource } from "./ws-remote-source-DFBhDc6Z.js";
|
|
11
3
|
//#region src/worker-db/db-worker.d.ts
|
|
12
4
|
declare function getWorkerConfig<Props = never>(): Promise<WorkerConfig<Props>>;
|
|
13
5
|
type WorkerOptions = {
|