@noy-db/hub 0.3.0-pre.3 → 0.3.0-pre.5

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 (388) hide show
  1. package/dist/adapter/index.d.ts +2 -2
  2. package/dist/adapter/index.js +1 -1
  3. package/dist/aggregate/index.d.ts +3 -3
  4. package/dist/aggregate/index.js +4 -4
  5. package/dist/api-JOXUNSKP.js +20 -0
  6. package/dist/as/index.d.ts +4 -4
  7. package/dist/as/index.js +12 -9
  8. package/dist/at/index.d.ts +2 -2
  9. package/dist/attestation/index.d.ts +3 -3
  10. package/dist/attestation/index.js +21 -18
  11. package/dist/attestation/index.js.map +1 -1
  12. package/dist/{backup-NGRJ46SH.js → backup-OPONO6Q5.js} +12 -9
  13. package/dist/{backup-NGRJ46SH.js.map → backup-OPONO6Q5.js.map} +1 -1
  14. package/dist/blobs/index.d.ts +4 -4
  15. package/dist/blobs/index.js +11 -8
  16. package/dist/blobs/index.js.map +1 -1
  17. package/dist/bundle/index.d.ts +5 -5
  18. package/dist/bundle/index.js +21 -18
  19. package/dist/bundle/index.js.map +1 -1
  20. package/dist/{bundle-B-P3_Jvb.d.ts → bundle-Bs13EZtX.d.ts} +1 -1
  21. package/dist/by/index.js +2 -2
  22. package/dist/cargo/index.d.ts +4 -4
  23. package/dist/cargo/index.js +23 -20
  24. package/dist/{chunk-VBYVKOMJ.js → chunk-3QRQOBS7.js} +3 -3
  25. package/dist/{chunk-JFYIHLU3.js → chunk-3Y4QLJ6K.js} +2 -2
  26. package/dist/{chunk-BZIWKN74.js → chunk-43ISXURO.js} +2 -2
  27. package/dist/{chunk-PYWW4KLO.js → chunk-44UTIDE2.js} +9 -9
  28. package/dist/{chunk-7IP75FP2.js → chunk-4K3MQ5S3.js} +2 -2
  29. package/dist/chunk-5EWYUR5P.js +37 -0
  30. package/dist/chunk-5EWYUR5P.js.map +1 -0
  31. package/dist/{chunk-2KSPDSWI.js → chunk-5MRE3C4Q.js} +5 -5
  32. package/dist/{chunk-PUNJAEY6.js → chunk-6HNKCKFZ.js} +7 -7
  33. package/dist/{chunk-PJDK2PPQ.js → chunk-6RXPSMKR.js} +3 -3
  34. package/dist/{chunk-6DP5HBQD.js → chunk-6UOSONVI.js} +9 -9
  35. package/dist/{chunk-YN66UOXT.js → chunk-7SY3PTED.js} +25 -9
  36. package/dist/{chunk-YN66UOXT.js.map → chunk-7SY3PTED.js.map} +1 -1
  37. package/dist/{chunk-UP6EMMDI.js → chunk-A4DWPOP3.js} +10 -10
  38. package/dist/{chunk-MCJAUQGE.js → chunk-A5DYVMDR.js} +3 -3
  39. package/dist/{chunk-MIOLJG2R.js → chunk-AF5ZRTZ4.js} +5 -2
  40. package/dist/chunk-AF5ZRTZ4.js.map +1 -0
  41. package/dist/{chunk-TICO2I2O.js → chunk-BKGIWGCX.js} +2 -2
  42. package/dist/{chunk-O5DNEXQC.js → chunk-BMQOH7MM.js} +2 -2
  43. package/dist/{chunk-3UDPDRUC.js → chunk-EWR7HL3K.js} +4 -4
  44. package/dist/{chunk-CVXLJIAV.js → chunk-FH52CDEW.js} +5 -5
  45. package/dist/chunk-G4MGYGSS.js +130 -0
  46. package/dist/chunk-G4MGYGSS.js.map +1 -0
  47. package/dist/{chunk-FELHYKIO.js → chunk-G7RDYYTE.js} +2 -2
  48. package/dist/{chunk-N2FP26NH.js → chunk-GBTUANXF.js} +16 -297
  49. package/dist/chunk-GBTUANXF.js.map +1 -0
  50. package/dist/{chunk-DHIN36UC.js → chunk-GQOT6QJR.js} +8 -8
  51. package/dist/{chunk-DGUR3CC4.js → chunk-GXGK22QU.js} +2 -2
  52. package/dist/{chunk-YTIAXSUE.js → chunk-GZZL5R73.js} +4 -4
  53. package/dist/{chunk-E4YJUNPU.js → chunk-H5XRIJX3.js} +7 -7
  54. package/dist/{chunk-DA34OEZU.js → chunk-H7RYPVMJ.js} +2 -2
  55. package/dist/{chunk-2ZORB5RW.js → chunk-HBKDR7R3.js} +3 -3
  56. package/dist/{chunk-ZNI3RTFV.js → chunk-HMXLN43G.js} +2 -2
  57. package/dist/{chunk-BYW7EU5L.js → chunk-HY6ZGGEC.js} +2 -2
  58. package/dist/{chunk-ADBMJDBW.js → chunk-IEUIUSBO.js} +449 -1077
  59. package/dist/chunk-IEUIUSBO.js.map +1 -0
  60. package/dist/{chunk-OVIVYAQL.js → chunk-LEA7WJEZ.js} +25 -10
  61. package/dist/chunk-LEA7WJEZ.js.map +1 -0
  62. package/dist/{chunk-5Z3RNFJC.js → chunk-LIP6JWYK.js} +3 -3
  63. package/dist/{chunk-OCDUQUAP.js → chunk-LN22XH4B.js} +1 -1
  64. package/dist/chunk-LN22XH4B.js.map +1 -0
  65. package/dist/chunk-LP7BEXCT.js +32 -0
  66. package/dist/chunk-LP7BEXCT.js.map +1 -0
  67. package/dist/{chunk-IJW6K6UX.js → chunk-LPRPVCNY.js} +5 -5
  68. package/dist/{chunk-6EVZXETK.js → chunk-M66NAZA4.js} +3 -3
  69. package/dist/{chunk-HGQG3VIP.js → chunk-N5YVZHCB.js} +2 -2
  70. package/dist/chunk-NO272T7Q.js +194 -0
  71. package/dist/chunk-NO272T7Q.js.map +1 -0
  72. package/dist/{chunk-NIA5VQ7G.js → chunk-NQVZB3S7.js} +29 -11
  73. package/dist/chunk-NQVZB3S7.js.map +1 -0
  74. package/dist/{chunk-6OQ7NKMZ.js → chunk-O2DB4C3M.js} +6 -6
  75. package/dist/{chunk-LHYQE3BP.js → chunk-OFBFAVLI.js} +6 -6
  76. package/dist/{chunk-IWVWB7BZ.js → chunk-OJU3CPFA.js} +12 -12
  77. package/dist/{chunk-ZFME46HJ.js → chunk-OPTFANOX.js} +3 -3
  78. package/dist/chunk-OPTFANOX.js.map +1 -0
  79. package/dist/{chunk-5EZAJEES.js → chunk-OVO2RZAE.js} +81 -27
  80. package/dist/chunk-OVO2RZAE.js.map +1 -0
  81. package/dist/{chunk-6I2YPLAG.js → chunk-P27Z66EB.js} +7 -7
  82. package/dist/{chunk-7MHVHGQZ.js → chunk-P2LDXRGP.js} +2 -2
  83. package/dist/chunk-P3NGV5RV.js +41 -0
  84. package/dist/chunk-P3NGV5RV.js.map +1 -0
  85. package/dist/{chunk-NPVICKZE.js → chunk-P5WXDYMD.js} +8 -197
  86. package/dist/chunk-P5WXDYMD.js.map +1 -0
  87. package/dist/{chunk-CPAROOKP.js → chunk-PGFY7IRW.js} +12 -41
  88. package/dist/chunk-PGFY7IRW.js.map +1 -0
  89. package/dist/{chunk-Z44OY24N.js → chunk-PI5CG2OV.js} +9 -5
  90. package/dist/chunk-PI5CG2OV.js.map +1 -0
  91. package/dist/{chunk-6RASM2J4.js → chunk-QKVILR7N.js} +2 -2
  92. package/dist/{chunk-LKBLAUOB.js → chunk-QNTEDPWP.js} +3 -3
  93. package/dist/{chunk-P6UXDALK.js → chunk-RDHAGBEB.js} +3 -3
  94. package/dist/{chunk-XRE4JOEO.js → chunk-RTS23VIJ.js} +2 -2
  95. package/dist/{chunk-5ZPWVNL3.js → chunk-S2WKOCTU.js} +2 -2
  96. package/dist/chunk-SAJJWVNQ.js +135 -0
  97. package/dist/chunk-SAJJWVNQ.js.map +1 -0
  98. package/dist/{chunk-VHEEU4ZO.js → chunk-SW56GSYC.js} +2 -2
  99. package/dist/{chunk-46YGCU6Z.js → chunk-T2EGAXPM.js} +2 -2
  100. package/dist/{chunk-LES2Z7B4.js → chunk-T45LAT2Y.js} +2 -2
  101. package/dist/{chunk-4NMFWOS2.js → chunk-T65UZXR6.js} +3 -3
  102. package/dist/{chunk-2N4MUSF3.js → chunk-TB5RNNJ4.js} +7 -7
  103. package/dist/chunk-TCIUO62Z.js +29 -0
  104. package/dist/chunk-TCIUO62Z.js.map +1 -0
  105. package/dist/chunk-THNJ3IKU.js +17 -0
  106. package/dist/chunk-THNJ3IKU.js.map +1 -0
  107. package/dist/{chunk-U6OM4E67.js → chunk-TL7QR5T6.js} +20 -15
  108. package/dist/chunk-TL7QR5T6.js.map +1 -0
  109. package/dist/{chunk-L4IRFTIF.js → chunk-TLJOJBZD.js} +3 -23
  110. package/dist/chunk-TLJOJBZD.js.map +1 -0
  111. package/dist/chunk-TQ3REHVF.js +95 -0
  112. package/dist/chunk-TQ3REHVF.js.map +1 -0
  113. package/dist/{chunk-6CNLU4TO.js → chunk-TYGW5TOR.js} +7 -7
  114. package/dist/{chunk-BLZRNHMG.js → chunk-U23JUUPX.js} +8 -1
  115. package/dist/{chunk-BLZRNHMG.js.map → chunk-U23JUUPX.js.map} +1 -1
  116. package/dist/{chunk-U5DWHU3S.js → chunk-U24XHXNK.js} +2 -2
  117. package/dist/chunk-ULIHDPKL.js +94 -0
  118. package/dist/chunk-ULIHDPKL.js.map +1 -0
  119. package/dist/chunk-UOEWDCUX.js +69 -0
  120. package/dist/chunk-UOEWDCUX.js.map +1 -0
  121. package/dist/{chunk-NTHKOFVL.js → chunk-VFRNWE5P.js} +52 -8
  122. package/dist/chunk-VFRNWE5P.js.map +1 -0
  123. package/dist/{chunk-4DZGZ7II.js → chunk-VMJ5URU7.js} +8 -8
  124. package/dist/chunk-VMJ5URU7.js.map +1 -0
  125. package/dist/{chunk-YDP2SA5K.js → chunk-VPCMJ5Z4.js} +5 -5
  126. package/dist/{chunk-ZAWD6O46.js → chunk-VRPBEOWU.js} +2 -2
  127. package/dist/{chunk-AY4P6PHN.js → chunk-VWGCJUTV.js} +2 -2
  128. package/dist/{chunk-IIK7W3AN.js → chunk-XJR3COJO.js} +5 -5
  129. package/dist/{chunk-ZD4D7UM6.js → chunk-XYYW64LB.js} +2 -2
  130. package/dist/{chunk-4NZCZUGL.js → chunk-YFF2RP3X.js} +2 -2
  131. package/dist/{chunk-WVIIJPTJ.js → chunk-Z3FZC5GV.js} +7 -7
  132. package/dist/{chunk-55HDKLI3.js → chunk-Z5PIUYNB.js} +8 -8
  133. package/dist/{chunk-ZRDYQZYH.js → chunk-Z7KI4WHR.js} +2 -2
  134. package/dist/{chunk-BV7KNFJY.js → chunk-ZBDK7T6X.js} +9 -9
  135. package/dist/chunk-ZKF6HH7V.js +120 -0
  136. package/dist/chunk-ZKF6HH7V.js.map +1 -0
  137. package/dist/{chunk-P6DN5QU7.js → chunk-ZKYMKF2S.js} +8 -8
  138. package/dist/{chunk-NMRKAGHE.js → chunk-ZROMNP7Q.js} +2 -2
  139. package/dist/{chunk-5A6TC3RQ.js → chunk-ZT4GWVTX.js} +29 -14
  140. package/dist/chunk-ZT4GWVTX.js.map +1 -0
  141. package/dist/classified/index.d.ts +4 -4
  142. package/dist/classified/index.js +3 -3
  143. package/dist/collection-facade-THH4ASGX.js +39 -0
  144. package/dist/computed-BMMEFRFJ.js +11 -0
  145. package/dist/config-drift-3UIJVI5G.js +24 -0
  146. package/dist/config-drift-3UIJVI5G.js.map +1 -0
  147. package/dist/consent/index.d.ts +3 -3
  148. package/dist/consent/index.js +10 -7
  149. package/dist/consent/index.js.map +1 -1
  150. package/dist/crdt/index.d.ts +3 -3
  151. package/dist/delegation-BQNIEHZE.js +25 -0
  152. package/dist/derivations/index.d.ts +4 -4
  153. package/dist/derivations/index.js +12 -9
  154. package/dist/describe/index.d.ts +1 -1
  155. package/dist/{describe-0tiXAjoO.d.ts → describe-C6iHNlqJ.d.ts} +9 -0
  156. package/dist/{dev-unlock-B_s9DUWa.d.ts → dev-unlock-Cqd5Xv5J.d.ts} +1 -1
  157. package/dist/{enclave-IS7HZSQ7.js → enclave-YN6223OG.js} +21 -8
  158. package/dist/executor-CBTNU5VZ.js +9 -0
  159. package/dist/executor-DJHNSTIR.js +9 -0
  160. package/dist/executor-FGISLQIN.js +21 -0
  161. package/dist/export-accessible-P7SLRLK3.js +23 -0
  162. package/dist/extract-partition-6JGY3KYR.js +36 -0
  163. package/dist/{fanout-sidecar-DDKRG2MX.js → fanout-sidecar-WS22Q5WH.js} +12 -9
  164. package/dist/{fanout-sidecar-DDKRG2MX.js.map → fanout-sidecar-WS22Q5WH.js.map} +1 -1
  165. package/dist/fence-watcher-DHQ775JB.js +69 -0
  166. package/dist/fence-watcher-DHQ775JB.js.map +1 -0
  167. package/dist/find-RNBG7LBY.js +11 -0
  168. package/dist/forget/index.js +10 -7
  169. package/dist/forget/index.js.map +1 -1
  170. package/dist/guards/index.d.ts +4 -4
  171. package/dist/guards/index.js +3 -3
  172. package/dist/{hash-CWxn7sf6.d.ts → hash-D8Q5MJLA.d.ts} +1 -1
  173. package/dist/history/index.d.ts +4 -4
  174. package/dist/history/index.js +12 -9
  175. package/dist/history/index.js.map +1 -1
  176. package/dist/i18n/index.d.ts +3 -3
  177. package/dist/i18n/index.js +14 -11
  178. package/dist/i18n/index.js.map +1 -1
  179. package/dist/in/index.d.ts +2 -2
  180. package/dist/{index-D05bV0_g.d.ts → index-D4GQe1Rx.d.ts} +818 -49
  181. package/dist/{index-DTMUUwwW.d.ts → index-DRxk8q_7.d.ts} +3 -3
  182. package/dist/index.d.ts +54 -18
  183. package/dist/index.js +1022 -123
  184. package/dist/index.js.map +1 -1
  185. package/dist/indexing/index.d.ts +3 -3
  186. package/dist/indexing/index.js +4 -4
  187. package/dist/issue-W5QG53B5.js +19 -0
  188. package/dist/json-schema-I22JCYCG.js +44 -0
  189. package/dist/json-schema-I22JCYCG.js.map +1 -0
  190. package/dist/kernel/index.d.ts +3 -3
  191. package/dist/kernel/index.js +13 -10
  192. package/dist/lazy/index.d.ts +21 -0
  193. package/dist/lazy/index.js +12 -0
  194. package/dist/{ledger-YUAJUNFP.js → ledger-KZWBKAG5.js} +12 -9
  195. package/dist/liberate-AQ7OWBZZ.js +24 -0
  196. package/dist/link-set-UQEIYQAM.js +31 -0
  197. package/dist/materialized-views/index.d.ts +4 -4
  198. package/dist/materialized-views/index.js +16 -13
  199. package/dist/{mime-magic-Qr_4HjP6.d.ts → mime-magic-DmwT7OzZ.d.ts} +1 -1
  200. package/dist/noydb-WQZNAECY.js +60 -0
  201. package/dist/on/index.d.ts +2 -2
  202. package/dist/on/index.js +10 -7
  203. package/dist/overlay-views/index.d.ts +4 -4
  204. package/dist/overlay-views/index.js +4 -4
  205. package/dist/periods/index.d.ts +3 -3
  206. package/dist/periods/index.js +13 -10
  207. package/dist/pod/index.d.ts +3 -3
  208. package/dist/pod/index.js +12 -9
  209. package/dist/{policy-LRE6HTO5.js → policy-YIKUH4AD.js} +5 -5
  210. package/dist/portability/index.d.ts +3 -3
  211. package/dist/portability/index.js +8 -8
  212. package/dist/{public-envelope-WVRRUVAJ.js → public-envelope-MRN5YYZZ.js} +4 -4
  213. package/dist/query/index.d.ts +2 -2
  214. package/dist/query/index.js +6 -6
  215. package/dist/register-V5AQTXNI.js +21 -0
  216. package/dist/registry-IMNMHWTM.js +17 -0
  217. package/dist/registry-K6VUQXKV.js +19 -0
  218. package/dist/registry-ZVO3T4M5.js +9 -0
  219. package/dist/request-withdrawal-EHALV66Y.js +31 -0
  220. package/dist/request-withdrawal-EHALV66Y.js.map +1 -0
  221. package/dist/{reveal-WSUHXCSS.js → reveal-TBLTFWQ2.js} +6 -5
  222. package/dist/{reveal-WSUHXCSS.js.map → reveal-TBLTFWQ2.js.map} +1 -1
  223. package/dist/revoke-MHAUAESM.js +24 -0
  224. package/dist/revoke-MHAUAESM.js.map +1 -0
  225. package/dist/sealed-record/index.d.ts +3 -3
  226. package/dist/sealed-record/index.js +13 -10
  227. package/dist/sealed-record/index.js.map +1 -1
  228. package/dist/session/index.d.ts +4 -4
  229. package/dist/session/index.js +10 -7
  230. package/dist/session/index.js.map +1 -1
  231. package/dist/shadow/index.d.ts +3 -3
  232. package/dist/shadow/index.js +2 -2
  233. package/dist/signer-PQ74YXRY.js +25 -0
  234. package/dist/signer-PQ74YXRY.js.map +1 -0
  235. package/dist/snapshots/index.d.ts +3 -3
  236. package/dist/snapshots/index.js +11 -8
  237. package/dist/snapshots/index.js.map +1 -1
  238. package/dist/{stale-LX4BR43V.js → stale-7Q62KVI3.js} +2 -2
  239. package/dist/stale-7Q62KVI3.js.map +1 -0
  240. package/dist/storage-3FKGLQMC.js +23 -0
  241. package/dist/storage-3FKGLQMC.js.map +1 -0
  242. package/dist/{store-coordination-provider-KTRIC6PR.js → store-coordination-provider-JJCEMTAE.js} +3 -3
  243. package/dist/sync/index.d.ts +2 -2
  244. package/dist/sync/index.js +10 -7
  245. package/dist/sync/index.js.map +1 -1
  246. package/dist/team/index.d.ts +45 -6
  247. package/dist/team/index.js +25 -15
  248. package/dist/tiers/index.d.ts +2 -2
  249. package/dist/tiers/index.js +11 -8
  250. package/dist/to/index.d.ts +2 -2
  251. package/dist/to/index.js +1 -1
  252. package/dist/{transition-guard-C1Pyz8nH.d.ts → transition-guard-C4hvR-Ac.d.ts} +1 -1
  253. package/dist/tx/index.d.ts +3 -3
  254. package/dist/tx/index.js +3 -3
  255. package/dist/ui/index.d.ts +1 -1
  256. package/dist/util/index.js +1 -1
  257. package/dist/validators-Ctgkj5qd.d.ts +101 -0
  258. package/dist/{vault-diff-Fn0WeY2w.d.ts → vault-diff-B1Ir6EGs.d.ts} +1 -1
  259. package/dist/{verify-SW6J63Q2.js → verify-YB5LQHNA.js} +11 -7
  260. package/dist/{verify-SW6J63Q2.js.map → verify-YB5LQHNA.js.map} +1 -1
  261. package/dist/walk-T65TZDN2.js +241 -0
  262. package/dist/walk-T65TZDN2.js.map +1 -0
  263. package/dist/with/index.d.ts +3 -3
  264. package/dist/with/index.js +12 -9
  265. package/dist/{with-materialized-view-NKxs6iK5.d.ts → with-materialized-view-Bp65kKdQ.d.ts} +1 -1
  266. package/dist/{with-overlayed-view-B4fPYHwV.d.ts → with-overlayed-view-BRhdQNrK.d.ts} +1 -1
  267. package/dist/{with-rollup-Bl0sRFEt.d.ts → with-rollup-bQRPc3y1.d.ts} +1 -1
  268. package/dist/withdraw-accessible-JMX2TCPX.js +28 -0
  269. package/dist/withdraw-accessible-JMX2TCPX.js.map +1 -0
  270. package/package.json +7 -3
  271. package/dist/api-LORZ2EZU.js +0 -17
  272. package/dist/chunk-4DZGZ7II.js.map +0 -1
  273. package/dist/chunk-5A6TC3RQ.js.map +0 -1
  274. package/dist/chunk-5EZAJEES.js.map +0 -1
  275. package/dist/chunk-ADBMJDBW.js.map +0 -1
  276. package/dist/chunk-CPAROOKP.js.map +0 -1
  277. package/dist/chunk-L4IRFTIF.js.map +0 -1
  278. package/dist/chunk-MIOLJG2R.js.map +0 -1
  279. package/dist/chunk-N2FP26NH.js.map +0 -1
  280. package/dist/chunk-NIA5VQ7G.js.map +0 -1
  281. package/dist/chunk-NPVICKZE.js.map +0 -1
  282. package/dist/chunk-NTHKOFVL.js.map +0 -1
  283. package/dist/chunk-OCDUQUAP.js.map +0 -1
  284. package/dist/chunk-OVIVYAQL.js.map +0 -1
  285. package/dist/chunk-QLQS5A7X.js +0 -524
  286. package/dist/chunk-QLQS5A7X.js.map +0 -1
  287. package/dist/chunk-U6OM4E67.js.map +0 -1
  288. package/dist/chunk-Z44OY24N.js.map +0 -1
  289. package/dist/chunk-ZFME46HJ.js.map +0 -1
  290. package/dist/collection-facade-XPVRHBGU.js +0 -36
  291. package/dist/delegation-4HUHUE6T.js +0 -22
  292. package/dist/executor-ANFBCOYA.js +0 -9
  293. package/dist/executor-IKT47SH2.js +0 -9
  294. package/dist/executor-OIECZXTV.js +0 -18
  295. package/dist/export-accessible-NZWCFZHL.js +0 -20
  296. package/dist/extract-partition-52LX6RQH.js +0 -33
  297. package/dist/issue-F4SYPJGJ.js +0 -16
  298. package/dist/liberate-6LDETRIW.js +0 -21
  299. package/dist/noydb-WQNBVJIG.js +0 -54
  300. package/dist/registry-6HZ2JSQ7.js +0 -14
  301. package/dist/registry-GPXZQ7DT.js +0 -9
  302. package/dist/registry-USYD2ECC.js +0 -16
  303. package/dist/request-withdrawal-54V4L6CR.js +0 -28
  304. package/dist/revoke-JV26NTQD.js +0 -21
  305. package/dist/signer-AE56T5HE.js +0 -22
  306. package/dist/validators-Dzn7T-3x.d.ts +0 -62
  307. package/dist/withdraw-accessible-DGA4V2TP.js +0 -25
  308. /package/dist/{api-LORZ2EZU.js.map → api-JOXUNSKP.js.map} +0 -0
  309. /package/dist/{chunk-VBYVKOMJ.js.map → chunk-3QRQOBS7.js.map} +0 -0
  310. /package/dist/{chunk-JFYIHLU3.js.map → chunk-3Y4QLJ6K.js.map} +0 -0
  311. /package/dist/{chunk-BZIWKN74.js.map → chunk-43ISXURO.js.map} +0 -0
  312. /package/dist/{chunk-PYWW4KLO.js.map → chunk-44UTIDE2.js.map} +0 -0
  313. /package/dist/{chunk-7IP75FP2.js.map → chunk-4K3MQ5S3.js.map} +0 -0
  314. /package/dist/{chunk-2KSPDSWI.js.map → chunk-5MRE3C4Q.js.map} +0 -0
  315. /package/dist/{chunk-PUNJAEY6.js.map → chunk-6HNKCKFZ.js.map} +0 -0
  316. /package/dist/{chunk-PJDK2PPQ.js.map → chunk-6RXPSMKR.js.map} +0 -0
  317. /package/dist/{chunk-6DP5HBQD.js.map → chunk-6UOSONVI.js.map} +0 -0
  318. /package/dist/{chunk-UP6EMMDI.js.map → chunk-A4DWPOP3.js.map} +0 -0
  319. /package/dist/{chunk-MCJAUQGE.js.map → chunk-A5DYVMDR.js.map} +0 -0
  320. /package/dist/{chunk-TICO2I2O.js.map → chunk-BKGIWGCX.js.map} +0 -0
  321. /package/dist/{chunk-O5DNEXQC.js.map → chunk-BMQOH7MM.js.map} +0 -0
  322. /package/dist/{chunk-3UDPDRUC.js.map → chunk-EWR7HL3K.js.map} +0 -0
  323. /package/dist/{chunk-CVXLJIAV.js.map → chunk-FH52CDEW.js.map} +0 -0
  324. /package/dist/{chunk-FELHYKIO.js.map → chunk-G7RDYYTE.js.map} +0 -0
  325. /package/dist/{chunk-DHIN36UC.js.map → chunk-GQOT6QJR.js.map} +0 -0
  326. /package/dist/{chunk-DGUR3CC4.js.map → chunk-GXGK22QU.js.map} +0 -0
  327. /package/dist/{chunk-YTIAXSUE.js.map → chunk-GZZL5R73.js.map} +0 -0
  328. /package/dist/{chunk-E4YJUNPU.js.map → chunk-H5XRIJX3.js.map} +0 -0
  329. /package/dist/{chunk-DA34OEZU.js.map → chunk-H7RYPVMJ.js.map} +0 -0
  330. /package/dist/{chunk-2ZORB5RW.js.map → chunk-HBKDR7R3.js.map} +0 -0
  331. /package/dist/{chunk-ZNI3RTFV.js.map → chunk-HMXLN43G.js.map} +0 -0
  332. /package/dist/{chunk-BYW7EU5L.js.map → chunk-HY6ZGGEC.js.map} +0 -0
  333. /package/dist/{chunk-5Z3RNFJC.js.map → chunk-LIP6JWYK.js.map} +0 -0
  334. /package/dist/{chunk-IJW6K6UX.js.map → chunk-LPRPVCNY.js.map} +0 -0
  335. /package/dist/{chunk-6EVZXETK.js.map → chunk-M66NAZA4.js.map} +0 -0
  336. /package/dist/{chunk-HGQG3VIP.js.map → chunk-N5YVZHCB.js.map} +0 -0
  337. /package/dist/{chunk-6OQ7NKMZ.js.map → chunk-O2DB4C3M.js.map} +0 -0
  338. /package/dist/{chunk-LHYQE3BP.js.map → chunk-OFBFAVLI.js.map} +0 -0
  339. /package/dist/{chunk-IWVWB7BZ.js.map → chunk-OJU3CPFA.js.map} +0 -0
  340. /package/dist/{chunk-6I2YPLAG.js.map → chunk-P27Z66EB.js.map} +0 -0
  341. /package/dist/{chunk-7MHVHGQZ.js.map → chunk-P2LDXRGP.js.map} +0 -0
  342. /package/dist/{chunk-6RASM2J4.js.map → chunk-QKVILR7N.js.map} +0 -0
  343. /package/dist/{chunk-LKBLAUOB.js.map → chunk-QNTEDPWP.js.map} +0 -0
  344. /package/dist/{chunk-P6UXDALK.js.map → chunk-RDHAGBEB.js.map} +0 -0
  345. /package/dist/{chunk-XRE4JOEO.js.map → chunk-RTS23VIJ.js.map} +0 -0
  346. /package/dist/{chunk-5ZPWVNL3.js.map → chunk-S2WKOCTU.js.map} +0 -0
  347. /package/dist/{chunk-VHEEU4ZO.js.map → chunk-SW56GSYC.js.map} +0 -0
  348. /package/dist/{chunk-46YGCU6Z.js.map → chunk-T2EGAXPM.js.map} +0 -0
  349. /package/dist/{chunk-LES2Z7B4.js.map → chunk-T45LAT2Y.js.map} +0 -0
  350. /package/dist/{chunk-4NMFWOS2.js.map → chunk-T65UZXR6.js.map} +0 -0
  351. /package/dist/{chunk-2N4MUSF3.js.map → chunk-TB5RNNJ4.js.map} +0 -0
  352. /package/dist/{chunk-6CNLU4TO.js.map → chunk-TYGW5TOR.js.map} +0 -0
  353. /package/dist/{chunk-U5DWHU3S.js.map → chunk-U24XHXNK.js.map} +0 -0
  354. /package/dist/{chunk-YDP2SA5K.js.map → chunk-VPCMJ5Z4.js.map} +0 -0
  355. /package/dist/{chunk-ZAWD6O46.js.map → chunk-VRPBEOWU.js.map} +0 -0
  356. /package/dist/{chunk-AY4P6PHN.js.map → chunk-VWGCJUTV.js.map} +0 -0
  357. /package/dist/{chunk-IIK7W3AN.js.map → chunk-XJR3COJO.js.map} +0 -0
  358. /package/dist/{chunk-ZD4D7UM6.js.map → chunk-XYYW64LB.js.map} +0 -0
  359. /package/dist/{chunk-4NZCZUGL.js.map → chunk-YFF2RP3X.js.map} +0 -0
  360. /package/dist/{chunk-WVIIJPTJ.js.map → chunk-Z3FZC5GV.js.map} +0 -0
  361. /package/dist/{chunk-55HDKLI3.js.map → chunk-Z5PIUYNB.js.map} +0 -0
  362. /package/dist/{chunk-ZRDYQZYH.js.map → chunk-Z7KI4WHR.js.map} +0 -0
  363. /package/dist/{chunk-BV7KNFJY.js.map → chunk-ZBDK7T6X.js.map} +0 -0
  364. /package/dist/{chunk-P6DN5QU7.js.map → chunk-ZKYMKF2S.js.map} +0 -0
  365. /package/dist/{chunk-NMRKAGHE.js.map → chunk-ZROMNP7Q.js.map} +0 -0
  366. /package/dist/{collection-facade-XPVRHBGU.js.map → collection-facade-THH4ASGX.js.map} +0 -0
  367. /package/dist/{delegation-4HUHUE6T.js.map → computed-BMMEFRFJ.js.map} +0 -0
  368. /package/dist/{enclave-IS7HZSQ7.js.map → delegation-BQNIEHZE.js.map} +0 -0
  369. /package/dist/{executor-ANFBCOYA.js.map → enclave-YN6223OG.js.map} +0 -0
  370. /package/dist/{executor-IKT47SH2.js.map → executor-CBTNU5VZ.js.map} +0 -0
  371. /package/dist/{executor-OIECZXTV.js.map → executor-DJHNSTIR.js.map} +0 -0
  372. /package/dist/{export-accessible-NZWCFZHL.js.map → executor-FGISLQIN.js.map} +0 -0
  373. /package/dist/{extract-partition-52LX6RQH.js.map → export-accessible-P7SLRLK3.js.map} +0 -0
  374. /package/dist/{issue-F4SYPJGJ.js.map → extract-partition-6JGY3KYR.js.map} +0 -0
  375. /package/dist/{ledger-YUAJUNFP.js.map → find-RNBG7LBY.js.map} +0 -0
  376. /package/dist/{liberate-6LDETRIW.js.map → issue-W5QG53B5.js.map} +0 -0
  377. /package/dist/{noydb-WQNBVJIG.js.map → lazy/index.js.map} +0 -0
  378. /package/dist/{policy-LRE6HTO5.js.map → ledger-KZWBKAG5.js.map} +0 -0
  379. /package/dist/{public-envelope-WVRRUVAJ.js.map → liberate-AQ7OWBZZ.js.map} +0 -0
  380. /package/dist/{registry-6HZ2JSQ7.js.map → link-set-UQEIYQAM.js.map} +0 -0
  381. /package/dist/{registry-GPXZQ7DT.js.map → noydb-WQZNAECY.js.map} +0 -0
  382. /package/dist/{registry-USYD2ECC.js.map → policy-YIKUH4AD.js.map} +0 -0
  383. /package/dist/{request-withdrawal-54V4L6CR.js.map → public-envelope-MRN5YYZZ.js.map} +0 -0
  384. /package/dist/{revoke-JV26NTQD.js.map → register-V5AQTXNI.js.map} +0 -0
  385. /package/dist/{signer-AE56T5HE.js.map → registry-IMNMHWTM.js.map} +0 -0
  386. /package/dist/{stale-LX4BR43V.js.map → registry-K6VUQXKV.js.map} +0 -0
  387. /package/dist/{withdraw-accessible-DGA4V2TP.js.map → registry-ZVO3T4M5.js.map} +0 -0
  388. /package/dist/{store-coordination-provider-KTRIC6PR.js.map → store-coordination-provider-JJCEMTAE.js.map} +0 -0
