@noy-db/hub 0.10.0-pre.0 → 0.10.0-pre.2

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 (492) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +2 -2
  3. package/dist/api-QSEKT4KS.js +15 -0
  4. package/dist/as/index.js +19 -12
  5. package/dist/as/index.js.map +1 -1
  6. package/dist/at/index.js +6 -9
  7. package/dist/attestation/index.js +16 -19
  8. package/dist/attestation/index.js.map +1 -1
  9. package/dist/{backup-E3GBMNDA.js → backup-BHKVK5SD.js} +9 -12
  10. package/dist/{backup-E3GBMNDA.js.map → backup-BHKVK5SD.js.map} +1 -1
  11. package/dist/blobs/index.js +10 -13
  12. package/dist/blobs/index.js.map +1 -1
  13. package/dist/broker/index.js +11 -14
  14. package/dist/broker/index.js.map +1 -1
  15. package/dist/by/index.js +2 -2
  16. package/dist/capsule/contract.d.ts +176 -16
  17. package/dist/capsule/contract.js +35 -30
  18. package/dist/capsule/enclave-aes/bound.d.ts +11 -1
  19. package/dist/capsule/enclave-aes/classify/digest.d.ts +4 -2
  20. package/dist/capsule/enclave-aes/index.d.ts +9 -0
  21. package/dist/capsule/enclave-aes/index.js +643 -78
  22. package/dist/capsule/enclave-aes/index.js.map +1 -1
  23. package/dist/capsule/enclave-aes/primitives.d.ts +2 -2
  24. package/dist/capsule/index.d.ts +1 -1
  25. package/dist/capsule/plumbing/classify-reveal.d.ts +29 -0
  26. package/dist/capsule/plumbing/classify-verify.d.ts +53 -0
  27. package/dist/capsule/plumbing/index.d.ts +17 -0
  28. package/dist/{capsule-YQKQZPH7.js → capsule-YAITMH77.js} +16 -9
  29. package/dist/cargo/index.js +34 -36
  30. package/dist/{chunk-U43RSPPX.js → chunk-23A4SBRR.js} +3 -4
  31. package/dist/{chunk-U43RSPPX.js.map → chunk-23A4SBRR.js.map} +1 -1
  32. package/dist/{chunk-PREYKC76.js → chunk-24AGG4PP.js} +3 -3
  33. package/dist/{chunk-ZVJKHGE5.js → chunk-24IJZA4M.js} +14 -8
  34. package/dist/chunk-24IJZA4M.js.map +1 -0
  35. package/dist/{chunk-4N4OIVK3.js → chunk-2NVQ5SEA.js} +15 -5
  36. package/dist/chunk-2NVQ5SEA.js.map +1 -0
  37. package/dist/{chunk-ZNVBCKMV.js → chunk-2SIREKBR.js} +2 -2
  38. package/dist/{chunk-N6EWQ5VB.js → chunk-37FOG6AE.js} +14 -7
  39. package/dist/chunk-37FOG6AE.js.map +1 -0
  40. package/dist/{chunk-UQRKAM2R.js → chunk-3M2KK7O7.js} +3 -3
  41. package/dist/{chunk-P6FATPXQ.js → chunk-3ZCVY3T6.js} +2 -2
  42. package/dist/{chunk-PBEHTFUG.js → chunk-4CGWLHPQ.js} +6 -6
  43. package/dist/{chunk-PFHDQY5L.js → chunk-56Z4NOC6.js} +3 -3
  44. package/dist/{chunk-GLSCL74M.js → chunk-5AVIUJP4.js} +13 -9
  45. package/dist/chunk-5AVIUJP4.js.map +1 -0
  46. package/dist/{chunk-F7X7MPK4.js → chunk-5BGHAVBN.js} +2 -2
  47. package/dist/{chunk-QHG7GQKM.js → chunk-5JNEDW7I.js} +2 -2
  48. package/dist/{chunk-GHMINSER.js → chunk-5OWJSDTO.js} +4 -4
  49. package/dist/{chunk-GHMINSER.js.map → chunk-5OWJSDTO.js.map} +1 -1
  50. package/dist/{chunk-DYIR6RC3.js → chunk-5Y4MO7UQ.js} +4 -4
  51. package/dist/{chunk-TLIFNRU5.js → chunk-63LZLRWG.js} +2 -2
  52. package/dist/{chunk-GZISWBCJ.js → chunk-74W56QPY.js} +4 -4
  53. package/dist/{chunk-CLOSXHR4.js → chunk-7KNYLHVX.js} +3 -3
  54. package/dist/chunk-7KNYLHVX.js.map +1 -0
  55. package/dist/{chunk-LFUID7OW.js → chunk-7VJ2SIEI.js} +42 -22
  56. package/dist/chunk-7VJ2SIEI.js.map +1 -0
  57. package/dist/{chunk-WVQDY3UM.js → chunk-AHA7UALU.js} +4 -4
  58. package/dist/{chunk-U277K5GR.js → chunk-AIHBYQHF.js} +259 -123
  59. package/dist/chunk-AIHBYQHF.js.map +1 -0
  60. package/dist/{chunk-S2ORTQGS.js → chunk-ANYX2M6P.js} +3 -3
  61. package/dist/{chunk-6WEPFEMJ.js → chunk-ATKYMRBC.js} +4 -4
  62. package/dist/{chunk-7UHLO4ZN.js → chunk-B2HU55QD.js} +2 -2
  63. package/dist/{chunk-Y22JWHCP.js → chunk-BEKMLYQ4.js} +4 -4
  64. package/dist/{chunk-27NCEPKM.js → chunk-BPFXD4EX.js} +23 -3
  65. package/dist/chunk-BPFXD4EX.js.map +1 -0
  66. package/dist/{chunk-7C7OF26T.js → chunk-C2NXAR3D.js} +5 -5
  67. package/dist/{chunk-Z2KP6PNF.js → chunk-CJBWJO5P.js} +6 -6
  68. package/dist/{chunk-Z2KP6PNF.js.map → chunk-CJBWJO5P.js.map} +1 -1
  69. package/dist/{chunk-6WIFF46H.js → chunk-CQLMRCKX.js} +2 -2
  70. package/dist/{chunk-URGHKZPL.js → chunk-CR5UPYIJ.js} +1 -1
  71. package/dist/chunk-CR5UPYIJ.js.map +1 -0
  72. package/dist/{chunk-LMC5L3MM.js → chunk-DS2JXSUA.js} +6 -6
  73. package/dist/{chunk-X6Z2SIRF.js → chunk-E2JIE4S3.js} +2 -2
  74. package/dist/{chunk-EQ6C2ZPT.js → chunk-E7Y4J4GL.js} +2 -2
  75. package/dist/{chunk-LZN6DTFI.js → chunk-ECDM6YRX.js} +2 -2
  76. package/dist/{chunk-WRLWEYHY.js → chunk-EFINFZIF.js} +11 -1
  77. package/dist/chunk-EFINFZIF.js.map +1 -0
  78. package/dist/{chunk-2T2TGRWE.js → chunk-EM56MHN5.js} +6 -6
  79. package/dist/{chunk-NK4LGBGQ.js → chunk-EQXOJH6O.js} +4 -4
  80. package/dist/{chunk-OK44MD3C.js → chunk-ET3U2C3A.js} +2 -2
  81. package/dist/{chunk-RF5WDM25.js → chunk-EU4G7PQH.js} +2 -2
  82. package/dist/{chunk-K5JNK63R.js → chunk-EUCUYK5E.js} +10 -10
  83. package/dist/{chunk-2ODEFG6K.js → chunk-EWSIJDWO.js} +4 -4
  84. package/dist/{chunk-LJ744WXU.js → chunk-F2FD4LSB.js} +2 -2
  85. package/dist/{chunk-L4UL4IAR.js → chunk-F7ENMZYJ.js} +2 -2
  86. package/dist/{chunk-KBIS64X4.js → chunk-FIIVYQOW.js} +5 -5
  87. package/dist/{chunk-TBVDI3LY.js → chunk-FPK2LPLR.js} +8 -8
  88. package/dist/chunk-FPK2LPLR.js.map +1 -0
  89. package/dist/{chunk-BQJ5ORU5.js → chunk-FQEUJGBV.js} +2 -2
  90. package/dist/{chunk-UORWAG7K.js → chunk-FY4FFNKK.js} +2 -2
  91. package/dist/{chunk-MMWX5OT5.js → chunk-GDCYZGPB.js} +2 -2
  92. package/dist/{chunk-7ONMS7QI.js → chunk-H6Q7GKLI.js} +2 -2
  93. package/dist/{chunk-654RE5YC.js → chunk-HDAPQF6Q.js} +3 -3
  94. package/dist/{chunk-5SMCBPJ2.js → chunk-HRLMUZLI.js} +5 -5
  95. package/dist/{chunk-R4GLRJ55.js → chunk-HRNQYGLQ.js} +2 -2
  96. package/dist/{chunk-HTRLQ4ZZ.js → chunk-I4S7IZSS.js} +321 -235
  97. package/dist/chunk-I4S7IZSS.js.map +1 -0
  98. package/dist/{chunk-UNAMWK2Q.js → chunk-IN4XZJYD.js} +4 -3
  99. package/dist/{chunk-UNAMWK2Q.js.map → chunk-IN4XZJYD.js.map} +1 -1
  100. package/dist/{chunk-2RH5SEY7.js → chunk-ISIXU45J.js} +2 -2
  101. package/dist/chunk-ISIXU45J.js.map +1 -0
  102. package/dist/{chunk-NHEKQWFI.js → chunk-J4L4AS2W.js} +2 -2
  103. package/dist/{chunk-UMV5GBTJ.js → chunk-JPSOFWJR.js} +2 -2
  104. package/dist/{chunk-A52BK5AY.js → chunk-JRCO67NG.js} +2 -2
  105. package/dist/{chunk-FVKQ5QUC.js → chunk-JW3I3NNZ.js} +2 -2
  106. package/dist/{chunk-BNYDOF2Q.js → chunk-JZMPSQBH.js} +4 -4
  107. package/dist/{chunk-ZK2WT532.js → chunk-K5TVSOPQ.js} +5 -5
  108. package/dist/{chunk-2IASHJPS.js → chunk-K75SL74I.js} +2 -2
  109. package/dist/{chunk-O3NGOHXQ.js → chunk-KA4AAUST.js} +2 -2
  110. package/dist/chunk-KHSBMLQE.js +161 -0
  111. package/dist/chunk-KHSBMLQE.js.map +1 -0
  112. package/dist/{chunk-QQLXKDGC.js → chunk-KUGUML7H.js} +3 -3
  113. package/dist/{chunk-AMSSAOOB.js → chunk-L4J5NC2Q.js} +2 -2
  114. package/dist/{chunk-AYOQZJDB.js → chunk-LIX4QPMM.js} +2 -2
  115. package/dist/{chunk-WIUH6EJ7.js → chunk-LWQFGR34.js} +3 -3
  116. package/dist/{chunk-QNOWNCZS.js → chunk-MMSSHMHW.js} +2 -2
  117. package/dist/{chunk-T5EXREMW.js → chunk-N25Z6PR4.js} +6 -5
  118. package/dist/chunk-N25Z6PR4.js.map +1 -0
  119. package/dist/{chunk-ND6S2DKC.js → chunk-N5S2BCW3.js} +2 -2
  120. package/dist/{chunk-X5RGG3ZW.js → chunk-NIZH2TYZ.js} +2 -2
  121. package/dist/{chunk-SXPLIRQH.js → chunk-NLDBQHDV.js} +2 -2
  122. package/dist/{chunk-AI35LNWQ.js → chunk-NQQ4MOPC.js} +4 -4
  123. package/dist/{chunk-B6EWMGFX.js → chunk-NUBI6PYH.js} +2 -2
  124. package/dist/{chunk-ID4ZBC3X.js → chunk-NYEXUZDW.js} +4 -4
  125. package/dist/{chunk-GU6QXHPZ.js → chunk-OIBFIWVJ.js} +4 -4
  126. package/dist/chunk-OIBFIWVJ.js.map +1 -0
  127. package/dist/{chunk-PWAMX5KU.js → chunk-OOLF5FU2.js} +2 -2
  128. package/dist/{chunk-WQUIJPN4.js → chunk-OQA7UF2Q.js} +3 -3
  129. package/dist/{chunk-7JRLCP2J.js → chunk-ORJPICJI.js} +2 -2
  130. package/dist/{chunk-IF2M43G4.js → chunk-PBRD75JF.js} +2 -2
  131. package/dist/{chunk-RKBCUP5D.js → chunk-PDCBL23X.js} +39 -17
  132. package/dist/chunk-PDCBL23X.js.map +1 -0
  133. package/dist/{chunk-BSEPI3HD.js → chunk-PR36DD2X.js} +7 -7
  134. package/dist/{chunk-52ZFNK46.js → chunk-PV4HIC4E.js} +2 -2
  135. package/dist/{chunk-TU6ZJTYT.js → chunk-PZNK4HTV.js} +3 -3
  136. package/dist/{chunk-LUQBG637.js → chunk-QBLPLNPE.js} +3 -3
  137. package/dist/{chunk-UADW5NOU.js → chunk-QZXUISRF.js} +5 -5
  138. package/dist/{chunk-BMAXBTYH.js → chunk-RBXYO7MD.js} +5 -5
  139. package/dist/{chunk-PZN76MMV.js → chunk-RIACRFWA.js} +4 -4
  140. package/dist/{chunk-ICHHNI5E.js → chunk-RL6RNDJQ.js} +8 -8
  141. package/dist/{chunk-4WLI37WK.js → chunk-SJ2P7UXD.js} +7 -7
  142. package/dist/{chunk-2QH3I7QC.js → chunk-SWXS4LV3.js} +11 -11
  143. package/dist/{chunk-4KYKRYRT.js → chunk-TOTCZFRF.js} +2 -2
  144. package/dist/{chunk-CSAN22QG.js → chunk-TT4D52EK.js} +6 -6
  145. package/dist/{chunk-VLRY2UH4.js → chunk-U7CMJY5P.js} +10 -10
  146. package/dist/{chunk-NIUHKKMM.js → chunk-UNKTZDA2.js} +11 -11
  147. package/dist/{chunk-NIUHKKMM.js.map → chunk-UNKTZDA2.js.map} +1 -1
  148. package/dist/{chunk-QVUMKG3Z.js → chunk-UXH4AKH3.js} +95 -151
  149. package/dist/chunk-UXH4AKH3.js.map +1 -0
  150. package/dist/{chunk-PU5ZEV65.js → chunk-UZVHSYIF.js} +2 -2
  151. package/dist/{chunk-3EXQXOQ2.js → chunk-VHKAW5OI.js} +29 -5
  152. package/dist/chunk-VHKAW5OI.js.map +1 -0
  153. package/dist/{chunk-XQGKS4OW.js → chunk-VKZ3TDET.js} +3 -3
  154. package/dist/{chunk-ZOFNZLAA.js → chunk-VLZPUG5A.js} +4 -4
  155. package/dist/{chunk-OR3OHKU6.js → chunk-VSN5FLMI.js} +2 -2
  156. package/dist/{chunk-JQMEXCUZ.js → chunk-VYBBE7RN.js} +8 -8
  157. package/dist/chunk-VYBBE7RN.js.map +1 -0
  158. package/dist/{chunk-SVXFCCSX.js → chunk-WHK4JVKF.js} +8 -8
  159. package/dist/{chunk-YVA6UPRN.js → chunk-X4LDBALX.js} +2 -2
  160. package/dist/{chunk-35CNOVQE.js → chunk-X67E7NIJ.js} +3 -3
  161. package/dist/{chunk-IPF5ORDI.js → chunk-XMARKBUC.js} +3 -3
  162. package/dist/{chunk-B3B6HV5S.js → chunk-XMBBTETD.js} +2 -2
  163. package/dist/{chunk-GQ4MF3CM.js → chunk-XMBTAN5E.js} +28 -14
  164. package/dist/chunk-XMBTAN5E.js.map +1 -0
  165. package/dist/{chunk-FUHUGKDN.js → chunk-XROQP6IQ.js} +4 -4
  166. package/dist/chunk-XWWDZKLS.js +196 -0
  167. package/dist/chunk-XWWDZKLS.js.map +1 -0
  168. package/dist/{chunk-DL4GCSTS.js → chunk-Y2RYUWSQ.js} +10 -10
  169. package/dist/{chunk-7IV7GVOS.js → chunk-YCTSQV7K.js} +5 -5
  170. package/dist/{chunk-IFUYLIEY.js → chunk-YF7P2DG7.js} +2 -2
  171. package/dist/{chunk-PIO6NW7O.js → chunk-ZG7DBIVX.js} +2 -2
  172. package/dist/{chunk-NUZ7ROUZ.js → chunk-ZGJ775X7.js} +2 -2
  173. package/dist/{chunk-6BEBWHNL.js → chunk-ZQQLOEWN.js} +3 -3
  174. package/dist/classified/index.js +5 -5
  175. package/dist/{classified-marker-7HXDMYHI.js → classified-marker-HKMRC7SC.js} +3 -3
  176. package/dist/{reveal-UAPBG743.js → classify-reveal-YSJKJEIR.js} +7 -12
  177. package/dist/classify-reveal-YSJKJEIR.js.map +1 -0
  178. package/dist/{verify-QWO5UKD6.js → classify-verify-ZCTKYQ43.js} +31 -41
  179. package/dist/classify-verify-ZCTKYQ43.js.map +1 -0
  180. package/dist/collection-facade-PPKNUR2J.js +38 -0
  181. package/dist/{computed-LZLSYOPG.js → computed-UCYVPMZA.js} +3 -3
  182. package/dist/consent/index.js +6 -9
  183. package/dist/consent/index.js.map +1 -1
  184. package/dist/cover/index.js +6 -9
  185. package/dist/custody/index.js +11 -13
  186. package/dist/{dead-filter-PZIJ4F4G.js → dead-filter-YOBWRG4O.js} +8 -11
  187. package/dist/{dead-filter-PZIJ4F4G.js.map → dead-filter-YOBWRG4O.js.map} +1 -1
  188. package/dist/debug/index.js +5 -8
  189. package/dist/debug/index.js.map +1 -1
  190. package/dist/delegation-SNALWRMO.js +24 -0
  191. package/dist/derivations/index.js +20 -23
  192. package/dist/derive-4GNU4E4I.js +17 -0
  193. package/dist/directory/index.js +7 -10
  194. package/dist/{dispatch-4BUYPWMJ.js → dispatch-QW32QBLW.js} +17 -20
  195. package/dist/{dispatch-4BUYPWMJ.js.map → dispatch-QW32QBLW.js.map} +1 -1
  196. package/dist/{dispatch-KOPDDPEQ.js → dispatch-V5WLDTVX.js} +5 -5
  197. package/dist/executor-7QN22OKI.js +8 -0
  198. package/dist/executor-BJZJNVBB.js +8 -0
  199. package/dist/executor-JEAAEJUM.js +32 -0
  200. package/dist/export-accessible-TVO2KQPG.js +20 -0
  201. package/dist/extract-partition-43CLDRN4.js +33 -0
  202. package/dist/{fanout-sidecar-FYDRL7F3.js → fanout-sidecar-DDONAFJT.js} +6 -9
  203. package/dist/{fanout-sidecar-FYDRL7F3.js.map → fanout-sidecar-DDONAFJT.js.map} +1 -1
  204. package/dist/forget/index.js +6 -9
  205. package/dist/forget/index.js.map +1 -1
  206. package/dist/guards/index.js +4 -4
  207. package/dist/history/index.js +11 -14
  208. package/dist/history/index.js.map +1 -1
  209. package/dist/i18n/index.js +11 -14
  210. package/dist/i18n/index.js.map +1 -1
  211. package/dist/index.d.ts +2 -2
  212. package/dist/index.js +122 -123
  213. package/dist/index.js.map +1 -1
  214. package/dist/indexing/index.js +5 -5
  215. package/dist/introspection/index.js +8 -11
  216. package/dist/issue-EIHEDAXM.js +16 -0
  217. package/dist/kernel/capsule-requirements.d.ts +84 -0
  218. package/dist/kernel/errors.d.ts +19 -3
  219. package/dist/kernel/export-scope.d.ts +28 -1
  220. package/dist/kernel/store-segment-guard.d.ts +29 -0
  221. package/dist/kernel/types.d.ts +169 -13
  222. package/dist/kernel/validation.d.ts +32 -0
  223. package/dist/kernel/vault.d.ts +5 -5
  224. package/dist/{ledger-UFJCB6T5.js → ledger-BMVUFQ3R.js} +8 -11
  225. package/dist/liberate-7KHXCLNJ.js +23 -0
  226. package/dist/link-set-PC2EJRKL.js +26 -0
  227. package/dist/{managed-secret-H5WYSJ46.js → managed-secret-RPRVEYZA.js} +7 -10
  228. package/dist/materialized-views/index.js +23 -26
  229. package/dist/{migrate-cek-SPESQAAO.js → migrate-cek-DTSCWGEF.js} +2 -2
  230. package/dist/money/index.js +5 -5
  231. package/dist/noydb-AYDNOXAX.js +98 -0
  232. package/dist/on/index.js +11 -13
  233. package/dist/overlay-views/index.js +4 -4
  234. package/dist/periods/index.js +9 -12
  235. package/dist/pod/index.js +65 -67
  236. package/dist/{pod-handle-GJLCOUGK.js → pod-handle-KBPQRN6Q.js} +6 -9
  237. package/dist/{pod-handle-GJLCOUGK.js.map → pod-handle-KBPQRN6Q.js.map} +1 -1
  238. package/dist/policy/index.js +7 -10
  239. package/dist/port/at/index.d.ts +1 -0
  240. package/dist/port/with/admission-authority.d.ts +2 -1
  241. package/dist/port/with/collection-registries.d.ts +37 -0
  242. package/dist/portability/index.js +8 -8
  243. package/dist/{post-register-2AC2STHC.js → post-register-RITSNASO.js} +6 -6
  244. package/dist/query/all/index.js +15 -15
  245. package/dist/query/index.js +7 -7
  246. package/dist/query/live/index.js +7 -7
  247. package/dist/query/reduce/index.js +10 -10
  248. package/dist/query/relate/index.js +9 -9
  249. package/dist/reduce/index.js +8 -8
  250. package/dist/register-BB34SK7E.js +27 -0
  251. package/dist/registry-65L6V5TO.js +20 -0
  252. package/dist/registry-HU62GPWA.js +32 -0
  253. package/dist/registry-SMNK6UM4.js +8 -0
  254. package/dist/registry-X5VPBKCO.js +8 -0
  255. package/dist/request-withdrawal-4SKAH46W.js +26 -0
  256. package/dist/{restore-to-OOPKLAPU.js → restore-to-VQHT67OH.js} +7 -10
  257. package/dist/{restore-to-OOPKLAPU.js.map → restore-to-VQHT67OH.js.map} +1 -1
  258. package/dist/revoke-IF5PX2JY.js +21 -0
  259. package/dist/satellites/index.js +1 -1
  260. package/dist/schema-update/index.js +2 -2
  261. package/dist/sealed-record/index.js +9 -12
  262. package/dist/sealed-record/index.js.map +1 -1
  263. package/dist/search/index.js +4 -4
  264. package/dist/{seed-BVYDPVIW.js → seed-F2OSDZJR.js} +11 -13
  265. package/dist/{seed-BVYDPVIW.js.map → seed-F2OSDZJR.js.map} +1 -1
  266. package/dist/sequence/index.js +6 -9
  267. package/dist/session/index.js +6 -9
  268. package/dist/session/index.js.map +1 -1
  269. package/dist/shadow/index.js +2 -2
  270. package/dist/signer-5P7IZC2K.js +20 -0
  271. package/dist/snapshots/index.js +8 -10
  272. package/dist/snapshots/index.js.map +1 -1
  273. package/dist/{stale-CROGJBIJ.js → stale-PUCZH5GJ.js} +7 -10
  274. package/dist/storage-5EGY5OYE.js +18 -0
  275. package/dist/store/index.js +1 -1
  276. package/dist/{store-coordination-provider-2YD2PTTP.js → store-coordination-provider-SEQM7SHJ.js} +7 -10
  277. package/dist/{store-coordination-provider-2YD2PTTP.js.map → store-coordination-provider-SEQM7SHJ.js.map} +1 -1
  278. package/dist/sync/index.js +13 -15
  279. package/dist/sync/index.js.map +1 -1
  280. package/dist/team/index.js +14 -16
  281. package/dist/tiers/index.js +8 -11
  282. package/dist/to/index.js +2 -2
  283. package/dist/transactions/index.js +3 -3
  284. package/dist/util/index.js +1 -1
  285. package/dist/vault-diff-H7LT5ZBJ.js +8 -0
  286. package/dist/vault-head/index.js +5 -8
  287. package/dist/vault-head/index.js.map +1 -1
  288. package/dist/walk-Z4N7PCZ2.js +17 -0
  289. package/dist/with-audit/portability/export-accessible.d.ts +3 -1
  290. package/dist/with-cargo/vault-diff.d.ts +28 -0
  291. package/dist/with-commit/sequence/index.d.ts +22 -0
  292. package/dist/with-party/team/delegation.d.ts +16 -12
  293. package/dist/with-party/team/keyring.d.ts +77 -0
  294. package/dist/with-party/team/managed-secret.d.ts +40 -3
  295. package/dist/with-party/team/noydb-facade.d.ts +2 -2
  296. package/dist/with-party/team/peer-recover.d.ts +2 -2
  297. package/dist/with-party/team/rotate-recover.d.ts +3 -3
  298. package/dist/with-shape/manifest/storage.d.ts +2 -2
  299. package/dist/with-shape/manifest/writer.d.ts +2 -2
  300. package/dist/with-store/store-middleware.d.ts +18 -5
  301. package/dist/with-sync/engine.d.ts +0 -2
  302. package/dist/withdraw-accessible-CRCIQSTL.js +23 -0
  303. package/package.json +3 -3
  304. package/dist/api-H4B7ZQXP.js +0 -18
  305. package/dist/capsule/enclave-aes/classify/reveal.d.ts +0 -10
  306. package/dist/capsule/enclave-aes/classify/verify.d.ts +0 -36
  307. package/dist/chunk-27NCEPKM.js.map +0 -1
  308. package/dist/chunk-2RH5SEY7.js.map +0 -1
  309. package/dist/chunk-3EXQXOQ2.js.map +0 -1
  310. package/dist/chunk-4N4OIVK3.js.map +0 -1
  311. package/dist/chunk-5A3HOTP5.js +0 -591
  312. package/dist/chunk-5A3HOTP5.js.map +0 -1
  313. package/dist/chunk-CLOSXHR4.js.map +0 -1
  314. package/dist/chunk-EPPAEGH5.js +0 -157
  315. package/dist/chunk-EPPAEGH5.js.map +0 -1
  316. package/dist/chunk-GLSCL74M.js.map +0 -1
  317. package/dist/chunk-GQ4MF3CM.js.map +0 -1
  318. package/dist/chunk-GU6QXHPZ.js.map +0 -1
  319. package/dist/chunk-HTRLQ4ZZ.js.map +0 -1
  320. package/dist/chunk-JQMEXCUZ.js.map +0 -1
  321. package/dist/chunk-LFUID7OW.js.map +0 -1
  322. package/dist/chunk-N6EWQ5VB.js.map +0 -1
  323. package/dist/chunk-NH2UOV3B.js +0 -18
  324. package/dist/chunk-NH2UOV3B.js.map +0 -1
  325. package/dist/chunk-O6VOR4NH.js +0 -27
  326. package/dist/chunk-O6VOR4NH.js.map +0 -1
  327. package/dist/chunk-ODBOHPZU.js +0 -22
  328. package/dist/chunk-ODBOHPZU.js.map +0 -1
  329. package/dist/chunk-Q4DBU5RM.js +0 -78
  330. package/dist/chunk-Q4DBU5RM.js.map +0 -1
  331. package/dist/chunk-QVUMKG3Z.js.map +0 -1
  332. package/dist/chunk-RKBCUP5D.js.map +0 -1
  333. package/dist/chunk-T5EXREMW.js.map +0 -1
  334. package/dist/chunk-TBVDI3LY.js.map +0 -1
  335. package/dist/chunk-U277K5GR.js.map +0 -1
  336. package/dist/chunk-URGHKZPL.js.map +0 -1
  337. package/dist/chunk-VZFTON37.js +0 -40
  338. package/dist/chunk-VZFTON37.js.map +0 -1
  339. package/dist/chunk-WRLWEYHY.js.map +0 -1
  340. package/dist/chunk-ZVJKHGE5.js.map +0 -1
  341. package/dist/collection-facade-V63BEBGU.js +0 -41
  342. package/dist/delegation-7SSGIETH.js +0 -26
  343. package/dist/derive-IMI3BMDS.js +0 -20
  344. package/dist/executor-7SY3M6TZ.js +0 -8
  345. package/dist/executor-SNHW4ELF.js +0 -35
  346. package/dist/executor-Z3IKK7G3.js +0 -8
  347. package/dist/export-accessible-O7DIVFUO.js +0 -22
  348. package/dist/extract-partition-ELZEJKXM.js +0 -35
  349. package/dist/find-KWB2RYWJ.js +0 -10
  350. package/dist/issue-5ZHXK4HJ.js +0 -19
  351. package/dist/liberate-OEOSNNFH.js +0 -25
  352. package/dist/link-set-KMUBFN2L.js +0 -29
  353. package/dist/noydb-QDZ4QIKO.js +0 -100
  354. package/dist/register-PIORIMMR.js +0 -30
  355. package/dist/registry-BIMICFUH.js +0 -23
  356. package/dist/registry-JGWLW53D.js +0 -35
  357. package/dist/registry-SELCBYEQ.js +0 -8
  358. package/dist/registry-W327UNYH.js +0 -8
  359. package/dist/request-withdrawal-K3SXXODI.js +0 -28
  360. package/dist/reveal-UAPBG743.js.map +0 -1
  361. package/dist/revoke-6AFVXTWF.js +0 -24
  362. package/dist/signer-TW5MAQJP.js +0 -23
  363. package/dist/storage-SO2L2Z5J.js +0 -21
  364. package/dist/vault-diff-C6WUJFNP.js +0 -8
  365. package/dist/verify-QWO5UKD6.js.map +0 -1
  366. package/dist/walk-3KEOL7BY.js +0 -20
  367. package/dist/withdraw-accessible-OZU525ND.js +0 -25
  368. package/dist/withdraw-accessible-OZU525ND.js.map +0 -1
  369. /package/dist/{api-H4B7ZQXP.js.map → api-QSEKT4KS.js.map} +0 -0
  370. /package/dist/{capsule-YQKQZPH7.js.map → capsule-YAITMH77.js.map} +0 -0
  371. /package/dist/{chunk-PREYKC76.js.map → chunk-24AGG4PP.js.map} +0 -0
  372. /package/dist/{chunk-ZNVBCKMV.js.map → chunk-2SIREKBR.js.map} +0 -0
  373. /package/dist/{chunk-UQRKAM2R.js.map → chunk-3M2KK7O7.js.map} +0 -0
  374. /package/dist/{chunk-P6FATPXQ.js.map → chunk-3ZCVY3T6.js.map} +0 -0
  375. /package/dist/{chunk-PBEHTFUG.js.map → chunk-4CGWLHPQ.js.map} +0 -0
  376. /package/dist/{chunk-PFHDQY5L.js.map → chunk-56Z4NOC6.js.map} +0 -0
  377. /package/dist/{chunk-F7X7MPK4.js.map → chunk-5BGHAVBN.js.map} +0 -0
  378. /package/dist/{chunk-QHG7GQKM.js.map → chunk-5JNEDW7I.js.map} +0 -0
  379. /package/dist/{chunk-DYIR6RC3.js.map → chunk-5Y4MO7UQ.js.map} +0 -0
  380. /package/dist/{chunk-TLIFNRU5.js.map → chunk-63LZLRWG.js.map} +0 -0
  381. /package/dist/{chunk-GZISWBCJ.js.map → chunk-74W56QPY.js.map} +0 -0
  382. /package/dist/{chunk-WVQDY3UM.js.map → chunk-AHA7UALU.js.map} +0 -0
  383. /package/dist/{chunk-S2ORTQGS.js.map → chunk-ANYX2M6P.js.map} +0 -0
  384. /package/dist/{chunk-6WEPFEMJ.js.map → chunk-ATKYMRBC.js.map} +0 -0
  385. /package/dist/{chunk-7UHLO4ZN.js.map → chunk-B2HU55QD.js.map} +0 -0
  386. /package/dist/{chunk-Y22JWHCP.js.map → chunk-BEKMLYQ4.js.map} +0 -0
  387. /package/dist/{chunk-7C7OF26T.js.map → chunk-C2NXAR3D.js.map} +0 -0
  388. /package/dist/{chunk-6WIFF46H.js.map → chunk-CQLMRCKX.js.map} +0 -0
  389. /package/dist/{chunk-LMC5L3MM.js.map → chunk-DS2JXSUA.js.map} +0 -0
  390. /package/dist/{chunk-X6Z2SIRF.js.map → chunk-E2JIE4S3.js.map} +0 -0
  391. /package/dist/{chunk-EQ6C2ZPT.js.map → chunk-E7Y4J4GL.js.map} +0 -0
  392. /package/dist/{chunk-LZN6DTFI.js.map → chunk-ECDM6YRX.js.map} +0 -0
  393. /package/dist/{chunk-2T2TGRWE.js.map → chunk-EM56MHN5.js.map} +0 -0
  394. /package/dist/{chunk-NK4LGBGQ.js.map → chunk-EQXOJH6O.js.map} +0 -0
  395. /package/dist/{chunk-OK44MD3C.js.map → chunk-ET3U2C3A.js.map} +0 -0
  396. /package/dist/{chunk-RF5WDM25.js.map → chunk-EU4G7PQH.js.map} +0 -0
  397. /package/dist/{chunk-K5JNK63R.js.map → chunk-EUCUYK5E.js.map} +0 -0
  398. /package/dist/{chunk-2ODEFG6K.js.map → chunk-EWSIJDWO.js.map} +0 -0
  399. /package/dist/{chunk-LJ744WXU.js.map → chunk-F2FD4LSB.js.map} +0 -0
  400. /package/dist/{chunk-L4UL4IAR.js.map → chunk-F7ENMZYJ.js.map} +0 -0
  401. /package/dist/{chunk-KBIS64X4.js.map → chunk-FIIVYQOW.js.map} +0 -0
  402. /package/dist/{chunk-BQJ5ORU5.js.map → chunk-FQEUJGBV.js.map} +0 -0
  403. /package/dist/{chunk-UORWAG7K.js.map → chunk-FY4FFNKK.js.map} +0 -0
  404. /package/dist/{chunk-MMWX5OT5.js.map → chunk-GDCYZGPB.js.map} +0 -0
  405. /package/dist/{chunk-7ONMS7QI.js.map → chunk-H6Q7GKLI.js.map} +0 -0
  406. /package/dist/{chunk-654RE5YC.js.map → chunk-HDAPQF6Q.js.map} +0 -0
  407. /package/dist/{chunk-5SMCBPJ2.js.map → chunk-HRLMUZLI.js.map} +0 -0
  408. /package/dist/{chunk-R4GLRJ55.js.map → chunk-HRNQYGLQ.js.map} +0 -0
  409. /package/dist/{chunk-NHEKQWFI.js.map → chunk-J4L4AS2W.js.map} +0 -0
  410. /package/dist/{chunk-UMV5GBTJ.js.map → chunk-JPSOFWJR.js.map} +0 -0
  411. /package/dist/{chunk-A52BK5AY.js.map → chunk-JRCO67NG.js.map} +0 -0
  412. /package/dist/{chunk-FVKQ5QUC.js.map → chunk-JW3I3NNZ.js.map} +0 -0
  413. /package/dist/{chunk-BNYDOF2Q.js.map → chunk-JZMPSQBH.js.map} +0 -0
  414. /package/dist/{chunk-ZK2WT532.js.map → chunk-K5TVSOPQ.js.map} +0 -0
  415. /package/dist/{chunk-2IASHJPS.js.map → chunk-K75SL74I.js.map} +0 -0
  416. /package/dist/{chunk-O3NGOHXQ.js.map → chunk-KA4AAUST.js.map} +0 -0
  417. /package/dist/{chunk-QQLXKDGC.js.map → chunk-KUGUML7H.js.map} +0 -0
  418. /package/dist/{chunk-AMSSAOOB.js.map → chunk-L4J5NC2Q.js.map} +0 -0
  419. /package/dist/{chunk-AYOQZJDB.js.map → chunk-LIX4QPMM.js.map} +0 -0
  420. /package/dist/{chunk-WIUH6EJ7.js.map → chunk-LWQFGR34.js.map} +0 -0
  421. /package/dist/{chunk-QNOWNCZS.js.map → chunk-MMSSHMHW.js.map} +0 -0
  422. /package/dist/{chunk-ND6S2DKC.js.map → chunk-N5S2BCW3.js.map} +0 -0
  423. /package/dist/{chunk-X5RGG3ZW.js.map → chunk-NIZH2TYZ.js.map} +0 -0
  424. /package/dist/{chunk-SXPLIRQH.js.map → chunk-NLDBQHDV.js.map} +0 -0
  425. /package/dist/{chunk-AI35LNWQ.js.map → chunk-NQQ4MOPC.js.map} +0 -0
  426. /package/dist/{chunk-B6EWMGFX.js.map → chunk-NUBI6PYH.js.map} +0 -0
  427. /package/dist/{chunk-ID4ZBC3X.js.map → chunk-NYEXUZDW.js.map} +0 -0
  428. /package/dist/{chunk-PWAMX5KU.js.map → chunk-OOLF5FU2.js.map} +0 -0
  429. /package/dist/{chunk-WQUIJPN4.js.map → chunk-OQA7UF2Q.js.map} +0 -0
  430. /package/dist/{chunk-7JRLCP2J.js.map → chunk-ORJPICJI.js.map} +0 -0
  431. /package/dist/{chunk-IF2M43G4.js.map → chunk-PBRD75JF.js.map} +0 -0
  432. /package/dist/{chunk-BSEPI3HD.js.map → chunk-PR36DD2X.js.map} +0 -0
  433. /package/dist/{chunk-52ZFNK46.js.map → chunk-PV4HIC4E.js.map} +0 -0
  434. /package/dist/{chunk-TU6ZJTYT.js.map → chunk-PZNK4HTV.js.map} +0 -0
  435. /package/dist/{chunk-LUQBG637.js.map → chunk-QBLPLNPE.js.map} +0 -0
  436. /package/dist/{chunk-UADW5NOU.js.map → chunk-QZXUISRF.js.map} +0 -0
  437. /package/dist/{chunk-BMAXBTYH.js.map → chunk-RBXYO7MD.js.map} +0 -0
  438. /package/dist/{chunk-PZN76MMV.js.map → chunk-RIACRFWA.js.map} +0 -0
  439. /package/dist/{chunk-ICHHNI5E.js.map → chunk-RL6RNDJQ.js.map} +0 -0
  440. /package/dist/{chunk-4WLI37WK.js.map → chunk-SJ2P7UXD.js.map} +0 -0
  441. /package/dist/{chunk-2QH3I7QC.js.map → chunk-SWXS4LV3.js.map} +0 -0
  442. /package/dist/{chunk-4KYKRYRT.js.map → chunk-TOTCZFRF.js.map} +0 -0
  443. /package/dist/{chunk-CSAN22QG.js.map → chunk-TT4D52EK.js.map} +0 -0
  444. /package/dist/{chunk-VLRY2UH4.js.map → chunk-U7CMJY5P.js.map} +0 -0
  445. /package/dist/{chunk-PU5ZEV65.js.map → chunk-UZVHSYIF.js.map} +0 -0
  446. /package/dist/{chunk-XQGKS4OW.js.map → chunk-VKZ3TDET.js.map} +0 -0
  447. /package/dist/{chunk-ZOFNZLAA.js.map → chunk-VLZPUG5A.js.map} +0 -0
  448. /package/dist/{chunk-OR3OHKU6.js.map → chunk-VSN5FLMI.js.map} +0 -0
  449. /package/dist/{chunk-SVXFCCSX.js.map → chunk-WHK4JVKF.js.map} +0 -0
  450. /package/dist/{chunk-YVA6UPRN.js.map → chunk-X4LDBALX.js.map} +0 -0
  451. /package/dist/{chunk-35CNOVQE.js.map → chunk-X67E7NIJ.js.map} +0 -0
  452. /package/dist/{chunk-IPF5ORDI.js.map → chunk-XMARKBUC.js.map} +0 -0
  453. /package/dist/{chunk-B3B6HV5S.js.map → chunk-XMBBTETD.js.map} +0 -0
  454. /package/dist/{chunk-FUHUGKDN.js.map → chunk-XROQP6IQ.js.map} +0 -0
  455. /package/dist/{chunk-DL4GCSTS.js.map → chunk-Y2RYUWSQ.js.map} +0 -0
  456. /package/dist/{chunk-7IV7GVOS.js.map → chunk-YCTSQV7K.js.map} +0 -0
  457. /package/dist/{chunk-IFUYLIEY.js.map → chunk-YF7P2DG7.js.map} +0 -0
  458. /package/dist/{chunk-PIO6NW7O.js.map → chunk-ZG7DBIVX.js.map} +0 -0
  459. /package/dist/{chunk-NUZ7ROUZ.js.map → chunk-ZGJ775X7.js.map} +0 -0
  460. /package/dist/{chunk-6BEBWHNL.js.map → chunk-ZQQLOEWN.js.map} +0 -0
  461. /package/dist/{classified-marker-7HXDMYHI.js.map → classified-marker-HKMRC7SC.js.map} +0 -0
  462. /package/dist/{collection-facade-V63BEBGU.js.map → collection-facade-PPKNUR2J.js.map} +0 -0
  463. /package/dist/{computed-LZLSYOPG.js.map → computed-UCYVPMZA.js.map} +0 -0
  464. /package/dist/{delegation-7SSGIETH.js.map → delegation-SNALWRMO.js.map} +0 -0
  465. /package/dist/{derive-IMI3BMDS.js.map → derive-4GNU4E4I.js.map} +0 -0
  466. /package/dist/{dispatch-KOPDDPEQ.js.map → dispatch-V5WLDTVX.js.map} +0 -0
  467. /package/dist/{executor-7SY3M6TZ.js.map → executor-7QN22OKI.js.map} +0 -0
  468. /package/dist/{executor-SNHW4ELF.js.map → executor-BJZJNVBB.js.map} +0 -0
  469. /package/dist/{executor-Z3IKK7G3.js.map → executor-JEAAEJUM.js.map} +0 -0
  470. /package/dist/{export-accessible-O7DIVFUO.js.map → export-accessible-TVO2KQPG.js.map} +0 -0
  471. /package/dist/{extract-partition-ELZEJKXM.js.map → extract-partition-43CLDRN4.js.map} +0 -0
  472. /package/dist/{find-KWB2RYWJ.js.map → issue-EIHEDAXM.js.map} +0 -0
  473. /package/dist/{issue-5ZHXK4HJ.js.map → ledger-BMVUFQ3R.js.map} +0 -0
  474. /package/dist/{ledger-UFJCB6T5.js.map → liberate-7KHXCLNJ.js.map} +0 -0
  475. /package/dist/{liberate-OEOSNNFH.js.map → link-set-PC2EJRKL.js.map} +0 -0
  476. /package/dist/{link-set-KMUBFN2L.js.map → managed-secret-RPRVEYZA.js.map} +0 -0
  477. /package/dist/{migrate-cek-SPESQAAO.js.map → migrate-cek-DTSCWGEF.js.map} +0 -0
  478. /package/dist/{managed-secret-H5WYSJ46.js.map → noydb-AYDNOXAX.js.map} +0 -0
  479. /package/dist/{post-register-2AC2STHC.js.map → post-register-RITSNASO.js.map} +0 -0
  480. /package/dist/{noydb-QDZ4QIKO.js.map → register-BB34SK7E.js.map} +0 -0
  481. /package/dist/{register-PIORIMMR.js.map → registry-65L6V5TO.js.map} +0 -0
  482. /package/dist/{registry-BIMICFUH.js.map → registry-HU62GPWA.js.map} +0 -0
  483. /package/dist/{registry-JGWLW53D.js.map → registry-SMNK6UM4.js.map} +0 -0
  484. /package/dist/{registry-SELCBYEQ.js.map → registry-X5VPBKCO.js.map} +0 -0
  485. /package/dist/{registry-W327UNYH.js.map → request-withdrawal-4SKAH46W.js.map} +0 -0
  486. /package/dist/{request-withdrawal-K3SXXODI.js.map → revoke-IF5PX2JY.js.map} +0 -0
  487. /package/dist/{revoke-6AFVXTWF.js.map → signer-5P7IZC2K.js.map} +0 -0
  488. /package/dist/{signer-TW5MAQJP.js.map → stale-PUCZH5GJ.js.map} +0 -0
  489. /package/dist/{stale-CROGJBIJ.js.map → storage-5EGY5OYE.js.map} +0 -0
  490. /package/dist/{storage-SO2L2Z5J.js.map → vault-diff-H7LT5ZBJ.js.map} +0 -0
  491. /package/dist/{vault-diff-C6WUJFNP.js.map → walk-Z4N7PCZ2.js.map} +0 -0
  492. /package/dist/{walk-3KEOL7BY.js.map → withdraw-accessible-CRCIQSTL.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  OverlayIdMismatchError
3
- } from "./chunk-2RH5SEY7.js";
3
+ } from "./chunk-ISIXU45J.js";
4
4
 
