@abloatai/ablo 0.35.0 → 0.37.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 -2
- package/CHANGELOG.md +71 -1929
- package/NOTICE +2 -2
- package/README.md +23 -532
- package/assets/banner.png +0 -0
- package/dist/auth.d.ts +2 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +2 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +3 -0
- package/dist/client.js.map +1 -0
- package/dist/coordination.d.ts +2 -0
- package/dist/coordination.d.ts.map +1 -0
- package/dist/coordination.js +2 -0
- package/dist/coordination.js.map +1 -0
- package/dist/index.d.ts +3 -112
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -161
- package/dist/index.js.map +1 -0
- package/dist/react.d.ts +4 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +3 -0
- package/dist/react.js.map +1 -0
- package/dist/schema.d.ts +2 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +2 -0
- package/dist/schema.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -0
- package/dist/source-conformance.d.ts +2 -0
- package/dist/source-conformance.d.ts.map +1 -0
- package/dist/source-conformance.js +2 -0
- package/dist/source-conformance.js.map +1 -0
- package/dist/source-drizzle.d.ts +2 -0
- package/dist/source-drizzle.d.ts.map +1 -0
- package/dist/source-drizzle.js +2 -0
- package/dist/source-drizzle.js.map +1 -0
- package/dist/source-kysely.d.ts +2 -0
- package/dist/source-kysely.d.ts.map +1 -0
- package/dist/source-kysely.js +2 -0
- package/dist/source-kysely.js.map +1 -0
- package/dist/source-next.d.ts +2 -0
- package/dist/source-next.d.ts.map +1 -0
- package/dist/source-next.js +2 -0
- package/dist/source-next.js.map +1 -0
- package/dist/source.d.ts +2 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +2 -0
- package/dist/source.js.map +1 -0
- package/dist/wire.d.ts +2 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +2 -0
- package/dist/wire.js.map +1 -0
- package/docs/agents.md +2 -2
- package/docs/api-keys.md +13 -12
- package/docs/api.md +15 -53
- package/docs/audit.md +4 -3
- package/docs/cli.md +11 -11
- package/docs/client-behavior.md +9 -9
- package/docs/concurrency-convention.md +28 -42
- package/docs/coordination.md +228 -86
- package/docs/data-sources.md +5 -5
- package/docs/debugging.md +34 -12
- package/docs/deployment.md +8 -8
- package/docs/examples/agent-human.md +4 -4
- package/docs/examples/ai-sdk-tool.md +1 -1
- package/docs/examples/existing-python-backend.md +15 -4
- package/docs/examples/nextjs.md +27 -6
- package/docs/examples/scoped-agent.md +3 -3
- package/docs/examples/server-agent.md +2 -2
- package/docs/groups.md +57 -3
- package/docs/guarantees.md +37 -10
- package/docs/how-it-works.md +32 -8
- package/docs/idempotency.md +6 -6
- package/docs/identity.md +24 -24
- package/docs/index.md +8 -8
- package/docs/integration-guide.md +38 -16
- package/docs/internal/README.md +18 -0
- package/docs/internal/agent-fleet-coordination-design.md +171 -0
- package/docs/internal/agent-orchestration.md +58 -0
- package/docs/internal/commit-identifiers.md +91 -0
- package/docs/internal/concurrency-open-decisions.md +37 -0
- package/docs/internal/data-source-reverse-channel.md +150 -0
- package/docs/internal/per-field-conflict-detection.md +165 -0
- package/docs/internal/postgres-replication.md +64 -0
- package/docs/internal/serializable-schema.md +119 -0
- package/docs/internal/structure.md +32 -0
- package/docs/mcp.md +9 -9
- package/docs/migration.md +37 -18
- package/docs/projects.md +1 -1
- package/docs/quickstart.md +2 -2
- package/docs/react.md +24 -13
- package/docs/schema-contract.md +3 -3
- package/docs/sessions.md +91 -37
- package/docs/webhooks.md +9 -9
- package/examples/README.md +2 -2
- package/examples/data-source/README.md +1 -1
- package/examples/data-source/ablo-driver.ts +1 -1
- package/examples/data-source/customer-server.ts +1 -1
- package/examples/data-source/run.ts +1 -1
- package/examples/data-source/schema.ts +1 -1
- package/examples/quickstart.ts +2 -2
- package/llms.txt +12 -12
- package/package.json +64 -174
- package/dist/BaseSyncedStore.d.ts +0 -823
- package/dist/BaseSyncedStore.js +0 -1955
- package/dist/Database.d.ts +0 -335
- package/dist/Database.js +0 -1500
- package/dist/InstanceCache.d.ts +0 -233
- package/dist/InstanceCache.js +0 -1164
- package/dist/LazyReferenceCollection.d.ts +0 -177
- package/dist/LazyReferenceCollection.js +0 -461
- package/dist/Model.d.ts +0 -444
- package/dist/Model.js +0 -909
- package/dist/ModelRegistry.d.ts +0 -221
- package/dist/ModelRegistry.js +0 -537
- package/dist/NetworkMonitor.d.ts +0 -26
- package/dist/NetworkMonitor.js +0 -77
- package/dist/RuntimeContext.d.ts +0 -52
- package/dist/RuntimeContext.js +0 -80
- package/dist/SyncClient.d.ts +0 -551
- package/dist/SyncClient.js +0 -2199
- package/dist/adapters/alwaysOnline.d.ts +0 -14
- package/dist/adapters/alwaysOnline.js +0 -17
- package/dist/adapters/inMemoryStorage.d.ts +0 -31
- package/dist/adapters/inMemoryStorage.js +0 -110
- package/dist/ai-sdk/coordinatedTool.d.ts +0 -120
- package/dist/ai-sdk/coordinatedTool.js +0 -134
- package/dist/ai-sdk/coordinationContext.d.ts +0 -46
- package/dist/ai-sdk/coordinationContext.js +0 -106
- package/dist/ai-sdk/index.d.ts +0 -121
- package/dist/ai-sdk/index.js +0 -121
- package/dist/ai-sdk/wrap.d.ts +0 -65
- package/dist/ai-sdk/wrap.js +0 -39
- package/dist/auth/index.d.ts +0 -1
- package/dist/auth/index.js +0 -8
- package/dist/batching/index.d.ts +0 -55
- package/dist/batching/index.js +0 -147
- package/dist/cli.cjs +0 -288600
- package/dist/client/Ablo.d.ts +0 -231
- package/dist/client/Ablo.js +0 -149
- package/dist/client/abloClient.d.ts +0 -309
- package/dist/client/abloClient.js +0 -13
- package/dist/client/clientPrelude.d.ts +0 -52
- package/dist/client/clientPrelude.js +0 -60
- package/dist/client/consoleLogger.d.ts +0 -35
- package/dist/client/consoleLogger.js +0 -44
- package/dist/client/coreClient.d.ts +0 -60
- package/dist/client/coreClient.js +0 -118
- package/dist/client/createInternalComponents.d.ts +0 -46
- package/dist/client/createInternalComponents.js +0 -92
- package/dist/client/createModelProxy.d.ts +0 -228
- package/dist/client/createModelProxy.js +0 -818
- package/dist/client/humans.d.ts +0 -48
- package/dist/client/humans.js +0 -52
- package/dist/client/modelRegistration.d.ts +0 -10
- package/dist/client/modelRegistration.js +0 -312
- package/dist/client/options.d.ts +0 -461
- package/dist/client/options.js +0 -7
- package/dist/client/reactiveEngine.d.ts +0 -48
- package/dist/client/reactiveEngine.js +0 -910
- package/dist/client/resourceTypes.d.ts +0 -12
- package/dist/client/resourceTypes.js +0 -10
- package/dist/client/schemaConfig.d.ts +0 -44
- package/dist/client/schemaConfig.js +0 -185
- package/dist/client/validateAbloOptions.d.ts +0 -42
- package/dist/client/validateAbloOptions.js +0 -43
- package/dist/client/wsMutationExecutor.d.ts +0 -27
- package/dist/client/wsMutationExecutor.js +0 -72
- package/dist/context.d.ts +0 -29
- package/dist/context.js +0 -58
- package/dist/coordination/ClaimLog.d.ts +0 -26
- package/dist/coordination/ClaimLog.js +0 -32
- package/dist/coordination/index.d.ts +0 -1
- package/dist/coordination/index.js +0 -8
- package/dist/core/DatabaseManager.d.ts +0 -105
- package/dist/core/DatabaseManager.js +0 -387
- package/dist/core/QueryProcessor.d.ts +0 -75
- package/dist/core/QueryProcessor.js +0 -255
- package/dist/core/QueryView.d.ts +0 -79
- package/dist/core/QueryView.js +0 -218
- package/dist/core/StoreManager.d.ts +0 -112
- package/dist/core/StoreManager.js +0 -302
- package/dist/core/ViewRegistry.d.ts +0 -20
- package/dist/core/ViewRegistry.js +0 -55
- package/dist/core/index.d.ts +0 -33
- package/dist/core/index.js +0 -48
- package/dist/core/openIDBWithTimeout.d.ts +0 -65
- package/dist/core/openIDBWithTimeout.js +0 -153
- package/dist/core/queryUtils.d.ts +0 -45
- package/dist/core/queryUtils.js +0 -69
- package/dist/core/storeContract.d.ts +0 -145
- package/dist/core/storeContract.js +0 -12
- package/dist/docs/catalog.d.ts +0 -72
- package/dist/docs/catalog.js +0 -227
- package/dist/docs/index.d.ts +0 -10
- package/dist/docs/index.js +0 -10
- package/dist/environment.d.ts +0 -1
- package/dist/environment.js +0 -8
- package/dist/interfaces/index.d.ts +0 -311
- package/dist/interfaces/index.js +0 -9
- package/dist/keys/index.d.ts +0 -1
- package/dist/keys/index.js +0 -8
- package/dist/mutators/RecordingMutation.d.ts +0 -36
- package/dist/mutators/RecordingMutation.js +0 -182
- package/dist/mutators/Transaction.d.ts +0 -40
- package/dist/mutators/Transaction.js +0 -58
- package/dist/mutators/UndoManager.d.ts +0 -258
- package/dist/mutators/UndoManager.js +0 -658
- package/dist/mutators/defineMutators.d.ts +0 -60
- package/dist/mutators/defineMutators.js +0 -18
- package/dist/mutators/inverseOp.d.ts +0 -126
- package/dist/mutators/inverseOp.js +0 -71
- package/dist/mutators/mutateActions.d.ts +0 -45
- package/dist/mutators/mutateActions.js +0 -105
- package/dist/mutators/readerActions.d.ts +0 -33
- package/dist/mutators/readerActions.js +0 -57
- package/dist/mutators/undoApply.d.ts +0 -51
- package/dist/mutators/undoApply.js +0 -117
- package/dist/policy/index.d.ts +0 -21
- package/dist/policy/index.js +0 -20
- package/dist/query/client.d.ts +0 -61
- package/dist/query/client.js +0 -137
- package/dist/query/types.d.ts +0 -85
- package/dist/query/types.js +0 -16
- package/dist/react/AbloProvider.d.ts +0 -230
- package/dist/react/AbloProvider.js +0 -455
- package/dist/react/ClientSideSuspense.d.ts +0 -36
- package/dist/react/ClientSideSuspense.js +0 -17
- package/dist/react/DefaultFallback.d.ts +0 -24
- package/dist/react/DefaultFallback.js +0 -43
- package/dist/react/context.d.ts +0 -55
- package/dist/react/context.js +0 -29
- package/dist/react/index.d.ts +0 -61
- package/dist/react/index.js +0 -66
- package/dist/react/internalContext.d.ts +0 -33
- package/dist/react/internalContext.js +0 -3
- package/dist/react/useAblo.d.ts +0 -75
- package/dist/react/useAblo.js +0 -102
- package/dist/react/useCurrentUserId.d.ts +0 -22
- package/dist/react/useCurrentUserId.js +0 -34
- package/dist/react/useErrorListener.d.ts +0 -20
- package/dist/react/useErrorListener.js +0 -38
- package/dist/react/useMutationFailureListener.d.ts +0 -26
- package/dist/react/useMutationFailureListener.js +0 -38
- package/dist/react/useMutators.d.ts +0 -56
- package/dist/react/useMutators.js +0 -84
- package/dist/react/useReactive.d.ts +0 -35
- package/dist/react/useReactive.js +0 -123
- package/dist/react/useSyncStatus.d.ts +0 -59
- package/dist/react/useSyncStatus.js +0 -76
- package/dist/react/useUndoScope.d.ts +0 -34
- package/dist/react/useUndoScope.js +0 -81
- package/dist/schema/coordination.d.ts +0 -112
- package/dist/schema/coordination.js +0 -129
- package/dist/schema/ddl.d.ts +0 -97
- package/dist/schema/ddl.js +0 -491
- package/dist/schema/ddlLock.d.ts +0 -35
- package/dist/schema/ddlLock.js +0 -46
- package/dist/schema/diff.d.ts +0 -225
- package/dist/schema/diff.js +0 -289
- package/dist/schema/generate.d.ts +0 -19
- package/dist/schema/generate.js +0 -86
- package/dist/schema/index.d.ts +0 -41
- package/dist/schema/index.js +0 -76
- package/dist/schema/queries.d.ts +0 -201
- package/dist/schema/queries.js +0 -144
- package/dist/schema/select.d.ts +0 -40
- package/dist/schema/select.js +0 -87
- package/dist/schema/serialize.d.ts +0 -115
- package/dist/schema/serialize.js +0 -262
- package/dist/schema/sugar.d.ts +0 -109
- package/dist/schema/sugar.js +0 -83
- package/dist/schema/syncDeltaRow.d.ts +0 -6
- package/dist/schema/syncDeltaRow.js +0 -6
- package/dist/server/adapter.d.ts +0 -173
- package/dist/server/adapter.js +0 -18
- package/dist/server/commit.d.ts +0 -107
- package/dist/server/commit.js +0 -1
- package/dist/server/index.d.ts +0 -14
- package/dist/server/index.js +0 -2
- package/dist/server/readConfig.d.ts +0 -80
- package/dist/server/readConfig.js +0 -8
- package/dist/server/storageMode.d.ts +0 -23
- package/dist/server/storageMode.js +0 -17
- package/dist/source/adapter.d.ts +0 -81
- package/dist/source/adapter.js +0 -22
- package/dist/source/adapters/drizzle.d.ts +0 -48
- package/dist/source/adapters/drizzle.js +0 -219
- package/dist/source/adapters/kysely.d.ts +0 -42
- package/dist/source/adapters/kysely.js +0 -205
- package/dist/source/adapters/kyselyMutationCore.d.ts +0 -76
- package/dist/source/adapters/kyselyMutationCore.js +0 -125
- package/dist/source/adapters/memory.d.ts +0 -13
- package/dist/source/adapters/memory.js +0 -130
- package/dist/source/adapters/prisma.d.ts +0 -63
- package/dist/source/adapters/prisma.js +0 -202
- package/dist/source/conformance.d.ts +0 -37
- package/dist/source/conformance.js +0 -215
- package/dist/source/connector.d.ts +0 -95
- package/dist/source/connector.js +0 -266
- package/dist/source/connectorProtocol.d.ts +0 -154
- package/dist/source/connectorProtocol.js +0 -163
- package/dist/source/contract.d.ts +0 -195
- package/dist/source/contract.js +0 -164
- package/dist/source/factory.d.ts +0 -92
- package/dist/source/factory.js +0 -286
- package/dist/source/footprint.d.ts +0 -111
- package/dist/source/footprint.js +0 -0
- package/dist/source/idempotency.d.ts +0 -61
- package/dist/source/idempotency.js +0 -144
- package/dist/source/index.d.ts +0 -23
- package/dist/source/index.js +0 -30
- package/dist/source/migrations.d.ts +0 -21
- package/dist/source/migrations.js +0 -103
- package/dist/source/next.d.ts +0 -32
- package/dist/source/next.js +0 -25
- package/dist/source/pushQueue.d.ts +0 -134
- package/dist/source/pushQueue.js +0 -256
- package/dist/source/signing.d.ts +0 -92
- package/dist/source/signing.js +0 -162
- package/dist/source/types.d.ts +0 -401
- package/dist/source/types.js +0 -59
- package/dist/stores/ObjectStore.d.ts +0 -115
- package/dist/stores/ObjectStore.js +0 -393
- package/dist/stores/ObjectStoreContract.d.ts +0 -38
- package/dist/stores/ObjectStoreContract.js +0 -1
- package/dist/stores/SyncActionStore.d.ts +0 -97
- package/dist/stores/SyncActionStore.js +0 -504
- package/dist/stores/syncAction.d.ts +0 -26
- package/dist/stores/syncAction.js +0 -16
- package/dist/surface.d.ts +0 -36
- package/dist/surface.js +0 -75
- package/dist/sync/BootstrapFetcher.d.ts +0 -280
- package/dist/sync/BootstrapFetcher.js +0 -962
- package/dist/sync/ConnectionManager.d.ts +0 -8
- package/dist/sync/ConnectionManager.js +0 -8
- package/dist/sync/OnDemandLoader.d.ts +0 -228
- package/dist/sync/OnDemandLoader.js +0 -742
- package/dist/sync/SubscriptionManager.d.ts +0 -159
- package/dist/sync/SubscriptionManager.js +0 -243
- package/dist/sync/SyncWebSocket.d.ts +0 -173
- package/dist/sync/SyncWebSocket.js +0 -438
- package/dist/sync/awaitClaimGrant.d.ts +0 -6
- package/dist/sync/awaitClaimGrant.js +0 -6
- package/dist/sync/bootstrapApply.d.ts +0 -70
- package/dist/sync/bootstrapApply.js +0 -73
- package/dist/sync/commitFrames.d.ts +0 -8
- package/dist/sync/commitFrames.js +0 -8
- package/dist/sync/contextPorts.d.ts +0 -18
- package/dist/sync/contextPorts.js +0 -31
- package/dist/sync/createClaimStream.d.ts +0 -7
- package/dist/sync/createClaimStream.js +0 -7
- package/dist/sync/createPresenceStream.d.ts +0 -69
- package/dist/sync/createPresenceStream.js +0 -200
- package/dist/sync/createSnapshot.d.ts +0 -29
- package/dist/sync/createSnapshot.js +0 -118
- package/dist/sync/credentialLifecycle.d.ts +0 -7
- package/dist/sync/credentialLifecycle.js +0 -7
- package/dist/sync/deltaPipeline.d.ts +0 -113
- package/dist/sync/deltaPipeline.js +0 -261
- package/dist/sync/groupChange.d.ts +0 -113
- package/dist/sync/groupChange.js +0 -242
- package/dist/sync/participants.d.ts +0 -115
- package/dist/sync/participants.js +0 -344
- package/dist/sync/persistedPrefix.d.ts +0 -12
- package/dist/sync/persistedPrefix.js +0 -22
- package/dist/sync/schemaDrift.d.ts +0 -55
- package/dist/sync/schemaDrift.js +0 -53
- package/dist/sync/schemas.d.ts +0 -70
- package/dist/sync/schemas.js +0 -94
- package/dist/sync/syncCursor.d.ts +0 -40
- package/dist/sync/syncCursor.js +0 -55
- package/dist/sync/syncPlan.d.ts +0 -54
- package/dist/sync/syncPlan.js +0 -50
- package/dist/sync/wsFrameHandlers.d.ts +0 -8
- package/dist/sync/wsFrameHandlers.js +0 -8
- 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/httpResponses.d.ts +0 -70
- package/dist/testing/fixtures/httpResponses.js +0 -90
- 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 -186
- 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 -72
- 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/transaction/ablo.d.ts +0 -88
- package/dist/transaction/ablo.js +0 -33
- package/dist/transaction/auth/apiKey.d.ts +0 -152
- package/dist/transaction/auth/apiKey.js +0 -419
- package/dist/transaction/auth/bootstrapScope.d.ts +0 -15
- package/dist/transaction/auth/bootstrapScope.js +0 -1
- package/dist/transaction/auth/capability.d.ts +0 -177
- package/dist/transaction/auth/capability.js +0 -199
- package/dist/transaction/auth/credentialEndpoint.d.ts +0 -61
- package/dist/transaction/auth/credentialEndpoint.js +0 -86
- package/dist/transaction/auth/credentialPolicy.d.ts +0 -148
- package/dist/transaction/auth/credentialPolicy.js +0 -125
- package/dist/transaction/auth/credentialSource.d.ts +0 -30
- package/dist/transaction/auth/credentialSource.js +0 -55
- package/dist/transaction/auth/hostedEndpoints.d.ts +0 -21
- package/dist/transaction/auth/hostedEndpoints.js +0 -21
- package/dist/transaction/auth/identity.d.ts +0 -55
- package/dist/transaction/auth/identity.js +0 -210
- package/dist/transaction/auth/index.d.ts +0 -162
- package/dist/transaction/auth/index.js +0 -304
- package/dist/transaction/auth/schemas.d.ts +0 -59
- package/dist/transaction/auth/schemas.js +0 -85
- package/dist/transaction/auth/sessionMint.d.ts +0 -28
- package/dist/transaction/auth/sessionMint.js +0 -85
- package/dist/transaction/coordination/awaitClaimGrant.d.ts +0 -49
- package/dist/transaction/coordination/awaitClaimGrant.js +0 -112
- package/dist/transaction/coordination/claimHeartbeatLoop.d.ts +0 -50
- package/dist/transaction/coordination/claimHeartbeatLoop.js +0 -88
- package/dist/transaction/coordination/claimMeta.d.ts +0 -49
- package/dist/transaction/coordination/claimMeta.js +0 -52
- package/dist/transaction/coordination/createClaimStream.d.ts +0 -64
- package/dist/transaction/coordination/createClaimStream.js +0 -475
- package/dist/transaction/coordination/events.d.ts +0 -74
- package/dist/transaction/coordination/events.js +0 -7
- package/dist/transaction/coordination/index.d.ts +0 -19
- package/dist/transaction/coordination/index.js +0 -44
- package/dist/transaction/coordination/locator.d.ts +0 -83
- package/dist/transaction/coordination/locator.js +0 -82
- package/dist/transaction/coordination/schema.d.ts +0 -1473
- package/dist/transaction/coordination/schema.js +0 -1013
- package/dist/transaction/coordination/targetConflict.d.ts +0 -2
- package/dist/transaction/coordination/targetConflict.js +0 -103
- package/dist/transaction/coordination/trace.d.ts +0 -78
- package/dist/transaction/coordination/trace.js +0 -138
- package/dist/transaction/durableWrites.d.ts +0 -62
- package/dist/transaction/durableWrites.js +0 -71
- package/dist/transaction/environment.d.ts +0 -105
- package/dist/transaction/environment.js +0 -108
- package/dist/transaction/errorCodes.d.ts +0 -403
- package/dist/transaction/errorCodes.js +0 -480
- package/dist/transaction/errors.d.ts +0 -428
- package/dist/transaction/errors.js +0 -686
- package/dist/transaction/index.d.ts +0 -20
- package/dist/transaction/index.js +0 -20
- package/dist/transaction/keys/index.d.ts +0 -87
- package/dist/transaction/keys/index.js +0 -207
- package/dist/transaction/log/syncDeltaRow.d.ts +0 -158
- package/dist/transaction/log/syncDeltaRow.js +0 -95
- package/dist/transaction/logPosition.d.ts +0 -97
- package/dist/transaction/logPosition.js +0 -125
- package/dist/transaction/logger.d.ts +0 -16
- package/dist/transaction/logger.js +0 -7
- package/dist/transaction/observability.d.ts +0 -53
- package/dist/transaction/observability.js +0 -19
- package/dist/transaction/persistence.d.ts +0 -12
- package/dist/transaction/persistence.js +0 -11
- package/dist/transaction/plugin.d.ts +0 -192
- package/dist/transaction/plugin.js +0 -87
- package/dist/transaction/policy/types.d.ts +0 -217
- package/dist/transaction/policy/types.js +0 -126
- package/dist/transaction/resources/functionalUpdate.d.ts +0 -79
- package/dist/transaction/resources/functionalUpdate.js +0 -87
- package/dist/transaction/resources/httpResources.d.ts +0 -266
- package/dist/transaction/resources/httpResources.js +0 -7
- package/dist/transaction/resources/modelOperations.d.ts +0 -319
- package/dist/transaction/resources/modelOperations.js +0 -12
- package/dist/transaction/resources/mutationOptions.d.ts +0 -66
- package/dist/transaction/resources/mutationOptions.js +0 -9
- package/dist/transaction/resources/where.d.ts +0 -85
- package/dist/transaction/resources/where.js +0 -70
- package/dist/transaction/resources/writeOptionsSchema.d.ts +0 -47
- package/dist/transaction/resources/writeOptionsSchema.js +0 -73
- package/dist/transaction/schema/field.d.ts +0 -126
- package/dist/transaction/schema/field.js +0 -265
- package/dist/transaction/schema/loadStrategy.d.ts +0 -45
- package/dist/transaction/schema/loadStrategy.js +0 -46
- package/dist/transaction/schema/model.d.ts +0 -379
- package/dist/transaction/schema/model.js +0 -123
- package/dist/transaction/schema/openapi.d.ts +0 -57
- package/dist/transaction/schema/openapi.js +0 -340
- package/dist/transaction/schema/relation.d.ts +0 -199
- package/dist/transaction/schema/relation.js +0 -104
- package/dist/transaction/schema/residency.d.ts +0 -29
- package/dist/transaction/schema/residency.js +0 -25
- package/dist/transaction/schema/roles.d.ts +0 -249
- package/dist/transaction/schema/roles.js +0 -230
- package/dist/transaction/schema/schema.d.ts +0 -324
- package/dist/transaction/schema/schema.js +0 -305
- package/dist/transaction/schema/tenancy.d.ts +0 -139
- package/dist/transaction/schema/tenancy.js +0 -190
- package/dist/transaction/transactionLayer.d.ts +0 -82
- package/dist/transaction/transactionLayer.js +0 -24
- package/dist/transaction/transactions/settlement/commitEnvelope.d.ts +0 -143
- package/dist/transaction/transactions/settlement/commitEnvelope.js +0 -161
- package/dist/transaction/transactions/settlement/httpCommitEnvelope.d.ts +0 -53
- package/dist/transaction/transactions/settlement/httpCommitEnvelope.js +0 -207
- package/dist/transaction/transactions/settlement/idempotencyKey.d.ts +0 -10
- package/dist/transaction/transactions/settlement/idempotencyKey.js +0 -9
- package/dist/transaction/transactions/settlement/pendingWrite.d.ts +0 -112
- package/dist/transaction/transactions/settlement/pendingWrite.js +0 -20
- package/dist/transaction/transport/commitFrames.d.ts +0 -90
- package/dist/transaction/transport/commitFrames.js +0 -134
- package/dist/transaction/transport/connectionManager.d.ts +0 -215
- package/dist/transaction/transport/connectionManager.js +0 -673
- package/dist/transaction/transport/credentialLifecycle.d.ts +0 -177
- package/dist/transaction/transport/credentialLifecycle.js +0 -324
- package/dist/transaction/transport/heartbeat.d.ts +0 -65
- package/dist/transaction/transport/heartbeat.js +0 -93
- package/dist/transaction/transport/httpClient.d.ts +0 -123
- package/dist/transaction/transport/httpClient.js +0 -145
- package/dist/transaction/transport/httpOptions.d.ts +0 -33
- package/dist/transaction/transport/httpOptions.js +0 -12
- package/dist/transaction/transport/httpTransport.d.ts +0 -8
- package/dist/transaction/transport/httpTransport.js +0 -1276
- package/dist/transaction/transport/networkProbe.d.ts +0 -84
- package/dist/transaction/transport/networkProbe.js +0 -207
- package/dist/transaction/transport/wsFrameHandlers.d.ts +0 -128
- package/dist/transaction/transport/wsFrameHandlers.js +0 -429
- package/dist/transaction/transport/wsTransport.d.ts +0 -576
- package/dist/transaction/transport/wsTransport.js +0 -1017
- package/dist/transaction/types/assertExact.d.ts +0 -17
- package/dist/transaction/types/assertExact.js +0 -1
- package/dist/transaction/types/global.d.ts +0 -107
- package/dist/transaction/types/global.js +0 -40
- package/dist/transaction/types/index.d.ts +0 -205
- package/dist/transaction/types/index.js +0 -56
- package/dist/transaction/types/modelData.d.ts +0 -10
- package/dist/transaction/types/modelData.js +0 -9
- package/dist/transaction/types/participant.d.ts +0 -20
- package/dist/transaction/types/participant.js +0 -10
- package/dist/transaction/types/streams.d.ts +0 -540
- package/dist/transaction/types/streams.js +0 -11
- package/dist/transaction/utils/asyncIterator.d.ts +0 -34
- package/dist/transaction/utils/asyncIterator.js +0 -135
- package/dist/transaction/utils/duration.d.ts +0 -25
- package/dist/transaction/utils/duration.js +0 -45
- package/dist/transaction/utils/json.d.ts +0 -57
- package/dist/transaction/utils/json.js +0 -276
- package/dist/transaction/wire/accountResponses.d.ts +0 -351
- package/dist/transaction/wire/accountResponses.js +0 -255
- package/dist/transaction/wire/auth.d.ts +0 -49
- package/dist/transaction/wire/auth.js +0 -57
- package/dist/transaction/wire/bootstrapReason.d.ts +0 -9
- package/dist/transaction/wire/bootstrapReason.js +0 -8
- package/dist/transaction/wire/claimEvent.d.ts +0 -76
- package/dist/transaction/wire/claimEvent.js +0 -73
- package/dist/transaction/wire/claims.d.ts +0 -463
- package/dist/transaction/wire/claims.js +0 -229
- package/dist/transaction/wire/commit.d.ts +0 -603
- package/dist/transaction/wire/commit.js +0 -321
- package/dist/transaction/wire/delta.d.ts +0 -250
- package/dist/transaction/wire/delta.js +0 -147
- package/dist/transaction/wire/errorEnvelope.d.ts +0 -72
- package/dist/transaction/wire/errorEnvelope.js +0 -123
- package/dist/transaction/wire/feedCursor.d.ts +0 -60
- package/dist/transaction/wire/feedCursor.js +0 -82
- package/dist/transaction/wire/feedEvent.d.ts +0 -177
- package/dist/transaction/wire/feedEvent.js +0 -39
- package/dist/transaction/wire/frames.d.ts +0 -194
- package/dist/transaction/wire/frames.js +0 -50
- package/dist/transaction/wire/inboundFrames.d.ts +0 -552
- package/dist/transaction/wire/inboundFrames.js +0 -116
- package/dist/transaction/wire/index.d.ts +0 -50
- package/dist/transaction/wire/index.js +0 -74
- package/dist/transaction/wire/listEnvelope.d.ts +0 -37
- package/dist/transaction/wire/listEnvelope.js +0 -42
- package/dist/transaction/wire/modelResponses.d.ts +0 -85
- package/dist/transaction/wire/modelResponses.js +0 -43
- package/dist/transaction/wire/protocol.d.ts +0 -38
- package/dist/transaction/wire/protocol.js +0 -38
- package/dist/transaction/wire/protocolVersion.d.ts +0 -73
- package/dist/transaction/wire/protocolVersion.js +0 -83
- package/dist/transactions/mutations/MutationQueue.d.ts +0 -655
- package/dist/transactions/mutations/MutationQueue.js +0 -2797
- package/dist/transactions/mutations/MutationStore.d.ts +0 -20
- package/dist/transactions/mutations/MutationStore.js +0 -53
- package/dist/transactions/mutations/UnconfirmedWrites.d.ts +0 -82
- package/dist/transactions/mutations/UnconfirmedWrites.js +0 -104
- package/dist/transactions/mutations/coalesceRules.d.ts +0 -58
- package/dist/transactions/mutations/coalesceRules.js +0 -140
- package/dist/transactions/mutations/commitLatency.d.ts +0 -52
- package/dist/transactions/mutations/commitLatency.js +0 -130
- package/dist/transactions/mutations/commitOutboxStore.d.ts +0 -28
- package/dist/transactions/mutations/commitOutboxStore.js +0 -26
- package/dist/transactions/mutations/commitPayload.d.ts +0 -164
- package/dist/transactions/mutations/commitPayload.js +0 -152
- package/dist/transactions/mutations/deltaConfirmation.d.ts +0 -59
- package/dist/transactions/mutations/deltaConfirmation.js +0 -233
- package/dist/transactions/mutations/durableWriteStore.d.ts +0 -14
- package/dist/transactions/mutations/durableWriteStore.js +0 -12
- package/dist/transactions/mutations/optimisticApply.d.ts +0 -49
- package/dist/transactions/mutations/optimisticApply.js +0 -65
- package/dist/transactions/mutations/replayValidation.d.ts +0 -186
- package/dist/transactions/mutations/replayValidation.js +0 -163
- package/dist/utils/mobxSetup.d.ts +0 -53
- package/dist/utils/mobxSetup.js +0 -330
- package/dist/webhooks/events.d.ts +0 -43
- package/dist/webhooks/events.js +0 -42
- package/dist/webhooks/index.d.ts +0 -8
- package/dist/webhooks/index.js +0 -8
- package/dist/wire/index.d.ts +0 -1
- package/dist/wire/index.js +0 -8
- package/docs/interaction-model.md +0 -99
package/docs/deployment.md
CHANGED
|
@@ -57,10 +57,10 @@ A **plane** is the isolation unit a credential acts on. `production` is the root
|
|
|
57
57
|
plane; every sandbox sits beside it. Three things are per-plane, and knowing
|
|
58
58
|
which three is most of what production readiness means:
|
|
59
59
|
|
|
60
|
-
- **Rows
|
|
61
|
-
- **The registered database
|
|
60
|
+
- **Rows:** a sandbox write is invisible to production and to every other sandbox.
|
|
61
|
+
- **The registered database:** one per plane, so your production database and
|
|
62
62
|
your dev database are separate registrations.
|
|
63
|
-
- **The active schema artifact
|
|
63
|
+
- **The active schema artifact:** the model shapes the engine actually routes on.
|
|
64
64
|
|
|
65
65
|
A key's plane is fixed at mint and spelled in its prefix: `sk_live_` acts on
|
|
66
66
|
production, `sk_test_` on a sandbox. There is no runtime override — the
|
|
@@ -219,14 +219,14 @@ handler, the Standard Webhooks signature, and rolling a secret.
|
|
|
219
219
|
|
|
220
220
|
## What to watch once it is live
|
|
221
221
|
|
|
222
|
-
- **`ablo logs
|
|
222
|
+
- **`ablo logs`:** commit activity as it happens, scoped by the key, so a live
|
|
223
223
|
key streams the org and a test key streams only its sandbox. `--json` emits
|
|
224
224
|
NDJSON for piping.
|
|
225
|
-
- **`ablo status
|
|
225
|
+
- **`ablo status`:** the readiness verdict. Cheap enough to run from a health
|
|
226
226
|
check on your own side.
|
|
227
|
-
- **The [audit log](./audit.md)
|
|
227
|
+
- **The [audit log](./audit.md):** every confirmed write traced back to the key
|
|
228
228
|
that made it and the person who authorized that key.
|
|
229
|
-
- **Your own logger
|
|
229
|
+
- **Your own logger:** pass `logger` to the client and SDK lifecycle, sync,
|
|
230
230
|
retry, and rollback events join your existing pipeline.
|
|
231
231
|
|
|
232
232
|
Writes carry receipts rather than being fire-and-forget: a commit is accepted the
|
|
@@ -242,7 +242,7 @@ and what each promises.
|
|
|
242
242
|
| `password authentication failed` during connect | Often a pooled host refusing a session it cannot serve, in the words of a wrong password. | Register the direct database host. |
|
|
243
243
|
| `server_execute_unknown_model` | The plane's active schema does not carry that model. | `ablo push` with a key for that plane. |
|
|
244
244
|
| Clients rejected at connect | The deployed schema and the client's schema disagree. | Push this tree, or deploy the revision the server is running. |
|
|
245
|
-
| `project_scope_denied` (403) | The model belongs to another project in your org. | Use a key minted for that project
|
|
245
|
+
| `project_scope_denied` (403) | The model belongs to another project in your org. | Use a key minted for that project: a push cannot cross projects. |
|
|
246
246
|
| 403 on `ablo push` | The key authenticated but cannot author schema. | A secret `sk_live_`; the `ablo login` live key is observe-only. |
|
|
247
247
|
|
|
248
248
|
## The checklist
|
|
@@ -25,7 +25,7 @@ a typed error if the row moved underneath you while the agent was busy.
|
|
|
25
25
|
## Schema-Backed Worker
|
|
26
26
|
|
|
27
27
|
The worker uses the same schema client the app uses. It reads the task from the
|
|
28
|
-
server with `
|
|
28
|
+
server with `get({ id })`, claims the row, and writes through
|
|
29
29
|
`ablo.tasks.update(...)` with a stale-check so a concurrent edit can't be
|
|
30
30
|
overwritten.
|
|
31
31
|
|
|
@@ -49,8 +49,8 @@ const ablo = Ablo({
|
|
|
49
49
|
export async function markDone(taskId: string) {
|
|
50
50
|
await ablo.ready();
|
|
51
51
|
|
|
52
|
-
//
|
|
53
|
-
const task = await ablo.tasks.
|
|
52
|
+
// get({ id }) is an async server read — await it.
|
|
53
|
+
const task = await ablo.tasks.get({ id: taskId });
|
|
54
54
|
if (!task) return { status: 'not_found' };
|
|
55
55
|
|
|
56
56
|
try {
|
|
@@ -109,7 +109,7 @@ Keep workers on the same schema-backed client as the app.
|
|
|
109
109
|
import { useAblo } from '@abloatai/ablo/react';
|
|
110
110
|
|
|
111
111
|
export function TaskRow({ task: serverTask }: Props) {
|
|
112
|
-
const data = useAblo((ablo) => ablo.tasks.local.
|
|
112
|
+
const data = useAblo((ablo) => ablo.tasks.local.get(serverTask.id)) ?? serverTask;
|
|
113
113
|
const holder = useAblo((ablo) => ablo.tasks.claim.state({ id: serverTask.id }));
|
|
114
114
|
const agentActive = holder?.participantKind === 'agent';
|
|
115
115
|
|
|
@@ -54,7 +54,7 @@ const updateTask = tool({
|
|
|
54
54
|
await ablo.ready();
|
|
55
55
|
|
|
56
56
|
// retrieve hits the server for the latest row (async — await it).
|
|
57
|
-
const task = await ablo.tasks.
|
|
57
|
+
const task = await ablo.tasks.get({ id: taskId });
|
|
58
58
|
if (!task) return { ok: false, reason: 'not_found' };
|
|
59
59
|
|
|
60
60
|
// If another agent already holds this row, claim waits for them to finish,
|
|
@@ -87,13 +87,24 @@ browser only ever sees the short-lived token:
|
|
|
87
87
|
```ts
|
|
88
88
|
// web/app/api/ablo-session/route.ts
|
|
89
89
|
import { ablo } from '@/ablo';
|
|
90
|
+
import { credentialEndpointSuccessSchema } from '@abloatai/ablo/auth';
|
|
90
91
|
|
|
91
92
|
export const runtime = 'nodejs';
|
|
92
93
|
|
|
93
94
|
export async function POST() {
|
|
94
95
|
const userId = await currentUserId(); // your auth
|
|
95
|
-
const { token } = await ablo.sessions.create({
|
|
96
|
-
|
|
96
|
+
const { token, expiresAt } = await ablo.sessions.create({
|
|
97
|
+
user: { id: userId },
|
|
98
|
+
can: { tasks: ['read', 'update'] },
|
|
99
|
+
});
|
|
100
|
+
return Response.json(
|
|
101
|
+
credentialEndpointSuccessSchema.parse({
|
|
102
|
+
token,
|
|
103
|
+
expiresAt,
|
|
104
|
+
credentialKind: 'ephemeral',
|
|
105
|
+
}),
|
|
106
|
+
{ headers: { 'Cache-Control': 'no-store' } },
|
|
107
|
+
);
|
|
97
108
|
}
|
|
98
109
|
```
|
|
99
110
|
|
|
@@ -112,7 +123,7 @@ export function ReportRow({
|
|
|
112
123
|
}: {
|
|
113
124
|
report: { id: string; location: string; status: string };
|
|
114
125
|
}) {
|
|
115
|
-
const report = useAblo((ablo) => ablo.weatherReports.local.
|
|
126
|
+
const report = useAblo((ablo) => ablo.weatherReports.local.get(serverReport.id)) ?? serverReport;
|
|
116
127
|
const active = useAblo((ablo) => ablo.weatherReports.claim.state({ id: serverReport.id }));
|
|
117
128
|
const claimed = Boolean(active);
|
|
118
129
|
|
|
@@ -275,7 +286,7 @@ and timestamp. If the change originated from an Ablo commit, include the same
|
|
|
275
286
|
Agents use the same model API as the UI:
|
|
276
287
|
|
|
277
288
|
```ts
|
|
278
|
-
const report = await ablo.weatherReports.
|
|
289
|
+
const report = await ablo.weatherReports.get({ id: reportId });
|
|
279
290
|
const snap = ablo.snapshot({ weatherReports: reportId });
|
|
280
291
|
|
|
281
292
|
await ablo.weatherReports.update({
|
package/docs/examples/nextjs.md
CHANGED
|
@@ -64,13 +64,34 @@ The browser can't hold `sk_`, so a backend route mints a scoped, short-lived
|
|
|
64
64
|
// app/api/ablo-session/route.ts
|
|
65
65
|
import { ablo } from '@/lib/ablo';
|
|
66
66
|
import { getCurrentUser } from '@/auth';
|
|
67
|
+
import {
|
|
68
|
+
credentialEndpointErrorSchema,
|
|
69
|
+
credentialEndpointSuccessSchema,
|
|
70
|
+
} from '@abloatai/ablo/auth';
|
|
67
71
|
|
|
68
72
|
export async function POST() {
|
|
69
73
|
const user = await getCurrentUser();
|
|
70
|
-
if (!user)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
if (!user) {
|
|
75
|
+
return Response.json(
|
|
76
|
+
credentialEndpointErrorSchema.parse({
|
|
77
|
+
error: { code: 'session_expired' },
|
|
78
|
+
}),
|
|
79
|
+
{ status: 401, headers: { 'Cache-Control': 'no-store' } },
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const { token, expiresAt } = await ablo.sessions.create({
|
|
84
|
+
user: { id: user.id },
|
|
85
|
+
can: { tasks: ['read', 'create', 'update'] },
|
|
86
|
+
});
|
|
87
|
+
return Response.json(
|
|
88
|
+
credentialEndpointSuccessSchema.parse({
|
|
89
|
+
token,
|
|
90
|
+
expiresAt,
|
|
91
|
+
credentialKind: 'ephemeral',
|
|
92
|
+
}),
|
|
93
|
+
{ headers: { 'Cache-Control': 'no-store' } },
|
|
94
|
+
);
|
|
74
95
|
}
|
|
75
96
|
```
|
|
76
97
|
|
|
@@ -124,7 +145,7 @@ export default async function TaskPage({
|
|
|
124
145
|
}: { params: Promise<{ id: string }> }) {
|
|
125
146
|
const { id } = await params;
|
|
126
147
|
await ablo.ready();
|
|
127
|
-
const task = await ablo.tasks.
|
|
148
|
+
const task = await ablo.tasks.get({ id });
|
|
128
149
|
if (!task) return null;
|
|
129
150
|
|
|
130
151
|
return <TaskEditor task={task} />;
|
|
@@ -167,7 +188,7 @@ you — re-fetch and retry.
|
|
|
167
188
|
import { useAblo } from '@abloatai/ablo/react';
|
|
168
189
|
|
|
169
190
|
export function TaskEditor({ task: serverTask }: Props) {
|
|
170
|
-
const data = useAblo((ablo) => ablo.tasks.local.
|
|
191
|
+
const data = useAblo((ablo) => ablo.tasks.local.get(serverTask.id)) ?? serverTask;
|
|
171
192
|
const holder = useAblo((ablo) => ablo.tasks.claim.state({ id: serverTask.id }));
|
|
172
193
|
const busy = Boolean(holder);
|
|
173
194
|
|
|
@@ -15,7 +15,7 @@ The three steps below show how to declare it, scope the agent, and write.
|
|
|
15
15
|
|
|
16
16
|
See [Identity & Sync Groups](../identity.md) for the full reference.
|
|
17
17
|
|
|
18
|
-
## 1. Schema
|
|
18
|
+
## 1. Schema: declare the relationship, once
|
|
19
19
|
|
|
20
20
|
```ts
|
|
21
21
|
import { defineSchema, identityRole, model, relation, z } from '@abloatai/ablo/schema';
|
|
@@ -44,7 +44,7 @@ export const schema = defineSchema(
|
|
|
44
44
|
);
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
## 2. Dispatch
|
|
47
|
+
## 2. Dispatch: narrow the agent to the workspace it's working on
|
|
48
48
|
|
|
49
49
|
An agent can never reach more than the user who triggered it — that's the upper
|
|
50
50
|
limit. From there you narrow it to a single workspace by minting the agent's session
|
|
@@ -95,7 +95,7 @@ const ablo = Ablo({
|
|
|
95
95
|
groups the session asks for with the groups the identity is actually allowed, so
|
|
96
96
|
the agent can never reach a workspace its triggering user couldn't.
|
|
97
97
|
|
|
98
|
-
## 3. Write
|
|
98
|
+
## 3. Write: it fans out to everyone on that workspace
|
|
99
99
|
|
|
100
100
|
Inside any component under the provider, grab the scoped client with `useAblo()`
|
|
101
101
|
and write. The connection is already narrowed to `workspace:<workspaceId>` from Step 2.
|
|
@@ -38,7 +38,7 @@ const ablo = Ablo({
|
|
|
38
38
|
export async function completeTask(taskId: string) {
|
|
39
39
|
await ablo.ready();
|
|
40
40
|
|
|
41
|
-
const task = await ablo.tasks.
|
|
41
|
+
const task = await ablo.tasks.get({ id: taskId });
|
|
42
42
|
if (!task) return { status: 'not_found' };
|
|
43
43
|
|
|
44
44
|
await using claim = await ablo.tasks.claim({
|
|
@@ -58,7 +58,7 @@ export async function completeTask(taskId: string) {
|
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
`
|
|
61
|
+
`get({ id })` is an async server read — it hits the server and returns the
|
|
62
62
|
row (or `undefined`, which the early `not_found` guard handles). The update runs
|
|
63
63
|
while the claim is held, and `wait: 'confirmed'` makes it resolve only once your
|
|
64
64
|
database has confirmed the row landed.
|
package/docs/groups.md
CHANGED
|
@@ -38,6 +38,56 @@ never persists work built on a premise it can no longer see.
|
|
|
38
38
|
|
|
39
39
|
---
|
|
40
40
|
|
|
41
|
+
## How you hear about it
|
|
42
|
+
|
|
43
|
+
Four channels carry "something changed", and they answer four different
|
|
44
|
+
questions. Pick by the question you have.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// A screen that stays current.
|
|
48
|
+
ablo.documents.onChange((docs) => render(docs));
|
|
49
|
+
|
|
50
|
+
// Who else is in here, and what are they holding.
|
|
51
|
+
await using room = await ablo.documents.join(documentIds, { ttl: '5m' });
|
|
52
|
+
room.peers;
|
|
53
|
+
|
|
54
|
+
// Stop this write if the thing I read moved while I composed it.
|
|
55
|
+
await ablo.blocks.update({ id, data, reads: [{ group: 'workspace:abc', readAt, onStale: 'notify' }] });
|
|
56
|
+
|
|
57
|
+
// Tell me later if this moves, even though I am not writing now.
|
|
58
|
+
await ablo.documents.track({ id: 's-1' });
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Question | Channel | Arrives |
|
|
62
|
+
| --- | --- | --- |
|
|
63
|
+
| What do the rows say right now? | `onChange` | As deltas land, on the socket |
|
|
64
|
+
| Who else is working here? | `join`, then `room.peers` and `room.claims` | As participants come and go, on the socket |
|
|
65
|
+
| Did the premise for **this** write move? | `reads` on the write | On that write's receipt, before it applies |
|
|
66
|
+
| Has anything I read moved since? | `track` | On your next commit's receipt |
|
|
67
|
+
|
|
68
|
+
Two distinctions do most of the work here.
|
|
69
|
+
|
|
70
|
+
**`join` is about people; `track` is about data.** Both open a subscription and
|
|
71
|
+
both are scoped by sync group, which is why they look alike. `join` reports
|
|
72
|
+
participants: who is present, what they are doing, which rows they hold. `track`
|
|
73
|
+
reports the rows themselves: something you said you cared about moved, here is
|
|
74
|
+
the watermark to re-read it at. A tool that wants to avoid duplicating a peer's
|
|
75
|
+
work needs `join`. A tool whose output goes stale when its inputs change needs
|
|
76
|
+
`track`.
|
|
77
|
+
|
|
78
|
+
**`reads` guards one write; `track` outlives it.** They speak the same
|
|
79
|
+
vocabulary and produce the same `StaleNotification`. A `reads` entry is checked
|
|
80
|
+
once, at the commit that carried it, and discarded. A `track` is persisted and
|
|
81
|
+
re-checked against every delta after it, so a long-running actor hears about a
|
|
82
|
+
change that landed while it was thinking, on the next commit it makes.
|
|
83
|
+
|
|
84
|
+
`onChange` and `join` need a live socket, so they are available on the default
|
|
85
|
+
WebSocket client. `reads` and `track` ride the commit, so they reach a socketless
|
|
86
|
+
actor over HTTP too, which is what makes them the notification path for agents
|
|
87
|
+
and workers.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
41
91
|
## Three ways a change reaches other rows
|
|
42
92
|
|
|
43
93
|
"A affects B and C" means three different things. The engine does the first two
|
|
@@ -206,8 +256,12 @@ them coarse everywhere else.
|
|
|
206
256
|
|
|
207
257
|
## Where this is defined
|
|
208
258
|
|
|
209
|
-
- **Access
|
|
210
|
-
|
|
259
|
+
- **Access**, meaning who may read or write a group, is
|
|
260
|
+
[`identity.md`](./identity.md).
|
|
261
|
+
- **The convention** behind non-coercion, the premise, and the notification is
|
|
211
262
|
[`concurrency-convention.md`](./concurrency-convention.md) (§4 and §5).
|
|
212
|
-
- **The mechanics
|
|
263
|
+
- **The mechanics**, the three coordination blocks underneath, are
|
|
213
264
|
[`coordination.md`](./coordination.md).
|
|
265
|
+
- **`join` and presence**, the participant half of the table above, are
|
|
266
|
+
[`coordination.md`](./coordination.md) for the claim stream and
|
|
267
|
+
[`react.md`](./react.md) for `useJoin`.
|
package/docs/guarantees.md
CHANGED
|
@@ -65,11 +65,13 @@ await ablo.weatherReports.update({
|
|
|
65
65
|
`onStale: 'reject'` prevents lost updates. If the target changed after the
|
|
66
66
|
snapshot, the server rejects the write instead of applying stale reasoning.
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
Two other dispositions exist. `overwrite` applies the write with no stale check
|
|
69
|
+
at all. `notify` **holds** the write, so the row is left as it stands, and hands
|
|
70
|
+
back a `StaleNotification` carrying the current value for the actor to reconcile
|
|
71
|
+
and re-issue; the rest of the batch still commits.
|
|
69
72
|
|
|
70
|
-
-
|
|
71
|
-
|
|
72
|
-
- `notify` accepts the write and marks it for product review.
|
|
73
|
+
See [Concurrency Convention](./concurrency-convention.md) for the full taxonomy,
|
|
74
|
+
what each disposition is checked against, and where the convention stops.
|
|
73
75
|
|
|
74
76
|
## Claim Coordination
|
|
75
77
|
|
|
@@ -99,14 +101,39 @@ Agents should import the same schema as the app and write through
|
|
|
99
101
|
|
|
100
102
|
## Audit Trail
|
|
101
103
|
|
|
102
|
-
|
|
104
|
+
Attribution is not a separate log you opt into. It rides on the change itself.
|
|
105
|
+
Every broadcast delta names the actor, the authority it acted under, the
|
|
106
|
+
credential that authorized it, and the approval stage it was in:
|
|
103
107
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
```ts
|
|
109
|
+
{
|
|
110
|
+
modelName: 'weatherReports',
|
|
111
|
+
modelId: 'report_stockholm',
|
|
112
|
+
actionType: 'U',
|
|
113
|
+
actor: { kind: 'agent', id: 'weather-agent-v3' },
|
|
114
|
+
onBehalfOf: { kind: 'user', id: 'user_8f2a' },
|
|
115
|
+
capabilityId: '…', // the key the write was authorized by
|
|
116
|
+
confirmationState: 'auto', // previewed | approved | required_human_approval
|
|
117
|
+
createdAt: '2026-05-14T14:22:01.034Z',
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`actor` and `onBehalfOf` are derived from the credential, not from the call site,
|
|
122
|
+
so an agent cannot name a different actor in its own write. `capabilityId` is
|
|
123
|
+
non-null for every agent and system commit, so a write can always be traced to
|
|
124
|
+
the key that made it, and from that key to the person it was issued to.
|
|
125
|
+
|
|
126
|
+
The stored history goes one step further than recording. Audit rows are chained
|
|
127
|
+
with a keyed hash, so the log is tamper-*evident*: `verify-chain` walks the chain
|
|
128
|
+
and, if it breaks, names the sequence number and the hashes that disagree. No
|
|
129
|
+
chain roots at an agent. The delegation root is always the person who set the
|
|
130
|
+
work in motion.
|
|
131
|
+
|
|
132
|
+
For agent work this is what answers, after the fact: what changed, who authorized
|
|
133
|
+
it, which run did it, and whether a human was in the loop.
|
|
107
134
|
|
|
108
|
-
|
|
109
|
-
|
|
135
|
+
See [Audit Log](./audit.md) for the stored row shape, the filters, verification,
|
|
136
|
+
and export.
|
|
110
137
|
|
|
111
138
|
## Persistence
|
|
112
139
|
|
package/docs/how-it-works.md
CHANGED
|
@@ -10,16 +10,16 @@ whole model — everything below explains what it means and how to use it.
|
|
|
10
10
|
await ablo.tasks.update({ id: 'task_42', data: { status: 'done' }, wait: 'confirmed' });
|
|
11
11
|
|
|
12
12
|
// Reads come back live, kept current from your database.
|
|
13
|
-
const task = ablo.tasks.local.
|
|
13
|
+
const task = ablo.tasks.local.get('task_42');
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
## The mental model
|
|
16
|
+
## The mental model: read this once
|
|
17
17
|
|
|
18
18
|
Ablo is a **coordination layer in front of your Postgres**. Agents, background
|
|
19
19
|
jobs, and the people alongside them all change the same application data through
|
|
20
20
|
one API, and Ablo makes sure their writes don't clobber each other.
|
|
21
21
|
|
|
22
|
-
- **Writes go through Ablo
|
|
22
|
+
- **Writes go through Ablo:** `ablo.<model>.create / update / delete` enter Ablo's
|
|
23
23
|
commit chokepoint — where claims, ordering, and idempotency are enforced — and
|
|
24
24
|
Ablo applies the change to your Postgres through a scoped writer role. The commit
|
|
25
25
|
is accepted (`queued`) the moment Ablo takes it.
|
|
@@ -37,17 +37,41 @@ one API, and Ablo makes sure their writes don't clobber each other.
|
|
|
37
37
|
That's the shape: **you write through Ablo → it lands in your Postgres → the WAL
|
|
38
38
|
echo confirms it → everyone connected sees it live.**
|
|
39
39
|
|
|
40
|
+
## The primitives
|
|
41
|
+
|
|
42
|
+
| Primitive | Plane | Purpose |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `Schema` | State | Declares typed models the app and agents can read and write. |
|
|
45
|
+
| `Model` | State | The generated `ablo.<model>` model. Use `retrieve`/`list` (async reads), `local.get`/`local.list`/`local.count` (the same verbs, synchronous and local-only), `create`, `update`, and `delete`. |
|
|
46
|
+
| `Claim` | Coordination | Who is working on a target. Taken via `ablo.<model>.claim({ id })` and read via `ablo.<model>.claim.state({ id })`. Ephemeral, never persisted. |
|
|
47
|
+
| `Commit` | Protocol | The durable write underneath model updates. Most users do not call it directly. |
|
|
48
|
+
| `Receipt` | Protocol | The lower-level durable result for custom runtimes. Schema writes use `wait: 'confirmed'`. |
|
|
49
|
+
|
|
50
|
+
### Why each primitive is separate
|
|
51
|
+
|
|
52
|
+
Why are `Claim`, `Commit`, and `Receipt` separate things instead of one? Each
|
|
53
|
+
does a job the others cannot. If you are coming from Replicache or Yjs you would
|
|
54
|
+
expect just `Commit`. Here is what the other two buy you over that minimum:
|
|
55
|
+
|
|
56
|
+
- **`Claim` is not a read lock.** Reads stay open. Claims serialize
|
|
57
|
+
acting-on-the-row, so slow work can wait in FIFO order, re-read, and write
|
|
58
|
+
from fresh state.
|
|
59
|
+
- **`Receipt` is not a `200 OK`.** It is the durable artifact a commit produced:
|
|
60
|
+
accepted commit id, server-assigned timestamps, stale-check outcome. It is
|
|
61
|
+
addressable after the fact and replayable into a different client. A status
|
|
62
|
+
code cannot be re-read by a sub-agent that was not on the original call.
|
|
63
|
+
|
|
40
64
|
## Where your data lives
|
|
41
65
|
|
|
42
66
|
You point Ablo at a Postgres database, and that's where its rows live. Only *which*
|
|
43
67
|
database differs by environment — the code is identical.
|
|
44
68
|
|
|
45
|
-
- **Production
|
|
69
|
+
- **Production:** your Postgres. `ablo connect` sets up a scoped writer role and
|
|
46
70
|
logical replication; your rows live in your database, and Ablo writes to them
|
|
47
71
|
through that role.
|
|
48
|
-
- **Sandbox and local dev
|
|
72
|
+
- **Sandbox and local dev:** a separate or local Postgres you can throw away. Same
|
|
49
73
|
models, same code, a different database behind them.
|
|
50
|
-
- **Before you connect one
|
|
74
|
+
- **Before you connect one.** Ablo keeps state in its own log, so you can build the
|
|
51
75
|
whole app today and point it at a real database when you're ready.
|
|
52
76
|
|
|
53
77
|
Registering the database is the whole switch. There is no tier or flag to choose.
|
|
@@ -82,13 +106,13 @@ export const ablo = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
|
|
|
82
106
|
await ablo.tasks.update({ id: 'task_42', data: { status: 'done' }, wait: 'confirmed' });
|
|
83
107
|
|
|
84
108
|
// 6. Read — live, no fetch loop.
|
|
85
|
-
const task = ablo.tasks.local.
|
|
109
|
+
const task = ablo.tasks.local.get('task_42');
|
|
86
110
|
|
|
87
111
|
// 7. Coordinate when more than one actor can touch a row. Hold a claim and Ablo
|
|
88
112
|
// serializes writes on that key against everyone else; read after claiming,
|
|
89
113
|
// then write. The lease releases automatically at the end of the scope.
|
|
90
114
|
await using _hold = await ablo.tasks.claim('task_42');
|
|
91
|
-
const latest = ablo.tasks.local.
|
|
115
|
+
const latest = ablo.tasks.local.get('task_42'); // read after claiming, not from memory
|
|
92
116
|
await ablo.tasks.update({ id: 'task_42', data: { status: 'done' } });
|
|
93
117
|
```
|
|
94
118
|
|
package/docs/idempotency.md
CHANGED
|
@@ -35,10 +35,10 @@ The key is not a lookup that happens before the write — it is the **execution
|
|
|
35
35
|
itself**. Ablo inserts a pending row keyed by the caller and the key inside the same transaction as
|
|
36
36
|
the mutation, and a unique index makes that insert the lock:
|
|
37
37
|
|
|
38
|
-
- **Insert wins
|
|
39
|
-
- **Insert conflicts
|
|
38
|
+
- **Insert wins:** this transaction owns the execution and runs the write.
|
|
39
|
+
- **Insert conflicts:** someone else owns it. The second caller waits for the owner to finish and
|
|
40
40
|
then replays its recorded result.
|
|
41
|
-
- **Insert conflicts, different request
|
|
41
|
+
- **Insert conflicts, different request:** the key was reused to mean something else. Rejected.
|
|
42
42
|
|
|
43
43
|
Because the lock and the write share a transaction, there is no window in which a write has happened
|
|
44
44
|
but its key has not been recorded.
|
|
@@ -52,7 +52,7 @@ same key string without colliding, and one agent can never replay another's resu
|
|
|
52
52
|
|---|---|
|
|
53
53
|
| A new key | Runs the write. |
|
|
54
54
|
| The same key, the same request, already finished | Replays the recorded result. The write does not run again. |
|
|
55
|
-
| The same key, the same request, still running | Waits for the in-flight attempt, then replays its result. If the original is still running after a short wait, rejects with `idempotency_conflict` (409)
|
|
55
|
+
| The same key, the same request, still running | Waits for the in-flight attempt, then replays its result. If the original is still running after a short wait, rejects with `idempotency_conflict` (409): retry the same key. |
|
|
56
56
|
| The same key, a **different** request | Rejects with `idempotency_conflict` (409). A key is bound to the request it first arrived with. |
|
|
57
57
|
|
|
58
58
|
Both conflict cases return the same code, so tell them apart by what your own
|
|
@@ -60,7 +60,7 @@ client did. If you retried an identical request, the original is still in flight
|
|
|
60
60
|
— wait and retry the same key. If you changed the request, that is a client bug:
|
|
61
61
|
use a new key.
|
|
62
62
|
|
|
63
|
-
## Failures are not replayed
|
|
63
|
+
## Failures are not replayed: they re-run
|
|
64
64
|
|
|
65
65
|
This is where Ablo deliberately differs from Stripe and from most payment APIs, and it is the
|
|
66
66
|
behaviour most likely to surprise you.
|
|
@@ -106,7 +106,7 @@ may already have committed. Restore the original route and retry the same key.
|
|
|
106
106
|
| Timeout or dropped connection, no response | Retry with the **same** key, with backoff. You get the recorded success, or the write runs now. |
|
|
107
107
|
| `source_unreachable` (503) | Retry with the **same** key once connectivity recovers. The write stays pinned to its route. |
|
|
108
108
|
| `replication_lag_timeout` (504) | The write may have materialized. Retry with the **same** key, or wait for source ingestion to catch up. |
|
|
109
|
-
| `AbloStaleContextError` | Re-read the row, regenerate, then write under a **new** key
|
|
109
|
+
| `AbloStaleContextError` | Re-read the row, regenerate, then write under a **new** key: the new write is a new intention. |
|
|
110
110
|
| `AbloClaimedError` | Someone else holds the row. Wait or yield; the key is unused, so reuse it when you retry. |
|
|
111
111
|
| `idempotency_conflict` (409) after an identical retry | The original is still in flight. Wait, then retry the **same** key. |
|
|
112
112
|
| `idempotency_conflict` (409) after changing the request | A client bug: a key is bound to the first request sent under it. Use a **new** key. |
|