@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
package/dist/source/index.js
CHANGED
|
@@ -1,429 +1,25 @@
|
|
|
1
|
-
import { AbloValidationError } from '../errors.js';
|
|
2
|
-
import { changeSetSchema } from './contract.js';
|
|
3
1
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* The entry point for the Data Source API, re-exporting the pieces you need from
|
|
3
|
+
* their individual modules:
|
|
6
4
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const entityId = options.entityId ?? options.operation.id;
|
|
13
|
-
if (typeof entityId !== 'string' || entityId.length === 0) {
|
|
14
|
-
throw new AbloValidationError('sourceEventForOperation requires operation.id or an explicit entityId', { code: 'source_event_invalid' });
|
|
15
|
-
}
|
|
16
|
-
const occurredAt = normalizeEventOccurredAt(options.occurredAt);
|
|
17
|
-
return {
|
|
18
|
-
id: options.eventId,
|
|
19
|
-
model: options.operation.model,
|
|
20
|
-
entityId,
|
|
21
|
-
type: options.operation.type,
|
|
22
|
-
...(options.data !== undefined ? { data: options.data } : {}),
|
|
23
|
-
...(options.organizationId ? { organizationId: options.organizationId } : {}),
|
|
24
|
-
...(options.clientTxId ? { clientTxId: options.clientTxId } : {}),
|
|
25
|
-
...(occurredAt !== undefined ? { occurredAt } : {}),
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
function normalizeEventOccurredAt(value) {
|
|
29
|
-
if (value === undefined)
|
|
30
|
-
return undefined;
|
|
31
|
-
const timestamp = value instanceof Date ? value.getTime() : value;
|
|
32
|
-
return Number.isFinite(timestamp) ? timestamp : undefined;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* HTTP headers used on signed source requests. Conforms to the
|
|
36
|
-
* Standard Webhooks specification (https://www.standardwebhooks.com/)
|
|
37
|
-
* so customer code can verify our signatures with any of the official
|
|
38
|
-
* libraries (svix, standardwebhooks, hookdeck, etc.) — no Ablo-
|
|
39
|
-
* specific verifier required.
|
|
40
|
-
*/
|
|
41
|
-
export const ABLO_SOURCE_HEADERS = {
|
|
42
|
-
signature: 'webhook-signature',
|
|
43
|
-
timestamp: 'webhook-timestamp',
|
|
44
|
-
id: 'webhook-id',
|
|
45
|
-
idempotencyKey: 'Idempotency-Key',
|
|
46
|
-
};
|
|
47
|
-
export class SourceSignatureError extends Error {
|
|
48
|
-
code;
|
|
49
|
-
constructor(code, message) {
|
|
50
|
-
super(message);
|
|
51
|
-
this.name = 'SourceSignatureError';
|
|
52
|
-
this.code = code;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
const DEFAULT_SIGNATURE_TOLERANCE_MS = 5 * 60 * 1000;
|
|
56
|
-
function json(data, status = 200) {
|
|
57
|
-
return new Response(JSON.stringify(data), {
|
|
58
|
-
status,
|
|
59
|
-
headers: { 'Content-Type': 'application/json' },
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Serve a request from an ORM `adapter`. Routes the four operations to the adapter
|
|
64
|
-
* interface (`read`/`commit`/`events`) and shapes the wire response. The adapter is the
|
|
65
|
-
* single point of dispatch — no per-model branching here.
|
|
66
|
-
*/
|
|
67
|
-
async function handleViaAdapter(adapter, body, scope) {
|
|
68
|
-
if (body.type === 'load') {
|
|
69
|
-
const rows = await adapter.read({
|
|
70
|
-
kind: 'load',
|
|
71
|
-
model: body.model,
|
|
72
|
-
id: body.id,
|
|
73
|
-
...(scope ? { scope } : {}),
|
|
74
|
-
});
|
|
75
|
-
return json({ row: rows[0] ?? null });
|
|
76
|
-
}
|
|
77
|
-
if (body.type === 'list') {
|
|
78
|
-
const rows = await adapter.read({
|
|
79
|
-
kind: 'list',
|
|
80
|
-
model: body.model,
|
|
81
|
-
...(body.query ? { query: body.query } : {}),
|
|
82
|
-
...(scope ? { scope } : {}),
|
|
83
|
-
});
|
|
84
|
-
return json({ rows });
|
|
85
|
-
}
|
|
86
|
-
if (body.type === 'commit') {
|
|
87
|
-
if (!body.clientTxId) {
|
|
88
|
-
return json({ error: 'source_commit_requires_client_tx_id', message: 'commit requires a clientTxId for idempotency' }, 400);
|
|
89
|
-
}
|
|
90
|
-
const parsed = changeSetSchema.safeParse({
|
|
91
|
-
operations: body.operations,
|
|
92
|
-
clientTxId: body.clientTxId,
|
|
93
|
-
});
|
|
94
|
-
if (!parsed.success) {
|
|
95
|
-
return json({ error: 'source_commit_invalid', message: parsed.error.message }, 400);
|
|
96
|
-
}
|
|
97
|
-
const result = await adapter.commit(parsed.data);
|
|
98
|
-
return json({ rows: result.rows });
|
|
99
|
-
}
|
|
100
|
-
if (body.type === 'events') {
|
|
101
|
-
const page = await adapter.events(body.cursor ?? null, body.limit ?? 100);
|
|
102
|
-
return json({
|
|
103
|
-
events: page.events.map((event) => ({
|
|
104
|
-
id: event.id,
|
|
105
|
-
model: event.model,
|
|
106
|
-
entityId: event.entityId,
|
|
107
|
-
type: event.type,
|
|
108
|
-
...(event.data !== undefined && event.data !== null ? { data: event.data } : {}),
|
|
109
|
-
...(event.organizationId ? { organizationId: event.organizationId } : {}),
|
|
110
|
-
...(event.clientTxId ? { clientTxId: event.clientTxId } : {}),
|
|
111
|
-
...(event.occurredAt !== undefined && event.occurredAt !== null
|
|
112
|
-
? { occurredAt: event.occurredAt }
|
|
113
|
-
: {}),
|
|
114
|
-
})),
|
|
115
|
-
...(page.nextCursor !== null ? { nextCursor: page.nextCursor } : {}),
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
return json({ error: 'unknown_source_request' }, 400);
|
|
119
|
-
}
|
|
120
|
-
async function readBody(request) {
|
|
121
|
-
if (typeof request.text === 'function') {
|
|
122
|
-
const rawBody = await request.text();
|
|
123
|
-
return { rawBody, body: JSON.parse(rawBody) };
|
|
124
|
-
}
|
|
125
|
-
const body = (await request.json());
|
|
126
|
-
return { rawBody: JSON.stringify(body), body };
|
|
127
|
-
}
|
|
128
|
-
function getHeader(request, name) {
|
|
129
|
-
const headers = request.headers;
|
|
130
|
-
if (!headers)
|
|
131
|
-
return null;
|
|
132
|
-
if (typeof headers.get === 'function') {
|
|
133
|
-
return headers.get(name);
|
|
134
|
-
}
|
|
135
|
-
const record = headers;
|
|
136
|
-
return record[name] ?? record[name.toLowerCase()] ?? null;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Parse a `webhook-signature` header per the Standard Webhooks spec.
|
|
140
|
-
* Values are space-delimited `<scheme>,<base64>` pairs (e.g.
|
|
141
|
-
* `v1,abc== v1,def==` during a key rotation window). Returns the set
|
|
142
|
-
* of `v1` signatures so the verifier can accept any of them.
|
|
143
|
-
*/
|
|
144
|
-
function parseSignatureHeader(raw) {
|
|
145
|
-
if (!raw)
|
|
146
|
-
return [];
|
|
147
|
-
const out = [];
|
|
148
|
-
for (const part of raw.split(/\s+/)) {
|
|
149
|
-
const trimmed = part.trim();
|
|
150
|
-
if (!trimmed)
|
|
151
|
-
continue;
|
|
152
|
-
const commaAt = trimmed.indexOf(',');
|
|
153
|
-
if (commaAt === -1)
|
|
154
|
-
continue;
|
|
155
|
-
const scheme = trimmed.slice(0, commaAt);
|
|
156
|
-
const value = trimmed.slice(commaAt + 1);
|
|
157
|
-
if (scheme === 'v1' && value.length > 0) {
|
|
158
|
-
out.push(value);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
return out;
|
|
162
|
-
}
|
|
163
|
-
function bufferToBase64(buffer) {
|
|
164
|
-
// Node + browsers both expose `btoa` on the global; we feed it
|
|
165
|
-
// a binary string built from the byte view.
|
|
166
|
-
let binary = '';
|
|
167
|
-
const bytes = new Uint8Array(buffer);
|
|
168
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
169
|
-
binary += String.fromCharCode(bytes[i]);
|
|
170
|
-
}
|
|
171
|
-
return btoa(binary);
|
|
172
|
-
}
|
|
173
|
-
async function hmacSha256Base64(apiKey, payload) {
|
|
174
|
-
const crypto = globalThis.crypto?.subtle;
|
|
175
|
-
if (!crypto) {
|
|
176
|
-
throw new SourceSignatureError('source_signature_invalid', 'WebCrypto HMAC support is unavailable in this runtime');
|
|
177
|
-
}
|
|
178
|
-
const encoder = new TextEncoder();
|
|
179
|
-
const key = await crypto.importKey('raw', encoder.encode(apiKey), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
180
|
-
return bufferToBase64(await crypto.sign('HMAC', key, encoder.encode(payload)));
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Constant-time string equality. Used over `===` so a malicious
|
|
184
|
-
* signature can't be probed byte-by-byte via timing differences.
|
|
185
|
-
*/
|
|
186
|
-
function timingSafeEqual(expected, actual) {
|
|
187
|
-
const max = Math.max(expected.length, actual.length);
|
|
188
|
-
let diff = expected.length ^ actual.length;
|
|
189
|
-
for (let i = 0; i < max; i++) {
|
|
190
|
-
diff |= (expected.charCodeAt(i) || 0) ^ (actual.charCodeAt(i) || 0);
|
|
191
|
-
}
|
|
192
|
-
return diff === 0;
|
|
193
|
-
}
|
|
194
|
-
export async function signAbloSourceRequest(options) {
|
|
195
|
-
const signedAt = options.timestamp ?? Math.floor(Date.now() / 1000);
|
|
196
|
-
// Standard Webhooks signing input: `${msg_id}.${timestamp}.${payload}`
|
|
197
|
-
const signature = await hmacSha256Base64(options.apiKey, `${options.messageId}.${signedAt}.${options.body}`);
|
|
198
|
-
return {
|
|
199
|
-
signedAt,
|
|
200
|
-
signature,
|
|
201
|
-
headers: {
|
|
202
|
-
[ABLO_SOURCE_HEADERS.id]: options.messageId,
|
|
203
|
-
[ABLO_SOURCE_HEADERS.timestamp]: String(signedAt),
|
|
204
|
-
[ABLO_SOURCE_HEADERS.signature]: `v1,${signature}`,
|
|
205
|
-
},
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
export async function verifyAbloSourceRequest(options) {
|
|
209
|
-
const messageId = getHeader(options.request, ABLO_SOURCE_HEADERS.id);
|
|
210
|
-
if (!messageId) {
|
|
211
|
-
throw new SourceSignatureError('source_id_missing', 'Missing webhook-id header');
|
|
212
|
-
}
|
|
213
|
-
const rawTimestamp = getHeader(options.request, ABLO_SOURCE_HEADERS.timestamp);
|
|
214
|
-
if (!rawTimestamp) {
|
|
215
|
-
throw new SourceSignatureError('source_timestamp_missing', 'Missing webhook-timestamp header');
|
|
216
|
-
}
|
|
217
|
-
const signedAt = Number(rawTimestamp);
|
|
218
|
-
if (!Number.isFinite(signedAt)) {
|
|
219
|
-
throw new SourceSignatureError('source_timestamp_invalid', 'Invalid webhook-timestamp header');
|
|
220
|
-
}
|
|
221
|
-
const toleranceMs = options.toleranceMs ?? DEFAULT_SIGNATURE_TOLERANCE_MS;
|
|
222
|
-
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
223
|
-
const toleranceSeconds = Math.ceil(toleranceMs / 1000);
|
|
224
|
-
if (Math.abs(nowSeconds - signedAt) > toleranceSeconds) {
|
|
225
|
-
throw new SourceSignatureError('source_timestamp_expired', 'webhook-timestamp is outside the allowed clock-skew window');
|
|
226
|
-
}
|
|
227
|
-
const presented = parseSignatureHeader(getHeader(options.request, ABLO_SOURCE_HEADERS.signature));
|
|
228
|
-
if (presented.length === 0) {
|
|
229
|
-
throw new SourceSignatureError('source_signature_missing', 'Missing webhook-signature header');
|
|
230
|
-
}
|
|
231
|
-
const expected = await hmacSha256Base64(options.apiKey, `${messageId}.${signedAt}.${options.body}`);
|
|
232
|
-
// Accept any presented signature that matches — supports key
|
|
233
|
-
// rotation per the Standard Webhooks spec.
|
|
234
|
-
const ok = presented.some((sig) => timingSafeEqual(expected, sig));
|
|
235
|
-
if (!ok) {
|
|
236
|
-
throw new SourceSignatureError('source_signature_invalid', 'Invalid webhook-signature');
|
|
237
|
-
}
|
|
238
|
-
return { messageId, signedAt };
|
|
239
|
-
}
|
|
240
|
-
async function resolveApiKey(apiKey, context) {
|
|
241
|
-
if (!apiKey)
|
|
242
|
-
return null;
|
|
243
|
-
return typeof apiKey === 'function' ? apiKey(context) : apiKey;
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Map a wire request to its scope tag. Each request type corresponds
|
|
247
|
-
* to one scope, so the function is total and exhaustive — adding a
|
|
248
|
-
* new request type forces a new scope tag, which is the right design
|
|
249
|
-
* pressure for keeping the scope vocabulary in sync with the wire.
|
|
5
|
+
* - `types.ts` — the shared wire and handler types, plus `sourceEventForOperation`
|
|
6
|
+
* - `signing.ts` — request signing and verification
|
|
7
|
+
* - `factory.ts` — the `abloSource()` / `dataSource()` endpoint factory
|
|
8
|
+
*
|
|
9
|
+
* Import from here; the sibling modules import one another directly.
|
|
250
10
|
*/
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return 'load';
|
|
255
|
-
case 'list':
|
|
256
|
-
return 'list';
|
|
257
|
-
case 'commit':
|
|
258
|
-
return 'commit';
|
|
259
|
-
case 'events':
|
|
260
|
-
return 'events';
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
function normalizeListResult(result) {
|
|
264
|
-
if (Array.isArray(result)) {
|
|
265
|
-
return { rows: result };
|
|
266
|
-
}
|
|
267
|
-
const page = result;
|
|
268
|
-
return page.nextCursor !== undefined
|
|
269
|
-
? { rows: page.rows, nextCursor: page.nextCursor }
|
|
270
|
-
: { rows: page.rows };
|
|
271
|
-
}
|
|
272
|
-
function getModelHandlers(options, model) {
|
|
273
|
-
const grouped = options.models?.[model];
|
|
274
|
-
if (grouped)
|
|
275
|
-
return grouped;
|
|
276
|
-
const direct = options[model];
|
|
277
|
-
return direct;
|
|
278
|
-
}
|
|
279
|
-
function sameModel(operations) {
|
|
280
|
-
const first = operations[0]?.model;
|
|
281
|
-
if (!first)
|
|
282
|
-
return null;
|
|
283
|
-
return operations.every((op) => op.model === first) ? first : null;
|
|
284
|
-
}
|
|
285
|
-
export function abloSource(options) {
|
|
286
|
-
return async function handleAbloSource(request) {
|
|
287
|
-
if (request.method !== 'POST') {
|
|
288
|
-
return json({ error: 'method_not_allowed' }, 405);
|
|
289
|
-
}
|
|
290
|
-
let body;
|
|
291
|
-
let rawBody;
|
|
292
|
-
try {
|
|
293
|
-
const parsed = await readBody(request);
|
|
294
|
-
body = parsed.body;
|
|
295
|
-
rawBody = parsed.rawBody;
|
|
296
|
-
}
|
|
297
|
-
catch {
|
|
298
|
-
return json({ error: 'invalid_json' }, 400);
|
|
299
|
-
}
|
|
300
|
-
let signature = null;
|
|
301
|
-
try {
|
|
302
|
-
const apiKey = await resolveApiKey(options.apiKey, {
|
|
303
|
-
request,
|
|
304
|
-
body,
|
|
305
|
-
rawBody,
|
|
306
|
-
});
|
|
307
|
-
if (!apiKey) {
|
|
308
|
-
return json({
|
|
309
|
-
error: 'source_api_key_missing',
|
|
310
|
-
message: 'Data Source apiKey is required',
|
|
311
|
-
}, 401);
|
|
312
|
-
}
|
|
313
|
-
signature = await verifyAbloSourceRequest({
|
|
314
|
-
request,
|
|
315
|
-
body: rawBody,
|
|
316
|
-
apiKey,
|
|
317
|
-
toleranceMs: options.signatureToleranceMs,
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
catch (err) {
|
|
321
|
-
if (err instanceof SourceSignatureError) {
|
|
322
|
-
return json({ error: err.code, message: err.message }, 401);
|
|
323
|
-
}
|
|
324
|
-
throw err;
|
|
325
|
-
}
|
|
326
|
-
const auth = options.authorize
|
|
327
|
-
? await options.authorize({ request, body, rawBody })
|
|
328
|
-
: undefined;
|
|
329
|
-
// Per-key permission scope check. When `resolveScopes` is set,
|
|
330
|
-
// the customer returns the operation set this key is allowed to
|
|
331
|
-
// invoke; we enforce before any model handler runs.
|
|
332
|
-
if (options.resolveScopes) {
|
|
333
|
-
const required = scopeFor(body);
|
|
334
|
-
const granted = await options.resolveScopes({ auth, request, body });
|
|
335
|
-
const grantedSet = granted instanceof Set ? granted : new Set(granted);
|
|
336
|
-
if (!grantedSet.has(required)) {
|
|
337
|
-
return json({
|
|
338
|
-
error: 'source_forbidden',
|
|
339
|
-
required,
|
|
340
|
-
granted: Array.from(grantedSet),
|
|
341
|
-
}, 403);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
const context = {
|
|
345
|
-
auth,
|
|
346
|
-
request,
|
|
347
|
-
messageId: signature?.messageId,
|
|
348
|
-
signedAt: signature?.signedAt,
|
|
349
|
-
...(body.scope ? { scope: body.scope } : {}),
|
|
350
|
-
};
|
|
351
|
-
// Adapter path: when an ORM adapter is configured it serves every operation,
|
|
352
|
-
// consumed at this generic layer (rows are JSON on the wire), so no per-model
|
|
353
|
-
// handler lookup and no typed↔generic boundary.
|
|
354
|
-
if (options.adapter) {
|
|
355
|
-
return handleViaAdapter(options.adapter, body, context.scope);
|
|
356
|
-
}
|
|
357
|
-
if (body.type === 'load') {
|
|
358
|
-
const handlers = getModelHandlers(options, body.model);
|
|
359
|
-
if (!handlers?.load) {
|
|
360
|
-
return json({ error: 'source_load_not_configured', model: body.model }, 404);
|
|
361
|
-
}
|
|
362
|
-
const row = await handlers.load({ id: body.id, context });
|
|
363
|
-
return json({ row });
|
|
364
|
-
}
|
|
365
|
-
if (body.type === 'list') {
|
|
366
|
-
const handlers = getModelHandlers(options, body.model);
|
|
367
|
-
if (!handlers?.list) {
|
|
368
|
-
return json({ error: 'source_list_not_configured', model: body.model }, 404);
|
|
369
|
-
}
|
|
370
|
-
const result = await handlers.list({ query: body.query ?? {}, context });
|
|
371
|
-
const normalized = normalizeListResult(result);
|
|
372
|
-
return json(normalized);
|
|
373
|
-
}
|
|
374
|
-
if (body.type === 'commit') {
|
|
375
|
-
if (options.commit) {
|
|
376
|
-
const result = await options.commit({
|
|
377
|
-
operations: body.operations,
|
|
378
|
-
clientTxId: body.clientTxId,
|
|
379
|
-
context,
|
|
380
|
-
});
|
|
381
|
-
return json(result);
|
|
382
|
-
}
|
|
383
|
-
const model = body.model ?? sameModel(body.operations);
|
|
384
|
-
if (!model) {
|
|
385
|
-
return json({ error: 'source_commit_requires_single_model' }, 400);
|
|
386
|
-
}
|
|
387
|
-
const handlers = getModelHandlers(options, model);
|
|
388
|
-
if (!handlers?.commit) {
|
|
389
|
-
return json({ error: 'source_commit_not_configured', model }, 404);
|
|
390
|
-
}
|
|
391
|
-
const result = await handlers.commit({
|
|
392
|
-
operations: body.operations,
|
|
393
|
-
clientTxId: body.clientTxId,
|
|
394
|
-
context,
|
|
395
|
-
});
|
|
396
|
-
return json(result);
|
|
397
|
-
}
|
|
398
|
-
if (body.type === 'events') {
|
|
399
|
-
if (!options.events) {
|
|
400
|
-
return json({ error: 'source_events_not_configured' }, 404);
|
|
401
|
-
}
|
|
402
|
-
const result = await options.events({
|
|
403
|
-
cursor: body.cursor,
|
|
404
|
-
limit: body.limit,
|
|
405
|
-
context,
|
|
406
|
-
});
|
|
407
|
-
return json({
|
|
408
|
-
events: result.events,
|
|
409
|
-
...(result.nextCursor !== undefined
|
|
410
|
-
? { nextCursor: result.nextCursor }
|
|
411
|
-
: {}),
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
return json({ error: 'unknown_source_request' }, 400);
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
export function dataSource(options) {
|
|
418
|
-
return abloSource(options);
|
|
419
|
-
}
|
|
11
|
+
export { sourceEventForOperation, } from './types.js';
|
|
12
|
+
export { ABLO_SOURCE_HEADERS, SourceSignatureError, signAbloSourceRequest, verifyAbloSourceRequest, } from './signing.js';
|
|
13
|
+
export { abloSource, dataSource, } from './factory.js';
|
|
420
14
|
export { createPushQueue, InMemoryPushQueueStorage, STANDARD_WEBHOOKS_RETRY_SCHEDULE, } from './pushQueue.js';
|
|
421
|
-
//
|
|
422
|
-
//
|
|
423
|
-
// Source
|
|
424
|
-
//
|
|
15
|
+
// The reverse-channel connector — an outbound transport for the load, list, and
|
|
16
|
+
// commit leg, and the dial-out counterpart to `createPushQueue`. It lets you serve
|
|
17
|
+
// a Data Source from localhost or a private network that has no public inbound
|
|
18
|
+
// URL. See `connectorProtocol.ts` for the frames it exchanges.
|
|
425
19
|
export { createSourceConnector, DEFAULT_RECONNECT_SCHEDULE, } from './connector.js';
|
|
426
|
-
export { SOURCE_CONNECTOR_PROTOCOL_VERSION, SOURCE_CONNECTOR_WS_PATH, WS_SOURCE_SUBPROTOCOL, sourceConnectorSubprotocols, encodeFrame, decodeFrame, ConnectorProtocolError, connectorFrameSchema, } from './
|
|
20
|
+
export { SOURCE_CONNECTOR_PROTOCOL_VERSION, SOURCE_CONNECTOR_WS_PATH, WS_SOURCE_SUBPROTOCOL, sourceConnectorSubprotocols, encodeFrame, decodeFrame, ConnectorProtocolError, connectorFrameSchema, } from './connectorProtocol.js';
|
|
21
|
+
// The Data Source adapter interface and its Zod contract, with per-ORM implementations.
|
|
22
|
+
export {} from './adapter.js';
|
|
427
23
|
export { operationSchema, operationTypeSchema, changeSetSchema, outboxEventSchema, eventsPageSchema, migrationSchema, adapterCapabilitiesSchema, } from './contract.js';
|
|
428
24
|
export { prismaDataSource } from './adapters/prisma.js';
|
|
429
25
|
export { adapterTableMigrations } from './migrations.js';
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The table-creation SQL every ORM adapter ships for its
|
|
3
|
-
* `ablo_idempotency
|
|
4
|
-
* outbox the `events()` feed reads
|
|
5
|
-
* Drizzle adapter, and `ablo migrate`
|
|
6
|
-
*
|
|
2
|
+
* The table-creation SQL every ORM adapter ships for its own infrastructure
|
|
3
|
+
* tables: `ablo_idempotency`, which dedupes commits by `clientTxId`, and
|
|
4
|
+
* `ablo_outbox`, the transactional outbox the `events()` feed reads. Defining it in
|
|
5
|
+
* one place keeps the Prisma adapter, the Drizzle adapter, and `ablo migrate` in
|
|
6
|
+
* agreement on the exact shape.
|
|
7
7
|
*
|
|
8
|
-
* These are
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* These are infrastructure tables, not model tables, and they exist only on your
|
|
9
|
+
* own database when you run a Data Source. Ablo's hosted storage does not use them;
|
|
10
|
+
* it records changes in its own `sync_deltas` log instead.
|
|
11
11
|
*/
|
|
12
12
|
import type { Migration } from './contract.js';
|
|
13
|
-
/**
|
|
13
|
+
/** Returns the adapter's table-creation migrations. The SQL is idempotent, guarded by `IF NOT EXISTS`. */
|
|
14
14
|
export declare function adapterTableMigrations(): readonly Migration[];
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The table-creation SQL every ORM adapter ships for its
|
|
3
|
-
* `ablo_idempotency
|
|
4
|
-
* outbox the `events()` feed reads
|
|
5
|
-
* Drizzle adapter, and `ablo migrate`
|
|
6
|
-
*
|
|
2
|
+
* The table-creation SQL every ORM adapter ships for its own infrastructure
|
|
3
|
+
* tables: `ablo_idempotency`, which dedupes commits by `clientTxId`, and
|
|
4
|
+
* `ablo_outbox`, the transactional outbox the `events()` feed reads. Defining it in
|
|
5
|
+
* one place keeps the Prisma adapter, the Drizzle adapter, and `ablo migrate` in
|
|
6
|
+
* agreement on the exact shape.
|
|
7
7
|
*
|
|
8
|
-
* These are
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* These are infrastructure tables, not model tables, and they exist only on your
|
|
9
|
+
* own database when you run a Data Source. Ablo's hosted storage does not use them;
|
|
10
|
+
* it records changes in its own `sync_deltas` log instead.
|
|
11
11
|
*/
|
|
12
|
-
/**
|
|
12
|
+
/** Returns the adapter's table-creation migrations. The SQL is idempotent, guarded by `IF NOT EXISTS`. */
|
|
13
13
|
export function adapterTableMigrations() {
|
|
14
14
|
return [
|
|
15
15
|
{
|
package/dist/source/next.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Next.js App Router
|
|
3
|
-
* returns a
|
|
4
|
-
* accepts directly
|
|
5
|
-
*
|
|
2
|
+
* A thin Next.js App Router wrapper for a Data Source. The core `dataSource()`
|
|
3
|
+
* already returns a standard `(Request) => Promise<Response>`, which the App Router
|
|
4
|
+
* accepts directly, so this helper adds only convenience: it names the handler
|
|
5
|
+
* `POST` so your route file can export it in one line.
|
|
6
6
|
*
|
|
7
7
|
* // app/api/ablo/source/route.ts
|
|
8
8
|
* import { dataSourceNext } from '@abloatai/ablo/source/next';
|
|
@@ -16,16 +16,15 @@
|
|
|
16
16
|
* adapter: prismaDataSource(prisma, schema),
|
|
17
17
|
* });
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* — not pre-built.
|
|
19
|
+
* For hand-written handlers, or another framework, call the core `dataSource()`
|
|
20
|
+
* directly and export its result however that framework expects.
|
|
22
21
|
*/
|
|
23
22
|
import type { SchemaRecord } from '../schema/schema.js';
|
|
24
|
-
import { type DataSourceOptions } from './
|
|
23
|
+
import { type DataSourceOptions } from './factory.js';
|
|
25
24
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
25
|
+
* The options for `dataSourceNext`, which are exactly the core
|
|
26
|
+
* `DataSourceOptions`. Pass `{ schema, apiKey, adapter }`, the same shape
|
|
27
|
+
* `dataSource()` takes.
|
|
29
28
|
*/
|
|
30
29
|
export type DataSourceNextOptions<S extends SchemaRecord, TAuth = unknown> = DataSourceOptions<S, TAuth>;
|
|
31
30
|
export declare function dataSourceNext<const S extends SchemaRecord, TAuth = unknown>(options: DataSourceNextOptions<S, TAuth>): {
|
package/dist/source/next.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Next.js App Router
|
|
3
|
-
* returns a
|
|
4
|
-
* accepts directly
|
|
5
|
-
*
|
|
2
|
+
* A thin Next.js App Router wrapper for a Data Source. The core `dataSource()`
|
|
3
|
+
* already returns a standard `(Request) => Promise<Response>`, which the App Router
|
|
4
|
+
* accepts directly, so this helper adds only convenience: it names the handler
|
|
5
|
+
* `POST` so your route file can export it in one line.
|
|
6
6
|
*
|
|
7
7
|
* // app/api/ablo/source/route.ts
|
|
8
8
|
* import { dataSourceNext } from '@abloatai/ablo/source/next';
|
|
@@ -16,11 +16,10 @@
|
|
|
16
16
|
* adapter: prismaDataSource(prisma, schema),
|
|
17
17
|
* });
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* — not pre-built.
|
|
19
|
+
* For hand-written handlers, or another framework, call the core `dataSource()`
|
|
20
|
+
* directly and export its result however that framework expects.
|
|
22
21
|
*/
|
|
23
|
-
import { dataSource } from './
|
|
22
|
+
import { dataSource } from './factory.js';
|
|
24
23
|
export function dataSourceNext(options) {
|
|
25
24
|
return { POST: dataSource(options) };
|
|
26
25
|
}
|