@gonvex/client 0.1.24 → 0.1.26

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/outbox.js ADDED
@@ -0,0 +1,324 @@
1
+ /**
2
+ * A durable, totally ordered mutation queue.
3
+ *
4
+ * The auto-incremented id is the enqueue order and is never reused while the
5
+ * database exists. `nextReady` may skip unrelated writes, but it never skips a
6
+ * lower-id write touching the same entity. An inflight entry remains a causal
7
+ * barrier until it is acknowledged, and `loadAll` recovers abandoned inflight
8
+ * work after a crash by returning it to pending.
9
+ *
10
+ * IndexedDB is an optimization for durability, not a prerequisite for the
11
+ * optimistic mutation path. Disabled or failed storage permanently degrades
12
+ * this instance to the same queue semantics in memory for the current session.
13
+ */
14
+ export class DexieMutationOutbox {
15
+ databaseName;
16
+ indexedDB;
17
+ keyRange;
18
+ listeners = new Set();
19
+ memoryEntries = new Map();
20
+ database;
21
+ databasePromise;
22
+ memoryOnly;
23
+ nextMemoryId = 1;
24
+ constructor(options = {}) {
25
+ this.databaseName = options.databaseName ?? "gonvex-outbox";
26
+ this.indexedDB = options.indexedDB;
27
+ this.keyRange = options.IDBKeyRange;
28
+ this.memoryOnly = options.enabled === false
29
+ || !(options.indexedDB ?? globalThis.indexedDB)
30
+ || !(options.IDBKeyRange ?? globalThis.IDBKeyRange);
31
+ }
32
+ async enqueue(mutation) {
33
+ const createdAt = Date.now();
34
+ const entry = {
35
+ path: mutation.path,
36
+ args: cloneValue(mutation.args),
37
+ idempotencyKey: mutation.idempotencyKey ?? createIdempotencyKey(),
38
+ entityKeys: [...(mutation.entityKeys ?? [])],
39
+ patches: mutation.patches?.map(clonePatch),
40
+ createdAt,
41
+ attempts: 0,
42
+ nextAttemptAt: createdAt,
43
+ state: "pending",
44
+ };
45
+ if (this.memoryOnly)
46
+ return this.enqueueInMemory(entry);
47
+ try {
48
+ const database = await this.open();
49
+ const id = await database.entries.add(entry);
50
+ const stored = { ...entry, id };
51
+ this.remember(stored);
52
+ this.notify();
53
+ return cloneEntry(stored);
54
+ }
55
+ catch {
56
+ this.degradeToMemory();
57
+ return this.enqueueInMemory(entry);
58
+ }
59
+ }
60
+ async loadAll() {
61
+ if (this.memoryOnly)
62
+ return this.loadAllFromMemory();
63
+ try {
64
+ const database = await this.open();
65
+ let changed = false;
66
+ let entries = [];
67
+ await database.transaction("rw", database.entries, async () => {
68
+ entries = await database.entries.orderBy("id").toArray();
69
+ entries = entries.map((entry) => {
70
+ if (entry.state !== "inflight")
71
+ return entry;
72
+ changed = true;
73
+ return { ...entry, state: "pending" };
74
+ });
75
+ if (changed)
76
+ await database.entries.bulkPut(entries);
77
+ });
78
+ this.replaceMemoryEntries(entries);
79
+ if (changed)
80
+ this.notify();
81
+ return entries.map(cloneEntry);
82
+ }
83
+ catch {
84
+ this.degradeToMemory();
85
+ return this.loadAllFromMemory();
86
+ }
87
+ }
88
+ async nextReady(now) {
89
+ if (this.memoryOnly)
90
+ return cloneOptionalEntry(firstReady(this.sortedMemoryEntries(), now));
91
+ try {
92
+ const database = await this.open();
93
+ const entries = await database.entries.orderBy("id").toArray();
94
+ this.replaceMemoryEntries(entries);
95
+ return cloneOptionalEntry(firstReady(entries, now));
96
+ }
97
+ catch {
98
+ this.degradeToMemory();
99
+ return cloneOptionalEntry(firstReady(this.sortedMemoryEntries(), now));
100
+ }
101
+ }
102
+ async markInflight(id) {
103
+ if (this.memoryOnly) {
104
+ this.markInflightInMemory(id);
105
+ return;
106
+ }
107
+ try {
108
+ const database = await this.open();
109
+ const entry = await database.entries.get(id);
110
+ if (!entry || entry.state === "inflight")
111
+ return;
112
+ const updated = { ...entry, state: "inflight" };
113
+ await database.entries.put(updated);
114
+ this.remember(updated);
115
+ this.notify();
116
+ }
117
+ catch {
118
+ this.degradeToMemory();
119
+ this.markInflightInMemory(id);
120
+ }
121
+ }
122
+ async ack(id) {
123
+ if (this.memoryOnly) {
124
+ this.ackInMemory(id);
125
+ return;
126
+ }
127
+ try {
128
+ const database = await this.open();
129
+ const entry = await database.entries.get(id);
130
+ if (!entry)
131
+ return;
132
+ await database.entries.delete(id);
133
+ this.memoryEntries.delete(id);
134
+ this.notify();
135
+ }
136
+ catch {
137
+ this.degradeToMemory();
138
+ this.ackInMemory(id);
139
+ }
140
+ }
141
+ async fail(id, error) {
142
+ if (this.memoryOnly) {
143
+ this.failInMemory(id, error);
144
+ return;
145
+ }
146
+ try {
147
+ const database = await this.open();
148
+ const entry = await database.entries.get(id);
149
+ if (!entry)
150
+ return;
151
+ const updated = failedEntry(entry, error, Date.now());
152
+ await database.entries.put(updated);
153
+ this.remember(updated);
154
+ this.notify();
155
+ }
156
+ catch {
157
+ this.degradeToMemory();
158
+ this.failInMemory(id, error);
159
+ }
160
+ }
161
+ async count() {
162
+ if (this.memoryOnly)
163
+ return this.memoryEntries.size;
164
+ try {
165
+ return await (await this.open()).entries.count();
166
+ }
167
+ catch {
168
+ this.degradeToMemory();
169
+ return this.memoryEntries.size;
170
+ }
171
+ }
172
+ subscribe(listener) {
173
+ this.listeners.add(listener);
174
+ return () => this.listeners.delete(listener);
175
+ }
176
+ enqueueInMemory(entry) {
177
+ const stored = { ...entry, id: this.nextMemoryId++ };
178
+ this.remember(stored);
179
+ this.notify();
180
+ return cloneEntry(stored);
181
+ }
182
+ loadAllFromMemory() {
183
+ let changed = false;
184
+ for (const [id, entry] of this.memoryEntries) {
185
+ if (entry.state !== "inflight")
186
+ continue;
187
+ this.memoryEntries.set(id, { ...entry, state: "pending" });
188
+ changed = true;
189
+ }
190
+ if (changed)
191
+ this.notify();
192
+ return this.sortedMemoryEntries().map(cloneEntry);
193
+ }
194
+ markInflightInMemory(id) {
195
+ const entry = this.memoryEntries.get(id);
196
+ if (!entry || entry.state === "inflight")
197
+ return;
198
+ this.memoryEntries.set(id, { ...entry, state: "inflight" });
199
+ this.notify();
200
+ }
201
+ ackInMemory(id) {
202
+ if (!this.memoryEntries.delete(id))
203
+ return;
204
+ this.notify();
205
+ }
206
+ failInMemory(id, error) {
207
+ const entry = this.memoryEntries.get(id);
208
+ if (!entry)
209
+ return;
210
+ this.memoryEntries.set(id, failedEntry(entry, error, Date.now()));
211
+ this.notify();
212
+ }
213
+ sortedMemoryEntries() {
214
+ return [...this.memoryEntries.values()].sort((left, right) => left.id - right.id);
215
+ }
216
+ remember(entry) {
217
+ this.memoryEntries.set(entry.id, cloneEntry(entry));
218
+ this.nextMemoryId = Math.max(this.nextMemoryId, entry.id + 1);
219
+ }
220
+ replaceMemoryEntries(entries) {
221
+ this.memoryEntries.clear();
222
+ for (const entry of entries)
223
+ this.remember(entry);
224
+ }
225
+ notify() {
226
+ for (const listener of this.listeners) {
227
+ try {
228
+ listener();
229
+ }
230
+ catch {
231
+ // A subscriber must not be able to break mutation delivery.
232
+ }
233
+ }
234
+ }
235
+ degradeToMemory() {
236
+ this.memoryOnly = true;
237
+ this.database?.close();
238
+ this.database = undefined;
239
+ this.databasePromise = undefined;
240
+ }
241
+ async open() {
242
+ if (!this.databasePromise) {
243
+ this.databasePromise = this.createDatabase().catch((error) => {
244
+ this.databasePromise = undefined;
245
+ throw error;
246
+ });
247
+ }
248
+ return this.databasePromise;
249
+ }
250
+ async createDatabase() {
251
+ const indexedDBValue = this.indexedDB ?? globalThis.indexedDB;
252
+ const keyRangeValue = this.keyRange ?? globalThis.IDBKeyRange;
253
+ if (!indexedDBValue || !keyRangeValue)
254
+ throw new Error("indexeddb-unavailable");
255
+ const { Dexie } = await import("dexie");
256
+ const database = new Dexie(this.databaseName, {
257
+ indexedDB: indexedDBValue,
258
+ IDBKeyRange: keyRangeValue,
259
+ });
260
+ database.version(1).stores({
261
+ entries: "++id, state, nextAttemptAt",
262
+ });
263
+ database.on("versionchange", () => database.close());
264
+ await database.open();
265
+ this.database = database;
266
+ return database;
267
+ }
268
+ }
269
+ export function createMutationOutbox(options = {}) {
270
+ return new DexieMutationOutbox(options);
271
+ }
272
+ function firstReady(entries, now) {
273
+ const blockedEntityKeys = new Set();
274
+ for (const entry of entries) {
275
+ if (entry.state === "pending"
276
+ && entry.nextAttemptAt <= now
277
+ && !entry.entityKeys.some((key) => blockedEntityKeys.has(key))) {
278
+ return entry;
279
+ }
280
+ for (const key of entry.entityKeys)
281
+ blockedEntityKeys.add(key);
282
+ }
283
+ return undefined;
284
+ }
285
+ function failedEntry(entry, error, now) {
286
+ const attempts = entry.attempts + 1;
287
+ return {
288
+ ...entry,
289
+ attempts,
290
+ state: "pending",
291
+ nextAttemptAt: now + Math.min(30_000, 1_000 * (2 ** attempts)),
292
+ lastError: error,
293
+ };
294
+ }
295
+ function createIdempotencyKey() {
296
+ if (globalThis.crypto?.randomUUID)
297
+ return globalThis.crypto.randomUUID();
298
+ return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
299
+ }
300
+ function cloneEntry(entry) {
301
+ return {
302
+ ...entry,
303
+ args: cloneValue(entry.args),
304
+ entityKeys: [...entry.entityKeys],
305
+ patches: entry.patches?.map(clonePatch),
306
+ };
307
+ }
308
+ function cloneOptionalEntry(entry) {
309
+ return entry ? cloneEntry(entry) : undefined;
310
+ }
311
+ function cloneValue(value) {
312
+ try {
313
+ return globalThis.structuredClone(value);
314
+ }
315
+ catch {
316
+ return value;
317
+ }
318
+ }
319
+ function clonePatch(patch) {
320
+ if (patch.op === "delete")
321
+ return { ...patch };
322
+ return { ...patch, fields: cloneValue(patch.fields) };
323
+ }
324
+ //# sourceMappingURL=outbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.js","sourceRoot":"","sources":["../src/outbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /** A writable reactive value. Reads use explicit `.value` access; no proxies. */
2
+ export interface Signal<T> extends ReadonlySignal<T> {
3
+ value: T;
4
+ }
5
+ /** The read-only surface shared by computed values and writable signals. */
6
+ export interface ReadonlySignal<T> {
7
+ readonly value: T;
8
+ /** Read the current value without making it a dependency of the active observer. */
9
+ peek(): T;
10
+ /** Listen for value changes. The returned function removes the listener. */
11
+ subscribe(fn: (value: T) => void): () => void;
12
+ }
13
+ /** Create a writable reactive value. */
14
+ export declare function signal<T>(initial: T): Signal<T>;
15
+ /** Create a lazy, cached value whose dependencies are discovered automatically. */
16
+ export declare function computed<T>(fn: () => T): ReadonlySignal<T>;
17
+ /** Run a callback now and again whenever one of the values it reads changes. */
18
+ export declare function effect(fn: () => void): () => void;
19
+ /** Coalesce subscriber callbacks and effect runs until the outermost batch ends. */
20
+ export declare function batch(fn: () => void): void;
@@ -0,0 +1,259 @@
1
+ /*
2
+ * Dependency collection uses a stack rather than a single global variable. A
3
+ * stack is important for computed chains: evaluating one computed may evaluate
4
+ * another, and reads must attach to the innermost evaluation in progress.
5
+ */
6
+ const evaluationStack = [];
7
+ let batchDepth = 0;
8
+ let isFlushing = false;
9
+ const pendingNotifications = new Set();
10
+ const pendingEffects = new Set();
11
+ /*
12
+ * A self-updating effect is allowed and is deferred until its current run has
13
+ * completed. To turn accidental `effect(() => count.value++)` loops into a
14
+ * useful error instead of locking the process, one effect may run at most this
15
+ * many times in a single synchronous flush.
16
+ */
17
+ const MAX_EFFECT_RUNS_PER_FLUSH = 100;
18
+ function track(dependency) {
19
+ const observer = evaluationStack[evaluationStack.length - 1];
20
+ if (observer === undefined || observer.disposed || observer.dependencies.has(dependency))
21
+ return;
22
+ observer.dependencies.add(dependency);
23
+ dependency.dependents.add(observer);
24
+ }
25
+ function detach(observer) {
26
+ for (const dependency of observer.dependencies)
27
+ dependency.dependents.delete(observer);
28
+ observer.dependencies.clear();
29
+ }
30
+ function queueNotification(node) {
31
+ pendingNotifications.add(node);
32
+ }
33
+ function queueEffect(observer) {
34
+ if (!observer.disposed)
35
+ pendingEffects.add(observer);
36
+ }
37
+ /** Flush synchronously unless a batch or reactive evaluation is still active. */
38
+ function flushIfReady() {
39
+ if (batchDepth === 0 && evaluationStack.length === 0 && !isFlushing)
40
+ flush();
41
+ }
42
+ function flush() {
43
+ if (isFlushing)
44
+ return;
45
+ isFlushing = true;
46
+ const effectRuns = new Map();
47
+ try {
48
+ // Subscribers run before effects. Either kind of callback may enqueue more
49
+ // work, so alternate until both insertion-ordered sets are empty.
50
+ while (pendingNotifications.size > 0 || pendingEffects.size > 0) {
51
+ if (pendingNotifications.size > 0) {
52
+ const notifications = Array.from(pendingNotifications);
53
+ pendingNotifications.clear();
54
+ for (const node of notifications)
55
+ node.notifySubscribers();
56
+ }
57
+ if (pendingEffects.size > 0) {
58
+ const effects = Array.from(pendingEffects);
59
+ pendingEffects.clear();
60
+ for (const observer of effects) {
61
+ if (observer.disposed)
62
+ continue;
63
+ const runs = (effectRuns.get(observer) ?? 0) + 1;
64
+ effectRuns.set(observer, runs);
65
+ if (runs > MAX_EFFECT_RUNS_PER_FLUSH) {
66
+ pendingEffects.clear();
67
+ throw new Error(`Effect exceeded ${MAX_EFFECT_RUNS_PER_FLUSH} synchronous re-runs`);
68
+ }
69
+ observer.run();
70
+ }
71
+ }
72
+ }
73
+ }
74
+ finally {
75
+ isFlushing = false;
76
+ }
77
+ }
78
+ class SignalNode {
79
+ current;
80
+ dependents = new Set();
81
+ subscribers = new Set();
82
+ constructor(current) {
83
+ this.current = current;
84
+ }
85
+ get value() {
86
+ track(this);
87
+ return this.current;
88
+ }
89
+ set value(next) {
90
+ if (Object.is(this.current, next))
91
+ return;
92
+ this.current = next;
93
+ // Invalidate the graph immediately. This keeps reads made inside a batch
94
+ // fresh, while actual callbacks remain coalesced until the batch ends.
95
+ for (const observer of Array.from(this.dependents))
96
+ observer.invalidate();
97
+ if (this.subscribers.size > 0)
98
+ queueNotification(this);
99
+ flushIfReady();
100
+ }
101
+ peek() {
102
+ return this.current;
103
+ }
104
+ subscribe(fn) {
105
+ this.subscribers.add(fn);
106
+ return () => {
107
+ this.subscribers.delete(fn);
108
+ };
109
+ }
110
+ notifySubscribers() {
111
+ // Checking membership makes disposal during an earlier callback effective
112
+ // immediately, even though iteration itself uses a stable snapshot.
113
+ for (const fn of Array.from(this.subscribers)) {
114
+ if (this.subscribers.has(fn))
115
+ fn(this.current);
116
+ }
117
+ }
118
+ }
119
+ class ComputedNode {
120
+ compute;
121
+ dependents = new Set();
122
+ dependencies = new Set();
123
+ disposed = false;
124
+ dirty = true;
125
+ evaluating = false;
126
+ initialized = false;
127
+ cached;
128
+ /*
129
+ * Each subscriber keeps its own last-seen value. This avoids reporting a
130
+ * change to a subscriber added midway through a batch, while still letting
131
+ * computed values stay lazy when nobody reads or subscribes to them.
132
+ */
133
+ subscribers = new Map();
134
+ constructor(compute) {
135
+ this.compute = compute;
136
+ }
137
+ get value() {
138
+ track(this);
139
+ return this.recompute();
140
+ }
141
+ peek() {
142
+ return this.recompute();
143
+ }
144
+ subscribe(fn) {
145
+ this.subscribers.set(fn, this.peek());
146
+ return () => {
147
+ this.subscribers.delete(fn);
148
+ };
149
+ }
150
+ invalidate() {
151
+ if (this.dirty)
152
+ return;
153
+ this.dirty = true;
154
+ // Propagating dirtiness (without recomputing) is what makes the graph
155
+ // pull-based and also lets the effect queue deduplicate diamond paths.
156
+ for (const observer of Array.from(this.dependents))
157
+ observer.invalidate();
158
+ if (this.subscribers.size > 0)
159
+ queueNotification(this);
160
+ }
161
+ notifySubscribers() {
162
+ const next = this.peek();
163
+ for (const [fn, previous] of Array.from(this.subscribers)) {
164
+ if (!this.subscribers.has(fn) || Object.is(previous, next))
165
+ continue;
166
+ this.subscribers.set(fn, next);
167
+ fn(next);
168
+ }
169
+ }
170
+ recompute() {
171
+ if (!this.dirty && this.initialized)
172
+ return this.cached;
173
+ if (this.evaluating)
174
+ throw new Error("Circular computed dependency");
175
+ detach(this);
176
+ this.evaluating = true;
177
+ // Clearing dirty before evaluation allows a write made during `compute` to
178
+ // invalidate this node again, leaving it dirty for the following read.
179
+ this.dirty = false;
180
+ evaluationStack.push(this);
181
+ try {
182
+ this.cached = this.compute();
183
+ this.initialized = true;
184
+ return this.cached;
185
+ }
186
+ catch (error) {
187
+ // Failed computations are retried on the next read.
188
+ this.dirty = true;
189
+ throw error;
190
+ }
191
+ finally {
192
+ evaluationStack.pop();
193
+ this.evaluating = false;
194
+ flushIfReady();
195
+ }
196
+ }
197
+ }
198
+ class EffectObserver {
199
+ callback;
200
+ dependencies = new Set();
201
+ disposed = false;
202
+ running = false;
203
+ constructor(callback) {
204
+ this.callback = callback;
205
+ }
206
+ invalidate() {
207
+ // If the callback writes one of its own dependencies, Set insertion queues
208
+ // exactly one follow-up run after the current invocation returns.
209
+ queueEffect(this);
210
+ }
211
+ run() {
212
+ if (this.disposed || this.running)
213
+ return;
214
+ detach(this);
215
+ this.running = true;
216
+ evaluationStack.push(this);
217
+ try {
218
+ this.callback();
219
+ }
220
+ finally {
221
+ evaluationStack.pop();
222
+ this.running = false;
223
+ }
224
+ }
225
+ dispose() {
226
+ if (this.disposed)
227
+ return;
228
+ this.disposed = true;
229
+ pendingEffects.delete(this);
230
+ detach(this);
231
+ }
232
+ }
233
+ /** Create a writable reactive value. */
234
+ export function signal(initial) {
235
+ return new SignalNode(initial);
236
+ }
237
+ /** Create a lazy, cached value whose dependencies are discovered automatically. */
238
+ export function computed(fn) {
239
+ return new ComputedNode(fn);
240
+ }
241
+ /** Run a callback now and again whenever one of the values it reads changes. */
242
+ export function effect(fn) {
243
+ const observer = new EffectObserver(fn);
244
+ observer.run();
245
+ flushIfReady();
246
+ return () => observer.dispose();
247
+ }
248
+ /** Coalesce subscriber callbacks and effect runs until the outermost batch ends. */
249
+ export function batch(fn) {
250
+ batchDepth += 1;
251
+ try {
252
+ fn();
253
+ }
254
+ finally {
255
+ batchDepth -= 1;
256
+ flushIfReady();
257
+ }
258
+ }
259
+ //# sourceMappingURL=signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../src/signals.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,8 @@ export type StoredSyncCollection = {
14
14
  cursor: SyncCursor;
15
15
  keyField: string;
16
16
  mode?: "eager" | "progressive";
17
+ /** Whether the server budget-cut the materialized collection. */
18
+ truncated?: boolean;
17
19
  orderBy?: string;
18
20
  orderDirection?: "asc" | "desc";
19
21
  maxRows?: number;
@@ -33,6 +35,8 @@ export type SyncStore = {
33
35
  applyDelta(scope: string, path: string, args: JsonValue, value: {
34
36
  cursor: SyncCursor;
35
37
  keyField: string;
38
+ mode?: "eager" | "progressive";
39
+ truncated?: boolean;
36
40
  orderBy?: string;
37
41
  orderDirection?: "asc" | "desc";
38
42
  upserts: JsonValue[];
@@ -63,6 +67,7 @@ export declare class DexieSyncStore implements SyncStore {
63
67
  cursor: SyncCursor;
64
68
  keyField: string;
65
69
  mode?: "eager" | "progressive";
70
+ truncated?: boolean;
66
71
  orderBy?: string;
67
72
  orderDirection?: "asc" | "desc";
68
73
  upserts: JsonValue[];