@seedprotocol/sdk 0.7.8 → 0.7.9-next.1177.ga3e08ed

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 (419) hide show
  1. package/README.md +1 -1
  2. package/dist/{ClientManager-B1r_8P5Z.js → ClientManager-GZfXErDX.js} +187 -1451
  3. package/dist/ClientManager-GZfXErDX.js.map +1 -0
  4. package/dist/{Item-CjTEShfk.js → Item-0oDoTPhi.js} +175 -238
  5. package/dist/Item-0oDoTPhi.js.map +1 -0
  6. package/dist/{ModelProperty-C3749Wjq.js → ModelProperty-i5flwzQG.js} +41 -40
  7. package/dist/ModelProperty-i5flwzQG.js.map +1 -0
  8. package/dist/{Schema-CX9CTtho.js → Schema-PFZwG9Nl.js} +88 -1623
  9. package/dist/Schema-PFZwG9Nl.js.map +1 -0
  10. package/dist/{SchemaValidationService-T5mqnY8q.js → SchemaValidationService-DnGKel4V.js} +7 -6
  11. package/dist/{SchemaValidationService-T5mqnY8q.js.map → SchemaValidationService-DnGKel4V.js.map} +1 -1
  12. package/dist/{backfillMetadataPropertyIds-DWWkh-Ex.js → backfillMetadataPropertyIds-BbxgavEQ.js} +4 -4
  13. package/dist/{backfillMetadataPropertyIds-DWWkh-Ex.js.map → backfillMetadataPropertyIds-BbxgavEQ.js.map} +1 -1
  14. package/dist/{changeFeed-DcsZ7deG.js → changeFeed-DKdVlUmt.js} +8 -7
  15. package/dist/changeFeed-DKdVlUmt.js.map +1 -0
  16. package/dist/configurePlatform-CrMafpMW.js +29 -0
  17. package/dist/configurePlatform-CrMafpMW.js.map +1 -0
  18. package/dist/db/drizzle/0024_merge_republished_ghost_seeds.sql +29 -0
  19. package/dist/db/drizzle/meta/0024_snapshot.json +1645 -0
  20. package/dist/db/drizzle/meta/_journal.json +7 -0
  21. package/dist/{detachRowsBeforeDelete-Bo_pky-R.js → detachRowsBeforeDelete-DXFYSHRR.js} +2 -3
  22. package/dist/{detachRowsBeforeDelete-Bo_pky-R.js.map → detachRowsBeforeDelete-DXFYSHRR.js.map} +1 -1
  23. package/dist/dist/{ClientManager-B1r_8P5Z.d.ts → ClientManager-GZfXErDX.d.ts} +323 -406
  24. package/dist/dist/ClientManager-GZfXErDX.d.ts.map +1 -0
  25. package/dist/dist/{Item-CjTEShfk.d.ts → Item-0oDoTPhi.d.ts} +85 -91
  26. package/dist/dist/Item-0oDoTPhi.d.ts.map +1 -0
  27. package/dist/dist/{ModelProperty-C3749Wjq.d.ts → ModelProperty-i5flwzQG.d.ts} +1 -1
  28. package/dist/dist/{ModelProperty-C3749Wjq.d.ts.map → ModelProperty-i5flwzQG.d.ts.map} +1 -1
  29. package/dist/dist/{Schema-CX9CTtho.d.ts → Schema-PFZwG9Nl.d.ts} +7 -183
  30. package/dist/dist/Schema-PFZwG9Nl.d.ts.map +1 -0
  31. package/dist/dist/{SchemaValidationService-T5mqnY8q.d.ts → SchemaValidationService-DnGKel4V.d.ts} +1 -1
  32. package/dist/dist/{SchemaValidationService-T5mqnY8q.d.ts.map → SchemaValidationService-DnGKel4V.d.ts.map} +1 -1
  33. package/dist/dist/{backfillMetadataPropertyIds-DWWkh-Ex.d.ts → backfillMetadataPropertyIds-BbxgavEQ.d.ts} +1 -1
  34. package/dist/dist/backfillMetadataPropertyIds-BbxgavEQ.d.ts.map +1 -0
  35. package/dist/dist/{changeFeed-DcsZ7deG.d.ts → changeFeed-DKdVlUmt.d.ts} +17 -20
  36. package/dist/dist/changeFeed-DKdVlUmt.d.ts.map +1 -0
  37. package/dist/dist/configurePlatform-CrMafpMW.d.ts +5 -0
  38. package/dist/dist/configurePlatform-CrMafpMW.d.ts.map +1 -0
  39. package/dist/dist/{detachRowsBeforeDelete-Bo_pky-R.d.ts → detachRowsBeforeDelete-DXFYSHRR.d.ts} +1 -1
  40. package/dist/dist/detachRowsBeforeDelete-DXFYSHRR.d.ts.map +1 -0
  41. package/dist/dist/{eas--9vtNkma.d.ts → eas-dyepi5jz.d.ts} +1 -1
  42. package/dist/dist/eas-dyepi5jz.d.ts.map +1 -0
  43. package/dist/dist/{errors-Do7v6RKu.d.ts → errors-C1qUEZ7A.d.ts} +5 -2
  44. package/dist/dist/errors-C1qUEZ7A.d.ts.map +1 -0
  45. package/dist/dist/{errors-rIWK7gwJ.d.ts → errors-D1zHAqjr.d.ts} +1 -1
  46. package/dist/dist/{errors-rIWK7gwJ.d.ts.map → errors-D1zHAqjr.d.ts.map} +1 -1
  47. package/dist/dist/eventBus-7vxTCc3a.d.ts +18 -0
  48. package/dist/dist/eventBus-7vxTCc3a.d.ts.map +1 -0
  49. package/dist/dist/findSeedRowsByUid-CT3sOXXw.d.ts +13 -0
  50. package/dist/dist/findSeedRowsByUid-CT3sOXXw.d.ts.map +1 -0
  51. package/dist/dist/{getItem-5j22EWWE.d.ts → getItem-Bhjecbia.d.ts} +1 -1
  52. package/dist/dist/getItem-Bhjecbia.d.ts.map +1 -0
  53. package/dist/dist/{getPublishPayload-BGl2SaGK.d.ts → getPublishPayload-DH4rMqXG.d.ts} +1 -1
  54. package/dist/dist/getPublishPayload-DH4rMqXG.d.ts.map +1 -0
  55. package/dist/dist/{getPublishUploads-DVsDx6Xf.d.ts → getPublishUploads-BzUIDA2G.d.ts} +5 -5
  56. package/dist/dist/getPublishUploads-BzUIDA2G.d.ts.map +1 -0
  57. package/dist/dist/index-CkYb3wcU.d.ts +14 -0
  58. package/dist/dist/index-CkYb3wcU.d.ts.map +1 -0
  59. package/dist/dist/{index-Dp4uyZYx.d.ts → index-DJmWkVIK.d.ts} +5 -5
  60. package/dist/dist/index-DJmWkVIK.d.ts.map +1 -0
  61. package/dist/dist/{index-C0SetTd1.d.ts → index-Dx_GTdyQ.d.ts} +1457 -1513
  62. package/dist/dist/index-Dx_GTdyQ.d.ts.map +1 -0
  63. package/dist/dist/{index-CZQrNqvq.d.ts → index-PbnKw2es.d.ts} +1 -1
  64. package/dist/dist/{index-CZQrNqvq.d.ts.map → index-PbnKw2es.d.ts.map} +1 -1
  65. package/dist/dist/{index.browser-Ll71Y_Dl.d.ts → index.browser-i9uPJice.d.ts} +13 -40
  66. package/dist/dist/{index.browser-Ll71Y_Dl.d.ts.map → index.browser-i9uPJice.d.ts.map} +1 -1
  67. package/dist/dist/{index.node-CgltN0cC.d.ts → index.node-CzMwMr_d.d.ts} +2 -45
  68. package/dist/dist/{index.node-CgltN0cC.d.ts.map → index.node-CzMwMr_d.d.ts.map} +1 -1
  69. package/dist/dist/minimumUpgradeVersion-BDhHvHtr.d.ts +9 -0
  70. package/dist/dist/minimumUpgradeVersion-BDhHvHtr.d.ts.map +1 -0
  71. package/dist/dist/{modelPropertyRecordSchemas-C_lYTzMr.d.ts → modelPropertyRecordSchemas-C5lW9aA-.d.ts} +1 -1
  72. package/dist/dist/modelPropertyRecordSchemas-C5lW9aA-.d.ts.map +1 -0
  73. package/dist/dist/platform.browser.d.ts +2 -2
  74. package/dist/dist/platform.node.d.ts +2 -2
  75. package/dist/dist/{property-pcDxNEpy.d.ts → property-BwYtg5Q_.d.ts} +3 -3
  76. package/dist/dist/property-BwYtg5Q_.d.ts.map +1 -0
  77. package/dist/dist/{propertyValidationRules-BEjN0f3-.d.ts → propertyValidationRules-CyHdpcPP.d.ts} +1 -1
  78. package/dist/dist/propertyValidationRules-CyHdpcPP.d.ts.map +1 -0
  79. package/dist/dist/{publishDraftGraph-I5yKe1Xz.d.ts → publishDraftGraph-C5F6b7GK.d.ts} +23 -6
  80. package/dist/dist/publishDraftGraph-C5F6b7GK.d.ts.map +1 -0
  81. package/dist/dist/{resolveModelForSyncedSeed-C5KXn6ex.d.ts → resolveModelForSyncedSeed-4gO9Hfn2.d.ts} +1 -1
  82. package/dist/dist/resolveModelForSyncedSeed-4gO9Hfn2.d.ts.map +1 -0
  83. package/dist/dist/syncDbWithEas-DUu_wjUG.d.ts +13 -0
  84. package/dist/dist/syncDbWithEas-DUu_wjUG.d.ts.map +1 -0
  85. package/dist/dist/{tolerantWebAccess-CIpS7RLk.d.ts → tolerantWebAccess-DecKDGen.d.ts} +1 -1
  86. package/dist/dist/{tolerantWebAccess-CIpS7RLk.d.ts.map → tolerantWebAccess-DecKDGen.d.ts.map} +1 -1
  87. package/dist/dist/{updateSeedRevokedAt-CR4zwn-6.d.ts → updateSeedRevokedAt-CP606vKs.d.ts} +1 -1
  88. package/dist/dist/updateSeedRevokedAt-CP606vKs.d.ts.map +1 -0
  89. package/dist/{eas--9vtNkma.js → eas-dyepi5jz.js} +3 -4
  90. package/dist/eas-dyepi5jz.js.map +1 -0
  91. package/dist/{errors-Do7v6RKu.js → errors-C1qUEZ7A.js} +12 -6
  92. package/dist/errors-C1qUEZ7A.js.map +1 -0
  93. package/dist/{errors-rIWK7gwJ.js → errors-D1zHAqjr.js} +46 -98
  94. package/dist/errors-D1zHAqjr.js.map +1 -0
  95. package/dist/eventBus-7vxTCc3a.js +64 -0
  96. package/dist/eventBus-7vxTCc3a.js.map +1 -0
  97. package/dist/findSeedRowsByUid-CT3sOXXw.js +47 -0
  98. package/dist/findSeedRowsByUid-CT3sOXXw.js.map +1 -0
  99. package/dist/{getItem-5j22EWWE.js → getItem-Bhjecbia.js} +5 -5
  100. package/dist/{getItem-5j22EWWE.js.map → getItem-Bhjecbia.js.map} +1 -1
  101. package/dist/{getPublishPayload-BGl2SaGK.js → getPublishPayload-DH4rMqXG.js} +27 -27
  102. package/dist/getPublishPayload-DH4rMqXG.js.map +1 -0
  103. package/dist/{getPublishUploads-DVsDx6Xf.js → getPublishUploads-BzUIDA2G.js} +64 -95
  104. package/dist/getPublishUploads-BzUIDA2G.js.map +1 -0
  105. package/dist/{index-CJK3F_MK.js → index-CkYb3wcU.js} +9 -8
  106. package/dist/index-CkYb3wcU.js.map +1 -0
  107. package/dist/{index-Dp4uyZYx.js → index-DJmWkVIK.js} +9 -8
  108. package/dist/index-DJmWkVIK.js.map +1 -0
  109. package/dist/{index-C0SetTd1.js → index-Dx_GTdyQ.js} +27 -463
  110. package/dist/index-Dx_GTdyQ.js.map +1 -0
  111. package/dist/{index-CZQrNqvq.js → index-PbnKw2es.js} +2 -2
  112. package/dist/index-PbnKw2es.js.map +1 -0
  113. package/dist/{index.browser-Ll71Y_Dl.js → index.browser-i9uPJice.js} +239 -179
  114. package/dist/index.browser-i9uPJice.js.map +1 -0
  115. package/dist/{index.node-CgltN0cC.js → index.node-CzMwMr_d.js} +51 -216
  116. package/dist/index.node-CzMwMr_d.js.map +1 -0
  117. package/dist/main.js +165 -241
  118. package/dist/main.js.map +1 -1
  119. package/dist/minimumUpgradeVersion-BDhHvHtr.js +81 -0
  120. package/dist/minimumUpgradeVersion-BDhHvHtr.js.map +1 -0
  121. package/dist/{modelPropertyRecordSchemas-C_lYTzMr.js → modelPropertyRecordSchemas-C5lW9aA-.js} +5 -5
  122. package/dist/{modelPropertyRecordSchemas-C_lYTzMr.js.map → modelPropertyRecordSchemas-C5lW9aA-.js.map} +1 -1
  123. package/dist/node.js +14 -221
  124. package/dist/node.js.map +1 -1
  125. package/dist/platform.browser.js +8 -7
  126. package/dist/platform.browser.js.map +1 -1
  127. package/dist/platform.node.js +7 -7
  128. package/dist/{property-pcDxNEpy.js → property-BwYtg5Q_.js} +8 -9
  129. package/dist/property-BwYtg5Q_.js.map +1 -0
  130. package/dist/{propertyValidationRules-BEjN0f3-.js → propertyValidationRules-CyHdpcPP.js} +10 -10
  131. package/dist/{propertyValidationRules-BEjN0f3-.js.map → propertyValidationRules-CyHdpcPP.js.map} +1 -1
  132. package/dist/{publishDraftGraph-I5yKe1Xz.js → publishDraftGraph-C5F6b7GK.js} +104 -35
  133. package/dist/publishDraftGraph-C5F6b7GK.js.map +1 -0
  134. package/dist/{resolveModelForSyncedSeed-C5KXn6ex.js → resolveModelForSyncedSeed-4gO9Hfn2.js} +3 -2
  135. package/dist/{resolveModelForSyncedSeed-C5KXn6ex.js.map → resolveModelForSyncedSeed-4gO9Hfn2.js.map} +1 -1
  136. package/dist/seedSchema/PendingWriteSchema.ts +3 -2
  137. package/dist/src/Item/Item.d.ts +1 -0
  138. package/dist/src/Item/Item.d.ts.map +1 -1
  139. package/dist/src/Item/service/actors/runPublish.d.ts.map +1 -1
  140. package/dist/src/ItemProperty/ItemProperty.d.ts +2 -2
  141. package/dist/src/ItemProperty/ItemProperty.d.ts.map +1 -1
  142. package/dist/src/ItemProperty/service/propertyMachine.d.ts +1 -1
  143. package/dist/src/ItemProperty/service/propertyMachine.d.ts.map +1 -1
  144. package/dist/src/Model/Model.d.ts.map +1 -1
  145. package/dist/src/Model/service/modelMachine.d.ts +0 -20
  146. package/dist/src/Model/service/modelMachine.d.ts.map +1 -1
  147. package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts +0 -20
  148. package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts.map +1 -1
  149. package/dist/src/Schema/service/schemaMachine.d.ts +1 -107
  150. package/dist/src/Schema/service/schemaMachine.d.ts.map +1 -1
  151. package/dist/src/Schema/validation.d.ts +0 -1
  152. package/dist/src/Schema/validation.d.ts.map +1 -1
  153. package/dist/src/browser/db/Db.d.ts +8 -3
  154. package/dist/src/browser/db/Db.d.ts.map +1 -1
  155. package/dist/src/browser/db/createSqlocalDrizzle.d.ts +20 -2
  156. package/dist/src/browser/db/createSqlocalDrizzle.d.ts.map +1 -1
  157. package/dist/src/browser/db/drizzleFiles.d.ts +3 -2
  158. package/dist/src/browser/db/drizzleFiles.d.ts.map +1 -1
  159. package/dist/src/browser/workers/FileDownloader.d.ts +1 -1
  160. package/dist/src/browser/workers/FileDownloader.d.ts.map +1 -1
  161. package/dist/src/browser/workers/filesDownload.d.ts.map +1 -1
  162. package/dist/src/client/actors/fileSystemInit.d.ts.map +1 -1
  163. package/dist/src/client/actors/platformClassesInit.d.ts +1 -1
  164. package/dist/src/client/actors/platformClassesInit.d.ts.map +1 -1
  165. package/dist/src/client/actors/processSchemaFiles.d.ts.map +1 -1
  166. package/dist/src/client/clientManagerMachine.d.ts.map +1 -1
  167. package/dist/src/client/constants.d.ts +0 -51
  168. package/dist/src/client/constants.d.ts.map +1 -1
  169. package/dist/src/db/minimumUpgradeVersion.d.ts +33 -0
  170. package/dist/src/db/minimumUpgradeVersion.d.ts.map +1 -0
  171. package/dist/src/db/read/batchLatestPublishedVersionBySeedLocalIds.d.ts +2 -1
  172. package/dist/src/db/read/batchLatestPublishedVersionBySeedLocalIds.d.ts.map +1 -1
  173. package/dist/src/db/read/findSeedRowsByUid.d.ts +13 -0
  174. package/dist/src/db/read/findSeedRowsByUid.d.ts.map +1 -0
  175. package/dist/src/db/read/getItemData.d.ts.map +1 -1
  176. package/dist/src/db/read/getLatestPublishedVersionRow.d.ts +2 -1
  177. package/dist/src/db/read/getLatestPublishedVersionRow.d.ts.map +1 -1
  178. package/dist/src/db/read/getLatestVersionRow.d.ts +1 -1
  179. package/dist/src/db/read/getLatestVersionRow.d.ts.map +1 -1
  180. package/dist/src/db/read/getPublishPayload.d.ts +4 -0
  181. package/dist/src/db/read/getPublishPayload.d.ts.map +1 -1
  182. package/dist/src/db/read/getPublishUploads.d.ts +1 -3
  183. package/dist/src/db/read/getPublishUploads.d.ts.map +1 -1
  184. package/dist/src/db/read/getRelatedItemsForPublish.d.ts +2 -0
  185. package/dist/src/db/read/getRelatedItemsForPublish.d.ts.map +1 -1
  186. package/dist/src/db/read/itemLoads.d.ts +20 -0
  187. package/dist/src/db/read/itemLoads.d.ts.map +1 -0
  188. package/dist/src/db/read/publishDraftGraph.d.ts +7 -0
  189. package/dist/src/db/read/publishDraftGraph.d.ts.map +1 -1
  190. package/dist/src/db/read/resolveRelatedSeedRef.d.ts +4 -4
  191. package/dist/src/db/read/resolveRelatedSeedRef.d.ts.map +1 -1
  192. package/dist/src/db/read/subqueries/latestVersion.d.ts +14 -0
  193. package/dist/src/db/read/subqueries/latestVersion.d.ts.map +1 -0
  194. package/dist/src/db/read/subqueries/versionData.d.ts +2 -2
  195. package/dist/src/db/read/subqueries/versionData.d.ts.map +1 -1
  196. package/dist/src/db/read/summarizePublishWork.d.ts.map +1 -1
  197. package/dist/src/db/write/applyPropertyAttestationUidsFromPublish.d.ts +6 -0
  198. package/dist/src/db/write/applyPropertyAttestationUidsFromPublish.d.ts.map +1 -1
  199. package/dist/src/db/write/easSyncProcess.d.ts +1 -1
  200. package/dist/src/db/write/easSyncProcess.d.ts.map +1 -1
  201. package/dist/src/db/write/updateVersionUid.d.ts +2 -2
  202. package/dist/src/db/write/updateVersionUid.d.ts.map +1 -1
  203. package/dist/src/events/files/download.d.ts +1 -10
  204. package/dist/src/events/files/download.d.ts.map +1 -1
  205. package/dist/src/events/item/easSyncManager.d.ts +0 -1
  206. package/dist/src/events/item/easSyncManager.d.ts.map +1 -1
  207. package/dist/src/events/item/index.d.ts.map +1 -1
  208. package/dist/src/events/item/syncDbWithEas.d.ts +0 -10
  209. package/dist/src/events/item/syncDbWithEas.d.ts.map +1 -1
  210. package/dist/src/helpers/FileManager/BaseFileManager.d.ts +1 -1
  211. package/dist/src/helpers/FileManager/BaseFileManager.d.ts.map +1 -1
  212. package/dist/src/helpers/FileManager/IFileManager.d.ts +7 -0
  213. package/dist/src/helpers/FileManager/IFileManager.d.ts.map +1 -1
  214. package/dist/src/helpers/FileManager/errors.d.ts +4 -1
  215. package/dist/src/helpers/FileManager/errors.d.ts.map +1 -1
  216. package/dist/src/helpers/arweaveContentTags.d.ts +1 -2
  217. package/dist/src/helpers/arweaveContentTags.d.ts.map +1 -1
  218. package/dist/src/helpers/constants.d.ts +3 -12
  219. package/dist/src/helpers/constants.d.ts.map +1 -1
  220. package/dist/src/helpers/db.d.ts +3 -28
  221. package/dist/src/helpers/db.d.ts.map +1 -1
  222. package/dist/src/helpers/ethereumUtils.d.ts +0 -2
  223. package/dist/src/helpers/ethereumUtils.d.ts.map +1 -1
  224. package/dist/src/helpers/htmlEmbeddedDataUriPublish.d.ts +2 -1
  225. package/dist/src/helpers/htmlEmbeddedDataUriPublish.d.ts.map +1 -1
  226. package/dist/src/helpers/index.d.ts +0 -7
  227. package/dist/src/helpers/index.d.ts.map +1 -1
  228. package/dist/src/helpers/itemStorageFile.d.ts +2 -2
  229. package/dist/src/helpers/reconcilePropertyDraftRows.d.ts +2 -1
  230. package/dist/src/helpers/reconcilePropertyDraftRows.d.ts.map +1 -1
  231. package/dist/src/helpers/schema.d.ts +0 -73
  232. package/dist/src/helpers/schema.d.ts.map +1 -1
  233. package/dist/src/helpers/updateSchema.d.ts +0 -46
  234. package/dist/src/helpers/updateSchema.d.ts.map +1 -1
  235. package/dist/src/imports/index.d.ts +0 -1
  236. package/dist/src/imports/index.d.ts.map +1 -1
  237. package/dist/src/imports/json.d.ts +2 -1
  238. package/dist/src/imports/json.d.ts.map +1 -1
  239. package/dist/src/index.d.ts +4 -6
  240. package/dist/src/index.d.ts.map +1 -1
  241. package/dist/src/node/db/Db.d.ts.map +1 -1
  242. package/dist/src/node/helpers/dotSeedDir.d.ts +7 -0
  243. package/dist/src/node/helpers/dotSeedDir.d.ts.map +1 -0
  244. package/dist/src/node/index.d.ts +0 -5
  245. package/dist/src/node/index.d.ts.map +1 -1
  246. package/dist/src/outbox/index.d.ts +1 -1
  247. package/dist/src/outbox/index.d.ts.map +1 -1
  248. package/dist/src/outbox/itemAppliers.d.ts.map +1 -1
  249. package/dist/src/outbox/outbox.d.ts +3 -19
  250. package/dist/src/outbox/outbox.d.ts.map +1 -1
  251. package/dist/src/platform/configurePlatform.d.ts.map +1 -1
  252. package/dist/src/platform/index.browser.d.ts.map +1 -1
  253. package/dist/src/platform/index.node.d.ts.map +1 -1
  254. package/dist/src/platform/types.d.ts +0 -2
  255. package/dist/src/platform/types.d.ts.map +1 -1
  256. package/dist/src/query/createLocalQueryDataSource.d.ts.map +1 -1
  257. package/dist/src/seedSchema/PendingWriteSchema.d.ts.map +1 -1
  258. package/dist/src/services/write/actors/validateEntity.d.ts +1 -1
  259. package/dist/src/services/write/actors/validateEntity.d.ts.map +1 -1
  260. package/dist/src/services/write/actors/writeToDatabase.d.ts.map +1 -1
  261. package/dist/src/services/write/writeProcessMachine.d.ts +1 -23
  262. package/dist/src/services/write/writeProcessMachine.d.ts.map +1 -1
  263. package/dist/src/stores/eas.d.ts +0 -1
  264. package/dist/src/stores/eas.d.ts.map +1 -1
  265. package/dist/src/types/index.d.ts +1 -18
  266. package/dist/src/types/index.d.ts.map +1 -1
  267. package/dist/src/types/machines.d.ts +1 -32
  268. package/dist/src/types/machines.d.ts.map +1 -1
  269. package/dist/{syncDbWithEas-b4fESZ7C.js → syncDbWithEas-DUu_wjUG.js} +37 -105
  270. package/dist/syncDbWithEas-DUu_wjUG.js.map +1 -0
  271. package/dist/{tolerantWebAccess-CIpS7RLk.js → tolerantWebAccess-DecKDGen.js} +9 -8
  272. package/dist/{tolerantWebAccess-CIpS7RLk.js.map → tolerantWebAccess-DecKDGen.js.map} +1 -1
  273. package/dist/{updateSeedRevokedAt-CR4zwn-6.js → updateSeedRevokedAt-CP606vKs.js} +3 -3
  274. package/dist/{updateSeedRevokedAt-CR4zwn-6.js.map → updateSeedRevokedAt-CP606vKs.js.map} +1 -1
  275. package/package.json +6 -8
  276. package/dist/ClientManager-B1r_8P5Z.js.map +0 -1
  277. package/dist/Item-CjTEShfk.js.map +0 -1
  278. package/dist/ModelProperty-C3749Wjq.js.map +0 -1
  279. package/dist/Schema-CX9CTtho.js.map +0 -1
  280. package/dist/changeFeed-DcsZ7deG.js.map +0 -1
  281. package/dist/configurePlatform-AWild9o4.js +0 -81
  282. package/dist/configurePlatform-AWild9o4.js.map +0 -1
  283. package/dist/dist/ClientManager-B1r_8P5Z.d.ts.map +0 -1
  284. package/dist/dist/Item-CjTEShfk.d.ts.map +0 -1
  285. package/dist/dist/Schema-CX9CTtho.d.ts.map +0 -1
  286. package/dist/dist/backfillMetadataPropertyIds-DWWkh-Ex.d.ts.map +0 -1
  287. package/dist/dist/changeFeed-DcsZ7deG.d.ts.map +0 -1
  288. package/dist/dist/configurePlatform-AWild9o4.d.ts +0 -30
  289. package/dist/dist/configurePlatform-AWild9o4.d.ts.map +0 -1
  290. package/dist/dist/detachRowsBeforeDelete-Bo_pky-R.d.ts.map +0 -1
  291. package/dist/dist/eas--9vtNkma.d.ts.map +0 -1
  292. package/dist/dist/errors-Do7v6RKu.d.ts.map +0 -1
  293. package/dist/dist/getItem-5j22EWWE.d.ts.map +0 -1
  294. package/dist/dist/getPublishPayload-BGl2SaGK.d.ts.map +0 -1
  295. package/dist/dist/getPublishUploads-DVsDx6Xf.d.ts.map +0 -1
  296. package/dist/dist/index-C0SetTd1.d.ts.map +0 -1
  297. package/dist/dist/index-CJK3F_MK.d.ts +0 -14
  298. package/dist/dist/index-CJK3F_MK.d.ts.map +0 -1
  299. package/dist/dist/index-Dp4uyZYx.d.ts.map +0 -1
  300. package/dist/dist/modelPropertyRecordSchemas-C_lYTzMr.d.ts.map +0 -1
  301. package/dist/dist/property-pcDxNEpy.d.ts.map +0 -1
  302. package/dist/dist/propertyValidationRules-BEjN0f3-.d.ts.map +0 -1
  303. package/dist/dist/publishDraftGraph-I5yKe1Xz.d.ts.map +0 -1
  304. package/dist/dist/resetAmbiguousLegacyItemData-0Tin9-JK.d.ts +0 -17
  305. package/dist/dist/resetAmbiguousLegacyItemData-0Tin9-JK.d.ts.map +0 -1
  306. package/dist/dist/resolveModelForSyncedSeed-C5KXn6ex.d.ts.map +0 -1
  307. package/dist/dist/syncDbWithEas-b4fESZ7C.d.ts +0 -22
  308. package/dist/dist/syncDbWithEas-b4fESZ7C.d.ts.map +0 -1
  309. package/dist/dist/updateSeedRevokedAt-CR4zwn-6.d.ts.map +0 -1
  310. package/dist/eas--9vtNkma.js.map +0 -1
  311. package/dist/errors-Do7v6RKu.js.map +0 -1
  312. package/dist/errors-rIWK7gwJ.js.map +0 -1
  313. package/dist/getPublishPayload-BGl2SaGK.js.map +0 -1
  314. package/dist/getPublishUploads-DVsDx6Xf.js.map +0 -1
  315. package/dist/index-C0SetTd1.js.map +0 -1
  316. package/dist/index-CJK3F_MK.js.map +0 -1
  317. package/dist/index-CZQrNqvq.js.map +0 -1
  318. package/dist/index-Dp4uyZYx.js.map +0 -1
  319. package/dist/index.browser-Ll71Y_Dl.js.map +0 -1
  320. package/dist/index.node-CgltN0cC.js.map +0 -1
  321. package/dist/property-pcDxNEpy.js.map +0 -1
  322. package/dist/publishDraftGraph-I5yKe1Xz.js.map +0 -1
  323. package/dist/resetAmbiguousLegacyItemData-0Tin9-JK.js +0 -98
  324. package/dist/resetAmbiguousLegacyItemData-0Tin9-JK.js.map +0 -1
  325. package/dist/src/Schema/service/actors/loadOrCreateSchema.d.ts +0 -5
  326. package/dist/src/Schema/service/actors/loadOrCreateSchema.d.ts.map +0 -1
  327. package/dist/src/browser/db/sqlWasmClient.d.ts +0 -1
  328. package/dist/src/browser/db/sqlWasmClient.d.ts.map +0 -1
  329. package/dist/src/browser/helpers/PathResolver.d.ts +0 -41
  330. package/dist/src/browser/helpers/PathResolver.d.ts.map +0 -1
  331. package/dist/src/browser/index.d.ts +0 -3
  332. package/dist/src/browser/index.d.ts.map +0 -1
  333. package/dist/src/browser/seed.d.ts +0 -21
  334. package/dist/src/browser/seed.d.ts.map +0 -1
  335. package/dist/src/browser/workers/content-hash.d.ts +0 -2
  336. package/dist/src/browser/workers/content-hash.d.ts.map +0 -1
  337. package/dist/src/browser/workers/dbWorker.d.ts +0 -1
  338. package/dist/src/browser/workers/dbWorker.d.ts.map +0 -1
  339. package/dist/src/client/BaseClientManager.d.ts +0 -7
  340. package/dist/src/client/BaseClientManager.d.ts.map +0 -1
  341. package/dist/src/client/actions/setAddresses.d.ts +0 -2
  342. package/dist/src/client/actions/setAddresses.d.ts.map +0 -1
  343. package/dist/src/db/alignRowPublishers.d.ts +0 -25
  344. package/dist/src/db/alignRowPublishers.d.ts.map +0 -1
  345. package/dist/src/db/clearStoredDisplayUrls.d.ts +0 -18
  346. package/dist/src/db/clearStoredDisplayUrls.d.ts.map +0 -1
  347. package/dist/src/db/migrateLegacyItemStorageRows.d.ts +0 -57
  348. package/dist/src/db/migrateLegacyItemStorageRows.d.ts.map +0 -1
  349. package/dist/src/db/read/getExistingItem.d.ts +0 -12
  350. package/dist/src/db/read/getExistingItem.d.ts.map +0 -1
  351. package/dist/src/db/read/getModels.d.ts +0 -5
  352. package/dist/src/db/read/getModels.d.ts.map +0 -1
  353. package/dist/src/db/read/getVersionsForVersionUids.d.ts +0 -10
  354. package/dist/src/db/read/getVersionsForVersionUids.d.ts.map +0 -1
  355. package/dist/src/db/removeForeignAttestationRows.d.ts +0 -27
  356. package/dist/src/db/removeForeignAttestationRows.d.ts.map +0 -1
  357. package/dist/src/db/resetAmbiguousLegacyItemData.d.ts +0 -17
  358. package/dist/src/db/resetAmbiguousLegacyItemData.d.ts.map +0 -1
  359. package/dist/src/db/write/applyArweaveL1TransactionIdLocal.d.ts +0 -14
  360. package/dist/src/db/write/applyArweaveL1TransactionIdLocal.d.ts.map +0 -1
  361. package/dist/src/db/write/convertVerbatimItemStorageRow.d.ts +0 -44
  362. package/dist/src/db/write/convertVerbatimItemStorageRow.d.ts.map +0 -1
  363. package/dist/src/db/write/restoreDataItemIdsOverwrittenByL1.d.ts +0 -18
  364. package/dist/src/db/write/restoreDataItemIdsOverwrittenByL1.d.ts.map +0 -1
  365. package/dist/src/db/write/saveAppState.d.ts +0 -2
  366. package/dist/src/db/write/saveAppState.d.ts.map +0 -1
  367. package/dist/src/eslint-rules/align-imports.d.ts +0 -12
  368. package/dist/src/eslint-rules/align-imports.d.ts.map +0 -1
  369. package/dist/src/events/files/index.d.ts +0 -4
  370. package/dist/src/events/files/index.d.ts.map +0 -1
  371. package/dist/src/events/index.d.ts +0 -13
  372. package/dist/src/events/index.d.ts.map +0 -1
  373. package/dist/src/events/services/allItems.d.ts +0 -6
  374. package/dist/src/events/services/allItems.d.ts.map +0 -1
  375. package/dist/src/events/services/index.d.ts +0 -3
  376. package/dist/src/events/services/index.d.ts.map +0 -1
  377. package/dist/src/helpers/ArweaveClient/index.d.ts +0 -30
  378. package/dist/src/helpers/ArweaveClient/index.d.ts.map +0 -1
  379. package/dist/src/helpers/PathResolver/BasePathResolver.d.ts +0 -26
  380. package/dist/src/helpers/PathResolver/BasePathResolver.d.ts.map +0 -1
  381. package/dist/src/helpers/PathResolver/IPathResolver.d.ts +0 -16
  382. package/dist/src/helpers/PathResolver/IPathResolver.d.ts.map +0 -1
  383. package/dist/src/helpers/easRevokedFilter.d.ts +0 -2
  384. package/dist/src/helpers/easRevokedFilter.d.ts.map +0 -1
  385. package/dist/src/helpers/file/fetchAll/actors.d.ts +0 -16
  386. package/dist/src/helpers/file/fetchAll/actors.d.ts.map +0 -1
  387. package/dist/src/helpers/file/fetchAll/index.d.ts +0 -58
  388. package/dist/src/helpers/file/fetchAll/index.d.ts.map +0 -1
  389. package/dist/src/helpers/files.d.ts +0 -10
  390. package/dist/src/helpers/files.d.ts.map +0 -1
  391. package/dist/src/helpers/updateMachineContext.d.ts +0 -7
  392. package/dist/src/helpers/updateMachineContext.d.ts.map +0 -1
  393. package/dist/src/imports/markdown.d.ts +0 -40
  394. package/dist/src/imports/markdown.d.ts.map +0 -1
  395. package/dist/src/node/constants.d.ts +0 -2
  396. package/dist/src/node/constants.d.ts.map +0 -1
  397. package/dist/src/node/db/index.d.ts +0 -5
  398. package/dist/src/node/db/index.d.ts.map +0 -1
  399. package/dist/src/node/helpers/PathResolver.d.ts +0 -44
  400. package/dist/src/node/helpers/PathResolver.d.ts.map +0 -1
  401. package/dist/src/node/helpers/scripts.d.ts +0 -14
  402. package/dist/src/node/helpers/scripts.d.ts.map +0 -1
  403. package/dist/src/node/seed.d.ts +0 -1
  404. package/dist/src/node/seed.d.ts.map +0 -1
  405. package/dist/src/node/webpack/fs-proxy.d.ts +0 -4
  406. package/dist/src/node/webpack/fs-proxy.d.ts.map +0 -1
  407. package/dist/src/node/webpack/index.d.ts +0 -7
  408. package/dist/src/node/webpack/index.d.ts.map +0 -1
  409. package/dist/src/services/events.d.ts +0 -2
  410. package/dist/src/services/events.d.ts.map +0 -1
  411. package/dist/src/testing/platformTestHandle.d.ts +0 -8
  412. package/dist/src/testing/platformTestHandle.d.ts.map +0 -1
  413. package/dist/src/types/browser.d.ts +0 -24
  414. package/dist/src/types/browser.d.ts.map +0 -1
  415. package/dist/src/types/seedProtocol.d.ts +0 -16
  416. package/dist/src/types/seedProtocol.d.ts.map +0 -1
  417. package/dist/src/types/services.d.ts +0 -1
  418. package/dist/src/types/services.d.ts.map +0 -1
  419. package/dist/syncDbWithEas-b4fESZ7C.js.map +0 -1
