@gonvex/client 0.1.31 → 0.3.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.
Files changed (59) hide show
  1. package/README.md +119 -95
  2. package/dist/control.d.ts +416 -0
  3. package/dist/control.js +210 -0
  4. package/dist/control.js.map +1 -0
  5. package/dist/error-reporter.d.ts +20 -6
  6. package/dist/error-reporter.js +55 -27
  7. package/dist/error-reporter.js.map +1 -1
  8. package/dist/index.d.ts +170 -132
  9. package/dist/index.js +1123 -1138
  10. package/dist/index.js.map +1 -1
  11. package/dist/indexeddb-replica.d.ts +20 -0
  12. package/dist/indexeddb-replica.js +193 -0
  13. package/dist/indexeddb-replica.js.map +1 -0
  14. package/dist/kv-stores.d.ts +15 -0
  15. package/dist/kv-stores.js +60 -0
  16. package/dist/kv-stores.js.map +1 -0
  17. package/dist/local-replica.d.ts +240 -0
  18. package/dist/local-replica.js +590 -0
  19. package/dist/local-replica.js.map +1 -0
  20. package/dist/optimistic.d.ts +34 -55
  21. package/dist/optimistic.js +70 -269
  22. package/dist/optimistic.js.map +1 -1
  23. package/dist/outbox.d.ts +74 -16
  24. package/dist/outbox.js +194 -14
  25. package/dist/outbox.js.map +1 -1
  26. package/dist/query-expression.d.ts +58 -0
  27. package/dist/query-expression.js +164 -0
  28. package/dist/query-expression.js.map +1 -0
  29. package/dist/replica-integrity.d.ts +5 -0
  30. package/dist/replica-integrity.js +58 -0
  31. package/dist/replica-integrity.js.map +1 -0
  32. package/package.json +4 -4
  33. package/dist/browser-cache-client.d.ts +0 -77
  34. package/dist/browser-cache-client.js +0 -156
  35. package/dist/browser-cache-client.js.map +0 -1
  36. package/dist/browser-cache-shared-worker.d.ts +0 -35
  37. package/dist/browser-cache-shared-worker.js +0 -118
  38. package/dist/browser-cache-shared-worker.js.map +0 -1
  39. package/dist/browser-cache.d.ts +0 -43
  40. package/dist/browser-cache.js +0 -67
  41. package/dist/browser-cache.js.map +0 -1
  42. package/dist/browser-capabilities.d.ts +0 -21
  43. package/dist/browser-capabilities.js +0 -31
  44. package/dist/browser-capabilities.js.map +0 -1
  45. package/dist/cache-coordinator.d.ts +0 -37
  46. package/dist/cache-coordinator.js +0 -109
  47. package/dist/cache-coordinator.js.map +0 -1
  48. package/dist/cache.d.ts +0 -74
  49. package/dist/cache.js +0 -120
  50. package/dist/cache.js.map +0 -1
  51. package/dist/persistent-cache.d.ts +0 -41
  52. package/dist/persistent-cache.js +0 -103
  53. package/dist/persistent-cache.js.map +0 -1
  54. package/dist/query-cache.d.ts +0 -88
  55. package/dist/query-cache.js +0 -346
  56. package/dist/query-cache.js.map +0 -1
  57. package/dist/sync-store.d.ts +0 -96
  58. package/dist/sync-store.js +0 -500
  59. package/dist/sync-store.js.map +0 -1