@@ -2,7 +2,7 @@
2
2
  function withCargo() {
3
3
  return {
4
4
  async extractPartition(vault, opts) {
5
- const { extractPartitionCore } = await import("./extract-partition-52LX6RQH.js");
5
+ const { extractPartitionCore } = await import("./extract-partition-6JGY3KYR.js");
6
6
  return extractPartitionCore(vault, opts);
7
7
  }
8
8
  };
@@ -11,4 +11,4 @@ function withCargo() {
11
11
  export {
12
12
  withCargo
13
13
  };
14
- //# sourceMappingURL=chunk-5ZPWVNL3.js.map
14
+ //# sourceMappingURL=chunk-S2WKOCTU.js.map
@@ -0,0 +1,135 @@
1
+ import {
2
+ canonicalize,
3
+ derivePersistedSchema
4
+ } from "./chunk-ULIHDPKL.js";
5
+ import {
6
+ loadPersistedSchemaEntry,
7
+ savePersistedSchema
8
+ } from "./chunk-TL7QR5T6.js";
9
+ import {
10
+ ConflictError
11
+ } from "./chunk-U23JUUPX.js";
12
+
13
+ // src/with-shape/schema-update/delta.ts
14
+ function computeSchemaDelta(stored, fresh, collection) {
15
+ const a = stored;
16
+ const b = fresh;
17
+ const aProps = a.properties ?? {};
18
+ const bProps = b.properties ?? {};
19
+ const aReq = new Set(a.required ?? []);
20
+ const bReq = new Set(b.required ?? []);
21
+ const aKeys = Object.keys(aProps);
22
+ const bKeys = Object.keys(bProps);
23
+ const added = bKeys.filter((k) => !(k in aProps));
24
+ const removed = aKeys.filter((k) => !(k in bProps));
25
+ const changed = [];
26
+ for (const k of bKeys) {
27
+ if (!(k in aProps)) continue;
28
+ const shapeChanged = canonicalize(aProps[k]) !== canonicalize(bProps[k]);
29
+ const requiredChanged = aReq.has(k) !== bReq.has(k);
30
+ if (shapeChanged || requiredChanged) {
31
+ changed.push({ field: k, requiredChanged, shapeChanged });
32
+ }
33
+ }
34
+ let kind;
35
+ if (added.length === 0 && removed.length === 0 && changed.length === 0) {
36
+ kind = "none";
37
+ } else if (removed.length === 0 && changed.length === 0 && added.every((k) => !bReq.has(k))) {
38
+ kind = "additive";
39
+ } else {
40
+ kind = "non-additive";
41
+ }
42
+ return { collection, kind, added, removed, changed };
43
+ }
44
+
45
+ // src/with-shape/schema-update/dispatch.ts
46
+ async function evaluateStrategies(delta, strategies, ctx) {
47
+ for (const strategy of strategies) {
48
+ const decision = await strategy.onSchemaDelta(delta, ctx);
49
+ if (decision.action !== "allow") return decision;
50
+ }
51
+ return { action: "allow" };
52
+ }
53
+
54
+ // src/with-shape/persisted-schemas/register.ts
55
+ var MAX_SCHEMA_CAS_RETRIES = 5;
56
+ async function persistSchemaIfNeeded(opts) {
57
+ const fresh = await derivePersistedSchema(opts.validator);
58
+ for (let attempt = 0; ; attempt++) {
59
+ const { version, payload: stored } = await loadPersistedSchemaEntry(
60
+ opts.store,
61
+ opts.vault,
62
+ opts.collectionName,
63
+ opts.dek
64
+ );
65
+ if (stored && isEquivalent(stored, fresh)) {
66
+ return { written: false, skipped: true, envelope: stored, decision: { action: "allow" } };
67
+ }
68
+ let decision = { action: "allow" };
69
+ const strategies = opts.strategies ?? [];
70
+ if (stored && strategies.length > 0 && stored.kind === fresh.kind && isPlainObject(stored.jsonSchema) && isPlainObject(fresh.jsonSchema)) {
71
+ const delta = computeSchemaDelta(stored.jsonSchema, fresh.jsonSchema, opts.collectionName);
72
+ decision = await evaluateStrategies(delta, strategies, { collection: opts.collectionName });
73
+ }
74
+ if (decision.action !== "allow") {
75
+ return { written: false, skipped: false, envelope: stored ?? fresh, decision };
76
+ }
77
+ const toSave = stored?.classified !== void 0 ? { ...fresh, classified: stored.classified } : fresh;
78
+ try {
79
+ await savePersistedSchema(opts.store, opts.vault, opts.collectionName, opts.dek, toSave, version);
80
+ return { written: true, skipped: false, envelope: toSave, decision };
81
+ } catch (err) {
82
+ if (err instanceof ConflictError && attempt < MAX_SCHEMA_CAS_RETRIES) continue;
83
+ throw err;
84
+ }
85
+ }
86
+ }
87
+ async function persistClassifiedMarker(opts) {
88
+ for (let attempt = 0; ; attempt++) {
89
+ const { version, payload: stored } = await loadPersistedSchemaEntry(
90
+ opts.store,
91
+ opts.vault,
92
+ opts.collectionName,
93
+ opts.dek
94
+ );
95
+ if (stored?.classified !== void 0 && markersEqual(stored.classified, opts.marker)) return;
96
+ const payload = stored !== void 0 ? { ...stored, classified: opts.marker } : {
97
+ _noydb_schema: 1,
98
+ kind: "Unknown",
99
+ jsonSchema: null,
100
+ hash: null,
101
+ derivedAt: (/* @__PURE__ */ new Date()).toISOString(),
102
+ classified: opts.marker
103
+ };
104
+ try {
105
+ await savePersistedSchema(opts.store, opts.vault, opts.collectionName, opts.dek, payload, version);
106
+ return;
107
+ } catch (err) {
108
+ if (err instanceof ConflictError && attempt < MAX_SCHEMA_CAS_RETRIES) continue;
109
+ throw err;
110
+ }
111
+ }
112
+ }
113
+ function markersEqual(a, b) {
114
+ return sameSet(a.digestOnly, b.digestOnly) && sameSet(a.equatable, b.equatable);
115
+ }
116
+ function sameSet(a, b) {
117
+ if (a.length !== b.length) return false;
118
+ const s = new Set(a);
119
+ return b.every((x) => s.has(x));
120
+ }
121
+ function isPlainObject(v) {
122
+ return typeof v === "object" && v !== null && !Array.isArray(v);
123
+ }
124
+ function isEquivalent(a, b) {
125
+ if (a.kind !== b.kind) return false;
126
+ if (a.hash && b.hash) return a.hash === b.hash;
127
+ if (a.hash === null && b.hash === null) return true;
128
+ return false;
129
+ }
130
+
131
+ export {
132
+ persistSchemaIfNeeded,
133
+ persistClassifiedMarker
134
+ };
135
+ //# sourceMappingURL=chunk-SAJJWVNQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-shape/schema-update/delta.ts","../src/with-shape/schema-update/dispatch.ts","../src/with-shape/persisted-schemas/register.ts"],"sourcesContent":["/**\n * Classify the difference between two derived JSON Schemas.\n *\n * v1 ruleset — top-level object properties + required-ness:\n * - additive ⇔ only new OPTIONAL properties (no removals, no changed\n * properties, no new required field, no required-ness flip)\n * - non-additive ⇔ any removal, any shape/type change, any required-ness\n * flip, or a new REQUIRED property\n * Deeper rules (nested objects, union widening, type narrowing) are\n * deferred. Callers only invoke this with two object schemas.\n */\nimport { canonicalize } from '../persisted-schemas/canonicalize.js'\nimport type { SchemaDelta, FieldChange } from './types.js'\n\ninterface ObjectSchema {\n readonly properties?: Record<string, unknown>\n readonly required?: readonly string[]\n}\n\nexport function computeSchemaDelta(\n stored: object,\n fresh: object,\n collection: string,\n): SchemaDelta {\n const a = stored as ObjectSchema\n const b = fresh as ObjectSchema\n const aProps = a.properties ?? {}\n const bProps = b.properties ?? {}\n const aReq = new Set(a.required ?? [])\n const bReq = new Set(b.required ?? [])\n\n const aKeys = Object.keys(aProps)\n const bKeys = Object.keys(bProps)\n\n const added = bKeys.filter(k => !(k in aProps))\n const removed = aKeys.filter(k => !(k in bProps))\n\n const changed: FieldChange[] = []\n for (const k of bKeys) {\n if (!(k in aProps)) continue\n const shapeChanged = canonicalize(aProps[k]) !== canonicalize(bProps[k])\n const requiredChanged = aReq.has(k) !== bReq.has(k)\n if (shapeChanged || requiredChanged) {\n changed.push({ field: k, requiredChanged, shapeChanged })\n }\n }\n\n let kind: SchemaDelta['kind']\n if (added.length === 0 && removed.length === 0 && changed.length === 0) {\n kind = 'none'\n } else if (\n removed.length === 0 &&\n changed.length === 0 &&\n added.every(k => !bReq.has(k))\n ) {\n kind = 'additive'\n } else {\n kind = 'non-additive'\n }\n\n return { collection, kind, added, removed, changed }\n}\n","/** Ordered strategy evaluation: first non-`allow` decision wins. */\nimport type { SchemaDelta, SchemaUpdateStrategy, UpdateContext, UpdateDecision } from './types.js'\n\nexport async function evaluateStrategies(\n delta: SchemaDelta,\n strategies: readonly SchemaUpdateStrategy[],\n ctx: UpdateContext,\n): Promise<UpdateDecision> {\n for (const strategy of strategies) {\n const decision = await strategy.onSchemaDelta(delta, ctx)\n if (decision.action !== 'allow') return decision\n }\n return { action: 'allow' }\n}\n","/**\n * Orchestrate the derive → hash → skip-or-write cycle for a collection's\n * persisted JSON Schema. Called by the Vault at collection-registration\n * time when the developer opts in via `collection({ persistJsonSchema:\n * true })`.\n *\n * Skip semantics:\n *\n * - Zod validators: skip when the new hash equals the stored hash.\n * - Non-Zod (stub envelopes have hash=null): skip when the stored\n * envelope's `kind` matches the freshly-detected kind (since there's\n * no body to compare yet — a kind change is the only signal).\n *\n * @module\n */\n\nimport { derivePersistedSchema } from './derive.js'\nimport { loadPersistedSchemaEntry, savePersistedSchema } from './storage.js'\nimport { computeSchemaDelta } from '../schema-update/delta.js'\nimport { evaluateStrategies } from '../schema-update/dispatch.js'\nimport { ConflictError } from '../../kernel/errors.js'\nimport type { SchemaUpdateStrategy, UpdateDecision } from '../schema-update/types.js'\nimport type { NoydbStore, ClassifiedMarker } from '../../kernel/types.js'\nimport type { PersistedSchemaEnvelope } from './types.js'\nimport type { EnclaveKey } from '../../kernel/enclave/index.js'\n\n/**\n * Max optimistic-CAS retries for the shared `_schemas/<collection>` record\n * (#583). Only two writers ever contend (the JSON-Schema writer and the\n * classified-marker writer), so one retry suffices; the headroom covers a\n * pathological re-order. Exhausting it rethrows the {@link ConflictError}\n * rather than silently losing a write.\n */\nconst MAX_SCHEMA_CAS_RETRIES = 5\n\nexport interface PersistSchemaResult {\n /** True when a fresh envelope was written to storage. */\n readonly written: boolean\n /** True when an existing envelope matched and the write was skipped. */\n readonly skipped: boolean\n /** The envelope that was either written or matched. */\n readonly envelope: PersistedSchemaEnvelope\n /** The update-strategy decision, present when strategies ran. */\n readonly decision?: UpdateDecision\n}\n\nexport async function persistSchemaIfNeeded(opts: {\n readonly store: NoydbStore\n readonly vault: string\n readonly collectionName: string\n readonly validator: unknown\n readonly dek: EnclaveKey\n readonly strategies?: readonly SchemaUpdateStrategy[]\n}): Promise<PersistSchemaResult> {\n const fresh = await derivePersistedSchema(opts.validator)\n\n // The `_schemas/<collection>` record is shared with the classified-marker\n // writer, so a plain load→save loses whichever writer put first (#583). Read\n // the version at load time and CAS on it; on conflict re-read (picking up the\n // other writer's field), re-evaluate, and retry.\n for (let attempt = 0; ; attempt++) {\n const { version, payload: stored } = await loadPersistedSchemaEntry(\n opts.store, opts.vault, opts.collectionName, opts.dek,\n )\n\n if (stored && isEquivalent(stored, fresh)) {\n return { written: false, skipped: true, envelope: stored, decision: { action: 'allow' } }\n }\n\n // Changed (or first registration). Run update strategies only when we\n // have a comparable JSON-Schema baseline and strategies were registered.\n let decision: UpdateDecision = { action: 'allow' }\n const strategies = opts.strategies ?? []\n if (\n stored &&\n strategies.length > 0 &&\n stored.kind === fresh.kind &&\n isPlainObject(stored.jsonSchema) &&\n isPlainObject(fresh.jsonSchema)\n ) {\n const delta = computeSchemaDelta(stored.jsonSchema, fresh.jsonSchema, opts.collectionName)\n decision = await evaluateStrategies(delta, strategies, { collection: opts.collectionName })\n }\n\n if (decision.action !== 'allow') {\n // reject (or cutover): do NOT overwrite the baseline — the\n // old schema stays the source of truth until the change is resolved.\n return { written: false, skipped: false, envelope: stored ?? fresh, decision }\n }\n\n // Preserve a previously-persisted classified marker (C-A / R10) — the schema\n // derivation knows nothing about it, so a naive overwrite here would drop the\n // config-drift guard's cross-session signal.\n const toSave: PersistedSchemaEnvelope =\n stored?.classified !== undefined ? { ...fresh, classified: stored.classified } : fresh\n try {\n await savePersistedSchema(opts.store, opts.vault, opts.collectionName, opts.dek, toSave, version)\n return { written: true, skipped: false, envelope: toSave, decision }\n } catch (err) {\n if (err instanceof ConflictError && attempt < MAX_SCHEMA_CAS_RETRIES) continue\n throw err\n }\n }\n}\n\n/**\n * Persist (or refresh) the C-A / R10 classified marker into the collection's\n * `_schemas/<collection>` record, preserving any existing derived JSON-Schema\n * body. Idempotent — a no-op when an equivalent marker is already stored.\n * Independent of `persistJsonSchema`: called on the first classified write so a\n * later naive handle can detect the drift cross-session.\n */\nexport async function persistClassifiedMarker(opts: {\n readonly store: NoydbStore\n readonly vault: string\n readonly collectionName: string\n readonly dek: EnclaveKey\n readonly marker: ClassifiedMarker\n}): Promise<void> {\n // Shares the `_schemas/<collection>` record with the JSON-Schema writer;\n // CAS on the loaded version so a concurrent schema (re)registration can't\n // silently drop the marker (and vice-versa) — see #583.\n for (let attempt = 0; ; attempt++) {\n const { version, payload: stored } = await loadPersistedSchemaEntry(\n opts.store, opts.vault, opts.collectionName, opts.dek,\n )\n if (stored?.classified !== undefined && markersEqual(stored.classified, opts.marker)) return\n const payload: PersistedSchemaEnvelope =\n stored !== undefined\n ? { ...stored, classified: opts.marker }\n : {\n _noydb_schema: 1,\n kind: 'Unknown',\n jsonSchema: null,\n hash: null,\n derivedAt: new Date().toISOString(),\n classified: opts.marker,\n }\n try {\n await savePersistedSchema(opts.store, opts.vault, opts.collectionName, opts.dek, payload, version)\n return\n } catch (err) {\n if (err instanceof ConflictError && attempt < MAX_SCHEMA_CAS_RETRIES) continue\n throw err\n }\n }\n}\n\nfunction markersEqual(a: ClassifiedMarker, b: ClassifiedMarker): boolean {\n return sameSet(a.digestOnly, b.digestOnly) && sameSet(a.equatable, b.equatable)\n}\n\nfunction sameSet(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) return false\n const s = new Set(a)\n return b.every((x) => s.has(x))\n}\n\nfunction isPlainObject(v: unknown): v is object {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\nfunction isEquivalent(a: PersistedSchemaEnvelope, b: PersistedSchemaEnvelope): boolean {\n if (a.kind !== b.kind) return false\n // Zod path: real hashes — compare directly.\n if (a.hash && b.hash) return a.hash === b.hash\n // Stub path: both have hash=null. Kind equality is the only signal we have.\n if (a.hash === null && b.hash === null) return true\n // Mixed (one has a hash, the other doesn't) — treat as changed.\n return false\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ConflictError,
3
3
  PodVersionConflictError
4
- } from "./chunk-BLZRNHMG.js";
4
+ } from "./chunk-U23JUUPX.js";
5
5
 
