@abloatai/ablo 0.34.1 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -1
- package/CHANGELOG.md +758 -5
- package/README.md +56 -502
- package/bin/ablo.cjs +39 -0
- package/dist/BaseSyncedStore.d.ts +176 -48
- package/dist/BaseSyncedStore.js +346 -214
- package/dist/Database.d.ts +17 -44
- package/dist/Database.js +96 -79
- package/dist/InstanceCache.d.ts +31 -6
- package/dist/InstanceCache.js +65 -30
- package/dist/LazyReferenceCollection.d.ts +3 -3
- package/dist/LazyReferenceCollection.js +4 -4
- package/dist/Model.d.ts +23 -13
- package/dist/Model.js +27 -17
- package/dist/ModelRegistry.d.ts +8 -4
- package/dist/ModelRegistry.js +20 -18
- package/dist/NetworkMonitor.d.ts +3 -1
- package/dist/NetworkMonitor.js +7 -5
- package/dist/{SyncEngineContext.d.ts → RuntimeContext.d.ts} +20 -13
- package/dist/{SyncEngineContext.js → RuntimeContext.js} +11 -12
- package/dist/SyncClient.d.ts +47 -47
- package/dist/SyncClient.js +215 -156
- package/dist/ai-sdk/coordinatedTool.d.ts +2 -2
- package/dist/ai-sdk/coordinatedTool.js +1 -1
- package/dist/ai-sdk/coordinationContext.d.ts +2 -2
- package/dist/ai-sdk/coordinationContext.js +1 -1
- package/dist/ai-sdk/wrap.d.ts +3 -3
- package/dist/ai-sdk/wrap.js +2 -2
- package/dist/auth/index.d.ts +1 -156
- package/dist/auth/index.js +8 -301
- package/dist/client/Ablo.d.ts +42 -287
- package/dist/client/Ablo.js +129 -963
- package/dist/client/abloClient.d.ts +309 -0
- package/dist/client/abloClient.js +13 -0
- package/dist/client/clientPrelude.d.ts +52 -0
- package/dist/client/clientPrelude.js +60 -0
- package/dist/client/consoleLogger.d.ts +2 -2
- package/dist/client/coreClient.d.ts +60 -0
- package/dist/client/coreClient.js +118 -0
- package/dist/client/createInternalComponents.d.ts +8 -4
- package/dist/client/createInternalComponents.js +17 -10
- package/dist/client/createModelProxy.d.ts +98 -373
- package/dist/client/createModelProxy.js +233 -139
- package/dist/client/humans.d.ts +69 -0
- package/dist/client/humans.js +78 -0
- package/dist/client/modelRegistration.d.ts +1 -1
- package/dist/client/modelRegistration.js +9 -9
- package/dist/client/options.d.ts +73 -17
- package/dist/client/reactiveEngine.d.ts +53 -0
- package/dist/client/reactiveEngine.js +688 -0
- package/dist/client/resourceTypes.d.ts +9 -250
- package/dist/client/resourceTypes.js +8 -5
- package/dist/client/schemaConfig.d.ts +4 -4
- package/dist/client/schemaConfig.js +6 -2
- package/dist/client/storeCluster.d.ts +47 -0
- package/dist/client/storeCluster.js +118 -0
- package/dist/client/storeLifecycle.d.ts +61 -0
- package/dist/client/storeLifecycle.js +231 -0
- package/dist/client/validateAbloOptions.d.ts +3 -2
- package/dist/client/validateAbloOptions.js +1 -1
- package/dist/client/wsMutationExecutor.d.ts +3 -3
- package/dist/client/wsMutationExecutor.js +3 -3
- package/dist/context.d.ts +22 -9
- package/dist/context.js +33 -9
- package/dist/coordination/ClaimLog.d.ts +26 -0
- package/dist/coordination/ClaimLog.js +32 -0
- package/dist/coordination/index.d.ts +1 -15
- package/dist/coordination/index.js +8 -31
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +2 -2
- package/dist/docs/catalog.d.ts +72 -0
- package/dist/docs/catalog.js +230 -0
- package/dist/docs/index.d.ts +10 -0
- package/dist/docs/index.js +10 -0
- package/dist/environment.d.ts +1 -40
- package/dist/environment.js +8 -37
- package/dist/index.d.ts +44 -36
- package/dist/index.js +30 -22
- package/dist/interfaces/index.d.ts +44 -134
- package/dist/keys/index.d.ts +1 -77
- package/dist/keys/index.js +8 -190
- package/dist/mutators/{RecordingTransaction.d.ts → RecordingMutation.d.ts} +4 -4
- package/dist/mutators/{RecordingTransaction.js → RecordingMutation.js} +2 -2
- package/dist/mutators/Transaction.d.ts +1 -1
- package/dist/mutators/Transaction.js +1 -1
- package/dist/mutators/UndoManager.d.ts +6 -6
- package/dist/mutators/UndoManager.js +5 -5
- package/dist/mutators/defineMutators.d.ts +3 -3
- package/dist/mutators/defineMutators.js +1 -1
- package/dist/mutators/inverseOp.js +2 -2
- package/dist/mutators/mutateActions.d.ts +3 -3
- package/dist/mutators/mutateActions.js +1 -1
- package/dist/mutators/readerActions.d.ts +1 -1
- package/dist/mutators/undoApply.d.ts +1 -1
- package/dist/mutators/undoApply.js +1 -1
- package/dist/policy/index.d.ts +2 -2
- package/dist/policy/index.js +1 -1
- package/dist/query/client.d.ts +5 -2
- package/dist/query/client.js +10 -9
- package/dist/query/types.d.ts +6 -41
- package/dist/query/types.js +2 -2
- package/dist/react/AbloProvider.d.ts +18 -8
- package/dist/react/AbloProvider.js +10 -9
- package/dist/react/context.d.ts +3 -3
- package/dist/react/context.js +1 -1
- package/dist/react/createAbloReact.d.ts +56 -0
- package/dist/react/createAbloReact.js +51 -0
- package/dist/react/index.d.ts +6 -5
- package/dist/react/index.js +6 -3
- package/dist/react/internalContext.d.ts +1 -1
- package/dist/react/useAblo.d.ts +12 -5
- package/dist/react/useAblo.js +26 -8
- package/dist/react/useCurrentUserId.js +1 -1
- package/dist/react/useErrorListener.js +1 -1
- package/dist/react/useMutationFailureListener.d.ts +2 -2
- package/dist/react/useMutationFailureListener.js +1 -1
- package/dist/react/useMutators.d.ts +3 -3
- package/dist/react/useMutators.js +3 -3
- package/dist/react/useUndoScope.d.ts +5 -5
- package/dist/react/useUndoScope.js +1 -1
- package/dist/schema/coordination.d.ts +69 -10
- package/dist/schema/coordination.js +90 -9
- package/dist/schema/ddl.js +2 -2
- package/dist/schema/diff.d.ts +1 -1
- package/dist/schema/generate.js +1 -1
- package/dist/schema/index.d.ts +11 -10
- package/dist/schema/index.js +22 -18
- package/dist/schema/queries.d.ts +27 -27
- package/dist/schema/queries.js +23 -23
- package/dist/schema/select.d.ts +3 -3
- package/dist/schema/select.js +6 -3
- package/dist/schema/serialize.d.ts +15 -6
- package/dist/schema/serialize.js +20 -3
- package/dist/schema/sugar.d.ts +6 -7
- package/dist/schema/sugar.js +9 -12
- package/dist/schema/syncDeltaRow.d.ts +4 -152
- package/dist/schema/syncDeltaRow.js +4 -105
- package/dist/server/adapter.d.ts +18 -1
- package/dist/server/commit.d.ts +10 -16
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/readConfig.d.ts +1 -1
- package/dist/source/adapter.d.ts +7 -5
- package/dist/source/adapter.js +7 -5
- package/dist/source/adapters/drizzle.d.ts +1 -1
- package/dist/source/adapters/drizzle.js +2 -2
- package/dist/source/adapters/kysely.d.ts +1 -1
- package/dist/source/adapters/kysely.js +1 -1
- package/dist/source/adapters/kyselyMutationCore.d.ts +1 -1
- package/dist/source/adapters/kyselyMutationCore.js +2 -2
- package/dist/source/adapters/memory.js +1 -1
- package/dist/source/adapters/prisma.d.ts +8 -3
- package/dist/source/adapters/prisma.js +1 -1
- package/dist/source/connector.js +1 -1
- package/dist/source/connectorProtocol.d.ts +2 -8
- package/dist/source/connectorProtocol.js +3 -2
- package/dist/source/contract.d.ts +29 -17
- package/dist/source/contract.js +27 -22
- package/dist/source/factory.d.ts +1 -1
- package/dist/source/idempotency.js +2 -2
- package/dist/source/index.d.ts +1 -0
- package/dist/source/index.js +3 -0
- package/dist/source/next.d.ts +1 -1
- package/dist/source/signing.d.ts +9 -2
- package/dist/source/signing.js +4 -1
- package/dist/source/types.d.ts +6 -4
- package/dist/source/types.js +1 -1
- package/dist/{core/storeContract.d.ts → storeContract.d.ts} +6 -6
- package/dist/{core → stores}/DatabaseManager.d.ts +3 -1
- package/dist/{core → stores}/DatabaseManager.js +14 -13
- package/dist/stores/ObjectStore.d.ts +1 -1
- package/dist/{core → stores}/StoreManager.d.ts +9 -26
- package/dist/{core → stores}/StoreManager.js +29 -77
- package/dist/stores/SyncActionStore.d.ts +4 -2
- package/dist/stores/SyncActionStore.js +11 -17
- package/dist/stores/syncAction.d.ts +26 -0
- package/dist/stores/syncAction.js +16 -0
- package/dist/surface.d.ts +3 -3
- package/dist/surface.js +6 -4
- package/dist/sync/BootstrapFetcher.d.ts +127 -6
- package/dist/sync/BootstrapFetcher.js +511 -83
- package/dist/sync/ConnectionManager.d.ts +6 -198
- package/dist/sync/ConnectionManager.js +6 -677
- package/dist/sync/OnDemandLoader.d.ts +5 -2
- package/dist/sync/OnDemandLoader.js +61 -21
- package/dist/sync/SubscriptionManager.d.ts +13 -2
- package/dist/sync/SubscriptionManager.js +23 -5
- package/dist/sync/SyncWebSocket.d.ts +27 -510
- package/dist/sync/SyncWebSocket.js +76 -954
- package/dist/sync/awaitClaimGrant.d.ts +4 -44
- package/dist/sync/awaitClaimGrant.js +4 -109
- package/dist/sync/bootstrapApply.d.ts +3 -0
- package/dist/sync/bootstrapApply.js +2 -2
- package/dist/sync/commitFrames.d.ts +6 -40
- package/dist/sync/commitFrames.js +6 -97
- package/dist/sync/contextPorts.d.ts +18 -0
- package/dist/sync/contextPorts.js +31 -0
- package/dist/sync/createClaimStream.d.ts +5 -49
- package/dist/sync/createClaimStream.js +5 -469
- package/dist/sync/createPresenceStream.d.ts +26 -4
- package/dist/sync/createPresenceStream.js +28 -20
- package/dist/sync/createSnapshot.d.ts +2 -2
- package/dist/sync/createSnapshot.js +1 -1
- package/dist/sync/credentialLifecycle.d.ts +5 -173
- package/dist/sync/credentialLifecycle.js +5 -320
- package/dist/sync/deltaPipeline.d.ts +13 -12
- package/dist/sync/deltaPipeline.js +21 -4
- package/dist/sync/groupChange.d.ts +3 -0
- package/dist/sync/groupChange.js +16 -14
- package/dist/sync/participants.d.ts +24 -6
- package/dist/sync/participants.js +32 -23
- package/dist/sync/schemaDrift.d.ts +55 -0
- package/dist/sync/schemaDrift.js +53 -0
- package/dist/sync/schemas.d.ts +23 -33
- package/dist/sync/schemas.js +29 -20
- package/dist/sync/syncPlan.d.ts +3 -3
- package/dist/sync/wsFrameHandlers.d.ts +6 -114
- package/dist/sync/wsFrameHandlers.js +6 -392
- package/dist/syncLog/contract.d.ts +20 -0
- package/dist/syncLog/contract.js +19 -0
- package/dist/syncLog/index.d.ts +1 -0
- package/dist/syncLog/index.js +1 -0
- package/dist/transaction/ablo.d.ts +88 -0
- package/dist/transaction/ablo.js +33 -0
- package/dist/{client/auth.d.ts → transaction/auth/apiKey.d.ts} +43 -8
- package/dist/{client/auth.js → transaction/auth/apiKey.js} +19 -0
- package/dist/transaction/auth/bootstrapScope.d.ts +15 -0
- package/dist/transaction/auth/bootstrapScope.js +1 -0
- package/dist/transaction/auth/capability.d.ts +212 -0
- package/dist/transaction/auth/capability.js +224 -0
- package/dist/{auth → transaction/auth}/credentialSource.d.ts +8 -1
- package/dist/{client → transaction/auth}/identity.d.ts +8 -7
- package/dist/{client → transaction/auth}/identity.js +1 -1
- package/dist/transaction/auth/index.d.ts +162 -0
- package/dist/transaction/auth/index.js +304 -0
- package/dist/{auth → transaction/auth}/schemas.d.ts +1 -1
- package/dist/{auth → transaction/auth}/schemas.js +13 -13
- package/dist/{client → transaction/auth}/sessionMint.d.ts +8 -8
- package/dist/{client → transaction/auth}/sessionMint.js +4 -7
- package/dist/transaction/coordination/awaitClaimGrant.d.ts +56 -0
- package/dist/transaction/coordination/awaitClaimGrant.js +124 -0
- package/dist/{client → transaction/coordination}/claimHeartbeatLoop.d.ts +34 -0
- package/dist/{client → transaction/coordination}/claimHeartbeatLoop.js +20 -0
- package/dist/transaction/coordination/claimMeta.d.ts +49 -0
- package/dist/transaction/coordination/claimMeta.js +52 -0
- package/dist/transaction/coordination/createClaimStream.d.ts +64 -0
- package/dist/transaction/coordination/createClaimStream.js +475 -0
- package/dist/transaction/coordination/events.d.ts +74 -0
- package/dist/transaction/coordination/events.js +7 -0
- package/dist/transaction/coordination/index.d.ts +19 -0
- package/dist/transaction/coordination/index.js +45 -0
- package/dist/transaction/coordination/locator.d.ts +104 -0
- package/dist/transaction/coordination/locator.js +102 -0
- package/dist/transaction/coordination/schema.d.ts +1536 -0
- package/dist/transaction/coordination/schema.js +1177 -0
- package/dist/transaction/coordination/targetConflict.d.ts +2 -0
- package/dist/transaction/coordination/targetConflict.js +107 -0
- package/dist/{coordination → transaction/coordination}/trace.d.ts +7 -18
- package/dist/{coordination → transaction/coordination}/trace.js +18 -25
- package/dist/transaction/durableWrites.d.ts +62 -0
- package/dist/{client → transaction}/durableWrites.js +28 -3
- package/dist/transaction/environment.d.ts +105 -0
- package/dist/transaction/environment.js +108 -0
- package/dist/{errorCodes.d.ts → transaction/errorCodes.d.ts} +12 -12
- package/dist/{errorCodes.js → transaction/errorCodes.js} +45 -18
- package/dist/{errors.d.ts → transaction/errors.d.ts} +37 -13
- package/dist/{errors.js → transaction/errors.js} +85 -16
- package/dist/transaction/footprint.d.ts +111 -0
- package/dist/transaction/footprint.js +0 -0
- package/dist/transaction/index.d.ts +20 -0
- package/dist/transaction/index.js +20 -0
- package/dist/transaction/keys/index.d.ts +87 -0
- package/dist/transaction/keys/index.js +207 -0
- package/dist/transaction/log/syncDeltaRow.d.ts +158 -0
- package/dist/transaction/log/syncDeltaRow.js +95 -0
- package/dist/{sync/syncPosition.d.ts → transaction/logPosition.d.ts} +22 -8
- package/dist/{sync/syncPosition.js → transaction/logPosition.js} +15 -6
- package/dist/transaction/logger.d.ts +16 -0
- package/dist/transaction/logger.js +7 -0
- package/dist/transaction/observability.d.ts +53 -0
- package/dist/transaction/observability.js +19 -0
- package/dist/transaction/plugin.d.ts +285 -0
- package/dist/transaction/plugin.js +106 -0
- package/dist/{policy → transaction/policy}/types.d.ts +3 -3
- package/dist/{policy → transaction/policy}/types.js +2 -0
- package/dist/transaction/resources/httpResources.d.ts +321 -0
- package/dist/transaction/resources/httpResources.js +7 -0
- package/dist/transaction/resources/modelOperations.d.ts +427 -0
- package/dist/transaction/resources/modelOperations.js +12 -0
- package/dist/transaction/resources/mutationOptions.d.ts +66 -0
- package/dist/transaction/resources/mutationOptions.js +9 -0
- package/dist/transaction/resources/where.d.ts +101 -0
- package/dist/transaction/resources/where.js +115 -0
- package/dist/{client → transaction/resources}/writeOptionsSchema.d.ts +2 -6
- package/dist/{client → transaction/resources}/writeOptionsSchema.js +9 -5
- package/dist/{schema → transaction/schema}/field.d.ts +17 -23
- package/dist/{schema → transaction/schema}/field.js +5 -5
- package/dist/transaction/schema/fieldRef.d.ts +38 -0
- package/dist/transaction/schema/fieldRef.js +11 -0
- package/dist/transaction/schema/loadStrategy.d.ts +45 -0
- package/dist/transaction/schema/loadStrategy.js +46 -0
- package/dist/{schema → transaction/schema}/model.d.ts +50 -35
- package/dist/{schema → transaction/schema}/model.js +30 -20
- package/dist/transaction/schema/openapi.d.ts +58 -0
- package/dist/transaction/schema/openapi.js +501 -0
- package/dist/{schema → transaction/schema}/relation.d.ts +21 -16
- package/dist/{schema → transaction/schema}/relation.js +7 -7
- package/dist/{schema → transaction/schema}/residency.d.ts +0 -9
- package/dist/{schema → transaction/schema}/residency.js +0 -5
- package/dist/{schema → transaction/schema}/roles.d.ts +5 -5
- package/dist/{schema → transaction/schema}/roles.js +5 -5
- package/dist/{schema → transaction/schema}/schema.d.ts +39 -10
- package/dist/{schema → transaction/schema}/schema.js +24 -3
- package/dist/{schema → transaction/schema}/tenancy.d.ts +1 -1
- package/dist/{schema → transaction/schema}/tenancy.js +7 -4
- package/dist/transaction/transactionLayer.d.ts +82 -0
- package/dist/transaction/transactionLayer.js +24 -0
- package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.d.ts +5 -6
- package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.js +9 -13
- package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.d.ts +9 -2
- package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.js +5 -9
- package/dist/{transactions/durableWriteStore.d.ts → transaction/transactions/settlement/pendingWrite.d.ts} +11 -37
- package/dist/transaction/transactions/settlement/pendingWrite.js +20 -0
- package/dist/transaction/transport/commitFrames.d.ts +90 -0
- package/dist/transaction/transport/commitFrames.js +134 -0
- package/dist/transaction/transport/connectionManager.d.ts +215 -0
- package/dist/transaction/transport/connectionManager.js +673 -0
- package/dist/transaction/transport/credentialLifecycle.d.ts +177 -0
- package/dist/transaction/transport/credentialLifecycle.js +324 -0
- package/dist/{sync → transaction/transport}/heartbeat.d.ts +3 -1
- package/dist/{sync → transaction/transport}/heartbeat.js +6 -4
- package/dist/transaction/transport/httpClient.d.ts +131 -0
- package/dist/{client → transaction/transport}/httpClient.js +6 -5
- package/dist/transaction/transport/httpOptions.d.ts +33 -0
- package/dist/transaction/transport/httpOptions.js +12 -0
- package/dist/{client → transaction/transport}/httpTransport.js +295 -97
- package/dist/{sync/NetworkProbe.d.ts → transaction/transport/networkProbe.d.ts} +7 -4
- package/dist/{sync/NetworkProbe.js → transaction/transport/networkProbe.js} +14 -13
- package/dist/transaction/transport/wsFrameHandlers.d.ts +128 -0
- package/dist/transaction/transport/wsFrameHandlers.js +429 -0
- package/dist/transaction/transport/wsTransport.d.ts +574 -0
- package/dist/transaction/transport/wsTransport.js +1023 -0
- package/dist/transaction/types/assertExact.d.ts +17 -0
- package/dist/transaction/types/assertExact.js +1 -0
- package/dist/{types → transaction/types}/global.d.ts +17 -2
- package/dist/{types → transaction/types}/global.js +2 -1
- package/dist/{types → transaction/types}/index.d.ts +14 -46
- package/dist/{types → transaction/types}/index.js +7 -16
- package/dist/{types → transaction/types}/streams.d.ts +73 -45
- package/dist/transaction/utils/duration.d.ts +50 -0
- package/dist/{utils → transaction/utils}/duration.js +32 -0
- package/dist/{utils → transaction/utils}/json.d.ts +18 -0
- package/dist/transaction/utils/json.js +276 -0
- package/dist/transaction/wire/accountResponses.d.ts +420 -0
- package/dist/transaction/wire/accountResponses.js +290 -0
- package/dist/transaction/wire/auth.d.ts +56 -0
- package/dist/transaction/wire/auth.js +63 -0
- package/dist/transaction/wire/claimEvent.d.ts +76 -0
- package/dist/transaction/wire/claimEvent.js +73 -0
- package/dist/transaction/wire/claims.d.ts +530 -0
- package/dist/transaction/wire/claims.js +327 -0
- package/dist/{wire → transaction/wire}/commit.d.ts +125 -193
- package/dist/{wire → transaction/wire}/commit.js +68 -47
- package/dist/{wire → transaction/wire}/delta.d.ts +66 -17
- package/dist/{wire → transaction/wire}/delta.js +37 -13
- package/dist/transaction/wire/errorEnvelope.d.ts +72 -0
- package/dist/{wire → transaction/wire}/errorEnvelope.js +36 -5
- package/dist/transaction/wire/feedCursor.d.ts +60 -0
- package/dist/transaction/wire/feedCursor.js +82 -0
- package/dist/transaction/wire/feedEvent.d.ts +204 -0
- package/dist/transaction/wire/feedEvent.js +65 -0
- package/dist/transaction/wire/frames.d.ts +194 -0
- package/dist/transaction/wire/frames.js +50 -0
- package/dist/transaction/wire/inboundFrames.d.ts +562 -0
- package/dist/transaction/wire/inboundFrames.js +116 -0
- package/dist/transaction/wire/index.d.ts +54 -0
- package/dist/transaction/wire/index.js +83 -0
- package/dist/{wire → transaction/wire}/listEnvelope.d.ts +13 -14
- package/dist/transaction/wire/listEnvelope.js +42 -0
- package/dist/transaction/wire/modelMutations.d.ts +31 -0
- package/dist/transaction/wire/modelMutations.js +52 -0
- package/dist/transaction/wire/modelResponses.d.ts +85 -0
- package/dist/transaction/wire/modelResponses.js +43 -0
- package/dist/transaction/wire/modelShape.d.ts +78 -0
- package/dist/transaction/wire/modelShape.js +74 -0
- package/dist/transactions/{TransactionQueue.d.ts → mutations/MutationQueue.d.ts} +85 -38
- package/dist/transactions/{TransactionQueue.js → mutations/MutationQueue.js} +141 -80
- package/dist/transactions/{TransactionStore.d.ts → mutations/MutationStore.d.ts} +8 -8
- package/dist/transactions/{TransactionStore.js → mutations/MutationStore.js} +2 -2
- package/dist/transactions/{coalesceRules.d.ts → mutations/coalesceRules.d.ts} +10 -10
- package/dist/transactions/{coalesceRules.js → mutations/coalesceRules.js} +1 -1
- package/dist/transactions/mutations/commitLatency.d.ts +52 -0
- package/dist/transactions/mutations/commitLatency.js +130 -0
- package/dist/transactions/{commitOutboxStore.d.ts → mutations/commitOutboxStore.d.ts} +1 -5
- package/dist/transactions/{commitOutboxStore.js → mutations/commitOutboxStore.js} +1 -1
- package/dist/transactions/{commitPayload.d.ts → mutations/commitPayload.d.ts} +18 -16
- package/dist/transactions/{commitPayload.js → mutations/commitPayload.js} +15 -15
- package/dist/transactions/{deltaConfirmation.d.ts → mutations/deltaConfirmation.d.ts} +15 -11
- package/dist/transactions/{deltaConfirmation.js → mutations/deltaConfirmation.js} +14 -12
- package/dist/transactions/mutations/durableWriteStore.d.ts +14 -0
- package/dist/transactions/mutations/durableWriteStore.js +12 -0
- package/dist/transactions/{optimisticApply.d.ts → mutations/optimisticApply.d.ts} +7 -7
- package/dist/transactions/{replayValidation.d.ts → mutations/replayValidation.d.ts} +4 -3
- package/dist/transactions/{replayValidation.js → mutations/replayValidation.js} +7 -5
- package/dist/utils/mobxSetup.d.ts +1 -1
- package/dist/utils/mobxSetup.js +5 -2
- package/dist/{core → views}/QueryView.d.ts +2 -2
- package/dist/{core → views}/QueryView.js +2 -2
- package/dist/{core → views}/ViewRegistry.d.ts +1 -1
- package/dist/{core/queryUtils.d.ts → views/incrementalView.d.ts} +6 -6
- package/dist/{core/queryUtils.js → views/incrementalView.js} +6 -6
- package/dist/webhooks/events.d.ts +2 -2
- package/dist/wire/index.d.ts +1 -34
- package/dist/wire/index.js +8 -49
- package/docs/agent-messaging.md +3 -3
- package/docs/agents.md +20 -13
- package/docs/api-keys.md +14 -10
- package/docs/api.md +27 -61
- package/docs/audit.md +6 -3
- package/docs/cli.md +41 -13
- package/docs/client-behavior.md +11 -9
- package/docs/concurrency-convention.md +49 -57
- package/docs/coordination.md +283 -121
- package/docs/data-sources.md +7 -5
- package/docs/debugging.md +39 -15
- package/docs/deployment.md +267 -0
- package/docs/examples/agent-human.md +49 -42
- package/docs/examples/ai-sdk-tool.md +69 -44
- package/docs/examples/existing-python-backend.md +8 -6
- package/docs/examples/nextjs.md +129 -47
- package/docs/examples/scoped-agent.md +46 -45
- package/docs/examples/server-agent.md +46 -26
- package/docs/groups.md +87 -30
- package/docs/guarantees.md +41 -12
- package/docs/how-it-works.md +38 -12
- package/docs/idempotency.md +126 -0
- package/docs/identity.md +77 -74
- package/docs/index.md +172 -86
- package/docs/integration-guide.md +31 -19
- package/docs/mcp.md +46 -21
- package/docs/migration.md +95 -18
- package/docs/operating-on-your-database.md +3 -1
- package/docs/projects.md +3 -1
- package/docs/quickstart.md +22 -5
- package/docs/react.md +31 -18
- package/docs/schema-contract.md +5 -3
- package/docs/session-settings.md +108 -0
- package/docs/sessions.md +4 -2
- package/docs/webhooks.md +12 -10
- package/llms.txt +48 -18
- package/package.json +21 -26
- package/dist/agent/Agent.d.ts +0 -366
- package/dist/agent/Agent.js +0 -514
- package/dist/agent/index.d.ts +0 -115
- package/dist/agent/index.js +0 -128
- package/dist/agent/session.d.ts +0 -93
- package/dist/agent/session.js +0 -149
- package/dist/agent/types.d.ts +0 -68
- package/dist/agent/types.js +0 -9
- package/dist/cli.cjs +0 -286329
- package/dist/client/durableWrites.d.ts +0 -21
- package/dist/client/httpClient.d.ts +0 -80
- package/dist/coordination/schema.d.ts +0 -722
- package/dist/coordination/schema.js +0 -578
- package/dist/schema/openapi.d.ts +0 -29
- package/dist/schema/openapi.js +0 -124
- package/dist/testing/fixtures/bootstrap.d.ts +0 -49
- package/dist/testing/fixtures/bootstrap.js +0 -59
- package/dist/testing/fixtures/deltas.d.ts +0 -83
- package/dist/testing/fixtures/deltas.js +0 -136
- package/dist/testing/fixtures/models.d.ts +0 -83
- package/dist/testing/fixtures/models.js +0 -272
- package/dist/testing/helpers/reactWrapper.d.ts +0 -69
- package/dist/testing/helpers/reactWrapper.js +0 -67
- package/dist/testing/helpers/syncEngineHarness.d.ts +0 -54
- package/dist/testing/helpers/syncEngineHarness.js +0 -73
- package/dist/testing/helpers/wait.d.ts +0 -30
- package/dist/testing/helpers/wait.js +0 -49
- package/dist/testing/index.d.ts +0 -23
- package/dist/testing/index.js +0 -33
- package/dist/testing/mocks/FakeDatabase.d.ts +0 -18
- package/dist/testing/mocks/FakeDatabase.js +0 -10
- package/dist/testing/mocks/MockMutationExecutor.d.ts +0 -87
- package/dist/testing/mocks/MockMutationExecutor.js +0 -192
- package/dist/testing/mocks/MockNetworkMonitor.d.ts +0 -20
- package/dist/testing/mocks/MockNetworkMonitor.js +0 -46
- package/dist/testing/mocks/MockSyncContext.d.ts +0 -51
- package/dist/testing/mocks/MockSyncContext.js +0 -71
- package/dist/testing/mocks/MockSyncStore.d.ts +0 -88
- package/dist/testing/mocks/MockSyncStore.js +0 -171
- package/dist/testing/mocks/MockWebSocket.d.ts +0 -71
- package/dist/testing/mocks/MockWebSocket.js +0 -118
- package/dist/transactions/durableWriteStore.js +0 -30
- package/dist/utils/duration.d.ts +0 -25
- package/dist/utils/json.js +0 -88
- package/dist/wire/errorEnvelope.d.ts +0 -55
- package/dist/wire/frames.d.ts +0 -197
- package/dist/wire/frames.js +0 -49
- package/dist/wire/listEnvelope.js +0 -18
- package/docs/interaction-model.md +0 -97
- /package/dist/{core → query}/QueryProcessor.d.ts +0 -0
- /package/dist/{core → query}/QueryProcessor.js +0 -0
- /package/dist/{core/storeContract.js → storeContract.js} +0 -0
- /package/dist/{core → stores}/openIDBWithTimeout.d.ts +0 -0
- /package/dist/{core → stores}/openIDBWithTimeout.js +0 -0
- /package/dist/{client → transaction/auth}/credentialEndpoint.d.ts +0 -0
- /package/dist/{client → transaction/auth}/credentialEndpoint.js +0 -0
- /package/dist/{auth → transaction/auth}/credentialPolicy.d.ts +0 -0
- /package/dist/{auth → transaction/auth}/credentialPolicy.js +0 -0
- /package/dist/{auth → transaction/auth}/credentialSource.js +0 -0
- /package/dist/{client → transaction/auth}/hostedEndpoints.d.ts +0 -0
- /package/dist/{client → transaction/auth}/hostedEndpoints.js +0 -0
- /package/dist/{client → transaction}/persistence.d.ts +0 -0
- /package/dist/{client → transaction}/persistence.js +0 -0
- /package/dist/{client → transaction/resources}/functionalUpdate.d.ts +0 -0
- /package/dist/{client → transaction/resources}/functionalUpdate.js +0 -0
- /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.d.ts +0 -0
- /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.js +0 -0
- /package/dist/{client → transaction/transport}/httpTransport.d.ts +0 -0
- /package/dist/{types → transaction/types}/modelData.d.ts +0 -0
- /package/dist/{types → transaction/types}/modelData.js +0 -0
- /package/dist/{types → transaction/types}/participant.d.ts +0 -0
- /package/dist/{types → transaction/types}/participant.js +0 -0
- /package/dist/{types → transaction/types}/streams.js +0 -0
- /package/dist/{utils → transaction/utils}/asyncIterator.d.ts +0 -0
- /package/dist/{utils → transaction/utils}/asyncIterator.js +0 -0
- /package/dist/{wire → transaction/wire}/bootstrapReason.d.ts +0 -0
- /package/dist/{wire → transaction/wire}/bootstrapReason.js +0 -0
- /package/dist/{wire → transaction/wire}/protocol.d.ts +0 -0
- /package/dist/{wire → transaction/wire}/protocol.js +0 -0
- /package/dist/{wire → transaction/wire}/protocolVersion.d.ts +0 -0
- /package/dist/{wire → transaction/wire}/protocolVersion.js +0 -0
- /package/dist/transactions/{UnconfirmedWrites.d.ts → mutations/UnconfirmedWrites.d.ts} +0 -0
- /package/dist/transactions/{UnconfirmedWrites.js → mutations/UnconfirmedWrites.js} +0 -0
- /package/dist/transactions/{optimisticApply.js → mutations/optimisticApply.js} +0 -0
- /package/dist/{core → views}/ViewRegistry.js +0 -0
package/dist/InstanceCache.js
CHANGED
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
import { makeObservable, observable, action, computed, runInAction } from 'mobx';
|
|
10
10
|
import { Model } from './Model.js';
|
|
11
11
|
import { ModelRegistry } from './ModelRegistry.js';
|
|
12
|
-
import {
|
|
13
|
-
import { AbloValidationError } from './errors.js';
|
|
14
|
-
import { ModelScope } from './types/index.js';
|
|
15
|
-
import { ViewRegistry } from './
|
|
16
|
-
import { QueryView } from './
|
|
12
|
+
import { globalRuntime } from './context.js';
|
|
13
|
+
import { AbloValidationError } from './transaction/errors.js';
|
|
14
|
+
import { ModelScope } from './transaction/types/index.js';
|
|
15
|
+
import { ViewRegistry } from './views/ViewRegistry.js';
|
|
16
|
+
import { QueryView } from './views/QueryView.js';
|
|
17
17
|
// Re-exported so `import { ModelScope } from './InstanceCache.js'` resolves
|
|
18
18
|
export { ModelScope };
|
|
19
19
|
/**
|
|
@@ -36,7 +36,7 @@ export class InstanceCache {
|
|
|
36
36
|
// reactivity source; there are no computed getters with conditional cache
|
|
37
37
|
// invalidation to get wrong.
|
|
38
38
|
// Foreign key indexes: Map<"ModelType:fieldName", Map<fieldValue, ObservableSet<modelId>>>
|
|
39
|
-
// Enables O(1) lookups like "all
|
|
39
|
+
// Enables O(1) lookups like "all Block models where sectionId = X"
|
|
40
40
|
// instead of scanning all models of a type and filtering.
|
|
41
41
|
foreignKeyIndexes = new Map();
|
|
42
42
|
// Registry of which fields to index: Map<modelName, fieldName[]>
|
|
@@ -51,6 +51,7 @@ export class InstanceCache {
|
|
|
51
51
|
};
|
|
52
52
|
// Configuration
|
|
53
53
|
config;
|
|
54
|
+
runtime;
|
|
54
55
|
gcTimer;
|
|
55
56
|
// ModelRegistry instance — single source of truth for model metadata
|
|
56
57
|
registry;
|
|
@@ -106,6 +107,7 @@ export class InstanceCache {
|
|
|
106
107
|
gcInterval: config.gcInterval ?? 60000, // 1 minute
|
|
107
108
|
useWeakRefs: config.useWeakRefs ?? true,
|
|
108
109
|
};
|
|
110
|
+
this.runtime = config.runtime ?? globalRuntime;
|
|
109
111
|
// Store the model registry reference
|
|
110
112
|
if (!modelRegistry) {
|
|
111
113
|
throw new AbloValidationError('InstanceCache requires ModelRegistry for production-safe model name lookup', { code: 'pool_registry_missing' });
|
|
@@ -187,6 +189,39 @@ export class InstanceCache {
|
|
|
187
189
|
this.metrics.hits++;
|
|
188
190
|
return model ?? undefined;
|
|
189
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Look a row up **within one model**.
|
|
194
|
+
*
|
|
195
|
+
* The pool is a single id space: `get(id)` returns whatever row carries that
|
|
196
|
+
* id, whatever model it belongs to. That is the correct storage shape — ids
|
|
197
|
+
* are globally unique, the same premise as Relay's Global Object
|
|
198
|
+
* Identification — but it means an *untyped* lookup cannot stand in for a
|
|
199
|
+
* typed one. Apollo and EmberData avoid the question by keying their identity
|
|
200
|
+
* maps on `Type:id`; with unique ids the equivalent guarantee comes from
|
|
201
|
+
* stating the expected model at the lookup instead.
|
|
202
|
+
*
|
|
203
|
+
* Returns `undefined` for a row belonging to another model: from the asking
|
|
204
|
+
* model's perspective that id is simply absent. Callers that must tell "not
|
|
205
|
+
* here" apart from "here, but another model's" should compare against
|
|
206
|
+
* {@link get}.
|
|
207
|
+
*
|
|
208
|
+
* Prefer this over `get()` anywhere the caller knows which model it wants —
|
|
209
|
+
* `get()` returning another model's row has caused three product bugs, most
|
|
210
|
+
* recently a resize gesture that reverted after every commit.
|
|
211
|
+
*/
|
|
212
|
+
// `T` appears only in the return position, which is normally a caller-chosen
|
|
213
|
+
// cast in disguise. It is sound here precisely because `modelName` is checked
|
|
214
|
+
// at runtime below before the row is handed back, so the caller's expected
|
|
215
|
+
// type and the row's registered identity cannot disagree.
|
|
216
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
217
|
+
getOfType(id, modelName) {
|
|
218
|
+
const model = this.get(id);
|
|
219
|
+
if (!model)
|
|
220
|
+
return undefined;
|
|
221
|
+
// Checked, so the assertion below is sound: `typeIndex` and
|
|
222
|
+
// `getModelName()` are the same registered-name identity.
|
|
223
|
+
return model.getModelName() === modelName ? model : undefined;
|
|
224
|
+
}
|
|
190
225
|
/**
|
|
191
226
|
* Add model with deduplication support
|
|
192
227
|
*/
|
|
@@ -231,7 +266,7 @@ export class InstanceCache {
|
|
|
231
266
|
(history.lastAction === 'U' || history.lastAction === 'D')) {
|
|
232
267
|
// Internal delta-ordering anomaly that reconciles on the next
|
|
233
268
|
// catch-up — forensic, not consumer-actionable → debug.
|
|
234
|
-
|
|
269
|
+
this.runtime.logger.debug(`InstanceCache.add() SUSPICIOUS: INSERT after ${history.lastAction}`, { modelType, id, syncId: deltaInfo.syncId });
|
|
235
270
|
}
|
|
236
271
|
}
|
|
237
272
|
// Update delta history
|
|
@@ -341,13 +376,13 @@ export class InstanceCache {
|
|
|
341
376
|
this.addToTypeIndex(id, modelType);
|
|
342
377
|
// Populate the foreign-key indexes. The single-item `add()` path
|
|
343
378
|
// does this; `addBatch()` used to skip it, which meant every
|
|
344
|
-
//
|
|
345
|
-
// loader (`
|
|
379
|
+
// block / ledger cell / message that came in through a bulk
|
|
380
|
+
// loader (`ensureReportBlocks`, `prefetchSectionBlocks`, bootstrap
|
|
346
381
|
// hydration) was in the pool but invisible to `hasMany` lookups
|
|
347
|
-
// — `
|
|
382
|
+
// — `section.blocks` returned `[]` until the user clicked a block
|
|
348
383
|
// and something else ran a non-batch `add` that happened to
|
|
349
384
|
// populate the FK index as a side effect. The UX symptom was
|
|
350
|
-
// "
|
|
385
|
+
// "sections show empty until you click on one." Adding this one
|
|
351
386
|
// line closes the gap.
|
|
352
387
|
this.addToForeignKeyIndex(id, model, modelType);
|
|
353
388
|
this.metrics.additions++;
|
|
@@ -461,7 +496,7 @@ export class InstanceCache {
|
|
|
461
496
|
// FK cleanup silently no-ops — leaving ghost ids in the FK index.
|
|
462
497
|
// That causes `getByForeignKey(..., parentId)` to report
|
|
463
498
|
// `matched > returned` (dropped-no-entry) and, on the UI, keeps the
|
|
464
|
-
// stale
|
|
499
|
+
// stale block visible until the next reload rebuilds the index
|
|
465
500
|
// from fresh data. Do the FK/type cleanup first, then delete the
|
|
466
501
|
// entry.
|
|
467
502
|
runInAction(() => {
|
|
@@ -506,7 +541,7 @@ export class InstanceCache {
|
|
|
506
541
|
// This is expected during migration from hand-coded → dynamic models.
|
|
507
542
|
}
|
|
508
543
|
catch (e) {
|
|
509
|
-
|
|
544
|
+
this.runtime.observability.breadcrumb(`Failed to create fallback instance for ${modelClass.name}`, 'sync.database', 'error', {
|
|
510
545
|
error: e instanceof Error ? e.message : String(e),
|
|
511
546
|
});
|
|
512
547
|
return [];
|
|
@@ -598,7 +633,7 @@ export class InstanceCache {
|
|
|
598
633
|
* data. Cleaner than `createFromData({ __typename, ...data })` — the
|
|
599
634
|
* typename lives in the arg list, not hidden inside the data object.
|
|
600
635
|
*
|
|
601
|
-
* Used for optimistic local writes: `pool.create('
|
|
636
|
+
* Used for optimistic local writes: `pool.create('Section', { id, reportId, ... })`.
|
|
602
637
|
* For hydration from server deltas (where `__typename` already rides on
|
|
603
638
|
* the payload), use `createFromData(data)` directly — that path is kept
|
|
604
639
|
* because the wire format attaches the discriminator to the data itself.
|
|
@@ -614,8 +649,8 @@ export class InstanceCache {
|
|
|
614
649
|
if (modelName === 'Unknown') {
|
|
615
650
|
// Malformed row with no type marker — dropped, but nothing the consumer
|
|
616
651
|
// can act on (the actionable schema-drift case is handled below) → debug.
|
|
617
|
-
|
|
618
|
-
|
|
652
|
+
this.runtime.logger.debug('InstanceCache.createFromData: No model identifier found', { data });
|
|
653
|
+
this.runtime.modelDebugLogger?.logError('Unknown', 'CREATE', 'No model identifier found', data);
|
|
619
654
|
return null;
|
|
620
655
|
}
|
|
621
656
|
if (opts?.strict) {
|
|
@@ -628,9 +663,9 @@ export class InstanceCache {
|
|
|
628
663
|
// Genuinely actionable and NOT self-healing: a model the server is sending
|
|
629
664
|
// isn't in your schema, so these rows are silently skipped. Keep at warn,
|
|
630
665
|
// consumer register (their model name + the `ablo status` fix); forensics ride debug.
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
666
|
+
this.runtime.logger.warn(`Received data for "${modelName}", which isn't in your schema — these rows will be skipped. Run \`ablo status\` to compare your local schema with the server.`);
|
|
667
|
+
this.runtime.logger.debug(`InstanceCache.createFromData: No constructor found for model "${modelName}"`, { data });
|
|
668
|
+
this.runtime.modelDebugLogger?.logError(modelName, 'CREATE', `No constructor found for model "${modelName}"`, data);
|
|
634
669
|
return null;
|
|
635
670
|
}
|
|
636
671
|
// If the model already exists, update it in place instead of creating a
|
|
@@ -643,11 +678,11 @@ export class InstanceCache {
|
|
|
643
678
|
existing.updateFromData(data);
|
|
644
679
|
return existing;
|
|
645
680
|
}
|
|
646
|
-
// Different type with same ID - this is a shared PK scenario (e.g.,
|
|
681
|
+
// Different type with same ID - this is a shared PK scenario (e.g., two models sharing one row id)
|
|
647
682
|
// Don't return existing, create new model (will use composite key for storage)
|
|
648
683
|
}
|
|
649
684
|
// Log model creation attempt
|
|
650
|
-
|
|
685
|
+
this.runtime.modelDebugLogger?.logCreation(modelName, data, Constructor);
|
|
651
686
|
try {
|
|
652
687
|
// Pass data directly to constructor for Prisma-first models
|
|
653
688
|
const model = new Constructor(data);
|
|
@@ -657,14 +692,14 @@ export class InstanceCache {
|
|
|
657
692
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
658
693
|
// Internal construction failure — captured via observability below and
|
|
659
694
|
// re-fetched on resync; the stack is forensic → debug.
|
|
660
|
-
|
|
661
|
-
|
|
695
|
+
this.runtime.logger.debug(`[InstanceCache.createFromData] FAILED ${modelName}`, { errorMessage, stack: error instanceof Error ? error.stack : undefined });
|
|
696
|
+
this.runtime.observability.captureMutationFailure({
|
|
662
697
|
context: 'createFromData',
|
|
663
698
|
modelName,
|
|
664
699
|
modelId: data.id,
|
|
665
700
|
error: errorMessage,
|
|
666
701
|
});
|
|
667
|
-
|
|
702
|
+
this.runtime.modelDebugLogger?.logError(modelName, 'CREATE', errorMessage, {
|
|
668
703
|
data,
|
|
669
704
|
constructor: Constructor.name,
|
|
670
705
|
});
|
|
@@ -849,7 +884,7 @@ export class InstanceCache {
|
|
|
849
884
|
// caused silent data loss — any model actively being rendered
|
|
850
885
|
// through a schema-driven dynamic class (i.e., most of them)
|
|
851
886
|
// would be demoted, collected, and the next render's
|
|
852
|
-
// `weakRef.deref()` returned undefined, so
|
|
887
|
+
// `weakRef.deref()` returned undefined, so blocks / cells /
|
|
853
888
|
// messages "disappeared" after ~10 min of idle.
|
|
854
889
|
//
|
|
855
890
|
// The `hasObservedCollections()` guard used by the eviction
|
|
@@ -871,7 +906,7 @@ export class InstanceCache {
|
|
|
871
906
|
}
|
|
872
907
|
}
|
|
873
908
|
if (skippedObserved > 0) {
|
|
874
|
-
|
|
909
|
+
this.runtime.logger.debug(`[InstanceCache GC] Skipped ${skippedObserved} models with active React observers`);
|
|
875
910
|
}
|
|
876
911
|
// Also clean up old tracking data
|
|
877
912
|
this.clearDeltaHistory();
|
|
@@ -934,8 +969,8 @@ export class InstanceCache {
|
|
|
934
969
|
* Register a foreign key field for indexing on a model type.
|
|
935
970
|
* Call once during app initialization (e.g., after model registration).
|
|
936
971
|
*
|
|
937
|
-
* Example: registerForeignKey('
|
|
938
|
-
* This enables getByForeignKey('
|
|
972
|
+
* Example: registerForeignKey('Block', 'sectionId')
|
|
973
|
+
* This enables getByForeignKey('Block', 'sectionId', someSectionId) → O(1) lookup
|
|
939
974
|
*/
|
|
940
975
|
registerForeignKey(modelName, fieldName) {
|
|
941
976
|
const fields = this.foreignKeyConfig.get(modelName) ?? [];
|
|
@@ -977,7 +1012,7 @@ export class InstanceCache {
|
|
|
977
1012
|
// entry for this specific parent id (entity genuinely has no
|
|
978
1013
|
// children). These used to `console.warn` diagnostic dumps on every
|
|
979
1014
|
// call, which turned into hundreds of log lines per second during
|
|
980
|
-
// cursor hover / rapid re-renders on
|
|
1015
|
+
// cursor hover / rapid re-renders on a busy page. If a caller
|
|
981
1016
|
// needs visibility into "why is this empty," wire an opt-in
|
|
982
1017
|
// `logger.debug` at the specific call site rather than re-adding
|
|
983
1018
|
// a blanket warn here.
|
|
@@ -1013,7 +1048,7 @@ export class InstanceCache {
|
|
|
1013
1048
|
// has dangling refs (legacy orphan deltas, pending CREATE
|
|
1014
1049
|
// transactions, etc.). Noisy at warn level, useful during
|
|
1015
1050
|
// investigation.
|
|
1016
|
-
|
|
1051
|
+
this.runtime.logger.debug('[InstanceCache.getByForeignKey] ROWS DROPPED', {
|
|
1017
1052
|
modelName,
|
|
1018
1053
|
fieldName,
|
|
1019
1054
|
fieldValue,
|
|
@@ -86,9 +86,9 @@ export declare class LazyReferenceCollection<T extends Model> {
|
|
|
86
86
|
* so any pool.remove invalidates the computed and re-renders the
|
|
87
87
|
* consumer with the deleted item gone.
|
|
88
88
|
*
|
|
89
|
-
* Without this, deleting a
|
|
90
|
-
* but the
|
|
91
|
-
* showing the deleted
|
|
89
|
+
* Without this, deleting a block would pool.remove() cleanly
|
|
90
|
+
* but the view — which reads `section.blocks.value` — would keep
|
|
91
|
+
* showing the deleted block until a full reload rebuilt the
|
|
92
92
|
* collection.
|
|
93
93
|
*/
|
|
94
94
|
get value(): T[];
|
|
@@ -7,7 +7,7 @@ import { makeObservable, observable, action, computed, onBecomeObserved, onBecom
|
|
|
7
7
|
import { Database } from './Database.js';
|
|
8
8
|
import { InstanceCache } from './InstanceCache.js';
|
|
9
9
|
import { getActiveRegistry } from './ModelRegistry.js';
|
|
10
|
-
import { AbloValidationError } from './errors.js';
|
|
10
|
+
import { AbloValidationError } from './transaction/errors.js';
|
|
11
11
|
/**
|
|
12
12
|
* A lazy-loaded one-to-many relationship between a parent {@link Model} and
|
|
13
13
|
* its children. It reads from the local store first and falls back to the
|
|
@@ -136,9 +136,9 @@ export class LazyReferenceCollection {
|
|
|
136
136
|
* so any pool.remove invalidates the computed and re-renders the
|
|
137
137
|
* consumer with the deleted item gone.
|
|
138
138
|
*
|
|
139
|
-
* Without this, deleting a
|
|
140
|
-
* but the
|
|
141
|
-
* showing the deleted
|
|
139
|
+
* Without this, deleting a block would pool.remove() cleanly
|
|
140
|
+
* but the view — which reads `section.blocks.value` — would keep
|
|
141
|
+
* showing the deleted block until a full reload rebuilt the
|
|
142
142
|
* collection.
|
|
143
143
|
*/
|
|
144
144
|
get value() {
|
package/dist/Model.d.ts
CHANGED
|
@@ -120,10 +120,10 @@ export declare abstract class Model {
|
|
|
120
120
|
* narrow the return to their concrete store type.
|
|
121
121
|
*
|
|
122
122
|
* @example
|
|
123
|
-
* // In a
|
|
124
|
-
* const store =
|
|
123
|
+
* // In a Section model getter
|
|
124
|
+
* const store = Section.getStore();
|
|
125
125
|
* if (!store) return [];
|
|
126
|
-
* return store.getByForeignKey<
|
|
126
|
+
* return store.getByForeignKey<Block>('Block', 'sectionId', this.id);
|
|
127
127
|
*/
|
|
128
128
|
static getStore<T extends SyncStoreRef = SyncStoreRef>(): T | null;
|
|
129
129
|
/**
|
|
@@ -159,7 +159,7 @@ export declare abstract class Model {
|
|
|
159
159
|
*
|
|
160
160
|
* This per-instance baseline is needed because application code can edit a
|
|
161
161
|
* model in two ways that coexist: a direct property write
|
|
162
|
-
* (`
|
|
162
|
+
* (`section.title = 'foo'`) and a recorded mutation. A design in which every
|
|
163
163
|
* write went through a single recorded path would not need it, since the
|
|
164
164
|
* last acknowledged state would already be the authoritative baseline.
|
|
165
165
|
*/
|
|
@@ -172,8 +172,8 @@ export declare abstract class Model {
|
|
|
172
172
|
* Capture a before-image for `keys` — the single source of truth for the
|
|
173
173
|
* "previous value" that undo inverses are built from. Both undo paths call
|
|
174
174
|
* this so they can never drift: the stream path
|
|
175
|
-
* (`
|
|
176
|
-
* (`
|
|
175
|
+
* (`MutationQueue.extractPreviousData`) and the manual-record path
|
|
176
|
+
* (`RecordingMutation.snapshotFields`).
|
|
177
177
|
*
|
|
178
178
|
* Resolution order per key:
|
|
179
179
|
* 1. `modifiedProperties.get(key).old` — first-old-wins pre-session
|
|
@@ -246,9 +246,16 @@ export declare abstract class Model {
|
|
|
246
246
|
* written, `onWrite(key, oldValue, newValue)` is invoked with the value
|
|
247
247
|
* captured immediately before assignment. `applyChanges` passes a hook
|
|
248
248
|
* that records the change in `modifiedProperties`; `updateFromData`
|
|
249
|
-
* passes none (hydration must not generate outbound mutations).
|
|
250
|
-
*
|
|
251
|
-
*
|
|
249
|
+
* passes none (hydration must not generate outbound mutations).
|
|
250
|
+
*
|
|
251
|
+
* This is not the ONLY tracking path. `mobxSetup`'s `observe()` bridge is
|
|
252
|
+
* live and forwards a DIRECT assignment (`layer.position = next`) to
|
|
253
|
+
* `propertyChanged` as well — product code writes model fields directly in
|
|
254
|
+
* plenty of places (keyboard nudge, formatting, AI tools), and those writes
|
|
255
|
+
* have to reach the server and the undo stream too. The two paths compose:
|
|
256
|
+
* a direct write establishes the first-old-wins baseline, and a later
|
|
257
|
+
* `applyChanges` carrying the value the model already holds is a no-op that
|
|
258
|
+
* leaves that baseline intact.
|
|
252
259
|
*/
|
|
253
260
|
private assignFieldsFromData;
|
|
254
261
|
/**
|
|
@@ -260,10 +267,13 @@ export declare abstract class Model {
|
|
|
260
267
|
* brand-new outbound mutation and the record would echo forever. For a
|
|
261
268
|
* local user edit, use `applyChanges` instead.
|
|
262
269
|
*
|
|
263
|
-
* Suppression
|
|
264
|
-
* clear/restore `modifiedProperties` around the
|
|
265
|
-
*
|
|
266
|
-
*
|
|
270
|
+
* Suppression takes two forms and BOTH are load-bearing: we pass no
|
|
271
|
+
* `onWrite` hook, and we clear/restore `modifiedProperties` around the
|
|
272
|
+
* assignment. The second is what catches `mobxSetup`'s `observe()` bridge,
|
|
273
|
+
* which fires on the assignment itself and would otherwise record an
|
|
274
|
+
* inbound delta as a local edit — queueing an outbound mutation that echoes
|
|
275
|
+
* forever, and putting a collaborator's change on your undo stack. Do not
|
|
276
|
+
* remove it while that bridge exists (`mobxSetup.M1`).
|
|
267
277
|
*/
|
|
268
278
|
updateFromData(data: ModelData): void;
|
|
269
279
|
/**
|
package/dist/Model.js
CHANGED
|
@@ -11,7 +11,7 @@ import { v4 as uuid } from 'uuid';
|
|
|
11
11
|
import { M1 } from './utils/mobxSetup.js';
|
|
12
12
|
import { getActiveRegistry, hasActiveRegistry } from './ModelRegistry.js';
|
|
13
13
|
import { getContext } from './context.js';
|
|
14
|
-
import { AbloValidationError } from './errors.js';
|
|
14
|
+
import { AbloValidationError } from './transaction/errors.js';
|
|
15
15
|
/**
|
|
16
16
|
* Validation error for model validation failures
|
|
17
17
|
*/
|
|
@@ -78,7 +78,7 @@ export class Model {
|
|
|
78
78
|
// A record that arrives WITH `createdAt` but WITHOUT `updatedAt` is
|
|
79
79
|
// server/IDB data whose update timestamp didn't survive the wire —
|
|
80
80
|
// falling back to "now" here fabricated an edit time for every such
|
|
81
|
-
// record on every bootstrap (the
|
|
81
|
+
// record on every bootstrap (the reports gallery sorted everything to
|
|
82
82
|
// "edited just now"). Fall back to createdAt instead; only a genuinely
|
|
83
83
|
// new local model (no dates at all) stamps the current time.
|
|
84
84
|
this.updatedAt = data.updatedAt
|
|
@@ -113,10 +113,10 @@ export class Model {
|
|
|
113
113
|
* narrow the return to their concrete store type.
|
|
114
114
|
*
|
|
115
115
|
* @example
|
|
116
|
-
* // In a
|
|
117
|
-
* const store =
|
|
116
|
+
* // In a Section model getter
|
|
117
|
+
* const store = Section.getStore();
|
|
118
118
|
* if (!store) return [];
|
|
119
|
-
* return store.getByForeignKey<
|
|
119
|
+
* return store.getByForeignKey<Block>('Block', 'sectionId', this.id);
|
|
120
120
|
*/
|
|
121
121
|
static getStore() {
|
|
122
122
|
return Model.store;
|
|
@@ -142,9 +142,9 @@ export class Model {
|
|
|
142
142
|
// Preserve the earliest captured `old` for this field until the entry
|
|
143
143
|
// is cleared (by `clearChanges` on sync-ack or by a mutator consuming
|
|
144
144
|
// it). Consecutive in-place mutations between mutator invocations —
|
|
145
|
-
// e.g. a drag loop writing `
|
|
145
|
+
// e.g. a drag loop writing `block.position = ...` on every frame —
|
|
146
146
|
// would otherwise overwrite `.old` with each frame's predecessor,
|
|
147
|
-
// destroying the pre-session baseline that `
|
|
147
|
+
// destroying the pre-session baseline that `RecordingMutation`
|
|
148
148
|
// relies on to record a correct undo inverse. `.new` always reflects
|
|
149
149
|
// the latest value so the transaction queue's `getChanges()` keeps
|
|
150
150
|
// sending the right payload to the server.
|
|
@@ -194,7 +194,7 @@ export class Model {
|
|
|
194
194
|
*
|
|
195
195
|
* This per-instance baseline is needed because application code can edit a
|
|
196
196
|
* model in two ways that coexist: a direct property write
|
|
197
|
-
* (`
|
|
197
|
+
* (`section.title = 'foo'`) and a recorded mutation. A design in which every
|
|
198
198
|
* write went through a single recorded path would not need it, since the
|
|
199
199
|
* last acknowledged state would already be the authoritative baseline.
|
|
200
200
|
*/
|
|
@@ -214,8 +214,8 @@ export class Model {
|
|
|
214
214
|
* Capture a before-image for `keys` — the single source of truth for the
|
|
215
215
|
* "previous value" that undo inverses are built from. Both undo paths call
|
|
216
216
|
* this so they can never drift: the stream path
|
|
217
|
-
* (`
|
|
218
|
-
* (`
|
|
217
|
+
* (`MutationQueue.extractPreviousData`) and the manual-record path
|
|
218
|
+
* (`RecordingMutation.snapshotFields`).
|
|
219
219
|
*
|
|
220
220
|
* Resolution order per key:
|
|
221
221
|
* 1. `modifiedProperties.get(key).old` — first-old-wins pre-session
|
|
@@ -428,9 +428,16 @@ export class Model {
|
|
|
428
428
|
* written, `onWrite(key, oldValue, newValue)` is invoked with the value
|
|
429
429
|
* captured immediately before assignment. `applyChanges` passes a hook
|
|
430
430
|
* that records the change in `modifiedProperties`; `updateFromData`
|
|
431
|
-
* passes none (hydration must not generate outbound mutations).
|
|
432
|
-
*
|
|
433
|
-
*
|
|
431
|
+
* passes none (hydration must not generate outbound mutations).
|
|
432
|
+
*
|
|
433
|
+
* This is not the ONLY tracking path. `mobxSetup`'s `observe()` bridge is
|
|
434
|
+
* live and forwards a DIRECT assignment (`layer.position = next`) to
|
|
435
|
+
* `propertyChanged` as well — product code writes model fields directly in
|
|
436
|
+
* plenty of places (keyboard nudge, formatting, AI tools), and those writes
|
|
437
|
+
* have to reach the server and the undo stream too. The two paths compose:
|
|
438
|
+
* a direct write establishes the first-old-wins baseline, and a later
|
|
439
|
+
* `applyChanges` carrying the value the model already holds is a no-op that
|
|
440
|
+
* leaves that baseline intact.
|
|
434
441
|
*/
|
|
435
442
|
assignFieldsFromData(data, onWrite) {
|
|
436
443
|
// Update properties with safety checks for read-only/computed accessors
|
|
@@ -489,10 +496,13 @@ export class Model {
|
|
|
489
496
|
* brand-new outbound mutation and the record would echo forever. For a
|
|
490
497
|
* local user edit, use `applyChanges` instead.
|
|
491
498
|
*
|
|
492
|
-
* Suppression
|
|
493
|
-
* clear/restore `modifiedProperties` around the
|
|
494
|
-
*
|
|
495
|
-
*
|
|
499
|
+
* Suppression takes two forms and BOTH are load-bearing: we pass no
|
|
500
|
+
* `onWrite` hook, and we clear/restore `modifiedProperties` around the
|
|
501
|
+
* assignment. The second is what catches `mobxSetup`'s `observe()` bridge,
|
|
502
|
+
* which fires on the assignment itself and would otherwise record an
|
|
503
|
+
* inbound delta as a local edit — queueing an outbound mutation that echoes
|
|
504
|
+
* forever, and putting a collaborator's change on your undo stack. Do not
|
|
505
|
+
* remove it while that bridge exists (`mobxSetup.M1`).
|
|
496
506
|
*/
|
|
497
507
|
updateFromData(data) {
|
|
498
508
|
if (this.isDisposed) {
|
package/dist/ModelRegistry.d.ts
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* classes. References resolve lazily, so a model may declare a reference to
|
|
8
8
|
* another model that is registered later.
|
|
9
9
|
*/
|
|
10
|
-
import { type ModelMetadata, type PropertyMetadata, type ReferenceMetadata, LoadStrategy } from './types/index.js';
|
|
10
|
+
import { type ModelMetadata, type PropertyMetadata, type ReferenceMetadata, LoadStrategy } from './transaction/types/index.js';
|
|
11
|
+
import type { RuntimeContext } from './RuntimeContext.js';
|
|
11
12
|
import type { Model } from './Model.js';
|
|
12
13
|
import type { ConcreteModelConstructor } from './BaseSyncedStore.js';
|
|
13
14
|
/**
|
|
@@ -51,9 +52,9 @@ export interface SerializedReferenceMetadata extends Omit<ExtendedReferenceMetad
|
|
|
51
52
|
* child's pending transactions can be cancelled.
|
|
52
53
|
*/
|
|
53
54
|
export interface BackReferenceMetadata {
|
|
54
|
-
/** The parent model name (e.g., '
|
|
55
|
+
/** The parent model name (e.g., 'Report') */
|
|
55
56
|
parentModel: string;
|
|
56
|
-
/** The foreign key property on this model (e.g., '
|
|
57
|
+
/** The foreign key property on this model (e.g., 'reportId') */
|
|
57
58
|
foreignKey: string;
|
|
58
59
|
/** Whether to cascade-cancel transactions when parent is deleted */
|
|
59
60
|
cascadeDelete: boolean;
|
|
@@ -61,6 +62,8 @@ export interface BackReferenceMetadata {
|
|
|
61
62
|
interface RegistryConfig {
|
|
62
63
|
validateOnRegister?: boolean;
|
|
63
64
|
allowLateReferences?: boolean;
|
|
65
|
+
/** The owning client's runtime. Defaults to the module-global bridge. */
|
|
66
|
+
runtime?: RuntimeContext;
|
|
64
67
|
}
|
|
65
68
|
/** Set the active ModelRegistry instance (called by createSyncEngine) */
|
|
66
69
|
export declare function setActiveRegistry(registry: ModelRegistry): void;
|
|
@@ -80,6 +83,7 @@ export declare class ModelRegistry {
|
|
|
80
83
|
private backReferences;
|
|
81
84
|
private schemaHash?;
|
|
82
85
|
private config;
|
|
86
|
+
private readonly runtime;
|
|
83
87
|
private registeredModels;
|
|
84
88
|
private pendingHashUpdate;
|
|
85
89
|
constructor(config?: RegistryConfig);
|
|
@@ -107,7 +111,7 @@ export declare class ModelRegistry {
|
|
|
107
111
|
* transactions for every child model that declares a back-reference to that
|
|
108
112
|
* parent.
|
|
109
113
|
*
|
|
110
|
-
* @param childModelName - The model that holds a foreign key to the parent (e.g., '
|
|
114
|
+
* @param childModelName - The model that holds a foreign key to the parent (e.g., 'Section')
|
|
111
115
|
* @param metadata - The back-reference configuration
|
|
112
116
|
*/
|
|
113
117
|
registerBackReference(childModelName: string, metadata: BackReferenceMetadata): void;
|
package/dist/ModelRegistry.js
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* another model that is registered later.
|
|
9
9
|
*/
|
|
10
10
|
// Removed Node.js crypto import for browser compatibility
|
|
11
|
-
import { PropertyType, LoadStrategy, } from './types/index.js';
|
|
12
|
-
import {
|
|
13
|
-
import { AbloValidationError } from './errors.js';
|
|
11
|
+
import { PropertyType, LoadStrategy, } from './transaction/types/index.js';
|
|
12
|
+
import { globalRuntime } from './context.js';
|
|
13
|
+
import { AbloValidationError } from './transaction/errors.js';
|
|
14
14
|
/**
|
|
15
15
|
* Module-level active registry. Set by createSyncEngine so that Model instances
|
|
16
16
|
* (which don't receive DI) can look up metadata without static maps.
|
|
@@ -51,6 +51,7 @@ export class ModelRegistry {
|
|
|
51
51
|
backReferences = new Map();
|
|
52
52
|
schemaHash;
|
|
53
53
|
config;
|
|
54
|
+
runtime;
|
|
54
55
|
registeredModels = new Set();
|
|
55
56
|
pendingHashUpdate = false;
|
|
56
57
|
constructor(config = {}) {
|
|
@@ -58,6 +59,7 @@ export class ModelRegistry {
|
|
|
58
59
|
validateOnRegister: config.validateOnRegister ?? true,
|
|
59
60
|
allowLateReferences: config.allowLateReferences ?? true,
|
|
60
61
|
};
|
|
62
|
+
this.runtime = config.runtime ?? globalRuntime;
|
|
61
63
|
}
|
|
62
64
|
validateModelConstructor(name, constructor) {
|
|
63
65
|
if (typeof constructor !== 'function') {
|
|
@@ -71,7 +73,7 @@ export class ModelRegistry {
|
|
|
71
73
|
const required = ['updateFromData', 'toJSON', 'getModelName'];
|
|
72
74
|
for (const method of required) {
|
|
73
75
|
if (typeof prototype[method] !== 'function') {
|
|
74
|
-
|
|
76
|
+
this.runtime.logger.debug('Model missing required method', name, { method });
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
}
|
|
@@ -99,7 +101,7 @@ export class ModelRegistry {
|
|
|
99
101
|
this.pendingReferences.set(targetName, pending);
|
|
100
102
|
}
|
|
101
103
|
pending.push({ modelName, propertyName, metadata });
|
|
102
|
-
|
|
104
|
+
this.runtime.logger.debug('Reference deferred', `${modelName}.${propertyName}`, { targetModel: targetName });
|
|
103
105
|
}
|
|
104
106
|
resolvePendingReferences(targetModelName) {
|
|
105
107
|
const pending = this.pendingReferences.get(targetModelName);
|
|
@@ -108,12 +110,12 @@ export class ModelRegistry {
|
|
|
108
110
|
for (const ref of pending) {
|
|
109
111
|
try {
|
|
110
112
|
this.completeReferenceRegistration(ref.modelName, ref.propertyName, ref.metadata);
|
|
111
|
-
|
|
113
|
+
this.runtime.logger.debug('Reference resolved', `${ref.modelName}.${ref.propertyName}`, {
|
|
112
114
|
targetModel: targetModelName,
|
|
113
115
|
});
|
|
114
116
|
}
|
|
115
117
|
catch (error) {
|
|
116
|
-
|
|
118
|
+
this.runtime.observability.breadcrumb(`Failed to resolve reference ${ref.modelName}.${ref.propertyName}`, 'sync.database', 'error', {
|
|
117
119
|
error: error instanceof Error ? error.message : String(error),
|
|
118
120
|
});
|
|
119
121
|
}
|
|
@@ -154,10 +156,10 @@ export class ModelRegistry {
|
|
|
154
156
|
}
|
|
155
157
|
// Check for duplicate
|
|
156
158
|
if (this.models.has(name)) {
|
|
157
|
-
|
|
159
|
+
this.runtime.logger.debug('Model already registered, skipping', name);
|
|
158
160
|
return;
|
|
159
161
|
}
|
|
160
|
-
|
|
162
|
+
this.runtime.logger.debug('Registering model', name);
|
|
161
163
|
// Register. The one cast in this file: input is any Model-subclass
|
|
162
164
|
// constructor (validated above); registered classes are concrete
|
|
163
165
|
// subclasses constructible with `data?` and carrying Model's statics —
|
|
@@ -180,7 +182,7 @@ export class ModelRegistry {
|
|
|
180
182
|
this.resolvePendingReferences(name);
|
|
181
183
|
// Invalidate schema hash
|
|
182
184
|
this.schemaHash = undefined;
|
|
183
|
-
|
|
185
|
+
this.runtime.logger.debug('Model registered', name, metadata);
|
|
184
186
|
}
|
|
185
187
|
/**
|
|
186
188
|
* Register property with validation
|
|
@@ -201,7 +203,7 @@ export class ModelRegistry {
|
|
|
201
203
|
if (existing) {
|
|
202
204
|
if (this.arePropertiesCompatible(existing, metadata)) {
|
|
203
205
|
// Properties are compatible, skip re-registration
|
|
204
|
-
|
|
206
|
+
this.runtime.logger.debug('Property already registered (compatible)', `${modelName}.${propertyName}`);
|
|
205
207
|
return;
|
|
206
208
|
}
|
|
207
209
|
else {
|
|
@@ -210,7 +212,7 @@ export class ModelRegistry {
|
|
|
210
212
|
}
|
|
211
213
|
props.set(propertyName, metadata);
|
|
212
214
|
this.schemaHash = undefined;
|
|
213
|
-
|
|
215
|
+
this.runtime.logger.debug('Property registered', `${modelName}.${propertyName}`, metadata);
|
|
214
216
|
}
|
|
215
217
|
/**
|
|
216
218
|
* Register reference with lazy resolution
|
|
@@ -248,7 +250,7 @@ export class ModelRegistry {
|
|
|
248
250
|
* transactions for every child model that declares a back-reference to that
|
|
249
251
|
* parent.
|
|
250
252
|
*
|
|
251
|
-
* @param childModelName - The model that holds a foreign key to the parent (e.g., '
|
|
253
|
+
* @param childModelName - The model that holds a foreign key to the parent (e.g., 'Section')
|
|
252
254
|
* @param metadata - The back-reference configuration
|
|
253
255
|
*/
|
|
254
256
|
registerBackReference(childModelName, metadata) {
|
|
@@ -265,7 +267,7 @@ export class ModelRegistry {
|
|
|
265
267
|
}
|
|
266
268
|
// Reverse lookup (parent → children) is derived on demand by
|
|
267
269
|
// `getChildModels`, which scans this map.
|
|
268
|
-
|
|
270
|
+
this.runtime.logger.debug('BackReference registered', `${childModelName} -> ${metadata.parentModel}`, {
|
|
269
271
|
foreignKey: metadata.foreignKey,
|
|
270
272
|
cascadeDelete: metadata.cascadeDelete,
|
|
271
273
|
});
|
|
@@ -365,7 +367,7 @@ export class ModelRegistry {
|
|
|
365
367
|
const sorted = JSON.stringify(schema, Object.keys(schema).sort());
|
|
366
368
|
// Create hash - browser-compatible simple hash
|
|
367
369
|
this.schemaHash = this.simpleHash(sorted);
|
|
368
|
-
|
|
370
|
+
this.runtime.logger.debug('Schema hash updated', this.schemaHash);
|
|
369
371
|
return this.schemaHash;
|
|
370
372
|
}
|
|
371
373
|
/**
|
|
@@ -410,10 +412,10 @@ export class ModelRegistry {
|
|
|
410
412
|
}
|
|
411
413
|
const isValid = errors.length === 0;
|
|
412
414
|
if (isValid) {
|
|
413
|
-
|
|
415
|
+
this.runtime.logger.info('All model references are valid');
|
|
414
416
|
}
|
|
415
417
|
else {
|
|
416
|
-
|
|
418
|
+
this.runtime.observability.breadcrumb('Reference validation failed', 'sync.database', 'error');
|
|
417
419
|
}
|
|
418
420
|
return {
|
|
419
421
|
valid: isValid,
|
|
@@ -458,7 +460,7 @@ export class ModelRegistry {
|
|
|
458
460
|
this.constructorToModelName.clear();
|
|
459
461
|
this.schemaHash = undefined;
|
|
460
462
|
this.pendingHashUpdate = false;
|
|
461
|
-
|
|
463
|
+
this.runtime.logger.info('ModelRegistry cleared');
|
|
462
464
|
}
|
|
463
465
|
/**
|
|
464
466
|
* Static wrapper for backward compatibility
|