@@ -1,22 +1,45 @@
1
- export type Row = Record<string, unknown>;
2
- export type OptimisticProjection = {
3
- entity: string;
4
- key: string;
5
- resultPath: readonly string[];
1
+ /** A path into reducer arguments, or a literal row identifier. */
2
+ export type OptimisticID = string | number | readonly string[];
3
+ export type OptimisticArgument = {
4
+ readonly $arg: string | readonly string[];
5
+ };
6
+ export type OptimisticValue = unknown | OptimisticArgument | readonly OptimisticValue[] | {
7
+ readonly [key: string]: OptimisticValue;
6
8
  };
7
- export type OptimisticMutationDefinition = {
9
+ export type OptimisticEffectDefinition = {
10
+ operation: "patch";
11
+ entity: string;
12
+ id: OptimisticID;
13
+ fields: Readonly<Record<string, OptimisticValue>>;
14
+ } | {
15
+ operation: "upsert";
8
16
  entity: string;
9
- rowIdPath: readonly string[];
10
- fieldsPath: readonly string[];
17
+ id: OptimisticID;
18
+ value: Readonly<Record<string, OptimisticValue>>;
19
+ } | {
20
+ operation: "delete";
21
+ entity: string;
22
+ id: OptimisticID;
23
+ };
24
+ /** Ordered effects from a module reducer's atomic optimistic transaction. */
25
+ export type OptimisticTransactionDefinition = {
26
+ effects: readonly OptimisticEffectDefinition[];
27
+ expectedRevision?: number;
11
28
  };
12
29
  type OptimisticRowPatch = {
13
- /** Canonical entity/table name. `collection` remains a compatibility alias. */
14
30
  entity?: string;
15
31
  collection?: string;
16
32
  rowId: string;
17
33
  op: "patch" | "insert";
18
34
  fields: Record<string, unknown>;
19
35
  };
36
+ type OptimisticUpsertPatch = {
37
+ entity?: string;
38
+ collection?: string;
39
+ rowId: string;
40
+ op: "upsert";
41
+ fields: Record<string, unknown>;
42
+ };
20
43
  type OptimisticDeletePatch = {
21
44
  entity?: string;
22
45
  collection?: string;
@@ -24,50 +47,6 @@ type OptimisticDeletePatch = {
24
47
  op: "delete";
25
48
  fields?: never;
26
49
  };
27
- export type OptimisticPatch = OptimisticRowPatch | OptimisticDeletePatch;
28
- /**
29
- * Ordered pending entity mutations layered over immutable authoritative data.
30
- *
31
- * A source is one concrete sync/query subscription (including its arguments).
32
- * Successful mutations remain pending until every source that exposed the
33
- * optimistic row reports that mutation id in an authoritative update. This
34
- * prevents a fast RPC acknowledgement from revealing an older subscription
35
- * snapshot while its invalidation is still in flight.
36
- */
37
- export declare class OptimisticOverlay {
38
- private readonly entries;
39
- private readonly listeners;
40
- private readonly cache;
41
- private version;
42
- private settling;
43
- add(mutationId: string, patches: OptimisticPatch[], options?: {
44
- accepted?: boolean;
45
- }): void;
46
- /** Reserve a live projection even when its first snapshot is still pending. */
47
- expectSource(source: string, entity: string): void;
48
- /** Mark the transport result successful without dropping visible optimism. */
49
- accept(mutationId: string): string[];
50
- /** Compatibility alias. Prefer accept followed by authoritative acknowledge. */
51
- settle(mutationId: string): void;
52
- /** Remove patches after a deterministic server rejection. */
53
- reject(mutationId: string): void;
54
- /**
55
- * Materialize entity rows for a concrete source. The three-argument overload
56
- * preserves the original collection-path API by using the entity as source.
57
- */
58
- apply(entity: string, rows: readonly Row[], keyField: string): Row[];
59
- apply(source: string, entity: string, rows: readonly Row[], keyField: string): Row[];
60
- /** Record authoritative delivery for a source; returns fully reconciled ids. */
61
- acknowledge(source: string, mutationIds: readonly string[] | undefined): string[];
62
- /** Reconcile restored committed entries against an authoritative snapshot. */
63
- acknowledgeMatching(source: string, entity: string, rows: readonly Row[], keyField: string): string[];
64
- /** Stop waiting for a subscription that no longer exists. */
65
- removeSource(source: string): string[];
66
- subscribe(listener: (entity: string) => void): () => void;
67
- pendingFor(entity: string, rowId: string): boolean;
68
- private settleReadyEntries;
69
- private remove;
70
- private changed;
71
- }
72
- export declare function optimisticPatchesFromReference(definition: OptimisticMutationDefinition | undefined, args: unknown): OptimisticPatch[];
50
+ export type OptimisticPatch = OptimisticRowPatch | OptimisticUpsertPatch | OptimisticDeletePatch;
51
+ export declare function optimisticPatchesFromReference(definition: OptimisticTransactionDefinition | undefined, args: unknown): OptimisticPatch[];
73
52
  export {};
@@ -1,287 +1,88 @@
1
- /**
2
- * Ordered pending entity mutations layered over immutable authoritative data.
3
- *
4
- * A source is one concrete sync/query subscription (including its arguments).
5
- * Successful mutations remain pending until every source that exposed the
6
- * optimistic row reports that mutation id in an authoritative update. This
7
- * prevents a fast RPC acknowledgement from revealing an older subscription
8
- * snapshot while its invalidation is still in flight.
9
- */
10
- export class OptimisticOverlay {
11
- entries = [];
12
- listeners = new Set();
13
- cache = new Map();
14
- version = 0;
15
- settling = false;
16
- add(mutationId, patches, options = {}) {
17
- const normalized = patches.map(clonePatch).filter((patch) => patchEntity(patch) !== "");
18
- if (normalized.length === 0)
19
- return;
20
- this.entries.push({
21
- mutationId,
22
- patches: normalized,
23
- accepted: options.accepted === true,
24
- targets: new Set(),
25
- acknowledgedTargets: new Set(),
26
- });
27
- this.changed(affectedEntities(normalized));
28
- }
29
- /** Reserve a live projection even when its first snapshot is still pending. */
30
- expectSource(source, entity) {
31
- let added = false;
32
- for (const entry of this.entries) {
33
- if (!entry.patches.some((patch) => patchEntity(patch) === entity))
34
- continue;
35
- if (entry.targets.has(source))
36
- continue;
37
- entry.targets.add(source);
38
- added = true;
39
- }
40
- if (!added)
41
- return;
42
- this.version += 1;
43
- this.cache.clear();
44
- }
45
- /** Mark the transport result successful without dropping visible optimism. */
46
- accept(mutationId) {
47
- const entry = this.entries.find((candidate) => candidate.mutationId === mutationId);
48
- if (!entry)
1
+ export function optimisticPatchesFromReference(definition, args) {
2
+ return isOptimisticTransactionDefinition(definition) ? optimisticPatchesFromTransaction(definition, args) : [];
3
+ }
4
+ function optimisticPatchesFromTransaction(transaction, args) {
5
+ if (!Array.isArray(transaction.effects) || transaction.effects.length === 0)
6
+ return [];
7
+ const record = isRecord(args) ? args : {};
8
+ const patches = [];
9
+ for (const effect of transaction.effects) {
10
+ if (!isOptimisticEffectDefinition(effect) || !effect.entity.trim())
49
11
  return [];
50
- entry.accepted = true;
51
- return this.settleReadyEntries();
52
- }
53
- /** Compatibility alias. Prefer accept followed by authoritative acknowledge. */
54
- settle(mutationId) {
55
- this.accept(mutationId);
56
- }
57
- /** Remove patches after a deterministic server rejection. */
58
- reject(mutationId) {
59
- this.remove(mutationId);
60
- }
61
- apply(sourceOrEntity, entityOrRows, rowsOrKey, maybeKey) {
62
- const legacy = Array.isArray(entityOrRows);
63
- const source = legacy ? sourceOrEntity : sourceOrEntity;
64
- const entity = legacy ? sourceOrEntity : entityOrRows;
65
- const rows = (legacy ? entityOrRows : rowsOrKey);
66
- const keyField = (legacy ? rowsOrKey : maybeKey);
67
- const cacheKey = `${source}\u0000${entity}`;
68
- const cached = this.cache.get(cacheKey);
69
- if (cached?.base === rows && cached.version === this.version)
70
- return cached.rows;
71
- let materialized = rows.slice();
72
- for (const entry of this.entries) {
73
- let touched = false;
74
- for (const patch of entry.patches) {
75
- if (patchEntity(patch) !== entity)
76
- continue;
77
- const index = materialized.findIndex((row) => {
78
- const key = row[keyField];
79
- return key !== null && key !== undefined && String(key) === patch.rowId;
80
- });
81
- if (patch.op === "patch") {
82
- if (index >= 0) {
83
- materialized[index] = { ...materialized[index], ...patch.fields };
84
- touched = true;
85
- }
86
- }
87
- else if (patch.op === "insert") {
88
- if (index < 0)
89
- materialized.push({ ...patch.fields, [keyField]: patch.rowId });
90
- touched = true;
91
- }
92
- else if (index >= 0) {
93
- materialized = [...materialized.slice(0, index), ...materialized.slice(index + 1)];
94
- touched = true;
95
- }
96
- }
97
- if (touched) {
98
- entry.targets.add(source);
99
- }
100
- else if (entry.targets.has(source)) {
101
- // The source cannot expose this row, so it is already reconciled from
102
- // that source's perspective.
103
- entry.acknowledgedTargets.add(source);
104
- }
105
- }
106
- this.cache.set(cacheKey, { base: rows, version: this.version, rows: materialized });
107
- return materialized;
108
- }
109
- /** Record authoritative delivery for a source; returns fully reconciled ids. */
110
- acknowledge(source, mutationIds) {
111
- if (!mutationIds?.length)
12
+ const rowId = optimisticRowId(effect.id, record);
13
+ if (!rowId)
112
14
  return [];
113
- const ids = new Set(mutationIds);
114
- for (const entry of this.entries) {
115
- if (ids.has(entry.mutationId) && entry.targets.has(source)) {
116
- entry.acknowledgedTargets.add(source);
117
- }
15
+ if (effect.operation === "delete") {
16
+ patches.push({ entity: effect.entity, rowId, op: "delete" });
17
+ continue;
118
18
  }
119
- return this.settleReadyEntries();
120
- }
121
- /** Reconcile restored committed entries against an authoritative snapshot. */
122
- acknowledgeMatching(source, entity, rows, keyField) {
123
- for (const entry of this.entries) {
124
- if (!entry.accepted || !entry.targets.has(source))
125
- continue;
126
- const patches = entry.patches.filter((patch) => {
127
- if (patchEntity(patch) !== entity)
128
- return false;
129
- if (patch.op === "delete")
130
- return patchMatchesRows(patch, rows, keyField);
131
- return rows.some((row) => {
132
- const key = row[keyField];
133
- return key !== null && key !== undefined && String(key) === patch.rowId;
134
- });
135
- });
136
- if (patches.length === 0 || !patches.every((patch) => patchMatchesRows(patch, rows, keyField)))
137
- continue;
138
- entry.acknowledgedTargets.add(source);
139
- }
140
- return this.settleReadyEntries();
141
- }
142
- /** Stop waiting for a subscription that no longer exists. */
143
- removeSource(source) {
144
- for (const entry of this.entries) {
145
- entry.targets.delete(source);
146
- entry.acknowledgedTargets.delete(source);
147
- }
148
- for (const key of this.cache.keys()) {
149
- if (key.startsWith(`${source}\u0000`))
150
- this.cache.delete(key);
151
- }
152
- return this.settleReadyEntries();
153
- }
154
- subscribe(listener) {
155
- this.listeners.add(listener);
156
- return () => this.listeners.delete(listener);
157
- }
158
- pendingFor(entity, rowId) {
159
- return this.entries.some((entry) => entry.patches.some((patch) => (patchEntity(patch) === entity && patch.rowId === rowId)));
160
- }
161
- settleReadyEntries() {
162
- // Removing an entry emits a new materialized snapshot. Query/sync
163
- // listeners may synchronously acknowledge that snapshot and re-enter this
164
- // method, so only the outer settlement pass is allowed to splice entries.
165
- // The nested acknowledgement still updates acknowledgedTargets; the outer
166
- // reverse loop observes that state when it reaches the remaining entry.
167
- if (this.settling)
19
+ const template = effect.operation === "patch" ? effect.fields : effect.value;
20
+ if (!isRecord(template))
168
21
  return [];
169
- this.settling = true;
170
- const settled = [];
171
- try {
172
- for (let index = this.entries.length - 1; index >= 0; index -= 1) {
173
- const entry = this.entries[index];
174
- if (!entry?.accepted)
175
- continue;
176
- if ([...entry.targets].some((target) => !entry.acknowledgedTargets.has(target)))
177
- continue;
178
- this.entries.splice(index, 1);
179
- settled.push(entry.mutationId);
180
- this.changed(affectedEntities(entry.patches));
181
- }
182
- return settled.reverse();
183
- }
184
- finally {
185
- this.settling = false;
186
- }
187
- }
188
- remove(mutationId) {
189
- const index = this.entries.findIndex((entry) => entry.mutationId === mutationId);
190
- if (index < 0)
191
- return;
192
- const [entry] = this.entries.splice(index, 1);
193
- this.changed(affectedEntities(entry.patches));
194
- }
195
- changed(entities) {
196
- this.version += 1;
197
- this.cache.clear();
198
- for (const entity of entities) {
199
- for (const listener of Array.from(this.listeners)) {
200
- try {
201
- listener(entity);
202
- }
203
- catch {
204
- // A view listener must not be able to break mutation delivery.
205
- }
206
- }
207
- }
22
+ const fields = resolveOptimisticValue(template, record);
23
+ if (!isRecord(fields) || containsUndefined(fields))
24
+ return [];
25
+ patches.push({ entity: effect.entity, rowId, op: effect.operation === "upsert" ? "upsert" : "patch", fields: normalizeOptimisticFields(fields) });
208
26
  }
27
+ return patches;
209
28
  }
210
- export function optimisticPatchesFromReference(definition, args) {
211
- if (!definition?.entity)
212
- return [];
213
- const record = isRecord(args) ? args : {};
214
- const configuredRowId = definition.rowIdPath.length > 0
215
- ? readPath(record, definition.rowIdPath)
216
- : undefined;
217
- const rowId = String(configuredRowId ?? record.id ?? record._id ?? "");
218
- const nested = readPath(record, definition.fieldsPath);
219
- if (!rowId || !isRecord(nested))
220
- return [];
221
- return [{
222
- entity: definition.entity,
223
- rowId,
224
- op: "patch",
225
- fields: normalizeOptimisticFields(nested),
226
- }];
29
+ function resolveOptimisticValue(value, args) {
30
+ if (Array.isArray(value))
31
+ return value.map((item) => resolveOptimisticValue(item, args));
32
+ if (!isRecord(value))
33
+ return value;
34
+ if (Object.keys(value).length === 1 && Object.prototype.hasOwnProperty.call(value, "$arg")) {
35
+ const path = value.$arg;
36
+ const segments = Array.isArray(path)
37
+ ? path.filter((part) => typeof part === "string" && part.trim().length > 0)
38
+ : typeof path === "string" ? path.split(".").map((part) => part.trim()).filter(Boolean) : [];
39
+ return segments.length > 0 ? readPath(args, segments) : undefined;
40
+ }
41
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, resolveOptimisticValue(item, args)]));
227
42
  }
228
- function normalizeOptimisticFields(fields) {
229
- const normalized = { ...fields };
230
- for (const [key, value] of Object.entries(fields)) {
231
- const camel = key.replace(/_([a-z0-9])/g, (_, character) => character.toUpperCase());
232
- if (!(camel in normalized))
233
- normalized[camel] = value;
234
- }
235
- return normalized;
43
+ function containsUndefined(value) {
44
+ if (value === undefined)
45
+ return true;
46
+ if (Array.isArray(value))
47
+ return value.some(containsUndefined);
48
+ return isRecord(value) && Object.values(value).some(containsUndefined);
49
+ }
50
+ function optimisticRowId(id, args) {
51
+ const value = Array.isArray(id) ? readPath(args, id) : id;
52
+ return typeof value === "string" || typeof value === "number" ? String(value).trim() : "";
53
+ }
54
+ function isOptimisticTransactionDefinition(value) {
55
+ return isRecord(value) && Array.isArray(value.effects);
56
+ }
57
+ function isOptimisticEffectDefinition(value) {
58
+ if (!isRecord(value) || (value.operation !== "patch" && value.operation !== "upsert" && value.operation !== "delete"))
59
+ return false;
60
+ if (typeof value.entity !== "string" || (typeof value.id !== "string" && typeof value.id !== "number" && !Array.isArray(value.id)))
61
+ return false;
62
+ if (Array.isArray(value.id) && value.id.some((part) => typeof part !== "string" || !part.trim()))
63
+ return false;
64
+ return value.operation === "delete" || isRecord(value.operation === "patch" ? value.fields : value.value);
65
+ }
66
+ function isRecord(value) {
67
+ return value !== null && typeof value === "object" && !Array.isArray(value);
236
68
  }
237
69
  function readPath(value, path) {
238
70
  let current = value;
239
- for (const segment of path) {
71
+ for (const part of path) {
240
72
  if (!isRecord(current))
241
73
  return undefined;
242
- current = current[segment];
74
+ current = current[part];
243
75
  }
244
76
  return current;
245
77
  }
246
- function isRecord(value) {
247
- return !!value && typeof value === "object" && !Array.isArray(value);
248
- }
249
- function patchEntity(patch) {
250
- return String(patch.entity ?? patch.collection ?? "");
251
- }
252
- function affectedEntities(patches) {
253
- return new Set(patches.map(patchEntity).filter(Boolean));
78
+ function normalizeOptimisticFields(value) {
79
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, normalizeOptimisticValue(item)]));
254
80
  }
255
- function clonePatch(patch) {
256
- if (patch.op === "delete")
257
- return { ...patch };
258
- return { ...patch, fields: { ...patch.fields } };
259
- }
260
- function patchMatchesRows(patch, rows, keyField) {
261
- const row = rows.find((candidate) => {
262
- const key = candidate[keyField];
263
- return key !== null && key !== undefined && String(key) === patch.rowId;
264
- });
265
- if (patch.op === "delete")
266
- return row === undefined;
267
- if (!row)
268
- return false;
269
- return Object.entries(patch.fields).every(([key, value]) => valuesEqual(row[key], value));
270
- }
271
- function valuesEqual(left, right) {
272
- if (Object.is(left, right))
273
- return true;
274
- if (Array.isArray(left) || Array.isArray(right)) {
275
- return Array.isArray(left)
276
- && Array.isArray(right)
277
- && left.length === right.length
278
- && left.every((value, index) => valuesEqual(value, right[index]));
279
- }
280
- if (!isRecord(left) || !isRecord(right))
281
- return false;
282
- const leftKeys = Object.keys(left).sort();
283
- const rightKeys = Object.keys(right).sort();
284
- return leftKeys.length === rightKeys.length
285
- && leftKeys.every((key, index) => key === rightKeys[index] && valuesEqual(left[key], right[key]));
81
+ function normalizeOptimisticValue(value) {
82
+ if (Array.isArray(value))
83
+ return value.map(normalizeOptimisticValue);
84
+ if (!isRecord(value))
85
+ return value;
86
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, normalizeOptimisticValue(item)]));
286
87
  }
287
88
  //# sourceMappingURL=optimistic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"optimistic.js","sourceRoot":"","sources":["../src/optimistic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"optimistic.js","sourceRoot":"","sources":["../src/optimistic.ts"],"names":[],"mappings":"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"}
package/dist/outbox.d.ts CHANGED
@@ -1,14 +1,34 @@
1
1
  import type { OptimisticPatch } from "./optimistic.js";
2
- export type MutationOutboxOptions = {
2
+ export type ReducerOutboxOptions = {
3
3
  databaseName?: string;
4
4
  indexedDB?: IDBFactory;
5
5
  IDBKeyRange?: typeof IDBKeyRange;
6
6
  enabled?: boolean;
7
+ /**
8
+ * Injectable durable record storage for runtimes without IndexedDB (React
9
+ * Native). When provided, the queue semantics still run in the SDK; the
10
+ * store only persists entries so they survive an app restart.
11
+ */
12
+ store?: OutboxStore;
7
13
  };
8
- export type MutationOutboxEntry = {
14
+ /**
15
+ * A dumb durable record store backing {@link StoreReducerOutbox}. It holds
16
+ * whole entries keyed by id and knows nothing about queue semantics — total
17
+ * order, causal barriers, and inflight recovery all stay in the SDK.
18
+ */
19
+ export type OutboxStore = {
20
+ /** Every persisted entry across all scopes; called once to hydrate. */
21
+ load(): Promise<ReducerOutboxEntry[]>;
22
+ /** Insert or replace the entry with this id. */
23
+ put(entry: ReducerOutboxEntry): Promise<void>;
24
+ delete(id: number): Promise<void>;
25
+ clear(scope?: string): Promise<void>;
26
+ close?(): void;
27
+ };
28
+ export type ReducerOutboxEntry = {
9
29
  /** Auto-incremented sequence number. Lower ids always happened first. */
10
30
  id: number;
11
- /** Authenticated project/tenant/user identity that owns this mutation. */
31
+ /** Authenticated project/tenant/user identity that owns this reducer. */
12
32
  scope: string;
13
33
  path: string;
14
34
  args: unknown;
@@ -23,7 +43,7 @@ export type MutationOutboxEntry = {
23
43
  lastError?: string;
24
44
  state: "pending" | "inflight" | "committed";
25
45
  };
26
- export type EnqueueMutation = {
46
+ export type EnqueueReducer = {
27
47
  scope: string;
28
48
  path: string;
29
49
  args: unknown;
@@ -33,10 +53,10 @@ export type EnqueueMutation = {
33
53
  /** Direct online sends start inflight so the background drain cannot race them. */
34
54
  state?: "pending" | "inflight";
35
55
  };
36
- export type MutationOutbox = {
37
- enqueue(mutation: EnqueueMutation): Promise<MutationOutboxEntry>;
38
- loadAll(scope: string): Promise<MutationOutboxEntry[]>;
39
- nextReady(scope: string, now: number): Promise<MutationOutboxEntry | undefined>;
56
+ export type ReducerOutbox = {
57
+ enqueue(reducer: EnqueueReducer): Promise<ReducerOutboxEntry>;
58
+ loadAll(scope: string): Promise<ReducerOutboxEntry[]>;
59
+ nextReady(scope: string, now: number): Promise<ReducerOutboxEntry | undefined>;
40
60
  markInflight(id: number): Promise<void>;
41
61
  markCommitted(id: number): Promise<void>;
42
62
  ack(id: number): Promise<void>;
@@ -46,7 +66,7 @@ export type MutationOutbox = {
46
66
  subscribe(listener: () => void): () => void;
47
67
  };
48
68
  /**
49
- * A durable, totally ordered mutation queue.
69
+ * A durable, totally ordered reducer queue.
50
70
  *
51
71
  * The auto-incremented id is the enqueue order and is never reused while the
52
72
  * database exists. `nextReady` may skip unrelated writes, but it never skips a
@@ -55,10 +75,10 @@ export type MutationOutbox = {
55
75
  * work after a crash by returning it to pending.
56
76
  *
57
77
  * IndexedDB is an optimization for durability, not a prerequisite for the
58
- * optimistic mutation path. Disabled or failed storage permanently degrades
78
+ * optimistic reducer path. Disabled or failed storage permanently degrades
59
79
  * this instance to the same queue semantics in memory for the current session.
60
80
  */
61
- export declare class DexieMutationOutbox implements MutationOutbox {
81
+ export declare class DexieReducerOutbox implements ReducerOutbox {
62
82
  private readonly databaseName;
63
83
  private readonly indexedDB?;
64
84
  private readonly keyRange?;
@@ -68,10 +88,10 @@ export declare class DexieMutationOutbox implements MutationOutbox {
68
88
  private databasePromise?;
69
89
  private memoryOnly;
70
90
  private nextMemoryId;
71
- constructor(options?: MutationOutboxOptions);
72
- enqueue(mutation: EnqueueMutation): Promise<MutationOutboxEntry>;
73
- loadAll(scope: string): Promise<MutationOutboxEntry[]>;
74
- nextReady(scope: string, now: number): Promise<MutationOutboxEntry | undefined>;
91
+ constructor(options?: ReducerOutboxOptions);
92
+ enqueue(reducer: EnqueueReducer): Promise<ReducerOutboxEntry>;
93
+ loadAll(scope: string): Promise<ReducerOutboxEntry[]>;
94
+ nextReady(scope: string, now: number): Promise<ReducerOutboxEntry | undefined>;
75
95
  markInflight(id: number): Promise<void>;
76
96
  markCommitted(id: number): Promise<void>;
77
97
  ack(id: number): Promise<void>;
@@ -93,4 +113,42 @@ export declare class DexieMutationOutbox implements MutationOutbox {
93
113
  private open;
94
114
  private createDatabase;
95
115
  }
96
- export declare function createMutationOutbox(options?: MutationOutboxOptions): MutationOutbox;
116
+ /**
117
+ * The same totally ordered queue semantics as {@link DexieReducerOutbox},
118
+ * run entirely in memory with every state transition written through an
119
+ * injected {@link OutboxStore}. Hydration replays `store.load()` once and
120
+ * seeds the auto-increment id from the highest persisted id, so replayed
121
+ * entries keep their original ids, idempotency keys, and enqueue order.
122
+ *
123
+ * The store is an optimization for durability, not a prerequisite for the
124
+ * optimistic reducer path. A failing store permanently degrades this
125
+ * instance to the same queue semantics in memory for the current session.
126
+ */
127
+ export declare class StoreReducerOutbox implements ReducerOutbox {
128
+ private readonly store;
129
+ private readonly listeners;
130
+ private readonly entries;
131
+ private readonly ready;
132
+ private memoryOnly;
133
+ private nextId;
134
+ constructor(store: OutboxStore, options?: {
135
+ enabled?: boolean;
136
+ });
137
+ enqueue(reducer: EnqueueReducer): Promise<ReducerOutboxEntry>;
138
+ loadAll(scope: string): Promise<ReducerOutboxEntry[]>;
139
+ nextReady(scope: string, now: number): Promise<ReducerOutboxEntry | undefined>;
140
+ markInflight(id: number): Promise<void>;
141
+ markCommitted(id: number): Promise<void>;
142
+ ack(id: number): Promise<void>;
143
+ fail(id: number, error: string): Promise<void>;
144
+ count(scope: string): Promise<number>;
145
+ clear(scope: string): Promise<void>;
146
+ subscribe(listener: () => void): () => void;
147
+ private hydrate;
148
+ private persistPut;
149
+ private persistDelete;
150
+ private sortedEntries;
151
+ private notify;
152
+ private degradeToMemory;
153
+ }
154
+ export declare function createReducerOutbox(options?: ReducerOutboxOptions): ReducerOutbox;