@seedprotocol/sdk 0.7.9 → 0.7.10-next.1353.g74aeeed

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.
Files changed (136) hide show
  1. package/README.md +1 -1
  2. package/dist/{BaseFileManager-BAlySv8w.js → BaseFileManager-DLou1TZS.js} +5 -1
  3. package/dist/BaseFileManager-DLou1TZS.js.map +1 -0
  4. package/dist/{Item-Bf4kWKpH.js → Item-oPnmIehk.js} +571 -346
  5. package/dist/Item-oPnmIehk.js.map +1 -0
  6. package/dist/{ModelProperty-BlaEgb_U.js → ModelProperty-D2vJozmW.js} +95 -62
  7. package/dist/ModelProperty-D2vJozmW.js.map +1 -0
  8. package/dist/{Schema-J_1f6p0c.js → Schema-BMXRF4j9.js} +88 -52
  9. package/dist/Schema-BMXRF4j9.js.map +1 -0
  10. package/dist/{SchemaValidationService-CnmKyzR-.js → SchemaValidationService-CieGrj5c.js} +5 -5
  11. package/dist/{SchemaValidationService-CnmKyzR-.js.map → SchemaValidationService-CieGrj5c.js.map} +1 -1
  12. package/dist/{errors-C1qUEZ7A.js → browserSupport-C64rX-2I.js} +38 -2
  13. package/dist/browserSupport-C64rX-2I.js.map +1 -0
  14. package/dist/{configurePlatform-CiOJ1R3q.js → configurePlatform-WkmvqeTO.js} +2 -2
  15. package/dist/{configurePlatform-CiOJ1R3q.js.map → configurePlatform-WkmvqeTO.js.map} +1 -1
  16. package/dist/{detachRowsBeforeDelete-sEaUwlOU.js → detachRowsBeforeDelete-BZr_0iZU.js} +2 -2
  17. package/dist/{detachRowsBeforeDelete-sEaUwlOU.js.map → detachRowsBeforeDelete-BZr_0iZU.js.map} +1 -1
  18. package/dist/dist/{BaseFileManager-BAlySv8w.d.ts → BaseFileManager-DLou1TZS.d.ts} +3 -1
  19. package/dist/dist/BaseFileManager-DLou1TZS.d.ts.map +1 -0
  20. package/dist/dist/{configurePlatform-CiOJ1R3q.d.ts → configurePlatform-WkmvqeTO.d.ts} +1 -1
  21. package/dist/dist/configurePlatform-WkmvqeTO.d.ts.map +1 -0
  22. package/dist/dist/{index-D0V-mjCV.d.ts → index-BjWk0x4-.d.ts} +1 -1
  23. package/dist/dist/{index-D0V-mjCV.d.ts.map → index-BjWk0x4-.d.ts.map} +1 -1
  24. package/dist/dist/{index.node-CYPemH-t.d.ts → index.node-BfiBriEq.d.ts} +7 -1
  25. package/dist/dist/{index.node-CYPemH-t.d.ts.map → index.node-BfiBriEq.d.ts.map} +1 -1
  26. package/dist/dist/platform.node.d.ts +2 -2
  27. package/dist/{eas-wB_fQ8Tc.js → eas-FZPPqxqe.js} +5 -5
  28. package/dist/{eas-wB_fQ8Tc.js.map → eas-FZPPqxqe.js.map} +1 -1
  29. package/dist/{errors-DLSoqSHG.js → errors-CnT0fSMK.js} +185 -97
  30. package/dist/errors-CnT0fSMK.js.map +1 -0
  31. package/dist/{getPublishPayload-BnIwpwz1.js → getPublishPayload-DKuEaq96.js} +8 -8
  32. package/dist/{getPublishPayload-BnIwpwz1.js.map → getPublishPayload-DKuEaq96.js.map} +1 -1
  33. package/dist/{getPublishPendingDiff-D6_-A5ns.js → getPublishPendingDiff-CH5xLMjU.js} +7 -7
  34. package/dist/{getPublishPendingDiff-D6_-A5ns.js.map → getPublishPendingDiff-CH5xLMjU.js.map} +1 -1
  35. package/dist/{getPublishUploads-sS6JfPgz.js → getPublishUploads-DivYpgNw.js} +7 -7
  36. package/dist/{getPublishUploads-sS6JfPgz.js.map → getPublishUploads-DivYpgNw.js.map} +1 -1
  37. package/dist/{index-D0V-mjCV.js → index-BjWk0x4-.js} +2 -2
  38. package/dist/index-BjWk0x4-.js.map +1 -0
  39. package/dist/{index-CYGWPoOx.js → index-CZMWKXLM.js} +7 -7
  40. package/dist/index-CZMWKXLM.js.map +1 -0
  41. package/dist/{index-BVBmz_cc.js → index-DXRhFg1N.js} +7 -7
  42. package/dist/index-DXRhFg1N.js.map +1 -0
  43. package/dist/{index-DmTtj1nk.js → index-Gh42_47r.js} +402 -20
  44. package/dist/index-Gh42_47r.js.map +1 -0
  45. package/dist/{index.browser-CUmBVYen.js → index.browser-DQstVvRV.js} +46 -10
  46. package/dist/index.browser-DQstVvRV.js.map +1 -0
  47. package/dist/{index.node-CYPemH-t.js → index.node-BfiBriEq.js} +31 -4
  48. package/dist/index.node-BfiBriEq.js.map +1 -0
  49. package/dist/main.js +17 -16
  50. package/dist/main.js.map +1 -1
  51. package/dist/{modelPropertyRecordSchemas-C7UgA5TH.js → modelPropertyRecordSchemas-DEe-lYhn.js} +5 -5
  52. package/dist/{modelPropertyRecordSchemas-C7UgA5TH.js.map → modelPropertyRecordSchemas-DEe-lYhn.js.map} +1 -1
  53. package/dist/node.js +8 -8
  54. package/dist/platform.browser.js +6 -6
  55. package/dist/platform.node.js +4 -4
  56. package/dist/{property-BxUYznH0.js → property-iNW1N3vm.js} +8 -8
  57. package/dist/{property-BxUYznH0.js.map → property-iNW1N3vm.js.map} +1 -1
  58. package/dist/{publishGraph-EcB40Uii.js → publishGraph-CRn_N3NT.js} +5 -5
  59. package/dist/{publishGraph-EcB40Uii.js.map → publishGraph-CRn_N3NT.js.map} +1 -1
  60. package/dist/{readHtmlBodyForStorageSeed-D6KPtWoR.js → readHtmlBodyForStorageSeed-B7HgPmq6.js} +10 -10
  61. package/dist/{readHtmlBodyForStorageSeed-D6KPtWoR.js.map → readHtmlBodyForStorageSeed-B7HgPmq6.js.map} +1 -1
  62. package/dist/src/Item/Item.d.ts +26 -5
  63. package/dist/src/Item/Item.d.ts.map +1 -1
  64. package/dist/src/ItemProperty/ItemProperty.d.ts +20 -5
  65. package/dist/src/ItemProperty/ItemProperty.d.ts.map +1 -1
  66. package/dist/src/ItemProperty/loadProperty.d.ts.map +1 -1
  67. package/dist/src/ItemProperty/propertyWrite.d.ts.map +1 -1
  68. package/dist/src/ItemProperty/service/actors/hydrateFromDb.d.ts.map +1 -1
  69. package/dist/src/Model/Model.d.ts +45 -34
  70. package/dist/src/Model/Model.d.ts.map +1 -1
  71. package/dist/src/ModelProperty/ModelProperty.d.ts +31 -13
  72. package/dist/src/ModelProperty/ModelProperty.d.ts.map +1 -1
  73. package/dist/src/Schema/Schema.d.ts +36 -27
  74. package/dist/src/Schema/Schema.d.ts.map +1 -1
  75. package/dist/src/archive/exportArchive.d.ts +57 -0
  76. package/dist/src/archive/exportArchive.d.ts.map +1 -0
  77. package/dist/src/browser/db/Db.d.ts +5 -0
  78. package/dist/src/browser/db/Db.d.ts.map +1 -1
  79. package/dist/src/browser/helpers/FileManager.d.ts.map +1 -1
  80. package/dist/src/browser/helpers/tolerantWebAccess.d.ts +12 -1
  81. package/dist/src/browser/helpers/tolerantWebAccess.d.ts.map +1 -1
  82. package/dist/src/client/ClientManager.d.ts +14 -4
  83. package/dist/src/client/ClientManager.d.ts.map +1 -1
  84. package/dist/src/db/Db/BaseDb.d.ts +2 -0
  85. package/dist/src/db/Db/BaseDb.d.ts.map +1 -1
  86. package/dist/src/helpers/FileManager/errors.d.ts +11 -0
  87. package/dist/src/helpers/FileManager/errors.d.ts.map +1 -1
  88. package/dist/src/helpers/browserSupport.d.ts +23 -0
  89. package/dist/src/helpers/browserSupport.d.ts.map +1 -0
  90. package/dist/src/helpers/cachedPropertyRefresh.d.ts +6 -6
  91. package/dist/src/helpers/cachedPropertyRefresh.d.ts.map +1 -1
  92. package/dist/src/helpers/entity/entityCache.d.ts +45 -3
  93. package/dist/src/helpers/entity/entityCache.d.ts.map +1 -1
  94. package/dist/src/helpers/entity/entityLifecycle.d.ts +21 -3
  95. package/dist/src/helpers/entity/entityLifecycle.d.ts.map +1 -1
  96. package/dist/src/helpers/propertyDefinition.d.ts +2 -0
  97. package/dist/src/helpers/propertyDefinition.d.ts.map +1 -1
  98. package/dist/src/helpers/schemaApply.d.ts.map +1 -1
  99. package/dist/src/helpers/tabCoordinator.d.ts +9 -2
  100. package/dist/src/helpers/tabCoordinator.d.ts.map +1 -1
  101. package/dist/src/index.d.ts +4 -1
  102. package/dist/src/index.d.ts.map +1 -1
  103. package/dist/src/interfaces/IDb.d.ts +6 -0
  104. package/dist/src/interfaces/IDb.d.ts.map +1 -1
  105. package/dist/src/node/db/Db.d.ts +6 -0
  106. package/dist/src/node/db/Db.d.ts.map +1 -1
  107. package/dist/src/outbox/conflicts.d.ts.map +1 -1
  108. package/dist/src/outbox/outbox.d.ts +6 -0
  109. package/dist/src/outbox/outbox.d.ts.map +1 -1
  110. package/dist/src/types/index.d.ts +16 -0
  111. package/dist/src/types/index.d.ts.map +1 -1
  112. package/dist/{syncDbWithEas-CA7PvBgu.js → syncDbWithEas-FuyqoEKk.js} +14 -14
  113. package/dist/{syncDbWithEas-CA7PvBgu.js.map → syncDbWithEas-FuyqoEKk.js.map} +1 -1
  114. package/dist/{tabEvents-CaVmngqr.js → tabEvents-DT5ez6io.js} +38 -12
  115. package/dist/tabEvents-DT5ez6io.js.map +1 -0
  116. package/dist/{tolerantWebAccess-BJqViq08.js → tolerantWebAccess-zEseJ2zT.js} +53 -13
  117. package/dist/tolerantWebAccess-zEseJ2zT.js.map +1 -0
  118. package/dist/{updateSeedRevokedAt-BL9Bg-G7.js → updateSeedRevokedAt-B9JRwr5T.js} +3 -3
  119. package/dist/{updateSeedRevokedAt-BL9Bg-G7.js.map → updateSeedRevokedAt-B9JRwr5T.js.map} +1 -1
  120. package/package.json +10 -12
  121. package/dist/BaseFileManager-BAlySv8w.js.map +0 -1
  122. package/dist/Item-Bf4kWKpH.js.map +0 -1
  123. package/dist/ModelProperty-BlaEgb_U.js.map +0 -1
  124. package/dist/Schema-J_1f6p0c.js.map +0 -1
  125. package/dist/dist/BaseFileManager-BAlySv8w.d.ts.map +0 -1
  126. package/dist/dist/configurePlatform-CiOJ1R3q.d.ts.map +0 -1
  127. package/dist/errors-C1qUEZ7A.js.map +0 -1
  128. package/dist/errors-DLSoqSHG.js.map +0 -1
  129. package/dist/index-BVBmz_cc.js.map +0 -1
  130. package/dist/index-CYGWPoOx.js.map +0 -1
  131. package/dist/index-D0V-mjCV.js.map +0 -1
  132. package/dist/index-DmTtj1nk.js.map +0 -1
  133. package/dist/index.browser-CUmBVYen.js.map +0 -1
  134. package/dist/index.node-CYPemH-t.js.map +0 -1
  135. package/dist/tabEvents-CaVmngqr.js.map +0 -1
  136. package/dist/tolerantWebAccess-BJqViq08.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { fromCallback, setup, assign, createActor, waitFor, fromPromise } from 'xstate';
