@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
package/dist/source/pushQueue.js
CHANGED
|
@@ -1,32 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* A durable retry queue for delivering source events to the server.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* drops, or
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* When your application changes a row, it can push the resulting event to
|
|
5
|
+
* the server, which acknowledges delivery synchronously. If your process
|
|
6
|
+
* crashes mid-call, the network drops, or the server returns a 5xx, that
|
|
7
|
+
* event would be lost without a safety net. This queue is the safety net:
|
|
8
|
+
* it persists each event first, then delivers it from a background worker
|
|
9
|
+
* with automatic retries. (Polling the change feed is the slower fallback
|
|
10
|
+
* for anything the queue never manages to deliver.)
|
|
9
11
|
*
|
|
10
|
-
*
|
|
11
|
-
* queue+worker pattern matching Stripe / Svix semantics:
|
|
12
|
+
* The queue follows a familiar enqueue-and-worker shape:
|
|
12
13
|
*
|
|
13
|
-
* - `enqueue(events)` returns
|
|
14
|
-
* - background worker delivers and retries
|
|
15
|
-
* Webhooks schedule (0, 5s, 5m, 30m, 2h, 5h, 10h, 14h,
|
|
16
|
-
* —
|
|
17
|
-
* -
|
|
14
|
+
* - `enqueue(events)` returns as soon as the events are persisted.
|
|
15
|
+
* - A background worker delivers them and retries on failure, following
|
|
16
|
+
* the Standard Webhooks schedule (0, 5s, 5m, 30m, 2h, 5h, 10h, 14h,
|
|
17
|
+
* 20h, 24h — roughly three days in total).
|
|
18
|
+
* - Items that exhaust every retry move to a dead-letter queue you can
|
|
19
|
+
* monitor.
|
|
18
20
|
*
|
|
19
|
-
* Persistence is pluggable
|
|
20
|
-
*
|
|
21
|
-
* outbox table for production.
|
|
21
|
+
* Persistence is pluggable through {@link PushQueueStorage}. Use
|
|
22
|
+
* {@link InMemoryPushQueueStorage} for a single process, or implement that
|
|
23
|
+
* interface against your own outbox table for production durability.
|
|
22
24
|
*/
|
|
23
25
|
import { ABLO_SOURCE_HEADERS, signAbloSourceRequest } from './signing.js';
|
|
24
26
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
27
|
+
* The default retry schedule, taken from the Standard Webhooks
|
|
28
|
+
* specification. The index is the attempt number and the value is the delay
|
|
29
|
+
* in milliseconds after the previous attempt failed. Once an item runs off
|
|
30
|
+
* the end of this array, it moves to the dead-letter queue.
|
|
28
31
|
*
|
|
29
|
-
*
|
|
32
|
+
* See https://www.standardwebhooks.com/.
|
|
30
33
|
*/
|
|
31
34
|
export const STANDARD_WEBHOOKS_RETRY_SCHEDULE = [
|
|
32
35
|
0, // immediate
|
|
@@ -40,6 +43,7 @@ export const STANDARD_WEBHOOKS_RETRY_SCHEDULE = [
|
|
|
40
43
|
20 * 60 * 60_000, // 20h
|
|
41
44
|
24 * 60 * 60_000, // 24h
|
|
42
45
|
];
|
|
46
|
+
/** Create a {@link PushQueue} from the given {@link PushQueueOptions}. */
|
|
43
47
|
export function createPushQueue(options) {
|
|
44
48
|
const tickIntervalMs = options.tickIntervalMs ?? 1000;
|
|
45
49
|
const batchSize = options.batchSize ?? 50;
|
|
@@ -133,8 +137,8 @@ export function createPushQueue(options) {
|
|
|
133
137
|
}
|
|
134
138
|
async function reschedule(item, error) {
|
|
135
139
|
const nextAttempt = item.attempts + 1;
|
|
136
|
-
//
|
|
137
|
-
//
|
|
140
|
+
// Past the end of the backoff schedule: no attempts left, so dead-letter
|
|
141
|
+
// the item.
|
|
138
142
|
const backoff = schedule[nextAttempt];
|
|
139
143
|
if (backoff === undefined) {
|
|
140
144
|
await options.storage.markDlq(item.id, error);
|
|
@@ -145,13 +149,13 @@ export function createPushQueue(options) {
|
|
|
145
149
|
await options.storage.reschedule(item.id, now() + delay, error);
|
|
146
150
|
}
|
|
147
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* A {@link PushQueueStorage} that keeps items in memory. It is not durable —
|
|
154
|
+
* items are lost when the process restarts — so it suits development and
|
|
155
|
+
* low-volume use. For production, implement {@link PushQueueStorage} against
|
|
156
|
+
* your own table.
|
|
157
|
+
*/
|
|
148
158
|
export class InMemoryPushQueueStorage {
|
|
149
|
-
/**
|
|
150
|
-
* Real implementation, not a mock. Suitable for low-volume single-
|
|
151
|
-
* process customers; not durable across restarts (in-flight items
|
|
152
|
-
* are lost). Production customers should swap in a SQL-backed
|
|
153
|
-
* storage that writes to their existing outbox table.
|
|
154
|
-
*/
|
|
155
159
|
items = new Map();
|
|
156
160
|
nextId = 0;
|
|
157
161
|
now;
|
package/dist/source/signing.d.ts
CHANGED
|
@@ -1,42 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Signs and verifies source requests using the Standard Webhooks scheme.
|
|
3
3
|
*
|
|
4
|
-
* Ablo
|
|
5
|
-
* key
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* Every request Ablo sends to a data source is signed with that source's API
|
|
5
|
+
* key, and the receiving endpoint verifies the signature before any handler
|
|
6
|
+
* runs. This module provides both halves: {@link signAbloSourceRequest} for
|
|
7
|
+
* the sender and {@link verifyAbloSourceRequest} for the receiver. Because the
|
|
8
|
+
* signature format follows the Standard Webhooks specification, you can verify
|
|
9
|
+
* it with any compatible library instead of these functions if you prefer.
|
|
9
10
|
*/
|
|
11
|
+
/** Inputs to {@link signAbloSourceRequest}. */
|
|
10
12
|
export interface SourceSignatureOptions {
|
|
13
|
+
/** The API key to sign with; the receiver verifies against the same key. */
|
|
11
14
|
readonly apiKey: string;
|
|
15
|
+
/** The exact request body being signed. */
|
|
12
16
|
readonly body: string;
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
18
|
+
* The unique message id, sent as the `webhook-id` header. It is folded into
|
|
19
|
+
* the signature to defend against replay, and receivers may deduplicate on
|
|
20
|
+
* it. Retries of the same request must reuse the same id.
|
|
17
21
|
*/
|
|
18
22
|
readonly messageId: string;
|
|
19
|
-
/**
|
|
20
|
-
* Unix timestamp in seconds. Defaults to the current time.
|
|
21
|
-
*/
|
|
23
|
+
/** The signing time as a Unix timestamp in seconds. Defaults to the current time. */
|
|
22
24
|
readonly timestamp?: number;
|
|
23
25
|
}
|
|
26
|
+
/** Inputs to {@link verifyAbloSourceRequest}. */
|
|
24
27
|
export interface SourceSignatureVerificationOptions {
|
|
28
|
+
/** The incoming request, whose headers carry the signature to check. */
|
|
25
29
|
readonly request: Request;
|
|
30
|
+
/** The request body, which must match what was signed. */
|
|
26
31
|
readonly body: string;
|
|
32
|
+
/** The API key to verify against. */
|
|
27
33
|
readonly apiKey: string;
|
|
34
|
+
/**
|
|
35
|
+
* How far the request's timestamp may differ from the current clock, in
|
|
36
|
+
* milliseconds, before it is rejected as expired. Defaults to five minutes.
|
|
37
|
+
*/
|
|
28
38
|
readonly toleranceMs?: number;
|
|
29
39
|
}
|
|
40
|
+
/** What {@link verifyAbloSourceRequest} returns once a signature checks out. */
|
|
30
41
|
export interface SourceSignatureVerificationResult {
|
|
42
|
+
/** The verified `webhook-id` of the request. */
|
|
31
43
|
readonly messageId: string;
|
|
44
|
+
/** The time the request was signed, as a Unix timestamp in seconds. */
|
|
32
45
|
readonly signedAt: number;
|
|
33
46
|
}
|
|
34
47
|
/**
|
|
35
|
-
* HTTP
|
|
36
|
-
* Standard Webhooks specification (https://www.standardwebhooks.com/)
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* specific verifier required.
|
|
48
|
+
* The HTTP header names carried on a signed source request. They follow the
|
|
49
|
+
* Standard Webhooks specification (https://www.standardwebhooks.com/), so you
|
|
50
|
+
* can verify the signature with any compatible library rather than
|
|
51
|
+
* {@link verifyAbloSourceRequest} if you prefer.
|
|
40
52
|
*/
|
|
41
53
|
export declare const ABLO_SOURCE_HEADERS: {
|
|
42
54
|
readonly signature: "webhook-signature";
|
|
@@ -44,15 +56,32 @@ export declare const ABLO_SOURCE_HEADERS: {
|
|
|
44
56
|
readonly id: "webhook-id";
|
|
45
57
|
readonly idempotencyKey: "Idempotency-Key";
|
|
46
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* Thrown when a source request fails signature verification. The
|
|
61
|
+
* {@link SourceSignatureError.code} names the specific reason — a missing
|
|
62
|
+
* header, a malformed or expired timestamp, or a signature that does not
|
|
63
|
+
* match.
|
|
64
|
+
*/
|
|
47
65
|
export declare class SourceSignatureError extends Error {
|
|
48
66
|
readonly code: 'source_signature_missing' | 'source_id_missing' | 'source_timestamp_missing' | 'source_timestamp_invalid' | 'source_timestamp_expired' | 'source_signature_invalid' | 'source_forbidden';
|
|
49
67
|
constructor(code: SourceSignatureError['code'], message: string);
|
|
50
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Sign a source request and return the headers to send with it. The signature
|
|
71
|
+
* covers the message id, the timestamp, and the body, so any change to those
|
|
72
|
+
* invalidates it. The receiver checks it with {@link verifyAbloSourceRequest}.
|
|
73
|
+
*/
|
|
51
74
|
export declare function signAbloSourceRequest(options: SourceSignatureOptions): Promise<{
|
|
52
75
|
readonly headers: Record<string, string>;
|
|
53
76
|
readonly signedAt: number;
|
|
54
77
|
readonly signature: string;
|
|
55
78
|
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Verify a signed source request, throwing {@link SourceSignatureError} when
|
|
81
|
+
* the message id, timestamp, or signature is missing, malformed, or outside
|
|
82
|
+
* the allowed clock-skew window. On success it returns the request's message
|
|
83
|
+
* id and signing time. This is the counterpart to {@link signAbloSourceRequest}.
|
|
84
|
+
*/
|
|
56
85
|
export declare function verifyAbloSourceRequest(options: SourceSignatureVerificationOptions): Promise<SourceSignatureVerificationResult>;
|
|
57
86
|
export type DataSourceSignatureOptions = SourceSignatureOptions;
|
|
58
87
|
export type DataSourceSignatureVerificationOptions = SourceSignatureVerificationOptions;
|
package/dist/source/signing.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Signs and verifies source requests using the Standard Webhooks scheme.
|
|
3
3
|
*
|
|
4
|
-
* Ablo
|
|
5
|
-
* key
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* Every request Ablo sends to a data source is signed with that source's API
|
|
5
|
+
* key, and the receiving endpoint verifies the signature before any handler
|
|
6
|
+
* runs. This module provides both halves: {@link signAbloSourceRequest} for
|
|
7
|
+
* the sender and {@link verifyAbloSourceRequest} for the receiver. Because the
|
|
8
|
+
* signature format follows the Standard Webhooks specification, you can verify
|
|
9
|
+
* it with any compatible library instead of these functions if you prefer.
|
|
9
10
|
*/
|
|
10
11
|
/**
|
|
11
|
-
* HTTP
|
|
12
|
-
* Standard Webhooks specification (https://www.standardwebhooks.com/)
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* specific verifier required.
|
|
12
|
+
* The HTTP header names carried on a signed source request. They follow the
|
|
13
|
+
* Standard Webhooks specification (https://www.standardwebhooks.com/), so you
|
|
14
|
+
* can verify the signature with any compatible library rather than
|
|
15
|
+
* {@link verifyAbloSourceRequest} if you prefer.
|
|
16
16
|
*/
|
|
17
17
|
export const ABLO_SOURCE_HEADERS = {
|
|
18
18
|
signature: 'webhook-signature',
|
|
@@ -20,6 +20,12 @@ export const ABLO_SOURCE_HEADERS = {
|
|
|
20
20
|
id: 'webhook-id',
|
|
21
21
|
idempotencyKey: 'Idempotency-Key',
|
|
22
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* Thrown when a source request fails signature verification. The
|
|
25
|
+
* {@link SourceSignatureError.code} names the specific reason — a missing
|
|
26
|
+
* header, a malformed or expired timestamp, or a signature that does not
|
|
27
|
+
* match.
|
|
28
|
+
*/
|
|
23
29
|
export class SourceSignatureError extends Error {
|
|
24
30
|
code;
|
|
25
31
|
constructor(code, message) {
|
|
@@ -94,6 +100,11 @@ function timingSafeEqual(expected, actual) {
|
|
|
94
100
|
}
|
|
95
101
|
return diff === 0;
|
|
96
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Sign a source request and return the headers to send with it. The signature
|
|
105
|
+
* covers the message id, the timestamp, and the body, so any change to those
|
|
106
|
+
* invalidates it. The receiver checks it with {@link verifyAbloSourceRequest}.
|
|
107
|
+
*/
|
|
97
108
|
export async function signAbloSourceRequest(options) {
|
|
98
109
|
const signedAt = options.timestamp ?? Math.floor(Date.now() / 1000);
|
|
99
110
|
// Standard Webhooks signing input: `${msg_id}.${timestamp}.${payload}`
|
|
@@ -108,6 +119,12 @@ export async function signAbloSourceRequest(options) {
|
|
|
108
119
|
},
|
|
109
120
|
};
|
|
110
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Verify a signed source request, throwing {@link SourceSignatureError} when
|
|
124
|
+
* the message id, timestamp, or signature is missing, malformed, or outside
|
|
125
|
+
* the allowed clock-skew window. On success it returns the request's message
|
|
126
|
+
* id and signing time. This is the counterpart to {@link signAbloSourceRequest}.
|
|
127
|
+
*/
|
|
111
128
|
export async function verifyAbloSourceRequest(options) {
|
|
112
129
|
const messageId = getHeader(options.request, ABLO_SOURCE_HEADERS.id);
|
|
113
130
|
if (!messageId) {
|