@gonvex/client 0.1.32 → 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.
- package/README.md +119 -95
- package/dist/control.d.ts +416 -0
- package/dist/control.js +210 -0
- package/dist/control.js.map +1 -0
- package/dist/error-reporter.d.ts +20 -6
- package/dist/error-reporter.js +55 -27
- package/dist/error-reporter.js.map +1 -1
- package/dist/index.d.ts +166 -133
- package/dist/index.js +1114 -1139
- package/dist/index.js.map +1 -1
- package/dist/indexeddb-replica.d.ts +20 -0
- package/dist/indexeddb-replica.js +193 -0
- package/dist/indexeddb-replica.js.map +1 -0
- package/dist/kv-stores.d.ts +2 -48
- package/dist/kv-stores.js +24 -411
- package/dist/kv-stores.js.map +1 -1
- package/dist/local-replica.d.ts +240 -0
- package/dist/local-replica.js +590 -0
- package/dist/local-replica.js.map +1 -0
- package/dist/optimistic.d.ts +34 -55
- package/dist/optimistic.js +70 -269
- package/dist/optimistic.js.map +1 -1
- package/dist/outbox.d.ts +25 -25
- package/dist/outbox.js +27 -27
- package/dist/outbox.js.map +1 -1
- package/dist/query-expression.d.ts +58 -0
- package/dist/query-expression.js +164 -0
- package/dist/query-expression.js.map +1 -0
- package/dist/replica-integrity.d.ts +5 -0
- package/dist/replica-integrity.js +58 -0
- package/dist/replica-integrity.js.map +1 -0
- package/package.json +4 -4
- package/dist/browser-cache-client.d.ts +0 -77
- package/dist/browser-cache-client.js +0 -156
- package/dist/browser-cache-client.js.map +0 -1
- package/dist/browser-cache-shared-worker.d.ts +0 -35
- package/dist/browser-cache-shared-worker.js +0 -118
- package/dist/browser-cache-shared-worker.js.map +0 -1
- package/dist/browser-cache.d.ts +0 -43
- package/dist/browser-cache.js +0 -67
- package/dist/browser-cache.js.map +0 -1
- package/dist/browser-capabilities.d.ts +0 -21
- package/dist/browser-capabilities.js +0 -31
- package/dist/browser-capabilities.js.map +0 -1
- package/dist/cache-coordinator.d.ts +0 -37
- package/dist/cache-coordinator.js +0 -109
- package/dist/cache-coordinator.js.map +0 -1
- package/dist/cache.d.ts +0 -74
- package/dist/cache.js +0 -120
- package/dist/cache.js.map +0 -1
- package/dist/persistent-cache.d.ts +0 -41
- package/dist/persistent-cache.js +0 -103
- package/dist/persistent-cache.js.map +0 -1
- package/dist/query-cache.d.ts +0 -88
- package/dist/query-cache.js +0 -346
- package/dist/query-cache.js.map +0 -1
- package/dist/sync-store.d.ts +0 -96
- package/dist/sync-store.js +0 -500
- package/dist/sync-store.js.map +0 -1
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import type { JsonValue, ReplicaCursor, SubscriptionRevision } from "@gonvex/protocol";
|
|
2
|
+
import type { OptimisticPatch } from "./optimistic.js";
|
|
3
|
+
export type ReplicaRow = Record<string, JsonValue>;
|
|
4
|
+
export type ReplicaChange = {
|
|
5
|
+
entity: string;
|
|
6
|
+
id: string;
|
|
7
|
+
operation: "insert" | "update" | "delete";
|
|
8
|
+
oldValue?: ReplicaRow;
|
|
9
|
+
newValue?: ReplicaRow;
|
|
10
|
+
changedColumns?: string[];
|
|
11
|
+
};
|
|
12
|
+
export type ReplicaWindow = {
|
|
13
|
+
signature: string;
|
|
14
|
+
kind: "live" | "replica";
|
|
15
|
+
entity: string;
|
|
16
|
+
key: string;
|
|
17
|
+
ids: string[];
|
|
18
|
+
cursor?: ReplicaCursor;
|
|
19
|
+
completeness: "complete" | "partial";
|
|
20
|
+
source: "server" | "cache";
|
|
21
|
+
resultSkeleton?: JsonValue;
|
|
22
|
+
resultPath?: string[];
|
|
23
|
+
scalar?: JsonValue;
|
|
24
|
+
windowRevision?: string;
|
|
25
|
+
subscriptionRevision?: SubscriptionRevision;
|
|
26
|
+
mode?: "eager" | "progressive";
|
|
27
|
+
truncated?: boolean;
|
|
28
|
+
orderBy?: string;
|
|
29
|
+
orderDirection?: "asc" | "desc";
|
|
30
|
+
maxRows?: number;
|
|
31
|
+
maxBytes?: number;
|
|
32
|
+
hashes?: Record<string, string>;
|
|
33
|
+
};
|
|
34
|
+
export type ReplicaTransaction = {
|
|
35
|
+
cursor: ReplicaCursor;
|
|
36
|
+
originCommandId?: string;
|
|
37
|
+
changes: ReplicaChange[];
|
|
38
|
+
memberships?: ReplicaWindow[];
|
|
39
|
+
};
|
|
40
|
+
export type ReplicaSnapshot = {
|
|
41
|
+
cursor?: ReplicaCursor;
|
|
42
|
+
entities: Record<string, Record<string, ReplicaRow>>;
|
|
43
|
+
liveQueries: Record<string, ReplicaWindow>;
|
|
44
|
+
};
|
|
45
|
+
/** Opaque persistence namespace for one deployment/project/tenant identity. */
|
|
46
|
+
export type ReplicaScope = string;
|
|
47
|
+
/**
|
|
48
|
+
* Storage implementations must persist the complete transaction atomically.
|
|
49
|
+
* The SQLite adapter maps this call to BEGIN/apply/cursor/COMMIT; IndexedDB
|
|
50
|
+
* implementations use one readwrite transaction over the same stores.
|
|
51
|
+
*/
|
|
52
|
+
export interface LocalReplicaStorage {
|
|
53
|
+
load(scope?: ReplicaScope): Promise<ReplicaSnapshot | undefined>;
|
|
54
|
+
applyTransaction(transaction: ReplicaTransaction, snapshot: ReplicaSnapshot, scope?: ReplicaScope): Promise<void>;
|
|
55
|
+
/** Persist a normalized Query/Collection materialization atomically. */
|
|
56
|
+
replaceSnapshot?(snapshot: ReplicaSnapshot, scope?: ReplicaScope): Promise<void>;
|
|
57
|
+
replaceWindow?(window: ReplicaWindow, snapshot: ReplicaSnapshot, scope?: ReplicaScope): Promise<void>;
|
|
58
|
+
applyWindowDelta?(window: ReplicaWindow, delta: {
|
|
59
|
+
upserts: ReplicaRow[];
|
|
60
|
+
deleted: string[];
|
|
61
|
+
}, snapshot: ReplicaSnapshot, scope?: ReplicaScope): Promise<void>;
|
|
62
|
+
removeWindow?(signature: string, snapshot: ReplicaSnapshot, scope?: ReplicaScope): Promise<void>;
|
|
63
|
+
clear?(scope?: ReplicaScope): Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
export type ReplicaFreshness = "current" | "verifying" | "offline";
|
|
66
|
+
export type LiveQueryResult<T extends ReplicaRow = ReplicaRow> = {
|
|
67
|
+
rows: T[];
|
|
68
|
+
/** Ordered normalized entity IDs owned by the retained query window. */
|
|
69
|
+
ids: string[];
|
|
70
|
+
total?: number;
|
|
71
|
+
offset?: number;
|
|
72
|
+
limit?: number;
|
|
73
|
+
source: "server" | "cache";
|
|
74
|
+
completeness: "complete" | "partial";
|
|
75
|
+
freshness: ReplicaFreshness;
|
|
76
|
+
supported?: boolean;
|
|
77
|
+
unsupportedOperator?: string;
|
|
78
|
+
};
|
|
79
|
+
export type ReplicaCollectionState<T extends ReplicaRow = ReplicaRow> = LiveQueryResult<T> & {
|
|
80
|
+
truncated: boolean;
|
|
81
|
+
computedRevision: number;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Read-only view of the normalized Local Replica exposed to application code.
|
|
85
|
+
*
|
|
86
|
+
* Mutations are deliberately absent from this interface. The Gonvex client
|
|
87
|
+
* applies committed transactions, optimistic reducer effects, scope changes,
|
|
88
|
+
* and cache/window updates internally so application code cannot create a
|
|
89
|
+
* second state-management path or advance the local replica by hand.
|
|
90
|
+
*/
|
|
91
|
+
export interface LocalReplicaView {
|
|
92
|
+
cursor(): ReplicaCursor | undefined;
|
|
93
|
+
freshness(): ReplicaFreshness;
|
|
94
|
+
version(): number;
|
|
95
|
+
subscribe(listener: () => void): () => void;
|
|
96
|
+
hasPendingCommand(commandId: string): boolean;
|
|
97
|
+
getWindow(signature: string): ReplicaWindow | undefined;
|
|
98
|
+
listWindows(): ReplicaWindow[];
|
|
99
|
+
windowRows<T extends ReplicaRow = ReplicaRow>(signature: string): T[];
|
|
100
|
+
entity<T extends ReplicaRow = ReplicaRow>(entity: string, id: string): T | undefined;
|
|
101
|
+
entityBatch<T extends ReplicaRow = ReplicaRow>(entity: string, ids: readonly string[]): Array<T | undefined>;
|
|
102
|
+
entityRows<T extends ReplicaRow = ReplicaRow>(entity: string): T[];
|
|
103
|
+
entityCompleteness(entity: string): "complete" | "partial";
|
|
104
|
+
liveQuery<T extends ReplicaRow = ReplicaRow>(signature: string): LiveQueryResult<T>;
|
|
105
|
+
collectionState<T extends ReplicaRow = ReplicaRow>(signature: string): ReplicaCollectionState<T>;
|
|
106
|
+
hasLiveQuery(signature: string): boolean;
|
|
107
|
+
snapshot(): ReplicaSnapshot;
|
|
108
|
+
}
|
|
109
|
+
export declare class LocalReplica implements LocalReplicaView {
|
|
110
|
+
private readonly storage?;
|
|
111
|
+
private cursorValue?;
|
|
112
|
+
private entities;
|
|
113
|
+
private liveQueries;
|
|
114
|
+
/** Rows introduced by a materialized window may be reclaimed conservatively. */
|
|
115
|
+
private readonly windowOwned;
|
|
116
|
+
private pendingCommands;
|
|
117
|
+
private listeners;
|
|
118
|
+
private persistence;
|
|
119
|
+
private application;
|
|
120
|
+
private hydration?;
|
|
121
|
+
private freshnessValue;
|
|
122
|
+
private versionValue;
|
|
123
|
+
private scopeValue;
|
|
124
|
+
private scopeLoaded;
|
|
125
|
+
private scopeActivation?;
|
|
126
|
+
private scopeActivationName?;
|
|
127
|
+
private scopeActivationGeneration;
|
|
128
|
+
constructor(storage?: LocalReplicaStorage | undefined);
|
|
129
|
+
hydrate(): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Atomically switch the authoritative store to an opaque persistence scope.
|
|
132
|
+
* A newer request supersedes an older one even if the older storage read is
|
|
133
|
+
* slow (or resolves after auth has already changed again).
|
|
134
|
+
*/
|
|
135
|
+
activateScope(scope?: ReplicaScope, forceReload?: boolean): Promise<void>;
|
|
136
|
+
cursor(): {
|
|
137
|
+
epoch: string;
|
|
138
|
+
revision: number;
|
|
139
|
+
} | undefined;
|
|
140
|
+
freshness(): ReplicaFreshness;
|
|
141
|
+
version(): number;
|
|
142
|
+
setFreshness(freshness: ReplicaFreshness): void;
|
|
143
|
+
subscribe(listener: () => void): () => boolean;
|
|
144
|
+
applyOptimistic(commandId: string, patches: OptimisticPatch[]): void;
|
|
145
|
+
acknowledgeCommand(commandId: string, committedRevision?: number): void;
|
|
146
|
+
rejectCommand(commandId: string): void;
|
|
147
|
+
/** True while an optimistic command still contributes visible patches. */
|
|
148
|
+
hasPendingCommand(commandId: string): boolean;
|
|
149
|
+
applyTransaction(transaction: ReplicaTransaction, scope?: ReplicaScope): Promise<void>;
|
|
150
|
+
materializeWindow(input: {
|
|
151
|
+
signature: string;
|
|
152
|
+
kind?: "live" | "replica";
|
|
153
|
+
entity: string;
|
|
154
|
+
key: string;
|
|
155
|
+
rows: ReplicaRow[];
|
|
156
|
+
completeness: "complete" | "partial";
|
|
157
|
+
source: "server" | "cache";
|
|
158
|
+
cursor?: ReplicaCursor;
|
|
159
|
+
resultSkeleton?: JsonValue;
|
|
160
|
+
resultPath?: string[];
|
|
161
|
+
scalar?: JsonValue;
|
|
162
|
+
windowRevision?: string;
|
|
163
|
+
subscriptionRevision?: SubscriptionRevision;
|
|
164
|
+
mode?: "eager" | "progressive";
|
|
165
|
+
truncated?: boolean;
|
|
166
|
+
orderBy?: string;
|
|
167
|
+
orderDirection?: "asc" | "desc";
|
|
168
|
+
maxRows?: number;
|
|
169
|
+
maxBytes?: number;
|
|
170
|
+
hashes?: Record<string, string>;
|
|
171
|
+
removedIDs?: string[];
|
|
172
|
+
scope?: ReplicaScope;
|
|
173
|
+
}): Promise<void>;
|
|
174
|
+
/** Replace one server/cache window while retaining shared normalized entities. */
|
|
175
|
+
replaceWindow(input: Parameters<LocalReplica["materializeWindow"]>[0]): Promise<void>;
|
|
176
|
+
/** Apply a bounded window delta and persist it in the same transaction. */
|
|
177
|
+
applyWindowDelta(input: {
|
|
178
|
+
signature: string;
|
|
179
|
+
kind?: "live" | "replica";
|
|
180
|
+
entity: string;
|
|
181
|
+
key: string;
|
|
182
|
+
upserts: ReplicaRow[];
|
|
183
|
+
deleted: string[];
|
|
184
|
+
completeness?: "complete" | "partial";
|
|
185
|
+
source?: "server" | "cache";
|
|
186
|
+
cursor?: ReplicaCursor;
|
|
187
|
+
resultSkeleton?: JsonValue;
|
|
188
|
+
resultPath?: string[];
|
|
189
|
+
scalar?: JsonValue;
|
|
190
|
+
windowRevision?: string;
|
|
191
|
+
subscriptionRevision?: SubscriptionRevision;
|
|
192
|
+
mode?: "eager" | "progressive";
|
|
193
|
+
truncated?: boolean;
|
|
194
|
+
orderBy?: string;
|
|
195
|
+
orderDirection?: "asc" | "desc";
|
|
196
|
+
maxRows?: number;
|
|
197
|
+
maxBytes?: number;
|
|
198
|
+
hashes?: Record<string, string>;
|
|
199
|
+
removedIDs?: string[];
|
|
200
|
+
scope?: ReplicaScope;
|
|
201
|
+
}): Promise<void>;
|
|
202
|
+
getWindow(signature: string): ReplicaWindow | undefined;
|
|
203
|
+
listWindows(): ReplicaWindow[];
|
|
204
|
+
windowRows<T extends ReplicaRow = ReplicaRow>(signature: string): T[];
|
|
205
|
+
removeWindow(signature: string, scope?: ReplicaScope): Promise<void>;
|
|
206
|
+
clear(scope?: ReplicaScope): Promise<void>;
|
|
207
|
+
private materializeWindowNow;
|
|
208
|
+
private applyTransactionNow;
|
|
209
|
+
entity<T extends ReplicaRow = ReplicaRow>(entity: string, id: string): T | undefined;
|
|
210
|
+
/** Resolve several IDs from one atomic Local Replica version. */
|
|
211
|
+
entityBatch<T extends ReplicaRow = ReplicaRow>(entity: string, ids: readonly string[]): Array<T | undefined>;
|
|
212
|
+
/** All cached rows for one normalized entity, including optimistic overlays. */
|
|
213
|
+
entityRows<T extends ReplicaRow = ReplicaRow>(entity: string): T[];
|
|
214
|
+
/** Exact only when an authoritative, non-truncated Replica Collection covers the entity. */
|
|
215
|
+
entityCompleteness(entity: string): "complete" | "partial";
|
|
216
|
+
liveQuery<T extends ReplicaRow = ReplicaRow>(signature: string): LiveQueryResult<T>;
|
|
217
|
+
/** Rows and protocol-owned completeness for one Replica Collection window. */
|
|
218
|
+
collectionState<T extends ReplicaRow = ReplicaRow>(signature: string): ReplicaCollectionState<T>;
|
|
219
|
+
hasLiveQuery(signature: string): boolean;
|
|
220
|
+
snapshot(): ReplicaSnapshot;
|
|
221
|
+
private reconcileCommands;
|
|
222
|
+
private persist;
|
|
223
|
+
private notify;
|
|
224
|
+
private trackWindowOwnership;
|
|
225
|
+
private pruneOwnedEntities;
|
|
226
|
+
private pruneOwnedEntitiesAfterRemoval;
|
|
227
|
+
}
|
|
228
|
+
export declare class MemoryLocalReplicaStorage implements LocalReplicaStorage {
|
|
229
|
+
private readonly values;
|
|
230
|
+
load(scope?: ReplicaScope): Promise<ReplicaSnapshot | undefined>;
|
|
231
|
+
applyTransaction(_transaction: ReplicaTransaction, snapshot: ReplicaSnapshot, scope?: ReplicaScope): Promise<void>;
|
|
232
|
+
replaceSnapshot(snapshot: ReplicaSnapshot, scope?: ReplicaScope): Promise<void>;
|
|
233
|
+
replaceWindow(_window: ReplicaWindow, snapshot: ReplicaSnapshot, scope?: ReplicaScope): Promise<void>;
|
|
234
|
+
applyWindowDelta(_window: ReplicaWindow, _delta: {
|
|
235
|
+
upserts: ReplicaRow[];
|
|
236
|
+
deleted: string[];
|
|
237
|
+
}, snapshot: ReplicaSnapshot, scope?: ReplicaScope): Promise<void>;
|
|
238
|
+
removeWindow(_signature: string, snapshot: ReplicaSnapshot, scope?: ReplicaScope): Promise<void>;
|
|
239
|
+
clear(scope?: ReplicaScope): Promise<void>;
|
|
240
|
+
}
|