2
- import { aj as isActorStopped, T as applyContextUpdate, U as isInternalUpdate, ak as differsFromOriginals, X as isEntityTornDown, al as onEntityTeardown, V as evictionLog, Y as sameEntity, Z as DEFAULT_READY_TIMEOUT_MS, _ as waitForEntityReady, $ as createReactiveProxy, a0 as runEntityLoad, a2 as entityStatus, I as Item, a1 as evictEntities, a3 as releaseEntity, a4 as destroyEntity, a7 as modelPropertiesToObject, a5 as EntityCache, a9 as easPropertyNameForPublish, ae as matchMetadataProperty, aQ as getSeedPublisher, af as metadataRowsOfProperty, ag as METADATA_LATEST_FIRST_ORDER_SQL, aR as deleteStagedFile, aS as storageFileName, aT as STORAGE_SUBDIR, aU as resolveNewSeedFields, aV as lookupPropertySchemaUid, aW as stageStorageContent, aX as requireStagedFile, aY as createSeed, aZ as createMetadata, H as compareMetadataRowsLatestFirst, a_ as storageValueRowOf, t as registerOutboxApplier, r as outboxOpValue, a$ as findSetConflict, b0 as recordPropertyEdit, h as OutboxOpDeferredError, u as startOutbox, i as OutboxOpFailedError, y as OwnershipError, B as isItemOwned, R as getLatestVersionRow, S as parseListPropertyValueFromStorage, ar as resolvePublisherFromSeedRow, aB as isLocalUnsealedDraft } from './Item-Bf4kWKpH.js';
2
+ import { ak as isActorStopped, T as applyContextUpdate, U as isInternalUpdate, al as differsFromOriginals, X as isEntityTornDown, am as onEntityTeardown, V as evictionLog, Y as sameEntity, Z as DEFAULT_READY_TIMEOUT_MS, _ as createReactiveProxy, $ as runEntityLoad, a0 as waitForEntityReady, a2 as EntityUnloadedError, a3 as entityStatus, I as Item, a1 as evictEntities, a4 as releaseEntity, a5 as destroyEntity, a8 as modelPropertiesToObject, a6 as EntityCache, aa as easPropertyNameForPublish, af as matchMetadataProperty, aT as getSeedPublisher, ag as metadataRowsOfProperty, ah as METADATA_LATEST_FIRST_ORDER_SQL, aU as deleteStagedFile, aV as storageFileName, aW as STORAGE_SUBDIR, aX as resolveNewSeedFields, aY as lookupPropertySchemaUid, aZ as stageStorageContent, a_ as requireStagedFile, a$ as createSeed, b0 as createMetadata, H as compareMetadataRowsLatestFirst, b1 as storageValueRowOf, t as registerOutboxApplier, r as outboxOpValue, b2 as findSetConflict, b3 as recordPropertyEdit, h as OutboxOpDeferredError, u as startOutbox, i as OutboxOpFailedError, y as OwnershipError, B as isItemOwned, R as getLatestVersionRow, S as parseListPropertyValueFromStorage, au as resolvePublisherFromSeedRow, aE as isLocalUnsealedDraft, b4 as setEntityUnloadGraceMs, b5 as stopOutbox, b6 as evictAllEntities } from './Item-oPnmIehk.js';
3
3
  import debug from 'debug';
