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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (470) hide show
  1. package/README.md +2 -2
  2. package/dist/api-5QVQX4HG.js +20 -0
  3. package/dist/attestation/index.js +18 -18
  4. package/dist/{backup-JL2GOTYQ.js → backup-USYSNCYM.js} +11 -11
  5. package/dist/blobs/index.js +15 -12
  6. package/dist/blobs/index.js.map +1 -1
  7. package/dist/broker/index.js +12 -12
  8. package/dist/cargo/index.js +34 -36
  9. package/dist/{chunk-JLHKBAFY.js → chunk-2BVW754E.js} +3 -3
  10. package/dist/{chunk-T7S4V52L.js → chunk-2PDBYF2O.js} +4 -4
  11. package/dist/{chunk-YGBIBOCR.js → chunk-2ZSC454H.js} +7 -7
  12. package/dist/{chunk-IGAIOGCN.js → chunk-32467U5J.js} +4 -4
  13. package/dist/{chunk-JA5O7UEZ.js → chunk-3GXDB3NQ.js} +6 -6
  14. package/dist/chunk-3GXDB3NQ.js.map +1 -0
  15. package/dist/{chunk-U73LHVPF.js → chunk-3S2YNMUS.js} +54 -6
  16. package/dist/chunk-3S2YNMUS.js.map +1 -0
  17. package/dist/{chunk-JW3XCZA2.js → chunk-3TZUC4WS.js} +11 -11
  18. package/dist/{chunk-JA5B3SLH.js → chunk-44Y3P5U6.js} +2 -2
  19. package/dist/{chunk-25G7U6RD.js → chunk-4B3DL75F.js} +2 -2
  20. package/dist/{chunk-L4OA7G5T.js → chunk-522MBPE5.js} +2 -2
  21. package/dist/chunk-5ABOFAHN.js +81 -0
  22. package/dist/chunk-5ABOFAHN.js.map +1 -0
  23. package/dist/chunk-5D2ALSM5.js +19 -0
  24. package/dist/chunk-5D2ALSM5.js.map +1 -0
  25. package/dist/{chunk-M25ZIEB2.js → chunk-5HSSTOOG.js} +2 -2
  26. package/dist/{chunk-LLVW4V7R.js → chunk-5WLDZZ6S.js} +3 -3
  27. package/dist/{chunk-BCOKZC4B.js → chunk-6SSWOUUS.js} +19 -19
  28. package/dist/chunk-6SSWOUUS.js.map +1 -0
  29. package/dist/{chunk-IGM563N5.js → chunk-6SYOHUHM.js} +6 -6
  30. package/dist/chunk-6SYOHUHM.js.map +1 -0
  31. package/dist/{chunk-7B4GPCX7.js → chunk-7IQWHYL2.js} +5 -5
  32. package/dist/{chunk-J3VW4J4E.js → chunk-7LP7FFJ2.js} +2 -2
  33. package/dist/chunk-7LP7FFJ2.js.map +1 -0
  34. package/dist/{chunk-5P5AAXYA.js → chunk-7U6AB7DZ.js} +7 -7
  35. package/dist/chunk-7U6AB7DZ.js.map +1 -0
  36. package/dist/chunk-AFHQATY4.js +47 -0
  37. package/dist/chunk-AFHQATY4.js.map +1 -0
  38. package/dist/{chunk-OWE4BNTM.js → chunk-AZXEOEQK.js} +4 -4
  39. package/dist/{chunk-GBEXTC6Z.js → chunk-BAAUFCJK.js} +3 -3
  40. package/dist/chunk-BAAUFCJK.js.map +1 -0
  41. package/dist/{chunk-BZEPJJOK.js → chunk-C2V7AJO2.js} +4 -4
  42. package/dist/chunk-CADUYBQD.js +151 -0
  43. package/dist/chunk-CADUYBQD.js.map +1 -0
  44. package/dist/{chunk-2JZ763FV.js → chunk-D4LAJ737.js} +2 -2
  45. package/dist/{chunk-5BHNQNBI.js → chunk-DOZFU7OZ.js} +1 -1
  46. package/dist/chunk-DOZFU7OZ.js.map +1 -0
  47. package/dist/{chunk-MEKAMERX.js → chunk-E7FSBI6I.js} +29 -29
  48. package/dist/chunk-E7FSBI6I.js.map +1 -0
  49. package/dist/{chunk-N4FZ6ITM.js → chunk-EGU4PWQW.js} +2 -2
  50. package/dist/chunk-EP5L47XV.js +22 -0
  51. package/dist/chunk-EP5L47XV.js.map +1 -0
  52. package/dist/{chunk-EW4HFWGJ.js → chunk-EPME33Y4.js} +6 -6
  53. package/dist/{chunk-W7TCXZWU.js → chunk-EWPS35AR.js} +794 -1045
  54. package/dist/chunk-EWPS35AR.js.map +1 -0
  55. package/dist/{chunk-JKWNG3TM.js → chunk-FHHYCBBP.js} +2 -2
  56. package/dist/{chunk-5BB3N4KU.js → chunk-G4MFQXYX.js} +2 -2
  57. package/dist/{chunk-KVHWEPT2.js → chunk-GHEMAVTN.js} +2 -2
  58. package/dist/{chunk-CGPO3ZYB.js → chunk-GQT6J4FJ.js} +15 -2
  59. package/dist/chunk-GQT6J4FJ.js.map +1 -0
  60. package/dist/{chunk-XW7NWO4A.js → chunk-GTNRMJYH.js} +2 -2
  61. package/dist/{chunk-YG2EG6CB.js → chunk-H5GMROCB.js} +4 -4
  62. package/dist/{chunk-JIMEB4C6.js → chunk-HA7P3BTB.js} +26 -177
  63. package/dist/chunk-HA7P3BTB.js.map +1 -0
  64. package/dist/{chunk-5KI3REO3.js → chunk-HDF5R2K6.js} +7 -7
  65. package/dist/{chunk-V3YB7RGR.js → chunk-HVPW6PCX.js} +3 -3
  66. package/dist/{chunk-2VUISNGP.js → chunk-HXVRRJBD.js} +5 -5
  67. package/dist/{chunk-ZJGZDOQO.js → chunk-ICYC5YNI.js} +6 -6
  68. package/dist/{chunk-KR5EGWI4.js → chunk-IUATR5UE.js} +27 -5
  69. package/dist/chunk-IUATR5UE.js.map +1 -0
  70. package/dist/{chunk-AFBJHD55.js → chunk-JGOKAZNB.js} +5 -5
  71. package/dist/{chunk-XGVDLQJE.js → chunk-JOCMXSR2.js} +3 -3
  72. package/dist/{chunk-XGVDLQJE.js.map → chunk-JOCMXSR2.js.map} +1 -1
  73. package/dist/{chunk-HGVFJL63.js → chunk-JTIPVW4J.js} +15 -5
  74. package/dist/{chunk-HGVFJL63.js.map → chunk-JTIPVW4J.js.map} +1 -1
  75. package/dist/{chunk-QXPOEAKR.js → chunk-KCZAFDP5.js} +2 -2
  76. package/dist/{chunk-MSO2C3KG.js → chunk-LC7DSMHR.js} +2 -2
  77. package/dist/{chunk-OVFCAS7U.js → chunk-LG2GUYRX.js} +9 -9
  78. package/dist/{chunk-2KL6NDD4.js → chunk-LN3MQFUE.js} +56 -4
  79. package/dist/chunk-LN3MQFUE.js.map +1 -0
  80. package/dist/{chunk-QUIG6BZT.js → chunk-M4GO4ZJK.js} +226 -36
  81. package/dist/chunk-M4GO4ZJK.js.map +1 -0
  82. package/dist/{chunk-QDNVHA2F.js → chunk-M7W2KYTL.js} +2 -2
  83. package/dist/{chunk-XULHFSHO.js → chunk-MLCTPWSO.js} +5 -5
  84. package/dist/chunk-MLCTPWSO.js.map +1 -0
  85. package/dist/{chunk-PEY6ZTCF.js → chunk-MMVQ3SUO.js} +9 -9
  86. package/dist/{chunk-PEY6ZTCF.js.map → chunk-MMVQ3SUO.js.map} +1 -1
  87. package/dist/{chunk-4X6DJZHY.js → chunk-MPPWL64H.js} +26 -43
  88. package/dist/chunk-MPPWL64H.js.map +1 -0
  89. package/dist/{chunk-QYJIOWKN.js → chunk-MQBFT2OT.js} +11 -9
  90. package/dist/chunk-MQBFT2OT.js.map +1 -0
  91. package/dist/{chunk-IUIVDVXM.js → chunk-MUPZ6IZX.js} +2 -2
  92. package/dist/{chunk-GZ2GKOF6.js → chunk-NA374QG7.js} +3 -3
  93. package/dist/chunk-NIKO2BBZ.js +23 -0
  94. package/dist/chunk-NIKO2BBZ.js.map +1 -0
  95. package/dist/{chunk-2U7Y7BNJ.js → chunk-ONB627HU.js} +2 -2
  96. package/dist/{chunk-GYB2QK5H.js → chunk-OWLZONGX.js} +2 -2
  97. package/dist/{chunk-YHPUDB7Q.js → chunk-OWOT7CFC.js} +2 -2
  98. package/dist/{chunk-VEX6G3YL.js → chunk-P4NUJVWL.js} +2 -2
  99. package/dist/chunk-PEOZ34EM.js +13 -0
  100. package/dist/chunk-PEOZ34EM.js.map +1 -0
  101. package/dist/{chunk-NM4LVUXH.js → chunk-PTT2NB46.js} +2 -2
  102. package/dist/chunk-PVEWA2DU.js +23 -0
  103. package/dist/chunk-PVEWA2DU.js.map +1 -0
  104. package/dist/{chunk-2ITLQZV5.js → chunk-PWWWMRT7.js} +2 -2
  105. package/dist/{chunk-FLHOTGOO.js → chunk-QVGEVZ5F.js} +3 -3
  106. package/dist/{chunk-HKR25MGX.js → chunk-QVIZDLAR.js} +10 -10
  107. package/dist/chunk-QVIZDLAR.js.map +1 -0
  108. package/dist/{chunk-OOTTXUNV.js → chunk-RM5EXCFF.js} +2 -2
  109. package/dist/{chunk-OOTTXUNV.js.map → chunk-RM5EXCFF.js.map} +1 -1
  110. package/dist/{chunk-OGFPMCSP.js → chunk-SBOHNJUD.js} +2 -2
  111. package/dist/{chunk-EDC6MLXV.js → chunk-SEU6QHH4.js} +2 -2
  112. package/dist/chunk-SMY5X46Z.js +14 -0
  113. package/dist/chunk-SMY5X46Z.js.map +1 -0
  114. package/dist/{chunk-F4COUZLL.js → chunk-TMR64XPL.js} +2 -2
  115. package/dist/{chunk-5OZCCLNC.js → chunk-TSNRZSRC.js} +2 -2
  116. package/dist/{chunk-2RMDVWGB.js → chunk-UNREYBZO.js} +2 -2
  117. package/dist/{chunk-BLB7P7LS.js → chunk-V2R2VWER.js} +176 -17
  118. package/dist/chunk-V2R2VWER.js.map +1 -0
  119. package/dist/{chunk-3XVOLB75.js → chunk-VDTWFN2P.js} +7 -5
  120. package/dist/chunk-VDTWFN2P.js.map +1 -0
  121. package/dist/chunk-VKQCVU2Z.js +21 -0
  122. package/dist/chunk-VKQCVU2Z.js.map +1 -0
  123. package/dist/{chunk-QCUH2G77.js → chunk-VNJMLOQS.js} +6 -6
  124. package/dist/{chunk-UEO5CHOP.js → chunk-WCJJQV2D.js} +13 -13
  125. package/dist/chunk-WCJJQV2D.js.map +1 -0
  126. package/dist/{chunk-25ZDB25Z.js → chunk-WWBC4KLB.js} +3 -3
  127. package/dist/chunk-WWBC4KLB.js.map +1 -0
  128. package/dist/{chunk-V7RGFJ3Z.js → chunk-XG7OZDOS.js} +6 -6
  129. package/dist/{chunk-GS3Q2KOZ.js → chunk-XONZGK6J.js} +2 -2
  130. package/dist/{chunk-5SZ24DL5.js → chunk-XSOGLHGY.js} +6 -6
  131. package/dist/{chunk-CCT4WZI6.js → chunk-XY6MNSAF.js} +5 -5
  132. package/dist/chunk-XY6MNSAF.js.map +1 -0
  133. package/dist/chunk-XZHEOSQ2.js +16 -0
  134. package/dist/chunk-XZHEOSQ2.js.map +1 -0
  135. package/dist/{chunk-NOT7XA7Q.js → chunk-YGMREQAK.js} +5 -5
  136. package/dist/{chunk-H4SMS4O2.js → chunk-YJ3TREAC.js} +2 -2
  137. package/dist/chunk-YMUFFJCO.js +23 -0
  138. package/dist/chunk-YMUFFJCO.js.map +1 -0
  139. package/dist/{chunk-E2R5NRZD.js → chunk-Z4D3YGAB.js} +2 -2
  140. package/dist/{chunk-WJDYZP3U.js → chunk-ZDFU34XY.js} +42 -39
  141. package/dist/chunk-ZDFU34XY.js.map +1 -0
  142. package/dist/{chunk-BZK6JEX4.js → chunk-ZF572E2M.js} +5 -5
  143. package/dist/{chunk-DEQ2JTBR.js → chunk-ZGEFBDPR.js} +4 -4
  144. package/dist/chunk-ZGEFBDPR.js.map +1 -0
  145. package/dist/{chunk-QAFWRGVD.js → chunk-ZHMUFYZF.js} +7 -7
  146. package/dist/{chunk-BVZGNMVM.js → chunk-ZHZ4PET5.js} +3 -3
  147. package/dist/{chunk-IZX3WZBF.js → chunk-ZM72UO3Y.js} +4 -4
  148. package/dist/{chunk-STR7WBOB.js → chunk-ZUDAK436.js} +2 -2
  149. package/dist/{chunk-ITI3SJRB.js → chunk-ZX5FNWH7.js} +2 -2
  150. package/dist/classified/index.js +5 -5
  151. package/dist/{classified-marker-7S5IEP6Q.js → classified-marker-SVDRXLD3.js} +3 -3
  152. package/dist/collection-facade-S5PPKZD5.js +44 -0
  153. package/dist/{computed-WZNKRLCY.js → computed-33DRJDOC.js} +3 -3
  154. package/dist/consent/index.js +13 -9
  155. package/dist/consent/index.js.map +1 -1
  156. package/dist/{cover-B5MY43CK.js → cover-ADBCTIKN.js} +4 -4
  157. package/dist/crdt/index.js +4 -0
  158. package/dist/crdt/index.js.map +1 -1
  159. package/dist/{dead-filter-KRRD57MR.js → dead-filter-HKDMTMVY.js} +2 -2
  160. package/dist/delegation-EV7LKJPH.js +25 -0
  161. package/dist/derivations/index.js +12 -12
  162. package/dist/derive-5LDJW76F.js +21 -0
  163. package/dist/dispatch-SPMYNXNW.js +194 -0
  164. package/dist/dispatch-SPMYNXNW.js.map +1 -0
  165. package/dist/dispatch-V5MSMQYX.js +72 -0
  166. package/dist/dispatch-V5MSMQYX.js.map +1 -0
  167. package/dist/{enclave-YFKA3GJT.js → enclave-ZA7C3H2L.js} +11 -11
  168. package/dist/executor-FCJEH3FU.js +9 -0
  169. package/dist/executor-OHET7TF7.js +9 -0
  170. package/dist/executor-SVHAJZ4A.js +28 -0
  171. package/dist/export-accessible-S35YKIBL.js +23 -0
  172. package/dist/extract-partition-UVHAM5WZ.js +38 -0
  173. package/dist/{fanout-sidecar-HJV3A7PM.js → fanout-sidecar-HRMHC34B.js} +9 -9
  174. package/dist/find-LEBUXVL7.js +11 -0
  175. package/dist/forget/index.js +9 -9
  176. package/dist/guards/index.js +3 -3
  177. package/dist/history/index.js +16 -12
  178. package/dist/history/index.js.map +1 -1
  179. package/dist/i18n/index.js +16 -14
  180. package/dist/i18n/index.js.map +1 -1
  181. package/dist/index.d.ts +17 -16
  182. package/dist/index.js +155 -211
  183. package/dist/index.js.map +1 -1
  184. package/dist/indexing/index.js +4 -2
  185. package/dist/indexing/index.js.map +1 -1
  186. package/dist/issue-5X3SMCF4.js +19 -0
  187. package/dist/kernel/collection.d.ts +0 -1
  188. package/dist/kernel/enclave/crypto.d.ts +8 -8
  189. package/dist/kernel/enclave/index.d.ts +2 -2
  190. package/dist/kernel/errors.d.ts +20 -20
  191. package/dist/kernel/lazy.d.ts +30 -0
  192. package/dist/kernel/noydb.d.ts +53 -101
  193. package/dist/kernel/query/builder.d.ts +10 -10
  194. package/dist/kernel/query/index.d.ts +0 -6
  195. package/dist/kernel/query/scan-builder.d.ts +4 -4
  196. package/dist/kernel/types.d.ts +87 -46
  197. package/dist/kernel/validation.d.ts +33 -33
  198. package/dist/kernel/vault.d.ts +12 -149
  199. package/dist/kernel/via/dispatch.d.ts +7 -0
  200. package/dist/{ledger-SW6QQOAV.js → ledger-K6JBFL3Z.js} +11 -11
  201. package/dist/liberate-NHTCKBU4.js +24 -0
  202. package/dist/{link-set-GNGGCFI4.js → link-set-XVZY2ODC.js} +11 -11
  203. package/dist/materialized-views/index.js +22 -19
  204. package/dist/noydb-TI3RFU6M.js +78 -0
  205. package/dist/overlay-views/index.js +4 -4
  206. package/dist/periods/index.js +15 -13
  207. package/dist/pod/index.js +11 -12
  208. package/dist/{policy-EAXSJNOT.js → policy-QWGJB7P7.js} +5 -5
  209. package/dist/port/with/collection-options.d.ts +171 -0
  210. package/dist/port/with/collection-registries.d.ts +62 -0
  211. package/dist/port/with/strategies.d.ts +2 -2
  212. package/dist/port/with/team-strategy.d.ts +3 -2
  213. package/dist/portability/index.js +8 -8
  214. package/dist/{post-register-A7HCFBP5.js → post-register-5VHHVFJY.js} +6 -6
  215. package/dist/query/index.js +6 -46
  216. package/dist/{aggregate → reduce}/index.js +24 -17
  217. package/dist/reduce/index.js.map +1 -0
  218. package/dist/register-CEX7R7NE.js +23 -0
  219. package/dist/registry-7CZWF3EQ.js +9 -0
  220. package/dist/registry-DIKMRXUC.js +19 -0
  221. package/dist/registry-EWIB5NTI.js +18 -0
  222. package/dist/request-withdrawal-AAG57QO4.js +31 -0
  223. package/dist/{reveal-PB3YG544.js → reveal-7OOT5XPD.js} +6 -6
  224. package/dist/revoke-U5LCIJMF.js +24 -0
  225. package/dist/satellites/index.js +1 -1
  226. package/dist/sealed-record/index.js +12 -12
  227. package/dist/{seed-EKF4DIBB.js → seed-GVOI6QP6.js} +12 -12
  228. package/dist/seed-GVOI6QP6.js.map +1 -0
  229. package/dist/session/index.js +13 -9
  230. package/dist/session/index.js.map +1 -1
  231. package/dist/shadow/index.js +6 -2
  232. package/dist/shadow/index.js.map +1 -1
  233. package/dist/signer-NAA2OX7H.js +25 -0
  234. package/dist/snapshots/index.js +14 -10
  235. package/dist/snapshots/index.js.map +1 -1
  236. package/dist/{stale-4UNPHWOU.js → stale-BJO2WIN7.js} +11 -10
  237. package/dist/storage-FL7XXZTN.js +23 -0
  238. package/dist/{store-coordination-provider-3AELCZ4Y.js → store-coordination-provider-DX5HECK3.js} +3 -3
  239. package/dist/sync/index.js +14 -10
  240. package/dist/sync/index.js.map +1 -1
  241. package/dist/team/index.js +26 -28
  242. package/dist/tiers/index.js +10 -10
  243. package/dist/to/index.js +1 -1
  244. package/dist/tx/index.js +7 -3
  245. package/dist/tx/index.js.map +1 -1
  246. package/dist/util/index.js +1 -1
  247. package/dist/{verify-MXN66IIH.js → verify-5X37OXRY.js} +5 -5
  248. package/dist/via/blob/index.d.ts +2 -0
  249. package/dist/via/i18n/core.d.ts +1 -1
  250. package/dist/via/i18n/index.d.ts +2 -0
  251. package/dist/via/money/money-reducer.d.ts +2 -2
  252. package/dist/{walk-H4YE52S2.js → walk-JXMWKKQW.js} +11 -11
  253. package/dist/with-audit/consent/index.d.ts +2 -0
  254. package/dist/with-audit/periods/index.d.ts +2 -0
  255. package/dist/with-audit/portability/export-accessible.d.ts +4 -4
  256. package/dist/with-audit/portability/request-withdrawal.d.ts +3 -3
  257. package/dist/with-audit/portability/withdraw-accessible.d.ts +2 -2
  258. package/dist/with-audit/sealed-record/strategy.d.ts +1 -1
  259. package/dist/with-cargo/adopt-partition.d.ts +7 -7
  260. package/dist/with-cargo/floor.d.ts +3 -3
  261. package/dist/with-cargo/index.d.ts +1 -1
  262. package/dist/with-commit/crdt/index.d.ts +2 -0
  263. package/dist/with-commit/history/index.d.ts +2 -0
  264. package/dist/with-commit/history/time-machine.d.ts +2 -2
  265. package/dist/with-fork/shadow/index.d.ts +2 -0
  266. package/dist/with-fork/snapshots/index.d.ts +2 -0
  267. package/dist/with-formula/derivations/dispatch.d.ts +98 -0
  268. package/dist/with-formula/materialized-views/dispatch.d.ts +75 -0
  269. package/dist/with-formula/materialized-views/types.d.ts +7 -7
  270. package/dist/with-lookup/indexing/index.d.ts +2 -0
  271. package/dist/with-lookup/{aggregate → reduce}/active.d.ts +8 -8
  272. package/dist/with-lookup/{aggregate → reduce}/groupby.d.ts +21 -21
  273. package/dist/with-lookup/reduce/index.d.ts +34 -0
  274. package/dist/with-lookup/{aggregate → reduce}/reducers.d.ts +10 -10
  275. package/dist/with-lookup/{aggregate/aggregation.d.ts → reduce/reduction.d.ts} +21 -21
  276. package/dist/with-lookup/{aggregate → reduce}/strategy.d.ts +15 -15
  277. package/dist/with-party/custody/liberate.d.ts +3 -3
  278. package/dist/with-party/session/dev-unlock.d.ts +2 -2
  279. package/dist/with-party/session/index.d.ts +2 -0
  280. package/dist/with-party/session/session.d.ts +2 -2
  281. package/dist/with-party/sync/index.d.ts +2 -0
  282. package/dist/with-party/team/deed.d.ts +8 -8
  283. package/dist/with-party/team/index.d.ts +2 -2
  284. package/dist/with-party/team/keyring.d.ts +39 -20
  285. package/dist/with-party/team/{managed-passphrase.d.ts → managed-secret.d.ts} +27 -27
  286. package/dist/with-party/team/noydb-facade.d.ts +43 -42
  287. package/dist/with-party/team/peer-recover.d.ts +13 -13
  288. package/dist/with-party/team/recovery.d.ts +5 -5
  289. package/dist/with-party/team/rotate-recover.d.ts +30 -30
  290. package/dist/with-pod/bundle.d.ts +30 -30
  291. package/dist/with-pod/format.d.ts +2 -2
  292. package/dist/withdraw-accessible-GO6KQJVM.js +28 -0
  293. package/package.json +6 -34
  294. package/dist/aggregate/index.js.map +0 -1
  295. package/dist/api-UPAT2O3M.js +0 -20
  296. package/dist/as/index.js +0 -30
  297. package/dist/at/index.js +0 -1
  298. package/dist/by/index.js +0 -11
  299. package/dist/chunk-25ZDB25Z.js.map +0 -1
  300. package/dist/chunk-2KL6NDD4.js.map +0 -1
  301. package/dist/chunk-2YELV6TV.js +0 -1
  302. package/dist/chunk-3O62PVDW.js +0 -205
  303. package/dist/chunk-3O62PVDW.js.map +0 -1
  304. package/dist/chunk-3XVOLB75.js.map +0 -1
  305. package/dist/chunk-4X6DJZHY.js.map +0 -1
  306. package/dist/chunk-5BHNQNBI.js.map +0 -1
  307. package/dist/chunk-5P5AAXYA.js.map +0 -1
  308. package/dist/chunk-BCOKZC4B.js.map +0 -1
  309. package/dist/chunk-BLB7P7LS.js.map +0 -1
  310. package/dist/chunk-CCT4WZI6.js.map +0 -1
  311. package/dist/chunk-CGPO3ZYB.js.map +0 -1
  312. package/dist/chunk-DEQ2JTBR.js.map +0 -1
  313. package/dist/chunk-GBEXTC6Z.js.map +0 -1
  314. package/dist/chunk-HKR25MGX.js.map +0 -1
  315. package/dist/chunk-IGM563N5.js.map +0 -1
  316. package/dist/chunk-J3VW4J4E.js.map +0 -1
  317. package/dist/chunk-JA5O7UEZ.js.map +0 -1
  318. package/dist/chunk-JIMEB4C6.js.map +0 -1
  319. package/dist/chunk-KMONEHDJ.js +0 -54
  320. package/dist/chunk-KMONEHDJ.js.map +0 -1
  321. package/dist/chunk-KR5EGWI4.js.map +0 -1
  322. package/dist/chunk-LB7FD65R.js +0 -163
  323. package/dist/chunk-LB7FD65R.js.map +0 -1
  324. package/dist/chunk-MEKAMERX.js.map +0 -1
  325. package/dist/chunk-QUIG6BZT.js.map +0 -1
  326. package/dist/chunk-QYJIOWKN.js.map +0 -1
  327. package/dist/chunk-U73LHVPF.js.map +0 -1
  328. package/dist/chunk-UEO5CHOP.js.map +0 -1
  329. package/dist/chunk-W7TCXZWU.js.map +0 -1
  330. package/dist/chunk-WEC3JGBA.js +0 -255
  331. package/dist/chunk-WEC3JGBA.js.map +0 -1
  332. package/dist/chunk-WJDYZP3U.js.map +0 -1
  333. package/dist/chunk-XULHFSHO.js.map +0 -1
  334. package/dist/collection-facade-CMZGQ6IS.js +0 -44
  335. package/dist/delegation-UT76AQIG.js +0 -25
  336. package/dist/derive-SGRCCKVP.js +0 -21
  337. package/dist/executor-TEZYRDN3.js +0 -9
  338. package/dist/executor-WQQRU6DO.js +0 -9
  339. package/dist/executor-YORMIBWV.js +0 -26
  340. package/dist/export-accessible-HXMKW5LJ.js +0 -23
  341. package/dist/extract-partition-QGQ2R42J.js +0 -38
  342. package/dist/find-VV6PBIHK.js +0 -11
  343. package/dist/in/index.js +0 -1
  344. package/dist/issue-7JJ4Z7E2.js +0 -19
  345. package/dist/liberate-FK7JI2QX.js +0 -24
  346. package/dist/noydb-N5IW6OFZ.js +0 -70
  347. package/dist/on/index.js +0 -17
  348. package/dist/port/as/index.d.ts +0 -26
  349. package/dist/port/at/index.d.ts +0 -18
  350. package/dist/port/in/index.d.ts +0 -21
  351. package/dist/port/on/index.d.ts +0 -27
  352. package/dist/port/ui/index.d.ts +0 -21
  353. package/dist/port/with/index.d.ts +0 -18
  354. package/dist/register-YBMRLZLO.js +0 -23
  355. package/dist/registry-3LXKNXWI.js +0 -9
  356. package/dist/registry-4V4YQCXJ.js +0 -19
  357. package/dist/registry-ZULMLCJK.js +0 -18
  358. package/dist/request-withdrawal-SEVUEUDG.js +0 -31
  359. package/dist/request-withdrawal-SEVUEUDG.js.map +0 -1
  360. package/dist/revoke-5QULL5GT.js +0 -24
  361. package/dist/revoke-5QULL5GT.js.map +0 -1
  362. package/dist/seed-EKF4DIBB.js.map +0 -1
  363. package/dist/signer-ZMH35FT4.js +0 -25
  364. package/dist/signer-ZMH35FT4.js.map +0 -1
  365. package/dist/stale-4UNPHWOU.js.map +0 -1
  366. package/dist/storage-QOZKQMID.js +0 -23
  367. package/dist/storage-QOZKQMID.js.map +0 -1
  368. package/dist/ui/index.js +0 -1
  369. package/dist/ui/index.js.map +0 -1
  370. package/dist/with/index.js +0 -31
  371. package/dist/with/index.js.map +0 -1
  372. package/dist/with-lookup/aggregate/index.d.ts +0 -23
  373. package/dist/withdraw-accessible-HPOVNG2G.js +0 -28
  374. package/dist/withdraw-accessible-HPOVNG2G.js.map +0 -1
  375. /package/dist/{api-UPAT2O3M.js.map → api-5QVQX4HG.js.map} +0 -0
  376. /package/dist/{backup-JL2GOTYQ.js.map → backup-USYSNCYM.js.map} +0 -0
  377. /package/dist/{chunk-JLHKBAFY.js.map → chunk-2BVW754E.js.map} +0 -0
  378. /package/dist/{chunk-T7S4V52L.js.map → chunk-2PDBYF2O.js.map} +0 -0
  379. /package/dist/{chunk-YGBIBOCR.js.map → chunk-2ZSC454H.js.map} +0 -0
  380. /package/dist/{chunk-IGAIOGCN.js.map → chunk-32467U5J.js.map} +0 -0
  381. /package/dist/{chunk-JW3XCZA2.js.map → chunk-3TZUC4WS.js.map} +0 -0
  382. /package/dist/{chunk-JA5B3SLH.js.map → chunk-44Y3P5U6.js.map} +0 -0
  383. /package/dist/{chunk-25G7U6RD.js.map → chunk-4B3DL75F.js.map} +0 -0
  384. /package/dist/{chunk-L4OA7G5T.js.map → chunk-522MBPE5.js.map} +0 -0
  385. /package/dist/{chunk-M25ZIEB2.js.map → chunk-5HSSTOOG.js.map} +0 -0
  386. /package/dist/{chunk-LLVW4V7R.js.map → chunk-5WLDZZ6S.js.map} +0 -0
  387. /package/dist/{chunk-7B4GPCX7.js.map → chunk-7IQWHYL2.js.map} +0 -0
  388. /package/dist/{chunk-OWE4BNTM.js.map → chunk-AZXEOEQK.js.map} +0 -0
  389. /package/dist/{chunk-BZEPJJOK.js.map → chunk-C2V7AJO2.js.map} +0 -0
  390. /package/dist/{chunk-2JZ763FV.js.map → chunk-D4LAJ737.js.map} +0 -0
  391. /package/dist/{chunk-N4FZ6ITM.js.map → chunk-EGU4PWQW.js.map} +0 -0
  392. /package/dist/{chunk-EW4HFWGJ.js.map → chunk-EPME33Y4.js.map} +0 -0
  393. /package/dist/{chunk-JKWNG3TM.js.map → chunk-FHHYCBBP.js.map} +0 -0
  394. /package/dist/{chunk-5BB3N4KU.js.map → chunk-G4MFQXYX.js.map} +0 -0
  395. /package/dist/{chunk-KVHWEPT2.js.map → chunk-GHEMAVTN.js.map} +0 -0
  396. /package/dist/{chunk-XW7NWO4A.js.map → chunk-GTNRMJYH.js.map} +0 -0
  397. /package/dist/{chunk-YG2EG6CB.js.map → chunk-H5GMROCB.js.map} +0 -0
  398. /package/dist/{chunk-5KI3REO3.js.map → chunk-HDF5R2K6.js.map} +0 -0
  399. /package/dist/{chunk-V3YB7RGR.js.map → chunk-HVPW6PCX.js.map} +0 -0
  400. /package/dist/{chunk-2VUISNGP.js.map → chunk-HXVRRJBD.js.map} +0 -0
  401. /package/dist/{chunk-ZJGZDOQO.js.map → chunk-ICYC5YNI.js.map} +0 -0
  402. /package/dist/{chunk-AFBJHD55.js.map → chunk-JGOKAZNB.js.map} +0 -0
  403. /package/dist/{chunk-QXPOEAKR.js.map → chunk-KCZAFDP5.js.map} +0 -0
  404. /package/dist/{chunk-MSO2C3KG.js.map → chunk-LC7DSMHR.js.map} +0 -0
  405. /package/dist/{chunk-OVFCAS7U.js.map → chunk-LG2GUYRX.js.map} +0 -0
  406. /package/dist/{chunk-QDNVHA2F.js.map → chunk-M7W2KYTL.js.map} +0 -0
  407. /package/dist/{chunk-IUIVDVXM.js.map → chunk-MUPZ6IZX.js.map} +0 -0
  408. /package/dist/{chunk-GZ2GKOF6.js.map → chunk-NA374QG7.js.map} +0 -0
  409. /package/dist/{chunk-2U7Y7BNJ.js.map → chunk-ONB627HU.js.map} +0 -0
  410. /package/dist/{chunk-GYB2QK5H.js.map → chunk-OWLZONGX.js.map} +0 -0
  411. /package/dist/{chunk-YHPUDB7Q.js.map → chunk-OWOT7CFC.js.map} +0 -0
  412. /package/dist/{chunk-VEX6G3YL.js.map → chunk-P4NUJVWL.js.map} +0 -0
  413. /package/dist/{chunk-NM4LVUXH.js.map → chunk-PTT2NB46.js.map} +0 -0
  414. /package/dist/{chunk-2ITLQZV5.js.map → chunk-PWWWMRT7.js.map} +0 -0
  415. /package/dist/{chunk-FLHOTGOO.js.map → chunk-QVGEVZ5F.js.map} +0 -0
  416. /package/dist/{chunk-OGFPMCSP.js.map → chunk-SBOHNJUD.js.map} +0 -0
  417. /package/dist/{chunk-EDC6MLXV.js.map → chunk-SEU6QHH4.js.map} +0 -0
  418. /package/dist/{chunk-F4COUZLL.js.map → chunk-TMR64XPL.js.map} +0 -0
  419. /package/dist/{chunk-5OZCCLNC.js.map → chunk-TSNRZSRC.js.map} +0 -0
  420. /package/dist/{chunk-2RMDVWGB.js.map → chunk-UNREYBZO.js.map} +0 -0
  421. /package/dist/{chunk-QCUH2G77.js.map → chunk-VNJMLOQS.js.map} +0 -0
  422. /package/dist/{chunk-V7RGFJ3Z.js.map → chunk-XG7OZDOS.js.map} +0 -0
  423. /package/dist/{chunk-GS3Q2KOZ.js.map → chunk-XONZGK6J.js.map} +0 -0
  424. /package/dist/{chunk-5SZ24DL5.js.map → chunk-XSOGLHGY.js.map} +0 -0
  425. /package/dist/{chunk-NOT7XA7Q.js.map → chunk-YGMREQAK.js.map} +0 -0
  426. /package/dist/{chunk-H4SMS4O2.js.map → chunk-YJ3TREAC.js.map} +0 -0
  427. /package/dist/{chunk-E2R5NRZD.js.map → chunk-Z4D3YGAB.js.map} +0 -0
  428. /package/dist/{chunk-BZK6JEX4.js.map → chunk-ZF572E2M.js.map} +0 -0
  429. /package/dist/{chunk-QAFWRGVD.js.map → chunk-ZHMUFYZF.js.map} +0 -0
  430. /package/dist/{chunk-BVZGNMVM.js.map → chunk-ZHZ4PET5.js.map} +0 -0
  431. /package/dist/{chunk-IZX3WZBF.js.map → chunk-ZM72UO3Y.js.map} +0 -0
  432. /package/dist/{chunk-STR7WBOB.js.map → chunk-ZUDAK436.js.map} +0 -0
  433. /package/dist/{chunk-ITI3SJRB.js.map → chunk-ZX5FNWH7.js.map} +0 -0
  434. /package/dist/{classified-marker-7S5IEP6Q.js.map → classified-marker-SVDRXLD3.js.map} +0 -0
  435. /package/dist/{as/index.js.map → collection-facade-S5PPKZD5.js.map} +0 -0
  436. /package/dist/{at/index.js.map → computed-33DRJDOC.js.map} +0 -0
  437. /package/dist/{by/index.js.map → cover-ADBCTIKN.js.map} +0 -0
  438. /package/dist/{dead-filter-KRRD57MR.js.map → dead-filter-HKDMTMVY.js.map} +0 -0
  439. /package/dist/{chunk-2YELV6TV.js.map → delegation-EV7LKJPH.js.map} +0 -0
  440. /package/dist/{collection-facade-CMZGQ6IS.js.map → derive-5LDJW76F.js.map} +0 -0
  441. /package/dist/{computed-WZNKRLCY.js.map → enclave-ZA7C3H2L.js.map} +0 -0
  442. /package/dist/{cover-B5MY43CK.js.map → executor-FCJEH3FU.js.map} +0 -0
  443. /package/dist/{delegation-UT76AQIG.js.map → executor-OHET7TF7.js.map} +0 -0
  444. /package/dist/{derive-SGRCCKVP.js.map → executor-SVHAJZ4A.js.map} +0 -0
  445. /package/dist/{enclave-YFKA3GJT.js.map → export-accessible-S35YKIBL.js.map} +0 -0
  446. /package/dist/{executor-TEZYRDN3.js.map → extract-partition-UVHAM5WZ.js.map} +0 -0
  447. /package/dist/{fanout-sidecar-HJV3A7PM.js.map → fanout-sidecar-HRMHC34B.js.map} +0 -0
  448. /package/dist/{executor-WQQRU6DO.js.map → find-LEBUXVL7.js.map} +0 -0
  449. /package/dist/{executor-YORMIBWV.js.map → issue-5X3SMCF4.js.map} +0 -0
  450. /package/dist/{export-accessible-HXMKW5LJ.js.map → ledger-K6JBFL3Z.js.map} +0 -0
  451. /package/dist/{extract-partition-QGQ2R42J.js.map → liberate-NHTCKBU4.js.map} +0 -0
  452. /package/dist/{find-VV6PBIHK.js.map → link-set-XVZY2ODC.js.map} +0 -0
  453. /package/dist/{in/index.js.map → noydb-TI3RFU6M.js.map} +0 -0
  454. /package/dist/{issue-7JJ4Z7E2.js.map → policy-QWGJB7P7.js.map} +0 -0
  455. /package/dist/{post-register-A7HCFBP5.js.map → post-register-5VHHVFJY.js.map} +0 -0
  456. /package/dist/{ledger-SW6QQOAV.js.map → register-CEX7R7NE.js.map} +0 -0
  457. /package/dist/{liberate-FK7JI2QX.js.map → registry-7CZWF3EQ.js.map} +0 -0
  458. /package/dist/{link-set-GNGGCFI4.js.map → registry-DIKMRXUC.js.map} +0 -0
  459. /package/dist/{noydb-N5IW6OFZ.js.map → registry-EWIB5NTI.js.map} +0 -0
  460. /package/dist/{on/index.js.map → request-withdrawal-AAG57QO4.js.map} +0 -0
  461. /package/dist/{reveal-PB3YG544.js.map → reveal-7OOT5XPD.js.map} +0 -0
  462. /package/dist/{policy-EAXSJNOT.js.map → revoke-U5LCIJMF.js.map} +0 -0
  463. /package/dist/{register-YBMRLZLO.js.map → signer-NAA2OX7H.js.map} +0 -0
  464. /package/dist/{registry-3LXKNXWI.js.map → stale-BJO2WIN7.js.map} +0 -0
  465. /package/dist/{registry-4V4YQCXJ.js.map → storage-FL7XXZTN.js.map} +0 -0
  466. /package/dist/{store-coordination-provider-3AELCZ4Y.js.map → store-coordination-provider-DX5HECK3.js.map} +0 -0
  467. /package/dist/{verify-MXN66IIH.js.map → verify-5X37OXRY.js.map} +0 -0
  468. /package/dist/{walk-H4YE52S2.js.map → walk-JXMWKKQW.js.map} +0 -0
  469. /package/dist/with-lookup/{aggregate → reduce}/canonical-key.d.ts +0 -0
  470. /package/dist/{registry-ZULMLCJK.js.map → withdraw-accessible-GO6KQJVM.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-commit/history/strategy.ts"],"sourcesContent":["/**\n * Strategy seam for the optional history + ledger + time-machine\n * service. Core imports `HistoryStrategy` type-only + `NO_HISTORY`\n * stub; real implementations of `saveHistory`, `LedgerStore`,\n * `VaultInstant`, `computePatch`, `diff` etc. are only reachable via\n * `withHistory()` in `./active.ts`.\n *\n * Applications that don't track per-record versioning, don't need the\n * hash-chained audit ledger, and don't restore to past instants ship\n * none of the ~1,880 LOC behind this seam.\n *\n * Strategy contract:\n *\n * - **saveHistory / pruneHistory / clearHistory** — no-ops under\n * NO_HISTORY. Writes still succeed; no snapshot is captured.\n * - **getHistoryEntries / getVersionEnvelope / diff** — throw under\n * NO_HISTORY. These are read APIs the consumer would only call\n * after explicitly asking for history; the throw guides them to\n * `@noy-db/hub/history`.\n * - **envelopePayloadHash / computePatch** — return empty / `[]`\n * under NO_HISTORY. These are only used inside the\n * `if (this.ledger)` branch, which is itself gated by\n * `buildLedger()` returning null.\n * - **buildLedger** — returns `null` under NO_HISTORY. The Vault's\n * public `vault.ledger()` accessor throws when null.\n * - **buildVaultInstant** — throws under NO_HISTORY. `vault.at()`\n * propagates the throw.\n *\n * @internal\n */\n\nimport type {\n EncryptedEnvelope,\n NoydbStore,\n HistoryOptions,\n PruneOptions,\n} from '../../kernel/types.js'\nimport type { LedgerStore } from './ledger/store.js'\nimport type { JsonPatch } from './ledger/patch.js'\nimport type { DiffEntry } from './diff.js'\nimport type { VaultInstant, VaultEngine } from './time-machine.js'\nimport type { EnclaveKey } from '../../kernel/enclave/index.js'\n\n/**\n * Options accepted by `HistoryStrategy.buildLedger`. Mirrors the\n * `LedgerStore` constructor verbatim — kept in this file so `core`\n * code never imports the LedgerStore module at runtime.\n *\n * @internal\n */\nexport interface BuildLedgerOptions {\n adapter: NoydbStore\n vault: string\n encrypted: boolean\n getDEK: (collectionName: string) => Promise<EnclaveKey>\n actor: string\n}\n\n/**\n * @internal\n */\nexport interface HistoryStrategy {\n /**\n * Persist a full encrypted envelope snapshot of the prior version\n * under `_history/{collection}:{id}:{paddedVersion}`. No-op under\n * `NO_HISTORY`.\n */\n saveHistory(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string,\n envelope: EncryptedEnvelope,\n ): Promise<void>\n\n /**\n * List history envelopes for a record, newest first. Throws under\n * `NO_HISTORY` — callers reach this via `collection.history()` /\n * `collection.getVersion()` / `collection.diff()`, which only work\n * with the strategy enabled.\n */\n getHistoryEntries(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string,\n options?: HistoryOptions,\n ): Promise<EncryptedEnvelope[]>\n\n /**\n * Fetch a specific version's envelope. Throws under `NO_HISTORY`.\n */\n getVersionEnvelope(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string,\n version: number,\n ): Promise<EncryptedEnvelope | null>\n\n /**\n * Prune history entries by retention rule. Returns `0` under\n * `NO_HISTORY`.\n */\n pruneHistory(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string | undefined,\n options: PruneOptions,\n ): Promise<number>\n\n /**\n * Clear all history for vault/collection/record. Returns `0` under\n * `NO_HISTORY`.\n */\n clearHistory(\n adapter: NoydbStore,\n vault: string,\n collection?: string,\n recordId?: string,\n ): Promise<number>\n\n /**\n * Crypto-shred (overwrite-to-tombstone) every `_history` version of a\n * record for GDPR erasure. Returns the number of versions newly\n * tombstoned, or `0` under `NO_HISTORY` (no history = nothing to shred).\n */\n tombstoneHistory(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string,\n actor: string,\n encrypted: boolean,\n ): Promise<number>\n\n /**\n * Re-key every `_history` snapshot of a record from `fromDek` to `toDek`\n * on a tier move (elevate/demote/putAtTier), mirroring the live-body\n * rewrap so prior versions are not left decryptable at rest under a tier\n * the record has moved away from. Optional `tier0Dek` enables the legacy\n * fallback for snapshots written before this rewrap existed (see\n * `history.ts` for the full contract). No-op under `NO_HISTORY` (no\n * history = nothing to rewrap).\n */\n rewrapHistory(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string,\n fromDek: EnclaveKey,\n toDek: EnclaveKey,\n tier0Dek?: EnclaveKey,\n ): Promise<void>\n\n /**\n * Compute the SHA-256 hash of an envelope's encrypted payload, used\n * by `LedgerStore.append` to track tamper-evidence. Returns the\n * empty string under `NO_HISTORY` (the call site is gated by\n * `if (this.ledger)`, so the value is never observed).\n */\n envelopePayloadHash(envelope: EncryptedEnvelope | null): Promise<string>\n\n /**\n * Compute the JSON patch from `from` → `to`. Returns `[]` under\n * `NO_HISTORY`.\n */\n computePatch(from: unknown, to: unknown): JsonPatch\n\n /**\n * Compute the typed diff between two records. Throws under\n * `NO_HISTORY` — `collection.diff()` is a history-read API.\n */\n diff(recordA: unknown, recordB: unknown): DiffEntry[]\n\n /**\n * Construct (or return null) a `LedgerStore` for the vault. Returns\n * `null` under `NO_HISTORY`; the Vault treats null as \"no ledger\n * attached\" — collection write paths skip the append branch and the\n * public `vault.ledger()` accessor throws.\n */\n buildLedger(opts: BuildLedgerOptions): LedgerStore | null\n\n /**\n * Construct a `VaultInstant` for time-machine reads. Throws under\n * `NO_HISTORY`.\n */\n buildVaultInstant(engine: VaultEngine, timestamp: string): VaultInstant\n}\n\n/**\n * Error thrown when the consumer reaches a history-gated surface\n * without opting into the strategy. The message names the offending\n * operation and points to the subpath import.\n *\n * @internal\n */\nfunction notEnabled(op: string): Error {\n return new Error(\n `${op} requires the history strategy. Import ` +\n '`{ withHistory }` from \"@noy-db/hub/history\" and pass it to ' +\n '`createNoydb({ historyStrategy: withHistory() })`.',\n )\n}\n\n/**\n * No-history stub. Snapshots and prune/clear are no-ops; reads and\n * time-machine throw with an actionable message; ledger construction\n * returns null so the write-path's `if (this.ledger)` branch is dead\n * code in the bundle.\n *\n * @internal\n */\nexport const NO_HISTORY: HistoryStrategy = {\n async saveHistory() {},\n async getHistoryEntries() { throw notEnabled('collection.history()') },\n async getVersionEnvelope() { throw notEnabled('collection.getVersion()') },\n async pruneHistory() { return 0 },\n async clearHistory() { return 0 },\n async tombstoneHistory() { return 0 },\n async rewrapHistory() {},\n async envelopePayloadHash() { return '' },\n computePatch() { return [] },\n diff() { throw notEnabled('collection.diff()') },\n buildLedger() { return null },\n buildVaultInstant() { throw notEnabled('vault.at() / vault.timeMachine()') },\n}\n"],"mappings":";AAsMA,SAAS,WAAW,IAAmB;AACrC,SAAO,IAAI;AAAA,IACT,GAAG,EAAE;AAAA,EAGP;AACF;AAUO,IAAM,aAA8B;AAAA,EACzC,MAAM,cAAc;AAAA,EAAC;AAAA,EACrB,MAAM,oBAAoB;AAAE,UAAM,WAAW,sBAAsB;AAAA,EAAE;AAAA,EACrE,MAAM,qBAAqB;AAAE,UAAM,WAAW,yBAAyB;AAAA,EAAE;AAAA,EACzE,MAAM,eAAe;AAAE,WAAO;AAAA,EAAE;AAAA,EAChC,MAAM,eAAe;AAAE,WAAO;AAAA,EAAE;AAAA,EAChC,MAAM,mBAAmB;AAAE,WAAO;AAAA,EAAE;AAAA,EACpC,MAAM,gBAAgB;AAAA,EAAC;AAAA,EACvB,MAAM,sBAAsB;AAAE,WAAO;AAAA,EAAG;AAAA,EACxC,eAAe;AAAE,WAAO,CAAC;AAAA,EAAE;AAAA,EAC3B,OAAO;AAAE,UAAM,WAAW,mBAAmB;AAAA,EAAE;AAAA,EAC/C,cAAc;AAAE,WAAO;AAAA,EAAK;AAAA,EAC5B,oBAAoB;AAAE,UAAM,WAAW,kCAAkC;AAAA,EAAE;AAC7E;","names":[]}
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  openEnvelopeJson
3
- } from "./chunk-PEY6ZTCF.js";
3
+ } from "./chunk-MMVQ3SUO.js";
4
4
  import {
5
5
  encrypt,
6
6
  hmacSha256Hex,
7
7
  sha256Hex
8
- } from "./chunk-5P5AAXYA.js";
8
+ } from "./chunk-7U6AB7DZ.js";
9
9
  import {
10
10
  NOYDB_FORMAT_VERSION
11
- } from "./chunk-5BHNQNBI.js";
11
+ } from "./chunk-DOZFU7OZ.js";
12
12
 
