@seedprotocol/sdk 0.6.9 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (382) hide show
  1. package/dist/{BasePathResolver-B6CKqoKw.js → BasePathResolver-ndE8XTpw.js} +36 -2
  2. package/dist/BasePathResolver-ndE8XTpw.js.map +1 -0
  3. package/dist/ClientManager-DLleL_2e.js +4763 -0
  4. package/dist/ClientManager-DLleL_2e.js.map +1 -0
  5. package/dist/{ClientManager-ChcmUL47.js → Item-zBFWQDU9.js} +1119 -5893
  6. package/dist/Item-zBFWQDU9.js.map +1 -0
  7. package/dist/{ModelProperty-D79uV42p.js → ModelProperty-lth9L37R.js} +289 -101
  8. package/dist/ModelProperty-lth9L37R.js.map +1 -0
  9. package/dist/{Schema-a8uO-hIZ.js → Schema-DOhlrQ-N.js} +94 -864
  10. package/dist/Schema-DOhlrQ-N.js.map +1 -0
  11. package/dist/{SchemaValidationService-Y49vqast.js → SchemaValidationService-DDKr5piy.js} +26 -18
  12. package/dist/SchemaValidationService-DDKr5piy.js.map +1 -0
  13. package/dist/{backfillMetadataPropertyIds-CBsf7LnU.js → backfillMetadataPropertyIds-fG3ujaSh.js} +11 -6
  14. package/dist/backfillMetadataPropertyIds-fG3ujaSh.js.map +1 -0
  15. package/dist/cjs/{ModelProperty-D9FGaGuE.js → ModelProperty-BEsIHAjk.js} +260 -81
  16. package/dist/cjs/ModelProperty-BEsIHAjk.js.map +1 -0
  17. package/dist/cjs/{Schema-BiJIPLEL.js → Schema-qEp5mH1N.js} +66 -847
  18. package/dist/cjs/Schema-qEp5mH1N.js.map +1 -0
  19. package/dist/cjs/{SchemaValidationService-DtYs_CNY.js → SchemaValidationService-CWEnZmOH.js} +18 -11
  20. package/dist/cjs/SchemaValidationService-CWEnZmOH.js.map +1 -0
  21. package/dist/cjs/{backfillMetadataPropertyIds-2XaN3b9S.js → backfillMetadataPropertyIds-tw8JGMT0.js} +8 -3
  22. package/dist/cjs/backfillMetadataPropertyIds-tw8JGMT0.js.map +1 -0
  23. package/dist/cjs/{eas-CMNppmGE.js → eas-CLiV2Hmn.js} +4 -4
  24. package/dist/cjs/{eas-CMNppmGE.js.map → eas-CLiV2Hmn.js.map} +1 -1
  25. package/dist/cjs/{getItem-B6jEINjW.js → getItem-DSRtx_68.js} +2 -2
  26. package/dist/cjs/{getItem-B6jEINjW.js.map → getItem-DSRtx_68.js.map} +1 -1
  27. package/dist/cjs/getLatestVersionRow-DVizNNoI.js +59 -0
  28. package/dist/cjs/getLatestVersionRow-DVizNNoI.js.map +1 -0
  29. package/dist/cjs/{getPublishPayload-D5DhLGvN.js → getPublishPayload-D5-dYtNq.js} +249 -60
  30. package/dist/cjs/getPublishPayload-D5-dYtNq.js.map +1 -0
  31. package/dist/cjs/{getPublishUploads-DMhCCKYF.js → getPublishUploads-B5Lq6q-_.js} +20 -13
  32. package/dist/cjs/getPublishUploads-B5Lq6q-_.js.map +1 -0
  33. package/dist/cjs/{getSegmentedItemProperties-CU8rtBAo.js → getSegmentedItemProperties-giHO7R3d.js} +10 -11
  34. package/dist/cjs/getSegmentedItemProperties-giHO7R3d.js.map +1 -0
  35. package/dist/cjs/{index-DPp9rdRL.js → index-B3UDbm1C.js} +3 -3
  36. package/dist/cjs/index-B3UDbm1C.js.map +1 -0
  37. package/dist/cjs/{index-CSNtEnbF.js → index-C66AfYDG.js} +2510 -1694
  38. package/dist/cjs/index-C66AfYDG.js.map +1 -0
  39. package/dist/cjs/{property-DlKiAWt4.js → property-BVJIP7SX.js} +40 -35
  40. package/dist/cjs/property-BVJIP7SX.js.map +1 -0
  41. package/dist/cjs/resetAmbiguousLegacyItemData-BaZqUui9.js +116 -0
  42. package/dist/cjs/resetAmbiguousLegacyItemData-BaZqUui9.js.map +1 -0
  43. package/dist/cjs/resolveModelForSyncedSeed-CC6dQctx.js +49 -0
  44. package/dist/cjs/resolveModelForSyncedSeed-CC6dQctx.js.map +1 -0
  45. package/dist/cjs/syncDbWithEas-Dk96sAG-.js +873 -0
  46. package/dist/cjs/syncDbWithEas-Dk96sAG-.js.map +1 -0
  47. package/dist/{configurePlatform-CE0Vew17.js → configurePlatform-BMoPG9vY.js} +4 -4
  48. package/dist/{configurePlatform-CE0Vew17.js.map → configurePlatform-BMoPG9vY.js.map} +1 -1
  49. package/dist/db/drizzle/0015_add_model_file_id_to_seeds.sql +11 -0
  50. package/dist/db/drizzle/0016_add_revoked_at_to_metadata.sql +1 -0
  51. package/dist/db/drizzle/0017_add_revoked_at_to_versions.sql +1 -0
  52. package/dist/db/drizzle/0018_add_storage_settings_to_properties.sql +53 -0
  53. package/dist/db/drizzle/0019_add_derived_from_uid_to_metadata.sql +35 -0
  54. package/dist/db/drizzle/meta/0011_snapshot.json +1182 -0
  55. package/dist/db/drizzle/meta/0012_snapshot.json +1244 -0
  56. package/dist/db/drizzle/meta/0013_snapshot.json +63 -1
  57. package/dist/db/drizzle/meta/0014_snapshot.json +62 -0
  58. package/dist/db/drizzle/meta/0015_snapshot.json +1338 -0
  59. package/dist/db/drizzle/meta/0016_snapshot.json +1345 -0
  60. package/dist/db/drizzle/meta/0017_snapshot.json +1352 -0
  61. package/dist/db/drizzle/meta/0018_snapshot.json +1373 -0
  62. package/dist/db/drizzle/meta/0019_snapshot.json +1380 -0
  63. package/dist/db/drizzle/meta/_journal.json +35 -0
  64. package/dist/{db-WbrzEf7c.js → db-BJZN0a0a.js} +546 -106
  65. package/dist/db-BJZN0a0a.js.map +1 -0
  66. package/dist/{eas-CfYCu4IX.js → eas-B0hsMLqt.js} +7 -7
  67. package/dist/eas-B0hsMLqt.js.map +1 -0
  68. package/dist/errors-CrBxGWah.js +17 -0
  69. package/dist/errors-CrBxGWah.js.map +1 -0
  70. package/dist/{getItem-Br-bGNFO.js → getItem-DEh4WfHG.js} +8 -10
  71. package/dist/{getItem-Br-bGNFO.js.map → getItem-DEh4WfHG.js.map} +1 -1
  72. package/dist/getLatestVersionRow-Brrl1AnW.js +46 -0
  73. package/dist/getLatestVersionRow-Brrl1AnW.js.map +1 -0
  74. package/dist/{getPublishPayload-BIrTVUxb.js → getPublishPayload-H032DHC7.js} +263 -75
  75. package/dist/getPublishPayload-H032DHC7.js.map +1 -0
  76. package/dist/{getPublishUploads-C6cDeZdz.js → getPublishUploads-CR66RlGJ.js} +25 -17
  77. package/dist/{getPublishUploads-C6cDeZdz.js.map → getPublishUploads-CR66RlGJ.js.map} +1 -1
  78. package/dist/{getSegmentedItemProperties-BmKE71vU.js → getSegmentedItemProperties-C2EJ2G0N.js} +13 -14
  79. package/dist/getSegmentedItemProperties-C2EJ2G0N.js.map +1 -0
  80. package/dist/{index-ClSv5pTA.js → index-6bJuv5Tt.js} +12 -11
  81. package/dist/index-6bJuv5Tt.js.map +1 -0
  82. package/dist/{index-Djd3667v.js → index-B0LgJblD.js} +2 -2
  83. package/dist/index-B0LgJblD.js.map +1 -0
  84. package/dist/{index-HRHkbVQd.js → index-DtfjeuxC.js} +417 -174
  85. package/dist/index-DtfjeuxC.js.map +1 -0
  86. package/dist/index.browser-CNrqhvEA.js +4139 -0
  87. package/dist/index.browser-CNrqhvEA.js.map +1 -0
  88. package/dist/{index.node-DBtQkEfz.js → index.node-DrHiTuOr.js} +9 -4
  89. package/dist/index.node-DrHiTuOr.js.map +1 -0
  90. package/dist/main.cjs +1 -1
  91. package/dist/main.js +771 -521
  92. package/dist/main.js.map +1 -1
  93. package/dist/node.js +19 -15
  94. package/dist/node.js.map +1 -1
  95. package/dist/platform.browser.js +18 -3719
  96. package/dist/platform.browser.js.map +1 -1
  97. package/dist/platform.node.js +3 -3
  98. package/dist/{property-CQjuZ4JW.js → property-D2Nnsmm1.js} +53 -48
  99. package/dist/property-D2Nnsmm1.js.map +1 -0
  100. package/dist/resetAmbiguousLegacyItemData-BqbHNUYk.js +88 -0
  101. package/dist/resetAmbiguousLegacyItemData-BqbHNUYk.js.map +1 -0
  102. package/dist/resolveModelForSyncedSeed-DQK6JfXS.js +46 -0
  103. package/dist/resolveModelForSyncedSeed-DQK6JfXS.js.map +1 -0
  104. package/dist/seedSchema/MetadataSchema.ts +9 -0
  105. package/dist/seedSchema/ModelSchema.ts +5 -0
  106. package/dist/seedSchema/SeedSchema.ts +3 -0
  107. package/dist/seedSchema/VersionSchema.ts +5 -0
  108. package/dist/src/Item/Item.d.ts +10 -0
  109. package/dist/src/Item/Item.d.ts.map +1 -1
  110. package/dist/src/Item/service/actors/loadOrCreateItem.d.ts.map +1 -1
  111. package/dist/src/Item/service/actors/waitForDb.d.ts.map +1 -1
  112. package/dist/src/Item/service/itemMachineSingle.d.ts +3 -29
  113. package/dist/src/Item/service/itemMachineSingle.d.ts.map +1 -1
  114. package/dist/src/ItemProperty/ItemProperty.d.ts +3 -4
  115. package/dist/src/ItemProperty/ItemProperty.d.ts.map +1 -1
  116. package/dist/src/ItemProperty/service/actors/hydrateFromDb.d.ts.map +1 -1
  117. package/dist/src/ItemProperty/service/actors/loadOrCreateProperty.d.ts.map +1 -1
  118. package/dist/src/ItemProperty/service/actors/saveValueToDb/saveFile.d.ts.map +1 -1
  119. package/dist/src/ItemProperty/service/actors/saveValueToDb/saveHtml.d.ts.map +1 -1
  120. package/dist/src/ItemProperty/service/actors/saveValueToDb/saveImage.d.ts.map +1 -1
  121. package/dist/src/ItemProperty/service/actors/saveValueToDb/saveItemStorage.d.ts.map +1 -1
  122. package/dist/src/ItemProperty/service/propertyMachine.d.ts +4 -9
  123. package/dist/src/ItemProperty/service/propertyMachine.d.ts.map +1 -1
  124. package/dist/src/Model/Model.d.ts +37 -0
  125. package/dist/src/Model/Model.d.ts.map +1 -1
  126. package/dist/src/Model/errors.d.ts +10 -0
  127. package/dist/src/Model/errors.d.ts.map +1 -0
  128. package/dist/src/Model/service/actors/createModelProperties.d.ts.map +1 -1
  129. package/dist/src/Model/service/actors/loadOrCreateModel.d.ts.map +1 -1
  130. package/dist/src/Model/service/modelMachine.d.ts +0 -8
  131. package/dist/src/Model/service/modelMachine.d.ts.map +1 -1
  132. package/dist/src/ModelProperty/ModelProperty.d.ts +33 -1
  133. package/dist/src/ModelProperty/ModelProperty.d.ts.map +1 -1
  134. package/dist/src/ModelProperty/service/actors/compareAndMarkDraft.d.ts.map +1 -1
  135. package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts +2 -9
  136. package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts.map +1 -1
  137. package/dist/src/Schema/Schema.d.ts +1 -2
  138. package/dist/src/Schema/Schema.d.ts.map +1 -1
  139. package/dist/src/Schema/service/schemaMachine.d.ts +1 -217
  140. package/dist/src/Schema/service/schemaMachine.d.ts.map +1 -1
  141. package/dist/src/Schema/service/validation/SchemaValidationService.d.ts.map +1 -1
  142. package/dist/src/browser/db/Db.d.ts +3 -0
  143. package/dist/src/browser/db/Db.d.ts.map +1 -1
  144. package/dist/src/browser/db/drizzleFiles.d.ts +7 -2
  145. package/dist/src/browser/db/drizzleFiles.d.ts.map +1 -1
  146. package/dist/src/browser/db/embeddedMigrations.d.ts +11 -2
  147. package/dist/src/browser/db/embeddedMigrations.d.ts.map +1 -1
  148. package/dist/src/browser/db/sqliteBusyRetry.d.ts +14 -0
  149. package/dist/src/browser/db/sqliteBusyRetry.d.ts.map +1 -0
  150. package/dist/src/browser/helpers/FileManager.d.ts +1 -0
  151. package/dist/src/browser/helpers/FileManager.d.ts.map +1 -1
  152. package/dist/src/browser/helpers/QueryClient.d.ts +1 -0
  153. package/dist/src/browser/helpers/QueryClient.d.ts.map +1 -1
  154. package/dist/src/browser/helpers/opfsErrors.d.ts +2 -0
  155. package/dist/src/browser/helpers/opfsErrors.d.ts.map +1 -0
  156. package/dist/src/browser/helpers/tolerantWebAccess.d.ts +47 -0
  157. package/dist/src/browser/helpers/tolerantWebAccess.d.ts.map +1 -0
  158. package/dist/src/browser/workers/FileDownloader.d.ts.map +1 -1
  159. package/dist/src/browser/workers/ImageResizer.d.ts.map +1 -1
  160. package/dist/src/browser/workers/filesDownload.d.ts.map +1 -1
  161. package/dist/src/browser/workers/imageResize.d.ts.map +1 -1
  162. package/dist/src/client/ClientManager.d.ts.map +1 -1
  163. package/dist/src/client/actors/addModelsToDb.d.ts +14 -0
  164. package/dist/src/client/actors/addModelsToDb.d.ts.map +1 -1
  165. package/dist/src/client/actors/platformClassesInit.d.ts.map +1 -1
  166. package/dist/src/client/actors/processSchemaFiles.d.ts.map +1 -1
  167. package/dist/src/client/actors/saveConfig.d.ts +11 -0
  168. package/dist/src/client/actors/saveConfig.d.ts.map +1 -1
  169. package/dist/src/client/constants.d.ts +0 -8
  170. package/dist/src/client/constants.d.ts.map +1 -1
  171. package/dist/src/db/backfillMetadataPropertyIds.d.ts.map +1 -1
  172. package/dist/src/db/configs/{dev.schema.config.d.ts → migrations.config.d.ts} +1 -1
  173. package/dist/src/db/configs/migrations.config.d.ts.map +1 -0
  174. package/dist/src/db/read/batchLatestPublishedVersionBySeedLocalIds.d.ts +1 -1
  175. package/dist/src/db/read/batchLatestPublishedVersionBySeedLocalIds.d.ts.map +1 -1
  176. package/dist/src/db/read/getItemData.d.ts.map +1 -1
  177. package/dist/src/db/read/getItemProperties.d.ts.map +1 -1
  178. package/dist/src/db/read/getItems.d.ts +7 -2
  179. package/dist/src/db/read/getItems.d.ts.map +1 -1
  180. package/dist/src/db/read/getLatestPublishedVersionRow.d.ts +2 -1
  181. package/dist/src/db/read/getLatestPublishedVersionRow.d.ts.map +1 -1
  182. package/dist/src/db/read/getLatestVersionRow.d.ts +13 -0
  183. package/dist/src/db/read/getLatestVersionRow.d.ts.map +1 -0
  184. package/dist/src/db/read/getModelSchemas.d.ts.map +1 -1
  185. package/dist/src/db/read/getPropertyData.d.ts.map +1 -1
  186. package/dist/src/db/read/getPublishPayload.d.ts +9 -11
  187. package/dist/src/db/read/getPublishPayload.d.ts.map +1 -1
  188. package/dist/src/db/read/getPublishPendingDiff.d.ts +2 -1
  189. package/dist/src/db/read/getPublishPendingDiff.d.ts.map +1 -1
  190. package/dist/src/db/read/getPublishUploads.d.ts.map +1 -1
  191. package/dist/src/db/read/getSchemaUidForModel.d.ts.map +1 -1
  192. package/dist/src/db/read/getSeedPublishState.d.ts +8 -2
  193. package/dist/src/db/read/getSeedPublishState.d.ts.map +1 -1
  194. package/dist/src/db/read/isSeedRevoked.d.ts +7 -0
  195. package/dist/src/db/read/isSeedRevoked.d.ts.map +1 -0
  196. package/dist/src/db/read/publishErrors.d.ts +37 -0
  197. package/dist/src/db/read/publishErrors.d.ts.map +1 -0
  198. package/dist/src/db/read/resolveModelForSyncedSeed.d.ts +39 -0
  199. package/dist/src/db/read/resolveModelForSyncedSeed.d.ts.map +1 -0
  200. package/dist/src/db/read/resolveModelRecord.d.ts +69 -0
  201. package/dist/src/db/read/resolveModelRecord.d.ts.map +1 -0
  202. package/dist/src/db/read/resolveRelatedSeedRef.d.ts +34 -0
  203. package/dist/src/db/read/resolveRelatedSeedRef.d.ts.map +1 -0
  204. package/dist/src/db/read/subqueries/liveVersion.d.ts +12 -0
  205. package/dist/src/db/read/subqueries/liveVersion.d.ts.map +1 -0
  206. package/dist/src/db/read/subqueries/metadataLatest.d.ts +4 -0
  207. package/dist/src/db/read/subqueries/metadataLatest.d.ts.map +1 -1
  208. package/dist/src/db/read/subqueries/versionData.d.ts +7 -2
  209. package/dist/src/db/read/subqueries/versionData.d.ts.map +1 -1
  210. package/dist/src/db/read/summarizePublishWork.d.ts +10 -2
  211. package/dist/src/db/read/summarizePublishWork.d.ts.map +1 -1
  212. package/dist/src/db/resetAmbiguousLegacyItemData.d.ts +17 -0
  213. package/dist/src/db/resetAmbiguousLegacyItemData.d.ts.map +1 -0
  214. package/dist/src/db/sqlParamBatches.d.ts +27 -0
  215. package/dist/src/db/sqlParamBatches.d.ts.map +1 -0
  216. package/dist/src/db/write/addExcludedTransactions.d.ts +7 -0
  217. package/dist/src/db/write/addExcludedTransactions.d.ts.map +1 -0
  218. package/dist/src/db/write/applyPropertyAttestationUidsFromPublish.d.ts +6 -0
  219. package/dist/src/db/write/applyPropertyAttestationUidsFromPublish.d.ts.map +1 -1
  220. package/dist/src/db/write/createMetadata.d.ts +2 -0
  221. package/dist/src/db/write/createMetadata.d.ts.map +1 -1
  222. package/dist/src/db/write/createNewItem.d.ts +3 -1
  223. package/dist/src/db/write/createNewItem.d.ts.map +1 -1
  224. package/dist/src/db/write/createSeed.d.ts +2 -1
  225. package/dist/src/db/write/createSeed.d.ts.map +1 -1
  226. package/dist/src/db/write/createSeeds.d.ts +1 -1
  227. package/dist/src/db/write/createSeeds.d.ts.map +1 -1
  228. package/dist/src/db/write/linkModelToSchema.d.ts +12 -0
  229. package/dist/src/db/write/linkModelToSchema.d.ts.map +1 -0
  230. package/dist/src/db/write/updateItemPropertyValue.d.ts.map +1 -1
  231. package/dist/src/db/write/updateMetadata.d.ts.map +1 -1
  232. package/dist/src/db/write/updateSeedRevokedAt.d.ts +11 -1
  233. package/dist/src/db/write/updateSeedRevokedAt.d.ts.map +1 -1
  234. package/dist/src/db/write/updateSeedUid.d.ts.map +1 -1
  235. package/dist/src/db/write/updateVersionUid.d.ts +2 -1
  236. package/dist/src/db/write/updateVersionUid.d.ts.map +1 -1
  237. package/dist/src/events/files/download.d.ts.map +1 -1
  238. package/dist/src/events/item/easSyncManager.d.ts +2 -0
  239. package/dist/src/events/item/easSyncManager.d.ts.map +1 -1
  240. package/dist/src/events/item/index.d.ts.map +1 -1
  241. package/dist/src/events/item/syncDbWithEas.d.ts +16 -0
  242. package/dist/src/events/item/syncDbWithEas.d.ts.map +1 -1
  243. package/dist/src/helpers/FileManager/BaseFileManager.d.ts +1 -0
  244. package/dist/src/helpers/FileManager/BaseFileManager.d.ts.map +1 -1
  245. package/dist/src/helpers/FileManager/IFileManager.d.ts +5 -0
  246. package/dist/src/helpers/FileManager/IFileManager.d.ts.map +1 -1
  247. package/dist/src/helpers/FileManager/errors.d.ts +10 -0
  248. package/dist/src/helpers/FileManager/errors.d.ts.map +1 -0
  249. package/dist/src/helpers/compareMetadataRowsLatestFirst.d.ts +21 -3
  250. package/dist/src/helpers/compareMetadataRowsLatestFirst.d.ts.map +1 -1
  251. package/dist/src/helpers/constants.d.ts +9 -0
  252. package/dist/src/helpers/constants.d.ts.map +1 -1
  253. package/dist/src/helpers/crypto.d.ts +5 -0
  254. package/dist/src/helpers/crypto.d.ts.map +1 -1
  255. package/dist/src/helpers/db.d.ts +25 -5
  256. package/dist/src/helpers/db.d.ts.map +1 -1
  257. package/dist/src/helpers/easPropertyCanonical.d.ts +1 -1
  258. package/dist/src/helpers/easPropertyCanonical.d.ts.map +1 -1
  259. package/dist/src/helpers/entity/entityCommon.d.ts +10 -0
  260. package/dist/src/helpers/entity/entityCommon.d.ts.map +1 -1
  261. package/dist/src/helpers/entity/entityDestroy.d.ts +1 -1
  262. package/dist/src/helpers/entity/entityDestroy.d.ts.map +1 -1
  263. package/dist/src/helpers/entity/entityLiveQuery.d.ts +5 -0
  264. package/dist/src/helpers/entity/entityLiveQuery.d.ts.map +1 -1
  265. package/dist/src/helpers/file/fetchAll/actors.d.ts.map +1 -1
  266. package/dist/src/helpers/getSegmentedItemProperties.d.ts.map +1 -1
  267. package/dist/src/helpers/htmlEmbeddedDataUriPublish.d.ts +6 -0
  268. package/dist/src/helpers/htmlEmbeddedDataUriPublish.d.ts.map +1 -1
  269. package/dist/src/helpers/isPublishedMetadataRow.d.ts +10 -0
  270. package/dist/src/helpers/isPublishedMetadataRow.d.ts.map +1 -0
  271. package/dist/src/helpers/ownership.d.ts.map +1 -1
  272. package/dist/src/helpers/property.d.ts +6 -1
  273. package/dist/src/helpers/property.d.ts.map +1 -1
  274. package/dist/src/helpers/schema.d.ts +14 -4
  275. package/dist/src/helpers/schema.d.ts.map +1 -1
  276. package/dist/src/helpers/tabCoordinator.d.ts +45 -0
  277. package/dist/src/helpers/tabCoordinator.d.ts.map +1 -0
  278. package/dist/src/helpers/tabEvents.d.ts +27 -0
  279. package/dist/src/helpers/tabEvents.d.ts.map +1 -0
  280. package/dist/src/helpers/tabLocks.d.ts +28 -0
  281. package/dist/src/helpers/tabLocks.d.ts.map +1 -0
  282. package/dist/src/helpers/updateSchema.d.ts.map +1 -1
  283. package/dist/src/imports/json.d.ts.map +1 -1
  284. package/dist/src/imports/markdown.d.ts.map +1 -1
  285. package/dist/src/index.d.ts +11 -2
  286. package/dist/src/index.d.ts.map +1 -1
  287. package/dist/src/node/db/Db.d.ts.map +1 -1
  288. package/dist/src/node/helpers/FileManager.d.ts +2 -0
  289. package/dist/src/node/helpers/FileManager.d.ts.map +1 -1
  290. package/dist/src/query/createLocalQueryDataSource.d.ts +4 -0
  291. package/dist/src/query/createLocalQueryDataSource.d.ts.map +1 -1
  292. package/dist/src/seedSchema/MetadataSchema.d.ts +36 -0
  293. package/dist/src/seedSchema/MetadataSchema.d.ts.map +1 -1
  294. package/dist/src/seedSchema/ModelSchema.d.ts +57 -0
  295. package/dist/src/seedSchema/ModelSchema.d.ts.map +1 -1
  296. package/dist/src/seedSchema/SeedSchema.d.ts +19 -0
  297. package/dist/src/seedSchema/SeedSchema.d.ts.map +1 -1
  298. package/dist/src/seedSchema/VersionSchema.d.ts +17 -0
  299. package/dist/src/seedSchema/VersionSchema.d.ts.map +1 -1
  300. package/dist/src/services/write/actors/writeToDatabase.d.ts +5 -0
  301. package/dist/src/services/write/actors/writeToDatabase.d.ts.map +1 -1
  302. package/dist/src/services/write/writeProcessMachine.d.ts.map +1 -1
  303. package/dist/src/stores/eas.d.ts +1 -1
  304. package/dist/src/stores/eas.d.ts.map +1 -1
  305. package/dist/src/types/index.d.ts +7 -0
  306. package/dist/src/types/index.d.ts.map +1 -1
  307. package/dist/src/types/item.d.ts +12 -3
  308. package/dist/src/types/item.d.ts.map +1 -1
  309. package/dist/src/types/property.d.ts +3 -2
  310. package/dist/src/types/property.d.ts.map +1 -1
  311. package/dist/syncDbWithEas-LRKr_NZF.js +855 -0
  312. package/dist/syncDbWithEas-LRKr_NZF.js.map +1 -0
  313. package/dist/{index-280bL-n4.js → tabEvents-DYI2GU7i.js} +231 -68
  314. package/dist/tabEvents-DYI2GU7i.js.map +1 -0
  315. package/dist/tolerantWebAccess-CzOBz5M6.js +160 -0
  316. package/dist/tolerantWebAccess-CzOBz5M6.js.map +1 -0
  317. package/dist/updateSeedRevokedAt-B58ORbY3.js +32 -0
  318. package/dist/updateSeedRevokedAt-B58ORbY3.js.map +1 -0
  319. package/package.json +5 -5
  320. package/dist/BasePathResolver-B6CKqoKw.js.map +0 -1
  321. package/dist/ClientManager-ChcmUL47.js.map +0 -1
  322. package/dist/ModelProperty-D79uV42p.js.map +0 -1
  323. package/dist/Schema-a8uO-hIZ.js.map +0 -1
  324. package/dist/SchemaValidationService-Y49vqast.js.map +0 -1
  325. package/dist/backfillMetadataPropertyIds-CBsf7LnU.js.map +0 -1
  326. package/dist/cjs/ModelProperty-D9FGaGuE.js.map +0 -1
  327. package/dist/cjs/Schema-BiJIPLEL.js.map +0 -1
  328. package/dist/cjs/SchemaValidationService-DtYs_CNY.js.map +0 -1
  329. package/dist/cjs/backfillMetadataPropertyIds-2XaN3b9S.js.map +0 -1
  330. package/dist/cjs/getPublishPayload-D5DhLGvN.js.map +0 -1
  331. package/dist/cjs/getPublishUploads-DMhCCKYF.js.map +0 -1
  332. package/dist/cjs/getSegmentedItemProperties-CU8rtBAo.js.map +0 -1
  333. package/dist/cjs/index-CSNtEnbF.js.map +0 -1
  334. package/dist/cjs/index-DPp9rdRL.js.map +0 -1
  335. package/dist/cjs/property-DlKiAWt4.js.map +0 -1
  336. package/dist/cjs/syncDbWithEas-C6n34o_Q.js +0 -606
  337. package/dist/cjs/syncDbWithEas-C6n34o_Q.js.map +0 -1
  338. package/dist/db-WbrzEf7c.js.map +0 -1
  339. package/dist/eas-CfYCu4IX.js.map +0 -1
  340. package/dist/getPublishPayload-BIrTVUxb.js.map +0 -1
  341. package/dist/getSegmentedItemProperties-BmKE71vU.js.map +0 -1
  342. package/dist/index-280bL-n4.js.map +0 -1
  343. package/dist/index-ClSv5pTA.js.map +0 -1
  344. package/dist/index-Djd3667v.js.map +0 -1
  345. package/dist/index-HRHkbVQd.js.map +0 -1
  346. package/dist/index.node-DBtQkEfz.js.map +0 -1
  347. package/dist/property-CQjuZ4JW.js.map +0 -1
  348. package/dist/src/Item/service/actors/fetchDataFromEas.d.ts +0 -4
  349. package/dist/src/Item/service/actors/fetchDataFromEas.d.ts.map +0 -1
  350. package/dist/src/Item/service/actors/hydrateExistingItem.d.ts +0 -4
  351. package/dist/src/Item/service/actors/hydrateExistingItem.d.ts.map +0 -1
  352. package/dist/src/Item/service/actors/hydrateNewItem.d.ts +0 -4
  353. package/dist/src/Item/service/actors/hydrateNewItem.d.ts.map +0 -1
  354. package/dist/src/Item/service/actors/initialize.d.ts +0 -4
  355. package/dist/src/Item/service/actors/initialize.d.ts.map +0 -1
  356. package/dist/src/Item/service/actors/reload.d.ts +0 -5
  357. package/dist/src/Item/service/actors/reload.d.ts.map +0 -1
  358. package/dist/src/Item/service/actors/saveDataToDb.d.ts +0 -4
  359. package/dist/src/Item/service/actors/saveDataToDb.d.ts.map +0 -1
  360. package/dist/src/ItemProperty/service/actors/resolveRemoteStorage.d.ts +0 -5
  361. package/dist/src/ItemProperty/service/actors/resolveRemoteStorage.d.ts.map +0 -1
  362. package/dist/src/Schema/service/addModelsMachine.d.ts +0 -123
  363. package/dist/src/Schema/service/addModelsMachine.d.ts.map +0 -1
  364. package/dist/src/db/configs/dev.schema.config.d.ts.map +0 -1
  365. package/dist/src/helpers/file/download/actors.d.ts +0 -17
  366. package/dist/src/helpers/file/download/actors.d.ts.map +0 -1
  367. package/dist/src/helpers/file/download/index.d.ts +0 -70
  368. package/dist/src/helpers/file/download/index.d.ts.map +0 -1
  369. package/dist/src/services/publish/actors/createPublishAttempt.d.ts +0 -4
  370. package/dist/src/services/publish/actors/createPublishAttempt.d.ts.map +0 -1
  371. package/dist/src/services/publish/actors/preparePublishRequestData.d.ts +0 -4
  372. package/dist/src/services/publish/actors/preparePublishRequestData.d.ts.map +0 -1
  373. package/dist/src/services/publish/actors/upload.d.ts +0 -4
  374. package/dist/src/services/publish/actors/upload.d.ts.map +0 -1
  375. package/dist/src/services/publish/actors/validateItemData.d.ts +0 -4
  376. package/dist/src/services/publish/actors/validateItemData.d.ts.map +0 -1
  377. package/dist/src/services/publish/publishMachine.d.ts +0 -32
  378. package/dist/src/services/publish/publishMachine.d.ts.map +0 -1
  379. package/dist/syncDbWithEas-CuARXfyN.js +0 -598
  380. package/dist/syncDbWithEas-CuARXfyN.js.map +0 -1
  381. package/dist/updateSeedRevokedAt-CBcLfHWs.js +0 -22
  382. package/dist/updateSeedRevokedAt-CBcLfHWs.js.map +0 -1