6
6
  // src/with-pod/pod-store.ts
7
7
  var BUNDLE_STORE_VERSION = 1;
@@ -152,4 +152,4 @@ export {
152
152
  wrapBundleStore,
153
153
  createBundleStore
154
154
  };
155
- //# sourceMappingURL=chunk-VHEEU4ZO.js.map
155
+ //# sourceMappingURL=chunk-SW56GSYC.js.map
@@ -2,7 +2,7 @@ import {
2
2
  IllegalTransitionError,
3
3
  RecordLockedError,
4
4
  ValidationError
5
- } from "./chunk-BLZRNHMG.js";
5
+ } from "./chunk-U23JUUPX.js";
6
6
 
7
7
  // src/with-audit/guards/with-guard.ts
8
8
  function withGuard(strategy) {
@@ -120,4 +120,4 @@ export {
120
120
  immutableGuard,
121
121
  transitionGuard
122
122
  };
123
- //# sourceMappingURL=chunk-46YGCU6Z.js.map
123
+ //# sourceMappingURL=chunk-T2EGAXPM.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NOYDB_FORMAT_VERSION
3
- } from "./chunk-OCDUQUAP.js";
3
+ } from "./chunk-LN22XH4B.js";
4
4
 
5
5
  // src/with-party/policy/storage.ts
