@noy-db/hub 0.4.0-pre.4 → 0.4.0-pre.6

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 (470) hide show
  1. package/README.md +2 -2
  2. package/dist/api-5QVQX4HG.js +20 -0
  3. package/dist/attestation/index.js +18 -18
  4. package/dist/{backup-JL2GOTYQ.js → backup-USYSNCYM.js} +11 -11
  5. package/dist/blobs/index.js +15 -12
  6. package/dist/blobs/index.js.map +1 -1
  7. package/dist/broker/index.js +12 -12
  8. package/dist/cargo/index.js +34 -36
  9. package/dist/{chunk-JLHKBAFY.js → chunk-2BVW754E.js} +3 -3
  10. package/dist/{chunk-T7S4V52L.js → chunk-2PDBYF2O.js} +4 -4
  11. package/dist/{chunk-YGBIBOCR.js → chunk-2ZSC454H.js} +7 -7
  12. package/dist/{chunk-IGAIOGCN.js → chunk-32467U5J.js} +4 -4
  13. package/dist/{chunk-JA5O7UEZ.js → chunk-3GXDB3NQ.js} +6 -6
  14. package/dist/chunk-3GXDB3NQ.js.map +1 -0
  15. package/dist/{chunk-U73LHVPF.js → chunk-3S2YNMUS.js} +54 -6
  16. package/dist/chunk-3S2YNMUS.js.map +1 -0
  17. package/dist/{chunk-JW3XCZA2.js → chunk-3TZUC4WS.js} +11 -11
  18. package/dist/{chunk-JA5B3SLH.js → chunk-44Y3P5U6.js} +2 -2
  19. package/dist/{chunk-25G7U6RD.js → chunk-4B3DL75F.js} +2 -2
  20. package/dist/{chunk-L4OA7G5T.js → chunk-522MBPE5.js} +2 -2
  21. package/dist/chunk-5ABOFAHN.js +81 -0
  22. package/dist/chunk-5ABOFAHN.js.map +1 -0
  23. package/dist/chunk-5D2ALSM5.js +19 -0
  24. package/dist/chunk-5D2ALSM5.js.map +1 -0
  25. package/dist/{chunk-M25ZIEB2.js → chunk-5HSSTOOG.js} +2 -2
  26. package/dist/{chunk-LLVW4V7R.js → chunk-5WLDZZ6S.js} +3 -3
  27. package/dist/{chunk-BCOKZC4B.js → chunk-6SSWOUUS.js} +19 -19
  28. package/dist/chunk-6SSWOUUS.js.map +1 -0
  29. package/dist/{chunk-IGM563N5.js → chunk-6SYOHUHM.js} +6 -6
  30. package/dist/chunk-6SYOHUHM.js.map +1 -0
  31. package/dist/{chunk-7B4GPCX7.js → chunk-7IQWHYL2.js} +5 -5
  32. package/dist/{chunk-J3VW4J4E.js → chunk-7LP7FFJ2.js} +2 -2
  33. package/dist/chunk-7LP7FFJ2.js.map +1 -0
  34. package/dist/{chunk-5P5AAXYA.js → chunk-7U6AB7DZ.js} +7 -7
  35. package/dist/chunk-7U6AB7DZ.js.map +1 -0
  36. package/dist/chunk-AFHQATY4.js +47 -0
  37. package/dist/chunk-AFHQATY4.js.map +1 -0
  38. package/dist/{chunk-OWE4BNTM.js → chunk-AZXEOEQK.js} +4 -4
  39. package/dist/{chunk-GBEXTC6Z.js → chunk-BAAUFCJK.js} +3 -3
  40. package/dist/chunk-BAAUFCJK.js.map +1 -0
  41. package/dist/{chunk-BZEPJJOK.js → chunk-C2V7AJO2.js} +4 -4
  42. package/dist/chunk-CADUYBQD.js +151 -0
  43. package/dist/chunk-CADUYBQD.js.map +1 -0
  44. package/dist/{chunk-2JZ763FV.js → chunk-D4LAJ737.js} +2 -2
  45. package/dist/{chunk-5BHNQNBI.js → chunk-DOZFU7OZ.js} +1 -1
  46. package/dist/chunk-DOZFU7OZ.js.map +1 -0
  47. package/dist/{chunk-MEKAMERX.js → chunk-E7FSBI6I.js} +29 -29
  48. package/dist/chunk-E7FSBI6I.js.map +1 -0
  49. package/dist/{chunk-N4FZ6ITM.js → chunk-EGU4PWQW.js} +2 -2
  50. package/dist/chunk-EP5L47XV.js +22 -0
  51. package/dist/chunk-EP5L47XV.js.map +1 -0
  52. package/dist/{chunk-EW4HFWGJ.js → chunk-EPME33Y4.js} +6 -6
  53. package/dist/{chunk-W7TCXZWU.js → chunk-EWPS35AR.js} +794 -1045
  54. package/dist/chunk-EWPS35AR.js.map +1 -0
  55. package/dist/{chunk-JKWNG3TM.js → chunk-FHHYCBBP.js} +2 -2
  56. package/dist/{chunk-5BB3N4KU.js → chunk-G4MFQXYX.js} +2 -2
  57. package/dist/{chunk-KVHWEPT2.js → chunk-GHEMAVTN.js} +2 -2
  58. package/dist/{chunk-CGPO3ZYB.js → chunk-GQT6J4FJ.js} +15 -2
  59. package/dist/chunk-GQT6J4FJ.js.map +1 -0
  60. package/dist/{chunk-XW7NWO4A.js → chunk-GTNRMJYH.js} +2 -2
  61. package/dist/{chunk-YG2EG6CB.js → chunk-H5GMROCB.js} +4 -4
  62. package/dist/{chunk-JIMEB4C6.js → chunk-HA7P3BTB.js} +26 -177
  63. package/dist/chunk-HA7P3BTB.js.map +1 -0
  64. package/dist/{chunk-5KI3REO3.js → chunk-HDF5R2K6.js} +7 -7
  65. package/dist/{chunk-V3YB7RGR.js → chunk-HVPW6PCX.js} +3 -3
  66. package/dist/{chunk-2VUISNGP.js → chunk-HXVRRJBD.js} +5 -5
  67. package/dist/{chunk-ZJGZDOQO.js → chunk-ICYC5YNI.js} +6 -6
  68. package/dist/{chunk-KR5EGWI4.js → chunk-IUATR5UE.js} +27 -5
  69. package/dist/chunk-IUATR5UE.js.map +1 -0
  70. package/dist/{chunk-AFBJHD55.js → chunk-JGOKAZNB.js} +5 -5
  71. package/dist/{chunk-XGVDLQJE.js → chunk-JOCMXSR2.js} +3 -3
  72. package/dist/{chunk-XGVDLQJE.js.map → chunk-JOCMXSR2.js.map} +1 -1
  73. package/dist/{chunk-HGVFJL63.js → chunk-JTIPVW4J.js} +15 -5
  74. package/dist/{chunk-HGVFJL63.js.map → chunk-JTIPVW4J.js.map} +1 -1
  75. package/dist/{chunk-QXPOEAKR.js → chunk-KCZAFDP5.js} +2 -2
  76. package/dist/{chunk-MSO2C3KG.js → chunk-LC7DSMHR.js} +2 -2
  77. package/dist/{chunk-OVFCAS7U.js → chunk-LG2GUYRX.js} +9 -9
  78. package/dist/{chunk-2KL6NDD4.js → chunk-LN3MQFUE.js} +56 -4
  79. package/dist/chunk-LN3MQFUE.js.map +1 -0
  80. package/dist/{chunk-QUIG6BZT.js → chunk-M4GO4ZJK.js} +226 -36
  81. package/dist/chunk-M4GO4ZJK.js.map +1 -0
  82. package/dist/{chunk-QDNVHA2F.js → chunk-M7W2KYTL.js} +2 -2
  83. package/dist/{chunk-XULHFSHO.js → chunk-MLCTPWSO.js} +5 -5
  84. package/dist/chunk-MLCTPWSO.js.map +1 -0
  85. package/dist/{chunk-PEY6ZTCF.js → chunk-MMVQ3SUO.js} +9 -9
  86. package/dist/{chunk-PEY6ZTCF.js.map → chunk-MMVQ3SUO.js.map} +1 -1
  87. package/dist/{chunk-4X6DJZHY.js → chunk-MPPWL64H.js} +26 -43
  88. package/dist/chunk-MPPWL64H.js.map +1 -0
  89. package/dist/{chunk-QYJIOWKN.js → chunk-MQBFT2OT.js} +11 -9
  90. package/dist/chunk-MQBFT2OT.js.map +1 -0
  91. package/dist/{chunk-IUIVDVXM.js → chunk-MUPZ6IZX.js} +2 -2
  92. package/dist/{chunk-GZ2GKOF6.js → chunk-NA374QG7.js} +3 -3
  93. package/dist/chunk-NIKO2BBZ.js +23 -0
  94. package/dist/chunk-NIKO2BBZ.js.map +1 -0
  95. package/dist/{chunk-2U7Y7BNJ.js → chunk-ONB627HU.js} +2 -2
  96. package/dist/{chunk-GYB2QK5H.js → chunk-OWLZONGX.js} +2 -2
  97. package/dist/{chunk-YHPUDB7Q.js → chunk-OWOT7CFC.js} +2 -2
  98. package/dist/{chunk-VEX6G3YL.js → chunk-P4NUJVWL.js} +2 -2
  99. package/dist/chunk-PEOZ34EM.js +13 -0
  100. package/dist/chunk-PEOZ34EM.js.map +1 -0
  101. package/dist/{chunk-NM4LVUXH.js → chunk-PTT2NB46.js} +2 -2
  102. package/dist/chunk-PVEWA2DU.js +23 -0
  103. package/dist/chunk-PVEWA2DU.js.map +1 -0
  104. package/dist/{chunk-2ITLQZV5.js → chunk-PWWWMRT7.js} +2 -2
  105. package/dist/{chunk-FLHOTGOO.js → chunk-QVGEVZ5F.js} +3 -3
  106. package/dist/{chunk-HKR25MGX.js → chunk-QVIZDLAR.js} +10 -10
  107. package/dist/chunk-QVIZDLAR.js.map +1 -0
  108. package/dist/{chunk-OOTTXUNV.js → chunk-RM5EXCFF.js} +2 -2
  109. package/dist/{chunk-OOTTXUNV.js.map → chunk-RM5EXCFF.js.map} +1 -1
  110. package/dist/{chunk-OGFPMCSP.js → chunk-SBOHNJUD.js} +2 -2
  111. package/dist/{chunk-EDC6MLXV.js → chunk-SEU6QHH4.js} +2 -2
  112. package/dist/chunk-SMY5X46Z.js +14 -0
  113. package/dist/chunk-SMY5X46Z.js.map +1 -0
  114. package/dist/{chunk-F4COUZLL.js → chunk-TMR64XPL.js} +2 -2
  115. package/dist/{chunk-5OZCCLNC.js → chunk-TSNRZSRC.js} +2 -2
  116. package/dist/{chunk-2RMDVWGB.js → chunk-UNREYBZO.js} +2 -2
  117. package/dist/{chunk-BLB7P7LS.js → chunk-V2R2VWER.js} +176 -17
  118. package/dist/chunk-V2R2VWER.js.map +1 -0
  119. package/dist/{chunk-3XVOLB75.js → chunk-VDTWFN2P.js} +7 -5
  120. package/dist/chunk-VDTWFN2P.js.map +1 -0
  121. package/dist/chunk-VKQCVU2Z.js +21 -0
  122. package/dist/chunk-VKQCVU2Z.js.map +1 -0
  123. package/dist/{chunk-QCUH2G77.js → chunk-VNJMLOQS.js} +6 -6
  124. package/dist/{chunk-UEO5CHOP.js → chunk-WCJJQV2D.js} +13 -13
  125. package/dist/chunk-WCJJQV2D.js.map +1 -0
  126. package/dist/{chunk-25ZDB25Z.js → chunk-WWBC4KLB.js} +3 -3
  127. package/dist/chunk-WWBC4KLB.js.map +1 -0
  128. package/dist/{chunk-V7RGFJ3Z.js → chunk-XG7OZDOS.js} +6 -6
  129. package/dist/{chunk-GS3Q2KOZ.js → chunk-XONZGK6J.js} +2 -2
  130. package/dist/{chunk-5SZ24DL5.js → chunk-XSOGLHGY.js} +6 -6
  131. package/dist/{chunk-CCT4WZI6.js → chunk-XY6MNSAF.js} +5 -5
  132. package/dist/chunk-XY6MNSAF.js.map +1 -0
  133. package/dist/chunk-XZHEOSQ2.js +16 -0
  134. package/dist/chunk-XZHEOSQ2.js.map +1 -0
  135. package/dist/{chunk-NOT7XA7Q.js → chunk-YGMREQAK.js} +5 -5
  136. package/dist/{chunk-H4SMS4O2.js → chunk-YJ3TREAC.js} +2 -2
  137. package/dist/chunk-YMUFFJCO.js +23 -0
  138. package/dist/chunk-YMUFFJCO.js.map +1 -0
  139. package/dist/{chunk-E2R5NRZD.js → chunk-Z4D3YGAB.js} +2 -2
  140. package/dist/{chunk-WJDYZP3U.js → chunk-ZDFU34XY.js} +42 -39
  141. package/dist/chunk-ZDFU34XY.js.map +1 -0
  142. package/dist/{chunk-BZK6JEX4.js → chunk-ZF572E2M.js} +5 -5
  143. package/dist/{chunk-DEQ2JTBR.js → chunk-ZGEFBDPR.js} +4 -4
  144. package/dist/chunk-ZGEFBDPR.js.map +1 -0
  145. package/dist/{chunk-QAFWRGVD.js → chunk-ZHMUFYZF.js} +7 -7
  146. package/dist/{chunk-BVZGNMVM.js → chunk-ZHZ4PET5.js} +3 -3
  147. package/dist/{chunk-IZX3WZBF.js → chunk-ZM72UO3Y.js} +4 -4
  148. package/dist/{chunk-STR7WBOB.js → chunk-ZUDAK436.js} +2 -2
  149. package/dist/{chunk-ITI3SJRB.js → chunk-ZX5FNWH7.js} +2 -2
  150. package/dist/classified/index.js +5 -5
  151. package/dist/{classified-marker-7S5IEP6Q.js → classified-marker-SVDRXLD3.js} +3 -3
  152. package/dist/collection-facade-S5PPKZD5.js +44 -0
  153. package/dist/{computed-WZNKRLCY.js → computed-33DRJDOC.js} +3 -3
  154. package/dist/consent/index.js +13 -9
  155. package/dist/consent/index.js.map +1 -1
  156. package/dist/{cover-B5MY43CK.js → cover-ADBCTIKN.js} +4 -4
  157. package/dist/crdt/index.js +4 -0
  158. package/dist/crdt/index.js.map +1 -1
  159. package/dist/{dead-filter-KRRD57MR.js → dead-filter-HKDMTMVY.js} +2 -2
  160. package/dist/delegation-EV7LKJPH.js +25 -0
  161. package/dist/derivations/index.js +12 -12
  162. package/dist/derive-5LDJW76F.js +21 -0
  163. package/dist/dispatch-SPMYNXNW.js +194 -0
  164. package/dist/dispatch-SPMYNXNW.js.map +1 -0
  165. package/dist/dispatch-V5MSMQYX.js +72 -0
  166. package/dist/dispatch-V5MSMQYX.js.map +1 -0
  167. package/dist/{enclave-YFKA3GJT.js → enclave-ZA7C3H2L.js} +11 -11
  168. package/dist/executor-FCJEH3FU.js +9 -0
  169. package/dist/executor-OHET7TF7.js +9 -0
  170. package/dist/executor-SVHAJZ4A.js +28 -0
  171. package/dist/export-accessible-S35YKIBL.js +23 -0
  172. package/dist/extract-partition-UVHAM5WZ.js +38 -0
  173. package/dist/{fanout-sidecar-HJV3A7PM.js → fanout-sidecar-HRMHC34B.js} +9 -9
  174. package/dist/find-LEBUXVL7.js +11 -0
  175. package/dist/forget/index.js +9 -9
  176. package/dist/guards/index.js +3 -3
  177. package/dist/history/index.js +16 -12
  178. package/dist/history/index.js.map +1 -1
  179. package/dist/i18n/index.js +16 -14
  180. package/dist/i18n/index.js.map +1 -1
  181. package/dist/index.d.ts +17 -16
  182. package/dist/index.js +155 -211
  183. package/dist/index.js.map +1 -1
  184. package/dist/indexing/index.js +4 -2
  185. package/dist/indexing/index.js.map +1 -1
  186. package/dist/issue-5X3SMCF4.js +19 -0
  187. package/dist/kernel/collection.d.ts +0 -1
  188. package/dist/kernel/enclave/crypto.d.ts +8 -8
  189. package/dist/kernel/enclave/index.d.ts +2 -2
  190. package/dist/kernel/errors.d.ts +20 -20
  191. package/dist/kernel/lazy.d.ts +30 -0
  192. package/dist/kernel/noydb.d.ts +53 -101
  193. package/dist/kernel/query/builder.d.ts +10 -10
  194. package/dist/kernel/query/index.d.ts +0 -6
  195. package/dist/kernel/query/scan-builder.d.ts +4 -4
  196. package/dist/kernel/types.d.ts +87 -46
  197. package/dist/kernel/validation.d.ts +33 -33
  198. package/dist/kernel/vault.d.ts +12 -149
  199. package/dist/kernel/via/dispatch.d.ts +7 -0
  200. package/dist/{ledger-SW6QQOAV.js → ledger-K6JBFL3Z.js} +11 -11
  201. package/dist/liberate-NHTCKBU4.js +24 -0
  202. package/dist/{link-set-GNGGCFI4.js → link-set-XVZY2ODC.js} +11 -11
  203. package/dist/materialized-views/index.js +22 -19
  204. package/dist/noydb-TI3RFU6M.js +78 -0
  205. package/dist/overlay-views/index.js +4 -4
  206. package/dist/periods/index.js +15 -13
  207. package/dist/pod/index.js +11 -12
  208. package/dist/{policy-EAXSJNOT.js → policy-QWGJB7P7.js} +5 -5
  209. package/dist/port/with/collection-options.d.ts +171 -0
  210. package/dist/port/with/collection-registries.d.ts +62 -0
  211. package/dist/port/with/strategies.d.ts +2 -2
  212. package/dist/port/with/team-strategy.d.ts +3 -2
  213. package/dist/portability/index.js +8 -8
  214. package/dist/{post-register-A7HCFBP5.js → post-register-5VHHVFJY.js} +6 -6
  215. package/dist/query/index.js +6 -46
  216. package/dist/{aggregate → reduce}/index.js +24 -17
  217. package/dist/reduce/index.js.map +1 -0
  218. package/dist/register-CEX7R7NE.js +23 -0
  219. package/dist/registry-7CZWF3EQ.js +9 -0
  220. package/dist/registry-DIKMRXUC.js +19 -0
  221. package/dist/registry-EWIB5NTI.js +18 -0
  222. package/dist/request-withdrawal-AAG57QO4.js +31 -0
  223. package/dist/{reveal-PB3YG544.js → reveal-7OOT5XPD.js} +6 -6
  224. package/dist/revoke-U5LCIJMF.js +24 -0
  225. package/dist/satellites/index.js +1 -1
  226. package/dist/sealed-record/index.js +12 -12
  227. package/dist/{seed-EKF4DIBB.js → seed-GVOI6QP6.js} +12 -12
  228. package/dist/seed-GVOI6QP6.js.map +1 -0
  229. package/dist/session/index.js +13 -9
  230. package/dist/session/index.js.map +1 -1
  231. package/dist/shadow/index.js +6 -2
  232. package/dist/shadow/index.js.map +1 -1
  233. package/dist/signer-NAA2OX7H.js +25 -0
  234. package/dist/snapshots/index.js +14 -10
  235. package/dist/snapshots/index.js.map +1 -1
  236. package/dist/{stale-4UNPHWOU.js → stale-BJO2WIN7.js} +11 -10
  237. package/dist/storage-FL7XXZTN.js +23 -0
  238. package/dist/{store-coordination-provider-3AELCZ4Y.js → store-coordination-provider-DX5HECK3.js} +3 -3
  239. package/dist/sync/index.js +14 -10
  240. package/dist/sync/index.js.map +1 -1
  241. package/dist/team/index.js +26 -28
  242. package/dist/tiers/index.js +10 -10
  243. package/dist/to/index.js +1 -1
  244. package/dist/tx/index.js +7 -3
  245. package/dist/tx/index.js.map +1 -1
  246. package/dist/util/index.js +1 -1
  247. package/dist/{verify-MXN66IIH.js → verify-5X37OXRY.js} +5 -5
  248. package/dist/via/blob/index.d.ts +2 -0
  249. package/dist/via/i18n/core.d.ts +1 -1
  250. package/dist/via/i18n/index.d.ts +2 -0
  251. package/dist/via/money/money-reducer.d.ts +2 -2
  252. package/dist/{walk-H4YE52S2.js → walk-JXMWKKQW.js} +11 -11
  253. package/dist/with-audit/consent/index.d.ts +2 -0
  254. package/dist/with-audit/periods/index.d.ts +2 -0
  255. package/dist/with-audit/portability/export-accessible.d.ts +4 -4
  256. package/dist/with-audit/portability/request-withdrawal.d.ts +3 -3
  257. package/dist/with-audit/portability/withdraw-accessible.d.ts +2 -2
  258. package/dist/with-audit/sealed-record/strategy.d.ts +1 -1
  259. package/dist/with-cargo/adopt-partition.d.ts +7 -7
  260. package/dist/with-cargo/floor.d.ts +3 -3
  261. package/dist/with-cargo/index.d.ts +1 -1
  262. package/dist/with-commit/crdt/index.d.ts +2 -0
  263. package/dist/with-commit/history/index.d.ts +2 -0
  264. package/dist/with-commit/history/time-machine.d.ts +2 -2
  265. package/dist/with-fork/shadow/index.d.ts +2 -0
  266. package/dist/with-fork/snapshots/index.d.ts +2 -0
  267. package/dist/with-formula/derivations/dispatch.d.ts +98 -0
  268. package/dist/with-formula/materialized-views/dispatch.d.ts +75 -0
  269. package/dist/with-formula/materialized-views/types.d.ts +7 -7
  270. package/dist/with-lookup/indexing/index.d.ts +2 -0
  271. package/dist/with-lookup/{aggregate → reduce}/active.d.ts +8 -8
  272. package/dist/with-lookup/{aggregate → reduce}/groupby.d.ts +21 -21
  273. package/dist/with-lookup/reduce/index.d.ts +34 -0
  274. package/dist/with-lookup/{aggregate → reduce}/reducers.d.ts +10 -10
  275. package/dist/with-lookup/{aggregate/aggregation.d.ts → reduce/reduction.d.ts} +21 -21
  276. package/dist/with-lookup/{aggregate → reduce}/strategy.d.ts +15 -15
  277. package/dist/with-party/custody/liberate.d.ts +3 -3
  278. package/dist/with-party/session/dev-unlock.d.ts +2 -2
  279. package/dist/with-party/session/index.d.ts +2 -0
  280. package/dist/with-party/session/session.d.ts +2 -2
  281. package/dist/with-party/sync/index.d.ts +2 -0
  282. package/dist/with-party/team/deed.d.ts +8 -8
  283. package/dist/with-party/team/index.d.ts +2 -2
  284. package/dist/with-party/team/keyring.d.ts +39 -20
  285. package/dist/with-party/team/{managed-passphrase.d.ts → managed-secret.d.ts} +27 -27
  286. package/dist/with-party/team/noydb-facade.d.ts +43 -42
  287. package/dist/with-party/team/peer-recover.d.ts +13 -13
  288. package/dist/with-party/team/recovery.d.ts +5 -5
  289. package/dist/with-party/team/rotate-recover.d.ts +30 -30
  290. package/dist/with-pod/bundle.d.ts +30 -30
  291. package/dist/with-pod/format.d.ts +2 -2
  292. package/dist/withdraw-accessible-GO6KQJVM.js +28 -0
  293. package/package.json +6 -34
  294. package/dist/aggregate/index.js.map +0 -1
  295. package/dist/api-UPAT2O3M.js +0 -20
  296. package/dist/as/index.js +0 -30
  297. package/dist/at/index.js +0 -1
  298. package/dist/by/index.js +0 -11
  299. package/dist/chunk-25ZDB25Z.js.map +0 -1
  300. package/dist/chunk-2KL6NDD4.js.map +0 -1
  301. package/dist/chunk-2YELV6TV.js +0 -1
  302. package/dist/chunk-3O62PVDW.js +0 -205
  303. package/dist/chunk-3O62PVDW.js.map +0 -1
  304. package/dist/chunk-3XVOLB75.js.map +0 -1
  305. package/dist/chunk-4X6DJZHY.js.map +0 -1
  306. package/dist/chunk-5BHNQNBI.js.map +0 -1
  307. package/dist/chunk-5P5AAXYA.js.map +0 -1
  308. package/dist/chunk-BCOKZC4B.js.map +0 -1
  309. package/dist/chunk-BLB7P7LS.js.map +0 -1
  310. package/dist/chunk-CCT4WZI6.js.map +0 -1
  311. package/dist/chunk-CGPO3ZYB.js.map +0 -1
  312. package/dist/chunk-DEQ2JTBR.js.map +0 -1
  313. package/dist/chunk-GBEXTC6Z.js.map +0 -1
  314. package/dist/chunk-HKR25MGX.js.map +0 -1
  315. package/dist/chunk-IGM563N5.js.map +0 -1
  316. package/dist/chunk-J3VW4J4E.js.map +0 -1
  317. package/dist/chunk-JA5O7UEZ.js.map +0 -1
  318. package/dist/chunk-JIMEB4C6.js.map +0 -1
  319. package/dist/chunk-KMONEHDJ.js +0 -54
  320. package/dist/chunk-KMONEHDJ.js.map +0 -1
  321. package/dist/chunk-KR5EGWI4.js.map +0 -1
  322. package/dist/chunk-LB7FD65R.js +0 -163
  323. package/dist/chunk-LB7FD65R.js.map +0 -1
  324. package/dist/chunk-MEKAMERX.js.map +0 -1
  325. package/dist/chunk-QUIG6BZT.js.map +0 -1
  326. package/dist/chunk-QYJIOWKN.js.map +0 -1
  327. package/dist/chunk-U73LHVPF.js.map +0 -1
  328. package/dist/chunk-UEO5CHOP.js.map +0 -1
  329. package/dist/chunk-W7TCXZWU.js.map +0 -1
  330. package/dist/chunk-WEC3JGBA.js +0 -255
  331. package/dist/chunk-WEC3JGBA.js.map +0 -1
  332. package/dist/chunk-WJDYZP3U.js.map +0 -1
  333. package/dist/chunk-XULHFSHO.js.map +0 -1
  334. package/dist/collection-facade-CMZGQ6IS.js +0 -44
  335. package/dist/delegation-UT76AQIG.js +0 -25
  336. package/dist/derive-SGRCCKVP.js +0 -21
  337. package/dist/executor-TEZYRDN3.js +0 -9
  338. package/dist/executor-WQQRU6DO.js +0 -9
  339. package/dist/executor-YORMIBWV.js +0 -26
  340. package/dist/export-accessible-HXMKW5LJ.js +0 -23
  341. package/dist/extract-partition-QGQ2R42J.js +0 -38
  342. package/dist/find-VV6PBIHK.js +0 -11
  343. package/dist/in/index.js +0 -1
  344. package/dist/issue-7JJ4Z7E2.js +0 -19
  345. package/dist/liberate-FK7JI2QX.js +0 -24
  346. package/dist/noydb-N5IW6OFZ.js +0 -70
  347. package/dist/on/index.js +0 -17
  348. package/dist/port/as/index.d.ts +0 -26
  349. package/dist/port/at/index.d.ts +0 -18
  350. package/dist/port/in/index.d.ts +0 -21
  351. package/dist/port/on/index.d.ts +0 -27
  352. package/dist/port/ui/index.d.ts +0 -21
  353. package/dist/port/with/index.d.ts +0 -18
  354. package/dist/register-YBMRLZLO.js +0 -23
  355. package/dist/registry-3LXKNXWI.js +0 -9
  356. package/dist/registry-4V4YQCXJ.js +0 -19
  357. package/dist/registry-ZULMLCJK.js +0 -18
  358. package/dist/request-withdrawal-SEVUEUDG.js +0 -31
  359. package/dist/request-withdrawal-SEVUEUDG.js.map +0 -1
  360. package/dist/revoke-5QULL5GT.js +0 -24
  361. package/dist/revoke-5QULL5GT.js.map +0 -1
  362. package/dist/seed-EKF4DIBB.js.map +0 -1
  363. package/dist/signer-ZMH35FT4.js +0 -25
  364. package/dist/signer-ZMH35FT4.js.map +0 -1
  365. package/dist/stale-4UNPHWOU.js.map +0 -1
  366. package/dist/storage-QOZKQMID.js +0 -23
  367. package/dist/storage-QOZKQMID.js.map +0 -1
  368. package/dist/ui/index.js +0 -1
  369. package/dist/ui/index.js.map +0 -1
  370. package/dist/with/index.js +0 -31
  371. package/dist/with/index.js.map +0 -1
  372. package/dist/with-lookup/aggregate/index.d.ts +0 -23
  373. package/dist/withdraw-accessible-HPOVNG2G.js +0 -28
  374. package/dist/withdraw-accessible-HPOVNG2G.js.map +0 -1
  375. /package/dist/{api-UPAT2O3M.js.map → api-5QVQX4HG.js.map} +0 -0
  376. /package/dist/{backup-JL2GOTYQ.js.map → backup-USYSNCYM.js.map} +0 -0
  377. /package/dist/{chunk-JLHKBAFY.js.map → chunk-2BVW754E.js.map} +0 -0
  378. /package/dist/{chunk-T7S4V52L.js.map → chunk-2PDBYF2O.js.map} +0 -0
  379. /package/dist/{chunk-YGBIBOCR.js.map → chunk-2ZSC454H.js.map} +0 -0
  380. /package/dist/{chunk-IGAIOGCN.js.map → chunk-32467U5J.js.map} +0 -0
  381. /package/dist/{chunk-JW3XCZA2.js.map → chunk-3TZUC4WS.js.map} +0 -0
  382. /package/dist/{chunk-JA5B3SLH.js.map → chunk-44Y3P5U6.js.map} +0 -0
  383. /package/dist/{chunk-25G7U6RD.js.map → chunk-4B3DL75F.js.map} +0 -0
  384. /package/dist/{chunk-L4OA7G5T.js.map → chunk-522MBPE5.js.map} +0 -0
  385. /package/dist/{chunk-M25ZIEB2.js.map → chunk-5HSSTOOG.js.map} +0 -0
  386. /package/dist/{chunk-LLVW4V7R.js.map → chunk-5WLDZZ6S.js.map} +0 -0
  387. /package/dist/{chunk-7B4GPCX7.js.map → chunk-7IQWHYL2.js.map} +0 -0
  388. /package/dist/{chunk-OWE4BNTM.js.map → chunk-AZXEOEQK.js.map} +0 -0
  389. /package/dist/{chunk-BZEPJJOK.js.map → chunk-C2V7AJO2.js.map} +0 -0
  390. /package/dist/{chunk-2JZ763FV.js.map → chunk-D4LAJ737.js.map} +0 -0
  391. /package/dist/{chunk-N4FZ6ITM.js.map → chunk-EGU4PWQW.js.map} +0 -0
  392. /package/dist/{chunk-EW4HFWGJ.js.map → chunk-EPME33Y4.js.map} +0 -0
  393. /package/dist/{chunk-JKWNG3TM.js.map → chunk-FHHYCBBP.js.map} +0 -0
  394. /package/dist/{chunk-5BB3N4KU.js.map → chunk-G4MFQXYX.js.map} +0 -0
  395. /package/dist/{chunk-KVHWEPT2.js.map → chunk-GHEMAVTN.js.map} +0 -0
  396. /package/dist/{chunk-XW7NWO4A.js.map → chunk-GTNRMJYH.js.map} +0 -0
  397. /package/dist/{chunk-YG2EG6CB.js.map → chunk-H5GMROCB.js.map} +0 -0
  398. /package/dist/{chunk-5KI3REO3.js.map → chunk-HDF5R2K6.js.map} +0 -0
  399. /package/dist/{chunk-V3YB7RGR.js.map → chunk-HVPW6PCX.js.map} +0 -0
  400. /package/dist/{chunk-2VUISNGP.js.map → chunk-HXVRRJBD.js.map} +0 -0
  401. /package/dist/{chunk-ZJGZDOQO.js.map → chunk-ICYC5YNI.js.map} +0 -0
  402. /package/dist/{chunk-AFBJHD55.js.map → chunk-JGOKAZNB.js.map} +0 -0
  403. /package/dist/{chunk-QXPOEAKR.js.map → chunk-KCZAFDP5.js.map} +0 -0
  404. /package/dist/{chunk-MSO2C3KG.js.map → chunk-LC7DSMHR.js.map} +0 -0
  405. /package/dist/{chunk-OVFCAS7U.js.map → chunk-LG2GUYRX.js.map} +0 -0
  406. /package/dist/{chunk-QDNVHA2F.js.map → chunk-M7W2KYTL.js.map} +0 -0
  407. /package/dist/{chunk-IUIVDVXM.js.map → chunk-MUPZ6IZX.js.map} +0 -0
  408. /package/dist/{chunk-GZ2GKOF6.js.map → chunk-NA374QG7.js.map} +0 -0
  409. /package/dist/{chunk-2U7Y7BNJ.js.map → chunk-ONB627HU.js.map} +0 -0
  410. /package/dist/{chunk-GYB2QK5H.js.map → chunk-OWLZONGX.js.map} +0 -0
  411. /package/dist/{chunk-YHPUDB7Q.js.map → chunk-OWOT7CFC.js.map} +0 -0
  412. /package/dist/{chunk-VEX6G3YL.js.map → chunk-P4NUJVWL.js.map} +0 -0
  413. /package/dist/{chunk-NM4LVUXH.js.map → chunk-PTT2NB46.js.map} +0 -0
  414. /package/dist/{chunk-2ITLQZV5.js.map → chunk-PWWWMRT7.js.map} +0 -0
  415. /package/dist/{chunk-FLHOTGOO.js.map → chunk-QVGEVZ5F.js.map} +0 -0
  416. /package/dist/{chunk-OGFPMCSP.js.map → chunk-SBOHNJUD.js.map} +0 -0
  417. /package/dist/{chunk-EDC6MLXV.js.map → chunk-SEU6QHH4.js.map} +0 -0
  418. /package/dist/{chunk-F4COUZLL.js.map → chunk-TMR64XPL.js.map} +0 -0
  419. /package/dist/{chunk-5OZCCLNC.js.map → chunk-TSNRZSRC.js.map} +0 -0
  420. /package/dist/{chunk-2RMDVWGB.js.map → chunk-UNREYBZO.js.map} +0 -0
  421. /package/dist/{chunk-QCUH2G77.js.map → chunk-VNJMLOQS.js.map} +0 -0
  422. /package/dist/{chunk-V7RGFJ3Z.js.map → chunk-XG7OZDOS.js.map} +0 -0
  423. /package/dist/{chunk-GS3Q2KOZ.js.map → chunk-XONZGK6J.js.map} +0 -0
  424. /package/dist/{chunk-5SZ24DL5.js.map → chunk-XSOGLHGY.js.map} +0 -0
  425. /package/dist/{chunk-NOT7XA7Q.js.map → chunk-YGMREQAK.js.map} +0 -0
  426. /package/dist/{chunk-H4SMS4O2.js.map → chunk-YJ3TREAC.js.map} +0 -0
  427. /package/dist/{chunk-E2R5NRZD.js.map → chunk-Z4D3YGAB.js.map} +0 -0
  428. /package/dist/{chunk-BZK6JEX4.js.map → chunk-ZF572E2M.js.map} +0 -0
  429. /package/dist/{chunk-QAFWRGVD.js.map → chunk-ZHMUFYZF.js.map} +0 -0
  430. /package/dist/{chunk-BVZGNMVM.js.map → chunk-ZHZ4PET5.js.map} +0 -0
  431. /package/dist/{chunk-IZX3WZBF.js.map → chunk-ZM72UO3Y.js.map} +0 -0
  432. /package/dist/{chunk-STR7WBOB.js.map → chunk-ZUDAK436.js.map} +0 -0
  433. /package/dist/{chunk-ITI3SJRB.js.map → chunk-ZX5FNWH7.js.map} +0 -0
  434. /package/dist/{classified-marker-7S5IEP6Q.js.map → classified-marker-SVDRXLD3.js.map} +0 -0
  435. /package/dist/{as/index.js.map → collection-facade-S5PPKZD5.js.map} +0 -0
  436. /package/dist/{at/index.js.map → computed-33DRJDOC.js.map} +0 -0
  437. /package/dist/{by/index.js.map → cover-ADBCTIKN.js.map} +0 -0
  438. /package/dist/{dead-filter-KRRD57MR.js.map → dead-filter-HKDMTMVY.js.map} +0 -0
  439. /package/dist/{chunk-2YELV6TV.js.map → delegation-EV7LKJPH.js.map} +0 -0
  440. /package/dist/{collection-facade-CMZGQ6IS.js.map → derive-5LDJW76F.js.map} +0 -0
  441. /package/dist/{computed-WZNKRLCY.js.map → enclave-ZA7C3H2L.js.map} +0 -0
  442. /package/dist/{cover-B5MY43CK.js.map → executor-FCJEH3FU.js.map} +0 -0
  443. /package/dist/{delegation-UT76AQIG.js.map → executor-OHET7TF7.js.map} +0 -0
  444. /package/dist/{derive-SGRCCKVP.js.map → executor-SVHAJZ4A.js.map} +0 -0
  445. /package/dist/{enclave-YFKA3GJT.js.map → export-accessible-S35YKIBL.js.map} +0 -0
  446. /package/dist/{executor-TEZYRDN3.js.map → extract-partition-UVHAM5WZ.js.map} +0 -0
  447. /package/dist/{fanout-sidecar-HJV3A7PM.js.map → fanout-sidecar-HRMHC34B.js.map} +0 -0
  448. /package/dist/{executor-WQQRU6DO.js.map → find-LEBUXVL7.js.map} +0 -0
  449. /package/dist/{executor-YORMIBWV.js.map → issue-5X3SMCF4.js.map} +0 -0
  450. /package/dist/{export-accessible-HXMKW5LJ.js.map → ledger-K6JBFL3Z.js.map} +0 -0
  451. /package/dist/{extract-partition-QGQ2R42J.js.map → liberate-NHTCKBU4.js.map} +0 -0
  452. /package/dist/{find-VV6PBIHK.js.map → link-set-XVZY2ODC.js.map} +0 -0
  453. /package/dist/{in/index.js.map → noydb-TI3RFU6M.js.map} +0 -0
  454. /package/dist/{issue-7JJ4Z7E2.js.map → policy-QWGJB7P7.js.map} +0 -0
  455. /package/dist/{post-register-A7HCFBP5.js.map → post-register-5VHHVFJY.js.map} +0 -0
  456. /package/dist/{ledger-SW6QQOAV.js.map → register-CEX7R7NE.js.map} +0 -0
  457. /package/dist/{liberate-FK7JI2QX.js.map → registry-7CZWF3EQ.js.map} +0 -0
  458. /package/dist/{link-set-GNGGCFI4.js.map → registry-DIKMRXUC.js.map} +0 -0
  459. /package/dist/{noydb-N5IW6OFZ.js.map → registry-EWIB5NTI.js.map} +0 -0
  460. /package/dist/{on/index.js.map → request-withdrawal-AAG57QO4.js.map} +0 -0
  461. /package/dist/{reveal-PB3YG544.js.map → reveal-7OOT5XPD.js.map} +0 -0
  462. /package/dist/{policy-EAXSJNOT.js.map → revoke-U5LCIJMF.js.map} +0 -0
  463. /package/dist/{register-YBMRLZLO.js.map → signer-NAA2OX7H.js.map} +0 -0
  464. /package/dist/{registry-3LXKNXWI.js.map → stale-BJO2WIN7.js.map} +0 -0
  465. /package/dist/{registry-4V4YQCXJ.js.map → storage-FL7XXZTN.js.map} +0 -0
  466. /package/dist/{store-coordination-provider-3AELCZ4Y.js.map → store-coordination-provider-DX5HECK3.js.map} +0 -0
  467. /package/dist/{verify-MXN66IIH.js.map → verify-5X37OXRY.js.map} +0 -0
  468. /package/dist/{walk-H4YE52S2.js.map → walk-JXMWKKQW.js.map} +0 -0
  469. /package/dist/with-lookup/{aggregate → reduce}/canonical-key.d.ts +0 -0
  470. /package/dist/{registry-ZULMLCJK.js.map → withdraw-accessible-GO6KQJVM.js.map} +0 -0
