@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.
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 +166 -133
  9. package/dist/index.js +1114 -1139
  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 +2 -48
  15. package/dist/kv-stores.js +24 -411
  16. package/dist/kv-stores.js.map +1 -1
  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 +25 -25
  24. package/dist/outbox.js +27 -27
  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
package/dist/index.d.ts CHANGED
@@ -1,44 +1,61 @@
1
- import type { BrowserTelemetryInfo, JsonValue, MessageTrace, ServerCapabilities, ServerMessage } from "@gonvex/protocol";
2
- import { type QueryCacheOptions, type QueryCacheStatus } from "./query-cache.js";
3
- import { type SyncStoreOptions } from "./sync-store.js";
1
+ import type { BrowserTelemetryInfo, ExecutionScope, JsonValue, MessageTrace, ServerCapabilities, ServerMessage } from "@gonvex/protocol";
4
2
  import { type ErrorReporterOptions } from "./error-reporter.js";
5
- import { OptimisticOverlay, type OptimisticMutationDefinition, type OptimisticPatch, type OptimisticProjection } from "./optimistic.js";
3
+ export { GonvexErrorReporter } from "./error-reporter.js";
4
+ export type { ErrorReporterOptions, ErrorEventPayload, ErrorContext, ErrorAccount } from "./error-reporter.js";
5
+ import { type OptimisticPatch, type OptimisticTransactionDefinition } from "./optimistic.js";
6
6
  import { type OutboxStore } from "./outbox.js";
7
- export * from "./cache.js";
8
- export * from "./cache-coordinator.js";
9
- export * from "./browser-cache.js";
10
- export * from "./browser-cache-client.js";
11
- export * from "./browser-cache-shared-worker.js";
12
- export * from "./browser-capabilities.js";
13
- export * from "./persistent-cache.js";
14
- export * from "./query-cache.js";
15
- export * from "./sync-store.js";
7
+ import { type LocalReplicaStorage, type LocalReplicaView, type ReplicaRow, type LiveQueryResult, type ReplicaCollectionState } from "./local-replica.js";
8
+ import { type LiveQueryPlan, type OfflineLiveQueryResult } from "./query-expression.js";
16
9
  export * from "./error-reporter.js";
17
10
  export * from "./optimistic.js";
18
11
  export * from "./outbox.js";
19
12
  export * from "./kv-stores.js";
20
13
  export * from "./signals.js";
21
- export type { QueryCacheDirective } from "@gonvex/protocol";
14
+ export { MemoryLocalReplicaStorage, type LocalReplicaStorage, type LocalReplicaView, type ReplicaChange, type ReplicaFreshness, type ReplicaRow, type ReplicaScope, type ReplicaSnapshot, type ReplicaTransaction, type ReplicaWindow, type LiveQueryResult, type ReplicaCollectionState, } from "./local-replica.js";
15
+ export * from "./query-expression.js";
16
+ export * from "./indexeddb-replica.js";
17
+ export * from "./control.js";
22
18
  type SubscriptionHandler = (message: ServerMessage) => void;
