@abloatai/ablo 0.26.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/CHANGELOG.md +14 -0
- package/README.md +101 -85
- package/dist/BaseSyncedStore.d.ts +85 -88
- package/dist/BaseSyncedStore.js +131 -147
- package/dist/Database.d.ts +54 -68
- package/dist/Database.js +97 -113
- package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
- package/dist/{ObjectPool.js → InstanceCache.js} +85 -83
- package/dist/LazyReferenceCollection.d.ts +11 -15
- package/dist/LazyReferenceCollection.js +12 -16
- package/dist/Model.d.ts +37 -52
- package/dist/Model.js +46 -61
- package/dist/ModelRegistry.d.ts +21 -19
- package/dist/ModelRegistry.js +23 -27
- package/dist/NetworkMonitor.d.ts +5 -6
- package/dist/NetworkMonitor.js +5 -6
- package/dist/SyncClient.d.ts +112 -112
- package/dist/SyncClient.js +165 -172
- 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 +27 -32
- package/dist/agent/Agent.js +18 -19
- 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} +26 -33
- package/dist/ai-sdk/index.d.ts +25 -22
- package/dist/ai-sdk/index.js +25 -22
- package/dist/ai-sdk/wrap.d.ts +6 -7
- package/dist/ai-sdk/wrap.js +1 -1
- package/dist/auth/credentialPolicy.d.ts +69 -74
- package/dist/auth/credentialPolicy.js +51 -56
- package/dist/auth/credentialSource.d.ts +6 -5
- package/dist/auth/credentialSource.js +9 -10
- package/dist/auth/index.d.ts +59 -58
- package/dist/auth/index.js +31 -37
- 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 +167 -119
- package/dist/client/Ablo.d.ts +73 -73
- package/dist/client/Ablo.js +125 -160
- package/dist/client/ApiClient.d.ts +30 -19
- package/dist/client/ApiClient.js +133 -38
- package/dist/client/auth.d.ts +47 -47
- package/dist/client/auth.js +108 -117
- package/dist/client/claimHeartbeatLoop.d.ts +50 -0
- package/dist/client/claimHeartbeatLoop.js +88 -0
- package/dist/client/consoleLogger.d.ts +5 -6
- package/dist/client/consoleLogger.js +5 -6
- package/dist/client/createInternalComponents.d.ts +14 -17
- package/dist/client/createInternalComponents.js +25 -30
- package/dist/client/createModelProxy.d.ts +130 -120
- package/dist/client/createModelProxy.js +152 -122
- package/dist/client/credentialEndpoint.d.ts +40 -42
- package/dist/client/credentialEndpoint.js +35 -36
- package/dist/client/functionalUpdate.d.ts +29 -27
- package/dist/client/functionalUpdate.js +21 -21
- package/dist/client/hostedEndpoints.d.ts +9 -12
- package/dist/client/hostedEndpoints.js +9 -12
- package/dist/client/httpClient.d.ts +57 -53
- package/dist/client/httpClient.js +29 -31
- package/dist/client/identity.d.ts +15 -20
- package/dist/client/identity.js +47 -58
- package/dist/client/modelRegistration.d.ts +5 -9
- package/dist/client/modelRegistration.js +67 -87
- package/dist/client/options.d.ts +134 -157
- package/dist/client/options.js +3 -7
- package/dist/client/registerDataSource.d.ts +9 -9
- package/dist/client/registerDataSource.js +15 -16
- package/dist/client/resourceTypes.d.ts +64 -75
- package/dist/client/resourceTypes.js +4 -10
- package/dist/client/schemaConfig.d.ts +31 -43
- package/dist/client/schemaConfig.js +38 -50
- package/dist/client/sessionMint.d.ts +16 -12
- package/dist/client/sessionMint.js +26 -31
- package/dist/client/validateAbloOptions.d.ts +12 -14
- package/dist/client/validateAbloOptions.js +8 -9
- package/dist/client/writeOptionsSchema.d.ts +18 -16
- package/dist/client/writeOptionsSchema.js +23 -20
- package/dist/client/wsMutationExecutor.d.ts +15 -20
- package/dist/client/wsMutationExecutor.js +17 -23
- package/dist/context.d.ts +6 -4
- package/dist/context.js +6 -4
- package/dist/coordination/index.d.ts +10 -8
- package/dist/coordination/index.js +14 -12
- package/dist/coordination/schema.d.ts +176 -128
- package/dist/coordination/schema.js +197 -133
- package/dist/coordination/trace.d.ts +9 -10
- package/dist/coordination/trace.js +13 -14
- package/dist/core/DatabaseManager.d.ts +5 -7
- package/dist/core/DatabaseManager.js +15 -19
- package/dist/core/QueryProcessor.d.ts +7 -9
- package/dist/core/QueryProcessor.js +22 -28
- package/dist/core/QueryView.d.ts +8 -8
- package/dist/core/QueryView.js +2 -2
- package/dist/core/StoreManager.d.ts +12 -14
- package/dist/core/StoreManager.js +21 -24
- package/dist/core/ViewRegistry.d.ts +5 -5
- package/dist/core/ViewRegistry.js +4 -4
- package/dist/core/index.d.ts +17 -12
- package/dist/core/index.js +32 -26
- package/dist/core/openIDBWithTimeout.d.ts +38 -36
- package/dist/core/openIDBWithTimeout.js +42 -43
- package/dist/core/queryUtils.d.ts +45 -0
- package/dist/core/queryUtils.js +69 -0
- package/dist/core/storeContract.d.ts +63 -61
- package/dist/core/storeContract.js +8 -12
- package/dist/environment.d.ts +28 -0
- package/dist/environment.js +21 -0
- package/dist/errorCodes.d.ts +107 -99
- package/dist/errorCodes.js +131 -132
- package/dist/errors.d.ts +160 -166
- package/dist/errors.js +155 -158
- package/dist/index.d.ts +30 -27
- package/dist/index.js +89 -86
- package/dist/interfaces/index.d.ts +102 -113
- package/dist/interfaces/index.js +5 -4
- package/dist/keys/index.d.ts +27 -29
- package/dist/keys/index.js +41 -40
- 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 +145 -156
- package/dist/mutators/defineMutators.d.ts +23 -34
- 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 +104 -100
- package/dist/policy/types.js +67 -66
- package/dist/query/client.d.ts +28 -23
- package/dist/query/client.js +45 -43
- package/dist/query/types.d.ts +37 -60
- package/dist/query/types.js +13 -33
- package/dist/react/AbloProvider.d.ts +1 -1
- package/dist/react/AbloProvider.js +2 -2
- package/dist/react/context.d.ts +25 -28
- 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 +16 -14
- 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 +10 -11
- package/dist/react/useMutationFailureListener.d.ts +8 -8
- package/dist/react/useMutationFailureListener.js +8 -8
- package/dist/react/useMutators.d.ts +11 -11
- package/dist/react/useMutators.js +3 -3
- package/dist/react/useReactive.js +2 -2
- package/dist/react/useSyncStatus.d.ts +4 -6
- package/dist/react/useUndoScope.d.ts +7 -9
- package/dist/react/useUndoScope.js +1 -1
- 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 +20 -24
- package/dist/schema/ddlLock.js +18 -23
- 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 +35 -48
- package/dist/schema/generate.d.ts +12 -12
- package/dist/schema/generate.js +12 -12
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.js +21 -23
- package/dist/schema/model.d.ts +118 -143
- package/dist/schema/model.js +22 -33
- package/dist/schema/openapi.d.ts +10 -9
- package/dist/schema/openapi.js +5 -3
- package/dist/schema/queries.d.ts +29 -31
- package/dist/schema/queries.js +23 -25
- package/dist/schema/relation.d.ts +89 -99
- package/dist/schema/relation.js +13 -13
- package/dist/schema/residency.d.ts +16 -13
- package/dist/schema/residency.js +16 -13
- package/dist/schema/roles.d.ts +36 -43
- package/dist/schema/roles.js +31 -37
- package/dist/schema/schema.d.ts +33 -42
- package/dist/schema/schema.js +31 -32
- package/dist/schema/select.d.ts +13 -13
- package/dist/schema/select.js +13 -13
- package/dist/schema/serialize.d.ts +28 -31
- 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} +26 -49
- 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 +30 -25
- package/dist/source/adapter.js +10 -10
- package/dist/source/adapters/drizzle.d.ts +28 -23
- package/dist/source/adapters/drizzle.js +30 -25
- package/dist/source/adapters/kysely.d.ts +27 -25
- package/dist/source/adapters/kysely.js +24 -23
- package/dist/source/adapters/memory.d.ts +8 -7
- package/dist/source/adapters/memory.js +9 -8
- package/dist/source/adapters/prisma.d.ts +13 -12
- package/dist/source/adapters/prisma.js +22 -25
- package/dist/source/conformance.d.ts +18 -11
- package/dist/source/conformance.js +17 -11
- package/dist/source/connector.d.ts +31 -32
- package/dist/source/connector.js +28 -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 +46 -58
- package/dist/source/factory.js +22 -27
- package/dist/source/index.d.ts +7 -9
- package/dist/source/index.js +12 -14
- package/dist/source/migrations.d.ts +9 -9
- package/dist/source/migrations.js +9 -9
- package/dist/source/next.d.ts +9 -10
- package/dist/source/next.js +6 -7
- package/dist/source/pushQueue.d.ts +69 -47
- package/dist/source/pushQueue.js +32 -28
- package/dist/source/signing.d.ts +46 -17
- package/dist/source/signing.js +28 -11
- package/dist/source/types.d.ts +121 -104
- package/dist/source/types.js +13 -14
- package/dist/stores/ObjectStore.d.ts +10 -11
- package/dist/stores/ObjectStore.js +11 -12
- package/dist/stores/ObjectStoreContract.d.ts +12 -15
- package/dist/stores/SyncActionStore.d.ts +7 -11
- package/dist/stores/SyncActionStore.js +13 -17
- package/dist/surface.d.ts +27 -20
- package/dist/surface.js +27 -20
- package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +36 -42
- package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +76 -76
- package/dist/sync/ConnectionManager.d.ts +39 -50
- package/dist/sync/ConnectionManager.js +55 -66
- package/dist/sync/NetworkProbe.d.ts +24 -29
- package/dist/sync/NetworkProbe.js +63 -69
- package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +42 -41
- package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +59 -54
- package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +43 -57
- package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +43 -51
- package/dist/sync/SyncWebSocket.d.ts +139 -165
- package/dist/sync/SyncWebSocket.js +191 -223
- package/dist/sync/awaitClaimGrant.d.ts +18 -18
- package/dist/sync/awaitClaimGrant.js +11 -11
- package/dist/sync/bootstrapApply.d.ts +34 -24
- package/dist/sync/bootstrapApply.js +27 -19
- package/dist/sync/commitFrames.d.ts +21 -20
- package/dist/sync/commitFrames.js +18 -18
- package/dist/sync/createClaimStream.d.ts +23 -22
- package/dist/sync/createClaimStream.js +105 -23
- package/dist/sync/createPresenceStream.d.ts +19 -18
- package/dist/sync/createPresenceStream.js +25 -26
- package/dist/sync/createSnapshot.d.ts +12 -14
- package/dist/sync/createSnapshot.js +20 -26
- package/dist/sync/credentialLifecycle.d.ts +104 -104
- package/dist/sync/credentialLifecycle.js +140 -147
- package/dist/sync/deltaPipeline.d.ts +36 -34
- package/dist/sync/deltaPipeline.js +64 -65
- package/dist/sync/groupChange.d.ts +63 -61
- package/dist/sync/groupChange.js +74 -78
- package/dist/sync/heartbeat.d.ts +34 -33
- package/dist/sync/heartbeat.js +31 -31
- package/dist/sync/participants.d.ts +19 -19
- package/dist/sync/schemas.d.ts +3 -2
- package/dist/sync/schemas.js +14 -10
- package/dist/sync/syncCursor.d.ts +17 -21
- package/dist/sync/syncCursor.js +17 -21
- package/dist/sync/syncPlan.d.ts +28 -36
- package/dist/sync/syncPlan.js +18 -19
- package/dist/sync/syncPosition.d.ts +54 -49
- package/dist/sync/syncPosition.js +57 -52
- package/dist/sync/wsFrameHandlers.d.ts +35 -36
- package/dist/sync/wsFrameHandlers.js +63 -67
- package/dist/testing/fixtures/bootstrap.d.ts +12 -6
- package/dist/testing/fixtures/bootstrap.js +12 -6
- package/dist/testing/fixtures/deltas.d.ts +30 -33
- package/dist/testing/fixtures/deltas.js +30 -33
- package/dist/testing/fixtures/models.d.ts +11 -10
- package/dist/testing/fixtures/models.js +11 -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 -15
- package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +12 -10
- package/dist/testing/helpers/wait.d.ts +13 -8
- package/dist/testing/helpers/wait.js +13 -8
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +2 -2
- 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 +20 -17
- package/dist/testing/mocks/MockSyncContext.js +15 -13
- package/dist/testing/mocks/MockSyncStore.d.ts +10 -10
- package/dist/testing/mocks/MockSyncStore.js +11 -11
- package/dist/testing/mocks/MockWebSocket.d.ts +26 -22
- package/dist/testing/mocks/MockWebSocket.js +22 -21
- package/dist/transactions/TransactionQueue.d.ts +181 -176
- package/dist/transactions/TransactionQueue.js +338 -350
- package/dist/transactions/TransactionStore.d.ts +6 -4
- package/dist/transactions/TransactionStore.js +6 -4
- package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
- package/dist/transactions/UnconfirmedWrites.js +104 -0
- package/dist/transactions/coalesceRules.d.ts +41 -17
- package/dist/transactions/coalesceRules.js +40 -17
- package/dist/transactions/commitPayload.d.ts +48 -52
- package/dist/transactions/commitPayload.js +48 -57
- package/dist/transactions/deltaConfirmation.d.ts +20 -22
- package/dist/transactions/deltaConfirmation.js +37 -45
- package/dist/transactions/optimisticApply.d.ts +49 -0
- package/dist/transactions/optimisticApply.js +65 -0
- package/dist/transactions/{persistedReplay.d.ts → replayValidation.d.ts} +28 -22
- package/dist/transactions/{persistedReplay.js → replayValidation.js} +33 -27
- package/dist/types/global.d.ts +46 -41
- package/dist/types/global.js +20 -19
- package/dist/types/index.d.ts +71 -77
- package/dist/types/index.js +22 -22
- package/dist/types/modelData.d.ts +6 -8
- package/dist/types/modelData.js +5 -7
- package/dist/types/participant.d.ts +10 -11
- package/dist/types/participant.js +6 -8
- package/dist/types/streams.d.ts +208 -195
- 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} +42 -98
- 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 +30 -31
- package/dist/wire/errorEnvelope.js +34 -40
- package/dist/wire/frames.d.ts +79 -86
- package/dist/wire/frames.js +26 -33
- package/dist/wire/index.d.ts +14 -12
- package/dist/wire/index.js +30 -26
- package/dist/wire/listEnvelope.d.ts +16 -23
- package/dist/wire/listEnvelope.js +7 -6
- package/dist/wire/protocol.d.ts +25 -32
- package/dist/wire/protocol.js +25 -32
- package/dist/wire/protocolVersion.d.ts +44 -40
- package/dist/wire/protocolVersion.js +44 -40
- package/docs/coordination.md +59 -0
- package/package.json +11 -10
- package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
- package/dist/ai-sdk/coordination-context.d.ts +0 -52
- package/dist/core/query-utils.d.ts +0 -34
- package/dist/core/query-utils.js +0 -59
- package/dist/schema/sync-delta-row.js +0 -103
- package/dist/schema/sync-delta-wire.js +0 -102
- 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 -8
- package/dist/server/storage-mode.js +0 -28
- package/dist/source/connector-protocol.d.ts +0 -159
- package/dist/source/connector-protocol.js +0 -161
- package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
- package/dist/transactions/OptimisticEchoTracker.js +0 -104
- package/dist/transactions/mutation-error-handler.d.ts +0 -5
- package/dist/transactions/mutation-error-handler.js +0 -39
- package/dist/transactions/optimistic.d.ts +0 -24
- package/dist/transactions/optimistic.js +0 -45
- package/dist/utils/mobx-setup.d.ts +0 -42
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The shared resource
|
|
3
|
-
* the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Extracted from `Ablo.ts` so `ApiClient.ts` / `httpClient.ts` /
|
|
7
|
-
* `sessionMint.ts` can take the wire-facing types WITHOUT importing the
|
|
8
|
-
* factory module that runtime-imports them back (the 4-cycle cluster madge
|
|
9
|
-
* flagged). This module is type-only — ZERO runtime imports — so importing it
|
|
10
|
-
* can never create a cycle. `Ablo.ts` re-exports everything here, so existing
|
|
11
|
-
* import paths keep resolving.
|
|
2
|
+
* The shared resource types of the client: {@link ModelRead}, {@link ModelClient},
|
|
3
|
+
* the commit and claim shapes, the session-mint params and resource, and the
|
|
4
|
+
* {@link HttpClaimApi} derivation. This module holds only types and has no runtime
|
|
5
|
+
* imports.
|
|
12
6
|
*/
|
|
13
7
|
import type { StaleNotification, ReadDependency } from '../coordination/schema.js';
|
|
14
8
|
import type { ModelTarget, ModelClaim } from '../coordination/schema.js';
|
|
@@ -19,16 +13,14 @@ import type { Claim, ClaimStream, ClaimWaitOptions, Duration, HeldClaim } from '
|
|
|
19
13
|
import type { ModelUpdater, ContentionOptions } from './functionalUpdate.js';
|
|
20
14
|
import type { ClaimOptions, ClaimParams, ClaimReadApi, AwaitedClaimMethod, ServerReadOptions } from './createModelProxy.js';
|
|
21
15
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* `
|
|
26
|
-
* `list({ where })` — async collection server read
|
|
27
|
-
* `get(id)` / `getAll(...)` / `getCount(...)` — local graph snapshots
|
|
16
|
+
* The operations available on each model in the sync engine:
|
|
17
|
+
* `retrieve({ id })` — an async single-row server read
|
|
18
|
+
* `list({ where })` — an async collection server read
|
|
19
|
+
* `get(id)` / `getAll(...)` / `getCount(...)` — synchronous local-cache reads
|
|
28
20
|
* `create({ data })` / `update({ id, data })` / `delete({ id })` — writes
|
|
29
|
-
* `claim({ id })` — durable claim handle for coordinated writes
|
|
21
|
+
* `claim({ id })` — a durable claim handle for coordinated writes
|
|
30
22
|
*/
|
|
31
|
-
export type { LocalCountOptions, LocalReadOptions, ModelListScope, ServerReadOptions, ModelRetrieveParams, ModelCreateParams, ModelUpdateParams, ModelDeleteParams, ClaimOptions, ClaimParams, ClaimLookupParams, ClaimReorderParams, Claim, HeldClaim, ModelOperations, } from './createModelProxy.js';
|
|
23
|
+
export type { LocalCountOptions, LocalReadOptions, ModelListScope, ServerReadOptions, ModelRetrieveParams, ModelCreateParams, ModelUpdateParams, ModelDeleteParams, ClaimOptions, ClaimParams, ClaimLookupParams, ClaimReorderParams, Claim, ClaimHeartbeat, ClaimHeartbeatOptions, HeldClaim, ModelOperations, } from './createModelProxy.js';
|
|
32
24
|
export type ModelOperationAction = 'create' | 'update' | 'delete' | 'archive' | 'unarchive';
|
|
33
25
|
export type CommitWait = 'queued' | 'confirmed';
|
|
34
26
|
export interface ModelRead<T = Record<string, unknown>> {
|
|
@@ -109,12 +101,12 @@ export interface CommitCreateOptions {
|
|
|
109
101
|
readonly operations?: readonly CommitOperationInput[];
|
|
110
102
|
readonly wait?: CommitWait;
|
|
111
103
|
/**
|
|
112
|
-
* Batch-level read dependencies
|
|
113
|
-
*
|
|
114
|
-
* (`{group,readAt}`,
|
|
115
|
-
*
|
|
116
|
-
* batch.
|
|
117
|
-
* not what you write.
|
|
104
|
+
* Batch-level read dependencies — the "did anything I looked at change?" guard.
|
|
105
|
+
* Declare the rows (`{ model, id, readAt, fields? }`) or sync groups
|
|
106
|
+
* (`{ group, readAt }`, for example `deck:abc`) this batch was premised on; the
|
|
107
|
+
* server checks that none moved since `readAt` and fires the entry's `onStale`
|
|
108
|
+
* over the batch. This is distinct from the write-target `readAt`: it guards what
|
|
109
|
+
* you read, not what you write.
|
|
118
110
|
*/
|
|
119
111
|
readonly reads?: readonly ReadDependency[] | null;
|
|
120
112
|
}
|
|
@@ -123,19 +115,18 @@ export interface CommitReceipt {
|
|
|
123
115
|
readonly status: CommitWait;
|
|
124
116
|
readonly lastSyncId?: number;
|
|
125
117
|
/**
|
|
126
|
-
* Stale-context notifications
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* resolve. Also fires on `conflict:notified`.
|
|
118
|
+
* Stale-context notifications: present only when this commit guarded a write with
|
|
119
|
+
* `onStale: 'notify'` and the premise moved concurrently. Each carries the
|
|
120
|
+
* conflicting field's current value, handed back as data rather than raising an
|
|
121
|
+
* `AbloStaleContextError`, so the caller — an agent or a human — decides how to
|
|
122
|
+
* resolve it.
|
|
132
123
|
*/
|
|
133
124
|
readonly notifications?: readonly StaleNotification[];
|
|
134
125
|
/**
|
|
135
|
-
* Ids of
|
|
136
|
-
*
|
|
137
|
-
* when a write missed.
|
|
138
|
-
* `AbloNotFoundError`; a raw `commits.create` caller can inspect it directly.
|
|
126
|
+
* Ids of update or delete targets in this commit that matched no rows, because
|
|
127
|
+
* the row does not exist or is outside the caller's organization. Present and
|
|
128
|
+
* non-empty only when a write missed. The typed resource wrappers turn this into
|
|
129
|
+
* an `AbloNotFoundError`; a raw `commits.create` caller can inspect it directly.
|
|
139
130
|
*/
|
|
140
131
|
readonly missingIds?: readonly string[];
|
|
141
132
|
}
|
|
@@ -158,20 +149,20 @@ export interface ModelMutationOptions extends ClaimedOptions {
|
|
|
158
149
|
readonly claim?: Claim | ClaimOptions | null;
|
|
159
150
|
}
|
|
160
151
|
/**
|
|
161
|
-
* The
|
|
162
|
-
*
|
|
163
|
-
*
|
|
152
|
+
* The stateless HTTP claim surface. Most code puts a `claim` directly on the write
|
|
153
|
+
* (`update({ id, data, claim })`) and lets the SDK release it; reach for this
|
|
154
|
+
* namespace for multi-step handles and coordination screens.
|
|
164
155
|
*
|
|
165
|
-
*
|
|
166
|
-
* round-trip,
|
|
167
|
-
* client resolves
|
|
168
|
-
*
|
|
169
|
-
*
|
|
156
|
+
* It is the same surface as the reactive claim API, but because every read is a
|
|
157
|
+
* server round-trip, `state`, `queue`, and `reorder` are awaited here. The
|
|
158
|
+
* WebSocket client resolves those synchronously from its local cache, which is what
|
|
159
|
+
* lets it read a claim's state inside a React render; a stateless client has no
|
|
160
|
+
* cache to read, so the promise is unavoidable.
|
|
170
161
|
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
162
|
+
* It is derived from `ClaimReadApi` through {@link AwaitedClaimMethod} so the two
|
|
163
|
+
* transports cannot drift: the only difference is the promise wrapper that
|
|
164
|
+
* statelessness forces. `claim({ id })` is identical on both (already async);
|
|
165
|
+
* `state`, `queue`, `reorder`, and `release` are the awaited form.
|
|
175
166
|
*/
|
|
176
167
|
export type HttpClaimApi<T = Record<string, unknown>> = ((params: ClaimParams<T>) => Promise<HeldClaim<T>>) & {
|
|
177
168
|
[K in keyof ClaimReadApi<T>]: AwaitedClaimMethod<ClaimReadApi<T>[K]>;
|
|
@@ -183,7 +174,7 @@ export interface ModelClient<T = Record<string, unknown>> {
|
|
|
183
174
|
* guards on the following write) and any active `.claims`. A stateless HTTP
|
|
184
175
|
* client can't synthesize the watermark from a local snapshot, so the
|
|
185
176
|
* envelope is load-bearing here (the WebSocket client's `retrieve` returns
|
|
186
|
-
* `T | undefined` because it reads from
|
|
177
|
+
* `T | undefined` because it reads from its local cache).
|
|
187
178
|
*
|
|
188
179
|
* ```ts
|
|
189
180
|
* const deal = await ablo.deals.retrieve({ id });
|
|
@@ -201,10 +192,10 @@ export interface ModelClient<T = Record<string, unknown>> {
|
|
|
201
192
|
*/
|
|
202
193
|
list?(options?: ServerReadOptions<T>): Promise<T[]>;
|
|
203
194
|
/**
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
195
|
+
* Creates a row and returns the confirmed server row, including framework
|
|
196
|
+
* defaults such as `createdAt` and `createdBy`. Matches the stateful client's
|
|
197
|
+
* `create`. Passing an id that already exists is idempotent: the existing row is
|
|
198
|
+
* returned, not the input.
|
|
208
199
|
*/
|
|
209
200
|
create(params: ModelMutationOptions & {
|
|
210
201
|
readonly data: Record<string, unknown>;
|
|
@@ -238,27 +229,26 @@ export interface ModelClient<T = Record<string, unknown>> {
|
|
|
238
229
|
}
|
|
239
230
|
/** A single data operation a scoped **agent** session may perform on a model. */
|
|
240
231
|
export type SessionOperation = 'read' | 'create' | 'update' | 'delete';
|
|
241
|
-
/**
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* honest string at the trust boundary. */
|
|
232
|
+
/** Parameters for minting an end-user session — full data authority within the
|
|
233
|
+
* organization. Mints an `ek_` token. `user.id` is your end user's id from your
|
|
234
|
+
* own identity provider and becomes the session's `participantId`; Ablo does not
|
|
235
|
+
* model your users, so it is treated as an opaque string at the trust boundary. */
|
|
246
236
|
export interface CreateUserSessionParams {
|
|
247
237
|
/** Your end user. `id` becomes the token's `participantId`. */
|
|
248
238
|
user: {
|
|
249
239
|
id: string;
|
|
250
240
|
};
|
|
251
|
-
/** Mint the session into
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
241
|
+
/** Mint the session into this organization instead of the key's own — for a
|
|
242
|
+
* platform that serves many tenants from one backend. Requires the `sk_` key to
|
|
243
|
+
* carry the `ephemeral:mint-any-org` scope; omit it for the normal
|
|
244
|
+
* single-tenant case. */
|
|
255
245
|
organizationId?: string;
|
|
256
246
|
/** Sync groups this session may subscribe to — typed (`'default'` or
|
|
257
247
|
* `<namespace>:<id>`; build with `syncGroup(kind, id)` from
|
|
258
248
|
* `@abloatai/ablo/schema`). Omit for the server default:
|
|
259
249
|
* `[org:<your org>, user:<user.id>]`. */
|
|
260
250
|
syncGroups?: readonly SyncGroupInput[];
|
|
261
|
-
/** Token lifetime in seconds. Defaults to 900 (
|
|
251
|
+
/** Token lifetime in seconds. Defaults to 900 (15 minutes). */
|
|
262
252
|
ttlSeconds?: number;
|
|
263
253
|
/** Opaque identity blob echoed back to the client as `ablo.user`. */
|
|
264
254
|
userMeta?: Record<string, unknown>;
|
|
@@ -281,7 +271,7 @@ export interface CreateAgentSessionParams<S extends SchemaRecord> {
|
|
|
281
271
|
* `@abloatai/ablo/schema`). Omit for the server default: the org
|
|
282
272
|
* anchor (`org:<your org>`) + the agent's own anchor. */
|
|
283
273
|
syncGroups?: readonly SyncGroupInput[];
|
|
284
|
-
/** Token lifetime in seconds. Defaults to 900 (
|
|
274
|
+
/** Token lifetime in seconds. Defaults to 900 (15 minutes). */
|
|
285
275
|
ttlSeconds?: number;
|
|
286
276
|
/** Opaque identity blob echoed back to the client as `ablo.agent`. */
|
|
287
277
|
userMeta?: Record<string, unknown>;
|
|
@@ -296,15 +286,15 @@ export type CreateSessionParams<S extends SchemaRecord> = CreateUserSessionParam
|
|
|
296
286
|
* {@link CreateSessionParams} it resolves to a connected, scoped {@link Ablo}
|
|
297
287
|
* client rather than a raw token. */
|
|
298
288
|
export interface CreateAgentClientParams<S extends SchemaRecord> {
|
|
299
|
-
/**
|
|
300
|
-
* FIFO queue gate on.
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
289
|
+
/** The wire participant identity (`agent:<id>`) that claim exclusion and the
|
|
290
|
+
* FIFO queue gate on. Omit it to get a fresh random id — a distinct, independent
|
|
291
|
+
* participant, which is the default and what you want for concurrent agents.
|
|
292
|
+
* Pass a stable string only when one logical agent must re-attach to its own
|
|
293
|
+
* held claims across reconnects or restarts. */
|
|
304
294
|
id?: string;
|
|
305
|
-
/**
|
|
306
|
-
*
|
|
307
|
-
* ids and coordinate as
|
|
295
|
+
/** A human-readable label for logs and attribution (carried in `userMeta.name`).
|
|
296
|
+
* It is independent of `id`: two agents that share a `name` still receive
|
|
297
|
+
* distinct ids and coordinate as separate participants — `name` never derives or
|
|
308
298
|
* collapses identity. */
|
|
309
299
|
name?: string;
|
|
310
300
|
/** Per-model operation allowlist, typed against the schema's model names. */
|
|
@@ -313,16 +303,15 @@ export interface CreateAgentClientParams<S extends SchemaRecord> {
|
|
|
313
303
|
* `<namespace>:<id>`). Omit for the server default (org anchor + the
|
|
314
304
|
* agent's own anchor). */
|
|
315
305
|
syncGroups?: readonly SyncGroupInput[];
|
|
316
|
-
/** Token lifetime in seconds. Defaults to 900 (
|
|
317
|
-
*
|
|
318
|
-
*
|
|
306
|
+
/** Token lifetime in seconds. Defaults to 900 (15 minutes); the returned client
|
|
307
|
+
* re-mints before expiry, so a long-running agent never handles rotation
|
|
308
|
+
* itself. */
|
|
319
309
|
ttlSeconds?: number;
|
|
320
310
|
/** Extra opaque identity blob echoed on the session scope. Merged with
|
|
321
311
|
* `name` (the `name` param wins if you also set `userMeta.name`). */
|
|
322
312
|
userMeta?: Record<string, unknown>;
|
|
323
313
|
}
|
|
324
|
-
/** A minted session token
|
|
325
|
-
* resource. `token` is the secret the holder presents as its bearer. */
|
|
314
|
+
/** A minted session. `token` is the secret the holder presents as its bearer. */
|
|
326
315
|
export interface AbloSession {
|
|
327
316
|
object: 'session';
|
|
328
317
|
/** Stable id of the minted credential (for revocation). */
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The shared resource
|
|
3
|
-
* the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Extracted from `Ablo.ts` so `ApiClient.ts` / `httpClient.ts` /
|
|
7
|
-
* `sessionMint.ts` can take the wire-facing types WITHOUT importing the
|
|
8
|
-
* factory module that runtime-imports them back (the 4-cycle cluster madge
|
|
9
|
-
* flagged). This module is type-only — ZERO runtime imports — so importing it
|
|
10
|
-
* can never create a cycle. `Ablo.ts` re-exports everything here, so existing
|
|
11
|
-
* import paths keep resolving.
|
|
2
|
+
* The shared resource types of the client: {@link ModelRead}, {@link ModelClient},
|
|
3
|
+
* the commit and claim shapes, the session-mint params and resource, and the
|
|
4
|
+
* {@link HttpClaimApi} derivation. This module holds only types and has no runtime
|
|
5
|
+
* imports.
|
|
12
6
|
*/
|
|
13
7
|
export {};
|
|
@@ -1,56 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
2
|
+
* Derives engine configuration from a schema. This module holds two pure
|
|
3
|
+
* functions: {@link computeFKDepthPriority} works out a safe row-insertion
|
|
4
|
+
* order from the schema's foreign-key relations, and
|
|
5
|
+
* {@link deriveConfigFromSchema} packages that ordering, together with a few
|
|
6
|
+
* defaults, into the {@link SyncEngineConfig} a client uses at startup. Both
|
|
7
|
+
* are deterministic transforms of the schema and hold no engine state.
|
|
8
8
|
*/
|
|
9
9
|
import type { Schema } from '../schema/schema.js';
|
|
10
10
|
import type { SyncEngineConfig } from '../interfaces/index.js';
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* The FK graph has an edge `child → parent` for every `belongsTo`. Tarjan
|
|
16
|
-
* runs a single linear DFS that simultaneously (a) detects cycles by
|
|
17
|
-
* grouping mutually-reachable nodes into SCCs and (b) emits those SCCs
|
|
18
|
-
* in reverse topological order of the condensation graph. In this edge
|
|
19
|
-
* convention a "sink" SCC has no outgoing edges — i.e. no parents — so
|
|
20
|
-
* it is an *FK root* (`organizations`, `themes`, etc.). Tarjan emits
|
|
21
|
-
* roots first and leaves last, exactly the order in which rows must be
|
|
22
|
-
* inserted to satisfy FK constraints.
|
|
23
|
-
*
|
|
24
|
-
* Priorities are assigned by emit order: SCC #0 → 10, SCC #1 → 20, …
|
|
25
|
-
* Members of the same SCC share a priority, so insertion order wins the
|
|
26
|
-
* tiebreak inside a cycle (this matters for cyclic schemas like
|
|
27
|
-
* `slideDecks ↔ layouts`, where one direction is the user's chosen
|
|
28
|
-
* "soft" edge — only the consumer's mutator sequence knows which one).
|
|
12
|
+
* Computes a create-priority map that gives the engine a safe order for
|
|
13
|
+
* inserting rows, so a child row is never written before the parent its
|
|
14
|
+
* foreign key references.
|
|
29
15
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
16
|
+
* Every `belongsTo` relation is an edge from a child model to its parent. This
|
|
17
|
+
* function runs Tarjan's strongly-connected-components algorithm over that
|
|
18
|
+
* graph, which does two things at once: it groups any models that reference
|
|
19
|
+
* each other in a cycle into a single component, and it produces those
|
|
20
|
+
* components in an order where parents come before children. Each model then
|
|
21
|
+
* gets a numeric priority from that order, where a lower number means "insert
|
|
22
|
+
* earlier". Top-level models with no parent — an organization or a theme, say —
|
|
23
|
+
* come first, and the deepest descendants come last.
|
|
36
24
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* the
|
|
41
|
-
* strictly higher priority than its parent
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* {@link BelongsToOptions.defer}.
|
|
25
|
+
* Models in the same cycle share a priority, so within a cycle the order rows
|
|
26
|
+
* were queued in breaks the tie. To break a cycle deterministically instead,
|
|
27
|
+
* mark one side of it with `belongsTo(target, fk, { defer: true })`. A deferred
|
|
28
|
+
* edge is left out of the graph, which turns the cycle into a chain and gives
|
|
29
|
+
* the deferred child a strictly higher priority than its parent. Pair it with a
|
|
30
|
+
* Postgres `DEFERRABLE INITIALLY DEFERRED` constraint if you also want the
|
|
31
|
+
* database to relax its check. See {@link BelongsToOptions.defer}.
|
|
45
32
|
*
|
|
46
|
-
* The returned map is keyed by
|
|
47
|
-
* to the schema key), because that is
|
|
48
|
-
*
|
|
49
|
-
* miss
|
|
50
|
-
* `defaultCreatePriority`.
|
|
33
|
+
* The returned map is keyed by each model's wire type name
|
|
34
|
+
* ({@link ModelDef.typename}, falling back to the schema key), because that is
|
|
35
|
+
* the name the engine looks up at commit time. Keying by the schema key would
|
|
36
|
+
* miss that lookup, and every model would fall back to the default priority.
|
|
51
37
|
*
|
|
38
|
+
* The result does not depend on which model the walk starts from, and the
|
|
39
|
+
* algorithm runs in time linear in the number of models plus relations.
|
|
52
40
|
* Reference: Tarjan, R. (1972), "Depth-first search and linear graph
|
|
53
|
-
* algorithms."
|
|
41
|
+
* algorithms."
|
|
54
42
|
*/
|
|
55
43
|
export declare function computeFKDepthPriority(schema: Schema): ReadonlyMap<string, number>;
|
|
56
44
|
export declare function deriveConfigFromSchema(schema: Schema): SyncEngineConfig;
|
|
@@ -1,56 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
2
|
+
* Derives engine configuration from a schema. This module holds two pure
|
|
3
|
+
* functions: {@link computeFKDepthPriority} works out a safe row-insertion
|
|
4
|
+
* order from the schema's foreign-key relations, and
|
|
5
|
+
* {@link deriveConfigFromSchema} packages that ordering, together with a few
|
|
6
|
+
* defaults, into the {@link SyncEngineConfig} a client uses at startup. Both
|
|
7
|
+
* are deterministic transforms of the schema and hold no engine state.
|
|
8
8
|
*/
|
|
9
9
|
import { schemaHash } from '../schema/serialize.js';
|
|
10
10
|
// ── Config derivation from schema ─────────────────────────────────────────
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* The FK graph has an edge `child → parent` for every `belongsTo`. Tarjan
|
|
16
|
-
* runs a single linear DFS that simultaneously (a) detects cycles by
|
|
17
|
-
* grouping mutually-reachable nodes into SCCs and (b) emits those SCCs
|
|
18
|
-
* in reverse topological order of the condensation graph. In this edge
|
|
19
|
-
* convention a "sink" SCC has no outgoing edges — i.e. no parents — so
|
|
20
|
-
* it is an *FK root* (`organizations`, `themes`, etc.). Tarjan emits
|
|
21
|
-
* roots first and leaves last, exactly the order in which rows must be
|
|
22
|
-
* inserted to satisfy FK constraints.
|
|
23
|
-
*
|
|
24
|
-
* Priorities are assigned by emit order: SCC #0 → 10, SCC #1 → 20, …
|
|
25
|
-
* Members of the same SCC share a priority, so insertion order wins the
|
|
26
|
-
* tiebreak inside a cycle (this matters for cyclic schemas like
|
|
27
|
-
* `slideDecks ↔ layouts`, where one direction is the user's chosen
|
|
28
|
-
* "soft" edge — only the consumer's mutator sequence knows which one).
|
|
12
|
+
* Computes a create-priority map that gives the engine a safe order for
|
|
13
|
+
* inserting rows, so a child row is never written before the parent its
|
|
14
|
+
* foreign key references.
|
|
29
15
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
16
|
+
* Every `belongsTo` relation is an edge from a child model to its parent. This
|
|
17
|
+
* function runs Tarjan's strongly-connected-components algorithm over that
|
|
18
|
+
* graph, which does two things at once: it groups any models that reference
|
|
19
|
+
* each other in a cycle into a single component, and it produces those
|
|
20
|
+
* components in an order where parents come before children. Each model then
|
|
21
|
+
* gets a numeric priority from that order, where a lower number means "insert
|
|
22
|
+
* earlier". Top-level models with no parent — an organization or a theme, say —
|
|
23
|
+
* come first, and the deepest descendants come last.
|
|
36
24
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* the
|
|
41
|
-
* strictly higher priority than its parent
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* {@link BelongsToOptions.defer}.
|
|
25
|
+
* Models in the same cycle share a priority, so within a cycle the order rows
|
|
26
|
+
* were queued in breaks the tie. To break a cycle deterministically instead,
|
|
27
|
+
* mark one side of it with `belongsTo(target, fk, { defer: true })`. A deferred
|
|
28
|
+
* edge is left out of the graph, which turns the cycle into a chain and gives
|
|
29
|
+
* the deferred child a strictly higher priority than its parent. Pair it with a
|
|
30
|
+
* Postgres `DEFERRABLE INITIALLY DEFERRED` constraint if you also want the
|
|
31
|
+
* database to relax its check. See {@link BelongsToOptions.defer}.
|
|
45
32
|
*
|
|
46
|
-
* The returned map is keyed by
|
|
47
|
-
* to the schema key), because that is
|
|
48
|
-
*
|
|
49
|
-
* miss
|
|
50
|
-
* `defaultCreatePriority`.
|
|
33
|
+
* The returned map is keyed by each model's wire type name
|
|
34
|
+
* ({@link ModelDef.typename}, falling back to the schema key), because that is
|
|
35
|
+
* the name the engine looks up at commit time. Keying by the schema key would
|
|
36
|
+
* miss that lookup, and every model would fall back to the default priority.
|
|
51
37
|
*
|
|
38
|
+
* The result does not depend on which model the walk starts from, and the
|
|
39
|
+
* algorithm runs in time linear in the number of models plus relations.
|
|
52
40
|
* Reference: Tarjan, R. (1972), "Depth-first search and linear graph
|
|
53
|
-
* algorithms."
|
|
41
|
+
* algorithms."
|
|
54
42
|
*/
|
|
55
43
|
export function computeFKDepthPriority(schema) {
|
|
56
44
|
// schemaKey → typename (wire name used at transaction time)
|
|
@@ -170,19 +158,19 @@ export function computeFKDepthPriority(schema) {
|
|
|
170
158
|
return out;
|
|
171
159
|
}
|
|
172
160
|
export function deriveConfigFromSchema(schema) {
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
//
|
|
177
|
-
// the declared fields and serializes accordingly.
|
|
161
|
+
// Field-level serialization for commits happens in the transaction queue,
|
|
162
|
+
// which reads each model's declared fields from the model registry at commit
|
|
163
|
+
// time. There is no per-field metadata to configure here, so these maps stay
|
|
164
|
+
// empty.
|
|
178
165
|
return {
|
|
179
166
|
modelCreatePriority: computeFKDepthPriority(schema),
|
|
180
167
|
defaultCreatePriority: 40,
|
|
181
168
|
defaultNonCreatePriority: 50,
|
|
182
169
|
essentialFields: {},
|
|
183
170
|
classNameFallbackMap: {},
|
|
184
|
-
// Hash this
|
|
185
|
-
// server
|
|
171
|
+
// Hash this schema once, so startup can detect when it has drifted from the
|
|
172
|
+
// schema the server currently has active. The server and the `ablo push`
|
|
173
|
+
// command compute this same hash.
|
|
186
174
|
expectedSchemaHash: schemaHash(schema),
|
|
187
175
|
};
|
|
188
176
|
}
|
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
import type { SchemaRecord } from '../schema/schema.js';
|
|
2
2
|
import type { AbloSession, CreateSessionParams } from './resourceTypes.js';
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
3
|
+
/**
|
|
4
|
+
* The resolved control-plane details a mint needs: a secret key, a base URL,
|
|
5
|
+
* and an optional `fetch`. When `fetch` is omitted, the auth helpers fall back
|
|
6
|
+
* to the runtime's global `fetch`.
|
|
7
|
+
*/
|
|
5
8
|
export interface MintSessionContext {
|
|
6
9
|
readonly apiKey: string;
|
|
7
10
|
readonly baseUrl: string;
|
|
8
11
|
readonly fetch?: typeof fetch;
|
|
9
12
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* checks, but `can` is keyed by schema key — so
|
|
13
|
-
* on a model whose
|
|
14
|
-
* `document.update`, not `documents.update
|
|
15
|
-
* `capability_scope_denied
|
|
16
|
-
* there the `can` key already
|
|
13
|
+
* Maps each schema key to its wire type name. Only the schema-aware client
|
|
14
|
+
* supplies this. A capability is scoped by the lowercased type name the
|
|
15
|
+
* server checks, but `can` is keyed by schema key — so
|
|
16
|
+
* `can: { documents: ['update'] }` on a model whose type name is overridden
|
|
17
|
+
* to `Document` must mint `document.update`, not `documents.update`, or the
|
|
18
|
+
* server denies the write with `capability_scope_denied`. The schemaless
|
|
19
|
+
* client omits this map, because there the `can` key is already the wire
|
|
20
|
+
* token and needs no translation.
|
|
17
21
|
*/
|
|
18
22
|
readonly modelTypenames?: Readonly<Record<string, string>>;
|
|
19
23
|
}
|
|
20
24
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
25
|
+
* Mints a session token from an already-resolved secret key and base URL.
|
|
26
|
+
* Routes the `{ user }` or `{ agent }` request to the matching mint endpoint
|
|
27
|
+
* and reshapes the response into an {@link AbloSession}.
|
|
24
28
|
*/
|
|
25
29
|
export declare function mintSession<S extends SchemaRecord>(params: CreateSessionParams<S>, ctx: MintSessionContext): Promise<AbloSession>;
|
|
@@ -1,37 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* never
|
|
2
|
+
* Mints a session token. This is the single implementation behind
|
|
3
|
+
* `sessions.create`, shared by the schema-aware client and the schemaless HTTP
|
|
4
|
+
* client so the two never disagree on how a token is produced.
|
|
5
5
|
*
|
|
6
|
-
* Minting is a
|
|
7
|
-
* holding a secret `sk_` exchanges it for a short-lived scoped
|
|
8
|
-
*
|
|
9
|
-
* (scoped to exactly the operations named in `can`). The two arms map to the
|
|
10
|
-
* server's two mint doors:
|
|
6
|
+
* Minting is a plain control-plane HTTP call — no socket, no synced data. A
|
|
7
|
+
* backend holding a secret key (`sk_`) exchanges it for a short-lived, scoped
|
|
8
|
+
* token whose kind depends on the session requested:
|
|
11
9
|
*
|
|
12
|
-
* `{ user }` → POST /auth/ephemeral-keys
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
10
|
+
* `{ user }` → POST /auth/ephemeral-keys, returning an `ek_` key that carries
|
|
11
|
+
* full end-user authority. This is the only route that mints a
|
|
12
|
+
* user session; the capability route rejects a `user`
|
|
13
|
+
* participant with `invalid_participant_kind`.
|
|
14
|
+
* `{ agent }` → POST /auth/capability, returning an `rk_` key scoped to exactly
|
|
15
|
+
* the operations named in `can`. For example
|
|
16
|
+
* `can: { tasks: ['update'] }` becomes the wire allowlist entry
|
|
17
|
+
* `tasks.update`, which the server matches against the model's
|
|
18
|
+
* registered names.
|
|
21
19
|
*
|
|
22
|
-
* The caller supplies the resolved
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* Type-only imports of `CreateSessionParams` / `AbloSession` keep this module a
|
|
27
|
-
* leaf (no runtime cycle back to `Ablo.ts`): at runtime it depends on `auth` +
|
|
28
|
-
* `schema` only.
|
|
20
|
+
* The caller supplies the already-resolved secret key and base URL in
|
|
21
|
+
* {@link MintSessionContext}. Choosing which key to pass — the original secret
|
|
22
|
+
* key, not a derived key that an earlier exchange may have produced — is the
|
|
23
|
+
* caller's responsibility.
|
|
29
24
|
*/
|
|
30
25
|
import { exchangeApiKey, mintUserSessionKey } from '../auth/index.js';
|
|
31
26
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
27
|
+
* Mints a session token from an already-resolved secret key and base URL.
|
|
28
|
+
* Routes the `{ user }` or `{ agent }` request to the matching mint endpoint
|
|
29
|
+
* and reshapes the response into an {@link AbloSession}.
|
|
35
30
|
*/
|
|
36
31
|
export async function mintSession(params, ctx) {
|
|
37
32
|
const { apiKey, baseUrl } = ctx;
|
|
@@ -64,10 +59,10 @@ export async function mintSession(params, ctx) {
|
|
|
64
59
|
};
|
|
65
60
|
}
|
|
66
61
|
const operations = Object.entries(params.can).flatMap(([model, ops]) => {
|
|
67
|
-
// Translate the schema key the developer used in `can`
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
62
|
+
// Translate the schema key the developer used in `can` into the wire type
|
|
63
|
+
// name the server checks — see `modelTypenames` above. Falls back to the
|
|
64
|
+
// key itself when no map is supplied (the schemaless client) or the key is
|
|
65
|
+
// absent from it.
|
|
71
66
|
const ns = ctx.modelTypenames?.[model] ?? model;
|
|
72
67
|
return (ops ?? []).map((op) => `${ns.toLowerCase()}.${op}`);
|
|
73
68
|
});
|