@@ -1,205 +0,0 @@
1
- import {
2
- derivePassphraseKey
3
- } from "./chunk-5P5AAXYA.js";
4
- import {
5
- NOYDB_FORMAT_VERSION
6
- } from "./chunk-5BHNQNBI.js";
7
-
8
- // src/with-party/team/wrapped-deks.ts
9
- var PBKDF2_ITERATIONS = 6e5;
10
- var SALT_BYTES = 32;
11
- var IV_BYTES = 12;
12
- var subtle = globalThis.crypto.subtle;
13
- async function mintWrappedDeksBlob(deks, credential) {
14
- const salt = crypto.getRandomValues(new Uint8Array(SALT_BYTES));
15
- const iv = crypto.getRandomValues(new Uint8Array(IV_BYTES));
16
- const wrappingKey = await deriveWrappingKey(credential, salt);
17
- const exported = {};
18
- for (const [coll, dek] of deks) {
19
- const raw = await subtle.exportKey("raw", dek);
20
- exported[coll] = bytesToBase64(new Uint8Array(raw));
21
- }
22
- const plaintext = new TextEncoder().encode(JSON.stringify({ deks: exported }));
23
- const ciphertext = await subtle.encrypt(
24
- { name: "AES-GCM", iv },
25
- wrappingKey,
26
- plaintext
27
- );
28
- return {
29
- salt: bytesToBase64(salt),
30
- iv: bytesToBase64(iv),
31
- wrappedDeks: bytesToBase64(new Uint8Array(ciphertext))
32
- };
33
- }
34
- async function unwrapDeksFromBlob(blob, credential) {
35
- const wrappingKey = await deriveWrappingKey(credential, base64ToBytes(blob.salt));
36
- const plaintext = await subtle.decrypt(
37
- { name: "AES-GCM", iv: base64ToBytes(blob.iv) },
38
- wrappingKey,
39
- base64ToBytes(blob.wrappedDeks)
40
- );
41
- const parsed = JSON.parse(new TextDecoder().decode(plaintext));
42
- const deks = /* @__PURE__ */ new Map();
43
- for (const [coll, b64] of Object.entries(parsed.deks)) {
44
- const raw = base64ToBytes(b64);
45
- const key = await subtle.importKey(
46
- "raw",
47
- raw,
48
- { name: "AES-GCM", length: 256 },
49
- true,
50
- ["encrypt", "decrypt"]
51
- );
52
- deks.set(coll, key);
53
- }
54
- return deks;
55
- }
56
- async function deriveWrappingKey(credential, salt) {
57
- return derivePassphraseKey(credential, salt, { iterations: PBKDF2_ITERATIONS, keyUsage: "aes-gcm" });
58
- }
59
- function bytesToBase64(b) {
60
- let s = "";
61
- for (const x of b) s += String.fromCharCode(x);
62
- return btoa(s);
63
- }
64
- function base64ToBytes(b64) {
65
- const s = atob(b64);
66
- const out = new Uint8Array(s.length);
67
- for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i);
68
- return out;
69
- }
70
-
71
- // src/with-party/team/recovery.ts
72
- var PAPER_DOC_ID = "recovery-paper";
73
- async function loadPaperRecoveryEntries(store, vault) {
74
- const env = await store.get(vault, "_meta", PAPER_DOC_ID);
75
- if (!env) return [];
76
- try {
77
- const doc = JSON.parse(env._data);
78
- if (doc.profile !== "paper" || !Array.isArray(doc.entries)) return [];
79
- return doc.entries;
80
- } catch {
81
- return [];
82
- }
83
- }
84
- async function savePaperRecoveryEntries(store, vault, entries) {
85
- const doc = {
86
- _noydb_recovery: 1,
87
- profile: "paper",
88
- entries
89
- };
90
- const envelope = {
91
- _noydb: NOYDB_FORMAT_VERSION,
92
- _v: 1,
93
- _ts: (/* @__PURE__ */ new Date()).toISOString(),
94
- _iv: "",
95
- _data: JSON.stringify(doc)
96
- };
97
- await store.put(vault, "_meta", PAPER_DOC_ID, envelope);
98
- }
99
- async function burnPaperRecoveryEntry(store, vault, codeId) {
100
- const entries = await loadPaperRecoveryEntries(store, vault);
101
- const remaining = entries.filter((e) => e.codeId !== codeId);
102
- await savePaperRecoveryEntries(store, vault, remaining);
103
- }
104
- async function hasRecoveryEnrolled(store, vault) {
105
- const paper = await loadPaperRecoveryEntries(store, vault);
106
- if (paper.length > 0) return true;
107
- const shamir = await loadShamirRecoveryEntries(store, vault);
108
- return shamir.length > 0;
109
- }
110
- async function hasStrongRecoveryEnrolled(store, vault) {
111
- const shamir = await loadShamirRecoveryEntries(store, vault);
112
- return shamir.length > 0;
113
- }
114
- var SHAMIR_DOC_ID = "recovery-shamir";
115
- async function loadShamirRecoveryEntries(store, vault) {
116
- const env = await store.get(vault, "_meta", SHAMIR_DOC_ID);
117
- if (!env) return [];
118
- try {
119
- const doc = JSON.parse(env._data);
120
- if (doc.profile !== "shamir" || !Array.isArray(doc.entries)) return [];
121
- return doc.entries;
122
- } catch {
123
- return [];
124
- }
125
- }
126
- async function saveShamirRecoveryEntries(store, vault, entries) {
127
- const doc = {
128
- _noydb_recovery: 1,
129
- profile: "shamir",
130
- entries
131
- };
132
- const envelope = {
133
- _noydb: NOYDB_FORMAT_VERSION,
134
- _v: 1,
135
- _ts: (/* @__PURE__ */ new Date()).toISOString(),
136
- _iv: "",
137
- _data: JSON.stringify(doc)
138
- };
139
- await store.put(vault, "_meta", SHAMIR_DOC_ID, envelope);
140
- }
141
- async function mintShamirRecoveryEntry(provider, deks, entryId, k, n, label) {
142
- const recoverySecret = crypto.getRandomValues(new Uint8Array(32));
143
- try {
144
- const credential = bytesToBase642(recoverySecret);
145
- const blob = await mintWrappedDeksBlob(deks, credential);
146
- const shareStrings = provider.splitToShares(recoverySecret, k, n);
147
- const entry = {
148
- ...blob,
149
- entryId,
150
- k,
151
- n,
152
- enrolledAt: (/* @__PURE__ */ new Date()).toISOString(),
153
- ...label !== void 0 && { label }
154
- };
155
- return { entry, shareStrings };
156
- } finally {
157
- recoverySecret.fill(0);
158
- }
159
- }
160
- async function unwrapDeksFromShamirEntry(provider, entry, shareStrings) {
161
- if (shareStrings.length < entry.k) {
162
- throw new Error(
163
- `Insufficient shares: this Shamir entry needs ${entry.k} of ${entry.n}, but ${shareStrings.length} were provided.`
164
- );
165
- }
166
- const secret = provider.combineShares(shareStrings);
167
- try {
168
- return await unwrapDeksFromBlob(entry, bytesToBase642(secret));
169
- } finally {
170
- secret.fill(0);
171
- }
172
- }
173
- function bytesToBase642(b) {
174
- let s = "";
175
- for (const x of b) s += String.fromCharCode(x);
176
- return btoa(s);
177
- }
178
- async function mintPaperRecoveryEntry(deks, code, codeId) {
179
- const blob = await mintWrappedDeksBlob(deks, code);
180
- return {
181
- ...blob,
182
- codeId,
183
- enrolledAt: (/* @__PURE__ */ new Date()).toISOString()
184
- };
185
- }
186
- async function unwrapDeksFromPaperEntry(entry, code) {
187
- return unwrapDeksFromBlob(entry, code);
188
- }
189
-
190
- export {
191
- mintWrappedDeksBlob,
192
- unwrapDeksFromBlob,
193
- loadPaperRecoveryEntries,
194
- savePaperRecoveryEntries,
195
- burnPaperRecoveryEntry,
196
- hasRecoveryEnrolled,
197
- hasStrongRecoveryEnrolled,
198
- loadShamirRecoveryEntries,
199
- saveShamirRecoveryEntries,
200
- mintShamirRecoveryEntry,
201
- unwrapDeksFromShamirEntry,
202
- mintPaperRecoveryEntry,
203
- unwrapDeksFromPaperEntry
204
- };
205
- //# sourceMappingURL=chunk-3O62PVDW.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-party/team/wrapped-deks.ts","../src/with-party/team/recovery.ts"],"sourcesContent":["/**\n * **Wrap-DEKs primitive** — a single canonical shape for the\n * pattern of \"serialize a DEK set, encrypt it under a credential-derived\n * AES-GCM key.\" Used by:\n *\n * - **tier-0** — paper recovery entries (`_meta/recovery-paper`),\n * credential = the printed code.\n * - **tier-2** — password authenticator slots (`KeyringFile.authenticators`,\n * `wrapKind: 'deks'`), credential = the user's password.\n *\n * **Not** used by `@noy-db/on-pin` — tier-3 wraps the DEK set under\n * the same conceptual pattern but at **100,000 PBKDF2 iterations**\n * (vs the 600,000 here), because the protection window for a PIN\n * slot is short (idle-timeout-bounded, typically 15 min) and 600k\n * iterations would make every PIN-resume noticeably slow. The wire\n * formats are deliberately incompatible. See `@noy-db/on-pin`'s\n * `PIN_PBKDF2_ITERATIONS` and the threat-model rationale in its\n * module docstring.\n *\n * Previously, the same crypto lived in two places: `mintPaperRecoveryEntry`\n * (in `team/recovery.ts`) and `enrollPasswordAuthenticator` (in\n * `@noy-db/on-password`). Both functions did identical work — PBKDF2\n * the credential, AES-GCM-encrypt the JSON-serialized DEK set — but\n * their implementations had drifted apart enough that fixing a bug\n * in one wouldn't fix the other.\n *\n * This module owns the canonical implementation. Consumers compose:\n *\n * - `mintPaperRecoveryEntry` is now a thin wrapper that calls\n * `mintWrappedDeksBlob` and adds `{ codeId, enrolledAt }`.\n * - `enrollPasswordAuthenticator` calls `mintWrappedDeksBlob` and\n * wraps the result in the slot envelope.\n *\n * @module\n */\n\nimport { derivePassphraseKey, type EnclaveKey } from '../../kernel/enclave/index.js'\n\nconst PBKDF2_ITERATIONS = 600_000\nconst SALT_BYTES = 32\nconst IV_BYTES = 12\n\nconst subtle = globalThis.crypto.subtle\n\n// ─── Type ──────────────────────────────────────────────────────────────\n\n/**\n * The wrap-DEKs primitive — a serialized + AES-GCM-encrypted DEK set\n * keyed under a credential-derived key.\n *\n * All three fields are base64-encoded so the blob is JSON-safe and\n * round-trips through `_meta/*` envelopes (which carry plaintext\n * JSON in `_data`).\n *\n * Composition: `PaperRecoveryEntry extends WrappedDeksBlob` plus\n * `{ codeId, enrolledAt }`. `KeyringAuthenticatorWrappingDEKs`\n * carries the same three fields with `salt` stored in `meta` for\n * slot-format back-compat (defers moving it to top-level).\n */\nexport interface WrappedDeksBlob {\n /** Base64 PBKDF2 salt for the credential-derived wrapping key. */\n readonly salt: string\n /** Base64 AES-GCM IV used for the `wrappedDeks` ciphertext. */\n readonly iv: string\n /** Base64 AES-GCM ciphertext of `{ deks: { collection: base64rawDek } }`. */\n readonly wrappedDeks: string\n}\n\n// ─── Mint ──────────────────────────────────────────────────────────────\n\n/**\n * Mint a fresh `WrappedDeksBlob` from a DEK set + a string credential.\n *\n * Generates a random salt + IV, derives a 256-bit AES-GCM key via\n * PBKDF2-SHA256(credential, salt, 600K), serializes the DEK set as\n * `{ deks: { coll: rawBase64 } }`, and AES-GCM-encrypts.\n *\n * The `credential` is the user-typed string (recovery code, password,\n * PIN). Caller normalization rules apply (e.g. paper\n * recovery uppercase-strips the code before reaching this function).\n *\n * @param deks - DEK set to wrap. Each DEK must be exportable via\n * `subtle.exportKey('raw', dek)` (the hub mints DEKs\n * this way; consumers feeding non-extractable keys\n * will get `InvalidAccessError` from WebCrypto).\n * @param credential - String input the consumer minted (paper code,\n * password, PIN). Treated as opaque bytes by PBKDF2.\n */\nexport async function mintWrappedDeksBlob(\n deks: Map<string, EnclaveKey>,\n credential: string,\n): Promise<WrappedDeksBlob> {\n const salt = crypto.getRandomValues(new Uint8Array(SALT_BYTES))\n const iv = crypto.getRandomValues(new Uint8Array(IV_BYTES))\n const wrappingKey = await deriveWrappingKey(credential, salt)\n\n // Serialize the DEK set as JSON `{ deks: { collection: base64 } }`.\n const exported: Record<string, string> = {}\n for (const [coll, dek] of deks) {\n const raw = await subtle.exportKey('raw', dek)\n exported[coll] = bytesToBase64(new Uint8Array(raw))\n }\n const plaintext = new TextEncoder().encode(JSON.stringify({ deks: exported }))\n const ciphertext = await subtle.encrypt(\n { name: 'AES-GCM', iv: iv as BufferSource },\n wrappingKey,\n plaintext as BufferSource,\n )\n\n return {\n salt: bytesToBase64(salt),\n iv: bytesToBase64(iv),\n wrappedDeks: bytesToBase64(new Uint8Array(ciphertext)),\n }\n}\n\n// ─── Unwrap ────────────────────────────────────────────────────────────\n\n/**\n * Reverse of {@link mintWrappedDeksBlob}. Re-derives the wrapping key\n * from the credential + stored salt, AES-GCM-decrypts the wrapped DEK\n * set, and re-imports each DEK as an extractable AES-GCM CryptoKey.\n *\n * Throws (AES-GCM auth tag failure) when the credential doesn't\n * match the blob. Callers iterating over multiple blobs (e.g. paper\n * recovery's \"try every entry until one matches\") should catch.\n */\nexport async function unwrapDeksFromBlob(\n blob: WrappedDeksBlob,\n credential: string,\n): Promise<Map<string, EnclaveKey>> {\n const wrappingKey = await deriveWrappingKey(credential, base64ToBytes(blob.salt))\n const plaintext = await subtle.decrypt(\n { name: 'AES-GCM', iv: base64ToBytes(blob.iv) as BufferSource },\n wrappingKey,\n base64ToBytes(blob.wrappedDeks) as BufferSource,\n )\n const parsed = JSON.parse(new TextDecoder().decode(plaintext)) as { deks: Record<string, string> }\n const deks = new Map<string, EnclaveKey>()\n for (const [coll, b64] of Object.entries(parsed.deks)) {\n const raw = base64ToBytes(b64)\n const key = await subtle.importKey(\n 'raw',\n raw as BufferSource,\n { name: 'AES-GCM', length: 256 },\n true,\n ['encrypt', 'decrypt'],\n )\n deks.set(coll, key)\n }\n return deks\n}\n\n// ─── Internals ─────────────────────────────────────────────────────────\n\nasync function deriveWrappingKey(credential: string, salt: Uint8Array): Promise<CryptoKey> {\n return derivePassphraseKey(credential, salt, { iterations: PBKDF2_ITERATIONS, keyUsage: 'aes-gcm' })\n}\n\nfunction bytesToBase64(b: Uint8Array): string {\n let s = ''\n for (const x of b) s += String.fromCharCode(x)\n return btoa(s)\n}\n\nfunction base64ToBytes(b64: string): Uint8Array {\n const s = atob(b64)\n const out = new Uint8Array(s.length)\n for (let i = 0; i < s.length; i++) out[i] = s.charCodeAt(i)\n return out\n}\n","/**\n * Recovery profile persistence + dispatch.\n *\n * Wires the **paper** profile end-to-end through\n * `@noy-db/on-recovery`. The other three profiles (Shamir,\n * multi-channel, admin-mediated) ship the API surface and throw\n * {@link RecoveryProfileNotImplementedError} during use; per-profile\n * dispatch lands in follow-up issues.\n *\n * Storage layout:\n *\n * ```\n * _meta/recovery-paper — JSON { entries: RecoveryCodeEntry[] } produced by `on-recovery`.\n * _meta/recovery-shamir — reserved\n * _meta/recovery-multi — reserved\n * _meta/recovery-admin — reserved\n * ```\n *\n * Like `_meta/policy` and `_meta/handle`, the documents are plain JSON\n * with empty `_iv` — the recovery-code wrapping is what protects the\n * KEK; the entries themselves are inert without the user's code.\n *\n * @module\n */\nimport type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js'\nimport { NOYDB_FORMAT_VERSION } from '../../kernel/types.js'\nimport type { EnclaveKey } from '../../kernel/enclave/index.js'\nimport {\n mintWrappedDeksBlob,\n unwrapDeksFromBlob,\n type WrappedDeksBlob,\n} from './wrapped-deks.js'\nimport type { ShamirRecoveryProvider } from './shamir-recovery-provider.js'\n\n/**\n * One paper recovery code as persisted in `_meta/recovery-paper`.\n *\n * The hub's KEK is intentionally non-extractable (see `crypto.ts`),\n * so the recovery entry can't AES-KW-wrap the KEK directly. Instead\n * we wrap a serialized DEK set: the entry holds the AES-GCM\n * ciphertext of `{ deks: { collection: rawDekBase64 } }`. Recovery\n * deserializes the DEK set, then mints a fresh KEK from the new\n * passphrase and rewraps the DEKs under it.\n *\n * This is the same pattern `@noy-db/on-pin` uses for tier-3 quick\n * resume — the cryptographic guarantee is identical (AES-GCM with a\n * PBKDF2-derived key), and it sidesteps the non-extractable-KEK\n * constraint cleanly.\n *\n * Type-level composition: `PaperRecoveryEntry extends\n * WrappedDeksBlob` — the three crypto fields (`salt`, `iv`,\n * `wrappedDeks`) come from the shared primitive; `codeId` and\n * `enrolledAt` are paper-recovery's own metadata. Wire format\n * unchanged.\n */\nexport interface PaperRecoveryEntry extends WrappedDeksBlob {\n readonly codeId: string\n readonly enrolledAt: string\n}\n\nexport interface PaperRecoveryDoc {\n readonly _noydb_recovery: 1\n readonly profile: 'paper'\n readonly entries: ReadonlyArray<PaperRecoveryEntry>\n}\n\nconst PAPER_DOC_ID = 'recovery-paper'\n\n/** Read the paper-recovery entries. Returns empty array when absent. */\nexport async function loadPaperRecoveryEntries(\n store: NoydbStore,\n vault: string,\n): Promise<ReadonlyArray<PaperRecoveryEntry>> {\n const env = await store.get(vault, '_meta', PAPER_DOC_ID)\n if (!env) return []\n try {\n const doc = JSON.parse(env._data) as PaperRecoveryDoc\n if (doc.profile !== 'paper' || !Array.isArray(doc.entries)) return []\n return doc.entries\n } catch {\n return []\n }\n}\n\n/** Replace the paper-recovery entries (used after burn-on-recovery). */\nexport async function savePaperRecoveryEntries(\n store: NoydbStore,\n vault: string,\n entries: ReadonlyArray<PaperRecoveryEntry>,\n): Promise<void> {\n const doc: PaperRecoveryDoc = {\n _noydb_recovery: 1,\n profile: 'paper',\n entries,\n }\n const envelope: EncryptedEnvelope = {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: 1,\n _ts: new Date().toISOString(),\n _iv: '',\n _data: JSON.stringify(doc),\n }\n await store.put(vault, '_meta', PAPER_DOC_ID, envelope)\n}\n\n/** Drop a single paper-recovery entry (burn-on-use). */\nexport async function burnPaperRecoveryEntry(\n store: NoydbStore,\n vault: string,\n codeId: string,\n): Promise<void> {\n const entries = await loadPaperRecoveryEntries(store, vault)\n const remaining = entries.filter((e) => e.codeId !== codeId)\n await savePaperRecoveryEntries(store, vault, remaining)\n}\n\n/** Whether at least one recovery profile has any enrolled entries. */\nexport async function hasRecoveryEnrolled(\n store: NoydbStore,\n vault: string,\n): Promise<boolean> {\n const paper = await loadPaperRecoveryEntries(store, vault)\n if (paper.length > 0) return true\n const shamir = await loadShamirRecoveryEntries(store, vault)\n return shamir.length > 0\n}\n\n/**\n * Whether at least one **strong** recovery profile is enrolled.\n *\n * \"Strong\" excludes paper-alone — under managed-passphrase mode the\n * user has no memorized passphrase, so a stolen/lost paper sheet\n * would be a single point of total loss. Strong profiles today:\n *\n * - `shamir` (k-of-n threshold; survives loss of up to n-k shares)\n * - `multi-channel` (when shipped — follow-up slice)\n * - `admin-mediated` (when shipped — follow-up slice)\n *\n * Managed mode requires this check to pass before `openVault` returns.\n */\nexport async function hasStrongRecoveryEnrolled(\n store: NoydbStore,\n vault: string,\n): Promise<boolean> {\n const shamir = await loadShamirRecoveryEntries(store, vault)\n return shamir.length > 0\n // When multi-channel / admin-mediated land, extend this check.\n}\n\n// ─── Shamir recovery ─────────────────────────────────────────────────────\n\n/**\n * One Shamir-recovery entry as persisted in `_meta/recovery-shamir`.\n *\n * Like {@link PaperRecoveryEntry}, the entry composes\n * {@link WrappedDeksBlob} (DEKs wrapped under a fresh ephemeral\n * recovery secret) with profile-specific metadata. Unlike paper, the\n * \"credential\" was never visible to the user — it was 32 random\n * bytes split into N Shamir shares at enrollment. The shares ARE\n * the credential; the user holds them, the hub never sees them\n * again after `enrollRecovery` returns.\n *\n * The recovery secret is base64-encoded and\n * passed as the `credential` arg to\n * {@link mintWrappedDeksBlob} / {@link unwrapDeksFromBlob}. The\n * PBKDF2 round over high-entropy input is harmless overhead — it\n * keeps the shared primitive unchanged while letting Shamir reuse\n * the same wrapping pipeline as paper.\n */\nexport interface ShamirRecoveryEntry extends WrappedDeksBlob {\n /** Stable id for this entry. Allows multiple Shamir splits to coexist. */\n readonly entryId: string\n /** Threshold — minimum shares to reconstruct. */\n readonly k: number\n /** Total shares minted at enrollment. */\n readonly n: number\n /** x-coordinates of the n minted shares. Informational. Omitted as of 0.2\n * (string-level provider doesn't expose share x-coords); kept optional so\n * pre-0.2 entries still read. */\n readonly xCoords?: ReadonlyArray<number>\n /** ISO timestamp. */\n readonly enrolledAt: string\n /** Optional caller-supplied label (e.g., \"2-of-3 board escrow\"). */\n readonly label?: string\n}\n\nexport interface ShamirRecoveryDoc {\n readonly _noydb_recovery: 1\n readonly profile: 'shamir'\n readonly entries: ReadonlyArray<ShamirRecoveryEntry>\n}\n\nconst SHAMIR_DOC_ID = 'recovery-shamir'\n\n/** Read the Shamir-recovery entries. Returns empty array when absent. */\nexport async function loadShamirRecoveryEntries(\n store: NoydbStore,\n vault: string,\n): Promise<ReadonlyArray<ShamirRecoveryEntry>> {\n const env = await store.get(vault, '_meta', SHAMIR_DOC_ID)\n if (!env) return []\n try {\n const doc = JSON.parse(env._data) as ShamirRecoveryDoc\n if (doc.profile !== 'shamir' || !Array.isArray(doc.entries)) return []\n return doc.entries\n } catch {\n return []\n }\n}\n\n/** Replace the Shamir-recovery entries (used by enrollment and rotation). */\nexport async function saveShamirRecoveryEntries(\n store: NoydbStore,\n vault: string,\n entries: ReadonlyArray<ShamirRecoveryEntry>,\n): Promise<void> {\n const doc: ShamirRecoveryDoc = {\n _noydb_recovery: 1,\n profile: 'shamir',\n entries,\n }\n const envelope: EncryptedEnvelope = {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: 1,\n _ts: new Date().toISOString(),\n _iv: '',\n _data: JSON.stringify(doc),\n }\n await store.put(vault, '_meta', SHAMIR_DOC_ID, envelope)\n}\n\n/**\n * Mint a fresh Shamir recovery entry from a DEK set.\n *\n * 1. Generates a 32-byte recovery secret.\n * 2. Wraps the DEK set under that secret via\n * {@link mintWrappedDeksBlob} (the recovery secret is base64-\n * encoded as the credential string — PBKDF2 over high-entropy\n * input is harmless overhead).\n * 3. Splits the recovery secret via Shamir into `n` shares with\n * threshold `k`.\n * 4. Zeros the in-memory recovery secret after wrapping + splitting.\n *\n * Returns:\n * - `entry` — the {@link ShamirRecoveryEntry} to persist.\n * - `shareStrings` — the `n` Base32-encoded share strings to\n * return to the caller. The HUB MUST NOT PERSIST THESE; once\n * returned they are the user's responsibility.\n *\n * @param deks - DEK set to wrap.\n * @param entryId - Stable id for this entry (caller-supplied or\n * hub-generated).\n * @param k - Threshold (>= 2).\n * @param n - Total shares (k <= n <= 255).\n * @param label - Optional caller label.\n */\nexport async function mintShamirRecoveryEntry(\n provider: ShamirRecoveryProvider,\n deks: Map<string, EnclaveKey>,\n entryId: string,\n k: number,\n n: number,\n label?: string,\n): Promise<{ entry: ShamirRecoveryEntry; shareStrings: string[] }> {\n const recoverySecret = crypto.getRandomValues(new Uint8Array(32))\n try {\n const credential = bytesToBase64(recoverySecret)\n const blob = await mintWrappedDeksBlob(deks, credential)\n const shareStrings = provider.splitToShares(recoverySecret, k, n)\n const entry: ShamirRecoveryEntry = {\n ...blob, entryId, k, n,\n enrolledAt: new Date().toISOString(),\n ...(label !== undefined && { label }),\n }\n return { entry, shareStrings }\n } finally {\n recoverySecret.fill(0)\n }\n}\n\n/**\n * Decrypt a Shamir recovery entry to recover the raw DEK set.\n *\n * Combines K or more `shares`, reconstructs the recovery secret,\n * unwraps the DEKs via {@link unwrapDeksFromBlob}.\n *\n * Throws (AES-GCM auth-tag mismatch) when the shares don't combine\n * to the secret originally used to mint the entry — typically\n * because they came from a different enrollment or were tampered\n * with. Callers iterating multiple entries should catch.\n */\nexport async function unwrapDeksFromShamirEntry(\n provider: ShamirRecoveryProvider,\n entry: ShamirRecoveryEntry,\n shareStrings: readonly string[],\n): Promise<Map<string, EnclaveKey>> {\n if (shareStrings.length < entry.k) {\n throw new Error(\n `Insufficient shares: this Shamir entry needs ${entry.k} of ${entry.n}, `\n + `but ${shareStrings.length} were provided.`,\n )\n }\n const secret = provider.combineShares(shareStrings)\n try {\n return await unwrapDeksFromBlob(entry, bytesToBase64(secret))\n } finally {\n secret.fill(0)\n }\n}\n\nfunction bytesToBase64(b: Uint8Array): string {\n let s = ''\n for (const x of b) s += String.fromCharCode(x)\n return btoa(s)\n}\n\n/**\n * Generate one paper-recovery entry from an unlocked DEK set.\n *\n * Returns the serializable entry (persisted via\n * {@link savePaperRecoveryEntries}). The recovery flow unwraps the\n * DEK set, then mints a fresh KEK from the user's new passphrase.\n *\n * Thin wrapper over {@link mintWrappedDeksBlob} — the crypto\n * lives in the shared primitive; this function just adds paper-\n * recovery's own metadata (`codeId`, `enrolledAt`).\n *\n * @param deks Map of collection-name → DEK (extractable).\n * @param code The plaintext recovery code (caller-supplied;\n * pair this with `@noy-db/on-recovery`'s code\n * generator/parser if available).\n * @param codeId Stable id used by `burnPaperRecoveryEntry`.\n */\nexport async function mintPaperRecoveryEntry(\n deks: Map<string, EnclaveKey>,\n code: string,\n codeId: string,\n): Promise<PaperRecoveryEntry> {\n const blob = await mintWrappedDeksBlob(deks, code)\n return {\n ...blob,\n codeId,\n enrolledAt: new Date().toISOString(),\n }\n}\n\n/**\n * Decrypt a recovery entry to recover the raw DEK set. Used by the\n * `recoverPassphrase` flow after the user's code has been parsed.\n *\n * Thin wrapper over {@link unwrapDeksFromBlob}.\n *\n * @throws when the code does not match the entry (AES-GCM auth tag fail).\n */\nexport async function unwrapDeksFromPaperEntry(\n entry: PaperRecoveryEntry,\n code: string,\n): Promise<Map<string, EnclaveKey>> {\n return unwrapDeksFromBlob(entry, code)\n}\n\n// The crypto helpers (deriveRecoveryWrappingKey, bytesToBase64,\n// base64ToBytes) live in the canonical wrap-DEKs primitive at\n// `./wrapped-deks.ts` and are reached via\n// `mintWrappedDeksBlob` / `unwrapDeksFromBlob`.\n"],"mappings":"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","names":["bytesToBase64"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/with-formula/materialized-views/stale.ts"],"sourcesContent":["import type { Collection } from '../../kernel/collection.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 { MaterializedViewExecutor as MVExecutorType } from './executor.js'\nimport type { MVQueryContext } from './types.js'\nimport type { NoydbStore } from '../../kernel/types.js'\nimport { RecordCodec } from '../../kernel/enclave/index.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({ 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 if (executor === null) {\n ({ MaterializedViewExecutor: executor } = (await import('./executor.js')) as {\n MaterializedViewExecutor: typeof MVExecutorType\n })\n }\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":[]}