@noy-db/hub 0.6.0-pre.9 → 0.7.0-pre.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (572) hide show
  1. package/CHANGELOG.md +7127 -0
  2. package/README.md +1 -1
  3. package/codemods/0.4.0-pre.json +24 -0
  4. package/codemods/0.6.0-pre.json +229 -0
  5. package/codemods/0.7.0-pre.json +258 -0
  6. package/dist/api-EQYRTZO2.js +20 -0
  7. package/dist/as/index.js +146 -0
  8. package/dist/as/index.js.map +1 -0
  9. package/dist/at/index.js +23 -0
  10. package/dist/attestation/index.js +19 -19
  11. package/dist/{backup-KULFZ2T4.js → backup-Z7ZBTAQ6.js} +36 -18
  12. package/dist/backup-Z7ZBTAQ6.js.map +1 -0
  13. package/dist/blobs/index.js +22 -20
  14. package/dist/blobs/index.js.map +1 -1
  15. package/dist/broker/index.js +12 -12
  16. package/dist/by/index.js +11 -0
  17. package/dist/cargo/index.js +40 -36
  18. package/dist/{chunk-YAWK6AWF.js → chunk-225O5CXQ.js} +2 -2
  19. package/dist/{chunk-MSWYQLMQ.js → chunk-2GXEQUEX.js} +2 -2
  20. package/dist/chunk-2GXEQUEX.js.map +1 -0
  21. package/dist/{chunk-3URQC7EH.js → chunk-2LPVI4PX.js} +355 -132
  22. package/dist/chunk-2LPVI4PX.js.map +1 -0
  23. package/dist/{chunk-JJNOLSG5.js → chunk-3L2MVE36.js} +15 -16
  24. package/dist/chunk-3L2MVE36.js.map +1 -0
  25. package/dist/{chunk-OF3L2SD6.js → chunk-3QARDAYW.js} +2 -2
  26. package/dist/{chunk-WLZ47GSL.js → chunk-467SKJ65.js} +12 -10
  27. package/dist/{chunk-WLZ47GSL.js.map → chunk-467SKJ65.js.map} +1 -1
  28. package/dist/{chunk-W3TVWF6N.js → chunk-4A4TYISP.js} +2 -2
  29. package/dist/{chunk-ZJADGNYF.js → chunk-4AOERLTV.js} +1 -1
  30. package/dist/chunk-4AOERLTV.js.map +1 -0
  31. package/dist/{chunk-CCZJJ4I2.js → chunk-4G25SDQL.js} +6 -6
  32. package/dist/{chunk-4I72F5DF.js → chunk-4LPF226H.js} +11 -14
  33. package/dist/chunk-4LPF226H.js.map +1 -0
  34. package/dist/{chunk-7F4DBNSP.js → chunk-4ZPE6SKS.js} +135 -18
  35. package/dist/chunk-4ZPE6SKS.js.map +1 -0
  36. package/dist/{chunk-7TSYBD3E.js → chunk-5263OEM3.js} +2 -2
  37. package/dist/{chunk-WFUIE565.js → chunk-57JTHWLQ.js} +17 -14
  38. package/dist/chunk-57JTHWLQ.js.map +1 -0
  39. package/dist/{chunk-FNSMZQS4.js → chunk-5ACAVJUI.js} +2 -2
  40. package/dist/{chunk-PDLLCOGD.js → chunk-5AFMP532.js} +20 -17
  41. package/dist/chunk-5AFMP532.js.map +1 -0
  42. package/dist/{chunk-JRKZTEZZ.js → chunk-5W7YXFV5.js} +444 -73
  43. package/dist/chunk-5W7YXFV5.js.map +1 -0
  44. package/dist/chunk-6EW2UCVF.js +190 -0
  45. package/dist/chunk-6EW2UCVF.js.map +1 -0
  46. package/dist/{chunk-4VUPLMZ6.js → chunk-6FOGTKBY.js} +68 -73
  47. package/dist/chunk-6FOGTKBY.js.map +1 -0
  48. package/dist/{chunk-VMCCGUQB.js → chunk-7LYUJNU3.js} +2 -2
  49. package/dist/{chunk-52JPHN5N.js → chunk-A2YW5EMU.js} +27 -149
  50. package/dist/chunk-A2YW5EMU.js.map +1 -0
  51. package/dist/{chunk-WLYIROCJ.js → chunk-AB5P32RE.js} +2 -2
  52. package/dist/{chunk-PL2GHSCM.js → chunk-ALB64CZM.js} +157 -90
  53. package/dist/chunk-ALB64CZM.js.map +1 -0
  54. package/dist/{chunk-SUFG5E73.js → chunk-ALUNQEBY.js} +2 -2
  55. package/dist/{chunk-CADUYBQD.js → chunk-ATL3ZVXT.js} +2 -2
  56. package/dist/{chunk-BWVKEOPE.js → chunk-ATV637J7.js} +7 -11
  57. package/dist/chunk-ATV637J7.js.map +1 -0
  58. package/dist/{chunk-DG27IUVI.js → chunk-CBRS2NEK.js} +2 -11
  59. package/dist/chunk-CBRS2NEK.js.map +1 -0
  60. package/dist/{chunk-7MNBICB5.js → chunk-CN6B5PEN.js} +16 -14
  61. package/dist/chunk-CN6B5PEN.js.map +1 -0
  62. package/dist/{chunk-6FJWSWFT.js → chunk-DBNYPLWY.js} +3 -3
  63. package/dist/{chunk-5JY5TSVY.js → chunk-DFAUMLD7.js} +25 -31
  64. package/dist/chunk-DFAUMLD7.js.map +1 -0
  65. package/dist/{chunk-FFDNKRCY.js → chunk-DKWPJOYH.js} +2 -2
  66. package/dist/chunk-DKWPJOYH.js.map +1 -0
  67. package/dist/{chunk-VJFMXYKP.js → chunk-E6YA6UAP.js} +2 -2
  68. package/dist/{chunk-WASHZV34.js → chunk-F23WQK3G.js} +65 -27
  69. package/dist/chunk-F23WQK3G.js.map +1 -0
  70. package/dist/{chunk-JIUVJ4M7.js → chunk-F7ZFRPGQ.js} +3 -3
  71. package/dist/{chunk-HXGUIPQB.js → chunk-FOG7YEJP.js} +3 -3
  72. package/dist/{chunk-QULVCV3M.js → chunk-GK4DRVUD.js} +6 -6
  73. package/dist/chunk-GK4DRVUD.js.map +1 -0
  74. package/dist/{chunk-BRVW2GS5.js → chunk-H36KSN6X.js} +87 -34
  75. package/dist/chunk-H36KSN6X.js.map +1 -0
  76. package/dist/{chunk-O2ERS4UJ.js → chunk-H4M7ADXY.js} +81 -52
  77. package/dist/chunk-H4M7ADXY.js.map +1 -0
  78. package/dist/{chunk-FZ6NYJ7L.js → chunk-H7HP56F6.js} +11 -8
  79. package/dist/chunk-H7HP56F6.js.map +1 -0
  80. package/dist/chunk-HK67PX4J.js +27 -0
  81. package/dist/chunk-HK67PX4J.js.map +1 -0
  82. package/dist/{chunk-X56RTUK3.js → chunk-HM4JSXX2.js} +3 -3
  83. package/dist/{chunk-AHLJSVRL.js → chunk-HTGRQZFB.js} +5 -7
  84. package/dist/chunk-HTGRQZFB.js.map +1 -0
  85. package/dist/{chunk-GQ3BX5EA.js → chunk-I3ISCYT7.js} +2 -2
  86. package/dist/{chunk-Q6TEJXBX.js → chunk-IESNYJXZ.js} +31 -49
  87. package/dist/chunk-IESNYJXZ.js.map +1 -0
  88. package/dist/{chunk-FUHKW252.js → chunk-J4MN6XIU.js} +2 -2
  89. package/dist/{chunk-ADW22QSB.js → chunk-J4UJ5FRV.js} +4 -4
  90. package/dist/{chunk-HNGSV2YC.js → chunk-JBIV4FLR.js} +67 -10
  91. package/dist/chunk-JBIV4FLR.js.map +1 -0
  92. package/dist/{chunk-HVQGCKY4.js → chunk-JVLSU7S2.js} +2 -2
  93. package/dist/{chunk-AR2JDFAE.js → chunk-KDJGJR7F.js} +2 -2
  94. package/dist/{chunk-NPP5R7FF.js → chunk-KN4W2OQ4.js} +22 -18
  95. package/dist/chunk-KN4W2OQ4.js.map +1 -0
  96. package/dist/{chunk-G6S5VVHP.js → chunk-L6GTLZRK.js} +10 -10
  97. package/dist/chunk-L6GTLZRK.js.map +1 -0
  98. package/dist/{chunk-2BMRJ6LQ.js → chunk-LF6DMX4C.js} +8 -11
  99. package/dist/{chunk-2BMRJ6LQ.js.map → chunk-LF6DMX4C.js.map} +1 -1
  100. package/dist/chunk-LFUID7OW.js +163 -0
  101. package/dist/chunk-LFUID7OW.js.map +1 -0
  102. package/dist/{chunk-747LRSOO.js → chunk-LKFKXS5K.js} +2 -2
  103. package/dist/{chunk-U5O6GIWZ.js → chunk-LR4Z47QD.js} +3 -3
  104. package/dist/{chunk-VZ3XFUQ7.js → chunk-MTBXJAS4.js} +16 -22
  105. package/dist/chunk-MTBXJAS4.js.map +1 -0
  106. package/dist/chunk-N4CNVSUF.js +66 -0
  107. package/dist/chunk-N4CNVSUF.js.map +1 -0
  108. package/dist/{chunk-RTAMLDWP.js → chunk-NLKLXXTO.js} +2 -2
  109. package/dist/{chunk-IGJCYUT5.js → chunk-NSITFOCJ.js} +1 -1
  110. package/dist/chunk-NSITFOCJ.js.map +1 -0
  111. package/dist/{chunk-FDX7OWWI.js → chunk-OPXR4PB2.js} +2 -2
  112. package/dist/{chunk-4GZ6XOVW.js → chunk-OWLVBOWO.js} +44 -42
  113. package/dist/chunk-OWLVBOWO.js.map +1 -0
  114. package/dist/{chunk-Z45YRGFO.js → chunk-P6ASQOZR.js} +2 -2
  115. package/dist/{chunk-5O5HRRTV.js → chunk-PCQDY6QN.js} +7 -7
  116. package/dist/{chunk-5O5HRRTV.js.map → chunk-PCQDY6QN.js.map} +1 -1
  117. package/dist/{chunk-BEFVYAR5.js → chunk-PGFKIOR3.js} +4 -4
  118. package/dist/chunk-PGFKIOR3.js.map +1 -0
  119. package/dist/{chunk-3FSX6LDG.js → chunk-POS53FG6.js} +18 -3
  120. package/dist/{chunk-3FSX6LDG.js.map → chunk-POS53FG6.js.map} +1 -1
  121. package/dist/{chunk-3IXIU6FP.js → chunk-PQ6Z2TAP.js} +7 -10
  122. package/dist/chunk-PQ6Z2TAP.js.map +1 -0
  123. package/dist/{chunk-CEJWMBXO.js → chunk-PUJTKLPL.js} +6 -2
  124. package/dist/chunk-PUJTKLPL.js.map +1 -0
  125. package/dist/{chunk-GAG7QOVO.js → chunk-QGJ4XIA7.js} +53 -18
  126. package/dist/chunk-QGJ4XIA7.js.map +1 -0
  127. package/dist/{chunk-2DHSSLOD.js → chunk-QHJKK77B.js} +13 -15
  128. package/dist/chunk-QHJKK77B.js.map +1 -0
  129. package/dist/{chunk-2Z3NCLNX.js → chunk-QI5NWLVW.js} +7 -7
  130. package/dist/{chunk-6SAFL5YE.js → chunk-RC4BROYR.js} +3 -3
  131. package/dist/{chunk-NJDQ4YSV.js → chunk-RDHUZ674.js} +4 -4
  132. package/dist/{chunk-YPYHVOXP.js → chunk-RK7N4OQ5.js} +2 -2
  133. package/dist/chunk-RK7N4OQ5.js.map +1 -0
  134. package/dist/{chunk-3737A6EA.js → chunk-S2VG3ABP.js} +127 -31
  135. package/dist/chunk-S2VG3ABP.js.map +1 -0
  136. package/dist/{chunk-3JVXVJ7L.js → chunk-S35S77YU.js} +10 -10
  137. package/dist/{chunk-KUDZVJKQ.js → chunk-SHILAQH5.js} +2 -2
  138. package/dist/{chunk-4UVDI4XE.js → chunk-T3PHCEN4.js} +4 -4
  139. package/dist/{chunk-55LKVALY.js → chunk-T7IR4N2S.js} +1 -3
  140. package/dist/chunk-T7IR4N2S.js.map +1 -0
  141. package/dist/{chunk-RXYYFSBB.js → chunk-TOV6VMHF.js} +6 -6
  142. package/dist/chunk-TOV6VMHF.js.map +1 -0
  143. package/dist/{chunk-W77KZHCW.js → chunk-TVIFAHZR.js} +16 -17
  144. package/dist/chunk-TVIFAHZR.js.map +1 -0
  145. package/dist/chunk-UBSFPGVJ.js +1 -0
  146. package/dist/{chunk-FAXZQ5UF.js → chunk-UCUALOSM.js} +2 -2
  147. package/dist/{chunk-4HDYQL3J.js → chunk-VAG47QHV.js} +2 -2
  148. package/dist/{chunk-35EBKWQU.js → chunk-VFIWDPXZ.js} +4 -4
  149. package/dist/{chunk-5ZKS6ZE2.js → chunk-VTG7327U.js} +4 -4
  150. package/dist/chunk-VTG7327U.js.map +1 -0
  151. package/dist/{chunk-VCETL77O.js → chunk-W5LHQXZU.js} +36 -7
  152. package/dist/chunk-W5LHQXZU.js.map +1 -0
  153. package/dist/{chunk-6NVPFKN3.js → chunk-WK5FSW7T.js} +92 -35
  154. package/dist/chunk-WK5FSW7T.js.map +1 -0
  155. package/dist/{chunk-HNHCQ556.js → chunk-WLLUM35R.js} +2 -2
  156. package/dist/{chunk-YJ6IONGA.js → chunk-X62MEF2O.js} +13 -5
  157. package/dist/chunk-X62MEF2O.js.map +1 -0
  158. package/dist/{chunk-7G6VDWXB.js → chunk-X67FCULK.js} +5 -5
  159. package/dist/chunk-X67FCULK.js.map +1 -0
  160. package/dist/{chunk-UHXCLPGC.js → chunk-XDVVBETV.js} +2 -2
  161. package/dist/chunk-XDVVBETV.js.map +1 -0
  162. package/dist/chunk-XJ3FEKEY.js +15 -0
  163. package/dist/chunk-XJ3FEKEY.js.map +1 -0
  164. package/dist/{chunk-E6427JU2.js → chunk-XSN63FUS.js} +19 -3
  165. package/dist/chunk-XSN63FUS.js.map +1 -0
  166. package/dist/{chunk-JRCYZEHU.js → chunk-XVU7J43V.js} +2 -2
  167. package/dist/{chunk-2GAJGUNM.js → chunk-Y3YLJORD.js} +408 -260
  168. package/dist/chunk-Y3YLJORD.js.map +1 -0
  169. package/dist/{chunk-6BU3L4UE.js → chunk-Y6GZ2P4M.js} +7 -10
  170. package/dist/chunk-Y6GZ2P4M.js.map +1 -0
  171. package/dist/{chunk-DMQCLZ4Z.js → chunk-YCSM3GZU.js} +2 -2
  172. package/dist/{chunk-RV3ARMPN.js → chunk-YKPGQJFU.js} +30 -180
  173. package/dist/chunk-YKPGQJFU.js.map +1 -0
  174. package/dist/{chunk-FMQJZH4R.js → chunk-YMLQBZFJ.js} +6 -6
  175. package/dist/{chunk-6HFM7EIT.js → chunk-YPSOHDNC.js} +2 -2
  176. package/dist/{chunk-CDB2HVQW.js → chunk-YXA2TCTZ.js} +14 -15
  177. package/dist/chunk-YXA2TCTZ.js.map +1 -0
  178. package/dist/{chunk-N35NC4JH.js → chunk-Z2PWOSCJ.js} +2 -2
  179. package/dist/{chunk-XWX7GL56.js → chunk-Z2WK53N6.js} +47 -23
  180. package/dist/chunk-Z2WK53N6.js.map +1 -0
  181. package/dist/{chunk-HPLWFNG4.js → chunk-Z7ZXZL6Y.js} +2 -2
  182. package/dist/{chunk-PNKHAKQ7.js → chunk-ZO252Q5S.js} +17 -10
  183. package/dist/chunk-ZO252Q5S.js.map +1 -0
  184. package/dist/classified/index.js +5 -5
  185. package/dist/{classified-marker-2KJAXRRO.js → classified-marker-BSQHU4JT.js} +3 -3
  186. package/dist/collection-facade-LG3NYZVB.js +45 -0
  187. package/dist/{computed-6G5M3UPH.js → computed-ASBNTLOK.js} +3 -3
  188. package/dist/consent/index.js +10 -10
  189. package/dist/cover/index.js +10 -3
  190. package/dist/custody/index.js +12 -11
  191. package/dist/{dead-filter-DCB62VWW.js → dead-filter-QKU56XTQ.js} +2 -2
  192. package/dist/debug/index.js +1 -1
  193. package/dist/{delegation-MO7YZYJS.js → delegation-XWRPYODW.js} +24 -23
  194. package/dist/delegation-XWRPYODW.js.map +1 -0
  195. package/dist/derivations/index.js +12 -12
  196. package/dist/derive-CXHCY46K.js +22 -0
  197. package/dist/directory/index.js +10 -10
  198. package/dist/{dispatch-MJ6SHB3Y.js → dispatch-4AP4PUZU.js} +18 -18
  199. package/dist/{dispatch-FZEAWKVM.js → dispatch-VR4LRXZ7.js} +9 -6
  200. package/dist/dispatch-VR4LRXZ7.js.map +1 -0
  201. package/dist/{enclave-JU4YIEPB.js → enclave-NYPT7WA7.js} +31 -9
  202. package/dist/executor-3KFRQETS.js +29 -0
  203. package/dist/executor-AFHQYRAU.js +9 -0
  204. package/dist/executor-YYDW6XQI.js +9 -0
  205. package/dist/export-accessible-BX2ILB4C.js +23 -0
  206. package/dist/extract-partition-UPOVITFI.js +38 -0
  207. package/dist/{fanout-sidecar-NNAJQXMX.js → fanout-sidecar-IWP3R4RC.js} +18 -27
  208. package/dist/fanout-sidecar-IWP3R4RC.js.map +1 -0
  209. package/dist/{fence-watcher-DHQ775JB.js → fence-watcher-ZVSMLKQD.js} +1 -1
  210. package/dist/fence-watcher-ZVSMLKQD.js.map +1 -0
  211. package/dist/find-SZBL2HPB.js +11 -0
  212. package/dist/forget/index.js +9 -9
  213. package/dist/guards/index.js +4 -4
  214. package/dist/history/index.js +23 -20
  215. package/dist/history/index.js.map +1 -1
  216. package/dist/i18n/index.js +14 -14
  217. package/dist/index.d.ts +35 -18
  218. package/dist/index.js +199 -204
  219. package/dist/index.js.map +1 -1
  220. package/dist/indexing/index.js +4 -4
  221. package/dist/introspection/index.js +12 -11
  222. package/dist/issue-G53NB6EW.js +19 -0
  223. package/dist/kernel/collection-config.d.ts +9 -9
  224. package/dist/kernel/collection.d.ts +9 -3
  225. package/dist/kernel/constants.d.ts +36 -0
  226. package/dist/kernel/enclave/crypto.d.ts +52 -4
  227. package/dist/kernel/enclave/index.d.ts +10 -3
  228. package/dist/kernel/enclave/record-aad.d.ts +131 -0
  229. package/dist/kernel/enclave/record-envelope.d.ts +76 -0
  230. package/dist/kernel/enclave/record-keys/envelope-body.d.ts +34 -2
  231. package/dist/kernel/enclave/record-keys/lifecycle.d.ts +22 -5
  232. package/dist/kernel/enclave/record-keys/record-codec.d.ts +47 -14
  233. package/dist/kernel/enclave/record-keys/rekey-blob.d.ts +88 -0
  234. package/dist/kernel/enclave/record-keys/rekey.d.ts +91 -0
  235. package/dist/kernel/enclave/record-keys/tombstone.d.ts +3 -2
  236. package/dist/kernel/errors.d.ts +134 -14
  237. package/dist/kernel/merge-authority.d.ts +25 -0
  238. package/dist/kernel/noydb.d.ts +33 -10
  239. package/dist/kernel/query/builder.d.ts +51 -4
  240. package/dist/kernel/query/join.d.ts +27 -0
  241. package/dist/kernel/query/live.d.ts +31 -9
  242. package/dist/kernel/query/predicate.d.ts +9 -0
  243. package/dist/kernel/refs.d.ts +3 -1
  244. package/dist/kernel/secret-mode.d.ts +1 -1
  245. package/dist/kernel/sync-policy.d.ts +0 -2
  246. package/dist/kernel/tier-visibility.d.ts +34 -0
  247. package/dist/kernel/types.d.ts +145 -28
  248. package/dist/kernel/vault.d.ts +16 -7
  249. package/dist/kernel/via/compose.d.ts +3 -3
  250. package/dist/kernel/via/index.d.ts +15 -6
  251. package/dist/kernel/via/pipeline.d.ts +6 -6
  252. package/dist/kernel/via/reconcile.d.ts +14 -2
  253. package/dist/kernel/via/taint-binding.d.ts +3 -3
  254. package/dist/{ledger-AETNF4OM.js → ledger-T5K4P2D7.js} +11 -11
  255. package/dist/liberate-VEOZRESE.js +25 -0
  256. package/dist/{link-set-E5HNY67I.js → link-set-76JZ6YB4.js} +11 -11
  257. package/dist/{managed-secret-CWQ6PND5.js → managed-secret-6YC32VXG.js} +13 -5
  258. package/dist/materialized-views/index.js +27 -27
  259. package/dist/migrate-cek-LBRKYUZZ.js +19 -0
  260. package/dist/migrate-cek-LBRKYUZZ.js.map +1 -0
  261. package/dist/money/index.js +5 -5
  262. package/dist/noydb-EDJA4JNJ.js +86 -0
  263. package/dist/on/index.js +1 -0
  264. package/dist/overlay-views/index.js +4 -4
  265. package/dist/periods/index.js +12 -12
  266. package/dist/pod/index.js +79 -88
  267. package/dist/pod-handle-P6DPBM5U.js +41 -0
  268. package/dist/pod-handle-P6DPBM5U.js.map +1 -0
  269. package/dist/policy/index.js +11 -4
  270. package/dist/port/as/active.d.ts +10 -0
  271. package/dist/port/as/index.d.ts +32 -0
  272. package/dist/port/as/types.d.ts +113 -0
  273. package/dist/port/at/index.d.ts +37 -0
  274. package/dist/port/by/default-provider.d.ts +3 -3
  275. package/dist/port/by/index.d.ts +32 -10
  276. package/dist/port/by/types.d.ts +29 -11
  277. package/dist/port/on/index.d.ts +50 -0
  278. package/dist/port/to/index.d.ts +4 -4
  279. package/dist/port/to/locator.d.ts +54 -8
  280. package/dist/port/with/computed-strategy.d.ts +1 -1
  281. package/dist/port/with/device-seal-strategy.d.ts +2 -2
  282. package/dist/port/with/formats-strategy.d.ts +76 -0
  283. package/dist/port/with/i18n-strategy.d.ts +4 -1
  284. package/dist/port/with/lookup-strategy.d.ts +4 -1
  285. package/dist/port/with/merge-authority.d.ts +52 -0
  286. package/dist/port/with/service-bus.d.ts +0 -4
  287. package/dist/port/with/strategies.d.ts +13 -5
  288. package/dist/port/with/team-strategy.d.ts +5 -1
  289. package/dist/portability/index.js +8 -8
  290. package/dist/{post-register-2XSSMGEQ.js → post-register-53O7AJRZ.js} +6 -6
  291. package/dist/query/index.js +6 -6
  292. package/dist/reduce/index.js +6 -6
  293. package/dist/register-6TCBR6XD.js +32 -0
  294. package/dist/registry-DH2L4O2V.js +18 -0
  295. package/dist/registry-IWFMXCHX.js +9 -0
  296. package/dist/registry-Q3FG3OAX.js +9 -0
  297. package/dist/registry-YC3IFG3A.js +19 -0
  298. package/dist/request-withdrawal-NM5VYR6F.js +31 -0
  299. package/dist/{reveal-BW36KCOQ.js → reveal-XBIMHAXR.js} +6 -6
  300. package/dist/revoke-MJNYWO72.js +24 -0
  301. package/dist/satellites/index.js +1 -1
  302. package/dist/schema-update/index.js +2 -2
  303. package/dist/sealed-record/index.js +20 -13
  304. package/dist/sealed-record/index.js.map +1 -1
  305. package/dist/search/index.js +4 -4
  306. package/dist/{seed-GDV5PT4R.js → seed-NSNIGYXE.js} +20 -22
  307. package/dist/seed-NSNIGYXE.js.map +1 -0
  308. package/dist/sequence/index.js +9 -9
  309. package/dist/session/index.js +10 -10
  310. package/dist/shadow/index.js +2 -2
  311. package/dist/share-link/index.js +1 -1
  312. package/dist/signer-6XVS2AU3.js +25 -0
  313. package/dist/snapshots/index.js +10 -10
  314. package/dist/snapshots/index.js.map +1 -1
  315. package/dist/{stale-ARHFVL5U.js → stale-MCS46TFO.js} +10 -10
  316. package/dist/storage-ZXUT476I.js +23 -0
  317. package/dist/storage-ZXUT476I.js.map +1 -0
  318. package/dist/{store-coordination-provider-GFCUOBR6.js → store-coordination-provider-6FM26VQM.js} +22 -15
  319. package/dist/store-coordination-provider-6FM26VQM.js.map +1 -0
  320. package/dist/sync/index.js +11 -11
  321. package/dist/team/index.js +17 -16
  322. package/dist/tiers/index.js +11 -10
  323. package/dist/to/index.js +17 -9
  324. package/dist/to/index.js.map +1 -1
  325. package/dist/transactions/index.js +4 -4
  326. package/dist/{ulid-PTAIMDG4.js → ulid-VQW6ERQN.js} +2 -2
  327. package/dist/ulid-VQW6ERQN.js.map +1 -0
  328. package/dist/util/index.js +1 -1
  329. package/dist/vault-diff-FE5J35NJ.js +9 -0
  330. package/dist/vault-diff-FE5J35NJ.js.map +1 -0
  331. package/dist/vault-head/index.js +115 -0
  332. package/dist/vault-head/index.js.map +1 -0
  333. package/dist/{verify-RO5RTZOJ.js → verify-WYOFLSNA.js} +5 -5
  334. package/dist/via/blob/binding.d.ts +6 -6
  335. package/dist/via/blob/index.d.ts +3 -0
  336. package/dist/via/classified/binding.d.ts +9 -9
  337. package/dist/via/computed/binding.d.ts +2 -2
  338. package/dist/via/i18n/binding.d.ts +4 -4
  339. package/dist/via/lookup/binding.d.ts +5 -5
  340. package/dist/via/lookup/handle.d.ts +4 -1
  341. package/dist/via/lookup/index.d.ts +1 -1
  342. package/dist/via/lookup/snapshot.d.ts +1 -1
  343. package/dist/via/money/binding.d.ts +3 -3
  344. package/dist/via/money/normalize.d.ts +1 -1
  345. package/dist/via/money/where.d.ts +3 -3
  346. package/dist/walk-JNEOYCAU.js +21 -0
  347. package/dist/walk-JNEOYCAU.js.map +1 -0
  348. package/dist/with-audit/periods/periods.d.ts +1 -1
  349. package/dist/with-audit/periods/strategy.d.ts +1 -1
  350. package/dist/with-audit/sealed-record/index.d.ts +13 -0
  351. package/dist/with-audit/tiers/index.d.ts +17 -2
  352. package/dist/with-cargo/adopt-partition.d.ts +7 -7
  353. package/dist/with-cargo/extract-partition.d.ts +1 -1
  354. package/dist/with-cargo/floor.d.ts +1 -1
  355. package/dist/with-cargo/index.d.ts +2 -2
  356. package/dist/with-commit/history/history.d.ts +26 -0
  357. package/dist/with-commit/history/index.d.ts +2 -1
  358. package/dist/with-commit/history/ledger/store.d.ts +7 -1
  359. package/dist/with-commit/history/strategy.d.ts +11 -1
  360. package/dist/with-commit/numbering/index.d.ts +0 -5
  361. package/dist/with-commit/vault-head/active.d.ts +2 -0
  362. package/dist/with-commit/vault-head/head.d.ts +28 -0
  363. package/dist/with-commit/vault-head/index.d.ts +10 -0
  364. package/dist/with-commit/vault-head/strategy.d.ts +127 -0
  365. package/dist/with-commit/vault-head/verify.d.ts +90 -0
  366. package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +4 -0
  367. package/dist/with-formula/materialized-views/projection-legs.d.ts +59 -0
  368. package/dist/with-formula/materialized-views/registry.d.ts +50 -0
  369. package/dist/with-formula/materialized-views/types.d.ts +68 -10
  370. package/dist/with-party/directory/cover/storage.d.ts +0 -8
  371. package/dist/with-party/directory/storage.d.ts +0 -11
  372. package/dist/with-party/directory/visibility.d.ts +0 -21
  373. package/dist/with-party/policy/storage.d.ts +0 -10
  374. package/dist/with-party/team/deed.d.ts +4 -4
  375. package/dist/with-party/team/device-seal.d.ts +5 -5
  376. package/dist/with-party/team/echo-ceremony.d.ts +2 -2
  377. package/dist/with-party/team/echo-secret.d.ts +4 -4
  378. package/dist/with-party/team/index.d.ts +3 -3
  379. package/dist/with-party/team/keyring.d.ts +141 -4
  380. package/dist/with-party/team/managed-secret.d.ts +21 -11
  381. package/dist/with-party/team/noydb-facade.d.ts +7 -3
  382. package/dist/with-party/team/{shamir-recovery-provider.d.ts → noydb-shamir.d.ts} +1 -1
  383. package/dist/with-party/team/recovery.d.ts +3 -3
  384. package/dist/with-party/team/roster-tag.d.ts +101 -0
  385. package/dist/with-party/team/rotate-recover.d.ts +5 -5
  386. package/dist/with-party/team/tiers.d.ts +2 -1
  387. package/dist/with-pod/format.d.ts +11 -13
  388. package/dist/with-pod/index.d.ts +10 -10
  389. package/dist/with-pod/open.d.ts +2 -2
  390. package/dist/with-pod/pod-handle.d.ts +19 -0
  391. package/dist/with-pod/pod-store.d.ts +0 -8
  392. package/dist/with-pod/{bundle.d.ts → pod.d.ts} +17 -25
  393. package/dist/with-pod/ulid.d.ts +1 -1
  394. package/dist/with-shape/blobs/blob-compaction.d.ts +13 -0
  395. package/dist/with-shape/blobs/blob-set.d.ts +83 -11
  396. package/dist/with-shape/blobs/orphan-report.d.ts +62 -0
  397. package/dist/with-shape/introspection/describe.d.ts +2 -2
  398. package/dist/with-shape/schema-update/fence-controller.d.ts +4 -4
  399. package/dist/with-shape/schema-update/fence-watcher.d.ts +4 -4
  400. package/dist/with-shape/schema-update/store-coordination-provider.d.ts +7 -6
  401. package/dist/with-sync/engine.d.ts +54 -5
  402. package/dist/with-sync/strategy.d.ts +3 -0
  403. package/dist/withdraw-accessible-ILTSXTIE.js +28 -0
  404. package/dist/withdraw-accessible-ILTSXTIE.js.map +1 -0
  405. package/package.json +29 -5
  406. package/dist/api-RXUMEKT3.js +0 -20
  407. package/dist/backup-KULFZ2T4.js.map +0 -1
  408. package/dist/bundle-handle-GFNHT52M.js +0 -36
  409. package/dist/bundle-handle-GFNHT52M.js.map +0 -1
  410. package/dist/chunk-2DHSSLOD.js.map +0 -1
  411. package/dist/chunk-2GAJGUNM.js.map +0 -1
  412. package/dist/chunk-3737A6EA.js.map +0 -1
  413. package/dist/chunk-3IXIU6FP.js.map +0 -1
  414. package/dist/chunk-3URQC7EH.js.map +0 -1
  415. package/dist/chunk-4GZ6XOVW.js.map +0 -1
  416. package/dist/chunk-4I72F5DF.js.map +0 -1
  417. package/dist/chunk-4VUPLMZ6.js.map +0 -1
  418. package/dist/chunk-52JPHN5N.js.map +0 -1
  419. package/dist/chunk-55LKVALY.js.map +0 -1
  420. package/dist/chunk-5JY5TSVY.js.map +0 -1
  421. package/dist/chunk-5ZKS6ZE2.js.map +0 -1
  422. package/dist/chunk-6BU3L4UE.js.map +0 -1
  423. package/dist/chunk-6NVPFKN3.js.map +0 -1
  424. package/dist/chunk-7F4DBNSP.js.map +0 -1
  425. package/dist/chunk-7G6VDWXB.js.map +0 -1
  426. package/dist/chunk-7H73RIE3.js +0 -45
  427. package/dist/chunk-7H73RIE3.js.map +0 -1
  428. package/dist/chunk-7MNBICB5.js.map +0 -1
  429. package/dist/chunk-AFHQATY4.js +0 -47
  430. package/dist/chunk-AFHQATY4.js.map +0 -1
  431. package/dist/chunk-AHLJSVRL.js.map +0 -1
  432. package/dist/chunk-BEFVYAR5.js.map +0 -1
  433. package/dist/chunk-BRVW2GS5.js.map +0 -1
  434. package/dist/chunk-BWVKEOPE.js.map +0 -1
  435. package/dist/chunk-CDB2HVQW.js.map +0 -1
  436. package/dist/chunk-CEJWMBXO.js.map +0 -1
  437. package/dist/chunk-DG27IUVI.js.map +0 -1
  438. package/dist/chunk-E6427JU2.js.map +0 -1
  439. package/dist/chunk-FFDNKRCY.js.map +0 -1
  440. package/dist/chunk-FZ6NYJ7L.js.map +0 -1
  441. package/dist/chunk-G6S5VVHP.js.map +0 -1
  442. package/dist/chunk-GAG7QOVO.js.map +0 -1
  443. package/dist/chunk-HNGSV2YC.js.map +0 -1
  444. package/dist/chunk-IGJCYUT5.js.map +0 -1
  445. package/dist/chunk-JJNOLSG5.js.map +0 -1
  446. package/dist/chunk-JRKZTEZZ.js.map +0 -1
  447. package/dist/chunk-MSWYQLMQ.js.map +0 -1
  448. package/dist/chunk-NPP5R7FF.js.map +0 -1
  449. package/dist/chunk-O2ERS4UJ.js.map +0 -1
  450. package/dist/chunk-PDLLCOGD.js.map +0 -1
  451. package/dist/chunk-PL2GHSCM.js.map +0 -1
  452. package/dist/chunk-PNKHAKQ7.js.map +0 -1
  453. package/dist/chunk-Q6TEJXBX.js.map +0 -1
  454. package/dist/chunk-QULVCV3M.js.map +0 -1
  455. package/dist/chunk-RV3ARMPN.js.map +0 -1
  456. package/dist/chunk-RXYYFSBB.js.map +0 -1
  457. package/dist/chunk-UHXCLPGC.js.map +0 -1
  458. package/dist/chunk-VCETL77O.js.map +0 -1
  459. package/dist/chunk-VZ3XFUQ7.js.map +0 -1
  460. package/dist/chunk-W77KZHCW.js.map +0 -1
  461. package/dist/chunk-WASHZV34.js.map +0 -1
  462. package/dist/chunk-WFUIE565.js.map +0 -1
  463. package/dist/chunk-XWX7GL56.js.map +0 -1
  464. package/dist/chunk-YJ6IONGA.js.map +0 -1
  465. package/dist/chunk-YPYHVOXP.js.map +0 -1
  466. package/dist/chunk-ZJADGNYF.js.map +0 -1
  467. package/dist/collection-facade-QEJIM6BC.js +0 -45
  468. package/dist/delegation-MO7YZYJS.js.map +0 -1
  469. package/dist/derive-IUA6JFLB.js +0 -22
  470. package/dist/dispatch-FZEAWKVM.js.map +0 -1
  471. package/dist/executor-CYJQLKKI.js +0 -9
  472. package/dist/executor-S4QIKEHW.js +0 -9
  473. package/dist/executor-YIQB2S6N.js +0 -29
  474. package/dist/export-accessible-4S36PQNR.js +0 -23
  475. package/dist/extract-partition-IO7FDZ2P.js +0 -38
  476. package/dist/fanout-sidecar-NNAJQXMX.js.map +0 -1
  477. package/dist/fence-watcher-DHQ775JB.js.map +0 -1
  478. package/dist/find-RBBYKXI7.js +0 -11
  479. package/dist/issue-RIVHSY2S.js +0 -19
  480. package/dist/liberate-GFN4C7RR.js +0 -24
  481. package/dist/noydb-ASEXNJS6.js +0 -83
  482. package/dist/register-4EFJCVYD.js +0 -32
  483. package/dist/registry-4SDHHOJ7.js +0 -18
  484. package/dist/registry-CZVINVQH.js +0 -9
  485. package/dist/registry-IKUR2MXD.js +0 -9
  486. package/dist/registry-OYTFGWVK.js +0 -19
  487. package/dist/request-withdrawal-KGXGDPVQ.js +0 -31
  488. package/dist/revoke-JFN773KF.js +0 -24
  489. package/dist/seed-GDV5PT4R.js.map +0 -1
  490. package/dist/signer-TA55QB6R.js +0 -25
  491. package/dist/storage-V7MTFAQJ.js +0 -23
  492. package/dist/store-coordination-provider-GFCUOBR6.js.map +0 -1
  493. package/dist/walk-3ZECBFDA.js +0 -21
  494. package/dist/with-pod/bundle-handle.d.ts +0 -9
  495. package/dist/withdraw-accessible-7PG4DYQK.js +0 -28
  496. /package/dist/{api-RXUMEKT3.js.map → api-EQYRTZO2.js.map} +0 -0
  497. /package/dist/{collection-facade-QEJIM6BC.js.map → at/index.js.map} +0 -0
  498. /package/dist/{computed-6G5M3UPH.js.map → by/index.js.map} +0 -0
  499. /package/dist/{chunk-YAWK6AWF.js.map → chunk-225O5CXQ.js.map} +0 -0
  500. /package/dist/{chunk-OF3L2SD6.js.map → chunk-3QARDAYW.js.map} +0 -0
  501. /package/dist/{chunk-W3TVWF6N.js.map → chunk-4A4TYISP.js.map} +0 -0
  502. /package/dist/{chunk-CCZJJ4I2.js.map → chunk-4G25SDQL.js.map} +0 -0
  503. /package/dist/{chunk-7TSYBD3E.js.map → chunk-5263OEM3.js.map} +0 -0
  504. /package/dist/{chunk-FNSMZQS4.js.map → chunk-5ACAVJUI.js.map} +0 -0
  505. /package/dist/{chunk-VMCCGUQB.js.map → chunk-7LYUJNU3.js.map} +0 -0
  506. /package/dist/{chunk-WLYIROCJ.js.map → chunk-AB5P32RE.js.map} +0 -0
  507. /package/dist/{chunk-SUFG5E73.js.map → chunk-ALUNQEBY.js.map} +0 -0
  508. /package/dist/{chunk-CADUYBQD.js.map → chunk-ATL3ZVXT.js.map} +0 -0
  509. /package/dist/{chunk-6FJWSWFT.js.map → chunk-DBNYPLWY.js.map} +0 -0
  510. /package/dist/{chunk-VJFMXYKP.js.map → chunk-E6YA6UAP.js.map} +0 -0
  511. /package/dist/{chunk-JIUVJ4M7.js.map → chunk-F7ZFRPGQ.js.map} +0 -0
  512. /package/dist/{chunk-HXGUIPQB.js.map → chunk-FOG7YEJP.js.map} +0 -0
  513. /package/dist/{chunk-X56RTUK3.js.map → chunk-HM4JSXX2.js.map} +0 -0
  514. /package/dist/{chunk-GQ3BX5EA.js.map → chunk-I3ISCYT7.js.map} +0 -0
  515. /package/dist/{chunk-FUHKW252.js.map → chunk-J4MN6XIU.js.map} +0 -0
  516. /package/dist/{chunk-ADW22QSB.js.map → chunk-J4UJ5FRV.js.map} +0 -0
  517. /package/dist/{chunk-HVQGCKY4.js.map → chunk-JVLSU7S2.js.map} +0 -0
  518. /package/dist/{chunk-AR2JDFAE.js.map → chunk-KDJGJR7F.js.map} +0 -0
  519. /package/dist/{chunk-747LRSOO.js.map → chunk-LKFKXS5K.js.map} +0 -0
  520. /package/dist/{chunk-U5O6GIWZ.js.map → chunk-LR4Z47QD.js.map} +0 -0
  521. /package/dist/{chunk-RTAMLDWP.js.map → chunk-NLKLXXTO.js.map} +0 -0
  522. /package/dist/{chunk-FDX7OWWI.js.map → chunk-OPXR4PB2.js.map} +0 -0
  523. /package/dist/{chunk-Z45YRGFO.js.map → chunk-P6ASQOZR.js.map} +0 -0
  524. /package/dist/{chunk-2Z3NCLNX.js.map → chunk-QI5NWLVW.js.map} +0 -0
  525. /package/dist/{chunk-6SAFL5YE.js.map → chunk-RC4BROYR.js.map} +0 -0
  526. /package/dist/{chunk-NJDQ4YSV.js.map → chunk-RDHUZ674.js.map} +0 -0
  527. /package/dist/{chunk-3JVXVJ7L.js.map → chunk-S35S77YU.js.map} +0 -0
  528. /package/dist/{chunk-KUDZVJKQ.js.map → chunk-SHILAQH5.js.map} +0 -0
  529. /package/dist/{chunk-4UVDI4XE.js.map → chunk-T3PHCEN4.js.map} +0 -0
  530. /package/dist/{derive-IUA6JFLB.js.map → chunk-UBSFPGVJ.js.map} +0 -0
  531. /package/dist/{chunk-FAXZQ5UF.js.map → chunk-UCUALOSM.js.map} +0 -0
  532. /package/dist/{chunk-4HDYQL3J.js.map → chunk-VAG47QHV.js.map} +0 -0
  533. /package/dist/{chunk-35EBKWQU.js.map → chunk-VFIWDPXZ.js.map} +0 -0
  534. /package/dist/{chunk-HNHCQ556.js.map → chunk-WLLUM35R.js.map} +0 -0
  535. /package/dist/{chunk-JRCYZEHU.js.map → chunk-XVU7J43V.js.map} +0 -0
  536. /package/dist/{chunk-DMQCLZ4Z.js.map → chunk-YCSM3GZU.js.map} +0 -0
  537. /package/dist/{chunk-FMQJZH4R.js.map → chunk-YMLQBZFJ.js.map} +0 -0
  538. /package/dist/{chunk-6HFM7EIT.js.map → chunk-YPSOHDNC.js.map} +0 -0
  539. /package/dist/{chunk-N35NC4JH.js.map → chunk-Z2PWOSCJ.js.map} +0 -0
  540. /package/dist/{chunk-HPLWFNG4.js.map → chunk-Z7ZXZL6Y.js.map} +0 -0
  541. /package/dist/{classified-marker-2KJAXRRO.js.map → classified-marker-BSQHU4JT.js.map} +0 -0
  542. /package/dist/{enclave-JU4YIEPB.js.map → collection-facade-LG3NYZVB.js.map} +0 -0
  543. /package/dist/{executor-CYJQLKKI.js.map → computed-ASBNTLOK.js.map} +0 -0
  544. /package/dist/{dead-filter-DCB62VWW.js.map → dead-filter-QKU56XTQ.js.map} +0 -0
  545. /package/dist/{executor-S4QIKEHW.js.map → derive-CXHCY46K.js.map} +0 -0
  546. /package/dist/{dispatch-MJ6SHB3Y.js.map → dispatch-4AP4PUZU.js.map} +0 -0
  547. /package/dist/{executor-YIQB2S6N.js.map → enclave-NYPT7WA7.js.map} +0 -0
  548. /package/dist/{export-accessible-4S36PQNR.js.map → executor-3KFRQETS.js.map} +0 -0
  549. /package/dist/{extract-partition-IO7FDZ2P.js.map → executor-AFHQYRAU.js.map} +0 -0
  550. /package/dist/{find-RBBYKXI7.js.map → executor-YYDW6XQI.js.map} +0 -0
  551. /package/dist/{issue-RIVHSY2S.js.map → export-accessible-BX2ILB4C.js.map} +0 -0
  552. /package/dist/{ledger-AETNF4OM.js.map → extract-partition-UPOVITFI.js.map} +0 -0
  553. /package/dist/{liberate-GFN4C7RR.js.map → find-SZBL2HPB.js.map} +0 -0
  554. /package/dist/{link-set-E5HNY67I.js.map → issue-G53NB6EW.js.map} +0 -0
  555. /package/dist/{managed-secret-CWQ6PND5.js.map → ledger-T5K4P2D7.js.map} +0 -0
  556. /package/dist/{noydb-ASEXNJS6.js.map → liberate-VEOZRESE.js.map} +0 -0
  557. /package/dist/{register-4EFJCVYD.js.map → link-set-76JZ6YB4.js.map} +0 -0
  558. /package/dist/{registry-4SDHHOJ7.js.map → managed-secret-6YC32VXG.js.map} +0 -0
  559. /package/dist/{registry-CZVINVQH.js.map → noydb-EDJA4JNJ.js.map} +0 -0
  560. /package/dist/{registry-IKUR2MXD.js.map → on/index.js.map} +0 -0
  561. /package/dist/{post-register-2XSSMGEQ.js.map → post-register-53O7AJRZ.js.map} +0 -0
  562. /package/dist/{registry-OYTFGWVK.js.map → register-6TCBR6XD.js.map} +0 -0
  563. /package/dist/{request-withdrawal-KGXGDPVQ.js.map → registry-DH2L4O2V.js.map} +0 -0
  564. /package/dist/{revoke-JFN773KF.js.map → registry-IWFMXCHX.js.map} +0 -0
  565. /package/dist/{signer-TA55QB6R.js.map → registry-Q3FG3OAX.js.map} +0 -0
  566. /package/dist/{stale-ARHFVL5U.js.map → registry-YC3IFG3A.js.map} +0 -0
  567. /package/dist/{storage-V7MTFAQJ.js.map → request-withdrawal-NM5VYR6F.js.map} +0 -0
  568. /package/dist/{reveal-BW36KCOQ.js.map → reveal-XBIMHAXR.js.map} +0 -0
  569. /package/dist/{ulid-PTAIMDG4.js.map → revoke-MJNYWO72.js.map} +0 -0
  570. /package/dist/{walk-3ZECBFDA.js.map → signer-6XVS2AU3.js.map} +0 -0
  571. /package/dist/{withdraw-accessible-7PG4DYQK.js.map → stale-MCS46TFO.js.map} +0 -0
  572. /package/dist/{verify-RO5RTZOJ.js.map → verify-WYOFLSNA.js.map} +0 -0