6
6
  var META_COLLECTION = "_meta";
@@ -39,4 +39,4 @@ export {
39
39
  loadVaultPolicy,
40
40
  saveVaultPolicy
41
41
  };
42
- //# sourceMappingURL=chunk-LES2Z7B4.js.map
42
+ //# sourceMappingURL=chunk-T45LAT2Y.js.map
@@ -6,7 +6,7 @@ import {
6
6
  ConflictError,
7
7
  InvariantError,
8
8
  ValidationError
9
- } from "./chunk-BLZRNHMG.js";
9
+ } from "./chunk-U23JUUPX.js";
10
10
 
11
11
  // src/with-commit/tx/transaction.ts
12
12
  var TxContext = class {
@@ -216,7 +216,7 @@ async function runTransaction(db, fn, options, txInvariants) {
216
216
  db._clearActiveTxContext(ctx);
217
217
  }
218
218
  if (ctx._amendment) {
219
- const { GuardExecutor } = await import("./executor-IKT47SH2.js");
219
+ const { GuardExecutor } = await import("./executor-DJHNSTIR.js");
220
220
  try {
221
221
  for (const [vaultName, v] of ctx._amendmentVaults) {
222
222
  const registry = v._getGuardRegistry();
@@ -352,4 +352,4 @@ export {
352
352
  runTransaction,
353
353
  revertExecuted
354
354
  };
355
- //# sourceMappingURL=chunk-4NMFWOS2.js.map
355
+ //# sourceMappingURL=chunk-T65UZXR6.js.map
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  openEnvelopeJson
3
- } from "./chunk-5EZAJEES.js";
4
- import {
5
- encrypt
6
- } from "./chunk-L4IRFTIF.js";
3
+ } from "./chunk-OVO2RZAE.js";
7
4
  import {
8
5
  NOYDB_FORMAT_VERSION
9
- } from "./chunk-OCDUQUAP.js";
6
+ } from "./chunk-LN22XH4B.js";
7
+ import {
8
+ encrypt
9
+ } from "./chunk-TLJOJBZD.js";
10
10
  import {
11
11
  ConflictError,
12
12
  USER_ENVELOPE_COLLECTION,
13
13
  USER_ENVELOPE_MAX_BYTES,
14
14
  UserEnvelopeOversizedError
15
- } from "./chunk-BLZRNHMG.js";
15
+ } from "./chunk-U23JUUPX.js";
16
16
 
