@seedprotocol/sdk 0.6.10 → 0.7.1

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 (399) hide show
  1. package/dist/{BasePathResolver-B6CKqoKw.js → BasePathResolver-DRT09oVv.js} +36 -2
  2. package/dist/BasePathResolver-DRT09oVv.js.map +1 -0
  3. package/dist/ClientManager-DngaZdw6.js +4763 -0
  4. package/dist/ClientManager-DngaZdw6.js.map +1 -0
  5. package/dist/{ClientManager-ChcmUL47.js → Item-ZUAmf943.js} +1175 -5903
  6. package/dist/Item-ZUAmf943.js.map +1 -0
  7. package/dist/{ModelProperty-D79uV42p.js → ModelProperty-6llK4MTH.js} +326 -109
  8. package/dist/ModelProperty-6llK4MTH.js.map +1 -0
  9. package/dist/{Schema-a8uO-hIZ.js → Schema-D-Ud-XYw.js} +164 -885
  10. package/dist/Schema-D-Ud-XYw.js.map +1 -0
  11. package/dist/{SchemaValidationService-Y49vqast.js → SchemaValidationService-IoS7JquP.js} +26 -18
  12. package/dist/SchemaValidationService-IoS7JquP.js.map +1 -0
  13. package/dist/{backfillMetadataPropertyIds-CBsf7LnU.js → backfillMetadataPropertyIds-BlVeE7w7.js} +11 -6
  14. package/dist/backfillMetadataPropertyIds-BlVeE7w7.js.map +1 -0
  15. package/dist/cjs/{ModelProperty-D9FGaGuE.js → ModelProperty-Dv7AQfmQ.js} +297 -89
  16. package/dist/cjs/ModelProperty-Dv7AQfmQ.js.map +1 -0
  17. package/dist/cjs/{Schema-BiJIPLEL.js → Schema-BHVp1g-M.js} +136 -868
  18. package/dist/cjs/Schema-BHVp1g-M.js.map +1 -0
  19. package/dist/cjs/{SchemaValidationService-DtYs_CNY.js → SchemaValidationService-BSU9knjf.js} +18 -11
  20. package/dist/cjs/SchemaValidationService-BSU9knjf.js.map +1 -0
  21. package/dist/cjs/{backfillMetadataPropertyIds-2XaN3b9S.js → backfillMetadataPropertyIds-WIovQ_d8.js} +8 -3
  22. package/dist/cjs/backfillMetadataPropertyIds-WIovQ_d8.js.map +1 -0
  23. package/dist/cjs/{eas-CMNppmGE.js → eas-CUYXdr2t.js} +4 -4
  24. package/dist/cjs/{eas-CMNppmGE.js.map → eas-CUYXdr2t.js.map} +1 -1
  25. package/dist/cjs/{getItem-B6jEINjW.js → getItem-z1tHu0hu.js} +2 -2
  26. package/dist/cjs/{getItem-B6jEINjW.js.map → getItem-z1tHu0hu.js.map} +1 -1
  27. package/dist/cjs/getLatestVersionRow-CcaabxIW.js +59 -0
  28. package/dist/cjs/getLatestVersionRow-CcaabxIW.js.map +1 -0
  29. package/dist/cjs/{getPublishPayload-D5DhLGvN.js → getPublishPayload-CEP_e-Kv.js} +283 -138
  30. package/dist/cjs/getPublishPayload-CEP_e-Kv.js.map +1 -0
  31. package/dist/cjs/{getPublishUploads-DMhCCKYF.js → getPublishUploads-Ctn5k1k6.js} +65 -19
  32. package/dist/cjs/getPublishUploads-Ctn5k1k6.js.map +1 -0
  33. package/dist/cjs/{index-CSNtEnbF.js → index-Cvvt0-5B.js} +2698 -1725
  34. package/dist/cjs/index-Cvvt0-5B.js.map +1 -0
  35. package/dist/cjs/{index-DPp9rdRL.js → index-DfGhF1dc.js} +3 -3
  36. package/dist/cjs/index-DfGhF1dc.js.map +1 -0
  37. package/dist/cjs/{property-DlKiAWt4.js → property-DbEPQ1m9.js} +40 -35
  38. package/dist/cjs/property-DbEPQ1m9.js.map +1 -0
  39. package/dist/cjs/publishDraftGraph-C38gf302.js +403 -0
  40. package/dist/cjs/publishDraftGraph-C38gf302.js.map +1 -0
  41. package/dist/cjs/resetAmbiguousLegacyItemData-CfMhRHwK.js +116 -0
  42. package/dist/cjs/resetAmbiguousLegacyItemData-CfMhRHwK.js.map +1 -0
  43. package/dist/cjs/resolveModelForSyncedSeed-CNYaLOir.js +49 -0
  44. package/dist/cjs/resolveModelForSyncedSeed-CNYaLOir.js.map +1 -0
  45. package/dist/cjs/syncDbWithEas-d1iOdTTI.js +886 -0
  46. package/dist/cjs/syncDbWithEas-d1iOdTTI.js.map +1 -0
  47. package/dist/{configurePlatform-CE0Vew17.js → configurePlatform-CZpjyuCo.js} +4 -4
  48. package/dist/{configurePlatform-CE0Vew17.js.map → configurePlatform-CZpjyuCo.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-Lw0KVZmc.js} +546 -106
  65. package/dist/db-Lw0KVZmc.js.map +1 -0
  66. package/dist/{eas-CfYCu4IX.js → eas-CQ-Smzk2.js} +7 -7
  67. package/dist/eas-CQ-Smzk2.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-CSfSok9f.js} +8 -10
  71. package/dist/{getItem-Br-bGNFO.js.map → getItem-CSfSok9f.js.map} +1 -1
  72. package/dist/getLatestVersionRow-72Atl9vB.js +46 -0
  73. package/dist/getLatestVersionRow-72Atl9vB.js.map +1 -0
  74. package/dist/{getPublishPayload-BIrTVUxb.js → getPublishPayload-76_KfB5Y.js} +297 -154
  75. package/dist/getPublishPayload-76_KfB5Y.js.map +1 -0
  76. package/dist/{getPublishUploads-C6cDeZdz.js → getPublishUploads-CqgMBD8f.js} +68 -21
  77. package/dist/getPublishUploads-CqgMBD8f.js.map +1 -0
  78. package/dist/{index-Djd3667v.js → index-5b3JsS55.js} +2 -2
  79. package/dist/index-5b3JsS55.js.map +1 -0
  80. package/dist/{index-ClSv5pTA.js → index-BpgD305l.js} +12 -11
  81. package/dist/index-BpgD305l.js.map +1 -0
  82. package/dist/{index-HRHkbVQd.js → index-Y-yYyRBf.js} +530 -196
  83. package/dist/index-Y-yYyRBf.js.map +1 -0
  84. package/dist/index.browser-DaTzn79x.js +4139 -0
  85. package/dist/index.browser-DaTzn79x.js.map +1 -0
  86. package/dist/{index.node-DBtQkEfz.js → index.node-NYKqFOoe.js} +9 -4
  87. package/dist/index.node-NYKqFOoe.js.map +1 -0
  88. package/dist/main.cjs +1 -1
  89. package/dist/main.js +886 -560
  90. package/dist/main.js.map +1 -1
  91. package/dist/node.js +19 -15
  92. package/dist/node.js.map +1 -1
  93. package/dist/platform.browser.js +18 -3719
  94. package/dist/platform.browser.js.map +1 -1
  95. package/dist/platform.node.js +3 -3
  96. package/dist/{property-CQjuZ4JW.js → property-ByaiSyUK.js} +53 -48
  97. package/dist/property-ByaiSyUK.js.map +1 -0
  98. package/dist/publishDraftGraph-BRm6Pq3Q.js +405 -0
  99. package/dist/publishDraftGraph-BRm6Pq3Q.js.map +1 -0
  100. package/dist/resetAmbiguousLegacyItemData-B4dX6ZA1.js +88 -0
  101. package/dist/resetAmbiguousLegacyItemData-B4dX6ZA1.js.map +1 -0
  102. package/dist/resolveModelForSyncedSeed-B0tco3zG.js +46 -0
  103. package/dist/resolveModelForSyncedSeed-B0tco3zG.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 +21 -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 +13 -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 +52 -2
  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/actors/validateModel.d.ts.map +1 -1
  131. package/dist/src/Model/service/modelMachine.d.ts +0 -8
  132. package/dist/src/Model/service/modelMachine.d.ts.map +1 -1
  133. package/dist/src/ModelProperty/ModelProperty.d.ts +42 -2
  134. package/dist/src/ModelProperty/ModelProperty.d.ts.map +1 -1
  135. package/dist/src/ModelProperty/service/actors/compareAndMarkDraft.d.ts.map +1 -1
  136. package/dist/src/ModelProperty/service/actors/saveToSchema.d.ts.map +1 -1
  137. package/dist/src/ModelProperty/service/actors/validateProperty.d.ts.map +1 -1
  138. package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts +2 -9
  139. package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts.map +1 -1
  140. package/dist/src/Schema/Schema.d.ts +8 -2
  141. package/dist/src/Schema/Schema.d.ts.map +1 -1
  142. package/dist/src/Schema/service/actors/checkExistingSchema.d.ts.map +1 -1
  143. package/dist/src/Schema/service/actors/createModelInstances.d.ts.map +1 -1
  144. package/dist/src/Schema/service/actors/loadOrCreateSchema.d.ts.map +1 -1
  145. package/dist/src/Schema/service/schemaMachine.d.ts +1 -217
  146. package/dist/src/Schema/service/schemaMachine.d.ts.map +1 -1
  147. package/dist/src/Schema/service/validation/SchemaValidationService.d.ts.map +1 -1
  148. package/dist/src/browser/db/Db.d.ts +3 -0
  149. package/dist/src/browser/db/Db.d.ts.map +1 -1
  150. package/dist/src/browser/db/drizzleFiles.d.ts +7 -2
  151. package/dist/src/browser/db/drizzleFiles.d.ts.map +1 -1
  152. package/dist/src/browser/db/embeddedMigrations.d.ts +11 -2
  153. package/dist/src/browser/db/embeddedMigrations.d.ts.map +1 -1
  154. package/dist/src/browser/db/sqliteBusyRetry.d.ts +14 -0
  155. package/dist/src/browser/db/sqliteBusyRetry.d.ts.map +1 -0
  156. package/dist/src/browser/helpers/FileManager.d.ts +1 -0
  157. package/dist/src/browser/helpers/FileManager.d.ts.map +1 -1
  158. package/dist/src/browser/helpers/QueryClient.d.ts +1 -0
  159. package/dist/src/browser/helpers/QueryClient.d.ts.map +1 -1
  160. package/dist/src/browser/helpers/opfsErrors.d.ts +2 -0
  161. package/dist/src/browser/helpers/opfsErrors.d.ts.map +1 -0
  162. package/dist/src/browser/helpers/tolerantWebAccess.d.ts +47 -0
  163. package/dist/src/browser/helpers/tolerantWebAccess.d.ts.map +1 -0
  164. package/dist/src/browser/workers/FileDownloader.d.ts.map +1 -1
  165. package/dist/src/browser/workers/ImageResizer.d.ts.map +1 -1
  166. package/dist/src/browser/workers/filesDownload.d.ts.map +1 -1
  167. package/dist/src/browser/workers/imageResize.d.ts.map +1 -1
  168. package/dist/src/client/ClientManager.d.ts.map +1 -1
  169. package/dist/src/client/actors/addModelsToDb.d.ts +14 -0
  170. package/dist/src/client/actors/addModelsToDb.d.ts.map +1 -1
  171. package/dist/src/client/actors/platformClassesInit.d.ts.map +1 -1
  172. package/dist/src/client/actors/processSchemaFiles.d.ts.map +1 -1
  173. package/dist/src/client/actors/saveConfig.d.ts +11 -0
  174. package/dist/src/client/actors/saveConfig.d.ts.map +1 -1
  175. package/dist/src/client/constants.d.ts +0 -8
  176. package/dist/src/client/constants.d.ts.map +1 -1
  177. package/dist/src/db/backfillMetadataPropertyIds.d.ts.map +1 -1
  178. package/dist/src/db/configs/{dev.schema.config.d.ts → migrations.config.d.ts} +1 -1
  179. package/dist/src/db/configs/migrations.config.d.ts.map +1 -0
  180. package/dist/src/db/read/batchLatestPublishedVersionBySeedLocalIds.d.ts +1 -1
  181. package/dist/src/db/read/batchLatestPublishedVersionBySeedLocalIds.d.ts.map +1 -1
  182. package/dist/src/db/read/getItemData.d.ts.map +1 -1
  183. package/dist/src/db/read/getItemProperties.d.ts.map +1 -1
  184. package/dist/src/db/read/getItems.d.ts +7 -2
  185. package/dist/src/db/read/getItems.d.ts.map +1 -1
  186. package/dist/src/db/read/getLatestPublishedVersionRow.d.ts +2 -1
  187. package/dist/src/db/read/getLatestPublishedVersionRow.d.ts.map +1 -1
  188. package/dist/src/db/read/getLatestVersionRow.d.ts +13 -0
  189. package/dist/src/db/read/getLatestVersionRow.d.ts.map +1 -0
  190. package/dist/src/db/read/getModelSchemas.d.ts.map +1 -1
  191. package/dist/src/db/read/getPropertyData.d.ts.map +1 -1
  192. package/dist/src/db/read/getPublishPayload.d.ts +18 -11
  193. package/dist/src/db/read/getPublishPayload.d.ts.map +1 -1
  194. package/dist/src/db/read/getPublishPendingDiff.d.ts +2 -1
  195. package/dist/src/db/read/getPublishPendingDiff.d.ts.map +1 -1
  196. package/dist/src/db/read/getPublishUploads.d.ts +5 -0
  197. package/dist/src/db/read/getPublishUploads.d.ts.map +1 -1
  198. package/dist/src/db/read/getSchemaUidForModel.d.ts.map +1 -1
  199. package/dist/src/db/read/getSeedPublishState.d.ts +8 -2
  200. package/dist/src/db/read/getSeedPublishState.d.ts.map +1 -1
  201. package/dist/src/db/read/isSeedRevoked.d.ts +7 -0
  202. package/dist/src/db/read/isSeedRevoked.d.ts.map +1 -0
  203. package/dist/src/db/read/publishDraftGraph.d.ts +57 -0
  204. package/dist/src/db/read/publishDraftGraph.d.ts.map +1 -0
  205. package/dist/src/db/read/publishErrors.d.ts +37 -0
  206. package/dist/src/db/read/publishErrors.d.ts.map +1 -0
  207. package/dist/src/db/read/resolveModelForSyncedSeed.d.ts +39 -0
  208. package/dist/src/db/read/resolveModelForSyncedSeed.d.ts.map +1 -0
  209. package/dist/src/db/read/resolveModelRecord.d.ts +69 -0
  210. package/dist/src/db/read/resolveModelRecord.d.ts.map +1 -0
  211. package/dist/src/db/read/resolveRelatedSeedRef.d.ts +34 -0
  212. package/dist/src/db/read/resolveRelatedSeedRef.d.ts.map +1 -0
  213. package/dist/src/db/read/subqueries/liveVersion.d.ts +12 -0
  214. package/dist/src/db/read/subqueries/liveVersion.d.ts.map +1 -0
  215. package/dist/src/db/read/subqueries/metadataLatest.d.ts +4 -0
  216. package/dist/src/db/read/subqueries/metadataLatest.d.ts.map +1 -1
  217. package/dist/src/db/read/subqueries/versionData.d.ts +7 -2
  218. package/dist/src/db/read/subqueries/versionData.d.ts.map +1 -1
  219. package/dist/src/db/read/summarizePublishWork.d.ts +10 -2
  220. package/dist/src/db/read/summarizePublishWork.d.ts.map +1 -1
  221. package/dist/src/db/resetAmbiguousLegacyItemData.d.ts +17 -0
  222. package/dist/src/db/resetAmbiguousLegacyItemData.d.ts.map +1 -0
  223. package/dist/src/db/sqlParamBatches.d.ts +27 -0
  224. package/dist/src/db/sqlParamBatches.d.ts.map +1 -0
  225. package/dist/src/db/write/addExcludedTransactions.d.ts +7 -0
  226. package/dist/src/db/write/addExcludedTransactions.d.ts.map +1 -0
  227. package/dist/src/db/write/applyPropertyAttestationUidsFromPublish.d.ts +6 -0
  228. package/dist/src/db/write/applyPropertyAttestationUidsFromPublish.d.ts.map +1 -1
  229. package/dist/src/db/write/createMetadata.d.ts +2 -0
  230. package/dist/src/db/write/createMetadata.d.ts.map +1 -1
  231. package/dist/src/db/write/createNewItem.d.ts +3 -1
  232. package/dist/src/db/write/createNewItem.d.ts.map +1 -1
  233. package/dist/src/db/write/createSeed.d.ts +2 -1
  234. package/dist/src/db/write/createSeed.d.ts.map +1 -1
  235. package/dist/src/db/write/createSeeds.d.ts +1 -1
  236. package/dist/src/db/write/createSeeds.d.ts.map +1 -1
  237. package/dist/src/db/write/linkModelToSchema.d.ts +12 -0
  238. package/dist/src/db/write/linkModelToSchema.d.ts.map +1 -0
  239. package/dist/src/db/write/updateItemPropertyValue.d.ts.map +1 -1
  240. package/dist/src/db/write/updateMetadata.d.ts.map +1 -1
  241. package/dist/src/db/write/updateSeedRevokedAt.d.ts +11 -1
  242. package/dist/src/db/write/updateSeedRevokedAt.d.ts.map +1 -1
  243. package/dist/src/db/write/updateSeedUid.d.ts.map +1 -1
  244. package/dist/src/db/write/updateVersionUid.d.ts +2 -1
  245. package/dist/src/db/write/updateVersionUid.d.ts.map +1 -1
  246. package/dist/src/events/files/download.d.ts.map +1 -1
  247. package/dist/src/events/item/easSyncManager.d.ts +2 -0
  248. package/dist/src/events/item/easSyncManager.d.ts.map +1 -1
  249. package/dist/src/events/item/index.d.ts.map +1 -1
  250. package/dist/src/events/item/syncDbWithEas.d.ts +16 -0
  251. package/dist/src/events/item/syncDbWithEas.d.ts.map +1 -1
  252. package/dist/src/helpers/FileManager/BaseFileManager.d.ts +1 -0
  253. package/dist/src/helpers/FileManager/BaseFileManager.d.ts.map +1 -1
  254. package/dist/src/helpers/FileManager/IFileManager.d.ts +5 -0
  255. package/dist/src/helpers/FileManager/IFileManager.d.ts.map +1 -1
  256. package/dist/src/helpers/FileManager/errors.d.ts +10 -0
  257. package/dist/src/helpers/FileManager/errors.d.ts.map +1 -0
  258. package/dist/src/helpers/compareMetadataRowsLatestFirst.d.ts +21 -3
  259. package/dist/src/helpers/compareMetadataRowsLatestFirst.d.ts.map +1 -1
  260. package/dist/src/helpers/constants.d.ts +9 -0
  261. package/dist/src/helpers/constants.d.ts.map +1 -1
  262. package/dist/src/helpers/crypto.d.ts +5 -0
  263. package/dist/src/helpers/crypto.d.ts.map +1 -1
  264. package/dist/src/helpers/db.d.ts +25 -5
  265. package/dist/src/helpers/db.d.ts.map +1 -1
  266. package/dist/src/helpers/easPropertyCanonical.d.ts +1 -1
  267. package/dist/src/helpers/easPropertyCanonical.d.ts.map +1 -1
  268. package/dist/src/helpers/entity/entityCommon.d.ts +10 -0
  269. package/dist/src/helpers/entity/entityCommon.d.ts.map +1 -1
  270. package/dist/src/helpers/entity/entityDestroy.d.ts +1 -1
  271. package/dist/src/helpers/entity/entityDestroy.d.ts.map +1 -1
  272. package/dist/src/helpers/entity/entityLiveQuery.d.ts +5 -0
  273. package/dist/src/helpers/entity/entityLiveQuery.d.ts.map +1 -1
  274. package/dist/src/helpers/entity/evictionEpoch.d.ts +18 -0
  275. package/dist/src/helpers/entity/evictionEpoch.d.ts.map +1 -0
  276. package/dist/src/helpers/file/fetchAll/actors.d.ts.map +1 -1
  277. package/dist/src/helpers/getSegmentedItemProperties.d.ts.map +1 -1
  278. package/dist/src/helpers/htmlEmbeddedDataUriPublish.d.ts +31 -3
  279. package/dist/src/helpers/htmlEmbeddedDataUriPublish.d.ts.map +1 -1
  280. package/dist/src/helpers/isPublishedMetadataRow.d.ts +10 -0
  281. package/dist/src/helpers/isPublishedMetadataRow.d.ts.map +1 -0
  282. package/dist/src/helpers/ownership.d.ts.map +1 -1
  283. package/dist/src/helpers/property.d.ts +6 -1
  284. package/dist/src/helpers/property.d.ts.map +1 -1
  285. package/dist/src/helpers/schema.d.ts +14 -4
  286. package/dist/src/helpers/schema.d.ts.map +1 -1
  287. package/dist/src/helpers/tabCoordinator.d.ts +45 -0
  288. package/dist/src/helpers/tabCoordinator.d.ts.map +1 -0
  289. package/dist/src/helpers/tabEvents.d.ts +27 -0
  290. package/dist/src/helpers/tabEvents.d.ts.map +1 -0
  291. package/dist/src/helpers/tabLocks.d.ts +28 -0
  292. package/dist/src/helpers/tabLocks.d.ts.map +1 -0
  293. package/dist/src/helpers/updateSchema.d.ts.map +1 -1
  294. package/dist/src/imports/json.d.ts.map +1 -1
  295. package/dist/src/imports/markdown.d.ts.map +1 -1
  296. package/dist/src/index.d.ts +13 -3
  297. package/dist/src/index.d.ts.map +1 -1
  298. package/dist/src/node/db/Db.d.ts.map +1 -1
  299. package/dist/src/node/helpers/FileManager.d.ts +2 -0
  300. package/dist/src/node/helpers/FileManager.d.ts.map +1 -1
  301. package/dist/src/query/createLocalQueryDataSource.d.ts +4 -0
  302. package/dist/src/query/createLocalQueryDataSource.d.ts.map +1 -1
  303. package/dist/src/seedSchema/MetadataSchema.d.ts +36 -0
  304. package/dist/src/seedSchema/MetadataSchema.d.ts.map +1 -1
  305. package/dist/src/seedSchema/ModelSchema.d.ts +57 -0
  306. package/dist/src/seedSchema/ModelSchema.d.ts.map +1 -1
  307. package/dist/src/seedSchema/SeedSchema.d.ts +19 -0
  308. package/dist/src/seedSchema/SeedSchema.d.ts.map +1 -1
  309. package/dist/src/seedSchema/VersionSchema.d.ts +17 -0
  310. package/dist/src/seedSchema/VersionSchema.d.ts.map +1 -1
  311. package/dist/src/services/write/actors/validateEntity.d.ts.map +1 -1
  312. package/dist/src/services/write/actors/writeToDatabase.d.ts +5 -0
  313. package/dist/src/services/write/actors/writeToDatabase.d.ts.map +1 -1
  314. package/dist/src/services/write/writeProcessMachine.d.ts.map +1 -1
  315. package/dist/src/stores/eas.d.ts +1 -1
  316. package/dist/src/stores/eas.d.ts.map +1 -1
  317. package/dist/src/types/index.d.ts +7 -0
  318. package/dist/src/types/index.d.ts.map +1 -1
  319. package/dist/src/types/item.d.ts +19 -11
  320. package/dist/src/types/item.d.ts.map +1 -1
  321. package/dist/src/types/property.d.ts +3 -2
  322. package/dist/src/types/property.d.ts.map +1 -1
  323. package/dist/syncDbWithEas-BPap9Sru.js +855 -0
  324. package/dist/syncDbWithEas-BPap9Sru.js.map +1 -0
  325. package/dist/{index-280bL-n4.js → tabEvents-C6NXS6Jl.js} +231 -68
  326. package/dist/tabEvents-C6NXS6Jl.js.map +1 -0
  327. package/dist/tolerantWebAccess-NBQ1NB4i.js +160 -0
  328. package/dist/tolerantWebAccess-NBQ1NB4i.js.map +1 -0
  329. package/dist/updateSeedRevokedAt-CYwgVNlM.js +32 -0
  330. package/dist/updateSeedRevokedAt-CYwgVNlM.js.map +1 -0
  331. package/package.json +8 -10
  332. package/dist/BasePathResolver-B6CKqoKw.js.map +0 -1
  333. package/dist/ClientManager-ChcmUL47.js.map +0 -1
  334. package/dist/ModelProperty-D79uV42p.js.map +0 -1
  335. package/dist/Schema-a8uO-hIZ.js.map +0 -1
  336. package/dist/SchemaValidationService-Y49vqast.js.map +0 -1
  337. package/dist/backfillMetadataPropertyIds-CBsf7LnU.js.map +0 -1
  338. package/dist/cjs/ModelProperty-D9FGaGuE.js.map +0 -1
  339. package/dist/cjs/Schema-BiJIPLEL.js.map +0 -1
  340. package/dist/cjs/SchemaValidationService-DtYs_CNY.js.map +0 -1
  341. package/dist/cjs/backfillMetadataPropertyIds-2XaN3b9S.js.map +0 -1
  342. package/dist/cjs/getPublishPayload-D5DhLGvN.js.map +0 -1
  343. package/dist/cjs/getPublishUploads-DMhCCKYF.js.map +0 -1
  344. package/dist/cjs/getSegmentedItemProperties-CU8rtBAo.js +0 -148
  345. package/dist/cjs/getSegmentedItemProperties-CU8rtBAo.js.map +0 -1
  346. package/dist/cjs/index-CSNtEnbF.js.map +0 -1
  347. package/dist/cjs/index-DPp9rdRL.js.map +0 -1
  348. package/dist/cjs/property-DlKiAWt4.js.map +0 -1
  349. package/dist/cjs/syncDbWithEas-C6n34o_Q.js +0 -606
  350. package/dist/cjs/syncDbWithEas-C6n34o_Q.js.map +0 -1
  351. package/dist/db-WbrzEf7c.js.map +0 -1
  352. package/dist/eas-CfYCu4IX.js.map +0 -1
  353. package/dist/getPublishPayload-BIrTVUxb.js.map +0 -1
  354. package/dist/getPublishUploads-C6cDeZdz.js.map +0 -1
  355. package/dist/getSegmentedItemProperties-BmKE71vU.js +0 -148
  356. package/dist/getSegmentedItemProperties-BmKE71vU.js.map +0 -1
  357. package/dist/index-280bL-n4.js.map +0 -1
  358. package/dist/index-ClSv5pTA.js.map +0 -1
  359. package/dist/index-Djd3667v.js.map +0 -1
  360. package/dist/index-HRHkbVQd.js.map +0 -1
  361. package/dist/index.node-DBtQkEfz.js.map +0 -1
  362. package/dist/property-CQjuZ4JW.js.map +0 -1
  363. package/dist/src/Item/service/actors/fetchDataFromEas.d.ts +0 -4
  364. package/dist/src/Item/service/actors/fetchDataFromEas.d.ts.map +0 -1
  365. package/dist/src/Item/service/actors/hydrateExistingItem.d.ts +0 -4
  366. package/dist/src/Item/service/actors/hydrateExistingItem.d.ts.map +0 -1
  367. package/dist/src/Item/service/actors/hydrateNewItem.d.ts +0 -4
  368. package/dist/src/Item/service/actors/hydrateNewItem.d.ts.map +0 -1
  369. package/dist/src/Item/service/actors/initialize.d.ts +0 -4
  370. package/dist/src/Item/service/actors/initialize.d.ts.map +0 -1
  371. package/dist/src/Item/service/actors/reload.d.ts +0 -5
  372. package/dist/src/Item/service/actors/reload.d.ts.map +0 -1
  373. package/dist/src/Item/service/actors/saveDataToDb.d.ts +0 -4
  374. package/dist/src/Item/service/actors/saveDataToDb.d.ts.map +0 -1
  375. package/dist/src/ItemProperty/service/actors/resolveRemoteStorage.d.ts +0 -5
  376. package/dist/src/ItemProperty/service/actors/resolveRemoteStorage.d.ts.map +0 -1
  377. package/dist/src/Schema/service/addModelsMachine.d.ts +0 -123
  378. package/dist/src/Schema/service/addModelsMachine.d.ts.map +0 -1
  379. package/dist/src/browser/helpers/index.d.ts +0 -4
  380. package/dist/src/browser/helpers/index.d.ts.map +0 -1
  381. package/dist/src/db/configs/dev.schema.config.d.ts.map +0 -1
  382. package/dist/src/helpers/file/download/actors.d.ts +0 -17
  383. package/dist/src/helpers/file/download/actors.d.ts.map +0 -1
  384. package/dist/src/helpers/file/download/index.d.ts +0 -70
  385. package/dist/src/helpers/file/download/index.d.ts.map +0 -1
  386. package/dist/src/services/publish/actors/createPublishAttempt.d.ts +0 -4
  387. package/dist/src/services/publish/actors/createPublishAttempt.d.ts.map +0 -1
  388. package/dist/src/services/publish/actors/preparePublishRequestData.d.ts +0 -4
  389. package/dist/src/services/publish/actors/preparePublishRequestData.d.ts.map +0 -1
  390. package/dist/src/services/publish/actors/upload.d.ts +0 -4
  391. package/dist/src/services/publish/actors/upload.d.ts.map +0 -1
  392. package/dist/src/services/publish/actors/validateItemData.d.ts +0 -4
  393. package/dist/src/services/publish/actors/validateItemData.d.ts.map +0 -1
  394. package/dist/src/services/publish/publishMachine.d.ts +0 -32
  395. package/dist/src/services/publish/publishMachine.d.ts.map +0 -1
  396. package/dist/syncDbWithEas-CuARXfyN.js +0 -598
  397. package/dist/syncDbWithEas-CuARXfyN.js.map +0 -1
  398. package/dist/updateSeedRevokedAt-CBcLfHWs.js +0 -22
  399. package/dist/updateSeedRevokedAt-CBcLfHWs.js.map +0 -1
