@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
@@ -1,15 +1,32 @@
1
1
  import { fromCallback, fromPromise, setup, assign, createActor } from 'xstate';
2
- import { a as BaseDb, m as models, p as properties, J as isInternalSchema, i as modelSchemas, s as schemas } from './BasePathResolver-B6CKqoKw.js';
3
- import { eq, or } from 'drizzle-orm';
4
- import './index-280bL-n4.js';
2
+ import { B as BaseDb, j as models, p as properties, K as isInternalSchema, g as modelSchemas, s as schemas } from './BasePathResolver-DRT09oVv.js';
3
+ import { eq, and, isNull, or } from 'drizzle-orm';
4
+ import './tabEvents-C6NXS6Jl.js';
5
5
  import debug from 'debug';
6
6
  import { generateId } from './generateId-BopUwD8F.js';
7
- import { y as writeModelToDb, z as writePropertyToDb, A as addSchemaToDb, C as renameModelInDb, d as TProperty } from './db-WbrzEf7c.js';
8
- import { n as waitForEntityIdle, af as getInvariantSafePropertyDescriptor, q as findEntity, H as getClient, y as ClientManagerState, I as Item, ag as unloadEntity, ah as clearDestroySubscriptions, u as forceRemoveFromCaches, v as runDestroyLifecycle } from './ClientManager-ChcmUL47.js';
7
+ import { G as writeModelToDb, K as writePropertyToDb, O as addSchemaToDb, A as AmbiguousModelError, Q as renameModelInDb, d as TProperty } from './db-Lw0KVZmc.js';
8
+ import { j as waitForEntityIdle, T as getInvariantSafePropertyDescriptor, m as findEntity, C as ClientManagerState, I as Item, U as clearDestroySubscriptions, n as forceRemoveFromCaches, V as unloadEntity, o as runDestroyLifecycle } from './Item-ZUAmf943.js';
9
+ import { h as getClient } from './ClientManager-DngaZdw6.js';
9
10
  import { modelPropertiesToObject } from './model-DGMe-TTm.js';
10
11
  import { toSnakeCase } from 'drizzle-orm/casing';
11
12
  import { Type } from '@sinclair/typebox';
12
13
 
14
+ /**
15
+ * Common getters and utilities for entity classes
16
+ * These work with any entity that has a getService() method returning an XState actor
17
+ */
18
+ /**
19
+ * Get the current state value from an entity's service
20
+ */
21
+ /**
22
+ * Whether an actor has been stopped (unload, destroy, or Schema eviction). Async work started by an
23
+ * entity (DB lookups, retry timers) must check this before sending, since a stopped actor ignores
24
+ * events and XState warns about every one of them.
25
+ */
26
+ function isActorStopped(actor) {
27
+ return actor.getSnapshot().status === 'stopped';
28
+ }
29
+
13
30
  const logger$7 = debug('seedSdk:model:actors:loadOrCreateModel');
