@sqlite-sync/core 0.12.3 → 0.13.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/{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
package/dist/index.js
CHANGED
|
@@ -1,655 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as acquireLock, d as noop, h as tryCatchAsync, i as TypedEvent, l as generateId, m as tryCatch, n as isNoOpCrdtEventPayload, o as createDeferredPromise, p as quoteId, r as TypedBroadcastChannel, s as createTypedEventTarget, t as CRDT_EVENT_NO_OP_PAYLOAD, u as jsonSafeParse } from "./crdt-table-schema-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { n as
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
set = (key, value) => {
|
|
18
|
-
if (this.onRemove && this.map.has(key)) {
|
|
19
|
-
const old = this.map.get(key);
|
|
20
|
-
this.map.set(key, value);
|
|
21
|
-
this.onRemove(key, old);
|
|
22
|
-
} else this.map.set(key, value);
|
|
23
|
-
if (this.map.size > this.maxSize) {
|
|
24
|
-
const firstKey = this.map.keys().next().value;
|
|
25
|
-
this.delete(firstKey);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
get = (key) => {
|
|
29
|
-
return this.map.get(key);
|
|
30
|
-
};
|
|
31
|
-
delete = (key) => {
|
|
32
|
-
if (this.onRemove && this.map.has(key)) {
|
|
33
|
-
const value = this.map.get(key);
|
|
34
|
-
this.map.delete(key);
|
|
35
|
-
this.onRemove(key, value);
|
|
36
|
-
} else this.map.delete(key);
|
|
37
|
-
};
|
|
38
|
-
clear = () => {
|
|
39
|
-
const onRemove = this.onRemove;
|
|
40
|
-
if (onRemove) this.map.forEach((value, key) => {
|
|
41
|
-
onRemove(key, value);
|
|
42
|
-
});
|
|
43
|
-
this.map.clear();
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
//#endregion
|
|
47
|
-
//#region src/memory-db/sqlite-reactive-db.ts
|
|
48
|
-
let sqliteModule = null;
|
|
49
|
-
function createSQLiteReactiveDb(opts) {
|
|
50
|
-
return SQLiteReactiveDb.create(opts);
|
|
51
|
-
}
|
|
52
|
-
var SQLiteReactiveDb = class SQLiteReactiveDb {
|
|
53
|
-
db;
|
|
54
|
-
sqlite3;
|
|
55
|
-
logger;
|
|
56
|
-
tablesUsedStatement = null;
|
|
57
|
-
eventTarget = createTypedEventTarget();
|
|
58
|
-
mutationVersion = 0;
|
|
59
|
-
tableMutationVersions = /* @__PURE__ */ new Map();
|
|
60
|
-
constructor(sqlite3, logger) {
|
|
61
|
-
this.sqlite3 = sqlite3;
|
|
62
|
-
this.logger = logger;
|
|
63
|
-
this.db = new SQLiteDbWrapper({
|
|
64
|
-
db: () => new sqlite3.oo1.DB({ filename: ":memory:" }),
|
|
65
|
-
logger: this.logger,
|
|
66
|
-
loggerPrefix: "memory",
|
|
67
|
-
sqlite3
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
static async create(opts) {
|
|
71
|
-
const logger = opts.logger;
|
|
72
|
-
const perf = startPerformanceLogger(logger, "system");
|
|
73
|
-
if (!sqliteModule) sqliteModule = await sqlite3InitModule();
|
|
74
|
-
const db = new SQLiteReactiveDb(sqliteModule, logger);
|
|
75
|
-
if (opts.snapshot) db.useSnapshot(opts.snapshot);
|
|
76
|
-
db.registerDbHooks();
|
|
77
|
-
perf.logEnd("createSQLiteMemoryDb", "success", "system");
|
|
78
|
-
return db;
|
|
79
|
-
}
|
|
80
|
-
liveQueryStatements = new BoundMap({
|
|
81
|
-
maxSize: 100,
|
|
82
|
-
onRemove(_, value) {
|
|
83
|
-
value.finalize();
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
sharedLiveQueries = /* @__PURE__ */ new Map();
|
|
87
|
-
createLiveQuery(query) {
|
|
88
|
-
let rowsVersion = 0;
|
|
89
|
-
const fetchRows = (parameters) => {
|
|
90
|
-
let statement = this.liveQueryStatements.get(query.sql);
|
|
91
|
-
if (!statement) {
|
|
92
|
-
statement = this.db.prepare(query.sql);
|
|
93
|
-
this.liveQueryStatements.set(query.sql, statement);
|
|
94
|
-
}
|
|
95
|
-
rowsVersion = this.mutationVersion;
|
|
96
|
-
return statement.execute(parameters);
|
|
97
|
-
};
|
|
98
|
-
let rows = null;
|
|
99
|
-
const getRows = () => {
|
|
100
|
-
if (!rows) rows = fetchRows(query.parameters);
|
|
101
|
-
return rows;
|
|
102
|
-
};
|
|
103
|
-
let subscriber = null;
|
|
104
|
-
let lastParameters = query.parameters;
|
|
105
|
-
const refresh = (parameters) => {
|
|
106
|
-
if (parameters) lastParameters = parameters;
|
|
107
|
-
rows = fetchRows(lastParameters);
|
|
108
|
-
subscriber?.();
|
|
109
|
-
};
|
|
110
|
-
const subscribe = (onchange) => {
|
|
111
|
-
if (subscriber) throw new Error("Subscriber already exists");
|
|
112
|
-
subscriber = onchange;
|
|
113
|
-
const subscription = this.subscribeToQueryChanges({
|
|
114
|
-
sql: query.sql,
|
|
115
|
-
onDataChange: refresh
|
|
116
|
-
});
|
|
117
|
-
if (rows && this.mutationVersion !== rowsVersion) refresh();
|
|
118
|
-
return () => {
|
|
119
|
-
subscription.unsubscribe();
|
|
120
|
-
subscriber = null;
|
|
121
|
-
};
|
|
122
|
-
};
|
|
123
|
-
return {
|
|
124
|
-
getRows,
|
|
125
|
-
refresh,
|
|
126
|
-
subscribe
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
getSharedLiveQuery(query) {
|
|
130
|
-
const existingEntry = this.sharedLiveQueries.get(query.sql)?.find((entry) => parametersAreEqual(entry.parameters, query.parameters));
|
|
131
|
-
if (existingEntry) {
|
|
132
|
-
if (existingEntry.listeners.size === 0) this.scheduleSharedLiveQueryCleanup(existingEntry);
|
|
133
|
-
return existingEntry;
|
|
134
|
-
}
|
|
135
|
-
const liveQuery = this.createLiveQuery(query);
|
|
136
|
-
const entry = {
|
|
137
|
-
sql: query.sql,
|
|
138
|
-
parameters: query.parameters,
|
|
139
|
-
listeners: /* @__PURE__ */ new Set(),
|
|
140
|
-
unsubscribeFromLiveQuery: null,
|
|
141
|
-
cleanupTimeout: null,
|
|
142
|
-
getRows: () => liveQuery.getRows(),
|
|
143
|
-
refresh: () => {
|
|
144
|
-
liveQuery.refresh();
|
|
145
|
-
},
|
|
146
|
-
getSubscriberCount: () => entry.listeners.size,
|
|
147
|
-
subscribe: (onchange) => {
|
|
148
|
-
this.cancelSharedLiveQueryCleanup(entry);
|
|
149
|
-
this.registerSharedLiveQueryEntry(entry);
|
|
150
|
-
entry.listeners.add(onchange);
|
|
151
|
-
if (!entry.unsubscribeFromLiveQuery) entry.unsubscribeFromLiveQuery = liveQuery.subscribe(() => {
|
|
152
|
-
for (const listener of entry.listeners) listener();
|
|
153
|
-
});
|
|
154
|
-
return () => {
|
|
155
|
-
entry.listeners.delete(onchange);
|
|
156
|
-
if (entry.listeners.size === 0) {
|
|
157
|
-
entry.unsubscribeFromLiveQuery?.();
|
|
158
|
-
entry.unsubscribeFromLiveQuery = null;
|
|
159
|
-
this.scheduleSharedLiveQueryCleanup(entry);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
this.registerSharedLiveQueryEntry(entry);
|
|
165
|
-
this.scheduleSharedLiveQueryCleanup(entry);
|
|
166
|
-
return entry;
|
|
167
|
-
}
|
|
168
|
-
registerSharedLiveQueryEntry(entry) {
|
|
169
|
-
const matchingSqlEntries = this.sharedLiveQueries.get(entry.sql) ?? [];
|
|
170
|
-
if (!matchingSqlEntries.includes(entry)) {
|
|
171
|
-
matchingSqlEntries.push(entry);
|
|
172
|
-
this.sharedLiveQueries.set(entry.sql, matchingSqlEntries);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
getSharedLiveQueriesSnapshot() {
|
|
176
|
-
const snapshot = [];
|
|
177
|
-
for (const entries of this.sharedLiveQueries.values()) for (const entry of entries) snapshot.push({
|
|
178
|
-
sql: entry.sql,
|
|
179
|
-
parameters: entry.parameters,
|
|
180
|
-
subscriberCount: entry.listeners.size
|
|
181
|
-
});
|
|
182
|
-
return snapshot;
|
|
183
|
-
}
|
|
184
|
-
scheduleSharedLiveQueryCleanup(entry) {
|
|
185
|
-
this.cancelSharedLiveQueryCleanup(entry);
|
|
186
|
-
entry.cleanupTimeout = setTimeout(() => {
|
|
187
|
-
entry.cleanupTimeout = null;
|
|
188
|
-
this.releaseSharedLiveQuery(entry);
|
|
189
|
-
}, 0);
|
|
190
|
-
}
|
|
191
|
-
cancelSharedLiveQueryCleanup(entry) {
|
|
192
|
-
if (entry.cleanupTimeout) {
|
|
193
|
-
clearTimeout(entry.cleanupTimeout);
|
|
194
|
-
entry.cleanupTimeout = null;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
releaseSharedLiveQuery(entry) {
|
|
198
|
-
if (entry.listeners.size > 0 || entry.unsubscribeFromLiveQuery) return;
|
|
199
|
-
const matchingSqlEntries = this.sharedLiveQueries.get(entry.sql);
|
|
200
|
-
if (!matchingSqlEntries) return;
|
|
201
|
-
const nextEntries = matchingSqlEntries.filter((candidate) => candidate !== entry);
|
|
202
|
-
if (nextEntries.length > 0) this.sharedLiveQueries.set(entry.sql, nextEntries);
|
|
203
|
-
else this.sharedLiveQueries.delete(entry.sql);
|
|
204
|
-
}
|
|
205
|
-
subscribeToQueryChanges(params) {
|
|
206
|
-
const { sql, onDataChange } = params;
|
|
207
|
-
const tables = this.getTablesUsed(sql);
|
|
208
|
-
const readTables = /* @__PURE__ */ new Set();
|
|
209
|
-
for (const table of tables) if (!readTables.has(table.name)) readTables.add(table.name);
|
|
210
|
-
else if (table.isWrite) throw new Error("This query writes and reads from the same table. This may cause infinite loops.");
|
|
211
|
-
const notifyDataChange = createDebouncedCallback(() => {
|
|
212
|
-
onDataChange();
|
|
213
|
-
}, 30);
|
|
214
|
-
for (const table of readTables) this.eventTarget.addEventListener(`table:${table}`, notifyDataChange);
|
|
215
|
-
this.eventTarget.addEventListener("any-table-changed", notifyDataChange);
|
|
216
|
-
return { unsubscribe: () => {
|
|
217
|
-
for (const table of readTables) this.eventTarget.removeEventListener(`table:${table}`, notifyDataChange);
|
|
218
|
-
this.eventTarget.removeEventListener("any-table-changed", notifyDataChange);
|
|
219
|
-
} };
|
|
220
|
-
}
|
|
221
|
-
subscribeToTableChanges(table, onChanges) {
|
|
222
|
-
this.eventTarget.addEventListener(`table:${table}`, onChanges);
|
|
223
|
-
this.eventTarget.addEventListener("any-table-changed", onChanges);
|
|
224
|
-
return { unsubscribe: () => {
|
|
225
|
-
this.eventTarget.removeEventListener(`table:${table}`, onChanges);
|
|
226
|
-
this.eventTarget.removeEventListener("any-table-changed", onChanges);
|
|
227
|
-
} };
|
|
228
|
-
}
|
|
229
|
-
getTablesUsed(query) {
|
|
230
|
-
if (!this.tablesUsedStatement) this.tablesUsedStatement = this.db.prepare("select t.tbl_name as name, u.wr as isWrite from tables_used(?) as u inner join sqlite_master as t on t.name = u.name where u.schema = 'main'", { loggerLevel: "system" });
|
|
231
|
-
const tables = this.tablesUsedStatement.execute([query]);
|
|
232
|
-
if (tables.length === 0 && query.toLowerCase().includes("delete")) tables.push(...this.getClearedTables(query));
|
|
233
|
-
return tables;
|
|
234
|
-
}
|
|
235
|
-
getClearedTables(query) {
|
|
236
|
-
const operations = this.db.execute(`EXPLAIN ${query.split(";")[0]}`, { loggerLevel: "system" }).rows;
|
|
237
|
-
const clearedTablesRootPages = /* @__PURE__ */ new Set();
|
|
238
|
-
for (const operation of operations) if (operation.opcode === "Clear" && operation.p2 === 0) clearedTablesRootPages.add(operation.p1);
|
|
239
|
-
if (clearedTablesRootPages.size === 0) return [];
|
|
240
|
-
return this.db.execute(`select t.tbl_name as name, true as isWrite from sqlite_master as t where t.rootpage in (${Array.from(clearedTablesRootPages).join(",")})`, { loggerLevel: "system" }).rows;
|
|
241
|
-
}
|
|
242
|
-
addEventListener(type, listener) {
|
|
243
|
-
this.eventTarget.addEventListener(type, listener);
|
|
244
|
-
}
|
|
245
|
-
removeEventListener(type, listener) {
|
|
246
|
-
this.eventTarget.removeEventListener(type, listener);
|
|
247
|
-
}
|
|
248
|
-
getTableMutationVersion(table) {
|
|
249
|
-
return this.tableMutationVersions.get(table) ?? 0;
|
|
250
|
-
}
|
|
251
|
-
notifyTableSubscribers(tables = null) {
|
|
252
|
-
if (!tables) {
|
|
253
|
-
this.eventTarget.dispatchEvent("any-table-changed", void 0);
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
for (const table of tables) this.eventTarget.dispatchEvent(`table:${table}`, void 0);
|
|
257
|
-
}
|
|
258
|
-
registerDbHooks() {
|
|
259
|
-
let updateQueue = /* @__PURE__ */ new Set();
|
|
260
|
-
this.sqlite3.capi.sqlite3_update_hook(this.db.ensureDb, (_ctx, _opId, _db, table) => {
|
|
261
|
-
updateQueue.add(table);
|
|
262
|
-
this.tableMutationVersions.set(table, ++this.mutationVersion);
|
|
263
|
-
}, 0);
|
|
264
|
-
this.sqlite3.capi.sqlite3_rollback_hook(this.db.ensureDb, () => {
|
|
265
|
-
if (updateQueue.size === 0) return 0;
|
|
266
|
-
updateQueue.clear();
|
|
267
|
-
this.eventTarget.dispatchEvent("transaction-rolled-back", void 0);
|
|
268
|
-
return 0;
|
|
269
|
-
}, 0);
|
|
270
|
-
this.sqlite3.capi.sqlite3_commit_hook(this.db.ensureDb, () => {
|
|
271
|
-
if (updateQueue.size === 0) return 0;
|
|
272
|
-
const tables = updateQueue;
|
|
273
|
-
updateQueue = /* @__PURE__ */ new Set();
|
|
274
|
-
this.eventTarget.dispatchEvent("transaction-committed", void 0);
|
|
275
|
-
queueMicrotask(() => {
|
|
276
|
-
this.notifyTableSubscribers(tables);
|
|
277
|
-
});
|
|
278
|
-
return 0;
|
|
279
|
-
}, 0);
|
|
280
|
-
}
|
|
281
|
-
createSnapshot() {
|
|
282
|
-
const perf = startPerformanceLogger(this.logger);
|
|
283
|
-
const snapshot = this.sqlite3.capi.sqlite3_js_db_export(this.db.ensureDb);
|
|
284
|
-
perf.logEnd("createSnapshot", `snapshot size: ${snapshot.byteLength}`, "info");
|
|
285
|
-
return snapshot;
|
|
286
|
-
}
|
|
287
|
-
useSnapshot(snapshot) {
|
|
288
|
-
this.db.useSnapshot(snapshot);
|
|
289
|
-
this.mutationVersion++;
|
|
290
|
-
this.notifyTableSubscribers();
|
|
291
|
-
}
|
|
292
|
-
dispose() {
|
|
293
|
-
for (const entries of this.sharedLiveQueries.values()) for (const entry of entries) {
|
|
294
|
-
this.cancelSharedLiveQueryCleanup(entry);
|
|
295
|
-
entry.unsubscribeFromLiveQuery?.();
|
|
296
|
-
entry.unsubscribeFromLiveQuery = null;
|
|
297
|
-
entry.listeners.clear();
|
|
298
|
-
}
|
|
299
|
-
this.sharedLiveQueries.clear();
|
|
300
|
-
this.liveQueryStatements.clear();
|
|
301
|
-
if (this.tablesUsedStatement) {
|
|
302
|
-
this.tablesUsedStatement.finalize();
|
|
303
|
-
this.tablesUsedStatement = null;
|
|
304
|
-
}
|
|
305
|
-
this.db.close();
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
function createDebouncedCallback(callback, delay) {
|
|
309
|
-
let timeout = null;
|
|
310
|
-
let shouldCallWithoutDelay = true;
|
|
311
|
-
return (...args) => {
|
|
312
|
-
if (shouldCallWithoutDelay) {
|
|
313
|
-
callback(...args);
|
|
314
|
-
shouldCallWithoutDelay = false;
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
const effect = () => {
|
|
318
|
-
timeout = null;
|
|
319
|
-
shouldCallWithoutDelay = true;
|
|
320
|
-
return callback(...args);
|
|
321
|
-
};
|
|
322
|
-
if (timeout) clearTimeout(timeout);
|
|
323
|
-
timeout = setTimeout(effect, delay);
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
function parametersAreEqual(a, b) {
|
|
327
|
-
if (a === b) return true;
|
|
328
|
-
if (!a || !b) return false;
|
|
329
|
-
if (a.length !== b.length) return false;
|
|
330
|
-
for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return false;
|
|
331
|
-
return true;
|
|
332
|
-
}
|
|
333
|
-
//#endregion
|
|
334
|
-
//#region src/schema/define-sync-schema.ts
|
|
335
|
-
const RESERVED_TABLE_NAMES = /* @__PURE__ */ new Set([
|
|
336
|
-
"change_history",
|
|
337
|
-
"crdt_events",
|
|
338
|
-
"worker.crdt_events",
|
|
339
|
-
"persisted_crdt_events",
|
|
340
|
-
"crdt_update_log",
|
|
341
|
-
"crdt_change_intents",
|
|
342
|
-
"worker.kv"
|
|
343
|
-
]);
|
|
344
|
-
/**
|
|
345
|
-
* Define a sync database schema from `t.table()` builders.
|
|
346
|
-
*
|
|
347
|
-
* Record keys are the crdt (view) table names; base table names default to the key
|
|
348
|
-
* prefixed with "_", overridable per table via `t.table(cols, { baseName })`.
|
|
349
|
-
*/
|
|
350
|
-
function defineSyncSchema({ tables, migrations }) {
|
|
351
|
-
const tablesConfig = Object.entries(tables).map(([crdtTableName, table]) => ({
|
|
352
|
-
crdtTableName,
|
|
353
|
-
baseTableName: table.baseName ?? `_${crdtTableName}`,
|
|
354
|
-
...table.exportImport === "ignore" ? { exportImport: "ignore" } : {}
|
|
355
|
-
}));
|
|
356
|
-
const seenNames = /* @__PURE__ */ new Set();
|
|
357
|
-
for (const { crdtTableName, baseTableName } of tablesConfig) for (const name of [crdtTableName, baseTableName]) {
|
|
358
|
-
const normalizedName = name.toLowerCase();
|
|
359
|
-
if (RESERVED_TABLE_NAMES.has(normalizedName)) throw new Error(`Table name "${name}" is reserved by sqlite-sync and cannot be used in a sync schema`);
|
|
360
|
-
if (seenNames.has(normalizedName)) throw new Error(`Duplicate table name "${name}" in sync schema`);
|
|
361
|
-
seenNames.add(normalizedName);
|
|
362
|
-
}
|
|
363
|
-
const writeOriginByName = buildWriteOriginByName({
|
|
364
|
-
tables,
|
|
365
|
-
tablesConfig
|
|
366
|
-
});
|
|
367
|
-
return {
|
|
368
|
-
tables,
|
|
369
|
-
get tablesConfig() {
|
|
370
|
-
return tablesConfig;
|
|
371
|
-
},
|
|
372
|
-
get writeOriginByName() {
|
|
373
|
-
return writeOriginByName;
|
|
374
|
-
},
|
|
375
|
-
get migrations() {
|
|
376
|
-
return migrations;
|
|
377
|
-
},
|
|
378
|
-
get "~clientSchema"() {
|
|
379
|
-
throw new Error("~clientSchema is type-only and cannot be accessed at runtime");
|
|
380
|
-
},
|
|
381
|
-
get "~serverSchema"() {
|
|
382
|
-
throw new Error("~serverSchema is type-only and cannot be accessed at runtime");
|
|
383
|
-
},
|
|
384
|
-
get "~mutationsSchema"() {
|
|
385
|
-
throw new Error("~mutationsSchema is type-only and cannot be accessed at runtime");
|
|
386
|
-
}
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
//#endregion
|
|
390
|
-
//#region src/schema/table-builder.ts
|
|
391
|
-
var ColumnBuilder = class ColumnBuilder {
|
|
392
|
-
meta;
|
|
393
|
-
constructor(meta) {
|
|
394
|
-
this.meta = meta;
|
|
395
|
-
}
|
|
396
|
-
/** Allow SQL NULL; widens the value type with `null`. */
|
|
397
|
-
nullable() {
|
|
398
|
-
return new ColumnBuilder({
|
|
399
|
-
...this.meta,
|
|
400
|
-
nullable: true
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
/** Declare a column default. The value is used both in DDL and when migrating older events. */
|
|
404
|
-
default(value) {
|
|
405
|
-
return new ColumnBuilder({
|
|
406
|
-
...this.meta,
|
|
407
|
-
hasDefault: true,
|
|
408
|
-
defaultValue: value
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
/** Narrow the TypeScript value type without changing storage, e.g. `t.text().$type<"movie" | "tv">()`. */
|
|
412
|
-
$type() {
|
|
413
|
-
return this;
|
|
414
|
-
}
|
|
415
|
-
/** Human/AI-readable description, surfaced in generated schema docs. */
|
|
416
|
-
describe(description) {
|
|
417
|
-
return new ColumnBuilder({
|
|
418
|
-
...this.meta,
|
|
419
|
-
description
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
};
|
|
423
|
-
const RESERVED_COLUMNS = ["id", "tombstone"];
|
|
424
|
-
const idColumnMeta = {
|
|
425
|
-
kind: "text",
|
|
426
|
-
sqlType: "text",
|
|
427
|
-
nullable: false,
|
|
428
|
-
hasDefault: false,
|
|
429
|
-
description: "Unique immutable item id"
|
|
430
|
-
};
|
|
431
|
-
const tombstoneColumnMeta = {
|
|
432
|
-
kind: "boolean",
|
|
433
|
-
sqlType: "integer",
|
|
434
|
-
nullable: false,
|
|
435
|
-
hasDefault: true,
|
|
436
|
-
defaultValue: false,
|
|
437
|
-
description: "Soft-delete marker"
|
|
438
|
-
};
|
|
439
|
-
var TableBuilder = class TableBuilder {
|
|
440
|
-
userColumns;
|
|
441
|
-
/** All columns in DDL order, including the auto-injected `id` and `tombstone`. */
|
|
442
|
-
columns;
|
|
443
|
-
baseName;
|
|
444
|
-
description;
|
|
445
|
-
/** Resolved {@link AiAccess}; defaults to `"read-write"`. */
|
|
446
|
-
aiAccess;
|
|
447
|
-
/** Resolved {@link WriteOrigin}; defaults to `"any"`. */
|
|
448
|
-
writeOrigin;
|
|
449
|
-
/** Resolved {@link ExportImportMode}; defaults to `"include"`. */
|
|
450
|
-
exportImport;
|
|
451
|
-
constructor(userColumns, options) {
|
|
452
|
-
this.userColumns = userColumns;
|
|
453
|
-
for (const reserved of RESERVED_COLUMNS) if (reserved in userColumns) throw new Error(`Column "${reserved}" is added automatically to every synced table and cannot be declared`);
|
|
454
|
-
this.columns = {
|
|
455
|
-
id: idColumnMeta,
|
|
456
|
-
...Object.fromEntries(Object.entries(userColumns).map(([name, column]) => [name, column.meta])),
|
|
457
|
-
tombstone: tombstoneColumnMeta
|
|
458
|
-
};
|
|
459
|
-
this.baseName = options?.baseName;
|
|
460
|
-
this.description = options?.description;
|
|
461
|
-
this.aiAccess = options?.ai ?? "read-write";
|
|
462
|
-
this.writeOrigin = options?.writes ?? "any";
|
|
463
|
-
this.exportImport = options?.exportImport ?? "include";
|
|
464
|
-
}
|
|
465
|
-
describe(description) {
|
|
466
|
-
return new TableBuilder(this.userColumns, {
|
|
467
|
-
baseName: this.baseName,
|
|
468
|
-
description,
|
|
469
|
-
ai: this.aiAccess,
|
|
470
|
-
writes: this.writeOrigin,
|
|
471
|
-
exportImport: this.exportImport
|
|
472
|
-
});
|
|
473
|
-
}
|
|
474
|
-
/** Type-only: the row shape returned by queries. Do not access at runtime. */
|
|
475
|
-
get $row() {
|
|
476
|
-
return null;
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* Validate a CRDT event payload against the declared columns.
|
|
480
|
-
* `item-created` payloads must contain every column without a default (nullable columns may be omitted)
|
|
481
|
-
* and their `tombstone` value is ignored, since applying a create always sets it to 0;
|
|
482
|
-
* `item-updated` payloads are partial and must not touch `id` or set `tombstone` to a deleted value.
|
|
483
|
-
*/
|
|
484
|
-
validatePayload(payload, options) {
|
|
485
|
-
const event = options?.event ?? "item-created";
|
|
486
|
-
const errors = [];
|
|
487
|
-
for (const key of Object.keys(payload)) if (!Object.hasOwn(this.columns, key)) errors.push(`Unknown column "${key}"`);
|
|
488
|
-
if (event === "item-updated") {
|
|
489
|
-
if ("id" in payload) errors.push(`Column "id" is immutable and cannot appear in an update payload`);
|
|
490
|
-
if (payload.tombstone === true || payload.tombstone === 1) errors.push(`Column "tombstone" cannot be set to true/1 in an update payload; use an item-deleted event`);
|
|
491
|
-
}
|
|
492
|
-
if (event === "item-created") for (const [name, meta] of Object.entries(this.columns)) {
|
|
493
|
-
if (Object.hasOwn(payload, name) || name === "tombstone" || meta.nullable || meta.hasDefault) continue;
|
|
494
|
-
errors.push(`Missing required column "${name}"`);
|
|
495
|
-
}
|
|
496
|
-
for (const [name, value] of Object.entries(payload)) {
|
|
497
|
-
const meta = Object.hasOwn(this.columns, name) ? this.columns[name] : void 0;
|
|
498
|
-
if (!meta || event === "item-updated" && name === "id" || event === "item-created" && name === "tombstone") continue;
|
|
499
|
-
const error = validateValue(name, value, meta);
|
|
500
|
-
if (error) errors.push(error);
|
|
501
|
-
}
|
|
502
|
-
return errors.length === 0 ? { success: true } : {
|
|
503
|
-
success: false,
|
|
504
|
-
errors
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
};
|
|
508
|
-
function describeValue(value) {
|
|
509
|
-
if (value === null) return "null";
|
|
510
|
-
if (Array.isArray(value)) return "array";
|
|
511
|
-
return typeof value;
|
|
512
|
-
}
|
|
513
|
-
function validateValue(name, value, meta) {
|
|
514
|
-
if (value === null) return meta.nullable ? null : `Column "${name}" is not nullable, got null`;
|
|
515
|
-
switch (meta.kind) {
|
|
516
|
-
case "text": return typeof value === "string" ? null : `Column "${name}" expects text, got ${describeValue(value)}`;
|
|
517
|
-
case "integer": return typeof value === "number" && Number.isInteger(value) ? null : `Column "${name}" expects an integer, got ${describeValue(value)}`;
|
|
518
|
-
case "real": return typeof value === "number" && Number.isFinite(value) ? null : `Column "${name}" expects a number, got ${describeValue(value)}`;
|
|
519
|
-
case "boolean": return typeof value === "boolean" || value === 0 || value === 1 ? null : `Column "${name}" expects a boolean (true/false or 0/1), got ${describeValue(value)}`;
|
|
520
|
-
case "enum":
|
|
521
|
-
if (typeof value !== "string") return `Column "${name}" expects one of ${formatEnumValues(meta)}, got ${describeValue(value)}`;
|
|
522
|
-
return meta.enumValues?.includes(value) ? null : `Column "${name}" expects one of ${formatEnumValues(meta)}, got "${value}"`;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
function formatEnumValues(meta) {
|
|
526
|
-
return (meta.enumValues ?? []).map((value) => `"${value}"`).join(" | ");
|
|
527
|
-
}
|
|
528
|
-
function column(kind, sqlType) {
|
|
529
|
-
return new ColumnBuilder({
|
|
530
|
-
kind,
|
|
531
|
-
sqlType,
|
|
532
|
-
nullable: false,
|
|
533
|
-
hasDefault: false
|
|
1
|
+
import { b as dummyKysely, c as memoryDbConfig, f as createKvStoreTableQuery, h as SQLiteDbWrapper, i as applyWorkerDbSchema, m as createStoredValue, p as createSQLiteKvStore, r as applyMemoryDbSchema, v as startPerformanceLogger, y as introspectDb } from "./system-schema-CXf3FmxN.js";
|
|
2
|
+
import { a as acquireLock, d as noop, h as tryCatchAsync, i as TypedEvent, l as generateId, m as tryCatch, n as isNoOpCrdtEventPayload, o as createDeferredPromise, p as quoteId, r as TypedBroadcastChannel, s as createTypedEventTarget, t as CRDT_EVENT_NO_OP_PAYLOAD, u as jsonSafeParse } from "./crdt-table-schema-D6Yf61Ex.js";
|
|
3
|
+
import { a as formatSchemaVerificationIssues, c as createMigrator, i as createSQLiteCrdtApplyFunction, l as createExportData, n as createCrdtStorage, o as verifySyncSchemaWithDriver, r as createCrdtApplyFunction, s as createMigrations, t as createCrdtSyncProducer, u as createImportData } from "./crdt-sync-producer-BY-WobgO.js";
|
|
4
|
+
import { c as deserializeHLC, i as validateNewCrdtEvent, l as serializeHLC, o as HLCCounter, r as CrdtEventValidationError, s as compareHLC, t as createCrdtSyncRemoteSource, u as xxhash } from "./crdt-sync-remote-source-yeTEkOjH.js";
|
|
5
|
+
import { n as parametersAreEqual, t as SQLiteReactiveDb } from "./sqlite-reactive-db-DLS1xRZp.js";
|
|
6
|
+
import { t as admitClientEvents } from "./admit-client-events-BDrJw4SK.js";
|
|
7
|
+
import { a as defineSyncSchema, i as t, n as ColumnBuilder, r as TableBuilder, t as createCrdtStorageMutator } from "./index.common-C8W9VKSY.js";
|
|
8
|
+
import { a as makeCrdtTable, o as registerCrdtIntentDrainer } from "./make-crdt-table-DYCXOYB7.js";
|
|
9
|
+
import { _ as createWasmSqliteDriver, a as acquireReplicaLock, c as isWorkerErrorResponseMessage, f as isWorkerResponseMessage, g as createWasmMemoryDriver, h as verifySyncSchema, p as syncDbClientLockName, s as createBroadcastChannels, t as RESET_REQUEST_TTL_MS, u as isWorkerNotificationMessage, v as loadSqliteWasm } from "./reset-state-CPOi_45B.js";
|
|
10
|
+
import { n as getOrCreateSQLiteSyncDevtoolsRegistry, r as validateDbId, t as createSyncedDbDatabase } from "./synced-db-database-B5M7MrBD.js";
|
|
11
|
+
//#region src/memory-db/wasm-reactive-db.ts
|
|
12
|
+
async function createSQLiteReactiveDb(opts) {
|
|
13
|
+
const driver = await createWasmMemoryDriver();
|
|
14
|
+
return SQLiteReactiveDb.create({
|
|
15
|
+
...opts,
|
|
16
|
+
driver
|
|
534
17
|
});
|
|
535
18
|
}
|
|
536
|
-
const t = {
|
|
537
|
-
text: () => column("text", "text"),
|
|
538
|
-
integer: () => column("integer", "integer"),
|
|
539
|
-
real: () => column("real", "real"),
|
|
540
|
-
/** Stored as INTEGER 0/1; always bind booleans as 0/1 when writing raw SQL. */
|
|
541
|
-
boolean: () => column("boolean", "integer"),
|
|
542
|
-
/**
|
|
543
|
-
* Union of string literals stored as TEXT, e.g. `t.enum(["movie", "tv"])`. Unlike `$type`, the
|
|
544
|
-
* allowed values are kept as runtime metadata, so payloads are validated against them.
|
|
545
|
-
* For an open-ended set, use `t.text().$type<"idle" | (string & {})>()` instead.
|
|
546
|
-
*/
|
|
547
|
-
enum: (values) => new ColumnBuilder({
|
|
548
|
-
kind: "enum",
|
|
549
|
-
sqlType: "text",
|
|
550
|
-
nullable: false,
|
|
551
|
-
hasDefault: false,
|
|
552
|
-
enumValues: values
|
|
553
|
-
}),
|
|
554
|
-
table: (columns, options) => new TableBuilder(columns, options)
|
|
555
|
-
};
|
|
556
|
-
//#endregion
|
|
557
|
-
//#region src/sqlite-crdt/crdt-storage-mutator.ts
|
|
558
|
-
function createCrdtStorageMutator({ storage }) {
|
|
559
|
-
const mapToStorageEvent = (event) => {
|
|
560
|
-
switch (event.type) {
|
|
561
|
-
case "item-created": return {
|
|
562
|
-
type: "item-created",
|
|
563
|
-
dataset: event.dataset,
|
|
564
|
-
item_id: event.item_id,
|
|
565
|
-
payload: JSON.stringify(event.payload)
|
|
566
|
-
};
|
|
567
|
-
case "item-updated": return {
|
|
568
|
-
type: "item-updated",
|
|
569
|
-
dataset: event.dataset,
|
|
570
|
-
item_id: event.item_id,
|
|
571
|
-
payload: JSON.stringify(event.payload)
|
|
572
|
-
};
|
|
573
|
-
case "item-deleted": return {
|
|
574
|
-
type: "item-deleted",
|
|
575
|
-
dataset: event.dataset,
|
|
576
|
-
item_id: event.item_id,
|
|
577
|
-
payload: "{}"
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
};
|
|
581
|
-
const applyEvents = (events) => {
|
|
582
|
-
storage.applyOwnEvents(events.map(mapToStorageEvent));
|
|
583
|
-
};
|
|
584
|
-
const applyEvent = (event) => {
|
|
585
|
-
storage.applyOwnEvents([mapToStorageEvent(event)]);
|
|
586
|
-
};
|
|
587
|
-
const applySnapshot = (snapshot) => {
|
|
588
|
-
storage.applyOwnSnapshot({
|
|
589
|
-
dataset: snapshot.dataset,
|
|
590
|
-
item_id: snapshot.id,
|
|
591
|
-
patch: { ...snapshot.patch }
|
|
592
|
-
});
|
|
593
|
-
};
|
|
594
|
-
return {
|
|
595
|
-
applyEvent,
|
|
596
|
-
applyEvents,
|
|
597
|
-
applySnapshot
|
|
598
|
-
};
|
|
599
|
-
}
|
|
600
|
-
//#endregion
|
|
601
|
-
//#region src/db-id.ts
|
|
602
|
-
const dbIdRegex = /^[a-zA-Z][a-zA-Z\-0-9]{2,63}$/;
|
|
603
|
-
function validateDbId(dbId) {
|
|
604
|
-
if (!dbIdRegex.test(dbId)) throw new Error("Invalid dbId. Must be between 3 and 64 characters long and start with a letter.");
|
|
605
|
-
}
|
|
606
|
-
//#endregion
|
|
607
|
-
//#region src/devtools-registry.ts
|
|
608
|
-
const devtoolsRegistrySymbol = Symbol.for("@sqlite-sync/devtools");
|
|
609
|
-
function createSQLiteSyncDevtoolsRegistry() {
|
|
610
|
-
const instances = /* @__PURE__ */ new Map();
|
|
611
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
612
|
-
let snapshot = { instances: [] };
|
|
613
|
-
const notify = () => {
|
|
614
|
-
for (const listener of listeners) listener();
|
|
615
|
-
};
|
|
616
|
-
const updateSnapshot = () => {
|
|
617
|
-
snapshot = { instances: Array.from(instances.values()) };
|
|
618
|
-
notify();
|
|
619
|
-
};
|
|
620
|
-
return {
|
|
621
|
-
version: 1,
|
|
622
|
-
instances,
|
|
623
|
-
subscribe(listener) {
|
|
624
|
-
listeners.add(listener);
|
|
625
|
-
return () => {
|
|
626
|
-
listeners.delete(listener);
|
|
627
|
-
};
|
|
628
|
-
},
|
|
629
|
-
getSnapshot() {
|
|
630
|
-
return snapshot;
|
|
631
|
-
},
|
|
632
|
-
register(instance) {
|
|
633
|
-
instances.set(instance.instanceId, instance);
|
|
634
|
-
updateSnapshot();
|
|
635
|
-
let isUnregistered = false;
|
|
636
|
-
return () => {
|
|
637
|
-
if (isUnregistered) return;
|
|
638
|
-
isUnregistered = true;
|
|
639
|
-
if (!instances.delete(instance.instanceId)) return;
|
|
640
|
-
updateSnapshot();
|
|
641
|
-
};
|
|
642
|
-
}
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
function getOrCreateSQLiteSyncDevtoolsRegistry() {
|
|
646
|
-
const registryGlobal = globalThis;
|
|
647
|
-
registryGlobal[devtoolsRegistrySymbol] ??= createSQLiteSyncDevtoolsRegistry();
|
|
648
|
-
return registryGlobal[devtoolsRegistrySymbol];
|
|
649
|
-
}
|
|
650
19
|
//#endregion
|
|
651
20
|
//#region src/memory-db/memory-db.ts
|
|
652
|
-
async function createMemoryDb({ nodeId, migrator, reactiveDb: _reactiveDb, hlcCounter, crdtTables, initializeSchema = true, initialSyncId,
|
|
21
|
+
async function createMemoryDb({ nodeId, migrator, reactiveDb: _reactiveDb, hlcCounter, crdtTables, initializeSchema = true, initialSyncId, stateHash, syncDbSchema }) {
|
|
653
22
|
await xxhash.ensureLoaded();
|
|
654
23
|
const reactiveDb = _reactiveDb;
|
|
655
24
|
const db = reactiveDb.db;
|
|
@@ -668,7 +37,7 @@ async function createMemoryDb({ nodeId, migrator, reactiveDb: _reactiveDb, hlcCo
|
|
|
668
37
|
migrator,
|
|
669
38
|
db,
|
|
670
39
|
dbConfig: memoryDbConfig,
|
|
671
|
-
|
|
40
|
+
stateHash,
|
|
672
41
|
schema: syncDbSchema
|
|
673
42
|
});
|
|
674
43
|
registerCrdtIntentDrainer({
|
|
@@ -783,32 +152,6 @@ function postWorkerConfig(worker, config) {
|
|
|
783
152
|
}
|
|
784
153
|
//#endregion
|
|
785
154
|
//#region src/sync-db.ts
|
|
786
|
-
function createSqlExecutor(tx, unsafe) {
|
|
787
|
-
return {
|
|
788
|
-
execute: (query) => tx.execute(query, unsafe ? { skipAfterMutatingStatement: true } : void 0),
|
|
789
|
-
executeKysely: (factory) => tx.executeKysely(factory, unsafe ? { skipAfterMutatingStatement: true } : void 0)
|
|
790
|
-
};
|
|
791
|
-
}
|
|
792
|
-
/** @internal Exported from this module for focused facade tests, but not from the package entry point. */
|
|
793
|
-
function createSyncedDbDatabase(reactiveDb) {
|
|
794
|
-
const safeExecutor = createSqlExecutor(reactiveDb.db, false);
|
|
795
|
-
const unsafeExecutor = createSqlExecutor(reactiveDb.db, true);
|
|
796
|
-
return {
|
|
797
|
-
...safeExecutor,
|
|
798
|
-
unsafe: unsafeExecutor,
|
|
799
|
-
executeTransaction: (callback) => reactiveDb.db.executeTransaction((tx) => {
|
|
800
|
-
const safeTransactionExecutor = createSqlExecutor(tx, false);
|
|
801
|
-
const unsafeTransactionExecutor = createSqlExecutor(tx, true);
|
|
802
|
-
return callback({
|
|
803
|
-
...safeTransactionExecutor,
|
|
804
|
-
unsafe: unsafeTransactionExecutor,
|
|
805
|
-
sql: tx.sql.bind(tx)
|
|
806
|
-
});
|
|
807
|
-
}),
|
|
808
|
-
createLiveQuery: reactiveDb.createLiveQuery.bind(reactiveDb),
|
|
809
|
-
getSharedLiveQuery: reactiveDb.getSharedLiveQuery.bind(reactiveDb)
|
|
810
|
-
};
|
|
811
|
-
}
|
|
812
155
|
const defaultLogger = (type, message, level = "info") => {
|
|
813
156
|
const logMessage = `[${type}] ${message}`;
|
|
814
157
|
switch (level) {
|
|
@@ -909,7 +252,7 @@ async function createSyncedDb(options) {
|
|
|
909
252
|
const subscription = workerClient.subscribe("new-event-chunk-applied", (event) => {
|
|
910
253
|
onEventsAvailable({
|
|
911
254
|
newSyncId: event.payload.newSyncId,
|
|
912
|
-
|
|
255
|
+
remoteStateHash: event.payload.stateHash ?? null
|
|
913
256
|
});
|
|
914
257
|
});
|
|
915
258
|
return {
|
|
@@ -1017,6 +360,6 @@ async function createSyncedDb(options) {
|
|
|
1017
360
|
}
|
|
1018
361
|
}
|
|
1019
362
|
//#endregion
|
|
1020
|
-
export { CRDT_EVENT_NO_OP_PAYLOAD, ColumnBuilder, CrdtEventValidationError, HLCCounter, RESET_REQUEST_TTL_MS, SQLiteDbWrapper, SQLiteReactiveDb, TableBuilder, TypedBroadcastChannel, TypedEvent, admitClientEvents, applyMemoryDbSchema, applyWorkerDbSchema, compareHLC, createCrdtApplyFunction, createCrdtStorage, createCrdtStorageMutator, createCrdtSyncProducer, createCrdtSyncRemoteSource, createDeferredPromise, createExportData, createImportData, createKvStoreTableQuery, createMigrations, createMigrator, createSQLiteCrdtApplyFunction, createSQLiteKvStore, createStoredValue, createSyncedDb, createTypedEventTarget, defineSyncSchema, deserializeHLC, dummyKysely, formatSchemaVerificationIssues, generateId, introspectDb, isNoOpCrdtEventPayload, jsonSafeParse, makeCrdtTable, parametersAreEqual, quoteId, serializeHLC, startPerformanceLogger, t, tryCatch, tryCatchAsync, validateNewCrdtEvent, verifySyncSchema, xxhash };
|
|
363
|
+
export { CRDT_EVENT_NO_OP_PAYLOAD, ColumnBuilder, CrdtEventValidationError, HLCCounter, RESET_REQUEST_TTL_MS, SQLiteDbWrapper, SQLiteReactiveDb, TableBuilder, TypedBroadcastChannel, TypedEvent, admitClientEvents, applyMemoryDbSchema, applyWorkerDbSchema, compareHLC, createCrdtApplyFunction, createCrdtStorage, createCrdtStorageMutator, createCrdtSyncProducer, createCrdtSyncRemoteSource, createDeferredPromise, createExportData, createImportData, createKvStoreTableQuery, createMigrations, createMigrator, createSQLiteCrdtApplyFunction, createSQLiteKvStore, createSQLiteReactiveDb, createStoredValue, createSyncedDb, createTypedEventTarget, createWasmMemoryDriver, createWasmSqliteDriver, defineSyncSchema, deserializeHLC, dummyKysely, formatSchemaVerificationIssues, generateId, introspectDb, isNoOpCrdtEventPayload, jsonSafeParse, loadSqliteWasm, makeCrdtTable, parametersAreEqual, quoteId, serializeHLC, startPerformanceLogger, t, tryCatch, tryCatchAsync, validateNewCrdtEvent, verifySyncSchema, verifySyncSchemaWithDriver, xxhash };
|
|
1021
364
|
|
|
1022
365
|
//# sourceMappingURL=index.js.map
|