@seedprotocol/sdk 0.7.9-next.1177.ga3e08ed → 0.7.9-next.1189.g5e63267

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 (200) hide show
  1. package/dist/{ClientManager-GZfXErDX.js → ClientManager-DqL0q_eu.js} +30 -17
  2. package/dist/ClientManager-DqL0q_eu.js.map +1 -0
  3. package/dist/{Item-0oDoTPhi.js → Item-CG5IhPtL.js} +260 -113
  4. package/dist/Item-CG5IhPtL.js.map +1 -0
  5. package/dist/{ModelProperty-i5flwzQG.js → ModelProperty-DDD47KVm.js} +26 -26
  6. package/dist/{ModelProperty-i5flwzQG.js.map → ModelProperty-DDD47KVm.js.map} +1 -1
  7. package/dist/{Schema-PFZwG9Nl.js → Schema-BS8oR7QV.js} +24 -24
  8. package/dist/{Schema-PFZwG9Nl.js.map → Schema-BS8oR7QV.js.map} +1 -1
  9. package/dist/{SchemaValidationService-DnGKel4V.js → SchemaValidationService-CZzKNL04.js} +6 -6
  10. package/dist/{SchemaValidationService-DnGKel4V.js.map → SchemaValidationService-CZzKNL04.js.map} +1 -1
  11. package/dist/{backfillMetadataPropertyIds-BbxgavEQ.js → backfillMetadataPropertyIds-C7P7FL6F.js} +3 -3
  12. package/dist/{backfillMetadataPropertyIds-BbxgavEQ.js.map → backfillMetadataPropertyIds-C7P7FL6F.js.map} +1 -1
  13. package/dist/{changeFeed-DKdVlUmt.js → changeFeed-M8sGbOrW.js} +6 -6
  14. package/dist/{changeFeed-DKdVlUmt.js.map → changeFeed-M8sGbOrW.js.map} +1 -1
  15. package/dist/{configurePlatform-CrMafpMW.js → configurePlatform-Dukm2QwO.js} +2 -2
  16. package/dist/{configurePlatform-CrMafpMW.js.map → configurePlatform-Dukm2QwO.js.map} +1 -1
  17. package/dist/db/drizzle/0025_add_metadata_retract.sql +1 -0
  18. package/dist/db/drizzle/meta/0025_snapshot.json +1652 -0
  19. package/dist/db/drizzle/meta/_journal.json +7 -0
  20. package/dist/{detachRowsBeforeDelete-DXFYSHRR.js → detachRowsBeforeDelete-Di1enVUF.js} +2 -2
  21. package/dist/{detachRowsBeforeDelete-DXFYSHRR.js.map → detachRowsBeforeDelete-Di1enVUF.js.map} +1 -1
  22. package/dist/dist/{ClientManager-GZfXErDX.d.ts → ClientManager-DqL0q_eu.d.ts} +1 -1
  23. package/dist/dist/{ClientManager-GZfXErDX.d.ts.map → ClientManager-DqL0q_eu.d.ts.map} +1 -1
  24. package/dist/dist/{Item-0oDoTPhi.d.ts → Item-CG5IhPtL.d.ts} +103 -64
  25. package/dist/dist/Item-CG5IhPtL.d.ts.map +1 -0
  26. package/dist/dist/{ModelProperty-i5flwzQG.d.ts → ModelProperty-DDD47KVm.d.ts} +1 -1
  27. package/dist/dist/{ModelProperty-i5flwzQG.d.ts.map → ModelProperty-DDD47KVm.d.ts.map} +1 -1
  28. package/dist/dist/{Schema-PFZwG9Nl.d.ts → Schema-BS8oR7QV.d.ts} +2 -2
  29. package/dist/dist/{Schema-PFZwG9Nl.d.ts.map → Schema-BS8oR7QV.d.ts.map} +1 -1
  30. package/dist/dist/{SchemaValidationService-DnGKel4V.d.ts → SchemaValidationService-CZzKNL04.d.ts} +1 -1
  31. package/dist/dist/{SchemaValidationService-DnGKel4V.d.ts.map → SchemaValidationService-CZzKNL04.d.ts.map} +1 -1
  32. package/dist/dist/{backfillMetadataPropertyIds-BbxgavEQ.d.ts → backfillMetadataPropertyIds-C7P7FL6F.d.ts} +1 -1
  33. package/dist/dist/backfillMetadataPropertyIds-C7P7FL6F.d.ts.map +1 -0
  34. package/dist/dist/{changeFeed-DKdVlUmt.d.ts → changeFeed-M8sGbOrW.d.ts} +1 -1
  35. package/dist/dist/{changeFeed-DKdVlUmt.d.ts.map → changeFeed-M8sGbOrW.d.ts.map} +1 -1
  36. package/dist/dist/{configurePlatform-CrMafpMW.d.ts → configurePlatform-Dukm2QwO.d.ts} +1 -1
  37. package/dist/dist/configurePlatform-Dukm2QwO.d.ts.map +1 -0
  38. package/dist/dist/{detachRowsBeforeDelete-DXFYSHRR.d.ts → detachRowsBeforeDelete-Di1enVUF.d.ts} +1 -1
  39. package/dist/dist/detachRowsBeforeDelete-Di1enVUF.d.ts.map +1 -0
  40. package/dist/dist/{eas-dyepi5jz.d.ts → eas-B5VJolSj.d.ts} +1 -1
  41. package/dist/dist/eas-B5VJolSj.d.ts.map +1 -0
  42. package/dist/dist/{errors-D1zHAqjr.d.ts → errors-CS3nDpUU.d.ts} +1 -1
  43. package/dist/dist/{errors-D1zHAqjr.d.ts.map → errors-CS3nDpUU.d.ts.map} +1 -1
  44. package/dist/dist/{findSeedRowsByUid-CT3sOXXw.d.ts → findSeedRowsByUid-CuQmK7An.d.ts} +1 -1
  45. package/dist/dist/findSeedRowsByUid-CuQmK7An.d.ts.map +1 -0
  46. package/dist/dist/{getItem-Bhjecbia.d.ts → getItem-Uha3_H0t.d.ts} +1 -1
  47. package/dist/dist/getItem-Uha3_H0t.d.ts.map +1 -0
  48. package/dist/dist/{getPublishPayload-DH4rMqXG.d.ts → getPublishPayload-pbin4lk8.d.ts} +20 -2
  49. package/dist/dist/getPublishPayload-pbin4lk8.d.ts.map +1 -0
  50. package/dist/dist/getPublishPendingDiff-ByIaPvCn.d.ts +18 -0
  51. package/dist/dist/getPublishPendingDiff-ByIaPvCn.d.ts.map +1 -0
  52. package/dist/dist/{getPublishUploads-BzUIDA2G.d.ts → getPublishUploads-BBqiowVc.d.ts} +1 -1
  53. package/dist/dist/{getPublishUploads-BzUIDA2G.d.ts.map → getPublishUploads-BBqiowVc.d.ts.map} +1 -1
  54. package/dist/dist/{index-DJmWkVIK.d.ts → index-DQoyhp2c.d.ts} +5 -5
  55. package/dist/dist/index-DQoyhp2c.d.ts.map +1 -0
  56. package/dist/dist/{index-PbnKw2es.d.ts → index-DxHpPNfn.d.ts} +18 -1
  57. package/dist/dist/{index-PbnKw2es.d.ts.map → index-DxHpPNfn.d.ts.map} +1 -1
  58. package/dist/dist/{index-CkYb3wcU.d.ts → index-njjjo74v.d.ts} +13 -13
  59. package/dist/dist/index-njjjo74v.d.ts.map +1 -0
  60. package/dist/dist/{index-Dx_GTdyQ.d.ts → index-rOTW-2QZ.d.ts} +139 -118
  61. package/dist/dist/index-rOTW-2QZ.d.ts.map +1 -0
  62. package/dist/dist/{index.browser-i9uPJice.d.ts → index.browser-QPWBkLJA.d.ts} +52 -1
  63. package/dist/dist/{index.browser-i9uPJice.d.ts.map → index.browser-QPWBkLJA.d.ts.map} +1 -1
  64. package/dist/dist/{index.node-CzMwMr_d.d.ts → index.node-WsEJCOwC.d.ts} +69 -1
  65. package/dist/dist/{index.node-CzMwMr_d.d.ts.map → index.node-WsEJCOwC.d.ts.map} +1 -1
  66. package/dist/dist/{modelPropertyRecordSchemas-C5lW9aA-.d.ts → modelPropertyRecordSchemas-onFOG2x6.d.ts} +1 -1
  67. package/dist/dist/modelPropertyRecordSchemas-onFOG2x6.d.ts.map +1 -0
  68. package/dist/dist/platform.browser.d.ts +2 -2
  69. package/dist/dist/platform.node.d.ts +2 -2
  70. package/dist/dist/{property-BwYtg5Q_.d.ts → property-C85DCD7K.d.ts} +3 -3
  71. package/dist/dist/property-C85DCD7K.d.ts.map +1 -0
  72. package/dist/dist/{propertyValidationRules-CyHdpcPP.d.ts → propertyValidationRules-CjUPOFeu.d.ts} +1 -1
  73. package/dist/dist/propertyValidationRules-CjUPOFeu.d.ts.map +1 -0
  74. package/dist/dist/{publishDraftGraph-C5F6b7GK.d.ts → publishDraftGraph-DBWAN72w.d.ts} +1 -1
  75. package/dist/dist/{publishDraftGraph-C5F6b7GK.d.ts.map → publishDraftGraph-DBWAN72w.d.ts.map} +1 -1
  76. package/dist/dist/{resolveModelForSyncedSeed-4gO9Hfn2.d.ts → resolveModelForSyncedSeed-fIURvYRV.d.ts} +1 -1
  77. package/dist/dist/resolveModelForSyncedSeed-fIURvYRV.d.ts.map +1 -0
  78. package/dist/dist/{syncDbWithEas-DUu_wjUG.d.ts → syncDbWithEas-BMHoou6X.d.ts} +1 -1
  79. package/dist/dist/syncDbWithEas-BMHoou6X.d.ts.map +1 -0
  80. package/dist/dist/{tolerantWebAccess-DecKDGen.d.ts → tolerantWebAccess-BHndShch.d.ts} +1 -1
  81. package/dist/dist/{tolerantWebAccess-DecKDGen.d.ts.map → tolerantWebAccess-BHndShch.d.ts.map} +1 -1
  82. package/dist/dist/{updateSeedRevokedAt-CP606vKs.d.ts → updateSeedRevokedAt-DpfG6ztE.d.ts} +1 -1
  83. package/dist/dist/updateSeedRevokedAt-DpfG6ztE.d.ts.map +1 -0
  84. package/dist/{eas-dyepi5jz.js → eas-B5VJolSj.js} +3 -3
  85. package/dist/{eas-dyepi5jz.js.map → eas-B5VJolSj.js.map} +1 -1
  86. package/dist/{errors-D1zHAqjr.js → errors-CS3nDpUU.js} +26 -26
  87. package/dist/{errors-D1zHAqjr.js.map → errors-CS3nDpUU.js.map} +1 -1
  88. package/dist/{findSeedRowsByUid-CT3sOXXw.js → findSeedRowsByUid-CuQmK7An.js} +3 -3
  89. package/dist/{findSeedRowsByUid-CT3sOXXw.js.map → findSeedRowsByUid-CuQmK7An.js.map} +1 -1
  90. package/dist/{getItem-Bhjecbia.js → getItem-Uha3_H0t.js} +4 -4
  91. package/dist/{getItem-Bhjecbia.js.map → getItem-Uha3_H0t.js.map} +1 -1
  92. package/dist/{getPublishPayload-DH4rMqXG.js → getPublishPayload-pbin4lk8.js} +201 -99
  93. package/dist/getPublishPayload-pbin4lk8.js.map +1 -0
  94. package/dist/getPublishPendingDiff-ByIaPvCn.js +118 -0
  95. package/dist/getPublishPendingDiff-ByIaPvCn.js.map +1 -0
  96. package/dist/{getPublishUploads-BzUIDA2G.js → getPublishUploads-BBqiowVc.js} +7 -7
  97. package/dist/{getPublishUploads-BzUIDA2G.js.map → getPublishUploads-BBqiowVc.js.map} +1 -1
  98. package/dist/{index-DJmWkVIK.js → index-DQoyhp2c.js} +8 -8
  99. package/dist/index-DQoyhp2c.js.map +1 -0
  100. package/dist/{index-PbnKw2es.js → index-DxHpPNfn.js} +2 -2
  101. package/dist/index-DxHpPNfn.js.map +1 -0
  102. package/dist/{index-CkYb3wcU.js → index-njjjo74v.js} +7 -7
  103. package/dist/index-njjjo74v.js.map +1 -0
  104. package/dist/{index-Dx_GTdyQ.js → index-rOTW-2QZ.js} +18 -3
  105. package/dist/index-rOTW-2QZ.js.map +1 -0
  106. package/dist/{index.browser-i9uPJice.js → index.browser-QPWBkLJA.js} +50 -34
  107. package/dist/index.browser-QPWBkLJA.js.map +1 -0
  108. package/dist/{index.node-CzMwMr_d.js → index.node-WsEJCOwC.js} +5 -5
  109. package/dist/{index.node-CzMwMr_d.js.map → index.node-WsEJCOwC.js.map} +1 -1
  110. package/dist/main.js +73 -103
  111. package/dist/main.js.map +1 -1
  112. package/dist/{modelPropertyRecordSchemas-C5lW9aA-.js → modelPropertyRecordSchemas-onFOG2x6.js} +4 -4
  113. package/dist/{modelPropertyRecordSchemas-C5lW9aA-.js.map → modelPropertyRecordSchemas-onFOG2x6.js.map} +1 -1
  114. package/dist/node.js +9 -9
  115. package/dist/node.js.map +1 -1
  116. package/dist/platform.browser.js +5 -5
  117. package/dist/platform.node.js +4 -4
  118. package/dist/{property-BwYtg5Q_.js → property-C85DCD7K.js} +6 -6
  119. package/dist/{property-BwYtg5Q_.js.map → property-C85DCD7K.js.map} +1 -1
  120. package/dist/{propertyValidationRules-CyHdpcPP.js → propertyValidationRules-CjUPOFeu.js} +6 -6
  121. package/dist/{propertyValidationRules-CyHdpcPP.js.map → propertyValidationRules-CjUPOFeu.js.map} +1 -1
  122. package/dist/{publishDraftGraph-C5F6b7GK.js → publishDraftGraph-DBWAN72w.js} +9 -9
  123. package/dist/{publishDraftGraph-C5F6b7GK.js.map → publishDraftGraph-DBWAN72w.js.map} +1 -1
  124. package/dist/{resolveModelForSyncedSeed-4gO9Hfn2.js → resolveModelForSyncedSeed-fIURvYRV.js} +2 -2
  125. package/dist/{resolveModelForSyncedSeed-4gO9Hfn2.js.map → resolveModelForSyncedSeed-fIURvYRV.js.map} +1 -1
  126. package/dist/seedSchema/MetadataSchema.ts +3 -0
  127. package/dist/src/Item/Item.d.ts.map +1 -1
  128. package/dist/src/Item/service/actors/loadOrCreateItem.d.ts.map +1 -1
  129. package/dist/src/ItemProperty/ItemProperty.d.ts +26 -0
  130. package/dist/src/ItemProperty/ItemProperty.d.ts.map +1 -1
  131. package/dist/src/ItemProperty/service/actors/loadOrCreateProperty.d.ts.map +1 -1
  132. package/dist/src/ItemProperty/service/actors/saveValueToDb/analyzeInput.d.ts.map +1 -1
  133. package/dist/src/ItemProperty/service/actors/saveValueToDb/saveFile.d.ts.map +1 -1
  134. package/dist/src/ItemProperty/service/actors/saveValueToDb/saveImage.d.ts.map +1 -1
  135. package/dist/src/ItemProperty/service/propertyMachine.d.ts +4 -1
  136. package/dist/src/ItemProperty/service/propertyMachine.d.ts.map +1 -1
  137. package/dist/src/browser/db/drizzleFiles.d.ts +3 -2
  138. package/dist/src/browser/db/drizzleFiles.d.ts.map +1 -1
  139. package/dist/src/db/read/getPropertyClear.d.ts +45 -0
  140. package/dist/src/db/read/getPropertyClear.d.ts.map +1 -0
  141. package/dist/src/db/read/getPublishPayload.d.ts.map +1 -1
  142. package/dist/src/db/read/getPublishPendingDiff.d.ts +5 -0
  143. package/dist/src/db/read/getPublishPendingDiff.d.ts.map +1 -1
  144. package/dist/src/db/read/summarizePublishWork.d.ts +5 -0
  145. package/dist/src/db/read/summarizePublishWork.d.ts.map +1 -1
  146. package/dist/src/db/write/markPropertyAttestationsRetracted.d.ts +11 -0
  147. package/dist/src/db/write/markPropertyAttestationsRetracted.d.ts.map +1 -0
  148. package/dist/src/db/write/updateItemPropertyValue.d.ts +2 -0
  149. package/dist/src/db/write/updateItemPropertyValue.d.ts.map +1 -1
  150. package/dist/src/events/item/syncDbWithEas.d.ts.map +1 -1
  151. package/dist/src/helpers/compareMetadataRowsLatestFirst.d.ts +9 -9
  152. package/dist/src/helpers/compareMetadataRowsLatestFirst.d.ts.map +1 -1
  153. package/dist/src/helpers/metadataPropertyNames.d.ts +6 -1
  154. package/dist/src/helpers/metadataPropertyNames.d.ts.map +1 -1
  155. package/dist/src/index.d.ts +3 -1
  156. package/dist/src/index.d.ts.map +1 -1
  157. package/dist/src/interfaces/IItemProperty.d.ts +4 -0
  158. package/dist/src/interfaces/IItemProperty.d.ts.map +1 -1
  159. package/dist/src/node/index.d.ts +1 -1
  160. package/dist/src/node/index.d.ts.map +1 -1
  161. package/dist/src/outbox/itemAppliers.d.ts +7 -0
  162. package/dist/src/outbox/itemAppliers.d.ts.map +1 -1
  163. package/dist/src/outbox/pendingValues.d.ts.map +1 -1
  164. package/dist/src/seedSchema/MetadataSchema.d.ts +17 -0
  165. package/dist/src/seedSchema/MetadataSchema.d.ts.map +1 -1
  166. package/dist/src/types/property.d.ts +8 -0
  167. package/dist/src/types/property.d.ts.map +1 -1
  168. package/dist/{syncDbWithEas-DUu_wjUG.js → syncDbWithEas-BMHoou6X.js} +47 -23
  169. package/dist/syncDbWithEas-BMHoou6X.js.map +1 -0
  170. package/dist/{tolerantWebAccess-DecKDGen.js → tolerantWebAccess-BHndShch.js} +6 -6
  171. package/dist/{tolerantWebAccess-DecKDGen.js.map → tolerantWebAccess-BHndShch.js.map} +1 -1
  172. package/dist/{updateSeedRevokedAt-CP606vKs.js → updateSeedRevokedAt-DpfG6ztE.js} +3 -3
  173. package/dist/{updateSeedRevokedAt-CP606vKs.js.map → updateSeedRevokedAt-DpfG6ztE.js.map} +1 -1
  174. package/package.json +6 -6
  175. package/dist/ClientManager-GZfXErDX.js.map +0 -1
  176. package/dist/Item-0oDoTPhi.js.map +0 -1
  177. package/dist/dist/Item-0oDoTPhi.d.ts.map +0 -1
  178. package/dist/dist/backfillMetadataPropertyIds-BbxgavEQ.d.ts.map +0 -1
  179. package/dist/dist/configurePlatform-CrMafpMW.d.ts.map +0 -1
  180. package/dist/dist/detachRowsBeforeDelete-DXFYSHRR.d.ts.map +0 -1
  181. package/dist/dist/eas-dyepi5jz.d.ts.map +0 -1
  182. package/dist/dist/findSeedRowsByUid-CT3sOXXw.d.ts.map +0 -1
  183. package/dist/dist/getItem-Bhjecbia.d.ts.map +0 -1
  184. package/dist/dist/getPublishPayload-DH4rMqXG.d.ts.map +0 -1
  185. package/dist/dist/index-CkYb3wcU.d.ts.map +0 -1
  186. package/dist/dist/index-DJmWkVIK.d.ts.map +0 -1
  187. package/dist/dist/index-Dx_GTdyQ.d.ts.map +0 -1
  188. package/dist/dist/modelPropertyRecordSchemas-C5lW9aA-.d.ts.map +0 -1
  189. package/dist/dist/property-BwYtg5Q_.d.ts.map +0 -1
  190. package/dist/dist/propertyValidationRules-CyHdpcPP.d.ts.map +0 -1
  191. package/dist/dist/resolveModelForSyncedSeed-4gO9Hfn2.d.ts.map +0 -1
  192. package/dist/dist/syncDbWithEas-DUu_wjUG.d.ts.map +0 -1
  193. package/dist/dist/updateSeedRevokedAt-CP606vKs.d.ts.map +0 -1
  194. package/dist/getPublishPayload-DH4rMqXG.js.map +0 -1
  195. package/dist/index-CkYb3wcU.js.map +0 -1
  196. package/dist/index-DJmWkVIK.js.map +0 -1
  197. package/dist/index-Dx_GTdyQ.js.map +0 -1
  198. package/dist/index-PbnKw2es.js.map +0 -1
  199. package/dist/index.browser-i9uPJice.js.map +0 -1
  200. package/dist/syncDbWithEas-DUu_wjUG.js.map +0 -1
