@abloatai/ablo 0.34.1 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -1
- package/CHANGELOG.md +758 -5
- package/README.md +56 -502
- package/bin/ablo.cjs +39 -0
- package/dist/BaseSyncedStore.d.ts +176 -48
- package/dist/BaseSyncedStore.js +346 -214
- package/dist/Database.d.ts +17 -44
- package/dist/Database.js +96 -79
- package/dist/InstanceCache.d.ts +31 -6
- package/dist/InstanceCache.js +65 -30
- package/dist/LazyReferenceCollection.d.ts +3 -3
- package/dist/LazyReferenceCollection.js +4 -4
- package/dist/Model.d.ts +23 -13
- package/dist/Model.js +27 -17
- package/dist/ModelRegistry.d.ts +8 -4
- package/dist/ModelRegistry.js +20 -18
- package/dist/NetworkMonitor.d.ts +3 -1
- package/dist/NetworkMonitor.js +7 -5
- package/dist/{SyncEngineContext.d.ts → RuntimeContext.d.ts} +20 -13
- package/dist/{SyncEngineContext.js → RuntimeContext.js} +11 -12
- package/dist/SyncClient.d.ts +47 -47
- package/dist/SyncClient.js +215 -156
- package/dist/ai-sdk/coordinatedTool.d.ts +2 -2
- package/dist/ai-sdk/coordinatedTool.js +1 -1
- package/dist/ai-sdk/coordinationContext.d.ts +2 -2
- package/dist/ai-sdk/coordinationContext.js +1 -1
- package/dist/ai-sdk/wrap.d.ts +3 -3
- package/dist/ai-sdk/wrap.js +2 -2
- package/dist/auth/index.d.ts +1 -156
- package/dist/auth/index.js +8 -301
- package/dist/client/Ablo.d.ts +42 -287
- package/dist/client/Ablo.js +129 -963
- package/dist/client/abloClient.d.ts +309 -0
- package/dist/client/abloClient.js +13 -0
- package/dist/client/clientPrelude.d.ts +52 -0
- package/dist/client/clientPrelude.js +60 -0
- package/dist/client/consoleLogger.d.ts +2 -2
- package/dist/client/coreClient.d.ts +60 -0
- package/dist/client/coreClient.js +118 -0
- package/dist/client/createInternalComponents.d.ts +8 -4
- package/dist/client/createInternalComponents.js +17 -10
- package/dist/client/createModelProxy.d.ts +98 -373
- package/dist/client/createModelProxy.js +233 -139
- package/dist/client/humans.d.ts +69 -0
- package/dist/client/humans.js +78 -0
- package/dist/client/modelRegistration.d.ts +1 -1
- package/dist/client/modelRegistration.js +9 -9
- package/dist/client/options.d.ts +73 -17
- package/dist/client/reactiveEngine.d.ts +53 -0
- package/dist/client/reactiveEngine.js +688 -0
- package/dist/client/resourceTypes.d.ts +9 -250
- package/dist/client/resourceTypes.js +8 -5
- package/dist/client/schemaConfig.d.ts +4 -4
- package/dist/client/schemaConfig.js +6 -2
- package/dist/client/storeCluster.d.ts +47 -0
- package/dist/client/storeCluster.js +118 -0
- package/dist/client/storeLifecycle.d.ts +61 -0
- package/dist/client/storeLifecycle.js +231 -0
- package/dist/client/validateAbloOptions.d.ts +3 -2
- package/dist/client/validateAbloOptions.js +1 -1
- package/dist/client/wsMutationExecutor.d.ts +3 -3
- package/dist/client/wsMutationExecutor.js +3 -3
- package/dist/context.d.ts +22 -9
- package/dist/context.js +33 -9
- package/dist/coordination/ClaimLog.d.ts +26 -0
- package/dist/coordination/ClaimLog.js +32 -0
- package/dist/coordination/index.d.ts +1 -15
- package/dist/coordination/index.js +8 -31
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +2 -2
- package/dist/docs/catalog.d.ts +72 -0
- package/dist/docs/catalog.js +230 -0
- package/dist/docs/index.d.ts +10 -0
- package/dist/docs/index.js +10 -0
- package/dist/environment.d.ts +1 -40
- package/dist/environment.js +8 -37
- package/dist/index.d.ts +44 -36
- package/dist/index.js +30 -22
- package/dist/interfaces/index.d.ts +44 -134
- package/dist/keys/index.d.ts +1 -77
- package/dist/keys/index.js +8 -190
- package/dist/mutators/{RecordingTransaction.d.ts → RecordingMutation.d.ts} +4 -4
- package/dist/mutators/{RecordingTransaction.js → RecordingMutation.js} +2 -2
- package/dist/mutators/Transaction.d.ts +1 -1
- package/dist/mutators/Transaction.js +1 -1
- package/dist/mutators/UndoManager.d.ts +6 -6
- package/dist/mutators/UndoManager.js +5 -5
- package/dist/mutators/defineMutators.d.ts +3 -3
- package/dist/mutators/defineMutators.js +1 -1
- package/dist/mutators/inverseOp.js +2 -2
- package/dist/mutators/mutateActions.d.ts +3 -3
- package/dist/mutators/mutateActions.js +1 -1
- package/dist/mutators/readerActions.d.ts +1 -1
- package/dist/mutators/undoApply.d.ts +1 -1
- package/dist/mutators/undoApply.js +1 -1
- package/dist/policy/index.d.ts +2 -2
- package/dist/policy/index.js +1 -1
- package/dist/query/client.d.ts +5 -2
- package/dist/query/client.js +10 -9
- package/dist/query/types.d.ts +6 -41
- package/dist/query/types.js +2 -2
- package/dist/react/AbloProvider.d.ts +18 -8
- package/dist/react/AbloProvider.js +10 -9
- package/dist/react/context.d.ts +3 -3
- package/dist/react/context.js +1 -1
- package/dist/react/createAbloReact.d.ts +56 -0
- package/dist/react/createAbloReact.js +51 -0
- package/dist/react/index.d.ts +6 -5
- package/dist/react/index.js +6 -3
- package/dist/react/internalContext.d.ts +1 -1
- package/dist/react/useAblo.d.ts +12 -5
- package/dist/react/useAblo.js +26 -8
- package/dist/react/useCurrentUserId.js +1 -1
- package/dist/react/useErrorListener.js +1 -1
- package/dist/react/useMutationFailureListener.d.ts +2 -2
- package/dist/react/useMutationFailureListener.js +1 -1
- package/dist/react/useMutators.d.ts +3 -3
- package/dist/react/useMutators.js +3 -3
- package/dist/react/useUndoScope.d.ts +5 -5
- package/dist/react/useUndoScope.js +1 -1
- package/dist/schema/coordination.d.ts +69 -10
- package/dist/schema/coordination.js +90 -9
- package/dist/schema/ddl.js +2 -2
- package/dist/schema/diff.d.ts +1 -1
- package/dist/schema/generate.js +1 -1
- package/dist/schema/index.d.ts +11 -10
- package/dist/schema/index.js +22 -18
- package/dist/schema/queries.d.ts +27 -27
- package/dist/schema/queries.js +23 -23
- package/dist/schema/select.d.ts +3 -3
- package/dist/schema/select.js +6 -3
- package/dist/schema/serialize.d.ts +15 -6
- package/dist/schema/serialize.js +20 -3
- package/dist/schema/sugar.d.ts +6 -7
- package/dist/schema/sugar.js +9 -12
- package/dist/schema/syncDeltaRow.d.ts +4 -152
- package/dist/schema/syncDeltaRow.js +4 -105
- package/dist/server/adapter.d.ts +18 -1
- package/dist/server/commit.d.ts +10 -16
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/readConfig.d.ts +1 -1
- package/dist/source/adapter.d.ts +7 -5
- package/dist/source/adapter.js +7 -5
- package/dist/source/adapters/drizzle.d.ts +1 -1
- package/dist/source/adapters/drizzle.js +2 -2
- package/dist/source/adapters/kysely.d.ts +1 -1
- package/dist/source/adapters/kysely.js +1 -1
- package/dist/source/adapters/kyselyMutationCore.d.ts +1 -1
- package/dist/source/adapters/kyselyMutationCore.js +2 -2
- package/dist/source/adapters/memory.js +1 -1
- package/dist/source/adapters/prisma.d.ts +8 -3
- package/dist/source/adapters/prisma.js +1 -1
- package/dist/source/connector.js +1 -1
- package/dist/source/connectorProtocol.d.ts +2 -8
- package/dist/source/connectorProtocol.js +3 -2
- package/dist/source/contract.d.ts +29 -17
- package/dist/source/contract.js +27 -22
- package/dist/source/factory.d.ts +1 -1
- package/dist/source/idempotency.js +2 -2
- package/dist/source/index.d.ts +1 -0
- package/dist/source/index.js +3 -0
- package/dist/source/next.d.ts +1 -1
- package/dist/source/signing.d.ts +9 -2
- package/dist/source/signing.js +4 -1
- package/dist/source/types.d.ts +6 -4
- package/dist/source/types.js +1 -1
- package/dist/{core/storeContract.d.ts → storeContract.d.ts} +6 -6
- package/dist/{core → stores}/DatabaseManager.d.ts +3 -1
- package/dist/{core → stores}/DatabaseManager.js +14 -13
- package/dist/stores/ObjectStore.d.ts +1 -1
- package/dist/{core → stores}/StoreManager.d.ts +9 -26
- package/dist/{core → stores}/StoreManager.js +29 -77
- package/dist/stores/SyncActionStore.d.ts +4 -2
- package/dist/stores/SyncActionStore.js +11 -17
- package/dist/stores/syncAction.d.ts +26 -0
- package/dist/stores/syncAction.js +16 -0
- package/dist/surface.d.ts +3 -3
- package/dist/surface.js +6 -4
- package/dist/sync/BootstrapFetcher.d.ts +127 -6
- package/dist/sync/BootstrapFetcher.js +511 -83
- package/dist/sync/ConnectionManager.d.ts +6 -198
- package/dist/sync/ConnectionManager.js +6 -677
- package/dist/sync/OnDemandLoader.d.ts +5 -2
- package/dist/sync/OnDemandLoader.js +61 -21
- package/dist/sync/SubscriptionManager.d.ts +13 -2
- package/dist/sync/SubscriptionManager.js +23 -5
- package/dist/sync/SyncWebSocket.d.ts +27 -510
- package/dist/sync/SyncWebSocket.js +76 -954
- package/dist/sync/awaitClaimGrant.d.ts +4 -44
- package/dist/sync/awaitClaimGrant.js +4 -109
- package/dist/sync/bootstrapApply.d.ts +3 -0
- package/dist/sync/bootstrapApply.js +2 -2
- package/dist/sync/commitFrames.d.ts +6 -40
- package/dist/sync/commitFrames.js +6 -97
- package/dist/sync/contextPorts.d.ts +18 -0
- package/dist/sync/contextPorts.js +31 -0
- package/dist/sync/createClaimStream.d.ts +5 -49
- package/dist/sync/createClaimStream.js +5 -469
- package/dist/sync/createPresenceStream.d.ts +26 -4
- package/dist/sync/createPresenceStream.js +28 -20
- package/dist/sync/createSnapshot.d.ts +2 -2
- package/dist/sync/createSnapshot.js +1 -1
- package/dist/sync/credentialLifecycle.d.ts +5 -173
- package/dist/sync/credentialLifecycle.js +5 -320
- package/dist/sync/deltaPipeline.d.ts +13 -12
- package/dist/sync/deltaPipeline.js +21 -4
- package/dist/sync/groupChange.d.ts +3 -0
- package/dist/sync/groupChange.js +16 -14
- package/dist/sync/participants.d.ts +24 -6
- package/dist/sync/participants.js +32 -23
- package/dist/sync/schemaDrift.d.ts +55 -0
- package/dist/sync/schemaDrift.js +53 -0
- package/dist/sync/schemas.d.ts +23 -33
- package/dist/sync/schemas.js +29 -20
- package/dist/sync/syncPlan.d.ts +3 -3
- package/dist/sync/wsFrameHandlers.d.ts +6 -114
- package/dist/sync/wsFrameHandlers.js +6 -392
- package/dist/syncLog/contract.d.ts +20 -0
- package/dist/syncLog/contract.js +19 -0
- package/dist/syncLog/index.d.ts +1 -0
- package/dist/syncLog/index.js +1 -0
- package/dist/transaction/ablo.d.ts +88 -0
- package/dist/transaction/ablo.js +33 -0
- package/dist/{client/auth.d.ts → transaction/auth/apiKey.d.ts} +43 -8
- package/dist/{client/auth.js → transaction/auth/apiKey.js} +19 -0
- package/dist/transaction/auth/bootstrapScope.d.ts +15 -0
- package/dist/transaction/auth/bootstrapScope.js +1 -0
- package/dist/transaction/auth/capability.d.ts +212 -0
- package/dist/transaction/auth/capability.js +224 -0
- package/dist/{auth → transaction/auth}/credentialSource.d.ts +8 -1
- package/dist/{client → transaction/auth}/identity.d.ts +8 -7
- package/dist/{client → transaction/auth}/identity.js +1 -1
- package/dist/transaction/auth/index.d.ts +162 -0
- package/dist/transaction/auth/index.js +304 -0
- package/dist/{auth → transaction/auth}/schemas.d.ts +1 -1
- package/dist/{auth → transaction/auth}/schemas.js +13 -13
- package/dist/{client → transaction/auth}/sessionMint.d.ts +8 -8
- package/dist/{client → transaction/auth}/sessionMint.js +4 -7
- package/dist/transaction/coordination/awaitClaimGrant.d.ts +56 -0
- package/dist/transaction/coordination/awaitClaimGrant.js +124 -0
- package/dist/{client → transaction/coordination}/claimHeartbeatLoop.d.ts +34 -0
- package/dist/{client → transaction/coordination}/claimHeartbeatLoop.js +20 -0
- package/dist/transaction/coordination/claimMeta.d.ts +49 -0
- package/dist/transaction/coordination/claimMeta.js +52 -0
- package/dist/transaction/coordination/createClaimStream.d.ts +64 -0
- package/dist/transaction/coordination/createClaimStream.js +475 -0
- package/dist/transaction/coordination/events.d.ts +74 -0
- package/dist/transaction/coordination/events.js +7 -0
- package/dist/transaction/coordination/index.d.ts +19 -0
- package/dist/transaction/coordination/index.js +45 -0
- package/dist/transaction/coordination/locator.d.ts +104 -0
- package/dist/transaction/coordination/locator.js +102 -0
- package/dist/transaction/coordination/schema.d.ts +1536 -0
- package/dist/transaction/coordination/schema.js +1177 -0
- package/dist/transaction/coordination/targetConflict.d.ts +2 -0
- package/dist/transaction/coordination/targetConflict.js +107 -0
- package/dist/{coordination → transaction/coordination}/trace.d.ts +7 -18
- package/dist/{coordination → transaction/coordination}/trace.js +18 -25
- package/dist/transaction/durableWrites.d.ts +62 -0
- package/dist/{client → transaction}/durableWrites.js +28 -3
- package/dist/transaction/environment.d.ts +105 -0
- package/dist/transaction/environment.js +108 -0
- package/dist/{errorCodes.d.ts → transaction/errorCodes.d.ts} +12 -12
- package/dist/{errorCodes.js → transaction/errorCodes.js} +45 -18
- package/dist/{errors.d.ts → transaction/errors.d.ts} +37 -13
- package/dist/{errors.js → transaction/errors.js} +85 -16
- package/dist/transaction/footprint.d.ts +111 -0
- package/dist/transaction/footprint.js +0 -0
- package/dist/transaction/index.d.ts +20 -0
- package/dist/transaction/index.js +20 -0
- package/dist/transaction/keys/index.d.ts +87 -0
- package/dist/transaction/keys/index.js +207 -0
- package/dist/transaction/log/syncDeltaRow.d.ts +158 -0
- package/dist/transaction/log/syncDeltaRow.js +95 -0
- package/dist/{sync/syncPosition.d.ts → transaction/logPosition.d.ts} +22 -8
- package/dist/{sync/syncPosition.js → transaction/logPosition.js} +15 -6
- package/dist/transaction/logger.d.ts +16 -0
- package/dist/transaction/logger.js +7 -0
- package/dist/transaction/observability.d.ts +53 -0
- package/dist/transaction/observability.js +19 -0
- package/dist/transaction/plugin.d.ts +285 -0
- package/dist/transaction/plugin.js +106 -0
- package/dist/{policy → transaction/policy}/types.d.ts +3 -3
- package/dist/{policy → transaction/policy}/types.js +2 -0
- package/dist/transaction/resources/httpResources.d.ts +321 -0
- package/dist/transaction/resources/httpResources.js +7 -0
- package/dist/transaction/resources/modelOperations.d.ts +427 -0
- package/dist/transaction/resources/modelOperations.js +12 -0
- package/dist/transaction/resources/mutationOptions.d.ts +66 -0
- package/dist/transaction/resources/mutationOptions.js +9 -0
- package/dist/transaction/resources/where.d.ts +101 -0
- package/dist/transaction/resources/where.js +115 -0
- package/dist/{client → transaction/resources}/writeOptionsSchema.d.ts +2 -6
- package/dist/{client → transaction/resources}/writeOptionsSchema.js +9 -5
- package/dist/{schema → transaction/schema}/field.d.ts +17 -23
- package/dist/{schema → transaction/schema}/field.js +5 -5
- package/dist/transaction/schema/fieldRef.d.ts +38 -0
- package/dist/transaction/schema/fieldRef.js +11 -0
- package/dist/transaction/schema/loadStrategy.d.ts +45 -0
- package/dist/transaction/schema/loadStrategy.js +46 -0
- package/dist/{schema → transaction/schema}/model.d.ts +50 -35
- package/dist/{schema → transaction/schema}/model.js +30 -20
- package/dist/transaction/schema/openapi.d.ts +58 -0
- package/dist/transaction/schema/openapi.js +501 -0
- package/dist/{schema → transaction/schema}/relation.d.ts +21 -16
- package/dist/{schema → transaction/schema}/relation.js +7 -7
- package/dist/{schema → transaction/schema}/residency.d.ts +0 -9
- package/dist/{schema → transaction/schema}/residency.js +0 -5
- package/dist/{schema → transaction/schema}/roles.d.ts +5 -5
- package/dist/{schema → transaction/schema}/roles.js +5 -5
- package/dist/{schema → transaction/schema}/schema.d.ts +39 -10
- package/dist/{schema → transaction/schema}/schema.js +24 -3
- package/dist/{schema → transaction/schema}/tenancy.d.ts +1 -1
- package/dist/{schema → transaction/schema}/tenancy.js +7 -4
- package/dist/transaction/transactionLayer.d.ts +82 -0
- package/dist/transaction/transactionLayer.js +24 -0
- package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.d.ts +5 -6
- package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.js +9 -13
- package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.d.ts +9 -2
- package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.js +5 -9
- package/dist/{transactions/durableWriteStore.d.ts → transaction/transactions/settlement/pendingWrite.d.ts} +11 -37
- package/dist/transaction/transactions/settlement/pendingWrite.js +20 -0
- package/dist/transaction/transport/commitFrames.d.ts +90 -0
- package/dist/transaction/transport/commitFrames.js +134 -0
- package/dist/transaction/transport/connectionManager.d.ts +215 -0
- package/dist/transaction/transport/connectionManager.js +673 -0
- package/dist/transaction/transport/credentialLifecycle.d.ts +177 -0
- package/dist/transaction/transport/credentialLifecycle.js +324 -0
- package/dist/{sync → transaction/transport}/heartbeat.d.ts +3 -1
- package/dist/{sync → transaction/transport}/heartbeat.js +6 -4
- package/dist/transaction/transport/httpClient.d.ts +131 -0
- package/dist/{client → transaction/transport}/httpClient.js +6 -5
- package/dist/transaction/transport/httpOptions.d.ts +33 -0
- package/dist/transaction/transport/httpOptions.js +12 -0
- package/dist/{client → transaction/transport}/httpTransport.js +295 -97
- package/dist/{sync/NetworkProbe.d.ts → transaction/transport/networkProbe.d.ts} +7 -4
- package/dist/{sync/NetworkProbe.js → transaction/transport/networkProbe.js} +14 -13
- package/dist/transaction/transport/wsFrameHandlers.d.ts +128 -0
- package/dist/transaction/transport/wsFrameHandlers.js +429 -0
- package/dist/transaction/transport/wsTransport.d.ts +574 -0
- package/dist/transaction/transport/wsTransport.js +1023 -0
- package/dist/transaction/types/assertExact.d.ts +17 -0
- package/dist/transaction/types/assertExact.js +1 -0
- package/dist/{types → transaction/types}/global.d.ts +17 -2
- package/dist/{types → transaction/types}/global.js +2 -1
- package/dist/{types → transaction/types}/index.d.ts +14 -46
- package/dist/{types → transaction/types}/index.js +7 -16
- package/dist/{types → transaction/types}/streams.d.ts +73 -45
- package/dist/transaction/utils/duration.d.ts +50 -0
- package/dist/{utils → transaction/utils}/duration.js +32 -0
- package/dist/{utils → transaction/utils}/json.d.ts +18 -0
- package/dist/transaction/utils/json.js +276 -0
- package/dist/transaction/wire/accountResponses.d.ts +420 -0
- package/dist/transaction/wire/accountResponses.js +290 -0
- package/dist/transaction/wire/auth.d.ts +56 -0
- package/dist/transaction/wire/auth.js +63 -0
- package/dist/transaction/wire/claimEvent.d.ts +76 -0
- package/dist/transaction/wire/claimEvent.js +73 -0
- package/dist/transaction/wire/claims.d.ts +530 -0
- package/dist/transaction/wire/claims.js +327 -0
- package/dist/{wire → transaction/wire}/commit.d.ts +125 -193
- package/dist/{wire → transaction/wire}/commit.js +68 -47
- package/dist/{wire → transaction/wire}/delta.d.ts +66 -17
- package/dist/{wire → transaction/wire}/delta.js +37 -13
- package/dist/transaction/wire/errorEnvelope.d.ts +72 -0
- package/dist/{wire → transaction/wire}/errorEnvelope.js +36 -5
- package/dist/transaction/wire/feedCursor.d.ts +60 -0
- package/dist/transaction/wire/feedCursor.js +82 -0
- package/dist/transaction/wire/feedEvent.d.ts +204 -0
- package/dist/transaction/wire/feedEvent.js +65 -0
- package/dist/transaction/wire/frames.d.ts +194 -0
- package/dist/transaction/wire/frames.js +50 -0
- package/dist/transaction/wire/inboundFrames.d.ts +562 -0
- package/dist/transaction/wire/inboundFrames.js +116 -0
- package/dist/transaction/wire/index.d.ts +54 -0
- package/dist/transaction/wire/index.js +83 -0
- package/dist/{wire → transaction/wire}/listEnvelope.d.ts +13 -14
- package/dist/transaction/wire/listEnvelope.js +42 -0
- package/dist/transaction/wire/modelMutations.d.ts +31 -0
- package/dist/transaction/wire/modelMutations.js +52 -0
- package/dist/transaction/wire/modelResponses.d.ts +85 -0
- package/dist/transaction/wire/modelResponses.js +43 -0
- package/dist/transaction/wire/modelShape.d.ts +78 -0
- package/dist/transaction/wire/modelShape.js +74 -0
- package/dist/transactions/{TransactionQueue.d.ts → mutations/MutationQueue.d.ts} +85 -38
- package/dist/transactions/{TransactionQueue.js → mutations/MutationQueue.js} +141 -80
- package/dist/transactions/{TransactionStore.d.ts → mutations/MutationStore.d.ts} +8 -8
- package/dist/transactions/{TransactionStore.js → mutations/MutationStore.js} +2 -2
- package/dist/transactions/{coalesceRules.d.ts → mutations/coalesceRules.d.ts} +10 -10
- package/dist/transactions/{coalesceRules.js → mutations/coalesceRules.js} +1 -1
- package/dist/transactions/mutations/commitLatency.d.ts +52 -0
- package/dist/transactions/mutations/commitLatency.js +130 -0
- package/dist/transactions/{commitOutboxStore.d.ts → mutations/commitOutboxStore.d.ts} +1 -5
- package/dist/transactions/{commitOutboxStore.js → mutations/commitOutboxStore.js} +1 -1
- package/dist/transactions/{commitPayload.d.ts → mutations/commitPayload.d.ts} +18 -16
- package/dist/transactions/{commitPayload.js → mutations/commitPayload.js} +15 -15
- package/dist/transactions/{deltaConfirmation.d.ts → mutations/deltaConfirmation.d.ts} +15 -11
- package/dist/transactions/{deltaConfirmation.js → mutations/deltaConfirmation.js} +14 -12
- package/dist/transactions/mutations/durableWriteStore.d.ts +14 -0
- package/dist/transactions/mutations/durableWriteStore.js +12 -0
- package/dist/transactions/{optimisticApply.d.ts → mutations/optimisticApply.d.ts} +7 -7
- package/dist/transactions/{replayValidation.d.ts → mutations/replayValidation.d.ts} +4 -3
- package/dist/transactions/{replayValidation.js → mutations/replayValidation.js} +7 -5
- package/dist/utils/mobxSetup.d.ts +1 -1
- package/dist/utils/mobxSetup.js +5 -2
- package/dist/{core → views}/QueryView.d.ts +2 -2
- package/dist/{core → views}/QueryView.js +2 -2
- package/dist/{core → views}/ViewRegistry.d.ts +1 -1
- package/dist/{core/queryUtils.d.ts → views/incrementalView.d.ts} +6 -6
- package/dist/{core/queryUtils.js → views/incrementalView.js} +6 -6
- package/dist/webhooks/events.d.ts +2 -2
- package/dist/wire/index.d.ts +1 -34
- package/dist/wire/index.js +8 -49
- package/docs/agent-messaging.md +3 -3
- package/docs/agents.md +20 -13
- package/docs/api-keys.md +14 -10
- package/docs/api.md +27 -61
- package/docs/audit.md +6 -3
- package/docs/cli.md +41 -13
- package/docs/client-behavior.md +11 -9
- package/docs/concurrency-convention.md +49 -57
- package/docs/coordination.md +283 -121
- package/docs/data-sources.md +7 -5
- package/docs/debugging.md +39 -15
- package/docs/deployment.md +267 -0
- package/docs/examples/agent-human.md +49 -42
- package/docs/examples/ai-sdk-tool.md +69 -44
- package/docs/examples/existing-python-backend.md +8 -6
- package/docs/examples/nextjs.md +129 -47
- package/docs/examples/scoped-agent.md +46 -45
- package/docs/examples/server-agent.md +46 -26
- package/docs/groups.md +87 -30
- package/docs/guarantees.md +41 -12
- package/docs/how-it-works.md +38 -12
- package/docs/idempotency.md +126 -0
- package/docs/identity.md +77 -74
- package/docs/index.md +172 -86
- package/docs/integration-guide.md +31 -19
- package/docs/mcp.md +46 -21
- package/docs/migration.md +95 -18
- package/docs/operating-on-your-database.md +3 -1
- package/docs/projects.md +3 -1
- package/docs/quickstart.md +22 -5
- package/docs/react.md +31 -18
- package/docs/schema-contract.md +5 -3
- package/docs/session-settings.md +108 -0
- package/docs/sessions.md +4 -2
- package/docs/webhooks.md +12 -10
- package/llms.txt +48 -18
- package/package.json +21 -26
- package/dist/agent/Agent.d.ts +0 -366
- package/dist/agent/Agent.js +0 -514
- package/dist/agent/index.d.ts +0 -115
- package/dist/agent/index.js +0 -128
- package/dist/agent/session.d.ts +0 -93
- package/dist/agent/session.js +0 -149
- package/dist/agent/types.d.ts +0 -68
- package/dist/agent/types.js +0 -9
- package/dist/cli.cjs +0 -286329
- package/dist/client/durableWrites.d.ts +0 -21
- package/dist/client/httpClient.d.ts +0 -80
- package/dist/coordination/schema.d.ts +0 -722
- package/dist/coordination/schema.js +0 -578
- package/dist/schema/openapi.d.ts +0 -29
- package/dist/schema/openapi.js +0 -124
- package/dist/testing/fixtures/bootstrap.d.ts +0 -49
- package/dist/testing/fixtures/bootstrap.js +0 -59
- package/dist/testing/fixtures/deltas.d.ts +0 -83
- package/dist/testing/fixtures/deltas.js +0 -136
- package/dist/testing/fixtures/models.d.ts +0 -83
- package/dist/testing/fixtures/models.js +0 -272
- package/dist/testing/helpers/reactWrapper.d.ts +0 -69
- package/dist/testing/helpers/reactWrapper.js +0 -67
- package/dist/testing/helpers/syncEngineHarness.d.ts +0 -54
- package/dist/testing/helpers/syncEngineHarness.js +0 -73
- package/dist/testing/helpers/wait.d.ts +0 -30
- package/dist/testing/helpers/wait.js +0 -49
- package/dist/testing/index.d.ts +0 -23
- package/dist/testing/index.js +0 -33
- package/dist/testing/mocks/FakeDatabase.d.ts +0 -18
- package/dist/testing/mocks/FakeDatabase.js +0 -10
- package/dist/testing/mocks/MockMutationExecutor.d.ts +0 -87
- package/dist/testing/mocks/MockMutationExecutor.js +0 -192
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +0 -20
- package/dist/testing/mocks/MockNetworkMonitor.js +0 -46
- package/dist/testing/mocks/MockSyncContext.d.ts +0 -51
- package/dist/testing/mocks/MockSyncContext.js +0 -71
- package/dist/testing/mocks/MockSyncStore.d.ts +0 -88
- package/dist/testing/mocks/MockSyncStore.js +0 -171
- package/dist/testing/mocks/MockWebSocket.d.ts +0 -71
- package/dist/testing/mocks/MockWebSocket.js +0 -118
- package/dist/transactions/durableWriteStore.js +0 -30
- package/dist/utils/duration.d.ts +0 -25
- package/dist/utils/json.js +0 -88
- package/dist/wire/errorEnvelope.d.ts +0 -55
- package/dist/wire/frames.d.ts +0 -197
- package/dist/wire/frames.js +0 -49
- package/dist/wire/listEnvelope.js +0 -18
- package/docs/interaction-model.md +0 -97
- /package/dist/{core → query}/QueryProcessor.d.ts +0 -0
- /package/dist/{core → query}/QueryProcessor.js +0 -0
- /package/dist/{core/storeContract.js → storeContract.js} +0 -0
- /package/dist/{core → stores}/openIDBWithTimeout.d.ts +0 -0
- /package/dist/{core → stores}/openIDBWithTimeout.js +0 -0
- /package/dist/{client → transaction/auth}/credentialEndpoint.d.ts +0 -0
- /package/dist/{client → transaction/auth}/credentialEndpoint.js +0 -0
- /package/dist/{auth → transaction/auth}/credentialPolicy.d.ts +0 -0
- /package/dist/{auth → transaction/auth}/credentialPolicy.js +0 -0
- /package/dist/{auth → transaction/auth}/credentialSource.js +0 -0
- /package/dist/{client → transaction/auth}/hostedEndpoints.d.ts +0 -0
- /package/dist/{client → transaction/auth}/hostedEndpoints.js +0 -0
- /package/dist/{client → transaction}/persistence.d.ts +0 -0
- /package/dist/{client → transaction}/persistence.js +0 -0
- /package/dist/{client → transaction/resources}/functionalUpdate.d.ts +0 -0
- /package/dist/{client → transaction/resources}/functionalUpdate.js +0 -0
- /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.d.ts +0 -0
- /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.js +0 -0
- /package/dist/{client → transaction/transport}/httpTransport.d.ts +0 -0
- /package/dist/{types → transaction/types}/modelData.d.ts +0 -0
- /package/dist/{types → transaction/types}/modelData.js +0 -0
- /package/dist/{types → transaction/types}/participant.d.ts +0 -0
- /package/dist/{types → transaction/types}/participant.js +0 -0
- /package/dist/{types → transaction/types}/streams.js +0 -0
- /package/dist/{utils → transaction/utils}/asyncIterator.d.ts +0 -0
- /package/dist/{utils → transaction/utils}/asyncIterator.js +0 -0
- /package/dist/{wire → transaction/wire}/bootstrapReason.d.ts +0 -0
- /package/dist/{wire → transaction/wire}/bootstrapReason.js +0 -0
- /package/dist/{wire → transaction/wire}/protocol.d.ts +0 -0
- /package/dist/{wire → transaction/wire}/protocol.js +0 -0
- /package/dist/{wire → transaction/wire}/protocolVersion.d.ts +0 -0
- /package/dist/{wire → transaction/wire}/protocolVersion.js +0 -0
- /package/dist/transactions/{UnconfirmedWrites.d.ts → mutations/UnconfirmedWrites.d.ts} +0 -0
- /package/dist/transactions/{UnconfirmedWrites.js → mutations/UnconfirmedWrites.js} +0 -0
- /package/dist/transactions/{optimisticApply.js → mutations/optimisticApply.js} +0 -0
- /package/dist/{core → views}/ViewRegistry.js +0 -0
package/docs/migration.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Version History & Migration Guide
|
|
2
2
|
|
|
3
|
+
> Every breaking change and the edit it requires, newest first.
|
|
4
|
+
|
|
3
5
|
The breaking-changes-first companion to the [Changelog](../CHANGELOG.md). The
|
|
4
6
|
changelog tells the story of each release; this page tells you exactly what to
|
|
5
7
|
change when you upgrade.
|
|
@@ -11,6 +13,9 @@ change when you upgrade.
|
|
|
11
13
|
|
|
12
14
|
| Version | What changed | What to do |
|
|
13
15
|
|---|---|---|
|
|
16
|
+
| **0.36.0** | `ttlSeconds` deprecated on the join surfaces in favour of `ttl` | `useJoin({ scope, ttlSeconds: '5m' })` → `useJoin({ scope, ttl: '5m' })`; same for `ParticipantJoinOptions`. Both spellings work until 0.37.0 |
|
|
17
|
+
| **0.35.0** | Synchronous reads moved under `local`, mirroring the async verbs | `get(id)` → `local.retrieve(id)`; `getAll(options)` → `local.list(options)`; `getCount(options)` → `local.count(options)` |
|
|
18
|
+
| **0.35.0** | `causedByTaskId` write option + seven `turn_*` error codes removed | Delete the `causedByTaskId` argument from writes; a branch on `turn_validation_failed` was unreachable and can go with it |
|
|
14
19
|
| **0.34.0** | Presence verb renamed `watch` → `join` | `ablo.<model>.watch(ids)` → `ablo.<model>.join(ids)`; `useWatch` → `useJoin`; the `WatchOptions` / `UseWatchOptions` / `UseWatchReturn` types → `JoinOptions` / `UseJoinOptions` / `UseJoinReturn`; error code `model_watch_not_configured` → `model_join_not_configured` |
|
|
15
20
|
| **0.28.0** | Removed React placeholders that had no working runtime | `usePresence` → `usePeers` or `useJoin`; `useClaim` → `ablo.<model>.claim`; `SyncGroupProvider` / `useSyncGroup` → `useJoin({ scope })` |
|
|
16
21
|
| **0.11.0** | Historical `intent` → `claim` rename | The hook renamed in that release was later removed in 0.28.0. Current code uses `ablo.<model>.claim` or `useJoin` |
|
|
@@ -27,7 +32,79 @@ change when you upgrade.
|
|
|
27
32
|
|
|
28
33
|
---
|
|
29
34
|
|
|
30
|
-
## 0.
|
|
35
|
+
## 0.36.0: one lease is spelled `ttl`
|
|
36
|
+
|
|
37
|
+
```diff
|
|
38
|
+
- useJoin({ scope: { documents: [id] }, ttlSeconds: '5m' })
|
|
39
|
+
+ useJoin({ scope: { documents: [id] }, ttl: '5m' })
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`ablo.<model>.join(ids, { ttl })` has always said `ttl`, and so does every other
|
|
43
|
+
lease in the SDK: `claim`'s `ttl`, `ClaimLeaseOptions.ttl`. The lower-level join
|
|
44
|
+
surfaces said `ttlSeconds` while accepting exactly the same values, including
|
|
45
|
+
duration strings, so a `ttl: '5m'` handed down from the model verb arrived as
|
|
46
|
+
`ttlSeconds: '5m'`, a field asserting a unit its value did not carry.
|
|
47
|
+
|
|
48
|
+
Both spellings work until 0.37.0, and `ttl` wins if you pass both. The wire is
|
|
49
|
+
unchanged: it has always carried seconds and still does.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 0.35.0: the synchronous reads move under `local`
|
|
54
|
+
|
|
55
|
+
```diff
|
|
56
|
+
- const task = ablo.tasks.get(id);
|
|
57
|
+
- const open = ablo.tasks.getAll({ where: { status: 'open' } });
|
|
58
|
+
- const count = ablo.tasks.getCount({ where: { status: 'open' } });
|
|
59
|
+
+ const task = ablo.tasks.local.retrieve(id);
|
|
60
|
+
+ const open = ablo.tasks.local.list({ where: { status: 'open' } });
|
|
61
|
+
+ const count = ablo.tasks.local.count({ where: { status: 'open' } });
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Options, return types, and reactivity inside `useAblo` selectors are unchanged.
|
|
65
|
+
Every verb now matches its asynchronous sibling, and `local` narrows the read to
|
|
66
|
+
what has already synced — which is what lets it return a value rather than a
|
|
67
|
+
promise.
|
|
68
|
+
|
|
69
|
+
`getAll` and `getCount` are distinctive enough to rename by search. `get` is not:
|
|
70
|
+
in most codebases it is outnumbered many times over by `Map.get` and
|
|
71
|
+
`headers.get`, and no search separates them. Upgrade the package first and let
|
|
72
|
+
the compiler name the sites — each one is a type error at exactly the call that
|
|
73
|
+
has to move.
|
|
74
|
+
|
|
75
|
+
## 0.35.0: `causedByTaskId` and the `turn_*` error codes removed
|
|
76
|
+
|
|
77
|
+
0.9.2 retired the `turn` primitive but left one field standing: `causedByTaskId`
|
|
78
|
+
on the write options bag. It was never usable. The server validated it against a
|
|
79
|
+
task record that nothing in the system has ever created, so supplying it had the
|
|
80
|
+
whole batch rejected with `turn_validation_failed`, while leaving it null passed
|
|
81
|
+
straight through. The safe way to use the option was to not use it.
|
|
82
|
+
|
|
83
|
+
**Removed:** `MutationOptions.causedByTaskId`, the seven `turn_*` error codes
|
|
84
|
+
(`turn_validation_failed`, `turn_open_failed`, `turn_close_failed`,
|
|
85
|
+
`turn_not_found`, `turn_foreign_agent`, `parent_turn_not_found`,
|
|
86
|
+
`parent_turn_foreign_agent`), and the stored row's provenance slice
|
|
87
|
+
(`deltaProvenanceSchema` and the `DeltaProvenance` type). `syncDeltaRowSchema` is
|
|
88
|
+
now the core and attribution slices composed.
|
|
89
|
+
|
|
90
|
+
```diff
|
|
91
|
+
- await ablo.documents.update({ id, data, causedByTaskId: turnId });
|
|
92
|
+
+ await ablo.documents.update({ id, data });
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Attribution is unaffected. A delta still records the actor, the `onBehalfOf`
|
|
96
|
+
principal behind a delegated write, the capability that authorized it, and the
|
|
97
|
+
claim it was made under — which is what answers "who did this, and by what
|
|
98
|
+
right." On the wire the field was optional and nullable, so a client that still
|
|
99
|
+
sends it is accepted and ignored.
|
|
100
|
+
|
|
101
|
+
The `caused_by_task_id` column stays, for the reason 0.9.2 gave when it kept it:
|
|
102
|
+
the audit hash-chain signs its value into every row. Dropping it is a versioned
|
|
103
|
+
migration of its own.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 0.34.0: presence verb renamed `watch` → `join`
|
|
31
108
|
|
|
32
109
|
The model-level presence verb read like a data subscription but delivered
|
|
33
110
|
presence — who else is on a row and what they hold — so it now says what it
|
|
@@ -35,13 +112,13 @@ does. `ablo.<model>.join(ids, { ttl })` opens the participant handle
|
|
|
35
112
|
(`.peers`, `.claims`, `await using` disposal); the returned `status` was
|
|
36
113
|
already `'joined'`, and the layer beneath always called itself `join`, so the
|
|
37
114
|
verb now matches. `onChange` remains the way to hear row *values* change, and
|
|
38
|
-
`track` remains the durable
|
|
115
|
+
`track` remains the durable premise for actors.
|
|
39
116
|
|
|
40
117
|
```ts
|
|
41
118
|
// before
|
|
42
|
-
await using room = await ablo.
|
|
119
|
+
await using room = await ablo.documents.watch(documentIds, { ttl: '5m' });
|
|
43
120
|
// after
|
|
44
|
-
await using room = await ablo.
|
|
121
|
+
await using room = await ablo.documents.join(documentIds, { ttl: '5m' });
|
|
45
122
|
```
|
|
46
123
|
|
|
47
124
|
The React hook follows: `useWatch({ scope })` → `useJoin({ scope })`. There is
|
|
@@ -50,7 +127,7 @@ no compatibility alias — rename the call sites and the `WatchOptions` /
|
|
|
50
127
|
|
|
51
128
|
---
|
|
52
129
|
|
|
53
|
-
## 0.28.0
|
|
130
|
+
## 0.28.0: dead React multiplayer placeholders removed
|
|
54
131
|
|
|
55
132
|
Four React exports looked usable but had no live implementation:
|
|
56
133
|
|
|
@@ -65,7 +142,7 @@ Four React exports looked usable but had no live implementation:
|
|
|
65
142
|
There is no compatibility alias: the replacement APIs were already the only
|
|
66
143
|
working paths.
|
|
67
144
|
|
|
68
|
-
## 0.11.0
|
|
145
|
+
## 0.11.0: `intent` → `claim` rename completed
|
|
69
146
|
|
|
70
147
|
> **Historical note:** this section documents the 0.11.0 transition.
|
|
71
148
|
> `useClaim` was subsequently removed in 0.28.0 because its provider callback
|
|
@@ -108,7 +185,7 @@ contending holders (`AbloClaimedError.claims` and a policy reason folded into th
|
|
|
108
185
|
message), and `participantKind` is the canonical `'user' | 'agent' | 'system'`
|
|
109
186
|
on presence and claim state.
|
|
110
187
|
|
|
111
|
-
## 0.10.0
|
|
188
|
+
## 0.10.0: environment enum `sandbox` / `production`; stateless HTTP transport
|
|
112
189
|
|
|
113
190
|
### Environment enum rename (the only breaking change)
|
|
114
191
|
|
|
@@ -148,7 +225,7 @@ distinct stores.
|
|
|
148
225
|
server-side actors (agents, workers, serverless): the same `ablo.<model>` surface
|
|
149
226
|
and `claim` coordination, but each call is one HTTP round-trip with identity on
|
|
150
227
|
the Bearer credential — no websocket, no local synced pool. The return type
|
|
151
|
-
narrows, so stateful-only APIs (
|
|
228
|
+
narrows, so stateful-only APIs (the `local` reads, `onChange`) become compile
|
|
152
229
|
errors instead of latent runtime gaps. Existing code keeps the default
|
|
153
230
|
`'websocket'` transport, unchanged.
|
|
154
231
|
|
|
@@ -164,7 +241,7 @@ await ablo.tasks.update({ id, data: { status: 'done' } });
|
|
|
164
241
|
|
|
165
242
|
---
|
|
166
243
|
|
|
167
|
-
## 0.9.2
|
|
244
|
+
## 0.9.2: `turn` / agent-`tasks` removed; `intents` deprecated
|
|
168
245
|
|
|
169
246
|
The SDK's coordination surface is now exactly two things: `ablo.<model>` writes
|
|
170
247
|
and `claim`. The parallel `turn` / agent-`tasks` mechanism was redundant —
|
|
@@ -213,7 +290,7 @@ everywhere you coordinate concurrent work.
|
|
|
213
290
|
|
|
214
291
|
---
|
|
215
292
|
|
|
216
|
-
## 0.9.0
|
|
293
|
+
## 0.9.0: one options object per verb; disposable `claim`
|
|
217
294
|
|
|
218
295
|
Every model verb takes a single options object, so the id, the data, and every
|
|
219
296
|
modifier are named siblings. Reactive local reads stay on the synchronous
|
|
@@ -227,7 +304,7 @@ modifier are named siblings. Reactive local reads stay on the synchronous
|
|
|
227
304
|
+ await ablo.tasks.retrieve({ id })
|
|
228
305
|
|
|
229
306
|
- useAblo((ablo) => ablo.tasks.retrieve(id)) ?? serverTask
|
|
230
|
-
+ useAblo((ablo) => ablo.tasks.
|
|
307
|
+
+ useAblo((ablo) => ablo.tasks.local.retrieve(id)) ?? serverTask
|
|
231
308
|
```
|
|
232
309
|
|
|
233
310
|
`claim` now returns a disposable handle instead of taking a callback. The handle
|
|
@@ -247,7 +324,7 @@ options object.
|
|
|
247
324
|
|
|
248
325
|
---
|
|
249
326
|
|
|
250
|
-
## 0.8.0
|
|
327
|
+
## 0.8.0: callable `claim` namespace
|
|
251
328
|
|
|
252
329
|
The flat coordination methods are gone; everything lives under `claim`.
|
|
253
330
|
|
|
@@ -260,7 +337,7 @@ The flat coordination methods are gone; everything lives under `claim`.
|
|
|
260
337
|
|
|
261
338
|
---
|
|
262
339
|
|
|
263
|
-
## 0.7.0
|
|
340
|
+
## 0.7.0: legacy React hooks removed
|
|
264
341
|
|
|
265
342
|
The query/mutation hooks were replaced by the single `useAblo()` accessor over
|
|
266
343
|
typed model methods.
|
|
@@ -282,7 +359,7 @@ shape with the canonical `{ type, code, message, doc_url, request_id }` envelope
|
|
|
282
359
|
|
|
283
360
|
---
|
|
284
361
|
|
|
285
|
-
## 0.6.0
|
|
362
|
+
## 0.6.0: `onChange` and the Resource → Model rename
|
|
286
363
|
|
|
287
364
|
```diff
|
|
288
365
|
- ablo.tasks.subscribe(cb)
|
|
@@ -298,7 +375,7 @@ Also renamed: `Ablo.Resource.*` → `Ablo.Model.*`, `ModelTarget.resource` →
|
|
|
298
375
|
|
|
299
376
|
---
|
|
300
377
|
|
|
301
|
-
## 0.5.0
|
|
378
|
+
## 0.5.0: intent-handle method renames
|
|
302
379
|
|
|
303
380
|
On the model intent handle (`ablo.<model>.intent(id)`):
|
|
304
381
|
|
|
@@ -315,7 +392,7 @@ unchanged at this release. (They were later folded under `claim` in 0.9.2.)
|
|
|
315
392
|
|
|
316
393
|
---
|
|
317
394
|
|
|
318
|
-
## 0.3.0
|
|
395
|
+
## 0.3.0: umbrella `<AbloProvider>`
|
|
319
396
|
|
|
320
397
|
One provider component now owns the full React lifecycle. `<SyncProvider>`,
|
|
321
398
|
`createAbloContext()`, and `withSync` were removed.
|
|
@@ -349,10 +426,10 @@ old code or old docs, this is the through-line:
|
|
|
349
426
|
|
|
350
427
|
| Release | State of coordination |
|
|
351
428
|
|---|---|
|
|
352
|
-
| 0.4.0 | `ablo.<model>.intent(id)` introduced
|
|
429
|
+
| 0.4.0 | `ablo.<model>.intent(id)` introduced: per-entity intent handle |
|
|
353
430
|
| 0.5.0 | Intent-handle methods renamed to claim vocabulary (`acquire`→`claim`, …) |
|
|
354
431
|
| 0.8.0 | Callable `claim` namespace (`claim(id)`, `claim.state`, `claim.queue`, …) |
|
|
355
432
|
| 0.9.0 | `claim` returns an `await using` disposable handle |
|
|
356
|
-
| 0.9.2 | `intents` deprecated and made `@internal
|
|
433
|
+
| 0.9.2 | `intents` deprecated and made `@internal`: **`claim` is the one coordination API** |
|
|
357
434
|
|
|
358
435
|
For the full chronological history, see the [Changelog](../CHANGELOG.md).
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Operating on Your Database
|
|
2
2
|
|
|
3
|
+
> Which actions run freely, which to verify first, and which belong to a human.
|
|
4
|
+
|
|
3
5
|
Ablo sits over your database as a coordination layer, not an owner. It reads
|
|
4
6
|
your Postgres replication stream and routes each write through a claim-checked
|
|
5
7
|
commit that lands in your own tables. It never runs DDL, never migrates, never
|
|
@@ -79,7 +81,7 @@ code question. The question that governs safety is *does removing this drop a
|
|
|
79
81
|
real table on the next push* — and that one is answered against the database,
|
|
80
82
|
not the codebase. Before removing a model that maps a live table, confirm the
|
|
81
83
|
table is gone or empty and that your push path is additive; otherwise keep the
|
|
82
|
-
model until the data is dealt with. A `load: '
|
|
84
|
+
model until the data is dealt with. A `load: 'lazy'` mapping is often present
|
|
83
85
|
precisely to hold a table in place, so treat its comment as load-bearing.
|
|
84
86
|
|
|
85
87
|
## The verification loop
|
package/docs/projects.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Projects
|
|
2
2
|
|
|
3
|
+
> One organization, many apps — each with its own schema, data planes, and keys.
|
|
4
|
+
|
|
3
5
|
A **project** is the isolation unit inside your organization — the shape you
|
|
4
6
|
know from Neon or Supabase. Each app you build gets its own project, and each
|
|
5
7
|
project gets its own schema, its own sandbox/production data planes, and its
|
|
@@ -93,5 +95,5 @@ another org's project ids 404 — never confirm existence across orgs.
|
|
|
93
95
|
|
|
94
96
|
| Code | Status | Meaning |
|
|
95
97
|
|------|--------|---------|
|
|
96
|
-
| `project_scope_denied` | 403 | The model/resource belongs to another project in your org
|
|
98
|
+
| `project_scope_denied` | 403 | The model/resource belongs to another project in your org: use a key minted for that project. |
|
|
97
99
|
| `project_slug_taken` | 409 | A project with this slug already exists in the organization. |
|
package/docs/quickstart.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Quickstart
|
|
2
2
|
|
|
3
|
+
> Make your first coordinated write, on the Postgres you already have.
|
|
4
|
+
|
|
3
5
|
Build with Ablo on **the Postgres you already have**. You declare a small Ablo
|
|
4
|
-
schema for the models
|
|
6
|
+
schema for the models your agents edit together, connect Ablo to your
|
|
5
7
|
database (`ablo connect`), and read and write every one of those models through
|
|
6
8
|
`ablo.<model>`. You write through Ablo; it lands the change in your Postgres and
|
|
7
9
|
confirms it by tailing your write-ahead log (WAL). Your rows live in your database,
|
|
@@ -86,6 +88,22 @@ import type { Model } from '@abloatai/ablo/schema';
|
|
|
86
88
|
type WeatherReport = Model<'weatherReports'>; // fully typed from YOUR schema
|
|
87
89
|
```
|
|
88
90
|
|
|
91
|
+
The same block is where you name the metadata your claims carry. Add a
|
|
92
|
+
`ClaimMeta` key and every `claim.state`, `claim.queue`, and held claim reads
|
|
93
|
+
`target.meta` as that shape:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
declare module '@abloatai/ablo' {
|
|
97
|
+
interface Register {
|
|
98
|
+
Schema: typeof schema;
|
|
99
|
+
ClaimMeta: { blocks: string[] };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const holder = ablo.weatherReports.claim.state({ id });
|
|
104
|
+
holder?.target.meta?.blocks.length; // typed, no guard
|
|
105
|
+
```
|
|
106
|
+
|
|
89
107
|
(The same `Register` binding types every hook and client — it's the
|
|
90
108
|
TanStack-Router pattern: declare the source of truth once, everything
|
|
91
109
|
infers from it.)
|
|
@@ -169,10 +187,9 @@ tables** — Ablo reads them, it does not create or migrate them:
|
|
|
169
187
|
the tables with your own migration tool; Ablo syncs the subset of models you
|
|
170
188
|
declared and reports the rest as "ignored / owned by you."
|
|
171
189
|
|
|
172
|
-
> **
|
|
173
|
-
>
|
|
174
|
-
>
|
|
175
|
-
> your own migrations stay in charge of your schema.
|
|
190
|
+
> **Starting from an empty database?** `npx ablo migrate` creates the tables
|
|
191
|
+
> your schema needs. Once they exist, your own migration tool stays in charge
|
|
192
|
+
> of them — Ablo adopts whatever shape you evolve.
|
|
176
193
|
|
|
177
194
|
Nothing runs locally — there is no dev server to start. Your app talks to Ablo's
|
|
178
195
|
hosted API; the rows live in your database.
|
package/docs/react.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# React
|
|
2
2
|
|
|
3
|
+
> Provider, hooks, and reactive reads for the interfaces people watch agent work arrive in.
|
|
4
|
+
|
|
3
5
|
The React bindings for `@abloatai/ablo`. Use them when you want live
|
|
4
6
|
data on the client without writing fetch + WebSocket plumbing yourself.
|
|
5
7
|
|
|
@@ -25,6 +27,7 @@ the thing, then pass it.
|
|
|
25
27
|
```ts
|
|
26
28
|
// lib/ablo.ts
|
|
27
29
|
import Ablo from '@abloatai/ablo';
|
|
30
|
+
import { createAbloReact } from '@abloatai/ablo/react';
|
|
28
31
|
import { schema } from '@/ablo/schema';
|
|
29
32
|
|
|
30
33
|
// The browser never holds your API key. It mints a short-lived session token
|
|
@@ -33,8 +36,18 @@ export const ablo = Ablo({
|
|
|
33
36
|
schema,
|
|
34
37
|
authEndpoint: '/api/ablo-session',
|
|
35
38
|
});
|
|
39
|
+
|
|
40
|
+
// The typed binding: capture the schema once, and every component imports
|
|
41
|
+
// born-typed hooks from this file — `useAblo()` takes no type arguments,
|
|
42
|
+
// and a selector's `ablo` parameter knows your models.
|
|
43
|
+
export const { AbloProvider, useAblo } = createAbloReact(schema);
|
|
36
44
|
```
|
|
37
45
|
|
|
46
|
+
Import `AbloProvider` and `useAblo` from `lib/ablo` rather than from the
|
|
47
|
+
package, and the schema generic never appears at a call site again — the
|
|
48
|
+
same one-binding-file convention as tRPC's `createTRPCReact` or
|
|
49
|
+
react-redux's typed hooks.
|
|
50
|
+
|
|
38
51
|
## AbloProvider
|
|
39
52
|
|
|
40
53
|
Mount it once near the root of your tree. It owns the connection, the local
|
|
@@ -65,10 +78,10 @@ export function Providers({
|
|
|
65
78
|
|
|
66
79
|
| Prop | Default | Purpose |
|
|
67
80
|
| ----------- | ---------------- | --------------------------------------------------------------------------------------------------------- |
|
|
68
|
-
| `client`
|
|
81
|
+
| `client` |: | **Required.** The `Ablo({ schema, apiKey })` instance. It carries the schema and connection config. |
|
|
69
82
|
| `userId` | resolved from auth | App participant id for app-owned fields and your `identityRoles`. Not the security boundary. |
|
|
70
83
|
| `fallback` | neutral spinner | Rendered during the *first* bootstrap only. Pass a branded skeleton, `null`, or `'passthrough'`. |
|
|
71
|
-
| `onError`
|
|
84
|
+
| `onError` |: | Engine / WebSocket / bootstrap errors. Wire to Sentry / Datadog. |
|
|
72
85
|
|
|
73
86
|
Everything that used to be a provider prop — `schema`, `url`, `apiKey`,
|
|
74
87
|
`teamIds`, `syncGroups`, `persistence`, `bootstrapMode` — now lives on
|
|
@@ -77,7 +90,7 @@ identity comes from, and why the API key never reaches the browser, is the whole
|
|
|
77
90
|
of [Identity & Sync Groups](./identity.md) — read that if it isn't obvious how
|
|
78
91
|
org / team / user map to what a participant can see.
|
|
79
92
|
|
|
80
|
-
## useAblo
|
|
93
|
+
## useAblo: model client
|
|
81
94
|
|
|
82
95
|
```tsx
|
|
83
96
|
'use client';
|
|
@@ -85,7 +98,7 @@ org / team / user map to what a participant can see.
|
|
|
85
98
|
import { useAblo } from '@abloatai/ablo/react';
|
|
86
99
|
|
|
87
100
|
export function ReportView({ report: serverReport }: { report: { id: string; location: string } }) {
|
|
88
|
-
const report = useAblo((ablo) => ablo.weatherReports.
|
|
101
|
+
const report = useAblo((ablo) => ablo.weatherReports.local.retrieve(serverReport.id)) ?? serverReport;
|
|
89
102
|
const active = useAblo((ablo) => ablo.weatherReports.claim.state({ id: serverReport.id }));
|
|
90
103
|
const claimed = Boolean(active);
|
|
91
104
|
|
|
@@ -95,7 +108,7 @@ export function ReportView({ report: serverReport }: { report: { id: string; loc
|
|
|
95
108
|
|
|
96
109
|
The hook:
|
|
97
110
|
|
|
98
|
-
1. Uses the same `ablo.<model>.
|
|
111
|
+
1. Uses the same `ablo.<model>.local.retrieve(id)` / `.local.list()` methods you'd call anywhere
|
|
99
112
|
else in the SDK — the hook just makes them reactive.
|
|
100
113
|
2. Tracks the model fields read by the selector and re-renders when confirmed
|
|
101
114
|
deltas arrive.
|
|
@@ -110,14 +123,14 @@ effects, or writes:
|
|
|
110
123
|
const abloClient = useAblo();
|
|
111
124
|
```
|
|
112
125
|
|
|
113
|
-
Prefer selector reads like `useAblo((ablo) => ablo.<model>.
|
|
126
|
+
Prefer selector reads like `useAblo((ablo) => ablo.<model>.local.retrieve(id))`. Older hooks
|
|
114
127
|
also accept a string model name; prefer the selector form shown above.
|
|
115
128
|
|
|
116
129
|
For collections, keep the selector on the model client too:
|
|
117
130
|
|
|
118
131
|
```tsx
|
|
119
132
|
const reports = useAblo((ablo) =>
|
|
120
|
-
ablo.weatherReports.
|
|
133
|
+
ablo.weatherReports.local.list({
|
|
121
134
|
where: { projectId },
|
|
122
135
|
filter: (report) => report.status !== 'ready',
|
|
123
136
|
state: 'live',
|
|
@@ -135,7 +148,7 @@ Use `retrieve` in Server Components when the row may not be in the local pool
|
|
|
135
148
|
yet — it hydrates from the local store and the server, and returns a Promise, so
|
|
136
149
|
`await` it. (Server reads come in two shapes: `retrieve({ id })` for one row and
|
|
137
150
|
`list({ where })` for many; both are async. The synchronous local reads are
|
|
138
|
-
`
|
|
151
|
+
the `local` reads, used in render below.)
|
|
139
152
|
|
|
140
153
|
## Writes
|
|
141
154
|
|
|
@@ -178,7 +191,7 @@ imperative work after an event or effect.
|
|
|
178
191
|
|
|
179
192
|
See [API reference](/docs/api) for the full options surface.
|
|
180
193
|
|
|
181
|
-
## useJoin
|
|
194
|
+
## useJoin: scoped presence + read interest
|
|
182
195
|
|
|
183
196
|
`useJoin` is the React form of `ablo.<model>.join`. It joins multiplayer for a
|
|
184
197
|
scope on the engine's existing socket (one TCP connection, N logical
|
|
@@ -191,11 +204,11 @@ write interest in it.
|
|
|
191
204
|
|
|
192
205
|
import { useJoin } from '@abloatai/ablo/react';
|
|
193
206
|
|
|
194
|
-
export function DeckPresence({
|
|
207
|
+
export function DeckPresence({ workspaceId }: { workspaceId: string }) {
|
|
195
208
|
const { peers, claims, status } = useJoin({
|
|
196
|
-
scope: { slideDecks:
|
|
209
|
+
scope: { slideDecks: workspaceId },
|
|
197
210
|
claim: true, // I intend to write — pin the scope + let peers observe the claim
|
|
198
|
-
hydrate: true, // backfill the
|
|
211
|
+
hydrate: true, // backfill the workspace's current rows if not already loaded
|
|
199
212
|
});
|
|
200
213
|
|
|
201
214
|
if (status !== 'joined') return <span>connecting…</span>;
|
|
@@ -207,10 +220,10 @@ Options (`UseJoinOptions`):
|
|
|
207
220
|
|
|
208
221
|
| Option | Default | Effect |
|
|
209
222
|
| --- | --- | --- |
|
|
210
|
-
| `scope`
|
|
211
|
-
| `claim` | `false` | Acquire a write-claim on the scope (sent so peers observe it; pins the scope so it never warm-drops while held). A viewer is not a claimant
|
|
223
|
+
| `scope` |: | Model-form scope (`{ slideDecks: id }`), resolved through the schema. Omit for engine-wide. |
|
|
224
|
+
| `claim` | `false` | Acquire a write-claim on the scope (sent so peers observe it; pins the scope so it never warm-drops while held). A viewer is not a claimant: leave `false` for read-only. |
|
|
212
225
|
| `hydrate` | `false` | Backfill the scope's current rows into the pool once on enter, then keep them fresh via the live tail. Set `true` for deep-linked / never-opened entities. Single-flight; soft-fails. |
|
|
213
|
-
| `ttlSeconds`
|
|
226
|
+
| `ttlSeconds` |: | Lease TTL for the scope claim. |
|
|
214
227
|
| `paused` | `false` | Tear down and don't re-join while true. |
|
|
215
228
|
|
|
216
229
|
Returns (`UseJoinReturn`): `{ participant, peers, claims, status, error }`.
|
|
@@ -218,7 +231,7 @@ Returns (`UseJoinReturn`): `{ participant, peers, claims, status, error }`.
|
|
|
218
231
|
write-claims; `status` is the join lifecycle. Auto-cleans up on unmount or when
|
|
219
232
|
`paused` flips true.
|
|
220
233
|
|
|
221
|
-
## usePeers
|
|
234
|
+
## usePeers: read-only presence
|
|
222
235
|
|
|
223
236
|
`usePeers` is a *pure reader* of the presence stream already flowing on the
|
|
224
237
|
connection. Unlike `useJoin`, it does **not** enter/leave a scope (no
|
|
@@ -230,8 +243,8 @@ connection is subscribed to.
|
|
|
230
243
|
|
|
231
244
|
import { usePeers } from '@abloatai/ablo/react';
|
|
232
245
|
|
|
233
|
-
export function CursorBroadcaster({
|
|
234
|
-
const peers = usePeers({ slideDecks:
|
|
246
|
+
export function CursorBroadcaster({ workspaceId }: { workspaceId: string }) {
|
|
247
|
+
const peers = usePeers({ slideDecks: workspaceId });
|
|
235
248
|
const alone = !peers.some((p) => p.participantKind === 'user');
|
|
236
249
|
// suppress live-cursor broadcasts while alone
|
|
237
250
|
}
|
package/docs/schema-contract.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Schema Contract
|
|
2
2
|
|
|
3
|
+
> One schema becomes typed clients, agent writes, interface reads, and the hosted push.
|
|
4
|
+
|
|
3
5
|
Ablo's schema is the integration contract. Define it once, pass it to `Ablo(...)`,
|
|
4
6
|
and every actor gets the same typed model surface:
|
|
5
7
|
|
|
@@ -10,7 +12,7 @@ defineSchema(...) -> ablo.<model>.create/retrieve/update/claim(...)
|
|
|
10
12
|
That one object drives:
|
|
11
13
|
|
|
12
14
|
- typed model clients in trusted server runtimes,
|
|
13
|
-
- React selectors through `useAblo((ablo) => ablo.<model>.
|
|
15
|
+
- React selectors through `useAblo((ablo) => ablo.<model>.local.retrieve(id))`,
|
|
14
16
|
- agent and background-worker writes,
|
|
15
17
|
- Data Source request/response shape when your database stays canonical,
|
|
16
18
|
- hosted schema push, migration planning, and schema-version gating.
|
|
@@ -75,8 +77,8 @@ const ready = await ablo.weatherReports.list({ where: { status: 'ready' } });
|
|
|
75
77
|
Use synchronous local reads in render after data has synced:
|
|
76
78
|
|
|
77
79
|
```ts
|
|
78
|
-
const report = ablo.weatherReports.
|
|
79
|
-
const pending = ablo.weatherReports.
|
|
80
|
+
const report = ablo.weatherReports.local.retrieve(reportId);
|
|
81
|
+
const pending = ablo.weatherReports.local.list({ where: { status: 'pending' } });
|
|
80
82
|
```
|
|
81
83
|
|
|
82
84
|
Use model writes for every actor:
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Session Settings
|
|
2
|
+
|
|
3
|
+
> Point your row-level-security policies at Ablo's writes, by naming the Postgres session settings they already read.
|
|
4
|
+
|
|
5
|
+
Ablo writes your rows through a scoped role with `row_security` on and
|
|
6
|
+
`NOBYPASSRLS` set, so your policies govern its writes the same way they govern
|
|
7
|
+
your own application's. They only govern well if they can see who the write is
|
|
8
|
+
for. Before each write, Ablo sets its own identity context on the transaction —
|
|
9
|
+
and if your policies read settings under names you chose, `sessionSettings` maps
|
|
10
|
+
one to the other:
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { defineSchema, model, z } from '@abloatai/ablo/schema';
|
|
14
|
+
|
|
15
|
+
export const schema = defineSchema(
|
|
16
|
+
{
|
|
17
|
+
invoices: model({
|
|
18
|
+
total: z.number(),
|
|
19
|
+
reference: z.string(),
|
|
20
|
+
}),
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
sessionSettings: { 'app.current_org': 'orgId' },
|
|
24
|
+
},
|
|
25
|
+
);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
A policy written against `current_setting('app.current_org')` now applies to
|
|
29
|
+
Ablo's write, unchanged:
|
|
30
|
+
|
|
31
|
+
```sql
|
|
32
|
+
CREATE POLICY tenant_isolation ON invoices
|
|
33
|
+
USING (organization_id = current_setting('app.current_org', true));
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The key is the setting name **your** policies read. The value names which piece
|
|
37
|
+
of Ablo's authenticated identity fills it.
|
|
38
|
+
|
|
39
|
+
## What Ablo sets on its own
|
|
40
|
+
|
|
41
|
+
Every direct write runs inside a transaction that begins by setting this
|
|
42
|
+
context, whether or not you map anything:
|
|
43
|
+
|
|
44
|
+
| Setting | Carries |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| `app.current_org_id` | The organization the credential acts for |
|
|
47
|
+
| `app.current_project_id` | The project |
|
|
48
|
+
| `app.current_environment` | The environment |
|
|
49
|
+
| `app.current_sandbox_id` | The sandbox, when the write is in one |
|
|
50
|
+
| `app.current_participant_id` | The participant making the write |
|
|
51
|
+
| `app.current_participant_kind` | Whether that participant is a person, an agent, or the system |
|
|
52
|
+
| `app.current_user_id` | The person on whose behalf the write is made |
|
|
53
|
+
|
|
54
|
+
If your policies read these names directly, you need no mapping at all — this
|
|
55
|
+
page is for the case where they read different ones.
|
|
56
|
+
|
|
57
|
+
`app.current_user_id` is worth reading twice, because it has three states rather
|
|
58
|
+
than two. It carries a person's id when a person is behind the write. It carries
|
|
59
|
+
`*` when a backend credential is acting as the organization itself, which is the
|
|
60
|
+
authority a server-side key holds. And it carries the empty string when no
|
|
61
|
+
identity could be established — written explicitly rather than left alone, so a
|
|
62
|
+
policy on a pooled connection reads absence as absence and denies, instead of
|
|
63
|
+
inheriting whatever the previous transaction left behind.
|
|
64
|
+
|
|
65
|
+
## What a mapping may name
|
|
66
|
+
|
|
67
|
+
The value side is a closed set, and every member is resolved by Ablo from the
|
|
68
|
+
authenticated key and the plane:
|
|
69
|
+
|
|
70
|
+
`orgId` · `projectId` · `environment` · `sandboxId` · `participantId` ·
|
|
71
|
+
`participantKind`
|
|
72
|
+
|
|
73
|
+
Because none of them come from the caller, a mapping can forward the tenant
|
|
74
|
+
identity Ablo already trusts, but cannot widen what a writer sees. A setting name
|
|
75
|
+
takes exactly one source — the name is the key — so naming the same setting twice
|
|
76
|
+
is unrepresentable rather than something to resolve later.
|
|
77
|
+
|
|
78
|
+
## What a mapping may not name
|
|
79
|
+
|
|
80
|
+
The settings in the table above, along with `row_security`, `search_path`,
|
|
81
|
+
`statement_timeout`, and `lock_timeout`, are reserved. `defineSchema` rejects a
|
|
82
|
+
mapping onto any of them, and the engine refuses one at write time too.
|
|
83
|
+
|
|
84
|
+
The reason is worth stating plainly: those settings are how Ablo bounds its own
|
|
85
|
+
write. A schema that could reassign them could relax the scoping under which
|
|
86
|
+
Ablo writes, which would put the boundary inside the thing being bounded. Point
|
|
87
|
+
your policies at a name you own — `app.current_org` rather than
|
|
88
|
+
`app.current_org_id` — and map that.
|
|
89
|
+
|
|
90
|
+
## Reads served from the log
|
|
91
|
+
|
|
92
|
+
One arrangement cannot honour a policy that names a person. When a plane is
|
|
93
|
+
served from its retained log rather than from its tables, every row carries the
|
|
94
|
+
organization and the project, but not the owner — so a rule about who owns a row
|
|
95
|
+
has nothing to act on.
|
|
96
|
+
|
|
97
|
+
Rather than fold those rows and return a plausible answer, such a read is
|
|
98
|
+
declined whole with `user_scope_not_enforced`: a member reading a colleague's
|
|
99
|
+
private records would otherwise be indistinguishable from a member reading their
|
|
100
|
+
own. Reads made by a credential acting for the organization are unaffected, as is
|
|
101
|
+
every plane served from its tables.
|
|
102
|
+
|
|
103
|
+
## Related
|
|
104
|
+
|
|
105
|
+
- [Data Sources](./data-sources.md) — the writer role's privileges, and what it
|
|
106
|
+
can and cannot do to your database.
|
|
107
|
+
- [Operating on Your Database](./operating-on-your-database.md) — which actions
|
|
108
|
+
are read-only, which are reversible, and which belong to a human.
|
package/docs/sessions.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Sessions
|
|
2
2
|
|
|
3
|
+
> Short-lived scoped credentials your backend mints for a browser or an agent.
|
|
4
|
+
|
|
3
5
|
A **session** is a short-lived credential your backend mints with its `sk_` and
|
|
4
6
|
hands to one actor — a signed-in **person's browser** or a scoped **agent**. It's
|
|
5
7
|
the same primitive in both cases (backend-minted, short-lived, scoped); the only
|
|
@@ -16,7 +18,7 @@ const userSession = await ablo.sessions.create({
|
|
|
16
18
|
// A scoped agent session — gated to exactly the operations you name.
|
|
17
19
|
const agentSession = await ablo.sessions.create({
|
|
18
20
|
agent: { id: 'agent:task-writer' },
|
|
19
|
-
can: { Task: ['read', 'update'],
|
|
21
|
+
can: { Task: ['read', 'update'], Workspace: ['read'] },
|
|
20
22
|
});
|
|
21
23
|
```
|
|
22
24
|
|
|
@@ -173,7 +175,7 @@ Your schema lives in a **project** — you push it once (`npx ablo push`) and ev
|
|
|
173
175
|
session you mint resolves against it. The flow for serving end-users:
|
|
174
176
|
|
|
175
177
|
1. **Push your schema** to your project.
|
|
176
|
-
2. **Mint an `ek_` per user
|
|
178
|
+
2. **Mint an `ek_` per user:** `sessions.create({ user: { id } })`. Your users
|
|
177
179
|
commit to that one schema.
|
|
178
180
|
|
|
179
181
|
**Your users do not have Ablo accounts.** You authenticate them however you
|