package/dist/main.js CHANGED
@@ -1,50 +1,56 @@
1
1
  import 'reflect-metadata';
2
- export { M as Model } from './index-HRHkbVQd.js';
3
- import { o as normalizePublisher, k as isDataType, M as ModelPropertyDataTypes, n as normalizeDataType } from './db-WbrzEf7c.js';
4
- export { v as getAddressesForItemsFilter, w as normalizeAddressConfig, x as normalizeAddressList, r as normalizeHexAddress } from './db-WbrzEf7c.js';
5
- export { getPropertySchema } from './property-CQjuZ4JW.js';
6
- import { n as normalizeRelationPropertyValue, r as resolveSeedIdsFromRefString, b as getArweaveUrlForTransaction } from './index-280bL-n4.js';
7
- export { c as classifyMediaRef, d as closestImageSize, f as ensureImageLocal, e as eventEmitter, g as getCorrectId, h as getFeedItemStringField, i as isPublishedSeedRef, j as normalizeArweaveTxIdForEnsure, k as normalizeFeedItemFields, l as resolveMediaRef } from './index-280bL-n4.js';
8
- import { x as compareMetadataRowsLatestFirst, c as getLatestPublishedVersionRow, p as parseListPropertyValueFromStorage, I as Item, g as getContentHash, n as waitForEntityIdle } from './ClientManager-ChcmUL47.js';
9
- export { A as ADDRESSES_PERSISTED_EVENT, y as ClientManagerState, E as EAS_CHAIN_ID_APP_STATE_KEY, f as ItemProperty, h as ItemPropertySaveValidationError, L as LOCAL_COPIES_REMOVED_EVENT, M as MachineIds, d as assertLocalDbChain, z as claimUnpublishedDrafts, C as client, B as createLocalQueryDataSource, D as createNewItem, F as createSchema, G as easSyncActor, H as getClient, J as getEasSchemaForItemProperty, e as getGetAdditionalSyncAddresses, K as getGetPublisherForNewSeeds, N as getMetadataLatest, O as getPublishedSeedRecord, P as getRevokeExecutor, Q as getSchemaNameFromId, R as getUploadExecutor, S as getVersionData, j as importJsonSchema, T as isItemOwned, U as isLocalUnsealedDraft, V as isSeedQueryLocalSourceRegistered, W as isSeedRowOwned, l as listRelationEasPropertyName, X as listSchemas, Y as loadAllSchemasFromDb, Z as mergeEasSyncRequestIntents, _ as ownedPublisherSql, $ as parseAddressesPersistedPayload, a0 as propertyMachine, a1 as publisherInAddressListSql, a2 as publisherIsInOwnedSet, m as readJsonImportFile, a3 as readSchema, a4 as registerSeedQueryLocalSource, a5 as requestEasSyncFromAddressChange, a6 as requestEasSyncFromEventBus, a7 as requestEasSyncFromModelsInit, a8 as sendEasSyncClientRequest, a9 as setAdditionalSyncAddresses, aa as setGetPublisherForNewSeeds, ab as setRevokeExecutor, ac as setUploadExecutor, ad as startEasSyncActor, s as syncSchemaFromSource, t as transformImportToSchemaFile, ae as unregisterSeedQueryLocalSource } from './ClientManager-ChcmUL47.js';
10
- import { a as BaseDb, v as versions, b as metadata, r as seeds, I as INTERNAL_PROPERTY_NAMES, Z as ZERO_BYTES32, B as BaseFileManager, h as htmlEmbeddedImageCoPublish } from './BasePathResolver-B6CKqoKw.js';
11
- export { E as EAS_SEED_DATA_SYNCED_TO_DB_EVENT, x as INTERNAL_DATA_TYPES, C as ImageSize, D as SEED_PROTOCOL_SCHEMA_NAME, F as SeedModels, G as VERSION_SCHEMA_DEF, V as VERSION_SCHEMA_UID, H as VERSION_SCHEMA_UID_OPTIMISM_SEPOLIA, c as appState, d as arweaveL1FinalizeJobs, f as easSyncProcesses, i as modelSchemas, j as modelUids, m as models, p as properties, o as propertyUids, q as publishProcesses, s as schemas, u as uploadProcesses } from './BasePathResolver-B6CKqoKw.js';
12
- import { eq, desc, or, and, isNotNull, ne } from 'drizzle-orm';
2
+ export { M as Model } from './index-DtfjeuxC.js';
3
+ import { s as normalizePublisher, k as isDataType, M as ModelPropertyDataTypes, n as normalizeDataType } from './db-BJZN0a0a.js';
4
+ export { A as AmbiguousModelError, o as eventEmitter, z as getAddressesForItemsFilter, C as normalizeAddressConfig, E as normalizeAddressList, u as normalizeHexAddress } from './db-BJZN0a0a.js';
5
+ export { getPropertySchema } from './property-D2Nnsmm1.js';
6
+ import { n as normalizeRelationPropertyValue, r as resolveSeedIdsFromRefString, b as getArweaveUrlForTransaction } from './tabEvents-DYI2GU7i.js';
7
+ export { A as ADDRESSES_PERSISTED_EVENT, F as FILES_CHANGED_EVENT, L as LOCAL_COPIES_REMOVED_EVENT, T as TabLockTimeoutError, c as classifyMediaRef, d as closestImageSize, f as ensureImageLocal, g as getCorrectId, h as getFeedItemStringField, j as isLeaderTab, i as isPublishedSeedRef, k as normalizeArweaveTxIdForEnsure, l as normalizeFeedItemFields, p as parseAddressesPersistedPayload, m as resolveMediaRef, w as whenLeaderTab } from './tabEvents-DYI2GU7i.js';
8
+ import { g as getContentHash } from './ClientManager-DLleL_2e.js';
9
+ export { E as EAS_CHAIN_ID_APP_STATE_KEY, a as assertLocalDbChain, c as claimUnpublishedDrafts, C as client, d as createLocalQueryDataSource, e as createSchema, f as easSyncActor, h as getClient, j as getPublishedSeedRecord, k as getSchemaNameFromId, i as importJsonSchema, m as isSeedQueryLocalSourceRegistered, n as listSchemas, o as loadAllSchemasFromDb, p as mergeEasSyncRequestIntents, r as readJsonImportFile, q as readSchema, u as registerSeedQueryLocalSource, v as requestEasSyncFromAddressChange, x as requestEasSyncFromEventBus, y as requestEasSyncFromModelsInit, z as sendEasSyncClientRequest, A as startEasSyncActor, s as syncSchemaFromSource, t as transformImportToSchemaFile, B as unregisterSeedQueryLocalSource } from './ClientManager-DLleL_2e.js';
10
+ import { i as isVersionRevoked, q as compareMetadataRowsLatestFirst, t as isPublishedMetadataRow, h as getLatestPublishedVersionRow, p as parseListPropertyValueFromStorage, I as Item, j as waitForEntityIdle } from './Item-zBFWQDU9.js';
11
+ export { C as ClientManagerState, d as ItemProperty, e as ItemPropertySaveValidationError, M as METADATA_LATEST_FIRST_ORDER_SQL, u as MachineIds, x as createNewItem, y as getEasSchemaForItemProperty, b as getGetAdditionalSyncAddresses, z as getGetPublisherForNewSeeds, A as getMetadataLatest, B as getRevokeExecutor, D as getUploadExecutor, E as getVersionData, F as isItemOwned, G as isLocalUnsealedDraft, H as isSeedRowOwned, l as listRelationEasPropertyName, J as ownedPublisherSql, K as pickLatestMetadataRowPerProperty, L as propertyMachine, N as publisherInAddressListSql, O as publisherIsInOwnedSet, P as setAdditionalSyncAddresses, Q as setGetPublisherForNewSeeds, R as setRevokeExecutor, S as setUploadExecutor } from './Item-zBFWQDU9.js';
12
+ import { B as BaseDb, v as versions, r as seeds, b as metadata, h as htmlEmbeddedImageCoPublish, Z as ZERO_BYTES32, a as BaseFileManager, C as INTERNAL_STORAGE_MODEL_FILE_IDS, y as INTERNAL_PROPERTY_NAMES } from './BasePathResolver-ndE8XTpw.js';
13
+ export { E as EAS_SEED_DATA_SYNCED_TO_DB_EVENT, A as INTERNAL_DATA_TYPES, D as ImageSize, F as SEED_PROTOCOL_SCHEMA_NAME, G as SeedModels, H as VERSION_SCHEMA_DEF, V as VERSION_SCHEMA_UID, J as VERSION_SCHEMA_UID_OPTIMISM_SEPOLIA, c as appState, d as arweaveL1FinalizeJobs, f as easSyncProcesses, i as modelSchemas, j as modelUids, m as models, p as properties, o as propertyUids, q as publishProcesses, s as schemas, u as uploadProcesses } from './BasePathResolver-ndE8XTpw.js';
14
+ import { eq, desc, and, or, isNotNull, ne } from 'drizzle-orm';
13
15
  import { isPlaceholderUid, isValidEasAttestationUid, normalizeBytes32Hex } from '@seedprotocol/eas';
