event-sourced-collection 0.0.12 → 0.0.13

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,121 @@
1
+ import { $ as InjectedCreateCollection, L as SyncLock, P as SQLiteDriver, et as InjectedModuleFn, p as EventSourcedSharedOptions } from "./types-uO49i9Ae.mjs";
2
+ import { r as ModulesInput, t as EventSourcedDBHandle } from "./create-event-sourced-db-handle-DmHdplVr.mjs";
3
+ import { PersistedCollectionPersistence } from "@tanstack/db-sqlite-persistence-core";
4
+
5
+ //#region src/platforms/browser-wa-sqlite-driver.d.ts
6
+ type BrowserWASQLiteDatabase = {
7
+ execute: <TRow = unknown>(sql: string, params?: ReadonlyArray<unknown>) => Promise<ReadonlyArray<TRow>>;
8
+ close?: () => Promise<void> | void;
9
+ };
10
+ //#endregion
11
+ //#region src/platforms/browser-types.d.ts
12
+ type BrowserCoordinatorInstance = {
13
+ dispose: () => void;
14
+ };
15
+ /**
16
+ * Injected TanStack browser persistence bindings. Parameters are `never` so
17
+ * version-skewed `@tanstack/browser-db-sqlite-persistence` exports stay assignable.
18
+ */
19
+ type BrowserPlatformDeps = {
20
+ openBrowserWASQLiteOPFSDatabase: (options: never) => Promise<BrowserWASQLiteDatabase>;
21
+ createBrowserWASQLitePersistence: (options: never) => PersistedCollectionPersistence;
22
+ BrowserCollectionCoordinator: new (options: never) => BrowserCoordinatorInstance;
23
+ };
24
+ type BrowserPlatformConfig = {
25
+ databaseName: string;
26
+ coordinatorDbName?: string;
27
+ };
28
+ type BrowserPlatformResult = {
29
+ driver: SQLiteDriver;
30
+ persistence: PersistedCollectionPersistence;
31
+ close: () => Promise<void>;
32
+ };
33
+ //#endregion
34
+ //#region src/platforms/browser-event-sourced-db.d.ts
35
+ type CollectionDefConstraint = {
36
+ getKey: (state: never) => string | number;
37
+ };
38
+ type BrowserEventSourcedModules = BrowserPlatformDeps & {
39
+ createCollection: InjectedCreateCollection;
40
+ persistedCollectionOptions: InjectedModuleFn;
41
+ };
42
+ /**
43
+ * Browser entry-point config. Shared sync/lifecycle fields come from
44
+ * {@link EventSourcedSharedOptions} (hover those properties for docs).
45
+ * Deep guide: `docs/usage.md`.
46
+ */
47
+ type BrowserEventSourcedDBConfig<TDefs extends Record<string, CollectionDefConstraint>> = Omit<EventSourcedSharedOptions, "lock" | "lockName"> & {
48
+ /**
49
+ * User collection registry. Object keys become `db.collections.<key>` and
50
+ * the wire `collectionId`. Must not collide with reserved names.
51
+ */
52
+ collections: TDefs;
53
+ /**
54
+ * OPFS SQLite database file name (e.g. `"my-app.sqlite"`). Also used as the
55
+ * default sync lock namespace so only one tab syncs for this DB at a time.
56
+ */
57
+ databaseName: string;
58
+ /**
59
+ * Name for the cross-tab collection coordinator database. Defaults to
60
+ * `databaseName` with a trailing `.sqlite` stripped.
61
+ */
62
+ coordinatorDbName?: string;
63
+ /**
64
+ * Browser OPFS persistence modules from
65
+ * `@tanstack/browser-db-sqlite-persistence` plus `createCollection`.
66
+ * Pass the imported bindings directly, or a function to keep WASM off the
67
+ * critical path.
68
+ */
69
+ modules: ModulesInput<BrowserEventSourcedModules>;
70
+ /**
71
+ * Defaults to a Web Locks–backed lock so only one tab syncs at a time.
72
+ * Pass `null` to opt out and let every tab sync independently.
73
+ */
74
+ lock?: SyncLock | null;
75
+ };
76
+ /**
77
+ * Browser-flavoured event-sourced DB: OPFS SQLite + optional Web Locks sync
78
+ * election, returned as a lazy singleton.
79
+ *
80
+ * @param config - See {@link BrowserEventSourcedDBConfig} for every option.
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * import { createBrowserEventSourcedDB } from "event-sourced-collection/browser"
85
+ * import type { CollectionDef, EventSourcedDB } from "event-sourced-collection"
86
+ *
87
+ * type Todo = { id: string; title: string }
88
+ * type Defs = { todos: CollectionDef<Todo, string> }
89
+ *
90
+ * const { ensureDb, db } = createBrowserEventSourcedDB<Defs>({
91
+ * databaseName: "app.sqlite",
92
+ * collections: { todos: { getKey: (todo) => todo.id } },
93
+ * sync: { push: "/api/sync/events", pull: "/api/sync/events" },
94
+ * modules: async () => {
95
+ * const { createCollection } = await import("@tanstack/db")
96
+ * const {
97
+ * BrowserCollectionCoordinator,
98
+ * createBrowserWASQLitePersistence,
99
+ * openBrowserWASQLiteOPFSDatabase,
100
+ * persistedCollectionOptions,
101
+ * } = await import("@tanstack/browser-db-sqlite-persistence")
102
+ * return {
103
+ * createCollection,
104
+ * BrowserCollectionCoordinator,
105
+ * createBrowserWASQLitePersistence,
106
+ * openBrowserWASQLiteOPFSDatabase,
107
+ * persistedCollectionOptions,
108
+ * }
109
+ * },
110
+ * })
111
+ *
112
+ * export async function start() {
113
+ * await ensureDb()
114
+ * }
115
+ * export { db }
116
+ * ```
117
+ */
118
+ declare function createBrowserEventSourcedDB<const TDefs extends Record<string, CollectionDefConstraint>>(config: BrowserEventSourcedDBConfig<TDefs>): EventSourcedDBHandle<TDefs>;
119
+ //#endregion
120
+ export { BrowserPlatformConfig as a, BrowserWASQLiteDatabase as c, BrowserCoordinatorInstance as i, BrowserEventSourcedModules as n, BrowserPlatformDeps as o, createBrowserEventSourcedDB as r, BrowserPlatformResult as s, BrowserEventSourcedDBConfig as t };
121
+ //# sourceMappingURL=browser-event-sourced-db-D3vSW3QV.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-event-sourced-db-D3vSW3QV.d.mts","names":[],"sources":["../src/platforms/browser-wa-sqlite-driver.ts","../src/platforms/browser-types.ts","../src/platforms/browser-event-sourced-db.ts"],"mappings":";;;;;KAEY,uBAAA;EACV,OAAA,mBACE,GAAA,UACA,MAAA,GAAS,aAAA,cACN,OAAA,CAAQ,aAAA,CAAc,IAAA;EAC3B,KAAA,SAAc,OAAA;AAAA;;;KCJJ,0BAAA;EACV,OAAO;AAAA;ADFT;;;;AAAA,KCSY,mBAAA;EACV,+BAAA,GAAkC,OAAA,YAAmB,OAAA,CAAQ,uBAAA;EAC7D,gCAAA,GAAmC,OAAA,YAAmB,8BAAA;EACtD,4BAAA,OAAmC,OAAA,YAAmB,0BAAA;AAAA;AAAA,KAG5C,qBAAA;EACV,YAAA;EACA,iBAAiB;AAAA;AAAA,KAGP,qBAAA;EACV,MAAA,EAD+B,YAAA;EAE/B,WAAA,EAAa,8BAAA;EACb,KAAA,QAAa,OAAA;AAAA;;;KCTV,uBAAA;EACH,MAAA,GAAS,KAAY;AAAA;AAAA,KAGX,0BAAA,GAA6B,mBAAA;EACvC,gBAAA,EAAkB,wBAAA;EAClB,0BAAA,EAA4B,gBAAA;AAAA;;;;;;KAQlB,2BAAA,eAA0C,MAAA,SAAe,uBAAA,KACnE,IAAA,CAAK,yBAAA;EF3BH;;;;EEgCA,WAAA,EAAa,KAAA;EF9BY;;;;EEmCzB,YAAA;;;;ADtCJ;EC2CI,iBAAA;;;AD1CK;AAOT;;;EC0CI,OAAA,EAAS,YAAA,CAAa,0BAAA;EDzC6B;;;;EC8CnD,IAAA,GAAO,QAAA;AAAA;;;;;;;;;;AD5CuE;AAGlF;;;;AAEmB;AAGnB;;;;;;;;;;;;;;;AAGsB;;;;ACZqC;;;;AAIpC;AAGvB;;;iBAqFgB,2BAAA,qBACM,MAAA,SAAe,uBAAA,GACnC,MAAA,EAAQ,2BAAA,CAA4B,KAAA,IAAM,oBAAA,CAAA,KAAA"}
@@ -1,36 +1,6 @@
1
- import { $ as InjectedCreateCollection, L as SyncLock, P as SQLiteDriver, et as InjectedModuleFn, p as EventSourcedSharedOptions } from "./types-DrV5f9_t.mjs";
2
- import { r as ModulesInput, t as EventSourcedDBHandle } from "./create-event-sourced-db-handle-Di5qN4QH.mjs";
3
- import { PersistedCollectionPersistence } from "@tanstack/db-sqlite-persistence-core";
1
+ import { a as BrowserPlatformConfig, c as BrowserWASQLiteDatabase, i as BrowserCoordinatorInstance, n as BrowserEventSourcedModules, o as BrowserPlatformDeps, r as createBrowserEventSourcedDB, s as BrowserPlatformResult, t as BrowserEventSourcedDBConfig } from "./browser-event-sourced-db-D3vSW3QV.mjs";
2
+ import { t as EventSourcedDBHandle } from "./create-event-sourced-db-handle-DmHdplVr.mjs";
4
3
 
