@sqlite-sync/core 0.9.2 → 0.9.3
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/{index-NvSJ253v.d.ts → index-iXdCBXzB.d.ts} +10 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -22
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/{reset-state-D3nsfx_t.js → reset-state-4Hn95CKG.js} +24 -14
- package/dist/reset-state-4Hn95CKG.js.map +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/worker.d.ts +1 -1
- package/dist/worker.js +1 -1
- package/package.json +1 -1
- package/dist/reset-state-D3nsfx_t.js.map +0 -1
|
@@ -159,6 +159,8 @@ type AiAccess = "read-write" | "read-only" | "hidden";
|
|
|
159
159
|
* `"any"` (default): every replica. `"server"`: client pushes drop these events.
|
|
160
160
|
*/
|
|
161
161
|
type WriteOrigin = "any" | "server";
|
|
162
|
+
/** Whether backup and restore include a table. */
|
|
163
|
+
type ExportImportMode = "include" | "ignore";
|
|
162
164
|
type ColumnMeta = {
|
|
163
165
|
kind: ColumnKind;
|
|
164
166
|
/** Storage type used in generated DDL. Booleans store as integer 0/1. */
|
|
@@ -199,6 +201,8 @@ type TableOptions<BaseName extends string | undefined = string | undefined, Writ
|
|
|
199
201
|
ai?: AiAccess;
|
|
200
202
|
/** Defaults to `"any"`. See {@link WriteOrigin}. */
|
|
201
203
|
writes?: Writes;
|
|
204
|
+
/** Defaults to `"include"`. Ignored tables are omitted from export and skipped on import. */
|
|
205
|
+
exportImport?: ExportImportMode;
|
|
202
206
|
};
|
|
203
207
|
type Simplify$1<T> = { [K in keyof T]: T[K]; } & {};
|
|
204
208
|
type ColumnValue<Column> = Column extends ColumnBuilder<infer Value, boolean> ? Value : never;
|
|
@@ -225,14 +229,10 @@ declare class TableBuilder<Cols extends TableColumns, BaseName extends string |
|
|
|
225
229
|
readonly aiAccess: AiAccess;
|
|
226
230
|
/** Resolved {@link WriteOrigin}; defaults to `"any"`. */
|
|
227
231
|
readonly writeOrigin: Writes;
|
|
232
|
+
/** Resolved {@link ExportImportMode}; defaults to `"include"`. */
|
|
233
|
+
readonly exportImport: ExportImportMode;
|
|
228
234
|
constructor(userColumns: Cols, options?: TableOptions<BaseName, Writes>);
|
|
229
|
-
/** Rebuilds the table with `overrides` applied over the current options. */
|
|
230
|
-
private withOptions;
|
|
231
235
|
describe(description: string): TableBuilder<Cols, BaseName, Writes>;
|
|
232
|
-
/** Same as `{ ai }` in {@link TableOptions}. */
|
|
233
|
-
ai(access: AiAccess): TableBuilder<Cols, BaseName, Writes>;
|
|
234
|
-
/** Same as `{ writes }` in {@link TableOptions}. */
|
|
235
|
-
writes<const Origin extends WriteOrigin>(origin: Origin): TableBuilder<Cols, BaseName, Origin>;
|
|
236
236
|
/** Type-only: the row shape returned by queries. Do not access at runtime. */
|
|
237
237
|
get $row(): InferRow<Cols>;
|
|
238
238
|
/**
|
|
@@ -263,6 +263,8 @@ declare const t: {
|
|
|
263
263
|
type CrdtTableConfig = {
|
|
264
264
|
baseTableName: string;
|
|
265
265
|
crdtTableName: string;
|
|
266
|
+
/** Defaults to `"include"`. */
|
|
267
|
+
exportImport?: ExportImportMode;
|
|
266
268
|
};
|
|
267
269
|
interface SyncDbSchema<ClientDB = {}, ServerDB = {}, MutationsDB = {}> {
|
|
268
270
|
get tablesConfig(): CrdtTableConfig[];
|
|
@@ -1203,5 +1205,5 @@ type ResetStore = {
|
|
|
1203
1205
|
*/
|
|
1204
1206
|
declare const RESET_REQUEST_TTL_MS: number;
|
|
1205
1207
|
//#endregion
|
|
1206
|
-
export { CrdtChangeIntent as $, AnyColumnBuilder as $t, createCrdtApplyFunction as A, InternalSQLiteWrapper as At, defineSyncSchema as B, ColumnMetadata as Bt, WorkerNotificationMessage as C,
|
|
1207
|
-
//# sourceMappingURL=index-
|
|
1208
|
+
export { CrdtChangeIntent as $, AnyColumnBuilder as $t, createCrdtApplyFunction as A, dummyKysely as An, InternalSQLiteWrapper as At, defineSyncSchema as B, ColumnMetadata as Bt, WorkerNotificationMessage as C, CrdtEventOrigin as Cn, tryCatch as Ct, SnapshotOptions as D, CrdtUpdateLogPayload as Dn, createSQLiteKvStore as Dt, CrdtStorageMutator as E, CrdtUpdateLogItem as En, createKvStoreTableQuery as Et, CrdtEventValidationError as F, SQLiteDbWrapper as Ft, SharedLiveQuerySnapshot as G, HLCCounter as Gt, admitClientEvents as H, TableMetadata as Ht, NewCrdtEventValidationResult as I, SQLiteTransactionWrapper as It, ImportDataOptions as J, serializeHLC as Jt, parametersAreEqual as K, compareHLC as Kt, validateNewCrdtEvent as L, LogLevel as Lt, SchemaVerificationIssue as M, KyselyStatementFactory as Mt, formatSchemaVerificationIssues as N, PreparedStatement as Nt, createCrdtStorageMutator as O, PersistedCrdtEvent as On, ExecuteParams as Ot, verifySyncSchema as P, QueryBuilderOutput as Pt, createImportData as Q, AiAccess as Qt, DefineSyncSchemaConfig as R, Logger as Rt, WorkerConfig as S, CRDT_EVENT_NO_OP_PAYLOAD as Sn, quoteId as St, createCrdtSyncProducer as T, CrdtEventType as Tn, KvStoreItem as Tt, SQLiteReactiveDb as U, introspectDb as Ut, AdmitClientEventsResult as V, DatabaseIntrospection as Vt, SharedLiveQuery as W, HLC as Wt, SyncedDbExport as X, ReadonlyTable as Xt, ImportDataResult as Y, CrdtTableConfig as Yt, createExportData as Z, SyncDbSchema as Zt, EventsPullRequest as _, SyncDbMigrator as _n, TypedEventTarget as _t, SyncedDbDatabase as a, InferRow as an, SystemDbConfig as at, createCrdtSyncRemoteSource as b, StoredValue as bn, generateId as bt, SyncedDbTransaction as c, SyncSchemaTables as cn, applyMemoryDbSchema as ct, CRDT_CHANGE_INTENTS_TABLE as d, TableOptions as dn, createSystemDbConfig as dt, AnyTableBuilder as en, CrdtStorage as et, createCrdtViewStatements as f, WriteOrigin as fn, runSystemMigrations as ft, CreateRemoteSourceFactory as g, MigrationsDb as gn, TypedEvent as gt, CrdtSyncRemoteSource as h, Migrations as hn, TypedBroadcastChannel as ht, SyncedDb as i, ExportImportMode as in, createCrdtStorage as it, createSQLiteCrdtApplyFunction as j, KyselyQueryFactory as jt, PendingCrdtEvent as k, isNoOpCrdtEventPayload as kn, ExecuteResult as kt, UnsafeSyncedDbSqlExecutor as l, TableBuilder as ln, applyWorkerDbSchema as lt, makeCrdtTable as m, MigratableEvent as mn, DistributiveOmit as mt, ResetRequest as n, ColumnKind as nn, OwnCrdtEvent as nt, SyncedDbOptions as o, PayloadValidationResult as on, SystemMigration as ot, drainCrdtChangeIntents as p, t as pn, DeferredPromise as pt, xxhash as q, deserializeHLC as qt, ResetStore as r, ColumnMeta as rn, OwnCrdtSnapshot as rt, SyncedDbSqlExecutor as s, SqliteStorageType as sn, SystemMigrationContext as st, RESET_REQUEST_TTL_MS as t, ColumnBuilder as tn, GetEventsBatch as tt, createSyncedDb as u, TableColumns as un, baseSystemMigrations as ut, EventsPushRequest as v, createMigrations as vn, createDeferredPromise as vt, WorkerState as w, CrdtEventStatus as wn, tryCatchAsync as wt, EventsPullResponse as x, createStoredValue as xn, jsonSafeParse as xt, EventsPushResponse as y, createMigrator as yn, createTypedEventTarget as yt, DefinedSyncSchema as z, startPerformanceLogger as zt };
|
|
1209
|
+
//# sourceMappingURL=index-iXdCBXzB.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $t as AnyColumnBuilder, A as createCrdtApplyFunction, B as defineSyncSchema, Bt as ColumnMetadata, C as WorkerNotificationMessage, Cn as
|
|
2
|
-
export { type AdmitClientEventsResult, type AiAccess, type AnyColumnBuilder, type AnyTableBuilder, CRDT_EVENT_NO_OP_PAYLOAD, ColumnBuilder, type ColumnKind, type ColumnMeta, type ColumnMetadata, type CrdtEventOrigin, type CrdtEventStatus, type CrdtEventType, CrdtEventValidationError, type CrdtStorage, type CrdtStorageMutator, type CrdtSyncRemoteSource, type CrdtTableConfig, type CrdtUpdateLogItem, type CrdtUpdateLogPayload, type DatabaseIntrospection, type DeferredPromise, type DefineSyncSchemaConfig, type DefinedSyncSchema, type DistributiveOmit, type EventsPullRequest, type EventsPushRequest, type EventsPushResponse, type ExecuteParams, type ExecuteResult, type HLC, HLCCounter, type ImportDataOptions, type ImportDataResult, type InferRow, type KvStoreItem, type KyselyQueryFactory, type LogLevel, type Logger, type MigratableEvent, type Migrations, type MigrationsDb, type NewCrdtEventValidationResult, type OwnCrdtEvent, type OwnCrdtSnapshot, type PayloadValidationResult, type PendingCrdtEvent, type PersistedCrdtEvent, type PreparedStatement, type QueryBuilderOutput, RESET_REQUEST_TTL_MS, type ReadonlyTable, type ResetRequest, type ResetStore, SQLiteDbWrapper, SQLiteReactiveDb, type SQLiteTransactionWrapper, type SchemaVerificationIssue, type SharedLiveQuery, type SharedLiveQuerySnapshot, type SnapshotOptions, type SqliteStorageType, type StoredValue, type SyncDbMigrator, type SyncDbSchema, type SyncSchemaTables, type SyncedDb, type SyncedDbDatabase, type SyncedDbExport, type SyncedDbOptions, type SyncedDbSqlExecutor, type SyncedDbTransaction, type SystemDbConfig, type SystemMigration, type SystemMigrationContext, TableBuilder, type TableColumns, type TableMetadata, type TableOptions, TypedBroadcastChannel, TypedEvent, type TypedEventTarget, type UnsafeSyncedDbSqlExecutor, type WorkerConfig, type WorkerNotificationMessage, type WorkerState, type WriteOrigin, 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 };
|
|
1
|
+
import { $t as AnyColumnBuilder, A as createCrdtApplyFunction, An as dummyKysely, B as defineSyncSchema, Bt as ColumnMetadata, C as WorkerNotificationMessage, Cn as CrdtEventOrigin, Ct as tryCatch, D as SnapshotOptions, Dn as CrdtUpdateLogPayload, Dt as createSQLiteKvStore, E as CrdtStorageMutator, En as CrdtUpdateLogItem, Et as createKvStoreTableQuery, F as CrdtEventValidationError, Ft as SQLiteDbWrapper, G as SharedLiveQuerySnapshot, Gt as HLCCounter, H as admitClientEvents, Ht as TableMetadata, I as NewCrdtEventValidationResult, It as SQLiteTransactionWrapper, J as ImportDataOptions, Jt as serializeHLC, K as parametersAreEqual, Kt as compareHLC, L as validateNewCrdtEvent, Lt as LogLevel, M as SchemaVerificationIssue, N as formatSchemaVerificationIssues, Nt as PreparedStatement, O as createCrdtStorageMutator, On as PersistedCrdtEvent, Ot as ExecuteParams, P as verifySyncSchema, Pt as QueryBuilderOutput, Q as createImportData, Qt as AiAccess, R as DefineSyncSchemaConfig, Rt as Logger, S as WorkerConfig, Sn as CRDT_EVENT_NO_OP_PAYLOAD, St as quoteId, T as createCrdtSyncProducer, Tn as CrdtEventType, Tt as KvStoreItem, U as SQLiteReactiveDb, Ut as introspectDb, V as AdmitClientEventsResult, Vt as DatabaseIntrospection, W as SharedLiveQuery, Wt as HLC, X as SyncedDbExport, Xt as ReadonlyTable, Y as ImportDataResult, Yt as CrdtTableConfig, Z as createExportData, Zt as SyncDbSchema, _ as EventsPullRequest, _n as SyncDbMigrator, _t as TypedEventTarget, a as SyncedDbDatabase, an as InferRow, at as SystemDbConfig, b as createCrdtSyncRemoteSource, bn as StoredValue, bt as generateId, c as SyncedDbTransaction, cn as SyncSchemaTables, ct as applyMemoryDbSchema, dn as TableOptions, en as AnyTableBuilder, et as CrdtStorage, fn as WriteOrigin, gn as MigrationsDb, gt as TypedEvent, h as CrdtSyncRemoteSource, hn as Migrations, ht as TypedBroadcastChannel, i as SyncedDb, in as ExportImportMode, it as createCrdtStorage, j as createSQLiteCrdtApplyFunction, jt as KyselyQueryFactory, k as PendingCrdtEvent, kn as isNoOpCrdtEventPayload, kt as ExecuteResult, l as UnsafeSyncedDbSqlExecutor, ln as TableBuilder, lt as applyWorkerDbSchema, m as makeCrdtTable, mn as MigratableEvent, mt as DistributiveOmit, n as ResetRequest, nn as ColumnKind, nt as OwnCrdtEvent, o as SyncedDbOptions, on as PayloadValidationResult, ot as SystemMigration, pn as t, pt as DeferredPromise, q as xxhash, qt as deserializeHLC, r as ResetStore, rn as ColumnMeta, rt as OwnCrdtSnapshot, s as SyncedDbSqlExecutor, sn as SqliteStorageType, st as SystemMigrationContext, t as RESET_REQUEST_TTL_MS, tn as ColumnBuilder, u as createSyncedDb, un as TableColumns, v as EventsPushRequest, vn as createMigrations, vt as createDeferredPromise, w as WorkerState, wn as CrdtEventStatus, wt as tryCatchAsync, xn as createStoredValue, xt as jsonSafeParse, y as EventsPushResponse, yn as createMigrator, yt as createTypedEventTarget, z as DefinedSyncSchema, zt as startPerformanceLogger } from "./index-iXdCBXzB.js";
|
|
2
|
+
export { type AdmitClientEventsResult, type AiAccess, type AnyColumnBuilder, type AnyTableBuilder, CRDT_EVENT_NO_OP_PAYLOAD, ColumnBuilder, type ColumnKind, type ColumnMeta, type ColumnMetadata, type CrdtEventOrigin, type CrdtEventStatus, type CrdtEventType, CrdtEventValidationError, type CrdtStorage, type CrdtStorageMutator, type CrdtSyncRemoteSource, type CrdtTableConfig, type CrdtUpdateLogItem, type CrdtUpdateLogPayload, type DatabaseIntrospection, type DeferredPromise, type DefineSyncSchemaConfig, type DefinedSyncSchema, type DistributiveOmit, type EventsPullRequest, type EventsPushRequest, type EventsPushResponse, type ExecuteParams, type ExecuteResult, type ExportImportMode, type HLC, HLCCounter, type ImportDataOptions, type ImportDataResult, type InferRow, type KvStoreItem, type KyselyQueryFactory, type LogLevel, type Logger, type MigratableEvent, type Migrations, type MigrationsDb, type NewCrdtEventValidationResult, type OwnCrdtEvent, type OwnCrdtSnapshot, type PayloadValidationResult, type PendingCrdtEvent, type PersistedCrdtEvent, type PreparedStatement, type QueryBuilderOutput, RESET_REQUEST_TTL_MS, type ReadonlyTable, type ResetRequest, type ResetStore, SQLiteDbWrapper, SQLiteReactiveDb, type SQLiteTransactionWrapper, type SchemaVerificationIssue, type SharedLiveQuery, type SharedLiveQuerySnapshot, type SnapshotOptions, type SqliteStorageType, type StoredValue, type SyncDbMigrator, type SyncDbSchema, type SyncSchemaTables, type SyncedDb, type SyncedDbDatabase, type SyncedDbExport, type SyncedDbOptions, type SyncedDbSqlExecutor, type SyncedDbTransaction, type SystemDbConfig, type SystemMigration, type SystemMigrationContext, TableBuilder, type TableColumns, type TableMetadata, type TableOptions, TypedBroadcastChannel, TypedEvent, type TypedEventTarget, type UnsafeSyncedDbSqlExecutor, type WorkerConfig, type WorkerNotificationMessage, type WorkerState, type WriteOrigin, 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 };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as serializeHLC, C as createMigrator, D as HLCCounter, E as introspectDb, M as createExportData, N as createImportData, O as compareHLC, P as dummyKysely, S as createMigrations, T as startPerformanceLogger, _ as createSQLiteCrdtApplyFunction, a as createBroadcastChannels, b as CrdtEventValidationError, c as isWorkerNotificationMessage, d as syncDbClientLockName, g as createCrdtApplyFunction, h as createCrdtStorage, j as xxhash, k as deserializeHLC, m as createCrdtSyncProducer, o as isWorkerErrorResponseMessage, p as createCrdtSyncRemoteSource, t as RESET_REQUEST_TTL_MS, u as isWorkerResponseMessage, v as formatSchemaVerificationIssues, w as SQLiteDbWrapper, x as validateNewCrdtEvent, y as verifySyncSchema } from "./reset-state-
|
|
1
|
+
import { A as serializeHLC, C as createMigrator, D as HLCCounter, E as introspectDb, M as createExportData, N as createImportData, O as compareHLC, P as dummyKysely, S as createMigrations, T as startPerformanceLogger, _ as createSQLiteCrdtApplyFunction, a as createBroadcastChannels, b as CrdtEventValidationError, c as isWorkerNotificationMessage, d as syncDbClientLockName, g as createCrdtApplyFunction, h as createCrdtStorage, j as xxhash, k as deserializeHLC, m as createCrdtSyncProducer, o as isWorkerErrorResponseMessage, p as createCrdtSyncRemoteSource, t as RESET_REQUEST_TTL_MS, u as isWorkerResponseMessage, v as formatSchemaVerificationIssues, w as SQLiteDbWrapper, x as validateNewCrdtEvent, y as verifySyncSchema } from "./reset-state-4Hn95CKG.js";
|
|
2
2
|
import { c as noop, d as tryCatch, f as tryCatchAsync, i as createTypedEventTarget, n as TypedEvent, o as generateId, r as createDeferredPromise, s as jsonSafeParse, t as TypedBroadcastChannel, u as quoteId } from "./utils-Dr5JwcTP.js";
|
|
3
3
|
import { a as memoryDbConfig, c as createKvStoreTableQuery, d as CRDT_EVENT_NO_OP_PAYLOAD, f as isNoOpCrdtEventPayload, l as createSQLiteKvStore, n as applyWorkerDbSchema, t as applyMemoryDbSchema, u as createStoredValue } from "./system-schema-CkglcfTS.js";
|
|
4
4
|
import { a as registerCrdtIntentDrainer, i as makeCrdtTable } from "./make-crdt-table-CvpTHmRY.js";
|
|
@@ -379,7 +379,8 @@ const RESERVED_TABLE_NAMES = /* @__PURE__ */ new Set([
|
|
|
379
379
|
function defineSyncSchema({ tables, migrations }) {
|
|
380
380
|
const tablesConfig = Object.entries(tables).map(([crdtTableName, table]) => ({
|
|
381
381
|
crdtTableName,
|
|
382
|
-
baseTableName: table.baseName ?? `_${crdtTableName}
|
|
382
|
+
baseTableName: table.baseName ?? `_${crdtTableName}`,
|
|
383
|
+
...table.exportImport === "ignore" ? { exportImport: "ignore" } : {}
|
|
383
384
|
}));
|
|
384
385
|
const seenNames = /* @__PURE__ */ new Set();
|
|
385
386
|
for (const { crdtTableName, baseTableName } of tablesConfig) for (const name of [crdtTableName, baseTableName]) {
|
|
@@ -474,6 +475,8 @@ var TableBuilder = class TableBuilder {
|
|
|
474
475
|
aiAccess;
|
|
475
476
|
/** Resolved {@link WriteOrigin}; defaults to `"any"`. */
|
|
476
477
|
writeOrigin;
|
|
478
|
+
/** Resolved {@link ExportImportMode}; defaults to `"include"`. */
|
|
479
|
+
exportImport;
|
|
477
480
|
constructor(userColumns, options) {
|
|
478
481
|
this.userColumns = userColumns;
|
|
479
482
|
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`);
|
|
@@ -486,31 +489,15 @@ var TableBuilder = class TableBuilder {
|
|
|
486
489
|
this.description = options?.description;
|
|
487
490
|
this.aiAccess = options?.ai ?? "read-write";
|
|
488
491
|
this.writeOrigin = options?.writes ?? "any";
|
|
489
|
-
|
|
490
|
-
/** Rebuilds the table with `overrides` applied over the current options. */
|
|
491
|
-
withOptions(overrides) {
|
|
492
|
-
return new TableBuilder(this.userColumns, {
|
|
493
|
-
baseName: this.baseName,
|
|
494
|
-
description: this.description,
|
|
495
|
-
ai: this.aiAccess,
|
|
496
|
-
writes: this.writeOrigin,
|
|
497
|
-
...overrides
|
|
498
|
-
});
|
|
492
|
+
this.exportImport = options?.exportImport ?? "include";
|
|
499
493
|
}
|
|
500
494
|
describe(description) {
|
|
501
|
-
return this.withOptions({ description });
|
|
502
|
-
}
|
|
503
|
-
/** Same as `{ ai }` in {@link TableOptions}. */
|
|
504
|
-
ai(access) {
|
|
505
|
-
return this.withOptions({ ai: access });
|
|
506
|
-
}
|
|
507
|
-
/** Same as `{ writes }` in {@link TableOptions}. */
|
|
508
|
-
writes(origin) {
|
|
509
495
|
return new TableBuilder(this.userColumns, {
|
|
510
496
|
baseName: this.baseName,
|
|
511
|
-
description
|
|
497
|
+
description,
|
|
512
498
|
ai: this.aiAccess,
|
|
513
|
-
writes:
|
|
499
|
+
writes: this.writeOrigin,
|
|
500
|
+
exportImport: this.exportImport
|
|
514
501
|
});
|
|
515
502
|
}
|
|
516
503
|
/** Type-only: the row shape returned by queries. Do not access at runtime. */
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/bound-map.ts","../src/memory-db/sqlite-reactive-db.ts","../src/schema/admit-client-events.ts","../src/schema/define-sync-schema.ts","../src/schema/table-builder.ts","../src/sqlite-crdt/crdt-storage-mutator.ts","../src/db-id.ts","../src/devtools-registry.ts","../src/memory-db/memory-db.ts","../src/worker-db/db-worker-client.ts","../src/sync-db.ts"],"sourcesContent":["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 sqlite3InitModule, { type Sqlite3Static } from \"@sqlite.org/sqlite-wasm\";\nimport { BoundMap } from \"../bound-map\";\nimport { type Logger, startPerformanceLogger } from \"../logger\";\nimport { type PreparedStatement, SQLiteDbWrapper } from \"../sqlite-db-wrapper\";\nimport { createTypedEventTarget, type TypedEvent } from \"../utils\";\n\nlet sqliteModule: Sqlite3Static | null = null;\n\ntype TableName<Database> = keyof Database extends string ? keyof Database : never;\n\ntype SQLiteReactiveDbOptions = {\n snapshot: Uint8Array<ArrayBufferLike>;\n logger: Logger;\n};\n\ntype EventsMap = {\n \"transaction-committed\": undefined;\n \"transaction-rolled-back\": undefined;\n \"any-table-changed\": undefined;\n} & Record<`table:${string}`, void>;\n\ntype LiveQuery<TResult> = {\n getRows: () => TResult[];\n refresh: () => void;\n subscribe: (onchange: () => void) => () => void;\n};\n\nexport type SharedLiveQuery<TResult> = LiveQuery<TResult> & {\n readonly sql: string;\n readonly parameters: readonly unknown[];\n getSubscriberCount: () => number;\n};\n\ntype SharedLiveQueryEntry<TResult> = SharedLiveQuery<TResult> & {\n listeners: Set<() => void>;\n unsubscribeFromLiveQuery: (() => void) | null;\n cleanupTimeout: ReturnType<typeof setTimeout> | null;\n};\n\nexport type SharedLiveQuerySnapshot = {\n sql: string;\n parameters: readonly unknown[];\n subscriberCount: number;\n};\n\nexport function createSQLiteReactiveDb<Database>(opts: SQLiteReactiveDbOptions) {\n return SQLiteReactiveDb.create<Database>(opts);\n}\n\nexport class SQLiteReactiveDb<Database> {\n readonly db: SQLiteDbWrapper<Database>;\n private sqlite3: Sqlite3Static;\n\n private readonly logger: Logger;\n\n private tablesUsedStatement: PreparedStatement<[string], { name: string; isWrite: boolean }> | null = null;\n\n private eventTarget = createTypedEventTarget<EventsMap>();\n private mutationVersion = 0;\n private tableMutationVersions = new Map<string, number>();\n\n private constructor(sqlite3: Sqlite3Static, logger: Logger) {\n this.sqlite3 = sqlite3;\n this.logger = logger;\n\n this.db = new SQLiteDbWrapper({\n db: () => new sqlite3.oo1.DB({ filename: \":memory:\" }),\n logger: this.logger,\n loggerPrefix: \"memory\",\n sqlite3,\n });\n }\n\n static async create<Database>(opts: SQLiteReactiveDbOptions) {\n const logger = opts.logger;\n const perf = startPerformanceLogger(logger, \"system\");\n if (!sqliteModule) {\n sqliteModule = await sqlite3InitModule();\n }\n\n const db = new SQLiteReactiveDb<Database>(sqliteModule, logger);\n\n if (opts.snapshot) {\n db.useSnapshot(opts.snapshot);\n }\n db.registerDbHooks();\n\n perf.logEnd(\"createSQLiteMemoryDb\", \"success\", \"system\");\n\n return db;\n }\n\n private liveQueryStatements = new BoundMap<string, PreparedStatement<any[], unknown>>({\n maxSize: 100,\n onRemove(_, value) {\n value.finalize();\n },\n });\n\n private sharedLiveQueries = new Map<string, SharedLiveQueryEntry<unknown>[]>();\n\n createLiveQuery<TResult>(query: { sql: string; parameters: readonly unknown[] }) {\n const fetchRows = (parameters: readonly unknown[]) => {\n let statement = this.liveQueryStatements.get(query.sql);\n if (!statement) {\n statement = this.db.prepare<any[], any>(query.sql);\n this.liveQueryStatements.set(query.sql, statement);\n }\n return statement.execute(parameters as any) as TResult[];\n };\n\n let rows: TResult[] | null = null;\n\n const getRows = () => {\n if (!rows) {\n rows = fetchRows(query.parameters);\n }\n return rows;\n };\n\n let subscriber: (() => void) | null = null;\n\n let lastParameters: readonly unknown[] = query.parameters;\n const refresh = (parameters?: readonly unknown[]) => {\n if (parameters) {\n lastParameters = parameters;\n }\n rows = fetchRows(lastParameters);\n subscriber?.();\n };\n\n const subscribe = (onchange: () => void) => {\n if (subscriber) {\n throw new Error(\"Subscriber already exists\");\n }\n\n subscriber = onchange;\n const subscription = this.subscribeToQueryChanges({\n sql: query.sql,\n onDataChange: refresh,\n });\n\n return () => {\n subscription.unsubscribe();\n subscriber = null;\n };\n };\n\n return { getRows, refresh, subscribe };\n }\n\n getSharedLiveQuery<TResult>(query: { sql: string; parameters: readonly unknown[] }) {\n const existingEntry = this.sharedLiveQueries\n .get(query.sql)\n ?.find((entry) => parametersAreEqual(entry.parameters, query.parameters));\n if (existingEntry) {\n if (existingEntry.listeners.size === 0) {\n this.scheduleSharedLiveQueryCleanup(existingEntry);\n }\n return existingEntry as SharedLiveQuery<TResult>;\n }\n\n const liveQuery = this.createLiveQuery<TResult>(query);\n let hasDetachedFromLiveQuery = false;\n const entry: SharedLiveQueryEntry<TResult> = {\n sql: query.sql,\n parameters: query.parameters,\n listeners: new Set(),\n unsubscribeFromLiveQuery: null,\n cleanupTimeout: null,\n getRows: () => liveQuery.getRows(),\n refresh: () => {\n liveQuery.refresh();\n },\n getSubscriberCount: () => entry.listeners.size,\n subscribe: (onchange) => {\n this.cancelSharedLiveQueryCleanup(entry);\n this.registerSharedLiveQueryEntry(entry as SharedLiveQueryEntry<unknown>);\n entry.listeners.add(onchange);\n\n if (!entry.unsubscribeFromLiveQuery) {\n entry.unsubscribeFromLiveQuery = liveQuery.subscribe(() => {\n for (const listener of entry.listeners) {\n listener();\n }\n });\n\n // Rows may have gone stale while no subscriber was listening\n // for table changes.\n if (hasDetachedFromLiveQuery) {\n hasDetachedFromLiveQuery = false;\n liveQuery.refresh();\n }\n }\n\n return () => {\n entry.listeners.delete(onchange);\n\n if (entry.listeners.size === 0) {\n entry.unsubscribeFromLiveQuery?.();\n entry.unsubscribeFromLiveQuery = null;\n hasDetachedFromLiveQuery = true;\n this.scheduleSharedLiveQueryCleanup(entry);\n }\n };\n },\n };\n\n this.registerSharedLiveQueryEntry(entry as SharedLiveQueryEntry<unknown>);\n\n // Evict the entry if no subscriber attaches by the next tick.\n this.scheduleSharedLiveQueryCleanup(entry as SharedLiveQueryEntry<unknown>);\n\n return entry;\n }\n\n private registerSharedLiveQueryEntry(entry: SharedLiveQueryEntry<unknown>) {\n const matchingSqlEntries = this.sharedLiveQueries.get(entry.sql) ?? [];\n if (!matchingSqlEntries.includes(entry)) {\n matchingSqlEntries.push(entry);\n this.sharedLiveQueries.set(entry.sql, matchingSqlEntries);\n }\n }\n\n getSharedLiveQueriesSnapshot(): SharedLiveQuerySnapshot[] {\n const snapshot: SharedLiveQuerySnapshot[] = [];\n for (const entries of this.sharedLiveQueries.values()) {\n for (const entry of entries) {\n snapshot.push({\n sql: entry.sql,\n parameters: entry.parameters,\n subscriberCount: entry.listeners.size,\n });\n }\n }\n return snapshot;\n }\n\n private scheduleSharedLiveQueryCleanup(entry: SharedLiveQueryEntry<unknown>) {\n this.cancelSharedLiveQueryCleanup(entry);\n entry.cleanupTimeout = setTimeout(() => {\n entry.cleanupTimeout = null;\n this.releaseSharedLiveQuery(entry);\n }, 0);\n }\n\n private cancelSharedLiveQueryCleanup(entry: SharedLiveQueryEntry<unknown>) {\n if (entry.cleanupTimeout) {\n clearTimeout(entry.cleanupTimeout);\n entry.cleanupTimeout = null;\n }\n }\n\n private releaseSharedLiveQuery(entry: SharedLiveQueryEntry<unknown>) {\n if (entry.listeners.size > 0 || entry.unsubscribeFromLiveQuery) {\n return;\n }\n\n const matchingSqlEntries = this.sharedLiveQueries.get(entry.sql);\n if (!matchingSqlEntries) {\n return;\n }\n\n const nextEntries = matchingSqlEntries.filter((candidate) => candidate !== entry);\n if (nextEntries.length > 0) {\n this.sharedLiveQueries.set(entry.sql, nextEntries);\n } else {\n this.sharedLiveQueries.delete(entry.sql);\n }\n }\n\n subscribeToQueryChanges(params: { sql: string; onDataChange: () => void }) {\n const { sql, onDataChange } = params;\n\n const tables = this.getTablesUsed(sql);\n const readTables = new Set<string>();\n for (const table of tables) {\n if (!readTables.has(table.name)) {\n readTables.add(table.name);\n } else if (table.isWrite) {\n throw new Error(\"This query writes and reads from the same table. This may cause infinite loops.\");\n }\n }\n\n const notifyDataChange = createDebouncedCallback(() => {\n onDataChange();\n }, 30);\n\n for (const table of readTables) {\n this.eventTarget.addEventListener(`table:${table}`, notifyDataChange);\n }\n this.eventTarget.addEventListener(\"any-table-changed\", notifyDataChange);\n\n return {\n unsubscribe: () => {\n for (const table of readTables) {\n this.eventTarget.removeEventListener(`table:${table}`, notifyDataChange);\n }\n this.eventTarget.removeEventListener(\"any-table-changed\", notifyDataChange);\n },\n };\n }\n\n subscribeToTableChanges(table: string, onChanges: () => void) {\n this.eventTarget.addEventListener(`table:${table}`, onChanges);\n this.eventTarget.addEventListener(\"any-table-changed\", onChanges);\n return {\n unsubscribe: () => {\n this.eventTarget.removeEventListener(`table:${table}`, onChanges);\n this.eventTarget.removeEventListener(\"any-table-changed\", onChanges);\n },\n };\n }\n\n getTablesUsed(query: string) {\n if (!this.tablesUsedStatement) {\n this.tablesUsedStatement = this.db.prepare<[string], { name: string; isWrite: boolean }>(\n \"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'\",\n { loggerLevel: \"system\" },\n );\n }\n\n const tables = this.tablesUsedStatement.execute([query]);\n\n if (tables.length === 0 && query.toLowerCase().includes(\"delete\")) {\n // tables_used function does not work with delete queries that clear entire tables\n tables.push(...this.getClearedTables(query));\n }\n\n return tables;\n }\n\n private getClearedTables(query: string) {\n const operations = this.db.execute<{\n opcode: string;\n p1: number;\n p2: number;\n }>(`EXPLAIN ${query.split(\";\")[0]}`, { loggerLevel: \"system\" }).rows;\n\n const clearedTablesRootPages = new Set<number>();\n for (const operation of operations) {\n if (operation.opcode === \"Clear\" && operation.p2 === 0) {\n clearedTablesRootPages.add(operation.p1);\n }\n }\n\n if (clearedTablesRootPages.size === 0) {\n return [];\n }\n\n const tableNames = this.db.execute<{ name: string; isWrite: boolean }>(\n `select t.tbl_name as name, true as isWrite from sqlite_master as t where t.rootpage in (${Array.from(\n clearedTablesRootPages,\n ).join(\",\")})`,\n { loggerLevel: \"system\" },\n ).rows;\n\n return tableNames;\n }\n\n addEventListener<K extends keyof EventsMap>(type: K, listener: (event: TypedEvent<EventsMap[K]>) => void) {\n this.eventTarget.addEventListener(type, listener);\n }\n\n removeEventListener<K extends keyof EventsMap>(type: K, listener: (event: TypedEvent<EventsMap[K]>) => void) {\n this.eventTarget.removeEventListener(type, listener);\n }\n\n getTableMutationVersion(table: string) {\n return this.tableMutationVersions.get(table) ?? 0;\n }\n\n private notifyTableSubscribers(tables: (TableName<Database> | (string & {}))[] | Set<string> | null = null) {\n if (!tables) {\n this.eventTarget.dispatchEvent(\"any-table-changed\", undefined);\n return;\n }\n\n for (const table of tables) {\n this.eventTarget.dispatchEvent(`table:${table}`, undefined);\n }\n }\n\n private registerDbHooks() {\n let updateQueue = new Set<string>();\n\n this.sqlite3.capi.sqlite3_update_hook(\n this.db.ensureDb,\n (_ctx, _opId, _db, table) => {\n updateQueue.add(table);\n this.tableMutationVersions.set(table, ++this.mutationVersion);\n },\n 0,\n );\n\n this.sqlite3.capi.sqlite3_rollback_hook(\n this.db.ensureDb,\n () => {\n if (updateQueue.size === 0) {\n return 0;\n }\n\n updateQueue.clear();\n this.eventTarget.dispatchEvent(\"transaction-rolled-back\", undefined);\n\n return 0;\n },\n 0,\n );\n\n this.sqlite3.capi.sqlite3_commit_hook(\n this.db.ensureDb,\n () => {\n if (updateQueue.size === 0) {\n return 0;\n }\n\n const tables = updateQueue;\n updateQueue = new Set<string>();\n this.eventTarget.dispatchEvent(\"transaction-committed\", undefined);\n\n queueMicrotask(() => {\n this.notifyTableSubscribers(tables);\n });\n return 0;\n },\n 0,\n );\n }\n\n createSnapshot() {\n const perf = startPerformanceLogger(this.logger);\n const snapshot = this.sqlite3.capi.sqlite3_js_db_export(this.db.ensureDb);\n perf.logEnd(\"createSnapshot\", `snapshot size: ${snapshot.byteLength}`, \"info\");\n\n return snapshot;\n }\n\n useSnapshot(snapshot: Uint8Array<ArrayBufferLike>) {\n this.db.useSnapshot(snapshot);\n this.notifyTableSubscribers();\n }\n\n dispose() {\n for (const entries of this.sharedLiveQueries.values()) {\n for (const entry of entries) {\n this.cancelSharedLiveQueryCleanup(entry);\n entry.unsubscribeFromLiveQuery?.();\n entry.unsubscribeFromLiveQuery = null;\n entry.listeners.clear();\n }\n }\n this.sharedLiveQueries.clear();\n this.liveQueryStatements.clear();\n if (this.tablesUsedStatement) {\n this.tablesUsedStatement.finalize();\n this.tablesUsedStatement = null;\n }\n this.db.close();\n }\n}\n\nfunction createDebouncedCallback<TArgs extends unknown[]>(callback: (...args: TArgs) => void, delay: number) {\n let timeout: unknown | null = null;\n let shouldCallWithoutDelay = true;\n\n return (...args: TArgs) => {\n if (shouldCallWithoutDelay) {\n callback(...args);\n shouldCallWithoutDelay = false;\n return;\n }\n\n const effect = () => {\n timeout = null;\n shouldCallWithoutDelay = true;\n return callback(...args);\n };\n\n if (timeout) {\n clearTimeout(timeout as any);\n }\n\n timeout = setTimeout(effect, delay);\n };\n}\n\nexport function parametersAreEqual(a: readonly unknown[] | undefined, b: readonly unknown[] | undefined): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) {\n return false;\n }\n }\n return true;\n}\n","import type { SyncDbSchema } from \"../sqlite-crdt/crdt-schema\";\nimport type { WriteOrigin } from \"./table-builder\";\n\nexport type AdmitClientEventsResult<T> = {\n admitted: T[];\n skipped: T[];\n};\n\ntype SchemaForAdmitClientEvents = Pick<SyncDbSchema, \"tables\" | \"tablesConfig\"> & {\n writeOriginByName?: ReadonlyMap<string, WriteOrigin>;\n};\n\nexport function buildWriteOriginByName(\n schema: Pick<SyncDbSchema, \"tables\" | \"tablesConfig\">,\n): Map<string, WriteOrigin> {\n const writeOriginByName = new Map<string, WriteOrigin>();\n for (const { crdtTableName, baseTableName } of schema.tablesConfig) {\n const writeOrigin = schema.tables[crdtTableName]?.writeOrigin ?? \"any\";\n writeOriginByName.set(crdtTableName, writeOrigin);\n writeOriginByName.set(baseTableName, writeOrigin);\n }\n return writeOriginByName;\n}\n\n/**\n * Splits a client push into events the hub should persist and events for tables with\n * `{ writes: \"server\" }`. Unknown datasets stay admitted. Matches either the crdt or the base\n * table name.\n */\nexport function admitClientEvents<T extends { dataset: string }>(opts: {\n syncDbSchema: SchemaForAdmitClientEvents;\n events: readonly T[];\n}): AdmitClientEventsResult<T> {\n const writeOriginByName = opts.syncDbSchema.writeOriginByName ?? buildWriteOriginByName(opts.syncDbSchema);\n\n const admitted: T[] = [];\n const skipped: T[] = [];\n for (const event of opts.events) {\n if (writeOriginByName.get(event.dataset) === \"server\") {\n skipped.push(event);\n } else {\n admitted.push(event);\n }\n }\n return { admitted, skipped };\n}\n","import type { Migrations } from \"../migrations/migrator\";\nimport type { CrdtTableConfig, ReadonlyTable, SyncDbSchema } from \"../sqlite-crdt/crdt-schema\";\nimport { buildWriteOriginByName } from \"./admit-client-events\";\nimport type {\n AnyTableBuilder,\n InferRow,\n SyncSchemaTables,\n TableBuilder,\n TableColumns,\n WriteOrigin,\n} from \"./table-builder\";\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\n// Names sqlite-sync uses for its own tables/views, so a user schema can't shadow them.\nconst RESERVED_TABLE_NAMES = new Set<string>([\n \"change_history\",\n \"crdt_events\",\n \"worker.crdt_events\",\n \"persisted_crdt_events\",\n \"crdt_update_log\",\n \"crdt_change_intents\",\n \"worker.kv\",\n]);\n\ntype RowOf<Table extends AnyTableBuilder> =\n Table extends TableBuilder<infer Cols extends TableColumns, any, WriteOrigin> ? InferRow<Cols> : never;\n\n// Falls back to the \"_\" convention unless ~baseName is a string *literal* — inference can\n// resolve an omitted override to its constraint (string | undefined) rather than undefined.\ntype BaseNameOf<CrdtName, Table extends AnyTableBuilder> = string extends Table[\"~baseName\"]\n ? `_${CrdtName & string}`\n : [Table[\"~baseName\"]] extends [string]\n ? Table[\"~baseName\"]\n : `_${CrdtName & string}`;\n\ntype ClientSchemaOf<Tables extends SyncSchemaTables> = Simplify<\n {\n [K in keyof Tables]: Tables[K][\"~writeOrigin\"] extends \"server\"\n ? ReadonlyTable<RowOf<Tables[K]>>\n : RowOf<Tables[K]>;\n } & {\n [K in keyof Tables as BaseNameOf<K, Tables[K]>]: ReadonlyTable<RowOf<Tables[K]>>;\n }\n>;\n\ntype ServerSchemaOf<Tables extends SyncSchemaTables> = Simplify<\n { [K in keyof Tables]: RowOf<Tables[K]> } & {\n [K in keyof Tables as BaseNameOf<K, Tables[K]>]: ReadonlyTable<RowOf<Tables[K]>>;\n }\n>;\n\ntype MutationsSchemaOf<Tables extends SyncSchemaTables> = Simplify<{\n [K in keyof Tables as BaseNameOf<K, Tables[K]>]: RowOf<Tables[K]>;\n}>;\n\nexport interface DefinedSyncSchema<Tables extends SyncSchemaTables>\n extends SyncDbSchema<ClientSchemaOf<Tables>, ServerSchemaOf<Tables>, MutationsSchemaOf<Tables>> {\n /** The table builders, for type extraction (`typeof schema.tables.item.$row`) and runtime metadata. */\n tables: Tables;\n /** Write origin keyed by crdt and base table name. */\n writeOriginByName: ReadonlyMap<string, WriteOrigin>;\n}\n\nexport type DefineSyncSchemaConfig<Tables extends SyncSchemaTables> = {\n tables: Tables;\n /** Full migration history (including the initial createTable version), built with `createMigrations`. */\n migrations: Migrations;\n};\n\n/**\n * Define a sync database schema from `t.table()` builders.\n *\n * Record keys are the crdt (view) table names; base table names default to the key\n * prefixed with \"_\", overridable per table via `t.table(cols, { baseName })`.\n */\nexport function defineSyncSchema<Tables extends SyncSchemaTables>({\n tables,\n migrations,\n}: DefineSyncSchemaConfig<Tables>): DefinedSyncSchema<Tables> {\n const tablesConfig: CrdtTableConfig[] = Object.entries(tables).map(([crdtTableName, table]) => ({\n crdtTableName,\n baseTableName: table.baseName ?? `_${crdtTableName}`,\n }));\n\n const seenNames = new Set<string>();\n for (const { crdtTableName, baseTableName } of tablesConfig) {\n for (const name of [crdtTableName, baseTableName]) {\n const normalizedName = name.toLowerCase();\n if (RESERVED_TABLE_NAMES.has(normalizedName)) {\n throw new Error(`Table name \"${name}\" is reserved by sqlite-sync and cannot be used in a sync schema`);\n }\n if (seenNames.has(normalizedName)) {\n throw new Error(`Duplicate table name \"${name}\" in sync schema`);\n }\n seenNames.add(normalizedName);\n }\n }\n\n const writeOriginByName = buildWriteOriginByName({ tables, tablesConfig });\n\n return {\n tables,\n get tablesConfig() {\n return tablesConfig;\n },\n get writeOriginByName() {\n return writeOriginByName;\n },\n get migrations() {\n return migrations;\n },\n get \"~clientSchema\"(): never {\n throw new Error(\"~clientSchema is type-only and cannot be accessed at runtime\");\n },\n get \"~serverSchema\"(): never {\n throw new Error(\"~serverSchema is type-only and cannot be accessed at runtime\");\n },\n get \"~mutationsSchema\"(): never {\n throw new Error(\"~mutationsSchema is type-only and cannot be accessed at runtime\");\n },\n };\n}\n","export type ColumnKind = \"text\" | \"integer\" | \"real\" | \"boolean\" | \"enum\";\n\nexport type SqliteStorageType = \"text\" | \"integer\" | \"real\";\n\n/**\n * What `@sqlite-sync/ai` may do with a table.\n * `read-only`: documented and queryable; mutations rejected.\n * `hidden`: omitted from the schema doc; reads rejected.\n */\nexport type AiAccess = \"read-write\" | \"read-only\" | \"hidden\";\n\n/**\n * Who may author CRDT events for a table.\n * `\"any\"` (default): every replica. `\"server\"`: client pushes drop these events.\n */\nexport type WriteOrigin = \"any\" | \"server\";\n\nexport type ColumnMeta = {\n kind: ColumnKind;\n /** Storage type used in generated DDL. Booleans store as integer 0/1. */\n sqlType: SqliteStorageType;\n nullable: boolean;\n hasDefault: boolean;\n /** Declared default in JS form (booleans as booleans). */\n defaultValue?: unknown;\n /** Allowed values for `enum` columns. */\n enumValues?: readonly string[];\n description?: string;\n};\n\nexport class ColumnBuilder<Value, HasDefault extends boolean = false> {\n declare readonly \"~types\": { value: Value; hasDefault: HasDefault };\n\n constructor(readonly meta: ColumnMeta) {}\n\n /** Allow SQL NULL; widens the value type with `null`. */\n nullable(): ColumnBuilder<Value | null, HasDefault> {\n return new ColumnBuilder({ ...this.meta, nullable: true });\n }\n\n /** Declare a column default. The value is used both in DDL and when migrating older events. */\n default(value: Value): ColumnBuilder<Value, true> {\n return new ColumnBuilder({ ...this.meta, hasDefault: true, defaultValue: value });\n }\n\n /** Narrow the TypeScript value type without changing storage, e.g. `t.text().$type<\"movie\" | \"tv\">()`. */\n $type<Narrowed extends Value>(): ColumnBuilder<Narrowed, HasDefault> {\n return this as unknown as ColumnBuilder<Narrowed, HasDefault>;\n }\n\n /** Human/AI-readable description, surfaced in generated schema docs. */\n describe(description: string): ColumnBuilder<Value, HasDefault> {\n return new ColumnBuilder({ ...this.meta, description });\n }\n}\n\nexport type AnyColumnBuilder = ColumnBuilder<any, boolean>;\n\nexport type TableColumns = Record<string, AnyColumnBuilder>;\n\nexport type AnyTableBuilder = TableBuilder<any, any, WriteOrigin>;\n\nexport type SyncSchemaTables = Record<string, AnyTableBuilder>;\n\nexport type TableOptions<\n BaseName extends string | undefined = string | undefined,\n Writes extends WriteOrigin = \"any\",\n> = {\n /** Override the materialized base table name (defaults to the crdt table name prefixed with \"_\"). */\n baseName?: BaseName;\n description?: string;\n /** Defaults to `\"read-write\"`. See {@link AiAccess}. */\n ai?: AiAccess;\n /** Defaults to `\"any\"`. See {@link WriteOrigin}. */\n writes?: Writes;\n};\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\ntype ColumnValue<Column> = Column extends ColumnBuilder<infer Value, boolean> ? Value : never;\n\nexport type InferRow<Cols extends TableColumns> = Simplify<\n { id: string } & { [K in keyof Cols]: ColumnValue<Cols[K]> } & { tombstone?: boolean }\n>;\n\nexport type PayloadValidationResult = { success: true } | { success: false; errors: string[] };\n\nconst RESERVED_COLUMNS = [\"id\", \"tombstone\"] as const;\n\nconst idColumnMeta: ColumnMeta = {\n kind: \"text\",\n sqlType: \"text\",\n nullable: false,\n hasDefault: false,\n description: \"Unique immutable item id\",\n};\n\nconst tombstoneColumnMeta: ColumnMeta = {\n kind: \"boolean\",\n sqlType: \"integer\",\n nullable: false,\n hasDefault: true,\n defaultValue: false,\n description: \"Soft-delete marker\",\n};\n\nexport class TableBuilder<\n Cols extends TableColumns,\n BaseName extends string | undefined = undefined,\n Writes extends WriteOrigin = \"any\",\n> {\n declare readonly \"~baseName\": BaseName;\n declare readonly \"~writeOrigin\": Writes;\n\n /** All columns in DDL order, including the auto-injected `id` and `tombstone`. */\n readonly columns: Record<string, ColumnMeta>;\n readonly baseName: BaseName;\n readonly description: string | undefined;\n /** Resolved {@link AiAccess}; defaults to `\"read-write\"`. */\n readonly aiAccess: AiAccess;\n /** Resolved {@link WriteOrigin}; defaults to `\"any\"`. */\n readonly writeOrigin: Writes;\n\n constructor(\n readonly userColumns: Cols,\n options?: TableOptions<BaseName, Writes>,\n ) {\n for (const reserved of RESERVED_COLUMNS) {\n if (reserved in userColumns) {\n throw new Error(`Column \"${reserved}\" is added automatically to every synced table and cannot be declared`);\n }\n }\n\n this.columns = {\n id: idColumnMeta,\n ...Object.fromEntries(Object.entries(userColumns).map(([name, column]) => [name, column.meta])),\n tombstone: tombstoneColumnMeta,\n };\n this.baseName = options?.baseName as BaseName;\n this.description = options?.description;\n this.aiAccess = options?.ai ?? \"read-write\";\n this.writeOrigin = (options?.writes ?? \"any\") as Writes;\n }\n\n /** Rebuilds the table with `overrides` applied over the current options. */\n private withOptions(overrides: Partial<TableOptions<BaseName, Writes>>): TableBuilder<Cols, BaseName, Writes> {\n return new TableBuilder<Cols, BaseName, Writes>(this.userColumns, {\n baseName: this.baseName,\n description: this.description,\n ai: this.aiAccess,\n writes: this.writeOrigin,\n ...overrides,\n });\n }\n\n describe(description: string): TableBuilder<Cols, BaseName, Writes> {\n return this.withOptions({ description });\n }\n\n /** Same as `{ ai }` in {@link TableOptions}. */\n ai(access: AiAccess): TableBuilder<Cols, BaseName, Writes> {\n return this.withOptions({ ai: access });\n }\n\n /** Same as `{ writes }` in {@link TableOptions}. */\n writes<const Origin extends WriteOrigin>(origin: Origin): TableBuilder<Cols, BaseName, Origin> {\n return new TableBuilder<Cols, BaseName, Origin>(this.userColumns, {\n baseName: this.baseName,\n description: this.description,\n ai: this.aiAccess,\n writes: origin,\n });\n }\n\n /** Type-only: the row shape returned by queries. Do not access at runtime. */\n get $row(): InferRow<Cols> {\n return null as never;\n }\n\n /**\n * Validate a CRDT event payload against the declared columns.\n * `item-created` payloads must contain every column without a default (nullable columns may be omitted);\n * `item-updated` payloads are partial and must not touch `id` or set `tombstone` to a deleted value.\n */\n validatePayload(\n payload: Record<string, unknown>,\n options?: { event?: \"item-created\" | \"item-updated\" },\n ): PayloadValidationResult {\n const event = options?.event ?? \"item-created\";\n const errors: string[] = [];\n\n for (const key of Object.keys(payload)) {\n if (!(key in this.columns)) {\n errors.push(`Unknown column \"${key}\"`);\n }\n }\n\n if (event === \"item-updated\") {\n if (\"id\" in payload) {\n errors.push(`Column \"id\" is immutable and cannot appear in an update payload`);\n }\n if (payload.tombstone === true || payload.tombstone === 1) {\n errors.push(`Column \"tombstone\" cannot be set to true/1 in an update payload; use an item-deleted event`);\n }\n }\n\n if (event === \"item-created\") {\n for (const [name, meta] of Object.entries(this.columns)) {\n if (name in payload || name === \"tombstone\" || meta.nullable || meta.hasDefault) {\n continue;\n }\n errors.push(`Missing required column \"${name}\"`);\n }\n }\n\n for (const [name, value] of Object.entries(payload)) {\n const meta = this.columns[name];\n if (!meta || (event === \"item-updated\" && name === \"id\")) {\n continue;\n }\n const error = validateValue(name, value, meta);\n if (error) {\n errors.push(error);\n }\n }\n\n return errors.length === 0 ? { success: true } : { success: false, errors };\n }\n}\n\nfunction describeValue(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n return typeof value;\n}\n\nfunction validateValue(name: string, value: unknown, meta: ColumnMeta): string | null {\n if (value === null) {\n return meta.nullable ? null : `Column \"${name}\" is not nullable, got null`;\n }\n\n switch (meta.kind) {\n case \"text\":\n return typeof value === \"string\" ? null : `Column \"${name}\" expects text, got ${describeValue(value)}`;\n case \"integer\":\n return typeof value === \"number\" && Number.isInteger(value)\n ? null\n : `Column \"${name}\" expects an integer, got ${describeValue(value)}`;\n case \"real\":\n return typeof value === \"number\" && Number.isFinite(value)\n ? null\n : `Column \"${name}\" expects a number, got ${describeValue(value)}`;\n case \"boolean\":\n return typeof value === \"boolean\" || value === 0 || value === 1\n ? null\n : `Column \"${name}\" expects a boolean (true/false or 0/1), got ${describeValue(value)}`;\n case \"enum\": {\n if (typeof value !== \"string\") {\n return `Column \"${name}\" expects one of ${formatEnumValues(meta)}, got ${describeValue(value)}`;\n }\n return meta.enumValues?.includes(value)\n ? null\n : `Column \"${name}\" expects one of ${formatEnumValues(meta)}, got \"${value}\"`;\n }\n }\n}\n\nfunction formatEnumValues(meta: ColumnMeta): string {\n return (meta.enumValues ?? []).map((value) => `\"${value}\"`).join(\" | \");\n}\n\nfunction column<Value>(kind: ColumnKind, sqlType: SqliteStorageType): ColumnBuilder<Value> {\n return new ColumnBuilder<Value>({ kind, sqlType, nullable: false, hasDefault: false });\n}\n\nexport const t = {\n text: () => column<string>(\"text\", \"text\"),\n integer: () => column<number>(\"integer\", \"integer\"),\n real: () => column<number>(\"real\", \"real\"),\n /** Stored as INTEGER 0/1; always bind booleans as 0/1 when writing raw SQL. */\n boolean: () => column<boolean>(\"boolean\", \"integer\"),\n /**\n * Union of string literals stored as TEXT, e.g. `t.enum([\"movie\", \"tv\"])`. Unlike `$type`, the\n * allowed values are kept as runtime metadata, so payloads are validated against them.\n * For an open-ended set, use `t.text().$type<\"idle\" | (string & {})>()` instead.\n */\n enum: <const Values extends readonly [string, ...string[]]>(values: Values) =>\n new ColumnBuilder<Values[number]>({\n kind: \"enum\",\n sqlType: \"text\",\n nullable: false,\n hasDefault: false,\n enumValues: values,\n }),\n table: <\n Cols extends TableColumns,\n const BaseName extends string | undefined = undefined,\n const Writes extends WriteOrigin = \"any\",\n >(\n columns: Cols,\n options?: TableOptions<BaseName, Writes>,\n ) => new TableBuilder(columns, options),\n};\n","import type { CrdtStorage, OwnCrdtEvent } from \"./crdt-storage\";\n\nexport type CrdtStorageMutator<Database> = ReturnType<typeof createCrdtStorageMutator<Database>>;\n\ntype CommitEventOptions<Database, Table extends keyof Database & string> =\n | {\n type: \"item-created\";\n dataset: Table;\n item_id: string;\n payload: CreateEventPayload<Database, Table>;\n }\n | {\n type: \"item-updated\";\n dataset: Table;\n item_id: string;\n payload: UpdateEventPayload<Database, Table>;\n }\n | {\n type: \"item-deleted\";\n dataset: Table;\n item_id: string;\n };\n\ntype CreateEventPayload<Database, Table extends keyof Database> = Omit<Database[Table], \"tombstone\">;\ntype UpdateEventPayload<Database, Table extends keyof Database> = Omit<Partial<Database[Table]>, \"id\" | \"tombstone\">;\n\nexport type SnapshotOptions<Database, Table extends keyof Database & string> = {\n dataset: Table;\n id: string;\n patch: UpdateEventPayload<Database, Table>;\n};\n\nexport function createCrdtStorageMutator<Database>({ storage }: { storage: CrdtStorage }) {\n const mapToStorageEvent = (event: CommitEventOptions<Database, keyof Database & string>): OwnCrdtEvent => {\n switch (event.type) {\n case \"item-created\":\n return {\n type: \"item-created\",\n dataset: event.dataset,\n item_id: event.item_id,\n payload: JSON.stringify(event.payload),\n };\n case \"item-updated\":\n return {\n type: \"item-updated\",\n dataset: event.dataset,\n item_id: event.item_id,\n payload: JSON.stringify(event.payload),\n };\n case \"item-deleted\":\n return {\n type: \"item-deleted\",\n dataset: event.dataset,\n item_id: event.item_id,\n payload: \"{}\",\n };\n }\n };\n\n const enqueueEvents = (events: CommitEventOptions<Database, keyof Database & string>[]) => {\n storage.enqueueOwnEvents(events.map(mapToStorageEvent));\n };\n\n const createEvent = <Table extends keyof Database & string>(event: CommitEventOptions<Database, Table>) => {\n return event;\n };\n\n const enqueueEvent = (event: CommitEventOptions<Database, keyof Database & string>) => {\n storage.enqueueOwnEvents([mapToStorageEvent(event)]);\n };\n\n const enqueueSnapshot = <Table extends keyof Database & string>(snapshot: SnapshotOptions<Database, Table>) => {\n storage.applyOwnSnapshot({\n dataset: snapshot.dataset,\n item_id: snapshot.id,\n patch: { ...snapshot.patch },\n });\n };\n\n return {\n enqueueEvents,\n createEvent,\n enqueueEvent,\n enqueueSnapshot,\n };\n}\n","const dbIdRegex = /^[a-zA-Z][a-zA-Z\\-0-9]{2,63}$/;\n\nexport function validateDbId(dbId: string) {\n if (!dbIdRegex.test(dbId)) {\n throw new Error(\"Invalid dbId. Must be between 3 and 64 characters long and start with a letter.\");\n }\n}\n","import type { SyncedDb } from \"./sync-db\";\n\nconst devtoolsRegistrySymbol = Symbol.for(\"@sqlite-sync/devtools\");\n\nexport type SQLiteSyncDevtoolsInstance = {\n instanceId: string;\n dbId: string;\n createdAt: number;\n instance: SyncedDb<any>;\n};\n\nexport type SQLiteSyncDevtoolsSnapshot = {\n instances: readonly SQLiteSyncDevtoolsInstance[];\n};\n\nexport type SQLiteSyncDevtoolsRegistry = {\n version: 1;\n instances: Map<string, SQLiteSyncDevtoolsInstance>;\n subscribe(listener: () => void): () => void;\n getSnapshot(): SQLiteSyncDevtoolsSnapshot;\n register(instance: SQLiteSyncDevtoolsInstance): () => void;\n};\n\ntype RegistryGlobal = typeof globalThis & {\n [key: symbol]: SQLiteSyncDevtoolsRegistry | undefined;\n};\n\nfunction createSQLiteSyncDevtoolsRegistry(): SQLiteSyncDevtoolsRegistry {\n const instances = new Map<string, SQLiteSyncDevtoolsInstance>();\n const listeners = new Set<() => void>();\n let snapshot: SQLiteSyncDevtoolsSnapshot = {\n instances: [],\n };\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n const updateSnapshot = () => {\n snapshot = {\n instances: Array.from(instances.values()),\n };\n notify();\n };\n\n return {\n version: 1,\n instances,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n getSnapshot() {\n return snapshot;\n },\n register(instance) {\n instances.set(instance.instanceId, instance);\n updateSnapshot();\n\n let isUnregistered = false;\n return () => {\n if (isUnregistered) return;\n isUnregistered = true;\n\n if (!instances.delete(instance.instanceId)) return;\n updateSnapshot();\n };\n },\n };\n}\n\nexport function getOrCreateSQLiteSyncDevtoolsRegistry(): SQLiteSyncDevtoolsRegistry {\n const registryGlobal = globalThis as RegistryGlobal;\n\n registryGlobal[devtoolsRegistrySymbol] ??= createSQLiteSyncDevtoolsRegistry();\n\n return registryGlobal[devtoolsRegistrySymbol];\n}\n","import { xxhash } from \"../hash\";\nimport type { HLCCounter } from \"../hlc\";\nimport type { SyncDbMigrator } from \"../migrations/migrator\";\nimport { applyMemoryDbSchema, type MemoryDbSchema, memoryDbConfig } from \"../migrations/system-schema\";\nimport type { CrdtTableConfig, SyncDbSchema } from \"../sqlite-crdt/crdt-schema\";\nimport { createCrdtStorage } from \"../sqlite-crdt/crdt-storage\";\nimport { makeCrdtTable, registerCrdtIntentDrainer } from \"../sqlite-crdt/make-crdt-table\";\nimport type { StoredValue } from \"../sqlite-crdt/stored-value\";\nimport type { SQLiteDbWrapper } from \"../sqlite-db-wrapper\";\nimport type { SQLiteReactiveDb } from \"./sqlite-reactive-db\";\n\ntype MemoryDbOptions<Database> = {\n nodeId: string;\n migrator: SyncDbMigrator;\n reactiveDb: SQLiteReactiveDb<Database>;\n hlcCounter: HLCCounter;\n crdtTables: CrdtTableConfig[];\n initializeSchema?: boolean;\n initialSyncId?: number;\n eventHlcAccumulator?: StoredValue<string>;\n syncDbSchema: Pick<SyncDbSchema, \"tables\" | \"tablesConfig\">;\n};\n\nexport async function createMemoryDb<Database>({\n nodeId,\n migrator,\n reactiveDb: _reactiveDb,\n hlcCounter,\n crdtTables,\n initializeSchema = true,\n initialSyncId,\n eventHlcAccumulator,\n syncDbSchema,\n}: MemoryDbOptions<Database>) {\n await xxhash.ensureLoaded();\n\n const reactiveDb = _reactiveDb as unknown as SQLiteReactiveDb<MemoryDbSchema>;\n const db = reactiveDb.db;\n\n if (initializeSchema) {\n applyMemoryDbSchema(db);\n for (const table of crdtTables) {\n makeCrdtTable({\n db,\n baseTableName: table.baseTableName,\n crdtTableName: table.crdtTableName,\n });\n }\n }\n\n const crdtStorage = createCrdtStorage({\n nodeId,\n initialLocalSyncId: initialSyncId ?? getCurrentSyncId(db),\n hlc: hlcCounter,\n migrator,\n db,\n dbConfig: memoryDbConfig,\n eventHlcAccumulator,\n schema: syncDbSchema,\n });\n\n registerCrdtIntentDrainer({\n reactiveDb,\n storage: crdtStorage,\n });\n\n return {\n crdtStorage,\n };\n}\n\nfunction getCurrentSyncId(db: SQLiteDbWrapper<MemoryDbSchema>) {\n return (\n db.execute<{ syncId: number }>(\"SELECT coalesce(max(sync_id), 0) AS syncId FROM persisted_crdt_events\", {\n loggerLevel: \"system\",\n }).rows[0]?.syncId ?? 0\n );\n}\n","import {\n createDeferredPromise,\n createTypedEventTarget,\n type DeferredPromise,\n noop,\n type TypedEventTarget,\n} from \"../utils\";\nimport type {\n AsyncRpc,\n WorkerBroadcastChannels,\n WorkerConfig,\n WorkerErrorResponseMessage,\n WorkerInitMessage,\n WorkerNotificationMessage,\n WorkerRequestMessage,\n WorkerRequestMethod,\n WorkerResponseMessage,\n WorkerRpc,\n WorkerState,\n} from \"./worker-common\";\nimport { isWorkerErrorResponseMessage, isWorkerNotificationMessage, isWorkerResponseMessage } from \"./worker-common\";\n\ntype NotificationEvents = {\n [K in WorkerNotificationMessage[\"notificationType\"]]: Extract<WorkerNotificationMessage, { notificationType: K }>;\n};\n\nexport const createWorkerDbClient = async ({\n broadcastChannels,\n worker,\n config,\n}: {\n broadcastChannels: WorkerBroadcastChannels;\n worker: Worker;\n config: WorkerConfig;\n}) => {\n const eventTarget = createTypedEventTarget<NotificationEvents>();\n const workerRequestsMap = new Map<string, DeferredPromise<unknown>>();\n let isDisposed = false;\n\n const queryWorker = <TMethod extends WorkerRequestMethod>(\n method: TMethod,\n args: Parameters<WorkerRpc[TMethod]>,\n ): Promise<Awaited<ReturnType<WorkerRpc[TMethod]>>> => {\n if (isDisposed) {\n return Promise.reject(new Error(\"Worker client disposed\"));\n }\n const requestId = crypto.randomUUID();\n const promise = createDeferredPromise<unknown>({\n timeout: 30_000,\n onTimeout: () => workerRequestsMap.delete(requestId),\n });\n workerRequestsMap.set(requestId, promise);\n\n const request: WorkerRequestMessage<TMethod> = {\n type: \"request\",\n requestId,\n method,\n args,\n };\n\n broadcastChannels.requests.postMessage(request);\n\n return promise.promise as Promise<Awaited<ReturnType<WorkerRpc[TMethod]>>>;\n };\n\n const handleWorkerResponse = (message: WorkerResponseMessage) => {\n const promise = workerRequestsMap.get(message.requestId);\n if (!promise) {\n return;\n }\n\n promise.resolve(message.data);\n workerRequestsMap.delete(message.requestId);\n };\n\n const handleWorkerError = (message: WorkerErrorResponseMessage) => {\n const promise = workerRequestsMap.get(message.requestId);\n if (!promise) {\n return;\n }\n\n promise.reject(new Error(message.error));\n workerRequestsMap.delete(message.requestId);\n };\n\n broadcastChannels.responses.onmessage = (event) => {\n const message = event.data;\n\n if (isWorkerResponseMessage(message)) {\n handleWorkerResponse(message);\n } else if (isWorkerErrorResponseMessage(message)) {\n handleWorkerError(message);\n } else if (isWorkerNotificationMessage(message)) {\n eventTarget.dispatchEvent(message.notificationType, message);\n }\n };\n\n const rpc: AsyncRpc<WorkerRpc> = {\n execute: (query) => queryWorker(\"execute\", [query]),\n getSnapshot: () => queryWorker(\"getSnapshot\", []),\n importData: (data, opts) => queryWorker(\"importData\", [data, opts]),\n pushTabEvents: (request) => queryWorker(\"pushTabEvents\", [request]),\n pullEvents: (params) => queryWorker(\"pullEvents\", [params]),\n postState: () => queryWorker(\"postState\", []),\n goOnline: () => queryWorker(\"goOnline\", []),\n goOffline: () => queryWorker(\"goOffline\", []),\n requestReload: (options) => queryWorker(\"requestReload\", [options]),\n };\n\n const statePromise = awaitWorkerState(eventTarget);\n postWorkerConfig(worker, config);\n // On first tab, the worker may not have its BroadcastChannel listener ready yet,\n // so this request can be silently dropped and timeout. The worker will independently\n // post state at the end of init. For subsequent tabs, this triggers the already-running\n // worker to send its current state.\n rpc.postState().catch(noop);\n\n let workerState = await statePromise;\n\n eventTarget.addEventListener(\"state-changed\", (event) => {\n workerState = event.payload.state;\n });\n\n const dispose = () => {\n isDisposed = true;\n broadcastChannels.responses.onmessage = null;\n for (const [id, deferred] of workerRequestsMap) {\n deferred.reject(new Error(\"Worker client disposed\"));\n workerRequestsMap.delete(id);\n }\n };\n\n return {\n ...rpc,\n subscribe: eventTarget.addEventListener,\n getState: () => workerState,\n dispose,\n };\n};\n\nfunction awaitWorkerState(eventTarget: TypedEventTarget<NotificationEvents>) {\n const promise = createDeferredPromise<WorkerState>({ timeout: 15_000 });\n\n const subscription = eventTarget.addEventListener(\"state-changed\", (event) => {\n promise.resolve(event.payload.state);\n subscription.unsubscribe();\n });\n\n return promise.promise;\n}\n\nfunction postWorkerConfig(worker: Worker, config: WorkerConfig) {\n const configMessage: WorkerInitMessage = {\n type: \"init\",\n config,\n };\n worker.postMessage(configMessage);\n}\n","import type { Compilable, CompiledQuery } from \"kysely\";\nimport { validateDbId } from \"./db-id\";\nimport { getOrCreateSQLiteSyncDevtoolsRegistry } from \"./devtools-registry\";\nimport { createExportData, type ImportDataOptions, type SyncedDbExport } from \"./export-import\";\nimport { HLCCounter } from \"./hlc\";\nimport { type Logger, startPerformanceLogger } from \"./logger\";\nimport { createMemoryDb } from \"./memory-db/memory-db\";\nimport { createSQLiteReactiveDb, type SharedLiveQuery, type SQLiteReactiveDb } from \"./memory-db/sqlite-reactive-db\";\nimport type { SyncDbMigrator } from \"./migrations/migrator\";\nimport type { SyncDbSchema } from \"./sqlite-crdt/crdt-schema\";\nimport { createCrdtSyncRemoteSource } from \"./sqlite-crdt/crdt-sync-remote-source\";\nimport { createStoredValue } from \"./sqlite-crdt/stored-value\";\nimport type {\n ExecuteParams,\n ExecuteResult,\n KyselyQueryFactory,\n QueryBuilderOutput,\n SQLiteTransactionWrapper,\n} from \"./sqlite-db-wrapper\";\nimport { createDeferredPromise, generateId } from \"./utils\";\nimport { createWorkerDbClient } from \"./worker-db/db-worker-client\";\nimport { createBroadcastChannels, syncDbClientLockName } from \"./worker-db/worker-common\";\n\nexport type SyncedDbOptions<Database, Props = undefined> = {\n dbId: string;\n worker: Worker;\n workerProps: Props;\n syncDbSchema: SyncDbSchema<Database>;\n};\n\n/** SQL execution that participates in CRDT intent draining. */\nexport type SyncedDbSqlExecutor<Database> = {\n execute<TResult = unknown>(query: ExecuteParams | string | CompiledQuery<TResult>): ExecuteResult<TResult>;\n executeKysely<TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>>(\n factory: KyselyQueryFactory<Database, TQuery, TResult>,\n ): ExecuteResult<TResult>;\n};\n\n/**\n * SQL execution that deliberately bypasses CRDT intent draining.\n *\n * Mutating a synced view through this executor can leave undrained intents and\n * must only be done by sqlite-sync internals or recovery tooling.\n */\nexport type UnsafeSyncedDbSqlExecutor<Database> = SyncedDbSqlExecutor<Database>;\n\nexport type SyncedDbTransaction<Database> = SyncedDbSqlExecutor<Database> & {\n unsafe: UnsafeSyncedDbSqlExecutor<Database>;\n sql<TResult = unknown>(\n templateOrString: TemplateStringsArray | string,\n ...parameters: unknown[]\n ): ExecuteResult<TResult>;\n};\n\nexport type SyncedDbDatabase<Database> = SyncedDbSqlExecutor<Database> & {\n unsafe: UnsafeSyncedDbSqlExecutor<Database>;\n executeTransaction<TResult>(callback: (tx: SyncedDbTransaction<Database>) => TResult): TResult;\n createLiveQuery<TResult>(query: { sql: string; parameters: readonly unknown[] }): {\n getRows: () => TResult[];\n refresh: (parameters?: readonly unknown[]) => void;\n subscribe: (onchange: () => void) => () => void;\n };\n getSharedLiveQuery<TResult>(query: { sql: string; parameters: readonly unknown[] }): SharedLiveQuery<TResult>;\n};\n\nfunction createSqlExecutor<Database>(\n tx: Pick<SQLiteTransactionWrapper<Database>, \"execute\" | \"executeKysely\">,\n unsafe: boolean,\n): SyncedDbSqlExecutor<Database> {\n return {\n execute: (query) => tx.execute(query, unsafe ? { skipAfterMutatingStatement: true } : undefined),\n executeKysely: (factory) => tx.executeKysely(factory, unsafe ? { skipAfterMutatingStatement: true } : undefined),\n };\n}\n\n/** @internal Exported from this module for focused facade tests, but not from the package entry point. */\nexport function createSyncedDbDatabase<Database>(reactiveDb: SQLiteReactiveDb<Database>): SyncedDbDatabase<Database> {\n const safeExecutor = createSqlExecutor(reactiveDb.db, false);\n const unsafeExecutor = createSqlExecutor(reactiveDb.db, true);\n\n return {\n ...safeExecutor,\n unsafe: unsafeExecutor,\n executeTransaction: (callback) =>\n reactiveDb.db.executeTransaction((tx) => {\n const safeTransactionExecutor = createSqlExecutor(tx, false);\n const unsafeTransactionExecutor = createSqlExecutor(tx, true);\n return callback({\n ...safeTransactionExecutor,\n unsafe: unsafeTransactionExecutor,\n sql: tx.sql.bind(tx),\n });\n }),\n createLiveQuery: reactiveDb.createLiveQuery.bind(reactiveDb),\n getSharedLiveQuery: reactiveDb.getSharedLiveQuery.bind(reactiveDb),\n };\n}\n\nconst defaultLogger: Logger = (type, message, level = \"info\") => {\n const logMessage = `[${type}] ${message}`;\n switch (level) {\n case \"info\":\n console.log(logMessage);\n break;\n case \"warning\":\n console.warn(logMessage);\n break;\n case \"error\":\n console.error(logMessage);\n break;\n case \"trace\":\n console.trace(logMessage);\n break;\n }\n};\n\nexport async function createSyncedDb<Database, Props = undefined>(options: SyncedDbOptions<Database, Props>) {\n validateDbId(options.dbId);\n\n const perf = startPerformanceLogger(defaultLogger);\n\n const instanceId = generateId();\n const tabId = generateId();\n\n const broadcastChannels = createBroadcastChannels(options.dbId);\n\n const clientLockAcquired = createDeferredPromise<void>();\n const clientLockRelease = createDeferredPromise<void>();\n navigator.locks.request(`${syncDbClientLockName}-${options.dbId}`, { mode: \"shared\" }, () => {\n clientLockAcquired.resolve();\n return clientLockRelease.promise;\n });\n await clientLockAcquired.promise;\n\n const workerClient = await createWorkerDbClient({\n worker: options.worker,\n config: {\n clientId: generateId(),\n dbId: options.dbId,\n props: options.workerProps as never,\n },\n broadcastChannels,\n });\n\n const hlcCounter = new HLCCounter(tabId, () => Date.now());\n\n const workerClientSnapshot = await workerClient.getSnapshot();\n const reactiveDb = await createSQLiteReactiveDb<Database>({\n snapshot: workerClientSnapshot.file,\n logger: defaultLogger,\n });\n\n const memoryDbMigrator: SyncDbMigrator = {\n currentSchemaVersion: workerClientSnapshot.schemaVersion,\n latestSchemaVersion: workerClientSnapshot.schemaVersion,\n migrateDbToLatest: () => {\n throw new Error(\"Memory DB migrations are not implemented\");\n },\n migrateEvent: (event, targetVersion) => {\n if (event.schema_version === targetVersion) {\n return event;\n }\n throw new Error(\"Memory DB migrations are not implemented\");\n },\n migrateEvents: (events) => events,\n };\n const { crdtStorage } = await createMemoryDb({\n nodeId: tabId,\n migrator: memoryDbMigrator,\n reactiveDb: reactiveDb,\n hlcCounter,\n crdtTables: options.syncDbSchema.tablesConfig,\n syncDbSchema: options.syncDbSchema,\n });\n\n const pullSyncId = createStoredValue({\n initialValue: workerClientSnapshot.syncId,\n });\n const pushSyncId = createStoredValue({\n initialValue: 0,\n });\n const tabRemoteSource = createCrdtSyncRemoteSource({\n bufferSize: 500,\n pullSyncId,\n pushSyncId,\n storage: crdtStorage,\n nodeId: tabId,\n migrator: memoryDbMigrator,\n remoteFactory: ({ onEventsAvailable }) => {\n const subscription = workerClient.subscribe(\"new-event-chunk-applied\", (event) => {\n onEventsAvailable({ newSyncId: event.payload.newSyncId, remoteEventHlcSum: event.payload.eventHlcSum });\n });\n\n return {\n pullEvents: (request) => workerClient.pullEvents(request),\n pushEvents: (request) => workerClient.pushTabEvents(request),\n disconnect: () => {\n subscription.unsubscribe();\n },\n };\n },\n });\n tabRemoteSource.goOnline();\n\n const reloadRequestedSubscription = workerClient.subscribe(\"reload-requested\", () => {\n globalThis.location?.reload();\n });\n\n perf.logEnd(\"createSyncedDb\", \"initialized\", \"info\");\n\n const exportData = createExportData({\n reactiveDb,\n tablesConfig: options.syncDbSchema.tablesConfig,\n schemaVersion: workerClientSnapshot.schemaVersion,\n });\n const importData = (data: SyncedDbExport, opts?: ImportDataOptions) => workerClient.importData(data, opts);\n\n let isDisposed = false;\n let unregisterDevtools: (() => void) | undefined;\n const dispose = async () => {\n if (isDisposed) return;\n isDisposed = true;\n\n unregisterDevtools?.();\n reloadRequestedSubscription.unsubscribe();\n clientLockRelease.resolve();\n await tabRemoteSource.dispose();\n broadcastChannels.requests.close();\n broadcastChannels.responses.close();\n workerClient.dispose();\n reactiveDb.dispose();\n };\n\n const syncedDb = {\n db: createSyncedDbDatabase(reactiveDb),\n state: {\n getState: workerClient.getState.bind(workerClient),\n subscribe: (onChange: () => void) => {\n const { unsubscribe } = workerClient.subscribe(\"state-changed\", onChange);\n return unsubscribe;\n },\n goOnline: workerClient.goOnline.bind(workerClient),\n goOffline: workerClient.goOffline.bind(workerClient),\n },\n /**\n * Ask the elected worker to broadcast a page reload to all tabs for this dbId.\n *\n * With `clean: true` the worker durably records a reset request epoch before\n * broadcasting, so the worker elected on the next startup initializes with\n * `clearOnInit: true` and wipes the persisted DB. Destructive — use as a\n * recovery path when the durable worker DB may be de-synced.\n *\n * Pending in-memory tab events are not preserved, and the returned promise\n * may never settle in the caller — the page typically unloads first.\n */\n requestReload: async (options: { clean: boolean }) => {\n await workerClient.requestReload(options);\n // Primary path: this tab receives the worker's \"reload-requested\" broadcast\n // like every other tab. Fallback in case the broadcast is missed — in the\n // normal case the page is already unloading and this timeout never fires.\n setTimeout(() => globalThis.location?.reload(), 250);\n },\n subscribe: workerClient.subscribe,\n exportData,\n importData,\n dispose,\n _internal: {\n executeAsync: workerClient.execute.bind(workerClient),\n getMemoryQueryTables: reactiveDb.getTablesUsed.bind(reactiveDb),\n getSharedLiveQueriesSnapshot: reactiveDb.getSharedLiveQueriesSnapshot.bind(reactiveDb),\n crdtTableNames: options.syncDbSchema.tablesConfig.map((table) => table.crdtTableName),\n crdtTablesConfig: options.syncDbSchema.tablesConfig,\n schemaVersion: workerClientSnapshot.schemaVersion,\n migrationVersions: Object.keys(options.syncDbSchema.migrations)\n .map(Number)\n .sort((a, b) => a - b),\n },\n };\n\n unregisterDevtools = getOrCreateSQLiteSyncDevtoolsRegistry().register({\n instanceId,\n dbId: options.dbId,\n createdAt: Date.now(),\n instance: syncedDb,\n });\n\n return syncedDb;\n}\n\nexport type SyncedDb<Database> = Awaited<ReturnType<typeof createSyncedDb<Database>>>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/bound-map.ts","../src/memory-db/sqlite-reactive-db.ts","../src/schema/admit-client-events.ts","../src/schema/define-sync-schema.ts","../src/schema/table-builder.ts","../src/sqlite-crdt/crdt-storage-mutator.ts","../src/db-id.ts","../src/devtools-registry.ts","../src/memory-db/memory-db.ts","../src/worker-db/db-worker-client.ts","../src/sync-db.ts"],"sourcesContent":["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 sqlite3InitModule, { type Sqlite3Static } from \"@sqlite.org/sqlite-wasm\";\nimport { BoundMap } from \"../bound-map\";\nimport { type Logger, startPerformanceLogger } from \"../logger\";\nimport { type PreparedStatement, SQLiteDbWrapper } from \"../sqlite-db-wrapper\";\nimport { createTypedEventTarget, type TypedEvent } from \"../utils\";\n\nlet sqliteModule: Sqlite3Static | null = null;\n\ntype TableName<Database> = keyof Database extends string ? keyof Database : never;\n\ntype SQLiteReactiveDbOptions = {\n snapshot: Uint8Array<ArrayBufferLike>;\n logger: Logger;\n};\n\ntype EventsMap = {\n \"transaction-committed\": undefined;\n \"transaction-rolled-back\": undefined;\n \"any-table-changed\": undefined;\n} & Record<`table:${string}`, void>;\n\ntype LiveQuery<TResult> = {\n getRows: () => TResult[];\n refresh: () => void;\n subscribe: (onchange: () => void) => () => void;\n};\n\nexport type SharedLiveQuery<TResult> = LiveQuery<TResult> & {\n readonly sql: string;\n readonly parameters: readonly unknown[];\n getSubscriberCount: () => number;\n};\n\ntype SharedLiveQueryEntry<TResult> = SharedLiveQuery<TResult> & {\n listeners: Set<() => void>;\n unsubscribeFromLiveQuery: (() => void) | null;\n cleanupTimeout: ReturnType<typeof setTimeout> | null;\n};\n\nexport type SharedLiveQuerySnapshot = {\n sql: string;\n parameters: readonly unknown[];\n subscriberCount: number;\n};\n\nexport function createSQLiteReactiveDb<Database>(opts: SQLiteReactiveDbOptions) {\n return SQLiteReactiveDb.create<Database>(opts);\n}\n\nexport class SQLiteReactiveDb<Database> {\n readonly db: SQLiteDbWrapper<Database>;\n private sqlite3: Sqlite3Static;\n\n private readonly logger: Logger;\n\n private tablesUsedStatement: PreparedStatement<[string], { name: string; isWrite: boolean }> | null = null;\n\n private eventTarget = createTypedEventTarget<EventsMap>();\n private mutationVersion = 0;\n private tableMutationVersions = new Map<string, number>();\n\n private constructor(sqlite3: Sqlite3Static, logger: Logger) {\n this.sqlite3 = sqlite3;\n this.logger = logger;\n\n this.db = new SQLiteDbWrapper({\n db: () => new sqlite3.oo1.DB({ filename: \":memory:\" }),\n logger: this.logger,\n loggerPrefix: \"memory\",\n sqlite3,\n });\n }\n\n static async create<Database>(opts: SQLiteReactiveDbOptions) {\n const logger = opts.logger;\n const perf = startPerformanceLogger(logger, \"system\");\n if (!sqliteModule) {\n sqliteModule = await sqlite3InitModule();\n }\n\n const db = new SQLiteReactiveDb<Database>(sqliteModule, logger);\n\n if (opts.snapshot) {\n db.useSnapshot(opts.snapshot);\n }\n db.registerDbHooks();\n\n perf.logEnd(\"createSQLiteMemoryDb\", \"success\", \"system\");\n\n return db;\n }\n\n private liveQueryStatements = new BoundMap<string, PreparedStatement<any[], unknown>>({\n maxSize: 100,\n onRemove(_, value) {\n value.finalize();\n },\n });\n\n private sharedLiveQueries = new Map<string, SharedLiveQueryEntry<unknown>[]>();\n\n createLiveQuery<TResult>(query: { sql: string; parameters: readonly unknown[] }) {\n const fetchRows = (parameters: readonly unknown[]) => {\n let statement = this.liveQueryStatements.get(query.sql);\n if (!statement) {\n statement = this.db.prepare<any[], any>(query.sql);\n this.liveQueryStatements.set(query.sql, statement);\n }\n return statement.execute(parameters as any) as TResult[];\n };\n\n let rows: TResult[] | null = null;\n\n const getRows = () => {\n if (!rows) {\n rows = fetchRows(query.parameters);\n }\n return rows;\n };\n\n let subscriber: (() => void) | null = null;\n\n let lastParameters: readonly unknown[] = query.parameters;\n const refresh = (parameters?: readonly unknown[]) => {\n if (parameters) {\n lastParameters = parameters;\n }\n rows = fetchRows(lastParameters);\n subscriber?.();\n };\n\n const subscribe = (onchange: () => void) => {\n if (subscriber) {\n throw new Error(\"Subscriber already exists\");\n }\n\n subscriber = onchange;\n const subscription = this.subscribeToQueryChanges({\n sql: query.sql,\n onDataChange: refresh,\n });\n\n return () => {\n subscription.unsubscribe();\n subscriber = null;\n };\n };\n\n return { getRows, refresh, subscribe };\n }\n\n getSharedLiveQuery<TResult>(query: { sql: string; parameters: readonly unknown[] }) {\n const existingEntry = this.sharedLiveQueries\n .get(query.sql)\n ?.find((entry) => parametersAreEqual(entry.parameters, query.parameters));\n if (existingEntry) {\n if (existingEntry.listeners.size === 0) {\n this.scheduleSharedLiveQueryCleanup(existingEntry);\n }\n return existingEntry as SharedLiveQuery<TResult>;\n }\n\n const liveQuery = this.createLiveQuery<TResult>(query);\n let hasDetachedFromLiveQuery = false;\n const entry: SharedLiveQueryEntry<TResult> = {\n sql: query.sql,\n parameters: query.parameters,\n listeners: new Set(),\n unsubscribeFromLiveQuery: null,\n cleanupTimeout: null,\n getRows: () => liveQuery.getRows(),\n refresh: () => {\n liveQuery.refresh();\n },\n getSubscriberCount: () => entry.listeners.size,\n subscribe: (onchange) => {\n this.cancelSharedLiveQueryCleanup(entry);\n this.registerSharedLiveQueryEntry(entry as SharedLiveQueryEntry<unknown>);\n entry.listeners.add(onchange);\n\n if (!entry.unsubscribeFromLiveQuery) {\n entry.unsubscribeFromLiveQuery = liveQuery.subscribe(() => {\n for (const listener of entry.listeners) {\n listener();\n }\n });\n\n // Rows may have gone stale while no subscriber was listening\n // for table changes.\n if (hasDetachedFromLiveQuery) {\n hasDetachedFromLiveQuery = false;\n liveQuery.refresh();\n }\n }\n\n return () => {\n entry.listeners.delete(onchange);\n\n if (entry.listeners.size === 0) {\n entry.unsubscribeFromLiveQuery?.();\n entry.unsubscribeFromLiveQuery = null;\n hasDetachedFromLiveQuery = true;\n this.scheduleSharedLiveQueryCleanup(entry);\n }\n };\n },\n };\n\n this.registerSharedLiveQueryEntry(entry as SharedLiveQueryEntry<unknown>);\n\n // Evict the entry if no subscriber attaches by the next tick.\n this.scheduleSharedLiveQueryCleanup(entry as SharedLiveQueryEntry<unknown>);\n\n return entry;\n }\n\n private registerSharedLiveQueryEntry(entry: SharedLiveQueryEntry<unknown>) {\n const matchingSqlEntries = this.sharedLiveQueries.get(entry.sql) ?? [];\n if (!matchingSqlEntries.includes(entry)) {\n matchingSqlEntries.push(entry);\n this.sharedLiveQueries.set(entry.sql, matchingSqlEntries);\n }\n }\n\n getSharedLiveQueriesSnapshot(): SharedLiveQuerySnapshot[] {\n const snapshot: SharedLiveQuerySnapshot[] = [];\n for (const entries of this.sharedLiveQueries.values()) {\n for (const entry of entries) {\n snapshot.push({\n sql: entry.sql,\n parameters: entry.parameters,\n subscriberCount: entry.listeners.size,\n });\n }\n }\n return snapshot;\n }\n\n private scheduleSharedLiveQueryCleanup(entry: SharedLiveQueryEntry<unknown>) {\n this.cancelSharedLiveQueryCleanup(entry);\n entry.cleanupTimeout = setTimeout(() => {\n entry.cleanupTimeout = null;\n this.releaseSharedLiveQuery(entry);\n }, 0);\n }\n\n private cancelSharedLiveQueryCleanup(entry: SharedLiveQueryEntry<unknown>) {\n if (entry.cleanupTimeout) {\n clearTimeout(entry.cleanupTimeout);\n entry.cleanupTimeout = null;\n }\n }\n\n private releaseSharedLiveQuery(entry: SharedLiveQueryEntry<unknown>) {\n if (entry.listeners.size > 0 || entry.unsubscribeFromLiveQuery) {\n return;\n }\n\n const matchingSqlEntries = this.sharedLiveQueries.get(entry.sql);\n if (!matchingSqlEntries) {\n return;\n }\n\n const nextEntries = matchingSqlEntries.filter((candidate) => candidate !== entry);\n if (nextEntries.length > 0) {\n this.sharedLiveQueries.set(entry.sql, nextEntries);\n } else {\n this.sharedLiveQueries.delete(entry.sql);\n }\n }\n\n subscribeToQueryChanges(params: { sql: string; onDataChange: () => void }) {\n const { sql, onDataChange } = params;\n\n const tables = this.getTablesUsed(sql);\n const readTables = new Set<string>();\n for (const table of tables) {\n if (!readTables.has(table.name)) {\n readTables.add(table.name);\n } else if (table.isWrite) {\n throw new Error(\"This query writes and reads from the same table. This may cause infinite loops.\");\n }\n }\n\n const notifyDataChange = createDebouncedCallback(() => {\n onDataChange();\n }, 30);\n\n for (const table of readTables) {\n this.eventTarget.addEventListener(`table:${table}`, notifyDataChange);\n }\n this.eventTarget.addEventListener(\"any-table-changed\", notifyDataChange);\n\n return {\n unsubscribe: () => {\n for (const table of readTables) {\n this.eventTarget.removeEventListener(`table:${table}`, notifyDataChange);\n }\n this.eventTarget.removeEventListener(\"any-table-changed\", notifyDataChange);\n },\n };\n }\n\n subscribeToTableChanges(table: string, onChanges: () => void) {\n this.eventTarget.addEventListener(`table:${table}`, onChanges);\n this.eventTarget.addEventListener(\"any-table-changed\", onChanges);\n return {\n unsubscribe: () => {\n this.eventTarget.removeEventListener(`table:${table}`, onChanges);\n this.eventTarget.removeEventListener(\"any-table-changed\", onChanges);\n },\n };\n }\n\n getTablesUsed(query: string) {\n if (!this.tablesUsedStatement) {\n this.tablesUsedStatement = this.db.prepare<[string], { name: string; isWrite: boolean }>(\n \"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'\",\n { loggerLevel: \"system\" },\n );\n }\n\n const tables = this.tablesUsedStatement.execute([query]);\n\n if (tables.length === 0 && query.toLowerCase().includes(\"delete\")) {\n // tables_used function does not work with delete queries that clear entire tables\n tables.push(...this.getClearedTables(query));\n }\n\n return tables;\n }\n\n private getClearedTables(query: string) {\n const operations = this.db.execute<{\n opcode: string;\n p1: number;\n p2: number;\n }>(`EXPLAIN ${query.split(\";\")[0]}`, { loggerLevel: \"system\" }).rows;\n\n const clearedTablesRootPages = new Set<number>();\n for (const operation of operations) {\n if (operation.opcode === \"Clear\" && operation.p2 === 0) {\n clearedTablesRootPages.add(operation.p1);\n }\n }\n\n if (clearedTablesRootPages.size === 0) {\n return [];\n }\n\n const tableNames = this.db.execute<{ name: string; isWrite: boolean }>(\n `select t.tbl_name as name, true as isWrite from sqlite_master as t where t.rootpage in (${Array.from(\n clearedTablesRootPages,\n ).join(\",\")})`,\n { loggerLevel: \"system\" },\n ).rows;\n\n return tableNames;\n }\n\n addEventListener<K extends keyof EventsMap>(type: K, listener: (event: TypedEvent<EventsMap[K]>) => void) {\n this.eventTarget.addEventListener(type, listener);\n }\n\n removeEventListener<K extends keyof EventsMap>(type: K, listener: (event: TypedEvent<EventsMap[K]>) => void) {\n this.eventTarget.removeEventListener(type, listener);\n }\n\n getTableMutationVersion(table: string) {\n return this.tableMutationVersions.get(table) ?? 0;\n }\n\n private notifyTableSubscribers(tables: (TableName<Database> | (string & {}))[] | Set<string> | null = null) {\n if (!tables) {\n this.eventTarget.dispatchEvent(\"any-table-changed\", undefined);\n return;\n }\n\n for (const table of tables) {\n this.eventTarget.dispatchEvent(`table:${table}`, undefined);\n }\n }\n\n private registerDbHooks() {\n let updateQueue = new Set<string>();\n\n this.sqlite3.capi.sqlite3_update_hook(\n this.db.ensureDb,\n (_ctx, _opId, _db, table) => {\n updateQueue.add(table);\n this.tableMutationVersions.set(table, ++this.mutationVersion);\n },\n 0,\n );\n\n this.sqlite3.capi.sqlite3_rollback_hook(\n this.db.ensureDb,\n () => {\n if (updateQueue.size === 0) {\n return 0;\n }\n\n updateQueue.clear();\n this.eventTarget.dispatchEvent(\"transaction-rolled-back\", undefined);\n\n return 0;\n },\n 0,\n );\n\n this.sqlite3.capi.sqlite3_commit_hook(\n this.db.ensureDb,\n () => {\n if (updateQueue.size === 0) {\n return 0;\n }\n\n const tables = updateQueue;\n updateQueue = new Set<string>();\n this.eventTarget.dispatchEvent(\"transaction-committed\", undefined);\n\n queueMicrotask(() => {\n this.notifyTableSubscribers(tables);\n });\n return 0;\n },\n 0,\n );\n }\n\n createSnapshot() {\n const perf = startPerformanceLogger(this.logger);\n const snapshot = this.sqlite3.capi.sqlite3_js_db_export(this.db.ensureDb);\n perf.logEnd(\"createSnapshot\", `snapshot size: ${snapshot.byteLength}`, \"info\");\n\n return snapshot;\n }\n\n useSnapshot(snapshot: Uint8Array<ArrayBufferLike>) {\n this.db.useSnapshot(snapshot);\n this.notifyTableSubscribers();\n }\n\n dispose() {\n for (const entries of this.sharedLiveQueries.values()) {\n for (const entry of entries) {\n this.cancelSharedLiveQueryCleanup(entry);\n entry.unsubscribeFromLiveQuery?.();\n entry.unsubscribeFromLiveQuery = null;\n entry.listeners.clear();\n }\n }\n this.sharedLiveQueries.clear();\n this.liveQueryStatements.clear();\n if (this.tablesUsedStatement) {\n this.tablesUsedStatement.finalize();\n this.tablesUsedStatement = null;\n }\n this.db.close();\n }\n}\n\nfunction createDebouncedCallback<TArgs extends unknown[]>(callback: (...args: TArgs) => void, delay: number) {\n let timeout: unknown | null = null;\n let shouldCallWithoutDelay = true;\n\n return (...args: TArgs) => {\n if (shouldCallWithoutDelay) {\n callback(...args);\n shouldCallWithoutDelay = false;\n return;\n }\n\n const effect = () => {\n timeout = null;\n shouldCallWithoutDelay = true;\n return callback(...args);\n };\n\n if (timeout) {\n clearTimeout(timeout as any);\n }\n\n timeout = setTimeout(effect, delay);\n };\n}\n\nexport function parametersAreEqual(a: readonly unknown[] | undefined, b: readonly unknown[] | undefined): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) {\n return false;\n }\n }\n return true;\n}\n","import type { SyncDbSchema } from \"../sqlite-crdt/crdt-schema\";\nimport type { WriteOrigin } from \"./table-builder\";\n\nexport type AdmitClientEventsResult<T> = {\n admitted: T[];\n skipped: T[];\n};\n\ntype SchemaForAdmitClientEvents = Pick<SyncDbSchema, \"tables\" | \"tablesConfig\"> & {\n writeOriginByName?: ReadonlyMap<string, WriteOrigin>;\n};\n\nexport function buildWriteOriginByName(\n schema: Pick<SyncDbSchema, \"tables\" | \"tablesConfig\">,\n): Map<string, WriteOrigin> {\n const writeOriginByName = new Map<string, WriteOrigin>();\n for (const { crdtTableName, baseTableName } of schema.tablesConfig) {\n const writeOrigin = schema.tables[crdtTableName]?.writeOrigin ?? \"any\";\n writeOriginByName.set(crdtTableName, writeOrigin);\n writeOriginByName.set(baseTableName, writeOrigin);\n }\n return writeOriginByName;\n}\n\n/**\n * Splits a client push into events the hub should persist and events for tables with\n * `{ writes: \"server\" }`. Unknown datasets stay admitted. Matches either the crdt or the base\n * table name.\n */\nexport function admitClientEvents<T extends { dataset: string }>(opts: {\n syncDbSchema: SchemaForAdmitClientEvents;\n events: readonly T[];\n}): AdmitClientEventsResult<T> {\n const writeOriginByName = opts.syncDbSchema.writeOriginByName ?? buildWriteOriginByName(opts.syncDbSchema);\n\n const admitted: T[] = [];\n const skipped: T[] = [];\n for (const event of opts.events) {\n if (writeOriginByName.get(event.dataset) === \"server\") {\n skipped.push(event);\n } else {\n admitted.push(event);\n }\n }\n return { admitted, skipped };\n}\n","import type { Migrations } from \"../migrations/migrator\";\nimport type { CrdtTableConfig, ReadonlyTable, SyncDbSchema } from \"../sqlite-crdt/crdt-schema\";\nimport { buildWriteOriginByName } from \"./admit-client-events\";\nimport type {\n AnyTableBuilder,\n InferRow,\n SyncSchemaTables,\n TableBuilder,\n TableColumns,\n WriteOrigin,\n} from \"./table-builder\";\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\n// Names sqlite-sync uses for its own tables/views, so a user schema can't shadow them.\nconst RESERVED_TABLE_NAMES = new Set<string>([\n \"change_history\",\n \"crdt_events\",\n \"worker.crdt_events\",\n \"persisted_crdt_events\",\n \"crdt_update_log\",\n \"crdt_change_intents\",\n \"worker.kv\",\n]);\n\ntype RowOf<Table extends AnyTableBuilder> =\n Table extends TableBuilder<infer Cols extends TableColumns, any, WriteOrigin> ? InferRow<Cols> : never;\n\n// Falls back to the \"_\" convention unless ~baseName is a string *literal* — inference can\n// resolve an omitted override to its constraint (string | undefined) rather than undefined.\ntype BaseNameOf<CrdtName, Table extends AnyTableBuilder> = string extends Table[\"~baseName\"]\n ? `_${CrdtName & string}`\n : [Table[\"~baseName\"]] extends [string]\n ? Table[\"~baseName\"]\n : `_${CrdtName & string}`;\n\ntype ClientSchemaOf<Tables extends SyncSchemaTables> = Simplify<\n {\n [K in keyof Tables]: Tables[K][\"~writeOrigin\"] extends \"server\"\n ? ReadonlyTable<RowOf<Tables[K]>>\n : RowOf<Tables[K]>;\n } & {\n [K in keyof Tables as BaseNameOf<K, Tables[K]>]: ReadonlyTable<RowOf<Tables[K]>>;\n }\n>;\n\ntype ServerSchemaOf<Tables extends SyncSchemaTables> = Simplify<\n { [K in keyof Tables]: RowOf<Tables[K]> } & {\n [K in keyof Tables as BaseNameOf<K, Tables[K]>]: ReadonlyTable<RowOf<Tables[K]>>;\n }\n>;\n\ntype MutationsSchemaOf<Tables extends SyncSchemaTables> = Simplify<{\n [K in keyof Tables as BaseNameOf<K, Tables[K]>]: RowOf<Tables[K]>;\n}>;\n\nexport interface DefinedSyncSchema<Tables extends SyncSchemaTables>\n extends SyncDbSchema<ClientSchemaOf<Tables>, ServerSchemaOf<Tables>, MutationsSchemaOf<Tables>> {\n /** The table builders, for type extraction (`typeof schema.tables.item.$row`) and runtime metadata. */\n tables: Tables;\n /** Write origin keyed by crdt and base table name. */\n writeOriginByName: ReadonlyMap<string, WriteOrigin>;\n}\n\nexport type DefineSyncSchemaConfig<Tables extends SyncSchemaTables> = {\n tables: Tables;\n /** Full migration history (including the initial createTable version), built with `createMigrations`. */\n migrations: Migrations;\n};\n\n/**\n * Define a sync database schema from `t.table()` builders.\n *\n * Record keys are the crdt (view) table names; base table names default to the key\n * prefixed with \"_\", overridable per table via `t.table(cols, { baseName })`.\n */\nexport function defineSyncSchema<Tables extends SyncSchemaTables>({\n tables,\n migrations,\n}: DefineSyncSchemaConfig<Tables>): DefinedSyncSchema<Tables> {\n const tablesConfig: CrdtTableConfig[] = Object.entries(tables).map(([crdtTableName, table]) => ({\n crdtTableName,\n baseTableName: table.baseName ?? `_${crdtTableName}`,\n ...(table.exportImport === \"ignore\" ? { exportImport: \"ignore\" } : {}),\n }));\n\n const seenNames = new Set<string>();\n for (const { crdtTableName, baseTableName } of tablesConfig) {\n for (const name of [crdtTableName, baseTableName]) {\n const normalizedName = name.toLowerCase();\n if (RESERVED_TABLE_NAMES.has(normalizedName)) {\n throw new Error(`Table name \"${name}\" is reserved by sqlite-sync and cannot be used in a sync schema`);\n }\n if (seenNames.has(normalizedName)) {\n throw new Error(`Duplicate table name \"${name}\" in sync schema`);\n }\n seenNames.add(normalizedName);\n }\n }\n\n const writeOriginByName = buildWriteOriginByName({ tables, tablesConfig });\n\n return {\n tables,\n get tablesConfig() {\n return tablesConfig;\n },\n get writeOriginByName() {\n return writeOriginByName;\n },\n get migrations() {\n return migrations;\n },\n get \"~clientSchema\"(): never {\n throw new Error(\"~clientSchema is type-only and cannot be accessed at runtime\");\n },\n get \"~serverSchema\"(): never {\n throw new Error(\"~serverSchema is type-only and cannot be accessed at runtime\");\n },\n get \"~mutationsSchema\"(): never {\n throw new Error(\"~mutationsSchema is type-only and cannot be accessed at runtime\");\n },\n };\n}\n","export type ColumnKind = \"text\" | \"integer\" | \"real\" | \"boolean\" | \"enum\";\n\nexport type SqliteStorageType = \"text\" | \"integer\" | \"real\";\n\n/**\n * What `@sqlite-sync/ai` may do with a table.\n * `read-only`: documented and queryable; mutations rejected.\n * `hidden`: omitted from the schema doc; reads rejected.\n */\nexport type AiAccess = \"read-write\" | \"read-only\" | \"hidden\";\n\n/**\n * Who may author CRDT events for a table.\n * `\"any\"` (default): every replica. `\"server\"`: client pushes drop these events.\n */\nexport type WriteOrigin = \"any\" | \"server\";\n\n/** Whether backup and restore include a table. */\nexport type ExportImportMode = \"include\" | \"ignore\";\n\nexport type ColumnMeta = {\n kind: ColumnKind;\n /** Storage type used in generated DDL. Booleans store as integer 0/1. */\n sqlType: SqliteStorageType;\n nullable: boolean;\n hasDefault: boolean;\n /** Declared default in JS form (booleans as booleans). */\n defaultValue?: unknown;\n /** Allowed values for `enum` columns. */\n enumValues?: readonly string[];\n description?: string;\n};\n\nexport class ColumnBuilder<Value, HasDefault extends boolean = false> {\n declare readonly \"~types\": { value: Value; hasDefault: HasDefault };\n\n constructor(readonly meta: ColumnMeta) {}\n\n /** Allow SQL NULL; widens the value type with `null`. */\n nullable(): ColumnBuilder<Value | null, HasDefault> {\n return new ColumnBuilder({ ...this.meta, nullable: true });\n }\n\n /** Declare a column default. The value is used both in DDL and when migrating older events. */\n default(value: Value): ColumnBuilder<Value, true> {\n return new ColumnBuilder({ ...this.meta, hasDefault: true, defaultValue: value });\n }\n\n /** Narrow the TypeScript value type without changing storage, e.g. `t.text().$type<\"movie\" | \"tv\">()`. */\n $type<Narrowed extends Value>(): ColumnBuilder<Narrowed, HasDefault> {\n return this as unknown as ColumnBuilder<Narrowed, HasDefault>;\n }\n\n /** Human/AI-readable description, surfaced in generated schema docs. */\n describe(description: string): ColumnBuilder<Value, HasDefault> {\n return new ColumnBuilder({ ...this.meta, description });\n }\n}\n\nexport type AnyColumnBuilder = ColumnBuilder<any, boolean>;\n\nexport type TableColumns = Record<string, AnyColumnBuilder>;\n\nexport type AnyTableBuilder = TableBuilder<any, any, WriteOrigin>;\n\nexport type SyncSchemaTables = Record<string, AnyTableBuilder>;\n\nexport type TableOptions<\n BaseName extends string | undefined = string | undefined,\n Writes extends WriteOrigin = \"any\",\n> = {\n /** Override the materialized base table name (defaults to the crdt table name prefixed with \"_\"). */\n baseName?: BaseName;\n description?: string;\n /** Defaults to `\"read-write\"`. See {@link AiAccess}. */\n ai?: AiAccess;\n /** Defaults to `\"any\"`. See {@link WriteOrigin}. */\n writes?: Writes;\n /** Defaults to `\"include\"`. Ignored tables are omitted from export and skipped on import. */\n exportImport?: ExportImportMode;\n};\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\ntype ColumnValue<Column> = Column extends ColumnBuilder<infer Value, boolean> ? Value : never;\n\nexport type InferRow<Cols extends TableColumns> = Simplify<\n { id: string } & { [K in keyof Cols]: ColumnValue<Cols[K]> } & { tombstone?: boolean }\n>;\n\nexport type PayloadValidationResult = { success: true } | { success: false; errors: string[] };\n\nconst RESERVED_COLUMNS = [\"id\", \"tombstone\"] as const;\n\nconst idColumnMeta: ColumnMeta = {\n kind: \"text\",\n sqlType: \"text\",\n nullable: false,\n hasDefault: false,\n description: \"Unique immutable item id\",\n};\n\nconst tombstoneColumnMeta: ColumnMeta = {\n kind: \"boolean\",\n sqlType: \"integer\",\n nullable: false,\n hasDefault: true,\n defaultValue: false,\n description: \"Soft-delete marker\",\n};\n\nexport class TableBuilder<\n Cols extends TableColumns,\n BaseName extends string | undefined = undefined,\n Writes extends WriteOrigin = \"any\",\n> {\n declare readonly \"~baseName\": BaseName;\n declare readonly \"~writeOrigin\": Writes;\n\n /** All columns in DDL order, including the auto-injected `id` and `tombstone`. */\n readonly columns: Record<string, ColumnMeta>;\n readonly baseName: BaseName;\n readonly description: string | undefined;\n /** Resolved {@link AiAccess}; defaults to `\"read-write\"`. */\n readonly aiAccess: AiAccess;\n /** Resolved {@link WriteOrigin}; defaults to `\"any\"`. */\n readonly writeOrigin: Writes;\n /** Resolved {@link ExportImportMode}; defaults to `\"include\"`. */\n readonly exportImport: ExportImportMode;\n\n constructor(\n readonly userColumns: Cols,\n options?: TableOptions<BaseName, Writes>,\n ) {\n for (const reserved of RESERVED_COLUMNS) {\n if (reserved in userColumns) {\n throw new Error(`Column \"${reserved}\" is added automatically to every synced table and cannot be declared`);\n }\n }\n\n this.columns = {\n id: idColumnMeta,\n ...Object.fromEntries(Object.entries(userColumns).map(([name, column]) => [name, column.meta])),\n tombstone: tombstoneColumnMeta,\n };\n this.baseName = options?.baseName as BaseName;\n this.description = options?.description;\n this.aiAccess = options?.ai ?? \"read-write\";\n this.writeOrigin = (options?.writes ?? \"any\") as Writes;\n this.exportImport = options?.exportImport ?? \"include\";\n }\n\n describe(description: string): TableBuilder<Cols, BaseName, Writes> {\n return new TableBuilder<Cols, BaseName, Writes>(this.userColumns, {\n baseName: this.baseName,\n description,\n ai: this.aiAccess,\n writes: this.writeOrigin,\n exportImport: this.exportImport,\n });\n }\n\n /** Type-only: the row shape returned by queries. Do not access at runtime. */\n get $row(): InferRow<Cols> {\n return null as never;\n }\n\n /**\n * Validate a CRDT event payload against the declared columns.\n * `item-created` payloads must contain every column without a default (nullable columns may be omitted);\n * `item-updated` payloads are partial and must not touch `id` or set `tombstone` to a deleted value.\n */\n validatePayload(\n payload: Record<string, unknown>,\n options?: { event?: \"item-created\" | \"item-updated\" },\n ): PayloadValidationResult {\n const event = options?.event ?? \"item-created\";\n const errors: string[] = [];\n\n for (const key of Object.keys(payload)) {\n if (!(key in this.columns)) {\n errors.push(`Unknown column \"${key}\"`);\n }\n }\n\n if (event === \"item-updated\") {\n if (\"id\" in payload) {\n errors.push(`Column \"id\" is immutable and cannot appear in an update payload`);\n }\n if (payload.tombstone === true || payload.tombstone === 1) {\n errors.push(`Column \"tombstone\" cannot be set to true/1 in an update payload; use an item-deleted event`);\n }\n }\n\n if (event === \"item-created\") {\n for (const [name, meta] of Object.entries(this.columns)) {\n if (name in payload || name === \"tombstone\" || meta.nullable || meta.hasDefault) {\n continue;\n }\n errors.push(`Missing required column \"${name}\"`);\n }\n }\n\n for (const [name, value] of Object.entries(payload)) {\n const meta = this.columns[name];\n if (!meta || (event === \"item-updated\" && name === \"id\")) {\n continue;\n }\n const error = validateValue(name, value, meta);\n if (error) {\n errors.push(error);\n }\n }\n\n return errors.length === 0 ? { success: true } : { success: false, errors };\n }\n}\n\nfunction describeValue(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n return typeof value;\n}\n\nfunction validateValue(name: string, value: unknown, meta: ColumnMeta): string | null {\n if (value === null) {\n return meta.nullable ? null : `Column \"${name}\" is not nullable, got null`;\n }\n\n switch (meta.kind) {\n case \"text\":\n return typeof value === \"string\" ? null : `Column \"${name}\" expects text, got ${describeValue(value)}`;\n case \"integer\":\n return typeof value === \"number\" && Number.isInteger(value)\n ? null\n : `Column \"${name}\" expects an integer, got ${describeValue(value)}`;\n case \"real\":\n return typeof value === \"number\" && Number.isFinite(value)\n ? null\n : `Column \"${name}\" expects a number, got ${describeValue(value)}`;\n case \"boolean\":\n return typeof value === \"boolean\" || value === 0 || value === 1\n ? null\n : `Column \"${name}\" expects a boolean (true/false or 0/1), got ${describeValue(value)}`;\n case \"enum\": {\n if (typeof value !== \"string\") {\n return `Column \"${name}\" expects one of ${formatEnumValues(meta)}, got ${describeValue(value)}`;\n }\n return meta.enumValues?.includes(value)\n ? null\n : `Column \"${name}\" expects one of ${formatEnumValues(meta)}, got \"${value}\"`;\n }\n }\n}\n\nfunction formatEnumValues(meta: ColumnMeta): string {\n return (meta.enumValues ?? []).map((value) => `\"${value}\"`).join(\" | \");\n}\n\nfunction column<Value>(kind: ColumnKind, sqlType: SqliteStorageType): ColumnBuilder<Value> {\n return new ColumnBuilder<Value>({ kind, sqlType, nullable: false, hasDefault: false });\n}\n\nexport const t = {\n text: () => column<string>(\"text\", \"text\"),\n integer: () => column<number>(\"integer\", \"integer\"),\n real: () => column<number>(\"real\", \"real\"),\n /** Stored as INTEGER 0/1; always bind booleans as 0/1 when writing raw SQL. */\n boolean: () => column<boolean>(\"boolean\", \"integer\"),\n /**\n * Union of string literals stored as TEXT, e.g. `t.enum([\"movie\", \"tv\"])`. Unlike `$type`, the\n * allowed values are kept as runtime metadata, so payloads are validated against them.\n * For an open-ended set, use `t.text().$type<\"idle\" | (string & {})>()` instead.\n */\n enum: <const Values extends readonly [string, ...string[]]>(values: Values) =>\n new ColumnBuilder<Values[number]>({\n kind: \"enum\",\n sqlType: \"text\",\n nullable: false,\n hasDefault: false,\n enumValues: values,\n }),\n table: <\n Cols extends TableColumns,\n const BaseName extends string | undefined = undefined,\n const Writes extends WriteOrigin = \"any\",\n >(\n columns: Cols,\n options?: TableOptions<BaseName, Writes>,\n ) => new TableBuilder(columns, options),\n};\n","import type { CrdtStorage, OwnCrdtEvent } from \"./crdt-storage\";\n\nexport type CrdtStorageMutator<Database> = ReturnType<typeof createCrdtStorageMutator<Database>>;\n\ntype CommitEventOptions<Database, Table extends keyof Database & string> =\n | {\n type: \"item-created\";\n dataset: Table;\n item_id: string;\n payload: CreateEventPayload<Database, Table>;\n }\n | {\n type: \"item-updated\";\n dataset: Table;\n item_id: string;\n payload: UpdateEventPayload<Database, Table>;\n }\n | {\n type: \"item-deleted\";\n dataset: Table;\n item_id: string;\n };\n\ntype CreateEventPayload<Database, Table extends keyof Database> = Omit<Database[Table], \"tombstone\">;\ntype UpdateEventPayload<Database, Table extends keyof Database> = Omit<Partial<Database[Table]>, \"id\" | \"tombstone\">;\n\nexport type SnapshotOptions<Database, Table extends keyof Database & string> = {\n dataset: Table;\n id: string;\n patch: UpdateEventPayload<Database, Table>;\n};\n\nexport function createCrdtStorageMutator<Database>({ storage }: { storage: CrdtStorage }) {\n const mapToStorageEvent = (event: CommitEventOptions<Database, keyof Database & string>): OwnCrdtEvent => {\n switch (event.type) {\n case \"item-created\":\n return {\n type: \"item-created\",\n dataset: event.dataset,\n item_id: event.item_id,\n payload: JSON.stringify(event.payload),\n };\n case \"item-updated\":\n return {\n type: \"item-updated\",\n dataset: event.dataset,\n item_id: event.item_id,\n payload: JSON.stringify(event.payload),\n };\n case \"item-deleted\":\n return {\n type: \"item-deleted\",\n dataset: event.dataset,\n item_id: event.item_id,\n payload: \"{}\",\n };\n }\n };\n\n const enqueueEvents = (events: CommitEventOptions<Database, keyof Database & string>[]) => {\n storage.enqueueOwnEvents(events.map(mapToStorageEvent));\n };\n\n const createEvent = <Table extends keyof Database & string>(event: CommitEventOptions<Database, Table>) => {\n return event;\n };\n\n const enqueueEvent = (event: CommitEventOptions<Database, keyof Database & string>) => {\n storage.enqueueOwnEvents([mapToStorageEvent(event)]);\n };\n\n const enqueueSnapshot = <Table extends keyof Database & string>(snapshot: SnapshotOptions<Database, Table>) => {\n storage.applyOwnSnapshot({\n dataset: snapshot.dataset,\n item_id: snapshot.id,\n patch: { ...snapshot.patch },\n });\n };\n\n return {\n enqueueEvents,\n createEvent,\n enqueueEvent,\n enqueueSnapshot,\n };\n}\n","const dbIdRegex = /^[a-zA-Z][a-zA-Z\\-0-9]{2,63}$/;\n\nexport function validateDbId(dbId: string) {\n if (!dbIdRegex.test(dbId)) {\n throw new Error(\"Invalid dbId. Must be between 3 and 64 characters long and start with a letter.\");\n }\n}\n","import type { SyncedDb } from \"./sync-db\";\n\nconst devtoolsRegistrySymbol = Symbol.for(\"@sqlite-sync/devtools\");\n\nexport type SQLiteSyncDevtoolsInstance = {\n instanceId: string;\n dbId: string;\n createdAt: number;\n instance: SyncedDb<any>;\n};\n\nexport type SQLiteSyncDevtoolsSnapshot = {\n instances: readonly SQLiteSyncDevtoolsInstance[];\n};\n\nexport type SQLiteSyncDevtoolsRegistry = {\n version: 1;\n instances: Map<string, SQLiteSyncDevtoolsInstance>;\n subscribe(listener: () => void): () => void;\n getSnapshot(): SQLiteSyncDevtoolsSnapshot;\n register(instance: SQLiteSyncDevtoolsInstance): () => void;\n};\n\ntype RegistryGlobal = typeof globalThis & {\n [key: symbol]: SQLiteSyncDevtoolsRegistry | undefined;\n};\n\nfunction createSQLiteSyncDevtoolsRegistry(): SQLiteSyncDevtoolsRegistry {\n const instances = new Map<string, SQLiteSyncDevtoolsInstance>();\n const listeners = new Set<() => void>();\n let snapshot: SQLiteSyncDevtoolsSnapshot = {\n instances: [],\n };\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n const updateSnapshot = () => {\n snapshot = {\n instances: Array.from(instances.values()),\n };\n notify();\n };\n\n return {\n version: 1,\n instances,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n getSnapshot() {\n return snapshot;\n },\n register(instance) {\n instances.set(instance.instanceId, instance);\n updateSnapshot();\n\n let isUnregistered = false;\n return () => {\n if (isUnregistered) return;\n isUnregistered = true;\n\n if (!instances.delete(instance.instanceId)) return;\n updateSnapshot();\n };\n },\n };\n}\n\nexport function getOrCreateSQLiteSyncDevtoolsRegistry(): SQLiteSyncDevtoolsRegistry {\n const registryGlobal = globalThis as RegistryGlobal;\n\n registryGlobal[devtoolsRegistrySymbol] ??= createSQLiteSyncDevtoolsRegistry();\n\n return registryGlobal[devtoolsRegistrySymbol];\n}\n","import { xxhash } from \"../hash\";\nimport type { HLCCounter } from \"../hlc\";\nimport type { SyncDbMigrator } from \"../migrations/migrator\";\nimport { applyMemoryDbSchema, type MemoryDbSchema, memoryDbConfig } from \"../migrations/system-schema\";\nimport type { CrdtTableConfig, SyncDbSchema } from \"../sqlite-crdt/crdt-schema\";\nimport { createCrdtStorage } from \"../sqlite-crdt/crdt-storage\";\nimport { makeCrdtTable, registerCrdtIntentDrainer } from \"../sqlite-crdt/make-crdt-table\";\nimport type { StoredValue } from \"../sqlite-crdt/stored-value\";\nimport type { SQLiteDbWrapper } from \"../sqlite-db-wrapper\";\nimport type { SQLiteReactiveDb } from \"./sqlite-reactive-db\";\n\ntype MemoryDbOptions<Database> = {\n nodeId: string;\n migrator: SyncDbMigrator;\n reactiveDb: SQLiteReactiveDb<Database>;\n hlcCounter: HLCCounter;\n crdtTables: CrdtTableConfig[];\n initializeSchema?: boolean;\n initialSyncId?: number;\n eventHlcAccumulator?: StoredValue<string>;\n syncDbSchema: Pick<SyncDbSchema, \"tables\" | \"tablesConfig\">;\n};\n\nexport async function createMemoryDb<Database>({\n nodeId,\n migrator,\n reactiveDb: _reactiveDb,\n hlcCounter,\n crdtTables,\n initializeSchema = true,\n initialSyncId,\n eventHlcAccumulator,\n syncDbSchema,\n}: MemoryDbOptions<Database>) {\n await xxhash.ensureLoaded();\n\n const reactiveDb = _reactiveDb as unknown as SQLiteReactiveDb<MemoryDbSchema>;\n const db = reactiveDb.db;\n\n if (initializeSchema) {\n applyMemoryDbSchema(db);\n for (const table of crdtTables) {\n makeCrdtTable({\n db,\n baseTableName: table.baseTableName,\n crdtTableName: table.crdtTableName,\n });\n }\n }\n\n const crdtStorage = createCrdtStorage({\n nodeId,\n initialLocalSyncId: initialSyncId ?? getCurrentSyncId(db),\n hlc: hlcCounter,\n migrator,\n db,\n dbConfig: memoryDbConfig,\n eventHlcAccumulator,\n schema: syncDbSchema,\n });\n\n registerCrdtIntentDrainer({\n reactiveDb,\n storage: crdtStorage,\n });\n\n return {\n crdtStorage,\n };\n}\n\nfunction getCurrentSyncId(db: SQLiteDbWrapper<MemoryDbSchema>) {\n return (\n db.execute<{ syncId: number }>(\"SELECT coalesce(max(sync_id), 0) AS syncId FROM persisted_crdt_events\", {\n loggerLevel: \"system\",\n }).rows[0]?.syncId ?? 0\n );\n}\n","import {\n createDeferredPromise,\n createTypedEventTarget,\n type DeferredPromise,\n noop,\n type TypedEventTarget,\n} from \"../utils\";\nimport type {\n AsyncRpc,\n WorkerBroadcastChannels,\n WorkerConfig,\n WorkerErrorResponseMessage,\n WorkerInitMessage,\n WorkerNotificationMessage,\n WorkerRequestMessage,\n WorkerRequestMethod,\n WorkerResponseMessage,\n WorkerRpc,\n WorkerState,\n} from \"./worker-common\";\nimport { isWorkerErrorResponseMessage, isWorkerNotificationMessage, isWorkerResponseMessage } from \"./worker-common\";\n\ntype NotificationEvents = {\n [K in WorkerNotificationMessage[\"notificationType\"]]: Extract<WorkerNotificationMessage, { notificationType: K }>;\n};\n\nexport const createWorkerDbClient = async ({\n broadcastChannels,\n worker,\n config,\n}: {\n broadcastChannels: WorkerBroadcastChannels;\n worker: Worker;\n config: WorkerConfig;\n}) => {\n const eventTarget = createTypedEventTarget<NotificationEvents>();\n const workerRequestsMap = new Map<string, DeferredPromise<unknown>>();\n let isDisposed = false;\n\n const queryWorker = <TMethod extends WorkerRequestMethod>(\n method: TMethod,\n args: Parameters<WorkerRpc[TMethod]>,\n ): Promise<Awaited<ReturnType<WorkerRpc[TMethod]>>> => {\n if (isDisposed) {\n return Promise.reject(new Error(\"Worker client disposed\"));\n }\n const requestId = crypto.randomUUID();\n const promise = createDeferredPromise<unknown>({\n timeout: 30_000,\n onTimeout: () => workerRequestsMap.delete(requestId),\n });\n workerRequestsMap.set(requestId, promise);\n\n const request: WorkerRequestMessage<TMethod> = {\n type: \"request\",\n requestId,\n method,\n args,\n };\n\n broadcastChannels.requests.postMessage(request);\n\n return promise.promise as Promise<Awaited<ReturnType<WorkerRpc[TMethod]>>>;\n };\n\n const handleWorkerResponse = (message: WorkerResponseMessage) => {\n const promise = workerRequestsMap.get(message.requestId);\n if (!promise) {\n return;\n }\n\n promise.resolve(message.data);\n workerRequestsMap.delete(message.requestId);\n };\n\n const handleWorkerError = (message: WorkerErrorResponseMessage) => {\n const promise = workerRequestsMap.get(message.requestId);\n if (!promise) {\n return;\n }\n\n promise.reject(new Error(message.error));\n workerRequestsMap.delete(message.requestId);\n };\n\n broadcastChannels.responses.onmessage = (event) => {\n const message = event.data;\n\n if (isWorkerResponseMessage(message)) {\n handleWorkerResponse(message);\n } else if (isWorkerErrorResponseMessage(message)) {\n handleWorkerError(message);\n } else if (isWorkerNotificationMessage(message)) {\n eventTarget.dispatchEvent(message.notificationType, message);\n }\n };\n\n const rpc: AsyncRpc<WorkerRpc> = {\n execute: (query) => queryWorker(\"execute\", [query]),\n getSnapshot: () => queryWorker(\"getSnapshot\", []),\n importData: (data, opts) => queryWorker(\"importData\", [data, opts]),\n pushTabEvents: (request) => queryWorker(\"pushTabEvents\", [request]),\n pullEvents: (params) => queryWorker(\"pullEvents\", [params]),\n postState: () => queryWorker(\"postState\", []),\n goOnline: () => queryWorker(\"goOnline\", []),\n goOffline: () => queryWorker(\"goOffline\", []),\n requestReload: (options) => queryWorker(\"requestReload\", [options]),\n };\n\n const statePromise = awaitWorkerState(eventTarget);\n postWorkerConfig(worker, config);\n // On first tab, the worker may not have its BroadcastChannel listener ready yet,\n // so this request can be silently dropped and timeout. The worker will independently\n // post state at the end of init. For subsequent tabs, this triggers the already-running\n // worker to send its current state.\n rpc.postState().catch(noop);\n\n let workerState = await statePromise;\n\n eventTarget.addEventListener(\"state-changed\", (event) => {\n workerState = event.payload.state;\n });\n\n const dispose = () => {\n isDisposed = true;\n broadcastChannels.responses.onmessage = null;\n for (const [id, deferred] of workerRequestsMap) {\n deferred.reject(new Error(\"Worker client disposed\"));\n workerRequestsMap.delete(id);\n }\n };\n\n return {\n ...rpc,\n subscribe: eventTarget.addEventListener,\n getState: () => workerState,\n dispose,\n };\n};\n\nfunction awaitWorkerState(eventTarget: TypedEventTarget<NotificationEvents>) {\n const promise = createDeferredPromise<WorkerState>({ timeout: 15_000 });\n\n const subscription = eventTarget.addEventListener(\"state-changed\", (event) => {\n promise.resolve(event.payload.state);\n subscription.unsubscribe();\n });\n\n return promise.promise;\n}\n\nfunction postWorkerConfig(worker: Worker, config: WorkerConfig) {\n const configMessage: WorkerInitMessage = {\n type: \"init\",\n config,\n };\n worker.postMessage(configMessage);\n}\n","import type { Compilable, CompiledQuery } from \"kysely\";\nimport { validateDbId } from \"./db-id\";\nimport { getOrCreateSQLiteSyncDevtoolsRegistry } from \"./devtools-registry\";\nimport { createExportData, type ImportDataOptions, type SyncedDbExport } from \"./export-import\";\nimport { HLCCounter } from \"./hlc\";\nimport { type Logger, startPerformanceLogger } from \"./logger\";\nimport { createMemoryDb } from \"./memory-db/memory-db\";\nimport { createSQLiteReactiveDb, type SharedLiveQuery, type SQLiteReactiveDb } from \"./memory-db/sqlite-reactive-db\";\nimport type { SyncDbMigrator } from \"./migrations/migrator\";\nimport type { SyncDbSchema } from \"./sqlite-crdt/crdt-schema\";\nimport { createCrdtSyncRemoteSource } from \"./sqlite-crdt/crdt-sync-remote-source\";\nimport { createStoredValue } from \"./sqlite-crdt/stored-value\";\nimport type {\n ExecuteParams,\n ExecuteResult,\n KyselyQueryFactory,\n QueryBuilderOutput,\n SQLiteTransactionWrapper,\n} from \"./sqlite-db-wrapper\";\nimport { createDeferredPromise, generateId } from \"./utils\";\nimport { createWorkerDbClient } from \"./worker-db/db-worker-client\";\nimport { createBroadcastChannels, syncDbClientLockName } from \"./worker-db/worker-common\";\n\nexport type SyncedDbOptions<Database, Props = undefined> = {\n dbId: string;\n worker: Worker;\n workerProps: Props;\n syncDbSchema: SyncDbSchema<Database>;\n};\n\n/** SQL execution that participates in CRDT intent draining. */\nexport type SyncedDbSqlExecutor<Database> = {\n execute<TResult = unknown>(query: ExecuteParams | string | CompiledQuery<TResult>): ExecuteResult<TResult>;\n executeKysely<TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>>(\n factory: KyselyQueryFactory<Database, TQuery, TResult>,\n ): ExecuteResult<TResult>;\n};\n\n/**\n * SQL execution that deliberately bypasses CRDT intent draining.\n *\n * Mutating a synced view through this executor can leave undrained intents and\n * must only be done by sqlite-sync internals or recovery tooling.\n */\nexport type UnsafeSyncedDbSqlExecutor<Database> = SyncedDbSqlExecutor<Database>;\n\nexport type SyncedDbTransaction<Database> = SyncedDbSqlExecutor<Database> & {\n unsafe: UnsafeSyncedDbSqlExecutor<Database>;\n sql<TResult = unknown>(\n templateOrString: TemplateStringsArray | string,\n ...parameters: unknown[]\n ): ExecuteResult<TResult>;\n};\n\nexport type SyncedDbDatabase<Database> = SyncedDbSqlExecutor<Database> & {\n unsafe: UnsafeSyncedDbSqlExecutor<Database>;\n executeTransaction<TResult>(callback: (tx: SyncedDbTransaction<Database>) => TResult): TResult;\n createLiveQuery<TResult>(query: { sql: string; parameters: readonly unknown[] }): {\n getRows: () => TResult[];\n refresh: (parameters?: readonly unknown[]) => void;\n subscribe: (onchange: () => void) => () => void;\n };\n getSharedLiveQuery<TResult>(query: { sql: string; parameters: readonly unknown[] }): SharedLiveQuery<TResult>;\n};\n\nfunction createSqlExecutor<Database>(\n tx: Pick<SQLiteTransactionWrapper<Database>, \"execute\" | \"executeKysely\">,\n unsafe: boolean,\n): SyncedDbSqlExecutor<Database> {\n return {\n execute: (query) => tx.execute(query, unsafe ? { skipAfterMutatingStatement: true } : undefined),\n executeKysely: (factory) => tx.executeKysely(factory, unsafe ? { skipAfterMutatingStatement: true } : undefined),\n };\n}\n\n/** @internal Exported from this module for focused facade tests, but not from the package entry point. */\nexport function createSyncedDbDatabase<Database>(reactiveDb: SQLiteReactiveDb<Database>): SyncedDbDatabase<Database> {\n const safeExecutor = createSqlExecutor(reactiveDb.db, false);\n const unsafeExecutor = createSqlExecutor(reactiveDb.db, true);\n\n return {\n ...safeExecutor,\n unsafe: unsafeExecutor,\n executeTransaction: (callback) =>\n reactiveDb.db.executeTransaction((tx) => {\n const safeTransactionExecutor = createSqlExecutor(tx, false);\n const unsafeTransactionExecutor = createSqlExecutor(tx, true);\n return callback({\n ...safeTransactionExecutor,\n unsafe: unsafeTransactionExecutor,\n sql: tx.sql.bind(tx),\n });\n }),\n createLiveQuery: reactiveDb.createLiveQuery.bind(reactiveDb),\n getSharedLiveQuery: reactiveDb.getSharedLiveQuery.bind(reactiveDb),\n };\n}\n\nconst defaultLogger: Logger = (type, message, level = \"info\") => {\n const logMessage = `[${type}] ${message}`;\n switch (level) {\n case \"info\":\n console.log(logMessage);\n break;\n case \"warning\":\n console.warn(logMessage);\n break;\n case \"error\":\n console.error(logMessage);\n break;\n case \"trace\":\n console.trace(logMessage);\n break;\n }\n};\n\nexport async function createSyncedDb<Database, Props = undefined>(options: SyncedDbOptions<Database, Props>) {\n validateDbId(options.dbId);\n\n const perf = startPerformanceLogger(defaultLogger);\n\n const instanceId = generateId();\n const tabId = generateId();\n\n const broadcastChannels = createBroadcastChannels(options.dbId);\n\n const clientLockAcquired = createDeferredPromise<void>();\n const clientLockRelease = createDeferredPromise<void>();\n navigator.locks.request(`${syncDbClientLockName}-${options.dbId}`, { mode: \"shared\" }, () => {\n clientLockAcquired.resolve();\n return clientLockRelease.promise;\n });\n await clientLockAcquired.promise;\n\n const workerClient = await createWorkerDbClient({\n worker: options.worker,\n config: {\n clientId: generateId(),\n dbId: options.dbId,\n props: options.workerProps as never,\n },\n broadcastChannels,\n });\n\n const hlcCounter = new HLCCounter(tabId, () => Date.now());\n\n const workerClientSnapshot = await workerClient.getSnapshot();\n const reactiveDb = await createSQLiteReactiveDb<Database>({\n snapshot: workerClientSnapshot.file,\n logger: defaultLogger,\n });\n\n const memoryDbMigrator: SyncDbMigrator = {\n currentSchemaVersion: workerClientSnapshot.schemaVersion,\n latestSchemaVersion: workerClientSnapshot.schemaVersion,\n migrateDbToLatest: () => {\n throw new Error(\"Memory DB migrations are not implemented\");\n },\n migrateEvent: (event, targetVersion) => {\n if (event.schema_version === targetVersion) {\n return event;\n }\n throw new Error(\"Memory DB migrations are not implemented\");\n },\n migrateEvents: (events) => events,\n };\n const { crdtStorage } = await createMemoryDb({\n nodeId: tabId,\n migrator: memoryDbMigrator,\n reactiveDb: reactiveDb,\n hlcCounter,\n crdtTables: options.syncDbSchema.tablesConfig,\n syncDbSchema: options.syncDbSchema,\n });\n\n const pullSyncId = createStoredValue({\n initialValue: workerClientSnapshot.syncId,\n });\n const pushSyncId = createStoredValue({\n initialValue: 0,\n });\n const tabRemoteSource = createCrdtSyncRemoteSource({\n bufferSize: 500,\n pullSyncId,\n pushSyncId,\n storage: crdtStorage,\n nodeId: tabId,\n migrator: memoryDbMigrator,\n remoteFactory: ({ onEventsAvailable }) => {\n const subscription = workerClient.subscribe(\"new-event-chunk-applied\", (event) => {\n onEventsAvailable({ newSyncId: event.payload.newSyncId, remoteEventHlcSum: event.payload.eventHlcSum });\n });\n\n return {\n pullEvents: (request) => workerClient.pullEvents(request),\n pushEvents: (request) => workerClient.pushTabEvents(request),\n disconnect: () => {\n subscription.unsubscribe();\n },\n };\n },\n });\n tabRemoteSource.goOnline();\n\n const reloadRequestedSubscription = workerClient.subscribe(\"reload-requested\", () => {\n globalThis.location?.reload();\n });\n\n perf.logEnd(\"createSyncedDb\", \"initialized\", \"info\");\n\n const exportData = createExportData({\n reactiveDb,\n tablesConfig: options.syncDbSchema.tablesConfig,\n schemaVersion: workerClientSnapshot.schemaVersion,\n });\n const importData = (data: SyncedDbExport, opts?: ImportDataOptions) => workerClient.importData(data, opts);\n\n let isDisposed = false;\n let unregisterDevtools: (() => void) | undefined;\n const dispose = async () => {\n if (isDisposed) return;\n isDisposed = true;\n\n unregisterDevtools?.();\n reloadRequestedSubscription.unsubscribe();\n clientLockRelease.resolve();\n await tabRemoteSource.dispose();\n broadcastChannels.requests.close();\n broadcastChannels.responses.close();\n workerClient.dispose();\n reactiveDb.dispose();\n };\n\n const syncedDb = {\n db: createSyncedDbDatabase(reactiveDb),\n state: {\n getState: workerClient.getState.bind(workerClient),\n subscribe: (onChange: () => void) => {\n const { unsubscribe } = workerClient.subscribe(\"state-changed\", onChange);\n return unsubscribe;\n },\n goOnline: workerClient.goOnline.bind(workerClient),\n goOffline: workerClient.goOffline.bind(workerClient),\n },\n /**\n * Ask the elected worker to broadcast a page reload to all tabs for this dbId.\n *\n * With `clean: true` the worker durably records a reset request epoch before\n * broadcasting, so the worker elected on the next startup initializes with\n * `clearOnInit: true` and wipes the persisted DB. Destructive — use as a\n * recovery path when the durable worker DB may be de-synced.\n *\n * Pending in-memory tab events are not preserved, and the returned promise\n * may never settle in the caller — the page typically unloads first.\n */\n requestReload: async (options: { clean: boolean }) => {\n await workerClient.requestReload(options);\n // Primary path: this tab receives the worker's \"reload-requested\" broadcast\n // like every other tab. Fallback in case the broadcast is missed — in the\n // normal case the page is already unloading and this timeout never fires.\n setTimeout(() => globalThis.location?.reload(), 250);\n },\n subscribe: workerClient.subscribe,\n exportData,\n importData,\n dispose,\n _internal: {\n executeAsync: workerClient.execute.bind(workerClient),\n getMemoryQueryTables: reactiveDb.getTablesUsed.bind(reactiveDb),\n getSharedLiveQueriesSnapshot: reactiveDb.getSharedLiveQueriesSnapshot.bind(reactiveDb),\n crdtTableNames: options.syncDbSchema.tablesConfig.map((table) => table.crdtTableName),\n crdtTablesConfig: options.syncDbSchema.tablesConfig,\n schemaVersion: workerClientSnapshot.schemaVersion,\n migrationVersions: Object.keys(options.syncDbSchema.migrations)\n .map(Number)\n .sort((a, b) => a - b),\n },\n };\n\n unregisterDevtools = getOrCreateSQLiteSyncDevtoolsRegistry().register({\n instanceId,\n dbId: options.dbId,\n createdAt: Date.now(),\n instance: syncedDb,\n });\n\n return syncedDb;\n}\n\nexport type SyncedDb<Database> = Awaited<ReturnType<typeof createSyncedDb<Database>>>;\n"],"mappings":"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"}
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as CrdtChangeIntent, At as InternalSQLiteWrapper, Mt as KyselyStatementFactory, d as CRDT_CHANGE_INTENTS_TABLE, dt as createSystemDbConfig, f as createCrdtViewStatements, ft as runSystemMigrations, p as drainCrdtChangeIntents, ut as baseSystemMigrations } from "./index-
|
|
1
|
+
import { $ as CrdtChangeIntent, At as InternalSQLiteWrapper, Mt as KyselyStatementFactory, d as CRDT_CHANGE_INTENTS_TABLE, dt as createSystemDbConfig, f as createCrdtViewStatements, ft as runSystemMigrations, p as drainCrdtChangeIntents, ut as baseSystemMigrations } from "./index-iXdCBXzB.js";
|
|
2
2
|
export { CRDT_CHANGE_INTENTS_TABLE, type CrdtChangeIntent, type InternalSQLiteWrapper, type KyselyStatementFactory, baseSystemMigrations, createCrdtViewStatements, createSystemDbConfig, drainCrdtChangeIntents, runSystemMigrations };
|