5
5
  // src/with-formula/overlay-views/virtual-collection.ts
6
6
  var OverlayedCollection = class {
@@ -206,4 +206,4 @@ var OverlayedCollection = class {
206
206
  export {
207
207
  OverlayedCollection
208
208
  };
209
- //# sourceMappingURL=chunk-PU5ZEV65.js.map
209
+ //# sourceMappingURL=chunk-UZVHSYIF.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  readPath
3
- } from "./chunk-SXPLIRQH.js";
3
+ } from "./chunk-NLDBQHDV.js";
4
4
  import {
5
5
  installViaBinder
6
- } from "./chunk-PIO6NW7O.js";
6
+ } from "./chunk-ZG7DBIVX.js";
7
7
  import {
8
8
  NoydbError,
9
9
  ValidationError
10
- } from "./chunk-2RH5SEY7.js";
10
+ } from "./chunk-ISIXU45J.js";
11
11
 
12
12
  // src/via/money/iso4217.ts
13
13
  var MINOR_UNITS = {
@@ -308,7 +308,7 @@ function canonicalizeIncomingMoney(record, moneyFields) {
308
308
  if (!moneyFields || Object.keys(moneyFields).length === 0) return record;
309
309
  try {
310
310
  return decodeMoneyFields(
311
- quantizeMoneyFields(record, moneyFields),
311
+ quantizeMoneyFields(stripMoneyVirtuals(record, moneyFields), moneyFields),
312
312
  moneyFields,
313
313
  "raw"
314
314
  );
@@ -316,6 +316,30 @@ function canonicalizeIncomingMoney(record, moneyFields) {
316
316
  return record;
317
317
  }
318
318
  }
319
+ function stripMoneyVirtuals(record, moneyFields) {
320
+ let out = { ...record };
321
+ for (const path of Object.keys(moneyFields)) {
322
+ if (isSimpleMoneyPath(path)) {
323
+ delete out[`${path}Formatted`];
324
+ delete out[`${path}Number`];
325
+ continue;
326
+ }
327
+ out = transformAtMoneyPath(
328
+ out,
329
+ path,
330
+ parseMoneyPath(path),
331
+ 0,
332
+ (container, key) => {
333
+ if (typeof key !== "string" || Array.isArray(container)) return;
334
+ delete container[`${key}Formatted`];
335
+ delete container[`${key}Number`];
336
+ },
337
+ /* lenient */
338
+ true
339
+ );
340
+ }
341
+ return out;
342
+ }
319
343
  function quantizeValue(field, raw, desc) {
320
344
  if (desc.mode === "fixed") {
321
345
  const currency2 = desc.fixedCurrency;
@@ -1130,4 +1154,4 @@ export {
1130
1154
  decodeMoneyFields,
1131
1155
  exactMath
1132
1156
  };
1133
- //# sourceMappingURL=chunk-3EXQXOQ2.js.map
1157
+ //# sourceMappingURL=chunk-VHKAW5OI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/via/money/iso4217.ts","../src/via/money/fixed-point.ts","../src/via/money/paths.ts","../src/via/money/normalize.ts","../src/via/money/where.ts","../src/via/money/money-reducer.ts","../src/via/money/binding.ts","../src/via/money/descriptor.ts","../src/via/money/exact.ts"],"sourcesContent":["/**\n * ISO 4217 minor-unit (scale) lookup.\n *\n * Maps a currency code to the number of decimal places its minor unit\n * uses — `EUR` → 2 (cents), `JPY` → 0 (no minor unit), `BHD` → 3 (fils).\n * Only listed codes are \"known\"; an unlisted code returns `null` so the\n * descriptor layer can demand an explicit `scale` / `scaleOverrides`\n * rather than silently assuming 2. This avoids the classic bug where a\n * 0-decimal currency (JPY) is stored as if it had cents.\n *\n * Coverage is the common ISO-4217 set; exotic or non-listed codes must\n * declare scale explicitly. This table is the single source of truth for\n * default scale resolution — see {@link scaleForCurrency}.\n */\nconst MINOR_UNITS: Readonly<Record<string, number>> = {\n // 2-decimal majors\n EUR: 2, USD: 2, GBP: 2, CHF: 2, CAD: 2, AUD: 2, NZD: 2, SGD: 2,\n HKD: 2, CNY: 2, INR: 2, BRL: 2, MXN: 2, ZAR: 2, RUB: 2, TRY: 2,\n PLN: 2, SEK: 2, NOK: 2, DKK: 2, CZK: 2, HUF: 2, RON: 2, ILS: 2,\n THB: 2, PHP: 2, MYR: 2, IDR: 2, AED: 2, SAR: 2, QAR: 2, EGP: 2,\n // 0-decimal\n JPY: 0, KRW: 0, ISK: 0, CLP: 0, VND: 0, XOF: 0, XAF: 0, PYG: 0,\n // 3-decimal\n BHD: 3, KWD: 3, OMR: 3, TND: 3, JOD: 3, IQD: 3, LYD: 3,\n}\n\n/**\n * Return the ISO-4217 minor-unit scale for a currency code, or `null`\n * when the code is not in the known set (caller must supply an explicit\n * scale).\n */\nexport function scaleForCurrency(code: string): number | null {\n const v = MINOR_UNITS[code]\n return v === undefined ? null : v\n}\n","/**\n * Pure fixed-point decimal core for the money descriptor.\n *\n * All conversion goes decimal-string ⇄ scaled `BigInt`. There is no\n * floating-point arithmetic anywhere: a value like `123.45` becomes\n * `12345n` purely by string manipulation, never by `value * 100` (which\n * would reintroduce the very drift money() exists to eliminate). BigInt\n * has no magnitude ceiling, so values past `Number.MAX_SAFE_INTEGER`\n * stay exact end-to-end.\n *\n * This module knows nothing about currencies, descriptors, or storage —\n * it is the isolated, exhaustively-tested arithmetic kernel.\n */\n\nexport type RoundingMode =\n | 'half-up'\n | 'half-even'\n | 'half-down'\n | 'up'\n | 'down'\n | 'ceil'\n | 'floor'\n\nexport type ParseResult =\n | { ok: true; value: bigint }\n | { ok: false; reason: 'precision' | 'nonfinite' }\n\n/**\n * Expand exponent notation (`1e-7`, `1.5e3`) into a plain decimal\n * string. Returns the input unchanged when it carries no exponent.\n */\nfunction expandExponent(s: string): string {\n const m = /^([+-]?)(\\d+)(?:\\.(\\d+))?[eE]([+-]?\\d+)$/.exec(s)\n if (!m) return s\n const sign = m[1] === '-' ? '-' : ''\n const intp = m[2]!\n const frac = m[3] ?? ''\n const exp = Number(m[4]!)\n const digits = intp + frac\n const pointPos = intp.length + exp\n let body: string\n if (pointPos <= 0) {\n body = '0.' + '0'.repeat(-pointPos) + digits\n } else if (pointPos >= digits.length) {\n body = digits + '0'.repeat(pointPos - digits.length)\n } else {\n body = digits.slice(0, pointPos) + '.' + digits.slice(pointPos)\n }\n return sign + body\n}\n\n/**\n * Normalize an input to a canonical decimal string, or `null` if it is\n * non-finite / not a valid decimal.\n */\nfunction toCanonicalDecimalString(input: number | string): string | null {\n let s: string\n if (typeof input === 'number') {\n if (!Number.isFinite(input)) return null\n s = String(input)\n } else {\n s = input.trim()\n }\n s = expandExponent(s)\n if (s.startsWith('+')) s = s.slice(1)\n // optional sign, then digits with at most one dot, at least one digit\n if (!/^-?(\\d+(\\.\\d*)?|\\.\\d+)$/.test(s)) return null\n return s\n}\n\n/**\n * Decide whether the truncated magnitude should be incremented by one\n * minor unit, given the discarded fractional tail. Only called when the\n * tail is known to contain a non-zero digit.\n */\nfunction shouldRoundUp(\n negative: boolean,\n lastKeptDigit: number,\n firstDiscarded: number,\n hasMoreNonZeroAfterFirst: boolean,\n mode: RoundingMode,\n): boolean {\n switch (mode) {\n case 'up':\n return true\n case 'down':\n return false\n case 'ceil':\n return !negative\n case 'floor':\n return negative\n case 'half-up':\n return firstDiscarded >= 5\n case 'half-down':\n return firstDiscarded > 5 || (firstDiscarded === 5 && hasMoreNonZeroAfterFirst)\n case 'half-even':\n if (firstDiscarded > 5) return true\n if (firstDiscarded < 5) return false\n // exactly 5 leading the tail\n return hasMoreNonZeroAfterFirst || lastKeptDigit % 2 === 1\n }\n}\n\n/**\n * Parse a decimal (`number | string`) into a scaled `BigInt` at the\n * given scale. When the input carries more fractional precision than\n * `scale`:\n * - `rounding` omitted ⇒ `{ ok: false, reason: 'precision' }`\n * - `rounding` set ⇒ the tail is rounded per the mode.\n * Non-finite / unparseable input ⇒ `{ ok: false, reason: 'nonfinite' }`.\n */\nexport function parseToScaledInt(\n input: number | string,\n scale: number,\n rounding?: RoundingMode,\n): ParseResult {\n const canonical = toCanonicalDecimalString(input)\n if (canonical === null) return { ok: false, reason: 'nonfinite' }\n\n const negative = canonical.startsWith('-')\n const unsigned = negative ? canonical.slice(1) : canonical\n const dot = unsigned.indexOf('.')\n const intPart = dot === -1 ? unsigned : unsigned.slice(0, dot)\n const fracPart = dot === -1 ? '' : unsigned.slice(dot + 1)\n\n const intDigits = intPart === '' ? '0' : intPart\n\n if (fracPart.length <= scale) {\n const keep = fracPart.padEnd(scale, '0')\n const magnitude = BigInt(intDigits + keep)\n return { ok: true, value: negative && magnitude !== 0n ? -magnitude : magnitude }\n }\n\n // More precision than scale — inspect the discarded tail.\n const keep = fracPart.slice(0, scale)\n const tail = fracPart.slice(scale)\n const magnitudeDigits = intDigits + keep\n let magnitude = BigInt(magnitudeDigits)\n\n if (/^0+$/.test(tail)) {\n // tail is all zeros — exact, no rounding required.\n return { ok: true, value: negative && magnitude !== 0n ? -magnitude : magnitude }\n }\n\n if (rounding === undefined) return { ok: false, reason: 'precision' }\n\n const lastKeptDigit = Number(magnitudeDigits[magnitudeDigits.length - 1])\n const firstDiscarded = Number(tail[0])\n const hasMoreNonZeroAfterFirst = /[1-9]/.test(tail.slice(1))\n if (shouldRoundUp(negative, lastKeptDigit, firstDiscarded, hasMoreNonZeroAfterFirst, rounding)) {\n magnitude += 1n\n }\n return { ok: true, value: negative && magnitude !== 0n ? -magnitude : magnitude }\n}\n\n/**\n * Number of fractional digits in the canonical decimal rendering of\n * `input` (`'123.45'` → 2, `100` → 0, `'1e-7'` → 7), or `null` when the\n * input is non-finite / not a decimal. Used to infer the working scale\n * of arithmetic helpers from their canonical-string inputs.\n */\nexport function decimalScaleOf(input: number | string): number | null {\n const s = toCanonicalDecimalString(input)\n if (s === null) return null\n const dot = s.indexOf('.')\n return dot === -1 ? 0 : s.length - dot - 1\n}\n\n/**\n * Re-scale a scaled `BigInt` from `fromScale` to `toScale`. Scaling up\n * is exact (append zeros); scaling down rounds the discarded tail per\n * `rounding`. The rounding decision reuses the same kernel as\n * {@link parseToScaledInt}, so `rescaleScaledInt(parse('1.005', 3), 3, 2)`\n * and `parse('1.005', 2, mode)` agree for every mode.\n */\nexport function rescaleScaledInt(\n value: bigint,\n fromScale: number,\n toScale: number,\n rounding: RoundingMode = 'half-up',\n): bigint {\n if (toScale >= fromScale) return value * 10n ** BigInt(toScale - fromScale)\n const drop = fromScale - toScale\n const negative = value < 0n\n const absStr = (negative ? -value : value).toString().padStart(drop + 1, '0')\n const keptStr = absStr.slice(0, absStr.length - drop)\n const tail = absStr.slice(absStr.length - drop)\n let magnitude = BigInt(keptStr)\n if (!/^0+$/.test(tail)) {\n const lastKeptDigit = Number(keptStr[keptStr.length - 1])\n const firstDiscarded = Number(tail[0])\n const hasMoreNonZeroAfterFirst = /[1-9]/.test(tail.slice(1))\n if (shouldRoundUp(negative, lastKeptDigit, firstDiscarded, hasMoreNonZeroAfterFirst, rounding)) {\n magnitude += 1n\n }\n }\n return negative && magnitude !== 0n ? -magnitude : magnitude\n}\n\n/**\n * Render a scaled `BigInt` back to its canonical decimal string at the\n * given scale. `(12345n, 2)` → `'123.45'`; `(5n, 0)` → `'5'`;\n * `(-1n, 2)` → `'-0.01'`. Exact for any magnitude.\n */\nexport function formatScaledInt(value: bigint, scale: number): string {\n const negative = value < 0n\n const abs = (negative ? -value : value).toString()\n if (scale === 0) return (negative ? '-' : '') + abs\n const padded = abs.padStart(scale + 1, '0')\n const cut = padded.length - scale\n const intPart = padded.slice(0, cut)\n const fracPart = padded.slice(cut)\n return (negative ? '-' : '') + intPart + '.' + fracPart\n}\n","/**\n * Nested-path support for `moneyFields` declarations.\n *\n * A descriptor map key is a PATH, not just a top-level field name:\n *\n * - `'total'` — top-level scalar (the original form)\n * - `'billing.monthlyServiceFee'` — nested object member\n * - `'lineItems[].amount'` — member of every element of an array\n * - `'summary.*'` — every value of a record/map object\n * - `'income[].taxWithheld'`, `'byMonth.*.amount'` — segments compose\n *\n * Paths are parsed ONCE, at collection registration, and a syntactically\n * invalid declaration throws there — loudly, at setup time. (The\n * historical failure mode this kills: a declared-but-unreachable path\n * that was silently ignored, leaving the field un-quantized — a latent\n * 100× bug.) A path that doesn't match a given record at write time is\n * NOT an error — optional fields and empty arrays are legitimate — but\n * a path segment that hits a value of the WRONG SHAPE (`[]` on a\n * non-array, `.*` on a non-object) throws, because that means the\n * declaration and the data model disagree.\n */\n\nimport { ValidationError } from '../../kernel/errors.js'\n\nexport type MoneyPathSegment =\n | { readonly kind: 'key'; readonly key: string; readonly array: boolean }\n | { readonly kind: 'wildcard'; readonly array: boolean }\n\nconst SEGMENT_RE = /^(\\*|[^.[\\]*]+)(\\[\\])?$/\n\nconst parseCache = new Map<string, readonly MoneyPathSegment[]>()\n\n/**\n * Parse a moneyFields path into segments. Throws `ValidationError` on\n * bad syntax. Results are memoized — the same declared paths are walked\n * on every write/read.\n */\nexport function parseMoneyPath(path: string): readonly MoneyPathSegment[] {\n const cached = parseCache.get(path)\n if (cached) return cached\n\n if (typeof path !== 'string' || path.length === 0) {\n throw new ValidationError('moneyFields: path must be a non-empty string')\n }\n const segments: MoneyPathSegment[] = []\n for (const part of path.split('.')) {\n const m = SEGMENT_RE.exec(part)\n if (!m) {\n throw new ValidationError(\n `moneyFields: invalid path \"${path}\" — segment \"${part}\" must be a key, \"key[]\", \"*\", or \"*[]\"`,\n )\n }\n const array = m[2] === '[]'\n segments.push(\n m[1] === '*' ? { kind: 'wildcard', array } : { kind: 'key', key: m[1]!, array },\n )\n }\n parseCache.set(path, segments)\n return segments\n}\n\n/** True when the path is a plain top-level field name (the fast path). */\nexport function isSimpleMoneyPath(path: string): boolean {\n return !path.includes('.') && !path.includes('[') && !path.includes('*')\n}\n\n/**\n * Validate every declared path's syntax. Call at collection\n * registration so typos throw at setup, not silently no-op per write.\n */\nexport function validateMoneyFieldPaths(moneyFields: Record<string, unknown>): void {\n for (const path of Object.keys(moneyFields)) parseMoneyPath(path)\n}\n\n/**\n * The leaf visitor: receives the (already-cloned) container holding the\n * money value and the key/index of that value. Mutating the container\n * is safe — every container on a matched path is a fresh clone.\n */\nexport type MoneyLeafVisitor = (\n container: Record<string, unknown> | unknown[],\n key: string | number,\n) => void\n\n/**\n * Walk `node` along `segments`, copy-on-write-cloning every container on\n * a matched path, and call `visit` at each leaf position. Returns the\n * (possibly new) node; unmatched paths return the input untouched.\n *\n * Shape mismatches (`[]` on a non-array, `*` on a non-object) THROW on\n * the write path — the declaration and the data model disagree, and\n * writing through would store an un-quantized amount. On the READ path\n * pass `lenient: true` instead: stored data predating a declaration\n * change must stay readable, so a mismatched node is returned untouched\n * (mirrors the defensive `continue` the flat decoder always had).\n */\nexport function transformAtMoneyPath(\n node: unknown,\n path: string,\n segments: readonly MoneyPathSegment[],\n index: number,\n visit: MoneyLeafVisitor,\n lenient: boolean,\n): unknown {\n if (node === null || node === undefined) return node\n const seg = segments[index]!\n const last = index === segments.length - 1\n\n if (seg.kind === 'key') {\n if (typeof node !== 'object' || Array.isArray(node)) {\n if (lenient) return node\n throw new ValidationError(\n `moneyFields: path \"${path}\" expected an object at segment \"${seg.key}\", got ${Array.isArray(node) ? 'an array' : typeof node}`,\n )\n }\n const obj = node as Record<string, unknown>\n if (!(seg.key in obj) || obj[seg.key] === null || obj[seg.key] === undefined) return node\n\n if (seg.array) {\n const arr = obj[seg.key]\n if (!Array.isArray(arr)) {\n if (lenient) return node\n throw new ValidationError(\n `moneyFields: path \"${path}\" declares \"${seg.key}[]\" but the value is not an array`,\n )\n }\n const cloned = [...arr]\n if (last) {\n for (let i = 0; i < cloned.length; i++) visit(cloned, i)\n } else {\n for (let i = 0; i < cloned.length; i++) {\n cloned[i] = transformAtMoneyPath(cloned[i], path, segments, index + 1, visit, lenient)\n }\n }\n return { ...obj, [seg.key]: cloned }\n }\n\n const clone = { ...obj }\n if (last) {\n visit(clone, seg.key)\n } else {\n clone[seg.key] = transformAtMoneyPath(clone[seg.key], path, segments, index + 1, visit, lenient)\n }\n return clone\n }\n\n // wildcard\n if (seg.array) {\n if (!Array.isArray(node)) {\n if (lenient) return node\n throw new ValidationError(`moneyFields: path \"${path}\" declares \"*[]\" but the value is not an array`)\n }\n const cloned = [...node]\n if (last) {\n for (let i = 0; i < cloned.length; i++) visit(cloned, i)\n } else {\n for (let i = 0; i < cloned.length; i++) {\n cloned[i] = transformAtMoneyPath(cloned[i], path, segments, index + 1, visit, lenient)\n }\n }\n return cloned\n }\n if (typeof node !== 'object' || Array.isArray(node)) {\n if (lenient) return node\n throw new ValidationError(\n `moneyFields: path \"${path}\" applies \"*\" to a non-object (${Array.isArray(node) ? 'array — use \"*[]\"' : typeof node})`,\n )\n }\n const obj = node as Record<string, unknown>\n const clone: Record<string, unknown> = { ...obj }\n for (const key of Object.keys(obj)) {\n const v = clone[key]\n if (v === null || v === undefined) continue\n if (last) visit(clone, key)\n else clone[key] = transformAtMoneyPath(v, path, segments, index + 1, visit, lenient)\n }\n return clone\n}\n","/**\n * Write-side and read-side normalization for money fields.\n *\n * - **Write** ({@link quantizeMoneyFields}): user input (`number | string`,\n * or `{ amount, currency }` in multi mode) → the canonical *stored*\n * form — a scaled-integer **digit string** (`'12345'`), or\n * `{ amount: '12345', currency: 'EUR' }` in multi mode. A JSON number\n * would truncate past 2^53, so the integer is always stored as a string.\n * - **Read** ({@link decodeMoneyFields}): stored form → an exact decimal\n * string (`'123.45'`) plus, when formatting is requested, the virtual\n * `<field>Formatted` (locale currency string) and `<field>Number`\n * (convenience JS number, explicitly lossy past 2^53).\n *\n * Both return a shallow clone; neither mutates the input record.\n */\n\nimport { parseToScaledInt, formatScaledInt } from './fixed-point.js'\nimport { MoneyPrecisionError, type MoneyDescriptor } from './descriptor.js'\nimport { isSimpleMoneyPath, parseMoneyPath, transformAtMoneyPath } from './paths.js'\n\ninterface MoneyValueObject {\n amount: unknown\n currency: unknown\n}\n\nfunction isMoneyValueObject(v: unknown): v is MoneyValueObject {\n return typeof v === 'object' && v !== null && 'currency' in v\n}\n\n/** Parse one decimal input to a stored digit string at `scale`. */\nfunction quantizeAmount(\n field: string,\n input: number | string,\n scale: number,\n rounding: MoneyDescriptor['rounding'],\n): string {\n const r = parseToScaledInt(input, scale, rounding)\n if (!r.ok) {\n if (r.reason === 'precision') throw new MoneyPrecisionError(field, input, scale)\n throw new TypeError(`money: field \"${field}\" value ${JSON.stringify(input)} is not a finite decimal`)\n }\n return r.value.toString()\n}\n\n/**\n * Canonicalize a STORED-form record's money fields for an internal\n * callback boundary. Gate handlers (guard `check` /\n * `frozenFields` / `onDelete`, period guard, amendment invariants) and\n * derivation `derive(source, ctx)` callbacks are user-facing: they must\n * see the same decoded canonical decimal that `get()` returns — the\n * scaled-int storage form never escapes. Decoded with `'raw'` (no\n * `<field>Formatted`/`<field>Number` virtuals): these boundaries carry\n * no locale, and fabricating one would re-create a two-read-paths\n * skew inside comparisons.\n */\nexport function canonicalizeStoredMoney(\n record: unknown,\n moneyFields: Record<string, MoneyDescriptor> | undefined,\n): unknown {\n if (record === null || record === undefined) return record\n if (!moneyFields || Object.keys(moneyFields).length === 0) return record\n return decodeMoneyFields(record as Record<string, unknown>, moneyFields, 'raw')\n}\n\n/**\n * Canonicalize an INCOMING record's money fields at the top of the\n * write pipeline. Raw user input (pre-quantize) may hold a\n * number (`10000`), a major-unit string (`'10000.00'`), or a spread of\n * an already-decoded read. Quantize→decode folds all three to the\n * canonical decimal string, so gate handlers, computed-field\n * callbacks, and schema validation all see the `get()` shape — and\n * freeze-style guards comparing `incoming[f]` vs `existing[f]` see\n * equal values for an unchanged field. Best-effort: input that fails\n * to quantize passes through unchanged — the write path quantizes\n * again after validation and surfaces the real\n * `MoneyPrecisionError`/`TypeError`.\n */\nexport function canonicalizeIncomingMoney(\n record: unknown,\n moneyFields: Record<string, MoneyDescriptor> | undefined,\n): unknown {\n if (!moneyFields || Object.keys(moneyFields).length === 0) return record\n try {\n return decodeMoneyFields(\n quantizeMoneyFields(stripMoneyVirtuals(record as Record<string, unknown>, moneyFields), moneyFields),\n moneyFields,\n 'raw',\n )\n } catch {\n return record\n }\n}\n\n/**\n * family#201 — DROP the `<path>Formatted` / `<path>Number` read virtuals a\n * caller carried in, before quantizing.\n *\n * ⛔ WHY. `'raw'` stops this function ADDING virtuals, but `decodeMoneyFields`\n * shallow-clones (`{ ...record }`), so virtuals already on the record survive —\n * and the commonest write there is is `const r = await coll.get(id, { locale });\n * await coll.put(id, r)`. The gate's `existing` goes through\n * {@link canonicalizeStoredMoney}, which carries none, so `frozenFields`\n * deep-compared `{ amount, sku, amountFormatted, amountNumber }` against\n * `{ amount, sku }` and refused an UNCHANGED re-put with `FieldFrozenError`.\n * Measured on a NESTED money path (`'line.amount'`): a top-level path compares\n * scalar-to-scalar and never saw it.\n *\n * ⭐ This is {@link canonicalizeStoredMoney}'s own stated rule applied to the\n * other side: those boundaries carry no locale, and letting a virtual through\n * \"would re-create a two-read-paths skew inside comparisons\". It also stops a\n * locale-formatted string being PERSISTED — measured: a round-tripped read\n * stored `amountFormatted` and it came back out of `locale: 'raw'`, where it\n * would go stale and carry one client's locale forever.\n *\n * ⚠️ A caller's own field named `<moneyPath>Formatted` is dropped too. That\n * name is already owned by the read path, which overwrites it on every\n * localized read, so it could never hold a value of theirs reliably.\n */\nfunction stripMoneyVirtuals(\n record: Record<string, unknown>,\n moneyFields: Record<string, MoneyDescriptor>,\n): Record<string, unknown> {\n let out: Record<string, unknown> = { ...record }\n for (const path of Object.keys(moneyFields)) {\n if (isSimpleMoneyPath(path)) {\n delete out[`${path}Formatted`]\n delete out[`${path}Number`]\n continue\n }\n // ⚠️ `parseMoneyPath` returns SEGMENT OBJECTS (`{ kind, key, array }`), not\n // strings. A `typeof leaf !== 'string'` guard here silently skipped every\n // nested path — the strip ran and did nothing, which is the one shape this\n // whole function exists for.\n out = transformAtMoneyPath(out, path, parseMoneyPath(path), 0, (container, key) => {\n if (typeof key !== 'string' || Array.isArray(container)) return\n delete container[`${key}Formatted`]\n delete container[`${key}Number`]\n }, /* lenient */ true) as Record<string, unknown>\n }\n return out\n}\n\n/** Quantize ONE field value (any nesting level) to its stored form. */\nfunction quantizeValue(field: string, raw: unknown, desc: MoneyDescriptor): unknown {\n if (desc.mode === 'fixed') {\n const currency = desc.fixedCurrency!\n return quantizeAmount(field, raw as number | string, desc.scaleFor(currency), desc.rounding)\n }\n // multi mode\n let amount: number | string\n let currency: string\n if (isMoneyValueObject(raw)) {\n currency = String(raw.currency)\n amount = raw.amount as number | string\n } else {\n const sole = desc.soleCurrency()\n if (sole === undefined) {\n throw new TypeError(\n `money: field \"${field}\" is multi-currency — write { amount, currency }, not a bare amount`,\n )\n }\n currency = sole\n amount = raw as number | string\n }\n const scale = desc.scaleFor(currency) // throws MoneyCurrencyError if disallowed\n return { amount: quantizeAmount(field, amount, scale, desc.rounding), currency }\n}\n\n/**\n * Canonicalize money values for a MATERIALIZED-VIEW row (#1018).\n *\n * A money field in an MV row is NOT in the scaled-integer storage form a\n * collection uses — the money-aware reducers emit `formatScaledInt(...)`, an\n * exact decimal string, and that is what lands in the output collection. So a\n * derived money field has to be canonicalized into the same shape as the\n * aggregated ones beside it.\n *\n * Quantizing it into storage form instead is what #1018 reported: `toPay` came\n * back as `\"1000000\"` where `netTotal` in the SAME row read `\"10000.00\"` —\n * 100× the true value, and a string that looks like a plausible amount rather\n * than an obvious error.\n *\n * Precision handling is identical to {@link quantizeMoneyFields} — the same\n * `parseToScaledInt` and the same `MoneyPrecisionError` — so a value that\n * cannot be represented at the declared scale is still refused rather than\n * silently rounded. Only the OUTPUT shape differs: decimal, not scaled.\n */\nexport function canonicalizeMoneyFieldsAsDecimal<T extends Record<string, unknown>>(\n record: T,\n moneyFields: Record<string, MoneyDescriptor>,\n): T {\n const out: Record<string, unknown> = { ...record }\n for (const [field, desc] of Object.entries(moneyFields)) {\n // Only simple top-level fields: an MV row is the flat product of\n // groupBy + aggregate + derive, so there are no nested money paths here.\n if (!isSimpleMoneyPath(field)) continue\n const raw = out[field]\n if (raw === null || raw === undefined) continue\n\n let amount: number | string\n let scale: number\n if (desc.mode === 'fixed') {\n amount = raw as number | string\n scale = desc.scaleFor(desc.fixedCurrency!)\n } else if (isMoneyValueObject(raw)) {\n amount = raw.amount as number | string\n scale = desc.scaleFor(String(raw.currency))\n } else {\n const sole = desc.soleCurrency()\n if (sole === undefined) {\n throw new TypeError(\n `money: field \"${field}\" is multi-currency — a derived value must be ` +\n '{ amount, currency }, not a bare amount',\n )\n }\n amount = raw as number | string\n scale = desc.scaleFor(sole)\n }\n\n const r = parseToScaledInt(amount, scale, desc.rounding)\n if (!r.ok) {\n if (r.reason === 'precision') throw new MoneyPrecisionError(field, amount, scale)\n throw new TypeError(`money: field \"${field}\" value ${JSON.stringify(amount)} is not a finite decimal`)\n }\n const decimal = formatScaledInt(r.value, scale)\n out[field] = desc.mode === 'fixed' || !isMoneyValueObject(raw)\n ? decimal\n : { amount: decimal, currency: String(raw.currency) }\n }\n return out as T\n}\n\n/**\n * Convert money fields in `record` from user input to their canonical\n * stored form. Returns a shallow clone (deep along declared nested\n * paths). A nested path whose declared shape disagrees with the\n * data throws: writing through would store an un-quantized amount.\n */\nexport function quantizeMoneyFields<T extends Record<string, unknown>>(\n record: T,\n moneyFields: Record<string, MoneyDescriptor>,\n): T {\n let out: Record<string, unknown> = { ...record }\n for (const [path, desc] of Object.entries(moneyFields)) {\n if (isSimpleMoneyPath(path)) {\n const raw = out[path]\n if (raw === null || raw === undefined) continue\n out[path] = quantizeValue(path, raw, desc)\n continue\n }\n out = transformAtMoneyPath(out, path, parseMoneyPath(path), 0, (container, key) => {\n const raw = (container as Record<string | number, unknown>)[key]\n if (raw === null || raw === undefined) return\n ;(container as Record<string | number, unknown>)[key] = quantizeValue(path, raw, desc)\n }, /* lenient */ false) as Record<string, unknown>\n }\n return out as T\n}\n\nfunction formatCurrency(decimal: string, currency: string, scale: number, locale: string): string {\n const fmt = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n minimumFractionDigits: scale,\n maximumFractionDigits: scale,\n })\n // V8's Intl.format accepts a decimal STRING and formats it at full\n // precision (exact past 2^53). The TS lib types only declare\n // number|bigint, so cast — a number arg here would re-introduce the\n // float drift this whole feature exists to eliminate.\n return (fmt.format as unknown as (value: string) => string)(decimal)\n}\n\n/**\n * The stored scaled-integer value of a money field as a `BigInt`, for\n * exact numeric comparison (e.g. `orderBy` / sorting), or `null` when the\n * stored value is missing/malformed. Mirrors the stored form `decodeValue`\n * reads: a bare scaled-int (fixed mode) or `{ amount, currency }`\n * (multi-currency). Comparison is in scaled space and is exact within a\n * single currency/scale (the `where` / `sum` BigInt model); across\n * currencies of different scales the raw scaled comparison is best-effort.\n */\nexport function moneyScaledValue(stored: unknown, desc: MoneyDescriptor): bigint | null {\n let raw: unknown\n if (desc.mode === 'fixed') {\n raw = stored\n } else {\n if (!isMoneyValueObject(stored)) return null\n raw = stored.amount\n }\n if (typeof raw !== 'string' && typeof raw !== 'number') return null\n try {\n return BigInt(String(raw))\n } catch {\n return null\n }\n}\n\n/**\n * The `NoydbVia.canonicalizeIndexKey` implementation for money (#672) —\n * bucket an eager index's money field entries by the BigInt-normalized\n * scaled-int string, not the raw stored bytes, so a pre-declaration /\n * non-canonical value (e.g. `'0100'`) lands under the SAME key a canonical\n * write produces (`'100'`). Only FIXED-mode declared money fields\n * participate — multi-mode stores `{ amount, currency }`, which has no\n * single bucketable scalar (mirrors `moneyIndexProbe`'s fixed-only gate,\n * `via/money/where.ts`). `undefined` when `field` isn't a declared\n * fixed-mode money field, or the stored value doesn't parse — in both\n * cases the caller falls back to the raw stringified bucket, which is\n * exactly what the scan (`evaluateMoneyClause`) also treats as a\n * non-match, preserving fast-path/scan parity.\n */\nexport function canonicalizeMoneyIndexKey(\n field: string,\n rawValue: unknown,\n moneyFields: Record<string, MoneyDescriptor>,\n): string | undefined {\n const desc = moneyFields[field]\n if (!desc || desc.mode !== 'fixed') return undefined\n return moneyScaledValue(rawValue, desc)?.toString()\n}\n\n/**\n * Decode ONE stored field value to its read shape, or `null` when the\n * stored value is malformed (defensive — never brick a read).\n */\nfunction decodeValue(\n stored: unknown,\n desc: MoneyDescriptor,\n): { decoded: unknown; decimal: string; currency: string; scale: number } | null {\n let currency: string\n let scaledIntString: string\n if (desc.mode === 'fixed') {\n if (typeof stored !== 'string' && typeof stored !== 'number') return null\n currency = desc.fixedCurrency!\n scaledIntString = String(stored)\n } else {\n if (!isMoneyValueObject(stored)) return null // defensive: malformed stored value\n const amount = stored.amount\n if (typeof stored.currency !== 'string' || (typeof amount !== 'string' && typeof amount !== 'number')) return null\n currency = stored.currency\n scaledIntString = String(amount)\n }\n const scale = desc.scaleFor(currency)\n let decimal: string\n try {\n decimal = formatScaledInt(BigInt(scaledIntString), scale)\n } catch {\n return null // defensive: non-integer stored value\n }\n return {\n decoded: desc.mode === 'fixed' ? decimal : { amount: decimal, currency },\n decimal,\n currency,\n scale,\n }\n}\n\n/**\n * money's `presentLate` hook (#669) — for each field in `virtualMoney` (money ∩\n * virtual-mode computed on the SAME field), quantize the computed fn's fresh\n * MAJOR-UNITS output to the descriptor's scale (with its declared rounding)\n * and present it EXACTLY like a stored money field: the exact decimal string\n * (via {@link formatScaledInt}), plus `<field>Formatted`/`<field>Number` when\n * `locale !== 'raw'`. NEVER the scaled-int decode {@link decodeMoneyFields}\n * runs for a genuinely-stored value — that would misread a virtual field's\n * raw major-unit `21` as 21 SCALED units (`'0.21'`, the #665 corruption this\n * must not reintroduce). Runs AFTER computed's `present()` (the pipeline's\n * `presentLate` fold point, `kernel/via/pipeline.ts`), so `record[field]`\n * already holds the fn's fresh output by the time this runs.\n *\n * Absent/null value → left untouched (nothing to dress). Unparseable value\n * (fails `parseToScaledInt` — e.g. excess precision with no declared\n * rounding) → left RAW, no throw: read-time dressing must never brick a\n * read. Fixed-mode fields only — a virtual field's computed output has no\n * natural `{ amount, currency }` shape to parse for multi-currency mode.\n */\nexport function presentVirtualMoneyFields<T extends Record<string, unknown>>(\n record: T,\n moneyFields: Record<string, MoneyDescriptor>,\n virtualMoney: ReadonlySet<string>,\n locale: string | undefined,\n): T {\n let out: Record<string, unknown> = record\n const format = locale !== 'raw'\n const fmtLocale = typeof locale === 'string' && locale !== 'raw' ? locale : 'en-US'\n for (const field of virtualMoney) {\n const desc = moneyFields[field]\n if (!desc || desc.mode !== 'fixed') continue\n const raw = out[field]\n if (raw === null || raw === undefined) continue\n if (typeof raw !== 'number' && typeof raw !== 'string') continue\n const currency = desc.fixedCurrency!\n const scale = desc.scaleFor(currency)\n const r = parseToScaledInt(raw, scale, desc.rounding)\n if (!r.ok) continue // unparseable / excess precision with no rounding declared — leave raw, no throw\n if (out === record) out = { ...record }\n const decimal = formatScaledInt(r.value, scale)\n out[field] = decimal\n if (format) {\n out[`${field}Formatted`] = formatCurrency(decimal, currency, scale, fmtLocale)\n out[`${field}Number`] = Number(decimal)\n }\n }\n return out as T\n}\n\n/**\n * Convert money fields in `record` from stored form to the read shape:\n * an exact decimal string, plus `<field>Formatted` / `<field>Number`\n * virtuals when `locale !== 'raw'`. Returns a shallow clone (deep along\n * declared nested paths; virtuals land as siblings inside the\n * nested container, e.g. each `lineItems[]` element gains\n * `amountFormatted`, except for values held directly in arrays where a\n * scalar has no sibling slot). The decode walk is LENIENT: stored data\n * predating a declaration change must stay readable.\n */\nexport function decodeMoneyFields<T extends Record<string, unknown>>(\n record: T,\n moneyFields: Record<string, MoneyDescriptor>,\n locale: string | undefined,\n): T {\n let out: Record<string, unknown> = { ...record }\n const format = locale !== 'raw'\n const fmtLocale = typeof locale === 'string' && locale !== 'raw' ? locale : 'en-US'\n\n for (const [path, desc] of Object.entries(moneyFields)) {\n if (isSimpleMoneyPath(path)) {\n const stored = out[path]\n if (stored === null || stored === undefined) continue\n const r = decodeValue(stored, desc)\n if (r === null) continue\n out[path] = r.decoded\n if (format) {\n out[`${path}Formatted`] = formatCurrency(r.decimal, r.currency, r.scale, fmtLocale)\n out[`${path}Number`] = Number(r.decimal)\n }\n continue\n }\n out = transformAtMoneyPath(out, path, parseMoneyPath(path), 0, (container, key) => {\n const stored = (container as Record<string | number, unknown>)[key]\n if (stored === null || stored === undefined) return\n const r = decodeValue(stored, desc)\n if (r === null) return\n ;(container as Record<string | number, unknown>)[key] = r.decoded\n if (format && typeof key === 'string' && !Array.isArray(container)) {\n container[`${key}Formatted`] = formatCurrency(r.decimal, r.currency, r.scale, fmtLocale)\n container[`${key}Number`] = Number(r.decimal)\n }\n }, /* lenient */ true) as Record<string, unknown>\n }\n return out as T\n}\n","/**\n * Money-aware `where()` comparison.\n *\n * Query clauses evaluate against RAW stored records — money decode\n * happens on output only — so a money field's stored form is a\n * scaled-integer digit string (`'1000000'`) while the caller naturally\n * writes the operand in major units (`10000`, `'10000.00'`). Without a\n * rewrite the comparison is silently wrong by the scale factor, and a\n * string-vs-number comparison is excluded by `isComparable` anyway.\n *\n * Two halves:\n *\n * - {@link moneyFieldClause} runs at QUERY BUILD time: it quantizes the\n * caller's major-unit operand into stored scaled-int space via the\n * same `parseToScaledInt` path as writes, so a malformed operand\n * throws at `.where()` — not silently filters everything out.\n * - {@link evaluateMoneyClause} runs per record and compares\n * `BigInt`-exact in scaled space (exact past 2^53, like the rest of\n * the money service).\n *\n * Currency semantics (multi mode): an operand carries one currency —\n * explicit via `{ amount, currency }`, or the descriptor's sole allowed\n * currency for a bare amount. A record in a DIFFERENT currency has no\n * defined order against the operand: it matches `!=` and nothing else.\n */\n\nimport { parseToScaledInt } from './fixed-point.js'\nimport { MoneyUnsupportedError, type MoneyDescriptor } from './descriptor.js'\nimport type { Operator } from '../../kernel/query/predicate.js'\n\n/** One quantized operand value: scaled digit string + its currency. */\ninterface MoneyOperandEntry {\n readonly scaled: string\n readonly currency: string\n}\n\n/**\n * The opaque `via` clause payload for a `where()` over a declared money\n * field (see `NoydbVia.buildClause` in kernel/via/index.ts). `entries` holds\n * one element for comparison ops, two for `between` (lo, hi — same\n * currency), N for `in`.\n */\nexport interface MoneyWhereOperand {\n readonly mode: 'fixed' | 'multi'\n readonly entries: ReadonlyArray<MoneyOperandEntry>\n}\n\ninterface MoneyValueObject {\n amount: unknown\n currency: unknown\n}\n\nfunction isMoneyValueObject(v: unknown): v is MoneyValueObject {\n return typeof v === 'object' && v !== null && 'currency' in v\n}\n\n/** Quantize ONE operand value to scaled space, resolving its currency. */\nfunction parseOperand(field: string, raw: unknown, desc: MoneyDescriptor): MoneyOperandEntry {\n let amount: unknown\n let currency: string\n if (desc.mode === 'fixed') {\n currency = desc.fixedCurrency!\n amount = raw\n } else if (isMoneyValueObject(raw)) {\n currency = String(raw.currency)\n amount = raw.amount\n } else {\n const sole = desc.soleCurrency()\n if (sole === undefined) {\n throw new MoneyUnsupportedError(\n `where(\"${field}\"): field is multi-currency — compare against { amount, currency }, not a bare amount`,\n )\n }\n currency = sole\n amount = raw\n }\n if (typeof amount !== 'number' && typeof amount !== 'string') {\n throw new MoneyUnsupportedError(\n `where(\"${field}\"): operand ${JSON.stringify(raw)} is not a money amount`,\n )\n }\n const r = parseToScaledInt(amount, desc.scaleFor(currency), desc.rounding)\n if (!r.ok) {\n throw new MoneyUnsupportedError(\n `where(\"${field}\"): operand ${JSON.stringify(amount)} is not a finite decimal`,\n )\n }\n return { scaled: r.value.toString(), currency }\n}\n\n/**\n * Build the `via` clause payload ({@link MoneyWhereOperand}) for a\n * `where()` over a declared money field — the `NoydbVia.buildClause`\n * implementation for money. The operand is quantized into stored\n * scaled-int space NOW — build time — so typos throw at the call site.\n */\nexport function moneyFieldClause(\n field: string,\n op: Operator,\n value: unknown,\n desc: MoneyDescriptor,\n): MoneyWhereOperand {\n switch (op) {\n case '==': case '!=': case '<': case '<=': case '>': case '>=': {\n const e = parseOperand(field, value, desc)\n return { mode: desc.mode, entries: [e] }\n }\n case 'between': {\n if (!Array.isArray(value) || value.length !== 2) {\n throw new MoneyUnsupportedError(`where(\"${field}\"): 'between' needs a [lo, hi] tuple`)\n }\n const lo = parseOperand(field, value[0], desc)\n const hi = parseOperand(field, value[1], desc)\n if (lo.currency !== hi.currency) {\n throw new MoneyUnsupportedError(\n `where(\"${field}\"): 'between' bounds mix currencies (${lo.currency} vs ${hi.currency})`,\n )\n }\n return { mode: desc.mode, entries: [lo, hi] }\n }\n case 'in': {\n if (!Array.isArray(value)) {\n throw new MoneyUnsupportedError(`where(\"${field}\"): 'in' needs an array of amounts`)\n }\n return { mode: desc.mode, entries: value.map(v => parseOperand(field, v, desc)) }\n }\n default:\n // contains / startsWith — string ops have no meaning in scaled space.\n throw new MoneyUnsupportedError(\n `where(\"${field}\"): operator '${op}' is not supported on a money field`,\n )\n }\n}\n\n/**\n * The `via` index-probe operand for a `where()` over a declared money\n * field (see `NoydbVia.indexProbe` in kernel/via/index.ts) — the STORED-form\n * value `CollectionIndexes.lookupEqual`/`lookupIn` (`with-lookup/indexing/\n * eager-indexes.ts`) can bucket directly.\n *\n * Only FIXED-mode `==`/`in` are sound:\n * - fixed-mode stores a bare scaled-int digit string (no currency\n * component), and `entries[i].scaled` is built by {@link parseOperand}\n * via the exact same `parseToScaledInt(...).value.toString()` path\n * `quantizeMoneyFields` (`via-money/normalize.ts#quantizeAmount`) uses\n * to produce the STORED value — so the two strings are byte-identical\n * by construction, and `stringifyKey` (which passes a string through\n * unchanged) buckets them the same way.\n * - multi-mode stores `{ amount, currency }` — the index would stringify\n * that object to its no-match `'\\0OBJECT\\0'` sentinel — so multi-mode\n * always returns `undefined` (no sound probe).\n * - every op besides `==`/`in` (range comparisons, `between`) has no\n * single stored-form value the hash index can serve, so they return\n * `undefined` too — the caller falls back to a scan.\n *\n * MIXED-ERA DATA (#672, fixed — including the #672 review's C1 finding): a\n * record whose stored value predates the field's `money()` declaration, or\n * otherwise bypassed `quantizeMoneyFields`, may hold a NON-canonical scaled\n * string (e.g. `'0100'` instead of `'100'`). `CollectionIndexes` no longer\n * buckets it under that raw string verbatim at ANY bucket-mutation site —\n * `build`, `upsert`, and `remove` all consult the same registered\n * canonicalizer (`ViaPipeline.canonicalizeIndexKey`; money's implementation:\n * `canonicalizeMoneyIndexKey`, `via/money/normalize.ts`), which re-parses the\n * stored value the same way the scan's `evaluateMoneyClause`/`readStored`\n * does (`BigInt(actual).toString()`). So the legacy record lands in the SAME\n * bucket a canonical write produces, an `==`/`in` probe for `'100'` finds it,\n * and — because add and remove now agree on that bucket — a later `put()`\n * (update) or `delete()` of that same legacy record cleans up the correct\n * bucket instead of stranding the id under a bucket the removal could never\n * reach. The two-string byte-identity argument above still explains WHY a\n * canonical write's probe hits directly (no canonicalization needed for the\n * common case); this note covers the pre-declaration tail.\n *\n * Boundary — CLOSED for the index layer (#677): LAZY mode's\n * `PersistedCollectionIndex` (`with-lookup/indexing/persisted-indexes.ts`)\n * now consults the SAME `ViaPipeline.canonicalizeIndexKey` at every\n * bucket-mutation site (`ingest`/`upsert`/`remove`) as `CollectionIndexes`\n * does, and its query path (`with-lookup/indexing/lazy-builder.ts`'s\n * `resolveCandidateIds()`) canonicalizes the `==`/`in` probe value before\n * calling `lookupEqual`/`lookupIn` — mirroring `candidateRecords()` above\n * resolving `indexValue` before its own `lookupEqual`/`lookupIn` call. A\n * lazy-mode mixed-era record's bucket and a canonicalized probe now agree,\n * the same as eager mode.\n *\n * Residual boundary CLOSED by #684: `LazyQuery.where()` now builds\n * `clause.via` exactly like `Query.where()`/`ScanBuilder.where()` do, and\n * `LazyQuery`'s post-filter (`lazy-builder.ts`'s `toArray()`) runs it\n * against the RAW record (a dedicated raw-fetch seam on `Collection`, split\n * out of `get()`) instead of the DECODED one — `clause.via.evaluate` (this\n * file's {@link evaluateMoneyClause}) now sees the same stored-form\n * operand/actual-value space eager's `filterRecords` does, at any `scale`.\n * Only survivors are decoded (`present()`) on the way out. Money RANGE\n * clauses additionally route around `PersistedCollectionIndex.lookupRange`\n * (raw/typed, wrong space for scaled-int money) — `resolveCandidateIds()`\n * enumerates the field's indexed ids instead and lets this now-via-aware\n * post-filter apply the correct BigInt-exact comparison. `lazyQuery().\n * where()` on a money field now agrees with `scan().where()` /\n * `query().where()` at every `scale` — for `.where()` results specifically.\n * `orderBy` ordering is a separate, still-open lazy-vs-eager divergence,\n * tracked in #695.\n */\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\nexport function moneyIndexProbe(op: Operator, payload: MoneyWhereOperand): unknown | undefined {\n if (payload.mode !== 'fixed') return undefined\n if (op === '==') return payload.entries[0]?.scaled\n if (op === 'in') return payload.entries.map(e => e.scaled)\n return undefined\n}\n\n/** Read a raw STORED money value into scaled space, or null if absent/malformed. */\nfunction readStored(actual: unknown, operand: MoneyWhereOperand): MoneyOperandEntry | null {\n let amount: unknown\n let currency: string\n if (operand.mode === 'fixed') {\n if (typeof actual !== 'string' && typeof actual !== 'number') return null\n amount = actual\n currency = operand.entries[0]?.currency ?? ''\n } else {\n if (!isMoneyValueObject(actual)) return null\n if (typeof actual.currency !== 'string') return null\n amount = actual.amount\n currency = actual.currency\n }\n if (typeof amount !== 'string' && typeof amount !== 'number') return null\n try {\n return { scaled: BigInt(amount).toString(), currency }\n } catch {\n return null\n }\n}\n\n/**\n * Per-record evaluation of a money clause: BigInt-exact comparison in\n * scaled-integer space. `actual` is the RAW stored field value.\n *\n * Missing/malformed stored values and cross-currency comparisons match\n * `!=` only — consistent with the generic clause semantics where an\n * absent field is \"not equal\" and has no defined order.\n */\nexport function evaluateMoneyClause(\n actual: unknown,\n op: Operator,\n operand: MoneyWhereOperand,\n): boolean {\n const stored = readStored(actual, operand)\n if (stored === null) return op === '!='\n const a = BigInt(stored.scaled)\n\n if (op === 'in') {\n return operand.entries.some(\n e => e.currency === stored.currency && BigInt(e.scaled) === a,\n )\n }\n if (op === 'between') {\n const [lo, hi] = operand.entries\n if (!lo || !hi || lo.currency !== stored.currency) return false\n return a >= BigInt(lo.scaled) && a <= BigInt(hi.scaled)\n }\n\n const e = operand.entries[0]\n if (!e) return false\n if (e.currency !== stored.currency) return op === '!='\n const b = BigInt(e.scaled)\n switch (op) {\n case '==': return a === b\n case '!=': return a !== b\n case '<': return a < b\n case '<=': return a <= b\n case '>': return a > b\n case '>=': return a >= b\n default: return false\n }\n}\n","/**\n * Money-aware aggregation: exact `sum` / `min` / `max` over money\n * fields.\n *\n * The generic reducers (`aggregate/reducers.ts`) read a field via\n * `readNumber`, which coerces a string (the stored scaled-integer form\n * of money, e.g. `'12345'`) to `0` — so an un-wrapped money `sum` would\n * silently return zero. {@link wrapMoneyReducers} rewrites any `sum` /\n * `min` / `max` over a declared money field into a reducer that\n * accumulates per-currency `BigInt` totals of the stored integers, so\n * the result is exact for any magnitude (past `Number.MAX_SAFE_INTEGER`\n * included).\n *\n * Results are currency-aware and never silently mix currencies:\n * - **fixed** mode → a single exact decimal string.\n * - **multi** mode → an exact `Record<currency, string>` map.\n * - **`sum` with `convertTo` + `fx`** → a single exact string, with\n * each currency converted via BigInt arithmetic (no float).\n *\n * `remove()` is implemented for every money reducer so they participate\n * in incremental live-aggregation and materialized-view maintenance\n * exactly like the generic reducers they replace.\n */\n\nimport { readPath } from '../../kernel/query/predicate.js'\nimport { formatScaledInt, parseToScaledInt } from './fixed-point.js'\nimport { scaleForCurrency } from './iso4217.js'\nimport { MoneyUnsupportedError } from './descriptor.js'\nimport type { MoneyDescriptor } from './descriptor.js'\nimport type { Reducer } from '../../with-lookup/reduce/reducers.js'\nimport type { ReduceSpec } from '../../with-lookup/reduce/reduction.js'\n\nexport type FxRates = Record<string, number | string>\n\ninterface ReadMoney {\n currency: string\n value: bigint\n}\n\n/**\n * Coerce an arbitrary money-field value into its scaled `BigInt` at the\n * given `scale`. Handles the two shapes a money field can arrive in by\n * the time it reaches a reducer:\n *\n * - **stored form** — a bare scaled-integer string (`'12345'`) or a\n * `bigint`. No decimal point, so `BigInt(v)` is the fast path.\n * - **decoded form** — a canonical decimal string (`'123.45'`), which\n * is what `query().toArray()` / `decodeMoneyFields` produce (UNION\n * arms map over decoded rows). `BigInt('123.45')` throws, so these\n * route through `parseToScaledInt(v, scale)`.\n *\n * A `number` is treated as a decimal magnitude (parsed at `scale`).\n * Anything unparseable → `null`.\n */\nfunction toScaledIntFromAny(v: unknown, scale: number): bigint | null {\n if (typeof v === 'bigint') return v\n if (typeof v === 'number') {\n const r = parseToScaledInt(v, scale)\n return r.ok ? r.value : null\n }\n if (typeof v === 'string') {\n if (!v.includes('.')) {\n // Stored scaled-integer form (e.g. '12345') — no decimal point.\n try {\n return BigInt(v)\n } catch {\n return null\n }\n }\n // Decoded canonical-decimal form (e.g. '123.45').\n const r = parseToScaledInt(v, scale)\n return r.ok ? r.value : null\n }\n return null\n}\n\n/** Read the raw stored money value (scaled integer) from a record. */\nfunction readMoney(record: unknown, field: string, desc: MoneyDescriptor): ReadMoney | null {\n const raw = readPath(record, field)\n if (raw === null || raw === undefined) return null\n if (desc.mode === 'fixed') {\n const cur = desc.fixedCurrency!\n const value = toScaledIntFromAny(raw, desc.scaleFor(cur))\n return value === null ? null : { currency: cur, value }\n }\n // multi mode: stored as { amount, currency }\n if (typeof raw !== 'object') return null\n const o = raw as { amount?: unknown; currency?: unknown }\n if (typeof o.currency !== 'string') return null\n const scale = desc.allows(o.currency) ? desc.scaleFor(o.currency) : 0\n const value = toScaledIntFromAny(o.amount, scale)\n return value === null ? null : { currency: o.currency, value }\n}\n\n/** Resolve the scale to use for a target currency (may be outside the allow-list). */\nfunction targetScaleFor(desc: MoneyDescriptor, currency: string): number {\n if (desc.allows(currency)) return desc.scaleFor(currency)\n const s = scaleForCurrency(currency)\n if (s === null) {\n throw new Error(`money: cannot determine scale for conversion target \"${currency}\"`)\n }\n return s\n}\n\n/** Parse a rate (number | string) into a scaled BigInt + its scale. */\nfunction parseRate(rate: number | string): { int: bigint; scale: number } {\n const s = String(rate).trim()\n const neg = s.startsWith('-')\n const body = neg ? s.slice(1) : s\n const dot = body.indexOf('.')\n const intPart = dot === -1 ? body : body.slice(0, dot)\n const fracPart = dot === -1 ? '' : body.slice(dot + 1)\n const int = BigInt((intPart === '' ? '0' : intPart) + fracPart)\n return { int: neg ? -int : int, scale: fracPart.length }\n}\n\n/** BigInt division of `n / d` with half-even (banker's) rounding. */\nfunction divRoundHalfEven(n: bigint, d: bigint): bigint {\n const q = n / d\n const r = n % d\n const twiceR = (r < 0n ? -r : r) * 2n\n if (twiceR < d) return q\n if (twiceR > d) return q + (n < 0n ? -1n : 1n)\n return q % 2n === 0n ? q : q + (n < 0n ? -1n : 1n)\n}\n\n/** Convert a scaled integer from `srcScale` to `targetScale` applying `rate`. */\nfunction convertScaled(value: bigint, srcScale: number, rate: number | string, targetScale: number): bigint {\n const { int: rateInt, scale: rateScale } = parseRate(rate)\n const product = value * rateInt\n const curScale = srcScale + rateScale\n if (curScale === targetScale) return product\n if (curScale < targetScale) return product * 10n ** BigInt(targetScale - curScale)\n return divRoundHalfEven(product, 10n ** BigInt(curScale - targetScale))\n}\n\nfunction finalizeSum(\n state: Map<string, bigint>,\n desc: MoneyDescriptor,\n convertTo: string | undefined,\n fx: FxRates | undefined,\n): string | Record<string, string> {\n if (convertTo !== undefined) {\n if (fx === undefined) {\n throw new Error(`money: sum convertTo \"${convertTo}\" requires an fx rate map`)\n }\n const targetScale = targetScaleFor(desc, convertTo)\n let total = 0n\n for (const [cur, v] of state) {\n if (cur === convertTo) {\n total += convertScaled(v, desc.scaleFor(cur), 1, targetScale)\n continue\n }\n const rate = fx[`${cur}->${convertTo}`]\n if (rate === undefined) {\n throw new Error(`money: no fx rate for \"${cur}->${convertTo}\"`)\n }\n total += convertScaled(v, desc.scaleFor(cur), rate, targetScale)\n }\n return formatScaledInt(total, targetScale)\n }\n\n if (desc.mode === 'fixed') {\n const cur = desc.fixedCurrency!\n return formatScaledInt(state.get(cur) ?? 0n, desc.scaleFor(cur))\n }\n\n const out: Record<string, string> = {}\n for (const [cur, v] of state) out[cur] = formatScaledInt(v, desc.scaleFor(cur))\n return out\n}\n\nfunction moneySumReducer(\n field: string,\n desc: MoneyDescriptor,\n convertTo: string | undefined,\n fx: FxRates | undefined,\n): Reducer<unknown, Map<string, bigint>> {\n return {\n op: 'sum',\n field,\n init: () => new Map<string, bigint>(),\n step: (state, record) => {\n const m = readMoney(record, field, desc)\n if (m) state.set(m.currency, (state.get(m.currency) ?? 0n) + m.value)\n return state\n },\n remove: (state, record) => {\n const m = readMoney(record, field, desc)\n if (m) state.set(m.currency, (state.get(m.currency) ?? 0n) - m.value)\n return state\n },\n finalize: (state) => finalizeSum(state, desc, convertTo, fx),\n }\n}\n\nfunction extremum(values: readonly bigint[], op: 'min' | 'max'): bigint {\n let out = values[0]!\n for (let i = 1; i < values.length; i++) {\n const v = values[i]!\n if (op === 'min' ? v < out : v > out) out = v\n }\n return out\n}\n\nfunction moneyMinMaxReducer(\n op: 'min' | 'max',\n field: string,\n desc: MoneyDescriptor,\n): Reducer<unknown, Map<string, bigint[]>> {\n return {\n op,\n field,\n init: () => new Map<string, bigint[]>(),\n step: (state, record) => {\n const m = readMoney(record, field, desc)\n if (m) {\n const arr = state.get(m.currency)\n if (arr) arr.push(m.value)\n else state.set(m.currency, [m.value])\n }\n return state\n },\n remove: (state, record) => {\n const m = readMoney(record, field, desc)\n if (m) {\n const arr = state.get(m.currency)\n if (arr) {\n const idx = arr.indexOf(m.value)\n if (idx >= 0) arr.splice(idx, 1)\n }\n }\n return state\n },\n finalize: (state) => {\n if (desc.mode === 'fixed') {\n const cur = desc.fixedCurrency!\n const arr = state.get(cur)\n if (!arr || arr.length === 0) return null\n return formatScaledInt(extremum(arr, op), desc.scaleFor(cur))\n }\n const out: Record<string, string> = {}\n for (const [cur, arr] of state) {\n if (arr.length > 0) out[cur] = formatScaledInt(extremum(arr, op), desc.scaleFor(cur))\n }\n return out\n },\n }\n}\n\n\n/**\n * Parse a probability into an EXACT rational from its decimal spelling.\n *\n * `0.9` becomes `9/10`, not the binary float nearest `0.9`. This is what keeps\n * a money percentile exact: the interpolation weight multiplies a scaled\n * integer, so a float weight would reintroduce the very rounding the BigInt\n * path exists to avoid.\n */\nfunction parseProbability(p: number): { num: bigint; den: bigint } {\n const { int, scale } = parseRate(p)\n return { num: int, den: 10n ** BigInt(scale) }\n}\n\n/**\n * `percentile_cont` over sorted scaled integers, in BigInt throughout.\n *\n * `x = p·(n−1)`; when `x` falls between two ranks the answer is\n * `a + (b−a)·frac`, and the division by the fraction's denominator rounds\n * HALF-EVEN — the same {@link divRoundHalfEven} the rest of the money module\n * uses for conversion. An even-sized median is exactly this case with\n * `frac = 1/2`.\n */\nfunction quantileScaled(sorted: readonly bigint[], p: number): bigint {\n const n = sorted.length\n if (n === 1) return sorted[0]!\n const { num, den } = parseProbability(p)\n const xNum = num * BigInt(n - 1)\n const lo = xNum / den\n const rem = xNum - lo * den\n const i = Number(lo)\n if (rem === 0n) return sorted[i]!\n const a = sorted[i]!\n const b = sorted[i + 1]!\n return a + divRoundHalfEven((b - a) * rem, den)\n}\n\n/**\n * Exact money `median` / `percentile` (#1353). Mirrors\n * {@link moneyMinMaxReducer}: per-currency multisets of scaled integers, so a\n * multi-currency field yields a per-currency map and currencies are never\n * mixed. `remove()` is supported, so these participate in incremental live\n * maintenance like every other money reducer.\n */\nfunction moneyQuantileReducer(\n op: 'median' | 'percentile',\n field: string,\n desc: MoneyDescriptor,\n p: number,\n): Reducer<unknown, Map<string, bigint[]>> {\n const quantile = (arr: readonly bigint[]): bigint => {\n const sorted = [...arr].sort((x, y) => (x < y ? -1 : x > y ? 1 : 0))\n return quantileScaled(sorted, p)\n }\n return {\n op,\n field,\n p,\n init: () => new Map<string, bigint[]>(),\n step: (state, record) => {\n const m = readMoney(record, field, desc)\n if (m) {\n const arr = state.get(m.currency)\n if (arr) arr.push(m.value)\n else state.set(m.currency, [m.value])\n }\n return state\n },\n remove: (state, record) => {\n const m = readMoney(record, field, desc)\n if (m) {\n const arr = state.get(m.currency)\n if (arr) {\n const idx = arr.indexOf(m.value)\n if (idx >= 0) arr.splice(idx, 1)\n }\n }\n return state\n },\n finalize: (state) => {\n if (desc.mode === 'fixed') {\n const cur = desc.fixedCurrency!\n const arr = state.get(cur)\n if (!arr || arr.length === 0) return null\n return formatScaledInt(quantile(arr), desc.scaleFor(cur))\n }\n const out: Record<string, string> = {}\n for (const [cur, arr] of state) {\n if (arr.length > 0) out[cur] = formatScaledInt(quantile(arr), desc.scaleFor(cur))\n }\n return out\n },\n }\n}\n\n/**\n * Why `variance` / `stddev` / `mode` / an approximate `percentile` refuse over\n * a money field rather than falling through to the generic reducer.\n *\n * The generic reducers read the field with `readNumber`, which coerces the\n * stored scaled-integer STRING to `0` — so the fall-through answer is not\n * \"slightly off\", it is a confidently reported zero. Refusing is the same\n * choice `avg` already made.\n *\n * `variance` / `stddev` are unimplementable exactly (a square root is not a\n * decimal), and `mode` is exactly computable but not implemented — the message\n * says which, because \"unsupported\" and \"not built yet\" call for different\n * consumer reactions.\n */\nconst MONEY_REFUSALS: Record<string, string> = {\n avg: 'avg() is not supported on money field \"%s\" in v1 — use sum() and count() and divide at the boundary.',\n variance:\n 'variance() is not supported on money field \"%s\" — a variance of currency is not a currency amount, and the exact BigInt path cannot express it. Read the scaled integers out and compute at the boundary.',\n stddev:\n 'stddev() is not supported on money field \"%s\" — a square root is not a decimal, so there is no exact answer to return. Read the scaled integers out and compute at the boundary.',\n mode: 'mode() is not implemented for money field \"%s\" (#1353) — it is exactly computable, but the generic reducer would read the stored scaled integer as 0, so it refuses rather than answer wrongly.',\n}\n\n/**\n * Rewrite any `sum` / `min` / `max` reducer over a declared money field\n * into its exact BigInt money-aware equivalent. Other reducers (and\n * reducers over non-money fields) pass through unchanged. Returns a new\n * spec; the input is not mutated.\n */\nexport function wrapMoneyReducers(\n spec: ReduceSpec,\n moneyFields: Record<string, MoneyDescriptor>,\n): ReduceSpec {\n let changed = false\n const out: Record<string, Reducer<unknown, unknown>> = {}\n for (const [key, reducer] of Object.entries(spec)) {\n const field = reducer.field\n const desc = field ? moneyFields[field] : undefined\n const refusal = desc && reducer.op ? MONEY_REFUSALS[reducer.op] : undefined\n if (refusal !== undefined) {\n throw new MoneyUnsupportedError(field!, refusal.replace('%s', field!))\n }\n if (desc && reducer.op === 'percentile' && reducer.approx === true) {\n throw new MoneyUnsupportedError(\n field!,\n `percentile({ approx: true }) is not supported on money field \"${field}\" — a t-digest summarises values as floating-point centroids. Drop \\`approx\\` for the exact BigInt path (O(n) memory per group).`,\n )\n }\n if (desc && (reducer.op === 'median' || reducer.op === 'percentile')) {\n changed = true\n out[key] = moneyQuantileReducer(\n reducer.op,\n field!,\n desc,\n reducer.op === 'median' ? 0.5 : (reducer.p ?? 0.5),\n ) as Reducer<unknown, unknown>\n continue\n }\n if (desc && (reducer.op === 'sum' || reducer.op === 'min' || reducer.op === 'max')) {\n changed = true\n out[key] =\n reducer.op === 'sum'\n ? moneySumReducer(field!, desc, reducer.convertTo, reducer.fx as FxRates | undefined)\n : (moneyMinMaxReducer(reducer.op, field!, desc) as Reducer<unknown, unknown>)\n } else {\n out[key] = reducer\n }\n }\n return changed ? out : spec\n}\n","/**\n * The money `NoydbVia` — wires the money engine (normalize/paths/where/\n * money-reducer) into the kernel's generic Via port. `money()`\n * (descriptor.ts) calls {@link linkMoneyVia} at declaration time — the\n * same #553 static-link pattern the retired `linkMoneyEngine()` /\n * `kernel/money-runtime.ts` seam used, now the only one (Task 6 cut the\n * query DSL over to this binding and deleted the legacy seam).\n */\nimport type { NoydbVia, ViaReadCtx } from '../../kernel/via/index.js'\nimport { installViaBinder } from '../../kernel/via/index.js'\nimport type { MoneyDescriptor } from './descriptor.js'\nimport { quantizeMoneyFields, decodeMoneyFields, canonicalizeStoredMoney, canonicalizeIncomingMoney, moneyScaledValue, canonicalizeMoneyIndexKey, presentVirtualMoneyFields } from './normalize.js'\nimport { validateMoneyFieldPaths } from './paths.js'\nimport { moneyFieldClause, evaluateMoneyClause, moneyIndexProbe, type MoneyWhereOperand } from './where.js'\nimport { wrapMoneyReducers } from './money-reducer.js'\nimport type { Operator } from '../../kernel/query/predicate.js'\nimport type { ReduceSpec } from '../../with-lookup/reduce/reduction.js'\n\n/** #669 — the money binder's config bag. `virtualMoneyFields` is the money∩virtual-mode-\n * computed field-name intersection (`kernel/collection-config.ts#resolveVirtualMoneyFields`);\n * absent/empty means no field on this collection composes money with a virtual computed\n * field on itself — the pre-#669 behavior (no `presentLate`, ordinary `present()` for\n * every declared money field). */\ninterface MoneyBindingConfig {\n readonly moneyFields: Record<string, MoneyDescriptor>\n readonly virtualMoneyFields?: ReadonlySet<string>\n}\n\nexport function moneyVia(moneyFields: Record<string, MoneyDescriptor>, virtualMoneyFields?: ReadonlySet<string>): NoydbVia {\n validateMoneyFieldPaths(moneyFields) // declaration-time (replaces sites 1 & 2)\n const hasVirtualMoney = virtualMoneyFields !== undefined && virtualMoneyFields.size > 0\n // #669 — a field that is BOTH money AND virtual-mode computed has no value yet when\n // money's ORDINARY present() runs (money is first in `_presentOrder`, computed second —\n // the #665 invariant); decodeMoneyFields already no-ops on an absent value, but the skip\n // is made explicit here so the intent reads at the call site: dressing this field happens\n // in `presentLate` below, once computed's present() has actually produced a value.\n const ordinaryPresentFields = hasVirtualMoney\n ? Object.fromEntries(Object.entries(moneyFields).filter(([f]) => !virtualMoneyFields.has(f)))\n : moneyFields\n return {\n brand: 'money',\n presentIsSync: true, // #1416 — decodeMoneyFields / presentVirtualMoneyFields are plain functions\n posture: { encryptedAtRest: 'envelope', queryable: 'ordered', exportable: true, forgettable: true },\n covers: (field) => field in moneyFields,\n coveredFields: Object.keys(moneyFields), // #1447\n ingest: (r) => canonicalizeIncomingMoney(r, moneyFields) as Record<string, unknown>,\n canonicalizeStored: (r) => canonicalizeStoredMoney(r, moneyFields) as Record<string, unknown>,\n encodeWrite: (r) => quantizeMoneyFields(r, moneyFields),\n present: (r, ctx) => decodeMoneyFields(r, ordinaryPresentFields, typeof ctx.locale === 'string' ? ctx.locale : undefined),\n ...(hasVirtualMoney\n ? {\n presentLate: (r: Record<string, unknown>, ctx: ViaReadCtx) =>\n presentVirtualMoneyFields(r, moneyFields, virtualMoneyFields, typeof ctx.locale === 'string' ? ctx.locale : undefined),\n }\n : {}),\n buildClause: (field, op, value) => {\n const desc = moneyFields[field]\n if (!desc) return undefined\n return moneyFieldClause(field, op as Operator, value, desc) // the MoneyWhereOperand payload\n },\n evaluateClause: (actual, op, payload) => evaluateMoneyClause(actual, op as Operator, payload as MoneyWhereOperand),\n indexProbe: (op, payload) => moneyIndexProbe(op as Operator, payload as MoneyWhereOperand),\n canonicalizeIndexKey: (field, rawValue) => canonicalizeMoneyIndexKey(field, rawValue, moneyFields),\n decodeResults: (r) => decodeMoneyFields(r as Record<string, unknown>, moneyFields, 'raw'),\n compareForOrder: (field, a, b) => {\n const desc = moneyFields[field]\n if (!desc) return undefined\n const av = moneyScaledValue(a, desc); const bv = moneyScaledValue(b, desc)\n if (av === null) return bv === null ? 0 : 1\n if (bv === null) return -1\n return av < bv ? -1 : av > bv ? 1 : 0\n },\n wrapReducers: (spec) => wrapMoneyReducers(spec as ReduceSpec, moneyFields),\n }\n}\n\nexport function linkMoneyVia(): void {\n installViaBinder('money', (cfg) => {\n const c = cfg as MoneyBindingConfig\n return moneyVia(c.moneyFields, c.virtualMoneyFields)\n })\n}\n","/**\n * The `money()` field descriptor — a branded schema-layer descriptor, a\n * sibling of `i18nText()` / `dictKey()`. It owns currency, scale, and\n * rounding policy for a field; the pure arithmetic lives in\n * {@link ./fixed-point} and default scale resolution in\n * {@link ./iso4217}.\n *\n * Two modes:\n * - **fixed** `money({ currency: 'EUR' })` — one currency for the\n * field; the value stores a bare scaled-integer string.\n * - **multi** `money({ currencies: 'any' | [...] })` — currency travels\n * per record; the value stores `{ amount, currency }`.\n *\n * `currency` and `currencies` are mutually exclusive.\n */\n\nimport type { RoundingMode } from './fixed-point.js'\nimport { scaleForCurrency } from './iso4217.js'\nimport { NoydbError } from '../../kernel/errors.js'\nimport { linkMoneyVia } from './binding.js'\n\nexport interface MoneyOptionsFixed {\n currency: string\n /** Override the ISO-4217 default scale (required for unlisted codes). */\n scale?: number\n rounding?: RoundingMode\n}\n\nexport interface MoneyOptionsMulti {\n currencies: 'any' | readonly string[]\n /** Per-currency scale overrides (required for unlisted codes). */\n scaleOverrides?: Record<string, number>\n rounding?: RoundingMode\n}\n\nexport type MoneyOptions = MoneyOptionsFixed | MoneyOptionsMulti\n\nexport interface MoneyDescriptor {\n readonly _noydbMoney: true\n /** Via port brand marker — lets a `MoneyDescriptor` satisfy the kernel's opaque `ViaDescriptor`. */\n readonly _viaBrand: 'money'\n readonly mode: 'fixed' | 'multi'\n readonly options: MoneyOptions\n readonly rounding: RoundingMode | undefined\n /** The currency for fixed mode; `undefined` in multi mode. */\n readonly fixedCurrency: string | undefined\n /** Resolve the scale for a currency, throwing if not allowed / unknown. */\n scaleFor(currency: string): number\n /** Whether this descriptor permits the given currency. */\n allows(currency: string): boolean\n /**\n * The single currency this descriptor implies, if any — fixed mode, or\n * multi mode with exactly one allow-listed currency. Lets a multi field\n * accept a bare amount unambiguously. `undefined` otherwise.\n */\n soleCurrency(): string | undefined\n}\n\n/** Raised when a written value carries more precision than `scale` allows. */\nexport class MoneyPrecisionError extends NoydbError {\n constructor(\n public readonly field: string,\n public readonly value: unknown,\n public readonly scale: number,\n ) {\n super(\n 'MONEY_PRECISION',\n `money: value ${JSON.stringify(value)} for field \"${field}\" exceeds scale ${scale} ` +\n `and no rounding mode is configured`,\n )\n this.name = 'MoneyPrecisionError'\n }\n}\n\n/** Raised when a currency is disallowed or has no resolvable scale. */\nexport class MoneyCurrencyError extends NoydbError {\n constructor(\n public readonly currency: string,\n public readonly reason: 'not-allowed' | 'unknown-scale',\n public readonly field?: string,\n ) {\n super(\n 'MONEY_CURRENCY',\n reason === 'not-allowed'\n ? `money: currency \"${currency}\" is not allowed${field ? ` for field \"${field}\"` : ''}`\n : `money: no scale known for currency \"${currency}\"${field ? ` (field \"${field}\")` : ''} — ` +\n `pass an explicit scale / scaleOverrides`,\n )\n this.name = 'MoneyCurrencyError'\n }\n}\n\n/** Raised when an aggregate operation is not supported on a money field. */\nexport class MoneyUnsupportedError extends NoydbError {\n constructor(\n public readonly field: string,\n message?: string,\n ) {\n super(\n 'MONEY_UNSUPPORTED',\n message ??\n `money: operation is not supported on field \"${field}\" — use sum() and count() and divide at the boundary`,\n )\n this.name = 'MoneyUnsupportedError'\n }\n}\n\nfunction isMultiOptions(o: MoneyOptions): o is MoneyOptionsMulti {\n return 'currencies' in o\n}\n\n/** Create a {@link MoneyDescriptor}. */\nexport function money(options: MoneyOptions): MoneyDescriptor {\n // The declaration is the Via binding's opt-in unit (#553): constructing\n // a descriptor statically links normalize/paths/where/money-reducer into\n // the kernel's Via port, so every later kernel consultation (including\n // the SYNC query DSL) finds the binding already installed.\n linkMoneyVia()\n const hasFixed = 'currency' in options\n const hasMulti = 'currencies' in options\n if (hasFixed && hasMulti) {\n throw new TypeError('money: `currency` and `currencies` are mutually exclusive')\n }\n if (!hasFixed && !hasMulti) {\n throw new TypeError('money: one of `currency` or `currencies` is required')\n }\n\n const rounding = options.rounding\n\n if (isMultiOptions(options)) {\n const overrides = options.scaleOverrides ?? {}\n const allowList = options.currencies\n const allows = (c: string): boolean =>\n allowList === 'any' ? true : allowList.includes(c)\n const scaleFor = (c: string): number => {\n if (!allows(c)) throw new MoneyCurrencyError(c, 'not-allowed')\n const s = overrides[c] ?? scaleForCurrency(c)\n if (s === null || s === undefined) throw new MoneyCurrencyError(c, 'unknown-scale')\n return s\n }\n // Eagerly validate the allow-list resolves (catch typos at construction).\n if (allowList !== 'any') for (const c of allowList) scaleFor(c)\n const soleCurrency = (): string | undefined =>\n allowList !== 'any' && allowList.length === 1 ? allowList[0] : undefined\n return {\n _noydbMoney: true,\n _viaBrand: 'money',\n mode: 'multi',\n options,\n rounding,\n fixedCurrency: undefined,\n scaleFor,\n allows,\n soleCurrency,\n }\n }\n\n // fixed\n const currency = options.currency\n const resolvedScale = options.scale ?? scaleForCurrency(currency)\n if (resolvedScale === null || resolvedScale === undefined) {\n throw new MoneyCurrencyError(currency, 'unknown-scale')\n }\n return {\n _noydbMoney: true,\n _viaBrand: 'money',\n mode: 'fixed',\n options,\n rounding,\n fixedCurrency: currency,\n scaleFor(c: string): number {\n if (c !== currency) throw new MoneyCurrencyError(c, 'not-allowed')\n return resolvedScale\n },\n allows: (c: string): boolean => c === currency,\n soleCurrency: (): string | undefined => currency,\n }\n}\n\n/** Runtime predicate for detecting a {@link MoneyDescriptor}. */\nexport function isMoneyDescriptor(x: unknown): x is MoneyDescriptor {\n return (\n typeof x === 'object' &&\n x !== null &&\n (x as { _noydbMoney?: unknown })._noydbMoney === true\n )\n}\n","/**\n * Exact decimal arithmetic for post-aggregate row math (#1007).\n *\n * Money leaves a reducer as a `MoneyString` — a decimal string, exact by\n * construction. Doing `Number(a) - Number(b)` on two of those re-introduces\n * binary floating point at the one step the money type exists to protect:\n * `10.05 - 0.10` becomes `9.950000000000001`, which `quantizeMoneyFields`\n * then correctly REFUSES rather than silently storing drift.\n *\n * So `derive` is handed these instead. Everything runs in scaled BigInt at the\n * widest scale of its inputs and formats back to a decimal string, which means\n * no operation here can introduce a representation error. Deliberately just\n * the additive set — `add` / `sub` / `neg` / `min` / `max` / `cmp`. Anything\n * needing multiplication or division needs a rounding policy, and a rounding\n * policy is a decision the caller must make explicitly, not one this module\n * should guess.\n *\n * @module\n */\n\nimport { ValidationError } from '../../kernel/errors.js'\n\n/** A value these helpers accept: a decimal string, a number, or a bigint of whole units. */\nexport type ExactOperand = string | number | bigint\n\n/** Scaled representation: `value` is the integer numerator, `scale` the number of decimal places. */\ninterface Scaled {\n readonly value: bigint\n readonly scale: number\n}\n\nconst DECIMAL = /^[+-]?\\d+(\\.\\d+)?$/\n\nfunction parse(operand: ExactOperand, op: string): Scaled {\n if (typeof operand === 'bigint') return { value: operand, scale: 0 }\n const text = typeof operand === 'number'\n // A non-integer JS number has already lost exactness before it reached us;\n // `toString()` gives the shortest round-trip form, which is the closest\n // honest reading of what the caller actually holds.\n ? String(operand)\n : operand.trim()\n if (!DECIMAL.test(text)) {\n throw new ValidationError(\n `exact.${op}: \"${text}\" is not a decimal value. Pass a decimal string (the shape money fields ` +\n 'carry), a number, or a bigint.',\n )\n }\n const [whole, fraction = ''] = text.split('.')\n const digits = `${whole}${fraction}`\n return { value: BigInt(digits), scale: fraction.length }\n}\n\n/** Bring two scaled values onto a common scale without losing a digit. */\nfunction align(a: Scaled, b: Scaled): { a: bigint; b: bigint; scale: number } {\n const scale = Math.max(a.scale, b.scale)\n const lift = (s: Scaled) => s.value * 10n ** BigInt(scale - s.scale)\n return { a: lift(a), b: lift(b), scale }\n}\n\nfunction format({ value, scale }: Scaled): string {\n if (scale === 0) return value.toString()\n const negative = value < 0n\n const digits = (negative ? -value : value).toString().padStart(scale + 1, '0')\n const whole = digits.slice(0, digits.length - scale)\n const fraction = digits.slice(digits.length - scale)\n return `${negative ? '-' : ''}${whole}.${fraction}`\n}\n\nfunction binary(op: string, a: ExactOperand, b: ExactOperand, f: (x: bigint, y: bigint) => bigint): string {\n const aligned = align(parse(a, op), parse(b, op))\n return format({ value: f(aligned.a, aligned.b), scale: aligned.scale })\n}\n\n/**\n * Exact decimal helpers handed to an MV `derive` as its second argument.\n *\n * Every result is a decimal string, so results compose without ever passing\n * through a float. Declare the derived field in the MV's `moneyFields` and the\n * final value is quantised to that descriptor's scale on the way to storage.\n */\nexport interface ExactMath {\n /** `a + b`, exact. */\n add(a: ExactOperand, b: ExactOperand): string\n /** `a - b`, exact. */\n sub(a: ExactOperand, b: ExactOperand): string\n /** `-a`, exact. */\n neg(a: ExactOperand): string\n /** The larger of `a` and `b`. */\n max(a: ExactOperand, b: ExactOperand): string\n /** The smaller of `a` and `b`. */\n min(a: ExactOperand, b: ExactOperand): string\n /** `-1` when `a < b`, `0` when equal, `1` when `a > b`. */\n cmp(a: ExactOperand, b: ExactOperand): -1 | 0 | 1\n}\n\n/** The singleton passed to `derive` — stateless, so there is nothing to construct per row. */\nexport const exactMath: ExactMath = {\n add: (a, b) => binary('add', a, b, (x, y) => x + y),\n sub: (a, b) => binary('sub', a, b, (x, y) => x - y),\n neg: (a) => binary('neg', 0, a, (x, y) => x - y),\n max: (a, b) => binary('max', a, b, (x, y) => (x > y ? x : y)),\n min: (a, b) => binary('min', a, b, (x, y) => (x < y ? x : y)),\n cmp: (a, b) => {\n const { a: x, b: y } = align(parse(a, 'cmp'), parse(b, 'cmp'))\n return x < y ? -1 : x > y ? 1 : 0\n },\n}\n"],"mappings":"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","names":["keep","magnitude","obj","clone","currency","format","isMoneyValueObject","e","value"]}
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  dekKey
3
- } from "./chunk-LJ744WXU.js";
3
+ } from "./chunk-F2FD4LSB.js";
4
4
  import {
5
5
  TierNotGrantedError
6
- } from "./chunk-2RH5SEY7.js";
6
+ } from "./chunk-ISIXU45J.js";
7
7
 
8
8
  // src/with-party/team/tiers.ts
9
9
  function effectiveClearance(dekSlots, collection) {
@@ -37,4 +37,4 @@ export {
37
37
  keyringClearance,
38
38
  assertTierAccess
39
39
  };
40
- //# sourceMappingURL=chunk-XQGKS4OW.js.map
40
+ //# sourceMappingURL=chunk-VKZ3TDET.js.map
@@ -4,17 +4,17 @@ import {
4
4
  revoke,
5
5
  rotateKeys,
6
6
  verifyRoster
7
- } from "./chunk-QVUMKG3Z.js";
7
+ } from "./chunk-UXH4AKH3.js";
8
8
  import {
9
9
  base64ToBuffer,
10
10
  bufferToBase64,
11
11
  decryptBytes,
12
12
  encryptBytes,
13
13
  generateEphemeralKey
14
- } from "./chunk-WRLWEYHY.js";
14
+ } from "./chunk-EFINFZIF.js";
15
15
  import {
16
16
  NoydbError
17
- } from "./chunk-2RH5SEY7.js";
17
+ } from "./chunk-ISIXU45J.js";
18
18
 
