@zeroback/client 0.0.1

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 (41) hide show
  1. package/dist/Backoff.d.ts +10 -0
  2. package/dist/Backoff.d.ts.map +1 -0
  3. package/dist/Backoff.js +18 -0
  4. package/dist/Backoff.js.map +1 -0
  5. package/dist/ConvexClient.d.ts +57 -0
  6. package/dist/ConvexClient.d.ts.map +1 -0
  7. package/dist/ConvexClient.js +267 -0
  8. package/dist/ConvexClient.js.map +1 -0
  9. package/dist/Protocol.d.ts +50 -0
  10. package/dist/Protocol.d.ts.map +1 -0
  11. package/dist/Protocol.js +2 -0
  12. package/dist/Protocol.js.map +1 -0
  13. package/dist/QueryStore.d.ts +31 -0
  14. package/dist/QueryStore.d.ts.map +1 -0
  15. package/dist/QueryStore.js +111 -0
  16. package/dist/QueryStore.js.map +1 -0
  17. package/dist/SubscriptionRegistry.d.ts +15 -0
  18. package/dist/SubscriptionRegistry.d.ts.map +1 -0
  19. package/dist/SubscriptionRegistry.js +24 -0
  20. package/dist/SubscriptionRegistry.js.map +1 -0
  21. package/dist/ZerobackClient.d.ts +57 -0
  22. package/dist/ZerobackClient.d.ts.map +1 -0
  23. package/dist/ZerobackClient.js +267 -0
  24. package/dist/ZerobackClient.js.map +1 -0
  25. package/dist/index.d.ts +11 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +7 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/persistence/IDBPersistence.d.ts +21 -0
  30. package/dist/persistence/IDBPersistence.d.ts.map +1 -0
  31. package/dist/persistence/IDBPersistence.js +131 -0
  32. package/dist/persistence/IDBPersistence.js.map +1 -0
  33. package/dist/persistence/MutationQueue.d.ts +17 -0
  34. package/dist/persistence/MutationQueue.d.ts.map +1 -0
  35. package/dist/persistence/MutationQueue.js +73 -0
  36. package/dist/persistence/MutationQueue.js.map +1 -0
  37. package/dist/persistence/PersistenceAdapter.d.ts +11 -0
  38. package/dist/persistence/PersistenceAdapter.d.ts.map +1 -0
  39. package/dist/persistence/PersistenceAdapter.js +2 -0
  40. package/dist/persistence/PersistenceAdapter.js.map +1 -0
  41. package/package.json +26 -0
