@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,10 +1,10 @@
1
1
  import { setup, assign, createActor } from 'xstate';
2
- import { T as applyContextUpdate, U as isInternalUpdate, V as evictionLog, W as holdChild, X as isEntityTornDown, Y as sameEntity, Z as DEFAULT_READY_TIMEOUT_MS, _ as waitForEntityReady, $ as createReactiveProxy, a0 as runEntityLoad, a1 as evictEntities, a2 as entityStatus, a3 as releaseEntity, a4 as destroyEntity, a5 as EntityCache } from './Item-Bf4kWKpH.js';
3
- import { SchemaValidationService } from './SchemaValidationService-CnmKyzR-.js';
4
- import { m as listLatestSchemaFiles, n as readSchemaFile, o as applySchemaFile, p as resolveSchemaRow, S as SCHEMA_FILE_FORMAT, q as loadAllSchemasFromDb, M as Model, u as getDraftSaveError, C as ConflictError, w as writeNextSchemaVersion, v as queueDraftSave, x as setupEntityLiveQuery, y as mergeSchemaFiles, z as trackDraftSave } from './errors-DLSoqSHG.js';
5
- import { B as BaseDb, t as schemas, d as models, j as modelSchemas, l as properties, w as BaseFileManager } from './BaseFileManager-BAlySv8w.js';
2
+ import { T as applyContextUpdate, U as isInternalUpdate, V as evictionLog, W as holdChild, X as isEntityTornDown, Y as sameEntity, Z as DEFAULT_READY_TIMEOUT_MS, _ as createReactiveProxy, $ as runEntityLoad, a0 as waitForEntityReady, a1 as evictEntities, a2 as EntityUnloadedError, a3 as entityStatus, a4 as releaseEntity, a5 as destroyEntity, a6 as EntityCache } from './Item-oPnmIehk.js';
3
+ import { SchemaValidationService } from './SchemaValidationService-CieGrj5c.js';
4
+ import { m as listLatestSchemaFiles, n as readSchemaFile, o as applySchemaFile, p as resolveSchemaRow, S as SCHEMA_FILE_FORMAT, q as loadAllSchemasFromDb, M as Model, u as getDraftSaveError, C as ConflictError, w as writeNextSchemaVersion, v as queueDraftSave, x as setupEntityLiveQuery, y as mergeSchemaFiles, z as trackDraftSave } from './errors-CnT0fSMK.js';
5
+ import { B as BaseDb, t as schemas, d as models, j as modelSchemas, l as properties, w as BaseFileManager } from './BaseFileManager-DLou1TZS.js';
6
6
  import { eq, desc, and, inArray } from 'drizzle-orm';
7
- import { S as SEED_PROTOCOL_SCHEMA_NAME, I as INTERNAL_SCHEMA_IDS, m as generateId, o as addSchemaToDb, p as isInternalSchema, q as inDefinitionsTransaction, s as isClientReady, u as upsertSchemaRow, t as broadcastSchemasInvalidate } from './tabEvents-CaVmngqr.js';
7
+ import { S as SEED_PROTOCOL_SCHEMA_NAME, I as INTERNAL_SCHEMA_IDS, m as generateId, o as addSchemaToDb, p as isInternalSchema, q as inDefinitionsTransaction, s as isClientReady, u as upsertSchemaRow, t as broadcastSchemasInvalidate } from './tabEvents-DT5ez6io.js';
8
8
  import '@seedprotocol/arweave';
9
9
  import 'pluralize';
10
10
  import '@seedprotocol/eas';
@@ -196,7 +196,7 @@ const createModelInstances = async (modelIds, since, owner) => {
196
196
  return;
197
197
  }