5
- //#region src/platforms/browser-wa-sqlite-driver.d.ts
6
- type BrowserWASQLiteDatabase = {
7
- execute: <TRow = unknown>(sql: string, params?: ReadonlyArray<unknown>) => Promise<ReadonlyArray<TRow>>;
8
- close?: () => Promise<void> | void;
9
- };
10
- //#endregion
11
- //#region src/platforms/browser-types.d.ts
12
- type BrowserCoordinatorInstance = {
13
- dispose: () => void;
14
- };
15
- /**
16
- * Injected TanStack browser persistence bindings. Parameters are `never` so
17
- * version-skewed `@tanstack/browser-db-sqlite-persistence` exports stay assignable.
18
- */
19
- type BrowserPlatformDeps = {
20
- openBrowserWASQLiteOPFSDatabase: (options: never) => Promise<BrowserWASQLiteDatabase>;
21
- createBrowserWASQLitePersistence: (options: never) => PersistedCollectionPersistence;
22
- BrowserCollectionCoordinator: new (options: never) => BrowserCoordinatorInstance;
23
- };
24
- type BrowserPlatformConfig = {
25
- databaseName: string;
26
- coordinatorDbName?: string;
27
- };
28
- type BrowserPlatformResult = {
29
- driver: SQLiteDriver;
30
- persistence: PersistedCollectionPersistence;
31
- close: () => Promise<void>;
32
- };
33
- //#endregion
34
4
  //#region src/platforms/browser.d.ts