19
19
  // src/with-party/team/device-seal.ts
20
20
  var MemoryDeviceSeal = class {
@@ -71,4 +71,4 @@ export {
71
71
  MemoryDeviceSeal,
72
72
  withTeam
73
73
  };
74
- //# sourceMappingURL=chunk-ZOFNZLAA.js.map
74
+ //# sourceMappingURL=chunk-VLZPUG5A.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NoydbError
3
- } from "./chunk-2RH5SEY7.js";
3
+ } from "./chunk-ISIXU45J.js";
4
4
 
5
5
  // src/with-formula/computed/index.ts
6
6
  var ComputedFieldError = class extends NoydbError {
@@ -35,4 +35,4 @@ export {
35
35
  ComputedFieldError,
36
36
  evalComputedFields
37
37
  };
38
- //# sourceMappingURL=chunk-OR3OHKU6.js.map
38
+ //# sourceMappingURL=chunk-VSN5FLMI.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  openInboxKeyPair,
3
3
  readKeyringFile
4
- } from "./chunk-QVUMKG3Z.js";
4
+ } from "./chunk-UXH4AKH3.js";
5
5
  import {
6
6
  generateULID
7
7
  } from "./chunk-4AOERLTV.js";
8
8
  import {
9
9
  dekKey
10
- } from "./chunk-LJ744WXU.js";
10
+ } from "./chunk-F2FD4LSB.js";
11
11
  import {
12
12
  base64ToBuffer,
13
13
  bufferToBase64,
@@ -21,12 +21,12 @@ import {
21
21
  recipientWrap,
22
22
  unwrapKey,
23
23
  wrapKey
24
- } from "./chunk-WRLWEYHY.js";
24
+ } from "./chunk-EFINFZIF.js";
25
25
  import {
26
26
  DelegationTargetMissingError,
27
27
  INBOX_KEY_ID,
28
28
  MemberInboxMissingError
29
- } from "./chunk-2RH5SEY7.js";
29
+ } from "./chunk-ISIXU45J.js";
30
30
 
