@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
package/docs/api.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# API
|
|
2
2
|
|
|
3
|
+
> The per-method reference for every model call an agent or an interface can make.
|
|
4
|
+
|
|
3
5
|
> **Upgrading?** Every breaking change and its migration is on the
|
|
4
6
|
> [Version History & Migration Guide](./migration.md).
|
|
5
7
|
|
|
@@ -11,10 +13,12 @@ row, you can optionally `claim` it so they serialize instead of clobbering
|
|
|
11
13
|
each other.
|
|
12
14
|
|
|
13
15
|
Two things to know before the method list. **Reads come in two flavors:**
|
|
14
|
-
`retrieve({ id })` / `list({ where })` are async
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
`retrieve({ id })` / `list({ where })` are async — they answer from what is
|
|
17
|
+
already local and fall back to the server. Put `local.` in front of either and
|
|
18
|
+
you get the same read restricted to what is already here, which is why it can
|
|
19
|
+
return a value rather than a promise: `local.retrieve(id)`, `local.list({ where })`,
|
|
20
|
+
`local.count({ where })`. Use those in render, after data has synced.
|
|
21
|
+
**Claims don't lock.** If another writer holds the row, `claim` waits
|
|
18
22
|
for them, re-reads the fresh row, then hands it to you — so two writers
|
|
19
23
|
serialize instead of clobbering.
|
|
20
24
|
|
|
@@ -49,31 +53,31 @@ Each schema model becomes a typed model on the client:
|
|
|
49
53
|
|
|
50
54
|
- `ablo.weatherReports.retrieve({ id })` reads one row asynchronously (server read).
|
|
51
55
|
- `ablo.weatherReports.list({ where })` reads a collection asynchronously (server read).
|
|
52
|
-
- `ablo.weatherReports.
|
|
56
|
+
- `ablo.weatherReports.local.retrieve(id)` reads one row synchronously from the local graph.
|
|
53
57
|
- `ablo.weatherReports.create({ data })` creates a row.
|
|
54
58
|
- `ablo.weatherReports.update({ id, data, ...options })` updates a row.
|
|
55
59
|
- `ablo.weatherReports.delete({ id, ...options })` deletes a row.
|
|
56
60
|
|
|
57
|
-
`
|
|
58
|
-
`
|
|
59
|
-
|
|
60
|
-
`
|
|
61
|
-
|
|
61
|
+
`local.` narrows a read to what has already synced. `retrieve({ id })` and
|
|
62
|
+
`list({ where })` answer from the local graph and fall back to IndexedDB and
|
|
63
|
+
then the network, so reach for them when the row may not be here yet.
|
|
64
|
+
`local.retrieve(id)` and `local.list({ where })` are the same reads with the
|
|
65
|
+
fallback removed — nothing to await, so they return a value.
|
|
62
66
|
|
|
63
67
|
| Method | Returns | Use when |
|
|
64
68
|
|---|---|---|
|
|
65
69
|
| `retrieve({ id })` | `Promise<T \| undefined>` | You need one row, hydrating from local store and server. |
|
|
66
70
|
| `list({ where })` | `Promise<T[]>` | You need to hydrate a collection from local store and server. |
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
71
|
+
| `local.retrieve(id)` | `T \| undefined` | You want a synchronous snapshot of one local row. |
|
|
72
|
+
| `local.list(options?)` | `T[]` | You want a synchronous snapshot of a local collection. |
|
|
73
|
+
| `local.count(options?)` | `number` | You want a synchronous count of local rows. |
|
|
70
74
|
| `create({ data, ...options })` | `Promise<T>` | You want to create through the schema model. |
|
|
71
75
|
| `update({ id, data, ...options })` | `Promise<T>` | You want to update through the schema model. |
|
|
72
76
|
| `delete({ id, ...options })` | `Promise<void>` | You want to delete through the schema model. |
|
|
73
77
|
|
|
74
78
|
`retrieve`, `list`, `create`, `update`, and `delete` are the main path — they go
|
|
75
|
-
through the server. `
|
|
76
|
-
|
|
79
|
+
through the server. The `local` reads work off the rows a session has already
|
|
80
|
+
synced, so a cheap re-read needs no round-trip.
|
|
77
81
|
|
|
78
82
|
## Protected Writes
|
|
79
83
|
|
|
@@ -103,7 +107,7 @@ Protected write options:
|
|
|
103
107
|
|
|
104
108
|
## Claims
|
|
105
109
|
|
|
106
|
-
Before anyone writes a row, they can claim it so other
|
|
110
|
+
Before anyone writes a row, they can claim it so other agents and people see
|
|
107
111
|
who is editing it in real time. Claims don't lock. If another writer holds the
|
|
108
112
|
row, `claim` waits for them, re-reads the fresh row, then hands it to you — so
|
|
109
113
|
two writers serialize instead of clobbering. A claim is temporary: it expires
|
|
@@ -116,49 +120,11 @@ blocks), and `ablo.<model>.claim.release({ id })` releases it early. The full
|
|
|
116
120
|
coordination surface is `claim.state({ id })` / `claim.queue({ id })` /
|
|
117
121
|
`claim.release({ id })` / `claim.reorder({ id, order })` hanging off `claim`.
|
|
118
122
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
| `id` | string | Unique identifier for the claim. |
|
|
125
|
-
| `status` | `'active' \| 'queued' \| 'committed' \| 'expired' \| 'canceled'` | The whole lifecycle, in one field. `active` is the holder; `queued` is a waiter in the FIFO line behind it. |
|
|
126
|
-
| `target` | `{ type, id, field? }` | What is being coordinated. |
|
|
127
|
-
| `description` | string | Peer-visible phrase for the work in progress — `'editing'`, `'writing'`, `'reviewing the risk section'`. Defaults to `'editing'`, and rides back in the rejection a blocked writer receives. |
|
|
128
|
-
| `heldBy` | string | Participant id holding the claim. |
|
|
129
|
-
| `participantKind` | `'user' \| 'agent' \| 'system'` | Who's behind it — a human (`user`), an AI (`agent`), or automated infrastructure (`system`). |
|
|
130
|
-
| `createdAt` | number? | Ms-epoch the holder opened it. Optional — derived shapes may omit it. |
|
|
131
|
-
| `expiresAt` | number | Ms-epoch at which the server auto-expires it if the holder doesn't finish. |
|
|
132
|
-
|
|
133
|
-
```json
|
|
134
|
-
{
|
|
135
|
-
"object": "claim",
|
|
136
|
-
"id": "claim_3MtwBwLkdIwHu7ix",
|
|
137
|
-
"status": "active",
|
|
138
|
-
"target": { "type": "weatherReports", "id": "report_stockholm", "field": "status" },
|
|
139
|
-
"description": "editing",
|
|
140
|
-
"heldBy": "agent:report-writer",
|
|
141
|
-
"participantKind": "agent",
|
|
142
|
-
"expiresAt": 1716580000000
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### Lifecycle
|
|
147
|
-
|
|
148
|
-
```
|
|
149
|
-
claim({ id }) update({ id }) lands
|
|
150
|
-
(free) ───────────▶ active ───────────────────────▶ committed
|
|
151
|
-
│
|
|
152
|
-
┌───────────┴───────────┐
|
|
153
|
-
▼ ▼
|
|
154
|
-
canceled expired
|
|
155
|
-
(release w/o write) (TTL; holder died)
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
A target is free when `ablo.<model>.claim.state({ id })` is `null`. Terminal
|
|
159
|
-
states drop out of the live stream, so a present claim is either `active` (the
|
|
160
|
-
holder) or `queued` (waiting in the FIFO line behind the holder; see
|
|
161
|
-
`claim.queue({ id })`).
|
|
123
|
+
The fields on a claim, its lifecycle diagram, and the full method surface are in
|
|
124
|
+
[Coordination](./coordination.md#the-claim-state-object), which is where that
|
|
125
|
+
object is defined. Note that the entity half of `target` is spelled `model`/`id`
|
|
126
|
+
on the SDK's model surface and `type`/`id` on the claim handle and the wait
|
|
127
|
+
line.
|
|
162
128
|
|
|
163
129
|
### Reading and claiming
|
|
164
130
|
|
|
@@ -206,7 +172,7 @@ The SDK is a convenience wrapper over a model-scoped HTTP surface — the same
|
|
|
206
172
|
noun (`model`) and verbs as `ablo.<model>.…`. Non-JS callers (or curl) use it
|
|
207
173
|
directly. The table below shows the shape with `{model}` as a placeholder; the
|
|
208
174
|
[OpenAPI spec](./openapi.json) expands it into one **typed** path per model
|
|
209
|
-
(`/api/v1/models/task`, `/api/v1/models/
|
|
175
|
+
(`/api/v1/models/task`, `/api/v1/models/workspace`, …, generated from your schema) so each
|
|
210
176
|
endpoint documents that model's real field contract instead of a generic blob.
|
|
211
177
|
|
|
212
178
|
| SDK call | HTTP |
|
|
@@ -232,7 +198,7 @@ error `code` (e.g. `stale_context`, `intent_conflict`) to act on.
|
|
|
232
198
|
operations across rows/models that must commit together) — the per-model routes
|
|
233
199
|
above are the one-record path. Both run the identical guarded-write engine.
|
|
234
200
|
|
|
235
|
-
The [coordination MCP server](./mcp.md) (`@
|
|
201
|
+
The [coordination MCP server](./mcp.md) (`@abloatai/mcp`) is this same surface
|
|
236
202
|
rendered as agent tools.
|
|
237
203
|
|
|
238
204
|
## Errors
|
package/docs/audit.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Audit log
|
|
2
2
|
|
|
3
|
+
> Trace any committed change back to the key that made it, and to the person behind that key.
|
|
4
|
+
|
|
3
5
|
The audit log records who changed what in your org, and when — including
|
|
4
6
|
changes an AI agent made on a person's behalf. Every change is one row, and the
|
|
5
7
|
rows are chained with a keyed hash (HMAC-SHA256) so you can later prove the
|
|
@@ -21,11 +23,12 @@ with which key — and the chain columns that make the log tamper-evident:
|
|
|
21
23
|
capabilityId: string | null, // the API key/capability used for the write
|
|
22
24
|
capabilityLabel: string | null, // its human-readable name, for scanning the log
|
|
23
25
|
delegationChainRootUserId: string | null, // always points at a human
|
|
24
|
-
actionType:
|
|
25
|
-
modelName: string,
|
|
26
|
+
actionType: 'I' | 'U' | 'D', // insert, update, delete
|
|
27
|
+
modelName: string, // the model that changed, e.g. 'orders'
|
|
28
|
+
modelId: string, // the row that changed
|
|
26
29
|
confirmationState: 'auto' | 'previewed' | 'approved' | 'required_human_approval' | 'auto_historical',
|
|
27
30
|
diffSummary: unknown,
|
|
28
|
-
// chain columns
|
|
31
|
+
// chain columns, carried on every stored row and checked by verify (below)
|
|
29
32
|
chainSeq: number,
|
|
30
33
|
prevHash: string,
|
|
31
34
|
rowHash: string,
|
package/docs/cli.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# CLI
|
|
2
2
|
|
|
3
|
+
> Scaffold a schema, connect a database, push it, and watch it sync.
|
|
4
|
+
|
|
3
5
|
The `ablo` CLI gets you from an empty project to live-syncing data: scaffold a
|
|
4
6
|
schema, authenticate, push the schema, and watch it sync. Your
|
|
5
7
|
`defineSchema(...)` is the single source of truth: whether you run the CLI
|
|
@@ -34,7 +36,7 @@ This mirrors `stripe login`.
|
|
|
34
36
|
| `ablo login` | Authorize in the browser; provisions + stores a test and a live key. |
|
|
35
37
|
| `ablo login --project <slug>` | Same, but scope (and mint) the pair to a project, and make it active. |
|
|
36
38
|
| `ablo logout` | Remove the stored keys. |
|
|
37
|
-
| `ablo status` | Show the active org, mode, both keys (prefix
|
|
39
|
+
| `ablo status` | Show the active org, mode, both keys (prefix, what each can do, expiry), and server health. |
|
|
38
40
|
| `ablo mode [sandbox\|production]` | Switch the active environment. With no argument, prompts. |
|
|
39
41
|
|
|
40
42
|
Keys live in `~/.config/ablo/credentials.json` (mode `0600`), keyed by project
|
|
@@ -49,8 +51,11 @@ belongs to one of them. Test keys are bound to an isolated sandbox: their reads
|
|
|
49
51
|
and writes never touch production data. Switch with `ablo mode`; `ablo dev` is always
|
|
50
52
|
the sandbox by design.
|
|
51
53
|
|
|
52
|
-
The schema
|
|
53
|
-
|
|
54
|
+
The schema is **one definition serving both**: a sandbox reads the production
|
|
55
|
+
schema until it is pushed one of its own, so your test and live keys see the same
|
|
56
|
+
models and only the rows differ. Each plane keeps its own copy once pushed, so a
|
|
57
|
+
schema change reaches production when you push it with a live key — see
|
|
58
|
+
[Deployment](./deployment.md).
|
|
54
59
|
|
|
55
60
|
## Projects
|
|
56
61
|
|
|
@@ -89,17 +94,40 @@ profiles entirely: it acts in whatever project it was minted for.
|
|
|
89
94
|
|
|
90
95
|
| Command | What it does | Flags |
|
|
91
96
|
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
92
|
-
| `ablo init` | Scaffold `ablo/` (`schema.ts`, client, optional Data Source / agent / component), write `.env`, install the SDK. Offers to log in at the end.
|
|
93
|
-
| `ablo login` / `logout` / `status` | Authentication & status (above).
|
|
94
|
-
| `ablo mode [sandbox\|production]` | Switch active environment.
|
|
97
|
+
| `ablo init` | Scaffold `ablo/` (`schema.ts`, client, optional Data Source / agent / component), write `.env`, install the SDK. Offers to log in at the end. |: |
|
|
98
|
+
| `ablo login` / `logout` / `status` | Authentication & status (above). |: |
|
|
99
|
+
| `ablo mode [sandbox\|production]` | Switch active environment. |: |
|
|
95
100
|
| `ablo projects list\|create\|use\|rename` | Manage projects and the active one (see [Projects](#projects)). Each project's keys/schema/data are isolated. | `--name "<display>"` (create/rename) |
|
|
96
|
-
| `ablo dev` | **Hosted
|
|
101
|
+
| `ablo dev` | **Hosted**: push the schema to your test sandbox, then watch `ablo/schema.ts` and re-push on save. | `--no-watch`, `--schema <path>`, `--export <name>`, `--url <url>` |
|
|
97
102
|
| `ablo logs` | Tail your scope's commit activity (`stripe logs tail`). Follows by default. | `-n, --tail <N>`, `--since <dur\|ts>`, `--model`, `--op`, `--json`, `--no-follow`, `--mode sandbox\|production` |
|
|
98
|
-
| `ablo push` | **Hosted
|
|
99
|
-
| `ablo migrate` | **Direct Postgres
|
|
100
|
-
| `ablo pull` | **Direct Postgres
|
|
101
|
-
| `ablo check` | **Direct Postgres
|
|
103
|
+
| `ablo push` | **Hosted**: upload the schema to Ablo; the server diffs, migrates, and activates it. | `--force`, `--rename old:new`, `--backfill model.field=value`, `--schema`, `--export`, `--url` |
|
|
104
|
+
| `ablo migrate` | **Direct Postgres**: provision just the synced models (plus the adapter's `ablo_outbox` / `ablo_idempotency`) in your own `DATABASE_URL`. Leaves your other tables alone. | `--dry-run`, `--output <file>`, `--schema`, `--export` |
|
|
105
|
+
| `ablo pull` | **Direct Postgres**: generate `defineSchema(...)` from your existing tables (read-only, like `prisma db pull`). | `--out <path>`, `--app-schema <name>`, `--import <pkg>`, `--force` |
|
|
106
|
+
| `ablo check` | **Direct Postgres**: verify your _existing_ tables fit the schema (read-only, no schema changes). | `--schema <path>`, `--export <name>`, `--app-schema <name>` |
|
|
102
107
|
| `ablo generate` | Emit TypeScript types from the schema. | `--out <path>`, `--schema`, `--export` |
|
|
108
|
+
| `ablo docs` | Read these pages for the version you installed: offline, no network (see [`ablo docs`](#ablo-docs)). | `--json` |
|
|
109
|
+
|
|
110
|
+
## `ablo docs`
|
|
111
|
+
|
|
112
|
+
The documentation for the version in your `node_modules`, not the version on the
|
|
113
|
+
website.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npx ablo docs # every page, with what it covers
|
|
117
|
+
npx ablo docs coordination # one page, as markdown
|
|
118
|
+
npx ablo docs --json # the page list, machine-readable
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
These pages ship inside the npm package, so they describe the code beside them
|
|
122
|
+
and stay reachable with no network — the sandboxes and CI runners agents work in
|
|
123
|
+
often have none. That matters most when a project is pinned: `get` / `getAll` /
|
|
124
|
+
`getCount` became `retrieve` / `list` in 0.35.0, and a website always describes
|
|
125
|
+
the newest release, so an agent on an earlier version reads the new name and
|
|
126
|
+
writes a call its own package doesn't have.
|
|
127
|
+
|
|
128
|
+
Pass a slug (`coordination`), a path (`docs/coordination.md`), or a file name
|
|
129
|
+
(`AGENTS.md`). A miss names the closest page. The same pages are served over
|
|
130
|
+
HTTP at `/api/docs/<slug>` and through the docs MCP server.
|
|
103
131
|
|
|
104
132
|
## `ablo dev`
|
|
105
133
|
|
|
@@ -213,7 +241,7 @@ The one type map, shared by both paths (there is no second mapping):
|
|
|
213
241
|
| Zod | Postgres |
|
|
214
242
|
| ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
|
|
215
243
|
| `z.string()` | `TEXT` |
|
|
216
|
-
| `z.number()` | `DOUBLE PRECISION
|
|
244
|
+
| `z.number()` | `DOUBLE PRECISION`: never `INTEGER`; a Zod number may be fractional, and truncating is silent data loss |
|
|
217
245
|
| `z.boolean()` | `BOOLEAN` |
|
|
218
246
|
| `z.date()` | `TIMESTAMPTZ` |
|
|
219
247
|
| `z.enum([...])` | `TEXT` + a `CHECK (col IN (...))` constraint |
|
|
@@ -268,7 +296,7 @@ migration can't leave clients gated against tables that don't match.
|
|
|
268
296
|
|
|
269
297
|
| Variable | Purpose | Default |
|
|
270
298
|
| ------------------------------------- | ------------------------------------------------------------------------ | -------------------------- |
|
|
271
|
-
| `ABLO_API_KEY` | Authenticate without `ablo login` (CI). Always overrides the stored key.
|
|
299
|
+
| `ABLO_API_KEY` | Authenticate without `ablo login` (CI). Always overrides the stored key. |: |
|
|
272
300
|
| `ABLO_API_URL` | Control-plane / API host (`push`, `dev`, `status`). | `https://api.abloatai.com` |
|
|
273
301
|
| `ABLO_AUTH_URL` | Dashboard origin for `ablo login`'s device flow. | `https://abloatai.com` |
|
|
274
302
|
| `ABLO_CONFIG_DIR` / `XDG_CONFIG_HOME` | Where the credential file lives. | `~/.config/ablo` |
|
package/docs/client-behavior.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Client Behavior
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Per-write options, claim behavior, and which errors are safe to retry.
|
|
4
|
+
|
|
5
|
+
When several writers touch the same data at once — an agent worker, a Server Action, a person in the browser — the SDK decides whose write lands and how the others find out. This page is the reference for that: per-write options like `wait` and `onStale`, claiming a record so your slow work runs uninterrupted, and which errors are safe to retry.
|
|
4
6
|
|
|
5
7
|
Claims don't lock. If another writer holds the row, `claim` waits for them, re-reads the fresh row, then hands it to you — so two writers serialize instead of clobbering.
|
|
6
8
|
|
|
@@ -32,7 +34,7 @@ Common options:
|
|
|
32
34
|
| `baseURL` | Override the hosted sync endpoint for staging or private deployments. |
|
|
33
35
|
| `persistence` | `memory` by default. Use `indexeddb` for a durable browser cache that survives reloads. |
|
|
34
36
|
| `durableWrites` | Optional crash recovery for unacknowledged agent/worker writes. Independent of the default memory cache; accepts `{ store, namespace? }`. |
|
|
35
|
-
| `transport` | `'websocket'` (default) is the live, stateful client
|
|
37
|
+
| `transport` | `'websocket'` (default) is the live, stateful client: a persistent socket, a local synced pool, and `onChange` subscriptions. `'http'` returns the **stateless** client for server-side actors (agents, workers, serverless): the same `ablo.<model>` read/write/claim surface, but each call is one HTTP round-trip with no socket. Under `'http'` the return type narrows to `AbloHttpClient`, so stateful-only methods (the `local` reads, `onChange`, `join`) are compile errors rather than runtime gaps. |
|
|
36
38
|
| `fetch` | Custom fetch implementation for tests or non-standard runtimes. |
|
|
37
39
|
| `defaultHeaders` | Extra headers attached to every HTTP request. |
|
|
38
40
|
| `defaultQuery` | Extra query parameters attached to every HTTP request. |
|
|
@@ -52,7 +54,7 @@ Each schema model becomes a typed model:
|
|
|
52
54
|
await ablo.ready();
|
|
53
55
|
|
|
54
56
|
const report = await ablo.weatherReports.retrieve({ id: 'report_stockholm' });
|
|
55
|
-
const local = ablo.weatherReports.
|
|
57
|
+
const local = ablo.weatherReports.local.retrieve('report_stockholm');
|
|
56
58
|
|
|
57
59
|
await ablo.weatherReports.create({ data: { location: 'Stockholm', status: 'pending' } });
|
|
58
60
|
await ablo.weatherReports.update({ id: 'report_stockholm', data: { status: 'ready' }, wait: 'confirmed' });
|
|
@@ -60,11 +62,11 @@ await ablo.weatherReports.delete({ id: 'report_stockholm', wait: 'confirmed' });
|
|
|
60
62
|
```
|
|
61
63
|
|
|
62
64
|
Call `retrieve`/`list` first — they fetch from the server and you `await` them.
|
|
63
|
-
After that, `
|
|
65
|
+
After that, `local.retrieve`/`local.list`/`local.count` read the already-synced data instantly with
|
|
64
66
|
no `await`, and stay reactive in render. Use the async pair to load, the sync trio
|
|
65
67
|
to read.
|
|
66
68
|
|
|
67
|
-
`
|
|
69
|
+
`local.list` accepts the same practical read options the React selector path uses:
|
|
68
70
|
`where`, `filter`, `orderBy`, `limit`, `offset`, and `state`. The `state`
|
|
69
71
|
lifecycle filter defaults to `'live'`; pass `'archived'` or `'all'` when you
|
|
70
72
|
intentionally want non-live rows.
|
|
@@ -91,7 +93,7 @@ await ablo.weatherReports.update({
|
|
|
91
93
|
|
|
92
94
|
Once the server accepts the write, every other connected client gets the new row
|
|
93
95
|
automatically — no polling or manual refresh on your side. React clients that use
|
|
94
|
-
`useAblo((ablo) => ablo.weatherReports.
|
|
96
|
+
`useAblo((ablo) => ablo.weatherReports.local.retrieve(id))` receive the new row, and selectors
|
|
95
97
|
such as `useAblo((ablo) => ablo.weatherReports.claim.state({ id }))`
|
|
96
98
|
receive active claim state. There is
|
|
97
99
|
no extra multiplayer setup beyond routing shared state through Ablo.
|
|
@@ -216,8 +218,8 @@ Only these imports are public SemVer surface:
|
|
|
216
218
|
- `@abloatai/ablo`
|
|
217
219
|
- `@abloatai/ablo/schema`
|
|
218
220
|
- `@abloatai/ablo/react`
|
|
219
|
-
- `@abloatai/ablo/testing`
|
|
220
221
|
|
|
221
222
|
`dataSource(...)` is exported from the root package for customer-owned storage
|
|
222
|
-
adapters. Everything outside the
|
|
223
|
-
apps and infrastructure.
|
|
223
|
+
adapters. Everything outside the three import paths is internal to Ablo-owned
|
|
224
|
+
apps and infrastructure. For adapter authors, `@abloatai/ablo/source/conformance`
|
|
225
|
+
is the suite that proves a storage adapter behaves correctly.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Concurrency Convention
|
|
2
2
|
|
|
3
|
-
> The governing
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
> The governing rule for how Ablo resolves concurrent writes to shared state.
|
|
4
|
+
|
|
5
|
+
This page is the contract: the `onStale` dispositions, what a conflict is
|
|
6
|
+
checked against, and where the convention stops. The three-layer mechanics of
|
|
7
|
+
claiming live in [Coordination](./coordination.md).
|
|
6
8
|
|
|
7
9
|
---
|
|
8
10
|
|
|
@@ -25,8 +27,8 @@ moments in time:
|
|
|
25
27
|
|
|
26
28
|
| form | when | mechanism |
|
|
27
29
|
|---|---|---|
|
|
28
|
-
| **Claim** | *prospective
|
|
29
|
-
| **Notification** | *in-flight
|
|
30
|
+
| **Claim** | *prospective*: before you act | reserve the row; others queue. Coordinate so the conflict never forms. |
|
|
31
|
+
| **Notification** | *in-flight*: after a concurrent change | surface the changed value; the actor resolves and re-issues. |
|
|
30
32
|
|
|
31
33
|
Use a claim when you will hold the row across a slow read→reason→write gap. Use a
|
|
32
34
|
notification when you didn't, and the premise moved under you.
|
|
@@ -35,14 +37,14 @@ notification when you didn't, and the premise moved under you.
|
|
|
35
37
|
|
|
36
38
|
## 2. The dispositions (`onStale`)
|
|
37
39
|
|
|
38
|
-
Every guarded write (and every
|
|
39
|
-
|
|
40
|
+
Every guarded write (and every premise declared in §4) says what should happen
|
|
41
|
+
when it goes stale. Three modes, split by whether they **force** an outcome:
|
|
40
42
|
|
|
41
43
|
| mode | coercive? | what the engine does | who resolves | use when |
|
|
42
44
|
|---|---|---|---|---|
|
|
43
|
-
| `notify` | **No
|
|
44
|
-
| `reject` | **Yes
|
|
45
|
-
| `overwrite` | **Yes
|
|
45
|
+
| `notify` | **No**: surface + delegate | Holds the write (does **not** apply it); returns a `StaleNotification` with the current value. | The actor (agent or human) reconciles and re-issues. | The aligned mode: tell the actor what changed, let it solve. |
|
|
46
|
+
| `reject` | **Yes**: force-abort | Throws `AbloStaleContextError`; the batch is discarded. | The caller retries from scratch. | Hard invariants; legacy/strict callers. The current default. |
|
|
47
|
+
| `overwrite` | **Yes**: force-clobber | Overwrites blindly last-writer-wins; **no** signal. | Nobody. | You genuinely own the field and concurrent values are noise. |
|
|
46
48
|
|
|
47
49
|
> `notify` is the convention. `reject` and `overwrite` are escape hatches for the
|
|
48
50
|
> two ends — "never let this be wrong" and "never bother me." They are not the
|
|
@@ -50,43 +52,44 @@ should be handled. Three modes, split by whether they **force** an outcome:
|
|
|
50
52
|
|
|
51
53
|
---
|
|
52
54
|
|
|
53
|
-
## 3. What is checked: two
|
|
55
|
+
## 3. What is checked: two premises
|
|
54
56
|
|
|
55
|
-
A conflict is a **
|
|
56
|
-
a concurrent delta. Ablo checks two
|
|
57
|
+
A conflict is a **premise intersection** — what your operation was based on
|
|
58
|
+
overlaps a concurrent delta. Ablo checks two premises, and they are independent.
|
|
59
|
+
They differ only in what declared them:
|
|
57
60
|
|
|
58
|
-
|
|
|
61
|
+
| premise | declared by | question | scope |
|
|
59
62
|
|---|---|---|---|
|
|
60
63
|
| **Write-target** | per-op `readAt` | "did a row I'm **writing** change since I read it?" | the rows in `operations[]` |
|
|
61
|
-
| **
|
|
64
|
+
| **Batch** | batch-level `reads[]` | "did anything I **looked at** change since I read it?" | rows/groups in `reads[]`, even if not written |
|
|
62
65
|
|
|
63
66
|
The write-target check alone is the narrow case the canary anomaly defeats: an
|
|
64
67
|
agent reads `deal.stage`, writes `task.status`, and a peer moves `deal.stage` —
|
|
65
|
-
`task` never changed, so a write-target-only check waves it through. The
|
|
66
|
-
closes that gap.
|
|
68
|
+
`task` never changed, so a write-target-only check waves it through. The batch
|
|
69
|
+
premise closes that gap.
|
|
67
70
|
|
|
68
71
|
---
|
|
69
72
|
|
|
70
|
-
## 4. The
|
|
73
|
+
## 4. The batch premise (`reads[]`)
|
|
71
74
|
|
|
72
|
-
A commit may declare, at the batch level,
|
|
75
|
+
A commit may declare, at the batch level, what its writes were based on.
|
|
73
76
|
Two granularities, developer's choice per entry:
|
|
74
77
|
|
|
75
78
|
```ts
|
|
76
79
|
reads: [
|
|
77
|
-
{ model: '
|
|
78
|
-
{ group: '
|
|
80
|
+
{ model: 'Document', id: 's-1', readAt: N, fields?: ['title'] }, // ROW premise
|
|
81
|
+
{ group: 'workspace:abc', readAt: N, onStale: 'notify' }, // GROUP premise
|
|
79
82
|
]
|
|
80
83
|
```
|
|
81
84
|
|
|
82
|
-
- **Row
|
|
85
|
+
- **Row:** did this specific row (optionally these fields) change? The literal
|
|
83
86
|
per-object premise.
|
|
84
|
-
- **Group
|
|
85
|
-
key (`
|
|
87
|
+
- **Group:** did *anything* in this sync group change? `group` is a sync-group
|
|
88
|
+
key (`workspace:abc`, `document:s1`, `org:X`) — the same unit a participant **watches
|
|
86
89
|
and claims**. This is the more Ablo-native granularity.
|
|
87
90
|
|
|
88
|
-
**Boundary — a stale
|
|
89
|
-
|
|
91
|
+
**Boundary — a stale premise fires over the whole batch.** Each entry covers
|
|
92
|
+
*all* the writes in the commit, so its disposition governs the batch:
|
|
90
93
|
`reject` aborts it, `notify` holds **every** write and notifies, `overwrite`
|
|
91
94
|
lets them land. Per-entry `onStale` defaults to `reject`.
|
|
92
95
|
|
|
@@ -105,13 +108,13 @@ Shape (canonical in `coordination/schema.ts`):
|
|
|
105
108
|
|
|
106
109
|
| field | meaning |
|
|
107
110
|
|---|---|
|
|
108
|
-
| `object` | Stripe-style type tag
|
|
111
|
+
| `object` | Stripe-style type tag: `'stale_notification'` |
|
|
109
112
|
| `model`, `id` | the conflicting row (for a group dep, both are the group key) |
|
|
110
113
|
| `group?` | set when this is a group-scoped notification |
|
|
111
114
|
| `readAt` | the watermark the committer reasoned against |
|
|
112
|
-
| `observedSyncId` | the newest delta on the premise
|
|
115
|
+
| `observedSyncId` | the newest delta on the premise: re-read at/after this |
|
|
113
116
|
| `conflictingFields` | fields that moved (empty for group / whole-entity) |
|
|
114
|
-
| `currentValues` | the live values of those fields
|
|
117
|
+
| `currentValues` | the live values of those fields: the premise to reconcile against (empty for group) |
|
|
115
118
|
| `writtenBy` | `{ kind, id }` of the concurrent author, reported faithfully |
|
|
116
119
|
|
|
117
120
|
Only `notify` produces a notification (the write was held). `reject` throws and
|
|
@@ -152,7 +155,7 @@ function reconcile(n: StaleNotification) {
|
|
|
152
155
|
|
|
153
156
|
The loop **terminates** because each retry advances `readAt` to `observedSyncId`;
|
|
154
157
|
a peer that keeps writing only ever notifies you against a *newer* baseline, never
|
|
155
|
-
the same one twice. A group
|
|
158
|
+
the same one twice. A group premise reconciles identically, except `group` is set
|
|
156
159
|
and `currentValues` is empty (re-read the group).
|
|
157
160
|
|
|
158
161
|
---
|
|
@@ -166,7 +169,7 @@ What the convention **guarantees**, and where it **stops**:
|
|
|
166
169
|
or human) owns the resolution. The engine does not distinguish them — it is
|
|
167
170
|
actor-neutral by design.
|
|
168
171
|
|
|
169
|
-
2. **Truthfulness
|
|
172
|
+
2. **Truthfulness:** `currentValues` / `observedSyncId` reflect committed state at
|
|
170
173
|
detection time, inside the same transaction as the write. A notification is
|
|
171
174
|
never speculative.
|
|
172
175
|
|
|
@@ -182,13 +185,11 @@ What the convention **guarantees**, and where it **stops**:
|
|
|
182
185
|
so they must not be gated by `notify`.
|
|
183
186
|
|
|
184
187
|
5. **Defaults.** A plain write (no `readAt`) is last-writer-wins with **no**
|
|
185
|
-
check. A guarded write with `readAt` but no `onStale` defaults to `reject
|
|
186
|
-
(back-compat). *Open decision (§7).*
|
|
188
|
+
check. A guarded write with `readAt` but no `onStale` defaults to `reject`.
|
|
187
189
|
|
|
188
190
|
6. **Policy seam.** Custom `ConflictPolicy` functions see **write-target**
|
|
189
|
-
conflicts (`stale_context` / `claim_held`). **
|
|
190
|
-
|
|
191
|
-
seam. *Open decision (§7).*
|
|
191
|
+
conflicts (`stale_context` / `claim_held`). **Batch-premise** conflicts are
|
|
192
|
+
resolved directly via each entry's `onStale`, not through the policy seam.
|
|
192
193
|
|
|
193
194
|
7. **Claims win when held.** A non-holder writing to a claimed row is rejected
|
|
194
195
|
(`AbloClaimedError`) regardless of `readAt` — the prospective form takes
|
|
@@ -197,26 +198,17 @@ What the convention **guarantees**, and where it **stops**:
|
|
|
197
198
|
|
|
198
199
|
---
|
|
199
200
|
|
|
200
|
-
## 7.
|
|
201
|
-
|
|
202
|
-
These are deliberately left open; they change behavior and are the user's call.
|
|
203
|
-
|
|
204
|
-
- **Default disposition for agents.** Should an agent-participant guarded write
|
|
205
|
-
default to `notify` (philosophy-aligned: surface, don't overwrite) instead of
|
|
206
|
-
`reject` (back-compat)? Trade-off: alignment vs. a behavior change for existing
|
|
207
|
-
agent callers.
|
|
208
|
-
- **Read-deps through the policy seam.** Should read-set conflicts also pass
|
|
209
|
-
through `ConflictPolicy` (requires a group-aware conflict shape), or stay on
|
|
210
|
-
the direct `onStale` mapping?
|
|
211
|
-
|
|
212
|
-
---
|
|
201
|
+
## 7. What this convention does not cover
|
|
213
202
|
|
|
214
|
-
|
|
203
|
+
Three limits worth knowing before you rely on it.
|
|
215
204
|
|
|
216
|
-
- Irreversible external side-effects
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
205
|
+
- **Irreversible external side-effects.** Emails, payments, and third-party
|
|
206
|
+
calls are not gated by this convention (§6.4). The engine cannot hold or undo
|
|
207
|
+
them, so never place one behind `notify`.
|
|
208
|
+
- **A caller that declares nothing gets no check.** The batch premise catches
|
|
209
|
+
only what you declared. Write-target checking needs a `readAt` to compare
|
|
210
|
+
against, so a plain write with neither is last-writer-wins (§6.5). What you
|
|
211
|
+
declare is what is protected.
|
|
212
|
+
- **`writtenBy.kind` reports what authenticated, not what you meant.** An `sk_`
|
|
213
|
+
key resolves to `system`, not `agent`. How identities map to participant kinds
|
|
214
|
+
is a separate concern from this convention.
|