14
16
  export { EAS_CHAIN_DEPLOYMENTS, BaseEasClient as EasClient, getCanonicalItemPropertiesFromEas, getEasChainDeployment, getEasEndpoint, getEasReadChainId, getEasSchemaUidBySchemaName, getItemPropertiesFromEas, getItemVersionsFromEas, getSeedsBySchemaName, getSeedsFromSchemaUids, isPlaceholderUid, isValidEasAttestationUid, normalizeBytes32Hex, pickLatestPropertyAttestationsByRefAndSchema, setSchemaUidForModel, setSchemaUidForSchemaDefinition, withExcludeRevokedFilter } from '@seedprotocol/eas';
15
- export { S as Schema, d as deleteModelFromSchema, a as deletePropertyFromModel, r as renameModelProperty, s as schemaMachine, u as updateModelProperties } from './Schema-a8uO-hIZ.js';
16
- export { ModelProperty } from './ModelProperty-D79uV42p.js';
17
- export { getModelSchemasFromEas } from './eas-CfYCu4IX.js';
17
+ import { generateId } from './generateId-BopUwD8F.js';
18
+ export { S as Schema, d as deleteModelFromSchema, a as deletePropertyFromModel, r as renameModelProperty, s as schemaMachine, u as updateModelProperties } from './Schema-DOhlrQ-N.js';
19
+ export { F as FileSystemLockedError } from './errors-CrBxGWah.js';
20
+ export { M as MODEL_AMBIGUOUS_EVENT } from './resolveModelForSyncedSeed-DQK6JfXS.js';
21
+ export { ModelProperty } from './ModelProperty-lth9L37R.js';
22
+ export { getModelSchemasFromEas } from './eas-B0hsMLqt.js';
18
23
  export { BaseArweaveClient, DEFAULT_ARWEAVE_GATEWAYS, DEFAULT_ARWEAVE_GRAPHQL_URL, DEFAULT_ARWEAVE_HOST, DEFAULT_GATEWAY_SIDECAR_HOST, DEFAULT_GATEWAY_SIDECAR_PORT, DEFAULT_SEED_FEED_HYPER_KEY, DEFAULT_SEED_GATEWAY_HYPER_KEY, SEED_RSS_IMAGE_RELATION_FIELD_KEYS, ensureReadGatewaySelected, fetchArweaveRawFromBaseUrl, fetchArweaveRawTextAcrossGateways, getArweaveReadBaseUrls, getArweaveUploadStatus, getDefaultArweaveReadGatewayHostsOrdered, getLastHealthyReadGatewayHost, getPreferredArweaveReadBaseUrls, getReadGatewayHostsForConfig, getResolvedArweaveReadBaseUrls, getResolvedSeedGatewayEndpoints, getUploadApiArweaveDataUrl, getUploadApiArweaveStatusUrl, getUploadPipelineTransactionStatus, invalidateReadGatewayCache, invalidateSidecarProbeCache, isArweaveL1AnchoringComplete, isEasAttestationExplorerUrl, isGatewayHostCircuitOpen, isKnownArweaveGatewayHostname, isReadGatewayKnownHealthy, mergePrimaryHostWithDefaults, normalizeGatewayHostKey, normalizeUploadApiBaseUrl, queryArweaveGatewayTransaction, queryArweaveGatewayTransactionWithFallback, recordGatewayHostFailure, recordGatewayHostSuccess, resetArweaveReadGatewayForTests, resolveSeedGatewayEndpoints, resolveSeedRssImageRelationFromItem, resolveSeedRssImageRelationRef, seedGatewayConfigFromClientContext, seedGatewayConfigFromSeedConfig, setPreferredArweaveReadBaseUrls, setResolvedSeedGatewayEndpoints } from '@seedprotocol/arweave';