17
17
  // src/with-party/directory/storage.ts
18
18
  var META_COLLECTION = "_meta";
@@ -147,4 +147,4 @@ export {
147
147
  deleteUserEnvelope,
148
148
  listUserEnvelopeIds
149
149
  };
150
- //# sourceMappingURL=chunk-2N4MUSF3.js.map
150
+ //# sourceMappingURL=chunk-TB5RNNJ4.js.map
@@ -0,0 +1,29 @@
1
+ import {
2
+ decrypt,
3
+ deriveSealedFieldKey,
4
+ deriveSealedFieldKeyFromCek
5
+ } from "./chunk-TLJOJBZD.js";
6
+
7
+ // src/kernel/enclave/record-keys/sealed-slot.ts
8
+ function parseSealedSlot(blob) {
9
+ const sep = blob.indexOf(":");
10
+ return { iv: blob.slice(0, sep), data: blob.slice(sep + 1) };
11
+ }
12
+ async function dualReadSealedSlot(blob, field, collection, cek, dek) {
13
+ const { iv, data } = parseSealedSlot(blob);
14
+ if (cek !== void 0) {
15
+ try {
16
+ const fieldKey2 = await deriveSealedFieldKeyFromCek(cek, collection, field);
17
+ return await decrypt(iv, data, fieldKey2);
18
+ } catch {
19
+ }
20
+ }
21
+ const fieldKey = await deriveSealedFieldKey(dek, collection, field);
22
+ return decrypt(iv, data, fieldKey);
23
+ }
24
+
25
+ export {
26
+ parseSealedSlot,
27
+ dualReadSealedSlot
28
+ };
29
+ //# sourceMappingURL=chunk-TCIUO62Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/kernel/enclave/record-keys/sealed-slot.ts"],"sourcesContent":["/**\n * Sealed-slot (`iv:data`) parsing + the CEK/DEK dual-read, factored out so the\n * three callers that decrypt a `_sealed[field]` slot share ONE implementation\n * with no coupling between them:\n *\n * - {@link RecordCodec.unsealField} / `classifySealedShred` (read + classify),\n * - `record-keys/sealing.ts:rotateRecordCek` (re-seal under a new CEK).\n *\n * These are pure helpers over an explicit `(cek, dek)` pair — NOT a context\n * object — so `sealing.ts` (which holds only the DEK) can import them without\n * pulling in the whole codec, avoiding a codec↔sealing dependency cycle.\n */\nimport { decrypt, deriveSealedFieldKey, deriveSealedFieldKeyFromCek } from '../crypto.js'\n\n/** Parse an `iv:data` sealed slot (split on the FIRST `:`). */\nexport function parseSealedSlot(blob: string): { iv: string; data: string } {\n const sep = blob.indexOf(':')\n return { iv: blob.slice(0, sep), data: blob.slice(sep + 1) }\n}\n\n/**\n * Dual-read: decrypt a sealed slot trying the CEK-derived field key first,\n * falling back to the collection-DEK field key. Legacy records\n * (even ones whose body is CEK-encrypted) are sealed under the collection-DEK\n * key; current writes seal under the per-record CEK. Try the CEK key first; on\n * its AES-GCM auth failure, fall back to the DEK key. Throws only if BOTH fail.\n * Returns the plaintext string (callers `JSON.parse` as needed).\n */\nexport async function dualReadSealedSlot(\n blob: string,\n field: string,\n collection: string,\n cek: CryptoKey | undefined,\n dek: CryptoKey,\n): Promise<string> {\n const { iv, data } = parseSealedSlot(blob)\n if (cek !== undefined) {\n try {\n const fieldKey = await deriveSealedFieldKeyFromCek(cek, collection, field)\n return await decrypt(iv, data, fieldKey)\n } catch {\n // fall through to the legacy collection-DEK derivation\n }\n }\n const fieldKey = await deriveSealedFieldKey(dek, collection, field)\n return decrypt(iv, data, fieldKey)\n}\n"],"mappings":";;;;;;;AAeO,SAAS,gBAAgB,MAA4C;AAC1E,QAAM,MAAM,KAAK,QAAQ,GAAG;AAC5B,SAAO,EAAE,IAAI,KAAK,MAAM,GAAG,GAAG,GAAG,MAAM,KAAK,MAAM,MAAM,CAAC,EAAE;AAC7D;AAUA,eAAsB,mBACpB,MACA,OACA,YACA,KACA,KACiB;AACjB,QAAM,EAAE,IAAI,KAAK,IAAI,gBAAgB,IAAI;AACzC,MAAI,QAAQ,QAAW;AACrB,QAAI;AACF,YAAMA,YAAW,MAAM,4BAA4B,KAAK,YAAY,KAAK;AACzE,aAAO,MAAM,QAAQ,IAAI,MAAMA,SAAQ;AAAA,IACzC,QAAQ;AAAA,IAER;AAAA,EACF;AACA,QAAM,WAAW,MAAM,qBAAqB,KAAK,YAAY,KAAK;AAClE,SAAO,QAAQ,IAAI,MAAM,QAAQ;AACnC;","names":["fieldKey"]}
@@ -0,0 +1,17 @@
1
+ import {
2
+ buildLazyCache
3
+ } from "./chunk-NO272T7Q.js";
4
+
5
+ // src/with-store/lazy/active.ts
6
+ function withLazy() {
7
+ return {
8
+ createCache(collection, cache) {
9
+ return buildLazyCache(collection, cache);
10
+ }
11
+ };
12
+ }
13
+
14
+ export {
15
+ withLazy
16
+ };
17
+ //# sourceMappingURL=chunk-THNJ3IKU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-store/lazy/active.ts"],"sourcesContent":["/**\n * Enable the lazy service (#267 Track A tail — lazy-mode promoted out of\n * `routing` into its own opt-in service).\n *\n * Pass to `createNoydb({ lazyStrategy: withLazy() })` to explicitly opt\n * into lazy mode's bounded-LRU working set for collections declared with\n * `prefetch: false` + a `cache` budget. Behavior is identical to the\n * deprecated implicit path (which warns once and will be removed at 1.0) —\n * opting in is the forward-stable spelling and the catalog's contract.\n */\nimport type { LazyStrategy } from './strategy.js'\nimport { buildLazyCache } from './strategy.js'\n\nexport function withLazy(): LazyStrategy {\n return {\n createCache(collection, cache) {\n return buildLazyCache(collection, cache)\n },\n }\n}\n"],"mappings":";;;;;AAaO,SAAS,WAAyB;AACvC,SAAO;AAAA,IACL,YAAY,YAAY,OAAO;AAC7B,aAAO,eAAe,YAAY,KAAK;AAAA,IACzC;AAAA,EACF;AACF;","names":[]}
@@ -1,44 +1,49 @@
1
1
  import {
2
2
  openEnvelopeJson
3
- } from "./chunk-5EZAJEES.js";
4
- import {
5
- encrypt
6
- } from "./chunk-L4IRFTIF.js";
3
+ } from "./chunk-OVO2RZAE.js";
7
4
  import {
8
5
  NOYDB_FORMAT_VERSION
9
- } from "./chunk-OCDUQUAP.js";
6
+ } from "./chunk-LN22XH4B.js";
7
+ import {
8
+ encrypt
9
+ } from "./chunk-TLJOJBZD.js";
10
10
 
11
11
  // src/with-shape/persisted-schemas/storage.ts
12
12
  var SCHEMAS_COLLECTION = "_schemas";