198
198
  try {
199
- const _mod_0 = await import('./errors-DLSoqSHG.js');
199
+ const _mod_0 = await import('./errors-CnT0fSMK.js');
200
200
  const _ns_0 = _mod_0.a4;
201
201
  const mod = _ns_0;
202
202
  const Model = mod?.Model ?? mod?.default;
@@ -207,7 +207,7 @@ const createModelInstances = async (modelIds, since, owner) => {
207
207
  const createPromises = modelIds.map(async (modelFileId) => {
208
208
  try {
209
209
  // Not if the schema was evicted (Schema.destroy, test cleanup) since this check started
210
- const model = await Model.createById(modelFileId, { since, hold: false });
210
+ const model = await Model.createById(modelFileId, { since });
211
211
  if (model && owner)
212
212
  holdChild(owner, model, Model.cache);
213
213
  if (model) {
@@ -248,7 +248,7 @@ const findSchemaRow = async (db, schemaName) => {
248
248
  */
249
249
  const createSchema = async (schemaName) => {
250
250
  if (schemaName === SEED_PROTOCOL_SCHEMA_NAME) {
251
- const _mod_1 = await import('./errors-DLSoqSHG.js');
251
+ const _mod_1 = await import('./errors-CnT0fSMK.js');
252
252
  const _ns_1 = _mod_1.a6;
253
253
  const internalSchema = _ns_1;
254
254
  const { schemaFile, schemaRecord } = await applySchemaFile(internalSchema.default, {
@@ -393,7 +393,7 @@ class Schema {
393
393
  }
394
394
  const waitForReady = options?.waitForReady !== false;
395
395
  const readyTimeout = options?.readyTimeout ?? DEFAULT_READY_TIMEOUT_MS;
396
- const holds = options?.hold === false ? 0 : 1;
396
+ const holds = options?.hold === true;
397
397
  // Cached under this name (or file id)
398
398
  const cached = this.cache.peek(schemaName);
399
399
  if (cached) {
@@ -401,7 +401,7 @@ class Schema {
401
401
  this.cache.holdInstance(cached);
402
402
  if (!waitForReady)
403
403
  return cached;
404
- return waitForEntityReady(cached, { timeout: readyTimeout }).then(() => cached);
404
+ return Schema.readyOrRelease(cached, readyTimeout, holds);
405
405
  }
406
406
  // Create new instance
407
407
  const newInstance = new this(schemaName);
@@ -446,6 +446,7 @@ class Schema {
446
446
  };
447
447
  },
448
448
  sendUpdate: (instance, prop, value) => {
449
+ instance._assertLoaded(`set ${prop} on`);
449
450
  // Handle special property updates
450
451
  if (prop === 'name') {
451
452
  // Update both metadata.name and schemaName
@@ -533,26 +534,43 @@ class Schema {
533
534
  }
534
535
  },
535
536
  });
536
- this.cache.add(proxiedInstance, [schemaName], { hold: holds === 1 });
537
+ this.cache.add(proxiedInstance, [schemaName], { hold: holds });
537
538
  void runEntityLoad(proxiedInstance, () => Schema.load(proxiedInstance));
538
539
  if (!waitForReady)
539
540
  return proxiedInstance;
540
- return waitForEntityReady(proxiedInstance, { timeout: readyTimeout }).then(() => proxiedInstance);
541
+ return Schema.readyOrRelease(proxiedInstance, readyTimeout, holds);
542
+ }
543
+ /** The schema once ready; a call that took a hold gives it back when the schema isn't ready in time. */
544
+ static async readyOrRelease(schema, timeout, held) {
545
+ try {
546
+ await waitForEntityReady(schema, { timeout });
547
+ }
548
+ catch (error) {
549
+ if (held)
550
+ schema.unload();
551
+ throw error;
552
+ }
553
+ return schema;
541
554
  }
542
555
  /**
543
- * Get schema instance by schemaFileId (preferred method)
544
- * Returns null if not found in cache
556
+ * The cached schema with this file id, or null. Takes no hold unless `hold: true`.
545
557
  */
546
- static getById(schemaFileId) {
547
- return this.cache.hold(schemaFileId) ?? null;
558
+ static getById(schemaFileId, options) {
559
+ return (options?.hold ? this.cache.hold(schemaFileId) : this.cache.peek(schemaFileId)) ?? null;
548
560
  }
549
561
  /**
550
- * The cached schema with this file id or name, without taking a hold. For SDK code that reads
551
- * the schema and doesn't hand it to a caller; callers that keep it use `create` or `find`.
562
+ * The cached schema with this file id or name, without taking a hold.
552
563
  */
553
564
  static peek(schemaFileIdOrName) {
554
565
  return this.cache.peek(schemaFileIdOrName);
555
566
  }
567
+ /**
568
+ * Takes one more hold on a cached, running instance, released with `unload()`. False (and no
569
+ * hold) when the instance isn't cached or was stopped.
570
+ */
571
+ static retain(instance) {
572
+ return instance.getService().getSnapshot().status === 'active' && this.cache.holdInstance(instance);
573
+ }
556
574
  /** Stop and drop every cached Schema, whoever holds it (test cleanup). */
557
575
  static clearCache() {
558
576
  evictEntities(this.cache, () => true);
@@ -561,16 +579,14 @@ class Schema {
561
579
  * Create or get schema instance by schemaFileId
562
580
  * Queries the database to find the schema name if not cached
563
581
  * @param schemaFileId - The schema file ID
564
- * @returns Schema instance, with a hold taken (unless `hold: false`)
582
+ * @returns Schema instance, with no hold unless `hold: true`
565
583
  */
566
- static async createById(schemaFileId,
567
- /** @internal `hold: false` as for `create` */
568
- options) {
584
+ static async createById(schemaFileId, options) {
569
585
  if (!schemaFileId) {
570
586
  throw new Error('Schema file ID is required');
571
587
  }
572
588
  // First, check if we have an instance cached by ID
573
- const cachedInstance = options?.hold === false ? this.peek(schemaFileId) : this.getById(schemaFileId);
589
+ const cachedInstance = this.getById(schemaFileId, options);
574
590
  if (cachedInstance) {
575
591
  return cachedInstance;
576
592
  }
@@ -594,35 +610,38 @@ class Schema {
594
610
  throw new Error(`Schema with ID "${schemaFileId}" has no name in database`);
595
611
  }
596
612
  // Create schema using the name (this will load from database/file)
597
- return this.create(schemaName, options?.hold === false ? { hold: false } : undefined);
613
+ return this.create(schemaName, options);
598
614
  }
599
615
  /**
600
616
  * Find a schema by schemaFileId or by name. Read-only: a name with no schema row gives undefined
601
617
  * and creates nothing (`Schema.create` creates a draft for an unknown name). By name, the cached
602
618
  * instance is used, else the stored schema is loaded. Waits for the schema to be fully loaded
603
- * (idle state) by default. Takes a hold unless `hold: false`.
619
+ * (idle state) by default. Takes no hold unless `hold: true`.
604
620
  * @returns Schema instance if found, undefined otherwise
605
621
  */
606
- static async find({ schemaFileId, schemaName, waitForReady = true, readyTimeout = DEFAULT_READY_TIMEOUT_MS, hold, }) {
622
+ static async find({ schemaFileId, schemaName, waitForReady = true, readyTimeout = DEFAULT_READY_TIMEOUT_MS, hold = false, }) {
607
623
  if (schemaName) {
608
624
  return this.findByName(schemaName, { waitForReady, readyTimeout, hold });
609
625
  }
610
626
  if (!schemaFileId) {
611
627
  return undefined;
612
628
  }
629
+ let schema;
613
630
  try {
614
- const schema = (hold === false ? Schema.peek(schemaFileId) : (Schema.getById(schemaFileId) ?? undefined)) ??
615
- (await Schema.createById(schemaFileId, hold === false ? { hold: false } : undefined));
631
+ schema = await Schema.createById(schemaFileId, { hold });
616
632
  if (waitForReady)
617
633
  await waitForEntityReady(schema, { timeout: readyTimeout });
618
634
  return schema;
619
635
  }
620
636
  catch {
637
+ // Keeps no hold when it returns nothing
638
+ if (hold)
639
+ schema?.unload();
621
640
  return undefined;
622
641
  }
623
642
  }
624
643
  static async findByName(schemaName, options) {
625
- const createOptions = { readyTimeout: options.readyTimeout, ...(options.hold === false && { hold: false }) };
644
+ const createOptions = { readyTimeout: options.readyTimeout, hold: options.hold };
626
645
  const loadOrCached = () => options.waitForReady
627
646
  ? this.create(schemaName, { ...createOptions, waitForReady: true })
628
647
  : this.create(schemaName, { ...createOptions, waitForReady: false });
@@ -644,7 +663,7 @@ class Schema {
644
663
  * Get instantiated Schema objects for all schemas (from database and files)
645
664
  * By default, returns only the latest version of each schema and excludes the internal Seed Protocol schema.
646
665
  * Uses loadAllSchemasFromDb() as the single source of truth, which intelligently merges database and file data.
647
- * Takes no holds on the instances it returns: a caller that keeps one uses `Schema.create` or `Schema.find`.
666
+ * Takes no holds unless `hold: true`.
648
667
  *
649
668
  * @param options - Configuration options
650
669
  * @param options.includeAllVersions - If true, returns all versions of each schema. Default: false
@@ -652,7 +671,7 @@ class Schema {
652
671
  * @returns Array of Schema instances
653
672
  */
654
673
  static async all(options = {}) {
655
- const { includeAllVersions = false, includeInternal = false, waitForReady = false, readyTimeout = DEFAULT_READY_TIMEOUT_MS, } = options;
674
+ const { includeAllVersions = false, includeInternal = false, waitForReady = false, readyTimeout = DEFAULT_READY_TIMEOUT_MS, hold = false, } = options;
656
675
  // Use loadAllSchemasFromDb as single source of truth
657
676
  // This intelligently merges database and file data, including drafts
658
677
  const allSchemasData = await loadAllSchemasFromDb();
@@ -702,8 +721,7 @@ class Schema {
702
721
  }
703
722
  processedSchemaNames.add(schemaName);
704
723
  // Try to use schemaFileId to ensure we load the correct version
705
- // First check if we have a cached instance by schemaFileId. Schema.all takes no holds: it
706
- // lists schemas (useSchemas caches the list and never unloads it).
724
+ // First check if we have a cached instance by schemaFileId
707
725
  if (schemaFileId) {
708
726
  const cachedById = this.peek(schemaFileId);
709
727
  if (cachedById) {
@@ -730,23 +748,35 @@ class Schema {
730
748
  // But to ensure we get the correct version, we'll use createById if we have the schemaFileId
731
749
  if (schemaFileId) {
732
750
  try {
733
- const instance = await this.createById(schemaFileId, { hold: false });
751
+ const instance = await this.createById(schemaFileId);
734
752
  schemaInstances.push(instance);
735
753
  }
736
754
  catch {
737
755
  // Fallback to creating by name if createById fails
738
- schemaInstances.push(this.create(schemaName, { waitForReady: false, hold: false }));
756
+ schemaInstances.push(this.create(schemaName, { waitForReady: false }));
739
757
  }
740
758
  }
741
759
  else {
742
- schemaInstances.push(this.create(schemaName, { waitForReady: false, hold: false }));
760
+ schemaInstances.push(this.create(schemaName, { waitForReady: false }));
743
761
  }
744
762
  }
745
763
  if (waitForReady && schemaInstances.length > 0) {
746
764
  await Promise.all(schemaInstances.map((schema) => waitForEntityReady(schema, { timeout: readyTimeout })));
747
765
  }
766
+ // Once nothing can throw, so a failed call keeps no holds
767
+ if (hold)
768
+ for (const schema of schemaInstances)
769
+ this.cache.holdInstance(schema);
748
770
  return schemaInstances;
749
771
  }
772
+ /** Throws EntityUnloadedError, naming the schema, when this instance was destroyed or evicted. */
773
+ _assertLoaded(action) {
774
+ if (!isEntityTornDown(this))
775
+ return;
776
+ const { schemaName, metadata, id } = this._getSnapshotContext();
777
+ throw new EntityUnloadedError(`Cannot ${action} schema ${metadata?.name ?? schemaName ?? '?'} (${id ?? 'no id'}): this Schema instance was ` +
778
+ 'destroyed or evicted. Look the schema up again (Schema.find).');
779
+ }
750
780
  getService() {
751
781
  return this._service;
752
782
  }
@@ -874,8 +904,8 @@ class Schema {
874
904
  */
875
905
  async _buildModelsFromInstances() {
876
906
  const context = this._getSnapshotContext();
877
- const _mod_2 = await import('./index-DmTtj1nk.js');
878
- const _ns_2 = _mod_2.j;
907
+ const _mod_2 = await import('./index-Gh42_47r.js');
908
+ const _ns_2 = _mod_2.k;
879
909
  const { convertPropertyToSchemaUpdate } = _ns_2;
880
910
  const models = {};
881
911
  for (const modelInstance of this.models) {
@@ -890,7 +920,7 @@ class Schema {
890
920
  const modelDbId = modelInstance.getService().getSnapshot().context._dbId;
891
921
  const db = BaseDb.getAppDb();
892
922
  if (propertyContexts.length === 0 && modelDbId && db) {
893
- const { ModelProperty } = await import('./ModelProperty-BlaEgb_U.js');
923
+ const { ModelProperty } = await import('./ModelProperty-D2vJozmW.js');
894
924
  const rows = await db.select().from(properties).where(eq(properties.modelId, modelDbId));
895
925
  propertyContexts = rows.map((row) => {
896
926
  const cached = row.schemaFileId ? ModelProperty.getById(row.schemaFileId) : undefined;
@@ -951,6 +981,7 @@ class Schema {
951
981
  * @returns The file path of the new schema version
952
982
  */
953
983
  async saveNewVersion() {
984
+ this._assertLoaded('save a new version of');
954
985
  // Check for conflicts before saving
955
986
  const conflictCheck = await this._checkForConflicts();
956
987
  if (conflictCheck.hasConflict) {
@@ -1019,7 +1050,7 @@ class Schema {
1019
1050
  });
1020
1051
  // Clear edited flags on the cached ModelProperty instances of the edited keys, then on the rows
1021
1052
  // (schema, those properties, the schema's models) in one transaction.
1022
- const { ModelProperty } = await import('./ModelProperty-BlaEgb_U.js');
1053
+ const { ModelProperty } = await import('./ModelProperty-D2vJozmW.js');
1023
1054
  const thisSchemaName = this.schemaName;
1024
1055
  const clearedKeys = [];
1025
1056
  for (const propertyKey of context._editedProperties) {
@@ -1038,8 +1069,8 @@ class Schema {
1038
1069
  cachedInstance.getService().send({ type: 'clearEdited' });
1039
1070
  clearedKeys.push({ modelName, propertyName });
1040
1071
  }
1041
- const _mod_3 = await import('./tabEvents-CaVmngqr.js');
1042
- const _ns_3 = _mod_3.be;
1072
+ const _mod_3 = await import('./tabEvents-DT5ez6io.js');
1073
+ const _ns_3 = _mod_3.bh;
1043
1074
  const { resolveModelRecord } = _ns_3;
1044
1075
  await inDefinitionsTransaction(async (tx) => {
1045
1076
  await tx
@@ -1124,6 +1155,7 @@ class Schema {
1124
1155
  * This refreshes the actor context with the latest data from the database
1125
1156
  */
1126
1157
  async reload() {
1158
+ this._assertLoaded('reload');
1127
1159
  logger(`Reloading schema ${this.schemaName} from database`);
1128
1160
  await runEntityLoad(this, () => Schema.load(this));
1129
1161
  if (this.status === 'error')
@@ -1283,8 +1315,8 @@ class Schema {
1283
1315
  evictEntities(this.cache, (schema) => schema._getSnapshotContext().schemaName === schemaName);
1284
1316
  }
1285
1317
  /**
1286
- * Release this caller's hold. With the last one the schema is stopped, leaves the cache, and
1287
- * releases its hold on each of its models.
1318
+ * Release this caller's hold, if it took one. The schema stays cached (see `Schema.cache`); only
1319
+ * `destroy`, eviction or client stop stop it.
1288
1320
  */
1289
1321
  unload() {
1290
1322
  releaseEntity(this, Schema.cache);
@@ -1315,10 +1347,10 @@ class Schema {
1315
1347
  // instances too, or a re-import would get them back with dangling _dbIds.
1316
1348
  if (schemaName) {
1317
1349
  const evictedModelNames = Model.evictForSchema(schemaName);
1318
- const { ModelProperty } = await import('./ModelProperty-BlaEgb_U.js');
1350
+ const { ModelProperty } = await import('./ModelProperty-D2vJozmW.js');
1319
1351
  ModelProperty.evictForModels(evictedModelNames, schemaName);
1320
1352
  // Evicting stops new writes but not ones already running; let those land before deleting their rows
1321
- const _mod_4 = await import('./errors-DLSoqSHG.js');
1353
+ const _mod_4 = await import('./errors-CnT0fSMK.js');
1322
1354
  const _ns_4 = _mod_4.a3;
1323
1355
  const { waitForInFlightWrites } = _ns_4;
1324
1356
  await waitForInFlightWrites();
@@ -1327,7 +1359,7 @@ class Schema {
1327
1359
  const db = BaseDb.getAppDb();
1328
1360
  if (!db || !schemaFileId)
1329
1361
  return;
1330
- const { detachModelRows } = await import('./detachRowsBeforeDelete-sEaUwlOU.js');
1362
+ const { detachModelRows } = await import('./detachRowsBeforeDelete-BZr_0iZU.js');
1331
1363
  // The schema's rows go together or not at all
1332
1364
  const deleted = await inDefinitionsTransaction(async (tx) => {
1333
1365
  const schemaRecords = await tx
@@ -1368,7 +1400,7 @@ class Schema {
1368
1400
  // the destroyed schema back on the next Schema.all().
1369
1401
  // Match on name as well as id: versions imported from complete schema files can each
1370
1402
  // have their own id, and any version left behind would bring the schema back.
1371
- const _mod_5 = await import('./errors-DLSoqSHG.js');
1403
+ const _mod_5 = await import('./errors-CnT0fSMK.js');
1372
1404
  const _ns_5 = _mod_5.a5;
1373
1405
  const { listCompleteSchemaFiles } = _ns_5;
1374
1406
  const files = await listCompleteSchemaFiles().catch(() => []);
@@ -1416,7 +1448,7 @@ class Schema {
1416
1448
  // One at a time: an eviction of this schema part way through stops the rest
1417
1449
  const since = evictionLog.now();
1418
1450
  for (const id of ids) {
1419
- await Model.createById(id, { since, hold: false });
1451
+ await Model.createById(id, { since });
1420
1452
  }
1421
1453
  },
1422
1454
  queryInitialData: async (schemaId) => {
@@ -1444,8 +1476,12 @@ class Schema {
1444
1476
  });
1445
1477
  }
1446
1478
  }
1447
- /** Cached under its file id and its name (ADR 0014). */
1448
- Schema.cache = new EntityCache();
1479
+ /**
1480
+ * Cached under its file id and its name (ADR 0014). A schema stays cached with no holds until it
1481
+ * is destroyed or evicted, or the client stops (`unloadUnheld: false`): sync and name matching
1482
+ * read the cached definitions synchronously.
1483
+ */
1484
+ Schema.cache = new EntityCache({ unloadUnheld: false });
1449
1485
 
1450
1486
  var Schema$1 = /*#__PURE__*/Object.freeze({
1451
1487
  __proto__: null,
@@ -1453,4 +1489,4 @@ var Schema$1 = /*#__PURE__*/Object.freeze({
1453
1489
  });
1454
1490
 
1455
1491
  export { Schema as S, Schema$1 as a, schemaMachine as s };
1456
- //# sourceMappingURL=Schema-J_1f6p0c.js.map
1492
+ //# sourceMappingURL=Schema-BMXRF4j9.js.map