4
- import { B as BaseDb, l as properties, d as models$1, j as modelSchemas, t as schemas, f as easSyncProcesses, a as appState, w as BaseFileManager, b as modelUids, s as seeds, v as versions, m as metadata$1, p as pendingWrites, h as htmlEmbeddedImageCoPublish, e as arweaveL1FinalizeJobs, r as publishProcesses } from './BaseFileManager-BAlySv8w.js';
5
- import { aH as writeModelToDb, aI as writePropertyToDb, m as generateId, p as isInternalSchema, A as AmbiguousModelError, aJ as currentNameMatchLevels, aK as renameModelInDb, s as isClientReady, a as TProperty, ay as withDbTabLock, af as MachineIds, ap as isLeaderTab, aL as postTabMessage, aM as onTabMessage, ax as whenLeaderTab, aN as listenForOtherTabsEvents, F as isBrowser, $ as isNode, aO as startTabCoordination, aq as normalizeAddressConfig, aP as isTestOrSeedDev, L as nameMatchLevels, C as loadNameMatchLevels, aD as withSeedDbLock, q as inDefinitionsTransaction, aQ as insertModelStubs, G as emitAcrossTabs, a8 as ADDRESSES_PERSISTED_EVENT, ar as normalizeAddressList, aR as warnOnInvalidNameMatch, u as upsertSchemaRow, aS as refreshCachedProperties, g as normalizePropertyRecordSchema, M as ModelPropertyDataTypes, j as findSeedRow, aT as tryWithTabLock, Y as getItemStorageSubdir, _ as getItemStorageLocalFileName, aU as notifyFileSaved, ad as ImageSize, n as normalizeDataType, ab as ClientManagerState, aV as ClientManagerEvents, at as parseAddressesPersistedPayload, x as normalizePublisher, w as writeInBatches, K as selectInBatches, ae as LOCAL_COPIES_REMOVED_EVENT, aW as getWatchedAddressesFromDb, aX as getOwnedAddressesFromDb, aY as CLIENT_NOT_INITIALIZED, aZ as registerClientActor } from './tabEvents-CaVmngqr.js';
4
+ import { B as BaseDb, l as properties, d as models$1, j as modelSchemas, t as schemas, f as easSyncProcesses, a as appState, w as BaseFileManager, b as modelUids, s as seeds, v as versions, m as metadata$1, p as pendingWrites, h as htmlEmbeddedImageCoPublish, e as arweaveL1FinalizeJobs, r as publishProcesses } from './BaseFileManager-DLou1TZS.js';
5
+ import { aI as writeModelToDb, aJ as writePropertyToDb, m as generateId, p as isInternalSchema, A as AmbiguousModelError, aK as currentNameMatchLevels, aL as renameModelInDb, s as isClientReady, a as TProperty, ay as withDbTabLock, af as MachineIds, ap as isLeaderTab, aM as postTabMessage, aN as onTabMessage, ax as whenLeaderTab, aO as listenForOtherTabsEvents, F as isBrowser, $ as isNode, aP as startTabCoordination, aq as normalizeAddressConfig, aQ as isTestOrSeedDev, L as nameMatchLevels, C as loadNameMatchLevels, aD as withSeedDbLock, q as inDefinitionsTransaction, aR as insertModelStubs, G as emitAcrossTabs, a8 as ADDRESSES_PERSISTED_EVENT, ar as normalizeAddressList, aS as warnOnInvalidNameMatch, u as upsertSchemaRow, aT as refreshCachedProperties, g as normalizePropertyRecordSchema, M as ModelPropertyDataTypes, j as findSeedRow, aU as tryWithTabLock, Y as getItemStorageSubdir, _ as getItemStorageLocalFileName, aV as notifyFileSaved, ad as ImageSize, n as normalizeDataType, ab as ClientManagerState, aW as ClientManagerEvents, at as parseAddressesPersistedPayload, x as normalizePublisher, w as writeInBatches, K as selectInBatches, ae as LOCAL_COPIES_REMOVED_EVENT, aX as getWatchedAddressesFromDb, aY as getOwnedAddressesFromDb, aZ as CLIENT_NOT_INITIALIZED, a_ as stopTabCoordination, a$ as registerClientActor } from './tabEvents-DT5ez6io.js';
6
6
  import { seedGatewayConfigFromSeedConfig, setPreferredArweaveReadBaseUrls, resolveSeedGatewayEndpoints, setResolvedSeedGatewayEndpoints, BaseArweaveClient, ensureReadGatewaySelected, DEFAULT_ARWEAVE_HOST } from '@seedprotocol/arweave';
7
7
  import 'pluralize';
8
8
  import { localNamesInBestMatchTier, configureEasReadChain, matchEasModelSchemas, whenEasReadChainSettled, getEasReadChainId, DEFAULT_EAS_CHAIN_ID, isEasReadChainConfigured, easName, isValidEasAttestationUid } from '@seedprotocol/eas';
