@abloatai/ablo 0.25.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -3
- package/CHANGELOG.md +34 -0
- package/README.md +104 -88
- package/dist/BaseSyncedStore.d.ts +140 -266
- package/dist/BaseSyncedStore.js +338 -739
- package/dist/Database.d.ts +62 -77
- package/dist/Database.js +106 -127
- package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
- package/dist/{ObjectPool.js → InstanceCache.js} +91 -83
- package/dist/LazyReferenceCollection.d.ts +11 -15
- package/dist/LazyReferenceCollection.js +16 -15
- package/dist/Model.d.ts +37 -52
- package/dist/Model.js +52 -69
- package/dist/ModelRegistry.d.ts +46 -25
- package/dist/ModelRegistry.js +32 -30
- package/dist/NetworkMonitor.d.ts +5 -6
- package/dist/NetworkMonitor.js +6 -7
- package/dist/SyncClient.d.ts +119 -109
- package/dist/SyncClient.js +303 -224
- package/dist/SyncEngineContext.d.ts +1 -3
- package/dist/SyncEngineContext.js +1 -2
- package/dist/adapters/alwaysOnline.d.ts +6 -8
- package/dist/adapters/alwaysOnline.js +6 -8
- package/dist/adapters/inMemoryStorage.d.ts +9 -9
- package/dist/adapters/inMemoryStorage.js +9 -9
- package/dist/agent/Agent.d.ts +39 -31
- package/dist/agent/Agent.js +35 -23
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +5 -5
- package/dist/agent/session.d.ts +47 -44
- package/dist/agent/session.js +37 -48
- package/dist/agent/types.d.ts +26 -31
- package/dist/agent/types.js +6 -7
- package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
- package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
- package/dist/ai-sdk/coordinationContext.d.ts +46 -0
- package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +30 -31
- package/dist/ai-sdk/index.d.ts +25 -22
- package/dist/ai-sdk/index.js +25 -22
- package/dist/ai-sdk/wrap.d.ts +7 -8
- package/dist/ai-sdk/wrap.js +2 -2
- package/dist/auth/credentialPolicy.d.ts +74 -71
- package/dist/auth/credentialPolicy.js +51 -56
- package/dist/auth/credentialSource.d.ts +7 -18
- package/dist/auth/credentialSource.js +10 -18
- package/dist/auth/index.d.ts +59 -58
- package/dist/auth/index.js +34 -40
- package/dist/auth/schemas.d.ts +5 -4
- package/dist/auth/schemas.js +5 -4
- package/dist/batching/index.d.ts +19 -21
- package/dist/batching/index.js +14 -17
- package/dist/cli.cjs +483 -369
- package/dist/client/Ablo.d.ts +107 -836
- package/dist/client/Ablo.js +174 -833
- package/dist/client/ApiClient.d.ts +44 -20
- package/dist/client/ApiClient.js +193 -44
- package/dist/client/auth.d.ts +51 -60
- package/dist/client/auth.js +137 -110
- package/dist/client/claimHeartbeatLoop.d.ts +50 -0
- package/dist/client/claimHeartbeatLoop.js +88 -0
- package/dist/client/consoleLogger.d.ts +35 -0
- package/dist/client/consoleLogger.js +44 -0
- package/dist/client/createInternalComponents.d.ts +14 -17
- package/dist/client/createInternalComponents.js +26 -31
- package/dist/client/createModelProxy.d.ts +130 -120
- package/dist/client/createModelProxy.js +158 -124
- package/dist/client/credentialEndpoint.d.ts +61 -0
- package/dist/client/credentialEndpoint.js +86 -0
- package/dist/client/functionalUpdate.d.ts +29 -27
- package/dist/client/functionalUpdate.js +21 -21
- package/dist/client/hostedEndpoints.d.ts +21 -0
- package/dist/client/hostedEndpoints.js +21 -0
- package/dist/client/httpClient.d.ts +58 -54
- package/dist/client/httpClient.js +29 -31
- package/dist/client/identity.d.ts +15 -20
- package/dist/client/identity.js +49 -59
- package/dist/client/modelRegistration.d.ts +10 -0
- package/dist/client/modelRegistration.js +301 -0
- package/dist/client/options.d.ts +373 -0
- package/dist/client/options.js +6 -0
- package/dist/client/registerDataSource.d.ts +9 -9
- package/dist/client/registerDataSource.js +15 -16
- package/dist/client/resourceTypes.d.ts +333 -0
- package/dist/client/resourceTypes.js +7 -0
- package/dist/client/schemaConfig.d.ts +44 -0
- package/dist/client/schemaConfig.js +176 -0
- package/dist/client/sessionMint.d.ts +17 -13
- package/dist/client/sessionMint.js +26 -31
- package/dist/client/validateAbloOptions.d.ts +12 -14
- package/dist/client/validateAbloOptions.js +9 -10
- package/dist/client/writeOptionsSchema.d.ts +18 -16
- package/dist/client/writeOptionsSchema.js +23 -20
- package/dist/client/wsMutationExecutor.d.ts +28 -0
- package/dist/client/wsMutationExecutor.js +71 -0
- package/dist/context.d.ts +6 -4
- package/dist/context.js +6 -7
- package/dist/coordination/index.d.ts +13 -4
- package/dist/coordination/index.js +29 -4
- package/dist/coordination/schema.d.ts +176 -128
- package/dist/coordination/schema.js +197 -133
- package/dist/coordination/trace.d.ts +9 -11
- package/dist/coordination/trace.js +13 -15
- package/dist/core/DatabaseManager.d.ts +5 -8
- package/dist/core/DatabaseManager.js +38 -40
- package/dist/core/QueryProcessor.d.ts +7 -9
- package/dist/core/QueryProcessor.js +27 -34
- package/dist/core/QueryView.d.ts +17 -5
- package/dist/core/QueryView.js +6 -7
- package/dist/core/StoreManager.d.ts +14 -16
- package/dist/core/StoreManager.js +26 -25
- package/dist/core/ViewRegistry.d.ts +5 -5
- package/dist/core/ViewRegistry.js +4 -4
- package/dist/core/index.d.ts +18 -13
- package/dist/core/index.js +32 -26
- package/dist/core/openIDBWithTimeout.d.ts +38 -36
- package/dist/core/openIDBWithTimeout.js +57 -54
- package/dist/core/queryUtils.d.ts +45 -0
- package/dist/core/queryUtils.js +69 -0
- package/dist/core/storeContract.d.ts +145 -0
- package/dist/core/storeContract.js +12 -0
- package/dist/environment.d.ts +28 -0
- package/dist/environment.js +21 -0
- package/dist/errorCodes.d.ts +118 -101
- package/dist/errorCodes.js +277 -260
- package/dist/errors.d.ts +170 -165
- package/dist/errors.js +161 -151
- package/dist/index.d.ts +30 -27
- package/dist/index.js +90 -82
- package/dist/interfaces/index.d.ts +108 -133
- package/dist/interfaces/index.js +5 -4
- package/dist/keys/index.d.ts +27 -29
- package/dist/keys/index.js +59 -49
- package/dist/mutators/RecordingTransaction.d.ts +16 -16
- package/dist/mutators/RecordingTransaction.js +31 -37
- package/dist/mutators/Transaction.d.ts +18 -26
- package/dist/mutators/Transaction.js +14 -20
- package/dist/mutators/UndoManager.d.ts +122 -131
- package/dist/mutators/UndoManager.js +149 -155
- package/dist/mutators/defineMutators.d.ts +24 -37
- package/dist/mutators/defineMutators.js +14 -20
- package/dist/mutators/inverseOp.d.ts +12 -15
- package/dist/mutators/inverseOp.js +12 -15
- package/dist/mutators/mutateActions.d.ts +10 -9
- package/dist/mutators/mutateActions.js +1 -1
- package/dist/mutators/readerActions.d.ts +9 -8
- package/dist/mutators/readerActions.js +2 -2
- package/dist/mutators/undoApply.d.ts +31 -27
- package/dist/mutators/undoApply.js +26 -24
- package/dist/policy/index.d.ts +5 -3
- package/dist/policy/index.js +5 -3
- package/dist/policy/types.d.ts +105 -101
- package/dist/policy/types.js +67 -66
- package/dist/query/client.d.ts +32 -16
- package/dist/query/client.js +103 -72
- package/dist/query/types.d.ts +37 -60
- package/dist/query/types.js +13 -33
- package/dist/react/AbloProvider.d.ts +7 -11
- package/dist/react/AbloProvider.js +24 -17
- package/dist/react/context.d.ts +27 -146
- package/dist/react/context.js +9 -10
- package/dist/react/index.d.ts +41 -42
- package/dist/react/index.js +37 -38
- package/dist/react/internalContext.d.ts +17 -19
- package/dist/react/useAblo.d.ts +23 -22
- package/dist/react/useAblo.js +17 -15
- package/dist/react/useCurrentUserId.d.ts +8 -7
- package/dist/react/useCurrentUserId.js +8 -7
- package/dist/react/useErrorListener.d.ts +7 -7
- package/dist/react/useErrorListener.js +11 -12
- package/dist/react/useMutationFailureListener.d.ts +8 -8
- package/dist/react/useMutationFailureListener.js +9 -9
- package/dist/react/useMutators.d.ts +11 -11
- package/dist/react/useMutators.js +10 -4
- package/dist/react/useReactive.js +2 -3
- package/dist/react/useSyncStatus.d.ts +4 -6
- package/dist/react/useUndoScope.d.ts +7 -9
- package/dist/react/useUndoScope.js +3 -3
- package/dist/schema/coordination.d.ts +21 -25
- package/dist/schema/coordination.js +21 -25
- package/dist/schema/ddl.d.ts +43 -39
- package/dist/schema/ddl.js +75 -68
- package/dist/schema/ddlLock.d.ts +35 -0
- package/dist/schema/ddlLock.js +46 -0
- package/dist/schema/diff.d.ts +99 -61
- package/dist/schema/diff.js +43 -34
- package/dist/schema/field.d.ts +37 -42
- package/dist/schema/field.js +36 -49
- package/dist/schema/generate.d.ts +12 -12
- package/dist/schema/generate.js +12 -12
- package/dist/schema/index.d.ts +5 -4
- package/dist/schema/index.js +29 -21
- package/dist/schema/model.d.ts +121 -146
- package/dist/schema/model.js +24 -35
- package/dist/schema/openapi.d.ts +10 -9
- package/dist/schema/openapi.js +7 -1
- package/dist/schema/queries.d.ts +30 -32
- package/dist/schema/queries.js +24 -25
- package/dist/schema/relation.d.ts +89 -99
- package/dist/schema/relation.js +13 -13
- package/dist/schema/residency.d.ts +38 -0
- package/dist/schema/residency.js +30 -0
- package/dist/schema/roles.d.ts +45 -27
- package/dist/schema/roles.js +52 -21
- package/dist/schema/schema.d.ts +36 -45
- package/dist/schema/schema.js +42 -39
- package/dist/schema/select.d.ts +13 -13
- package/dist/schema/select.js +13 -13
- package/dist/schema/serialize.d.ts +36 -39
- package/dist/schema/serialize.js +27 -31
- package/dist/schema/sugar.d.ts +17 -32
- package/dist/schema/sugar.js +14 -29
- package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +27 -50
- package/dist/schema/syncDeltaRow.js +89 -0
- package/dist/schema/tenancy.d.ts +44 -46
- package/dist/schema/tenancy.js +46 -48
- package/dist/server/adapter.d.ts +58 -58
- package/dist/server/adapter.js +13 -14
- package/dist/server/commit.d.ts +60 -64
- package/dist/server/index.d.ts +9 -10
- package/dist/server/index.js +1 -1
- package/dist/server/readConfig.d.ts +70 -0
- package/dist/server/readConfig.js +8 -0
- package/dist/server/storageMode.d.ts +23 -0
- package/dist/server/storageMode.js +17 -0
- package/dist/source/adapter.d.ts +31 -26
- package/dist/source/adapter.js +10 -10
- package/dist/source/adapters/drizzle.d.ts +28 -23
- package/dist/source/adapters/drizzle.js +34 -28
- package/dist/source/adapters/kysely.d.ts +27 -25
- package/dist/source/adapters/kysely.js +28 -26
- package/dist/source/adapters/memory.d.ts +8 -7
- package/dist/source/adapters/memory.js +10 -9
- package/dist/source/adapters/prisma.d.ts +13 -12
- package/dist/source/adapters/prisma.js +27 -29
- package/dist/source/conformance.d.ts +18 -11
- package/dist/source/conformance.js +27 -19
- package/dist/source/connector.d.ts +31 -32
- package/dist/source/connector.js +30 -28
- package/dist/source/connectorProtocol.d.ts +160 -0
- package/dist/source/connectorProtocol.js +162 -0
- package/dist/source/contract.d.ts +26 -27
- package/dist/source/contract.js +28 -29
- package/dist/source/factory.d.ts +94 -0
- package/dist/source/factory.js +268 -0
- package/dist/source/index.d.ts +10 -462
- package/dist/source/index.js +17 -421
- package/dist/source/migrations.d.ts +9 -9
- package/dist/source/migrations.js +9 -9
- package/dist/source/next.d.ts +10 -11
- package/dist/source/next.js +7 -8
- package/dist/source/pushQueue.d.ts +70 -48
- package/dist/source/pushQueue.js +36 -29
- package/dist/source/signing.d.ts +88 -0
- package/dist/source/signing.js +159 -0
- package/dist/source/types.d.ts +351 -0
- package/dist/source/types.js +43 -0
- package/dist/stores/ObjectStore.d.ts +11 -12
- package/dist/stores/ObjectStore.js +34 -35
- package/dist/stores/ObjectStoreContract.d.ts +12 -15
- package/dist/stores/SyncActionStore.d.ts +8 -12
- package/dist/stores/SyncActionStore.js +77 -46
- package/dist/surface.d.ts +28 -21
- package/dist/surface.js +28 -20
- package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +37 -45
- package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +101 -80
- package/dist/sync/ConnectionManager.d.ts +47 -50
- package/dist/sync/ConnectionManager.js +74 -70
- package/dist/sync/NetworkProbe.d.ts +27 -31
- package/dist/sync/NetworkProbe.js +67 -72
- package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +49 -36
- package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +79 -54
- package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +45 -59
- package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +44 -52
- package/dist/sync/SyncWebSocket.d.ts +175 -250
- package/dist/sync/SyncWebSocket.js +431 -769
- package/dist/sync/awaitClaimGrant.d.ts +18 -18
- package/dist/sync/awaitClaimGrant.js +38 -30
- package/dist/sync/bootstrapApply.d.ts +70 -0
- package/dist/sync/bootstrapApply.js +73 -0
- package/dist/sync/commitFrames.d.ts +44 -0
- package/dist/sync/commitFrames.js +94 -0
- package/dist/sync/createClaimStream.d.ts +23 -22
- package/dist/sync/createClaimStream.js +108 -25
- package/dist/sync/createPresenceStream.d.ts +19 -18
- package/dist/sync/createPresenceStream.js +25 -26
- package/dist/sync/createSnapshot.d.ts +13 -17
- package/dist/sync/createSnapshot.js +20 -26
- package/dist/sync/credentialLifecycle.d.ts +175 -0
- package/dist/sync/credentialLifecycle.js +322 -0
- package/dist/sync/deltaPipeline.d.ts +113 -0
- package/dist/sync/deltaPipeline.js +261 -0
- package/dist/sync/groupChange.d.ts +113 -0
- package/dist/sync/groupChange.js +242 -0
- package/dist/sync/heartbeat.d.ts +63 -0
- package/dist/sync/heartbeat.js +91 -0
- package/dist/sync/participants.d.ts +27 -27
- package/dist/sync/schemas.d.ts +3 -2
- package/dist/sync/schemas.js +14 -10
- package/dist/sync/syncCursor.d.ts +40 -0
- package/dist/sync/syncCursor.js +55 -0
- package/dist/sync/syncPlan.d.ts +54 -0
- package/dist/sync/syncPlan.js +50 -0
- package/dist/sync/syncPosition.d.ts +54 -49
- package/dist/sync/syncPosition.js +57 -52
- package/dist/sync/wsFrameHandlers.d.ts +116 -0
- package/dist/sync/wsFrameHandlers.js +374 -0
- package/dist/testing/fixtures/bootstrap.d.ts +21 -17
- package/dist/testing/fixtures/bootstrap.js +12 -6
- package/dist/testing/fixtures/deltas.d.ts +31 -34
- package/dist/testing/fixtures/deltas.js +30 -33
- package/dist/testing/fixtures/models.d.ts +11 -10
- package/dist/testing/fixtures/models.js +12 -10
- package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
- package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
- package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -18
- package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +14 -11
- package/dist/testing/helpers/wait.d.ts +13 -8
- package/dist/testing/helpers/wait.js +13 -8
- package/dist/testing/index.d.ts +4 -4
- package/dist/testing/index.js +3 -3
- package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
- package/dist/testing/mocks/MockMutationExecutor.js +15 -14
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
- package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
- package/dist/testing/mocks/MockSyncContext.d.ts +21 -34
- package/dist/testing/mocks/MockSyncContext.js +16 -45
- package/dist/testing/mocks/MockSyncStore.d.ts +14 -14
- package/dist/testing/mocks/MockSyncStore.js +11 -11
- package/dist/testing/mocks/MockWebSocket.d.ts +28 -24
- package/dist/testing/mocks/MockWebSocket.js +22 -21
- package/dist/transactions/TransactionQueue.d.ts +190 -221
- package/dist/transactions/TransactionQueue.js +424 -822
- package/dist/transactions/TransactionStore.d.ts +20 -0
- package/dist/transactions/TransactionStore.js +53 -0
- package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
- package/dist/transactions/UnconfirmedWrites.js +104 -0
- package/dist/transactions/coalesceRules.d.ts +58 -0
- package/dist/transactions/coalesceRules.js +140 -0
- package/dist/transactions/commitPayload.d.ts +130 -0
- package/dist/transactions/commitPayload.js +143 -0
- package/dist/transactions/deltaConfirmation.d.ts +58 -0
- package/dist/transactions/deltaConfirmation.js +215 -0
- package/dist/transactions/optimisticApply.d.ts +49 -0
- package/dist/transactions/optimisticApply.js +65 -0
- package/dist/transactions/replayValidation.d.ts +99 -0
- package/dist/transactions/replayValidation.js +111 -0
- package/dist/types/global.d.ts +46 -41
- package/dist/types/global.js +20 -19
- package/dist/types/index.d.ts +74 -80
- package/dist/types/index.js +22 -27
- package/dist/types/modelData.d.ts +10 -0
- package/dist/types/modelData.js +9 -0
- package/dist/types/participant.d.ts +20 -0
- package/dist/types/participant.js +10 -0
- package/dist/types/streams.d.ts +216 -209
- package/dist/types/streams.js +7 -7
- package/dist/utils/asyncIterator.d.ts +25 -32
- package/dist/utils/asyncIterator.js +25 -32
- package/dist/utils/duration.d.ts +12 -15
- package/dist/utils/duration.js +12 -15
- package/dist/utils/mobxSetup.d.ts +53 -0
- package/dist/utils/{mobx-setup.js → mobxSetup.js} +44 -100
- package/dist/webhooks/events.d.ts +21 -16
- package/dist/webhooks/events.js +10 -8
- package/dist/webhooks/index.d.ts +5 -7
- package/dist/webhooks/index.js +5 -7
- package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
- package/dist/wire/delta.js +114 -0
- package/dist/wire/errorEnvelope.d.ts +35 -27
- package/dist/wire/errorEnvelope.js +38 -32
- package/dist/wire/frames.d.ts +150 -67
- package/dist/wire/frames.js +48 -1
- package/dist/wire/index.d.ts +18 -13
- package/dist/wire/index.js +36 -13
- package/dist/wire/listEnvelope.d.ts +16 -23
- package/dist/wire/listEnvelope.js +7 -6
- package/dist/wire/protocol.d.ts +38 -0
- package/dist/wire/protocol.js +38 -0
- package/dist/wire/protocolVersion.d.ts +60 -0
- package/dist/wire/protocolVersion.js +67 -0
- package/docs/api-keys.md +4 -3
- package/docs/coordination.md +59 -0
- package/docs/examples/existing-python-backend.md +3 -3
- package/docs/identity.md +4 -4
- package/docs/integration-guide.md +1 -1
- package/docs/react.md +1 -1
- package/docs/sessions.md +5 -7
- package/package.json +24 -21
- package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
- package/dist/ai-sdk/coordination-context.d.ts +0 -52
- package/dist/client/index.d.ts +0 -36
- package/dist/client/index.js +0 -33
- package/dist/config/index.d.ts +0 -10
- package/dist/config/index.js +0 -12
- package/dist/core/query-utils.d.ts +0 -34
- package/dist/core/query-utils.js +0 -59
- package/dist/interfaces/headless.d.ts +0 -95
- package/dist/interfaces/headless.js +0 -41
- package/dist/query/index.d.ts +0 -6
- package/dist/query/index.js +0 -5
- package/dist/realtime/index.d.ts +0 -10
- package/dist/realtime/index.js +0 -9
- package/dist/schema/plane.d.ts +0 -23
- package/dist/schema/plane.js +0 -19
- package/dist/schema/sync-delta-row.js +0 -103
- package/dist/schema/sync-delta-wire.js +0 -102
- package/dist/server/next.d.ts +0 -51
- package/dist/server/next.js +0 -47
- package/dist/server/read-config.d.ts +0 -67
- package/dist/server/read-config.js +0 -8
- package/dist/server/storage-mode.d.ts +0 -1
- package/dist/server/storage-mode.js +0 -18
- package/dist/source/connector-protocol.d.ts +0 -159
- package/dist/source/connector-protocol.js +0 -161
- package/dist/sync/OfflineFlush.d.ts +0 -9
- package/dist/sync/OfflineFlush.js +0 -22
- package/dist/sync/OfflineTransactionStore.d.ts +0 -37
- package/dist/sync/OfflineTransactionStore.js +0 -263
- package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
- package/dist/transactions/OptimisticEchoTracker.js +0 -104
- package/dist/transactions/index.d.ts +0 -16
- package/dist/transactions/index.js +0 -7
- package/dist/transactions/mutation-error-handler.d.ts +0 -5
- package/dist/transactions/mutation-error-handler.js +0 -39
- package/dist/utils/mobx-setup.d.ts +0 -42
|
@@ -1,24 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The single mutable holder for the active bearer credential every transport
|
|
3
|
+
* uses.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* through
|
|
5
|
+
* Each transport reads the current token from this object at request or connect
|
|
6
|
+
* time — the HTTP request paths and the WebSocket URL authorizer alike. When the
|
|
7
|
+
* token is refreshed, it is written here once, and every reader observes the new
|
|
8
|
+
* value through its getter rather than being updated one by one.
|
|
8
9
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* offers the token as a `Sec-WebSocket-Protocol` value — `ablo.bearer.<token>` —
|
|
14
|
-
* alongside the real `ablo.sync.v1` protocol the server selects. This keeps the
|
|
15
|
-
* credential out of the query string, which ALB access logs, proxies, and
|
|
16
|
-
* browser history capture. The server reads the token from the subprotocol and
|
|
17
|
-
* echoes back ONLY `ablo.sync.v1`, never the token-bearing value. Shared with
|
|
18
|
-
* the sync-server so client and server can never drift on the wire format.
|
|
19
|
-
*/
|
|
20
|
-
export const WS_BEARER_SUBPROTOCOL_PREFIX = 'ablo.bearer.';
|
|
21
|
-
export const WS_SYNC_SUBPROTOCOL = 'ablo.sync.v1';
|
|
10
|
+
// The WebSocket bearer-subprotocol constants are defined in `../wire/protocol.js`
|
|
11
|
+
// as part of the wire contract shared between client and server. They are
|
|
12
|
+
// re-exported here so this module stays a stable import site for them.
|
|
13
|
+
export { WS_BEARER_SUBPROTOCOL_PREFIX, WS_SYNC_SUBPROTOCOL } from '../wire/protocol.js';
|
|
22
14
|
export function createAuthCredentialSource(initialToken) {
|
|
23
15
|
let authToken = normalizeToken(initialToken);
|
|
24
16
|
return {
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Exchanges an API key for a capability token and the scope it grants.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Consumer never sees this happen. Same shape as Stripe / Anthropic
|
|
11
|
-
* SDKs hide their internal auth-handshake — the apiKey is the only
|
|
12
|
-
* credential the consumer touches.
|
|
4
|
+
* The `Ablo({...})` factory calls this during startup when you provide an
|
|
5
|
+
* `apiKey` but no explicit capability token, organization, or user identity. It
|
|
6
|
+
* sends one `POST /auth/capability` request; the server responds with the
|
|
7
|
+
* granted scope and any user metadata, which the client uses to populate its
|
|
8
|
+
* session state. The API key is the only credential you handle directly — this
|
|
9
|
+
* exchange happens automatically behind it.
|
|
13
10
|
*/
|
|
14
11
|
import { type CapabilityExchangeResponse, type EphemeralKeyResponse, type IdentityResolveResponse } from './schemas.js';
|
|
15
12
|
export type { CapabilityExchangeResponse, EphemeralKeyResponse, IdentityResolveResponse, } from './schemas.js';
|
|
@@ -28,24 +25,27 @@ export interface ExchangeApiKeyRequest {
|
|
|
28
25
|
}
|
|
29
26
|
export declare function exchangeApiKey(options: ExchangeApiKeyRequest): Promise<CapabilityExchangeResponse>;
|
|
30
27
|
export interface MintUserSessionRequest {
|
|
31
|
-
/**
|
|
32
|
-
*
|
|
28
|
+
/** Your secret API key (an `sk_` key). Minting a session is a server-side
|
|
29
|
+
* operation, so it always presents the secret key, never a token derived
|
|
30
|
+
* from it. */
|
|
33
31
|
readonly apiKey: string;
|
|
34
32
|
readonly baseUrl: string;
|
|
35
|
-
/** The end user's
|
|
33
|
+
/** The end user's identifier in your identity provider. It becomes the
|
|
34
|
+
* session's `participantId`. */
|
|
36
35
|
readonly userId: string;
|
|
37
|
-
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
36
|
+
/** The organization to mint the session into, for a platform that manages many
|
|
37
|
+
* organizations. Requires the secret key to carry the `ephemeral:mint-any-org`
|
|
38
|
+
* capability. Omit to mint into the key's own organization. */
|
|
40
39
|
readonly organizationId?: string;
|
|
41
|
-
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* schema from it instead of
|
|
45
|
-
* Requires the
|
|
46
|
-
*
|
|
40
|
+
/** Points this session's schema at a shared project while its data stays scoped
|
|
41
|
+
* to `organizationId`. Use this when each customer has its own organization but
|
|
42
|
+
* they all share one schema: keep a single schema project, and every customer's
|
|
43
|
+
* session resolves its schema from it instead of pushing the schema into each
|
|
44
|
+
* organization separately. Requires the secret key to carry the
|
|
45
|
+
* `ephemeral:mint-any-org` capability. Omit to resolve the schema from the
|
|
46
|
+
* session's own organization. */
|
|
47
47
|
readonly schemaProject?: {
|
|
48
|
-
/** The
|
|
48
|
+
/** The organization that owns the shared schema project. */
|
|
49
49
|
readonly organizationId: string;
|
|
50
50
|
/** The project the schema was pushed under. */
|
|
51
51
|
readonly projectId: string;
|
|
@@ -57,13 +57,13 @@ export interface MintUserSessionRequest {
|
|
|
57
57
|
readonly timeoutMs?: number;
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
60
|
+
* Mints an end-user session key (an `ek_` key) by calling
|
|
61
|
+
* `POST /auth/ephemeral-keys`, using your secret key as authorization. Your
|
|
62
|
+
* backend calls this to issue a session that a browser can present as its bearer
|
|
63
|
+
* credential; the server trusts the resulting key because a secret key minted it.
|
|
64
|
+
*
|
|
65
|
+
* This is a distinct endpoint from `/auth/capability`, which exchanges keys for
|
|
66
|
+
* agents and systems and cannot mint sessions for human users.
|
|
67
67
|
*/
|
|
68
68
|
export declare function mintUserSessionKey(options: MintUserSessionRequest): Promise<EphemeralKeyResponse>;
|
|
69
69
|
export interface ResolveIdentityRequest {
|
|
@@ -73,46 +73,47 @@ export interface ResolveIdentityRequest {
|
|
|
73
73
|
readonly timeoutMs?: number;
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
76
|
+
* Resolves the caller's identity from an authenticated request by calling
|
|
77
|
+
* `GET /auth/identity`. This lets browser and session flows learn who the
|
|
78
|
+
* current user is without requiring the application to pass a user id up front —
|
|
79
|
+
* for example, to key local storage.
|
|
79
80
|
*/
|
|
80
81
|
export declare function resolveIdentity(options: ResolveIdentityRequest): Promise<IdentityResolveResponse>;
|
|
81
82
|
/**
|
|
82
|
-
*
|
|
83
|
+
* Keeps a capability token fresh so a long-lived client never disconnects when
|
|
84
|
+
* its token expires.
|
|
83
85
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
86
|
+
* A capability token has a shorter lifetime — one hour by default — than a
|
|
87
|
+
* typical browser session. Without a refresh, the WebSocket is force-closed at
|
|
88
|
+
* expiry (close code 1008) or the next reconnect fails with a 401, and either way
|
|
89
|
+
* the user sees a mid-session disconnect. The scheduler prevents that by
|
|
90
|
+
* re-minting the token ahead of time.
|
|
89
91
|
*
|
|
90
|
-
*
|
|
91
|
-
* one refresh path:
|
|
92
|
+
* Three triggers share one refresh path:
|
|
92
93
|
*
|
|
93
|
-
* 1. Proactive —
|
|
94
|
-
* 2. Visibility —
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* 3. Reactive — caller invokes
|
|
98
|
-
* failure
|
|
94
|
+
* 1. Proactive — a timer set for `expiresAtMs - bufferMs - now`.
|
|
95
|
+
* 2. Visibility — when a hidden tab becomes visible and the token is already
|
|
96
|
+
* within the buffer window, refresh immediately. This covers a
|
|
97
|
+
* background tab whose timers were throttled while it was idle.
|
|
98
|
+
* 3. Reactive — the caller invokes {@link RefreshScheduler.refreshNow} after
|
|
99
|
+
* observing an auth failure, such as a WebSocket close 1008 or
|
|
100
|
+
* 4001.
|
|
99
101
|
*
|
|
100
|
-
* All three
|
|
101
|
-
*
|
|
102
|
-
*
|
|
102
|
+
* All three await the same in-flight promise, so concurrent triggers mint the
|
|
103
|
+
* token only once. Each successful refresh records the new expiry and reschedules
|
|
104
|
+
* the proactive timer.
|
|
103
105
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* scaling sensibly for shorter TTLs.
|
|
106
|
+
* The refresh margin is `max(60s, ttl/10)` — six minutes for a one-hour token,
|
|
107
|
+
* and it scales down for shorter lifetimes.
|
|
107
108
|
*/
|
|
108
109
|
export interface RefreshSchedulerOptions {
|
|
109
110
|
/** Initial absolute expiry, ms since epoch (server-supplied). */
|
|
110
111
|
readonly initialExpiresAtMs: number;
|
|
111
112
|
/**
|
|
112
|
-
* Performs the
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
113
|
+
* Performs the token exchange and returns the new expiry. Errors propagate to
|
|
114
|
+
* `onError`; the scheduler stays alive and retries on its next trigger. It does
|
|
115
|
+
* not back off between retries, since the common failure here is a revoked API
|
|
116
|
+
* key, for which retrying would not help.
|
|
116
117
|
*/
|
|
117
118
|
readonly refresh: () => Promise<{
|
|
118
119
|
expiresAtMs: number;
|
|
@@ -133,7 +134,7 @@ export interface RefreshSchedulerOptions {
|
|
|
133
134
|
* If true, install a `visibilitychange` listener on `document` that
|
|
134
135
|
* triggers a refresh when the tab becomes visible and the token is
|
|
135
136
|
* within the buffer window. No-op if `document` is undefined (Node).
|
|
136
|
-
* Default: true in browser
|
|
137
|
+
* Default: true in browser environments.
|
|
137
138
|
*/
|
|
138
139
|
readonly attachVisibilityListener?: boolean;
|
|
139
140
|
/** Time source. Override in tests; defaults to `Date.now`. */
|
package/dist/auth/index.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Exchanges an API key for a capability token and the scope it grants.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Consumer never sees this happen. Same shape as Stripe / Anthropic
|
|
11
|
-
* SDKs hide their internal auth-handshake — the apiKey is the only
|
|
12
|
-
* credential the consumer touches.
|
|
4
|
+
* The `Ablo({...})` factory calls this during startup when you provide an
|
|
5
|
+
* `apiKey` but no explicit capability token, organization, or user identity. It
|
|
6
|
+
* sends one `POST /auth/capability` request; the server responds with the
|
|
7
|
+
* granted scope and any user metadata, which the client uses to populate its
|
|
8
|
+
* session state. The API key is the only credential you handle directly — this
|
|
9
|
+
* exchange happens automatically behind it.
|
|
13
10
|
*/
|
|
14
11
|
import { parseCapabilityExchangeResponse, parseEphemeralKeyResponse, parseIdentityResolveResponse, } from './schemas.js';
|
|
15
12
|
import { AbloAuthenticationError, hasWireCode, translateHttpError } from '../errors.js';
|
|
@@ -26,7 +23,7 @@ export async function exchangeApiKey(options) {
|
|
|
26
23
|
const url = `${options.baseUrl.replace(/\/+$/, '')}/auth/capability`;
|
|
27
24
|
const timeoutMs = options.timeoutMs ?? 10_000;
|
|
28
25
|
const controller = new AbortController();
|
|
29
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
26
|
+
const timer = setTimeout(() => { controller.abort(); }, timeoutMs);
|
|
30
27
|
let response;
|
|
31
28
|
try {
|
|
32
29
|
response = await fetcher(url, {
|
|
@@ -62,12 +59,10 @@ export async function exchangeApiKey(options) {
|
|
|
62
59
|
catch {
|
|
63
60
|
// ignore — server returned non-JSON error
|
|
64
61
|
}
|
|
65
|
-
// Route through the
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
// every failure to a generic code with an empty message). Fall back to
|
|
70
|
-
// `exchange_failed` only when the body carried no recognizable code.
|
|
62
|
+
// Route the error through the wire-error translator so the server's envelope
|
|
63
|
+
// (`code`, `message`, `doc_url`) is preserved and mapped to the matching
|
|
64
|
+
// AbloError subclass. Fall back to `exchange_failed` only when the body
|
|
65
|
+
// carried no recognizable error code.
|
|
71
66
|
const requestId = response.headers.get('x-request-id') ?? undefined;
|
|
72
67
|
throw hasWireCode(body)
|
|
73
68
|
? translateHttpError(response.status, body, requestId)
|
|
@@ -76,13 +71,13 @@ export async function exchangeApiKey(options) {
|
|
|
76
71
|
return parseCapabilityExchangeResponse(await response.json());
|
|
77
72
|
}
|
|
78
73
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
74
|
+
* Mints an end-user session key (an `ek_` key) by calling
|
|
75
|
+
* `POST /auth/ephemeral-keys`, using your secret key as authorization. Your
|
|
76
|
+
* backend calls this to issue a session that a browser can present as its bearer
|
|
77
|
+
* credential; the server trusts the resulting key because a secret key minted it.
|
|
78
|
+
*
|
|
79
|
+
* This is a distinct endpoint from `/auth/capability`, which exchanges keys for
|
|
80
|
+
* agents and systems and cannot mint sessions for human users.
|
|
86
81
|
*/
|
|
87
82
|
export async function mintUserSessionKey(options) {
|
|
88
83
|
if (!options.apiKey) {
|
|
@@ -96,7 +91,7 @@ export async function mintUserSessionKey(options) {
|
|
|
96
91
|
const url = `${options.baseUrl.replace(/\/+$/, '')}/auth/ephemeral-keys`;
|
|
97
92
|
const timeoutMs = options.timeoutMs ?? 10_000;
|
|
98
93
|
const controller = new AbortController();
|
|
99
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
94
|
+
const timer = setTimeout(() => { controller.abort(); }, timeoutMs);
|
|
100
95
|
let response;
|
|
101
96
|
try {
|
|
102
97
|
response = await fetcher(url, {
|
|
@@ -108,8 +103,8 @@ export async function mintUserSessionKey(options) {
|
|
|
108
103
|
body: JSON.stringify({
|
|
109
104
|
user: { id: options.userId },
|
|
110
105
|
...(options.organizationId ? { organizationId: options.organizationId } : {}),
|
|
111
|
-
//
|
|
112
|
-
//
|
|
106
|
+
// The public option is project-centric; map it to the flat wire keys the
|
|
107
|
+
// endpoint expects.
|
|
113
108
|
...(options.schemaProject
|
|
114
109
|
? {
|
|
115
110
|
schemaProjectId: options.schemaProject.projectId,
|
|
@@ -145,9 +140,10 @@ export async function mintUserSessionKey(options) {
|
|
|
145
140
|
return parseEphemeralKeyResponse(await response.json());
|
|
146
141
|
}
|
|
147
142
|
/**
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
143
|
+
* Resolves the caller's identity from an authenticated request by calling
|
|
144
|
+
* `GET /auth/identity`. This lets browser and session flows learn who the
|
|
145
|
+
* current user is without requiring the application to pass a user id up front —
|
|
146
|
+
* for example, to key local storage.
|
|
151
147
|
*/
|
|
152
148
|
export async function resolveIdentity(options) {
|
|
153
149
|
if (!options.baseUrl) {
|
|
@@ -159,7 +155,7 @@ export async function resolveIdentity(options) {
|
|
|
159
155
|
const url = `${options.baseUrl.replace(/\/+$/, '')}/auth/identity`;
|
|
160
156
|
const timeoutMs = options.timeoutMs ?? 10_000;
|
|
161
157
|
const controller = new AbortController();
|
|
162
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
158
|
+
const timer = setTimeout(() => { controller.abort(); }, timeoutMs);
|
|
163
159
|
let response;
|
|
164
160
|
try {
|
|
165
161
|
const headers = { Accept: 'application/json' };
|
|
@@ -186,12 +182,10 @@ export async function resolveIdentity(options) {
|
|
|
186
182
|
catch {
|
|
187
183
|
// ignore non-JSON auth errors
|
|
188
184
|
}
|
|
189
|
-
//
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
//
|
|
193
|
-
// empty reason because the old parser looked for `error`/`reason` keys the
|
|
194
|
-
// server doesn't emit.
|
|
185
|
+
// Translate the error envelope the same way `exchangeApiKey` does, so the
|
|
186
|
+
// server's precise auth diagnosis (for example `jwt_issuer_untrusted` with
|
|
187
|
+
// its full message) reaches the caller instead of collapsing every 401 to a
|
|
188
|
+
// generic `identity_resolve_failed`.
|
|
195
189
|
const requestId = response.headers.get('x-request-id') ?? undefined;
|
|
196
190
|
throw hasWireCode(body)
|
|
197
191
|
? translateHttpError(response.status, body, requestId)
|
|
@@ -209,9 +203,9 @@ export function createRefreshScheduler(options) {
|
|
|
209
203
|
let timer = null;
|
|
210
204
|
let inFlight = null;
|
|
211
205
|
let disposed = false;
|
|
212
|
-
//
|
|
213
|
-
//
|
|
214
|
-
//
|
|
206
|
+
// Attach the visibility listener only in a browser-like environment. A
|
|
207
|
+
// non-browser runtime has no `document`, so the default behaves correctly
|
|
208
|
+
// without an explicit opt-out.
|
|
215
209
|
const wantsVisibility = options.attachVisibilityListener ?? true;
|
|
216
210
|
const hasDocument = typeof document !== 'undefined';
|
|
217
211
|
const visibilityActive = wantsVisibility && hasDocument;
|
package/dist/auth/schemas.d.ts
CHANGED
|
@@ -32,10 +32,11 @@ export declare const IdentityResolveResponseSchema: z.ZodObject<{
|
|
|
32
32
|
}, z.core.$loose>;
|
|
33
33
|
export type IdentityResolveResponse = z.infer<typeof IdentityResolveResponseSchema>;
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* the key
|
|
38
|
-
* token
|
|
35
|
+
* The response shape of `POST /auth/ephemeral-keys`, the endpoint that mints an
|
|
36
|
+
* end-user session key (an `ek_` key). The shape is flat, with no nested scope
|
|
37
|
+
* block: the server records the scope on the key itself and re-derives it on
|
|
38
|
+
* every request, so the client only needs the token and identity fields to hand
|
|
39
|
+
* to the browser.
|
|
39
40
|
*/
|
|
40
41
|
export declare const EphemeralKeyResponseSchema: z.ZodObject<{
|
|
41
42
|
object: z.ZodOptional<z.ZodLiteral<"ephemeral_key">>;
|
package/dist/auth/schemas.js
CHANGED
|
@@ -30,10 +30,11 @@ export const IdentityResolveResponseSchema = z
|
|
|
30
30
|
})
|
|
31
31
|
.passthrough();
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* the key
|
|
36
|
-
* token
|
|
33
|
+
* The response shape of `POST /auth/ephemeral-keys`, the endpoint that mints an
|
|
34
|
+
* end-user session key (an `ek_` key). The shape is flat, with no nested scope
|
|
35
|
+
* block: the server records the scope on the key itself and re-derives it on
|
|
36
|
+
* every request, so the client only needs the token and identity fields to hand
|
|
37
|
+
* to the browser.
|
|
37
38
|
*/
|
|
38
39
|
export const EphemeralKeyResponseSchema = z
|
|
39
40
|
.object({
|
package/dist/batching/index.d.ts
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* A small, dependency-free primitive that coalesces work into batches.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* burst
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
4
|
+
* It accumulates items enqueued close together — the common case being a
|
|
5
|
+
* synchronous burst such as `Promise.all([ a(), b(), c() ])` within one
|
|
6
|
+
* event-loop tick — and dispatches them as a single batch rather than one call
|
|
7
|
+
* each. It is a pure state machine: it stages items on the microtask queue,
|
|
8
|
+
* flushes on size, cost, or time triggers, and applies in-flight backpressure,
|
|
9
|
+
* with no dependency on any data model, storage layer, or network. You supply
|
|
10
|
+
* the dispatch function through {@link BatchSchedulerHooks}.
|
|
11
11
|
*
|
|
12
12
|
* Guarantees:
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
15
|
-
*
|
|
16
|
-
* - items dispatch in enqueue order
|
|
17
|
-
* before a batch is cut
|
|
18
|
-
*
|
|
19
|
-
* The slides-sdk wraps this to coalesce `commits.create` calls; the stateful
|
|
20
|
-
* `TransactionQueue` MAY adopt it later (it would supply `compare` for FK
|
|
21
|
-
* ordering and keep its merge/confirm/retry logic in its own hooks).
|
|
13
|
+
* - each batch is a single `dispatchBatch(items)` call, applied atomically.
|
|
14
|
+
* - if a dispatch fails, every enqueued promise in that batch rejects with
|
|
15
|
+
* the same error.
|
|
16
|
+
* - items dispatch in enqueue order, optionally reordered by `compare` just
|
|
17
|
+
* before a batch is cut; batches run first-in, first-out under a
|
|
18
|
+
* `maxInFlight` cap.
|
|
22
19
|
*/
|
|
23
20
|
export interface BatchSchedulerOptions<T> {
|
|
24
21
|
/** Master switch. When false, every `enqueue` dispatches solo immediately. Default true. */
|
|
@@ -38,16 +35,17 @@ export interface BatchSchedulerHooks<T, R> {
|
|
|
38
35
|
/** The single dispatch for one batch. One call → atomic at this layer. */
|
|
39
36
|
dispatchBatch(items: T[]): Promise<R>;
|
|
40
37
|
/**
|
|
41
|
-
* Optional ordering applied to the staged items
|
|
42
|
-
*
|
|
43
|
-
*
|
|
38
|
+
* Optional ordering applied to the staged items just before a batch is cut —
|
|
39
|
+
* for example, to send parent rows ahead of the rows that reference them. Omit
|
|
40
|
+
* for first-in, first-out order. This changes only the order of items within
|
|
41
|
+
* the dispatched array, not which items share a batch.
|
|
44
42
|
*/
|
|
45
43
|
compare?(a: T, b: T): number;
|
|
46
44
|
}
|
|
47
45
|
export interface BatchScheduler<T, R> {
|
|
48
46
|
/** Stage one item; resolves with its batch's dispatch result, or rejects with the batch error. */
|
|
49
47
|
enqueue(item: T): Promise<R>;
|
|
50
|
-
/** Stage an item that must dispatch in its
|
|
48
|
+
/** Stage an item that must dispatch in a batch of its own — for example, one carrying an explicit idempotency key. */
|
|
51
49
|
enqueueSolo(item: T): Promise<R>;
|
|
52
50
|
/** Force-flush the pending batch and resolve once everything in flight has settled. */
|
|
53
51
|
flush(): Promise<void>;
|
package/dist/batching/index.js
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* A small, dependency-free primitive that coalesces work into batches.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* burst
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
4
|
+
* It accumulates items enqueued close together — the common case being a
|
|
5
|
+
* synchronous burst such as `Promise.all([ a(), b(), c() ])` within one
|
|
6
|
+
* event-loop tick — and dispatches them as a single batch rather than one call
|
|
7
|
+
* each. It is a pure state machine: it stages items on the microtask queue,
|
|
8
|
+
* flushes on size, cost, or time triggers, and applies in-flight backpressure,
|
|
9
|
+
* with no dependency on any data model, storage layer, or network. You supply
|
|
10
|
+
* the dispatch function through {@link BatchSchedulerHooks}.
|
|
11
11
|
*
|
|
12
12
|
* Guarantees:
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
15
|
-
*
|
|
16
|
-
* - items dispatch in enqueue order
|
|
17
|
-
* before a batch is cut
|
|
18
|
-
*
|
|
19
|
-
* The slides-sdk wraps this to coalesce `commits.create` calls; the stateful
|
|
20
|
-
* `TransactionQueue` MAY adopt it later (it would supply `compare` for FK
|
|
21
|
-
* ordering and keep its merge/confirm/retry logic in its own hooks).
|
|
13
|
+
* - each batch is a single `dispatchBatch(items)` call, applied atomically.
|
|
14
|
+
* - if a dispatch fails, every enqueued promise in that batch rejects with
|
|
15
|
+
* the same error.
|
|
16
|
+
* - items dispatch in enqueue order, optionally reordered by `compare` just
|
|
17
|
+
* before a batch is cut; batches run first-in, first-out under a
|
|
18
|
+
* `maxInFlight` cap.
|
|
22
19
|
*/
|
|
23
20
|
export function createBatchScheduler(hooks, options) {
|
|
24
21
|
const enabled = options?.enabled ?? true;
|