@@ -1,15 +1,16 @@
1
- import { startCase, isEqual } from 'lodash-es';
2
- import { G as BaseDb, l as easSyncProcesses, J as eventEmitter, au as isBrowser, a4 as isNode, aI as normalizeAddressConfig, aX as isTestOrSeedDev, h as appState, aY as downloadAllFilesRequestHandler, aZ as downloadAllFilesBinaryRequestHandler, Q as BaseFileManager, ag as loadNameMatchLevels, t as models$1, s as modelUids, C as seeds, aJ as normalizeAddressList, B as schemas, aU as loadModelsFromDbForSchema, aQ as addSchemaToDb, aN as isInternalSchema, aj as generateId, aW as clearNameMatchLevels, a_ as warnOnInvalidNameMatch, a$ as INTERNAL_SCHEMA_IDS, b0 as linkModelToSchema, n as normalizeDataType, ad as easPropertyNameForPublish, ay as SEED_PROTOCOL_SCHEMA_NAME, r as modelSchemas, a2 as getItemStorageSubdir, a3 as getItemStorageLocalFileName, m as metadata$1, w as properties, O as resolveItemModelFileId, F as versions, ae as normalizePublisher, v as pendingWrites, b1 as getMetadataPropertyNamesForQuery, p as htmlEmbeddedImageCoPublish, j as arweaveL1FinalizeJobs, A as publishProcesses, b2 as getWatchedAddressesFromDb, b3 as getOwnedAddressesFromDb, b4 as CLIENT_NOT_INITIALIZED } from './index-C0SetTd1.js';
1
+ import { isEqual } from 'lodash-es';
2
+ import { L as BaseDb, u as easSyncProcesses, am as isBrowser, $ as isNode, aA as normalizeAddressConfig, aQ as isTestOrSeedDev, h as appState, Q as BaseFileManager, aa as loadNameMatchLevels, p as models$1, o as modelUids, s as seeds, aB as normalizeAddressList, J as schemas, aL as loadModelsFromDbForSchema, aN as addSchemaToDb, aF as isInternalSchema, ad as generateId, aR as warnOnInvalidNameMatch, aS as INTERNAL_SCHEMA_IDS, aT as linkModelToSchema, n as normalizeDataType, a7 as easPropertyNameForPublish, aq as SEED_PROTOCOL_SCHEMA_NAME, z as modelSchemas, v as versions, m as metadata$1, Z as getItemStorageSubdir, _ as getItemStorageLocalFileName, C as pendingWrites, aU as getMetadataPropertyNamesForQuery, x as htmlEmbeddedImageCoPublish, t as arweaveL1FinalizeJobs, I as publishProcesses, a8 as normalizePublisher, aV as getWatchedAddressesFromDb, aW as getOwnedAddressesFromDb, aX as CLIENT_NOT_INITIALIZED } from './index-Dx_GTdyQ.js';
3
3
  import debug from 'debug';
4
4
  import { createActor, setup, assign, fromPromise, fromCallback, waitFor } from 'xstate';
5
- import { Y as MachineIds, an as ClientManagerEvents, D as compareMetadataRowsLatestFirst, u as writeInBatches, ao as resolvePublisherFromSeedRow, ap as getSeedPublisher, aq as propertyNameVariants, M as METADATA_LATEST_FIRST_ORDER_SQL, L as selectInBatches, ar as createSeed, as as createMetadata, at as updateItemPropertyValue, s as registerOutboxApplier, q as outboxOpValue, i as OutboxOpDeferredError, t as startOutbox, j as OutboxOpFailedError, z as OwnershipError, B as isItemOwned, G as parseListPropertyValueFromStorage, X as ClientManagerState, a5 as isLocalUnsealedDraft, I as Item } from './Item-CjTEShfk.js';
6
- import { eq, inArray, and, isNotNull, ne, desc, countDistinct, isNull, or, sql, like, lt } from 'drizzle-orm';
7
- import { d as withDbTabLock, a as isLeaderTab, k as postTabMessage, o as onTabMessage, c as whenLeaderTab, l as listenForOtherTabsEvents, m as startTabCoordination, g as withSeedDbLock, e as emitAcrossTabs, A as ADDRESSES_PERSISTED_EVENT, q as tryWithTabLock, r as withTabLock, u as notifyFileSaved, p as parseAddressesPersistedPayload, L as LOCAL_COPIES_REMOVED_EVENT } from './changeFeed-DcsZ7deG.js';
5
+ import { X as MachineIds, am as ClientManagerEvents, an as getSeedPublisher, ao as propertyNameVariants, M as METADATA_LATEST_FIRST_ORDER_SQL, z as selectInBatches, ap as createSeed, aq as createMetadata, C as compareMetadataRowsLatestFirst, ar as updateItemPropertyValue, r as registerOutboxApplier, n as outboxOpValue, i as OutboxOpDeferredError, s as startOutbox, j as OutboxOpFailedError, u as OwnershipError, x as isItemOwned, F as parseListPropertyValueFromStorage, W as ClientManagerState, as as resolvePublisherFromSeedRow, a4 as isLocalUnsealedDraft, y as writeInBatches, I as Item } from './Item-0oDoTPhi.js';
6
+ import { eq, inArray, and, isNotNull, ne, desc, countDistinct, isNull, sql, lt, or, like } from 'drizzle-orm';
7
+ import { d as withDbTabLock, a as isLeaderTab, k as postTabMessage, o as onTabMessage, c as whenLeaderTab, l as listenForOtherTabsEvents, m as startTabCoordination, g as withSeedDbLock, e as emitAcrossTabs, A as ADDRESSES_PERSISTED_EVENT, q as tryWithTabLock, r as notifyFileSaved, p as parseAddressesPersistedPayload, L as LOCAL_COPIES_REMOVED_EVENT } from './changeFeed-DKdVlUmt.js';
8
8
  import { seedGatewayConfigFromSeedConfig, setPreferredArweaveReadBaseUrls, resolveSeedGatewayEndpoints, setResolvedSeedGatewayEndpoints, BaseArweaveClient, ensureReadGatewaySelected, DEFAULT_ARWEAVE_HOST } from '@seedprotocol/arweave';
9
- import { configureEasReadChain, easName, BaseQueryClient, BaseEasClient, GET_SCHEMAS, whenEasReadChainSettled, getEasReadChainId, DEFAULT_EAS_CHAIN_ID, isEasReadChainConfigured, isPlaceholderUid, localNamesInBestMatchTier, isValidEasAttestationUid } from '@seedprotocol/eas';
9
+ import { configureEasReadChain, easName, BaseQueryClient, BaseEasClient, GET_SCHEMAS, whenEasReadChainSettled, getEasReadChainId, DEFAULT_EAS_CHAIN_ID, isEasReadChainConfigured, localNamesInBestMatchTier, isPlaceholderUid, isValidEasAttestationUid } from '@seedprotocol/eas';
10
10
  import 'pluralize';
11
11
  import { sha3_256 } from '@noble/hashes/sha3';
12
12
  import { utf8ToBytes, bytesToHex } from '@noble/hashes/utils';
13
+ import { e as eventEmitter } from './eventBus-7vxTCc3a.js';
13
14
  import { clearLocalQuerySource, registerLocalQuerySource, getSeed } from '@seedprotocol/query';
14
15
 
15
16
  let writeTail = Promise.resolve();
@@ -212,7 +213,7 @@ function toRunSyncArg(options) {
212
213
  return undefined;
213
214
  }