@@ -0,0 +1,57 @@
1
+ import { QueryStore } from "./QueryStore";
2
+ import type { LocalStore, QueryKey } from "./QueryStore";
3
+ import type { PersistenceAdapter } from "./persistence/PersistenceAdapter.js";
4
+ export type ConnectionState = "connecting" | "connected" | "disconnected";
5
+ export interface ZerobackClientOptions {
6
+ persistence?: boolean | PersistenceAdapter;
7
+ maxCacheAge?: number;
8
+ schemaVersion?: string;
9
+ }
10
+ export declare class ZerobackClient {
11
+ private ws;
12
+ private subscriptions;
13
+ private pendingRequests;
14
+ private url;
15
+ private backoff;
16
+ private isConnecting;
17
+ private messageQueue;
18
+ private closed;
19
+ private _connectionState;
20
+ private connectionListeners;
21
+ /** Centralized query result cache with optimistic update support. */
22
+ readonly queryStore: QueryStore;
23
+ /** Sequential mutation queue — ensures mutations execute one at a time in order. */
24
+ private mutationQueue;
25
+ private persistedMutationQueue;
26
+ private options;
27
+ constructor(url: string, options?: ZerobackClientOptions);
28
+ /**
29
+ * Initialize the client with persistence.
30
+ * Hydrates cached data from IndexedDB, connects the WebSocket, and replays
31
+ * any persisted offline mutations. Only needed when persistence is enabled.
32
+ */
33
+ init(): Promise<void>;
34
+ private replayPersistedMutations;
35
+ hasServerResult(key: QueryKey): boolean;
36
+ get connectionState(): ConnectionState;
37
+ onConnectionChange(listener: (state: ConnectionState) => void): () => void;
38
+ private setConnectionState;
39
+ private connect;
40
+ private scheduleReconnect;
41
+ /** Re-subscribe all active subscriptions after reconnect or server reset. */
42
+ private resubscribeAll;
43
+ private flushMessageQueue;
44
+ private send;
45
+ subscribe(fnName: string, args: unknown, callback?: (data: unknown) => void): () => void;
46
+ /** Subscribe to changes for a specific query key in the centralized store. */
47
+ watchQuery(key: QueryKey, listener: () => void): () => void;
48
+ /** Get the current (merged base + optimistic) result for a query key. */
49
+ getQueryResult(key: QueryKey): unknown | undefined;
50
+ mutation(fnName: string, args: unknown, opts?: {
51
+ optimisticUpdate?: (store: LocalStore) => void;
52
+ }): Promise<unknown>;
53
+ action(fnName: string, args: unknown): Promise<unknown>;
54
+ private handleMessage;
55
+ close(): void;
56
+ }
57
+ //# sourceMappingURL=ZerobackClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ZerobackClient.d.ts","sourceRoot":"","sources":["../src/ZerobackClient.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAI9E,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,CAAC;AAE1E,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,eAAe,CAGlB;IACL,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,gBAAgB,CAAmC;IAC3D,OAAO,CAAC,mBAAmB,CAA+C;IAE1E,qEAAqE;IACrE,QAAQ,CAAC,UAAU,aAAoB;IAEvC,oFAAoF;IACpF,OAAO,CAAC,aAAa,CAAoC;IAEzD,OAAO,CAAC,sBAAsB,CAA8B;IAC5D,OAAO,CAAC,OAAO,CAAwB;gBAE3B,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAqBxD;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAMb,wBAAwB;IAatC,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO;IAIvC,IAAI,eAAe,IAAI,eAAe,CAErC;IAED,kBAAkB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI;IAK1E,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,OAAO;IA6Cf,OAAO,CAAC,iBAAiB;IAczB,6EAA6E;IAC7E,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,IAAI;IAQZ,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI;IASxF,8EAA8E;IAC9E,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAI3D,yEAAyE;IACzE,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS;IAIlD,QAAQ,CACN,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;KAAE,GACxD,OAAO,CAAC,OAAO,CAAC;IAoCb,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ7D,OAAO,CAAC,aAAa;IAsDrB,KAAK,IAAI,IAAI;CAMd"}
@@ -0,0 +1,267 @@
1
+ import { SubscriptionRegistry } from "./SubscriptionRegistry";
2
+ import { Backoff } from "./Backoff";
3
+ import { QueryStore } from "./QueryStore";
4
+ import { IDBPersistence } from "./persistence/IDBPersistence.js";
5
+ import { MutationQueue } from "./persistence/MutationQueue.js";
6
+ export class ZerobackClient {
7
+ ws = null;
8
+ subscriptions;
9
+ pendingRequests = new Map();
10
+ url;
11
+ backoff = new Backoff();
12
+ isConnecting = false;
13
+ messageQueue = [];
14
+ closed = false;
15
+ _connectionState = "disconnected";
16
+ connectionListeners = new Set();
17
+ /** Centralized query result cache with optimistic update support. */
18
+ queryStore = new QueryStore();
19
+ /** Sequential mutation queue — ensures mutations execute one at a time in order. */
20
+ mutationQueue = Promise.resolve();
21
+ persistedMutationQueue = null;
22
+ options;
23
+ constructor(url, options) {
24
+ this.url = url;
25
+ this.options = options ?? {};
26
+ this.subscriptions = new SubscriptionRegistry();
27
+ if (this.options.persistence) {
28
+ const adapter = typeof this.options.persistence === "object"
29
+ ? this.options.persistence
30
+ : new IDBPersistence(url, {
31
+ maxCacheAge: this.options.maxCacheAge,
32
+ schemaVersion: this.options.schemaVersion,
33
+ });
34
+ this.queryStore.setPersistence(adapter);
35
+ this.persistedMutationQueue = new MutationQueue(url);
36
+ // When persistence is enabled, defer connect() to init()
37
+ }
38
+ else {
39
+ this.connect();
40
+ }
41
+ }
42
+ /**
43
+ * Initialize the client with persistence.
44
+ * Hydrates cached data from IndexedDB, connects the WebSocket, and replays
45
+ * any persisted offline mutations. Only needed when persistence is enabled.
46
+ */
47
+ async init() {
48
+ await this.queryStore.hydrate();
49
+ this.connect();
50
+ await this.replayPersistedMutations();
51
+ }
52
+ async replayPersistedMutations() {
53
+ if (!this.persistedMutationQueue)
54
+ return;
55
+ const pending = await this.persistedMutationQueue.getAll();
56
+ for (const m of pending) {
57
+ try {
58
+ await this.mutation(m.fnName, m.args);
59
+ }
60
+ catch {
61
+ // Mutation failed on replay — discard it
62
+ }
63
+ await this.persistedMutationQueue.remove(m.id);
64
+ }
65
+ }
66
+ hasServerResult(key) {
67
+ return this.queryStore.hasServerConfirmation(key);
68
+ }
69
+ get connectionState() {
70
+ return this._connectionState;
71
+ }
72
+ onConnectionChange(listener) {
73
+ this.connectionListeners.add(listener);
74
+ return () => this.connectionListeners.delete(listener);
75
+ }
76
+ setConnectionState(state) {
77
+ if (this._connectionState === state)
78
+ return;
79
+ this._connectionState = state;
80
+ for (const listener of this.connectionListeners) {
81
+ listener(state);
82
+ }
83
+ }
84
+ connect() {
85
+ if (this.closed || this.isConnecting || (this.ws?.readyState === WebSocket.OPEN)) {
86
+ return;
87
+ }
88
+ this.isConnecting = true;
89
+ this.setConnectionState("connecting");
90
+ try {
91
+ this.ws = new WebSocket(this.url);
92
+ }
93
+ catch {
94
+ this.isConnecting = false;
95
+ this.setConnectionState("disconnected");
96
+ this.scheduleReconnect();
97
+ return;
98
+ }
99
+ this.ws.onopen = () => {
100
+ this.isConnecting = false;
101
+ this.backoff.reset();
102
+ this.setConnectionState("connected");
103
+ this.resubscribeAll();
104
+ this.flushMessageQueue();
105
+ };
106
+ this.ws.onmessage = (event) => {
107
+ try {
108
+ const msg = JSON.parse(event.data);
109
+ this.handleMessage(msg);
110
+ }
111
+ catch {
112
+ // Ignore unparseable messages
113
+ }
114
+ };
115
+ this.ws.onclose = () => {
116
+ this.isConnecting = false;
117
+ this.setConnectionState("disconnected");
118
+ if (!this.closed)
119
+ this.scheduleReconnect();
120
+ };
121
+ this.ws.onerror = () => {
122
+ this.isConnecting = false;
123
+ };
124
+ }
125
+ scheduleReconnect() {
126
+ if (this.closed || !this.backoff.shouldRetry()) {
127
+ // Reject all pending requests on permanent disconnect
128
+ for (const [id, pending] of this.pendingRequests) {
129
+ pending.reject(new Error("Connection lost"));
130
+ this.pendingRequests.delete(id);
131
+ }
132
+ return;
133
+ }
134
+ const delay = this.backoff.next();
135
+ setTimeout(() => this.connect(), delay);
136
+ }
137
+ /** Re-subscribe all active subscriptions after reconnect or server reset. */
138
+ resubscribeAll() {
139
+ for (const sub of this.subscriptions.getAll()) {
140
+ this.send({ type: "query", id: sub.id, fn: sub.fnName, args: sub.args });
141
+ }
142
+ }
143
+ flushMessageQueue() {
144
+ while (this.messageQueue.length > 0) {
145
+ const msg = this.messageQueue.shift();
146
+ this.send(msg);
147
+ }
148
+ }
149
+ send(msg) {
150
+ if (this.ws?.readyState === WebSocket.OPEN) {
151
+ this.ws.send(JSON.stringify(msg));
152
+ }
153
+ else {
154
+ this.messageQueue.push(msg);
155
+ }
156
+ }
157
+ subscribe(fnName, args, callback) {
158
+ const subId = this.subscriptions.add(fnName, args, callback ?? (() => { }));
159
+ this.send({ type: "query", id: subId, fn: fnName, args });
160
+ return () => {
161
+ this.subscriptions.remove(subId);
162
+ this.send({ type: "unsubscribe", id: subId });
163
+ };
164
+ }
165
+ /** Subscribe to changes for a specific query key in the centralized store. */
166
+ watchQuery(key, listener) {
167
+ return this.queryStore.subscribe(key, listener);
168
+ }
169
+ /** Get the current (merged base + optimistic) result for a query key. */
170
+ getQueryResult(key) {
171
+ return this.queryStore.getResult(key);
172
+ }
173
+ mutation(fnName, args, opts) {
174
+ const id = crypto.randomUUID();
175
+ // Apply optimistic update immediately (before waiting in queue)
176
+ if (opts?.optimisticUpdate) {
177
+ this.queryStore.addLayer(id, opts.optimisticUpdate);
178
+ }
179
+ // Persist mutation for offline replay (fire-and-forget)
180
+ if (this.persistedMutationQueue) {
181
+ this.persistedMutationQueue.add({ id, fnName, args, timestamp: Date.now() }).catch(() => { });
182
+ }
183
+ // Chain onto the mutation queue so mutations execute sequentially
184
+ const result = this.mutationQueue.then(async () => {
185
+ try {
186
+ const res = await new Promise((resolve, reject) => {
187
+ this.pendingRequests.set(id, { resolve, reject });
188
+ this.send({ type: "mutation", id, fn: fnName, args });
189
+ });
190
+ // Mutation succeeded — remove from persisted queue
191
+ this.persistedMutationQueue?.remove(id).catch(() => { });
192
+ return res;
193
+ }
194
+ finally {
195
+ if (opts?.optimisticUpdate) {
196
+ this.queryStore.removeLayer(id);
197
+ }
198
+ }
199
+ });
200
+ // Update the queue — always resolve so subsequent mutations aren't blocked by failures
201
+ this.mutationQueue = result.then(() => { }, () => { });
202
+ return result;
203
+ }
204
+ async action(fnName, args) {
205
+ const id = crypto.randomUUID();
206
+ return new Promise((resolve, reject) => {
207
+ this.pendingRequests.set(id, { resolve, reject });
208
+ this.send({ type: "action", id, fn: fnName, args });
209
+ });
210
+ }
211
+ handleMessage(msg) {
212
+ switch (msg.type) {
213
+ case "result":
214
+ case "update": {
215
+ // Update centralized store
216
+ const sub = this.subscriptions.get(msg.id);
217
+ if (sub) {
218
+ const key = QueryStore.makeKey(sub.fnName, sub.args);
219
+ this.queryStore.setServerResult(key, msg.result);
220
+ }
221
+ // Also call subscription callback (for usePaginatedQuery and direct subscribers)
222
+ this.subscriptions.notify(msg.id, msg.result);
223
+ break;
224
+ }
225
+ case "updates":
226
+ for (const item of msg.items) {
227
+ const sub = this.subscriptions.get(item.id);
228
+ if (sub) {
229
+ const key = QueryStore.makeKey(sub.fnName, sub.args);
230
+ this.queryStore.setServerResult(key, item.result);
231
+ }
232
+ this.subscriptions.notify(item.id, item.result);
233
+ }
234
+ break;
235
+ case "mutationResult":
236
+ case "actionResult": {
237
+ const pending = this.pendingRequests.get(msg.id);
238
+ if (pending) {
239
+ pending.resolve(msg.result);
240
+ this.pendingRequests.delete(msg.id);
241
+ }
242
+ break;
243
+ }
244
+ case "error":
245
+ if (msg.id) {
246
+ const pending = this.pendingRequests.get(msg.id);
247
+ if (pending) {
248
+ pending.reject(new Error(msg.message));
249
+ this.pendingRequests.delete(msg.id);
250
+ }
251
+ }
252
+ break;
253
+ case "reset":
254
+ // Server lost subscription state (e.g. hibernation wake) — re-subscribe
255
+ this.queryStore.clearServerConfirmations();
256
+ this.resubscribeAll();
257
+ break;
258
+ }
259
+ }
260
+ close() {
261
+ this.closed = true;
262
+ this.ws?.close();
263
+ this.ws = null;
264
+ this.setConnectionState("disconnected");
265
+ }
266
+ }
267
+ //# sourceMappingURL=ZerobackClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ZerobackClient.js","sourceRoot":"","sources":["../src/ZerobackClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export { ZerobackClient } from "./ZerobackClient.js";
2
+ export type { ConnectionState, ZerobackClientOptions } from "./ZerobackClient.js";
3
+ export { SubscriptionRegistry } from "./SubscriptionRegistry.js";
4
+ export { Backoff } from "./Backoff.js";
5
+ export { QueryStore } from "./QueryStore.js";
6
+ export type { LocalStore } from "./QueryStore.js";
7
+ export type { ClientMessage, ServerMessage } from "./Protocol.js";
8
+ export type { PersistenceAdapter, CachedEntry } from "./persistence/PersistenceAdapter.js";
9
+ export { IDBPersistence } from "./persistence/IDBPersistence.js";
10
+ export { MutationQueue } from "./persistence/MutationQueue.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { ZerobackClient } from "./ZerobackClient.js";
2
+ export { SubscriptionRegistry } from "./SubscriptionRegistry.js";
3
+ export { Backoff } from "./Backoff.js";
4
+ export { QueryStore } from "./QueryStore.js";
5
+ export { IDBPersistence } from "./persistence/IDBPersistence.js";
6
+ export { MutationQueue } from "./persistence/MutationQueue.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAI7C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { CachedEntry, PersistenceAdapter } from "./PersistenceAdapter.js";
2
+ export interface IDBPersistenceOptions {
3
+ maxCacheAge?: number;
4
+ schemaVersion?: string;
5
+ }
6
+ export declare class IDBPersistence implements PersistenceAdapter {
7
+ private dbName;
8
+ private dbPromise;
9
+ private maxCacheAge;
10
+ private schemaVersion;
11
+ constructor(deploymentUrl: string, opts?: IDBPersistenceOptions);
12
+ private open;
13
+ getAll(): Promise<Map<string, CachedEntry>>;
14
+ set(key: string, entry: CachedEntry): Promise<void>;
15
+ delete(key: string): Promise<void>;
16
+ clear(): Promise<void>;
17
+ private getMeta;
18
+ private setMeta;
19
+ private getAllFromStore;
20
+ }
21
+ //# sourceMappingURL=IDBPersistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IDBPersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/IDBPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAM/E,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,cAAe,YAAW,kBAAkB;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAqB;gBAE9B,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB;IAM/D,OAAO,CAAC,IAAI;IAuBN,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IA6B3C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,eAAe;CAmBxB"}
@@ -0,0 +1,131 @@
1
+ const STORE_QUERY_CACHE = "queryCache";
2
+ const STORE_META = "meta";
3
+ const DB_VERSION = 1;
4
+ export class IDBPersistence {
5
+ dbName;
6
+ dbPromise = null;
7
+ maxCacheAge;
8
+ schemaVersion;
9
+ constructor(deploymentUrl, opts) {
10
+ this.dbName = "vex_" + hashString(deploymentUrl);
11
+ this.maxCacheAge = opts?.maxCacheAge ?? 7 * 24 * 60 * 60 * 1000; // 7 days
12
+ this.schemaVersion = opts?.schemaVersion;
13
+ }
14
+ open() {
15
+ if (this.dbPromise)
16
+ return this.dbPromise;
17
+ this.dbPromise = new Promise((resolve, reject) => {
18
+ const request = indexedDB.open(this.dbName, DB_VERSION);
19
+ request.onupgradeneeded = () => {
20
+ const db = request.result;
21
+ if (!db.objectStoreNames.contains(STORE_QUERY_CACHE)) {
22
+ db.createObjectStore(STORE_QUERY_CACHE);
23
+ }
24
+ if (!db.objectStoreNames.contains(STORE_META)) {
25
+ db.createObjectStore(STORE_META);
26
+ }
27
+ };
28
+ request.onsuccess = () => resolve(request.result);
29
+ request.onerror = () => reject(request.error);
30
+ });
31
+ return this.dbPromise;
32
+ }
33
+ async getAll() {
34
+ const db = await this.open();
35
+ // Check schema version — clear if mismatched
36
+ if (this.schemaVersion) {
37
+ const storedVersion = await this.getMeta(db, "schemaVersion");
38
+ if (storedVersion && storedVersion !== this.schemaVersion) {
39
+ await this.clear();
40
+ await this.setMeta(db, "schemaVersion", this.schemaVersion);
41
+ return new Map();
42
+ }
43
+ if (!storedVersion) {
44
+ await this.setMeta(db, "schemaVersion", this.schemaVersion);
45
+ }
46
+ }
47
+ const now = Date.now();
48
+ const result = new Map();
49
+ const entries = await this.getAllFromStore(db, STORE_QUERY_CACHE);
50
+ for (const [key, entry] of entries) {
51
+ if (now - entry.timestamp < this.maxCacheAge) {
52
+ result.set(key, entry);
53
+ }
54
+ }
55
+ return result;
56
+ }
57
+ async set(key, entry) {
58
+ const db = await this.open();
59
+ return new Promise((resolve, reject) => {
60
+ const tx = db.transaction(STORE_QUERY_CACHE, "readwrite");
61
+ tx.objectStore(STORE_QUERY_CACHE).put(entry, key);
62
+ tx.oncomplete = () => resolve();
63
+ tx.onerror = () => reject(tx.error);
64
+ });
65
+ }
66
+ async delete(key) {
67
+ const db = await this.open();
68
+ return new Promise((resolve, reject) => {
69
+ const tx = db.transaction(STORE_QUERY_CACHE, "readwrite");
70
+ tx.objectStore(STORE_QUERY_CACHE).delete(key);
71
+ tx.oncomplete = () => resolve();
72
+ tx.onerror = () => reject(tx.error);
73
+ });
74
+ }
75
+ async clear() {
76
+ const db = await this.open();
77
+ return new Promise((resolve, reject) => {
78
+ const storeNames = [STORE_QUERY_CACHE, STORE_META];
79
+ const tx = db.transaction(storeNames, "readwrite");
80
+ for (const name of storeNames) {
81
+ tx.objectStore(name).clear();
82
+ }
83
+ tx.oncomplete = () => resolve();
84
+ tx.onerror = () => reject(tx.error);
85
+ });
86
+ }
87
+ getMeta(db, key) {
88
+ return new Promise((resolve, reject) => {
89
+ const tx = db.transaction(STORE_META, "readonly");
90
+ const req = tx.objectStore(STORE_META).get(key);
91
+ req.onsuccess = () => resolve(req.result);
92
+ req.onerror = () => reject(req.error);
93
+ });
94
+ }
95
+ setMeta(db, key, value) {
96
+ return new Promise((resolve, reject) => {
97
+ const tx = db.transaction(STORE_META, "readwrite");
98
+ tx.objectStore(STORE_META).put(value, key);
99
+ tx.oncomplete = () => resolve();
100
+ tx.onerror = () => reject(tx.error);
101
+ });
102
+ }
103
+ getAllFromStore(db, storeName) {
104
+ return new Promise((resolve, reject) => {
105
+ const tx = db.transaction(storeName, "readonly");
106
+ const store = tx.objectStore(storeName);
107
+ const entries = [];
108
+ const cursor = store.openCursor();
109
+ cursor.onsuccess = () => {
110
+ const c = cursor.result;
111
+ if (c) {
112
+ entries.push([c.key, c.value]);
113
+ c.continue();
114
+ }
115
+ else {
116
+ resolve(entries);
117
+ }
118
+ };
119
+ cursor.onerror = () => reject(cursor.error);
120
+ });
121
+ }
122
+ }
123
+ function hashString(str) {
124
+ let hash = 0;
125
+ for (let i = 0; i < str.length; i++) {
126
+ const char = str.charCodeAt(i);
127
+ hash = ((hash << 5) - hash + char) | 0;
128
+ }
129
+ return Math.abs(hash).toString(36);
130
+ }
131
+ //# sourceMappingURL=IDBPersistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IDBPersistence.js","sourceRoot":"","sources":["../../src/persistence/IDBPersistence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface PersistedMutation {
2
+ id: string;
3
+ fnName: string;
4
+ args: unknown;
5
+ timestamp: number;
6
+ }
7
+ export declare class MutationQueue {
8
+ private dbName;
9
+ private dbPromise;
10
+ constructor(deploymentUrl: string);
11
+ private open;
12
+ add(mutation: PersistedMutation): Promise<void>;
13
+ remove(id: string): Promise<void>;
14
+ getAll(): Promise<PersistedMutation[]>;
15
+ clear(): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=MutationQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MutationQueue.d.ts","sourceRoot":"","sources":["../../src/persistence/MutationQueue.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAqC;gBAE1C,aAAa,EAAE,MAAM;IAIjC,OAAO,CAAC,IAAI;IAoBN,GAAG,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjC,MAAM,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAetC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAS7B"}
@@ -0,0 +1,73 @@
1
+ const STORE_PENDING_MUTATIONS = "pendingMutations";
2
+ const DB_VERSION = 1;
3
+ export class MutationQueue {
4
+ dbName;
5
+ dbPromise = null;
6
+ constructor(deploymentUrl) {
7
+ this.dbName = "vex_mutations_" + hashString(deploymentUrl);
8
+ }
9
+ open() {
10
+ if (this.dbPromise)
11
+ return this.dbPromise;
12
+ this.dbPromise = new Promise((resolve, reject) => {
13
+ const request = indexedDB.open(this.dbName, DB_VERSION);
14
+ request.onupgradeneeded = () => {
15
+ const db = request.result;
16
+ if (!db.objectStoreNames.contains(STORE_PENDING_MUTATIONS)) {
17
+ db.createObjectStore(STORE_PENDING_MUTATIONS, { keyPath: "id" });
18
+ }
19
+ };
20
+ request.onsuccess = () => resolve(request.result);
21
+ request.onerror = () => reject(request.error);
22
+ });
23
+ return this.dbPromise;
24
+ }
25
+ async add(mutation) {
26
+ const db = await this.open();
27
+ return new Promise((resolve, reject) => {
28
+ const tx = db.transaction(STORE_PENDING_MUTATIONS, "readwrite");
29
+ tx.objectStore(STORE_PENDING_MUTATIONS).put(mutation);
30
+ tx.oncomplete = () => resolve();
31
+ tx.onerror = () => reject(tx.error);
32
+ });
33
+ }
34
+ async remove(id) {
35
+ const db = await this.open();
36
+ return new Promise((resolve, reject) => {
37
+ const tx = db.transaction(STORE_PENDING_MUTATIONS, "readwrite");
38
+ tx.objectStore(STORE_PENDING_MUTATIONS).delete(id);
39
+ tx.oncomplete = () => resolve();
40
+ tx.onerror = () => reject(tx.error);
41
+ });
42
+ }
43
+ async getAll() {
44
+ const db = await this.open();
45
+ return new Promise((resolve, reject) => {
46
+ const tx = db.transaction(STORE_PENDING_MUTATIONS, "readonly");
47
+ const req = tx.objectStore(STORE_PENDING_MUTATIONS).getAll();
48
+ req.onsuccess = () => {
49
+ const mutations = req.result.sort((a, b) => a.timestamp - b.timestamp);
50
+ resolve(mutations);
51
+ };
52
+ req.onerror = () => reject(req.error);
53
+ });
54
+ }
55
+ async clear() {
56
+ const db = await this.open();
57
+ return new Promise((resolve, reject) => {
58
+ const tx = db.transaction(STORE_PENDING_MUTATIONS, "readwrite");
59
+ tx.objectStore(STORE_PENDING_MUTATIONS).clear();
60
+ tx.oncomplete = () => resolve();
61
+ tx.onerror = () => reject(tx.error);
62
+ });
63
+ }
64
+ }
65
+ function hashString(str) {
66
+ let hash = 0;
67
+ for (let i = 0; i < str.length; i++) {
68
+ const char = str.charCodeAt(i);
69
+ hash = ((hash << 5) - hash + char) | 0;
70
+ }
71
+ return Math.abs(hash).toString(36);
72
+ }
73
+ //# sourceMappingURL=MutationQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MutationQueue.js","sourceRoot":"","sources":["../../src/persistence/MutationQueue.ts"],"names":[],"mappings":"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"}