13
13
  // src/with-audit/forget/strategy.ts
14
14
  var NO_FORGET = { subjects: {} };
@@ -147,4 +147,4 @@ export {
147
147
  coerceSubjectId,
148
148
  readDottedPath
149
149
  };
150
- //# sourceMappingURL=chunk-OWE4BNTM.js.map
150
+ //# sourceMappingURL=chunk-AZXEOEQK.js.map
@@ -4,13 +4,13 @@ import {
4
4
  import {
5
5
  base64ToBuffer,
6
6
  bufferToBase64
7
- } from "./chunk-5P5AAXYA.js";
7
+ } from "./chunk-7U6AB7DZ.js";
8
8
  import {
9
9
  SessionExpiredError,
10
10
  SessionNotFoundError,
11
11
  SessionPolicyError,
12
12
  ValidationError
13
- } from "./chunk-IGM563N5.js";
13
+ } from "./chunk-6SYOHUHM.js";
14
14
 
15
15
  // src/with-party/session/session.ts
16
16
  var subtle = globalThis.crypto.subtle;
@@ -364,4 +364,4 @@ export {
364
364
  clearDevUnlock,
365
365
  isDevUnlockActive
366
366
  };
367
- //# sourceMappingURL=chunk-GBEXTC6Z.js.map
367
+ //# sourceMappingURL=chunk-BAAUFCJK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-party/session/session.ts","../src/with-party/session/session-policy.ts","../src/with-party/session/dev-unlock.ts"],"sourcesContent":["/**\n * Session tokens —\n *\n * After a vault is unlocked (via secret, WebAuthn, OIDC, or magic-\n * link), the caller can call `createSession()` to get a session token that\n * allows re-establishing the KEK for the session lifetime without re-running\n * PBKDF2 or any interactive auth challenge.\n *\n * Security model\n * ──────────────\n * A session consists of two pieces that must both be present to recover the\n * KEK:\n *\n * 1. The **session key** — a non-extractable AES-256-GCM CryptoKey that\n * exists only in memory. \"Non-extractable\" is enforced by the WebCrypto\n * API: the key object cannot be serialized, exported, or sent over\n * postMessage. When the JS context is GC'd (tab close, navigation away,\n * worker termination) the key becomes unrecoverable.\n *\n * 2. The **session token** — a JSON object that carries the KEK wrapped\n * with the session key (AES-256-GCM, fresh IV per session), plus\n * unencrypted session metadata (sessionId, userId, vault, role,\n * expiresAt). The token can be serialized to JSON and stored in\n * sessionStorage or passed across callsites within the same tab, but\n * it is useless without the session key.\n *\n * The session key is kept in a module-level Map indexed by sessionId. Callers\n * that need to re-use a session must hold on to the sessionId returned from\n * `createSession()`; the key is looked up automatically by `resolveSession()`.\n *\n * Revocation: `revokeSession()` removes the entry from the Map. Because the\n * key is non-extractable, removal is sufficient — no one holds a serializable\n * copy of the key.\n *\n * Tab-scoped lifetime: the module-level Map lives only as long as the JS\n * module. Tab close → module unloaded → Map GC'd → all session keys gone.\n * This is the zero-effort logout: closing the tab is always a secure logout.\n *\n * Expiry: `createSession()` accepts a `ttlMs` option. `resolveSession()`\n * checks `expiresAt` and throws `SessionExpiredError` if the token is stale,\n * even if the session key is still in the Map.\n */\n\nimport { bufferToBase64, base64ToBuffer, type EnclaveKey } from '../../kernel/enclave/index.js'\nimport { generateULID } from '../../with-pod/ulid.js'\nimport type { Role } from '../../kernel/types.js'\nimport type { UnlockedKeyring } from '../team/keyring.js'\nimport { SessionExpiredError, SessionNotFoundError } from '../../kernel/errors.js'\n\nconst subtle = globalThis.crypto.subtle\n\n// Default session TTL: 60 minutes\nconst DEFAULT_TTL_MS = 60 * 60 * 1000\n\n// Module-level session key store. Tab-scoped by construction.\nconst sessionKeyStore = new Map<string, CryptoKey>()\n\n// ─── Public types ──────────────────────────────────────────────────────\n\n/** The serializable part of a session token. Safe to store in sessionStorage. */\nexport interface SessionToken {\n readonly _noydb_session: 1\n /** Unique session identifier (ULID). Use this as the handle for resolve/revoke. */\n readonly sessionId: string\n readonly userId: string\n readonly vault: string\n readonly role: Role\n /** ISO timestamp — resolveSession() rejects this token after this time. */\n readonly expiresAt: string\n /** KEK wrapped with the session key (AES-256-GCM). Base64. */\n readonly wrappedKek: string\n /** IV used for the wrapping operation. Base64. */\n readonly kekIv: string\n}\n\n/** Result returned from `createSession()`. */\nexport interface CreateSessionResult {\n /** Serializable token — store in sessionStorage or pass to `resolveSession()`. */\n token: SessionToken\n /** The sessionId — use this handle for `resolveSession()` and `revokeSession()`. */\n sessionId: string\n}\n\n/** Options for `createSession()`. */\nexport interface CreateSessionOptions {\n /**\n * Session lifetime in milliseconds. Defaults to 60 minutes.\n * After this duration, `resolveSession()` throws `SessionExpiredError`.\n */\n ttlMs?: number\n}\n\n// ─── Core session operations ───────────────────────────────────────────\n\n/**\n * Create a session for an already-unlocked keyring.\n *\n * Call this after any successful unlock (secret, WebAuthn, OIDC,\n * magic-link). The returned `sessionId` is the handle for later\n * `resolveSession()` and `revokeSession()` calls.\n *\n * The session key is generated fresh (non-extractable) and stored in the\n * module-level Map. The KEK from `keyring.kek` is exported (it must be\n * extractable — it was derived by `deriveKey()` which sets extractable: false,\n * but it's unwrapped from the keyring which sets extractable: true) and then\n * re-wrapped with the session key.\n *\n * @param keyring - An already-unlocked keyring whose `kek` is available.\n * @param vault - The vault name this session is scoped to.\n * @param options - Optional session configuration.\n */\nexport async function createSession(\n keyring: UnlockedKeyring,\n vault: string,\n options: CreateSessionOptions = {},\n): Promise<CreateSessionResult> {\n const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS\n const sessionId = generateULID()\n const expiresAt = new Date(Date.now() + ttlMs).toISOString()\n\n // Generate a fresh non-extractable session key.\n // AES-256-GCM is used here (rather than AES-KW) because the session key\n // wraps raw key bytes (the exported KEK) rather than a CryptoKey object.\n const sessionKey = await subtle.generateKey(\n { name: 'AES-GCM', length: 256 },\n false, // non-extractable — this is the tab-scope security invariant\n ['encrypt', 'decrypt'],\n )\n\n // Export the KEK as raw bytes so we can wrap it.\n // The KEK is AES-256-KW, which must have been importable (extractable: true)\n // to allow wrapKey — it is, because unwrapKey sets extractable: true for\n // DEKs, but the KEK itself is derived with extractable: false (see\n // crypto.ts deriveKey). We use a separate raw export + encrypt path.\n //\n // Wait — the KEK is AES-KW with extractable:false. We cannot export it.\n // Instead, we wrap the DEKs (which ARE extractable) and the salt+role+userId\n // metadata together. This means resolveSession() reconstructs an\n // UnlockedKeyring by re-wrapping the DEKs list from the token.\n //\n // Simpler approach: export each DEK (they're extractable) and encrypt\n // the serialized DEK map with the session key. The keyring is reconstructed\n // from the session token without the original KEK — only DEKs matter for\n // record operations.\n //\n // This is the right design: sessions don't need the KEK (no re-grant,\n // no re-derive during session lifetime). They need the DEK set.\n\n const dekMap: Record<string, string> = {}\n for (const [collName, dek] of keyring.deks) {\n const raw = await subtle.exportKey('raw', dek)\n dekMap[collName] = bufferToBase64(raw)\n }\n\n const payload = JSON.stringify({\n userId: keyring.userId,\n displayName: keyring.displayName,\n role: keyring.role,\n permissions: keyring.permissions,\n deks: dekMap,\n salt: bufferToBase64(keyring.salt),\n })\n\n const iv = globalThis.crypto.getRandomValues(new Uint8Array(12))\n const encrypted = await subtle.encrypt(\n { name: 'AES-GCM', iv },\n sessionKey,\n new TextEncoder().encode(payload),\n )\n\n const token: SessionToken = {\n _noydb_session: 1,\n sessionId,\n userId: keyring.userId,\n vault,\n role: keyring.role,\n expiresAt,\n wrappedKek: bufferToBase64(encrypted),\n kekIv: bufferToBase64(iv),\n }\n\n sessionKeyStore.set(sessionId, sessionKey)\n return { token, sessionId }\n}\n\n/**\n * Resolve a session token back into an UnlockedKeyring.\n *\n * Looks up the session key by `sessionId`, checks the token is not expired,\n * then decrypts the payload to reconstruct the keyring's DEK set.\n *\n * Throws `SessionExpiredError` if the token's `expiresAt` is in the past.\n * Throws `SessionNotFoundError` if the session key is not in the store\n * (tab was reloaded, session was revoked, or the sessionId is wrong).\n *\n * @param token - The SessionToken from `createSession()`.\n */\nexport async function resolveSession(token: SessionToken): Promise<UnlockedKeyring> {\n // Expiry check first — fast path without touching crypto\n if (Date.now() > new Date(token.expiresAt).getTime()) {\n sessionKeyStore.delete(token.sessionId)\n throw new SessionExpiredError(token.sessionId)\n }\n\n const sessionKey = sessionKeyStore.get(token.sessionId)\n if (!sessionKey) {\n throw new SessionNotFoundError(token.sessionId)\n }\n\n const iv = base64ToBuffer(token.kekIv)\n const ciphertext = base64ToBuffer(token.wrappedKek)\n\n let plaintext: ArrayBuffer\n try {\n plaintext = await subtle.decrypt(\n { name: 'AES-GCM', iv },\n sessionKey,\n ciphertext,\n )\n } catch {\n throw new SessionNotFoundError(token.sessionId)\n }\n\n const payload = JSON.parse(new TextDecoder().decode(plaintext)) as {\n userId: string\n displayName: string\n role: Role\n permissions: Record<string, 'rw' | 'ro'>\n deks: Record<string, string>\n salt: string\n }\n\n const deks = new Map<string, EnclaveKey>()\n for (const [collName, rawBase64] of Object.entries(payload.deks)) {\n const dek = await subtle.importKey(\n 'raw',\n base64ToBuffer(rawBase64),\n { name: 'AES-GCM', length: 256 },\n true,\n ['encrypt', 'decrypt'],\n )\n deks.set(collName, dek)\n }\n\n return {\n userId: payload.userId,\n displayName: payload.displayName,\n role: payload.role,\n permissions: payload.permissions,\n deks,\n kek: null, // KEK not available in session context\n salt: base64ToBuffer(payload.salt),\n authenticators: [],\n }\n}\n\n/**\n * Revoke a session by removing its key from the store.\n *\n * After revocation, `resolveSession()` will throw `SessionNotFoundError`\n * for this sessionId. The session token (if held by the caller) becomes\n * permanently useless. This is the explicit logout path.\n *\n * No-op if the session was already expired or does not exist.\n */\nexport function revokeSession(sessionId: string): void {\n sessionKeyStore.delete(sessionId)\n}\n\n/**\n * Check if a session is still alive (key in store + not expired).\n * Does not decrypt anything — purely a metadata check.\n */\nexport function isSessionAlive(token: SessionToken): boolean {\n if (Date.now() > new Date(token.expiresAt).getTime()) return false\n return sessionKeyStore.has(token.sessionId)\n}\n\n/**\n * Revoke all active sessions. Used by `Noydb.close()` to ensure that\n * closing the instance destroys all session state, not just the keyring\n * cache.\n */\nexport function revokeAllSessions(): void {\n sessionKeyStore.clear()\n}\n\n/**\n * Return the number of active sessions currently in the store.\n * Useful for diagnostics and tests.\n */\nexport function activeSessionCount(): number {\n return sessionKeyStore.size\n}\n","/**\n * Session policies —\n *\n * A `SessionPolicy` is a small declarative object that controls how long a\n * session lives and which operations require re-authentication. It is\n * evaluated by the `PolicyEnforcer` class, which the Noydb instance\n * integrates to replace the bare `sessionTimeout` timer from.\n *\n * Design decisions\n * ────────────────\n * Policies are stateless value objects — no timers, no event listeners.\n * The Noydb instance is the stateful coordinator: it holds the enforcer,\n * calls `enforcer.touch()` on every operation, and calls\n * `enforcer.checkOperation()` before high-risk operations.\n *\n * This keeps the policy module easy to unit-test (no global timers to mock)\n * and avoids the \"who owns cleanup\" problem that comes with timer-based\n * callbacks embedded in a value object.\n *\n * `lockOnBackground` registers a `visibilitychange` listener on the document\n * at enforcer creation time and removes it on `destroy()`. It is a no-op in\n * non-browser environments (no `document`).\n */\n\nimport type { SessionPolicy, ReAuthOperation } from '../../kernel/types.js'\nimport { SessionExpiredError, SessionPolicyError } from '../../kernel/errors.js'\nimport { revokeSession } from './session.js'\n\n// ─── PolicyEnforcer ────────────────────────────────────────────────────\n\nexport interface PolicyEnforcerOptions {\n /** The policy to enforce. */\n policy: SessionPolicy\n /** The session ID to revoke when idle/absolute timeouts fire. */\n sessionId: string\n /**\n * Called when the policy decides the session should end (idle timeout,\n * absolute timeout, or lockOnBackground). Use this to trigger the\n * same cleanup that `Noydb.close()` would perform.\n */\n onRevoke: (reason: 'idle' | 'absolute' | 'background') => void\n}\n\n/**\n * Stateful enforcer for a single session policy.\n *\n * Create one per open session, call `touch()` on every operation,\n * call `checkOperation(op)` before export/grant/revoke/rotate/changeSecret,\n * and call `destroy()` when the session ends.\n */\nexport class PolicyEnforcer {\n private readonly policy: SessionPolicy\n private readonly sessionId: string\n private readonly onRevoke: PolicyEnforcerOptions['onRevoke']\n private readonly createdAt: number\n private lastActivityAt: number\n private idleTimer: ReturnType<typeof setTimeout> | null = null\n private absoluteTimer: ReturnType<typeof setTimeout> | null = null\n private visibilityHandler: (() => void) | null = null\n\n constructor(opts: PolicyEnforcerOptions) {\n this.policy = opts.policy\n this.sessionId = opts.sessionId\n this.onRevoke = opts.onRevoke\n this.createdAt = Date.now()\n this.lastActivityAt = Date.now()\n\n this.scheduleIdleTimer()\n this.scheduleAbsoluteTimer()\n this.registerBackgroundLock()\n }\n\n /**\n * Record an activity timestamp and reset the idle timer.\n * Call this at the top of every Noydb public method.\n */\n touch(): void {\n this.lastActivityAt = Date.now()\n this.scheduleIdleTimer()\n }\n\n /**\n * Check whether the given operation is allowed under the active policy.\n * Throws `SessionPolicyError` if the operation requires re-authentication.\n * Throws `SessionExpiredError` if the absolute timeout has been exceeded\n * (defensive check in case the timer fired before the call arrived).\n *\n * This is a synchronous check — callers don't await it.\n */\n checkOperation(op: ReAuthOperation): void {\n // Defensive absolute-timeout check (timer may have fired late)\n const { absoluteTimeoutMs } = this.policy\n if (absoluteTimeoutMs !== undefined && Date.now() - this.createdAt >= absoluteTimeoutMs) {\n this.expire('absolute')\n throw new SessionExpiredError(this.sessionId)\n }\n\n const required = this.policy.requireReAuthFor ?? []\n if (required.includes(op)) {\n throw new SessionPolicyError(op)\n }\n }\n\n /**\n * Tear down timers and background-lock listener. Call from `Noydb.close()`\n * and whenever the session is revoked externally.\n */\n destroy(): void {\n if (this.idleTimer) {\n clearTimeout(this.idleTimer)\n this.idleTimer = null\n }\n if (this.absoluteTimer) {\n clearTimeout(this.absoluteTimer)\n this.absoluteTimer = null\n }\n if (this.visibilityHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.visibilityHandler)\n this.visibilityHandler = null\n }\n }\n\n /** How long since the last activity, in ms. */\n get idleMs(): number {\n return Date.now() - this.lastActivityAt\n }\n\n /** How long since session creation, in ms. */\n get ageMs(): number {\n return Date.now() - this.createdAt\n }\n\n // ── Private ──────────────────────────────────────────────────────────\n\n private scheduleIdleTimer(): void {\n const { idleTimeoutMs } = this.policy\n if (!idleTimeoutMs) return\n\n if (this.idleTimer) clearTimeout(this.idleTimer)\n this.idleTimer = setTimeout(() => {\n this.expire('idle')\n }, idleTimeoutMs)\n }\n\n private scheduleAbsoluteTimer(): void {\n const { absoluteTimeoutMs } = this.policy\n if (!absoluteTimeoutMs) return\n\n if (this.absoluteTimer) clearTimeout(this.absoluteTimer)\n this.absoluteTimer = setTimeout(() => {\n this.expire('absolute')\n }, absoluteTimeoutMs)\n }\n\n private registerBackgroundLock(): void {\n if (!this.policy.lockOnBackground) return\n if (typeof document === 'undefined') return\n\n this.visibilityHandler = () => {\n if (document.hidden) {\n this.expire('background')\n }\n }\n document.addEventListener('visibilitychange', this.visibilityHandler)\n }\n\n private expire(reason: 'idle' | 'absolute' | 'background'): void {\n this.destroy()\n revokeSession(this.sessionId)\n this.onRevoke(reason)\n }\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────\n\n/**\n * Build a `PolicyEnforcer` from a policy + session token, and return it\n * alongside a cleanup function. Convenience wrapper for Noydb.\n */\nexport function createEnforcer(opts: PolicyEnforcerOptions): PolicyEnforcer {\n return new PolicyEnforcer(opts)\n}\n\n/**\n * Validate that a `SessionPolicy` is well-formed.\n * Throws a plain `Error` (not `NoydbError`) because this is a developer\n * error — invalid policies passed at construction time, not at runtime.\n */\nexport function validateSessionPolicy(policy: SessionPolicy): void {\n const { idleTimeoutMs, absoluteTimeoutMs } = policy\n if (idleTimeoutMs !== undefined && (typeof idleTimeoutMs !== 'number' || idleTimeoutMs <= 0)) {\n throw new Error(`SessionPolicy.idleTimeoutMs must be a positive number, got ${idleTimeoutMs}`)\n }\n if (absoluteTimeoutMs !== undefined && (typeof absoluteTimeoutMs !== 'number' || absoluteTimeoutMs <= 0)) {\n throw new Error(`SessionPolicy.absoluteTimeoutMs must be a positive number, got ${absoluteTimeoutMs}`)\n }\n if (idleTimeoutMs !== undefined && absoluteTimeoutMs !== undefined && idleTimeoutMs >= absoluteTimeoutMs) {\n throw new Error(\n `SessionPolicy.idleTimeoutMs (${idleTimeoutMs}ms) must be less than absoluteTimeoutMs (${absoluteTimeoutMs}ms)`,\n )\n }\n}\n","/**\n * Dev-mode persistent unlock —\n *\n * Solves the developer inner-loop friction: hot-reload destroys the session\n * (page navigation semantics), forcing a secret re-entry every refresh.\n *\n * This module provides an opt-in, deliberately-named escape hatch that lets\n * developers store the keyring payload in sessionStorage or localStorage so\n * the vault auto-unlocks on every page load — without a secret,\n * without a biometric prompt, without any OIDC flow.\n *\n * ⚠️ WARNING — this is a loaded footgun ⚠️\n * ─────────────────────────────────────────\n * The keyring payload stored by this module contains the DEKs. Whoever has\n * access to sessionStorage/localStorage has access to the DEKs. On a shared\n * development machine, a compromised browser extension, or a mis-configured\n * origin, this is a complete key exposure.\n *\n * This module is ONLY safe for local development. It must NEVER be active\n * in production builds.\n *\n * Guardrails (all enforced by the module, not by the caller)\n * ──────────────────────────────────────────────────────────\n * 1. **Production guard:** `enableDevUnlock()` throws immediately if\n * `process.env.NODE_ENV === 'production'` or if `import.meta.env?.PROD === true`\n * (Vite convention). Also throws if the hostname is NOT localhost or 127.0.0.1.\n *\n * 2. **Explicit acknowledgement string:** the caller must pass\n * `acknowledge: 'I-UNDERSTAND-THIS-DISABLES-UNLOCK-SECURITY'` or the call\n * throws. This string appears in every grep for `devUnlock` in the codebase,\n * making it impossible to enable this feature accidentally.\n *\n * 3. **Scope is vault + userId:** the storage key includes both the\n * vault name and the userId, so dev-unlock for vault-A does\n * NOT auto-unlock vault-B.\n *\n * 4. **Storage scope:** default is `sessionStorage` (cleared on tab close).\n * `localStorage` is opt-in and requires an additional\n * `persistAcrossTabs: true` flag in the options.\n *\n * 5. **Clear method:** `clearDevUnlock()` removes the stored payload. Wire\n * this to a dev toolbar button or `Ctrl+Shift+L` so clearing is one action.\n *\n * 6. **Console banner:** on first enable, a highly visible console warning\n * fires. Cannot be suppressed.\n *\n * Usage\n * ─────\n * ```ts\n * // In your dev entry point only (guarded by import.meta.env.DEV):\n * if (import.meta.env.DEV) {\n * const { enableDevUnlock, loadDevUnlock } = await import('@noy-db/hub')\n * enableDevUnlock('my-compartment', 'alice', keyring, {\n * acknowledge: 'I-UNDERSTAND-THIS-DISABLES-UNLOCK-SECURITY',\n * })\n * }\n *\n * // On page load:\n * if (import.meta.env.DEV) {\n * const keyring = await loadDevUnlock('my-compartment', 'alice')\n * if (keyring) {\n * // Skip unlock prompt, use keyring directly\n * }\n * }\n * ```\n */\n\nimport { bufferToBase64, base64ToBuffer, type EnclaveKey } from '../../kernel/enclave/index.js'\nimport { ValidationError } from '../../kernel/errors.js'\nimport type { UnlockedKeyring } from '../team/keyring.js'\nimport type { Role } from '../../kernel/types.js'\n\n// The exact acknowledgement string callers must pass\nconst REQUIRED_ACKNOWLEDGE = 'I-UNDERSTAND-THIS-DISABLES-UNLOCK-SECURITY'\n\nconst STORAGE_PREFIX = 'noydb:dev-unlock:'\n\n// ─── Options ──────────────────────────────────────────────────────────\n\nexport interface DevUnlockOptions {\n /**\n * Required: the exact string 'I-UNDERSTAND-THIS-DISABLES-UNLOCK-SECURITY'.\n * Any other value causes `enableDevUnlock()` to throw.\n */\n acknowledge: string\n /**\n * If `true`, stores in localStorage (persists across tabs and browser restarts).\n * If `false` (default), stores in sessionStorage (cleared on tab close).\n */\n persistAcrossTabs?: boolean\n}\n\n// ─── Production guard ─────────────────────────────────────────────────\n\nfunction assertDevEnvironment(): void {\n // Node.js: check NODE_ENV\n if (\n typeof process !== 'undefined' &&\n process.env.NODE_ENV === 'production'\n ) {\n throw new ValidationError(\n 'devUnlock is not available in production builds. ' +\n 'process.env.NODE_ENV is \"production\".',\n )\n }\n\n // Vite / build tool convention\n if (\n typeof globalThis !== 'undefined' &&\n (globalThis as Record<string, unknown>).__vite_is_production__ === true\n ) {\n throw new ValidationError('devUnlock is not available in production builds.')\n }\n\n // Browser: only allow on localhost\n if (\n typeof window !== 'undefined' &&\n typeof window.location !== 'undefined'\n ) {\n const host = window.location.hostname\n if (host !== 'localhost' && host !== '127.0.0.1' && host !== '::1' && !host.endsWith('.local')) {\n throw new ValidationError(\n `devUnlock is only available on localhost. Current hostname: \"${host}\". ` +\n 'Set NODE_ENV=development and run on localhost to use dev unlock.',\n )\n }\n }\n}\n\n// ─── Storage key ──────────────────────────────────────────────────────\n\nfunction storageKey(vault: string, userId: string): string {\n return `${STORAGE_PREFIX}${vault}:${userId}`\n}\n\nfunction resolveStorage(persistAcrossTabs?: boolean): Storage {\n if (typeof window === 'undefined') {\n throw new ValidationError('devUnlock requires a browser environment (window.sessionStorage / window.localStorage).')\n }\n return persistAcrossTabs ? window.localStorage : window.sessionStorage\n}\n\n// ─── Public API ────────────────────────────────────────────────────────\n\n/**\n * Serialize and store a keyring to browser storage for dev-mode auto-unlock.\n *\n * Throws immediately if:\n * - The acknowledge string is wrong.\n * - Running in a production environment (NODE_ENV=production).\n * - Running on a non-localhost hostname.\n *\n * Emits a highly visible console warning that cannot be suppressed.\n *\n * @param vault - The vault name.\n * @param userId - The user ID.\n * @param keyring - The unlocked keyring to persist.\n * @param options - Options including the required acknowledge string.\n */\nexport async function enableDevUnlock(\n vault: string,\n userId: string,\n keyring: UnlockedKeyring,\n options: DevUnlockOptions,\n): Promise<void> {\n if (options.acknowledge !== REQUIRED_ACKNOWLEDGE) {\n throw new ValidationError(\n `devUnlock requires acknowledge: '${REQUIRED_ACKNOWLEDGE}'. ` +\n `Got: '${options.acknowledge}'. This is intentional — the full string must appear in your source.`,\n )\n }\n\n assertDevEnvironment()\n\n const storage = resolveStorage(options.persistAcrossTabs)\n\n const dekMap: Record<string, string> = {}\n for (const [collName, dek] of keyring.deks) {\n const raw = await globalThis.crypto.subtle.exportKey('raw', dek)\n dekMap[collName] = bufferToBase64(raw)\n }\n\n const payload = JSON.stringify({\n _noydb_dev_unlock: 1,\n userId: keyring.userId,\n displayName: keyring.displayName,\n role: keyring.role,\n permissions: keyring.permissions,\n deks: dekMap,\n salt: bufferToBase64(keyring.salt),\n })\n\n storage.setItem(storageKey(vault, userId), payload)\n\n // Visible, unsuppressable warning\n console.warn(\n '%c⚠️ NOYDB DEV UNLOCK ACTIVE ⚠️',\n 'color: red; font-size: 16px; font-weight: bold',\n `\\n\\nVault \"${vault}\" user \"${userId}\" is stored in ` +\n `${options.persistAcrossTabs ? 'localStorage' : 'sessionStorage'} in PLAINTEXT DEKs.\\n` +\n 'This is ONLY safe for local development. Never use in production.\\n' +\n 'Call clearDevUnlock() to remove.',\n )\n}\n\n/**\n * Load a dev-mode keyring from browser storage.\n *\n * Returns `null` if no dev-unlock state is stored for this vault + user,\n * or if the stored payload is malformed.\n *\n * Does NOT perform the production environment check — it's safe to CALL\n * `loadDevUnlock` in production (it will simply return `null` because no\n * dev-unlock state was ever written). The guard only fires on `enableDevUnlock`.\n *\n * @param vault - The vault name.\n * @param userId - The user ID.\n * @param options - Optional storage override.\n */\nexport async function loadDevUnlock(\n vault: string,\n userId: string,\n options: { persistAcrossTabs?: boolean } = {},\n): Promise<UnlockedKeyring | null> {\n if (typeof window === 'undefined') return null\n\n const storage = resolveStorage(options.persistAcrossTabs)\n const raw = storage.getItem(storageKey(vault, userId))\n if (!raw) return null\n\n let parsed: {\n _noydb_dev_unlock?: number\n userId: string\n displayName: string\n role: Role\n permissions: Record<string, 'rw' | 'ro'>\n deks: Record<string, string>\n salt: string\n }\n try {\n parsed = JSON.parse(raw)\n } catch {\n return null\n }\n\n if (parsed._noydb_dev_unlock !== 1) return null\n\n const deks = new Map<string, EnclaveKey>()\n for (const [collName, rawBase64] of Object.entries(parsed.deks)) {\n const dek = await globalThis.crypto.subtle.importKey(\n 'raw',\n base64ToBuffer(rawBase64),\n { name: 'AES-GCM', length: 256 },\n true,\n ['encrypt', 'decrypt'],\n )\n deks.set(collName, dek)\n }\n\n return {\n userId: parsed.userId,\n displayName: parsed.displayName,\n role: parsed.role,\n permissions: parsed.permissions,\n deks,\n kek: null,\n salt: base64ToBuffer(parsed.salt),\n authenticators: [],\n }\n}\n\n/**\n * Remove dev-unlock state from browser storage.\n *\n * Safe to call in production (no-op if no dev state exists).\n */\nexport function clearDevUnlock(\n vault: string,\n userId: string,\n options: { persistAcrossTabs?: boolean } = {},\n): void {\n if (typeof window === 'undefined') return\n const storage = resolveStorage(options.persistAcrossTabs)\n storage.removeItem(storageKey(vault, userId))\n}\n\n/**\n * Check if dev-unlock state exists for this vault + user.\n *\n * Safe to call in production (returns false if nothing is stored).\n */\nexport function isDevUnlockActive(\n vault: string,\n userId: string,\n options: { persistAcrossTabs?: boolean } = {},\n): boolean {\n if (typeof window === 'undefined') return false\n const storage = resolveStorage(options.persistAcrossTabs)\n return storage.getItem(storageKey(vault, userId)) !== null\n}\n"],"mappings":"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","names":[]}
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  envelopePayloadHash
3
- } from "./chunk-JLHKBAFY.js";
3
+ } from "./chunk-2BVW754E.js";
4
4
  import {
5
5
  NOYDB_FORMAT_VERSION
6
- } from "./chunk-5BHNQNBI.js";
6
+ } from "./chunk-DOZFU7OZ.js";
7
7
  import {
8
8
  DictKeyMissingError,
9
9
  PermissionDeniedError
10
- } from "./chunk-IGM563N5.js";
10
+ } from "./chunk-6SYOHUHM.js";
11
11
 