214
215
  const runEasSync = fromPromise(async ({ input, }) => {
215
- const { runSyncFromEas } = await import('./syncDbWithEas-b4fESZ7C.js');
216
+ const { runSyncFromEas } = await import('./syncDbWithEas-DUu_wjUG.js');
216
217
  // Sync checks for rows and then inserts the rest (no unique index on uids), so syncs in
217
218
  // different tabs take turns. A sync can run for minutes, so wait without a timeout.
218
219
  await withDbTabLock('eas-sync', async () => {
@@ -271,7 +272,8 @@ const syncRetry = createRetryWhenOnline(() => {
271
272
  const initialContext = {
272
273
  runOptions: {},
273
274
  activeCorrelationIds: [],
274
- activePrimarySource: 'event_bus',
275
+ // Replaced by the first request's source before any run.
276
+ activePrimarySource: 'models_init',
275
277
  pendingMergedOptions: undefined,
276
278
  pendingCorrelationIds: [],
277
279
  pendingPrimarySource: null,
@@ -394,7 +396,7 @@ const easSyncMachine = setup({
394
396
  activeCorrelationIds: ({ context }) => [
395
397
  ...context.pendingCorrelationIds,
396
398
  ],
397
- activePrimarySource: ({ context }) => context.pendingPrimarySource ?? 'event_bus',
399
+ activePrimarySource: ({ context }) => context.pendingPrimarySource ?? 'models_init',
398
400
  pendingMergedOptions: () => undefined,
399
401
  pendingCorrelationIds: () => [],
400
402
  pendingPrimarySource: () => null,
@@ -422,7 +424,7 @@ function newCorrelationId() {
422
424
  return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
423
425
  }
424
426
  /** Requests deferred in this tab until it leads, by source; each runs once on takeover. */
425
- const deferredUntilLeader$5 = new Set();
427
+ const deferredUntilLeader$1 = new Set();
426
428
  /**
427
429
  * Automatic syncs run in the leader tab only (docs/MULTI_TAB.md). A tab that skips one runs it if
428
430
  * it later becomes leader, so closing the leader doesn't lose the catch-up sync.
@@ -433,11 +435,11 @@ function runInLeaderTab(source, request) {
433
435
  return;
434
436
  }
435
437
  log(`${source} sync skipped: another tab leads`);
436
- if (deferredUntilLeader$5.has(source))
438
+ if (deferredUntilLeader$1.has(source))
437
439
  return;
438
- deferredUntilLeader$5.add(source);
440
+ deferredUntilLeader$1.add(source);
439
441
  void whenLeaderTab().then(() => {
440
- deferredUntilLeader$5.delete(source);
442
+ deferredUntilLeader$1.delete(source);
441
443
  request();
442
444
  });
443
445
  }
@@ -453,17 +455,6 @@ function listenForEasSyncRequestsFromOtherTabs() {
453
455
  }
454
456
  });
455
457
  }
456
- function requestEasSyncFromEventBus() {
457
- runInLeaderTab('event_bus', sendEventBusRequest);
458
- }
459
- function sendEventBusRequest() {
460
- startEasSyncActor();
461
- easSyncActor.send({
462
- type: 'REQUEST',
463
- correlationId: newCorrelationId(),
464
- source: 'event_bus',
465
- });
466
- }
467
458
  function requestEasSyncFromAddressChange(addresses) {
468
459
  if (!isLeaderTab()) {
469
460
  // The leader syncs these addresses; its own address list may be stale.
@@ -505,43 +496,18 @@ var easSyncManager = /*#__PURE__*/Object.freeze({
505
496
  easSyncMachine: easSyncMachine,
506
497
  listenForEasSyncRequestsFromOtherTabs: listenForEasSyncRequestsFromOtherTabs,
507
498
  requestEasSyncFromAddressChange: requestEasSyncFromAddressChange,
508
- requestEasSyncFromEventBus: requestEasSyncFromEventBus,
509
499
  requestEasSyncFromModelsInit: requestEasSyncFromModelsInit,
510
500
  sendEasSyncClientRequest: sendEasSyncClientRequest,
511
501
  startEasSyncActor: startEasSyncActor
512
502
  });
513
503
 
514
- const logger$g = debug('seedSdk:services:events');
515
- const handleServiceSaveState = (event) => {
516
- const { serviceId } = event;
517
- logger$g(`[browser] [service.saveState.request] serviceId: ${serviceId}`);
518
- // TODO: This is called from Node as well. Do we need it? If so, need to generalize this to all platforms.
519
- // localStorage.setItem(`seed_sdk_service_${serviceId}`, JSON.stringify(state))
520
- };
521
- const setupServicesEventHandlers = () => {
522
- eventEmitter.addListener('service.saveState.request', handleServiceSaveState);
523
- };
524
-
525
504
  const setupAllItemsEventHandlers = () => {
526
505
  startEasSyncActor();
527
506
  listenForEasSyncRequestsFromOtherTabs();
528
507
  listenForOtherTabsEvents();
529
- eventEmitter.addListener('syncDbWithEas', requestEasSyncFromEventBus);
530
508
  };
531
509
  // Note: getAreItemEventHandlersReady removed - was only used by useItemIsReady hook which has been removed
532
510
 
533
- // AllItems services have been removed - this handler is no longer needed
534
- // Service state persistence is now handled by entity instances directly
535
- const saveServiceHandler = async (_event) => {
536
- // AllItems services removed - this functionality is no longer needed
537
- // Entity instances (Schema, Model, Item) manage their own state
538
- console.warn('[saveServiceHandler] AllItems services removed - handler is a no-op');
539
- };
540
-
541
- const setupServiceHandlers = () => {
542
- eventEmitter.addListener('service.save', saveServiceHandler);
543
- };
544
-
545
511
  /** `filesDir` when the config sets neither it nor `endpoints.files`. */
546
512
  const DEFAULT_FILES_DIR = '.seed';
547
513
  /**
@@ -563,9 +529,9 @@ function applySeedConfigDefaults(config) {
563
529
  return { ...config, filesDir, endpoints: next };
564
530
  }
565
531
 
566
- const logger$f = debug('seedSdk:ClientManager:initialize');
532
+ const logger$b = debug('seedSdk:ClientManager:initialize');
567
533
  const platformClassesInit = fromCallback(({ sendBack, input: { context, event } }) => {
568
- logger$f('initialize from ClientManager');
534
+ logger$b('initialize from ClientManager');
569
535
  const { isInitialized } = context;
570
536
  if (!event || !('options' in event)) {
571
537
  throw new Error('Initialize event must include options');
@@ -590,9 +556,7 @@ const platformClassesInit = fromCallback(({ sendBack, input: { context, event }
590
556
  if (!config) {
591
557
  throw new Error('client.init requires a config');
592
558
  }
593
- const _mod_0 = await import('./configurePlatform-AWild9o4.js');
594
- const _ns_0 = _mod_0.a;
595
- const { configurePlatform } = _ns_0;
559
+ const { configurePlatform } = await import('./configurePlatform-CrMafpMW.js');
596
560
  if (isBrowser()) {
597
561
  const { createPlatformServices } = await import('./platform.browser.js');
598
562
  configurePlatform(createPlatformServices());
@@ -630,7 +594,7 @@ const platformClassesInit = fromCallback(({ sendBack, input: { context, event }
630
594
  BaseArweaveClient.setHost(`${resolvedGateway.arweaveProtocol}://${resolvedGateway.arweaveHost}`);
631
595
  // filesDir falls back to endpoints.files (applySeedConfigDefaults fills both)
632
596
  let normalizedFilesDir = filesDir || endpoints?.files;
633
- // jsdom (and any env with both Node + window) is "browser" for SDK: PathResolver is OPFS/virtual.
597
+ // jsdom (and any env with both Node + window) is "browser" for SDK: filesDir is an OPFS path.
634
598
  // Do not run real fs against those paths (e.g. mkdir '/.seed').
635
599
  if (isNode() && !isBrowser() && normalizedFilesDir) {
636
600
  // Lives in the Node platform so browser bundles (and Next.js server builds, which
@@ -671,8 +635,6 @@ const platformClassesInit = fromCallback(({ sendBack, input: { context, event }
671
635
  // Models are now Model instances, no registration needed
672
636
  // They should be created via Model.create() and are accessible via Model static methods
673
637
  setupAllItemsEventHandlers();
674
- setupServicesEventHandlers();
675
- setupServiceHandlers();
676
638
  });
677
639
  // Handle the promise immediately - this ensures rejections are caught synchronously
678
640
  // The catch handler is attached synchronously before the async function executes
@@ -703,7 +665,7 @@ const platformClassesInit = fromCallback(({ sendBack, input: { context, event }
703
665
  };
704
666
  });
705
667
 
706
- const logger$e = debug('seedSdk:client:writeToDb');
668
+ const logger$a = debug('seedSdk:client:writeToDb');
707
669
  const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
708
670
  const _saveAppState = async () => {
709
671
  try {
@@ -711,7 +673,7 @@ const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
711
673
  if (!appDb) {
712
674
  // In test environments, continue anyway
713
675
  if (isTestOrSeedDev()) {
714
- logger$e('[client/actors] [saveAppState] App DB not found, but continuing in test environment');
676
+ logger$a('[client/actors] [saveAppState] App DB not found, but continuing in test environment');
715
677
  return;
716
678
  }
717
679
  throw new Error('App DB not found');
@@ -727,13 +689,13 @@ const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
727
689
  value: JSON.stringify(value),
728
690
  },
729
691
  });
730
- logger$e('result', result);
692
+ logger$a('result', result);
731
693
  }
732
694
  catch (error) {
733
- logger$e('[client/actors] [saveAppState] Error saving app state:', error);
695
+ logger$a('[client/actors] [saveAppState] Error saving app state:', error);
734
696
  // In test environments, continue anyway
735
697
  if (isTestOrSeedDev()) {
736
- logger$e('[client/actors] [saveAppState] Continuing despite error in test environment');
698
+ logger$a('[client/actors] [saveAppState] Continuing despite error in test environment');
737
699
  return;
738
700
  }
739
701
  throw error;
@@ -748,10 +710,10 @@ const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
748
710
  });
749
711
  })
750
712
  .catch((error) => {
751
- logger$e('[client/actors] [saveAppState] Error in promise chain:', error);
713
+ logger$a('[client/actors] [saveAppState] Error in promise chain:', error);
752
714
  // In test environments, still send success to allow state machine to progress
753
715
  if (isTestOrSeedDev()) {
754
- logger$e('[client/actors] [saveAppState] Sending success despite error in test environment');
716
+ logger$a('[client/actors] [saveAppState] Sending success despite error in test environment');
755
717
  sendBack({
756
718
  type: 'saveAppStateSuccess',
757
719
  key,
@@ -769,29 +731,7 @@ const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
769
731
  });
770
732
  });
771
733
 
772
- let isInitialized = false;
773
- const fsInitHandler = async () => {
774
- if (isInitialized) {
775
- return;
776
- }
777
- isInitialized = true;
778
- };
779
- let areReady = false;
780
- const setupFsListeners = () => {
781
- eventEmitter.addListener('fs.downloadAll.request', downloadAllFilesRequestHandler);
782
- eventEmitter.addListener('fs.downloadAllBinary.request', downloadAllFilesBinaryRequestHandler);
783
- eventEmitter.addListener('fs.init', fsInitHandler);
784
- areReady = true;
785
- };
786
- const areFsListenersReady = () => {
787
- return areReady;
788
- };
789
-
790
734
  const fileSystemInit = fromCallback(({ sendBack, input: { context }, }) => {
791
- setupFsListeners();
792
- if (!areFsListenersReady()) {
793
- throw new Error('fs listeners not ready during init');
794
- }
795
735
  // Check for filesDir synchronously before starting async operation
796
736
  // This ensures the error is thrown synchronously and caught by XState
797
737
  const { filesDir } = context;
@@ -800,7 +740,6 @@ const fileSystemInit = fromCallback(({ sendBack, input: { context }, }) => {
800
740
  }
801
741
  const _fileSystemInit = async () => {
802
742
  await BaseFileManager.initializeFileSystem(filesDir);
803
- eventEmitter.emit('fs.init');
804
743
  };
805
744
  _fileSystemInit()
806
745
  .then(() => {
@@ -820,7 +759,7 @@ const fileSystemInit = fromCallback(({ sendBack, input: { context }, }) => {
820
759
  };
821
760
  });
822
761
 
823
- const logger$d = debug('seedSdk:client:actors:dbInit');
762
+ const logger$9 = debug('seedSdk:client:actors:dbInit');
824
763
  const dbInit = fromCallback(({ sendBack, input: { context } }) => {
825
764
  const _dbInit = async () => {
826
765
  const { filesDir, dbConfig } = context;
@@ -834,14 +773,14 @@ const dbInit = fromCallback(({ sendBack, input: { context } }) => {
834
773
  if (!appDb) {
835
774
  throw new Error('Database not available after preparation');
836
775
  }
837
- logger$d('[client/actors] [dbInit] Database prepared and ready');
776
+ logger$9('[client/actors] [dbInit] Database prepared and ready');
838
777
  };
839
778
  _dbInit()
840
779
  .then(() => {
841
780
  sendBack({ type: ClientManagerEvents.DB_READY });
842
781
  })
843
782
  .catch((error) => {
844
- logger$d('Error in dbInit:', error);
783
+ logger$9('Error in dbInit:', error);
845
784
  sendBack({
846
785
  type: 'error',
847
786
  error: error instanceof Error ? error : new Error(String(error))
@@ -849,7 +788,7 @@ const dbInit = fromCallback(({ sendBack, input: { context } }) => {
849
788
  });
850
789
  });
851
790
 
852
- const logger$c = debug('seedSdk:client:actors:addModelsToStore');
791
+ const logger$8 = debug('seedSdk:client:actors:addModelsToStore');
853
792
  const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
854
793
  const _addModelsToStore = async () => {
855
794
  let { models } = context;
@@ -863,7 +802,7 @@ const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
863
802
  // Models are now Model instances, no registration needed
864
803
  // They should be created via Model.create() and are accessible via Model static methods
865
804
  for (const [key] of Object.entries(allModels)) {
866
- logger$c('model available:', key);
805
+ logger$8('model available:', key);
867
806
  }
868
807
  };
869
808
  _addModelsToStore()
@@ -871,7 +810,7 @@ const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
871
810
  sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_STORE_SUCCESS });
872
811
  })
873
812
  .catch((error) => {
874
- logger$c('[client/actors] [addModelsToStore] Error:', error);
813
+ logger$8('[client/actors] [addModelsToStore] Error:', error);
875
814
  sendBack({
876
815
  type: 'error',
877
816
  error: error instanceof Error ? error : new Error(String(error)),
@@ -879,7 +818,7 @@ const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
879
818
  });
880
819
  });
881
820
 
882
- const logger$b = debug('seedSdk:client:actors:addModelsToDb');
821
+ const logger$7 = debug('seedSdk:client:actors:addModelsToDb');
883
822
  /**
884
823
  * Returns every `models` row named in `modelNames`, inserting a null-schemaFileId stub for each name
885
824
  * with no row yet (the schema import adopts stubs via findOrCreateModelRecord). Check-then-insert:
@@ -902,7 +841,7 @@ async function ensureModelStubs(appDb, modelNames, filesDir) {
902
841
  .returning({ id: models$1.id, name: models$1.name, schemaFileId: models$1.schemaFileId }));
903
842
  rows.push(...newlyInserted);
904
843
  for (const name of modelsToInsert) {
905
- logger$b('[client/actors] [addModelsToDb] inserted model:', name);
844
+ logger$7('[client/actors] [addModelsToDb] inserted model:', name);
906
845
  }
907
846
  }
908
847
  return rows;
@@ -942,7 +881,7 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
942
881
  for (const modelName of modelNames) {
943
882
  const foundModel = rowFor(modelName);
944
883
  if (!foundModel) {
945
- logger$b('[client/actors] [addModelsToDb] Warning: Could not find or create model:', modelName);
884
+ logger$7('[client/actors] [addModelsToDb] Warning: Could not find or create model:', modelName);
946
885
  hasModelsInDb = false;
947
886
  continue;
948
887
  }
@@ -954,7 +893,7 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
954
893
  }
955
894
  // If we have no models to process, still send success (empty models is valid)
956
895
  if (schemaDefsByModelName.size === 0) {
957
- logger$b('[client/actors] [addModelsToDb] No models to process, but continuing');
896
+ logger$7('[client/actors] [addModelsToDb] No models to process, but continuing');
958
897
  return;
959
898
  }
960
899
  const schemaDefs = Array.from(schemaDefsByModelName.values()).map(({ schemaDef }) => schemaDef);
@@ -1001,15 +940,15 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
1001
940
  requestEasSyncFromModelsInit();
1002
941
  }
1003
942
  else {
1004
- logger$b('[client/actors] [addModelsToDb] No schemas found from EAS, but continuing');
943
+ logger$7('[client/actors] [addModelsToDb] No schemas found from EAS, but continuing');
1005
944
  }
1006
945
  }
1007
946
  catch (error) {
1008
947
  if (isTestOrSeedDev()) {
1009
- logger$b('[client/actors] [addModelsToDb] Warning: Could not fetch schemas from EAS (background):', error.message);
948
+ logger$7('[client/actors] [addModelsToDb] Warning: Could not fetch schemas from EAS (background):', error.message);
1010
949
  }
1011
950
  else {
1012
- logger$b('[client/actors] [addModelsToDb] Error fetching schemas (background):', error.message);
951
+ logger$7('[client/actors] [addModelsToDb] Error fetching schemas (background):', error.message);
1013
952
  }
1014
953
  // Probably offline: the startup sync waits for this lookup, so try again.
1015
954
  modelUidsRetry.schedule();
@@ -1023,16 +962,16 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
1023
962
  _addModelsToDb()
1024
963
  // Model.findByModelType reads the nameMatch levels synchronously: have them before init is ready.
1025
964
  .then(() => loadNameMatchLevels().catch((error) => {
1026
- logger$b('[client/actors] [addModelsToDb] Could not load nameMatch levels:', error);
965
+ logger$7('[client/actors] [addModelsToDb] Could not load nameMatch levels:', error);
1027
966
  }))
1028
967
  .then(() => {
1029
968
  sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
1030
969
  })
1031
970
  .catch((error) => {
1032
- logger$b('[client/actors] [addModelsToDb] Error:', error);
971
+ logger$7('[client/actors] [addModelsToDb] Error:', error);
1033
972
  // In test environments, still send success to allow initialization to complete
1034
973
  if (isTestOrSeedDev()) {
1035
- logger$b('[client/actors] [addModelsToDb] Continuing despite error in test environment');
974
+ logger$7('[client/actors] [addModelsToDb] Continuing despite error in test environment');
1036
975
  sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
1037
976
  }
1038
977
  else {
@@ -1045,7 +984,7 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
1045
984
  return () => { };
1046
985
  });
1047
986
 
1048
- const logger$a = debug('seedSdk:helpers:localDbChain');
987
+ const logger$6 = debug('seedSdk:helpers:localDbChain');
1049
988
  /** appState key recording which EAS chain the local database holds attestations from. */
1050
989
  const EAS_CHAIN_ID_APP_STATE_KEY = 'easChainId';
1051
990
  /**
@@ -1115,7 +1054,7 @@ async function loadLocalDbChain() {
1115
1054
  const localChainId = await resolveLocalDbChainId(appDb);
1116
1055
  if (localChainId !== undefined) {
1117
1056
  configureEasReadChain('localDb', { chainId: localChainId });
1118
- logger$a('local DB holds chain %d', localChainId);
1057
+ logger$6('local DB holds chain %d', localChainId);
1119
1058
  return;
1120
1059
  }
1121
1060
  if (isEasReadChainConfigured()) {
@@ -1164,7 +1103,7 @@ function resetAddressesPersistedAnnouncement() {
1164
1103
  lastAnnounced = undefined;
1165
1104
  }
1166
1105
 
1167
- const logger$9 = debug('seedSdk:client:actors:saveConfig');
1106
+ const logger$5 = debug('seedSdk:client:actors:saveConfig');
1168
1107
  let warnedKeptStoredAddresses = false;
1169
1108
  /**
1170
1109
  * Saves the addresses passed to init.
@@ -1205,13 +1144,13 @@ async function persistInitAddresses(appDb, { addresses, addressesProvided, owned
1205
1144
  announceAddressesPersisted({ owned, watched });
1206
1145
  }
1207
1146
  const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
1208
- logger$9('saveConfig starting');
1147
+ logger$5('saveConfig starting');
1209
1148
  const { endpoints, addresses, addressesProvided, ownedAddresses, watchedAddresses, arweaveDomain, uploadApiBaseUrl, gatewayTransport, gatewayHyperKey, gatewaySidecarHost, gatewaySidecarPort, gatewayProxyBaseUrl, } = context;
1210
1149
  // Validate endpoints - required for proper initialization
1211
1150
  // If endpoints are missing or invalid, initialization should fail
1212
1151
  if (!endpoints || !endpoints.filePaths || !endpoints.files) {
1213
1152
  const error = new Error('saveConfig called with invalid endpoints: endpoints must include both filePaths and files');
1214
- logger$9('[internal/actors] [saveConfig] Invalid endpoints:', { endpoints });
1153
+ logger$5('[internal/actors] [saveConfig] Invalid endpoints:', { endpoints });
1215
1154
  throw error;
1216
1155
  }
1217
1156
  const _saveConfig = async () => {
@@ -1220,7 +1159,7 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
1220
1159
  if (!appDb) {
1221
1160
  // In test environments, continue anyway
1222
1161
  if (isTestOrSeedDev()) {
1223
- logger$9('[internal/actors] [saveConfig] App DB not found, but continuing in test environment');
1162
+ logger$5('[internal/actors] [saveConfig] App DB not found, but continuing in test environment');
1224
1163
  return;
1225
1164
  }
1226
1165
  throw new Error('App DB not found');
@@ -1275,10 +1214,10 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
1275
1214
  await loadLocalDbChain();
1276
1215
  }
1277
1216
  catch (error) {
1278
- logger$9('[internal/actors] [saveConfig] Error saving config:', error);
1217
+ logger$5('[internal/actors] [saveConfig] Error saving config:', error);
1279
1218
  // In test environments, continue anyway
1280
1219
  if (isTestOrSeedDev()) {
1281
- logger$9('[internal/actors] [saveConfig] Continuing despite error in test environment');
1220
+ logger$5('[internal/actors] [saveConfig] Continuing despite error in test environment');
1282
1221
  return;
1283
1222
  }
1284
1223
  throw error;
@@ -1287,14 +1226,14 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
1287
1226
  // Init writes run one tab at a time (docs/MULTI_TAB.md).
1288
1227
  withSeedDbLock('init', context.filesDir, _saveConfig)
1289
1228
  .then(() => {
1290
- logger$9('[internal/actors] [saveConfig] saveConfig success');
1229
+ logger$5('[internal/actors] [saveConfig] saveConfig success');
1291
1230
  return sendBack({ type: ClientManagerEvents.SAVE_CONFIG_SUCCESS });
1292
1231
  })
1293
1232
  .catch((error) => {
1294
- logger$9('[internal/actors] [saveConfig] Error in saveConfig promise chain:', error);
1233
+ logger$5('[internal/actors] [saveConfig] Error in saveConfig promise chain:', error);
1295
1234
  // In test environments, still send success to allow state machine to progress
1296
1235
  if (isTestOrSeedDev()) {
1297
- logger$9('[internal/actors] [saveConfig] Sending success despite error in test environment');
1236
+ logger$5('[internal/actors] [saveConfig] Sending success despite error in test environment');
1298
1237
  sendBack({ type: ClientManagerEvents.SAVE_CONFIG_SUCCESS });
1299
1238
  }
1300
1239
  else {
@@ -1307,140 +1246,7 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
1307
1246
  return () => { };
1308
1247
  });
1309
1248
 
1310
- const logger$8 = debug('seedSdk:helpers:schema');
1311
- /**
1312
- * Sanitize a schema name to be filesystem-safe
1313
- * Replaces all special characters (except alphanumeric, hyphens, underscores) with underscores
1314
- * Converts spaces to underscores
1315
- * Removes leading/trailing underscores
1316
- *
1317
- * @param name - Schema name to sanitize
1318
- * @returns Sanitized name safe for use in filenames
1319
- */
1320
- const sanitizeSchemaName$1 = (name) => {
1321
- return name
1322
- .replace(/[^a-zA-Z0-9\s_-]/g, '_') // Replace special chars (except spaces, hyphens, underscores) with underscore
1323
- .replace(/\s+/g, '_') // Convert spaces to underscores
1324
- .replace(/^_+|_+$/g, '') // Remove leading/trailing underscores
1325
- .replace(/_+/g, '_'); // Collapse multiple underscores to single
1326
- };
1327
- /**
1328
- * Generate filename for a schema
1329
- * Format: {schemaFileId}_{schemaName}_v{version}.json
1330
- *
1331
- * The ID-first format ensures all files for a schema group together when sorted alphabetically.
1332
- *
1333
- * @param name - Schema name
1334
- * @param version - Schema version
1335
- * @param schemaFileId - Schema file ID (required)
1336
- */
1337
- const getSchemaFilename = (name, version, schemaFileId) => {
1338
- const sanitizedName = sanitizeSchemaName$1(name);
1339
- return `${schemaFileId}_${sanitizedName}_v${version}.json`;
1340
- };
1341
- /**
1342
- * Get the full file path for a schema
1343
- * Format: {schemaFileId}_{schemaName}_v{version}.json
1344
- *
1345
- * The ID-first format ensures all files for a schema group together when sorted alphabetically.
1346
- *
1347
- * @param name - Schema name
1348
- * @param version - Schema version
1349
- * @param schemaFileId - Schema file ID (required)
1350
- */
1351
- const getSchemaFilePath$1 = (name, version, schemaFileId) => {
1352
- const path = BaseFileManager.getPathModule();
1353
- const filename = getSchemaFilename(name, version, schemaFileId);
1354
- const workingDir = BaseFileManager.getWorkingDir();
1355
- return path.join(workingDir, filename);
1356
- };
1357
- /**
1358
- * Create a new schema file
1359
- * @param schema - The schema object to save
1360
- * @param schemaFileId - Schema file ID (required)
1361
- * @throws Error if schema already exists or if workingDir is invalid
1362
- */
1363
- const createSchema = async (schema, schemaFileId) => {
1364
- if (!schema.name || !schema.version) {
1365
- throw new Error('Schema must have a name and version');
1366
- }
1367
- const filePath = getSchemaFilePath$1(schema.name, schema.version, schemaFileId);
1368
- // Check if schema already exists
1369
- const exists = await BaseFileManager.pathExists(filePath);
1370
- if (exists) {
1371
- throw new Error(`Schema ${schema.name} v${schema.version} already exists`);
1372
- }
1373
- // Ensure working directory exists
1374
- const workingDir = BaseFileManager.getWorkingDir();
1375
- await BaseFileManager.createDirIfNotExists(workingDir);
1376
- // Write schema to file
1377
- const content = JSON.stringify(schema, null, 2);
1378
- await BaseFileManager.saveFile(filePath, content);
1379
- };
1380
- /**
1381
- * Read a schema file by name and version
1382
- * @param name - The name of the schema
1383
- * @param version - The version of the schema
1384
- * @param schemaFileId - Schema file ID (required)
1385
- * @returns The schema object, or null if not found
1386
- */
1387
- const readSchema = async (name, version, schemaFileId) => {
1388
- const filePath = getSchemaFilePath$1(name, version, schemaFileId);
1389
- const exists = await BaseFileManager.pathExists(filePath);
1390
- if (!exists) {
1391
- return null;
1392
- }
1393
- try {
1394
- const content = await BaseFileManager.readFileAsString(filePath);
1395
- return JSON.parse(content);
1396
- }
1397
- catch (error) {
1398
- throw new Error(`Failed to read schema ${name} v${version}: ${error instanceof Error ? error.message : String(error)}`);
1399
- }
1400
- };
1401
- /**
1402
- * Update an existing schema file
1403
- * @param schema - The updated schema object (must have same name and version as existing)
1404
- * @param schemaFileId - Schema file ID (required)
1405
- * @throws Error if schema doesn't exist
1406
- */
1407
- async function updateSchema(schema, schemaFileId) {
1408
- if (!schema.name || !schema.version) {
1409
- throw new Error('Schema must have a name and version');
1410
- }
1411
- const filePath = getSchemaFilePath$1(schema.name, schema.version, schemaFileId);
1412
- // Check if schema exists
1413
- const exists = await BaseFileManager.pathExists(filePath);
1414
- if (!exists) {
1415
- throw new Error(`Schema ${schema.name} v${schema.version} does not exist`);
1416
- }
1417
- // Write updated schema to file
1418
- const content = JSON.stringify(schema, null, 2);
1419
- await BaseFileManager.saveFile(filePath, content);
1420
- }
1421
- /**
1422
- * Delete a schema file
1423
- * @param name - The name of the schema
1424
- * @param version - The version of the schema
1425
- * @param schemaFileId - Schema file ID (required)
1426
- * @throws Error if schema doesn't exist
1427
- */
1428
- async function deleteSchema(name, version, schemaFileId) {
1429
- const filePath = getSchemaFilePath$1(name, version, schemaFileId);
1430
- // Check if schema exists
1431
- const exists = await BaseFileManager.pathExists(filePath);
1432
- if (!exists) {
1433
- throw new Error(`Schema ${name} v${version} does not exist`);
1434
- }
1435
- // Delete the file
1436
- const fs = await BaseFileManager.getFs();
1437
- try {
1438
- await fs.promises.unlink(filePath);
1439
- }
1440
- catch (error) {
1441
- throw new Error(`Failed to delete schema ${name} v${version}: ${error instanceof Error ? error.message : String(error)}`);
1442
- }
1443
- }
1249
+ const logger$4 = debug('seedSdk:helpers:schema');
1444
1250
  /**
1445
1251
  * List all schema files in the working directory
1446
1252
  * Only returns files that are NOT already complete schema files (i.e., files without $schema field)
@@ -1502,7 +1308,7 @@ async function listCompleteSchemaFiles() {
1502
1308
  const dirExists = await BaseFileManager.pathExists(workingDir);
1503
1309
  if (!dirExists) {
1504
1310
  // Directory doesn't exist yet - return empty array (not an error condition)
1505
- logger$8(`Working directory does not exist yet: ${workingDir}, returning empty schema list`);
1311
+ logger$4(`Working directory does not exist yet: ${workingDir}, returning empty schema list`);
1506
1312
  return [];
1507
1313
  }
1508
1314
  const files = await fs.promises.readdir(workingDir);
@@ -1546,24 +1352,6 @@ async function listCompleteSchemaFiles() {
1546
1352
  throw new Error(`Failed to list complete schemas: ${error instanceof Error ? error.message : String(error)}`);
1547
1353
  }
1548
1354
  }
1549
- /**
1550
- * Find a schema by name (returns the latest version if multiple versions exist)
1551
- * @param name - The name of the schema
1552
- * @returns The schema with the highest version, or null if not found
1553
- */
1554
- async function findSchemaByName(name) {
1555
- const schemas = await listCompleteSchemaFiles();
1556
- const matchingSchemas = schemas.filter((s) => s.name === name);
1557
- if (matchingSchemas.length === 0) {
1558
- return null;
1559
- }
1560
- // Find the schema with the highest version
1561
- const latest = matchingSchemas.reduce((prev, current) => current.version > prev.version ? current : prev);
1562
- if (!latest.schemaFileId) {
1563
- throw new Error(`Schema ${latest.name} v${latest.version} is missing schemaFileId`);
1564
- }
1565
- return readSchema(latest.name, latest.version, latest.schemaFileId);
1566
- }
1567
1355
  /**
1568
1356
  * Get the latest version number for a schema by name
1569
1357
  * Only considers complete schema files (with $schema field)
@@ -1596,27 +1384,6 @@ async function listLatestSchemaFiles() {
1596
1384
  }
1597
1385
  return Array.from(schemaMap.values());
1598
1386
  }
1599
- /**
1600
- * Filter an array of schemas to only include the latest version for each schema name
1601
- * Works with any object that has a name (via metadata.name or name property) and a version property
1602
- * @param schemas - Array of schema objects
1603
- * @returns Array containing only the latest version of each schema
1604
- */
1605
- function filterLatestSchemas(schemas) {
1606
- // Group by schema name and keep only the latest version of each
1607
- const schemaMap = new Map();
1608
- for (const schema of schemas) {
1609
- const schemaName = schema.metadata?.name || schema.name;
1610
- if (!schemaName) {
1611
- continue; // Skip schemas without a name
1612
- }
1613
- const existing = schemaMap.get(schemaName);
1614
- if (!existing || schema.version > existing.version) {
1615
- schemaMap.set(schemaName, schema);
1616
- }
1617
- }
1618
- return Array.from(schemaMap.values());
1619
- }
1620
1387
  async function loadAllSchemasFromDb() {
1621
1388
  const db = BaseDb.getAppDb();
1622
1389
  if (!db) {
@@ -1639,7 +1406,7 @@ async function loadAllSchemasFromDb() {
1639
1406
  }
1640
1407
  catch (error) {
1641
1408
  // If we can't list schema files (e.g., directory doesn't exist yet), continue without file-based loading
1642
- logger$8(`Error listing complete schema files (continuing with DB data): ${error instanceof Error ? error.message : String(error)}`);
1409
+ logger$4(`Error listing complete schema files (continuing with DB data): ${error instanceof Error ? error.message : String(error)}`);
1643
1410
  completeSchemaFiles = [];
1644
1411
  }
1645
1412
  }
@@ -1692,7 +1459,7 @@ async function loadAllSchemasFromDb() {
1692
1459
  continue;
1693
1460
  }
1694
1461
  catch (error) {
1695
- logger$8(`Error parsing schemaData for ${schemaName}:`, error);
1462
+ logger$4(`Error parsing schemaData for ${schemaName}:`, error);
1696
1463
  // Fall through to file-based loading
1697
1464
  }
1698
1465
  }
@@ -1734,7 +1501,7 @@ async function loadAllSchemasFromDb() {
1734
1501
  continue;
1735
1502
  }
1736
1503
  catch (error) {
1737
- logger$8(`Error loading schema file for ${schemaName}:`, error);
1504
+ logger$4(`Error loading schema file for ${schemaName}:`, error);
1738
1505
  // Fall through to try loading from schemaData if available
1739
1506
  }
1740
1507
  }
@@ -1778,7 +1545,7 @@ async function loadAllSchemasFromDb() {
1778
1545
  continue;
1779
1546
  }
1780
1547
  catch (error) {
1781
- logger$8(`Error parsing schemaData for ${schemaName}:`, error);
1548
+ logger$4(`Error parsing schemaData for ${schemaName}:`, error);
1782
1549
  }
1783
1550
  }
1784
1551
  }
@@ -1789,11 +1556,11 @@ async function loadAllSchemasFromDb() {
1789
1556
  // Only process if not already in result
1790
1557
  if (!processedSchemaNames.has(schemaFileInfo.name)) {
1791
1558
  if (isInternalSchema(schemaFileInfo.name, schemaFileInfo.schemaFileId)) {
1792
- logger$8(`STEP 3: skipping internal schema file: ${schemaFileInfo.filePath}`);
1559
+ logger$4(`STEP 3: skipping internal schema file: ${schemaFileInfo.filePath}`);
1793
1560
  continue;
1794
1561
  }
1795
1562
  try {
1796
- logger$8(`STEP 3: processing schema file: ${schemaFileInfo.name} from ${schemaFileInfo.filePath}`);
1563
+ logger$4(`STEP 3: processing schema file: ${schemaFileInfo.name} from ${schemaFileInfo.filePath}`);
1797
1564
  const content = await BaseFileManager.readFileAsString(schemaFileInfo.filePath);
1798
1565
  const schemaFile = JSON.parse(content);
1799
1566
  // Import this schema to database (mark as non-draft since it's in a file)
@@ -1813,68 +1580,12 @@ async function loadAllSchemasFromDb() {
1813
1580
  processedSchemaNames.add(schemaFileInfo.name);
1814
1581
  }
1815
1582
  catch (error) {
1816
- logger$8(`Error loading schema file ${schemaFileInfo.filePath}:`, error);
1583
+ logger$4(`Error loading schema file ${schemaFileInfo.filePath}:`, error);
1817
1584
  }
1818
1585
  }
1819
1586
  }
1820
1587
  return result;
1821
1588
  }
1822
- /**
1823
- * Migration helper: Migrate existing file-based schemas to the database
1824
- * This function should be called once to migrate existing schema files to the new database-first approach
1825
- * All existing schemas will be marked as published (isDraft = false) since they already exist in files
1826
- * @returns Number of schemas migrated
1827
- */
1828
- async function migrateFileSchemasToDb() {
1829
- const db = BaseDb.getAppDb();
1830
- if (!db) {
1831
- throw new Error('Database not found');
1832
- }
1833
- logger$8('Starting migration of file-based schemas to database');
1834
- // Get all complete schema files
1835
- const completeSchemas = await listCompleteSchemaFiles();
1836
- let migratedCount = 0;
1837
- for (const schemaFileInfo of completeSchemas) {
1838
- try {
1839
- // Read the schema file
1840
- const content = await BaseFileManager.readFileAsString(schemaFileInfo.filePath);
1841
- const schemaFile = JSON.parse(content);
1842
- if (!schemaFile.$schema || !schemaFile.metadata?.name) {
1843
- logger$8(`Skipping invalid schema file: ${schemaFileInfo.filePath}`);
1844
- continue;
1845
- }
1846
- const schemaName = schemaFile.metadata.name;
1847
- // Check if schema already exists in database
1848
- const existingSchemas = await db
1849
- .select()
1850
- .from(schemas)
1851
- .where(eq(schemas.name, schemaName))
1852
- .limit(1);
1853
- // Only migrate if it doesn't exist or if existing record doesn't have schemaFileId
1854
- if (existingSchemas.length === 0 || !existingSchemas[0].schemaFileId) {
1855
- // Add schema to database as published (isDraft = false)
1856
- await addSchemaToDb({
1857
- name: schemaName,
1858
- version: schemaFile.version,
1859
- createdAt: new Date(schemaFile.metadata.createdAt).getTime(),
1860
- updatedAt: new Date(schemaFile.metadata.updatedAt).getTime(),
1861
- }, schemaFile.id, // schemaFileId
1862
- JSON.stringify(schemaFile, null, 2), // schemaData
1863
- false);
1864
- migratedCount++;
1865
- logger$8(`Migrated schema: ${schemaName} v${schemaFile.version}`);
1866
- }
1867
- else {
1868
- logger$8(`Schema ${schemaName} already exists in database, skipping`);
1869
- }
1870
- }
1871
- catch (error) {
1872
- logger$8(`Error migrating schema file ${schemaFileInfo.filePath}:`, error);
1873
- }
1874
- }
1875
- logger$8(`Migration complete: ${migratedCount} schemas migrated`);
1876
- return migratedCount;
1877
- }
1878
1589
  /**
1879
1590
  * Extract the schema name from a schemaId string
1880
1591
  * @param schemaId - Schema ID in the format `${schemaName}-${schemaVersion}`
@@ -1891,19 +1602,12 @@ function getSchemaNameFromId(schemaId) {
1891
1602
 
1892
1603
  var schema = /*#__PURE__*/Object.freeze({
1893
1604
  __proto__: null,
1894
- createSchema: createSchema,
1895
- deleteSchema: deleteSchema,
1896
- filterLatestSchemas: filterLatestSchemas,
1897
- findSchemaByName: findSchemaByName,
1898
1605
  getLatestSchemaVersion: getLatestSchemaVersion,
1899
1606
  getSchemaNameFromId: getSchemaNameFromId,
1900
1607
  listCompleteSchemaFiles: listCompleteSchemaFiles,
1901
1608
  listLatestSchemaFiles: listLatestSchemaFiles,
1902
1609
  listSchemaFiles: listSchemaFiles,
1903
- loadAllSchemasFromDb: loadAllSchemasFromDb,
1904
- migrateFileSchemasToDb: migrateFileSchemasToDb,
1905
- readSchema: readSchema,
1906
- updateSchema: updateSchema
1610
+ loadAllSchemasFromDb: loadAllSchemasFromDb
1907
1611
  });
1908
1612
 
1909
1613
  function toBytes(data) {
@@ -1925,7 +1629,7 @@ const getDeterministicIdsWithPrefix = (prefix) => {
1925
1629
  return (suffix) => bytesToHex(prefixHash.clone().update(utf8ToBytes(suffix)).digest()).slice(0, 10);
1926
1630
  };
1927
1631
 
1928
- const logger$7 = debug('seedSdk:imports:json');
1632
+ const logger$3 = debug('seedSdk:imports:json');
1929
1633
  /**
1930
1634
  * Get refValueType from a property object with case-insensitive key lookup.
1931
1635
  * Handles refValueType, refvaluetype, ref_value_type, elementType, and legacy items.type / items.Type.
@@ -1992,119 +1696,6 @@ function getRefValueType(prop) {
1992
1696
  }
1993
1697
  return undefined;
1994
1698
  }
1995
- /**
1996
- * Verify that properties are persisted to the database for a given model
1997
- * This is important in browser environments where database writes may not be immediately visible
1998
- * @param db - Database instance
1999
- * @param modelId - Database ID of the model
2000
- * @param modelName - Name of the model (for logging)
2001
- * @param maxRetries - Maximum number of retry attempts
2002
- * @param retryDelay - Delay between retries in milliseconds
2003
- * @returns Promise that resolves when properties are found, or rejects if not found after max retries
2004
- */
2005
- const verifyPropertiesPersisted = async (db, modelId, modelName, maxRetries = 10, retryDelay = 100) => {
2006
- const _mod_1 = await import('./index-C0SetTd1.js');
2007
- const _ns_1 = _mod_1.bj;
2008
- const modelSchemaMod = _ns_1;
2009
- const { properties: propertiesTable } = modelSchemaMod;
2010
- const drizzleMod = await import('drizzle-orm');
2011
- const { eq } = drizzleMod;
2012
- for (let attempt = 0; attempt < maxRetries; attempt++) {
2013
- const props = await db
2014
- .select()
2015
- .from(propertiesTable)
2016
- .where(eq(propertiesTable.modelId, modelId))
2017
- .limit(1);
2018
- if (props.length > 0) {
2019
- logger$7(`Verified properties exist for model "${modelName}" (modelId: ${modelId}) after ${attempt + 1} attempt(s)`);
2020
- return;
2021
- }
2022
- if (attempt < maxRetries - 1) {
2023
- logger$7(`Properties not yet visible for model "${modelName}" (modelId: ${modelId}), retrying in ${retryDelay}ms (attempt ${attempt + 1}/${maxRetries})`);
2024
- await new Promise(resolve => setTimeout(resolve, retryDelay));
2025
- }
2026
- }
2027
- throw new Error(`Properties not found for model "${modelName}" (modelId: ${modelId}) after ${maxRetries} attempts. This may indicate a database write issue in the browser environment.`);
2028
- };
2029
- /**
2030
- * Compare two schema files structurally, ignoring metadata timestamps
2031
- * This is used to determine if an existing schema file matches the schema being imported
2032
- * @param schema1 - First schema to compare
2033
- * @param schema2 - Second schema to compare
2034
- * @returns true if schemas are structurally equivalent, false otherwise
2035
- */
2036
- function compareSchemasStructurally(schema1, schema2) {
2037
- // Compare basic fields
2038
- if (schema1.$schema !== schema2.$schema)
2039
- return false;
2040
- if (schema1.version !== schema2.version)
2041
- return false;
2042
- if (schema1.id !== schema2.id)
2043
- return false;
2044
- // Compare metadata (ignoring timestamps)
2045
- if (schema1.metadata?.name !== schema2.metadata?.name)
2046
- return false;
2047
- // Compare models structure
2048
- const models1 = schema1.models || {};
2049
- const models2 = schema2.models || {};
2050
- const modelNames1 = Object.keys(models1).sort();
2051
- const modelNames2 = Object.keys(models2).sort();
2052
- if (modelNames1.length !== modelNames2.length)
2053
- return false;
2054
- if (!modelNames1.every((name, i) => name === modelNames2[i]))
2055
- return false;
2056
- // Compare each model's structure
2057
- for (const modelName of modelNames1) {
2058
- const model1 = models1[modelName];
2059
- const model2 = models2[modelName];
2060
- // Compare model IDs if both have them
2061
- if (model1.id !== model2.id)
2062
- return false;
2063
- // Compare properties
2064
- const props1 = model1.properties || {};
2065
- const props2 = model2.properties || {};
2066
- const propNames1 = Object.keys(props1).sort();
2067
- const propNames2 = Object.keys(props2).sort();
2068
- if (propNames1.length !== propNames2.length)
2069
- return false;
2070
- if (!propNames1.every((name, i) => name === propNames2[i]))
2071
- return false;
2072
- // Compare each property's structure
2073
- for (const propName of propNames1) {
2074
- const prop1 = props1[propName];
2075
- const prop2 = props2[propName];
2076
- // Compare property IDs if both have them
2077
- if (prop1.id !== prop2.id)
2078
- return false;
2079
- // Compare property types
2080
- if (prop1.type !== prop2.type)
2081
- return false;
2082
- // Compare other relevant fields (ref, refValueType for List, etc.)
2083
- if (prop1.ref !== prop2.ref)
2084
- return false;
2085
- const refVal1 = prop1.refValueType ?? prop1.items?.type;
2086
- const refVal2 = prop2.refValueType ?? prop2.items?.type;
2087
- if (refVal1 !== refVal2)
2088
- return false;
2089
- const model1 = prop1.ref ?? prop1.items?.model;
2090
- const model2 = prop2.ref ?? prop2.items?.model;
2091
- if (model1 !== model2)
2092
- return false;
2093
- }
2094
- }
2095
- // Compare enums
2096
- const enums1 = schema1.enums || {};
2097
- const enums2 = schema2.enums || {};
2098
- const enumNames1 = Object.keys(enums1).sort();
2099
- const enumNames2 = Object.keys(enums2).sort();
2100
- if (enumNames1.length !== enumNames2.length)
2101
- return false;
2102
- if (!enumNames1.every((name, i) => name === enumNames2[i]))
2103
- return false;
2104
- // Note: We don't compare migrations as they're historical records
2105
- // and may differ even for the same schema structure
2106
- return true;
2107
- }
2108
1699
  /**
2109
1700
  * Create a canonical JSON string for schema comparison (ignores IDs and timestamps).
2110
1701
  * Used to detect if schema content has changed via string comparison of schemaData.
@@ -2319,7 +1910,7 @@ const readCompleteSchemaFile = async (filePath) => {
2319
1910
  return schema;
2320
1911
  }
2321
1912
  catch (error) {
2322
- logger$7(`Could not read schema file ${filePath}:`, error);
1913
+ logger$3(`Could not read schema file ${filePath}:`, error);
2323
1914
  return undefined;
2324
1915
  }
2325
1916
  };
@@ -2384,7 +1975,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2384
1975
  if (parsed.$schema && parsed.metadata?.name) {
2385
1976
  // It's already a complete schema format - preserve it (id may be missing, will be generated)
2386
1977
  originalSchemaFile = parsed;
2387
- logger$7(`Input is complete schema format (${originalSchemaFile.id ? `preserving ID: ${originalSchemaFile.id}` : 'id will be generated'})`);
1978
+ logger$3(`Input is complete schema format (${originalSchemaFile.id ? `preserving ID: ${originalSchemaFile.id}` : 'id will be generated'})`);
2388
1979
  }
2389
1980
  }
2390
1981
  catch {
@@ -2396,7 +1987,6 @@ async function importSchema(importFilePathOrContents, version, options) {
2396
1987
  }
2397
1988
  // Use original schema file if available, otherwise transform from import format
2398
1989
  let schemaFile;
2399
- let replacingStoredFile = false;
2400
1990
  if (originalSchemaFile) {
2401
1991
  schemaFile = originalSchemaFile;
2402
1992
  // Normalize models if provided as array (some tools output array format)
@@ -2410,9 +2000,9 @@ async function importSchema(importFilePathOrContents, version, options) {
2410
2000
  // Check DB for existing schema by name+version (same as minimal path)
2411
2001
  const db = BaseDb.getAppDb();
2412
2002
  if (db) {
2413
- const _mod_2 = await import('./index-C0SetTd1.js');
2414
- const _ns_2 = _mod_2.bl;
2415
- const schemaSchemaMod = _ns_2;
2003
+ const _mod_0 = await import('./index-Dx_GTdyQ.js');
2004
+ const _ns_0 = _mod_0.bc;
2005
+ const schemaSchemaMod = _ns_0;
2416
2006
  const { schemas: schemasTable } = schemaSchemaMod;
2417
2007
  const drizzleMod = await import('drizzle-orm');
2418
2008
  const { eq, and, desc } = drizzleMod;
@@ -2424,16 +2014,16 @@ async function importSchema(importFilePathOrContents, version, options) {
2424
2014
  .limit(1);
2425
2015
  if (existingByName.length > 0 && existingByName[0].schemaData) {
2426
2016
  const existing = existingByName[0];
2427
- logger$7(`Idempotency: found existing schema by name+version: ${schemaFile.metadata.name} v${schemaFile.version ?? version}`);
2017
+ logger$3(`Idempotency: found existing schema by name+version: ${schemaFile.metadata.name} v${schemaFile.version ?? version}`);
2428
2018
  const existingSchema = JSON.parse(existing.schemaData);
2429
2019
  const contentMatches = compareSchemaContent(schemaFile, existingSchema);
2430
- logger$7(`Idempotency: compareSchemaContent=${contentMatches} for ${schemaFile.metadata.name}`);
2020
+ logger$3(`Idempotency: compareSchemaContent=${contentMatches} for ${schemaFile.metadata.name}`);
2431
2021
  if (contentMatches) {
2432
2022
  if (existing.schemaFileId) {
2433
2023
  const workingDir = BaseFileManager.getWorkingDir();
2434
2024
  const existingFilePath = getSchemaFilePath(workingDir, schemaFile.metadata.name, schemaFile.version ?? version, existing.schemaFileId);
2435
2025
  if (await BaseFileManager.pathExists(existingFilePath)) {
2436
- logger$7(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content, loading existing file`);
2026
+ logger$3(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content, loading existing file`);
2437
2027
  return await loadSchemaFromFile(existingFilePath);
2438
2028
  }
2439
2029
  await BaseFileManager.createDirIfNotExists(workingDir);
@@ -2441,7 +2031,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2441
2031
  await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
2442
2032
  return await loadSchemaFromFile(existingFilePath);
2443
2033
  }
2444
- logger$7(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content (no schemaFileId), using DB`);
2034
+ logger$3(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content (no schemaFileId), using DB`);
2445
2035
  return '';
2446
2036
  }
2447
2037
  }
@@ -2457,7 +2047,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2457
2047
  // processSchemaFiles runs multiple times (React StrictMode, app restarts).
2458
2048
  if (!schemaFile.id) {
2459
2049
  schemaFile.id = await getDeterministicSchemaFileId(schemaFile);
2460
- logger$7(`Generated deterministic schema ID for ${schemaFile.metadata.name}:`, schemaFile.id);
2050
+ logger$3(`Generated deterministic schema ID for ${schemaFile.metadata.name}:`, schemaFile.id);
2461
2051
  }
2462
2052
  // A file with this schemaFileId and version is reused only when its content matches. A pinned id
2463
2053
  // (one the schema file sets) keeps the same path when the content changes.
@@ -2466,7 +2056,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2466
2056
  if (await BaseFileManager.pathExists(existingFilePath)) {
2467
2057
  const storedSchema = await readCompleteSchemaFile(existingFilePath);
2468
2058
  if (storedSchema && compareSchemaContent(schemaFile, storedSchema)) {
2469
- logger$7(`Schema file already exists with schemaFileId ${schemaFile.id} and the same content, loading it`);
2059
+ logger$3(`Schema file already exists with schemaFileId ${schemaFile.id} and the same content, loading it`);
2470
2060
  return await loadSchemaFromFile(existingFilePath);
2471
2061
  }
2472
2062
  if (!options.replaceStoredFile) {
@@ -2475,7 +2065,6 @@ async function importSchema(importFilePathOrContents, version, options) {
2475
2065
  }
2476
2066
  console.warn(`[seed] schema ${schemaFile.metadata.name} v${schemaFile.version}: content changed but id ` +
2477
2067
  `${schemaFile.id} and version did not; replacing the stored schema file. Bump "version" when the schema changes.`);
2478
- replacingStoredFile = true;
2479
2068
  }
2480
2069
  // Generate missing model and property IDs.
2481
2070
  // Use deterministic IDs (from schema content hash) so addModelsToDb finds existing
@@ -2485,12 +2074,12 @@ async function importSchema(importFilePathOrContents, version, options) {
2485
2074
  for (const [modelName, model] of Object.entries(schemaFile.models || {})) {
2486
2075
  if (!model.id) {
2487
2076
  model.id = getDeterministicId(modelName);
2488
- logger$7(`Generated deterministic model ID for ${modelName}:`, model.id);
2077
+ logger$3(`Generated deterministic model ID for ${modelName}:`, model.id);
2489
2078
  }
2490
2079
  for (const [propName, prop] of Object.entries(model.properties || {})) {
2491
2080
  if (!prop.id) {
2492
2081
  prop.id = getDeterministicId(modelName + propName);
2493
- logger$7(`Generated deterministic property ID for ${modelName}.${propName}:`, prop.id);
2082
+ logger$3(`Generated deterministic property ID for ${modelName}.${propName}:`, prop.id);
2494
2083
  }
2495
2084
  }
2496
2085
  }
@@ -2502,9 +2091,9 @@ async function importSchema(importFilePathOrContents, version, options) {
2502
2091
  // For minimal imports: check DB for existing schema before creating new file
2503
2092
  const db = BaseDb.getAppDb();
2504
2093
  if (db) {
2505
- const _mod_3 = await import('./index-C0SetTd1.js');
2506
- const _ns_3 = _mod_3.bl;
2507
- const schemaSchemaMod = _ns_3;
2094
+ const _mod_1 = await import('./index-Dx_GTdyQ.js');
2095
+ const _ns_1 = _mod_1.bc;
2096
+ const schemaSchemaMod = _ns_1;
2508
2097
  const { schemas: schemasTable } = schemaSchemaMod;
2509
2098
  const drizzleMod = await import('drizzle-orm');
2510
2099
  const { eq, and, desc } = drizzleMod;
@@ -2526,14 +2115,14 @@ async function importSchema(importFilePathOrContents, version, options) {
2526
2115
  const workingDir = BaseFileManager.getWorkingDir();
2527
2116
  const existingFilePath = getSchemaFilePath(workingDir, importData.name, version, existing.schemaFileId);
2528
2117
  if (await BaseFileManager.pathExists(existingFilePath)) {
2529
- logger$7(`Schema ${importData.name} v${version} already exists with same content, loading existing file`);
2118
+ logger$3(`Schema ${importData.name} v${version} already exists with same content, loading existing file`);
2530
2119
  return await loadSchemaFromFile(existingFilePath);
2531
2120
  }
2532
2121
  // File missing but schemaData exists - restore file from schemaData
2533
2122
  await BaseFileManager.createDirIfNotExists(workingDir);
2534
2123
  await BaseFileManager.saveFile(existingFilePath, existing.schemaData);
2535
2124
  await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
2536
- logger$7(`Restored schema file from schemaData for ${importData.name} v${version}`);
2125
+ logger$3(`Restored schema file from schemaData for ${importData.name} v${version}`);
2537
2126
  return await loadSchemaFromFile(existingFilePath);
2538
2127
  }
2539
2128
  // No schemaFileId - restore file from schemaData using id from parsed schema
@@ -2544,10 +2133,10 @@ async function importSchema(importFilePathOrContents, version, options) {
2544
2133
  await BaseFileManager.createDirIfNotExists(workingDir);
2545
2134
  await BaseFileManager.saveFile(existingFilePath, existing.schemaData);
2546
2135
  await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
2547
- logger$7(`Restored schema file from schemaData for ${importData.name} v${version}`);
2136
+ logger$3(`Restored schema file from schemaData for ${importData.name} v${version}`);
2548
2137
  return await loadSchemaFromFile(existingFilePath);
2549
2138
  }
2550
- logger$7(`Schema ${importData.name} v${version} already exists with same content (no id), using DB`);
2139
+ logger$3(`Schema ${importData.name} v${version} already exists with same content (no id), using DB`);
2551
2140
  return '';
2552
2141
  }
2553
2142
  // Content differs - create new version
@@ -2558,7 +2147,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2558
2147
  .orderBy(desc(schemasTable.version))
2559
2148
  .limit(1);
2560
2149
  const newVersion = latestVersionRows.length > 0 ? latestVersionRows[0].version + 1 : version;
2561
- logger$7(`Schema ${importData.name} content changed, creating new version v${newVersion}`);
2150
+ logger$3(`Schema ${importData.name} content changed, creating new version v${newVersion}`);
2562
2151
  schemaFile = transformImportToSchemaFile(importData, newVersion);
2563
2152
  version = newVersion;
2564
2153
  }
@@ -2584,7 +2173,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2584
2173
  // Check if this is an internal SDK schema (should not create files in app directory)
2585
2174
  const isInternal = isInternalSchema(schemaFile.metadata.name, schemaFile.id);
2586
2175
  if (isInternal) {
2587
- logger$7(`Skipping file creation for internal schema: ${schemaFile.metadata.name}`);
2176
+ logger$3(`Skipping file creation for internal schema: ${schemaFile.metadata.name}`);
2588
2177
  // For internal schemas, just load to database and store, don't create file
2589
2178
  // Extract schema name and version
2590
2179
  const schemaName = schemaFile.metadata?.name;
@@ -2641,7 +2230,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2641
2230
  // Use fixed internal schema ID if missing (never generate for internal)
2642
2231
  if (!schemaFile.id) {
2643
2232
  schemaFile.id = INTERNAL_SCHEMA_IDS[0];
2644
- logger$7('Using fixed internal schema ID:', schemaFile.id);
2233
+ logger$3('Using fixed internal schema ID:', schemaFile.id);
2645
2234
  }
2646
2235
  // Extract schemaFileIds from JSON file and generate missing ones BEFORE creating models
2647
2236
  // This ensures Model instances are created with correct IDs
@@ -2651,7 +2240,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2651
2240
  // Generate model ID if missing
2652
2241
  if (!model.id) {
2653
2242
  model.id = generateId();
2654
- logger$7(`Generated model ID for ${modelName}:`, model.id);
2243
+ logger$3(`Generated model ID for ${modelName}:`, model.id);
2655
2244
  // Update the schemaFile object so it's included in schemaData
2656
2245
  schemaFile.models[modelName].id = model.id;
2657
2246
  }
@@ -2661,7 +2250,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2661
2250
  // Generate property ID if missing
2662
2251
  if (!prop.id) {
2663
2252
  prop.id = generateId();
2664
- logger$7(`Generated property ID for ${modelName}.${propName}:`, prop.id);
2253
+ logger$3(`Generated property ID for ${modelName}.${propName}:`, prop.id);
2665
2254
  // Update the schemaFile object so it's included in schemaData
2666
2255
  schemaFile.models[modelName].properties[propName].id = prop.id;
2667
2256
  }
@@ -2675,7 +2264,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2675
2264
  // addModelsToDb below writes their rows; the models adopt them once it has run.
2676
2265
  const rowsWritten = createRowsWrittenSignal();
2677
2266
  const modelDefinitions = await createModelsFromJson(importDataForInternal, modelFileIds, propertyFileIds, rowsWritten.promise);
2678
- logger$7('loadSchemaFromFile (internal) - modelDefinitions length:', Object.keys(modelDefinitions).length);
2267
+ logger$3('loadSchemaFromFile (internal) - modelDefinitions length:', Object.keys(modelDefinitions).length);
2679
2268
  // Convert schema file metadata to schema input for database
2680
2269
  const schemaInput = {
2681
2270
  name: schemaName,
@@ -2685,9 +2274,9 @@ async function importSchema(importFilePathOrContents, version, options) {
2685
2274
  updatedAt: new Date(schemaFile.metadata.updatedAt).getTime(),
2686
2275
  };
2687
2276
  // Use dynamic import to break circular dependency
2688
- const _mod_4 = await import('./index-C0SetTd1.js');
2689
- const _ns_4 = _mod_4.bo;
2690
- const dbMod = _ns_4;
2277
+ const _mod_2 = await import('./index-Dx_GTdyQ.js');
2278
+ const _ns_2 = _mod_2.bf;
2279
+ const dbMod = _ns_2;
2691
2280
  const { addSchemaToDb, addModelsToDb } = dbMod;
2692
2281
  // Try to add schema and models to database if database is available
2693
2282
  try {
@@ -2707,13 +2296,13 @@ async function importSchema(importFilePathOrContents, version, options) {
2707
2296
  });
2708
2297
  // Verify expected models are linked (single attempt - addModelsToDb already confirmed)
2709
2298
  const expectedModelNames = Object.keys(schemaFile.models || {});
2710
- const _mod_5 = await import('./index-C0SetTd1.js');
2711
- const _ns_5 = _mod_5.bm;
2712
- const modelSchemaSchemaMod = _ns_5;
2299
+ const _mod_3 = await import('./index-Dx_GTdyQ.js');
2300
+ const _ns_3 = _mod_3.bd;
2301
+ const modelSchemaSchemaMod = _ns_3;
2713
2302
  const { modelSchemas } = modelSchemaSchemaMod;
2714
- const _mod_6 = await import('./index-C0SetTd1.js');
2715
- const _ns_6 = _mod_6.bj;
2716
- const modelSchemaMod = _ns_6;
2303
+ const _mod_4 = await import('./index-Dx_GTdyQ.js');
2304
+ const _ns_4 = _mod_4.ba;
2305
+ const modelSchemaMod = _ns_4;
2717
2306
  const { models: modelsTable } = modelSchemaMod;
2718
2307
  const drizzleMod = await import('drizzle-orm');
2719
2308
  const { eq, and, isNull } = drizzleMod;
@@ -2791,7 +2380,6 @@ async function importSchema(importFilePathOrContents, version, options) {
2791
2380
  }
2792
2381
  }
2793
2382
  }
2794
- // Skip expensive verifyPropertiesPersisted - addModelsToDb already persisted; verification was for browser quirks
2795
2383
  // Skip "After properties" block for internal schema: addSchemaToDb/addModelsToDb already stored
2796
2384
  // correct schemaData. The per-model ID sync (6 model + 6 property selects + schema update) is
2797
2385
  // redundant during init and causes slow OPFS writes. Ad-hoc loadSchemaFromFile uses the same
@@ -2801,7 +2389,7 @@ async function importSchema(importFilePathOrContents, version, options) {
2801
2389
  }
2802
2390
  catch (dbError) {
2803
2391
  // Database not available - log warning but continue
2804
- logger$7('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
2392
+ logger$3('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
2805
2393
  }
2806
2394
  finally {
2807
2395
  rowsWritten.settle();
@@ -2809,78 +2397,20 @@ async function importSchema(importFilePathOrContents, version, options) {
2809
2397
  // Models are now Model instances, no registration needed
2810
2398
  // They should be created via Model.create() and are accessible via Model static methods
2811
2399
  for (const [modelName] of Object.entries(modelDefinitions)) {
2812
- logger$7('loadSchemaFromFile (internal) - model available:', modelName);
2400
+ logger$3('loadSchemaFromFile (internal) - model available:', modelName);
2813
2401
  }
2814
2402
  // Schema is now saved to database
2815
2403
  // useSchemas hook will pick it up via database queries
2816
2404
  return ''; // Return empty string to indicate no file was created
2817
2405
  }
2818
2406
  const workingDir = BaseFileManager.getWorkingDir();
2819
- const path = BaseFileManager.getPathModule();
2820
2407
  // Ensure schema ID is defined (should always be set by this point, but check for safety)
2821
2408
  if (!schemaFile.id) {
2822
2409
  schemaFile.id = generateId();
2823
- logger$7('Generated schema ID before file path creation:', schemaFile.id);
2410
+ logger$3('Generated schema ID before file path creation:', schemaFile.id);
2824
2411
  }
2825
2412
  // Get the target file path using ID-based naming (preferred)
2826
2413
  const filePath = getSchemaFilePath(workingDir, schemaFile.metadata.name, version, schemaFile.id);
2827
- // Check if schema already exists
2828
- const exists = !replacingStoredFile && (await BaseFileManager.pathExists(filePath));
2829
- if (exists) {
2830
- // If we have a file path and the import file is the same as the target file,
2831
- // and it's already a complete schema, just load it without writing
2832
- if (importFilePath) {
2833
- const normalizedImportPath = path.resolve(importFilePath);
2834
- const normalizedTargetPath = path.resolve(filePath);
2835
- if (normalizedImportPath === normalizedTargetPath) {
2836
- // Check if the file is already a complete schema
2837
- try {
2838
- const content = await BaseFileManager.readFileAsString(importFilePath);
2839
- const data = JSON.parse(content);
2840
- if (data.$schema) {
2841
- // File is already a complete schema, just load it
2842
- logger$7(`Schema file ${filePath} already exists and is complete, loading it`);
2843
- return await loadSchemaFromFile(filePath);
2844
- }
2845
- }
2846
- catch {
2847
- // If we can't read the file, proceed with the error
2848
- }
2849
- }
2850
- }
2851
- // File exists - check if it matches the schema we're trying to import
2852
- try {
2853
- const existingContent = await BaseFileManager.readFileAsString(filePath);
2854
- const existingSchema = JSON.parse(existingContent);
2855
- // Verify it's a complete schema file
2856
- if (existingSchema.$schema) {
2857
- // Compare schemas structurally
2858
- if (compareSchemasStructurally(schemaFile, existingSchema)) {
2859
- // Schemas match - just load the existing file
2860
- logger$7(`Schema ${schemaFile.metadata.name} v${version} already exists with matching content, loading it`);
2861
- return await loadSchemaFromFile(filePath);
2862
- }
2863
- else {
2864
- // Schemas don't match - throw error to prevent data loss
2865
- throw new Error(`Schema ${schemaFile.metadata.name} v${version} already exists with different content. ` +
2866
- `To update the schema, delete the existing file first or use a different version.`);
2867
- }
2868
- }
2869
- else {
2870
- // File exists but is not a complete schema - this shouldn't happen with ID-based naming
2871
- // but we'll treat it as a conflict
2872
- throw new Error(`Schema ${schemaFile.metadata.name} v${version} already exists but file is not a complete schema`);
2873
- }
2874
- }
2875
- catch (error) {
2876
- // If error is already our custom error, re-throw it
2877
- if (error instanceof Error && error.message.includes('already exists')) {
2878
- throw error;
2879
- }
2880
- // If we can't read/parse the existing file, throw a generic error
2881
- throw new Error(`Schema ${schemaFile.metadata.name} v${version} already exists but could not be read: ${error instanceof Error ? error.message : String(error)}`);
2882
- }
2883
- }
2884
2414
  // Ensure working directory exists
2885
2415
  await BaseFileManager.createDirIfNotExists(workingDir);
2886
2416
  // Write schema to file
@@ -2913,9 +2443,9 @@ async function applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, prope
2913
2443
  createdAt: new Date(schemaFile.metadata.createdAt).getTime(),
2914
2444
  updatedAt: new Date(schemaFile.metadata.updatedAt).getTime(),
2915
2445
  };
2916
- const _mod_7 = await import('./index-C0SetTd1.js');
2917
- const _ns_7 = _mod_7.bo;
2918
- const dbMod = _ns_7;
2446
+ const _mod_5 = await import('./index-Dx_GTdyQ.js');
2447
+ const _ns_5 = _mod_5.bf;
2448
+ const dbMod = _ns_5;
2919
2449
  const { addSchemaToDb, addModelsToDb } = dbMod;
2920
2450
  const db = BaseDb.getAppDb();
2921
2451
  if (!db) {
@@ -2945,9 +2475,9 @@ async function applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, prope
2945
2475
  * draft (its edits aren't the app's to undo) or a newer version than schemaFile.
2946
2476
  */
2947
2477
  async function getModelsDroppedFromStoredSchema(db, schemaFile) {
2948
- const _mod_8 = await import('./index-C0SetTd1.js');
2949
- const _ns_8 = _mod_8.bl;
2950
- const { schemas: schemasTable } = _ns_8;
2478
+ const _mod_6 = await import('./index-Dx_GTdyQ.js');
2479
+ const _ns_6 = _mod_6.bc;
2480
+ const { schemas: schemasTable } = _ns_6;
2951
2481
  const { eq } = await import('drizzle-orm');
2952
2482
  const rows = await db
2953
2483
  .select({ version: schemasTable.version, isDraft: schemasTable.isDraft, schemaData: schemasTable.schemaData })
@@ -2973,12 +2503,12 @@ async function getModelsDroppedFromStoredSchema(db, schemaFile) {
2973
2503
  }
2974
2504
  /** Delete the model_schemas rows linking the named models to the schema. The models and their items stay. */
2975
2505
  async function unlinkModelsFromSchema(db, schemaId, modelNames) {
2976
- const _mod_9 = await import('./index-C0SetTd1.js');
2977
- const _ns_9 = _mod_9.bm;
2978
- const { modelSchemas } = _ns_9;
2979
- const _mod_10 = await import('./index-C0SetTd1.js');
2980
- const _ns_10 = _mod_10.bj;
2981
- const { models: modelsTable } = _ns_10;
2506
+ const _mod_7 = await import('./index-Dx_GTdyQ.js');
2507
+ const _ns_7 = _mod_7.bd;
2508
+ const { modelSchemas } = _ns_7;
2509
+ const _mod_8 = await import('./index-Dx_GTdyQ.js');
2510
+ const _ns_8 = _mod_8.ba;
2511
+ const { models: modelsTable } = _ns_8;
2982
2512
  const { and, eq, inArray } = await import('drizzle-orm');
2983
2513
  const links = await db
2984
2514
  .select({ id: modelSchemas.id })
@@ -2988,7 +2518,7 @@ async function unlinkModelsFromSchema(db, schemaId, modelNames) {
2988
2518
  if (links.length === 0)
2989
2519
  return;
2990
2520
  await db.delete(modelSchemas).where(inArray(modelSchemas.id, links.map((link) => link.id)));
2991
- logger$7(`Unlinked models dropped from the schema (schema id ${schemaId}): ${modelNames.join(', ')}`);
2521
+ logger$3(`Unlinked models dropped from the schema (schema id ${schemaId}): ${modelNames.join(', ')}`);
2992
2522
  }
2993
2523
  /**
2994
2524
  * Sync a canonical schema from a file path or inlined object to the database.
@@ -3091,7 +2621,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
3091
2621
  // Generate schema ID if missing (before creating schemaInput)
3092
2622
  if (!schemaFile.id) {
3093
2623
  schemaFile.id = generateId();
3094
- logger$7('Generated schema ID for schema file:', schemaFile.id);
2624
+ logger$3('Generated schema ID for schema file:', schemaFile.id);
3095
2625
  }
3096
2626
  // Extract schemaFileIds from JSON file and generate missing ones BEFORE creating models
3097
2627
  // This ensures Model instances are created with correct IDs
@@ -3101,7 +2631,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
3101
2631
  // Generate model ID if missing
3102
2632
  if (!model.id) {
3103
2633
  model.id = generateId();
3104
- logger$7(`Generated model ID for ${modelName}:`, model.id);
2634
+ logger$3(`Generated model ID for ${modelName}:`, model.id);
3105
2635
  // Update the schemaFile object so it's included in schemaData
3106
2636
  schemaFile.models[modelName].id = model.id;
3107
2637
  }
@@ -3111,7 +2641,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
3111
2641
  // Generate property ID if missing
3112
2642
  if (!prop.id) {
3113
2643
  prop.id = generateId();
3114
- logger$7(`Generated property ID for ${modelName}.${propName}:`, prop.id);
2644
+ logger$3(`Generated property ID for ${modelName}.${propName}:`, prop.id);
3115
2645
  // Update the schemaFile object so it's included in schemaData
3116
2646
  schemaFile.models[modelName].properties[propName].id = prop.id;
3117
2647
  }
@@ -3125,7 +2655,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
3125
2655
  // applySchemaToDb below writes their rows; the models adopt them once it has run.
3126
2656
  const rowsWritten = createRowsWrittenSignal();
3127
2657
  const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds, rowsWritten.promise);
3128
- logger$7('loadSchemaFromFile - modelDefinitions length:', Object.keys(modelDefinitions).length);
2658
+ logger$3('loadSchemaFromFile - modelDefinitions length:', Object.keys(modelDefinitions).length);
3129
2659
  // Try to add schema and models to database if database is available
3130
2660
  try {
3131
2661
  const db = BaseDb.getAppDb();
@@ -3137,134 +2667,12 @@ const loadSchemaFromFile = async (schemaFilePath) => {
3137
2667
  modelName,
3138
2668
  jsonPropertiesToSchemaProperties(modelName, modelDef, propertyFileIds.get(modelName)),
3139
2669
  ]));
3140
- const { schemaRecord } = await applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, propertyFileIds, propertyDefinitions).finally(rowsWritten.settle);
3141
- // Query the database to get model IDs that were just created
3142
- const _mod_11 = await import('./index-C0SetTd1.js');
3143
- const _ns_11 = _mod_11.bm;
3144
- const modelSchemaSchemaMod = _ns_11;
3145
- const { modelSchemas } = modelSchemaSchemaMod;
3146
- const _mod_12 = await import('./index-C0SetTd1.js');
3147
- const _ns_12 = _mod_12.bj;
3148
- const modelSchemaMod = _ns_12;
3149
- const { models: modelsTable } = modelSchemaMod;
3150
- const drizzleMod = await import('drizzle-orm');
3151
- const { eq } = drizzleMod;
3152
- // Try to find models directly by schemaFileId first (more reliable than join table)
3153
- const seedModelId = modelFileIds.get('Seed');
3154
- let seedModel = [];
3155
- if (seedModelId) {
3156
- // Retry querying for the model until it's visible
3157
- for (let attempt = 0; attempt < 10; attempt++) {
3158
- seedModel = await db
3159
- .select()
3160
- .from(modelsTable)
3161
- .where(eq(modelsTable.schemaFileId, seedModelId))
3162
- .limit(1);
3163
- if (seedModel.length > 0 && seedModel[0].id) {
3164
- break;
3165
- }
3166
- if (attempt < 9) {
3167
- await new Promise(resolve => setTimeout(resolve, 100));
3168
- }
3169
- }
3170
- if (seedModel.length > 0 && seedModel[0].id) {
3171
- await verifyPropertiesPersisted(db, seedModel[0].id, 'Seed', 10, 100);
3172
- }
3173
- }
3174
- // Also verify via join table if schemaRecord.id is available (for completeness)
3175
- if (schemaRecord.id) {
3176
- // Retry querying join table until entries are visible
3177
- let modelLinks = [];
3178
- for (let attempt = 0; attempt < 10; attempt++) {
3179
- modelLinks = await db
3180
- .select({
3181
- modelId: modelSchemas.modelId,
3182
- modelName: modelsTable.name,
3183
- })
3184
- .from(modelSchemas)
3185
- .innerJoin(modelsTable, eq(modelSchemas.modelId, modelsTable.id))
3186
- .where(eq(modelSchemas.schemaId, schemaRecord.id));
3187
- if (modelLinks.length > 0) {
3188
- break;
3189
- }
3190
- if (attempt < 9) {
3191
- await new Promise(resolve => setTimeout(resolve, 100));
3192
- }
3193
- }
3194
- logger$7(`Verifying properties: found ${modelLinks.length} model links for schema ${schemaName} (id: ${schemaRecord.id})`);
3195
- // If we didn't verify via direct lookup, verify via join table
3196
- if (!seedModelId || (seedModel.length === 0 || !seedModel[0].id)) {
3197
- const seedModelLink = modelLinks.find((link) => link.modelName === 'Seed');
3198
- if (seedModelLink && seedModelLink.modelId) {
3199
- logger$7(`Verifying properties for Seed model via join table (modelId: ${seedModelLink.modelId})`);
3200
- await verifyPropertiesPersisted(db, seedModelLink.modelId, 'Seed', 10, 100);
3201
- }
3202
- else if (modelLinks.length > 0 && modelLinks[0].modelId) {
3203
- // Fallback to first model if Seed not found
3204
- logger$7(`Verifying properties for ${modelLinks[0].modelName} model via join table (modelId: ${modelLinks[0].modelId})`);
3205
- await verifyPropertiesPersisted(db, modelLinks[0].modelId, modelLinks[0].modelName || 'unknown', 10, 100);
3206
- }
3207
- }
3208
- }
3209
- // After properties are created (file path), ensure schemaFile has the correct IDs from database
3210
- // Query the database to get the actual schemaFileId values that were used
3211
- // This ensures schemaData matches what's actually in the database
3212
- const _mod_13 = await import('./index-C0SetTd1.js');
3213
- const _ns_13 = _mod_13.bj;
3214
- const modelSchemaMod2 = _ns_13;
3215
- const { properties: propertiesTable } = modelSchemaMod2;
3216
- let schemaFileUpdated = false;
3217
- for (const [modelName, modelFileId] of modelFileIds.entries()) {
3218
- // Get model record to find modelId
3219
- const modelRecords = await db
3220
- .select()
3221
- .from(modelsTable)
3222
- .where(eq(modelsTable.schemaFileId, modelFileId))
3223
- .limit(1);
3224
- if (modelRecords.length > 0) {
3225
- const modelId = modelRecords[0].id;
3226
- // Get all properties for this model from database
3227
- const propertyRecords = await db
3228
- .select()
3229
- .from(propertiesTable)
3230
- .where(eq(propertiesTable.modelId, modelId));
3231
- // Update schemaFile with actual database IDs (only if they differ)
3232
- for (const propRecord of propertyRecords) {
3233
- if (propRecord.schemaFileId && schemaFile.models[modelName]?.properties[propRecord.name]) {
3234
- const currentId = schemaFile.models[modelName].properties[propRecord.name].id;
3235
- if (currentId !== propRecord.schemaFileId) {
3236
- schemaFile.models[modelName].properties[propRecord.name].id = propRecord.schemaFileId;
3237
- logger$7(`Updated schemaFile property ID for ${modelName}.${propRecord.name} from ${currentId} to ${propRecord.schemaFileId}`);
3238
- schemaFileUpdated = true;
3239
- }
3240
- }
3241
- }
3242
- }
3243
- }
3244
- // Always update schemaData to ensure it matches the current schemaFile state
3245
- // This is important even if nothing changed, to ensure consistency
3246
- const updatedSchemaData = JSON.stringify(schemaFile, null, 2);
3247
- // Update the schema record in the database with current schemaData
3248
- const _mod_14 = await import('./index-C0SetTd1.js');
3249
- const _ns_14 = _mod_14.bl;
3250
- const schemaSchemaMod = _ns_14;
3251
- const { schemas: schemasTable } = schemaSchemaMod;
3252
- await db
3253
- .update(schemasTable)
3254
- .set({ schemaData: updatedSchemaData })
3255
- .where(eq(schemasTable.id, schemaRecord.id));
3256
- clearNameMatchLevels();
3257
- if (schemaFileUpdated) {
3258
- logger$7(`Updated schemaData in database with actual property IDs for schema "${schemaName}"`);
3259
- }
3260
- else {
3261
- logger$7(`Verified schemaData in database matches schemaFile for schema "${schemaName}"`);
3262
- }
2670
+ await applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, propertyFileIds, propertyDefinitions).finally(rowsWritten.settle);
3263
2671
  }
3264
2672
  }
3265
2673
  catch (dbError) {
3266
2674
  // Database not available - log warning but continue
3267
- logger$7('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
2675
+ logger$3('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
3268
2676
  }
3269
2677
  finally {
3270
2678
  rowsWritten.settle();
@@ -3272,7 +2680,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
3272
2680
  // Models are now Model instances, no registration needed
3273
2681
  // They should be created via Model.create() and are accessible via Model static methods
3274
2682
  for (const [modelName] of Object.entries(modelDefinitions)) {
3275
- logger$7('loadSchemaFromFile - model available:', modelName);
2683
+ logger$3('loadSchemaFromFile - model available:', modelName);
3276
2684
  }
3277
2685
  return schemaFilePath;
3278
2686
  }
@@ -3372,19 +2780,19 @@ const createRowsWrittenSignal = () => {
3372
2780
  const createModelFromJson = async (modelName, modelDef, schemaName, modelFileId, // Optional modelFileId from JSON file
3373
2781
  propertyFileIds, // Optional map of property names to their file IDs from the JSON file
3374
2782
  persistedBy) => {
3375
- const _mod_15 = await import('./errors-rIWK7gwJ.js');
3376
- const _ns_15 = _mod_15.i;
3377
- const modelMod = _ns_15;
2783
+ const _mod_9 = await import('./errors-D1zHAqjr.js');
2784
+ const _ns_9 = _mod_9.i;
2785
+ const modelMod = _ns_9;
3378
2786
  const { Model } = modelMod;
3379
2787
  const convertedProperties = jsonPropertiesToSchemaProperties(modelName, modelDef, propertyFileIds);
3380
2788
  // Create Model instance with the definition
3381
2789
  // Pass id (schemaFileId) if provided to ensure Model instance uses correct ID
3382
2790
  // Note: indexes and description are ignored - they remain in JSON for schema file format compliance but are not used by Model instances
3383
2791
  if (modelFileId) {
3384
- logger$7(`Creating schema model "${modelName}" with modelFileId: ${modelFileId}`);
2792
+ logger$3(`Creating schema model "${modelName}" with modelFileId: ${modelFileId}`);
3385
2793
  }
3386
2794
  else {
3387
- logger$7(`Warning: Creating schema model "${modelName}" without modelFileId - it will be renamed if duplicates exist`);
2795
+ logger$3(`Warning: Creating schema model "${modelName}" without modelFileId - it will be renamed if duplicates exist`);
3388
2796
  }
3389
2797
  // The schema holds its models once (Model.takeSchemaHold); a model it already holds takes no more.
3390
2798
  const schemaHold = Model.takeSchemaHold(modelFileId);
@@ -3416,7 +2824,7 @@ const createModelsFromJson = async (importData, modelFileIds, propertyFileIds, p
3416
2824
  // Use modelFileId from map (no fallback to modelDef.id as JsonImportSchema doesn't have id property)
3417
2825
  const finalModelFileId = modelFileId;
3418
2826
  if (!finalModelFileId) {
3419
- logger$7(`Warning: No modelFileId found for model "${modelName}" - model will be created without ID`);
2827
+ logger$3(`Warning: No modelFileId found for model "${modelName}" - model will be created without ID`);
3420
2828
  }
3421
2829
  // Get propertyFileIds for this model if available
3422
2830
  const modelPropertyFileIds = propertyFileIds?.get(modelName);
@@ -3431,9 +2839,10 @@ const createModelsFromJson = async (importData, modelFileIds, propertyFileIds, p
3431
2839
  * use correct schemaFileIds - preventing duplicate models (Publication 1, etc.) when
3432
2840
  * processSchemaFiles runs multiple times.
3433
2841
  * @param filePath - Path to the JSON import file
2842
+ * @param persistedBy - See createModelsFromJson
3434
2843
  * @returns ModelDefinitions with Model classes created from the JSON schema
3435
2844
  */
3436
- const createModelsFromJsonFile = async (filePath) => {
2845
+ const createModelsFromJsonFile = async (filePath, persistedBy) => {
3437
2846
  const workingDir = BaseFileManager.getWorkingDir();
3438
2847
  const internalFilePath = filePath.startsWith(workingDir) ? filePath : `${workingDir}/${filePath}`;
3439
2848
  const content = await BaseFileManager.readFileAsString(internalFilePath);
@@ -3462,7 +2871,7 @@ const createModelsFromJsonFile = async (filePath) => {
3462
2871
  }
3463
2872
  }
3464
2873
  }
3465
- return createModelsFromJson(importData, modelFileIds, propertyFileIds);
2874
+ return createModelsFromJson(importData, modelFileIds, propertyFileIds, persistedBy);
3466
2875
  };
3467
2876
 
3468
2877
  var $schema = "https://seedprotocol.org/schemas/data-model/v1";
@@ -3606,7 +3015,7 @@ var SEEDPROTOCOL_Seed_Protocol_v1 = /*#__PURE__*/Object.freeze({
3606
3015
  version: version
3607
3016
  });
3608
3017
 
3609
- const logger$6 = debug('seedSdk:client:actors:processSchemaFiles');
3018
+ const logger$2 = debug('seedSdk:client:actors:processSchemaFiles');
3610
3019
  let processSchemaFilesChain = Promise.resolve();
3611
3020
  function resolveSchemaFilePath(schemaFile) {
3612
3021
  const path = BaseFileManager.getPathModule();
@@ -3634,7 +3043,7 @@ async function resolveSchemaNameFromSource(source) {
3634
3043
  }
3635
3044
  }
3636
3045
  catch (error) {
3637
- logger$6('Could not resolve schema name from path:', source, error);
3046
+ logger$2('Could not resolve schema name from path:', source, error);
3638
3047
  }
3639
3048
  }
3640
3049
  return null;
@@ -3649,7 +3058,7 @@ function userSchemaLoadError(option, source, error) {
3649
3058
  // Schema processing can be slow with syncSchemaFromSource, loadAllSchemasFromDb, and OPFS file I/O
3650
3059
  const PROCESS_SCHEMA_FILES_TIMEOUT_MS = 120000;
3651
3060
  const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3652
- logger$6('processSchemaFiles started');
3061
+ logger$2('processSchemaFiles started');
3653
3062
  let hasResponded = false;
3654
3063
  let timeoutId = null;
3655
3064
  const reportError = (error) => {
@@ -3659,7 +3068,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3659
3068
  clearTimeout(timeoutId);
3660
3069
  timeoutId = null;
3661
3070
  }
3662
- logger$6('processSchemaFiles error:', error);
3071
+ logger$2('processSchemaFiles error:', error);
3663
3072
  sendBack({
3664
3073
  type: 'error',
3665
3074
  error: error instanceof Error ? error : new Error(String(error))
@@ -3673,7 +3082,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3673
3082
  clearTimeout(timeoutId);
3674
3083
  timeoutId = null;
3675
3084
  }
3676
- logger$6('processSchemaFiles completed');
3085
+ logger$2('processSchemaFiles completed');
3677
3086
  sendBack({ type: ClientManagerEvents.PROCESS_SCHEMA_FILES_SUCCESS });
3678
3087
  }
3679
3088
  };
@@ -3685,7 +3094,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3685
3094
  // Schemas written (or confirmed present) this run — skip redundant loadSchemaFromFile later
3686
3095
  const schemasWrittenThisRun = new Set();
3687
3096
  // First, load the internal seed-protocol schema
3688
- logger$6('Loading internal seed-protocol schema');
3097
+ logger$2('Loading internal seed-protocol schema');
3689
3098
  const internalSchemaData = internalSchema;
3690
3099
  const db = BaseDb.getAppDb();
3691
3100
  const internalSchemaExists = db
@@ -3694,21 +3103,21 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3694
3103
  // Always mark internal schema as written so the DB/file loop does not re-apply it
3695
3104
  schemasWrittenThisRun.add(SEED_PROTOCOL_SCHEMA_NAME);
3696
3105
  if (internalSchemaExists) {
3697
- logger$6('Internal seed-protocol schema already in DB, skipping import');
3106
+ logger$2('Internal seed-protocol schema already in DB, skipping import');
3698
3107
  }
3699
3108
  else {
3700
3109
  try {
3701
3110
  // Import the internal schema to database (will create models and add to store)
3702
3111
  await importJsonSchema({ contents: JSON.stringify(internalSchemaData) }, internalSchemaData.version);
3703
- logger$6(`Loaded internal seed-protocol schema v${internalSchemaData.version}`);
3112
+ logger$2(`Loaded internal seed-protocol schema v${internalSchemaData.version}`);
3704
3113
  }
3705
3114
  catch (error) {
3706
3115
  // If schema already exists, that's fine - it means it was already loaded
3707
3116
  if (error?.message?.includes('already exists')) {
3708
- logger$6('Internal seed-protocol schema already loaded');
3117
+ logger$2('Internal seed-protocol schema already loaded');
3709
3118
  }
3710
3119
  else {
3711
- logger$6('Error loading internal seed-protocol schema:', error);
3120
+ logger$2('Error loading internal seed-protocol schema:', error);
3712
3121
  // Don't fail if internal schema can't be loaded - it might already be in DB
3713
3122
  }
3714
3123
  }
@@ -3721,7 +3130,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3721
3130
  : '';
3722
3131
  const schemaId = typeof context.schema === 'object' && context.schema?.id ? String(context.schema.id) : undefined;
3723
3132
  if (isInternalSchema(schemaName, schemaId)) {
3724
- logger$6('Schema is internal (Seed Protocol), already loaded - skipping syncSchemaFromSource');
3133
+ logger$2('Schema is internal (Seed Protocol), already loaded - skipping syncSchemaFromSource');
3725
3134
  }
3726
3135
  else {
3727
3136
  try {
@@ -3730,7 +3139,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3730
3139
  if (syncedName) {
3731
3140
  schemasWrittenThisRun.add(syncedName);
3732
3141
  }
3733
- logger$6(`Synced canonical schema from ${typeof context.schema === 'string' ? context.schema : 'object'}`);
3142
+ logger$2(`Synced canonical schema from ${typeof context.schema === 'string' ? context.schema : 'object'}`);
3734
3143
  }
3735
3144
  catch (error) {
3736
3145
  // A schema the app passed in failed (missing file, bad JSON, DB write). Re-running an
@@ -3749,7 +3158,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3749
3158
  if (parsed?.metadata?.name) {
3750
3159
  schemasWrittenThisRun.add(String(parsed.metadata.name));
3751
3160
  }
3752
- logger$6(`Loaded schema from ${resolvedPath}`);
3161
+ logger$2(`Loaded schema from ${resolvedPath}`);
3753
3162
  }
3754
3163
  catch (error) {
3755
3164
  throw userSchemaLoadError('schemaFile', context.schemaFile, error);
@@ -3757,14 +3166,14 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3757
3166
  }
3758
3167
  // Process minimal import files (files without $schema) - skip when canonical schema is set
3759
3168
  if (!context.schema) {
3760
- logger$6('Listing schema files');
3169
+ logger$2('Listing schema files');
3761
3170
  let schemaFiles = [];
3762
3171
  try {
3763
3172
  schemaFiles = await listSchemaFiles();
3764
- logger$6(`Found ${schemaFiles.length} schema files to process`);
3173
+ logger$2(`Found ${schemaFiles.length} schema files to process`);
3765
3174
  }
3766
3175
  catch (error) {
3767
- logger$6('Error listing schema files (continuing anyway):', error);
3176
+ logger$2('Error listing schema files (continuing anyway):', error);
3768
3177
  schemaFiles = [];
3769
3178
  }
3770
3179
  for (const schemaFile of schemaFiles) {
@@ -3775,25 +3184,29 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3775
3184
  }
3776
3185
  }
3777
3186
  catch (error) {
3778
- logger$6(`Error importing schema file ${schemaFile.filePath}:`, error);
3187
+ logger$2(`Error importing schema file ${schemaFile.filePath}:`, error);
3779
3188
  }
3780
3189
  }
3781
3190
  }
3782
3191
  // Then, load all schemas using the unified database-first approach
3783
- logger$6('Loading schemas from database and files');
3192
+ logger$2('Loading schemas from database and files');
3784
3193
  let allSchemasData = [];
3785
3194
  try {
3786
3195
  allSchemasData = await loadAllSchemasFromDb();
3787
- logger$6(`Loaded ${allSchemasData.length} schemas (${allSchemasData.filter(s => s.isDraft).length} drafts, ${allSchemasData.filter(s => !s.isDraft).length} published)`);
3196
+ logger$2(`Loaded ${allSchemasData.length} schemas (${allSchemasData.filter(s => s.isDraft).length} drafts, ${allSchemasData.filter(s => !s.isDraft).length} published)`);
3788
3197
  }
3789
3198
  catch (error) {
3790
- logger$6('Error loading schemas from database (continuing anyway):', error);
3199
+ logger$2('Error loading schemas from database (continuing anyway):', error);
3791
3200
  // Continue with empty array - this is not critical for initialization
3792
3201
  // Schemas can be loaded on-demand later
3793
3202
  allSchemasData = [];
3794
3203
  }
3795
3204
  // Collect models to add to context (schemas are now loaded on-demand via database queries)
3796
3205
  const allModels = { ...(context.models || {}) };
3206
+ // The models built below describe rows that loadSchemaFromFile or an earlier init already wrote:
3207
+ // they adopt those rows, and only a model with no row writes one. Without it every init rewrote
3208
+ // each property row and cleared is_edited.
3209
+ const rowsWritten = Promise.resolve();
3797
3210
  // Linked model count per schema row, to tell whether an earlier load already applied a file's models
3798
3211
  const linkedModelCounts = new Map();
3799
3212
  if (db) {
@@ -3808,13 +3221,13 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3808
3221
  }
3809
3222
  }
3810
3223
  catch (error) {
3811
- logger$6('Error counting linked models (re-applying all schema files):', error);
3224
+ logger$2('Error counting linked models (re-applying all schema files):', error);
3812
3225
  }
3813
3226
  }
3814
3227
  for (const schemaData of allSchemasData) {
3815
3228
  const schema = schemaData.schema;
3816
3229
  const schemaName = schema.metadata?.name || 'unknown';
3817
- logger$6(`Processing schema: ${schemaName} v${schema.version} (${schemaData.isDraft ? 'draft' : 'published'}, source: ${schemaData.source})`);
3230
+ logger$2(`Processing schema: ${schemaName} v${schema.version} (${schemaData.isDraft ? 'draft' : 'published'}, source: ${schemaData.source})`);
3818
3231
  // For published schemas (not drafts), load models from file if available
3819
3232
  if (!schemaData.isDraft && schema.id) {
3820
3233
  // loadAllSchemasFromDb already picked the latest file for this schema (and read it)
@@ -3834,17 +3247,17 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3834
3247
  schemaData.schemaRecordId != null &&
3835
3248
  (linkedModelCounts.get(schemaData.schemaRecordId) ?? 0) >= expectedModelCount;
3836
3249
  if (alreadyWritten || alreadyApplied) {
3837
- const modelDefinitions = await createModelsFromJsonFile(latestFilePath);
3250
+ const modelDefinitions = await createModelsFromJsonFile(latestFilePath, rowsWritten);
3838
3251
  Object.assign(allModels, modelDefinitions);
3839
3252
  }
3840
3253
  else {
3841
3254
  await loadSchemaFromFile(latestFilePath);
3842
- const modelDefinitions = await createModelsFromJsonFile(latestFilePath);
3255
+ const modelDefinitions = await createModelsFromJsonFile(latestFilePath, rowsWritten);
3843
3256
  Object.assign(allModels, modelDefinitions);
3844
3257
  }
3845
3258
  }
3846
3259
  catch (error) {
3847
- logger$6(`Error loading schema file for ${schemaName}:`, error);
3260
+ logger$2(`Error loading schema file for ${schemaName}:`, error);
3848
3261
  }
3849
3262
  }
3850
3263
  else {
@@ -3891,13 +3304,13 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3891
3304
  },
3892
3305
  ])),
3893
3306
  };
3894
- const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
3307
+ const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds, rowsWritten);
3895
3308
  Object.assign(allModels, modelDefinitions);
