@abloatai/ablo 0.25.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -3
- package/CHANGELOG.md +34 -0
- package/README.md +104 -88
- package/dist/BaseSyncedStore.d.ts +140 -266
- package/dist/BaseSyncedStore.js +338 -739
- package/dist/Database.d.ts +62 -77
- package/dist/Database.js +106 -127
- package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
- package/dist/{ObjectPool.js → InstanceCache.js} +91 -83
- package/dist/LazyReferenceCollection.d.ts +11 -15
- package/dist/LazyReferenceCollection.js +16 -15
- package/dist/Model.d.ts +37 -52
- package/dist/Model.js +52 -69
- package/dist/ModelRegistry.d.ts +46 -25
- package/dist/ModelRegistry.js +32 -30
- package/dist/NetworkMonitor.d.ts +5 -6
- package/dist/NetworkMonitor.js +6 -7
- package/dist/SyncClient.d.ts +119 -109
- package/dist/SyncClient.js +303 -224
- package/dist/SyncEngineContext.d.ts +1 -3
- package/dist/SyncEngineContext.js +1 -2
- package/dist/adapters/alwaysOnline.d.ts +6 -8
- package/dist/adapters/alwaysOnline.js +6 -8
- package/dist/adapters/inMemoryStorage.d.ts +9 -9
- package/dist/adapters/inMemoryStorage.js +9 -9
- package/dist/agent/Agent.d.ts +39 -31
- package/dist/agent/Agent.js +35 -23
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +5 -5
- package/dist/agent/session.d.ts +47 -44
- package/dist/agent/session.js +37 -48
- package/dist/agent/types.d.ts +26 -31
- package/dist/agent/types.js +6 -7
- package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
- package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
- package/dist/ai-sdk/coordinationContext.d.ts +46 -0
- package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +30 -31
- package/dist/ai-sdk/index.d.ts +25 -22
- package/dist/ai-sdk/index.js +25 -22
- package/dist/ai-sdk/wrap.d.ts +7 -8
- package/dist/ai-sdk/wrap.js +2 -2
- package/dist/auth/credentialPolicy.d.ts +74 -71
- package/dist/auth/credentialPolicy.js +51 -56
- package/dist/auth/credentialSource.d.ts +7 -18
- package/dist/auth/credentialSource.js +10 -18
- package/dist/auth/index.d.ts +59 -58
- package/dist/auth/index.js +34 -40
- package/dist/auth/schemas.d.ts +5 -4
- package/dist/auth/schemas.js +5 -4
- package/dist/batching/index.d.ts +19 -21
- package/dist/batching/index.js +14 -17
- package/dist/cli.cjs +483 -369
- package/dist/client/Ablo.d.ts +107 -836
- package/dist/client/Ablo.js +174 -833
- package/dist/client/ApiClient.d.ts +44 -20
- package/dist/client/ApiClient.js +193 -44
- package/dist/client/auth.d.ts +51 -60
- package/dist/client/auth.js +137 -110
- package/dist/client/claimHeartbeatLoop.d.ts +50 -0
- package/dist/client/claimHeartbeatLoop.js +88 -0
- package/dist/client/consoleLogger.d.ts +35 -0
- package/dist/client/consoleLogger.js +44 -0
- package/dist/client/createInternalComponents.d.ts +14 -17
- package/dist/client/createInternalComponents.js +26 -31
- package/dist/client/createModelProxy.d.ts +130 -120
- package/dist/client/createModelProxy.js +158 -124
- package/dist/client/credentialEndpoint.d.ts +61 -0
- package/dist/client/credentialEndpoint.js +86 -0
- package/dist/client/functionalUpdate.d.ts +29 -27
- package/dist/client/functionalUpdate.js +21 -21
- package/dist/client/hostedEndpoints.d.ts +21 -0
- package/dist/client/hostedEndpoints.js +21 -0
- package/dist/client/httpClient.d.ts +58 -54
- package/dist/client/httpClient.js +29 -31
- package/dist/client/identity.d.ts +15 -20
- package/dist/client/identity.js +49 -59
- package/dist/client/modelRegistration.d.ts +10 -0
- package/dist/client/modelRegistration.js +301 -0
- package/dist/client/options.d.ts +373 -0
- package/dist/client/options.js +6 -0
- package/dist/client/registerDataSource.d.ts +9 -9
- package/dist/client/registerDataSource.js +15 -16
- package/dist/client/resourceTypes.d.ts +333 -0
- package/dist/client/resourceTypes.js +7 -0
- package/dist/client/schemaConfig.d.ts +44 -0
- package/dist/client/schemaConfig.js +176 -0
- package/dist/client/sessionMint.d.ts +17 -13
- package/dist/client/sessionMint.js +26 -31
- package/dist/client/validateAbloOptions.d.ts +12 -14
- package/dist/client/validateAbloOptions.js +9 -10
- package/dist/client/writeOptionsSchema.d.ts +18 -16
- package/dist/client/writeOptionsSchema.js +23 -20
- package/dist/client/wsMutationExecutor.d.ts +28 -0
- package/dist/client/wsMutationExecutor.js +71 -0
- package/dist/context.d.ts +6 -4
- package/dist/context.js +6 -7
- package/dist/coordination/index.d.ts +13 -4
- package/dist/coordination/index.js +29 -4
- package/dist/coordination/schema.d.ts +176 -128
- package/dist/coordination/schema.js +197 -133
- package/dist/coordination/trace.d.ts +9 -11
- package/dist/coordination/trace.js +13 -15
- package/dist/core/DatabaseManager.d.ts +5 -8
- package/dist/core/DatabaseManager.js +38 -40
- package/dist/core/QueryProcessor.d.ts +7 -9
- package/dist/core/QueryProcessor.js +27 -34
- package/dist/core/QueryView.d.ts +17 -5
- package/dist/core/QueryView.js +6 -7
- package/dist/core/StoreManager.d.ts +14 -16
- package/dist/core/StoreManager.js +26 -25
- package/dist/core/ViewRegistry.d.ts +5 -5
- package/dist/core/ViewRegistry.js +4 -4
- package/dist/core/index.d.ts +18 -13
- package/dist/core/index.js +32 -26
- package/dist/core/openIDBWithTimeout.d.ts +38 -36
- package/dist/core/openIDBWithTimeout.js +57 -54
- package/dist/core/queryUtils.d.ts +45 -0
- package/dist/core/queryUtils.js +69 -0
- package/dist/core/storeContract.d.ts +145 -0
- package/dist/core/storeContract.js +12 -0
- package/dist/environment.d.ts +28 -0
- package/dist/environment.js +21 -0
- package/dist/errorCodes.d.ts +118 -101
- package/dist/errorCodes.js +277 -260
- package/dist/errors.d.ts +170 -165
- package/dist/errors.js +161 -151
- package/dist/index.d.ts +30 -27
- package/dist/index.js +90 -82
- package/dist/interfaces/index.d.ts +108 -133
- package/dist/interfaces/index.js +5 -4
- package/dist/keys/index.d.ts +27 -29
- package/dist/keys/index.js +59 -49
- package/dist/mutators/RecordingTransaction.d.ts +16 -16
- package/dist/mutators/RecordingTransaction.js +31 -37
- package/dist/mutators/Transaction.d.ts +18 -26
- package/dist/mutators/Transaction.js +14 -20
- package/dist/mutators/UndoManager.d.ts +122 -131
- package/dist/mutators/UndoManager.js +149 -155
- package/dist/mutators/defineMutators.d.ts +24 -37
- package/dist/mutators/defineMutators.js +14 -20
- package/dist/mutators/inverseOp.d.ts +12 -15
- package/dist/mutators/inverseOp.js +12 -15
- package/dist/mutators/mutateActions.d.ts +10 -9
- package/dist/mutators/mutateActions.js +1 -1
- package/dist/mutators/readerActions.d.ts +9 -8
- package/dist/mutators/readerActions.js +2 -2
- package/dist/mutators/undoApply.d.ts +31 -27
- package/dist/mutators/undoApply.js +26 -24
- package/dist/policy/index.d.ts +5 -3
- package/dist/policy/index.js +5 -3
- package/dist/policy/types.d.ts +105 -101
- package/dist/policy/types.js +67 -66
- package/dist/query/client.d.ts +32 -16
- package/dist/query/client.js +103 -72
- package/dist/query/types.d.ts +37 -60
- package/dist/query/types.js +13 -33
- package/dist/react/AbloProvider.d.ts +7 -11
- package/dist/react/AbloProvider.js +24 -17
- package/dist/react/context.d.ts +27 -146
- package/dist/react/context.js +9 -10
- package/dist/react/index.d.ts +41 -42
- package/dist/react/index.js +37 -38
- package/dist/react/internalContext.d.ts +17 -19
- package/dist/react/useAblo.d.ts +23 -22
- package/dist/react/useAblo.js +17 -15
- package/dist/react/useCurrentUserId.d.ts +8 -7
- package/dist/react/useCurrentUserId.js +8 -7
- package/dist/react/useErrorListener.d.ts +7 -7
- package/dist/react/useErrorListener.js +11 -12
- package/dist/react/useMutationFailureListener.d.ts +8 -8
- package/dist/react/useMutationFailureListener.js +9 -9
- package/dist/react/useMutators.d.ts +11 -11
- package/dist/react/useMutators.js +10 -4
- package/dist/react/useReactive.js +2 -3
- package/dist/react/useSyncStatus.d.ts +4 -6
- package/dist/react/useUndoScope.d.ts +7 -9
- package/dist/react/useUndoScope.js +3 -3
- package/dist/schema/coordination.d.ts +21 -25
- package/dist/schema/coordination.js +21 -25
- package/dist/schema/ddl.d.ts +43 -39
- package/dist/schema/ddl.js +75 -68
- package/dist/schema/ddlLock.d.ts +35 -0
- package/dist/schema/ddlLock.js +46 -0
- package/dist/schema/diff.d.ts +99 -61
- package/dist/schema/diff.js +43 -34
- package/dist/schema/field.d.ts +37 -42
- package/dist/schema/field.js +36 -49
- package/dist/schema/generate.d.ts +12 -12
- package/dist/schema/generate.js +12 -12
- package/dist/schema/index.d.ts +5 -4
- package/dist/schema/index.js +29 -21
- package/dist/schema/model.d.ts +121 -146
- package/dist/schema/model.js +24 -35
- package/dist/schema/openapi.d.ts +10 -9
- package/dist/schema/openapi.js +7 -1
- package/dist/schema/queries.d.ts +30 -32
- package/dist/schema/queries.js +24 -25
- package/dist/schema/relation.d.ts +89 -99
- package/dist/schema/relation.js +13 -13
- package/dist/schema/residency.d.ts +38 -0
- package/dist/schema/residency.js +30 -0
- package/dist/schema/roles.d.ts +45 -27
- package/dist/schema/roles.js +52 -21
- package/dist/schema/schema.d.ts +36 -45
- package/dist/schema/schema.js +42 -39
- package/dist/schema/select.d.ts +13 -13
- package/dist/schema/select.js +13 -13
- package/dist/schema/serialize.d.ts +36 -39
- package/dist/schema/serialize.js +27 -31
- package/dist/schema/sugar.d.ts +17 -32
- package/dist/schema/sugar.js +14 -29
- package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +27 -50
- package/dist/schema/syncDeltaRow.js +89 -0
- package/dist/schema/tenancy.d.ts +44 -46
- package/dist/schema/tenancy.js +46 -48
- package/dist/server/adapter.d.ts +58 -58
- package/dist/server/adapter.js +13 -14
- package/dist/server/commit.d.ts +60 -64
- package/dist/server/index.d.ts +9 -10
- package/dist/server/index.js +1 -1
- package/dist/server/readConfig.d.ts +70 -0
- package/dist/server/readConfig.js +8 -0
- package/dist/server/storageMode.d.ts +23 -0
- package/dist/server/storageMode.js +17 -0
- package/dist/source/adapter.d.ts +31 -26
- package/dist/source/adapter.js +10 -10
- package/dist/source/adapters/drizzle.d.ts +28 -23
- package/dist/source/adapters/drizzle.js +34 -28
- package/dist/source/adapters/kysely.d.ts +27 -25
- package/dist/source/adapters/kysely.js +28 -26
- package/dist/source/adapters/memory.d.ts +8 -7
- package/dist/source/adapters/memory.js +10 -9
- package/dist/source/adapters/prisma.d.ts +13 -12
- package/dist/source/adapters/prisma.js +27 -29
- package/dist/source/conformance.d.ts +18 -11
- package/dist/source/conformance.js +27 -19
- package/dist/source/connector.d.ts +31 -32
- package/dist/source/connector.js +30 -28
- package/dist/source/connectorProtocol.d.ts +160 -0
- package/dist/source/connectorProtocol.js +162 -0
- package/dist/source/contract.d.ts +26 -27
- package/dist/source/contract.js +28 -29
- package/dist/source/factory.d.ts +94 -0
- package/dist/source/factory.js +268 -0
- package/dist/source/index.d.ts +10 -462
- package/dist/source/index.js +17 -421
- package/dist/source/migrations.d.ts +9 -9
- package/dist/source/migrations.js +9 -9
- package/dist/source/next.d.ts +10 -11
- package/dist/source/next.js +7 -8
- package/dist/source/pushQueue.d.ts +70 -48
- package/dist/source/pushQueue.js +36 -29
- package/dist/source/signing.d.ts +88 -0
- package/dist/source/signing.js +159 -0
- package/dist/source/types.d.ts +351 -0
- package/dist/source/types.js +43 -0
- package/dist/stores/ObjectStore.d.ts +11 -12
- package/dist/stores/ObjectStore.js +34 -35
- package/dist/stores/ObjectStoreContract.d.ts +12 -15
- package/dist/stores/SyncActionStore.d.ts +8 -12
- package/dist/stores/SyncActionStore.js +77 -46
- package/dist/surface.d.ts +28 -21
- package/dist/surface.js +28 -20
- package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +37 -45
- package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +101 -80
- package/dist/sync/ConnectionManager.d.ts +47 -50
- package/dist/sync/ConnectionManager.js +74 -70
- package/dist/sync/NetworkProbe.d.ts +27 -31
- package/dist/sync/NetworkProbe.js +67 -72
- package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +49 -36
- package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +79 -54
- package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +45 -59
- package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +44 -52
- package/dist/sync/SyncWebSocket.d.ts +175 -250
- package/dist/sync/SyncWebSocket.js +431 -769
- package/dist/sync/awaitClaimGrant.d.ts +18 -18
- package/dist/sync/awaitClaimGrant.js +38 -30
- package/dist/sync/bootstrapApply.d.ts +70 -0
- package/dist/sync/bootstrapApply.js +73 -0
- package/dist/sync/commitFrames.d.ts +44 -0
- package/dist/sync/commitFrames.js +94 -0
- package/dist/sync/createClaimStream.d.ts +23 -22
- package/dist/sync/createClaimStream.js +108 -25
- package/dist/sync/createPresenceStream.d.ts +19 -18
- package/dist/sync/createPresenceStream.js +25 -26
- package/dist/sync/createSnapshot.d.ts +13 -17
- package/dist/sync/createSnapshot.js +20 -26
- package/dist/sync/credentialLifecycle.d.ts +175 -0
- package/dist/sync/credentialLifecycle.js +322 -0
- package/dist/sync/deltaPipeline.d.ts +113 -0
- package/dist/sync/deltaPipeline.js +261 -0
- package/dist/sync/groupChange.d.ts +113 -0
- package/dist/sync/groupChange.js +242 -0
- package/dist/sync/heartbeat.d.ts +63 -0
- package/dist/sync/heartbeat.js +91 -0
- package/dist/sync/participants.d.ts +27 -27
- package/dist/sync/schemas.d.ts +3 -2
- package/dist/sync/schemas.js +14 -10
- package/dist/sync/syncCursor.d.ts +40 -0
- package/dist/sync/syncCursor.js +55 -0
- package/dist/sync/syncPlan.d.ts +54 -0
- package/dist/sync/syncPlan.js +50 -0
- package/dist/sync/syncPosition.d.ts +54 -49
- package/dist/sync/syncPosition.js +57 -52
- package/dist/sync/wsFrameHandlers.d.ts +116 -0
- package/dist/sync/wsFrameHandlers.js +374 -0
- package/dist/testing/fixtures/bootstrap.d.ts +21 -17
- package/dist/testing/fixtures/bootstrap.js +12 -6
- package/dist/testing/fixtures/deltas.d.ts +31 -34
- package/dist/testing/fixtures/deltas.js +30 -33
- package/dist/testing/fixtures/models.d.ts +11 -10
- package/dist/testing/fixtures/models.js +12 -10
- package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
- package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
- package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -18
- package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +14 -11
- package/dist/testing/helpers/wait.d.ts +13 -8
- package/dist/testing/helpers/wait.js +13 -8
- package/dist/testing/index.d.ts +4 -4
- package/dist/testing/index.js +3 -3
- package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
- package/dist/testing/mocks/MockMutationExecutor.js +15 -14
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
- package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
- package/dist/testing/mocks/MockSyncContext.d.ts +21 -34
- package/dist/testing/mocks/MockSyncContext.js +16 -45
- package/dist/testing/mocks/MockSyncStore.d.ts +14 -14
- package/dist/testing/mocks/MockSyncStore.js +11 -11
- package/dist/testing/mocks/MockWebSocket.d.ts +28 -24
- package/dist/testing/mocks/MockWebSocket.js +22 -21
- package/dist/transactions/TransactionQueue.d.ts +190 -221
- package/dist/transactions/TransactionQueue.js +424 -822
- package/dist/transactions/TransactionStore.d.ts +20 -0
- package/dist/transactions/TransactionStore.js +53 -0
- package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
- package/dist/transactions/UnconfirmedWrites.js +104 -0
- package/dist/transactions/coalesceRules.d.ts +58 -0
- package/dist/transactions/coalesceRules.js +140 -0
- package/dist/transactions/commitPayload.d.ts +130 -0
- package/dist/transactions/commitPayload.js +143 -0
- package/dist/transactions/deltaConfirmation.d.ts +58 -0
- package/dist/transactions/deltaConfirmation.js +215 -0
- package/dist/transactions/optimisticApply.d.ts +49 -0
- package/dist/transactions/optimisticApply.js +65 -0
- package/dist/transactions/replayValidation.d.ts +99 -0
- package/dist/transactions/replayValidation.js +111 -0
- package/dist/types/global.d.ts +46 -41
- package/dist/types/global.js +20 -19
- package/dist/types/index.d.ts +74 -80
- package/dist/types/index.js +22 -27
- package/dist/types/modelData.d.ts +10 -0
- package/dist/types/modelData.js +9 -0
- package/dist/types/participant.d.ts +20 -0
- package/dist/types/participant.js +10 -0
- package/dist/types/streams.d.ts +216 -209
- package/dist/types/streams.js +7 -7
- package/dist/utils/asyncIterator.d.ts +25 -32
- package/dist/utils/asyncIterator.js +25 -32
- package/dist/utils/duration.d.ts +12 -15
- package/dist/utils/duration.js +12 -15
- package/dist/utils/mobxSetup.d.ts +53 -0
- package/dist/utils/{mobx-setup.js → mobxSetup.js} +44 -100
- package/dist/webhooks/events.d.ts +21 -16
- package/dist/webhooks/events.js +10 -8
- package/dist/webhooks/index.d.ts +5 -7
- package/dist/webhooks/index.js +5 -7
- package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
- package/dist/wire/delta.js +114 -0
- package/dist/wire/errorEnvelope.d.ts +35 -27
- package/dist/wire/errorEnvelope.js +38 -32
- package/dist/wire/frames.d.ts +150 -67
- package/dist/wire/frames.js +48 -1
- package/dist/wire/index.d.ts +18 -13
- package/dist/wire/index.js +36 -13
- package/dist/wire/listEnvelope.d.ts +16 -23
- package/dist/wire/listEnvelope.js +7 -6
- package/dist/wire/protocol.d.ts +38 -0
- package/dist/wire/protocol.js +38 -0
- package/dist/wire/protocolVersion.d.ts +60 -0
- package/dist/wire/protocolVersion.js +67 -0
- package/docs/api-keys.md +4 -3
- package/docs/coordination.md +59 -0
- package/docs/examples/existing-python-backend.md +3 -3
- package/docs/identity.md +4 -4
- package/docs/integration-guide.md +1 -1
- package/docs/react.md +1 -1
- package/docs/sessions.md +5 -7
- package/package.json +24 -21
- package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
- package/dist/ai-sdk/coordination-context.d.ts +0 -52
- package/dist/client/index.d.ts +0 -36
- package/dist/client/index.js +0 -33
- package/dist/config/index.d.ts +0 -10
- package/dist/config/index.js +0 -12
- package/dist/core/query-utils.d.ts +0 -34
- package/dist/core/query-utils.js +0 -59
- package/dist/interfaces/headless.d.ts +0 -95
- package/dist/interfaces/headless.js +0 -41
- package/dist/query/index.d.ts +0 -6
- package/dist/query/index.js +0 -5
- package/dist/realtime/index.d.ts +0 -10
- package/dist/realtime/index.js +0 -9
- package/dist/schema/plane.d.ts +0 -23
- package/dist/schema/plane.js +0 -19
- package/dist/schema/sync-delta-row.js +0 -103
- package/dist/schema/sync-delta-wire.js +0 -102
- package/dist/server/next.d.ts +0 -51
- package/dist/server/next.js +0 -47
- package/dist/server/read-config.d.ts +0 -67
- package/dist/server/read-config.js +0 -8
- package/dist/server/storage-mode.d.ts +0 -1
- package/dist/server/storage-mode.js +0 -18
- package/dist/source/connector-protocol.d.ts +0 -159
- package/dist/source/connector-protocol.js +0 -161
- package/dist/sync/OfflineFlush.d.ts +0 -9
- package/dist/sync/OfflineFlush.js +0 -22
- package/dist/sync/OfflineTransactionStore.d.ts +0 -37
- package/dist/sync/OfflineTransactionStore.js +0 -263
- package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
- package/dist/transactions/OptimisticEchoTracker.js +0 -104
- package/dist/transactions/index.d.ts +0 -16
- package/dist/transactions/index.js +0 -7
- package/dist/transactions/mutation-error-handler.d.ts +0 -5
- package/dist/transactions/mutation-error-handler.js +0 -39
- package/dist/utils/mobx-setup.d.ts +0 -42
package/AGENTS.md
CHANGED
|
@@ -6,16 +6,18 @@ Claims don't lock. If another writer holds the row, `claim` waits for them and r
|
|
|
6
6
|
|
|
7
7
|
## Start here — scaffold with `ablo init`
|
|
8
8
|
|
|
9
|
-
Don't hand-write the integration. Run the CLI; it generates the current-API schema, client, Data Source endpoint, and (for Next.js) the browser provider + session route:
|
|
9
|
+
Don't hand-write the integration. Run the CLI; it generates the current-API schema, client, the database connection (logical replication by default, or a signed Data Source endpoint as the fallback), and (for Next.js) the browser provider + session route:
|
|
10
10
|
|
|
11
11
|
- **Scaffold:** `npx ablo init --yes` — flag-driven, never prompts. Override defaults with `--framework <nextjs|vite|remix|vanilla>`, `--auth <apikey|…>`, `--no-agent`, `--no-pull`, `--no-install`, `--no-login`. (Plain `ablo init` needs a TTY and will **HANG** in an agent/CI run — always pass `--yes`.)
|
|
12
12
|
- **Auth:** set `ABLO_API_KEY` in the environment. Do **NOT** run `ablo login` — it opens a browser device flow and blocks an agent.
|
|
13
|
-
- **
|
|
13
|
+
- **Connect your database — logical replication (the primary path):** `npx ablo connect` prints the setup SQL (`wal_level=logical`, a publication, a `REPLICATION` role); `npx ablo connect --register` registers the source with Ablo in one step. Ablo **consumes your Postgres' logical-replication stream** — it never runs DDL on, writes to, owns, or migrates your database, and your application keeps the write path. Registration **is** the enable; there is no tier or flag to pick. (Ablo hosts only the transaction log + coordination, never your rows.)
|
|
14
|
+
- **Fallback — signed Data Source endpoint** (DB can't grant a `REPLICATION` role): the generated `ablo/data-source.ts` exposes one route; Ablo sends signed requests and your app touches its own DB. **Only in this mode** does `npx ablo migrate` provision the adapter's bookkeeping tables (`ablo_outbox`, `ablo_idempotency`) plus your Ablo models — it does **not** touch your other tables. Keep your own migrations (drizzle-kit / prisma migrate) for auth and anything outside the Ablo schema.
|
|
15
|
+
- **No database yet?** A sandbox `sk_test` key holds throwaway **test data** (Stripe-test-mode style) so you can try Ablo before connecting your own Postgres. Test-mode only — in production every row lives in your database.
|
|
14
16
|
- **Adopt an existing DB schema:** `npx ablo pull prisma [path]` / `pull drizzle <module>` (lossless) or `pull` (live DB, lossy). Writes `ablo/schema.ts`.
|
|
15
17
|
- **Push your schema — REQUIRED before any write works.** The server keeps its OWN copy of the schema. After you create or edit `ablo/schema.ts`, run `npx ablo push` (one-shot) — or `npx ablo dev --no-watch`. **Skip this and every write to a new or changed model fails with `server_execute_unknown_model`.** (Plain `ablo dev` watches forever — never run it bare in an agent.)
|
|
16
18
|
- **Other long-running:** `npx ablo logs --no-follow` (default tails forever). `npx ablo mode test|live` ALWAYS pass the argument. `status`, `push`, `pull`, `check`, `generate` are one-shot — safe as-is.
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
When you use the signed-endpoint fallback, the generated `ablo/data-source.ts` is the whole endpoint and needs no hand-editing: `dataSourceNext({ schema, apiKey, adapter: prismaDataSource(prisma, schema) })` (or `drizzleDataSource(db, schema)`). The adapter owns commit / idempotency / outbox.
|
|
19
21
|
|
|
20
22
|
## Rule
|
|
21
23
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.27.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- **Claims can now be held for long-running work by heartbeating — on both transports.** A claim's TTL is crash cleanup, not a work estimate; work that outlives it (a 30-minute report, a long agent run) keeps its lease by beating. `claim({ heartbeat: true })` beats automatically until release; `held.heartbeat()` beats by hand. A lapsed lease answers the next beat with `AbloClaimedError` (`claim_lost`) — for a socketless worker, the failed beat _is_ the loss notification, and any write attempted under the old lease is independently rejected by its `readAt` guard.
|
|
8
|
+
|
|
9
|
+
- **Beats carry progress and pressure.** `heartbeat({ details })` stores lightweight progress as the claim's peer-visible `meta.progress` (last beat wins, via `claim.state`); every beat's answer reports `queueDepth` — how many participants wait in line behind the lease — observable per auto-beat with the new `onHeartbeat` claim option.
|
|
10
|
+
|
|
11
|
+
- **`ablo.claims.heartbeatAll({ ttl })`** extends every lease the credential holds in one request (`POST /v1/claims/heartbeat`) — the stateless twin of the WebSocket keepalive, for workers holding many rows.
|
|
12
|
+
|
|
13
|
+
- **Keepalive renewals extend but never shorten a lease**, so an explicit work-duration `ttl` now survives pings and brief reconnects instead of collapsing to the liveness window.
|
|
14
|
+
|
|
15
|
+
- **README.** The quick start leads with a runnable example, and a new _Background workers_ section shows the enqueue-on-your-own-queue / heartbeat-the-claim pattern end to end.
|
|
16
|
+
|
|
17
|
+
## 0.26.0
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- **`ablo connect --register` works against any deployment.** Registering your database as an Ablo data source over logical replication is now a first-class path everywhere — the gate that could refuse a new connection-string registration is gone. Point `ablo connect --register` at your Postgres and Ablo begins consuming its replication stream while your application keeps owning the write path; registering the source _is_ the enable, with no tier or flag to choose. The signed `dataSource()` endpoint remains the explicit fallback for databases that can't grant replication.
|
|
22
|
+
|
|
23
|
+
- **More engine failures surface as typed errors you can branch on**, instead of opaque `500`s. New `AbloError` codes: `schema_provisioning_forbidden` (`403` — a push tried to create tables in a database where the engine isn't permitted to run DDL), `request_too_large` (`413` — a query or commit body exceeded the size limit), `commit_operation_invalid` (`400` — a malformed commit operation), and `upload_not_configured` (`503` — an upload was attempted with no blob store wired).
|
|
24
|
+
|
|
25
|
+
- **`@abloatai/ablo/wire` now exports the protocol schemas.** `commitOperationSchema`, `commitPayloadSchema`, and the frame schemas let tooling and tests validate client↔engine frames against the same contract the engine enforces.
|
|
26
|
+
|
|
27
|
+
- **Protocol version negotiation is surfaced.** `@abloatai/ablo/wire` exports `PROTOCOL_VERSION`, `MIN_SUPPORTED_PROTOCOL_VERSION`, `WS_CLOSE_PROTOCOL_VERSION`, `PROTOCOL_VERSION_HEADER`, `protocolVersionProblem`, and `ERROR_CONTRACT_VERSION` — the single integer the client and server compare on connect to detect an incompatible peer and fail with a clear reason instead of a cryptic wire error.
|
|
28
|
+
|
|
29
|
+
- **`@abloatai/ablo/coordination` exposes the conflict-policy vocabulary** — `defaultPolicy`, `capabilityPreemptPolicy`, and `interpretConflictAxis` — for server-side consumers building on the claim model. `@abloatai/ablo/schema` gains the role primitives (`identityRole`, `entityRole`, and their types and schemas) for declaring identity- and entity-scoped roles.
|
|
30
|
+
|
|
31
|
+
- **Removed unused API surface.** Dropped the `@abloatai/ablo/server/next` subpath export and the unused `MutationDispatcher` interface (plus its `MockMutationDispatcher` test double) and the offline-mutation-queue internals behind them — none had documented consumers. Every supported entry point (`@abloatai/ablo`, `/ai-sdk`, `/react`, `/source`, `/coordination`, `/schema`, `/keys`, `/auth`, `/wire`, …) is unchanged.
|
|
32
|
+
|
|
33
|
+
- **Internal:** the SDK's largest modules — the `Ablo` client, the data-source runtime, the transaction queue, and the WebSocket sync loop — were decomposed into cohesive leaf modules. No public runtime API or import path changed.
|
|
34
|
+
|
|
35
|
+
- **CLI & docs.** `ablo push` prints a calmer, information-first deploy banner (a production push still requires typing the project name to confirm). The README and `AGENTS.md` now lead with the one-path logical-replication model and clarify that sandbox is test-mode only — in production your rows stay in your database and Ablo holds only the transaction log.
|
|
36
|
+
|
|
3
37
|
## 0.25.0
|
|
4
38
|
|
|
5
39
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -39,10 +39,10 @@ Under the hood, you define your data once with a Zod schema and get the same
|
|
|
39
39
|
typed model client for every actor — people, server actions, and agents:
|
|
40
40
|
|
|
41
41
|
```ts
|
|
42
|
-
await ablo.
|
|
43
|
-
await ablo.
|
|
44
|
-
await ablo.
|
|
45
|
-
await using
|
|
42
|
+
await ablo.weatherReports.create({ data }) // create
|
|
43
|
+
await ablo.weatherReports.retrieve({ id }) // read
|
|
44
|
+
await ablo.weatherReports.update({ id, data }) // update
|
|
45
|
+
await using claim = await ablo.weatherReports.claim({ id }) // hold for slow agent work
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
The schema is the public contract. It gives you typed model methods, realtime
|
|
@@ -63,8 +63,9 @@ yet? A **sandbox** `sk_test` key holds throwaway **test data** — like Stripe t
|
|
|
63
63
|
mode — so you can explore before pointing it at your Postgres. Test-mode only; in
|
|
64
64
|
production every row lives in your database.)
|
|
65
65
|
|
|
66
|
-
**Built for** collaborative editors, AI agent workflows,
|
|
67
|
-
|
|
66
|
+
**Built for** collaborative editors, AI agent workflows, background workers on
|
|
67
|
+
your own infrastructure, and internal tools — anywhere people and agents change
|
|
68
|
+
shared state and everyone has to see it live.
|
|
68
69
|
|
|
69
70
|
## Set up
|
|
70
71
|
|
|
@@ -111,62 +112,15 @@ instead of guessing:
|
|
|
111
112
|
|
|
112
113
|
## Quick Start
|
|
113
114
|
|
|
115
|
+
One schema, one client, one write path for humans and agents — this runs as-is
|
|
116
|
+
after `ablo push`:
|
|
117
|
+
|
|
114
118
|
```ts
|
|
115
119
|
import Ablo from '@abloatai/ablo';
|
|
116
120
|
import { defineSchema, model, z } from '@abloatai/ablo/schema';
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
The schema is registered once (init scaffolds `ablo/register.ts` for you), and
|
|
120
|
-
every type is one parameter away — no `typeof schema` re-stating, anywhere:
|
|
121
|
-
|
|
122
|
-
```ts
|
|
123
|
-
// ablo/register.ts — scaffolded by `npx ablo init`, sits beside ablo/schema.ts
|
|
124
|
-
import type { schema } from './schema';
|
|
125
|
-
declare module '@abloatai/ablo' {
|
|
126
|
-
interface Register { Schema: typeof schema }
|
|
127
|
-
}
|
|
128
|
-
export {};
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
It's a regular `.ts` module, not a hand-authored `.d.ts`. The top-level
|
|
132
|
-
`import type { schema }` makes the `declare module` block *merge* into (augment)
|
|
133
|
-
the SDK's `Register` interface instead of colliding with it — the same shape
|
|
134
|
-
[TanStack Router uses in `src/router.tsx`](https://tanstack.com/router/latest/docs/framework/react/guide/type-safety). Any `.ts` file in your
|
|
135
|
-
`tsconfig` `include` works; it never needs to be imported.
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
import type { Model } from '@abloatai/ablo/schema';
|
|
139
|
-
|
|
140
|
-
type WeatherReport = Model<'weatherReports'>; // fully typed from YOUR schema
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
(The same `Register` binding types every hook and client — it's the
|
|
144
|
-
TanStack-Router pattern: declare the source of truth once, everything
|
|
145
|
-
infers from it.)
|
|
146
121
|
|
|
147
|
-
### Naming the client type
|
|
148
|
-
|
|
149
|
-
When you need to pass the client around (a function parameter, a context value),
|
|
150
|
-
**infer the type from the value** — `type Sync = typeof sync`:
|
|
151
|
-
|
|
152
|
-
```ts
|
|
153
|
-
export const sync = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
|
|
154
|
-
export type Sync = typeof sync; // fully-typed, schema-aware
|
|
155
|
-
|
|
156
|
-
function persist(client: Sync) { /* ... */ }
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
This is the same idiom as tRPC's `type AppRouter = typeof appRouter` and
|
|
160
|
-
Drizzle's `typeof db` — the factory resolves the typed overload at the call
|
|
161
|
-
site, so `typeof sync` carries your schema. Do **not** write
|
|
162
|
-
`ReturnType<typeof Ablo>`: that collapses to the untyped last overload and
|
|
163
|
-
loses your model types. There is no bespoke client-type generic to import —
|
|
164
|
-
`typeof` your client value is the type.
|
|
165
|
-
|
|
166
|
-
```ts
|
|
167
122
|
const schema = defineSchema({
|
|
168
|
-
//
|
|
169
|
-
// provided automatically — don't declare them.
|
|
123
|
+
// id, createdAt, updatedAt, organizationId, createdBy come free on every model
|
|
170
124
|
weatherReports: model({
|
|
171
125
|
location: z.string(),
|
|
172
126
|
status: z.enum(['pending', 'ready']),
|
|
@@ -174,29 +128,21 @@ const schema = defineSchema({
|
|
|
174
128
|
}),
|
|
175
129
|
});
|
|
176
130
|
|
|
177
|
-
const ablo = Ablo({
|
|
178
|
-
schema,
|
|
179
|
-
apiKey: process.env.ABLO_API_KEY, // written to .env.local by `npx ablo push`
|
|
180
|
-
});
|
|
181
|
-
// Your Postgres is connected once via `npx ablo connect` (logical replication) —
|
|
182
|
-
// not passed here. Ablo tails its WAL; your rows never leave your database.
|
|
183
|
-
|
|
131
|
+
const ablo = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
|
|
184
132
|
await ablo.ready();
|
|
185
133
|
|
|
186
134
|
const created = await ablo.weatherReports.create({
|
|
187
|
-
data: {
|
|
188
|
-
location: 'Stockholm',
|
|
189
|
-
status: 'pending',
|
|
190
|
-
},
|
|
135
|
+
data: { location: 'Stockholm', status: 'pending' },
|
|
191
136
|
});
|
|
192
137
|
|
|
193
|
-
//
|
|
194
|
-
// claim is held nobody else can overwrite it; anyone else who tries waits in
|
|
195
|
-
// line and re-reads the result. This is the whole point of Ablo.
|
|
138
|
+
// Claim the row before slow work — anyone else waits in line, then re-reads.
|
|
196
139
|
await using claim = await ablo.weatherReports.claim({ id: created.id });
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
140
|
+
const forecast = await fetchForecast(claim.data.location); // slow: API or LLM call
|
|
141
|
+
await ablo.weatherReports.update({
|
|
142
|
+
id: created.id,
|
|
143
|
+
data: { status: 'ready', forecast },
|
|
144
|
+
claim, // the write completes the claimed work and releases the lease
|
|
145
|
+
});
|
|
200
146
|
|
|
201
147
|
const ready = ablo.weatherReports.get(created.id);
|
|
202
148
|
console.log({ id: ready?.id, status: ready?.status });
|
|
@@ -210,6 +156,38 @@ Expected output:
|
|
|
210
156
|
{ id: '...', status: 'ready' }
|
|
211
157
|
```
|
|
212
158
|
|
|
159
|
+
### TypeScript setup (once, scaffolded for you)
|
|
160
|
+
|
|
161
|
+
`npx ablo init` writes `ablo/register.ts` next to your schema. It binds your
|
|
162
|
+
schema to the SDK's types once — the same declaration-merging shape
|
|
163
|
+
[TanStack Router uses](https://tanstack.com/router/latest/docs/framework/react/guide/type-safety) —
|
|
164
|
+
so every hook and client infers from it:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
// ablo/register.ts — scaffolded by `npx ablo init`
|
|
168
|
+
import type { schema } from './schema';
|
|
169
|
+
declare module '@abloatai/ablo' {
|
|
170
|
+
interface Register { Schema: typeof schema }
|
|
171
|
+
}
|
|
172
|
+
export {};
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
import type { Model } from '@abloatai/ablo/schema';
|
|
177
|
+
|
|
178
|
+
type WeatherReport = Model<'weatherReports'>; // fully typed from your schema
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
To pass the client around, take the type from the value — the tRPC /
|
|
182
|
+
Drizzle idiom:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
export const sync = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
|
|
186
|
+
export type Sync = typeof sync;
|
|
187
|
+
|
|
188
|
+
function persist(client: Sync) { /* ... */ }
|
|
189
|
+
```
|
|
190
|
+
|
|
213
191
|
## Reading
|
|
214
192
|
|
|
215
193
|
Two ways to read, depending on whether you can wait. `get(id)` / `getAll({ where })`
|
|
@@ -262,7 +240,11 @@ meanwhile, or worse, acts on stale state. `claim` holds the row across that gap:
|
|
|
262
240
|
await using claim = await ablo.weatherReports.claim({ id: 'report_stockholm' });
|
|
263
241
|
const report = claim.data;
|
|
264
242
|
const forecast = await weatherAgent.getWeather(report.location);
|
|
265
|
-
await ablo.weatherReports.update({
|
|
243
|
+
await ablo.weatherReports.update({
|
|
244
|
+
id: report.id,
|
|
245
|
+
data: { forecast, status: 'ready' },
|
|
246
|
+
claim, // attribute the write to the held claim
|
|
247
|
+
});
|
|
266
248
|
```
|
|
267
249
|
|
|
268
250
|
If someone else holds the row, `claim()` waits in a fair queue, then re-reads —
|
|
@@ -311,6 +293,46 @@ try {
|
|
|
311
293
|
See [Coordination](./docs/coordination.md) for the full `claim` / `claim.state` /
|
|
312
294
|
`claim.queue` / `claim.release` reference.
|
|
313
295
|
|
|
296
|
+
## Background workers — jobs that run for minutes, not seconds
|
|
297
|
+
|
|
298
|
+
Your API route enqueues a job on your own queue (SQS, EventBridge, anything);
|
|
299
|
+
a worker on your own infrastructure does the slow part. **Keep that queue —
|
|
300
|
+
Ablo is the worker's data layer.** It covers the two things every queue leaves
|
|
301
|
+
to you: keeping the row safe, and showing progress live.
|
|
302
|
+
|
|
303
|
+
Long work holds its claim by **heartbeating** — the same pattern as an SQS
|
|
304
|
+
visibility heartbeat or a Temporal activity heartbeat:
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
// on your worker — stateless HTTP, no socket to hold
|
|
308
|
+
await using claim = await ablo.weatherReports.claim({
|
|
309
|
+
id: msg.reportId,
|
|
310
|
+
ttl: '10m',
|
|
311
|
+
heartbeat: true, // beats automatically until release
|
|
312
|
+
onHeartbeatLost: () => abort(), // the lease is gone → stop working
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
for (const step of steps) {
|
|
316
|
+
await runStep(step);
|
|
317
|
+
// write progress to the row — every subscribed UI updates live
|
|
318
|
+
await ablo.weatherReports.update({ id: msg.reportId, data: { progress: step.pct }, claim });
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
- A worker that **crashes** stops beating; the row frees within one beat and
|
|
323
|
+
the next worker takes over.
|
|
324
|
+
- A worker that **wakes up late** learns it on its next beat
|
|
325
|
+
(`AbloClaimedError`), and the write path rejects its stale writes anyway.
|
|
326
|
+
- **Retries stay on your queue** — the redelivered job claims the now-free
|
|
327
|
+
row, reads its current state, and resumes.
|
|
328
|
+
- A worker holding **many rows** extends them all in one call:
|
|
329
|
+
`ablo.claims.heartbeatAll({ ttl: '5m' })`.
|
|
330
|
+
|
|
331
|
+
SQS's heartbeat protects the *message* from redelivery; Ablo's protects the
|
|
332
|
+
*row* from concurrent and stale writes. SQS is at-least-once, so two workers
|
|
333
|
+
will eventually get the same job — the claim is what keeps that from
|
|
334
|
+
corrupting data.
|
|
335
|
+
|
|
314
336
|
## React
|
|
315
337
|
|
|
316
338
|
In a React app it's the **same `ablo.<model>` API** — just mounted through a
|
|
@@ -322,10 +344,10 @@ import Ablo from '@abloatai/ablo';
|
|
|
322
344
|
import { AbloProvider, useAblo } from '@abloatai/ablo/react';
|
|
323
345
|
import { schema } from './ablo/schema';
|
|
324
346
|
|
|
325
|
-
// Build the client once —
|
|
347
|
+
// Build the client once — authEndpoint is your session route; no key in the browser.
|
|
326
348
|
const ablo = Ablo({
|
|
327
349
|
schema,
|
|
328
|
-
|
|
350
|
+
authEndpoint: '/api/ablo-session',
|
|
329
351
|
});
|
|
330
352
|
|
|
331
353
|
function App() {
|
|
@@ -381,7 +403,7 @@ to sync-group strings.
|
|
|
381
403
|
// team membership is asserted server-side when the session route mints the token.
|
|
382
404
|
const ablo = Ablo({
|
|
383
405
|
schema,
|
|
384
|
-
|
|
406
|
+
authEndpoint: '/api/ablo-session',
|
|
385
407
|
});
|
|
386
408
|
|
|
387
409
|
<AbloProvider client={ablo} userId={user.id}>
|
|
@@ -445,14 +467,8 @@ connects:
|
|
|
445
467
|
| **Logical replication** (primary) | `npx ablo connect` prints the setup SQL (`wal_level=logical`, a publication, a `REPLICATION` role); `npx ablo connect --register` tells Ablo to replicate it. Ablo tails the WAL — it never runs DDL on, writes to, owns, or migrates your database. | Your database can grant a `REPLICATION` role (most can). |
|
|
446
468
|
| **Signed endpoint** (fallback) | Your app exposes one route built from an ORM adapter (`prismaDataSource` / `drizzleDataSource`); Ablo sends signed requests and your app touches its own database. Needs no database configuration. | Your database **can't** grant a replication role (a locked-down managed DB). |
|
|
447
469
|
|
|
448
|
-
|
|
449
|
-
coordination
|
|
450
|
-
connect your own Postgres. Test-mode only: in production your rows always live in
|
|
451
|
-
your database and Ablo holds just the transaction log, never your data.)
|
|
452
|
-
|
|
453
|
-
Your database is the system of record. The old `databaseUrl` dial-in (Ablo
|
|
454
|
-
holding a read/write connection) is **deprecated and being removed** — connect
|
|
455
|
-
via logical replication instead. See
|
|
470
|
+
Your database is the system of record — Ablo holds the transaction log and
|
|
471
|
+
coordination, never your rows. See
|
|
456
472
|
[Connect Your Database](./docs/data-sources.md).
|
|
457
473
|
|
|
458
474
|
## Configuration
|
|
@@ -466,7 +482,7 @@ Every other option has correct defaults:
|
|
|
466
482
|
| --- | --- | --- | --- |
|
|
467
483
|
| `schema` | `Schema` | — (required) | Typed model proxies (`ablo.<model>.*`) |
|
|
468
484
|
| `apiKey` | `string \| ApiKeySetter \| null` | `process.env.ABLO_API_KEY` | Server key — a string, or an async function for rotation |
|
|
469
|
-
| `databaseUrl` | `string \| null` | `—` |
|
|
485
|
+
| `databaseUrl` | `string \| null` | `—` | Deprecated. Connect via `npx ablo connect` instead — see [Connect Your Database](./docs/data-sources.md). |
|
|
470
486
|
|
|
471
487
|
Keep `apiKey` in trusted server runtimes. In the browser, `<AbloProvider>`
|
|
472
488
|
authenticates with the signed-in user's session; the raw-key path is gated
|
|
@@ -519,7 +535,7 @@ contract; there are no retry or timeout knobs to tune.
|
|
|
519
535
|
- [Guarantees](./docs/guarantees.md) — confirmed writes, stale-write protection, claim coordination, and agent lifecycle.
|
|
520
536
|
- [Integration Guide](./docs/integration-guide.md) — integrate React, your database, multiplayer, and agents.
|
|
521
537
|
- [React](./docs/react.md) — `<AbloProvider>`, `useAblo`, presence, status, and bootstrap gating.
|
|
522
|
-
- [Coordination](./docs/coordination.md) — `claim` / `claim.state` / `claim.queue` / `claim.release` reference: hold a row across slow agent work, and observe the line waiting behind it.
|
|
538
|
+
- [Coordination](./docs/coordination.md) — `claim` / `claim.state` / `claim.queue` / `claim.release` / `heartbeat` reference: hold a row across slow agent work — minutes or hours, via heartbeats — and observe the line waiting behind it.
|
|
523
539
|
- [Client Behavior](./docs/client-behavior.md) — options, errors, retries, timeouts, and public imports.
|
|
524
540
|
- [Connect Your Database](./docs/data-sources.md) — connect your Postgres by logical replication (`npx ablo connect`) or, as a fallback, a signed endpoint; your database is the system of record either way.
|
|
525
541
|
- [Existing Python Backend](./docs/examples/existing-python-backend.md) — migrate existing Python endpoints to multiplayer and agent-safe writes gradually.
|