23
- export type SyncReadyMessage = Extract<ServerMessage, {
24
- type: "sync.ready";
19
+ export type ReplicaReadyMessage = Extract<ServerMessage, {
20
+ type: "replica.ready";
25
21
  }> & {
26
22
  /** True when the server cut this collection at its row or byte budget. */
27
23
  truncated?: boolean;
28
24
  };
29
- export type SyncMessage = Extract<ServerMessage, {
30
- type: "sync.snapshot" | "sync.delta" | "sync.needHashes" | "sync.syncing" | "sync.reset" | "sync.error";
31
- }> | SyncReadyMessage;
32
- export type SyncSubscriptionHandler = (message: SyncMessage) => void;
25
+ export type ReplicaMessage = Extract<ServerMessage, {
26
+ type: "replica.snapshot" | "replica.delta" | "replica.needHashes" | "replica.syncing" | "replica.reset" | "replica.error";
27
+ }> | ReplicaReadyMessage;
28
+ export type ReplicaSubscriptionHandler = (message: ReplicaMessage) => void;
33
29
  type WatchUpdateHandler = () => void;
34
30
  type TelemetryHandler = (event: GonvexTelemetryEvent) => void;
35
31
  type ConnectionStateHandler = (state: ConnectionState) => void;
36
- export type FunctionReference = {
32
+ export type SupportCommand = {
33
+ id: string;
34
+ kind: string;
35
+ payload: JsonValue;
36
+ };
37
+ export type FunctionReference<Args extends JsonValue = JsonValue, Result extends JsonValue = JsonValue> = {
37
38
  kind: string;
38
39
  path: string;
40
+ /** Core Control Plane functions share the same persistent connection. */
41
+ scope?: ExecutionScope;
42
+ authorization?: "public" | "account" | "tenantAdmin" | "developer" | "projectAdmin" | "internal";
43
+ argsSchema?: JsonValue;
44
+ resultSchema?: JsonValue;
45
+ delivery?: "oneShot" | "live" | "replica";
46
+ offline?: {
47
+ mode: "forbidden" | "allowed" | "onlineOnly";
48
+ conflict?: "reject" | "expectedVersion" | "merge";
49
+ reason?: string;
50
+ };
51
+ live?: {
52
+ entity: string;
53
+ key: string;
54
+ resultPath?: readonly string[];
55
+ plan: LiveQueryPlan;
56
+ };
39
57
  optimistic?: {
40
- projection?: OptimisticProjection;
41
- mutation?: OptimisticMutationDefinition;
58
+ transaction?: OptimisticTransactionDefinition;
42
59
  };
43
60
  };
44
61
  export type GonvexClientErrorCode = "server" | "timeout" | "disconnected" | "closed" | "auth";
@@ -49,20 +66,20 @@ export type GonvexClientErrorCode = "server" | "timeout" | "disconnected" | "clo
49
66
  *
50
67
  * - `server`: the runtime executed the function and returned an error.
51
68
  * - `timeout`: no response arrived within the operation timeout. For
52
- * mutations/actions the write may or may not have been applied.
69
+ * reducers/actions the write may or may not have been applied.
53
70
  * - `disconnected`: the socket dropped while the operation was pending.
54
- * Mutations/actions fail closed unless a mutation opted into the outbox.
71
+ * Reducers/actions fail closed unless a reducer opted into the outbox.
55
72
  * - `closed`: the client was explicitly closed.
56
73
  * - `auth`: authentication was rejected.
57
74
  */
58
75
  export declare class GonvexClientError extends Error {
59
76
  readonly code: GonvexClientErrorCode;
60
77
  readonly path?: string;
61
- readonly operation?: "query" | "mutation" | "action";
78
+ readonly operation?: "query" | "reducer" | "action";
62
79
  constructor(message: string, options: {
63
80
  code: GonvexClientErrorCode;
64
81
  path?: string;
65
- operation?: "query" | "mutation" | "action";
82
+ operation?: "query" | "reducer" | "action";
66
83
  });
67
84
  }
68
85
  export type ConnectionState = {
@@ -71,33 +88,33 @@ export type ConnectionState = {
71
88
  connectionCount: number;
72
89
  connectionRetries: number;
73
90
  hasInflightRequests: boolean;
74
- inflightMutations: number;
91
+ inflightReducers: number;
75
92
  inflightActions: number;
76
93
  inflightOneShotQueries: number;
77
94
  };
78
95
  export type GonvexTimeoutOptions = {
79
96
  /** One-shot `client.query()` timeout. Default 20s. `0` disables. */
80
97
  queryTimeoutMs?: number;
81
- /** `client.mutation()` timeout. Default 20s. `0` disables. */
82
- mutationTimeoutMs?: number;
98
+ /** `client.reducer()` timeout. Default 20s. `0` disables. */
99
+ reducerTimeoutMs?: number;
83
100
  /** `client.action()` timeout. Default 60s. `0` disables. */
84
101
  actionTimeoutMs?: number;
85
102
  };
86
103
  export declare const DEFAULT_QUERY_TIMEOUT_MS = 20000;
87
- export declare const DEFAULT_MUTATION_TIMEOUT_MS = 20000;
104
+ export declare const DEFAULT_REDUCER_TIMEOUT_MS = 20000;
88
105
  export declare const DEFAULT_ACTION_TIMEOUT_MS = 60000;
89
106
  export type CallOptions = {
90
107
  /** Per-call override of the operation timeout. `0` disables. */
91
108
  timeoutMs?: number;
92
- /** Ordered row changes to expose until the mutation settles. */
109
+ /** Ordered row changes to expose until the reducer settles. */
93
110
  optimistic?: OptimisticPatch[];
94
111
  /** Queue transport failures durably instead of rejecting. Default `reject`. */
95
112
  offline?: "queue" | "reject";
96
113
  };
97
- /** Returned when an offline mutation has been accepted by the local outbox. */
98
- export type QueuedMutationOutcome = {
114
+ /** Returned when an offline reducer has been accepted by the local outbox. */
115
+ export type QueuedReducerOutcome = {
99
116
  status: "queued";
100
- mutationId: string;
117
+ reducerId: string;
101
118
  };
102
119
  export type GonvexAuthTokenFetcher = (args: {
103
120
  /** True when the server just rejected the current token — bypass any cache. */
@@ -109,33 +126,24 @@ export type GonvexClientAuth = {
109
126
  tenant?: string;
110
127
  telemetry?: boolean;
111
128
  /**
112
- * Async source of the auth token, mirroring Convex's `fetchToken` contract.
129
+ * Async source of the auth token.
113
130
  * When installed, the client re-fetches before every auth send — on first
114
131
  * connect, on every reconnect, and once more with `forceRefreshToken: true`
115
132
  * when the server rejects the current token — so a socket that outlives a
116
- * short-lived JWT (e.g. an ~1h Firebase ID token) reauthenticates with a
133
+ * short-lived Gonvex app session reauthenticates with a
117
134
  * live credential instead of replaying the expired one. A `token` passed in
118
135
  * the same `setAuth` call is trusted and sent as-is; resolving `null` signs
119
136
  * the session out; a rejected fetch keeps the currently installed token so
120
137
  * an offline start is not signed out.
121
138
  */
122
139
  fetchToken?: GonvexAuthTokenFetcher;
123
- /**
124
- * Non-secret identity hint ({@link https://datatracker.ietf.org/doc/html/rfc7519 JWT}
125
- * `sub` and `iss` claims) that stands in for a token when deriving the local
126
- * cache identity. Lets a cold start with no usable token — e.g. an offline
127
- * tab whose identity provider cannot refresh — recover the warm query-cache
128
- * directive and serve cached reads. Never sent to the server; a parseable
129
- * token always takes precedence, and both must derive the same key for the
130
- * same user (persist the claims of the last token you installed).
131
- */
140
+ /** Non-secret identity hint used to isolate local-replica persistence. */
132
141
  identity?: {
133
142
  sub: string;
134
143
  iss?: string;
135
144
  };
136
145
  };
137
146
  export type GonvexClientOptions = GonvexClientAuth & {
138
- queryCache?: false | QueryCacheOptions;
139
147
  /**
140
148
  * Keep listenerless live queries subscribed for this long so route
141
149
  * backtracking can reuse their current result without WebSocket churn.
@@ -143,15 +151,14 @@ export type GonvexClientOptions = GonvexClientAuth & {
143
151
  */
144
152
  querySubscriptionRetentionMs?: number;
145
153
  /**
146
- * Keep listenerless durable syncs open briefly across React remounts.
154
+ * Keep listenerless Replica Collections open briefly across React remounts.
147
155
  * Defaults to 250ms, preventing close/open/snapshot churn in StrictMode.
148
156
  */
149
- syncSubscriptionRetentionMs?: number;
150
- sync?: false | SyncStoreOptions;
157
+ replicaSubscriptionRetentionMs?: number;
151
158
  /**
152
- * Durable mutation queue settings. Every replay keeps its original
159
+ * Durable reducer queue settings. Every replay keeps its original
153
160
  * idempotency key, making an accidental cross-tab double-send server-safe.
154
- * Runtimes without IndexedDB inject `store` to keep queued mutations
161
+ * Runtimes without IndexedDB inject `store` to keep queued reducers
155
162
  * durable; queue semantics always stay in the SDK.
156
163
  */
157
164
  outbox?: {
@@ -159,14 +166,18 @@ export type GonvexClientOptions = GonvexClientAuth & {
159
166
  enabled?: boolean;
160
167
  store?: OutboxStore;
161
168
  };
162
- errorReporting?: false | Omit<ErrorReporterOptions, "endpoint" | "project" | "tenant">;
169
+ /** Transactional normalized store used by Replica Collections and Live Queries. */
170
+ localReplica?: {
171
+ storage?: LocalReplicaStorage;
172
+ };
173
+ errorReporting?: false | Omit<ErrorReporterOptions, "transport" | "project" | "tenant">;
163
174
  timeouts?: GonvexTimeoutOptions;
164
175
  };
165
176
  export type GonvexTelemetryEvent = {
166
- type: "mutation" | "action" | "query";
177
+ type: "reducer" | "action" | "query";
167
178
  id: string;
168
179
  path: string;
169
- reason?: "initial" | "invalidate" | "recover";
180
+ reason?: "initial" | "change" | "recover";
170
181
  outcome: "ok" | "error";
171
182
  error?: string;
172
183
  clientSentAtMs?: number;
@@ -180,14 +191,13 @@ export declare class GonvexClient {
180
191
  private socket;
181
192
  private readonly handlers;
182
193
  private readonly querySubscriptions;
183
- private readonly syncSubscriptions;
194
+ private readonly replicaSubscriptions;
184
195
  private readonly oneShotQueries;
185
196
  private readonly telemetryHandlers;
186
197
  private readonly pendingMessages;
187
- private readonly pendingSyncOpens;
198
+ private readonly pendingReplicaOpens;
188
199
  private readonly pendingQuerySubscribes;
189
- private readonly syncPersistence;
190
- private syncOpenFlushTimer;
200
+ private replicaOpenFlushTimer;
191
201
  private querySubscribeFlushTimer;
192
202
  private serverCapabilities;
193
203
  private auth;
@@ -197,29 +207,23 @@ export declare class GonvexClient {
197
207
  private authRetriedAfterError;
198
208
  private readonly authErrorHandlers;
199
209
  private telemetryEnabled;
200
- private readonly queryCache;
201
- private readonly queryCacheWaitForScope;
202
- private readonly queryCacheReadTimeoutMs;
203
210
  private readonly querySubscriptionRetentionMs;
204
- private readonly syncSubscriptionRetentionMs;
205
- private readonly syncStore;
206
- private readonly mutationOutbox;
207
- private readonly overlay;
208
- private readonly optimisticMutationIds;
211
+ private readonly replicaSubscriptionRetentionMs;
212
+ private readonly reducerOutbox;
213
+ private readonly replica;
214
+ private readonly replicaView;
215
+ private readonly optimisticReducerIds;
209
216
  private readonly optimisticOutboxEntryIds;
210
217
  private outboxReady;
211
218
  private outboxScope;
212
219
  private outboxScopeGeneration;
213
220
  private readonly outboxEphemeralScope;
221
+ private replicaScope;
222
+ private hasAuthoritativeReplicaScope;
223
+ private replicaReady;
214
224
  private readonly unsubscribeOutbox;
215
- private readonly unsubscribeOverlay;
216
225
  private drainingOutbox;
217
226
  private outboxDrainTimer;
218
- private queryCacheDirective;
219
- private queryCacheGeneration;
220
- private syncScopeGeneration;
221
- private queryCacheNegotiatedSocketGeneration;
222
- private syncIdentityGeneration;
223
227
  private readonly sessionScopeHandlers;
224
228
  private readonly errorReporter;
225
229
  private reconnectTimer;
@@ -228,14 +232,24 @@ export declare class GonvexClient {
228
232
  private manuallyClosed;
229
233
  private readonly pendingCalls;
230
234
  private readonly connectionStateHandlers;
235
+ private readonly supportCommandHandlers;
231
236
  private isWebSocketConnected;
232
237
  private hasEverConnected;
233
238
  private connectionCount;
234
239
  private readonly timeouts;
235
240
  constructor(url: string, options?: GonvexClientOptions);
236
- /** The client's materialized optimistic state for pending-row indicators. */
237
- get optimisticOverlay(): OptimisticOverlay;
238
- /** Number of mutations waiting for a definitive server result. */
241
+ /** The single normalized authoritative + optimistic application data store. */
242
+ get localReplica(): LocalReplicaView;
243
+ replicaSignature(ref: FunctionReference, args?: JsonValue): string;
244
+ /** Read one persisted Live Query membership without starting another transport subscription. */
245
+ retainedLiveQuery<T extends ReplicaRow = ReplicaRow>(signature: string): LiveQueryResult<T>;
246
+ /** Resolve an ordered ID batch from one normalized entity store. */
247
+ replicaEntities<T extends ReplicaRow = ReplicaRow>(entity: string, ids: readonly string[]): Array<T | undefined>;
248
+ /** Read rows and server-owned completeness for a persisted Replica Collection. */
249
+ replicaCollectionState<T extends ReplicaRow = ReplicaRow>(ref: FunctionReference, args?: JsonValue): ReplicaCollectionState<T>;
250
+ /** Run the generated Live Query plan over the bounded normalized cache. */
251
+ offlineLiveQuery<T extends ReplicaRow = ReplicaRow>(ref: FunctionReference, args?: JsonValue): OfflineLiveQueryResult<T>;
252
+ /** Number of reducers waiting for a definitive server result. */
239
253
  outboxCount(): Promise<number>;
240
254
  connectionState(): ConnectionState;
241
255
  /** Metadata advertised by the runtime in its latest session.ready frame. */
@@ -256,79 +270,96 @@ export declare class GonvexClient {
256
270
  private rejectPendingCalls;
257
271
  onTelemetry(handler: TelemetryHandler): () => boolean;
258
272
  onSessionScopeChange(handler: () => void): () => boolean;
259
- clearQueryCache(options?: {
260
- allScopes?: boolean;
261
- }): Promise<void>;
262
- getQueryCacheStatus(): QueryCacheStatus;
263
- subscribeQuery(ref: FunctionReference, args: JsonValue | undefined, onMessage: SubscriptionHandler): () => void;
273
+ onSupportCommand(handler: (command: SupportCommand) => void): () => boolean;
274
+ subscribeLiveQuery<Args extends JsonValue = JsonValue, Result extends JsonValue = JsonValue>(ref: FunctionReference<Args, Result>, args: Args | undefined, onMessage: SubscriptionHandler): () => void;
275
+ /** Watch an authorized host-owned Control Plane Query on the persistent connection. */
276
+ watchControlQuery<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args): {
277
+ getSnapshot(): Readonly<{
278
+ result: T | undefined;
279
+ version: number;
280
+ }>;
281
+ onUpdate(listener: WatchUpdateHandler): () => void;
282
+ };
283
+ private handleQueryMessage;
284
+ private materializeLiveQuery;
264
285
  private normalizeSubscriptionMessage;
265
286
  private acceptRevision;
266
- watchQuery<T = JsonValue>(ref: FunctionReference, args?: JsonValue): {
267
- localQueryResult(): T | undefined;
268
- onUpdate(handler: WatchUpdateHandler): () => void;
269
- };
270
- subscribeSync(ref: FunctionReference, args: JsonValue | undefined, onMessage: SyncSubscriptionHandler): () => void;
271
- watchSync<T extends JsonValue = JsonValue>(ref: FunctionReference, args?: JsonValue): {
272
- localSyncResult(): T[] | undefined;
273
- status(): {
287
+ private subscribeReplicaTransport;
288
+ /** Subscribe to a bounded Replica Collection. */
289
+ subscribeReplica<Args extends JsonValue = JsonValue, Result extends JsonValue = JsonValue>(ref: FunctionReference<Args, Result>, args: Args | undefined, onMessage: ReplicaSubscriptionHandler): () => void;
290
+ /** Watch a bounded Replica Collection through the normalized Local Replica. */
291
+ watchReplica<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args): {
292
+ localReplicaResult: () => T[] | undefined;
293
+ localReplicaState: () => ReplicaCollectionState | undefined;
294
+ status: () => {
274
295
  isLoading: boolean;
275
296
  isUpToDate: boolean;
276
297
  };
277
298
  onUpdate(handler: WatchUpdateHandler): () => void;
278
299
  };
279
- private handleSyncMessage;
280
- private acceptSyncReady;
281
- private handleSyncWatermark;
282
- private scheduleSyncWatermarkPersistence;
283
- private emitSyncMessage;
284
- private materializeSyncMessage;
300
+ /**
301
+ * Watch a structured Live Query through normalized LocalReplica rows. The
302
+ * latest query result is retained only as the transport-shaped skeleton;
303
+ * its row window is always rebuilt from LocalReplica membership/entities.
304
+ */
305
+ watchLiveQuery<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args): {
306
+ localLiveQueryResult: () => T | undefined;
307
+ onUpdate(handler: WatchUpdateHandler): () => void;
308
+ };
309
+ private handleReplicaMessage;
310
+ private acceptReplicaReady;
311
+ private handleReplicaWatermark;
312
+ private emitReplicaMessage;
313
+ private materializeReplicaMessage;
285
314
  private materializeQueryMessage;
286
315
  private emitOptimisticEntity;
287
316
  private acknowledgeOptimisticSource;
288
317
  private acknowledgeOptimisticQuerySnapshot;
289
- private markSyncSubscriptionsOutOfDate;
290
- private startSync;
291
- private sendSyncOpen;
292
- private syncOpenRequest;
293
- private flushSyncOpens;
294
- private unsubscribeSyncListener;
295
- private persistSyncSnapshot;
296
- private persistSyncDelta;
318
+ private markReplicaSubscriptionsOutOfDate;
319
+ private startReplica;
320
+ private sendReplicaOpen;
321
+ private replicaOpenRequest;
322
+ private flushReplicaOpens;
323
+ private unsubscribeReplicaListener;
297
324
  private activateOutboxScope;
325
+ private activateReplicaDirective;
326
+ private quarantineReplicaScope;
327
+ private rejectMissingReplicaDirective;
328
+ private rejectReplicaDirective;
298
329
  private restoreOutbox;
299
- private addOptimisticMutation;
300
- private settleOptimisticMutation;
301
- private rejectOptimisticMutation;
302
- private ackOptimisticMutation;
330
+ private addOptimisticReducer;
331
+ private settleOptimisticReducer;
332
+ private rejectOptimisticReducer;
333
+ private ackOptimisticReducer;
303
334
  private drainOutbox;
304
335
  private scheduleOutboxDrain;
305
- mutation<T = JsonValue>(ref: FunctionReference, args: JsonValue, options: CallOptions & {
336
+ reducer<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args: Args, options: CallOptions & {
306
337
  offline: "queue";
307
- }): Promise<T | QueuedMutationOutcome>;
308
- mutation<T = JsonValue>(ref: FunctionReference, args?: JsonValue, options?: CallOptions): Promise<T>;
309
- private runOptimisticMutation;
310
- action<T = JsonValue>(ref: FunctionReference, args?: JsonValue, options?: CallOptions): Promise<T>;
311
- query<T = JsonValue>(ref: FunctionReference, args?: JsonValue, options?: CallOptions): Promise<T>;
338
+ }): Promise<T | QueuedReducerOutcome>;
339
+ reducer<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args, options?: CallOptions): Promise<T>;
340
+ private runOptimisticReducer;
341
+ action<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args, options?: CallOptions): Promise<T>;
342
+ query<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args, options?: CallOptions): Promise<T>;
312
343
  /**
313
344
  * Force a live query subscription to re-request its result from the server,
314
345
  * e.g. after a `query.error` or when a subscriber gave up waiting. No-op if
315
346
  * nothing is subscribed to this query.
316
347
  */
317
- retryQuery(ref: FunctionReference, args?: JsonValue): void;
348
+ retryLiveQuery(ref: FunctionReference, args?: JsonValue): void;
318
349
  /**
319
- * Flush a queue of mutations in one `mutation.callMany` frame (queue order,
350
+ * Flush a queue of reducers in one `reducer.callMany` frame (queue order,
320
351
  * one websocket round trip). Each entry settles independently — a failed
321
352
  * call does not reject the batch — so offline queues can apply per-row
322
- * outcomes. Falls back to the standard per-mutation path when the runtime
353
+ * outcomes. Falls back to the standard per-reducer path when the runtime
323
354
  * lacks batching or when a call needs generated/explicit optimism or durable
324
- * offline queuing, so there is never a second mutation-state implementation.
355
+ * offline queuing, so there is never a second reducer-state implementation.
325
356
  */
326
- mutationMany<T = JsonValue>(calls: Array<{
357
+ reducerMany<T extends JsonValue = JsonValue>(calls: Array<{
327
358
  ref: FunctionReference;
328
359
  args?: JsonValue;
329
360
  }>, options?: CallOptions): Promise<Array<{
330
361
  status: "ok";
331
- result: T;
362
+ result: T | QueuedReducerOutcome;
332
363
  } | {
333
364
  status: "error";
334
365
  error: GonvexClientError;
@@ -339,25 +370,30 @@ export declare class GonvexClient {
339
370
  private sendSubscription;
340
371
  private flushQuerySubscribes;
341
372
  private resumeQuerySubscriptions;
342
- private enqueueSyncPersistence;
343
- private scheduleSyncRetry;
344
- private clearSyncRetry;
373
+ private resumeReplicaSubscriptions;
374
+ private scheduleReplicaRetry;
375
+ private clearReplicaRetry;
345
376
  private requestSubscriptionSnapshot;
346
377
  private sendOneShotQuery;
347
378
  private resubscribeQueries;
379
+ private sendPendingControlCall;
380
+ private sendInvocation;
381
+ private hasControlPlaneWork;
348
382
  private scheduleReconnect;
349
- private installQueryCacheDirective;
350
- private recoverWarmSyncDirective;
351
- private resetQueryCacheScope;
352
- private resetQueryResultCacheState;
353
- private resetSyncCacheState;
354
- private startQueryCacheRead;
355
- private persistQueryResult;
356
- private deleteCachedQuery;
383
+ private resetReplicaScopeState;
384
+ /**
385
+ * A subscription id is also the server's response routing key. Rotate it on
386
+ * auth scope changes so a delayed frame from the previous tenant cannot be
387
+ * delivered to a handler that now materializes into the new scope.
388
+ */
389
+ private rotateSubscriptionScopes;
357
390
  private emitTelemetryFromCall;
358
391
  private recordTelemetry;
359
392
  private emitTelemetry;
360
393
  private reportTelemetry;
394
+ /** Send a bounded native error-telemetry frame using authenticated connection attribution. */
395
+ reportError(type: "register" | "envelope" | "heartbeat", payload: unknown): Promise<void>;
396
+ private sendNativeError;
361
397
  private sendAuth;
362
398
  private sendAuthFrame;
363
399
  private fetchAndSendAuth;
@@ -368,6 +404,3 @@ export declare class GonvexClient {
368
404
  private sendNow;
369
405
  private flushPendingMessages;
370
406
  }
371
- export declare class ConvexReactClient extends GonvexClient {
372
- constructor(url: string, options?: GonvexClientOptions);
373
- }