@seedprotocol/sdk 0.7.3-next.613.g79a8dfd → 0.7.3-next.654.g52217f6

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 (164) hide show
  1. package/dist/{BasePathResolver-BdxCSIzn.js → BasePathResolver-CfSfMW5_.js} +7 -10
  2. package/dist/BasePathResolver-CfSfMW5_.js.map +1 -0
  3. package/dist/{ClientManager-DDA9956Y.js → ClientManager-C-QXqUK9.js} +438 -153
  4. package/dist/ClientManager-C-QXqUK9.js.map +1 -0
  5. package/dist/{Item-D4FigtYS.js → Item-C7sUUu2B.js} +291 -105
  6. package/dist/Item-C7sUUu2B.js.map +1 -0
  7. package/dist/{ModelProperty-BDt6AU2h.js → ModelProperty-DJxeOOrc.js} +28 -27
  8. package/dist/ModelProperty-DJxeOOrc.js.map +1 -0
  9. package/dist/{Schema-B8xqLWkL.js → Schema-fXtvd-yL.js} +30 -30
  10. package/dist/{Schema-B8xqLWkL.js.map → Schema-fXtvd-yL.js.map} +1 -1
  11. package/dist/{SchemaValidationService-BPxkfDLU.js → SchemaValidationService-CvRS2HSO.js} +10 -9
  12. package/dist/{SchemaValidationService-BPxkfDLU.js.map → SchemaValidationService-CvRS2HSO.js.map} +1 -1
  13. package/dist/{backfillMetadataPropertyIds-DuTPcv8t.js → backfillMetadataPropertyIds-SXW-8C64.js} +4 -4
  14. package/dist/{backfillMetadataPropertyIds-DuTPcv8t.js.map → backfillMetadataPropertyIds-SXW-8C64.js.map} +1 -1
  15. package/dist/cjs/{ModelProperty-B-cZm1yU.js → ModelProperty-DXZ39Wyv.js} +24 -23
  16. package/dist/cjs/{ModelProperty-B-cZm1yU.js.map → ModelProperty-DXZ39Wyv.js.map} +1 -1
  17. package/dist/cjs/{Schema-STP972Xw.js → Schema-DdP109QD.js} +26 -25
  18. package/dist/cjs/{Schema-STP972Xw.js.map → Schema-DdP109QD.js.map} +1 -1
  19. package/dist/cjs/{SchemaValidationService-CKNW1bKg.js → SchemaValidationService-CSXxx7sQ.js} +5 -4
  20. package/dist/cjs/{SchemaValidationService-CKNW1bKg.js.map → SchemaValidationService-CSXxx7sQ.js.map} +1 -1
  21. package/dist/cjs/{backfillMetadataPropertyIds-CP3y1skt.js → backfillMetadataPropertyIds-CPYoaMl4.js} +6 -5
  22. package/dist/cjs/{backfillMetadataPropertyIds-CP3y1skt.js.map → backfillMetadataPropertyIds-CPYoaMl4.js.map} +1 -1
  23. package/dist/cjs/{eas-CAnUC4wd.js → eas-B2YDQssV.js} +6 -5
  24. package/dist/cjs/{eas-CAnUC4wd.js.map → eas-B2YDQssV.js.map} +1 -1
  25. package/dist/cjs/{getItem-CWgb3e9G.js → getItem-DgnaQzbE.js} +5 -4
  26. package/dist/cjs/{getItem-CWgb3e9G.js.map → getItem-DgnaQzbE.js.map} +1 -1
  27. package/dist/cjs/{getPublishPayload-BsZWiJ03.js → getPublishPayload-CqlqRdot.js} +12 -11
  28. package/dist/cjs/{getPublishPayload-BsZWiJ03.js.map → getPublishPayload-CqlqRdot.js.map} +1 -1
  29. package/dist/cjs/getPublishUploads-DsXY9S4U.js +872 -0
  30. package/dist/cjs/getPublishUploads-DsXY9S4U.js.map +1 -0
  31. package/dist/cjs/{index-nA5PxBSs.js → index-BHaWOwNF.js} +6 -5
  32. package/dist/cjs/index-BHaWOwNF.js.map +1 -0
  33. package/dist/cjs/{index-usKaANAq.js → index-C4XlgCJ4.js} +1156 -526
  34. package/dist/cjs/index-C4XlgCJ4.js.map +1 -0
  35. package/dist/cjs/{property-xMwPhQ5N.js → property-fa0iju0J.js} +8 -7
  36. package/dist/cjs/{property-xMwPhQ5N.js.map → property-fa0iju0J.js.map} +1 -1
  37. package/dist/cjs/{publishDraftGraph-BRWlR1KO.js → publishDraftGraph-3ASwAlD7.js} +4 -4
  38. package/dist/cjs/{publishDraftGraph-BRWlR1KO.js.map → publishDraftGraph-3ASwAlD7.js.map} +1 -1
  39. package/dist/cjs/{resetAmbiguousLegacyItemData-8nfkj9rz.js → resetAmbiguousLegacyItemData-Bu_MBBYt.js} +5 -4
  40. package/dist/cjs/{resetAmbiguousLegacyItemData-8nfkj9rz.js.map → resetAmbiguousLegacyItemData-Bu_MBBYt.js.map} +1 -1
  41. package/dist/cjs/{resolveModelForSyncedSeed-kYRuDWYw.js → resolveModelForSyncedSeed-BANIiuFU.js} +2 -2
  42. package/dist/cjs/{resolveModelForSyncedSeed-kYRuDWYw.js.map → resolveModelForSyncedSeed-BANIiuFU.js.map} +1 -1
  43. package/dist/cjs/{syncDbWithEas-DqRhV8o2.js → syncDbWithEas-CrmxxmUW.js} +10 -9
  44. package/dist/cjs/{syncDbWithEas-DqRhV8o2.js.map → syncDbWithEas-CrmxxmUW.js.map} +1 -1
  45. package/dist/{configurePlatform-YcOiDQBZ.js → configurePlatform-BRw2j0ZN.js} +7 -4
  46. package/dist/{configurePlatform-YcOiDQBZ.js.map → configurePlatform-BRw2j0ZN.js.map} +1 -1
  47. package/dist/{db-CQt-gcAl.js → db-D9K_f5cF.js} +14 -14
  48. package/dist/{db-CQt-gcAl.js.map → db-D9K_f5cF.js.map} +1 -1
  49. package/dist/{eas-CpOD74Ke.js → eas-DHxfswCt.js} +8 -5
  50. package/dist/eas-DHxfswCt.js.map +1 -0
  51. package/dist/{getItem-B_OoFkd7.js → getItem-d6N_aM6S.js} +8 -5
  52. package/dist/{getItem-B_OoFkd7.js.map → getItem-d6N_aM6S.js.map} +1 -1
  53. package/dist/{getPublishPayload-Xl3sRkR-.js → getPublishPayload-BHrxVtzY.js} +16 -16
  54. package/dist/{getPublishPayload-Xl3sRkR-.js.map → getPublishPayload-BHrxVtzY.js.map} +1 -1
  55. package/dist/getPublishUploads-BEqRiKIS.js +657 -0
  56. package/dist/getPublishUploads-BEqRiKIS.js.map +1 -0
  57. package/dist/{index-BGt4_oPO.js → index-CiMEoGu3.js} +12 -11
  58. package/dist/index-CiMEoGu3.js.map +1 -0
  59. package/dist/{index-CSOQFAOn.js → index-DglvthOk.js} +2 -2
  60. package/dist/index-DglvthOk.js.map +1 -0
  61. package/dist/{index-Xl1_4Lmb.js → index-s15q14rm.js} +29 -29
  62. package/dist/{index-Xl1_4Lmb.js.map → index-s15q14rm.js.map} +1 -1
  63. package/dist/{index.browser-CjTe0vt1.js → index.browser-Cm06tP4X.js} +553 -165
  64. package/dist/index.browser-Cm06tP4X.js.map +1 -0
  65. package/dist/{index.node-Cfa7npS6.js → index.node-C30dmFgn.js} +5 -5
  66. package/dist/{index.node-Cfa7npS6.js.map → index.node-C30dmFgn.js.map} +1 -1
  67. package/dist/main.cjs +4 -3
  68. package/dist/main.cjs.map +1 -1
  69. package/dist/main.js +32 -44
  70. package/dist/main.js.map +1 -1
  71. package/dist/mimeTypes-DHAHC4eZ.js +204 -0
  72. package/dist/mimeTypes-DHAHC4eZ.js.map +1 -0
  73. package/dist/node.js +13 -12
  74. package/dist/node.js.map +1 -1
  75. package/dist/platform.browser.js +9 -7
  76. package/dist/platform.browser.js.map +1 -1
  77. package/dist/platform.node.js +3 -3
  78. package/dist/{property-BrXkY1Rg.js → property-DhmmYAvQ.js} +12 -9
  79. package/dist/property-DhmmYAvQ.js.map +1 -0
  80. package/dist/{publishDraftGraph-X0Wr9txE.js → publishDraftGraph-yYP74WRt.js} +8 -8
  81. package/dist/{publishDraftGraph-X0Wr9txE.js.map → publishDraftGraph-yYP74WRt.js.map} +1 -1
  82. package/dist/{resetAmbiguousLegacyItemData-Ci6PM_vC.js → resetAmbiguousLegacyItemData-Bk0QyDW8.js} +2 -2
  83. package/dist/{resetAmbiguousLegacyItemData-Ci6PM_vC.js.map → resetAmbiguousLegacyItemData-Bk0QyDW8.js.map} +1 -1
  84. package/dist/{resolveModelForSyncedSeed-DFVdnYq8.js → resolveModelForSyncedSeed-8cAzvUFd.js} +2 -2
  85. package/dist/{resolveModelForSyncedSeed-DFVdnYq8.js.map → resolveModelForSyncedSeed-8cAzvUFd.js.map} +1 -1
  86. package/dist/src/Item/Item.d.ts +1 -1
  87. package/dist/src/Item/Item.d.ts.map +1 -1
  88. package/dist/src/ItemProperty/service/actors/saveValueToDb/saveItemStorage.d.ts.map +1 -1
  89. package/dist/src/browser/helpers/FileManager.d.ts +4 -1
  90. package/dist/src/browser/helpers/FileManager.d.ts.map +1 -1
  91. package/dist/src/browser/helpers/tolerantWebAccess.d.ts +79 -4
  92. package/dist/src/browser/helpers/tolerantWebAccess.d.ts.map +1 -1
  93. package/dist/src/browser/workers/FileDownloader.d.ts +19 -4
  94. package/dist/src/browser/workers/FileDownloader.d.ts.map +1 -1
  95. package/dist/src/browser/workers/filesDownload.d.ts.map +1 -1
  96. package/dist/src/client/clientManagerMachine.d.ts.map +1 -1
  97. package/dist/src/db/migrateLegacyItemStorageRows.d.ts +57 -0
  98. package/dist/src/db/migrateLegacyItemStorageRows.d.ts.map +1 -0
  99. package/dist/src/db/read/getCompositeChildPaths.d.ts +13 -0
  100. package/dist/src/db/read/getCompositeChildPaths.d.ts.map +1 -0
  101. package/dist/src/db/read/getItems.d.ts.map +1 -1
  102. package/dist/src/db/read/getPublishUploads.d.ts +32 -3
  103. package/dist/src/db/read/getPublishUploads.d.ts.map +1 -1
  104. package/dist/src/db/read/summarizePublishWork.d.ts.map +1 -1
  105. package/dist/src/db/write/convertVerbatimItemStorageRow.d.ts +44 -0
  106. package/dist/src/db/write/convertVerbatimItemStorageRow.d.ts.map +1 -0
  107. package/dist/src/db/write/createNewItem.d.ts.map +1 -1
  108. package/dist/src/events/files/download.d.ts.map +1 -1
  109. package/dist/src/helpers/FileManager/BaseFileManager.d.ts +3 -3
  110. package/dist/src/helpers/FileManager/BaseFileManager.d.ts.map +1 -1
  111. package/dist/src/helpers/FileManager/IFileManager.d.ts +25 -1
  112. package/dist/src/helpers/FileManager/IFileManager.d.ts.map +1 -1
  113. package/dist/src/helpers/arweaveContentTags.d.ts +33 -0
  114. package/dist/src/helpers/arweaveContentTags.d.ts.map +1 -0
  115. package/dist/src/helpers/compositeUpload.d.ts +28 -0
  116. package/dist/src/helpers/compositeUpload.d.ts.map +1 -0
  117. package/dist/src/helpers/itemStorageFile.d.ts +57 -0
  118. package/dist/src/helpers/itemStorageFile.d.ts.map +1 -0
  119. package/dist/src/helpers/mapWithConcurrency.d.ts +7 -0
  120. package/dist/src/helpers/mapWithConcurrency.d.ts.map +1 -0
  121. package/dist/src/helpers/mimeTypes.d.ts +43 -0
  122. package/dist/src/helpers/mimeTypes.d.ts.map +1 -0
  123. package/dist/src/helpers/ownership.d.ts +19 -3
  124. package/dist/src/helpers/ownership.d.ts.map +1 -1
  125. package/dist/src/helpers/storageDir.d.ts +16 -0
  126. package/dist/src/helpers/storageDir.d.ts.map +1 -0
  127. package/dist/src/helpers/tabCoordinator.d.ts +5 -1
  128. package/dist/src/helpers/tabCoordinator.d.ts.map +1 -1
  129. package/dist/src/helpers/tabEvents.d.ts +23 -2
  130. package/dist/src/helpers/tabEvents.d.ts.map +1 -1
  131. package/dist/src/index.d.ts +6 -4
  132. package/dist/src/index.d.ts.map +1 -1
  133. package/dist/src/types/fileManager.d.ts +3 -14
  134. package/dist/src/types/fileManager.d.ts.map +1 -1
  135. package/dist/src/types/publish.d.ts +14 -0
  136. package/dist/src/types/publish.d.ts.map +1 -1
  137. package/dist/{syncDbWithEas-BU-jZ5bJ.js → syncDbWithEas--HUA9WNb.js} +15 -14
  138. package/dist/syncDbWithEas--HUA9WNb.js.map +1 -0
  139. package/dist/{tabEvents-BZJMY5uK.js → tabEvents-DguZpCCv.js} +294 -58
  140. package/dist/tabEvents-DguZpCCv.js.map +1 -0
  141. package/dist/tolerantWebAccess-BZYWt09Y.js +551 -0
  142. package/dist/tolerantWebAccess-BZYWt09Y.js.map +1 -0
  143. package/dist/{updateSeedRevokedAt-iLpzae1i.js → updateSeedRevokedAt-D_EG-q3b.js} +3 -3
  144. package/dist/{updateSeedRevokedAt-iLpzae1i.js.map → updateSeedRevokedAt-D_EG-q3b.js.map} +1 -1
  145. package/package.json +5 -5
  146. package/dist/BasePathResolver-BdxCSIzn.js.map +0 -1
  147. package/dist/ClientManager-DDA9956Y.js.map +0 -1
  148. package/dist/Item-D4FigtYS.js.map +0 -1
  149. package/dist/ModelProperty-BDt6AU2h.js.map +0 -1
  150. package/dist/cjs/getPublishUploads-BQr8aMVP.js +0 -495
  151. package/dist/cjs/getPublishUploads-BQr8aMVP.js.map +0 -1
  152. package/dist/cjs/index-nA5PxBSs.js.map +0 -1
  153. package/dist/cjs/index-usKaANAq.js.map +0 -1
  154. package/dist/eas-CpOD74Ke.js.map +0 -1
  155. package/dist/getPublishUploads-DHP01KgU.js +0 -484
  156. package/dist/getPublishUploads-DHP01KgU.js.map +0 -1
  157. package/dist/index-BGt4_oPO.js.map +0 -1
  158. package/dist/index-CSOQFAOn.js.map +0 -1
  159. package/dist/index.browser-CjTe0vt1.js.map +0 -1
  160. package/dist/property-BrXkY1Rg.js.map +0 -1
  161. package/dist/syncDbWithEas-BU-jZ5bJ.js.map +0 -1
  162. package/dist/tabEvents-BZJMY5uK.js.map +0 -1
  163. package/dist/tolerantWebAccess-BZ2RA_mb.js +0 -160
  164. package/dist/tolerantWebAccess-BZ2RA_mb.js.map +0 -1
@@ -12,12 +12,13 @@ var pluralize = require('pluralize');
12
12
  var typebox = require('@sinclair/typebox');
13
13
  var casing = require('drizzle-orm/casing');
14
14
  var lodashEs = require('lodash-es');
15
+ var sha256 = require('@noble/hashes/sha256');
16
+ var sha3 = require('@noble/hashes/sha3');
17
+ var utils = require('@noble/hashes/utils');
15
18
  var nanoid = require('nanoid');
16
19
  var nanoidDictionary = require('nanoid-dictionary');
17
20
  var query = require('@seedprotocol/query');
18
21
  var rxjs = require('rxjs');
19
- var sha3 = require('@noble/hashes/sha3');
20
- var utils = require('@noble/hashes/utils');
21
22
  var fsAsync = require('fs/promises');
22
23
  var fs = require('fs');
23
24
  var path = require('path');