14
31
  /**
15
32
  * Create ModelProperty instances for all property IDs to ensure they're cached
@@ -21,7 +38,7 @@ const createPropertyInstances = async (propertyFileIds) => {
21
38
  return;
22
39
  }
23
40
  try {
24
- const mod = await import('./ModelProperty-D79uV42p.js');
41
+ const mod = await import('./ModelProperty-6llK4MTH.js');
25
42
  const ModelProperty = mod?.ModelProperty ?? mod?.default;
26
43
  if (!ModelProperty) {
27
44
  logger$7('createPropertyInstances: ModelProperty not available from dynamic import');
@@ -52,7 +69,7 @@ const createPropertyInstances = async (propertyFileIds) => {
52
69
  // Don't throw - this is best-effort to pre-populate cache
53
70
  }
54
71
  };
55
- const loadOrCreateModel = fromCallback(({ sendBack, input: { context } }) => {
72
+ const loadOrCreateModel = fromCallback(({ sendBack, input: { context }, self }) => {
56
73
  const _loadOrCreateModel = async () => {
57
74
  const { modelName, schemaName, id, _idFromSchema } = context; // id is now the schemaFileId (string)
58
75
  if (!modelName || !schemaName) {
@@ -85,11 +102,40 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context } }) => {
85
102
  // But if we have a schemaFileId and the model found by name has a different schemaFileId,
86
103
  // don't use it - we're creating a new model from a schema file with a specific ID
87
104
  if (!modelRecord) {
88
- const dbModels = await db
89
- .select()
105
+ // Model names are only unique per schema: prefer this schema's row, and otherwise only
106
+ // consider same-name rows that no schema claims yet (never another schema's model).
107
+ const _mod_0 = await import('./BasePathResolver-DRT09oVv.js');
108
+ const _ns_0 = _mod_0.R;
109
+ const { modelSchemas } = _ns_0;
110
+ const _mod_1 = await import('./BasePathResolver-DRT09oVv.js');
111
+ const _ns_1 = _mod_1.Q;
112
+ const { schemas: schemasTable } = _ns_1;
113
+ let dbModels = await db
114
+ .select({
115
+ id: models.id,
116
+ name: models.name,
117
+ schemaFileId: models.schemaFileId,
118
+ isEdited: models.isEdited,
119
+ })
90
120
  .from(models)
91
- .where(eq(models.name, modelName))
121
+ .innerJoin(modelSchemas, eq(models.id, modelSchemas.modelId))
122
+ .innerJoin(schemasTable, eq(modelSchemas.schemaId, schemasTable.id))
123
+ .where(and(eq(models.name, modelName), eq(schemasTable.name, schemaName)))
92
124
  .limit(1);
125
+ if (dbModels.length === 0) {
126
+ dbModels = await db
127
+ .select({
128
+ id: models.id,
129
+ name: models.name,
130
+ schemaFileId: models.schemaFileId,
131
+ isEdited: models.isEdited,
132
+ })
133
+ .from(models)
134
+ .leftJoin(modelSchemas, eq(models.id, modelSchemas.modelId))
135
+ // Stubs only: an unlinked row with a schemaFileId is a deleted schema's leftover, not ours
136
+ .where(and(eq(models.name, modelName), isNull(modelSchemas.id), isNull(models.schemaFileId)))
137
+ .limit(1);
138
+ }
93
139
  if (dbModels.length > 0) {
94
140
  const foundModel = dbModels[0];
95
141
  const dbSchemaFileId = foundModel.schemaFileId;
@@ -98,7 +144,9 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context } }) => {
98
144
  // This handles the case where Model.create was called with a generated ID, but the model
99
145
  // already exists in the database with a different ID. By updating the current instance's
100
146
  // schemaFileId to match the database, both will point to the same cached instance.
101
- if (dbSchemaFileId) {
147
+ // Skip for schema models (_idFromSchema): their id is authoritative, and a same-name row
148
+ // with a different id belongs to another schema (e.g. two schemas that each define "Post").
149
+ if (dbSchemaFileId && !(_idFromSchema && schemaFileId && schemaFileId !== dbSchemaFileId)) {
102
150
  try {
103
151
  const modelMod = await Promise.resolve().then(function () { return Model$1; });
104
152
  const { Model } = modelMod;
@@ -164,7 +212,9 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context } }) => {
164
212
  .map((record) => record.schemaFileId)
165
213
  .filter((id) => id !== null && id !== undefined);
166
214
  if (propertyFileIds.length > 0) {
167
- await createPropertyInstances(propertyFileIds);
215
+ // Not for a model stopped meanwhile (unloaded, or evicted with its schema)
216
+ if (!isActorStopped(self))
217
+ await createPropertyInstances(propertyFileIds);
168
218
  }
169
219
  // Generate schemaFileId if not set
170
220
  if (!schemaFileId) {
@@ -205,10 +255,13 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context } }) => {
205
255
  // Step 2: Fallback to Schema context (only if database doesn't have the model)
206
256
  // This handles the case where model exists in schema file but not yet in database
207
257
  try {
208
- const _mod_0 = await import('./Schema-a8uO-hIZ.js');
209
- const _ns_0 = _mod_0.b;
210
- const schemaMod = _ns_0;
258
+ const _mod_2 = await import('./Schema-D-Ud-XYw.js');
259
+ const _ns_2 = _mod_2.b;
260
+ const schemaMod = _ns_2;
211
261
  const { Schema } = schemaMod;
262
+ // Stopped meanwhile (unloaded, or evicted with its schema): don't load the schema again
263
+ if (isActorStopped(self))
264
+ return;
212
265
  const schema = Schema.create(schemaName, { waitForReady: false });
213
266
  const schemaSnapshot = schema.getService().getSnapshot();
214
267
  // Wait for schema to load if it's still loading
@@ -353,13 +406,13 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context } }) => {
353
406
  }
354
407
  // Also check database for models (in case they're persisted but not in Schema context)
355
408
  if (db) {
356
- const _mod_1 = await import('./BasePathResolver-B6CKqoKw.js');
357
- const _ns_1 = _mod_1.Q;
358
- const modelSchemaSchemaMod = _ns_1;
409
+ const _mod_3 = await import('./BasePathResolver-DRT09oVv.js');
410
+ const _ns_3 = _mod_3.R;
411
+ const modelSchemaSchemaMod = _ns_3;
359
412
  const { modelSchemas } = modelSchemaSchemaMod;
360
- const _mod_2 = await import('./BasePathResolver-B6CKqoKw.js');
361
- const _ns_2 = _mod_2.O;
362
- const schemaSchemaMod = _ns_2;
413
+ const _mod_4 = await import('./BasePathResolver-DRT09oVv.js');
414
+ const _ns_4 = _mod_4.Q;
415
+ const schemaSchemaMod = _ns_4;
363
416
  const { schemas: schemasTable } = schemaSchemaMod;
364
417
  // Query all models for this schema to check for duplicates (case-insensitive)
365
418
  logger$7(`Checking database for duplicate model names in schema "${schemaName}"`);
@@ -453,12 +506,14 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context } }) => {
453
506
  }
454
507
  // Mark schema as draft when a new model is created so saveNewVersion() can persist it
455
508
  try {
456
- const _mod_3 = await import('./Schema-a8uO-hIZ.js');
457
- const _ns_3 = _mod_3.b;
458
- const schemaMod = _ns_3;
509
+ const _mod_5 = await import('./Schema-D-Ud-XYw.js');
510
+ const _ns_5 = _mod_5.b;
511
+ const schemaMod = _ns_5;
459
512
  const { Schema } = schemaMod;
460
- const schema = Schema.create(schemaName, { waitForReady: false });
461
- schema.getService().send({ type: 'markAsDraft', propertyKey: 'schema:models' });
513
+ if (!isActorStopped(self)) {
514
+ const schema = Schema.create(schemaName, { waitForReady: false });
515
+ schema.getService().send({ type: 'markAsDraft', propertyKey: 'schema:models' });
516
+ }
462
517
  }
463
518
  catch (err) {
464
519
  logger$7(`Failed to mark schema as draft after creating model: ${err}`);
@@ -479,7 +534,7 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context } }) => {
479
534
  const logger$6 = debug('seedSdk:model:actors:validateModel');
480
535
  // Validation timeout in milliseconds (10 seconds)
481
536
  const VALIDATION_TIMEOUT_MS = 10000;
482
- const validateModel = fromCallback(({ sendBack, input: { context } }) => {
537
+ const validateModel = fromCallback(({ sendBack, input: { context }, self }) => {
483
538
  let hasResponded = false;
484
539
  // Timeout handler to ensure we always respond
485
540
  const timeoutId = setTimeout(() => {
@@ -499,12 +554,12 @@ const validateModel = fromCallback(({ sendBack, input: { context } }) => {
499
554
  const _validateModel = async () => {
500
555
  try {
501
556
  // Use dynamic imports to break circular dependencies
502
- const validationServiceMod = await import('./SchemaValidationService-Y49vqast.js');
557
+ const validationServiceMod = await import('./SchemaValidationService-IoS7JquP.js');
503
558
  const { SchemaValidationService } = validationServiceMod;
504
559
  const validationService = new SchemaValidationService();
505
- const _mod_4 = await import('./Schema-a8uO-hIZ.js');
506
- const _ns_4 = _mod_4.b;
507
- const schemaMod = _ns_4;
560
+ const _mod_6 = await import('./Schema-D-Ud-XYw.js');
561
+ const _ns_6 = _mod_6.b;
562
+ const schemaMod = _ns_6;
508
563
  const { Schema } = schemaMod;
509
564
  // Validate model structure
510
565
  const structureResult = validationService.validateModelStructure(context);
@@ -519,6 +574,9 @@ const validateModel = fromCallback(({ sendBack, input: { context } }) => {
519
574
  // If we have schema name, validate against schema
520
575
  // CRITICAL: Use validateModelAgainstSchema which doesn't require the model to be in schema context
521
576
  // This allows validation BEFORE registration, preventing update loops
577
+ // Stopped meanwhile (unloaded, or evicted with its schema): don't load the schema again
578
+ if (isActorStopped(self))
579
+ return;
522
580
  if (context.schemaName) {
523
581
  try {
524
582
  const schema = Schema.create(context.schemaName, {
@@ -601,10 +659,14 @@ const validateModel = fromCallback(({ sendBack, input: { context } }) => {
601
659
  });
602
660
 
603
661
  const logger$5 = debug('seedSdk:model:actors:createModelProperties');
604
- const createModelProperties = fromCallback(({ sendBack, input }) => {
662
+ const createModelProperties = fromCallback(({ sendBack, input, self }) => {
663
+ // The model was stopped (unloaded, or evicted with its schema by Schema.destroy / test cleanup) while
664
+ // this ran: stopping it stops this actor too, but can't cancel the awaits below. A stopped model
665
+ // creates no properties (they'd be cached for a model that's gone, and write rows under it).
666
+ const stopped = () => isActorStopped(self);
605
667
  const _createProperties = async () => {
606
668
  const { context, propertyDefinitions } = input;
607
- const { id, _dbId, modelName } = context;
669
+ const { id, _dbId, modelName, schemaName } = context;
608
670
  if (!id || !_dbId || !modelName) {
609
671
  throw new Error('Model ID, file ID, and name are required to create properties');
610
672
  }
@@ -614,7 +676,7 @@ const createModelProperties = fromCallback(({ sendBack, input }) => {
614
676
  return;
615
677
  }
616
678
  logger$5(`Creating ${Object.keys(propertyDefinitions).length} properties for model "${modelName}" (id: ${_dbId})`);
617
- const mod = await import('./ModelProperty-D79uV42p.js');
679
+ const mod = await import('./ModelProperty-6llK4MTH.js');
618
680
  const ModelProperty = mod?.ModelProperty ?? mod?.default;
619
681
  if (!ModelProperty) {
620
682
  logger$5('ModelProperty not available from dynamic import');
@@ -622,13 +684,25 @@ const createModelProperties = fromCallback(({ sendBack, input }) => {
622
684
  return;
623
685
  }
624
686
  const drizzleMod = await import('drizzle-orm');
625
- const { eq } = drizzleMod;
687
+ const { and, eq } = drizzleMod;
626
688
  const db = BaseDb.getAppDb();
627
689
  for (const [propName, propData] of Object.entries(propertyDefinitions)) {
628
- // Use provided ID or generate a random one
690
+ // The model's own write (writeModelToDb) normally stored this property already, under
691
+ // propData.id or an id it generated. Reuse that row so the instance gets the same id
692
+ // and doesn't write the property a second time.
693
+ const propertyRecord = db
694
+ ? (await db
695
+ .select()
696
+ .from(properties)
697
+ .where(propData.id
698
+ ? eq(properties.schemaFileId, propData.id)
699
+ : and(eq(properties.modelId, _dbId), eq(properties.name, propName)))
700
+ .limit(1))[0]
701
+ : undefined;
702
+ // Otherwise use provided ID or generate a random one
629
703
  // IDs should be generated in the import process before creating properties
630
704
  const { generateId } = await import('./generateId-BopUwD8F.js');
631
- const propertyFileId = propData.id || generateId();
705
+ const propertyFileId = propData.id || propertyRecord?.schemaFileId || generateId();
632
706
  logger$5(`Creating property "${propName}" with fileId "${propertyFileId}"`);
633
707
  // Query database to get refModelId if the property has ref/refModelName
634
708
  // The property should already be in DB from addModelsToDb
@@ -637,24 +711,18 @@ const createModelProperties = fromCallback(({ sendBack, input }) => {
637
711
  try {
638
712
  const refModelName = propData.refModelName || propData.ref;
639
713
  // First try to get refModelId from the property record in the database
640
- const propertyRecords = await db
641
- .select()
642
- .from(properties)
643
- .where(eq(properties.schemaFileId, propertyFileId))
644
- .limit(1);
645
- if (propertyRecords.length > 0 && propertyRecords[0].refModelId) {
646
- refModelId = propertyRecords[0].refModelId;
714
+ if (propertyRecord?.refModelId) {
715
+ refModelId = propertyRecord.refModelId;
647
716
  logger$5(`Found refModelId ${refModelId} from database for property "${propName}"`);
648
717
  }
649
718
  else if (refModelName) {
650
- // Fallback: query models table directly by name
651
- const refModelRecords = await db
652
- .select()
653
- .from(models)
654
- .where(eq(models.name, refModelName))
655
- .limit(1);
656
- if (refModelRecords.length > 0 && refModelRecords[0].id) {
657
- refModelId = refModelRecords[0].id;
719
+ // Fallback: resolve the ref by name within this model's schema
720
+ const _mod_7 = await import('./db-Lw0KVZmc.js');
721
+ const _ns_7 = _mod_7.Y;
722
+ const { resolveModelRecord } = _ns_7;
723
+ const refModelRecord = await resolveModelRecord(refModelName, { schemaName }, db);
724
+ if (refModelRecord?.id) {
725
+ refModelId = refModelRecord.id;
658
726
  logger$5(`Resolved refModelId ${refModelId} from model name "${refModelName}" for property "${propName}"`);
659
727
  }
660
728
  }
@@ -664,6 +732,10 @@ const createModelProperties = fromCallback(({ sendBack, input }) => {
664
732
  // Continue without refModelId - it will be resolved later in _initializeOriginalValues
665
733
  }
666
734
  }
735
+ if (stopped()) {
736
+ logger$5(`Model "${modelName}" was stopped while creating its properties; not creating the rest`);
737
+ return;
738
+ }
667
739
  // Create ModelProperty instance
668
740
  // This will load from DB if it exists, or create new instance
669
741
  // The property should already be in DB from writeModelToDb
@@ -678,12 +750,14 @@ const createModelProperties = fromCallback(({ sendBack, input }) => {
678
750
  refModelName: propData.refModelName,
679
751
  refModelId,
680
752
  refValueType: propData.refValueType,
681
- storageType: propData.storageType,
682
- localStorageDir: propData.localStorageDir,
683
- filenameSuffix: propData.filenameSuffix,
753
+ // Definitions built from DB rows may lack storage settings; the row has them.
754
+ storageType: propData.storageType ?? propertyRecord?.storageType ?? undefined,
755
+ localStorageDir: propData.localStorageDir ?? propertyRecord?.localStorageDir ?? undefined,
756
+ filenameSuffix: propData.filenameSuffix ?? propertyRecord?.filenameSuffix ?? undefined,
684
757
  required: propData.required,
685
758
  _propertyFileId: propertyFileId, // Store schemaFileId for getById() lookups
686
- }); // Use 'as any' because _propertyFileId is not in TProperty type
759
+ _dbId: propertyRecord?.schemaFileId === propertyFileId ? propertyRecord.id : undefined, // Already persisted: skip the write
760
+ }, { schemaName }); // Use 'as any' because _propertyFileId is not in TProperty type
687
761
  }
688
762
  logger$5(`Successfully created all properties for model "${modelName}"`);
689
763
  sendBack({ type: 'createModelPropertiesSuccess' });
@@ -700,6 +774,37 @@ const createModelProperties = fromCallback(({ sendBack, input }) => {
700
774
  };
701
775
  });
702
776
 
777
+ /**
778
+ * Eviction epochs: lets work that was started before a schema's Model/ModelProperty instances were
779
+ * evicted (Schema.destroy, test cleanup) tell, when it finishes, that it must not put instances for
780
+ * that schema back in the caches. Stopping the evicted actors can't cancel such work (a DB lookup
781
+ * that ends in Model.create, a model's property creation), and finishing it after the eviction would
782
+ * rebuild instances from rows that are about to be deleted, which then write themselves again.
783
+ *
784
+ * Capture `currentEvictionEpoch()` when the work starts; before creating or caching an instance, skip
785
+ * it when `schemaEvictedSince(schemaName, epoch)`. Work started after an eviction is unaffected.
786
+ */
787
+ let epoch = 0;
788
+ const lastEvictionBySchema = new Map();
789
+ function currentEvictionEpoch() {
790
+ return epoch;
791
+ }
792
+ /** Called by Model.evictForSchema. */
793
+ function recordSchemaEviction(schemaName) {
794
+ epoch += 1;
795
+ lastEvictionBySchema.set(schemaName, epoch);
796
+ }
797
+ /** True when the schema's instances were evicted after `since` (an epoch from currentEvictionEpoch). */
798
+ function schemaEvictedSince(schemaName, since) {
799
+ if (epoch === since || !schemaName)
800
+ return false;
801
+ return (lastEvictionBySchema.get(schemaName) ?? 0) > since;
802
+ }
803
+ /** True when any schema was evicted after `since` (cheap check before looking up which schemas apply). */
804
+ function anyEvictionSince(since) {
805
+ return epoch !== since;
806
+ }
807
+
703
808
  const logger$4 = debug('seedSdk:write:validateEntity');