35
5
  /**
36
6
  * Opens OPFS SQLite, a cross-tab coordinator, and TanStack persistence.
@@ -61,91 +31,5 @@ type BrowserPlatformResult = {
61
31
  */
62
32
  declare function createBrowserPlatform(deps: BrowserPlatformDeps, config: BrowserPlatformConfig): Promise<BrowserPlatformResult>;
63
33
  //#endregion
64
- //#region src/platforms/browser-event-sourced-db.d.ts
65
- type CollectionDefConstraint = {
66
- getKey: (state: never) => string | number;
67
- };
68
- type BrowserEventSourcedModules = BrowserPlatformDeps & {
69
- createCollection: InjectedCreateCollection;
70
- persistedCollectionOptions: InjectedModuleFn;
71
- };
72
- /**
73
- * Browser entry-point config. Shared sync/lifecycle fields come from
74
- * {@link EventSourcedSharedOptions} (hover those properties for docs).
75
- * Deep guide: `docs/usage.md`.
76
- */
77
- type BrowserEventSourcedDBConfig<TDefs extends Record<string, CollectionDefConstraint>> = Omit<EventSourcedSharedOptions, "lock" | "lockName"> & {
78
- /**
79
- * User collection registry. Object keys become `db.collections.<key>` and
80
- * the wire `collectionId`. Must not collide with reserved names.
81
- */
82
- collections: TDefs;
83
- /**
84
- * OPFS SQLite database file name (e.g. `"my-app.sqlite"`). Also used as the
85
- * default sync lock namespace so only one tab syncs for this DB at a time.
86
- */
87
- databaseName: string;
88
- /**
89
- * Name for the cross-tab collection coordinator database. Defaults to
90
- * `databaseName` with a trailing `.sqlite` stripped.
91
- */
92
- coordinatorDbName?: string;
93
- /**
94
- * Browser OPFS persistence modules from
95
- * `@tanstack/browser-db-sqlite-persistence` plus `createCollection`.
96
- * Pass the imported bindings directly, or a function to keep WASM off the
97
- * critical path.
98
- */
99
- modules: ModulesInput<BrowserEventSourcedModules>;
100
- /**
101
- * Defaults to a Web Locks–backed lock so only one tab syncs at a time.
102
- * Pass `null` to opt out and let every tab sync independently.
103
- */
104
- lock?: SyncLock | null;
105
- };
106
- /**
107
- * Browser-flavoured event-sourced DB: OPFS SQLite + optional Web Locks sync
108
- * election, returned as a lazy singleton.
109
- *
110
- * @param config - See {@link BrowserEventSourcedDBConfig} for every option.
111
- *
112
- * @example
113
- * ```ts
114
- * import { createBrowserEventSourcedDB } from "event-sourced-collection/browser"
115
- * import type { CollectionDef, EventSourcedDB } from "event-sourced-collection"
116
- *
117
- * type Todo = { id: string; title: string }
118
- * type Defs = { todos: CollectionDef<Todo, string> }
119
- *
120
- * const { ensureDb, db } = createBrowserEventSourcedDB<Defs>({
121
- * databaseName: "app.sqlite",
122
- * collections: { todos: { getKey: (todo) => todo.id } },
123
- * sync: { push: "/api/sync/events", pull: "/api/sync/events" },
124
- * modules: async () => {
125
- * const { createCollection } = await import("@tanstack/db")
126
- * const {
127
- * BrowserCollectionCoordinator,
128
- * createBrowserWASQLitePersistence,
129
- * openBrowserWASQLiteOPFSDatabase,
130
- * persistedCollectionOptions,
131
- * } = await import("@tanstack/browser-db-sqlite-persistence")
132
- * return {
133
- * createCollection,
134
- * BrowserCollectionCoordinator,
135
- * createBrowserWASQLitePersistence,
136
- * openBrowserWASQLiteOPFSDatabase,
137
- * persistedCollectionOptions,
138
- * }
139
- * },
140
- * })
141
- *
142
- * export async function start() {
143
- * await ensureDb()
144
- * }
145
- * export { db }
146
- * ```
147
- */
148
- declare function createBrowserEventSourcedDB<const TDefs extends Record<string, CollectionDefConstraint>>(config: BrowserEventSourcedDBConfig<TDefs>): EventSourcedDBHandle<TDefs>;
149
- //#endregion
150
34
  export { type BrowserCoordinatorInstance, type BrowserEventSourcedDBConfig, type EventSourcedDBHandle as BrowserEventSourcedDBHandle, type BrowserEventSourcedModules, type BrowserPlatformConfig, type BrowserPlatformDeps, type BrowserPlatformResult, type BrowserWASQLiteDatabase, createBrowserEventSourcedDB, createBrowserPlatform };
