@gonvex/client 0.5.2-staging.2 → 0.5.2-staging.20
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 +68 -2
- package/dist/browser-upgrades.d.ts +19 -0
- package/dist/browser-upgrades.js +157 -0
- package/dist/browser-upgrades.js.map +1 -0
- package/dist/client-upgrades.d.ts +26 -0
- package/dist/client-upgrades.js +41 -0
- package/dist/client-upgrades.js.map +1 -0
- package/dist/control.d.ts +2 -0
- package/dist/control.js +1 -0
- package/dist/control.js.map +1 -1
- package/dist/index.d.ts +344 -7
- package/dist/index.js +1528 -173
- package/dist/index.js.map +1 -1
- package/dist/indexeddb-read-view.d.ts +24 -0
- package/dist/indexeddb-read-view.js +164 -0
- package/dist/indexeddb-read-view.js.map +1 -0
- package/dist/indexeddb-replica.d.ts +41 -3
- package/dist/indexeddb-replica.js +402 -101
- package/dist/indexeddb-replica.js.map +1 -1
- package/dist/local-replica.d.ts +125 -4
- package/dist/local-replica.js +831 -85
- package/dist/local-replica.js.map +1 -1
- package/dist/outbox.d.ts +118 -10
- package/dist/outbox.js +391 -89
- package/dist/outbox.js.map +1 -1
- package/dist/paged-read-view.d.ts +13 -0
- package/dist/paged-read-view.js +60 -0
- package/dist/paged-read-view.js.map +1 -0
- package/dist/query-expression.d.ts +39 -2
- package/dist/query-expression.js +106 -5
- package/dist/query-expression.js.map +1 -1
- package/dist/replica-integrity.d.ts +2 -0
- package/dist/replica-integrity.js +10 -0
- package/dist/replica-integrity.js.map +1 -1
- package/dist/replica-record.d.ts +14 -0
- package/dist/replica-record.js +46 -0
- package/dist/replica-record.js.map +1 -0
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
import type { BrowserTelemetryInfo, ExecutionScope, JsonValue, MessageTrace, ServerCapabilities, ServerMessage } from "@gonvex/protocol";
|
|
1
|
+
import type { BrowserTelemetryInfo, ExecutionScope, JsonValue, MessageTrace, ServerCapabilities, ServerMessage, ReducerErrorClass } from "@gonvex/protocol";
|
|
2
|
+
import type { LocalRuntimeBinding } from "@gonvex/local-runtime/worker-client";
|
|
2
3
|
import { type ErrorReporterOptions } from "./error-reporter.js";
|
|
3
4
|
export { GonvexErrorReporter } from "./error-reporter.js";
|
|
4
5
|
export type { ErrorReporterOptions, ErrorEventPayload, ErrorContext, ErrorAccount } from "./error-reporter.js";
|
|
5
6
|
import { type OptimisticPatch, type OptimisticTransactionDefinition } from "./optimistic.js";
|
|
6
|
-
import { type OutboxStore } from "./outbox.js";
|
|
7
|
+
import { type OutboxErrorClass, type ReducerOutboxScopeSummary, type ReducerOutboxState, type OutboxStore } from "./outbox.js";
|
|
7
8
|
import { type LocalReplicaStorage, type LocalReplicaView, type ReplicaRow, type LiveQueryResult, type ReplicaCollectionState, type ReplicaCollectionSubscriptionState, type ReplicaCollectionPlan } from "./local-replica.js";
|
|
8
9
|
import { type LiveQueryPlan, type OfflineLiveQueryResult } from "./query-expression.js";
|
|
9
10
|
export * from "./error-reporter.js";
|
|
10
11
|
export * from "./optimistic.js";
|
|
11
12
|
export * from "./outbox.js";
|
|
12
13
|
export * from "./kv-stores.js";
|
|
14
|
+
export * from "./client-upgrades.js";
|
|
15
|
+
export * from "./browser-upgrades.js";
|
|
13
16
|
export * from "./signals.js";
|
|
17
|
+
export * from "./paged-read-view.js";
|
|
18
|
+
export { mergeReplicaRecord, type ReplicaRecordVersion, type VersionedReplicaRecord } from './replica-record.js';
|
|
14
19
|
export * from "./external-auth.js";
|
|
15
|
-
export { MemoryLocalReplicaStorage, type LocalReplicaStorage, type LocalReplicaView, type ReplicaChange, type ReplicaFreshness, type ReplicaRow, type ReplicaScope, type ReplicaSnapshot, type ReplicaTransaction, type ReplicaWindow, type LiveQueryResult, type ReplicaCollectionState, type ReplicaCollectionSubscriptionState, type ReplicaCollectionPlan, } from "./local-replica.js";
|
|
20
|
+
export { MemoryLocalReplicaStorage, type LocalReplicaStorage, type LocalReplicaSession, type LocalReplicaView, type ReplicaChange, type ReplicaFreshness, type ReplicaRow, type ReplicaScope, type ReplicaSnapshot, type ReplicaTransaction, type ReplicaWindow, type LiveQueryResult, type ReplicaCollectionState, type ReplicaCollectionSubscriptionState, type ReplicaCollectionPlan, } from "./local-replica.js";
|
|
16
21
|
export * from "./query-expression.js";
|
|
17
22
|
export * from "./indexeddb-replica.js";
|
|
18
23
|
export * from "./control.js";
|
|
@@ -49,6 +54,11 @@ export type FunctionReference<Args extends JsonValue = JsonValue, Result extends
|
|
|
49
54
|
conflict?: "reject" | "expectedVersion" | "merge";
|
|
50
55
|
reason?: string;
|
|
51
56
|
};
|
|
57
|
+
localExecution?: 1;
|
|
58
|
+
/** SDK-owned version check for replay; never an application argument. */
|
|
59
|
+
receiptPath?: string;
|
|
60
|
+
artifactHash?: string;
|
|
61
|
+
intentEntropy?: string;
|
|
52
62
|
live?: {
|
|
53
63
|
entity: string;
|
|
54
64
|
key: string;
|
|
@@ -85,12 +95,128 @@ export declare class GonvexClientError extends Error {
|
|
|
85
95
|
readonly code: GonvexClientErrorCode;
|
|
86
96
|
readonly path?: string;
|
|
87
97
|
readonly operation?: "query" | "reducer" | "action";
|
|
98
|
+
/**
|
|
99
|
+
* For `server` Reducer errors: the runtime's classification, or a legacy
|
|
100
|
+
* inference when an older runtime sent none. Undefined means a legacy
|
|
101
|
+
* runtime's unclassified error, which is handled as a rejection.
|
|
102
|
+
*/
|
|
103
|
+
readonly errorClass?: ReducerErrorClass;
|
|
104
|
+
/** True when the same call (same idempotency key) may succeed later. */
|
|
105
|
+
readonly retryable?: boolean;
|
|
88
106
|
constructor(message: string, options: {
|
|
89
107
|
code: GonvexClientErrorCode;
|
|
90
108
|
path?: string;
|
|
91
109
|
operation?: "query" | "reducer" | "action";
|
|
110
|
+
errorClass?: ReducerErrorClass;
|
|
111
|
+
retryable?: boolean;
|
|
92
112
|
});
|
|
93
113
|
}
|
|
114
|
+
/** One durable reducer intent, as exposed to application UI. */
|
|
115
|
+
export type OutboxIntent = {
|
|
116
|
+
/** The reducer id / idempotency key. Stable across retries, reloads and tabs. */
|
|
117
|
+
id: string;
|
|
118
|
+
/** Local queue sequence number. Lower numbers were issued first. */
|
|
119
|
+
entryId: number;
|
|
120
|
+
reducer: string;
|
|
121
|
+
state: ReducerOutboxState;
|
|
122
|
+
/** Failed deliveries counted toward the retry budget. */
|
|
123
|
+
attempts: number;
|
|
124
|
+
lastError?: string;
|
|
125
|
+
errorClass?: OutboxErrorClass;
|
|
126
|
+
createdAt: number;
|
|
127
|
+
nextAttemptAt: number;
|
|
128
|
+
/** When the intent became `failed` or `rejected`. */
|
|
129
|
+
settledAt?: number;
|
|
130
|
+
args: unknown;
|
|
131
|
+
/** Short, display-safe JSON preview of the arguments. */
|
|
132
|
+
argsSummary: string;
|
|
133
|
+
/** Rows this intent's optimistic prediction touched (best effort). */
|
|
134
|
+
entities: Array<{
|
|
135
|
+
entity: string;
|
|
136
|
+
id: string;
|
|
137
|
+
}>;
|
|
138
|
+
};
|
|
139
|
+
/** Per-row delivery status derived from the outbox. */
|
|
140
|
+
export type EntityIntentStatus = "syncing" | "failed" | "rejected";
|
|
141
|
+
export type ReducerRejectionEvent = {
|
|
142
|
+
reducerId: string;
|
|
143
|
+
path: string;
|
|
144
|
+
error: string;
|
|
145
|
+
errorClass?: OutboxErrorClass;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Why a locally executing Reducer ran without a local result.
|
|
149
|
+
* - `incompleteReplica`: the body read rows the Local Replica does not hold
|
|
150
|
+
* (no generated local collection, or one that has not hydrated yet).
|
|
151
|
+
* - `localError`: a replayed prediction failed locally for another reason.
|
|
152
|
+
*/
|
|
153
|
+
export type LocalExecutionFallbackReason = "incompleteReplica" | "localError";
|
|
154
|
+
/**
|
|
155
|
+
* Emitted when the client degrades from local execution to a queued-only
|
|
156
|
+
* intent: the change is durable and will reach the server, but it has no
|
|
157
|
+
* optimistic result, so it is not visible until the server commits it (and
|
|
158
|
+
* never while offline).
|
|
159
|
+
*/
|
|
160
|
+
export type LocalExecutionFallbackEvent = {
|
|
161
|
+
/** Reducer path. */
|
|
162
|
+
path: string;
|
|
163
|
+
/** Durable intent id, the Reducer's idempotency key. */
|
|
164
|
+
intentId: string;
|
|
165
|
+
/**
|
|
166
|
+
* `call`: the Reducer call returned `{ status: "queued" }` without a local
|
|
167
|
+
* result. `replay`: re-executing a pending intent lost the prediction it had.
|
|
168
|
+
*/
|
|
169
|
+
phase: "call" | "replay";
|
|
170
|
+
reason: LocalExecutionFallbackReason;
|
|
171
|
+
/** The table whose rows were missing, for `incompleteReplica`. */
|
|
172
|
+
table?: string;
|
|
173
|
+
/** The local error message. */
|
|
174
|
+
error: string;
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Which local dependency tables the client keeps hydrated so locally
|
|
178
|
+
* executing Reducers can run from their first call. See
|
|
179
|
+
* {@link GonvexClientOptions.localDependencyResidency}.
|
|
180
|
+
*/
|
|
181
|
+
export type LocalDependencyResidency = "bounded" | "off" | {
|
|
182
|
+
/** Largest declared `maxRows` of a collection kept resident. Default 1000. */
|
|
183
|
+
maxRows?: number;
|
|
184
|
+
/** Largest declared `maxBytes` of a collection kept resident. Default: no byte bound. */
|
|
185
|
+
maxBytes?: number;
|
|
186
|
+
};
|
|
187
|
+
/** Default row bound of `localDependencyResidency: "bounded"`. */
|
|
188
|
+
export declare const DEFAULT_LOCAL_DEPENDENCY_RESIDENT_MAX_ROWS = 1000;
|
|
189
|
+
export type OutboxScope = ReducerOutboxScopeSummary & {
|
|
190
|
+
/** True for the identity this client is currently signed in as. */
|
|
191
|
+
current: boolean;
|
|
192
|
+
};
|
|
193
|
+
export type OutboxRetryOptions = {
|
|
194
|
+
/**
|
|
195
|
+
* Counted delivery failures (transient server errors and timeouts) before an
|
|
196
|
+
* intent is parked as `failed`. Default 10. `Infinity` retries forever.
|
|
197
|
+
*/
|
|
198
|
+
maxAttempts?: number;
|
|
199
|
+
/** Cap for the exponential backoff between attempts. Default 60s. */
|
|
200
|
+
maxBackoffMs?: number;
|
|
201
|
+
};
|
|
202
|
+
export type ResetLocalReplicaOptions = {
|
|
203
|
+
/**
|
|
204
|
+
* Keep the durable outbox (default true). Pending, failed and rejected
|
|
205
|
+
* intents survive the reset and their predictions are re-applied on top of
|
|
206
|
+
* the rehydrated data. `false` also deletes every intent of the active
|
|
207
|
+
* identity that is not already inflight or committed; use it only for an
|
|
208
|
+
* explicit "discard unsynced changes" action.
|
|
209
|
+
*/
|
|
210
|
+
keepOutbox?: boolean;
|
|
211
|
+
};
|
|
212
|
+
export type ResetLocalReplicaResult = {
|
|
213
|
+
/** Intents deleted because `keepOutbox: false` was requested. */
|
|
214
|
+
discardedIntents: number;
|
|
215
|
+
/** Replica Collections and Live Queries re-requested from the server. */
|
|
216
|
+
resubscribed: number;
|
|
217
|
+
};
|
|
218
|
+
export declare const DEFAULT_OUTBOX_MAX_ATTEMPTS = 10;
|
|
219
|
+
export declare const DEFAULT_OUTBOX_RETRY_MAX_BACKOFF_MS = 60000;
|
|
94
220
|
export type ConnectionState = {
|
|
95
221
|
isWebSocketConnected: boolean;
|
|
96
222
|
hasEverConnected: boolean;
|
|
@@ -153,6 +279,34 @@ export type GonvexClientAuth = {
|
|
|
153
279
|
};
|
|
154
280
|
};
|
|
155
281
|
export type GonvexClientOptions = GonvexClientAuth & {
|
|
282
|
+
/** Anonymous, online-only connection scoped to one tenant ID or routing domain. */
|
|
283
|
+
public?: {
|
|
284
|
+
tenant: string;
|
|
285
|
+
};
|
|
286
|
+
clientContract?: import("./client-upgrades.js").ClientContract;
|
|
287
|
+
onUpdateRequired?: (reason: string) => void;
|
|
288
|
+
/** Supplied by generated client bindings, once for the entire application. */
|
|
289
|
+
localRuntime?: LocalRuntimeBinding & {
|
|
290
|
+
clientContract?: import("./client-upgrades.js").ClientContract;
|
|
291
|
+
collections?: readonly FunctionReference[];
|
|
292
|
+
/** Per locally executing Reducer, the tables its body reads locally (from codegen). */
|
|
293
|
+
localDependencies?: Readonly<Record<string, readonly string[]>>;
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* Keep the generated local collections that locally executing Reducers
|
|
297
|
+
* depend on subscribed for the whole session, so a Reducer's first call
|
|
298
|
+
* runs locally instead of falling back to a queued-only intent.
|
|
299
|
+
*
|
|
300
|
+
* `"bounded"` (default) keeps a dependency table resident only when its
|
|
301
|
+
* generated collection declares `maxRows` of at most 1000 (the smallest
|
|
302
|
+
* `maxRows` among the table's unfiltered Replica Collections). Larger or
|
|
303
|
+
* undeclared collections stay page-driven: the screens that show them
|
|
304
|
+
* subscribe. Pass `{ maxRows, maxBytes }` to change the bounds, or `"off"`
|
|
305
|
+
* to disable residency.
|
|
306
|
+
*/
|
|
307
|
+
localDependencyResidency?: LocalDependencyResidency;
|
|
308
|
+
/** Observe local-execution fallbacks; see {@link GonvexClient.onLocalExecutionFallback}. */
|
|
309
|
+
onLocalExecutionFallback?: (event: LocalExecutionFallbackEvent) => void;
|
|
156
310
|
/**
|
|
157
311
|
* Keep listenerless live queries subscribed for this long so route
|
|
158
312
|
* backtracking can reuse their current result without WebSocket churn.
|
|
@@ -174,10 +328,13 @@ export type GonvexClientOptions = GonvexClientAuth & {
|
|
|
174
328
|
databaseName?: string;
|
|
175
329
|
enabled?: boolean;
|
|
176
330
|
store?: OutboxStore;
|
|
331
|
+
retry?: OutboxRetryOptions;
|
|
177
332
|
};
|
|
178
333
|
/** Transactional normalized store used by Replica Collections and Live Queries. */
|
|
179
334
|
localReplica?: {
|
|
180
335
|
storage?: LocalReplicaStorage;
|
|
336
|
+
maxResidentRows?: number;
|
|
337
|
+
maxResidentBytes?: number;
|
|
181
338
|
};
|
|
182
339
|
errorReporting?: false | Omit<ErrorReporterOptions, "transport" | "project" | "tenant">;
|
|
183
340
|
timeouts?: GonvexTimeoutOptions;
|
|
@@ -197,10 +354,34 @@ export type GonvexTelemetryEvent = {
|
|
|
197
354
|
};
|
|
198
355
|
export declare class GonvexClient {
|
|
199
356
|
private readonly url;
|
|
357
|
+
private readonly localTableBindings;
|
|
358
|
+
private readonly localBinding?;
|
|
359
|
+
private readonly localExecutor?;
|
|
360
|
+
private readonly localStorage?;
|
|
361
|
+
private localIdentity?;
|
|
362
|
+
private localLane;
|
|
363
|
+
private preparationLane;
|
|
364
|
+
private localReplayScheduled;
|
|
365
|
+
private waitingLocalEdits;
|
|
366
|
+
private replacingLocal;
|
|
367
|
+
private readonly unsubscribeLocal?;
|
|
368
|
+
private readonly localCollectionClosers;
|
|
369
|
+
private readonly localCollectionKeys;
|
|
370
|
+
private readonly localExecutionTables;
|
|
371
|
+
private readonly reducerRejectionHandlers;
|
|
372
|
+
private readonly localFallbackHandlers;
|
|
373
|
+
private readonly residentDependencyTables;
|
|
374
|
+
private readonly outboxRetry;
|
|
375
|
+
private unauthenticatedRetries;
|
|
376
|
+
private intentsSnapshotValue;
|
|
377
|
+
private readonly intentListeners;
|
|
378
|
+
private intentsRefreshRunning;
|
|
379
|
+
private intentsRefreshDirty;
|
|
200
380
|
private socket;
|
|
201
381
|
private readonly handlers;
|
|
202
382
|
private readonly querySubscriptions;
|
|
203
383
|
private readonly replicaSubscriptions;
|
|
384
|
+
private readonly replicaMetadataListeners;
|
|
204
385
|
private readonly oneShotQueries;
|
|
205
386
|
private readonly telemetryHandlers;
|
|
206
387
|
private readonly pendingMessages;
|
|
@@ -210,6 +391,7 @@ export declare class GonvexClient {
|
|
|
210
391
|
private querySubscribeFlushTimer;
|
|
211
392
|
private serverCapabilities;
|
|
212
393
|
private activeArtifactHashValue;
|
|
394
|
+
private readonly publicTenant?;
|
|
213
395
|
private auth;
|
|
214
396
|
private authInFlight;
|
|
215
397
|
private latestAuthFrameId;
|
|
@@ -219,6 +401,7 @@ export declare class GonvexClient {
|
|
|
219
401
|
private authFetchGeneration;
|
|
220
402
|
private authRetriedAfterError;
|
|
221
403
|
private readonly authErrorHandlers;
|
|
404
|
+
private readonly developerCredentialHandlers;
|
|
222
405
|
private managedAuthAttempt;
|
|
223
406
|
private telemetryEnabled;
|
|
224
407
|
private readonly querySubscriptionRetentionMs;
|
|
@@ -241,8 +424,15 @@ export declare class GonvexClient {
|
|
|
241
424
|
private processedReplicaWatermarkRevision;
|
|
242
425
|
private readonly pendingReplicaTransactions;
|
|
243
426
|
private readonly unsubscribeOutbox;
|
|
427
|
+
private readonly sharedOutboxStore?;
|
|
428
|
+
private readonly unsubscribePeerOutbox?;
|
|
429
|
+
private readonly unsubscribePeerReplica?;
|
|
430
|
+
private peerRefreshScheduled;
|
|
431
|
+
private peerRefreshDirty;
|
|
244
432
|
private readonly unsubscribeBrowserOnline;
|
|
245
433
|
private drainingOutbox;
|
|
434
|
+
/** A wake-up (timer, enqueue, reconnect) that arrived while a drain was running. */
|
|
435
|
+
private outboxDrainRequested;
|
|
246
436
|
private outboxDrainTimer;
|
|
247
437
|
private readonly sessionScopeHandlers;
|
|
248
438
|
private readonly errorReporter;
|
|
@@ -254,11 +444,104 @@ export declare class GonvexClient {
|
|
|
254
444
|
private readonly pendingCalls;
|
|
255
445
|
private readonly connectionStateHandlers;
|
|
256
446
|
private readonly supportCommandHandlers;
|
|
447
|
+
private readonly pendingNativeErrors;
|
|
257
448
|
private isWebSocketConnected;
|
|
258
449
|
private hasEverConnected;
|
|
259
450
|
private connectionCount;
|
|
260
451
|
private readonly timeouts;
|
|
452
|
+
private readonly clientContract?;
|
|
453
|
+
private readonly updateRequiredHandler?;
|
|
454
|
+
private updateRequired;
|
|
455
|
+
private lastOnlineAtMs;
|
|
261
456
|
constructor(url: string, options?: GonvexClientOptions);
|
|
457
|
+
/**
|
|
458
|
+
* Authoritative sync failures arrive after an offline call returned locally.
|
|
459
|
+
* The intent also stays in the outbox as `rejected` until it is discarded
|
|
460
|
+
* or retried, so a UI that mounts later can still show it.
|
|
461
|
+
*/
|
|
462
|
+
onReducerRejection(listener: (event: ReducerRejectionEvent) => void): () => void;
|
|
463
|
+
/**
|
|
464
|
+
* Observe every point where a locally executing Reducer degrades to a
|
|
465
|
+
* queued-only intent (no local result). The intent is still durable and is
|
|
466
|
+
* delivered to the server; this exists so apps can log and fix the missing
|
|
467
|
+
* local data. Returns an unsubscribe function.
|
|
468
|
+
*/
|
|
469
|
+
onLocalExecutionFallback(listener: (event: LocalExecutionFallbackEvent) => void): () => void;
|
|
470
|
+
private reportLocalFallback;
|
|
471
|
+
/** Every durable intent of the current identity, oldest first. */
|
|
472
|
+
listIntents(): Promise<OutboxIntent[]>;
|
|
473
|
+
/**
|
|
474
|
+
* Synchronous snapshot for external stores (React `useSyncExternalStore`).
|
|
475
|
+
* Kept current while at least one {@link subscribeIntents} listener exists.
|
|
476
|
+
*/
|
|
477
|
+
intentsSnapshot(): readonly OutboxIntent[];
|
|
478
|
+
/** Observe intent changes; call {@link intentsSnapshot} for the new value. */
|
|
479
|
+
subscribeIntents(listener: () => void): () => void;
|
|
480
|
+
/**
|
|
481
|
+
* Delivery status for one row from the current snapshot: `failed` or
|
|
482
|
+
* `rejected` when an intent touching it needs attention, `syncing` while one
|
|
483
|
+
* is still queued, otherwise undefined.
|
|
484
|
+
*/
|
|
485
|
+
entityIntentStatus(entity: string, id: string): EntityIntentStatus | undefined;
|
|
486
|
+
/**
|
|
487
|
+
* Re-arm a `failed` or `rejected` intent with a fresh retry budget. The
|
|
488
|
+
* original idempotency key is reused, so an attempt that had actually
|
|
489
|
+
* committed is replayed by the server rather than applied twice.
|
|
490
|
+
*/
|
|
491
|
+
retryIntent(id: string): Promise<boolean>;
|
|
492
|
+
/**
|
|
493
|
+
* Drop a `pending`, `failed` or `rejected` intent: it will never be sent,
|
|
494
|
+
* its optimistic prediction is removed and later local intents are rebased.
|
|
495
|
+
* Inflight and committed intents cannot be discarded. Discarding an intent
|
|
496
|
+
* whose earlier attempt timed out does not undo a commit that the server
|
|
497
|
+
* may already have applied; the replica then shows the server's truth.
|
|
498
|
+
*/
|
|
499
|
+
discardIntent(id: string): Promise<boolean>;
|
|
500
|
+
/**
|
|
501
|
+
* Discard the persisted Local Replica of the active identity (IndexedDB,
|
|
502
|
+
* Expo SQLite or any configured storage) and rehydrate it from the server.
|
|
503
|
+
*
|
|
504
|
+
* Online only: without an authenticated connection the call rejects with a
|
|
505
|
+
* `GonvexClientError` (`code: "disconnected"`) and changes nothing, so the
|
|
506
|
+
* user is never left with an empty cache that cannot be refilled. The saved
|
|
507
|
+
* offline session (identity and replica directive) is kept.
|
|
508
|
+
*
|
|
509
|
+
* By default the outbox is untouched: pending, failed and rejected intents
|
|
510
|
+
* stay durable, and the predictions of every live intent are re-applied
|
|
511
|
+
* immediately and recomputed as server data arrives. Active Replica
|
|
512
|
+
* Collections and Live Queries are re-requested without their old cursors,
|
|
513
|
+
* so the server sends full snapshots.
|
|
514
|
+
*/
|
|
515
|
+
resetLocalReplica(options?: ResetLocalReplicaOptions): Promise<ResetLocalReplicaResult>;
|
|
516
|
+
/** Outbox owners with durable entries, including identities that never returned. */
|
|
517
|
+
listOutboxScopes(): Promise<OutboxScope[]>;
|
|
518
|
+
/**
|
|
519
|
+
* Permanently delete another identity's durable intents. The active scope
|
|
520
|
+
* cannot be purged this way; use {@link discardIntent} for its entries.
|
|
521
|
+
*/
|
|
522
|
+
purgeOutboxScope(scope: string): Promise<number>;
|
|
523
|
+
/** Purge every outbox scope except the current identity's. Never runs automatically. */
|
|
524
|
+
purgeForeignOutboxScopes(): Promise<number>;
|
|
525
|
+
private refreshIntents;
|
|
526
|
+
private publishIntents;
|
|
527
|
+
private restoreLocalSession;
|
|
528
|
+
private ensureLocalCollections;
|
|
529
|
+
private hydrateMissingLocalTable;
|
|
530
|
+
private localSnapshot;
|
|
531
|
+
private localReadCoverage;
|
|
532
|
+
private isUncoveredLocalRead;
|
|
533
|
+
private executeLocal;
|
|
534
|
+
private inLocalLane;
|
|
535
|
+
private replaceLocalPredictions;
|
|
536
|
+
private coordinateOutbox;
|
|
537
|
+
private refreshPeerOutbox;
|
|
538
|
+
private scheduleLocalReplay;
|
|
539
|
+
private reportLocalRejection;
|
|
540
|
+
private rebaseLocalEntries;
|
|
541
|
+
private rebaseLocalEntriesLocked;
|
|
542
|
+
private runLocalReducer;
|
|
543
|
+
/** Preload code for a mounted control without reading data or executing an intent. */
|
|
544
|
+
prepareReducer(ref: FunctionReference): Promise<void>;
|
|
262
545
|
/** The single normalized authoritative + optimistic application data store. */
|
|
263
546
|
get localReplica(): LocalReplicaView;
|
|
264
547
|
replicaSignature(ref: FunctionReference, args?: JsonValue): string;
|
|
@@ -266,11 +549,16 @@ export declare class GonvexClient {
|
|
|
266
549
|
retainedLiveQuery<T extends ReplicaRow = ReplicaRow>(signature: string): LiveQueryResult<T>;
|
|
267
550
|
/** Resolve an ordered ID batch from one normalized entity store. */
|
|
268
551
|
replicaEntities<T extends ReplicaRow = ReplicaRow>(entity: string, ids: readonly string[]): Array<T | undefined>;
|
|
552
|
+
/** Retain only the data an active view observes; cold rows remain on disk. */
|
|
553
|
+
retainReplicaEntities(entity: string, ids: readonly string[]): () => void;
|
|
554
|
+
retainReplicaWindow(signature: string): () => void;
|
|
269
555
|
/** Read rows and server-owned completeness for a persisted Replica Collection. */
|
|
270
556
|
replicaCollectionState<T extends ReplicaRow = ReplicaRow>(ref: FunctionReference, args?: JsonValue): ReplicaCollectionState<T>;
|
|
271
557
|
/** Run the generated Live Query plan over the bounded normalized cache. */
|
|
272
|
-
offlineLiveQuery<T extends ReplicaRow = ReplicaRow>(ref: FunctionReference, args?: JsonValue
|
|
273
|
-
|
|
558
|
+
offlineLiveQuery<T extends ReplicaRow = ReplicaRow>(ref: FunctionReference, args?: JsonValue, options?: {
|
|
559
|
+
window?: boolean;
|
|
560
|
+
}): OfflineLiveQueryResult<T>;
|
|
561
|
+
/** Number of reducers still queued for delivery (excludes failed and rejected intents). */
|
|
274
562
|
outboxCount(): Promise<number>;
|
|
275
563
|
connectionState(): ConnectionState;
|
|
276
564
|
/** Metadata advertised by the runtime in its latest session.ready frame. */
|
|
@@ -294,6 +582,15 @@ export declare class GonvexClient {
|
|
|
294
582
|
* degrading to an unauthenticated session.
|
|
295
583
|
*/
|
|
296
584
|
onAuthError(handler: (error: string) => void): () => void;
|
|
585
|
+
/**
|
|
586
|
+
* Subscribe to rotated developer-mode reconnect credentials. The runtime
|
|
587
|
+
* consumes each developer credential when it accepts a connection and
|
|
588
|
+
* returns a single-use successor; the client already uses that successor
|
|
589
|
+
* for its own reconnects. Auth providers subscribe so they can keep the
|
|
590
|
+
* newest credential in tab-scoped storage and resume developer mode after a
|
|
591
|
+
* page reload. The value is a secret: never log it or put it in a URL.
|
|
592
|
+
*/
|
|
593
|
+
onDeveloperCredential(handler: (token: string) => void): () => void;
|
|
297
594
|
private applyAuth;
|
|
298
595
|
connect(): void;
|
|
299
596
|
close(): void;
|
|
@@ -318,7 +615,9 @@ export declare class GonvexClient {
|
|
|
318
615
|
/** Subscribe to a bounded Replica Collection. */
|
|
319
616
|
subscribeReplica<Args extends JsonValue = JsonValue, Result extends JsonValue = JsonValue>(ref: FunctionReference<Args, Result>, args: Args | undefined, onMessage: ReplicaSubscriptionHandler): () => void;
|
|
320
617
|
/** Watch a bounded Replica Collection through the normalized Local Replica. */
|
|
321
|
-
watchReplica<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args
|
|
618
|
+
watchReplica<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args, options?: {
|
|
619
|
+
deferStart?: boolean;
|
|
620
|
+
}): {
|
|
322
621
|
localReplicaResult: () => T[] | undefined;
|
|
323
622
|
localReplicaState: () => ReplicaCollectionSubscriptionState | undefined;
|
|
324
623
|
status: () => {
|
|
@@ -332,7 +631,9 @@ export declare class GonvexClient {
|
|
|
332
631
|
* latest query result is retained only as the transport-shaped skeleton;
|
|
333
632
|
* its row window is always rebuilt from LocalReplica membership/entities.
|
|
334
633
|
*/
|
|
335
|
-
watchLiveQuery<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args
|
|
634
|
+
watchLiveQuery<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args, options?: {
|
|
635
|
+
deferStart?: boolean;
|
|
636
|
+
}): {
|
|
336
637
|
localLiveQueryResult: () => T | undefined;
|
|
337
638
|
onUpdate(handler: WatchUpdateHandler): () => void;
|
|
338
639
|
};
|
|
@@ -356,6 +657,8 @@ export declare class GonvexClient {
|
|
|
356
657
|
private unsubscribeReplicaListener;
|
|
357
658
|
private activateOutboxScope;
|
|
358
659
|
private activateReplicaDirective;
|
|
660
|
+
private setReplicaReady;
|
|
661
|
+
private setOutboxReady;
|
|
359
662
|
private quarantineReplicaScope;
|
|
360
663
|
private rejectMissingReplicaDirective;
|
|
361
664
|
private rejectReplicaDirective;
|
|
@@ -365,12 +668,32 @@ export declare class GonvexClient {
|
|
|
365
668
|
private rejectOptimisticReducer;
|
|
366
669
|
private ackOptimisticReducer;
|
|
367
670
|
private drainOutbox;
|
|
671
|
+
/**
|
|
672
|
+
* Record a non-rejection delivery failure and arm the next attempt.
|
|
673
|
+
* - update_required: keep the intent pending and stop for an app update.
|
|
674
|
+
* - unauthenticated: keep the intent, re-authenticate, retry with backoff
|
|
675
|
+
* that never spends the retry budget.
|
|
676
|
+
* - network: connectivity loss; retried on reconnect without spending budget.
|
|
677
|
+
* - transient (and timeouts): exponential backoff, parked as `failed` once
|
|
678
|
+
* the retry budget is spent.
|
|
679
|
+
*/
|
|
680
|
+
private recordDeliveryFailure;
|
|
681
|
+
/**
|
|
682
|
+
* Arm a timer for the earliest backed-off entry. Timer clocks and
|
|
683
|
+
* `Date.now()` can disagree by a millisecond, so a wake-up may find its
|
|
684
|
+
* entry not quite due; without this the queue would wait for an unrelated
|
|
685
|
+
* event to resume.
|
|
686
|
+
*/
|
|
687
|
+
private scheduleNextOutboxAttempt;
|
|
688
|
+
/** Re-send auth on the open socket so a lost tenant session is restored. */
|
|
689
|
+
private requestReauthentication;
|
|
368
690
|
private scheduleOutboxDrain;
|
|
369
691
|
reducer<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args: Args, options: CallOptions & {
|
|
370
692
|
offline: "queue";
|
|
371
693
|
}): Promise<T | QueuedReducerOutcome>;
|
|
372
694
|
reducer<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args, options?: CallOptions): Promise<T>;
|
|
373
695
|
private runOptimisticReducer;
|
|
696
|
+
private requireClientUpdate;
|
|
374
697
|
private canSendReducerNow;
|
|
375
698
|
action<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args, options?: CallOptions): Promise<T>;
|
|
376
699
|
query<T extends JsonValue = JsonValue, Args extends JsonValue = JsonValue>(ref: FunctionReference<Args, T>, args?: Args, options?: CallOptions): Promise<T>;
|
|
@@ -428,6 +751,8 @@ export declare class GonvexClient {
|
|
|
428
751
|
/** Send a bounded native error-telemetry frame using authenticated connection attribution. */
|
|
429
752
|
reportError(type: "register" | "envelope" | "heartbeat", payload: unknown): Promise<void>;
|
|
430
753
|
private sendNativeError;
|
|
754
|
+
private flushPendingNativeErrors;
|
|
755
|
+
private sendNativeErrorFrame;
|
|
431
756
|
private sendAuth;
|
|
432
757
|
private sendAuthFrame;
|
|
433
758
|
private settleManagedAuthAttempt;
|
|
@@ -440,3 +765,15 @@ export declare class GonvexClient {
|
|
|
440
765
|
private sendNow;
|
|
441
766
|
private flushPendingMessages;
|
|
442
767
|
}
|
|
768
|
+
/** Row status from a list of intents: failed > rejected > syncing. */
|
|
769
|
+
export declare function entityStatusFromIntents(intents: readonly OutboxIntent[], entity: string, id: string): EntityIntentStatus | undefined;
|
|
770
|
+
/**
|
|
771
|
+
* Dependency tables of locally executing Reducers that stay resident. A
|
|
772
|
+
* table qualifies when its unfiltered generated collection declares a small
|
|
773
|
+
* enough `maxRows` (and `maxBytes`, when bounded). Collections without a
|
|
774
|
+
* declared bound are never resident: their size is unknown.
|
|
775
|
+
*/
|
|
776
|
+
export declare function residentLocalDependencyTables(binding: {
|
|
777
|
+
collections?: readonly FunctionReference[];
|
|
778
|
+
localDependencies?: Readonly<Record<string, readonly string[]>>;
|
|
779
|
+
} | undefined, policy?: LocalDependencyResidency): string[];
|