704
809
  // XState v5 type inference bug: fromPromise types are inverted
705
810
  // We use type assertion to work around this
@@ -707,6 +812,20 @@ const validateEntity = fromPromise(async ({ input }) => {
707
812
  // Type assertion to fix XState v5 type inference bug
708
813
  // Convert through unknown to avoid type overlap error
709
814
  const entityInput = input;
815
+ // Validation awaits imports before looking up the schema; the entity can be evicted with its
816
+ // schema meanwhile (Schema.destroy, test cleanup). Schema.create would then load the evicted
817
+ // schema again, and its load re-creates the schema's models from rows being deleted.
818
+ const evictionEpoch = currentEvictionEpoch();
819
+ /** The schema to validate against; throws (validation then skips the schema check) once it was evicted. */
820
+ const schemaForValidation = async (schemaName) => {
821
+ const _mod_8 = await import('./Schema-D-Ud-XYw.js');
822
+ const _ns_8 = _mod_8.b;
823
+ const { Schema } = _ns_8;
824
+ if (schemaEvictedSince(schemaName, evictionEpoch)) {
825
+ throw new Error(`Schema "${schemaName}" was evicted during validation`);
826
+ }
827
+ return Schema.create(schemaName, { waitForReady: false });
828
+ };
710
829
  const _validate = async () => {
711
830
  try {
712
831
  const msg = `[validateEntity] Starting validation for ${entityInput.entityType}`;
@@ -717,7 +836,7 @@ const validateEntity = fromPromise(async ({ input }) => {
717
836
  const structureMsg = `[validateEntity] Validating model structure`;
718
837
  logger$4(structureMsg);
719
838
  // Use existing Model validation
720
- const validationServiceMod = await import('./SchemaValidationService-Y49vqast.js');
839
+ const validationServiceMod = await import('./SchemaValidationService-IoS7JquP.js');
721
840
  const { SchemaValidationService } = validationServiceMod;
722
841
  const validationService = new SchemaValidationService();
723
842
  // Validate model structure
@@ -735,13 +854,7 @@ const validateEntity = fromPromise(async ({ input }) => {
735
854
  if (entityInput.entityData.schemaName) {
736
855
  try {
737
856
  logger$4(`[validateEntity] Validating model against schema "${entityInput.entityData.schemaName}"`);
738
- const _mod_5 = await import('./Schema-a8uO-hIZ.js');
739
- const _ns_5 = _mod_5.b;
740
- const schemaMod = _ns_5;
741
- const { Schema } = schemaMod;
742
- const schema = Schema.create(entityInput.entityData.schemaName, {
743
- waitForReady: false,
744
- });
857
+ const schema = await schemaForValidation(entityInput.entityData.schemaName);
745
858
  const schemaSnapshot = schema.getService().getSnapshot();
746
859
  const schemaStatus = schemaSnapshot.value;
747
860
  logger$4(`[validateEntity] Schema status: ${schemaStatus}`);
@@ -773,7 +886,7 @@ const validateEntity = fromPromise(async ({ input }) => {
773
886
  }
774
887
  else if (entityInput.entityType === 'modelProperty') {
775
888
  // Use existing ModelProperty validation
776
- const validationServiceMod = await import('./SchemaValidationService-Y49vqast.js');
889
+ const validationServiceMod = await import('./SchemaValidationService-IoS7JquP.js');
777
890
  const { SchemaValidationService } = validationServiceMod;
778
891
  const validationService = new SchemaValidationService();
779
892
  // Validate property structure
@@ -788,13 +901,7 @@ const validateEntity = fromPromise(async ({ input }) => {
788
901
  // If schema name and model name provided, validate against schema
789
902
  if (entityInput.entityData._schemaName && entityInput.entityData.modelName) {
790
903
  try {
791
- const _mod_6 = await import('./Schema-a8uO-hIZ.js');
792
- const _ns_6 = _mod_6.b;
793
- const schemaMod = _ns_6;
794
- const { Schema } = schemaMod;
795
- const schema = Schema.create(entityInput.entityData._schemaName, {
796
- waitForReady: false,
797
- });
904
+ const schema = await schemaForValidation(entityInput.entityData._schemaName);
798
905
  const schemaSnapshot = schema.getService().getSnapshot();
799
906
  const schemaStatus = schemaSnapshot.value;
800
907
  if (schemaStatus === 'idle') {
@@ -819,7 +926,7 @@ const validateEntity = fromPromise(async ({ input }) => {
819
926
  }
820
927
  else if (entityInput.entityType === 'schema') {
821
928
  // Schema validation - use existing validation
822
- const validationServiceMod = await import('./SchemaValidationService-Y49vqast.js');
929
+ const validationServiceMod = await import('./SchemaValidationService-IoS7JquP.js');
823
930
  const { SchemaValidationService } = validationServiceMod;
824
931
  const validationService = new SchemaValidationService();
825
932
  const schemaResult = validationService.validateSchema(entityInput.entityData);
@@ -849,6 +956,22 @@ const validateEntity = fromPromise(async ({ input }) => {
849
956
  });
850
957
 
851
958
  const logger$3 = debug('seedSdk:write:writeToDatabase');
959
+ // Writes that have started. Stopping a write process's actor can't cancel one, so code that deletes rows
960
+ // under live instances (Schema.destroy, test cleanup) waits for these after evicting the instances.
961
+ const inFlightWrites = new Set();
962
+ /**
963
+ * Resolves once every database write started so far has finished (or after timeoutMs). Evict/stop the
964
+ * instances first so no new writes start while waiting.
965
+ */
966
+ const waitForInFlightWrites = async (timeoutMs = 5000) => {
967
+ const deadline = Date.now() + timeoutMs;
968
+ while (inFlightWrites.size > 0 && Date.now() < deadline) {
969
+ await Promise.race([
970
+ Promise.allSettled([...inFlightWrites]),
971
+ new Promise((resolve) => setTimeout(resolve, deadline - Date.now())),
972
+ ]);
973
+ }
974
+ };
852
975
  const writeToDatabase = fromCallback(({ sendBack, input }) => {
853
976
  const _write = async () => {
854
977
  try {
@@ -892,7 +1015,7 @@ const writeToDatabase = fromCallback(({ sendBack, input }) => {
892
1015
  // initial write completes is not overwritten by the stale requestWrite payload.
893
1016
  let dataToWrite = input.entityData;
894
1017
  try {
895
- const mod = await import('./ModelProperty-D79uV42p.js');
1018
+ const mod = await import('./ModelProperty-6llK4MTH.js');
896
1019
  const ModelProperty = mod?.ModelProperty ?? mod?.default;
897
1020
  if (ModelProperty && typeof ModelProperty.getById === 'function') {
898
1021
  const instance = ModelProperty.getById(input.entityId);
@@ -909,6 +1032,7 @@ const writeToDatabase = fromCallback(({ sendBack, input }) => {
909
1032
  storageType: ctx.storageType ?? input.entityData.storageType,
910
1033
  localStorageDir: ctx.localStorageDir ?? input.entityData.localStorageDir,
911
1034
  filenameSuffix: ctx.filenameSuffix ?? input.entityData.filenameSuffix,
1035
+ required: ctx.required ?? input.entityData.required,
912
1036
  };
913
1037
  }
914
1038
  }
@@ -941,18 +1065,26 @@ const writeToDatabase = fromCallback(({ sendBack, input }) => {
941
1065
  });
942
1066
  }
943
1067
  };
944
- _write().catch((error) => {
1068
+ const write = _write().catch((error) => {
945
1069
  logger$3('Error in writeToDatabase promise:', error);
946
1070
  sendBack({
947
1071
  type: 'writeError',
948
1072
  error: error instanceof Error ? error : new Error(String(error)),
949
1073
  });
950
1074
  });
1075
+ inFlightWrites.add(write);
1076
+ write.finally(() => inFlightWrites.delete(write));
951
1077
  return () => {
952
1078
  // Cleanup function (optional)
953
1079
  };
954
1080
  });
955
1081
 
1082
+ var writeToDatabase$1 = /*#__PURE__*/Object.freeze({
1083
+ __proto__: null,
1084
+ waitForInFlightWrites: waitForInFlightWrites,
1085
+ writeToDatabase: writeToDatabase
1086
+ });
1087
+
956
1088
  const logger$2 = debug('seedSdk:write:writeProcessMachine');
957
1089
  const writeProcessMachine = setup({
958
1090
  types: {
@@ -1131,7 +1263,10 @@ const writeProcessMachine = setup({
1131
1263
  retryCount: ({ context }) => context.retryCount + 1,
1132
1264
  }),
1133
1265
  ({ context, event }) => {
1134
- logger$2(`[writing] Write error for ${context.entityType} "${context.entityId}":`, event.error);
1266
+ const errorMsg = `[writing] Write error for ${context.entityType} "${context.entityId}": ${event.error}`;
1267
+ logger$2(errorMsg);
1268
+ // Nothing else reports a failed persist to the caller, so always log to console
1269
+ console.error(errorMsg, event.error);
1135
1270
  },
1136
1271
  ],
1137
1272
  },
@@ -1189,9 +1324,6 @@ const modelMachine = setup({
1189
1324
  isModelValid: ({ context }) => {
1190
1325
  return !context._validationErrors || context._validationErrors.length === 0;
1191
1326
  },
1192
- hasValidationErrors: ({ context }) => {
1193
- return !!context._validationErrors && context._validationErrors.length > 0;
1194
- },
1195
1327
  },
1196
1328
  actions: {
1197
1329
  assignValidationErrors: assign(({ context, event }) => {
@@ -1266,16 +1398,23 @@ const modelMachine = setup({
1266
1398
  ({ context, event, self }) => {
1267
1399
  if (event._liveQueryPropertyIds !== undefined) {
1268
1400
  const newPropertyIds = event._liveQueryPropertyIds;
1401
+ // The model can be evicted with its schema (Schema.destroy, test cleanup) before the
1402
+ // timer and import below run: then create nothing, and drop lookups an eviction overtakes.
1403
+ const evictionEpoch = currentEvictionEpoch();
1269
1404
  // Use setTimeout to check after assign has been applied
1270
1405
  setTimeout(() => {
1271
- self.getSnapshot();
1406
+ const snapshot = self.getSnapshot();
1407
+ if (snapshot.status === 'stopped')
1408
+ return;
1272
1409
  // Create ModelProperty instances for any new property IDs
1273
1410
  if (Array.isArray(newPropertyIds) && newPropertyIds.length > 0) {
1274
1411
  // Import and create instances asynchronously (fire-and-forget)
1275
- import('./ModelProperty-D79uV42p.js').then(({ ModelProperty }) => {
1412
+ import('./ModelProperty-6llK4MTH.js').then(({ ModelProperty }) => {
1413
+ if (self.getSnapshot().status === 'stopped')
1414
+ return;
1276
1415
  const createPromises = newPropertyIds.map(async (propertyFileId) => {
1277
1416
  try {
1278
- const property = await ModelProperty.createById(propertyFileId);
1417
+ const property = await ModelProperty.createById(propertyFileId, { evictionEpoch });
1279
1418
  if (property) {
1280
1419
  logger$1(`[modelMachine] Created/cached ModelProperty instance for propertyFileId "${propertyFileId}" after _liveQueryPropertyIds update`);
1281
1420
  }
@@ -1349,22 +1488,15 @@ const modelMachine = setup({
1349
1488
  })),
1350
1489
  },
1351
1490
  destroyStarted: {
1352
- actions: assign({ _destroyInProgress: true, _destroyError: null }),
1353
- },
1354
- destroyDone: {
1355
- actions: assign({ _destroyInProgress: false }),
1491
+ actions: assign({ _destroyError: null }),
1356
1492
  },
1357
1493
  destroyError: {
1358
1494
  actions: assign(({ event }) => ({
1359
- _destroyInProgress: false,
1360
1495
  _destroyError: event.error instanceof Error
1361
1496
  ? { message: event.error.message, name: event.error.name }
1362
1497
  : { message: String(event.error) },
1363
1498
  })),
1364
1499
  },
1365
- clearDestroyError: {
1366
- actions: assign({ _destroyError: null }),
1367
- },
1368
1500
  },
1369
1501
  states: {
1370
1502
  loading: {
@@ -1497,10 +1629,9 @@ const modelMachine = setup({
1497
1629
  },
1498
1630
  ],
1499
1631
  },
1500
- always: {
1501
- guard: 'hasValidationErrors',
1502
- target: 'validating',
1503
- },
1632
+ // No `always: hasValidationErrors -> validating` here: validation is re-run when the context changes
1633
+ // (updateContext) or on request (validateModel). Re-entering while errors exist would loop forever on a
1634
+ // model that is still invalid.
1504
1635
  },
1505
1636
  validating: {
1506
1637
  on: {
@@ -1550,6 +1681,8 @@ const modelMachine = setup({
1550
1681
  // Trigger property refresh after properties are created
1551
1682
  // This ensures _liveQueryPropertyIds is updated in Node.js where liveQuery isn't available
1552
1683
  setTimeout(() => {
1684
+ if (self.getSnapshot().status === 'stopped')
1685
+ return;
1553
1686
  self.send({ type: 'refreshProperties' });
1554
1687
  }, 100); // Small delay to ensure properties are written to DB
1555
1688
  },
@@ -1604,11 +1737,16 @@ function setupEntityLiveQuery(instance, config) {
1604
1737
  const initialIds = config.extractEntityIds(initialRows);
1605
1738
  if (initialIds.length > 0) {
1606
1739
  logger(`Initial query returned ${initialIds.length} entities`);
1607
- // Create child instances if provided
1740
+ // Create child instances if provided (not for a stopped entity: an unloaded or evicted
1741
+ // parent must not re-cache its children)
1742
+ if (isActorStopped(instance.getService()))
1743
+ return;
1608
1744
  if (config.createChildInstances) {
1609
1745
  await config.createChildInstances(initialIds);
1610
1746
  }
1611
- // Update context with initial IDs
1747
+ // Update context with initial IDs (the queries above can outlive the instance)
1748
+ if (isActorStopped(instance.getService()))
1749
+ return;
1612
1750
  config.updateContext(instance, initialIds);
1613
1751
  }
1614
1752
  }
@@ -1633,11 +1771,15 @@ function setupEntityLiveQuery(instance, config) {
1633
1771
  }
1634
1772
  logger(`Query returned ${rows.length} rows`);
1635
1773
  const ids = config.extractEntityIds(rows);
1636
- // Create child instances if provided (before updating context)
1774
+ // Create child instances if provided (before updating context; not for a stopped entity)
1775
+ if (isActorStopped(instance.getService()))
1776
+ return;
1637
1777
  if (config.createChildInstances && ids.length > 0) {
1638
1778
  await config.createChildInstances(ids);
1639
1779
  }
1640
1780
  // Update context with new IDs
1781
+ if (isActorStopped(instance.getService()))
1782
+ return;
1641
1783
  config.updateContext(instance, ids);
1642
1784
  },
1643
1785
  error: (error) => {
@@ -1656,9 +1798,31 @@ function setupEntityLiveQuery(instance, config) {
1656
1798
  setupState.subscriptionSetUp = false; // Reset on error so we can retry
1657
1799
  }
1658
1800
  };
1659
- // Set up liveQuery subscription as soon as we have entity ID
1660
- const setupSubscription = instance.getService().subscribe(async (snapshot) => {
1661
- // Check if entity is ready
1801
+ // The entity's DB row can be written after the entity goes idle (e.g. a schema import writes its
1802
+ // models' rows after the Model instances loaded from the schema file). Nothing changes the
1803
+ // entity's snapshot then, so an idle entity's id is also retried on a timer until found or the
1804
+ // actor stops. Only while idle and not writing (canRetryEntityId): a busy entity's own snapshots
1805
+ // drive the lookup, and finding its row mid-write handed a Model its _dbId before its write (and
1806
+ // its properties' rows) had finished.
1807
+ let retryIndex = 0;
1808
+ let retryTimer;
1809
+ const scheduleRetry = () => {
1810
+ if (retryTimer !== undefined || retryIndex >= ENTITY_ID_RETRY_DELAYS_MS.length)
1811
+ return;
1812
+ retryTimer = setTimeout(() => {
1813
+ retryTimer = undefined;
1814
+ // Busy: its next snapshot retries
1815
+ if (instance.getService().getSnapshot().value !== 'idle')
1816
+ return;
1817
+ if (config.canRetryEntityId && !config.canRetryEntityId(instance))
1818
+ return;
1819
+ retryIndex++;
1820
+ void trySetup();
1821
+ }, ENTITY_ID_RETRY_DELAYS_MS[retryIndex]);
1822
+ };
1823
+ const trySetup = async () => {
1824
+ if (setupState.subscriptionSetUp || isActorStopped(instance.getService()))
1825
+ return;
1662
1826
  if (config.isReady && !config.isReady(instance)) {
1663
1827
  if (config.waitForReady) {
1664
1828
  await config.waitForReady(instance);
@@ -1667,35 +1831,42 @@ function setupEntityLiveQuery(instance, config) {
1667
1831
  return; // Not ready yet, will retry on next snapshot
1668
1832
  }
1669
1833
  }
1670
- // Get entity ID
1671
- const entityId = await config.getEntityId(instance);
1834
+ let entityId;
1835
+ try {
1836
+ entityId = await config.getEntityId(instance);
1837
+ }
1838
+ catch (error) {
1839
+ logger(`Error getting entity ID: ${error}`);
1840
+ }
1672
1841
  if (!entityId) {
1673
- return; // Need entity ID to proceed
1842
+ scheduleRetry();
1843
+ return;
1674
1844
  }
1675
1845
  // Once we have entity ID, set up the liveQuery subscription (only once)
1676
1846
  if (!setupState.subscriptionSetUp) {
1677
1847
  await setupLiveQuery(entityId);
1678
- if (setupState.subscriptionSetUp) {
1679
- setupSubscription.unsubscribe();
1680
- }
1681
1848
  }
1682
- });
1683
- // Also check current state immediately in case entity ID is already available
1684
- instance.getService().getSnapshot();
1685
- if (config.isReady && !config.isReady(instance)) {
1686
- // Not ready yet, will be handled by subscription
1687
- return;
1688
- }
1689
- config.getEntityId(instance).then((entityId) => {
1690
- if (entityId && !setupState.subscriptionSetUp) {
1691
- setupLiveQuery(entityId).catch((error) => {
1692
- logger(`Error in immediate setup: ${error}`);
1693
- });
1849
+ if (setupState.subscriptionSetUp) {
1850
+ setupSubscription.unsubscribe();
1851
+ if (retryTimer !== undefined)
1852
+ clearTimeout(retryTimer);
1694
1853
  }
1695
- }).catch((error) => {
1696
- logger(`Error getting entity ID: ${error}`);
1854
+ };
1855
+ // Set up liveQuery subscription as soon as we have entity ID
1856
+ const setupSubscription = instance.getService().subscribe({
1857
+ next: () => {
1858
+ void trySetup();
1859
+ },
1860
+ complete: () => {
1861
+ if (retryTimer !== undefined)
1862
+ clearTimeout(retryTimer);
1863
+ },
1697
1864
  });
1865
+ // Also check current state immediately in case entity ID is already available
1866
+ void trySetup();
1698
1867
  }
1868
+ /** Backoff for retrying an entity's id when its DB row isn't there yet (~60s in total). */
1869
+ const ENTITY_ID_RETRY_DELAYS_MS = [50, 100, 200, 400, 800, 1600, ...Array(28).fill(2000)];
1699
1870
 
1700
1871
  /**
1701
1872
  * Returns model rows (id, name, schemaFileId, isEdited) for building Model instances.
@@ -1743,7 +1914,7 @@ const saveDraftLogger = debug('seedSdk:model:saveDraftToDb');
1743
1914
  // Lazy import cache for ModelProperty to avoid circular dependency
1744
1915
  // Eagerly start loading to minimize delay on first access
1745
1916
  let ModelPropertyClass = null;
1746
- const modelPropertyImportPromise = import('./ModelProperty-D79uV42p.js')
1917
+ const modelPropertyImportPromise = import('./ModelProperty-6llK4MTH.js')
1747
1918
  .then(module => {
1748
1919
  ModelPropertyClass = module.ModelProperty;
1749
1920
  return ModelPropertyClass;
@@ -1758,17 +1929,10 @@ function getModelProperty() {
1758
1929
  // and the getter will return empty array, which matches the original behavior
1759
1930
  return ModelPropertyClass;
1760
1931
  }
1761
- // Lazy import cache for Schema to avoid circular dependency
1762
- let SchemaClass = null;
1763
- const schemaImportPromise = (async () => { const _mod_7 = await import('./Schema-a8uO-hIZ.js'); return _mod_7.b; })()
1764
- .then(module => {
1765
- SchemaClass = module.Schema;
1766
- return SchemaClass;
1767
- })
1768
- .catch(() => {
1769
- // If import fails, SchemaClass remains null
1770
- return null;
1771
- });
1932
+ // Lazy import for Schema to avoid circular dependency
1933
+ const schemaImportPromise = (async () => { const _mod_11 = await import('./Schema-D-Ud-XYw.js'); return _mod_11.b; })()
1934
+ .then(module => module.Schema)
1935
+ .catch(() => null);
1772
1936
  // WeakMap to store mutable state per Model instance
1773
1937
  // This avoids issues with read-only properties when instances are frozen by Immer
1774
1938
  const modelInstanceState = new WeakMap();
@@ -1830,6 +1994,14 @@ class Model {
1830
1994
  });
1831
1995
  // Note: Property getters/setters are now handled by the Proxy in create()
1832
1996
  }
1997
+ /**
1998
+ * True when a name-cached instance belongs to a different model than the requested modelFileId.
1999
+ * A schema re-imported under the same name can give its models new ids while the previous
2000
+ * instances are still cached by name; Model.create must not hand those back for the new id.
2001
+ */
2002
+ static isOtherModelId(cachedId, requestedId) {
2003
+ return !!requestedId && !!cachedId && cachedId !== requestedId;
2004
+ }
1833
2005
  /**
1834
2006
  * Find a unique model name by checking for duplicates (case-insensitive) in the cache
1835
2007
  * If duplicates are found, appends an incrementing number to make it unique
@@ -1888,36 +2060,6 @@ class Model {
1888
2060
  }
1889
2061
  }
1890
2062
  }
1891
- // Also check schema context models (case-insensitive)
1892
- // This ensures runtime-created models are renamed if they conflict with schema-defined models
1893
- try {
1894
- // Use lazy-loaded Schema class to avoid circular dependency
1895
- if (SchemaClass) {
1896
- const schema = SchemaClass.create(schemaName);
1897
- const schemaContext = schema.getService().getSnapshot().context;
1898
- if (schemaContext.models) {
1899
- for (const schemaModelName of Object.keys(schemaContext.models)) {
1900
- const lowerSchemaModelName = schemaModelName.toLowerCase();
1901
- // If it matches the base name (case-insensitive), check if it has a number suffix
1902
- if (lowerSchemaModelName === lowerModelName) {
1903
- existingNumbers.add(0); // Base name exists in schema
1904
- }
1905
- else if (lowerSchemaModelName.startsWith(lowerModelName + ' ')) {
1906
- // Check if it's the base name followed by a space and a number
1907
- const suffix = lowerSchemaModelName.slice(lowerModelName.length + 1);
1908
- const number = parseInt(suffix, 10);
1909
- if (!isNaN(number) && suffix === number.toString()) {
1910
- existingNumbers.add(number);
1911
- }
1912
- }
1913
- }
1914
- }
1915
- }
1916
- }
1917
- catch (error) {
1918
- // If schema check fails, continue with cache-only check
1919
- // This is a best-effort check and shouldn't block model creation
1920
- }
1921
2063
  // If no duplicates found (no base name match and no numbered variants), return original name
1922
2064
  if (existingNumbers.size === 0) {
1923
2065
  return modelName;
@@ -1997,7 +2139,7 @@ class Model {
1997
2139
  if (this.instanceCache.has(legacyKey)) {
1998
2140
  const { instance, refCount } = this.instanceCache.get(legacyKey);
1999
2141
  const ctx = instance._getSnapshotContext();
2000
- if (!ctx._idFromSchema) {
2142
+ if (!ctx._idFromSchema && !this.isOtherModelId(ctx.id, id)) {
2001
2143
  this.instanceCache.set(legacyKey, {
2002
2144
  instance,
2003
2145
  refCount: refCount + 1,
@@ -2033,7 +2175,8 @@ class Model {
2033
2175
  : `${schemaName}:__pending__${resolvedId}`;
2034
2176
  // Step 6: Check legacy cache with unique name (backward compatibility during migration)
2035
2177
  // This is a fallback in case an instance was cached with a unique name
2036
- if (this.instanceCache.has(nameKey)) {
2178
+ if (this.instanceCache.has(nameKey) &&
2179
+ !this.isOtherModelId(this.instanceCache.get(nameKey).instance._getSnapshotContext().id, id)) {
2037
2180
  const { instance, refCount } = this.instanceCache.get(nameKey);
2038
2181
  this.instanceCache.set(nameKey, {
2039
2182
  instance,
@@ -2285,6 +2428,9 @@ class Model {
2285
2428
  resolve();
2286
2429
  }, 10000);
2287
2430
  });
2431
+ // Unloaded or evicted (e.g. Schema.destroy) while it loaded: a stopped model never writes
2432
+ if (isActorStopped(proxiedInstance._service))
2433
+ return;
2288
2434
  // Only write if validation passed (model is in idle state, not error)
2289
2435
  const finalSnapshot = proxiedInstance._service.getSnapshot();
2290
2436
  if (finalSnapshot.value === 'idle' && (!finalSnapshot.context._validationErrors || finalSnapshot.context._validationErrors.length === 0)) {
@@ -2408,15 +2554,20 @@ class Model {
2408
2554
  }
2409
2555
  logger(`WARNING: Could not verify schema exists in database: ${error}. Proceeding anyway.`);
2410
2556
  }
2411
- // Track pending write
2412
- Model.trackPendingWrite(finalSnapshot.context.id, schemaId); // id is now the schemaFileId (string)
2557
+ const pendingModelFileId = finalSnapshot.context.id;
2558
+ const pendingSchemaId = schemaId;
2413
2559
  // Wait for writeProcess to be spawned (it's spawned in idle state entry action)
2414
2560
  // Retry a few times if writeProcess isn't available yet
2415
2561
  let retries = 0;
2416
2562
  const maxRetries = 10;
2417
2563
  const checkAndSend = async () => {
2564
+ // Unloaded or evicted (e.g. Schema.destroy) before the write started: nothing to write to
2565
+ if (isActorStopped(proxiedInstance._service))
2566
+ return;
2418
2567
  const currentSnapshot = proxiedInstance._service.getSnapshot();
2419
2568
  if (currentSnapshot.context.writeProcess) {
2569
+ // Track pending write (only once it really starts: a stopped model leaves none behind)
2570
+ Model.trackPendingWrite(pendingModelFileId, pendingSchemaId); // id is now the schemaFileId (string)
2420
2571
  logger(`Triggering write process for model "${finalSnapshot.context.modelName}" (schemaId: ${schemaId})`);
2421
2572
  // Use pending property definitions if available, otherwise convert from ModelProperty instances
2422
2573
  let propertiesObject = {};
@@ -2540,14 +2691,45 @@ class Model {
2540
2691
  }
2541
2692
  return this.getById(id);
2542
2693
  }
2543
- // If schemaName not provided, try to find in cache by searching all name keys
2694
+ // If schemaName not provided, search all name keys. Model names are only unique per schema, so
2695
+ // this throws AmbiguousModelError when cached models from several schemas share the name.
2696
+ // Callers that know the schema or model id should use Model.resolve() instead.
2697
+ return this._getUniqueCachedModel(modelName, (cachedModelName) => cachedModelName === modelName);
2698
+ }
2699
+ /** The one cached Model whose name matches, or AmbiguousModelError if models from several schemas do. */
2700
+ static _getUniqueCachedModel(label, matches) {
2701
+ const matchesById = new Map(); // modelFileId -> schemaName
2544
2702
  for (const [nameKey, id] of this.instanceCacheByName.entries()) {
2545
- const [, cachedModelName] = nameKey.split(':');
2546
- if (cachedModelName === modelName) {
2547
- return this.getById(id);
2703
+ const separator = nameKey.lastIndexOf(':');
2704
+ const cachedModelName = nameKey.slice(separator + 1);
2705
+ if (id && cachedModelName && matches(cachedModelName) && this.instanceCacheById.has(id)) {
2706
+ matchesById.set(id, nameKey.slice(0, separator));
2548
2707
  }
2549
2708
  }
2550
- return undefined;
2709
+ if (matchesById.size > 1) {
2710
+ throw new AmbiguousModelError(label, [...matchesById.values()]);
2711
+ }
2712
+ const [matchId] = matchesById.keys();
2713
+ return matchId ? this.getById(matchId) : undefined;
2714
+ }
2715
+ /**
2716
+ * Resolve a cached Model from the most specific scope available: modelFileId (Model.id), then
2717
+ * schemaName + modelName, then modelName alone.
2718
+ */
2719
+ static resolve(modelName, scope = {}) {
2720
+ if (scope.modelFileId) {
2721
+ const byId = this.getById(scope.modelFileId);
2722
+ if (byId)
2723
+ return byId;
2724
+ }
2725
+ if (!modelName)
2726
+ return undefined;
2727
+ if (scope.schemaName) {
2728
+ const bySchema = this.getByName(modelName, scope.schemaName);
2729
+ if (bySchema)
2730
+ return bySchema;
2731
+ }
2732
+ return this.getByName(modelName);
2551
2733
  }
2552
2734
  /**
2553
2735
  * Find Model by modelType (snake_case from DB/metadata).
@@ -2556,14 +2738,7 @@ class Model {
2556
2738
  static findByModelType(modelType) {
2557
2739
  if (!modelType)
2558
2740
  return undefined;
2559
- for (const [nameKey, id] of this.instanceCacheByName.entries()) {
2560
- const parts = nameKey.split(':', 2);
2561
- const cachedModelName = parts[1];
2562
- if (cachedModelName && toSnakeCase(cachedModelName) === modelType) {
2563
- return this.getById(id);
2564
- }
2565
- }
2566
- return undefined;
2741
+ return this._getUniqueCachedModel(modelType, (cachedModelName) => toSnakeCase(cachedModelName) === modelType);
2567
2742
  }
2568
2743
  /**
2569
2744
  * Get all Model instances for a schema from cache only (synchronous).
@@ -2595,6 +2770,54 @@ class Model {
2595
2770
  }
2596
2771
  return instances;
2597
2772
  }
2773
+ /**
2774
+ * Async Model.resolve(): exact cache hit by modelFileId or schemaName+modelName, else the DB row for
2775
+ * that scope (instantiating the Model), and only then the name-only fallback.
2776
+ */
2777
+ static async resolveAsync(modelName, scope = {}) {
2778
+ if (scope.modelFileId) {
2779
+ const byId = this.getById(scope.modelFileId);
2780
+ if (byId)
2781
+ return byId;
2782
+ }
2783
+ if (modelName && scope.schemaName) {
2784
+ const bySchema = this.getByName(modelName, scope.schemaName);
2785
+ if (bySchema)
2786
+ return bySchema;
2787
+ }
2788
+ if (scope.modelFileId || scope.schemaName) {
2789
+ const db = BaseDb.getAppDb();
2790
+ if (db) {
2791
+ const evictionEpoch = currentEvictionEpoch();
2792
+ try {
2793
+ const rows = await db
2794
+ .select({
2795
+ modelFileId: models.schemaFileId,
2796
+ modelName: models.name,
2797
+ schemaName: schemas.name,
2798
+ })
2799
+ .from(models)
2800
+ .innerJoin(modelSchemas, eq(models.id, modelSchemas.modelId))
2801
+ .innerJoin(schemas, eq(modelSchemas.schemaId, schemas.id))
2802
+ .where(scope.modelFileId
2803
+ ? eq(models.schemaFileId, scope.modelFileId)
2804
+ : and(eq(models.name, modelName ?? ''), eq(schemas.name, scope.schemaName)))
2805
+ .limit(1);
2806
+ const record = rows[0];
2807
+ if (record?.modelName && record.schemaName && record.modelFileId) {
2808
+ // Its schema was evicted while we read the row: don't bring the model back.
2809
+ if (schemaEvictedSince(record.schemaName, evictionEpoch))
2810
+ return undefined;
2811
+ return this.create(record.modelName, record.schemaName, { id: record.modelFileId });
2812
+ }
2813
+ }
2814
+ catch (error) {
2815
+ logger(`Model.resolveAsync: scoped lookup failed for "${modelName}": ${error instanceof Error ? error.message : String(error)}`);
2816
+ }
2817
+ }
2818
+ }
2819
+ return modelName ? this.getByNameAsync(modelName) : undefined;
2820
+ }
2598
2821
  /**
2599
2822
  * Get Model instance by name, querying database if not in cache
2600
2823
  * This is an async version that can query the database when schemaName is not provided
@@ -2603,7 +2826,7 @@ class Model {
2603
2826
  * @param schemaName - Optional schema name (will query DB if not provided)
2604
2827
  * @returns The Model instance if found, undefined otherwise
2605
2828
  */
2606
- static async getByNameAsync(modelName, schemaName) {
2829
+ static async getByNameAsync(modelName, schemaName, options) {
2607
2830
  // First try cache
2608
2831
  const cached = this.getByName(modelName, schemaName);
2609
2832
  if (cached) {
@@ -2615,8 +2838,16 @@ class Model {
2615
2838
  if (!db) {
2616
2839
  return undefined;
2617
2840
  }
2841
+ const evictionEpoch = options?.evictionEpoch ?? currentEvictionEpoch();
2618
2842
  try {
2619
- // Query model by name
2843
+ // Query model by name (throws AmbiguousModelError when several schemas define it)
2844
+ const _mod_9 = await import('./db-Lw0KVZmc.js');
2845
+ const _ns_9 = _mod_9.Y;
2846
+ const { resolveModelRecord } = _ns_9;
2847
+ const resolved = await resolveModelRecord(modelName, {}, db);
2848
+ if (!resolved?.schemaFileId) {
2849
+ return undefined;
2850
+ }
2620
2851
  const modelRecords = await db
2621
2852
  .select({
2622
2853
  modelFileId: models.schemaFileId,
@@ -2626,7 +2857,7 @@ class Model {
2626
2857
  .from(models)
2627
2858
  .innerJoin(modelSchemas, eq(models.id, modelSchemas.modelId))
2628
2859
  .innerJoin(schemas, eq(modelSchemas.schemaId, schemas.id))
2629
- .where(eq(models.name, modelName))
2860
+ .where(eq(models.id, resolved.id))
2630
2861
  .limit(1);
2631
2862
  if (modelRecords.length === 0) {
2632
2863
  return undefined;
@@ -2635,12 +2866,18 @@ class Model {
2635
2866
  if (!record.modelName || !record.schemaName || !record.modelFileId) {
2636
2867
  return undefined;
2637
2868
  }
2869
+ // Its schema was evicted while we read the row: don't bring the model back.
2870
+ if (schemaEvictedSince(record.schemaName, evictionEpoch)) {
2871
+ return undefined;
2872
+ }
2638
2873
  // Create model instance (will be cached)
2639
2874
  return this.create(record.modelName, record.schemaName, {
2640
2875
  id: record.modelFileId, // id is now the schemaFileId (string)
2641
2876
  });
2642
2877
  }
2643
2878
  catch (error) {
2879
+ if (error instanceof AmbiguousModelError)
2880
+ throw error;
2644
2881
  logger(`Model.getByNameAsync: Error looking up model by name "${modelName}": ${error instanceof Error ? error.message : String(error)}`);
2645
2882
  return undefined;
2646
2883
  }
@@ -2654,7 +2891,7 @@ class Model {
2654
2891
  * @param modelFileId - The model file ID to look up
2655
2892
  * @returns The Model instance if found, undefined otherwise
2656
2893
  */
2657
- static async createById(modelFileId) {
2894
+ static async createById(modelFileId, options) {
2658
2895
  if (!modelFileId) {
2659
2896
  return undefined;
2660
2897
  }
@@ -2670,6 +2907,7 @@ class Model {
2670
2907
  logger(`Model.createById: Database not available for ID "${modelFileId}"`);
2671
2908
  return undefined;
2672
2909
  }
2910
+ const evictionEpoch = options?.evictionEpoch ?? currentEvictionEpoch();
2673
2911
  try {
2674
2912
  // Query model by schemaFileId and join to get schema name
2675
2913
  const modelRecords = await db
@@ -2692,6 +2930,12 @@ class Model {
2692
2930
  logger(`Model.createById: Missing modelName or schemaName for ID "${modelFileId}"`);
2693
2931
  return undefined;
2694
2932
  }
2933
+ // Its schema was evicted while we read the row (e.g. a Schema live query in flight during
2934
+ // Schema.destroy or test cleanup): don't bring the model back.
2935
+ if (schemaEvictedSince(schemaName, evictionEpoch)) {
2936
+ logger(`Model.createById: schema "${schemaName}" was evicted during the lookup of "${modelFileId}"`);
2937
+ return undefined;
2938
+ }
2695
2939
  // Step 3: Create model using existing create method (which will handle caching)
2696
2940
  logger(`Model.createById: Creating model "${modelName}" in schema "${schemaName}" from ID "${modelFileId}"`);
2697
2941
  return this.create(modelName, schemaName, {
@@ -2746,6 +2990,7 @@ class Model {
2746
2990
  logger(`Model.createBySchemaId: Database not available for schema "${schemaIdentifier}"`);
2747
2991
  return [];
2748
2992
  }
2993
+ const evictionEpoch = currentEvictionEpoch();
2749
2994
  try {
2750
2995
  // Query all models for this schema - support both schemaFileId and schema name
2751
2996
  const modelRecords = await db
@@ -2768,6 +3013,10 @@ class Model {
2768
3013
  if (!record.modelName || !record.schemaName || !record.modelFileId) {
2769
3014
  continue;
2770
3015
  }
3016
+ // Its schema was evicted while we read the rows: don't bring its models back.
3017
+ if (schemaEvictedSince(record.schemaName, evictionEpoch)) {
3018
+ continue;
3019
+ }
2771
3020
  // Check cache first
2772
3021
  const cached = this.getById(record.modelFileId);
2773
3022
  if (cached) {
@@ -2846,9 +3095,10 @@ class Model {
2846
3095
  const instances = [];
2847
3096
  const seen = new Set();
2848
3097
  for (const row of rows) {
2849
- if (row.schemaFileId) {
3098
+ // A model can appear more than once (e.g. duplicate model_schemas links); return it once.
3099
+ if (row.schemaFileId && !seen.has(row.schemaFileId)) {
2850
3100
  const instance = await this.createById(row.schemaFileId);
2851
- if (instance) {
3101
+ if (instance && !seen.has(instance.id ?? row.schemaFileId)) {
2852
3102
  instances.push(instance);
2853
3103
  seen.add(instance.id ?? row.schemaFileId);
2854
3104
  }
@@ -3206,6 +3456,52 @@ class Model {
3206
3456
  }, 10000);
3207
3457
  });
3208
3458
  }
3459
+ /**
3460
+ * Force-evict every cached Model belonging to a schema, ignoring refCounts, and stop their services.
3461
+ * Used by Schema.destroy(): once the DB rows are gone, cached instances would keep a dangling _dbId
3462
+ * and be handed back by Model.create/Model.all after the schema is re-imported.
3463
+ * @returns names of the evicted models (so callers can evict their ModelProperty instances)
3464
+ */
3465
+ static evictForSchema(schemaName) {
3466
+ // Work already running for this schema's models must not re-cache them when it finishes.
3467
+ recordSchemaEviction(schemaName);
3468
+ const instances = new Set();
3469
+ for (const { instance } of this.instanceCacheById.values())
3470
+ instances.add(instance);
3471
+ for (const { instance } of this.instanceCache.values())
3472
+ instances.add(instance);
3473
+ const evictedNames = [];
3474
+ for (const instance of instances) {
3475
+ let context;
3476
+ try {
3477
+ context = instance._getSnapshotContext();
3478
+ }
3479
+ catch {
3480
+ continue;
3481
+ }
3482
+ if (context.schemaName !== schemaName)
3483
+ continue;
3484
+ const nameKey = `${context.schemaName}:${context.modelName}`;
3485
+ clearDestroySubscriptions(instance, { instanceState: modelInstanceState });
3486
+ forceRemoveFromCaches(instance, {
3487
+ getCacheKeys: () => (context.id ? [context.id, nameKey] : [nameKey]),
3488
+ caches: [
3489
+ Model.instanceCacheById,
3490
+ Model.instanceCacheByName,
3491
+ Model.instanceCache,
3492
+ ],
3493
+ });
3494
+ try {
3495
+ instance._service.stop();
3496
+ }
3497
+ catch {
3498
+ // Service might already be stopped
3499
+ }
3500
+ if (context.modelName)
3501
+ evictedNames.push(context.modelName);
3502
+ }
3503
+ return evictedNames;
3504
+ }
3209
3505
  /**
3210
3506
  * Unload the model instance and clean up resources
3211
3507
  */
@@ -3320,16 +3616,18 @@ class Model {
3320
3616
  if (!db) {
3321
3617
  return undefined;
3322
3618
  }
3323
- const modelRecords = await db
3324
- .select()
3325
- .from(models)
3326
- .where(eq(models.name, modelName))
3327
- .limit(1);
3328
- if (modelRecords.length === 0 || !modelRecords[0].id) {
3619
+ // Model names are only unique per schema: find this model's row by its id (schemaFileId).
3620
+ const _mod_10 = await import('./db-Lw0KVZmc.js');
3621
+ const _ns_10 = _mod_10.Y;
3622
+ const { resolveModelRecord } = _ns_10;
3623
+ const modelRecord = await resolveModelRecord(modelName, { modelFileId: context.id, schemaName: context.schemaName }, db);
3624
+ if (!modelRecord?.id) {
3329
3625
  return undefined;
3330
3626
  }
3331
- dbId = modelRecords[0].id;
3332
- // Update context with _dbId
3627
+ dbId = modelRecord.id;
3628
+ // Update context with _dbId (unless the model was stopped while the lookup ran)
3629
+ if (isActorStopped(model._service))
3630
+ return undefined;
3333
3631
  model._service.send({
3334
3632
  type: 'updateContext',
3335
3633
  _dbId: dbId,
@@ -3389,6 +3687,12 @@ class Model {
3389
3687
  schemaFileId: row.schemaFileId,
3390
3688
  }));
3391
3689
  },
3690
+ // The model writes from its writeProcess child while itself idle; wait for that write to end.
3691
+ canRetryEntityId: (model) => {
3692
+ const writeProcess = model._getSnapshotContext().writeProcess;
3693
+ const writeState = writeProcess?.getSnapshot().value;
3694
+ return writeState !== 'validating' && writeState !== 'writing';
3695
+ },
3392
3696
  instanceState: modelInstanceState,
3393
3697
  loggerName: 'seedSdk:model:liveQuery',
3394
3698
  });
@@ -3412,6 +3716,9 @@ class Model {
3412
3716
  .select({ schemaFileId: properties.schemaFileId })
3413
3717
  .from(properties)
3414
3718
  .where(eq(properties.modelId, dbId)); // Use _dbId (database integer ID)
3719
+ // Stopped while querying: don't re-cache ModelProperty instances for an evicted/unloaded model
3720
+ if (isActorStopped(this._service))
3721
+ return;
3415
3722
  const propertyIds = propertyRows
3416
3723
  .map((row) => row.schemaFileId)
3417
3724
  .filter((id) => id !== null && id !== undefined);
@@ -3446,7 +3753,10 @@ class Model {
3446
3753
  logger(`[Model._refreshPropertiesFromDb] Error importing ModelProperty or creating instances: ${error}`);
3447
3754
  }
3448
3755
  }
3449
- // Update context with refreshed property IDs AFTER creating instances
3756
+ // Update context with refreshed property IDs AFTER creating instances (the awaits above can
3757
+ // outlive the instance)
3758
+ if (isActorStopped(this._service))
3759
+ return;
3450
3760
  this._service.send({
3451
3761
  type: 'updateContext',
3452
3762
  _liveQueryPropertyIds: propertyIds,
@@ -3463,6 +3773,30 @@ class Model {
3463
3773
  async refreshProperties() {
3464
3774
  await this._refreshPropertiesFromDb();
3465
3775
  }
3776
+ /**
3777
+ * Refresh the property ids of every cached Model whose DB row is `dbId`. Called when a property
3778
+ * write for that model finishes: until then `properties` includes it as a pending write, and in Node
3779
+ * (no reactive liveQuery) nothing else adds it to `_liveQueryPropertyIds`.
3780
+ */
3781
+ static async refreshPropertiesForDbId(dbId) {
3782
+ const instances = new Set();
3783
+ for (const { instance } of this.instanceCacheById.values())
3784
+ instances.add(instance);
3785
+ for (const { instance } of this.instanceCache.values())
3786
+ instances.add(instance);
3787
+ for (const instance of instances) {
3788
+ let context;
3789
+ try {
3790
+ context = instance._getSnapshotContext();
3791
+ }
3792
+ catch {
3793
+ continue;
3794
+ }
3795
+ if (context._dbId !== dbId)
3796
+ continue;
3797
+ await instance._refreshPropertiesFromDb();
3798
+ }
3799
+ }
3466
3800
  }
3467
3801
  // Primary cache: ID-based (never changes on rename)
3468
3802
  Model.instanceCacheById = new Map();
@@ -3488,5 +3822,5 @@ var Model$1 = /*#__PURE__*/Object.freeze({
3488
3822
  const TModelValues = Type.Record(Type.String(), Type.Any());
3489
3823
  const TModelSchema = Type.Record(Type.String(), TProperty);
3490
3824
 
3491
- export { ConflictError as C, Model as M, TModelSchema as T, TModelValues as a, Model$1 as b, setupEntityLiveQuery as s, writeProcessMachine as w };
3492
- //# sourceMappingURL=index-HRHkbVQd.js.map
3825
+ export { ConflictError as C, Model as M, TModelSchema as T, TModelValues as a, anyEvictionSince as b, currentEvictionEpoch as c, setupEntityLiveQuery as d, writeToDatabase$1 as e, Model$1 as f, isActorStopped as i, schemaEvictedSince as s, writeProcessMachine as w };
3826
+ //# sourceMappingURL=index-Y-yYyRBf.js.map