151
35
  //# sourceMappingURL=browser.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.mts","names":[],"sources":["../src/platforms/browser-wa-sqlite-driver.ts","../src/platforms/browser-types.ts","../src/platforms/browser.ts","../src/platforms/browser-event-sourced-db.ts"],"mappings":";;;;;KAEY,uBAAA;EACV,OAAA,mBACE,GAAA,UACA,MAAA,GAAS,aAAA,cACN,OAAA,CAAQ,aAAA,CAAc,IAAA;EAC3B,KAAA,SAAc,OAAA;AAAA;;;KCJJ,0BAAA;EACV,OAAO;AAAA;;ADFT;;;KCSY,mBAAA;EACV,+BAAA,GAAkC,OAAA,YAAmB,OAAA,CAAQ,uBAAA;EAC7D,gCAAA,GAAmC,OAAA,YAAmB,8BAAA;EACtD,4BAAA,OAAmC,OAAA,YAAmB,0BAAA;AAAA;AAAA,KAG5C,qBAAA;EACV,YAAA;EACA,iBAAiB;AAAA;AAAA,KAGP,qBAAA;EACV,MAAA,EAD+B,YAAA;EAE/B,WAAA,EAAa,8BAAA;EACb,KAAA,QAAa,OAAA;AAAA;;;;;;ADvBf;;;;;;;;;;;;;;;;;;;;;AAKuB;;;iBEoCD,qBAAA,CACpB,IAAA,EAAM,mBAAA,EACN,MAAA,EAAQ,qBAAA,GACP,OAAA,CAAQ,qBAAA;;;KC9BN,uBAAA;EACH,MAAA,GAAS,KAAY;AAAA;AAAA,KAGX,0BAAA,GAA6B,mBAAA;EACvC,gBAAA,EAAkB,wBAAA;EAClB,0BAAA,EAA4B,gBAAA;AAAA;;;;;;KAQlB,2BAAA,eAA0C,MAAA,SAAe,uBAAA,KACnE,IAAA,CAAK,yBAAA;EH5BK;;;;EGiCR,WAAA,EAAa,KAAA;EH9BF;;;;EGmCX,YAAA;EHlCmB;;;;EGuCnB,iBAAA;EF3CkC;;;AAC7B;AAOT;;EE0CI,OAAA,EAAS,YAAA,CAAa,0BAAA;EFzCqC;;;;EE8C3D,IAAA,GAAO,QAAA;AAAA;;;;;;;;;;;AF5CuE;AAGlF;;;;AAEmB;AAGnB;;;;;;;;;;;;;;;AAGsB;;;;ACkBtB;;;;;;;iBC8DgB,2BAAA,qBACM,MAAA,SAAe,uBAAA,GACnC,MAAA,EAAQ,2BAAA,CAA4B,KAAA,IAAM,oBAAA,CAAA,KAAA"}
