@sqlite-sync/core 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1159 @@
1
+ import { ColumnDataType, ColumnDefinitionBuilderCallback, ColumnType, Compilable, CompiledQuery, CreateIndexBuilder, CreateTableBuilder, Expression, Kysely, SchemaModule } from "kysely";
2
+ import { Database, FunctionOptions, SqlValue, Sqlite3Static } from "@sqlite.org/sqlite-wasm";
3
+ //#region src/dummy-kysely.d.ts
4
+ declare const dummyKysely: Kysely<any>;
5
+ //#endregion
6
+ //#region src/sqlite-crdt/crdt-table-schema.d.ts
7
+ type NewCrdtEvent = {
8
+ type: CrdtEventType;
9
+ dataset: string;
10
+ item_id: string;
11
+ payload: Record<string, unknown>;
12
+ };
13
+ type CrdtEventType = "item-created" | "item-updated" | "item-deleted";
14
+ type CrdtEventStatus = "pending" | "applied" | "failed" | "deduped";
15
+ /** Persisted on applied events that were accepted but did not mutate materialized state. */
16
+ declare const CRDT_EVENT_NO_OP_PAYLOAD = "no-op";
17
+ declare function isNoOpCrdtEventPayload(payload: string): payload is "no-op";
18
+ type CrdtEventOrigin = "remote" | "own" | "own-applied" | "local";
19
+ type PersistedCrdtEvent = {
20
+ schema_version: number;
21
+ sync_id: number;
22
+ status: CrdtEventStatus;
23
+ type: CrdtEventType;
24
+ timestamp: string;
25
+ origin: CrdtEventOrigin;
26
+ source_node_id: string;
27
+ dataset: string;
28
+ item_id: string;
29
+ payload: string;
30
+ };
31
+ type CrdtUpdateLogItem = {
32
+ dataset: string;
33
+ item_id: string;
34
+ payload: string;
35
+ };
36
+ type CrdtUpdateLogPayload = Record<string, string>;
37
+ //#endregion
38
+ //#region src/sqlite-crdt/stored-value.d.ts
39
+ type StoredValue<T> = {
40
+ get current(): T;
41
+ set current(newValue: T);
42
+ };
43
+ declare function createStoredValue<T>({ initialValue, saveToStorage }: {
44
+ initialValue: T;
45
+ saveToStorage?: (value: T) => void;
46
+ }): StoredValue<T>;
47
+ //#endregion
48
+ //#region src/migrations/migrator.d.ts
49
+ type MigratableEvent = {
50
+ schema_version: number;
51
+ type: CrdtEventType;
52
+ dataset: string;
53
+ item_id: string;
54
+ payload: string;
55
+ };
56
+ type CrdtEventTransformer = (event: NewCrdtEvent) => NewCrdtEvent | null;
57
+ type MigrationStepSql = {
58
+ sql: string;
59
+ parameters?: readonly unknown[];
60
+ } | Compilable | ((db: Kysely<unknown>) => Compilable);
61
+ type UpdateLogMutation = {
62
+ type: "rename-table";
63
+ oldTable: string;
64
+ newTable: string;
65
+ } | {
66
+ type: "drop-table";
67
+ table: string;
68
+ } | {
69
+ type: "rename-column";
70
+ table: string;
71
+ oldColumn: string;
72
+ newColumn: string;
73
+ } | {
74
+ type: "add-column";
75
+ table: string;
76
+ column: string;
77
+ } | {
78
+ type: "drop-column";
79
+ table: string;
80
+ column: string;
81
+ };
82
+ type MigrationStep = {
83
+ sql: MigrationStepSql | MigrationStepSql[];
84
+ eventTransformer?: MigrationEventTransformers;
85
+ updateLogMutations?: UpdateLogMutation[];
86
+ };
87
+ type RawMigrationStep = {
88
+ sql: MigrationSql[];
89
+ eventTransformer?: CompiledMigrationEventTransformer;
90
+ updateLogMutations?: UpdateLogMutation[];
91
+ };
92
+ type MigrationSql = {
93
+ sql: string;
94
+ parameters: readonly unknown[];
95
+ };
96
+ type DataTypeExpression = ColumnDataType | Expression<any>;
97
+ declare const migrationSteps: {
98
+ createTable: (table: string, build: (table: CreateTableBuilder<string, never>) => Compilable) => MigrationStep;
99
+ dropTable: (table: string) => MigrationStep;
100
+ createIndex: (indexName: string, build: (index: CreateIndexBuilder) => Compilable) => MigrationStep;
101
+ dropIndex: (indexName: string) => MigrationStep;
102
+ renameTable: ({ oldTable, newTable }: {
103
+ oldTable: string;
104
+ newTable: string;
105
+ }) => MigrationStep;
106
+ renameColumn: ({ table, oldColumn, newColumn }: {
107
+ table: string;
108
+ oldColumn: string;
109
+ newColumn: string;
110
+ }) => MigrationStep;
111
+ addColumn: ({ table, column, type, defaultValue, build }: {
112
+ table: string;
113
+ column: string;
114
+ type: DataTypeExpression;
115
+ defaultValue: number | boolean | string | null;
116
+ build?: ColumnDefinitionBuilderCallback;
117
+ }) => MigrationStep;
118
+ dropColumn: ({ table, column }: {
119
+ table: string;
120
+ column: string;
121
+ }) => MigrationStep;
122
+ };
123
+ type MigrationEventTransformers = Record<string, CrdtEventTransformer>;
124
+ type CompiledMigrationEventTransformer = (event: NewCrdtEvent) => NewCrdtEvent | null;
125
+ declare function createMigrations(buildMigrations: (builder: typeof migrationSteps) => Record<number, MigrationStep[]>): Record<number, RawMigrationStep>;
126
+ type Migrations = ReturnType<typeof createMigrations>;
127
+ type MigrationsDb = {
128
+ startTransaction: (callback: (tx: MigrationsTransaction) => void) => void;
129
+ };
130
+ type MigrationsTransaction = {
131
+ execute: (sql: string, parameters: readonly unknown[], meta?: {
132
+ loggerLevel?: "system";
133
+ }) => void;
134
+ };
135
+ declare function createMigrator({ migrations, schemaVersion, updateLogTableName }: {
136
+ migrations: Migrations;
137
+ schemaVersion: StoredValue<number>;
138
+ updateLogTableName?: string;
139
+ }): {
140
+ latestSchemaVersion: number;
141
+ readonly currentSchemaVersion: number;
142
+ migrateDbToLatest: (db: MigrationsDb) => void;
143
+ migrateEvent: <Event extends MigratableEvent>(event: Event, targetVersion?: number) => Event | null;
144
+ migrateEvents: <Event extends MigratableEvent>(events: Event[], targetVersion?: number) => Event[];
145
+ };
146
+ type SyncDbMigrator = ReturnType<typeof createMigrator>;
147
+ //#endregion
148
+ //#region src/schema/table-builder.d.ts
149
+ type ColumnKind = "text" | "integer" | "real" | "boolean" | "enum";
150
+ type SqliteStorageType = "text" | "integer" | "real";
151
+ type ColumnMeta = {
152
+ kind: ColumnKind;
153
+ /** Storage type used in generated DDL. Booleans store as integer 0/1. */
154
+ sqlType: SqliteStorageType;
155
+ nullable: boolean;
156
+ hasDefault: boolean;
157
+ /** Declared default in JS form (booleans as booleans). */
158
+ defaultValue?: unknown;
159
+ /** Allowed values for `enum` columns. */
160
+ enumValues?: readonly string[];
161
+ description?: string;
162
+ };
163
+ declare class ColumnBuilder<Value, HasDefault extends boolean = false> {
164
+ readonly meta: ColumnMeta;
165
+ readonly "~types": {
166
+ value: Value;
167
+ hasDefault: HasDefault;
168
+ };
169
+ constructor(meta: ColumnMeta);
170
+ /** Allow SQL NULL; widens the value type with `null`. */
171
+ nullable(): ColumnBuilder<Value | null, HasDefault>;
172
+ /** Declare a column default. The value is used both in DDL and when migrating older events. */
173
+ default(value: Value): ColumnBuilder<Value, true>;
174
+ /** Narrow the TypeScript value type without changing storage, e.g. `t.text().$type<"movie" | "tv">()`. */
175
+ $type<Narrowed extends Value>(): ColumnBuilder<Narrowed, HasDefault>;
176
+ /** Human/AI-readable description, surfaced in generated schema docs. */
177
+ describe(description: string): ColumnBuilder<Value, HasDefault>;
178
+ }
179
+ type AnyColumnBuilder = ColumnBuilder<any, boolean>;
180
+ type TableColumns = Record<string, AnyColumnBuilder>;
181
+ type AnyTableBuilder = TableBuilder<any, any>;
182
+ type SyncSchemaTables = Record<string, AnyTableBuilder>;
183
+ type TableOptions<BaseName extends string | undefined = string | undefined> = {
184
+ /** Override the materialized base table name (defaults to the crdt table name prefixed with "_"). */
185
+ baseName?: BaseName;
186
+ description?: string;
187
+ };
188
+ type Simplify$1<T> = { [K in keyof T]: T[K]; } & {};
189
+ type ColumnValue<Column> = Column extends ColumnBuilder<infer Value, boolean> ? Value : never;
190
+ type InferRow<Cols extends TableColumns> = Simplify$1<{
191
+ id: string;
192
+ } & { [K in keyof Cols]: ColumnValue<Cols[K]>; } & {
193
+ tombstone?: boolean;
194
+ }>;
195
+ type PayloadValidationResult = {
196
+ success: true;
197
+ } | {
198
+ success: false;
199
+ errors: string[];
200
+ };
201
+ declare class TableBuilder<Cols extends TableColumns, BaseName extends string | undefined = undefined> {
202
+ readonly userColumns: Cols;
203
+ readonly "~baseName": BaseName;
204
+ /** All columns in DDL order, including the auto-injected `id` and `tombstone`. */
205
+ readonly columns: Record<string, ColumnMeta>;
206
+ readonly baseName: BaseName;
207
+ readonly description: string | undefined;
208
+ constructor(userColumns: Cols, options?: TableOptions<BaseName>);
209
+ describe(description: string): TableBuilder<Cols, BaseName>;
210
+ /** Type-only: the row shape returned by queries. Do not access at runtime. */
211
+ get $row(): InferRow<Cols>;
212
+ /**
213
+ * Validate a CRDT event payload against the declared columns.
214
+ * `item-created` payloads must contain every column without a default (nullable columns may be omitted);
215
+ * `item-updated` payloads are partial and must not touch `id` or set `tombstone` to a deleted value.
216
+ */
217
+ validatePayload(payload: Record<string, unknown>, options?: {
218
+ event?: "item-created" | "item-updated";
219
+ }): PayloadValidationResult;
220
+ }
221
+ declare const t: {
222
+ text: () => ColumnBuilder<string, false>;
223
+ integer: () => ColumnBuilder<number, false>;
224
+ real: () => ColumnBuilder<number, false>;
225
+ /** Stored as INTEGER 0/1; always bind booleans as 0/1 when writing raw SQL. */
226
+ boolean: () => ColumnBuilder<boolean, false>;
227
+ /**
228
+ * Union of string literals stored as TEXT, e.g. `t.enum(["movie", "tv"])`. Unlike `$type`, the
229
+ * allowed values are kept as runtime metadata, so payloads are validated against them.
230
+ * For an open-ended set, use `t.text().$type<"idle" | (string & {})>()` instead.
231
+ */
232
+ enum: <const Values extends readonly [string, ...string[]]>(values: Values) => ColumnBuilder<Values[number], false>;
233
+ table: <Cols extends TableColumns, const BaseName extends string | undefined = undefined>(columns: Cols, options?: TableOptions<BaseName>) => TableBuilder<Cols, BaseName>;
234
+ };
235
+ //#endregion
236
+ //#region src/sqlite-crdt/crdt-schema.d.ts
237
+ type CrdtTableConfig = {
238
+ baseTableName: string;
239
+ crdtTableName: string;
240
+ };
241
+ interface SyncDbSchema<ClientDB = {}, ServerDB = {}, MutationsDB = {}> {
242
+ get tablesConfig(): CrdtTableConfig[];
243
+ get migrations(): Migrations;
244
+ get tables(): SyncSchemaTables;
245
+ "~clientSchema": ClientDB;
246
+ "~serverSchema": ServerDB;
247
+ "~mutationsSchema": MutationsDB;
248
+ }
249
+ type ReadonlyTable<Table extends Record<string, unknown>> = { [K in keyof Table]: ColumnType<Table[K], never, never>; };
250
+ //#endregion
251
+ //#region src/hlc.d.ts
252
+ interface HLC {
253
+ timestamp: number;
254
+ counter: number;
255
+ nodeId: string;
256
+ }
257
+ declare class HLCCounter {
258
+ private timestamp;
259
+ private counter;
260
+ private nodeId;
261
+ private readonly getTimestamp;
262
+ private readonly maxDrift;
263
+ constructor(nodeId: string, getTimestamp: () => number, maxDrift?: number);
264
+ getCurrentHLC(): HLC;
265
+ getNextHLC(): HLC;
266
+ mergeHLC(hlc: HLC): void;
267
+ }
268
+ declare function serializeHLC(hlc: HLC): string;
269
+ declare function deserializeHLC(serialized: string): HLC;
270
+ declare function compareHLC(one: HLC, two: HLC): number;
271
+ //#endregion
272
+ //#region src/introspection.d.ts
273
+ type TableMetadata = {
274
+ name: string;
275
+ isView: boolean;
276
+ columns: ColumnMetadata[];
277
+ };
278
+ type DatabaseIntrospection = Record<string, TableMetadata>;
279
+ type ColumnMetadata = {
280
+ name: string;
281
+ dataType: string;
282
+ isNullable: boolean;
283
+ isAutoIncrementing: boolean;
284
+ hasDefaultValue: boolean;
285
+ defaultValueSql: string | null;
286
+ isPrimaryKey: boolean;
287
+ comment: undefined;
288
+ };
289
+ declare function introspectDb<BaseDatabase>(_db: SQLiteDbWrapper<BaseDatabase>): DatabaseIntrospection;
290
+ //#endregion
291
+ //#region src/logger.d.ts
292
+ type LogLevel = "info" | "warning" | "error" | "trace" | "system";
293
+ type Logger = (type: string, message: string, level?: LogLevel) => void;
294
+ type PerformanceLogger = {
295
+ restart: () => void;
296
+ logEnd: (type: string, message: string, level?: LogLevel) => void;
297
+ };
298
+ declare const startPerformanceLogger: (logger: Logger | undefined, level?: LogLevel) => PerformanceLogger;
299
+ //#endregion
300
+ //#region src/sqlite-db-wrapper.d.ts
301
+ type ExecuteParams = {
302
+ sql: string;
303
+ parameters: readonly unknown[];
304
+ };
305
+ type ExecuteResult<T> = {
306
+ rows: T[];
307
+ };
308
+ type PreparedStatement<TParams extends unknown[], TResult> = {
309
+ execute: (parameters: TParams) => TResult[];
310
+ finalize: () => void;
311
+ isFinalized: boolean;
312
+ };
313
+ type ScalarFunctionOptions<TArgs extends readonly SqlValue[], TResult extends SqlValue | undefined> = {
314
+ name: string;
315
+ callback: (...args: TArgs) => TResult;
316
+ } & Pick<FunctionOptions, "deterministic" | "directOnly" | "innocuous">;
317
+ type SqliteWrapperOptions = {
318
+ logger?: Logger;
319
+ loggerPrefix?: string;
320
+ sqlite3: Sqlite3Static;
321
+ db: () => Database;
322
+ };
323
+ type SQLiteTransactionWrapper<TDatabase = unknown> = Pick<SQLiteDbWrapper<TDatabase>, "sql" | "execute" | "executePrepared" | "executePreparedRaw" | "executeKysely">;
324
+ type InternalSQLiteTransactionWrapper<TDatabase = unknown> = Pick<SQLiteDbWrapper<TDatabase>, "executePrepared" | "executePreparedRaw">;
325
+ type InternalSQLiteWrapper<TDatabase = unknown> = InternalSQLiteTransactionWrapper<TDatabase> & {
326
+ executeTransaction: (callback: (db: InternalSQLiteTransactionWrapper<TDatabase>) => void) => void;
327
+ };
328
+ type QueryMetaOpts = {
329
+ loggerLevel?: "info" | "system";
330
+ };
331
+ /** Runs after user SQL succeeds, before its transaction or savepoint is committed. */
332
+ type AfterMutatingStatement<TDatabase> = (db: InternalSQLiteTransactionWrapper<TDatabase>) => void;
333
+ type ExecuteOptions = QueryMetaOpts & {
334
+ /** For internal mutations whose effects must not be processed by afterMutatingStatement. */
335
+ skipAfterMutatingStatement?: boolean;
336
+ };
337
+ declare class SQLiteDbWrapper<TDatabase = unknown> {
338
+ private db;
339
+ private sqlite3;
340
+ private logger?;
341
+ private loggerPrefix?;
342
+ private loadedDbSchema;
343
+ private readonly dataPointers;
344
+ private preparedStatements;
345
+ private preparedStatementsMap;
346
+ private preparedRawStatementsMap;
347
+ private afterMutatingStatement;
348
+ constructor(opts: SqliteWrapperOptions);
349
+ get ensureDb(): Database;
350
+ get dbSchema(): DatabaseIntrospection;
351
+ private executeSql;
352
+ execute<T = unknown>(opts: ExecuteParams | string | CompiledQuery<T>, options?: ExecuteOptions): ExecuteResult<T>;
353
+ setAfterMutatingStatement(callback: AfterMutatingStatement<TDatabase>): void;
354
+ executeTransaction<T>(callback: (db: SQLiteTransactionWrapper<TDatabase>) => T): T;
355
+ isInTransaction(): boolean;
356
+ beginTransaction(): {
357
+ commit: () => void;
358
+ rollback: () => void;
359
+ };
360
+ private beginStatementTransaction;
361
+ prepare<TParams extends unknown[], TResult>(sql: string, opts?: QueryMetaOpts): PreparedStatement<TParams, TResult>;
362
+ prepareKysely<TParams extends Record<string, unknown>>(opts?: QueryMetaOpts): <TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>>(factory: KyselyStatementFactory<TParams, TDatabase, TQuery, TResult>) => TypedStatement<TParams, TResult>;
363
+ executeKysely<TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>>(factory: KyselyQueryFactory<TDatabase, TQuery, TResult>, options?: ExecuteOptions): ExecuteResult<TResult>;
364
+ executePrepared<TParams extends Record<string, unknown>, TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>>(key: string, params: TParams, factory: KyselyStatementFactory<TParams, TDatabase, TQuery, TResult>, meta?: QueryMetaOpts): TResult[];
365
+ executePreparedRaw<TParams extends unknown[], TResult>({ key, sql, params, meta }: {
366
+ key: string;
367
+ sql: string;
368
+ params?: TParams;
369
+ meta?: QueryMetaOpts;
370
+ }): TResult[];
371
+ sql<T = unknown>(templateOrString: TemplateStringsArray | string, ...parameters: unknown[]): ExecuteResult<T>;
372
+ createScalarFunction<TArgs extends SqlValue[], TResult extends SqlValue | undefined>({ name, callback, deterministic, directOnly, innocuous }: ScalarFunctionOptions<TArgs, TResult>): Database;
373
+ useSnapshot(snapshot: Uint8Array<ArrayBufferLike>): void;
374
+ createSnapshot(): Uint8Array<ArrayBuffer>;
375
+ invalidateDbSchema(): void;
376
+ cleanup(): void;
377
+ close(): void;
378
+ }
379
+ type QueryBuilderOutput<QB> = QB extends Compilable<infer O> ? O : never;
380
+ type ParamsGetter<TParams> = <TKey extends keyof TParams>(key: TKey) => TParams[TKey];
381
+ type TypedStatement<TParams extends Record<string, unknown>, TResult> = {
382
+ execute: (parameters: TParams) => TResult[];
383
+ };
384
+ type KyselyStatementFactory<TParams extends Record<string, unknown>, TDatabase, TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>> = (kysely: Kysely<TDatabase>, params: ParamsGetter<TParams>) => TQuery;
385
+ type KyselyQueryFactory<TDatabase, TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>> = (kysely: Kysely<TDatabase>) => TQuery;
386
+ //#endregion
387
+ //#region src/sqlite-kv-store.d.ts
388
+ type KvStoreItem = {
389
+ key: string;
390
+ value: string;
391
+ };
392
+ declare function createKvStoreTableQuery(schema: SchemaModule, tableName: string): import("kysely").CreateTableBuilder<string, "key" | "value">;
393
+ declare function createSQLiteKvStore({ db, metaTableName }: {
394
+ db: InternalSQLiteWrapper<any>;
395
+ metaTableName: string;
396
+ }): {
397
+ get: (key: string) => string | null;
398
+ set: (key: string, value: string) => void;
399
+ remove: (key: string) => void;
400
+ createStringStoredValue: (key: string, defaultValue: string) => StoredValue<string>;
401
+ createNumberStoredValue: (key: string, defaultValue: number) => StoredValue<number>;
402
+ };
403
+ //#endregion
404
+ //#region src/utils.d.ts
405
+ type DeferredPromise<T> = {
406
+ promise: Promise<T>;
407
+ resolve: (value: T) => void;
408
+ reject: (error: Error) => void;
409
+ };
410
+ type DeferredPromiseOptions = {
411
+ timeout?: number;
412
+ onTimeout?: () => void;
413
+ };
414
+ declare function createDeferredPromise<T>(opts?: DeferredPromiseOptions): DeferredPromise<T>;
415
+ declare const generateId: () => `${string}-${string}-${string}-${string}-${string}`;
416
+ type DistributiveOmit<T, K extends keyof T> = T extends any ? Omit<T, K> : never;
417
+ declare class TypedBroadcastChannel<TMessage> {
418
+ private readonly channel;
419
+ constructor(name: string);
420
+ postMessage(message: TMessage): void;
421
+ set onmessage(callback: ((event: MessageEvent<TMessage>) => void) | null);
422
+ close(): void;
423
+ }
424
+ declare class TypedEvent<T = unknown> extends Event {
425
+ readonly payload: T;
426
+ constructor(type: string, payload: T);
427
+ }
428
+ type TypedEventTarget<T extends Record<string, unknown>> = {
429
+ addEventListener: <K extends keyof T & string>(type: K, listener: (event: TypedEvent<T[K]>) => void) => {
430
+ unsubscribe: () => void;
431
+ };
432
+ removeEventListener: <K extends keyof T & string>(type: K, listener: (event: TypedEvent<T[K]>) => void) => void;
433
+ dispatchEvent: <K extends keyof T & string>(type: K, payload: T[K]) => void;
434
+ };
435
+ declare const createTypedEventTarget: <T extends Record<string, unknown>>() => TypedEventTarget<T>;
436
+ type TryCatchResult<T> = {
437
+ success: true;
438
+ data: T;
439
+ } | {
440
+ success: false;
441
+ error: unknown;
442
+ };
443
+ declare function tryCatch<T>(fn: () => T): TryCatchResult<T>;
444
+ declare function tryCatchAsync<T>(fn: () => Promise<T>): Promise<TryCatchResult<T>>;
445
+ declare function jsonSafeParse<T>(json: string): TryCatchResult<T>;
446
+ /** Quote a SQLite identifier (table/column name), handling dot-separated schema qualifiers. */
447
+ declare function quoteId(name: string): string;
448
+ type ParsedTableName = {
449
+ schema: "main" | (string & {});
450
+ table: string;
451
+ fullIdentifier: string;
452
+ };
453
+ //#endregion
454
+ //#region src/migrations/system-schema.d.ts
455
+ type SystemDbConfig = {
456
+ eventsTable: ParsedTableName;
457
+ updateLogTable: ParsedTableName;
458
+ };
459
+ declare function createSystemDbConfig({ eventsTableName, updateLogTableName }: {
460
+ eventsTableName: string;
461
+ updateLogTableName: string;
462
+ }): SystemDbConfig;
463
+ type SystemMigrationContext = SystemDbConfig & {
464
+ execute: (sql: string) => void;
465
+ };
466
+ type SystemMigration = {
467
+ version: number;
468
+ up: (ctx: SystemMigrationContext) => void;
469
+ };
470
+ declare const baseSystemMigrations: SystemMigration[];
471
+ declare function runSystemMigrations(opts: {
472
+ version: StoredValue<number>;
473
+ migrations: SystemMigration[];
474
+ dbConfig: SystemDbConfig;
475
+ execute: (sql: string) => void;
476
+ transaction: (callback: () => void) => void;
477
+ }): void;
478
+ declare function applyWorkerDbSchema(db: SQLiteDbWrapper<any>): {
479
+ kvStore: {
480
+ get: (key: string) => string | null;
481
+ set: (key: string, value: string) => void;
482
+ remove: (key: string) => void;
483
+ createStringStoredValue: (key: string, defaultValue: string) => StoredValue<string>;
484
+ createNumberStoredValue: (key: string, defaultValue: number) => StoredValue<number>;
485
+ };
486
+ };
487
+ declare function applyMemoryDbSchema(db: SQLiteDbWrapper<any>): void;
488
+ //#endregion
489
+ //#region src/sqlite-crdt/crdt-storage.d.ts
490
+ type LocalCrdtEvent = {
491
+ type: CrdtEventType;
492
+ dataset: string;
493
+ item_id: string;
494
+ payload: string;
495
+ timestamp: string;
496
+ schema_version: number;
497
+ };
498
+ type OwnCrdtEvent = {
499
+ type: CrdtEventType;
500
+ dataset: string;
501
+ item_id: string;
502
+ payload: string;
503
+ timestamp?: undefined;
504
+ schema_version?: undefined;
505
+ };
506
+ type OwnCrdtSnapshot = {
507
+ dataset: string;
508
+ item_id: string;
509
+ patch: Record<string, unknown>;
510
+ };
511
+ type CrdtChangeIntent = {
512
+ seq: number;
513
+ dataset: string;
514
+ type: CrdtEventType;
515
+ item_id: string;
516
+ new_item_id: string | null;
517
+ payload_json: string;
518
+ };
519
+ type RemoteCrdtEvent = {
520
+ type: CrdtEventType;
521
+ dataset: string;
522
+ item_id: string;
523
+ payload: string;
524
+ timestamp: string;
525
+ schema_version: number;
526
+ };
527
+ type GetEventsBatchQuery = {
528
+ afterSyncId: number;
529
+ status: CrdtEventStatus;
530
+ limit: number;
531
+ } & ({
532
+ excludeOrigin: CrdtEventOrigin;
533
+ excludeNodeId?: undefined;
534
+ } | {
535
+ excludeOrigin?: undefined;
536
+ excludeNodeId: string;
537
+ });
538
+ type GetEventsBatch = {
539
+ events: PersistedCrdtEvent[];
540
+ hasMore: boolean;
541
+ nextSyncId: number;
542
+ };
543
+ type EnqueueEventsResult = {
544
+ beforeSyncId: number;
545
+ afterSyncId: number;
546
+ /** Resolves when the enqueued events have been processed (applied/deduped/failed). */
547
+ processed: Promise<void>;
548
+ };
549
+ type StorageHLC = Pick<HLCCounter, "getNextHLC" | "mergeHLC">;
550
+ type DbSyncerStorage = {
551
+ nodeId: string;
552
+ initialLocalSyncId: number;
553
+ migrator: SyncDbMigrator;
554
+ db: InternalSQLiteWrapper<any>;
555
+ dbConfig: SystemDbConfig;
556
+ hlc: StorageHLC;
557
+ eventHlcAccumulator?: StoredValue<string>;
558
+ onEventApplied?: (event: PersistedCrdtEvent) => void;
559
+ schema: Pick<SyncDbSchema, "tables" | "tablesConfig">;
560
+ };
561
+ type CrdtStorage = Omit<ReturnType<typeof createCrdtStorage>, "internal">;
562
+ type InternalCrdtStorage = ReturnType<typeof createCrdtStorage>;
563
+ type EventsAppliedPayload = {
564
+ syncId: number;
565
+ eventHlcSum: string | null;
566
+ };
567
+ type InternalDbSchema = {
568
+ _crdt_events: PersistedCrdtEvent;
569
+ _crdt_update_log: CrdtUpdateLogItem;
570
+ };
571
+ declare function createCrdtStorage(storage: DbSyncerStorage): {
572
+ getEventsBatch: (options: GetEventsBatchQuery) => GetEventsBatch;
573
+ enqueueLocalEvents: (events: LocalCrdtEvent[], sourceNodeId: string) => EnqueueEventsResult;
574
+ enqueueOwnEvents: (events: OwnCrdtEvent[]) => EnqueueEventsResult;
575
+ enqueueRemoteEvents: (events: RemoteCrdtEvent[]) => EnqueueEventsResult;
576
+ applyOwnEvents: (events: OwnCrdtEvent[]) => void;
577
+ applyOwnSnapshot: (snapshot: OwnCrdtSnapshot) => void;
578
+ checkIsQuiescent: (pushedSyncId: number) => boolean;
579
+ getEventHlcAccumulator: () => string | null;
580
+ addEventListener: <K extends "events-applied" | "remote-event-apply-failed">(type: K, listener: (event: TypedEvent<{
581
+ "events-applied": EventsAppliedPayload;
582
+ "remote-event-apply-failed": {
583
+ syncId: number;
584
+ };
585
+ }[K]>) => void) => {
586
+ unsubscribe: () => void;
587
+ };
588
+ removeEventListener: <K extends "events-applied" | "remote-event-apply-failed">(type: K, listener: (event: TypedEvent<{
589
+ "events-applied": EventsAppliedPayload;
590
+ "remote-event-apply-failed": {
591
+ syncId: number;
592
+ };
593
+ }[K]>) => void) => void;
594
+ internal: {
595
+ applyOwnEventFromTransaction: (tx: InternalSQLiteTransactionWrapper<InternalDbSchema>, event: OwnCrdtEvent) => void;
596
+ applyOwnIntentsFromTransaction: (tx: InternalSQLiteTransactionWrapper<InternalDbSchema>, intents: CrdtChangeIntent[]) => {
597
+ appliedEvents: number;
598
+ };
599
+ processEnqueuedEvents: {
600
+ (): Promise<void>;
601
+ promise(): Promise<void> | null;
602
+ isExecuting(): boolean;
603
+ };
604
+ };
605
+ };
606
+ //#endregion
607
+ //#region src/export-import.d.ts
608
+ /**
609
+ * A portable, schema-version-aware dump of every active entity in a synced DB.
610
+ * Unlike a raw SQLite snapshot, it carries no event history — just the current
611
+ * `tombstone = 0` rows, ready to be replayed as fresh create events on import.
612
+ */
613
+ type SyncedDbExport = {
614
+ schemaVersion: number;
615
+ exportedAt: string;
616
+ /** base table name -> active rows (each includes `id`, excludes `tombstone`). */
617
+ tables: Record<string, Array<Record<string, unknown>>>;
618
+ };
619
+ type ImportDataOptions = {
620
+ validate?: boolean;
621
+ };
622
+ type ImportDataResult = {
623
+ imported: number;
624
+ };
625
+ type ExportImportReactiveDb = {
626
+ db: {
627
+ execute<T>(sql: string, meta: {
628
+ loggerLevel: "system";
629
+ }): ExecuteResult<T>;
630
+ };
631
+ };
632
+ type ApplyImportEvents = (events: OwnCrdtEvent[]) => void | Promise<void>;
633
+ type ImportMigrator = Pick<SyncDbMigrator, "currentSchemaVersion" | "migrateEvents">;
634
+ type CreateExportDataOptions = {
635
+ reactiveDb: ExportImportReactiveDb;
636
+ tablesConfig: CrdtTableConfig[];
637
+ schemaVersion: number;
638
+ };
639
+ type CreateImportDataOptions = {
640
+ migrator: ImportMigrator;
641
+ tablesConfig?: CrdtTableConfig[];
642
+ applyEvents: ApplyImportEvents;
643
+ };
644
+ declare function createImportData({ migrator, tablesConfig, applyEvents }: CreateImportDataOptions): (data: SyncedDbExport, opts?: ImportDataOptions) => ImportDataResult | Promise<ImportDataResult>;
645
+ declare function createExportData({ reactiveDb, tablesConfig, schemaVersion }: CreateExportDataOptions): (opts?: {
646
+ tables?: string[];
647
+ }) => SyncedDbExport;
648
+ //#endregion
649
+ //#region src/hash.d.ts
650
+ declare function ensureLoaded(): Promise<void>;
651
+ declare function h64(input: string, seed?: bigint): bigint;
652
+ declare const xxhash: {
653
+ ensureLoaded: typeof ensureLoaded;
654
+ h64: typeof h64;
655
+ };
656
+ //#endregion
657
+ //#region src/memory-db/sqlite-reactive-db.d.ts
658
+ type SQLiteReactiveDbOptions = {
659
+ snapshot: Uint8Array<ArrayBufferLike>;
660
+ logger: Logger;
661
+ };
662
+ type EventsMap = {
663
+ "transaction-committed": undefined;
664
+ "transaction-rolled-back": undefined;
665
+ "any-table-changed": undefined;
666
+ } & Record<`table:${string}`, void>;
667
+ type LiveQuery<TResult> = {
668
+ getRows: () => TResult[];
669
+ refresh: () => void;
670
+ subscribe: (onchange: () => void) => () => void;
671
+ };
672
+ type SharedLiveQuery<TResult> = LiveQuery<TResult> & {
673
+ readonly sql: string;
674
+ readonly parameters: readonly unknown[];
675
+ getSubscriberCount: () => number;
676
+ };
677
+ type SharedLiveQuerySnapshot = {
678
+ sql: string;
679
+ parameters: readonly unknown[];
680
+ subscriberCount: number;
681
+ };
682
+ declare class SQLiteReactiveDb<Database> {
683
+ readonly db: SQLiteDbWrapper<Database>;
684
+ private sqlite3;
685
+ private readonly logger;
686
+ private tablesUsedStatement;
687
+ private eventTarget;
688
+ private mutationVersion;
689
+ private tableMutationVersions;
690
+ private constructor();
691
+ static create<Database>(opts: SQLiteReactiveDbOptions): Promise<SQLiteReactiveDb<Database>>;
692
+ private liveQueryStatements;
693
+ private sharedLiveQueries;
694
+ createLiveQuery<TResult>(query: {
695
+ sql: string;
696
+ parameters: readonly unknown[];
697
+ }): {
698
+ getRows: () => TResult[];
699
+ refresh: (parameters?: readonly unknown[]) => void;
700
+ subscribe: (onchange: () => void) => () => void;
701
+ };
702
+ getSharedLiveQuery<TResult>(query: {
703
+ sql: string;
704
+ parameters: readonly unknown[];
705
+ }): SharedLiveQuery<TResult>;
706
+ private registerSharedLiveQueryEntry;
707
+ getSharedLiveQueriesSnapshot(): SharedLiveQuerySnapshot[];
708
+ private scheduleSharedLiveQueryCleanup;
709
+ private cancelSharedLiveQueryCleanup;
710
+ private releaseSharedLiveQuery;
711
+ subscribeToQueryChanges(params: {
712
+ sql: string;
713
+ onDataChange: () => void;
714
+ }): {
715
+ unsubscribe: () => void;
716
+ };
717
+ subscribeToTableChanges(table: string, onChanges: () => void): {
718
+ unsubscribe: () => void;
719
+ };
720
+ getTablesUsed(query: string): {
721
+ name: string;
722
+ isWrite: boolean;
723
+ }[];
724
+ private getClearedTables;
725
+ addEventListener<K extends keyof EventsMap>(type: K, listener: (event: TypedEvent<EventsMap[K]>) => void): void;
726
+ removeEventListener<K extends keyof EventsMap>(type: K, listener: (event: TypedEvent<EventsMap[K]>) => void): void;
727
+ getTableMutationVersion(table: string): number;
728
+ private notifyTableSubscribers;
729
+ private registerDbHooks;
730
+ createSnapshot(): Uint8Array<ArrayBuffer>;
731
+ useSnapshot(snapshot: Uint8Array<ArrayBufferLike>): void;
732
+ dispose(): void;
733
+ }
734
+ declare function parametersAreEqual(a: readonly unknown[] | undefined, b: readonly unknown[] | undefined): boolean;
735
+ //#endregion
736
+ //#region src/schema/define-sync-schema.d.ts
737
+ type Simplify<T> = { [K in keyof T]: T[K]; } & {};
738
+ type RowOf<Table extends AnyTableBuilder> = Table extends TableBuilder<infer Cols extends TableColumns, any> ? InferRow<Cols> : never;
739
+ type BaseNameOf<CrdtName, Table extends AnyTableBuilder> = string extends Table["~baseName"] ? `_${CrdtName & string}` : [Table["~baseName"]] extends [string] ? Table["~baseName"] : `_${CrdtName & string}`;
740
+ type ClientSchemaOf<Tables extends SyncSchemaTables> = Simplify<{ [K in keyof Tables]: RowOf<Tables[K]>; } & { [K in keyof Tables as BaseNameOf<K, Tables[K]>]: ReadonlyTable<RowOf<Tables[K]>>; }>;
741
+ type ServerSchemaOf<Tables extends SyncSchemaTables> = Simplify<{ [K in keyof Tables]: ReadonlyTable<RowOf<Tables[K]>>; } & { [K in keyof Tables as BaseNameOf<K, Tables[K]>]: ReadonlyTable<RowOf<Tables[K]>>; }>;
742
+ type MutationsSchemaOf<Tables extends SyncSchemaTables> = Simplify<{ [K in keyof Tables as BaseNameOf<K, Tables[K]>]: RowOf<Tables[K]>; }>;
743
+ interface DefinedSyncSchema<Tables extends SyncSchemaTables> extends SyncDbSchema<ClientSchemaOf<Tables>, ServerSchemaOf<Tables>, MutationsSchemaOf<Tables>> {
744
+ /** The table builders, for type extraction (`typeof schema.tables.item.$row`) and runtime metadata. */
745
+ tables: Tables;
746
+ }
747
+ type DefineSyncSchemaConfig<Tables extends SyncSchemaTables> = {
748
+ tables: Tables;
749
+ /** Full migration history (including the initial createTable version), built with `createMigrations`. */
750
+ migrations: Migrations;
751
+ };
752
+ /**
753
+ * Define a sync database schema from `t.table()` builders.
754
+ *
755
+ * Record keys are the crdt (view) table names; base table names default to the key
756
+ * prefixed with "_", overridable per table via `t.table(cols, { baseName })`.
757
+ */
758
+ declare function defineSyncSchema<Tables extends SyncSchemaTables>({ tables, migrations }: DefineSyncSchemaConfig<Tables>): DefinedSyncSchema<Tables>;
759
+ //#endregion
760
+ //#region src/schema/validate-crdt-event.d.ts
761
+ type NewCrdtEventValidationResult = {
762
+ success: true;
763
+ event: NewCrdtEvent;
764
+ } | {
765
+ success: false;
766
+ errors: string[];
767
+ };
768
+ declare class CrdtEventValidationError extends Error {
769
+ readonly errors: string[];
770
+ constructor(errors: string[]);
771
+ }
772
+ declare function validateNewCrdtEvent(schema: Pick<SyncDbSchema, "tables" | "tablesConfig">, input: unknown): NewCrdtEventValidationResult;
773
+ //#endregion
774
+ //#region src/schema/verify-sync-schema.d.ts
775
+ type SchemaVerificationIssue = {
776
+ table: string;
777
+ column?: string;
778
+ message: string;
779
+ };
780
+ /**
781
+ * Verify that replaying the full migration history on a fresh database produces
782
+ * exactly the declared table schema. Creates a throwaway in-memory SQLite db,
783
+ * applies all migrations, introspects the result, and diffs it against the
784
+ * `t.table()` declarations.
785
+ *
786
+ * Returns an empty array when migrations and schema agree. Intended for dev-time
787
+ * checks (`startDbWorker({ verifySchema: true })`) and tests:
788
+ * `expect(await verifySyncSchema(syncDbSchema)).toEqual([])`.
789
+ */
790
+ declare function verifySyncSchema(schema: SyncDbSchema): Promise<SchemaVerificationIssue[]>;
791
+ declare function formatSchemaVerificationIssues(issues: SchemaVerificationIssue[]): string;
792
+ //#endregion
793
+ //#region src/sqlite-crdt/apply-crdt-event.d.ts
794
+ type PendingCrdtEvent = {
795
+ type: CrdtEventType;
796
+ dataset: string;
797
+ item_id: string;
798
+ timestamp: string;
799
+ payload: string;
800
+ };
801
+ declare const createSQLiteCrdtApplyFunction: ({ db, dbConfig }: {
802
+ db: InternalSQLiteWrapper<any>;
803
+ dbConfig: SystemDbConfig;
804
+ }) => (event: PendingCrdtEvent) => void;
805
+ type CreateCrdtApplyOpts = {
806
+ getCrdtUpdateLog: (opts: {
807
+ itemId: string;
808
+ dataset: string;
809
+ }) => CrdtUpdateLogPayload | null;
810
+ insertItem: (opts: {
811
+ dataset: string;
812
+ payload: Record<string, unknown>;
813
+ }) => void;
814
+ insertCrdtUpdateLog: (opts: {
815
+ dataset: string;
816
+ itemId: string;
817
+ payload: string;
818
+ }) => void;
819
+ updateItem: (opts: {
820
+ dataset: string;
821
+ itemId: string;
822
+ payload: Record<string, unknown>;
823
+ }) => void;
824
+ updateCrdtUpdateLog: (opts: {
825
+ dataset: string;
826
+ itemId: string;
827
+ payload: string;
828
+ }) => void;
829
+ };
830
+ declare function createCrdtApplyFunction({ getCrdtUpdateLog, insertItem, insertCrdtUpdateLog, updateItem, updateCrdtUpdateLog }: CreateCrdtApplyOpts): (event: PendingCrdtEvent) => void;
831
+ //#endregion
832
+ //#region src/sqlite-crdt/crdt-storage-mutator.d.ts
833
+ type CrdtStorageMutator<Database> = ReturnType<typeof createCrdtStorageMutator<Database>>;
834
+ type CommitEventOptions<Database, Table extends keyof Database & string> = {
835
+ type: "item-created";
836
+ dataset: Table;
837
+ item_id: string;
838
+ payload: CreateEventPayload<Database, Table>;
839
+ } | {
840
+ type: "item-updated";
841
+ dataset: Table;
842
+ item_id: string;
843
+ payload: UpdateEventPayload<Database, Table>;
844
+ } | {
845
+ type: "item-deleted";
846
+ dataset: Table;
847
+ item_id: string;
848
+ };
849
+ type CreateEventPayload<Database, Table extends keyof Database> = Omit<Database[Table], "tombstone">;
850
+ type UpdateEventPayload<Database, Table extends keyof Database> = Omit<Partial<Database[Table]>, "id" | "tombstone">;
851
+ type SnapshotOptions<Database, Table extends keyof Database & string> = {
852
+ dataset: Table;
853
+ id: string;
854
+ patch: UpdateEventPayload<Database, Table>;
855
+ };
856
+ declare function createCrdtStorageMutator<Database>({ storage }: {
857
+ storage: CrdtStorage;
858
+ }): {
859
+ enqueueEvents: (events: CommitEventOptions<Database, keyof Database & string>[]) => void;
860
+ createEvent: <Table extends keyof Database & string>(event: CommitEventOptions<Database, Table>) => CommitEventOptions<Database, Table>;
861
+ enqueueEvent: (event: CommitEventOptions<Database, keyof Database & string>) => void;
862
+ enqueueSnapshot: <Table extends keyof Database & string>(snapshot: SnapshotOptions<Database, Table>) => void;
863
+ };
864
+ //#endregion
865
+ //#region src/sqlite-crdt/crdt-sync-producer.d.ts
866
+ type CrdtSyncProducer = {
867
+ storage: CrdtStorage;
868
+ broadcastEvents: (request: {
869
+ newSyncId: number;
870
+ eventHlcSum: string | null;
871
+ }) => void;
872
+ };
873
+ declare const createCrdtSyncProducer: ({ storage, broadcastEvents }: CrdtSyncProducer) => void;
874
+ //#endregion
875
+ //#region src/worker-db/worker-common.d.ts
876
+ type WorkerNotificationMessage = {
877
+ notificationType: "new-event-chunk-applied";
878
+ newSyncId: number;
879
+ /** Worker's HLC checksum after applying up to `newSyncId`. */
880
+ eventHlcSum: string | null;
881
+ } | {
882
+ notificationType: "state-changed";
883
+ state: WorkerState;
884
+ } | {
885
+ notificationType: "reload-requested";
886
+ reloadEpoch: string;
887
+ clean: boolean;
888
+ } | {
889
+ notificationType: "de-sync-detected";
890
+ reason: DeSyncDetectedReason;
891
+ } | {
892
+ notificationType: "remote-schema-version-mismatch";
893
+ remoteSchemaVersion: number;
894
+ localSchemaVersion: number;
895
+ };
896
+ type WorkerState = {
897
+ remoteState: "online" | "offline" | "pending";
898
+ deSynced: boolean;
899
+ schemaVersionMismatched: boolean;
900
+ };
901
+ type EventsPullResponse = {
902
+ events: {
903
+ schema_version: number;
904
+ type: CrdtEventType;
905
+ timestamp: string;
906
+ dataset: string;
907
+ item_id: string;
908
+ payload: string;
909
+ }[];
910
+ hasMore: boolean;
911
+ nextSyncId: number;
912
+ };
913
+ type WorkerConfig<Props = any> = {
914
+ dbId: string;
915
+ clientId: string;
916
+ props: Props;
917
+ };
918
+ //#endregion
919
+ //#region src/sqlite-crdt/crdt-sync-remote-source.d.ts
920
+ type CrdtSyncRemoteSourceConfig = {
921
+ bufferSize: number;
922
+ storage: CrdtStorage;
923
+ migrator: SyncDbMigrator;
924
+ pullSyncId: StoredValue<number>;
925
+ pushSyncId: StoredValue<number>;
926
+ nodeId: string;
927
+ remoteFactory?: CreateRemoteSourceFactory;
928
+ };
929
+ type EventsPullRequest = {
930
+ afterSyncId: number;
931
+ excludeNodeId?: string;
932
+ };
933
+ type EventsPushRequest = {
934
+ nodeId: string;
935
+ events: (PendingCrdtEvent & {
936
+ schema_version: number;
937
+ })[];
938
+ };
939
+ type EventsPushResponse = {
940
+ ok: boolean;
941
+ /** Remote sync_id right before the pushed events were enqueued. */
942
+ beforeSyncId?: number;
943
+ /** Remote sync_id right after the pushed events were enqueued. */
944
+ afterSyncId?: number;
945
+ };
946
+ type CrdtSyncRemoteSource = ReturnType<typeof createCrdtSyncRemoteSource>;
947
+ type EventsAvailable = {
948
+ newSyncId: number;
949
+ remoteEventHlcSum: string | null;
950
+ };
951
+ type CreateRemoteSourceFactory = (opts: {
952
+ onEventsAvailable: (event: EventsAvailable) => void;
953
+ }) => RemoteSource | Promise<RemoteSource>;
954
+ type RemoteSource = {
955
+ pullEvents: (request: EventsPullRequest) => Promise<EventsPullResponse>;
956
+ pushEvents: (request: EventsPushRequest) => Promise<EventsPushResponse>;
957
+ disconnect?: () => void | Promise<void>;
958
+ };
959
+ type RemoteSourceState = {
960
+ type: "pending";
961
+ deSynced: boolean;
962
+ schemaVersionMismatched: boolean;
963
+ } | {
964
+ type: "offline";
965
+ reason: OfflineReason;
966
+ deSynced: boolean;
967
+ schemaVersionMismatched: boolean;
968
+ } | {
969
+ type: "online";
970
+ source: RemoteSource;
971
+ deSynced: boolean;
972
+ schemaVersionMismatched: boolean;
973
+ };
974
+ type OfflineReason = "NOT_INITIALIZED" | "INITIALIZATION_FAILED" | "REMOTE_PUSH_ERROR" | "REMOTE_PULL_ERROR" | "DISCONNECTED";
975
+ type DeSyncDetectedReason = "CHECKSUM_MISMATCH" | "ERROR_APPLYING_REMOTE_EVENT";
976
+ declare const createCrdtSyncRemoteSource: ({ bufferSize, storage, migrator, pullSyncId, pushSyncId, nodeId, remoteFactory }: CrdtSyncRemoteSourceConfig) => {
977
+ goOnline: () => Promise<void>;
978
+ goOffline: {
979
+ (reason: OfflineReason): Promise<void>;
980
+ promise(): Promise<void> | null;
981
+ isExecuting(): boolean;
982
+ };
983
+ syncWithRemote: {
984
+ (): Promise<void>;
985
+ promise(): Promise<void> | null;
986
+ isExecuting(): boolean;
987
+ };
988
+ getState: () => WorkerState;
989
+ dispose: () => Promise<void>;
990
+ addEventListener: <K extends "state-changed" | "de-sync-detected" | "remote-schema-version-mismatch">(type: K, listener: (event: TypedEvent<{
991
+ "state-changed": RemoteSourceState["type"];
992
+ "de-sync-detected": {
993
+ reason: DeSyncDetectedReason;
994
+ };
995
+ "remote-schema-version-mismatch": {
996
+ remoteSchemaVersion: number;
997
+ localSchemaVersion: number;
998
+ };
999
+ }[K]>) => void) => {
1000
+ unsubscribe: () => void;
1001
+ };
1002
+ removeEventListener: <K extends "state-changed" | "de-sync-detected" | "remote-schema-version-mismatch">(type: K, listener: (event: TypedEvent<{
1003
+ "state-changed": RemoteSourceState["type"];
1004
+ "de-sync-detected": {
1005
+ reason: DeSyncDetectedReason;
1006
+ };
1007
+ "remote-schema-version-mismatch": {
1008
+ remoteSchemaVersion: number;
1009
+ localSchemaVersion: number;
1010
+ };
1011
+ }[K]>) => void) => void;
1012
+ };
1013
+ //#endregion
1014
+ //#region src/sqlite-crdt/make-crdt-table.d.ts
1015
+ declare const CRDT_CHANGE_INTENTS_TABLE = "crdt_change_intents";
1016
+ declare function makeCrdtTable({ db, baseTableName, crdtTableName }: {
1017
+ db: SQLiteDbWrapper<any>;
1018
+ baseTableName: string;
1019
+ crdtTableName: string;
1020
+ }): void;
1021
+ declare function createCrdtViewStatements({ baseTableName, crdtTableName, columnNames }: {
1022
+ baseTableName: string;
1023
+ crdtTableName: string;
1024
+ columnNames: string[];
1025
+ }): string[];
1026
+ declare function drainCrdtChangeIntents({ tx, storage }: {
1027
+ tx: InternalSQLiteTransactionWrapper<any>;
1028
+ storage: InternalCrdtStorage;
1029
+ }): boolean;
1030
+ //#endregion
1031
+ //#region src/sync-db.d.ts
1032
+ type SyncedDbOptions<Database, Props = undefined> = {
1033
+ dbId: string;
1034
+ worker: Worker;
1035
+ workerProps: Props;
1036
+ syncDbSchema: SyncDbSchema<Database>;
1037
+ };
1038
+ /** SQL execution that participates in CRDT intent draining. */
1039
+ type SyncedDbSqlExecutor<Database> = {
1040
+ execute<TResult = unknown>(query: ExecuteParams | string | CompiledQuery<TResult>): ExecuteResult<TResult>;
1041
+ executeKysely<TQuery extends Compilable<TResult>, TResult = QueryBuilderOutput<TQuery>>(factory: KyselyQueryFactory<Database, TQuery, TResult>): ExecuteResult<TResult>;
1042
+ };
1043
+ /**
1044
+ * SQL execution that deliberately bypasses CRDT intent draining.
1045
+ *
1046
+ * Mutating a synced view through this executor can leave undrained intents and
1047
+ * must only be done by sqlite-sync internals or recovery tooling.
1048
+ */
1049
+ type UnsafeSyncedDbSqlExecutor<Database> = SyncedDbSqlExecutor<Database>;
1050
+ type SyncedDbTransaction<Database> = SyncedDbSqlExecutor<Database> & {
1051
+ unsafe: UnsafeSyncedDbSqlExecutor<Database>;
1052
+ sql<TResult = unknown>(templateOrString: TemplateStringsArray | string, ...parameters: unknown[]): ExecuteResult<TResult>;
1053
+ };
1054
+ type SyncedDbDatabase<Database> = SyncedDbSqlExecutor<Database> & {
1055
+ unsafe: UnsafeSyncedDbSqlExecutor<Database>;
1056
+ executeTransaction<TResult>(callback: (tx: SyncedDbTransaction<Database>) => TResult): TResult;
1057
+ createLiveQuery<TResult>(query: {
1058
+ sql: string;
1059
+ parameters: readonly unknown[];
1060
+ }): {
1061
+ getRows: () => TResult[];
1062
+ refresh: (parameters?: readonly unknown[]) => void;
1063
+ subscribe: (onchange: () => void) => () => void;
1064
+ };
1065
+ getSharedLiveQuery<TResult>(query: {
1066
+ sql: string;
1067
+ parameters: readonly unknown[];
1068
+ }): SharedLiveQuery<TResult>;
1069
+ };
1070
+ declare function createSyncedDb<Database, Props = undefined>(options: SyncedDbOptions<Database, Props>): Promise<{
1071
+ db: SyncedDbDatabase<Database>;
1072
+ state: {
1073
+ getState: () => WorkerState;
1074
+ subscribe: (onChange: () => void) => () => void;
1075
+ goOnline: () => Promise<void>;
1076
+ goOffline: () => Promise<void>;
1077
+ };
1078
+ /**
1079
+ * Ask the elected worker to broadcast a page reload to all tabs for this dbId.
1080
+ *
1081
+ * With `clean: true` the worker durably records a reset request epoch before
1082
+ * broadcasting, so the worker elected on the next startup initializes with
1083
+ * `clearOnInit: true` and wipes the persisted DB. Destructive — use as a
1084
+ * recovery path when the durable worker DB may be de-synced.
1085
+ *
1086
+ * Pending in-memory tab events are not preserved, and the returned promise
1087
+ * may never settle in the caller — the page typically unloads first.
1088
+ */
1089
+ requestReload: (options: {
1090
+ clean: boolean;
1091
+ }) => Promise<void>;
1092
+ subscribe: <K extends "state-changed" | "de-sync-detected" | "remote-schema-version-mismatch" | "new-event-chunk-applied" | "reload-requested">(type: K, listener: (event: TypedEvent<{
1093
+ "state-changed": {
1094
+ notificationType: "state-changed";
1095
+ state: WorkerState;
1096
+ };
1097
+ "de-sync-detected": {
1098
+ notificationType: "de-sync-detected";
1099
+ reason: DeSyncDetectedReason;
1100
+ };
1101
+ "remote-schema-version-mismatch": {
1102
+ notificationType: "remote-schema-version-mismatch";
1103
+ remoteSchemaVersion: number;
1104
+ localSchemaVersion: number;
1105
+ };
1106
+ "new-event-chunk-applied": {
1107
+ notificationType: "new-event-chunk-applied";
1108
+ newSyncId: number;
1109
+ eventHlcSum: string | null;
1110
+ };
1111
+ "reload-requested": {
1112
+ notificationType: "reload-requested";
1113
+ reloadEpoch: string;
1114
+ clean: boolean;
1115
+ };
1116
+ }[K]>) => void) => {
1117
+ unsubscribe: () => void;
1118
+ };
1119
+ exportData: (opts?: {
1120
+ tables?: string[];
1121
+ }) => SyncedDbExport;
1122
+ importData: (data: SyncedDbExport, opts?: ImportDataOptions) => Promise<ImportDataResult>;
1123
+ dispose: () => Promise<void>;
1124
+ _internal: {
1125
+ executeAsync: (query: ExecuteParams) => Promise<ExecuteResult<unknown>>;
1126
+ getMemoryQueryTables: (query: string) => {
1127
+ name: string;
1128
+ isWrite: boolean;
1129
+ }[];
1130
+ getSharedLiveQueriesSnapshot: () => SharedLiveQuerySnapshot[];
1131
+ crdtTableNames: string[];
1132
+ crdtTablesConfig: CrdtTableConfig[];
1133
+ schemaVersion: number;
1134
+ migrationVersions: number[];
1135
+ };
1136
+ }>;
1137
+ type SyncedDb<Database> = Awaited<ReturnType<typeof createSyncedDb<Database>>>;
1138
+ //#endregion
1139
+ //#region src/worker-db/reset-state.d.ts
1140
+ type ResetRequest = {
1141
+ epoch: string;
1142
+ requestedAt: number;
1143
+ };
1144
+ /** Durable async key-value storage for reset state. Injectable for tests. */
1145
+ type ResetStore = {
1146
+ get: <T>(key: string) => Promise<T | undefined>;
1147
+ set: (key: string, value: unknown) => Promise<void>;
1148
+ delete: (key: string) => Promise<void>;
1149
+ };
1150
+ /**
1151
+ * A clean reset is a recovery action for a de-sync detected now. If the reload
1152
+ * never happens (broadcast lost, tab crashed mid-reload, browser killed the page),
1153
+ * the request must not fire on an arbitrary later cold start and silently wipe
1154
+ * local-only writes accumulated since.
1155
+ */
1156
+ declare const RESET_REQUEST_TTL_MS: number;
1157
+ //#endregion
1158
+ export { GetEventsBatch as $, ColumnKind as $t, createCrdtApplyFunction as A, KyselyStatementFactory as At, defineSyncSchema as B, TableMetadata as Bt, WorkerNotificationMessage as C, PersistedCrdtEvent as Cn, KvStoreItem as Ct, SnapshotOptions as D, ExecuteResult as Dt, CrdtStorageMutator as E, ExecuteParams as Et, CrdtEventValidationError as F, LogLevel as Ft, xxhash as G, deserializeHLC as Gt, SharedLiveQuery as H, HLC as Ht, NewCrdtEventValidationResult as I, Logger as It, SyncedDbExport as J, ReadonlyTable as Jt, ImportDataOptions as K, serializeHLC as Kt, validateNewCrdtEvent as L, startPerformanceLogger as Lt, SchemaVerificationIssue as M, QueryBuilderOutput as Mt, formatSchemaVerificationIssues as N, SQLiteDbWrapper as Nt, createCrdtStorageMutator as O, InternalSQLiteWrapper as Ot, verifySyncSchema as P, SQLiteTransactionWrapper as Pt, CrdtStorage as Q, ColumnBuilder as Qt, DefineSyncSchemaConfig as R, ColumnMetadata as Rt, WorkerConfig as S, CrdtUpdateLogPayload as Sn, tryCatchAsync as St, createCrdtSyncProducer as T, dummyKysely as Tn, createSQLiteKvStore as Tt, SharedLiveQuerySnapshot as U, HLCCounter as Ut, SQLiteReactiveDb as V, introspectDb as Vt, parametersAreEqual as W, compareHLC as Wt, createImportData as X, AnyColumnBuilder as Xt, createExportData as Y, SyncDbSchema as Yt, CrdtChangeIntent as Z, AnyTableBuilder as Zt, EventsPullRequest as _, CRDT_EVENT_NO_OP_PAYLOAD as _n, createTypedEventTarget as _t, SyncedDbDatabase as a, TableBuilder as an, SystemMigrationContext as at, createCrdtSyncRemoteSource as b, CrdtEventType as bn, quoteId as bt, SyncedDbTransaction as c, t as cn, baseSystemMigrations as ct, CRDT_CHANGE_INTENTS_TABLE as d, MigrationsDb as dn, DeferredPromise as dt, ColumnMeta as en, OwnCrdtEvent as et, createCrdtViewStatements as f, SyncDbMigrator as fn, DistributiveOmit as ft, CreateRemoteSourceFactory as g, createStoredValue as gn, createDeferredPromise as gt, CrdtSyncRemoteSource as h, StoredValue as hn, TypedEventTarget as ht, SyncedDb as i, SyncSchemaTables as in, SystemMigration as it, createSQLiteCrdtApplyFunction as j, PreparedStatement as jt, PendingCrdtEvent as k, KyselyQueryFactory as kt, UnsafeSyncedDbSqlExecutor as l, MigratableEvent as ln, createSystemDbConfig as lt, makeCrdtTable as m, createMigrator as mn, TypedEvent as mt, ResetRequest as n, PayloadValidationResult as nn, createCrdtStorage as nt, SyncedDbOptions as o, TableColumns as on, applyMemoryDbSchema as ot, drainCrdtChangeIntents as p, createMigrations as pn, TypedBroadcastChannel as pt, ImportDataResult as q, CrdtTableConfig as qt, ResetStore as r, SqliteStorageType as rn, SystemDbConfig as rt, SyncedDbSqlExecutor as s, TableOptions as sn, applyWorkerDbSchema as st, RESET_REQUEST_TTL_MS as t, InferRow as tn, OwnCrdtSnapshot as tt, createSyncedDb as u, Migrations as un, runSystemMigrations as ut, EventsPushRequest as v, CrdtEventOrigin as vn, generateId as vt, WorkerState as w, isNoOpCrdtEventPayload as wn, createKvStoreTableQuery as wt, EventsPullResponse as x, CrdtUpdateLogItem as xn, tryCatch as xt, EventsPushResponse as y, CrdtEventStatus as yn, jsonSafeParse as yt, DefinedSyncSchema as z, DatabaseIntrospection as zt };
1159
+ //# sourceMappingURL=index-Ct_YbBmV.d.ts.map