12
12
  // src/via/lookup/handle.ts
13
13
  function isDeleteMarker(envelope) {
@@ -389,4 +389,4 @@ export {
389
389
  dictCollectionName,
390
390
  LookupHandle
391
391
  };
392
- //# sourceMappingURL=chunk-BZEPJJOK.js.map
392
+ //# sourceMappingURL=chunk-C2V7AJO2.js.map
@@ -0,0 +1,151 @@
1
+ import {
2
+ readPath
3
+ } from "./chunk-IGJCYUT5.js";
4
+
5
+ // src/with-lookup/reduce/reducers.ts
6
+ function count(opts) {
7
+ const _seed = opts?.seed;
8
+ void _seed;
9
+ return {
10
+ op: "count",
11
+ init: () => 0,
12
+ step: (state) => state + 1,
13
+ remove: (state) => state - 1,
14
+ finalize: (state) => state,
15
+ merge: (a, b) => a + b
16
+ };
17
+ }
18
+ function sum(field, opts) {
19
+ const _seed = opts?.seed;
20
+ void _seed;
21
+ return {
22
+ op: "sum",
23
+ field,
24
+ // Money-only metadata, read by `wrapMoneyReducers`. No effect on a
25
+ // generic numeric sum.
26
+ ...opts?.convertTo !== void 0 ? { convertTo: opts.convertTo } : {},
27
+ ...opts?.fx !== void 0 ? { fx: opts.fx } : {},
28
+ init: () => 0,
29
+ step: (state, record) => state + readNumber(record, field),
30
+ remove: (state, record) => state - readNumber(record, field),
31
+ finalize: (state) => state,
32
+ merge: (a, b) => a + b
33
+ };
34
+ }
35
+ function avg(field, opts) {
36
+ const _seed = opts?.seed;
37
+ void _seed;
38
+ return {
39
+ op: "avg",
40
+ field,
41
+ init: () => ({ sum: 0, count: 0 }),
42
+ step: (state, record) => ({
43
+ sum: state.sum + readNumber(record, field),
44
+ count: state.count + 1
45
+ }),
46
+ remove: (state, record) => ({
47
+ sum: state.sum - readNumber(record, field),
48
+ count: state.count - 1
49
+ }),
50
+ finalize: (state) => state.count === 0 ? null : state.sum / state.count,
51
+ merge: (a, b) => ({ sum: a.sum + b.sum, count: a.count + b.count })
52
+ };
53
+ }
54
+ function pushValue(state, value) {
55
+ return { values: [...state.values, value] };
56
+ }
57
+ function removeValue(state, value) {
58
+ const idx = state.values.indexOf(value);
59
+ if (idx < 0) return state;
60
+ const next = state.values.slice();
61
+ next.splice(idx, 1);
62
+ return { values: next };
63
+ }
64
+ function min(field, opts) {
65
+ const _seed = opts?.seed;
66
+ void _seed;
67
+ return {
68
+ op: "min",
69
+ field,
70
+ init: () => ({ values: [] }),
71
+ step: (state, record) => pushValue(state, readNumber(record, field)),
72
+ remove: (state, record) => removeValue(state, readNumber(record, field)),
73
+ finalize: (state) => {
74
+ if (state.values.length === 0) return null;
75
+ let out = state.values[0];
76
+ for (let i = 1; i < state.values.length; i++) {
77
+ const v = state.values[i];
78
+ if (v < out) out = v;
79
+ }
80
+ return out;
81
+ },
82
+ merge: (a, b) => ({ values: [...a.values, ...b.values] })
83
+ };
84
+ }
85
+ function max(field, opts) {
86
+ const _seed = opts?.seed;
87
+ void _seed;
88
+ return {
89
+ op: "max",
90
+ field,
91
+ init: () => ({ values: [] }),
92
+ step: (state, record) => pushValue(state, readNumber(record, field)),
93
+ remove: (state, record) => removeValue(state, readNumber(record, field)),
94
+ finalize: (state) => {
95
+ if (state.values.length === 0) return null;
96
+ let out = state.values[0];
97
+ for (let i = 1; i < state.values.length; i++) {
98
+ const v = state.values[i];
99
+ if (v > out) out = v;
100
+ }
101
+ return out;
102
+ },
103
+ merge: (a, b) => ({ values: [...a.values, ...b.values] })
104
+ };
105
+ }
106
+ function moneySum(field, opts) {
107
+ return sum(field, opts);
108
+ }
109
+ function moneyMin(field, opts) {
110
+ return min(field, opts);
111
+ }
112
+ function moneyMax(field, opts) {
113
+ return max(field, opts);
114
+ }
115
+ var reducerBuilder = {
116
+ count,
117
+ // The generic F parameter on sum/min/max in the interface is type-only; the
118
+ // standalone factories are plain `(field: string)` functions. With M=never the
119
+ // conditional return collapses to the numeric branch, matching the factories'
120
+ // return type, but TypeScript cannot verify that collapse for a generic method
121
+ // signature — so each factory is cast directly to the method's type.
122
+ sum,
123
+ avg,
124
+ min,
125
+ max,
126
+ moneySum,
127
+ moneyMin,
128
+ moneyMax
129
+ };
130
+ function readNumber(record, field) {
131
+ const value = readPath(record, field);
132
+ if (typeof value === "object" && value !== null && "amount" in value && "currency" in value) {
133
+ throw new Error(
134
+ `aggregate: field "${field}" holds a money value but was not money-aware \u2014 declare it in the collection's moneyFields so sum/min/max stay exact`
135
+ );
136
+ }
137
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
138
+ }
139
+
140
+ export {
141
+ count,
142
+ sum,
143
+ avg,
144
+ min,
145
+ max,
146
+ moneySum,
147
+ moneyMin,
148
+ moneyMax,
149
+ reducerBuilder
150
+ };
151
+ //# sourceMappingURL=chunk-CADUYBQD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-lookup/reduce/reducers.ts"],"sourcesContent":["/**\n * Reduction reducers for the query DSL.\n *\n * the reducer protocol plus five built-in factories\n * (`count`, `sum`, `avg`, `min`, `max`) consumed by `Query.aggregate()`\n * and, in the future, `Scan.aggregate()`. Every factory accepts\n * an optional `{ seed }` parameter that is plumbed through the\n * protocol but unused by the executor — that's the load-bearing\n * half of constraint #2. When partition-aware reduction\n * lands, the seed carries the previous partition's running total into\n * the next partition without requiring a protocol change.\n *\n * Reducers are intentionally generic over their internal state type\n * `S` so compound reducers (avg keeps `{sum, count}`, min/max keep a\n * value bag) can model internal bookkeeping without leaking the\n * implementation through the accumulator's public shape. `finalize`\n * collapses `S` back into the user-visible `R`.\n *\n * Reducers are pure data — `init` / `step` / `finalize` / optional\n * `remove` are stateless functions that receive and return `S`. This\n * is the shape that admits O(1) incremental maintenance in a future\n * optimization (delta-aware `LiveReduction` applies `step` or\n * `remove` per delta), without blocking the simpler \"full re-run on\n * source change\" that ships.\n */\n\nimport { readPath } from '../../kernel/query/predicate.js'\nimport type { MoneyString } from '../../via/money/branded.js'\nimport type { QueryField } from '../../kernel/types.js'\n\n/**\n * A single reducer: factory-produced, ready to plug into an\n * `.aggregate()` spec.\n *\n * Type parameters:\n * - `R` — user-visible result type (what the reduction returns\n * for this slot, e.g. `number` for `sum()`)\n * - `S` — internal state type, defaults to `R` for simple reducers\n * that don't need compound bookkeeping\n *\n * A reducer is stateless: every method is pure over `S`. `init()` is\n * called once per reduction run to build the initial state; `step()`\n * folds a record into the state; `remove()` (optional) un-folds a\n * record, enabling incremental live maintenance; `finalize()` reads\n * the final answer out of the state at the end of the run.\n */\nexport interface Reducer<R, S = R> {\n /** Build the initial state for a fresh reduction run. */\n init(): S\n /** Fold a record into the state. Returns the new state. */\n step(state: S, record: unknown): S\n /**\n * Un-fold a record from the state. Returns the new state.\n *\n * Optional — reducers without `remove` cannot be maintained\n * incrementally and must be re-run from scratch when the underlying\n * record set changes. `sum`, `count`, `avg` implement `remove` in\n * O(1); `min` and `max` implement it in O(N) worst case (when the\n * extremum itself is removed and the next extremum must be\n * recomputed from the remaining contributing values).\n */\n remove?(state: S, record: unknown): S\n /** Collapse the internal state into the user-visible result. */\n finalize(state: S): R\n /**\n * Combine two independent partial states into one (then `finalize` once).\n * Optional. MUST be associative + commutative with `init()` as identity.\n * Never merge finalized results — only states. Enables parallel /\n * hierarchical reduction (e.g. cross-shard or advisor→firm rollup).\n */\n merge?(a: S, b: S): S\n /**\n * Identifying operation tag stamped by each built-in factory.\n * Used by `summariseAggregateOp` in the introspection walker to\n * render human-readable aggregate descriptors in `dumpSchema()`.\n * Optional so third-party custom reducers are unaffected.\n */\n readonly op?: 'count' | 'sum' | 'avg' | 'min' | 'max'\n /**\n * Field name for field-based reducers (`sum`, `avg`, `min`, `max`).\n * Absent on `count` which aggregates over record count, not a field.\n */\n readonly field?: string\n /**\n * Money-only: target currency for `sum` over a multi-currency money\n * field. Consumed by `wrapMoneyReducers` to convert per-currency\n * subtotals to one figure. Ignored for non-money fields.\n */\n readonly convertTo?: string\n /**\n * Money-only: FX rate map (`'USD->EUR' → rate`) used with `convertTo`.\n */\n readonly fx?: Record<string, number | string>\n}\n\n/**\n * Common options accepted by every reducer factory.\n *\n * `seed` — optional initial value for the internal state. **Unused by\n * the executor**, plumbed through the protocol for constraint\n * #2 (partition-aware reduction seam). In, partitioned\n * reductions will pass the previous partition's carry as `seed` so\n * a long time series can be rolled forward one partition at a time\n * without re-reducing closed partitions.\n *\n * always uses `init()` with the factory's zero value, regardless\n * of whether `seed` was passed. Do not remove the parameter — that's\n * the whole point of having it exist now.\n */\nexport interface ReducerOptions<TSeed = unknown> {\n /** constraint #2 — seed is plumbed through but unused in. */\n readonly seed?: TSeed\n /**\n * Money-only (honored by `sum` over a multi-currency money field):\n * convert per-currency subtotals to this currency for a single figure.\n */\n readonly convertTo?: string\n /** Money-only: FX rate map (`'USD->EUR' → rate`) used with `convertTo`. */\n readonly fx?: Record<string, number | string>\n}\n\n// ---------------------------------------------------------------------------\n// Factories\n// ---------------------------------------------------------------------------\n\n/**\n * Count the number of records that match the query. Ignores field\n * values entirely — the count is over the number of records, not over\n * the number of non-null field values in any column.\n */\nexport function count(opts?: ReducerOptions<number>): Reducer<number> {\n // Seed captured on the closure but unused at execution time in\n //. The reference in _seed keeps lint happy.\n const _seed = opts?.seed\n void _seed\n return {\n op: 'count',\n init: () => 0,\n step: (state) => state + 1,\n remove: (state) => state - 1,\n finalize: (state) => state,\n merge: (a, b) => a + b,\n }\n}\n\n/**\n * Sum a numeric field across all matching records. Non-number values\n * at the field path are coerced to 0 — consumers who want a different\n * behavior (throw, skip, treat as NaN) should filter upstream via\n * `.where()` or write a custom reducer.\n *\n * KNOWN LIMITATION (type imprecision): the declared result type is `number`,\n * but when `field` is a **money** field the runtime returns a decimal *string*\n * (e.g. `'0.30'`, or `{ EUR: '0.30' }` in multi-currency mode) — money sums are\n * BigInt-exact in scaled space and never collapse to a float. The `number` type\n * is therefore a lie for money fields; narrow the result yourself at the call\n * site. A precise fix requires threading money-field declarations into the type\n * system (tracked separately).\n */\nexport function sum(\n field: string,\n opts?: ReducerOptions<number>,\n): Reducer<number> {\n const _seed = opts?.seed\n void _seed\n return {\n op: 'sum',\n field,\n // Money-only metadata, read by `wrapMoneyReducers`. No effect on a\n // generic numeric sum.\n ...(opts?.convertTo !== undefined ? { convertTo: opts.convertTo } : {}),\n ...(opts?.fx !== undefined ? { fx: opts.fx } : {}),\n init: () => 0,\n step: (state, record) => state + readNumber(record, field),\n remove: (state, record) => state - readNumber(record, field),\n finalize: (state) => state,\n merge: (a, b) => a + b,\n }\n}\n\n/**\n * Arithmetic mean of a numeric field across all matching records.\n *\n * Returns `null` for an empty result set (zero records is not a\n * well-defined denominator — returning NaN would poison downstream\n * arithmetic, and throwing would force every consumer to wrap in\n * try/catch just to handle \"no matches\"). Consumers who want an\n * explicit zero should coalesce with `?? 0`.\n *\n * Internal state is `{sum, count}` so the running average can be\n * maintained incrementally — on each delta, both fields update in\n * O(1) and `finalize` divides. Directly storing `avg` as state would\n * not admit incremental removal without also tracking count.\n */\nexport function avg(\n field: string,\n opts?: ReducerOptions<{ sum: number; count: number }>,\n): Reducer<number | null, { sum: number; count: number }> {\n const _seed = opts?.seed\n void _seed\n return {\n op: 'avg',\n field,\n init: () => ({ sum: 0, count: 0 }),\n step: (state, record) => ({\n sum: state.sum + readNumber(record, field),\n count: state.count + 1,\n }),\n remove: (state, record) => ({\n sum: state.sum - readNumber(record, field),\n count: state.count - 1,\n }),\n finalize: (state) => (state.count === 0 ? null : state.sum / state.count),\n merge: (a, b) => ({ sum: a.sum + b.sum, count: a.count + b.count }),\n }\n}\n\nexport interface MinMaxState {\n /**\n * Multiset of contributing field values. Stored as a plain array\n * because we need to support `remove` and a plain array gives us\n * O(1) push + O(N) worst-case removal — which matches the\n * documented min/max removal complexity. A sorted structure would\n * let us drop the O(N) rescan but adds complexity that doesn't\n * need; consumers hitting the O(N) ceiling should file an issue.\n */\n readonly values: number[]\n}\n\nfunction pushValue(state: MinMaxState, value: number): MinMaxState {\n return { values: [...state.values, value] }\n}\n\nfunction removeValue(state: MinMaxState, value: number): MinMaxState {\n // Remove the first matching value — duplicates are fine, we only\n // need to drop one instance per `remove()` call so the multiset\n // count stays consistent with the record count.\n const idx = state.values.indexOf(value)\n if (idx < 0) return state\n const next = state.values.slice()\n next.splice(idx, 1)\n return { values: next }\n}\n\n/**\n * Smallest numeric value of a field across all matching records.\n * Returns `null` for an empty result set. See `avg()` for the\n * reasoning on `null` vs NaN vs throwing.\n *\n * Incremental complexity: O(1) for `step`, O(N) worst case for\n * `remove` when the current minimum is removed (the state holds the\n * full multiset of contributing values and `finalize` scans for the\n * new minimum). Consumers with very large result sets and frequent\n * removals of the current extremum should either accept the cost or\n * wait for a future optimization.\n */\nexport function min(\n field: string,\n opts?: ReducerOptions<number>,\n): Reducer<number | null, MinMaxState> {\n const _seed = opts?.seed\n void _seed\n return {\n op: 'min',\n field,\n init: () => ({ values: [] }),\n step: (state, record) => pushValue(state, readNumber(record, field)),\n remove: (state, record) => removeValue(state, readNumber(record, field)),\n finalize: (state) => {\n if (state.values.length === 0) return null\n let out = state.values[0]!\n for (let i = 1; i < state.values.length; i++) {\n const v = state.values[i]!\n if (v < out) out = v\n }\n return out\n },\n merge: (a, b) => ({ values: [...a.values, ...b.values] }),\n }\n}\n\n/**\n * Largest numeric value of a field across all matching records.\n * Mirror of `min()` — see that doc for semantics, null-on-empty\n * behavior, and the O(N) removal caveat.\n */\nexport function max(\n field: string,\n opts?: ReducerOptions<number>,\n): Reducer<number | null, MinMaxState> {\n const _seed = opts?.seed\n void _seed\n return {\n op: 'max',\n field,\n init: () => ({ values: [] }),\n step: (state, record) => pushValue(state, readNumber(record, field)),\n remove: (state, record) => removeValue(state, readNumber(record, field)),\n finalize: (state) => {\n if (state.values.length === 0) return null\n let out = state.values[0]!\n for (let i = 1; i < state.values.length; i++) {\n const v = state.values[i]!\n if (v > out) out = v\n }\n return out\n },\n merge: (a, b) => ({ values: [...a.values, ...b.values] }),\n }\n}\n\n// ---------------------------------------------------------------------------\n// Money-typed reducer constructors\n// ---------------------------------------------------------------------------\n\n/**\n * `sum()` for a **declared money field**, typed to match the runtime.\n *\n * `sum()` returns `Reducer<number>`, but `wrapMoneyReducers` (applied at\n * `query.aggregate()` time, once `moneyFields` is known) rewrites any\n * `sum`/`min`/`max` over a money field to a money reducer that finalizes to a\n * `MoneyString` decimal — so the `number` type is a lie for money fields and\n * consumers need a cast at every read site. `moneySum` is the same reducer with\n * the correct `Reducer<MoneyString>` return type, so no read-site cast is\n * needed. It is the caller's assertion that `field` is a money field; use plain\n * `sum()` for non-money fields. (For a multi-currency money field WITHOUT\n * `convertTo`, the runtime returns a per-currency `Record<string, MoneyString>`\n * rather than a single `MoneyString` — pass `convertTo` to collapse to one\n * currency, or read the map at the boundary.)\n */\nexport function moneySum(field: string, opts?: ReducerOptions<number>): Reducer<MoneyString> {\n // The constructed reducer is the plain numeric `sum`; `wrapMoneyReducers`\n // swaps in the MoneyString-producing money reducer at aggregate() time.\n return sum(field, opts) as unknown as Reducer<MoneyString>\n}\n\n/**\n * `min()` for a declared money field, typed `Reducer<MoneyString | null>`\n * (null on an empty result set in fixed-currency mode, mirroring `min()`). See\n * {@link moneySum} for the late-binding rewrite. Note: `convertTo`/`fx` on\n * `opts` have no effect on min/max (cross-currency min/max is unsupported — use\n * {@link moneySum} for currency conversion). In multi-currency mode the runtime\n * returns a per-currency map and an empty result is `{}` rather than `null`.\n */\nexport function moneyMin(field: string, opts?: ReducerOptions<number>): Reducer<MoneyString | null> {\n return min(field, opts) as unknown as Reducer<MoneyString | null>\n}\n\n/**\n * `max()` for a declared money field, typed `Reducer<MoneyString | null>`\n * (null on an empty result set in fixed-currency mode, mirroring `max()`). See\n * {@link moneyMin} for the `convertTo`/`fx` and multi-currency caveats.\n */\nexport function moneyMax(field: string, opts?: ReducerOptions<number>): Reducer<MoneyString | null> {\n return max(field, opts) as unknown as Reducer<MoneyString | null>\n}\n\n// ---------------------------------------------------------------------------\n// Builder (typed spec-builder for aggregate())\n// ---------------------------------------------------------------------------\n\n/**\n * Typed builder passed to the `aggregate(b => spec)` overload.\n *\n * Each field-taking method narrows `field` to `QueryField<T, S>`, which\n * excludes any field listed in the collection's `sensitive` option at\n * compile time. `count()` carries no field argument and is always allowed.\n *\n * The type parameters match the `Query<T, S>` they come from:\n * - `T` — the record type of the collection\n * - `S` — the union of sensitive field keys (defaults to `never`)\n *\n * ONE shared runtime instance (`reducerBuilder`) serves all `T`/`S`\n * combinations — the field narrowing is type-only; the methods delegate\n * directly to the standalone factories.\n */\nexport interface ReducerBuilder<T, S extends keyof T = never, M extends keyof T & string = never> {\n count(opts?: ReducerOptions<number>): Reducer<number>\n sum<F extends QueryField<T, S>>(field: F, opts?: ReducerOptions<number>): [F] extends [M] ? Reducer<MoneyString> : Reducer<number>\n avg(field: QueryField<T, S>, opts?: ReducerOptions<{ sum: number; count: number }>): ReturnType<typeof avg>\n min<F extends QueryField<T, S>>(field: F, opts?: ReducerOptions<number>): [F] extends [M] ? Reducer<MoneyString | null> : ReturnType<typeof min>\n max<F extends QueryField<T, S>>(field: F, opts?: ReducerOptions<number>): [F] extends [M] ? Reducer<MoneyString | null> : ReturnType<typeof max>\n moneySum(field: QueryField<T, S>, opts?: ReducerOptions<number>): Reducer<MoneyString>\n moneyMin(field: QueryField<T, S>, opts?: ReducerOptions<number>): Reducer<MoneyString | null>\n moneyMax(field: QueryField<T, S>, opts?: ReducerOptions<number>): Reducer<MoneyString | null>\n}\n\n/**\n * Shared runtime instance for the `aggregate(b => spec)` builder form.\n *\n * The field-narrowing to `QueryField<T, S>` is type-only — each method\n * delegates directly to its standalone factory. A `(field: string) => R`\n * factory is assignable to a `(field: QueryField<T,S>) => R` method by\n * parameter-contravariance, so this single instance works for all `T`/`S`.\n */\nexport const reducerBuilder: ReducerBuilder<Record<string, unknown>> = {\n count,\n // The generic F parameter on sum/min/max in the interface is type-only; the\n // standalone factories are plain `(field: string)` functions. With M=never the\n // conditional return collapses to the numeric branch, matching the factories'\n // return type, but TypeScript cannot verify that collapse for a generic method\n // signature — so each factory is cast directly to the method's type.\n sum: sum as ReducerBuilder<Record<string, unknown>>['sum'],\n avg,\n min: min as ReducerBuilder<Record<string, unknown>>['min'],\n max: max as ReducerBuilder<Record<string, unknown>>['max'],\n moneySum, moneyMin, moneyMax,\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Read a numeric field from a record. Non-number values (null,\n * undefined, strings, objects) coerce to 0 so sum/avg/min/max don't\n * produce NaN on one bad row. Consumers who want strict typing should\n * validate upstream with Standard Schema, which NOYDB already runs on\n * every `put()`.\n */\nfunction readNumber(record: unknown, field: string): number {\n const value = readPath(record, field)\n // Defensive: a `{ amount, currency }` value means a multi-currency\n // money field reached a generic numeric reducer instead of being\n // rewritten by `wrapMoneyReducers` — that would silently produce a\n // wrong total. Surface it loudly rather than coercing to 0.\n if (\n typeof value === 'object' &&\n value !== null &&\n 'amount' in value &&\n 'currency' in value\n ) {\n throw new Error(\n `aggregate: field \"${field}\" holds a money value but was not money-aware — ` +\n `declare it in the collection's moneyFields so sum/min/max stay exact`,\n )\n }\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ValidationError
3
- } from "./chunk-IGM563N5.js";
3
+ } from "./chunk-6SYOHUHM.js";
4
4
 
5
5
  // src/with-formula/overlay-views/with-overlayed-view.ts
6
6
  function withOverlayedView(spec) {
@@ -33,4 +33,4 @@ function withOverlayedView(spec) {
33
33
  export {
34
34
  withOverlayedView
35
35
  };
36
- //# sourceMappingURL=chunk-2JZ763FV.js.map
36
+ //# sourceMappingURL=chunk-D4LAJ737.js.map
@@ -29,4 +29,4 @@ export {
29
29
  SealedHandle,
30
30
  createStore
31
31
  };
32
- //# sourceMappingURL=chunk-5BHNQNBI.js.map
32
+ //# sourceMappingURL=chunk-DOZFU7OZ.js.map