31
31
  // src/with-party/team/delegation.ts
32
32
  var DELEGATIONS_COLLECTION = "_delegations";
@@ -43,7 +43,7 @@ async function issueDelegation(store, vault, grantor, delegationsDek, opts) {
43
43
  );
44
44
  }
45
45
  const cekBytes = globalThis.crypto.getRandomValues(new Uint8Array(32));
46
- const targetKek = await importWrappingKey(cekBytes);
46
+ const cek = await importWrappingKey(cekBytes);
47
47
  const sealedCek = bufferToBase64(await recipientWrap(await importRecipientPublicKeySpki(base64ToBuffer(targetInbox.pub)), cekBytes));
48
48
  cekBytes.fill(0);
49
49
  const tier = opts.tier;
@@ -54,7 +54,7 @@ async function issueDelegation(store, vault, grantor, delegationsDek, opts) {
54
54
  const suffix = `#${tier}`;
55
55
  const entries = {};
56
56
  for (const [slot, dek] of grantor.deks) {
57
- if (slot.endsWith(suffix)) entries[slot] = await wrapKey(dek, targetKek);
57
+ if (slot.endsWith(suffix)) entries[slot] = await wrapKey(dek, cek);
58
58
  }
59
59
  if (Object.keys(entries).length === 0) {
60
60
  throw new DelegationTargetMissingError(
@@ -71,7 +71,7 @@ async function issueDelegation(store, vault, grantor, delegationsDek, opts) {
71
71
  `grantor holds no tier-${tier} DEK for collection "${collectionName}", so there is nothing to delegate. Obtain the tier grant first.`
72
72
  );
73
73
  }
74
- wrappedDek = await wrapKey(sourceDek, targetKek);
74
+ wrappedDek = await wrapKey(sourceDek, cek);
75
75
  }
76
76
  const until = typeof opts.until === "string" ? opts.until : opts.until.toISOString();
77
77
  const token = {
@@ -166,4 +166,4 @@ export {
166
166
  loadActiveDelegations,
167
167
  revokeDelegation
168
168
  };
169
- //# sourceMappingURL=chunk-JQMEXCUZ.js.map
169
+ //# sourceMappingURL=chunk-VYBBE7RN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-party/team/delegation.ts"],"sourcesContent":["/**\n * Time-boxed cross-tier delegation tokens.\n *\n * A higher-tier user can issue a delegation that grants another user\n * temporary access to records at a specified tier. The delegation is\n * persisted as an encrypted envelope in the reserved `_delegations`\n * collection. While `until` is still in the future, the target merges the\n * unwrapped tier DEKs into their in-memory DEK map by calling\n * `Vault.refreshDelegations()` — EXPLICIT, never automatic; the core#56\n * section below says why a read path must not scan on open.\n *\n * ## Token shape\n *\n * ```\n * {\n * id, // ULID, also the _delegations record id\n * toUser, // grantee user id\n * fromUser, // grantor user id (owner/admin/higher-tier principal)\n * tier, // tier being delegated\n * collection, // collection name OR null for \"every collection\"\n * record, // optional specific record id\n * until, // ISO timestamp — token expires at this instant\n * wrappedDek, // base64 AES-KW-wrapped tier DEK, under the token's content key\n * sealedCek, // that content key, RSA-OAEP-sealed to the target's inbox public half\n * createdAt, // ISO timestamp\n * }\n * ```\n *\n * ## Cross-user (core#65)\n *\n * The wrap key is a per-token CONTENT KEY, not anybody's KEK: the tier DEKs are\n * AES-KW-wrapped under it exactly as they used to be under a KEK, and the key\n * itself is RSA-OAEP-sealed to the target's INBOX PUBLIC HALF (core#96 mints\n * that pair for every grantee, private half sealed under a DEK only that\n * member's own KEK unwraps). So a grantor delegates to somebody whose secret it\n * does not know — the thing this module could not do — while the slot NAMES\n * stay readable to any member holding the `_delegations` DEK, which is what\n * makes an audit enumeration possible without making the keys usable.\n *\n * The ciphertext is stored as a normal noy-db envelope — the\n * `_delegations` collection has its own DEK shared across all vault\n * users, so an operator can enumerate active delegations for audit\n * without being able to *use* them (the `wrappedDek` inside is keyed to\n * the token's own content key — see the core#65 section above).\n *\n * ## Revocation\n *\n * Delete the `_delegations/<id>` envelope. The target picks the change up\n * at its next `Vault.refreshDelegations()` call — this module is pure\n * logic and schedules nothing.\n *\n * @module\n */\n\nimport type { NoydbStore, KeyringFile } from '../../kernel/types.js'\nimport type { UnlockedKeyring } from './keyring.js'\nimport {\n buildRecordAad, buildRecordEnvelope, encrypt, openEnvelopeJson, wrapKey, unwrapKey,\n importWrappingKey, importRecipientPublicKeySpki, recipientWrap, recipientUnwrap,\n bufferToBase64, base64ToBuffer, type EnclaveKey,\n} from '../../capsule/index.js'\nimport { dekKey } from './tiers.js'\nimport { readKeyringFile, openInboxKeyPair } from './keyring.js'\nimport { INBOX_KEY_ID } from '../../kernel/constants.js'\nimport { DelegationTargetMissingError, MemberInboxMissingError } from '../../kernel/errors.js'\nimport { generateULID } from '../../with-pod/ulid.js'\n\nexport const DELEGATIONS_COLLECTION = '_delegations'\n\n/**\n * Durable payload of a delegation token. Encrypted under the vault's\n * `_delegations` DEK; the `wrappedDek` inside is additionally wrapped under\n * the token's per-token CONTENT KEY — see {@link DelegationToken.sealedCek},\n * which carries the pre-core#65 exception.\n */\nexport interface DelegationToken {\n readonly id: string\n readonly toUser: string\n readonly fromUser: string\n readonly tier: number\n /**\n * Collection name, or `null` for a COLLECTION-WIDE token — see\n * {@link DelegationToken.wrappedDeks} for what that means and what it cannot\n * mean.\n */\n readonly collection: string | null\n /** Optional specific record id scope. */\n readonly record?: string\n readonly until: string\n /**\n * The delegated tier DEK for {@link DelegationToken.collection}, wrapped\n * under the token's content key — see {@link DelegationToken.sealedCek},\n * which carries the pre-core#65 exception. Present on a per-collection\n * token; absent on a collection-wide one, which carries\n * {@link DelegationToken.wrappedDeks}.\n */\n readonly wrappedDek?: string\n /**\n * A collection-wide token's payload: `<collection>#<tier>` → wrapped DEK, one\n * entry per collection the grantor held at that tier (core#56).\n *\n * ## ⛔ Why a MAP and not one key\n *\n * Every collection has its OWN tier DEK — measured, `docs#1` and `ledger#1`\n * are different keys. The original design tried to express \"every collection\"\n * as a single DEK under a wildcard slot `__any#<tier>`, which cannot work: one\n * key decrypts one collection. A wildcard accepted at the access gate would\n * have passed the check and then failed decryption — a gate that says yes\n * followed by a crypto error. `__any#` is gone; every entry here merges under\n * its REAL `<collection>#<tier>` key, so `assertTierAccess` needs no wildcard\n * and gains no new privilege surface.\n *\n * ## ⚠️ \"Every collection\" means \"every collection AS OF ISSUE TIME\"\n *\n * This is a SNAPSHOT. A collection created after the token was issued is not\n * in it and will not be granted by it — the grantor did not hold its DEK to\n * wrap. That is a real limit of the shape, not an oversight, and it is stated\n * here because a caller who reads \"all collections\" will otherwise assume\n * otherwise.\n */\n readonly wrappedDeks?: Readonly<Record<string, string>>\n /**\n * core#65 — the token's CONTENT KEY, RSA-OAEP-sealed to the target's inbox\n * public half. `wrappedDek` / `wrappedDeks` are AES-KW-wrapped under it, so\n * only the target can unwrap them, and only they can: the matching private\n * half is sealed in their keyring under a DEK their own KEK unwraps.\n *\n * Absent on a token written before core#65, whose wraps are under the\n * grantor's own KEK — those still load for a target that shares that KEK\n * (the only case that ever worked) and are skipped for anyone else, exactly\n * as before.\n */\n readonly sealedCek?: string\n readonly createdAt: string\n}\n\nexport interface IssueDelegationOptions {\n readonly toUser: string\n readonly tier: number\n readonly collection?: string\n readonly record?: string\n readonly until: Date | string\n}\n\n/**\n * Build and persist a delegation token. The caller must hold a tier-N DEK; the\n * target must have a keyring in this vault with an inbox key pair (core#96).\n *\n * core#65 — the wraps are keyed to a per-token content key sealed to that\n * pair, so the grantor needs nothing of the target's but their PUBLIC half.\n */\nexport async function issueDelegation(\n store: NoydbStore,\n vault: string,\n grantor: UnlockedKeyring,\n delegationsDek: EnclaveKey,\n opts: IssueDelegationOptions,\n): Promise<DelegationToken> {\n const targetFound = await readKeyringFile(store, vault, opts.toUser)\n if (!targetFound) {\n throw new DelegationTargetMissingError(opts.toUser)\n }\n const targetInbox = targetFound.file.inbox_key\n if (!targetInbox) {\n throw new MemberInboxMissingError(\n opts.toUser,\n `Delegation target \"${opts.toUser}\" has a keyring with no inbox key pair — it predates core#96, ` +\n 'so a delegated key cannot be sealed to them. Re-grant the user once (a fresh temporary secret ' +\n 'they rotate on first open); the new keyring carries the pair.',\n )\n }\n const cekBytes = globalThis.crypto.getRandomValues(new Uint8Array(32))\n const cek = await importWrappingKey(cekBytes)\n const sealedCek = bufferToBase64(await recipientWrap(await importRecipientPublicKeySpki(base64ToBuffer(targetInbox.pub)), cekBytes))\n cekBytes.fill(0)\n const tier = opts.tier\n const collectionName = opts.collection ?? null\n\n // Collection-wide: wrap EVERY tier DEK the grantor holds at this tier, each\n // under its own real slot key. See `wrappedDeks` for why this is a map and\n // for the as-of-issue-time limit it carries.\n let wrappedDek: string | undefined\n let wrappedDeks: Record<string, string> | undefined\n if (collectionName === null) {\n const suffix = `#${tier}`\n const entries: Record<string, string> = {}\n for (const [slot, dek] of grantor.deks) {\n if (slot.endsWith(suffix)) entries[slot] = await wrapKey(dek, cek)\n }\n if (Object.keys(entries).length === 0) {\n throw new DelegationTargetMissingError(\n opts.toUser,\n `grantor holds no tier-${tier} DEK for ANY collection, so a collection-wide ` +\n `delegation would grant nothing. Obtain a tier grant first, or name a ` +\n `\\`collection\\`.`,\n )\n }\n wrappedDeks = entries\n } else {\n const sourceDek = grantor.deks.get(dekKey(collectionName, tier))\n if (!sourceDek) {\n throw new DelegationTargetMissingError(\n opts.toUser,\n `grantor holds no tier-${tier} DEK for collection \"${collectionName}\", so there ` +\n `is nothing to delegate. Obtain the tier grant first.`,\n )\n }\n wrappedDek = await wrapKey(sourceDek, cek)\n }\n\n const until = typeof opts.until === 'string' ? opts.until : opts.until.toISOString()\n const token: DelegationToken = {\n id: generateULID(),\n toUser: opts.toUser,\n fromUser: grantor.userId,\n tier,\n collection: collectionName,\n ...(opts.record && { record: opts.record }),\n until,\n ...(wrappedDek !== undefined && { wrappedDek }),\n ...(wrappedDeks !== undefined && { wrappedDeks }),\n sealedCek,\n createdAt: new Date().toISOString(),\n }\n\n const plaintext = JSON.stringify(token)\n const identity = { collection: DELEGATIONS_COLLECTION, id: token.id, by: grantor.userId, version: 1 }\n const { iv, data } = await encrypt(plaintext, delegationsDek, buildRecordAad(identity))\n const envelope = buildRecordEnvelope(\n identity,\n { ts: token.createdAt, iv, data},\n )\n await store.put(vault, DELEGATIONS_COLLECTION, token.id, envelope)\n return token\n}\n\n/**\n * ## Why the vault calls this EXPLICITLY, and never from `openVault` (core#56)\n *\n * The module header above describes a runtime that scans on every open. Doing\n * that automatically would call `getDEK('_delegations')`, which MINTS a DEK when\n * absent and persists the keyring — so merely opening a vault would write to it.\n * Worse, on a vault whose shared `_delegations` DEK this user does not hold, it\n * would mint a WRONG one and then fail to decrypt every token under it.\n *\n * ⛔ A read path must not have that side effect. `Vault.refreshDelegations()`\n * therefore lists first, returns `[]` when nothing is written, and looks the DEK\n * up WITHOUT minting — which also makes the module header's \"at each open\"\n * cheap to honour, and its \"periodic intervals (tracked by the caller)\" is what\n * an explicit method is.\n *\n * ## Cross-user delegation (core#65) — and the one thing it still needs\n *\n * A token's wraps are keyed to a per-token content key sealed to the target's\n * INBOX PUBLIC HALF, so any member can be a target. Opening one therefore needs\n * that member's inbox PRIVATE half, which is sealed in their keyring file under\n * `deks[INBOX_KEY_ID]` — so this function reads the caller's own keyring file,\n * once, and only when a sealed token is actually addressed to them.\n *\n * ⚠️ A pre-core#65 token (no `sealedCek`) is wrapped under the GRANTOR's KEK and\n * still requires `user.kek`; it is skipped for anyone who does not share it,\n * which is the behaviour those tokens were written under.\n */\n\n/**\n * Enumerate every live (non-expired) delegation addressed to `toUser`\n * and merge the unwrapped tier DEKs into their keyring. Returns the\n * list of merged delegations so the caller can register per-access\n * audit context.\n */\nexport async function loadActiveDelegations(\n store: NoydbStore,\n vault: string,\n user: UnlockedKeyring,\n delegationsDek: EnclaveKey,\n now: Date = new Date(),\n): Promise<DelegationToken[]> {\n const ids = await store.list(vault, DELEGATIONS_COLLECTION)\n const merged: DelegationToken[] = []\n const nowIso = now.toISOString()\n /** This member's own inbox key pair material, read at most once per call. `null` = read, absent. */\n let ownInbox: NonNullable<KeyringFile['inbox_key']> | null | undefined\n for (const id of ids) {\n const env = await store.get(vault, DELEGATIONS_COLLECTION, id)\n if (!env) continue\n let token: DelegationToken\n try {\n const plaintext = await openEnvelopeJson({ collection: DELEGATIONS_COLLECTION, id }, env, delegationsDek)\n token = JSON.parse(plaintext) as DelegationToken\n } catch {\n continue\n }\n if (token.toUser !== user.userId) continue\n if (token.until <= nowIso) continue\n\n // core#65 — the wrap key. A sealed token carries its own content key,\n // opened with this member's inbox pair; a legacy token is under the\n // grantor's KEK and needs `user.kek`, absent on a tier-3 PIN resume, a\n // wrap-DEKs tier-2 unlock or a session restore (reached again at the next\n // tier-1 unlock). A sealed token has no such limit: the pair's private\n // half is sealed under a DEK the rebuilt set already carries.\n let wrapKeyForToken: EnclaveKey\n if (token.sealedCek !== undefined) {\n const inboxKeyAes = user.deks.get(INBOX_KEY_ID)\n if (!inboxKeyAes) continue\n if (ownInbox === undefined) {\n const own = await readKeyringFile(store, vault, user.userId)\n ownInbox = own?.file.inbox_key ?? null\n }\n if (!ownInbox) continue\n try {\n const pair = await openInboxKeyPair(ownInbox, inboxKeyAes)\n const cekBytes = await recipientUnwrap(pair, base64ToBuffer(token.sealedCek))\n try {\n wrapKeyForToken = await importWrappingKey(cekBytes)\n } finally {\n cekBytes.fill(0)\n }\n } catch {\n // Sealed to somebody else's pair, or this member's own pair was\n // replaced (a re-grant mints a fresh one). Not ours to open.\n continue\n }\n } else {\n if (!user.kek) continue\n wrapKeyForToken = user.kek\n }\n\n // ⭐ Every merged key lands under its REAL `<collection>#<tier>` slot, which\n // is exactly what `assertTierAccess` and `getDEK` already look up. There is\n // no wildcard slot and no lookup change anywhere — see `wrappedDeks`.\n const wraps: Record<string, string> = token.collection\n ? (token.wrappedDek ? { [dekKey(token.collection, token.tier)]: token.wrappedDek } : {})\n : { ...(token.wrappedDeks ?? {}) }\n if (Object.keys(wraps).length === 0) continue\n\n let anyMerged = false\n for (const [slot, wrapped] of Object.entries(wraps)) {\n let dek: EnclaveKey\n try {\n dek = await unwrapKey(wrapped, wrapKeyForToken)\n } catch {\n // One unusable entry must not discard the rest of a collection-wide\n // token — a revoked or re-wrapped collection is the expected case.\n continue\n }\n user.deks.set(slot, dek)\n anyMerged = true\n }\n if (!anyMerged) continue\n merged.push(token)\n }\n return merged\n}\n\n/**\n * Revoke a delegation by id — the caller resolves the envelope and\n * issues a `delete`. Provided as a stable helper so the naming is\n * symmetric to `issueDelegation`.\n */\nexport async function revokeDelegation(\n store: NoydbStore,\n vault: string,\n id: string,\n): Promise<void> {\n await store.delete(vault, DELEGATIONS_COLLECTION, id)\n}\n"],"mappings":"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","names":[]}
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  bindDistinctReducers,
3
3
  reducerBuilder
4
- } from "./chunk-4KYKRYRT.js";
4
+ } from "./chunk-TOTCZFRF.js";
5
5
  import {
6
6
  ViaPipeline
7
- } from "./chunk-6WIFF46H.js";
7
+ } from "./chunk-CQLMRCKX.js";
8
8
  import {
9
9
  distinctKeyOf
10
10
  } from "./chunk-SUZKW6UR.js";
