@abloatai/ablo 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +101 -85
- package/dist/BaseSyncedStore.d.ts +85 -88
- package/dist/BaseSyncedStore.js +131 -147
- package/dist/Database.d.ts +54 -68
- package/dist/Database.js +97 -113
- package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
- package/dist/{ObjectPool.js → InstanceCache.js} +85 -83
- package/dist/LazyReferenceCollection.d.ts +11 -15
- package/dist/LazyReferenceCollection.js +12 -16
- package/dist/Model.d.ts +37 -52
- package/dist/Model.js +46 -61
- package/dist/ModelRegistry.d.ts +21 -19
- package/dist/ModelRegistry.js +23 -27
- package/dist/NetworkMonitor.d.ts +5 -6
- package/dist/NetworkMonitor.js +5 -6
- package/dist/SyncClient.d.ts +112 -112
- package/dist/SyncClient.js +165 -172
- package/dist/adapters/alwaysOnline.d.ts +6 -8
- package/dist/adapters/alwaysOnline.js +6 -8
- package/dist/adapters/inMemoryStorage.d.ts +9 -9
- package/dist/adapters/inMemoryStorage.js +9 -9
- package/dist/agent/Agent.d.ts +27 -32
- package/dist/agent/Agent.js +18 -19
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +5 -5
- package/dist/agent/session.d.ts +47 -44
- package/dist/agent/session.js +37 -48
- package/dist/agent/types.d.ts +26 -31
- package/dist/agent/types.js +6 -7
- package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
- package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
- package/dist/ai-sdk/coordinationContext.d.ts +46 -0
- package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +26 -33
- package/dist/ai-sdk/index.d.ts +25 -22
- package/dist/ai-sdk/index.js +25 -22
- package/dist/ai-sdk/wrap.d.ts +6 -7
- package/dist/ai-sdk/wrap.js +1 -1
- package/dist/auth/credentialPolicy.d.ts +69 -74
- package/dist/auth/credentialPolicy.js +51 -56
- package/dist/auth/credentialSource.d.ts +6 -5
- package/dist/auth/credentialSource.js +9 -10
- package/dist/auth/index.d.ts +59 -58
- package/dist/auth/index.js +31 -37
- package/dist/auth/schemas.d.ts +5 -4
- package/dist/auth/schemas.js +5 -4
- package/dist/batching/index.d.ts +19 -21
- package/dist/batching/index.js +14 -17
- package/dist/cli.cjs +167 -119
- package/dist/client/Ablo.d.ts +73 -73
- package/dist/client/Ablo.js +125 -160
- package/dist/client/ApiClient.d.ts +30 -19
- package/dist/client/ApiClient.js +133 -38
- package/dist/client/auth.d.ts +47 -47
- package/dist/client/auth.js +108 -117
- package/dist/client/claimHeartbeatLoop.d.ts +50 -0
- package/dist/client/claimHeartbeatLoop.js +88 -0
- package/dist/client/consoleLogger.d.ts +5 -6
- package/dist/client/consoleLogger.js +5 -6
- package/dist/client/createInternalComponents.d.ts +14 -17
- package/dist/client/createInternalComponents.js +25 -30
- package/dist/client/createModelProxy.d.ts +130 -120
- package/dist/client/createModelProxy.js +152 -122
- package/dist/client/credentialEndpoint.d.ts +40 -42
- package/dist/client/credentialEndpoint.js +35 -36
- package/dist/client/functionalUpdate.d.ts +29 -27
- package/dist/client/functionalUpdate.js +21 -21
- package/dist/client/hostedEndpoints.d.ts +9 -12
- package/dist/client/hostedEndpoints.js +9 -12
- package/dist/client/httpClient.d.ts +57 -53
- package/dist/client/httpClient.js +29 -31
- package/dist/client/identity.d.ts +15 -20
- package/dist/client/identity.js +47 -58
- package/dist/client/modelRegistration.d.ts +5 -9
- package/dist/client/modelRegistration.js +67 -87
- package/dist/client/options.d.ts +134 -157
- package/dist/client/options.js +3 -7
- package/dist/client/registerDataSource.d.ts +9 -9
- package/dist/client/registerDataSource.js +15 -16
- package/dist/client/resourceTypes.d.ts +64 -75
- package/dist/client/resourceTypes.js +4 -10
- package/dist/client/schemaConfig.d.ts +31 -43
- package/dist/client/schemaConfig.js +38 -50
- package/dist/client/sessionMint.d.ts +16 -12
- package/dist/client/sessionMint.js +26 -31
- package/dist/client/validateAbloOptions.d.ts +12 -14
- package/dist/client/validateAbloOptions.js +8 -9
- package/dist/client/writeOptionsSchema.d.ts +18 -16
- package/dist/client/writeOptionsSchema.js +23 -20
- package/dist/client/wsMutationExecutor.d.ts +15 -20
- package/dist/client/wsMutationExecutor.js +17 -23
- package/dist/context.d.ts +6 -4
- package/dist/context.js +6 -4
- package/dist/coordination/index.d.ts +10 -8
- package/dist/coordination/index.js +14 -12
- package/dist/coordination/schema.d.ts +176 -128
- package/dist/coordination/schema.js +197 -133
- package/dist/coordination/trace.d.ts +9 -10
- package/dist/coordination/trace.js +13 -14
- package/dist/core/DatabaseManager.d.ts +5 -7
- package/dist/core/DatabaseManager.js +15 -19
- package/dist/core/QueryProcessor.d.ts +7 -9
- package/dist/core/QueryProcessor.js +22 -28
- package/dist/core/QueryView.d.ts +8 -8
- package/dist/core/QueryView.js +2 -2
- package/dist/core/StoreManager.d.ts +12 -14
- package/dist/core/StoreManager.js +21 -24
- package/dist/core/ViewRegistry.d.ts +5 -5
- package/dist/core/ViewRegistry.js +4 -4
- package/dist/core/index.d.ts +17 -12
- package/dist/core/index.js +32 -26
- package/dist/core/openIDBWithTimeout.d.ts +38 -36
- package/dist/core/openIDBWithTimeout.js +42 -43
- package/dist/core/queryUtils.d.ts +45 -0
- package/dist/core/queryUtils.js +69 -0
- package/dist/core/storeContract.d.ts +63 -61
- package/dist/core/storeContract.js +8 -12
- package/dist/environment.d.ts +28 -0
- package/dist/environment.js +21 -0
- package/dist/errorCodes.d.ts +107 -99
- package/dist/errorCodes.js +131 -132
- package/dist/errors.d.ts +160 -166
- package/dist/errors.js +155 -158
- package/dist/index.d.ts +30 -27
- package/dist/index.js +89 -86
- package/dist/interfaces/index.d.ts +102 -113
- package/dist/interfaces/index.js +5 -4
- package/dist/keys/index.d.ts +27 -29
- package/dist/keys/index.js +41 -40
- package/dist/mutators/RecordingTransaction.d.ts +16 -16
- package/dist/mutators/RecordingTransaction.js +31 -37
- package/dist/mutators/Transaction.d.ts +18 -26
- package/dist/mutators/Transaction.js +14 -20
- package/dist/mutators/UndoManager.d.ts +122 -131
- package/dist/mutators/UndoManager.js +145 -156
- package/dist/mutators/defineMutators.d.ts +23 -34
- package/dist/mutators/defineMutators.js +14 -20
- package/dist/mutators/inverseOp.d.ts +12 -15
- package/dist/mutators/inverseOp.js +12 -15
- package/dist/mutators/mutateActions.d.ts +10 -9
- package/dist/mutators/mutateActions.js +1 -1
- package/dist/mutators/readerActions.d.ts +9 -8
- package/dist/mutators/readerActions.js +2 -2
- package/dist/mutators/undoApply.d.ts +31 -27
- package/dist/mutators/undoApply.js +26 -24
- package/dist/policy/index.d.ts +5 -3
- package/dist/policy/index.js +5 -3
- package/dist/policy/types.d.ts +104 -100
- package/dist/policy/types.js +67 -66
- package/dist/query/client.d.ts +28 -23
- package/dist/query/client.js +45 -43
- package/dist/query/types.d.ts +37 -60
- package/dist/query/types.js +13 -33
- package/dist/react/AbloProvider.d.ts +1 -1
- package/dist/react/AbloProvider.js +2 -2
- package/dist/react/context.d.ts +25 -28
- package/dist/react/context.js +9 -10
- package/dist/react/index.d.ts +41 -42
- package/dist/react/index.js +37 -38
- package/dist/react/internalContext.d.ts +17 -19
- package/dist/react/useAblo.d.ts +23 -22
- package/dist/react/useAblo.js +16 -14
- package/dist/react/useCurrentUserId.d.ts +8 -7
- package/dist/react/useCurrentUserId.js +8 -7
- package/dist/react/useErrorListener.d.ts +7 -7
- package/dist/react/useErrorListener.js +10 -11
- package/dist/react/useMutationFailureListener.d.ts +8 -8
- package/dist/react/useMutationFailureListener.js +8 -8
- package/dist/react/useMutators.d.ts +11 -11
- package/dist/react/useMutators.js +3 -3
- package/dist/react/useReactive.js +2 -2
- package/dist/react/useSyncStatus.d.ts +4 -6
- package/dist/react/useUndoScope.d.ts +7 -9
- package/dist/react/useUndoScope.js +1 -1
- package/dist/schema/coordination.d.ts +21 -25
- package/dist/schema/coordination.js +21 -25
- package/dist/schema/ddl.d.ts +43 -39
- package/dist/schema/ddl.js +75 -68
- package/dist/schema/ddlLock.d.ts +20 -24
- package/dist/schema/ddlLock.js +18 -23
- package/dist/schema/diff.d.ts +99 -61
- package/dist/schema/diff.js +43 -34
- package/dist/schema/field.d.ts +37 -42
- package/dist/schema/field.js +35 -48
- package/dist/schema/generate.d.ts +12 -12
- package/dist/schema/generate.js +12 -12
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.js +21 -23
- package/dist/schema/model.d.ts +118 -143
- package/dist/schema/model.js +22 -33
- package/dist/schema/openapi.d.ts +10 -9
- package/dist/schema/openapi.js +5 -3
- package/dist/schema/queries.d.ts +29 -31
- package/dist/schema/queries.js +23 -25
- package/dist/schema/relation.d.ts +89 -99
- package/dist/schema/relation.js +13 -13
- package/dist/schema/residency.d.ts +16 -13
- package/dist/schema/residency.js +16 -13
- package/dist/schema/roles.d.ts +36 -43
- package/dist/schema/roles.js +31 -37
- package/dist/schema/schema.d.ts +33 -42
- package/dist/schema/schema.js +31 -32
- package/dist/schema/select.d.ts +13 -13
- package/dist/schema/select.js +13 -13
- package/dist/schema/serialize.d.ts +28 -31
- package/dist/schema/serialize.js +27 -31
- package/dist/schema/sugar.d.ts +17 -32
- package/dist/schema/sugar.js +14 -29
- package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +26 -49
- package/dist/schema/syncDeltaRow.js +89 -0
- package/dist/schema/tenancy.d.ts +44 -46
- package/dist/schema/tenancy.js +46 -48
- package/dist/server/adapter.d.ts +58 -58
- package/dist/server/adapter.js +13 -14
- package/dist/server/commit.d.ts +60 -64
- package/dist/server/index.d.ts +9 -10
- package/dist/server/index.js +1 -1
- package/dist/server/readConfig.d.ts +70 -0
- package/dist/server/readConfig.js +8 -0
- package/dist/server/storageMode.d.ts +23 -0
- package/dist/server/storageMode.js +17 -0
- package/dist/source/adapter.d.ts +30 -25
- package/dist/source/adapter.js +10 -10
- package/dist/source/adapters/drizzle.d.ts +28 -23
- package/dist/source/adapters/drizzle.js +30 -25
- package/dist/source/adapters/kysely.d.ts +27 -25
- package/dist/source/adapters/kysely.js +24 -23
- package/dist/source/adapters/memory.d.ts +8 -7
- package/dist/source/adapters/memory.js +9 -8
- package/dist/source/adapters/prisma.d.ts +13 -12
- package/dist/source/adapters/prisma.js +22 -25
- package/dist/source/conformance.d.ts +18 -11
- package/dist/source/conformance.js +17 -11
- package/dist/source/connector.d.ts +31 -32
- package/dist/source/connector.js +28 -28
- package/dist/source/connectorProtocol.d.ts +160 -0
- package/dist/source/connectorProtocol.js +162 -0
- package/dist/source/contract.d.ts +26 -27
- package/dist/source/contract.js +28 -29
- package/dist/source/factory.d.ts +46 -58
- package/dist/source/factory.js +22 -27
- package/dist/source/index.d.ts +7 -9
- package/dist/source/index.js +12 -14
- package/dist/source/migrations.d.ts +9 -9
- package/dist/source/migrations.js +9 -9
- package/dist/source/next.d.ts +9 -10
- package/dist/source/next.js +6 -7
- package/dist/source/pushQueue.d.ts +69 -47
- package/dist/source/pushQueue.js +32 -28
- package/dist/source/signing.d.ts +46 -17
- package/dist/source/signing.js +28 -11
- package/dist/source/types.d.ts +121 -104
- package/dist/source/types.js +13 -14
- package/dist/stores/ObjectStore.d.ts +10 -11
- package/dist/stores/ObjectStore.js +11 -12
- package/dist/stores/ObjectStoreContract.d.ts +12 -15
- package/dist/stores/SyncActionStore.d.ts +7 -11
- package/dist/stores/SyncActionStore.js +13 -17
- package/dist/surface.d.ts +27 -20
- package/dist/surface.js +27 -20
- package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +36 -42
- package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +76 -76
- package/dist/sync/ConnectionManager.d.ts +39 -50
- package/dist/sync/ConnectionManager.js +55 -66
- package/dist/sync/NetworkProbe.d.ts +24 -29
- package/dist/sync/NetworkProbe.js +63 -69
- package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +42 -41
- package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +59 -54
- package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +43 -57
- package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +43 -51
- package/dist/sync/SyncWebSocket.d.ts +139 -165
- package/dist/sync/SyncWebSocket.js +191 -223
- package/dist/sync/awaitClaimGrant.d.ts +18 -18
- package/dist/sync/awaitClaimGrant.js +11 -11
- package/dist/sync/bootstrapApply.d.ts +34 -24
- package/dist/sync/bootstrapApply.js +27 -19
- package/dist/sync/commitFrames.d.ts +21 -20
- package/dist/sync/commitFrames.js +18 -18
- package/dist/sync/createClaimStream.d.ts +23 -22
- package/dist/sync/createClaimStream.js +105 -23
- package/dist/sync/createPresenceStream.d.ts +19 -18
- package/dist/sync/createPresenceStream.js +25 -26
- package/dist/sync/createSnapshot.d.ts +12 -14
- package/dist/sync/createSnapshot.js +20 -26
- package/dist/sync/credentialLifecycle.d.ts +104 -104
- package/dist/sync/credentialLifecycle.js +140 -147
- package/dist/sync/deltaPipeline.d.ts +36 -34
- package/dist/sync/deltaPipeline.js +64 -65
- package/dist/sync/groupChange.d.ts +63 -61
- package/dist/sync/groupChange.js +74 -78
- package/dist/sync/heartbeat.d.ts +34 -33
- package/dist/sync/heartbeat.js +31 -31
- package/dist/sync/participants.d.ts +19 -19
- package/dist/sync/schemas.d.ts +3 -2
- package/dist/sync/schemas.js +14 -10
- package/dist/sync/syncCursor.d.ts +17 -21
- package/dist/sync/syncCursor.js +17 -21
- package/dist/sync/syncPlan.d.ts +28 -36
- package/dist/sync/syncPlan.js +18 -19
- package/dist/sync/syncPosition.d.ts +54 -49
- package/dist/sync/syncPosition.js +57 -52
- package/dist/sync/wsFrameHandlers.d.ts +35 -36
- package/dist/sync/wsFrameHandlers.js +63 -67
- package/dist/testing/fixtures/bootstrap.d.ts +12 -6
- package/dist/testing/fixtures/bootstrap.js +12 -6
- package/dist/testing/fixtures/deltas.d.ts +30 -33
- package/dist/testing/fixtures/deltas.js +30 -33
- package/dist/testing/fixtures/models.d.ts +11 -10
- package/dist/testing/fixtures/models.js +11 -10
- package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
- package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
- package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -15
- package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +12 -10
- package/dist/testing/helpers/wait.d.ts +13 -8
- package/dist/testing/helpers/wait.js +13 -8
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +2 -2
- package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
- package/dist/testing/mocks/MockMutationExecutor.js +15 -14
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
- package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
- package/dist/testing/mocks/MockSyncContext.d.ts +20 -17
- package/dist/testing/mocks/MockSyncContext.js +15 -13
- package/dist/testing/mocks/MockSyncStore.d.ts +10 -10
- package/dist/testing/mocks/MockSyncStore.js +11 -11
- package/dist/testing/mocks/MockWebSocket.d.ts +26 -22
- package/dist/testing/mocks/MockWebSocket.js +22 -21
- package/dist/transactions/TransactionQueue.d.ts +181 -176
- package/dist/transactions/TransactionQueue.js +338 -350
- package/dist/transactions/TransactionStore.d.ts +6 -4
- package/dist/transactions/TransactionStore.js +6 -4
- package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
- package/dist/transactions/UnconfirmedWrites.js +104 -0
- package/dist/transactions/coalesceRules.d.ts +41 -17
- package/dist/transactions/coalesceRules.js +40 -17
- package/dist/transactions/commitPayload.d.ts +48 -52
- package/dist/transactions/commitPayload.js +48 -57
- package/dist/transactions/deltaConfirmation.d.ts +20 -22
- package/dist/transactions/deltaConfirmation.js +37 -45
- package/dist/transactions/optimisticApply.d.ts +49 -0
- package/dist/transactions/optimisticApply.js +65 -0
- package/dist/transactions/{persistedReplay.d.ts → replayValidation.d.ts} +28 -22
- package/dist/transactions/{persistedReplay.js → replayValidation.js} +33 -27
- package/dist/types/global.d.ts +46 -41
- package/dist/types/global.js +20 -19
- package/dist/types/index.d.ts +71 -77
- package/dist/types/index.js +22 -22
- package/dist/types/modelData.d.ts +6 -8
- package/dist/types/modelData.js +5 -7
- package/dist/types/participant.d.ts +10 -11
- package/dist/types/participant.js +6 -8
- package/dist/types/streams.d.ts +208 -195
- package/dist/types/streams.js +7 -7
- package/dist/utils/asyncIterator.d.ts +25 -32
- package/dist/utils/asyncIterator.js +25 -32
- package/dist/utils/duration.d.ts +12 -15
- package/dist/utils/duration.js +12 -15
- package/dist/utils/mobxSetup.d.ts +53 -0
- package/dist/utils/{mobx-setup.js → mobxSetup.js} +42 -98
- package/dist/webhooks/events.d.ts +21 -16
- package/dist/webhooks/events.js +10 -8
- package/dist/webhooks/index.d.ts +5 -7
- package/dist/webhooks/index.js +5 -7
- package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
- package/dist/wire/delta.js +114 -0
- package/dist/wire/errorEnvelope.d.ts +30 -31
- package/dist/wire/errorEnvelope.js +34 -40
- package/dist/wire/frames.d.ts +79 -86
- package/dist/wire/frames.js +26 -33
- package/dist/wire/index.d.ts +14 -12
- package/dist/wire/index.js +30 -26
- package/dist/wire/listEnvelope.d.ts +16 -23
- package/dist/wire/listEnvelope.js +7 -6
- package/dist/wire/protocol.d.ts +25 -32
- package/dist/wire/protocol.js +25 -32
- package/dist/wire/protocolVersion.d.ts +44 -40
- package/dist/wire/protocolVersion.js +44 -40
- package/docs/coordination.md +59 -0
- package/package.json +11 -10
- package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
- package/dist/ai-sdk/coordination-context.d.ts +0 -52
- package/dist/core/query-utils.d.ts +0 -34
- package/dist/core/query-utils.js +0 -59
- package/dist/schema/sync-delta-row.js +0 -103
- package/dist/schema/sync-delta-wire.js +0 -102
- package/dist/server/read-config.d.ts +0 -67
- package/dist/server/read-config.js +0 -8
- package/dist/server/storage-mode.d.ts +0 -8
- package/dist/server/storage-mode.js +0 -28
- package/dist/source/connector-protocol.d.ts +0 -159
- package/dist/source/connector-protocol.js +0 -161
- package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
- package/dist/transactions/OptimisticEchoTracker.js +0 -104
- package/dist/transactions/mutation-error-handler.d.ts +0 -5
- package/dist/transactions/mutation-error-handler.js +0 -39
- package/dist/transactions/optimistic.d.ts +0 -24
- package/dist/transactions/optimistic.js +0 -45
- package/dist/utils/mobx-setup.d.ts +0 -42
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Factories that build well-formed delta objects for tests. A delta, a
|
|
3
|
+
* {@link SyncAction}, is a single change to one model instance in the wire
|
|
4
|
+
* format the server sends: an insert, update, delete, archive, and so on.
|
|
5
|
+
* These helpers let tests construct deltas without a live server.
|
|
5
6
|
*/
|
|
6
7
|
let deltaCounter = 0;
|
|
7
8
|
/** Reset the delta counter (call in beforeEach for deterministic IDs) */
|
|
@@ -9,7 +10,7 @@ export function resetDeltaCounter() {
|
|
|
9
10
|
deltaCounter = 0;
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
+
* Builds a single delta ({@link SyncAction}) in the server's wire format.
|
|
13
14
|
*/
|
|
14
15
|
export function createDelta(options) {
|
|
15
16
|
deltaCounter++;
|
|
@@ -23,25 +24,25 @@ export function createDelta(options) {
|
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
26
|
-
*
|
|
27
|
+
* Builds an insert delta for a new entity.
|
|
27
28
|
*/
|
|
28
29
|
export function createInsertDelta(modelName, modelId, data, syncId) {
|
|
29
30
|
return createDelta({ modelName, modelId, action: 'I', data, id: syncId });
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
|
-
*
|
|
33
|
+
* Builds an update delta for an existing entity.
|
|
33
34
|
*/
|
|
34
35
|
export function createUpdateDelta(modelName, modelId, data, syncId) {
|
|
35
36
|
return createDelta({ modelName, modelId, action: 'U', data, id: syncId });
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
38
|
-
*
|
|
39
|
+
* Builds a delete delta.
|
|
39
40
|
*/
|
|
40
41
|
export function createDeleteDelta(modelName, modelId, syncId) {
|
|
41
42
|
return createDelta({ modelName, modelId, action: 'D', data: {}, id: syncId });
|
|
42
43
|
}
|
|
43
44
|
/**
|
|
44
|
-
*
|
|
45
|
+
* Builds an archive delta, stamping `archivedAt` with the current time.
|
|
45
46
|
*/
|
|
46
47
|
export function createArchiveDelta(modelName, modelId, syncId) {
|
|
47
48
|
return createDelta({
|
|
@@ -53,7 +54,7 @@ export function createArchiveDelta(modelName, modelId, syncId) {
|
|
|
53
54
|
});
|
|
54
55
|
}
|
|
55
56
|
/**
|
|
56
|
-
*
|
|
57
|
+
* Builds an unarchive delta, clearing `archivedAt`.
|
|
57
58
|
*/
|
|
58
59
|
export function createUnarchiveDelta(modelName, modelId, syncId) {
|
|
59
60
|
return createDelta({
|
|
@@ -65,22 +66,20 @@ export function createUnarchiveDelta(modelName, modelId, syncId) {
|
|
|
65
66
|
});
|
|
66
67
|
}
|
|
67
68
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* store as if newly created. Typically follows a GroupAdded delta.
|
|
69
|
+
* Builds a covering ('C') delta. It signals that the client has gained
|
|
70
|
+
* permission to see an entity that already exists. The client treats it
|
|
71
|
+
* like an insert, adding the entity to its local store as if newly created.
|
|
72
|
+
* A covering delta typically follows a group-added delta.
|
|
73
73
|
*/
|
|
74
74
|
export function createCoveringDelta(modelName, modelId, data, syncId) {
|
|
75
75
|
return createDelta({ modelName, modelId, action: 'C', data, id: syncId });
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* (addedGroups/removedGroups), this does not trigger a re-bootstrap.
|
|
78
|
+
* Builds a group-added ('G') delta in the incremental payload shape. It
|
|
79
|
+
* signals that the recipient was added to a single sync group. The client
|
|
80
|
+
* updates its subscription state and waits for covering deltas to deliver
|
|
81
|
+
* the newly visible entities. Unlike the older payload that carries both
|
|
82
|
+
* added and removed groups, this shape does not trigger a re-bootstrap.
|
|
84
83
|
*/
|
|
85
84
|
export function createGroupAddedDelta(userId, group, syncId) {
|
|
86
85
|
return createDelta({
|
|
@@ -92,11 +91,10 @@ export function createGroupAddedDelta(userId, group, syncId) {
|
|
|
92
91
|
});
|
|
93
92
|
}
|
|
94
93
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* the deprecated EmitGroupChange path.
|
|
94
|
+
* Builds a group-change ('G') delta in the older payload shape, which
|
|
95
|
+
* carries both added and removed groups in one delta and forces a full
|
|
96
|
+
* re-bootstrap on the client. Useful for testing backward compatibility
|
|
97
|
+
* with that older shape.
|
|
100
98
|
*/
|
|
101
99
|
export function createLegacyGroupChangeDelta(userId, added, removed, syncId) {
|
|
102
100
|
return createDelta({
|
|
@@ -108,11 +106,9 @@ export function createLegacyGroupChangeDelta(userId, added, removed, syncId) {
|
|
|
108
106
|
});
|
|
109
107
|
}
|
|
110
108
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* purges affected local state and triggers a re-bootstrap with the
|
|
115
|
-
* updated group list.
|
|
109
|
+
* Builds a group-removed ('S') delta. It signals that the recipient lost
|
|
110
|
+
* access to a sync group. The client purges the affected local state and
|
|
111
|
+
* re-bootstraps with the updated group list.
|
|
116
112
|
*/
|
|
117
113
|
export function createGroupRemovedDelta(userId, group, syncId) {
|
|
118
114
|
return createDelta({
|
|
@@ -124,15 +120,16 @@ export function createGroupRemovedDelta(userId, group, syncId) {
|
|
|
124
120
|
});
|
|
125
121
|
}
|
|
126
122
|
/**
|
|
127
|
-
*
|
|
123
|
+
* Builds a batch of deltas with sequential sync IDs.
|
|
128
124
|
*/
|
|
129
125
|
export function createDeltaBatch(deltas, startingSyncId) {
|
|
130
126
|
const start = startingSyncId ?? deltaCounter + 1;
|
|
131
127
|
return deltas.map((d, i) => createDelta({ ...d, id: start + i }));
|
|
132
128
|
}
|
|
133
129
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
130
|
+
* Builds a confirmation delta, which signals that a mutation was persisted
|
|
131
|
+
* by the server. The client's transaction queue watches for these to
|
|
132
|
+
* confirm its in-flight writes.
|
|
136
133
|
*/
|
|
137
134
|
export function createConfirmationDelta(modelName, modelId, syncId, action = 'U', data = {}) {
|
|
138
135
|
return createDelta({ modelName, modelId, action, data, id: syncId });
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* TestSlideDeck (10) → TestSlide (15, FK→SlideDeck) → TestSlideLayer (20, FK→Slide)
|
|
2
|
+
* A small set of {@link Model} subclasses used across the package's tests.
|
|
3
|
+
* They form two foreign-key chains and carry the creation priorities the
|
|
4
|
+
* transaction queue uses to order dependent writes:
|
|
5
|
+
* TestProject (10) → TestTask (10, references Project) → TestComment (30, references Task)
|
|
6
|
+
* TestSlideDeck (10) → TestSlide (15, references SlideDeck) → TestSlideLayer (20, references Slide)
|
|
8
7
|
*/
|
|
9
8
|
import { Model } from '../../Model.js';
|
|
10
9
|
import { ModelRegistry } from '../../ModelRegistry.js';
|
|
@@ -54,16 +53,18 @@ export declare class TestSlideLayer extends Model {
|
|
|
54
53
|
getModelName(): string;
|
|
55
54
|
}
|
|
56
55
|
/**
|
|
57
|
-
*
|
|
56
|
+
* Maps each test model to its creation priority, matching the order the
|
|
57
|
+
* transaction queue uses when writing dependent models.
|
|
58
58
|
*/
|
|
59
59
|
export declare const TEST_MODEL_PRIORITIES: Map<string, number>;
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
61
|
+
* Registers every test model with a {@link ModelRegistry}, wiring up their
|
|
62
|
+
* properties, references, and foreign-key relationships.
|
|
63
63
|
*/
|
|
64
64
|
export declare function registerTestModels(registry: ModelRegistry): void;
|
|
65
65
|
/**
|
|
66
|
-
*
|
|
66
|
+
* Builds a sync engine configuration pre-loaded with the test models'
|
|
67
|
+
* creation priorities and related settings.
|
|
67
68
|
*/
|
|
68
69
|
export declare function createTestConfig(): {
|
|
69
70
|
modelCreatePriority: ReadonlyMap<string, number>;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* TestSlideDeck (10) → TestSlide (15, FK→SlideDeck) → TestSlideLayer (20, FK→Slide)
|
|
2
|
+
* A small set of {@link Model} subclasses used across the package's tests.
|
|
3
|
+
* They form two foreign-key chains and carry the creation priorities the
|
|
4
|
+
* transaction queue uses to order dependent writes:
|
|
5
|
+
* TestProject (10) → TestTask (10, references Project) → TestComment (30, references Task)
|
|
6
|
+
* TestSlideDeck (10) → TestSlide (15, references SlideDeck) → TestSlideLayer (20, references Slide)
|
|
8
7
|
*/
|
|
9
8
|
import { Model } from '../../Model.js';
|
|
10
9
|
import { ModelRegistry } from '../../ModelRegistry.js';
|
|
@@ -127,7 +126,8 @@ export class TestSlideLayer extends Model {
|
|
|
127
126
|
// Model Registration Helper
|
|
128
127
|
// ─────────────────────────────────────────────
|
|
129
128
|
/**
|
|
130
|
-
*
|
|
129
|
+
* Maps each test model to its creation priority, matching the order the
|
|
130
|
+
* transaction queue uses when writing dependent models.
|
|
131
131
|
*/
|
|
132
132
|
export const TEST_MODEL_PRIORITIES = new Map([
|
|
133
133
|
['Project', 10],
|
|
@@ -138,8 +138,8 @@ export const TEST_MODEL_PRIORITIES = new Map([
|
|
|
138
138
|
['Comment', 30],
|
|
139
139
|
]);
|
|
140
140
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
141
|
+
* Registers every test model with a {@link ModelRegistry}, wiring up their
|
|
142
|
+
* properties, references, and foreign-key relationships.
|
|
143
143
|
*/
|
|
144
144
|
export function registerTestModels(registry) {
|
|
145
145
|
registry.startBatch();
|
|
@@ -183,7 +183,8 @@ export function registerTestModels(registry) {
|
|
|
183
183
|
// Test SyncEngineConfig factory
|
|
184
184
|
// ─────────────────────────────────────────────
|
|
185
185
|
/**
|
|
186
|
-
*
|
|
186
|
+
* Builds a sync engine configuration pre-loaded with the test models'
|
|
187
|
+
* creation priorities and related settings.
|
|
187
188
|
*/
|
|
188
189
|
export function createTestConfig() {
|
|
189
190
|
return {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* React
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* React testing helpers for this package. They wire the package's
|
|
3
|
+
* `SyncProvider` into `@testing-library/react` so you can test components
|
|
4
|
+
* and hooks built on `useModel`, `useModels`, and `useMutations` against a
|
|
5
|
+
* mock store, with no live server.
|
|
6
6
|
*/
|
|
7
7
|
import * as React from 'react';
|
|
8
8
|
import { type SyncStoreContract } from '../../react/context.js';
|
|
@@ -14,8 +14,10 @@ export interface TestWrapperOptions {
|
|
|
14
14
|
organizationId?: string;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Builds a wrapper component for `@testing-library/react`'s `renderHook`
|
|
18
|
+
* and `render`. It wraps the children in the package's `SyncProvider`,
|
|
19
|
+
* backed by a mock store, so the hooks and components under test can read
|
|
20
|
+
* from it. Pass your own store to seed specific data, or let one be created.
|
|
19
21
|
*
|
|
20
22
|
* @example
|
|
21
23
|
* import { renderHook } from '@testing-library/react';
|
|
@@ -33,11 +35,12 @@ export declare function createReactTestWrapper(options?: TestWrapperOptions): Re
|
|
|
33
35
|
children: React.ReactNode;
|
|
34
36
|
}>;
|
|
35
37
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
+
* A drop-in replacement for `@testing-library/react`'s `renderHook` that
|
|
39
|
+
* wraps the hook in the package's `SyncProvider` and a mock store for you,
|
|
40
|
+
* so you don't build the wrapper by hand.
|
|
38
41
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
42
|
+
* `@testing-library/react` is loaded lazily, so projects that don't use
|
|
43
|
+
* these helpers never have to install it.
|
|
41
44
|
*
|
|
42
45
|
* @example
|
|
43
46
|
* import { renderSyncHook, createMockSyncStore } from '@abloatai/ablo/testing';
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* React
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* React testing helpers for this package. They wire the package's
|
|
3
|
+
* `SyncProvider` into `@testing-library/react` so you can test components
|
|
4
|
+
* and hooks built on `useModel`, `useModels`, and `useMutations` against a
|
|
5
|
+
* mock store, with no live server.
|
|
6
6
|
*/
|
|
7
7
|
import * as React from 'react';
|
|
8
8
|
import { SyncProvider } from '../../react/context.js';
|
|
9
9
|
import { MockSyncStore, createMockSyncStore } from '../mocks/MockSyncStore.js';
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* Builds a wrapper component for `@testing-library/react`'s `renderHook`
|
|
12
|
+
* and `render`. It wraps the children in the package's `SyncProvider`,
|
|
13
|
+
* backed by a mock store, so the hooks and components under test can read
|
|
14
|
+
* from it. Pass your own store to seed specific data, or let one be created.
|
|
13
15
|
*
|
|
14
16
|
* @example
|
|
15
17
|
* import { renderHook } from '@testing-library/react';
|
|
@@ -30,11 +32,12 @@ export function createReactTestWrapper(options = {}) {
|
|
|
30
32
|
return Wrapper;
|
|
31
33
|
}
|
|
32
34
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
+
* A drop-in replacement for `@testing-library/react`'s `renderHook` that
|
|
36
|
+
* wraps the hook in the package's `SyncProvider` and a mock store for you,
|
|
37
|
+
* so you don't build the wrapper by hand.
|
|
35
38
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
39
|
+
* `@testing-library/react` is loaded lazily, so projects that don't use
|
|
40
|
+
* these helpers never have to install it.
|
|
38
41
|
*
|
|
39
42
|
* @example
|
|
40
43
|
* import { renderSyncHook, createMockSyncStore } from '@abloatai/ablo/testing';
|
|
@@ -49,8 +52,8 @@ export function createReactTestWrapper(options = {}) {
|
|
|
49
52
|
* expect(result.current?.id).toBe(myTask.id);
|
|
50
53
|
*/
|
|
51
54
|
export function renderSyncHook(callback, options = {}) {
|
|
52
|
-
//
|
|
53
|
-
// to install it
|
|
55
|
+
// Load @testing-library/react lazily so projects that never call these
|
|
56
|
+
// helpers don't have to install it.
|
|
54
57
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
55
58
|
const rtl = require('@testing-library/react');
|
|
56
59
|
return rtl.renderHook(callback, {
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* An integration-test harness that assembles a full sync engine stack —
|
|
3
|
+
* the model registry, object pool, transaction queue, and related parts —
|
|
4
|
+
* from the real implementations, but with mocked input and output. It lets
|
|
5
|
+
* tests exercise the engine end to end without a network or a live server.
|
|
6
6
|
*/
|
|
7
7
|
import { ModelRegistry } from '../../ModelRegistry.js';
|
|
8
|
-
import {
|
|
8
|
+
import { InstanceCache } from '../../InstanceCache.js';
|
|
9
9
|
import { MockMutationExecutor } from '../mocks/MockMutationExecutor.js';
|
|
10
10
|
import { MockNetworkMonitor } from '../mocks/MockNetworkMonitor.js';
|
|
11
11
|
import { MockWebSocket } from '../mocks/MockWebSocket.js';
|
|
12
12
|
import type { TestContextResult } from '../mocks/MockSyncContext.js';
|
|
13
13
|
export interface TestHarness {
|
|
14
|
-
/**
|
|
14
|
+
/** A model registry pre-loaded with the test models. */
|
|
15
15
|
registry: ModelRegistry;
|
|
16
|
-
/**
|
|
17
|
-
pool:
|
|
18
|
-
/**
|
|
16
|
+
/** A real object pool with the test foreign-key indexes configured. */
|
|
17
|
+
pool: InstanceCache;
|
|
18
|
+
/** A mock WebSocket for injecting deltas into the engine. */
|
|
19
19
|
webSocket: MockWebSocket;
|
|
20
|
-
/**
|
|
20
|
+
/** The dependency-injection context holding every mock. */
|
|
21
21
|
context: TestContextResult;
|
|
22
|
-
/** Shorthand
|
|
22
|
+
/** Shorthand for the mock mutation executor on {@link context}. */
|
|
23
23
|
mutationExecutor: MockMutationExecutor;
|
|
24
|
-
/** Shorthand
|
|
24
|
+
/** Shorthand for the mock network monitor on {@link context}. */
|
|
25
25
|
networkMonitor: MockNetworkMonitor;
|
|
26
|
-
/**
|
|
26
|
+
/** Tears down the harness and resets its counters. */
|
|
27
27
|
cleanup: () => void;
|
|
28
28
|
}
|
|
29
29
|
export interface TestHarnessOptions {
|
|
@@ -31,7 +31,7 @@ export interface TestHarnessOptions {
|
|
|
31
31
|
startOffline?: boolean;
|
|
32
32
|
/** Initial sync ID for mutation executor */
|
|
33
33
|
initialSyncId?: number;
|
|
34
|
-
/**
|
|
34
|
+
/** InstanceCache config overrides */
|
|
35
35
|
poolConfig?: {
|
|
36
36
|
maxSize?: number;
|
|
37
37
|
maxAge?: number;
|
|
@@ -40,7 +40,9 @@ export interface TestHarnessOptions {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
43
|
+
* Builds a full test harness: real sync engine components wired to mocked
|
|
44
|
+
* input and output. Reset the counters and tear everything down through the
|
|
45
|
+
* returned {@link TestHarness.cleanup}.
|
|
44
46
|
*
|
|
45
47
|
* Usage:
|
|
46
48
|
* ```ts
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* An integration-test harness that assembles a full sync engine stack —
|
|
3
|
+
* the model registry, object pool, transaction queue, and related parts —
|
|
4
|
+
* from the real implementations, but with mocked input and output. It lets
|
|
5
|
+
* tests exercise the engine end to end without a network or a live server.
|
|
6
6
|
*/
|
|
7
7
|
import { ModelRegistry, setActiveRegistry } from '../../ModelRegistry.js';
|
|
8
|
-
import {
|
|
8
|
+
import { InstanceCache } from '../../InstanceCache.js';
|
|
9
9
|
import { MockMutationExecutor } from '../mocks/MockMutationExecutor.js';
|
|
10
10
|
import { MockNetworkMonitor } from '../mocks/MockNetworkMonitor.js';
|
|
11
11
|
import { MockWebSocket } from '../mocks/MockWebSocket.js';
|
|
@@ -13,7 +13,9 @@ import { createTestContext } from '../mocks/MockSyncContext.js';
|
|
|
13
13
|
import { registerTestModels, createTestConfig, resetFixtureCounter, } from '../fixtures/models.js';
|
|
14
14
|
import { resetDeltaCounter } from '../fixtures/deltas.js';
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* Builds a full test harness: real sync engine components wired to mocked
|
|
17
|
+
* input and output. Reset the counters and tear everything down through the
|
|
18
|
+
* returned {@link TestHarness.cleanup}.
|
|
17
19
|
*
|
|
18
20
|
* Usage:
|
|
19
21
|
* ```ts
|
|
@@ -30,7 +32,7 @@ export function createTestHarness(options = {}) {
|
|
|
30
32
|
const registry = new ModelRegistry();
|
|
31
33
|
setActiveRegistry(registry);
|
|
32
34
|
registerTestModels(registry);
|
|
33
|
-
// Create
|
|
35
|
+
// Create the dependency-injection context with the test config
|
|
34
36
|
const testConfig = createTestConfig();
|
|
35
37
|
const context = createTestContext({
|
|
36
38
|
config: testConfig,
|
|
@@ -39,14 +41,14 @@ export function createTestHarness(options = {}) {
|
|
|
39
41
|
initialSyncId: options.initialSyncId ?? 1,
|
|
40
42
|
},
|
|
41
43
|
});
|
|
42
|
-
// Create real
|
|
43
|
-
const pool = new
|
|
44
|
+
// Create the real object pool with foreign-key indexes
|
|
45
|
+
const pool = new InstanceCache({
|
|
44
46
|
maxSize: options.poolConfig?.maxSize ?? 10000,
|
|
45
47
|
maxAge: options.poolConfig?.maxAge ?? 5 * 60 * 1000,
|
|
46
48
|
gcInterval: options.poolConfig?.gcInterval ?? 0, // Disable auto-GC in tests
|
|
47
49
|
useWeakRefs: options.poolConfig?.useWeakRefs ?? false, // Disable WeakRefs for predictable tests
|
|
48
50
|
}, registry);
|
|
49
|
-
// Register
|
|
51
|
+
// Register foreign-key indexes for the test models
|
|
50
52
|
pool.registerForeignKey('Task', 'projectId');
|
|
51
53
|
pool.registerForeignKey('Comment', 'taskId');
|
|
52
54
|
pool.registerForeignKey('Slide', 'deckId');
|
|
@@ -1,25 +1,30 @@
|
|
|
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
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* Flushes all pending microtasks, such as resolved promises and
|
|
7
|
+
* `queueMicrotask` callbacks. Useful for testing work the transaction queue
|
|
8
|
+
* batches on the microtask queue.
|
|
7
9
|
*/
|
|
8
10
|
export declare function flushMicrotasks(): Promise<void>;
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
+
* Polls `condition` until it returns true, checking every `interval`
|
|
13
|
+
* milliseconds. Rejects with an {@link AbloConnectionError} if `maxWait`
|
|
14
|
+
* milliseconds pass first.
|
|
12
15
|
*/
|
|
13
16
|
export declare function waitFor(condition: () => boolean, options?: {
|
|
14
17
|
maxWait?: number;
|
|
15
18
|
interval?: number;
|
|
16
19
|
}): Promise<void>;
|
|
17
20
|
/**
|
|
18
|
-
*
|
|
21
|
+
* Waits for the given number of milliseconds. Use sparingly; prefer
|
|
22
|
+
* {@link flushMicrotasks} or {@link waitFor}, which don't tie tests to
|
|
23
|
+
* wall-clock time.
|
|
19
24
|
*/
|
|
20
25
|
export declare function delay(ms: number): Promise<void>;
|
|
21
26
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
27
|
+
* Flushes pending microtasks, then runs `fn` and returns its result. Handy
|
|
28
|
+
* for asserting state after the transaction queue processes a batch.
|
|
24
29
|
*/
|
|
25
30
|
export declare function afterMicrotasks<T>(fn: () => T): Promise<T>;
|
|
@@ -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
|
@@ -15,7 +15,7 @@ export { TestProject, TestTask, TestComment, TestSlideDeck, TestSlide, TestSlide
|
|
|
15
15
|
export { createDelta, createInsertDelta, createUpdateDelta, createDeleteDelta, createArchiveDelta, createUnarchiveDelta, createCoveringDelta, createGroupAddedDelta, createLegacyGroupChangeDelta, createGroupRemovedDelta, createDeltaBatch, createConfirmationDelta, resetDeltaCounter, } from './fixtures/deltas.js';
|
|
16
16
|
export { createFullBootstrapResponse, createPartialBootstrapResponse, createTestBootstrapResponse, } from './fixtures/bootstrap.js';
|
|
17
17
|
export type { BootstrapModelData, BootstrapResponse } from './fixtures/bootstrap.js';
|
|
18
|
-
export { createTestHarness, } from './helpers/
|
|
19
|
-
export type { TestHarness, TestHarnessOptions } from './helpers/
|
|
18
|
+
export { createTestHarness, } from './helpers/syncEngineHarness.js';
|
|
19
|
+
export type { TestHarness, TestHarnessOptions } from './helpers/syncEngineHarness.js';
|
|
20
20
|
export { flushMicrotasks, waitFor, delay, afterMicrotasks, } from './helpers/wait.js';
|
|
21
|
-
export { createReactTestWrapper, renderSyncHook, MockSyncStore, createMockSyncStore, type TestWrapperOptions, } from './helpers/
|
|
21
|
+
export { createReactTestWrapper, renderSyncHook, MockSyncStore, createMockSyncStore, type TestWrapperOptions, } from './helpers/reactWrapper.js';
|
package/dist/testing/index.js
CHANGED
|
@@ -26,7 +26,7 @@ export { createFullBootstrapResponse, createPartialBootstrapResponse, createTest
|
|
|
26
26
|
// ─────────────────────────────────────────────
|
|
27
27
|
// Helpers
|
|
28
28
|
// ─────────────────────────────────────────────
|
|
29
|
-
export { createTestHarness, } from './helpers/
|
|
29
|
+
export { createTestHarness, } from './helpers/syncEngineHarness.js';
|
|
30
30
|
export { flushMicrotasks, waitFor, delay, afterMicrotasks, } from './helpers/wait.js';
|
|
31
31
|
// React testing helpers
|
|
32
|
-
export { createReactTestWrapper, renderSyncHook, MockSyncStore, createMockSyncStore, } from './helpers/
|
|
32
|
+
export { createReactTestWrapper, renderSyncHook, MockSyncStore, createMockSyncStore, } from './helpers/reactWrapper.js';
|
|
@@ -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>;
|