13
- async function loadPersistedSchema(store, vault, collection, dek) {
13
+ async function loadPersistedSchemaEntry(store, vault, collection, dek) {
14
14
  const envelope = await store.get(vault, SCHEMAS_COLLECTION, collection);
15
- if (!envelope) return void 0;
15
+ if (!envelope) return { version: 0, payload: void 0 };
16
+ const version = envelope._v;
16
17
  try {
17
18
  const plaintext = await openEnvelopeJson(envelope, dek);
18
19
  const parsed = JSON.parse(plaintext);
19
- if (parsed._noydb_schema !== 1) return void 0;
20
- return parsed;
20
+ if (parsed._noydb_schema !== 1) return { version, payload: void 0 };
21
+ return { version, payload: parsed };
21
22
  } catch {
22
- return void 0;
23
+ return { version, payload: void 0 };
23
24
  }
24
25
  }
25
- async function savePersistedSchema(store, vault, collection, dek, payload) {
26
+ async function loadPersistedSchema(store, vault, collection, dek) {
27
+ return (await loadPersistedSchemaEntry(store, vault, collection, dek)).payload;
28
+ }
29
+ async function savePersistedSchema(store, vault, collection, dek, payload, expectedVersion) {
26
30
  const json = JSON.stringify(payload);
27
31
  const { iv, data } = await encrypt(json, dek);
28
- const prior = await store.get(vault, SCHEMAS_COLLECTION, collection);
32
+ const baseVersion = expectedVersion ?? (await store.get(vault, SCHEMAS_COLLECTION, collection))?._v ?? 0;
29
33
  const env = {
30
34
  _noydb: NOYDB_FORMAT_VERSION,
31
- _v: (prior?._v ?? 0) + 1,
35
+ _v: baseVersion + 1,
32
36
  _ts: (/* @__PURE__ */ new Date()).toISOString(),
33
37
  _iv: iv,
34
38
  _data: data
35
39
  };
36
- await store.put(vault, SCHEMAS_COLLECTION, collection, env);
40
+ await store.put(vault, SCHEMAS_COLLECTION, collection, env, expectedVersion);
37
41
  }
38
42
 
39
43
  export {
40
44
  SCHEMAS_COLLECTION,
45
+ loadPersistedSchemaEntry,
41
46
  loadPersistedSchema,
42
47
  savePersistedSchema
43
48
  };
44
- //# sourceMappingURL=chunk-U6OM4E67.js.map
49
+ //# sourceMappingURL=chunk-TL7QR5T6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-shape/persisted-schemas/storage.ts"],"sourcesContent":["/**\n * Read / write the per-collection persisted-schema envelope. Mirrors the\n * standard noy-db record envelope shape and is **AES-GCM encrypted with\n * the collection's DEK** — the schema body (field names, enum values,\n * constraints) is sensitive metadata, so it gets the same encryption\n * envelope as the records it describes.\n *\n * Storage layout:\n *\n * <vault>/_schemas/<collection> → EncryptedEnvelope\n *\n * The DEK passed to {@link savePersistedSchema} / {@link loadPersistedSchema}\n * is the same key the collection uses for its records.\n *\n * @module\n */\n\nimport { encrypt, openEnvelopeJson, type EnclaveKey } from '../../kernel/enclave/index.js'\nimport { NOYDB_FORMAT_VERSION } from '../../kernel/types.js'\nimport type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js'\nimport type { PersistedSchemaEnvelope } from './types.js'\n\n/** Reserved collection name where persisted schemas live. */\nexport const SCHEMAS_COLLECTION = '_schemas' as const\n\n/**\n * A decrypted persisted-schema read paired with the wrapping envelope's\n * `_v`. The version is the optimistic-concurrency token: pass it back to\n * {@link savePersistedSchema} as `expectedVersion` to make the write a CAS\n * that rejects a stale put (see #583 — the `_schemas` record is shared by\n * the JSON-Schema writer and the classified-marker writer).\n */\nexport interface PersistedSchemaEntry {\n /** Wrapping envelope `_v` (0 when no record exists yet). */\n readonly version: number\n /** Decrypted payload, or `undefined` when absent/corrupt/wrong-DEK. */\n readonly payload: PersistedSchemaEnvelope | undefined\n}\n\n/**\n * Read the persisted-schema envelope for one collection together with its\n * wrapping `_v`. The version reflects the raw stored envelope even when the\n * payload cannot be decrypted/parsed (so a CAS still guards a corrupt record\n * rather than silently clobbering it).\n */\nexport async function loadPersistedSchemaEntry(\n store: NoydbStore,\n vault: string,\n collection: string,\n dek: EnclaveKey,\n): Promise<PersistedSchemaEntry> {\n const envelope = await store.get(vault, SCHEMAS_COLLECTION, collection)\n if (!envelope) return { version: 0, payload: undefined }\n const version = envelope._v\n try {\n const plaintext = await openEnvelopeJson(envelope, dek)\n const parsed = JSON.parse(plaintext) as PersistedSchemaEnvelope\n if (parsed._noydb_schema !== 1) return { version, payload: undefined }\n return { version, payload: parsed }\n } catch {\n return { version, payload: undefined }\n }\n}\n\n/**\n * Read and decrypt the persisted-schema envelope for one collection.\n * Returns `undefined` when no envelope has been written or when decryption\n * fails (e.g. wrong DEK passed). Tolerates corrupted records — JSON parse\n * failures surface as `undefined`, mirroring `_meta/handle`'s contract.\n */\nexport async function loadPersistedSchema(\n store: NoydbStore,\n vault: string,\n collection: string,\n dek: EnclaveKey,\n): Promise<PersistedSchemaEnvelope | undefined> {\n return (await loadPersistedSchemaEntry(store, vault, collection, dek)).payload\n}\n\n/**\n * Encrypt and persist a schema envelope for one collection. Always\n * overwrites any prior write (callers gate on hash equality before calling\n * to avoid no-op writes).\n *\n * Pass `expectedVersion` — the `version` from {@link loadPersistedSchemaEntry}\n * captured at load time — to make the write an optimistic CAS: on a store with\n * `casAtomic`, `store.put` throws {@link ConflictError} when the record was\n * bumped concurrently, so a lost update on the shared `_schemas` record is\n * rejected instead of silently clobbering the other writer's field (#583).\n * When omitted, keeps the legacy unconditional last-writer-wins behaviour.\n */\nexport async function savePersistedSchema(\n store: NoydbStore,\n vault: string,\n collection: string,\n dek: EnclaveKey,\n payload: PersistedSchemaEnvelope,\n expectedVersion?: number,\n): Promise<void> {\n const json = JSON.stringify(payload)\n const { iv, data } = await encrypt(json, dek)\n const baseVersion = expectedVersion ?? (await store.get(vault, SCHEMAS_COLLECTION, collection))?._v ?? 0\n const env: EncryptedEnvelope = {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: baseVersion + 1,\n _ts: new Date().toISOString(),\n _iv: iv,\n _data: data,\n }\n await store.put(vault, SCHEMAS_COLLECTION, collection, env, expectedVersion)\n}\n"],"mappings":";;;;;;;;;;;AAuBO,IAAM,qBAAqB;AAsBlC,eAAsB,yBACpB,OACA,OACA,YACA,KAC+B;AAC/B,QAAM,WAAW,MAAM,MAAM,IAAI,OAAO,oBAAoB,UAAU;AACtE,MAAI,CAAC,SAAU,QAAO,EAAE,SAAS,GAAG,SAAS,OAAU;AACvD,QAAM,UAAU,SAAS;AACzB,MAAI;AACF,UAAM,YAAY,MAAM,iBAAiB,UAAU,GAAG;AACtD,UAAM,SAAS,KAAK,MAAM,SAAS;AACnC,QAAI,OAAO,kBAAkB,EAAG,QAAO,EAAE,SAAS,SAAS,OAAU;AACrE,WAAO,EAAE,SAAS,SAAS,OAAO;AAAA,EACpC,QAAQ;AACN,WAAO,EAAE,SAAS,SAAS,OAAU;AAAA,EACvC;AACF;AAQA,eAAsB,oBACpB,OACA,OACA,YACA,KAC8C;AAC9C,UAAQ,MAAM,yBAAyB,OAAO,OAAO,YAAY,GAAG,GAAG;AACzE;AAcA,eAAsB,oBACpB,OACA,OACA,YACA,KACA,SACA,iBACe;AACf,QAAM,OAAO,KAAK,UAAU,OAAO;AACnC,QAAM,EAAE,IAAI,KAAK,IAAI,MAAM,QAAQ,MAAM,GAAG;AAC5C,QAAM,cAAc,oBAAoB,MAAM,MAAM,IAAI,OAAO,oBAAoB,UAAU,IAAI,MAAM;AACvG,QAAM,MAAyB;AAAA,IAC7B,QAAQ;AAAA,IACR,IAAI,cAAc;AAAA,IAClB,MAAK,oBAAI,KAAK,GAAE,YAAY;AAAA,IAC5B,KAAK;AAAA,IACL,OAAO;AAAA,EACT;AACA,QAAM,MAAM,IAAI,OAAO,oBAAoB,YAAY,KAAK,eAAe;AAC7E;","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  DecryptionError,
3
3
  InvalidKeyError,
4
4
  TamperedError
5
- } from "./chunk-BLZRNHMG.js";
5
+ } from "./chunk-U23JUUPX.js";
6
6
 
7
7
  // src/kernel/enclave/crypto.ts
8
8
  var PBKDF2_ITERATIONS = 6e5;
@@ -373,24 +373,6 @@ function base64ToBuffer(base64) {
373
373
  return bytes;
374
374
  }
375
375
 