@@ -1,6 +1,6 @@
1
- import { u as timingNow, v as timingSince, x as timingLogger, y as TAB_ID, o as onTabMessage, c as whenLeaderTab, a as isLeaderTab, k as postTabMessage, f as createSessionObjectUrl, t as timingMarks, z as timed, r as notifyFileSaved, B as revokeSessionObjectUrl, b as watchEntityRows, C as queryEntityRows, D as isSessionObjectUrl, E as timedDb } from './changeFeed-DKdVlUmt.js';
1
+ import { u as timingNow, v as timingSince, x as timingLogger, y as TAB_ID, o as onTabMessage, c as whenLeaderTab, a as isLeaderTab, k as postTabMessage, f as createSessionObjectUrl, t as timingMarks, z as timed, r as notifyFileSaved, B as revokeSessionObjectUrl, b as watchEntityRows, C as queryEntityRows, D as isSessionObjectUrl, E as timedDb } from './changeFeed-M8sGbOrW.js';
2
2
  import { waitFor, fromCallback, setup, assign, stateIn, createActor, isMachineSnapshot } from 'xstate';
3
- import { L as BaseDb, v as versions, m as metadata, s as seeds, N as resolveStorageNameToSchemaName, aY as toSchemaPropertyName, i as isDataType, ad as generateId, C as pendingWrites, ak as isSqliteBusyError, J as schemas, p as models, z as modelSchemas, aW as getOwnedAddressesFromDb, a0 as ZERO_BYTES32, aB as normalizeAddressList, ae as normalizeHexAddress, ax as getAddressesForItemsFilter, a2 as INTERNAL_PROPERTY_NAMES, aZ as easSchemaDefinitionForProperty, Q as BaseFileManager, a_ as getStorageTransactionIdForSeedUid, a$ as convertTxIdToImage, a8 as normalizePublisher, a6 as listRelationEasPropertyName, n as normalizeDataType, U as resolveItemModelFileId, b0 as getPropertyIdForSchemaFileId, S as getPropertyIdForModelAndName, aU as getMetadataPropertyNamesForQuery, aw as ensureImageLocal, ap as ImageSize, b1 as downloadTransactionIdWithDedupe, b2 as resolveMetadataRecord, M as ModelPropertyDataTypes, o as modelUids, af as toMetadataPropertyName, b3 as getDataTypeFromString, b4 as getMimeType, V as INTERNAL_STORAGE_MODEL_FILE_IDS, g as normalizePropertyRecordSchema, b5 as listRelationStoragePropertyName, b6 as PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP, k as getCorrectId, Z as getItemStorageSubdir, _ as getItemStorageLocalFileName, b7 as toItemPropertyKey, b8 as getAlternatePropertyNameForInstanceLookup, E as properties, a3 as isStorageSeedRef } from './index-Dx_GTdyQ.js';
3
+ import { L as BaseDb, v as versions, m as metadata, s as seeds, N as resolveStorageNameToSchemaName, aY as toSchemaPropertyName, i as isDataType, a5 as generateId, C as pendingWrites, al as isSqliteBusyError, J as schemas, p as models, z as modelSchemas, aW as getOwnedAddressesFromDb, ad as ZERO_BYTES32, aC as normalizeAddressList, a6 as normalizeHexAddress, ay as getAddressesForItemsFilter, af as INTERNAL_PROPERTY_NAMES, aZ as easSchemaDefinitionForProperty, Q as BaseFileManager, a_ as getStorageTransactionIdForSeedUid, a$ as convertTxIdToImage, a0 as normalizePublisher, a7 as listRelationEasPropertyName, n as normalizeDataType, U as resolveItemModelFileId, b0 as getPropertyIdForSchemaFileId, S as getPropertyIdForModelAndName, ab as getMetadataPropertyNamesForQuery, ax as ensureImageLocal, aq as ImageSize, b1 as downloadTransactionIdWithDedupe, b2 as resolveMetadataRecord, M as ModelPropertyDataTypes, o as modelUids, a9 as toMetadataPropertyName, b3 as getDataTypeFromString, b4 as getMimeType, V as INTERNAL_STORAGE_MODEL_FILE_IDS, g as normalizePropertyRecordSchema, b5 as listRelationStoragePropertyName, b6 as PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP, k as getCorrectId, Z as getItemStorageSubdir, _ as getItemStorageLocalFileName, b7 as toItemPropertyKey, b8 as getAlternatePropertyNameForInstanceLookup, E as properties, ag as isStorageSeedRef } from './index-rOTW-2QZ.js';
4
4
  import { or, isNull, eq, sql, max, count, and, getTableColumns, asc, inArray, lt, isNotNull, desc, gt } from 'drizzle-orm';
