@noy-db/hub 0.6.0-pre.2 → 0.6.0-pre.21

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 (499) hide show
  1. package/CHANGELOG.md +5234 -0
  2. package/codemods/0.4.0-pre.json +699 -0
  3. package/codemods/0.6.0-pre.json +211 -0
  4. package/dist/api-EYNT6KGS.js +20 -0
  5. package/dist/attestation/index.js +19 -19
  6. package/dist/{backup-YYBE5RPC.js → backup-FSC36VWC.js} +36 -18
  7. package/dist/backup-FSC36VWC.js.map +1 -0
  8. package/dist/blobs/index.js +13 -13
  9. package/dist/broker/index.js +12 -12
  10. package/dist/cargo/index.js +33 -33
  11. package/dist/{chunk-35EBKWQU.js → chunk-2LFOMUEA.js} +4 -4
  12. package/dist/{chunk-OF3L2SD6.js → chunk-32B7VCKU.js} +2 -2
  13. package/dist/{chunk-MSWYQLMQ.js → chunk-3B6S6RSI.js} +2 -2
  14. package/dist/{chunk-PJNTR2NV.js → chunk-3ENNPCIW.js} +7 -10
  15. package/dist/chunk-3ENNPCIW.js.map +1 -0
  16. package/dist/{chunk-7F4DBNSP.js → chunk-3O72ZD2E.js} +3 -3
  17. package/dist/{chunk-FNSMZQS4.js → chunk-3PMFMUFX.js} +2 -2
  18. package/dist/{chunk-WQDTCJ6W.js → chunk-45YHJ3GV.js} +11 -3
  19. package/dist/{chunk-WQDTCJ6W.js.map → chunk-45YHJ3GV.js.map} +1 -1
  20. package/dist/{chunk-NIVEDYJZ.js → chunk-4A34KWOU.js} +31 -49
  21. package/dist/chunk-4A34KWOU.js.map +1 -0
  22. package/dist/{chunk-ZJADGNYF.js → chunk-4AOERLTV.js} +1 -1
  23. package/dist/chunk-4AOERLTV.js.map +1 -0
  24. package/dist/{chunk-EDXAQ6JI.js → chunk-4N5Q23KV.js} +87 -34
  25. package/dist/chunk-4N5Q23KV.js.map +1 -0
  26. package/dist/{chunk-VV4NSB7P.js → chunk-4OQZNXQG.js} +15 -24
  27. package/dist/chunk-4OQZNXQG.js.map +1 -0
  28. package/dist/{chunk-FAXZQ5UF.js → chunk-4RAS6HN6.js} +2 -2
  29. package/dist/{chunk-C2OOEM57.js → chunk-4YL2LMXK.js} +92 -35
  30. package/dist/chunk-4YL2LMXK.js.map +1 -0
  31. package/dist/{chunk-EP7VPR7Y.js → chunk-5Q7AJ7DN.js} +11 -8
  32. package/dist/chunk-5Q7AJ7DN.js.map +1 -0
  33. package/dist/{chunk-VMCCGUQB.js → chunk-6JPGVL7X.js} +2 -2
  34. package/dist/{chunk-PRDRGL73.js → chunk-6KTVJ5ZZ.js} +17 -14
  35. package/dist/chunk-6KTVJ5ZZ.js.map +1 -0
  36. package/dist/{chunk-4MC5JRRX.js → chunk-6WO62AJW.js} +14 -15
  37. package/dist/chunk-6WO62AJW.js.map +1 -0
  38. package/dist/{chunk-WLYIROCJ.js → chunk-6YD5SYQS.js} +2 -2
  39. package/dist/{chunk-YAWK6AWF.js → chunk-7KAE7CQ2.js} +2 -2
  40. package/dist/{chunk-MWKDOHEF.js → chunk-7LNE2N2V.js} +17 -10
  41. package/dist/chunk-7LNE2N2V.js.map +1 -0
  42. package/dist/{chunk-5PR33AC4.js → chunk-7PJ3BKHS.js} +20 -17
  43. package/dist/chunk-7PJ3BKHS.js.map +1 -0
  44. package/dist/{chunk-JXIDGFKS.js → chunk-A4TOGAUW.js} +4 -2
  45. package/dist/chunk-A4TOGAUW.js.map +1 -0
  46. package/dist/{chunk-VCETL77O.js → chunk-AU3AUJIZ.js} +27 -7
  47. package/dist/chunk-AU3AUJIZ.js.map +1 -0
  48. package/dist/{chunk-NKH7GSIH.js → chunk-AUPSEJ7O.js} +4 -4
  49. package/dist/{chunk-CCZJJ4I2.js → chunk-B6IYATME.js} +4 -4
  50. package/dist/{chunk-WYZ5MYUA.js → chunk-BAHOV5I5.js} +44 -42
  51. package/dist/chunk-BAHOV5I5.js.map +1 -0
  52. package/dist/{chunk-G5APARUV.js → chunk-BEZDLIDG.js} +13 -15
  53. package/dist/chunk-BEZDLIDG.js.map +1 -0
  54. package/dist/{chunk-ERB6NDDW.js → chunk-CAGI4LLJ.js} +427 -72
  55. package/dist/chunk-CAGI4LLJ.js.map +1 -0
  56. package/dist/{chunk-4UVDI4XE.js → chunk-CLAHBPOI.js} +4 -4
  57. package/dist/{chunk-HNGSV2YC.js → chunk-CWM4GQD2.js} +39 -10
  58. package/dist/chunk-CWM4GQD2.js.map +1 -0
  59. package/dist/{chunk-HVQGCKY4.js → chunk-D3R7Q4QK.js} +2 -2
  60. package/dist/{chunk-I4F6PKUK.js → chunk-DIZ6HM7Q.js} +16 -17
  61. package/dist/chunk-DIZ6HM7Q.js.map +1 -0
  62. package/dist/{chunk-ZNACADFG.js → chunk-DVRZYAGT.js} +4 -4
  63. package/dist/chunk-DVRZYAGT.js.map +1 -0
  64. package/dist/{chunk-P7OG2ETF.js → chunk-DXKLLKME.js} +3 -3
  65. package/dist/{chunk-TDJPS3T2.js → chunk-E5SC6ENM.js} +24 -19
  66. package/dist/chunk-E5SC6ENM.js.map +1 -0
  67. package/dist/{chunk-26JMGSSC.js → chunk-EES37S2V.js} +4 -4
  68. package/dist/chunk-EES37S2V.js.map +1 -0
  69. package/dist/{chunk-JIUVJ4M7.js → chunk-EKEIEJL6.js} +2 -2
  70. package/dist/{chunk-GASWQ3XG.js → chunk-ESKIAXO2.js} +15 -16
  71. package/dist/chunk-ESKIAXO2.js.map +1 -0
  72. package/dist/{chunk-TOAIYQJR.js → chunk-FFSQFH6D.js} +7 -10
  73. package/dist/chunk-FFSQFH6D.js.map +1 -0
  74. package/dist/{chunk-DG27IUVI.js → chunk-FS7NTGCJ.js} +2 -2
  75. package/dist/{chunk-V5KYPBUR.js → chunk-FW7NGYLT.js} +11 -14
  76. package/dist/chunk-FW7NGYLT.js.map +1 -0
  77. package/dist/{chunk-52QYGZHH.js → chunk-GBBDFE6C.js} +2 -2
  78. package/dist/chunk-GBBDFE6C.js.map +1 -0
  79. package/dist/{chunk-HXGUIPQB.js → chunk-GQXFOAYZ.js} +3 -3
  80. package/dist/{chunk-BTVYJWSN.js → chunk-GTHVPVAR.js} +10 -10
  81. package/dist/{chunk-DMQCLZ4Z.js → chunk-GWO2IDAB.js} +2 -2
  82. package/dist/{chunk-6HFM7EIT.js → chunk-H3G4I3PN.js} +2 -2
  83. package/dist/chunk-HK67PX4J.js +27 -0
  84. package/dist/chunk-HK67PX4J.js.map +1 -0
  85. package/dist/{chunk-E7OBCBXS.js → chunk-HQSPF5IY.js} +22 -18
  86. package/dist/chunk-HQSPF5IY.js.map +1 -0
  87. package/dist/{chunk-VJFMXYKP.js → chunk-HR5R5JOM.js} +2 -2
  88. package/dist/{chunk-FDX7OWWI.js → chunk-HYYVT2KZ.js} +2 -2
  89. package/dist/{chunk-JRCYZEHU.js → chunk-I6QKB7MT.js} +2 -2
  90. package/dist/{chunk-MZ5ZFO2D.js → chunk-ICDHUUMQ.js} +84 -112
  91. package/dist/chunk-ICDHUUMQ.js.map +1 -0
  92. package/dist/{chunk-W5W6KHN2.js → chunk-IGNJOJEP.js} +1 -1
  93. package/dist/chunk-IGNJOJEP.js.map +1 -0
  94. package/dist/{chunk-KUDZVJKQ.js → chunk-IJ46VCWD.js} +2 -2
  95. package/dist/{chunk-4HDYQL3J.js → chunk-INMHEMXX.js} +2 -2
  96. package/dist/{chunk-66W5OOCX.js → chunk-JLYQQNY4.js} +52 -65
  97. package/dist/chunk-JLYQQNY4.js.map +1 -0
  98. package/dist/{chunk-UHXCLPGC.js → chunk-JNMTN5D5.js} +2 -2
  99. package/dist/chunk-JNMTN5D5.js.map +1 -0
  100. package/dist/{chunk-I4ZAO7F7.js → chunk-JWMBG5S3.js} +7 -11
  101. package/dist/chunk-JWMBG5S3.js.map +1 -0
  102. package/dist/chunk-KRVS7YWY.js +123 -0
  103. package/dist/chunk-KRVS7YWY.js.map +1 -0
  104. package/dist/{chunk-AR2JDFAE.js → chunk-KV6JM2IA.js} +2 -2
  105. package/dist/{chunk-PVU7LW5L.js → chunk-KX57HODD.js} +6 -6
  106. package/dist/{chunk-PY7CI6L5.js → chunk-LGFTOU27.js} +553 -275
  107. package/dist/chunk-LGFTOU27.js.map +1 -0
  108. package/dist/chunk-LN7P6MZB.js +190 -0
  109. package/dist/chunk-LN7P6MZB.js.map +1 -0
  110. package/dist/{chunk-UIBGXRDD.js → chunk-LX46B56Q.js} +25 -31
  111. package/dist/chunk-LX46B56Q.js.map +1 -0
  112. package/dist/{chunk-CEJWMBXO.js → chunk-LXECF2ZR.js} +2 -2
  113. package/dist/{chunk-7VHY5E3X.js → chunk-MSLPDFK2.js} +7 -7
  114. package/dist/{chunk-I6SDX7WX.js → chunk-MZTUTEHP.js} +16 -22
  115. package/dist/chunk-MZTUTEHP.js.map +1 -0
  116. package/dist/{chunk-VRA4Q7DA.js → chunk-NCCEDL2K.js} +55 -48
  117. package/dist/chunk-NCCEDL2K.js.map +1 -0
  118. package/dist/{chunk-HNHCQ556.js → chunk-NR2SUJ3H.js} +2 -2
  119. package/dist/{chunk-AHLJSVRL.js → chunk-NW4TY6VC.js} +5 -7
  120. package/dist/chunk-NW4TY6VC.js.map +1 -0
  121. package/dist/{chunk-RKKORO4M.js → chunk-O742QBZZ.js} +10 -10
  122. package/dist/chunk-O742QBZZ.js.map +1 -0
  123. package/dist/{chunk-VN45YLWM.js → chunk-OHOKBMTM.js} +343 -132
  124. package/dist/chunk-OHOKBMTM.js.map +1 -0
  125. package/dist/{chunk-W3TVWF6N.js → chunk-OIBEJN5H.js} +2 -2
  126. package/dist/{chunk-QD724WDJ.js → chunk-OMYCSTXL.js} +4 -4
  127. package/dist/{chunk-Z45YRGFO.js → chunk-ONVD6GBY.js} +2 -2
  128. package/dist/{chunk-TAGFGKHP.js → chunk-OTHHO3KI.js} +7 -10
  129. package/dist/chunk-OTHHO3KI.js.map +1 -0
  130. package/dist/{chunk-3737A6EA.js → chunk-P2MR5UNE.js} +75 -18
  131. package/dist/chunk-P2MR5UNE.js.map +1 -0
  132. package/dist/chunk-PENPHA45.js +66 -0
  133. package/dist/chunk-PENPHA45.js.map +1 -0
  134. package/dist/{chunk-3FSX6LDG.js → chunk-PPCOKVFA.js} +8 -3
  135. package/dist/{chunk-3FSX6LDG.js.map → chunk-PPCOKVFA.js.map} +1 -1
  136. package/dist/{chunk-VOQW5LAM.js → chunk-QSIEL6TL.js} +102 -71
  137. package/dist/chunk-QSIEL6TL.js.map +1 -0
  138. package/dist/chunk-RFO4UXKQ.js +201 -0
  139. package/dist/chunk-RFO4UXKQ.js.map +1 -0
  140. package/dist/{chunk-KCQX65FU.js → chunk-RKCRPPNB.js} +3 -3
  141. package/dist/{chunk-7TSYBD3E.js → chunk-RSXQNFGO.js} +2 -2
  142. package/dist/{chunk-SZ2K3MHL.js → chunk-S56VYR4Q.js} +8 -11
  143. package/dist/{chunk-SZ2K3MHL.js.map → chunk-S56VYR4Q.js.map} +1 -1
  144. package/dist/{chunk-7NXHMW6Y.js → chunk-SYS46BL7.js} +2 -2
  145. package/dist/{chunk-55LKVALY.js → chunk-T7IR4N2S.js} +1 -3
  146. package/dist/chunk-T7IR4N2S.js.map +1 -0
  147. package/dist/{chunk-A67356IR.js → chunk-T7JGWTES.js} +33 -8
  148. package/dist/chunk-T7JGWTES.js.map +1 -0
  149. package/dist/{chunk-WHJKIZS7.js → chunk-TDSN2O2V.js} +27 -149
  150. package/dist/chunk-TDSN2O2V.js.map +1 -0
  151. package/dist/{chunk-747LRSOO.js → chunk-TMBSPLUG.js} +2 -2
  152. package/dist/{chunk-LWSJG3LI.js → chunk-TQPASLY4.js} +7 -3
  153. package/dist/chunk-TQPASLY4.js.map +1 -0
  154. package/dist/{chunk-WKPJXWKR.js → chunk-TX5MKAHA.js} +3 -3
  155. package/dist/{chunk-HFQ6LGIO.js → chunk-U27Y4DJZ.js} +12 -10
  156. package/dist/{chunk-HFQ6LGIO.js.map → chunk-U27Y4DJZ.js.map} +1 -1
  157. package/dist/{chunk-E6427JU2.js → chunk-VVSOPRUE.js} +18 -2
  158. package/dist/chunk-VVSOPRUE.js.map +1 -0
  159. package/dist/{chunk-7G6VDWXB.js → chunk-WVE6YKMX.js} +3 -3
  160. package/dist/chunk-WVE6YKMX.js.map +1 -0
  161. package/dist/{chunk-GLKDWWNO.js → chunk-YALD3SST.js} +16 -14
  162. package/dist/chunk-YALD3SST.js.map +1 -0
  163. package/dist/{chunk-NJDQ4YSV.js → chunk-YKXZHUOW.js} +4 -4
  164. package/dist/{chunk-VW6ZZGCG.js → chunk-ZLHHE5XZ.js} +3 -3
  165. package/dist/{chunk-FUHKW252.js → chunk-ZZXLB6AS.js} +2 -2
  166. package/dist/classified/index.js +5 -5
  167. package/dist/{classified-marker-FTOX7Q5L.js → classified-marker-NA6HUV33.js} +3 -3
  168. package/dist/collection-facade-VBM35WAH.js +45 -0
  169. package/dist/{computed-6G5M3UPH.js → computed-GSTLWSY5.js} +3 -3
  170. package/dist/consent/index.js +10 -10
  171. package/dist/cover/index.js +10 -3
  172. package/dist/custody/index.js +11 -11
  173. package/dist/{dead-filter-ENRIOQIE.js → dead-filter-UALP5DJX.js} +2 -2
  174. package/dist/debug/index.js +1 -1
  175. package/dist/{delegation-SSEPLXXO.js → delegation-JLNXM7KH.js} +24 -23
  176. package/dist/delegation-JLNXM7KH.js.map +1 -0
  177. package/dist/derivations/index.js +12 -12
  178. package/dist/derive-YUO3TQYN.js +22 -0
  179. package/dist/directory/index.js +10 -10
  180. package/dist/{dispatch-RE74SH6L.js → dispatch-4ZHLSFZQ.js} +5 -5
  181. package/dist/{dispatch-BDVGYC6X.js → dispatch-77CB75KB.js} +18 -18
  182. package/dist/{enclave-52VUXNRL.js → enclave-O4NOROCJ.js} +27 -9
  183. package/dist/executor-CZDXBXKE.js +29 -0
  184. package/dist/executor-DVJAWN3B.js +9 -0
  185. package/dist/executor-VRLG4TQJ.js +9 -0
  186. package/dist/export-accessible-UXSMG7AB.js +23 -0
  187. package/dist/extract-partition-TVY7AMKH.js +38 -0
  188. package/dist/{fanout-sidecar-DTBIDOWF.js → fanout-sidecar-NLQ7QAYW.js} +18 -27
  189. package/dist/fanout-sidecar-NLQ7QAYW.js.map +1 -0
  190. package/dist/find-WSARMJBW.js +11 -0
  191. package/dist/forget/index.js +9 -9
  192. package/dist/guards/index.js +7 -7
  193. package/dist/history/index.js +23 -20
  194. package/dist/history/index.js.map +1 -1
  195. package/dist/i18n/index.js +14 -14
  196. package/dist/index.d.ts +33 -15
  197. package/dist/index.js +187 -191
  198. package/dist/index.js.map +1 -1
  199. package/dist/indexing/index.js +2 -2
  200. package/dist/introspection/index.js +11 -11
  201. package/dist/issue-3JNJNPT3.js +19 -0
  202. package/dist/kernel/constants.d.ts +18 -0
  203. package/dist/kernel/enclave/crypto.d.ts +24 -4
  204. package/dist/kernel/enclave/index.d.ts +9 -2
  205. package/dist/kernel/enclave/record-aad.d.ts +131 -0
  206. package/dist/kernel/enclave/record-envelope.d.ts +76 -0
  207. package/dist/kernel/enclave/record-keys/envelope-body.d.ts +34 -2
  208. package/dist/kernel/enclave/record-keys/lifecycle.d.ts +22 -5
  209. package/dist/kernel/enclave/record-keys/record-codec.d.ts +47 -14
  210. package/dist/kernel/enclave/record-keys/rekey-blob.d.ts +88 -0
  211. package/dist/kernel/enclave/record-keys/rekey.d.ts +68 -0
  212. package/dist/kernel/enclave/record-keys/tombstone.d.ts +3 -2
  213. package/dist/kernel/errors.d.ts +71 -12
  214. package/dist/kernel/merge-authority.d.ts +25 -0
  215. package/dist/kernel/noydb.d.ts +27 -4
  216. package/dist/kernel/query/builder.d.ts +15 -2
  217. package/dist/kernel/query/join.d.ts +27 -0
  218. package/dist/kernel/sync-policy.d.ts +0 -2
  219. package/dist/kernel/tier-visibility.d.ts +15 -0
  220. package/dist/kernel/types.d.ts +145 -12
  221. package/dist/kernel/vault.d.ts +22 -18
  222. package/dist/kernel/via/index.d.ts +11 -2
  223. package/dist/{ledger-4WJL66BW.js → ledger-MVPNG5OS.js} +11 -11
  224. package/dist/liberate-4LOJOLDT.js +24 -0
  225. package/dist/{link-set-N4ZPV6E6.js → link-set-3POMQR3I.js} +11 -11
  226. package/dist/{managed-secret-OTHS64IF.js → managed-secret-IARIJJ7Q.js} +11 -3
  227. package/dist/materialized-views/index.js +22 -21
  228. package/dist/migrate-cek-XM2ETTZW.js +19 -0
  229. package/dist/migrate-cek-XM2ETTZW.js.map +1 -0
  230. package/dist/money/index.js +12 -8
  231. package/dist/noydb-IRILUDED.js +84 -0
  232. package/dist/overlay-views/index.js +4 -4
  233. package/dist/periods/index.js +22 -12
  234. package/dist/pod/index.js +75 -86
  235. package/dist/pod-handle-MELERCKU.js +41 -0
  236. package/dist/pod-handle-MELERCKU.js.map +1 -0
  237. package/dist/policy/index.js +11 -4
  238. package/dist/port/to/index.d.ts +4 -4
  239. package/dist/port/to/locator.d.ts +54 -8
  240. package/dist/port/with/i18n-strategy.d.ts +4 -1
  241. package/dist/port/with/lookup-strategy.d.ts +4 -1
  242. package/dist/port/with/merge-authority.d.ts +52 -0
  243. package/dist/port/with/service-bus.d.ts +0 -4
  244. package/dist/port/with/strategies.d.ts +2 -0
  245. package/dist/port/with/team-strategy.d.ts +5 -1
  246. package/dist/portability/index.js +8 -8
  247. package/dist/{post-register-ZAG2CAIY.js → post-register-Z5T7FY45.js} +6 -6
  248. package/dist/query/index.js +3 -3
  249. package/dist/reduce/index.js +4 -4
  250. package/dist/register-UZ37QPDB.js +32 -0
  251. package/dist/registry-ETJNA7PO.js +9 -0
  252. package/dist/registry-F7U6KSLX.js +9 -0
  253. package/dist/registry-L4ELKX6C.js +18 -0
  254. package/dist/registry-SDT5LIGO.js +19 -0
  255. package/dist/request-withdrawal-PVFEYX57.js +31 -0
  256. package/dist/{reveal-CMOJY4VO.js → reveal-DQ2E3QAZ.js} +6 -6
  257. package/dist/revoke-YXY6SHUH.js +24 -0
  258. package/dist/satellites/index.js +1 -1
  259. package/dist/schema-update/index.js +2 -2
  260. package/dist/sealed-record/index.js +20 -13
  261. package/dist/sealed-record/index.js.map +1 -1
  262. package/dist/search/index.js +4 -4
  263. package/dist/{seed-UK4QRIUN.js → seed-DZ4ORU5N.js} +19 -22
  264. package/dist/seed-DZ4ORU5N.js.map +1 -0
  265. package/dist/sequence/index.js +9 -9
  266. package/dist/session/index.js +10 -10
  267. package/dist/shadow/index.js +2 -2
  268. package/dist/share-link/index.js +1 -1
  269. package/dist/signer-Q7XQBMPA.js +25 -0
  270. package/dist/snapshots/index.js +10 -10
  271. package/dist/snapshots/index.js.map +1 -1
  272. package/dist/{stale-ZWXSOWJI.js → stale-NI7SAXAZ.js} +10 -10
  273. package/dist/storage-3VNGSHXS.js +23 -0
  274. package/dist/{store-coordination-provider-PB6QZ57W.js → store-coordination-provider-TYKNR3OU.js} +18 -12
  275. package/dist/store-coordination-provider-TYKNR3OU.js.map +1 -0
  276. package/dist/sync/index.js +11 -11
  277. package/dist/team/index.js +15 -14
  278. package/dist/tiers/index.js +11 -10
  279. package/dist/to/index.js +17 -9
  280. package/dist/to/index.js.map +1 -1
  281. package/dist/transactions/index.js +4 -4
  282. package/dist/{ulid-PTAIMDG4.js → ulid-VQW6ERQN.js} +2 -2
  283. package/dist/util/index.js +1 -1
  284. package/dist/vault-head/index.js +115 -0
  285. package/dist/vault-head/index.js.map +1 -0
  286. package/dist/{verify-RO5RTZOJ.js → verify-6J2YLKSO.js} +5 -5
  287. package/dist/via/lookup/handle.d.ts +4 -1
  288. package/dist/via/money/exact.d.ts +44 -0
  289. package/dist/via/money/index.d.ts +2 -0
  290. package/dist/via/money/normalize.d.ts +20 -0
  291. package/dist/walk-WRA7RAPY.js +21 -0
  292. package/dist/with-audit/guards/immutable-guard.d.ts +14 -0
  293. package/dist/with-audit/periods/active.d.ts +28 -1
  294. package/dist/with-audit/periods/index.d.ts +4 -2
  295. package/dist/with-audit/periods/periods.d.ts +161 -6
  296. package/dist/with-audit/periods/strategy.d.ts +14 -5
  297. package/dist/with-audit/periods/vault-facade.d.ts +89 -10
  298. package/dist/with-audit/periods/window.d.ts +10 -0
  299. package/dist/with-audit/sealed-record/index.d.ts +13 -0
  300. package/dist/with-audit/tiers/index.d.ts +17 -2
  301. package/dist/with-cargo/adopt-partition.d.ts +1 -1
  302. package/dist/with-cargo/extract-partition.d.ts +1 -1
  303. package/dist/with-cargo/index.d.ts +2 -2
  304. package/dist/with-commit/history/history.d.ts +26 -0
  305. package/dist/with-commit/history/index.d.ts +2 -1
  306. package/dist/with-commit/history/ledger/store.d.ts +7 -1
  307. package/dist/with-commit/history/strategy.d.ts +11 -1
  308. package/dist/with-commit/numbering/index.d.ts +0 -5
  309. package/dist/with-commit/vault-head/active.d.ts +2 -0
  310. package/dist/with-commit/vault-head/head.d.ts +28 -0
  311. package/dist/with-commit/vault-head/index.d.ts +10 -0
  312. package/dist/with-commit/vault-head/strategy.d.ts +127 -0
  313. package/dist/with-commit/vault-head/verify.d.ts +90 -0
  314. package/dist/with-formula/materialized-views/types.d.ts +52 -0
  315. package/dist/with-party/directory/cover/storage.d.ts +0 -8
  316. package/dist/with-party/directory/storage.d.ts +0 -11
  317. package/dist/with-party/directory/visibility.d.ts +0 -21
  318. package/dist/with-party/policy/storage.d.ts +0 -10
  319. package/dist/with-party/team/index.d.ts +1 -1
  320. package/dist/with-party/team/keyring.d.ts +149 -3
  321. package/dist/with-party/team/noydb-facade.d.ts +5 -1
  322. package/dist/with-party/team/roster-tag.d.ts +101 -0
  323. package/dist/with-party/team/tiers.d.ts +2 -1
  324. package/dist/with-pod/format.d.ts +10 -12
  325. package/dist/with-pod/index.d.ts +10 -10
  326. package/dist/with-pod/open.d.ts +2 -2
  327. package/dist/with-pod/pod-handle.d.ts +19 -0
  328. package/dist/with-pod/pod-store.d.ts +0 -8
  329. package/dist/with-pod/{bundle.d.ts → pod.d.ts} +26 -19
  330. package/dist/with-pod/ulid.d.ts +1 -1
  331. package/dist/with-shape/blobs/blob-set.d.ts +2 -2
  332. package/dist/with-shape/introspection/index.d.ts +1 -0
  333. package/dist/with-sync/engine.d.ts +54 -5
  334. package/dist/with-sync/strategy.d.ts +3 -0
  335. package/dist/withdraw-accessible-4JTDFRFZ.js +28 -0
  336. package/package.json +13 -5
  337. package/dist/api-WVY3H3YH.js +0 -20
  338. package/dist/backup-YYBE5RPC.js.map +0 -1
  339. package/dist/bundle-handle-JEUWU2SJ.js +0 -36
  340. package/dist/bundle-handle-JEUWU2SJ.js.map +0 -1
  341. package/dist/chunk-26JMGSSC.js.map +0 -1
  342. package/dist/chunk-3737A6EA.js.map +0 -1
  343. package/dist/chunk-4MC5JRRX.js.map +0 -1
  344. package/dist/chunk-52QYGZHH.js.map +0 -1
  345. package/dist/chunk-55LKVALY.js.map +0 -1
  346. package/dist/chunk-5PR33AC4.js.map +0 -1
  347. package/dist/chunk-66W5OOCX.js.map +0 -1
  348. package/dist/chunk-7G6VDWXB.js.map +0 -1
  349. package/dist/chunk-A67356IR.js.map +0 -1
  350. package/dist/chunk-AFHQATY4.js +0 -47
  351. package/dist/chunk-AFHQATY4.js.map +0 -1
  352. package/dist/chunk-AHLJSVRL.js.map +0 -1
  353. package/dist/chunk-C2OOEM57.js.map +0 -1
  354. package/dist/chunk-DIMKRG2E.js +0 -131
  355. package/dist/chunk-DIMKRG2E.js.map +0 -1
  356. package/dist/chunk-E6427JU2.js.map +0 -1
  357. package/dist/chunk-E7OBCBXS.js.map +0 -1
  358. package/dist/chunk-EDXAQ6JI.js.map +0 -1
  359. package/dist/chunk-EP7VPR7Y.js.map +0 -1
  360. package/dist/chunk-ERB6NDDW.js.map +0 -1
  361. package/dist/chunk-G5APARUV.js.map +0 -1
  362. package/dist/chunk-GASWQ3XG.js.map +0 -1
  363. package/dist/chunk-GLKDWWNO.js.map +0 -1
  364. package/dist/chunk-HNGSV2YC.js.map +0 -1
  365. package/dist/chunk-I4F6PKUK.js.map +0 -1
  366. package/dist/chunk-I4ZAO7F7.js.map +0 -1
  367. package/dist/chunk-I6SDX7WX.js.map +0 -1
  368. package/dist/chunk-JXIDGFKS.js.map +0 -1
  369. package/dist/chunk-LWSJG3LI.js.map +0 -1
  370. package/dist/chunk-MWKDOHEF.js.map +0 -1
  371. package/dist/chunk-MZ5ZFO2D.js.map +0 -1
  372. package/dist/chunk-NIVEDYJZ.js.map +0 -1
  373. package/dist/chunk-NWCGDAV6.js +0 -45
  374. package/dist/chunk-NWCGDAV6.js.map +0 -1
  375. package/dist/chunk-PJNTR2NV.js.map +0 -1
  376. package/dist/chunk-PRDRGL73.js.map +0 -1
  377. package/dist/chunk-PY7CI6L5.js.map +0 -1
  378. package/dist/chunk-RKKORO4M.js.map +0 -1
  379. package/dist/chunk-TAGFGKHP.js.map +0 -1
  380. package/dist/chunk-TDJPS3T2.js.map +0 -1
  381. package/dist/chunk-TOAIYQJR.js.map +0 -1
  382. package/dist/chunk-UHXCLPGC.js.map +0 -1
  383. package/dist/chunk-UIBGXRDD.js.map +0 -1
  384. package/dist/chunk-V5KYPBUR.js.map +0 -1
  385. package/dist/chunk-VCETL77O.js.map +0 -1
  386. package/dist/chunk-VN45YLWM.js.map +0 -1
  387. package/dist/chunk-VOQW5LAM.js.map +0 -1
  388. package/dist/chunk-VRA4Q7DA.js.map +0 -1
  389. package/dist/chunk-VV4NSB7P.js.map +0 -1
  390. package/dist/chunk-W5W6KHN2.js.map +0 -1
  391. package/dist/chunk-WHJKIZS7.js.map +0 -1
  392. package/dist/chunk-WYZ5MYUA.js.map +0 -1
  393. package/dist/chunk-ZJADGNYF.js.map +0 -1
  394. package/dist/chunk-ZNACADFG.js.map +0 -1
  395. package/dist/collection-facade-QN5ULWYC.js +0 -45
  396. package/dist/delegation-SSEPLXXO.js.map +0 -1
  397. package/dist/derive-6V3PIZF7.js +0 -22
  398. package/dist/executor-CYJQLKKI.js +0 -9
  399. package/dist/executor-FHHLXO4Y.js +0 -28
  400. package/dist/executor-S4QIKEHW.js +0 -9
  401. package/dist/export-accessible-PE5AYKZR.js +0 -23
  402. package/dist/extract-partition-X2L26O6A.js +0 -38
  403. package/dist/fanout-sidecar-DTBIDOWF.js.map +0 -1
  404. package/dist/find-RBBYKXI7.js +0 -11
  405. package/dist/issue-RNU55YOF.js +0 -19
  406. package/dist/liberate-PX4CAT5V.js +0 -24
  407. package/dist/noydb-YPSEGK32.js +0 -83
  408. package/dist/register-TMD6YRCX.js +0 -32
  409. package/dist/registry-CZVINVQH.js +0 -9
  410. package/dist/registry-FVLDWQKT.js +0 -18
  411. package/dist/registry-IKUR2MXD.js +0 -9
  412. package/dist/registry-JET4HBLY.js +0 -19
  413. package/dist/request-withdrawal-RH55LNZL.js +0 -31
  414. package/dist/revoke-R5TBYVA6.js +0 -24
  415. package/dist/seed-UK4QRIUN.js.map +0 -1
  416. package/dist/signer-AGALOXOO.js +0 -25
  417. package/dist/storage-N7LB275C.js +0 -23
  418. package/dist/store-coordination-provider-PB6QZ57W.js.map +0 -1
  419. package/dist/walk-OCUHCYJ6.js +0 -21
  420. package/dist/with-pod/bundle-handle.d.ts +0 -9
  421. package/dist/withdraw-accessible-QQNWM5BO.js +0 -28
  422. /package/dist/{api-WVY3H3YH.js.map → api-EYNT6KGS.js.map} +0 -0
  423. /package/dist/{chunk-35EBKWQU.js.map → chunk-2LFOMUEA.js.map} +0 -0
  424. /package/dist/{chunk-OF3L2SD6.js.map → chunk-32B7VCKU.js.map} +0 -0
  425. /package/dist/{chunk-MSWYQLMQ.js.map → chunk-3B6S6RSI.js.map} +0 -0
  426. /package/dist/{chunk-7F4DBNSP.js.map → chunk-3O72ZD2E.js.map} +0 -0
  427. /package/dist/{chunk-FNSMZQS4.js.map → chunk-3PMFMUFX.js.map} +0 -0
  428. /package/dist/{chunk-FAXZQ5UF.js.map → chunk-4RAS6HN6.js.map} +0 -0
  429. /package/dist/{chunk-VMCCGUQB.js.map → chunk-6JPGVL7X.js.map} +0 -0
  430. /package/dist/{chunk-WLYIROCJ.js.map → chunk-6YD5SYQS.js.map} +0 -0
  431. /package/dist/{chunk-YAWK6AWF.js.map → chunk-7KAE7CQ2.js.map} +0 -0
  432. /package/dist/{chunk-NKH7GSIH.js.map → chunk-AUPSEJ7O.js.map} +0 -0
  433. /package/dist/{chunk-CCZJJ4I2.js.map → chunk-B6IYATME.js.map} +0 -0
  434. /package/dist/{chunk-4UVDI4XE.js.map → chunk-CLAHBPOI.js.map} +0 -0
  435. /package/dist/{chunk-HVQGCKY4.js.map → chunk-D3R7Q4QK.js.map} +0 -0
  436. /package/dist/{chunk-P7OG2ETF.js.map → chunk-DXKLLKME.js.map} +0 -0
  437. /package/dist/{chunk-JIUVJ4M7.js.map → chunk-EKEIEJL6.js.map} +0 -0
  438. /package/dist/{chunk-DG27IUVI.js.map → chunk-FS7NTGCJ.js.map} +0 -0
  439. /package/dist/{chunk-HXGUIPQB.js.map → chunk-GQXFOAYZ.js.map} +0 -0
  440. /package/dist/{chunk-BTVYJWSN.js.map → chunk-GTHVPVAR.js.map} +0 -0
  441. /package/dist/{chunk-DMQCLZ4Z.js.map → chunk-GWO2IDAB.js.map} +0 -0
  442. /package/dist/{chunk-6HFM7EIT.js.map → chunk-H3G4I3PN.js.map} +0 -0
  443. /package/dist/{chunk-VJFMXYKP.js.map → chunk-HR5R5JOM.js.map} +0 -0
  444. /package/dist/{chunk-FDX7OWWI.js.map → chunk-HYYVT2KZ.js.map} +0 -0
  445. /package/dist/{chunk-JRCYZEHU.js.map → chunk-I6QKB7MT.js.map} +0 -0
  446. /package/dist/{chunk-KUDZVJKQ.js.map → chunk-IJ46VCWD.js.map} +0 -0
  447. /package/dist/{chunk-4HDYQL3J.js.map → chunk-INMHEMXX.js.map} +0 -0
  448. /package/dist/{chunk-AR2JDFAE.js.map → chunk-KV6JM2IA.js.map} +0 -0
  449. /package/dist/{chunk-PVU7LW5L.js.map → chunk-KX57HODD.js.map} +0 -0
  450. /package/dist/{chunk-CEJWMBXO.js.map → chunk-LXECF2ZR.js.map} +0 -0
  451. /package/dist/{chunk-7VHY5E3X.js.map → chunk-MSLPDFK2.js.map} +0 -0
  452. /package/dist/{chunk-HNHCQ556.js.map → chunk-NR2SUJ3H.js.map} +0 -0
  453. /package/dist/{chunk-W3TVWF6N.js.map → chunk-OIBEJN5H.js.map} +0 -0
  454. /package/dist/{chunk-QD724WDJ.js.map → chunk-OMYCSTXL.js.map} +0 -0
  455. /package/dist/{chunk-Z45YRGFO.js.map → chunk-ONVD6GBY.js.map} +0 -0
  456. /package/dist/{chunk-KCQX65FU.js.map → chunk-RKCRPPNB.js.map} +0 -0
  457. /package/dist/{chunk-7TSYBD3E.js.map → chunk-RSXQNFGO.js.map} +0 -0
  458. /package/dist/{chunk-7NXHMW6Y.js.map → chunk-SYS46BL7.js.map} +0 -0
  459. /package/dist/{chunk-747LRSOO.js.map → chunk-TMBSPLUG.js.map} +0 -0
  460. /package/dist/{chunk-WKPJXWKR.js.map → chunk-TX5MKAHA.js.map} +0 -0
  461. /package/dist/{chunk-NJDQ4YSV.js.map → chunk-YKXZHUOW.js.map} +0 -0
  462. /package/dist/{chunk-VW6ZZGCG.js.map → chunk-ZLHHE5XZ.js.map} +0 -0
  463. /package/dist/{chunk-FUHKW252.js.map → chunk-ZZXLB6AS.js.map} +0 -0
  464. /package/dist/{classified-marker-FTOX7Q5L.js.map → classified-marker-NA6HUV33.js.map} +0 -0
  465. /package/dist/{collection-facade-QN5ULWYC.js.map → collection-facade-VBM35WAH.js.map} +0 -0
  466. /package/dist/{computed-6G5M3UPH.js.map → computed-GSTLWSY5.js.map} +0 -0
  467. /package/dist/{dead-filter-ENRIOQIE.js.map → dead-filter-UALP5DJX.js.map} +0 -0
  468. /package/dist/{derive-6V3PIZF7.js.map → derive-YUO3TQYN.js.map} +0 -0
  469. /package/dist/{dispatch-RE74SH6L.js.map → dispatch-4ZHLSFZQ.js.map} +0 -0
  470. /package/dist/{dispatch-BDVGYC6X.js.map → dispatch-77CB75KB.js.map} +0 -0
  471. /package/dist/{enclave-52VUXNRL.js.map → enclave-O4NOROCJ.js.map} +0 -0
  472. /package/dist/{executor-CYJQLKKI.js.map → executor-CZDXBXKE.js.map} +0 -0
  473. /package/dist/{executor-FHHLXO4Y.js.map → executor-DVJAWN3B.js.map} +0 -0
  474. /package/dist/{executor-S4QIKEHW.js.map → executor-VRLG4TQJ.js.map} +0 -0
  475. /package/dist/{export-accessible-PE5AYKZR.js.map → export-accessible-UXSMG7AB.js.map} +0 -0
  476. /package/dist/{extract-partition-X2L26O6A.js.map → extract-partition-TVY7AMKH.js.map} +0 -0
  477. /package/dist/{find-RBBYKXI7.js.map → find-WSARMJBW.js.map} +0 -0
  478. /package/dist/{issue-RNU55YOF.js.map → issue-3JNJNPT3.js.map} +0 -0
  479. /package/dist/{ledger-4WJL66BW.js.map → ledger-MVPNG5OS.js.map} +0 -0
  480. /package/dist/{liberate-PX4CAT5V.js.map → liberate-4LOJOLDT.js.map} +0 -0
  481. /package/dist/{link-set-N4ZPV6E6.js.map → link-set-3POMQR3I.js.map} +0 -0
  482. /package/dist/{managed-secret-OTHS64IF.js.map → managed-secret-IARIJJ7Q.js.map} +0 -0
  483. /package/dist/{noydb-YPSEGK32.js.map → noydb-IRILUDED.js.map} +0 -0
  484. /package/dist/{post-register-ZAG2CAIY.js.map → post-register-Z5T7FY45.js.map} +0 -0
  485. /package/dist/{register-TMD6YRCX.js.map → register-UZ37QPDB.js.map} +0 -0
  486. /package/dist/{registry-CZVINVQH.js.map → registry-ETJNA7PO.js.map} +0 -0
  487. /package/dist/{registry-FVLDWQKT.js.map → registry-F7U6KSLX.js.map} +0 -0
  488. /package/dist/{registry-IKUR2MXD.js.map → registry-L4ELKX6C.js.map} +0 -0
  489. /package/dist/{registry-JET4HBLY.js.map → registry-SDT5LIGO.js.map} +0 -0
  490. /package/dist/{request-withdrawal-RH55LNZL.js.map → request-withdrawal-PVFEYX57.js.map} +0 -0
  491. /package/dist/{reveal-CMOJY4VO.js.map → reveal-DQ2E3QAZ.js.map} +0 -0
  492. /package/dist/{revoke-R5TBYVA6.js.map → revoke-YXY6SHUH.js.map} +0 -0
  493. /package/dist/{signer-AGALOXOO.js.map → signer-Q7XQBMPA.js.map} +0 -0
  494. /package/dist/{stale-ZWXSOWJI.js.map → stale-NI7SAXAZ.js.map} +0 -0
  495. /package/dist/{storage-N7LB275C.js.map → storage-3VNGSHXS.js.map} +0 -0
  496. /package/dist/{ulid-PTAIMDG4.js.map → ulid-VQW6ERQN.js.map} +0 -0
  497. /package/dist/{verify-RO5RTZOJ.js.map → verify-6J2YLKSO.js.map} +0 -0
  498. /package/dist/{walk-OCUHCYJ6.js.map → walk-WRA7RAPY.js.map} +0 -0
  499. /package/dist/{withdraw-accessible-QQNWM5BO.js.map → withdraw-accessible-4JTDFRFZ.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-audit/attestation/revoke.ts"],"sourcesContent":["import type { NoydbStore } from '../../kernel/types.js'\nimport { buildRecordAad, buildRecordEnvelope, encrypt, openEnvelopeJson, type EnclaveKey } from '../../kernel/enclave/index.js'\nimport { AttestationError, ConflictError } from '../../kernel/errors.js'\nimport { loadOrCreateSigner, ATTESTATIONS_COLLECTION, REVOKED_RECORD_ID } from './signer.js'\nimport { signRevocationList, type RevocationList } from '@noy-db/attestation'\n\n/** Everything the revoke core needs from the Vault, injected for testability. */\nexport interface RevokeContext {\n readonly store: NoydbStore\n readonly vault: string\n readonly role: string\n /** The _attestations collection DEK. */\n getDEK(): Promise<EnclaveKey>\n}\n\ninterface RevokedSet {\n docIds: string[]\n updatedAt: string\n}\n\nfunction requireOwner(ctx: RevokeContext, op: string): void {\n if (ctx.role !== 'owner') {\n throw new AttestationError(`${op} requires the 'owner' role; caller is '${ctx.role}'. Revocation is the firm's identity operation.`)\n }\n}\n\nasync function readSet(store: NoydbStore, vault: string, dek: EnclaveKey): Promise<{ docIds: Set<string>; version: number | undefined }> {\n const env = await store.get(vault, ATTESTATIONS_COLLECTION, REVOKED_RECORD_ID)\n if (!env) return { docIds: new Set<string>(), version: undefined }\n const set = JSON.parse(await openEnvelopeJson({ collection: ATTESTATIONS_COLLECTION, id: REVOKED_RECORD_ID }, env, dek)) as RevokedSet\n return { docIds: new Set(set.docIds), version: env._v }\n}\n\n/** Read-modify-write the _revoked set with optimistic concurrency + one retry. */\nasync function mutateSet(ctx: RevokeContext, mutate: (ids: Set<string>) => void): Promise<void> {\n const dek = await ctx.getDEK()\n for (let attempt = 0; attempt < 2; attempt++) {\n const { docIds, version } = await readSet(ctx.store, ctx.vault, dek)\n mutate(docIds)\n const payload: RevokedSet = { docIds: [...docIds].sort(), updatedAt: new Date().toISOString() }\n const expectedVersion = version ?? 0\n const identity = { collection: ATTESTATIONS_COLLECTION, id: REVOKED_RECORD_ID, version: expectedVersion + 1 }\n const { iv, data } = await encrypt(JSON.stringify(payload), dek, buildRecordAad(identity))\n const env = buildRecordEnvelope(\n identity,\n { ts: payload.updatedAt, iv, data },\n )\n try {\n await ctx.store.put(ctx.vault, ATTESTATIONS_COLLECTION, REVOKED_RECORD_ID, env, expectedVersion)\n return\n } catch (e) {\n if (e instanceof ConflictError && attempt === 0) continue\n throw e\n }\n }\n}\n\nexport async function revokeDocCore(ctx: RevokeContext, docId: string): Promise<void> {\n requireOwner(ctx, 'revokeAttestation')\n const issued = await ctx.store.get(ctx.vault, ATTESTATIONS_COLLECTION, docId)\n if (!issued) throw new AttestationError(`revokeAttestation: attestation '${docId}' not found (was it issued by this vault?).`)\n await mutateSet(ctx, (ids) => ids.add(docId))\n}\n\nexport async function unrevokeDocCore(ctx: RevokeContext, docId: string): Promise<void> {\n requireOwner(ctx, 'unrevokeAttestation')\n await mutateSet(ctx, (ids) => ids.delete(docId))\n}\n\nexport async function getRevokedDocIdsCore(ctx: RevokeContext): Promise<string[]> {\n const dek = await ctx.getDEK()\n const { docIds } = await readSet(ctx.store, ctx.vault, dek)\n return [...docIds].sort()\n}\n\nexport async function publishRevocationListCore(ctx: RevokeContext): Promise<RevocationList> {\n requireOwner(ctx, 'publishRevocationList')\n const docIds = await getRevokedDocIdsCore(ctx)\n const signer = await loadOrCreateSigner(ctx.store, ctx.vault, () => ctx.getDEK())\n return signRevocationList(docIds, new Date().toISOString(), signer.keyId, signer.privateKeyPkcs8B64)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAIA,SAAS,0BAA+C;AAgBxD,SAAS,aAAa,KAAoB,IAAkB;AAC1D,MAAI,IAAI,SAAS,SAAS;AACxB,UAAM,IAAI,iBAAiB,GAAG,EAAE,0CAA0C,IAAI,IAAI,iDAAiD;AAAA,EACrI;AACF;AAEA,eAAe,QAAQ,OAAmB,OAAe,KAAgF;AACvI,QAAM,MAAM,MAAM,MAAM,IAAI,OAAO,yBAAyB,iBAAiB;AAC7E,MAAI,CAAC,IAAK,QAAO,EAAE,QAAQ,oBAAI,IAAY,GAAG,SAAS,OAAU;AACjE,QAAM,MAAM,KAAK,MAAM,MAAM,iBAAiB,EAAE,YAAY,yBAAyB,IAAI,kBAAkB,GAAG,KAAK,GAAG,CAAC;AACvH,SAAO,EAAE,QAAQ,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,IAAI,GAAG;AACxD;AAGA,eAAe,UAAU,KAAoB,QAAmD;AAC9F,QAAM,MAAM,MAAM,IAAI,OAAO;AAC7B,WAAS,UAAU,GAAG,UAAU,GAAG,WAAW;AAC5C,UAAM,EAAE,QAAQ,QAAQ,IAAI,MAAM,QAAQ,IAAI,OAAO,IAAI,OAAO,GAAG;AACnE,WAAO,MAAM;AACb,UAAM,UAAsB,EAAE,QAAQ,CAAC,GAAG,MAAM,EAAE,KAAK,GAAG,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE;AAC9F,UAAM,kBAAkB,WAAW;AACnC,UAAM,WAAW,EAAE,YAAY,yBAAyB,IAAI,mBAAmB,SAAS,kBAAkB,EAAE;AAC5G,UAAM,EAAE,IAAI,KAAK,IAAI,MAAM,QAAQ,KAAK,UAAU,OAAO,GAAG,KAAK,eAAe,QAAQ,CAAC;AACzF,UAAM,MAAM;AAAA,MACV;AAAA,MACA,EAAE,IAAI,QAAQ,WAAW,IAAI,KAAK;AAAA,IACpC;AACA,QAAI;AACF,YAAM,IAAI,MAAM,IAAI,IAAI,OAAO,yBAAyB,mBAAmB,KAAK,eAAe;AAC/F;AAAA,IACF,SAAS,GAAG;AACV,UAAI,aAAa,iBAAiB,YAAY,EAAG;AACjD,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,eAAsB,cAAc,KAAoB,OAA8B;AACpF,eAAa,KAAK,mBAAmB;AACrC,QAAM,SAAS,MAAM,IAAI,MAAM,IAAI,IAAI,OAAO,yBAAyB,KAAK;AAC5E,MAAI,CAAC,OAAQ,OAAM,IAAI,iBAAiB,mCAAmC,KAAK,6CAA6C;AAC7H,QAAM,UAAU,KAAK,CAAC,QAAQ,IAAI,IAAI,KAAK,CAAC;AAC9C;AAEA,eAAsB,gBAAgB,KAAoB,OAA8B;AACtF,eAAa,KAAK,qBAAqB;AACvC,QAAM,UAAU,KAAK,CAAC,QAAQ,IAAI,OAAO,KAAK,CAAC;AACjD;AAEA,eAAsB,qBAAqB,KAAuC;AAChF,QAAM,MAAM,MAAM,IAAI,OAAO;AAC7B,QAAM,EAAE,OAAO,IAAI,MAAM,QAAQ,IAAI,OAAO,IAAI,OAAO,GAAG;AAC1D,SAAO,CAAC,GAAG,MAAM,EAAE,KAAK;AAC1B;AAEA,eAAsB,0BAA0B,KAA6C;AAC3F,eAAa,KAAK,uBAAuB;AACzC,QAAM,SAAS,MAAM,qBAAqB,GAAG;AAC7C,QAAM,SAAS,MAAM,mBAAmB,IAAI,OAAO,IAAI,OAAO,MAAM,IAAI,OAAO,CAAC;AAChF,SAAO,mBAAmB,SAAQ,oBAAI,KAAK,GAAE,YAAY,GAAG,OAAO,OAAO,OAAO,kBAAkB;AACrG;","names":[]}
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  dictCollectionName
3
- } from "./chunk-PRDRGL73.js";
3
+ } from "./chunk-6KTVJ5ZZ.js";
4
4
  import {
5
5
  getAtPath,
6
6
  presentI18nForJoin
7
- } from "./chunk-7G6VDWXB.js";
7
+ } from "./chunk-WVE6YKMX.js";
8
8
  import {
9
9
  PeriodClosedError,
10
10
  UnknownDictCodeError,
11
11
  ValidationError
12
- } from "./chunk-HNGSV2YC.js";
12
+ } from "./chunk-CWM4GQD2.js";
13
13
 