376
- // src/kernel/enclave/record-keys/sealed-slot.ts
377
- function parseSealedSlot(blob) {
378
- const sep = blob.indexOf(":");
379
- return { iv: blob.slice(0, sep), data: blob.slice(sep + 1) };
380
- }
381
- async function dualReadSealedSlot(blob, field, collection, cek, dek) {
382
- const { iv, data } = parseSealedSlot(blob);
383
- if (cek !== void 0) {
384
- try {
385
- const fieldKey2 = await deriveSealedFieldKeyFromCek(cek, collection, field);
386
- return await decrypt(iv, data, fieldKey2);
387
- } catch {
388
- }
389
- }
390
- const fieldKey = await deriveSealedFieldKey(dek, collection, field);
391
- return decrypt(iv, data, fieldKey);
392
- }
393
-
394
376
  export {
395
377
  deriveKey,
396
378
  derivePassphraseKey,
@@ -417,8 +399,6 @@ export {
417
399
  generateIV,
418
400
  generateSalt,
419
401
  bufferToBase64,
420
- base64ToBuffer,
421
- parseSealedSlot,
422
- dualReadSealedSlot
402
+ base64ToBuffer
423
403
  };
424
- //# sourceMappingURL=chunk-L4IRFTIF.js.map
404
+ //# sourceMappingURL=chunk-TLJOJBZD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/kernel/enclave/crypto.ts"],"sourcesContent":["/**\n * Cryptographic primitives — thin wrappers around the Web Crypto API.\n *\n * ## Design principle\n *\n * **Zero npm crypto dependencies.** Every operation uses `globalThis.crypto.subtle`,\n * which is available natively in Node.js ≥ 18, all modern browsers, and\n * Deno/Bun. This avoids supply-chain risk from third-party crypto packages and\n * ensures the library stays auditable.\n *\n * ## Algorithms\n *\n * | Use case | Algorithm | Parameters |\n * |----------|-----------|------------|\n * | Key derivation | PBKDF2-SHA256 | 600,000 iterations, 32-byte salt |\n * | Record encryption | AES-256-GCM | 12-byte random IV per operation |\n * | DEK wrapping | AES-KW (RFC 3394) | 256-bit KEK |\n * | Binary encrypt | AES-256-GCM | same as record encryption |\n * | Integrity | HMAC-SHA256 | for presence channels |\n * | Content hash | SHA-256 | for ledger and bundle integrity |\n *\n * ## Key lifecycle\n *\n * ```\n * passphrase + salt\n * └─► deriveKey() → KEK (CryptoKey, extractable: false)\n * └─► wrapKey() → wrapped DEK bytes [stored in keyring]\n * └─► unwrapKey() → DEK (CryptoKey) [memory only during session]\n * └─► encrypt() / decrypt() → ciphertext / plaintext\n * ```\n *\n * IVs are generated fresh by {@link generateIV} on every encrypt call.\n * Reusing an IV with the same key would break GCM's authentication guarantee —\n * this function should be the only place IVs are produced.\n *\n * @module\n */\n\nimport { DecryptionError, InvalidKeyError, TamperedError } from '../errors.js'\n\n/**\n * **EnclaveKey** — the opaque key type at the enclave seam.\n *\n * In noy-db's reference enclave this is `CryptoKey` (the Web Crypto API's\n * key handle). A fork's enclave redefines this alias to its own key\n * representation (e.g. `type EnclaveKey = null` for a keyless HSM-backed\n * fork) — outside `kernel/enclave/**`, every consumer must treat it as\n * opaque: never construct, inspect, or serialize it directly, only pass it\n * between barrel functions (`encrypt`/`decrypt`/`wrapKey`/`unwrapKey`/…).\n */\nexport type EnclaveKey = CryptoKey\n\nconst PBKDF2_ITERATIONS = 600_000\nconst SALT_BYTES = 32\nconst IV_BYTES = 12\nconst KEY_BITS = 256\n\nconst subtle = globalThis.crypto.subtle\n\n// ─── Key Derivation ────────────────────────────────────────────────────\n\n/** Derive a KEK from a passphrase and salt using PBKDF2-SHA256. */\nexport async function deriveKey(\n passphrase: string,\n salt: Uint8Array,\n): Promise<CryptoKey> {\n const keyMaterial = await subtle.importKey(\n 'raw',\n new TextEncoder().encode(passphrase),\n 'PBKDF2',\n false,\n ['deriveKey'],\n )\n\n return subtle.deriveKey(\n {\n name: 'PBKDF2',\n salt: salt as BufferSource,\n iterations: PBKDF2_ITERATIONS,\n hash: 'SHA-256',\n },\n keyMaterial,\n { name: 'AES-KW', length: KEY_BITS },\n false,\n ['wrapKey', 'unwrapKey'],\n )\n}\n\n/**\n * Which AES algorithm/usage a {@link derivePassphraseKey} result is for:\n * `'aes-kw'` mints a key-wrapping key (`wrapKey`/`unwrapKey`, e.g. for\n * KEK derivation); `'aes-gcm'` mints a direct encrypt/decrypt key (e.g.\n * for the wrap-DEKs primitive in `with-party/team/wrapped-deks.ts`).\n */\nexport type PassphraseKeyUsage = 'aes-kw' | 'aes-gcm'\n\n/**\n * Derive a non-extractable AES key from a passphrase/credential and salt\n * via PBKDF2-SHA256, generalizing {@link deriveKey}'s AES-KW derivation to\n * also cover AES-GCM-usage keys. Callers pin their own `iterations` and\n * `keyUsage` so an existing call site's exact parameters (and thus its\n * derived-key bytes) are preserved verbatim when migrated onto this\n * shared primitive — this is call-site consolidation, not a KDF change.\n */\nexport async function derivePassphraseKey(\n passphrase: string,\n salt: Uint8Array,\n params: { iterations: number; keyUsage: PassphraseKeyUsage },\n): Promise<CryptoKey> {\n const keyMaterial = await subtle.importKey(\n 'raw',\n new TextEncoder().encode(passphrase),\n 'PBKDF2',\n false,\n ['deriveKey'],\n )\n\n return params.keyUsage === 'aes-gcm'\n ? subtle.deriveKey(\n {\n name: 'PBKDF2',\n salt: salt as BufferSource,\n iterations: params.iterations,\n hash: 'SHA-256',\n },\n keyMaterial,\n { name: 'AES-GCM', length: KEY_BITS },\n false,\n ['encrypt', 'decrypt'],\n )\n : subtle.deriveKey(\n {\n name: 'PBKDF2',\n salt: salt as BufferSource,\n iterations: params.iterations,\n hash: 'SHA-256',\n },\n keyMaterial,\n { name: 'AES-KW', length: KEY_BITS },\n false,\n ['wrapKey', 'unwrapKey'],\n )\n}\n\n// ─── DEK Generation ────────────────────────────────────────────────────\n\n/** Generate a random AES-256-GCM data encryption key. */\nexport async function generateDEK(): Promise<CryptoKey> {\n return subtle.generateKey(\n { name: 'AES-GCM', length: KEY_BITS },\n true, // extractable — needed for AES-KW wrapping\n ['encrypt', 'decrypt'],\n )\n}\n\n// ─── Key Wrapping ──────────────────────────────────────────────────────\n\n/** Wrap (encrypt) a DEK with a KEK using AES-KW. Returns base64 string. */\nexport async function wrapKey(dek: CryptoKey, kek: CryptoKey): Promise<string> {\n const wrapped = await subtle.wrapKey('raw', dek, kek, 'AES-KW')\n return bufferToBase64(wrapped)\n}\n\n/** Unwrap (decrypt) a DEK from base64 string using a KEK. */\nexport async function unwrapKey(\n wrappedBase64: string,\n kek: CryptoKey,\n): Promise<CryptoKey> {\n try {\n return await subtle.unwrapKey(\n 'raw',\n base64ToBuffer(wrappedBase64) as BufferSource,\n kek,\n 'AES-KW',\n { name: 'AES-GCM', length: KEY_BITS },\n true,\n ['encrypt', 'decrypt'],\n )\n } catch {\n throw new InvalidKeyError()\n }\n}\n\n// ─── Per-record CEK wrapping ───────────────────────────────────────────\n\n/**\n * Derive a **dedicated** AES-KW wrapping key from a collection/tier DEK via\n * HKDF-SHA256, used to wrap/unwrap a per-record CEK.\n *\n * The collection/tier DEKs are AES-256-**GCM** keys (usages\n * `encrypt`/`decrypt`) and cannot themselves act as an AES-KW KEK. We do NOT\n * re-import the raw DEK bytes directly as an AES-KW key — that would reuse one\n * key across two primitives (AES-GCM for `_det`/presence, AES-KW for CEK\n * wrapping), violating key separation. Instead we HKDF-derive a domain-\n * separated KW key (salt `noydb-cek-wrap`), exactly as `derivePresenceKey`\n * derives a separate presence key. The derivation is deterministic, so\n * wrapping the same CEK under the same DEK always yields identical ciphertext\n * — which is what lets an update reuse a record's stable CEK and produce a\n * byte-identical `_cek`. The KW key is independent of the DEK's GCM key.\n *\n * The DEK must be extractable (it is — `generateDEK`/`unwrapKey` mint\n * extractable keys).\n */\nasync function asKwKey(dek: CryptoKey): Promise<CryptoKey> {\n const rawDek = await subtle.exportKey('raw', dek)\n const hkdfKey = await subtle.importKey('raw', rawDek, 'HKDF', false, ['deriveBits'])\n const salt = new TextEncoder().encode('noydb-cek-wrap')\n const info = new TextEncoder().encode('v1')\n const bits = await subtle.deriveBits(\n { name: 'HKDF', hash: 'SHA-256', salt, info },\n hkdfKey,\n KEY_BITS,\n )\n return subtle.importKey('raw', bits, 'AES-KW', false, ['wrapKey', 'unwrapKey'])\n}\n\n/**\n * AES-KW-wrap a per-record CEK under a collection/tier DEK. Returns base64.\n * Deterministic over `(cek, dek)`.\n */\nexport async function wrapCek(cek: CryptoKey, dek: CryptoKey): Promise<string> {\n const kw = await asKwKey(dek)\n const wrapped = await subtle.wrapKey('raw', cek, kw, 'AES-KW')\n return bufferToBase64(wrapped)\n}\n\n/**\n * Unwrap a per-record CEK from base64 under a collection/tier DEK. Throws\n * `InvalidKeyError` if the wrapped bytes do not authenticate under the DEK.\n */\nexport async function unwrapCek(wrappedBase64: string, dek: CryptoKey): Promise<CryptoKey> {\n const kw = await asKwKey(dek)\n try {\n return await subtle.unwrapKey(\n 'raw',\n base64ToBuffer(wrappedBase64) as BufferSource,\n kw,\n 'AES-KW',\n { name: 'AES-GCM', length: KEY_BITS },\n true,\n ['encrypt', 'decrypt'],\n )\n } catch {\n throw new InvalidKeyError()\n }\n}\n\n/**\n * Import a raw 32-byte AES-256-GCM record CEK (e.g. from a sealed-CEK\n * delivery binding). Non-extractable, decrypt-only — the imported key is\n * used solely to open the record's `_iv`/`_data` body under `decrypt()`.\n */\nexport async function importCek(rawKey: Uint8Array): Promise<CryptoKey> {\n return subtle.importKey('raw', rawKey as BufferSource, { name: 'AES-GCM', length: KEY_BITS }, false, ['decrypt'])\n}\n\n// ─── Encrypt / Decrypt ─────────────────────────────────────────────────\n\nexport interface EncryptResult {\n iv: string // base64\n data: string // base64\n}\n\n/** Encrypt plaintext JSON string with AES-256-GCM. Fresh IV per call. */\nexport async function encrypt(\n plaintext: string,\n dek: CryptoKey,\n): Promise<EncryptResult> {\n const iv = generateIV()\n const encoded = new TextEncoder().encode(plaintext)\n\n const ciphertext = await subtle.encrypt(\n { name: 'AES-GCM', iv: iv as BufferSource },\n dek,\n encoded,\n )\n\n return {\n iv: bufferToBase64(iv),\n data: bufferToBase64(ciphertext),\n }\n}\n\n/** Decrypt AES-256-GCM ciphertext. Throws on wrong key or tampered data. */\nexport async function decrypt(\n ivBase64: string,\n dataBase64: string,\n dek: CryptoKey,\n): Promise<string> {\n const iv = base64ToBuffer(ivBase64)\n const ciphertext = base64ToBuffer(dataBase64)\n\n try {\n const plaintext = await subtle.decrypt(\n { name: 'AES-GCM', iv: iv as BufferSource },\n dek,\n ciphertext as BufferSource,\n )\n return new TextDecoder().decode(plaintext)\n } catch (err) {\n if (err instanceof Error && err.name === 'OperationError') {\n throw new TamperedError()\n }\n throw new DecryptionError(\n err instanceof Error ? err.message : 'Decryption failed',\n )\n }\n}\n\n// ─── Binary Encrypt / Decrypt ────────\n\n/**\n * Encrypt raw bytes with AES-256-GCM using a fresh random IV.\n * Used by the attachment store so binary blobs avoid double base64 encoding\n * (the existing `encrypt()` function calls `TextEncoder` on a string — here\n * we pass the `Uint8Array` directly to `subtle.encrypt`).\n */\nexport async function encryptBytes(\n data: Uint8Array,\n dek: CryptoKey,\n): Promise<EncryptResult> {\n const iv = generateIV()\n const ciphertext = await subtle.encrypt(\n { name: 'AES-GCM', iv: iv as BufferSource },\n dek,\n data as unknown as BufferSource,\n )\n return {\n iv: bufferToBase64(iv),\n data: bufferToBase64(ciphertext),\n }\n}\n\n/**\n * Decrypt AES-256-GCM ciphertext back to raw bytes.\n * Counterpart to `encryptBytes`. Throws `TamperedError` on auth-tag failure.\n */\nexport async function decryptBytes(\n ivBase64: string,\n dataBase64: string,\n dek: CryptoKey,\n): Promise<Uint8Array> {\n const iv = base64ToBuffer(ivBase64)\n const ciphertext = base64ToBuffer(dataBase64)\n try {\n const plaintext = await subtle.decrypt(\n { name: 'AES-GCM', iv: iv as BufferSource },\n dek,\n ciphertext as BufferSource,\n )\n return new Uint8Array(plaintext)\n } catch (err) {\n if (err instanceof Error && err.name === 'OperationError') {\n throw new TamperedError()\n }\n throw new DecryptionError(\n err instanceof Error ? err.message : 'Decryption failed',\n )\n }\n}\n\n/**\n * SHA-256 hex digest of raw bytes. Used to derive content-addressed\n * eTags for blob deduplication. Computed on plaintext bytes\n * before compression and encryption so the eTag identifies content, not\n * ciphertext, and survives re-encryption (key rotation, re-upload).\n */\nexport async function sha256Hex(data: Uint8Array): Promise<string> {\n const hash = await subtle.digest('SHA-256', data as unknown as BufferSource)\n return Array.from(new Uint8Array(hash))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n// ─── HMAC-SHA-256 ─────────────────────────────\n\n/**\n * Compute HMAC-SHA-256(key, data) and return hex string.\n *\n * Used to derive content-addressed eTags that are opaque to the store:\n * ```\n * eTag = hmacSha256Hex(blobDEK, plaintext)\n * ```\n *\n * Unlike a plain SHA-256, the HMAC is keyed by the vault-shared `_blob` DEK,\n * so an attacker with store access cannot pre-compute eTags for known files.\n * Deduplication still works within a vault (same key + same content = same eTag).\n */\nexport async function hmacSha256Hex(key: CryptoKey, data: Uint8Array): Promise<string> {\n // Export AES-GCM DEK raw bytes → import as HMAC key\n const rawKey = await subtle.exportKey('raw', key)\n const hmacKey = await subtle.importKey(\n 'raw',\n rawKey,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n const sig = await subtle.sign('HMAC', hmacKey, data as unknown as BufferSource)\n return Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n// ─── AAD-aware Binary Encrypt / Decrypt ──\n\n/**\n * Encrypt raw bytes with AES-256-GCM using Additional Authenticated Data.\n *\n * The AAD binds each chunk to its parent blob and position, preventing\n * chunk reorder, substitution, and truncation attacks:\n * ```\n * AAD = UTF-8(\"{eTag}:{chunkIndex}:{chunkCount}\")\n * ```\n *\n * The AAD is NOT stored — the reader reconstructs it from `BlobObject`\n * metadata and passes it to `decryptBytesWithAAD`.\n */\nexport async function encryptBytesWithAAD(\n data: Uint8Array,\n dek: CryptoKey,\n aad: Uint8Array,\n): Promise<EncryptResult> {\n const iv = generateIV()\n const ciphertext = await subtle.encrypt(\n {\n name: 'AES-GCM',\n iv: iv as BufferSource,\n additionalData: aad as BufferSource,\n },\n dek,\n data as unknown as BufferSource,\n )\n return {\n iv: bufferToBase64(iv),\n data: bufferToBase64(ciphertext),\n }\n}\n\n/**\n * Decrypt AES-256-GCM ciphertext with AAD verification.\n *\n * If the AAD does not match the one used at encryption time (e.g. because\n * a chunk was reordered or substituted from another blob), the GCM auth\n * tag fails and this throws `TamperedError`.\n */\nexport async function decryptBytesWithAAD(\n ivBase64: string,\n dataBase64: string,\n dek: CryptoKey,\n aad: Uint8Array,\n): Promise<Uint8Array> {\n const iv = base64ToBuffer(ivBase64)\n const ciphertext = base64ToBuffer(dataBase64)\n try {\n const plaintext = await subtle.decrypt(\n {\n name: 'AES-GCM',\n iv: iv as BufferSource,\n additionalData: aad as BufferSource,\n },\n dek,\n ciphertext as BufferSource,\n )\n return new Uint8Array(plaintext)\n } catch (err) {\n if (err instanceof Error && err.name === 'OperationError') {\n throw new TamperedError()\n }\n throw new DecryptionError(\n err instanceof Error ? err.message : 'Decryption failed',\n )\n }\n}\n\n// ─── Presence Key Derivation ──────────────────────────────\n\n/**\n * Derive an AES-256-GCM presence key from a collection DEK using HKDF-SHA256.\n *\n * The presence key is domain-separated from the data DEK by the fixed salt\n * `'noydb-presence'` and the `info` = collection name. This means:\n * - The adapter never sees the presence key.\n * - Presence payloads rotate automatically when the collection DEK is rotated.\n * - Revoked users cannot derive the new presence key after a DEK rotation.\n *\n * @param dek The collection's AES-256-GCM DEK (extractable).\n * @param collectionName Used as the HKDF `info` parameter for domain separation.\n * @returns A non-extractable AES-256-GCM key suitable for presence payload encryption.\n */\nexport async function derivePresenceKey(dek: CryptoKey, collectionName: string): Promise<CryptoKey> {\n // Step 1: export DEK raw bytes\n const rawDek = await subtle.exportKey('raw', dek)\n\n // Step 2: import as HKDF key material\n const hkdfKey = await subtle.importKey(\n 'raw',\n rawDek,\n 'HKDF',\n false,\n ['deriveBits'],\n )\n\n // Step 3: derive 256 bits with salt='noydb-presence' and info=collectionName\n const salt = new TextEncoder().encode('noydb-presence')\n const info = new TextEncoder().encode(collectionName)\n const bits = await subtle.deriveBits(\n { name: 'HKDF', hash: 'SHA-256', salt, info },\n hkdfKey,\n KEY_BITS,\n )\n\n // Step 4: import derived bits as AES-GCM key\n return subtle.importKey(\n 'raw',\n bits,\n { name: 'AES-GCM', length: KEY_BITS },\n false,\n ['encrypt', 'decrypt'],\n )\n}\n\n// ─── Sealed Field Key Derivation ──────────────────────────\n\n/**\n * Derive a **per-field** AES-256-GCM key from a collection DEK using\n * HKDF-SHA256, used to encrypt a single sensitive field into its own\n * `_sealed[field]` envelope slot (structural group-encryption).\n *\n * Domain-separated from the data DEK (and from the presence/deterministic\n * channels) by the fixed salt `'noydb-sealed'` and an `info` of\n * `JSON.stringify(['noydb-sealed', collectionName, field])`. The JSON-array\n * encoding is injective — each element is separately quoted/escaped — so\n * collection `a/sealed/b` + field `c` cannot collide with collection `a` +\n * field `b/sealed/c`. Each sensitive field gets a **distinct** key, so a\n * `_sealed[a]` ciphertext does not authenticate under field `b`'s key —\n * sealed fields are cryptographically isolated from one another. The\n * collection name keeps the same field name in two collections from sharing a\n * key, mirroring how `derivePresenceKey` / `encryptDeterministic` domain-separate.\n *\n * @param dek The collection's AES-256-GCM DEK (extractable).\n * @param collectionName Part of the HKDF `info` for domain separation.\n * @param field Sensitive field name — the rest of the `info`.\n * @returns A non-extractable AES-256-GCM key for that field's sealed slot.\n */\nexport async function deriveSealedFieldKey(\n dek: CryptoKey,\n collectionName: string,\n field: string,\n): Promise<CryptoKey> {\n const rawDek = await subtle.exportKey('raw', dek)\n const hkdfKey = await subtle.importKey('raw', rawDek, 'HKDF', false, ['deriveBits'])\n const salt = new TextEncoder().encode('noydb-sealed')\n // JSON-array encoding is injective: each element is separately quoted/\n // escaped, so collection `a/sealed/b` + field `c` cannot collide with\n // collection `a` + field `b/sealed/c`.\n const info = new TextEncoder().encode(JSON.stringify(['noydb-sealed', collectionName, field]))\n const bits = await subtle.deriveBits(\n { name: 'HKDF', hash: 'SHA-256', salt, info },\n hkdfKey,\n KEY_BITS,\n )\n return subtle.importKey(\n 'raw',\n bits,\n { name: 'AES-GCM', length: KEY_BITS },\n false,\n ['encrypt', 'decrypt'],\n )\n}\n\n/**\n * Derive a per-record sealed-field key from the record's **per-record CEK**\n * rather than the collection DEK. Same HKDF construction as\n * {@link deriveSealedFieldKey} but with salt `'noydb-sealed-cek'` (distinct\n * from `'noydb-sealed'`), so a CEK-derived key can never collide with a\n * DEK-derived one for the same `{collection, field}`.\n *\n * The point: the sealed ciphertext's only key now flows from the record's CEK.\n * Dropping the record's wrapped `_cek` (crypto-shred / `forget`) makes the key\n * — and thus `_sealed[field]` — unrecoverable, giving sealed fields the same\n * erasure guarantee `_data` already has. The CEK must be extractable (it is —\n * `unwrapCek`/`generateDEK` mint extractable keys).\n *\n * @param cek The record's AES-256-GCM CEK (extractable).\n * @param collectionName Part of the HKDF `info` for domain separation.\n * @param field Sensitive field name — the rest of the `info`.\n * @returns A non-extractable AES-256-GCM key for that field's sealed slot.\n */\nexport async function deriveSealedFieldKeyFromCek(\n cek: CryptoKey,\n collectionName: string,\n field: string,\n): Promise<CryptoKey> {\n const rawCek = await subtle.exportKey('raw', cek)\n const hkdfKey = await subtle.importKey('raw', rawCek, 'HKDF', false, ['deriveBits'])\n const salt = new TextEncoder().encode('noydb-sealed-cek')\n const info = new TextEncoder().encode(JSON.stringify(['noydb-sealed-cek', collectionName, field]))\n const bits = await subtle.deriveBits(\n { name: 'HKDF', hash: 'SHA-256', salt, info },\n hkdfKey,\n KEY_BITS,\n )\n return subtle.importKey(\n 'raw',\n bits,\n { name: 'AES-GCM', length: KEY_BITS },\n false,\n ['encrypt', 'decrypt'],\n )\n}\n\n// ─── Deterministic Encryption ────────────────────────────\n\n/**\n * Derive the collection's **dedicated deterministic-index key** from its DEK\n * via HKDF-SHA256 (L-1, #554).\n *\n * `_det` slots previously encrypted under the raw collection DEK — the same\n * key `_data` uses with a *randomized*-IV regime while `_det` uses a\n * *deterministic*-IV regime. Two IV regimes on one key is avoidable hygiene\n * debt (~2^-96 theoretical collision), so the deterministic index now gets its\n * own HKDF-separated key: salt `'noydb-det'`, info\n * `JSON.stringify(['noydb-det'])` (the injective JSON-array domain tag, same\n * convention as {@link deriveSealedFieldKey}). Per-field separation still\n * comes from the `'<collection>/<field>'` context inside\n * {@link encryptDeterministic}, exactly as before.\n *\n * The derived key stays **DEK-derived (collection-level)** on purpose: `_det`\n * is carried verbatim through per-record CEK rotation (see\n * `record-keys/sealing.ts`), so its key must not depend on the CEK. It rotates\n * with the collection DEK, like the presence key.\n *\n * The key is minted **extractable** — {@link encryptDeterministic} derives its\n * per-value IV via HKDF over the raw key bytes (an `exportKey` under the\n * hood), which a non-extractable key would forbid. Same in-memory posture as\n * the DEK itself (`generateDEK` mints extractable keys).\n *\n * @param dek The collection's AES-256-GCM DEK (extractable).\n * @returns A dedicated AES-256-GCM key for the `_det` deterministic index.\n */\nexport async function deriveDeterministicKey(dek: CryptoKey): Promise<CryptoKey> {\n const rawDek = await subtle.exportKey('raw', dek)\n const hkdfKey = await subtle.importKey('raw', rawDek, 'HKDF', false, ['deriveBits'])\n const salt = new TextEncoder().encode('noydb-det')\n const info = new TextEncoder().encode(JSON.stringify(['noydb-det']))\n const bits = await subtle.deriveBits(\n { name: 'HKDF', hash: 'SHA-256', salt, info },\n hkdfKey,\n KEY_BITS,\n )\n return subtle.importKey(\n 'raw',\n bits,\n { name: 'AES-GCM', length: KEY_BITS },\n true,\n ['encrypt', 'decrypt'],\n )\n}\n\n/**\n * Derive a deterministic 12-byte IV from `{ DEK, context, plaintext }`\n * via HKDF-SHA256. Given the same three inputs, the IV is identical, so\n * `encryptDeterministic` produces the same ciphertext on every call —\n * which is precisely what enables blind equality search on encrypted\n * fields.\n *\n * **The side channel this opens.** Two records whose field value is the\n * same produce the same ciphertext. An observer with store access can\n * therefore tell which records share a value — not *what* the value is,\n * but the equivalence class. This is the well-known trade-off of\n * deterministic encryption and is why the feature is strictly opt-in\n * per field, guarded by `acknowledgeDeterministicRisk: true` at\n * collection creation.\n *\n * The context string MUST include the collection name and field name,\n * so:\n * - The same plaintext in two different fields encrypts differently\n * (no cross-field equality leak).\n * - The same plaintext in two different collections (different DEKs)\n * encrypts differently by virtue of the key, even before HKDF\n * domain separation kicks in.\n */\nasync function deriveDeterministicIV(\n dek: CryptoKey,\n context: string,\n plaintext: string,\n): Promise<Uint8Array> {\n const rawDek = await subtle.exportKey('raw', dek)\n const hkdfKey = await subtle.importKey('raw', rawDek, 'HKDF', false, ['deriveBits'])\n const salt = new TextEncoder().encode('noydb-deterministic-v1')\n const info = new TextEncoder().encode(`${context}\\x00${plaintext}`)\n const bits = await subtle.deriveBits(\n { name: 'HKDF', hash: 'SHA-256', salt, info },\n hkdfKey,\n IV_BYTES * 8,\n )\n return new Uint8Array(bits)\n}\n\n/**\n * Encrypt a plaintext string with AES-256-GCM and a deterministic,\n * HKDF-derived IV.\n *\n * The same `{ dek, context, plaintext }` triple always produces the\n * same `{ iv, data }` — call this twice and you can string-compare the\n * ciphertexts to check equality of the inputs without decrypting them.\n *\n * @param context Domain-separation string — by convention\n * `'<collection>/<field>'`. Different contexts encrypt\n * the same plaintext to different ciphertexts, so\n * `email` in collection `users` does not collide with\n * `email` in collection `customers`.\n */\nexport async function encryptDeterministic(\n plaintext: string,\n dek: CryptoKey,\n context: string,\n): Promise<EncryptResult> {\n const iv = await deriveDeterministicIV(dek, context, plaintext)\n const encoded = new TextEncoder().encode(plaintext)\n const ciphertext = await subtle.encrypt(\n { name: 'AES-GCM', iv: iv as BufferSource },\n dek,\n encoded,\n )\n return {\n iv: bufferToBase64(iv),\n data: bufferToBase64(ciphertext),\n }\n}\n\n/**\n * Counterpart to {@link encryptDeterministic}. The IV is stored\n * alongside the ciphertext (exactly like the randomized path), so\n * decrypt uses the stored IV and verifies the GCM auth tag — a tampered\n * ciphertext throws `TamperedError` just like randomized AES-GCM.\n */\nexport async function decryptDeterministic(\n ivBase64: string,\n dataBase64: string,\n dek: CryptoKey,\n): Promise<string> {\n return decrypt(ivBase64, dataBase64, dek)\n}\n\n// ─── Random Generation ─────────────────────────────────────────────────\n\n/** Generate a random 12-byte IV for AES-GCM. */\nexport function generateIV(): Uint8Array {\n return globalThis.crypto.getRandomValues(new Uint8Array(IV_BYTES))\n}\n\n/** Generate a random 32-byte salt for PBKDF2. */\nexport function generateSalt(): Uint8Array {\n return globalThis.crypto.getRandomValues(new Uint8Array(SALT_BYTES))\n}\n\n// ─── Base64 Helpers ────────────────────────────────────────────────────\n\nexport function bufferToBase64(buffer: ArrayBuffer | Uint8Array): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer)\n let binary = ''\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]!)\n }\n return btoa(binary)\n}\n\nexport function base64ToBuffer(base64: string): Uint8Array<ArrayBuffer> {\n const binary = atob(base64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return bytes\n}\n"],"mappings":"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","names":[]}