19
- export { u as updateSeedRevokedAt } from './updateSeedRevokedAt-CBcLfHWs.js';
20
- import { g as getSegmentedItemProperties } from './getSegmentedItemProperties-BmKE71vU.js';
21
- export { PublishValidationFailedError, resolvePublishPayloadValues, validateItemForPublish } from './getPublishPayload-BIrTVUxb.js';
24
+ export { u as updateSeedRevokedAt } from './updateSeedRevokedAt-B58ORbY3.js';
25
+ import { g as getSegmentedItemProperties } from './getSegmentedItemProperties-C2EJ2G0N.js';
26
+ import { i as isSeedRevoked, f as findRelatedSeedRow, a as isUnpublishedSeed, h as htmlPropertyNameForHtmlSeed, r as relatedModelNameFromDef } from './getPublishPayload-H032DHC7.js';
27
+ export { P as PublishValidationFailedError, R as RELATED_ITEM_UNPUBLISHED_CODE, b as RelatedItemUnpublishedError, c as resolvePublishPayloadValues, v as validateItemForPublish } from './getPublishPayload-H032DHC7.js';
22
28
  import 'pluralize';
23
- export { itemHasPublishUploadCandidates } from './getPublishUploads-C6cDeZdz.js';
29
+ export { itemHasPublishUploadCandidates } from './getPublishUploads-CR66RlGJ.js';
24
30
  import { parseFragment, serialize } from 'parse5';
25
31
  import 'js-yaml';
26
32
  import 'fs';
27
- export { generateId } from './generateId-BopUwD8F.js';
28
33
  import 'xstate';
29
34
  import 'debug';
30
35
  import './model-DGMe-TTm.js';
31
36
  import 'drizzle-orm/casing';
32
37
  import '@sinclair/typebox';
33
38
  import 'lodash-es';
39
+ import 'rxjs';
34
40
  import 'nanoid';
35
41
  import 'nanoid-dictionary';
36
42
  import '@seedprotocol/query';
43
+ import 'drizzle-orm/sqlite-core';
37
44
  import '@noble/hashes/sha3';
38
45
  import '@noble/hashes/utils';
39
- import 'rxjs';
40
- import 'drizzle-orm/sqlite-core';
41
- import './SchemaValidationService-Y49vqast.js';
46
+ import './SchemaValidationService-DDKr5piy.js';
42
47
  import '@sinclair/typebox/value';
43
48
  import '@ethereum-attestation-service/eas-sdk';
44
49
 
45
50
  /**
46
51
  * Updates the version record with the attestation UID after a Version attestation is created.
47
- * Targets the version without a uid yet (the one being published).
52
+ * Targets the version without a uid yet (the one being published). A uid one of the seed's
53
+ * version rows already has is ignored.
48
54
  * Publisher is immutable once set: we never overwrite an existing publisher.
49
55
  */
