@abloatai/ablo 0.24.0 → 0.26.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/AGENTS.md +5 -3
- package/CHANGELOG.md +33 -0
- package/README.md +45 -36
- package/dist/BaseSyncedStore.d.ts +72 -195
- package/dist/BaseSyncedStore.js +240 -625
- package/dist/Database.d.ts +8 -9
- package/dist/Database.js +9 -14
- package/dist/LazyReferenceCollection.js +5 -0
- package/dist/Model.js +6 -8
- package/dist/ModelRegistry.d.ts +25 -6
- package/dist/ModelRegistry.js +12 -6
- package/dist/NetworkMonitor.js +1 -1
- package/dist/ObjectPool.js +9 -3
- package/dist/SyncClient.d.ts +15 -5
- package/dist/SyncClient.js +152 -66
- package/dist/SyncEngineContext.d.ts +1 -3
- package/dist/SyncEngineContext.js +1 -2
- package/dist/agent/Agent.d.ts +21 -8
- package/dist/agent/Agent.js +26 -13
- package/dist/ai-sdk/coordination-context.js +9 -3
- package/dist/ai-sdk/wrap.d.ts +1 -1
- package/dist/ai-sdk/wrap.js +1 -1
- package/dist/auth/credentialPolicy.d.ts +10 -2
- package/dist/auth/credentialSource.d.ts +1 -13
- package/dist/auth/credentialSource.js +6 -13
- package/dist/auth/index.js +3 -3
- package/dist/cli.cjs +583 -287
- package/dist/client/Ablo.d.ts +35 -764
- package/dist/client/Ablo.js +64 -688
- package/dist/client/ApiClient.d.ts +14 -1
- package/dist/client/ApiClient.js +63 -9
- package/dist/client/auth.d.ts +8 -17
- package/dist/client/auth.js +42 -6
- package/dist/client/consoleLogger.d.ts +36 -0
- package/dist/client/consoleLogger.js +45 -0
- package/dist/client/createInternalComponents.js +1 -1
- package/dist/client/createModelProxy.js +10 -6
- package/dist/client/credentialEndpoint.d.ts +63 -0
- package/dist/client/credentialEndpoint.js +87 -0
- package/dist/client/hostedEndpoints.d.ts +24 -0
- package/dist/client/hostedEndpoints.js +24 -0
- package/dist/client/httpClient.d.ts +1 -1
- package/dist/client/identity.js +2 -1
- package/dist/client/modelRegistration.d.ts +14 -0
- package/dist/client/modelRegistration.js +321 -0
- package/dist/client/options.d.ts +396 -0
- package/dist/client/options.js +10 -0
- package/dist/client/resourceTypes.d.ts +344 -0
- package/dist/client/resourceTypes.js +13 -0
- package/dist/client/schemaConfig.d.ts +56 -0
- package/dist/client/schemaConfig.js +188 -0
- package/dist/client/sessionMint.d.ts +1 -1
- package/dist/client/validateAbloOptions.js +1 -1
- package/dist/client/wsMutationExecutor.d.ts +33 -0
- package/dist/client/wsMutationExecutor.js +77 -0
- package/dist/context.js +0 -3
- package/dist/coordination/index.d.ts +8 -1
- package/dist/coordination/index.js +24 -1
- package/dist/coordination/trace.d.ts +0 -1
- package/dist/coordination/trace.js +0 -1
- package/dist/core/DatabaseManager.d.ts +0 -1
- package/dist/core/DatabaseManager.js +26 -24
- package/dist/core/QueryProcessor.js +7 -8
- package/dist/core/QueryView.d.ts +14 -2
- package/dist/core/QueryView.js +4 -5
- package/dist/core/StoreManager.d.ts +2 -2
- package/dist/core/StoreManager.js +5 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/openIDBWithTimeout.js +15 -11
- package/dist/core/query-utils.js +1 -1
- package/dist/core/storeContract.d.ts +143 -0
- package/dist/core/storeContract.js +16 -0
- package/dist/errorCodes.d.ts +11 -2
- package/dist/errorCodes.js +155 -137
- package/dist/errors.d.ts +18 -7
- package/dist/errors.js +14 -1
- package/dist/index.js +5 -0
- package/dist/interfaces/index.d.ts +6 -20
- package/dist/keys/index.js +18 -9
- package/dist/mutators/UndoManager.js +6 -1
- package/dist/mutators/defineMutators.d.ts +1 -3
- package/dist/policy/types.d.ts +1 -1
- package/dist/query/client.d.ts +11 -0
- package/dist/query/client.js +81 -52
- package/dist/react/AbloProvider.d.ts +6 -10
- package/dist/react/AbloProvider.js +22 -15
- package/dist/react/context.d.ts +2 -118
- package/dist/react/useAblo.js +1 -1
- package/dist/react/useErrorListener.js +1 -1
- package/dist/react/useMutationFailureListener.js +1 -1
- package/dist/react/useMutators.js +7 -1
- package/dist/react/useReactive.js +0 -1
- package/dist/react/useUndoScope.js +2 -2
- package/dist/schema/ddlLock.d.ts +39 -0
- package/dist/schema/ddlLock.js +51 -0
- package/dist/schema/field.js +1 -1
- package/dist/schema/index.d.ts +4 -3
- package/dist/schema/index.js +15 -5
- package/dist/schema/model.d.ts +3 -3
- package/dist/schema/model.js +2 -2
- package/dist/schema/openapi.js +5 -1
- package/dist/schema/queries.d.ts +1 -1
- package/dist/schema/queries.js +1 -0
- package/dist/schema/residency.d.ts +35 -0
- package/dist/schema/residency.js +27 -0
- package/dist/schema/roles.d.ts +25 -0
- package/dist/schema/roles.js +37 -0
- package/dist/schema/schema.d.ts +3 -3
- package/dist/schema/schema.js +11 -7
- package/dist/schema/serialize.d.ts +8 -8
- package/dist/schema/sync-delta-row.d.ts +2 -2
- package/dist/schema/sync-delta-row.js +2 -2
- package/dist/server/storage-mode.d.ts +8 -1
- package/dist/server/storage-mode.js +14 -4
- package/dist/source/adapter.d.ts +1 -1
- package/dist/source/adapters/drizzle.js +4 -3
- package/dist/source/adapters/kysely.js +4 -3
- package/dist/source/adapters/memory.js +1 -1
- package/dist/source/adapters/prisma.js +5 -4
- package/dist/source/conformance.js +10 -8
- package/dist/source/connector.js +4 -2
- package/dist/source/factory.d.ts +106 -0
- package/dist/source/factory.js +273 -0
- package/dist/source/index.d.ts +11 -461
- package/dist/source/index.js +14 -416
- package/dist/source/next.d.ts +1 -1
- package/dist/source/next.js +1 -1
- package/dist/source/pushQueue.d.ts +1 -1
- package/dist/source/pushQueue.js +6 -3
- package/dist/source/signing.d.ts +59 -0
- package/dist/source/signing.js +142 -0
- package/dist/source/types.d.ts +334 -0
- package/dist/source/types.js +44 -0
- package/dist/stores/ObjectStore.d.ts +1 -1
- package/dist/stores/ObjectStore.js +23 -23
- package/dist/stores/SyncActionStore.d.ts +1 -1
- package/dist/stores/SyncActionStore.js +70 -35
- package/dist/surface.d.ts +1 -1
- package/dist/surface.js +1 -0
- package/dist/sync/AreaOfInterestManager.d.ts +2 -2
- package/dist/sync/AreaOfInterestManager.js +1 -1
- package/dist/sync/BootstrapHelper.d.ts +1 -3
- package/dist/sync/BootstrapHelper.js +29 -8
- package/dist/sync/ConnectionManager.d.ts +8 -0
- package/dist/sync/ConnectionManager.js +19 -4
- package/dist/sync/HydrationCoordinator.d.ts +12 -0
- package/dist/sync/HydrationCoordinator.js +25 -5
- package/dist/sync/NetworkProbe.d.ts +3 -2
- package/dist/sync/NetworkProbe.js +7 -6
- package/dist/sync/SyncWebSocket.d.ts +71 -120
- package/dist/sync/SyncWebSocket.js +324 -630
- package/dist/sync/awaitClaimGrant.js +27 -19
- package/dist/sync/bootstrapApply.d.ts +60 -0
- package/dist/sync/bootstrapApply.js +65 -0
- package/dist/sync/commitFrames.d.ts +43 -0
- package/dist/sync/commitFrames.js +94 -0
- package/dist/sync/createClaimStream.js +3 -2
- package/dist/sync/createSnapshot.d.ts +1 -3
- package/dist/sync/credentialLifecycle.d.ts +175 -0
- package/dist/sync/credentialLifecycle.js +329 -0
- package/dist/sync/deltaPipeline.d.ts +111 -0
- package/dist/sync/deltaPipeline.js +262 -0
- package/dist/sync/groupChange.d.ts +111 -0
- package/dist/sync/groupChange.js +246 -0
- package/dist/sync/heartbeat.d.ts +62 -0
- package/dist/sync/heartbeat.js +91 -0
- package/dist/sync/participants.d.ts +8 -8
- package/dist/sync/syncCursor.d.ts +44 -0
- package/dist/sync/syncCursor.js +59 -0
- package/dist/sync/syncPlan.d.ts +62 -0
- package/dist/sync/syncPlan.js +51 -0
- package/dist/sync/wsFrameHandlers.d.ts +117 -0
- package/dist/sync/wsFrameHandlers.js +378 -0
- package/dist/testing/fixtures/bootstrap.d.ts +9 -11
- package/dist/testing/fixtures/deltas.d.ts +1 -1
- package/dist/testing/fixtures/models.js +1 -0
- package/dist/testing/helpers/sync-engine-harness.d.ts +0 -3
- package/dist/testing/helpers/sync-engine-harness.js +2 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/mocks/MockSyncContext.d.ts +1 -17
- package/dist/testing/mocks/MockSyncContext.js +1 -32
- package/dist/testing/mocks/MockSyncStore.d.ts +4 -4
- package/dist/testing/mocks/MockWebSocket.d.ts +2 -2
- package/dist/transactions/TransactionQueue.d.ts +20 -56
- package/dist/transactions/TransactionQueue.js +101 -487
- package/dist/transactions/TransactionStore.d.ts +18 -0
- package/dist/transactions/TransactionStore.js +51 -0
- package/dist/transactions/coalesceRules.d.ts +34 -0
- package/dist/transactions/coalesceRules.js +117 -0
- package/dist/transactions/commitPayload.d.ts +134 -0
- package/dist/transactions/commitPayload.js +152 -0
- package/dist/transactions/deltaConfirmation.d.ts +60 -0
- package/dist/transactions/deltaConfirmation.js +223 -0
- package/dist/transactions/optimistic.d.ts +24 -0
- package/dist/transactions/optimistic.js +45 -0
- package/dist/transactions/persistedReplay.d.ts +93 -0
- package/dist/transactions/persistedReplay.js +105 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js +0 -5
- package/dist/types/modelData.d.ts +12 -0
- package/dist/types/modelData.js +11 -0
- package/dist/types/participant.d.ts +21 -0
- package/dist/types/participant.js +12 -0
- package/dist/types/streams.d.ts +8 -14
- package/dist/utils/mobx-setup.d.ts +1 -1
- package/dist/utils/mobx-setup.js +2 -2
- package/dist/wire/errorEnvelope.d.ts +11 -2
- package/dist/wire/errorEnvelope.js +14 -2
- package/dist/wire/frames.d.ts +90 -0
- package/dist/wire/frames.js +55 -1
- package/dist/wire/index.d.ts +4 -1
- package/dist/wire/index.js +20 -1
- package/dist/wire/protocol.d.ts +45 -0
- package/dist/wire/protocol.js +45 -0
- package/dist/wire/protocolVersion.d.ts +56 -0
- package/dist/wire/protocolVersion.js +63 -0
- package/docs/api-keys.md +4 -3
- package/docs/data-sources.md +12 -5
- package/docs/examples/existing-python-backend.md +3 -3
- package/docs/identity.md +4 -4
- package/docs/integration-guide.md +1 -1
- package/docs/react.md +1 -1
- package/docs/sessions.md +5 -7
- package/llms.txt +4 -2
- package/package.json +15 -13
- package/dist/client/index.d.ts +0 -36
- package/dist/client/index.js +0 -33
- package/dist/config/index.d.ts +0 -10
- package/dist/config/index.js +0 -12
- package/dist/interfaces/headless.d.ts +0 -95
- package/dist/interfaces/headless.js +0 -41
- package/dist/query/index.d.ts +0 -6
- package/dist/query/index.js +0 -5
- package/dist/realtime/index.d.ts +0 -10
- package/dist/realtime/index.js +0 -9
- package/dist/schema/plane.d.ts +0 -23
- package/dist/schema/plane.js +0 -19
- package/dist/server/next.d.ts +0 -51
- package/dist/server/next.js +0 -47
- package/dist/sync/OfflineFlush.d.ts +0 -9
- package/dist/sync/OfflineFlush.js +0 -22
- package/dist/sync/OfflineTransactionStore.d.ts +0 -37
- package/dist/sync/OfflineTransactionStore.js +0 -263
- package/dist/transactions/index.d.ts +0 -16
- package/dist/transactions/index.js +0 -7
|
@@ -9,17 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { EventEmitter } from 'events';
|
|
11
11
|
import type { MutationOperation } from '../interfaces/index.js';
|
|
12
|
-
import type
|
|
12
|
+
import { type ClientSyncDelta } from '../schema/sync-delta-wire.js';
|
|
13
13
|
import type { ClaimError, ClaimRejection, StaleNotification, ReadDependency } from '../coordination/schema.js';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* guarded write (`onStale: 'notify') hit a concurrent change — the
|
|
17
|
-
* advisory self-heal signal, surfaced both here and via `conflict:notified`.
|
|
18
|
-
*/
|
|
19
|
-
export interface CommitAck {
|
|
20
|
-
lastSyncId: number;
|
|
21
|
-
notifications?: StaleNotification[];
|
|
22
|
-
}
|
|
14
|
+
import { type CommitAck } from './commitFrames.js';
|
|
15
|
+
export type { CommitAck } from './commitFrames.js';
|
|
23
16
|
import { type AuthTokenGetter } from '../auth/credentialSource.js';
|
|
24
17
|
/**
|
|
25
18
|
* The wire delta the client receives. Derived from the canonical
|
|
@@ -57,18 +50,6 @@ export interface GroupRemovedPayload {
|
|
|
57
50
|
group: string;
|
|
58
51
|
userId: string;
|
|
59
52
|
}
|
|
60
|
-
export interface VersionVector {
|
|
61
|
-
tasks: number;
|
|
62
|
-
projects: number;
|
|
63
|
-
users: number;
|
|
64
|
-
events: number;
|
|
65
|
-
inboxitems: number;
|
|
66
|
-
teams: number;
|
|
67
|
-
assignments: number;
|
|
68
|
-
comments: number;
|
|
69
|
-
threads: number;
|
|
70
|
-
[entityType: string]: number;
|
|
71
|
-
}
|
|
72
53
|
export interface SyncCapabilities {
|
|
73
54
|
partialBootstrap?: boolean;
|
|
74
55
|
compressedDeltas?: boolean;
|
|
@@ -83,7 +64,6 @@ export interface SyncWebSocketOptions {
|
|
|
83
64
|
organizationId: string;
|
|
84
65
|
lastSyncId?: number;
|
|
85
66
|
syncGroups?: string[];
|
|
86
|
-
versions?: VersionVector;
|
|
87
67
|
capabilities?: SyncCapabilities;
|
|
88
68
|
reconnectDelay?: number;
|
|
89
69
|
maxReconnectDelay?: number;
|
|
@@ -181,7 +161,7 @@ export interface PresenceUpdateEvent {
|
|
|
181
161
|
/** Server stamps every presence frame with this participant's open
|
|
182
162
|
* claims so peers see them without a separate channel. Wire
|
|
183
163
|
* shape mirrors `apps/sync-server/src/hub/types.ts Claim`. */
|
|
184
|
-
activeClaims?:
|
|
164
|
+
activeClaims?: {
|
|
185
165
|
claimId: string;
|
|
186
166
|
entityType: string;
|
|
187
167
|
entityId: string;
|
|
@@ -205,7 +185,7 @@ export interface PresenceUpdateEvent {
|
|
|
205
185
|
*/
|
|
206
186
|
status?: 'active' | 'committed' | 'expired' | 'canceled';
|
|
207
187
|
error?: ClaimError;
|
|
208
|
-
}
|
|
188
|
+
}[];
|
|
209
189
|
localTime?: string;
|
|
210
190
|
type?: string;
|
|
211
191
|
timezone?: string;
|
|
@@ -335,20 +315,12 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
335
315
|
/** Periodic catchup interval — polls for missed deltas every 30s while connected */
|
|
336
316
|
private catchupInterval;
|
|
337
317
|
/**
|
|
338
|
-
* Application-level heartbeat
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
* socket if no inbound traffic arrives within 10s. ANY inbound message
|
|
345
|
-
* counts as proof-of-life — the explicit `pong` is just a guarantee that
|
|
346
|
-
* something will arrive even on an idle stream.
|
|
347
|
-
*/
|
|
348
|
-
private heartbeatTimer;
|
|
349
|
-
private heartbeatTimeoutTimer;
|
|
350
|
-
private static readonly HEARTBEAT_INTERVAL_MS;
|
|
351
|
-
private static readonly HEARTBEAT_TIMEOUT_MS;
|
|
318
|
+
* Application-level heartbeat — ping every 30s, force-close on a 10s
|
|
319
|
+
* silent watchdog. The full zombie-socket rationale lives with the
|
|
320
|
+
* timers in `sync/heartbeat.ts`; the transport closures below are the
|
|
321
|
+
* only socket access the controller gets.
|
|
322
|
+
*/
|
|
323
|
+
private readonly heartbeat;
|
|
352
324
|
private isConnecting;
|
|
353
325
|
private isManualClose;
|
|
354
326
|
/** When true, a session error has been detected (from any path — WS close or HTTP bootstrap).
|
|
@@ -376,11 +348,23 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
376
348
|
private lastCloseReason;
|
|
377
349
|
private lastForceCloseReason;
|
|
378
350
|
private sessionErrorAt;
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
351
|
+
/**
|
|
352
|
+
* Sync-position state (lastSyncId watermark, version vector, server
|
|
353
|
+
* cursor). The advance discipline stays documented at `sendAck` /
|
|
354
|
+
* `handleDelta`; the state itself lives in `sync/syncCursor.ts`.
|
|
355
|
+
*/
|
|
356
|
+
private readonly cursor;
|
|
382
357
|
/** Registered collaboration event keys (colon format) for dispatch in onmessage */
|
|
383
358
|
private collaborationEventTypes;
|
|
359
|
+
/**
|
|
360
|
+
* Minimal session adapter handed to the frame dispatch table
|
|
361
|
+
* (`sync/wsFrameHandlers.ts`). Exposes ONLY the members the handlers
|
|
362
|
+
* touch; the closure members read live state so host-side reassignment
|
|
363
|
+
* (e.g. the `pendingSubscriptions` reset on close) can't strand the
|
|
364
|
+
* handlers on a stale reference. Built in the constructor, after the
|
|
365
|
+
* state it captures exists.
|
|
366
|
+
*/
|
|
367
|
+
private readonly frameSession;
|
|
384
368
|
/**
|
|
385
369
|
* In-flight `commit` mutation requests keyed by clientTxId. Resolved when
|
|
386
370
|
* a matching `mutation_result` frame arrives from the server, or rejected on
|
|
@@ -410,6 +394,14 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
410
394
|
* Suppresses further reconnection attempts and Sentry error capture.
|
|
411
395
|
*/
|
|
412
396
|
setSessionErrorDetected(): void;
|
|
397
|
+
/**
|
|
398
|
+
* Clear the session-error latch so `connect()` / `scheduleReconnect()`
|
|
399
|
+
* work again. Called by the store's access-credential recovery path when
|
|
400
|
+
* the close was a re-mintable `ek_`/`rk_` expiry (`4001 credential_expired`),
|
|
401
|
+
* not a login loss — see `isAccessCredentialExpiryCloseReason`. Genuine
|
|
402
|
+
* session losses never clear the latch; re-auth builds a fresh client.
|
|
403
|
+
*/
|
|
404
|
+
clearSessionError(): void;
|
|
413
405
|
/**
|
|
414
406
|
* Connect to the sync engine WebSocket
|
|
415
407
|
*/
|
|
@@ -419,26 +411,39 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
419
411
|
*/
|
|
420
412
|
private setupEventHandlers;
|
|
421
413
|
/**
|
|
422
|
-
*
|
|
423
|
-
* (`
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
414
|
+
* Validate + normalize a wire delta at the receive boundary — the ONE
|
|
415
|
+
* seam every inbound delta (`delta` frame, batch element, `sync_response`
|
|
416
|
+
* replay, legacy bare frame) passes through before it is emitted,
|
|
417
|
+
* persisted to IDB, or allowed to advance any watermark.
|
|
418
|
+
*
|
|
419
|
+
* Normalization (older/deployed servers stay compatible):
|
|
420
|
+
* - `id`: the contract says `number`, but deployed servers have sent the
|
|
421
|
+
* raw Postgres BIGINT serialization — a STRING — and every downstream
|
|
422
|
+
* watermark gate (`typeof syncId === 'number'` in
|
|
423
|
+
* `Database.processDeltaBatch`, the metadata-cursor update, numeric
|
|
424
|
+
* `>=` thresholds in TransactionQueue) silently breaks on strings:
|
|
425
|
+
* acks are withheld, the resume cursor never advances, and every
|
|
426
|
+
* reconnect replays from 0. Coerce ONCE here.
|
|
427
|
+
* - `transactionId` / `createdBy`: the SERVER projection sends these as
|
|
428
|
+
* nullable (and `createdBy` as a nested ParticipantRef); the client
|
|
429
|
+
* contract types them as optional strings and never reads them.
|
|
430
|
+
* Normalize to absent instead of rejecting every real server delta.
|
|
431
|
+
*
|
|
432
|
+
* Validation: `clientSyncDeltaSchema.safeParse` — the canonical Zod wire
|
|
433
|
+
* contract. A frame that fails is DROPPED (returns `null`) with a
|
|
434
|
+
* debug-level log + observability breadcrumb; it is never applied. One
|
|
435
|
+
* parse per delta — callers must not re-parse.
|
|
432
436
|
*/
|
|
433
437
|
private normalizeWireDelta;
|
|
434
438
|
/**
|
|
435
|
-
* Handle incoming sync delta
|
|
439
|
+
* Handle incoming sync delta (untrusted wire input — validated and
|
|
440
|
+
* normalized by {@link normalizeWireDelta}; malformed deltas are dropped).
|
|
436
441
|
*/
|
|
437
442
|
private handleDelta;
|
|
438
443
|
/**
|
|
439
444
|
* Send acknowledgment for received delta with version vector.
|
|
440
445
|
*
|
|
441
|
-
* This is the SOLE forward-mover of `this.lastSyncId` for live
|
|
446
|
+
* This is the SOLE forward-mover of `this.cursor.lastSyncId` for live
|
|
442
447
|
* deltas. Called by `BaseSyncedStore.flushPendingDeltas` with the
|
|
443
448
|
* `persistedSyncId` watermark — i.e. only after the deltas have
|
|
444
449
|
* actually committed to IDB. Keeping the cursor advance here (rather
|
|
@@ -455,16 +460,6 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
455
460
|
* Send message to server
|
|
456
461
|
*/
|
|
457
462
|
send(message: any): void;
|
|
458
|
-
/**
|
|
459
|
-
* Project the SDK's `MutationOperation[]` onto the canonical wire
|
|
460
|
-
* `CommitMessage`. This is the single serialize boundary between the SDK op
|
|
461
|
-
* type (loose `type: string`, plus an SDK-internal `options` the server never
|
|
462
|
-
* reads) and the strict wire contract. The per-field map gives compile-time
|
|
463
|
-
* drift detection (a `CommitOperation` shape change breaks here) and the lone
|
|
464
|
-
* `as` narrows the validated op `type` to the wire union — the only
|
|
465
|
-
* loosening, localized to this boundary.
|
|
466
|
-
*/
|
|
467
|
-
private buildCommitFrame;
|
|
468
463
|
/**
|
|
469
464
|
* Send a `commit` mutation request over the existing WebSocket and
|
|
470
465
|
* resolve when the server's `mutation_result` frame comes back with
|
|
@@ -484,22 +479,7 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
484
479
|
* NOT auto-retry here — the caller's TransactionQueue owns retry +
|
|
485
480
|
* offline replay semantics and the SDK shouldn't duplicate that logic.
|
|
486
481
|
*/
|
|
487
|
-
|
|
488
|
-
* Defensively validate the optional `notifications` array off a commit ack.
|
|
489
|
-
* Untrusted wire data — a malformed entry is dropped rather than throwing,
|
|
490
|
-
* so a bad notification never sinks an otherwise-successful commit.
|
|
491
|
-
*/
|
|
492
|
-
private parseNotifications;
|
|
493
|
-
/**
|
|
494
|
-
* Single instrumentation point for claim events. Every `claim_*` frame routes
|
|
495
|
-
* through here so a developer debugging a collision gets one consistent trace
|
|
496
|
-
* — a console line AND a structured capture — without each dispatch case
|
|
497
|
-
* re-deriving the row/holder shape. The wire payload is loosely typed
|
|
498
|
-
* (`Record<string, unknown>`), so this is the one place that narrows it into
|
|
499
|
-
* a {@link ClaimEvent}.
|
|
500
|
-
*/
|
|
501
|
-
private recordClaim;
|
|
502
|
-
sendCommit(operations: ReadonlyArray<MutationOperation>, clientTxId: string, timeoutMs?: number, causedByTaskId?: string | null, reads?: readonly ReadDependency[] | null): Promise<CommitAck>;
|
|
482
|
+
sendCommit(operations: readonly MutationOperation[], clientTxId: string, timeoutMs?: number, causedByTaskId?: string | null, reads?: readonly ReadDependency[] | null): Promise<CommitAck>;
|
|
503
483
|
/**
|
|
504
484
|
* Send a commit frame without waiting for `mutation_result`.
|
|
505
485
|
*
|
|
@@ -508,7 +488,7 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
508
488
|
* eventual `mutation_result` frame is intentionally ignored by this
|
|
509
489
|
* instance because no pending resolver is registered.
|
|
510
490
|
*/
|
|
511
|
-
sendCommitQueued(operations:
|
|
491
|
+
sendCommitQueued(operations: readonly MutationOperation[], clientTxId: string, causedByTaskId?: string | null, reads?: readonly ReadDependency[] | null): void;
|
|
512
492
|
/**
|
|
513
493
|
* Activate a participant claim on this connection. Multiplexed
|
|
514
494
|
* subscription pattern (Phoenix Channels / Pusher) — the same
|
|
@@ -526,7 +506,7 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
526
506
|
* `apps/sync-server/docs/PARTICIPANT_CLAIMS.md` for the migration
|
|
527
507
|
* framing (Phase A.1).
|
|
528
508
|
*/
|
|
529
|
-
sendClaim(claimId: string, syncGroups:
|
|
509
|
+
sendClaim(claimId: string, syncGroups: readonly string[], options?: {
|
|
530
510
|
capabilityToken?: string;
|
|
531
511
|
ttlSeconds?: number;
|
|
532
512
|
timeoutMs?: number;
|
|
@@ -562,7 +542,7 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
562
542
|
* the read side and carries no capability token of its own; it's bounded
|
|
563
543
|
* by the connection credential's grant.
|
|
564
544
|
*/
|
|
565
|
-
updateSubscription(syncGroups:
|
|
545
|
+
updateSubscription(syncGroups: readonly string[], options?: {
|
|
566
546
|
timeoutMs?: number;
|
|
567
547
|
}): Promise<{
|
|
568
548
|
syncGroups: string[];
|
|
@@ -584,15 +564,15 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
584
564
|
/**
|
|
585
565
|
* Send spreadsheet selection presence
|
|
586
566
|
*/
|
|
587
|
-
sendSheetSelection(sheetId: string, selectedCells:
|
|
567
|
+
sendSheetSelection(sheetId: string, selectedCells: {
|
|
588
568
|
ref: string;
|
|
589
|
-
}
|
|
569
|
+
}[]): void;
|
|
590
570
|
/**
|
|
591
571
|
* Send slide layer selection presence
|
|
592
572
|
*/
|
|
593
|
-
sendSlideSelection(deckId: string, slideId: string, selectedLayers:
|
|
573
|
+
sendSlideSelection(deckId: string, slideId: string, selectedLayers: {
|
|
594
574
|
layerId: string;
|
|
595
|
-
}
|
|
575
|
+
}[]): void;
|
|
596
576
|
/**
|
|
597
577
|
* Send slide cursor position for real-time collaboration
|
|
598
578
|
* Note: Throttling should be handled by the caller (e.g., useSlideCursorBroadcast hook)
|
|
@@ -628,26 +608,6 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
628
608
|
* Disconnect from WebSocket
|
|
629
609
|
*/
|
|
630
610
|
disconnect(): void;
|
|
631
|
-
/**
|
|
632
|
-
* Application-level heartbeat. Every `HEARTBEAT_INTERVAL_MS` while
|
|
633
|
-
* `OPEN`, send `{ type: 'ping' }` and arm a `HEARTBEAT_TIMEOUT_MS`
|
|
634
|
-
* watchdog. Any inbound frame (handled in `onmessage`) clears the
|
|
635
|
-
* watchdog. If the watchdog fires, we treat the connection as
|
|
636
|
-
* zombie and force-close it — `onclose` then triggers the existing
|
|
637
|
-
* reconnect path.
|
|
638
|
-
*
|
|
639
|
-
* Why both sides need this:
|
|
640
|
-
* - The server sends RFC 6455 protocol pings via `ws.ping()` every
|
|
641
|
-
* 30s. Browsers auto-respond with a pong but DO NOT expose either
|
|
642
|
-
* frame to JavaScript, so the client is blind to its own keepalive.
|
|
643
|
-
* - On a half-open TCP (laptop wake, NAT timeout, mobile handoff)
|
|
644
|
-
* the browser may keep `readyState === OPEN` for minutes before
|
|
645
|
-
* the OS surfaces the broken connection. App-level traffic is
|
|
646
|
-
* the only signal we can observe.
|
|
647
|
-
*/
|
|
648
|
-
private startHeartbeat;
|
|
649
|
-
private stopHeartbeat;
|
|
650
|
-
private clearHeartbeatTimeout;
|
|
651
611
|
/**
|
|
652
612
|
* Force-close the socket from the client side using a private 4xxx
|
|
653
613
|
* code. Callers expect `onclose` to fire; that handler runs the
|
|
@@ -697,18 +657,6 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
697
657
|
* Update last sync ID (for persistence)
|
|
698
658
|
*/
|
|
699
659
|
setLastSyncId(syncId: number): void;
|
|
700
|
-
/**
|
|
701
|
-
* Get current version vector
|
|
702
|
-
*/
|
|
703
|
-
getVersionVector(): VersionVector;
|
|
704
|
-
/**
|
|
705
|
-
* Update version vector for specific entity type
|
|
706
|
-
*/
|
|
707
|
-
updateVersionVector(entityType: string, version: number): void;
|
|
708
|
-
/**
|
|
709
|
-
* Set version vector (for initialization)
|
|
710
|
-
*/
|
|
711
|
-
setVersionVector(versions: VersionVector): void;
|
|
712
660
|
/**
|
|
713
661
|
* Update sync cursor (for incremental sync)
|
|
714
662
|
*/
|
|
@@ -730,7 +678,10 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
730
678
|
*/
|
|
731
679
|
requestBootstrap(entities?: string[]): Promise<void>;
|
|
732
680
|
/**
|
|
733
|
-
* Handle sync response from server
|
|
681
|
+
* Handle sync response from server. Untrusted wire input — the envelope
|
|
682
|
+
* fields are narrowed defensively and every delta is validated through
|
|
683
|
+
* {@link normalizeWireDelta} (exactly once each; malformed ones drop out
|
|
684
|
+
* of the batch).
|
|
734
685
|
*/
|
|
735
686
|
private handleSyncResponse;
|
|
736
687
|
/**
|