@@ -1,18 +1,18 @@
1
1
  /**
2
2
  * Per-client schema-fence watcher. Watches the fence via the injected
3
- * {@link CoordinationProvider}; on `draining` it drains in-flight writes
3
+ * {@link NoydbMesh}; on `draining` it drains in-flight writes
4
4
  * and reports presence (its ack); emits a same-instance signal on every
5
5
  * state transition (for UI). Driven by an interval in production and by
6
6
  * explicit `check()`/`beat()` in tests.
7
7
  *
8
8
  * The transport is the coordination port: the default
9
- * {@link StoreCoordinationProvider} maps `reportPresence` →
9
+ * {@link StoreMesh} maps `reportPresence` →
10
10
  * `_meta/schema-fence:client:<id>` and `readFence` → `_meta/schema-fence`,
11
11
  * so behavior is byte-for-byte the same; `by-tabs` / `by-peer` swap in
12
12
  * real-time push transports.
13
13
  */
14
14
  import { type FenceState } from './fence.js';
15
- import type { CoordinationProvider } from '../../port/by/index.js';
15
+ import type { NoydbMesh } from '../../port/by/index.js';
16
16
  export interface FenceWatcherEvent {
17
17
  readonly currentSchemaVersion: number;
18
18
  readonly fenceState: FenceState;
@@ -20,7 +20,7 @@ export interface FenceWatcherEvent {
20
20
  export declare class FenceWatcher {
21
21
  #private;
22
22
  constructor(opts: {
23
- coordination: CoordinationProvider;
23
+ coordination: NoydbMesh;
24
24
  vault: string;
25
25
  clientId: string;
26
26
  sessionId?: string;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Store-backed default {@link CoordinationProvider}.
2
+ * Store-backed default {@link NoydbMesh}.
3
3
  *
4
4
  * Maps the five coordination-port methods onto today's `_meta/schema-fence`
5
5
  * store ops so that, with no `by-*` provider injected, the fence service
@@ -11,15 +11,16 @@
11
11
  */
12
12
  import type { NoydbStore } from '../../kernel/types.js';
13
13
  import type { Unsubscribe } from '../../port/with/write-hooks.js';
14
- import type { CoordinationProvider, FenceState, WriterPresence } from '../../port/by/types.js';
15
- export declare class StoreCoordinationProvider implements CoordinationProvider {
14
+ import { type FenceDoc } from './fence.js';
15
+ import type { NoydbMesh, WriterPresence } from '../../port/by/types.js';
16
+ export declare class StoreMesh implements NoydbMesh {
16
17
  #private;
17
18
  constructor(store: NoydbStore, opts?: {
18
19
  pollIntervalMs?: number;
19
20
  });
20
- setFence(vault: string, fence: FenceState): Promise<void>;
21
- readFence(vault: string): Promise<FenceState>;
22
- observeFence(vault: string, onChange: (f: FenceState) => void): Unsubscribe;
21
+ setFence(vault: string, fence: FenceDoc): Promise<void>;
22
+ readFence(vault: string): Promise<FenceDoc>;
23
+ observeFence(vault: string, onChange: (f: FenceDoc) => void): Unsubscribe;
23
24
  reportPresence(vault: string, p: WriterPresence): Promise<void>;
24
25
  observePresence(vault: string, onChange: (writers: readonly WriterPresence[]) => void): Unsubscribe;
25
26
  reachableWriters(vault: string, o: {
@@ -1,4 +1,5 @@
1
1
  import type { NoydbStore, DirtyEntry, ConflictStrategy, CollectionConflictResolver, PushOptions, PullOptions, PushResult, PullResult, SyncStatus, SyncTargetRole } from '../kernel/types.js';
2
+ import type { MergeAuthority } from '../port/with/merge-authority.js';
2
3
  import { type PeriodPullSource } from './period-scope.js';
3
4
  import type { NoydbEventEmitter } from '../kernel/events.js';
4
5
  import type { SyncPolicy } from '../kernel/sync-policy.js';
@@ -12,6 +13,7 @@ export interface ReservedLookupSource {
12
13
  }
13
14
  /** Sync engine: dirty tracking, push, pull, conflict resolution, scheduling. */
14
15
  export declare class SyncEngine {
16
+ private readonly mergeAuthority;
15
17
  private readonly local;
16
18
  private readonly remote;
17
19
  private readonly strategy;
@@ -24,8 +26,17 @@ export declare class SyncEngine {
24
26
  * into the scheduler below. */
25
27
  readonly policy: SyncPolicy | undefined;
26
28
  private dirty;
29
+ /** #1036 — last SUCCESSFUL push/pull. Never advanced by a failed attempt. */
27
30
  private lastPush;
28
31
  private lastPull;
32
+ /**
33
+ * #1036 — the failure that ended the most recent attempt, cleared by the next
34
+ * success. Live state only: deliberately NOT persisted in `_sync/meta`, since a
35
+ * reload cannot know whether the target is still failing. It exists so a poller
36
+ * can separate "never synced" (both null) from "synced a while ago, failing
37
+ * since" (`lastPush` set, `lastError` set).
38
+ */
39
+ private lastError;
29
40
  private loaded;
30
41
  private autoSyncInterval;
31
42
  private isOnline;
@@ -92,6 +103,15 @@ export declare class SyncEngine {
92
103
  syncPolicy?: SyncPolicy;
93
104
  role?: SyncTargetRole;
94
105
  label?: string;
106
+ /**
107
+ * #1042 — the merge's verify/re-stamp capability. Optional so an engine
108
+ * built without one behaves exactly as before; the Vault supplies it.
109
+ *
110
+ * A closure, not an import: `with-sync` is DEK-free and
111
+ * `check:architecture` enforces that, so the capability arrives already
112
+ * bound to the keys rather than the engine reaching for them.
113
+ */
114
+ mergeAuthority?: MergeAuthority;
95
115
  });
96
116
  /** Start the sync scheduler. Called after vault is fully opened. */
97
117
  startScheduler(): void;
@@ -148,6 +168,18 @@ export declare class SyncEngine {
148
168
  * are removed from the dirty log on success.
149
169
  */
150
170
  pushFiltered(predicate: (entry: DirtyEntry) => boolean): Promise<PushResult>;
171
+ /**
172
+ * #1036 — close out a push/pull. `push()` and `pull()` collect per-record
173
+ * failures into their result's `errors` rather than throwing, and the clock used
174
+ * to be stamped regardless — so an unreachable store still reported a fresh
175
+ * `lastPush`, and a UI rendered "Last synced: just now" over a sync that moved
176
+ * nothing. An attempt only advances the clock when it had no errors.
177
+ *
178
+ * An empty dirty log is a success, not a failure: nothing to send is not the
179
+ * same as failing to send, and treating it otherwise would leave a quiet vault
180
+ * looking permanently unsynced.
181
+ */
182
+ private recordOutcome;
151
183
  /** Get current sync status. */
152
184
  status(): SyncStatus;
153
185
  /** Start auto-sync: listen for online/offline events, optional periodic sync. */
@@ -168,11 +200,28 @@ export declare class SyncEngine {
168
200
  * the remote's (the same-`_v` push tie), re-stamp it at `remote._v + 1`.
169
201
  * Without this the loser's next pull sees no delta (`_v`-based
170
202
  * detection) and the peers stay silently diverged at the same version.
171
- * `_v` is envelope metadata — AEAD-unbound, and `_vdig` is deliberately
172
- * `_v`-independent — so the engine may restamp ciphertext. Callers must
173
- * mirror the advanced envelope locally (`applyRemote`) so both sides
174
- * agree. The 'merged' branch needs none of this: resolver output is
175
- * already stamped `max(local, remote) + 1`.
203
+ * ## Why this is async, and why it goes through `MergeAuthority` (#1093)
204
+ *
205
+ * It used to be `{ ...winner, _v: remote._v + 1 }` — a metadata restamp on
206
+ * ciphertext the engine cannot decrypt. That spread was the SOLE reason `_v`
207
+ * could not be bound into the AAD: a version rewritten onto a body sealed at
208
+ * a different one produces a record no reader can open.
209
+ *
210
+ * `with-sync` is DEK-free by design and `check:architecture` enforces it, so
211
+ * the re-seal cannot happen here. It happens in the injected authority, which
212
+ * holds the keys. The engine still decides WHICH version to advance to; it
213
+ * simply no longer pretends it can rewrite a sealed body.
214
+ *
215
+ * The authority is ALWAYS present in the product — `kernel/noydb.ts` builds
216
+ * one from the keyring and passes it at both engine-construction sites, and
217
+ * `with-sync/active.ts` is the only place an engine is constructed. The
218
+ * fallback below is reachable only by constructing `SyncEngine` directly,
219
+ * which tests do. It restamps, as before — and would produce an unreadable
220
+ * record if such a test ever held AEAD-sealed envelopes. None do; the
221
+ * fixtures that reach it build their own plaintext ones.
222
+ *
223
+ * The 'merged' branch needs none of this: resolver output is already stamped
224
+ * `max(local, remote) + 1` by whoever built it.
176
225
  */
177
226
  private advancePastRemote;
178
227
  private applyRemote;
@@ -25,6 +25,7 @@
25
25
  * @internal
26
26
  */
27
27
  import type { NoydbStore, ConflictStrategy, SyncTargetRole } from '../kernel/types.js';
28
+ import type { MergeAuthority } from '../port/with/merge-authority.js';
28
29
  import type { NoydbEventEmitter } from '../kernel/events.js';
29
30
  import type { SyncPolicy } from '../kernel/sync-policy.js';
30
31
  import type { SyncEngine } from './engine.js';
@@ -47,6 +48,8 @@ export interface BuildSyncEngineOptions {
47
48
  syncPolicy?: SyncPolicy;
48
49
  role?: SyncTargetRole;
49
50
  label?: string;
51
+ /** #1042 — the merge's verify/re-stamp capability, bound to the keys by the caller. */
52
+ mergeAuthority?: MergeAuthority;
50
53
  }
51
54
  /**
52
55
  * @internal
@@ -0,0 +1,28 @@
1
+ import {
2
+ FROZEN_SNAPSHOTS_COLLECTION,
3
+ freezeAndDeleteClosure,
4
+ freezeSnapshotOnly,
5
+ randomId,
6
+ withdrawAccessibleData
7
+ } from "./chunk-H7HP56F6.js";
8
+ import "./chunk-DKWPJOYH.js";
9
+ import "./chunk-6FOGTKBY.js";
10
+ import "./chunk-LF6DMX4C.js";
11
+ import "./chunk-2LPVI4PX.js";
12
+ import "./chunk-N4CNVSUF.js";
13
+ import "./chunk-FOG7YEJP.js";
14
+ import "./chunk-KDJGJR7F.js";
15
+ import "./chunk-LKFKXS5K.js";
16
+ import "./chunk-LP7BEXCT.js";
17
+ import "./chunk-W5LHQXZU.js";
18
+ import "./chunk-RK7N4OQ5.js";
19
+ import "./chunk-JBIV4FLR.js";
20
+ import "./chunk-PZ5AY32C.js";
21
+ export {
22
+ FROZEN_SNAPSHOTS_COLLECTION,
23
+ freezeAndDeleteClosure,
24
+ freezeSnapshotOnly,
25
+ randomId,
26
+ withdrawAccessibleData
27
+ };
28
+ //# sourceMappingURL=withdraw-accessible-ILTSXTIE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noy-db/hub",
3
- "version": "0.6.0-pre.9",
3
+ "version": "0.7.0-pre.0",
4
4
  "description": "Zero-knowledge, offline-first, encrypted document store — core library with AES-256-GCM, PBKDF2, multi-user keyring, and sync engine",
5
5
  "license": "MIT",
6
6
  "author": "vLannaAi <vicio@lanna.ai>",
@@ -37,6 +37,10 @@
37
37
  "types": "./dist/with-party/session/index.d.ts",
38
38
  "default": "./dist/session/index.js"
39
39
  },
40
+ "./vault-head": {
41
+ "types": "./dist/with-commit/vault-head/index.d.ts",
42
+ "default": "./dist/vault-head/index.js"
43
+ },
40
44
  "./history": {
41
45
  "types": "./dist/with-commit/history/index.d.ts",
42
46
  "default": "./dist/history/index.js"
@@ -165,6 +169,22 @@
165
169
  "types": "./dist/port/to/index.d.ts",
166
170
  "default": "./dist/to/index.js"
167
171
  },
172
+ "./at": {
173
+ "types": "./dist/port/at/index.d.ts",
174
+ "default": "./dist/at/index.js"
175
+ },
176
+ "./as": {
177
+ "types": "./dist/port/as/index.d.ts",
178
+ "default": "./dist/as/index.js"
179
+ },
180
+ "./by": {
181
+ "types": "./dist/port/by/index.d.ts",
182
+ "default": "./dist/by/index.js"
183
+ },
184
+ "./on": {
185
+ "types": "./dist/port/on/index.d.ts",
186
+ "default": "./dist/on/index.js"
187
+ },
168
188
  "./store": {
169
189
  "types": "./dist/with-store/index.d.ts",
170
190
  "default": "./dist/store/index.js"
@@ -196,13 +216,16 @@
196
216
  "./reduce": {
197
217
  "types": "./dist/with-lookup/reduce/index.d.ts",
198
218
  "default": "./dist/reduce/index.js"
199
- }
219
+ },
220
+ "./codemods/0.6.0-pre.json": "./codemods/0.6.0-pre.json",
221
+ "./codemods/0.7.0-pre.json": "./codemods/0.7.0-pre.json"
200
222
  },
201
223
  "module": "./dist/index.js",
202
224
  "types": "./dist/index.d.ts",
203
225
  "files": [
204
226
  "dist",
205
227
  "README.md",
228
+ "CHANGELOG.md",
206
229
  "LICENSE",
207
230
  "codemods"
208
231
  ],
@@ -210,14 +233,14 @@
210
233
  "node": ">=22.0.0"
211
234
  },
212
235
  "dependencies": {
213
- "@noy-db/attestation": "0.6.0-pre.9"
236
+ "@noy-db/attestation": "0.7.0-pre.0"
214
237
  },
215
238
  "devDependencies": {
216
239
  "@types/node": "^22.0.0",
217
240
  "esbuild": "^0.25.0",
218
241
  "zod": "^4.0.0",
219
242
  "zod-to-json-schema": "^3.25.2",
220
- "@noy-db/on-shamir": "0.6.0-pre.9"
243
+ "@noy-db/on-shamir": "0.7.0-pre.0"
221
244
  },
222
245
  "peerDependencies": {
223
246
  "zod-to-json-schema": "^3.25.0"
@@ -256,6 +279,7 @@
256
279
  "typecheck:types": "tsc --noEmit -p tsconfig.typetest.json",
257
280
  "typecheck:tests": "tsc --noEmit -p tsconfig.tests.json",
258
281
  "bundle-check": "node scripts/check-bundle.mjs",
259
- "check:types": "node scripts/check-type-reachability.mjs"
282
+ "check:types": "node scripts/check-type-reachability.mjs",
283
+ "check:codemods": "node scripts/check-codemod-coverage.mjs"
260
284
  }
261
285
  }
@@ -1,20 +0,0 @@
1
- import {
2
- UserApi,
3
- createUserApi
4
- } from "./chunk-6FJWSWFT.js";
5
- import "./chunk-5JY5TSVY.js";
6
- import "./chunk-3URQC7EH.js";
7
- import "./chunk-7H73RIE3.js";
8
- import "./chunk-HXGUIPQB.js";
9
- import "./chunk-AR2JDFAE.js";
10
- import "./chunk-747LRSOO.js";
11
- import "./chunk-LP7BEXCT.js";
12
- import "./chunk-VCETL77O.js";
13
- import "./chunk-YPYHVOXP.js";
14
- import "./chunk-HNGSV2YC.js";
15
- import "./chunk-PZ5AY32C.js";
16
- export {
17
- UserApi,
18
- createUserApi
19
- };
20
- //# sourceMappingURL=api-RXUMEKT3.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-pod/backup.ts"],"sourcesContent":["/**\n * Vault backup / restore / integrity.\n *\n * Holds `dump()` (verifiable encrypted JSON backup, including the blob\n * collections so blob \"covers\" travel in the bundle), `load()` (restore +\n * post-load integrity gate), `verifyBackupIntegrity()` (chain + data-envelope\n * cross-check), and `exportJSON()` (plaintext per-collection export, built on\n * the vault's `exportStream`). Behaviour is byte-identical to the inline\n * `Vault` methods these functions replaced — every dependency the moving code\n * touched on `this.*` arrives via {@link BackupContext}. `Vault` keeps the\n * public methods as thin delegators.\n *\n * Internal — reached through `vault.dump()` / `vault.load()` / etc.\n */\nimport { NOYDB_BACKUP_VERSION } from '../kernel/types.js'\nimport { BackupLedgerError, BackupCorruptedError } from '../kernel/errors.js'\nimport { LEDGER_COLLECTION, LEDGER_DELTAS_COLLECTION } from '../with-commit/history/ledger/constants.js'\nimport { SCHEMAS_COLLECTION } from '../with-shape/persisted-schemas/storage.js'\nimport { SEQUENCE_COLLECTION } from '../with-commit/sequence/index.js'\nimport { MANIFEST_COLLECTION } from '../with-shape/manifest/reserved-collections.js'\nimport type {\n NoydbStore,\n EncryptedEnvelope,\n VaultBackup,\n VaultSnapshot,\n ExportStreamOptions,\n ExportChunk,\n} from '../kernel/types.js'\nimport type { LedgerStore } from '../with-commit/history/ledger/store.js'\n\n/** Everything the moving backup methods touched on the vault's `this.*`. */\nexport interface BackupContext {\n /** The ciphertext store. */\n readonly adapter: NoydbStore\n /** Vault namespace name. */\n readonly vault: string\n /** The invoking keyring's user id (read fresh per call). */\n userId(): string\n /** The vault's ledger store, or null when history is off. */\n getLedgerOrNull(): LedgerStore | null\n /** Recompute an envelope's `payloadHash` (bound `historyStrategy.envelopePayloadHash`). */\n envelopePayloadHash(envelope: EncryptedEnvelope): Promise<string>\n /**\n * Refresh the in-memory keyring from the freshly-loaded keyring file and\n * rebuild the DEK resolver. No-op when the vault has no `reloadKeyring`\n * callback (plaintext vaults / test constructions).\n */\n reloadKeyringAndRebuildDEK(): Promise<void>\n /** Clear the vault's collection cache (post-load). */\n clearCollectionCache(): void\n /** Reset the ledger store so the next `ledger()` rebuilds its head cache. */\n resetLedgerStore(): void\n /** The vault's decrypt+ACL export stream (used by `exportJSON`). */\n exportStream(opts: ExportStreamOptions): AsyncIterableIterator<ExportChunk>\n}\n\n/** Result of {@link verifyBackupIntegrity}. */\nexport type VerifyBackupResult =\n | { readonly ok: true; readonly head: string; readonly length: number }\n | {\n readonly ok: false\n readonly kind: 'chain'\n readonly divergedAt: number\n readonly message: string\n }\n | {\n readonly ok: false\n readonly kind: 'data'\n readonly collection: string\n readonly id: string\n readonly message: string\n }\n\n/**\n * Dump vault as a verifiable encrypted JSON backup string.\n *\n * backups embed the current ledger head and the full `_ledger` +\n * `_ledger_deltas` internal collections so the receiver can run\n * `verifyBackupIntegrity()` after `load()` and detect any tampering between\n * dump and restore. Backups produced without a ledger skip the integrity check\n * with a warning — both modes round-trip cleanly.\n */\nexport async function dumpVault(ctx: BackupContext): Promise<string> {\n const snapshot = await ctx.adapter.loadAll(ctx.vault)\n\n // Load keyrings (separate path because loadAll filters them out\n // along with all other underscore-prefixed internal collections).\n const keyringIds = await ctx.adapter.list(ctx.vault, '_keyring')\n const keyrings: Record<string, unknown> = {}\n for (const keyringId of keyringIds) {\n const envelope = await ctx.adapter.get(ctx.vault, '_keyring', keyringId)\n if (envelope) {\n keyrings[keyringId] = JSON.parse(envelope._data)\n }\n }\n\n // Load the ledger entries + deltas so the receiver can replay\n // the chain after restore. Without this, `load()` would have an\n // empty ledger and `verifyBackupIntegrity()` would have nothing\n // to compare against.\n //\n // Also enumerate the blob collections so blob content (\"covers\")\n // travels in the bundle (the blob DEK already travels in `_keyring`).\n // Literals are inlined (not imported from blobs/blob-set.ts) to keep\n // the blob runtime out of this kernel hot path — they mirror\n // BLOB_INDEX/CHUNKS/EVICTION_AUDIT_COLLECTION and SLOTS/VERSIONS_PREFIX.\n // The collect-loop skips empty ids, so this no-ops without blobs.\n const internalSnapshot: VaultSnapshot = {}\n const internalNames = [\n LEDGER_COLLECTION, LEDGER_DELTAS_COLLECTION, SCHEMAS_COLLECTION, SEQUENCE_COLLECTION,\n MANIFEST_COLLECTION, // #941: the pod's manifest-set record(s) travel in the bundle too\n '_history', // full-snapshot version history — so history()/getVersion()/diff() survive the bundle\n '_blob_index', '_blob_chunks', '_blob_eviction_audit',\n // #753 spec §7 Q3: `_blob_intent` markers travel too — restoring mid-op\n // state (a blob row without its marker) would reproduce the ambiguity\n // the journal exists to prevent. Note: `_mv_stale` does NOT travel\n // today (a pre-existing, separate gap) — observed here, tracked on\n // #761, not fixed in this pass.\n '_blob_intent',\n // #769: `_blob_slots_<c>` envelopes travel verbatim (raw ciphertext,\n // same DEK, same vault) — including any `SlotRecord.pendingRelease`\n // resume breadcrumb they carry. This is INTENTIONALLY the opposite of\n // `extract-partition`'s `reKeyBlobs`, which STRIPS `pendingRelease`:\n // a full-vault backup restores into the SAME vault it was taken from,\n // so a breadcrumb taken mid-rehome (together with its `_blob_intent`\n // marker, carried above) is resumable on restore — carry-and-resume is\n // correct here. A partition extraction crosses vaults: the breadcrumb's\n // old eTag may not exist in the destination, so it must be stripped\n // there instead. Asymmetry: backup = same-vault-resumable = carry;\n // partition = cross-vault = strip-breadcrumb-carry-marker.\n ...Object.keys(snapshot).flatMap((c) => [`_blob_slots_${c}`, `_blob_versions_${c}`]),\n ]\n for (const internalName of internalNames) {\n const ids = await ctx.adapter.list(ctx.vault, internalName)\n if (ids.length === 0) continue\n const records: Record<string, EncryptedEnvelope> = {}\n for (const id of ids) {\n const envelope = await ctx.adapter.get(ctx.vault, internalName, id)\n if (envelope) records[id] = envelope\n }\n internalSnapshot[internalName] = records\n }\n\n // Embed the ledger head if there's a chain. An empty ledger\n // (fresh vault) leaves `ledgerHead` undefined, which\n // load() treats the same as a legacy backup (no integrity\n // check, console warning). If history is not opted in,\n // `getLedgerOrNull` returns null and we skip embedding entirely\n // — the backup is still valid, just without the integrity head.\n const ledgerForHead = ctx.getLedgerOrNull()\n const head = ledgerForHead ? await ledgerForHead.head() : null\n const backup: VaultBackup = {\n _noydb_backup: NOYDB_BACKUP_VERSION,\n _compartment: ctx.vault,\n _exported_at: new Date().toISOString(),\n _exported_by: ctx.userId(),\n keyrings: keyrings as VaultBackup['keyrings'],\n collections: snapshot,\n ...(Object.keys(internalSnapshot).length > 0\n ? { _internal: internalSnapshot }\n : {}),\n ...(head\n ? {\n ledgerHead: {\n hash: head.hash,\n index: head.entry.index,\n ts: head.entry.ts,\n },\n }\n : {}),\n }\n\n return JSON.stringify(backup)\n}\n\n/**\n * Restore a vault from a verifiable backup. After loading, runs\n * `verifyBackupIntegrity()` to confirm the hash chain, the embedded head, and\n * every data envelope's payload hash. Legacy backups (no `ledgerHead`) load\n * with a console warning and skip the integrity check.\n */\nexport async function loadVault(ctx: BackupContext, backupJson: string): Promise<void> {\n const backup = JSON.parse(backupJson) as VaultBackup\n\n // 1. Restore data collections.\n await ctx.adapter.saveAll(ctx.vault, backup.collections)\n\n // 2. Restore keyrings.\n for (const [userId, keyringFile] of Object.entries(backup.keyrings)) {\n const envelope = {\n _noydb: 1 as const,\n _v: 1,\n _ts: new Date().toISOString(),\n _iv: '',\n _data: JSON.stringify(keyringFile),\n }\n await ctx.adapter.put(ctx.vault, '_keyring', userId, envelope)\n }\n\n // 3. Restore internal collections (`_ledger`, `_ledger_deltas`).\n // Required so verifyBackupIntegrity has the chain to walk.\n if (backup._internal) {\n for (const [internalName, records] of Object.entries(backup._internal)) {\n for (const [id, envelope] of Object.entries(records)) {\n await ctx.adapter.put(ctx.vault, internalName, id, envelope)\n }\n }\n }\n\n // 4. Refresh the in-memory keyring from the freshly-loaded\n // keyring file. Without this, the Vault's getDEK\n // closure still holds the OLD session's DEKs, and every\n // decrypt of a loaded ledger entry / data envelope fails\n // with TamperedError because the DEK doesn't match the\n // ciphertext that was encrypted with the SOURCE user's DEK.\n // Skipped for plaintext vaults and for tests that\n // construct Vault without a reloadKeyring callback.\n await ctx.reloadKeyringAndRebuildDEK()\n\n // 5. Clear collection cache + reset the ledger store so the\n // next ledger() call rebuilds its head cache from the\n // freshly-loaded entries.\n ctx.clearCollectionCache()\n ctx.resetLedgerStore()\n\n // 5. Run the verification gate. Legacy backups (no ledgerHead)\n // skip this with a one-line warning so existing consumers can\n // still read them while migrating.\n if (!backup.ledgerHead) {\n console.warn(\n `[noy-db] Loaded a legacy backup with no ledgerHead — ` +\n `verifiable-backup integrity check skipped. ` +\n `Re-export with a ledger-aware build to get tamper detection.`,\n )\n return\n }\n\n const result = await verifyBackupIntegrity(ctx)\n if (!result.ok) {\n // Surface the most specific error class we can. The result\n // shape carries enough info for callers to inspect.\n if (result.kind === 'data') {\n throw new BackupCorruptedError(\n result.collection,\n result.id,\n result.message,\n )\n }\n throw new BackupLedgerError(result.message, result.divergedAt)\n }\n\n // 6. Cross-check: the freshly-verified head must match the\n // value embedded at dump time. A mismatch means someone\n // truncated or extended the chain after dump.\n if (result.head !== backup.ledgerHead.hash) {\n throw new BackupLedgerError(\n `Backup ledger head mismatch: embedded \"${backup.ledgerHead.hash}\" ` +\n `but reconstructed \"${result.head}\".`,\n )\n }\n}\n\n/**\n * End-to-end backup integrity check: `ledger.verify()` (hash chain) plus a data\n * envelope cross-check (every current record's `_data` hash must match the\n * latest `put` entry's `payloadHash`). Returns a discriminated union so callers\n * can distinguish chain vs data failures.\n */\nexport async function verifyBackupIntegrity(ctx: BackupContext): Promise<VerifyBackupResult> {\n // Step 1: chain verification. Without the history strategy there\n // is no ledger; an unaudited backup verifies trivially as `ok`\n // because there's nothing to diverge from.\n const ledgerForVerify = ctx.getLedgerOrNull()\n if (!ledgerForVerify) {\n return { ok: true, head: '', length: 0 }\n }\n const chainResult = await ledgerForVerify.verify()\n if (!chainResult.ok) {\n return {\n ok: false,\n kind: 'chain',\n divergedAt: chainResult.divergedAt,\n message:\n `Ledger chain diverged at index ${chainResult.divergedAt}: ` +\n `expected prevHash \"${chainResult.expected}\" but found \"${chainResult.actual}\".`,\n }\n }\n\n // Step 2: data envelope cross-check. Walk every entry in the\n // ledger and, for the LATEST `put` per (collection, id), recompute\n // the data envelope's payloadHash and compare. Earlier puts of the\n // same id are skipped because the data collection only holds the\n // current version — historical envelopes live in the deltas\n // collection (which is itself protected by the chain).\n // Reuse the ledger we already resolved in step 1.\n const allEntries = await ledgerForVerify.loadAllEntries()\n\n // Find the latest non-delete entry per (collection, id). Walk\n // the entries in reverse so we hit the latest first; mark each\n // (collection, id) as seen and skip subsequent entries.\n const seen = new Set<string>()\n const latest = new Map<\n string,\n { collection: string; id: string; expectedHash: string }\n >()\n for (let i = allEntries.length - 1; i >= 0; i--) {\n const entry = allEntries[i]\n if (!entry) continue\n // Amendment entries are multi-record audit entries whose\n // `collection` and `id` are empty strings — building a `\"/\"`\n // key here would mark that synthetic slot as seen and falsely\n // trip the data check on a record that never existed. Skip\n // them BEFORE the key/seen bookkeeping so they neither\n // tombstone real entries nor enter the latest map.\n if (entry.op === 'amendment' || entry.op === 'lifecycle') continue\n const key = `${entry.collection}/${entry.id}`\n if (seen.has(key)) continue\n seen.add(key)\n // For deletes the data collection should NOT have the record,\n // so we skip — there's nothing to cross-check. Marking the key\n // as seen above ensures any earlier `put` of the same id is\n // also skipped (the record was subsequently deleted).\n if (entry.op === 'delete') continue\n latest.set(key, {\n collection: entry.collection,\n id: entry.id,\n expectedHash: entry.payloadHash,\n })\n }\n\n for (const { collection, id, expectedHash } of latest.values()) {\n const envelope = await ctx.adapter.get(ctx.vault, collection, id)\n if (!envelope) {\n return {\n ok: false,\n kind: 'data',\n collection,\n id,\n message:\n `Ledger expects data record \"${collection}/${id}\" to exist, ` +\n `but the adapter has no envelope for it.`,\n }\n }\n const actualHash = await ctx.envelopePayloadHash(envelope)\n if (actualHash !== expectedHash) {\n return {\n ok: false,\n kind: 'data',\n collection,\n id,\n message:\n `Data envelope \"${collection}/${id}\" has been tampered with: ` +\n `expected payloadHash \"${expectedHash}\", got \"${actualHash}\".`,\n }\n }\n }\n\n return {\n ok: true,\n head: chainResult.head,\n length: chainResult.length,\n }\n}\n\n/**\n * Plaintext per-collection export, built on the vault's `exportStream`. Forces\n * collection granularity (record-by-record output makes no sense in a single\n * string) and merges dictionary snapshots across collections.\n */\nexport async function exportVaultJSON(ctx: BackupContext, opts: ExportStreamOptions = {}): Promise<string> {\n // Force per-collection granularity regardless of caller setting:\n // record-by-record output doesn't make sense in a single string.\n const collections: Record<\n string,\n {\n schema: null\n refs: Record<string, { target: string; mode: 'strict' | 'warn' | 'cascade' }>\n records: unknown[]\n }\n > = {}\n let ledgerHead: ExportChunk['ledgerHead'] | undefined\n // Merged dictionary snapshot across all collections.\n // Only populated when `resolveLabels` is not set.\n const allDictionaries: Record<\n string, // collection name\n Record<string, Record<string, Record<string, string>>>\n > = {}\n\n for await (const chunk of ctx.exportStream({\n granularity: 'collection',\n withLedgerHead: opts.withLedgerHead === true,\n // Thread the export locale so records are read at the\n // `export` layer (i18nText collapsed + dictKey/staticDict labels resolved).\n ...(opts.resolveLabels !== undefined ? { resolveLabels: opts.resolveLabels } : {}),\n })) {\n collections[chunk.collection] = {\n schema: null, // Standard Schema validators are not JSON-serializable\n refs: chunk.refs,\n records: chunk.records,\n }\n if (chunk.ledgerHead) ledgerHead = chunk.ledgerHead\n // Collect dictionary snapshots unless resolveLabels is set\n if (!opts.resolveLabels && chunk.dictionaries) {\n allDictionaries[chunk.collection] = chunk.dictionaries\n }\n }\n\n const hasDictionaries = Object.keys(allDictionaries).length > 0\n return JSON.stringify({\n _noydb_export: 1,\n _compartment: ctx.vault,\n _exported_at: new Date().toISOString(),\n _exported_by: ctx.userId(),\n collections,\n ...(hasDictionaries ? { _dictionaries: allDictionaries } : {}),\n ...(ledgerHead ? { ledgerHead } : {}),\n })\n}\n"],"mappings":"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","names":[]}
@@ -1,36 +0,0 @@
1
- import {
2
- NOYDB_FORMAT_VERSION
3
- } from "./chunk-YPYHVOXP.js";
4
- import "./chunk-PZ5AY32C.js";
5
-
6
- // src/with-pod/bundle-handle.ts
7
- async function buildBundleHandle(adapter, name) {
8
- const existing = await adapter.get(name, "_meta", "handle");
9
- if (existing) {
10
- try {
11
- const parsed = JSON.parse(existing._data);
12
- if (parsed !== null && typeof parsed === "object" && "handle" in parsed) {
13
- const handle2 = parsed.handle;
14
- if (typeof handle2 === "string" && /^[0-9A-HJKMNP-TV-Z]{26}$/.test(handle2)) {
15
- return handle2;
16
- }
17
- }
18
- } catch {
19
- }
20
- }
21
- const { generateULID } = await import("./ulid-PTAIMDG4.js");
22
- const handle = generateULID();
23
- const envelope = {
24
- _noydb: NOYDB_FORMAT_VERSION,
25
- _v: 1,
26
- _ts: (/* @__PURE__ */ new Date()).toISOString(),
27
- _iv: "",
28
- _data: JSON.stringify({ handle })
29
- };
30
- await adapter.put(name, "_meta", "handle", envelope);
31
- return handle;
32
- }
33
- export {
34
- buildBundleHandle
35
- };
36
- //# sourceMappingURL=bundle-handle-GFNHT52M.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-pod/bundle-handle.ts"],"sourcesContent":["/**\n * Vault bundle handle — the stable opaque ULID identifying a vault\n * across `.noydb` exports.\n *\n * Behaviour is byte-identical to the inline `Vault.getBundleHandle`\n * method this function replaced. `Vault` keeps the public method as\n * a thin delegator.\n *\n * Internal — reached through `vault.getBundleHandle()`.\n */\nimport { NOYDB_FORMAT_VERSION } from '../kernel/types.js'\nimport type { NoydbStore, EncryptedEnvelope } from '../kernel/types.js'\n\n/**\n * Return the stable opaque bundle handle for the given vault adapter,\n * generating and persisting a fresh ULID on first call.\n *\n * See {@link import('../kernel/vault.js').Vault.getBundleHandle} for\n * the full rationale and storage-path documentation.\n */\nexport async function buildBundleHandle(adapter: NoydbStore, name: string): Promise<string> {\n const existing = await adapter.get(name, '_meta', 'handle')\n if (existing) {\n try {\n const parsed = JSON.parse(existing._data) as unknown\n if (parsed !== null && typeof parsed === 'object' && 'handle' in parsed) {\n const handle = (parsed as { handle: unknown }).handle\n if (typeof handle === 'string' && /^[0-9A-HJKMNP-TV-Z]{26}$/.test(handle)) {\n return handle\n }\n }\n } catch {\n // Fall through to regenerate — corrupted handle envelope\n // is treated as missing, not as an error. The new handle\n // overwrites the bad one.\n }\n }\n const { generateULID } = await import('./ulid.js')\n const handle = generateULID()\n const envelope: EncryptedEnvelope = {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: 1,\n _ts: new Date().toISOString(),\n _iv: '',\n _data: JSON.stringify({ handle }),\n }\n await adapter.put(name, '_meta', 'handle', envelope)\n return handle\n}\n"],"mappings":";;;;;;AAoBA,eAAsB,kBAAkB,SAAqB,MAA+B;AAC1F,QAAM,WAAW,MAAM,QAAQ,IAAI,MAAM,SAAS,QAAQ;AAC1D,MAAI,UAAU;AACZ,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,SAAS,KAAK;AACxC,UAAI,WAAW,QAAQ,OAAO,WAAW,YAAY,YAAY,QAAQ;AACvE,cAAMA,UAAU,OAA+B;AAC/C,YAAI,OAAOA,YAAW,YAAY,2BAA2B,KAAKA,OAAM,GAAG;AACzE,iBAAOA;AAAA,QACT;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAIR;AAAA,EACF;AACA,QAAM,EAAE,aAAa,IAAI,MAAM,OAAO,oBAAW;AACjD,QAAM,SAAS,aAAa;AAC5B,QAAM,WAA8B;AAAA,IAClC,QAAQ;AAAA,IACR,IAAI;AAAA,IACJ,MAAK,oBAAI,KAAK,GAAE,YAAY;AAAA,IAC5B,KAAK;AAAA,IACL,OAAO,KAAK,UAAU,EAAE,OAAO,CAAC;AAAA,EAClC;AACA,QAAM,QAAQ,IAAI,MAAM,SAAS,UAAU,QAAQ;AACnD,SAAO;AACT;","names":["handle"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-shape/manifest/types.ts","../src/with-shape/manifest/storage.ts","../src/with-shape/manifest/derive.ts"],"sourcesContent":["/**\n * The pod-wide **schema manifest** record type (#941).\n *\n * This is an INDEX, not a full-inline manifest: `SchemaManifest.collections`\n * carries per-collection *metadata* (generation / content hash / field ids),\n * never the JSON Schema body itself. The JSON Schema stays the source of\n * truth at `_schemas/<collection>`, encrypted under that collection's own\n * DEK (see `with-shape/persisted-schemas`). Inlining full schemas into one\n * pod-wide manifest record would either leak every collection's schema to a\n * principal scoped to a single collection, or force the manifest itself\n * onto a collection-DEK it has no business holding — the index preserves\n * per-collection DEK isolation while still giving a single place to answer\n * \"what schema generation is this pod at, and does collection X's stored\n * schema match its declared content hash.\"\n *\n * `aggregateHash` binds the whole per-collection index's content: it is\n * `sha256Hex(canonicalJson(collections))`, so any change to any collection's\n * entry (a new generation, a changed hash, added/renamed field ids) changes\n * `aggregateHash` too. Canonical JSON (sorted object keys, no whitespace)\n * makes the hash independent of the map's key insertion order.\n *\n * @module\n */\n\n/** Per-collection entry inside a {@link SchemaManifest}'s `collections` index. */\nexport interface SchemaManifestEntry {\n /** The vault-wide schema-fence generation this collection's schema was last written at. */\n readonly generation: number\n /** SHA-256 (hex) of the collection's canonicalised JSON Schema (see `persisted-schemas/derive.ts`). */\n readonly contentHash: string\n /** Stable per-field ids (#946), keyed by the field's current name. Absent when the collection has none. */\n readonly fieldIds?: Record<string, string>\n}\n\n/**\n * The pod-wide schema manifest — one record per pod, stored at\n * `_manifest/schema` (see `storage.ts`). An INDEX over the per-collection\n * `_schemas/<collection>` entries, not the schemas themselves.\n */\nexport interface SchemaManifest {\n readonly v: 1\n readonly kind: 'schema'\n /** Pod-wide schema-fence generation (`FenceDoc.currentSchemaVersion`) as of this manifest's derivation. */\n readonly generation: number\n /** Per-collection index: collection name → its manifest entry. */\n readonly collections: Record<string, SchemaManifestEntry>\n /** `sha256Hex(canonicalJson(collections))` — the pod-wide content binding over the index. */\n readonly aggregateHash: string\n}\n\n/** The record id the schema manifest is stored under inside `_manifest`. */\nexport const MANIFEST_SCHEMA_RECORD_ID = 'schema' as const\n","/**\n * Read / write the pod-wide `_manifest/schema` envelope.\n *\n * Mirrors `with-shape/persisted-schemas/storage.ts`'s shape: the same\n * standard noy-db record envelope, AES-GCM encrypted with a collection DEK\n * (here, the `_manifest` collection's own DEK — the manifest INDEX\n * discloses collection names + hashes + generations + field ids, metadata\n * rather than schema bodies, so it gets the same encryption grain as\n * `_schemas` itself).\n *\n * Storage layout:\n *\n * <vault>/_manifest/schema → EncryptedEnvelope\n *\n * Unlike `persisted-schemas/storage.ts` (which takes an already-resolved\n * `EnclaveKey`), these functions take a `getDEK` resolver and call\n * `getDEK(MANIFEST_COLLECTION)` themselves — there is exactly one manifest\n * record per pod, so there is no per-collection DEK the caller needs to\n * pick; resolving it here keeps every manifest call-site symmetric.\n *\n * @module\n */\n\nimport { openEnvelopeJson, writeEnvelopeBody, type EnclaveKey } from '../../kernel/enclave/index.js'\nimport { canonicalJson, sha256Hex } from '../../with-commit/history/ledger/index.js'\nimport { NOYDB_FORMAT_VERSION } from '../../kernel/types.js'\nimport type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js'\nimport { MANIFEST_COLLECTION } from './reserved-collections.js'\nimport { MANIFEST_SCHEMA_RECORD_ID, type SchemaManifest, type SchemaManifestEntry } from './types.js'\n\n/** A resolver for a collection's DEK — the same shape as `Vault`'s internal `getDEK`. */\nexport type GetManifestDEK = (collectionName: string) => Promise<EnclaveKey>\n\n/**\n * A decrypted schema-manifest read paired with the wrapping envelope's `_v`\n * — the optimistic-concurrency token. Pass `version` back to\n * {@link saveSchemaManifest} (via `writeSchemaManifest`'s `expectedVersion`)\n * to make the write a strict CAS.\n */\nexport interface LoadedSchemaManifest {\n /** Wrapping envelope `_v`. */\n readonly version: number\n /** Decrypted schema manifest. */\n readonly manifest: SchemaManifest\n}\n\n/**\n * Read the `_manifest/schema` envelope together with its wrapping `_v`.\n * Returns `undefined` when no manifest has ever been written, when the\n * envelope fails to decrypt (wrong DEK), or when it doesn't parse as a\n * `v: 1, kind: 'schema'` manifest.\n */\nexport async function loadSchemaManifestEntry(\n store: NoydbStore,\n vault: string,\n getDEK: GetManifestDEK,\n): Promise<LoadedSchemaManifest | undefined> {\n const envelope = await store.get(vault, MANIFEST_COLLECTION, MANIFEST_SCHEMA_RECORD_ID)\n if (!envelope) return undefined\n const dek = await getDEK(MANIFEST_COLLECTION)\n try {\n const plaintext = await openEnvelopeJson(envelope, dek)\n const parsed = JSON.parse(plaintext) as SchemaManifest\n if (parsed.v !== 1 || parsed.kind !== 'schema') return undefined\n return { version: envelope._v, manifest: parsed }\n } catch {\n return undefined\n }\n}\n\n/**\n * Encrypt and persist the schema manifest as a strict CAS write:\n * `expectedVersion` must match the stored envelope's `_v` (0 when no\n * envelope exists yet) or `store.put` throws `ConflictError` — surfaced by\n * `writer.ts`'s `writeSchemaManifest` as `ManifestConflictError` rather than\n * retried.\n */\nexport async function saveSchemaManifest(\n store: NoydbStore,\n vault: string,\n manifest: SchemaManifest,\n expectedVersion: number,\n getDEK: GetManifestDEK,\n): Promise<void> {\n const dek = await getDEK(MANIFEST_COLLECTION)\n const json = JSON.stringify(manifest)\n const body = await writeEnvelopeBody(json, dek)\n const env: EncryptedEnvelope = {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: expectedVersion + 1,\n _ts: new Date().toISOString(),\n ...body,\n }\n await store.put(vault, MANIFEST_COLLECTION, MANIFEST_SCHEMA_RECORD_ID, env, expectedVersion)\n}\n\n/**\n * `sha256Hex(canonicalJson(collections))` — the pod-wide content binding\n * over a schema manifest's per-collection index. Canonical JSON sorts\n * object keys at every depth, so the result is independent of the map's\n * key insertion order. Shared by the writer's tests and (#941 Task 3) the\n * derivation path, so the hash is computed identically everywhere.\n */\nexport async function computeAggregateHash(\n collections: Record<string, SchemaManifestEntry>,\n): Promise<string> {\n return sha256Hex(canonicalJson(collections))\n}\n","/**\n * Derive the pod-wide {@link SchemaManifest} from the per-collection\n * `_schemas/<collection>` records — the source of truth (#941 Task 3).\n *\n * The manifest is an INDEX, never a cache with independent state: every\n * field in a {@link SchemaManifestEntry} is a direct projection of the\n * matching `PersistedSchemaEnvelope` (`hash` → `contentHash`, `fieldIds` →\n * `fieldIds`, `generation` → `generation`, falling back to the live fence's\n * `currentSchemaVersion` for a legacy pre-#946 envelope that never got a\n * generation stamp). Re-running this function against the same stored state\n * always produces the same manifest — that's what makes round-trip identity\n * (AC #2: dump → restore → re-derive matches the original) hold for free,\n * with no special-cased restore logic.\n *\n * A collection whose `_schemas/<collection>` envelope decrypts successfully\n * but has no derivable content (`hash === null` — a stub envelope for a\n * non-Zod validator) is legitimately omitted from the index: there is no\n * content hash to bind.\n *\n * ## Scoped principals: \"cannot decrypt\" is NOT \"doesn't exist\"\n *\n * A `_schemas/<collection>` envelope is encrypted under **that data\n * collection's own DEK** — the same key its records use — NOT a shared\n * `_schemas`-wide key. In a team vault, a collection-scoped grantee (e.g.\n * `grant(..., { role: 'operator', permissions: { invoices: 'rw' } })`) holds\n * only the DEKs their `permissions` name, plus every system-prefixed (`_*`)\n * collection's DEK — `_manifest` included, by `grant()`'s \"propagate system\n * collections to every role\" rule (`keyring.ts`). So a member scoped to\n * `invoices` CAN decrypt `_manifest/schema` (the pod-wide index) but CANNOT\n * decrypt a sibling's `_schemas/customers` envelope — even though that\n * envelope is right there in `store.list(vault, SCHEMAS_COLLECTION)`.\n *\n * `lookupDEK` (the {@link LookupDEK} passed in) reflects this: it returns\n * `undefined` for a collection name whose DEK the caller does not hold —\n * deliberately NEVER minting a fresh one (see the module doc on\n * `LookupDEK` for why). This function distinguishes that case\n * (`undecodableCollections`) from \"the schema envelope legitimately has no\n * derivable content\" (`hash === null`) — the caller (`sync.ts`) MUST treat\n * an incomplete view differently: writing a manifest derived from a\n * partial view would silently drop every collection this principal can't\n * see. See `sync.ts`'s module doc for how the sync path handles this.\n *\n * @module\n */\n\nimport type { EnclaveKey } from '../../kernel/enclave/index.js'\nimport { loadFence } from '../schema-update/fence.js'\nimport { loadPersistedSchema, SCHEMAS_COLLECTION } from '../persisted-schemas/storage.js'\nimport { computeAggregateHash } from './storage.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport type { SchemaManifest, SchemaManifestEntry } from './types.js'\n\n/**\n * A NON-MINTING DEK lookup: returns the collection's DEK if the caller\n * already holds it, `undefined` otherwise. Deliberately distinct from\n * `storage.ts`'s `GetManifestDEK` (which mints+persists a fresh DEK for an\n * absent collection — correct for a caller about to WRITE that collection,\n * e.g. `_manifest` itself). `deriveSchemaManifest` only ever READS sibling\n * collections it never created and has no business minting keys for — an\n * absent DEK here means \"not my collection to see,\" never \"new collection\n * that needs a key.\" Minting here would be worse than a no-op: it would\n * silently persist a garbage DEK into the caller's OWN `_keyring/<user>`\n * file (via `ensureCollectionDEK`'s `persistKeyring` side effect) that\n * still can't decrypt anything — see `sync.ts` / `with-pod/open.ts`'s\n * fix notes (#941 review).\n */\nexport type LookupDEK = (collectionName: string) => Promise<EnclaveKey | undefined>\n\nexport interface DeriveSchemaManifestResult {\n /** The derived manifest — an index over every collection this principal could decrypt. */\n readonly manifest: SchemaManifest\n /**\n * Names present in `_schemas` (per `store.list`) whose envelope this\n * principal could NOT decrypt — either no DEK held for that collection,\n * or the DEK held failed to decrypt/parse it (treated the same: the\n * caller cannot verify what's there, so it cannot safely be omitted or\n * asserted). Empty for a principal with full visibility (typically the\n * owner/admin/custodian). Non-empty means `manifest.collections` is\n * DEFINITELY INCOMPLETE relative to the pod's true collection set —\n * see `sync.ts` for why that must gate whether the manifest gets written.\n */\n readonly undecodableCollections: readonly string[]\n}\n\n/**\n * Read the fence generation + every `_schemas/<collection>` envelope this\n * principal can decrypt, and project them into a fresh {@link SchemaManifest}.\n * `lookupDEK` is called once per collection found under `_schemas` (never\n * mints — see {@link LookupDEK}). Names whose DEK isn't held, or whose\n * envelope fails to decrypt/parse despite holding a DEK, are reported via\n * `undecodableCollections` rather than silently dropped from the result.\n */\nexport async function deriveSchemaManifest(\n store: NoydbStore,\n vault: string,\n lookupDEK: LookupDEK,\n): Promise<DeriveSchemaManifestResult> {\n const fence = await loadFence(store, vault)\n const collectionNames = await store.list(vault, SCHEMAS_COLLECTION)\n\n const collections: Record<string, SchemaManifestEntry> = {}\n const undecodableCollections: string[] = []\n for (const name of collectionNames) {\n const dek = await lookupDEK(name)\n if (dek === undefined) {\n undecodableCollections.push(name) // present in _schemas, but not decodable by this principal\n continue\n }\n\n const payload = await loadPersistedSchema(store, vault, name, dek)\n if (!payload) {\n // Held a DEK but still couldn't decrypt/parse — cannot distinguish\n // \"wrong key after all\" from real corruption from here; treat as\n // undecodable (never silently drop) rather than \"no content.\"\n undecodableCollections.push(name)\n continue\n }\n if (payload.hash === null) continue // legitimately no derivable content (stub envelope)\n\n const entry: SchemaManifestEntry = {\n generation: payload.generation ?? fence.currentSchemaVersion,\n contentHash: payload.hash,\n }\n collections[name] = payload.fieldIds !== undefined ? { ...entry, fieldIds: payload.fieldIds } : entry\n }\n\n const aggregateHash = await computeAggregateHash(collections)\n const manifest: SchemaManifest = { v: 1, kind: 'schema', generation: fence.currentSchemaVersion, collections, aggregateHash }\n return { manifest, undecodableCollections }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAmDO,IAAM,4BAA4B;;;ACCzC,eAAsB,wBACpB,OACA,OACA,QAC2C;AAC3C,QAAM,WAAW,MAAM,MAAM,IAAI,OAAO,qBAAqB,yBAAyB;AACtF,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,MAAM,MAAM,OAAO,mBAAmB;AAC5C,MAAI;AACF,UAAM,YAAY,MAAM,iBAAiB,UAAU,GAAG;AACtD,UAAM,SAAS,KAAK,MAAM,SAAS;AACnC,QAAI,OAAO,MAAM,KAAK,OAAO,SAAS,SAAU,QAAO;AACvD,WAAO,EAAE,SAAS,SAAS,IAAI,UAAU,OAAO;AAAA,EAClD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AASA,eAAsB,mBACpB,OACA,OACA,UACA,iBACA,QACe;AACf,QAAM,MAAM,MAAM,OAAO,mBAAmB;AAC5C,QAAM,OAAO,KAAK,UAAU,QAAQ;AACpC,QAAM,OAAO,MAAM,kBAAkB,MAAM,GAAG;AAC9C,QAAM,MAAyB;AAAA,IAC7B,QAAQ;AAAA,IACR,IAAI,kBAAkB;AAAA,IACtB,MAAK,oBAAI,KAAK,GAAE,YAAY;AAAA,IAC5B,GAAG;AAAA,EACL;AACA,QAAM,MAAM,IAAI,OAAO,qBAAqB,2BAA2B,KAAK,eAAe;AAC7F;AASA,eAAsB,qBACpB,aACiB;AACjB,SAAO,UAAU,cAAc,WAAW,CAAC;AAC7C;;;ACfA,eAAsB,qBACpB,OACA,OACA,WACqC;AACrC,QAAM,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1C,QAAM,kBAAkB,MAAM,MAAM,KAAK,OAAO,kBAAkB;AAElE,QAAM,cAAmD,CAAC;AAC1D,QAAM,yBAAmC,CAAC;AAC1C,aAAW,QAAQ,iBAAiB;AAClC,UAAM,MAAM,MAAM,UAAU,IAAI;AAChC,QAAI,QAAQ,QAAW;AACrB,6BAAuB,KAAK,IAAI;AAChC;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,oBAAoB,OAAO,OAAO,MAAM,GAAG;AACjE,QAAI,CAAC,SAAS;AAIZ,6BAAuB,KAAK,IAAI;AAChC;AAAA,IACF;AACA,QAAI,QAAQ,SAAS,KAAM;AAE3B,UAAM,QAA6B;AAAA,MACjC,YAAY,QAAQ,cAAc,MAAM;AAAA,MACxC,aAAa,QAAQ;AAAA,IACvB;AACA,gBAAY,IAAI,IAAI,QAAQ,aAAa,SAAY,EAAE,GAAG,OAAO,UAAU,QAAQ,SAAS,IAAI;AAAA,EAClG;AAEA,QAAM,gBAAgB,MAAM,qBAAqB,WAAW;AAC5D,QAAM,WAA2B,EAAE,GAAG,GAAG,MAAM,UAAU,YAAY,MAAM,sBAAsB,aAAa,cAAc;AAC5H,SAAO,EAAE,UAAU,uBAAuB;AAC5C;","names":[]}