50
56
  const updateVersionUid = async ({ seedLocalId, versionUid, publisher, attestationCreatedAt, }) => {
@@ -59,10 +65,37 @@ const updateVersionUid = async ({ seedLocalId, versionUid, publisher, attestatio
59
65
  .from(versions)
60
66
  .where(eq(versions.seedLocalId, seedLocalId))
61
67
  .orderBy(desc(versions.createdAt));
62
- const toUpdate = rows.find((r) => r.localId && isPlaceholderUid(r.uid));
63
- if (!toUpdate?.localId)
68
+ // Already recorded: nothing to stamp. A patch publish attaches to an existing version, and the
69
+ // modular executor's SeedPublished event still reports that version's uid; stamping it onto a
70
+ // local draft version would give two rows the same version uid.
71
+ const wanted = versionUid.toLowerCase();
72
+ if (rows.some((r) => r.uid?.toLowerCase() === wanted))
64
73
  return;
74
+ const toUpdate = rows.find((r) => r.localId && isPlaceholderUid(r.uid));
65
75
  const normalizedPublisher = normalizePublisher(publisher);
76
+ if (!toUpdate?.localId) {
77
+ // No local draft version took this attestation (e.g. a republish after unpublish, where every
78
+ // version row is a revoked attestation): record the new version so it is the latest one.
79
+ const [seed] = await appDb
80
+ .select({ type: seeds.type })
81
+ .from(seeds)
82
+ .where(eq(seeds.localId, seedLocalId))
83
+ .limit(1);
84
+ if (!seed)
85
+ return;
86
+ const now = Date.now();
87
+ await appDb.insert(versions).values({
88
+ localId: generateId(),
89
+ seedLocalId,
90
+ seedType: seed.type,
91
+ uid: versionUid,
92
+ createdAt: now,
93
+ updatedAt: now,
94
+ ...(normalizedPublisher && { publisher: normalizedPublisher }),
95
+ ...(attestationCreatedAt != null && { attestationCreatedAt }),
96
+ });
97
+ return;
98
+ }
66
99
  let shouldSetPublisher = normalizedPublisher != null;
67
100
  if (shouldSetPublisher && toUpdate.publisher != null && toUpdate.publisher !== '') {
68
101
  shouldSetPublisher = false;
@@ -83,6 +116,12 @@ const updateVersionUid = async ({ seedLocalId, versionUid, publisher, attestatio
83
116
  * so getPublishPendingDiff stays aligned with on-chain state.
84
117
  * When pair.propertyName is set, match that property even if the row has no schemaUid;
85
118
  * if the row has a schemaUid it must still match. Pair-only schema match remains for unnamed pairs.
119
+ *
120
+ * A full-snapshot publish (`new_version`, or a republish after unpublish) also attests properties
121
+ * whose rows are already attested (on an older version, or the revoked seed's). With no placeholder
122
+ * to take the uid, the attestation is recorded as a new row for the published version: a copy of
123
+ * the property's latest row with the new uid, so readers show the published version without a
124
+ * sync. Rows keep or get the published version's local id when `versionUid` has a version row.
86
125
  */
87
126
  async function applyPropertyAttestationUidsFromPublish(params) {
88
127
  const { seedLocalId, attestationCreatedAtMs, pairs, versionUid } = params;
@@ -96,6 +135,27 @@ async function applyPropertyAttestationUidsFromPublish(params) {
96
135
  const validVersion = versionUid != null && versionUid !== '' && isValidEasAttestationUid(versionUid)
97
136
  ? versionUid
98
137
  : undefined;
138
+ let versionLocalId;
139
+ let liveSeedUid = null;
140
+ if (validVersion) {
141
+ const [versionRow] = await appDb
142
+ .select({ localId: versions.localId, seedUid: versions.seedUid })
143
+ .from(versions)
144
+ .where(and(eq(versions.seedLocalId, seedLocalId), eq(versions.uid, validVersion)))
145
+ .limit(1);
146
+ versionLocalId = versionRow?.localId ?? undefined;
147
+ const [seedRow] = await appDb
148
+ .select({ uid: seeds.uid, revokedAt: seeds.revokedAt })
149
+ .from(seeds)
150
+ .where(eq(seeds.localId, seedLocalId))
151
+ .limit(1);
152
+ // A republish records its new seed uid after this; updateSeedUid fills it in then.
153
+ liveSeedUid =
154
+ versionRow?.seedUid ??
155
+ (isValidEasAttestationUid(seedRow?.uid) && !isVersionRevoked(seedRow?.revokedAt)
156
+ ? seedRow.uid
157
+ : null);
158
+ }
99
159
  for (const pair of pairs) {
100
160
  const att = pair.attestationUid?.trim();
101
161
  if (!isValidEasAttestationUid(att))
@@ -106,6 +166,9 @@ async function applyPropertyAttestationUidsFromPublish(params) {
106
166
  const pairName = pair.propertyName != null && pair.propertyName !== '' ? pair.propertyName : undefined;
107
167
  const candidates = working
108
168
  .filter((r) => {
169
+ // Rows sync derived for ItemStorage properties aren't placeholders for an attestation.
170
+ if (r.derivedFromUid != null)
171
+ return false;
109
172
  if (pairName) {
110
173
  if (r.propertyName !== pairName)
111
174
  return false;
@@ -120,8 +183,34 @@ async function applyPropertyAttestationUidsFromPublish(params) {
120
183
  })
121
184
  .sort(compareMetadataRowsLatestFirst);
122
185
  const target = candidates.find((r) => isPlaceholderUid(r.uid));
123
- if (!target?.localId)
186
+ if (!target?.localId) {
187
+ // Full snapshot: the property's rows are all attested. Record this attestation as a new row
188
+ // for the published version (unless it is already recorded, e.g. a replayed receipt).
189
+ const source = candidates[0];
190
+ if (!source || !validVersion)
191
+ continue;
192
+ if (working.some((r) => r.uid?.toLowerCase() === att.toLowerCase()))
193
+ continue;
194
+ const now = Date.now();
195
+ const row = {
196
+ ...source,
197
+ localId: generateId(),
198
+ uid: att,
199
+ schemaUid: normalizeBytes32Hex(source.schemaUid) ? source.schemaUid : wantSchema,
200
+ seedUid: liveSeedUid,
201
+ versionUid: validVersion,
202
+ versionLocalId: versionLocalId ?? source.versionLocalId,
203
+ attestationCreatedAt: attestationCreatedAtMs ?? now,
204
+ attestationRaw: null,
205
+ revokedAt: null,
206
+ derivedFromUid: null,
207
+ createdAt: now,
208
+ updatedAt: now,
209
+ };
210
+ await appDb.insert(metadata).values(row);
211
+ working.push(row);
124
212
  continue;
213
+ }
125
214
  const writeSchemaUid = !normalizeBytes32Hex(target.schemaUid);
126
215
  await appDb
127
216
  .update(metadata)
@@ -130,6 +219,7 @@ async function applyPropertyAttestationUidsFromPublish(params) {
130
219
  ...(writeSchemaUid && { schemaUid: wantSchema }),
131
220
  ...(attestationCreatedAtMs != null && { attestationCreatedAt: attestationCreatedAtMs }),
132
221
  ...(validVersion && { versionUid: validVersion }),
222
+ ...(versionLocalId && { versionLocalId }),
133
223
  updatedAt: Date.now(),
134
224
  })
135
225
  .where(eq(metadata.localId, target.localId));
@@ -141,6 +231,7 @@ async function applyPropertyAttestationUidsFromPublish(params) {
141
231
  ...(writeSchemaUid && { schemaUid: wantSchema }),
142
232
  attestationCreatedAt: attestationCreatedAtMs ?? working[i].attestationCreatedAt,
143
233
  ...(validVersion && { versionUid: validVersion }),
234
+ ...(versionLocalId && { versionLocalId }),
144
235
  };
145
236
  }
146
237
  }
@@ -171,7 +262,8 @@ function resolveSeedIds$1(arg) {
171
262
  }
172
263
  /**
173
264
  * Per property: the **latest** metadata row (by `attestationCreatedAt` / `createdAt`) lacks a valid
174
- * EAS attestation `uid` — local edit or missing post-publish UID backfill. **Not** equivalent to
265
+ * EAS attestation `uid` — local edit or missing post-publish UID backfill. Rows sync derived for
266
+ * ItemStorage properties (`derivedFromUid` set) count as published. **Not** equivalent to
175
267
  * draft vs onchain for the whole seed; use `getSeedPublishState` for that.
176
268
  */
177
269
  async function getPublishPendingDiff(arg) {
@@ -208,9 +300,8 @@ async function getPublishPendingDiff(arg) {
208
300
  const latest = list[0];
209
301
  if (!latest)
210
302
  continue;
211
- const hasUid = isValidEasAttestationUid(latest.uid);
212
- if (!hasUid) {
213
- const prevWithUid = list.find((r) => isValidEasAttestationUid(r.uid));
303
+ if (!isPublishedMetadataRow(latest)) {
304
+ const prevWithUid = list.find(isPublishedMetadataRow);
214
305
  pendingProperties.push({
215
306
  propertyName,
216
307
  currentValue: latest.propertyValue ?? null,
@@ -259,7 +350,8 @@ function maxMs(a, b) {
259
350
  }
260
351
  /**
261
352
  * Whether the seed has **any** on-chain anchor in local SQLite: valid EAS UID on the seed row,
262
- * on the newest **published** version row (`getLatestPublishedVersionRow`), or on **any** metadata row.
353
+ * on the newest **published** version row (`getLatestPublishedVersionRow`, which skips revoked
354
+ * versions), or on **any** metadata row.
263
355
  * Not the same as “no unpublished edits”; see `getPublishPendingDiff` for per-property head rows.
264
356
  */
265
357
  async function getSeedPublishState(arg) {
@@ -271,6 +363,7 @@ async function getSeedPublishState(arg) {
271
363
  versionAttestationUid: null,
272
364
  explorerUid: null,
273
365
  lastAttestedAtMs: null,
366
+ revokedAt: null,
274
367
  };
275
368
  if (!appDb || (!seedLocalId && !seedUid)) {
276
369
  return empty;
@@ -316,6 +409,7 @@ async function getSeedPublishState(arg) {
316
409
  versionAttestationUid,
317
410
  explorerUid,
318
411
  lastAttestedAtMs,
412
+ revokedAt: seedRow?.revokedAt ? seedRow.revokedAt : null,
319
413
  };
320
414
  }
321
415
 
@@ -437,7 +531,7 @@ async function getRelatedItemsForPublish(item, visited = new Set()) {
437
531
  visited.add(seedLocalId);
438
532
  const result = [];
439
533
  const { itemRelationProperties, itemImageProperties, itemListProperties } = await getSegmentedItemProperties(item);
440
- const getItemMod = await import('./getItem-Br-bGNFO.js');
534
+ const getItemMod = await import('./getItem-DEh4WfHG.js');
441
535
  const { getItem } = getItemMod;
442
536
  const processRelationOrImage = async (prop) => {
443
537
  const snapshot = prop.getService().getSnapshot();
@@ -456,8 +550,8 @@ async function getRelatedItemsForPublish(item, visited = new Set()) {
456
550
  if (!value && prop.propertyName && isStorageSeed) {
457
551
  const ctx = context;
458
552
  if (ctx.seedLocalId || ctx.seedUid) {
459
- const _mod_0 = await import('./ClientManager-ChcmUL47.js');
460
- const _ns_0 = _mod_0.al;
553
+ const _mod_0 = await import('./Item-zBFWQDU9.js');
554
+ const _ns_0 = _mod_0.Y;
461
555
  const { getPropertyData } = _ns_0;
462
556
  const meta = await getPropertyData({
463
557
  propertyName: prop.propertyName,
@@ -515,110 +609,481 @@ async function getRelatedItemsForPublish(item, visited = new Set()) {
515
609
  return result;
516
610
  }
517
611
 
518
- /**
519
- * Counts seeds, property attestations, and Arweave upload bytes for a publish
520
- * without building transactions or requiring a valid payload.
521
- */
522
- const DATA_URI = /^data:[^;]+;base64,([\s\S]*)$/i;
523
- const matchesDataType = (actual, expected) => normalizeDataType(actual) === expected;
524
- function isZeroUid(uid) {
525
- return !uid || uid === ZERO_BYTES32;
612
+ const HTML_EMBEDDED_MAX_IMAGES_PER_DOC = 50;
613
+ const HTML_EMBEDDED_MAX_IMAGE_BYTES = 5 * 1024 * 1024;
614
+ const HTML_EMBEDDED_MAX_TOTAL_BYTES = 25 * 1024 * 1024;
615
+ const DATA_URI_IMAGE = /^data:(image\/[a-zA-Z0-9.+-]+);base64,([\s\S]*)$/i;
616
+ const MIME_NORMALIZE = {
617
+ 'image/jpg': 'image/jpeg',
618
+ };
619
+ function normalizeMime(m) {
620
+ const lower = m.toLowerCase().trim();
621
+ return MIME_NORMALIZE[lower] ?? lower;
526
622
  }
527
- function isStorageTransactionPropertyName(name) {
528
- return name === 'storageTransactionId' || name === 'storage_transaction_id';
623
+ const ALLOWED_MIMES = new Set([
624
+ 'image/png',
625
+ 'image/jpeg',
626
+ 'image/webp',
627
+ 'image/gif',
628
+ 'image/svg+xml',
629
+ ]);
630
+ class HtmlEmbeddedDataUriLimitError extends Error {
631
+ constructor(message) {
632
+ super(message);
633
+ this.name = 'HtmlEmbeddedDataUriLimitError';
634
+ }
529
635
  }
530
- /** Decoded byte length of a data-URI, or null if the string is not a base64 data URI. */
531
- function estimateDataUriByteLength(dataUri) {
532
- const m = DATA_URI.exec((dataUri ?? '').trim());
533
- if (!m)
534
- return null;
535
- const b64 = m[1].replace(/\s/g, '');
536
- if (!b64)
537
- return 0;
538
- const padding = b64.endsWith('==') ? 2 : b64.endsWith('=') ? 1 : 0;
539
- return Math.max(0, Math.floor((b64.length * 3) / 4) - padding);
636
+ function resolveEffectiveHtmlEmbeddedDataUriPolicy(propertyDef, publishLevel) {
637
+ const fromProp = propertyDef?.htmlEmbeddedDataUriPolicy;
638
+ if (fromProp === 'materialize' || fromProp === 'preserve')
639
+ return fromProp;
640
+ if (publishLevel === 'materialize' || publishLevel === 'preserve')
641
+ return publishLevel;
642
+ return 'materialize';
540
643
  }
541
- function propertyContext(prop) {
542
- const snapshot = prop.getService().getSnapshot();
543
- return snapshot && 'context' in snapshot
544
- ? (snapshot.context ?? null)
545
- : null;
644
+ function getAttr(node, name) {
645
+ const a = node.attrs?.find((x) => x.name === name);
646
+ return a?.value;
546
647
  }
547
- function getPublishValue(prop, context) {
548
- const propertyDef = prop.propertyDef ?? context.propertyRecordSchema;
549
- const isFileImageHtml = matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.File) ||
550
- matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Image) ||
551
- matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Html);
552
- const isJsonStorage = matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Json) ||
553
- matchesDataType(propertyDef?.refValueType, ModelPropertyDataTypes.Json);
554
- const isRelation = matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Relation);
555
- const isStorageTransactionIdProp = isStorageTransactionPropertyName(prop.propertyName);
556
- const preferPropertyValue = isFileImageHtml || isRelation || isJsonStorage || isStorageTransactionIdProp;
557
- let value = preferPropertyValue
558
- ? context.propertyValue
559
- : (prop.value ?? context.propertyValue);
560
- if (isRelation || isFileImageHtml || isJsonStorage) {
561
- const pv = context.propertyValue;
562
- if (typeof value === 'object' || value == null) {
563
- if (typeof pv === 'string' && pv.trim())
564
- value = pv.trim();
565
- else if (pv && typeof pv === 'object' && typeof pv.seedLocalId === 'string') {
566
- value = pv.seedLocalId;
648
+ function setAttr(node, name, value) {
649
+ if (!node.attrs)
650
+ node.attrs = [];
651
+ const i = node.attrs.findIndex((x) => x.name === name);
652
+ if (i >= 0)
653
+ node.attrs[i].value = value;
654
+ else
655
+ node.attrs.push({ name, value });
656
+ }
657
+ /**
658
+ * Walk fragment tree; collect unique data:image base64 URIs with limits.
659
+ */
660
+ async function extractDataUriImagesFromHtml(html) {
661
+ const fragment = parseFragment(html);
662
+ const found = [];
663
+ const seenUris = new Set();
664
+ let totalBytes = 0;
665
+ const walk = async (node) => {
666
+ if (node.nodeName === '#text' || node.nodeName === '#comment')
667
+ return;
668
+ const el = node;
669
+ if (el.tagName === 'img') {
670
+ const src = getAttr(el, 'src')?.trim();
671
+ if (src && src.startsWith('data:image/')) {
672
+ const m = DATA_URI_IMAGE.exec(src);
673
+ if (m) {
674
+ const mimeRaw = normalizeMime(m[1]);
675
+ if (!ALLOWED_MIMES.has(mimeRaw)) {
676
+ throw new HtmlEmbeddedDataUriLimitError(`Unsupported embedded image type: ${mimeRaw}. Allowed: ${[...ALLOWED_MIMES].join(', ')}`);
677
+ }
678
+ let binary;
679
+ try {
680
+ const b64 = m[2].replace(/\s/g, '');
681
+ binary = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
682
+ }
683
+ catch {
684
+ throw new HtmlEmbeddedDataUriLimitError('Invalid base64 in embedded image data URI');
685
+ }
686
+ const byteLength = binary.byteLength;
687
+ if (byteLength > HTML_EMBEDDED_MAX_IMAGE_BYTES) {
688
+ throw new HtmlEmbeddedDataUriLimitError(`Embedded image exceeds max size (${HTML_EMBEDDED_MAX_IMAGE_BYTES} bytes)`);
689
+ }
690
+ totalBytes += byteLength;
691
+ if (totalBytes > HTML_EMBEDDED_MAX_TOTAL_BYTES) {
692
+ throw new HtmlEmbeddedDataUriLimitError(`Total embedded image size exceeds max (${HTML_EMBEDDED_MAX_TOTAL_BYTES} bytes)`);
693
+ }
694
+ if (!seenUris.has(src)) {
695
+ if (seenUris.size >= HTML_EMBEDDED_MAX_IMAGES_PER_DOC) {
696
+ throw new HtmlEmbeddedDataUriLimitError(`Too many distinct embedded images (max ${HTML_EMBEDDED_MAX_IMAGES_PER_DOC})`);
697
+ }
698
+ seenUris.add(src);
699
+ const stableKey = await getContentHash(binary);
700
+ found.push({ dataUri: src, stableKey, byteLength, mimeType: mimeRaw });
701
+ }
702
+ }
567
703
  }
568
704
  }
569
- }
570
- return value;
571
- }
572
- function shouldAttestProperty(prop, forceFullSnapshot) {
573
- if (INTERNAL_PROPERTY_NAMES.includes(prop.propertyName))
574
- return false;
575
- const context = propertyContext(prop);
576
- if (!context)
577
- return false;
578
- const value = getPublishValue(prop, context);
579
- if (value == null || value === '')
580
- return false;
581
- if (prop.uid && !forceFullSnapshot) {
582
- const allowStorageTx = isStorageTransactionPropertyName(prop.propertyName) &&
583
- typeof value === 'string' &&
584
- value.trim() !== '';
585
- if (!allowStorageTx)
586
- return false;
587
- }
588
- return true;
705
+ const parent = el;
706
+ if (parent.childNodes) {
707
+ for (const c of parent.childNodes)
708
+ await walk(c);
709
+ }
710
+ };
711
+ for (const c of fragment.childNodes)
712
+ await walk(c);
713
+ return found;
589
714
  }
590
- function getStorageDirForDataType(dataType) {
591
- switch (normalizeDataType(dataType)) {
592
- case 'Image':
593
- return BaseFileManager.getFilesPath('images');
594
- case 'File':
595
- return BaseFileManager.getFilesPath('files');
596
- case 'Html':
597
- return BaseFileManager.getFilesPath('html');
598
- case 'Json':
599
- return BaseFileManager.getFilesPath('json');
600
- default:
601
- return BaseFileManager.getFilesPath('images');
602
- }
715
+ /**
716
+ * Replace `data:image/...` src values with Arweave URLs using upload results keyed by image seed local id.
717
+ */
718
+ function replaceDataUrisInParsedHtml(html, replacements) {
719
+ if (replacements.size === 0)
720
+ return html;
721
+ const fragment = parseFragment(html);
722
+ const walk = (node) => {
723
+ if (node.nodeName === '#text' || node.nodeName === '#comment')
724
+ return;
725
+ const el = node;
726
+ if (el.tagName === 'img') {
727
+ const src = getAttr(el, 'src')?.trim();
728
+ if (src && replacements.has(src)) {
729
+ setAttr(el, 'src', replacements.get(src));
730
+ }
731
+ }
732
+ const parent = el;
733
+ if (parent.childNodes) {
734
+ for (const c of parent.childNodes)
735
+ walk(c);
736
+ }
737
+ };
738
+ for (const c of fragment.childNodes)
739
+ walk(c);
740
+ return serialize(fragment);
603
741
  }
604
- async function addUpload(acc, seen, key, bytes) {
605
- if (bytes <= 0 || seen.has(key))
742
+ async function deleteCoPublishRowsForParent(appDb, parentSeedLocalId) {
743
+ if (!appDb)
606
744
  return;
607
- seen.add(key);
608
- acc.uploadCount += 1;
609
- acc.uploadBytes += bytes;
745
+ await appDb.delete(htmlEmbeddedImageCoPublish).where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, parentSeedLocalId));
610
746
  }
611
- async function addUploadFromPath(acc, seen, filePath, key) {
612
- if (!filePath || filePath.endsWith('undefined'))
613
- return;
614
- const size = await BaseFileManager.getFileSize(filePath);
615
- if (size == null || size <= 0)
616
- return;
617
- await addUpload(acc, seen, key, size);
747
+ /**
748
+ * Create an Image item and persist a data URI into its storageTransactionId (same path as user paste).
749
+ */
750
+ async function createImageItemFromDataUri(dataUri) {
751
+ const imageItem = await Item.create({
752
+ modelName: 'Image',
753
+ modelFileId: INTERNAL_STORAGE_MODEL_FILE_IDS.image,
754
+ });
755
+ await waitForEntityIdle(imageItem, { timeout: 60000 });
756
+ const st = imageItem.internalProperties['storageTransactionId'] ??
757
+ imageItem.allProperties['storageTransactionId'];
758
+ if (!st) {
759
+ throw new Error('Image item missing storageTransactionId property');
760
+ }
761
+ st.value = dataUri;
762
+ await st.save();
763
+ await waitForEntityIdle(imageItem, { timeout: 60000 });
764
+ return { seedLocalId: imageItem.seedLocalId };
618
765
  }
619
- async function collectUploadBytes(item, itemUploadProperties, itemImageProperties, relatedItemProperty, acc, seen) {
620
- for (const uploadProperty of itemUploadProperties) {
621
- let childBytes = 0;
766
+ /**
767
+ * Scan Html storage properties, materialize embedded images as Image items, insert co-publish rows.
768
+ * Call before phase-1 Arweave tx build. Does not rewrite Html files yet.
769
+ */
770
+ async function prepareHtmlEmbeddedImagesForPublish(item, publishPolicy) {
771
+ const appDb = BaseDb.getAppDb();
772
+ if (!appDb) {
773
+ return { deferredHtmlSeedLocalIds: [] };
774
+ }
775
+ const deferred = new Set();
776
+ // The item's own Html, and the Html of the draft items published with it: each gets its embedded
777
+ // images materialized and co-published (rows keyed by the item owning the Html property).
778
+ for (const parent of [item, ...(await getRelatedDraftsCoPublishedWith(item))]) {
779
+ await prepareHtmlEmbeddedImagesOfItem(appDb, parent, publishPolicy, deferred);
780
+ }
781
+ return { deferredHtmlSeedLocalIds: [...deferred] };
782
+ }
783
+ /**
784
+ * Draft items (no seed uid yet) that a publish of `item` publishes with it: the targets of its
785
+ * relation properties, one level deep, as getPublishPayload and getPublishUploads walk them.
786
+ * Html-embedded images of these items are co-published with `item` like its own.
787
+ */
788
+ async function getRelatedDraftsCoPublishedWith(item) {
789
+ const { itemRelationProperties } = await getSegmentedItemProperties(item);
790
+ const out = [];
791
+ const seen = new Set([item.seedLocalId]);
792
+ for (const relationProperty of itemRelationProperties) {
793
+ if (relationProperty.uid)
794
+ continue;
795
+ const snap = relationProperty.getService().getSnapshot();
796
+ const value = 'context' in snap ? snap.context.propertyValue : undefined;
797
+ const { seedLocalId, seedUid } = resolveSeedIdsFromRefString(normalizeRelationPropertyValue(value) ?? '');
798
+ if (!seedLocalId && !seedUid)
799
+ continue;
800
+ const related = await Item.find({ seedLocalId, seedUid });
801
+ if (!related?.seedLocalId || seen.has(related.seedLocalId))
802
+ continue;
803
+ if (related.seedUid && related.seedUid !== ZERO_BYTES32)
804
+ continue;
805
+ seen.add(related.seedLocalId);
806
+ out.push(related);
807
+ }
808
+ return out;
809
+ }
810
+ async function prepareHtmlEmbeddedImagesOfItem(appDb, item, publishPolicy, deferred) {
811
+ await deleteCoPublishRowsForParent(appDb, item.seedLocalId);
812
+ for (const p of item.properties) {
813
+ const def = p.propertyDef;
814
+ if (!def || normalizeDataTypeLocal(def.dataType) !== ModelPropertyDataTypes.Html)
815
+ continue;
816
+ const policy = resolveEffectiveHtmlEmbeddedDataUriPolicy(def, publishPolicy);
817
+ if (policy !== 'materialize')
818
+ continue;
819
+ const snap = p.getService().getSnapshot();
820
+ const ctx = 'context' in snap ? snap.context : null;
821
+ const htmlSeedLocalId = typeof ctx?.propertyValue === 'string' ? ctx.propertyValue : '';
822
+ const refResolved = ctx?.refResolvedValue;
823
+ if (!htmlSeedLocalId?.trim() || !refResolved)
824
+ continue;
825
+ const filePath = `${BaseFileManager.getFilesPath('html')}/${refResolved}`;
826
+ const exists = await BaseFileManager.pathExists(filePath);
827
+ if (!exists)
828
+ continue;
829
+ let html;
830
+ try {
831
+ html = await BaseFileManager.readFileAsString(filePath);
832
+ }
833
+ catch {
834
+ const buf = await BaseFileManager.readFileAsBuffer(filePath);
835
+ if (typeof Buffer !== 'undefined' && Buffer.isBuffer(buf)) {
836
+ html = buf.toString('utf-8');
837
+ }
838
+ else if (typeof Blob !== 'undefined' && buf instanceof Blob) {
839
+ html = await buf.text();
840
+ }
841
+ else if (buf instanceof ArrayBuffer) {
842
+ html = new TextDecoder('utf-8', { fatal: false }).decode(buf);
843
+ }
844
+ else {
845
+ const v = buf;
846
+ html = new TextDecoder('utf-8', { fatal: false }).decode(new Uint8Array(v.buffer, v.byteOffset, v.byteLength));
847
+ }
848
+ }
849
+ let extracted;
850
+ try {
851
+ extracted = await extractDataUriImagesFromHtml(html);
852
+ }
853
+ catch (e) {
854
+ if (e instanceof HtmlEmbeddedDataUriLimitError)
855
+ throw e;
856
+ throw e;
857
+ }
858
+ if (extracted.length === 0)
859
+ continue;
860
+ deferred.add(htmlSeedLocalId.trim());
861
+ for (const ent of extracted) {
862
+ const { seedLocalId: imageSeedLocalId } = await createImageItemFromDataUri(ent.dataUri);
863
+ const now = Date.now();
864
+ await appDb.insert(htmlEmbeddedImageCoPublish).values({
865
+ parentSeedLocalId: item.seedLocalId,
866
+ htmlSeedLocalId: htmlSeedLocalId.trim(),
867
+ imageSeedLocalId,
868
+ stableKey: ent.stableKey,
869
+ createdAt: now,
870
+ }).onConflictDoNothing();
871
+ }
872
+ }
873
+ }
874
+ function normalizeDataTypeLocal(dt) {
875
+ if (!dt)
876
+ return '';
877
+ return dt.charAt(0).toUpperCase() + dt.slice(1).toLowerCase();
878
+ }
879
+ /**
880
+ * After phase-1 uploads, rewrite Html files on disk: data URI → Arweave gateway URL.
881
+ */
882
+ async function rewriteHtmlEmbeddedImagesOnDisk(parentSeedLocalId, uploadedTransactions) {
883
+ const appDb = BaseDb.getAppDb();
884
+ if (!appDb)
885
+ return;
886
+ const parentItem = await Item.find({ seedLocalId: parentSeedLocalId });
887
+ if (!parentItem)
888
+ return;
889
+ const txByImageSeed = new Map();
890
+ for (const u of uploadedTransactions) {
891
+ if (u.seedLocalId && u.txId) {
892
+ txByImageSeed.set(u.seedLocalId.trim(), u.txId.trim());
893
+ }
894
+ }
895
+ // The parent's Html and that of the draft items published with it (see prepareHtmlEmbeddedImagesForPublish).
896
+ for (const item of [parentItem, ...(await getRelatedDraftsCoPublishedWith(parentItem))]) {
897
+ await rewriteHtmlEmbeddedImagesOfItem(appDb, item, txByImageSeed);
898
+ }
899
+ }
900
+ async function rewriteHtmlEmbeddedImagesOfItem(appDb, parentItem, txByImageSeed) {
901
+ const rows = await appDb
902
+ .select()
903
+ .from(htmlEmbeddedImageCoPublish)
904
+ .where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, parentItem.seedLocalId));
905
+ if (rows.length === 0)
906
+ return;
907
+ const htmlSeedIds = new Set(rows.map((r) => String(r.htmlSeedLocalId).trim()));
908
+ const refByHtmlSeed = new Map();
909
+ if (parentItem) {
910
+ for (const p of parentItem.properties) {
911
+ const def = p.propertyDef;
912
+ if (!def || normalizeDataTypeLocal(def.dataType) !== ModelPropertyDataTypes.Html)
913
+ continue;
914
+ const snap = p.getService().getSnapshot();
915
+ const ctx = 'context' in snap ? snap.context : null;
916
+ const pv = typeof ctx?.propertyValue === 'string' ? ctx.propertyValue.trim() : '';
917
+ const refResolved = ctx?.refResolvedValue;
918
+ if (pv && refResolved)
919
+ refByHtmlSeed.set(pv, refResolved);
920
+ }
921
+ }
922
+ for (const htmlSeedLocalId of htmlSeedIds) {
923
+ const refResolved = refByHtmlSeed.get(String(htmlSeedLocalId));
924
+ if (!refResolved)
925
+ continue;
926
+ const filePath = `${BaseFileManager.getFilesPath('html')}/${refResolved}`;
927
+ if (!(await BaseFileManager.pathExists(filePath)))
928
+ continue;
929
+ const html = await BaseFileManager.readFileAsString(filePath);
930
+ const replacements = new Map();
931
+ for (const r of rows) {
932
+ if (String(r.htmlSeedLocalId).trim() !== htmlSeedLocalId)
933
+ continue;
934
+ const txId = txByImageSeed.get(r.imageSeedLocalId.trim());
935
+ if (!txId)
936
+ continue;
937
+ const dataUri = await findDataUriForStableKey(html, r.stableKey);
938
+ if (dataUri)
939
+ replacements.set(dataUri, getArweaveUrlForTransaction(txId));
940
+ }
941
+ if (replacements.size === 0)
942
+ continue;
943
+ const newHtml = replaceDataUrisInParsedHtml(html, replacements);
944
+ try {
945
+ await BaseFileManager.saveFile(filePath, newHtml);
946
+ }
947
+ catch {
948
+ const fs = await BaseFileManager.getFs();
949
+ fs.writeFileSync(filePath, newHtml);
950
+ }
951
+ if (parentItem) {
952
+ for (const p of parentItem.properties) {
953
+ const snap = p.getService().getSnapshot();
954
+ const ctx = 'context' in snap ? snap.context : null;
955
+ const pv = typeof ctx?.propertyValue === 'string' ? ctx.propertyValue.trim() : '';
956
+ if (pv === htmlSeedLocalId) {
957
+ p.getService().send({
958
+ type: 'updateContext',
959
+ renderValue: newHtml,
960
+ });
961
+ }
962
+ }
963
+ }
964
+ }
965
+ }
966
+ async function findDataUriForStableKey(html, stableKey) {
967
+ const entries = await extractDataUriImagesFromHtml(html);
968
+ const hit = entries.find((e) => e.stableKey === stableKey);
969
+ return hit?.dataUri;
970
+ }
971
+ /**
972
+ * Remove co-publish rows after a successful publish for this parent seed.
973
+ */
974
+ async function clearHtmlEmbeddedImageCoPublishRows(parentSeedLocalId) {
975
+ const appDb = BaseDb.getAppDb();
976
+ if (!appDb || !parentSeedLocalId)
977
+ return;
978
+ await appDb
979
+ .delete(htmlEmbeddedImageCoPublish)
980
+ .where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, parentSeedLocalId.trim()));
981
+ }
982
+
983
+ /**
984
+ * Counts seeds, property attestations, and Arweave upload bytes for a publish
985
+ * without building transactions or requiring a valid payload.
986
+ */
987
+ const DATA_URI = /^data:[^;]+;base64,([\s\S]*)$/i;
988
+ const matchesDataType = (actual, expected) => normalizeDataType(actual) === expected;
989
+ function isZeroUid(uid) {
990
+ return !uid || uid === ZERO_BYTES32;
991
+ }
992
+ function isStorageTransactionPropertyName(name) {
993
+ return name === 'storageTransactionId' || name === 'storage_transaction_id';
994
+ }
995
+ /** Decoded byte length of a data-URI, or null if the string is not a base64 data URI. */
996
+ function estimateDataUriByteLength(dataUri) {
997
+ const m = DATA_URI.exec((dataUri ?? '').trim());
998
+ if (!m)
999
+ return null;
1000
+ const b64 = m[1].replace(/\s/g, '');
1001
+ if (!b64)
1002
+ return 0;
1003
+ const padding = b64.endsWith('==') ? 2 : b64.endsWith('=') ? 1 : 0;
1004
+ return Math.max(0, Math.floor((b64.length * 3) / 4) - padding);
1005
+ }
1006
+ function propertyContext(prop) {
1007
+ const snapshot = prop.getService().getSnapshot();
1008
+ return snapshot && 'context' in snapshot
1009
+ ? (snapshot.context ?? null)
1010
+ : null;
1011
+ }
1012
+ function getPublishValue(prop, context) {
1013
+ const propertyDef = prop.propertyDef ?? context.propertyRecordSchema;
1014
+ const isFileImageHtml = matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.File) ||
1015
+ matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Image) ||
1016
+ matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Html);
1017
+ const isJsonStorage = matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Json) ||
1018
+ matchesDataType(propertyDef?.refValueType, ModelPropertyDataTypes.Json);
1019
+ const isRelation = matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Relation);
1020
+ const isStorageTransactionIdProp = isStorageTransactionPropertyName(prop.propertyName);
1021
+ const preferPropertyValue = isFileImageHtml || isRelation || isJsonStorage || isStorageTransactionIdProp;
1022
+ let value = preferPropertyValue
1023
+ ? context.propertyValue
1024
+ : (prop.value ?? context.propertyValue);
1025
+ if (isRelation || isFileImageHtml || isJsonStorage) {
1026
+ const pv = context.propertyValue;
1027
+ if (typeof value === 'object' || value == null) {
1028
+ if (typeof pv === 'string' && pv.trim())
1029
+ value = pv.trim();
1030
+ else if (pv && typeof pv === 'object' && typeof pv.seedLocalId === 'string') {
1031
+ value = pv.seedLocalId;
1032
+ }
1033
+ }
1034
+ }
1035
+ return value;
1036
+ }
1037
+ function shouldAttestProperty(prop, forceFullSnapshot) {
1038
+ if (INTERNAL_PROPERTY_NAMES.includes(prop.propertyName))
1039
+ return false;
1040
+ const context = propertyContext(prop);
1041
+ if (!context)
1042
+ return false;
1043
+ const value = getPublishValue(prop, context);
1044
+ if (value == null || value === '')
1045
+ return false;
1046
+ if (prop.uid && !forceFullSnapshot) {
1047
+ const allowStorageTx = isStorageTransactionPropertyName(prop.propertyName) &&
1048
+ typeof value === 'string' &&
1049
+ value.trim() !== '';
1050
+ if (!allowStorageTx)
1051
+ return false;
1052
+ }
1053
+ return true;
1054
+ }
1055
+ function getStorageDirForDataType(dataType) {
1056
+ switch (normalizeDataType(dataType)) {
1057
+ case 'Image':
1058
+ return BaseFileManager.getFilesPath('images');
1059
+ case 'File':
1060
+ return BaseFileManager.getFilesPath('files');
1061
+ case 'Html':
1062
+ return BaseFileManager.getFilesPath('html');
1063
+ case 'Json':
1064
+ return BaseFileManager.getFilesPath('json');
1065
+ default:
1066
+ return BaseFileManager.getFilesPath('images');
1067
+ }
1068
+ }
1069
+ async function addUpload(acc, seen, key, bytes) {
1070
+ if (bytes <= 0 || seen.has(key))
1071
+ return;
1072
+ seen.add(key);
1073
+ acc.uploadCount += 1;
1074
+ acc.uploadBytes += bytes;
1075
+ }
1076
+ async function addUploadFromPath(acc, seen, filePath, key) {
1077
+ if (!filePath || filePath.endsWith('undefined'))
1078
+ return;
1079
+ const size = await BaseFileManager.getFileSize(filePath);
1080
+ if (size == null || size <= 0)
1081
+ return;
1082
+ await addUpload(acc, seen, key, size);
1083
+ }
1084
+ async function collectUploadBytes(item, itemUploadProperties, itemImageProperties, relatedItemProperty, acc, seen) {
1085
+ for (const uploadProperty of itemUploadProperties) {
1086
+ let childBytes = 0;
622
1087
  let childCount = 0;
623
1088
  for (const childProperty of uploadProperty.childProperties) {
624
1089
  const filePath = childProperty.localStoragePath;
@@ -662,7 +1127,7 @@ async function loadRelatedItem(value) {
662
1127
  const { seedLocalId, seedUid } = resolveSeedIdsFromRefString(normalized);
663
1128
  if (!seedLocalId && !seedUid)
664
1129
  return undefined;
665
- const { getItem } = await import('./getItem-Br-bGNFO.js');
1130
+ const { getItem } = await import('./getItem-DEh4WfHG.js');
666
1131
  try {
667
1132
  return await getItem({ seedLocalId, seedUid });
668
1133
  }
@@ -696,425 +1161,210 @@ async function unpublishedListItems(listProperty) {
696
1161
  if (related && isZeroUid(related.seedUid))
697
1162
  out.push(related);
698
1163
  }
699
- return out;
700
- }
701
- async function appendCoPublishImages(item, acc, seen, visited, forceFullSnapshot, publishMode) {
702
- const appDb = BaseDb.getAppDb();
703
- if (!appDb)
704
- return;
705
- const rows = await appDb
706
- .select()
707
- .from(htmlEmbeddedImageCoPublish)
708
- .where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, item.seedLocalId));
709
- for (const row of rows) {
710
- const _mod_1 = await import('./ClientManager-ChcmUL47.js');
711
- const _ns_1 = _mod_1.am;
712
- const { Item } = _ns_1;
713
- const imageItem = await Item.find({
714
- seedLocalId: row.imageSeedLocalId,
715
- modelName: 'Image',
716
- });
717
- if (!imageItem)
718
- continue;
719
- const st = imageItem.internalProperties['storageTransactionId'] ??
720
- imageItem.allProperties['storageTransactionId'];
721
- const stCtx = st ? propertyContext(st) : null;
722
- const stValue = typeof stCtx?.propertyValue === 'string' ? stCtx.propertyValue : '';
723
- const dataUriBytes = estimateDataUriByteLength(stValue);
724
- if (dataUriBytes != null && dataUriBytes > 0) {
725
- await addUpload(acc, seen, `seed:${imageItem.seedLocalId}`, dataUriBytes);
726
- }
727
- await summarizeItem(imageItem, publishMode, forceFullSnapshot, acc, seen, visited);
728
- }
729
- }
730
- async function summarizeItem(item, publishMode, forceFullSnapshot, acc, seenUploads, visited) {
731
- const seedLocalId = item.seedLocalId;
732
- if (!seedLocalId || visited.has(seedLocalId))
733
- return;
734
- visited.add(seedLocalId);
735
- acc.seedCount += 1;
736
- if (isZeroUid(item.seedUid))
737
- acc.newSeedCount += 1;
738
- if (isZeroUid(item.seedUid) || forceFullSnapshot)
739
- acc.newVersionCount += 1;
740
- const { itemBasicProperties, itemRelationProperties, itemListProperties, itemUploadProperties, itemImageProperties, } = await getSegmentedItemProperties(item);
741
- await collectUploadBytes(item, itemUploadProperties, itemImageProperties, undefined, acc, seenUploads);
742
- for (const rel of itemRelationProperties) {
743
- const related = await relatedIfUnpublished(rel);
744
- if (related) {
745
- await summarizeItem(related, publishMode, forceFullSnapshot, acc, seenUploads, visited);
746
- }
747
- }
748
- for (const listProperty of itemListProperties) {
749
- for (const related of await unpublishedListItems(listProperty)) {
750
- await summarizeItem(related, publishMode, forceFullSnapshot, acc, seenUploads, visited);
751
- }
752
- }
753
- await appendCoPublishImages(item, acc, seenUploads, visited, forceFullSnapshot, publishMode);
754
- const attestable = [
755
- ...itemBasicProperties,
756
- ...itemRelationProperties,
757
- ...itemListProperties,
758
- ...itemImageProperties,
759
- ...itemUploadProperties.map((u) => u.itemProperty),
760
- ];
761
- const seenProps = new Set();
762
- for (const prop of attestable) {
763
- const key = prop.localId || `${prop.propertyName}:${prop.seedLocalId}`;
764
- if (seenProps.has(key))
765
- continue;
766
- seenProps.add(key);
767
- if (shouldAttestProperty(prop, forceFullSnapshot))
768
- acc.attestationCount += 1;
769
- }
770
- }
771
- /**
772
- * Local measurement of what a publish would do: seed/version/attestation counts
773
- * and Arweave upload byte totals. Does not hit the network or create transactions.
774
- */
775
- const summarizePublishWork = async (item, options) => {
776
- const publishMode = options?.publishMode ?? 'patch';
777
- const forceFullSnapshot = publishMode === 'new_version';
778
- const acc = {
779
- publishMode,
780
- seedCount: 0,
781
- newSeedCount: 0,
782
- newVersionCount: 0,
783
- attestationCount: 0,
784
- uploadCount: 0,
785
- uploadBytes: 0,
786
- };
787
- await summarizeItem(item, publishMode, forceFullSnapshot, acc, new Set(), new Set());
788
- return acc;
789
- };
790
-
791
- const HTML_EMBEDDED_MAX_IMAGES_PER_DOC = 50;
792
- const HTML_EMBEDDED_MAX_IMAGE_BYTES = 5 * 1024 * 1024;
793
- const HTML_EMBEDDED_MAX_TOTAL_BYTES = 25 * 1024 * 1024;
794
- const DATA_URI_IMAGE = /^data:(image\/[a-zA-Z0-9.+-]+);base64,([\s\S]*)$/i;
795
- const MIME_NORMALIZE = {
796
- 'image/jpg': 'image/jpeg',
797
- };
798
- function normalizeMime(m) {
799
- const lower = m.toLowerCase().trim();
800
- return MIME_NORMALIZE[lower] ?? lower;
801
- }
802
- const ALLOWED_MIMES = new Set([
803
- 'image/png',
804
- 'image/jpeg',
805
- 'image/webp',
806
- 'image/gif',
807
- 'image/svg+xml',
808
- ]);
809
- class HtmlEmbeddedDataUriLimitError extends Error {
810
- constructor(message) {
811
- super(message);
812
- this.name = 'HtmlEmbeddedDataUriLimitError';
813
- }
814
- }
815
- function resolveEffectiveHtmlEmbeddedDataUriPolicy(propertyDef, publishLevel) {
816
- const fromProp = propertyDef?.htmlEmbeddedDataUriPolicy;
817
- if (fromProp === 'materialize' || fromProp === 'preserve')
818
- return fromProp;
819
- if (publishLevel === 'materialize' || publishLevel === 'preserve')
820
- return publishLevel;
821
- return 'materialize';
822
- }
823
- function getAttr(node, name) {
824
- const a = node.attrs?.find((x) => x.name === name);
825
- return a?.value;
826
- }
827
- function setAttr(node, name, value) {
828
- if (!node.attrs)
829
- node.attrs = [];
830
- const i = node.attrs.findIndex((x) => x.name === name);
831
- if (i >= 0)
832
- node.attrs[i].value = value;
833
- else
834
- node.attrs.push({ name, value });
835
- }
836
- /**
837
- * Walk fragment tree; collect unique data:image base64 URIs with limits.
838
- */
839
- async function extractDataUriImagesFromHtml(html) {
840
- const fragment = parseFragment(html);
841
- const found = [];
842
- const seenUris = new Set();
843
- let totalBytes = 0;
844
- const walk = async (node) => {
845
- if (node.nodeName === '#text' || node.nodeName === '#comment')
846
- return;
847
- const el = node;
848
- if (el.tagName === 'img') {
849
- const src = getAttr(el, 'src')?.trim();
850
- if (src && src.startsWith('data:image/')) {
851
- const m = DATA_URI_IMAGE.exec(src);
852
- if (m) {
853
- const mimeRaw = normalizeMime(m[1]);
854
- if (!ALLOWED_MIMES.has(mimeRaw)) {
855
- throw new HtmlEmbeddedDataUriLimitError(`Unsupported embedded image type: ${mimeRaw}. Allowed: ${[...ALLOWED_MIMES].join(', ')}`);
856
- }
857
- let binary;
858
- try {
859
- const b64 = m[2].replace(/\s/g, '');
860
- binary = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
861
- }
862
- catch {
863
- throw new HtmlEmbeddedDataUriLimitError('Invalid base64 in embedded image data URI');
864
- }
865
- const byteLength = binary.byteLength;
866
- if (byteLength > HTML_EMBEDDED_MAX_IMAGE_BYTES) {
867
- throw new HtmlEmbeddedDataUriLimitError(`Embedded image exceeds max size (${HTML_EMBEDDED_MAX_IMAGE_BYTES} bytes)`);
868
- }
869
- totalBytes += byteLength;
870
- if (totalBytes > HTML_EMBEDDED_MAX_TOTAL_BYTES) {
871
- throw new HtmlEmbeddedDataUriLimitError(`Total embedded image size exceeds max (${HTML_EMBEDDED_MAX_TOTAL_BYTES} bytes)`);
872
- }
873
- if (!seenUris.has(src)) {
874
- if (seenUris.size >= HTML_EMBEDDED_MAX_IMAGES_PER_DOC) {
875
- throw new HtmlEmbeddedDataUriLimitError(`Too many distinct embedded images (max ${HTML_EMBEDDED_MAX_IMAGES_PER_DOC})`);
876
- }
877
- seenUris.add(src);
878
- const stableKey = await getContentHash(binary);
879
- found.push({ dataUri: src, stableKey, byteLength, mimeType: mimeRaw });
880
- }
881
- }
882
- }
883
- }
884
- const parent = el;
885
- if (parent.childNodes) {
886
- for (const c of parent.childNodes)
887
- await walk(c);
888
- }
889
- };
890
- for (const c of fragment.childNodes)
891
- await walk(c);
892
- return found;
893
- }
894
- /**
895
- * Replace `data:image/...` src values with Arweave URLs using upload results keyed by image seed local id.
896
- */
897
- function replaceDataUrisInParsedHtml(html, replacements) {
898
- if (replacements.size === 0)
899
- return html;
900
- const fragment = parseFragment(html);
901
- const walk = (node) => {
902
- if (node.nodeName === '#text' || node.nodeName === '#comment')
903
- return;
904
- const el = node;
905
- if (el.tagName === 'img') {
906
- const src = getAttr(el, 'src')?.trim();
907
- if (src && replacements.has(src)) {
908
- setAttr(el, 'src', replacements.get(src));
909
- }
910
- }
911
- const parent = el;
912
- if (parent.childNodes) {
913
- for (const c of parent.childNodes)
914
- walk(c);
915
- }
916
- };
917
- for (const c of fragment.childNodes)
918
- walk(c);
919
- return serialize(fragment);
920
- }
921
- async function deleteCoPublishRowsForParent(appDb, parentSeedLocalId) {
922
- if (!appDb)
923
- return;
924
- await appDb.delete(htmlEmbeddedImageCoPublish).where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, parentSeedLocalId));
925
- }
926
- /**
927
- * Create an Image item and persist a data URI into its storageTransactionId (same path as user paste).
928
- */
929
- async function createImageItemFromDataUri(dataUri) {
930
- const imageItem = await Item.create({
931
- modelName: 'Image',
932
- });
933
- await waitForEntityIdle(imageItem, { timeout: 60000 });
934
- const st = imageItem.internalProperties['storageTransactionId'] ??
935
- imageItem.allProperties['storageTransactionId'];
936
- if (!st) {
937
- throw new Error('Image item missing storageTransactionId property');
938
- }
939
- st.value = dataUri;
940
- await st.save();
941
- await waitForEntityIdle(imageItem, { timeout: 60000 });
942
- return { seedLocalId: imageItem.seedLocalId };
1164
+ return out;
943
1165
  }
944
- /**
945
- * Scan Html storage properties, materialize embedded images as Image items, insert co-publish rows.
946
- * Call before phase-1 Arweave tx build. Does not rewrite Html files yet.
947
- */
948
- async function prepareHtmlEmbeddedImagesForPublish(item, publishPolicy) {
949
- const appDb = BaseDb.getAppDb();
950
- if (!appDb) {
951
- return { deferredHtmlSeedLocalIds: [] };
1166
+ /** Seed refs held by a relation/image property (one) or a list property (each member). */
1167
+ function seedRefsOf(prop, isList) {
1168
+ const context = propertyContext(prop);
1169
+ if (!context)
1170
+ return [];
1171
+ let value = context.propertyValue;
1172
+ if (isList) {
1173
+ if (typeof value === 'string')
1174
+ value = parseListPropertyValueFromStorage(value);
1175
+ return (Array.isArray(value) ? value : [])
1176
+ .map((v) => normalizeRelationPropertyValue(v))
1177
+ .filter((v) => !!v);
952
1178
  }
953
- await deleteCoPublishRowsForParent(appDb, item.seedLocalId);
954
- const deferred = new Set();
955
- for (const p of item.properties) {
956
- const def = p.propertyDef;
957
- if (!def || normalizeDataTypeLocal(def.dataType) !== ModelPropertyDataTypes.Html)
958
- continue;
959
- const policy = resolveEffectiveHtmlEmbeddedDataUriPolicy(def, publishPolicy);
960
- if (policy !== 'materialize')
961
- continue;
962
- const snap = p.getService().getSnapshot();
963
- const ctx = 'context' in snap ? snap.context : null;
964
- const htmlSeedLocalId = typeof ctx?.propertyValue === 'string' ? ctx.propertyValue : '';
965
- const refResolved = ctx?.refResolvedValue;
966
- if (!htmlSeedLocalId?.trim() || !refResolved)
967
- continue;
968
- const filePath = `${BaseFileManager.getFilesPath('html')}/${refResolved}`;
969
- const exists = await BaseFileManager.pathExists(filePath);
970
- if (!exists)
1179
+ const ref = normalizeRelationPropertyValue(value);
1180
+ return ref ? [ref] : [];
1181
+ }
1182
+ /** Like getPublishPayload: attested refs to revoked seeds block the publish. */
1183
+ async function collectUnpublishedRelatedItems(props, isList, forceFullSnapshot, out) {
1184
+ for (const prop of props) {
1185
+ if (!shouldAttestProperty(prop, forceFullSnapshot))
971
1186
  continue;
972
- let html;
973
- try {
974
- html = await BaseFileManager.readFileAsString(filePath);
975
- }
976
- catch {
977
- const buf = await BaseFileManager.readFileAsBuffer(filePath);
978
- if (typeof Buffer !== 'undefined' && Buffer.isBuffer(buf)) {
979
- html = buf.toString('utf-8');
980
- }
981
- else if (typeof Blob !== 'undefined' && buf instanceof Blob) {
982
- html = await buf.text();
983
- }
984
- else if (buf instanceof ArrayBuffer) {
985
- html = new TextDecoder('utf-8', { fatal: false }).decode(buf);
986
- }
987
- else {
988
- const v = buf;
989
- html = new TextDecoder('utf-8', { fatal: false }).decode(new Uint8Array(v.buffer, v.byteOffset, v.byteLength));
1187
+ for (const ref of seedRefsOf(prop, isList)) {
1188
+ const { seedLocalId, seedUid } = resolveSeedIdsFromRefString(ref);
1189
+ if (!seedLocalId && !seedUid)
1190
+ continue;
1191
+ const row = await findRelatedSeedRow({ seedLocalId, seedUid });
1192
+ if (!isUnpublishedSeed(row))
1193
+ continue;
1194
+ if (out.some((r) => r.propertyName === prop.propertyName && r.seedLocalId === row.seedLocalId)) {
1195
+ continue;
990
1196
  }
991
- }
992
- let extracted;
993
- try {
994
- extracted = await extractDataUriImagesFromHtml(html);
995
- }
996
- catch (e) {
997
- if (e instanceof HtmlEmbeddedDataUriLimitError)
998
- throw e;
999
- throw e;
1000
- }
1001
- if (extracted.length === 0)
1002
- continue;
1003
- deferred.add(htmlSeedLocalId.trim());
1004
- for (const ent of extracted) {
1005
- const { seedLocalId: imageSeedLocalId } = await createImageItemFromDataUri(ent.dataUri);
1006
- const now = Date.now();
1007
- await appDb.insert(htmlEmbeddedImageCoPublish).values({
1008
- parentSeedLocalId: item.seedLocalId,
1009
- htmlSeedLocalId: htmlSeedLocalId.trim(),
1010
- imageSeedLocalId,
1011
- stableKey: ent.stableKey,
1012
- createdAt: now,
1013
- }).onConflictDoNothing();
1197
+ const related = await loadRelatedItem(row.seedLocalId);
1198
+ out.push({
1199
+ propertyName: prop.propertyName,
1200
+ modelName: related?.modelName ?? relatedModelNameFromDef(prop.propertyDef) ?? row.type ?? 'unknown',
1201
+ seedLocalId: row.seedLocalId,
1202
+ seedUid: row.seedUid,
1203
+ });
1014
1204
  }
1015
1205
  }
1016
- return { deferredHtmlSeedLocalIds: [...deferred] };
1017
- }
1018
- function normalizeDataTypeLocal(dt) {
1019
- if (!dt)
1020
- return '';
1021
- return dt.charAt(0).toUpperCase() + dt.slice(1).toLowerCase();
1022
1206
  }
1023
1207
  /**
1024
- * After phase-1 uploads, rewrite Html files on disk: data URI → Arweave gateway URL.
1208
+ * Images embedded in Html properties (co-published) whose seed was revoked: getPublishPayload rejects
1209
+ * them like image properties pointing at revoked seeds. Like getPublishPayload, checks the published
1210
+ * item's co-publish rows and those of the draft items published with it.
1025
1211
  */
1026
- async function rewriteHtmlEmbeddedImagesOnDisk(parentSeedLocalId, uploadedTransactions) {
1212
+ async function collectUnpublishedEmbeddedImages(item, out) {
1213
+ const appDb = BaseDb.getAppDb();
1214
+ if (!appDb || !item.seedLocalId)
1215
+ return;
1216
+ for (const owner of [item, ...(await getRelatedDraftsCoPublishedWith(item))]) {
1217
+ const rows = await appDb
1218
+ .select()
1219
+ .from(htmlEmbeddedImageCoPublish)
1220
+ .where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, owner.seedLocalId));
1221
+ for (const row of rows) {
1222
+ const seed = await findRelatedSeedRow({ seedLocalId: row.imageSeedLocalId });
1223
+ if (!isUnpublishedSeed(seed))
1224
+ continue;
1225
+ const propertyName = htmlPropertyNameForHtmlSeed(owner, row.htmlSeedLocalId);
1226
+ if (out.some((r) => r.propertyName === propertyName && r.seedLocalId === seed.seedLocalId))
1227
+ continue;
1228
+ out.push({ propertyName, modelName: 'Image', seedLocalId: seed.seedLocalId, seedUid: seed.seedUid });
1229
+ }
1230
+ }
1231
+ }
1232
+ async function appendCoPublishImages(item, acc, seen, visited, forceFullSnapshot, publishMode) {
1027
1233
  const appDb = BaseDb.getAppDb();
1028
1234
  if (!appDb)
1029
1235
  return;
1030
1236
  const rows = await appDb
1031
1237
  .select()
1032
1238
  .from(htmlEmbeddedImageCoPublish)
1033
- .where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, parentSeedLocalId));
1034
- if (rows.length === 0)
1035
- return;
1036
- const txByImageSeed = new Map();
1037
- for (const u of uploadedTransactions) {
1038
- if (u.seedLocalId && u.txId) {
1039
- txByImageSeed.set(u.seedLocalId.trim(), u.txId.trim());
1239
+ .where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, item.seedLocalId));
1240
+ for (const row of rows) {
1241
+ const _mod_1 = await import('./Item-zBFWQDU9.js');
1242
+ const _ns_1 = _mod_1.Z;
1243
+ const { Item } = _ns_1;
1244
+ const imageItem = await Item.find({
1245
+ seedLocalId: row.imageSeedLocalId,
1246
+ modelName: 'Image',
1247
+ });
1248
+ // Like getPublishPayload: an embedded image that already has a seed (published, or unpublished
1249
+ // and reported by collectUnpublishedEmbeddedImages) is not co-published.
1250
+ if (!imageItem || !isZeroUid(imageItem.seedUid))
1251
+ continue;
1252
+ const st = imageItem.internalProperties['storageTransactionId'] ??
1253
+ imageItem.allProperties['storageTransactionId'];
1254
+ const stCtx = st ? propertyContext(st) : null;
1255
+ const stValue = typeof stCtx?.propertyValue === 'string' ? stCtx.propertyValue : '';
1256
+ const dataUriBytes = estimateDataUriByteLength(stValue);
1257
+ if (dataUriBytes != null && dataUriBytes > 0) {
1258
+ await addUpload(acc, seen, `seed:${imageItem.seedLocalId}`, dataUriBytes);
1040
1259
  }
1260
+ await summarizeItem(imageItem, publishMode, forceFullSnapshot, acc, seen, visited);
1041
1261
  }
1042
- const htmlSeedIds = new Set(rows.map((r) => String(r.htmlSeedLocalId).trim()));
1043
- const parentItem = await Item.find({ seedLocalId: parentSeedLocalId });
1044
- const refByHtmlSeed = new Map();
1045
- if (parentItem) {
1046
- for (const p of parentItem.properties) {
1047
- const def = p.propertyDef;
1048
- if (!def || normalizeDataTypeLocal(def.dataType) !== ModelPropertyDataTypes.Html)
1049
- continue;
1050
- const snap = p.getService().getSnapshot();
1051
- const ctx = 'context' in snap ? snap.context : null;
1052
- const pv = typeof ctx?.propertyValue === 'string' ? ctx.propertyValue.trim() : '';
1053
- const refResolved = ctx?.refResolvedValue;
1054
- if (pv && refResolved)
1055
- refByHtmlSeed.set(pv, refResolved);
1262
+ }
1263
+ async function summarizeItem(item, publishMode, forceFullSnapshot, acc, seenUploads, visited) {
1264
+ const seedLocalId = item.seedLocalId;
1265
+ if (!seedLocalId || visited.has(seedLocalId))
1266
+ return;
1267
+ visited.add(seedLocalId);
1268
+ acc.seedCount += 1;
1269
+ if (isZeroUid(item.seedUid))
1270
+ acc.newSeedCount += 1;
1271
+ if (isZeroUid(item.seedUid) || forceFullSnapshot)
1272
+ acc.newVersionCount += 1;
1273
+ const { itemBasicProperties, itemRelationProperties, itemListProperties, itemUploadProperties, itemImageProperties, } = await getSegmentedItemProperties(item);
1274
+ await collectUploadBytes(item, itemUploadProperties, itemImageProperties, undefined, acc, seenUploads);
1275
+ await collectUnpublishedRelatedItems([...itemRelationProperties, ...itemImageProperties], false, forceFullSnapshot, acc.unpublishedRelatedItems);
1276
+ await collectUnpublishedRelatedItems(itemListProperties, true, forceFullSnapshot, acc.unpublishedRelatedItems);
1277
+ for (const rel of itemRelationProperties) {
1278
+ const related = await relatedIfUnpublished(rel);
1279
+ if (related) {
1280
+ await summarizeItem(related, publishMode, forceFullSnapshot, acc, seenUploads, visited);
1056
1281
  }
1057
1282
  }
1058
- for (const htmlSeedLocalId of htmlSeedIds) {
1059
- const refResolved = refByHtmlSeed.get(String(htmlSeedLocalId));
1060
- if (!refResolved)
1061
- continue;
1062
- const filePath = `${BaseFileManager.getFilesPath('html')}/${refResolved}`;
1063
- if (!(await BaseFileManager.pathExists(filePath)))
1064
- continue;
1065
- const html = await BaseFileManager.readFileAsString(filePath);
1066
- const replacements = new Map();
1067
- for (const r of rows) {
1068
- if (String(r.htmlSeedLocalId).trim() !== htmlSeedLocalId)
1069
- continue;
1070
- const txId = txByImageSeed.get(r.imageSeedLocalId.trim());
1071
- if (!txId)
1072
- continue;
1073
- const dataUri = await findDataUriForStableKey(html, r.stableKey);
1074
- if (dataUri)
1075
- replacements.set(dataUri, getArweaveUrlForTransaction(txId));
1283
+ for (const listProperty of itemListProperties) {
1284
+ for (const related of await unpublishedListItems(listProperty)) {
1285
+ await summarizeItem(related, publishMode, forceFullSnapshot, acc, seenUploads, visited);
1076
1286
  }
1077
- if (replacements.size === 0)
1287
+ }
1288
+ await appendCoPublishImages(item, acc, seenUploads, visited, forceFullSnapshot, publishMode);
1289
+ const attestable = [
1290
+ ...itemBasicProperties,
1291
+ ...itemRelationProperties,
1292
+ ...itemListProperties,
1293
+ ...itemImageProperties,
1294
+ ...itemUploadProperties.map((u) => u.itemProperty),
1295
+ ];
1296
+ const seenProps = new Set();
1297
+ for (const prop of attestable) {
1298
+ const key = prop.localId || `${prop.propertyName}:${prop.seedLocalId}`;
1299
+ if (seenProps.has(key))
1078
1300
  continue;
1079
- const newHtml = replaceDataUrisInParsedHtml(html, replacements);
1080
- try {
1081
- await BaseFileManager.saveFile(filePath, newHtml);
1082
- }
1083
- catch {
1084
- const fs = await BaseFileManager.getFs();
1085
- fs.writeFileSync(filePath, newHtml);
1086
- }
1087
- if (parentItem) {
1088
- for (const p of parentItem.properties) {
1089
- const snap = p.getService().getSnapshot();
1090
- const ctx = 'context' in snap ? snap.context : null;
1091
- const pv = typeof ctx?.propertyValue === 'string' ? ctx.propertyValue.trim() : '';
1092
- if (pv === htmlSeedLocalId) {
1093
- p.getService().send({
1094
- type: 'updateContext',
1095
- renderValue: newHtml,
1096
- });
1097
- }
1098
- }
1099
- }
1301
+ seenProps.add(key);
1302
+ if (shouldAttestProperty(prop, forceFullSnapshot))
1303
+ acc.attestationCount += 1;
1100
1304
  }
1101
1305
  }
1102
- async function findDataUriForStableKey(html, stableKey) {
1103
- const entries = await extractDataUriImagesFromHtml(html);
1104
- const hit = entries.find((e) => e.stableKey === stableKey);
1105
- return hit?.dataUri;
1106
- }
1107
1306
  /**
1108
- * Remove co-publish rows after a successful publish for this parent seed.
1307
+ * Local measurement of what a publish would do: seed/version/attestation counts
1308
+ * and Arweave upload byte totals. Does not hit the network or create transactions.
1109
1309
  */
1110
- async function clearHtmlEmbeddedImageCoPublishRows(parentSeedLocalId) {
1111
- const appDb = BaseDb.getAppDb();
1112
- if (!appDb || !parentSeedLocalId)
1310
+ const publishForcesFullSnapshot = async (item, publishMode) => {
1311
+ // Like getPublishPayload: an item whose seed was revoked republishes as a new seed with a full
1312
+ // snapshot.
1313
+ const republishRevokedSeed = !isZeroUid(item.seedUid) && (await isSeedRevoked(item.seedLocalId));
1314
+ return { republishRevokedSeed, forceFullSnapshot: publishMode === 'new_version' || republishRevokedSeed };
1315
+ };
1316
+ async function collectUnpublishedRelatedItemsDeep(item, forceFullSnapshot, out, visited) {
1317
+ const seedLocalId = item.seedLocalId;
1318
+ if (!seedLocalId || visited.has(seedLocalId))
1113
1319
  return;
1114
- await appDb
1115
- .delete(htmlEmbeddedImageCoPublish)
1116
- .where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, parentSeedLocalId.trim()));
1320
+ visited.add(seedLocalId);
1321
+ const { itemRelationProperties, itemListProperties, itemImageProperties } = await getSegmentedItemProperties(item);
1322
+ await collectUnpublishedRelatedItems([...itemRelationProperties, ...itemImageProperties], false, forceFullSnapshot, out);
1323
+ await collectUnpublishedRelatedItems(itemListProperties, true, forceFullSnapshot, out);
1324
+ // Unpublished drafts the publish carries along are checked too.
1325
+ for (const rel of itemRelationProperties) {
1326
+ const related = await relatedIfUnpublished(rel);
1327
+ if (related)
1328
+ await collectUnpublishedRelatedItemsDeep(related, forceFullSnapshot, out, visited);
1329
+ }
1330
+ for (const listProperty of itemListProperties) {
1331
+ for (const related of await unpublishedListItems(listProperty)) {
1332
+ await collectUnpublishedRelatedItemsDeep(related, forceFullSnapshot, out, visited);
1333
+ }
1334
+ }
1117
1335
  }
1336
+ /**
1337
+ * References a publish of `item` would attest to items whose seed was unpublished (revoked), the
1338
+ * same ones getPublishPayload rejects with RelatedItemUnpublishedError. Local reads only: the
1339
+ * publish package checks this before registering schemas or uploading anything.
1340
+ */
1341
+ const getUnpublishedRelatedItems = async (item, options) => {
1342
+ const { forceFullSnapshot } = await publishForcesFullSnapshot(item, options?.publishMode ?? 'patch');
1343
+ const out = [];
1344
+ await collectUnpublishedRelatedItemsDeep(item, forceFullSnapshot, out, new Set());
1345
+ await collectUnpublishedEmbeddedImages(item, out);
1346
+ return out;
1347
+ };
1348
+ const summarizePublishWork = async (item, options) => {
1349
+ const publishMode = options?.publishMode ?? 'patch';
1350
+ const { republishRevokedSeed, forceFullSnapshot } = await publishForcesFullSnapshot(item, publishMode);
1351
+ const acc = {
1352
+ publishMode,
1353
+ seedCount: 0,
1354
+ newSeedCount: 0,
1355
+ newVersionCount: 0,
1356
+ attestationCount: 0,
1357
+ uploadCount: 0,
1358
+ uploadBytes: 0,
1359
+ unpublishedRelatedItems: [],
1360
+ };
1361
+ await summarizeItem(item, publishMode, forceFullSnapshot, acc, new Set(), new Set());
1362
+ await collectUnpublishedEmbeddedImages(item, acc.unpublishedRelatedItems);
1363
+ // summarizeItem counts the root as an existing seed (it has a seedUid).
1364
+ if (republishRevokedSeed)
1365
+ acc.newSeedCount += 1;
1366
+ return acc;
1367
+ };
1118
1368
 
1119
- export { BaseDb, BaseFileManager, BaseFileManager as FileManager, HTML_EMBEDDED_MAX_IMAGES_PER_DOC, HTML_EMBEDDED_MAX_IMAGE_BYTES, HTML_EMBEDDED_MAX_TOTAL_BYTES, HtmlEmbeddedDataUriLimitError, Item, ModelPropertyDataTypes, applyArweaveL1TransactionIdLocal, applyPropertyAttestationUidsFromPublish, clearHtmlEmbeddedImageCoPublishRows, estimateDataUriByteLength, extractDataUriImagesFromHtml, getArweaveUrlForTransaction, getAttesterForSeed, getMetadataAttestationUidsForSeedUid, getPublishPendingDiff, getRelatedItemsForPublish, getSeedPublishState, getSegmentedItemProperties, getVersionsForSeedUid, htmlEmbeddedImageCoPublish, isDataType, metadata, normalizeDataType, normalizePublisher, normalizeRelationPropertyValue, prepareHtmlEmbeddedImagesForPublish, replaceDataUrisInParsedHtml, resolveEffectiveHtmlEmbeddedDataUriPolicy, resolveSeedIdsFromRefString, rewriteHtmlEmbeddedImagesOnDisk, seeds, shouldAttestProperty, summarizePublishWork, updateVersionUid, versions, waitForEntityIdle };
1369
+ export { BaseDb, BaseFileManager, BaseFileManager as FileManager, HTML_EMBEDDED_MAX_IMAGES_PER_DOC, HTML_EMBEDDED_MAX_IMAGE_BYTES, HTML_EMBEDDED_MAX_TOTAL_BYTES, HtmlEmbeddedDataUriLimitError, Item, ModelPropertyDataTypes, applyArweaveL1TransactionIdLocal, applyPropertyAttestationUidsFromPublish, clearHtmlEmbeddedImageCoPublishRows, compareMetadataRowsLatestFirst, estimateDataUriByteLength, extractDataUriImagesFromHtml, generateId, getArweaveUrlForTransaction, getAttesterForSeed, getMetadataAttestationUidsForSeedUid, getPublishPendingDiff, getRelatedItemsForPublish, getSeedPublishState, getSegmentedItemProperties, getUnpublishedRelatedItems, getVersionsForSeedUid, htmlEmbeddedImageCoPublish, isDataType, metadata, normalizeDataType, normalizePublisher, normalizeRelationPropertyValue, prepareHtmlEmbeddedImagesForPublish, replaceDataUrisInParsedHtml, resolveEffectiveHtmlEmbeddedDataUriPolicy, resolveSeedIdsFromRefString, rewriteHtmlEmbeddedImagesOnDisk, seeds, shouldAttestProperty, summarizePublishWork, updateVersionUid, versions, waitForEntityIdle };
1120
1370
  //# sourceMappingURL=main.js.map