3896
- logger$6(`Loaded ${Object.keys(modelDefinitions).length} models from schema data for ${schemaName}`);
3309
+ logger$2(`Loaded ${Object.keys(modelDefinitions).length} models from schema data for ${schemaName}`);
3897
3310
  }
3898
3311
  }
3899
3312
  catch (error) {
3900
- logger$6(`Error creating models from schema data for ${schemaName}:`, error);
3313
+ logger$2(`Error creating models from schema data for ${schemaName}:`, error);
3901
3314
  }
3902
3315
  }
3903
3316
  }
@@ -3945,13 +3358,13 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3945
3358
  },
3946
3359
  ])),
3947
3360
  };
3948
- const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
3361
+ const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds, rowsWritten);
3949
3362
  Object.assign(allModels, modelDefinitions);
3950
- logger$6(`Loaded ${Object.keys(modelDefinitions).length} models from draft schema ${schemaName}`);
3363
+ logger$2(`Loaded ${Object.keys(modelDefinitions).length} models from draft schema ${schemaName}`);
3951
3364
  }
3952
3365
  }
3953
3366
  catch (error) {
3954
- logger$6(`Error creating models from draft schema ${schemaName}:`, error);
3367
+ logger$2(`Error creating models from draft schema ${schemaName}:`, error);
3955
3368
  }