@@ -0,0 +1,855 @@
1
+ import { s as normalizePublisher, t as getAllAddressesFromDb, u as normalizeHexAddress, o as getPropertyIdForModelAndName, r as resolveItemModelFileId, v as getItemStoragePropertiesForModel } from './db-Lw0KVZmc.js';
2
+ import { r as resolveModelForSyncedSeed, s as skipSeedOnAmbiguousModel } from './resolveModelForSyncedSeed-B0tco3zG.js';
3
+ import { camelCase } from 'lodash-es';
4
+ import { parseEasPropertyMetadata, parseEasRelationPropertyName } from '@seedprotocol/query';
5
+ import { B as BaseDb, i as modelUids, j as models, r as seeds, E as EAS_SEED_DATA_SYNCED_TO_DB_EVENT, v as versions, m as metadata } from './BasePathResolver-DRT09oVv.js';
6
+ import { eq, inArray, and, or, isNull, ne, isNotNull } from 'drizzle-orm';
7
+ import { t as toSnakeCase, s as scheduleBulkFilesDownloadFromEasSync, e as emitAcrossTabs } from './tabEvents-C6NXS6Jl.js';
8
+ import { modelPropertiesToObject } from './model-DGMe-TTm.js';
9
+ import { getSeedsFromSchemaUids, getItemVersionsFromEas, getItemPropertiesFromEas, BaseEasClient, GET_SEEDS, pickLatestPropertyAttestationsByRefAndSchema, setSchemaUidForSchemaDefinition } from '@seedprotocol/eas';
10
+ import pluralize from 'pluralize';
11
+ import { c as chunkValues, d as rowsPerInsert, e as getGetAdditionalSyncAddresses, s as selectInBatches, w as writeInBatches } from './Item-ZUAmf943.js';
12
+ import { u as updateSeedRevokedAt } from './updateSeedRevokedAt-CYwgVNlM.js';
13
+ import { getModelSchemasFromEas } from './eas-CQ-Smzk2.js';
14
+ import { w as waitForEasReadChain, a as assertLocalDbChain } from './ClientManager-DngaZdw6.js';
15
+ import { generateId } from './generateId-BopUwD8F.js';
16
+ import 'drizzle-orm/casing';
17
+ import 'debug';
18
+ import '@sinclair/typebox';
19
+ import 'drizzle-orm/sqlite-core';
20
+ import '@seedprotocol/arweave';
21
+ import 'xstate';
22
+ import 'nanoid';
23
+ import 'nanoid-dictionary';
24
+ import 'rxjs';
25
+ import '@noble/hashes/sha3';
26
+ import '@noble/hashes/utils';
27
+
28
+ // Dynamic import to break circular dependency: Model -> BaseItem -> ... -> getModelSchemas -> Model
29
+ // import { Model } from '@/Model/Model'
30
+ const schemaStringToModelRecord = new Map();
31
+ const getModelSchemas = async () => {
32
+ // Dynamic import to break circular dependency
33
+ const _mod_0 = await import('./index-Y-yYyRBf.js');
34
+ const _ns_0 = _mod_0.f;
35
+ const modelMod = _ns_0;
36
+ const { Model } = modelMod;
37
+ const allModels = await Model.all();
38
+ const modelRecords = [];
39
+ const appDb = BaseDb.getAppDb();
40
+ for (const model of allModels) {
41
+ const modelName = model.modelName;
42
+ if (!modelName)
43
+ continue;
44
+ const foundModelQuery = await appDb
45
+ .select({
46
+ id: models.id,
47
+ name: models.name,
48
+ uid: modelUids.uid,
49
+ })
50
+ .from(models)
51
+ .leftJoin(modelUids, eq(models.id, modelUids.modelId))
52
+ // Model names are only unique per schema: use this model's own row
53
+ .where(model.id ? eq(models.schemaFileId, model.id) : eq(models.name, modelName))
54
+ .limit(1);
55
+ if (!foundModelQuery[0]) {
56
+ console.error(`[item/events] [syncDbWithEas] model ${modelName} not found in SDK DB`);
57
+ continue;
58
+ }
59
+ const foundModel = {
60
+ id: foundModelQuery[0].id,
61
+ name: foundModelQuery[0].name,
62
+ uid: foundModelQuery[0].uid,
63
+ tableName: pluralize(foundModelQuery[0].name).toLowerCase(),
64
+ };
65
+ modelRecords.push(foundModel);
66
+ if (modelName === 'Seed') {
67
+ continue;
68
+ }
69
+ const schemaString = `bytes32 ${toSnakeCase(modelName)}`;
70
+ schemaStringToModelRecord.set(schemaString, foundModel);
71
+ }
72
+ return {
73
+ schemaStringToModelRecord,
74
+ modelRecords,
75
+ };
76
+ };
77
+
78
+ const createSeeds = async (newSeeds) => {
79
+ const appDb = BaseDb.getAppDb();
80
+ const values = newSeeds.map((row) => {
81
+ const publisher = normalizePublisher(row.publisher);
82
+ return {
83
+ ...row,
84
+ ...(publisher ? { publisher } : {}),
85
+ };
86
+ });
87
+ // Sync can create thousands of seeds at once: keep each INSERT under SQLite's parameter limit.
88
+ for (const chunk of chunkValues(values, rowsPerInsert(seeds))) {
89
+ await appDb.insert(seeds).values(chunk);
90
+ }
91
+ };
92
+
93
+ /**
94
+ * Sync stores the newest non-revoked attestation per (version, property schema). When every
95
+ * attestation of a property is revoked (e.g. after `item.unpublish()`), keep the newest one so a
96
+ * revoked item synced to a new device still has its last values next to its seed's `revokedAt`.
97
+ */
98
+ const SYNC_CANONICAL_OPTIONS = { ifAllRevoked: 'newestRevoked' };
99
+ /**
100
+ * When an attestation was revoked, in Unix seconds: EAS `revocationTime` is a block timestamp in
101
+ * seconds, the same unit local unpublish writes to `seeds.revoked_at`. `undefined` when not revoked.
102
+ * A revoked attestation without a revocation time (0 or not selected) falls back to now.
103
+ */
104
+ const revokedAtSeconds = (attestation) => {
105
+ if (!attestation.revoked)
106
+ return undefined;
107
+ return attestation.revocationTime != null && attestation.revocationTime > 0
108
+ ? attestation.revocationTime
109
+ : Math.floor(Date.now() / 1000);
110
+ };
111
+ /**
112
+ * `revoked_at` to store for an attestation that already has a row (seed, version or metadata), given the
113
+ * stored value. EAS's `revocationTime` wins once EAS reports one. A stored stamp is otherwise kept:
114
+ * local unpublish writes one only after its revoke transactions are mined, and revocation can't be
115
+ * undone, so EAS reporting the attestation as live then just means its index hasn't caught up yet.
116
+ */
117
+ const syncedRevokedAt = (attestation, stored) => {
118
+ if (attestation.revoked && attestation.revocationTime != null && attestation.revocationTime > 0) {
119
+ return attestation.revocationTime;
120
+ }
121
+ return stored ?? revokedAtSeconds(attestation) ?? null;
122
+ };
123
+ const relationValuesToExclude = [
124
+ '0x0000000000000000000000000000000000000000000000000000000000000020',
125
+ ];
126
+ const createSyncRunState = () => ({
127
+ seedUidToLocalId: new Map(),
128
+ seedUidToModelType: new Map(),
129
+ versionUidToLocalId: new Map(),
130
+ versionUidToSeedUid: new Map(),
131
+ relatedSeedUids: new Set(),
132
+ });
133
+ const isRelationPropertyName = (propertyNameSnake) => (propertyNameSnake.endsWith('_id') || propertyNameSnake.endsWith('_ids')) &&
134
+ propertyNameSnake !== 'storage_transaction_id' &&
135
+ propertyNameSnake !== 'storage_provider_transaction_id';
136
+ /**
137
+ * Seed UIDs that relation properties point at. Collected from every property the run fetched, not
138
+ * only newly stored ones, so related seeds are refreshed (new versions, revocations) on each sync.
139
+ */
140
+ const collectRelatedSeedUids = (properties, into) => {
141
+ for (const property of properties) {
142
+ const parsed = parseEasPropertyMetadata(property.decodedDataJson);
143
+ if (!parsed.ok)
144
+ continue;
145
+ const { name, value } = parsed.metadata;
146
+ if (!name || !isRelationPropertyName(name))
147
+ continue;
148
+ const values = Array.isArray(value) ? value : [value];
149
+ for (const v of values) {
150
+ if (typeof v === 'string' && v && !relationValuesToExclude.includes(v))
151
+ into.add(v);
152
+ }
153
+ }
154
+ };
155
+ /**
156
+ * Earlier syncs SQL-escaped a seed's attestation JSON (`'` -> `''`) and then bound it as a
157
+ * parameter, so stored `seeds.attestation_raw` had every quote doubled. Doubled JSON still parses,
158
+ * so a legacy row is recognized by comparing with the attestation EAS returns now: it is legacy
159
+ * when it equals that attestation with quotes doubled, ignoring the revocation fields (EAS may have
160
+ * revoked it since). A row whose data legitimately contains `''` equals the fresh JSON itself and is
161
+ * left alone.
162
+ */
163
+ const isSqlEscapedAttestationRaw = (stored, fresh) => {
164
+ if (!stored.includes("''"))
165
+ return false;
166
+ const freshJson = JSON.stringify(fresh);
167
+ if (stored === freshJson || !freshJson.includes("'"))
168
+ return false;
169
+ let parsed;
170
+ try {
171
+ parsed = JSON.parse(stored);
172
+ }
173
+ catch {
174
+ return false;
175
+ }
176
+ if (!parsed || typeof parsed !== 'object')
177
+ return false;
178
+ const stored_ = parsed;
179
+ const withStoredRevocation = {
180
+ ...fresh,
181
+ ...('revoked' in stored_ && { revoked: stored_.revoked }),
182
+ ...('revocationTime' in stored_ && { revocationTime: stored_.revocationTime }),
183
+ };
184
+ return stored === JSON.stringify(withStoredRevocation).replace(/'/g, "''");
185
+ };
186
+ const saveEasSeedsToDb = async ({ itemSeeds, state }) => {
187
+ const { seedUidToLocalId, seedUidToModelType } = state;
188
+ const appDb = BaseDb.getAppDb();
189
+ const seedUids = itemSeeds.map((seed) => seed.id);
190
+ const existingSeedRecordsRows = await selectInBatches(seedUids, (chunk) => appDb.select().from(seeds).where(inArray(seeds.uid, chunk)));
191
+ const existingSeedUids = new Set();
192
+ if (existingSeedRecordsRows && existingSeedRecordsRows.length > 0) {
193
+ for (const row of existingSeedRecordsRows) {
194
+ if (row.uid) {
195
+ existingSeedUids.add(row.uid);
196
+ if (row.localId) {
197
+ seedUidToLocalId.set(row.uid, row.localId);
198
+ }
199
+ if (row.type) {
200
+ seedUidToModelType.set(row.uid, row.type);
201
+ }
202
+ }
203
+ }
204
+ }
205
+ const newSeeds = itemSeeds.filter((seed) => !existingSeedUids.has(seed.id));
206
+ // Update existing seeds when attestations are revoked on EAS, and replace a local unpublish stamp
207
+ // with EAS's revocationTime once EAS reports one (see `syncedRevokedAt`).
208
+ const seedByUid = new Map(itemSeeds.map((s) => [s.id, s]));
209
+ for (const row of existingSeedRecordsRows) {
210
+ if (!row.uid || !row.localId)
211
+ continue;
212
+ const attestation = seedByUid.get(row.uid);
213
+ if (!attestation)
214
+ continue;
215
+ const revokedAt = syncedRevokedAt(attestation, row.revokedAt);
216
+ if (revokedAt == null || revokedAt === row.revokedAt)
217
+ continue;
218
+ await updateSeedRevokedAt({ seedLocalId: row.localId, revokedAt });
219
+ }
220
+ // Repair seed rows an earlier sync stored with SQL-escaped (doubled) quotes.
221
+ for (const row of existingSeedRecordsRows) {
222
+ if (!row.uid || !row.attestationRaw)
223
+ continue;
224
+ const attestation = seedByUid.get(row.uid);
225
+ if (!attestation || !isSqlEscapedAttestationRaw(row.attestationRaw, attestation))
226
+ continue;
227
+ await appDb
228
+ .update(seeds)
229
+ .set({ attestationRaw: JSON.stringify(attestation) })
230
+ .where(eq(seeds.uid, row.uid));
231
+ }
232
+ if (newSeeds.length === 0) {
233
+ return { seedUids };
234
+ }
235
+ const newSeedsData = [];
236
+ for (let i = 0; i < newSeeds.length; i++) {
237
+ const seed = newSeeds[i];
238
+ seedUidToModelType.set(seed.id, seed.schema.schemaNames[0].name);
239
+ const seedLocalId = generateId();
240
+ seedUidToLocalId.set(seed.id, seedLocalId);
241
+ // createSeeds binds parameters: store the JSON as is.
242
+ const attestationRaw = JSON.stringify(seed);
243
+ const revokedAt = revokedAtSeconds(seed);
244
+ // EAS only knows the model by name; the seam may match it to a local model (not built yet).
245
+ const modelFileId = await resolveModelForSyncedSeed({
246
+ seedUid: seed.id,
247
+ modelType: seed.schema.schemaNames[0].name,
248
+ schemaUid: seed.schemaId,
249
+ });
250
+ newSeedsData.push({
251
+ localId: seedLocalId,
252
+ uid: seed.id,
253
+ schemaUid: seed.schemaId,
254
+ type: seed.schema.schemaNames[0].name,
255
+ ...(modelFileId && { modelFileId }),
256
+ publisher: seed.attester ? normalizeHexAddress(seed.attester) : seed.attester,
257
+ createdAt: Date.now(),
258
+ attestationCreatedAt: seed.timeCreated * 1000,
259
+ attestationRaw,
260
+ ...(revokedAt !== undefined && { revokedAt }),
261
+ });
262
+ }
263
+ await createSeeds(newSeedsData);
264
+ // All fetched seeds, not only the new ones: existing seeds can have new versions on EAS.
265
+ return { seedUids };
266
+ };
267
+ /**
268
+ * Rows per versions INSERT. A row binds at most one parameter per `versions` column (12 today, 10
269
+ * set by sync), so a batch binds at most 600: under SQLite's old default limit of 999 host
270
+ * parameters (sqlite-wasm and libsql allow more). saveEasVersionsBatches.test.ts checks this.
271
+ */
272
+ const VERSION_INSERT_BATCH = 50;
273
+ const saveEasVersionsToDb = async ({ itemVersions, state }) => {
274
+ const { seedUidToLocalId, seedUidToModelType, versionUidToLocalId, versionUidToSeedUid } = state;
275
+ const versionUids = itemVersions.map((version) => version.id);
276
+ const appDb = BaseDb.getAppDb();
277
+ const existingVersionRecordsRows = await selectInBatches(versionUids, (chunk) => appDb.select().from(versions).where(inArray(versions.uid, chunk)));
278
+ const existingVersionUids = new Set();
279
+ const versionByUid = new Map(itemVersions.map((version) => [version.id, version]));
280
+ if (existingVersionRecordsRows && existingVersionRecordsRows.length > 0) {
281
+ for (const row of existingVersionRecordsRows) {
282
+ if (row.uid) {
283
+ existingVersionUids.add(row.uid);
284
+ if (row.localId) {
285
+ versionUidToLocalId.set(row.uid, row.localId);
286
+ }
287
+ if (row.seedUid) {
288
+ versionUidToSeedUid.set(row.uid, row.seedUid);
289
+ }
290
+ // Already-stored versions pick up revocations (and EAS's revocation time) too.
291
+ const attestation = versionByUid.get(row.uid);
292
+ const revokedAt = attestation ? syncedRevokedAt(attestation, row.revokedAt) : null;
293
+ if (attestation && revokedAt !== (row.revokedAt ?? null)) {
294
+ await appDb
295
+ .update(versions)
296
+ .set({ revokedAt, updatedAt: Date.now() })
297
+ .where(eq(versions.uid, row.uid));
298
+ }
299
+ }
300
+ }
301
+ }
302
+ const newVersions = itemVersions.filter((version) => !existingVersionUids.has(version.id));
303
+ const rows = [];
304
+ const storedVersionUids = new Set(existingVersionUids);
305
+ for (const version of newVersions) {
306
+ const seedUid = version.refUID;
307
+ const seedLocalId = seedUidToLocalId.get(seedUid);
308
+ if (!seedLocalId) {
309
+ // Storing it anyway would orphan the version (and its properties) from any local seed.
310
+ console.warn('[item/events] [syncDbWithEas] skipping version whose seed has no local id: ', version.id, seedUid);
311
+ continue;
312
+ }
313
+ const versionLocalId = generateId();
314
+ versionUidToSeedUid.set(version.id, seedUid);
315
+ versionUidToLocalId.set(version.id, versionLocalId);
316
+ storedVersionUids.add(version.id);
317
+ rows.push({
318
+ localId: versionLocalId,
319
+ uid: version.id,
320
+ seedUid,
321
+ seedLocalId,
322
+ seedType: seedUidToModelType.get(seedUid) ?? null,
323
+ createdAt: Date.now(),
324
+ attestationCreatedAt: version.timeCreated * 1000,
325
+ attestationRaw: JSON.stringify(version),
326
+ publisher: version.attester ? normalizeHexAddress(version.attester) : '',
327
+ revokedAt: revokedAtSeconds(version) ?? null,
328
+ });
329
+ }
330
+ // Bound parameters: keep each statement well under SQLite's host-parameter limit.
331
+ for (let i = 0; i < rows.length; i += VERSION_INSERT_BATCH) {
332
+ await appDb.insert(versions).values(rows.slice(i, i + VERSION_INSERT_BATCH));
333
+ }
334
+ // Only versions that are stored locally: properties of a skipped version would have no version row.
335
+ return { versionUids: versionUids.filter((uid) => storedVersionUids.has(uid)) };
336
+ };
337
+ const createMetadataRecordsForStorageTransactionId = async (storageTransactionIdProperty, modelSchema, state) => {
338
+ const { seedUidToLocalId, seedUidToModelType, versionUidToLocalId, versionUidToSeedUid } = state;
339
+ // Validate and parse decodedDataJson
340
+ const parsed = parseEasPropertyMetadata(storageTransactionIdProperty.decodedDataJson);
341
+ if (!parsed.ok) {
342
+ if (parsed.reason === 'empty') {
343
+ console.warn('[item/events] [syncDbWithEas] empty decodedDataJson for storageTransactionIdProperty: ', storageTransactionIdProperty.id);
344
+ }
345
+ else if (parsed.reason === 'parse') {
346
+ console.warn('[item/events] [syncDbWithEas] failed to parse decodedDataJson for storageTransactionIdProperty: ', storageTransactionIdProperty.id, parsed.error);
347
+ }
348
+ else {
349
+ console.warn('[item/events] [syncDbWithEas] invalid decodedDataJson structure for storageTransactionIdProperty: ', storageTransactionIdProperty.id);
350
+ }
351
+ return;
352
+ }
353
+ const attestationData = parsed.metadata;
354
+ camelCase(attestationData.name);
355
+ const propertyValue = typeof attestationData.value === 'string'
356
+ ? attestationData.value
357
+ : JSON.stringify(attestationData.value);
358
+ const seedUid = versionUidToSeedUid.get(storageTransactionIdProperty.refUID);
359
+ const seedLocalId = seedUidToLocalId.get(seedUid);
360
+ const versionUid = storageTransactionIdProperty.refUID;
361
+ const versionLocalId = versionUidToLocalId.get(versionUid);
362
+ const modelType = seedUidToModelType.get(seedUid);
363
+ // Storage settings come from the `properties` table. The model's property instances (modelSchema)
364
+ // are only a fallback: whether they have loaded, and with storage settings, depends on timing.
365
+ const itemStorageProperties = new Map();
366
+ if (modelType != null) {
367
+ const stored = (await skipSeedOnAmbiguousModel({ seedLocalId, seedUid }, 'easSync.storageTransactionId', async () => getItemStoragePropertiesForModel(modelType, {
368
+ modelFileId: await resolveItemModelFileId({ seedLocalId, seedUid }),
369
+ }))) ?? [];
370
+ for (const property of stored)
371
+ itemStorageProperties.set(property.name, property);
372
+ }
373
+ if (itemStorageProperties.size === 0 && modelSchema) {
374
+ for (const [_propertyName, propertyDef] of Object.entries(modelSchema)) {
375
+ if (propertyDef?.storageType === 'ItemStorage') {
376
+ itemStorageProperties.set(_propertyName, {
377
+ localStorageDir: propertyDef.localStorageDir,
378
+ filenameSuffix: propertyDef.filenameSuffix,
379
+ });
380
+ }
381
+ }
382
+ }
383
+ if (itemStorageProperties.size === 0) {
384
+ return;
385
+ }
386
+ const appDb = BaseDb.getAppDb();
387
+ for (const [_propertyName, propertyDef] of itemStorageProperties.entries()) {
388
+ const existingMetadataRecordRows = await appDb
389
+ .select({ localId: metadata.localId })
390
+ .from(metadata)
391
+ .where(and(isNotNull(metadata.derivedFromUid), eq(metadata.propertyName, _propertyName), eq(metadata.propertyValue, propertyValue), eq(metadata.versionUid, storageTransactionIdProperty.refUID)));
392
+ // Already derived from another attestation carrying this transaction id: syncDerivedStorageRows
393
+ // points that row at the canonical attestation.
394
+ if (existingMetadataRecordRows && existingMetadataRecordRows.length > 0) {
395
+ continue;
396
+ }
397
+ const propertyId = propertyDef.id ??
398
+ (modelType != null
399
+ ? ((await skipSeedOnAmbiguousModel({ seedLocalId, seedUid }, 'easSync.storageTransactionId', async () => getPropertyIdForModelAndName(modelType, _propertyName, {
400
+ modelFileId: await resolveItemModelFileId({ seedLocalId, seedUid }),
401
+ }))) ?? null)
402
+ : null);
403
+ const propertyLocalId = generateId();
404
+ await appDb.insert(metadata).values({
405
+ localId: propertyLocalId,
406
+ propertyId: propertyId ?? undefined,
407
+ propertyName: _propertyName,
408
+ propertyValue,
409
+ localStorageDir: propertyDef.localStorageDir ?? undefined,
410
+ seedLocalId,
411
+ seedUid,
412
+ versionLocalId,
413
+ versionUid,
414
+ refValueType: 'file',
415
+ refResolvedValue: `${propertyValue}${propertyDef.filenameSuffix ?? ''}`,
416
+ modelType: seedUidToModelType.get(seedUid),
417
+ derivedFromUid: storageTransactionIdProperty.id,
418
+ // Ranked like a synced row, at its attestation's time: a local edit made after that
419
+ // publish wins over it, a newer publish wins over an older edit.
420
+ attestationCreatedAt: storageTransactionIdProperty.timeCreated * 1000,
421
+ createdAt: Date.now(),
422
+ updatedAt: Date.now(),
423
+ });
424
+ }
425
+ };
426
+ /** Serialize property saves: concurrent `runSyncFromEas` used to hit `isSavingToDb` and return `{}` with no insert. */
427
+ let saveEasPropertiesDbChain = Promise.resolve();
428
+ /**
429
+ * Make local metadata match EAS for every fetched (version, property schema): exactly one synced
430
+ * row, for the canonical attestation (ADR 0006), with `revoked_at` set when that attestation is
431
+ * revoked (which, with `SYNC_CANONICAL_OPTIONS`, means all of the property's attestations on that
432
+ * version are).
433
+ *
434
+ * - Canonical attestation not stored yet: insert it. This also covers an older live attestation
435
+ * taking over from a revoked newer one, and a newer attestation superseding the stored one.
436
+ * - Stored row for a fetched attestation that isn't canonical (revoked, or superseded): delete it,
437
+ * so readers, which take the newest row per property, can't pick it.
438
+ * - Stored canonical row: bring `revoked_at` up to date.
439
+ *
440
+ * Rows without an attestation UID (local edits) and rows for attestations EAS didn't return are
441
+ * left alone.
442
+ */
443
+ const saveEasPropertiesToDbBody = async ({ fetchedProperties, itemSeeds, state, }) => {
444
+ const itemProperties = pickLatestPropertyAttestationsByRefAndSchema(fetchedProperties, SYNC_CANONICAL_OPTIONS);
445
+ const propertyUids = itemProperties.map((property) => property.id);
446
+ collectRelatedSeedUids(itemProperties, state.relatedSeedUids);
447
+ const appDb = BaseDb.getAppDb();
448
+ const storedRows = await selectInBatches(fetchedProperties.map((property) => property.id), (chunk) => appDb
449
+ .select({ uid: metadata.uid, revokedAt: metadata.revokedAt })
450
+ .from(metadata)
451
+ .where(inArray(metadata.uid, chunk)));
452
+ const canonicalByUid = new Map(itemProperties.map((property) => [property.id, property]));
453
+ const existingPropertyRecordsUids = new Set();
454
+ const staleUids = new Set();
455
+ const revokedAtUpdates = new Map();
456
+ for (const row of storedRows) {
457
+ if (!row.uid)
458
+ continue;
459
+ const canonical = canonicalByUid.get(row.uid);
460
+ if (!canonical) {
461
+ staleUids.add(row.uid);
462
+ continue;
463
+ }
464
+ existingPropertyRecordsUids.add(row.uid);
465
+ // Same policy as seeds and versions: a local unpublish stamp stays until EAS reports a
466
+ // revocationTime, even while EAS (its index lagging) still reports the attestation live.
467
+ const revokedAt = syncedRevokedAt(canonical, row.revokedAt);
468
+ if ((row.revokedAt ?? null) !== revokedAt) {
469
+ revokedAtUpdates.set(row.uid, revokedAt);
470
+ }
471
+ }
472
+ const newProperties = itemProperties.filter((property) => !existingPropertyRecordsUids.has(property.id));
473
+ // Insert before deleting, so a property never goes without a row in between.
474
+ if (newProperties.length > 0) {
475
+ await insertSyncedProperties({ newProperties, itemSeeds, state });
476
+ }
477
+ if (staleUids.size > 0) {
478
+ await writeInBatches([...staleUids], (chunk) => appDb.delete(metadata).where(inArray(metadata.uid, chunk)));
479
+ }
480
+ for (const [uid, revokedAt] of revokedAtUpdates) {
481
+ await appDb
482
+ .update(metadata)
483
+ .set({ revokedAt, updatedAt: Date.now() })
484
+ .where(eq(metadata.uid, uid));
485
+ }
486
+ await syncDerivedStorageRows({ fetchedProperties, canonicalProperties: itemProperties });
487
+ return { propertyUids };
488
+ };
489
+ /** The transaction id a `storage_transaction_id` attestation carries; undefined for other properties. */
490
+ const storageTransactionIdOf = (property) => {
491
+ const parsed = parseEasPropertyMetadata(property.decodedDataJson);
492
+ if (!parsed.ok || parsed.metadata.name !== 'storage_transaction_id')
493
+ return undefined;
494
+ const { value } = parsed.metadata;
495
+ // Same serialization as the derived rows' property_value.
496
+ return typeof value === 'string' ? value : JSON.stringify(value);
497
+ };
498
+ /**
499
+ * Make derived ItemStorage rows follow their `storage_transaction_id` attestation the way synced
500
+ * rows follow theirs. Derived rows are identified by `derived_from_uid`, the attestation they were
501
+ * derived from:
502
+ * - A row derived from another fetched attestation with the canonical one's transaction id (on the
503
+ * same version) is pointed at the canonical one; creation makes one row per transaction id.
504
+ * - Rows derived from a fetched attestation that isn't canonical are deleted.
505
+ * - Rows derived from the canonical one take its `revoked_at` once it has one (a stamp is never
506
+ * cleared, see `syncedRevokedAt`).
507
+ * Local drafts (no uid, no `derived_from_uid`) are never touched.
508
+ */
509
+ const syncDerivedStorageRows = async ({ fetchedProperties, canonicalProperties, }) => {
510
+ const canonical = canonicalProperties
511
+ .map((property) => ({ property, transactionId: storageTransactionIdOf(property) }))
512
+ .filter((c) => !!c.transactionId);
513
+ const canonicalUids = new Set(canonicalProperties.map((property) => property.id));
514
+ const appDb = BaseDb.getAppDb();
515
+ for (const { property, transactionId } of canonical) {
516
+ const sameTransaction = fetchedProperties
517
+ .filter((other) => other.id !== property.id &&
518
+ other.refUID === property.refUID &&
519
+ storageTransactionIdOf(other) === transactionId)
520
+ .map((other) => other.id);
521
+ if (sameTransaction.length === 0)
522
+ continue;
523
+ // A stamp belongs to the attestation it came from; the new source's is applied below.
524
+ await writeInBatches(sameTransaction, (chunk) => appDb
525
+ .update(metadata)
526
+ .set({
527
+ derivedFromUid: property.id,
528
+ revokedAt: null,
529
+ attestationCreatedAt: property.timeCreated * 1000,
530
+ updatedAt: Date.now(),
531
+ })
532
+ .where(inArray(metadata.derivedFromUid, chunk)));
533
+ }
534
+ const staleSourceUids = fetchedProperties
535
+ .filter((property) => !canonicalUids.has(property.id) && storageTransactionIdOf(property))
536
+ .map((property) => property.id);
537
+ if (staleSourceUids.length > 0) {
538
+ await writeInBatches(staleSourceUids, (chunk) => appDb.delete(metadata).where(inArray(metadata.derivedFromUid, chunk)));
539
+ }
540
+ if (canonical.length === 0)
541
+ return;
542
+ // The canonical rows' revoked_at as just stored (the saves above already applied EAS's state).
543
+ const sourceRows = await selectInBatches(canonical.map((c) => c.property.id), (chunk) => appDb
544
+ .select({ uid: metadata.uid, revokedAt: metadata.revokedAt })
545
+ .from(metadata)
546
+ .where(inArray(metadata.uid, chunk)));
547
+ const revokedAtByUid = new Map(sourceRows.map((row) => [row.uid, row.revokedAt ?? null]));
548
+ for (const { property } of canonical) {
549
+ const revokedAt = revokedAtByUid.get(property.id) ?? null;
550
+ // The source's revoked_at already follows `syncedRevokedAt`. A live source leaves a derived
551
+ // row's stamp alone: like a stamped synced row, it is only replaced by a revocation time.
552
+ if (revokedAt == null)
553
+ continue;
554
+ await appDb
555
+ .update(metadata)
556
+ .set({ revokedAt, updatedAt: Date.now() })
557
+ .where(and(eq(metadata.derivedFromUid, property.id), or(isNull(metadata.revokedAt), ne(metadata.revokedAt, revokedAt))));
558
+ }
559
+ };
560
+ /**
561
+ * The cached Model of a synced seed: its own model (seeds.model_file_id) when it has one, else by
562
+ * EAS schema name, the snake_case model name (`sync_storage_post` → SyncStoragePost; a
563
+ * `startCase` lookup never matched multi-word names). Throws AmbiguousModelError when several
564
+ * schemas define a model with that name; callers skip the seed (skipSeedOnAmbiguousModel).
565
+ */
566
+ const resolveSyncedSeedModel = async (Model, modelType, seed) => {
567
+ const modelFileId = await resolveItemModelFileId(seed);
568
+ return (modelFileId ? Model.getById(modelFileId) : undefined) ?? Model.findByModelType(modelType);
569
+ };
570
+ const insertSyncedProperties = async ({ newProperties, itemSeeds, state, }) => {
571
+ const { seedUidToLocalId, seedUidToModelType, versionUidToLocalId, versionUidToSeedUid } = state;
572
+ // Dynamic import to break circular dependency
573
+ const _mod_1 = await import('./index-Y-yYyRBf.js');
574
+ const _ns_1 = _mod_1.f;
575
+ const modelMod = _ns_1;
576
+ const { Model } = modelMod;
577
+ // Loads every model into Model's cache, where resolveSyncedSeedModel looks them up.
578
+ await Model.all();
579
+ const appDb = BaseDb.getAppDb();
580
+ // Bound as parameters, in batches of rowsPerInsert(metadata) rows, so no statement exceeds
581
+ // SQLite's parameter or statement-length limits however many properties a sync stores.
582
+ const rows = [];
583
+ for (const property of newProperties) {
584
+ const propertyLocalId = generateId();
585
+ // Validate and parse decodedDataJson
586
+ const parsed = parseEasPropertyMetadata(property.decodedDataJson);
587
+ if (!parsed.ok) {
588
+ if (parsed.reason === 'empty') {
589
+ console.warn('[item/events] [syncDbWithEas] empty decodedDataJson for property: ', property.id);
590
+ }
591
+ else if (parsed.reason === 'parse') {
592
+ console.warn('[item/events] [syncDbWithEas] failed to parse decodedDataJson for property: ', property.id, parsed.error);
593
+ }
594
+ else {
595
+ console.warn('[item/events] [syncDbWithEas] invalid decodedDataJson structure for property: ', property.id);
596
+ }
597
+ continue;
598
+ }
599
+ const propertyMetadata = parsed.metadata;
600
+ let propertyNameSnake = propertyMetadata.name;
601
+ if (!propertyNameSnake) {
602
+ console.warn('[item/events] [syncDbWithEas] no propertyName found for property: ', property);
603
+ continue;
604
+ }
605
+ let isRelation = false;
606
+ let refValueType;
607
+ let refSeedType;
608
+ let refSchemaUid;
609
+ let isList = false;
610
+ const schemaUid = property.schemaId;
611
+ setSchemaUidForSchemaDefinition({
612
+ text: propertyNameSnake,
613
+ schemaUid,
614
+ });
615
+ if (isRelationPropertyName(propertyNameSnake)) {
616
+ isRelation = true;
617
+ if (Array.isArray(propertyMetadata.value)) {
618
+ isList = true;
619
+ refValueType = 'list';
620
+ const result = parseEasRelationPropertyName(propertyNameSnake);
621
+ if (result) {
622
+ propertyNameSnake = result.propertyName;
623
+ refSeedType = result.modelName;
624
+ }
625
+ }
626
+ if (!isList) {
627
+ if (relationValuesToExclude.includes(propertyMetadata.value)) {
628
+ continue;
629
+ }
630
+ }
631
+ }
632
+ let propertyValue = propertyMetadata.value;
633
+ if (typeof propertyValue !== 'string') {
634
+ propertyValue = JSON.stringify(propertyValue);
635
+ }
636
+ if (isRelation && !isList) {
637
+ const relatedSeed = itemSeeds.find((seed) => seed.id === propertyMetadata.value);
638
+ if (relatedSeed && relatedSeed.schema && relatedSeed.schema.schemaNames) {
639
+ refSeedType = relatedSeed.schema.schemaNames[0].name;
640
+ refSchemaUid = relatedSeed.schemaId;
641
+ }
642
+ }
643
+ if (isRelation && isList) {
644
+ const relatedSeeds = itemSeeds.filter((seed) => propertyMetadata.value.includes(seed.id));
645
+ if (relatedSeeds && relatedSeeds.length > 0) {
646
+ refSeedType = relatedSeeds[0].schema.schemaNames[0].name;
647
+ refSchemaUid = relatedSeeds[0].schemaId;
648
+ }
649
+ }
650
+ const propertyName = camelCase(propertyNameSnake);
651
+ const easDataType = propertyMetadata.type;
652
+ const versionUid = property.refUID;
653
+ const versionLocalId = versionUidToLocalId.get(versionUid);
654
+ const attestationCreatedAt = property.timeCreated * 1000;
655
+ const seedUid = versionUidToSeedUid.get(versionUid);
656
+ const seedLocalId = seedUidToLocalId.get(seedUid);
657
+ const modelType = seedUidToModelType.get(seedUid);
658
+ const model = modelType != null
659
+ ? await skipSeedOnAmbiguousModel({ seedLocalId, seedUid }, 'easSync.metadata', async () => resolveSyncedSeedModel(Model, modelType, { seedLocalId, seedUid }))
660
+ : undefined;
661
+ const modelSchema = model?.properties ? modelPropertiesToObject(model.properties) : undefined;
662
+ if (propertyNameSnake === 'storage_transaction_id') {
663
+ await createMetadataRecordsForStorageTransactionId(property, modelSchema, state);
664
+ }
665
+ const propertyId = modelType != null
666
+ ? ((await skipSeedOnAmbiguousModel({ seedLocalId, seedUid }, 'easSync.metadata', async () => getPropertyIdForModelAndName(modelType, propertyName, {
667
+ // EAS identifies models by name only; a locally-created seed still knows its model.
668
+ modelFileId: await resolveItemModelFileId({ seedLocalId, seedUid }),
669
+ }))) ?? null)
670
+ : null;
671
+ rows.push({
672
+ localId: propertyLocalId,
673
+ uid: property.id,
674
+ schemaUid: property.schemaId,
675
+ propertyId,
676
+ propertyName,
677
+ propertyValue,
678
+ easDataType,
679
+ versionUid,
680
+ versionLocalId: versionLocalId ?? null,
681
+ seedUid: seedUid ?? null,
682
+ seedLocalId: seedLocalId ?? null,
683
+ modelType: modelType ?? null,
684
+ refValueType: refValueType || null,
685
+ refSeedType: refSeedType || null,
686
+ refModelUid: refSchemaUid || null,
687
+ createdAt: Date.now(),
688
+ attestationCreatedAt,
689
+ attestationRaw: JSON.stringify(property),
690
+ publisher: property.attester ? normalizeHexAddress(property.attester) : '',
691
+ revokedAt: revokedAtSeconds(property) ?? null,
692
+ });
693
+ }
694
+ // No conflict clause, as before: every row has a fresh local_id, and callers pass only
695
+ // attestations with no stored row.
696
+ const batchSize = rowsPerInsert(metadata);
697
+ for (let i = 0; i < rows.length; i += batchSize) {
698
+ await appDb.insert(metadata).values(rows.slice(i, i + batchSize));
699
+ }
700
+ };
701
+ const saveEasPropertiesToDb = (params) => {
702
+ const next = saveEasPropertiesDbChain.then(() => saveEasPropertiesToDbBody(params));
703
+ saveEasPropertiesDbChain = next.then(() => undefined, () => undefined);
704
+ return next;
705
+ };
706
+ /**
707
+ * Fetch every version of `seedUids` and every property attestation of those versions, and store
708
+ * them. The main sync and the related-seed fetch both go through here, so they treat revocation
709
+ * the same way: revoked attestations are fetched on purpose (`excludeRevoked: false`), revoked
710
+ * seeds record `revokedAt` (in `saveEasSeedsToDb`), and properties go through the canonical pick
711
+ * (newest non-revoked per version and property schema, see ADR 0006).
712
+ */
713
+ const syncVersionsAndPropertiesForSeeds = async ({ seedUids, itemSeeds, state, }) => {
714
+ if (seedUids.length === 0)
715
+ return;
716
+ const itemVersions = await getItemVersionsFromEas({
717
+ seedUids,
718
+ excludeRevoked: false,
719
+ });
720
+ const { versionUids } = await saveEasVersionsToDb({
721
+ itemVersions,
722
+ state,
723
+ });
724
+ if (versionUids.length === 0)
725
+ return;
726
+ const fetchedProperties = await getItemPropertiesFromEas({
727
+ versionUids,
728
+ excludeRevoked: false,
729
+ });
730
+ // The save makes the canonical pick; it also needs the other attestations to clean up after them.
731
+ await saveEasPropertiesToDb({
732
+ fetchedProperties,
733
+ itemSeeds,
734
+ state,
735
+ });
736
+ };
737
+ /**
738
+ * Relation targets of synced properties, fetched by id from any attester (one level deep).
739
+ *
740
+ * This deliberately matches the main sync instead of filtering out revoked attestations: a
741
+ * relation to an unpublished seed should still resolve locally, to the seed's last values next to
742
+ * its `revokedAt`, exactly as if that seed had been synced in its own right. Filtering at the query
743
+ * would also break the canonical pick, which needs the revoked attestations to skip them (or to
744
+ * keep the newest one when all are revoked), and would leave `seeds.revoked_at` unset.
745
+ */
746
+ const getRelatedSeedsAndVersions = async (state) => {
747
+ // Snapshot: relations found on the related seeds themselves aren't followed (one level deep).
748
+ const uids = Array.from(state.relatedSeedUids);
749
+ if (uids.length === 0)
750
+ return;
751
+ const easClient = BaseEasClient.getEasClient();
752
+ // No `revoked` filter, like `getSeedsFromSchemaUids({ excludeRevoked: false })` in the main sync.
753
+ const { itemSeeds } = await easClient.request(GET_SEEDS, {
754
+ where: {
755
+ id: {
756
+ in: uids,
757
+ },
758
+ },
759
+ });
760
+ const { seedUids } = await saveEasSeedsToDb({ itemSeeds, state });
761
+ // Only seeds EAS returned: a version of an unknown seed would be stored without its seed.
762
+ await syncVersionsAndPropertiesForSeeds({ seedUids, itemSeeds, state });
763
+ };
764
+ /**
765
+ * Core sync logic: fetches item attestations from EAS for configured models and given addresses,
766
+ * then saves seeds, versions, and properties to the local DB.
767
+ * Uses owned + watched addresses from DB when addresses are not provided.
768
+ */
769
+ const runSyncFromEas = async (options) => {
770
+ let addresses = options?.addresses ?? (await getAllAddressesFromDb());
771
+ const additionalGetter = getGetAdditionalSyncAddresses();
772
+ if (additionalGetter) {
773
+ const additional = await additionalGetter();
774
+ if (additional?.length) {
775
+ const seen = new Set(addresses.map((a) => a.toLowerCase()));
776
+ for (const addr of additional) {
777
+ if (addr && !seen.has(addr.toLowerCase())) {
778
+ seen.add(addr.toLowerCase());
779
+ addresses = [...addresses, addr];
780
+ }
781
+ }
782
+ }
783
+ }
784
+ if (!addresses || addresses.length === 0) {
785
+ return;
786
+ }
787
+ // Don't read the default chain while publish is about to configure another one.
788
+ await waitForEasReadChain();
789
+ // Never mix attestations from two chains in one local DB.
790
+ await assertLocalDbChain();
791
+ const appDb = BaseDb.getAppDb();
792
+ const { schemaStringToModelRecord } = await getModelSchemas();
793
+ const modelSchemas = await getModelSchemasFromEas();
794
+ const schemaUids = [];
795
+ for (const modelSchema of modelSchemas) {
796
+ const foundModel = schemaStringToModelRecord.get(modelSchema.schema);
797
+ if (!foundModel) {
798
+ // Skip schemas that don't have a corresponding model in the user's config
799
+ // This can happen with "bytes32 image" if there's no Image model defined
800
+ console.warn(`[item/events] [syncDbWithEas] Model not found for schema ${modelSchema.schema}, skipping`);
801
+ continue;
802
+ }
803
+ try {
804
+ await appDb
805
+ .insert(modelUids)
806
+ .values({
807
+ modelId: foundModel.id,
808
+ uid: modelSchema.id,
809
+ })
810
+ .onConflictDoNothing();
811
+ }
812
+ catch (err) {
813
+ // Model may have been deleted by test teardown or another process; skip to avoid unhandled rejection
814
+ const e = err;
815
+ const code = e?.code ?? e?.rawCode ?? e?.cause?.code ?? e?.cause?.rawCode;
816
+ if (code === 'SQLITE_CONSTRAINT_FOREIGNKEY' || code === 787) {
817
+ continue;
818
+ }
819
+ throw err;
820
+ }
821
+ schemaUids.push(modelSchema.id);
822
+ }
823
+ // If no schemas were found, skip the rest of the sync process
824
+ // This can happen when models exist but don't have schemas registered in EAS yet
825
+ if (schemaUids.length === 0) {
826
+ return;
827
+ }
828
+ const itemSeeds = await getSeedsFromSchemaUids({
829
+ schemaUids,
830
+ addresses,
831
+ excludeRevoked: false,
832
+ });
833
+ const state = createSyncRunState();
834
+ const { seedUids } = await saveEasSeedsToDb({
835
+ itemSeeds,
836
+ state,
837
+ });
838
+ await syncVersionsAndPropertiesForSeeds({ seedUids, itemSeeds, state });
839
+ await getRelatedSeedsAndVersions(state);
840
+ scheduleBulkFilesDownloadFromEasSync(addresses);
841
+ try {
842
+ const _mod_2 = await import('./Item-ZUAmf943.js');
843
+ const _ns_2 = _mod_2.Z;
844
+ const itemMod = _ns_2;
845
+ await itemMod.Item.rehydrateCachedItemsFromDbAfterEasSync();
846
+ }
847
+ catch (err) {
848
+ console.warn('[item/events] [syncDbWithEas] rehydrateCachedItemsFromDbAfterEasSync:', err);
849
+ }
850
+ // Other tabs reload their cached Items too (docs/MULTI_TAB.md).
851
+ emitAcrossTabs(EAS_SEED_DATA_SYNCED_TO_DB_EVENT);
852
+ };
853
+
854
+ export { VERSION_INSERT_BATCH, isSqlEscapedAttestationRaw, runSyncFromEas };
855
+ //# sourceMappingURL=syncDbWithEas-BPap9Sru.js.map