1
+ {"version":3,"file":"browser.d.mts","names":[],"sources":["../src/platforms/browser.ts"],"mappings":";;;;;AA2CA;;;;;;;;;;;;;;;;AAGgC;;;;;;;;;;iBAHV,qBAAA,CACpB,IAAA,EAAM,mBAAA,EACN,MAAA,EAAQ,qBAAA,GACP,OAAA,CAAQ,qBAAA"}
package/dist/browser.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as resolveModules, t as createEventSourcedDBHandle } from "./create-event-sourced-db-handle-CD8WSjXW.mjs";
1
+ import { n as resolveModules, t as createEventSourcedDBHandle } from "./create-event-sourced-db-handle-BqV3vLjS.mjs";
2
2
  import { t as createWebLocksSyncLock } from "./web-locks-Bi2f732X.mjs";
3
3
  //#region src/platforms/browser-wa-sqlite-driver.ts
4
4
  function assertTransactionCallbackHasDriverArg(fn) {
@@ -115,6 +115,22 @@ async function replayEvent(context, event) {
115
115
  reason
116
116
  };
117
117
  }
118
+ if (context.localOnlyIds.has(collectionId)) {
119
+ const reason = `local-only collection "${collectionId}"`;
120
+ log.debug("replay skipped: local-only collection", {
121
+ eventId,
122
+ collectionId
123
+ });
124
+ context.emit("onEventSkipped", {
125
+ eventId,
126
+ collectionId,
127
+ reason
128
+ });
129
+ return {
130
+ status: "skipped",
131
+ reason
132
+ };
133
+ }
118
134
  const migrated = upcast(context, event);