5
5
  import pluralize from 'pluralize';
6
6
  import debug from 'debug';
@@ -437,31 +437,29 @@ var versionData = /*#__PURE__*/Object.freeze({
437
437
  * Canonical "latest metadata row first" ordering, the one readers use to pick a property's value
438
438
  * from its rows across versions:
439
439
  *
440
- * 1. Live rows (`revoked_at IS NULL`) before revoked ones. A synced row with `revoked_at` set is
441
- * kept only because every attestation of that property on its version is revoked (ADR 0006);
442
- * it must not hide a live value from another version, but is still the value to show when no
443
- * live row is left (an unpublished item keeps its last values). Local drafts (no uid) are live.
444
- * 2. Newest first: `COALESCE(attestation_created_at, created_at)`.
445
- * 3. Tie-break on `local_id`, descending.
440
+ * 1. Newest first: `COALESCE(attestation_created_at, created_at)`. A revoked row counts like any
441
+ * other. Sync keeps one attestation per version and property schema (the newest live one, else
442
+ * the newest revoked one, ADR 0006), so a revoked row is the newest only when its whole version
443
+ * has none live: on a live seed that is a retraction, stored with no value, and an earlier
444
+ * version's value must not show through it (ADR 0021); on an unpublished seed every row is
445
+ * revoked and keeps its last value.
446
+ * 2. Tie-break on `local_id`, descending.
446
447
  *
447
448
  * {@link METADATA_LATEST_FIRST_ORDER_SQL} is the same ordering in SQL. SQL that can't take a
448
449
  * fragment (e.g. liveQuery tagged templates, where every interpolation is a bound value) spells it
449
450
  * out; keep those in sync.
450
451
  */
451
- const METADATA_LATEST_FIRST_ORDER_SQL = '(revoked_at IS NOT NULL), COALESCE(attestation_created_at, created_at) DESC, local_id DESC';
452
+ const METADATA_LATEST_FIRST_ORDER_SQL = 'COALESCE(attestation_created_at, created_at) DESC, local_id DESC';
452
453
  function metadataLatestFirstSortKey(row) {
453
454
  return {
454
- revoked: row.revokedAt != null,
455
455
  t: row.attestationCreatedAt ?? row.createdAt ?? 0,
456
456
  localId: String(row.localId ?? ''),
457
457
  };
458
458
  }
459
- /** Sort comparator: live before revoked; then larger time first; on tie, larger localId (lexicographic) first. */
459
+ /** Sort comparator: larger time first; on tie, larger localId (lexicographic) first. */
460
460
  function compareMetadataRowsLatestFirst(a, b) {
461
461
  const ka = metadataLatestFirstSortKey(a);
462
462
  const kb = metadataLatestFirstSortKey(b);
463
- if (ka.revoked !== kb.revoked)
464
- return ka.revoked ? 1 : -1;
465
463
  if (kb.t !== ka.t)
466
464
  return kb.t - ka.t;
467
465
  return kb.localId.localeCompare(ka.localId);
@@ -549,8 +547,16 @@ function metadataValueStrength(row) {
549
547
  return 0;
550
548
  return String(v).trim().length;
551
549
  }
552
- /** When storage + schema names map to the same key, prefer non-empty, then richer payload, then newer row. */
550
+ /** A `<name>Id` row with no value and no file: a cleared Image, File, Html or Relation (ADR 0021). */
551
+ const isClearedIdRow = (row) => !!row?.propertyName?.endsWith('Id') && row.propertyValue === null && !row.refResolvedValue;
552
+ /**
553
+ * When storage + schema names map to the same key, prefer non-empty, then richer payload, then newer
554
+ * row. A cleared Id row newer than the other wins: the other is the value it cleared, or older.
555
+ */
553
556
  function pickBetterMetadataRowForSameInstance(a, b) {
557
+ const newer = compareMetadataRowsLatestFirst(a, b) < 0 ? a : b;
558
+ if (isClearedIdRow(newer))
559
+ return newer;
554
560
  const sa = metadataValueStrength(a);
555
561
  const sb = metadataValueStrength(b);
556
562
  if (sa > 0 && sb === 0)
@@ -594,7 +600,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
594
600
  const itemPropertyMod = await Promise.resolve().then(function () { return ItemProperty$1; });
595
601
  const { ItemProperty } = itemPropertyMod;
596
602
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
597
- const _mod_0 = await import('./errors-D1zHAqjr.js');
603
+ const _mod_0 = await import('./errors-CS3nDpUU.js');
598
604
  const _ns_0 = _mod_0.i;
599
605
  const { Model } = _ns_0;
600
606
  // Resolve Model and build property schemas (use getByNameAsync for models not yet in cache)
@@ -612,7 +618,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
612
618
  const schemaNameToTry = schemaName ?? model?.schemaName;
613
619
  if (schemaNameToTry) {
614
620
  try {
615
- const _mod_1 = await import('./Schema-PFZwG9Nl.js');
621
+ const _mod_1 = await import('./Schema-BS8oR7QV.js');
616
622
  const _ns_1 = _mod_1.a;
617
623
  const { Schema } = _ns_1;
618
624
  const schemaInstance = Schema.create(schemaNameToTry, { waitForReady: false, hold: false });
@@ -628,7 +634,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
628
634
  }
629
635
  if (Object.keys(propertySchemas).length === 0) {
630
636
  try {
631
- const _mod_2 = await import('./ClientManager-GZfXErDX.js');
637
+ const _mod_2 = await import('./ClientManager-DqL0q_eu.js');
632
638
  const _ns_2 = _mod_2.S;
633
639
  const { loadAllSchemasFromDb } = _ns_2;
634
640
  const allSchemas = await loadAllSchemasFromDb();
@@ -649,10 +655,10 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
649
655
  }
650
656
  if (Object.keys(propertySchemas).length === 0) {
651
657
  try {
652
- const _mod_3 = await import('./ClientManager-GZfXErDX.js');
658
+ const _mod_3 = await import('./ClientManager-DqL0q_eu.js');
653
659
  const _ns_3 = _mod_3.S;
654
660
  const { listCompleteSchemaFiles } = _ns_3;
655
- const _mod_4 = await import('./index-Dx_GTdyQ.js');
661
+ const _mod_4 = await import('./index-rOTW-2QZ.js');
656
662
  const _ns_4 = _mod_4.bb;
657
663
  const { BaseFileManager } = _ns_4;
658
664
  const schemaFiles = await listCompleteSchemaFiles();
@@ -673,7 +679,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
673
679
  }
674
680
  }
675
681
  if (Object.keys(propertySchemas).length === 0) {
676
- const schemaMod = await import('./index-DJmWkVIK.js');
682
+ const schemaMod = await import('./index-DQoyhp2c.js');
677
683
  const { ModelPropertyDataTypes } = schemaMod;
678
684
  const KNOWN_MODEL_FALLBACKS = {
679
685
  Post: {
@@ -690,7 +696,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
690
696
  }
691
697
  }
692
698
  // Fallbacks above may return schema-file shape ({ type, model, items }); normalize to dataType/ref/refValueType.
693
- const { normalizePropertyRecordSchema } = await import('./property-BwYtg5Q_.js');
699
+ const { normalizePropertyRecordSchema } = await import('./property-C85DCD7K.js');
694
700
  propertySchemas = Object.fromEntries(Object.entries(propertySchemas).map(([name, def]) => [name, normalizePropertyRecordSchema(def)]));
695
701
  // Collapse rows that map to the same instance key (e.g. authorIdentityIds + authors -> authors).
696
702
  // ItemProperty.create cache does not sync propertyValue on hit; processing order would otherwise
@@ -723,7 +729,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
723
729
  // Infer propertyRecordSchema from metadata when schema is missing (enables persistence)
724
730
  let propSchema = propertySchemas[propertyName];
725
731
  if (!propSchema && isRefTypeFromMeta) {
726
- const schemaMod = await import('./index-DJmWkVIK.js');
732
+ const schemaMod = await import('./index-DQoyhp2c.js');
727
733
  const { ModelPropertyDataTypes } = schemaMod;
728
734
  propSchema = {
729
735
  dataType: refSeedType === 'html' ? ModelPropertyDataTypes.Html
@@ -1727,7 +1733,12 @@ const isItemStorageOp = (value) => typeof value === 'object' && value !== null &
1727
1733
  function overlayOf(op) {
1728
1734
  if (op.kind === 'set') {
1729
1735
  const value = outboxOpValue(op);
1730
- return value ? { propertyValue: value.newValue ?? null } : undefined;
1736
+ if (!value)
1737
+ return undefined;
1738
+ // A clear drops the file reference too, so the old image doesn't show while the op waits
1739
+ return value.clear
1740
+ ? { propertyValue: null, refSeedType: null, refResolvedValue: null, refResolvedDisplayValue: null, localStorageDir: null }
1741
+ : { propertyValue: value.newValue ?? null };
1731
1742
  }
1732
1743
  const value = outboxOpValue(op);
1733
1744
  if (!value)
@@ -2386,7 +2397,7 @@ const getItemsData = async ({ modelName, modelFileId, schemaName, deleted, inclu
2386
2397
  conditions.push(eq(seeds.type, easName(modelName)));
2387
2398
  }
2388
2399
  if (!modelFileId && schemaName && modelName) {
2389
- const _mod_5 = await import('./index-Dx_GTdyQ.js');
2400
+ const _mod_5 = await import('./index-rOTW-2QZ.js');
2390
2401
  const _ns_5 = _mod_5.be;
2391
2402
  const { resolveModelRecord } = _ns_5;
2392
2403
  modelFileId = (await resolveModelRecord(modelName, { schemaName }))?.schemaFileId ?? undefined;
@@ -2614,7 +2625,7 @@ const resolveRelatedValue = fromCallback(({ sendBack, input: { context } }) => {
2614
2625
  const { isRelation, propertyValue, propertyName, propertyRecordSchema, populatedFromDb, } = context;
2615
2626
  const _resolveRelatedValue = async () => {
2616
2627
  // Use dynamic import to break circular dependency
2617
- const schemaMod = await import('./index-DJmWkVIK.js');
2628
+ const schemaMod = await import('./index-DQoyhp2c.js');
2618
2629
  const { ModelPropertyDataTypes } = schemaMod;
2619
2630
  if (!propertyValue || !isRelation || populatedFromDb) {
2620
2631
  return;
@@ -3028,7 +3039,7 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
3028
3039
  propertyRecordSchema?.validation &&
3029
3040
  metadataValues.propertyValue != null &&
3030
3041
  metadataValues.propertyValue !== '') {
3031
- const { SchemaValidationService } = await import('./SchemaValidationService-DnGKel4V.js');
3042
+ const { SchemaValidationService } = await import('./SchemaValidationService-CZzKNL04.js');
3032
3043
  const validationService = new SchemaValidationService();
3033
3044
  const validationResult = validationService.validatePropertyValue(metadataValues.propertyValue, normalizeDataType(propertyRecordSchema.dataType), propertyRecordSchema.validation, propertyRecordSchema.refValueType
3034
3045
  ? normalizeDataType(String(propertyRecordSchema.refValueType))
@@ -3236,7 +3247,7 @@ async function readHtmlBodyFromChildStorageArweave(seedLocalId) {
3236
3247
  /* offline / bad tx id */
3237
3248
  }
3238
3249
  try {
3239
- const _mod_6 = await import('./index-Dx_GTdyQ.js');
3250
+ const _mod_6 = await import('./index-rOTW-2QZ.js');
3240
3251
  const _ns_6 = _mod_6.bg;
3241
3252
  const { downloadTransactionIdWithDedupe } = _ns_6;
3242
3253
  await downloadTransactionIdWithDedupe(txId);
@@ -3297,7 +3308,7 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
3297
3308
  // to use dynamically imported ModelPropertyDataTypes
3298
3309
  const _hydrateFromDb = async () => {
3299
3310
  // Use dynamic import to break circular dependency
3300
- const schemaMod = await import('./index-DJmWkVIK.js');
3311
+ const schemaMod = await import('./index-DQoyhp2c.js');
3301
3312
  const { ModelPropertyDataTypes } = schemaMod;
3302
3313
  const appDb = BaseDb.getAppDb();
3303
3314
  const whereClauses = [];
@@ -3345,7 +3356,7 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
3345
3356
  }
3346
3357
  const stored = rows?.[0] ?? { seedLocalId, seedUid, propertyName };
3347
3358
  const firstRow = pending ? applyPendingRow({ ...stored }, pending) : { ...stored };
3348
- const _mod_7 = await import('./ClientManager-GZfXErDX.js');
3359
+ const _mod_7 = await import('./ClientManager-DqL0q_eu.js');
3349
3360
  const _ns_7 = _mod_7.U;
3350
3361
  const { getPropertyConflict } = _ns_7;
3351
3362
  const conflict = await getPropertyConflict(firstRow.seedLocalId ?? seedLocalId, propertyName);
@@ -3604,11 +3615,11 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
3604
3615
  const modelNameForNew = context.modelName;
3605
3616
  if (modelNameForNew) {
3606
3617
  try {
3607
- const _mod_8 = await import('./errors-D1zHAqjr.js');
3618
+ const _mod_8 = await import('./errors-CS3nDpUU.js');
3608
3619
  const _ns_8 = _mod_8.i;
3609
3620
  const { Model } = _ns_8;
3610
3621
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
3611
- const _mod_9 = await import('./index-Dx_GTdyQ.js');
3622
+ const _mod_9 = await import('./index-rOTW-2QZ.js');
3612
3623
  const _ns_9 = _mod_9.be;
3613
3624
  const { resolveItemModelFileId } = _ns_9;
3614
3625
  const normalizedModelName = upperFirst(camelCase(modelNameForNew));
@@ -3670,7 +3681,7 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
3670
3681
  // It ends up in the context below, and later lookups by name (Model.getByName) can't match it.
3671
3682
  const modelName = context.modelName || (metadataRecord.modelType ? upperFirst(camelCase(metadataRecord.modelType)) : undefined);
3672
3683
  // Model names are only unique per schema: pin lookups to the item's own model row.
3673
- const _mod_10 = await import('./index-Dx_GTdyQ.js');
3684
+ const _mod_10 = await import('./index-rOTW-2QZ.js');
3674
3685
  const _ns_10 = _mod_10.be;
3675
3686
  const { resolveItemModelFileId } = _ns_10;
3676
3687
  const modelFileId = await resolveItemModelFileId({
@@ -3685,7 +3696,7 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
3685
3696
  // Normalize snake_case to PascalCase: "test_post" -> "TestPost" (startCase gives "Test Post" which fails)
3686
3697
  const normalizedModelName = upperFirst(camelCase(modelName));
3687
3698
  // One read for the whole model, shared by the item's other properties loading now
3688
- const { loadModelPropertyRecordSchemas } = await import('./modelPropertyRecordSchemas-C5lW9aA-.js');
3699
+ const { loadModelPropertyRecordSchemas } = await import('./modelPropertyRecordSchemas-onFOG2x6.js');
3689
3700
  const schemas = await loadModelPropertyRecordSchemas(normalizedModelName, modelFileId, db);
3690
3701
  propertyRecordSchema = schemas.get(propertyName);
3691
3702
  timing.mark('model schema');
@@ -3698,7 +3709,7 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
3698
3709
  // Fix 1: Fallback to in-memory Model when DB doesn't have model/properties yet (e.g. runtime-created model)
3699
3710
  if (!propertyRecordSchema && modelName) {
3700
3711
  try {
3701
- const _mod_11 = await import('./errors-D1zHAqjr.js');
3712
+ const _mod_11 = await import('./errors-CS3nDpUU.js');
3702
3713
  const _ns_11 = _mod_11.i;
3703
3714
  const { Model } = _ns_11;
3704
3715
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
@@ -3869,6 +3880,9 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
3869
3880
  propertyValueOut = parseListPropertyValueFromStorage(propertyValueOut);
3870
3881
  renderValue = propertyValueOut;
3871
3882
  }
3883
+ // A stored row with no value is a cleared property (ADR 0021): send null so the machine drops
3884
+ // what context held (undefined keeps it).
3885
+ const cleared = metadataRecord.propertyValue === null && !metadataRecord.refResolvedValue;
3872
3886
  timing.mark('value');
3873
3887
  timing.log(timingLabel);
3874
3888
  // Return loaded property data (use propertyName from context to match schema key, e.g. "html" not "htmlId")
@@ -3876,8 +3890,8 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
3876
3890
  type: 'loadOrCreatePropertySuccess',
3877
3891
  property: {
3878
3892
  propertyName,
3879
- propertyValue: propertyValueOut,
3880
- renderValue,
3893
+ propertyValue: propertyValueOut ?? (cleared ? null : undefined),
3894
+ renderValue: renderValue ?? (cleared ? null : undefined),
3881
3895
  seedLocalId: metadataRecord.seedLocalId || seedLocalId,
3882
3896
  seedUid: metadataRecord.seedUid || seedUid,
3883
3897
  versionLocalId: metadataRecord.versionLocalId || versionLocalId,
@@ -3889,7 +3903,7 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
3889
3903
  modelFileId: modelFileId ?? context.modelFileId,
3890
3904
  propertyRecordSchema,
3891
3905
  refSeedType: refSeedType ?? context.refSeedType,
3892
- refResolvedValue: metadataRecord.refResolvedValue ?? context.refResolvedValue,
3906
+ refResolvedValue: metadataRecord.refResolvedValue ?? (cleared ? null : context.refResolvedValue),
3893
3907
  refResolvedDisplayValue,
3894
3908
  localStorageDir: metadataRecord.localStorageDir ?? context.localStorageDir ?? (normalizedDataType === 'Image' ? '/images' : undefined),
3895
3909
  },
@@ -3927,13 +3941,14 @@ const getVersionData = async ({ localId, seedLocalId, uid, }, db = BaseDb.getApp
3927
3941
  };
3928
3942
 
3929
3943
  const logger$2 = debug('seedSdk:write:updateItemPropertyValue');
3930
- const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, newValue, seedUid, seedLocalId, modelName, refSeedType, refResolvedValue, refResolvedDisplayValue, versionLocalId, versionUid, schemaUid, localStorageDir, dataType, refValueType, }, options = {}) => {
3944
+ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, newValue, seedUid, seedLocalId, modelName, refSeedType, refResolvedValue, refResolvedDisplayValue, versionLocalId, versionUid, schemaUid, localStorageDir, dataType, refValueType, retract, }, options = {}) => {
3931
3945
  if (!localIdParam && !seedLocalId) {
3932
3946
  logger$2(`[db/write] [updateItemPropertyValue] no propertyLocalId or seedLocalId for property: ${propertyName}`);
3933
3947
  return;
3934
3948
  }
3935
3949
  // Every write below binds parameters: store the value as given (no SQL escaping).
3936
3950
  const safeNewValue = newValue;
3951
+ const retractValue = retract && newValue == null ? true : null;
3937
3952
  const appDb = options.db ?? BaseDb.getAppDb();
3938
3953
  // Path 1: When localId is provided, query by local_id first (avoids property name mismatch)
3939
3954
  let rows;
@@ -3990,14 +4005,15 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
3990
4005
  rows = newestRows;
3991
4006
  }
3992
4007
  if (rows && rows.length > 0) {
3993
- const { localId, uid, propertyName: propertyNameFromDb, propertyValue: propertyValueFromDb, modelType, seedLocalId: seedLocalIdFromDb, versionLocalId, schemaUid, easDataType, refSeedType: refSeedTypeFromDb, refResolvedValue: refResolvedValueFromDb, } = rows[0];
4008
+ const { localId, uid, propertyName: propertyNameFromDb, propertyValue: propertyValueFromDb, modelType, seedLocalId: seedLocalIdFromDb, versionLocalId, schemaUid, easDataType, refSeedType: refSeedTypeFromDb, refResolvedValue: refResolvedValueFromDb, retract: retractFromDb, } = rows[0];
3994
4009
  // Stored model types are the model's EAS name (ADR 0008): `blog_post` for BlogPost.
3995
4010
  const modelTypeForName = modelName ? easName(modelName) : undefined;
3996
4011
  if (propertyValueFromDb === newValue &&
3997
4012
  modelType === modelTypeForName &&
3998
4013
  // The DB holds null where callers leave a field out (plain values pass no ref fields).
3999
4014
  (refSeedTypeFromDb ?? null) === (refSeedType ?? null) &&
4000
- (refResolvedValueFromDb ?? null) === (refResolvedValue ?? null)) {
4015
+ (refResolvedValueFromDb ?? null) === (refResolvedValue ?? null) &&
4016
+ !!retractFromDb === !!retractValue) {
4001
4017
  logger$2(`[db/write] [updateItemPropertyValue] value is the same as most recent record for property: ${propertyNameFromDb}`);
4002
4018
  return localId == null ? undefined : { localId, uid: uid ?? null, schemaUid: schemaUid ?? '' };
4003
4019
  }
@@ -4012,6 +4028,7 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
4012
4028
  refSeedType: refSeedType ?? null,
4013
4029
  refResolvedValue: refResolvedValue ?? null,
4014
4030
  refResolvedDisplayValue: refResolvedDisplayValue ?? null,
4031
+ retract: retractValue,
4015
4032
  // Readers take the newest row by COALESCE(attestation_created_at, created_at), so a draft's
4016
4033
  // time is when its value was last set: a synced value older than this edit mustn't win.
4017
4034
  createdAt: now,
@@ -4047,6 +4064,7 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
4047
4064
  refResolvedValue: refResolvedValue || null,
4048
4065
  refResolvedDisplayValue: refResolvedDisplayValue || null,
4049
4066
  localStorageDir: localStorageDir || null,
4067
+ retract: retractValue,
4050
4068
  });
4051
4069
  return {
4052
4070
  localId: newLocalId,
@@ -4084,6 +4102,7 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
4084
4102
  refResolvedValue: refResolvedValue || null,
4085
4103
  refResolvedDisplayValue: refResolvedDisplayValue || null,
4086
4104
  localStorageDir: localStorageDir || null,
4105
+ retract: retractValue,
4087
4106
  });
4088
4107
  return {
4089
4108
  localId: newLocalId,
@@ -4158,7 +4177,7 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
4158
4177
  const result = await updateItemPropertyValue({ ...props, seedLocalId, propertyName: propertyNameRaw });
4159
4178
  return { skipped: false, result, conflict: null };
4160
4179
  }
4161
- const { appendOutboxOp, getOutboxOps, outboxOpResult, startItemOutbox, throwItemWriteError, waitForOutboxOp } = await import('./index-CkYb3wcU.js');
4180
+ const { appendOutboxOp, getOutboxOps, outboxOpResult, startItemOutbox, throwItemWriteError, waitForOutboxOp } = await import('./index-njjjo74v.js');
4162
4181
  startItemOutbox();
4163
4182
  // Checked right before appending (no await in between): ops apply in append order
4164
4183
  if (writeTicket && !writeTicket.isLatest())
@@ -4189,13 +4208,43 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
4189
4208
  return false;
4190
4209
  }
4191
4210
  // Use dynamic import to break circular dependency
4192
- const schemaMod = await import('./index-DJmWkVIK.js');
4211
+ const schemaMod = await import('./index-DQoyhp2c.js');
4193
4212
  const { ModelPropertyDataTypes } = schemaMod;
4194
- const { SchemaValidationService } = await import('./SchemaValidationService-DnGKel4V.js');
4213
+ const { SchemaValidationService } = await import('./SchemaValidationService-CZzKNL04.js');
4195
4214
  const propertyName = propertyNameRaw;
4196
4215
  if (!propertyName) {
4197
4216
  throw new Error('propertyName is required');
4198
4217
  }
4218
+ // A clear (ADR 0021): a null value with no file reference, written like a plain value. The old
4219
+ // storage seed and its file stay, as when a value is replaced.
4220
+ if (event?.clear) {
4221
+ const written = await timed(`${label} write`, () => writePlainValue({
4222
+ localId,
4223
+ newValue: null,
4224
+ versionLocalId,
4225
+ versionUid,
4226
+ modelName,
4227
+ schemaUid,
4228
+ dataType: propertyRecordSchema.dataType,
4229
+ refValueType: propertyRecordSchema.refValueType,
4230
+ clear: event.clear,
4231
+ }));
4232
+ if (written.skipped)
4233
+ return true;
4234
+ sendBack({
4235
+ type: 'updateContext',
4236
+ propertyValue: null,
4237
+ renderValue: null,
4238
+ refResolvedValue: undefined,
4239
+ refResolvedDisplayValue: undefined,
4240
+ localStorageDir: undefined,
4241
+ storageTransactionId: undefined,
4242
+ retract: event.clear.retract || undefined,
4243
+ conflict: written.conflict ?? null,
4244
+ ...rowContext(written.result),
4245
+ });
4246
+ return true;
4247
+ }
4199
4248
  if (normalizeDataType(propertyRecordSchema.dataType) === ModelPropertyDataTypes.List &&
4200
4249
  typeof newValue === 'string' &&
4201
4250
  newValue.trim() !== '') {
@@ -4210,6 +4259,26 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
4210
4259
  }
4211
4260
  const normalizedDataType = normalizeDataType(propertyRecordSchema.dataType);
4212
4261
  const normalizedRefValueType = normalizeDataType(propertyRecordSchema.refValueType);
4262
+ // An empty Image, File or Html value is a clear (ItemProperty.setValue sends one). Refused when
4263
+ // it arrives as a value: saveImage would take '' for the images folder itself.
4264
+ const isStorageSeedValue = normalizedRefValueType === ModelPropertyDataTypes.Image ||
4265
+ normalizedDataType === ModelPropertyDataTypes.Image ||
4266
+ normalizedDataType === ModelPropertyDataTypes.File ||
4267
+ normalizedDataType === ModelPropertyDataTypes.Html;
4268
+ if (isStorageSeedValue && (newValue == null || (typeof newValue === 'string' && newValue.trim() === ''))) {
4269
+ sendBack({
4270
+ type: 'saveValueValidationError',
4271
+ errors: [
4272
+ {
4273
+ field: 'value',
4274
+ message: `${propertyName} can't be saved empty: use clear() to remove a ${propertyRecordSchema.dataType} value`,
4275
+ code: 'empty_storage_value',
4276
+ severity: 'error',
4277
+ },
4278
+ ],
4279
+ });
4280
+ return false;
4281
+ }
4213
4282
  // A Relation with a non-Image refValueType stores the related seed id like any other value,
4214
4283
  // through the write below.
4215
4284
  if (normalizedRefValueType === ModelPropertyDataTypes.Image ||
@@ -4450,7 +4519,7 @@ async function writeStorageValue(item, value, ticket) {
4450
4519
  if (!seedLocalId) {
4451
4520
  throw new Error(`No local seed for the item to save ${item.propertyName} to`);
4452
4521
  }
4453
- const { appendOutboxOp, getOutboxOps, outboxOpResult, startItemOutbox, throwItemWriteError, waitForOutboxOp } = await import('./index-CkYb3wcU.js');
4522
+ const { appendOutboxOp, getOutboxOps, outboxOpResult, startItemOutbox, throwItemWriteError, waitForOutboxOp } = await import('./index-njjjo74v.js');
4454
4523
  startItemOutbox();
4455
4524
  // Checked right before appending (no await in between): ops apply in append order
4456
4525
  if (ticket && !ticket.isLatest()) {
@@ -4517,7 +4586,11 @@ const saveImage = fromCallback(({ sendBack, input: { context, event } }) => {
4517
4586
  // Check before classifying the string: a filename like "photo.png" also matches the URL regex
4518
4587
  // and would otherwise be fetched relative to the page.
4519
4588
  let isExistingFileReference = false;
4520
- if (typeof newValue === 'string' && !newValue.includes('/') && !newValue.startsWith('data:')) {
4589
+ // An empty name would check the images folder itself
4590
+ if (typeof newValue === 'string' &&
4591
+ newValue.trim() !== '' &&
4592
+ !newValue.includes('/') &&
4593
+ !newValue.startsWith('data:')) {
4521
4594
  const existingFilePath = BaseFileManager.getFilesPath('images', newValue);
4522
4595
  if (await BaseFileManager.pathExists(existingFilePath)) {
4523
4596
  isExistingFileReference = true;
@@ -4703,7 +4776,8 @@ async function classifyFileString(value) {
4703
4776
  if (/^(https?:\/\/|blob:)/i.test(value)) {
4704
4777
  return { kind: 'url' };
4705
4778
  }
4706
- if (!/[\\/]/.test(value) && value.length < 256) {
4779
+ // An empty name would check the files folder itself
4780
+ if (value.trim() !== '' && !/[\\/]/.test(value) && value.length < 256) {
4707
4781
  const existingFilePath = BaseFileManager.getFilesPath('files', value);
4708
4782
  if (await BaseFileManager.pathExists(existingFilePath)) {
4709
4783
  return { kind: 'existing' };
@@ -5137,6 +5211,17 @@ const propertyMachine = setup({
5137
5211
  // stateIn return type does not satisfy setup() inference; runtime guard is correct for root state `idle`.
5138
5212
  propertyMachineIsIdle: stateIn('idle'),
5139
5213
  },
5214
+ actions: {
5215
+ /**
5216
+ * A storage save (Image, File, Html, ItemStorage) failed. Each throws before or during its
5217
+ * write, so nothing was stored: restore the shown value, as saveFailed does.
5218
+ */
5219
+ restoreValueAfterSaveError: assign(({ context, event }) => ({
5220
+ _saveError: toError(event.error),
5221
+ ...(context._valueBeforeSave ?? {}),
5222
+ _valueBeforeSave: undefined,
5223
+ })),
5224
+ },
5140
5225
  actors: {
5141
5226
  waitForDb,
5142
5227
  loadOrCreateProperty,
@@ -5342,9 +5427,7 @@ const propertyMachine = setup({
5342
5427
  saveImageSuccess: 'doneSaving',
5343
5428
  saveImageError: {
5344
5429
  target: 'doneSaving',
5345
- actions: assign({
5346
- _saveError: ({ event }) => toError(event.error),
5347
- }),
5430
+ actions: 'restoreValueAfterSaveError',
5348
5431
  },
5349
5432
  },
5350
5433
  invoke: {
@@ -5360,9 +5443,7 @@ const propertyMachine = setup({
5360
5443
  saveFileSuccess: 'doneSaving',
5361
5444
  saveFileError: {
5362
5445
  target: 'doneSaving',
5363
- actions: assign({
5364
- _saveError: ({ event }) => toError(event.error),
5365
- }),
5446
+ actions: 'restoreValueAfterSaveError',
5366
5447
  },
5367
5448
  },
5368
5449
  invoke: {
@@ -5377,9 +5458,7 @@ const propertyMachine = setup({
5377
5458
  saveHtmlSuccess: 'doneSaving',
5378
5459
  saveHtmlError: {
5379
5460
  target: 'doneSaving',
5380
- actions: assign({
5381
- _saveError: ({ event }) => toError(event.error),
5382
- }),
5461
+ actions: 'restoreValueAfterSaveError',
5383
5462
  },
5384
5463
  },
5385
5464
  invoke: {
@@ -5394,9 +5473,7 @@ const propertyMachine = setup({
5394
5473
  saveItemStorageSuccess: 'doneSaving',
5395
5474
  saveItemStorageError: {
5396
5475
  target: 'doneSaving',
5397
- actions: assign({
5398
- _saveError: ({ event }) => toError(event.error),
5399
- }),
5476
+ actions: 'restoreValueAfterSaveError',
5400
5477
  },
5401
5478
  },
5402
5479
  invoke: {
@@ -5439,10 +5516,10 @@ const getPropertyData = async ({ propertyName, seedLocalId, seedUid, modelName,
5439
5516
  let names = [...getMetadataPropertyNamesForQuery(propertyName)];
5440
5517
  if (modelName) {
5441
5518
  try {
5442
- const _mod_12 = await import('./errors-D1zHAqjr.js');
5519
+ const _mod_12 = await import('./errors-CS3nDpUU.js');
5443
5520
  const _ns_12 = _mod_12.i;
5444
5521
  const { Model } = _ns_12;
5445
- const _mod_13 = await import('./index-Dx_GTdyQ.js');
5522
+ const _mod_13 = await import('./index-rOTW-2QZ.js');
5446
5523
  const _ns_13 = _mod_13.be;
5447
5524
  const { resolveItemModelFileId } = _ns_13;
5448
5525
  // Model names are only unique per schema: use the seed's own model when it is recorded.
@@ -5679,7 +5756,7 @@ const HTML_PROP_SEED_UID_RE = /^0x[a-fA-F0-9]{64}$/;
5679
5756
  */
5680
5757
  const resolvePropertyRecordSchemaFromSchemaData = async (modelName, propertyName, modelType, schemaName) => {
5681
5758
  try {
5682
- const _mod_14 = await import('./ClientManager-GZfXErDX.js');
5759
+ const _mod_14 = await import('./ClientManager-DqL0q_eu.js');
5683
5760
  const _ns_14 = _mod_14.S;
5684
5761
  const { loadAllSchemasFromDb } = _ns_14;
5685
5762
  const allSchemas = await loadAllSchemasFromDb();
@@ -5733,11 +5810,11 @@ hints = {}) => {
5733
5810
  return undefined;
5734
5811
  }
5735
5812
  try {
5736
- const _mod_15 = await import('./errors-D1zHAqjr.js');
5813
+ const _mod_15 = await import('./errors-CS3nDpUU.js');
5737
5814
  const _ns_15 = _mod_15.i;
5738
5815
  const { Model } = _ns_15;
5739
5816
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
5740
- const _mod_16 = await import('./index-Dx_GTdyQ.js');
5817
+ const _mod_16 = await import('./index-rOTW-2QZ.js');
5741
5818
  const _ns_16 = _mod_16.be;
5742
5819
  const { resolveItemModelFileId } = _ns_16;
5743
5820
  const modelFileId = await resolveItemModelFileId(hints);
@@ -5845,6 +5922,37 @@ class ItemPropertySaveValidationError extends Error {
5845
5922
  this.name = 'ItemPropertySaveValidationError';
5846
5923
  }
5847
5924
  }
5925
+ /**
5926
+ * Thrown by ItemProperty.clear() for a Boolean or Date property: their EAS types have no empty value
5927
+ * to attest, so only a retraction can clear one (ADR 0021).
5928
+ */
5929
+ class ClearNotSupportedError extends Error {
5930
+ constructor(propertyName, dataType) {
5931
+ super(`${propertyName} can't be cleared: ${dataType} properties have no empty value. Use clear({ retract: true }).`);
5932
+ this.propertyName = propertyName;
5933
+ this.dataType = dataType;
5934
+ this.name = 'ClearNotSupportedError';
5935
+ }
5936
+ }
5937
+ /** Types whose value is a storage seed: an empty value is a clear, not a value to store. */
5938
+ const STORAGE_SEED_TYPES = new Set(['Image', 'File', 'Html']);
5939
+ /** What a clear shows at once: no value and no file. */
5940
+ const CLEARED_CONTEXT = {
5941
+ propertyValue: null,
5942
+ renderValue: null,
5943
+ refResolvedValue: undefined,
5944
+ refResolvedDisplayValue: undefined,
5945
+ localStorageDir: undefined,
5946
+ storageTransactionId: undefined,
5947
+ };
5948
+ const snapshotOf = (context) => ({
5949
+ propertyValue: context.propertyValue,
5950
+ renderValue: context.renderValue,
5951
+ refResolvedValue: context.refResolvedValue,
5952
+ refResolvedDisplayValue: context.refResolvedDisplayValue,
5953
+ localStorageDir: context.localStorageDir,
5954
+ storageTransactionId: context.storageTransactionId,
5955
+ });
5848
5956
  class ItemProperty {
5849
5957
  constructor(initialValues) {
5850
5958
  this._isRelation = false;
@@ -5935,7 +6043,7 @@ class ItemProperty {
5935
6043
  return;
5936
6044
  }
5937
6045
  // Use dynamic import to break circular dependency
5938
- const schemaMod = await import('./index-DJmWkVIK.js');
6046
+ const schemaMod = await import('./index-DQoyhp2c.js');
5939
6047
  const { ModelPropertyDataTypes } = schemaMod;
5940
6048
  const { context } = snapshot;
5941
6049
  const { propertyRecordSchema } = context;
@@ -6152,6 +6260,9 @@ class ItemProperty {
6152
6260
  }
6153
6261
  return { refResolvedDisplayValue: undefined };
6154
6262
  };
6263
+ // A row with no value and no file is a cleared property (ADR 0021), here or synced from
6264
+ // another device: drop the storage transaction id too, or the old file's gateway URL shows.
6265
+ const clearedFromRow = (row) => row.propertyValue == null && !row.refResolvedValue ? { storageTransactionId: undefined } : {};
6155
6266
  const drizzleMod = await import('drizzle-orm');
6156
6267
  const { eq, and, or } = drizzleMod;
6157
6268
  const metadataLatestMod = await Promise.resolve().then(function () { return metadataLatest; });
@@ -6194,6 +6305,7 @@ class ItemProperty {
6194
6305
  schemaUid: metaRow.schemaUid || undefined,
6195
6306
  refResolvedValue: metaRow.refResolvedValue || undefined,
6196
6307
  ...displayValueFromRow(metaRow),
6308
+ ...clearedFromRow(metaRow),
6197
6309
  localStorageDir: metaRow.localStorageDir || undefined,
6198
6310
  });
6199
6311
  }
@@ -6215,7 +6327,7 @@ class ItemProperty {
6215
6327
  ref_resolved_value as refResolvedValue, ref_resolved_display_value as refResolvedDisplayValue, local_storage_dir as localStorageDir
6216
6328
  FROM metadata
6217
6329
  WHERE seed_uid = ${resolvedSeedUid} AND property_name = ${p0} AND property_name IS NOT NULL
6218
- ORDER BY (revoked_at IS NOT NULL), COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6330
+ ORDER BY COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6219
6331
  `;
6220
6332
  }
6221
6333
  if (propertyNames.length === 2) {
@@ -6225,7 +6337,7 @@ class ItemProperty {
6225
6337
  ref_resolved_value as refResolvedValue, ref_resolved_display_value as refResolvedDisplayValue, local_storage_dir as localStorageDir
6226
6338
  FROM metadata
6227
6339
  WHERE seed_uid = ${resolvedSeedUid} AND (property_name = ${p0} OR property_name = ${p1}) AND property_name IS NOT NULL
6228
- ORDER BY (revoked_at IS NOT NULL), COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6340
+ ORDER BY COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6229
6341
  `;
6230
6342
  }
6231
6343
  if (propertyNames.length >= 3) {
@@ -6235,7 +6347,7 @@ class ItemProperty {
6235
6347
  ref_resolved_value as refResolvedValue, ref_resolved_display_value as refResolvedDisplayValue, local_storage_dir as localStorageDir
6236
6348
  FROM metadata
6237
6349
  WHERE seed_uid = ${resolvedSeedUid} AND (property_name = ${p0} OR property_name = ${p1} OR property_name = ${p2}) AND property_name IS NOT NULL
6238
- ORDER BY (revoked_at IS NOT NULL), COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6350
+ ORDER BY COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6239
6351
  `;
6240
6352
  }
6241
6353
  }
@@ -6247,7 +6359,7 @@ class ItemProperty {
6247
6359
  ref_resolved_value as refResolvedValue, ref_resolved_display_value as refResolvedDisplayValue, local_storage_dir as localStorageDir
6248
6360
  FROM metadata
6249
6361
  WHERE seed_local_id = ${resolvedSeedLocalId} AND property_name = ${p0} AND property_name IS NOT NULL
6250
- ORDER BY (revoked_at IS NOT NULL), COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6362
+ ORDER BY COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6251
6363
  `;
6252
6364
  }
6253
6365
  if (propertyNames.length === 2) {
@@ -6257,7 +6369,7 @@ class ItemProperty {
6257
6369
  ref_resolved_value as refResolvedValue, ref_resolved_display_value as refResolvedDisplayValue, local_storage_dir as localStorageDir
6258
6370
  FROM metadata
6259
6371
  WHERE seed_local_id = ${resolvedSeedLocalId} AND (property_name = ${p0} OR property_name = ${p1}) AND property_name IS NOT NULL
6260
- ORDER BY (revoked_at IS NOT NULL), COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6372
+ ORDER BY COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6261
6373
  `;
6262
6374
  }
6263
6375
  if (propertyNames.length >= 3) {
@@ -6267,7 +6379,7 @@ class ItemProperty {
6267
6379
  ref_resolved_value as refResolvedValue, ref_resolved_display_value as refResolvedDisplayValue, local_storage_dir as localStorageDir
6268
6380
  FROM metadata
6269
6381
  WHERE seed_local_id = ${resolvedSeedLocalId} AND (property_name = ${p0} OR property_name = ${p1} OR property_name = ${p2}) AND property_name IS NOT NULL
6270
- ORDER BY (revoked_at IS NOT NULL), COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6382
+ ORDER BY COALESCE(attestation_created_at, created_at) DESC, local_id DESC LIMIT 1
6271
6383
  `;
6272
6384
  }
6273
6385
  }
@@ -6318,6 +6430,7 @@ class ItemProperty {
6318
6430
  schemaUid: metaRow.schemaUid || undefined,
6319
6431
  refResolvedValue: metaRow.refResolvedValue || undefined,
6320
6432
  ...displayValueFromRow(metaRow),
6433
+ ...clearedFromRow(metaRow),
6321
6434
  localStorageDir: metaRow.localStorageDir || undefined,
6322
6435
  });
6323
6436
  }, {
@@ -6387,7 +6500,7 @@ class ItemProperty {
6387
6500
  const ctx = this._service.getSnapshot().context;
6388
6501
  let modelFileId;
6389
6502
  try {
6390
- const _mod_17 = await import('./index-Dx_GTdyQ.js');
6503
+ const _mod_17 = await import('./index-rOTW-2QZ.js');
6391
6504
  const _ns_17 = _mod_17.be;
6392
6505
  const { resolveItemModelFileId } = _ns_17;
6393
6506
  modelFileId = await resolveItemModelFileId({
@@ -6738,7 +6851,7 @@ class ItemProperty {
6738
6851
  const propertiesData = await getItemProperties({ seedLocalId, seedUid });
6739
6852
  const instances = [];
6740
6853
  const seenNormalized = new Set();
6741
- const _mod_18 = await import('./index-Dx_GTdyQ.js');
6854
+ const _mod_18 = await import('./index-rOTW-2QZ.js');
6742
6855
  const _ns_18 = _mod_18.be;
6743
6856
  const { resolveItemModelFileId } = _ns_18;
6744
6857
  const itemModelFileId = await resolveItemModelFileId({ seedLocalId, seedUid });
@@ -6756,7 +6869,7 @@ class ItemProperty {
6756
6869
  }
6757
6870
  else if (baseName) {
6758
6871
  try {
6759
- const _mod_19 = await import('./errors-D1zHAqjr.js');
6872
+ const _mod_19 = await import('./errors-CS3nDpUU.js');
6760
6873
  const _ns_19 = _mod_19.i;
6761
6874
  const { Model } = _ns_19;
6762
6875
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
@@ -6773,7 +6886,7 @@ class ItemProperty {
6773
6886
  }
6774
6887
  if (modelName && propertyName) {
6775
6888
  try {
6776
- const _mod_20 = await import('./errors-D1zHAqjr.js');
6889
+ const _mod_20 = await import('./errors-CS3nDpUU.js');
6777
6890
  const _ns_20 = _mod_20.i;
6778
6891
  const { Model } = _ns_20;
6779
6892
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
@@ -6976,7 +7089,7 @@ class ItemProperty {
6976
7089
  const { seedLocalId, propertyName } = this._getSnapshotContext();
6977
7090
  if (!seedLocalId || !propertyName)
6978
7091
  return;
6979
- const { appendOutboxOpAndWait, markPropertyConflictsResolved, startItemOutbox, throwItemWriteError } = await import('./index-CkYb3wcU.js');
7092
+ const { appendOutboxOpAndWait, markPropertyConflictsResolved, startItemOutbox, throwItemWriteError } = await import('./index-njjjo74v.js');
6980
7093
  if (choice === 'remote') {
6981
7094
  startItemOutbox();
6982
7095
  await appendOutboxOpAndWait({
@@ -7025,17 +7138,54 @@ class ItemProperty {
7025
7138
  setValue(value, options = {}) {
7026
7139
  const context = this._getSnapshotContext();
7027
7140
  // Restored if the save is refused (item not owned), breaks a validation rule, or fails.
7028
- const before = options.before ??
7029
- this._unsavedBefore ?? { propertyValue: context.propertyValue, renderValue: context.renderValue };
7141
+ const before = options.before ?? this._unsavedBefore ?? snapshotOf(context);
7030
7142
  this._unsavedBefore = undefined;
7143
+ // An empty Image, File or Html value has nothing to store: it clears the property
7144
+ if ((value == null || (typeof value === 'string' && value.trim() === '')) && this._holdsStorageSeed(context)) {
7145
+ this._sendSave(null, before, { retract: false });
7146
+ return;
7147
+ }
7148
+ this._sendSave(value, before);
7149
+ }
7150
+ /**
7151
+ * Clears the value and resolves once it is stored, like `save()` (ADR 0021). A refused or failed
7152
+ * clear restores the value. Publish then attests the property's empty value, so its history shows
7153
+ * the removal and reads of earlier Versions keep the old value.
7154
+ *
7155
+ * @param options.retract - Publish revokes the property's attestations instead, so reads of earlier
7156
+ * Versions stop showing the value too. Revocation is permanent.
7157
+ * @throws ClearNotSupportedError for a Boolean or Date property without `retract`: their EAS types
7158
+ * have no empty value.
7159
+ */
7160
+ async clear(options = {}) {
7161
+ const retract = options.retract === true;
7162
+ const context = this._getSnapshotContext();
7163
+ const dataType = normalizeDataType(this._dataType ?? context.propertyRecordSchema?.dataType);
7164
+ if (!retract && (dataType === 'Boolean' || dataType === 'Date')) {
7165
+ throw new ClearNotSupportedError(this.propertyName, dataType);
7166
+ }
7167
+ const before = this._unsavedBefore ?? snapshotOf(context);
7168
+ this._unsavedBefore = undefined;
7169
+ this._sendSave(null, before, { retract });
7170
+ await this.save();
7171
+ }
7172
+ /** An Image, File or Html property, or a Relation to Image: its value is a storage seed. */
7173
+ _holdsStorageSeed(context) {
7174
+ const schema = context.propertyRecordSchema;
7175
+ const dataType = normalizeDataType(this._dataType ?? schema?.dataType);
7176
+ return STORAGE_SEED_TYPES.has(dataType ?? '') || normalizeDataType(schema?.refValueType) === 'Image';
7177
+ }
7178
+ /** Shows `value` at once and sends the save; `clear` shows and saves a cleared value instead. */
7179
+ _sendSave(value, before, clear) {
7180
+ const context = this._getSnapshotContext();
7031
7181
  // Update context immediately so UI shows the value before save completes. A new edit settles
7032
7182
  // the property's conflict (ADR 0019).
7033
7183
  this._service.send({
7034
7184
  type: 'updateContext',
7035
- propertyValue: value,
7036
- renderValue: value,
7185
+ ...(clear ? CLEARED_CONTEXT : { propertyValue: value, renderValue: value }),
7037
7186
  conflict: null,
7038
7187
  });
7188
+ const saveEvent = { type: 'save', newValue: value, before, ...(clear && { clear }) };
7039
7189
  // If no propertyRecordSchema, try to resolve from Model before persisting (fixes external app persistence)
7040
7190
  if (!context.propertyRecordSchema) {
7041
7191
  const { modelName, propertyName, modelType, modelFileId, seedLocalId, seedUid, propertyId } = context;
@@ -7048,7 +7198,7 @@ class ItemProperty {
7048
7198
  if (!schema)
7049
7199
  return false;
7050
7200
  this._service.send({ type: 'updateContext', propertyRecordSchema: schema });
7051
- this._service.send({ type: 'save', newValue: value, before });
7201
+ this._service.send(saveEvent);
7052
7202
  return true;
7053
7203
  }, () => false);
7054
7204
  this._pendingSchemaSave = pending;
@@ -7058,11 +7208,7 @@ class ItemProperty {
7058
7208
  });
7059
7209
  }
7060
7210
  else {
7061
- this._service.send({
7062
- type: 'save',
7063
- newValue: value,
7064
- before,
7065
- });
7211
+ this._service.send(saveEvent);
7066
7212
  }
7067
7213
  }
7068
7214
  /**
@@ -7073,7 +7219,7 @@ class ItemProperty {
7073
7219
  showValue(value) {
7074
7220
  if (!this._unsavedBefore) {
7075
7221
  const context = this._getSnapshotContext();
7076
- this._unsavedBefore = { propertyValue: context.propertyValue, renderValue: context.renderValue };
7222
+ this._unsavedBefore = snapshotOf(context);
7077
7223
  }
7078
7224
  this._service.send({ type: 'updateContext', propertyValue: value, renderValue: value });
7079
7225
  }
@@ -7223,7 +7369,7 @@ class ItemProperty {
7223
7369
  if (db && seedLocalId) {
7224
7370
  // Through the outbox (ADR 0019): after the property's pending edits, which would
7225
7371
  // otherwise write its rows back
7226
- const { appendOutboxOpAndWait, startItemOutbox, throwItemWriteError } = await import('./index-CkYb3wcU.js');
7372
+ const { appendOutboxOpAndWait, startItemOutbox, throwItemWriteError } = await import('./index-njjjo74v.js');
7227
7373
  startItemOutbox();
7228
7374
  await appendOutboxOpAndWait({
7229
7375
  seedLocalId,
@@ -7233,7 +7379,7 @@ class ItemProperty {
7233
7379
  }).catch(throwItemWriteError);
7234
7380
  }
7235
7381
  else if (db) {
7236
- const _mod_21 = await import('./index-PbnKw2es.js');
7382
+ const _mod_21 = await import('./index-DxHpPNfn.js');
7237
7383
  const _ns_21 = _mod_21.s;
7238
7384
  const seedSchemaMod = _ns_21;
7239
7385
  const { metadata } = seedSchemaMod;
@@ -7266,6 +7412,7 @@ ItemProperty.instanceCache = new Map();
7266
7412
 
7267
7413
  var ItemProperty$1 = /*#__PURE__*/Object.freeze({
7268
7414
  __proto__: null,
7415
+ ClearNotSupportedError: ClearNotSupportedError,
7269
7416
  ItemProperty: ItemProperty,
7270
7417
  ItemPropertySaveValidationError: ItemPropertySaveValidationError
7271
7418
  });
@@ -7283,7 +7430,7 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
7283
7430
  }
7284
7431
  const seedType = easName(modelName);
7285
7432
  // Dynamic import to break circular dependency
7286
- const _mod_22 = await import('./errors-D1zHAqjr.js');
7433
+ const _mod_22 = await import('./errors-CS3nDpUU.js');
7287
7434
  const _ns_22 = _mod_22.i;
7288
7435
  const modelMod = _ns_22;
7289
7436
  const { Model } = modelMod;
@@ -7339,7 +7486,7 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
7339
7486
  }
7340
7487
  rows.push({ propertyName, propertyValue, propertyRecordSchema, schemaUid: schemaUids.get(propertyName) });
7341
7488
  }
7342
- const { appendOutboxOpAndWait, startItemOutbox } = await import('./index-CkYb3wcU.js');
7489
+ const { appendOutboxOpAndWait, startItemOutbox } = await import('./index-njjjo74v.js');
7343
7490
  startItemOutbox();
7344
7491
  const fields = await timed(`${label} seed fields`, () => resolveNewSeedFields(seedType));
7345
7492
  const applied = await timed(`${label} outbox apply`, () => appendOutboxOpAndWait({
@@ -7358,7 +7505,7 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
7358
7505
  }
7359
7506
  catch (error) {
7360
7507
  // Staged values of a create that never got appended (once appended, the op's discard does it)
7361
- const _mod_23 = await import('./ClientManager-GZfXErDX.js');
7508
+ const _mod_23 = await import('./ClientManager-DqL0q_eu.js');
7362
7509
  const _ns_23 = _mod_23.V;
7363
7510
  const { deleteFiles } = _ns_23;
7364
7511
  await deleteFiles(stagedPaths);
@@ -7488,7 +7635,7 @@ const getModel = () => {
7488
7635
  // the fragile `import(...).then(n => n.X)` chunk-namespace pattern.
7489
7636
  if (!modelImportPromise) {
7490
7637
  modelImportPromise = (async () => {
7491
- const _mod_24 = await import('./errors-D1zHAqjr.js');
7638
+ const _mod_24 = await import('./errors-CS3nDpUU.js');
7492
7639
  const _ns_24 = _mod_24.i;
7493
7640
  const mod = _ns_24;
7494
7641
  ModelClass = mod.Model;
@@ -7627,7 +7774,7 @@ class Item {
7627
7774
  * sync wrote while they were pending (ADR 0019). Each property's is also on `property.conflict`.
7628
7775
  */
7629
7776
  this.conflicts = async () => {
7630
- const _mod_25 = await import('./ClientManager-GZfXErDX.js');
7777
+ const _mod_25 = await import('./ClientManager-DqL0q_eu.js');
7631
7778
  const _ns_25 = _mod_25.U;
7632
7779
  const { getItemConflicts } = _ns_25;
7633
7780
  return getItemConflicts(this.seedLocalId);
@@ -7722,15 +7869,15 @@ class Item {
7722
7869
  };
7723
7870
  this.getPublishUploads = async (options) => {
7724
7871
  // Use dynamic import to break circular dependency
7725
- const _mod_26 = await import('./getPublishUploads-BzUIDA2G.js');
7872
+ const _mod_26 = await import('./getPublishUploads-BBqiowVc.js');
7726
7873
  const _ns_26 = _mod_26.o;
7727
7874
  const getPublishUploadsMod = _ns_26;
7728
7875
  const { getPublishUploads } = getPublishUploadsMod;
7729
7876
  return await getPublishUploads(this, [], undefined, options);
7730
7877
  };
7731
7878
  this.getPublishPayload = async (uploadedTransactions, options) => {
7732
- const _mod_27 = await import('./getPublishPayload-DH4rMqXG.js');
7733
- const _ns_27 = _mod_27.g;
7879
+ const _mod_27 = await import('./getPublishPayload-pbin4lk8.js');
7880
+ const _ns_27 = _mod_27.c;
7734
7881
  const getPublishPayloadMod = _ns_27;
7735
7882
  const { getPublishPayload } = getPublishPayloadMod;
7736
7883
  return await getPublishPayload(this, uploadedTransactions, options);
@@ -8273,7 +8420,7 @@ class Item {
8273
8420
  const db = BaseDb.getAppDb();
8274
8421
  if (db && props.modelName) {
8275
8422
  // Model names are only unique per schema: resolve the exact models row from the most specific scope.
8276
- const _mod_28 = await import('./index-Dx_GTdyQ.js');
8423
+ const _mod_28 = await import('./index-rOTW-2QZ.js');
8277
8424
  const _ns_28 = _mod_28.be;
8278
8425
  const { resolveModelRecord } = _ns_28;
8279
8426
  const modelRecord = await resolveModelRecord(props.modelName, {
@@ -8282,7 +8429,7 @@ class Item {
8282
8429
  });
8283
8430
  const modelRecords = modelRecord ? [modelRecord] : [];
8284
8431
  if (!modelRecord) {
8285
- const _mod_29 = await import('./errors-D1zHAqjr.js');
8432
+ const _mod_29 = await import('./errors-CS3nDpUU.js');
8286
8433
  const _ns_29 = _mod_29.j;
8287
8434
  const { UnknownModelError } = _ns_29;
8288
8435
  throw new UnknownModelError(props.modelName, schemaName ?? modelInstance?.schemaName);
@@ -8293,10 +8440,10 @@ class Item {
8293
8440
  // Scope the constructor's Model lookup to this model's schema (as getItemData does on reload),
8294
8441
  // so a same-named model cached from another schema can't supply the property set.
8295
8442
  if (modelRecord && !props.schemaName) {
8296
- const _mod_30 = await import('./index-Dx_GTdyQ.js');
8443
+ const _mod_30 = await import('./index-rOTW-2QZ.js');
8297
8444
  const _ns_30 = _mod_30.bd;
8298
8445
  const { modelSchemas } = _ns_30;
8299
- const _mod_31 = await import('./index-Dx_GTdyQ.js');
8446
+ const _mod_31 = await import('./index-rOTW-2QZ.js');
8300
8447
  const _ns_31 = _mod_31.bc;
8301
8448
  const { schemas: schemasTable } = _ns_31;
8302
8449
  const schemaRows = await db
@@ -8400,7 +8547,7 @@ class Item {
8400
8547
  /* best-effort cache cleanup */
8401
8548
  }
8402
8549
  try {
8403
- const { appendOutboxOpAndWait, deleteFiles, startItemOutbox } = await import('./index-CkYb3wcU.js');
8550
+ const { appendOutboxOpAndWait, deleteFiles, startItemOutbox } = await import('./index-njjjo74v.js');
8404
8551
  startItemOutbox();
8405
8552
  const applied = await appendOutboxOpAndWait({
8406
8553
  seedLocalId,
@@ -8423,7 +8570,7 @@ class Item {
8423
8570
  for (const [propertyName, value] of pipelineValues) {
8424
8571
  const property = await this.waitForPropertyInstance(item, propertyName, timeout);
8425
8572
  if (!property) {
8426
- const _mod_32 = await import('./errors-D1zHAqjr.js');
8573
+ const _mod_32 = await import('./errors-CS3nDpUU.js');
8427
8574
  const _ns_32 = _mod_32.j;
8428
8575
  const { ItemCreateError } = _ns_32;
8429
8576
  throw new ItemCreateError(`Item.create: property ${item.modelName}.${propertyName} did not load for item ${item.seedLocalId}; value was not saved`, { code: 'property_not_loaded', modelName: item.modelName, property: propertyName, seedLocalId: item.seedLocalId });
@@ -8435,14 +8582,14 @@ class Item {
8435
8582
  }
8436
8583
  catch (error) {
8437
8584
  if (error instanceof ItemPropertySaveValidationError) {
8438
- const _mod_33 = await import('./errors-D1zHAqjr.js');
8585
+ const _mod_33 = await import('./errors-CS3nDpUU.js');
8439
8586
  const _ns_33 = _mod_33.j;
8440
8587
  const { ItemCreateValidationError } = _ns_33;
8441
8588
  const created = new ItemCreateValidationError(item.modelName, error.validationErrors.map((e) => ({ property: propertyName, code: e.code, message: e.message })));
8442
8589
  created.cause = error;
8443
8590
  throw created;
8444
8591
  }
8445
- const _mod_34 = await import('./errors-D1zHAqjr.js');
8592
+ const _mod_34 = await import('./errors-CS3nDpUU.js');
8446
8593
  const _ns_34 = _mod_34.j;
8447
8594
  const { ItemCreateError } = _ns_34;
8448
8595
  throw new ItemCreateError(`Item.create: failed to save ${item.modelName}.${propertyName} for item ${item.seedLocalId}: ` +
@@ -8610,7 +8757,7 @@ class Item {
8610
8757
  if (!appDb || Item.instanceCache.size === 0) {
8611
8758
  return;
8612
8759
  }
8613
- const _mod_35 = await import('./index-PbnKw2es.js');
8760
+ const _mod_35 = await import('./index-DxHpPNfn.js');
8614
8761
  const _ns_35 = _mod_35.s;
8615
8762
  const { metadata } = _ns_35;
8616
8763
  const { eq, and } = await import('drizzle-orm');
@@ -8744,11 +8891,11 @@ class Item {
8744
8891
  }
8745
8892
  /** Throws ItemCreateValidationError for unknown keys and values that break their property's rules. */
8746
8893
  static async assertValidCreateValues(props, propertyNames, dataTypeByPropertyName, skipKeys) {
8747
- const _mod_36 = await import('./errors-D1zHAqjr.js');
8894
+ const _mod_36 = await import('./errors-CS3nDpUU.js');
8748
8895
  const _ns_36 = _mod_36.j;
8749
8896
  const { ItemCreateValidationError } = _ns_36;
8750
- const { getPropertySchema } = await import('./property-BwYtg5Q_.js');
8751
- const { SchemaValidationService } = await import('./SchemaValidationService-DnGKel4V.js');
8897
+ const { getPropertySchema } = await import('./property-C85DCD7K.js');
8898
+ const { SchemaValidationService } = await import('./SchemaValidationService-CZzKNL04.js');
8752
8899
  const validationService = new SchemaValidationService();
8753
8900
  const modelName = props.modelName;
8754
8901
  const known = new Set(propertyNames);
@@ -8785,7 +8932,7 @@ class Item {
8785
8932
  // Not JSON: validated as given, and rejected as a non-array
8786
8933
  }
8787
8934
  }
8788
- const { resolvePropertyValidationRules } = await import('./propertyValidationRules-CyHdpcPP.js');
8935
+ const { resolvePropertyValidationRules } = await import('./propertyValidationRules-CjUPOFeu.js');
8789
8936
  const rules = propertySchema?.validation ??
8790
8937
  (await resolvePropertyValidationRules(modelName, key, {
8791
8938
  modelFileId: props.modelFileId,
@@ -9097,7 +9244,7 @@ class Item {
9097
9244
  itemActor.send(event);
9098
9245
  };
9099
9246
  try {
9100
- const _mod_37 = await import('./index-PbnKw2es.js');
9247
+ const _mod_37 = await import('./index-DxHpPNfn.js');
9101
9248
  const _ns_37 = _mod_37.s;
9102
9249
  const seedSchemaMod = _ns_37;
9103
9250
  const { seeds, metadata } = seedSchemaMod;
@@ -9480,7 +9627,7 @@ class Item {
9480
9627
  return;
9481
9628
  }
9482
9629
  // Through the outbox (ADR 0019): after the item's pending edits, not before them
9483
- const { appendOutboxOpAndWait, startItemOutbox, throwItemWriteError } = await import('./index-CkYb3wcU.js');
9630
+ const { appendOutboxOpAndWait, startItemOutbox, throwItemWriteError } = await import('./index-njjjo74v.js');
9484
9631
  startItemOutbox();
9485
9632
  await appendOutboxOpAndWait({
9486
9633
  seedLocalId: context.seedLocalId,
@@ -9507,5 +9654,5 @@ var Item$1 = /*#__PURE__*/Object.freeze({
9507
9654
  Item: Item
9508
9655
  });
9509
9656
 
9510
- export { getMetadataLatest as $, getItemData as A, waitForEntityIdle as B, compareMetadataRowsLatestFirst as C, getEasSchemaUidForModel as D, getLatestPublishedVersionRow as E, parseListPropertyValueFromStorage as F, chunkValues as G, rowsPerInsert as H, Item as I, getGetAdditionalSyncAddresses as J, isVersionRevoked as K, isActorStopped as L, METADATA_LATEST_FIRST_ORDER_SQL as M, DEFAULT_READY_TIMEOUT_MS as N, OUTBOX_DEFER_MS as O, createReactiveProxy as P, sameEntity as Q, findEntity as R, forceRemoveFromCaches as S, runDestroyLifecycle as T, latestVersionOrder as U, isPublishedMetadataRow as V, ClientManagerState as W, MachineIds as X, PUBLISH_NOT_CONFIGURED_MESSAGE as Y, createNewItem as Z, getGetPublisherForNewSeeds as _, appendOutboxOpAndWait as a, getPublishExecutor as a0, getRevokeExecutor as a1, getUploadExecutor as a2, getVersionData$1 as a3, isLocalUnsealedDraft as a4, isSeedRowOwned as a5, localUnsealedDraftSql as a6, ownedPublisherSql as a7, ownedSeedsSql as a8, pickLatestMetadataRowPerProperty as a9, placeholderUidSql as aa, propertyMachine as ab, publisherInAddressListSql as ac, publisherIsInOwnedSet as ad, setAdditionalSyncAddresses as ae, setGetPublisherForNewSeeds as af, setPublishExecutor as ag, setRevokeExecutor as ah, setUploadExecutor as ai, ActorKeyedState as aj, clearDestroySubscriptions as ak, unloadEntity as al, ClientManagerEvents as am, getSeedPublisher as an, propertyNameVariants as ao, createSeed as ap, createMetadata as aq, updateItemPropertyValue as ar, resolvePublisherFromSeedRow as as, getPropertyData$1 as at, Item$1 as au, waitForOutboxOp as b, appendOutboxOp as c, OUTBOX_MAX_ATTEMPTS as d, OUTBOX_PRUNE_AFTER_MS as e, OUTBOX_PRUNE_FAILED_AFTER_MS as f, getOutboxOps as g, OUTBOX_RETRY_DELAYS_MS as h, OutboxOpDeferredError as i, OutboxOpFailedError as j, OutboxOpRejectedError as k, drainOutbox as l, getPendingSetValue as m, outboxOpValue as n, outboxOpResult as o, pruneOutbox as p, ItemProperty as q, registerOutboxApplier as r, startOutbox as s, ItemPropertySaveValidationError as t, OwnershipError as u, assertItemOwned as v, waitForPendingOutboxOps as w, isItemOwned as x, writeInBatches as y, selectInBatches as z };
9511
- //# sourceMappingURL=Item-0oDoTPhi.js.map
9657
+ export { getGetPublisherForNewSeeds as $, getLatestPublishedVersionRow as A, writeInBatches as B, ClearNotSupportedError as C, selectInBatches as D, getItemData as E, waitForEntityIdle as F, chunkValues as G, rowsPerInsert as H, Item as I, getGetAdditionalSyncAddresses as J, getEasSchemaUidForModel as K, parseListPropertyValueFromStorage as L, METADATA_LATEST_FIRST_ORDER_SQL as M, isVersionRevoked as N, OUTBOX_DEFER_MS as O, isActorStopped as P, DEFAULT_READY_TIMEOUT_MS as Q, createReactiveProxy as R, sameEntity as S, findEntity as T, forceRemoveFromCaches as U, runDestroyLifecycle as V, latestVersionOrder as W, ClientManagerState as X, MachineIds as Y, PUBLISH_NOT_CONFIGURED_MESSAGE as Z, createNewItem as _, appendOutboxOpAndWait as a, getMetadataLatest as a0, getPublishExecutor as a1, getRevokeExecutor as a2, getUploadExecutor as a3, getVersionData$1 as a4, isLocalUnsealedDraft as a5, isSeedRowOwned as a6, localUnsealedDraftSql as a7, ownedPublisherSql as a8, ownedSeedsSql as a9, pickLatestMetadataRowPerProperty as aa, placeholderUidSql as ab, propertyMachine as ac, publisherInAddressListSql as ad, publisherIsInOwnedSet as ae, setAdditionalSyncAddresses as af, setGetPublisherForNewSeeds as ag, setPublishExecutor as ah, setRevokeExecutor as ai, setUploadExecutor as aj, ActorKeyedState as ak, clearDestroySubscriptions as al, unloadEntity as am, ClientManagerEvents as an, getSeedPublisher as ao, propertyNameVariants as ap, createSeed as aq, createMetadata as ar, updateItemPropertyValue as as, resolvePublisherFromSeedRow as at, getPropertyData$1 as au, Item$1 as av, waitForOutboxOp as b, appendOutboxOp as c, OUTBOX_MAX_ATTEMPTS as d, OUTBOX_PRUNE_AFTER_MS as e, OUTBOX_PRUNE_FAILED_AFTER_MS as f, getOutboxOps as g, OUTBOX_RETRY_DELAYS_MS as h, OutboxOpDeferredError as i, OutboxOpFailedError as j, OutboxOpRejectedError as k, drainOutbox as l, getPendingSetValue as m, outboxOpValue as n, outboxOpResult as o, pruneOutbox as p, ItemProperty as q, registerOutboxApplier as r, startOutbox as s, ItemPropertySaveValidationError as t, OwnershipError as u, assertItemOwned as v, waitForPendingOutboxOps as w, isItemOwned as x, compareMetadataRowsLatestFirst as y, isPublishedMetadataRow as z };
9658
+ //# sourceMappingURL=Item-CG5IhPtL.js.map