@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
package/dist/Model.d.ts
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Model
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - Return updates/changes (not perform them)
|
|
9
|
-
*
|
|
10
|
-
* Models do NOT:
|
|
11
|
-
* - Access stores or singletons
|
|
12
|
-
* - Perform side effects (saving, notifications)
|
|
13
|
-
* - Know about sync infrastructure
|
|
2
|
+
* Model is the base class for the sync engine's domain models. A model is a
|
|
3
|
+
* plain domain object: it holds data and business logic, tracks its own
|
|
4
|
+
* property changes, and validates itself, and it returns the changes to apply
|
|
5
|
+
* rather than applying them. It does not reach into stores or singletons and
|
|
6
|
+
* does not perform side effects such as saving or sending notifications;
|
|
7
|
+
* persistence and sync are driven by the store that owns the model.
|
|
14
8
|
*/
|
|
15
9
|
/** Store interface — methods that Model subclasses can call on the store */
|
|
16
10
|
interface SyncStoreRef {
|
|
@@ -67,9 +61,10 @@ export interface ModelChanges {
|
|
|
67
61
|
timestamp: Date;
|
|
68
62
|
}
|
|
69
63
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
64
|
+
* The abstract base class every domain model extends. It holds the model's id
|
|
65
|
+
* and timestamps, tracks in-place property changes for change detection and
|
|
66
|
+
* undo, and serializes itself, while leaving persistence and sync to the store
|
|
67
|
+
* that owns it.
|
|
73
68
|
*/
|
|
74
69
|
export declare abstract class Model {
|
|
75
70
|
/** Static reference to active SyncedStore for reactive queries */
|
|
@@ -156,27 +151,17 @@ export declare abstract class Model {
|
|
|
156
151
|
*/
|
|
157
152
|
isNew(): boolean;
|
|
158
153
|
/**
|
|
159
|
-
*
|
|
160
|
-
* load.
|
|
161
|
-
*
|
|
162
|
-
* `modifiedProperties
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* Architectural note: this method exists because we allow direct
|
|
166
|
-
* property writes (`slide.title = 'foo'`) AND mutator-recorded
|
|
167
|
-
* writes to coexist. Zero / Replicache structurally avoids this:
|
|
168
|
-
* every mutation MUST go through a registered mutator function,
|
|
169
|
-
* mutator args are serialized, and on server pull all unacked
|
|
170
|
-
* mutations are dropped and the mutator functions are replayed on
|
|
171
|
-
* the new basis (rebase). That makes per-instance baselines
|
|
172
|
-
* unnecessary because the b-tree at the new basis IS the
|
|
173
|
-
* authoritative pre-session state.
|
|
154
|
+
* Return a read-only view of the snapshot taken at {@link markAsPersisted}
|
|
155
|
+
* or at load time. The undo machinery uses it to recover a field's pre-edit
|
|
156
|
+
* value when the field was written without first being tracked in
|
|
157
|
+
* `modifiedProperties`. The returned object is the live snapshot, so callers
|
|
158
|
+
* must not mutate it.
|
|
174
159
|
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* `
|
|
178
|
-
*
|
|
179
|
-
*
|
|
160
|
+
* This per-instance baseline is needed because application code can edit a
|
|
161
|
+
* model in two ways that coexist: a direct property write
|
|
162
|
+
* (`slide.title = 'foo'`) and a recorded mutation. A design in which every
|
|
163
|
+
* write went through a single recorded path would not need it, since the
|
|
164
|
+
* last acknowledged state would already be the authoritative baseline.
|
|
180
165
|
*/
|
|
181
166
|
getOriginalSnapshot(): Readonly<ModelData> | undefined;
|
|
182
167
|
/**
|
|
@@ -184,7 +169,7 @@ export declare abstract class Model {
|
|
|
184
169
|
*/
|
|
185
170
|
clearChanges(): void;
|
|
186
171
|
/**
|
|
187
|
-
* Capture a before-image for `keys` — the
|
|
172
|
+
* Capture a before-image for `keys` — the single source of truth for the
|
|
188
173
|
* "previous value" that undo inverses are built from. Both undo paths call
|
|
189
174
|
* this so they can never drift: the stream path
|
|
190
175
|
* (`TransactionQueue.extractPreviousData`) and the manual-record path
|
|
@@ -194,10 +179,10 @@ export declare abstract class Model {
|
|
|
194
179
|
* 1. `modifiedProperties.get(key).old` — first-old-wins pre-session
|
|
195
180
|
* baseline, set whenever the field was mutated in place before commit.
|
|
196
181
|
* 2. `getOriginalSnapshot()[key]` — the last loaded/acked row, the correct
|
|
197
|
-
* before-image for a key written
|
|
182
|
+
* before-image for a key written without a prior in-place mutation
|
|
198
183
|
* (e.g. a `precomputedChanges` write).
|
|
199
184
|
* 3. `fallbackToLive` only — the current live value. The manual-record path
|
|
200
|
-
* wants this last resort; the stream path deliberately
|
|
185
|
+
* wants this last resort; the stream path deliberately omits unresolved
|
|
201
186
|
* keys so `buildUndoOps` drops an un-revertible inverse rather than
|
|
202
187
|
* inventing one. The flag is the one intentional difference between the
|
|
203
188
|
* two callers — do not collapse it.
|
|
@@ -205,8 +190,8 @@ export declare abstract class Model {
|
|
|
205
190
|
* `id` is always skipped. Values are read out per-key, so the
|
|
206
191
|
* `getOriginalSnapshot()` "callers must not mutate" contract is preserved.
|
|
207
192
|
*
|
|
208
|
-
* Invariant this relies on: a given undo scope is
|
|
209
|
-
* (`recordFromStream: true`)
|
|
193
|
+
* Invariant this relies on: a given undo scope is either stream-recorded
|
|
194
|
+
* (`recordFromStream: true`) or manual (`useMutators({ undoScope })`), never
|
|
210
195
|
* both — otherwise a write would be captured twice. No surface sets both.
|
|
211
196
|
*/
|
|
212
197
|
capturePreviousValues(keys: Iterable<string>, opts?: {
|
|
@@ -214,7 +199,7 @@ export declare abstract class Model {
|
|
|
214
199
|
}): ModelData;
|
|
215
200
|
/**
|
|
216
201
|
* Drop the `modifiedProperties` entries for `keys` — re-baselines a field
|
|
217
|
-
* after its `.old` has been frozen into a committed transaction, so the
|
|
202
|
+
* after its `.old` has been frozen into a committed transaction, so the next
|
|
218
203
|
* write to the same field starts from this commit's result rather than the
|
|
219
204
|
* stale pre-session `.old` that {@link propertyChanged}'s first-old-wins
|
|
220
205
|
* policy preserves. Safe because the committed transaction owns its own
|
|
@@ -257,7 +242,7 @@ export declare abstract class Model {
|
|
|
257
242
|
* properties, and coercing date fields. Shared by `updateFromData`
|
|
258
243
|
* (hydration) and `applyChanges` (local user update).
|
|
259
244
|
*
|
|
260
|
-
* Change tracking is
|
|
245
|
+
* Change tracking is explicit: for every field actually
|
|
261
246
|
* written, `onWrite(key, oldValue, newValue)` is invoked with the value
|
|
262
247
|
* captured immediately before assignment. `applyChanges` passes a hook
|
|
263
248
|
* that records the change in `modifiedProperties`; `updateFromData`
|
|
@@ -270,10 +255,10 @@ export declare abstract class Model {
|
|
|
270
255
|
* Update from raw data (hydration)
|
|
271
256
|
*
|
|
272
257
|
* Used for inbound server deltas and pool upserts. Change tracking is
|
|
273
|
-
* deliberately suppressed: hydration writes must
|
|
258
|
+
* deliberately suppressed: hydration writes must not land in
|
|
274
259
|
* `modifiedProperties`, otherwise applying a server delta would queue a
|
|
275
260
|
* brand-new outbound mutation and the record would echo forever. For a
|
|
276
|
-
*
|
|
261
|
+
* local user edit, use `applyChanges` instead.
|
|
277
262
|
*
|
|
278
263
|
* Suppression is belt-and-suspenders: we pass no `onWrite` hook AND
|
|
279
264
|
* clear/restore `modifiedProperties` around the assignment, so any
|
|
@@ -282,18 +267,18 @@ export declare abstract class Model {
|
|
|
282
267
|
*/
|
|
283
268
|
updateFromData(data: ModelData): void;
|
|
284
269
|
/**
|
|
285
|
-
* Apply a
|
|
286
|
-
* path for `proxy.update({ id, data })`, which is the
|
|
270
|
+
* Apply a local, user-initiated update from a data object — the write
|
|
271
|
+
* path for `proxy.update({ id, data })`, which is the one and only way
|
|
287
272
|
* application code mutates synced fields.
|
|
288
273
|
*
|
|
289
274
|
* Unlike `updateFromData` (hydration, untracked), this records every
|
|
290
275
|
* written field in `modifiedProperties` via `propertyChanged`, so
|
|
291
|
-
* `getChanges()`
|
|
292
|
-
* server and the undo system gets a correct pre-write baseline.
|
|
293
|
-
*
|
|
294
|
-
*
|
|
276
|
+
* `getChanges()` and the transaction queue send the edited fields to the
|
|
277
|
+
* server and the undo system gets a correct pre-write baseline. Recording
|
|
278
|
+
* is explicit here, through the `onWrite` hook, and does not rely on any
|
|
279
|
+
* MobX `observe()` side channel.
|
|
295
280
|
*
|
|
296
|
-
* `_originalData` is intentionally
|
|
281
|
+
* `_originalData` is intentionally not reset here: it stays as the
|
|
297
282
|
* last-persisted baseline until `clearChanges()` runs on sync-ack.
|
|
298
283
|
*/
|
|
299
284
|
applyChanges(data: ModelData): void;
|
|
@@ -335,7 +320,7 @@ export declare abstract class Model {
|
|
|
335
320
|
_unregisterObservedCollection(collection: Disposable): void;
|
|
336
321
|
/**
|
|
337
322
|
* Check if any collection on this model is currently being observed by React
|
|
338
|
-
* Used by
|
|
323
|
+
* Used by InstanceCache GC to prevent disposing models in active use
|
|
339
324
|
*/
|
|
340
325
|
hasObservedCollections(): boolean;
|
|
341
326
|
/**
|
package/dist/Model.js
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Model
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - Return updates/changes (not perform them)
|
|
9
|
-
*
|
|
10
|
-
* Models do NOT:
|
|
11
|
-
* - Access stores or singletons
|
|
12
|
-
* - Perform side effects (saving, notifications)
|
|
13
|
-
* - Know about sync infrastructure
|
|
2
|
+
* Model is the base class for the sync engine's domain models. A model is a
|
|
3
|
+
* plain domain object: it holds data and business logic, tracks its own
|
|
4
|
+
* property changes, and validates itself, and it returns the changes to apply
|
|
5
|
+
* rather than applying them. It does not reach into stores or singletons and
|
|
6
|
+
* does not perform side effects such as saving or sending notifications;
|
|
7
|
+
* persistence and sync are driven by the store that owns the model.
|
|
14
8
|
*/
|
|
15
9
|
import { runInAction, isComputedProp } from 'mobx';
|
|
16
10
|
import { v4 as uuid } from 'uuid';
|
|
17
|
-
import { M1 } from './utils/
|
|
11
|
+
import { M1 } from './utils/mobxSetup.js';
|
|
18
12
|
import { getActiveRegistry, hasActiveRegistry } from './ModelRegistry.js';
|
|
19
13
|
import { getContext } from './context.js';
|
|
20
14
|
import { AbloValidationError } from './errors.js';
|
|
@@ -30,9 +24,10 @@ export class ValidationError extends Error {
|
|
|
30
24
|
}
|
|
31
25
|
}
|
|
32
26
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
27
|
+
* The abstract base class every domain model extends. It holds the model's id
|
|
28
|
+
* and timestamps, tracks in-place property changes for change detection and
|
|
29
|
+
* undo, and serializes itself, while leaving persistence and sync to the store
|
|
30
|
+
* that owns it.
|
|
36
31
|
*/
|
|
37
32
|
export class Model {
|
|
38
33
|
/** Static reference to active SyncedStore for reactive queries */
|
|
@@ -189,27 +184,17 @@ export class Model {
|
|
|
189
184
|
return this._isNew;
|
|
190
185
|
}
|
|
191
186
|
/**
|
|
192
|
-
*
|
|
193
|
-
* load.
|
|
194
|
-
*
|
|
195
|
-
* `modifiedProperties
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
* Architectural note: this method exists because we allow direct
|
|
199
|
-
* property writes (`slide.title = 'foo'`) AND mutator-recorded
|
|
200
|
-
* writes to coexist. Zero / Replicache structurally avoids this:
|
|
201
|
-
* every mutation MUST go through a registered mutator function,
|
|
202
|
-
* mutator args are serialized, and on server pull all unacked
|
|
203
|
-
* mutations are dropped and the mutator functions are replayed on
|
|
204
|
-
* the new basis (rebase). That makes per-instance baselines
|
|
205
|
-
* unnecessary because the b-tree at the new basis IS the
|
|
206
|
-
* authoritative pre-session state.
|
|
187
|
+
* Return a read-only view of the snapshot taken at {@link markAsPersisted}
|
|
188
|
+
* or at load time. The undo machinery uses it to recover a field's pre-edit
|
|
189
|
+
* value when the field was written without first being tracked in
|
|
190
|
+
* `modifiedProperties`. The returned object is the live snapshot, so callers
|
|
191
|
+
* must not mutate it.
|
|
207
192
|
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
* `
|
|
211
|
-
*
|
|
212
|
-
*
|
|
193
|
+
* This per-instance baseline is needed because application code can edit a
|
|
194
|
+
* model in two ways that coexist: a direct property write
|
|
195
|
+
* (`slide.title = 'foo'`) and a recorded mutation. A design in which every
|
|
196
|
+
* write went through a single recorded path would not need it, since the
|
|
197
|
+
* last acknowledged state would already be the authoritative baseline.
|
|
213
198
|
*/
|
|
214
199
|
getOriginalSnapshot() {
|
|
215
200
|
return this._originalData;
|
|
@@ -224,7 +209,7 @@ export class Model {
|
|
|
224
209
|
});
|
|
225
210
|
}
|
|
226
211
|
/**
|
|
227
|
-
* Capture a before-image for `keys` — the
|
|
212
|
+
* Capture a before-image for `keys` — the single source of truth for the
|
|
228
213
|
* "previous value" that undo inverses are built from. Both undo paths call
|
|
229
214
|
* this so they can never drift: the stream path
|
|
230
215
|
* (`TransactionQueue.extractPreviousData`) and the manual-record path
|
|
@@ -234,10 +219,10 @@ export class Model {
|
|
|
234
219
|
* 1. `modifiedProperties.get(key).old` — first-old-wins pre-session
|
|
235
220
|
* baseline, set whenever the field was mutated in place before commit.
|
|
236
221
|
* 2. `getOriginalSnapshot()[key]` — the last loaded/acked row, the correct
|
|
237
|
-
* before-image for a key written
|
|
222
|
+
* before-image for a key written without a prior in-place mutation
|
|
238
223
|
* (e.g. a `precomputedChanges` write).
|
|
239
224
|
* 3. `fallbackToLive` only — the current live value. The manual-record path
|
|
240
|
-
* wants this last resort; the stream path deliberately
|
|
225
|
+
* wants this last resort; the stream path deliberately omits unresolved
|
|
241
226
|
* keys so `buildUndoOps` drops an un-revertible inverse rather than
|
|
242
227
|
* inventing one. The flag is the one intentional difference between the
|
|
243
228
|
* two callers — do not collapse it.
|
|
@@ -245,8 +230,8 @@ export class Model {
|
|
|
245
230
|
* `id` is always skipped. Values are read out per-key, so the
|
|
246
231
|
* `getOriginalSnapshot()` "callers must not mutate" contract is preserved.
|
|
247
232
|
*
|
|
248
|
-
* Invariant this relies on: a given undo scope is
|
|
249
|
-
* (`recordFromStream: true`)
|
|
233
|
+
* Invariant this relies on: a given undo scope is either stream-recorded
|
|
234
|
+
* (`recordFromStream: true`) or manual (`useMutators({ undoScope })`), never
|
|
250
235
|
* both — otherwise a write would be captured twice. No surface sets both.
|
|
251
236
|
*/
|
|
252
237
|
capturePreviousValues(keys, opts) {
|
|
@@ -271,7 +256,7 @@ export class Model {
|
|
|
271
256
|
}
|
|
272
257
|
/**
|
|
273
258
|
* Drop the `modifiedProperties` entries for `keys` — re-baselines a field
|
|
274
|
-
* after its `.old` has been frozen into a committed transaction, so the
|
|
259
|
+
* after its `.old` has been frozen into a committed transaction, so the next
|
|
275
260
|
* write to the same field starts from this commit's result rather than the
|
|
276
261
|
* stale pre-session `.old` that {@link propertyChanged}'s first-old-wins
|
|
277
262
|
* policy preserves. Safe because the committed transaction owns its own
|
|
@@ -362,7 +347,7 @@ export class Model {
|
|
|
362
347
|
// New model - return create operation
|
|
363
348
|
return {
|
|
364
349
|
type: 'create',
|
|
365
|
-
modelName: this.getModelName(), //
|
|
350
|
+
modelName: this.getModelName(), // the registered model name
|
|
366
351
|
modelId: this.id,
|
|
367
352
|
timestamp: new Date(),
|
|
368
353
|
};
|
|
@@ -371,7 +356,7 @@ export class Model {
|
|
|
371
356
|
// Existing model with changes - return update operation
|
|
372
357
|
return {
|
|
373
358
|
type: 'update',
|
|
374
|
-
modelName: this.getModelName(), //
|
|
359
|
+
modelName: this.getModelName(), // the registered model name
|
|
375
360
|
modelId: this.id,
|
|
376
361
|
changes: new Map(this.modifiedProperties),
|
|
377
362
|
timestamp: new Date(),
|
|
@@ -392,7 +377,7 @@ export class Model {
|
|
|
392
377
|
this.willDelete();
|
|
393
378
|
return {
|
|
394
379
|
type: 'delete',
|
|
395
|
-
modelName: this.getModelName(), //
|
|
380
|
+
modelName: this.getModelName(), // the registered model name
|
|
396
381
|
modelId: this.id,
|
|
397
382
|
timestamp: new Date(),
|
|
398
383
|
};
|
|
@@ -409,7 +394,7 @@ export class Model {
|
|
|
409
394
|
this.archivedAt = new Date();
|
|
410
395
|
return {
|
|
411
396
|
type: 'archive',
|
|
412
|
-
modelName: this.getModelName(), //
|
|
397
|
+
modelName: this.getModelName(), // the registered model name
|
|
413
398
|
modelId: this.id,
|
|
414
399
|
timestamp: new Date(),
|
|
415
400
|
};
|
|
@@ -426,7 +411,7 @@ export class Model {
|
|
|
426
411
|
this.archivedAt = null;
|
|
427
412
|
return {
|
|
428
413
|
type: 'unarchive',
|
|
429
|
-
modelName: this.getModelName(), //
|
|
414
|
+
modelName: this.getModelName(), // the registered model name
|
|
430
415
|
modelId: this.id,
|
|
431
416
|
timestamp: new Date(),
|
|
432
417
|
};
|
|
@@ -437,7 +422,7 @@ export class Model {
|
|
|
437
422
|
* properties, and coercing date fields. Shared by `updateFromData`
|
|
438
423
|
* (hydration) and `applyChanges` (local user update).
|
|
439
424
|
*
|
|
440
|
-
* Change tracking is
|
|
425
|
+
* Change tracking is explicit: for every field actually
|
|
441
426
|
* written, `onWrite(key, oldValue, newValue)` is invoked with the value
|
|
442
427
|
* captured immediately before assignment. `applyChanges` passes a hook
|
|
443
428
|
* that records the change in `modifiedProperties`; `updateFromData`
|
|
@@ -497,10 +482,10 @@ export class Model {
|
|
|
497
482
|
* Update from raw data (hydration)
|
|
498
483
|
*
|
|
499
484
|
* Used for inbound server deltas and pool upserts. Change tracking is
|
|
500
|
-
* deliberately suppressed: hydration writes must
|
|
485
|
+
* deliberately suppressed: hydration writes must not land in
|
|
501
486
|
* `modifiedProperties`, otherwise applying a server delta would queue a
|
|
502
487
|
* brand-new outbound mutation and the record would echo forever. For a
|
|
503
|
-
*
|
|
488
|
+
* local user edit, use `applyChanges` instead.
|
|
504
489
|
*
|
|
505
490
|
* Suppression is belt-and-suspenders: we pass no `onWrite` hook AND
|
|
506
491
|
* clear/restore `modifiedProperties` around the assignment, so any
|
|
@@ -527,18 +512,18 @@ export class Model {
|
|
|
527
512
|
this.didUpdate();
|
|
528
513
|
}
|
|
529
514
|
/**
|
|
530
|
-
* Apply a
|
|
531
|
-
* path for `proxy.update({ id, data })`, which is the
|
|
515
|
+
* Apply a local, user-initiated update from a data object — the write
|
|
516
|
+
* path for `proxy.update({ id, data })`, which is the one and only way
|
|
532
517
|
* application code mutates synced fields.
|
|
533
518
|
*
|
|
534
519
|
* Unlike `updateFromData` (hydration, untracked), this records every
|
|
535
520
|
* written field in `modifiedProperties` via `propertyChanged`, so
|
|
536
|
-
* `getChanges()`
|
|
537
|
-
* server and the undo system gets a correct pre-write baseline.
|
|
538
|
-
*
|
|
539
|
-
*
|
|
521
|
+
* `getChanges()` and the transaction queue send the edited fields to the
|
|
522
|
+
* server and the undo system gets a correct pre-write baseline. Recording
|
|
523
|
+
* is explicit here, through the `onWrite` hook, and does not rely on any
|
|
524
|
+
* MobX `observe()` side channel.
|
|
540
525
|
*
|
|
541
|
-
* `_originalData` is intentionally
|
|
526
|
+
* `_originalData` is intentionally not reset here: it stays as the
|
|
542
527
|
* last-persisted baseline until `clearChanges()` runs on sync-ack.
|
|
543
528
|
*/
|
|
544
529
|
applyChanges(data) {
|
|
@@ -564,8 +549,8 @@ export class Model {
|
|
|
564
549
|
const modelName = this.getModelName();
|
|
565
550
|
const properties = getActiveRegistry().getProperties(modelName);
|
|
566
551
|
const result = {
|
|
567
|
-
__class: this.getModelName(), //
|
|
568
|
-
__typename: this.getModelName(), //
|
|
552
|
+
__class: this.getModelName(), // the registered model name for consistency
|
|
553
|
+
__typename: this.getModelName(), // __typename mirrors __class as the wire type discriminator
|
|
569
554
|
id: this.id,
|
|
570
555
|
createdAt: this.createdAt?.toISOString(),
|
|
571
556
|
updatedAt: this.updatedAt?.toISOString(),
|
|
@@ -656,7 +641,7 @@ export class Model {
|
|
|
656
641
|
}
|
|
657
642
|
/**
|
|
658
643
|
* Check if any collection on this model is currently being observed by React
|
|
659
|
-
* Used by
|
|
644
|
+
* Used by InstanceCache GC to prevent disposing models in active use
|
|
660
645
|
*/
|
|
661
646
|
hasObservedCollections() {
|
|
662
647
|
return this._observedCollections.size > 0;
|
|
@@ -813,7 +798,7 @@ export class Model {
|
|
|
813
798
|
}
|
|
814
799
|
// Try to get model class by identifier
|
|
815
800
|
let ModelClass = getActiveRegistry().getModelByName(modelIdentifier);
|
|
816
|
-
// If not found
|
|
801
|
+
// If not found by registered name, try mapping to the class name
|
|
817
802
|
if (!ModelClass) {
|
|
818
803
|
const classNameMap = {
|
|
819
804
|
Task: 'TaskModel',
|
package/dist/ModelRegistry.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ModelRegistry
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* - Comprehensive error reporting
|
|
10
|
-
* - Best practices from Linear Sync Engine
|
|
2
|
+
* ModelRegistry is the source of truth for model metadata: which model classes
|
|
3
|
+
* exist, the properties and references declared on each, the back-references
|
|
4
|
+
* used for cascade handling, and a stable hash of the whole schema.
|
|
5
|
+
* {@link Model} instances resolve their metadata through the active registry,
|
|
6
|
+
* and {@link InstanceCache} uses it to map between model names and constructor
|
|
7
|
+
* classes. References resolve lazily, so a model may declare a reference to
|
|
8
|
+
* another model that is registered later.
|
|
11
9
|
*/
|
|
12
10
|
import { type ModelMetadata, type PropertyMetadata, type ReferenceMetadata, LoadStrategy } from './types/index.js';
|
|
13
11
|
import type { Model } from './Model.js';
|
|
@@ -30,7 +28,8 @@ export type ModelClassInput = new (...args: never[]) => Model;
|
|
|
30
28
|
*/
|
|
31
29
|
export type RegisteredModelClass = Omit<typeof Model, never> & ConcreteModelConstructor<Model>;
|
|
32
30
|
/**
|
|
33
|
-
*
|
|
31
|
+
* {@link ReferenceMetadata} extended with cascade behavior: what happens to a
|
|
32
|
+
* referencing model when the referenced model is deleted or archived.
|
|
34
33
|
*/
|
|
35
34
|
export interface ExtendedReferenceMetadata extends ReferenceMetadata {
|
|
36
35
|
onDelete?: 'cascade' | 'nullify' | 'restrict';
|
|
@@ -47,8 +46,9 @@ export interface SerializedReferenceMetadata extends Omit<ExtendedReferenceMetad
|
|
|
47
46
|
referencedModel: string;
|
|
48
47
|
}
|
|
49
48
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
49
|
+
* Metadata that records a child model's foreign key to a parent model, used
|
|
50
|
+
* for cascade-aware transaction handling: when the parent is deleted, the
|
|
51
|
+
* child's pending transactions can be cancelled.
|
|
52
52
|
*/
|
|
53
53
|
export interface BackReferenceMetadata {
|
|
54
54
|
/** The parent model name (e.g., 'SlideDeck') */
|
|
@@ -81,7 +81,6 @@ export declare class ModelRegistry {
|
|
|
81
81
|
private schemaHash?;
|
|
82
82
|
private config;
|
|
83
83
|
private registeredModels;
|
|
84
|
-
private batchMode;
|
|
85
84
|
private pendingHashUpdate;
|
|
86
85
|
constructor(config?: RegistryConfig);
|
|
87
86
|
private validateModelConstructor;
|
|
@@ -102,13 +101,14 @@ export declare class ModelRegistry {
|
|
|
102
101
|
*/
|
|
103
102
|
registerReference(modelName: string, propertyName: string, metadata: ExtendedReferenceMetadata): void;
|
|
104
103
|
/**
|
|
105
|
-
*
|
|
104
|
+
* Register a back-reference for cascade-aware transaction handling.
|
|
106
105
|
*
|
|
107
|
-
* When a parent model is deleted, the
|
|
108
|
-
* transactions for
|
|
106
|
+
* When a parent model is deleted, the transaction queue cancels pending
|
|
107
|
+
* transactions for every child model that declares a back-reference to that
|
|
108
|
+
* parent.
|
|
109
109
|
*
|
|
110
|
-
* @param childModelName - The model that
|
|
111
|
-
* @param metadata -
|
|
110
|
+
* @param childModelName - The model that holds a foreign key to the parent (e.g., 'Slide')
|
|
111
|
+
* @param metadata - The back-reference configuration
|
|
112
112
|
*/
|
|
113
113
|
registerBackReference(childModelName: string, metadata: BackReferenceMetadata): void;
|
|
114
114
|
/** Get all models with specific load strategy. */
|
|
@@ -141,7 +141,9 @@ export declare class ModelRegistry {
|
|
|
141
141
|
foreignKey: string;
|
|
142
142
|
}[];
|
|
143
143
|
/**
|
|
144
|
-
*
|
|
144
|
+
* Compute a stable hash of the registered schema — model names, property
|
|
145
|
+
* types, and their indexed and optional flags. Memoized until the schema
|
|
146
|
+
* changes.
|
|
145
147
|
*/
|
|
146
148
|
getSchemaHash(): string;
|
|
147
149
|
/**
|
package/dist/ModelRegistry.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ModelRegistry
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* - Comprehensive error reporting
|
|
10
|
-
* - Best practices from Linear Sync Engine
|
|
2
|
+
* ModelRegistry is the source of truth for model metadata: which model classes
|
|
3
|
+
* exist, the properties and references declared on each, the back-references
|
|
4
|
+
* used for cascade handling, and a stable hash of the whole schema.
|
|
5
|
+
* {@link Model} instances resolve their metadata through the active registry,
|
|
6
|
+
* and {@link InstanceCache} uses it to map between model names and constructor
|
|
7
|
+
* classes. References resolve lazily, so a model may declare a reference to
|
|
8
|
+
* another model that is registered later.
|
|
11
9
|
*/
|
|
12
10
|
// Removed Node.js crypto import for browser compatibility
|
|
13
11
|
import { PropertyType, LoadStrategy, } from './types/index.js';
|
|
@@ -43,19 +41,17 @@ export class ModelRegistry {
|
|
|
43
41
|
properties = new Map();
|
|
44
42
|
references = new Map();
|
|
45
43
|
pendingReferences = new Map();
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
44
|
+
// Maps a constructor back to its model name. Keyed as `unknown` on purpose:
|
|
45
|
+
// lookups arrive both as `this.constructor` (a Function) and as typed model
|
|
46
|
+
// classes, and both are accepted without a cast.
|
|
49
47
|
constructorToModelName = new Map();
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
// is derived on demand by `getChildModels`, populated only here.
|
|
48
|
+
// Back-references for cascade-aware transaction handling. Maps a child model
|
|
49
|
+
// name to the parent models it references. The inverse direction (parent to
|
|
50
|
+
// children) is derived on demand by `getChildModels`; it is populated here.
|
|
54
51
|
backReferences = new Map();
|
|
55
52
|
schemaHash;
|
|
56
53
|
config;
|
|
57
54
|
registeredModels = new Set();
|
|
58
|
-
batchMode = false;
|
|
59
55
|
pendingHashUpdate = false;
|
|
60
56
|
constructor(config = {}) {
|
|
61
57
|
this.config = {
|
|
@@ -169,7 +165,7 @@ export class ModelRegistry {
|
|
|
169
165
|
const modelClass = constructor;
|
|
170
166
|
this.models.set(name, modelClass);
|
|
171
167
|
this.modelMetadata.set(name, metadata);
|
|
172
|
-
//
|
|
168
|
+
// Record the reverse mapping from constructor to model name
|
|
173
169
|
this.constructorToModelName.set(constructor, name);
|
|
174
170
|
// Initialize property maps
|
|
175
171
|
if (!this.properties.has(name)) {
|
|
@@ -246,13 +242,14 @@ export class ModelRegistry {
|
|
|
246
242
|
this.completeReferenceRegistration(modelName, propertyName, metadata);
|
|
247
243
|
}
|
|
248
244
|
/**
|
|
249
|
-
*
|
|
245
|
+
* Register a back-reference for cascade-aware transaction handling.
|
|
250
246
|
*
|
|
251
|
-
* When a parent model is deleted, the
|
|
252
|
-
* transactions for
|
|
247
|
+
* When a parent model is deleted, the transaction queue cancels pending
|
|
248
|
+
* transactions for every child model that declares a back-reference to that
|
|
249
|
+
* parent.
|
|
253
250
|
*
|
|
254
|
-
* @param childModelName - The model that
|
|
255
|
-
* @param metadata -
|
|
251
|
+
* @param childModelName - The model that holds a foreign key to the parent (e.g., 'Slide')
|
|
252
|
+
* @param metadata - The back-reference configuration
|
|
256
253
|
*/
|
|
257
254
|
registerBackReference(childModelName, metadata) {
|
|
258
255
|
// Add to instance map
|
|
@@ -345,7 +342,9 @@ export class ModelRegistry {
|
|
|
345
342
|
return children;
|
|
346
343
|
}
|
|
347
344
|
/**
|
|
348
|
-
*
|
|
345
|
+
* Compute a stable hash of the registered schema — model names, property
|
|
346
|
+
* types, and their indexed and optional flags. Memoized until the schema
|
|
347
|
+
* changes.
|
|
349
348
|
*/
|
|
350
349
|
getSchemaHash() {
|
|
351
350
|
if (this.schemaHash)
|
|
@@ -428,7 +427,6 @@ export class ModelRegistry {
|
|
|
428
427
|
* Start batch registration mode to optimize performance
|
|
429
428
|
*/
|
|
430
429
|
startBatch() {
|
|
431
|
-
this.batchMode = true;
|
|
432
430
|
this.pendingHashUpdate = false;
|
|
433
431
|
}
|
|
434
432
|
/**
|
|
@@ -438,7 +436,6 @@ export class ModelRegistry {
|
|
|
438
436
|
* End batch registration mode and update schema hash if needed
|
|
439
437
|
*/
|
|
440
438
|
endBatch() {
|
|
441
|
-
this.batchMode = false;
|
|
442
439
|
if (this.pendingHashUpdate) {
|
|
443
440
|
this.getSchemaHash(); // This will recalculate if needed
|
|
444
441
|
this.pendingHashUpdate = false;
|
|
@@ -460,7 +457,6 @@ export class ModelRegistry {
|
|
|
460
457
|
this.backReferences.clear();
|
|
461
458
|
this.constructorToModelName.clear();
|
|
462
459
|
this.schemaHash = undefined;
|
|
463
|
-
this.batchMode = false;
|
|
464
460
|
this.pendingHashUpdate = false;
|
|
465
461
|
getContext().logger.info('ModelRegistry cleared');
|
|
466
462
|
}
|
package/dist/NetworkMonitor.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* NetworkMonitor
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the
|
|
7
|
-
* The visibility handler detects this and emits 'online' to trigger recovery.
|
|
2
|
+
* NetworkMonitor tracks network connectivity and reports it through events.
|
|
3
|
+
* It listens to the browser's online and offline events, and it also watches
|
|
4
|
+
* for a tab becoming visible again: after a laptop sleep/wake or a long spell
|
|
5
|
+
* in the background, the WebSocket can die silently without an offline event
|
|
6
|
+
* firing, so returning to the tab emits a recovery signal the store can act on.
|
|
8
7
|
*/
|
|
9
8
|
import { EventEmitter } from 'events';
|
|
10
9
|
export declare class NetworkMonitor extends EventEmitter {
|
package/dist/NetworkMonitor.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* NetworkMonitor
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the
|
|
7
|
-
* The visibility handler detects this and emits 'online' to trigger recovery.
|
|
2
|
+
* NetworkMonitor tracks network connectivity and reports it through events.
|
|
3
|
+
* It listens to the browser's online and offline events, and it also watches
|
|
4
|
+
* for a tab becoming visible again: after a laptop sleep/wake or a long spell
|
|
5
|
+
* in the background, the WebSocket can die silently without an offline event
|
|
6
|
+
* firing, so returning to the tab emits a recovery signal the store can act on.
|
|
8
7
|
*/
|
|
9
8
|
import { EventEmitter } from 'events';
|
|
10
9
|
import { getContext } from './context.js';
|