@abloatai/ablo 0.26.0 → 0.28.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 +42 -2
- package/README.md +102 -86
- package/dist/BaseSyncedStore.d.ts +85 -88
- package/dist/BaseSyncedStore.js +134 -151
- package/dist/Database.d.ts +68 -69
- package/dist/Database.js +316 -135
- 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 +54 -52
- package/dist/Model.js +78 -62
- 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 +122 -118
- package/dist/SyncClient.js +541 -245
- package/dist/adapters/alwaysOnline.d.ts +6 -8
- package/dist/adapters/alwaysOnline.js +6 -8
- package/dist/adapters/inMemoryStorage.d.ts +10 -9
- package/dist/adapters/inMemoryStorage.js +21 -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 +173 -121
- package/dist/client/Ablo.d.ts +97 -74
- package/dist/client/Ablo.js +129 -163
- package/dist/client/ApiClient.d.ts +30 -19
- package/dist/client/ApiClient.js +442 -81
- 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 +16 -17
- package/dist/client/createInternalComponents.js +26 -31
- 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 +59 -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 +78 -87
- package/dist/client/options.d.ts +157 -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 +16 -20
- package/dist/client/wsMutationExecutor.js +18 -23
- package/dist/commit/contract.d.ts +493 -0
- package/dist/commit/contract.js +187 -0
- package/dist/commit/index.d.ts +6 -0
- package/dist/commit/index.js +5 -0
- 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 +14 -14
- package/dist/core/StoreManager.js +33 -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 +137 -134
- package/dist/errors.d.ts +160 -166
- package/dist/errors.js +155 -158
- package/dist/index.d.ts +36 -27
- package/dist/index.js +91 -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 +124 -131
- package/dist/mutators/UndoManager.js +177 -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 +28 -25
- package/dist/react/useAblo.js +41 -17
- 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 +3 -3
- 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 +64 -43
- 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 +24 -12
- package/dist/stores/ObjectStore.js +38 -16
- package/dist/stores/ObjectStoreContract.d.ts +14 -15
- package/dist/stores/SyncActionStore.d.ts +7 -11
- package/dist/stores/SyncActionStore.js +13 -17
- package/dist/surface.d.ts +28 -21
- package/dist/surface.js +29 -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 +141 -166
- 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/persistedPrefix.d.ts +12 -0
- package/dist/sync/persistedPrefix.js +22 -0
- 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 +5 -3
- package/dist/testing/index.js +3 -2
- package/dist/testing/mocks/FakeDatabase.d.ts +18 -0
- package/dist/testing/mocks/FakeDatabase.js +10 -0
- 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 +28 -23
- package/dist/testing/mocks/MockWebSocket.js +22 -21
- package/dist/transactions/TransactionQueue.d.ts +244 -181
- package/dist/transactions/TransactionQueue.js +929 -423
- 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/commitEnvelope.d.ts +132 -0
- package/dist/transactions/commitEnvelope.js +139 -0
- package/dist/transactions/commitOutboxStore.d.ts +32 -0
- package/dist/transactions/commitOutboxStore.js +26 -0
- package/dist/transactions/commitPayload.d.ts +63 -52
- package/dist/transactions/commitPayload.js +54 -57
- package/dist/transactions/deltaConfirmation.d.ts +20 -22
- package/dist/transactions/deltaConfirmation.js +37 -45
- package/dist/transactions/httpCommitEnvelope.d.ts +43 -0
- package/dist/transactions/httpCommitEnvelope.js +179 -0
- package/dist/transactions/optimisticApply.d.ts +49 -0
- package/dist/transactions/optimisticApply.js +65 -0
- package/dist/transactions/replayValidation.d.ts +182 -0
- package/dist/transactions/replayValidation.js +156 -0
- 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/wire/bootstrapReason.d.ts +9 -0
- package/dist/wire/bootstrapReason.js +8 -0
- 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 +315 -86
- package/dist/wire/frames.js +47 -33
- package/dist/wire/index.d.ts +18 -14
- package/dist/wire/index.js +32 -27
- 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/api.md +10 -10
- package/docs/coordination.md +59 -0
- package/docs/mcp.md +1 -1
- package/package.json +17 -11
- 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/transactions/persistedReplay.d.ts +0 -93
- package/dist/transactions/persistedReplay.js +0 -105
- package/dist/utils/mobx-setup.d.ts +0 -42
package/dist/policy/types.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The conflict types a policy decides on. The engine detects a conflict and
|
|
3
|
+
* hands it to your {@link ConflictPolicy}, which returns a
|
|
4
|
+
* {@link ConflictDecision}.
|
|
3
5
|
*
|
|
4
|
-
*
|
|
5
|
-
* is older than the latest delta on the target
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* There are two conflict shapes. A {@link StaleContextConflict} is a write
|
|
7
|
+
* whose `readAt` watermark is older than the latest delta on the target row. A
|
|
8
|
+
* {@link ClaimHeldConflict} is a participant trying to claim a target that
|
|
9
|
+
* someone else already holds. {@link Conflict} is the discriminated union of
|
|
10
|
+
* the two; switch on `kind` to narrow it.
|
|
8
11
|
*/
|
|
9
12
|
import type { ParticipantRef } from '../types/participant.js';
|
|
10
13
|
import type { OnStaleMode } from '../coordination/schema.js';
|
|
@@ -32,19 +35,18 @@ export interface StaleContextConflict extends ConflictBase {
|
|
|
32
35
|
readonly observedSyncId: number;
|
|
33
36
|
/**
|
|
34
37
|
* The fields whose concurrent change triggered this conflict — the
|
|
35
|
-
* intersection of the committer
|
|
36
|
-
*
|
|
37
|
-
* whole-entity change
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* cosmetic field. See `docs/internal/per-field-conflict-detection.md`.
|
|
38
|
+
* intersection of the fields the committer wrote and the columns a newer
|
|
39
|
+
* delta touched. An empty array means the conflicting delta was a
|
|
40
|
+
* whole-entity change, such as a create or delete, which conflicts with any
|
|
41
|
+
* write. A policy can use this to decide at field granularity — for example,
|
|
42
|
+
* allowing the write when the only overlap is on a cosmetic field.
|
|
41
43
|
*/
|
|
42
44
|
readonly conflictingFields?: readonly string[];
|
|
43
45
|
/**
|
|
44
|
-
* The committer's declared `onStale` intent for this
|
|
45
|
-
* honors it: `'notify'`
|
|
46
|
-
*
|
|
47
|
-
* `'reject'
|
|
46
|
+
* The committer's declared `onStale` intent for this operation. The default
|
|
47
|
+
* policy honors it: `'notify'` holds the write and notifies, and anything
|
|
48
|
+
* else rejects. A custom policy may override this. When absent, it is treated
|
|
49
|
+
* as `'reject'`, the default for an unguarded write.
|
|
48
50
|
*/
|
|
49
51
|
readonly requestedMode?: 'reject' | 'overwrite' | 'notify';
|
|
50
52
|
}
|
|
@@ -57,11 +59,12 @@ export interface ClaimHeldConflict extends ConflictBase {
|
|
|
57
59
|
/** Holder's claim expiry (ms since epoch). */
|
|
58
60
|
readonly expiresAt: number;
|
|
59
61
|
/**
|
|
60
|
-
* The
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* the committer holds `claim.preempt`"
|
|
64
|
-
* Empty for a human session
|
|
62
|
+
* The capability operations granted to the committer — the allowlist carried
|
|
63
|
+
* by its key. A policy decides purely from the conflict it is given, so this
|
|
64
|
+
* is the only place it can read the committer's privileges. It lets a policy
|
|
65
|
+
* express a rule such as "preempt only if the committer holds `claim.preempt`"
|
|
66
|
+
* (see {@link capabilityPreemptPolicy}). Empty for a human session that
|
|
67
|
+
* carries no allowlist.
|
|
65
68
|
*/
|
|
66
69
|
readonly committerOperations: readonly string[];
|
|
67
70
|
}
|
|
@@ -79,37 +82,40 @@ export type ConflictDecision = {
|
|
|
79
82
|
readonly note?: string;
|
|
80
83
|
}
|
|
81
84
|
/**
|
|
82
|
-
* Evict the current holder and grant the target to the committer.
|
|
83
|
-
* meaningful for
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
85
|
+
* Evict the current holder and grant the target to the committer. This is
|
|
86
|
+
* only meaningful for a `claim_held` conflict raised at claim time: the
|
|
87
|
+
* holder receives a `claim_lost` notification with reason `'preempted'`, and
|
|
88
|
+
* the committer takes the lease ahead of anyone already waiting in line for
|
|
89
|
+
* it. Return it only for a committer you consider higher priority — for
|
|
90
|
+
* example, a supervisor over its own sub-agents, or an identity that holds a
|
|
91
|
+
* preempt capability. At commit time there is no holder to evict, so a
|
|
92
|
+
* `preempt` decision is treated as `allow`.
|
|
90
93
|
*/
|
|
91
94
|
| {
|
|
92
95
|
readonly action: 'preempt';
|
|
93
96
|
readonly reason?: string;
|
|
94
97
|
}
|
|
95
98
|
/**
|
|
96
|
-
*
|
|
97
|
-
* `stale_context` conflict
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
99
|
+
* Hold the write instead of aborting it. This is only meaningful for a
|
|
100
|
+
* `stale_context` conflict. The engine withholds the conflicting operation
|
|
101
|
+
* and returns a `StaleNotification` carrying the current value, so the actor
|
|
102
|
+
* — an agent or a human — can reconcile and re-commit. The rest of the batch
|
|
103
|
+
* still commits. It maps from `onStale: 'notify'`.
|
|
101
104
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* client's reconciliation retry cap.
|
|
105
|
+
* The monotonic `sync_id` landing order decides who yields: the stale
|
|
106
|
+
* committer always recomputes against the newer value, an asymmetry that
|
|
107
|
+
* prevents two notifying writers from looping against each other. Retries are
|
|
108
|
+
* bounded by the client's reconciliation retry cap.
|
|
106
109
|
*/
|
|
107
110
|
| {
|
|
108
111
|
readonly action: 'notify';
|
|
109
112
|
readonly reason?: string;
|
|
110
113
|
};
|
|
111
114
|
/**
|
|
112
|
-
*
|
|
115
|
+
* The function that decides a conflict. It receives a {@link Conflict} and
|
|
116
|
+
* returns a {@link ConflictDecision}, either synchronously or as a promise.
|
|
117
|
+
* Register your implementation with the engine; the example below allows a
|
|
118
|
+
* cosmetic "linter" writer and defers everything else to {@link defaultPolicy}.
|
|
113
119
|
*
|
|
114
120
|
* ```ts
|
|
115
121
|
* const policy: ConflictPolicy = (conflict) => {
|
|
@@ -122,64 +128,61 @@ export type ConflictDecision = {
|
|
|
122
128
|
*/
|
|
123
129
|
export type ConflictPolicy = (conflict: Conflict) => ConflictDecision | Promise<ConflictDecision>;
|
|
124
130
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
131
|
+
* The conflict policy the engine uses when you do not supply your own. It
|
|
132
|
+
* favors people: a human is never blocked, while agents and automated writers
|
|
133
|
+
* yield to a claim someone else holds.
|
|
127
134
|
*
|
|
128
|
-
*
|
|
129
|
-
* construction, identical to `coordination(humansOverwrite())` applied to every
|
|
130
|
-
* model — so a developer who wants different behaviour just declares the conflict
|
|
131
|
-
* axis on that model (`humansReject()`, `humansNotify()`, `systemOverwrite()`, …)
|
|
132
|
-
* and it wins. The default and the override speak the same vocabulary; the
|
|
133
|
-
* default is the one you get for free.
|
|
135
|
+
* For a `claim_held` conflict, the decision follows the committer's kind:
|
|
134
136
|
*
|
|
135
|
-
* • `user` → `allow` — a human is never blocked by a claim
|
|
136
|
-
* coordination hint among agents, not a lock on
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
137
|
+
* • `user` → `allow` — a human is never blocked by a claim. A claim is a
|
|
138
|
+
* coordination hint among agents, not a lock on
|
|
139
|
+
* people.
|
|
140
|
+
* • `agent` → `reject` — an agent yields to a claim held by someone else.
|
|
141
|
+
* The one sanctioned exception is the privileged
|
|
142
|
+
* `claim.preempt` capability; see
|
|
143
|
+
* {@link capabilityPreemptPolicy}.
|
|
144
|
+
* • `system` → `reject` — automated and backend writers serialize through
|
|
145
|
+
* claims the same way agents do, so a server job
|
|
146
|
+
* cannot silently overwrite a held row. Declare the
|
|
147
|
+
* model's conflict axis to overwrite if you want that.
|
|
145
148
|
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
* contract (claim serialization / the retry-storm guard) depends on them
|
|
150
|
-
* respecting claims unless a model says otherwise.
|
|
149
|
+
* Allowing only `user` by default is deliberate: a backend key is a
|
|
150
|
+
* full-access credential, and claim serialization depends on those writers
|
|
151
|
+
* respecting claims unless a model opts out.
|
|
151
152
|
*
|
|
152
|
-
* `stale_context`
|
|
153
|
+
* For a `stale_context` conflict, the decision honors the committer's declared
|
|
154
|
+
* `onStale` intent: `'notify'` holds the write and notifies the actor to
|
|
155
|
+
* resolve it, and anything else (including `'reject'` or an absent value)
|
|
156
|
+
* rejects. An `onStale` of `'overwrite'` never reaches a policy — it is a hard
|
|
157
|
+
* opt-out resolved before the conflict is detected.
|
|
153
158
|
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
* `'overwrite'` never reaches a policy on the stale path — it's a hard opt-out
|
|
158
|
-
* resolved before detection.
|
|
159
|
+
* To change this behavior for a model, declare its conflict axis in the schema;
|
|
160
|
+
* a declared axis overrides this default.
|
|
159
161
|
*/
|
|
160
162
|
export declare const defaultPolicy: (conflict: Conflict) => ConflictDecision;
|
|
161
163
|
/**
|
|
162
|
-
*
|
|
163
|
-
* committer
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
164
|
+
* A ready-made policy that grants capability-gated preemption. When the
|
|
165
|
+
* committer's capability allowlist includes the `claim.preempt` operation, a
|
|
166
|
+
* `claim_held` conflict is preempted: the current holder is evicted and the
|
|
167
|
+
* committer takes the lease. Every other conflict falls back to
|
|
168
|
+
* {@link defaultPolicy}, which rejects. Register it as your conflict policy to
|
|
169
|
+
* let a privileged identity take over a held entity without writing a bespoke
|
|
170
|
+
* policy. The authorization rests on holding the capability, not on any
|
|
171
|
+
* particular identity string.
|
|
168
172
|
*/
|
|
169
173
|
export declare const capabilityPreemptPolicy: ConflictPolicy;
|
|
170
174
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* registry to the schema-agnostic server, which names no app model.
|
|
175
|
+
* A model's declared conflict disposition, keyed by the kind of committer. You
|
|
176
|
+
* set it in the model's schema, for example
|
|
177
|
+
* `conflict: { user: 'overwrite', agent: 'reject' }`, and the engine applies it
|
|
178
|
+
* at commit time. It is plain data using the same `'reject' | 'overwrite' |
|
|
179
|
+
* 'notify'` vocabulary as the write guards, so it travels through the schema
|
|
180
|
+
* registry to the server without naming any application model.
|
|
178
181
|
*
|
|
179
|
-
*
|
|
180
|
-
* omitted kind falls
|
|
181
|
-
* agent: 'reject' }` reads "a human's write wins
|
|
182
|
-
* write yields"
|
|
182
|
+
* Each key is the committer's participant kind, which the server derives and a
|
|
183
|
+
* client cannot forge; an omitted kind falls back to the engine default. So
|
|
184
|
+
* `{ user: 'overwrite', agent: 'reject' }` reads as "a human's write wins, an
|
|
185
|
+
* agent's write yields," and `system`, being unlisted, takes the default.
|
|
183
186
|
*/
|
|
184
187
|
export interface ConflictAxis {
|
|
185
188
|
/** What happens when a human (`user` session) commits into a conflict. */
|
|
@@ -190,24 +193,25 @@ export interface ConflictAxis {
|
|
|
190
193
|
readonly system?: OnStaleMode;
|
|
191
194
|
}
|
|
192
195
|
/**
|
|
193
|
-
*
|
|
194
|
-
* synchronous
|
|
195
|
-
*
|
|
196
|
+
* Resolves a declared {@link ConflictAxis} into a {@link ConflictDecision} for
|
|
197
|
+
* one concrete conflict. It is pure and synchronous, doing no I/O, so it can
|
|
198
|
+
* run on either the client or the server. It reads the committer's kind from
|
|
199
|
+
* the conflict and maps the declared mode:
|
|
196
200
|
*
|
|
197
|
-
* - undefined → the engine default
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* - `
|
|
202
|
-
* - `
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
* `reject` rather than silently
|
|
201
|
+
* - undefined → the engine default, {@link defaultPolicy}: a human is
|
|
202
|
+
* allowed, an agent or system committer is rejected on a
|
|
203
|
+
* `claim_held`, and a stale write honors `onStale: 'notify'`.
|
|
204
|
+
* - `overwrite` → `allow`; the write wins and the committer is never blocked.
|
|
205
|
+
* - `reject` → `reject`; the committer yields.
|
|
206
|
+
* - `notify` → on a `stale_context` conflict, hold the write and notify so
|
|
207
|
+
* the committer re-reads and re-applies; on a `claim_held`
|
|
208
|
+
* conflict there is no held write to reconcile (see
|
|
209
|
+
* {@link ConflictDecision} `notify`), so it degrades to
|
|
210
|
+
* `reject` rather than silently writing to a claimed row.
|
|
207
211
|
*
|
|
208
|
-
*
|
|
209
|
-
* agent
|
|
210
|
-
* applied, not here.
|
|
212
|
+
* This is only the generic interpretation. Stronger server-side rules — such as
|
|
213
|
+
* an agent never bypassing a claim held by someone else — are enforced where
|
|
214
|
+
* the decision is applied, not here.
|
|
211
215
|
*/
|
|
212
216
|
export declare function interpretConflictAxis(axis: ConflictAxis, conflict: Conflict): ConflictDecision;
|
|
213
217
|
export {};
|
package/dist/policy/types.js
CHANGED
|
@@ -1,59 +1,57 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The conflict types a policy decides on. The engine detects a conflict and
|
|
3
|
+
* hands it to your {@link ConflictPolicy}, which returns a
|
|
4
|
+
* {@link ConflictDecision}.
|
|
3
5
|
*
|
|
4
|
-
*
|
|
5
|
-
* is older than the latest delta on the target
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* There are two conflict shapes. A {@link StaleContextConflict} is a write
|
|
7
|
+
* whose `readAt` watermark is older than the latest delta on the target row. A
|
|
8
|
+
* {@link ClaimHeldConflict} is a participant trying to claim a target that
|
|
9
|
+
* someone else already holds. {@link Conflict} is the discriminated union of
|
|
10
|
+
* the two; switch on `kind` to narrow it.
|
|
8
11
|
*/
|
|
9
12
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
13
|
+
* The conflict policy the engine uses when you do not supply your own. It
|
|
14
|
+
* favors people: a human is never blocked, while agents and automated writers
|
|
15
|
+
* yield to a claim someone else holds.
|
|
12
16
|
*
|
|
13
|
-
*
|
|
14
|
-
* construction, identical to `coordination(humansOverwrite())` applied to every
|
|
15
|
-
* model — so a developer who wants different behaviour just declares the conflict
|
|
16
|
-
* axis on that model (`humansReject()`, `humansNotify()`, `systemOverwrite()`, …)
|
|
17
|
-
* and it wins. The default and the override speak the same vocabulary; the
|
|
18
|
-
* default is the one you get for free.
|
|
17
|
+
* For a `claim_held` conflict, the decision follows the committer's kind:
|
|
19
18
|
*
|
|
20
|
-
* • `user` → `allow` — a human is never blocked by a claim
|
|
21
|
-
* coordination hint among agents, not a lock on
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
19
|
+
* • `user` → `allow` — a human is never blocked by a claim. A claim is a
|
|
20
|
+
* coordination hint among agents, not a lock on
|
|
21
|
+
* people.
|
|
22
|
+
* • `agent` → `reject` — an agent yields to a claim held by someone else.
|
|
23
|
+
* The one sanctioned exception is the privileged
|
|
24
|
+
* `claim.preempt` capability; see
|
|
25
|
+
* {@link capabilityPreemptPolicy}.
|
|
26
|
+
* • `system` → `reject` — automated and backend writers serialize through
|
|
27
|
+
* claims the same way agents do, so a server job
|
|
28
|
+
* cannot silently overwrite a held row. Declare the
|
|
29
|
+
* model's conflict axis to overwrite if you want that.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* contract (claim serialization / the retry-storm guard) depends on them
|
|
35
|
-
* respecting claims unless a model says otherwise.
|
|
31
|
+
* Allowing only `user` by default is deliberate: a backend key is a
|
|
32
|
+
* full-access credential, and claim serialization depends on those writers
|
|
33
|
+
* respecting claims unless a model opts out.
|
|
36
34
|
*
|
|
37
|
-
* `stale_context`
|
|
35
|
+
* For a `stale_context` conflict, the decision honors the committer's declared
|
|
36
|
+
* `onStale` intent: `'notify'` holds the write and notifies the actor to
|
|
37
|
+
* resolve it, and anything else (including `'reject'` or an absent value)
|
|
38
|
+
* rejects. An `onStale` of `'overwrite'` never reaches a policy — it is a hard
|
|
39
|
+
* opt-out resolved before the conflict is detected.
|
|
38
40
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* `'overwrite'` never reaches a policy on the stale path — it's a hard opt-out
|
|
43
|
-
* resolved before detection.
|
|
41
|
+
* To change this behavior for a model, declare its conflict axis in the schema;
|
|
42
|
+
* a declared axis overrides this default.
|
|
44
43
|
*/
|
|
45
|
-
// Typed by its real
|
|
46
|
-
// async-permissive `ConflictPolicy` alias, so
|
|
47
|
-
// `interpretConflictAxis` and `capabilityPreemptPolicy`
|
|
48
|
-
// `ConflictDecision`
|
|
49
|
-
// `ConflictPolicy`
|
|
44
|
+
// Typed by its real synchronous shape with `satisfies`, rather than the
|
|
45
|
+
// async-permissive `ConflictPolicy` alias, so synchronous callers such as
|
|
46
|
+
// `interpretConflictAxis` and `capabilityPreemptPolicy` receive a plain
|
|
47
|
+
// `ConflictDecision` rather than `ConflictDecision | Promise<…>`. It remains
|
|
48
|
+
// assignable to `ConflictPolicy` wherever it is used as one.
|
|
50
49
|
export const defaultPolicy = ((conflict) => {
|
|
51
50
|
if (conflict.kind === 'claim_held') {
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
// agent-degradation guard).
|
|
51
|
+
// A human (`user`) is never blocked; agents and system actors yield.
|
|
52
|
+
// Keeping every non-`user` kind on `reject` here ensures an agent cannot
|
|
53
|
+
// bypass a claim even on this default resolution path, which — unlike the
|
|
54
|
+
// declared-axis path — has no separate agent guard of its own.
|
|
57
55
|
return conflict.committer.kind === 'user'
|
|
58
56
|
? { action: 'allow', note: 'principal:not-blocked' }
|
|
59
57
|
: { action: 'reject', reason: 'claim_conflict' };
|
|
@@ -63,12 +61,14 @@ export const defaultPolicy = ((conflict) => {
|
|
|
63
61
|
: { action: 'reject', reason: 'stale_context' };
|
|
64
62
|
});
|
|
65
63
|
/**
|
|
66
|
-
*
|
|
67
|
-
* committer
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
64
|
+
* A ready-made policy that grants capability-gated preemption. When the
|
|
65
|
+
* committer's capability allowlist includes the `claim.preempt` operation, a
|
|
66
|
+
* `claim_held` conflict is preempted: the current holder is evicted and the
|
|
67
|
+
* committer takes the lease. Every other conflict falls back to
|
|
68
|
+
* {@link defaultPolicy}, which rejects. Register it as your conflict policy to
|
|
69
|
+
* let a privileged identity take over a held entity without writing a bespoke
|
|
70
|
+
* policy. The authorization rests on holding the capability, not on any
|
|
71
|
+
* particular identity string.
|
|
72
72
|
*/
|
|
73
73
|
export const capabilityPreemptPolicy = (conflict) => {
|
|
74
74
|
if (conflict.kind === 'claim_held' &&
|
|
@@ -78,24 +78,25 @@ export const capabilityPreemptPolicy = (conflict) => {
|
|
|
78
78
|
return defaultPolicy(conflict);
|
|
79
79
|
};
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
82
|
-
* synchronous
|
|
83
|
-
*
|
|
81
|
+
* Resolves a declared {@link ConflictAxis} into a {@link ConflictDecision} for
|
|
82
|
+
* one concrete conflict. It is pure and synchronous, doing no I/O, so it can
|
|
83
|
+
* run on either the client or the server. It reads the committer's kind from
|
|
84
|
+
* the conflict and maps the declared mode:
|
|
84
85
|
*
|
|
85
|
-
* - undefined → the engine default
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* - `
|
|
90
|
-
* - `
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* `reject` rather than silently
|
|
86
|
+
* - undefined → the engine default, {@link defaultPolicy}: a human is
|
|
87
|
+
* allowed, an agent or system committer is rejected on a
|
|
88
|
+
* `claim_held`, and a stale write honors `onStale: 'notify'`.
|
|
89
|
+
* - `overwrite` → `allow`; the write wins and the committer is never blocked.
|
|
90
|
+
* - `reject` → `reject`; the committer yields.
|
|
91
|
+
* - `notify` → on a `stale_context` conflict, hold the write and notify so
|
|
92
|
+
* the committer re-reads and re-applies; on a `claim_held`
|
|
93
|
+
* conflict there is no held write to reconcile (see
|
|
94
|
+
* {@link ConflictDecision} `notify`), so it degrades to
|
|
95
|
+
* `reject` rather than silently writing to a claimed row.
|
|
95
96
|
*
|
|
96
|
-
*
|
|
97
|
-
* agent
|
|
98
|
-
* applied, not here.
|
|
97
|
+
* This is only the generic interpretation. Stronger server-side rules — such as
|
|
98
|
+
* an agent never bypassing a claim held by someone else — are enforced where
|
|
99
|
+
* the decision is applied, not here.
|
|
99
100
|
*/
|
|
100
101
|
export function interpretConflictAxis(axis, conflict) {
|
|
101
102
|
const mode = axis[conflict.committer.kind];
|
package/dist/query/client.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HTTP client for the
|
|
2
|
+
* The HTTP client for the sync query endpoint.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* {@link postQuery} is a small wrapper over `fetch` that POSTs a
|
|
5
|
+
* {@link QueryBatch} as JSON to `/sync/query`, attaches the bearer credential
|
|
6
|
+
* as an `Authorization` header, and parses the response into a typed
|
|
7
|
+
* {@link QueryBatchResult}. An HTTP failure is not thrown: it is logged, and
|
|
8
|
+
* every query in the batch comes back with an empty result, so a
|
|
9
|
+
* fire-and-forget caller cannot crash on an unhandled rejection.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* without duplicating the fetch boilerplate.
|
|
11
|
+
* Higher-level query helpers build on this to issue structured queries without
|
|
12
|
+
* repeating the fetch and error-handling boilerplate.
|
|
13
13
|
*/
|
|
14
14
|
import type { QueryBatch, QueryBatchResult } from './types.js';
|
|
15
15
|
import { type RecoveryClass } from '../errorCodes.js';
|
|
@@ -30,27 +30,32 @@ export interface PostQueryOptions {
|
|
|
30
30
|
*/
|
|
31
31
|
getAuthToken?: AuthTokenGetter;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
33
|
+
* A fixed credential string, for callers that hold only a copied token.
|
|
34
|
+
* Prefer `getAuthToken`, which is re-read on each request so a refresh takes
|
|
35
|
+
* effect without rebuilding the client.
|
|
35
36
|
*/
|
|
36
37
|
capabilityToken?: string;
|
|
37
38
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
39
|
+
* An optional hook that tries to recover from a rejected credential. When a
|
|
40
|
+
* query comes back with a 401, its {@link RecoveryClass} is passed here: a
|
|
41
|
+
* return of `'retry'` means a fresh credential has been obtained and the
|
|
42
|
+
* request is replayed exactly once, while `'stop'` ends the attempt. Because
|
|
43
|
+
* the replay happens at most once, a wedged credential cannot cause a retry
|
|
44
|
+
* loop. When this hook is absent, a 401 is logged and returns empty results
|
|
45
|
+
* like any other failure.
|
|
45
46
|
*/
|
|
46
47
|
recoverCredential?: (recovery: RecoveryClass) => Promise<'retry' | 'stop'>;
|
|
47
48
|
}
|
|
48
49
|
/**
|
|
49
|
-
*
|
|
50
|
-
* QueryBatchResult.
|
|
50
|
+
* Sends a batch of queries to `/sync/query` and returns the parsed
|
|
51
|
+
* {@link QueryBatchResult}. An HTTP failure is not thrown: it is logged, and
|
|
52
|
+
* every query in the batch comes back with an empty result, which keeps a
|
|
53
|
+
* fire-and-forget caller from crashing on an unhandled rejection. A 401 may
|
|
54
|
+
* first be handed to {@link PostQueryOptions.recoverCredential} for a single
|
|
55
|
+
* retry.
|
|
51
56
|
*
|
|
52
|
-
* The
|
|
53
|
-
*
|
|
54
|
-
*
|
|
57
|
+
* The response preserves order: `results[i]` corresponds to the query at
|
|
58
|
+
* `queries[i]`, so callers can rely on index alignment to pull typed results
|
|
59
|
+
* out of a multi-query batch.
|
|
55
60
|
*/
|
|
56
61
|
export declare function postQuery(options: PostQueryOptions, batch: QueryBatch): Promise<QueryBatchResult>;
|