11
11
  import {
12
12
  MaintenanceMethods
13
- } from "./chunk-F7X7MPK4.js";
13
+ } from "./chunk-5BGHAVBN.js";
14
14
  import {
15
15
  groupKeyName,
16
16
  isDateTruncKey,
@@ -18,7 +18,7 @@ import {
18
18
  } from "./chunk-XBKH4FOC.js";
19
19
  import {
20
20
  ScanBuilder
21
- } from "./chunk-GZISWBCJ.js";
21
+ } from "./chunk-74W56QPY.js";
22
22
  import {
23
23
  installMethods
24
24
  } from "./chunk-F6NCB7KT.js";
@@ -29,14 +29,14 @@ import {
29
29
  executeClausePipeline,
30
30
  filterRecords,
31
31
  fnViewDecoder
32
- } from "./chunk-7C7OF26T.js";
32
+ } from "./chunk-C2NXAR3D.js";
33
33
  import {
34
34
  readPath
35
- } from "./chunk-SXPLIRQH.js";
35
+ } from "./chunk-NLDBQHDV.js";
36
36
  import {
37
37
  FieldNotQueryableError,
38
38
  GroupCardinalityError
39
- } from "./chunk-2RH5SEY7.js";
39
+ } from "./chunk-ISIXU45J.js";
40
40
 