3956
3369
  }
3957
3370
  // Schemas are now loaded on-demand via database queries (useSchemas hook uses loadAllSchemasFromDb)
@@ -3982,651 +3395,6 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
3982
3395
  };
3983
3396
  });
3984
3397
 
3985
- /** Absolute path of the file {@link writeItemStorageFile} writes for `target`. */
3986
- const getItemStorageFilePath = (target) => BaseFileManager.getFilesPath(getItemStorageSubdir(target.localStorageDir), target.fileName || getItemStorageLocalFileName(target.seedId, target.filenameSuffix));
3987
- /**
3988
- * Write an ItemStorage property's content to its local file, where saveItemStorage, reads, publish
3989
- * (resolveItemStorageChildFile) and download all look for it. Returns what the metadata row records:
3990
- * `refResolvedValue` (the file name) and `localStorageDir` (with a leading slash).
3991
- *
3992
- * Callers that also update the file's metadata row hold {@link withItemStorageFileLock} around
3993
- * both, so another writer of the same file can't land in between.
3994
- */
3995
- const writeItemStorageFile = async (target, content) => {
3996
- const dir = getItemStorageSubdir(target.localStorageDir);
3997
- const fileName = target.fileName || getItemStorageLocalFileName(target.seedId, target.filenameSuffix);
3998
- await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath(dir));
3999
- const filePath = BaseFileManager.getFilesPath(dir, fileName);
4000
- await BaseFileManager.saveFile(filePath, content);
4001
- return { fileName, filePath, localStorageDir: target.localStorageDir || `/${dir}` };
4002
- };
4003
- /**
4004
- * Lock name for one ItemStorage file: `seed:item-storage:<absolute file path>`. The path starts
4005
- * with the files root, which also names the database (`<filesDir>/db/seed.db`), so the name is
4006
- * per database as well as per file.
4007
- */
4008
- const itemStorageFileLockName = (filePath) => `seed:item-storage:${filePath}`;
4009
- /**
4010
- * Runs `fn` holding the lock of one ItemStorage file, across tabs (Web Locks) and within this JS
4011
- * realm (an in-process queue where Web Locks are missing, e.g. Node < 24.5; see `withTabLock`).
4012
- *
4013
- * Writers of a local draft's file (saveItemStorage, convertVerbatimItemStorageRow, createNewItem)
4014
- * hold it across "read the row → write the file → update the row", so the file and the row end
4015
- * with the same writer's content. See docs/MULTI_TAB.md.
4016
- *
4017
- * Lock ordering: this lock is always the innermost. It may be taken while holding a broader lock
4018
- * (`seed:item-storage-migration:<db>`, `seed:publish:<seedLocalId>`), never the other way round,
4019
- * and no other lock (nor a second file lock) is requested while it is held. Keep the section to
4020
- * local DB and file I/O: no network. Not re-entrant.
4021
- */
4022
- function withItemStorageFileLock(filePath, fn) {
4023
- return withTabLock(itemStorageFileLockName(filePath), fn);
4024
- }
4025
- /** {@link withItemStorageFileLock} only if the lock is free now (see `tryWithTabLock`). */
4026
- function tryWithItemStorageFileLock(filePath, fn) {
4027
- return tryWithTabLock(itemStorageFileLockName(filePath), fn);
4028
- }
4029
- /** Lock attempts before giving up when the row's target file keeps changing under us. */
4030
- const ROW_LOCK_ATTEMPTS = 3;
4031
- const readRow = async (localId) => {
4032
- const rows = await BaseDb.getAppDb()
4033
- .select()
4034
- .from(metadata$1)
4035
- .where(eq(metadata$1.localId, localId))
4036
- .limit(1);
4037
- return rows[0];
4038
- };
4039
- /**
4040
- * Runs `fn` with a fresh read of metadata row `localId`, holding the lock of the file that row's
4041
- * content goes to. `fileOf` names that file (absolute path) for a row, or returns undefined when
4042
- * there is nothing to write (then `fn` isn't called and the result is undefined).
4043
- *
4044
- * The file depends on the row, so the row is read once to pick the lock and again once it is held;
4045
- * if the row now points at another file (another writer changed it meanwhile), the lock is
4046
- * released and taken again for that file.
4047
- */
4048
- async function withLockedItemStorageRow(localId, fileOf, fn) {
4049
- for (let attempt = 0; attempt < ROW_LOCK_ATTEMPTS; attempt++) {
4050
- const row = await readRow(localId);
4051
- const filePath = row && fileOf(row);
4052
- if (!filePath)
4053
- return undefined;
4054
- const outcome = await withItemStorageFileLock(filePath, async () => {
4055
- const fresh = await readRow(localId);
4056
- const freshPath = fresh && fileOf(fresh);
4057
- if (!freshPath)
4058
- return { done: true, value: undefined };
4059
- if (freshPath !== filePath)
4060
- return { done: false };
4061
- return { done: true, value: await fn(fresh, filePath) };
4062
- });
4063
- if (outcome.done)
4064
- return outcome.value;
4065
- }
4066
- throw new Error(`ItemStorage file of metadata row ${localId} kept changing; not written`);
4067
- }
4068
-
4069
- /**
4070
- * A legacy ItemStorage draft row: a local edit (no attestation uid, not derived from one) that holds
4071
- * the content itself in property_value, with no file reference. Item.create / createNewItem stored
4072
- * ItemStorage values like this before they went through the save pipeline.
4073
- */
4074
- const isVerbatimItemStorageDraftRow = (row) => !row.uid &&
4075
- row.derivedFromUid == null &&
4076
- !row.refResolvedValue &&
4077
- typeof row.propertyValue === 'string' &&
4078
- row.propertyValue !== '';
4079
- /**
4080
- * Convert one legacy ItemStorage draft row (see {@link isVerbatimItemStorageDraftRow}) into the
4081
- * shape saveItemStorage gives a row: the content goes to the file a save would write
4082
- * (`<seedUid or seedLocalId><extension>` in the property's storage directory), and the row records
4083
- * `refResolvedValue`, `localStorageDir` and `refValueType: 'file'` with property_value cleared.
4084
- * Used by publish (resolveItemStorageChildFile) and the one-time migration (migrateLegacyItemStorageRows).
4085
- *
4086
- * Reading the row, writing the file and updating the row happen under the file's lock
4087
- * ({@link withItemStorageFileLock}), which saveItemStorage holds too: a save in this or another tab
4088
- * either finishes before (the row, read again once the lock is held, is no longer legacy and is
4089
- * left alone) or starts after (and overwrites the file and row with its content). Without the lock
4090
- * a save landing between the read and the file write would have its file overwritten with the old
4091
- * content. The row update also stays conditional on the row being unchanged, for writers that
4092
- * don't take the lock (a tab still running an older SDK).
4093
- *
4094
- * Returns undefined when there was nothing to convert. Throws when the file can't be written; the
4095
- * row is then unchanged.
4096
- */
4097
- const convertVerbatimItemStorageRow = async (localId, storage = {}) => {
4098
- const appDb = BaseDb.getAppDb();
4099
- if (!appDb || !localId)
4100
- return undefined;
4101
- const targetOf = (row) => {
4102
- if (!isVerbatimItemStorageDraftRow(row))
4103
- return undefined;
4104
- const seedId = storage.seedId || row.seedUid || row.seedLocalId;
4105
- if (!seedId)
4106
- return undefined;
4107
- return {
4108
- seedId,
4109
- localStorageDir: storage.localStorageDir || row.localStorageDir,
4110
- filenameSuffix: storage.filenameSuffix,
4111
- };
4112
- };
4113
- return withLockedItemStorageRow(localId, (row) => {
4114
- const target = targetOf(row);
4115
- return target && getItemStorageFilePath(target);
4116
- }, async (row) => {
4117
- const content = row.propertyValue;
4118
- const { fileName, filePath, localStorageDir } = await writeItemStorageFile(targetOf(row), content);
4119
- await appDb
4120
- .update(metadata$1)
4121
- .set({ refResolvedValue: fileName, localStorageDir, refValueType: 'file', propertyValue: null })
4122
- .where(and(eq(metadata$1.localId, localId), isNull(metadata$1.refResolvedValue), eq(metadata$1.propertyValue, content)));
4123
- // Changed between the read and the update by a writer outside the lock: that change stands.
4124
- const after = await appDb
4125
- .select({ refResolvedValue: metadata$1.refResolvedValue, propertyValue: metadata$1.propertyValue })
4126
- .from(metadata$1)
4127
- .where(eq(metadata$1.localId, localId))
4128
- .limit(1);
4129
- if (after[0]?.refResolvedValue !== fileName || after[0]?.propertyValue != null)
4130
- return undefined;
4131
- return { fileName, filePath, localStorageDir, content };
4132
- });
4133
- };
4134
-
4135
- const logger$5 = debug('seedSdk:db:migrateLegacyItemStorageRows');
4136
- /** appState key recording that legacy ItemStorage rows have been written to their files. */
4137
- const LEGACY_ITEM_STORAGE_MIGRATION_KEY = 'legacyItemStorageFiles:v1';
4138
- /** Runs in a row that left rows unconverted because a file write failed, before giving up. */
4139
- const LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS = 3;
4140
- const readMarker = async () => {
4141
- const db = BaseDb.getAppDb();
4142
- const rows = await db
4143
- .select({ value: appState.value })
4144
- .from(appState)
4145
- .where(eq(appState.key, LEGACY_ITEM_STORAGE_MIGRATION_KEY))
4146
- .limit(1);
4147
- if (!rows.length)
4148
- return undefined;
4149
- try {
4150
- return JSON.parse(rows[0].value ?? '');
4151
- }
4152
- catch {
4153
- return null;
4154
- }
4155
- };
4156
- const writeMarker = async (marker) => {
4157
- const db = BaseDb.getAppDb();
4158
- const now = Date.now();
4159
- const value = JSON.stringify(marker);
4160
- await db
4161
- .insert(appState)
4162
- .values({ key: LEGACY_ITEM_STORAGE_MIGRATION_KEY, value, createdAt: now, updatedAt: now })
4163
- .onConflictDoUpdate({ target: appState.key, set: { value, updatedAt: now } });
4164
- };
4165
- /**
4166
- * The storage settings of a metadata row's property: by its property_id, else by name in the
4167
- * seed's own model (model names are only unique per schema). Undefined when it can't be told.
4168
- */
4169
- const createStorageResolver = () => {
4170
- const db = BaseDb.getAppDb();
4171
- const byPropertyId = new Map();
4172
- const byModelAndName = new Map();
4173
- return async (row) => {
4174
- if (row.propertyId != null) {
4175
- if (!byPropertyId.has(row.propertyId)) {
4176
- const found = await db
4177
- .select({
4178
- storageType: properties.storageType,
4179
- localStorageDir: properties.localStorageDir,
4180
- filenameSuffix: properties.filenameSuffix,
4181
- })
4182
- .from(properties)
4183
- .where(eq(properties.id, row.propertyId))
4184
- .limit(1);
4185
- byPropertyId.set(row.propertyId, found[0]);
4186
- }
4187
- const fromId = byPropertyId.get(row.propertyId);
4188
- if (fromId)
4189
- return fromId;
4190
- }
4191
- const modelFileId = await resolveItemModelFileId({ seedLocalId: row.seedLocalId, seedUid: row.seedUid });
4192
- if (!modelFileId || !row.propertyName)
4193
- return undefined;
4194
- const key = `${modelFileId}\u0000${row.propertyName}`;
4195
- if (!byModelAndName.has(key)) {
4196
- const found = await db
4197
- .select({
4198
- storageType: properties.storageType,
4199
- localStorageDir: properties.localStorageDir,
4200
- filenameSuffix: properties.filenameSuffix,
4201
- })
4202
- .from(properties)
4203
- .innerJoin(models$1, eq(properties.modelId, models$1.id))
4204
- .where(and(eq(models$1.schemaFileId, modelFileId), eq(properties.name, row.propertyName)))
4205
- .limit(1);
4206
- byModelAndName.set(key, found[0]);
4207
- }
4208
- return byModelAndName.get(key);
4209
- };
4210
- };
4211
- /** True if `row` is the row readers show for its property: the newest of its seed's rows by that name. */
4212
- const isNewestRowOfProperty = async (row) => {
4213
- if (!row.seedLocalId || !row.propertyName)
4214
- return false;
4215
- const db = BaseDb.getAppDb();
4216
- const siblings = await db
4217
- .select()
4218
- .from(metadata$1)
4219
- .where(and(eq(metadata$1.seedLocalId, row.seedLocalId), eq(metadata$1.propertyName, row.propertyName)));
4220
- return [...siblings].sort(compareMetadataRowsLatestFirst)[0]?.localId === row.localId;
4221
- };
4222
- /**
4223
- * One-time data migration: writes the content of legacy ItemStorage draft rows to their files.
4224
- *
4225
- * Before Item.create / createNewItem saved ItemStorage values through the save pipeline, a value
4226
- * given at creation was stored verbatim in metadata.property_value with no file. Publish converts
4227
- * such a row lazily (resolveItemStorageChildFile); this converts them all up front, with the same
4228
- * code ({@link convertVerbatimItemStorageRow}), so every ItemStorage draft has the shape a save
4229
- * gives it: the content in `<seedUid or seedLocalId><extension>`, the row holding
4230
- * refResolvedValue / localStorageDir / refValueType 'file' and no property_value.
4231
- *
4232
- * Only local drafts (no uid, not derived from an attestation) of properties whose properties row
4233
- * says `storage_type = 'ItemStorage'` are touched, and of those only the newest row of each
4234
- * seed's property: that is the row reads show and saves write to, and older rows sharing the one
4235
- * file name would overwrite it with older content. Published and synced rows are never changed.
4236
- *
4237
- * A row that fails is logged and left as it was (publish still converts it). The run is recorded
4238
- * in appState under {@link LEGACY_ITEM_STORAGE_MIGRATION_KEY}; a run with failed rows is retried
4239
- * on the next start, up to {@link LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS} runs. Safe to run
4240
- * again regardless: a converted row no longer matches.
4241
- *
4242
- * @param options.force run even when the marker says it is done
4243
- */
4244
- async function migrateLegacyItemStorageRows(options = {}) {
4245
- const result = {
4246
- alreadyDone: false,
4247
- candidates: 0,
4248
- converted: 0,
4249
- failed: 0,
4250
- skipped: 0,
4251
- };
4252
- const db = BaseDb.getAppDb();
4253
- if (!db)
4254
- return { ...result, alreadyDone: true };
4255
- const marker = await readMarker();
4256
- const previousAttempts = marker?.status === 'retry' ? marker.attempts : 0;
4257
- if (!options.force && marker && marker.status === 'done') {
4258
- return { ...result, alreadyDone: true };
4259
- }
4260
- const itemStorageNames = (await db
4261
- .selectDistinct({ name: properties.name })
4262
- .from(properties)
4263
- .where(eq(properties.storageType, 'ItemStorage'))).map((r) => r.name);
4264
- const candidates = itemStorageNames.length
4265
- ? await db
4266
- .select()
4267
- .from(metadata$1)
4268
- .where(and(inArray(metadata$1.propertyName, itemStorageNames), or(isNull(metadata$1.uid), eq(metadata$1.uid, '')), isNull(metadata$1.derivedFromUid), isNull(metadata$1.refResolvedValue), isNotNull(metadata$1.propertyValue), ne(metadata$1.propertyValue, '')))
4269
- : [];
4270
- const resolveStorage = createStorageResolver();
4271
- for (const row of candidates) {
4272
- if (!row.localId || !isVerbatimItemStorageDraftRow(row))
4273
- continue;
4274
- try {
4275
- const storage = await resolveStorage(row);
4276
- if (storage?.storageType !== 'ItemStorage')
4277
- continue;
4278
- result.candidates++;
4279
- if (!(await isNewestRowOfProperty(row))) {
4280
- result.skipped++;
4281
- continue;
4282
- }
4283
- const converted = await convertVerbatimItemStorageRow(row.localId, {
4284
- localStorageDir: storage.localStorageDir,
4285
- filenameSuffix: storage.filenameSuffix,
4286
- });
4287
- if (converted) {
4288
- result.converted++;
4289
- logger$5(`wrote ${row.propertyName} of ${row.seedLocalId} to ${converted.filePath}`);
4290
- }
4291
- else {
4292
- result.skipped++;
4293
- }
4294
- }
4295
- catch (error) {
4296
- result.failed++;
4297
- logger$5(`converting ${row.propertyName} of ${row.seedLocalId} (${row.localId}) failed; left as is`, error);
4298
- }
4299
- }
4300
- const attempts = previousAttempts + 1;
4301
- await writeMarker({
4302
- status: result.failed > 0 && attempts < LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS ? 'retry' : 'done',
4303
- attempts,
4304
- converted: result.converted,
4305
- failed: result.failed,
4306
- at: Date.now(),
4307
- });
4308
- if (result.candidates > 0) {
4309
- logger$5(`legacy ItemStorage rows: ${result.converted} converted, ${result.failed} failed, ` +
4310
- `${result.skipped} skipped of ${result.candidates}`);
4311
- }
4312
- return result;
4313
- }
4314
- let running$4;
4315
- let deferredUntilLeader$4 = false;
4316
- const runInBackground$4 = () => {
4317
- running$4 ?? (running$4 = withDbTabLock('item-storage-migration', () => migrateLegacyItemStorageRows())
4318
- .then(() => undefined)
4319
- .catch((error) => {
4320
- // Never fails init: rows stay as they were and publish converts them lazily.
4321
- logger$5('legacy ItemStorage migration failed', error);
4322
- })
4323
- .finally(() => {
4324
- running$4 = undefined;
4325
- }));
4326
- return running$4;
4327
- };
4328
- /**
4329
- * Starts {@link migrateLegacyItemStorageRows} in the background once client init has finished
4330
- * (the properties table then holds the current storage settings). It runs in the leader tab only
4331
- * (docs/MULTI_TAB.md), under a `seed:item-storage-migration:<db>` lock in case several tabs lead
4332
- * (`multiTab: 'off'`); a tab that isn't leader runs it if it takes over. Never throws.
4333
- */
4334
- function startLegacyItemStorageMigration() {
4335
- if (isLeaderTab()) {
4336
- void runInBackground$4();
4337
- return;
4338
- }
4339
- if (deferredUntilLeader$4)
4340
- return;
4341
- deferredUntilLeader$4 = true;
4342
- void whenLeaderTab().then(() => {
4343
- deferredUntilLeader$4 = false;
4344
- void runInBackground$4();
4345
- });
4346
- }
4347
-
4348
- const logger$4 = debug('seedSdk:db:removeForeignAttestationRows');
4349
- /** appState key recording that the cleanup below has run on this database. */
4350
- const FOREIGN_ATTESTATION_CLEANUP_KEY = 'foreignAttestationRowsRemoved';
4351
- /** Lowercased `attester` of a stored attestation JSON; NULL when the JSON is invalid or has none. */
4352
- const attesterOf = (raw) => sql `(CASE WHEN json_valid(${raw}) THEN lower(json_extract(${raw}, '$.attester')) END)`;
4353
- /**
4354
- * Deletes rows that an SDK without the attester check (partitionByRefAttester) synced from other
4355
- * accounts' attestations: versions whose attester isn't their seed's, and
4356
- * properties whose attester isn't their version's, plus the properties of those versions. Sync
4357
- * removes them too, but only for the seeds it reaches, and only online; this needs no network.
4358
- *
4359
- * Only rows synced from EAS on both sides are compared, by the `attester` in their stored
4360
- * attestation, as sync compares them: local drafts and rows without a stored attestation are
4361
- * kept, like partitionByRefAttester keeps children whose attesters aren't both known.
4362
- */
4363
- async function removeForeignAttestationRows() {
4364
- const appDb = BaseDb.getAppDb();
4365
- const foreignVersions = await appDb
4366
- .select({ uid: versions.uid })
4367
- .from(versions)
4368
- .innerJoin(seeds, eq(seeds.localId, versions.seedLocalId))
4369
- .where(and(isNotNull(versions.uid), sql `${attesterOf(versions.attestationRaw)} <> ${attesterOf(seeds.attestationRaw)}`));
4370
- const foreignVersionUids = foreignVersions.map((row) => row.uid).filter(Boolean);
4371
- const foreignProperties = await appDb
4372
- .select({ localId: metadata$1.localId })
4373
- .from(metadata$1)
4374
- .innerJoin(versions, eq(versions.uid, metadata$1.versionUid))
4375
- .where(and(isNotNull(metadata$1.uid), sql `${attesterOf(metadata$1.attestationRaw)} <> ${attesterOf(versions.attestationRaw)}`));
4376
- const foreignPropertyLocalIds = foreignProperties.map((row) => row.localId).filter(Boolean);
4377
- let propertyRows = foreignPropertyLocalIds.length;
4378
- await writeInBatches(foreignPropertyLocalIds, (chunk) => appDb.delete(metadata$1).where(inArray(metadata$1.localId, chunk)));
4379
- await writeInBatches(foreignVersionUids, async (chunk) => {
4380
- const removed = await appDb
4381
- .delete(metadata$1)
4382
- .where(inArray(metadata$1.versionUid, chunk))
4383
- .returning({ localId: metadata$1.localId });
4384
- propertyRows += removed.length;
4385
- });
4386
- await writeInBatches(foreignVersionUids, (chunk) => appDb.delete(versions).where(inArray(versions.uid, chunk)));
4387
- return { versionRows: foreignVersionUids.length, propertyRows };
4388
- }
4389
- /** Runs the cleanup unless this database has had it, and records that it has. */
4390
- async function runOnce$2() {
4391
- const appDb = BaseDb.getAppDb();
4392
- const marker = await appDb
4393
- .select()
4394
- .from(appState)
4395
- .where(eq(appState.key, FOREIGN_ATTESTATION_CLEANUP_KEY))
4396
- .limit(1);
4397
- if (marker.length > 0)
4398
- return;
4399
- const result = await removeForeignAttestationRows();
4400
- const value = JSON.stringify({ ...result, at: Date.now() });
4401
- await appDb
4402
- .insert(appState)
4403
- .values({ key: FOREIGN_ATTESTATION_CLEANUP_KEY, value })
4404
- .onConflictDoUpdate({ target: appState.key, set: { value } });
4405
- if (result.versionRows > 0 || result.propertyRows > 0) {
4406
- logger$4(`removed ${result.versionRows} version and ${result.propertyRows} property rows from other attesters`);
4407
- }
4408
- }
4409
- let running$3;
4410
- let deferredUntilLeader$3 = false;
4411
- const runInBackground$3 = () => {
4412
- // Under the sync's lock, so it can't interleave with a sync writing the same rows.
4413
- running$3 ?? (running$3 = withDbTabLock('eas-sync', runOnce$2, { timeoutMs: Infinity })
4414
- .catch((error) => {
4415
- // Never fails init: the rows stay until the next sync of their seeds removes them.
4416
- logger$4('foreign attestation cleanup failed', error);
4417
- })
4418
- .finally(() => {
4419
- running$3 = undefined;
4420
- }));
4421
- return running$3;
4422
- };
4423
- /**
4424
- * Starts {@link removeForeignAttestationRows} in the background after client init, once per
4425
- * database: a one-time data fix, so an init step rather than a SQL migration (it needs the
4426
- * attester out of stored JSON, the same rule as sync, and must never block or fail init). Leader
4427
- * tab only (docs/MULTI_TAB.md); a tab that isn't leader runs it if it takes over. Never throws.
4428
- */
4429
- function startForeignAttestationCleanup() {
4430
- if (isLeaderTab()) {
4431
- void runInBackground$3();
4432
- return;
4433
- }
4434
- if (deferredUntilLeader$3)
4435
- return;
4436
- deferredUntilLeader$3 = true;
4437
- void whenLeaderTab().then(() => {
4438
- deferredUntilLeader$3 = false;
4439
- void runInBackground$3();
4440
- });
4441
- }
4442
-
4443
- const logger$3 = debug('seedSdk:db:alignRowPublishers');
4444
- /** appState key recording that the fix below has run on this database. */
4445
- const ROW_PUBLISHERS_ALIGNED_KEY = 'rowPublishersAligned';
4446
- /**
4447
- * Gives version and property rows their seed's publisher. Before, edits wrote property rows with no
4448
- * publisher, and versions and property rows took the session's publisher rather than the seed's,
4449
- * so connecting another wallet could claim rows of a seed that already had one. Local query reads
4450
- * report a row's publisher as its attester and leave out rows whose attester isn't their parent's.
4451
- *
4452
- * Only rows without a stored attestation are changed: synced rows carry their attester in
4453
- * `attestation_raw`. When the seed belongs to no wallet yet, its unsealed rows lose any publisher,
4454
- * so they're claimed with it.
4455
- */
4456
- async function alignRowPublishers() {
4457
- const appDb = BaseDb.getAppDb();
4458
- const align = async (table) => {
4459
- const rows = (await appDb
4460
- .select({
4461
- localId: table.localId,
4462
- uid: table.uid,
4463
- publisher: table.publisher,
4464
- seedPublisher: seeds.publisher,
4465
- seedAttestationRaw: seeds.attestationRaw,
4466
- seedUid: seeds.uid,
4467
- attestationRaw: table.attestationRaw,
4468
- })
4469
- .from(table)
4470
- .innerJoin(seeds, eq(seeds.localId, table.seedLocalId)));
4471
- const byTarget = new Map();
4472
- for (const row of rows) {
4473
- if (!row.localId || (row.attestationRaw != null && row.attestationRaw !== ''))
4474
- continue;
4475
- const seedPublisher = normalizePublisher(resolvePublisherFromSeedRow({
4476
- publisher: row.seedPublisher,
4477
- attestationRaw: row.seedAttestationRaw,
4478
- uid: row.seedUid,
4479
- }));
4480
- const current = normalizePublisher(row.publisher);
4481
- let target;
4482
- if (seedPublisher) {
4483
- if (current === seedPublisher)
4484
- continue;
4485
- target = seedPublisher;
4486
- }
4487
- else {
4488
- // A seed with no wallet yet: its unsealed rows go with it when it's claimed.
4489
- if (!current || !isPlaceholderUid(row.uid))
4490
- continue;
4491
- target = null;
4492
- }
4493
- const ids = byTarget.get(target) ?? [];
4494
- ids.push(row.localId);
4495
- byTarget.set(target, ids);
4496
- }
4497
- let changed = 0;
4498
- for (const [target, ids] of byTarget) {
4499
- await writeInBatches(ids, (chunk) => appDb.update(table).set({ publisher: target }).where(inArray(table.localId, chunk)));
4500
- changed += ids.length;
4501
- }
4502
- return changed;
4503
- };
4504
- const versionRows = await align(versions);
4505
- const propertyRows = await align(metadata$1);
4506
- return { versionRows, propertyRows };
4507
- }
4508
- /** Runs the fix unless this database has had it, and records that it has. */
4509
- async function runOnce$1() {
4510
- const appDb = BaseDb.getAppDb();
4511
- const marker = await appDb
4512
- .select()
4513
- .from(appState)
4514
- .where(eq(appState.key, ROW_PUBLISHERS_ALIGNED_KEY))
4515
- .limit(1);
4516
- if (marker.length > 0)
4517
- return;
4518
- const result = await alignRowPublishers();
4519
- const value = JSON.stringify({ ...result, at: Date.now() });
4520
- await appDb
4521
- .insert(appState)
4522
- .values({ key: ROW_PUBLISHERS_ALIGNED_KEY, value })
4523
- .onConflictDoUpdate({ target: appState.key, set: { value } });
4524
- if (result.versionRows > 0 || result.propertyRows > 0) {
4525
- logger$3(`gave ${result.versionRows} version and ${result.propertyRows} property rows their seed's publisher`);
4526
- }
4527
- }
4528
- let running$2;
4529
- let deferredUntilLeader$2 = false;
4530
- const runInBackground$2 = () => {
4531
- // Under the sync's lock: sync writes these rows too.
4532
- running$2 ?? (running$2 = withDbTabLock('eas-sync', runOnce$1, { timeoutMs: Infinity })
4533
- .catch((error) => {
4534
- // Never fails init: the rows keep their old publisher.
4535
- logger$3('row publisher fix failed', error);
4536
- })
4537
- .finally(() => {
4538
- running$2 = undefined;
4539
- }));
4540
- return running$2;
4541
- };
4542
- /**
4543
- * Starts {@link alignRowPublishers} in the background after client init, once per database, like
4544
- * the foreign-attestation cleanup. Leader tab only (docs/MULTI_TAB.md). Never throws.
4545
- */
4546
- function startAlignRowPublishers() {
4547
- if (isLeaderTab()) {
4548
- void runInBackground$2();
4549
- return;
4550
- }
4551
- if (deferredUntilLeader$2)
4552
- return;
4553
- deferredUntilLeader$2 = true;
4554
- void whenLeaderTab().then(() => {
4555
- deferredUntilLeader$2 = false;
4556
- void runInBackground$2();
4557
- });
4558
- }
4559
-
4560
- const logger$2 = debug('seedSdk:db:clearStoredDisplayUrls');
4561
- /** appState key recording that the fix below has run on this database. */
4562
- const STORED_DISPLAY_URLS_CLEARED_KEY = 'storedDisplayUrlsCleared';
4563
- /**
4564
- * Nulls `ref_resolved_display_value` on File and Image rows that hold a session URL. SDK 0.7.5 and
4565
- * 0.7.6 stored a File's content URL there: a `blob:` URL that is dead after a reload, or a
4566
- * `file://` URL that breaks when filesDir moves. Readers now mint the URL from the file on disk and
4567
- * ignore the column for these types; clearing it keeps older readers and direct DB queries from
4568
- * picking the dead URL up. Returns the number of rows changed.
4569
- */
4570
- async function clearStoredDisplayUrls() {
4571
- const appDb = BaseDb.getAppDb();
4572
- const where = and(inArray(metadata$1.refSeedType, ['file', 'image']), or(like(metadata$1.refResolvedDisplayValue, 'blob:%'), like(metadata$1.refResolvedDisplayValue, 'file:%')));
4573
- const rows = (await appDb.select({ localId: metadata$1.localId }).from(metadata$1).where(where));
4574
- if (rows.length === 0)
4575
- return 0;
4576
- await appDb.update(metadata$1).set({ refResolvedDisplayValue: null }).where(where);
4577
- return rows.length;
4578
- }
4579
- /** Runs the fix unless this database has had it, and records that it has. */
4580
- async function runOnce() {
4581
- const appDb = BaseDb.getAppDb();
4582
- const marker = await appDb
4583
- .select()
4584
- .from(appState)
4585
- .where(eq(appState.key, STORED_DISPLAY_URLS_CLEARED_KEY))
4586
- .limit(1);
4587
- if (marker.length > 0)
4588
- return;
4589
- const rows = await clearStoredDisplayUrls();
4590
- const value = JSON.stringify({ rows, at: Date.now() });
4591
- await appDb
4592
- .insert(appState)
4593
- .values({ key: STORED_DISPLAY_URLS_CLEARED_KEY, value })
4594
- .onConflictDoUpdate({ target: appState.key, set: { value } });
4595
- if (rows > 0) {
4596
- logger$2(`cleared stored display URLs on ${rows} File/Image rows`);
4597
- }
4598
- }
4599
- let running$1;
4600
- let deferredUntilLeader$1 = false;
4601
- const runInBackground$1 = () => {
4602
- running$1 ?? (running$1 = runOnce()
4603
- .catch((error) => {
4604
- // Never fails init: readers ignore the column for File and Image anyway.
4605
- logger$2('clearing stored display URLs failed', error);
4606
- })
4607
- .finally(() => {
4608
- running$1 = undefined;
4609
- }));
4610
- return running$1;
4611
- };
4612
- /**
4613
- * Starts {@link clearStoredDisplayUrls} in the background after client init, once per database.
4614
- * Leader tab only (docs/MULTI_TAB.md). Never throws.
4615
- */
4616
- function startClearStoredDisplayUrls() {
4617
- if (isLeaderTab()) {
4618
- void runInBackground$1();
4619
- return;
4620
- }
4621
- if (deferredUntilLeader$1)
4622
- return;
4623
- deferredUntilLeader$1 = true;
4624
- void whenLeaderTab().then(() => {
4625
- deferredUntilLeader$1 = false;
4626
- void runInBackground$1();
4627
- });
4628
- }
4629
-
4630
3398
  const logger$1 = debug('seedSdk:db:canonicalizeModelTypes');