14
14
  // src/via/lookup/registry.ts
15
15
  function enforceStaticDictOnPut(staticFields, record) {
@@ -487,4 +487,4 @@ export {
487
487
  forgetDerivedFanout,
488
488
  selfWriteFieldEqual
489
489
  };
490
- //# sourceMappingURL=chunk-ZNACADFG.js.map
490
+ //# sourceMappingURL=chunk-DVRZYAGT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/via/lookup/registry.ts","../src/via/lookup/snapshot.ts","../src/port/with/lookup-strategy.ts","../src/kernel/via/dispatch.ts"],"sourcesContent":["/**\n * Pure dict-registry helpers — extracted from `kernel/vault.ts`'s dict\n * bodies (#650 Task 1 — via-lookup extraction, phase D).\n *\n * These take the vault-resident registry Maps (and a couple of vault-bound\n * callbacks) as ARGUMENTS instead of closing over `this` — no `Vault`\n * import here, so this module stays a plain, testable function library.\n * `kernel/vault.ts` keeps the registry Maps themselves (they're populated\n * by `vault.collection()` and read by the backup path) and calls these\n * helpers through the `port/with/lookup-strategy.ts` seam.\n */\n\nimport { getAtPath } from '../../kernel/paths.js'\nimport { UnknownDictCodeError, ValidationError } from '../../kernel/errors.js'\nimport type { JoinableSource } from '../../kernel/query/index.js'\nimport type { FieldRef, ViaGraph } from '../../kernel/via/graph.js'\nimport type { StaticDictDescriptor } from '../../port/with/i18n-strategy.js'\nimport { dictCollectionName, type LookupHandle } from './handle.js'\nimport type { LookupDescriptor, OnDelete } from './descriptor.js'\n\n/**\n * Validate staticDict codes on a `put()`. For each `staticDict()` field,\n * every stored code must be a declared key of the descriptor's table, else\n * `UnknownDictCodeError`. Opt out per descriptor with `{ validateCodes:\n * false }`. Supports scalar, dotted, and `[].`-wildcard field paths via\n * `getAtPath` (same path support as i18n validation).\n *\n * `staticFields` is the collection's `field → StaticDictDescriptor` map\n * (`Vault#staticDescriptorByField.get(collectionName)`) — `undefined`/empty\n * is a no-op.\n */\nexport function enforceStaticDictOnPut(\n staticFields: Record<string, StaticDictDescriptor> | undefined,\n record: unknown,\n): void {\n if (!staticFields || Object.keys(staticFields).length === 0) return\n if (!record || typeof record !== 'object') return\n\n const obj = record as Record<string, unknown>\n for (const [field, desc] of Object.entries(staticFields)) {\n if (desc.validateCodes === false) continue\n const known = new Set<string>(desc.keys)\n const values = getAtPath(obj, field)\n for (const value of values) {\n if (value === undefined || value === null) continue\n const codes = Array.isArray(value) ? value : [value]\n for (const code of codes) {\n if (typeof code !== 'string') continue\n if (!known.has(code)) {\n throw new UnknownDictCodeError(desc.name, field, code)\n }\n }\n }\n }\n}\n\n/**\n * Build a `JoinableSource` for a dictKey field, for use in dict joins.\n * Returns a source whose snapshot contains `{ key, labels, ...labels }`\n * records — one per dictionary entry — keyed by the stable key.\n *\n * staticDict: a code-table-backed source — snapshot() materialises the\n * in-memory table into rows, mirroring `LookupHandle.snapshotEntries()`.\n * Carries `displayLocale` so a locale-less `{ by: 'label' }` query has a\n * default locale to resolve at.\n *\n * Plain dictKey: the snapshot is built synchronously from the\n * `LookupHandle`'s write-through cache, which is populated on every\n * `put()`, `rename()`, `delete()`, and `list()` call. For pre-existing\n * data not yet touched this session, call `await vault.dictionary(name).list()`\n * first to warm the cache.\n *\n * Returns `null` when `field` is not a dictKey in `leftCollection`.\n */\nexport function resolveDictSource(\n leftCollection: string,\n field: string,\n staticDescriptorByField: ReadonlyMap<string, Record<string, StaticDictDescriptor>>,\n dictKeyFieldRegistry: ReadonlyMap<string, Record<string, string>>,\n getDictionaryHandle: (name: string) => LookupHandle,\n): JoinableSource | null {\n const staticFields = staticDescriptorByField.get(leftCollection)\n if (staticFields && field in staticFields) {\n const desc = staticFields[field]!\n const rows: readonly Record<string, unknown>[] = Object.entries(desc.table).map(\n ([key, labels]) => ({ key, labels, ...(labels as Record<string, string>) }),\n )\n const source: JoinableSource = {\n snapshot(): readonly unknown[] {\n return rows\n },\n lookupById(id: string): unknown {\n return rows.find((e) => e['key'] === id)\n },\n }\n if (desc.displayLocale !== undefined) {\n ;(source as { displayLocale?: string }).displayLocale = desc.displayLocale\n }\n return source\n }\n\n const dictFields = dictKeyFieldRegistry.get(leftCollection)\n if (!dictFields || !(field in dictFields)) return null\n const dictName = dictFields[field]\n if (!dictName) return null\n const handle = getDictionaryHandle(dictName)\n return {\n snapshot(): readonly unknown[] {\n return handle.snapshotEntries()\n },\n lookupById(id: string): unknown {\n const entries = handle.snapshotEntries()\n return entries.find((e) => e['key'] === id)\n },\n }\n}\n\n/** The minimal collection surface `updateReferencingRecords` needs. */\nexport interface DictReferencingCollection {\n list(): Promise<Record<string, unknown>[]>\n put(id: string, record: Record<string, unknown>): Promise<unknown>\n}\n\n/**\n * Find and rewrite records in every registered collection whose\n * dictKeyField points at `name`, replacing `oldKey` with `newKey`. Used by\n * `LookupHandle.rename()` (the only sanctioned mass-mutation path for\n * dictKey fields) via the vault's `findAndUpdateReferences` callback.\n *\n * `registry` is `Vault#dictKeyFieldRegistry` (collection name → field name\n * → dictionary name); `getCollection` is the vault's collection accessor —\n * rewrites go through the public `coll.put()` choke point, same as before.\n */\nexport async function updateReferencingRecords(\n registry: ReadonlyMap<string, Record<string, string>>,\n getCollection: (collectionName: string) => DictReferencingCollection,\n name: string,\n oldKey: string,\n newKey: string,\n): Promise<void> {\n for (const [collectionName, dictFields] of registry) {\n // Find fields that point at this dictionary\n const fields = Object.entries(dictFields)\n .filter(([, dn]) => dn === name)\n .map(([field]) => field)\n if (fields.length === 0) continue\n\n const coll = getCollection(collectionName)\n const records = await coll.list()\n for (const record of records) {\n let changed = false\n const updated = { ...record }\n for (const field of fields) {\n if (updated[field] === oldKey) {\n updated[field] = newKey\n changed = true\n }\n }\n if (changed) {\n const id = record['id'] as string | undefined\n if (id !== undefined) {\n await coll.put(id, updated)\n }\n }\n }\n }\n}\n\n/**\n * Resolve a label from an in-memory `{ locale -> label }` map, walking the\n * same fallback chain semantics as `LookupHandle.resolveLabel` (#650 Task 2\n * — moved here from `kernel/vault.ts` so the SAME chain serves both the\n * i18n binding's `dictLabelResolver` and the lookup binding's\n * `lookupLabelResolver`, which #650 Task 2 wires to the identical closure).\n */\nexport function resolveLabelFromMap(\n labels: Readonly<Record<string, string>>,\n locale: string,\n fallback?: string | readonly string[],\n): string | undefined {\n if (labels[locale] !== undefined) return labels[locale]\n const chain = Array.isArray(fallback)\n ? (fallback as readonly string[])\n : fallback\n ? [fallback as string]\n : []\n for (const fb of chain) {\n if (fb === 'any') {\n const any = Object.values(labels)[0]\n if (any !== undefined) return any\n } else if (labels[fb] !== undefined) {\n return labels[fb]\n }\n }\n return undefined\n}\n\n/**\n * Project a native `lookup(dimension, { backing:'static', table, … })`\n * descriptor into the legacy `StaticDictDescriptor` shape — the\n * alias-equivalence compat seam (#650 Task 2) that lets a native\n * static-tier lookup field reuse the SAME vault registries\n * (`staticByName`/`staticDescriptorByField`) — and therefore the same\n * `dictLabelResolver`/`resolveDictSource` machinery — as its `staticDict()`\n * alias. `vocabulary:'closed'` maps to `validateCodes:true` (closed = only\n * declared codes are legal); `'open'` maps to `validateCodes:false`.\n * Returns `undefined` for non-static or table-less (bare `enumOf`)\n * descriptors — those have nothing to register.\n */\nexport function lookupToStaticDictCompat(desc: LookupDescriptor): StaticDictDescriptor | undefined {\n if (desc.backing !== 'static' || desc.table === undefined) return undefined\n return {\n _noydbStaticDict: true,\n _viaBrand: 'i18n',\n name: desc.dimension,\n table: desc.table,\n keys: desc.keys ?? Object.keys(desc.table),\n ...(desc.displayLocale !== undefined ? { displayLocale: desc.displayLocale } : {}),\n ...(desc.onMissing !== undefined ? { onMissing: desc.onMissing } : {}),\n ...(desc.substitute !== undefined ? { substitute: desc.substitute } : {}),\n validateCodes: desc.vocabulary === 'closed',\n }\n}\n\n/** The vault-registry entries a collection's `lookupFields` contribute — the alias-equivalence bridge (#650 Task 2). */\nexport interface LookupDictCompat {\n /** Reserved-tier fields: field name -> dimension (dictionary) name — merges into `dictKeyFieldRegistry`. */\n readonly dictFieldMap: Record<string, string>\n /** Static-tier (table-bearing) fields, projected — merges into `staticDescriptorByField`/`staticByName`. */\n readonly staticEntries: ReadonlyArray<readonly [string, StaticDictDescriptor]>\n}\n\n/**\n * Bridge a collection's `lookupFields` into the SAME shape the legacy dict\n * registries expect, so `resolveDictSource`/`dictLabelResolver` (and\n * therefore `.join()`/`orderBy({by:'label'})`) serve a native `dict()`/\n * `lookup(static)` field identically to its `dictKey()`/`staticDict()`\n * alias — the reserved-vs-first-class-backing \"matrix\" tier is NOT bridged\n * here (no vault registry backs it; Task 5/6 build its own graph edge /\n * snapshot seam).\n */\nexport function collectLookupDictCompat(\n lookupFields: Record<string, LookupDescriptor> | undefined,\n): LookupDictCompat {\n const dictFieldMap: Record<string, string> = {}\n const staticEntries: Array<readonly [string, StaticDictDescriptor]> = []\n for (const [field, desc] of Object.entries(lookupFields ?? {})) {\n if (desc.backing === 'reserved') {\n dictFieldMap[field] = desc.dimension\n } else {\n const compat = lookupToStaticDictCompat(desc)\n if (compat) staticEntries.push([field, compat])\n }\n }\n return { dictFieldMap, staticEntries }\n}\n\n/**\n * Reserved-dict deps of a set of named collections (#653) — the `_dict_*`\n * collections partial sync must auto-include alongside a `collections`\n * filter, mirroring `SyncEngine`'s existing satellite-pair expansion.\n * One hop is provably complete: `vault.collection()` refuses `_dict_*`\n * names, so a dict can never itself declare lookup fields — no\n * dict-of-dict chain to recurse through.\n */\nexport function reservedDictDepsOf(\n names: readonly string[],\n dictKeyFieldRegistry: ReadonlyMap<string, Record<string, string>>,\n): readonly string[] {\n const out = new Set<string>()\n for (const name of names) {\n const fieldMap = dictKeyFieldRegistry.get(name)\n if (!fieldMap) continue\n for (const dictName of Object.values(fieldMap)) out.add(dictCollectionName(dictName))\n }\n return [...out]\n}\n\n/**\n * A lookup dimension's sync membership/altKey table, materialized from its\n * backing rows (#650 Task 3). `keys` is every canonical key present;\n * `altIndex` maps an altKey candidate VALUE to its owning canonical key.\n */\nexport interface MaterializedBacking {\n /** Canonical key values present in the materialized rows. */\n readonly keys: ReadonlySet<string>\n /** altKey candidate value -> canonical key. */\n readonly altIndex: ReadonlyMap<string, string>\n}\n\n/**\n * Build a lookup dimension's altKey index from its backing rows, enforcing\n * declare/warm-time uniqueness across `key ∪ altKeys` values (#650 Task 3 —\n * the CHE/SWZ drift class: two different rows must never claim the same\n * candidate key). `rows` is keyed by canonical key (`row[descriptor.key]`\n * for the matrix tier; the dimension's own key for static/reserved).\n * An altKey candidate VALUE may be a string or number — both normalize via\n * `coerceLookupKey` (#651 Task 3); non-scalar/absent values are skipped.\n * Pure — no I/O. Throws `ValidationError` on collision.\n */\nexport function materializeBackingTable(\n descriptor: LookupDescriptor,\n rows: ReadonlyMap<string, Record<string, unknown>>,\n): MaterializedBacking {\n const keys = new Set<string>(rows.keys())\n // Every value that has claimed ownership so far (canonical keys seed it) —\n // the union `key ∪ altKeys` uniqueness set the spec requires.\n const owner = new Map<string, string>()\n for (const key of keys) owner.set(key, key)\n\n const altIndex = new Map<string, string>()\n const altFields = descriptor.altKeys ?? []\n for (const [canonicalKey, row] of rows) {\n for (const altField of altFields) {\n const value = coerceLookupKey(row[altField])\n if (value === undefined || value === '') continue\n const existingOwner = owner.get(value)\n if (existingOwner !== undefined && existingOwner !== canonicalKey) {\n throw new ValidationError(\n `lookup \"${descriptor.dimension}\": altKey field \"${altField}\" value \"${value}\" is claimed by ` +\n `both \"${existingOwner}\" and \"${canonicalKey}\" — key/altKey values must be unique across the dimension.`,\n )\n }\n owner.set(value, canonicalKey)\n altIndex.set(value, canonicalKey)\n }\n }\n return { keys, altIndex }\n}\n\n/**\n * Closed-vocabulary membership test for one candidate key (#650 Task 3).\n * Static tier: sync, against the in-config key set (declared `keys`, or the\n * table's own keys when table-bearing). Reserved tier: sync — the declared\n * `keys` union the reserved handle's live write-through snapshot (closes\n * #649 for the native `dict()` spelling: the declared-keys promise the old\n * `dictKey()` doc comment made falsely). Matrix (collection) tier: sync —\n * delegates to `buildLookupAltIndex` so membership is checked against the\n * SAME `row[descriptor.key]` keying the altKey index uses (review fix,\n * Important 1: an earlier PUT-id `.get(key)` scan disagreed with the\n * altIndex whenever `descriptor.key !== 'id'`, wrongly rejecting valid\n * non-id candidates and wrongly accepting an unrelated row's PUT-id).\n */\nexport function checkLookupMembership(\n descriptor: LookupDescriptor,\n key: string,\n getDictionary: (dimension: string) => LookupHandle,\n getCollection: (dimension: string) => { querySourceForJoin(): JoinableSource },\n): boolean {\n if (descriptor.backing === 'static') {\n const known = descriptor.keys ?? (descriptor.table ? Object.keys(descriptor.table) : [])\n return known.includes(key)\n }\n if (descriptor.backing === 'reserved') {\n if ((descriptor.keys ?? []).includes(key)) return true\n return getDictionary(descriptor.dimension).snapshotEntries().some((e) => e['key'] === key)\n }\n return buildLookupAltIndex(descriptor, getDictionary, getCollection).keys.has(key)\n}\n\n/**\n * The ONE guarded key coercion (#651 Task 3, dm12) — string/number values\n * coerce to their canonical `String()` form; everything else (`null`,\n * `undefined`, objects, …) coerces to `undefined`. Every consumer that turns\n * a raw record field into a lookup key routes through this, closing the\n * bare-`String()` `\"undefined\"`/`\"null\"`-key poisoning class (seam map\n * finding 6): a row whose key field is genuinely absent must never mint the\n * literal candidate string `\"undefined\"`.\n */\nexport function coerceLookupKey(raw: unknown): string | undefined {\n return typeof raw === 'string' || typeof raw === 'number' ? String(raw) : undefined\n}\n\n/**\n * Resolve a backing row's canonical key VALUE — `coerceLookupKey(row[descriptor.key])`\n * (#651 Task 3). The matrix tier's `row[descriptor.key]`, never the row's own PUT-id\n * when the two differ (`descriptor.key !== 'id'`).\n */\nexport function resolveBackingRowKey(\n descriptor: LookupDescriptor,\n row: Record<string, unknown>,\n): string | undefined {\n return coerceLookupKey(row[descriptor.key])\n}\n\n/**\n * The referencing-side match predicate — does `rec[field]` (coerced) equal an\n * already-coerced `compareKey` (#651 Task 3)? Shared by every site that scans a\n * referencing collection for rows pointing at a given backing key\n * (`with-shape/links/vault-facade.ts`'s ref-delete propagation, `kernel/via/dispatch.ts`'s\n * forget-fanout twin).\n */\nexport function matchesReferencingValue(\n rec: Record<string, unknown>,\n field: string,\n compareKey: string,\n): boolean {\n return coerceLookupKey(rec[field]) === compareKey\n}\n\n/**\n * Materialize a lookup dimension's altKey index from whatever backing data\n * is synchronously available (#650 Task 3 — the `ingest` source). Static:\n * the in-config table. Reserved: the reserved handle's live write-through\n * cache (the same warm-via-put()/list() cache `resolveDictSource` already\n * relies on). Matrix (collection): the backing collection's own in-memory\n * eager cache via `querySourceForJoin()` — already public, already the\n * mechanism `.join()` uses (`with-shape/links/vault-facade.ts`'s\n * `resolveSource`); no new I/O, no fire-and-forget warm step. Like that\n * existing join precedent, a dimension collection this vault session has\n * not yet opened/populated sees an empty snapshot (no altKey normalization\n * until it has rows) — open/populate it first for normalization to apply.\n * A matrix row whose `descriptor.key` field coerces to `undefined` (missing/\n * non-scalar) is SKIPPED — never enters the index under a poisoned\n * `\"undefined\"` key (#651 Task 3, dm12).\n */\nexport function buildLookupAltIndex(\n descriptor: LookupDescriptor,\n getDictionary: (dimension: string) => LookupHandle,\n getCollection: (dimension: string) => { querySourceForJoin(): JoinableSource },\n): MaterializedBacking {\n if (descriptor.backing === 'static') {\n return materializeBackingTable(descriptor, new Map(Object.entries(descriptor.table ?? {})))\n }\n if (descriptor.backing === 'reserved') {\n const entries = getDictionary(descriptor.dimension).snapshotEntries()\n return materializeBackingTable(descriptor, new Map(entries.map((e) => [String(e['key']), e])))\n }\n const rows = getCollection(descriptor.dimension).querySourceForJoin().snapshot()\n const keyed = new Map<string, Record<string, unknown>>()\n for (const r of rows) {\n const row = r as Record<string, unknown>\n const key = resolveBackingRowKey(descriptor, row)\n if (key !== undefined) keyed.set(key, row)\n }\n return materializeBackingTable(descriptor, keyed)\n}\n\n/** One cross-collection `'ref'` graph edge a lookup field declares (#650 Task 5). Module-private —\n * only `registerLookupRefEdges` below (the exported entry point) consumes it. */\ninterface LookupRefEdge {\n readonly referencing: FieldRef\n readonly sources: readonly FieldRef[]\n readonly onDelete: OnDelete\n /** The backing dimension's canonical-key FIELD NAME on its own row (`desc.key` — matrix tier\n * only varies this; reserved/static tiers are always `'id'`). A referencing field always\n * stores THIS field's value, never the backing row's PUT-id when the two differ. */\n readonly keyField: string\n}\n\n/**\n * Compute the cross-collection `'ref'` edges a collection's `lookupFields` declare (#650 Task 5,\n * spec §4) — one edge per non-static-backing field: target = the referencing field; sources =\n * the backing dimension's whole-collection node (`field:'*'`, the wildcard key\n * `ViaGraph.referencingEdgesOf` does its O(1) reverse lookup against) PLUS, when the descriptor\n * names a presentation field (`present.label`), that SPECIFIC field too. `foldPosture`'s\n * `DEFAULT_POSTURE` is the fold's identity element, so adding the wildcard alongside a real field\n * source changes nothing when that field is plain — but folds in a classified/money posture when\n * it isn't (taint composition, spec §4: \"a lookup edge whose source names a classified field\n * contributes that field's posture\"). Static tier (`backing:'static'`) has no backing collection/\n * dimension rows to reference-check — excluded. Pure; consumed only by `registerLookupRefEdges` below.\n */\nfunction collectLookupRefEdges(\n collectionName: string,\n lookupFields: Record<string, LookupDescriptor> | undefined,\n): readonly LookupRefEdge[] {\n const edges: LookupRefEdge[] = []\n for (const [field, desc] of Object.entries(lookupFields ?? {})) {\n if (desc.backing === 'static') continue\n const backing = desc.backing === 'reserved' ? dictCollectionName(desc.dimension) : desc.dimension\n edges.push({\n referencing: { collection: collectionName, field },\n sources: [\n { collection: backing, field: '*' },\n ...(desc.present?.label !== undefined ? [{ collection: backing, field: desc.present.label }] : []),\n ],\n onDelete: desc.onDelete,\n keyField: desc.key,\n })\n }\n return edges\n}\n\n/** Thin wrapper — `collectLookupRefEdges` + one `graph.registerDerived` call per edge. Lets\n * `vault.collection()` (kernel-surface-budgeted, #650 Task 5) register a collection's lookup-ref\n * edges with a single line, keeping the ceiling-guarded call site a thin call (route logic here). */\nexport function registerLookupRefEdges(\n graph: ViaGraph,\n collectionName: string,\n lookupFields: Record<string, LookupDescriptor> | undefined,\n): void {\n for (const e of collectLookupRefEdges(collectionName, lookupFields)) {\n graph.registerDerived(e.referencing, e.sources, 'ref', 'record', e.onDelete, e.keyField)\n }\n}\n\n/**\n * `LookupViaConfig.snapshotFor`'s vault-built row source (#650 Task 6, spec\n * §5; matrix-tier coverage added #650 Task 7, spec §6 — Task 6 deferred it,\n * see `task-6-report.md`'s Concerns #1; the reviewer's Task-7 dispatch\n * refuted the \"needs a new vault-resident registry\" premise: the descriptor\n * is already in hand at both call sites, so `snapshotFor` just needs to\n * ACCEPT it). Takes the full `descriptor` (not a bare dimension name) so it\n * can route the matrix tier's `key` field, which — unlike reserved tier's\n * hardcoded `'id'` — varies per collection. Routes on `descriptor.backing`:\n *\n * - **reserved**: rows come straight from the SAME `LookupHandle.\n * snapshotEntries()` write-through cache `dictLabelResolver`/\n * `resolveDictSource` already read (no second copy), keyed by each\n * entry's own canonical `key` (always `'id'` by construction for this\n * tier — `dict()`'s factory hardcodes it).\n * - **collection** (matrix): rows come from `getCollection(dimension).\n * querySourceForJoin().snapshot()` — the SAME sync, already-live cache\n * `buildLookupAltIndex`'s matrix branch (above, this file) and `.join()`\n * itself already read — re-keyed via `resolveBackingRowKey(descriptor, row)`,\n * NOT the row's own PUT-id (which may differ when `key !== 'id'`; the exact\n * distinction the #650 Task 3 review fix already applies to\n * `checkLookupMembership`'s matrix branch). A row whose `descriptor.key`\n * field coerces to `undefined` is skipped (#651 Task 3, dm12).\n * - **static**: never routed here — `descriptor.table` is read directly by\n * the caller (`binding.ts`'s `compareLookupOrder`/`resolveLookupOrderLabel`,\n * `snapshot.ts`'s `presentLookupForJoin`); no vault call needed.\n *\n * `isReservedDimension` is the vault's `reservedLookupCollections`\n * membership test.\n */\nexport function buildLookupSnapshotRows(\n descriptor: LookupDescriptor,\n isReservedDimension: (dimension: string) => boolean,\n getDictionary: (dimension: string) => LookupHandle,\n getCollection: (dimension: string) => { querySourceForJoin(): JoinableSource },\n): ReadonlyMap<string, Record<string, unknown>> | undefined {\n const dimension = descriptor.dimension\n if (isReservedDimension(dimension)) {\n const rows = new Map<string, Record<string, unknown>>()\n for (const entry of getDictionary(dimension).snapshotEntries()) {\n const key = entry['key']\n if (typeof key === 'string') rows.set(key, entry)\n }\n return rows\n }\n if (descriptor.backing === 'collection') {\n const rawRows = getCollection(dimension).querySourceForJoin().snapshot()\n const rows = new Map<string, Record<string, unknown>>()\n for (const r of rawRows) {\n const row = r as Record<string, unknown>\n const key = resolveBackingRowKey(descriptor, row)\n if (key !== undefined) rows.set(key, row)\n }\n return rows\n }\n return undefined\n}\n","/**\n * The sync lookup snapshot + join/locale seam (#650 Task 6, spec §5 — \"the\n * snapshot+locale seam\"). Retires the #626 kernel→via grandfather:\n * `kernel/query/join.ts` no longer imports `via/i18n/core.js` directly\n * — it calls the `presentForJoin` hook this file's `buildPresentForJoin`\n * builds instead (seam map Part 2 item 4, the #626 reviewer-spec'd shape:\n * a sync `presentI18nForJoin`-class hook on `JoinableSource`).\n *\n * `LookupSnapshot` is the sync materialized `key -> row` view over ONE\n * lookup dimension's ALREADY-LIVE backing data (the `active.ts`\n * `_syncCache`/`snapshotEntries` write-through-cache pattern — never a\n * second copy of the data: `LookupViaConfig.snapshotFor`'s vault-built\n * closure reads the SAME `LookupHandle._syncCache` /\n * first-class-collection cache every other lookup consumer\n * (`dictLabelResolver`, `resolveDictSource`, `getAltIndex`) already reads).\n * Serves (reserved AND matrix tier since #650 Task 7 — `registry.ts`'s\n * `buildLookupSnapshotRows` routes both; static tier is read straight off\n * `descriptor.table` by every consumer below, never through this cache):\n * - join dressing (`presentForJoin`, consumed by `kernel/query/join.ts`\n * via `JoinableSource.presentForJoin`)\n * - dimension sort (`compareForOrder`, consumed by\n * `via/lookup/binding.ts`'s `ViaBinding.compareForOrder` closure)\n * - per-call-locale order-label resolution (`resolveOrderLabel`, #650\n * Task 7 — the `orderBy(..., {by:'label'})` channel `compareForOrder`\n * structurally can't serve, no locale param; consumed by\n * `kernel/query/builder.ts`'s `buildOrderLabelMaps`)\n * - membership: reserved/static-tier membership (#650 Task 3,\n * `checkLookupMembership`) already reads the identical sync caches\n * directly — not re-plumbed through this file; see\n * `.superpowers/sdd/task-6-report.md`'s \"bridge disposition\" section.\n *\n * Sync end-to-end (#553) — every function here is a pure, synchronous\n * transform over already-materialized rows; no store read, no Promise.\n */\nimport type { LookupDescriptor } from './descriptor.js'\nimport { presentI18nForJoin, type I18nTextDescriptor } from '../i18n/core.js'\n\n/** A lookup dimension's sync materialized view — see file header. */\nexport interface LookupSnapshot {\n /** The full backing row for `key`, or `undefined` when `key` isn't (yet) present in the snapshot. */\n row(key: string): Record<string, unknown> | undefined\n /** The dimension's declared presentation label for `key` at `locale` — mirrors `binding.ts`'s `fetchLookupLabel` (matrix-row branch), generalized to any tier's already-materialized rows. */\n label(key: string, locale: string, fallback?: unknown): string | undefined\n /**\n * Exact ordering for two canonical keys against `descriptor.sortBy`\n * (falls back to `present.label`, then to the raw keys) at `locale`.\n * Never throws — degrades to comparing the raw keys when no sortable\n * value resolves for either side.\n */\n compareKeys(a: string, b: string, locale: string): number\n}\n\n/** Read one row field, resolving a `by`-keyed (locale-map) value when `by` is declared. */\nfunction readRowField(\n row: Record<string, unknown> | undefined,\n field: string | undefined,\n by: string | undefined,\n locale: string,\n fallback?: unknown,\n): string | undefined {\n if (!row || field === undefined) return undefined\n const raw = row[field]\n if (by === undefined) return typeof raw === 'string' ? raw : undefined\n if (!raw || typeof raw !== 'object') return undefined\n const map = raw as Record<string, unknown>\n const val = map[locale]\n if (typeof val === 'string') return val\n if (typeof fallback === 'string' && typeof map[fallback] === 'string') return map[fallback]\n return undefined\n}\n\n/**\n * Build a sync `LookupSnapshot` over one dimension's already-materialized\n * rows (canonical-key -> row, the SAME keying `materializeBackingTable`\n * (`registry.ts`, #650 Task 3) uses). Pure — never reads a store.\n */\nexport function buildLookupSnapshot(\n dimension: string,\n rows: ReadonlyMap<string, Record<string, unknown>>,\n descriptor: LookupDescriptor,\n): LookupSnapshot {\n void dimension // identity only — kept for parity with materializeBackingTable/buildLookupAltIndex's signature and future diagnostics\n return {\n row: (key) => rows.get(key),\n label: (key, locale, fallback) =>\n readRowField(rows.get(key), descriptor.present?.label, descriptor.present?.by, locale, fallback),\n compareKeys: (a, b, locale) => {\n const sortField = descriptor.sortBy ?? descriptor.present?.label\n const av = readRowField(rows.get(a), sortField, descriptor.present?.by, locale) ?? a\n const bv = readRowField(rows.get(b), sortField, descriptor.present?.by, locale) ?? b\n return av < bv ? -1 : av > bv ? 1 : 0\n },\n }\n}\n\n/**\n * The lookup-label HALF of `presentForJoin` (#626 retirement, spec §5;\n * matrix-tier coverage added #650 Task 7) — resolves `<field>Label` for\n * every declared lookup field with a `present` dressing dimension, sync,\n * from `getSnapshotRows` (the vault-built `LookupViaConfig.snapshotFor`\n * closure — now descriptor-routed, see `registry.ts`'s\n * `buildLookupSnapshotRows`; static tier reads its own in-config `table`\n * directly, no vault call — never `undefined` for a declared static table).\n * Mirrors `binding.ts`'s `runLookupPresent` (the async `present()` hook)\n * minus the array/`[].`-wildcard handling that hook needs for full-record\n * reads — join dressing only ever sees the joined RIGHT-side record's\n * scalar fields, so that complexity doesn't apply here.\n */\nfunction presentLookupForJoin(\n record: Record<string, unknown>,\n locale: string,\n lookupFields: Record<string, LookupDescriptor>,\n getSnapshotRows: (descriptor: LookupDescriptor) => ReadonlyMap<string, Record<string, unknown>> | undefined,\n): Record<string, unknown> {\n let result = record\n for (const [field, desc] of Object.entries(lookupFields)) {\n if (desc.present === undefined) continue\n const raw = record[field]\n if (typeof raw !== 'string') continue\n const rows = desc.backing === 'static'\n ? (desc.table ? new Map(Object.entries(desc.table)) : undefined)\n : getSnapshotRows(desc)\n if (!rows) continue\n const label = buildLookupSnapshot(desc.dimension, rows, desc).label(raw, locale)\n if (label === undefined) continue\n if (result === record) result = { ...record }\n result[`${field}Label`] = label\n }\n return result\n}\n\n/**\n * Build the combined sync `presentForJoin(record, locale)` hook a\n * `Collection` attaches to the `JoinableSource` it exposes\n * (`querySourceForJoin()`) — the i18n-text half (`presentI18nForJoin`, the\n * exact `applyI18nLocale(..., 'join')` partial application\n * `kernel/query/join.ts` used to call directly, #626) composed with the\n * lookup-label half above. `undefined` when the collection declares\n * neither — `JoinableSource.presentForJoin` then stays unset, matching\n * today's `i18nFields`-absent behavior exactly (#626 parity lock).\n */\nexport function buildPresentForJoin(\n i18nFields: Record<string, I18nTextDescriptor> | undefined,\n lookupFields: Record<string, LookupDescriptor> | undefined,\n getSnapshotRows: ((descriptor: LookupDescriptor) => ReadonlyMap<string, Record<string, unknown>> | undefined) | undefined,\n): ((record: unknown, locale: string) => unknown) | undefined {\n const hasI18n = i18nFields !== undefined && Object.keys(i18nFields).length > 0\n const hasLookup = lookupFields !== undefined && Object.keys(lookupFields).length > 0\n if (!hasI18n && !hasLookup) return undefined\n const resolveRows = getSnapshotRows ?? (() => undefined)\n return (record, locale) => {\n if (record === null || typeof record !== 'object') return record\n let result = record as Record<string, unknown>\n if (hasI18n) result = presentI18nForJoin(result, i18nFields, locale)\n if (hasLookup) result = presentLookupForJoin(result, locale, lookupFields, resolveRows)\n return result\n }\n}\n","/**\n * Lookup strategy seam (#650 Task 1 — via-lookup extraction, phase D of the\n * Via port; precedent: `port/with/i18n-strategy.ts`). Lives on the `/with`\n * port (the one seam the kernel spine may import statically) so `Vault` can\n * reach the dict-registry pure helpers and the `LookupHandle`/`NO_LOOKUP`\n * types without a spine→`via/` static import (Check 14 via-layering bans\n * that; `port/with/` is always allowed, Check 9's sanctioned exception).\n *\n * `kernel/vault.ts` imports ONLY this module for lookup — never\n * `via/lookup/*` directly.\n *\n * This task (#650 Task 1) is a pure move: `Vault.dictionary()` still\n * constructs its handle through `i18nStrategy.buildDictionaryHandle`\n * (`port/with/i18n-strategy.ts`), which now internally delegates to\n * `withLookup().buildLookupHandle` (same handle, new home). `LookupStrategy`\n * / `NO_LOOKUP` / `isLookupCollectionName` here are the seam later phase-D\n * tasks bind `vault.collection()`'s lookup fields onto — unused by Task 1's\n * wiring, but their exact shapes are frozen now so later tasks don't\n * re-litigate them.\n */\n\nimport type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js'\nimport type { LedgerStore } from '../../with-commit/history/ledger/store.js'\nimport type { UnlockedKeyring } from '../../with-party/team/keyring.js'\nimport type { NoydbEventEmitter } from '../../kernel/events.js'\nimport type { ViaCryptoCtx } from '../../kernel/via/index.js'\nimport type { LookupHandle, DictionaryOptions } from '../../via/lookup/handle.js'\nimport {\n enforceStaticDictOnPut,\n resolveDictSource,\n updateReferencingRecords,\n resolveLabelFromMap,\n collectLookupDictCompat,\n lookupToStaticDictCompat,\n reservedDictDepsOf,\n materializeBackingTable,\n checkLookupMembership,\n buildLookupAltIndex,\n registerLookupRefEdges,\n buildLookupSnapshotRows,\n coerceLookupKey,\n resolveBackingRowKey,\n matchesReferencingValue,\n type DictReferencingCollection,\n type LookupDictCompat,\n type MaterializedBacking,\n} from '../../via/lookup/registry.js'\nimport { buildPresentForJoin } from '../../via/lookup/snapshot.js'\nimport type { LookupDescriptor } from '../../via/lookup/descriptor.js'\n\n/**\n * Backing options for `LookupStrategy.buildLookupHandle` — same shape as\n * `DictionaryOptions` (kept as a distinct alias since the \"lookup\" name is\n * the forward-looking one; `DictionaryOptions` stays the dict-tier name).\n */\nexport type LookupBackingOptions = DictionaryOptions\n\n/**\n * Options accepted by `LookupStrategy.buildLookupHandle`. Mirrors the\n * `LookupHandle` constructor verbatim, plus the two choke-point\n * participation hooks (`onDirty`/`onRecordMutated`) #647 (Task 4) wires —\n * both `undefined` in this task (pure move, no new call sites).\n */\nexport interface BuildLookupHandleOptions<Keys extends string = string> {\n readonly adapter: NoydbStore\n readonly compartmentName: string\n readonly dimensionName: string\n readonly keyring: UnlockedKeyring\n /**\n * The `reservedEnvelopes('_dict_')` capability (#629 Task 4) — the\n * handle's sanctioned crypto door onto its `_dict_<name>` collection.\n * Bound by the Vault to its own `getDEK`, the same per-collection-name\n * DEK resolver every other collection uses.\n */\n readonly reservedEnvelopes: ReturnType<ViaCryptoCtx['reservedEnvelopes']>\n readonly encrypted: boolean\n readonly ledger: LedgerStore | undefined\n readonly options: LookupBackingOptions\n readonly findAndUpdateReferences:\n | ((dimension: string, oldKey: string, newKey: string) => Promise<void>)\n | undefined\n readonly emitter: NoydbEventEmitter\n /**\n * #647 fix wave 1 — mints a version-ordered delete-marker envelope. Bound by the Vault to the\n * real `kernel/enclave` `buildDeleteMarker` function — `LookupHandle` (`via/lookup/**`)\n * may not import `kernel/enclave/` itself (Check 11/15), so this capability is injected the\n * same way `reservedEnvelopes` above is.\n */\n readonly buildDeleteMarker: (identity: { collection: string; id: string }, version: number, actor: string) => EncryptedEnvelope\n /** #650 Task 4 (#647) — choke-point participation hooks. */\n readonly onDirty?: ((collection: string, id: string, action: 'put' | 'delete', version: number) => Promise<void>) | undefined\n readonly onRecordMutated?: ((collection: string, id: string, action: 'put' | 'delete', version: number) => Promise<void>) | undefined\n /**\n * #650 Task 5 (#648) — the real reference check `LookupHandle.delete()`'s strict branch calls:\n * restrict throws `DictKeyInUseError` naming the referencing collection, cascade/nullify apply\n * their propagation. Bound by the Vault (never a `Collection`/keyring/DEK reach-around); a\n * no-op when the dimension has no declared lookup-referencing edges (today's dangling behavior\n * for undeclared refs is unaffected). Return value is discarded by the handle — callers who\n * need cascade/nullify counts (forget) go through `VaultLinks` directly.\n */\n readonly checkReferencesOnDelete?: ((key: string) => Promise<unknown>) | undefined\n /**\n * Used by the active strategy to satisfy the generic-key parameter on the\n * returned handle. The NO_LOOKUP stub never reads it. Mirrors\n * `BuildDictionaryHandleOptions._keyMarker` (`port/with/i18n-strategy.ts`).\n */\n // marker generic — runtime sees no value\n _keyMarker?: Keys\n}\n\nexport interface LookupStrategy {\n /**\n * Construct a typed `LookupHandle` for the named dimension. Throws under\n * `NO_LOOKUP`.\n */\n buildLookupHandle<Keys extends string = string>(\n opts: BuildLookupHandleOptions<Keys>,\n ): LookupHandle<Keys>\n}\n\nfunction notEnabled(op: string): Error {\n return new Error(\n `${op}: the NO_LOOKUP stub was reached, which should be unreachable today — there is no ` +\n '`lookupStrategy` `createNoydb({ ... })` option yet to select this stub over the real one; ' +\n '`vault.dictionary()` always resolves through `withLookup()` (see `via/i18n/active.ts`\\'s ' +\n 'delegation). This is forward scaffolding for a later task (mirrors `NO_I18N`\\'s shape) — if you ' +\n 'hit this, it indicates a bug, not a missing opt-in.',\n )\n}\n\n/**\n * No-lookup stub. Mirrors `NO_I18N.buildDictionaryHandle`'s shape, but unlike `NO_I18N` (wired as\n * `vault.ts`'s `opts.i18nStrategy ?? NO_I18N` default), nothing selects this stub today — there is\n * no `lookupStrategy` option on `createNoydb()`; `vault.dictionary()`'s only construction path\n * (`Vault.i18nStrategy.buildDictionaryHandle` → `withLookup().buildLookupHandle`) never reaches\n * here. Kept as forward scaffolding for a later task that wires an independent lookup opt-in.\n */\nexport const NO_LOOKUP: LookupStrategy = {\n buildLookupHandle() {\n throw notEnabled('vault.dictionary()')\n },\n}\n\n/** `_dict_*` (legacy dict tier) and `_lookup_*` (the phase-D reserved backing). */\nexport const LOOKUP_COLLECTION_PREFIXES = ['_dict_', '_lookup_'] as const\n\n/** Return true when a collection name is a reserved lookup-backing collection. */\nexport function isLookupCollectionName(name: string): boolean {\n return LOOKUP_COLLECTION_PREFIXES.some((prefix) => name.startsWith(prefix))\n}\n\n// Re-exported pure registry helpers (#650 Task 1) — `kernel/vault.ts`'s\n// thin delegators call these directly; small always-on functions, not\n// behind the tree-shake seam (same bundling class as `isLookupCollectionName`\n// above, just too large to duplicate inline like that one is).\nexport { enforceStaticDictOnPut, resolveDictSource, updateReferencingRecords }\nexport type { DictReferencingCollection }\n\n// #650 Task 4 (#647) — the reserved-collection naming helper `vault.ts`'s sync-registry\n// bookkeeping needs (mapping a declared dimension name to its `_dict_<name>` collection name).\nexport { dictCollectionName } from '../../via/lookup/handle.js'\n\n// #650 Task 2 — the alias-equivalence bridge (`resolveLabelFromMap` +\n// `collectLookupDictCompat`/`lookupToStaticDictCompat`) + the runtime\n// brand/shape predicates `via/compose.ts` needs to route `'lookup'`-branded\n// descriptors, mirroring `isI18nTextDescriptor`/`isDictKeyDescriptor` below.\nexport { resolveLabelFromMap, collectLookupDictCompat, lookupToStaticDictCompat }\nexport type { LookupDictCompat }\n\n// #653 — partial-sync reserved-dict expansion: maps a set of named collections to the\n// one-hop `_dict_*` deps their lookup fields reference, off `dictKeyFieldRegistry`.\nexport { reservedDictDepsOf }\n\n// #650 Task 3 — altKeys ingest normalization + open/closed vocabulary\n// governance: the declare/warm-time altIndex builder + the membership test\n// vault.ts's `membership`/`getAltIndex` closures delegate to.\nexport { materializeBackingTable, checkLookupMembership, buildLookupAltIndex }\nexport type { MaterializedBacking }\n\n// #650 Task 5 — registers a collection's lookup-fields' cross-collection 'ref' graph edges.\nexport { registerLookupRefEdges }\n\n// #650 Task 6 — the sync snapshot+locale seam (#626 retirement, spec §5):\n// `snapshotFor`'s vault-built row source + the combined presentForJoin\n// builder `kernel/collection-config.ts` calls to build the\n// `JoinableSource.presentForJoin` hook `kernel/query/join.ts` consumes.\nexport { buildLookupSnapshotRows, buildPresentForJoin }\nexport type { LookupSnapshot } from '../../via/lookup/snapshot.js'\n\n// #651 Task 3 — the ONE descriptor-keyed key-resolution core (guarded coercion +\n// backing-row-key resolve + referencing-value match) — every consumer (vault.ts,\n// with-shape/links/vault-facade.ts, kernel/via/dispatch.ts) routes through here,\n// never a bare `String()`, ending the dm12 dialect drift.\nexport { coerceLookupKey, resolveBackingRowKey, matchesReferencingValue }\n\n/** Runtime predicate for detecting a `LookupDescriptor` (any of the three tiers). */\nexport function isLookupDescriptor(x: unknown): x is LookupDescriptor {\n return (\n typeof x === 'object' &&\n x !== null &&\n (x as { _viaBrand?: unknown })._viaBrand === 'lookup'\n )\n}\n\n/** Runtime predicate for the bare enum tier (`backing:'static'`, no in-code `table` — no label source). */\nexport function isEnumDescriptor(x: unknown): x is LookupDescriptor {\n return isLookupDescriptor(x) && x.backing === 'static' && x.table === undefined\n}\n\n/**\n * Type-only re-exports — the kernel spine imports these descriptor/handle\n * types through the port instead of reaching into `via/lookup/*` or\n * `via/i18n/*` directly. `isolatedModules: true` erases these at\n * build time — no runtime coupling.\n */\nexport type { LookupHandle, DictEntry, DictionaryOptions } from '../../via/lookup/handle.js'\nexport type { LookupDescriptor, Vocabulary, LookupBacking, OnDelete } from '../../via/lookup/descriptor.js'\nexport type { LookupViaConfig } from '../../via/lookup/binding.js'\nexport type { DictKeyDescriptor, StaticDictDescriptor } from '../../via/i18n/dictionary.js'\n","// kernel/via/dispatch.ts — the batched, origin-aware sync/cutover/restore dispatch wave\n// (Via port phase C, #638 Task 4, fixes #621).\n//\n// `Collection._onRecordMutated`'s `sync-apply`/`cutover`/`restore` cases feed touched\n// (collection, id) pairs into a per-session `GraphBatch` (owned by `Vault._collectGraphTouch`)\n// instead of dispatching inline — the `local-write` path keeps its own byte-identical inline\n// dispatch (`wave` stays `undefined` there, per the spec's behavior lock). At batch-flush time\n// `runGraphDispatchWave` decrypts each touched record (id threaded into the decrypt, matching\n// the phase-B at-rest contract) and re-runs the SAME `dispatchDerivations`/\n// `dispatchMaterializedViews` the local-write path uses, sharing one `WaveContext` so N touched\n// records feeding the SAME rollup/MV target recompute exactly once (per-target dedup).\n// See design-history/2026-07-11-via-phase-c-design.md §3.\n\nimport type { ViaGraph } from './graph.js'\nimport type { Collection } from '../collection.js'\nimport type { EncryptedEnvelope } from '../types.js'\nimport { PeriodClosedError } from '../errors.js'\nimport { matchesReferencingValue } from '../../port/with/lookup-strategy.js'\n\n/** One deleted child's resolved rollup PARENT intent (#640) — ids + a field name only. A\n * resolved `parentId` is an id, same class as any touched record id — never a stored value. */\nexport interface RollupDeleteIntent {\n readonly into: string\n readonly parentId: string\n readonly field: string\n}\n\n/** One collection's batched touches this session (#640 widens the #638 `Set<string>` shape):\n * `puts` — the original semantics, unchanged; `deletes` — a deleted record's id mapped to its\n * resolved rollup-parent intents, captured PRE-invalidation by `Collection._onRecordMutated`'s\n * sync-apply delete case (the FK is only readable there — see `kernel/collection.ts\n * #_rollupDeleteIntents`). */\nexport interface GraphTouch {\n readonly puts: Set<string>\n readonly deletes: Map<string, readonly RollupDeleteIntent[]>\n}\n\n/** Per-session touched set — collection → its `GraphTouch`. Metadata only — ids (collection\n * names, record ids INCLUDING resolved rollup parent ids) and field names; NEVER record payload\n * or key material. A resolved parentId is an id, same class as the touched ids — not a stored\n * value. */\nexport type GraphBatch = Map<string, GraphTouch>\n\n/** Get-or-create `batch`'s `GraphTouch` entry for `collection` (#640) — shared by\n * `Vault._collectGraphTouch`/`_collectGraphDelete` so each stays a one-line call. */\nexport function touchFor(batch: GraphBatch, collection: string): GraphTouch {\n let t = batch.get(collection)\n if (!t) {\n t = { puts: new Set(), deletes: new Map() }\n batch.set(collection, t)\n }\n return t\n}\n\n/** #640 — sync, I/O-free: `deleted`'s resolved rollup PARENT intents (the FK is only readable\n * NOW, before the record is gone) — a pure function so `Collection._rollupDeleteIntents` stays\n * a one-line delegator under the kernel-surface ceiling. `registry` is `this.derivationSource\n * ?.registry()`; `collectionName` is `this.name` (the CHILD/`rollup.from` side). Generic over\n * the registry's own spec shape so this file never imports a `with-formula` type (port-layering\n * — via/dispatch.ts must not gain a with-* import). */\nexport function resolveRollupDeleteIntents<S extends { source: string; rollup?: { from: string; key: string; field: string } }>(\n registry: { strategiesForSource(name: string): ReadonlyArray<{ spec: S }> } | undefined,\n collectionName: string,\n deleted: Record<string, unknown>,\n): RollupDeleteIntent[] {\n if (!registry) return []\n const intents: RollupDeleteIntent[] = []\n for (const { spec } of registry.strategiesForSource(collectionName)) {\n if (!spec.rollup || spec.rollup.from !== collectionName) continue\n const kv = deleted[spec.rollup.key]\n if (typeof kv === 'string' || typeof kv === 'number') intents.push({ into: spec.source, parentId: String(kv), field: spec.rollup.field })\n }\n return intents\n}\n\n/** #640 — resolve a `RollupDeleteIntent` back to its registry `spec`. The wave's per-intent\n * driver needs `spec.rollup.compute`, which `GraphBatch`'s metadata-only pin forbids batching —\n * so it's re-resolved here, post-boundary, instead of carried across it. `undefined` if the\n * intent's originating strategy was unregistered between collect time and wave time (residual\n * gap, freshness-only). */\nexport function findRollupSpecForIntent<S extends { source: string; rollup?: { from: string; field: string } }>(\n registry: { strategiesForSource(name: string): ReadonlyArray<{ spec: S }> } | undefined,\n collectionName: string,\n intent: RollupDeleteIntent,\n): S | undefined {\n return registry?.strategiesForSource(collectionName).find((s) => s.spec.source === intent.into && s.spec.rollup?.field === intent.field && s.spec.rollup?.from === collectionName)?.spec\n}\n\n/** One dedup ledger for a single wave — a target is recomputed at most once (mark-on-check). */\nexport class WaveContext {\n private readonly _seen = new Set<string>()\n seen(targetKey: string): boolean {\n if (this._seen.has(targetKey)) return true\n this._seen.add(targetKey)\n return false\n }\n}\n\n/** The slice of `Vault` the wave needs: the shared graph (the #553 zero-cost skip) and cached-\n * collection lookup — never constructs, since a touched collection is, by construction,\n * already open (it just fired `_onRecordMutated`). */\nexport interface VaultLike {\n readonly graph: ViaGraph\n _getCollection(name: string): Collection<Record<string, unknown>> | undefined\n /** #640 (#644 item 3) — structured wave-error surfacing, additive to the existing console.warn. */\n _emit(event: string, payload: unknown): void\n}\n\n/**\n * Run ONE dispatch wave for a completed batch: for each touched (collection, id), decrypt the\n * applied envelope (id threaded), then run the SAME `dispatchDerivations` +\n * `dispatchMaterializedViews` the local-write path uses — with a shared `WaveContext` so N\n * touched records feeding the SAME target recompute once. #553: a collection with no graph\n * out-edges (e.g. money-only) is skipped before any decrypt/dispatch async work.\n */\nexport async function runGraphDispatchWave(vault: VaultLike, batch: GraphBatch): Promise<void> {\n const wave = new WaveContext()\n for (const [collectionName, touch] of batch) {\n if (vault.graph.dependentsOf(collectionName).length === 0) continue\n const coll = vault._getCollection(collectionName)\n if (!coll) continue\n for (const id of touch.puts) {\n try {\n // Decrypt is INSIDE the per-id isolation boundary (whole-branch review Important\n // finding, #638): an undecryptable synced envelope (`TamperedError`) must not\n // escape `_getStoredRecordForDispatch` and abort the wave — that would propagate\n // through `_flushGraphBatch` and reject the surrounding `SyncEngine.pull`/`push`\n // AFTER records were already applied + meta persisted, starving every other\n // touched target in the same batch.\n const stored = await coll._getStoredRecordForDispatch(id)\n if (!stored) continue\n await coll.dispatchDerivations(id, stored.record, stored.version, wave)\n await coll.dispatchMaterializedViews(id, stored.record, wave)\n } catch (err) {\n // #638 Task 5 review mandate: one touched record's recompute must not abort the\n // whole wave (starving co-batched healthy targets) or the pull/push it's nested\n // inside. `PeriodClosedError` never reaches here — `putDerivedOutput` already\n // intercepts it at every output-write call site and turns it into a skip+event.\n // Anything else (a genuine decrypt failure, a derive()/executor bug, a schema\n // violation on the output, ...) is surfaced — not silently swallowed — via the\n // SAME console.warn channel `dispatchDerivations`/the MV executor already use for\n // their own non-strict-mode output failures, then isolated to just this one id.\n // #644 item 3: ADDITIVELY (never in place of the warn) emit a structured event too,\n // so a listener doesn't have to scrape console output to react to a wave failure.\n console.warn(`[via-dispatch] wave recompute failed for ${collectionName}/${id}:`, err)\n vault._emit('derivation:wave-error', { collection: collectionName, id, error: err })\n }\n }\n // #640 — delete-kind touches: the deleted child's rollup-parent intents, resolved (sync,\n // pre-invalidation) at collect time by `Collection._rollupDeleteIntents`. Same per-id\n // isolation as the puts loop above. #658: the wave now ALSO heals MV rows and array-shape\n // derivation output rows for the deleted child — parity with the local-delete boundary\n // (`Collection._doDelete`'s `!internal` block, which already calls all three). Still never\n // routed through `dispatchDerivations` (the mutation-choke-point.test.ts:85-99 pin — sync-\n // applied deletes never RE-DERIVE); `dispatchMaterializedViewsOnDelete`/\n // `dispatchArrayDerivationsOnDelete` only need `id` (MV refresh recomputes+diffs; array-\n // derivation reads its per-source sidecar) and never call `derive()`, so the pin holds.\n for (const [id, intents] of touch.deletes) {\n try {\n await coll._recomputeDeletedRollups(intents, wave)\n // #658: record-shape same-id outputs are left untouched (eraseRecordShapeToo defaults\n // false), matching local delete — the user deletes those directly if wanted.\n // #658: TODO dedup MV refresh per wave — `dispatchMaterializedViewsOnDelete` doesn't\n // accept a `WaveContext` (unlike the put-path `dispatchMaterializedViews`), so N deleted\n // children of one eager MV in a batch each trigger a full refresh pass. Threading `wave`\n // through would touch collection.ts's zero-slack kernel-surface ceiling for a perf-only\n // win; correctness doesn't depend on it (idempotent per source-id) — left as a follow-up.\n await coll.dispatchMaterializedViewsOnDelete(id)\n await coll.dispatchArrayDerivationsOnDelete(id)\n } catch (err) {\n console.warn(`[via-dispatch] wave delete-recompute failed for ${collectionName}/${id}:`, err)\n vault._emit('derivation:wave-error', { collection: collectionName, id, error: err })\n }\n }\n }\n}\n\n/** A record's post-freeze source mutation, for the `'derivation:skipped-frozen'` event\n * and the optional audit-trail entry. See {@link putDerivedOutput}. */\nexport interface DerivationSkippedFrozen {\n readonly source: { readonly collection: string; readonly id: string }\n readonly target: { readonly collection: string; readonly id: string }\n readonly period: string\n readonly endDate: string\n}\n\n/** The minimal put-capable shape `putDerivedOutput` needs. Any `Collection<T>` structurally\n * satisfies this — its real `options` type is a superset of what's declared here. */\nexport interface CollectionLike {\n put(id: string, value: unknown, options?: { readonly source?: string }): Promise<void>\n}\n\nexport interface PutDerivedOutputCtx {\n readonly emit: (ev: string, p: unknown) => void\n readonly source: { readonly collection: string; readonly id: string }\n readonly audit?: ((e: DerivationSkippedFrozen) => Promise<void>) | undefined\n}\n\n/**\n * Attempt a dispatch-driven output write. On `PeriodClosedError` (the closed-period\n * `beforePut` gate — `freezePeriod`/`archivePeriod` add no separate gate, per seam map\n * Part 7): SKIP (no `_ts` stamped — the gate throws before any write happens), emit\n * `'derivation:skipped-frozen'` on the event bus (ALWAYS), and append an audit-trail entry\n * when the with-history ledger is active. Returns `'written' | 'skipped-frozen'`. Any OTHER\n * error propagates unchanged — this helper narrows exactly one error class. The SOURCE\n * write is never wrapped through this helper — only derived-output writes are (§7).\n */\nexport async function putDerivedOutput(\n outColl: CollectionLike, id: string, value: unknown,\n ctx: PutDerivedOutputCtx,\n options?: { readonly source?: string },\n): Promise<'written' | 'skipped-frozen'> {\n try {\n await outColl.put(id, value, options)\n return 'written'\n } catch (err) {\n if (!(err instanceof PeriodClosedError)) throw err\n // Reach-around for the target collection's private `name` — the SAME pattern\n // `with-formula/materialized-views/executor.ts`'s `listOutputIds` already uses to\n // read a `Collection`'s private `adapter`/`vault`/`name` fields from outside the class.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const targetCollection = (outColl as any).name as string\n const event: DerivationSkippedFrozen = {\n source: ctx.source,\n target: { collection: targetCollection, id },\n period: err.periodName,\n endDate: err.endDate,\n }\n ctx.emit('derivation:skipped-frozen', event)\n if (ctx.audit) await ctx.audit(event)\n return 'skipped-frozen'\n }\n}\n\n/** Structural (no static import — kernel spine may not statically reach a with-* service,\n * the S4 gate recipe `check-architecture.mjs`'s port-layering check enforces) shape of the\n * with-history `LedgerStore.append` seam this helper needs. */\ninterface AuditLedgerLike {\n append(input: {\n readonly op: 'lifecycle'\n readonly collection: string\n readonly id: string\n readonly version: number\n readonly actor: string\n readonly payloadHash: string\n readonly reason?: string\n }): Promise<unknown>\n}\n\n/** @internal — the optional with-history ledger audit hook for `putDerivedOutput`, present\n * only when the ledger is active (mirrors every other kernel event's `if (this.ledger)`\n * gate). Encoded as a `'lifecycle'` entry — the existing \"non-data audit event\" op (the\n * same convention `forget`'s JSON-summary-in-`reason` entry uses; `ledger/entry.ts:88-104`). */\nexport function ledgerAuditHook(\n ledger: AuditLedgerLike | undefined, actor: string,\n): ((e: DerivationSkippedFrozen) => Promise<void>) | undefined {\n if (!ledger) return undefined\n return async (e) => {\n await ledger.append({\n op: 'lifecycle', collection: e.target.collection, id: e.target.id, version: 0, actor, payloadHash: '',\n reason: JSON.stringify({ event: 'derivation-skipped-frozen', ...e }),\n })\n }\n}\n\n/** `recomputeRollup`/`dispatchRollupsOnDelete`'s per-target write outcome (#638 Task 6):\n * `'written'`/`'skipped-frozen'` mirror {@link putDerivedOutput}'s result; `'noop'` covers\n * no-parent/no-change/deduped-by-wave — nothing to report either way. */\nexport type RollupOutcome = 'written' | 'skipped-frozen' | 'noop'\n\n/** Mutable accumulator `forgetDerivedFanout` writes into, one per `Vault.forget()` call — keeps\n * the per-ref loop's call site to a single line under vault.ts's tight kernel-surface ceiling.\n * Maps 1:1 onto `ForgetResult`'s additive fields (`with-audit/forget/strategy.ts`). */\nexport interface ForgetFanoutStats {\n recordsErased: number\n aggregatesRecomputed: number\n readonly residueFrozen: string[]\n /** #650 Task 5 (#648) — referencing records tombstoned via a `'ref'` edge's `cascade` policy. */\n lookupReferencesCascaded: number\n /** #650 Task 5 (#648) — referencing fields cleared via a `'ref'` edge's `nullify` policy. */\n lookupReferencesNullified: number\n /** #650 Task 5 review (Important fix) — `'ref'` edges whose compare-key could NOT be resolved,\n * even from the LIVE pre-shred row (the backing row itself is unreadable) — propagation was\n * skipped for these, reported here so the skip is never silent. `backing:key:collection.field`\n * entries, one per un-propagated edge. */\n readonly lookupReferencesResidue: string[]\n /** #776/#782/#785 — `outputCollection:id` MV-output rows that survived erasure invalidation\n * (eager tombstone leg AND lazy/manual `invalidateMVAtRest`) despite belonging to the\n * forgotten subject, because the ownership stamp could not be decoded (undecodable under\n * the default DEK — e.g. elevated above tier 0 on a tiered output collection). Ownership\n * UNCONFIRMED. Never erased, but surfaced here rather than silently skipped. */\n readonly derivedResidueUndecodable: string[]\n /** #782/#785 — `outputCollection:id` MV-output rows that decoded and stamp-matched but whose\n * `_internalDelete` declined (the #718 tier-elevation gate). Ownership CONFIRMED, erasure\n * declined — a real silent survival, surfaced here rather than silently skipped. */\n readonly derivedResidueDeclined: string[]\n}\n\n/**\n * #622 — after `_writeTombstone(ref.id, actor)` erases the forgotten subject's own record, fan\n * out to its derived residue via the graph (spec §5): record-grain artifacts (MV rows,\n * array-shape derivation rows, same-id record-shape derivation copies) are ERASED through the\n * SAME `!internal` housekeeping-bypass machinery the ordinary delete path uses (no user\n * `onDelete` re-fires — the shred-is-not-a-domain-delete property `_writeTombstone` protects);\n * aggregate-grain rollups are RECOMPUTED without the forgotten contribution in open periods, or\n * skip+audit (via `putDerivedOutput`, already wired into the rollup/MV output paths) in frozen\n * ones. Mutates `stats` in place. `envelope` is `ref`'s PRE-tombstone envelope, decoded only if\n * a rollup edge is actually present — the #553 zero-cost-skip discipline: no decrypt for the\n * common case of a forgotten record with no aggregate-grain consumer, and no work at all when\n * `ref.collection` has no graph out-edges. `lookupCompareKeys` is the `'ref'` edges' compare-key\n * map, resolved from the LIVE row BEFORE any shred (`VaultLinks.checkLookupRefsRestrict`'s return\n * value — `Vault.forget()`'s pre-shred restrict check doubles as the live-resolve pass) — see\n * {@link applyLookupRefsFanout}.\n */\nexport async function forgetDerivedFanout(\n vault: VaultLike,\n ref: { readonly collection: string; readonly id: string },\n envelope: EncryptedEnvelope | null,\n stats: ForgetFanoutStats,\n lookupCompareKeys: ReadonlyMap<string, string | undefined>,\n): Promise<void> {\n const coll = vault._getCollection(ref.collection)\n\n // #761 item 4 — drive the MV arm off `dispatchMaterializedViewsOnDelete` UNCONDITIONALLY,\n // ABOVE the `edges` check below: `registry.edges()` drops the same-collection\n // partition-disjoint MV edge (registry.ts's `sources.length === 0 → continue`), so a\n // same-collection MV's source collection never appears in `vault.graph`'s derived-artifact\n // edges even though the MV IS registered — forget() would otherwise never reach it.\n // `dispatchMaterializedViewsOnDelete` self-guards O(1) via `mvsForSource` (a no-op when\n // this collection isn't an MV source), so this is safe to call unconditionally. Safe to\n // route through the eager executor's tombstone leg ONLY because that leg is now\n // stamp-scoped (#762) — before that fix this would have opened a NEW forget-time\n // data-loss path into the unscoped tombstone diff.\n if (coll) {\n const mv = await coll.dispatchMaterializedViewsOnDelete(ref.id)\n stats.recordsErased += mv.deleted\n stats.derivedResidueUndecodable.push(...mv.residueUndecodable)\n stats.derivedResidueDeclined.push(...mv.residueDeclined)\n }\n\n const edges = vault.graph.derivedArtifactsOf(ref.collection)\n if (edges.length === 0 || !coll) return\n\n // #650 Task 5 (#648) — 'ref' cascade/nullify propagate ADDITIVELY, here, AFTER the shred\n // (restrict already refused BEFORE any shred — the caller's pre-tombstone check, spec §4).\n // The I/O shell (loop shape, collection accessor) is duplicated, not imported, from\n // `VaultLinks.applyLookupRefsPropagation`/`checkLookupRefsRestrict` (with-shape/links/\n // vault-facade.ts) — the kernel spine may not statically import a with-* service\n // (port-layering, the #638 Task 5 via/dispatch.ts precedent); `vault._getCollection` is\n // cached-only while `VaultLinks`' accessor constructs. The pure match predicate itself is\n // shared through the port seam (#651 Task 3 — `matchesReferencingValue`, `port/with/\n // lookup-strategy.ts`), so only the shell, not the coercion logic, stays duplicated. A\n // referencing edge whose dimension uses a non-default `key` (matrix tier only) needs the\n // backing row's OWN value at that field, not its PUT-id — the row is ALREADY tombstoned by\n // now, so it's read from `lookupCompareKeys`, resolved by the caller from the LIVE row\n // BEFORE the shred (#650 Task 5 review, Important fix — eliminates the post-shred\n // envelope-decode dependency this used to have, which silently skipped propagation whenever\n // that decode failed).\n if (edges.some((e) => e.kind === 'ref')) {\n const { cascaded, nullified, residue } = await applyLookupRefsFanout(vault, ref.collection, ref.id, lookupCompareKeys)\n stats.lookupReferencesCascaded += cascaded\n stats.lookupReferencesNullified += nullified\n stats.lookupReferencesResidue.push(...residue)\n }\n\n if (edges.some((e) => e.kind === 'derivation')) {\n // #622 review Finding 1: count REAL erasures (dispatchArrayDerivationsOnDelete's own\n // `_internalDelete`-backed tally), not the derivation EDGE count — an edge exists whenever\n // this collection is ANY trigger (source/sources[]/triggerBy), but the same-id record-shape\n // guard only erases for `spec.source === this.name`, and `derive()` may never have produced\n // an output row (optional-skip) in the first place. Both cases must contribute 0, not +1.\n stats.recordsErased += await coll.dispatchArrayDerivationsOnDelete(ref.id, true)\n }\n\n if (envelope && edges.some((e) => e.kind === 'rollup')) {\n const priorRecord = await coll._decodeEnvelope(envelope, ref.id)\n if (priorRecord) {\n for (const r of await coll.dispatchRollupsOnDelete(ref.id, priorRecord)) {\n if (r.outcome === 'written') stats.aggregatesRecomputed += 1\n else if (r.outcome === 'skipped-frozen') stats.residueFrozen.push(`${r.into}:${r.parentId}`)\n }\n }\n }\n}\n\n/**\n * Apply `cascade`/`nullify` propagation for `backing`'s non-restrict `'ref'` edges — the\n * forget-path counterpart of `VaultLinks.applyLookupRefsPropagation` (I/O shell duplicated, not\n * imported, match predicate shared via the port — see {@link forgetDerivedFanout}'s call site\n * comment). `restrict` edges are skipped here: the\n * forget loop's `checkLookupRefsRestrict`-equivalent call already refused (or the reference no\n * longer existed) BEFORE `_writeTombstone` ran, so by the time this runs only cascade/nullify\n * remain to propagate. `compareKeys` is the non-`'id'`-`keyField` compare-value map, resolved by\n * the caller from the LIVE row BEFORE the shred (#650 Task 5 review, Important fix) — the live row\n * is already shredded by the time THIS function runs, so it can no longer resolve one itself. A\n * `keyField` absent from (or `undefined` in) the map means that live resolve failed too — the edge\n * is reported as residue instead of silently skipped (never a bare `continue` with no trace).\n */\nasync function applyLookupRefsFanout(\n vault: VaultLike,\n backing: string,\n key: string,\n compareKeys: ReadonlyMap<string, string | undefined>,\n): Promise<{ cascaded: number; nullified: number; residue: string[] }> {\n let cascaded = 0\n let nullified = 0\n const residue: string[] = []\n for (const { referencing, onDelete, keyField } of vault.graph.referencingEdgesOf(backing)) {\n if (onDelete === 'restrict') continue\n const compareKey = keyField === 'id' ? key : compareKeys.get(keyField)\n if (compareKey === undefined) {\n residue.push(`${backing}:${key}:${referencing.collection}.${referencing.field}`)\n continue\n }\n const coll = vault._getCollection(referencing.collection)\n if (!coll) continue\n const matches = (await coll.list()).filter((rec) => matchesReferencingValue(rec, referencing.field, compareKey))\n for (const rec of matches) {\n const id = rec['id'] as string | undefined\n if (id === undefined) continue\n if (onDelete === 'cascade') {\n await coll.delete(id)\n cascaded++\n } else if (onDelete === 'nullify') {\n await coll.put(id, { ...rec, [referencing.field]: null })\n nullified++\n }\n }\n }\n return { cascaded, nullified, residue }\n}\n\n/**\n * Value-equality for a single self-write reverse-denorm field. Scalars\n * compare by identity; objects by canonical JSON (denorm values should be\n * deterministically shaped). Used as the cycle guard — when every denorm\n * field already matches, no write is issued and the self-write recursion ends.\n */\nexport function selfWriteFieldEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') return false\n try {\n return JSON.stringify(a) === JSON.stringify(b)\n } catch {\n return false\n }\n}\n"],"mappings":"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","names":[]}
@@ -4,10 +4,10 @@ import {
4
4
  } from "./chunk-KHKKD62N.js";
5
5
  import {
6
6
  derivePersistedSchema
7
- } from "./chunk-Z45YRGFO.js";
7
+ } from "./chunk-ONVD6GBY.js";
8
8
  import {
9
9
  loadPersistedSchema
10
- } from "./chunk-4MC5JRRX.js";
10
+ } from "./chunk-6WO62AJW.js";
11
11
 