119
135
  if (migrated.status !== "ok") return migrated.outcome;
120
136
  const target = targets[collectionId];
@@ -1459,9 +1475,14 @@ async function createEventSourcedDB(config) {
1459
1475
  };
1460
1476
  const { outbox, inbox, deadletter, syncmeta, rowversions } = meta;
1461
1477
  const userCollections = {};
1478
+ const localOnlyIds = new Set(Object.keys(config.collections).filter((id) => config.collections[id].localOnly === true));
1462
1479
  for (const collectionId of Object.keys(config.collections)) {
1463
1480
  const def = config.collections[collectionId];
1464
1481
  const getKey = def.getKey;
1482
+ const hook = (type) => def.localOnly ? noOutboxHook : createMutationHook({
1483
+ ...mutationContext,
1484
+ type
1485
+ });
1465
1486
  const mutationContext = {
1466
1487
  outbox,
1467
1488
  rowversions,
@@ -1479,18 +1500,9 @@ async function createEventSourcedDB(config) {
1479
1500
  persistence: config.persistence,
1480
1501
  schemaVersion: def.schemaVersion ?? defaultSchemaVersion,
1481
1502
  gcTime: Number.POSITIVE_INFINITY,
1482
- onInsert: createMutationHook({
1483
- ...mutationContext,
1484
- type: "insert"
1485
- }),
1486
- onUpdate: createMutationHook({
1487
- ...mutationContext,
1488
- type: "update"
1489
- }),
1490
- onDelete: createMutationHook({
1491
- ...mutationContext,
1492
- type: "delete"
1493
- })
1503
+ onInsert: hook("insert"),
1504
+ onUpdate: hook("update"),
1505
+ onDelete: hook("delete")
1494
1506
  });
1495
1507
  const collection = config.createCollection(options);
1496
1508
  applyCollectionIndexes(collection, collectionId, def.indexes, log);
@@ -1532,8 +1544,10 @@ async function createEventSourcedDB(config) {
1532
1544
  clientId: clientId.value,
1533
1545
  pullCursor: readPullCursor(syncmeta, inbox)
1534
1546
  });
1547
+ for (const entry of [...outbox.state.values()]) if (!entry.sync && localOnlyIds.has(entry.collectionId)) await outbox.delete(entry.eventId).isPersisted.promise;
1535
1548
  const replayContext = {
1536
1549
  targets: replayTargets,
1550
+ localOnlyIds,
1537
1551
  rowversions,
1538
1552
  deadletter,
1539
1553
  unknownEventHandling,
@@ -1959,6 +1973,10 @@ function applyCollectionIndexes(collection, collectionId, indexes, log) {
1959
1973
  register();
1960
1974
  indexable.on?.("status:ready", register);
1961
1975
  }
1976
+ /** Handler for `localOnly` collections: persist locally, author no event. */
1977
+ async function noOutboxHook() {
1978
+ return {};
1979
+ }
1962
1980
  function createMutationHook(context) {
1963
1981
  const { outbox, rowversions, collectionId, type, seq, clientId, eventSchemaVersion, conflictDetection, emit, log } = context;
1964
1982
  return async (params) => {
@@ -2183,4 +2201,4 @@ async function resolveModules(modules) {
2183
2201
  //#endregion
2184
2202
  export { generateEventId as a, resolvePushLimits as c, createHttpTransport as d, BackendMismatchError as f, createEventSourcedDB as i, SyncPullError as l, resolveModules as n, createEventSourcedLogger as o, createLazySingleton as r, SYNC_PUSH_PRESETS as s, createEventSourcedDBHandle as t, SyncPushError as u };
2185
2203
 
2186
- //# sourceMappingURL=create-event-sourced-db-handle-CD8WSjXW.mjs.map
2204
+ //# sourceMappingURL=create-event-sourced-db-handle-BqV3vLjS.mjs.map