@@ -36,10 +36,10 @@ const validateModel = fromCallback(({ sendBack, input: { context }, self }) => {
36
36
  const _validateModel = async () => {
37
37
  try {
38
38
  // Use dynamic imports to break circular dependencies
39
- const validationServiceMod = await import('./SchemaValidationService-CnmKyzR-.js');
39
+ const validationServiceMod = await import('./SchemaValidationService-CieGrj5c.js');
40
40
  const { SchemaValidationService } = validationServiceMod;
41
41
  const validationService = new SchemaValidationService();
42
- const _mod_0 = await import('./Schema-J_1f6p0c.js');
42
+ const _mod_0 = await import('./Schema-BMXRF4j9.js');
43
43
  const _ns_0 = _mod_0.a;
44
44
  const schemaMod = _ns_0;
45
45
  const { Schema } = schemaMod;
@@ -61,7 +61,7 @@ const validateModel = fromCallback(({ sendBack, input: { context }, self }) => {
61
61
  return;
62
62
  if (context.schemaName) {
63
63
  try {
64
- const schema = await Schema.find({ schemaName: context.schemaName, waitForReady: false, hold: false });
64
+ const schema = await Schema.find({ schemaName: context.schemaName, waitForReady: false });
65
65
  if (!schema)
66
66
  throw new Error(`No schema named "${context.schemaName}"`);
67
67
  const schemaSnapshot = schema.getService().getSnapshot();
@@ -320,7 +320,7 @@ async function createModelProperties(model, propertyDefinitions) {
320
320
  throw new Error('Model ID, file ID, and name are required to create properties');
321
321
  }
322
322
  logger$f(`Creating ${Object.keys(propertyDefinitions).length} properties for model "${modelName}" (id: ${_dbId})`);
323
- const { ModelProperty } = await import('./ModelProperty-BlaEgb_U.js');
323
+ const { ModelProperty } = await import('./ModelProperty-D2vJozmW.js');
324
324
  const { and, eq } = await import('drizzle-orm');
325
325
  const db = BaseDb.getAppDb();
326
326
  for (const [propName, propData] of Object.entries(propertyDefinitions)) {
@@ -338,8 +338,8 @@ async function createModelProperties(model, propertyDefinitions) {
338
338
  : undefined;
339
339
  // Otherwise use provided ID or generate a random one
340
340
  // IDs should be generated in the import process before creating properties
341
- const _mod_1 = await import('./tabEvents-CaVmngqr.js');
342
- const _ns_1 = _mod_1.bi;
341
+ const _mod_1 = await import('./tabEvents-DT5ez6io.js');
342
+ const _ns_1 = _mod_1.bl;
343
343
  const { generateId } = _ns_1;
344
344
  const propertyFileId = propData.id || propertyRecord?.schemaFileId || generateId();
345
345
  logger$f(`Creating property "${propName}" with fileId "${propertyFileId}"`);
@@ -356,8 +356,8 @@ async function createModelProperties(model, propertyDefinitions) {
356
356
  }
357
357
  else if (refModelName) {
358
358
  // Fallback: resolve the ref by name within this model's schema
359
- const _mod_2 = await import('./tabEvents-CaVmngqr.js');
360
- const _ns_2 = _mod_2.be;
359
+ const _mod_2 = await import('./tabEvents-DT5ez6io.js');
360
+ const _ns_2 = _mod_2.bh;
361
361
  const { resolveModelRecord } = _ns_2;
362
362
  const refModelRecord = await resolveModelRecord(refModelName, { schemaName }, db);
363
363
  if (refModelRecord?.id) {
@@ -405,8 +405,8 @@ async function createModelProperties(model, propertyDefinitions) {
405
405
  _dbId: propertyRecord?.schemaFileId === propertyFileId
406
406
  ? propertyRecord.id
407
407
  : undefined, // Already persisted: skip the write
408
- }, { schemaName, hold: false }); // Use 'as any' because _propertyFileId is not in TProperty type
409
- // The model keeps its properties; an app's unload of the same instance doesn't stop them.
408
+ }, { schemaName }); // Use 'as any' because _propertyFileId is not in TProperty type
409
+ // The model holds its properties (a child hold), released when the model is destroyed or evicted
410
410
  ModelProperty.holdForModel(property, model);
411
411
  }
412
412
  logger$f(`Created all properties for model "${modelName}"`);
@@ -452,7 +452,7 @@ const write = async (input) => {
452
452
  });
453
453
  }
454
454
  // Imported here: the validation service imports the Schema barrel, which imports this module's callers
455
- const { SchemaValidationService } = await import('./SchemaValidationService-CnmKyzR-.js');
455
+ const { SchemaValidationService } = await import('./SchemaValidationService-CieGrj5c.js');
456
456
  const data = input.data();
457
457
  const { errors } = new SchemaValidationService().validatePropertyStructure(data);
458
458
  if (errors.length > 0) {
@@ -613,7 +613,7 @@ const createPropertyInstances = async (propertyFileIds, since) => {
613
613
  return;
614
614
  }
615
615
  try {
616
- const mod = await import('./ModelProperty-BlaEgb_U.js');
616
+ const mod = await import('./ModelProperty-D2vJozmW.js');
617
617
  const ModelProperty = mod?.ModelProperty ?? mod?.default;
618
618
  if (!ModelProperty) {
619
619
  logger$d('createPropertyInstances: ModelProperty not available from dynamic import');
@@ -684,10 +684,10 @@ async function loadModel(context, isStopped) {
684
684
  if (!modelRecord) {
685
685
  // Model names are only unique per schema: prefer this schema's row, and otherwise only
686
686
  // consider same-name rows that no schema claims yet (never another schema's model).
687
- const _mod_3 = await import('./BaseFileManager-BAlySv8w.js');
687
+ const _mod_3 = await import('./BaseFileManager-DLou1TZS.js');
688
688
  const _ns_3 = _mod_3.M;
689
689
  const { modelSchemas } = _ns_3;
690
- const _mod_4 = await import('./BaseFileManager-BAlySv8w.js');
690
+ const _mod_4 = await import('./BaseFileManager-DLou1TZS.js');
691
691
  const _ns_4 = _mod_4.z;
692
692
  const { schemas: schemasTable } = _ns_4;
693
693
  let dbModels = await db
@@ -827,13 +827,13 @@ async function loadModel(context, isStopped) {
827
827
  // Step 2: Fallback to Schema context (only if database doesn't have the model)
828
828
  // This handles the case where model exists in schema file but not yet in database
829
829
  try {
830
- const _mod_5 = await import('./Schema-J_1f6p0c.js');
830
+ const _mod_5 = await import('./Schema-BMXRF4j9.js');
831
831
  const _ns_5 = _mod_5.a;
832
832
  const { Schema } = _ns_5;
833
833
  // Stopped meanwhile (unloaded, or evicted with its schema): don't load the schema again
834
834
  if (isStopped())
835
835
  throw new Error('the model was unloaded while it loaded');
836
- const schema = Schema.create(schemaName, { waitForReady: false, hold: false });
836
+ const schema = Schema.create(schemaName, { waitForReady: false });
837
837
  // A schema still loading: its models are known once it has loaded
838
838
  await schema.waitForReady();
839
839
  const schemaContext = schema.getService().getSnapshot().context;
@@ -912,11 +912,11 @@ async function loadModel(context, isStopped) {
912
912
  }
913
913
  // Also check database for models (in case they're persisted but not in Schema context)
914
914
  if (db) {
915
- const _mod_6 = await import('./BaseFileManager-BAlySv8w.js');
915
+ const _mod_6 = await import('./BaseFileManager-DLou1TZS.js');
916
916
  const _ns_6 = _mod_6.M;
917
917
  const modelSchemaSchemaMod = _ns_6;
918
918
  const { modelSchemas } = modelSchemaSchemaMod;
919
- const _mod_7 = await import('./BaseFileManager-BAlySv8w.js');
919
+ const _mod_7 = await import('./BaseFileManager-DLou1TZS.js');
920
920
  const _ns_7 = _mod_7.z;
921
921
  const schemaSchemaMod = _ns_7;
922
922
  const { schemas: schemasTable } = schemaSchemaMod;
@@ -995,11 +995,11 @@ async function loadModel(context, isStopped) {
995
995
  }
996
996
  // Mark schema as draft when a new model is created so saveNewVersion() can persist it
997
997
  try {
998
- const _mod_8 = await import('./Schema-J_1f6p0c.js');
998
+ const _mod_8 = await import('./Schema-BMXRF4j9.js');
999
999
  const _ns_8 = _mod_8.a;
1000
1000
  const { Schema } = _ns_8;
1001
1001
  if (!isStopped()) {
1002
- const schema = Schema.create(schemaName, { waitForReady: false, hold: false });
1002
+ const schema = Schema.create(schemaName, { waitForReady: false });
1003
1003
  schema.getService().send({ type: 'markAsDraft', propertyKey: 'schema:models' });
1004
1004
  }
1005
1005
  }
@@ -1089,7 +1089,7 @@ const saveDraftLogger = debug('seedSdk:model:saveDraftToDb');
1089
1089
  // Lazy import cache for ModelProperty to avoid circular dependency
1090
1090
  // Eagerly start loading to minimize delay on first access
1091
1091
  let ModelPropertyClass = null;
1092
- const modelPropertyImportPromise = import('./ModelProperty-BlaEgb_U.js')
1092
+ const modelPropertyImportPromise = import('./ModelProperty-D2vJozmW.js')
1093
1093
  .then(module => {
1094
1094
  ModelPropertyClass = module.ModelProperty;
1095
1095
  return ModelPropertyClass;
@@ -1319,7 +1319,7 @@ class Model {
1319
1319
  }
1320
1320
  const waitForReady = options?.waitForReady !== false;
1321
1321
  const readyTimeout = options?.readyTimeout ?? DEFAULT_READY_TIMEOUT_MS;
1322
- const holds = options?.hold === false ? 0 : 1;
1322
+ const holds = options?.hold === true;
1323
1323
  // Extract schema name and instance
1324
1324
  let schemaName;
1325
1325
  let schemaInstance; // Using any to avoid circular dependency with Schema
@@ -1344,7 +1344,7 @@ class Model {
1344
1344
  logger$c(`Model.create: Found instance in ID cache for "${modelName}" (ID: ${id})`);
1345
1345
  if (!waitForReady)
1346
1346
  return cachedById;
1347
- return waitForEntityReady(cachedById, { timeout: readyTimeout }).then(() => cachedById);
1347
+ return Model.readyOrRelease(cachedById, readyTimeout, holds);
1348
1348
  }
1349
1349
  // A runtime create (no id) gets a new model, numbered when the name is taken ("My Model 1");
1350
1350
  // a schema model (with id) keeps its name.
@@ -1364,6 +1364,7 @@ class Model {
1364
1364
  }
1365
1365
  // Wrap instance in Proxy for reactive property access. `name` is an alias for `modelName`.
1366
1366
  const sendUpdate = (target, prop, value) => {
1367
+ target._assertLoaded(`set ${prop} on`);
1367
1368
  if (prop === 'modelName') {
1368
1369
  // Model name change - need to update Schema and database
1369
1370
  const context = target._getSnapshotContext();
@@ -1427,7 +1428,7 @@ class Model {
1427
1428
  });
1428
1429
  // A runtime create gets its name key once its load settles the name (it may be numbered)
1429
1430
  this.cache.add(proxiedInstance, [resolvedId, id ? modelKey(schemaName, uniqueModelName) : undefined], {
1430
- hold: holds === 1,
1431
+ hold: holds,
1431
1432
  });
1432
1433
  logger$c(`Model.create: Created new instance for "${uniqueModelName}" (ID: ${id})`);
1433
1434
  // Step 11: Register with schema if requested, OR trigger write if properties are provided
@@ -1465,36 +1466,54 @@ class Model {
1465
1466
  });
1466
1467
  if (!waitForReady)
1467
1468
  return proxiedInstance;
1468
- return waitForEntityReady(proxiedInstance, { timeout: readyTimeout }).then(() => proxiedInstance);
1469
+ return Model.readyOrRelease(proxiedInstance, readyTimeout, holds);
1469
1470
  }
1470
- /**
1471
- * Get Model instance by modelFileId (O(1) lookup). Takes a hold on the instance; release it with
1472
- * `unload()`.
1473
- */
1474
- static getById(modelFileId) {
1475
- return this.cache.hold(modelFileId);
1471
+ /** The model once ready; a call that took a hold gives it back when the model isn't ready in time. */
1472
+ static async readyOrRelease(model, timeout, held) {
1473
+ try {
1474
+ await waitForEntityReady(model, { timeout });
1475
+ }
1476
+ catch (error) {
1477
+ if (held)
1478
+ model.unload();
1479
+ throw error;
1480
+ }
1481
+ return model;
1482
+ }
1483
+ /** The cached Model with this modelFileId. Takes no hold unless `hold: true`. */
1484
+ static getById(modelFileId, options) {
1485
+ return options?.hold ? this.cache.hold(modelFileId) : this.cache.peek(modelFileId);
1476
1486
  }
1477
1487
  /**
1478
- * The cached Model with this modelFileId, without taking a hold. For SDK code that reads the
1479
- * model and doesn't hand it to a caller; callers that keep it use `getById`, `find` or `create`.
1488
+ * The cached Model with this modelFileId, without taking a hold.
1480
1489
  */
1481
1490
  static peek(modelFileId) {
1482
1491
  return this.cache.peek(modelFileId);
1483
1492
  }
1484
1493
  /**
1485
- * Get Model instance by name (O(1) lookup via name→ID mapping). Takes a hold on the instance;
1486
- * release it with `unload()`.
1494
+ * Takes one more hold on a cached, running instance, released with `unload()`. False (and no
1495
+ * hold) when the instance isn't cached or was stopped.
1496
+ */
1497
+ static retain(instance) {
1498
+ return instance.getService().getSnapshot().status === 'active' && this.cache.holdInstance(instance);
1499
+ }
1500
+ /**
1501
+ * Get Model instance by name (O(1) lookup via name→ID mapping). Takes no hold unless `hold: true`.
1487
1502
  *
1488
1503
  * @param modelName - The name of the model
1489
1504
  * @param schemaName - The schema name (optional, will query DB if not provided)
1490
1505
  * @returns The Model instance if found, undefined otherwise
1491
1506
  */
1492
- static getByName(modelName, schemaName) {
1507
+ static getByName(modelName, schemaName, options) {
1493
1508
  const model = this.peekByName(modelName, schemaName);
1494
- return model && this.cache.holdInstance(model) ? model : undefined;
1509
+ if (!model)
1510
+ return undefined;
1511
+ if (options?.hold)
1512
+ this.cache.holdInstance(model);
1513
+ return model;
1495
1514
  }
1496
1515
  /**
1497
- * `getByName` without taking a hold. Without `schemaName` it searches every cached schema and
1516
+ * The cached Model by name, without taking a hold. Without `schemaName` it searches every cached schema and
1498
1517
  * throws AmbiguousModelError when models from several schemas share the name; callers that know
1499
1518
  * the schema or model id should use Model.resolve() instead.
1500
1519
  */
@@ -1579,8 +1598,8 @@ class Model {
1579
1598
  if (db) {
1580
1599
  const since = evictionLog.now();
1581
1600
  try {
1582
- const _mod_9 = await import('./tabEvents-CaVmngqr.js');
1583
- const _ns_9 = _mod_9.be;
1601
+ const _mod_9 = await import('./tabEvents-DT5ez6io.js');
1602
+ const _ns_9 = _mod_9.bh;
1584
1603
  const { resolveModelRecord, getModelSchemaName } = _ns_9;
1585
1604
  const resolved = scope.modelFileId
1586
1605
  ? await resolveModelRecord(undefined, { modelFileId: scope.modelFileId }, db)
@@ -1594,7 +1613,7 @@ class Model {
1594
1613
  // Its schema was evicted, or it was destroyed, while we read the row: don't bring it back.
1595
1614
  if (evictionLog.evictedSince([`schema:${record.schemaName}`, `model:${record.modelFileId}`], since))
1596
1615
  return undefined;
1597
- return this.create(record.modelName, record.schemaName, { id: record.modelFileId, hold: false });
1616
+ return this.create(record.modelName, record.schemaName, { id: record.modelFileId });
1598
1617
  }
1599
1618
  }
1600
1619
  catch (error) {
@@ -1602,7 +1621,7 @@ class Model {
1602
1621
  }
1603
1622
  }
1604
1623
  }
1605
- return modelName ? this.getByNameAsync(modelName, undefined, { hold: false }) : undefined;
1624
+ return modelName ? this.getByNameAsync(modelName) : undefined;
1606
1625
  }
1607
1626
  /**
1608
1627
  * Get Model instance by name, querying database if not in cache
@@ -1610,11 +1629,11 @@ class Model {
1610
1629
  *
1611
1630
  * @param modelName - The name of the model
1612
1631
  * @param schemaName - Optional schema name (will query DB if not provided)
1613
- * @returns The Model instance if found, undefined otherwise. Takes a hold unless `hold: false`.
1632
+ * @returns The Model instance if found, undefined otherwise. Takes no hold unless `hold: true`.
1614
1633
  */
1615
1634
  static async getByNameAsync(modelName, schemaName, options) {
1616
1635
  // First try cache
1617
- const cached = options?.hold === false ? this.peekByName(modelName, schemaName) : this.getByName(modelName, schemaName);
1636
+ const cached = this.getByName(modelName, schemaName, options);
1618
1637
  if (cached) {
1619
1638
  return cached;
1620
1639
  }
@@ -1626,8 +1645,8 @@ class Model {
1626
1645
  }
1627
1646
  const since = options?.since ?? evictionLog.now();
1628
1647
  try {
1629
- const _mod_10 = await import('./tabEvents-CaVmngqr.js');
1630
- const _ns_10 = _mod_10.be;
1648
+ const _mod_10 = await import('./tabEvents-DT5ez6io.js');
1649
+ const _ns_10 = _mod_10.bh;
1631
1650
  const { resolveModelRecord, getModelSchemaName } = _ns_10;
1632
1651
  const resolved = await resolveModelRecord(modelName, schemaName ? { schemaName, strict: true } : {}, db);
1633
1652
  if (!resolved?.schemaFileId) {
@@ -1644,7 +1663,7 @@ class Model {
1644
1663
  // Create model instance (will be cached)
1645
1664
  return this.create(resolved.name, recordSchemaName, {
1646
1665
  id: resolved.schemaFileId, // id is now the schemaFileId (string)
1647
- ...(options?.hold === false && { hold: false }),
1666
+ hold: options?.hold,
1648
1667
  });
1649
1668
  }
1650
1669
  catch (error) {
@@ -1659,14 +1678,14 @@ class Model {
1659
1678
  * Checks cache first, then database if not found
1660
1679
  *
1661
1680
  * @param modelFileId - The model file ID to look up
1662
- * @returns The Model instance if found, undefined otherwise
1681
+ * @returns The Model instance if found, undefined otherwise. Takes no hold unless `hold: true`.
1663
1682
  */
1664
1683
  static async createById(modelFileId, options) {
1665
1684
  if (!modelFileId) {
1666
1685
  return undefined;
1667
1686
  }
1668
1687
  // Step 1: Check cache first (fast path)
1669
- const cached = options?.hold === false ? this.peek(modelFileId) : this.getById(modelFileId);
1688
+ const cached = this.getById(modelFileId, options);
1670
1689
  if (cached) {
1671
1690
  logger$c(`Model.createById: Found instance in cache for ID "${modelFileId}"`);
1672
1691
  return cached;
@@ -1711,7 +1730,7 @@ class Model {
1711
1730
  logger$c(`Model.createById: Creating model "${modelName}" in schema "${schemaName}" from ID "${modelFileId}"`);
1712
1731
  return this.create(modelName, schemaName, {
1713
1732
  id: modelFileId, // id is now the schemaFileId (string)
1714
- ...(options?.hold === false && { hold: false }),
1733
+ hold: options?.hold,
1715
1734
  });
1716
1735
  }
1717
1736
  catch (error) {
@@ -1721,18 +1740,27 @@ class Model {
1721
1740
  }
1722
1741
  /**
1723
1742
  * Find Model instance by modelFileId, modelName/schemaName, or both
1724
- * Waits for the model to be fully loaded (idle state) by default
1743
+ * Waits for the model to be fully loaded (idle state) by default. Takes no hold unless
1744
+ * `hold: true`; a call that throws (the model isn't ready in `readyTimeout`) keeps none.
1725
1745
  * @param options - Find options including lookup parameters and wait configuration
1726
1746
  * @returns Model instance if found, undefined otherwise
1727
1747
  */
1728
- static async find({ modelFileId, modelName, schemaName, waitForReady = true, readyTimeout = DEFAULT_READY_TIMEOUT_MS, }) {
1748
+ static async find({ modelFileId, modelName, schemaName, waitForReady = true, readyTimeout = DEFAULT_READY_TIMEOUT_MS, hold = false, }) {
1729
1749
  const model = modelFileId
1730
- ? (Model.getById(modelFileId) ?? (await Model.createById(modelFileId)))
1750
+ ? await Model.createById(modelFileId, { hold })
1731
1751
  : modelName
1732
- ? (Model.getByName(modelName, schemaName) ?? (await Model.getByNameAsync(modelName, schemaName)))
1752
+ ? await Model.getByNameAsync(modelName, schemaName, { hold })
1733
1753
  : undefined;
1734
- if (model && waitForReady)
1735
- await waitForEntityReady(model, { timeout: readyTimeout });
1754
+ if (model && waitForReady) {
1755
+ try {
1756
+ await waitForEntityReady(model, { timeout: readyTimeout });
1757
+ }
1758
+ catch (error) {
1759
+ if (hold)
1760
+ model.unload();
1761
+ throw error;
1762
+ }
1763
+ }
1736
1764
  return model;
1737
1765
  }
1738
1766
  /**
@@ -1740,9 +1768,9 @@ class Model {
1740
1768
  * Queries database for all models with the given schemaId/schemaName and returns Model instances
1741
1769
  *
1742
1770
  * @param schemaIdentifier - The schema file ID or schema name to get models for
1743
- * @returns Array of Model instances for the schema
1771
+ * @returns Array of Model instances for the schema. Takes no holds unless `hold: true`.
1744
1772
  */
1745
- static async createBySchemaId(schemaIdentifier) {
1773
+ static async createBySchemaId(schemaIdentifier, options) {
1746
1774
  if (!schemaIdentifier) {
1747
1775
  return [];
1748
1776
  }
@@ -1779,7 +1807,7 @@ class Model {
1779
1807
  continue;
1780
1808
  }
1781
1809
  // Check cache first
1782
- const cached = this.getById(record.modelFileId);
1810
+ const cached = this.getById(record.modelFileId, options);
1783
1811
  if (cached) {
1784
1812
  modelInstances.push(cached);
1785
1813
  }
@@ -1788,6 +1816,7 @@ class Model {
1788
1816
  const model = this.create(record.modelName, record.schemaName, {
1789
1817
  id: record.modelFileId, // id is now the schemaFileId (string)
1790
1818
  waitForReady: false,
1819
+ hold: options?.hold,
1791
1820
  });
1792
1821
  modelInstances.push(model);
1793
1822
  }
@@ -1804,22 +1833,27 @@ class Model {
1804
1833
  * Get all Model instances, optionally filtered by schema.
1805
1834
  * When DB is available, loads from DB via getModelsData; otherwise returns from cache.
1806
1835
  * With waitForReady, waits for each model to be ready (idle, with any properties from Model.create
1807
- * created) and leaves out models that error or time out. Takes no holds: a caller that keeps a
1808
- * model uses `Model.find` or `Model.create`.
1836
+ * created) and leaves out models that error or time out. Takes no holds unless `hold: true`.
1809
1837
  */
1810
1838
  static async all(schemaName, options) {
1811
- const { waitForReady = false, readyTimeout = DEFAULT_READY_TIMEOUT_MS } = options ?? {};
1839
+ const { waitForReady = false, readyTimeout = DEFAULT_READY_TIMEOUT_MS, hold = false } = options ?? {};
1840
+ const held = (models) => {
1841
+ if (hold)
1842
+ for (const model of models)
1843
+ this.cache.holdInstance(model);
1844
+ return models;
1845
+ };
1812
1846
  const appDb = BaseDb.getAppDb();
1813
1847
  const inSchema = (model) => !schemaName || model._getSnapshotContext().schemaName === schemaName;
1814
1848
  if (!appDb)
1815
- return this.cache.instances(inSchema);
1849
+ return held(this.cache.instances(inSchema));
1816
1850
  const rows = await getModelsData(schemaName);
1817
1851
  const instances = [];
1818
1852
  const seen = new Set();
1819
1853
  for (const row of rows) {
1820
1854
  // A model can appear more than once (e.g. duplicate model_schemas links); return it once.
1821
1855
  if (row.schemaFileId && !seen.has(row.schemaFileId)) {
1822
- const instance = await this.createById(row.schemaFileId, { hold: false });
1856
+ const instance = await this.createById(row.schemaFileId);
1823
1857
  if (instance && !seen.has(instance.id ?? row.schemaFileId)) {
1824
1858
  instances.push(instance);
1825
1859
  seen.add(instance.id ?? row.schemaFileId);
@@ -1843,9 +1877,17 @@ class Model {
1843
1877
  logger$c(`Model.all: leaving out a model that isn't ready: ${error instanceof Error ? error.message : String(error)}`);
1844
1878
  return false;
1845
1879
  })));
1846
- return instances.filter((_, i) => ready[i]);
1880
+ return held(instances.filter((_, i) => ready[i]));
1847
1881
  }
1848
- return instances;
1882
+ return held(instances);
1883
+ }
1884
+ /** Throws EntityUnloadedError, naming the model, when this instance was destroyed or evicted. */
1885
+ _assertLoaded(action) {
1886
+ if (!isEntityTornDown(this))
1887
+ return;
1888
+ const { modelName, schemaName, id } = this._getSnapshotContext();
1889
+ throw new EntityUnloadedError(`Cannot ${action} model ${schemaName ?? '?'}.${modelName ?? '?'} (${id ?? 'no id'}): this Model instance was ` +
1890
+ 'destroyed or evicted. Look the model up again (Model.find).');
1849
1891
  }
1850
1892
  getService() {
1851
1893
  return this._service;
@@ -2033,6 +2075,7 @@ class Model {
2033
2075
  * @returns The created item instance
2034
2076
  */
2035
2077
  async create(values) {
2078
+ this._assertLoaded('create an item of');
2036
2079
  if (!this.modelName) {
2037
2080
  throw new Error('Cannot create item: model name is not set on this Model instance');
2038
2081
  }
@@ -2049,6 +2092,7 @@ class Model {
2049
2092
  * This refreshes the actor context with the latest data from the database
2050
2093
  */
2051
2094
  async reload() {
2095
+ this._assertLoaded('reload');
2052
2096
  logger$c(`Reloading model ${this.modelName} from database`);
2053
2097
  await runEntityLoad(this, () => Model.load(this));
2054
2098
  if (this.status === 'error')
@@ -2072,7 +2116,10 @@ class Model {
2072
2116
  }
2073
2117
  return evictedNames;
2074
2118
  }
2075
- /** Release this caller's hold. The model is stopped and leaves the cache with its last hold. */
2119
+ /**
2120
+ * Release this caller's hold, if it took one. The model stays cached (see `Model.cache`); only
2121
+ * `destroy`, eviction or client stop stop it.
2122
+ */
2076
2123
  unload() {
2077
2124
  releaseEntity(this, Model.cache);
2078
2125
  }
@@ -2099,9 +2146,9 @@ class Model {
2099
2146
  .limit(1);
2100
2147
  if (modelRecord) {
2101
2148
  const modelId = modelRecord.id;
2102
- const { detachModelRows } = await import('./detachRowsBeforeDelete-sEaUwlOU.js');
2103
- const _mod_11 = await import('./tabEvents-CaVmngqr.js');
2104
- const _ns_11 = _mod_11.bg;
2149
+ const { detachModelRows } = await import('./detachRowsBeforeDelete-BZr_0iZU.js');
2150
+ const _mod_11 = await import('./tabEvents-DT5ez6io.js');
2151
+ const _ns_11 = _mod_11.bj;
2105
2152
  const { inDefinitionsTransaction } = _ns_11;
2106
2153
  // The model's rows go together or not at all
2107
2154
  await inDefinitionsTransaction(async (tx) => {
@@ -2117,10 +2164,10 @@ class Model {
2117
2164
  getModelProperty()?.evictForModel({ modelName, schemaName, modelId: dbId });
2118
2165
  if (schemaName && modelName) {
2119
2166
  // Imported here, not at module load: Model and Schema import each other.
2120
- const _mod_12 = await import('./Schema-J_1f6p0c.js');
2167
+ const _mod_12 = await import('./Schema-BMXRF4j9.js');
2121
2168
  const _ns_12 = _mod_12.a;
2122
2169
  const { Schema } = _ns_12;
2123
- const schema = await Schema.find({ schemaName, waitForReady: false, hold: false });
2170
+ const schema = await Schema.find({ schemaName, waitForReady: false });
2124
2171
  const schemaContext = schema?.getService().getSnapshot().context;
2125
2172
  if (schema && schemaContext?.models?.[modelName]) {
2126
2173
  const updatedModels = { ...schemaContext.models };
@@ -2156,8 +2203,8 @@ class Model {
2156
2203
  return undefined;
2157
2204
  }
2158
2205
  // Model names are only unique per schema: find this model's row by its id (schemaFileId).
2159
- const _mod_13 = await import('./tabEvents-CaVmngqr.js');
2160
- const _ns_13 = _mod_13.be;
2206
+ const _mod_13 = await import('./tabEvents-DT5ez6io.js');
2207
+ const _ns_13 = _mod_13.bh;
2161
2208
  const { resolveModelRecord } = _ns_13;
2162
2209
  const modelRecord = await resolveModelRecord(modelName, { modelFileId: context.id, schemaName: context.schemaName }, db);
2163
2210
  if (!modelRecord?.id) {
@@ -2322,8 +2369,12 @@ class Model {
2322
2369
  }
2323
2370
  }
2324
2371
  }
2325
- /** Cached under its id and `schemaName:modelName` (ADR 0014). */
2326
- Model.cache = new EntityCache();
2372
+ /**
2373
+ * Cached under its id and `schemaName:modelName` (ADR 0014). Stays cached with no holds until it
2374
+ * is destroyed or evicted (`unloadUnheld: false`): Model.resolve, findByModelType and sync read
2375
+ * the cache synchronously.
2376
+ */
2377
+ Model.cache = new EntityCache({ unloadUnheld: false });
2327
2378
 
2328
2379
  var Model$1 = /*#__PURE__*/Object.freeze({
2329
2380
  __proto__: null,
@@ -2534,7 +2585,7 @@ function toRunSyncArg(options) {
2534
2585
  return undefined;
2535
2586
  }
2536
2587
  const runEasSync = fromPromise(async ({ input, }) => {
2537
- const { runSyncFromEas } = await import('./syncDbWithEas-CA7PvBgu.js');
2588
+ const { runSyncFromEas } = await import('./syncDbWithEas-FuyqoEKk.js');
2538
2589
  // Sync checks for rows and then inserts the rest (no unique index on uids), so syncs in
2539
2590
  // different tabs take turns. A sync can run for minutes, so wait without a timeout.
2540
2591
  await withDbTabLock('eas-sync', async () => {
@@ -2867,7 +2918,7 @@ async function platformClassesInit({ event }) {
2867
2918
  if (!config) {
2868
2919
  throw new Error('client.init requires a config');
2869
2920
  }
2870
- const { configurePlatform } = await import('./configurePlatform-CiOJ1R3q.js');
2921
+ const { configurePlatform } = await import('./configurePlatform-WkmvqeTO.js');
2871
2922
  if (isBrowser()) {
2872
2923
  const { createPlatformServices } = await import('./platform.browser.js');
2873
2924
  configurePlatform(createPlatformServices());
@@ -3154,7 +3205,7 @@ async function addModelsToDb(context) {
3154
3205
  timeout = setTimeout(() => reject(new Error('EAS query timeout after 10 seconds')), 10000);
3155
3206
  });
3156
3207
  // The lookup and the model_uids rule sync uses too (each name at its nameMatch level).
3157
- const { getModelSchemasFromEas } = await import('./eas-wB_fQ8Tc.js');
3208
+ const { getModelSchemasFromEas } = await import('./eas-FZPPqxqe.js');
3158
3209
  const lookups = await localModelSchemaLookups([...modelNamesWithRows]);
3159
3210
  // Cleared, so a finished lookup doesn't keep a Node process alive for 10 s.
3160
3211
  const schemas = await Promise.race([getModelSchemasFromEas(lookups), timeoutPromise]).finally(() => clearTimeout(timeout));
@@ -3737,7 +3788,7 @@ function schemaFilePropertyDefinition(modelName, propName, prop) {
3737
3788
  dataType: def.dataType,
3738
3789
  ref: hasRef ? def.ref : undefined,
3739
3790
  refModelName: hasRef ? def.refModelName : undefined,
3740
- refValueType: isList ? def.refValueType : undefined,
3791
+ refValueType: hasRef ? def.refValueType : undefined,
3741
3792
  storageType: def.storageType,
3742
3793
  localStorageDir: def.localStorageDir,
3743
3794
  filenameSuffix: def.filenameSuffix,
@@ -3771,14 +3822,12 @@ async function createModelsForSchemaFile(file) {
3771
3822
  const result = {};
3772
3823
  for (const [modelName, model] of Object.entries(file.models)) {
3773
3824
  const modelFileId = model.id;
3774
- // No hold: a loaded Schema holds its models (loadOrCreateSchema)
3775
3825
  result[modelName] = Model.create(modelName, file.metadata.name, {
3776
3826
  modelFileId,
3777
3827
  id: modelFileId,
3778
3828
  properties: definitions.get(modelName) ?? {},
3779
3829
  waitForReady: false,
3780
3830
  persistedBy: Promise.resolve(),
3781
- hold: false,
3782
3831
  });
3783
3832
  }
3784
3833
  return result;
@@ -3871,8 +3920,8 @@ async function applySchemaFile(source, options = {}) {
3871
3920
  if (!schemaRecord) {
3872
3921
  warnOnEasNameCollisions(file);
3873
3922
  warnOnInvalidNameMatch(file);
3874
- const _mod_14 = await import('./tabEvents-CaVmngqr.js');
3875
- const _ns_14 = _mod_14.bh;
3923
+ const _mod_14 = await import('./tabEvents-DT5ez6io.js');
3924
+ const _ns_14 = _mod_14.bk;
3876
3925
  const { addModelsToDb, broadcastSchemasInvalidate } = _ns_14;
3877
3926
  const modelFileIds = new Map(Object.entries(file.models).map(([name, model]) => [name, model.id]));
3878
3927
  const propertyDefinitions = schemaFilePropertyDefinitions(file);
@@ -4023,8 +4072,8 @@ async function resolveSchemaRow(row, db = BaseDb.getAppDb()) {
4023
4072
  metadata: { ...schema.metadata, name: row.name },
4024
4073
  };
4025
4074
  if (row.id && db) {
4026
- const _mod_15 = await import('./tabEvents-CaVmngqr.js');
4027
- const _ns_15 = _mod_15.bh;
4075
+ const _mod_15 = await import('./tabEvents-DT5ez6io.js');
4076
+ const _ns_15 = _mod_15.bk;
4028
4077
  const { loadModelsFromDbForSchema, mergeDbModelsIntoSchemaModels } = _ns_15;
4029
4078
  const dbModels = await loadModelsFromDbForSchema(row.id, db);
4030
4079
  if (Object.keys(dbModels).length > 0) {
@@ -4603,6 +4652,10 @@ function startCanonicalizeModelTypes() {
4603
4652
  void runInBackground();
4604
4653
  });
4605
4654
  }
4655
+ /** Resolves when a background run has finished (at once if none is running). */
4656
+ function whenCanonicalizeModelTypesSettled() {
4657
+ return running ?? Promise.resolve();
4658
+ }
4606
4659
 
4607
4660
  const getVersionData = async ({ localId, seedLocalId, uid, }, db = BaseDb.getAppDb()) => {
4608
4661
  const appDb = db;
@@ -4955,8 +5008,8 @@ async function applyStorageValue(seedLocalId, propertyName, value, db, prepared)
4955
5008
  const row = prepared
4956
5009
  ? { ...stored, refResolvedValue: prepared.fileName, schemaUid: prepared.schemaUid, refModelUid: prepared.refModelUid }
4957
5010
  : stored;
4958
- const _mod_16 = await import('./Item-Bf4kWKpH.js');
4959
- const _ns_16 = _mod_16.b1;
5011
+ const _mod_16 = await import('./Item-oPnmIehk.js');
5012
+ const _ns_16 = _mod_16.b7;
4960
5013
  const { currentPropertyRow } = _ns_16;
4961
5014
  const existing = await currentPropertyRow({ seedLocalId }, {
4962
5015
  propertyName,
@@ -5269,8 +5322,8 @@ function startItemOutbox() {
5269
5322
  return {};
5270
5323
  // Cached, shared with item creation, so a save doesn't wait on the EAS indexer each time.
5271
5324
  // Not required for the row; publish resolves the schema again.
5272
- const _mod_17 = await import('./Item-Bf4kWKpH.js');
5273
- const _ns_17 = _mod_17.b4;
5325
+ const _mod_17 = await import('./Item-oPnmIehk.js');
5326
+ const _ns_17 = _mod_17.ba;
5274
5327
  const { lookupPropertySchemaUid } = _ns_17;
5275
5328
  return {
5276
5329
  schemaUid: await lookupPropertySchemaUid(op.propertyName, value.propertyRecordSchema),
@@ -6251,23 +6304,52 @@ const ensureInitialized = () => {
6251
6304
  };
6252
6305
  const CLIENT_ALREADY_STOPPED_WARNING = 'client.stop() or client.unload() was called after the client had already stopped; this call does nothing. ' +
6253
6306
  'Remove the extra call, or call client.init() before stopping again.';
6254
- /** Shared by stop() and unload(). A repeat call after a stop warns and does nothing. */
6255
- const stopClient = ({ unsubscribe }) => {
6307
+ /** Set while a stop releases the client's resources; init waits for it. */
6308
+ let stopping;
6309
+ /**
6310
+ * Shared by stop() and unload(). Stops the client in any state, including after a failed or
6311
+ * unfinished init, then releases what it holds: the outbox drain, cached entities, this tab's
6312
+ * leadership and the database (closed, so its file is released). A repeat call after a stop warns
6313
+ * and does nothing.
6314
+ */
6315
+ const stopClient = async ({ unsubscribe }) => {
6256
6316
  if (clientManager.getSnapshot().status === 'stopped') {
6257
6317
  console.warn(CLIENT_ALREADY_STOPPED_WARNING);
6258
6318
  return;
6259
6319
  }
6260
- ensureInitialized();
6261
6320
  activeInitConfig = undefined;
6262
6321
  cancelAllRetriesWhenOnline();
6263
6322
  unregisterSeedQueryLocalSource();
6264
6323
  resetAddressesPersistedAnnouncement();
6324
+ // The next init sets its own period. Instances waiting out this one are evicted with the rest
6325
+ // (releaseClientResources), which cancels their timers.
6326
+ setEntityUnloadGraceMs(undefined);
6265
6327
  clientManager.stop();
6266
6328
  if (unsubscribe)
6267
6329
  subscription.unsubscribe();
6268
6330
  notifyServiceListeners();
6331
+ const releasing = releaseClientResources();
6332
+ stopping = releasing;
6333
+ try {
6334
+ await releasing;
6335
+ }
6336
+ finally {
6337
+ if (stopping === releasing)
6338
+ stopping = undefined;
6339
+ }
6340
+ };
6341
+ const releaseClientResources = async () => {
6342
+ await stopOutbox();
6343
+ await whenCanonicalizeModelTypesSettled();
6344
+ // Before the database closes, so their live queries end first.
6345
+ evictAllEntities();
6346
+ stopTabCoordination();
6347
+ await BaseDb.close();
6269
6348
  };
6270
6349
  const coalescedInit = createCoalescedAsync(async (options) => {
6350
+ // A stop still closing the database: open it again only once that's done.
6351
+ if (stopping)
6352
+ await stopping;
6271
6353
  // If the actor is stopped (e.g., from a previous failed test), restart it
6272
6354
  const snapshot = clientManager.getSnapshot();
6273
6355
  const currentState = snapshot.value;
@@ -6302,6 +6384,7 @@ const coalescedInit = createCoalescedAsync(async (options) => {
6302
6384
  }
6303
6385
  });
6304
6386
  }
6387
+ setEntityUnloadGraceMs(options?.config?.entityCache?.unloadGraceMs);
6305
6388
  // The root-level init handler moves to PLATFORM_CLASSES_INIT (stopping any running step) as
6306
6389
  // send() returns; the platformClassesInit step fills the context from options.
6307
6390
  clientManager.send({ type: 'init', options });
@@ -6487,7 +6570,12 @@ const clientInstance = {
6487
6570
  });
6488
6571
  return () => subscription.unsubscribe();
6489
6572
  },
6573
+ /**
6574
+ * Stops the client, from any state (a failed init too), and closes the database. Resolves once
6575
+ * everything is released; `init` may be called right away and waits for that.
6576
+ */
6490
6577
  stop: () => stopClient({ unsubscribe: false }),
6578
+ /** As `stop`, and also ends the client's internal state subscription. */
6491
6579
  unload: () => stopClient({ unsubscribe: true }),
6492
6580
  };
6493
6581
  // Export the singleton instance
@@ -6547,4 +6635,4 @@ var errors = /*#__PURE__*/Object.freeze({
6547
6635
  });
6548
6636
 
6549
6637
  export { sendEasSyncClientRequest as $, waitForEasReadChain as A, assertLocalDbChain as B, ConflictError as C, writeModelUids as D, getContentHash as E, saveDefinition as F, EAS_CHAIN_ID_APP_STATE_KEY as G, INIT_CONFIG_CONFLICT_MESSAGE as H, ItemCreateValidationError as I, ItemCreateError as J, claimUnpublishedDrafts as K, createLocalQueryDataSource as L, Model as M, easSyncActor as N, getClient as O, getPublishedSeedRecord as P, getSchemaNameFromId as Q, RelationTargetError as R, SCHEMA_FILE_FORMAT as S, TModelSchema as T, UnknownModelError as U, isSeedQueryLocalSourceRegistered as V, listCompleteSchemaFiles as W, mergeEasSyncRequestIntents as X, registerSeedQueryLocalSource as Y, requestEasSyncFromAddressChange as Z, requestEasSyncFromModelsInit as _, applyCreateItem as a, setRetriesWhenOnlineEnabled as a0, startEasSyncActor as a1, unregisterSeedQueryLocalSource as a2, saveDefinition$1 as a3, Model$1 as a4, schema as a5, SEEDPROTOCOL_Seed_Protocol_v1 as a6, itemAppliers as a7, errors as a8, applyDelete as b, applyItemStorageValue as c, deleteFiles as d, applyStorageValue as e, TModelValues as f, ClientManager as g, syncSchemaFromSource as h, importJsonSchema as i, transformImportToSchemaFile as j, localModelSchemaLookups as k, loadSchemaFromFile as l, listLatestSchemaFiles as m, readSchemaFile as n, applySchemaFile as o, resolveSchemaRow as p, loadAllSchemasFromDb as q, readJsonImportFile as r, startItemOutbox as s, throwItemWriteError as t, getDraftSaveError as u, queueDraftSave as v, writeNextSchemaVersion as w, setupEntityLiveQuery as x, mergeSchemaFiles as y, trackDraftSave as z };
6550
- //# sourceMappingURL=errors-DLSoqSHG.js.map
6638
+ //# sourceMappingURL=errors-CnT0fSMK.js.map