12
12
  // src/with-shape/introspection/walk.ts
13
13
  var INTERNAL_PREFIX = "_";
@@ -238,4 +238,4 @@ function summariseAggregateOp(value) {
238
238
  export {
239
239
  dumpVaultSchema
240
240
  };
241
- //# sourceMappingURL=chunk-P7OG2ETF.js.map
241
+ //# sourceMappingURL=chunk-DXKLLKME.js.map
@@ -1,38 +1,41 @@
1
1
  import {
2
2
  walkClosure
3
- } from "./chunk-WYZ5MYUA.js";
3
+ } from "./chunk-BAHOV5I5.js";
4
4
  import {
5
5
  resolveManagedSecret
6
- } from "./chunk-TAGFGKHP.js";
6
+ } from "./chunk-OTHHO3KI.js";
7
7
  import {
8
8
  parseExtractedPartitionBody,
9
9
  readPod,
10
10
  readPodHeader
11
- } from "./chunk-VOQW5LAM.js";
11
+ } from "./chunk-QSIEL6TL.js";
12
12
  import {
13
13
  createOwnerKeyring
14
- } from "./chunk-ERB6NDDW.js";
14
+ } from "./chunk-CAGI4LLJ.js";
15
15
  import {
16
16
  diff
17
17
  } from "./chunk-SVLR4POP.js";
