@abloatai/ablo 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -2
- package/README.md +102 -86
- package/dist/BaseSyncedStore.d.ts +85 -88
- package/dist/BaseSyncedStore.js +134 -151
- package/dist/Database.d.ts +68 -69
- package/dist/Database.js +316 -135
- package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
- package/dist/{ObjectPool.js → InstanceCache.js} +85 -83
- package/dist/LazyReferenceCollection.d.ts +11 -15
- package/dist/LazyReferenceCollection.js +12 -16
- package/dist/Model.d.ts +54 -52
- package/dist/Model.js +78 -62
- package/dist/ModelRegistry.d.ts +21 -19
- package/dist/ModelRegistry.js +23 -27
- package/dist/NetworkMonitor.d.ts +5 -6
- package/dist/NetworkMonitor.js +5 -6
- package/dist/SyncClient.d.ts +122 -118
- package/dist/SyncClient.js +541 -245
- package/dist/adapters/alwaysOnline.d.ts +6 -8
- package/dist/adapters/alwaysOnline.js +6 -8
- package/dist/adapters/inMemoryStorage.d.ts +10 -9
- package/dist/adapters/inMemoryStorage.js +21 -9
- package/dist/agent/Agent.d.ts +27 -32
- package/dist/agent/Agent.js +18 -19
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +5 -5
- package/dist/agent/session.d.ts +47 -44
- package/dist/agent/session.js +37 -48
- package/dist/agent/types.d.ts +26 -31
- package/dist/agent/types.js +6 -7
- package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
- package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
- package/dist/ai-sdk/coordinationContext.d.ts +46 -0
- package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +26 -33
- package/dist/ai-sdk/index.d.ts +25 -22
- package/dist/ai-sdk/index.js +25 -22
- package/dist/ai-sdk/wrap.d.ts +6 -7
- package/dist/ai-sdk/wrap.js +1 -1
- package/dist/auth/credentialPolicy.d.ts +69 -74
- package/dist/auth/credentialPolicy.js +51 -56
- package/dist/auth/credentialSource.d.ts +6 -5
- package/dist/auth/credentialSource.js +9 -10
- package/dist/auth/index.d.ts +59 -58
- package/dist/auth/index.js +31 -37
- package/dist/auth/schemas.d.ts +5 -4
- package/dist/auth/schemas.js +5 -4
- package/dist/batching/index.d.ts +19 -21
- package/dist/batching/index.js +14 -17
- package/dist/cli.cjs +173 -121
- package/dist/client/Ablo.d.ts +97 -74
- package/dist/client/Ablo.js +129 -163
- package/dist/client/ApiClient.d.ts +30 -19
- package/dist/client/ApiClient.js +442 -81
- package/dist/client/auth.d.ts +47 -47
- package/dist/client/auth.js +108 -117
- package/dist/client/claimHeartbeatLoop.d.ts +50 -0
- package/dist/client/claimHeartbeatLoop.js +88 -0
- package/dist/client/consoleLogger.d.ts +5 -6
- package/dist/client/consoleLogger.js +5 -6
- package/dist/client/createInternalComponents.d.ts +16 -17
- package/dist/client/createInternalComponents.js +26 -31
- package/dist/client/createModelProxy.d.ts +130 -120
- package/dist/client/createModelProxy.js +152 -122
- package/dist/client/credentialEndpoint.d.ts +40 -42
- package/dist/client/credentialEndpoint.js +35 -36
- package/dist/client/functionalUpdate.d.ts +29 -27
- package/dist/client/functionalUpdate.js +21 -21
- package/dist/client/hostedEndpoints.d.ts +9 -12
- package/dist/client/hostedEndpoints.js +9 -12
- package/dist/client/httpClient.d.ts +59 -53
- package/dist/client/httpClient.js +29 -31
- package/dist/client/identity.d.ts +15 -20
- package/dist/client/identity.js +47 -58
- package/dist/client/modelRegistration.d.ts +5 -9
- package/dist/client/modelRegistration.js +78 -87
- package/dist/client/options.d.ts +157 -157
- package/dist/client/options.js +3 -7
- package/dist/client/registerDataSource.d.ts +9 -9
- package/dist/client/registerDataSource.js +15 -16
- package/dist/client/resourceTypes.d.ts +64 -75
- package/dist/client/resourceTypes.js +4 -10
- package/dist/client/schemaConfig.d.ts +31 -43
- package/dist/client/schemaConfig.js +38 -50
- package/dist/client/sessionMint.d.ts +16 -12
- package/dist/client/sessionMint.js +26 -31
- package/dist/client/validateAbloOptions.d.ts +12 -14
- package/dist/client/validateAbloOptions.js +8 -9
- package/dist/client/writeOptionsSchema.d.ts +18 -16
- package/dist/client/writeOptionsSchema.js +23 -20
- package/dist/client/wsMutationExecutor.d.ts +16 -20
- package/dist/client/wsMutationExecutor.js +18 -23
- package/dist/commit/contract.d.ts +493 -0
- package/dist/commit/contract.js +187 -0
- package/dist/commit/index.d.ts +6 -0
- package/dist/commit/index.js +5 -0
- package/dist/context.d.ts +6 -4
- package/dist/context.js +6 -4
- package/dist/coordination/index.d.ts +10 -8
- package/dist/coordination/index.js +14 -12
- package/dist/coordination/schema.d.ts +176 -128
- package/dist/coordination/schema.js +197 -133
- package/dist/coordination/trace.d.ts +9 -10
- package/dist/coordination/trace.js +13 -14
- package/dist/core/DatabaseManager.d.ts +5 -7
- package/dist/core/DatabaseManager.js +15 -19
- package/dist/core/QueryProcessor.d.ts +7 -9
- package/dist/core/QueryProcessor.js +22 -28
- package/dist/core/QueryView.d.ts +8 -8
- package/dist/core/QueryView.js +2 -2
- package/dist/core/StoreManager.d.ts +14 -14
- package/dist/core/StoreManager.js +33 -24
- package/dist/core/ViewRegistry.d.ts +5 -5
- package/dist/core/ViewRegistry.js +4 -4
- package/dist/core/index.d.ts +17 -12
- package/dist/core/index.js +32 -26
- package/dist/core/openIDBWithTimeout.d.ts +38 -36
- package/dist/core/openIDBWithTimeout.js +42 -43
- package/dist/core/queryUtils.d.ts +45 -0
- package/dist/core/queryUtils.js +69 -0
- package/dist/core/storeContract.d.ts +63 -61
- package/dist/core/storeContract.js +8 -12
- package/dist/environment.d.ts +28 -0
- package/dist/environment.js +21 -0
- package/dist/errorCodes.d.ts +107 -99
- package/dist/errorCodes.js +137 -134
- package/dist/errors.d.ts +160 -166
- package/dist/errors.js +155 -158
- package/dist/index.d.ts +36 -27
- package/dist/index.js +91 -86
- package/dist/interfaces/index.d.ts +102 -113
- package/dist/interfaces/index.js +5 -4
- package/dist/keys/index.d.ts +27 -29
- package/dist/keys/index.js +41 -40
- package/dist/mutators/RecordingTransaction.d.ts +16 -16
- package/dist/mutators/RecordingTransaction.js +31 -37
- package/dist/mutators/Transaction.d.ts +18 -26
- package/dist/mutators/Transaction.js +14 -20
- package/dist/mutators/UndoManager.d.ts +124 -131
- package/dist/mutators/UndoManager.js +177 -156
- package/dist/mutators/defineMutators.d.ts +23 -34
- package/dist/mutators/defineMutators.js +14 -20
- package/dist/mutators/inverseOp.d.ts +12 -15
- package/dist/mutators/inverseOp.js +12 -15
- package/dist/mutators/mutateActions.d.ts +10 -9
- package/dist/mutators/mutateActions.js +1 -1
- package/dist/mutators/readerActions.d.ts +9 -8
- package/dist/mutators/readerActions.js +2 -2
- package/dist/mutators/undoApply.d.ts +31 -27
- package/dist/mutators/undoApply.js +26 -24
- package/dist/policy/index.d.ts +5 -3
- package/dist/policy/index.js +5 -3
- package/dist/policy/types.d.ts +104 -100
- package/dist/policy/types.js +67 -66
- package/dist/query/client.d.ts +28 -23
- package/dist/query/client.js +45 -43
- package/dist/query/types.d.ts +37 -60
- package/dist/query/types.js +13 -33
- package/dist/react/AbloProvider.d.ts +1 -1
- package/dist/react/AbloProvider.js +2 -2
- package/dist/react/context.d.ts +25 -28
- package/dist/react/context.js +9 -10
- package/dist/react/index.d.ts +41 -42
- package/dist/react/index.js +37 -38
- package/dist/react/internalContext.d.ts +17 -19
- package/dist/react/useAblo.d.ts +28 -25
- package/dist/react/useAblo.js +41 -17
- package/dist/react/useCurrentUserId.d.ts +8 -7
- package/dist/react/useCurrentUserId.js +8 -7
- package/dist/react/useErrorListener.d.ts +7 -7
- package/dist/react/useErrorListener.js +10 -11
- package/dist/react/useMutationFailureListener.d.ts +8 -8
- package/dist/react/useMutationFailureListener.js +8 -8
- package/dist/react/useMutators.d.ts +11 -11
- package/dist/react/useMutators.js +3 -3
- package/dist/react/useReactive.js +2 -2
- package/dist/react/useSyncStatus.d.ts +4 -6
- package/dist/react/useUndoScope.d.ts +7 -9
- package/dist/react/useUndoScope.js +1 -1
- package/dist/schema/coordination.d.ts +21 -25
- package/dist/schema/coordination.js +21 -25
- package/dist/schema/ddl.d.ts +43 -39
- package/dist/schema/ddl.js +75 -68
- package/dist/schema/ddlLock.d.ts +20 -24
- package/dist/schema/ddlLock.js +18 -23
- package/dist/schema/diff.d.ts +99 -61
- package/dist/schema/diff.js +43 -34
- package/dist/schema/field.d.ts +37 -42
- package/dist/schema/field.js +35 -48
- package/dist/schema/generate.d.ts +12 -12
- package/dist/schema/generate.js +12 -12
- package/dist/schema/index.d.ts +3 -3
- package/dist/schema/index.js +21 -23
- package/dist/schema/model.d.ts +118 -143
- package/dist/schema/model.js +22 -33
- package/dist/schema/openapi.d.ts +10 -9
- package/dist/schema/openapi.js +5 -3
- package/dist/schema/queries.d.ts +29 -31
- package/dist/schema/queries.js +23 -25
- package/dist/schema/relation.d.ts +89 -99
- package/dist/schema/relation.js +13 -13
- package/dist/schema/residency.d.ts +16 -13
- package/dist/schema/residency.js +16 -13
- package/dist/schema/roles.d.ts +36 -43
- package/dist/schema/roles.js +31 -37
- package/dist/schema/schema.d.ts +64 -43
- package/dist/schema/schema.js +31 -32
- package/dist/schema/select.d.ts +13 -13
- package/dist/schema/select.js +13 -13
- package/dist/schema/serialize.d.ts +28 -31
- package/dist/schema/serialize.js +27 -31
- package/dist/schema/sugar.d.ts +17 -32
- package/dist/schema/sugar.js +14 -29
- package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +26 -49
- package/dist/schema/syncDeltaRow.js +89 -0
- package/dist/schema/tenancy.d.ts +44 -46
- package/dist/schema/tenancy.js +46 -48
- package/dist/server/adapter.d.ts +58 -58
- package/dist/server/adapter.js +13 -14
- package/dist/server/commit.d.ts +60 -64
- package/dist/server/index.d.ts +9 -10
- package/dist/server/index.js +1 -1
- package/dist/server/readConfig.d.ts +70 -0
- package/dist/server/readConfig.js +8 -0
- package/dist/server/storageMode.d.ts +23 -0
- package/dist/server/storageMode.js +17 -0
- package/dist/source/adapter.d.ts +30 -25
- package/dist/source/adapter.js +10 -10
- package/dist/source/adapters/drizzle.d.ts +28 -23
- package/dist/source/adapters/drizzle.js +30 -25
- package/dist/source/adapters/kysely.d.ts +27 -25
- package/dist/source/adapters/kysely.js +24 -23
- package/dist/source/adapters/memory.d.ts +8 -7
- package/dist/source/adapters/memory.js +9 -8
- package/dist/source/adapters/prisma.d.ts +13 -12
- package/dist/source/adapters/prisma.js +22 -25
- package/dist/source/conformance.d.ts +18 -11
- package/dist/source/conformance.js +17 -11
- package/dist/source/connector.d.ts +31 -32
- package/dist/source/connector.js +28 -28
- package/dist/source/connectorProtocol.d.ts +160 -0
- package/dist/source/connectorProtocol.js +162 -0
- package/dist/source/contract.d.ts +26 -27
- package/dist/source/contract.js +28 -29
- package/dist/source/factory.d.ts +46 -58
- package/dist/source/factory.js +22 -27
- package/dist/source/index.d.ts +7 -9
- package/dist/source/index.js +12 -14
- package/dist/source/migrations.d.ts +9 -9
- package/dist/source/migrations.js +9 -9
- package/dist/source/next.d.ts +9 -10
- package/dist/source/next.js +6 -7
- package/dist/source/pushQueue.d.ts +69 -47
- package/dist/source/pushQueue.js +32 -28
- package/dist/source/signing.d.ts +46 -17
- package/dist/source/signing.js +28 -11
- package/dist/source/types.d.ts +121 -104
- package/dist/source/types.js +13 -14
- package/dist/stores/ObjectStore.d.ts +24 -12
- package/dist/stores/ObjectStore.js +38 -16
- package/dist/stores/ObjectStoreContract.d.ts +14 -15
- package/dist/stores/SyncActionStore.d.ts +7 -11
- package/dist/stores/SyncActionStore.js +13 -17
- package/dist/surface.d.ts +28 -21
- package/dist/surface.js +29 -20
- package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +36 -42
- package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +76 -76
- package/dist/sync/ConnectionManager.d.ts +39 -50
- package/dist/sync/ConnectionManager.js +55 -66
- package/dist/sync/NetworkProbe.d.ts +24 -29
- package/dist/sync/NetworkProbe.js +63 -69
- package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +42 -41
- package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +59 -54
- package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +43 -57
- package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +43 -51
- package/dist/sync/SyncWebSocket.d.ts +141 -166
- package/dist/sync/SyncWebSocket.js +191 -223
- package/dist/sync/awaitClaimGrant.d.ts +18 -18
- package/dist/sync/awaitClaimGrant.js +11 -11
- package/dist/sync/bootstrapApply.d.ts +34 -24
- package/dist/sync/bootstrapApply.js +27 -19
- package/dist/sync/commitFrames.d.ts +21 -20
- package/dist/sync/commitFrames.js +18 -18
- package/dist/sync/createClaimStream.d.ts +23 -22
- package/dist/sync/createClaimStream.js +105 -23
- package/dist/sync/createPresenceStream.d.ts +19 -18
- package/dist/sync/createPresenceStream.js +25 -26
- package/dist/sync/createSnapshot.d.ts +12 -14
- package/dist/sync/createSnapshot.js +20 -26
- package/dist/sync/credentialLifecycle.d.ts +104 -104
- package/dist/sync/credentialLifecycle.js +140 -147
- package/dist/sync/deltaPipeline.d.ts +36 -34
- package/dist/sync/deltaPipeline.js +64 -65
- package/dist/sync/groupChange.d.ts +63 -61
- package/dist/sync/groupChange.js +74 -78
- package/dist/sync/heartbeat.d.ts +34 -33
- package/dist/sync/heartbeat.js +31 -31
- package/dist/sync/participants.d.ts +19 -19
- package/dist/sync/persistedPrefix.d.ts +12 -0
- package/dist/sync/persistedPrefix.js +22 -0
- package/dist/sync/schemas.d.ts +3 -2
- package/dist/sync/schemas.js +14 -10
- package/dist/sync/syncCursor.d.ts +17 -21
- package/dist/sync/syncCursor.js +17 -21
- package/dist/sync/syncPlan.d.ts +28 -36
- package/dist/sync/syncPlan.js +18 -19
- package/dist/sync/syncPosition.d.ts +54 -49
- package/dist/sync/syncPosition.js +57 -52
- package/dist/sync/wsFrameHandlers.d.ts +35 -36
- package/dist/sync/wsFrameHandlers.js +63 -67
- package/dist/testing/fixtures/bootstrap.d.ts +12 -6
- package/dist/testing/fixtures/bootstrap.js +12 -6
- package/dist/testing/fixtures/deltas.d.ts +30 -33
- package/dist/testing/fixtures/deltas.js +30 -33
- package/dist/testing/fixtures/models.d.ts +11 -10
- package/dist/testing/fixtures/models.js +11 -10
- package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
- package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
- package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -15
- package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +12 -10
- package/dist/testing/helpers/wait.d.ts +13 -8
- package/dist/testing/helpers/wait.js +13 -8
- package/dist/testing/index.d.ts +5 -3
- package/dist/testing/index.js +3 -2
- package/dist/testing/mocks/FakeDatabase.d.ts +18 -0
- package/dist/testing/mocks/FakeDatabase.js +10 -0
- package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
- package/dist/testing/mocks/MockMutationExecutor.js +15 -14
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
- package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
- package/dist/testing/mocks/MockSyncContext.d.ts +20 -17
- package/dist/testing/mocks/MockSyncContext.js +15 -13
- package/dist/testing/mocks/MockSyncStore.d.ts +10 -10
- package/dist/testing/mocks/MockSyncStore.js +11 -11
- package/dist/testing/mocks/MockWebSocket.d.ts +28 -23
- package/dist/testing/mocks/MockWebSocket.js +22 -21
- package/dist/transactions/TransactionQueue.d.ts +244 -181
- package/dist/transactions/TransactionQueue.js +929 -423
- package/dist/transactions/TransactionStore.d.ts +6 -4
- package/dist/transactions/TransactionStore.js +6 -4
- package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
- package/dist/transactions/UnconfirmedWrites.js +104 -0
- package/dist/transactions/coalesceRules.d.ts +41 -17
- package/dist/transactions/coalesceRules.js +40 -17
- package/dist/transactions/commitEnvelope.d.ts +132 -0
- package/dist/transactions/commitEnvelope.js +139 -0
- package/dist/transactions/commitOutboxStore.d.ts +32 -0
- package/dist/transactions/commitOutboxStore.js +26 -0
- package/dist/transactions/commitPayload.d.ts +63 -52
- package/dist/transactions/commitPayload.js +54 -57
- package/dist/transactions/deltaConfirmation.d.ts +20 -22
- package/dist/transactions/deltaConfirmation.js +37 -45
- package/dist/transactions/httpCommitEnvelope.d.ts +43 -0
- package/dist/transactions/httpCommitEnvelope.js +179 -0
- package/dist/transactions/optimisticApply.d.ts +49 -0
- package/dist/transactions/optimisticApply.js +65 -0
- package/dist/transactions/replayValidation.d.ts +182 -0
- package/dist/transactions/replayValidation.js +156 -0
- package/dist/types/global.d.ts +46 -41
- package/dist/types/global.js +20 -19
- package/dist/types/index.d.ts +71 -77
- package/dist/types/index.js +22 -22
- package/dist/types/modelData.d.ts +6 -8
- package/dist/types/modelData.js +5 -7
- package/dist/types/participant.d.ts +10 -11
- package/dist/types/participant.js +6 -8
- package/dist/types/streams.d.ts +208 -195
- package/dist/types/streams.js +7 -7
- package/dist/utils/asyncIterator.d.ts +25 -32
- package/dist/utils/asyncIterator.js +25 -32
- package/dist/utils/duration.d.ts +12 -15
- package/dist/utils/duration.js +12 -15
- package/dist/utils/mobxSetup.d.ts +53 -0
- package/dist/utils/{mobx-setup.js → mobxSetup.js} +42 -98
- package/dist/webhooks/events.d.ts +21 -16
- package/dist/webhooks/events.js +10 -8
- package/dist/webhooks/index.d.ts +5 -7
- package/dist/webhooks/index.js +5 -7
- package/dist/wire/bootstrapReason.d.ts +9 -0
- package/dist/wire/bootstrapReason.js +8 -0
- package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
- package/dist/wire/delta.js +114 -0
- package/dist/wire/errorEnvelope.d.ts +30 -31
- package/dist/wire/errorEnvelope.js +34 -40
- package/dist/wire/frames.d.ts +315 -86
- package/dist/wire/frames.js +47 -33
- package/dist/wire/index.d.ts +18 -14
- package/dist/wire/index.js +32 -27
- package/dist/wire/listEnvelope.d.ts +16 -23
- package/dist/wire/listEnvelope.js +7 -6
- package/dist/wire/protocol.d.ts +25 -32
- package/dist/wire/protocol.js +25 -32
- package/dist/wire/protocolVersion.d.ts +44 -40
- package/dist/wire/protocolVersion.js +44 -40
- package/docs/api.md +10 -10
- package/docs/coordination.md +59 -0
- package/docs/mcp.md +1 -1
- package/package.json +17 -11
- package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
- package/dist/ai-sdk/coordination-context.d.ts +0 -52
- package/dist/core/query-utils.d.ts +0 -34
- package/dist/core/query-utils.js +0 -59
- package/dist/schema/sync-delta-row.js +0 -103
- package/dist/schema/sync-delta-wire.js +0 -102
- package/dist/server/read-config.d.ts +0 -67
- package/dist/server/read-config.js +0 -8
- package/dist/server/storage-mode.d.ts +0 -8
- package/dist/server/storage-mode.js +0 -28
- package/dist/source/connector-protocol.d.ts +0 -159
- package/dist/source/connector-protocol.js +0 -161
- package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
- package/dist/transactions/OptimisticEchoTracker.js +0 -104
- package/dist/transactions/mutation-error-handler.d.ts +0 -5
- package/dist/transactions/mutation-error-handler.js +0 -39
- package/dist/transactions/optimistic.d.ts +0 -24
- package/dist/transactions/optimistic.js +0 -45
- package/dist/transactions/persistedReplay.d.ts +0 -93
- package/dist/transactions/persistedReplay.js +0 -105
- package/dist/utils/mobx-setup.d.ts +0 -42
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TransactionQueue
|
|
2
|
+
* TransactionQueue manages the lifecycle of local writes on their way to the
|
|
3
|
+
* server: it applies each change optimistically, batches the writes made in one
|
|
4
|
+
* event-loop tick into a single commit, retries transient failures, and rolls
|
|
5
|
+
* back on permanent rejection.
|
|
3
6
|
*
|
|
4
|
-
* Key
|
|
5
|
-
* - Optimistic updates with rollback
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
*
|
|
7
|
+
* Key behaviours:
|
|
8
|
+
* - Optimistic updates with rollback on failure.
|
|
9
|
+
* - Configurable conflict resolution.
|
|
10
|
+
* - Microtask batching: transactions created in the same event-loop tick share
|
|
11
|
+
* a batch id and commit together in one round trip.
|
|
12
|
+
* - A dependency-injected executor, so several queues can coexist.
|
|
9
13
|
*/
|
|
10
14
|
import { EventEmitter } from 'events';
|
|
11
15
|
import type { Database } from '../Database.js';
|
|
@@ -14,22 +18,23 @@ import { SyncPosition } from '../sync/syncPosition.js';
|
|
|
14
18
|
import type { WriteOptions } from '../interfaces/index.js';
|
|
15
19
|
import type { StaleNotification, ReadDependency } from '../coordination/schema.js';
|
|
16
20
|
import { type MutationInput, type Transaction, type UserContext } from './commitPayload.js';
|
|
21
|
+
import { type DurableCommitEnvelope, type DurableCommitOperation, type CommitOutboxScope } from './commitEnvelope.js';
|
|
22
|
+
import type { CommitOutboxStore } from './commitOutboxStore.js';
|
|
17
23
|
export type { Transaction, UserContext } from './commitPayload.js';
|
|
18
24
|
/**
|
|
19
|
-
* A
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* batch path, so reconnect-retry behavior is identical.
|
|
25
|
+
* A pre-built, multi-operation commit submitted through
|
|
26
|
+
* `ablo.commits.create()`. Unlike the per-model {@link Transaction} (see
|
|
27
|
+
* `./commitPayload.js`), the caller supplies the operations and the whole
|
|
28
|
+
* envelope commits atomically: the queue does not coalesce it, reorder its
|
|
29
|
+
* operations for foreign keys, or apply it optimistically. It runs through the
|
|
30
|
+
* same `mutationExecutor.commit()` as the model batch path, so its
|
|
31
|
+
* retry-on-reconnect behaviour is identical.
|
|
27
32
|
*/
|
|
28
33
|
interface CommitTransaction {
|
|
29
34
|
id: string;
|
|
30
35
|
kind: 'commit';
|
|
31
36
|
operations: {
|
|
32
|
-
type:
|
|
37
|
+
type: DurableCommitOperation['type'];
|
|
33
38
|
model: string;
|
|
34
39
|
id: string;
|
|
35
40
|
input?: Record<string, unknown>;
|
|
@@ -38,13 +43,19 @@ interface CommitTransaction {
|
|
|
38
43
|
onStale?: 'reject' | 'overwrite' | 'notify' | null;
|
|
39
44
|
}[];
|
|
40
45
|
causedByTaskId?: string | null;
|
|
41
|
-
/**
|
|
46
|
+
/** Read dependencies for the whole batch, forwarded to the executor so the server can detect stale-context writes. */
|
|
42
47
|
reads?: ReadDependency[] | null;
|
|
43
48
|
status: 'pending' | 'executing' | 'completed' | 'failed';
|
|
44
49
|
createdAt: number;
|
|
45
50
|
attempts: number;
|
|
46
51
|
lastSyncId?: number;
|
|
47
52
|
error?: Error;
|
|
53
|
+
sealedAt: number;
|
|
54
|
+
sequence: number;
|
|
55
|
+
sealPromise?: Promise<void>;
|
|
56
|
+
durableEnvelope?: DurableCommitEnvelope;
|
|
57
|
+
/** Journal entries atomically consumed when this request was sealed. */
|
|
58
|
+
sourceMutationIds?: string[];
|
|
48
59
|
}
|
|
49
60
|
interface ConflictResolution {
|
|
50
61
|
strategy: 'last-write-wins' | 'merge' | 'reject' | 'custom';
|
|
@@ -72,21 +83,21 @@ interface TransactionQueueConfig {
|
|
|
72
83
|
capMs: number;
|
|
73
84
|
};
|
|
74
85
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* jitter
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* batch workers (e.g. 60s for agent-worker).
|
|
86
|
+
* How long, in milliseconds, to wait after the connection drops before
|
|
87
|
+
* failing any in-flight commit-lane transaction with an
|
|
88
|
+
* {@link AbloConnectionError}. Brief disconnects, such as a server restart
|
|
89
|
+
* or mobile network jitter, are absorbed transparently; only a disconnect
|
|
90
|
+
* that outlasts this window surfaces as a failure. Set it lower for
|
|
91
|
+
* interactive use (for example 10 seconds for chat) and higher for
|
|
92
|
+
* background batch work. Defaults to 30 seconds.
|
|
83
93
|
*
|
|
84
|
-
* Without this deadline, `commits.create({wait:'confirmed'})`
|
|
85
|
-
* forever
|
|
94
|
+
* Without this deadline, `commits.create({ wait: 'confirmed' })` would wait
|
|
95
|
+
* forever if the connection died while a commit was in flight.
|
|
86
96
|
*/
|
|
87
97
|
commitOfflineGraceMs: number;
|
|
88
98
|
}
|
|
89
99
|
export declare class TransactionQueue extends EventEmitter {
|
|
100
|
+
private static readonly DURABLE_REPLAY_WINDOW_MS;
|
|
90
101
|
private store;
|
|
91
102
|
private lastPermanentErrorSig?;
|
|
92
103
|
private _mutationExecutor;
|
|
@@ -103,6 +114,15 @@ export declare class TransactionQueue extends EventEmitter {
|
|
|
103
114
|
private commitLane;
|
|
104
115
|
private commitStore;
|
|
105
116
|
private commitProcessing;
|
|
117
|
+
private lastCommitSequence;
|
|
118
|
+
private durableReplayBlock;
|
|
119
|
+
/** Browser-backed strict outbox; absent for standalone/in-memory consumers. */
|
|
120
|
+
private commitOutbox;
|
|
121
|
+
private commitOutboxScope;
|
|
122
|
+
private nextCommitSequence;
|
|
123
|
+
private emitCommitLifecycle;
|
|
124
|
+
private assertDurableReplayOpen;
|
|
125
|
+
private assertEnvelopeInsideReplayWindow;
|
|
106
126
|
private computePriorityScore;
|
|
107
127
|
private ensureDerivedFields;
|
|
108
128
|
private entityKey;
|
|
@@ -121,17 +141,49 @@ export declare class TransactionQueue extends EventEmitter {
|
|
|
121
141
|
private isConnectedFn;
|
|
122
142
|
private commitOfflineGraceTimer;
|
|
123
143
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* queue advances `acked`
|
|
127
|
-
* `applied
|
|
128
|
-
*
|
|
144
|
+
* This client's place in the global order of sync deltas. The instance is
|
|
145
|
+
* shared: the client injects one, and a standalone queue creates its own. The
|
|
146
|
+
* queue advances the `acked` cursor as commit responses arrive, the store
|
|
147
|
+
* advances `applied` and `persisted`, and snapshots and claims read
|
|
148
|
+
* `readFloor`. See `../sync/syncPosition.js` for the full contract.
|
|
129
149
|
*/
|
|
130
150
|
readonly position: SyncPosition;
|
|
131
151
|
/** Applied-cursor alias, kept so the many internal read sites stay legible. */
|
|
132
152
|
private get lastSeenSyncId();
|
|
133
153
|
private noteAck;
|
|
134
154
|
private batchIndex;
|
|
155
|
+
/** Mints the request identity once; retry paths only read the stored value. */
|
|
156
|
+
private generateCommitIdempotencyKey;
|
|
157
|
+
/**
|
|
158
|
+
* Binds an ordered transaction batch to one wire-level idempotency key.
|
|
159
|
+
* Existing envelopes are validated and restored to their original order;
|
|
160
|
+
* they are never extended with newly queued work.
|
|
161
|
+
*/
|
|
162
|
+
private ensureCommitEnvelope;
|
|
163
|
+
/** Bind the strict local outbox used before any mutation reaches the wire. */
|
|
164
|
+
setCommitOutbox(outbox: CommitOutboxStore): void;
|
|
165
|
+
setCommitOutboxScope(scope: CommitOutboxScope): void;
|
|
166
|
+
private sourceMutationIdsFor;
|
|
167
|
+
/**
|
|
168
|
+
* Atomically replaces staged mutation journal rows with one exact request.
|
|
169
|
+
* The returned operations are the JSON-normalized values that must be sent;
|
|
170
|
+
* callers never send a separately reconstructed payload after sealing.
|
|
171
|
+
*/
|
|
172
|
+
private sealDurableCommit;
|
|
173
|
+
/** Best-effort cleanup after a definitive result; replay is safe if it fails. */
|
|
174
|
+
private removeDurableCommit;
|
|
175
|
+
/**
|
|
176
|
+
* Takes either one complete retry envelope or a fresh batch. A retry waits
|
|
177
|
+
* until every original member has re-entered the queue, preventing an
|
|
178
|
+
* ambiguous A+B commit from being replayed later as A and B separately.
|
|
179
|
+
*/
|
|
180
|
+
private takeNextExecutionBatch;
|
|
181
|
+
/**
|
|
182
|
+
* Selects one reconnect batch without changing the request identity of work
|
|
183
|
+
* that was already attempted. Explicit caller keys remain one-call batches;
|
|
184
|
+
* an existing envelope is replayed only with all of its original members.
|
|
185
|
+
*/
|
|
186
|
+
private takeOfflineFlushBatch;
|
|
135
187
|
/**
|
|
136
188
|
* Resolvers for per-transaction `confirmation` promises. Populated in
|
|
137
189
|
* `attachConfirmation` at staging time, consumed by the constructor-time
|
|
@@ -142,99 +194,104 @@ export declare class TransactionQueue extends EventEmitter {
|
|
|
142
194
|
private confirmationResolvers;
|
|
143
195
|
constructor(config?: Partial<TransactionQueueConfig>);
|
|
144
196
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
* outcomes for the routing-helper grace-window use case).
|
|
150
|
-
*
|
|
151
|
-
* Looks across `pending`, `executing`, and `awaiting_delta` — these
|
|
152
|
-
* are the three non-terminal statuses where rollback is still
|
|
153
|
-
* possible. Skips `completed` (already settled) and `failed` /
|
|
154
|
-
* `rolled_back` (already rejected; the call site missed the
|
|
155
|
-
* `confirmation` window and should rely on `onMutationFailure` toast
|
|
156
|
-
* instead).
|
|
197
|
+
* Returns the in-flight confirmation promise for a given model and id. When
|
|
198
|
+
* several transactions match, it returns the most recent one's promise; when
|
|
199
|
+
* none is open it resolves immediately, which covers both "already confirmed"
|
|
200
|
+
* and "never staged".
|
|
157
201
|
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
* `
|
|
202
|
+
* It considers the three non-terminal statuses in which the write can still
|
|
203
|
+
* be rolled back — `pending`, `executing`, and `awaiting_delta` — and ignores
|
|
204
|
+
* `completed` (already settled) and `failed`/`rolled_back` (already
|
|
205
|
+
* rejected). This complements the `confirmation` promise carried on a known
|
|
206
|
+
* {@link Transaction}: use this method at call sites that hold a model
|
|
207
|
+
* returned by `ablo.<model>.create()` but never see the underlying
|
|
208
|
+
* transaction.
|
|
161
209
|
*/
|
|
162
210
|
confirmationFor(modelName: string, modelId: string): Promise<void>;
|
|
163
211
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
212
|
+
* Attaches a `confirmation` promise to a newly created transaction. Call this
|
|
213
|
+
* before the transaction is staged so a caller can `await tx.confirmation`
|
|
214
|
+
* immediately after a create, update, or delete returns. It is idempotent and
|
|
215
|
+
* returns early if one is already attached.
|
|
168
216
|
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
* rejection.
|
|
172
|
-
* `.then`/`.catch
|
|
217
|
+
* It also attaches a no-op rejection handler. Most callers never await the
|
|
218
|
+
* confirmation, and without this the runtime would report an unhandled
|
|
219
|
+
* rejection when a write fails. Callers that do want to observe failure simply
|
|
220
|
+
* attach their own `.then`/`.catch`.
|
|
173
221
|
*/
|
|
174
222
|
private attachConfirmation;
|
|
175
223
|
/**
|
|
176
|
-
*
|
|
177
|
-
*
|
|
224
|
+
* Registers a predicate the queue uses to check whether it is connected.
|
|
225
|
+
* While disconnected, confirmation timeouts re-schedule themselves instead of
|
|
226
|
+
* escalating, so a transaction is never rolled back merely because the client
|
|
227
|
+
* was briefly offline.
|
|
178
228
|
*/
|
|
179
229
|
setConnectionChecker(fn: () => boolean): void;
|
|
180
230
|
/**
|
|
181
|
-
*
|
|
231
|
+
* Drives the offline-grace timer for in-flight commit-lane transactions.
|
|
182
232
|
*
|
|
183
|
-
* On `'disconnected'
|
|
184
|
-
* `config.commitOfflineGraceMs`. If
|
|
185
|
-
*
|
|
186
|
-
* `
|
|
187
|
-
*
|
|
188
|
-
* lets `waitForCommitReceipt` reject in seconds instead of hanging
|
|
189
|
-
* forever — which is what wedged the 2026-05-15 subagent run.
|
|
233
|
+
* On `'disconnected'` it starts a one-shot timer of
|
|
234
|
+
* `config.commitOfflineGraceMs`. If that timer fires — meaning the disconnect
|
|
235
|
+
* outlasted the grace window — every commit-lane transaction still `pending`
|
|
236
|
+
* or `executing` is failed with an {@link AbloConnectionError}, so
|
|
237
|
+
* {@link waitForCommitReceipt} rejects within seconds instead of hanging.
|
|
190
238
|
*
|
|
191
|
-
* On `'connected'
|
|
192
|
-
* absorbed transparently;
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
* Called from SyncClient's `setConnectionState` after the
|
|
196
|
-
* `'connection:disconnected'` / `'connection:established'` events.
|
|
239
|
+
* On `'connected'` it clears any pending grace timer. Brief disconnects are
|
|
240
|
+
* absorbed transparently; {@link processCommitLane} and
|
|
241
|
+
* {@link flushOfflineQueue} resume the work on reconnect.
|
|
197
242
|
*/
|
|
198
243
|
setConnectionState(state: 'connected' | 'disconnected'): void;
|
|
199
244
|
private failInFlightCommitsOnOffline;
|
|
200
245
|
/**
|
|
201
|
-
*
|
|
202
|
-
* right after
|
|
203
|
-
*
|
|
204
|
-
*
|
|
246
|
+
* Binds the mutation executor for this queue instance. The owning client
|
|
247
|
+
* calls this right after construction, so commits made here always dispatch
|
|
248
|
+
* through this instance's connection even when several client instances exist
|
|
249
|
+
* in the same process.
|
|
205
250
|
*/
|
|
206
251
|
setMutationExecutor(executor: import('../interfaces/index.js').MutationExecutor): void;
|
|
207
252
|
/**
|
|
208
|
-
*
|
|
209
|
-
*
|
|
253
|
+
* Stages a transaction for commit. Transactions staged within the same
|
|
254
|
+
* event-loop tick are committed together.
|
|
210
255
|
*/
|
|
211
256
|
private stageTransaction;
|
|
212
257
|
/**
|
|
213
|
-
*
|
|
214
|
-
*
|
|
258
|
+
* Schedules the staged transactions to commit on a microtask, so all
|
|
259
|
+
* transactions created synchronously within one tick are batched together.
|
|
215
260
|
*/
|
|
216
261
|
private scheduleCommit;
|
|
217
262
|
/**
|
|
218
|
-
*
|
|
219
|
-
*
|
|
263
|
+
* Moves all staged transactions onto the execution queue, assigning them a
|
|
264
|
+
* single shared batch index so they commit together.
|
|
220
265
|
*/
|
|
221
266
|
private commitCreatedTransactions;
|
|
267
|
+
/**
|
|
268
|
+
* Flushes every pending transaction in one commit, the fast path taken on
|
|
269
|
+
* reconnect. If transport fails, the transactions retain this exact commit
|
|
270
|
+
* envelope when they fall back to normal queue processing.
|
|
271
|
+
*/
|
|
222
272
|
flushOfflineQueue(): Promise<void>;
|
|
223
273
|
/**
|
|
224
|
-
*
|
|
274
|
+
* Records a create and applies it optimistically, then stages it for the next
|
|
275
|
+
* batched commit. Returns the {@link Transaction}, whose `confirmation`
|
|
276
|
+
* promise settles once the server confirms the write.
|
|
225
277
|
*/
|
|
226
|
-
create(model: Model, context: UserContext, writeOptions?: WriteOptions): Promise<Transaction>;
|
|
278
|
+
create(model: Model, context: UserContext, writeOptions?: WriteOptions, sourceMutationId?: string): Promise<Transaction>;
|
|
227
279
|
/**
|
|
228
|
-
*
|
|
229
|
-
*
|
|
280
|
+
* Records an update and applies it optimistically, then stages it for the next
|
|
281
|
+
* batched commit. Rapid updates to the same entity coalesce into a single wire
|
|
282
|
+
* operation.
|
|
283
|
+
* @param precomputedChanges - Optional pre-captured changes, used instead of re-reading them from the model.
|
|
230
284
|
*/
|
|
231
|
-
update(model: Model, context: UserContext, precomputedChanges?: Record<string, unknown>, writeOptions?: WriteOptions): Promise<Transaction>;
|
|
285
|
+
update(model: Model, context: UserContext, precomputedChanges?: Record<string, unknown>, writeOptions?: WriteOptions, sourceMutationId?: string): Promise<Transaction>;
|
|
232
286
|
/**
|
|
233
|
-
*
|
|
287
|
+
* Records a delete and applies it optimistically. If the row's own create has
|
|
288
|
+
* not yet been sent, both are cancelled locally rather than sending a create
|
|
289
|
+
* followed by a delete; if the create is already in flight, the delete waits
|
|
290
|
+
* until it settles so the server never sees a delete before the create.
|
|
234
291
|
*/
|
|
235
|
-
delete(model: Model, context: UserContext, writeOptions?: WriteOptions): Promise<Transaction>;
|
|
292
|
+
delete(model: Model, context: UserContext, writeOptions?: WriteOptions, sourceMutationId?: string): Promise<Transaction>;
|
|
236
293
|
/**
|
|
237
|
-
*
|
|
294
|
+
* Uploads a single attachment, delegating to the mutation executor.
|
|
238
295
|
*/
|
|
239
296
|
uploadAttachment(_file: File, options: {
|
|
240
297
|
id: string;
|
|
@@ -243,7 +300,7 @@ export declare class TransactionQueue extends EventEmitter {
|
|
|
243
300
|
url: string;
|
|
244
301
|
} | null>;
|
|
245
302
|
/**
|
|
246
|
-
*
|
|
303
|
+
* Uploads several attachments in one call, delegating to the mutation executor.
|
|
247
304
|
*/
|
|
248
305
|
batchUploadAttachments(_files: File[], items: {
|
|
249
306
|
id: string;
|
|
@@ -253,66 +310,69 @@ export declare class TransactionQueue extends EventEmitter {
|
|
|
253
310
|
url: string;
|
|
254
311
|
}[]>;
|
|
255
312
|
/**
|
|
256
|
-
*
|
|
313
|
+
* Records an archive and applies it optimistically, then stages it for the
|
|
314
|
+
* next batched commit.
|
|
257
315
|
*/
|
|
258
|
-
archive(model: Model, context: UserContext, writeOptions?: WriteOptions): Promise<Transaction>;
|
|
316
|
+
archive(model: Model, context: UserContext, writeOptions?: WriteOptions, sourceMutationId?: string): Promise<Transaction>;
|
|
259
317
|
/**
|
|
260
|
-
*
|
|
318
|
+
* Records an unarchive and applies it optimistically, then stages it for the
|
|
319
|
+
* next batched commit.
|
|
261
320
|
*/
|
|
262
321
|
unarchive(model: Model, context: UserContext): Promise<Transaction>;
|
|
263
322
|
/**
|
|
264
|
-
*
|
|
323
|
+
* Places a transaction on the execution queue, coalescing it into an existing
|
|
324
|
+
* same-entity update where possible so redundant writes collapse.
|
|
265
325
|
*/
|
|
266
326
|
private enqueue;
|
|
267
327
|
private scheduleProcessing;
|
|
268
328
|
/**
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
* This reduces N round-trips to 1, dramatically improving batch latency.
|
|
329
|
+
* Processes one batch of transactions in a single commit. Rather than calling
|
|
330
|
+
* the server once per operation type or model, it collects every batchable
|
|
331
|
+
* operation and sends them together; the server applies the mixed operations
|
|
332
|
+
* atomically within one transaction. This turns many round trips into one and
|
|
333
|
+
* greatly reduces batch latency.
|
|
276
334
|
*/
|
|
277
335
|
private processBatch;
|
|
278
336
|
/**
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
* @param syncId - The sync
|
|
337
|
+
* Confirms every awaiting transaction whose sync-id threshold this delta meets
|
|
338
|
+
* or exceeds. The confirmation policy and timeout tracking live in
|
|
339
|
+
* {@link DeltaConfirmationTracker} (`./deltaConfirmation.js`).
|
|
340
|
+
* @param syncId - The sync id of the received delta.
|
|
283
341
|
*/
|
|
284
342
|
onDeltaReceived(syncId: number): void;
|
|
285
343
|
private scheduleDeltaConfirmationTimeout;
|
|
286
344
|
/**
|
|
287
|
-
*
|
|
288
|
-
*
|
|
345
|
+
* Resolves once the given transaction is confirmed and rejects if it fails.
|
|
346
|
+
* The confirming delta's timeout is handled by
|
|
347
|
+
* {@link scheduleDeltaConfirmationTimeout}.
|
|
289
348
|
*/
|
|
290
349
|
waitForConfirmation(transactionId: string): Promise<void>;
|
|
291
350
|
hasClientMutationId(id: string): boolean;
|
|
292
351
|
/**
|
|
293
|
-
*
|
|
294
|
-
* path
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
352
|
+
* Enqueues a pre-built, multi-operation atomic commit — the
|
|
353
|
+
* `ablo.commits.create()` path. The caller supplies the operations; the queue
|
|
354
|
+
* only retries on reconnect and de-duplicates, and does not apply the change
|
|
355
|
+
* optimistically or reorder for foreign keys. A duplicate `clientTxId`
|
|
356
|
+
* already in flight is ignored: the server's `mutation_log` de-duplicates
|
|
357
|
+
* across sessions, and this guard covers a double-enqueue within one session.
|
|
299
358
|
*/
|
|
300
359
|
enqueueCommit(clientTxId: string, operations: CommitTransaction['operations'], options?: {
|
|
301
360
|
causedByTaskId?: string | null;
|
|
302
361
|
reads?: ReadDependency[] | null;
|
|
303
|
-
}): void
|
|
362
|
+
}): Promise<void>;
|
|
304
363
|
/**
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
364
|
+
* Drains the pending commit-lane envelopes one at a time. A transient
|
|
365
|
+
* failure, such as a network error, leaves the envelope at the head of the
|
|
366
|
+
* lane in `pending` and stops; reconnect re-kicks it through
|
|
367
|
+
* {@link flushOfflineQueue}. A permanent failure emits
|
|
368
|
+
* `transaction:failed:<id>` and drops the envelope.
|
|
309
369
|
*/
|
|
310
370
|
private processCommitLane;
|
|
311
371
|
/**
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
372
|
+
* Resolves once a commit-lane transaction is confirmed, returning the server's
|
|
373
|
+
* `lastSyncId` and any stale-context notifications; rejects on permanent
|
|
374
|
+
* failure. This backs the `wait: 'confirmed'` semantics of
|
|
375
|
+
* `ablo.commits.create()`.
|
|
316
376
|
*/
|
|
317
377
|
waitForCommitReceipt(clientTxId: string): Promise<{
|
|
318
378
|
lastSyncId: number;
|
|
@@ -320,88 +380,92 @@ export declare class TransactionQueue extends EventEmitter {
|
|
|
320
380
|
}>;
|
|
321
381
|
private isReorderPayload;
|
|
322
382
|
/**
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
383
|
+
* Classifies an error as transient (worth retrying) or permanent. The
|
|
384
|
+
* approach is deliberately conservative: only known-transient errors are
|
|
385
|
+
* retried, and anything unrecognized is treated as permanent so a failing
|
|
386
|
+
* write cannot loop forever.
|
|
327
387
|
*
|
|
328
|
-
* Transient
|
|
329
|
-
* - Network failures, connection errors, timeouts
|
|
330
|
-
* - Server errors (5xx
|
|
331
|
-
* - Rate limiting (429)
|
|
388
|
+
* Transient (retried):
|
|
389
|
+
* - Network failures, connection errors, and timeouts.
|
|
390
|
+
* - Server errors (HTTP 5xx).
|
|
391
|
+
* - Rate limiting (HTTP 429).
|
|
332
392
|
*
|
|
333
|
-
* Permanent
|
|
334
|
-
* - Validation errors
|
|
335
|
-
* - Not found, unauthorized, forbidden
|
|
336
|
-
* - Any other business
|
|
393
|
+
* Permanent (not retried), among others:
|
|
394
|
+
* - Validation errors and constraint violations.
|
|
395
|
+
* - Not found, unauthorized, and forbidden.
|
|
396
|
+
* - Any other business-logic error from the server.
|
|
337
397
|
*/
|
|
338
398
|
private isPermanentError;
|
|
399
|
+
/** True only when the server definitively rejected before applying. */
|
|
400
|
+
private isDefinitiveRejection;
|
|
339
401
|
/**
|
|
340
|
-
*
|
|
402
|
+
* Handles a failed transaction: retries transient failures with backoff and
|
|
403
|
+
* rolls back permanent ones, settling the transaction's confirmation promise
|
|
404
|
+
* either way.
|
|
341
405
|
*/
|
|
342
406
|
private handleFailure;
|
|
343
407
|
/**
|
|
344
|
-
*
|
|
408
|
+
* Resolves a conflict against server data using the configured strategy:
|
|
409
|
+
* last-write-wins rolls the local change back, merge and reject re-enqueue it,
|
|
410
|
+
* and custom applies the caller's resolver.
|
|
345
411
|
*/
|
|
346
412
|
handleConflict(transaction: Transaction, serverData: MutationInput): Promise<void>;
|
|
347
413
|
/**
|
|
348
|
-
* Optimistic updates
|
|
349
|
-
* these
|
|
414
|
+
* Optimistic updates. The apply and rollback rules live in `./optimisticApply.js`;
|
|
415
|
+
* these methods bind them to the queue's own tracking map and event emitter.
|
|
350
416
|
*/
|
|
351
417
|
private applyOptimisticCreate;
|
|
352
418
|
private applyOptimisticUpdate;
|
|
353
419
|
private applyOptimisticDelete;
|
|
354
420
|
private rollbackOptimistic;
|
|
355
421
|
/**
|
|
356
|
-
*
|
|
422
|
+
* Loads transactions persisted from a previous session and re-enqueues them,
|
|
423
|
+
* so writes made while offline survive a restart. Does nothing when
|
|
424
|
+
* persistence is disabled.
|
|
357
425
|
*/
|
|
358
|
-
|
|
426
|
+
loadPersistedTransactions(database: Database): Promise<void>;
|
|
359
427
|
/**
|
|
360
|
-
*
|
|
428
|
+
* Restore exact sealed requests after the local database is open. Sealed
|
|
429
|
+
* envelopes replay through the atomic commit lane and are never re-projected
|
|
430
|
+
* through model/schema state from the new process.
|
|
361
431
|
*/
|
|
362
|
-
|
|
432
|
+
restoreDurableCommits(): Promise<Set<string>>;
|
|
363
433
|
/**
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
* DROPPED with an observability capture instead of replayed as commits.
|
|
434
|
+
* Validates and rehydrates one persisted row. Rows written to the same store
|
|
435
|
+
* by other subsystems are skipped, and rows that fail the persisted
|
|
436
|
+
* transaction schema — from an older version or corruption — are dropped and
|
|
437
|
+
* reported rather than replayed as commits.
|
|
369
438
|
*/
|
|
370
439
|
private deserializeTransaction;
|
|
371
440
|
/**
|
|
372
|
-
*
|
|
441
|
+
* Cancels every pending or executing transaction for a given model id,
|
|
442
|
+
* optionally limited to one operation type, rolling back their optimistic
|
|
443
|
+
* state. Returns the cancelled transactions.
|
|
373
444
|
*/
|
|
374
445
|
cancelTransactionsForModel(modelId: string, transactionType?: string): Transaction[];
|
|
375
446
|
/**
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
* This keeps FK relationship knowledge in ModelRegistry/SyncedStore,
|
|
380
|
-
* while TransactionQueue just handles the cancellation mechanics.
|
|
447
|
+
* Cancels pending transactions for child rows that reference a deleted parent,
|
|
448
|
+
* used to cascade a parent deletion. The caller supplies the foreign-key
|
|
449
|
+
* relationship; this method performs the cancellation.
|
|
381
450
|
*
|
|
382
|
-
* @param childModelName - The child model type (
|
|
383
|
-
* @param foreignKey - The
|
|
384
|
-
* @param parentId - The deleted parent's
|
|
385
|
-
* @returns
|
|
451
|
+
* @param childModelName - The child model type (for example 'SlideLayer').
|
|
452
|
+
* @param foreignKey - The foreign-key property name (for example 'slideId').
|
|
453
|
+
* @param parentId - The deleted parent's id.
|
|
454
|
+
* @returns The number of transactions cancelled.
|
|
386
455
|
*/
|
|
387
456
|
cancelTransactionsByForeignKey(childModelName: string, foreignKey: string, parentId: string): number;
|
|
388
457
|
/**
|
|
389
|
-
*
|
|
458
|
+
* Returns the number of transactions still pending or executing.
|
|
390
459
|
*/
|
|
391
460
|
getOutstandingTransactionCount(): number;
|
|
392
|
-
/**
|
|
393
|
-
* Utilities
|
|
394
|
-
*/
|
|
461
|
+
/** Generates a unique local transaction id. */
|
|
395
462
|
private generateId;
|
|
396
463
|
private mergeData;
|
|
397
464
|
private extractCreateData;
|
|
398
465
|
private mapChangesToInput;
|
|
399
466
|
private extractUpdateData;
|
|
400
|
-
private buildUpdateInput;
|
|
401
467
|
private extractPreviousData;
|
|
402
|
-
/**
|
|
403
|
-
* Public API
|
|
404
|
-
*/
|
|
468
|
+
/** Returns a snapshot of queue counts and the current configuration. */
|
|
405
469
|
getStats(): {
|
|
406
470
|
pending: number;
|
|
407
471
|
executing: number;
|
|
@@ -432,24 +496,23 @@ export declare class TransactionQueue extends EventEmitter {
|
|
|
432
496
|
capMs: number;
|
|
433
497
|
};
|
|
434
498
|
/**
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
* jitter
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
* batch workers (e.g. 60s for agent-worker).
|
|
499
|
+
* How long, in milliseconds, to wait after the connection drops before
|
|
500
|
+
* failing any in-flight commit-lane transaction with an
|
|
501
|
+
* {@link AbloConnectionError}. Brief disconnects, such as a server restart
|
|
502
|
+
* or mobile network jitter, are absorbed transparently; only a disconnect
|
|
503
|
+
* that outlasts this window surfaces as a failure. Set it lower for
|
|
504
|
+
* interactive use (for example 10 seconds for chat) and higher for
|
|
505
|
+
* background batch work. Defaults to 30 seconds.
|
|
443
506
|
*
|
|
444
|
-
* Without this deadline, `commits.create({wait:'confirmed'})`
|
|
445
|
-
* forever
|
|
507
|
+
* Without this deadline, `commits.create({ wait: 'confirmed' })` would wait
|
|
508
|
+
* forever if the connection died while a commit was in flight.
|
|
446
509
|
*/
|
|
447
510
|
commitOfflineGraceMs: number;
|
|
448
511
|
};
|
|
449
512
|
};
|
|
450
513
|
/**
|
|
451
|
-
*
|
|
452
|
-
*
|
|
514
|
+
* Returns detailed internal state — pending, executing, and awaiting-delta
|
|
515
|
+
* transactions — to help diagnose delta-confirmation issues.
|
|
453
516
|
*/
|
|
454
517
|
getDebugInfo(): {
|
|
455
518
|
lastSeenSyncId: number;
|
|
@@ -476,12 +539,11 @@ export declare class TransactionQueue extends EventEmitter {
|
|
|
476
539
|
modelId: string;
|
|
477
540
|
}[];
|
|
478
541
|
};
|
|
479
|
-
/**
|
|
480
|
-
* Set configuration
|
|
481
|
-
*/
|
|
542
|
+
/** Merges the given options into the queue's configuration. */
|
|
482
543
|
setConfig(config: Partial<TransactionQueueConfig>): void;
|
|
483
544
|
/**
|
|
484
|
-
*
|
|
545
|
+
* Re-emits an incoming sync delta on the `sync:delta` event for the store to
|
|
546
|
+
* apply. Because rows use stable ids, no id reconciliation is needed here.
|
|
485
547
|
*/
|
|
486
548
|
handleSyncDelta(delta: {
|
|
487
549
|
id: string;
|
|
@@ -490,7 +552,8 @@ export declare class TransactionQueue extends EventEmitter {
|
|
|
490
552
|
data: any;
|
|
491
553
|
}): boolean;
|
|
492
554
|
/**
|
|
493
|
-
*
|
|
555
|
+
* Releases the queue's resources: rolls back outstanding optimistic updates,
|
|
556
|
+
* clears all timers and stored transactions, and removes event listeners.
|
|
494
557
|
*/
|
|
495
558
|
dispose(): void;
|
|
496
559
|
}
|