@abloatai/ablo 0.34.0 → 0.35.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 +4 -1
- package/CHANGELOG.md +684 -5
- package/README.md +39 -22
- package/dist/BaseSyncedStore.d.ts +152 -44
- package/dist/BaseSyncedStore.js +300 -184
- package/dist/Database.d.ts +9 -24
- package/dist/Database.js +37 -22
- package/dist/InstanceCache.d.ts +25 -4
- package/dist/InstanceCache.js +48 -15
- package/dist/LazyReferenceCollection.d.ts +3 -3
- package/dist/LazyReferenceCollection.js +4 -4
- package/dist/Model.d.ts +6 -6
- package/dist/Model.js +10 -10
- package/dist/ModelRegistry.d.ts +4 -4
- package/dist/ModelRegistry.js +3 -3
- package/dist/{SyncEngineContext.d.ts → RuntimeContext.d.ts} +20 -13
- package/dist/{SyncEngineContext.js → RuntimeContext.js} +11 -12
- package/dist/SyncClient.d.ts +42 -32
- package/dist/SyncClient.js +166 -110
- 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/cli.cjs +3459 -1126
- package/dist/client/Ablo.d.ts +42 -287
- package/dist/client/Ablo.js +118 -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 +4 -4
- package/dist/client/createInternalComponents.js +9 -8
- package/dist/client/createModelProxy.d.ts +78 -373
- package/dist/client/createModelProxy.js +114 -86
- package/dist/client/humans.d.ts +48 -0
- package/dist/client/humans.js +52 -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 +48 -0
- package/dist/client/reactiveEngine.js +910 -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/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 +9 -9
- package/dist/context.js +10 -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/DatabaseManager.js +1 -1
- package/dist/core/QueryView.d.ts +1 -1
- package/dist/core/QueryView.js +1 -1
- package/dist/core/StoreManager.d.ts +4 -23
- package/dist/core/StoreManager.js +5 -55
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/core/storeContract.d.ts +2 -2
- package/dist/docs/catalog.d.ts +72 -0
- package/dist/docs/catalog.js +227 -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 +40 -34
- package/dist/index.js +26 -20
- 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 +2 -2
- package/dist/query/client.js +4 -4
- package/dist/query/types.d.ts +6 -41
- package/dist/query/types.js +2 -2
- package/dist/react/AbloProvider.d.ts +6 -8
- package/dist/react/AbloProvider.js +5 -7
- package/dist/react/context.d.ts +1 -1
- package/dist/react/context.js +1 -1
- package/dist/react/index.d.ts +5 -5
- package/dist/react/index.js +3 -3
- package/dist/react/internalContext.d.ts +1 -1
- package/dist/react/useAblo.d.ts +3 -3
- package/dist/react/useAblo.js +1 -1
- 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 +86 -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 +10 -10
- package/dist/schema/index.js +18 -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 +3 -3
- package/dist/schema/serialize.d.ts +15 -6
- package/dist/schema/serialize.js +17 -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/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/footprint.d.ts +111 -0
- package/dist/source/footprint.js +0 -0
- 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/stores/ObjectStore.d.ts +1 -1
- package/dist/stores/SyncActionStore.d.ts +1 -1
- package/dist/stores/SyncActionStore.js +2 -10
- 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 +123 -6
- package/dist/sync/BootstrapFetcher.js +492 -66
- package/dist/sync/ConnectionManager.d.ts +6 -198
- package/dist/sync/ConnectionManager.js +6 -677
- package/dist/sync/OnDemandLoader.d.ts +2 -2
- package/dist/sync/OnDemandLoader.js +60 -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/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 +1 -1
- package/dist/sync/participants.d.ts +5 -4
- package/dist/sync/participants.js +29 -22
- package/dist/sync/schemaDrift.d.ts +55 -0
- package/dist/sync/schemaDrift.js +53 -0
- package/dist/sync/schemas.d.ts +21 -32
- package/dist/sync/schemas.js +26 -17
- 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/testing/fixtures/bootstrap.d.ts +1 -1
- package/dist/testing/fixtures/deltas.d.ts +1 -1
- package/dist/testing/fixtures/httpResponses.d.ts +70 -0
- package/dist/testing/fixtures/httpResponses.js +90 -0
- package/dist/testing/fixtures/models.js +1 -1
- package/dist/testing/helpers/wait.js +1 -1
- package/dist/testing/mocks/MockMutationExecutor.d.ts +2 -2
- package/dist/testing/mocks/MockMutationExecutor.js +8 -14
- package/dist/testing/mocks/MockSyncContext.d.ts +11 -11
- package/dist/testing/mocks/MockSyncContext.js +10 -9
- package/dist/testing/mocks/MockSyncStore.js +1 -1
- package/dist/testing/mocks/MockWebSocket.d.ts +2 -2
- 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 +177 -0
- package/dist/transaction/auth/capability.js +199 -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 +49 -0
- package/dist/transaction/coordination/awaitClaimGrant.js +112 -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 +44 -0
- package/dist/transaction/coordination/locator.d.ts +83 -0
- package/dist/transaction/coordination/locator.js +82 -0
- package/dist/transaction/coordination/schema.d.ts +1473 -0
- package/dist/{coordination → transaction/coordination}/schema.js +490 -55
- package/dist/transaction/coordination/targetConflict.d.ts +2 -0
- package/dist/transaction/coordination/targetConflict.js +103 -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} +11 -11
- package/dist/{errorCodes.js → transaction/errorCodes.js} +35 -12
- package/dist/{errors.d.ts → transaction/errors.d.ts} +37 -13
- package/dist/{errors.js → transaction/errors.js} +85 -16
- 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 +192 -0
- package/dist/transaction/plugin.js +87 -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 +266 -0
- package/dist/transaction/resources/httpResources.js +7 -0
- package/dist/transaction/resources/modelOperations.d.ts +319 -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 +85 -0
- package/dist/transaction/resources/where.js +70 -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 +5 -5
- package/dist/{schema → transaction/schema}/field.js +5 -5
- 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 +57 -0
- package/dist/transaction/schema/openapi.js +340 -0
- package/dist/{schema → transaction/schema}/relation.d.ts +14 -14
- 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 +12 -10
- package/dist/{schema → transaction/schema}/schema.js +4 -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 +4 -5
- 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} +10 -36
- 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/{client → transaction/transport}/httpClient.d.ts +59 -16
- package/dist/{client → transaction/transport}/httpClient.js +5 -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 +171 -85
- 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 +576 -0
- package/dist/transaction/transport/wsTransport.js +1017 -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 +63 -45
- 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 +351 -0
- package/dist/transaction/wire/accountResponses.js +255 -0
- package/dist/transaction/wire/auth.d.ts +49 -0
- package/dist/transaction/wire/auth.js +57 -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 +463 -0
- package/dist/transaction/wire/claims.js +229 -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 +177 -0
- package/dist/transaction/wire/feedEvent.js +39 -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 +552 -0
- package/dist/transaction/wire/inboundFrames.js +116 -0
- package/dist/transaction/wire/index.d.ts +50 -0
- package/dist/transaction/wire/index.js +74 -0
- package/dist/{wire → transaction/wire}/listEnvelope.d.ts +13 -14
- package/dist/transaction/wire/listEnvelope.js +42 -0
- package/dist/transaction/wire/modelResponses.d.ts +85 -0
- package/dist/transaction/wire/modelResponses.js +43 -0
- package/dist/transactions/{TransactionQueue.d.ts → mutations/MutationQueue.d.ts} +79 -38
- package/dist/transactions/{TransactionQueue.js → mutations/MutationQueue.js} +110 -59
- 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} +16 -15
- package/dist/transactions/{commitPayload.js → mutations/commitPayload.js} +12 -12
- package/dist/transactions/{deltaConfirmation.d.ts → mutations/deltaConfirmation.d.ts} +11 -11
- package/dist/transactions/{deltaConfirmation.js → mutations/deltaConfirmation.js} +7 -7
- 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} +3 -3
- package/dist/transactions/{replayValidation.js → mutations/replayValidation.js} +4 -3
- package/dist/utils/mobxSetup.d.ts +1 -1
- package/dist/utils/mobxSetup.js +5 -2
- 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 +19 -12
- package/docs/api-keys.md +8 -4
- package/docs/api.md +22 -18
- package/docs/audit.md +2 -0
- package/docs/cli.md +31 -3
- package/docs/client-behavior.md +8 -6
- package/docs/concurrency-convention.md +30 -24
- package/docs/coordination.md +48 -38
- package/docs/data-sources.md +3 -1
- package/docs/debugging.md +5 -3
- 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 +45 -44
- package/docs/examples/server-agent.md +46 -26
- package/docs/groups.md +32 -29
- package/docs/guarantees.md +4 -2
- package/docs/how-it-works.md +9 -7
- package/docs/idempotency.md +126 -0
- package/docs/identity.md +58 -54
- package/docs/index.md +172 -84
- package/docs/integration-guide.md +17 -16
- package/docs/interaction-model.md +6 -4
- package/docs/mcp.md +41 -16
- package/docs/migration.md +63 -5
- package/docs/operating-on-your-database.md +111 -0
- package/docs/projects.md +2 -0
- package/docs/quickstart.md +22 -5
- package/docs/react.md +12 -10
- package/docs/schema-contract.md +5 -3
- package/docs/session-settings.md +108 -0
- package/docs/sessions.md +3 -1
- package/docs/webhooks.md +3 -1
- package/llms.txt +47 -17
- package/package.json +10 -8
- 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/client/durableWrites.d.ts +0 -21
- package/dist/coordination/schema.d.ts +0 -722
- package/dist/schema/openapi.d.ts +0 -29
- package/dist/schema/openapi.js +0 -124
- package/dist/transactions/durableWriteStore.js +0 -30
- 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/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/coordination}/claimHeartbeatLoop.d.ts +0 -0
- /package/dist/{client → transaction/coordination}/claimHeartbeatLoop.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/{utils → transaction/utils}/duration.d.ts +0 -0
- /package/dist/{utils → transaction/utils}/duration.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/README.md
CHANGED
|
@@ -66,10 +66,21 @@ claims are visible while the work is still in progress.
|
|
|
66
66
|
[Version History & Migration Guide](./docs/migration.md)
|
|
67
67
|
|
|
68
68
|
It works with the auth and database you already have. **In production, your
|
|
69
|
-
database is the system of record.**
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
database is the system of record.** You write through Ablo, and Ablo writes to
|
|
70
|
+
your Postgres: the call enters Ablo's commit chokepoint — where claims, ordering,
|
|
71
|
+
and idempotency are enforced — and lands in your own tables through a scoped
|
|
72
|
+
writer role. The commit is accepted (`queued`) the moment Ablo takes it; when the
|
|
73
|
+
row surfaces in your write-ahead log, the receipt is promoted to `confirmed`.
|
|
74
|
+
**The WAL echo is how Ablo confirms, not how it writes** — your database, not
|
|
75
|
+
Ablo, is the source of truth for row state, and that same stream is what keeps
|
|
76
|
+
every connected client current, scoped to *sync groups* from your own identity.
|
|
77
|
+
|
|
78
|
+
The writer role is non-superuser and cannot bypass RLS. Before each write Ablo
|
|
79
|
+
sets your tenant context on the connection, so your own row-level security
|
|
80
|
+
policies enforce against Ablo exactly as they do against your app. Ablo runs no
|
|
81
|
+
DDL and owns no schema — your migration tool stays in charge of the shape of your
|
|
82
|
+
database, and Ablo holds only the ordered transaction log and the coordination
|
|
83
|
+
state, never your rows. (Trying Ablo with no database
|
|
73
84
|
yet? A **sandbox** `sk_test` key holds throwaway **test data** — like Stripe test
|
|
74
85
|
mode — so you can explore before pointing it at your Postgres. Test-mode only; in
|
|
75
86
|
production every row lives in your database.)
|
|
@@ -91,7 +102,8 @@ production, your database is the system of record**.
|
|
|
91
102
|
npm install @abloatai/ablo
|
|
92
103
|
npx ablo login # opens the browser: sign in (or sign up) → a sk_test_ key is saved locally
|
|
93
104
|
npx ablo init # scaffolds ablo/schema.ts (offers to log in if you skipped it)
|
|
94
|
-
npx ablo push # pushes your schema (sandbox), writes ABLO_API_KEY to .env.local
|
|
105
|
+
npx ablo push # pushes your schema (sandbox), writes ABLO_API_KEY to .env.local
|
|
106
|
+
npx ablo dev # the same push, watching ablo/schema.ts and re-pushing on save
|
|
95
107
|
```
|
|
96
108
|
|
|
97
109
|
Then point Ablo at the tables for your synced models. Most teams **already
|
|
@@ -124,7 +136,7 @@ instead of guessing:
|
|
|
124
136
|
|
|
125
137
|
## Quick Start
|
|
126
138
|
|
|
127
|
-
One schema, one client, one write path for
|
|
139
|
+
One schema, one client, one write path for agents, servers, and people — this runs as-is
|
|
128
140
|
after `ablo push`:
|
|
129
141
|
|
|
130
142
|
```ts
|
|
@@ -156,7 +168,7 @@ await ablo.weatherReports.update({
|
|
|
156
168
|
claim, // the write completes the claimed work and releases the lease
|
|
157
169
|
});
|
|
158
170
|
|
|
159
|
-
const ready = ablo.weatherReports.
|
|
171
|
+
const ready = ablo.weatherReports.local.retrieve(created.id);
|
|
160
172
|
console.log({ id: ready?.id, status: ready?.status });
|
|
161
173
|
|
|
162
174
|
await ablo.dispose();
|
|
@@ -202,16 +214,15 @@ function persist(client: Sync) { /* ... */ }
|
|
|
202
214
|
|
|
203
215
|
## Reading
|
|
204
216
|
|
|
205
|
-
Two ways to read, depending on whether you can wait. `
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
authoritative answer right now.
|
|
217
|
+
Two ways to read, depending on whether you can wait. `retrieve({ id })` /
|
|
218
|
+
`list({ where })` answer from what's local and go ask the server when they have
|
|
219
|
+
to, so they return a `Promise`. Put `local.` in front and the read is restricted
|
|
220
|
+
to what's already here — instant, reactive in render, and what your UI uses.
|
|
210
221
|
|
|
211
222
|
```ts
|
|
212
|
-
ablo.weatherReports.
|
|
223
|
+
ablo.weatherReports.local.retrieve('report_stockholm');
|
|
213
224
|
|
|
214
|
-
const pending = ablo.weatherReports.
|
|
225
|
+
const pending = ablo.weatherReports.local.list({
|
|
215
226
|
where: { status: 'pending' },
|
|
216
227
|
orderBy: { location: 'asc' },
|
|
217
228
|
limit: 20,
|
|
@@ -373,7 +384,7 @@ function App() {
|
|
|
373
384
|
}
|
|
374
385
|
|
|
375
386
|
function Report({ id }: { id: string }) {
|
|
376
|
-
const report = useAblo((ablo) => ablo.weatherReports.
|
|
387
|
+
const report = useAblo((ablo) => ablo.weatherReports.local.retrieve(id));
|
|
377
388
|
const ablo = useAblo();
|
|
378
389
|
|
|
379
390
|
if (!report) return null;
|
|
@@ -392,7 +403,7 @@ method as the server example above.
|
|
|
392
403
|
|
|
393
404
|
`<AbloProvider>` owns the connection — no API key in the browser. That's the
|
|
394
405
|
whole loop: read with `useAblo(selector)`, write with `ablo.<model>`, and every
|
|
395
|
-
other client (
|
|
406
|
+
other client (agent or human) on that row sees it in real time. See
|
|
396
407
|
[React](./docs/react.md) for the `<AbloProvider>` prop surface (`client`,
|
|
397
408
|
`userId`, `fallback`, `onError`) — schema, scope, and team membership live on the
|
|
398
409
|
`Ablo({ … })` client you pass it — plus status hooks.
|
|
@@ -402,7 +413,7 @@ other client (human or agent) on that row sees it in real time. See
|
|
|
402
413
|
Ablo is **not** an auth provider — you keep your own (Clerk, Auth0, NextAuth,
|
|
403
414
|
whatever). Ablo's job starts after you've authenticated a request: you tell it
|
|
404
415
|
*who* is connecting, and it scopes their realtime data to the right **sync
|
|
405
|
-
groups** (named channels like `org:acme` or `
|
|
416
|
+
groups** (named channels like `org:acme` or `workspace:abc123` that are both the unit
|
|
406
417
|
of fan-out and the unit of access).
|
|
407
418
|
|
|
408
419
|
The model is a proxy: your `ABLO_API_KEY` stays on your trusted server, your
|
|
@@ -434,19 +445,25 @@ browser.
|
|
|
434
445
|
|
|
435
446
|
## Multiplayer
|
|
436
447
|
|
|
437
|
-
There is no separate multiplayer mode. When
|
|
438
|
-
|
|
448
|
+
There is no separate multiplayer mode. When agent workers, server actions, and
|
|
449
|
+
human UI share the same schema and write through `ablo.<model>`, they all see
|
|
439
450
|
each other's changes in real time — that's the default, not a feature you turn on.
|
|
440
451
|
|
|
441
452
|
- `ablo.<model>.create/update/delete` fan out confirmed deltas to subscribers.
|
|
442
453
|
- `useAblo(...)` gives React clients the live row, kept current automatically.
|
|
443
|
-
- `ablo.<model>.claim({ id })` / `claim.state({ id })` / `claim.queue({ id })` let
|
|
454
|
+
- `ablo.<model>.claim({ id })` / `claim.state({ id })` / `claim.queue({ id })` let agents and people coordinate (and observe) active work on a row — and the line waiting behind it — before a write lands.
|
|
455
|
+
|
|
456
|
+
The bare client is the coordination layer: commit, read, observe, claim. The live
|
|
457
|
+
plane people watch — presence, live queries, the local copy — is the `humans()`
|
|
458
|
+
plugin on top of it, installed by default on a socket client. There is no
|
|
459
|
+
`agents()` plugin, and the absence is the point: an agent is the default caller
|
|
460
|
+
here, not a special one.
|
|
444
461
|
|
|
445
462
|
Writes go through Ablo. `ablo.<model>.create/update/delete` and the HTTP write
|
|
446
463
|
endpoint enter Ablo's commit chokepoint — where claims, ordering, and idempotency
|
|
447
464
|
are enforced — and Ablo lands the change in your database. It then tails the WAL to
|
|
448
465
|
confirm the row landed and fans the confirmed change out to every connected client.
|
|
449
|
-
One surface for
|
|
466
|
+
One surface for agents, servers, and people; one place coordination happens.
|
|
450
467
|
|
|
451
468
|
## HTTP Writes
|
|
452
469
|
|
|
@@ -477,7 +494,7 @@ connects:
|
|
|
477
494
|
|
|
478
495
|
| | How Ablo connects to your Postgres | Use when |
|
|
479
496
|
| --- | --- | --- |
|
|
480
|
-
| **`ablo connect`** (primary) | Sets up logical replication and a scoped writer role (`npx ablo connect apply` does it end to end). Ablo writes your rows through the writer role and reads them back over the WAL to confirm — it writes rows but runs no DDL and owns no schema. | Your database can grant a `REPLICATION` role (most can). |
|
|
497
|
+
| **`ablo connect`** (primary) | Sets up logical replication and a scoped writer role (`npx ablo connect apply` does it end to end). Ablo writes your rows through the writer role and reads them back over the WAL to confirm — it writes rows but runs no DDL and owns no schema. The role is non-superuser and cannot bypass RLS, so your own policies govern Ablo's writes. | Your database can grant a `REPLICATION` role (most can). |
|
|
481
498
|
| **Signed endpoint** (fallback) | Your app exposes one route built from an ORM adapter (`prismaDataSource` / `drizzleDataSource`); Ablo writes and confirms through it. Needs no replication setup. | Your database **can't** grant a replication role (a locked-down managed DB). |
|
|
482
499
|
|
|
483
500
|
Your database is the system of record. See
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* queue, {@link Database} owns local persistence, {@link InstanceCache} holds the
|
|
11
11
|
* in-memory models, and {@link ModelRegistry} holds their metadata.
|
|
12
12
|
*/
|
|
13
|
-
import type { RecoveryClass } from './errorCodes.js';
|
|
13
|
+
import type { RecoveryClass } from './transaction/errorCodes.js';
|
|
14
14
|
import { ConnectionManager } from './sync/ConnectionManager.js';
|
|
15
15
|
import { SubscriptionManager } from './sync/SubscriptionManager.js';
|
|
16
16
|
import { type ParticipantScope } from './sync/participants.js';
|
|
@@ -18,22 +18,23 @@ import type { SyncClient } from './SyncClient.js';
|
|
|
18
18
|
import type { Database, BootstrapResult } from './Database.js';
|
|
19
19
|
import type { InstanceCache } from './InstanceCache.js';
|
|
20
20
|
import { ModelRegistry } from './ModelRegistry.js';
|
|
21
|
-
import { SyncWebSocket, type SyncDelta, type SyncGroupChangePayload, type GroupAddedPayload, type GroupRemovedPayload, type BootstrapHint, type BootstrapDataEvent, type
|
|
21
|
+
import { SyncWebSocket, type SyncDelta, type SyncGroupChangePayload, type GroupAddedPayload, type GroupRemovedPayload, type BootstrapHint, type BootstrapDataEvent, type PresenceUpdate, type EventMap, type DefaultCollaborationEvents, type SyncWebSocketEventMap } from './sync/SyncWebSocket.js';
|
|
22
22
|
import { QueryProcessor } from './core/QueryProcessor.js';
|
|
23
23
|
import { Model } from './Model.js';
|
|
24
24
|
import { ModelScope } from './InstanceCache.js';
|
|
25
|
-
import type { Schema } from './schema/schema.js';
|
|
25
|
+
import type { Schema } from './transaction/schema/schema.js';
|
|
26
26
|
import type { SyncStatus, LocalMutation } from './core/storeContract.js';
|
|
27
|
-
import type { AuthCredentialSource } from './auth/credentialSource.js';
|
|
28
|
-
import type { ModelData } from './types/modelData.js';
|
|
27
|
+
import type { AuthCredentialSource } from './transaction/auth/credentialSource.js';
|
|
28
|
+
import type { ModelData } from './transaction/types/modelData.js';
|
|
29
29
|
import type { EnrichmentPlanEntry, ForeignKeyIndexSpec } from './sync/syncPlan.js';
|
|
30
30
|
import { type CredentialRefresher } from './sync/credentialLifecycle.js';
|
|
31
31
|
import type { RehydrationStats } from './sync/bootstrapApply.js';
|
|
32
|
+
import type { ParticipantKind } from './transaction/types/participant.js';
|
|
32
33
|
/** Constructor type for Model subclasses (accepts abstract classes) */
|
|
33
34
|
export type ModelConstructor<T extends Model> = abstract new (...args: never[]) => T;
|
|
34
35
|
/** Concrete constructor type for instantiation */
|
|
35
36
|
export type ConcreteModelConstructor<T extends Model> = new (data?: any) => T;
|
|
36
|
-
export type { ModelData } from './types/modelData.js';
|
|
37
|
+
export type { ModelData } from './transaction/types/modelData.js';
|
|
37
38
|
/** Query result interface */
|
|
38
39
|
export interface QueryResult<T extends Model> {
|
|
39
40
|
data: T[];
|
|
@@ -47,6 +48,16 @@ export interface SyncedStoreConfig {
|
|
|
47
48
|
enableOffline?: boolean;
|
|
48
49
|
enableCache?: boolean;
|
|
49
50
|
enableTelemetry?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Wire message types to surface as collaboration events, e.g.
|
|
53
|
+
* `['document:selection', 'document:cursor']`.
|
|
54
|
+
*
|
|
55
|
+
* The vocabulary belongs to the application, not the SDK — these name the
|
|
56
|
+
* application's own concepts, and a schema with no documents should never see
|
|
57
|
+
* them. Defaults to none, so an application opts in by naming the events it
|
|
58
|
+
* actually broadcasts.
|
|
59
|
+
*/
|
|
60
|
+
collaborationEvents?: readonly string[];
|
|
50
61
|
/**
|
|
51
62
|
* Declarative enrichment plan consumed by `enrichRelations`. Replaces
|
|
52
63
|
* the subclass override of `enrichRelations` for per-model parent
|
|
@@ -75,7 +86,7 @@ export interface UserContext {
|
|
|
75
86
|
* sessions; 'agent' for headless bots / worker processes. The
|
|
76
87
|
* store routes this to SyncWebSocket so the WS URL carries
|
|
77
88
|
* `kind=agent` and the server applies capability-token auth. */
|
|
78
|
-
kind?:
|
|
89
|
+
kind?: ParticipantKind;
|
|
79
90
|
/** Restricted (`rk_`) API key for `kind: 'agent'` — the agent's
|
|
80
91
|
* bearer credential. Sent in the `ablo.bearer.<token>` WebSocket
|
|
81
92
|
* subprotocol, never in the URL. */
|
|
@@ -107,14 +118,20 @@ export interface SmartSyncOptions {
|
|
|
107
118
|
maxBatchSize?: number;
|
|
108
119
|
}
|
|
109
120
|
export type { RehydrationStats } from './sync/bootstrapApply.js';
|
|
110
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* Bootstrap retry configuration.
|
|
123
|
+
*
|
|
124
|
+
* There is deliberately no overall timeout here. How long one attempt may run
|
|
125
|
+
* is not a policy this layer gets to invent — it is a property of the fetcher's
|
|
126
|
+
* watchdogs, read from `BootstrapFetcher.budgetMs`. A second number kept here
|
|
127
|
+
* would only be able to disagree with them, which is exactly what it used to do.
|
|
128
|
+
*/
|
|
111
129
|
export declare const BOOTSTRAP_CONFIG: {
|
|
112
|
-
readonly OVERALL_TIMEOUT_MS: 15000;
|
|
113
130
|
readonly MAX_RETRY_ATTEMPTS: 3;
|
|
114
131
|
readonly RETRY_DELAY_MS: 500;
|
|
115
132
|
};
|
|
116
133
|
export { ModelScope };
|
|
117
|
-
export type { SyncDelta, SyncGroupChangePayload, GroupAddedPayload, GroupRemovedPayload, BootstrapHint, BootstrapDataEvent,
|
|
134
|
+
export type { SyncDelta, SyncGroupChangePayload, GroupAddedPayload, GroupRemovedPayload, BootstrapHint, BootstrapDataEvent, PresenceUpdate, };
|
|
118
135
|
export { deriveSyncPlanFromSchema } from './sync/syncPlan.js';
|
|
119
136
|
/**
|
|
120
137
|
* The abstract base class that application-specific sync stores extend. It
|
|
@@ -133,13 +150,13 @@ export { deriveSyncPlanFromSchema } from './sync/syncPlan.js';
|
|
|
133
150
|
* the underlying SyncWebSocket without casts:
|
|
134
151
|
*
|
|
135
152
|
* @example
|
|
136
|
-
* interface
|
|
137
|
-
* '
|
|
138
|
-
* '
|
|
153
|
+
* interface EditorEvents {
|
|
154
|
+
* 'document:selection': [SelectionEvent];
|
|
155
|
+
* 'document:cursor': [CursorEvent];
|
|
139
156
|
* }
|
|
140
|
-
* class
|
|
141
|
-
*
|
|
142
|
-
* return this.syncWebSocket
|
|
157
|
+
* class EditorStore extends BaseSyncedStore<EditorEvents> {
|
|
158
|
+
* subscribeToCursor(handler: (e: CursorEvent) => void) {
|
|
159
|
+
* return this.syncWebSocket.subscribe('document:cursor', handler);
|
|
143
160
|
* }
|
|
144
161
|
* }
|
|
145
162
|
*/
|
|
@@ -155,15 +172,20 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
155
172
|
* `create(key, data)` factory and model self-healing.
|
|
156
173
|
*/
|
|
157
174
|
protected readonly schema?: TSchema;
|
|
158
|
-
|
|
175
|
+
/**
|
|
176
|
+
* The connection, owned by whoever built this store (ADR 0016 follow-up
|
|
177
|
+
* 3b): the host constructs it and hands it in, the store seeds its late
|
|
178
|
+
* values during `initialize()` and owns the lifecycle from there. One
|
|
179
|
+
* instance for the store's whole lifetime — reconnects replace the socket
|
|
180
|
+
* inside it, never the object.
|
|
181
|
+
*/
|
|
182
|
+
protected readonly syncWebSocket: SyncWebSocket<TCollaboration>;
|
|
159
183
|
/**
|
|
160
184
|
* Dynamic read interest (area-of-interest) over the connection's sync
|
|
161
|
-
* groups.
|
|
162
|
-
*
|
|
163
|
-
* to whichever instance is current, so callers (the React participant
|
|
164
|
-
* hook) never hold a stale reference. Null until `setupWebSocketSync`.
|
|
185
|
+
* groups. Constructed with the connection; the permanent base scopes are
|
|
186
|
+
* seeded in `setupWebSocketSync` once identity resolves.
|
|
165
187
|
*/
|
|
166
|
-
protected areaOfInterest: SubscriptionManager
|
|
188
|
+
protected readonly areaOfInterest: SubscriptionManager;
|
|
167
189
|
/** Sync groups whose current state has been backfilled into the pool
|
|
168
190
|
* (hydrate-on-enter). Cleared when the pool is reset on (re)bootstrap. */
|
|
169
191
|
private readonly hydratedGroups;
|
|
@@ -171,15 +193,32 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
171
193
|
* enters of the same scope so they share one fetch. */
|
|
172
194
|
private readonly hydratingGroups;
|
|
173
195
|
private _syncServerUrl?;
|
|
196
|
+
/** Application-declared collaboration event types; empty unless configured. */
|
|
197
|
+
private _collaborationEvents;
|
|
174
198
|
/**
|
|
175
199
|
* Public accessor for the underlying SyncWebSocket. Used by the
|
|
176
200
|
* factory in `createSyncEngine` to wire the default mutation
|
|
177
201
|
* executor — the executor needs the WS handle to send commit
|
|
178
202
|
* frames, and the factory can't reach `protected` state through
|
|
179
|
-
* normal typing.
|
|
180
|
-
|
|
203
|
+
* normal typing.
|
|
204
|
+
*/
|
|
205
|
+
getSyncWebSocket(): SyncWebSocket<TCollaboration>;
|
|
206
|
+
/**
|
|
207
|
+
* Subscribe to pushed frames — deltas, presence updates, claim grants and
|
|
208
|
+
* losses, connection changes, and this store's collaboration events.
|
|
209
|
+
* Durable by construction: the connection object exists for the store's
|
|
210
|
+
* whole lifetime (reconnects replace only the socket inside it), so a
|
|
211
|
+
* subscription made before the first connect starts delivering when the
|
|
212
|
+
* socket opens and keeps delivering across every reconnect. Returns the
|
|
213
|
+
* unsubscribe function.
|
|
181
214
|
*/
|
|
182
|
-
|
|
215
|
+
subscribe<K extends keyof SyncWebSocketEventMap<TCollaboration>>(event: K, handler: (...args: SyncWebSocketEventMap<TCollaboration>[K]) => void): () => void;
|
|
216
|
+
/**
|
|
217
|
+
* Send a collaboration event (an app-specific real-time message from this
|
|
218
|
+
* store's `TCollaboration` map). A no-op while the connection is down —
|
|
219
|
+
* presence-grade traffic is not queued.
|
|
220
|
+
*/
|
|
221
|
+
sendCollaborationEvent<K extends string & keyof TCollaboration>(messageType: K, payload: TCollaboration[K] extends [infer P] ? Omit<P & Record<string, unknown>, 'timestamp'> : never): void;
|
|
183
222
|
private scopeToGroups;
|
|
184
223
|
/**
|
|
185
224
|
* Bring a scope into view and subscribe to its sync groups. With
|
|
@@ -230,13 +269,15 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
230
269
|
protected pendingDeltas: SyncDelta[];
|
|
231
270
|
protected batchTimer: ReturnType<typeof setTimeout> | null;
|
|
232
271
|
protected syncPromise: Promise<void> | null;
|
|
233
|
-
/** Resume/ack cursor — delegates to the shared
|
|
234
|
-
*
|
|
272
|
+
/** Resume/ack cursor — delegates to the shared LogPosition (see
|
|
273
|
+
* logPosition.ts). Advances only after IDB persistence. */
|
|
235
274
|
protected get lastAckedId(): number;
|
|
236
|
-
/** Pool-applied cursor — delegates to the shared
|
|
275
|
+
/** Pool-applied cursor — delegates to the shared LogPosition. */
|
|
237
276
|
protected get highestProcessedSyncId(): number;
|
|
238
277
|
protected bootstrapDeltaQueue: SyncDelta[] | null;
|
|
239
278
|
protected activeBootstrapCount: number;
|
|
279
|
+
/** The live deadline for the bootstrap attempt in flight, if any. */
|
|
280
|
+
private bootstrapDeadlineTimer;
|
|
240
281
|
protected pendingDeletes: Set<string>;
|
|
241
282
|
protected modelTypesHydrated: Set<string>;
|
|
242
283
|
protected modelTypeHydrationInFlight: Map<string, Promise<void>>;
|
|
@@ -245,6 +286,15 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
245
286
|
database: Database;
|
|
246
287
|
objectPool: InstanceCache;
|
|
247
288
|
modelRegistry: ModelRegistry;
|
|
289
|
+
/**
|
|
290
|
+
* The connection, built by the host. When omitted, the store constructs
|
|
291
|
+
* its own from `url` and the collaboration-event config — the
|
|
292
|
+
* self-contained path subclasses and tests use. Either way the store
|
|
293
|
+
* owns the lifecycle from here: it seeds the late values (identity,
|
|
294
|
+
* read scope, resume cursor) during `initialize()` and releases the
|
|
295
|
+
* first connect.
|
|
296
|
+
*/
|
|
297
|
+
syncWebSocket?: SyncWebSocket<TCollaboration>;
|
|
248
298
|
/**
|
|
249
299
|
* Optional schema. When provided, {@link deriveSyncPlanFromSchema} walks
|
|
250
300
|
* the schema's models and relations to auto-populate foreign-key indexes
|
|
@@ -331,7 +381,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
331
381
|
subscribeSessionError(listener: (error: Error) => void): () => void;
|
|
332
382
|
/**
|
|
333
383
|
* Subscribe to per-mutation failure payloads. Forwarded from the
|
|
334
|
-
* underlying `SyncClient.
|
|
384
|
+
* underlying `SyncClient.mutationQueue` so consumers (toast layer,
|
|
335
385
|
* route-level reverted boundaries, telemetry) can react without
|
|
336
386
|
* reaching across the store. Returns an unsubscribe function.
|
|
337
387
|
*
|
|
@@ -342,10 +392,17 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
342
392
|
* same shape, same lifecycle.
|
|
343
393
|
*/
|
|
344
394
|
subscribeMutationFailure(listener: (payload: {
|
|
345
|
-
transaction: import('./transactions/
|
|
395
|
+
transaction: import('./transactions/mutations/MutationQueue.js').QueuedMutation;
|
|
346
396
|
error: Error;
|
|
347
397
|
permanent?: boolean;
|
|
348
398
|
}) => void): () => void;
|
|
399
|
+
/**
|
|
400
|
+
* Subscribe to commit round-trip latency. Forwarded from the underlying
|
|
401
|
+
* `SyncClient` for the same reason as `subscribeMutationFailure` — the
|
|
402
|
+
* React provider binds against this surface, so the engine's wiring stays
|
|
403
|
+
* private while the SDK keeps one hook to expose.
|
|
404
|
+
*/
|
|
405
|
+
subscribeCommitLatency(listener: (sample: import('./transactions/mutations/commitLatency.js').CommitLatencySample) => void): () => void;
|
|
349
406
|
/**
|
|
350
407
|
* Wait for the in-flight transaction for (modelName, modelId) to be
|
|
351
408
|
* confirmed by the server. See `SyncClient.waitForConfirmation` for the
|
|
@@ -355,7 +412,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
355
412
|
/**
|
|
356
413
|
* Observe the LOCAL mutation stream for undo recording (see
|
|
357
414
|
* {@link import('./core/storeContract.js').LocalMutation}). Taps the
|
|
358
|
-
*
|
|
415
|
+
* MutationQueue's `transaction:created` event — fired once per local
|
|
359
416
|
* create/update/delete/archive with `previousData` already captured.
|
|
360
417
|
* Remote/collaborator deltas apply via `applyDeltaBatchToPool` and never
|
|
361
418
|
* emit here, so undo is naturally local-only (you can't undo a teammate).
|
|
@@ -366,8 +423,29 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
366
423
|
* Prevents the common issue where bootstrap hangs on startup.
|
|
367
424
|
*/
|
|
368
425
|
protected executeBootstrapWithTimeout<T>(bootstrapFn: () => Promise<T>, _context: UserContext, signal?: AbortSignal): Promise<T>;
|
|
369
|
-
/**
|
|
426
|
+
/**
|
|
427
|
+
* The outer deadline for one bootstrap attempt.
|
|
428
|
+
*
|
|
429
|
+
* The length is DERIVED from the fetcher's own watchdog budget, not chosen. A
|
|
430
|
+
* chosen number is what broke this: the previous fixed 15s was shorter than a
|
|
431
|
+
* single model chunk's allowance — 20s waiting for response headers plus 15s
|
|
432
|
+
* of stall grace — so on any workspace with one slow model the deadline fired
|
|
433
|
+
* before the watchdogs it was meant to backstop, and every attempt timed out
|
|
434
|
+
* by construction. The watchdogs below are progress-based and already
|
|
435
|
+
* guarantee termination; this deadline exists only for a hang somewhere other
|
|
436
|
+
* than the network, so it must sit above them, and it can only do that
|
|
437
|
+
* reliably by asking them how long they take.
|
|
438
|
+
*
|
|
439
|
+
* Reaching it aborts the work in flight. `Promise.race` merely stops waiting:
|
|
440
|
+
* without the abort the losing bootstrap keeps running, keeps its sockets, and
|
|
441
|
+
* races the retry that replaced it — which is how one page load turned into
|
|
442
|
+
* dozens of overlapping requests.
|
|
443
|
+
*/
|
|
370
444
|
protected createBootstrapTimeout(attempt: number): Promise<never>;
|
|
445
|
+
/** Disarm the deadline once its attempt has settled. Load-bearing now that
|
|
446
|
+
* firing it aborts real work: a leftover timer would cancel a later,
|
|
447
|
+
* unrelated bootstrap. */
|
|
448
|
+
private clearBootstrapDeadline;
|
|
371
449
|
/** Reset bootstrap-related state for a clean retry */
|
|
372
450
|
protected resetBootstrapState(): void;
|
|
373
451
|
/** Perform reconnect: bootstrap + WS reconnect. Returns outcome for state machine. */
|
|
@@ -495,8 +573,15 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
495
573
|
* driven session" vs "is this a server agent". The latter never has
|
|
496
574
|
* a tab to lose focus or a network adapter to wake up.
|
|
497
575
|
*/
|
|
498
|
-
protected createConnectionManager(kind?:
|
|
499
|
-
/**
|
|
576
|
+
protected createConnectionManager(kind?: ParticipantKind): ConnectionManager | null;
|
|
577
|
+
/**
|
|
578
|
+
* Disconnect and clean up all resources. Terminal: this means "the client
|
|
579
|
+
* is finished", not "close and reopen later" — the connection object stays
|
|
580
|
+
* assigned but closed, the event wiring is torn down, and nothing
|
|
581
|
+
* re-initializes a disconnected store. (Mid-session closes during recovery
|
|
582
|
+
* go through the connection FSM's `onDisconnectWebSocket`, which closes
|
|
583
|
+
* the transport without touching the store.)
|
|
584
|
+
*/
|
|
500
585
|
disconnect(): Promise<void>;
|
|
501
586
|
/**
|
|
502
587
|
* Destroy every IndexedDB database owned by the sync engine.
|
|
@@ -535,7 +620,30 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
535
620
|
* mutation attempt surface a clearer error.
|
|
536
621
|
*/
|
|
537
622
|
protected waitForWebSocketConnected(timeoutMs: number): Promise<boolean>;
|
|
623
|
+
/**
|
|
624
|
+
* Seed the connection's late values and open it. The socket itself exists
|
|
625
|
+
* from construction; what identity resolution supplies — the participant
|
|
626
|
+
* kind, the credential, the read scope, and the resume cursor — is seeded
|
|
627
|
+
* here, and only then is the held first connect released. A retried
|
|
628
|
+
* `initialize()` after a failed `ready()` re-runs this against the same
|
|
629
|
+
* connection object: the reconnect counter is reset for a clean slate,
|
|
630
|
+
* while the session-error latch deliberately survives (only the
|
|
631
|
+
* credential-expiry recovery clears it).
|
|
632
|
+
*/
|
|
538
633
|
protected setupWebSocketSync(context: UserContext, lastSyncId: number): void;
|
|
634
|
+
/**
|
|
635
|
+
* Wire the store's handlers onto the connection. Runs once, at
|
|
636
|
+
* construction — the connection object is stable for the store's
|
|
637
|
+
* lifetime, so the wiring is too.
|
|
638
|
+
*/
|
|
639
|
+
protected wireSocketEvents(): void;
|
|
640
|
+
/**
|
|
641
|
+
* Build and start the connection FSM. The `onConnectionEvent` hook is the
|
|
642
|
+
* bridge — WS events fire the hook, the hook forwards into the FSM. Called
|
|
643
|
+
* from `setupWebSocketSync` because the FSM's shape depends on the resolved
|
|
644
|
+
* participant kind (agents get none — see {@link createConnectionManager}).
|
|
645
|
+
*/
|
|
646
|
+
private startConnectionManager;
|
|
539
647
|
/** Memoized pipeline context — `enqueueDelta` runs once per delta, so the
|
|
540
648
|
* accessor object is built once and reused (the get/set accessors always
|
|
541
649
|
* read the live host fields). */
|
|
@@ -590,7 +698,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
590
698
|
* schema build time) to find children. The previous implementation did
|
|
591
699
|
* `getByType(ctor).filter(e => e.toJSON()[foreignKey] === parentId)` —
|
|
592
700
|
* a full pool scan per child model + a `toJSON()` allocation per
|
|
593
|
-
* candidate. For a
|
|
701
|
+
* candidate. For a report delete with 10K blocks in the pool, that was
|
|
594
702
|
* 10K toJSON allocations per cascade level. The FK-indexed lookup
|
|
595
703
|
* skips both the scan AND the allocation.
|
|
596
704
|
*/
|
|
@@ -605,7 +713,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
605
713
|
* Save a model (create or update).
|
|
606
714
|
*
|
|
607
715
|
* Accepts any entity shape with `{ id: string }` so consumers can pass the
|
|
608
|
-
* Zod-inferred model types from `
|
|
716
|
+
* Zod-inferred model types from `Model<Schema, K>` without knowing
|
|
609
717
|
* about the internal `Model` base class. At runtime, every entity reaching
|
|
610
718
|
* this method came through the object pool (via `store.create`, a query
|
|
611
719
|
* accessor, or an optimistic insert) and IS a `Model` instance — the one
|
|
@@ -618,7 +726,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
618
726
|
}>(entity: T, options?: {
|
|
619
727
|
skipValidation?: boolean;
|
|
620
728
|
}): Promise<void>;
|
|
621
|
-
/** Save with an atomic server mutation (e.g.,
|
|
729
|
+
/** Save with an atomic server mutation (e.g., createSectionWithBlocks) */
|
|
622
730
|
saveWithAtomicMutation(model: Model, mutation: (gql: unknown) => Promise<unknown>): Promise<void>;
|
|
623
731
|
/** Delete a model. Accepts schema-inferred entity shapes (see `save`). */
|
|
624
732
|
delete<T extends {
|
|
@@ -648,17 +756,17 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
648
756
|
* Create a model instance locally, typed via the schema.
|
|
649
757
|
*
|
|
650
758
|
* ```ts
|
|
651
|
-
* const
|
|
652
|
-
* //
|
|
759
|
+
* const ledger = store.create('ledgers', { name, reportId });
|
|
760
|
+
* // ledger: Ledger | null — no cast needed
|
|
653
761
|
* ```
|
|
654
762
|
*
|
|
655
763
|
* The `typename` arg is the schema key (camelCase plural, e.g.
|
|
656
|
-
* `'
|
|
657
|
-
* `
|
|
764
|
+
* `'ledgers'`); the returned instance has the
|
|
765
|
+
* `Model<Schema, K>` shape including computeds + relation accessors.
|
|
658
766
|
* Wraps `pool.create(...)` — the underlying runtime is unchanged, just
|
|
659
767
|
* type-narrowed.
|
|
660
768
|
*/
|
|
661
|
-
create<K extends keyof TSchema['models'] & string>(typename: K, data: Record<string, unknown>): import('./schema/schema.js').
|
|
769
|
+
create<K extends keyof TSchema['models'] & string>(typename: K, data: Record<string, unknown>): import('./transaction/schema/schema.js').Model<TSchema, K> | null;
|
|
662
770
|
/**
|
|
663
771
|
* Query entry point for callers that hold a {@link Model} constructor and an
|
|
664
772
|
* options object. It filters, orders, and paginates the matching models from
|
|
@@ -676,7 +784,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
676
784
|
/**
|
|
677
785
|
* Get all models of a type. Returns Model[] honestly — callers that need
|
|
678
786
|
* narrow types should use `useAblo((ablo) => ablo.<model>.list(...))`
|
|
679
|
-
* which does proper inference via `
|
|
787
|
+
* which does proper inference via `Model<S, K>`.
|
|
680
788
|
*/
|
|
681
789
|
allModelsOfType(modelClass: ModelConstructor<Model>, scope?: ModelScope): Model[];
|
|
682
790
|
/** Error handler for fire-and-forget flushPendingDeltas calls */
|
|
@@ -688,7 +796,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
|
|
|
688
796
|
/** Handle bootstrap_data event. Override in subclass. */
|
|
689
797
|
protected handleBootstrapData(_data: BootstrapDataEvent): void;
|
|
690
798
|
/** Handle presence_update event. Override in subclass. */
|
|
691
|
-
protected handlePresenceUpdate(_data:
|
|
799
|
+
protected handlePresenceUpdate(_data: PresenceUpdate): void;
|
|
692
800
|
protected incrementPendingChanges(): void;
|
|
693
801
|
protected decrementPendingChanges(): void;
|
|
694
802
|
protected updateSyncStatus(updates: Partial<SyncStatus>): void;
|