18
18
  import {
19
19
  LedgerStore
20
- } from "./chunk-NIVEDYJZ.js";
20
+ } from "./chunk-4A34KWOU.js";
21
21
  import {
22
22
  LEDGER_COLLECTION
23
23
  } from "./chunk-I7FD46FF.js";
24
24
  import {
25
25
  openEnvelopeJson
26
- } from "./chunk-VN45YLWM.js";
26
+ } from "./chunk-OHOKBMTM.js";
27
+ import {
28
+ buildRecordEnvelope
29
+ } from "./chunk-PENPHA45.js";
27
30
  import {
28
31
  base64ToBuffer,
29
32
  wrapKey
30
- } from "./chunk-VCETL77O.js";
33
+ } from "./chunk-AU3AUJIZ.js";
31
34
  import {
32
35
  AdoptionStateError,
33
36
  TransferSealError,
34
37
  ValidationError
35
- } from "./chunk-HNGSV2YC.js";
38
+ } from "./chunk-CWM4GQD2.js";
36
39
 
37
40
  // src/with-cargo/vault-diff.ts
38
41
  async function diffVault(vault, candidate, options = {}) {
@@ -193,7 +196,7 @@ function shortJSON(value) {
193
196
  function withCargo() {
194
197
  return {
195
198
  async extractPartition(vault, opts) {
196
- const { extractPartitionCore } = await import("./extract-partition-X2L26O6A.js");
199
+ const { extractPartitionCore } = await import("./extract-partition-TVY7AMKH.js");
197
200
  return extractPartitionCore(vault, opts);
198
201
  }
199
202
  };
@@ -322,13 +325,15 @@ async function adoptPartition(bundleBytes, opts) {
322
325
  }
323
326
  const adoptedAt = (/* @__PURE__ */ new Date()).toISOString();
324
327
  const adoption = { sealId: seal.sealId, adoptedAt, needsOwner: true, transferSeal: seal };
325
- await destinationStore.put(vaultName, "_meta", "adoption", {
326
- _noydb: 1,
327
- _v: 1,
328
- _ts: adoptedAt,
329
- _iv: "",
330
- _data: JSON.stringify(adoption)
331
- });
328
+ await destinationStore.put(
329
+ vaultName,
330
+ "_meta",
331
+ "adoption",
332
+ buildRecordEnvelope(
333
+ { collection: "_meta", id: "adoption", version: 1 },
334
+ { ts: adoptedAt, iv: "", data: JSON.stringify(adoption) }
335
+ )
336
+ );
332
337
  return { vaultName, needsOwner: true, sealId: seal.sealId };
333
338
  }
334
339
  function isManaged(o) {
@@ -399,7 +404,7 @@ async function createOwnerOnAdoptedPartition(store, vaultName, opts) {
399
404
  }
400
405
  }
401
406
  if (isManaged(opts)) {
402
- const { createNoydb } = await import("./noydb-YPSEGK32.js");
407
+ const { createNoydb } = await import("./noydb-IRILUDED.js");
403
408
  const db = await createNoydb({
404
409
  store,
405
410
  user: userId,
@@ -430,7 +435,7 @@ async function decryptExtractedPartition(bundleBytes, transferKey) {
430
435
  if (dek === void 0) continue;
431
436
  const recs = [];
432
437
  for (const [id, env] of Object.entries(byId)) {
433
- const plaintext = await openEnvelopeJson(env, dek);
438
+ const plaintext = await openEnvelopeJson({ collection, id }, env, dek);
434
439
  const body = JSON.parse(plaintext);
435
440
  recs.push({
436
441
  id,
@@ -455,4 +460,4 @@ export {
455
460
  withCargo,
456
461
  describeExtraction
457
462
  };
458
- //# sourceMappingURL=chunk-TDJPS3T2.js.map
463
+ //# sourceMappingURL=chunk-E5SC6ENM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-cargo/vault-diff.ts","../src/with-cargo/active.ts","../src/with-cargo/describe-extraction.ts","../src/with-cargo/adopt-partition.ts","../src/with-cargo/decrypt-partition.ts"],"sourcesContent":["/**\n * Vault-level diff orchestrator.\n *\n * Compares a live `Vault`'s plaintext state against a candidate state\n * (another vault, a plain `{ collection: records[] }` map, or a vault\n * dump JSON) and returns a structured `VaultDiff` plan listing the\n * records that would be added, modified, or deleted to bring the live\n * vault into the candidate's shape.\n *\n * Builds on two existing record-level helpers:\n *\n * 1. `diff(a, b)` from `./history/diff.ts` — emits dot-pathed\n * `DiffEntry[]` with `type: 'added' | 'removed' | 'changed'` for\n * each changed field of two records. Used here for the\n * `fieldDiffs` of every `modified` entry, and (with empty result)\n * as the default deep-equal check.\n *\n * 2. `Vault.exportStream()` from `./vault.ts` — the canonical\n * decrypt-and-stream-records iterator. Used to walk both sides\n * when the candidate is itself a `Vault`. ACL-scoped: collections\n * the caller can't read silently drop out, the same way every\n * other plaintext-emitting export pipeline filters them.\n *\n * The new orchestration is the **vault-level** enumeration: bucket\n * each record id into added (only in candidate), deleted (only in\n * vault), or modified (in both with field changes); leave the\n * field-level granularity to the existing `diff()`.\n *\n * Use cases:\n *\n * - Import preview (`@noy-db/as-*` `fromString` returns a plan\n * whose body is a `VaultDiff`).\n * - Backup verification (\"does this `.noydb` bundle from yesterday\n * match the current vault?\").\n * - Two-vault reconciliation (\"what's different between Office A\n * and Office B before we sync?\").\n * - Test assertions (golden-file testing with one-liner\n * `expect(plan.summary).toEqual(...)`).\n *\n * @module\n */\n\nimport type { Vault } from '../kernel/vault.js'\nimport { diff as fieldDiff, type DiffEntry as FieldDiffEntry } from '../with-commit/history/diff.js'\n\n// ─── Public types ──────────────────────────────────────────────────────\n\n/** Per-record entry shape — added and deleted records carry only the record value. */\nexport interface VaultDiffEntry<T = unknown> {\n readonly collection: string\n readonly id: string\n readonly record: T\n /**\n * Unencrypted envelope metadata for the RECEIVER-side record.\n * Populated only when `diffVault` is called with `{includeMetadata: true}`.\n * Default: `undefined` (zero extra reads, no behavior change).\n *\n * Populated for `modified` (the CURRENT receiver state, before the candidate\n * is applied) and `deleted` (the receiver envelope of the record being\n * removed). `added` entries have no receiver envelope at diff time, so their\n * `metadata` is always absent.\n */\n readonly metadata?: {\n readonly version: number\n readonly timestamp: string\n readonly by?: string\n readonly source?: string\n readonly sourceTs?: string\n }\n}\n\n/** Modified records carry both halves of the diff plus the field-level breakdown. */\nexport interface VaultDiffModifiedEntry<T = unknown> extends VaultDiffEntry<T> {\n /** The record as it stands in the live vault. */\n readonly before: T\n /** Top-level keys whose values differ between `before` and `record`. */\n readonly fieldsChanged: readonly string[]\n /**\n * Field-level diff entries from `diff(before, record)`. Reuses the\n * existing per-record diff helper so consumers can render git-style\n * `path: from → to` rows without re-walking the records.\n */\n readonly fieldDiffs: readonly FieldDiffEntry[]\n}\n\nexport interface VaultDiff<T = unknown> {\n readonly added: readonly VaultDiffEntry<T>[]\n readonly modified: readonly VaultDiffModifiedEntry<T>[]\n readonly deleted: readonly VaultDiffEntry<T>[]\n /** Only populated when `options.includeUnchanged: true`. */\n readonly unchanged: readonly VaultDiffEntry<T>[] | undefined\n readonly summary: {\n readonly add: number\n readonly modify: number\n readonly delete: number\n readonly total: number\n }\n /**\n * Format the diff as a human-readable string.\n *\n * - `'count'` — one line, just the numbers (`12 added · 3 modified · 0 deleted`)\n * - `'one-line'` — count plus a single overview line\n * - `'full'` — count + one row per added/modified/deleted record (default)\n */\n format(opts?: { detail?: 'count' | 'one-line' | 'full' }): string\n}\n\nexport interface DiffOptions {\n /** Restrict the diff to a subset of collections. */\n readonly collections?: readonly string[]\n /** Field on each record that carries its id. Defaults to `'id'`. */\n readonly idKey?: string\n /** Override the default deep-equal check for \"modified vs unchanged\". */\n readonly compareFn?: (a: unknown, b: unknown) => boolean\n /** If true, include unchanged records in the diff (off by default to save memory). */\n readonly includeUnchanged?: boolean\n /**\n * When `true`, each entry in `added`, `modified`, and `deleted` will carry a\n * `metadata` field with the RECEIVER-side envelope metadata\n * (`version`, `timestamp`, `by?`, `source?`, `sourceTs?`).\n *\n * Off by default — no extra adapter reads, no behavior change for existing callers.\n */\n readonly includeMetadata?: boolean\n}\n\n/**\n * Candidate state to diff the vault against:\n *\n * - A `Vault` instance — both sides are walked via `exportStream()`.\n * - A `Record<collection, records[]>` map — same shape `as-json.toObject()`\n * produces. Useful for diffing parsed file content against the live vault.\n * - A `VaultDump` (output of `vault.dump()`) — a JSON string carrying the\n * full vault state. Parsed and reduced to the map shape above.\n */\nexport type DiffCandidate<T = unknown> =\n | Vault\n | Record<string, readonly T[]>\n | string\n\n// ─── Implementation ────────────────────────────────────────────────────\n\n/**\n * Compute the diff between a live vault and a candidate state.\n *\n * Ungated shared import/merge infrastructure: the `as-*` exporters call this\n * internally from their `fromString`/import merge logic, so it is always\n * available (not behind `withCargo()`). Only `extractPartition` is a gated\n * cargo capability.\n *\n * Returns a fully buffered `VaultDiff` — no streaming. Memory cost is\n * O(n + m) in the row count of vault + candidate. For documented\n * 1K-50K-record vaults this is fine; a streaming variant lands as a\n * follow-up if a > 100K-record consumer arrives.\n */\nexport async function diffVault<T = unknown>(\n vault: Vault,\n candidate: DiffCandidate<T>,\n options: DiffOptions = {},\n): Promise<VaultDiff<T>> {\n const idKey = options.idKey ?? 'id'\n const filter = options.collections ? new Set(options.collections) : null\n const compareFn =\n options.compareFn ?? ((a: unknown, b: unknown) => fieldDiff(a, b).length === 0)\n\n // Side A — walk the live vault via exportStream(). Each chunk arrives\n // already decrypted and ACL-scoped, so collections the caller can't\n // read silently drop out. exportStream's records are typed `unknown[]`\n // — diffVault is the type-erasure boundary; the caller asserts the\n // record shape via the function's `<T>` generic.\n const live = new Map<string, Map<string, T>>()\n for await (const chunk of vault.exportStream({ granularity: 'collection' })) {\n if (filter && !filter.has(chunk.collection)) continue\n const collection = live.get(chunk.collection) ?? new Map<string, T>()\n for (const record of chunk.records) {\n const id = readIdField(record, idKey)\n if (!id) continue\n collection.set(id, record as T)\n }\n live.set(chunk.collection, collection)\n }\n\n // Side B — normalise the candidate into the same shape.\n const cand = await normaliseCandidate<T>(candidate, idKey, filter)\n\n // Walk every (collection, id) on either side and bucket.\n const added: VaultDiffEntry<T>[] = []\n const modified: VaultDiffModifiedEntry<T>[] = []\n const deleted: VaultDiffEntry<T>[] = []\n const unchanged: VaultDiffEntry<T>[] | undefined = options.includeUnchanged ? [] : undefined\n\n const collectionNames = new Set([...live.keys(), ...cand.keys()])\n for (const collection of [...collectionNames].sort()) {\n const liveColl = live.get(collection) ?? new Map<string, T>()\n const candColl = cand.get(collection) ?? new Map<string, T>()\n const allIds = new Set([...liveColl.keys(), ...candColl.keys()])\n\n for (const id of [...allIds].sort()) {\n const before = liveColl.get(id)\n const after = candColl.get(id)\n\n if (before === undefined && after !== undefined) {\n // added: record only in candidate — no receiver envelope\n added.push({ collection, id, record: after })\n } else if (before !== undefined && after === undefined) {\n // deleted: record only in receiver — attach metadata if requested\n const metadata = options.includeMetadata\n ? (await vault.collection(collection).getMetadata(id)) ?? undefined\n : undefined\n deleted.push({ collection, id, record: before, ...(metadata !== undefined ? { metadata } : {}) })\n } else if (before !== undefined && after !== undefined) {\n if (compareFn(before, after)) {\n unchanged?.push({ collection, id, record: after })\n } else {\n // modified: record in both — attach receiver-side metadata if requested\n const metadata = options.includeMetadata\n ? (await vault.collection(collection).getMetadata(id)) ?? undefined\n : undefined\n const fieldDiffs = fieldDiff(before, after)\n const fieldsChanged = uniqueTopLevelKeys(fieldDiffs)\n modified.push({\n collection,\n id,\n record: after,\n before,\n fieldsChanged,\n fieldDiffs,\n ...(metadata !== undefined ? { metadata } : {}),\n })\n }\n }\n }\n }\n\n const summary = {\n add: added.length,\n modify: modified.length,\n delete: deleted.length,\n total: added.length + modified.length + deleted.length,\n }\n\n return {\n added,\n modified,\n deleted,\n unchanged,\n summary,\n format(opts) {\n return formatDiff(opts?.detail ?? 'full', { added, modified, deleted, summary })\n },\n }\n}\n\n// ─── Internals ─────────────────────────────────────────────────────────\n\nasync function normaliseCandidate<T>(\n candidate: DiffCandidate<T>,\n idKey: string,\n filter: Set<string> | null,\n): Promise<Map<string, Map<string, T>>> {\n const out = new Map<string, Map<string, T>>()\n\n // Vault instance — duck-type via the exportStream method (matches\n // vault.ts's structural shape without forcing a runtime instanceof check\n // that would import the class and risk circular deps).\n if (\n typeof candidate === 'object' &&\n candidate !== null &&\n 'exportStream' in candidate &&\n typeof (candidate as Vault).exportStream === 'function'\n ) {\n for await (const chunk of (candidate as Vault).exportStream({ granularity: 'collection' })) {\n if (filter && !filter.has(chunk.collection)) continue\n const collection = out.get(chunk.collection) ?? new Map<string, T>()\n for (const record of chunk.records) {\n const id = readIdField(record, idKey)\n if (!id) continue\n collection.set(id, record as T)\n }\n out.set(chunk.collection, collection)\n }\n return out\n }\n\n // String — assume a vault.dump() JSON string. Parse and reduce to the map shape.\n if (typeof candidate === 'string') {\n let parsed: unknown\n try {\n parsed = JSON.parse(candidate)\n } catch (err) {\n throw new Error(\n `diffVault: candidate string is not valid JSON (${(err as Error).message})`,\n )\n }\n return collectionsFromObject<T>(parsed, idKey, filter)\n }\n\n // Plain object — `Record<collection, records[]>` (same shape as-json.toObject() returns).\n return collectionsFromObject<T>(candidate, idKey, filter)\n}\n\nfunction collectionsFromObject<T>(\n raw: unknown,\n idKey: string,\n filter: Set<string> | null,\n): Map<string, Map<string, T>> {\n const out = new Map<string, Map<string, T>>()\n if (raw === null || typeof raw !== 'object') {\n throw new Error('diffVault: candidate must be a Vault, an object, or a JSON string')\n }\n // A vault dump JSON has a top-level shape like { _compartment, _keyring, <coll>: <records[]> }.\n // We accept both: keys starting with `_` are skipped (they're metadata), the rest are collections.\n for (const [key, value] of Object.entries(raw)) {\n if (key.startsWith('_')) continue\n if (filter && !filter.has(key)) continue\n if (!Array.isArray(value)) continue\n const collection = new Map<string, T>()\n for (const record of value as readonly T[]) {\n if (record === null || typeof record !== 'object') continue\n const id = readIdField(record, idKey)\n if (!id) continue\n collection.set(id, record)\n }\n out.set(key, collection)\n }\n return out\n}\n\nfunction uniqueTopLevelKeys(diffs: readonly FieldDiffEntry[]): readonly string[] {\n const keys = new Set<string>()\n for (const d of diffs) {\n // path is dot-separated; the top-level key is everything before the\n // first `.` or `[`. (`a.b.c` → `a`, `tags[0]` → `tags`, `(root)` → `(root)`).\n const m = /^[^.[]+/.exec(d.path)\n if (m) keys.add(m[0])\n }\n return [...keys]\n}\n\n/**\n * Pull the id field off a record without going through `String(obj)`,\n * which would emit `[object Object]` for nested objects and silently\n * collapse rows that share the same parent. Only string and number ids\n * are accepted; anything else returns the empty string and the record\n * is skipped at the call site.\n */\nfunction readIdField(record: unknown, idKey: string): string {\n if (record === null || typeof record !== 'object') return ''\n const v = (record as Record<string, unknown>)[idKey]\n if (typeof v === 'string') return v\n if (typeof v === 'number' && Number.isFinite(v)) return String(v)\n return ''\n}\n\ninterface FormatBuckets<T> {\n readonly added: readonly VaultDiffEntry<T>[]\n readonly modified: readonly VaultDiffModifiedEntry<T>[]\n readonly deleted: readonly VaultDiffEntry<T>[]\n readonly summary: VaultDiff<T>['summary']\n}\n\nfunction formatDiff<T>(\n detail: 'count' | 'one-line' | 'full',\n b: FormatBuckets<T>,\n): string {\n const head = `${b.summary.add} added · ${b.summary.modify} modified · ${b.summary.delete} deleted`\n if (detail === 'count') return head\n if (b.summary.total === 0) return head + '\\n(no changes)'\n if (detail === 'one-line') return head\n\n const rows: string[] = [head, '']\n for (const e of b.added) rows.push(`${e.collection}/${e.id}\\tadded`)\n for (const e of b.modified) {\n const fields = e.fieldDiffs\n .map((f) => `${f.path}: ${shortJSON(f.from)} → ${shortJSON(f.to)}`)\n .join(', ')\n rows.push(`${e.collection}/${e.id}\\tmodified\\t${fields}`)\n }\n for (const e of b.deleted) rows.push(`${e.collection}/${e.id}\\tdeleted`)\n return rows.join('\\n')\n}\n\nfunction shortJSON(value: unknown): string {\n if (value === undefined) return 'undefined'\n const s = JSON.stringify(value)\n // JSON.stringify returns string for any JSON value except `undefined`\n // (handled above), `function`, and `symbol`. Fall back to a static\n // tag for those — never let an arbitrary object hit the default\n // stringifier (which the lint rule explicitly bans).\n if (typeof s !== 'string') return '<unrepresentable>'\n return s.length > 60 ? s.slice(0, 57) + '...' : s\n}\n","/**\n * Enable the cargo (partition extraction) capability.\n * Pass to `createNoydb({ cargoStrategy: withCargo() })` to make the source-side\n * `extractPartition(vault, ...)` free function live. The extraction crypto\n * engine is dynamically imported here, so it stays out of the floor bundle\n * until opted in. The recipient-side `adoptPartition` /\n * `decryptExtractedPartition` free functions — and `diffVault` (shared\n * import/merge infra) — are ungated and unaffected.\n */\nimport type { CargoStrategy } from './strategy.js'\n\nexport function withCargo(): CargoStrategy {\n return {\n async extractPartition(vault, opts) {\n const { extractPartitionCore } = await import('./extract-partition.js')\n return extractPartitionCore(vault, opts)\n },\n }\n}\n","/**\n * Partition-extraction dry-run. Read-only preview of what an\n * `extractPartition` would move: record counts, byte totals, and the\n * timestamp span per collection — computed from raw encrypted\n * envelopes WITHOUT decrypting them. Writes nothing, mutates nothing.\n *\n * @module\n */\nimport type { Vault } from '../kernel/vault.js'\nimport { walkClosure, type WalkClosureOptions, type DanglingRefNotice } from './walk-closure.js'\n\nexport interface ExtractionPreview {\n readonly totalRecords: number\n /** Sum of serialized encrypted-envelope sizes (bytes). */\n readonly totalBytes: number\n readonly byCollection: ReadonlyArray<{\n readonly name: string\n readonly recordCount: number\n readonly bytes: number\n /** Earliest envelope `_ts` in this collection (lexicographic). */\n readonly oldestTs?: string\n readonly newestTs?: string\n }>\n readonly graph: { readonly depth: number; readonly cyclesDetected: boolean }\n /** Records the walk reached but whose envelope couldn't be read. */\n readonly inaccessible: ReadonlyArray<{ readonly collection: string; readonly id: string }>\n /**\n * #772: outbound FK edges whose referenced parent was excluded from the\n * closure (missing, or tier-elevated and therefore invisible) — mirrors\n * `ExtractPartitionResult.danglingRefs` (#759) so a preview/extract pair\n * gives the SAME signal. A parent excluded this way never appears in\n * `byCollection` at all; this is the only preview-time indicator.\n */\n readonly danglingRefs: ReadonlyArray<DanglingRefNotice>\n}\n\nexport async function describeExtraction(\n vault: Vault,\n opts: WalkClosureOptions,\n): Promise<ExtractionPreview> {\n const { closure, graph, danglingRefs } = await walkClosure(vault, opts)\n\n const { name: vaultName, adapter } = vault._introspectState()\n const encoder = new TextEncoder()\n\n const byCollection: Array<{\n name: string; recordCount: number; bytes: number; oldestTs?: string; newestTs?: string\n }> = []\n const inaccessible: Array<{ collection: string; id: string }> = []\n let totalBytes = 0\n let totalRecords = 0\n\n for (const [collectionName, ids] of closure) {\n let bytes = 0\n let oldestTs: string | undefined\n let newestTs: string | undefined\n let recordCount = 0\n\n for (const id of ids) {\n const env = await adapter.get(vaultName, collectionName, id)\n if (!env) {\n // Walk reached it (via decrypted list) but the raw store read\n // returned nothing — surface rather than miscount.\n inaccessible.push({ collection: collectionName, id })\n continue\n }\n recordCount++\n bytes += encoder.encode(JSON.stringify(env)).length\n const ts = env._ts\n if (oldestTs === undefined || ts < oldestTs) oldestTs = ts\n if (newestTs === undefined || ts > newestTs) newestTs = ts\n }\n\n byCollection.push({\n name: collectionName,\n recordCount,\n bytes,\n // Spread conditionally — exactOptionalPropertyTypes forbids an\n // explicit `undefined` on an optional property.\n ...(oldestTs !== undefined ? { oldestTs } : {}),\n ...(newestTs !== undefined ? { newestTs } : {}),\n })\n totalBytes += bytes\n totalRecords += recordCount\n }\n\n byCollection.sort((a, b) => a.name.localeCompare(b.name))\n\n return Object.freeze({\n totalRecords,\n totalBytes,\n byCollection,\n graph,\n inaccessible,\n danglingRefs,\n })\n}\n","/**\n * Partition adoption. Recipient side: verify an extracted bundle,\n * validate the transfer key, import the re-keyed collections into a\n * destination store, and record an `_meta/adoption` marker. The bundle\n * stays UNOWNED after adoption — `createOwnerOnAdoptedPartition`\n * mints the owner; the transfer seal is then destroyed.\n *\n * @module\n */\nimport { base64ToBuffer, wrapKey, type EnclaveKey } from '../kernel/enclave/index.js'\nimport { TransferSealError, AdoptionStateError, ValidationError } from '../kernel/errors.js'\nimport type { NoydbStore, VaultSnapshot, KeyringFile } from '../kernel/types.js'\nimport { createOwnerKeyring } from '../with-party/team/keyring.js'\nimport { resolveManagedSecret } from '../with-party/team/managed-secret.js'\nimport type { SealingKeyProvider } from '../with-party/team/managed-secret.js'\nimport type { ShamirRecoveryProvider } from '../with-party/team/shamir-recovery-provider.js'\nimport type { RecoveryEnrollmentInput } from '../with-party/team/rotate-recover.js'\nimport { LedgerStore } from '../with-commit/history/ledger/store.js'\nimport { LEDGER_COLLECTION } from '../with-commit/history/ledger/constants.js'\nimport type { TransferSealPayload } from '../with-pod/pod.js'\nimport { readPodHeader, readPod, parseExtractedPartitionBody } from '../with-pod/pod.js'\nimport { buildRecordEnvelope } from '../kernel/enclave/index.js'\n\n/**\n * Reverse of `sealDeks`. Imports the transfer key, decrypts the\n * sealed `{ collection: base64(rawDEK) }` map (layout iv(12)‖ct‖tag), and\n * re-imports each DEK as an AES-GCM key. Throws `TransferSealError` on a\n * wrong key (AES-GCM auth-tag failure) or malformed payload.\n */\nexport async function unsealDeks(\n seal: TransferSealPayload,\n transferKey: Uint8Array,\n): Promise<Map<string, EnclaveKey>> {\n if (transferKey.byteLength !== 32) {\n throw new TransferSealError(\n `transfer key must be 32 bytes, got ${transferKey.byteLength}.`,\n )\n }\n const key = await crypto.subtle.importKey('raw', transferKey as BufferSource, 'AES-GCM', false, ['decrypt'])\n const raw = base64ToBuffer(seal.payload)\n let plaintext: ArrayBuffer\n try {\n plaintext = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: raw.slice(0, 12) as BufferSource },\n key,\n raw.slice(12) as BufferSource,\n )\n } catch {\n throw new TransferSealError(\n 'transfer seal could not be opened — wrong transfer key (AES-GCM authentication failed).',\n )\n }\n let dekMap: Record<string, string>\n try {\n dekMap = JSON.parse(new TextDecoder().decode(plaintext)) as Record<string, string>\n } catch {\n throw new TransferSealError('transfer seal payload is not valid JSON after decryption.')\n }\n const deks = new Map<string, EnclaveKey>()\n for (const [collection, b64] of Object.entries(dekMap)) {\n // Extractable: the recipient must be able to re-wrap these under their\n // own KEK (AES-KW) at owner-creation. Matches generateDEK.\n const dek = await crypto.subtle.importKey('raw', base64ToBuffer(b64) as BufferSource, 'AES-GCM', true, ['encrypt', 'decrypt'])\n deks.set(collection, dek)\n }\n return deks\n}\n\nexport interface AdoptPartitionOptions {\n readonly transferKey: Uint8Array\n readonly destinationStore: NoydbStore\n readonly vaultName: string\n}\n\nexport interface AdoptPartitionResult {\n readonly vaultName: string\n readonly needsOwner: true\n readonly sealId: string\n}\n\nexport async function adoptPartition(\n bundleBytes: Uint8Array,\n opts: AdoptPartitionOptions,\n): Promise<AdoptPartitionResult> {\n const { transferKey, destinationStore, vaultName } = opts\n\n const header = readPodHeader(bundleBytes)\n if (header.bundleKind !== 'extracted-partition' || header.transferSeal === undefined) {\n throw new ValidationError(\n 'adoptPartition requires an extracted-partition bundle with a transfer seal. '\n + 'For ordinary backups use readPod + vault.load.',\n )\n }\n\n const { dumpJson } = await readPod(bundleBytes)\n const { dump, seal } = parseExtractedPartitionBody(dumpJson)\n\n // Validate the transfer key by unsealing in memory; throws\n // TransferSealError on mismatch. DEKs are discarded here — they stay\n // sealed at rest (in _meta/adoption) until owner-creation wraps them under the\n // recipient's KEK.\n await unsealDeks(seal, transferKey)\n\n // Single-occupancy per vaultName: an `_meta/adoption` marker already present\n // means this slot holds a partition (adopted-and-unowned, or already owned).\n // saveAll below would overwrite its data and replace the marker, stranding the\n // prior adoption's transfer seal. Refuse regardless of sealId — re-adopting the\n // SAME bundle is a redundant call, and adopting a DIFFERENT bundle here would\n // clobber the existing partition. Either way, pick a fresh vaultName.\n const existing = await destinationStore.get(vaultName, '_meta', 'adoption')\n if (existing) {\n const prior = JSON.parse(existing._data) as { sealId?: string }\n if (prior.sealId === seal.sealId) {\n throw new AdoptionStateError(\n `partition (sealId ${seal.sealId}) is already adopted into vault \"${vaultName}\".`,\n )\n }\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already holds an adopted partition (sealId ${prior.sealId}); `\n + `adopting a different partition (sealId ${seal.sealId}) here would overwrite it. `\n + `Adopt into a fresh vaultName instead.`,\n )\n }\n\n // The marker-only check above misses a worse case: a vaultName already in use\n // by an ORDINARY vault (createNoydb + openVault) carries no `_meta/adoption`,\n // yet `saveAll` below is destructive on SQL adapters (`DELETE FROM ... WHERE\n // vault = ?` followed by upsert) and would wipe the legitimate keyring +\n // data. Refuse adoption into ANY occupied slot — a fresh vaultName is the\n // documented precondition.\n const existingKeyring = await destinationStore.list(vaultName, '_keyring')\n if (existingKeyring.length > 0) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already holds a keyring (an unrelated owner exists at this slot); `\n + `adoptPartition requires a fresh vaultName to avoid destructive saveAll on SQL adapters.`,\n )\n }\n\n const backup = JSON.parse(dump) as { collections: VaultSnapshot; _internal?: VaultSnapshot }\n await destinationStore.saveAll(vaultName, backup.collections)\n\n // Import carried internal collections (e.g. _schemas from carrySchemas).\n // saveAll only writes data collections; _internal is written per-record.\n if (backup._internal) {\n for (const [collection, records] of Object.entries(backup._internal)) {\n for (const [id, envelope] of Object.entries(records)) {\n await destinationStore.put(vaultName, collection, id, envelope)\n }\n }\n }\n\n const adoptedAt = new Date().toISOString()\n const adoption = { sealId: seal.sealId, adoptedAt, needsOwner: true as const, transferSeal: seal }\n await destinationStore.put(vaultName, '_meta', 'adoption',\n buildRecordEnvelope({ collection: '_meta', id: 'adoption', version: 1 },\n { ts: adoptedAt, iv: '', data: JSON.stringify(adoption) }))\n\n return { vaultName, needsOwner: true, sealId: seal.sealId }\n}\n\nexport interface CreateOwnerResult {\n readonly vaultName: string\n readonly userId: string\n}\n\n/** Standard-mode owner: recipient supplies the secret. */\nexport interface CreateOwnerStandardOptions {\n readonly userId: string\n readonly secret: string\n readonly transferKey: Uint8Array\n}\n\n/**\n * Managed-mode owner: the secret is minted + sealed under\n * a `SealingKeyProvider` (e.g. an `at-*` OS keychain) so the partition\n * auto-unlocks on the recipient's device. Managed mode mandates a strong\n * (Shamir) recovery profile at creation, which needs the\n * `shamirRecovery` provider injected.\n */\nexport interface CreateOwnerManagedOptions {\n readonly userId: string\n readonly secretMode: 'managed'\n readonly sealingKey: SealingKeyProvider\n readonly recovery: ReadonlyArray<RecoveryEnrollmentInput>\n readonly shamirRecovery: ShamirRecoveryProvider\n readonly transferKey: Uint8Array\n}\n\nexport type CreateOwnerOptions = CreateOwnerStandardOptions | CreateOwnerManagedOptions\n\nfunction isManaged(o: CreateOwnerOptions): o is CreateOwnerManagedOptions {\n return 'secretMode' in o && o.secretMode === 'managed'\n}\n\n/**\n * Mint the first owner keyring on an adopted-but-unowned partition,\n * then destroy the transfer seal.\n *\n * Standard mode: the recipient supplies a secret. Managed mode: the\n * secret is minted + sealed under a `SealingKeyProvider` and a strong\n * (Shamir) recovery profile is enrolled — orchestrated via the existing\n * `openVaultAndEnrollRecovery` ceremony.\n *\n * Either way, reuses `createOwnerKeyring` to derive the KEK + write the base\n * keyring, then wraps the partition's DEKs (recovered from the seal) under that\n * KEK and re-persists the merged keyring file.\n *\n * Idempotent under retry: the seal is destroyed LAST (Stage D), after the\n * keyring (Stage A), the ledger transition (Stage B), and — in managed mode —\n * strong-recovery enrollment (Stage C). A failure in the fallible enrollment\n * step leaves the seal intact, and re-running with the same `userId` +\n * `transferKey` resumes from the first incomplete stage. (Multi-profile recovery\n * arrays may re-enroll an already-enrolled profile on retry; managed mode's\n * mandated single Shamir profile does not.)\n */\nexport async function createOwnerOnAdoptedPartition(\n store: NoydbStore,\n vaultName: string,\n opts: CreateOwnerOptions,\n): Promise<CreateOwnerResult> {\n const { userId, transferKey } = opts\n\n // Managed mode requires a strong (Shamir) recovery profile, validated BEFORE\n // any disk write — same gate as createNoydb.\n if (isManaged(opts) && !opts.recovery.some((r) => r.profile === 'shamir')) {\n throw new AdoptionStateError(\n 'managed-mode adoption requires at least one strong (shamir) recovery profile in '\n + '`recovery` — paper alone is not strong when there is no user secret to fall back on.',\n )\n }\n\n // 1. Verify adopted-unowned state.\n const adoptionEnv = await store.get(vaultName, '_meta', 'adoption')\n if (!adoptionEnv) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" is not an adopted partition (no _meta/adoption). `\n + `createOwnerOnAdoptedPartition only applies to vaults created via adoptPartition.`,\n )\n }\n const adoption = JSON.parse(adoptionEnv._data) as {\n sealId: string; adoptedAt: string; needsOwner?: boolean\n consumedAt?: string; transferSeal?: TransferSealPayload\n }\n if (adoption.consumedAt !== undefined || adoption.transferSeal === undefined) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already has an owner (transfer seal consumed at ${adoption.consumedAt}).`,\n )\n }\n\n // 2. Recover the partition DEKs from the seal (throws on wrong key) BEFORE\n // writing any keyring, so a bad transfer key leaves no trace. Always\n // validated, including when resuming a partial prior call.\n const partitionDeks = await unsealDeks(adoption.transferSeal, transferKey)\n\n // The ceremony below is split into stages so a failure in the fallible\n // managed-enrollment step (network/provider outage) leaves the call RETRYABLE\n // — the seal is destroyed only once everything durable is in place. Each stage\n // detects its own prior completion rather than relying on a single resume bit.\n\n // A keyring present for a DIFFERENT user (with the seal still unconsumed) is a\n // genuine second-owner attempt — refuse it. A same-user keyring is a resumed\n // partial call and is handled by the stage checks below.\n const existingKeyring = await store.get(vaultName, '_keyring', userId)\n const otherOwners = (await store.list(vaultName, '_keyring')).filter((u) => u !== userId)\n if (otherOwners.length > 0) {\n throw new AdoptionStateError(\n `vault \"${vaultName}\" already has a keyring for a different owner; cannot create owner \"${userId}\".`,\n )\n }\n\n // Stage A — mint the owner keyring + merge the partition DEKs. Considered done\n // only when the keyring already holds every partition DEK. createOwnerKeyring\n // overwrites (fresh KEK + fresh _users DEK), so re-running is safe ONLY while\n // no recovery has been enrolled yet — guaranteed here because enrollment\n // (Stage C) runs strictly after Stage A completes.\n const partitionCollections = [...partitionDeks.keys()]\n const priorDeks = existingKeyring ? (JSON.parse(existingKeyring._data) as KeyringFile).deks : {}\n const ownerMinted = existingKeyring !== null && partitionCollections.every((c) => c in priorDeks)\n if (!ownerMinted) {\n // Resolve the owner secret. Managed mode mints a random secret, seals\n // it under the provider, and persists _meta/sealed-secret (so the\n // partition auto-unlocks on the recipient's device); standard mode uses the\n // caller's secret. Idempotent under retry — resolveManagedSecret's reopen\n // arm reuses an already-sealed secret.\n const secret = isManaged(opts)\n ? await resolveManagedSecret(store, vaultName, opts.sealingKey)\n : opts.secret\n\n // Mint the owner keyring (KEK + _users DEK + canary, written to disk).\n const unlocked = await createOwnerKeyring(store, vaultName, { userId: userId, secret: secret })\n\n // Merge the partition DEKs (wrapped under the new KEK) into the keyring.\n const env = await store.get(vaultName, '_keyring', userId)\n if (!env) throw new AdoptionStateError(`keyring write for \"${userId}\" did not persist`)\n const keyringFile = JSON.parse(env._data) as KeyringFile\n const kek = unlocked.kek\n if (!kek) throw new AdoptionStateError(`owner keyring for \"${userId}\" has no KEK to wrap partition DEKs under`)\n const mergedDeks: Record<string, string> = { ...keyringFile.deks }\n for (const [collection, dek] of partitionDeks) {\n mergedDeks[collection] = await wrapKey(dek, kek)\n }\n const mergedFile: KeyringFile = { ...keyringFile, deks: mergedDeks }\n await store.put(vaultName, '_keyring', userId, { ...env, _data: JSON.stringify(mergedFile) })\n }\n\n // Stage B — record the ownership transition on the carried\n // audit chain (carryLedger sealed the _ledger DEK). No-op without that DEK.\n // Idempotent: appended only if the closing `transfer-seal-consumed` entry is\n // absent, so a retry does not duplicate the pair.\n const ledgerDek = partitionDeks.get(LEDGER_COLLECTION)\n if (ledgerDek) {\n const ledger = new LedgerStore({\n adapter: store,\n vault: vaultName,\n encrypted: true,\n getDEK: async () => ledgerDek,\n actor: userId,\n })\n const creationReason = `creation-of-new-owner:${userId}`\n const consumedReason = `transfer-seal-consumed:${adoption.sealId}`\n // Gate each append on its own presence — a crash or store error strictly\n // between the two adjacent puts would otherwise re-append the first one\n // on retry. The pair is the audit record, not a single transaction.\n const recordedReasons = new Set((await ledger.loadAllEntries()).map((e) => e.reason))\n if (!recordedReasons.has(creationReason)) {\n await ledger.append({ op: 'lifecycle', collection: '', id: '', version: 0, actor: '', payloadHash: '', reason: creationReason })\n }\n if (!recordedReasons.has(consumedReason)) {\n await ledger.append({ op: 'lifecycle', collection: '', id: '', version: 0, actor: '', payloadHash: '', reason: consumedReason })\n }\n }\n\n // Stage C — Managed mode: enroll the mandatory strong recovery\n // by orchestrating the existing public ceremony. The partition is\n // now a managed-mode vault on disk (sealed secret + keyring), so we\n // open it as a normal client and let openVaultAndEnrollRecovery do the\n // gate-bypass + enroll + re-assert. Dynamic import keeps the Noydb class\n // out of the @noy-db/hub/cargo static graph. Runs BEFORE seal destruction\n // so a failure here leaves the seal intact and the call retryable.\n if (isManaged(opts)) {\n const { createNoydb } = await import('../kernel/noydb.js')\n const db = await createNoydb({\n store,\n user: userId,\n secretMode: 'managed',\n sealingKey: opts.sealingKey,\n shamirRecovery: opts.shamirRecovery,\n })\n await db.team.openVaultAndEnrollRecovery(vaultName, { recovery: opts.recovery })\n }\n\n // Stage D — Destroy the transfer seal LAST — the commit point. Everything\n // above is either idempotent or resumable, so the seal is only consumed\n // once the owner keyring (and, in managed mode, strong recovery) is\n // durably in place. Retain sealId + consumedAt for audit.\n const consumed = { sealId: adoption.sealId, adoptedAt: adoption.adoptedAt, consumedAt: new Date().toISOString() }\n await store.put(vaultName, '_meta', 'adoption', { ...adoptionEnv, _data: JSON.stringify(consumed) })\n\n return { vaultName, userId }\n}\n","/**\n * Read-side counterpart to `extractPartition`: decrypt an\n * extracted-partition bundle's records to plaintext using its transfer\n * key, WITHOUT adopting it into a vault. Used by an outward\n * orchestration layer's reconcile/merge and field-authority flows to\n * compare incoming records against a receiver. The transfer key validates the bundle\n * (wrong key throws).\n * @module\n */\nimport type { EncryptedEnvelope } from '../kernel/types.js'\nimport { openEnvelopeJson } from '../kernel/enclave/index.js'\nimport { readPodHeader, readPod, parseExtractedPartitionBody } from '../with-pod/pod.js'\nimport { unsealDeks } from './adopt-partition.js'\n\n/** One decrypted record from an extracted-partition compartment. */\nexport interface DecryptedRecord {\n readonly id: string\n readonly record: Record<string, unknown>\n /** Source envelope write timestamp (ISO) — for last-write-wins merges. */\n readonly ts: string\n /** Source envelope version. */\n readonly version: number\n /** Provenance source id (FR-5). Present only when the source collection had provenance:true and a source was supplied on put. */\n readonly source?: string\n /** ISO-8601 timestamp the provenance source was recorded (FR-5). */\n readonly sourceTs?: string\n}\n\n/**\n * Decrypt every record of an extracted-partition bundle to plaintext,\n * grouped by collection. Throws if the bundle isn't an\n * extracted-partition or the transfer key is wrong.\n */\nexport async function decryptExtractedPartition(\n bundleBytes: Uint8Array,\n transferKey: Uint8Array,\n): Promise<Record<string, DecryptedRecord[]>> {\n const header = readPodHeader(bundleBytes)\n if (header.bundleKind !== 'extracted-partition' || header.transferSeal === undefined) {\n throw new Error('decryptExtractedPartition: bundle is not an extracted-partition.')\n }\n const { dumpJson } = await readPod(bundleBytes)\n const { dump, seal } = parseExtractedPartitionBody(dumpJson)\n const deks = await unsealDeks(seal, transferKey) // throws TransferSealError on wrong key\n const backup = JSON.parse(dump) as { collections: Record<string, Record<string, EncryptedEnvelope>> }\n const out: Record<string, DecryptedRecord[]> = {}\n for (const [collection, byId] of Object.entries(backup.collections)) {\n const dek = deks.get(collection)\n if (dek === undefined) continue // no DEK sealed for this collection — skip\n const recs: DecryptedRecord[] = []\n for (const [id, env] of Object.entries(byId)) {\n const plaintext = await openEnvelopeJson({ collection, id }, env, dek)\n const body = JSON.parse(plaintext) as Record<string, unknown>\n recs.push({\n id,\n record: { ...body, id },\n ts: env._ts,\n version: env._v,\n ...(env._source !== undefined ? { source: env._source } : {}),\n ...(env._sourceTs !== undefined ? { sourceTs: env._sourceTs } : {}),\n })\n }\n out[collection] = recs\n }\n return out\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2JA,eAAsB,UACpB,OACA,WACA,UAAuB,CAAC,GACD;AACvB,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,SAAS,QAAQ,cAAc,IAAI,IAAI,QAAQ,WAAW,IAAI;AACpE,QAAM,YACJ,QAAQ,cAAc,CAAC,GAAY,MAAe,KAAU,GAAG,CAAC,EAAE,WAAW;AAO/E,QAAM,OAAO,oBAAI,IAA4B;AAC7C,mBAAiB,SAAS,MAAM,aAAa,EAAE,aAAa,aAAa,CAAC,GAAG;AAC3E,QAAI,UAAU,CAAC,OAAO,IAAI,MAAM,UAAU,EAAG;AAC7C,UAAM,aAAa,KAAK,IAAI,MAAM,UAAU,KAAK,oBAAI,IAAe;AACpE,eAAW,UAAU,MAAM,SAAS;AAClC,YAAM,KAAK,YAAY,QAAQ,KAAK;AACpC,UAAI,CAAC,GAAI;AACT,iBAAW,IAAI,IAAI,MAAW;AAAA,IAChC;AACA,SAAK,IAAI,MAAM,YAAY,UAAU;AAAA,EACvC;AAGA,QAAM,OAAO,MAAM,mBAAsB,WAAW,OAAO,MAAM;AAGjE,QAAM,QAA6B,CAAC;AACpC,QAAM,WAAwC,CAAC;AAC/C,QAAM,UAA+B,CAAC;AACtC,QAAM,YAA6C,QAAQ,mBAAmB,CAAC,IAAI;AAEnF,QAAM,kBAAkB,oBAAI,IAAI,CAAC,GAAG,KAAK,KAAK,GAAG,GAAG,KAAK,KAAK,CAAC,CAAC;AAChE,aAAW,cAAc,CAAC,GAAG,eAAe,EAAE,KAAK,GAAG;AACpD,UAAM,WAAW,KAAK,IAAI,UAAU,KAAK,oBAAI,IAAe;AAC5D,UAAM,WAAW,KAAK,IAAI,UAAU,KAAK,oBAAI,IAAe;AAC5D,UAAM,SAAS,oBAAI,IAAI,CAAC,GAAG,SAAS,KAAK,GAAG,GAAG,SAAS,KAAK,CAAC,CAAC;AAE/D,eAAW,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,GAAG;AACnC,YAAM,SAAS,SAAS,IAAI,EAAE;AAC9B,YAAM,QAAQ,SAAS,IAAI,EAAE;AAE7B,UAAI,WAAW,UAAa,UAAU,QAAW;AAE/C,cAAM,KAAK,EAAE,YAAY,IAAI,QAAQ,MAAM,CAAC;AAAA,MAC9C,WAAW,WAAW,UAAa,UAAU,QAAW;AAEtD,cAAM,WAAW,QAAQ,kBACpB,MAAM,MAAM,WAAW,UAAU,EAAE,YAAY,EAAE,KAAM,SACxD;AACJ,gBAAQ,KAAK,EAAE,YAAY,IAAI,QAAQ,QAAQ,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC,EAAG,CAAC;AAAA,MAClG,WAAW,WAAW,UAAa,UAAU,QAAW;AACtD,YAAI,UAAU,QAAQ,KAAK,GAAG;AAC5B,qBAAW,KAAK,EAAE,YAAY,IAAI,QAAQ,MAAM,CAAC;AAAA,QACnD,OAAO;AAEL,gBAAM,WAAW,QAAQ,kBACpB,MAAM,MAAM,WAAW,UAAU,EAAE,YAAY,EAAE,KAAM,SACxD;AACJ,gBAAM,aAAa,KAAU,QAAQ,KAAK;AAC1C,gBAAM,gBAAgB,mBAAmB,UAAU;AACnD,mBAAS,KAAK;AAAA,YACZ;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,YACA,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,UAC/C,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU;AAAA,IACd,KAAK,MAAM;AAAA,IACX,QAAQ,SAAS;AAAA,IACjB,QAAQ,QAAQ;AAAA,IAChB,OAAO,MAAM,SAAS,SAAS,SAAS,QAAQ;AAAA,EAClD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,MAAM;AACX,aAAO,WAAW,MAAM,UAAU,QAAQ,EAAE,OAAO,UAAU,SAAS,QAAQ,CAAC;AAAA,IACjF;AAAA,EACF;AACF;AAIA,eAAe,mBACb,WACA,OACA,QACsC;AACtC,QAAM,MAAM,oBAAI,IAA4B;AAK5C,MACE,OAAO,cAAc,YACrB,cAAc,QACd,kBAAkB,aAClB,OAAQ,UAAoB,iBAAiB,YAC7C;AACA,qBAAiB,SAAU,UAAoB,aAAa,EAAE,aAAa,aAAa,CAAC,GAAG;AAC1F,UAAI,UAAU,CAAC,OAAO,IAAI,MAAM,UAAU,EAAG;AAC7C,YAAM,aAAa,IAAI,IAAI,MAAM,UAAU,KAAK,oBAAI,IAAe;AACnE,iBAAW,UAAU,MAAM,SAAS;AAClC,cAAM,KAAK,YAAY,QAAQ,KAAK;AACpC,YAAI,CAAC,GAAI;AACT,mBAAW,IAAI,IAAI,MAAW;AAAA,MAChC;AACA,UAAI,IAAI,MAAM,YAAY,UAAU;AAAA,IACtC;AACA,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,cAAc,UAAU;AACjC,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,SAAS;AAAA,IAC/B,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,kDAAmD,IAAc,OAAO;AAAA,MAC1E;AAAA,IACF;AACA,WAAO,sBAAyB,QAAQ,OAAO,MAAM;AAAA,EACvD;AAGA,SAAO,sBAAyB,WAAW,OAAO,MAAM;AAC1D;AAEA,SAAS,sBACP,KACA,OACA,QAC6B;AAC7B,QAAM,MAAM,oBAAI,IAA4B;AAC5C,MAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,QAAI,IAAI,WAAW,GAAG,EAAG;AACzB,QAAI,UAAU,CAAC,OAAO,IAAI,GAAG,EAAG;AAChC,QAAI,CAAC,MAAM,QAAQ,KAAK,EAAG;AAC3B,UAAM,aAAa,oBAAI,IAAe;AACtC,eAAW,UAAU,OAAuB;AAC1C,UAAI,WAAW,QAAQ,OAAO,WAAW,SAAU;AACnD,YAAM,KAAK,YAAY,QAAQ,KAAK;AACpC,UAAI,CAAC,GAAI;AACT,iBAAW,IAAI,IAAI,MAAM;AAAA,IAC3B;AACA,QAAI,IAAI,KAAK,UAAU;AAAA,EACzB;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAAqD;AAC/E,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,KAAK,OAAO;AAGrB,UAAM,IAAI,UAAU,KAAK,EAAE,IAAI;AAC/B,QAAI,EAAG,MAAK,IAAI,EAAE,CAAC,CAAC;AAAA,EACtB;AACA,SAAO,CAAC,GAAG,IAAI;AACjB;AASA,SAAS,YAAY,QAAiB,OAAuB;AAC3D,MAAI,WAAW,QAAQ,OAAO,WAAW,SAAU,QAAO;AAC1D,QAAM,IAAK,OAAmC,KAAK;AACnD,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,MAAI,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,EAAG,QAAO,OAAO,CAAC;AAChE,SAAO;AACT;AASA,SAAS,WACP,QACA,GACQ;AACR,QAAM,OAAO,GAAG,EAAE,QAAQ,GAAG,eAAY,EAAE,QAAQ,MAAM,kBAAe,EAAE,QAAQ,MAAM;AACxF,MAAI,WAAW,QAAS,QAAO;AAC/B,MAAI,EAAE,QAAQ,UAAU,EAAG,QAAO,OAAO;AACzC,MAAI,WAAW,WAAY,QAAO;AAElC,QAAM,OAAiB,CAAC,MAAM,EAAE;AAChC,aAAW,KAAK,EAAE,MAAO,MAAK,KAAK,GAAG,EAAE,UAAU,IAAI,EAAE,EAAE,QAAS;AACnE,aAAW,KAAK,EAAE,UAAU;AAC1B,UAAM,SAAS,EAAE,WACd,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,UAAU,EAAE,IAAI,CAAC,WAAM,UAAU,EAAE,EAAE,CAAC,EAAE,EACjE,KAAK,IAAI;AACZ,SAAK,KAAK,GAAG,EAAE,UAAU,IAAI,EAAE,EAAE,aAAe,MAAM,EAAE;AAAA,EAC1D;AACA,aAAW,KAAK,EAAE,QAAS,MAAK,KAAK,GAAG,EAAE,UAAU,IAAI,EAAE,EAAE,UAAW;AACvE,SAAO,KAAK,KAAK,IAAI;AACvB;AAEA,SAAS,UAAU,OAAwB;AACzC,MAAI,UAAU,OAAW,QAAO;AAChC,QAAM,IAAI,KAAK,UAAU,KAAK;AAK9B,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,SAAO,EAAE,SAAS,KAAK,EAAE,MAAM,GAAG,EAAE,IAAI,QAAQ;AAClD;;;AC5XO,SAAS,YAA2B;AACzC,SAAO;AAAA,IACL,MAAM,iBAAiB,OAAO,MAAM;AAClC,YAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,iCAAwB;AACtE,aAAO,qBAAqB,OAAO,IAAI;AAAA,IACzC;AAAA,EACF;AACF;;;ACkBA,eAAsB,mBACpB,OACA,MAC4B;AAC5B,QAAM,EAAE,SAAS,OAAO,aAAa,IAAI,MAAM,YAAY,OAAO,IAAI;AAEtE,QAAM,EAAE,MAAM,WAAW,QAAQ,IAAI,MAAM,iBAAiB;AAC5D,QAAM,UAAU,IAAI,YAAY;AAEhC,QAAM,eAED,CAAC;AACN,QAAM,eAA0D,CAAC;AACjE,MAAI,aAAa;AACjB,MAAI,eAAe;AAEnB,aAAW,CAAC,gBAAgB,GAAG,KAAK,SAAS;AAC3C,QAAI,QAAQ;AACZ,QAAI;AACJ,QAAI;AACJ,QAAI,cAAc;AAElB,eAAW,MAAM,KAAK;AACpB,YAAM,MAAM,MAAM,QAAQ,IAAI,WAAW,gBAAgB,EAAE;AAC3D,UAAI,CAAC,KAAK;AAGR,qBAAa,KAAK,EAAE,YAAY,gBAAgB,GAAG,CAAC;AACpD;AAAA,MACF;AACA;AACA,eAAS,QAAQ,OAAO,KAAK,UAAU,GAAG,CAAC,EAAE;AAC7C,YAAM,KAAK,IAAI;AACf,UAAI,aAAa,UAAa,KAAK,SAAU,YAAW;AACxD,UAAI,aAAa,UAAa,KAAK,SAAU,YAAW;AAAA,IAC1D;AAEA,iBAAa,KAAK;AAAA,MAChB,MAAM;AAAA,MACN;AAAA,MACA;AAAA;AAAA;AAAA,MAGA,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,MAC7C,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/C,CAAC;AACD,kBAAc;AACd,oBAAgB;AAAA,EAClB;AAEA,eAAa,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAExD,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;;;ACnEA,eAAsB,WACpB,MACA,aACkC;AAClC,MAAI,YAAY,eAAe,IAAI;AACjC,UAAM,IAAI;AAAA,MACR,sCAAsC,YAAY,UAAU;AAAA,IAC9D;AAAA,EACF;AACA,QAAM,MAAM,MAAM,OAAO,OAAO,UAAU,OAAO,aAA6B,WAAW,OAAO,CAAC,SAAS,CAAC;AAC3G,QAAM,MAAM,eAAe,KAAK,OAAO;AACvC,MAAI;AACJ,MAAI;AACF,gBAAY,MAAM,OAAO,OAAO;AAAA,MAC9B,EAAE,MAAM,WAAW,IAAI,IAAI,MAAM,GAAG,EAAE,EAAkB;AAAA,MACxD;AAAA,MACA,IAAI,MAAM,EAAE;AAAA,IACd;AAAA,EACF,QAAQ;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,SAAS,CAAC;AAAA,EACzD,QAAQ;AACN,UAAM,IAAI,kBAAkB,2DAA2D;AAAA,EACzF;AACA,QAAM,OAAO,oBAAI,IAAwB;AACzC,aAAW,CAAC,YAAY,GAAG,KAAK,OAAO,QAAQ,MAAM,GAAG;AAGtD,UAAM,MAAM,MAAM,OAAO,OAAO,UAAU,OAAO,eAAe,GAAG,GAAmB,WAAW,MAAM,CAAC,WAAW,SAAS,CAAC;AAC7H,SAAK,IAAI,YAAY,GAAG;AAAA,EAC1B;AACA,SAAO;AACT;AAcA,eAAsB,eACpB,aACA,MAC+B;AAC/B,QAAM,EAAE,aAAa,kBAAkB,UAAU,IAAI;AAErD,QAAM,SAAS,cAAc,WAAW;AACxC,MAAI,OAAO,eAAe,yBAAyB,OAAO,iBAAiB,QAAW;AACpF,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,EAAE,SAAS,IAAI,MAAM,QAAQ,WAAW;AAC9C,QAAM,EAAE,MAAM,KAAK,IAAI,4BAA4B,QAAQ;AAM3D,QAAM,WAAW,MAAM,WAAW;AAQlC,QAAM,WAAW,MAAM,iBAAiB,IAAI,WAAW,SAAS,UAAU;AAC1E,MAAI,UAAU;AACZ,UAAM,QAAQ,KAAK,MAAM,SAAS,KAAK;AACvC,QAAI,MAAM,WAAW,KAAK,QAAQ;AAChC,YAAM,IAAI;AAAA,QACR,qBAAqB,KAAK,MAAM,oCAAoC,SAAS;AAAA,MAC/E;AAAA,IACF;AACA,UAAM,IAAI;AAAA,MACR,UAAU,SAAS,gDAAgD,MAAM,MAAM,6CACnC,KAAK,MAAM;AAAA,IAEzD;AAAA,EACF;AAQA,QAAM,kBAAkB,MAAM,iBAAiB,KAAK,WAAW,UAAU;AACzE,MAAI,gBAAgB,SAAS,GAAG;AAC9B,UAAM,IAAI;AAAA,MACR,UAAU,SAAS;AAAA,IAErB;AAAA,EACF;AAEA,QAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,QAAM,iBAAiB,QAAQ,WAAW,OAAO,WAAW;AAI5D,MAAI,OAAO,WAAW;AACpB,eAAW,CAAC,YAAY,OAAO,KAAK,OAAO,QAAQ,OAAO,SAAS,GAAG;AACpE,iBAAW,CAAC,IAAI,QAAQ,KAAK,OAAO,QAAQ,OAAO,GAAG;AACpD,cAAM,iBAAiB,IAAI,WAAW,YAAY,IAAI,QAAQ;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,QAAM,WAAW,EAAE,QAAQ,KAAK,QAAQ,WAAW,YAAY,MAAe,cAAc,KAAK;AACjG,QAAM,iBAAiB;AAAA,IAAI;AAAA,IAAW;AAAA,IAAS;AAAA,IAC7C;AAAA,MAAoB,EAAE,YAAY,SAAS,IAAI,YAAY,SAAS,EAAE;AAAA,MACpE,EAAE,IAAI,WAAW,IAAI,IAAI,MAAM,KAAK,UAAU,QAAQ,EAAE;AAAA,IAAC;AAAA,EAAC;AAE9D,SAAO,EAAE,WAAW,YAAY,MAAM,QAAQ,KAAK,OAAO;AAC5D;AAgCA,SAAS,UAAU,GAAuD;AACxE,SAAO,gBAAgB,KAAK,EAAE,eAAe;AAC/C;AAuBA,eAAsB,8BACpB,OACA,WACA,MAC4B;AAC5B,QAAM,EAAE,QAAQ,YAAY,IAAI;AAIhC,MAAI,UAAU,IAAI,KAAK,CAAC,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,QAAQ,GAAG;AACzE,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAGA,QAAM,cAAc,MAAM,MAAM,IAAI,WAAW,SAAS,UAAU;AAClE,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI;AAAA,MACR,UAAU,SAAS;AAAA,IAErB;AAAA,EACF;AACA,QAAM,WAAW,KAAK,MAAM,YAAY,KAAK;AAI7C,MAAI,SAAS,eAAe,UAAa,SAAS,iBAAiB,QAAW;AAC5E,UAAM,IAAI;AAAA,MACR,UAAU,SAAS,qDAAqD,SAAS,UAAU;AAAA,IAC7F;AAAA,EACF;AAKA,QAAM,gBAAgB,MAAM,WAAW,SAAS,cAAc,WAAW;AAUzE,QAAM,kBAAkB,MAAM,MAAM,IAAI,WAAW,YAAY,MAAM;AACrE,QAAM,eAAe,MAAM,MAAM,KAAK,WAAW,UAAU,GAAG,OAAO,CAAC,MAAM,MAAM,MAAM;AACxF,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,IAAI;AAAA,MACR,UAAU,SAAS,uEAAuE,MAAM;AAAA,IAClG;AAAA,EACF;AAOA,QAAM,uBAAuB,CAAC,GAAG,cAAc,KAAK,CAAC;AACrD,QAAM,YAAY,kBAAmB,KAAK,MAAM,gBAAgB,KAAK,EAAkB,OAAO,CAAC;AAC/F,QAAM,cAAc,oBAAoB,QAAQ,qBAAqB,MAAM,CAAC,MAAM,KAAK,SAAS;AAChG,MAAI,CAAC,aAAa;AAMhB,UAAM,SAAS,UAAU,IAAI,IACzB,MAAM,qBAAqB,OAAO,WAAW,KAAK,UAAU,IAC5D,KAAK;AAGT,UAAM,WAAW,MAAM,mBAAmB,OAAO,WAAW,EAAE,QAAgB,OAAe,CAAC;AAG9F,UAAM,MAAM,MAAM,MAAM,IAAI,WAAW,YAAY,MAAM;AACzD,QAAI,CAAC,IAAK,OAAM,IAAI,mBAAmB,sBAAsB,MAAM,mBAAmB;AACtF,UAAM,cAAc,KAAK,MAAM,IAAI,KAAK;AACxC,UAAM,MAAM,SAAS;AACrB,QAAI,CAAC,IAAK,OAAM,IAAI,mBAAmB,sBAAsB,MAAM,2CAA2C;AAC9G,UAAM,aAAqC,EAAE,GAAG,YAAY,KAAK;AACjE,eAAW,CAAC,YAAY,GAAG,KAAK,eAAe;AAC7C,iBAAW,UAAU,IAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,IACjD;AACA,UAAM,aAA0B,EAAE,GAAG,aAAa,MAAM,WAAW;AACnE,UAAM,MAAM,IAAI,WAAW,YAAY,QAAQ,EAAE,GAAG,KAAK,OAAO,KAAK,UAAU,UAAU,EAAE,CAAC;AAAA,EAC9F;AAMA,QAAM,YAAY,cAAc,IAAI,iBAAiB;AACrD,MAAI,WAAW;AACb,UAAM,SAAS,IAAI,YAAY;AAAA,MAC7B,SAAS;AAAA,MACT,OAAO;AAAA,MACP,WAAW;AAAA,MACX,QAAQ,YAAY;AAAA,MACpB,OAAO;AAAA,IACT,CAAC;AACD,UAAM,iBAAiB,yBAAyB,MAAM;AACtD,UAAM,iBAAiB,0BAA0B,SAAS,MAAM;AAIhE,UAAM,kBAAkB,IAAI,KAAK,MAAM,OAAO,eAAe,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AACpF,QAAI,CAAC,gBAAgB,IAAI,cAAc,GAAG;AACxC,YAAM,OAAO,OAAO,EAAE,IAAI,aAAa,YAAY,IAAI,IAAI,IAAI,SAAS,GAAG,OAAO,IAAI,aAAa,IAAI,QAAQ,eAAe,CAAC;AAAA,IACjI;AACA,QAAI,CAAC,gBAAgB,IAAI,cAAc,GAAG;AACxC,YAAM,OAAO,OAAO,EAAE,IAAI,aAAa,YAAY,IAAI,IAAI,IAAI,SAAS,GAAG,OAAO,IAAI,aAAa,IAAI,QAAQ,eAAe,CAAC;AAAA,IACjI;AAAA,EACF;AASA,MAAI,UAAU,IAAI,GAAG;AACnB,UAAM,EAAE,YAAY,IAAI,MAAM,OAAO,qBAAoB;AACzD,UAAM,KAAK,MAAM,YAAY;AAAA,MAC3B;AAAA,MACA,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,YAAY,KAAK;AAAA,MACjB,gBAAgB,KAAK;AAAA,IACvB,CAAC;AACD,UAAM,GAAG,KAAK,2BAA2B,WAAW,EAAE,UAAU,KAAK,SAAS,CAAC;AAAA,EACjF;AAMA,QAAM,WAAW,EAAE,QAAQ,SAAS,QAAQ,WAAW,SAAS,WAAW,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE;AAChH,QAAM,MAAM,IAAI,WAAW,SAAS,YAAY,EAAE,GAAG,aAAa,OAAO,KAAK,UAAU,QAAQ,EAAE,CAAC;AAEnG,SAAO,EAAE,WAAW,OAAO;AAC7B;;;ACtUA,eAAsB,0BACpB,aACA,aAC4C;AAC5C,QAAM,SAAS,cAAc,WAAW;AACxC,MAAI,OAAO,eAAe,yBAAyB,OAAO,iBAAiB,QAAW;AACpF,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AACA,QAAM,EAAE,SAAS,IAAI,MAAM,QAAQ,WAAW;AAC9C,QAAM,EAAE,MAAM,KAAK,IAAI,4BAA4B,QAAQ;AAC3D,QAAM,OAAO,MAAM,WAAW,MAAM,WAAW;AAC/C,QAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,QAAM,MAAyC,CAAC;AAChD,aAAW,CAAC,YAAY,IAAI,KAAK,OAAO,QAAQ,OAAO,WAAW,GAAG;AACnE,UAAM,MAAM,KAAK,IAAI,UAAU;AAC/B,QAAI,QAAQ,OAAW;AACvB,UAAM,OAA0B,CAAC;AACjC,eAAW,CAAC,IAAI,GAAG,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC5C,YAAM,YAAY,MAAM,iBAAiB,EAAE,YAAY,GAAG,GAAG,KAAK,GAAG;AACrE,YAAM,OAAO,KAAK,MAAM,SAAS;AACjC,WAAK,KAAK;AAAA,QACR;AAAA,QACA,QAAQ,EAAE,GAAG,MAAM,GAAG;AAAA,QACtB,IAAI,IAAI;AAAA,QACR,SAAS,IAAI;AAAA,QACb,GAAI,IAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,QAAQ,IAAI,CAAC;AAAA,QAC3D,GAAI,IAAI,cAAc,SAAY,EAAE,UAAU,IAAI,UAAU,IAAI,CAAC;AAAA,MACnE,CAAC;AAAA,IACH;AACA,QAAI,UAAU,IAAI;AAAA,EACpB;AACA,SAAO;AACT;","names":[]}
@@ -3,10 +3,10 @@ import {
3
3
  } from "./chunk-5D2ALSM5.js";
4
4
  import {
5
5
  RecordCodec
6
- } from "./chunk-VN45YLWM.js";
6
+ } from "./chunk-OHOKBMTM.js";
7
7
 
8
8
  // src/with-formula/materialized-views/stale.ts
9
- var loadMVExecutor = lazy(() => import("./executor-FHHLXO4Y.js"));
9
+ var loadMVExecutor = lazy(() => import("./executor-CZDXBXKE.js"));
10
10
  var _staleByRegistry = /* @__PURE__ */ new WeakMap();
11
11
  function markMVStale(registry, mvName) {
12
12
  let set = _staleByRegistry.get(registry);
@@ -26,7 +26,7 @@ function storeOf(accessor, collectionName) {
26
26
  return { adapter: c.adapter, vault: c.vault };
27
27
  }
28
28
  async function writeMVStaleMarker(adapter, vault, mvName) {
29
- const env = RecordCodec.buildPlaintextEnvelope({ version: 1, data: "{}" });
29
+ const env = RecordCodec.buildPlaintextEnvelope({ collection: MV_STALE_COLLECTION, id: mvName, version: 1 }, { data: "{}" });
30
30
  await adapter.put(vault, MV_STALE_COLLECTION, mvName, env);
31
31
  }
32
32
  async function deleteMVStaleMarker(adapter, vault, mvName) {
@@ -134,4 +134,4 @@ export {
134
134
  clearMVStale,
135
135
  clearMVStaleFully
136
136
  };
137
- //# sourceMappingURL=chunk-26JMGSSC.js.map
137
+ //# sourceMappingURL=chunk-EES37S2V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-formula/materialized-views/stale.ts"],"sourcesContent":["import type { Collection } from '../../kernel/collection.js'\nimport type { MaterializedViewExecutor as MVExecutorType } from './executor.js'\nimport type { TxContext } from '../../with-commit/tx/transaction.js'\nimport type { PutDerivedOutputCtx } from '../../kernel/via/dispatch.js'\nimport type { MaterializedViewRegistry, RegisteredMV } from './registry.js'\n// Type-only — runtime class loaded via dynamic import in\n// `resolveStaleMVOnRead` only when a stale flag actually fires.\n// Keeps the executor chunk out of the floor bundle (mirrors v1 floor-bundle isolation).\nimport type { MVQueryContext } from './types.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport { RecordCodec } from '../../kernel/enclave/index.js'\n\nimport { lazy } from '../../kernel/lazy.js'\n\n/** #846c — one memoized binding instead of a cast at the call site. */\nconst loadMVExecutor = lazy(() => import('./executor.js'))\n\n/**\n * Accessor shape passed in from the owning Vault. Provides the\n * registry (used as a stable WeakMap key + to look up MVs by output\n * collection) and the runtime context the lazy refresh needs.\n * Mirrors v1's `DerivationStaleAccessor`.\n */\nexport interface MVStaleAccessor {\n registry(): MaterializedViewRegistry\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getCollection(name: string): Collection<any>\n getActiveTxContext(): TxContext | null\n getQueryContext(): MVQueryContext\n}\n\n/**\n * In-memory stale map keyed by `MaterializedViewRegistry` instance\n * (stable per vault). Each registry maps to a set of MV names that\n * have at least one pending source-change requiring a re-materialize.\n *\n * Persistence across vault close is NOT implemented in this iteration\n * (concern flagged in the v2 spec, mirrors v1 derivation behavior).\n * On vault re-open, the unset stale flag is interpreted as \"fresh\" —\n * `vault.refreshView(name)` is the explicit recompute escape hatch.\n *\n * @internal\n */\nconst _staleByRegistry = new WeakMap<MaterializedViewRegistry, Set<string>>()\n\n/**\n * Mark an MV as stale. Called from `Collection.dispatchMaterializedViews`\n * when a source-write fires for a `refresh: 'lazy'` MV.\n *\n * @internal\n */\nexport function markMVStale(registry: MaterializedViewRegistry, mvName: string): void {\n let set = _staleByRegistry.get(registry)\n if (!set) {\n set = new Set()\n _staleByRegistry.set(registry, set)\n }\n set.add(mvName)\n}\n\n/**\n * Test-only: check whether a given MV name is currently flagged stale\n * against a registry. Exported so the regression suite can pin the\n * stale-bit lifecycle without touching the internal `WeakMap`.\n *\n * @internal\n */\nexport function isMVStale(registry: MaterializedViewRegistry, mvName: string): boolean {\n return _staleByRegistry.get(registry)?.has(mvName) ?? false\n}\n\n/**\n * Reserved collection holding CONTENT-FREE lazy-stale markers (record id =\n * MV name, plaintext `_iv: ''` envelope, no payload) — mirrors the\n * `_meta`/schema-fence marker envelope shape. Written only from the\n * delete/forget/elevate dispatcher (#736); ordinary source writes stay\n * in-memory-only (the cheap path). Read via the adapter directly, never\n * through `vault.collection()` — same reserved-collection convention as\n * `_subject_index`/`_meta`.\n */\nexport const MV_STALE_COLLECTION = '_mv_stale'\n\n/**\n * Once-per-registry hydrate guard for `resolveStaleMVOnRead`'s persisted-marker fold-in.\n * Stores the in-flight/settled PROMISE (not a boolean) — a concurrent cold first read that\n * arrives while the hydrate is still awaiting `adapter.list` must await the SAME promise\n * rather than observing \"already hydrating\" and reading an empty pending set (#736\n * whole-branch review).\n */\nconst _hydratedByRegistry = new WeakMap<MaterializedViewRegistry, Promise<void>>()\n\n/** The adapter + vault name backing any collection in this vault (all collections share both). */\nfunction storeOf(accessor: MVStaleAccessor, collectionName: string): { adapter: NoydbStore; vault: string } {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const c = accessor.getCollection(collectionName) as any\n return { adapter: c.adapter as NoydbStore, vault: c.vault as string }\n}\n\nasync function writeMVStaleMarker(adapter: NoydbStore, vault: string, mvName: string): Promise<void> {\n // Content-free — the marker's only payload is its key (the MV name).\n const env = RecordCodec.buildPlaintextEnvelope({ collection: MV_STALE_COLLECTION, id: mvName, version: 1 }, { data: '{}' })\n await adapter.put(vault, MV_STALE_COLLECTION, mvName, env)\n}\n\nasync function deleteMVStaleMarker(adapter: NoydbStore, vault: string, mvName: string): Promise<void> {\n await adapter.delete(vault, MV_STALE_COLLECTION, mvName)\n}\n\n/**\n * On first `resolveStaleMVOnRead` call for a (cold-reopened) registry, fold every\n * persisted `_mv_stale` marker into the in-memory pending set — otherwise a cold\n * session's empty `WeakMap` entry reads as \"fresh\" and serves the emptied output\n * collection forever.\n */\nasync function hydratePersistedStaleMarkers(accessor: MVStaleAccessor, registry: MaterializedViewRegistry): Promise<void> {\n const mvs = registry.all()\n if (mvs.length === 0) return\n const { adapter, vault } = storeOf(accessor, mvs[0]!.outputCollection)\n // No try/catch: a genuine store failure here must surface, not be read as\n // \"nothing pending\" — silently treating it as fresh is the exact leak class\n // this module closes (mirrors `subject-index.ts`'s bare `adapter.list` reads).\n for (const name of await adapter.list(vault, MV_STALE_COLLECTION)) markMVStale(registry, name)\n}\n\n/**\n * Invalidate an MV from the delete/forget/elevate dispatcher (#736) — the ordinary\n * source-write path (`dispatchMaterializedViews`) never calls this. Deletes EVERY\n * persisted row in `reg.outputCollection` via `_internalDelete` (the at-rest law: a\n * stale mark alone leaves the elevated/forgotten source's plaintext sitting in the\n * output row) using the adapter directly so the read-path's `resolveStaleMVOnRead`\n * isn't triggered mid-invalidation. `mode: 'lazy'` also persists the stale mark so a\n * cold session recomputes on next read; `'manual'` gets the purge only — the MV\n * serves empty until an explicit `vault.refreshView()` (erasure wins). Deletion is\n * stamp-scoped (`_materializedFrom.mvName === reg.spec.name` — see the loop below),\n * so another registered MV sharing this output collection keeps its own rows intact:\n * no cross-MV re-marking is needed here, only `reg` itself is marked stale.\n *\n * Returns the count of rows actually `_internalDelete`d (#761 item 1) — folded by the\n * caller into `dispatchMaterializedViewsOnDelete`'s `deleted` so `ForgetResult.derivedRecordsErased`\n * counts lazy/manual purges too, not just the eager executor's tombstone leg — plus\n * `residueUndecodable`, the bare ids whose ownership stamp could NOT be decoded (#776): a\n * candidate row that fails to decode under the collection's default DEK (e.g. elevated above\n * tier 0 on a tiered output collection) has UNKNOWN ownership — it might be this MV's own\n * output, or (same-collection shape) a plain user record — so it is never erased, but it must\n * be SURFACED rather than silently skipped (the #724 posture), since it may still hold the\n * forgotten/pre-elevation contribution, decryptable by tier-holders — and `residueDeclined`\n * (#785), the bare ids that DID decode and stamp-match but whose `_internalDelete` declined\n * (ownership CONFIRMED, erasure declined).\n *\n * @internal\n */\nexport async function invalidateMVAtRest(\n accessor: MVStaleAccessor,\n reg: RegisteredMV,\n mode: 'lazy' | 'manual',\n): Promise<{ deleted: number; residueUndecodable: string[]; residueDeclined: string[] }> {\n const outputColl = accessor.getCollection(reg.outputCollection)\n const txCtx = accessor.getActiveTxContext()\n const { adapter, vault } = storeOf(accessor, reg.outputCollection)\n let deleted = 0\n const residueUndecodable: string[] = []\n const residueDeclined: string[] = []\n for (const id of await adapter.list(vault, reg.outputCollection)) {\n // A same-collection partition MV (`output: { collection: <source>, partition }`,\n // the DERIV-PP30-001 shape) writes INTO its own source collection — `adapter.list`\n // over `reg.outputCollection` then also returns untouched user source records.\n // Decode each candidate row (the invalidation path is rare; this cost is fine\n // here) and only erase rows THIS MV stamped via `_materializedFrom.mvName` —\n // an unstamped row, or one stamped by a different MV, is never this MV's to\n // delete (#736 whole-branch review, Critical).\n const envelope = await adapter.get(vault, reg.outputCollection, id)\n if (envelope === null) continue\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const decoded = await (outputColl as any)._decodeEnvelope(envelope, id)\n if (decoded === null) { residueUndecodable.push(id); continue } // #776 — ownership unknown, surfaced not skipped\n const stampedBy = (decoded as Record<string, unknown>)._materializedFrom as { mvName?: string } | undefined\n if (stampedBy?.mvName !== reg.spec.name) continue\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (await (outputColl as any)._internalDelete(id, txCtx)) {\n deleted++\n } else {\n // #782 part b — decoded AND stamp-owned, but erasure declined (#718 tier-elevation\n // gate). Ownership IS confirmed — a real silent survival, not a legit stamp-mismatch\n // skip. Surface it too, in its own channel (#785 — distinct from the decode-null case).\n residueDeclined.push(id)\n }\n }\n\n // `mode: 'manual'` gets the purge only (erasure wins, no auto-recompute promise);\n // `'lazy'` also marks + persists ITS OWN stale bit for cold-session recompute. No\n // sibling MV on the same output collection is touched here — the stamp-scoped\n // deletion above never erased sibling rows in the first place (#736 re-review).\n if (mode === 'lazy') {\n const registry = accessor.registry()\n markMVStale(registry, reg.spec.name)\n await writeMVStaleMarker(adapter, vault, reg.spec.name)\n }\n return { deleted, residueUndecodable, residueDeclined }\n}\n\n/**\n * Called from `Collection.get` (and any reader that materializes the\n * MV's output collection). If any MV producing `outputCollection` is\n * flagged stale, runs the executor against the live source state\n * before returning. No-op when there is no pending work — keeps the\n * read fast path negligible.\n *\n * `dispatchCtx` (#641): threaded from the calling `Collection`'s\n * `#dispatchCtx({ collection: outputCollection, id: 'resolve-on-read' })` — a read has no\n * real \"reacting write\" record, so `'resolve-on-read'` is the sentinel id, mirroring\n * `Vault.refreshView()`'s `'refreshView'` sentinel for the same reason. Passed straight\n * through to the executor so a stale row whose output lands in a closed period follows the\n * frozen-output rule (skip + `derivation:skipped-frozen`, #637) instead of throwing\n * `PeriodClosedError` out of a read.\n *\n * Dynamic-imports the executor only when a stale flag actually fires\n * (the floor-bundle isolation pattern v1 derivations established in\n * floor-bundle isolation pattern).\n */\nexport async function resolveStaleMVOnRead(\n accessor: MVStaleAccessor,\n outputCollection: string,\n dispatchCtx?: PutDerivedOutputCtx,\n): Promise<void> {\n const registry = accessor.registry()\n // Cold session: the in-memory WeakMap has no entry for this (freshly\n // constructed) registry yet — fold any persisted `_mv_stale` markers in\n // before reading the pending set, once per registry (#736). Memoize the\n // PROMISE, not a boolean: a concurrent first read arriving while the\n // hydrate is still awaiting `adapter.list` must await the SAME promise —\n // otherwise it observes \"already hydrating\", skips straight to an empty\n // pending set, and serves the purged/stale view as fresh (#736\n // whole-branch review, hydrate-once race). On rejection, evict the entry\n // BEFORE rethrowing — a cached rejected promise would otherwise poison the\n // MV read surface for the rest of the session (every later read re-awaits\n // the same rejection instead of retrying the store call) (#736 re-review).\n let hydrate = _hydratedByRegistry.get(registry)\n if (!hydrate) {\n hydrate = hydratePersistedStaleMarkers(accessor, registry).catch((err: unknown) => {\n _hydratedByRegistry.delete(registry)\n throw err\n })\n _hydratedByRegistry.set(registry, hydrate)\n }\n await hydrate\n const pending = _staleByRegistry.get(registry)\n if (!pending || pending.size === 0) return\n\n const { adapter, vault } = storeOf(accessor, outputCollection)\n\n // Clean up persisted markers for MV names no longer registered (renamed or\n // removed since the marker was written). Without this sweep an orphaned name\n // can never become a `candidate` below — `candidates` is built from\n // `registry.all()`, which no longer lists it — so both the in-memory pending\n // entry and the persisted `_mv_stale` row would linger forever, re-hydrating\n // on every cold session (#736 whole-branch review).\n for (const name of pending) {\n if (registry.byName(name)) continue\n pending.delete(name)\n await deleteMVStaleMarker(adapter, vault, name)\n }\n if (pending.size === 0) return\n\n // Find every MV that writes to this output collection AND is\n // currently flagged stale. Multiple MVs CAN share an output\n // collection in theory; in practice the registration validation +\n // cycle detection make this unusual.\n const candidates: string[] = []\n for (const mv of registry.all()) {\n if (mv.outputCollection !== outputCollection) continue\n if (!pending.has(mv.spec.name)) continue\n candidates.push(mv.spec.name)\n }\n if (candidates.length === 0) return\n\n let executor: typeof MVExecutorType | null = null\n for (const name of candidates) {\n const reg = registry.byName(name)\n if (!reg) {\n // Unreachable in practice — `candidates` is drawn from `registry.all()`,\n // and the orphan sweep above already cleared any name absent from it.\n // Kept as a defensive fallback; also clears the persisted marker so it\n // can't linger if this ever does fire.\n pending.delete(name)\n await deleteMVStaleMarker(adapter, vault, name)\n continue\n }\n executor ??= (await loadMVExecutor()).MaterializedViewExecutor\n // A cold-hydrated stale flag (unlike an in-session one) can fire with\n // NONE of the MV's dependency collections touched yet this session —\n // the sync `Query.toArray()` `spec.query()` runs reads straight off\n // `Collection`'s in-memory cache, populated only by a prior async\n // touch (`ensureHydrated()`, called from `get`/`list`/`put`, never\n // from `query()` itself). Warm every dependency first so the recompute\n // sees the live persisted state instead of an empty cache (#736).\n for (const dep of reg.dependencies) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await (accessor.getCollection(dep) as any).ensureHydrated()\n }\n await executor.refresh(reg, {\n getCollection: (n) => accessor.getCollection(n),\n getActiveTxContext: () => accessor.getActiveTxContext(),\n getQueryContext: () => accessor.getQueryContext(),\n ...(dispatchCtx !== undefined ? { dispatchCtx } : {}),\n })\n pending.delete(name)\n // Runs even when no marker was ever persisted for this name (an in-session-only\n // stale bit — e.g. the cheap ordinary-write path never writes one, see the\n // \"cheap-path guarantee\" test). `adapter.delete` on an absent key is a harmless\n // void — keeping this unconditional avoids branching on marker origin here.\n await deleteMVStaleMarker(adapter, vault, name)\n }\n}\n\n/**\n * Drop every stale flag for a registry. Used after a manual\n * `vault.refreshView(name)` runs the executor explicitly — the\n * post-refresh state matches the registered strategies, so\n * lingering stale bits would force a redundant refresh on the next\n * read.\n *\n * @internal\n */\nexport function clearMVStale(registry: MaterializedViewRegistry, mvName: string): void {\n _staleByRegistry.get(registry)?.delete(mvName)\n}\n\n/**\n * `clearMVStale` plus the persisted marker (#736) — `Vault.refreshView()`'s\n * completion path. A lingering persisted marker after a manual refresh would\n * make the NEXT cold session recompute redundantly.\n *\n * @internal\n */\nexport async function clearMVStaleFully(\n adapter: NoydbStore,\n vault: string,\n registry: MaterializedViewRegistry,\n mvName: string,\n): Promise<void> {\n clearMVStale(registry, mvName)\n await deleteMVStaleMarker(adapter, vault, mvName)\n}\n"],"mappings":"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","names":[]}
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  FieldNotQueryableError,
7
7
  IndexRequiredError
8
- } from "./chunk-HNGSV2YC.js";
8
+ } from "./chunk-CWM4GQD2.js";
9
9
 
10
10
  // src/with-lookup/indexing/strategy.ts
11
11
  var NO_INDEXING = {
@@ -534,4 +534,4 @@ export {
534
534
  PersistedCollectionIndex,
535
535
  LazyQuery
536
536
  };
537
- //# sourceMappingURL=chunk-JIUVJ4M7.js.map
537
+ //# sourceMappingURL=chunk-EKEIEJL6.js.map