4631
3399
  /**
4632
3400
  * Model types in the local DB (`seeds.type`, `versions.seed_type`, `metadata.model_type`) are the
@@ -4720,6 +3488,19 @@ const createVersion = async ({ seedLocalId, seedUid, seedType, uid, }, options =
4720
3488
  return newVersionLocalId;
4721
3489
  };
4722
3490
 
3491
+ /** Absolute path of the file {@link writeItemStorageFile} writes for `target`. */
3492
+ const getItemStorageFilePath = (target) => BaseFileManager.getFilesPath(getItemStorageSubdir(target.localStorageDir), target.fileName || getItemStorageLocalFileName(target.seedId, target.filenameSuffix));
3493
+ /**
3494
+ * Lock name for one ItemStorage file: `seed:item-storage:<absolute file path>`. The path starts
3495
+ * with the files root, which also names the database (`<filesDir>/db/seed.db`), so the name is
3496
+ * per database as well as per file.
3497
+ */
3498
+ const itemStorageFileLockName = (filePath) => `seed:item-storage:${filePath}`;
3499
+ /** {@link withItemStorageFileLock} only if the lock is free now (see `tryWithTabLock`). */
3500
+ function tryWithItemStorageFileLock(filePath, fn) {
3501
+ return tryWithTabLock(itemStorageFileLockName(filePath), fn);
3502
+ }
3503
+
4723
3504
  /**
4724
3505
  * Conflicts between a local edit and a value sync wrote after it (ADR 0019). The local edit wins:
4725
3506
  * a pending edit applies over the synced row as a new draft, and a draft already written stays the
@@ -5036,7 +3817,6 @@ async function applyItemStorageValue(seedLocalId, propertyName, op, db) {
5036
3817
  localStorageDir,
5037
3818
  // The draft is as new as its content (see updateItemPropertyValue).
5038
3819
  createdAt: now,
5039
- // Same shape as a row the migration or publish converted (convertVerbatimItemStorageRow).
5040
3820
  ...(clearsVerbatimValue && { propertyValue: null, refValueType: 'file' }),
5041
3821
  })
5042
3822
  .where(eq(metadata$1.localId, draft.localId));
@@ -5504,16 +4284,6 @@ const clientManagerMachine = setup({
5504
4284
  assign({
5505
4285
  isInitialized: true,
5506
4286
  }),
5507
- // One-time data migration that writes files, so it can't be a SQL migration in prepareDb.
5508
- // In the background after init: the app is usable at once, the properties table holds the
5509
- // current storage settings by now, and a failure never fails init.
5510
- () => startLegacyItemStorageMigration(),
5511
- // Also once, in the background: rows an older sync stored from other accounts' attestations.
5512
- () => startForeignAttestationCleanup(),
5513
- // Also once: version and property rows get their seed's publisher (rows from older edits had none).
5514
- () => startAlignRowPublishers(),
5515
- // Also once: File/Image rows lose the session URLs 0.7.5–0.7.6 stored (dead blob: URLs after reload).
5516
- () => startClearStoredDisplayUrls(),
5517
4287
  // Stored model types to the ADR 0008 form (html_page), so exact type filters find old rows.
5518
4288
  () => startCanonicalizeModelTypes(),
5519
4289
  // Registers the item appliers and resumes outbox ops left pending (a reload, a closed
@@ -5656,10 +4426,8 @@ function seedRowToAttestation(row) {
5656
4426
  return null;
5657
4427
  const fromRaw = attestationFromRaw(row.attestationRaw);
5658
4428
  if (fromRaw) {
5659
- const schemaName = row.schemaName ??
5660
- fromRaw.schema?.schemaNames?.[0]?.name ??
5661
- row.type ??
5662
- 'unknown';
4429
+ // The EAS schema name ("post"), which `seeds.type` also holds.
4430
+ const schemaName = fromRaw.schema?.schemaNames?.[0]?.name ?? row.type ?? 'unknown';
5663
4431
  return withLocalRevocation({
5664
4432
  ...fromRaw,
5665
4433
  id: row.uid,
@@ -5672,7 +4440,7 @@ function seedRowToAttestation(row) {
5672
4440
  schemaId: fromRaw.schemaId || row.schemaUid || '',
5673
4441
  }, row.revokedAt);
5674
4442
  }
5675
- const schemaName = row.schemaName ?? row.type ?? 'unknown';
4443
+ const schemaName = row.type ?? 'unknown';
5676
4444
  return withLocalRevocation({
5677
4445
  id: row.uid,
5678
4446
  decodedDataJson: '',
@@ -5739,29 +4507,6 @@ function metadataRowToAttestation(row) {
5739
4507
  attester: row.publisher ?? undefined,
5740
4508
  }, row.revokedAt);
5741
4509
  }
5742
- async function resolveSchemaNameForSeedType(appDb, seedType,
5743
- /** seeds.model_file_id: the seed's own model (model names are only unique per schema). */
5744
- modelFileId) {
5745
- if (!seedType)
5746
- return null;
5747
- const normalized = startCase(seedType);
5748
- try {
5749
- const schemaRows = await appDb
5750
- .select({ schemaName: schemas.name })
5751
- .from(models$1)
5752
- .innerJoin(modelSchemas, eq(models$1.id, modelSchemas.modelId))
5753
- .innerJoin(schemas, eq(modelSchemas.schemaId, schemas.id))
5754
- .where(modelFileId ? eq(models$1.schemaFileId, modelFileId) : eq(models$1.name, normalized))
5755
- .orderBy(desc(models$1.id))
5756
- .limit(1);
5757
- if (schemaRows[0]?.schemaName)
5758
- return schemaRows[0].schemaName;
5759
- }
5760
- catch {
5761
- // ignore
5762
- }
5763
- return seedType;
5764
- }
5765
4510
  function monthBoundsUnix(year, month) {
5766
4511
  const startDate = new Date(year, month - 1, 1);
5767
4512
  const endDate = new Date(year, month, 0, 23, 59, 59);
@@ -5783,7 +4528,6 @@ async function listPublishedSeedRows(schemaName, opts) {
5783
4528
  uid: seeds.uid,
5784
4529
  schemaUid: seeds.schemaUid,
5785
4530
  type: seeds.type,
5786
- modelFileId: seeds.modelFileId,
5787
4531
  publisher: seeds.publisher,
5788
4532
  attestationRaw: seeds.attestationRaw,
5789
4533
  attestationCreatedAt: seeds.attestationCreatedAt,
@@ -5812,11 +4556,7 @@ async function listPublishedSeedRows(schemaName, opts) {
5812
4556
  const hasPublished = versionRows.some((v) => v.uid && isValidEasAttestationUid(v.uid) && !isRevokedLocally(v.revokedAt));
5813
4557
  if (!hasPublished)
5814
4558
  continue;
5815
- const schemaResolved = await resolveSchemaNameForSeedType(appDb, row.type, row.modelFileId);
5816
- const att = seedRowToAttestation({
5817
- ...row,
5818
- schemaName: schemaResolved === schemaName ? schemaName : (schemaResolved ?? schemaName),
5819
- });
4559
+ const att = seedRowToAttestation(row);
5820
4560
  if (!att)
5821
4561
  continue;
5822
4562
  // Force requested schema name so assembleSeeds filters correctly
@@ -5851,7 +4591,6 @@ function createLocalQueryDataSource() {
5851
4591
  uid: seeds.uid,
5852
4592
  schemaUid: seeds.schemaUid,
5853
4593
  type: seeds.type,
5854
- modelFileId: seeds.modelFileId,
5855
4594
  publisher: seeds.publisher,
5856
4595
  attestationRaw: seeds.attestationRaw,
5857
4596
  attestationCreatedAt: seeds.attestationCreatedAt,
@@ -5865,8 +4604,7 @@ function createLocalQueryDataSource() {
5865
4604
  return null;
5866
4605
  if (isRevokedLocally(row.revokedAt))
5867
4606
  return null;
5868
- const schemaName = await resolveSchemaNameForSeedType(appDb, row.type, row.modelFileId);
5869
- return seedRowToAttestation({ ...row, schemaName });
4607
+ return seedRowToAttestation(row);
5870
4608
  },
5871
4609
  async listSeedsBySchemaName(schemaName, opts) {
5872
4610
  const all = await listPublishedSeedRows(schemaName);
@@ -5950,7 +4688,6 @@ function createLocalQueryDataSource() {
5950
4688
  uid: seeds.uid,
5951
4689
  schemaUid: seeds.schemaUid,
5952
4690
  type: seeds.type,
5953
- modelFileId: seeds.modelFileId,
5954
4691
  publisher: seeds.publisher,
5955
4692
  attestationRaw: seeds.attestationRaw,
5956
4693
  attestationCreatedAt: seeds.attestationCreatedAt,
@@ -5962,8 +4699,7 @@ function createLocalQueryDataSource() {
5962
4699
  for (const row of rows) {
5963
4700
  if (isRevokedLocally(row.revokedAt))
5964
4701
  continue;
5965
- const schemaName = await resolveSchemaNameForSeedType(appDb, row.type, row.modelFileId);
5966
- const att = seedRowToAttestation({ ...row, schemaName });
4702
+ const att = seedRowToAttestation(row);
5967
4703
  if (att)
5968
4704
  out.push(att);
5969
4705
  }
@@ -6539,5 +5275,5 @@ var ClientManager$1 = /*#__PURE__*/Object.freeze({
6539
5275
  getClient: getClient
6540
5276
  });
6541
5277
 
6542
- export { ClientManager$1 as $, getPublishedSeedRecord as A, getSchemaNameFromId as B, ClientManager as C, isSeedQueryLocalSourceRegistered as D, EAS_CHAIN_ID_APP_STATE_KEY as E, listCompleteSchemaFiles as F, loadAllSchemasFromDb as G, mergeEasSyncRequestIntents as H, INIT_CONFIG_CONFLICT_MESSAGE as I, readSchema as J, registerSeedQueryLocalSource as K, requestEasSyncFromAddressChange as L, requestEasSyncFromEventBus as M, requestEasSyncFromModelsInit as N, sendEasSyncClientRequest as O, setRetriesWhenOnlineEnabled as P, startEasSyncActor as Q, RelationTargetError as R, unregisterSeedQueryLocalSource as S, createRowsWrittenSignal as T, createModelsFromJson as U, getLatestSchemaVersion as V, jsonPropertiesToSchemaProperties as W, schema as X, SEEDPROTOCOL_Seed_Protocol_v1 as Y, conflicts as Z, itemAppliers as _, applyCreateItem as a, applyDelete as b, applyItemStorageValue as c, deleteFiles as d, applyStorageValue as e, getPropertyConflict as f, getItemConflicts as g, getRefValueType as h, importJsonSchema as i, syncSchemaFromSource as j, transformImportToSchemaFile as k, loadSchemaFromFile as l, markPropertyConflictsResolved as m, getContentHash as n, isVerbatimItemStorageDraftRow as o, convertVerbatimItemStorageRow as p, assertLocalDbChain as q, readJsonImportFile as r, startItemOutbox as s, throwItemWriteError as t, claimUnpublishedDrafts as u, createLocalQueryDataSource as v, waitForEasReadChain as w, createSchema as x, easSyncActor as y, getClient as z };
6543
- //# sourceMappingURL=ClientManager-B1r_8P5Z.js.map
5278
+ export { listCompleteSchemaFiles as A, loadAllSchemasFromDb as B, ClientManager as C, mergeEasSyncRequestIntents as D, EAS_CHAIN_ID_APP_STATE_KEY as E, registerSeedQueryLocalSource as F, requestEasSyncFromAddressChange as G, requestEasSyncFromModelsInit as H, INIT_CONFIG_CONFLICT_MESSAGE as I, sendEasSyncClientRequest as J, setRetriesWhenOnlineEnabled as K, startEasSyncActor as L, unregisterSeedQueryLocalSource as M, getLatestSchemaVersion as N, createRowsWrittenSignal as O, createModelsFromJson as P, jsonPropertiesToSchemaProperties as Q, RelationTargetError as R, schema as S, SEEDPROTOCOL_Seed_Protocol_v1 as T, conflicts as U, itemAppliers as V, ClientManager$1 as W, applyCreateItem as a, applyDelete as b, applyItemStorageValue as c, deleteFiles as d, applyStorageValue as e, getPropertyConflict as f, getItemConflicts as g, getRefValueType as h, importJsonSchema as i, syncSchemaFromSource as j, transformImportToSchemaFile as k, loadSchemaFromFile as l, markPropertyConflictsResolved as m, getContentHash as n, assertLocalDbChain as o, claimUnpublishedDrafts as p, createLocalQueryDataSource as q, readJsonImportFile as r, startItemOutbox as s, throwItemWriteError as t, easSyncActor as u, getClient as v, waitForEasReadChain as w, getPublishedSeedRecord as x, getSchemaNameFromId as y, isSeedQueryLocalSourceRegistered as z };
5279
+ //# sourceMappingURL=ClientManager-GZfXErDX.js.map