41
41
  // src/kernel/query/relate/join-reduce.ts
42
42
  function liftToAlias(alias, path, inner) {
@@ -527,4 +527,4 @@ function installReduce() {
527
527
  export {
528
528
  installReduce
529
529
  };
530
- //# sourceMappingURL=chunk-SVXFCCSX.js.map
530
+ //# sourceMappingURL=chunk-WHK4JVKF.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  LookupHandle
3
- } from "./chunk-WVQDY3UM.js";
3
+ } from "./chunk-AHA7UALU.js";
4
4
 
5
5
  // src/via/lookup/active.ts
6
6
  function withLookup() {
@@ -33,4 +33,4 @@ function withLookup() {
33
33
  export {
34
34
  withLookup
35
35
  };
36
- //# sourceMappingURL=chunk-YVA6UPRN.js.map
36
+ //# sourceMappingURL=chunk-X4LDBALX.js.map
@@ -5,13 +5,13 @@ import {
5
5
  resolveEchoReveal,
6
6
  verifyPrompt,
7
7
  verifyTypedEcho
8
- } from "./chunk-QVUMKG3Z.js";
8
+ } from "./chunk-UXH4AKH3.js";
9
9
  import {
10
10
  NoAccessError,
11
11
  ValidationError,
12
12
  WrongEchoError,
13
13
  WrongPromptError
14
- } from "./chunk-2RH5SEY7.js";
14
+ } from "./chunk-ISIXU45J.js";
15
15
 
