@abloatai/ablo 0.34.1 → 0.36.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 +2 -1
- package/CHANGELOG.md +758 -5
- package/README.md +56 -502
- package/bin/ablo.cjs +39 -0
- package/dist/BaseSyncedStore.d.ts +176 -48
- package/dist/BaseSyncedStore.js +346 -214
- package/dist/Database.d.ts +17 -44
- package/dist/Database.js +96 -79
- package/dist/InstanceCache.d.ts +31 -6
- package/dist/InstanceCache.js +65 -30
- package/dist/LazyReferenceCollection.d.ts +3 -3
- package/dist/LazyReferenceCollection.js +4 -4
- package/dist/Model.d.ts +23 -13
- package/dist/Model.js +27 -17
- package/dist/ModelRegistry.d.ts +8 -4
- package/dist/ModelRegistry.js +20 -18
- package/dist/NetworkMonitor.d.ts +3 -1
- package/dist/NetworkMonitor.js +7 -5
- package/dist/{SyncEngineContext.d.ts → RuntimeContext.d.ts} +20 -13
- package/dist/{SyncEngineContext.js → RuntimeContext.js} +11 -12
- package/dist/SyncClient.d.ts +47 -47
- package/dist/SyncClient.js +215 -156
- package/dist/ai-sdk/coordinatedTool.d.ts +2 -2
- package/dist/ai-sdk/coordinatedTool.js +1 -1
- package/dist/ai-sdk/coordinationContext.d.ts +2 -2
- package/dist/ai-sdk/coordinationContext.js +1 -1
- package/dist/ai-sdk/wrap.d.ts +3 -3
- package/dist/ai-sdk/wrap.js +2 -2
- package/dist/auth/index.d.ts +1 -156
- package/dist/auth/index.js +8 -301
- package/dist/client/Ablo.d.ts +42 -287
- package/dist/client/Ablo.js +129 -963
- package/dist/client/abloClient.d.ts +309 -0
- package/dist/client/abloClient.js +13 -0
- package/dist/client/clientPrelude.d.ts +52 -0
- package/dist/client/clientPrelude.js +60 -0
- package/dist/client/consoleLogger.d.ts +2 -2
- package/dist/client/coreClient.d.ts +60 -0
- package/dist/client/coreClient.js +118 -0
- package/dist/client/createInternalComponents.d.ts +8 -4
- package/dist/client/createInternalComponents.js +17 -10
- package/dist/client/createModelProxy.d.ts +98 -373
- package/dist/client/createModelProxy.js +233 -139
- package/dist/client/humans.d.ts +69 -0
- package/dist/client/humans.js +78 -0
- package/dist/client/modelRegistration.d.ts +1 -1
- package/dist/client/modelRegistration.js +9 -9
- package/dist/client/options.d.ts +73 -17
- package/dist/client/reactiveEngine.d.ts +53 -0
- package/dist/client/reactiveEngine.js +688 -0
- package/dist/client/resourceTypes.d.ts +9 -250
- package/dist/client/resourceTypes.js +8 -5
- package/dist/client/schemaConfig.d.ts +4 -4
- package/dist/client/schemaConfig.js +6 -2
- package/dist/client/storeCluster.d.ts +47 -0
- package/dist/client/storeCluster.js +118 -0
- package/dist/client/storeLifecycle.d.ts +61 -0
- package/dist/client/storeLifecycle.js +231 -0
- package/dist/client/validateAbloOptions.d.ts +3 -2
- package/dist/client/validateAbloOptions.js +1 -1
- package/dist/client/wsMutationExecutor.d.ts +3 -3
- package/dist/client/wsMutationExecutor.js +3 -3
- package/dist/context.d.ts +22 -9
- package/dist/context.js +33 -9
- package/dist/coordination/ClaimLog.d.ts +26 -0
- package/dist/coordination/ClaimLog.js +32 -0
- package/dist/coordination/index.d.ts +1 -15
- package/dist/coordination/index.js +8 -31
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +2 -2
- package/dist/docs/catalog.d.ts +72 -0
- package/dist/docs/catalog.js +230 -0
- package/dist/docs/index.d.ts +10 -0
- package/dist/docs/index.js +10 -0
- package/dist/environment.d.ts +1 -40
- package/dist/environment.js +8 -37
- package/dist/index.d.ts +44 -36
- package/dist/index.js +30 -22
- package/dist/interfaces/index.d.ts +44 -134
- package/dist/keys/index.d.ts +1 -77
- package/dist/keys/index.js +8 -190
- package/dist/mutators/{RecordingTransaction.d.ts → RecordingMutation.d.ts} +4 -4
- package/dist/mutators/{RecordingTransaction.js → RecordingMutation.js} +2 -2
- package/dist/mutators/Transaction.d.ts +1 -1
- package/dist/mutators/Transaction.js +1 -1
- package/dist/mutators/UndoManager.d.ts +6 -6
- package/dist/mutators/UndoManager.js +5 -5
- package/dist/mutators/defineMutators.d.ts +3 -3
- package/dist/mutators/defineMutators.js +1 -1
- package/dist/mutators/inverseOp.js +2 -2
- package/dist/mutators/mutateActions.d.ts +3 -3
- package/dist/mutators/mutateActions.js +1 -1
- package/dist/mutators/readerActions.d.ts +1 -1
- package/dist/mutators/undoApply.d.ts +1 -1
- package/dist/mutators/undoApply.js +1 -1
- package/dist/policy/index.d.ts +2 -2
- package/dist/policy/index.js +1 -1
- package/dist/query/client.d.ts +5 -2
- package/dist/query/client.js +10 -9
- package/dist/query/types.d.ts +6 -41
- package/dist/query/types.js +2 -2
- package/dist/react/AbloProvider.d.ts +18 -8
- package/dist/react/AbloProvider.js +10 -9
- package/dist/react/context.d.ts +3 -3
- package/dist/react/context.js +1 -1
- package/dist/react/createAbloReact.d.ts +56 -0
- package/dist/react/createAbloReact.js +51 -0
- package/dist/react/index.d.ts +6 -5
- package/dist/react/index.js +6 -3
- package/dist/react/internalContext.d.ts +1 -1
- package/dist/react/useAblo.d.ts +12 -5
- package/dist/react/useAblo.js +26 -8
- package/dist/react/useCurrentUserId.js +1 -1
- package/dist/react/useErrorListener.js +1 -1
- package/dist/react/useMutationFailureListener.d.ts +2 -2
- package/dist/react/useMutationFailureListener.js +1 -1
- package/dist/react/useMutators.d.ts +3 -3
- package/dist/react/useMutators.js +3 -3
- package/dist/react/useUndoScope.d.ts +5 -5
- package/dist/react/useUndoScope.js +1 -1
- package/dist/schema/coordination.d.ts +69 -10
- package/dist/schema/coordination.js +90 -9
- package/dist/schema/ddl.js +2 -2
- package/dist/schema/diff.d.ts +1 -1
- package/dist/schema/generate.js +1 -1
- package/dist/schema/index.d.ts +11 -10
- package/dist/schema/index.js +22 -18
- package/dist/schema/queries.d.ts +27 -27
- package/dist/schema/queries.js +23 -23
- package/dist/schema/select.d.ts +3 -3
- package/dist/schema/select.js +6 -3
- package/dist/schema/serialize.d.ts +15 -6
- package/dist/schema/serialize.js +20 -3
- package/dist/schema/sugar.d.ts +6 -7
- package/dist/schema/sugar.js +9 -12
- package/dist/schema/syncDeltaRow.d.ts +4 -152
- package/dist/schema/syncDeltaRow.js +4 -105
- package/dist/server/adapter.d.ts +18 -1
- package/dist/server/commit.d.ts +10 -16
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/readConfig.d.ts +1 -1
- package/dist/source/adapter.d.ts +7 -5
- package/dist/source/adapter.js +7 -5
- package/dist/source/adapters/drizzle.d.ts +1 -1
- package/dist/source/adapters/drizzle.js +2 -2
- package/dist/source/adapters/kysely.d.ts +1 -1
- package/dist/source/adapters/kysely.js +1 -1
- package/dist/source/adapters/kyselyMutationCore.d.ts +1 -1
- package/dist/source/adapters/kyselyMutationCore.js +2 -2
- package/dist/source/adapters/memory.js +1 -1
- package/dist/source/adapters/prisma.d.ts +8 -3
- package/dist/source/adapters/prisma.js +1 -1
- package/dist/source/connector.js +1 -1
- package/dist/source/connectorProtocol.d.ts +2 -8
- package/dist/source/connectorProtocol.js +3 -2
- package/dist/source/contract.d.ts +29 -17
- package/dist/source/contract.js +27 -22
- package/dist/source/factory.d.ts +1 -1
- package/dist/source/idempotency.js +2 -2
- package/dist/source/index.d.ts +1 -0
- package/dist/source/index.js +3 -0
- package/dist/source/next.d.ts +1 -1
- package/dist/source/signing.d.ts +9 -2
- package/dist/source/signing.js +4 -1
- package/dist/source/types.d.ts +6 -4
- package/dist/source/types.js +1 -1
- package/dist/{core/storeContract.d.ts → storeContract.d.ts} +6 -6
- package/dist/{core → stores}/DatabaseManager.d.ts +3 -1
- package/dist/{core → stores}/DatabaseManager.js +14 -13
- package/dist/stores/ObjectStore.d.ts +1 -1
- package/dist/{core → stores}/StoreManager.d.ts +9 -26
- package/dist/{core → stores}/StoreManager.js +29 -77
- package/dist/stores/SyncActionStore.d.ts +4 -2
- package/dist/stores/SyncActionStore.js +11 -17
- package/dist/stores/syncAction.d.ts +26 -0
- package/dist/stores/syncAction.js +16 -0
- package/dist/surface.d.ts +3 -3
- package/dist/surface.js +6 -4
- package/dist/sync/BootstrapFetcher.d.ts +127 -6
- package/dist/sync/BootstrapFetcher.js +511 -83
- package/dist/sync/ConnectionManager.d.ts +6 -198
- package/dist/sync/ConnectionManager.js +6 -677
- package/dist/sync/OnDemandLoader.d.ts +5 -2
- package/dist/sync/OnDemandLoader.js +61 -21
- package/dist/sync/SubscriptionManager.d.ts +13 -2
- package/dist/sync/SubscriptionManager.js +23 -5
- package/dist/sync/SyncWebSocket.d.ts +27 -510
- package/dist/sync/SyncWebSocket.js +76 -954
- package/dist/sync/awaitClaimGrant.d.ts +4 -44
- package/dist/sync/awaitClaimGrant.js +4 -109
- package/dist/sync/bootstrapApply.d.ts +3 -0
- package/dist/sync/bootstrapApply.js +2 -2
- package/dist/sync/commitFrames.d.ts +6 -40
- package/dist/sync/commitFrames.js +6 -97
- package/dist/sync/contextPorts.d.ts +18 -0
- package/dist/sync/contextPorts.js +31 -0
- package/dist/sync/createClaimStream.d.ts +5 -49
- package/dist/sync/createClaimStream.js +5 -469
- package/dist/sync/createPresenceStream.d.ts +26 -4
- package/dist/sync/createPresenceStream.js +28 -20
- package/dist/sync/createSnapshot.d.ts +2 -2
- package/dist/sync/createSnapshot.js +1 -1
- package/dist/sync/credentialLifecycle.d.ts +5 -173
- package/dist/sync/credentialLifecycle.js +5 -320
- package/dist/sync/deltaPipeline.d.ts +13 -12
- package/dist/sync/deltaPipeline.js +21 -4
- package/dist/sync/groupChange.d.ts +3 -0
- package/dist/sync/groupChange.js +16 -14
- package/dist/sync/participants.d.ts +24 -6
- package/dist/sync/participants.js +32 -23
- package/dist/sync/schemaDrift.d.ts +55 -0
- package/dist/sync/schemaDrift.js +53 -0
- package/dist/sync/schemas.d.ts +23 -33
- package/dist/sync/schemas.js +29 -20
- package/dist/sync/syncPlan.d.ts +3 -3
- package/dist/sync/wsFrameHandlers.d.ts +6 -114
- package/dist/sync/wsFrameHandlers.js +6 -392
- package/dist/syncLog/contract.d.ts +20 -0
- package/dist/syncLog/contract.js +19 -0
- package/dist/syncLog/index.d.ts +1 -0
- package/dist/syncLog/index.js +1 -0
- package/dist/transaction/ablo.d.ts +88 -0
- package/dist/transaction/ablo.js +33 -0
- package/dist/{client/auth.d.ts → transaction/auth/apiKey.d.ts} +43 -8
- package/dist/{client/auth.js → transaction/auth/apiKey.js} +19 -0
- package/dist/transaction/auth/bootstrapScope.d.ts +15 -0
- package/dist/transaction/auth/bootstrapScope.js +1 -0
- package/dist/transaction/auth/capability.d.ts +212 -0
- package/dist/transaction/auth/capability.js +224 -0
- package/dist/{auth → transaction/auth}/credentialSource.d.ts +8 -1
- package/dist/{client → transaction/auth}/identity.d.ts +8 -7
- package/dist/{client → transaction/auth}/identity.js +1 -1
- package/dist/transaction/auth/index.d.ts +162 -0
- package/dist/transaction/auth/index.js +304 -0
- package/dist/{auth → transaction/auth}/schemas.d.ts +1 -1
- package/dist/{auth → transaction/auth}/schemas.js +13 -13
- package/dist/{client → transaction/auth}/sessionMint.d.ts +8 -8
- package/dist/{client → transaction/auth}/sessionMint.js +4 -7
- package/dist/transaction/coordination/awaitClaimGrant.d.ts +56 -0
- package/dist/transaction/coordination/awaitClaimGrant.js +124 -0
- package/dist/{client → transaction/coordination}/claimHeartbeatLoop.d.ts +34 -0
- package/dist/{client → transaction/coordination}/claimHeartbeatLoop.js +20 -0
- package/dist/transaction/coordination/claimMeta.d.ts +49 -0
- package/dist/transaction/coordination/claimMeta.js +52 -0
- package/dist/transaction/coordination/createClaimStream.d.ts +64 -0
- package/dist/transaction/coordination/createClaimStream.js +475 -0
- package/dist/transaction/coordination/events.d.ts +74 -0
- package/dist/transaction/coordination/events.js +7 -0
- package/dist/transaction/coordination/index.d.ts +19 -0
- package/dist/transaction/coordination/index.js +45 -0
- package/dist/transaction/coordination/locator.d.ts +104 -0
- package/dist/transaction/coordination/locator.js +102 -0
- package/dist/transaction/coordination/schema.d.ts +1536 -0
- package/dist/transaction/coordination/schema.js +1177 -0
- package/dist/transaction/coordination/targetConflict.d.ts +2 -0
- package/dist/transaction/coordination/targetConflict.js +107 -0
- package/dist/{coordination → transaction/coordination}/trace.d.ts +7 -18
- package/dist/{coordination → transaction/coordination}/trace.js +18 -25
- package/dist/transaction/durableWrites.d.ts +62 -0
- package/dist/{client → transaction}/durableWrites.js +28 -3
- package/dist/transaction/environment.d.ts +105 -0
- package/dist/transaction/environment.js +108 -0
- package/dist/{errorCodes.d.ts → transaction/errorCodes.d.ts} +12 -12
- package/dist/{errorCodes.js → transaction/errorCodes.js} +45 -18
- package/dist/{errors.d.ts → transaction/errors.d.ts} +37 -13
- package/dist/{errors.js → transaction/errors.js} +85 -16
- package/dist/transaction/footprint.d.ts +111 -0
- package/dist/transaction/footprint.js +0 -0
- package/dist/transaction/index.d.ts +20 -0
- package/dist/transaction/index.js +20 -0
- package/dist/transaction/keys/index.d.ts +87 -0
- package/dist/transaction/keys/index.js +207 -0
- package/dist/transaction/log/syncDeltaRow.d.ts +158 -0
- package/dist/transaction/log/syncDeltaRow.js +95 -0
- package/dist/{sync/syncPosition.d.ts → transaction/logPosition.d.ts} +22 -8
- package/dist/{sync/syncPosition.js → transaction/logPosition.js} +15 -6
- package/dist/transaction/logger.d.ts +16 -0
- package/dist/transaction/logger.js +7 -0
- package/dist/transaction/observability.d.ts +53 -0
- package/dist/transaction/observability.js +19 -0
- package/dist/transaction/plugin.d.ts +285 -0
- package/dist/transaction/plugin.js +106 -0
- package/dist/{policy → transaction/policy}/types.d.ts +3 -3
- package/dist/{policy → transaction/policy}/types.js +2 -0
- package/dist/transaction/resources/httpResources.d.ts +321 -0
- package/dist/transaction/resources/httpResources.js +7 -0
- package/dist/transaction/resources/modelOperations.d.ts +427 -0
- package/dist/transaction/resources/modelOperations.js +12 -0
- package/dist/transaction/resources/mutationOptions.d.ts +66 -0
- package/dist/transaction/resources/mutationOptions.js +9 -0
- package/dist/transaction/resources/where.d.ts +101 -0
- package/dist/transaction/resources/where.js +115 -0
- package/dist/{client → transaction/resources}/writeOptionsSchema.d.ts +2 -6
- package/dist/{client → transaction/resources}/writeOptionsSchema.js +9 -5
- package/dist/{schema → transaction/schema}/field.d.ts +17 -23
- package/dist/{schema → transaction/schema}/field.js +5 -5
- package/dist/transaction/schema/fieldRef.d.ts +38 -0
- package/dist/transaction/schema/fieldRef.js +11 -0
- package/dist/transaction/schema/loadStrategy.d.ts +45 -0
- package/dist/transaction/schema/loadStrategy.js +46 -0
- package/dist/{schema → transaction/schema}/model.d.ts +50 -35
- package/dist/{schema → transaction/schema}/model.js +30 -20
- package/dist/transaction/schema/openapi.d.ts +58 -0
- package/dist/transaction/schema/openapi.js +501 -0
- package/dist/{schema → transaction/schema}/relation.d.ts +21 -16
- package/dist/{schema → transaction/schema}/relation.js +7 -7
- package/dist/{schema → transaction/schema}/residency.d.ts +0 -9
- package/dist/{schema → transaction/schema}/residency.js +0 -5
- package/dist/{schema → transaction/schema}/roles.d.ts +5 -5
- package/dist/{schema → transaction/schema}/roles.js +5 -5
- package/dist/{schema → transaction/schema}/schema.d.ts +39 -10
- package/dist/{schema → transaction/schema}/schema.js +24 -3
- package/dist/{schema → transaction/schema}/tenancy.d.ts +1 -1
- package/dist/{schema → transaction/schema}/tenancy.js +7 -4
- package/dist/transaction/transactionLayer.d.ts +82 -0
- package/dist/transaction/transactionLayer.js +24 -0
- package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.d.ts +5 -6
- package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.js +9 -13
- package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.d.ts +9 -2
- package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.js +5 -9
- package/dist/{transactions/durableWriteStore.d.ts → transaction/transactions/settlement/pendingWrite.d.ts} +11 -37
- package/dist/transaction/transactions/settlement/pendingWrite.js +20 -0
- package/dist/transaction/transport/commitFrames.d.ts +90 -0
- package/dist/transaction/transport/commitFrames.js +134 -0
- package/dist/transaction/transport/connectionManager.d.ts +215 -0
- package/dist/transaction/transport/connectionManager.js +673 -0
- package/dist/transaction/transport/credentialLifecycle.d.ts +177 -0
- package/dist/transaction/transport/credentialLifecycle.js +324 -0
- package/dist/{sync → transaction/transport}/heartbeat.d.ts +3 -1
- package/dist/{sync → transaction/transport}/heartbeat.js +6 -4
- package/dist/transaction/transport/httpClient.d.ts +131 -0
- package/dist/{client → transaction/transport}/httpClient.js +6 -5
- package/dist/transaction/transport/httpOptions.d.ts +33 -0
- package/dist/transaction/transport/httpOptions.js +12 -0
- package/dist/{client → transaction/transport}/httpTransport.js +295 -97
- package/dist/{sync/NetworkProbe.d.ts → transaction/transport/networkProbe.d.ts} +7 -4
- package/dist/{sync/NetworkProbe.js → transaction/transport/networkProbe.js} +14 -13
- package/dist/transaction/transport/wsFrameHandlers.d.ts +128 -0
- package/dist/transaction/transport/wsFrameHandlers.js +429 -0
- package/dist/transaction/transport/wsTransport.d.ts +574 -0
- package/dist/transaction/transport/wsTransport.js +1023 -0
- package/dist/transaction/types/assertExact.d.ts +17 -0
- package/dist/transaction/types/assertExact.js +1 -0
- package/dist/{types → transaction/types}/global.d.ts +17 -2
- package/dist/{types → transaction/types}/global.js +2 -1
- package/dist/{types → transaction/types}/index.d.ts +14 -46
- package/dist/{types → transaction/types}/index.js +7 -16
- package/dist/{types → transaction/types}/streams.d.ts +73 -45
- package/dist/transaction/utils/duration.d.ts +50 -0
- package/dist/{utils → transaction/utils}/duration.js +32 -0
- package/dist/{utils → transaction/utils}/json.d.ts +18 -0
- package/dist/transaction/utils/json.js +276 -0
- package/dist/transaction/wire/accountResponses.d.ts +420 -0
- package/dist/transaction/wire/accountResponses.js +290 -0
- package/dist/transaction/wire/auth.d.ts +56 -0
- package/dist/transaction/wire/auth.js +63 -0
- package/dist/transaction/wire/claimEvent.d.ts +76 -0
- package/dist/transaction/wire/claimEvent.js +73 -0
- package/dist/transaction/wire/claims.d.ts +530 -0
- package/dist/transaction/wire/claims.js +327 -0
- package/dist/{wire → transaction/wire}/commit.d.ts +125 -193
- package/dist/{wire → transaction/wire}/commit.js +68 -47
- package/dist/{wire → transaction/wire}/delta.d.ts +66 -17
- package/dist/{wire → transaction/wire}/delta.js +37 -13
- package/dist/transaction/wire/errorEnvelope.d.ts +72 -0
- package/dist/{wire → transaction/wire}/errorEnvelope.js +36 -5
- package/dist/transaction/wire/feedCursor.d.ts +60 -0
- package/dist/transaction/wire/feedCursor.js +82 -0
- package/dist/transaction/wire/feedEvent.d.ts +204 -0
- package/dist/transaction/wire/feedEvent.js +65 -0
- package/dist/transaction/wire/frames.d.ts +194 -0
- package/dist/transaction/wire/frames.js +50 -0
- package/dist/transaction/wire/inboundFrames.d.ts +562 -0
- package/dist/transaction/wire/inboundFrames.js +116 -0
- package/dist/transaction/wire/index.d.ts +54 -0
- package/dist/transaction/wire/index.js +83 -0
- package/dist/{wire → transaction/wire}/listEnvelope.d.ts +13 -14
- package/dist/transaction/wire/listEnvelope.js +42 -0
- package/dist/transaction/wire/modelMutations.d.ts +31 -0
- package/dist/transaction/wire/modelMutations.js +52 -0
- package/dist/transaction/wire/modelResponses.d.ts +85 -0
- package/dist/transaction/wire/modelResponses.js +43 -0
- package/dist/transaction/wire/modelShape.d.ts +78 -0
- package/dist/transaction/wire/modelShape.js +74 -0
- package/dist/transactions/{TransactionQueue.d.ts → mutations/MutationQueue.d.ts} +85 -38
- package/dist/transactions/{TransactionQueue.js → mutations/MutationQueue.js} +141 -80
- package/dist/transactions/{TransactionStore.d.ts → mutations/MutationStore.d.ts} +8 -8
- package/dist/transactions/{TransactionStore.js → mutations/MutationStore.js} +2 -2
- package/dist/transactions/{coalesceRules.d.ts → mutations/coalesceRules.d.ts} +10 -10
- package/dist/transactions/{coalesceRules.js → mutations/coalesceRules.js} +1 -1
- package/dist/transactions/mutations/commitLatency.d.ts +52 -0
- package/dist/transactions/mutations/commitLatency.js +130 -0
- package/dist/transactions/{commitOutboxStore.d.ts → mutations/commitOutboxStore.d.ts} +1 -5
- package/dist/transactions/{commitOutboxStore.js → mutations/commitOutboxStore.js} +1 -1
- package/dist/transactions/{commitPayload.d.ts → mutations/commitPayload.d.ts} +18 -16
- package/dist/transactions/{commitPayload.js → mutations/commitPayload.js} +15 -15
- package/dist/transactions/{deltaConfirmation.d.ts → mutations/deltaConfirmation.d.ts} +15 -11
- package/dist/transactions/{deltaConfirmation.js → mutations/deltaConfirmation.js} +14 -12
- package/dist/transactions/mutations/durableWriteStore.d.ts +14 -0
- package/dist/transactions/mutations/durableWriteStore.js +12 -0
- package/dist/transactions/{optimisticApply.d.ts → mutations/optimisticApply.d.ts} +7 -7
- package/dist/transactions/{replayValidation.d.ts → mutations/replayValidation.d.ts} +4 -3
- package/dist/transactions/{replayValidation.js → mutations/replayValidation.js} +7 -5
- package/dist/utils/mobxSetup.d.ts +1 -1
- package/dist/utils/mobxSetup.js +5 -2
- package/dist/{core → views}/QueryView.d.ts +2 -2
- package/dist/{core → views}/QueryView.js +2 -2
- package/dist/{core → views}/ViewRegistry.d.ts +1 -1
- package/dist/{core/queryUtils.d.ts → views/incrementalView.d.ts} +6 -6
- package/dist/{core/queryUtils.js → views/incrementalView.js} +6 -6
- package/dist/webhooks/events.d.ts +2 -2
- package/dist/wire/index.d.ts +1 -34
- package/dist/wire/index.js +8 -49
- package/docs/agent-messaging.md +3 -3
- package/docs/agents.md +20 -13
- package/docs/api-keys.md +14 -10
- package/docs/api.md +27 -61
- package/docs/audit.md +6 -3
- package/docs/cli.md +41 -13
- package/docs/client-behavior.md +11 -9
- package/docs/concurrency-convention.md +49 -57
- package/docs/coordination.md +283 -121
- package/docs/data-sources.md +7 -5
- package/docs/debugging.md +39 -15
- package/docs/deployment.md +267 -0
- package/docs/examples/agent-human.md +49 -42
- package/docs/examples/ai-sdk-tool.md +69 -44
- package/docs/examples/existing-python-backend.md +8 -6
- package/docs/examples/nextjs.md +129 -47
- package/docs/examples/scoped-agent.md +46 -45
- package/docs/examples/server-agent.md +46 -26
- package/docs/groups.md +87 -30
- package/docs/guarantees.md +41 -12
- package/docs/how-it-works.md +38 -12
- package/docs/idempotency.md +126 -0
- package/docs/identity.md +77 -74
- package/docs/index.md +172 -86
- package/docs/integration-guide.md +31 -19
- package/docs/mcp.md +46 -21
- package/docs/migration.md +95 -18
- package/docs/operating-on-your-database.md +3 -1
- package/docs/projects.md +3 -1
- package/docs/quickstart.md +22 -5
- package/docs/react.md +31 -18
- package/docs/schema-contract.md +5 -3
- package/docs/session-settings.md +108 -0
- package/docs/sessions.md +4 -2
- package/docs/webhooks.md +12 -10
- package/llms.txt +48 -18
- package/package.json +21 -26
- package/dist/agent/Agent.d.ts +0 -366
- package/dist/agent/Agent.js +0 -514
- package/dist/agent/index.d.ts +0 -115
- package/dist/agent/index.js +0 -128
- package/dist/agent/session.d.ts +0 -93
- package/dist/agent/session.js +0 -149
- package/dist/agent/types.d.ts +0 -68
- package/dist/agent/types.js +0 -9
- package/dist/cli.cjs +0 -286329
- package/dist/client/durableWrites.d.ts +0 -21
- package/dist/client/httpClient.d.ts +0 -80
- package/dist/coordination/schema.d.ts +0 -722
- package/dist/coordination/schema.js +0 -578
- package/dist/schema/openapi.d.ts +0 -29
- package/dist/schema/openapi.js +0 -124
- package/dist/testing/fixtures/bootstrap.d.ts +0 -49
- package/dist/testing/fixtures/bootstrap.js +0 -59
- package/dist/testing/fixtures/deltas.d.ts +0 -83
- package/dist/testing/fixtures/deltas.js +0 -136
- package/dist/testing/fixtures/models.d.ts +0 -83
- package/dist/testing/fixtures/models.js +0 -272
- package/dist/testing/helpers/reactWrapper.d.ts +0 -69
- package/dist/testing/helpers/reactWrapper.js +0 -67
- package/dist/testing/helpers/syncEngineHarness.d.ts +0 -54
- package/dist/testing/helpers/syncEngineHarness.js +0 -73
- package/dist/testing/helpers/wait.d.ts +0 -30
- package/dist/testing/helpers/wait.js +0 -49
- package/dist/testing/index.d.ts +0 -23
- package/dist/testing/index.js +0 -33
- package/dist/testing/mocks/FakeDatabase.d.ts +0 -18
- package/dist/testing/mocks/FakeDatabase.js +0 -10
- package/dist/testing/mocks/MockMutationExecutor.d.ts +0 -87
- package/dist/testing/mocks/MockMutationExecutor.js +0 -192
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +0 -20
- package/dist/testing/mocks/MockNetworkMonitor.js +0 -46
- package/dist/testing/mocks/MockSyncContext.d.ts +0 -51
- package/dist/testing/mocks/MockSyncContext.js +0 -71
- package/dist/testing/mocks/MockSyncStore.d.ts +0 -88
- package/dist/testing/mocks/MockSyncStore.js +0 -171
- package/dist/testing/mocks/MockWebSocket.d.ts +0 -71
- package/dist/testing/mocks/MockWebSocket.js +0 -118
- package/dist/transactions/durableWriteStore.js +0 -30
- package/dist/utils/duration.d.ts +0 -25
- package/dist/utils/json.js +0 -88
- package/dist/wire/errorEnvelope.d.ts +0 -55
- package/dist/wire/frames.d.ts +0 -197
- package/dist/wire/frames.js +0 -49
- package/dist/wire/listEnvelope.js +0 -18
- package/docs/interaction-model.md +0 -97
- /package/dist/{core → query}/QueryProcessor.d.ts +0 -0
- /package/dist/{core → query}/QueryProcessor.js +0 -0
- /package/dist/{core/storeContract.js → storeContract.js} +0 -0
- /package/dist/{core → stores}/openIDBWithTimeout.d.ts +0 -0
- /package/dist/{core → stores}/openIDBWithTimeout.js +0 -0
- /package/dist/{client → transaction/auth}/credentialEndpoint.d.ts +0 -0
- /package/dist/{client → transaction/auth}/credentialEndpoint.js +0 -0
- /package/dist/{auth → transaction/auth}/credentialPolicy.d.ts +0 -0
- /package/dist/{auth → transaction/auth}/credentialPolicy.js +0 -0
- /package/dist/{auth → transaction/auth}/credentialSource.js +0 -0
- /package/dist/{client → transaction/auth}/hostedEndpoints.d.ts +0 -0
- /package/dist/{client → transaction/auth}/hostedEndpoints.js +0 -0
- /package/dist/{client → transaction}/persistence.d.ts +0 -0
- /package/dist/{client → transaction}/persistence.js +0 -0
- /package/dist/{client → transaction/resources}/functionalUpdate.d.ts +0 -0
- /package/dist/{client → transaction/resources}/functionalUpdate.js +0 -0
- /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.d.ts +0 -0
- /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.js +0 -0
- /package/dist/{client → transaction/transport}/httpTransport.d.ts +0 -0
- /package/dist/{types → transaction/types}/modelData.d.ts +0 -0
- /package/dist/{types → transaction/types}/modelData.js +0 -0
- /package/dist/{types → transaction/types}/participant.d.ts +0 -0
- /package/dist/{types → transaction/types}/participant.js +0 -0
- /package/dist/{types → transaction/types}/streams.js +0 -0
- /package/dist/{utils → transaction/utils}/asyncIterator.d.ts +0 -0
- /package/dist/{utils → transaction/utils}/asyncIterator.js +0 -0
- /package/dist/{wire → transaction/wire}/bootstrapReason.d.ts +0 -0
- /package/dist/{wire → transaction/wire}/bootstrapReason.js +0 -0
- /package/dist/{wire → transaction/wire}/protocol.d.ts +0 -0
- /package/dist/{wire → transaction/wire}/protocol.js +0 -0
- /package/dist/{wire → transaction/wire}/protocolVersion.d.ts +0 -0
- /package/dist/{wire → transaction/wire}/protocolVersion.js +0 -0
- /package/dist/transactions/{UnconfirmedWrites.d.ts → mutations/UnconfirmedWrites.d.ts} +0 -0
- /package/dist/transactions/{UnconfirmedWrites.js → mutations/UnconfirmedWrites.js} +0 -0
- /package/dist/transactions/{optimisticApply.js → mutations/optimisticApply.js} +0 -0
- /package/dist/{core → views}/ViewRegistry.js +0 -0
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The duplex transport: a WebSocket connection to the sync server, extracted
|
|
3
|
+
* out of the reactive engine's `SyncWebSocket` (ADR 0016). It owns the socket
|
|
4
|
+
* lifecycle (connect, reconnect with exponential backoff, disconnect, the
|
|
5
|
+
* application-level heartbeat), sends commits, claims, releases, and
|
|
6
|
+
* subscription updates over the one connection, correlates their
|
|
7
|
+
* acknowledgement frames back to awaiting callers, and dispatches every other
|
|
8
|
+
* inbound frame through {@link dispatchWsFrame}.
|
|
9
|
+
*
|
|
10
|
+
* What it deliberately does not do is materialise: deltas, sync responses,
|
|
11
|
+
* and bootstrap payloads are surfaced through protected frame hooks
|
|
12
|
+
* ({@link handleDelta} and its siblings) whose defaults just emit, so a
|
|
13
|
+
* server-side caller gets the push feed — claim grants, losses, deltas —
|
|
14
|
+
* with no store, no cursor, and no renderer. The reactive engine subclasses
|
|
15
|
+
* this and overrides the hooks with validation, cursor advancement, and
|
|
16
|
+
* bootstrap handling. The membership test (ADR 0016): a caller with no socket
|
|
17
|
+
* loses only push — it polls instead; a caller with no reactive layer loses
|
|
18
|
+
* the local copy it never wanted.
|
|
19
|
+
*/
|
|
20
|
+
import { EventEmitter } from 'events';
|
|
21
|
+
import type { ParticipantKind } from '../types/participant.js';
|
|
22
|
+
import type { BootstrapReason } from '../wire/bootstrapReason.js';
|
|
23
|
+
import type { ClientSyncDelta } from '../wire/delta.js';
|
|
24
|
+
import type { ClaimAcquired, PresenceUpdate, ClaimExpired, ClaimGranted, ClaimHeartbeatAckPayload, ClaimLost, ClaimQueue, ClaimQueued, ClaimRejection, ParticipantClaimPayload, StaleNotification, ReadDependency, TrackDependency } from '../coordination/schema.js';
|
|
25
|
+
import { type AuthTokenGetter } from '../auth/credentialSource.js';
|
|
26
|
+
import { type CommitAck, type CommitFrameOperation } from './commitFrames.js';
|
|
27
|
+
import { type Logger } from '../logger.js';
|
|
28
|
+
import { type SocketObservability } from '../observability.js';
|
|
29
|
+
export interface SyncCapabilities {
|
|
30
|
+
partialBootstrap?: boolean;
|
|
31
|
+
compressedDeltas?: boolean;
|
|
32
|
+
streamingBootstrap?: boolean;
|
|
33
|
+
batchedDeltas?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface WsTransportOptions {
|
|
36
|
+
/** Base HTTP URL of the sync server */
|
|
37
|
+
baseUrl?: string;
|
|
38
|
+
url?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Engine bookkeeping only. The server is bearer-only — it resolves identity
|
|
41
|
+
* from the verified credential and never reads these — and the transport
|
|
42
|
+
* itself never reads them either. A bare connection omits them.
|
|
43
|
+
*/
|
|
44
|
+
userId?: string;
|
|
45
|
+
organizationId?: string;
|
|
46
|
+
lastSyncId?: number;
|
|
47
|
+
syncGroups?: string[];
|
|
48
|
+
capabilities?: SyncCapabilities;
|
|
49
|
+
reconnectDelay?: number;
|
|
50
|
+
maxReconnectDelay?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Collaboration event type keys to listen for (e.g., ['document:selection',
|
|
53
|
+
* 'document:cursor']). Wire messages with matching types (underscore format)
|
|
54
|
+
* are emitted as events.
|
|
55
|
+
*
|
|
56
|
+
* Defaults to none. The vocabulary is the application's, not the SDK's, so
|
|
57
|
+
* an application names the events it broadcasts rather than inheriting a
|
|
58
|
+
* built-in list that would only ever fit one consumer.
|
|
59
|
+
*/
|
|
60
|
+
collaborationEvents?: string[];
|
|
61
|
+
/**
|
|
62
|
+
* The participant kind declared on the WebSocket upgrade. Defaults to
|
|
63
|
+
* `'user'` (session auth, the web app). Agent runtimes pass `'agent'` so the
|
|
64
|
+
* server verifies them by capability token instead of session auth. The
|
|
65
|
+
* server reads this as the `kind` query parameter.
|
|
66
|
+
*/
|
|
67
|
+
kind?: ParticipantKind;
|
|
68
|
+
/**
|
|
69
|
+
* The agent's bearer credential — a restricted (`rk_`) API key. When set, it
|
|
70
|
+
* is sent in the `ablo.bearer.<token>` WebSocket subprotocol so the credential
|
|
71
|
+
* stays out of URLs and proxy logs. Required for `kind: 'agent'` and ignored
|
|
72
|
+
* for `kind: 'user'`.
|
|
73
|
+
*/
|
|
74
|
+
capabilityToken?: string;
|
|
75
|
+
/**
|
|
76
|
+
* Getter for the current credential. When provided, the WebSocket upgrade
|
|
77
|
+
* reads it instead of a copied `capabilityToken`, so reconnects always use
|
|
78
|
+
* the freshest token from the SDK's single credential source. Preferred over
|
|
79
|
+
* `getCapabilityToken`.
|
|
80
|
+
*/
|
|
81
|
+
getAuthToken?: AuthTokenGetter;
|
|
82
|
+
/** @deprecated Use `getAuthToken`. Kept for direct low-level callers. */
|
|
83
|
+
getCapabilityToken?: AuthTokenGetter;
|
|
84
|
+
/**
|
|
85
|
+
* Hold the first connection until the owner releases it. While held,
|
|
86
|
+
* `connect()` is ignored (debug-logged). A host that builds the socket
|
|
87
|
+
* before identity is resolved sets this, seeds the late values (`setKind`,
|
|
88
|
+
* `setSyncGroups`, the resume cursor), and calls {@link WsTransport.allowConnect}
|
|
89
|
+
* followed by `connect()` — so no caller can open an unscoped connection in
|
|
90
|
+
* the window between construction and identity resolution.
|
|
91
|
+
*/
|
|
92
|
+
deferConnect?: boolean;
|
|
93
|
+
/** Where the transport logs. Defaults to silent. */
|
|
94
|
+
logger?: Logger;
|
|
95
|
+
/** Where lifecycle breadcrumbs, socket errors, and coordination outcomes
|
|
96
|
+
* are reported. Defaults to silent. */
|
|
97
|
+
observability?: SocketObservability;
|
|
98
|
+
/** The connectivity signal consulted before connecting, sending, and
|
|
99
|
+
* scheduling reconnects. Defaults to always-online, which is correct for a
|
|
100
|
+
* server-side host; the browser engine passes its `navigator.onLine`-backed
|
|
101
|
+
* provider. */
|
|
102
|
+
onlineStatus?: {
|
|
103
|
+
isOnline(): boolean;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Bootstrap hint from server indicating full or partial bootstrap is needed.
|
|
108
|
+
* Properties are optional since server payload structure may vary.
|
|
109
|
+
*/
|
|
110
|
+
export interface BootstrapHint {
|
|
111
|
+
tables?: string[];
|
|
112
|
+
reason?: BootstrapReason;
|
|
113
|
+
staleTables?: string[];
|
|
114
|
+
totalDeltaCount?: number;
|
|
115
|
+
}
|
|
116
|
+
/** Bootstrap data event payload */
|
|
117
|
+
export interface BootstrapDataEvent {
|
|
118
|
+
entityType: string;
|
|
119
|
+
data: unknown;
|
|
120
|
+
isComplete: boolean;
|
|
121
|
+
cursor?: string;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The presence frame, re-exported at the path consumers already reach it
|
|
125
|
+
* through. The declaration lives with the rest of the coordination vocabulary;
|
|
126
|
+
* this keeps `import { PresenceUpdate } from '…/wsTransport'` working for
|
|
127
|
+
* everything that used to import the hand-written type from here. The local
|
|
128
|
+
* `import type` above is what makes this a re-export of a bound name rather
|
|
129
|
+
* than a pass-through that leaves the name unusable in this file.
|
|
130
|
+
*/
|
|
131
|
+
export type { PresenceUpdate };
|
|
132
|
+
/**
|
|
133
|
+
* Core event map — transport-level events that every connection emits.
|
|
134
|
+
* SDK consumers extend this with app-specific collaboration events.
|
|
135
|
+
*/
|
|
136
|
+
export interface CoreSyncEventMap {
|
|
137
|
+
connected: [];
|
|
138
|
+
disconnected: [CloseEvent];
|
|
139
|
+
reconnecting: [{
|
|
140
|
+
attempt: number;
|
|
141
|
+
delay: number;
|
|
142
|
+
}];
|
|
143
|
+
delta: [ClientSyncDelta];
|
|
144
|
+
delta_batch: [ClientSyncDelta[]];
|
|
145
|
+
bootstrap_required: [BootstrapHint];
|
|
146
|
+
bootstrap_data: [BootstrapDataEvent];
|
|
147
|
+
presence_update: [PresenceUpdate];
|
|
148
|
+
error: [Error];
|
|
149
|
+
session_error: [Error];
|
|
150
|
+
/**
|
|
151
|
+
* The WebSocket `onclose` fired before `onopen` — the handshake itself
|
|
152
|
+
* failed. The browser cannot expose the HTTP status (it shows as code
|
|
153
|
+
* 1006 with no reason), so the consumer should run an authenticated
|
|
154
|
+
* HTTP probe to distinguish auth failure (session expired) from a
|
|
155
|
+
* generic network issue.
|
|
156
|
+
*/
|
|
157
|
+
handshake_failed: [CloseEvent];
|
|
158
|
+
reconnect_failed: [{
|
|
159
|
+
attempts: number;
|
|
160
|
+
}];
|
|
161
|
+
/**
|
|
162
|
+
* Server-initiated notification that a previously-active claim's
|
|
163
|
+
* TTL has expired. Consumers (e.g., the participant SDK) re-mint
|
|
164
|
+
* a fresh capability and re-claim, OR accept the drop. The claim
|
|
165
|
+
* is already inactive on the server side by the time this fires —
|
|
166
|
+
* no client-side action needed unless re-claiming.
|
|
167
|
+
*/
|
|
168
|
+
claim_expired: [ClaimExpired];
|
|
169
|
+
/**
|
|
170
|
+
* Server rejected an `claim_begin` because another participant
|
|
171
|
+
* already holds an open claim on the same target (cooperative
|
|
172
|
+
* mutex enforced server-side). Surfaces to the participant-level
|
|
173
|
+
* ClaimStream so the caller knows their announce was denied.
|
|
174
|
+
* Payload mirrors the wire frame's `payload`.
|
|
175
|
+
*/
|
|
176
|
+
claim_rejected: [ClaimRejection];
|
|
177
|
+
/**
|
|
178
|
+
* Fair-queue frames (opt-in `queue: true` on `claim_begin`). `claim_acquired`
|
|
179
|
+
* means the target was free and the lease is ours immediately; `claim_queued`
|
|
180
|
+
* means the claim is waiting in line (carries `position`); `claim_granted`
|
|
181
|
+
* means it reached the head and the lease is now ours; `claim_lost` means a
|
|
182
|
+
* held/granted claim was taken away (TTL lapse on disconnect, revoke).
|
|
183
|
+
*/
|
|
184
|
+
/**
|
|
185
|
+
* Per-entity wait-queue snapshot: `{ target, queue: Claim[] }` with each
|
|
186
|
+
* entry `status: 'queued'` + `position`. Broadcast to entity peers on every
|
|
187
|
+
* queue mutation — powers the reactive `ablo.<model>.claim.queue({ id })` read.
|
|
188
|
+
*/
|
|
189
|
+
claim_queue: [ClaimQueue];
|
|
190
|
+
claim_acquired: [ClaimAcquired];
|
|
191
|
+
claim_queued: [ClaimQueued];
|
|
192
|
+
claim_granted: [ClaimGranted];
|
|
193
|
+
claim_lost: [ClaimLost];
|
|
194
|
+
/**
|
|
195
|
+
* Reply to an outbound `claim_heartbeat` — the lease's fate: `held` with
|
|
196
|
+
* the extended `expiresAt`, `queued` with the current `position`, or
|
|
197
|
+
* `lost`. Correlated back to the awaiting caller by `claimId` in the
|
|
198
|
+
* claim stream.
|
|
199
|
+
*/
|
|
200
|
+
claim_heartbeat_ack: [ClaimHeartbeatAckPayload];
|
|
201
|
+
/**
|
|
202
|
+
* A committed write guarded with `onStale: 'notify'` collided with a
|
|
203
|
+
* concurrent change. Rather than forcing an outcome, the engine returns the
|
|
204
|
+
* conflicting field's current value so the actor — an agent reasoning over the
|
|
205
|
+
* change, or a person watching the row — can reconcile it. The commit itself
|
|
206
|
+
* succeeded; the held operations were not written, and the actor re-issues
|
|
207
|
+
* them once it has reconciled.
|
|
208
|
+
*/
|
|
209
|
+
'conflict:notified': [{
|
|
210
|
+
clientTxId: string;
|
|
211
|
+
notifications: StaleNotification[];
|
|
212
|
+
}];
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Collaboration event — app-specific real-time events (selection, cursors, etc.)
|
|
216
|
+
* Each event is a [payload] tuple matching the EventEmitter convention.
|
|
217
|
+
*/
|
|
218
|
+
export type DefaultCollaborationEvents = Record<string, never>;
|
|
219
|
+
/**
|
|
220
|
+
* Constraint for event maps: every value must be a tuple of handler args.
|
|
221
|
+
*
|
|
222
|
+
* Why a mapped type and not `Record<string, unknown[]>`?
|
|
223
|
+
* `Record<string, ...>` requires an implicit string index signature, which
|
|
224
|
+
* TypeScript interfaces don't have. So a closed interface like Ablo's
|
|
225
|
+
* `AbloCollaborationEvents` would fail to satisfy `Record<string, unknown[]>`,
|
|
226
|
+
* even though every one of its values is a tuple. This mapped form iterates
|
|
227
|
+
* over `keyof T` instead of demanding a string index, so it accepts both
|
|
228
|
+
* closed interfaces and open Record types — while still enforcing
|
|
229
|
+
* "every value is an array."
|
|
230
|
+
*/
|
|
231
|
+
export type EventMap<T> = {
|
|
232
|
+
[K in keyof T]: unknown[];
|
|
233
|
+
};
|
|
234
|
+
/**
|
|
235
|
+
* Full event map = core + collaboration events.
|
|
236
|
+
* Pass your own TCollaboration to add app-specific events.
|
|
237
|
+
*/
|
|
238
|
+
export type SyncWebSocketEventMap<TCollaboration extends EventMap<TCollaboration> = DefaultCollaborationEvents> = CoreSyncEventMap & TCollaboration;
|
|
239
|
+
export declare class WsTransport<TCollaboration extends EventMap<TCollaboration> = DefaultCollaborationEvents> extends EventEmitter {
|
|
240
|
+
/**
|
|
241
|
+
* Subscribe to events with automatic cleanup.
|
|
242
|
+
* Returns unsubscribe function for clean disposal.
|
|
243
|
+
*/
|
|
244
|
+
subscribe<K extends keyof SyncWebSocketEventMap<TCollaboration>>(event: K, handler: (...args: SyncWebSocketEventMap<TCollaboration>[K]) => void): () => void;
|
|
245
|
+
/**
|
|
246
|
+
* Send a collaboration event (app-specific real-time message).
|
|
247
|
+
* The wire format is `{ type: messageType, payload: { ...payload, timestamp } }`.
|
|
248
|
+
*/
|
|
249
|
+
sendCollaborationEvent<K extends string & keyof TCollaboration>(messageType: K, payload: TCollaboration[K] extends [infer P] ? Omit<P & Record<string, unknown>, 'timestamp'> : never): void;
|
|
250
|
+
private ws;
|
|
251
|
+
protected options: Required<Omit<WsTransportOptions, 'baseUrl' | 'kind' | 'capabilityToken' | 'getAuthToken' | 'getCapabilityToken' | 'deferConnect' | 'logger' | 'observability' | 'onlineStatus'>> & {
|
|
252
|
+
baseUrl?: string;
|
|
253
|
+
kind?: WsTransportOptions['kind'];
|
|
254
|
+
capabilityToken?: WsTransportOptions['capabilityToken'];
|
|
255
|
+
getAuthToken?: WsTransportOptions['getAuthToken'];
|
|
256
|
+
getCapabilityToken?: WsTransportOptions['getCapabilityToken'];
|
|
257
|
+
};
|
|
258
|
+
/** The transport's reporting ports, shared with the subclassing engine. */
|
|
259
|
+
protected readonly logger: Logger;
|
|
260
|
+
protected readonly observability: SocketObservability;
|
|
261
|
+
protected readonly onlineStatus: {
|
|
262
|
+
isOnline(): boolean;
|
|
263
|
+
};
|
|
264
|
+
private reconnectAttempts;
|
|
265
|
+
/** Stop retrying after this many consecutive failures (backoff caps at 30s, so ~7.5 min total) */
|
|
266
|
+
private static readonly MAX_RECONNECT_ATTEMPTS;
|
|
267
|
+
private reconnectTimer;
|
|
268
|
+
/**
|
|
269
|
+
* Application-level heartbeat: ping every 30 seconds and force-close after a
|
|
270
|
+
* 10-second silence. The {@link HeartbeatController} holds the timing and the
|
|
271
|
+
* zombie-socket rationale; the closures below are the only socket access it
|
|
272
|
+
* gets.
|
|
273
|
+
*/
|
|
274
|
+
private readonly heartbeat;
|
|
275
|
+
private isConnecting;
|
|
276
|
+
private isManualClose;
|
|
277
|
+
/** True while the owner still holds the first connection (`deferConnect`).
|
|
278
|
+
* `connect()` is ignored until {@link allowConnect} lifts the hold. */
|
|
279
|
+
private connectHeld;
|
|
280
|
+
/** When true, a session error has been detected (from any path — WS close or HTTP bootstrap).
|
|
281
|
+
* Suppresses reconnection and Sentry error capture to avoid cascading noise. */
|
|
282
|
+
private _sessionErrorDetected;
|
|
283
|
+
/** True once `onopen` has fired at least once on the current socket. Reset each
|
|
284
|
+
* time a new socket is created in `connect()`. Used by `onclose` to detect
|
|
285
|
+
* handshake failures (close before open) — the one signal we have for "the
|
|
286
|
+
* server rejected the upgrade" since browsers hide the HTTP status (e.g.
|
|
287
|
+
* 401) behind the opaque 1006 close code. */
|
|
288
|
+
private _everOpened;
|
|
289
|
+
/**
|
|
290
|
+
* Diagnostic snapshot of the last connection lifecycle. Persisted across
|
|
291
|
+
* the lifetime of the transport so that any subsequent "not connected"
|
|
292
|
+
* rejection can quote the actual root cause (close code + reason + when)
|
|
293
|
+
* instead of bottoming out at a generic error string. Browser WS code 1006
|
|
294
|
+
* hides the real reason, so we layer on our own signals: `forceCloseReason`
|
|
295
|
+
* captures heartbeat trips / send failures, `everOpened` distinguishes
|
|
296
|
+
* handshake reject from mid-session drop, and `sessionErrorAt` tells us
|
|
297
|
+
* whether reconnect is suppressed.
|
|
298
|
+
*/
|
|
299
|
+
private lastOpenAt;
|
|
300
|
+
private lastCloseAt;
|
|
301
|
+
private lastCloseCode;
|
|
302
|
+
private lastCloseReason;
|
|
303
|
+
private lastForceCloseReason;
|
|
304
|
+
private sessionErrorAt;
|
|
305
|
+
/** Registered collaboration event keys (colon format) for dispatch in onmessage */
|
|
306
|
+
private collaborationEventTypes;
|
|
307
|
+
/**
|
|
308
|
+
* A minimal session adapter handed to the inbound frame dispatch table
|
|
309
|
+
* ({@link dispatchWsFrame}). It exposes only the members the handlers touch;
|
|
310
|
+
* the closure members read live state so a reassignment here (for example the
|
|
311
|
+
* `pendingSubscriptions` reset on close) cannot strand a handler on a stale
|
|
312
|
+
* reference. Built in the constructor, after the state it captures exists.
|
|
313
|
+
*/
|
|
314
|
+
private readonly frameSession;
|
|
315
|
+
/**
|
|
316
|
+
* In-flight `commit` mutation requests keyed by clientTxId. Resolved when
|
|
317
|
+
* a matching `mutation_result` frame arrives from the server, or rejected on
|
|
318
|
+
* timeout / disconnect. Lets consumers await a server ack for mutations
|
|
319
|
+
* sent over the same socket that streams deltas.
|
|
320
|
+
*/
|
|
321
|
+
private pendingMutations;
|
|
322
|
+
/**
|
|
323
|
+
* In-flight `claim` requests keyed by claimId. Resolved when the matching
|
|
324
|
+
* `claim_ack` arrives, or rejected on timeout or disconnect — the same
|
|
325
|
+
* request/response pattern as `pendingMutations`, multiplexed over the one
|
|
326
|
+
* connection.
|
|
327
|
+
*/
|
|
328
|
+
private pendingClaims;
|
|
329
|
+
/**
|
|
330
|
+
* In-flight `update_subscription` frames awaiting `subscription_ack`.
|
|
331
|
+
* A FIFO queue rather than a keyed Map because the wire ack carries no
|
|
332
|
+
* correlation id — the server applies subscription updates in receive
|
|
333
|
+
* order and acks in the same order, so `shift()` on ack matches the
|
|
334
|
+
* oldest pending request. (Read-interest changes are infrequent and
|
|
335
|
+
* usually settle before the next one, so depth is ~1 in practice.)
|
|
336
|
+
*/
|
|
337
|
+
private pendingSubscriptions;
|
|
338
|
+
constructor(options: WsTransportOptions);
|
|
339
|
+
/**
|
|
340
|
+
* One inbound delta, straight off the wire and unvalidated. The default
|
|
341
|
+
* emits it as-is; the reactive engine's override validates against the
|
|
342
|
+
* canonical delta schema and drops anything malformed before emitting.
|
|
343
|
+
*/
|
|
344
|
+
protected handleDelta(rawDelta: unknown): void;
|
|
345
|
+
/** A `sync_response` frame. Meaningless without a resume cursor to advance,
|
|
346
|
+
* so the transport default does nothing. */
|
|
347
|
+
protected handleSyncResponse(_payload: unknown): void;
|
|
348
|
+
/** A `bootstrap_response` frame. Bootstrap is materialisation, so the
|
|
349
|
+
* transport default does nothing. */
|
|
350
|
+
protected handleBootstrapResponse(_payload: unknown): void;
|
|
351
|
+
/**
|
|
352
|
+
* Handles a presence update from the server. The wire frame's payload is
|
|
353
|
+
* forwarded as-is, so every consumer reads the same shape; stripping fields
|
|
354
|
+
* here would drop `kind`, `activity`, `syncGroups`, and `isAgent` for
|
|
355
|
+
* consumers that need them.
|
|
356
|
+
*
|
|
357
|
+
* The wire frame is:
|
|
358
|
+
* { type: 'presence_update', payload: { kind, userId, status,
|
|
359
|
+
* syncGroups, activity, isAgent, timestamp, activeClaims } }
|
|
360
|
+
*/
|
|
361
|
+
protected handlePresenceUpdate(message: Partial<PresenceUpdate> & {
|
|
362
|
+
payload?: PresenceUpdate;
|
|
363
|
+
[k: string]: unknown;
|
|
364
|
+
}): void;
|
|
365
|
+
/**
|
|
366
|
+
* Runs after the socket opens and `connected` is emitted, before the
|
|
367
|
+
* heartbeat starts. The default does nothing; the reactive engine's
|
|
368
|
+
* override runs its open ritual — presence, ack, incremental sync, and the
|
|
369
|
+
* catch-up poll.
|
|
370
|
+
*/
|
|
371
|
+
protected onOpened(): void;
|
|
372
|
+
/**
|
|
373
|
+
* Runs inside the close handler, after the socket reference is cleared and
|
|
374
|
+
* before in-flight requests are rejected. The default does nothing; the
|
|
375
|
+
* reactive engine's override stops its catch-up poll.
|
|
376
|
+
*/
|
|
377
|
+
protected onClosed(): void;
|
|
378
|
+
/**
|
|
379
|
+
* The resume position sent as the `cursor` query parameter on the upgrade.
|
|
380
|
+
* The transport itself holds no cursor — a bare connection resumes from
|
|
381
|
+
* nothing — so the default is empty; the reactive engine's override supplies
|
|
382
|
+
* its persisted sync cursor.
|
|
383
|
+
*/
|
|
384
|
+
protected resumeCursor(): string;
|
|
385
|
+
/**
|
|
386
|
+
* Mark that a session error has been detected (e.g. 401 from HTTP bootstrap).
|
|
387
|
+
* Suppresses further reconnection attempts and Sentry error capture.
|
|
388
|
+
*/
|
|
389
|
+
setSessionErrorDetected(): void;
|
|
390
|
+
/**
|
|
391
|
+
* Clear the session-error latch so `connect()` / `scheduleReconnect()`
|
|
392
|
+
* work again. Called by the store's access-credential recovery path when
|
|
393
|
+
* the close was a re-mintable `ek_`/`rk_` expiry (`4001 credential_expired`),
|
|
394
|
+
* not a login loss — see `isAccessCredentialExpiryCloseReason`. Genuine
|
|
395
|
+
* session losses never clear the latch; re-auth builds a fresh client.
|
|
396
|
+
*/
|
|
397
|
+
clearSessionError(): void;
|
|
398
|
+
/**
|
|
399
|
+
* Lift the `deferConnect` hold. The owner calls this once the connection's
|
|
400
|
+
* identity and read scope are seeded; from then on `connect()` works
|
|
401
|
+
* normally, including every reconnect path.
|
|
402
|
+
*/
|
|
403
|
+
allowConnect(): void;
|
|
404
|
+
/**
|
|
405
|
+
* Connect to the sync engine WebSocket
|
|
406
|
+
*/
|
|
407
|
+
connect(): void;
|
|
408
|
+
/**
|
|
409
|
+
* Setup WebSocket event handlers
|
|
410
|
+
*/
|
|
411
|
+
private setupEventHandlers;
|
|
412
|
+
/**
|
|
413
|
+
* Send message to server
|
|
414
|
+
*/
|
|
415
|
+
send(message: any): void;
|
|
416
|
+
/**
|
|
417
|
+
* Sends a `commit` mutation request over the existing WebSocket and resolves
|
|
418
|
+
* when the server's `mutation_result` frame comes back with the same
|
|
419
|
+
* `clientTxId`. The wire frame is `{ type: 'commit', payload: { operations,
|
|
420
|
+
* clientTxId } }`.
|
|
421
|
+
*
|
|
422
|
+
* Times out after 15 seconds of silence from the server. The socket may close
|
|
423
|
+
* during an in-flight mutation (a network flap, a server restart); this does
|
|
424
|
+
* not auto-retry — the caller's transaction queue owns retry and offline
|
|
425
|
+
* replay, and the SDK does not duplicate that logic.
|
|
426
|
+
*/
|
|
427
|
+
sendCommit(operations: readonly CommitFrameOperation[], clientTxId: string, timeoutMs?: number, reads?: readonly ReadDependency[] | null, track?: readonly TrackDependency[] | null): Promise<CommitAck>;
|
|
428
|
+
/**
|
|
429
|
+
* Send a commit frame without waiting for `mutation_result`.
|
|
430
|
+
*
|
|
431
|
+
* This backs the public `wait: 'queued'` API: the socket accepted the
|
|
432
|
+
* frame for delivery, but the server has not confirmed it yet. The
|
|
433
|
+
* eventual `mutation_result` frame is intentionally ignored by this
|
|
434
|
+
* instance because no pending resolver is registered.
|
|
435
|
+
*/
|
|
436
|
+
sendCommitQueued(operations: readonly CommitFrameOperation[], clientTxId: string, reads?: readonly ReadDependency[] | null, track?: readonly TrackDependency[] | null): void;
|
|
437
|
+
/**
|
|
438
|
+
* Activates a participant claim on this connection. One connection can hold
|
|
439
|
+
* several concurrent claims at once, each scoped to a different set of sync
|
|
440
|
+
* groups, so the SDK reuses the existing connection instead of opening a
|
|
441
|
+
* separate socket per scope.
|
|
442
|
+
*
|
|
443
|
+
* Returns a promise that resolves with the server-canonicalized `syncGroups`
|
|
444
|
+
* and effective `ttlSeconds` once `claim_ack` arrives, or rejects with a typed
|
|
445
|
+
* error on a failed ack, a timeout, or a disconnect.
|
|
446
|
+
*/
|
|
447
|
+
sendClaim(claimId: string, syncGroups: readonly string[], options?: Pick<ParticipantClaimPayload, 'capabilityToken' | 'ttlSeconds'> & {
|
|
448
|
+
timeoutMs?: number;
|
|
449
|
+
}): Promise<{
|
|
450
|
+
syncGroups: string[];
|
|
451
|
+
ttlSeconds?: number;
|
|
452
|
+
}>;
|
|
453
|
+
/**
|
|
454
|
+
* Drop a previously-active claim. Idempotent — `release` is
|
|
455
|
+
* fire-and-forget per the wire contract; the server accepts
|
|
456
|
+
* unknown claimIds silently so disconnect-time release storms
|
|
457
|
+
* never error. No ack is expected.
|
|
458
|
+
*
|
|
459
|
+
* If a claim's send promise is still pending (no claim_ack yet),
|
|
460
|
+
* we reject it locally — the user explicitly chose to release.
|
|
461
|
+
*/
|
|
462
|
+
sendRelease(claimId: string): void;
|
|
463
|
+
/**
|
|
464
|
+
* Moves this connection's read interest — replaces the connection-level sync
|
|
465
|
+
* groups mid-session as the user opens and closes entities. This is the
|
|
466
|
+
* area-of-interest navigation primitive: the server fans out deltas only for
|
|
467
|
+
* the groups currently in view, rather than the fixed set chosen at connect.
|
|
468
|
+
*
|
|
469
|
+
* This is a full-set replace: pass the complete new group list, not a delta.
|
|
470
|
+
* Resolves with the server's effective set once `subscription_ack` arrives;
|
|
471
|
+
* rejects (with a typed error) on a scope denial (a restricted `rk_` key
|
|
472
|
+
* requesting a group outside its allowlist), a timeout, or a disconnect. On
|
|
473
|
+
* success the new set is recorded as `options.syncGroups`, so a later reconnect
|
|
474
|
+
* re-subscribes to the current interest rather than the connect-time set.
|
|
475
|
+
*
|
|
476
|
+
* Distinct from {@link sendClaim} (a write claim, per operation, with a TTL):
|
|
477
|
+
* this is the read side, carries no capability token of its own, and is
|
|
478
|
+
* bounded by the connection credential's grant.
|
|
479
|
+
*/
|
|
480
|
+
updateSubscription(syncGroups: readonly string[], options?: {
|
|
481
|
+
timeoutMs?: number;
|
|
482
|
+
}): Promise<{
|
|
483
|
+
syncGroups: string[];
|
|
484
|
+
}>;
|
|
485
|
+
/**
|
|
486
|
+
* Sets a fixed credential for callers that construct the socket directly. The
|
|
487
|
+
* SDK instead supplies `getAuthToken`, so reconnects read the shared
|
|
488
|
+
* credential source rather than this copied value.
|
|
489
|
+
*/
|
|
490
|
+
setCapabilityToken(token: string): void;
|
|
491
|
+
/**
|
|
492
|
+
* Seeds the participant kind after identity resolution. The kind rides the
|
|
493
|
+
* upgrade URL and selects the server's auth path, and on the hosted path it
|
|
494
|
+
* is derived from the credential's scope — known only once identity
|
|
495
|
+
* resolves, after the socket is built. Call before `connect()`.
|
|
496
|
+
*/
|
|
497
|
+
setKind(kind: ParticipantKind): void;
|
|
498
|
+
getAuthToken(): string | undefined;
|
|
499
|
+
/**
|
|
500
|
+
* Return the credential that will be used by the next WebSocket upgrade.
|
|
501
|
+
* ConnectionManager reads this for HTTP auth probes so visibility/network
|
|
502
|
+
* checks authenticate the same way reconnects do.
|
|
503
|
+
*/
|
|
504
|
+
getCapabilityToken(): string | undefined;
|
|
505
|
+
private resolveAuthToken;
|
|
506
|
+
/**
|
|
507
|
+
* Schedule reconnection with exponential backoff
|
|
508
|
+
*/
|
|
509
|
+
private scheduleReconnect;
|
|
510
|
+
/**
|
|
511
|
+
* Reset reconnect attempt counter. Called when network comes back online
|
|
512
|
+
* to allow a fresh reconnect cycle after the max was previously reached.
|
|
513
|
+
*/
|
|
514
|
+
resetReconnectAttempts(): void;
|
|
515
|
+
/**
|
|
516
|
+
* Disconnect from WebSocket
|
|
517
|
+
*/
|
|
518
|
+
disconnect(): void;
|
|
519
|
+
/**
|
|
520
|
+
* Force-close the socket from the client side using a private 4xxx
|
|
521
|
+
* code. Callers expect `onclose` to fire; that handler runs the
|
|
522
|
+
* existing reconnect / handshake-failed dispatch. Wrapped in
|
|
523
|
+
* try/catch because `close()` on a CLOSING/CLOSED socket throws on
|
|
524
|
+
* some browsers.
|
|
525
|
+
*/
|
|
526
|
+
protected forceClose(reason: string): void;
|
|
527
|
+
/**
|
|
528
|
+
* Get connection state
|
|
529
|
+
*/
|
|
530
|
+
isConnected(): boolean;
|
|
531
|
+
/**
|
|
532
|
+
* Snapshot of recent connection lifecycle state, for diagnostic logs
|
|
533
|
+
* and error messages. Cheap to call (no I/O); safe to log every time
|
|
534
|
+
* a send is rejected so we can attribute "not connected" rejections
|
|
535
|
+
* to the actual root cause (handshake reject vs heartbeat zombie vs
|
|
536
|
+
* session expiry vs explicit close).
|
|
537
|
+
*/
|
|
538
|
+
getConnectionDiagnostics(): {
|
|
539
|
+
readyState: number | null;
|
|
540
|
+
isConnecting: boolean;
|
|
541
|
+
isManualClose: boolean;
|
|
542
|
+
sessionErrorDetected: boolean;
|
|
543
|
+
everOpened: boolean;
|
|
544
|
+
reconnectAttempts: number;
|
|
545
|
+
maxReconnectAttempts: number;
|
|
546
|
+
lastOpenAt: number | null;
|
|
547
|
+
lastCloseAt: number | null;
|
|
548
|
+
lastCloseCode: number | null;
|
|
549
|
+
lastCloseReason: string | null;
|
|
550
|
+
lastForceCloseReason: string | null;
|
|
551
|
+
sessionErrorAt: number | null;
|
|
552
|
+
msSinceLastOpen: number | null;
|
|
553
|
+
msSinceLastClose: number | null;
|
|
554
|
+
};
|
|
555
|
+
/**
|
|
556
|
+
* Build a richly-diagnosed "not connected" error so callers (and the
|
|
557
|
+
* logs they emit) can attribute the rejection. The message embeds the
|
|
558
|
+
* dominant signal in human-readable form; the structured detail is
|
|
559
|
+
* also attached as `error.diagnostics` for log scrapers.
|
|
560
|
+
*/
|
|
561
|
+
protected notConnectedError(action: string): Error & {
|
|
562
|
+
diagnostics: ReturnType<WsTransport['getConnectionDiagnostics']>;
|
|
563
|
+
};
|
|
564
|
+
/** Returns the sync groups this connection is subscribed to. */
|
|
565
|
+
getSyncGroups(): string[];
|
|
566
|
+
/**
|
|
567
|
+
* Seeds the connection's read interest — the sync groups the next upgrade
|
|
568
|
+
* URL carries. The set is already mutable state (`subscription_ack` writes
|
|
569
|
+
* the acked set back so a reconnect resubscribes to current interest);
|
|
570
|
+
* this setter is the host's way to seed it once identity resolves, before
|
|
571
|
+
* the first `connect()`.
|
|
572
|
+
*/
|
|
573
|
+
setSyncGroups(syncGroups: readonly string[]): void;
|
|
574
|
+
}
|