@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/types.d.ts
CHANGED
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The types that describe a data source — the shapes exchanged over the wire
|
|
3
|
+
* and the handler interfaces you implement.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* `sourceEventForOperation` lives here too: it is the pure constructor for the
|
|
11
|
-
* `SourceEvent` marker shape and has no dependency on the endpoint factory.
|
|
5
|
+
* A data source lets Ablo read from and write to your own database. These
|
|
6
|
+
* types cover the four request kinds Ablo can send ({@link SourceRequest}),
|
|
7
|
+
* the operations and change events they carry ({@link SourceOperation} and
|
|
8
|
+
* {@link SourceEvent}), the list-query and pagination shapes, and the handler
|
|
9
|
+
* and context types your source implements. {@link sourceEventForOperation}
|
|
10
|
+
* builds a change-event marker from an operation.
|
|
12
11
|
*/
|
|
13
12
|
import type { Environment } from '../environment.js';
|
|
13
|
+
/** A scalar value that can appear in a source filter. */
|
|
14
14
|
export type SourcePrimitive = string | number | boolean | null;
|
|
15
|
+
/**
|
|
16
|
+
* A single filter condition on a `list` query: a field paired with a value,
|
|
17
|
+
* or a field, comparison operator, and value. The two-element form is
|
|
18
|
+
* shorthand for equality.
|
|
19
|
+
*/
|
|
15
20
|
export type SourceWhere = readonly [field: string, value: SourcePrimitive] | readonly [
|
|
16
21
|
field: string,
|
|
17
22
|
op: '=' | '!=' | '<' | '<=' | '>' | '>=' | 'IN' | 'NOT IN' | 'IS' | 'IS NOT' | 'LIKE' | 'NOT LIKE' | 'ILIKE' | 'NOT ILIKE',
|
|
18
23
|
value: SourcePrimitive | readonly SourcePrimitive[]
|
|
19
24
|
];
|
|
25
|
+
/** The query Ablo passes to your `list` handler: filters, ordering, a limit, and a pagination cursor. */
|
|
20
26
|
export interface SourceListQuery {
|
|
21
27
|
readonly where?: readonly SourceWhere[];
|
|
22
28
|
readonly limit?: number;
|
|
@@ -24,33 +30,31 @@ export interface SourceListQuery {
|
|
|
24
30
|
readonly order?: 'asc' | 'desc';
|
|
25
31
|
readonly related?: readonly string[];
|
|
26
32
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
33
|
+
* An opaque cursor returned by a previous `list` call. Your `list` handler
|
|
34
|
+
* decides what it encodes — a page index, a last id, a keyset. Ablo treats
|
|
35
|
+
* it as a black box and hands it back to fetch the next page until your
|
|
36
|
+
* handler stops returning a `nextCursor`.
|
|
31
37
|
*/
|
|
32
38
|
readonly cursor?: string;
|
|
33
39
|
}
|
|
34
40
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* cursor that Ablo will round-trip on the next request.
|
|
41
|
+
* The paginated return shape for a `list` handler. A handler may return a
|
|
42
|
+
* plain `Row[]` for a single, unpaginated page, or return this shape to expose
|
|
43
|
+
* a `nextCursor` that Ablo hands back on the following request.
|
|
39
44
|
*/
|
|
40
45
|
export interface SourceListPage<Row> {
|
|
41
46
|
readonly rows: readonly Row[];
|
|
42
47
|
readonly nextCursor?: string;
|
|
43
48
|
}
|
|
49
|
+
/** What a `list` handler returns: either a plain array of rows or a {@link SourceListPage}. */
|
|
44
50
|
export type SourceListResult<Row> = readonly Row[] | SourceListPage<Row>;
|
|
45
51
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* fall outside the participant's permitted
|
|
52
|
+
* The scope of a source request: who is asking and what they are allowed to
|
|
53
|
+
* see. Ablo attaches this so your `authorize` and model handlers can reject
|
|
54
|
+
* calls that fall outside the participant's permitted sync groups.
|
|
49
55
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* Mirrors how Auth0 Custom DB scripts receive the requested scope and
|
|
53
|
-
* trust the script to honor it.
|
|
56
|
+
* It is advisory. Because the canonical data lives in your database, your
|
|
57
|
+
* handlers are the only place that can actually enforce these limits.
|
|
54
58
|
*/
|
|
55
59
|
export interface SourceRequestContext {
|
|
56
60
|
readonly participantId?: string;
|
|
@@ -58,22 +62,22 @@ export interface SourceRequestContext {
|
|
|
58
62
|
readonly organizationId?: string;
|
|
59
63
|
readonly requiredSyncGroups?: readonly string[];
|
|
60
64
|
/**
|
|
61
|
-
*
|
|
62
|
-
* handlers on
|
|
63
|
-
* traffic exercises the same code
|
|
65
|
+
* Whether this request runs in production or sandbox mode. Branch your
|
|
66
|
+
* handlers on it — for example, read and write a separate sandbox database
|
|
67
|
+
* when `mode === 'sandbox'` — so sandbox traffic exercises the same code
|
|
68
|
+
* against isolated data. Keeping the two apart is your handler's
|
|
69
|
+
* responsibility, since your database holds the canonical rows.
|
|
64
70
|
*
|
|
65
|
-
*
|
|
66
|
-
* shape, same handler code, different namespace. Ablo's server-side
|
|
67
|
-
* fan-out does not yet partition deltas by mode — that lands when
|
|
68
|
-
* `sync_deltas.mode` ships. Until then, isolation is enforced
|
|
69
|
-
* customer-side via this field, which is the right boundary anyway
|
|
70
|
-
* (the customer's database is where the canonical data lives).
|
|
71
|
-
*
|
|
72
|
-
* Defaults to `'production'` when omitted so callers that don't opt in
|
|
73
|
-
* keep the existing behavior.
|
|
71
|
+
* Defaults to `'production'` when omitted.
|
|
74
72
|
*/
|
|
75
73
|
readonly mode?: Environment;
|
|
76
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* A single change Ablo asks your source to apply — a create, update, delete,
|
|
77
|
+
* archive, or unarchive of one row of `model`. Operations arrive in your
|
|
78
|
+
* `commit` handler through {@link SourceCommitParams}. `onStale` says what to
|
|
79
|
+
* do when the row changed since it was read at `readAt`.
|
|
80
|
+
*/
|
|
77
81
|
export interface SourceOperation {
|
|
78
82
|
readonly type: 'CREATE' | 'UPDATE' | 'DELETE' | 'ARCHIVE' | 'UNARCHIVE';
|
|
79
83
|
readonly model: string;
|
|
@@ -83,6 +87,11 @@ export interface SourceOperation {
|
|
|
83
87
|
readonly readAt?: number | null;
|
|
84
88
|
readonly onStale?: 'reject' | 'overwrite' | 'notify' | null;
|
|
85
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* A computed change to one row, ready to append to the change log. Your
|
|
92
|
+
* `commit` handler may return these directly, or return rows and let Ablo
|
|
93
|
+
* derive the deltas from them.
|
|
94
|
+
*/
|
|
86
95
|
export interface SourceDelta {
|
|
87
96
|
readonly model: string;
|
|
88
97
|
readonly id: string;
|
|
@@ -91,21 +100,20 @@ export interface SourceDelta {
|
|
|
91
100
|
readonly transactionId?: string | null;
|
|
92
101
|
}
|
|
93
102
|
/**
|
|
94
|
-
* A change that happened in
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* SDK
|
|
103
|
+
* A change that already happened in your database. Your `events` handler
|
|
104
|
+
* returns these, and Ablo appends them to the `sync_deltas` change log and
|
|
105
|
+
* fans them out to connected clients, exactly as it would a change made
|
|
106
|
+
* through the SDK.
|
|
98
107
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* `mutation_log` row exists yet.
|
|
108
|
+
* Your handler can return the whole outbox unfiltered. Ablo deduplicates on
|
|
109
|
+
* the stable `id` and uses `clientTxId` to drop echoes of changes the SDK
|
|
110
|
+
* already committed. If that earlier commit never landed, the same outbox
|
|
111
|
+
* event repairs the gap on the next poll or push.
|
|
104
112
|
*/
|
|
105
113
|
export interface SourceEvent {
|
|
106
114
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
115
|
+
* A globally unique event id from your outbox. Ablo uses it for replay
|
|
116
|
+
* protection, so re-delivering the same id is a no-op.
|
|
109
117
|
*/
|
|
110
118
|
readonly id: string;
|
|
111
119
|
readonly model: string;
|
|
@@ -113,111 +121,118 @@ export interface SourceEvent {
|
|
|
113
121
|
readonly type: SourceOperation['type'];
|
|
114
122
|
readonly data?: Record<string, unknown> | null;
|
|
115
123
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* receive the resulting delta.
|
|
124
|
+
* The tenant this event belongs to. Populate it from the row's organization
|
|
125
|
+
* column for multi-tenant data; a single-tenant source may omit it and let
|
|
126
|
+
* the poller fall back to its configured default. It drives fan-out: clients
|
|
127
|
+
* in `org:${organizationId}` receive the resulting change.
|
|
121
128
|
*/
|
|
122
129
|
readonly organizationId?: string;
|
|
123
130
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
131
|
+
* The originating SDK commit id, when you know it. If your outbox records the
|
|
132
|
+
* `clientTxId` that Ablo passed into the matching `commit` handler, echo it
|
|
133
|
+
* back here and Ablo will skip events whose commit already produced a change.
|
|
134
|
+
* Leave it unset for changes made outside the SDK, such as cron jobs, batch
|
|
135
|
+
* imports, or manual edits.
|
|
129
136
|
*/
|
|
130
137
|
readonly clientTxId?: string;
|
|
131
138
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
139
|
+
* When the change occurred in your database. Optional and used only as an
|
|
140
|
+
* ordering hint; Ablo trusts the order of your handler's response over this
|
|
141
|
+
* field.
|
|
135
142
|
*/
|
|
136
143
|
readonly occurredAt?: number;
|
|
137
144
|
}
|
|
145
|
+
/** Inputs to {@link sourceEventForOperation}. */
|
|
138
146
|
export interface SourceEventForOperationOptions {
|
|
139
147
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
148
|
+
* The stable id from your outbox table. It is Ablo's replay-protection key,
|
|
149
|
+
* so retries must return the same id.
|
|
142
150
|
*/
|
|
143
151
|
readonly eventId: string;
|
|
144
152
|
readonly operation: SourceOperation;
|
|
145
153
|
/**
|
|
146
|
-
*
|
|
147
|
-
*
|
|
154
|
+
* The committed row id. Defaults to `operation.id`; pass it explicitly for
|
|
155
|
+
* creates where the database assigns the id inside the transaction.
|
|
148
156
|
*/
|
|
149
157
|
readonly entityId?: string;
|
|
150
158
|
/**
|
|
151
|
-
*
|
|
152
|
-
* the event carries no
|
|
153
|
-
* realtime
|
|
159
|
+
* The row's payload after the write. Pass `null` for a delete. When omitted,
|
|
160
|
+
* the event carries no payload, which is valid but leaves less for clients to
|
|
161
|
+
* hydrate from in realtime.
|
|
154
162
|
*/
|
|
155
163
|
readonly data?: Record<string, unknown> | null;
|
|
156
164
|
/**
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
165
|
+
* The commit request's idempotency key. Echoing it lets Ablo drop echoes of
|
|
166
|
+
* a change the SDK already committed, while still letting the outbox event
|
|
167
|
+
* repair that change if it never landed.
|
|
160
168
|
*/
|
|
161
169
|
readonly clientTxId?: string;
|
|
162
170
|
readonly organizationId?: string;
|
|
163
171
|
readonly occurredAt?: number | Date;
|
|
164
172
|
}
|
|
165
173
|
/**
|
|
166
|
-
* Build the
|
|
167
|
-
* the
|
|
174
|
+
* Build the {@link SourceEvent} marker you should record in your outbox table,
|
|
175
|
+
* within the same transaction as the row change it describes.
|
|
168
176
|
*
|
|
169
|
-
* This helper does not persist anything.
|
|
170
|
-
*
|
|
171
|
-
*
|
|
177
|
+
* This helper only shapes the marker; it does not persist anything. Writing the
|
|
178
|
+
* returned event through your ORM or raw SQL keeps every source emitting the
|
|
179
|
+
* fields Ablo expects when it reconciles the change.
|
|
172
180
|
*/
|
|
173
181
|
export declare function sourceEventForOperation(options: SourceEventForOperationOptions): SourceEvent;
|
|
182
|
+
/** What your `commit` handler returns after applying operations. */
|
|
174
183
|
export interface SourceCommitResult<Row = Record<string, unknown>> {
|
|
175
184
|
/**
|
|
176
|
-
*
|
|
177
|
-
* realtime projections and append
|
|
185
|
+
* The rows as they stand after the write. Ablo uses them to update its
|
|
186
|
+
* realtime projections and append the resulting changes.
|
|
178
187
|
*/
|
|
179
188
|
readonly rows?: readonly Row[];
|
|
180
189
|
/**
|
|
181
|
-
*
|
|
182
|
-
*
|
|
190
|
+
* Explicit changes, for sources that already compute them. Most sources can
|
|
191
|
+
* return rows instead and let Ablo derive the change payload.
|
|
183
192
|
*/
|
|
184
193
|
readonly deltas?: readonly SourceDelta[];
|
|
185
194
|
}
|
|
195
|
+
/** The arguments passed to a top-level {@link SourceCommitHandler}. */
|
|
186
196
|
export interface SourceCommitParams<TAuth = unknown> {
|
|
187
197
|
readonly operations: readonly SourceOperation[];
|
|
188
198
|
readonly clientTxId?: string;
|
|
189
199
|
readonly context: SourceHandlerContext<TAuth>;
|
|
190
200
|
}
|
|
191
201
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
* operation granularity — model-level scoping is a future addition.
|
|
202
|
+
* The operation an API key is permitted to invoke, one per request kind:
|
|
203
|
+
* `load` and `list` read, `commit` writes, and `events` reads the change feed.
|
|
204
|
+
* A key carries the set of scopes it is allowed to use.
|
|
196
205
|
*/
|
|
197
206
|
export type SourceScope = 'load' | 'list' | 'commit' | 'events';
|
|
207
|
+
/** What your `events` handler returns: a batch of changes and an optional next cursor. */
|
|
198
208
|
export interface SourceEventsResult {
|
|
199
209
|
readonly events: readonly SourceEvent[];
|
|
200
210
|
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
211
|
+
* The cursor for the next poll. When omitted, Ablo treats the feed as fully
|
|
212
|
+
* drained for this round and reuses the last event's cursor, or the initial
|
|
213
|
+
* cursor, on the following call.
|
|
204
214
|
*/
|
|
205
215
|
readonly nextCursor?: string;
|
|
206
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Your handler for the `events` request. Return the changes since `cursor` so
|
|
219
|
+
* Ablo can append and fan them out. See {@link SourceEvent}.
|
|
220
|
+
*/
|
|
207
221
|
export type SourceEventsHandler<TAuth = unknown> = (params: {
|
|
208
222
|
/**
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
223
|
+
* The cursor from a previous `events` call, or undefined on the first poll of
|
|
224
|
+
* a newly connected source. You decide what it encodes — a last event id, a
|
|
225
|
+
* timestamp, a log sequence number.
|
|
212
226
|
*/
|
|
213
227
|
readonly cursor?: string;
|
|
214
228
|
/**
|
|
215
|
-
*
|
|
216
|
-
*
|
|
229
|
+
* A suggested upper bound on how many events to return. You may return fewer;
|
|
230
|
+
* returning many more risks tripping Ablo's per-poll cap.
|
|
217
231
|
*/
|
|
218
232
|
readonly limit?: number;
|
|
219
233
|
readonly context: SourceHandlerContext<TAuth>;
|
|
220
234
|
}) => Promise<SourceEventsResult> | SourceEventsResult;
|
|
235
|
+
/** The request being authorized, passed to a function-form {@link SourceApiKey} or an `authorize` hook. */
|
|
221
236
|
export interface SourceAuthorizeContext {
|
|
222
237
|
readonly request: Request;
|
|
223
238
|
readonly body: unknown;
|
|
@@ -227,22 +242,23 @@ export interface SourceHandlerContext<TAuth = unknown> {
|
|
|
227
242
|
readonly auth: TAuth;
|
|
228
243
|
readonly request: Request;
|
|
229
244
|
/**
|
|
230
|
-
* `webhook-id` from the signed request
|
|
231
|
-
* Standard Webhooks
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
245
|
+
* The `webhook-id` from the signed request, globally unique per the
|
|
246
|
+
* Standard Webhooks specification. Dedupe by this id to defend against
|
|
247
|
+
* replay: Ablo does not deduplicate at the source-handler boundary.
|
|
248
|
+
* Commit idempotency keys on `clientTxId`, and event replay protection
|
|
249
|
+
* keys on the outbox event `id`.
|
|
235
250
|
*/
|
|
236
251
|
readonly messageId?: string;
|
|
237
252
|
readonly signedAt?: number;
|
|
238
253
|
/**
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
* `list`
|
|
254
|
+
* The scope context Ablo attached to this request, naming the participant
|
|
255
|
+
* and the sync groups they are allowed to see. Present when the host
|
|
256
|
+
* opted into scope-aware requests. Use it in `authorize` to reject
|
|
257
|
+
* out-of-scope calls, and in `list` and `load` to filter rows down to
|
|
258
|
+
* what the participant may see.
|
|
243
259
|
*
|
|
244
|
-
* Absent for
|
|
245
|
-
* single-tenant deployments that do not need scoped fan-out
|
|
260
|
+
* Absent for requests made without scope context, such as tests or
|
|
261
|
+
* single-tenant deployments that do not need scoped fan-out.
|
|
246
262
|
*/
|
|
247
263
|
readonly scope?: SourceRequestContext;
|
|
248
264
|
}
|
|
@@ -256,8 +272,9 @@ export interface SourceModelHandlers<Row, CreateInput, TAuth = unknown> {
|
|
|
256
272
|
readonly context: SourceHandlerContext<TAuth>;
|
|
257
273
|
}): Promise<SourceListResult<Row>> | SourceListResult<Row>;
|
|
258
274
|
/**
|
|
259
|
-
* Apply one or more operations for this model
|
|
260
|
-
* transaction.
|
|
275
|
+
* Apply one or more operations for this model within your own database
|
|
276
|
+
* transaction. Your handler must be idempotent on the operation and its
|
|
277
|
+
* `clientTxId`, so that a retried commit does not apply the change twice.
|
|
261
278
|
*/
|
|
262
279
|
commit?(params: {
|
|
263
280
|
readonly operations: readonly SourceOperation[];
|
package/dist/source/types.js
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The types that describe a data source — the shapes exchanged over the wire
|
|
3
|
+
* and the handler interfaces you implement.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* `sourceEventForOperation` lives here too: it is the pure constructor for the
|
|
11
|
-
* `SourceEvent` marker shape and has no dependency on the endpoint factory.
|
|
5
|
+
* A data source lets Ablo read from and write to your own database. These
|
|
6
|
+
* types cover the four request kinds Ablo can send ({@link SourceRequest}),
|
|
7
|
+
* the operations and change events they carry ({@link SourceOperation} and
|
|
8
|
+
* {@link SourceEvent}), the list-query and pagination shapes, and the handler
|
|
9
|
+
* and context types your source implements. {@link sourceEventForOperation}
|
|
10
|
+
* builds a change-event marker from an operation.
|
|
12
11
|
*/
|
|
13
12
|
import { AbloValidationError } from '../errors.js';
|
|
14
13
|
/**
|
|
15
|
-
* Build the
|
|
16
|
-
* the
|
|
14
|
+
* Build the {@link SourceEvent} marker you should record in your outbox table,
|
|
15
|
+
* within the same transaction as the row change it describes.
|
|
17
16
|
*
|
|
18
|
-
* This helper does not persist anything.
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* This helper only shapes the marker; it does not persist anything. Writing the
|
|
18
|
+
* returned event through your ORM or raw SQL keeps every source emitting the
|
|
19
|
+
* fields Ablo expects when it reconciles the change.
|
|
21
20
|
*/
|
|
22
21
|
export function sourceEventForOperation(options) {
|
|
23
22
|
const entityId = options.entityId ?? options.operation.id;
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Abstract base class for all store implementations.
|
|
5
|
-
* Provides the interface for storing and retrieving models from IndexedDB.
|
|
6
|
-
* Uses native IndexedDB for maximum performance (no wrapper overhead).
|
|
2
|
+
* The IndexedDB-backed object store: durable, per-model record storage for
|
|
3
|
+
* the browser. See {@link ObjectStore}.
|
|
7
4
|
*/
|
|
8
5
|
import type { ModelMetadata } from '../types/index.js';
|
|
9
6
|
import type { ObjectStoreContract } from './ObjectStoreContract.js';
|
|
10
7
|
/**
|
|
11
|
-
*
|
|
8
|
+
* An IndexedDB-backed store holding the records of a single model.
|
|
12
9
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* It implements {@link ObjectStoreContract}, the shared surface that
|
|
11
|
+
* {@link InMemoryObjectStore} also satisfies, so callers can hold either
|
|
12
|
+
* implementation behind one type. Because both are checked against the same
|
|
13
|
+
* interface, any drift between them surfaces as a typecheck error rather
|
|
14
|
+
* than a runtime surprise.
|
|
17
15
|
*
|
|
18
|
-
*
|
|
16
|
+
* The store talks to the native IndexedDB API directly and uses relaxed
|
|
17
|
+
* transaction durability on writes.
|
|
19
18
|
*/
|
|
20
19
|
export declare class ObjectStore implements ObjectStoreContract {
|
|
21
20
|
protected db: IDBDatabase;
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Abstract base class for all store implementations.
|
|
5
|
-
* Provides the interface for storing and retrieving models from IndexedDB.
|
|
6
|
-
* Uses native IndexedDB for maximum performance (no wrapper overhead).
|
|
2
|
+
* The IndexedDB-backed object store: durable, per-model record storage for
|
|
3
|
+
* the browser. See {@link ObjectStore}.
|
|
7
4
|
*/
|
|
8
5
|
/**
|
|
9
|
-
*
|
|
6
|
+
* An IndexedDB-backed store holding the records of a single model.
|
|
10
7
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
8
|
+
* It implements {@link ObjectStoreContract}, the shared surface that
|
|
9
|
+
* {@link InMemoryObjectStore} also satisfies, so callers can hold either
|
|
10
|
+
* implementation behind one type. Because both are checked against the same
|
|
11
|
+
* interface, any drift between them surfaces as a typecheck error rather
|
|
12
|
+
* than a runtime surprise.
|
|
15
13
|
*
|
|
16
|
-
*
|
|
14
|
+
* The store talks to the native IndexedDB API directly and uses relaxed
|
|
15
|
+
* transaction durability on writes.
|
|
17
16
|
*/
|
|
18
17
|
export class ObjectStore {
|
|
19
18
|
db;
|
|
@@ -45,7 +44,7 @@ export class ObjectStore {
|
|
|
45
44
|
// but we can check if the database object is still valid
|
|
46
45
|
try {
|
|
47
46
|
// Accessing objectStoreNames will throw if the database is closed
|
|
48
|
-
|
|
47
|
+
void this.db.objectStoreNames;
|
|
49
48
|
return true;
|
|
50
49
|
}
|
|
51
50
|
catch (error) {
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The shared interface for record-shaped object stores. Two implementations
|
|
3
|
+
* satisfy it:
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - {@link InMemoryObjectStore} —
|
|
5
|
+
* - {@link ObjectStore} — backed by IndexedDB, for durable persistence in
|
|
6
|
+
* the browser.
|
|
7
|
+
* - {@link InMemoryObjectStore} — backed by a Map, for tests and
|
|
8
|
+
* environments without IndexedDB.
|
|
7
9
|
*
|
|
8
|
-
* Both expose the same
|
|
9
|
-
* `delete
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* Centralizing the types here means a future drift between the two
|
|
16
|
-
* stores trips a typecheck error at the implementor, not silently in
|
|
17
|
-
* a caller. This replaced ad-hoc `as unknown as ReturnType<...>`
|
|
18
|
-
* casts in `Database.ts` that bridged the two classes.
|
|
10
|
+
* Both expose the same asynchronous surface — `put`, `get`, `getAll`,
|
|
11
|
+
* `delete`, `getAllFromIndex`, `clear`, and `markAsClosing` — so callers
|
|
12
|
+
* work against this interface and never branch on which concrete store they
|
|
13
|
+
* hold. Because both implementations are checked against one interface, any
|
|
14
|
+
* drift between them surfaces as a typecheck error at the store rather than
|
|
15
|
+
* a silent failure in a caller.
|
|
19
16
|
*/
|
|
20
17
|
export interface ObjectStoreContract {
|
|
21
18
|
/** Insert or update a record. The record must carry an `id` field. */
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Stores and manages sync actions received from the server.
|
|
5
|
-
* Critical for delta sync and maintaining sync state consistency.
|
|
2
|
+
* A local, IndexedDB-backed store for the sync actions (change deltas) the
|
|
3
|
+
* server sends. See {@link SyncActionStore}.
|
|
6
4
|
*/
|
|
7
5
|
import type { SyncAction } from '../types/index.js';
|
|
8
6
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* - Enables rewind/replay for conflict resolution
|
|
15
|
-
* - Maintains sync watermark
|
|
7
|
+
* Stores the sync actions (the change deltas) the server sends, keyed by
|
|
8
|
+
* their sync id, and tracks which ones have been applied. It keeps a
|
|
9
|
+
* watermark of the last applied id, holds not-yet-applied actions as
|
|
10
|
+
* pending, and can rewind a range of actions back to pending so they can be
|
|
11
|
+
* replayed while resolving a conflict.
|
|
16
12
|
*/
|
|
17
13
|
export declare class SyncActionStore {
|
|
18
14
|
private db;
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Stores and manages sync actions received from the server.
|
|
5
|
-
* Critical for delta sync and maintaining sync state consistency.
|
|
2
|
+
* A local, IndexedDB-backed store for the sync actions (change deltas) the
|
|
3
|
+
* server sends. See {@link SyncActionStore}.
|
|
6
4
|
*/
|
|
7
5
|
// Uses native IndexedDB for maximum performance
|
|
8
6
|
import { z } from 'zod';
|
|
9
7
|
import { getContext } from '../context.js';
|
|
10
8
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* (`storedAt
|
|
15
|
-
*
|
|
16
|
-
*
|
|
9
|
+
* The validation boundary for rows read back from the store. A row may have
|
|
10
|
+
* been written by an earlier session, so this build cannot assume its shape.
|
|
11
|
+
* Parsing in strip mode also drops the storage bookkeeping fields
|
|
12
|
+
* (`storedAt`, `applied`, `appliedAt`) that are not part of a
|
|
13
|
+
* {@link SyncAction}. A row that fails to parse is dropped and logged rather
|
|
14
|
+
* than replayed as a malformed delta.
|
|
17
15
|
*/
|
|
18
16
|
const storedSyncActionSchema = z.object({
|
|
19
17
|
id: z.number(),
|
|
@@ -35,13 +33,11 @@ function toSyncAction(row) {
|
|
|
35
33
|
return parsed.data;
|
|
36
34
|
}
|
|
37
35
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* - Enables rewind/replay for conflict resolution
|
|
44
|
-
* - Maintains sync watermark
|
|
36
|
+
* Stores the sync actions (the change deltas) the server sends, keyed by
|
|
37
|
+
* their sync id, and tracks which ones have been applied. It keeps a
|
|
38
|
+
* watermark of the last applied id, holds not-yet-applied actions as
|
|
39
|
+
* pending, and can rewind a range of actions back to pending so they can be
|
|
40
|
+
* replayed while resolving a conflict.
|
|
45
41
|
*/
|
|
46
42
|
export class SyncActionStore {
|
|
47
43
|
db;
|