@@ -210,20 +211,17 @@ class BaseFileManager {
210
211
  static getContentUrlFromPath(path) {
211
212
  return BaseFileManager.requireImpl().getContentUrlFromPath(path);
212
213
  }
213
- static downloadAllFiles({ transactionIds, arweaveHost, arweaveBaseUrls, excludedTransactions, }) {
214
- return BaseFileManager.requireImpl().downloadAllFiles({
215
- transactionIds,
216
- arweaveHost,
217
- arweaveBaseUrls,
218
- excludedTransactions,
219
- });
214
+ static downloadAllFiles(params) {
215
+ return BaseFileManager.requireImpl().downloadAllFiles(params);
220
216
  }
221
- static downloadFileByTransactionId({ transactionId, arweaveHost, arweaveBaseUrls, excludedTransactions, }) {
217
+ static downloadFileByTransactionId({ transactionId, arweaveHost, arweaveBaseUrls, excludedTransactions, expectedContentHash, compositeChildPaths, }) {
222
218
  return BaseFileManager.requireImpl().downloadAllFiles({
223
219
  transactionIds: [transactionId],
224
220
  arweaveHost,
225
221
  arweaveBaseUrls,
226
222
  excludedTransactions,
223
+ expectedContentHashes: expectedContentHash ? { [transactionId]: expectedContentHash } : undefined,
224
+ compositeChildPaths: compositeChildPaths ? { [transactionId]: compositeChildPaths } : undefined,
227
225
  });
228
226
  }
229
227
  static resizeImage({ filePath, width, height }) {
@@ -1508,7 +1506,7 @@ function linkModelToSchema(db, modelId, schemaId) {
1508
1506
  return current;
1509
1507
  }
1510
1508
 
1511
- const logger$A = debug('seedSdk:helpers:db');
1509
+ const logger$B = debug('seedSdk:helpers:db');
1512
1510
  /**
1513
1511
  * The `properties` storage columns for a property definition, in either the internal shape
1514
1512
  * (`storageType`, `localStorageDir`, `filenameSuffix`) or the schema-file shape
@@ -1614,7 +1612,7 @@ async function getItemStoragePropertiesForModel(modelNameOrType, scope = {}) {
1614
1612
  async function migrateMetadataForPropertyRename(modelName, oldPropertyName, newPropertyName, propertySchemaFileId, scope = {}) {
1615
1613
  const db = BaseDb.getAppDb();
1616
1614
  if (!db) {
1617
- logger$A('[migrateMetadataForPropertyRename] Database not available, skipping');
1615
+ logger$B('[migrateMetadataForPropertyRename] Database not available, skipping');
1618
1616
  return 0;
1619
1617
  }
1620
1618
  // Find the property row by schemaFileId (preferred) or by name
@@ -1626,7 +1624,7 @@ async function migrateMetadataForPropertyRename(modelName, oldPropertyName, newP
1626
1624
  propertyId = await getPropertyIdForModelAndName(modelName, oldPropertyName, scope);
1627
1625
  }
1628
1626
  if (propertyId == null) {
1629
- logger$A(`[migrateMetadataForPropertyRename] Property not found: ${modelName}.${oldPropertyName}, skipping`);
1627
+ logger$B(`[migrateMetadataForPropertyRename] Property not found: ${modelName}.${oldPropertyName}, skipping`);
1630
1628
  return 0;
1631
1629
  }
1632
1630
  // Primary path: update metadata by propertyId
@@ -1655,11 +1653,11 @@ async function migrateMetadataForPropertyRename(modelName, oldPropertyName, newP
1655
1653
  .where(drizzleOrm.and(drizzleOrm.eq(metadata$1.propertyName, oldPropertyName), drizzleOrm.eq(metadata$1.modelType, modelType), drizzleOrm.isNull(metadata$1.propertyId)));
1656
1654
  }
1657
1655
  if (updatedByFallback > 0) {
1658
- logger$A(`[migrateMetadataForPropertyRename] Fallback updated ${updatedByFallback} rows (propertyId was null)`);
1656
+ logger$B(`[migrateMetadataForPropertyRename] Fallback updated ${updatedByFallback} rows (propertyId was null)`);
1659
1657
  }
1660
1658
  const total = updatedByPropertyId + updatedByFallback;
1661
1659
  if (total > 0) {
1662
- logger$A(`[migrateMetadataForPropertyRename] Migrated ${total} metadata rows for ${modelName}.${oldPropertyName} -> ${newPropertyName}`);
1660
+ logger$B(`[migrateMetadataForPropertyRename] Migrated ${total} metadata rows for ${modelName}.${oldPropertyName} -> ${newPropertyName}`);
1663
1661
  }
1664
1662
  return total;
1665
1663
  }
@@ -1808,7 +1806,7 @@ const findOrCreateModelRecord = async (db, modelName, modelFileId, schemaId) =>
1808
1806
  .set({ schemaFileId: modelFileId, isEdited: false })
1809
1807
  .where(drizzleOrm.eq(models$1.id, chosen.id));
1810
1808
  chosen = { ...chosen, schemaFileId: modelFileId, isEdited: false };
1811
- logger$A(`Adopted existing model "${modelName}" (id: ${chosen.id}) with schemaFileId "${modelFileId}"`);
1809
+ logger$B(`Adopted existing model "${modelName}" (id: ${chosen.id}) with schemaFileId "${modelFileId}"`);
1812
1810
  }
1813
1811
  if (chosen) {
1814
1812
  return chosen;
@@ -2079,7 +2077,7 @@ const addSchemaToDb = async (schema, schemaFileId, schemaData, isDraft, isEdited
2079
2077
  .limit(1);
2080
2078
  if (draftSchemas.length > 0) {
2081
2079
  // Found a draft - we'll update it to non-draft below
2082
- logger$A(`Found draft schema "${schema.name}" with schemaFileId "${draftSchemas[0].schemaFileId}", will update to non-draft with schemaFileId "${schemaFileId}"`);
2080
+ logger$B(`Found draft schema "${schema.name}" with schemaFileId "${draftSchemas[0].schemaFileId}", will update to non-draft with schemaFileId "${schemaFileId}"`);
2083
2081
  existingSchemas = draftSchemas;
2084
2082
  }
2085
2083
  }
@@ -2099,11 +2097,11 @@ const addSchemaToDb = async (schema, schemaFileId, schemaData, isDraft, isEdited
2099
2097
  !existingSchemas[0].schemaFileId ||
2100
2098
  (isDraft === false && existingSchemas[0].isDraft === true);
2101
2099
  if (shouldUpdate) {
2102
- logger$A(`Updating schemaFileId from "${existingSchemas[0].schemaFileId}" to "${schemaFileId}" for schema "${schema.name}"`);
2100
+ logger$B(`Updating schemaFileId from "${existingSchemas[0].schemaFileId}" to "${schemaFileId}" for schema "${schema.name}"`);
2103
2101
  updates.schemaFileId = schemaFileId;
2104
2102
  }
2105
2103
  else {
2106
- logger$A(`Preserving existing schemaFileId "${existingSchemas[0].schemaFileId}" for non-draft schema "${schema.name}" (new schemaFileId "${schemaFileId}" would overwrite it)`);
2104
+ logger$B(`Preserving existing schemaFileId "${existingSchemas[0].schemaFileId}" for non-draft schema "${schema.name}" (new schemaFileId "${schemaFileId}" would overwrite it)`);
2107
2105
  }
2108
2106
  }
2109
2107
  // Always update name if it's different (handles name changes)
@@ -2130,16 +2128,16 @@ const addSchemaToDb = async (schema, schemaFileId, schemaData, isDraft, isEdited
2130
2128
  updates.updatedAt = schema.updatedAt;
2131
2129
  }
2132
2130
  if (Object.keys(updates).length > 0) {
2133
- logger$A(`Applying updates to schema "${schema.name}" (id: ${existingSchemas[0].id}):`, Object.keys(updates));
2131
+ logger$B(`Applying updates to schema "${schema.name}" (id: ${existingSchemas[0].id}):`, Object.keys(updates));
2134
2132
  await db
2135
2133
  .update(schemas)
2136
2134
  .set(updates)
2137
2135
  .where(drizzleOrm.eq(schemas.id, existingSchemas[0].id));
2138
2136
  const updated = { ...existingSchemas[0], ...updates };
2139
- logger$A(`Schema "${schema.name}" updated. New schemaFileId: "${updated.schemaFileId}", isDraft: ${updated.isDraft}`);
2137
+ logger$B(`Schema "${schema.name}" updated. New schemaFileId: "${updated.schemaFileId}", isDraft: ${updated.isDraft}`);
2140
2138
  return updated;
2141
2139
  }
2142
- logger$A(`No updates needed for schema "${schema.name}" (id: ${existingSchemas[0].id})`);
2140
+ logger$B(`No updates needed for schema "${schema.name}" (id: ${existingSchemas[0].id})`);
2143
2141
  return existingSchemas[0];
2144
2142
  }
2145
2143
  const newSchema = await db.insert(schemas).values({
@@ -2322,7 +2320,7 @@ modelId) {
2322
2320
  // Compare database value with schema file value
2323
2321
  // If they differ, the property has been edited
2324
2322
  if (dbProperty.dataType !== schemaFileValue.dataType) {
2325
- logger$A(`Property ${modelName}:${propertyName} has been edited (dataType differs: DB=${dbProperty.dataType}, Schema=${schemaFileValue.dataType})`);
2323
+ logger$B(`Property ${modelName}:${propertyName} has been edited (dataType differs: DB=${dbProperty.dataType}, Schema=${schemaFileValue.dataType})`);
2326
2324
  return true;
2327
2325
  }
2328
2326
  // Check refModelId if it's a relation
@@ -2331,19 +2329,19 @@ modelId) {
2331
2329
  if (refModelRecord) {
2332
2330
  const expectedRefModelId = refModelRecord.id;
2333
2331
  if (dbProperty.refModelId !== expectedRefModelId) {
2334
- logger$A(`Property ${modelName}:${propertyName} has been edited (refModelId differs)`);
2332
+ logger$B(`Property ${modelName}:${propertyName} has been edited (refModelId differs)`);
2335
2333
  return true;
2336
2334
  }
2337
2335
  }
2338
2336
  }
2339
2337
  else if (dbProperty.refModelId !== null) {
2340
2338
  // Schema file has no ref, but DB has one
2341
- logger$A(`Property ${modelName}:${propertyName} has been edited (refModelId differs)`);
2339
+ logger$B(`Property ${modelName}:${propertyName} has been edited (refModelId differs)`);
2342
2340
  return true;
2343
2341
  }
2344
2342
  // Check refValueType
2345
2343
  if (dbProperty.refValueType !== (schemaFileValue.refValueType || null)) {
2346
- logger$A(`Property ${modelName}:${propertyName} has been edited (refValueType differs)`);
2344
+ logger$B(`Property ${modelName}:${propertyName} has been edited (refValueType differs)`);
2347
2345
  return true;
2348
2346
  }
2349
2347
  // Check required (for Relation/Image properties)
@@ -2351,7 +2349,7 @@ modelId) {
2351
2349
  const schemaRequired = !!schemaFileValue.required;
2352
2350
  const dbRequired = dbProperty.required === true;
2353
2351
  if (dbRequired !== schemaRequired) {
2354
- logger$A(`Property ${modelName}:${propertyName} has been edited (required differs: DB=${dbRequired}, Schema=${schemaRequired})`);
2352
+ logger$B(`Property ${modelName}:${propertyName} has been edited (required differs: DB=${dbRequired}, Schema=${schemaRequired})`);
2355
2353
  return true;
2356
2354
  }
2357
2355
  }
@@ -2367,7 +2365,7 @@ modelId) {
2367
2365
  if (dbStorage.storageType !== fileStorage.storageType ||
2368
2366
  dbStorage.localStorageDir !== fileStorage.localStorageDir ||
2369
2367
  dbStorage.filenameSuffix !== fileStorage.filenameSuffix) {
2370
- logger$A(`Property ${modelName}:${propertyName} has been edited (storage settings differ)`);
2368
+ logger$B(`Property ${modelName}:${propertyName} has been edited (storage settings differ)`);
2371
2369
  return true;
2372
2370
  }
2373
2371
  }
@@ -2379,7 +2377,7 @@ modelId) {
2379
2377
  }
2380
2378
  catch (error) {
2381
2379
  // If we can't check, assume it's not edited to be safe
2382
- logger$A('Error checking if property is edited:', error);
2380
+ logger$B('Error checking if property is edited:', error);
2383
2381
  return false;
2384
2382
  }
2385
2383
  }
@@ -2404,11 +2402,11 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
2404
2402
  // SchemaType includes id, so check if it's set
2405
2403
  if (schema.id !== null && schema.id !== undefined) {
2406
2404
  schemaRecord = schema;
2407
- logger$A(`Using existing schema record with id: ${schemaRecord.id}`);
2405
+ logger$B(`Using existing schema record with id: ${schemaRecord.id}`);
2408
2406
  }
2409
2407
  else {
2410
2408
  schemaRecord = await addSchemaToDb(schema, schemaFileData?.schemaFileId);
2411
- logger$A(`Created/found schema record with id: ${schemaRecord.id}`);
2409
+ logger$B(`Created/found schema record with id: ${schemaRecord.id}`);
2412
2410
  }
2413
2411
  }
2414
2412
  // Handle model renames first if provided
@@ -2434,7 +2432,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
2434
2432
  .where(drizzleOrm.eq(models$1.schemaFileId, modelFileId))
2435
2433
  .limit(1);
2436
2434
  if (existingWithFileId.length > 0 && existingWithFileId[0].id !== modelRecord.id) {
2437
- logger$A(`WARNING: Model "${modelName}" (id: ${modelRecord.id}) conflicts with existing model "${existingWithFileId[0].name}" (id: ${existingWithFileId[0].id}) both trying to use schemaFileId "${modelFileId}"`);
2435
+ logger$B(`WARNING: Model "${modelName}" (id: ${modelRecord.id}) conflicts with existing model "${existingWithFileId[0].name}" (id: ${existingWithFileId[0].id}) both trying to use schemaFileId "${modelFileId}"`);
2438
2436
  modelRecord = existingWithFileId[0];
2439
2437
  }
2440
2438
  else if (!modelRecord.schemaFileId) {
@@ -2492,7 +2490,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
2492
2490
  if (!propertyFileId) {
2493
2491
  const { generateId } = await Promise.resolve().then(function () { return generateId$1; });
2494
2492
  propertyFileId = generateId();
2495
- logger$A(`Generated propertyFileId "${propertyFileId}" for property "${modelName}:${propertyName}" (not found in propertyFileIds map)`);
2493
+ logger$B(`Generated propertyFileId "${propertyFileId}" for property "${modelName}:${propertyName}" (not found in propertyFileIds map)`);
2496
2494
  }
2497
2495
  // First, try to find by schemaFileId (preferred for change tracking)
2498
2496
  let existingProperty;
@@ -2559,7 +2557,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
2559
2557
  if (potentialMatches.length > 0) {
2560
2558
  const matchedProperty = potentialMatches[0];
2561
2559
  existingProperty = matchedProperty;
2562
- logger$A(`Found renamed property: ${modelName}:${matchedProperty.name} -> ${propertyName} (matched by characteristics)`);
2560
+ logger$B(`Found renamed property: ${modelName}:${matchedProperty.name} -> ${propertyName} (matched by characteristics)`);
2563
2561
  }
2564
2562
  }
2565
2563
  if (existingProperty) {
@@ -2580,7 +2578,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
2580
2578
  }, modelRecord.id);
2581
2579
  if (isPropertyEdited) {
2582
2580
  // Property has been locally edited - skip update to preserve local changes
2583
- logger$A(`Skipping update for property ${modelName}:${existingProperty.name} -> ${propertyName} - it has been locally edited and will be preserved`);
2581
+ logger$B(`Skipping update for property ${modelName}:${existingProperty.name} -> ${propertyName} - it has been locally edited and will be preserved`);
2584
2582
  continue;
2585
2583
  }
2586
2584
  // Property exists (possibly with different name) - update it with new values from schema file
@@ -2631,18 +2629,18 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
2631
2629
  if (existingByFileId.length > 0) {
2632
2630
  const found = existingByFileId[0];
2633
2631
  matchedDbPropertyIds.add(found.id);
2634
- logger$A(`Property ${modelName}:${propertyName} already exists by schemaFileId "${propertyFileId}" (id: ${found.id}), skipping insert`);
2632
+ logger$B(`Property ${modelName}:${propertyName} already exists by schemaFileId "${propertyFileId}" (id: ${found.id}), skipping insert`);
2635
2633
  continue;
2636
2634
  }
2637
2635
  }
2638
- logger$A(`Creating new property ${modelName}:${propertyName} with schemaFileId: ${propertyData.schemaFileId}`);
2636
+ logger$B(`Creating new property ${modelName}:${propertyName} with schemaFileId: ${propertyData.schemaFileId}`);
2639
2637
  try {
2640
2638
  await db.insert(properties).values(propertyDataWithIsEdited);
2641
2639
  }
2642
2640
  catch (insertError) {
2643
2641
  // Treat UNIQUE constraint as success - property already exists (e.g. from concurrent addModelsToDb call)
2644
2642
  if (isSqliteUniqueConstraintError(insertError)) {
2645
- logger$A(`Property ${modelName}:${propertyName} already exists (UNIQUE constraint), treating as success`);
2643
+ logger$B(`Property ${modelName}:${propertyName} already exists (UNIQUE constraint), treating as success`);
2646
2644
  }
2647
2645
  else {
2648
2646
  throw insertError;
@@ -2653,14 +2651,14 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
2653
2651
  }
2654
2652
  catch (error) {
2655
2653
  const errorMessage = error?.message || String(error);
2656
- logger$A(`Error processing model "${modelName}": ${errorMessage}`);
2654
+ logger$B(`Error processing model "${modelName}": ${errorMessage}`);
2657
2655
  modelProcessingErrors.push({ modelName, error: errorMessage });
2658
2656
  // Continue processing other models even if one fails
2659
2657
  }
2660
2658
  }
2661
2659
  if (modelProcessingErrors.length > 0) {
2662
2660
  console.warn(`[addModelsToDb] Errors occurred while processing ${modelProcessingErrors.length} model(s):`, modelProcessingErrors.map(e => `${e.modelName}: ${e.error}`).join('; '));
2663
- logger$A(`Errors processing models: ${modelProcessingErrors.map(e => e.modelName).join(', ')}`);
2661
+ logger$B(`Errors processing models: ${modelProcessingErrors.map(e => e.modelName).join(', ')}`);
2664
2662
  }
2665
2663
  // If schema was provided, create modelSchema join records to connect models to the schema
2666
2664
  if (schemaRecord && schemaRecord.id) {
@@ -2668,7 +2666,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
2668
2666
  .filter(([, r]) => r.id)
2669
2667
  .map(([name, r]) => ({ modelName: name, modelId: r.id }));
2670
2668
  if (modelIds.length === 0) {
2671
- logger$A('No model IDs to link, skipping schema linking');
2669
+ logger$B('No model IDs to link, skipping schema linking');
2672
2670
  }
2673
2671
  else {
2674
2672
  // Single batch query: get all existing joins for this schema
@@ -2682,13 +2680,13 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
2682
2680
  for (const { modelName, modelId } of toInsert) {
2683
2681
  if (!(await linkModelToSchema(db, modelId, schemaRecord.id)))
2684
2682
  continue;
2685
- logger$A(`Created join table entry for model ${modelName} (id: ${modelId}) to schema (id: ${schemaRecord.id})`);
2683
+ logger$B(`Created join table entry for model ${modelName} (id: ${modelId}) to schema (id: ${schemaRecord.id})`);
2686
2684
  }
2687
2685
  }
2688
2686
  }
2689
2687
  }
2690
2688
  else if (schemaRecord && !schemaRecord.id) {
2691
- logger$A(`Warning: schemaRecord provided but has no id, cannot create join table entries`);
2689
+ logger$B(`Warning: schemaRecord provided but has no id, cannot create join table entries`);
2692
2690
  }
2693
2691
  };
2694
2692
  /**
@@ -2701,7 +2699,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
2701
2699
  const loadModelsFromDbForSchema = async (schemaId) => {
2702
2700
  const db = BaseDb.getAppDb();
2703
2701
  if (!db) {
2704
- logger$A('Database not found, cannot load models from DB');
2702
+ logger$B('Database not found, cannot load models from DB');
2705
2703
  return {};
2706
2704
  }
2707
2705
  try {
@@ -2770,11 +2768,11 @@ const loadModelsFromDbForSchema = async (schemaId) => {
2770
2768
  // or reconstructed from schemaData if available
2771
2769
  };
2772
2770
  }
2773
- logger$A(`Loaded ${Object.keys(models).length} models from database for schema ${schemaId}`);
2771
+ logger$B(`Loaded ${Object.keys(models).length} models from database for schema ${schemaId}`);
2774
2772
  return models;
2775
2773
  }
2776
2774
  catch (error) {
2777
- logger$A(`Error loading models from database for schema ${schemaId}:`, error);
2775
+ logger$B(`Error loading models from database for schema ${schemaId}:`, error);
2778
2776
  return {};
2779
2777
  }
2780
2778
  };
@@ -2891,34 +2889,34 @@ const savePropertyToDb = async (property) => {
2891
2889
  // Find existing property - try multiple strategies to handle name changes
2892
2890
  // 1. First try by schemaFileId (most reliable - doesn't change when name changes)
2893
2891
  let existingProperties = [];
2894
- logger$A(`[savePropertyToDb] Looking for property ${property.modelName}:${property.name} (schemaFileId: ${schemaFileId}, originalName: ${property._originalValues?.name})`);
2892
+ logger$B(`[savePropertyToDb] Looking for property ${property.modelName}:${property.name} (schemaFileId: ${schemaFileId}, originalName: ${property._originalValues?.name})`);
2895
2893
  if (schemaFileId) {
2896
2894
  existingProperties = await db
2897
2895
  .select()
2898
2896
  .from(properties)
2899
2897
  .where(drizzleOrm.and(drizzleOrm.eq(properties.schemaFileId, schemaFileId), drizzleOrm.eq(properties.modelId, modelRecord.id)))
2900
2898
  .limit(1);
2901
- logger$A(`[savePropertyToDb] Found ${existingProperties.length} properties by schemaFileId`);
2899
+ logger$B(`[savePropertyToDb] Found ${existingProperties.length} properties by schemaFileId`);
2902
2900
  }
2903
2901
  // 2. If not found by schemaFileId, try by original name (if name was changed)
2904
2902
  if (existingProperties.length === 0 && property._originalValues?.name && property._originalValues.name !== property.name) {
2905
- logger$A(`[savePropertyToDb] Trying to find by original name: ${property._originalValues.name}`);
2903
+ logger$B(`[savePropertyToDb] Trying to find by original name: ${property._originalValues.name}`);
2906
2904
  existingProperties = await db
2907
2905
  .select()
2908
2906
  .from(properties)
2909
2907
  .where(drizzleOrm.and(drizzleOrm.eq(properties.name, property._originalValues.name), drizzleOrm.eq(properties.modelId, modelRecord.id)))
2910
2908
  .limit(1);
2911
- logger$A(`[savePropertyToDb] Found ${existingProperties.length} properties by original name`);
2909
+ logger$B(`[savePropertyToDb] Found ${existingProperties.length} properties by original name`);
2912
2910
  }
2913
2911
  // 3. Fallback: try by current name
2914
2912
  if (existingProperties.length === 0) {
2915
- logger$A(`[savePropertyToDb] Trying to find by current name: ${property.name}`);
2913
+ logger$B(`[savePropertyToDb] Trying to find by current name: ${property.name}`);
2916
2914
  existingProperties = await db
2917
2915
  .select()
2918
2916
  .from(properties)
2919
2917
  .where(drizzleOrm.and(drizzleOrm.eq(properties.name, property.name), drizzleOrm.eq(properties.modelId, modelRecord.id)))
2920
2918
  .limit(1);
2921
- logger$A(`[savePropertyToDb] Found ${existingProperties.length} properties by current name`);
2919
+ logger$B(`[savePropertyToDb] Found ${existingProperties.length} properties by current name`);
2922
2920
  }
2923
2921
  // Prepare property data
2924
2922
  const propertyData = {
@@ -2967,7 +2965,7 @@ const savePropertyToDb = async (property) => {
2967
2965
  isEdited: true, // Mark as edited when saving changes
2968
2966
  })
2969
2967
  .where(drizzleOrm.eq(properties.id, existingProperty.id));
2970
- logger$A(`Updated property ${property.modelName}:${property._originalValues?.name || 'unknown'} -> ${property.name} in database`);
2968
+ logger$B(`Updated property ${property.modelName}:${property._originalValues?.name || 'unknown'} -> ${property.name} in database`);
2971
2969
  }
2972
2970
  else {
2973
2971
  // Property doesn't exist, create it
@@ -2977,12 +2975,12 @@ const savePropertyToDb = async (property) => {
2977
2975
  ...propertyData,
2978
2976
  isEdited: true, // Runtime-created properties are edited
2979
2977
  });
2980
- logger$A(`Created property ${property.modelName}:${property.name} in database`);
2978
+ logger$B(`Created property ${property.modelName}:${property.name} in database`);
2981
2979
  }
2982
2980
  catch (insertError) {
2983
2981
  // Treat UNIQUE constraint as success - property already exists (e.g. from concurrent addModelsToDb or race)
2984
2982
  if (isSqliteUniqueConstraintError(insertError)) {
2985
- logger$A(`Property ${property.modelName}:${property.name} already exists (UNIQUE constraint), treating as success`);
2983
+ logger$B(`Property ${property.modelName}:${property.name} already exists (UNIQUE constraint), treating as success`);
2986
2984
  }
2987
2985
  else {
2988
2986
  throw insertError;
@@ -3099,7 +3097,7 @@ async function writeModelToDb(modelFileId, data) {
3099
3097
  if (doubleCheck.length > 0) {
3100
3098
  // Another process created it, use existing
3101
3099
  modelId = doubleCheck[0].id;
3102
- logger$A(`Model with schemaFileId "${modelFileId}" was created by another process, using existing record (id: ${modelId})`);
3100
+ logger$B(`Model with schemaFileId "${modelFileId}" was created by another process, using existing record (id: ${modelId})`);
3103
3101
  }
3104
3102
  else {
3105
3103
  try {
@@ -3113,7 +3111,7 @@ async function writeModelToDb(modelFileId, data) {
3113
3111
  catch (error) {
3114
3112
  // Handle unique constraint violation
3115
3113
  if (isSqliteUniqueConstraintError(error)) {
3116
- logger$A(`Unique constraint violation for schemaFileId "${modelFileId}", attempting to find existing model`);
3114
+ logger$B(`Unique constraint violation for schemaFileId "${modelFileId}", attempting to find existing model`);
3117
3115
  const existing = await db
3118
3116
  .select()
3119
3117
  .from(models$1)
@@ -3121,7 +3119,7 @@ async function writeModelToDb(modelFileId, data) {
3121
3119
  .limit(1);
3122
3120
  if (existing.length > 0) {
3123
3121
  modelId = existing[0].id;
3124
- logger$A(`Found existing model with schemaFileId "${modelFileId}" (id: ${modelId}) after constraint violation`);
3122
+ logger$B(`Found existing model with schemaFileId "${modelFileId}" (id: ${modelId}) after constraint violation`);
3125
3123
  }
3126
3124
  else {
3127
3125
  throw error;
@@ -3191,7 +3189,7 @@ async function writeModelToDb(modelFileId, data) {
3191
3189
  if (schemaCheck.length === 0) {
3192
3190
  throw new Error(`Schema with id ${data.schemaId} does not exist in database. Cannot create join record.`);
3193
3191
  }
3194
- logger$A(`Creating join record: modelId=${modelId}, schemaId=${data.schemaId} (both verified to exist)`);
3192
+ logger$B(`Creating join record: modelId=${modelId}, schemaId=${data.schemaId} (both verified to exist)`);
3195
3193
  await linkModelToSchema(db, modelId, data.schemaId);
3196
3194
  // Notify React useModels so it can invalidate; live query over join often doesn't re-run when model_schemas is inserted.
3197
3195
  // Yield so the insert is visible to the refetch that will run when the broadcast is received.
@@ -3206,13 +3204,13 @@ async function writeModelToDb(modelFileId, data) {
3206
3204
  }
3207
3205
  catch (_) { }
3208
3206
  }
3209
- logger$A(`Successfully created join record for model ${data.modelName} (id: ${modelId}) to schema (id: ${data.schemaId})`);
3207
+ logger$B(`Successfully created join record for model ${data.modelName} (id: ${modelId}) to schema (id: ${data.schemaId})`);
3210
3208
  }
3211
3209
  catch (error) {
3212
3210
  if (error?.code === 'SQLITE_CONSTRAINT_FOREIGNKEY') {
3213
- logger$A(`FOREIGN KEY constraint failed when creating join record for model "${data.modelName}"`);
3214
- logger$A(`modelId: ${modelId}, schemaId: ${data.schemaId}`);
3215
- logger$A(`Error details:`, error);
3211
+ logger$B(`FOREIGN KEY constraint failed when creating join record for model "${data.modelName}"`);
3212
+ logger$B(`modelId: ${modelId}, schemaId: ${data.schemaId}`);
3213
+ logger$B(`Error details:`, error);
3216
3214
  // Re-throw with more context
3217
3215
  throw new Error(`FOREIGN KEY constraint failed when creating join record for model "${data.modelName}" (modelId: ${modelId}, schemaId: ${data.schemaId}). ${error.message}`);
3218
3216
  }
@@ -3232,7 +3230,7 @@ async function writeModelToDb(modelFileId, data) {
3232
3230
  if (existingProps.length > 0 && existingProps[0].schemaFileId) {
3233
3231
  // Use existing property's schemaFileId
3234
3232
  propertyFileId = existingProps[0].schemaFileId;
3235
- logger$A(`Using existing propertyFileId "${propertyFileId}" for property "${data.modelName}:${propName}"`);
3233
+ logger$B(`Using existing propertyFileId "${propertyFileId}" for property "${data.modelName}:${propName}"`);
3236
3234
  }
3237
3235
  else if (propData.id) {
3238
3236
  // Use provided ID
@@ -3243,7 +3241,7 @@ async function writeModelToDb(modelFileId, data) {
3243
3241
  // IDs should be generated in the import process before calling writeModelToDb
3244
3242
  const { generateId } = await Promise.resolve().then(function () { return generateId$1; });
3245
3243
  propertyFileId = generateId();
3246
- logger$A(`Generated propertyFileId "${propertyFileId}" for property "${data.modelName}:${propName}"`);
3244
+ logger$B(`Generated propertyFileId "${propertyFileId}" for property "${data.modelName}:${propName}"`);
3247
3245
  }
3248
3246
  await writePropertyToDb(propertyFileId, {
3249
3247
  modelId,
@@ -3252,7 +3250,7 @@ async function writeModelToDb(modelFileId, data) {
3252
3250
  });
3253
3251
  }
3254
3252
  }
3255
- logger$A(`Wrote model ${data.modelName} (${modelFileId}) to database`);
3253
+ logger$B(`Wrote model ${data.modelName} (${modelFileId}) to database`);
3256
3254
  }
3257
3255
  /**
3258
3256
  * Write property to database
@@ -3327,7 +3325,7 @@ async function writePropertyToDb(propertyFileId, data, isEdited = false) {
3327
3325
  .update(properties)
3328
3326
  .set(propertyData)
3329
3327
  .where(drizzleOrm.eq(properties.id, existing.id));
3330
- logger$A(`Updated property ${data.name} (${propertyFileId}) in database`);
3328
+ logger$B(`Updated property ${data.name} (${propertyFileId}) in database`);
3331
3329
  }
3332
3330
  else {
3333
3331
  // Property doesn't exist, create it
@@ -3343,17 +3341,17 @@ async function writePropertyToDb(propertyFileId, data, isEdited = false) {
3343
3341
  .update(properties)
3344
3342
  .set(propertyData)
3345
3343
  .where(drizzleOrm.eq(properties.id, doubleCheck[0].id));
3346
- logger$A(`Property with schemaFileId "${propertyFileId}" was created by another process, updated existing record`);
3344
+ logger$B(`Property with schemaFileId "${propertyFileId}" was created by another process, updated existing record`);
3347
3345
  }
3348
3346
  else {
3349
3347
  try {
3350
3348
  await db.insert(properties).values({ required: false, ...propertyData });
3351
- logger$A(`Created property ${data.name} (${propertyFileId}) in database`);
3349
+ logger$B(`Created property ${data.name} (${propertyFileId}) in database`);
3352
3350
  }
3353
3351
  catch (error) {
3354
3352
  // Handle unique constraint violation
3355
3353
  if (isSqliteUniqueConstraintError(error)) {
3356
- logger$A(`Unique constraint violation for property schemaFileId "${propertyFileId}", attempting to find existing property`);
3354
+ logger$B(`Unique constraint violation for property schemaFileId "${propertyFileId}", attempting to find existing property`);
3357
3355
  const existing = await db
3358
3356
  .select()
3359
3357
  .from(properties)
@@ -3364,7 +3362,7 @@ async function writePropertyToDb(propertyFileId, data, isEdited = false) {
3364
3362
  .update(properties)
3365
3363
  .set(propertyData)
3366
3364
  .where(drizzleOrm.eq(properties.id, existing[0].id));
3367
- logger$A(`Found existing property with schemaFileId "${propertyFileId}" (id: ${existing[0].id}) after constraint violation, updated it`);
3365
+ logger$B(`Found existing property with schemaFileId "${propertyFileId}" (id: ${existing[0].id}) after constraint violation, updated it`);
3368
3366
  }
3369
3367
  else {
3370
3368
  throw new Error(`Failed to create or find property "${data.name}" with schemaFileId "${propertyFileId}": ${error.message}`);
@@ -3637,7 +3635,114 @@ const supportsOpfsFileDownloads = () => {
3637
3635
  return isBrowser() || isElectronRenderer();
3638
3636
  };
3639
3637
 
3640
- const logger$z = debug('seedSdk:files:download');
3638
+ /**
3639
+ * Tag every Seed upload carries with the hex digest of its data. Producers: the SDK's
3640
+ * `getPublishUploadData` / `getPublishUploads` (and through them both the L1 transaction path and
3641
+ * the bundler / DataItem path in `@seedprotocol/publish`). Consumer: the files download
3642
+ * (`events/files/download.ts` and the download worker), which verifies downloaded bytes against it
3643
+ * and copies a verified value into `metadata.content_hash`.
3644
+ */
3645
+ const CONTENT_SHA256_TAG = 'Content-SHA-256';
3646
+ const CONTENT_TYPE_TAG = 'Content-Type';
3647
+ /**
3648
+ * Lowercase hex SHA-256 of `data`: the value of the {@link CONTENT_SHA256_TAG} tag.
3649
+ *
3650
+ * Uses @noble/hashes rather than WebCrypto so it also works outside secure contexts (WebCrypto's
3651
+ * `crypto.subtle` is missing on plain-http origins); the digest is the same.
3652
+ *
3653
+ * In SDK 0.7.2 and earlier the L1 transaction path (`getPublishUploads`) wrote SHA3-256 under this tag name
3654
+ * while the bundler path wrote SHA-256. Uploads from that path still carry SHA3-256 digests; use
3655
+ * {@link contentSha256TagMatches} to check a tag value against bytes.
3656
+ */
3657
+ const getContentSha256 = (data) => utils.bytesToHex(sha256.sha256(data));
3658
+ /**
3659
+ * Tags for one upload, in the order every upload uses: content hash, content type, then any
3660
+ * configured extra tags (e.g. App-Name from `arweaveUploadTags`).
3661
+ */
3662
+ const buildArweaveContentTags = (contentHash, contentType, extra) => {
3663
+ const tags = [];
3664
+ if (contentHash)
3665
+ tags.push({ name: CONTENT_SHA256_TAG, value: contentHash });
3666
+ if (contentType)
3667
+ tags.push({ name: CONTENT_TYPE_TAG, value: contentType });
3668
+ if (extra?.length)
3669
+ tags.push(...extra);
3670
+ return tags;
3671
+ };
3672
+
3673
+ /** Subdirectory of the files root that holds a storage seed's file, by its data type. */
3674
+ const getStorageSubdirForDataType = (dataType) => {
3675
+ switch (normalizeDataType(dataType ?? undefined)) {
3676
+ case 'Image':
3677
+ return 'images';
3678
+ case 'Html':
3679
+ return 'html';
3680
+ case 'Json':
3681
+ return 'json';
3682
+ case 'File':
3683
+ default:
3684
+ // Unknown types are generic files; `images/` is only for what the SDK knows is an image.
3685
+ return 'files';
3686
+ }
3687
+ };
3688
+ /** Absolute directory for a storage seed's file (`images/`, `files/`, `html/` or `json/` under the files root). */
3689
+ const getStorageDirForDataType = (dataType) => BaseFileManager.getFilesPath(getStorageSubdirForDataType(dataType));
3690
+ /**
3691
+ * Subdirectory (relative to the files root, no leading slash) for an ItemStorage property's file:
3692
+ * its model's `storage.path` (`localStorageDir`), else `files`.
3693
+ */
3694
+ const getItemStorageSubdir = (localStorageDir) => (localStorageDir ?? '').replace(/^\/+/, '').replace(/\/+$/, '') || 'files';
3695
+ /**
3696
+ * File name a local save gives an ItemStorage property: `<seedUid or seedLocalId><extension>`
3697
+ * (see saveItemStorage). Downloaded content is named after its transaction instead
3698
+ * (`<txId><extension>`, see syncDbWithEas), which is what the metadata row's refResolvedValue says.
3699
+ */
3700
+ const getItemStorageLocalFileName = (seedId, filenameSuffix) => `${seedId}${filenameSuffix ?? ''}`;
3701
+
3702
+ /** Rows per query: well under SQLite's bound-parameter limit. */
3703
+ const CHUNK_SIZE = 400;
3704
+ /**
3705
+ * Where the download worker saves each child of a composite upload, by transaction id then child
3706
+ * (property) name: a path relative to the files root.
3707
+ *
3708
+ * The paths come from the ItemStorage rows sync derives from a `storage_transaction_id`
3709
+ * attestation (see `createMetadataRecordsForStorageTransactionId`): property value = the
3710
+ * transaction id, `refResolvedValue` = `<txId><extension>`, `localStorageDir` = the model's storage
3711
+ * directory. Those rows are what hydration reads, so a child saved here is found as that property's
3712
+ * file. Transactions with no such rows are left out; the worker then falls back to the legacy
3713
+ * html / json layout.
3714
+ */
3715
+ const getCompositeChildPaths = async (transactionIds) => {
3716
+ const out = {};
3717
+ const appDb = BaseDb.getAppDb();
3718
+ if (!appDb || transactionIds.length === 0)
3719
+ return out;
3720
+ for (let i = 0; i < transactionIds.length; i += CHUNK_SIZE) {
3721
+ const chunk = transactionIds.slice(i, i + CHUNK_SIZE);
3722
+ const rows = await appDb
3723
+ .select({
3724
+ transactionId: metadata$1.propertyValue,
3725
+ propertyName: metadata$1.propertyName,
3726
+ refResolvedValue: metadata$1.refResolvedValue,
3727
+ localStorageDir: metadata$1.localStorageDir,
3728
+ })
3729
+ .from(metadata$1)
3730
+ .where(drizzleOrm.and(drizzleOrm.isNotNull(metadata$1.derivedFromUid), drizzleOrm.isNotNull(metadata$1.refResolvedValue), drizzleOrm.inArray(metadata$1.propertyValue, chunk)));
3731
+ for (const row of rows) {
3732
+ const { transactionId, propertyName, refResolvedValue } = row;
3733
+ if (!transactionId || !propertyName || !refResolvedValue)
3734
+ continue;
3735
+ // A file name, never a path: anything else is not where the SDK would look.
3736
+ if (refResolvedValue.includes('/') || refResolvedValue.includes('\\'))
3737
+ continue;
3738
+ const byName = (out[transactionId] ?? (out[transactionId] = {}));
3739
+ byName[propertyName] ?? (byName[propertyName] = `${getItemStorageSubdir(row.localStorageDir)}/${refResolvedValue}`);
3740
+ }
3741
+ }
3742
+ return out;
3743
+ };
3744
+
3745
+ const logger$A = debug('seedSdk:files:download');
3641
3746
  const AUTO_BULK_DOWNLOAD_THROTTLE_MS = 10000;
3642
3747
  /** Avoid refetch-on-every-call: transient empty indexer responses were overwriting good cache (see trailing throttle ~10s after success). */
3643
3748
  const GET_FILES_METADATA_STALE_MS = 120000;
@@ -3647,7 +3752,7 @@ const lazyDownloadInFlightByTransactionId = new Map();
3647
3752
  const syncDbFiles = async (endpoints) => {
3648
3753
  // TODO: Implement syncDbFiles functionality if needed
3649
3754
  // This was previously in @/services/internal/helpers
3650
- logger$z('[download] syncDbFiles called but not yet implemented');
3755
+ logger$A('[download] syncDbFiles called but not yet implemented');
3651
3756
  return Promise.resolve();
3652
3757
  };
3653
3758
  const getAppDbReady = async () => {
@@ -3787,76 +3892,117 @@ const parseTransactionIdsFromMetadata = (filesMetadata, excludedTransactions) =>
3787
3892
  }
3788
3893
  return transactionIds;
3789
3894
  };
3790
- const downloadTransactionIds = async (rawTransactionIds, options) => {
3791
- if (!supportsOpfsFileDownloads()) {
3792
- return false;
3895
+ /** Content-SHA-256 tag values for the transactions that have one, from one batched tag lookup (cached). */
3896
+ const getExpectedContentHashes = async (transactionIds) => {
3897
+ const queryClient = eas.BaseQueryClient.getQueryClient();
3898
+ const tagsById = new Map();
3899
+ const toFetch = [];
3900
+ for (const transactionId of transactionIds) {
3901
+ // Tags never change once a transaction is indexed, so a cached lookup stays good.
3902
+ const cached = queryClient.getQueryData?.(['getTransactionTags', transactionId]);
3903
+ if (cached)
3904
+ tagsById.set(transactionId, cached);
3905
+ else
3906
+ toFetch.push(transactionId);
3907
+ }
3908
+ if (toFetch.length > 0) {
3909
+ try {
3910
+ const fetched = await arweave.getTransactionTagsByIds(toFetch, {
3911
+ client: arweave.BaseArweaveClient.getArweaveClient(),
3912
+ onError: (error) => logger$A('[download] transaction tags lookup failed', error),
3913
+ });
3914
+ for (const [transactionId, tags] of fetched) {
3915
+ tagsById.set(transactionId, tags);
3916
+ // Seed the per-transaction cache entry (the client interface has no setQueryData).
3917
+ void queryClient
3918
+ .fetchQuery({ queryKey: ['getTransactionTags', transactionId], queryFn: async () => tags })
3919
+ .catch(() => { });
3920
+ }
3921
+ }
3922
+ catch (error) {
3923
+ logger$A('[download] transaction tags lookup failed', error);
3924
+ }
3793
3925
  }
3794
- const transactionIds = Array.from(new Set(rawTransactionIds.filter((tx) => !!tx && tx.trim().length > 0)));
3795
- if (transactionIds.length === 0) {
3796
- return false;
3926
+ const out = {};
3927
+ for (const [transactionId, tags] of tagsById) {
3928
+ const value = tags.find((tag) => tag.name === CONTENT_SHA256_TAG)?.value?.trim();
3929
+ if (value)
3930
+ out[transactionId] = value;
3797
3931
  }
3798
- const excludedTransactions = await getExcludedTransactions();
3799
- const queryClient = eas.BaseQueryClient.getQueryClient();
3800
- const transactionIdsToDownload = [];
3801
- await arweave.ensureReadGatewaySelected();
3932
+ return out;
3933
+ };
3934
+ /** Store the (now verified) Content-SHA-256 of each downloaded transaction on its metadata row. */
3935
+ const recordVerifiedContentHashes = async (transactionIds, expectedContentHashes) => {
3802
3936
  for (const transactionId of transactionIds) {
3803
- if (excludedTransactions.has(transactionId)) {
3937
+ const contentHash = expectedContentHashes[transactionId];
3938
+ if (!contentHash)
3804
3939
  continue;
3805
- }
3806
3940
  try {
3807
- // Browser: do not call getTransactionStatus() — many gateways (e.g. g8way.io) redirect or omit
3808
- // CORS headers, so fetch() fails and we would wrongly exclude txs. The OPFS worker fetch decides success.
3809
- let tags = [];
3810
- try {
3811
- tags = await queryClient.fetchQuery({
3812
- queryKey: ['getTransactionTags', transactionId],
3813
- queryFn: async () => arweave.BaseArweaveClient.getTransactionTags(transactionId),
3814
- });
3815
- }
3816
- catch {
3817
- tags = [];
3941
+ const metadataRecord = await getMetadata({ storageTransactionId: transactionId });
3942
+ if (metadataRecord) {
3943
+ await saveMetadata(metadataRecord, { contentHash });
3818
3944
  }
3819
- if (tags && tags.length > 0) {
3820
- for (const { name, value } of tags) {
3821
- if (name !== 'Content-SHA-256')
3822
- continue;
3823
- const metadataRecord = await getMetadata({
3824
- storageTransactionId: transactionId,
3825
- });
3826
- if (metadataRecord) {
3827
- await saveMetadata(metadataRecord, {
3828
- contentHash: value,
3829
- });
3830
- }
3831
- }
3832
- }
3833
- transactionIdsToDownload.push(transactionId);
3834
3945
  }
3835
3946
  catch (error) {
3836
- logger$z(error);
3947
+ logger$A(error);
3837
3948
  }
3838
3949
  }
3950
+ };
3951
+ const downloadTransactionIds = async (rawTransactionIds, options) => {
3952
+ if (!supportsOpfsFileDownloads()) {
3953
+ return false;
3954
+ }
3955
+ const transactionIds = Array.from(new Set(rawTransactionIds.filter((tx) => !!tx && tx.trim().length > 0)));
3956
+ if (transactionIds.length === 0) {
3957
+ return false;
3958
+ }
3959
+ const excludedTransactions = await getExcludedTransactions();
3960
+ await arweave.ensureReadGatewaySelected();
3961
+ // Browser: do not call getTransactionStatus() — many gateways (e.g. g8way.io) redirect or omit
3962
+ // CORS headers, so fetch() fails and we would wrongly exclude txs. The OPFS worker fetch decides success.
3963
+ const transactionIdsToDownload = transactionIds.filter((id) => !excludedTransactions.has(id));
3839
3964
  if (transactionIdsToDownload.length === 0) {
3840
3965
  return false;
3841
3966
  }
3967
+ // One batched lookup for every upload's Content-SHA-256 tag; downloads are verified against it.
3968
+ // Missing tags (old uploads, or a just-published one not indexed yet) just mean no verification.
3969
+ const expectedContentHashes = await getExpectedContentHashes(transactionIdsToDownload);
3842
3970
  // Preferred gateways first: a just-published item is only on the gateway it was uploaded through.
3843
3971
  const arweaveBaseUrls = arweave.getArweaveReadBaseUrls();
3972
+ // Where each ItemStorage child of a composite goes (the worker cannot read the DB or the schema).
3973
+ const compositeChildPaths = await getCompositeChildPaths(transactionIdsToDownload).catch((error) => {
3974
+ logger$A('[download] composite child paths lookup failed', error);
3975
+ return {};
3976
+ });
3977
+ let result;
3844
3978
  if (transactionIdsToDownload.length === 1) {
3845
- await BaseFileManager.downloadFileByTransactionId({
3846
- transactionId: transactionIdsToDownload[0],
3979
+ const transactionId = transactionIdsToDownload[0];
3980
+ result = await BaseFileManager.downloadFileByTransactionId({
3981
+ transactionId,
3847
3982
  arweaveHost: arweave.BaseArweaveClient.getBaseUrl(),
3848
3983
  arweaveBaseUrls,
3849
3984
  excludedTransactions,
3985
+ expectedContentHash: expectedContentHashes[transactionId],
3986
+ compositeChildPaths: compositeChildPaths[transactionId],
3850
3987
  });
3851
3988
  }
3852
3989
  else {
3853
- await BaseFileManager.downloadAllFiles({
3990
+ result = await BaseFileManager.downloadAllFiles({
3854
3991
  transactionIds: transactionIdsToDownload,
3855
3992
  arweaveHost: arweave.BaseArweaveClient.getBaseUrl(),
3856
3993
  arweaveBaseUrls,
3857
3994
  excludedTransactions,
3995
+ expectedContentHashes,
3996
+ compositeChildPaths,
3858
3997
  });
3859
3998
  }
3999
+ if (result) {
4000
+ for (const transactionId of result.hashMismatchTransactionIds) {
4001
+ // Not saved by the worker; left for a later run (a gateway may serve the right bytes then).
4002
+ logger$A(`[download] ${transactionId}: downloaded bytes do not match Content-SHA-256; skipped`);
4003
+ }
4004
+ await recordVerifiedContentHashes(result.verifiedTransactionIds, expectedContentHashes);
4005
+ }
3860
4006
  if (options?.resizeAllImages !== false) {
3861
4007
  await BaseFileManager.resizeAllImages({
3862
4008
  width: 480,
@@ -3941,6 +4087,7 @@ const downloadAllFilesBinaryRequestHandler = async (addressesHintOrPayload) => {
3941
4087
  await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath('html'));
3942
4088
  await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath('json'));
3943
4089
  await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath('images'));
4090
+ await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath('files'));
3944
4091
  const excludedTransactions = await getExcludedTransactions();
3945
4092
  const fromEas = parseTransactionIdsFromMetadata(filesMetadata ?? [], excludedTransactions);
3946
4093
  const fromLocal = await collectTransactionIdsFromLocalMetadata();
@@ -3970,7 +4117,7 @@ const downloadTransactionIdWithDedupe = async (transactionId) => {
3970
4117
  };
3971
4118
  const scheduleBulkFilesDownloadFromEasSyncThrottled = lodashEs.throttle((addressesHint) => {
3972
4119
  void downloadAllFilesBinaryRequestHandler(addressesHint).catch((error) => {
3973
- logger$z('[scheduleBulkFilesDownloadFromEasSync] failed', error);
4120
+ logger$A('[scheduleBulkFilesDownloadFromEasSync] failed', error);
3974
4121
  });
3975
4122
  }, AUTO_BULK_DOWNLOAD_THROTTLE_MS, { leading: true, trailing: false });
3976
4123
  const scheduleBulkFilesDownloadFromEasSync = (addressesHint) => {
@@ -4122,7 +4269,7 @@ const INTERNAL_STORAGE_MODEL_FILE_IDS = {
4122
4269
  html: 'SEEDPROTOCOL_HTML',
4123
4270
  };
4124
4271
 
4125
- const logger$y = debug('seedSdk:helpers:ensureImageLocal');
4272
+ const logger$z = debug('seedSdk:helpers:ensureImageLocal');
4126
4273
  /** Arweave transaction ids are 43 chars in the URL-safe base64 alphabet. */
4127
4274
  const ARWEAVE_TX_ID_RE = /^[a-z0-9_-]{43}$/i;
4128
4275
  const IMAGE_SIZES = [
@@ -4291,7 +4438,7 @@ const runEnsureImageLocal = async (params) => {
4291
4438
  };
4292
4439
  }
4293
4440
  catch (error) {
4294
- logger$y('ensureImageLocal failed', error);
4441
+ logger$z('ensureImageLocal failed', error);
4295
4442
  return { status: 'failed' };
4296
4443
  }
4297
4444
  };
@@ -4348,7 +4495,7 @@ var generateId$1 = /*#__PURE__*/Object.freeze({
4348
4495
  generateId: generateId
4349
4496
  });
4350
4497
 
4351
- const logger$x = debug('seedSdk:shared:helpers');
4498
+ const logger$y = debug('seedSdk:shared:helpers');
4352
4499
  const toSnakeCase = (str) => {
4353
4500
  return str.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
4354
4501
  };
@@ -4405,7 +4552,7 @@ const convertTxIdToImage = async (txId) => {
4405
4552
  const imageFilePath = BaseFileManager.getFilesPath('images', txId);
4406
4553
  const fileExists = await BaseFileManager.pathExists(imageFilePath);
4407
4554
  if (!fileExists) {
4408
- logger$x(`[ItemView] [updateImage] ${imageFilePath} does not exist`);
4555
+ logger$y(`[ItemView] [updateImage] ${imageFilePath} does not exist`);
4409
4556
  return;
4410
4557
  }
4411
4558
  const buffer = await BaseFileManager.readFileAsBuffer(imageFilePath);
@@ -4450,7 +4597,7 @@ function isActorStopped(actor) {
4450
4597
  return actor.getSnapshot().status === 'stopped';
4451
4598
  }
4452
4599
 
4453
- const logger$w = debug('seedSdk:model:actors:loadOrCreateModel');
4600
+ const logger$x = debug('seedSdk:model:actors:loadOrCreateModel');
4454
4601
  /**
4455
4602
  * Create ModelProperty instances for all property IDs to ensure they're cached
4456
4603
  * This ensures that ModelProperty.getById() in Model.properties getter will find the instances
@@ -4461,10 +4608,10 @@ const createPropertyInstances = async (propertyFileIds) => {
4461
4608
  return;
4462
4609
  }
4463
4610
  try {
4464
- const mod = await Promise.resolve().then(function () { return require('./ModelProperty-B-cZm1yU.js'); });
4611
+ const mod = await Promise.resolve().then(function () { return require('./ModelProperty-DXZ39Wyv.js'); });
4465
4612
  const ModelProperty = mod?.ModelProperty ?? mod?.default;
4466
4613
  if (!ModelProperty) {
4467
- logger$w('createPropertyInstances: ModelProperty not available from dynamic import');
4614
+ logger$x('createPropertyInstances: ModelProperty not available from dynamic import');
4468
4615
  return;
4469
4616
  }
4470
4617
  // Create instances for all property IDs in parallel
@@ -4473,22 +4620,22 @@ const createPropertyInstances = async (propertyFileIds) => {
4473
4620
  try {
4474
4621
  const property = await ModelProperty.createById(propertyFileId);
4475
4622
  if (property) {
4476
- logger$w(`Created/cached ModelProperty instance for propertyFileId "${propertyFileId}"`);
4623
+ logger$x(`Created/cached ModelProperty instance for propertyFileId "${propertyFileId}"`);
4477
4624
  }
4478
4625
  else {
4479
- logger$w(`ModelProperty.createById returned undefined for propertyFileId "${propertyFileId}" (may not exist in DB yet)`);
4626
+ logger$x(`ModelProperty.createById returned undefined for propertyFileId "${propertyFileId}" (may not exist in DB yet)`);
4480
4627
  }
4481
4628
  }
4482
4629
  catch (error) {
4483
- logger$w(`Error creating ModelProperty instance for propertyFileId "${propertyFileId}": ${error}`);
4630
+ logger$x(`Error creating ModelProperty instance for propertyFileId "${propertyFileId}": ${error}`);
4484
4631
  // Don't throw - continue with other properties
4485
4632
  }
4486
4633
  });
4487
4634
  await Promise.all(createPromises);
4488
- logger$w(`Finished creating/caching ${propertyFileIds.length} ModelProperty instances`);
4635
+ logger$x(`Finished creating/caching ${propertyFileIds.length} ModelProperty instances`);
4489
4636
  }
4490
4637
  catch (error) {
4491
- logger$w(`Error in createPropertyInstances: ${error}`);
4638
+ logger$x(`Error in createPropertyInstances: ${error}`);
4492
4639
  // Don't throw - this is best-effort to pre-populate cache
4493
4640
  }
4494
4641
  };
@@ -4518,7 +4665,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4518
4665
  if (dbModels.length > 0) {
4519
4666
  modelRecord = dbModels[0];
4520
4667
  foundBySchemaFileId = true;
4521
- logger$w(`Found model "${modelName}" in database by schemaFileId "${schemaFileId}"`);
4668
+ logger$x(`Found model "${modelName}" in database by schemaFileId "${schemaFileId}"`);
4522
4669
  }
4523
4670
  }
4524
4671
  // If not found by ID, try by name
@@ -4572,16 +4719,16 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4572
4719
  // Access instanceCacheById via type assertion since it's protected
4573
4720
  const cacheById = Model.instanceCacheById;
4574
4721
  if (cacheById.has(dbSchemaFileId)) {
4575
- logger$w(`Model "${modelName}" found in database by name with schemaFileId "${dbSchemaFileId}", and a cached instance already exists. Updating current instance to use the same schemaFileId.`);
4722
+ logger$x(`Model "${modelName}" found in database by name with schemaFileId "${dbSchemaFileId}", and a cached instance already exists. Updating current instance to use the same schemaFileId.`);
4576
4723
  // Update the current instance's schemaFileId to match the database
4577
4724
  // This ensures both instances point to the same cached instance
4578
4725
  modelRecord = foundModel;
4579
4726
  schemaFileId = dbSchemaFileId;
4580
- logger$w(`Using existing cached instance with schemaFileId "${schemaFileId}" for model "${modelName}"`);
4727
+ logger$x(`Using existing cached instance with schemaFileId "${schemaFileId}" for model "${modelName}"`);
4581
4728
  }
4582
4729
  }
4583
4730
  catch (error) {
4584
- logger$w(`Error checking Model cache for schemaFileId "${dbSchemaFileId}": ${error}`);
4731
+ logger$x(`Error checking Model cache for schemaFileId "${dbSchemaFileId}": ${error}`);
4585
4732
  // Fall through to normal processing
4586
4733
  }
4587
4734
  }
@@ -4589,31 +4736,31 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4589
4736
  // this is a new model - don't use the existing model (will be renamed if duplicate)
4590
4737
  // UNLESS we found a cached instance above (in which case modelRecord is already set)
4591
4738
  if (!modelRecord && schemaFileId && dbSchemaFileId && schemaFileId !== dbSchemaFileId) {
4592
- logger$w(`Model "${modelName}" found by name but has different schemaFileId (provided: "${schemaFileId}", db: "${dbSchemaFileId}"). Creating new model (will check for duplicates).`);
4739
+ logger$x(`Model "${modelName}" found by name but has different schemaFileId (provided: "${schemaFileId}", db: "${dbSchemaFileId}"). Creating new model (will check for duplicates).`);
4593
4740
  // Don't set modelRecord - we'll create a new model with potentially renamed name
4594
4741
  }
4595
4742
  else if (!modelRecord && schemaFileId && !dbSchemaFileId) {
4596
4743
  // We have a schemaFileId but the found model doesn't have one - this is a new model
4597
4744
  // Don't reuse the existing model, create a new one (will be renamed if duplicate)
4598
- logger$w(`Model "${modelName}" found by name but found model has no schemaFileId. Creating new model with schemaFileId "${schemaFileId}" (will check for duplicates).`);
4745
+ logger$x(`Model "${modelName}" found by name but found model has no schemaFileId. Creating new model with schemaFileId "${schemaFileId}" (will check for duplicates).`);
4599
4746
  // Don't set modelRecord - we'll create a new model
4600
4747
  }
4601
4748
  else if (!modelRecord) {
4602
4749
  // Only reuse existing model if:
4603
4750
  // 1. No schemaFileId was provided (loading existing model), OR
4604
4751
  // 2. schemaFileId matches (same model)
4605
- logger$w(`Model "${modelName}" found by name, reusing existing model (schemaFileId: provided="${schemaFileId}", db="${dbSchemaFileId}")`);
4752
+ logger$x(`Model "${modelName}" found by name, reusing existing model (schemaFileId: provided="${schemaFileId}", db="${dbSchemaFileId}")`);
4606
4753
  modelRecord = foundModel;
4607
4754
  // Only use database schemaFileId if no id was explicitly provided
4608
4755
  // If an id was provided, we should use it (it might be creating a new model with a specific ID)
4609
4756
  if (!id && dbSchemaFileId) {
4610
4757
  schemaFileId = dbSchemaFileId;
4611
- logger$w(`Using database schemaFileId "${schemaFileId}" for model "${modelName}" (no ID was provided)`);
4758
+ logger$x(`Using database schemaFileId "${schemaFileId}" for model "${modelName}" (no ID was provided)`);
4612
4759
  }
4613
4760
  else if (id) {
4614
- logger$w(`Preserving provided id (schemaFileId) "${schemaFileId}" for model "${modelName}" (ignoring database schemaFileId "${dbSchemaFileId}")`);
4761
+ logger$x(`Preserving provided id (schemaFileId) "${schemaFileId}" for model "${modelName}" (ignoring database schemaFileId "${dbSchemaFileId}")`);
4615
4762
  }
4616
- logger$w(`Found model "${modelName}" in database by name, schemaFileId: "${schemaFileId}"`);
4763
+ logger$x(`Found model "${modelName}" in database by name, schemaFileId: "${schemaFileId}"`);
4617
4764
  }
4618
4765
  }
4619
4766
  }
@@ -4638,7 +4785,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4638
4785
  // Generate schemaFileId if not set
4639
4786
  if (!schemaFileId) {
4640
4787
  schemaFileId = generateId();
4641
- logger$w(`Generated id (schemaFileId) "${schemaFileId}" for model "${modelName}"`);
4788
+ logger$x(`Generated id (schemaFileId) "${schemaFileId}" for model "${modelName}"`);
4642
4789
  }
4643
4790
  // Include _dbId from database record so properties can be created if needed
4644
4791
  // Even if we found an existing model, we may still need to create properties
@@ -4667,14 +4814,14 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4667
4814
  }
4668
4815
  }
4669
4816
  catch (error) {
4670
- logger$w(`Error loading model from database: ${error}`);
4817
+ logger$x(`Error loading model from database: ${error}`);
4671
4818
  // Fall through to create new model
4672
4819
  }
4673
4820
  }
4674
4821
  // Step 2: Fallback to Schema context (only if database doesn't have the model)
4675
4822
  // This handles the case where model exists in schema file but not yet in database
4676
4823
  try {
4677
- const schemaMod = await Promise.resolve().then(function () { return require('./Schema-STP972Xw.js'); });
4824
+ const schemaMod = await Promise.resolve().then(function () { return require('./Schema-DdP109QD.js'); });
4678
4825
  const { Schema } = schemaMod;
4679
4826
  // Stopped meanwhile (unloaded, or evicted with its schema): don't load the schema again
4680
4827
  if (isActorStopped(self))
@@ -4705,10 +4852,10 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4705
4852
  const byName = schemaContext.models[modelName];
4706
4853
  const schemaModelId = byName?.id ?? null;
4707
4854
  if (schemaFileId === schemaModelId) {
4708
- logger$w(`Found model "${modelName}" in Schema context (database fallback)`);
4855
+ logger$x(`Found model "${modelName}" in Schema context (database fallback)`);
4709
4856
  if (!schemaFileId) {
4710
4857
  schemaFileId = generateId();
4711
- logger$w(`Generated id (schemaFileId) "${schemaFileId}" for model "${modelName}"`);
4858
+ logger$x(`Generated id (schemaFileId) "${schemaFileId}" for model "${modelName}"`);
4712
4859
  }
4713
4860
  sendBack({
4714
4861
  type: 'loadOrCreateModelSuccess',
@@ -4724,7 +4871,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4724
4871
  // Schema context may not have model by name yet (e.g. still loading). If our id appears in any schema model, we're the schema model.
4725
4872
  for (const def of Object.values(schemaContext.models)) {
4726
4873
  if (def?.id === schemaFileId) {
4727
- logger$w(`Found model in Schema context by id "${schemaFileId}" (database fallback)`);
4874
+ logger$x(`Found model in Schema context by id "${schemaFileId}" (database fallback)`);
4728
4875
  sendBack({
4729
4876
  type: 'loadOrCreateModelSuccess',
4730
4877
  model: { id: schemaFileId },
@@ -4736,7 +4883,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4736
4883
  }
4737
4884
  }
4738
4885
  catch (error) {
4739
- logger$w(`Error loading model from Schema context: ${error}`);
4886
+ logger$x(`Error loading model from Schema context: ${error}`);
4740
4887
  // Fall through to create new model
4741
4888
  }
4742
4889
  // Step 3: Check for duplicate names in database before creating new model
@@ -4756,7 +4903,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4756
4903
  // 3. This is an internal schema (internal schemas should preserve original names from schema files), OR
4757
4904
  // 4. This instance was created with modelFileId from schema (_idFromSchema) - schema models keep their name
4758
4905
  const shouldSkipDuplicateCheck = modelRecord !== null || foundBySchemaFileId || isInternal || !!_idFromSchema;
4759
- logger$w(`Duplicate check: modelRecord=${modelRecord !== null}, foundBySchemaFileId=${foundBySchemaFileId}, isInternal=${isInternal}, _idFromSchema=${!!_idFromSchema}, schemaFileId=${schemaFileId}, shouldSkip=${shouldSkipDuplicateCheck}`);
4906
+ logger$x(`Duplicate check: modelRecord=${modelRecord !== null}, foundBySchemaFileId=${foundBySchemaFileId}, isInternal=${isInternal}, _idFromSchema=${!!_idFromSchema}, schemaFileId=${schemaFileId}, shouldSkip=${shouldSkipDuplicateCheck}`);
4760
4907
  if (!shouldSkipDuplicateCheck) {
4761
4908
  try {
4762
4909
  const lowerModelName = modelName.toLowerCase();
@@ -4768,7 +4915,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4768
4915
  // Check name-based cache for this schema
4769
4916
  // Skip the current model (context.id): Model.create() adds the new instance to the cache
4770
4917
  // before this callback runs, so we must not count it as a duplicate.
4771
- logger$w(`Checking Model cache for duplicates in schema "${schemaName}"`);
4918
+ logger$x(`Checking Model cache for duplicates in schema "${schemaName}"`);
4772
4919
  const currentModelFileId = schemaFileId ?? null;
4773
4920
  const cacheByName = Model.instanceCacheByName;
4774
4921
  for (const [nameKey, cachedModelFileId] of cacheByName.entries()) {
@@ -4779,7 +4926,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4779
4926
  const lowerCachedName = cachedModelName.toLowerCase();
4780
4927
  if (lowerCachedName === lowerModelName) {
4781
4928
  existingNumbers.add(0); // Base name exists
4782
- logger$w(`Found duplicate in Model cache: "${cachedModelName}" matches "${modelName}"`);
4929
+ logger$x(`Found duplicate in Model cache: "${cachedModelName}" matches "${modelName}"`);
4783
4930
  }
4784
4931
  else if (lowerCachedName.startsWith(lowerModelName + ' ')) {
4785
4932
  // Check if it's the base name followed by a space and a number
@@ -4787,7 +4934,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4787
4934
  const number = parseInt(suffix, 10);
4788
4935
  if (!isNaN(number) && suffix === number.toString()) {
4789
4936
  existingNumbers.add(number);
4790
- logger$w(`Found numbered variant in Model cache: "${cachedModelName}" (number: ${number})`);
4937
+ logger$x(`Found numbered variant in Model cache: "${cachedModelName}" (number: ${number})`);
4791
4938
  }
4792
4939
  }
4793
4940
  }
@@ -4803,7 +4950,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4803
4950
  const lowerCachedName = cachedModelName.toLowerCase();
4804
4951
  if (lowerCachedName === lowerModelName) {
4805
4952
  existingNumbers.add(0); // Base name exists
4806
- logger$w(`Found duplicate in Model legacy cache: "${cachedModelName}" matches "${modelName}"`);
4953
+ logger$x(`Found duplicate in Model legacy cache: "${cachedModelName}" matches "${modelName}"`);
4807
4954
  }
4808
4955
  else if (lowerCachedName.startsWith(lowerModelName + ' ')) {
4809
4956
  // Check if it's the base name followed by a space and a number
@@ -4811,14 +4958,14 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4811
4958
  const number = parseInt(suffix, 10);
4812
4959
  if (!isNaN(number) && suffix === number.toString()) {
4813
4960
  existingNumbers.add(number);
4814
- logger$w(`Found numbered variant in Model legacy cache: "${cachedModelName}" (number: ${number})`);
4961
+ logger$x(`Found numbered variant in Model legacy cache: "${cachedModelName}" (number: ${number})`);
4815
4962
  }
4816
4963
  }
4817
4964
  }
4818
4965
  }
4819
4966
  }
4820
4967
  catch (error) {
4821
- logger$w(`Error checking Model cache for duplicates: ${error}`);
4968
+ logger$x(`Error checking Model cache for duplicates: ${error}`);
4822
4969
  // Continue with database check
4823
4970
  }
4824
4971
  // Also check database for models (in case they're persisted but not in Schema context)
@@ -4828,7 +4975,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4828
4975
  const schemaSchemaMod = await Promise.resolve().then(function () { return SchemaSchema; });
4829
4976
  const { schemas: schemasTable } = schemaSchemaMod;
4830
4977
  // Query all models for this schema to check for duplicates (case-insensitive)
4831
- logger$w(`Checking database for duplicate model names in schema "${schemaName}"`);
4978
+ logger$x(`Checking database for duplicate model names in schema "${schemaName}"`);
4832
4979
  const allModelsForSchema = await db
4833
4980
  .select({
4834
4981
  name: models$1.name,
@@ -4837,16 +4984,16 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4837
4984
  .innerJoin(modelSchemas, drizzleOrm.eq(models$1.id, modelSchemas.modelId))
4838
4985
  .innerJoin(schemasTable, drizzleOrm.eq(modelSchemas.schemaId, schemasTable.id))
4839
4986
  .where(drizzleOrm.eq(schemasTable.name, schemaName));
4840
- logger$w(`Found ${allModelsForSchema.length} models in database for schema "${schemaName}": ${allModelsForSchema.map((m) => m.name).join(', ')}`);
4987
+ logger$x(`Found ${allModelsForSchema.length} models in database for schema "${schemaName}": ${allModelsForSchema.map((m) => m.name).join(', ')}`);
4841
4988
  if (allModelsForSchema.length === 0 && modelName.includes('Shared')) {
4842
- logger$w(`[DEBUG] No models found in database for schema "${schemaName}" when checking for duplicate "${modelName}"`);
4989
+ logger$x(`[DEBUG] No models found in database for schema "${schemaName}" when checking for duplicate "${modelName}"`);
4843
4990
  }
4844
4991
  // Check for exact match (case-insensitive) or matches with number suffix
4845
4992
  for (const dbModel of allModelsForSchema) {
4846
4993
  const lowerDbName = dbModel.name.toLowerCase();
4847
4994
  if (lowerDbName === lowerModelName) {
4848
4995
  existingNumbers.add(0); // Base name exists
4849
- logger$w(`Found duplicate in database: "${dbModel.name}" matches "${modelName}"`);
4996
+ logger$x(`Found duplicate in database: "${dbModel.name}" matches "${modelName}"`);
4850
4997
  }
4851
4998
  else if (lowerDbName.startsWith(lowerModelName + ' ')) {
4852
4999
  // Check if it's the base name followed by a space and a number
@@ -4854,48 +5001,48 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4854
5001
  const number = parseInt(suffix, 10);
4855
5002
  if (!isNaN(number) && suffix === number.toString()) {
4856
5003
  existingNumbers.add(number);
4857
- logger$w(`Found numbered variant in database: "${dbModel.name}" (number: ${number})`);
5004
+ logger$x(`Found numbered variant in database: "${dbModel.name}" (number: ${number})`);
4858
5005
  }
4859
5006
  }
4860
5007
  }
4861
5008
  }
4862
5009
  // If duplicates found, generate unique name
4863
- logger$w(`Duplicate check results: existingNumbers=${Array.from(existingNumbers).join(', ')}, hasBaseName=${existingNumbers.has(0)}`);
5010
+ logger$x(`Duplicate check results: existingNumbers=${Array.from(existingNumbers).join(', ')}, hasBaseName=${existingNumbers.has(0)}`);
4864
5011
  if (existingNumbers.has(0)) {
4865
5012
  let nextNumber = 1;
4866
5013
  while (existingNumbers.has(nextNumber)) {
4867
5014
  nextNumber++;
4868
5015
  }
4869
5016
  finalModelName = `${modelName} ${nextNumber}`;
4870
- logger$w(`Found duplicate model name "${modelName}" in schema "${schemaName}", using unique name "${finalModelName}"`);
5017
+ logger$x(`Found duplicate model name "${modelName}" in schema "${schemaName}", using unique name "${finalModelName}"`);
4871
5018
  }
4872
5019
  else {
4873
- logger$w(`No duplicate found for model name "${modelName}" in schema "${schemaName}"`);
5020
+ logger$x(`No duplicate found for model name "${modelName}" in schema "${schemaName}"`);
4874
5021
  }
4875
5022
  }
4876
5023
  catch (error) {
4877
- logger$w(`Error checking for duplicate model names: ${error}`);
5024
+ logger$x(`Error checking for duplicate model names: ${error}`);
4878
5025
  // Continue with original name if check fails
4879
5026
  }
4880
5027
  }
4881
5028
  else {
4882
5029
  if (foundBySchemaFileId) {
4883
- logger$w(`Preserving original model name "${modelName}" for model found by schemaFileId (schemaFileId: ${schemaFileId})`);
5030
+ logger$x(`Preserving original model name "${modelName}" for model found by schemaFileId (schemaFileId: ${schemaFileId})`);
4884
5031
  }
4885
5032
  else if (modelRecord) {
4886
- logger$w(`Using existing model name "${modelName}" from database (modelRecord found)`);
5033
+ logger$x(`Using existing model name "${modelName}" from database (modelRecord found)`);
4887
5034
  }
4888
5035
  else if (isInternal) {
4889
- logger$w(`Preserving original model name "${modelName}" for internal schema "${schemaName}" (skipping duplicate check)`);
5036
+ logger$x(`Preserving original model name "${modelName}" for internal schema "${schemaName}" (skipping duplicate check)`);
4890
5037
  }
4891
5038
  }
4892
5039
  }
4893
5040
  // Step 4: Create new empty model (not found in database or Schema context)
4894
- logger$w(`Creating new model "${finalModelName}" in schema "${schemaName}"`);
5041
+ logger$x(`Creating new model "${finalModelName}" in schema "${schemaName}"`);
4895
5042
  // Generate schemaFileId for new model
4896
5043
  if (!schemaFileId) {
4897
5044
  schemaFileId = generateId();
4898
- logger$w(`Generated id (schemaFileId) "${schemaFileId}" for new model "${finalModelName}"`);
5045
+ logger$x(`Generated id (schemaFileId) "${schemaFileId}" for new model "${finalModelName}"`);
4899
5046
  }
4900
5047
  // Runtime creates use a placeholder cache key in Model.create; move it to the final name. Skip when schema model (_idFromSchema).
4901
5048
  if (!_idFromSchema) {
@@ -4907,7 +5054,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4907
5054
  // This avoids the issue where updateContext with modelName triggers validation and state transition
4908
5055
  // We use _pendingModelName (internal field) which won't trigger validation
4909
5056
  if (finalModelName !== modelName) {
4910
- logger$w(`Model name changed from "${modelName}" to "${finalModelName}", storing in _pendingModelName for loadOrCreateModelSuccess`);
5057
+ logger$x(`Model name changed from "${modelName}" to "${finalModelName}", storing in _pendingModelName for loadOrCreateModelSuccess`);
4911
5058
  // Store the final name in a temporary internal field that will be picked up by loadOrCreateModelSuccess
4912
5059
  sendBack({
4913
5060
  type: 'updateContext',
@@ -4915,11 +5062,11 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4915
5062
  });
4916
5063
  }
4917
5064
  else {
4918
- logger$w(`Model name unchanged: "${modelName}"`);
5065
+ logger$x(`Model name unchanged: "${modelName}"`);
4919
5066
  }
4920
5067
  // Mark schema as draft when a new model is created so saveNewVersion() can persist it
4921
5068
  try {
4922
- const schemaMod = await Promise.resolve().then(function () { return require('./Schema-STP972Xw.js'); });
5069
+ const schemaMod = await Promise.resolve().then(function () { return require('./Schema-DdP109QD.js'); });
4923
5070
  const { Schema } = schemaMod;
4924
5071
  if (!isActorStopped(self)) {
4925
5072
  const schema = Schema.create(schemaName, { waitForReady: false });
@@ -4927,7 +5074,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4927
5074
  }
4928
5075
  }
4929
5076
  catch (err) {
4930
- logger$w(`Failed to mark schema as draft after creating model: ${err}`);
5077
+ logger$x(`Failed to mark schema as draft after creating model: ${err}`);
4931
5078
  }
4932
5079
  sendBack({
4933
5080
  type: 'loadOrCreateModelSuccess',
@@ -4937,12 +5084,12 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context }, s
4937
5084
  });
4938
5085
  };
4939
5086
  _loadOrCreateModel().catch((error) => {
4940
- logger$w('Error loading or creating model:', error);
5087
+ logger$x('Error loading or creating model:', error);
4941
5088
  sendBack({ type: 'loadOrCreateModelError', error });
4942
5089
  });
4943
5090
  });
4944
5091
 
4945
- const logger$v = debug('seedSdk:model:actors:validateModel');
5092
+ const logger$w = debug('seedSdk:model:actors:validateModel');
4946
5093
  // Validation timeout in milliseconds (10 seconds)
4947
5094
  const VALIDATION_TIMEOUT_MS = 10000;
4948
5095
  const validateModel = xstate.fromCallback(({ sendBack, input: { context }, self }) => {
@@ -4965,10 +5112,10 @@ const validateModel = xstate.fromCallback(({ sendBack, input: { context }, self
4965
5112
  const _validateModel = async () => {
4966
5113
  try {
4967
5114
  // Use dynamic imports to break circular dependencies
4968
- const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-CKNW1bKg.js'); });
5115
+ const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-CSXxx7sQ.js'); });
4969
5116
  const { SchemaValidationService } = validationServiceMod;
4970
5117
  const validationService = new SchemaValidationService();
4971
- const schemaMod = await Promise.resolve().then(function () { return require('./Schema-STP972Xw.js'); });
5118
+ const schemaMod = await Promise.resolve().then(function () { return require('./Schema-DdP109QD.js'); });
4972
5119
  const { Schema } = schemaMod;
4973
5120
  // Validate model structure
4974
5121
  const structureResult = validationService.validateModelStructure(context);
@@ -5012,12 +5159,12 @@ const validateModel = xstate.fromCallback(({ sendBack, input: { context }, self
5012
5159
  }
5013
5160
  }
5014
5161
  else {
5015
- logger$v(`Schema is in ${schemaStatus} state, skipping schema validation`);
5162
+ logger$w(`Schema is in ${schemaStatus} state, skipping schema validation`);
5016
5163
  // Continue with structure validation only
5017
5164
  }
5018
5165
  }
5019
5166
  catch (error) {
5020
- logger$v('Error validating model against schema:', error);
5167
+ logger$w('Error validating model against schema:', error);
5021
5168
  // Continue with structure validation only
5022
5169
  }
5023
5170
  }
@@ -5032,7 +5179,7 @@ const validateModel = xstate.fromCallback(({ sendBack, input: { context }, self
5032
5179
  if (!hasResponded) {
5033
5180
  hasResponded = true;
5034
5181
  clearTimeout(timeoutId);
5035
- logger$v('Error in validateModel:', error);
5182
+ logger$w('Error in validateModel:', error);
5036
5183
  sendBack({
5037
5184
  type: 'validationError',
5038
5185
  errors: [{
@@ -5049,7 +5196,7 @@ const validateModel = xstate.fromCallback(({ sendBack, input: { context }, self
5049
5196
  if (!hasResponded) {
5050
5197
  hasResponded = true;
5051
5198
  clearTimeout(timeoutId);
5052
- logger$v('Error in validateModel:', error);
5199
+ logger$w('Error in validateModel:', error);
5053
5200
  sendBack({
5054
5201
  type: 'validationError',
5055
5202
  errors: [{
@@ -5067,7 +5214,7 @@ const validateModel = xstate.fromCallback(({ sendBack, input: { context }, self
5067
5214
  };
5068
5215
  });
5069
5216
 
5070
- const logger$u = debug('seedSdk:model:actors:createModelProperties');
5217
+ const logger$v = debug('seedSdk:model:actors:createModelProperties');
5071
5218
  const createModelProperties = xstate.fromCallback(({ sendBack, input, self }) => {
5072
5219
  // The model was stopped (unloaded, or evicted with its schema by Schema.destroy / test cleanup) while
5073
5220
  // this ran: stopping it stops this actor too, but can't cancel the awaits below. A stopped model
@@ -5080,15 +5227,15 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input, self }) =>
5080
5227
  throw new Error('Model ID, file ID, and name are required to create properties');
5081
5228
  }
5082
5229
  if (!propertyDefinitions || Object.keys(propertyDefinitions).length === 0) {
5083
- logger$u('No property definitions provided, skipping property creation');
5230
+ logger$v('No property definitions provided, skipping property creation');
5084
5231
  sendBack({ type: 'createModelPropertiesSuccess' });
5085
5232
  return;
5086
5233
  }
5087
- logger$u(`Creating ${Object.keys(propertyDefinitions).length} properties for model "${modelName}" (id: ${_dbId})`);
5088
- const mod = await Promise.resolve().then(function () { return require('./ModelProperty-B-cZm1yU.js'); });
5234
+ logger$v(`Creating ${Object.keys(propertyDefinitions).length} properties for model "${modelName}" (id: ${_dbId})`);
5235
+ const mod = await Promise.resolve().then(function () { return require('./ModelProperty-DXZ39Wyv.js'); });
5089
5236
  const ModelProperty = mod?.ModelProperty ?? mod?.default;
5090
5237
  if (!ModelProperty) {
5091
- logger$u('ModelProperty not available from dynamic import');
5238
+ logger$v('ModelProperty not available from dynamic import');
5092
5239
  sendBack({ type: 'createModelPropertiesError', error: new Error('ModelProperty not available') });
5093
5240
  return;
5094
5241
  }
@@ -5112,7 +5259,7 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input, self }) =>
5112
5259
  // IDs should be generated in the import process before creating properties
5113
5260
  const { generateId } = await Promise.resolve().then(function () { return generateId$1; });
5114
5261
  const propertyFileId = propData.id || propertyRecord?.schemaFileId || generateId();
5115
- logger$u(`Creating property "${propName}" with fileId "${propertyFileId}"`);
5262
+ logger$v(`Creating property "${propName}" with fileId "${propertyFileId}"`);
5116
5263
  // Query database to get refModelId if the property has ref/refModelName
5117
5264
  // The property should already be in DB from addModelsToDb
5118
5265
  let refModelId = propData.refModelId;
@@ -5122,7 +5269,7 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input, self }) =>
5122
5269
  // First try to get refModelId from the property record in the database
5123
5270
  if (propertyRecord?.refModelId) {
5124
5271
  refModelId = propertyRecord.refModelId;
5125
- logger$u(`Found refModelId ${refModelId} from database for property "${propName}"`);
5272
+ logger$v(`Found refModelId ${refModelId} from database for property "${propName}"`);
5126
5273
  }
5127
5274
  else if (refModelName) {
5128
5275
  // Fallback: resolve the ref by name within this model's schema
@@ -5130,17 +5277,17 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input, self }) =>
5130
5277
  const refModelRecord = await resolveModelRecord(refModelName, { schemaName }, db);
5131
5278
  if (refModelRecord?.id) {
5132
5279
  refModelId = refModelRecord.id;
5133
- logger$u(`Resolved refModelId ${refModelId} from model name "${refModelName}" for property "${propName}"`);
5280
+ logger$v(`Resolved refModelId ${refModelId} from model name "${refModelName}" for property "${propName}"`);
5134
5281
  }
5135
5282
  }
5136
5283
  }
5137
5284
  catch (error) {
5138
- logger$u(`Error fetching refModelId for property "${propName}":`, error);
5285
+ logger$v(`Error fetching refModelId for property "${propName}":`, error);
5139
5286
  // Continue without refModelId - it will be resolved later in _initializeOriginalValues
5140
5287
  }
5141
5288
  }
5142
5289
  if (stopped()) {
5143
- logger$u(`Model "${modelName}" was stopped while creating its properties; not creating the rest`);
5290
+ logger$v(`Model "${modelName}" was stopped while creating its properties; not creating the rest`);
5144
5291
  return;
5145
5292
  }
5146
5293
  // Create ModelProperty instance
@@ -5166,11 +5313,11 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input, self }) =>
5166
5313
  _dbId: propertyRecord?.schemaFileId === propertyFileId ? propertyRecord.id : undefined, // Already persisted: skip the write
5167
5314
  }, { schemaName }); // Use 'as any' because _propertyFileId is not in TProperty type
5168
5315
  }
5169
- logger$u(`Successfully created all properties for model "${modelName}"`);
5316
+ logger$v(`Successfully created all properties for model "${modelName}"`);
5170
5317
  sendBack({ type: 'createModelPropertiesSuccess' });
5171
5318
  };
5172
5319
  _createProperties().catch((error) => {
5173
- logger$u(`Error creating model properties: ${error}`);
5320
+ logger$v(`Error creating model properties: ${error}`);
5174
5321
  sendBack({
5175
5322
  type: 'createModelPropertiesError',
5176
5323
  error: error instanceof Error ? error : new Error(String(error))
@@ -5212,7 +5359,7 @@ function anyEvictionSince(since) {
5212
5359
  return epoch !== since;
5213
5360
  }
5214
5361
 
5215
- const logger$t = debug('seedSdk:write:validateEntity');
5362
+ const logger$u = debug('seedSdk:write:validateEntity');
5216
5363
  // XState v5 type inference bug: fromPromise types are inverted
5217
5364
  // We use type assertion to work around this
5218
5365
  const validateEntity = xstate.fromPromise(async ({ input }) => {
@@ -5225,7 +5372,7 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
5225
5372
  const evictionEpoch = currentEvictionEpoch();
5226
5373
  /** The schema to validate against; throws (validation then skips the schema check) once it was evicted. */
5227
5374
  const schemaForValidation = async (schemaName) => {
5228
- const { Schema } = await Promise.resolve().then(function () { return require('./Schema-STP972Xw.js'); });
5375
+ const { Schema } = await Promise.resolve().then(function () { return require('./Schema-DdP109QD.js'); });
5229
5376
  if (schemaEvictedSince(schemaName, evictionEpoch)) {
5230
5377
  throw new Error(`Schema "${schemaName}" was evicted during validation`);
5231
5378
  }
@@ -5234,20 +5381,20 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
5234
5381
  const _validate = async () => {
5235
5382
  try {
5236
5383
  const msg = `[validateEntity] Starting validation for ${entityInput.entityType}`;
5237
- logger$t(msg);
5238
- logger$t(`[validateEntity] Entity data:`, entityInput.entityData);
5384
+ logger$u(msg);
5385
+ logger$u(`[validateEntity] Entity data:`, entityInput.entityData);
5239
5386
  let result = { isValid: true, errors: [] };
5240
5387
  if (entityInput.entityType === 'model') {
5241
5388
  const structureMsg = `[validateEntity] Validating model structure`;
5242
- logger$t(structureMsg);
5389
+ logger$u(structureMsg);
5243
5390
  // Use existing Model validation
5244
- const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-CKNW1bKg.js'); });
5391
+ const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-CSXxx7sQ.js'); });
5245
5392
  const { SchemaValidationService } = validationServiceMod;
5246
5393
  const validationService = new SchemaValidationService();
5247
5394
  // Validate model structure
5248
5395
  const structureResult = validationService.validateModelStructure(entityInput.entityData);
5249
5396
  const structureResultMsg = `[validateEntity] Structure validation result: isValid=${structureResult.isValid}, errors=${structureResult.errors?.length || 0}`;
5250
- logger$t(structureResultMsg);
5397
+ logger$u(structureResultMsg);
5251
5398
  if (!structureResult.isValid) {
5252
5399
  result = {
5253
5400
  isValid: false,
@@ -5258,16 +5405,16 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
5258
5405
  // If schema name provided, validate against schema
5259
5406
  if (entityInput.entityData.schemaName) {
5260
5407
  try {
5261
- logger$t(`[validateEntity] Validating model against schema "${entityInput.entityData.schemaName}"`);
5408
+ logger$u(`[validateEntity] Validating model against schema "${entityInput.entityData.schemaName}"`);
5262
5409
  const schema = await schemaForValidation(entityInput.entityData.schemaName);
5263
5410
  const schemaSnapshot = schema.getService().getSnapshot();
5264
5411
  const schemaStatus = schemaSnapshot.value;
5265
- logger$t(`[validateEntity] Schema status: ${schemaStatus}`);
5412
+ logger$u(`[validateEntity] Schema status: ${schemaStatus}`);
5266
5413
  if (schemaStatus === 'idle') {
5267
5414
  const schemaContext = schemaSnapshot.context;
5268
- logger$t(`[validateEntity] Running validateModelAgainstSchema`);
5415
+ logger$u(`[validateEntity] Running validateModelAgainstSchema`);
5269
5416
  const schemaResult = validationService.validateModelAgainstSchema(schemaContext, entityInput.entityData.modelName, entityInput.entityData);
5270
- logger$t(`[validateEntity] Schema validation result:`, schemaResult);
5417
+ logger$u(`[validateEntity] Schema validation result:`, schemaResult);
5271
5418
  if (!schemaResult.isValid) {
5272
5419
  result = {
5273
5420
  isValid: false,
@@ -5276,22 +5423,22 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
5276
5423
  }
5277
5424
  }
5278
5425
  else {
5279
- logger$t(`[validateEntity] Schema not in idle state (${schemaStatus}), skipping schema validation`);
5426
+ logger$u(`[validateEntity] Schema not in idle state (${schemaStatus}), skipping schema validation`);
5280
5427
  }
5281
5428
  }
5282
5429
  catch (error) {
5283
- logger$t('Error validating model against schema:', error);
5430
+ logger$u('Error validating model against schema:', error);
5284
5431
  // Continue with structure validation only
5285
5432
  }
5286
5433
  }
5287
5434
  else {
5288
- logger$t(`[validateEntity] No schemaName provided, skipping schema validation`);
5435
+ logger$u(`[validateEntity] No schemaName provided, skipping schema validation`);
5289
5436
  }
5290
5437
  }
5291
5438
  }
5292
5439
  else if (entityInput.entityType === 'modelProperty') {
5293
5440
  // Use existing ModelProperty validation
5294
- const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-CKNW1bKg.js'); });
5441
+ const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-CSXxx7sQ.js'); });
5295
5442
  const { SchemaValidationService } = validationServiceMod;
5296
5443
  const validationService = new SchemaValidationService();
5297
5444
  // Validate property structure
@@ -5323,7 +5470,7 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
5323
5470
  }
5324
5471
  }
5325
5472
  catch (error) {
5326
- logger$t('Error validating property against schema:', error);
5473
+ logger$u('Error validating property against schema:', error);
5327
5474
  // Continue with structure validation only
5328
5475
  }
5329
5476
  }
@@ -5331,7 +5478,7 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
5331
5478
  }
5332
5479
  else if (entityInput.entityType === 'schema') {
5333
5480
  // Schema validation - use existing validation
5334
- const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-CKNW1bKg.js'); });
5481
+ const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-CSXxx7sQ.js'); });
5335
5482
  const { SchemaValidationService } = validationServiceMod;
5336
5483
  const validationService = new SchemaValidationService();
5337
5484
  const schemaResult = validationService.validateSchema(entityInput.entityData);
@@ -5344,14 +5491,14 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
5344
5491
  }
5345
5492
  // Return the result - fromPromise will automatically put this in event.output
5346
5493
  const completeMsg = `[validateEntity] Validation complete: isValid=${result.isValid}, errors=${result.errors?.length || 0}`;
5347
- logger$t(completeMsg);
5348
- logger$t(`[validateEntity] Validation complete:`, result);
5494
+ logger$u(completeMsg);
5495
+ logger$u(`[validateEntity] Validation complete:`, result);
5349
5496
  return result;
5350
5497
  }
5351
5498
  catch (error) {
5352
5499
  const errorMsg = `[validateEntity] Error in validateEntity: ${error instanceof Error ? error.message : String(error)}`;
5353
- logger$t(errorMsg);
5354
- logger$t('Error in validateEntity:', error);
5500
+ logger$u(errorMsg);
5501
+ logger$u('Error in validateEntity:', error);
5355
5502
  // Throw error - fromPromise will automatically create error.platform event
5356
5503
  throw error;
5357
5504
  }
@@ -5360,7 +5507,7 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
5360
5507
  // @ts-ignore - XState v5 type inference bug: fromPromise incorrectly expects output type to match input type
5361
5508
  });
5362
5509
 
5363
- const logger$s = debug('seedSdk:write:writeToDatabase');
5510
+ const logger$t = debug('seedSdk:write:writeToDatabase');
5364
5511
  // Writes that have started. Stopping a write process's actor can't cancel one, so code that deletes rows
5365
5512
  // under live instances (Schema.destroy, test cleanup) waits for these after evicting the instances.
5366
5513
  const inFlightWrites = new Set();
@@ -5387,8 +5534,8 @@ const writeToDatabase = xstate.fromCallback(({ sendBack, input }) => {
5387
5534
  let output = input.entityData;
5388
5535
  if (input.entityType === 'model') {
5389
5536
  const writeMsg = `Writing model to database: ${input.entityData.modelName} (schemaId: ${input.entityData.schemaId})`;
5390
- logger$s(writeMsg);
5391
- logger$s(`Writing model to database:`, {
5537
+ logger$t(writeMsg);
5538
+ logger$t(`Writing model to database:`, {
5392
5539
  modelFileId: input.entityId,
5393
5540
  modelName: input.entityData.modelName,
5394
5541
  schemaId: input.entityData.schemaId,
@@ -5413,14 +5560,14 @@ const writeToDatabase = xstate.fromCallback(({ sendBack, input }) => {
5413
5560
  output = input.entityData;
5414
5561
  }
5415
5562
  const successMsg = `Successfully wrote model "${input.entityData.modelName}" to database`;
5416
- logger$s(successMsg);
5563
+ logger$t(successMsg);
5417
5564
  }
5418
5565
  else if (input.entityType === 'modelProperty') {
5419
5566
  // Use current ModelProperty context when available so a user rename before the
5420
5567
  // initial write completes is not overwritten by the stale requestWrite payload.
5421
5568
  let dataToWrite = input.entityData;
5422
5569
  try {
5423
- const mod = await Promise.resolve().then(function () { return require('./ModelProperty-B-cZm1yU.js'); });
5570
+ const mod = await Promise.resolve().then(function () { return require('./ModelProperty-DXZ39Wyv.js'); });
5424
5571
  const ModelProperty = mod?.ModelProperty ?? mod?.default;
5425
5572
  if (ModelProperty && typeof ModelProperty.getById === 'function') {
5426
5573
  const instance = ModelProperty.getById(input.entityId);
@@ -5463,7 +5610,7 @@ const writeToDatabase = xstate.fromCallback(({ sendBack, input }) => {
5463
5610
  });
5464
5611
  }
5465
5612
  catch (error) {
5466
- logger$s('Error in writeToDatabase:', error);
5613
+ logger$t('Error in writeToDatabase:', error);
5467
5614
  sendBack({
5468
5615
  type: 'writeError',
5469
5616
  error: error instanceof Error ? error : new Error(String(error)),
@@ -5471,7 +5618,7 @@ const writeToDatabase = xstate.fromCallback(({ sendBack, input }) => {
5471
5618
  }
5472
5619
  };
5473
5620
  const write = _write().catch((error) => {
5474
- logger$s('Error in writeToDatabase promise:', error);
5621
+ logger$t('Error in writeToDatabase promise:', error);
5475
5622
  sendBack({
5476
5623
  type: 'writeError',
5477
5624
  error: error instanceof Error ? error : new Error(String(error)),
@@ -5490,7 +5637,7 @@ var writeToDatabase$1 = /*#__PURE__*/Object.freeze({
5490
5637
  writeToDatabase: writeToDatabase
5491
5638
  });
5492
5639
 
5493
- const logger$r = debug('seedSdk:write:writeProcessMachine');
5640
+ const logger$s = debug('seedSdk:write:writeProcessMachine');
5494
5641
  const writeProcessMachine = xstate.setup({
5495
5642
  types: {
5496
5643
  context: {},
@@ -5528,8 +5675,8 @@ const writeProcessMachine = xstate.setup({
5528
5675
  writeStatus: 'validating',
5529
5676
  }),
5530
5677
  ({ event, context }) => {
5531
- logger$r(`[startWrite] Received startWrite for ${context.entityType} "${context.entityId}"`);
5532
- logger$r(`[startWrite] Data:`, event.data);
5678
+ logger$s(`[startWrite] Received startWrite for ${context.entityType} "${context.entityId}"`);
5679
+ logger$s(`[startWrite] Data:`, event.data);
5533
5680
  },
5534
5681
  ],
5535
5682
  },
@@ -5538,14 +5685,14 @@ const writeProcessMachine = xstate.setup({
5538
5685
  validating: {
5539
5686
  entry: ({ context }) => {
5540
5687
  const msg = `[validating] Entering validating state for ${context.entityType} "${context.entityId}"`;
5541
- logger$r(msg);
5542
- logger$r(`[validating] Entity data:`, context.pendingWrite?.data || context.entityData);
5688
+ logger$s(msg);
5689
+ logger$s(`[validating] Entity data:`, context.pendingWrite?.data || context.entityData);
5543
5690
  },
5544
5691
  invoke: {
5545
5692
  src: 'validateEntity',
5546
5693
  input: ({ context }) => {
5547
5694
  const entityData = context.pendingWrite?.data || context.entityData;
5548
- logger$r(`[validating] Invoking validateEntity with:`, { entityType: context.entityType, entityData });
5695
+ logger$s(`[validating] Invoking validateEntity with:`, { entityType: context.entityType, entityData });
5549
5696
  return {
5550
5697
  entityType: context.entityType,
5551
5698
  entityData,
@@ -5573,8 +5720,8 @@ const writeProcessMachine = xstate.setup({
5573
5720
  return false;
5574
5721
  }
5575
5722
  const resultMsg = `[validating] Validation result: isValid=${result.isValid}, errors=${result.errors?.length || 0}`;
5576
- logger$r(resultMsg);
5577
- logger$r(`[validating] Validation result:`, result);
5723
+ logger$s(resultMsg);
5724
+ logger$s(`[validating] Validation result:`, result);
5578
5725
  return result.isValid;
5579
5726
  },
5580
5727
  actions: [
@@ -5584,7 +5731,7 @@ const writeProcessMachine = xstate.setup({
5584
5731
  }),
5585
5732
  ({ context }) => {
5586
5733
  const msg = `[validating] Validation passed, transitioning to writing for ${context.entityType} "${context.entityId}"`;
5587
- logger$r(msg);
5734
+ logger$s(msg);
5588
5735
  },
5589
5736
  ],
5590
5737
  },
@@ -5604,7 +5751,7 @@ const writeProcessMachine = xstate.setup({
5604
5751
  }),
5605
5752
  ({ context, event }) => {
5606
5753
  const result = event.output;
5607
- logger$r(`[validating] Validation failed for ${context.entityType} "${context.entityId}":`, result.errors);
5754
+ logger$s(`[validating] Validation failed for ${context.entityType} "${context.entityId}":`, result.errors);
5608
5755
  },
5609
5756
  ],
5610
5757
  },
@@ -5618,7 +5765,7 @@ const writeProcessMachine = xstate.setup({
5618
5765
  }),
5619
5766
  ({ context, event }) => {
5620
5767
  const errorMsg = `[validating] Validation error for ${context.entityType} "${context.entityId}": ${event.error}`;
5621
- logger$r(errorMsg);
5768
+ logger$s(errorMsg);
5622
5769
  console.error(errorMsg, event.error); // Always log to console
5623
5770
  },
5624
5771
  ],
@@ -5633,8 +5780,8 @@ const writeProcessMachine = xstate.setup({
5633
5780
  src: 'writeToDatabase',
5634
5781
  input: ({ context }) => {
5635
5782
  const entityData = context.pendingWrite?.data || context.entityData;
5636
- logger$r(`[writing] Calling writeToDatabase for ${context.entityType} "${context.entityId}"`);
5637
- logger$r(`[writing] Entity data:`, entityData);
5783
+ logger$s(`[writing] Calling writeToDatabase for ${context.entityType} "${context.entityId}"`);
5784
+ logger$s(`[writing] Entity data:`, entityData);
5638
5785
  return {
5639
5786
  entityType: context.entityType,
5640
5787
  entityId: context.entityId,
@@ -5655,7 +5802,7 @@ const writeProcessMachine = xstate.setup({
5655
5802
  },
5656
5803
  }),
5657
5804
  ({ context }) => {
5658
- logger$r(`[writing] Write successful for ${context.entityType} "${context.entityId}"`);
5805
+ logger$s(`[writing] Write successful for ${context.entityType} "${context.entityId}"`);
5659
5806
  },
5660
5807
  ],
5661
5808
  },
@@ -5669,7 +5816,7 @@ const writeProcessMachine = xstate.setup({
5669
5816
  }),
5670
5817
  ({ context, event }) => {
5671
5818
  const errorMsg = `[writing] Write error for ${context.entityType} "${context.entityId}": ${event.error}`;
5672
- logger$r(errorMsg);
5819
+ logger$s(errorMsg);
5673
5820
  // Nothing else reports a failed persist to the caller, so always log to console
5674
5821
  console.error(errorMsg, event.error);
5675
5822
  },
@@ -5712,7 +5859,7 @@ const writeProcessMachine = xstate.setup({
5712
5859
  },
5713
5860
  });
5714
5861
 
5715
- const logger$q = debug('seedSdk:model:modelMachine');
5862
+ const logger$r = debug('seedSdk:model:modelMachine');
5716
5863
  const modelMachine = xstate.setup({
5717
5864
  types: {
5718
5865
  context: {},
@@ -5814,25 +5961,25 @@ const modelMachine = xstate.setup({
5814
5961
  // Create ModelProperty instances for any new property IDs
5815
5962
  if (Array.isArray(newPropertyIds) && newPropertyIds.length > 0) {
5816
5963
  // Import and create instances asynchronously (fire-and-forget)
5817
- Promise.resolve().then(function () { return require('./ModelProperty-B-cZm1yU.js'); }).then(({ ModelProperty }) => {
5964
+ Promise.resolve().then(function () { return require('./ModelProperty-DXZ39Wyv.js'); }).then(({ ModelProperty }) => {
5818
5965
  if (self.getSnapshot().status === 'stopped')
5819
5966
  return;
5820
5967
  const createPromises = newPropertyIds.map(async (propertyFileId) => {
5821
5968
  try {
5822
5969
  const property = await ModelProperty.createById(propertyFileId, { evictionEpoch });
5823
5970
  if (property) {
5824
- logger$q(`[modelMachine] Created/cached ModelProperty instance for propertyFileId "${propertyFileId}" after _liveQueryPropertyIds update`);
5971
+ logger$r(`[modelMachine] Created/cached ModelProperty instance for propertyFileId "${propertyFileId}" after _liveQueryPropertyIds update`);
5825
5972
  }
5826
5973
  }
5827
5974
  catch (error) {
5828
- logger$q(`[modelMachine] Error creating ModelProperty instance for propertyFileId "${propertyFileId}": ${error}`);
5975
+ logger$r(`[modelMachine] Error creating ModelProperty instance for propertyFileId "${propertyFileId}": ${error}`);
5829
5976
  }
5830
5977
  });
5831
5978
  Promise.all(createPromises).catch((error) => {
5832
- logger$q(`[modelMachine] Error creating property instances: ${error}`);
5979
+ logger$r(`[modelMachine] Error creating property instances: ${error}`);
5833
5980
  });
5834
5981
  }).catch((error) => {
5835
- logger$q(`[modelMachine] Error importing ModelProperty: ${error}`);
5982
+ logger$r(`[modelMachine] Error importing ModelProperty: ${error}`);
5836
5983
  });
5837
5984
  }
5838
5985
  }, 0);
@@ -5910,11 +6057,11 @@ const modelMachine = xstate.setup({
5910
6057
  target: 'idle',
5911
6058
  actions: xstate.assign(({ context, event }) => {
5912
6059
  const hasPendingProps = !!(context._pendingPropertyDefinitions && Object.keys(context._pendingPropertyDefinitions).length > 0);
5913
- logger$q(`[loadOrCreateModelSuccess] Preserving _pendingPropertyDefinitions: ${hasPendingProps} (${Object.keys(context._pendingPropertyDefinitions || {}).length} properties)`);
6060
+ logger$r(`[loadOrCreateModelSuccess] Preserving _pendingPropertyDefinitions: ${hasPendingProps} (${Object.keys(context._pendingPropertyDefinitions || {}).length} properties)`);
5914
6061
  // Check if there's a pending model name update (set before this event to avoid validation trigger)
5915
6062
  const finalModelName = context._pendingModelName || context.modelName;
5916
6063
  if (context._pendingModelName) {
5917
- logger$q(`[loadOrCreateModelSuccess] Applying pending model name: "${context.modelName}" -> "${finalModelName}"`);
6064
+ logger$r(`[loadOrCreateModelSuccess] Applying pending model name: "${context.modelName}" -> "${finalModelName}"`);
5918
6065
  }
5919
6066
  return {
5920
6067
  ...context,
@@ -5955,7 +6102,7 @@ const modelMachine = xstate.setup({
5955
6102
  entry: xstate.assign({
5956
6103
  writeProcess: ({ context, spawn }) => {
5957
6104
  if (!context.writeProcess && context.id) {
5958
- logger$q(`[idle entry] Spawning writeProcess for model "${context.modelName}" (${context.id})`);
6105
+ logger$r(`[idle entry] Spawning writeProcess for model "${context.modelName}" (${context.id})`);
5959
6106
  return spawn(writeProcessMachine, {
5960
6107
  input: {
5961
6108
  entityType: 'model',
@@ -5976,7 +6123,7 @@ const modelMachine = xstate.setup({
5976
6123
  actions: ({ self }) => {
5977
6124
  // This event will be handled by the Model instance's subscription
5978
6125
  // The Model will call _refreshPropertiesFromDb when it receives this event
5979
- logger$q(`[idle] refreshProperties event received, will be handled by Model instance`);
6126
+ logger$r(`[idle] refreshProperties event received, will be handled by Model instance`);
5980
6127
  },
5981
6128
  },
5982
6129
  validateModel: {
@@ -5988,14 +6135,14 @@ const modelMachine = xstate.setup({
5988
6135
  requestWrite: {
5989
6136
  actions: ({ context, event }) => {
5990
6137
  if (context.writeProcess) {
5991
- logger$q(`[requestWrite] Sending startWrite to writeProcess with data:`, event.data);
6138
+ logger$r(`[requestWrite] Sending startWrite to writeProcess with data:`, event.data);
5992
6139
  context.writeProcess.send({
5993
6140
  type: 'startWrite',
5994
6141
  data: event.data,
5995
6142
  });
5996
6143
  }
5997
6144
  else {
5998
- logger$q(`[requestWrite] ERROR: writeProcess not available for model "${context.modelName}" (${context.id})`);
6145
+ logger$r(`[requestWrite] ERROR: writeProcess not available for model "${context.modelName}" (${context.id})`);
5999
6146
  }
6000
6147
  },
6001
6148
  },
@@ -6004,18 +6151,18 @@ const modelMachine = xstate.setup({
6004
6151
  guard: ({ context }) => {
6005
6152
  // If we have pending property definitions, transition to creatingProperties
6006
6153
  const hasPending = !!(context._pendingPropertyDefinitions && Object.keys(context._pendingPropertyDefinitions).length > 0);
6007
- logger$q(`[writeSuccess guard] hasPending: ${hasPending}, _pendingPropertyDefinitions keys: ${context._pendingPropertyDefinitions ? Object.keys(context._pendingPropertyDefinitions).length : 0}`);
6154
+ logger$r(`[writeSuccess guard] hasPending: ${hasPending}, _pendingPropertyDefinitions keys: ${context._pendingPropertyDefinitions ? Object.keys(context._pendingPropertyDefinitions).length : 0}`);
6008
6155
  return hasPending;
6009
6156
  },
6010
6157
  target: 'creatingProperties',
6011
6158
  actions: xstate.assign(({ context, event }) => {
6012
- logger$q(`[writeSuccess] Transitioning to creatingProperties for model "${context.modelName}"`);
6159
+ logger$r(`[writeSuccess] Transitioning to creatingProperties for model "${context.modelName}"`);
6013
6160
  // Update _dbId from write output if available (writeToDatabase returns _dbId, not id)
6014
6161
  const newContext = { ...context };
6015
6162
  const dbId = event.output?._dbId ?? event.output?.id;
6016
6163
  if (dbId != null) {
6017
6164
  newContext._dbId = dbId;
6018
- logger$q(`[writeSuccess] Updated _dbId to ${dbId}`);
6165
+ logger$r(`[writeSuccess] Updated _dbId to ${dbId}`);
6019
6166
  }
6020
6167
  return newContext;
6021
6168
  }),
@@ -6059,12 +6206,12 @@ const modelMachine = xstate.setup({
6059
6206
  },
6060
6207
  creatingProperties: {
6061
6208
  entry: ({ context }) => {
6062
- logger$q(`[creatingProperties entry] Starting property creation for model "${context.modelName}" with ${Object.keys(context._pendingPropertyDefinitions || {}).length} properties`);
6209
+ logger$r(`[creatingProperties entry] Starting property creation for model "${context.modelName}" with ${Object.keys(context._pendingPropertyDefinitions || {}).length} properties`);
6063
6210
  },
6064
6211
  invoke: {
6065
6212
  src: 'createModelProperties',
6066
6213
  input: ({ context }) => {
6067
- logger$q(`[creatingProperties invoke] Invoking createModelProperties with ${Object.keys(context._pendingPropertyDefinitions || {}).length} property definitions`);
6214
+ logger$r(`[creatingProperties invoke] Invoking createModelProperties with ${Object.keys(context._pendingPropertyDefinitions || {}).length} property definitions`);
6068
6215
  return {
6069
6216
  context,
6070
6217
  propertyDefinitions: context._pendingPropertyDefinitions || {},
@@ -6096,7 +6243,7 @@ const modelMachine = xstate.setup({
6096
6243
  createModelPropertiesError: {
6097
6244
  target: 'error',
6098
6245
  actions: ({ event }) => {
6099
- logger$q('Error creating model properties:', event.error);
6246
+ logger$r('Error creating model properties:', event.error);
6100
6247
  },
6101
6248
  },
6102
6249
  },
@@ -6452,7 +6599,7 @@ var metadataLatest = /*#__PURE__*/Object.freeze({
6452
6599
  getMetadataLatest: getMetadataLatest
6453
6600
  });
6454
6601
 
6455
- const logger$p = debug('seedSdk:item:actors:loadOrCreateItem');
6602
+ const logger$q = debug('seedSdk:item:actors:loadOrCreateItem');
6456
6603
  /**
6457
6604
  * Maps metadata.property_name to the ItemProperty Map key (same rules as the instance loop below).
6458
6605
  */
@@ -6544,16 +6691,16 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
6544
6691
  const schemaNameToTry = schemaName ?? model$1?.schemaName;
6545
6692
  if (schemaNameToTry) {
6546
6693
  try {
6547
- const { Schema } = await Promise.resolve().then(function () { return require('./Schema-STP972Xw.js'); });
6694
+ const { Schema } = await Promise.resolve().then(function () { return require('./Schema-DdP109QD.js'); });
6548
6695
  const schemaInstance = Schema.create(schemaNameToTry, { waitForReady: false });
6549
6696
  const schemaContext = schemaInstance.getService().getSnapshot().context;
6550
6697
  if (schemaContext.models?.[modelName]?.properties) {
6551
6698
  propertySchemas = schemaContext.models[modelName].properties;
6552
- logger$p(`Fallback: got ${Object.keys(propertySchemas).length} property schemas from Schema context for ${modelName}`);
6699
+ logger$q(`Fallback: got ${Object.keys(propertySchemas).length} property schemas from Schema context for ${modelName}`);
6553
6700
  }
6554
6701
  }
6555
6702
  catch (err) {
6556
- logger$p(`Fallback Schema context failed for ${modelName}: ${err}`);
6703
+ logger$q(`Fallback Schema context failed for ${modelName}: ${err}`);
6557
6704
  }
6558
6705
  }
6559
6706
  if (Object.keys(propertySchemas).length === 0) {
@@ -6566,13 +6713,13 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
6566
6713
  const models = schemaFile.models;
6567
6714
  if (models?.[modelName]?.properties) {
6568
6715
  propertySchemas = models[modelName].properties;
6569
- logger$p(`Fallback: got ${Object.keys(propertySchemas).length} property schemas from loadAllSchemasFromDb for ${modelName}`);
6716
+ logger$q(`Fallback: got ${Object.keys(propertySchemas).length} property schemas from loadAllSchemasFromDb for ${modelName}`);
6570
6717
  break;
6571
6718
  }
6572
6719
  }
6573
6720
  }
6574
6721
  catch (err) {
6575
- logger$p(`Fallback loadAllSchemasFromDb failed for ${modelName}: ${err}`);
6722
+ logger$q(`Fallback loadAllSchemasFromDb failed for ${modelName}: ${err}`);
6576
6723
  }
6577
6724
  }
6578
6725
  if (Object.keys(propertySchemas).length === 0) {
@@ -6587,17 +6734,17 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
6587
6734
  continue;
6588
6735
  if (schemaFile.models?.[modelName]?.properties) {
6589
6736
  propertySchemas = schemaFile.models[modelName].properties;
6590
- logger$p(`Fallback: got ${Object.keys(propertySchemas).length} property schemas from schema file for ${modelName}`);
6737
+ logger$q(`Fallback: got ${Object.keys(propertySchemas).length} property schemas from schema file for ${modelName}`);
6591
6738
  break;
6592
6739
  }
6593
6740
  }
6594
6741
  }
6595
6742
  catch (err) {
6596
- logger$p(`Fallback schema file scan failed for ${modelName}: ${err}`);
6743
+ logger$q(`Fallback schema file scan failed for ${modelName}: ${err}`);
6597
6744
  }
6598
6745
  }
6599
6746
  if (Object.keys(propertySchemas).length === 0) {
6600
- const schemaMod = await Promise.resolve().then(function () { return require('./index-nA5PxBSs.js'); });
6747
+ const schemaMod = await Promise.resolve().then(function () { return require('./index-BHaWOwNF.js'); });
6601
6748
  const { ModelPropertyDataTypes } = schemaMod;
6602
6749
  const KNOWN_MODEL_FALLBACKS = {
6603
6750
  Post: {
@@ -6609,12 +6756,12 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
6609
6756
  };
6610
6757
  if (KNOWN_MODEL_FALLBACKS[modelName]) {
6611
6758
  propertySchemas = KNOWN_MODEL_FALLBACKS[modelName];
6612
- logger$p(`Fallback: using known model schema for ${modelName} (${Object.keys(propertySchemas).length} properties)`);
6759
+ logger$q(`Fallback: using known model schema for ${modelName} (${Object.keys(propertySchemas).length} properties)`);
6613
6760
  }
6614
6761
  }
6615
6762
  }
6616
6763
  // Fallbacks above may return schema-file shape ({ type, model, items }); normalize to dataType/ref/refValueType.
6617
- const { normalizePropertyRecordSchema } = await Promise.resolve().then(function () { return require('./property-xMwPhQ5N.js'); });
6764
+ const { normalizePropertyRecordSchema } = await Promise.resolve().then(function () { return require('./property-fa0iju0J.js'); });
6618
6765
  propertySchemas = Object.fromEntries(Object.entries(propertySchemas).map(([name, def]) => [name, normalizePropertyRecordSchema(def)]));
6619
6766
  // Collapse rows that map to the same instance key (e.g. authorIdentityIds + authors -> authors).
6620
6767
  // ItemProperty.create cache does not sync propertyValue on hit; processing order would otherwise
@@ -6627,7 +6774,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
6627
6774
  try {
6628
6775
  let propertyName = metaRow.propertyName;
6629
6776
  if (!propertyName) {
6630
- logger$p(`Metadata row missing propertyName, skipping`);
6777
+ logger$q(`Metadata row missing propertyName, skipping`);
6631
6778
  continue;
6632
6779
  }
6633
6780
  const listSchemaKey = resolveStorageNameToSchemaName(propertySchemas, propertyName);
@@ -6647,7 +6794,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
6647
6794
  // Infer propertyRecordSchema from metadata when schema is missing (enables persistence)
6648
6795
  let propSchema = propertySchemas[propertyName];
6649
6796
  if (!propSchema && isRefTypeFromMeta) {
6650
- const schemaMod = await Promise.resolve().then(function () { return require('./index-nA5PxBSs.js'); });
6797
+ const schemaMod = await Promise.resolve().then(function () { return require('./index-BHaWOwNF.js'); });
6651
6798
  const { ModelPropertyDataTypes } = schemaMod;
6652
6799
  propSchema = {
6653
6800
  dataType: refSeedType === 'html' ? ModelPropertyDataTypes.Html
@@ -6677,14 +6824,14 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
6677
6824
  const property = ItemProperty.create(createProps, { waitForReady: false });
6678
6825
  if (property) {
6679
6826
  propertyInstances.set(propertyName, property);
6680
- logger$p(`Created/cached ItemProperty instance for propertyName "${propertyName}" with propertyRecordSchema: ${!!createProps.propertyRecordSchema}`);
6827
+ logger$q(`Created/cached ItemProperty instance for propertyName "${propertyName}" with propertyRecordSchema: ${!!createProps.propertyRecordSchema}`);
6681
6828
  }
6682
6829
  else {
6683
- logger$p(`ItemProperty.create returned undefined for propertyName "${propertyName}"`);
6830
+ logger$q(`ItemProperty.create returned undefined for propertyName "${propertyName}"`);
6684
6831
  }
6685
6832
  }
6686
6833
  catch (error) {
6687
- logger$p(`Error creating ItemProperty instance for propertyName "${metaRow.propertyName}": ${error}`);
6834
+ logger$q(`Error creating ItemProperty instance for propertyName "${metaRow.propertyName}": ${error}`);
6688
6835
  }
6689
6836
  }
6690
6837
  // Create placeholder ItemProperty instances for model schema properties without metadata
@@ -6707,17 +6854,17 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
6707
6854
  const property = ItemProperty.create(createProps, { waitForReady: false });
6708
6855
  if (property) {
6709
6856
  propertyInstances.set(propertyName, property);
6710
- logger$p(`Created placeholder ItemProperty for model property "${propertyName}" (no metadata)`);
6857
+ logger$q(`Created placeholder ItemProperty for model property "${propertyName}" (no metadata)`);
6711
6858
  }
6712
6859
  }
6713
6860
  catch (error) {
6714
- logger$p(`Error creating placeholder ItemProperty for "${propertyName}": ${error}`);
6861
+ logger$q(`Error creating placeholder ItemProperty for "${propertyName}": ${error}`);
6715
6862
  }
6716
6863
  }
6717
- logger$p(`Finished creating/caching ${propertyInstances.size} ItemProperty instances`);
6864
+ logger$q(`Finished creating/caching ${propertyInstances.size} ItemProperty instances`);
6718
6865
  }
6719
6866
  catch (error) {
6720
- logger$p(`Error in createItemPropertyInstances: ${error}`);
6867
+ logger$q(`Error in createItemPropertyInstances: ${error}`);
6721
6868
  // Don't throw - this is best-effort to pre-populate cache
6722
6869
  }
6723
6870
  return propertyInstances;
@@ -6725,7 +6872,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
6725
6872
  const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } }) => {
6726
6873
  const _loadOrCreateItem = async () => {
6727
6874
  const { seedLocalId, seedUid, modelName } = context;
6728
- logger$p(`loadOrCreateItem called for modelName: ${modelName}, seedLocalId: ${seedLocalId}, seedUid: ${seedUid}`);
6875
+ logger$q(`loadOrCreateItem called for modelName: ${modelName}, seedLocalId: ${seedLocalId}, seedUid: ${seedUid}`);
6729
6876
  if (!seedLocalId && !seedUid) {
6730
6877
  throw new Error('seedLocalId or seedUid is required');
6731
6878
  }
@@ -6755,7 +6902,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
6755
6902
  .limit(1);
6756
6903
  if (seedRecords.length === 0) {
6757
6904
  // Seed not found - this is a new item, will be created elsewhere
6758
- logger$p(`Seed not found in database for seedLocalId: ${seedLocalId}, seedUid: ${seedUid}`);
6905
+ logger$q(`Seed not found in database for seedLocalId: ${seedLocalId}, seedUid: ${seedUid}`);
6759
6906
  sendBack({
6760
6907
  type: 'loadOrCreateItemSuccess',
6761
6908
  item: {
@@ -6798,7 +6945,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
6798
6945
  .where(drizzleOrm.eq(seeds.localId, resolvedSeedLocalId))
6799
6946
  .limit(1);
6800
6947
  if (versionRecords.length === 0) {
6801
- logger$p(`No version data found for seedLocalId: ${resolvedSeedLocalId}`);
6948
+ logger$q(`No version data found for seedLocalId: ${resolvedSeedLocalId}`);
6802
6949
  sendBack({
6803
6950
  type: 'loadOrCreateItemSuccess',
6804
6951
  item: {
@@ -6825,7 +6972,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
6825
6972
  // A seed whose versions are all revoked (fully unpublished) has no latest version but still has
6826
6973
  // its last property values; load those like any other item. Only a seed without versions stops here.
6827
6974
  if (!latestVersionLocalId && !versionRecord.versionsCount) {
6828
- logger$p(`No latest version found for seedLocalId: ${resolvedSeedLocalId}`);
6975
+ logger$q(`No latest version found for seedLocalId: ${resolvedSeedLocalId}`);
6829
6976
  sendBack({
6830
6977
  type: 'loadOrCreateItemSuccess',
6831
6978
  item: {
@@ -6857,7 +7004,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
6857
7004
  .select()
6858
7005
  .from(metadataLatest)
6859
7006
  .where(drizzleOrm.eq(metadataLatest.rowNum, 1));
6860
- logger$p(`Found ${metadataRecords.length} latest-per-property metadata rows for seed ${resolvedSeedLocalId} (latestVersionLocalId=${latestVersionLocalId} used for placeholders only)`);
7007
+ logger$q(`Found ${metadataRecords.length} latest-per-property metadata rows for seed ${resolvedSeedLocalId} (latestVersionLocalId=${latestVersionLocalId} used for placeholders only)`);
6861
7008
  // Step 4: Create ItemProperty instances from metadata records + placeholders for model schema properties
6862
7009
  // Always call when we have a valid version so placeholders are created for properties without metadata
6863
7010
  const propertyInstances = await createItemPropertyInstances(metadataRecords, resolvedSeedLocalId, resolvedSeedUid, modelName, latestVersionLocalId, latestVersionUid, modelScope);
@@ -6890,7 +7037,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
6890
7037
  });
6891
7038
  };
6892
7039
  _loadOrCreateItem().catch((error) => {
6893
- logger$p(`Error in loadOrCreateItem: ${error}`);
7040
+ logger$q(`Error in loadOrCreateItem: ${error}`);
6894
7041
  sendBack({
6895
7042
  type: 'loadOrCreateItemError',
6896
7043
  error: error instanceof Error ? error.message : String(error),
@@ -6898,7 +7045,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
6898
7045
  });
6899
7046
  });
6900
7047
 
6901
- const logger$o = debug('seedSdk:Item:runPublish');
7048
+ const logger$p = debug('seedSdk:Item:runPublish');
6902
7049
  const runPublish = xstate.fromCallback(({ sendBack, input: { context } }) => {
6903
7050
  const { seedLocalId } = context;
6904
7051
  const _runPublish = async () => {
@@ -6914,9 +7061,9 @@ const runPublish = xstate.fromCallback(({ sendBack, input: { context } }) => {
6914
7061
  sendBack({ type: 'publishError', error: new Error(`Item not found for seedLocalId: ${seedLocalId}`) });
6915
7062
  return;
6916
7063
  }
6917
- const getPublishUploadsMod = await Promise.resolve().then(function () { return require('./getPublishUploads-BQr8aMVP.js'); });
7064
+ const getPublishUploadsMod = await Promise.resolve().then(function () { return require('./getPublishUploads-DsXY9S4U.js'); });
6918
7065
  const { getPublishUploads } = getPublishUploadsMod;
6919
- const getPublishPayloadMod = await Promise.resolve().then(function () { return require('./getPublishPayload-BsZWiJ03.js'); });
7066
+ const getPublishPayloadMod = await Promise.resolve().then(function () { return require('./getPublishPayload-CqlqRdot.js'); });
6920
7067
  const { getPublishPayload } = getPublishPayloadMod;
6921
7068
  const uploads = await getPublishUploads(item);
6922
7069
  let uploadedTransactions = [];
@@ -6932,12 +7079,12 @@ const runPublish = xstate.fromCallback(({ sendBack, input: { context } }) => {
6932
7079
  }
6933
7080
  }
6934
7081
  await getPublishPayload(item, uploadedTransactions);
6935
- logger$o('runPublish: payload prepared (upload/EAS submit stubbed)');
7082
+ logger$p('runPublish: payload prepared (upload/EAS submit stubbed)');
6936
7083
  sendBack({ type: 'publishSuccess' });
6937
7084
  }
6938
7085
  catch (err) {
6939
7086
  const error = err instanceof Error ? err : new Error(String(err));
6940
- logger$o('runPublish error:', error);
7087
+ logger$p('runPublish error:', error);
6941
7088
  sendBack({ type: 'publishError', error });
6942
7089
  }
6943
7090
  };
@@ -7212,7 +7359,7 @@ async function getLatestPublishedVersionRow(seedLocalId) {
7212
7359
  return null;
7213
7360
  }
7214
7361
 
7215
- const logger$n = debug('seedSdk:db:read:getItemData');
7362
+ const logger$o = debug('seedSdk:db:read:getItemData');
7216
7363
  /**
7217
7364
  * Assemble flat ItemData for Item / liveQuery / draft-head authoring.
7218
7365
  *
@@ -7228,7 +7375,7 @@ const getItemData = async ({ modelName, seedLocalId, seedUid, }) => {
7228
7375
  if (seedUid && !seedLocalId) {
7229
7376
  const seedData = await getSeedData({ seedUid });
7230
7377
  if (!seedData) {
7231
- logger$n('[db/queries] [getItem] no seedData seedUid', seedUid);
7378
+ logger$o('[db/queries] [getItem] no seedData seedUid', seedUid);
7232
7379
  return;
7233
7380
  }
7234
7381
  seedLocalId = seedData.localId || undefined;
@@ -7255,9 +7402,9 @@ const getItemData = async ({ modelName, seedLocalId, seedUid, }) => {
7255
7402
  .from(seeds)
7256
7403
  .where(drizzleOrm.and(...whereClauses))
7257
7404
  .limit(1);
7258
- logger$n('[getItemData] Seed query result', { rowsCount: seedRows?.length || 0, firstRow: seedRows?.[0] });
7405
+ logger$o('[getItemData] Seed query result', { rowsCount: seedRows?.length || 0, firstRow: seedRows?.[0] });
7259
7406
  if (!seedRows || seedRows.length === 0) {
7260
- logger$n('[db/queries] [getItemDataFromDb] no seedRows found', { modelName, seedLocalId, seedUid });
7407
+ logger$o('[db/queries] [getItemDataFromDb] no seedRows found', { modelName, seedLocalId, seedUid });
7261
7408
  return;
7262
7409
  }
7263
7410
  const seedRow = seedRows[0];
@@ -7283,7 +7430,7 @@ const getItemData = async ({ modelName, seedLocalId, seedUid, }) => {
7283
7430
  }
7284
7431
  }
7285
7432
  catch (error) {
7286
- logger$n('[getItemData] Error deriving schemaName:', error);
7433
+ logger$o('[getItemData] Error deriving schemaName:', error);
7287
7434
  }
7288
7435
  }
7289
7436
  // Now get version data if it exists - query versions table directly
@@ -7539,8 +7686,9 @@ function isSeedRowOwned(row, ownedAddresses) {
7539
7686
  return publisherIsInOwnedSet(publisher, ownedAddresses);
7540
7687
  }
7541
7688
  /**
7542
- * SQL for `addressFilter: 'owned' | 'watched'`. Empty list → no rows (`1=0`).
7543
- * Compares `lower(publisher)` so checksummed rows match persisted lowercase owned.
7689
+ * SQL for an address list on `publisher`. Empty list → no rows (`1=0`).
7690
+ * Compares `lower(publisher)` so checksummed rows match persisted lowercase addresses.
7691
+ * Used for `addressFilter: 'watched'`; `'owned'` uses {@link ownedSeedsSql}.
7544
7692
  */
7545
7693
  function publisherInAddressListSql(column, addresses) {
7546
7694
  const normalized = normalizeAddressList(addresses);
@@ -7549,6 +7697,30 @@ function publisherInAddressListSql(column, addresses) {
7549
7697
  }
7550
7698
  return drizzleOrm.inArray(drizzleOrm.sql `lower(${column})`, normalized);
7551
7699
  }
7700
+ /** SQL form of {@link isPlaceholderUid}: null, `''`, `'NULL'`, or zero bytes32 (trimmed, any case). */
7701
+ function placeholderUidSql(column) {
7702
+ return drizzleOrm.or(drizzleOrm.isNull(column), drizzleOrm.eq(column, 'NULL'), drizzleOrm.sql `trim(${column}) = ''`, drizzleOrm.sql `lower(trim(${column})) = ${ZERO_BYTES32.toLowerCase()}`);
7703
+ }
7704
+ const isBlankSql = (column) => drizzleOrm.or(drizzleOrm.isNull(column), drizzleOrm.eq(column, ''));
7705
+ /** SQL form of {@link isLocalUnsealedDraft} on `seeds`. */
7706
+ function localUnsealedDraftSql() {
7707
+ return drizzleOrm.and(isBlankSql(seeds.publisher), placeholderUidSql(seeds.uid), isBlankSql(seeds.attestationRaw));
7708
+ }
7709
+ /**
7710
+ * SQL for `addressFilter: 'owned'`: a row passes exactly when {@link isSeedRowOwned} is true.
7711
+ * - Empty owned → local unsealed drafts (pre-connect authoring), not every row.
7712
+ * - Owned set → `lower(trim(publisher))` in the set, or, when publisher is blank, the
7713
+ * `attestationRaw.attester` ({@link resolvePublisherFromSeedRow}). `json_valid` guards
7714
+ * `json_extract`, which throws on malformed JSON.
7715
+ */
7716
+ function ownedSeedsSql(ownedAddresses) {
7717
+ const normalized = normalizeAddressList(ownedAddresses);
7718
+ if (normalized.length === 0) {
7719
+ return localUnsealedDraftSql();
7720
+ }
7721
+ const attester = drizzleOrm.sql `CASE WHEN json_valid(${seeds.attestationRaw}) THEN lower(trim(json_extract(${seeds.attestationRaw}, '$.attester'))) END`;
7722
+ return drizzleOrm.or(drizzleOrm.inArray(drizzleOrm.sql `lower(trim(${seeds.publisher}))`, normalized), drizzleOrm.and(isBlankSql(seeds.publisher), drizzleOrm.inArray(attester, normalized)));
7723
+ }
7552
7724
  /**
7553
7725
  * Checks if the current user owns the item (publisher is in persisted owned addresses).
7554
7726
  *
@@ -7585,6 +7757,9 @@ var ownership = /*#__PURE__*/Object.freeze({
7585
7757
  isItemOwned: isItemOwned,
7586
7758
  isLocalUnsealedDraft: isLocalUnsealedDraft,
7587
7759
  isSeedRowOwned: isSeedRowOwned,
7760
+ localUnsealedDraftSql: localUnsealedDraftSql,
7761
+ ownedSeedsSql: ownedSeedsSql,
7762
+ placeholderUidSql: placeholderUidSql,
7588
7763
  publisherInAddressListSql: publisherInAddressListSql,
7589
7764
  publisherIsInOwnedSet: publisherIsInOwnedSet,
7590
7765
  resolvePublisherFromSeedRow: resolvePublisherFromSeedRow
@@ -7604,7 +7779,7 @@ const getItemsData = async ({ modelName, modelFileId, schemaName, deleted, inclu
7604
7779
  const appDb = BaseDb.getAppDb();
7605
7780
  const conditions = [];
7606
7781
  if (!includeEas) {
7607
- conditions.push(drizzleOrm.or(drizzleOrm.isNull(seeds.uid), drizzleOrm.eq(seeds.uid, ''), drizzleOrm.eq(seeds.uid, 'NULL'), drizzleOrm.eq(seeds.uid, ZERO_BYTES32)));
7782
+ conditions.push(placeholderUidSql(seeds.uid));
7608
7783
  }
7609
7784
  if (modelName) {
7610
7785
  conditions.push(drizzleOrm.eq(seeds.type, casing.toSnakeCase(modelName)));
@@ -7620,7 +7795,7 @@ const getItemsData = async ({ modelName, modelFileId, schemaName, deleted, inclu
7620
7795
  }
7621
7796
  if (addressFilter === 'owned') {
7622
7797
  const ownedAddresses = await getAddressesForItemsFilter('owned');
7623
- conditions.push(publisherInAddressListSql(seeds.publisher, ownedAddresses));
7798
+ conditions.push(ownedSeedsSql(ownedAddresses));
7624
7799
  }
7625
7800
  else if (addressFilter === 'watched') {
7626
7801
  const watchedAddresses = await getAddressesForItemsFilter('watched');
@@ -7697,12 +7872,12 @@ async function getLatestVersionRow(seedLocalId) {
7697
7872
  return rows[0] ?? null;
7698
7873
  }
7699
7874
 
7700
- const logger$m = debug('seedSdk:ItemProperty:service:actors:waitForDb');
7875
+ const logger$n = debug('seedSdk:ItemProperty:service:actors:waitForDb');
7701
7876
  const waitForDb = xstate.fromCallback(({ sendBack }) => {
7702
7877
  // Check immediately first
7703
7878
  const appDb = BaseDb.getAppDb();
7704
7879
  if (appDb) {
7705
- logger$m('Database is ready (immediate check)');
7880
+ logger$n('Database is ready (immediate check)');
7706
7881
  sendBack({ type: 'waitForDbSuccess' });
7707
7882
  return;
7708
7883
  }
@@ -7714,24 +7889,24 @@ const waitForDb = xstate.fromCallback(({ sendBack }) => {
7714
7889
  const appDb = BaseDb.getAppDb();
7715
7890
  if (appDb) {
7716
7891
  clearInterval(interval);
7717
- logger$m('Database is ready (after polling)');
7892
+ logger$n('Database is ready (after polling)');
7718
7893
  resolve();
7719
7894
  }
7720
7895
  else if (Date.now() - startTime > timeout) {
7721
7896
  clearInterval(interval);
7722
7897
  const error = new Error('Database not available after timeout');
7723
- logger$m(`Database wait timeout: ${error.message}`);
7898
+ logger$n(`Database wait timeout: ${error.message}`);
7724
7899
  reject(error);
7725
7900
  }
7726
7901
  }, 100);
7727
7902
  });
7728
7903
  _waitForDb
7729
7904
  .then(() => {
7730
- logger$m('Sending waitForDbSuccess event');
7905
+ logger$n('Sending waitForDbSuccess event');
7731
7906
  sendBack({ type: 'waitForDbSuccess' });
7732
7907
  })
7733
7908
  .catch((error) => {
7734
- logger$m(`Error waiting for database: ${error}`);
7909
+ logger$n(`Error waiting for database: ${error}`);
7735
7910
  sendBack({ type: 'waitForDbError', error: error.message });
7736
7911
  });
7737
7912
  });
@@ -7883,7 +8058,7 @@ const getRelationValueData = async (propertyValue) => {
7883
8058
 
7884
8059
  // Dynamic import to break circular dependency: schema/index -> ... -> resolveRelatedValue -> schema/index
7885
8060
  // import { ModelPropertyDataTypes } from '@/schema'
7886
- const logger$l = debug('seedSdk:property:actors:resolveRelatedValue');
8061
+ const logger$m = debug('seedSdk:property:actors:resolveRelatedValue');
7887
8062
  const storageTransactionIdToContentUrl = new Map();
7888
8063
  const refResolvedValueToContentUrl = new Map();
7889
8064
  const seedUidToContentUrl = new Map();
@@ -7891,14 +8066,14 @@ const resolveRelatedValue = xstate.fromCallback(({ sendBack, input: { context }
7891
8066
  const { isRelation, propertyValue, propertyName, seedUid, propertyRecordSchema, populatedFromDb, schemaUid, } = context;
7892
8067
  const _resolveRelatedValue = async () => {
7893
8068
  // Use dynamic import to break circular dependency
7894
- const schemaMod = await Promise.resolve().then(function () { return require('./index-nA5PxBSs.js'); });
8069
+ const schemaMod = await Promise.resolve().then(function () { return require('./index-BHaWOwNF.js'); });
7895
8070
  const { ModelPropertyDataTypes } = schemaMod;
7896
8071
  if (!propertyValue || !isRelation || populatedFromDb) {
7897
8072
  return;
7898
8073
  }
7899
8074
  if (Array.isArray(propertyValue)) {
7900
8075
  // TODO: Handle array of seedUids
7901
- logger$l(`${propertyName} value is an array of seedUids`);
8076
+ logger$m(`${propertyName} value is an array of seedUids`);
7902
8077
  return;
7903
8078
  }
7904
8079
  if (typeof propertyValue === 'object') {
@@ -7910,7 +8085,7 @@ const resolveRelatedValue = xstate.fromCallback(({ sendBack, input: { context }
7910
8085
  parsedValue = JSON.parse(relationKey);
7911
8086
  }
7912
8087
  catch (error) {
7913
- logger$l(`${propertyName} value is not a JSON string.`);
8088
+ logger$m(`${propertyName} value is not a JSON string.`);
7914
8089
  }
7915
8090
  if (!parsedValue && seedUidToContentUrl.has(relationKey)) {
7916
8091
  const contentUrl = seedUidToContentUrl.get(relationKey);
@@ -7925,7 +8100,7 @@ const resolveRelatedValue = xstate.fromCallback(({ sendBack, input: { context }
7925
8100
  return true;
7926
8101
  }
7927
8102
  if (Array.isArray(parsedValue)) {
7928
- logger$l(`${propertyName} value is a stringified array of seedUids`);
8103
+ logger$m(`${propertyName} value is a stringified array of seedUids`);
7929
8104
  return;
7930
8105
  }
7931
8106
  const storageTransactionId = await getStorageTransactionIdForSeedUid(relationKey);
@@ -8374,7 +8549,7 @@ async function readHtmlBodyForStorageSeedPropertyValue(propertyValue) {
8374
8549
 
8375
8550
  // Dynamic import to break circular dependency: schema/index -> ... -> hydrateFromDb -> schema/index
8376
8551
  // import { ModelPropertyDataTypes } from '@/schema'
8377
- const logger$k = debug('seedSdk:property:actors:hydrateFromDb');
8552
+ const logger$l = debug('seedSdk:property:actors:hydrateFromDb');
8378
8553
  const hydrateFromDb = xstate.fromCallback(({ sendBack, input: { context } }) => {
8379
8554
  const { seedUid, seedLocalId, propertyName: propertyNameRaw, propertyRecordSchema, modelName, } = context;
8380
8555
  if (!propertyNameRaw) {
@@ -8385,7 +8560,7 @@ const hydrateFromDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
8385
8560
  // to use dynamically imported ModelPropertyDataTypes
8386
8561
  const _hydrateFromDb = async () => {
8387
8562
  // Use dynamic import to break circular dependency
8388
- const schemaMod = await Promise.resolve().then(function () { return require('./index-nA5PxBSs.js'); });
8563
+ const schemaMod = await Promise.resolve().then(function () { return require('./index-BHaWOwNF.js'); });
8389
8564
  const { ModelPropertyDataTypes } = schemaMod;
8390
8565
  const appDb = BaseDb.getAppDb();
8391
8566
  const whereClauses = [];
@@ -8491,7 +8666,7 @@ const hydrateFromDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
8491
8666
  }
8492
8667
  }
8493
8668
  catch (e) {
8494
- logger$k('[hydrateFromDb] Image file resolution error', e);
8669
+ logger$l('[hydrateFromDb] Image file resolution error', e);
8495
8670
  }
8496
8671
  }
8497
8672
  }
@@ -8522,7 +8697,7 @@ const hydrateFromDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
8522
8697
  }
8523
8698
  }
8524
8699
  catch (e) {
8525
- logger$k('[hydrateFromDb] File resolution error', e);
8700
+ logger$l('[hydrateFromDb] File resolution error', e);
8526
8701
  }
8527
8702
  }
8528
8703
  if (propertyRecordSchema &&
@@ -8625,11 +8800,11 @@ const hydrateFromDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
8625
8800
  });
8626
8801
  });
8627
8802
 
8628
- const logger$j = debug('seedSdk:itemProperty:actors:loadOrCreateProperty');
8803
+ const logger$k = debug('seedSdk:itemProperty:actors:loadOrCreateProperty');
8629
8804
  const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context } }) => {
8630
8805
  const _loadOrCreateProperty = async () => {
8631
8806
  const { seedLocalId, seedUid, propertyName, versionLocalId } = context;
8632
- logger$j(`loadOrCreateProperty called for propertyName: ${propertyName}, seedLocalId: ${seedLocalId}, seedUid: ${seedUid}`);
8807
+ logger$k(`loadOrCreateProperty called for propertyName: ${propertyName}, seedLocalId: ${seedLocalId}, seedUid: ${seedUid}`);
8633
8808
  if (!seedLocalId && !seedUid) {
8634
8809
  throw new Error('seedLocalId or seedUid is required');
8635
8810
  }
@@ -8681,15 +8856,15 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
8681
8856
  const schemas = modelPropertiesToObject(model$1.properties);
8682
8857
  propertyRecordSchema = schemas[propertyName];
8683
8858
  if (propertyRecordSchema) {
8684
- logger$j(`Metadata not found: loaded propertyRecordSchema from Model for propertyName "${propertyName}"`);
8859
+ logger$k(`Metadata not found: loaded propertyRecordSchema from Model for propertyName "${propertyName}"`);
8685
8860
  }
8686
8861
  }
8687
8862
  }
8688
8863
  catch (error) {
8689
- logger$j(`Metadata not found: Model fallback failed for propertyName "${propertyName}": ${error}`);
8864
+ logger$k(`Metadata not found: Model fallback failed for propertyName "${propertyName}": ${error}`);
8690
8865
  }
8691
8866
  }
8692
- logger$j(`Metadata not found in database for propertyName: ${propertyName}, seedLocalId: ${seedLocalId}`);
8867
+ logger$k(`Metadata not found in database for propertyName: ${propertyName}, seedLocalId: ${seedLocalId}`);
8693
8868
  sendBack({
8694
8869
  type: 'loadOrCreatePropertySuccess',
8695
8870
  property: {
@@ -8762,7 +8937,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
8762
8937
  };
8763
8938
  // Merge with schema from file/DB to get validation rules (enum, pattern, etc.) - properties table doesn't store these
8764
8939
  try {
8765
- const { getPropertySchema } = await Promise.resolve().then(function () { return require('./property-xMwPhQ5N.js'); });
8940
+ const { getPropertySchema } = await Promise.resolve().then(function () { return require('./property-fa0iju0J.js'); });
8766
8941
  let schemaFromFile = await getPropertySchema(normalizedModelName, propertyName, {
8767
8942
  modelFileId: modelRecord?.schemaFileId ?? modelFileId,
8768
8943
  });
@@ -8802,7 +8977,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
8802
8977
  }
8803
8978
  }
8804
8979
  catch (error) {
8805
- logger$j(`Error loading propertyRecordSchema from database: ${error}`);
8980
+ logger$k(`Error loading propertyRecordSchema from database: ${error}`);
8806
8981
  // Continue without propertyRecordSchema
8807
8982
  }
8808
8983
  }
@@ -8820,12 +8995,12 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
8820
8995
  const schemas = modelPropertiesToObject(model$1.properties);
8821
8996
  propertyRecordSchema = schemas[propertyName];
8822
8997
  if (propertyRecordSchema) {
8823
- logger$j(`Fallback: loaded propertyRecordSchema from Model for propertyName "${propertyName}"`);
8998
+ logger$k(`Fallback: loaded propertyRecordSchema from Model for propertyName "${propertyName}"`);
8824
8999
  }
8825
9000
  }
8826
9001
  }
8827
9002
  catch (error) {
8828
- logger$j(`Fallback Model lookup failed for propertyName "${propertyName}": ${error}`);
9003
+ logger$k(`Fallback Model lookup failed for propertyName "${propertyName}": ${error}`);
8829
9004
  }
8830
9005
  }
8831
9006
  // For Html: read file content for renderValue (propertyValue is seed ID; blob URLs in DB are invalid after reload)
@@ -8866,7 +9041,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
8866
9041
  }
8867
9042
  }
8868
9043
  catch (e) {
8869
- logger$j(`Failed to read Html file for ${propertyName}: ${e}`);
9044
+ logger$k(`Failed to read Html file for ${propertyName}: ${e}`);
8870
9045
  }
8871
9046
  }
8872
9047
  // Covers missing ref row, wrong ref, or DB dataType casing "html" (handled by isHtml above).
@@ -8924,7 +9099,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
8924
9099
  });
8925
9100
  }
8926
9101
  catch (e) {
8927
- logger$j(`loadOrCreateProperty: updateMetadata refResolvedValue failed for ${propertyName}:`, e);
9102
+ logger$k(`loadOrCreateProperty: updateMetadata refResolvedValue failed for ${propertyName}:`, e);
8928
9103
  }
8929
9104
  }
8930
9105
  }
@@ -8946,7 +9121,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
8946
9121
  }
8947
9122
  }
8948
9123
  catch (e) {
8949
- logger$j(`Failed to resolve Image file for ${propertyName}: ${e}`);
9124
+ logger$k(`Failed to resolve Image file for ${propertyName}: ${e}`);
8950
9125
  }
8951
9126
  }
8952
9127
  const isFile = refSeedType === 'file' ||
@@ -8964,7 +9139,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
8964
9139
  }
8965
9140
  }
8966
9141
  catch (e) {
8967
- logger$j(`Failed to resolve File for ${propertyName}: ${e}`);
9142
+ logger$k(`Failed to resolve File for ${propertyName}: ${e}`);
8968
9143
  }
8969
9144
  }
8970
9145
  let propertyValueOut = metadataRecord.propertyValue || undefined;
@@ -8997,7 +9172,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
8997
9172
  });
8998
9173
  };
8999
9174
  _loadOrCreateProperty().catch((error) => {
9000
- logger$j(`Error in loadOrCreateProperty: ${error}`);
9175
+ logger$k(`Error in loadOrCreateProperty: ${error}`);
9001
9176
  sendBack({
9002
9177
  type: 'loadOrCreatePropertyError',
9003
9178
  error: error instanceof Error ? error.message : String(error),
@@ -9027,10 +9202,10 @@ const getVersionData = async ({ localId, seedLocalId, uid, }) => {
9027
9202
  return queryRows[0];
9028
9203
  };
9029
9204
 
9030
- const logger$i = debug('seedSdk:write:updateItemPropertyValue');
9205
+ const logger$j = debug('seedSdk:write:updateItemPropertyValue');
9031
9206
  const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, newValue, seedUid, seedLocalId, modelName, refSeedType, refResolvedValue, refResolvedDisplayValue, versionLocalId, versionUid, schemaUid, localStorageDir, dataType, refValueType, }) => {
9032
9207
  if (!localIdParam && !seedLocalId) {
9033
- logger$i(`[db/write] [updateItemPropertyValue] no propertyLocalId or seedLocalId for property: ${propertyName}`);
9208
+ logger$j(`[db/write] [updateItemPropertyValue] no propertyLocalId or seedLocalId for property: ${propertyName}`);
9034
9209
  return;
9035
9210
  }
9036
9211
  // Every write below binds parameters: store the value as given (no SQL escaping).
@@ -9082,7 +9257,7 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
9082
9257
  modelType === modelName?.toLowerCase() &&
9083
9258
  refSeedTypeFromDb === refSeedType &&
9084
9259
  refResolvedValueFromDb === refResolvedValue) {
9085
- logger$i(`[db/write] [updateItemPropertyValue] value is the same as most recent record for property: ${propertyNameFromDb}`);
9260
+ logger$j(`[db/write] [updateItemPropertyValue] value is the same as most recent record for property: ${propertyNameFromDb}`);
9086
9261
  return;
9087
9262
  }
9088
9263
  // This means we already have a local-only record so we should just update that one
@@ -9183,9 +9358,9 @@ const analyzeInput = xstate.fromCallback(({ sendBack, input: { context, event }
9183
9358
  }
9184
9359
  const _analyzeInput = async () => {
9185
9360
  // Use dynamic import to break circular dependency
9186
- const schemaMod = await Promise.resolve().then(function () { return require('./index-nA5PxBSs.js'); });
9361
+ const schemaMod = await Promise.resolve().then(function () { return require('./index-BHaWOwNF.js'); });
9187
9362
  const { ModelPropertyDataTypes } = schemaMod;
9188
- const { SchemaValidationService } = await Promise.resolve().then(function () { return require('./SchemaValidationService-CKNW1bKg.js'); });
9363
+ const { SchemaValidationService } = await Promise.resolve().then(function () { return require('./SchemaValidationService-CSXxx7sQ.js'); });
9189
9364
  let propertyName = propertyNameRaw;
9190
9365
  if (!propertyName) {
9191
9366
  throw new Error('propertyName is required');
@@ -9446,7 +9621,11 @@ function waitForTurn(previous, name, timeoutMs) {
9446
9621
  return Promise.race([previous, timedOut]).finally(() => clearTimeout(timer));
9447
9622
  }
9448
9623
 
9449
- const logger$h = debug('seedSdk:helpers:tabCoordinator');
9624
+ const logger$i = debug('seedSdk:helpers:tabCoordinator');
9625
+ /** Identifies this tab (this page's SDK instance) in the messages it sends. */
9626
+ const TAB_ID = typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
9627
+ ? crypto.randomUUID()
9628
+ : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
9450
9629
  let state;
9451
9630
  let leader = false;
9452
9631
  let leaderWaiters = [];
@@ -9465,6 +9644,10 @@ function startTabCoordination({ filesDir, mode = 'coordinate' }) {
9465
9644
  }
9466
9645
  const channel = new BroadcastChannel(`seed:tabs:${dbKey}`);
9467
9646
  channel.onmessage = (event) => {
9647
+ // A BroadcastChannel never hears itself, but another channel object in this page would (a
9648
+ // second channel opened by a test, or the same module loaded twice): skip our own messages.
9649
+ if (event.data?.from === TAB_ID)
9650
+ return;
9468
9651
  for (const handler of messageHandlers)
9469
9652
  handler(event.data);
9470
9653
  };
@@ -9485,7 +9668,7 @@ function becomeLeader() {
9485
9668
  if (leader)
9486
9669
  return;
9487
9670
  leader = true;
9488
- logger$h(`this tab leads ${state?.dbKey}`);
9671
+ logger$i(`this tab leads ${state?.dbKey}`);
9489
9672
  const waiters = leaderWaiters;
9490
9673
  leaderWaiters = [];
9491
9674
  for (const resolve of waiters)
@@ -9502,7 +9685,7 @@ function whenLeaderTab() {
9502
9685
  }
9503
9686
  /** Sends to the other tabs of this database; a no-op when not coordinating. */
9504
9687
  function postTabMessage(message) {
9505
- state?.channel?.postMessage(message);
9688
+ state?.channel?.postMessage({ ...message, from: TAB_ID });
9506
9689
  }
9507
9690
  function onTabMessage(handler) {
9508
9691
  messageHandlers.add(handler);
@@ -9513,7 +9696,7 @@ function withDbTabLock(scope, fn, options) {
9513
9696
  return state ? withTabLock(`seed:${scope}:${state.dbKey}`, fn, options) : fn();
9514
9697
  }
9515
9698
 
9516
- const logger$g = debug('seedSdk:helpers:tabEvents');
9699
+ const logger$h = debug('seedSdk:helpers:tabEvents');
9517
9700
  /**
9518
9701
  * Keeps other tabs current (docs/MULTI_TAB.md). The event bus is per tab, so events that mean "the
9519
9702
  * shared database or OPFS changed" are also posted to the other tabs, which refresh their caches
@@ -9533,12 +9716,11 @@ function emitAcrossTabs(name, payload) {
9533
9716
  postTabMessage({ type: 'event', name, payload });
9534
9717
  }
9535
9718
  /**
9536
- * A file saved through this tab's file system: emits `file-saved` here (as before) and tells other
9537
- * tabs, whose caches don't see it.
9719
+ * A file saved through this tab's file system: emits `file-saved` here. Other tabs hear about it
9720
+ * from the file system itself (see queueFilesChangedNotice), once the write has reached OPFS.
9538
9721
  */
9539
9722
  function notifyFileSaved(filePath) {
9540
9723
  eventEmitter.emit('file-saved', filePath);
9541
- postTabMessage({ type: 'files-changed', paths: [filePath] });
9542
9724
  }
9543
9725
  /** Refreshes this tab's in-memory state for an event another tab emitted, before re-emitting it. */
9544
9726
  async function catchUpOn(name, payload) {
@@ -9566,7 +9748,7 @@ function listenForOtherTabsEvents() {
9566
9748
  onTabMessage((message) => {
9567
9749
  if (message.type === 'event' && RELAYED_EVENTS.has(message.name)) {
9568
9750
  void catchUpOn(message.name, message.payload)
9569
- .catch((error) => logger$g(`catching up on ${message.name} failed`, error))
9751
+ .catch((error) => logger$h(`catching up on ${message.name} failed`, error))
9570
9752
  .then(() => {
9571
9753
  if (message.payload === undefined) {
9572
9754
  eventEmitter.emit(message.name);
@@ -9577,8 +9759,9 @@ function listenForOtherTabsEvents() {
9577
9759
  });
9578
9760
  }
9579
9761
  else if (message.type === 'files-changed') {
9762
+ // Only refreshes caches: never writes, so never sends files-changed back.
9580
9763
  void BaseFileManager.invalidateCachedPaths(message.paths)
9581
- .catch((error) => logger$g('refreshing changed files failed', error))
9764
+ .catch((error) => logger$h('refreshing changed files failed', error))
9582
9765
  .then(() => eventEmitter.emit(FILES_CHANGED_EVENT, message.paths));
9583
9766
  }
9584
9767
  });
@@ -9717,7 +9900,7 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
9717
9900
  propertyRecordSchema?.validation &&
9718
9901
  metadataValues.propertyValue != null &&
9719
9902
  metadataValues.propertyValue !== '') {
9720
- const { SchemaValidationService } = await Promise.resolve().then(function () { return require('./SchemaValidationService-CKNW1bKg.js'); });
9903
+ const { SchemaValidationService } = await Promise.resolve().then(function () { return require('./SchemaValidationService-CSXxx7sQ.js'); });
9721
9904
  const validationService = new SchemaValidationService();
9722
9905
  const validationResult = validationService.validatePropertyValue(metadataValues.propertyValue, normalizeDataType(propertyRecordSchema.dataType), propertyRecordSchema.validation, propertyRecordSchema.refValueType
9723
9906
  ? normalizeDataType(String(propertyRecordSchema.refValueType))
@@ -10299,7 +10482,7 @@ const saveRelation = xstate.fromCallback(({ sendBack, input: { context, event }
10299
10482
  }
10300
10483
  const _saveRelation = async () => {
10301
10484
  // Use dynamic import to break circular dependency
10302
- const schemaMod = await Promise.resolve().then(function () { return require('./index-nA5PxBSs.js'); });
10485
+ const schemaMod = await Promise.resolve().then(function () { return require('./index-BHaWOwNF.js'); });
10303
10486
  const { ModelPropertyDataTypes } = schemaMod;
10304
10487
  if (!propertyNameRaw) {
10305
10488
  throw new Error('propertyName is required');
@@ -10390,6 +10573,86 @@ const getItemPropertyData = async (props) => {
10390
10573
  return queryRows[0];
10391
10574
  };
10392
10575
 
10576
+ /** Absolute path of the file {@link writeItemStorageFile} writes for `target`. */
10577
+ const getItemStorageFilePath = (target) => BaseFileManager.getFilesPath(getItemStorageSubdir(target.localStorageDir), target.fileName || getItemStorageLocalFileName(target.seedId, target.filenameSuffix));
10578
+ /**
10579
+ * Write an ItemStorage property's content to its local file, where saveItemStorage, reads, publish
10580
+ * (resolveItemStorageChildFile) and download all look for it. Returns what the metadata row records:
10581
+ * `refResolvedValue` (the file name) and `localStorageDir` (with a leading slash).
10582
+ *
10583
+ * Callers that also update the file's metadata row hold {@link withItemStorageFileLock} around
10584
+ * both, so another writer of the same file can't land in between.
10585
+ */
10586
+ const writeItemStorageFile = async (target, content) => {
10587
+ const dir = getItemStorageSubdir(target.localStorageDir);
10588
+ const fileName = target.fileName || getItemStorageLocalFileName(target.seedId, target.filenameSuffix);
10589
+ await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath(dir));
10590
+ const filePath = BaseFileManager.getFilesPath(dir, fileName);
10591
+ await BaseFileManager.saveFile(filePath, content);
10592
+ return { fileName, filePath, localStorageDir: target.localStorageDir || `/${dir}` };
10593
+ };
10594
+ /**
10595
+ * Lock name for one ItemStorage file: `seed:item-storage:<absolute file path>`. The path starts
10596
+ * with the files root, which also names the database (`<filesDir>/db/seed.db`), so the name is
10597
+ * per database as well as per file.
10598
+ */
10599
+ const itemStorageFileLockName = (filePath) => `seed:item-storage:${filePath}`;
10600
+ /**
10601
+ * Runs `fn` holding the lock of one ItemStorage file, across tabs (Web Locks) and within this JS
10602
+ * realm (an in-process queue where Web Locks are missing, e.g. Node < 24.5; see `withTabLock`).
10603
+ *
10604
+ * Writers of a local draft's file (saveItemStorage, convertVerbatimItemStorageRow, createNewItem)
10605
+ * hold it across "read the row → write the file → update the row", so the file and the row end
10606
+ * with the same writer's content. See docs/MULTI_TAB.md.
10607
+ *
10608
+ * Lock ordering: this lock is always the innermost. It may be taken while holding a broader lock
10609
+ * (`seed:item-storage-migration:<db>`, `seed:publish:<seedLocalId>`), never the other way round,
10610
+ * and no other lock (nor a second file lock) is requested while it is held. Keep the section to
10611
+ * local DB and file I/O: no network. Not re-entrant.
10612
+ */
10613
+ function withItemStorageFileLock(filePath, fn) {
10614
+ return withTabLock(itemStorageFileLockName(filePath), fn);
10615
+ }
10616
+ /** Lock attempts before giving up when the row's target file keeps changing under us. */
10617
+ const ROW_LOCK_ATTEMPTS = 3;
10618
+ const readRow = async (localId) => {
10619
+ const rows = await BaseDb.getAppDb()
10620
+ .select()
10621
+ .from(metadata$1)
10622
+ .where(drizzleOrm.eq(metadata$1.localId, localId))
10623
+ .limit(1);
10624
+ return rows[0];
10625
+ };
10626
+ /**
10627
+ * Runs `fn` with a fresh read of metadata row `localId`, holding the lock of the file that row's
10628
+ * content goes to. `fileOf` names that file (absolute path) for a row, or returns undefined when
10629
+ * there is nothing to write (then `fn` isn't called and the result is undefined).
10630
+ *
10631
+ * The file depends on the row, so the row is read once to pick the lock and again once it is held;
10632
+ * if the row now points at another file (another writer changed it meanwhile), the lock is
10633
+ * released and taken again for that file.
10634
+ */
10635
+ async function withLockedItemStorageRow(localId, fileOf, fn) {
10636
+ for (let attempt = 0; attempt < ROW_LOCK_ATTEMPTS; attempt++) {
10637
+ const row = await readRow(localId);
10638
+ const filePath = row && fileOf(row);
10639
+ if (!filePath)
10640
+ return undefined;
10641
+ const outcome = await withItemStorageFileLock(filePath, async () => {
10642
+ const fresh = await readRow(localId);
10643
+ const freshPath = fresh && fileOf(fresh);
10644
+ if (!freshPath)
10645
+ return { done: true, value: undefined };
10646
+ if (freshPath !== filePath)
10647
+ return { done: false };
10648
+ return { done: true, value: await fn(fresh, filePath) };
10649
+ });
10650
+ if (outcome.done)
10651
+ return outcome.value;
10652
+ }
10653
+ throw new Error(`ItemStorage file of metadata row ${localId} kept changing; not written`);
10654
+ }
10655
+
10393
10656
  /** A local edit: no attestation uid of its own and not derived from one. */
10394
10657
  const isLocalDraft = (row) => !row.uid && row.derivedFromUid == null;
10395
10658
  const saveItemStorage = xstate.fromCallback(({ sendBack, input: { context, event } }) => {
@@ -10443,22 +10706,25 @@ const saveItemStorage = xstate.fromCallback(({ sendBack, input: { context, event
10443
10706
  const latest = [...queryRows].sort(compareMetadataRowsLatestFirst)[0];
10444
10707
  propertyData = latest && isLocalDraft(latest) ? latest : undefined;
10445
10708
  if (!propertyData && newValue) {
10446
- const filename = `${draftSeedUid || draftSeedLocalId}${propertyRecordSchema.filenameSuffix}`;
10447
- const dir = propertyRecordSchema.localStorageDir?.replace(/^\//, '') || 'files';
10448
- await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath(dir));
10449
- const writeToPath = BaseFileManager.getFilesPath(dir, filename);
10450
- await BaseFileManager.saveFile(writeToPath, newValue);
10451
- propertyData = await createMetadata({
10452
- propertyName,
10453
- propertyValue: filename,
10454
- modelType: (modelName ?? knownRow?.modelType ?? '').toLowerCase() || undefined,
10455
- seedLocalId: draftSeedLocalId,
10456
- seedUid: draftSeedUid,
10457
- versionLocalId,
10458
- versionUid,
10709
+ const target = {
10710
+ seedId: draftSeedUid || draftSeedLocalId,
10459
10711
  localStorageDir: propertyRecordSchema.localStorageDir,
10460
- refValueType: 'file',
10461
- }, propertyRecordSchema);
10712
+ filenameSuffix: propertyRecordSchema.filenameSuffix,
10713
+ };
10714
+ propertyData = await withItemStorageFileLock(getItemStorageFilePath(target), async () => {
10715
+ const { fileName: filename } = await writeItemStorageFile(target, newValue);
10716
+ return createMetadata({
10717
+ propertyName,
10718
+ propertyValue: filename,
10719
+ modelType: (modelName ?? knownRow?.modelType ?? '').toLowerCase() || undefined,
10720
+ seedLocalId: draftSeedLocalId,
10721
+ seedUid: draftSeedUid,
10722
+ versionLocalId,
10723
+ versionUid,
10724
+ localStorageDir: propertyRecordSchema.localStorageDir,
10725
+ refValueType: 'file',
10726
+ }, propertyRecordSchema);
10727
+ });
10462
10728
  }
10463
10729
  }
10464
10730
  else if (propertyData && !isLocalDraft(propertyData)) {
@@ -10467,31 +10733,64 @@ const saveItemStorage = xstate.fromCallback(({ sendBack, input: { context, event
10467
10733
  if (!propertyData) {
10468
10734
  throw new Error(`No metadata row to save ${propertyName} to`);
10469
10735
  }
10470
- const localStorageDir = propertyRecordSchema.localStorageDir || propertyData.localStorageDir;
10471
- const fileName = propertyData.refResolvedValue ||
10472
- `${propertyData.seedUid || propertyData.seedLocalId}${propertyRecordSchema.filenameSuffix}`;
10473
- if (!localStorageDir || !fileName) {
10474
- throw new Error(`Missing localStorageDir: ${localStorageDir} or fileName: ${fileName}`);
10475
- }
10476
- const dir = localStorageDir.replace(/^\//, '');
10477
- await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath(dir));
10478
- const filePath = BaseFileManager.getFilesPath(dir, fileName);
10479
- try {
10480
- await BaseFileManager.saveFile(filePath, newValue);
10481
- }
10482
- catch (error) {
10483
- const fs = await BaseFileManager.getFs();
10484
- fs.writeFileSync(filePath, newValue);
10485
- }
10486
- await appDb
10487
- .update(metadata$1)
10488
- .set({
10489
- refResolvedValue: fileName,
10490
- })
10491
- .where(drizzleOrm.eq(metadata$1.localId, propertyData.localId));
10736
+ // No storage.path: the `files` directory, as resolveItemStorageChildFile and download assume.
10737
+ const localStorageDirOf = (row) => propertyRecordSchema.localStorageDir || row.localStorageDir || '/files';
10738
+ const fileNameOf = (row) => {
10739
+ if (row.refResolvedValue)
10740
+ return row.refResolvedValue;
10741
+ const seedId = row.seedUid || row.seedLocalId;
10742
+ return seedId ? getItemStorageLocalFileName(seedId, propertyRecordSchema.filenameSuffix) : undefined;
10743
+ };
10744
+ if (!fileNameOf(propertyData)) {
10745
+ throw new Error(`Missing a seed id to name the ${propertyName} file after`);
10746
+ }
10747
+ // Read the row, write the file and update the row under the file's lock, so a conversion of a
10748
+ // legacy row (migration, publish) or another save of this file, in this tab or another, can't
10749
+ // land in between and leave the file with older content than the row says.
10750
+ const saved = await withLockedItemStorageRow(propertyData.localId, (row) => {
10751
+ const fileName = fileNameOf(row);
10752
+ return fileName && BaseFileManager.getFilesPath(getItemStorageSubdir(localStorageDirOf(row)), fileName);
10753
+ }, async (row, filePath) => {
10754
+ const localStorageDir = localStorageDirOf(row);
10755
+ const fileName = fileNameOf(row);
10756
+ try {
10757
+ await writeItemStorageFile({ seedId: row.seedUid || row.seedLocalId || '', localStorageDir, fileName }, newValue);
10758
+ }
10759
+ catch (error) {
10760
+ const fs = await BaseFileManager.getFs();
10761
+ fs.writeFileSync(filePath, newValue);
10762
+ }
10763
+ // A legacy row (made before Item.create saved ItemStorage values) holds the old content itself
10764
+ // in propertyValue. The file is the content now: drop it, or a fresh load shows the old text
10765
+ // until the file is read. A row whose propertyValue is the file name keeps it.
10766
+ const clearsVerbatimValue = !row.refResolvedValue &&
10767
+ row.propertyValue != null &&
10768
+ row.propertyValue !== '' &&
10769
+ row.propertyValue !== fileName;
10770
+ // The row says where the file is (read back by hydration, the browser's metadata live query
10771
+ // and publish); without localStorageDir the live query would clear it from the context.
10772
+ await appDb
10773
+ .update(metadata$1)
10774
+ .set({
10775
+ refResolvedValue: fileName,
10776
+ localStorageDir,
10777
+ // Same shape as a row the migration or publish converted (convertVerbatimItemStorageRow).
10778
+ ...(clearsVerbatimValue && { propertyValue: null, refValueType: 'file' }),
10779
+ })
10780
+ .where(drizzleOrm.eq(metadata$1.localId, row.localId));
10781
+ return { fileName, localStorageDir };
10782
+ });
10783
+ // The row went away (or lost its seed ids) before the lock was granted.
10784
+ if (!saved)
10785
+ throw new Error(`No metadata row to save ${propertyName} to`);
10786
+ const { fileName, localStorageDir } = saved;
10492
10787
  sendBack({
10493
10788
  type: 'updateContext',
10494
10789
  renderValue: newValue,
10790
+ // Where the file is, right away: localStoragePath (and so publish uploads) must not wait for
10791
+ // the browser's metadata live query, which Node does not have at all.
10792
+ refResolvedValue: fileName,
10793
+ localStorageDir,
10495
10794
  // Point the property at the draft row when the edit moved off a published row.
10496
10795
  ...(propertyData.localId !== localId && { localId: propertyData.localId }),
10497
10796
  });
@@ -11150,7 +11449,7 @@ hints = {}) => {
11150
11449
  };
11151
11450
  /** Convert modelType (snake_case from DB) to Model name (PascalCase). startCase adds spaces ("Test Post"); Model names are "TestPost". */
11152
11451
  const modelTypeToModelName = (modelType) => modelType ? lodashEs.upperFirst(lodashEs.camelCase(modelType)) : '';
11153
- const logger$f = debug('seedSdk:property:class');
11452
+ const logger$g = debug('seedSdk:property:class');
11154
11453
  // Define tracked properties for the Proxy
11155
11454
  // These properties will be read from/written to the actor context
11156
11455
  const TRACKED_PROPERTIES$2 = [
@@ -11242,7 +11541,7 @@ class ItemProperty {
11242
11541
  serviceInput.propertyValue = JSON.parse(propertyValue);
11243
11542
  }
11244
11543
  catch (e) {
11245
- logger$f('List property value is not JSON', e);
11544
+ logger$g('List property value is not JSON', e);
11246
11545
  }
11247
11546
  }
11248
11547
  }
@@ -11265,7 +11564,7 @@ class ItemProperty {
11265
11564
  return;
11266
11565
  }
11267
11566
  // Use dynamic import to break circular dependency
11268
- const schemaMod = await Promise.resolve().then(function () { return require('./index-nA5PxBSs.js'); });
11567
+ const schemaMod = await Promise.resolve().then(function () { return require('./index-BHaWOwNF.js'); });
11269
11568
  const { ModelPropertyDataTypes } = schemaMod;
11270
11569
  const { context } = snapshot;
11271
11570
  const { propertyRecordSchema } = context;
@@ -11359,7 +11658,7 @@ class ItemProperty {
11359
11658
  }
11360
11659
  }
11361
11660
  catch (e) {
11362
- logger$f(`[ItemProperty] [${context.seedLocalId}] [${context.propertyName}] [storageType] error`, e);
11661
+ logger$g(`[ItemProperty] [${context.seedLocalId}] [${context.propertyName}] [storageType] error`, e);
11363
11662
  renderValue = isHtml ? undefined : 'No file found';
11364
11663
  }
11365
11664
  }
@@ -12425,13 +12724,38 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
12425
12724
  for (const propertyName of allPropertyNames) {
12426
12725
  const propertyValue = propertyData[propertyName];
12427
12726
  const propertyRecordSchema = propertySchemas?.[propertyName];
12428
- await createMetadata({
12727
+ // ItemStorage content lives in the property's file (`<seedLocalId><extension>`), as a save puts
12728
+ // it; the row records where. Stored verbatim in the row, publish would never upload it.
12729
+ const isItemStorageValue = propertyRecordSchema?.storageType === 'ItemStorage' &&
12730
+ propertyValue != null &&
12731
+ propertyValue !== '';
12732
+ const insertRow = (storageFields) => createMetadata({
12429
12733
  seedLocalId: newSeedId,
12430
12734
  versionLocalId: newVersionId,
12431
12735
  propertyName,
12432
- propertyValue,
12736
+ propertyValue: storageFields ? undefined : propertyValue,
12737
+ ...storageFields,
12433
12738
  modelName,
12434
12739
  }, propertyRecordSchema, { skipValidation: true, modelFileId });
12740
+ if (!isItemStorageValue) {
12741
+ await insertRow();
12742
+ continue;
12743
+ }
12744
+ // File and row under the file's lock, like every writer of a local draft's file (see
12745
+ // withItemStorageFileLock). The seed is new, so nothing else should be writing it yet.
12746
+ const target = {
12747
+ seedId: newSeedId,
12748
+ localStorageDir: propertyRecordSchema.localStorageDir,
12749
+ filenameSuffix: propertyRecordSchema.filenameSuffix,
12750
+ };
12751
+ await withItemStorageFileLock(getItemStorageFilePath(target), async () => {
12752
+ const written = await writeItemStorageFile(target, propertyValue);
12753
+ await insertRow({
12754
+ refResolvedValue: written.fileName,
12755
+ localStorageDir: written.localStorageDir,
12756
+ refValueType: 'file',
12757
+ });
12758
+ });
12435
12759
  }
12436
12760
  return {
12437
12761
  modelName,
@@ -12593,10 +12917,16 @@ const getModel = () => {
12593
12917
  };
12594
12918
  // Define tracked properties for the Proxy
12595
12919
  // These properties will be read from/written to the actor context
12596
- /** Raw File/Image/Html content (not already a storage seed reference) needs ItemProperty.save(). */
12597
- function needsStorageSavePipeline(dataType, value) {
12920
+ /**
12921
+ * Initial values that need ItemProperty.save() rather than a verbatim metadata row: raw File/Image/Html
12922
+ * content (not already a storage seed reference) becomes a storage seed, and an ItemStorage property's
12923
+ * content goes into its file (`<seedLocalId><extension>`), where publish and reads look for it.
12924
+ */
12925
+ function needsStorageSavePipeline(dataType, value, storageType) {
12598
12926
  if (value == null || value === '')
12599
12927
  return false;
12928
+ if (storageType === 'ItemStorage')
12929
+ return true;
12600
12930
  const isStorageType = isDataType(dataType, exports.ModelPropertyDataTypes.File) ||
12601
12931
  isDataType(dataType, exports.ModelPropertyDataTypes.Image) ||
12602
12932
  isDataType(dataType, exports.ModelPropertyDataTypes.Html);
@@ -12709,12 +13039,12 @@ class Item {
12709
13039
  };
12710
13040
  this.getPublishUploads = async (options) => {
12711
13041
  // Use dynamic import to break circular dependency
12712
- const getPublishUploadsMod = await Promise.resolve().then(function () { return require('./getPublishUploads-BQr8aMVP.js'); });
13042
+ const getPublishUploadsMod = await Promise.resolve().then(function () { return require('./getPublishUploads-DsXY9S4U.js'); });
12713
13043
  const { getPublishUploads } = getPublishUploadsMod;
12714
13044
  return await getPublishUploads(this, [], undefined, options);
12715
13045
  };
12716
13046
  this.getPublishPayload = async (uploadedTransactions, options) => {
12717
- const getPublishPayloadMod = await Promise.resolve().then(function () { return require('./getPublishPayload-BsZWiJ03.js'); });
13047
+ const getPublishPayloadMod = await Promise.resolve().then(function () { return require('./getPublishPayload-CqlqRdot.js'); });
12718
13048
  const { getPublishPayload } = getPublishPayloadMod;
12719
13049
  return await getPublishPayload(this, uploadedTransactions, options);
12720
13050
  };
@@ -13244,6 +13574,7 @@ class Item {
13244
13574
  // Get property names directly from database to make Item independent from Model
13245
13575
  let propertyNames = [];
13246
13576
  const dataTypeByPropertyName = new Map();
13577
+ const storageTypeByPropertyName = new Map();
13247
13578
  const db = BaseDb.getAppDb();
13248
13579
  if (db && props.modelName) {
13249
13580
  // Model names are only unique per schema: resolve the exact models row from the most specific scope.
@@ -13273,13 +13604,19 @@ class Item {
13273
13604
  }
13274
13605
  if (modelRecords.length > 0 && modelRecords[0].id) {
13275
13606
  const propertyRecords = await db
13276
- .select({ name: properties.name, dataType: properties.dataType })
13607
+ .select({
13608
+ name: properties.name,
13609
+ dataType: properties.dataType,
13610
+ storageType: properties.storageType,
13611
+ })
13277
13612
  .from(properties)
13278
13613
  .where(drizzleOrm.eq(properties.modelId, modelRecords[0].id));
13279
13614
  propertyNames = propertyRecords.map((r) => r.name).filter((name) => Boolean(name));
13280
13615
  for (const r of propertyRecords) {
13281
13616
  if (r.name && r.dataType)
13282
13617
  dataTypeByPropertyName.set(r.name, r.dataType);
13618
+ if (r.name && r.storageType)
13619
+ storageTypeByPropertyName.set(r.name, r.storageType);
13283
13620
  }
13284
13621
  }
13285
13622
  }
@@ -13288,7 +13625,8 @@ class Item {
13288
13625
  modelFileId: props.modelFileId,
13289
13626
  };
13290
13627
  // File/Image/Html values that are raw content (html string, data URI, URL, File) must go through
13291
- // the property's save pipeline to become storage seeds; createNewItem would store them verbatim.
13628
+ // the property's save pipeline to become storage seeds, and ItemStorage values to be written to
13629
+ // their file with the property context pointing at it (as `prop.value = v; await prop.save()`).
13292
13630
  const pipelineValues = [];
13293
13631
  // Only include properties that are in the model schema
13294
13632
  // Exclude modelInstance, modelName, and schemaName as they're metadata, not item properties
@@ -13298,7 +13636,7 @@ class Item {
13298
13636
  continue;
13299
13637
  }
13300
13638
  if (propertyNames.length === 0 || propertyNames.includes(key)) {
13301
- if (needsStorageSavePipeline(dataTypeByPropertyName.get(key), value)) {
13639
+ if (needsStorageSavePipeline(dataTypeByPropertyName.get(key), value, storageTypeByPropertyName.get(key))) {
13302
13640
  pipelineValues.push([key, value]);
13303
13641
  continue;
13304
13642
  }
@@ -13430,7 +13768,7 @@ class Item {
13430
13768
  return proxiedInstance;
13431
13769
  }
13432
13770
  /**
13433
- * Run each File/Image/Html initial value through its ItemProperty save pipeline (sequentially, to
13771
+ * Run each File/Image/Html/ItemStorage initial value through its ItemProperty save pipeline (sequentially, to
13434
13772
  * avoid SQLite write contention). Rejects on the first failure; the item itself has been created.
13435
13773
  */
13436
13774
  static async savePipelineValues(item, pipelineValues, timeout) {
@@ -14520,7 +14858,7 @@ const runEasSync = xstate.fromPromise(async ({ input, }) => {
14520
14858
  requestPayload: input.requestPayload,
14521
14859
  persistedSnapshot: input.runningSnapshot,
14522
14860
  });
14523
- const { runSyncFromEas } = await Promise.resolve().then(function () { return require('./syncDbWithEas-DqRhV8o2.js'); });
14861
+ const { runSyncFromEas } = await Promise.resolve().then(function () { return require('./syncDbWithEas-CrmxxmUW.js'); });
14524
14862
  try {
14525
14863
  // Sync checks for rows and then inserts the rest (no unique index on uids), so syncs in
14526
14864
  // different tabs take turns. A sync can run for minutes, so wait without a timeout.
@@ -14696,7 +15034,7 @@ function newCorrelationId() {
14696
15034
  return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
14697
15035
  }
14698
15036
  /** Requests deferred in this tab until it leads, by source; each runs once on takeover. */
14699
- const deferredUntilLeader = new Set();
15037
+ const deferredUntilLeader$1 = new Set();
14700
15038
  /**
14701
15039
  * Automatic syncs run in the leader tab only (docs/MULTI_TAB.md). A tab that skips one runs it if
14702
15040
  * it later becomes leader, so closing the leader doesn't lose the catch-up sync.
@@ -14707,11 +15045,11 @@ function runInLeaderTab(source, request) {
14707
15045
  return;
14708
15046
  }
14709
15047
  log(`${source} sync skipped: another tab leads`);
14710
- if (deferredUntilLeader.has(source))
15048
+ if (deferredUntilLeader$1.has(source))
14711
15049
  return;
14712
- deferredUntilLeader.add(source);
15050
+ deferredUntilLeader$1.add(source);
14713
15051
  void whenLeaderTab().then(() => {
14714
- deferredUntilLeader.delete(source);
15052
+ deferredUntilLeader$1.delete(source);
14715
15053
  request();
14716
15054
  });
14717
15055
  }
@@ -14785,10 +15123,10 @@ var easSyncManager = /*#__PURE__*/Object.freeze({
14785
15123
  startEasSyncActor: startEasSyncActor
14786
15124
  });
14787
15125
 
14788
- const logger$e = debug('seedSdk:services:events');
15126
+ const logger$f = debug('seedSdk:services:events');
14789
15127
  const handleServiceSaveState = (event) => {
14790
15128
  const { state, serviceId } = event;
14791
- logger$e(`[browser] [service.saveState.request] serviceId: ${serviceId}`);
15129
+ logger$f(`[browser] [service.saveState.request] serviceId: ${serviceId}`);
14792
15130
  // TODO: This is called from Node as well. Do we need it? If so, need to generalize this to all platforms.
14793
15131
  // localStorage.setItem(`seed_sdk_service_${serviceId}`, JSON.stringify(state))
14794
15132
  };
@@ -14897,9 +15235,9 @@ function normalizeSeedConfigEndpoints(config) {
14897
15235
  return { ...config, endpoints: next };
14898
15236
  }
14899
15237
 
14900
- const logger$d = debug('seedSdk:ClientManager:initialize');
15238
+ const logger$e = debug('seedSdk:ClientManager:initialize');
14901
15239
  const platformClassesInit = xstate.fromCallback(({ sendBack, input: { context, event } }) => {
14902
- logger$d('initialize from ClientManager');
15240
+ logger$e('initialize from ClientManager');
14903
15241
  const { isInitialized } = context;
14904
15242
  if (!event || !('options' in event)) {
14905
15243
  throw new Error('Initialize event must include options');
@@ -15071,7 +15409,7 @@ const platformClassesInit = xstate.fromCallback(({ sendBack, input: { context, e
15071
15409
  };
15072
15410
  });
15073
15411
 
15074
- const logger$c = debug('seedSdk:client:writeToDb');
15412
+ const logger$d = debug('seedSdk:client:writeToDb');
15075
15413
  const saveAppState = xstate.fromCallback(({ sendBack, input: { key, value } }) => {
15076
15414
  const _saveAppState = async () => {
15077
15415
  try {
@@ -15079,7 +15417,7 @@ const saveAppState = xstate.fromCallback(({ sendBack, input: { key, value } }) =
15079
15417
  if (!appDb) {
15080
15418
  // In test environments, continue anyway
15081
15419
  if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
15082
- logger$c('[client/actors] [saveAppState] App DB not found, but continuing in test environment');
15420
+ logger$d('[client/actors] [saveAppState] App DB not found, but continuing in test environment');
15083
15421
  return;
15084
15422
  }
15085
15423
  throw new Error('App DB not found');
@@ -15095,13 +15433,13 @@ const saveAppState = xstate.fromCallback(({ sendBack, input: { key, value } }) =
15095
15433
  value: JSON.stringify(value),
15096
15434
  },
15097
15435
  });
15098
- logger$c('result', result);
15436
+ logger$d('result', result);
15099
15437
  }
15100
15438
  catch (error) {
15101
- logger$c('[client/actors] [saveAppState] Error saving app state:', error);
15439
+ logger$d('[client/actors] [saveAppState] Error saving app state:', error);
15102
15440
  // In test environments, continue anyway
15103
15441
  if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
15104
- logger$c('[client/actors] [saveAppState] Continuing despite error in test environment');
15442
+ logger$d('[client/actors] [saveAppState] Continuing despite error in test environment');
15105
15443
  return;
15106
15444
  }
15107
15445
  throw error;
@@ -15116,10 +15454,10 @@ const saveAppState = xstate.fromCallback(({ sendBack, input: { key, value } }) =
15116
15454
  });
15117
15455
  })
15118
15456
  .catch((error) => {
15119
- logger$c('[client/actors] [saveAppState] Error in promise chain:', error);
15457
+ logger$d('[client/actors] [saveAppState] Error in promise chain:', error);
15120
15458
  // In test environments, still send success to allow state machine to progress
15121
15459
  if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
15122
- logger$c('[client/actors] [saveAppState] Sending success despite error in test environment');
15460
+ logger$d('[client/actors] [saveAppState] Sending success despite error in test environment');
15123
15461
  sendBack({
15124
15462
  type: 'saveAppStateSuccess',
15125
15463
  key,
@@ -15189,7 +15527,7 @@ const fileSystemInit = xstate.fromCallback(({ sendBack, input: { context }, }) =
15189
15527
  };
15190
15528
  });
15191
15529
 
15192
- const logger$b = debug('seedSdk:client:actors:dbInit');
15530
+ const logger$c = debug('seedSdk:client:actors:dbInit');
15193
15531
  const dbInit = xstate.fromCallback(({ sendBack, input: { context } }) => {
15194
15532
  const _dbInit = async () => {
15195
15533
  const { filesDir } = context;
@@ -15203,14 +15541,14 @@ const dbInit = xstate.fromCallback(({ sendBack, input: { context } }) => {
15203
15541
  if (!appDb) {
15204
15542
  throw new Error('Database not available after preparation');
15205
15543
  }
15206
- logger$b('[client/actors] [dbInit] Database prepared and ready');
15544
+ logger$c('[client/actors] [dbInit] Database prepared and ready');
15207
15545
  };
15208
15546
  _dbInit()
15209
15547
  .then(() => {
15210
15548
  sendBack({ type: ClientManagerEvents.DB_READY });
15211
15549
  })
15212
15550
  .catch((error) => {
15213
- logger$b('Error in dbInit:', error);
15551
+ logger$c('Error in dbInit:', error);
15214
15552
  sendBack({
15215
15553
  type: 'error',
15216
15554
  error: error instanceof Error ? error : new Error(String(error))
@@ -15218,7 +15556,7 @@ const dbInit = xstate.fromCallback(({ sendBack, input: { context } }) => {
15218
15556
  });
15219
15557
  });
15220
15558
 
15221
- const logger$a = debug('seedSdk:client:actors:addModelsToStore');
15559
+ const logger$b = debug('seedSdk:client:actors:addModelsToStore');
15222
15560
  const addModelsToStore = xstate.fromCallback(({ sendBack, input: { context } }) => {
15223
15561
  const _addModelsToStore = async () => {
15224
15562
  let { models } = context;
@@ -15232,7 +15570,7 @@ const addModelsToStore = xstate.fromCallback(({ sendBack, input: { context } })
15232
15570
  // Models are now Model instances, no registration needed
15233
15571
  // They should be created via Model.create() and are accessible via Model static methods
15234
15572
  for (const [key] of Object.entries(allModels)) {
15235
- logger$a('model available:', key);
15573
+ logger$b('model available:', key);
15236
15574
  }
15237
15575
  };
15238
15576
  _addModelsToStore()
@@ -15240,7 +15578,7 @@ const addModelsToStore = xstate.fromCallback(({ sendBack, input: { context } })
15240
15578
  sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_STORE_SUCCESS });
15241
15579
  })
15242
15580
  .catch((error) => {
15243
- logger$a('[client/actors] [addModelsToStore] Error:', error);
15581
+ logger$b('[client/actors] [addModelsToStore] Error:', error);
15244
15582
  sendBack({
15245
15583
  type: 'error',
15246
15584
  error: error instanceof Error ? error : new Error(String(error)),
@@ -15248,7 +15586,7 @@ const addModelsToStore = xstate.fromCallback(({ sendBack, input: { context } })
15248
15586
  });
15249
15587
  });
15250
15588
 
15251
- const logger$9 = debug('seedSdk:client:actors:addModelsToDb');
15589
+ const logger$a = debug('seedSdk:client:actors:addModelsToDb');
15252
15590
  /**
15253
15591
  * Returns every `models` row named in `modelNames`, inserting a null-schemaFileId stub for each name
15254
15592
  * with no row yet (the schema import adopts stubs via findOrCreateModelRecord). Check-then-insert:
@@ -15271,7 +15609,7 @@ async function ensureModelStubs(appDb, modelNames, filesDir) {
15271
15609
  .returning({ id: models$1.id, name: models$1.name, schemaFileId: models$1.schemaFileId }));
15272
15610
  rows.push(...newlyInserted);
15273
15611
  for (const name of modelsToInsert) {
15274
- logger$9('[client/actors] [addModelsToDb] inserted model:', name);
15612
+ logger$a('[client/actors] [addModelsToDb] inserted model:', name);
15275
15613
  }
15276
15614
  }
15277
15615
  return rows;
@@ -15308,7 +15646,7 @@ const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
15308
15646
  for (const modelName of modelNames) {
15309
15647
  const foundModel = rowFor(modelName);
15310
15648
  if (!foundModel) {
15311
- logger$9('[client/actors] [addModelsToDb] Warning: Could not find or create model:', modelName);
15649
+ logger$a('[client/actors] [addModelsToDb] Warning: Could not find or create model:', modelName);
15312
15650
  hasModelsInDb = false;
15313
15651
  continue;
15314
15652
  }
@@ -15320,7 +15658,7 @@ const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
15320
15658
  }
15321
15659
  // If we have no models to process, still send success (empty models is valid)
15322
15660
  if (schemaDefsByModelName.size === 0) {
15323
- logger$9('[client/actors] [addModelsToDb] No models to process, but continuing');
15661
+ logger$a('[client/actors] [addModelsToDb] No models to process, but continuing');
15324
15662
  sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
15325
15663
  return;
15326
15664
  }
@@ -15363,15 +15701,15 @@ const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
15363
15701
  requestEasSyncFromModelsInit();
15364
15702
  }
15365
15703
  else {
15366
- logger$9('[client/actors] [addModelsToDb] No schemas found from EAS, but continuing');
15704
+ logger$a('[client/actors] [addModelsToDb] No schemas found from EAS, but continuing');
15367
15705
  }
15368
15706
  }
15369
15707
  catch (error) {
15370
15708
  if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
15371
- logger$9('[client/actors] [addModelsToDb] Warning: Could not fetch schemas from EAS (background):', error.message);
15709
+ logger$a('[client/actors] [addModelsToDb] Warning: Could not fetch schemas from EAS (background):', error.message);
15372
15710
  }
15373
15711
  else {
15374
- logger$9('[client/actors] [addModelsToDb] Error fetching schemas (background):', error.message);
15712
+ logger$a('[client/actors] [addModelsToDb] Error fetching schemas (background):', error.message);
15375
15713
  }
15376
15714
  }
15377
15715
  };
@@ -15383,10 +15721,10 @@ const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
15383
15721
  sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
15384
15722
  })
15385
15723
  .catch((error) => {
15386
- logger$9('[client/actors] [addModelsToDb] Error:', error);
15724
+ logger$a('[client/actors] [addModelsToDb] Error:', error);
15387
15725
  // In test environments, still send success to allow initialization to complete
15388
15726
  if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
15389
- logger$9('[client/actors] [addModelsToDb] Continuing despite error in test environment');
15727
+ logger$a('[client/actors] [addModelsToDb] Continuing despite error in test environment');
15390
15728
  sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
15391
15729
  }
15392
15730
  else {
@@ -15399,7 +15737,7 @@ const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
15399
15737
  return () => { };
15400
15738
  });
15401
15739
 
15402
- const logger$8 = debug('seedSdk:helpers:localDbChain');
15740
+ const logger$9 = debug('seedSdk:helpers:localDbChain');
15403
15741
  /** appState key recording which EAS chain the local database holds attestations from. */
15404
15742
  const EAS_CHAIN_ID_APP_STATE_KEY = 'easChainId';
15405
15743
  /**
@@ -15469,7 +15807,7 @@ async function loadLocalDbChain() {
15469
15807
  const localChainId = await resolveLocalDbChainId(appDb);
15470
15808
  if (localChainId !== undefined) {
15471
15809
  eas.configureEasReadChain('localDb', { chainId: localChainId });
15472
- logger$8('local DB holds chain %d', localChainId);
15810
+ logger$9('local DB holds chain %d', localChainId);
15473
15811
  return;
15474
15812
  }
15475
15813
  if (eas.isEasReadChainConfigured()) {
@@ -15495,7 +15833,7 @@ async function assertLocalDbChain() {
15495
15833
  eas.configureEasReadChain('localDb', { chainId: localChainId ?? chainId });
15496
15834
  }
15497
15835
 
15498
- const logger$7 = debug('seedSdk:client:actors:saveConfig');
15836
+ const logger$8 = debug('seedSdk:client:actors:saveConfig');
15499
15837
  /**
15500
15838
  * Saves the addresses passed to init. Hosts pass `addresses: []` before a wallet connects. In the
15501
15839
  * first (leader) tab that clears stored addresses, as it always has, so drafts made before the
@@ -15515,13 +15853,13 @@ async function persistInitAddresses(appDb, { addresses, ownedAddresses, watchedA
15515
15853
  .onConflictDoUpdate({ target: appState.key, set: { value } });
15516
15854
  }
15517
15855
  const saveConfig = xstate.fromCallback(({ sendBack, input: { context } }) => {
15518
- logger$7('saveConfig starting');
15856
+ logger$8('saveConfig starting');
15519
15857
  const { endpoints, addresses, ownedAddresses, watchedAddresses, arweaveDomain, uploadApiBaseUrl, gatewayTransport, gatewayHyperKey, gatewaySidecarHost, gatewaySidecarPort, gatewayProxyBaseUrl, } = context;
15520
15858
  // Validate endpoints - required for proper initialization
15521
15859
  // If endpoints are missing or invalid, initialization should fail
15522
15860
  if (!endpoints || !endpoints.filePaths || !endpoints.files) {
15523
15861
  const error = new Error('saveConfig called with invalid endpoints: endpoints must include both filePaths and files');
15524
- logger$7('[internal/actors] [saveConfig] Invalid endpoints:', { endpoints });
15862
+ logger$8('[internal/actors] [saveConfig] Invalid endpoints:', { endpoints });
15525
15863
  throw error;
15526
15864
  }
15527
15865
  const _saveConfig = async () => {
@@ -15530,7 +15868,7 @@ const saveConfig = xstate.fromCallback(({ sendBack, input: { context } }) => {
15530
15868
  if (!appDb) {
15531
15869
  // In test environments, continue anyway
15532
15870
  if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
15533
- logger$7('[internal/actors] [saveConfig] App DB not found, but continuing in test environment');
15871
+ logger$8('[internal/actors] [saveConfig] App DB not found, but continuing in test environment');
15534
15872
  return;
15535
15873
  }
15536
15874
  throw new Error('App DB not found');
@@ -15585,10 +15923,10 @@ const saveConfig = xstate.fromCallback(({ sendBack, input: { context } }) => {
15585
15923
  await loadLocalDbChain();
15586
15924
  }
15587
15925
  catch (error) {
15588
- logger$7('[internal/actors] [saveConfig] Error saving config:', error);
15926
+ logger$8('[internal/actors] [saveConfig] Error saving config:', error);
15589
15927
  // In test environments, continue anyway
15590
15928
  if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
15591
- logger$7('[internal/actors] [saveConfig] Continuing despite error in test environment');
15929
+ logger$8('[internal/actors] [saveConfig] Continuing despite error in test environment');
15592
15930
  return;
15593
15931
  }
15594
15932
  throw error;
@@ -15597,14 +15935,14 @@ const saveConfig = xstate.fromCallback(({ sendBack, input: { context } }) => {
15597
15935
  // Init writes run one tab at a time (docs/MULTI_TAB.md).
15598
15936
  withSeedDbLock('init', context.filesDir, _saveConfig)
15599
15937
  .then(() => {
15600
- logger$7('[internal/actors] [saveConfig] saveConfig success');
15938
+ logger$8('[internal/actors] [saveConfig] saveConfig success');
15601
15939
  return sendBack({ type: ClientManagerEvents.SAVE_CONFIG_SUCCESS });
15602
15940
  })
15603
15941
  .catch((error) => {
15604
- logger$7('[internal/actors] [saveConfig] Error in saveConfig promise chain:', error);
15942
+ logger$8('[internal/actors] [saveConfig] Error in saveConfig promise chain:', error);
15605
15943
  // In test environments, still send success to allow state machine to progress
15606
15944
  if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
15607
- logger$7('[internal/actors] [saveConfig] Sending success despite error in test environment');
15945
+ logger$8('[internal/actors] [saveConfig] Sending success despite error in test environment');
15608
15946
  sendBack({ type: ClientManagerEvents.SAVE_CONFIG_SUCCESS });
15609
15947
  }
15610
15948
  else {
@@ -15617,7 +15955,7 @@ const saveConfig = xstate.fromCallback(({ sendBack, input: { context } }) => {
15617
15955
  return () => { };
15618
15956
  });
15619
15957
 
15620
- const logger$6 = debug('seedSdk:helpers:schema');
15958
+ const logger$7 = debug('seedSdk:helpers:schema');
15621
15959
  /**
15622
15960
  * Sanitize a schema name to be filesystem-safe
15623
15961
  * Replaces all special characters (except alphanumeric, hyphens, underscores) with underscores
@@ -15813,7 +16151,7 @@ async function listCompleteSchemaFiles() {
15813
16151
  const dirExists = await BaseFileManager.pathExists(workingDir);
15814
16152
  if (!dirExists) {
15815
16153
  // Directory doesn't exist yet - return empty array (not an error condition)
15816
- logger$6(`Working directory does not exist yet: ${workingDir}, returning empty schema list`);
16154
+ logger$7(`Working directory does not exist yet: ${workingDir}, returning empty schema list`);
15817
16155
  return [];
15818
16156
  }
15819
16157
  const files = await fs.promises.readdir(workingDir);
@@ -15949,7 +16287,7 @@ async function loadAllSchemasFromDb() {
15949
16287
  }
15950
16288
  catch (error) {
15951
16289
  // If we can't list schema files (e.g., directory doesn't exist yet), continue without file-based loading
15952
- logger$6(`Error listing complete schema files (continuing with DB data): ${error instanceof Error ? error.message : String(error)}`);
16290
+ logger$7(`Error listing complete schema files (continuing with DB data): ${error instanceof Error ? error.message : String(error)}`);
15953
16291
  completeSchemaFiles = [];
15954
16292
  }
15955
16293
  }
@@ -16002,7 +16340,7 @@ async function loadAllSchemasFromDb() {
16002
16340
  continue;
16003
16341
  }
16004
16342
  catch (error) {
16005
- logger$6(`Error parsing schemaData for ${schemaName}:`, error);
16343
+ logger$7(`Error parsing schemaData for ${schemaName}:`, error);
16006
16344
  // Fall through to file-based loading
16007
16345
  }
16008
16346
  }
@@ -16044,7 +16382,7 @@ async function loadAllSchemasFromDb() {
16044
16382
  continue;
16045
16383
  }
16046
16384
  catch (error) {
16047
- logger$6(`Error loading schema file for ${schemaName}:`, error);
16385
+ logger$7(`Error loading schema file for ${schemaName}:`, error);
16048
16386
  // Fall through to try loading from schemaData if available
16049
16387
  }
16050
16388
  }
@@ -16088,7 +16426,7 @@ async function loadAllSchemasFromDb() {
16088
16426
  continue;
16089
16427
  }
16090
16428
  catch (error) {
16091
- logger$6(`Error parsing schemaData for ${schemaName}:`, error);
16429
+ logger$7(`Error parsing schemaData for ${schemaName}:`, error);
16092
16430
  }
16093
16431
  }
16094
16432
  }
@@ -16099,11 +16437,11 @@ async function loadAllSchemasFromDb() {
16099
16437
  // Only process if not already in result
16100
16438
  if (!processedSchemaNames.has(schemaFileInfo.name)) {
16101
16439
  if (isInternalSchema(schemaFileInfo.name, schemaFileInfo.schemaFileId)) {
16102
- logger$6(`STEP 3: skipping internal schema file: ${schemaFileInfo.filePath}`);
16440
+ logger$7(`STEP 3: skipping internal schema file: ${schemaFileInfo.filePath}`);
16103
16441
  continue;
16104
16442
  }
16105
16443
  try {
16106
- logger$6(`STEP 3: processing schema file: ${schemaFileInfo.name} from ${schemaFileInfo.filePath}`);
16444
+ logger$7(`STEP 3: processing schema file: ${schemaFileInfo.name} from ${schemaFileInfo.filePath}`);
16107
16445
  const content = await BaseFileManager.readFileAsString(schemaFileInfo.filePath);
16108
16446
  const schemaFile = JSON.parse(content);
16109
16447
  // Import this schema to database (mark as non-draft since it's in a file)
@@ -16123,7 +16461,7 @@ async function loadAllSchemasFromDb() {
16123
16461
  processedSchemaNames.add(schemaFileInfo.name);
16124
16462
  }
16125
16463
  catch (error) {
16126
- logger$6(`Error loading schema file ${schemaFileInfo.filePath}:`, error);
16464
+ logger$7(`Error loading schema file ${schemaFileInfo.filePath}:`, error);
16127
16465
  }
16128
16466
  }
16129
16467
  }
@@ -16140,7 +16478,7 @@ async function migrateFileSchemasToDb() {
16140
16478
  if (!db) {
16141
16479
  throw new Error('Database not found');
16142
16480
  }
16143
- logger$6('Starting migration of file-based schemas to database');
16481
+ logger$7('Starting migration of file-based schemas to database');
16144
16482
  // Get all complete schema files
16145
16483
  const completeSchemas = await listCompleteSchemaFiles();
16146
16484
  let migratedCount = 0;
@@ -16150,7 +16488,7 @@ async function migrateFileSchemasToDb() {
16150
16488
  const content = await BaseFileManager.readFileAsString(schemaFileInfo.filePath);
16151
16489
  const schemaFile = JSON.parse(content);
16152
16490
  if (!schemaFile.$schema || !schemaFile.metadata?.name) {
16153
- logger$6(`Skipping invalid schema file: ${schemaFileInfo.filePath}`);
16491
+ logger$7(`Skipping invalid schema file: ${schemaFileInfo.filePath}`);
16154
16492
  continue;
16155
16493
  }
16156
16494
  const schemaName = schemaFile.metadata.name;
@@ -16172,17 +16510,17 @@ async function migrateFileSchemasToDb() {
16172
16510
  JSON.stringify(schemaFile, null, 2), // schemaData
16173
16511
  false);
16174
16512
  migratedCount++;
16175
- logger$6(`Migrated schema: ${schemaName} v${schemaFile.version}`);
16513
+ logger$7(`Migrated schema: ${schemaName} v${schemaFile.version}`);
16176
16514
  }
16177
16515
  else {
16178
- logger$6(`Schema ${schemaName} already exists in database, skipping`);
16516
+ logger$7(`Schema ${schemaName} already exists in database, skipping`);
16179
16517
  }
16180
16518
  }
16181
16519
  catch (error) {
16182
- logger$6(`Error migrating schema file ${schemaFileInfo.filePath}:`, error);
16520
+ logger$7(`Error migrating schema file ${schemaFileInfo.filePath}:`, error);
16183
16521
  }
16184
16522
  }
16185
- logger$6(`Migration complete: ${migratedCount} schemas migrated`);
16523
+ logger$7(`Migration complete: ${migratedCount} schemas migrated`);
16186
16524
  return migratedCount;
16187
16525
  }
16188
16526
  /**
@@ -16237,7 +16575,7 @@ const getDeterministicIdsWithPrefix = (prefix) => {
16237
16575
  return (suffix) => utils.bytesToHex(prefixHash.clone().update(utils.utf8ToBytes(suffix)).digest()).slice(0, 10);
16238
16576
  };
16239
16577
 
16240
- const logger$5 = debug('seedSdk:imports:json');
16578
+ const logger$6 = debug('seedSdk:imports:json');
16241
16579
  /**
16242
16580
  * Get refValueType from a property object with case-insensitive key lookup.
16243
16581
  * Handles refValueType, refvaluetype, ref_value_type, elementType, and legacy items.type / items.Type.
@@ -16326,11 +16664,11 @@ const verifyPropertiesPersisted = async (db, modelId, modelName, maxRetries = 10
16326
16664
  .where(eq(propertiesTable.modelId, modelId))
16327
16665
  .limit(1);
16328
16666
  if (props.length > 0) {
16329
- logger$5(`Verified properties exist for model "${modelName}" (modelId: ${modelId}) after ${attempt + 1} attempt(s)`);
16667
+ logger$6(`Verified properties exist for model "${modelName}" (modelId: ${modelId}) after ${attempt + 1} attempt(s)`);
16330
16668
  return;
16331
16669
  }
16332
16670
  if (attempt < maxRetries - 1) {
16333
- logger$5(`Properties not yet visible for model "${modelName}" (modelId: ${modelId}), retrying in ${retryDelay}ms (attempt ${attempt + 1}/${maxRetries})`);
16671
+ logger$6(`Properties not yet visible for model "${modelName}" (modelId: ${modelId}), retrying in ${retryDelay}ms (attempt ${attempt + 1}/${maxRetries})`);
16334
16672
  await new Promise(resolve => setTimeout(resolve, retryDelay));
16335
16673
  }
16336
16674
  }
@@ -16636,7 +16974,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16636
16974
  if (parsed.$schema && parsed.metadata) {
16637
16975
  // It's already a complete schema format - preserve it (id may be missing, will be generated)
16638
16976
  originalSchemaFile = parsed;
16639
- logger$5(`Input is complete schema format (${originalSchemaFile.id ? `preserving ID: ${originalSchemaFile.id}` : 'id will be generated'})`);
16977
+ logger$6(`Input is complete schema format (${originalSchemaFile.id ? `preserving ID: ${originalSchemaFile.id}` : 'id will be generated'})`);
16640
16978
  }
16641
16979
  }
16642
16980
  catch {
@@ -16673,16 +17011,16 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16673
17011
  .limit(1);
16674
17012
  if (existingByName.length > 0 && existingByName[0].schemaData) {
16675
17013
  const existing = existingByName[0];
16676
- logger$5(`Idempotency: found existing schema by name+version: ${schemaFile.metadata.name} v${schemaFile.version ?? version}`);
17014
+ logger$6(`Idempotency: found existing schema by name+version: ${schemaFile.metadata.name} v${schemaFile.version ?? version}`);
16677
17015
  const existingSchema = JSON.parse(existing.schemaData);
16678
17016
  const contentMatches = compareSchemaContent(schemaFile, existingSchema);
16679
- logger$5(`Idempotency: compareSchemaContent=${contentMatches} for ${schemaFile.metadata.name}`);
17017
+ logger$6(`Idempotency: compareSchemaContent=${contentMatches} for ${schemaFile.metadata.name}`);
16680
17018
  if (contentMatches) {
16681
17019
  if (existing.schemaFileId) {
16682
17020
  const workingDir = BaseFileManager.getWorkingDir();
16683
17021
  const existingFilePath = getSchemaFilePath(workingDir, schemaFile.metadata.name, schemaFile.version ?? version, existing.schemaFileId);
16684
17022
  if (await BaseFileManager.pathExists(existingFilePath)) {
16685
- logger$5(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content, loading existing file`);
17023
+ logger$6(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content, loading existing file`);
16686
17024
  return await loadSchemaFromFile(existingFilePath);
16687
17025
  }
16688
17026
  await BaseFileManager.createDirIfNotExists(workingDir);
@@ -16690,7 +17028,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16690
17028
  await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
16691
17029
  return await loadSchemaFromFile(existingFilePath);
16692
17030
  }
16693
- logger$5(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content (no schemaFileId), using DB`);
17031
+ logger$6(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content (no schemaFileId), using DB`);
16694
17032
  return '';
16695
17033
  }
16696
17034
  }
@@ -16706,7 +17044,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16706
17044
  // processSchemaFiles runs multiple times (React StrictMode, app restarts).
16707
17045
  if (!schemaFile.id) {
16708
17046
  schemaFile.id = await getDeterministicSchemaFileId(schemaFile);
16709
- logger$5(`Generated deterministic schema ID for ${schemaFile.metadata.name}:`, schemaFile.id);
17047
+ logger$6(`Generated deterministic schema ID for ${schemaFile.metadata.name}:`, schemaFile.id);
16710
17048
  }
16711
17049
  // Before generating IDs, check if a file already exists with this schemaFileId
16712
17050
  // This handles the case where the schema was already loaded via loadSchemaFromFile
@@ -16716,7 +17054,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16716
17054
  const existingFileExists = await BaseFileManager.pathExists(existingFilePath);
16717
17055
  if (existingFileExists) {
16718
17056
  // File already exists with this schemaFileId - just load it instead of creating a new one
16719
- logger$5(`Schema file already exists with schemaFileId ${schemaFile.id}, loading it instead of creating new file`);
17057
+ logger$6(`Schema file already exists with schemaFileId ${schemaFile.id}, loading it instead of creating new file`);
16720
17058
  return await loadSchemaFromFile(existingFilePath);
16721
17059
  }
16722
17060
  // Generate missing model and property IDs.
@@ -16727,12 +17065,12 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16727
17065
  for (const [modelName, model] of Object.entries(schemaFile.models || {})) {
16728
17066
  if (!model.id) {
16729
17067
  model.id = getDeterministicId(modelName);
16730
- logger$5(`Generated deterministic model ID for ${modelName}:`, model.id);
17068
+ logger$6(`Generated deterministic model ID for ${modelName}:`, model.id);
16731
17069
  }
16732
17070
  for (const [propName, prop] of Object.entries(model.properties || {})) {
16733
17071
  if (!prop.id) {
16734
17072
  prop.id = getDeterministicId(modelName + propName);
16735
- logger$5(`Generated deterministic property ID for ${modelName}.${propName}:`, prop.id);
17073
+ logger$6(`Generated deterministic property ID for ${modelName}.${propName}:`, prop.id);
16736
17074
  }
16737
17075
  }
16738
17076
  }
@@ -16766,14 +17104,14 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16766
17104
  const workingDir = BaseFileManager.getWorkingDir();
16767
17105
  const existingFilePath = getSchemaFilePath(workingDir, importData.name, version, existing.schemaFileId);
16768
17106
  if (await BaseFileManager.pathExists(existingFilePath)) {
16769
- logger$5(`Schema ${importData.name} v${version} already exists with same content, loading existing file`);
17107
+ logger$6(`Schema ${importData.name} v${version} already exists with same content, loading existing file`);
16770
17108
  return await loadSchemaFromFile(existingFilePath);
16771
17109
  }
16772
17110
  // File missing but schemaData exists - restore file from schemaData
16773
17111
  await BaseFileManager.createDirIfNotExists(workingDir);
16774
17112
  await BaseFileManager.saveFile(existingFilePath, existing.schemaData);
16775
17113
  await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
16776
- logger$5(`Restored schema file from schemaData for ${importData.name} v${version}`);
17114
+ logger$6(`Restored schema file from schemaData for ${importData.name} v${version}`);
16777
17115
  return await loadSchemaFromFile(existingFilePath);
16778
17116
  }
16779
17117
  // No schemaFileId - restore file from schemaData using id from parsed schema
@@ -16784,10 +17122,10 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16784
17122
  await BaseFileManager.createDirIfNotExists(workingDir);
16785
17123
  await BaseFileManager.saveFile(existingFilePath, existing.schemaData);
16786
17124
  await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
16787
- logger$5(`Restored schema file from schemaData for ${importData.name} v${version}`);
17125
+ logger$6(`Restored schema file from schemaData for ${importData.name} v${version}`);
16788
17126
  return await loadSchemaFromFile(existingFilePath);
16789
17127
  }
16790
- logger$5(`Schema ${importData.name} v${version} already exists with same content (no id), using DB`);
17128
+ logger$6(`Schema ${importData.name} v${version} already exists with same content (no id), using DB`);
16791
17129
  return '';
16792
17130
  }
16793
17131
  // Content differs - create new version
@@ -16798,7 +17136,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16798
17136
  .orderBy(desc(schemasTable.version))
16799
17137
  .limit(1);
16800
17138
  const newVersion = latestVersionRows.length > 0 ? latestVersionRows[0].version + 1 : version;
16801
- logger$5(`Schema ${importData.name} content changed, creating new version v${newVersion}`);
17139
+ logger$6(`Schema ${importData.name} content changed, creating new version v${newVersion}`);
16802
17140
  schemaFile = transformImportToSchemaFile(importData, newVersion);
16803
17141
  version = newVersion;
16804
17142
  }
@@ -16822,7 +17160,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16822
17160
  // Check if this is an internal SDK schema (should not create files in app directory)
16823
17161
  const isInternal = isInternalSchema(schemaFile.metadata.name, schemaFile.id);
16824
17162
  if (isInternal) {
16825
- logger$5(`Skipping file creation for internal schema: ${schemaFile.metadata.name}`);
17163
+ logger$6(`Skipping file creation for internal schema: ${schemaFile.metadata.name}`);
16826
17164
  // For internal schemas, just load to database and store, don't create file
16827
17165
  // Extract schema name and version
16828
17166
  const schemaName = schemaFile.metadata?.name;
@@ -16879,7 +17217,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16879
17217
  // Use fixed internal schema ID if missing (never generate for internal)
16880
17218
  if (!schemaFile.id) {
16881
17219
  schemaFile.id = INTERNAL_SCHEMA_IDS[0];
16882
- logger$5('Using fixed internal schema ID:', schemaFile.id);
17220
+ logger$6('Using fixed internal schema ID:', schemaFile.id);
16883
17221
  }
16884
17222
  // Extract schemaFileIds from JSON file and generate missing ones BEFORE creating models
16885
17223
  // This ensures Model instances are created with correct IDs
@@ -16889,7 +17227,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16889
17227
  // Generate model ID if missing
16890
17228
  if (!model.id) {
16891
17229
  model.id = generateId();
16892
- logger$5(`Generated model ID for ${modelName}:`, model.id);
17230
+ logger$6(`Generated model ID for ${modelName}:`, model.id);
16893
17231
  // Update the schemaFile object so it's included in schemaData
16894
17232
  schemaFile.models[modelName].id = model.id;
16895
17233
  }
@@ -16899,7 +17237,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16899
17237
  // Generate property ID if missing
16900
17238
  if (!prop.id) {
16901
17239
  prop.id = generateId();
16902
- logger$5(`Generated property ID for ${modelName}.${propName}:`, prop.id);
17240
+ logger$6(`Generated property ID for ${modelName}.${propName}:`, prop.id);
16903
17241
  // Update the schemaFile object so it's included in schemaData
16904
17242
  schemaFile.models[modelName].properties[propName].id = prop.id;
16905
17243
  }
@@ -16911,7 +17249,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
16911
17249
  }
16912
17250
  // Convert JSON models to Model classes, passing modelFileIds and propertyFileIds so Model instances use correct IDs
16913
17251
  const modelDefinitions = await createModelsFromJson(importDataForInternal, modelFileIds, propertyFileIds);
16914
- logger$5('loadSchemaFromFile (internal) - modelDefinitions length:', Object.keys(modelDefinitions).length);
17252
+ logger$6('loadSchemaFromFile (internal) - modelDefinitions length:', Object.keys(modelDefinitions).length);
16915
17253
  // Convert schema file metadata to schema input for database
16916
17254
  const schemaInput = {
16917
17255
  name: schemaName,
@@ -17031,12 +17369,12 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
17031
17369
  }
17032
17370
  catch (dbError) {
17033
17371
  // Database not available - log warning but continue
17034
- logger$5('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
17372
+ logger$6('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
17035
17373
  }
17036
17374
  // Models are now Model instances, no registration needed
17037
17375
  // They should be created via Model.create() and are accessible via Model static methods
17038
17376
  for (const [modelName] of Object.entries(modelDefinitions)) {
17039
- logger$5('loadSchemaFromFile (internal) - model available:', modelName);
17377
+ logger$6('loadSchemaFromFile (internal) - model available:', modelName);
17040
17378
  }
17041
17379
  // Schema is now saved to database
17042
17380
  // useSchemas hook will pick it up via database queries
@@ -17047,7 +17385,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
17047
17385
  // Ensure schema ID is defined (should always be set by this point, but check for safety)
17048
17386
  if (!schemaFile.id) {
17049
17387
  schemaFile.id = generateId();
17050
- logger$5('Generated schema ID before file path creation:', schemaFile.id);
17388
+ logger$6('Generated schema ID before file path creation:', schemaFile.id);
17051
17389
  }
17052
17390
  // Get the target file path using ID-based naming (preferred)
17053
17391
  const filePath = getSchemaFilePath(workingDir, schemaFile.metadata.name, version, schemaFile.id);
@@ -17066,7 +17404,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
17066
17404
  const data = JSON.parse(content);
17067
17405
  if (data.$schema) {
17068
17406
  // File is already a complete schema, just load it
17069
- logger$5(`Schema file ${filePath} already exists and is complete, loading it`);
17407
+ logger$6(`Schema file ${filePath} already exists and is complete, loading it`);
17070
17408
  return await loadSchemaFromFile(filePath);
17071
17409
  }
17072
17410
  }
@@ -17084,7 +17422,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
17084
17422
  // Compare schemas structurally
17085
17423
  if (compareSchemasStructurally(schemaFile, existingSchema)) {
17086
17424
  // Schemas match - just load the existing file
17087
- logger$5(`Schema ${schemaFile.metadata.name} v${version} already exists with matching content, loading it`);
17425
+ logger$6(`Schema ${schemaFile.metadata.name} v${version} already exists with matching content, loading it`);
17088
17426
  return await loadSchemaFromFile(filePath);
17089
17427
  }
17090
17428
  else {
@@ -17259,7 +17597,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
17259
17597
  // Generate schema ID if missing (before creating schemaInput)
17260
17598
  if (!schemaFile.id) {
17261
17599
  schemaFile.id = generateId();
17262
- logger$5('Generated schema ID for schema file:', schemaFile.id);
17600
+ logger$6('Generated schema ID for schema file:', schemaFile.id);
17263
17601
  }
17264
17602
  // Extract schemaFileIds from JSON file and generate missing ones BEFORE creating models
17265
17603
  // This ensures Model instances are created with correct IDs
@@ -17269,7 +17607,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
17269
17607
  // Generate model ID if missing
17270
17608
  if (!model.id) {
17271
17609
  model.id = generateId();
17272
- logger$5(`Generated model ID for ${modelName}:`, model.id);
17610
+ logger$6(`Generated model ID for ${modelName}:`, model.id);
17273
17611
  // Update the schemaFile object so it's included in schemaData
17274
17612
  schemaFile.models[modelName].id = model.id;
17275
17613
  }
@@ -17279,7 +17617,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
17279
17617
  // Generate property ID if missing
17280
17618
  if (!prop.id) {
17281
17619
  prop.id = generateId();
17282
- logger$5(`Generated property ID for ${modelName}.${propName}:`, prop.id);
17620
+ logger$6(`Generated property ID for ${modelName}.${propName}:`, prop.id);
17283
17621
  // Update the schemaFile object so it's included in schemaData
17284
17622
  schemaFile.models[modelName].properties[propName].id = prop.id;
17285
17623
  }
@@ -17291,7 +17629,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
17291
17629
  }
17292
17630
  // Convert JSON models to Model classes, passing modelFileIds and propertyFileIds so Model instances use correct IDs
17293
17631
  const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
17294
- logger$5('loadSchemaFromFile - modelDefinitions length:', Object.keys(modelDefinitions).length);
17632
+ logger$6('loadSchemaFromFile - modelDefinitions length:', Object.keys(modelDefinitions).length);
17295
17633
  // Try to add schema and models to database if database is available
17296
17634
  try {
17297
17635
  const db = BaseDb.getAppDb();
@@ -17346,17 +17684,17 @@ const loadSchemaFromFile = async (schemaFilePath) => {
17346
17684
  await new Promise(resolve => setTimeout(resolve, 100));
17347
17685
  }
17348
17686
  }
17349
- logger$5(`Verifying properties: found ${modelLinks.length} model links for schema ${schemaName} (id: ${schemaRecord.id})`);
17687
+ logger$6(`Verifying properties: found ${modelLinks.length} model links for schema ${schemaName} (id: ${schemaRecord.id})`);
17350
17688
  // If we didn't verify via direct lookup, verify via join table
17351
17689
  if (!seedModelId || (seedModel.length === 0 || !seedModel[0].id)) {
17352
17690
  const seedModelLink = modelLinks.find((link) => link.modelName === 'Seed');
17353
17691
  if (seedModelLink && seedModelLink.modelId) {
17354
- logger$5(`Verifying properties for Seed model via join table (modelId: ${seedModelLink.modelId})`);
17692
+ logger$6(`Verifying properties for Seed model via join table (modelId: ${seedModelLink.modelId})`);
17355
17693
  await verifyPropertiesPersisted(db, seedModelLink.modelId, 'Seed', 10, 100);
17356
17694
  }
17357
17695
  else if (modelLinks.length > 0 && modelLinks[0].modelId) {
17358
17696
  // Fallback to first model if Seed not found
17359
- logger$5(`Verifying properties for ${modelLinks[0].modelName} model via join table (modelId: ${modelLinks[0].modelId})`);
17697
+ logger$6(`Verifying properties for ${modelLinks[0].modelName} model via join table (modelId: ${modelLinks[0].modelId})`);
17360
17698
  await verifyPropertiesPersisted(db, modelLinks[0].modelId, modelLinks[0].modelName || 'unknown', 10, 100);
17361
17699
  }
17362
17700
  }
@@ -17387,7 +17725,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
17387
17725
  const currentId = schemaFile.models[modelName].properties[propRecord.name].id;
17388
17726
  if (currentId !== propRecord.schemaFileId) {
17389
17727
  schemaFile.models[modelName].properties[propRecord.name].id = propRecord.schemaFileId;
17390
- logger$5(`Updated schemaFile property ID for ${modelName}.${propRecord.name} from ${currentId} to ${propRecord.schemaFileId}`);
17728
+ logger$6(`Updated schemaFile property ID for ${modelName}.${propRecord.name} from ${currentId} to ${propRecord.schemaFileId}`);
17391
17729
  schemaFileUpdated = true;
17392
17730
  }
17393
17731
  }
@@ -17405,21 +17743,21 @@ const loadSchemaFromFile = async (schemaFilePath) => {
17405
17743
  .set({ schemaData: updatedSchemaData })
17406
17744
  .where(eq(schemasTable.id, schemaRecord.id));
17407
17745
  if (schemaFileUpdated) {
17408
- logger$5(`Updated schemaData in database with actual property IDs for schema "${schemaName}"`);
17746
+ logger$6(`Updated schemaData in database with actual property IDs for schema "${schemaName}"`);
17409
17747
  }
17410
17748
  else {
17411
- logger$5(`Verified schemaData in database matches schemaFile for schema "${schemaName}"`);
17749
+ logger$6(`Verified schemaData in database matches schemaFile for schema "${schemaName}"`);
17412
17750
  }
17413
17751
  }
17414
17752
  }
17415
17753
  catch (dbError) {
17416
17754
  // Database not available - log warning but continue
17417
- logger$5('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
17755
+ logger$6('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
17418
17756
  }
17419
17757
  // Models are now Model instances, no registration needed
17420
17758
  // They should be created via Model.create() and are accessible via Model static methods
17421
17759
  for (const [modelName] of Object.entries(modelDefinitions)) {
17422
- logger$5('loadSchemaFromFile - model available:', modelName);
17760
+ logger$6('loadSchemaFromFile - model available:', modelName);
17423
17761
  }
17424
17762
  return schemaFilePath;
17425
17763
  }
@@ -17504,10 +17842,10 @@ propertyFileIds) => {
17504
17842
  // Pass id (schemaFileId) if provided to ensure Model instance uses correct ID
17505
17843
  // Note: indexes and description are ignored - they remain in JSON for schema file format compliance but are not used by Model instances
17506
17844
  if (modelFileId) {
17507
- logger$5(`Creating schema model "${modelName}" with modelFileId: ${modelFileId}`);
17845
+ logger$6(`Creating schema model "${modelName}" with modelFileId: ${modelFileId}`);
17508
17846
  }
17509
17847
  else {
17510
- logger$5(`Warning: Creating schema model "${modelName}" without modelFileId - it will be renamed if duplicates exist`);
17848
+ logger$6(`Warning: Creating schema model "${modelName}" without modelFileId - it will be renamed if duplicates exist`);
17511
17849
  }
17512
17850
  const modelInstance = Model.create(modelName, schemaName, {
17513
17851
  modelFileId: modelFileId, // Pass modelFileId (preferred) as id (schemaFileId) from JSON file
@@ -17533,7 +17871,7 @@ const createModelsFromJson = async (importData, modelFileIds, propertyFileIds) =
17533
17871
  // Use modelFileId from map (no fallback to modelDef.id as JsonImportSchema doesn't have id property)
17534
17872
  const finalModelFileId = modelFileId;
17535
17873
  if (!finalModelFileId) {
17536
- logger$5(`Warning: No modelFileId found for model "${modelName}" - model will be created without ID`);
17874
+ logger$6(`Warning: No modelFileId found for model "${modelName}" - model will be created without ID`);
17537
17875
  }
17538
17876
  // Get propertyFileIds for this model if available
17539
17877
  const modelPropertyFileIds = propertyFileIds?.get(modelName);
@@ -17723,7 +18061,7 @@ var SEEDPROTOCOL_Seed_Protocol_v1 = /*#__PURE__*/Object.freeze({
17723
18061
  version: version
17724
18062
  });
17725
18063
 
17726
- const logger$4 = debug('seedSdk:client:actors:processSchemaFiles');
18064
+ const logger$5 = debug('seedSdk:client:actors:processSchemaFiles');
17727
18065
  let processSchemaFilesChain = Promise.resolve();
17728
18066
  function resolveSchemaFilePath(schemaFile) {
17729
18067
  const path = BaseFileManager.getPathModule();
@@ -17751,7 +18089,7 @@ async function resolveSchemaNameFromSource(source) {
17751
18089
  }
17752
18090
  }
17753
18091
  catch (error) {
17754
- logger$4('Could not resolve schema name from path:', source, error);
18092
+ logger$5('Could not resolve schema name from path:', source, error);
17755
18093
  }
17756
18094
  }
17757
18095
  return null;
@@ -17760,7 +18098,7 @@ async function resolveSchemaNameFromSource(source) {
17760
18098
  // Schema processing can be slow with syncSchemaFromSource, loadAllSchemasFromDb, and OPFS file I/O
17761
18099
  const PROCESS_SCHEMA_FILES_TIMEOUT_MS = 120000;
17762
18100
  const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }) => {
17763
- logger$4('processSchemaFiles started');
18101
+ logger$5('processSchemaFiles started');
17764
18102
  let hasResponded = false;
17765
18103
  let timeoutId = null;
17766
18104
  const reportError = (error) => {
@@ -17770,7 +18108,7 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
17770
18108
  clearTimeout(timeoutId);
17771
18109
  timeoutId = null;
17772
18110
  }
17773
- logger$4('processSchemaFiles error:', error);
18111
+ logger$5('processSchemaFiles error:', error);
17774
18112
  sendBack({
17775
18113
  type: 'error',
17776
18114
  error: error instanceof Error ? error : new Error(String(error))
@@ -17784,7 +18122,7 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
17784
18122
  clearTimeout(timeoutId);
17785
18123
  timeoutId = null;
17786
18124
  }
17787
- logger$4('processSchemaFiles completed');
18125
+ logger$5('processSchemaFiles completed');
17788
18126
  sendBack({ type: ClientManagerEvents.PROCESS_SCHEMA_FILES_SUCCESS });
17789
18127
  }
17790
18128
  };
@@ -17796,7 +18134,7 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
17796
18134
  // Schemas written (or confirmed present) this run — skip redundant loadSchemaFromFile later
17797
18135
  const schemasWrittenThisRun = new Set();
17798
18136
  // First, load the internal seed-protocol schema
17799
- logger$4('Loading internal seed-protocol schema');
18137
+ logger$5('Loading internal seed-protocol schema');
17800
18138
  const internalSchemaData = internalSchema;
17801
18139
  const db = BaseDb.getAppDb();
17802
18140
  const internalSchemaExists = db
@@ -17805,21 +18143,21 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
17805
18143
  // Always mark internal schema as written so the DB/file loop does not re-apply it
17806
18144
  schemasWrittenThisRun.add(SEED_PROTOCOL_SCHEMA_NAME);
17807
18145
  if (internalSchemaExists) {
17808
- logger$4('Internal seed-protocol schema already in DB, skipping import');
18146
+ logger$5('Internal seed-protocol schema already in DB, skipping import');
17809
18147
  }
17810
18148
  else {
17811
18149
  try {
17812
18150
  // Import the internal schema to database (will create models and add to store)
17813
18151
  await importJsonSchema({ contents: JSON.stringify(internalSchemaData) }, internalSchemaData.version);
17814
- logger$4(`Loaded internal seed-protocol schema v${internalSchemaData.version}`);
18152
+ logger$5(`Loaded internal seed-protocol schema v${internalSchemaData.version}`);
17815
18153
  }
17816
18154
  catch (error) {
17817
18155
  // If schema already exists, that's fine - it means it was already loaded
17818
18156
  if (error?.message?.includes('already exists')) {
17819
- logger$4('Internal seed-protocol schema already loaded');
18157
+ logger$5('Internal seed-protocol schema already loaded');
17820
18158
  }
17821
18159
  else {
17822
- logger$4('Error loading internal seed-protocol schema:', error);
18160
+ logger$5('Error loading internal seed-protocol schema:', error);
17823
18161
  // Don't fail if internal schema can't be loaded - it might already be in DB
17824
18162
  }
17825
18163
  }
@@ -17832,7 +18170,7 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
17832
18170
  : '';
17833
18171
  const schemaId = typeof context.schema === 'object' && context.schema?.id ? String(context.schema.id) : undefined;
17834
18172
  if (isInternalSchema(schemaName, schemaId)) {
17835
- logger$4('Schema is internal (Seed Protocol), already loaded - skipping syncSchemaFromSource');
18173
+ logger$5('Schema is internal (Seed Protocol), already loaded - skipping syncSchemaFromSource');
17836
18174
  }
17837
18175
  else {
17838
18176
  try {
@@ -17841,10 +18179,10 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
17841
18179
  if (syncedName) {
17842
18180
  schemasWrittenThisRun.add(syncedName);
17843
18181
  }
17844
- logger$4(`Synced canonical schema from ${typeof context.schema === 'string' ? context.schema : 'object'}`);
18182
+ logger$5(`Synced canonical schema from ${typeof context.schema === 'string' ? context.schema : 'object'}`);
17845
18183
  }
17846
18184
  catch (error) {
17847
- logger$4(`Error syncing canonical schema:`, error);
18185
+ logger$5(`Error syncing canonical schema:`, error);
17848
18186
  // Don't fail init - schema might already be in DB
17849
18187
  }
17850
18188
  }
@@ -17859,23 +18197,23 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
17859
18197
  if (parsed?.metadata?.name) {
17860
18198
  schemasWrittenThisRun.add(String(parsed.metadata.name));
17861
18199
  }
17862
- logger$4(`Loaded schema from ${resolvedPath}`);
18200
+ logger$5(`Loaded schema from ${resolvedPath}`);
17863
18201
  }
17864
18202
  catch (error) {
17865
- logger$4(`Error loading schema file ${context.schemaFile}:`, error);
18203
+ logger$5(`Error loading schema file ${context.schemaFile}:`, error);
17866
18204
  // Don't fail init - schema might already be in DB
17867
18205
  }
17868
18206
  }
17869
18207
  // Process minimal import files (files without $schema) - skip when canonical schema is set
17870
18208
  if (!context.schema) {
17871
- logger$4('Listing schema files');
18209
+ logger$5('Listing schema files');
17872
18210
  let schemaFiles = [];
17873
18211
  try {
17874
18212
  schemaFiles = await listSchemaFiles();
17875
- logger$4(`Found ${schemaFiles.length} schema files to process`);
18213
+ logger$5(`Found ${schemaFiles.length} schema files to process`);
17876
18214
  }
17877
18215
  catch (error) {
17878
- logger$4('Error listing schema files (continuing anyway):', error);
18216
+ logger$5('Error listing schema files (continuing anyway):', error);
17879
18217
  schemaFiles = [];
17880
18218
  }
17881
18219
  for (const schemaFile of schemaFiles) {
@@ -17886,19 +18224,19 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
17886
18224
  }
17887
18225
  }
17888
18226
  catch (error) {
17889
- logger$4(`Error importing schema file ${schemaFile.filePath}:`, error);
18227
+ logger$5(`Error importing schema file ${schemaFile.filePath}:`, error);
17890
18228
  }
17891
18229
  }
17892
18230
  }
17893
18231
  // Then, load all schemas using the unified database-first approach
17894
- logger$4('Loading schemas from database and files');
18232
+ logger$5('Loading schemas from database and files');
17895
18233
  let allSchemasData = [];
17896
18234
  try {
17897
18235
  allSchemasData = await loadAllSchemasFromDb();
17898
- logger$4(`Loaded ${allSchemasData.length} schemas (${allSchemasData.filter(s => s.isDraft).length} drafts, ${allSchemasData.filter(s => !s.isDraft).length} published)`);
18236
+ logger$5(`Loaded ${allSchemasData.length} schemas (${allSchemasData.filter(s => s.isDraft).length} drafts, ${allSchemasData.filter(s => !s.isDraft).length} published)`);
17899
18237
  }
17900
18238
  catch (error) {
17901
- logger$4('Error loading schemas from database (continuing anyway):', error);
18239
+ logger$5('Error loading schemas from database (continuing anyway):', error);
17902
18240
  // Continue with empty array - this is not critical for initialization
17903
18241
  // Schemas can be loaded on-demand later
17904
18242
  allSchemasData = [];
@@ -17919,13 +18257,13 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
17919
18257
  }
17920
18258
  }
17921
18259
  catch (error) {
17922
- logger$4('Error counting linked models (re-applying all schema files):', error);
18260
+ logger$5('Error counting linked models (re-applying all schema files):', error);
17923
18261
  }
17924
18262
  }
17925
18263
  for (const schemaData of allSchemasData) {
17926
18264
  const schema = schemaData.schema;
17927
18265
  const schemaName = schema.metadata?.name || 'unknown';
17928
- logger$4(`Processing schema: ${schemaName} v${schema.version} (${schemaData.isDraft ? 'draft' : 'published'}, source: ${schemaData.source})`);
18266
+ logger$5(`Processing schema: ${schemaName} v${schema.version} (${schemaData.isDraft ? 'draft' : 'published'}, source: ${schemaData.source})`);
17929
18267
  // For published schemas (not drafts), load models from file if available
17930
18268
  if (!schemaData.isDraft && schema.id) {
17931
18269
  // loadAllSchemasFromDb already picked the latest file for this schema (and read it)
@@ -17955,7 +18293,7 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
17955
18293
  }
17956
18294
  }
17957
18295
  catch (error) {
17958
- logger$4(`Error loading schema file for ${schemaName}:`, error);
18296
+ logger$5(`Error loading schema file for ${schemaName}:`, error);
17959
18297
  }
17960
18298
  }
17961
18299
  else {
@@ -18004,11 +18342,11 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
18004
18342
  };
18005
18343
  const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
18006
18344
  Object.assign(allModels, modelDefinitions);
18007
- logger$4(`Loaded ${Object.keys(modelDefinitions).length} models from schema data for ${schemaName}`);
18345
+ logger$5(`Loaded ${Object.keys(modelDefinitions).length} models from schema data for ${schemaName}`);
18008
18346
  }
18009
18347
  }
18010
18348
  catch (error) {
18011
- logger$4(`Error creating models from schema data for ${schemaName}:`, error);
18349
+ logger$5(`Error creating models from schema data for ${schemaName}:`, error);
18012
18350
  }
18013
18351
  }
18014
18352
  }
@@ -18058,11 +18396,11 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
18058
18396
  };
18059
18397
  const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
18060
18398
  Object.assign(allModels, modelDefinitions);
18061
- logger$4(`Loaded ${Object.keys(modelDefinitions).length} models from draft schema ${schemaName}`);
18399
+ logger$5(`Loaded ${Object.keys(modelDefinitions).length} models from draft schema ${schemaName}`);
18062
18400
  }
18063
18401
  }
18064
18402
  catch (error) {
18065
- logger$4(`Error creating models from draft schema ${schemaName}:`, error);
18403
+ logger$5(`Error creating models from draft schema ${schemaName}:`, error);
18066
18404
  }
18067
18405
  }
18068
18406
  // Schemas are now loaded on-demand via database queries (useSchemas hook uses loadAllSchemasFromDb)
@@ -18080,7 +18418,7 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
18080
18418
  // Its schema and model inserts check for rows first, so tabs take turns (docs/MULTI_TAB.md).
18081
18419
  .then(() => withSeedDbLock('init', context.filesDir, _processSchemaFiles))
18082
18420
  .catch((err) => {
18083
- logger$4('processSchemaFiles chain error:', err);
18421
+ logger$5('processSchemaFiles chain error:', err);
18084
18422
  throw err;
18085
18423
  });
18086
18424
  processSchemaFilesChain.then(reportSuccess).catch((error) => {
@@ -18095,6 +18433,285 @@ const processSchemaFiles = xstate.fromCallback(({ sendBack, input: { context } }
18095
18433
  };
18096
18434
  });
18097
18435
 
18436
+ /**
18437
+ * A legacy ItemStorage draft row: a local edit (no attestation uid, not derived from one) that holds
18438
+ * the content itself in property_value, with no file reference. Item.create / createNewItem stored
18439
+ * ItemStorage values like this before they went through the save pipeline.
18440
+ */
18441
+ const isVerbatimItemStorageDraftRow = (row) => !row.uid &&
18442
+ row.derivedFromUid == null &&
18443
+ !row.refResolvedValue &&
18444
+ typeof row.propertyValue === 'string' &&
18445
+ row.propertyValue !== '';
18446
+ /**
18447
+ * Convert one legacy ItemStorage draft row (see {@link isVerbatimItemStorageDraftRow}) into the
18448
+ * shape saveItemStorage gives a row: the content goes to the file a save would write
18449
+ * (`<seedUid or seedLocalId><extension>` in the property's storage directory), and the row records
18450
+ * `refResolvedValue`, `localStorageDir` and `refValueType: 'file'` with property_value cleared.
18451
+ * Used by publish (resolveItemStorageChildFile) and the one-time migration (migrateLegacyItemStorageRows).
18452
+ *
18453
+ * Reading the row, writing the file and updating the row happen under the file's lock
18454
+ * ({@link withItemStorageFileLock}), which saveItemStorage holds too: a save in this or another tab
18455
+ * either finishes before (the row, read again once the lock is held, is no longer legacy and is
18456
+ * left alone) or starts after (and overwrites the file and row with its content). Without the lock
18457
+ * a save landing between the read and the file write would have its file overwritten with the old
18458
+ * content. The row update also stays conditional on the row being unchanged, for writers that
18459
+ * don't take the lock (a tab still running an older SDK).
18460
+ *
18461
+ * Returns undefined when there was nothing to convert. Throws when the file can't be written; the
18462
+ * row is then unchanged.
18463
+ */
18464
+ const convertVerbatimItemStorageRow = async (localId, storage = {}) => {
18465
+ const appDb = BaseDb.getAppDb();
18466
+ if (!appDb || !localId)
18467
+ return undefined;
18468
+ const targetOf = (row) => {
18469
+ if (!isVerbatimItemStorageDraftRow(row))
18470
+ return undefined;
18471
+ const seedId = storage.seedId || row.seedUid || row.seedLocalId;
18472
+ if (!seedId)
18473
+ return undefined;
18474
+ return {
18475
+ seedId,
18476
+ localStorageDir: storage.localStorageDir || row.localStorageDir,
18477
+ filenameSuffix: storage.filenameSuffix,
18478
+ };
18479
+ };
18480
+ return withLockedItemStorageRow(localId, (row) => {
18481
+ const target = targetOf(row);
18482
+ return target && getItemStorageFilePath(target);
18483
+ }, async (row) => {
18484
+ const content = row.propertyValue;
18485
+ const { fileName, filePath, localStorageDir } = await writeItemStorageFile(targetOf(row), content);
18486
+ await appDb
18487
+ .update(metadata$1)
18488
+ .set({ refResolvedValue: fileName, localStorageDir, refValueType: 'file', propertyValue: null })
18489
+ .where(drizzleOrm.and(drizzleOrm.eq(metadata$1.localId, localId), drizzleOrm.isNull(metadata$1.refResolvedValue), drizzleOrm.eq(metadata$1.propertyValue, content)));
18490
+ // Changed between the read and the update by a writer outside the lock: that change stands.
18491
+ const after = await appDb
18492
+ .select({ refResolvedValue: metadata$1.refResolvedValue, propertyValue: metadata$1.propertyValue })
18493
+ .from(metadata$1)
18494
+ .where(drizzleOrm.eq(metadata$1.localId, localId))
18495
+ .limit(1);
18496
+ if (after[0]?.refResolvedValue !== fileName || after[0]?.propertyValue != null)
18497
+ return undefined;
18498
+ return { fileName, filePath, localStorageDir, content };
18499
+ });
18500
+ };
18501
+
18502
+ const logger$4 = debug('seedSdk:db:migrateLegacyItemStorageRows');
18503
+ /** appState key recording that legacy ItemStorage rows have been written to their files. */
18504
+ const LEGACY_ITEM_STORAGE_MIGRATION_KEY = 'legacyItemStorageFiles:v1';
18505
+ /** Runs in a row that left rows unconverted because a file write failed, before giving up. */
18506
+ const LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS = 3;
18507
+ const readMarker = async () => {
18508
+ const db = BaseDb.getAppDb();
18509
+ const rows = await db
18510
+ .select({ value: appState.value })
18511
+ .from(appState)
18512
+ .where(drizzleOrm.eq(appState.key, LEGACY_ITEM_STORAGE_MIGRATION_KEY))
18513
+ .limit(1);
18514
+ if (!rows.length)
18515
+ return undefined;
18516
+ try {
18517
+ return JSON.parse(rows[0].value ?? '');
18518
+ }
18519
+ catch {
18520
+ return null;
18521
+ }
18522
+ };
18523
+ const writeMarker = async (marker) => {
18524
+ const db = BaseDb.getAppDb();
18525
+ const now = Date.now();
18526
+ const value = JSON.stringify(marker);
18527
+ await db
18528
+ .insert(appState)
18529
+ .values({ key: LEGACY_ITEM_STORAGE_MIGRATION_KEY, value, createdAt: now, updatedAt: now })
18530
+ .onConflictDoUpdate({ target: appState.key, set: { value, updatedAt: now } });
18531
+ };
18532
+ /**
18533
+ * The storage settings of a metadata row's property: by its property_id, else by name in the
18534
+ * seed's own model (model names are only unique per schema). Undefined when it can't be told.
18535
+ */
18536
+ const createStorageResolver = () => {
18537
+ const db = BaseDb.getAppDb();
18538
+ const byPropertyId = new Map();
18539
+ const byModelAndName = new Map();
18540
+ return async (row) => {
18541
+ if (row.propertyId != null) {
18542
+ if (!byPropertyId.has(row.propertyId)) {
18543
+ const found = await db
18544
+ .select({
18545
+ storageType: properties.storageType,
18546
+ localStorageDir: properties.localStorageDir,
18547
+ filenameSuffix: properties.filenameSuffix,
18548
+ })
18549
+ .from(properties)
18550
+ .where(drizzleOrm.eq(properties.id, row.propertyId))
18551
+ .limit(1);
18552
+ byPropertyId.set(row.propertyId, found[0]);
18553
+ }
18554
+ const fromId = byPropertyId.get(row.propertyId);
18555
+ if (fromId)
18556
+ return fromId;
18557
+ }
18558
+ const modelFileId = await resolveItemModelFileId({ seedLocalId: row.seedLocalId, seedUid: row.seedUid });
18559
+ if (!modelFileId || !row.propertyName)
18560
+ return undefined;
18561
+ const key = `${modelFileId}\u0000${row.propertyName}`;
18562
+ if (!byModelAndName.has(key)) {
18563
+ const found = await db
18564
+ .select({
18565
+ storageType: properties.storageType,
18566
+ localStorageDir: properties.localStorageDir,
18567
+ filenameSuffix: properties.filenameSuffix,
18568
+ })
18569
+ .from(properties)
18570
+ .innerJoin(models$1, drizzleOrm.eq(properties.modelId, models$1.id))
18571
+ .where(drizzleOrm.and(drizzleOrm.eq(models$1.schemaFileId, modelFileId), drizzleOrm.eq(properties.name, row.propertyName)))
18572
+ .limit(1);
18573
+ byModelAndName.set(key, found[0]);
18574
+ }
18575
+ return byModelAndName.get(key);
18576
+ };
18577
+ };
18578
+ /** True if `row` is the row readers show for its property: the newest of its seed's rows by that name. */
18579
+ const isNewestRowOfProperty = async (row) => {
18580
+ if (!row.seedLocalId || !row.propertyName)
18581
+ return false;
18582
+ const db = BaseDb.getAppDb();
18583
+ const siblings = await db
18584
+ .select()
18585
+ .from(metadata$1)
18586
+ .where(drizzleOrm.and(drizzleOrm.eq(metadata$1.seedLocalId, row.seedLocalId), drizzleOrm.eq(metadata$1.propertyName, row.propertyName)));
18587
+ return [...siblings].sort(compareMetadataRowsLatestFirst)[0]?.localId === row.localId;
18588
+ };
18589
+ /**
18590
+ * One-time data migration: writes the content of legacy ItemStorage draft rows to their files.
18591
+ *
18592
+ * Before Item.create / createNewItem saved ItemStorage values through the save pipeline, a value
18593
+ * given at creation was stored verbatim in metadata.property_value with no file. Publish converts
18594
+ * such a row lazily (resolveItemStorageChildFile); this converts them all up front, with the same
18595
+ * code ({@link convertVerbatimItemStorageRow}), so every ItemStorage draft has the shape a save
18596
+ * gives it: the content in `<seedUid or seedLocalId><extension>`, the row holding
18597
+ * refResolvedValue / localStorageDir / refValueType 'file' and no property_value.
18598
+ *
18599
+ * Only local drafts (no uid, not derived from an attestation) of properties whose properties row
18600
+ * says `storage_type = 'ItemStorage'` are touched, and of those only the newest row of each
18601
+ * seed's property: that is the row reads show and saves write to, and older rows sharing the one
18602
+ * file name would overwrite it with older content. Published and synced rows are never changed.
18603
+ *
18604
+ * A row that fails is logged and left as it was (publish still converts it). The run is recorded
18605
+ * in appState under {@link LEGACY_ITEM_STORAGE_MIGRATION_KEY}; a run with failed rows is retried
18606
+ * on the next start, up to {@link LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS} runs. Safe to run
18607
+ * again regardless: a converted row no longer matches.
18608
+ *
18609
+ * @param options.force run even when the marker says it is done
18610
+ */
18611
+ async function migrateLegacyItemStorageRows(options = {}) {
18612
+ const result = {
18613
+ alreadyDone: false,
18614
+ candidates: 0,
18615
+ converted: 0,
18616
+ failed: 0,
18617
+ skipped: 0,
18618
+ };
18619
+ const db = BaseDb.getAppDb();
18620
+ if (!db)
18621
+ return { ...result, alreadyDone: true };
18622
+ const marker = await readMarker();
18623
+ const previousAttempts = marker?.status === 'retry' ? marker.attempts : 0;
18624
+ if (!options.force && marker && marker.status === 'done') {
18625
+ return { ...result, alreadyDone: true };
18626
+ }
18627
+ const itemStorageNames = (await db
18628
+ .selectDistinct({ name: properties.name })
18629
+ .from(properties)
18630
+ .where(drizzleOrm.eq(properties.storageType, 'ItemStorage'))).map((r) => r.name);
18631
+ const candidates = itemStorageNames.length
18632
+ ? await db
18633
+ .select()
18634
+ .from(metadata$1)
18635
+ .where(drizzleOrm.and(drizzleOrm.inArray(metadata$1.propertyName, itemStorageNames), drizzleOrm.or(drizzleOrm.isNull(metadata$1.uid), drizzleOrm.eq(metadata$1.uid, '')), drizzleOrm.isNull(metadata$1.derivedFromUid), drizzleOrm.isNull(metadata$1.refResolvedValue), drizzleOrm.isNotNull(metadata$1.propertyValue), drizzleOrm.ne(metadata$1.propertyValue, '')))
18636
+ : [];
18637
+ const resolveStorage = createStorageResolver();
18638
+ for (const row of candidates) {
18639
+ if (!row.localId || !isVerbatimItemStorageDraftRow(row))
18640
+ continue;
18641
+ try {
18642
+ const storage = await resolveStorage(row);
18643
+ if (storage?.storageType !== 'ItemStorage')
18644
+ continue;
18645
+ result.candidates++;
18646
+ if (!(await isNewestRowOfProperty(row))) {
18647
+ result.skipped++;
18648
+ continue;
18649
+ }
18650
+ const converted = await convertVerbatimItemStorageRow(row.localId, {
18651
+ localStorageDir: storage.localStorageDir,
18652
+ filenameSuffix: storage.filenameSuffix,
18653
+ });
18654
+ if (converted) {
18655
+ result.converted++;
18656
+ logger$4(`wrote ${row.propertyName} of ${row.seedLocalId} to ${converted.filePath}`);
18657
+ }
18658
+ else {
18659
+ result.skipped++;
18660
+ }
18661
+ }
18662
+ catch (error) {
18663
+ result.failed++;
18664
+ logger$4(`converting ${row.propertyName} of ${row.seedLocalId} (${row.localId}) failed; left as is`, error);
18665
+ }
18666
+ }
18667
+ const attempts = previousAttempts + 1;
18668
+ await writeMarker({
18669
+ status: result.failed > 0 && attempts < LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS ? 'retry' : 'done',
18670
+ attempts,
18671
+ converted: result.converted,
18672
+ failed: result.failed,
18673
+ at: Date.now(),
18674
+ });
18675
+ if (result.candidates > 0) {
18676
+ logger$4(`legacy ItemStorage rows: ${result.converted} converted, ${result.failed} failed, ` +
18677
+ `${result.skipped} skipped of ${result.candidates}`);
18678
+ }
18679
+ return result;
18680
+ }
18681
+ let running;
18682
+ let deferredUntilLeader = false;
18683
+ const runInBackground = () => {
18684
+ running ?? (running = withDbTabLock('item-storage-migration', () => migrateLegacyItemStorageRows())
18685
+ .then(() => undefined)
18686
+ .catch((error) => {
18687
+ // Never fails init: rows stay as they were and publish converts them lazily.
18688
+ logger$4('legacy ItemStorage migration failed', error);
18689
+ })
18690
+ .finally(() => {
18691
+ running = undefined;
18692
+ }));
18693
+ return running;
18694
+ };
18695
+ /**
18696
+ * Starts {@link migrateLegacyItemStorageRows} in the background once client init has finished
18697
+ * (the properties table then holds the current storage settings). It runs in the leader tab only
18698
+ * (docs/MULTI_TAB.md), under a `seed:item-storage-migration:<db>` lock in case several tabs lead
18699
+ * (`multiTab: 'off'`); a tab that isn't leader runs it if it takes over. Never throws.
18700
+ */
18701
+ function startLegacyItemStorageMigration() {
18702
+ if (isLeaderTab()) {
18703
+ void runInBackground();
18704
+ return;
18705
+ }
18706
+ if (deferredUntilLeader)
18707
+ return;
18708
+ deferredUntilLeader = true;
18709
+ void whenLeaderTab().then(() => {
18710
+ deferredUntilLeader = false;
18711
+ void runInBackground();
18712
+ });
18713
+ }
18714
+
18098
18715
  const { UNINITIALIZED, PLATFORM_CLASSES_INIT, FILE_SYSTEM_INIT, DB_INIT, SAVE_CONFIG, PROCESS_SCHEMA_FILES, ADD_MODELS_TO_STORE, ADD_MODELS_TO_DB, IDLE, INIT_FAILED, } = exports.ClientManagerState;
18099
18716
  const { UPDATE_CONTEXT, PLATFORM_CLASSES_READY, FILE_SYSTEM_READY, DB_READY, SAVE_CONFIG_SUCCESS, SAVE_APP_STATE_SUCCESS, SAVE_APP_STATE_ERROR, SET_ADDRESSES, ADD_MODELS_TO_STORE_SUCCESS, ADD_MODELS_TO_DB_SUCCESS, PROCESS_SCHEMA_FILES_SUCCESS, } = ClientManagerEvents;
18100
18717
  const logSyncAfterAddressSave = debug("seedSdk:client:clientManagerMachine:syncAfterAddressSave");
@@ -18315,9 +18932,15 @@ const clientManagerMachine = xstate.setup({
18315
18932
  },
18316
18933
  },
18317
18934
  [IDLE]: {
18318
- entry: xstate.assign({
18319
- isInitialized: true,
18320
- }),
18935
+ entry: [
18936
+ xstate.assign({
18937
+ isInitialized: true,
18938
+ }),
18939
+ // One-time data migration that writes files, so it can't be a SQL migration in prepareDb.
18940
+ // In the background after init: the app is usable at once, the properties table holds the
18941
+ // current storage settings by now, and a failure never fails init.
18942
+ () => startLegacyItemStorageMigration(),
18943
+ ],
18321
18944
  on: {
18322
18945
  [SAVE_APP_STATE_SUCCESS]: {
18323
18946
  actions: [
@@ -19391,7 +20014,7 @@ const saveDraftLogger = debug('seedSdk:model:saveDraftToDb');
19391
20014
  // Lazy import cache for ModelProperty to avoid circular dependency
19392
20015
  // Eagerly start loading to minimize delay on first access
19393
20016
  let ModelPropertyClass = null;
19394
- const modelPropertyImportPromise = Promise.resolve().then(function () { return require('./ModelProperty-B-cZm1yU.js'); })
20017
+ const modelPropertyImportPromise = Promise.resolve().then(function () { return require('./ModelProperty-DXZ39Wyv.js'); })
19395
20018
  .then(module => {
19396
20019
  ModelPropertyClass = module.ModelProperty;
19397
20020
  return ModelPropertyClass;
@@ -19407,7 +20030,7 @@ function getModelProperty() {
19407
20030
  return ModelPropertyClass;
19408
20031
  }
19409
20032
  // Lazy import for Schema to avoid circular dependency
19410
- const schemaImportPromise = Promise.resolve().then(function () { return require('./Schema-STP972Xw.js'); })
20033
+ const schemaImportPromise = Promise.resolve().then(function () { return require('./Schema-DdP109QD.js'); })
19411
20034
  .then(module => module.Schema)
19412
20035
  .catch(() => null);
19413
20036
  // WeakMap to store mutable state per Model instance
@@ -21472,7 +22095,7 @@ function resolveSdkDrizzleMigrationsDir(sdkRootDir) {
21472
22095
  })();
21473
22096
  // Also resolve relative to this module so temp-cwd tests / odd roots still find
21474
22097
  // packages/sdk/src/db/drizzle (or dist/db/drizzle after publish).
21475
- const moduleDir = path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cjs/index-usKaANAq.js', document.baseURI).href))));
22098
+ const moduleDir = path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cjs/index-C4XlgCJ4.js', document.baseURI).href))));
21476
22099
  const candidates = [
21477
22100
  path.join(root, 'db', 'drizzle'), // production: sdkRoot is dist/
21478
22101
  path.join(root, 'dist', 'db', 'drizzle'), // sdk package root with built dist
@@ -21542,10 +22165,10 @@ class NodeDb {
21542
22165
  logger$1('[Db.prepareDb] running migrations from %s', outDir);
21543
22166
  await migrator.migrate(db, { migrationsFolder: outDir });
21544
22167
  this.db = db;
21545
- const { backfillMetadataPropertyIds } = await Promise.resolve().then(function () { return require('./backfillMetadataPropertyIds-CP3y1skt.js'); });
22168
+ const { backfillMetadataPropertyIds } = await Promise.resolve().then(function () { return require('./backfillMetadataPropertyIds-CPYoaMl4.js'); });
21546
22169
  await backfillMetadataPropertyIds();
21547
22170
  // One-time: clear item data whose model can't be determined (seeds.model_file_id, migration 0015)
21548
- const { resetAmbiguousLegacyItemData } = await Promise.resolve().then(function () { return require('./resetAmbiguousLegacyItemData-8nfkj9rz.js'); });
22171
+ const { resetAmbiguousLegacyItemData } = await Promise.resolve().then(function () { return require('./resetAmbiguousLegacyItemData-Bu_MBBYt.js'); });
21549
22172
  await resetAmbiguousLegacyItemData();
21550
22173
  return this.db;
21551
22174
  }
@@ -22076,10 +22699,13 @@ exports.anyEvictionSince = anyEvictionSince;
22076
22699
  exports.appState = appState;
22077
22700
  exports.arweaveL1FinalizeJobs = arweaveL1FinalizeJobs;
22078
22701
  exports.assertLocalDbChain = assertLocalDbChain;
22702
+ exports.buildArweaveContentTags = buildArweaveContentTags;
22079
22703
  exports.chunkValues = chunkValues;
22080
22704
  exports.clearDestroySubscriptions = clearDestroySubscriptions;
22081
22705
  exports.commandExists = commandExists;
22706
+ exports.compareMetadataRowsLatestFirst = compareMetadataRowsLatestFirst;
22082
22707
  exports.config = config;
22708
+ exports.convertVerbatimItemStorageRow = convertVerbatimItemStorageRow;
22083
22709
  exports.createModelsFromJson = createModelsFromJson;
22084
22710
  exports.createReactiveProxy = createReactiveProxy;
22085
22711
  exports.currentEvictionEpoch = currentEvictionEpoch;
@@ -22095,13 +22721,15 @@ exports.forceRemoveFromCaches = forceRemoveFromCaches;
22095
22721
  exports.generateId = generateId;
22096
22722
  exports.getAllAddressesFromDb = getAllAddressesFromDb;
22097
22723
  exports.getClient = getClient;
22098
- exports.getContentHash = getContentHash;
22724
+ exports.getContentSha256 = getContentSha256;
22099
22725
  exports.getCorrectId = getCorrectId;
22100
22726
  exports.getEasSchemaUidForModel = getEasSchemaUidForModel;
22101
22727
  exports.getGetAdditionalSyncAddresses = getGetAdditionalSyncAddresses;
22102
22728
  exports.getItemData = getItemData;
22103
22729
  exports.getItemModelScope = getItemModelScope;
22730
+ exports.getItemStorageLocalFileName = getItemStorageLocalFileName;
22104
22731
  exports.getItemStoragePropertiesForModel = getItemStoragePropertiesForModel;
22732
+ exports.getItemStorageSubdir = getItemStorageSubdir;
22105
22733
  exports.getLatestPublishedVersionRow = getLatestPublishedVersionRow;
22106
22734
  exports.getLatestSchemaVersion = getLatestSchemaVersion;
22107
22735
  exports.getModelId = getModelId;
@@ -22109,6 +22737,7 @@ exports.getModelIdByFileId = getModelIdByFileId;
22109
22737
  exports.getPropertyData = getPropertyData$1;
22110
22738
  exports.getPropertyIdForModelAndName = getPropertyIdForModelAndName;
22111
22739
  exports.getRefValueType = getRefValueType;
22740
+ exports.getStorageDirForDataType = getStorageDirForDataType;
22112
22741
  exports.htmlEmbeddedImageCoPublish = htmlEmbeddedImageCoPublish;
22113
22742
  exports.importJsonSchema = importJsonSchema;
22114
22743
  exports.isActorStopped = isActorStopped;
@@ -22116,6 +22745,7 @@ exports.isDataType = isDataType;
22116
22745
  exports.isInternalSchema = isInternalSchema;
22117
22746
  exports.isPublishedSeedRef = isPublishedSeedRef;
22118
22747
  exports.isStorageSeedRef = isStorageSeedRef;
22748
+ exports.isVerbatimItemStorageDraftRow = isVerbatimItemStorageDraftRow;
22119
22749
  exports.isVersionRevoked = isVersionRevoked;
22120
22750
  exports.listCompleteSchemaFiles = listCompleteSchemaFiles;
22121
22751
  exports.listRelationEasPropertyName = listRelationEasPropertyName;
@@ -22168,4 +22798,4 @@ exports.withSeed = withSeed;
22168
22798
  exports.writeInBatches = writeInBatches;
22169
22799
  exports.writeProcessMachine = writeProcessMachine;
22170
22800
  exports.writeToDatabase = writeToDatabase$1;
22171
- //# sourceMappingURL=index-usKaANAq.js.map
22801
+ //# sourceMappingURL=index-C4XlgCJ4.js.map