@abloatai/ablo 0.25.0 → 0.27.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 +34 -0
- package/README.md +104 -88
- package/dist/BaseSyncedStore.d.ts +140 -266
- package/dist/BaseSyncedStore.js +338 -739
- package/dist/Database.d.ts +62 -77
- package/dist/Database.js +106 -127
- package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
- package/dist/{ObjectPool.js → InstanceCache.js} +91 -83
- package/dist/LazyReferenceCollection.d.ts +11 -15
- package/dist/LazyReferenceCollection.js +16 -15
- package/dist/Model.d.ts +37 -52
- package/dist/Model.js +52 -69
- package/dist/ModelRegistry.d.ts +46 -25
- package/dist/ModelRegistry.js +32 -30
- package/dist/NetworkMonitor.d.ts +5 -6
- package/dist/NetworkMonitor.js +6 -7
- package/dist/SyncClient.d.ts +119 -109
- package/dist/SyncClient.js +303 -224
- package/dist/SyncEngineContext.d.ts +1 -3
- package/dist/SyncEngineContext.js +1 -2
- package/dist/adapters/alwaysOnline.d.ts +6 -8
- package/dist/adapters/alwaysOnline.js +6 -8
- package/dist/adapters/inMemoryStorage.d.ts +9 -9
- package/dist/adapters/inMemoryStorage.js +9 -9
- package/dist/agent/Agent.d.ts +39 -31
- package/dist/agent/Agent.js +35 -23
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +5 -5
- package/dist/agent/session.d.ts +47 -44
- package/dist/agent/session.js +37 -48
- package/dist/agent/types.d.ts +26 -31
- package/dist/agent/types.js +6 -7
- package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
- package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
- package/dist/ai-sdk/coordinationContext.d.ts +46 -0
- package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +30 -31
- package/dist/ai-sdk/index.d.ts +25 -22
- package/dist/ai-sdk/index.js +25 -22
- package/dist/ai-sdk/wrap.d.ts +7 -8
- package/dist/ai-sdk/wrap.js +2 -2
- package/dist/auth/credentialPolicy.d.ts +74 -71
- package/dist/auth/credentialPolicy.js +51 -56
- package/dist/auth/credentialSource.d.ts +7 -18
- package/dist/auth/credentialSource.js +10 -18
- package/dist/auth/index.d.ts +59 -58
- package/dist/auth/index.js +34 -40
- package/dist/auth/schemas.d.ts +5 -4
- package/dist/auth/schemas.js +5 -4
- package/dist/batching/index.d.ts +19 -21
- package/dist/batching/index.js +14 -17
- package/dist/cli.cjs +483 -369
- package/dist/client/Ablo.d.ts +107 -836
- package/dist/client/Ablo.js +174 -833
- package/dist/client/ApiClient.d.ts +44 -20
- package/dist/client/ApiClient.js +193 -44
- package/dist/client/auth.d.ts +51 -60
- package/dist/client/auth.js +137 -110
- package/dist/client/claimHeartbeatLoop.d.ts +50 -0
- package/dist/client/claimHeartbeatLoop.js +88 -0
- package/dist/client/consoleLogger.d.ts +35 -0
- package/dist/client/consoleLogger.js +44 -0
- package/dist/client/createInternalComponents.d.ts +14 -17
- package/dist/client/createInternalComponents.js +26 -31
- package/dist/client/createModelProxy.d.ts +130 -120
- package/dist/client/createModelProxy.js +158 -124
- package/dist/client/credentialEndpoint.d.ts +61 -0
- package/dist/client/credentialEndpoint.js +86 -0
- package/dist/client/functionalUpdate.d.ts +29 -27
- package/dist/client/functionalUpdate.js +21 -21
- package/dist/client/hostedEndpoints.d.ts +21 -0
- package/dist/client/hostedEndpoints.js +21 -0
- package/dist/client/httpClient.d.ts +58 -54
- package/dist/client/httpClient.js +29 -31
- package/dist/client/identity.d.ts +15 -20
- package/dist/client/identity.js +49 -59
- package/dist/client/modelRegistration.d.ts +10 -0
- package/dist/client/modelRegistration.js +301 -0
- package/dist/client/options.d.ts +373 -0
- package/dist/client/options.js +6 -0
- package/dist/client/registerDataSource.d.ts +9 -9
- package/dist/client/registerDataSource.js +15 -16
- package/dist/client/resourceTypes.d.ts +333 -0
- package/dist/client/resourceTypes.js +7 -0
- package/dist/client/schemaConfig.d.ts +44 -0
- package/dist/client/schemaConfig.js +176 -0
- package/dist/client/sessionMint.d.ts +17 -13
- package/dist/client/sessionMint.js +26 -31
- package/dist/client/validateAbloOptions.d.ts +12 -14
- package/dist/client/validateAbloOptions.js +9 -10
- package/dist/client/writeOptionsSchema.d.ts +18 -16
- package/dist/client/writeOptionsSchema.js +23 -20
- package/dist/client/wsMutationExecutor.d.ts +28 -0
- package/dist/client/wsMutationExecutor.js +71 -0
- package/dist/context.d.ts +6 -4
- package/dist/context.js +6 -7
- package/dist/coordination/index.d.ts +13 -4
- package/dist/coordination/index.js +29 -4
- package/dist/coordination/schema.d.ts +176 -128
- package/dist/coordination/schema.js +197 -133
- package/dist/coordination/trace.d.ts +9 -11
- package/dist/coordination/trace.js +13 -15
- package/dist/core/DatabaseManager.d.ts +5 -8
- package/dist/core/DatabaseManager.js +38 -40
- package/dist/core/QueryProcessor.d.ts +7 -9
- package/dist/core/QueryProcessor.js +27 -34
- package/dist/core/QueryView.d.ts +17 -5
- package/dist/core/QueryView.js +6 -7
- package/dist/core/StoreManager.d.ts +14 -16
- package/dist/core/StoreManager.js +26 -25
- package/dist/core/ViewRegistry.d.ts +5 -5
- package/dist/core/ViewRegistry.js +4 -4
- package/dist/core/index.d.ts +18 -13
- package/dist/core/index.js +32 -26
- package/dist/core/openIDBWithTimeout.d.ts +38 -36
- package/dist/core/openIDBWithTimeout.js +57 -54
- package/dist/core/queryUtils.d.ts +45 -0
- package/dist/core/queryUtils.js +69 -0
- package/dist/core/storeContract.d.ts +145 -0
- package/dist/core/storeContract.js +12 -0
- package/dist/environment.d.ts +28 -0
- package/dist/environment.js +21 -0
- package/dist/errorCodes.d.ts +118 -101
- package/dist/errorCodes.js +277 -260
- package/dist/errors.d.ts +170 -165
- package/dist/errors.js +161 -151
- package/dist/index.d.ts +30 -27
- package/dist/index.js +90 -82
- package/dist/interfaces/index.d.ts +108 -133
- package/dist/interfaces/index.js +5 -4
- package/dist/keys/index.d.ts +27 -29
- package/dist/keys/index.js +59 -49
- package/dist/mutators/RecordingTransaction.d.ts +16 -16
- package/dist/mutators/RecordingTransaction.js +31 -37
- package/dist/mutators/Transaction.d.ts +18 -26
- package/dist/mutators/Transaction.js +14 -20
- package/dist/mutators/UndoManager.d.ts +122 -131
- package/dist/mutators/UndoManager.js +149 -155
- package/dist/mutators/defineMutators.d.ts +24 -37
- package/dist/mutators/defineMutators.js +14 -20
- package/dist/mutators/inverseOp.d.ts +12 -15
- package/dist/mutators/inverseOp.js +12 -15
- package/dist/mutators/mutateActions.d.ts +10 -9
- package/dist/mutators/mutateActions.js +1 -1
- package/dist/mutators/readerActions.d.ts +9 -8
- package/dist/mutators/readerActions.js +2 -2
- package/dist/mutators/undoApply.d.ts +31 -27
- package/dist/mutators/undoApply.js +26 -24
- package/dist/policy/index.d.ts +5 -3
- package/dist/policy/index.js +5 -3
- package/dist/policy/types.d.ts +105 -101
- package/dist/policy/types.js +67 -66
- package/dist/query/client.d.ts +32 -16
- package/dist/query/client.js +103 -72
- package/dist/query/types.d.ts +37 -60
- package/dist/query/types.js +13 -33
- package/dist/react/AbloProvider.d.ts +7 -11
- package/dist/react/AbloProvider.js +24 -17
- package/dist/react/context.d.ts +27 -146
- package/dist/react/context.js +9 -10
- package/dist/react/index.d.ts +41 -42
- package/dist/react/index.js +37 -38
- package/dist/react/internalContext.d.ts +17 -19
- package/dist/react/useAblo.d.ts +23 -22
- package/dist/react/useAblo.js +17 -15
- package/dist/react/useCurrentUserId.d.ts +8 -7
- package/dist/react/useCurrentUserId.js +8 -7
- package/dist/react/useErrorListener.d.ts +7 -7
- package/dist/react/useErrorListener.js +11 -12
- package/dist/react/useMutationFailureListener.d.ts +8 -8
- package/dist/react/useMutationFailureListener.js +9 -9
- package/dist/react/useMutators.d.ts +11 -11
- package/dist/react/useMutators.js +10 -4
- package/dist/react/useReactive.js +2 -3
- package/dist/react/useSyncStatus.d.ts +4 -6
- package/dist/react/useUndoScope.d.ts +7 -9
- package/dist/react/useUndoScope.js +3 -3
- package/dist/schema/coordination.d.ts +21 -25
- package/dist/schema/coordination.js +21 -25
- package/dist/schema/ddl.d.ts +43 -39
- package/dist/schema/ddl.js +75 -68
- package/dist/schema/ddlLock.d.ts +35 -0
- package/dist/schema/ddlLock.js +46 -0
- package/dist/schema/diff.d.ts +99 -61
- package/dist/schema/diff.js +43 -34
- package/dist/schema/field.d.ts +37 -42
- package/dist/schema/field.js +36 -49
- package/dist/schema/generate.d.ts +12 -12
- package/dist/schema/generate.js +12 -12
- package/dist/schema/index.d.ts +5 -4
- package/dist/schema/index.js +29 -21
- package/dist/schema/model.d.ts +121 -146
- package/dist/schema/model.js +24 -35
- package/dist/schema/openapi.d.ts +10 -9
- package/dist/schema/openapi.js +7 -1
- package/dist/schema/queries.d.ts +30 -32
- package/dist/schema/queries.js +24 -25
- package/dist/schema/relation.d.ts +89 -99
- package/dist/schema/relation.js +13 -13
- package/dist/schema/residency.d.ts +38 -0
- package/dist/schema/residency.js +30 -0
- package/dist/schema/roles.d.ts +45 -27
- package/dist/schema/roles.js +52 -21
- package/dist/schema/schema.d.ts +36 -45
- package/dist/schema/schema.js +42 -39
- package/dist/schema/select.d.ts +13 -13
- package/dist/schema/select.js +13 -13
- package/dist/schema/serialize.d.ts +36 -39
- package/dist/schema/serialize.js +27 -31
- package/dist/schema/sugar.d.ts +17 -32
- package/dist/schema/sugar.js +14 -29
- package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +27 -50
- package/dist/schema/syncDeltaRow.js +89 -0
- package/dist/schema/tenancy.d.ts +44 -46
- package/dist/schema/tenancy.js +46 -48
- package/dist/server/adapter.d.ts +58 -58
- package/dist/server/adapter.js +13 -14
- package/dist/server/commit.d.ts +60 -64
- package/dist/server/index.d.ts +9 -10
- package/dist/server/index.js +1 -1
- package/dist/server/readConfig.d.ts +70 -0
- package/dist/server/readConfig.js +8 -0
- package/dist/server/storageMode.d.ts +23 -0
- package/dist/server/storageMode.js +17 -0
- package/dist/source/adapter.d.ts +31 -26
- package/dist/source/adapter.js +10 -10
- package/dist/source/adapters/drizzle.d.ts +28 -23
- package/dist/source/adapters/drizzle.js +34 -28
- package/dist/source/adapters/kysely.d.ts +27 -25
- package/dist/source/adapters/kysely.js +28 -26
- package/dist/source/adapters/memory.d.ts +8 -7
- package/dist/source/adapters/memory.js +10 -9
- package/dist/source/adapters/prisma.d.ts +13 -12
- package/dist/source/adapters/prisma.js +27 -29
- package/dist/source/conformance.d.ts +18 -11
- package/dist/source/conformance.js +27 -19
- package/dist/source/connector.d.ts +31 -32
- package/dist/source/connector.js +30 -28
- package/dist/source/connectorProtocol.d.ts +160 -0
- package/dist/source/connectorProtocol.js +162 -0
- package/dist/source/contract.d.ts +26 -27
- package/dist/source/contract.js +28 -29
- package/dist/source/factory.d.ts +94 -0
- package/dist/source/factory.js +268 -0
- package/dist/source/index.d.ts +10 -462
- package/dist/source/index.js +17 -421
- package/dist/source/migrations.d.ts +9 -9
- package/dist/source/migrations.js +9 -9
- package/dist/source/next.d.ts +10 -11
- package/dist/source/next.js +7 -8
- package/dist/source/pushQueue.d.ts +70 -48
- package/dist/source/pushQueue.js +36 -29
- package/dist/source/signing.d.ts +88 -0
- package/dist/source/signing.js +159 -0
- package/dist/source/types.d.ts +351 -0
- package/dist/source/types.js +43 -0
- package/dist/stores/ObjectStore.d.ts +11 -12
- package/dist/stores/ObjectStore.js +34 -35
- package/dist/stores/ObjectStoreContract.d.ts +12 -15
- package/dist/stores/SyncActionStore.d.ts +8 -12
- package/dist/stores/SyncActionStore.js +77 -46
- package/dist/surface.d.ts +28 -21
- package/dist/surface.js +28 -20
- package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +37 -45
- package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +101 -80
- package/dist/sync/ConnectionManager.d.ts +47 -50
- package/dist/sync/ConnectionManager.js +74 -70
- package/dist/sync/NetworkProbe.d.ts +27 -31
- package/dist/sync/NetworkProbe.js +67 -72
- package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +49 -36
- package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +79 -54
- package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +45 -59
- package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +44 -52
- package/dist/sync/SyncWebSocket.d.ts +175 -250
- package/dist/sync/SyncWebSocket.js +431 -769
- package/dist/sync/awaitClaimGrant.d.ts +18 -18
- package/dist/sync/awaitClaimGrant.js +38 -30
- package/dist/sync/bootstrapApply.d.ts +70 -0
- package/dist/sync/bootstrapApply.js +73 -0
- package/dist/sync/commitFrames.d.ts +44 -0
- package/dist/sync/commitFrames.js +94 -0
- package/dist/sync/createClaimStream.d.ts +23 -22
- package/dist/sync/createClaimStream.js +108 -25
- package/dist/sync/createPresenceStream.d.ts +19 -18
- package/dist/sync/createPresenceStream.js +25 -26
- package/dist/sync/createSnapshot.d.ts +13 -17
- package/dist/sync/createSnapshot.js +20 -26
- package/dist/sync/credentialLifecycle.d.ts +175 -0
- package/dist/sync/credentialLifecycle.js +322 -0
- package/dist/sync/deltaPipeline.d.ts +113 -0
- package/dist/sync/deltaPipeline.js +261 -0
- package/dist/sync/groupChange.d.ts +113 -0
- package/dist/sync/groupChange.js +242 -0
- package/dist/sync/heartbeat.d.ts +63 -0
- package/dist/sync/heartbeat.js +91 -0
- package/dist/sync/participants.d.ts +27 -27
- package/dist/sync/schemas.d.ts +3 -2
- package/dist/sync/schemas.js +14 -10
- package/dist/sync/syncCursor.d.ts +40 -0
- package/dist/sync/syncCursor.js +55 -0
- package/dist/sync/syncPlan.d.ts +54 -0
- package/dist/sync/syncPlan.js +50 -0
- package/dist/sync/syncPosition.d.ts +54 -49
- package/dist/sync/syncPosition.js +57 -52
- package/dist/sync/wsFrameHandlers.d.ts +116 -0
- package/dist/sync/wsFrameHandlers.js +374 -0
- package/dist/testing/fixtures/bootstrap.d.ts +21 -17
- package/dist/testing/fixtures/bootstrap.js +12 -6
- package/dist/testing/fixtures/deltas.d.ts +31 -34
- package/dist/testing/fixtures/deltas.js +30 -33
- package/dist/testing/fixtures/models.d.ts +11 -10
- package/dist/testing/fixtures/models.js +12 -10
- package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
- package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
- package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -18
- package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +14 -11
- package/dist/testing/helpers/wait.d.ts +13 -8
- package/dist/testing/helpers/wait.js +13 -8
- package/dist/testing/index.d.ts +4 -4
- package/dist/testing/index.js +3 -3
- package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
- package/dist/testing/mocks/MockMutationExecutor.js +15 -14
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
- package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
- package/dist/testing/mocks/MockSyncContext.d.ts +21 -34
- package/dist/testing/mocks/MockSyncContext.js +16 -45
- package/dist/testing/mocks/MockSyncStore.d.ts +14 -14
- package/dist/testing/mocks/MockSyncStore.js +11 -11
- package/dist/testing/mocks/MockWebSocket.d.ts +28 -24
- package/dist/testing/mocks/MockWebSocket.js +22 -21
- package/dist/transactions/TransactionQueue.d.ts +190 -221
- package/dist/transactions/TransactionQueue.js +424 -822
- package/dist/transactions/TransactionStore.d.ts +20 -0
- package/dist/transactions/TransactionStore.js +53 -0
- package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
- package/dist/transactions/UnconfirmedWrites.js +104 -0
- package/dist/transactions/coalesceRules.d.ts +58 -0
- package/dist/transactions/coalesceRules.js +140 -0
- package/dist/transactions/commitPayload.d.ts +130 -0
- package/dist/transactions/commitPayload.js +143 -0
- package/dist/transactions/deltaConfirmation.d.ts +58 -0
- package/dist/transactions/deltaConfirmation.js +215 -0
- package/dist/transactions/optimisticApply.d.ts +49 -0
- package/dist/transactions/optimisticApply.js +65 -0
- package/dist/transactions/replayValidation.d.ts +99 -0
- package/dist/transactions/replayValidation.js +111 -0
- package/dist/types/global.d.ts +46 -41
- package/dist/types/global.js +20 -19
- package/dist/types/index.d.ts +74 -80
- package/dist/types/index.js +22 -27
- package/dist/types/modelData.d.ts +10 -0
- package/dist/types/modelData.js +9 -0
- package/dist/types/participant.d.ts +20 -0
- package/dist/types/participant.js +10 -0
- package/dist/types/streams.d.ts +216 -209
- package/dist/types/streams.js +7 -7
- package/dist/utils/asyncIterator.d.ts +25 -32
- package/dist/utils/asyncIterator.js +25 -32
- package/dist/utils/duration.d.ts +12 -15
- package/dist/utils/duration.js +12 -15
- package/dist/utils/mobxSetup.d.ts +53 -0
- package/dist/utils/{mobx-setup.js → mobxSetup.js} +44 -100
- package/dist/webhooks/events.d.ts +21 -16
- package/dist/webhooks/events.js +10 -8
- package/dist/webhooks/index.d.ts +5 -7
- package/dist/webhooks/index.js +5 -7
- package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
- package/dist/wire/delta.js +114 -0
- package/dist/wire/errorEnvelope.d.ts +35 -27
- package/dist/wire/errorEnvelope.js +38 -32
- package/dist/wire/frames.d.ts +150 -67
- package/dist/wire/frames.js +48 -1
- package/dist/wire/index.d.ts +18 -13
- package/dist/wire/index.js +36 -13
- package/dist/wire/listEnvelope.d.ts +16 -23
- package/dist/wire/listEnvelope.js +7 -6
- package/dist/wire/protocol.d.ts +38 -0
- package/dist/wire/protocol.js +38 -0
- package/dist/wire/protocolVersion.d.ts +60 -0
- package/dist/wire/protocolVersion.js +67 -0
- package/docs/api-keys.md +4 -3
- package/docs/coordination.md +59 -0
- 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/package.json +24 -21
- package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
- package/dist/ai-sdk/coordination-context.d.ts +0 -52
- 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/core/query-utils.d.ts +0 -34
- package/dist/core/query-utils.js +0 -59
- 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/schema/sync-delta-row.js +0 -103
- package/dist/schema/sync-delta-wire.js +0 -102
- package/dist/server/next.d.ts +0 -51
- package/dist/server/next.js +0 -47
- package/dist/server/read-config.d.ts +0 -67
- package/dist/server/read-config.js +0 -8
- package/dist/server/storage-mode.d.ts +0 -1
- package/dist/server/storage-mode.js +0 -18
- package/dist/source/connector-protocol.d.ts +0 -159
- package/dist/source/connector-protocol.js +0 -161
- 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/OptimisticEchoTracker.d.ts +0 -82
- package/dist/transactions/OptimisticEchoTracker.js +0 -104
- package/dist/transactions/index.d.ts +0 -16
- package/dist/transactions/index.js +0 -7
- package/dist/transactions/mutation-error-handler.d.ts +0 -5
- package/dist/transactions/mutation-error-handler.js +0 -39
- package/dist/utils/mobx-setup.d.ts +0 -42
|
@@ -1,74 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - Automatic reconnection with exponential backoff
|
|
2
|
+
* Manages the WebSocket connection to the sync server. It owns the socket
|
|
3
|
+
* lifecycle (connect, reconnect, disconnect), receives and validates the
|
|
4
|
+
* incoming delta stream, sends commits and claims over the same socket, and
|
|
5
|
+
* reconnects automatically with exponential backoff. Consumers subscribe to its
|
|
6
|
+
* typed events (see {@link CoreSyncEventMap}) to react to deltas, presence, and
|
|
7
|
+
* connection changes.
|
|
9
8
|
*/
|
|
10
9
|
import { EventEmitter } from 'events';
|
|
11
10
|
import type { MutationOperation } from '../interfaces/index.js';
|
|
12
|
-
import type
|
|
11
|
+
import { type ClientSyncDelta } from '../wire/delta.js';
|
|
13
12
|
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
|
-
}
|
|
13
|
+
import { type CommitAck } from './commitFrames.js';
|
|
14
|
+
export type { CommitAck } from './commitFrames.js';
|
|
23
15
|
import { type AuthTokenGetter } from '../auth/credentialSource.js';
|
|
24
16
|
/**
|
|
25
|
-
* The wire delta the client receives.
|
|
26
|
-
* `clientSyncDeltaSchema`
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
17
|
+
* The wire delta the client receives. It is inferred from the canonical
|
|
18
|
+
* `clientSyncDeltaSchema` so the client and server share one contract rather
|
|
19
|
+
* than two hand-maintained definitions. The action vocabulary
|
|
20
|
+
* (`I`/`U`/`D`/`A`/`V`/`C`/`G`/`S`) and the client-only extras (`metadata`,
|
|
21
|
+
* `clientMutationId`, and the deprecated flat `createdBy`) live in that schema;
|
|
22
|
+
* see its own documentation for the full field reference.
|
|
31
23
|
*/
|
|
32
24
|
export type SyncDelta = ClientSyncDelta;
|
|
33
25
|
/**
|
|
34
|
-
* Payload for
|
|
35
|
-
*
|
|
26
|
+
* Payload for an older actionType `'G'` delta. It carries both the added and
|
|
27
|
+
* removed sync groups in one delta and forces a full re-bootstrap.
|
|
36
28
|
*/
|
|
37
29
|
export interface SyncGroupChangePayload {
|
|
38
30
|
removedGroups: string[];
|
|
39
31
|
addedGroups: string[];
|
|
40
32
|
}
|
|
41
33
|
/**
|
|
42
|
-
* Payload for incremental actionType 'G'
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* re-bootstrap required.
|
|
34
|
+
* Payload for an incremental actionType `'G'` delta. It signals that the
|
|
35
|
+
* recipient has joined a single sync group; the following `'C'` (covering)
|
|
36
|
+
* deltas deliver the newly visible entities. No re-bootstrap is required.
|
|
46
37
|
*/
|
|
47
38
|
export interface GroupAddedPayload {
|
|
48
39
|
group: string;
|
|
49
40
|
userId: string;
|
|
50
41
|
}
|
|
51
42
|
/**
|
|
52
|
-
* Payload for actionType 'S'
|
|
53
|
-
*
|
|
54
|
-
*
|
|
43
|
+
* Payload for an actionType `'S'` delta. It signals that the recipient has lost
|
|
44
|
+
* access to a sync group; the client purges the affected local entities and
|
|
45
|
+
* updates its subscription metadata.
|
|
55
46
|
*/
|
|
56
47
|
export interface GroupRemovedPayload {
|
|
57
48
|
group: string;
|
|
58
49
|
userId: string;
|
|
59
50
|
}
|
|
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
51
|
export interface SyncCapabilities {
|
|
73
52
|
partialBootstrap?: boolean;
|
|
74
53
|
compressedDeltas?: boolean;
|
|
@@ -83,7 +62,6 @@ export interface SyncWebSocketOptions {
|
|
|
83
62
|
organizationId: string;
|
|
84
63
|
lastSyncId?: number;
|
|
85
64
|
syncGroups?: string[];
|
|
86
|
-
versions?: VersionVector;
|
|
87
65
|
capabilities?: SyncCapabilities;
|
|
88
66
|
reconnectDelay?: number;
|
|
89
67
|
maxReconnectDelay?: number;
|
|
@@ -93,27 +71,25 @@ export interface SyncWebSocketOptions {
|
|
|
93
71
|
*/
|
|
94
72
|
collaborationEvents?: string[];
|
|
95
73
|
/**
|
|
96
|
-
*
|
|
97
|
-
* (session
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* session auth. The server reads this as the `kind` query param.
|
|
74
|
+
* The participant kind declared on the WebSocket upgrade. Defaults to
|
|
75
|
+
* `'user'` (session auth, the web app). Agent runtimes pass `'agent'` so the
|
|
76
|
+
* server verifies them by capability token instead of session auth. The
|
|
77
|
+
* server reads this as the `kind` query parameter.
|
|
101
78
|
*/
|
|
102
79
|
kind?: 'user' | 'agent' | 'system';
|
|
103
80
|
/**
|
|
104
|
-
* The agent's bearer credential — a restricted (`rk_`) API key. When
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* migration.)
|
|
81
|
+
* The agent's bearer credential — a restricted (`rk_`) API key. When set, it
|
|
82
|
+
* is sent in the `ablo.bearer.<token>` WebSocket subprotocol so the credential
|
|
83
|
+
* stays out of URLs and proxy logs. Required for `kind: 'agent'` and ignored
|
|
84
|
+
* for `kind: 'user'`.
|
|
109
85
|
*/
|
|
110
86
|
capabilityToken?: string;
|
|
111
87
|
/**
|
|
112
|
-
*
|
|
113
|
-
* instead of a copied `capabilityToken`, so reconnects use
|
|
114
|
-
* from the SDK's single
|
|
88
|
+
* Getter for the current credential. When provided, the WebSocket upgrade
|
|
89
|
+
* reads it instead of a copied `capabilityToken`, so reconnects always use
|
|
90
|
+
* the freshest token from the SDK's single credential source. Preferred over
|
|
91
|
+
* `getCapabilityToken`.
|
|
115
92
|
*/
|
|
116
|
-
/** Shared SDK auth getter. Preferred internal name. */
|
|
117
93
|
getAuthToken?: AuthTokenGetter;
|
|
118
94
|
/** @deprecated Use `getAuthToken`. Kept for direct low-level callers. */
|
|
119
95
|
getCapabilityToken?: AuthTokenGetter;
|
|
@@ -136,14 +112,11 @@ export interface BootstrapDataEvent {
|
|
|
136
112
|
cursor?: string;
|
|
137
113
|
}
|
|
138
114
|
/**
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* the union of what the server actually sends. Stripping fields at
|
|
145
|
-
* this layer (the prior bug) silently broke rich-presence consumers
|
|
146
|
-
* that needed `kind`, `activity`, `isAgent` to dispatch correctly.
|
|
115
|
+
* Payload of a presence-update event, mirroring the `payload` field of the wire
|
|
116
|
+
* frame. This type is the union of everything the server may send; each
|
|
117
|
+
* consumer reads its own subset. Forwarding the full shape, rather than
|
|
118
|
+
* stripping fields here, is deliberate — presence consumers rely on `kind`,
|
|
119
|
+
* `activity`, and `isAgent` to dispatch correctly.
|
|
147
120
|
*/
|
|
148
121
|
export interface PresenceUpdateEvent {
|
|
149
122
|
/** Server-stamped transition: 'enter' on join + roster snapshot,
|
|
@@ -171,17 +144,16 @@ export interface PresenceUpdateEvent {
|
|
|
171
144
|
* not self-declare — server is the source of truth. */
|
|
172
145
|
isAgent?: boolean;
|
|
173
146
|
/**
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* boolean
|
|
177
|
-
* raw wire input — normalize via `participantKindFromWire`.
|
|
147
|
+
* The canonical participant kind (`'user' | 'agent' | 'system'`), stamped by
|
|
148
|
+
* the server. Some servers omit it, in which case readers fall back to the
|
|
149
|
+
* lossy `isAgent` boolean, which cannot express `'system'`. Typed as `string`
|
|
150
|
+
* because it is raw wire input — normalize it via `participantKindFromWire`.
|
|
178
151
|
*/
|
|
179
152
|
participantKind?: string;
|
|
180
153
|
timestamp?: number;
|
|
181
|
-
/**
|
|
182
|
-
*
|
|
183
|
-
|
|
184
|
-
activeClaims?: Array<{
|
|
154
|
+
/** Every presence frame carries this participant's open claims, stamped by
|
|
155
|
+
* the server, so peers see them without a separate channel. */
|
|
156
|
+
activeClaims?: {
|
|
185
157
|
claimId: string;
|
|
186
158
|
entityType: string;
|
|
187
159
|
entityId: string;
|
|
@@ -198,14 +170,14 @@ export interface PresenceUpdateEvent {
|
|
|
198
170
|
declaredAt: number;
|
|
199
171
|
expiresAt: number;
|
|
200
172
|
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
173
|
+
* The claim's lifecycle state. When absent, the reader treats it as
|
|
174
|
+
* `'active'`. A terminal state (`committed`, `expired`, or `canceled`) rides
|
|
175
|
+
* one final frame as the claim ends, so peers learn how it resolved before
|
|
176
|
+
* it drops from the active set.
|
|
205
177
|
*/
|
|
206
178
|
status?: 'active' | 'committed' | 'expired' | 'canceled';
|
|
207
179
|
error?: ClaimError;
|
|
208
|
-
}
|
|
180
|
+
}[];
|
|
209
181
|
localTime?: string;
|
|
210
182
|
type?: string;
|
|
211
183
|
timezone?: string;
|
|
@@ -276,14 +248,19 @@ export interface CoreSyncEventMap {
|
|
|
276
248
|
claim_granted: [Record<string, unknown>];
|
|
277
249
|
claim_lost: [Record<string, unknown>];
|
|
278
250
|
/**
|
|
279
|
-
*
|
|
280
|
-
* `
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
*
|
|
251
|
+
* Reply to an outbound `claim_heartbeat` — the lease's fate: `held` with
|
|
252
|
+
* the extended `expiresAt`, `queued` with the current `position`, or
|
|
253
|
+
* `lost`. Correlated back to the awaiting caller by `claimId` in the
|
|
254
|
+
* claim stream.
|
|
255
|
+
*/
|
|
256
|
+
claim_heartbeat_ack: [Record<string, unknown>];
|
|
257
|
+
/**
|
|
258
|
+
* A committed write guarded with `onStale: 'notify'` collided with a
|
|
259
|
+
* concurrent change. Rather than forcing an outcome, the engine returns the
|
|
260
|
+
* conflicting field's current value so the actor — an agent reasoning over the
|
|
261
|
+
* change, or a person watching the row — can reconcile it. The commit itself
|
|
262
|
+
* succeeded; the held operations were not written, and the actor re-issues
|
|
263
|
+
* them once it has reconciled.
|
|
287
264
|
*/
|
|
288
265
|
'conflict:notified': [{
|
|
289
266
|
clientTxId: string;
|
|
@@ -302,7 +279,7 @@ export type DefaultCollaborationEvents = Record<string, never>;
|
|
|
302
279
|
* `Record<string, ...>` requires an implicit string index signature, which
|
|
303
280
|
* TypeScript interfaces don't have. So a closed interface like Ablo's
|
|
304
281
|
* `AbloCollaborationEvents` would fail to satisfy `Record<string, unknown[]>`,
|
|
305
|
-
* even though every one of its values
|
|
282
|
+
* even though every one of its values is a tuple. This mapped form iterates
|
|
306
283
|
* over `keyof T` instead of demanding a string index, so it accepts both
|
|
307
284
|
* closed interfaces and open Record types — while still enforcing
|
|
308
285
|
* "every value is an array."
|
|
@@ -335,20 +312,12 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
335
312
|
/** Periodic catchup interval — polls for missed deltas every 30s while connected */
|
|
336
313
|
private catchupInterval;
|
|
337
314
|
/**
|
|
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;
|
|
315
|
+
* Application-level heartbeat: ping every 30 seconds and force-close after a
|
|
316
|
+
* 10-second silence. The {@link HeartbeatController} holds the timing and the
|
|
317
|
+
* zombie-socket rationale; the closures below are the only socket access it
|
|
318
|
+
* gets.
|
|
319
|
+
*/
|
|
320
|
+
private readonly heartbeat;
|
|
352
321
|
private isConnecting;
|
|
353
322
|
private isManualClose;
|
|
354
323
|
/** When true, a session error has been detected (from any path — WS close or HTTP bootstrap).
|
|
@@ -376,11 +345,22 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
376
345
|
private lastCloseReason;
|
|
377
346
|
private lastForceCloseReason;
|
|
378
347
|
private sessionErrorAt;
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
348
|
+
/**
|
|
349
|
+
* Sync-position state: the lastSyncId watermark, version vector, and server
|
|
350
|
+
* cursor. The advance discipline is documented at `sendAck` and `handleDelta`;
|
|
351
|
+
* the state itself lives in {@link SyncCursor}.
|
|
352
|
+
*/
|
|
353
|
+
private readonly cursor;
|
|
382
354
|
/** Registered collaboration event keys (colon format) for dispatch in onmessage */
|
|
383
355
|
private collaborationEventTypes;
|
|
356
|
+
/**
|
|
357
|
+
* A minimal session adapter handed to the inbound frame dispatch table
|
|
358
|
+
* ({@link dispatchWsFrame}). It exposes only the members the handlers touch;
|
|
359
|
+
* the closure members read live state so a reassignment here (for example the
|
|
360
|
+
* `pendingSubscriptions` reset on close) cannot strand a handler on a stale
|
|
361
|
+
* reference. Built in the constructor, after the state it captures exists.
|
|
362
|
+
*/
|
|
363
|
+
private readonly frameSession;
|
|
384
364
|
/**
|
|
385
365
|
* In-flight `commit` mutation requests keyed by clientTxId. Resolved when
|
|
386
366
|
* a matching `mutation_result` frame arrives from the server, or rejected on
|
|
@@ -389,10 +369,10 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
389
369
|
*/
|
|
390
370
|
private pendingMutations;
|
|
391
371
|
/**
|
|
392
|
-
* In-flight `claim` requests keyed by claimId. Resolved when the
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
372
|
+
* In-flight `claim` requests keyed by claimId. Resolved when the matching
|
|
373
|
+
* `claim_ack` arrives, or rejected on timeout or disconnect — the same
|
|
374
|
+
* request/response pattern as `pendingMutations`, multiplexed over the one
|
|
375
|
+
* connection.
|
|
396
376
|
*/
|
|
397
377
|
private pendingClaims;
|
|
398
378
|
/**
|
|
@@ -410,6 +390,14 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
410
390
|
* Suppresses further reconnection attempts and Sentry error capture.
|
|
411
391
|
*/
|
|
412
392
|
setSessionErrorDetected(): void;
|
|
393
|
+
/**
|
|
394
|
+
* Clear the session-error latch so `connect()` / `scheduleReconnect()`
|
|
395
|
+
* work again. Called by the store's access-credential recovery path when
|
|
396
|
+
* the close was a re-mintable `ek_`/`rk_` expiry (`4001 credential_expired`),
|
|
397
|
+
* not a login loss — see `isAccessCredentialExpiryCloseReason`. Genuine
|
|
398
|
+
* session losses never clear the latch; re-auth builds a fresh client.
|
|
399
|
+
*/
|
|
400
|
+
clearSessionError(): void;
|
|
413
401
|
/**
|
|
414
402
|
* Connect to the sync engine WebSocket
|
|
415
403
|
*/
|
|
@@ -419,32 +407,40 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
419
407
|
*/
|
|
420
408
|
private setupEventHandlers;
|
|
421
409
|
/**
|
|
422
|
-
*
|
|
423
|
-
* (`
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
410
|
+
* Validates and normalizes a wire delta at the receive boundary — the single
|
|
411
|
+
* seam every inbound delta (a `delta` frame, a batch element, a `sync_response`
|
|
412
|
+
* replay, or the older bare frame) passes through before it is emitted,
|
|
413
|
+
* persisted, or allowed to advance any watermark.
|
|
414
|
+
*
|
|
415
|
+
* Normalization keeps already-deployed servers compatible:
|
|
416
|
+
* - `id`: the contract says `number`, but some servers have sent the raw
|
|
417
|
+
* Postgres BIGINT serialization — a string — and every downstream watermark
|
|
418
|
+
* gate treats a string as invalid, so acks are withheld, the resume cursor
|
|
419
|
+
* never advances, and every reconnect replays from zero. Coerce it once here.
|
|
420
|
+
* - `transactionId` / `createdBy`: the server projection sends these as
|
|
421
|
+
* nullable (and `createdBy` as a nested reference); the client contract
|
|
422
|
+
* types them as optional strings and never reads them, so normalize them to
|
|
423
|
+
* absent rather than reject every real server delta.
|
|
424
|
+
*
|
|
425
|
+
* Validation runs `clientSyncDeltaSchema.safeParse`, the canonical wire
|
|
426
|
+
* contract. A frame that fails is dropped (returns `null`) with a debug log
|
|
427
|
+
* and an observability breadcrumb; it is never applied. There is one parse per
|
|
428
|
+
* delta — callers must not re-parse.
|
|
432
429
|
*/
|
|
433
430
|
private normalizeWireDelta;
|
|
434
431
|
/**
|
|
435
|
-
* Handle incoming sync delta
|
|
432
|
+
* Handle incoming sync delta (untrusted wire input — validated and
|
|
433
|
+
* normalized by {@link normalizeWireDelta}; malformed deltas are dropped).
|
|
436
434
|
*/
|
|
437
435
|
private handleDelta;
|
|
438
436
|
/**
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
* `
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
* cursor never gets ahead of the persisted view, so reconnect/
|
|
447
|
-
* catch-up requests can't accidentally skip un-persisted deltas.
|
|
437
|
+
* Acknowledges received deltas up to the given syncId. This is the only place
|
|
438
|
+
* `this.cursor.lastSyncId` moves forward for live deltas. The store calls it
|
|
439
|
+
* with its persisted-syncId watermark — that is, only after the deltas have
|
|
440
|
+
* committed to local storage. Advancing the cursor here, rather than at
|
|
441
|
+
* receipt in `handleDelta` or `handleSyncResponse`, keeps the cursor from
|
|
442
|
+
* getting ahead of the persisted view, so reconnect and catch-up requests
|
|
443
|
+
* cannot skip un-persisted deltas.
|
|
448
444
|
*/
|
|
449
445
|
private sendAck;
|
|
450
446
|
/**
|
|
@@ -456,50 +452,17 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
456
452
|
*/
|
|
457
453
|
send(message: any): void;
|
|
458
454
|
/**
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
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
|
-
/**
|
|
469
|
-
* Send a `commit` mutation request over the existing WebSocket and
|
|
470
|
-
* resolve when the server's `mutation_result` frame comes back with
|
|
471
|
-
* the same `clientTxId`. The wire-level frame is `{ type: 'commit',
|
|
472
|
-
* payload: { operations, clientTxId } }` — matching the
|
|
473
|
-
* `handleCommit` path on `apps/sync-server/src/hub/Hub.ts` (see the
|
|
474
|
-
* dispatch at Hub.ts:737).
|
|
455
|
+
* Sends a `commit` mutation request over the existing WebSocket and resolves
|
|
456
|
+
* when the server's `mutation_result` frame comes back with the same
|
|
457
|
+
* `clientTxId`. The wire frame is `{ type: 'commit', payload: { operations,
|
|
458
|
+
* clientTxId } }`.
|
|
475
459
|
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
* confusion stops here.
|
|
481
|
-
*
|
|
482
|
-
* Times out after 15s of silence from the server. The socket may close
|
|
483
|
-
* during an in-flight mutation (network flap, server restart); we do
|
|
484
|
-
* NOT auto-retry here — the caller's TransactionQueue owns retry +
|
|
485
|
-
* offline replay semantics and the SDK shouldn't duplicate that logic.
|
|
486
|
-
*/
|
|
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}.
|
|
460
|
+
* Times out after 15 seconds of silence from the server. The socket may close
|
|
461
|
+
* during an in-flight mutation (a network flap, a server restart); this does
|
|
462
|
+
* not auto-retry — the caller's transaction queue owns retry and offline
|
|
463
|
+
* replay, and the SDK does not duplicate that logic.
|
|
500
464
|
*/
|
|
501
|
-
|
|
502
|
-
sendCommit(operations: ReadonlyArray<MutationOperation>, clientTxId: string, timeoutMs?: number, causedByTaskId?: string | null, reads?: readonly ReadDependency[] | null): Promise<CommitAck>;
|
|
465
|
+
sendCommit(operations: readonly MutationOperation[], clientTxId: string, timeoutMs?: number, causedByTaskId?: string | null, reads?: readonly ReadDependency[] | null): Promise<CommitAck>;
|
|
503
466
|
/**
|
|
504
467
|
* Send a commit frame without waiting for `mutation_result`.
|
|
505
468
|
*
|
|
@@ -508,25 +471,18 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
508
471
|
* eventual `mutation_result` frame is intentionally ignored by this
|
|
509
472
|
* instance because no pending resolver is registered.
|
|
510
473
|
*/
|
|
511
|
-
sendCommitQueued(operations:
|
|
474
|
+
sendCommitQueued(operations: readonly MutationOperation[], clientTxId: string, causedByTaskId?: string | null, reads?: readonly ReadDependency[] | null): void;
|
|
512
475
|
/**
|
|
513
|
-
*
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
* Returns a promise that resolves with the server-canonicalized
|
|
519
|
-
* `syncGroups` and effective `ttlSeconds` once `claim_ack` arrives,
|
|
520
|
-
* or rejects with a typed error on `success: false` ack /
|
|
521
|
-
* timeout / disconnect.
|
|
476
|
+
* Activates a participant claim on this connection. One connection can hold
|
|
477
|
+
* several concurrent claims at once, each scoped to a different set of sync
|
|
478
|
+
* groups, so the SDK reuses the existing connection instead of opening a
|
|
479
|
+
* separate socket per scope.
|
|
522
480
|
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
* `apps/sync-server/docs/PARTICIPANT_CLAIMS.md` for the migration
|
|
527
|
-
* framing (Phase A.1).
|
|
481
|
+
* Returns a promise that resolves with the server-canonicalized `syncGroups`
|
|
482
|
+
* and effective `ttlSeconds` once `claim_ack` arrives, or rejects with a typed
|
|
483
|
+
* error on a failed ack, a timeout, or a disconnect.
|
|
528
484
|
*/
|
|
529
|
-
sendClaim(claimId: string, syncGroups:
|
|
485
|
+
sendClaim(claimId: string, syncGroups: readonly string[], options?: {
|
|
530
486
|
capabilityToken?: string;
|
|
531
487
|
ttlSeconds?: number;
|
|
532
488
|
timeoutMs?: number;
|
|
@@ -545,32 +501,31 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
545
501
|
*/
|
|
546
502
|
sendRelease(claimId: string): void;
|
|
547
503
|
/**
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
* area-of-interest
|
|
551
|
-
*
|
|
552
|
-
* chosen at connect.
|
|
504
|
+
* Moves this connection's read interest — replaces the connection-level sync
|
|
505
|
+
* groups mid-session as the user opens and closes entities. This is the
|
|
506
|
+
* area-of-interest navigation primitive: the server fans out deltas only for
|
|
507
|
+
* the groups currently in view, rather than the fixed set chosen at connect.
|
|
553
508
|
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
* requesting a group outside its allowlist), timeout, or disconnect. On
|
|
558
|
-
* success the new set is recorded as `options.syncGroups
|
|
559
|
-
*
|
|
509
|
+
* This is a full-set replace: pass the complete new group list, not a delta.
|
|
510
|
+
* Resolves with the server's effective set once `subscription_ack` arrives;
|
|
511
|
+
* rejects (with a typed error) on a scope denial (a restricted `rk_` key
|
|
512
|
+
* requesting a group outside its allowlist), a timeout, or a disconnect. On
|
|
513
|
+
* success the new set is recorded as `options.syncGroups`, so a later reconnect
|
|
514
|
+
* re-subscribes to the current interest rather than the connect-time set.
|
|
560
515
|
*
|
|
561
|
-
* Distinct from {@link sendClaim} (write
|
|
562
|
-
* the read side
|
|
563
|
-
* by the connection credential's grant.
|
|
516
|
+
* Distinct from {@link sendClaim} (a write claim, per operation, with a TTL):
|
|
517
|
+
* this is the read side, carries no capability token of its own, and is
|
|
518
|
+
* bounded by the connection credential's grant.
|
|
564
519
|
*/
|
|
565
|
-
updateSubscription(syncGroups:
|
|
520
|
+
updateSubscription(syncGroups: readonly string[], options?: {
|
|
566
521
|
timeoutMs?: number;
|
|
567
522
|
}): Promise<{
|
|
568
523
|
syncGroups: string[];
|
|
569
524
|
}>;
|
|
570
525
|
/**
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
526
|
+
* Sets a fixed credential for callers that construct the socket directly. The
|
|
527
|
+
* SDK instead supplies `getAuthToken`, so reconnects read the shared
|
|
528
|
+
* credential source rather than this copied value.
|
|
574
529
|
*/
|
|
575
530
|
setCapabilityToken(token: string): void;
|
|
576
531
|
getAuthToken(): string | undefined;
|
|
@@ -584,15 +539,15 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
584
539
|
/**
|
|
585
540
|
* Send spreadsheet selection presence
|
|
586
541
|
*/
|
|
587
|
-
sendSheetSelection(sheetId: string, selectedCells:
|
|
542
|
+
sendSheetSelection(sheetId: string, selectedCells: {
|
|
588
543
|
ref: string;
|
|
589
|
-
}
|
|
544
|
+
}[]): void;
|
|
590
545
|
/**
|
|
591
546
|
* Send slide layer selection presence
|
|
592
547
|
*/
|
|
593
|
-
sendSlideSelection(deckId: string, slideId: string, selectedLayers:
|
|
548
|
+
sendSlideSelection(deckId: string, slideId: string, selectedLayers: {
|
|
594
549
|
layerId: string;
|
|
595
|
-
}
|
|
550
|
+
}[]): void;
|
|
596
551
|
/**
|
|
597
552
|
* Send slide cursor position for real-time collaboration
|
|
598
553
|
* Note: Throttling should be handled by the caller (e.g., useSlideCursorBroadcast hook)
|
|
@@ -628,26 +583,6 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
628
583
|
* Disconnect from WebSocket
|
|
629
584
|
*/
|
|
630
585
|
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
586
|
/**
|
|
652
587
|
* Force-close the socket from the client side using a private 4xxx
|
|
653
588
|
* code. Callers expect `onclose` to fire; that handler runs the
|
|
@@ -697,18 +632,6 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
697
632
|
* Update last sync ID (for persistence)
|
|
698
633
|
*/
|
|
699
634
|
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
635
|
/**
|
|
713
636
|
* Update sync cursor (for incremental sync)
|
|
714
637
|
*/
|
|
@@ -722,7 +645,7 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
722
645
|
*/
|
|
723
646
|
getLastSyncId(): number;
|
|
724
647
|
/**
|
|
725
|
-
*
|
|
648
|
+
* Requests an incremental sync from the server, starting at the current cursor.
|
|
726
649
|
*/
|
|
727
650
|
requestIncrementalSync(): Promise<void>;
|
|
728
651
|
/**
|
|
@@ -730,7 +653,10 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
730
653
|
*/
|
|
731
654
|
requestBootstrap(entities?: string[]): Promise<void>;
|
|
732
655
|
/**
|
|
733
|
-
* Handle sync response from server
|
|
656
|
+
* Handle sync response from server. Untrusted wire input — the envelope
|
|
657
|
+
* fields are narrowed defensively and every delta is validated through
|
|
658
|
+
* {@link normalizeWireDelta} (exactly once each; malformed ones drop out
|
|
659
|
+
* of the batch).
|
|
734
660
|
*/
|
|
735
661
|
private handleSyncResponse;
|
|
736
662
|
/**
|
|
@@ -738,13 +664,12 @@ export declare class SyncWebSocket<TCollaboration extends EventMap<TCollaboratio
|
|
|
738
664
|
*/
|
|
739
665
|
private handleBootstrapResponse;
|
|
740
666
|
/**
|
|
741
|
-
*
|
|
742
|
-
* forwarded as-is so every consumer
|
|
743
|
-
*
|
|
744
|
-
*
|
|
745
|
-
* `kind`, `activity`, `syncGroups`, `isAgent` for rich consumers.
|
|
667
|
+
* Handles a presence update from the server. The wire frame's payload is
|
|
668
|
+
* forwarded as-is, so every consumer reads the same shape; stripping fields
|
|
669
|
+
* here would drop `kind`, `activity`, `syncGroups`, and `isAgent` for
|
|
670
|
+
* consumers that need them.
|
|
746
671
|
*
|
|
747
|
-
*
|
|
672
|
+
* The wire frame is:
|
|
748
673
|
* { type: 'presence_update', payload: { kind, userId, status,
|
|
749
674
|
* syncGroups, activity, isAgent, timestamp, activeClaims } }
|
|
750
675
|
*/
|