@abloatai/ablo 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +101 -85
- package/dist/BaseSyncedStore.d.ts +85 -88
- package/dist/BaseSyncedStore.js +131 -147
- package/dist/Database.d.ts +54 -68
- package/dist/Database.js +97 -113
- package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
- package/dist/{ObjectPool.js → InstanceCache.js} +85 -83
- package/dist/LazyReferenceCollection.d.ts +11 -15
- package/dist/LazyReferenceCollection.js +12 -16
- package/dist/Model.d.ts +37 -52
- package/dist/Model.js +46 -61
- package/dist/ModelRegistry.d.ts +21 -19
- package/dist/ModelRegistry.js +23 -27
- package/dist/NetworkMonitor.d.ts +5 -6
- package/dist/NetworkMonitor.js +5 -6
- package/dist/SyncClient.d.ts +112 -112
- package/dist/SyncClient.js +165 -172
- package/dist/adapters/alwaysOnline.d.ts +6 -8
- package/dist/adapters/alwaysOnline.js +6 -8
- package/dist/adapters/inMemoryStorage.d.ts +9 -9
- package/dist/adapters/inMemoryStorage.js +9 -9
- package/dist/agent/Agent.d.ts +27 -32
- package/dist/agent/Agent.js +18 -19
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +5 -5
- package/dist/agent/session.d.ts +47 -44
- package/dist/agent/session.js +37 -48
- package/dist/agent/types.d.ts +26 -31
- package/dist/agent/types.js +6 -7
- package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
- package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
- package/dist/ai-sdk/coordinationContext.d.ts +46 -0
- package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +26 -33
- package/dist/ai-sdk/index.d.ts +25 -22
- package/dist/ai-sdk/index.js +25 -22
- package/dist/ai-sdk/wrap.d.ts +6 -7
- package/dist/ai-sdk/wrap.js +1 -1
- package/dist/auth/credentialPolicy.d.ts +69 -74
- package/dist/auth/credentialPolicy.js +51 -56
- package/dist/auth/credentialSource.d.ts +6 -5
- package/dist/auth/credentialSource.js +9 -10
- package/dist/auth/index.d.ts +59 -58
- package/dist/auth/index.js +31 -37
- package/dist/auth/schemas.d.ts +5 -4
- package/dist/auth/schemas.js +5 -4
- package/dist/batching/index.d.ts +19 -21
- package/dist/batching/index.js +14 -17
- package/dist/cli.cjs +167 -119
- package/dist/client/Ablo.d.ts +73 -73
- package/dist/client/Ablo.js +125 -160
- package/dist/client/ApiClient.d.ts +30 -19
- package/dist/client/ApiClient.js +133 -38
- package/dist/client/auth.d.ts +47 -47
- package/dist/client/auth.js +108 -117
- package/dist/client/claimHeartbeatLoop.d.ts +50 -0
- package/dist/client/claimHeartbeatLoop.js +88 -0
- package/dist/client/consoleLogger.d.ts +5 -6
- package/dist/client/consoleLogger.js +5 -6
- package/dist/client/createInternalComponents.d.ts +14 -17
- package/dist/client/createInternalComponents.js +25 -30
- package/dist/client/createModelProxy.d.ts +130 -120
- package/dist/client/createModelProxy.js +152 -122
- package/dist/client/credentialEndpoint.d.ts +40 -42
- package/dist/client/credentialEndpoint.js +35 -36
- package/dist/client/functionalUpdate.d.ts +29 -27
- package/dist/client/functionalUpdate.js +21 -21
- package/dist/client/hostedEndpoints.d.ts +9 -12
- package/dist/client/hostedEndpoints.js +9 -12
- package/dist/client/httpClient.d.ts +57 -53
- package/dist/client/httpClient.js +29 -31
- package/dist/client/identity.d.ts +15 -20
- package/dist/client/identity.js +47 -58
- package/dist/client/modelRegistration.d.ts +5 -9
- package/dist/client/modelRegistration.js +67 -87
- package/dist/client/options.d.ts +134 -157
- package/dist/client/options.js +3 -7
- package/dist/client/registerDataSource.d.ts +9 -9
- package/dist/client/registerDataSource.js +15 -16
- package/dist/client/resourceTypes.d.ts +64 -75
- package/dist/client/resourceTypes.js +4 -10
- package/dist/client/schemaConfig.d.ts +31 -43
- package/dist/client/schemaConfig.js +38 -50
- package/dist/client/sessionMint.d.ts +16 -12
- package/dist/client/sessionMint.js +26 -31
- package/dist/client/validateAbloOptions.d.ts +12 -14
- package/dist/client/validateAbloOptions.js +8 -9
- package/dist/client/writeOptionsSchema.d.ts +18 -16
- package/dist/client/writeOptionsSchema.js +23 -20
- package/dist/client/wsMutationExecutor.d.ts +15 -20
- package/dist/client/wsMutationExecutor.js +17 -23
- package/dist/context.d.ts +6 -4
- package/dist/context.js +6 -4
- package/dist/coordination/index.d.ts +10 -8
- package/dist/coordination/index.js +14 -12
- package/dist/coordination/schema.d.ts +176 -128
- package/dist/coordination/schema.js +197 -133
- package/dist/coordination/trace.d.ts +9 -10
- package/dist/coordination/trace.js +13 -14
- package/dist/core/DatabaseManager.d.ts +5 -7
- package/dist/core/DatabaseManager.js +15 -19
- package/dist/core/QueryProcessor.d.ts +7 -9
- package/dist/core/QueryProcessor.js +22 -28
- package/dist/core/QueryView.d.ts +8 -8
- package/dist/core/QueryView.js +2 -2
- package/dist/core/StoreManager.d.ts +12 -14
- package/dist/core/StoreManager.js +21 -24
- package/dist/core/ViewRegistry.d.ts +5 -5
- package/dist/core/ViewRegistry.js +4 -4
- package/dist/core/index.d.ts +17 -12
- package/dist/core/index.js +32 -26
- package/dist/core/openIDBWithTimeout.d.ts +38 -36
- package/dist/core/openIDBWithTimeout.js +42 -43
- package/dist/core/queryUtils.d.ts +45 -0
- package/dist/core/queryUtils.js +69 -0
- package/dist/core/storeContract.d.ts +63 -61
- package/dist/core/storeContract.js +8 -12
- package/dist/environment.d.ts +28 -0
- package/dist/environment.js +21 -0
- package/dist/errorCodes.d.ts +107 -99
- package/dist/errorCodes.js +131 -132
- package/dist/errors.d.ts +160 -166
- package/dist/errors.js +155 -158
- package/dist/index.d.ts +30 -27
- package/dist/index.js +89 -86
- package/dist/interfaces/index.d.ts +102 -113
- package/dist/interfaces/index.js +5 -4
- package/dist/keys/index.d.ts +27 -29
- package/dist/keys/index.js +41 -40
- package/dist/mutators/RecordingTransaction.d.ts +16 -16
- package/dist/mutators/RecordingTransaction.js +31 -37
- package/dist/mutators/Transaction.d.ts +18 -26
- package/dist/mutators/Transaction.js +14 -20
- package/dist/mutators/UndoManager.d.ts +122 -131
- package/dist/mutators/UndoManager.js +145 -156
- package/dist/mutators/defineMutators.d.ts +23 -34
- package/dist/mutators/defineMutators.js +14 -20
- package/dist/mutators/inverseOp.d.ts +12 -15
- package/dist/mutators/inverseOp.js +12 -15
- package/dist/mutators/mutateActions.d.ts +10 -9
- package/dist/mutators/mutateActions.js +1 -1
- package/dist/mutators/readerActions.d.ts +9 -8
- package/dist/mutators/readerActions.js +2 -2
- package/dist/mutators/undoApply.d.ts +31 -27
- package/dist/mutators/undoApply.js +26 -24
- package/dist/policy/index.d.ts +5 -3
- package/dist/policy/index.js +5 -3
- package/dist/policy/types.d.ts +104 -100
- package/dist/policy/types.js +67 -66
- package/dist/query/client.d.ts +28 -23
- package/dist/query/client.js +45 -43
- package/dist/query/types.d.ts +37 -60
- package/dist/query/types.js +13 -33
- package/dist/react/AbloProvider.d.ts +1 -1
- package/dist/react/AbloProvider.js +2 -2
- package/dist/react/context.d.ts +25 -28
- package/dist/react/context.js +9 -10
- package/dist/react/index.d.ts +41 -42
- package/dist/react/index.js +37 -38
- package/dist/react/internalContext.d.ts +17 -19
- package/dist/react/useAblo.d.ts +23 -22
- package/dist/react/useAblo.js +16 -14
- package/dist/react/useCurrentUserId.d.ts +8 -7
- package/dist/react/useCurrentUserId.js +8 -7
- package/dist/react/useErrorListener.d.ts +7 -7
- package/dist/react/useErrorListener.js +10 -11
- package/dist/react/useMutationFailureListener.d.ts +8 -8
- package/dist/react/useMutationFailureListener.js +8 -8
- package/dist/react/useMutators.d.ts +11 -11
- package/dist/react/useMutators.js +3 -3
- package/dist/react/useReactive.js +2 -2
- package/dist/react/useSyncStatus.d.ts +4 -6
- package/dist/react/useUndoScope.d.ts +7 -9
- package/dist/react/useUndoScope.js +1 -1
- package/dist/schema/coordination.d.ts +21 -25
- package/dist/schema/coordination.js +21 -25
- package/dist/schema/ddl.d.ts +43 -39
- package/dist/schema/ddl.js +75 -68
- package/dist/schema/ddlLock.d.ts +20 -24
- package/dist/schema/ddlLock.js +18 -23
- package/dist/schema/diff.d.ts +99 -61
- package/dist/schema/diff.js +43 -34
- package/dist/schema/field.d.ts +37 -42
- package/dist/schema/field.js +35 -48
- package/dist/schema/generate.d.ts +12 -12
- package/dist/schema/generate.js +12 -12
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.js +21 -23
- package/dist/schema/model.d.ts +118 -143
- package/dist/schema/model.js +22 -33
- package/dist/schema/openapi.d.ts +10 -9
- package/dist/schema/openapi.js +5 -3
- package/dist/schema/queries.d.ts +29 -31
- package/dist/schema/queries.js +23 -25
- package/dist/schema/relation.d.ts +89 -99
- package/dist/schema/relation.js +13 -13
- package/dist/schema/residency.d.ts +16 -13
- package/dist/schema/residency.js +16 -13
- package/dist/schema/roles.d.ts +36 -43
- package/dist/schema/roles.js +31 -37
- package/dist/schema/schema.d.ts +33 -42
- package/dist/schema/schema.js +31 -32
- package/dist/schema/select.d.ts +13 -13
- package/dist/schema/select.js +13 -13
- package/dist/schema/serialize.d.ts +28 -31
- package/dist/schema/serialize.js +27 -31
- package/dist/schema/sugar.d.ts +17 -32
- package/dist/schema/sugar.js +14 -29
- package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +26 -49
- package/dist/schema/syncDeltaRow.js +89 -0
- package/dist/schema/tenancy.d.ts +44 -46
- package/dist/schema/tenancy.js +46 -48
- package/dist/server/adapter.d.ts +58 -58
- package/dist/server/adapter.js +13 -14
- package/dist/server/commit.d.ts +60 -64
- package/dist/server/index.d.ts +9 -10
- package/dist/server/index.js +1 -1
- package/dist/server/readConfig.d.ts +70 -0
- package/dist/server/readConfig.js +8 -0
- package/dist/server/storageMode.d.ts +23 -0
- package/dist/server/storageMode.js +17 -0
- package/dist/source/adapter.d.ts +30 -25
- package/dist/source/adapter.js +10 -10
- package/dist/source/adapters/drizzle.d.ts +28 -23
- package/dist/source/adapters/drizzle.js +30 -25
- package/dist/source/adapters/kysely.d.ts +27 -25
- package/dist/source/adapters/kysely.js +24 -23
- package/dist/source/adapters/memory.d.ts +8 -7
- package/dist/source/adapters/memory.js +9 -8
- package/dist/source/adapters/prisma.d.ts +13 -12
- package/dist/source/adapters/prisma.js +22 -25
- package/dist/source/conformance.d.ts +18 -11
- package/dist/source/conformance.js +17 -11
- package/dist/source/connector.d.ts +31 -32
- package/dist/source/connector.js +28 -28
- package/dist/source/connectorProtocol.d.ts +160 -0
- package/dist/source/connectorProtocol.js +162 -0
- package/dist/source/contract.d.ts +26 -27
- package/dist/source/contract.js +28 -29
- package/dist/source/factory.d.ts +46 -58
- package/dist/source/factory.js +22 -27
- package/dist/source/index.d.ts +7 -9
- package/dist/source/index.js +12 -14
- package/dist/source/migrations.d.ts +9 -9
- package/dist/source/migrations.js +9 -9
- package/dist/source/next.d.ts +9 -10
- package/dist/source/next.js +6 -7
- package/dist/source/pushQueue.d.ts +69 -47
- package/dist/source/pushQueue.js +32 -28
- package/dist/source/signing.d.ts +46 -17
- package/dist/source/signing.js +28 -11
- package/dist/source/types.d.ts +121 -104
- package/dist/source/types.js +13 -14
- package/dist/stores/ObjectStore.d.ts +10 -11
- package/dist/stores/ObjectStore.js +11 -12
- package/dist/stores/ObjectStoreContract.d.ts +12 -15
- package/dist/stores/SyncActionStore.d.ts +7 -11
- package/dist/stores/SyncActionStore.js +13 -17
- package/dist/surface.d.ts +27 -20
- package/dist/surface.js +27 -20
- package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +36 -42
- package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +76 -76
- package/dist/sync/ConnectionManager.d.ts +39 -50
- package/dist/sync/ConnectionManager.js +55 -66
- package/dist/sync/NetworkProbe.d.ts +24 -29
- package/dist/sync/NetworkProbe.js +63 -69
- package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +42 -41
- package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +59 -54
- package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +43 -57
- package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +43 -51
- package/dist/sync/SyncWebSocket.d.ts +139 -165
- package/dist/sync/SyncWebSocket.js +191 -223
- package/dist/sync/awaitClaimGrant.d.ts +18 -18
- package/dist/sync/awaitClaimGrant.js +11 -11
- package/dist/sync/bootstrapApply.d.ts +34 -24
- package/dist/sync/bootstrapApply.js +27 -19
- package/dist/sync/commitFrames.d.ts +21 -20
- package/dist/sync/commitFrames.js +18 -18
- package/dist/sync/createClaimStream.d.ts +23 -22
- package/dist/sync/createClaimStream.js +105 -23
- package/dist/sync/createPresenceStream.d.ts +19 -18
- package/dist/sync/createPresenceStream.js +25 -26
- package/dist/sync/createSnapshot.d.ts +12 -14
- package/dist/sync/createSnapshot.js +20 -26
- package/dist/sync/credentialLifecycle.d.ts +104 -104
- package/dist/sync/credentialLifecycle.js +140 -147
- package/dist/sync/deltaPipeline.d.ts +36 -34
- package/dist/sync/deltaPipeline.js +64 -65
- package/dist/sync/groupChange.d.ts +63 -61
- package/dist/sync/groupChange.js +74 -78
- package/dist/sync/heartbeat.d.ts +34 -33
- package/dist/sync/heartbeat.js +31 -31
- package/dist/sync/participants.d.ts +19 -19
- package/dist/sync/schemas.d.ts +3 -2
- package/dist/sync/schemas.js +14 -10
- package/dist/sync/syncCursor.d.ts +17 -21
- package/dist/sync/syncCursor.js +17 -21
- package/dist/sync/syncPlan.d.ts +28 -36
- package/dist/sync/syncPlan.js +18 -19
- package/dist/sync/syncPosition.d.ts +54 -49
- package/dist/sync/syncPosition.js +57 -52
- package/dist/sync/wsFrameHandlers.d.ts +35 -36
- package/dist/sync/wsFrameHandlers.js +63 -67
- package/dist/testing/fixtures/bootstrap.d.ts +12 -6
- package/dist/testing/fixtures/bootstrap.js +12 -6
- package/dist/testing/fixtures/deltas.d.ts +30 -33
- package/dist/testing/fixtures/deltas.js +30 -33
- package/dist/testing/fixtures/models.d.ts +11 -10
- package/dist/testing/fixtures/models.js +11 -10
- package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
- package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
- package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -15
- package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +12 -10
- package/dist/testing/helpers/wait.d.ts +13 -8
- package/dist/testing/helpers/wait.js +13 -8
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +2 -2
- package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
- package/dist/testing/mocks/MockMutationExecutor.js +15 -14
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
- package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
- package/dist/testing/mocks/MockSyncContext.d.ts +20 -17
- package/dist/testing/mocks/MockSyncContext.js +15 -13
- package/dist/testing/mocks/MockSyncStore.d.ts +10 -10
- package/dist/testing/mocks/MockSyncStore.js +11 -11
- package/dist/testing/mocks/MockWebSocket.d.ts +26 -22
- package/dist/testing/mocks/MockWebSocket.js +22 -21
- package/dist/transactions/TransactionQueue.d.ts +181 -176
- package/dist/transactions/TransactionQueue.js +338 -350
- package/dist/transactions/TransactionStore.d.ts +6 -4
- package/dist/transactions/TransactionStore.js +6 -4
- package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
- package/dist/transactions/UnconfirmedWrites.js +104 -0
- package/dist/transactions/coalesceRules.d.ts +41 -17
- package/dist/transactions/coalesceRules.js +40 -17
- package/dist/transactions/commitPayload.d.ts +48 -52
- package/dist/transactions/commitPayload.js +48 -57
- package/dist/transactions/deltaConfirmation.d.ts +20 -22
- package/dist/transactions/deltaConfirmation.js +37 -45
- package/dist/transactions/optimisticApply.d.ts +49 -0
- package/dist/transactions/optimisticApply.js +65 -0
- package/dist/transactions/{persistedReplay.d.ts → replayValidation.d.ts} +28 -22
- package/dist/transactions/{persistedReplay.js → replayValidation.js} +33 -27
- package/dist/types/global.d.ts +46 -41
- package/dist/types/global.js +20 -19
- package/dist/types/index.d.ts +71 -77
- package/dist/types/index.js +22 -22
- package/dist/types/modelData.d.ts +6 -8
- package/dist/types/modelData.js +5 -7
- package/dist/types/participant.d.ts +10 -11
- package/dist/types/participant.js +6 -8
- package/dist/types/streams.d.ts +208 -195
- package/dist/types/streams.js +7 -7
- package/dist/utils/asyncIterator.d.ts +25 -32
- package/dist/utils/asyncIterator.js +25 -32
- package/dist/utils/duration.d.ts +12 -15
- package/dist/utils/duration.js +12 -15
- package/dist/utils/mobxSetup.d.ts +53 -0
- package/dist/utils/{mobx-setup.js → mobxSetup.js} +42 -98
- package/dist/webhooks/events.d.ts +21 -16
- package/dist/webhooks/events.js +10 -8
- package/dist/webhooks/index.d.ts +5 -7
- package/dist/webhooks/index.js +5 -7
- package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
- package/dist/wire/delta.js +114 -0
- package/dist/wire/errorEnvelope.d.ts +30 -31
- package/dist/wire/errorEnvelope.js +34 -40
- package/dist/wire/frames.d.ts +79 -86
- package/dist/wire/frames.js +26 -33
- package/dist/wire/index.d.ts +14 -12
- package/dist/wire/index.js +30 -26
- package/dist/wire/listEnvelope.d.ts +16 -23
- package/dist/wire/listEnvelope.js +7 -6
- package/dist/wire/protocol.d.ts +25 -32
- package/dist/wire/protocol.js +25 -32
- package/dist/wire/protocolVersion.d.ts +44 -40
- package/dist/wire/protocolVersion.js +44 -40
- package/docs/coordination.md +59 -0
- package/package.json +11 -10
- package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
- package/dist/ai-sdk/coordination-context.d.ts +0 -52
- package/dist/core/query-utils.d.ts +0 -34
- package/dist/core/query-utils.js +0 -59
- package/dist/schema/sync-delta-row.js +0 -103
- package/dist/schema/sync-delta-wire.js +0 -102
- package/dist/server/read-config.d.ts +0 -67
- package/dist/server/read-config.js +0 -8
- package/dist/server/storage-mode.d.ts +0 -8
- package/dist/server/storage-mode.js +0 -28
- package/dist/source/connector-protocol.d.ts +0 -159
- package/dist/source/connector-protocol.js +0 -161
- package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
- package/dist/transactions/OptimisticEchoTracker.js +0 -104
- package/dist/transactions/mutation-error-handler.d.ts +0 -5
- package/dist/transactions/mutation-error-handler.js +0 -39
- package/dist/transactions/optimistic.d.ts +0 -24
- package/dist/transactions/optimistic.js +0 -45
- package/dist/utils/mobx-setup.d.ts +0 -42
|
@@ -1,56 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Builds the internal component graph the client runs on.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Mirrors the pattern Anthropic uses: their client constructor wires
|
|
11
|
-
* endpoint modules. Ours wires the sync-engine components instead.
|
|
4
|
+
* From the caller's options and schema this wires together the model registry,
|
|
5
|
+
* object pool, bootstrap helper, database, sync client, and hydration
|
|
6
|
+
* coordinator. Each component depends on the one before it, so construction
|
|
7
|
+
* order matters; keeping it here means the client constructor does not have to
|
|
8
|
+
* know that order.
|
|
12
9
|
*/
|
|
13
10
|
import { Database } from '../Database.js';
|
|
14
11
|
import { ModelRegistry, setActiveRegistry } from '../ModelRegistry.js';
|
|
15
|
-
import {
|
|
12
|
+
import { InstanceCache } from '../InstanceCache.js';
|
|
16
13
|
import { SyncClient } from '../SyncClient.js';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
14
|
+
import { OnDemandLoader } from '../sync/OnDemandLoader.js';
|
|
15
|
+
import { BootstrapFetcher } from '../sync/BootstrapFetcher.js';
|
|
19
16
|
import { resolveBootstrapBaseUrl } from './auth.js';
|
|
20
17
|
import { shouldUseInMemoryPersistence } from './persistence.js';
|
|
21
18
|
export function createInternalComponents(input) {
|
|
22
19
|
const { schema, url, options, auth } = input;
|
|
23
|
-
// The registry is created here but model registration happens in
|
|
24
|
-
//
|
|
25
|
-
// schema-to-class translation depends on private helpers there).
|
|
20
|
+
// The registry is created here, but model registration happens in the caller,
|
|
21
|
+
// which owns the schema-to-class translation.
|
|
26
22
|
const modelRegistry = new ModelRegistry({
|
|
27
23
|
validateOnRegister: false,
|
|
28
24
|
allowLateReferences: true,
|
|
29
25
|
});
|
|
30
26
|
setActiveRegistry(modelRegistry);
|
|
31
|
-
const objectPool = new
|
|
27
|
+
const objectPool = new InstanceCache({ maxSize: options.maxPoolSize ?? 10000 }, modelRegistry);
|
|
32
28
|
const bootstrapBaseUrl = resolveBootstrapBaseUrl({
|
|
33
29
|
url,
|
|
34
30
|
bootstrapBaseUrl: options.bootstrapBaseUrl,
|
|
35
31
|
});
|
|
36
|
-
const bootstrapHelper = new
|
|
32
|
+
const bootstrapHelper = new BootstrapFetcher({
|
|
37
33
|
baseUrl: bootstrapBaseUrl,
|
|
38
34
|
syncGroups: options.syncGroups,
|
|
39
35
|
instantModels: deriveInstantModels(schema),
|
|
40
36
|
getAuthToken: auth?.getAuthToken,
|
|
41
37
|
});
|
|
42
38
|
const database = new Database(modelRegistry, bootstrapHelper, {
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
39
|
+
// By default there is no browser-local durable store unless the caller asks
|
|
40
|
+
// for one. Node and edge runtimes always use the in-memory store because
|
|
41
|
+
// IndexedDB is unavailable there.
|
|
46
42
|
inMemory: shouldUseInMemoryPersistence(options),
|
|
47
43
|
});
|
|
48
44
|
const syncClient = new SyncClient(objectPool, database);
|
|
49
|
-
// Lazy-load lane: hydrates pool
|
|
50
|
-
// entities not in scope at bootstrap (`load: 'lazy'` models, or
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
const hydration = new
|
|
45
|
+
// Lazy-load lane: hydrates the object pool and IndexedDB on demand for
|
|
46
|
+
// entities not in scope at bootstrap (`load: 'lazy'` models, or an entity
|
|
47
|
+
// reached by deep link before the pool warmed up). Single-flight, with
|
|
48
|
+
// write-through to IndexedDB.
|
|
49
|
+
const hydration = new OnDemandLoader({
|
|
54
50
|
objectPool,
|
|
55
51
|
database,
|
|
56
52
|
registry: modelRegistry,
|
|
@@ -73,11 +69,10 @@ export function createInternalComponents(input) {
|
|
|
73
69
|
};
|
|
74
70
|
}
|
|
75
71
|
/**
|
|
76
|
-
*
|
|
77
|
-
* Models
|
|
78
|
-
*
|
|
79
|
-
* `
|
|
80
|
-
* mechanism. Default load strategy is `'instant'`.
|
|
72
|
+
* Derives the set of models to fetch in the initial bootstrap request from each
|
|
73
|
+
* model's load strategy. Models declared `load: 'lazy'` or `'manual'` are left
|
|
74
|
+
* out of the bootstrap and fetched on demand instead. The default strategy is
|
|
75
|
+
* `'instant'`, which includes the model.
|
|
81
76
|
*/
|
|
82
77
|
function deriveInstantModels(schema) {
|
|
83
78
|
const schemaModels = schema.models ?? schema;
|
|
@@ -1,38 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Builds the typed client for a single schema model — the object reached as
|
|
3
|
+
* `ablo.<model>`.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* local-graph snapshots `get` / `getAll` / `getCount`, the writes
|
|
12
|
-
* `create` / `update` / `delete`, the coordination namespace `claim`
|
|
13
|
-
* (`claim({ id })` plus `claim.state` / `claim.queue` / `claim.release` /
|
|
14
|
-
* `claim.reorder`), and `onChange`. The factory returns a plain object; the
|
|
15
|
-
* client assembles the `ablo.<model>` lookup table from these.
|
|
5
|
+
* Each schema model gets one {@link ModelOperations}: the async server reads
|
|
6
|
+
* `retrieve` and `list`, the synchronous local-graph snapshots `get`, `getAll`,
|
|
7
|
+
* and `getCount`, the writes `create`, `update`, and `delete`, the coordination
|
|
8
|
+
* namespace `claim` (callable as `claim({ id })`, plus `claim.state`,
|
|
9
|
+
* `claim.queue`, `claim.release`, and `claim.reorder`), `watch`, and `onChange`.
|
|
10
|
+
* The factory returns a plain object; the client assembles the `ablo.<model>`
|
|
11
|
+
* lookup table from one of these per model.
|
|
16
12
|
*/
|
|
13
|
+
import { AbloClaimedError } from '../errors.js';
|
|
17
14
|
import { type ModelUpdater, type ContentionOptions } from './functionalUpdate.js';
|
|
18
15
|
import type { MutationOptions } from '../interfaces/index.js';
|
|
19
16
|
import type { ModelRegistry } from '../ModelRegistry.js';
|
|
20
|
-
import type {
|
|
17
|
+
import type { InstanceCache } from '../InstanceCache.js';
|
|
21
18
|
import type { SyncClient } from '../SyncClient.js';
|
|
22
|
-
import type {
|
|
19
|
+
import type { OnDemandLoader } from '../sync/OnDemandLoader.js';
|
|
23
20
|
import type { JoinedParticipant } from '../sync/participants.js';
|
|
24
21
|
import type { LoadWhere } from '../query/types.js';
|
|
25
22
|
import { ModelScope } from '../types/index.js';
|
|
26
|
-
import type { Duration, Claim, HeldClaim, ClaimWaitOptions, Snapshot, TargetRange } from '../types/streams.js';
|
|
23
|
+
import type { Duration, Claim, ClaimHeartbeat, ClaimHeartbeatOptions, HeldClaim, ClaimWaitOptions, Snapshot, TargetRange } from '../types/streams.js';
|
|
27
24
|
export interface ModelClientMeta {
|
|
28
25
|
readonly key: string;
|
|
29
26
|
readonly typename: string;
|
|
30
27
|
}
|
|
31
28
|
export declare function getModelClientMeta(modelClient: unknown): ModelClientMeta | undefined;
|
|
32
29
|
export type ModelListScope = ModelScope | 'live' | 'archived' | 'all';
|
|
33
|
-
/** Options for the
|
|
34
|
-
* `filter`, equality `where`,
|
|
35
|
-
*
|
|
30
|
+
/** Options for the synchronous local-pool reads `get`, `getAll`, and
|
|
31
|
+
* `onChange` — a JavaScript `filter`, an equality `where`, and a lifecycle
|
|
32
|
+
* `state`. This is the local, reactive axis; contrast {@link ServerReadOptions},
|
|
33
|
+
* the asynchronous server axis. */
|
|
36
34
|
export interface LocalReadOptions<T> {
|
|
37
35
|
where?: Partial<T>;
|
|
38
36
|
/** Arbitrary local predicate. Applied after `where`. */
|
|
@@ -42,23 +40,22 @@ export interface LocalReadOptions<T> {
|
|
|
42
40
|
};
|
|
43
41
|
limit?: number;
|
|
44
42
|
offset?: number;
|
|
45
|
-
/** Lifecycle filter — `live` (default), `archived`, or `all`. Named
|
|
46
|
-
*
|
|
47
|
-
* sync-group `scope`. */
|
|
43
|
+
/** Lifecycle filter — `live` (the default), `archived`, or `all`. Named
|
|
44
|
+
* `state` so it does not collide with the sync-group `scope`. */
|
|
48
45
|
state?: ModelListScope;
|
|
49
46
|
}
|
|
50
47
|
export type LocalCountOptions<T> = Pick<LocalReadOptions<T>, 'where' | 'filter' | 'state'>;
|
|
51
|
-
/** Options for the
|
|
52
|
-
* `type`, `expand
|
|
53
|
-
*
|
|
48
|
+
/** Options for the asynchronous server reads `retrieve` and `list` — the
|
|
49
|
+
* operator `where` filter, `type`, and `expand`. This is the server axis;
|
|
50
|
+
* contrast {@link LocalReadOptions}, the local, reactive axis. */
|
|
54
51
|
export interface ServerReadOptions<T> {
|
|
55
52
|
/**
|
|
56
|
-
* Filter for the lookup. Accepts:
|
|
57
|
-
* - object form
|
|
58
|
-
* - tuple form
|
|
53
|
+
* Filter for the lookup. Accepts two forms:
|
|
54
|
+
* - object form — `{ name: 'foo' }`: equality, where an array value means `IN`
|
|
55
|
+
* - tuple form — `[['name', 'ILIKE', '%Goldman%']]`: explicit operators
|
|
59
56
|
*
|
|
60
|
-
* See
|
|
61
|
-
* `list()` calls and union
|
|
57
|
+
* See {@link LoadWhere} for the full grammar. The wire protocol matches on AND
|
|
58
|
+
* only; for OR semantics, run two `list()` calls and union the results.
|
|
62
59
|
*/
|
|
63
60
|
where?: LoadWhere<T>;
|
|
64
61
|
orderBy?: {
|
|
@@ -151,36 +148,33 @@ export interface ModelCollaboration<T> {
|
|
|
151
148
|
*/
|
|
152
149
|
readonly selfParticipantId: string;
|
|
153
150
|
/**
|
|
154
|
-
* The local participant's kind (`'user' | 'agent' | 'system'`). Used to
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
151
|
+
* The local participant's kind (`'user' | 'agent' | 'system'`). Used to stamp
|
|
152
|
+
* the synthesized self-claim returned from `claim.state` when this client
|
|
153
|
+
* holds the lease: server presence frames exclude a holder's own claims, so
|
|
154
|
+
* the holder builds its own view.
|
|
158
155
|
*/
|
|
159
156
|
readonly selfParticipantKind?: 'user' | 'agent' | 'system';
|
|
160
157
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* doubles can omit it. Forwards to `BaseSyncedStore.enterScope`.
|
|
158
|
+
* Subscribes the connection to a scope's sync group(s) — read interest. The
|
|
159
|
+
* typed surface calls this on single-entity reads and claim observation so a
|
|
160
|
+
* client lands in the same entity-scoped group the holder's claim presence
|
|
161
|
+
* fans out on; a peer subscribed only to broader `org:` or `user:` groups
|
|
162
|
+
* would otherwise never see claim broadcasts. Fire-and-forget and best-effort:
|
|
163
|
+
* read interest must never make a read reject or stall. Optional so minimal
|
|
164
|
+
* test doubles can omit it.
|
|
169
165
|
*/
|
|
170
166
|
enterScope?(scope: Record<string, string>): void | Promise<void>;
|
|
171
167
|
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* Forwards to `BaseSyncedStore.pinScope`.
|
|
168
|
+
* Pins a scope's sync group(s) — write intent: a row this client holds an
|
|
169
|
+
* active claim on stays subscribed regardless of navigation. Same
|
|
170
|
+
* fire-and-forget, best-effort semantics as `enterScope`.
|
|
176
171
|
*/
|
|
177
172
|
pinScope?(scope: Record<string, string>): void | Promise<void>;
|
|
178
173
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* case the proxy throws a clear error. Forwards to `participantManager.join`.
|
|
174
|
+
* Opens a presence and claim subscription on this model's sync group(s) and
|
|
175
|
+
* returns the live participant handle. Backs `ablo.<model>.watch(ids)`.
|
|
176
|
+
* WebSocket only, since presence needs a live socket; it is absent on other
|
|
177
|
+
* client constructions, where the proxy throws a clear error.
|
|
184
178
|
*/
|
|
185
179
|
createWatch?(modelKey: string, ids: string | readonly string[], options?: WatchOptions): Promise<JoinedParticipant>;
|
|
186
180
|
}
|
|
@@ -201,28 +195,50 @@ export interface ClaimTargetOptions<T = Record<string, unknown>> {
|
|
|
201
195
|
/** Crash-cleanup TTL — the claim auto-releases if the holder dies. */
|
|
202
196
|
ttl?: Duration;
|
|
203
197
|
/**
|
|
204
|
-
*
|
|
205
|
-
* resolves once
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
* work
|
|
209
|
-
*
|
|
198
|
+
* Behavior under contention. `true` (the default) queues behind the current
|
|
199
|
+
* holder and resolves once the row is yours. `false` is fail-fast: if another
|
|
200
|
+
* participant already holds the row, it rejects immediately with
|
|
201
|
+
* {@link AbloClaimedError} instead of waiting. Use `false` to deduplicate
|
|
202
|
+
* distributed work ("if someone else has this job, skip it"), where waiting
|
|
203
|
+
* would mean double-processing.
|
|
210
204
|
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
* typed claim defaults it ON because it serializes writers; the low-level
|
|
215
|
-
* lease and HTTP default it OFF — they return/resolve immediately and can't
|
|
216
|
-
* transparently wait for a grant.
|
|
205
|
+
* The high-level typed claim defaults this on because it serializes writers;
|
|
206
|
+
* the low-level lease and the HTTP client default it off, since they resolve
|
|
207
|
+
* immediately and cannot transparently wait for a grant.
|
|
217
208
|
*/
|
|
218
209
|
queue?: boolean;
|
|
219
210
|
/**
|
|
220
|
-
* Backpressure:
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
* however deep the queue is.
|
|
211
|
+
* Backpressure: queue, but not behind too many others. If the server reports a
|
|
212
|
+
* position at or beyond `maxQueueDepth` when the client joins the line, it
|
|
213
|
+
* rejects with {@link AbloClaimedError} (`queue_too_deep`) instead of waiting.
|
|
214
|
+
* Omit to wait however deep the queue is.
|
|
224
215
|
*/
|
|
225
216
|
maxQueueDepth?: number;
|
|
217
|
+
/**
|
|
218
|
+
* Keep the lease alive for the duration of real work by beating on a
|
|
219
|
+
* cadence — the pattern for background workers whose task outlives the
|
|
220
|
+
* crash-cleanup TTL. `true` beats every third of the TTL (so two beats can
|
|
221
|
+
* fail before the lease is at risk, and a crashed worker's lease still
|
|
222
|
+
* lapses within one beat window); a duration such as `'2m'` sets the
|
|
223
|
+
* cadence explicitly. The loop stops on release. A beat answered with a
|
|
224
|
+
* definitive loss stops the loop and calls {@link onHeartbeatLost}; you can
|
|
225
|
+
* also beat manually with `held.heartbeat()`.
|
|
226
|
+
*/
|
|
227
|
+
heartbeat?: true | Duration;
|
|
228
|
+
/**
|
|
229
|
+
* Called once if the auto-heartbeat learns the lease is no longer yours
|
|
230
|
+
* (expired and possibly granted onward). The loop has already stopped;
|
|
231
|
+
* abandon the work or re-claim. Any write attempted under the old lease is
|
|
232
|
+
* independently rejected by its `readAt` guard.
|
|
233
|
+
*/
|
|
234
|
+
onHeartbeatLost?: (error: AbloClaimedError) => void;
|
|
235
|
+
/**
|
|
236
|
+
* Called after every successful beat (manual or auto) with the server's
|
|
237
|
+
* answer — chiefly `queueDepth`, the number of participants waiting in
|
|
238
|
+
* line behind this lease. A worker that can checkpoint may read pressure
|
|
239
|
+
* here and release early when others wait.
|
|
240
|
+
*/
|
|
241
|
+
onHeartbeat?(beat: ClaimHeartbeat): void;
|
|
226
242
|
}
|
|
227
243
|
/** Options for `claim({ id, ... })`. */
|
|
228
244
|
export interface ClaimParams<T = Record<string, unknown>> extends ClaimTargetOptions<T> {
|
|
@@ -236,7 +252,7 @@ export interface ClaimReorderParams<T = Record<string, unknown>> extends ClaimLo
|
|
|
236
252
|
readonly order: readonly Claim[];
|
|
237
253
|
}
|
|
238
254
|
/**
|
|
239
|
-
* A claim handle: the held entity data plus an explicit release hook
|
|
255
|
+
* A claim handle: the held entity data plus an explicit release hook.
|
|
240
256
|
*
|
|
241
257
|
* ```ts
|
|
242
258
|
* const claim = await ablo.weatherReports.claim({
|
|
@@ -257,9 +273,9 @@ export interface ClaimReorderParams<T = Record<string, unknown>> extends ClaimLo
|
|
|
257
273
|
*
|
|
258
274
|
* `data` is a snapshot taken after the lease is held. Write through the flat
|
|
259
275
|
* `ablo.<model>.update({ id, data, claim })` verb — the handle carries the
|
|
260
|
-
* lease id and snapshot watermark for attribution
|
|
276
|
+
* lease id and snapshot watermark for attribution and stale-write protection.
|
|
261
277
|
*/
|
|
262
|
-
export type { Claim, HeldClaim };
|
|
278
|
+
export type { Claim, ClaimHeartbeat, ClaimHeartbeatOptions, HeldClaim };
|
|
263
279
|
export type ClaimOptions<T = Record<string, unknown>> = ClaimTargetOptions<T>;
|
|
264
280
|
/**
|
|
265
281
|
* The coordination surface for a model, exposed as a callable namespace.
|
|
@@ -284,15 +300,15 @@ export type ClaimOptions<T = Record<string, unknown>> = ClaimTargetOptions<T>;
|
|
|
284
300
|
* controls for UI and operators.
|
|
285
301
|
*/
|
|
286
302
|
/**
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
* local pool with no round-trip, which is what lets
|
|
290
|
-
*
|
|
303
|
+
* The coordination reads and scheduler controls on a claim namespace, in their
|
|
304
|
+
* reactive (synchronous) form: `state`, `queue`, and `reorder` resolve against
|
|
305
|
+
* the local pool with no round-trip, which is what lets a reactive selector read
|
|
306
|
+
* coordination state inside a React render.
|
|
291
307
|
*
|
|
292
|
-
* This is the single source of truth for the claim read surface
|
|
293
|
-
* HTTP client exposes the
|
|
294
|
-
*
|
|
295
|
-
*
|
|
308
|
+
* This is the single source of truth for the claim read surface. The stateless
|
|
309
|
+
* HTTP client exposes the awaited projection of exactly these methods (derived
|
|
310
|
+
* via {@link AwaitedClaimMethod}), so the two transports cannot drift — change a
|
|
311
|
+
* signature here and the HTTP surface follows.
|
|
296
312
|
*/
|
|
297
313
|
export interface ClaimReadApi<T = Record<string, unknown>> {
|
|
298
314
|
/**
|
|
@@ -323,10 +339,10 @@ export interface ClaimReadApi<T = Record<string, unknown>> {
|
|
|
323
339
|
export type AwaitedClaimMethod<F> = F extends (...args: infer A) => infer R ? R extends Promise<unknown> ? (...args: A) => R : (...args: A) => Promise<R> : F;
|
|
324
340
|
export interface ClaimApi<T> extends ClaimReadApi<T> {
|
|
325
341
|
/**
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
342
|
+
* Takes a claim and returns an explicit held-work handle — a {@link HeldClaim}.
|
|
343
|
+
* `data`, `release`, `revoke`, and the async disposer are always present (this
|
|
344
|
+
* call re-reads the row under the lease), so callers can use `handle.data`
|
|
345
|
+
* directly and `await using` works without a guard.
|
|
330
346
|
*/
|
|
331
347
|
(params: ClaimParams<T>): Promise<HeldClaim<T>>;
|
|
332
348
|
}
|
|
@@ -358,42 +374,37 @@ export interface WatchOptions {
|
|
|
358
374
|
}
|
|
359
375
|
export interface ModelOperations<T, CreateInput> {
|
|
360
376
|
/**
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
* and lands the row in the local graph. Resolves to
|
|
364
|
-
* such row exists.
|
|
377
|
+
* Reads a single entity by id from the server; asynchronous. Resolves through
|
|
378
|
+
* a three-tier lookup — local pool, then IndexedDB, then a network
|
|
379
|
+
* `POST /sync/query` — and lands the row in the local graph. Resolves to
|
|
380
|
+
* `undefined` when no such row exists.
|
|
365
381
|
*
|
|
366
|
-
* This is the default "get me this entity" read and the one
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
* `get(id)`.
|
|
370
|
-
*
|
|
371
|
-
* Mirrors `stripe.customers.retrieve({ id })` — network-backed.
|
|
382
|
+
* This is the default "get me this entity" read, and the one a stateless
|
|
383
|
+
* client wants, since its local graph starts empty. For a synchronous read of
|
|
384
|
+
* an already-warm graph (such as a React selector) use `get(id)`.
|
|
372
385
|
*/
|
|
373
386
|
retrieve(params: ModelRetrieveParams): Promise<T | undefined>;
|
|
374
387
|
/**
|
|
375
|
-
*
|
|
376
|
-
* lookup
|
|
377
|
-
* matched rows.
|
|
378
|
-
*
|
|
379
|
-
* Mirrors `stripe.customers.list({...})` — network-backed. For a synchronous
|
|
380
|
-
* read of the local graph use `getAll(...)`.
|
|
388
|
+
* Lists entities matching a filter from the server; asynchronous. Uses the
|
|
389
|
+
* same three-tier lookup and graph hydration as `retrieve`, deduplicated so
|
|
390
|
+
* concurrent identical calls share one request. Returns the matched rows. For
|
|
391
|
+
* a synchronous read of the local graph use `getAll(...)`.
|
|
381
392
|
*/
|
|
382
393
|
list(options?: ServerReadOptions<T>): Promise<T[]>;
|
|
383
394
|
/**
|
|
384
|
-
* Synchronous snapshot of a single entity from the
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
* `useAblo((ablo) => ablo.<model>.get(id))`.
|
|
395
|
+
* Synchronous snapshot of a single entity from the local graph; no network.
|
|
396
|
+
* Returns `undefined` when the row is not resident (a client whose graph is
|
|
397
|
+
* still empty, or a `lazy` model not yet loaded). Pairs with reactive
|
|
398
|
+
* selectors: `useAblo((ablo) => ablo.<model>.get(id))`.
|
|
388
399
|
*/
|
|
389
400
|
get(id: string): T | undefined;
|
|
390
401
|
/**
|
|
391
|
-
* Synchronous snapshot of a filtered collection from the
|
|
392
|
-
*
|
|
402
|
+
* Synchronous snapshot of a filtered collection from the local graph; no
|
|
403
|
+
* network round-trip. Empty until `retrieve`, `list`, or bootstrap has warmed
|
|
393
404
|
* the graph.
|
|
394
405
|
*/
|
|
395
406
|
getAll(options?: LocalReadOptions<T>): T[];
|
|
396
|
-
/** Count entities in the
|
|
407
|
+
/** Count entities in the local graph; synchronous, no network. */
|
|
397
408
|
getCount(options?: LocalCountOptions<T>): number;
|
|
398
409
|
/**
|
|
399
410
|
* Create a new entity — **optimistic, offline-first**. Resolves once
|
|
@@ -404,14 +415,14 @@ export interface ModelOperations<T, CreateInput> {
|
|
|
404
415
|
/** Update an entity by id — optimistic, offline-first (see `create`). */
|
|
405
416
|
update(params: ModelUpdateParams<T>): Promise<T>;
|
|
406
417
|
/**
|
|
407
|
-
*
|
|
408
|
-
* `update(id, current => next)
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
418
|
+
* Updates under contention with a function of the latest state —
|
|
419
|
+
* `update(id, current => next)`. The client reads the freshest row, runs your
|
|
420
|
+
* updater, writes the result as a compare-and-swap, and re-reads and re-runs
|
|
421
|
+
* on any concurrent write. Nothing about claims, identity, or conflict codes
|
|
422
|
+
* surfaces: the write either lands or throws {@link AbloContentionError} once
|
|
423
|
+
* its reconcile budget is spent. Return `null` or `undefined` from the updater
|
|
424
|
+
* to skip the write. Resolves to the reconciled row, or `undefined` when the
|
|
425
|
+
* updater opted out.
|
|
415
426
|
*/
|
|
416
427
|
update(id: string, updater: ModelUpdater<T>, options?: ContentionOptions): Promise<T | undefined>;
|
|
417
428
|
/** Delete an entity by id — optimistic, offline-first (see `create`). */
|
|
@@ -445,13 +456,12 @@ export interface ModelOperations<T, CreateInput> {
|
|
|
445
456
|
*/
|
|
446
457
|
claim: ClaimApi<T>;
|
|
447
458
|
/**
|
|
448
|
-
*
|
|
449
|
-
* model and
|
|
459
|
+
* Subscribes this client to the sync group(s) for one or more rows of this
|
|
460
|
+
* model and returns a live participant handle — presence (`.peers`), the
|
|
450
461
|
* scoped claim stream (`.claims`), and `.leave()` / `await using` disposal.
|
|
451
462
|
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
* this is absent on HTTP clients and throws on any non-ws construction.
|
|
463
|
+
* WebSocket only: presence needs a live socket, so this is absent on HTTP
|
|
464
|
+
* clients and throws on any non-WebSocket construction.
|
|
455
465
|
*
|
|
456
466
|
* ```ts
|
|
457
467
|
* await using participant = await ablo.slides.watch(slideIds, { ttl: '5m' });
|
|
@@ -459,7 +469,7 @@ export interface ModelOperations<T, CreateInput> {
|
|
|
459
469
|
* ```
|
|
460
470
|
*/
|
|
461
471
|
watch(ids: string | readonly string[], options?: WatchOptions): Promise<JoinedParticipant>;
|
|
462
|
-
/**
|
|
472
|
+
/** Subscribe to changes; the callback runs on every change. */
|
|
463
473
|
onChange(callback: (entities: T[]) => void, options?: LocalReadOptions<T>): () => void;
|
|
464
474
|
}
|
|
465
|
-
export declare function createModelProxy<T, C>(schemaKey: string, registeredModelName: string, objectPool:
|
|
475
|
+
export declare function createModelProxy<T, C>(schemaKey: string, registeredModelName: string, objectPool: InstanceCache, syncClient: SyncClient, registry: ModelRegistry, hydration: OnDemandLoader, collaboration?: ModelCollaboration<T>): ModelOperations<T, C>;
|