@lunora/replica 1.0.0-alpha.3 → 1.0.0-alpha.5
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/adapters/sqlite-wasm.d.mts +18 -8
- package/dist/adapters/sqlite-wasm.d.ts +18 -8
- package/dist/adapters/sqlite-wasm.mjs +12 -24
- package/dist/index.d.mts +79 -18
- package/dist/index.d.ts +79 -18
- package/dist/index.mjs +9 -9
- package/dist/packem_shared/EventLog-CnK-3Wge.mjs +264 -0
- package/dist/packem_shared/{EventLogDO-CZYUvvSr.mjs → EventLogDO-DqlsVx0H.mjs} +155 -9
- package/dist/packem_shared/{EventLogDOClient-DGiEdi96.mjs → EventLogDOClient-F4FO8Si4.mjs} +8 -2
- package/dist/packem_shared/{EventSource-DfV4VoRD.mjs → EventSource-D5yO9_aI.mjs} +48 -22
- package/dist/packem_shared/{EventsSync-DkVbU0WV.mjs → EventsSync-BP36tC9O.mjs} +49 -17
- package/dist/packem_shared/{LocalMirror-GeJ26eNe.mjs → LocalMirror-a-5jEqFN.mjs} +34 -3
- package/dist/packem_shared/{MaterializerRuntime-HqNXqJxp.mjs → MaterializerRuntime-BoIrsMYB.mjs} +65 -45
- package/dist/packem_shared/applyDiff-98tKzmiW.mjs +67 -0
- package/dist/packem_shared/{classifyChanges-aZmkxgVI.mjs → classifyChanges-RcqLBpLs.mjs} +6 -3
- package/dist/packem_shared/{local-mirror.d-Cd8tAg-W.d.ts → local-mirror.d-ByIjd7sW.d.ts} +94 -3
- package/dist/packem_shared/{local-mirror.d-BUeOe5KC.d.mts → local-mirror.d-DL1XJBB3.d.mts} +94 -3
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.mjs +2 -2
- package/package.json +1 -1
- package/dist/packem_shared/EventLog-zMy7AYP4.mjs +0 -162
- package/dist/packem_shared/applyDiff-BtbIl1D3.mjs +0 -40
|
@@ -6,21 +6,31 @@ import { S as SqliteAdapter } from "../packem_shared/types.d-BuAWjEY5.mjs";
|
|
|
6
6
|
* The adapter takes a structural projection of the OO API (`sqlite3.oo1.DB`) so
|
|
7
7
|
* the package never imports from `@sqlite.org/sqlite-wasm` directly — consumers
|
|
8
8
|
* install it themselves and pass in their database instance.
|
|
9
|
+
*
|
|
10
|
+
* IMPORTANT (REPLICA-01): the real `oo1.DB.exec()` does NOT return sql.js's
|
|
11
|
+
* `{ columns, values }[]` result shape — with `rowMode: "object"` and
|
|
12
|
+
* `returnValue: "resultRows"` it returns the rows directly, as
|
|
13
|
+
* `Record<string, unknown>[]`. This adapter is written against that real
|
|
14
|
+
* shape; `lastInsertRowId` uses the driver's `selectValue()` convenience
|
|
15
|
+
* method (a single-scalar query helper) rather than parsing a result-row
|
|
16
|
+
* array.
|
|
9
17
|
* @param database An already-initialised `sqlite3.oo1.DB` instance.
|
|
10
18
|
* @param database.close Tear down the database connection.
|
|
11
|
-
* @param database.exec Execute SQL with optional bind params
|
|
12
|
-
*
|
|
19
|
+
* @param database.exec Execute SQL with optional bind params. With
|
|
20
|
+
* `{ returnValue: "resultRows", rowMode: "object" }` it returns the matched
|
|
21
|
+
* rows directly (`Record<string, unknown>[]`); otherwise (DDL/DML/BEGIN/
|
|
22
|
+
* COMMIT/ROLLBACK) its return value is unused here.
|
|
23
|
+
* @param database.selectValue Run a query and return the first column of the
|
|
24
|
+
* first row as a single scalar — used for `SELECT last_insert_rowid()`.
|
|
13
25
|
* @experimental
|
|
14
26
|
*/
|
|
15
27
|
declare const createSqliteWasmAdapter: (database: {
|
|
16
28
|
close: () => void;
|
|
17
29
|
exec: (sql: string, options?: {
|
|
18
30
|
bind?: unknown[];
|
|
19
|
-
returnValue?: "resultRows"
|
|
20
|
-
rowMode?: "
|
|
21
|
-
}) =>
|
|
22
|
-
|
|
23
|
-
values: unknown[][];
|
|
24
|
-
}[];
|
|
31
|
+
returnValue?: "resultRows";
|
|
32
|
+
rowMode?: "object";
|
|
33
|
+
}) => Record<string, unknown>[] | undefined;
|
|
34
|
+
selectValue: (sql: string, bind?: unknown[]) => unknown;
|
|
25
35
|
}) => SqliteAdapter;
|
|
26
36
|
export { createSqliteWasmAdapter };
|
|
@@ -6,21 +6,31 @@ import { S as SqliteAdapter } from "../packem_shared/types.d-BuAWjEY5.js";
|
|
|
6
6
|
* The adapter takes a structural projection of the OO API (`sqlite3.oo1.DB`) so
|
|
7
7
|
* the package never imports from `@sqlite.org/sqlite-wasm` directly — consumers
|
|
8
8
|
* install it themselves and pass in their database instance.
|
|
9
|
+
*
|
|
10
|
+
* IMPORTANT (REPLICA-01): the real `oo1.DB.exec()` does NOT return sql.js's
|
|
11
|
+
* `{ columns, values }[]` result shape — with `rowMode: "object"` and
|
|
12
|
+
* `returnValue: "resultRows"` it returns the rows directly, as
|
|
13
|
+
* `Record<string, unknown>[]`. This adapter is written against that real
|
|
14
|
+
* shape; `lastInsertRowId` uses the driver's `selectValue()` convenience
|
|
15
|
+
* method (a single-scalar query helper) rather than parsing a result-row
|
|
16
|
+
* array.
|
|
9
17
|
* @param database An already-initialised `sqlite3.oo1.DB` instance.
|
|
10
18
|
* @param database.close Tear down the database connection.
|
|
11
|
-
* @param database.exec Execute SQL with optional bind params
|
|
12
|
-
*
|
|
19
|
+
* @param database.exec Execute SQL with optional bind params. With
|
|
20
|
+
* `{ returnValue: "resultRows", rowMode: "object" }` it returns the matched
|
|
21
|
+
* rows directly (`Record<string, unknown>[]`); otherwise (DDL/DML/BEGIN/
|
|
22
|
+
* COMMIT/ROLLBACK) its return value is unused here.
|
|
23
|
+
* @param database.selectValue Run a query and return the first column of the
|
|
24
|
+
* first row as a single scalar — used for `SELECT last_insert_rowid()`.
|
|
13
25
|
* @experimental
|
|
14
26
|
*/
|
|
15
27
|
declare const createSqliteWasmAdapter: (database: {
|
|
16
28
|
close: () => void;
|
|
17
29
|
exec: (sql: string, options?: {
|
|
18
30
|
bind?: unknown[];
|
|
19
|
-
returnValue?: "resultRows"
|
|
20
|
-
rowMode?: "
|
|
21
|
-
}) =>
|
|
22
|
-
|
|
23
|
-
values: unknown[][];
|
|
24
|
-
}[];
|
|
31
|
+
returnValue?: "resultRows";
|
|
32
|
+
rowMode?: "object";
|
|
33
|
+
}) => Record<string, unknown>[] | undefined;
|
|
34
|
+
selectValue: (sql: string, bind?: unknown[]) => unknown;
|
|
25
35
|
}) => SqliteAdapter;
|
|
26
36
|
export { createSqliteWasmAdapter };
|
|
@@ -8,22 +8,12 @@ const createSqliteWasmAdapter = (database) => {
|
|
|
8
8
|
}
|
|
9
9
|
},
|
|
10
10
|
query(sql, params) {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const colNames = first.columns;
|
|
18
|
-
const rows = [];
|
|
19
|
-
for (const row of first.values) {
|
|
20
|
-
const object = {};
|
|
21
|
-
for (const [i, column] of colNames.entries()) {
|
|
22
|
-
object[column] = row[i];
|
|
23
|
-
}
|
|
24
|
-
rows.push(object);
|
|
25
|
-
}
|
|
26
|
-
return rows;
|
|
11
|
+
const rows = database.exec(sql, {
|
|
12
|
+
bind: params && params.length > 0 ? [...params] : void 0,
|
|
13
|
+
returnValue: "resultRows",
|
|
14
|
+
rowMode: "object"
|
|
15
|
+
});
|
|
16
|
+
return rows ?? [];
|
|
27
17
|
},
|
|
28
18
|
transaction(function_) {
|
|
29
19
|
database.exec("BEGIN");
|
|
@@ -36,16 +26,14 @@ const createSqliteWasmAdapter = (database) => {
|
|
|
36
26
|
}
|
|
37
27
|
},
|
|
38
28
|
lastInsertRowId() {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return -1;
|
|
29
|
+
const value = database.selectValue("SELECT last_insert_rowid()");
|
|
30
|
+
if (typeof value === "number") {
|
|
31
|
+
return value;
|
|
43
32
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return -1;
|
|
33
|
+
if (typeof value === "bigint") {
|
|
34
|
+
return Number(value);
|
|
47
35
|
}
|
|
48
|
-
return
|
|
36
|
+
return -1;
|
|
49
37
|
},
|
|
50
38
|
close() {
|
|
51
39
|
database.close();
|
package/dist/index.d.mts
CHANGED
|
@@ -2,8 +2,8 @@ export { createBetterSqlite3Adapter } from "./adapters/better-sqlite3.mjs";
|
|
|
2
2
|
export { createSqliteWasmAdapter } from "./adapters/sqlite-wasm.mjs";
|
|
3
3
|
export { createSqlJsAdapter } from "./adapters/sqljs.mjs";
|
|
4
4
|
import { S as SqliteAdapter } from "./packem_shared/types.d-BuAWjEY5.mjs";
|
|
5
|
-
import { T as TableDiff, I as InputEvent, S as Seq, E as EventLogEntry, a as EventLog, A as AppendOptions, L as LocalMirror } from "./packem_shared/local-mirror.d-
|
|
6
|
-
export { type C as ClientSeq, type b as EventLogSnapshot, type G as GlobalSeq, type
|
|
5
|
+
import { T as TableDiff, I as InputEvent, S as Seq, E as EventLogEntry, a as EventLog, A as AppendOptions, L as LocalMirror } from "./packem_shared/local-mirror.d-DL1XJBB3.mjs";
|
|
6
|
+
export { type C as ClientSeq, type b as EventLogOptions, type c as EventLogSnapshot, type G as GlobalSeq, type d as LocalMirrorOptions, type M as MirrorTableDef, type R as RowChange, e as classifyChanges, f as createTableDiff, g as diffSize, i as isClientSeq, h as isDiffEmpty, j as isGlobalSeq, k as isInputEvent, m as mergeDiffs } from "./packem_shared/local-mirror.d-DL1XJBB3.mjs";
|
|
7
7
|
/**
|
|
8
8
|
* Apply a single {@link TableDiff} to an in-memory row map and return
|
|
9
9
|
* the updated map.
|
|
@@ -166,9 +166,17 @@ declare class EventLogDOClient {
|
|
|
166
166
|
constructor(options: EventLogDOClientOptions);
|
|
167
167
|
/**
|
|
168
168
|
* Append one or more events to the log.
|
|
169
|
+
* @param events The events to append.
|
|
170
|
+
* @param options Idempotency controls for the batch.
|
|
171
|
+
* @param options.batchId Optional idempotency key for the whole batch — a
|
|
172
|
+
* retried `append` call with the same `batchId` (e.g. after a network
|
|
173
|
+
* timeout that hid a successful response) returns the originally-persisted
|
|
174
|
+
* entries instead of inserting duplicates.
|
|
169
175
|
* @returns The persisted entries with their assigned `seq` numbers.
|
|
170
176
|
*/
|
|
171
|
-
append(events: AppendEventInput[]
|
|
177
|
+
append(events: AppendEventInput[], options?: {
|
|
178
|
+
batchId?: string;
|
|
179
|
+
}): Promise<EventLogEntry[]>;
|
|
172
180
|
/**
|
|
173
181
|
* Fetch all entries with `seq >= sinceSeq`.
|
|
174
182
|
*
|
|
@@ -284,18 +292,50 @@ type EventSourceEvents = {
|
|
|
284
292
|
};
|
|
285
293
|
};
|
|
286
294
|
/**
|
|
295
|
+
* Sentinel a reducer can return to EXPLICITLY signal it does not handle a
|
|
296
|
+
* given event's `type` — as opposed to returning the current `state`
|
|
297
|
+
* reference unchanged to represent a legitimate, idempotent no-op for a type
|
|
298
|
+
* it DOES recognise.
|
|
299
|
+
*
|
|
300
|
+
* Reference equality alone can't tell these two cases apart (REPLICA-07): a
|
|
301
|
+
* reducer that intentionally returns `state` for a type it fully understands
|
|
302
|
+
* (e.g. "already applied this event, nothing to do") would otherwise be
|
|
303
|
+
* misclassified as "unhandled" and trigger {@link UnknownEventHandling} — a
|
|
304
|
+
* spurious warning, or worse, a thrown error under `"fail"`. Return `UNHANDLED`
|
|
305
|
+
* only for a `type` your reducer truly does not recognise; every other return
|
|
306
|
+
* (including a `state` returned by reference) is treated as handled.
|
|
307
|
+
*
|
|
308
|
+
* Reducers that always recognise every event they're given (a single
|
|
309
|
+
* always-matching type, or a catch-all) can ignore this entirely.
|
|
310
|
+
* @experimental
|
|
311
|
+
*/
|
|
312
|
+
declare const UNHANDLED: unique symbol;
|
|
313
|
+
/**
|
|
287
314
|
* A function that reduces an event into a state mutation.
|
|
288
315
|
*
|
|
289
316
|
* Pure functions are strongly encouraged: given the same event payload
|
|
290
|
-
* and state, they must produce the same next state.
|
|
317
|
+
* and state, they must produce the same next state. Return {@link UNHANDLED}
|
|
318
|
+
* to explicitly mark an event `type` this reducer does not process — see
|
|
319
|
+
* {@link UNHANDLED} for why reference equality against the input `state`
|
|
320
|
+
* cannot be used for this instead.
|
|
291
321
|
* @experimental
|
|
292
322
|
*/
|
|
293
|
-
type EventReducer<S> = (state: S, entry: EventLogEntry) => S;
|
|
323
|
+
type EventReducer<S> = (state: S, entry: EventLogEntry) => S | typeof UNHANDLED;
|
|
294
324
|
/**
|
|
295
325
|
* Options for constructing an {@link EventSource}.
|
|
296
326
|
* @experimental
|
|
297
327
|
*/
|
|
298
328
|
interface EventSourceOptions {
|
|
329
|
+
/**
|
|
330
|
+
* Cap this runtime's internal `log` to this many entries (REPLICA-06).
|
|
331
|
+
* `replayFromLog` copies every entry it replays from the source log into
|
|
332
|
+
* `this.log` too — a second, uncapped copy of the same history — so a
|
|
333
|
+
* long-lived `EventSource` fed by repeated replay accumulates entries in
|
|
334
|
+
* both places forever without a cap.
|
|
335
|
+
*
|
|
336
|
+
* `undefined` (the default) preserves unbounded retention.
|
|
337
|
+
*/
|
|
338
|
+
maxLogEntries?: number;
|
|
299
339
|
/**
|
|
300
340
|
* How to handle events whose `type` is not recognised by the reducer.
|
|
301
341
|
* @default "warn"
|
|
@@ -506,27 +546,38 @@ declare class MaterializerRuntime {
|
|
|
506
546
|
#private;
|
|
507
547
|
constructor(materializers: AnyMaterializer[], options?: MaterializerRuntimeOptions);
|
|
508
548
|
/**
|
|
509
|
-
* The
|
|
549
|
+
* The lowest per-materializer watermark — the seq of the next event that
|
|
550
|
+
* at least one materializer has not yet applied. `0` when there are no
|
|
551
|
+
* materializers.
|
|
510
552
|
*/
|
|
511
553
|
get appliedSeq(): number;
|
|
512
554
|
/**
|
|
513
|
-
* Replay a batch of entries
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
555
|
+
* Replay a batch of entries, applying each entry only to the
|
|
556
|
+
* materializers whose own watermark is behind it — a materializer at or
|
|
557
|
+
* past an entry's seq (e.g. recovered from a snapshot, or already caught
|
|
558
|
+
* up) skips it, so no materializer ever double-applies an event.
|
|
559
|
+
* @returns The number of entries applied to at least one materializer.
|
|
517
560
|
*/
|
|
518
561
|
applyEntries(entries: ReadonlyArray<EventLogEntry>): number;
|
|
519
562
|
/**
|
|
520
563
|
* Attempt to recover materialized state from a snapshot store.
|
|
521
564
|
*
|
|
522
|
-
* When a snapshot is found for a materializer, its state
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
565
|
+
* When a snapshot is found for a materializer, its state AND its own
|
|
566
|
+
* watermark are restored from that snapshot. A materializer with no
|
|
567
|
+
* snapshot keeps its current watermark (`0` for a fresh runtime) — it
|
|
568
|
+
* does NOT inherit another materializer's watermark, so it still catches
|
|
569
|
+
* up from the very beginning (REPLICA-04: previously a shared watermark
|
|
570
|
+
* was bumped to the MAX across snapshots, permanently skipping events 0..N
|
|
571
|
+
* for any un-snapshotted or lagging materializer).
|
|
572
|
+
* @returns The highest snapshot `appliedSeq` across all materializers, or
|
|
573
|
+
* `0` — kept for backward compatibility; callers that need the fetch
|
|
574
|
+
* watermark for catch-up should use the per-materializer minimum instead
|
|
575
|
+
* (see `initialize`).
|
|
526
576
|
*/
|
|
527
577
|
recoverFromSnapshots(): Promise<number>;
|
|
528
578
|
/**
|
|
529
|
-
* Persist the current state of all materializers as snapshots
|
|
579
|
+
* Persist the current state of all materializers as snapshots, each
|
|
580
|
+
* tagged with ITS OWN watermark (not a shared one).
|
|
530
581
|
*/
|
|
531
582
|
persistSnapshots(): Promise<void>;
|
|
532
583
|
/**
|
|
@@ -534,8 +585,11 @@ declare class MaterializerRuntime {
|
|
|
534
585
|
*
|
|
535
586
|
* 1. Recover materialized state from snapshots (if a snapshotStore is
|
|
536
587
|
* configured).
|
|
537
|
-
* 2. Fetch all entries since the
|
|
538
|
-
*
|
|
588
|
+
* 2. Fetch all entries since the MINIMUM per-materializer watermark from
|
|
589
|
+
* the DO — not the maximum — so a materializer with no snapshot (or a
|
|
590
|
+
* lower one) still receives every event it hasn't seen (REPLICA-04).
|
|
591
|
+
* 3. Apply them through the materializers; `applyEntries` skips each
|
|
592
|
+
* entry for any materializer already past it, so nothing is double-applied.
|
|
539
593
|
*
|
|
540
594
|
* Call this once on startup / after the DO binding is available.
|
|
541
595
|
* @returns The number of entries applied during catch-up.
|
|
@@ -584,6 +638,13 @@ interface EventLogDOState {
|
|
|
584
638
|
sql: {
|
|
585
639
|
exec: (query: string, ...params: unknown[]) => unknown;
|
|
586
640
|
};
|
|
641
|
+
/**
|
|
642
|
+
* The DO platform's native atomic-transaction primitive (async;
|
|
643
|
+
* commits on resolve, rolls back on throw/reject). Test doubles that
|
|
644
|
+
* omit it fall back to a bare (non-transactional) call — see
|
|
645
|
+
* `#handleAppend`.
|
|
646
|
+
*/
|
|
647
|
+
transaction?: <T>(closure: () => Promise<T> | T) => Promise<T>;
|
|
587
648
|
};
|
|
588
649
|
}
|
|
589
650
|
/**
|
|
@@ -907,4 +968,4 @@ declare class EventsSync {
|
|
|
907
968
|
*/
|
|
908
969
|
sync(): Promise<number>;
|
|
909
970
|
}
|
|
910
|
-
export { type AppendEventInput, type AppendOptions, type EventCallback, EventEmitter, type EventFactory, EventLog, EventLogDO, EventLogDOClient, type EventLogDOClientOptions, type EventLogEntry, type EventNamespace, type EventReducer, EventSource, type EventSourceEvents, type EventSourceOptions, type EventsContextOutput, type EventsDefinition, type EventsFacade, EventsSync, type EventsSyncOptions, InMemorySnapshotStore, type InputEvent, LocalMirror, type Materializer, type MaterializerDef, type MaterializerReducer, MaterializerRuntime, type MaterializerRuntimeOptions, type Seq, type SnapshotStore, type SqliteAdapter, type StateChangeCallback, type SubscriptionClient, SubscriptionManager, type TableDiff, type UnknownEventHandling, applyDiff, applyDiffToDatabase as applyDiffToDb, applyDiffToSnapshot, applyDiffs, applyDiffsToDatabase as applyDiffsToDb, defineEvents, defineMaterializer, eventsContext, subscribeToMirror };
|
|
971
|
+
export { type AppendEventInput, type AppendOptions, type EventCallback, EventEmitter, type EventFactory, EventLog, EventLogDO, EventLogDOClient, type EventLogDOClientOptions, type EventLogEntry, type EventNamespace, type EventReducer, EventSource, type EventSourceEvents, type EventSourceOptions, type EventsContextOutput, type EventsDefinition, type EventsFacade, EventsSync, type EventsSyncOptions, InMemorySnapshotStore, type InputEvent, LocalMirror, type Materializer, type MaterializerDef, type MaterializerReducer, MaterializerRuntime, type MaterializerRuntimeOptions, type Seq, type SnapshotStore, type SqliteAdapter, type StateChangeCallback, type SubscriptionClient, SubscriptionManager, type TableDiff, UNHANDLED, type UnknownEventHandling, applyDiff, applyDiffToDatabase as applyDiffToDb, applyDiffToSnapshot, applyDiffs, applyDiffsToDatabase as applyDiffsToDb, defineEvents, defineMaterializer, eventsContext, subscribeToMirror };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ export { createBetterSqlite3Adapter } from "./adapters/better-sqlite3.js";
|
|
|
2
2
|
export { createSqliteWasmAdapter } from "./adapters/sqlite-wasm.js";
|
|
3
3
|
export { createSqlJsAdapter } from "./adapters/sqljs.js";
|
|
4
4
|
import { S as SqliteAdapter } from "./packem_shared/types.d-BuAWjEY5.js";
|
|
5
|
-
import { T as TableDiff, I as InputEvent, S as Seq, E as EventLogEntry, a as EventLog, A as AppendOptions, L as LocalMirror } from "./packem_shared/local-mirror.d-
|
|
6
|
-
export { type C as ClientSeq, type b as EventLogSnapshot, type G as GlobalSeq, type
|
|
5
|
+
import { T as TableDiff, I as InputEvent, S as Seq, E as EventLogEntry, a as EventLog, A as AppendOptions, L as LocalMirror } from "./packem_shared/local-mirror.d-ByIjd7sW.js";
|
|
6
|
+
export { type C as ClientSeq, type b as EventLogOptions, type c as EventLogSnapshot, type G as GlobalSeq, type d as LocalMirrorOptions, type M as MirrorTableDef, type R as RowChange, e as classifyChanges, f as createTableDiff, g as diffSize, i as isClientSeq, h as isDiffEmpty, j as isGlobalSeq, k as isInputEvent, m as mergeDiffs } from "./packem_shared/local-mirror.d-ByIjd7sW.js";
|
|
7
7
|
/**
|
|
8
8
|
* Apply a single {@link TableDiff} to an in-memory row map and return
|
|
9
9
|
* the updated map.
|
|
@@ -166,9 +166,17 @@ declare class EventLogDOClient {
|
|
|
166
166
|
constructor(options: EventLogDOClientOptions);
|
|
167
167
|
/**
|
|
168
168
|
* Append one or more events to the log.
|
|
169
|
+
* @param events The events to append.
|
|
170
|
+
* @param options Idempotency controls for the batch.
|
|
171
|
+
* @param options.batchId Optional idempotency key for the whole batch — a
|
|
172
|
+
* retried `append` call with the same `batchId` (e.g. after a network
|
|
173
|
+
* timeout that hid a successful response) returns the originally-persisted
|
|
174
|
+
* entries instead of inserting duplicates.
|
|
169
175
|
* @returns The persisted entries with their assigned `seq` numbers.
|
|
170
176
|
*/
|
|
171
|
-
append(events: AppendEventInput[]
|
|
177
|
+
append(events: AppendEventInput[], options?: {
|
|
178
|
+
batchId?: string;
|
|
179
|
+
}): Promise<EventLogEntry[]>;
|
|
172
180
|
/**
|
|
173
181
|
* Fetch all entries with `seq >= sinceSeq`.
|
|
174
182
|
*
|
|
@@ -284,18 +292,50 @@ type EventSourceEvents = {
|
|
|
284
292
|
};
|
|
285
293
|
};
|
|
286
294
|
/**
|
|
295
|
+
* Sentinel a reducer can return to EXPLICITLY signal it does not handle a
|
|
296
|
+
* given event's `type` — as opposed to returning the current `state`
|
|
297
|
+
* reference unchanged to represent a legitimate, idempotent no-op for a type
|
|
298
|
+
* it DOES recognise.
|
|
299
|
+
*
|
|
300
|
+
* Reference equality alone can't tell these two cases apart (REPLICA-07): a
|
|
301
|
+
* reducer that intentionally returns `state` for a type it fully understands
|
|
302
|
+
* (e.g. "already applied this event, nothing to do") would otherwise be
|
|
303
|
+
* misclassified as "unhandled" and trigger {@link UnknownEventHandling} — a
|
|
304
|
+
* spurious warning, or worse, a thrown error under `"fail"`. Return `UNHANDLED`
|
|
305
|
+
* only for a `type` your reducer truly does not recognise; every other return
|
|
306
|
+
* (including a `state` returned by reference) is treated as handled.
|
|
307
|
+
*
|
|
308
|
+
* Reducers that always recognise every event they're given (a single
|
|
309
|
+
* always-matching type, or a catch-all) can ignore this entirely.
|
|
310
|
+
* @experimental
|
|
311
|
+
*/
|
|
312
|
+
declare const UNHANDLED: unique symbol;
|
|
313
|
+
/**
|
|
287
314
|
* A function that reduces an event into a state mutation.
|
|
288
315
|
*
|
|
289
316
|
* Pure functions are strongly encouraged: given the same event payload
|
|
290
|
-
* and state, they must produce the same next state.
|
|
317
|
+
* and state, they must produce the same next state. Return {@link UNHANDLED}
|
|
318
|
+
* to explicitly mark an event `type` this reducer does not process — see
|
|
319
|
+
* {@link UNHANDLED} for why reference equality against the input `state`
|
|
320
|
+
* cannot be used for this instead.
|
|
291
321
|
* @experimental
|
|
292
322
|
*/
|
|
293
|
-
type EventReducer<S> = (state: S, entry: EventLogEntry) => S;
|
|
323
|
+
type EventReducer<S> = (state: S, entry: EventLogEntry) => S | typeof UNHANDLED;
|
|
294
324
|
/**
|
|
295
325
|
* Options for constructing an {@link EventSource}.
|
|
296
326
|
* @experimental
|
|
297
327
|
*/
|
|
298
328
|
interface EventSourceOptions {
|
|
329
|
+
/**
|
|
330
|
+
* Cap this runtime's internal `log` to this many entries (REPLICA-06).
|
|
331
|
+
* `replayFromLog` copies every entry it replays from the source log into
|
|
332
|
+
* `this.log` too — a second, uncapped copy of the same history — so a
|
|
333
|
+
* long-lived `EventSource` fed by repeated replay accumulates entries in
|
|
334
|
+
* both places forever without a cap.
|
|
335
|
+
*
|
|
336
|
+
* `undefined` (the default) preserves unbounded retention.
|
|
337
|
+
*/
|
|
338
|
+
maxLogEntries?: number;
|
|
299
339
|
/**
|
|
300
340
|
* How to handle events whose `type` is not recognised by the reducer.
|
|
301
341
|
* @default "warn"
|
|
@@ -506,27 +546,38 @@ declare class MaterializerRuntime {
|
|
|
506
546
|
#private;
|
|
507
547
|
constructor(materializers: AnyMaterializer[], options?: MaterializerRuntimeOptions);
|
|
508
548
|
/**
|
|
509
|
-
* The
|
|
549
|
+
* The lowest per-materializer watermark — the seq of the next event that
|
|
550
|
+
* at least one materializer has not yet applied. `0` when there are no
|
|
551
|
+
* materializers.
|
|
510
552
|
*/
|
|
511
553
|
get appliedSeq(): number;
|
|
512
554
|
/**
|
|
513
|
-
* Replay a batch of entries
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
555
|
+
* Replay a batch of entries, applying each entry only to the
|
|
556
|
+
* materializers whose own watermark is behind it — a materializer at or
|
|
557
|
+
* past an entry's seq (e.g. recovered from a snapshot, or already caught
|
|
558
|
+
* up) skips it, so no materializer ever double-applies an event.
|
|
559
|
+
* @returns The number of entries applied to at least one materializer.
|
|
517
560
|
*/
|
|
518
561
|
applyEntries(entries: ReadonlyArray<EventLogEntry>): number;
|
|
519
562
|
/**
|
|
520
563
|
* Attempt to recover materialized state from a snapshot store.
|
|
521
564
|
*
|
|
522
|
-
* When a snapshot is found for a materializer, its state
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
565
|
+
* When a snapshot is found for a materializer, its state AND its own
|
|
566
|
+
* watermark are restored from that snapshot. A materializer with no
|
|
567
|
+
* snapshot keeps its current watermark (`0` for a fresh runtime) — it
|
|
568
|
+
* does NOT inherit another materializer's watermark, so it still catches
|
|
569
|
+
* up from the very beginning (REPLICA-04: previously a shared watermark
|
|
570
|
+
* was bumped to the MAX across snapshots, permanently skipping events 0..N
|
|
571
|
+
* for any un-snapshotted or lagging materializer).
|
|
572
|
+
* @returns The highest snapshot `appliedSeq` across all materializers, or
|
|
573
|
+
* `0` — kept for backward compatibility; callers that need the fetch
|
|
574
|
+
* watermark for catch-up should use the per-materializer minimum instead
|
|
575
|
+
* (see `initialize`).
|
|
526
576
|
*/
|
|
527
577
|
recoverFromSnapshots(): Promise<number>;
|
|
528
578
|
/**
|
|
529
|
-
* Persist the current state of all materializers as snapshots
|
|
579
|
+
* Persist the current state of all materializers as snapshots, each
|
|
580
|
+
* tagged with ITS OWN watermark (not a shared one).
|
|
530
581
|
*/
|
|
531
582
|
persistSnapshots(): Promise<void>;
|
|
532
583
|
/**
|
|
@@ -534,8 +585,11 @@ declare class MaterializerRuntime {
|
|
|
534
585
|
*
|
|
535
586
|
* 1. Recover materialized state from snapshots (if a snapshotStore is
|
|
536
587
|
* configured).
|
|
537
|
-
* 2. Fetch all entries since the
|
|
538
|
-
*
|
|
588
|
+
* 2. Fetch all entries since the MINIMUM per-materializer watermark from
|
|
589
|
+
* the DO — not the maximum — so a materializer with no snapshot (or a
|
|
590
|
+
* lower one) still receives every event it hasn't seen (REPLICA-04).
|
|
591
|
+
* 3. Apply them through the materializers; `applyEntries` skips each
|
|
592
|
+
* entry for any materializer already past it, so nothing is double-applied.
|
|
539
593
|
*
|
|
540
594
|
* Call this once on startup / after the DO binding is available.
|
|
541
595
|
* @returns The number of entries applied during catch-up.
|
|
@@ -584,6 +638,13 @@ interface EventLogDOState {
|
|
|
584
638
|
sql: {
|
|
585
639
|
exec: (query: string, ...params: unknown[]) => unknown;
|
|
586
640
|
};
|
|
641
|
+
/**
|
|
642
|
+
* The DO platform's native atomic-transaction primitive (async;
|
|
643
|
+
* commits on resolve, rolls back on throw/reject). Test doubles that
|
|
644
|
+
* omit it fall back to a bare (non-transactional) call — see
|
|
645
|
+
* `#handleAppend`.
|
|
646
|
+
*/
|
|
647
|
+
transaction?: <T>(closure: () => Promise<T> | T) => Promise<T>;
|
|
587
648
|
};
|
|
588
649
|
}
|
|
589
650
|
/**
|
|
@@ -907,4 +968,4 @@ declare class EventsSync {
|
|
|
907
968
|
*/
|
|
908
969
|
sync(): Promise<number>;
|
|
909
970
|
}
|
|
910
|
-
export { type AppendEventInput, type AppendOptions, type EventCallback, EventEmitter, type EventFactory, EventLog, EventLogDO, EventLogDOClient, type EventLogDOClientOptions, type EventLogEntry, type EventNamespace, type EventReducer, EventSource, type EventSourceEvents, type EventSourceOptions, type EventsContextOutput, type EventsDefinition, type EventsFacade, EventsSync, type EventsSyncOptions, InMemorySnapshotStore, type InputEvent, LocalMirror, type Materializer, type MaterializerDef, type MaterializerReducer, MaterializerRuntime, type MaterializerRuntimeOptions, type Seq, type SnapshotStore, type SqliteAdapter, type StateChangeCallback, type SubscriptionClient, SubscriptionManager, type TableDiff, type UnknownEventHandling, applyDiff, applyDiffToDatabase as applyDiffToDb, applyDiffToSnapshot, applyDiffs, applyDiffsToDatabase as applyDiffsToDb, defineEvents, defineMaterializer, eventsContext, subscribeToMirror };
|
|
971
|
+
export { type AppendEventInput, type AppendOptions, type EventCallback, EventEmitter, type EventFactory, EventLog, EventLogDO, EventLogDOClient, type EventLogDOClientOptions, type EventLogEntry, type EventNamespace, type EventReducer, EventSource, type EventSourceEvents, type EventSourceOptions, type EventsContextOutput, type EventsDefinition, type EventsFacade, EventsSync, type EventsSyncOptions, InMemorySnapshotStore, type InputEvent, LocalMirror, type Materializer, type MaterializerDef, type MaterializerReducer, MaterializerRuntime, type MaterializerRuntimeOptions, type Seq, type SnapshotStore, type SqliteAdapter, type StateChangeCallback, type SubscriptionClient, SubscriptionManager, type TableDiff, UNHANDLED, type UnknownEventHandling, applyDiff, applyDiffToDatabase as applyDiffToDb, applyDiffToSnapshot, applyDiffs, applyDiffsToDatabase as applyDiffsToDb, defineEvents, defineMaterializer, eventsContext, subscribeToMirror };
|
package/dist/index.mjs
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
export { createBetterSqlite3Adapter } from './adapters/better-sqlite3.mjs';
|
|
2
2
|
export { createSqliteWasmAdapter } from './adapters/sqlite-wasm.mjs';
|
|
3
3
|
export { createSqlJsAdapter } from './adapters/sqljs.mjs';
|
|
4
|
-
export { applyDiff, applyDiffToSnapshot, applyDiffs } from './packem_shared/applyDiff-
|
|
4
|
+
export { applyDiff, applyDiffToSnapshot, applyDiffs } from './packem_shared/applyDiff-98tKzmiW.mjs';
|
|
5
5
|
export { defineEvents } from './packem_shared/defineEvents-DiBkPTh_.mjs';
|
|
6
|
-
export { MaterializerRuntime, defineMaterializer } from './packem_shared/MaterializerRuntime-
|
|
6
|
+
export { MaterializerRuntime, defineMaterializer } from './packem_shared/MaterializerRuntime-BoIrsMYB.mjs';
|
|
7
7
|
export { applyDiffToDb, applyDiffsToDb } from './packem_shared/applyDiffToDb-DQ1xZp5J.mjs';
|
|
8
8
|
export { EventEmitter } from './packem_shared/EventEmitter-CMZfct03.mjs';
|
|
9
|
-
export { EventLog } from './packem_shared/EventLog-
|
|
10
|
-
export { EventLogDO } from './packem_shared/EventLogDO-
|
|
11
|
-
export { EventLogDOClient } from './packem_shared/EventLogDOClient-
|
|
12
|
-
export { EventSource } from './packem_shared/EventSource-
|
|
9
|
+
export { EventLog } from './packem_shared/EventLog-CnK-3Wge.mjs';
|
|
10
|
+
export { EventLogDO } from './packem_shared/EventLogDO-DqlsVx0H.mjs';
|
|
11
|
+
export { EventLogDOClient } from './packem_shared/EventLogDOClient-F4FO8Si4.mjs';
|
|
12
|
+
export { EventSource, UNHANDLED } from './packem_shared/EventSource-D5yO9_aI.mjs';
|
|
13
13
|
export { eventsContext } from './packem_shared/eventsContext-Bk_p48hj.mjs';
|
|
14
|
-
export { LocalMirror } from './packem_shared/LocalMirror-
|
|
14
|
+
export { LocalMirror } from './packem_shared/LocalMirror-a-5jEqFN.mjs';
|
|
15
15
|
export { isClientSeq, isGlobalSeq, isInputEvent } from './packem_shared/isClientSeq-C46BkzqJ.mjs';
|
|
16
16
|
export { InMemorySnapshotStore } from './packem_shared/InMemorySnapshotStore-BHVAD-Bp.mjs';
|
|
17
17
|
export { subscribeToMirror } from './packem_shared/subscribeToMirror-CiaM-nQ7.mjs';
|
|
18
18
|
export { SubscriptionManager } from './packem_shared/SubscriptionManager-C5xbw0pg.mjs';
|
|
19
|
-
export { EventsSync } from './packem_shared/EventsSync-
|
|
20
|
-
export { classifyChanges, createTableDiff, diffSize, isDiffEmpty, mergeDiffs } from './packem_shared/classifyChanges-
|
|
19
|
+
export { EventsSync } from './packem_shared/EventsSync-BP36tC9O.mjs';
|
|
20
|
+
export { classifyChanges, createTableDiff, diffSize, isDiffEmpty, mergeDiffs } from './packem_shared/classifyChanges-RcqLBpLs.mjs';
|