@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,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Asynchronous helpers for tests whose assertions depend on timing — for
|
|
3
|
+
* flushing pending work, polling for a condition, or waiting a fixed delay.
|
|
3
4
|
*/
|
|
4
5
|
import { AbloConnectionError } from '../../errors.js';
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
7
|
+
* Flushes all pending microtasks, such as resolved promises and
|
|
8
|
+
* `queueMicrotask` callbacks. Useful for testing work the transaction queue
|
|
9
|
+
* batches on the microtask queue.
|
|
8
10
|
*/
|
|
9
11
|
export function flushMicrotasks() {
|
|
10
12
|
return new Promise((resolve) => {
|
|
@@ -13,8 +15,9 @@ export function flushMicrotasks() {
|
|
|
13
15
|
});
|
|
14
16
|
}
|
|
15
17
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
+
* Polls `condition` until it returns true, checking every `interval`
|
|
19
|
+
* milliseconds. Rejects with an {@link AbloConnectionError} if `maxWait`
|
|
20
|
+
* milliseconds pass first.
|
|
18
21
|
*/
|
|
19
22
|
export async function waitFor(condition, options = {}) {
|
|
20
23
|
const { maxWait = 5000, interval = 10 } = options;
|
|
@@ -29,14 +32,16 @@ export async function waitFor(condition, options = {}) {
|
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
/**
|
|
32
|
-
*
|
|
35
|
+
* Waits for the given number of milliseconds. Use sparingly; prefer
|
|
36
|
+
* {@link flushMicrotasks} or {@link waitFor}, which don't tie tests to
|
|
37
|
+
* wall-clock time.
|
|
33
38
|
*/
|
|
34
39
|
export function delay(ms) {
|
|
35
40
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
36
41
|
}
|
|
37
42
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
43
|
+
* Flushes pending microtasks, then runs `fn` and returns its result. Handy
|
|
44
|
+
* for asserting state after the transaction queue processes a batch.
|
|
40
45
|
*/
|
|
41
46
|
export async function afterMicrotasks(fn) {
|
|
42
47
|
await flushMicrotasks();
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -9,13 +9,15 @@ export type { CapturedMutation, MockMutationExecutorOptions } from './mocks/Mock
|
|
|
9
9
|
export { MockNetworkMonitor } from './mocks/MockNetworkMonitor.js';
|
|
10
10
|
export { MockWebSocket } from './mocks/MockWebSocket.js';
|
|
11
11
|
export type { MockDelta, MockBootstrapHint } from './mocks/MockWebSocket.js';
|
|
12
|
+
export { fakeDatabase } from './mocks/FakeDatabase.js';
|
|
13
|
+
export type { FakeDatabaseOverrides } from './mocks/FakeDatabase.js';
|
|
12
14
|
export { createTestContext, } from './mocks/MockSyncContext.js';
|
|
13
15
|
export type { TestContextOptions, TestContextResult } from './mocks/MockSyncContext.js';
|
|
14
16
|
export { TestProject, TestTask, TestComment, TestSlideDeck, TestSlide, TestSlideLayer, TEST_MODEL_PRIORITIES, registerTestModels, createTestConfig, resetFixtureCounter, createProjectFixture, createTaskFixture, createCommentFixture, createSlideDeckFixture, createSlideFixture, createSlideLayerFixture, } from './fixtures/models.js';
|
|
15
17
|
export { createDelta, createInsertDelta, createUpdateDelta, createDeleteDelta, createArchiveDelta, createUnarchiveDelta, createCoveringDelta, createGroupAddedDelta, createLegacyGroupChangeDelta, createGroupRemovedDelta, createDeltaBatch, createConfirmationDelta, resetDeltaCounter, } from './fixtures/deltas.js';
|
|
16
18
|
export { createFullBootstrapResponse, createPartialBootstrapResponse, createTestBootstrapResponse, } from './fixtures/bootstrap.js';
|
|
17
19
|
export type { BootstrapModelData, BootstrapResponse } from './fixtures/bootstrap.js';
|
|
18
|
-
export { createTestHarness, } from './helpers/
|
|
19
|
-
export type { TestHarness, TestHarnessOptions } from './helpers/
|
|
20
|
+
export { createTestHarness, } from './helpers/syncEngineHarness.js';
|
|
21
|
+
export type { TestHarness, TestHarnessOptions } from './helpers/syncEngineHarness.js';
|
|
20
22
|
export { flushMicrotasks, waitFor, delay, afterMicrotasks, } from './helpers/wait.js';
|
|
21
|
-
export { createReactTestWrapper, renderSyncHook, MockSyncStore, createMockSyncStore, type TestWrapperOptions, } from './helpers/
|
|
23
|
+
export { createReactTestWrapper, renderSyncHook, MockSyncStore, createMockSyncStore, type TestWrapperOptions, } from './helpers/reactWrapper.js';
|
package/dist/testing/index.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
export { MockMutationExecutor } from './mocks/MockMutationExecutor.js';
|
|
11
11
|
export { MockNetworkMonitor } from './mocks/MockNetworkMonitor.js';
|
|
12
12
|
export { MockWebSocket } from './mocks/MockWebSocket.js';
|
|
13
|
+
export { fakeDatabase } from './mocks/FakeDatabase.js';
|
|
13
14
|
export { createTestContext, } from './mocks/MockSyncContext.js';
|
|
14
15
|
// ─────────────────────────────────────────────
|
|
15
16
|
// Fixtures: Models
|
|
@@ -26,7 +27,7 @@ export { createFullBootstrapResponse, createPartialBootstrapResponse, createTest
|
|
|
26
27
|
// ─────────────────────────────────────────────
|
|
27
28
|
// Helpers
|
|
28
29
|
// ─────────────────────────────────────────────
|
|
29
|
-
export { createTestHarness, } from './helpers/
|
|
30
|
+
export { createTestHarness, } from './helpers/syncEngineHarness.js';
|
|
30
31
|
export { flushMicrotasks, waitFor, delay, afterMicrotasks, } from './helpers/wait.js';
|
|
31
32
|
// React testing helpers
|
|
32
|
-
export { createReactTestWrapper, renderSyncHook, MockSyncStore, createMockSyncStore, } from './helpers/
|
|
33
|
+
export { createReactTestWrapper, renderSyncHook, MockSyncStore, createMockSyncStore, } from './helpers/reactWrapper.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Database } from '../../Database.js';
|
|
2
|
+
/**
|
|
3
|
+
* Overrides for {@link fakeDatabase}. Everything is typechecked against
|
|
4
|
+
* Database's public surface except `getPersistedTransactions`, which widens to
|
|
5
|
+
* `unknown[]`: persisted rows are untrusted input (the CommitOutboxStore port
|
|
6
|
+
* documents this), and restore-path tests feed deliberately corrupt rows.
|
|
7
|
+
*/
|
|
8
|
+
export type FakeDatabaseOverrides = Omit<Partial<Database>, 'getPersistedTransactions'> & {
|
|
9
|
+
getPersistedTransactions?: () => Promise<unknown[]>;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* A Database double that implements ONLY the given members — no real
|
|
13
|
+
* prototype behind it, so a code path reaching for anything else fails
|
|
14
|
+
* loudly instead of silently running real IndexedDB logic. The bare `as`
|
|
15
|
+
* is a single narrowing assert (Database is assignable to the overrides
|
|
16
|
+
* type), so every override stays typechecked against the real surface.
|
|
17
|
+
*/
|
|
18
|
+
export declare function fakeDatabase(overrides: FakeDatabaseOverrides): Database;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Database double that implements ONLY the given members — no real
|
|
3
|
+
* prototype behind it, so a code path reaching for anything else fails
|
|
4
|
+
* loudly instead of silently running real IndexedDB logic. The bare `as`
|
|
5
|
+
* is a single narrowing assert (Database is assignable to the overrides
|
|
6
|
+
* type), so every override stays typechecked against the real surface.
|
|
7
|
+
*/
|
|
8
|
+
export function fakeDatabase(overrides) {
|
|
9
|
+
return overrides;
|
|
10
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* A test double for {@link MutationExecutor} that records every call instead
|
|
3
|
+
* of writing to a database. Use it to assert what a component tried to commit
|
|
4
|
+
* and to script the response — success, failure, or added latency — without a
|
|
5
|
+
* live backend. Each successful commit hands back an incrementing `lastSyncId`,
|
|
6
|
+
* so tests can drive the delta-confirmation flow that depends on those ids.
|
|
6
7
|
*/
|
|
7
8
|
import type { MutationExecutor, MutationOperation, MutationOptions, CommitResult } from '../../interfaces/index.js';
|
|
8
9
|
export interface CapturedMutation {
|
|
@@ -16,15 +17,15 @@ export interface CapturedMutation {
|
|
|
16
17
|
timestamp: number;
|
|
17
18
|
}
|
|
18
19
|
export interface MockMutationExecutorOptions {
|
|
19
|
-
/**
|
|
20
|
+
/** The first `lastSyncId` to return. It increments by one after each commit. */
|
|
20
21
|
initialSyncId?: number;
|
|
21
|
-
/** Whether mutations
|
|
22
|
+
/** Whether mutations succeed by default. Set this false to make every call reject. */
|
|
22
23
|
shouldSucceed?: boolean;
|
|
23
|
-
/**
|
|
24
|
+
/** A delay applied before each call resolves, in milliseconds, to simulate a slow network. */
|
|
24
25
|
latencyMs?: number;
|
|
25
26
|
}
|
|
26
27
|
export declare class MockMutationExecutor implements MutationExecutor {
|
|
27
|
-
/**
|
|
28
|
+
/** Every captured call, in the order it was made. Assertions read from this list. */
|
|
28
29
|
readonly calls: CapturedMutation[];
|
|
29
30
|
/** Current sync ID — incremented on each successful commit */
|
|
30
31
|
private _syncId;
|
|
@@ -35,23 +36,23 @@ export declare class MockMutationExecutor implements MutationExecutor {
|
|
|
35
36
|
/** Per-method response overrides */
|
|
36
37
|
private _responseOverrides;
|
|
37
38
|
constructor(options?: MockMutationExecutorOptions);
|
|
38
|
-
/**
|
|
39
|
+
/** Returns the current sync id without advancing it. */
|
|
39
40
|
get currentSyncId(): number;
|
|
40
|
-
/**
|
|
41
|
+
/** Sets the next sync id the executor will return. */
|
|
41
42
|
setSyncId(id: number): void;
|
|
42
|
-
/**
|
|
43
|
+
/** Makes every mutation reject. Pass an error to control what is thrown. */
|
|
43
44
|
failAll(error?: Error): void;
|
|
44
|
-
/**
|
|
45
|
+
/** Restores the default where mutations succeed, clearing any failure overrides. */
|
|
45
46
|
succeedAll(): void;
|
|
46
|
-
/**
|
|
47
|
+
/** Makes a single named method reject. Pass an error to control what is thrown. */
|
|
47
48
|
failMethod(method: string, error?: Error): void;
|
|
48
|
-
/**
|
|
49
|
+
/** Removes the failure override for one method. */
|
|
49
50
|
clearFailure(method: string): void;
|
|
50
|
-
/**
|
|
51
|
+
/** Returns the captured calls for one method, in order. */
|
|
51
52
|
getCallsByMethod(method: string): CapturedMutation[];
|
|
52
|
-
/**
|
|
53
|
+
/** The most recent captured call, or undefined if none have been made. */
|
|
53
54
|
get lastCall(): CapturedMutation | undefined;
|
|
54
|
-
/**
|
|
55
|
+
/** Clears captured calls and restores the initial options. */
|
|
55
56
|
reset(options?: MockMutationExecutorOptions): void;
|
|
56
57
|
commit(operations: MutationOperation[], options?: MutationOptions): Promise<CommitResult>;
|
|
57
58
|
executeCreate(modelName: string, id: string, input: Record<string, unknown>, clientMutationId?: string): Promise<void>;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* A test double for {@link MutationExecutor} that records every call instead
|
|
3
|
+
* of writing to a database. Use it to assert what a component tried to commit
|
|
4
|
+
* and to script the response — success, failure, or added latency — without a
|
|
5
|
+
* live backend. Each successful commit hands back an incrementing `lastSyncId`,
|
|
6
|
+
* so tests can drive the delta-confirmation flow that depends on those ids.
|
|
6
7
|
*/
|
|
7
8
|
import { AbloError } from '../../errors.js';
|
|
8
9
|
export class MockMutationExecutor {
|
|
9
|
-
/**
|
|
10
|
+
/** Every captured call, in the order it was made. Assertions read from this list. */
|
|
10
11
|
calls = [];
|
|
11
12
|
/** Current sync ID — incremented on each successful commit */
|
|
12
13
|
_syncId;
|
|
@@ -24,43 +25,43 @@ export class MockMutationExecutor {
|
|
|
24
25
|
// ─────────────────────────────────────────────
|
|
25
26
|
// Test control API
|
|
26
27
|
// ─────────────────────────────────────────────
|
|
27
|
-
/**
|
|
28
|
+
/** Returns the current sync id without advancing it. */
|
|
28
29
|
get currentSyncId() {
|
|
29
30
|
return this._syncId;
|
|
30
31
|
}
|
|
31
|
-
/**
|
|
32
|
+
/** Sets the next sync id the executor will return. */
|
|
32
33
|
setSyncId(id) {
|
|
33
34
|
this._syncId = id;
|
|
34
35
|
}
|
|
35
|
-
/**
|
|
36
|
+
/** Makes every mutation reject. Pass an error to control what is thrown. */
|
|
36
37
|
failAll(error) {
|
|
37
38
|
this._shouldSucceed = false;
|
|
38
39
|
if (error) {
|
|
39
40
|
this._failureOverrides.set('*', error);
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
|
-
/**
|
|
43
|
+
/** Restores the default where mutations succeed, clearing any failure overrides. */
|
|
43
44
|
succeedAll() {
|
|
44
45
|
this._shouldSucceed = true;
|
|
45
46
|
this._failureOverrides.clear();
|
|
46
47
|
}
|
|
47
|
-
/**
|
|
48
|
+
/** Makes a single named method reject. Pass an error to control what is thrown. */
|
|
48
49
|
failMethod(method, error) {
|
|
49
50
|
this._failureOverrides.set(method, error ?? new Error(`Mock ${method} failed`));
|
|
50
51
|
}
|
|
51
|
-
/**
|
|
52
|
+
/** Removes the failure override for one method. */
|
|
52
53
|
clearFailure(method) {
|
|
53
54
|
this._failureOverrides.delete(method);
|
|
54
55
|
}
|
|
55
|
-
/**
|
|
56
|
+
/** Returns the captured calls for one method, in order. */
|
|
56
57
|
getCallsByMethod(method) {
|
|
57
58
|
return this.calls.filter((c) => c.method === method);
|
|
58
59
|
}
|
|
59
|
-
/**
|
|
60
|
+
/** The most recent captured call, or undefined if none have been made. */
|
|
60
61
|
get lastCall() {
|
|
61
62
|
return this.calls[this.calls.length - 1];
|
|
62
63
|
}
|
|
63
|
-
/**
|
|
64
|
+
/** Clears captured calls and restores the initial options. */
|
|
64
65
|
reset(options) {
|
|
65
66
|
this.calls.length = 0;
|
|
66
67
|
this._syncId = options?.initialSyncId ?? 1;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* A test double for {@link OnlineStatusProvider} that lets tests flip the
|
|
3
|
+
* connection between online and offline on demand. Alongside its own state, it
|
|
4
|
+
* updates the global `navigator.onLine` flag so code that reads the browser
|
|
5
|
+
* value directly sees the same status.
|
|
6
6
|
*/
|
|
7
7
|
import type { OnlineStatusProvider } from '../../interfaces/index.js';
|
|
8
8
|
export declare class MockNetworkMonitor implements OnlineStatusProvider {
|
|
9
9
|
private _online;
|
|
10
10
|
constructor(initialOnline?: boolean);
|
|
11
11
|
isOnline(): boolean;
|
|
12
|
-
/**
|
|
12
|
+
/** Marks the connection online and sets `navigator.onLine` to true. */
|
|
13
13
|
goOnline(): void;
|
|
14
|
-
/**
|
|
14
|
+
/** Marks the connection offline and sets `navigator.onLine` to false. */
|
|
15
15
|
goOffline(): void;
|
|
16
|
-
/**
|
|
16
|
+
/** Flips between online and offline, returning the new online state. */
|
|
17
17
|
toggle(): boolean;
|
|
18
|
-
/**
|
|
18
|
+
/** Returns the monitor to its online starting state. */
|
|
19
19
|
reset(): void;
|
|
20
20
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* A test double for {@link OnlineStatusProvider} that lets tests flip the
|
|
3
|
+
* connection between online and offline on demand. Alongside its own state, it
|
|
4
|
+
* updates the global `navigator.onLine` flag so code that reads the browser
|
|
5
|
+
* value directly sees the same status.
|
|
6
6
|
*/
|
|
7
7
|
export class MockNetworkMonitor {
|
|
8
8
|
_online;
|
|
@@ -12,7 +12,7 @@ export class MockNetworkMonitor {
|
|
|
12
12
|
isOnline() {
|
|
13
13
|
return this._online;
|
|
14
14
|
}
|
|
15
|
-
/**
|
|
15
|
+
/** Marks the connection online and sets `navigator.onLine` to true. */
|
|
16
16
|
goOnline() {
|
|
17
17
|
this._online = true;
|
|
18
18
|
// Also update navigator.onLine for code that reads it directly
|
|
@@ -21,7 +21,7 @@ export class MockNetworkMonitor {
|
|
|
21
21
|
value: true,
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
-
/**
|
|
24
|
+
/** Marks the connection offline and sets `navigator.onLine` to false. */
|
|
25
25
|
goOffline() {
|
|
26
26
|
this._online = false;
|
|
27
27
|
Object.defineProperty(navigator, 'onLine', {
|
|
@@ -29,7 +29,7 @@ export class MockNetworkMonitor {
|
|
|
29
29
|
value: false,
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
-
/**
|
|
32
|
+
/** Flips between online and offline, returning the new online state. */
|
|
33
33
|
toggle() {
|
|
34
34
|
if (this._online) {
|
|
35
35
|
this.goOffline();
|
|
@@ -39,7 +39,7 @@ export class MockNetworkMonitor {
|
|
|
39
39
|
}
|
|
40
40
|
return this._online;
|
|
41
41
|
}
|
|
42
|
-
/**
|
|
42
|
+
/** Returns the monitor to its online starting state. */
|
|
43
43
|
reset() {
|
|
44
44
|
this.goOnline();
|
|
45
45
|
}
|
|
@@ -1,44 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* Assembles a ready-to-use {@link SyncEngineContext} for tests. The context
|
|
3
|
+
* bundles every dependency the engine needs — logger, network monitor,
|
|
4
|
+
* mutation executor, and configuration — so a test can start the engine
|
|
5
|
+
* without a real backend. {@link createTestContext} is the entry point: it
|
|
6
|
+
* wires the mocks, installs the context globally through {@link initSyncEngine},
|
|
7
|
+
* and returns handles to each mock for assertions.
|
|
7
8
|
*/
|
|
8
9
|
import type { SyncEngineContext } from '../../SyncEngineContext.js';
|
|
9
10
|
import type { SyncLogger, SyncObservabilityProvider, SessionErrorDetector, SyncEngineConfig } from '../../interfaces/index.js';
|
|
10
11
|
import { MockMutationExecutor } from './MockMutationExecutor.js';
|
|
11
12
|
import { MockNetworkMonitor } from './MockNetworkMonitor.js';
|
|
12
13
|
export interface TestContextOptions {
|
|
13
|
-
/**
|
|
14
|
+
/** Replaces the default no-op logger. */
|
|
14
15
|
logger?: SyncLogger;
|
|
15
|
-
/**
|
|
16
|
+
/** Replaces the default no-op observability provider. */
|
|
16
17
|
observability?: SyncObservabilityProvider;
|
|
17
|
-
/**
|
|
18
|
+
/** Replaces the detector that decides whether an error means the session has expired. */
|
|
18
19
|
sessionErrorDetector?: SessionErrorDetector;
|
|
19
|
-
/**
|
|
20
|
+
/** Options forwarded to the {@link MockMutationExecutor} that the context creates. */
|
|
20
21
|
mutationExecutorOptions?: ConstructorParameters<typeof MockMutationExecutor>[0];
|
|
21
|
-
/**
|
|
22
|
+
/** A partial {@link SyncEngineConfig} merged over the defaults. */
|
|
22
23
|
config?: Partial<SyncEngineConfig>;
|
|
23
|
-
/**
|
|
24
|
+
/** Starts the network monitor offline. Defaults to online. */
|
|
24
25
|
startOffline?: boolean;
|
|
25
26
|
}
|
|
26
27
|
export interface TestContextResult {
|
|
27
|
-
/** The
|
|
28
|
+
/** The assembled context that {@link createTestContext} installed globally. */
|
|
28
29
|
context: SyncEngineContext;
|
|
29
|
-
/**
|
|
30
|
+
/** Handles to the underlying mocks, so tests can drive them and assert on them. */
|
|
30
31
|
mocks: {
|
|
31
32
|
mutationExecutor: MockMutationExecutor;
|
|
32
33
|
networkMonitor: MockNetworkMonitor;
|
|
33
34
|
};
|
|
34
|
-
/**
|
|
35
|
+
/** Tears the test down by resetting the engine and the mocks. Call it when the test finishes. */
|
|
35
36
|
cleanup: () => void;
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
39
|
+
* Builds a {@link SyncEngineContext} with every mock pre-wired and installs it
|
|
40
|
+
* globally through {@link initSyncEngine}, so code under test reaches the engine
|
|
41
|
+
* the same way it would in production. Returns the context, the mock handles,
|
|
42
|
+
* and a cleanup function to call when the test finishes.
|
|
40
43
|
*
|
|
41
|
-
*
|
|
44
|
+
* @example
|
|
42
45
|
* ```ts
|
|
43
46
|
* const { context, mocks, cleanup } = createTestContext();
|
|
44
47
|
* // ... run tests using mocks.mutationExecutor, mocks.networkMonitor
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* Assembles a ready-to-use {@link SyncEngineContext} for tests. The context
|
|
3
|
+
* bundles every dependency the engine needs — logger, network monitor,
|
|
4
|
+
* mutation executor, and configuration — so a test can start the engine
|
|
5
|
+
* without a real backend. {@link createTestContext} is the entry point: it
|
|
6
|
+
* wires the mocks, installs the context globally through {@link initSyncEngine},
|
|
7
|
+
* and returns handles to each mock for assertions.
|
|
7
8
|
*/
|
|
8
9
|
import { noopLogger, noopObservability, noopAnalytics, defaultSessionErrorDetector, emptyConfig, } from '../../SyncEngineContext.js';
|
|
9
10
|
import { initSyncEngine, resetSyncEngine } from '../../context.js';
|
|
@@ -12,10 +13,12 @@ import { registerTestModels } from '../fixtures/models.js';
|
|
|
12
13
|
import { MockMutationExecutor } from './MockMutationExecutor.js';
|
|
13
14
|
import { MockNetworkMonitor } from './MockNetworkMonitor.js';
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* Builds a {@link SyncEngineContext} with every mock pre-wired and installs it
|
|
17
|
+
* globally through {@link initSyncEngine}, so code under test reaches the engine
|
|
18
|
+
* the same way it would in production. Returns the context, the mock handles,
|
|
19
|
+
* and a cleanup function to call when the test finishes.
|
|
17
20
|
*
|
|
18
|
-
*
|
|
21
|
+
* @example
|
|
19
22
|
* ```ts
|
|
20
23
|
* const { context, mocks, cleanup } = createTestContext();
|
|
21
24
|
* // ... run tests using mocks.mutationExecutor, mocks.networkMonitor
|
|
@@ -57,11 +60,10 @@ export function createTestContext(options = {}) {
|
|
|
57
60
|
},
|
|
58
61
|
cleanup: () => {
|
|
59
62
|
resetSyncEngine();
|
|
60
|
-
//
|
|
61
|
-
// from in-flight transactions
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
// with hasActiveRegistry()===true simply reuses it.
|
|
63
|
+
// Leave the active ModelRegistry in place on purpose. Async callbacks
|
|
64
|
+
// from in-flight transactions can call Model.toJSON() after a test's
|
|
65
|
+
// teardown has run; keeping the default registry available keeps those
|
|
66
|
+
// late calls valid, and the next createTestContext simply reuses it.
|
|
65
67
|
mutationExecutor.reset();
|
|
66
68
|
networkMonitor.reset();
|
|
67
69
|
},
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* All reactive operations are synchronous and observable via Jest spies.
|
|
2
|
+
* An in-memory {@link SyncStoreContract} for tests. It lets you seed rows,
|
|
3
|
+
* read and write them synchronously, and inspect every call the code under
|
|
4
|
+
* test made — all without a real sync backend.
|
|
6
5
|
*/
|
|
7
6
|
import type { Model } from '../../Model.js';
|
|
8
|
-
import type { ModelScope } from '../../
|
|
7
|
+
import type { ModelScope } from '../../InstanceCache.js';
|
|
9
8
|
import type { SyncStoreContract } from '../../react/context.js';
|
|
10
9
|
interface QueryOptions<T extends Model> {
|
|
11
10
|
predicate?: (model: T) => boolean;
|
|
@@ -20,9 +19,10 @@ interface QueryResult<T extends Model> {
|
|
|
20
19
|
}
|
|
21
20
|
type ModelCtor<T extends Model> = abstract new (...args: never[]) => T;
|
|
22
21
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
22
|
+
* An in-memory implementation of {@link SyncStoreContract}. Seed rows with
|
|
23
|
+
* {@link MockSyncStore.setModels}, then read and write through the contract
|
|
24
|
+
* methods; every call is recorded on {@link MockSyncStore.calls} so tests can
|
|
25
|
+
* assert on what happened.
|
|
26
26
|
*/
|
|
27
27
|
export declare class MockSyncStore implements SyncStoreContract {
|
|
28
28
|
private byClass;
|
|
@@ -48,7 +48,7 @@ export declare class MockSyncStore implements SyncStoreContract {
|
|
|
48
48
|
*/
|
|
49
49
|
setModels<T extends Model>(modelClass: ModelCtor<T>, models: T[]): void;
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
51
|
+
* Adds or replaces a single model, keyed by its id.
|
|
52
52
|
*/
|
|
53
53
|
addModel<T extends Model>(modelClass: ModelCtor<T>, model: T): void;
|
|
54
54
|
/**
|
|
@@ -77,7 +77,7 @@ export declare class MockSyncStore implements SyncStoreContract {
|
|
|
77
77
|
pendingChanges: number;
|
|
78
78
|
isSessionError: boolean;
|
|
79
79
|
};
|
|
80
|
-
/**
|
|
80
|
+
/** A minimal object pool backing the useEntity and useEntities hooks in tests. */
|
|
81
81
|
pool: SyncStoreContract['pool'];
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* All reactive operations are synchronous and observable via Jest spies.
|
|
2
|
+
* An in-memory {@link SyncStoreContract} for tests. It lets you seed rows,
|
|
3
|
+
* read and write them synchronously, and inspect every call the code under
|
|
4
|
+
* test made — all without a real sync backend.
|
|
6
5
|
*/
|
|
7
6
|
import { ViewRegistry } from '../../core/ViewRegistry.js';
|
|
8
7
|
import { AbloValidationError } from '../../errors.js';
|
|
9
8
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* An in-memory implementation of {@link SyncStoreContract}. Seed rows with
|
|
10
|
+
* {@link MockSyncStore.setModels}, then read and write through the contract
|
|
11
|
+
* methods; every call is recorded on {@link MockSyncStore.calls} so tests can
|
|
12
|
+
* assert on what happened.
|
|
13
13
|
*/
|
|
14
14
|
export class MockSyncStore {
|
|
15
15
|
// Seeded data, keyed by model class
|
|
@@ -37,7 +37,7 @@ export class MockSyncStore {
|
|
|
37
37
|
this.byClass.set(modelClass, map);
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* Adds or replaces a single model, keyed by its id.
|
|
41
41
|
*/
|
|
42
42
|
addModel(modelClass, model) {
|
|
43
43
|
let map = this.byClass.get(modelClass);
|
|
@@ -110,8 +110,8 @@ export class MockSyncStore {
|
|
|
110
110
|
}
|
|
111
111
|
async save(model) {
|
|
112
112
|
this.calls.save.push(model);
|
|
113
|
-
//
|
|
114
|
-
//
|
|
113
|
+
// Store the model under its constructor so a later retrieve or query
|
|
114
|
+
// returns it.
|
|
115
115
|
const ctor = model.constructor;
|
|
116
116
|
this.addModel(ctor, model);
|
|
117
117
|
}
|
|
@@ -140,7 +140,7 @@ export class MockSyncStore {
|
|
|
140
140
|
pendingChanges: 0,
|
|
141
141
|
isSessionError: false,
|
|
142
142
|
};
|
|
143
|
-
/**
|
|
143
|
+
/** A minimal object pool backing the useEntity and useEntities hooks in tests. */
|
|
144
144
|
pool = {
|
|
145
145
|
get: (id) => {
|
|
146
146
|
for (const models of this.byClass.values()) {
|