@abloatai/ablo 0.25.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/AGENTS.md +5 -3
- package/CHANGELOG.md +34 -0
- package/README.md +104 -88
- package/dist/BaseSyncedStore.d.ts +140 -266
- package/dist/BaseSyncedStore.js +338 -739
- package/dist/Database.d.ts +62 -77
- package/dist/Database.js +106 -127
- package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
- package/dist/{ObjectPool.js → InstanceCache.js} +91 -83
- package/dist/LazyReferenceCollection.d.ts +11 -15
- package/dist/LazyReferenceCollection.js +16 -15
- package/dist/Model.d.ts +37 -52
- package/dist/Model.js +52 -69
- package/dist/ModelRegistry.d.ts +46 -25
- package/dist/ModelRegistry.js +32 -30
- package/dist/NetworkMonitor.d.ts +5 -6
- package/dist/NetworkMonitor.js +6 -7
- package/dist/SyncClient.d.ts +119 -109
- package/dist/SyncClient.js +303 -224
- package/dist/SyncEngineContext.d.ts +1 -3
- package/dist/SyncEngineContext.js +1 -2
- 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 +39 -31
- package/dist/agent/Agent.js +35 -23
- 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} +30 -31
- package/dist/ai-sdk/index.d.ts +25 -22
- package/dist/ai-sdk/index.js +25 -22
- package/dist/ai-sdk/wrap.d.ts +7 -8
- package/dist/ai-sdk/wrap.js +2 -2
- package/dist/auth/credentialPolicy.d.ts +74 -71
- package/dist/auth/credentialPolicy.js +51 -56
- package/dist/auth/credentialSource.d.ts +7 -18
- package/dist/auth/credentialSource.js +10 -18
- package/dist/auth/index.d.ts +59 -58
- package/dist/auth/index.js +34 -40
- 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 +483 -369
- package/dist/client/Ablo.d.ts +107 -836
- package/dist/client/Ablo.js +174 -833
- package/dist/client/ApiClient.d.ts +44 -20
- package/dist/client/ApiClient.js +193 -44
- package/dist/client/auth.d.ts +51 -60
- package/dist/client/auth.js +137 -110
- package/dist/client/claimHeartbeatLoop.d.ts +50 -0
- package/dist/client/claimHeartbeatLoop.js +88 -0
- package/dist/client/consoleLogger.d.ts +35 -0
- package/dist/client/consoleLogger.js +44 -0
- package/dist/client/createInternalComponents.d.ts +14 -17
- package/dist/client/createInternalComponents.js +26 -31
- package/dist/client/createModelProxy.d.ts +130 -120
- package/dist/client/createModelProxy.js +158 -124
- package/dist/client/credentialEndpoint.d.ts +61 -0
- package/dist/client/credentialEndpoint.js +86 -0
- package/dist/client/functionalUpdate.d.ts +29 -27
- package/dist/client/functionalUpdate.js +21 -21
- package/dist/client/hostedEndpoints.d.ts +21 -0
- package/dist/client/hostedEndpoints.js +21 -0
- package/dist/client/httpClient.d.ts +58 -54
- package/dist/client/httpClient.js +29 -31
- package/dist/client/identity.d.ts +15 -20
- package/dist/client/identity.js +49 -59
- package/dist/client/modelRegistration.d.ts +10 -0
- package/dist/client/modelRegistration.js +301 -0
- package/dist/client/options.d.ts +373 -0
- package/dist/client/options.js +6 -0
- package/dist/client/registerDataSource.d.ts +9 -9
- package/dist/client/registerDataSource.js +15 -16
- package/dist/client/resourceTypes.d.ts +333 -0
- package/dist/client/resourceTypes.js +7 -0
- package/dist/client/schemaConfig.d.ts +44 -0
- package/dist/client/schemaConfig.js +176 -0
- package/dist/client/sessionMint.d.ts +17 -13
- package/dist/client/sessionMint.js +26 -31
- package/dist/client/validateAbloOptions.d.ts +12 -14
- package/dist/client/validateAbloOptions.js +9 -10
- package/dist/client/writeOptionsSchema.d.ts +18 -16
- package/dist/client/writeOptionsSchema.js +23 -20
- package/dist/client/wsMutationExecutor.d.ts +28 -0
- package/dist/client/wsMutationExecutor.js +71 -0
- package/dist/context.d.ts +6 -4
- package/dist/context.js +6 -7
- package/dist/coordination/index.d.ts +13 -4
- package/dist/coordination/index.js +29 -4
- package/dist/coordination/schema.d.ts +176 -128
- package/dist/coordination/schema.js +197 -133
- package/dist/coordination/trace.d.ts +9 -11
- package/dist/coordination/trace.js +13 -15
- package/dist/core/DatabaseManager.d.ts +5 -8
- package/dist/core/DatabaseManager.js +38 -40
- package/dist/core/QueryProcessor.d.ts +7 -9
- package/dist/core/QueryProcessor.js +27 -34
- package/dist/core/QueryView.d.ts +17 -5
- package/dist/core/QueryView.js +6 -7
- package/dist/core/StoreManager.d.ts +14 -16
- package/dist/core/StoreManager.js +26 -25
- package/dist/core/ViewRegistry.d.ts +5 -5
- package/dist/core/ViewRegistry.js +4 -4
- package/dist/core/index.d.ts +18 -13
- package/dist/core/index.js +32 -26
- package/dist/core/openIDBWithTimeout.d.ts +38 -36
- package/dist/core/openIDBWithTimeout.js +57 -54
- package/dist/core/queryUtils.d.ts +45 -0
- package/dist/core/queryUtils.js +69 -0
- package/dist/core/storeContract.d.ts +145 -0
- package/dist/core/storeContract.js +12 -0
- package/dist/environment.d.ts +28 -0
- package/dist/environment.js +21 -0
- package/dist/errorCodes.d.ts +118 -101
- package/dist/errorCodes.js +277 -260
- package/dist/errors.d.ts +170 -165
- package/dist/errors.js +161 -151
- package/dist/index.d.ts +30 -27
- package/dist/index.js +90 -82
- package/dist/interfaces/index.d.ts +108 -133
- package/dist/interfaces/index.js +5 -4
- package/dist/keys/index.d.ts +27 -29
- package/dist/keys/index.js +59 -49
- 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 +149 -155
- package/dist/mutators/defineMutators.d.ts +24 -37
- 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 +105 -101
- package/dist/policy/types.js +67 -66
- package/dist/query/client.d.ts +32 -16
- package/dist/query/client.js +103 -72
- package/dist/query/types.d.ts +37 -60
- package/dist/query/types.js +13 -33
- package/dist/react/AbloProvider.d.ts +7 -11
- package/dist/react/AbloProvider.js +24 -17
- package/dist/react/context.d.ts +27 -146
- 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 +17 -15
- 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 +11 -12
- package/dist/react/useMutationFailureListener.d.ts +8 -8
- package/dist/react/useMutationFailureListener.js +9 -9
- package/dist/react/useMutators.d.ts +11 -11
- package/dist/react/useMutators.js +10 -4
- package/dist/react/useReactive.js +2 -3
- package/dist/react/useSyncStatus.d.ts +4 -6
- package/dist/react/useUndoScope.d.ts +7 -9
- package/dist/react/useUndoScope.js +3 -3
- 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 +35 -0
- package/dist/schema/ddlLock.js +46 -0
- 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 +36 -49
- package/dist/schema/generate.d.ts +12 -12
- package/dist/schema/generate.js +12 -12
- package/dist/schema/index.d.ts +5 -4
- package/dist/schema/index.js +29 -21
- package/dist/schema/model.d.ts +121 -146
- package/dist/schema/model.js +24 -35
- package/dist/schema/openapi.d.ts +10 -9
- package/dist/schema/openapi.js +7 -1
- package/dist/schema/queries.d.ts +30 -32
- package/dist/schema/queries.js +24 -25
- package/dist/schema/relation.d.ts +89 -99
- package/dist/schema/relation.js +13 -13
- package/dist/schema/residency.d.ts +38 -0
- package/dist/schema/residency.js +30 -0
- package/dist/schema/roles.d.ts +45 -27
- package/dist/schema/roles.js +52 -21
- package/dist/schema/schema.d.ts +36 -45
- package/dist/schema/schema.js +42 -39
- package/dist/schema/select.d.ts +13 -13
- package/dist/schema/select.js +13 -13
- package/dist/schema/serialize.d.ts +36 -39
- 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} +27 -50
- 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 +31 -26
- package/dist/source/adapter.js +10 -10
- package/dist/source/adapters/drizzle.d.ts +28 -23
- package/dist/source/adapters/drizzle.js +34 -28
- package/dist/source/adapters/kysely.d.ts +27 -25
- package/dist/source/adapters/kysely.js +28 -26
- package/dist/source/adapters/memory.d.ts +8 -7
- package/dist/source/adapters/memory.js +10 -9
- package/dist/source/adapters/prisma.d.ts +13 -12
- package/dist/source/adapters/prisma.js +27 -29
- package/dist/source/conformance.d.ts +18 -11
- package/dist/source/conformance.js +27 -19
- package/dist/source/connector.d.ts +31 -32
- package/dist/source/connector.js +30 -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 +94 -0
- package/dist/source/factory.js +268 -0
- package/dist/source/index.d.ts +10 -462
- package/dist/source/index.js +17 -421
- package/dist/source/migrations.d.ts +9 -9
- package/dist/source/migrations.js +9 -9
- package/dist/source/next.d.ts +10 -11
- package/dist/source/next.js +7 -8
- package/dist/source/pushQueue.d.ts +70 -48
- package/dist/source/pushQueue.js +36 -29
- package/dist/source/signing.d.ts +88 -0
- package/dist/source/signing.js +159 -0
- package/dist/source/types.d.ts +351 -0
- package/dist/source/types.js +43 -0
- package/dist/stores/ObjectStore.d.ts +11 -12
- package/dist/stores/ObjectStore.js +34 -35
- package/dist/stores/ObjectStoreContract.d.ts +12 -15
- package/dist/stores/SyncActionStore.d.ts +8 -12
- package/dist/stores/SyncActionStore.js +77 -46
- package/dist/surface.d.ts +28 -21
- package/dist/surface.js +28 -20
- package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +37 -45
- package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +101 -80
- package/dist/sync/ConnectionManager.d.ts +47 -50
- package/dist/sync/ConnectionManager.js +74 -70
- package/dist/sync/NetworkProbe.d.ts +27 -31
- package/dist/sync/NetworkProbe.js +67 -72
- package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +49 -36
- package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +79 -54
- package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +45 -59
- package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +44 -52
- package/dist/sync/SyncWebSocket.d.ts +175 -250
- package/dist/sync/SyncWebSocket.js +431 -769
- package/dist/sync/awaitClaimGrant.d.ts +18 -18
- package/dist/sync/awaitClaimGrant.js +38 -30
- package/dist/sync/bootstrapApply.d.ts +70 -0
- package/dist/sync/bootstrapApply.js +73 -0
- package/dist/sync/commitFrames.d.ts +44 -0
- package/dist/sync/commitFrames.js +94 -0
- package/dist/sync/createClaimStream.d.ts +23 -22
- package/dist/sync/createClaimStream.js +108 -25
- package/dist/sync/createPresenceStream.d.ts +19 -18
- package/dist/sync/createPresenceStream.js +25 -26
- package/dist/sync/createSnapshot.d.ts +13 -17
- package/dist/sync/createSnapshot.js +20 -26
- package/dist/sync/credentialLifecycle.d.ts +175 -0
- package/dist/sync/credentialLifecycle.js +322 -0
- package/dist/sync/deltaPipeline.d.ts +113 -0
- package/dist/sync/deltaPipeline.js +261 -0
- package/dist/sync/groupChange.d.ts +113 -0
- package/dist/sync/groupChange.js +242 -0
- package/dist/sync/heartbeat.d.ts +63 -0
- package/dist/sync/heartbeat.js +91 -0
- package/dist/sync/participants.d.ts +27 -27
- package/dist/sync/schemas.d.ts +3 -2
- package/dist/sync/schemas.js +14 -10
- package/dist/sync/syncCursor.d.ts +40 -0
- package/dist/sync/syncCursor.js +55 -0
- package/dist/sync/syncPlan.d.ts +54 -0
- package/dist/sync/syncPlan.js +50 -0
- package/dist/sync/syncPosition.d.ts +54 -49
- package/dist/sync/syncPosition.js +57 -52
- package/dist/sync/wsFrameHandlers.d.ts +116 -0
- package/dist/sync/wsFrameHandlers.js +374 -0
- package/dist/testing/fixtures/bootstrap.d.ts +21 -17
- package/dist/testing/fixtures/bootstrap.js +12 -6
- package/dist/testing/fixtures/deltas.d.ts +31 -34
- package/dist/testing/fixtures/deltas.js +30 -33
- package/dist/testing/fixtures/models.d.ts +11 -10
- package/dist/testing/fixtures/models.js +12 -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 -18
- package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +14 -11
- package/dist/testing/helpers/wait.d.ts +13 -8
- package/dist/testing/helpers/wait.js +13 -8
- package/dist/testing/index.d.ts +4 -4
- package/dist/testing/index.js +3 -3
- 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 +21 -34
- package/dist/testing/mocks/MockSyncContext.js +16 -45
- package/dist/testing/mocks/MockSyncStore.d.ts +14 -14
- package/dist/testing/mocks/MockSyncStore.js +11 -11
- package/dist/testing/mocks/MockWebSocket.d.ts +28 -24
- package/dist/testing/mocks/MockWebSocket.js +22 -21
- package/dist/transactions/TransactionQueue.d.ts +190 -221
- package/dist/transactions/TransactionQueue.js +424 -822
- package/dist/transactions/TransactionStore.d.ts +20 -0
- package/dist/transactions/TransactionStore.js +53 -0
- package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
- package/dist/transactions/UnconfirmedWrites.js +104 -0
- package/dist/transactions/coalesceRules.d.ts +58 -0
- package/dist/transactions/coalesceRules.js +140 -0
- package/dist/transactions/commitPayload.d.ts +130 -0
- package/dist/transactions/commitPayload.js +143 -0
- package/dist/transactions/deltaConfirmation.d.ts +58 -0
- package/dist/transactions/deltaConfirmation.js +215 -0
- package/dist/transactions/optimisticApply.d.ts +49 -0
- package/dist/transactions/optimisticApply.js +65 -0
- package/dist/transactions/replayValidation.d.ts +99 -0
- package/dist/transactions/replayValidation.js +111 -0
- package/dist/types/global.d.ts +46 -41
- package/dist/types/global.js +20 -19
- package/dist/types/index.d.ts +74 -80
- package/dist/types/index.js +22 -27
- package/dist/types/modelData.d.ts +10 -0
- package/dist/types/modelData.js +9 -0
- package/dist/types/participant.d.ts +20 -0
- package/dist/types/participant.js +10 -0
- package/dist/types/streams.d.ts +216 -209
- 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} +44 -100
- 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 +35 -27
- package/dist/wire/errorEnvelope.js +38 -32
- package/dist/wire/frames.d.ts +150 -67
- package/dist/wire/frames.js +48 -1
- package/dist/wire/index.d.ts +18 -13
- package/dist/wire/index.js +36 -13
- package/dist/wire/listEnvelope.d.ts +16 -23
- package/dist/wire/listEnvelope.js +7 -6
- package/dist/wire/protocol.d.ts +38 -0
- package/dist/wire/protocol.js +38 -0
- package/dist/wire/protocolVersion.d.ts +60 -0
- package/dist/wire/protocolVersion.js +67 -0
- package/docs/api-keys.md +4 -3
- package/docs/coordination.md +59 -0
- package/docs/examples/existing-python-backend.md +3 -3
- package/docs/identity.md +4 -4
- package/docs/integration-guide.md +1 -1
- package/docs/react.md +1 -1
- package/docs/sessions.md +5 -7
- package/package.json +24 -21
- package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
- package/dist/ai-sdk/coordination-context.d.ts +0 -52
- package/dist/client/index.d.ts +0 -36
- package/dist/client/index.js +0 -33
- package/dist/config/index.d.ts +0 -10
- package/dist/config/index.js +0 -12
- package/dist/core/query-utils.d.ts +0 -34
- package/dist/core/query-utils.js +0 -59
- package/dist/interfaces/headless.d.ts +0 -95
- package/dist/interfaces/headless.js +0 -41
- package/dist/query/index.d.ts +0 -6
- package/dist/query/index.js +0 -5
- package/dist/realtime/index.d.ts +0 -10
- package/dist/realtime/index.js +0 -9
- package/dist/schema/plane.d.ts +0 -23
- package/dist/schema/plane.js +0 -19
- package/dist/schema/sync-delta-row.js +0 -103
- package/dist/schema/sync-delta-wire.js +0 -102
- package/dist/server/next.d.ts +0 -51
- package/dist/server/next.js +0 -47
- 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 -1
- package/dist/server/storage-mode.js +0 -18
- package/dist/source/connector-protocol.d.ts +0 -159
- package/dist/source/connector-protocol.js +0 -161
- package/dist/sync/OfflineFlush.d.ts +0 -9
- package/dist/sync/OfflineFlush.js +0 -22
- package/dist/sync/OfflineTransactionStore.d.ts +0 -37
- package/dist/sync/OfflineTransactionStore.js +0 -263
- package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
- package/dist/transactions/OptimisticEchoTracker.js +0 -104
- package/dist/transactions/index.d.ts +0 -16
- package/dist/transactions/index.js +0 -7
- package/dist/transactions/mutation-error-handler.d.ts +0 -5
- package/dist/transactions/mutation-error-handler.js +0 -39
- package/dist/utils/mobx-setup.d.ts +0 -42
package/dist/core/index.d.ts
CHANGED
|
@@ -1,28 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The framework-extension entry point of this package. Import from here only
|
|
3
|
+
* when you are building on top of the sync engine — wiring your own store and
|
|
4
|
+
* provider stack, writing a sync adapter, or driving a test harness. Everyday
|
|
5
|
+
* application code should use the `Ablo({ schema })` client from the package
|
|
6
|
+
* root instead; the primitives exported here are lower-level building blocks.
|
|
3
7
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* here — the consumer surface is `Ablo({ schema })` on the root.
|
|
8
|
-
*
|
|
9
|
-
* TRIMMED to what framework-level consumers actually import (verified by
|
|
10
|
-
* a monorepo-wide import scan). Everything else the engine defines stays
|
|
11
|
-
* module-private: if a new framework concern genuinely needs another
|
|
12
|
-
* primitive, add the export deliberately — don't re-widen the barrel.
|
|
8
|
+
* The surface is deliberately narrow: it exposes only the types and classes an
|
|
9
|
+
* extension actually needs. Anything the engine does not export here is
|
|
10
|
+
* internal and may change.
|
|
13
11
|
*/
|
|
14
12
|
export { BaseSyncedStore, type ModelConstructor, type ConcreteModelConstructor, } from '../BaseSyncedStore.js';
|
|
15
13
|
export { SyncClient } from '../SyncClient.js';
|
|
16
14
|
export { Database } from '../Database.js';
|
|
17
|
-
export {
|
|
15
|
+
export { InstanceCache, ModelScope } from '../InstanceCache.js';
|
|
16
|
+
/** @deprecated `ObjectPool` was renamed to {@link InstanceCache} — the class is an
|
|
17
|
+
* identity-map cache of live model instances, not a reuse pool. This alias keeps existing
|
|
18
|
+
* imports working and will be removed in a future major version. */
|
|
19
|
+
export { InstanceCache as ObjectPool } from '../InstanceCache.js';
|
|
18
20
|
export { Model } from '../Model.js';
|
|
19
21
|
export { LazyReferenceCollection, type LazyCollectionOptions, } from '../LazyReferenceCollection.js';
|
|
20
22
|
export { ModelRegistry, getActiveRegistry, } from '../ModelRegistry.js';
|
|
21
23
|
export { postQuery, type PostQueryOptions } from '../query/client.js';
|
|
22
24
|
export { computeFKDepthPriority, type InternalAbloOptions } from '../client/Ablo.js';
|
|
23
|
-
export type { SyncLogger, SyncObservabilityProvider, MutationExecutor,
|
|
25
|
+
export type { SyncLogger, SyncObservabilityProvider, MutationExecutor, SessionErrorDetector, OnlineStatusProvider, CommitResult, MutationOperation, } from '../interfaces/index.js';
|
|
24
26
|
export { SyncWebSocket, type SyncDelta, type SyncWebSocketOptions, } from '../sync/SyncWebSocket.js';
|
|
25
|
-
export {
|
|
27
|
+
export { BootstrapFetcher } from '../sync/BootstrapFetcher.js';
|
|
28
|
+
/** @deprecated `BootstrapHelper` was renamed to {@link BootstrapFetcher}. This alias keeps
|
|
29
|
+
* existing imports working and will be removed in a future major version. */
|
|
30
|
+
export { BootstrapFetcher as BootstrapHelper } from '../sync/BootstrapFetcher.js';
|
|
26
31
|
export { createClaimStream, type AttachableClaimStream, type ClaimStreamConfig, } from '../sync/createClaimStream.js';
|
|
27
32
|
export { awaitClaimGrant, type GrantTransport, } from '../sync/awaitClaimGrant.js';
|
|
28
33
|
export { LoadStrategy } from '../types/index.js';
|
package/dist/core/index.js
CHANGED
|
@@ -1,42 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The framework-extension entry point of this package. Import from here only
|
|
3
|
+
* when you are building on top of the sync engine — wiring your own store and
|
|
4
|
+
* provider stack, writing a sync adapter, or driving a test harness. Everyday
|
|
5
|
+
* application code should use the `Ablo({ schema })` client from the package
|
|
6
|
+
* root instead; the primitives exported here are lower-level building blocks.
|
|
3
7
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* here — the consumer surface is `Ablo({ schema })` on the root.
|
|
8
|
-
*
|
|
9
|
-
* TRIMMED to what framework-level consumers actually import (verified by
|
|
10
|
-
* a monorepo-wide import scan). Everything else the engine defines stays
|
|
11
|
-
* module-private: if a new framework concern genuinely needs another
|
|
12
|
-
* primitive, add the export deliberately — don't re-widen the barrel.
|
|
8
|
+
* The surface is deliberately narrow: it exposes only the types and classes an
|
|
9
|
+
* extension actually needs. Anything the engine does not export here is
|
|
10
|
+
* internal and may change.
|
|
13
11
|
*/
|
|
14
|
-
//
|
|
12
|
+
// The base store class, plus the constructor shapes that subclasses reference.
|
|
15
13
|
export { BaseSyncedStore, } from '../BaseSyncedStore.js';
|
|
16
14
|
// Core infrastructure classes
|
|
17
15
|
export { SyncClient } from '../SyncClient.js';
|
|
18
16
|
export { Database } from '../Database.js';
|
|
19
|
-
export {
|
|
17
|
+
export { InstanceCache, ModelScope } from '../InstanceCache.js';
|
|
18
|
+
/** @deprecated `ObjectPool` was renamed to {@link InstanceCache} — the class is an
|
|
19
|
+
* identity-map cache of live model instances, not a reuse pool. This alias keeps existing
|
|
20
|
+
* imports working and will be removed in a future major version. */
|
|
21
|
+
export { InstanceCache as ObjectPool } from '../InstanceCache.js';
|
|
20
22
|
export { Model } from '../Model.js';
|
|
21
23
|
export { LazyReferenceCollection, } from '../LazyReferenceCollection.js';
|
|
22
24
|
export { ModelRegistry, getActiveRegistry, } from '../ModelRegistry.js';
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
+
// A lower-level network read primitive. Prefer `ablo.<model>.list(...)` for
|
|
26
|
+
// ordinary reads; reach for this only when writing a custom on-demand loader.
|
|
25
27
|
export { postQuery } from '../query/client.js';
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
+
// Computes a dependency-safe ordering for a set of models by walking their
|
|
29
|
+
// foreign-key relationships, so writes commit parents before children. Used by
|
|
30
|
+
// schema-aware test fixtures and scaffolding tools.
|
|
28
31
|
export { computeFKDepthPriority } from '../client/Ablo.js';
|
|
29
|
-
//
|
|
30
|
-
// multi-
|
|
32
|
+
// The sync layer: the WebSocket wrapper and the delta shape it carries. Needed
|
|
33
|
+
// when writing a sync adapter or a multi-participant test harness.
|
|
31
34
|
export { SyncWebSocket, } from '../sync/SyncWebSocket.js';
|
|
32
|
-
export {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
//
|
|
37
|
-
//
|
|
35
|
+
export { BootstrapFetcher } from '../sync/BootstrapFetcher.js';
|
|
36
|
+
/** @deprecated `BootstrapHelper` was renamed to {@link BootstrapFetcher}. This alias keeps
|
|
37
|
+
* existing imports working and will be removed in a future major version. */
|
|
38
|
+
export { BootstrapFetcher as BootstrapHelper } from '../sync/BootstrapFetcher.js';
|
|
39
|
+
// The lower-level claim-coordination primitives behind the `ablo.<model>.claim`
|
|
40
|
+
// API. `createClaimStream` builds the announce-and-await machinery on top of a
|
|
41
|
+
// `SyncWebSocket`; `awaitClaimGrant` coordinates fair, first-in-first-out
|
|
42
|
+
// grants. These are for extension code and test harnesses; ordinary
|
|
43
|
+
// application code should use `ablo.<model>.claim`.
|
|
38
44
|
export { createClaimStream, } from '../sync/createClaimStream.js';
|
|
39
45
|
export { awaitClaimGrant, } from '../sync/awaitClaimGrant.js';
|
|
40
|
-
//
|
|
41
|
-
//
|
|
46
|
+
// An enum naming the strategies for loading a model's data. Referenced when
|
|
47
|
+
// registering models in extension code.
|
|
42
48
|
export { LoadStrategy } from '../types/index.js';
|
|
@@ -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();
|
|
@@ -95,41 +94,45 @@ export function openIDBWithTimeout(name, version, options = {}) {
|
|
|
95
94
|
// A consumer reaction must never break the close.
|
|
96
95
|
}
|
|
97
96
|
};
|
|
98
|
-
settle(() => resolve(db));
|
|
97
|
+
settle(() => { resolve(db); });
|
|
99
98
|
};
|
|
100
|
-
request.onerror = () => settle(() => reject(request.error));
|
|
99
|
+
request.onerror = () => { settle(() => { reject(request.error); }); };
|
|
101
100
|
// The critical handler: another tab is blocking us. Native API leaves
|
|
102
101
|
// the request pending indefinitely; we fail fast with a clear error so
|
|
103
102
|
// the UI can tell the user to close other tabs.
|
|
104
103
|
request.onblocked = () => {
|
|
105
|
-
settle(() =>
|
|
106
|
-
`
|
|
104
|
+
settle(() => {
|
|
105
|
+
reject(new IDBOpenTimeoutError(name, 'blocked', `IndexedDB \"${name}\" open blocked — another tab is holding an ` +
|
|
106
|
+
`older version. Close other Ablo tabs and reload.`));
|
|
107
|
+
});
|
|
107
108
|
};
|
|
108
109
|
// Catch-all timeout: even without `onblocked`, some browsers in some
|
|
109
110
|
// storage states hang without firing any event. Bounded wait →
|
|
110
111
|
// deterministic error.
|
|
111
112
|
const timer = setTimeout(() => {
|
|
112
|
-
settle(() =>
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
settle(() => {
|
|
114
|
+
reject(new IDBOpenTimeoutError(name, 'timeout', `IndexedDB \"${name}\" open did not resolve within ${timeoutMs}ms. ` +
|
|
115
|
+
`Storage may be in a bad state — clearing site data and reloading ` +
|
|
116
|
+
`usually fixes this.`));
|
|
117
|
+
});
|
|
115
118
|
}, timeoutMs);
|
|
116
119
|
});
|
|
117
120
|
}
|
|
118
121
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
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.
|
|
124
127
|
*
|
|
125
|
-
* Like
|
|
126
|
-
*
|
|
127
|
-
* store it fires
|
|
128
|
-
*
|
|
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.
|
|
129
132
|
*
|
|
130
|
-
* Resolves `true` on a clean delete
|
|
131
|
-
*
|
|
132
|
-
* 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.
|
|
133
136
|
*/
|
|
134
137
|
export function deleteIDBWithTimeout(name, timeoutMs = 5_000) {
|
|
135
138
|
return new Promise((resolve) => {
|
|
@@ -142,9 +145,9 @@ export function deleteIDBWithTimeout(name, timeoutMs = 5_000) {
|
|
|
142
145
|
resolve(value);
|
|
143
146
|
};
|
|
144
147
|
const request = indexedDB.deleteDatabase(name);
|
|
145
|
-
request.onsuccess = () => settle(true);
|
|
146
|
-
request.onerror = () => settle(false);
|
|
147
|
-
request.onblocked = () => settle(false);
|
|
148
|
-
const timer = setTimeout(() => settle(false), timeoutMs);
|
|
148
|
+
request.onsuccess = () => { settle(true); };
|
|
149
|
+
request.onerror = () => { settle(false); };
|
|
150
|
+
request.onblocked = () => { settle(false); };
|
|
151
|
+
const timer = setTimeout(() => { settle(false); }, timeoutMs);
|
|
149
152
|
});
|
|
150
153
|
}
|
|
@@ -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
|
+
}
|