@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,32 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* The error raised when opening an IndexedDB database does not complete in a
|
|
3
|
+
* bounded time. {@link openIDBWithTimeout} throws it in two situations: another
|
|
4
|
+
* browser tab is holding an older version of the database open and blocking the
|
|
5
|
+
* upgrade (`reason: 'blocked'`), or the open request produced no result at all
|
|
6
|
+
* within the timeout (`reason: 'timeout'`).
|
|
4
7
|
*
|
|
5
|
-
* The native
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* This helper converts that into a real error after a bounded wait, which
|
|
12
|
-
* flows up through `engine.ready()` → `SyncEngineProvider.handleError()` →
|
|
13
|
-
* the error skeleton with a retry button. A visible error is strictly better
|
|
14
|
-
* than a forever-spinner the user can only escape by closing the tab.
|
|
8
|
+
* The native open request can otherwise hang indefinitely — when a blocking tab
|
|
9
|
+
* never closes its connection, neither the success nor the error callback fires,
|
|
10
|
+
* and any code awaiting the open waits forever. Turning that into a thrown error
|
|
11
|
+
* lets the surrounding application show a recoverable failure instead of an
|
|
12
|
+
* unbreakable spinner.
|
|
15
13
|
*/
|
|
16
14
|
export declare class IDBOpenTimeoutError extends Error {
|
|
17
15
|
readonly dbName: string;
|
|
18
16
|
readonly reason: 'blocked' | 'timeout';
|
|
19
17
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* brittle message match.
|
|
18
|
+
* A stable identifier for this failure, independent of the message text. When
|
|
19
|
+
* this error is wrapped into an {@link AbloError} by `toAbloError`, the string
|
|
20
|
+
* code is preserved, so error handlers can recognize a wedged-storage failure
|
|
21
|
+
* and offer a recovery path rather than matching on the message.
|
|
25
22
|
*/
|
|
26
23
|
readonly code = "storage_open_timeout";
|
|
27
24
|
constructor(dbName: string, reason: 'blocked' | 'timeout', message: string);
|
|
28
25
|
}
|
|
29
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Returns true when a caught value is the storage-open-timeout failure. It
|
|
28
|
+
* detects the failure by its stable `code`, so it still matches after the error
|
|
29
|
+
* has been wrapped into an {@link AbloError} or another error type.
|
|
30
|
+
*/
|
|
30
31
|
export declare function isStorageOpenTimeout(err: unknown): boolean;
|
|
31
32
|
export interface OpenIDBOptions {
|
|
32
33
|
/** Called inside `onupgradeneeded` — mirrors `IDBOpenDBRequest.onupgradeneeded`. */
|
|
@@ -34,30 +35,31 @@ export interface OpenIDBOptions {
|
|
|
34
35
|
/** Max milliseconds to wait for the open request to resolve. Default 10_000. */
|
|
35
36
|
timeoutMs?: number;
|
|
36
37
|
/**
|
|
37
|
-
* Called when another context
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
38
|
+
* Called when another context — a new tab, a page reload after a deploy, or
|
|
39
|
+
* this package's own {@link deleteIDBWithTimeout} recovery — needs to upgrade
|
|
40
|
+
* or delete the database and fires a `versionchange` event on this connection.
|
|
41
|
+
* The connection is always closed first, which is what lets the other
|
|
42
|
+
* context's upgrade or delete proceed instead of blocking on this one. Provide
|
|
43
|
+
* this callback to react after that close, for example to prompt the user to
|
|
44
|
+
* reload. Any error it throws is ignored.
|
|
43
45
|
*/
|
|
44
46
|
onVersionChange?: () => void;
|
|
45
47
|
}
|
|
46
48
|
export declare function openIDBWithTimeout(name: string, version: number | undefined, options?: OpenIDBOptions): Promise<IDBDatabase>;
|
|
47
49
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
50
|
+
* Deletes an IndexedDB database within a bounded time — the delete counterpart
|
|
51
|
+
* to {@link openIDBWithTimeout}. It is used to recover from a wedged backing
|
|
52
|
+
* store: when opening a database times out, the caller can delete it and start
|
|
53
|
+
* fresh, which is safe for any database whose contents can be rebuilt on the
|
|
54
|
+
* next load.
|
|
53
55
|
*
|
|
54
|
-
* Like
|
|
55
|
-
*
|
|
56
|
-
* store it fires
|
|
57
|
-
*
|
|
56
|
+
* Like an open request, a native delete can hang indefinitely — it fires a
|
|
57
|
+
* blocked event and waits when another connection still holds the database, and
|
|
58
|
+
* on a truly stuck store it fires no event at all. Both cases become a bounded,
|
|
59
|
+
* resolved result here, so the caller never spins.
|
|
58
60
|
*
|
|
59
|
-
* Resolves `true` on a clean delete
|
|
60
|
-
*
|
|
61
|
-
* leaves
|
|
61
|
+
* Resolves to `true` on a clean delete and `false` when the delete was blocked
|
|
62
|
+
* or timed out. Either way the caller can decide whether to retry the open; a
|
|
63
|
+
* delete that did nothing leaves the store no worse off.
|
|
62
64
|
*/
|
|
63
65
|
export declare function deleteIDBWithTimeout(name: string, timeoutMs?: number): Promise<boolean>;
|
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* The error raised when opening an IndexedDB database does not complete in a
|
|
3
|
+
* bounded time. {@link openIDBWithTimeout} throws it in two situations: another
|
|
4
|
+
* browser tab is holding an older version of the database open and blocking the
|
|
5
|
+
* upgrade (`reason: 'blocked'`), or the open request produced no result at all
|
|
6
|
+
* within the timeout (`reason: 'timeout'`).
|
|
4
7
|
*
|
|
5
|
-
* The native
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* This helper converts that into a real error after a bounded wait, which
|
|
12
|
-
* flows up through `engine.ready()` → `SyncEngineProvider.handleError()` →
|
|
13
|
-
* the error skeleton with a retry button. A visible error is strictly better
|
|
14
|
-
* than a forever-spinner the user can only escape by closing the tab.
|
|
8
|
+
* The native open request can otherwise hang indefinitely — when a blocking tab
|
|
9
|
+
* never closes its connection, neither the success nor the error callback fires,
|
|
10
|
+
* and any code awaiting the open waits forever. Turning that into a thrown error
|
|
11
|
+
* lets the surrounding application show a recoverable failure instead of an
|
|
12
|
+
* unbreakable spinner.
|
|
15
13
|
*/
|
|
16
14
|
export class IDBOpenTimeoutError extends Error {
|
|
17
15
|
dbName;
|
|
18
16
|
reason;
|
|
19
17
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* brittle message match.
|
|
18
|
+
* A stable identifier for this failure, independent of the message text. When
|
|
19
|
+
* this error is wrapped into an {@link AbloError} by `toAbloError`, the string
|
|
20
|
+
* code is preserved, so error handlers can recognize a wedged-storage failure
|
|
21
|
+
* and offer a recovery path rather than matching on the message.
|
|
25
22
|
*/
|
|
26
23
|
code = 'storage_open_timeout';
|
|
27
24
|
constructor(dbName, reason, message) {
|
|
@@ -31,7 +28,11 @@ export class IDBOpenTimeoutError extends Error {
|
|
|
31
28
|
this.name = 'IDBOpenTimeoutError';
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Returns true when a caught value is the storage-open-timeout failure. It
|
|
33
|
+
* detects the failure by its stable `code`, so it still matches after the error
|
|
34
|
+
* has been wrapped into an {@link AbloError} or another error type.
|
|
35
|
+
*/
|
|
35
36
|
export function isStorageOpenTimeout(err) {
|
|
36
37
|
return (typeof err === 'object' &&
|
|
37
38
|
err !== null &&
|
|
@@ -57,13 +58,12 @@ export function openIDBWithTimeout(name, version, options = {}) {
|
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
60
|
request.onsuccess = () => {
|
|
60
|
-
// If we
|
|
61
|
+
// If we already timed out or were blocked and rejected, this is a late
|
|
61
62
|
// success: the native open eventually completed after we gave up. The
|
|
62
|
-
// resulting connection is orphaned —
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
// mode). Close it here so a timed-out attempt can't poison the store.
|
|
63
|
+
// resulting connection is orphaned — nothing up the stack holds it, so
|
|
64
|
+
// nothing will close it. A leaked open connection holds an IndexedDB lock
|
|
65
|
+
// that wedges every later open or delete of this database name, so close
|
|
66
|
+
// it here to keep a timed-out attempt from poisoning the store.
|
|
67
67
|
if (settled) {
|
|
68
68
|
try {
|
|
69
69
|
request.result.close();
|
|
@@ -74,13 +74,12 @@ export function openIDBWithTimeout(name, version, options = {}) {
|
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
76
|
const db = request.result;
|
|
77
|
-
//
|
|
78
|
-
// connection
|
|
79
|
-
//
|
|
80
|
-
// the other context's request indefinitely —
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
// event). Auto-closing here makes the store self-releasing.
|
|
77
|
+
// Required resilience handler per the IndexedDB specification: close this
|
|
78
|
+
// connection as soon as any other context wants to upgrade or delete the
|
|
79
|
+
// database. Without it, a connection that ignores `versionchange` blocks
|
|
80
|
+
// the other context's request indefinitely — a common cause of a database
|
|
81
|
+
// that stays wedged across reloads. Closing here makes the store release
|
|
82
|
+
// itself.
|
|
84
83
|
db.onversionchange = () => {
|
|
85
84
|
try {
|
|
86
85
|
db.close();
|
|
@@ -120,20 +119,20 @@ export function openIDBWithTimeout(name, version, options = {}) {
|
|
|
120
119
|
});
|
|
121
120
|
}
|
|
122
121
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
122
|
+
* Deletes an IndexedDB database within a bounded time — the delete counterpart
|
|
123
|
+
* to {@link openIDBWithTimeout}. It is used to recover from a wedged backing
|
|
124
|
+
* store: when opening a database times out, the caller can delete it and start
|
|
125
|
+
* fresh, which is safe for any database whose contents can be rebuilt on the
|
|
126
|
+
* next load.
|
|
128
127
|
*
|
|
129
|
-
* Like
|
|
130
|
-
*
|
|
131
|
-
* store it fires
|
|
132
|
-
*
|
|
128
|
+
* Like an open request, a native delete can hang indefinitely — it fires a
|
|
129
|
+
* blocked event and waits when another connection still holds the database, and
|
|
130
|
+
* on a truly stuck store it fires no event at all. Both cases become a bounded,
|
|
131
|
+
* resolved result here, so the caller never spins.
|
|
133
132
|
*
|
|
134
|
-
* Resolves `true` on a clean delete
|
|
135
|
-
*
|
|
136
|
-
* leaves
|
|
133
|
+
* Resolves to `true` on a clean delete and `false` when the delete was blocked
|
|
134
|
+
* or timed out. Either way the caller can decide whether to retry the open; a
|
|
135
|
+
* delete that did nothing leaves the store no worse off.
|
|
137
136
|
*/
|
|
138
137
|
export function deleteIDBWithTimeout(name, timeoutMs = 5_000) {
|
|
139
138
|
return new Promise((resolve) => {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small, self-contained helpers for sorting, filtering, and binary insertion.
|
|
3
|
+
* The incrementally-updated views that implement {@link IncrementalView} rely on
|
|
4
|
+
* these for their ordering and matching, so keeping the rules in one place
|
|
5
|
+
* ensures every view sorts and filters identically. The functions here work on
|
|
6
|
+
* plain arrays and values — they hold no reference to models, pools, or the
|
|
7
|
+
* reactivity system.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The interface a live view implements to receive incremental updates: one call
|
|
11
|
+
* when an entity is added, one when it changes, and one when it is removed. A
|
|
12
|
+
* view registry holds its views under this non-generic base type so it can keep
|
|
13
|
+
* views over different entity shapes in a single collection and notify them
|
|
14
|
+
* uniformly. Because a generic `View<T>` is invariant in `T`, this shared base
|
|
15
|
+
* is what lets the registry store and dispatch to them without unsafe casts.
|
|
16
|
+
*/
|
|
17
|
+
export interface IncrementalView {
|
|
18
|
+
handleAdded(entity: Record<string, unknown>): void;
|
|
19
|
+
handleUpdated(entity: Record<string, unknown>): void;
|
|
20
|
+
handleRemoved(id: string): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Compares two values for sorting, tolerating `null` and `undefined`, which
|
|
24
|
+
* always sort last regardless of direction. `dir` is 1 for ascending or -1 for
|
|
25
|
+
* descending. Returns -1, 0, or 1.
|
|
26
|
+
*/
|
|
27
|
+
export declare function compareValues(a: unknown, b: unknown, dir: 1 | -1): number;
|
|
28
|
+
/**
|
|
29
|
+
* Finds, by binary search, the index at which `item` should be inserted to keep
|
|
30
|
+
* an array ordered. The array must already be sorted by `sortKey` in direction
|
|
31
|
+
* `dir`, using the same rule as {@link compareValues}. Returns that insertion
|
|
32
|
+
* index.
|
|
33
|
+
*/
|
|
34
|
+
export declare function binaryInsertionIndex<T>(arr: ArrayLike<T>, item: T, sortKey: string, dir: 1 | -1): number;
|
|
35
|
+
/**
|
|
36
|
+
* Returns true when an entity satisfies a declarative `where` filter: every key
|
|
37
|
+
* present in `where` must equal the entity's value for that key. A key whose
|
|
38
|
+
* filter value is `undefined` is skipped, so a partially-filled filter matches
|
|
39
|
+
* on only its defined keys.
|
|
40
|
+
*/
|
|
41
|
+
export declare function matchesWhere<T extends Record<string, unknown>>(entity: T, where: Partial<T>): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Find the index of an entity by id in an array. Returns -1 if not found.
|
|
44
|
+
*/
|
|
45
|
+
export declare function findIndexById<T extends Record<string, unknown>>(arr: ArrayLike<T>, id: string): number;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small, self-contained helpers for sorting, filtering, and binary insertion.
|
|
3
|
+
* The incrementally-updated views that implement {@link IncrementalView} rely on
|
|
4
|
+
* these for their ordering and matching, so keeping the rules in one place
|
|
5
|
+
* ensures every view sorts and filters identically. The functions here work on
|
|
6
|
+
* plain arrays and values — they hold no reference to models, pools, or the
|
|
7
|
+
* reactivity system.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Compares two values for sorting, tolerating `null` and `undefined`, which
|
|
11
|
+
* always sort last regardless of direction. `dir` is 1 for ascending or -1 for
|
|
12
|
+
* descending. Returns -1, 0, or 1.
|
|
13
|
+
*/
|
|
14
|
+
export function compareValues(a, b, dir) {
|
|
15
|
+
if (a === b)
|
|
16
|
+
return 0;
|
|
17
|
+
if (a == null)
|
|
18
|
+
return 1;
|
|
19
|
+
if (b == null)
|
|
20
|
+
return -1;
|
|
21
|
+
return (a < b ? -1 : 1) * dir;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Finds, by binary search, the index at which `item` should be inserted to keep
|
|
25
|
+
* an array ordered. The array must already be sorted by `sortKey` in direction
|
|
26
|
+
* `dir`, using the same rule as {@link compareValues}. Returns that insertion
|
|
27
|
+
* index.
|
|
28
|
+
*/
|
|
29
|
+
export function binaryInsertionIndex(arr, item, sortKey, dir) {
|
|
30
|
+
let lo = 0;
|
|
31
|
+
let hi = arr.length;
|
|
32
|
+
const itemVal = item[sortKey];
|
|
33
|
+
while (lo < hi) {
|
|
34
|
+
const mid = (lo + hi) >>> 1;
|
|
35
|
+
const midVal = arr[mid][sortKey];
|
|
36
|
+
if (compareValues(midVal, itemVal, dir) <= 0) {
|
|
37
|
+
lo = mid + 1;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
hi = mid;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return lo;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Returns true when an entity satisfies a declarative `where` filter: every key
|
|
47
|
+
* present in `where` must equal the entity's value for that key. A key whose
|
|
48
|
+
* filter value is `undefined` is skipped, so a partially-filled filter matches
|
|
49
|
+
* on only its defined keys.
|
|
50
|
+
*/
|
|
51
|
+
export function matchesWhere(entity, where) {
|
|
52
|
+
for (const [key, value] of Object.entries(where)) {
|
|
53
|
+
if (value === undefined)
|
|
54
|
+
continue;
|
|
55
|
+
if (entity[key] !== value)
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Find the index of an entity by id in an array. Returns -1 if not found.
|
|
62
|
+
*/
|
|
63
|
+
export function findIndexById(arr, id) {
|
|
64
|
+
for (let i = 0; i < arr.length; i++) {
|
|
65
|
+
if (arr[i]?.id === id)
|
|
66
|
+
return i;
|
|
67
|
+
}
|
|
68
|
+
return -1;
|
|
69
|
+
}
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The framework-neutral store contract. {@link SyncStoreContract} is the minimal
|
|
3
|
+
* store interface the SDK's hooks and mutators are written against, and
|
|
4
|
+
* {@link BaseSyncedStore} is the concrete class that implements it. Framework
|
|
5
|
+
* integrations, such as the React bindings, re-export these types, so a hook can
|
|
6
|
+
* accept any store that satisfies the contract without depending on a particular
|
|
7
|
+
* UI framework.
|
|
3
8
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* that implements it. The contract used to live in `react/context.ts`, which
|
|
7
|
-
* meant the CORE store layer imported its own contract from the React
|
|
8
|
-
* adapter (a module that runtime-imports 'react') — an L2-core →
|
|
9
|
-
* react-integration inversion and a module cycle. It now lives here, in a
|
|
10
|
-
* dependency-free core leaf: `react/context.ts` re-exports these types so
|
|
11
|
-
* React consumers are unchanged, and the core layer never touches 'react'.
|
|
12
|
-
*
|
|
13
|
-
* Everything in this module is type-only — no runtime imports, no runtime
|
|
14
|
-
* exports beyond erased interfaces.
|
|
9
|
+
* This module is type-only: it has no runtime imports and contributes nothing to
|
|
10
|
+
* the runtime bundle beyond the erased interface declarations.
|
|
15
11
|
*/
|
|
16
12
|
import type { Model } from '../Model.js';
|
|
17
13
|
import type { ModelScope } from '../types/index.js';
|
|
18
14
|
import type { QueryView, QueryViewOptions } from './QueryView.js';
|
|
19
15
|
import type { ViewRegistry } from './ViewRegistry.js';
|
|
20
16
|
import type { ParticipantScope } from '../sync/participants.js';
|
|
21
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* A snapshot of the client's synchronization state, shaped for binding to UI.
|
|
19
|
+
* {@link SyncStoreContract.syncStatus} exposes a reactive instance of this, and
|
|
20
|
+
* the `useSyncStatus()` hook reads its fields to render connection and progress
|
|
21
|
+
* indicators.
|
|
22
|
+
*/
|
|
22
23
|
export interface SyncStatus {
|
|
23
24
|
state: 'idle' | 'syncing' | 'error' | 'offline' | 'reconnecting';
|
|
24
25
|
progress: number;
|
|
@@ -30,39 +31,41 @@ export interface SyncStatus {
|
|
|
30
31
|
offlineSince?: Date;
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
|
-
* A single
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* This mirrors how Yjs's `UndoManager` derives reverse-ops by observing the
|
|
42
|
-
* doc and Liveblocks' `room.history` records room ops: undo listens to the
|
|
43
|
-
* one place all local writes converge, rather than wrapping the write call.
|
|
34
|
+
* A single locally-originated mutation, observed as it flows through the commit
|
|
35
|
+
* stream. The undo system records these to build its inverse operations: one is
|
|
36
|
+
* emitted per local create, update, delete, or archive. Changes arriving from
|
|
37
|
+
* other participants do not appear here — they apply through a separate path
|
|
38
|
+
* that does not queue mutations. Because `previousData` captures the field
|
|
39
|
+
* values as they were before the edit, each event carries everything needed to
|
|
40
|
+
* derive its inverse, with no separate snapshot step. A store exposes this
|
|
41
|
+
* stream through {@link SyncStoreContract.subscribeLocalMutations}.
|
|
44
42
|
*/
|
|
45
43
|
export interface LocalMutation {
|
|
46
44
|
type: 'create' | 'update' | 'delete' | 'archive' | 'unarchive';
|
|
47
|
-
/**
|
|
45
|
+
/** The registered name of the mutated model, for example `'SlideLayer'`. */
|
|
48
46
|
modelName: string;
|
|
49
47
|
modelId: string;
|
|
50
|
-
/**
|
|
48
|
+
/** The new field values, for a create or an update. */
|
|
51
49
|
data?: Record<string, unknown> | null;
|
|
52
|
-
/**
|
|
50
|
+
/** The field values as they were before the edit. For an update these form
|
|
51
|
+
* the inverse patch; for a delete they hold the full row needed to recreate
|
|
52
|
+
* it. */
|
|
53
53
|
previousData?: Record<string, unknown> | null;
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
56
|
+
* The minimal store interface the SDK's hooks and mutators depend on. Provide a
|
|
57
|
+
* concrete store that implements it — {@link BaseSyncedStore} is the built-in
|
|
58
|
+
* implementation — and the hooks work against your store without knowing its
|
|
59
|
+
* exact type. Optional members exist so lightweight test doubles can implement
|
|
60
|
+
* only the parts they exercise.
|
|
58
61
|
*/
|
|
59
62
|
export interface SyncStoreContract {
|
|
60
63
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
64
|
+
* Subscribes to the stream of local mutations for undo recording, delivering
|
|
65
|
+
* each optimistic write before it is acknowledged by the server. See
|
|
66
|
+
* {@link LocalMutation}. Returns a function that removes the subscription.
|
|
67
|
+
* This is optional: when a store does not implement it, undo scopes simply
|
|
68
|
+
* record nothing.
|
|
66
69
|
*/
|
|
67
70
|
subscribeLocalMutations?(handler: (mutation: LocalMutation) => void): () => void;
|
|
68
71
|
retrieve(modelClass: abstract new (...args: never[]) => Model, id: string): Model | undefined;
|
|
@@ -77,17 +80,15 @@ export interface SyncStoreContract {
|
|
|
77
80
|
data: Model[];
|
|
78
81
|
};
|
|
79
82
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* and the rest of the local-first lineage all expose one-row writes
|
|
86
|
-
* and rely on the implicit tick boundary.
|
|
83
|
+
* Saves one entity, creating it if new or updating it if it already exists.
|
|
84
|
+
* Calling `save` repeatedly within the same tick is efficient: the writes are
|
|
85
|
+
* coalesced and persisted, then sent to the server, as a single commit. There
|
|
86
|
+
* is deliberately no bulk method — issue one `save` per row and let the tick
|
|
87
|
+
* boundary batch them.
|
|
87
88
|
*
|
|
88
|
-
* `skipValidation`
|
|
89
|
-
*
|
|
90
|
-
*
|
|
89
|
+
* Pass `skipValidation` on trusted, high-volume paths — bulk import or
|
|
90
|
+
* hydration, where the data has already been validated — to skip the per-row
|
|
91
|
+
* schema check, which is a measurable cost at that volume.
|
|
91
92
|
*/
|
|
92
93
|
save(model: Model, options?: {
|
|
93
94
|
skipValidation?: boolean;
|
|
@@ -95,7 +96,8 @@ export interface SyncStoreContract {
|
|
|
95
96
|
delete(model: Model): Promise<void>;
|
|
96
97
|
archive(model: Model): Promise<void>;
|
|
97
98
|
unarchive(model: Model): Promise<void>;
|
|
98
|
-
/** The
|
|
99
|
+
/** The in-memory object pool: look up individual entities or collections by
|
|
100
|
+
* id or model name, create views, and resolve foreign-key relationships. */
|
|
99
101
|
pool: {
|
|
100
102
|
get(id: string): Model | undefined;
|
|
101
103
|
getByTypeName(typename: string, scope?: ModelScope): Model[];
|
|
@@ -106,10 +108,11 @@ export interface SyncStoreContract {
|
|
|
106
108
|
viewRegistry: ViewRegistry;
|
|
107
109
|
};
|
|
108
110
|
/**
|
|
109
|
-
* Reactive sync
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
111
|
+
* Reactive getters for the current sync state. In the built-in store these
|
|
112
|
+
* are backed by observable computeds, so reading them inside a reactive
|
|
113
|
+
* context — an observer component or a reaction — re-runs that context when
|
|
114
|
+
* the state changes. Code that prefers not to work with the reactivity system
|
|
115
|
+
* directly can read the same values through the `useSyncStatus()` hook.
|
|
113
116
|
*/
|
|
114
117
|
readonly isReady: boolean;
|
|
115
118
|
readonly isSyncing: boolean;
|
|
@@ -118,14 +121,13 @@ export interface SyncStoreContract {
|
|
|
118
121
|
readonly isError: boolean;
|
|
119
122
|
readonly hasUnsyncedChanges: boolean;
|
|
120
123
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* resolver the claim path uses, so
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* forwards to its `AreaOfInterestManager`.
|
|
124
|
+
* Manages the connection's area of interest — the dynamic set of data it
|
|
125
|
+
* subscribes to. Call `enterScope` and `leaveScope` to move that interest as
|
|
126
|
+
* the user navigates between documents, and `pinScope` and `unpinScope` to
|
|
127
|
+
* keep a scope subscribed while it stays important, such as while a claim is
|
|
128
|
+
* held. Every scope resolves through the same resolver the claim path uses, so
|
|
129
|
+
* read subscriptions and write claims always agree on which group they refer
|
|
130
|
+
* to. These are optional and do nothing until the connection is open.
|
|
129
131
|
*/
|
|
130
132
|
enterScope?(scope: ParticipantScope, opts?: {
|
|
131
133
|
hydrate?: boolean;
|
|
@@ -134,10 +136,10 @@ export interface SyncStoreContract {
|
|
|
134
136
|
pinScope?(scope: ParticipantScope): Promise<void>;
|
|
135
137
|
unpinScope?(scope: ParticipantScope): Promise<void>;
|
|
136
138
|
/**
|
|
137
|
-
*
|
|
138
|
-
* `state`, `progress`, `pendingChanges`, `isSessionError`,
|
|
139
|
-
*
|
|
140
|
-
*
|
|
139
|
+
* The full reactive {@link SyncStatus} record. The `useSyncStatus()` hook
|
|
140
|
+
* reads its fields — `state`, `progress`, `pendingChanges`, `isSessionError`,
|
|
141
|
+
* and `error` — to present the current sync state. It is part of the contract
|
|
142
|
+
* so hooks and test doubles can read or set it directly.
|
|
141
143
|
*/
|
|
142
144
|
readonly syncStatus: SyncStatus;
|
|
143
145
|
}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The framework-neutral store contract. {@link SyncStoreContract} is the minimal
|
|
3
|
+
* store interface the SDK's hooks and mutators are written against, and
|
|
4
|
+
* {@link BaseSyncedStore} is the concrete class that implements it. Framework
|
|
5
|
+
* integrations, such as the React bindings, re-export these types, so a hook can
|
|
6
|
+
* accept any store that satisfies the contract without depending on a particular
|
|
7
|
+
* UI framework.
|
|
3
8
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* that implements it. The contract used to live in `react/context.ts`, which
|
|
7
|
-
* meant the CORE store layer imported its own contract from the React
|
|
8
|
-
* adapter (a module that runtime-imports 'react') — an L2-core →
|
|
9
|
-
* react-integration inversion and a module cycle. It now lives here, in a
|
|
10
|
-
* dependency-free core leaf: `react/context.ts` re-exports these types so
|
|
11
|
-
* React consumers are unchanged, and the core layer never touches 'react'.
|
|
12
|
-
*
|
|
13
|
-
* Everything in this module is type-only — no runtime imports, no runtime
|
|
14
|
-
* exports beyond erased interfaces.
|
|
9
|
+
* This module is type-only: it has no runtime imports and contributes nothing to
|
|
10
|
+
* the runtime bundle beyond the erased interface declarations.
|
|
15
11
|
*/
|
|
16
12
|
export {};
|
package/dist/environment.d.ts
CHANGED
|
@@ -1,12 +1,40 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The two environments an Ablo project runs in: `production` for live data and
|
|
4
|
+
* `sandbox` for isolated test data. Every credential and every stored row
|
|
5
|
+
* belongs to exactly one of them.
|
|
6
|
+
*/
|
|
2
7
|
export declare const ENVIRONMENTS: readonly ["production", "sandbox"];
|
|
8
|
+
/**
|
|
9
|
+
* How an environment is spelled inside an API-key prefix: a `live` key acts on
|
|
10
|
+
* the production environment and a `test` key acts on the sandbox. Convert
|
|
11
|
+
* between this spelling and {@link Environment} with
|
|
12
|
+
* {@link environmentFromKeyPrefix} and {@link environmentToKeyPrefix}.
|
|
13
|
+
*/
|
|
3
14
|
export type KeyPrefixEnvironment = 'live' | 'test';
|
|
15
|
+
/** A Zod schema that validates a value as one of the {@link ENVIRONMENTS}. */
|
|
4
16
|
export declare const environmentSchema: z.ZodEnum<{
|
|
5
17
|
production: "production";
|
|
6
18
|
sandbox: "sandbox";
|
|
7
19
|
}>;
|
|
20
|
+
/** One of the {@link ENVIRONMENTS} — either `'production'` or `'sandbox'`. */
|
|
8
21
|
export type Environment = z.infer<typeof environmentSchema>;
|
|
22
|
+
/**
|
|
23
|
+
* Coerces an untrusted value into a valid {@link Environment}, returning
|
|
24
|
+
* `fallback` (which defaults to `'production'`) when the value is not a
|
|
25
|
+
* recognized environment. Use it when reading an environment from configuration
|
|
26
|
+
* or off the wire.
|
|
27
|
+
*/
|
|
9
28
|
export declare function normalizeEnvironment(value: unknown, fallback?: Environment): Environment;
|
|
29
|
+
/**
|
|
30
|
+
* Maps an API-key prefix spelling to its {@link Environment}: a `'test'` key
|
|
31
|
+
* operates on the sandbox, and anything else on production.
|
|
32
|
+
*/
|
|
10
33
|
export declare function environmentFromKeyPrefix(value: KeyPrefixEnvironment): Environment;
|
|
34
|
+
/**
|
|
35
|
+
* Maps an {@link Environment} to the spelling used in an API-key prefix: the
|
|
36
|
+
* sandbox is `'test'` and production is `'live'`.
|
|
37
|
+
*/
|
|
11
38
|
export declare function environmentToKeyPrefix(value: Environment): KeyPrefixEnvironment;
|
|
39
|
+
/** Returns true when the given environment is the sandbox. */
|
|
12
40
|
export declare function isSandboxEnvironment(value: Environment): boolean;
|