16
16
  // src/with-party/team/echo-ceremony.ts
17
17
  async function beginEchoUnlock(store, vault, opts) {
@@ -57,4 +57,4 @@ async function beginEchoUnlock(store, vault, opts) {
57
57
  export {
58
58
  beginEchoUnlock
59
59
  };
60
- //# sourceMappingURL=chunk-35CNOVQE.js.map
60
+ //# sourceMappingURL=chunk-X67E7NIJ.js.map
@@ -5,10 +5,10 @@ import {
5
5
  generateSigningKeyPair,
6
6
  openEnvelopeJson,
7
7
  sha256Hex
8
- } from "./chunk-WRLWEYHY.js";
8
+ } from "./chunk-EFINFZIF.js";
9
9
  import {
10
10
  ConflictError
11
- } from "./chunk-2RH5SEY7.js";
11
+ } from "./chunk-ISIXU45J.js";
12
12
 
13
13
  // src/with-audit/attestation/signer.ts
14
14
  var ATTESTATIONS_COLLECTION = "_attestations";
@@ -54,4 +54,4 @@ export {
54
54
  loadSigner,
55
55
  loadOrCreateSigner
56
56
  };
57
- //# sourceMappingURL=chunk-IPF5ORDI.js.map
57
+ //# sourceMappingURL=chunk-XMARKBUC.js.map