@noy-db/hub 0.2.0-pre.16 → 0.2.0-pre.18

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 (306) hide show
  1. package/dist/aggregate/index.cjs.map +1 -1
  2. package/dist/aggregate/index.d.cts +3 -2
  3. package/dist/aggregate/index.d.ts +3 -2
  4. package/dist/aggregate/index.js +4 -4
  5. package/dist/attestation/index.cjs.map +1 -1
  6. package/dist/attestation/index.d.cts +5 -3
  7. package/dist/attestation/index.d.ts +5 -3
  8. package/dist/attestation/index.js +6 -6
  9. package/dist/blobs/index.cjs +226 -11
  10. package/dist/blobs/index.cjs.map +1 -1
  11. package/dist/blobs/index.d.cts +6 -4
  12. package/dist/blobs/index.d.ts +6 -4
  13. package/dist/blobs/index.js +6 -5
  14. package/dist/blobs/index.js.map +1 -1
  15. package/dist/bundle/index.cjs +2065 -352
  16. package/dist/bundle/index.cjs.map +1 -1
  17. package/dist/bundle/index.d.cts +7 -5
  18. package/dist/bundle/index.d.ts +7 -5
  19. package/dist/bundle/index.js +21 -10
  20. package/dist/bundle/index.js.map +1 -1
  21. package/dist/{chunk-6RR3MNMG.js → chunk-2U226RDC.js} +3 -3
  22. package/dist/{chunk-L2BNJ6HM.js → chunk-32XVU2LT.js} +3 -3
  23. package/dist/{chunk-X73VS74Y.js → chunk-33DAO2XG.js} +2 -2
  24. package/dist/chunk-45643PAU.js +151 -0
  25. package/dist/chunk-45643PAU.js.map +1 -0
  26. package/dist/{chunk-QSUK7YWK.js → chunk-4UI5T3K7.js} +4 -4
  27. package/dist/{chunk-G4SCICH5.js → chunk-5KKNBDCT.js} +2 -2
  28. package/dist/{chunk-DUREQF5W.js → chunk-647TFNYL.js} +34 -8
  29. package/dist/chunk-647TFNYL.js.map +1 -0
  30. package/dist/{chunk-E2CDVKMH.js → chunk-6FHCU3QO.js} +5 -5
  31. package/dist/{chunk-F4OJZIWQ.js → chunk-6Q5XRLKG.js} +4 -4
  32. package/dist/{chunk-HOR4R722.js → chunk-6XEGHIBA.js} +30 -4
  33. package/dist/chunk-6XEGHIBA.js.map +1 -0
  34. package/dist/{chunk-4TBBMHVC.js → chunk-6YEC7LLO.js} +2 -2
  35. package/dist/{chunk-ZNQYHJXX.js → chunk-AB7JF2KF.js} +2 -2
  36. package/dist/{chunk-UMLVJTYV.js → chunk-ADB7GPM3.js} +7 -4
  37. package/dist/chunk-ADB7GPM3.js.map +1 -0
  38. package/dist/{chunk-XL35NSEN.js → chunk-BUBJYIZ7.js} +3 -3
  39. package/dist/chunk-C2OYWD5S.js +125 -0
  40. package/dist/chunk-C2OYWD5S.js.map +1 -0
  41. package/dist/{chunk-KABJXG2F.js → chunk-CMISAJAE.js} +195 -17
  42. package/dist/chunk-CMISAJAE.js.map +1 -0
  43. package/dist/{chunk-3YWP3WBP.js → chunk-DKMPR76W.js} +5 -5
  44. package/dist/{chunk-BI6ETQPF.js → chunk-DR5I7Q6N.js} +4 -4
  45. package/dist/{chunk-667MB6AH.js → chunk-F2IJ2HGD.js} +1370 -232
  46. package/dist/chunk-F2IJ2HGD.js.map +1 -0
  47. package/dist/{chunk-6H2ZUNR7.js → chunk-FQRAYDS4.js} +4 -4
  48. package/dist/{chunk-535SSHBS.js → chunk-HMFC6M2G.js} +99 -2
  49. package/dist/chunk-HMFC6M2G.js.map +1 -0
  50. package/dist/{chunk-TS26M2SB.js → chunk-HOO5I3VG.js} +2 -2
  51. package/dist/{chunk-OMAMZKKD.js → chunk-HWK75CYX.js} +2 -2
  52. package/dist/{chunk-TKIY625R.js → chunk-HZOEBM67.js} +2 -2
  53. package/dist/{chunk-DLZ2ONOD.js → chunk-IQ4GMEYZ.js} +6 -6
  54. package/dist/{chunk-XWH4MXIU.js → chunk-K3NYRK7U.js} +2 -2
  55. package/dist/{chunk-7BQ4QWYX.js → chunk-KOURQXIU.js} +23 -6
  56. package/dist/chunk-KOURQXIU.js.map +1 -0
  57. package/dist/{chunk-7Z7KSVA5.js → chunk-KQ523X3A.js} +15 -2
  58. package/dist/chunk-KQ523X3A.js.map +1 -0
  59. package/dist/{chunk-JD3OZAI4.js → chunk-KTZ2MHQK.js} +2 -2
  60. package/dist/{chunk-F3BPIPLS.js → chunk-LGPSCKWZ.js} +1 -1
  61. package/dist/chunk-LGPSCKWZ.js.map +1 -0
  62. package/dist/{chunk-SCJPI4Z5.js → chunk-LQ3GD5LL.js} +5 -5
  63. package/dist/{chunk-AAVWKNZW.js → chunk-M3H7VSRV.js} +2 -2
  64. package/dist/{chunk-BR3AMFGS.js → chunk-MGB67HKX.js} +5 -5
  65. package/dist/{chunk-GNI5STXQ.js → chunk-P57D4KBG.js} +52 -38
  66. package/dist/chunk-P57D4KBG.js.map +1 -0
  67. package/dist/{chunk-Z6FNBOTC.js → chunk-PDVP3C2I.js} +1 -1
  68. package/dist/{chunk-Z6FNBOTC.js.map → chunk-PDVP3C2I.js.map} +1 -1
  69. package/dist/{chunk-OB2ZJQ2D.js → chunk-PGVEL5IZ.js} +3 -3
  70. package/dist/{chunk-YULZKK4F.js → chunk-QJKZ5WUP.js} +37 -2
  71. package/dist/chunk-QJKZ5WUP.js.map +1 -0
  72. package/dist/{chunk-BQ65SS5A.js → chunk-QPJ7Z4L3.js} +2 -2
  73. package/dist/{chunk-CZI2A4MQ.js → chunk-RQFG2YSV.js} +3 -3
  74. package/dist/{chunk-CJORTUJ2.js → chunk-RZWQNMMP.js} +2 -2
  75. package/dist/{chunk-FFXM3ZIF.js → chunk-T4T5I5L6.js} +3 -3
  76. package/dist/{chunk-QVIEAYTP.js → chunk-TFAN3NFD.js} +3 -3
  77. package/dist/{chunk-Z4DO7YSI.js → chunk-TPOHMOGX.js} +2 -2
  78. package/dist/{chunk-VLMPU56Q.js → chunk-TTS3RWL5.js} +2 -2
  79. package/dist/{chunk-IXBIFDEW.js → chunk-VVDSDOVV.js} +4 -4
  80. package/dist/{chunk-FWPKCXTN.js → chunk-WZCG3EZ6.js} +2 -2
  81. package/dist/{chunk-HBXJ37ZY.js → chunk-Y5XVB75E.js} +4 -4
  82. package/dist/chunk-YWYW2YNO.js +129 -0
  83. package/dist/chunk-YWYW2YNO.js.map +1 -0
  84. package/dist/{chunk-IQLVUT37.js → chunk-Z3BE5BRK.js} +2 -2
  85. package/dist/{chunk-42FEUPZQ.js → chunk-Z3I2WNGF.js} +58 -3
  86. package/dist/chunk-Z3I2WNGF.js.map +1 -0
  87. package/dist/{state-vault-TMXZRTY5.js → chunk-ZJ67TB4S.js} +24 -7
  88. package/dist/chunk-ZJ67TB4S.js.map +1 -0
  89. package/dist/consent/index.cjs.map +1 -1
  90. package/dist/consent/index.d.cts +6 -4
  91. package/dist/consent/index.d.ts +6 -4
  92. package/dist/consent/index.js +3 -3
  93. package/dist/{crypto-QXQOHMHF.js → crypto-FNK3XPCS.js} +7 -3
  94. package/dist/{delegation-NIQ43IPU.js → delegation-FMXNUWE6.js} +5 -5
  95. package/dist/derivations/index.cjs +82 -2
  96. package/dist/derivations/index.cjs.map +1 -1
  97. package/dist/derivations/index.d.cts +7 -5
  98. package/dist/derivations/index.d.ts +7 -5
  99. package/dist/derivations/index.js +8 -6
  100. package/dist/{dev-unlock-8XzcD2Z4.d.cts → dev-unlock-3_2b_vo6.d.cts} +1 -1
  101. package/dist/{dev-unlock-DR3upLd1.d.ts → dev-unlock-BMvwPr_E.d.ts} +1 -1
  102. package/dist/{strategy-BtW8fAjz.d.cts → errors-DUTlAt3Y.d.cts} +113 -727
  103. package/dist/{strategy-BtW8fAjz.d.ts → errors-DUTlAt3Y.d.ts} +113 -727
  104. package/dist/executor-IZ2NVXCY.js +11 -0
  105. package/dist/executor-THSEYEJG.js +8 -0
  106. package/dist/executor-WLFDUTOM.js +8 -0
  107. package/dist/{fanout-sidecar-67CMI3UT.js → fanout-sidecar-JGHXAJO5.js} +2 -2
  108. package/dist/forget/index.cjs +43 -0
  109. package/dist/forget/index.cjs.map +1 -0
  110. package/dist/forget/index.d.cts +1 -0
  111. package/dist/forget/index.d.ts +1 -0
  112. package/dist/forget/index.js +14 -0
  113. package/dist/guards/index.cjs +80 -3
  114. package/dist/guards/index.cjs.map +1 -1
  115. package/dist/guards/index.d.cts +7 -5
  116. package/dist/guards/index.d.ts +7 -5
  117. package/dist/guards/index.js +10 -6
  118. package/dist/{hash-CDjye9KV.d.ts → hash-BThBJFO1.d.ts} +1 -1
  119. package/dist/{hash-DuQ88_5W.d.cts → hash-BnWnL9bQ.d.cts} +1 -1
  120. package/dist/history/index.cjs +27 -4
  121. package/dist/history/index.cjs.map +1 -1
  122. package/dist/history/index.d.cts +7 -5
  123. package/dist/history/index.d.ts +7 -5
  124. package/dist/history/index.js +9 -7
  125. package/dist/history/index.js.map +1 -1
  126. package/dist/i18n/index.cjs +53 -0
  127. package/dist/i18n/index.cjs.map +1 -1
  128. package/dist/i18n/index.d.cts +6 -4
  129. package/dist/i18n/index.d.ts +6 -4
  130. package/dist/i18n/index.js +16 -8
  131. package/dist/i18n/index.js.map +1 -1
  132. package/dist/index-C-SSRIxP.d.cts +348 -0
  133. package/dist/index-C-SSRIxP.d.ts +348 -0
  134. package/dist/{index-C8Bk3-VF.d.cts → index-C6lgoUhK.d.cts} +47 -2
  135. package/dist/{index-nP99bXLg.d.ts → index-DP1JTWHZ.d.ts} +47 -2
  136. package/dist/index.cjs +3280 -1208
  137. package/dist/index.cjs.map +1 -1
  138. package/dist/index.d.cts +15 -12
  139. package/dist/index.d.ts +15 -12
  140. package/dist/index.js +149 -107
  141. package/dist/index.js.map +1 -1
  142. package/dist/indexing/index.cjs.map +1 -1
  143. package/dist/indexing/index.js +4 -4
  144. package/dist/issue-R2MWQO6K.js +12 -0
  145. package/dist/{ledger-A3LL253R.js → ledger-GXC2YA3A.js} +6 -6
  146. package/dist/materialized-views/index.cjs.map +1 -1
  147. package/dist/materialized-views/index.d.cts +7 -5
  148. package/dist/materialized-views/index.d.ts +7 -5
  149. package/dist/materialized-views/index.js +12 -12
  150. package/dist/noydb-RJL6FQ4B.js +37 -0
  151. package/dist/overlay-views/index.cjs.map +1 -1
  152. package/dist/overlay-views/index.d.cts +7 -5
  153. package/dist/overlay-views/index.d.ts +7 -5
  154. package/dist/overlay-views/index.js +4 -4
  155. package/dist/periods/index.cjs.map +1 -1
  156. package/dist/periods/index.d.cts +6 -4
  157. package/dist/periods/index.d.ts +6 -4
  158. package/dist/periods/index.js +6 -6
  159. package/dist/{public-envelope-YP2UWMLG.js → public-envelope-HXOFHY4N.js} +4 -4
  160. package/dist/query/index.cjs +30 -4
  161. package/dist/query/index.cjs.map +1 -1
  162. package/dist/query/index.d.cts +3 -2
  163. package/dist/query/index.d.ts +3 -2
  164. package/dist/query/index.js +6 -6
  165. package/dist/read-only-facade-EX6WZZBP.js +7 -0
  166. package/dist/registry-3T2RZC5A.js +8 -0
  167. package/dist/registry-DMS7OKBM.js +8 -0
  168. package/dist/{registry-UTA4CLQS.js → registry-WVXO6NH5.js} +3 -3
  169. package/dist/{revoke-HNMQZSCL.js → revoke-7LCWE2AH.js} +6 -6
  170. package/dist/sealed-record/index.cjs +139 -0
  171. package/dist/sealed-record/index.cjs.map +1 -0
  172. package/dist/sealed-record/index.d.cts +123 -0
  173. package/dist/sealed-record/index.d.ts +123 -0
  174. package/dist/sealed-record/index.js +42 -0
  175. package/dist/sealed-record/index.js.map +1 -0
  176. package/dist/session/index.cjs.map +1 -1
  177. package/dist/session/index.d.cts +7 -5
  178. package/dist/session/index.d.ts +7 -5
  179. package/dist/session/index.js +3 -3
  180. package/dist/shadow/index.cjs.map +1 -1
  181. package/dist/shadow/index.d.cts +6 -4
  182. package/dist/shadow/index.d.ts +6 -4
  183. package/dist/shadow/index.js +2 -2
  184. package/dist/{signer-DCMNKXSF.js → signer-HAVDLGOK.js} +5 -5
  185. package/dist/snapshots/index.cjs.map +1 -1
  186. package/dist/snapshots/index.d.cts +6 -4
  187. package/dist/snapshots/index.d.ts +6 -4
  188. package/dist/snapshots/index.js +4 -4
  189. package/dist/{stale-W5PQTRYH.js → stale-PGTEGJDI.js} +2 -2
  190. package/dist/stale-PGTEGJDI.js.map +1 -0
  191. package/dist/state-vault-QKQKN3H3.js +14 -0
  192. package/dist/state-vault-QKQKN3H3.js.map +1 -0
  193. package/dist/store/index.cjs.map +1 -1
  194. package/dist/store/index.d.cts +6 -4
  195. package/dist/store/index.d.ts +6 -4
  196. package/dist/store/index.js +2 -2
  197. package/dist/strategy-Diwh5lzS.d.ts +739 -0
  198. package/dist/strategy-nuyN8K5N.d.cts +739 -0
  199. package/dist/sync/index.cjs.map +1 -1
  200. package/dist/sync/index.d.cts +5 -3
  201. package/dist/sync/index.d.ts +5 -3
  202. package/dist/sync/index.js +4 -4
  203. package/dist/team/index.cjs.map +1 -1
  204. package/dist/team/index.d.cts +6 -4
  205. package/dist/team/index.d.ts +6 -4
  206. package/dist/team/index.js +8 -8
  207. package/dist/transition-guard--t3exQHF.d.cts +165 -0
  208. package/dist/transition-guard-BlI9Oy5K.d.ts +165 -0
  209. package/dist/tx/index.cjs.map +1 -1
  210. package/dist/tx/index.d.cts +6 -4
  211. package/dist/tx/index.d.ts +6 -4
  212. package/dist/tx/index.js +3 -3
  213. package/dist/{types-Bze6vkwm.d.cts → types-BpLPqyaO.d.cts} +1264 -513
  214. package/dist/{types-DrmBTscX.d.ts → types-Diqc2caK.d.ts} +1264 -513
  215. package/dist/{ulid-DbBVrNSt.d.ts → ulid-B1zNV8r9.d.ts} +1 -1
  216. package/dist/{ulid-DfZlAh0u.d.cts → ulid-DNiRB4Mx.d.cts} +1 -1
  217. package/dist/util/index.cjs.map +1 -1
  218. package/dist/util/index.js +1 -1
  219. package/dist/{vault-group-DX2HFQMX.js → vault-group-DPZVFRI5.js} +182 -6
  220. package/dist/vault-group-DPZVFRI5.js.map +1 -0
  221. package/dist/{with-materialized-view--4PsvMDu.d.cts → with-materialized-view-BdH_A_r6.d.cts} +1 -1
  222. package/dist/{with-materialized-view-QT1Tp7NO.d.ts → with-materialized-view-CzAgp_HJ.d.ts} +1 -1
  223. package/dist/{with-overlayed-view-BEXfpzSb.d.ts → with-overlayed-view-BJbqQnsR.d.ts} +1 -1
  224. package/dist/{with-overlayed-view-DlH5qmeB.d.cts → with-overlayed-view-C40rDPlu.d.cts} +1 -1
  225. package/dist/with-rollup-Bopu5UDZ.d.cts +47 -0
  226. package/dist/with-rollup-DrlGkxiE.d.ts +47 -0
  227. package/package.json +23 -3
  228. package/dist/chunk-42FEUPZQ.js.map +0 -1
  229. package/dist/chunk-535SSHBS.js.map +0 -1
  230. package/dist/chunk-667MB6AH.js.map +0 -1
  231. package/dist/chunk-7BQ4QWYX.js.map +0 -1
  232. package/dist/chunk-7Z7KSVA5.js.map +0 -1
  233. package/dist/chunk-DUREQF5W.js.map +0 -1
  234. package/dist/chunk-F3BPIPLS.js.map +0 -1
  235. package/dist/chunk-GNI5STXQ.js.map +0 -1
  236. package/dist/chunk-HOR4R722.js.map +0 -1
  237. package/dist/chunk-KABJXG2F.js.map +0 -1
  238. package/dist/chunk-OQSRJG6A.js +0 -63
  239. package/dist/chunk-OQSRJG6A.js.map +0 -1
  240. package/dist/chunk-UMLVJTYV.js.map +0 -1
  241. package/dist/chunk-YULZKK4F.js.map +0 -1
  242. package/dist/executor-6ZDSDZ6V.js +0 -8
  243. package/dist/executor-AZLS3KBK.js +0 -11
  244. package/dist/executor-IDZDAFNH.js +0 -8
  245. package/dist/immutable-guard-CRPvu24K.d.cts +0 -82
  246. package/dist/immutable-guard-Dov3WvwF.d.ts +0 -82
  247. package/dist/issue-RZP3VI6O.js +0 -12
  248. package/dist/noydb-WCMY2ZOW.js +0 -35
  249. package/dist/read-only-facade-ITU6L7BL.js +0 -7
  250. package/dist/registry-EB6SISTA.js +0 -8
  251. package/dist/registry-IUZQVVBB.js +0 -8
  252. package/dist/state-vault-TMXZRTY5.js.map +0 -1
  253. package/dist/vault-group-DX2HFQMX.js.map +0 -1
  254. package/dist/with-derivation-CCqAchD5.d.cts +0 -13
  255. package/dist/with-derivation-_lySGdlm.d.ts +0 -13
  256. /package/dist/{chunk-6RR3MNMG.js.map → chunk-2U226RDC.js.map} +0 -0
  257. /package/dist/{chunk-L2BNJ6HM.js.map → chunk-32XVU2LT.js.map} +0 -0
  258. /package/dist/{chunk-X73VS74Y.js.map → chunk-33DAO2XG.js.map} +0 -0
  259. /package/dist/{chunk-QSUK7YWK.js.map → chunk-4UI5T3K7.js.map} +0 -0
  260. /package/dist/{chunk-G4SCICH5.js.map → chunk-5KKNBDCT.js.map} +0 -0
  261. /package/dist/{chunk-E2CDVKMH.js.map → chunk-6FHCU3QO.js.map} +0 -0
  262. /package/dist/{chunk-F4OJZIWQ.js.map → chunk-6Q5XRLKG.js.map} +0 -0
  263. /package/dist/{chunk-4TBBMHVC.js.map → chunk-6YEC7LLO.js.map} +0 -0
  264. /package/dist/{chunk-ZNQYHJXX.js.map → chunk-AB7JF2KF.js.map} +0 -0
  265. /package/dist/{chunk-XL35NSEN.js.map → chunk-BUBJYIZ7.js.map} +0 -0
  266. /package/dist/{chunk-3YWP3WBP.js.map → chunk-DKMPR76W.js.map} +0 -0
  267. /package/dist/{chunk-BI6ETQPF.js.map → chunk-DR5I7Q6N.js.map} +0 -0
  268. /package/dist/{chunk-6H2ZUNR7.js.map → chunk-FQRAYDS4.js.map} +0 -0
  269. /package/dist/{chunk-TS26M2SB.js.map → chunk-HOO5I3VG.js.map} +0 -0
  270. /package/dist/{chunk-OMAMZKKD.js.map → chunk-HWK75CYX.js.map} +0 -0
  271. /package/dist/{chunk-TKIY625R.js.map → chunk-HZOEBM67.js.map} +0 -0
  272. /package/dist/{chunk-DLZ2ONOD.js.map → chunk-IQ4GMEYZ.js.map} +0 -0
  273. /package/dist/{chunk-XWH4MXIU.js.map → chunk-K3NYRK7U.js.map} +0 -0
  274. /package/dist/{chunk-JD3OZAI4.js.map → chunk-KTZ2MHQK.js.map} +0 -0
  275. /package/dist/{chunk-SCJPI4Z5.js.map → chunk-LQ3GD5LL.js.map} +0 -0
  276. /package/dist/{chunk-AAVWKNZW.js.map → chunk-M3H7VSRV.js.map} +0 -0
  277. /package/dist/{chunk-BR3AMFGS.js.map → chunk-MGB67HKX.js.map} +0 -0
  278. /package/dist/{chunk-OB2ZJQ2D.js.map → chunk-PGVEL5IZ.js.map} +0 -0
  279. /package/dist/{chunk-BQ65SS5A.js.map → chunk-QPJ7Z4L3.js.map} +0 -0
  280. /package/dist/{chunk-CZI2A4MQ.js.map → chunk-RQFG2YSV.js.map} +0 -0
  281. /package/dist/{chunk-CJORTUJ2.js.map → chunk-RZWQNMMP.js.map} +0 -0
  282. /package/dist/{chunk-FFXM3ZIF.js.map → chunk-T4T5I5L6.js.map} +0 -0
  283. /package/dist/{chunk-QVIEAYTP.js.map → chunk-TFAN3NFD.js.map} +0 -0
  284. /package/dist/{chunk-Z4DO7YSI.js.map → chunk-TPOHMOGX.js.map} +0 -0
  285. /package/dist/{chunk-VLMPU56Q.js.map → chunk-TTS3RWL5.js.map} +0 -0
  286. /package/dist/{chunk-IXBIFDEW.js.map → chunk-VVDSDOVV.js.map} +0 -0
  287. /package/dist/{chunk-FWPKCXTN.js.map → chunk-WZCG3EZ6.js.map} +0 -0
  288. /package/dist/{chunk-HBXJ37ZY.js.map → chunk-Y5XVB75E.js.map} +0 -0
  289. /package/dist/{chunk-IQLVUT37.js.map → chunk-Z3BE5BRK.js.map} +0 -0
  290. /package/dist/{crypto-QXQOHMHF.js.map → crypto-FNK3XPCS.js.map} +0 -0
  291. /package/dist/{delegation-NIQ43IPU.js.map → delegation-FMXNUWE6.js.map} +0 -0
  292. /package/dist/{executor-6ZDSDZ6V.js.map → executor-IZ2NVXCY.js.map} +0 -0
  293. /package/dist/{executor-AZLS3KBK.js.map → executor-THSEYEJG.js.map} +0 -0
  294. /package/dist/{executor-IDZDAFNH.js.map → executor-WLFDUTOM.js.map} +0 -0
  295. /package/dist/{fanout-sidecar-67CMI3UT.js.map → fanout-sidecar-JGHXAJO5.js.map} +0 -0
  296. /package/dist/{issue-RZP3VI6O.js.map → forget/index.js.map} +0 -0
  297. /package/dist/{ledger-A3LL253R.js.map → issue-R2MWQO6K.js.map} +0 -0
  298. /package/dist/{noydb-WCMY2ZOW.js.map → ledger-GXC2YA3A.js.map} +0 -0
  299. /package/dist/{public-envelope-YP2UWMLG.js.map → noydb-RJL6FQ4B.js.map} +0 -0
  300. /package/dist/{read-only-facade-ITU6L7BL.js.map → public-envelope-HXOFHY4N.js.map} +0 -0
  301. /package/dist/{registry-EB6SISTA.js.map → read-only-facade-EX6WZZBP.js.map} +0 -0
  302. /package/dist/{registry-IUZQVVBB.js.map → registry-3T2RZC5A.js.map} +0 -0
  303. /package/dist/{registry-UTA4CLQS.js.map → registry-DMS7OKBM.js.map} +0 -0
  304. /package/dist/{revoke-HNMQZSCL.js.map → registry-WVXO6NH5.js.map} +0 -0
  305. /package/dist/{signer-DCMNKXSF.js.map → revoke-7LCWE2AH.js.map} +0 -0
  306. /package/dist/{stale-W5PQTRYH.js.map → signer-HAVDLGOK.js.map} +0 -0
@@ -2,18 +2,18 @@ import {
2
2
  ATTESTATIONS_COLLECTION,
3
3
  REVOKED_RECORD_ID,
4
4
  loadOrCreateSigner
5
- } from "./chunk-IXBIFDEW.js";
5
+ } from "./chunk-VVDSDOVV.js";
6
6
  import {
7
7
  NOYDB_FORMAT_VERSION
8
- } from "./chunk-F3BPIPLS.js";
8
+ } from "./chunk-LGPSCKWZ.js";
9
9
  import {
10
10
  decrypt,
11
11
  encrypt
12
- } from "./chunk-YULZKK4F.js";
12
+ } from "./chunk-QJKZ5WUP.js";
13
13
  import {
14
14
  AttestationError,
15
15
  ConflictError
16
- } from "./chunk-535SSHBS.js";
16
+ } from "./chunk-HMFC6M2G.js";
17
17
 
18
18
  // src/attestation/revoke.ts
19
19
  import { signRevocationList } from "@noy-db/attestation";
@@ -80,4 +80,4 @@ export {
80
80
  getRevokedDocIdsCore,
81
81
  publishRevocationListCore
82
82
  };
83
- //# sourceMappingURL=chunk-E2CDVKMH.js.map
83
+ //# sourceMappingURL=chunk-6FHCU3QO.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  dekKey
3
- } from "./chunk-4TBBMHVC.js";
3
+ } from "./chunk-6YEC7LLO.js";
4
4
  import {
5
5
  generateULID
6
6
  } from "./chunk-FZU343FL.js";
@@ -9,10 +9,10 @@ import {
9
9
  encrypt,
10
10
  unwrapKey,
11
11
  wrapKey
12
- } from "./chunk-YULZKK4F.js";
12
+ } from "./chunk-QJKZ5WUP.js";
13
13
  import {
14
14
  DelegationTargetMissingError
15
- } from "./chunk-535SSHBS.js";
15
+ } from "./chunk-HMFC6M2G.js";
16
16
 
17
17
  // src/team/delegation.ts
18
18
  var DELEGATIONS_COLLECTION = "_delegations";
@@ -94,4 +94,4 @@ export {
94
94
  loadActiveDelegations,
95
95
  revokeDelegation
96
96
  };
97
- //# sourceMappingURL=chunk-F4OJZIWQ.js.map
97
+ //# sourceMappingURL=chunk-6Q5XRLKG.js.map
@@ -1,9 +1,12 @@
1
+ import {
2
+ NOYDB_FORMAT_VERSION
3
+ } from "./chunk-LGPSCKWZ.js";
1
4
  import {
2
5
  decrypt
3
- } from "./chunk-YULZKK4F.js";
6
+ } from "./chunk-QJKZ5WUP.js";
4
7
  import {
5
8
  ReadOnlyAtInstantError
6
- } from "./chunk-535SSHBS.js";
9
+ } from "./chunk-HMFC6M2G.js";
7
10
 
8
11
  // src/history/history.ts
9
12
  var HISTORY_COLLECTION = "_history";
@@ -79,6 +82,28 @@ async function clearHistory(adapter, vault, collection, recordId) {
79
82
  }
80
83
  return toDelete.length;
81
84
  }
85
+ async function tombstoneHistory(adapter, vault, collection, recordId, actor) {
86
+ const allIds = await adapter.list(vault, HISTORY_COLLECTION);
87
+ const matchingIds = allIds.filter((id) => matchesPrefix(id, collection, recordId));
88
+ const now = (/* @__PURE__ */ new Date()).toISOString();
89
+ let count = 0;
90
+ for (const id of matchingIds) {
91
+ const env = await adapter.get(vault, HISTORY_COLLECTION, id);
92
+ if (!env) continue;
93
+ if (!env._data && env._cek === void 0) continue;
94
+ const tombstone = {
95
+ _noydb: NOYDB_FORMAT_VERSION,
96
+ _v: env._v,
97
+ _ts: now,
98
+ _iv: "",
99
+ _data: "",
100
+ ...actor ? { _by: actor } : {}
101
+ };
102
+ await adapter.put(vault, HISTORY_COLLECTION, id, tombstone);
103
+ count++;
104
+ }
105
+ return count;
106
+ }
82
107
 
83
108
  // src/history/time-machine.ts
84
109
  var VaultInstant = class {
@@ -187,7 +212,7 @@ var CollectionInstant = class {
187
212
  for (const e of entries) {
188
213
  if (e.collection !== this.name || e.id !== id) continue;
189
214
  if (e.ts > this.targetTs) break;
190
- if (e.op === "amendment" || e.op === "lifecycle") continue;
215
+ if (e.op === "amendment" || e.op === "lifecycle" || e.op === "forget") continue;
191
216
  latest = { op: e.op === "migration" ? "put" : e.op, version: e.version };
192
217
  }
193
218
  if (!latest) return null;
@@ -304,9 +329,10 @@ export {
304
329
  getVersionEnvelope,
305
330
  pruneHistory,
306
331
  clearHistory,
332
+ tombstoneHistory,
307
333
  VaultInstant,
308
334
  CollectionInstant,
309
335
  diff,
310
336
  formatDiff
311
337
  };
312
- //# sourceMappingURL=chunk-HOR4R722.js.map
338
+ //# sourceMappingURL=chunk-6XEGHIBA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/history/history.ts","../src/history/time-machine.ts","../src/history/diff.ts"],"sourcesContent":["import type { NoydbStore, EncryptedEnvelope, HistoryOptions, PruneOptions } from '../types.js'\nimport { NOYDB_FORMAT_VERSION } from '../types.js'\n\n/**\n * History storage convention:\n * Collection: `_history`\n * ID format: `{collection}:{recordId}:{paddedVersion}`\n * Version is zero-padded to 10 digits for lexicographic sorting.\n */\n\nconst HISTORY_COLLECTION = '_history'\nconst VERSION_PAD = 10\n\nfunction historyId(collection: string, recordId: string, version: number): string {\n return `${collection}:${recordId}:${String(version).padStart(VERSION_PAD, '0')}`\n}\n\n// Unused today, kept for future history-id parsing utilities.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction parseHistoryId(id: string): { collection: string; recordId: string; version: number } | null {\n const lastColon = id.lastIndexOf(':')\n if (lastColon < 0) return null\n const versionStr = id.slice(lastColon + 1)\n const rest = id.slice(0, lastColon)\n const firstColon = rest.indexOf(':')\n if (firstColon < 0) return null\n return {\n collection: rest.slice(0, firstColon),\n recordId: rest.slice(firstColon + 1),\n version: parseInt(versionStr, 10),\n }\n}\n\nfunction matchesPrefix(id: string, collection: string, recordId?: string): boolean {\n if (recordId) {\n return id.startsWith(`${collection}:${recordId}:`)\n }\n return id.startsWith(`${collection}:`)\n}\n\n/** Save a history entry (a complete encrypted envelope snapshot). */\nexport async function saveHistory(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string,\n envelope: EncryptedEnvelope,\n): Promise<void> {\n const id = historyId(collection, recordId, envelope._v)\n await adapter.put(vault, HISTORY_COLLECTION, id, envelope)\n}\n\n/** Get history entries for a record, sorted newest-first. */\nexport async function getHistory(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string,\n options?: HistoryOptions,\n): Promise<EncryptedEnvelope[]> {\n const allIds = await adapter.list(vault, HISTORY_COLLECTION)\n const matchingIds = allIds\n .filter(id => matchesPrefix(id, collection, recordId))\n .sort()\n .reverse() // newest first\n\n const entries: EncryptedEnvelope[] = []\n\n for (const id of matchingIds) {\n const envelope = await adapter.get(vault, HISTORY_COLLECTION, id)\n if (!envelope) continue\n\n // Apply time filters\n if (options?.from && envelope._ts < options.from) continue\n if (options?.to && envelope._ts > options.to) continue\n\n entries.push(envelope)\n\n if (options?.limit && entries.length >= options.limit) break\n }\n\n return entries\n}\n\n/** Get a specific version's envelope from history. */\nexport async function getVersionEnvelope(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string,\n version: number,\n): Promise<EncryptedEnvelope | null> {\n const id = historyId(collection, recordId, version)\n return adapter.get(vault, HISTORY_COLLECTION, id)\n}\n\n/** Prune history entries. Returns the number of entries deleted. */\nexport async function pruneHistory(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string | undefined,\n options: PruneOptions,\n): Promise<number> {\n const allIds = await adapter.list(vault, HISTORY_COLLECTION)\n const matchingIds = allIds\n .filter(id => recordId ? matchesPrefix(id, collection, recordId) : matchesPrefix(id, collection))\n .sort()\n\n let toDelete: string[] = []\n\n if (options.keepVersions !== undefined) {\n // Keep only the N most recent, delete the rest\n const keep = options.keepVersions\n if (matchingIds.length > keep) {\n toDelete = matchingIds.slice(0, matchingIds.length - keep)\n }\n }\n\n if (options.beforeDate) {\n // Delete entries older than the specified date\n for (const id of matchingIds) {\n if (toDelete.includes(id)) continue\n const envelope = await adapter.get(vault, HISTORY_COLLECTION, id)\n if (envelope && envelope._ts < options.beforeDate) {\n toDelete.push(id)\n }\n }\n }\n\n // Deduplicate\n const uniqueDeletes = [...new Set(toDelete)]\n\n for (const id of uniqueDeletes) {\n await adapter.delete(vault, HISTORY_COLLECTION, id)\n }\n\n return uniqueDeletes.length\n}\n\n/** Clear all history for a vault, optionally scoped to a collection or record. */\nexport async function clearHistory(\n adapter: NoydbStore,\n vault: string,\n collection?: string,\n recordId?: string,\n): Promise<number> {\n const allIds = await adapter.list(vault, HISTORY_COLLECTION)\n let toDelete: string[]\n\n if (collection && recordId) {\n toDelete = allIds.filter(id => matchesPrefix(id, collection, recordId))\n } else if (collection) {\n toDelete = allIds.filter(id => matchesPrefix(id, collection))\n } else {\n toDelete = allIds\n }\n\n for (const id of toDelete) {\n await adapter.delete(vault, HISTORY_COLLECTION, id)\n }\n\n return toDelete.length\n}\n\n/**\n * Crypto-shred every `_history` version of a record (#304). Each non-tombstone\n * history envelope is OVERWRITTEN in place with a tombstone\n * `{ _noydb, _v, _ts: now, _by: actor, _iv: '', _data: '' }` — dropping\n * `_iv`/`_data`/`_cek`/`_det`, so the prior ciphertext (and the wrapped CEK\n * that could decrypt it) is gone everywhere this store reaches. The version\n * counter (`_v`) is preserved so the audit trail still shows \"N versions\n * existed and were erased.\"\n *\n * Overwrite — NOT delete — so the history key itself survives as proof the\n * version existed. Already-tombstoned versions (re-run / idempotent forget)\n * are left untouched and not counted.\n *\n * Returns the number of history versions newly tombstoned.\n */\nexport async function tombstoneHistory(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n recordId: string,\n actor: string,\n): Promise<number> {\n const allIds = await adapter.list(vault, HISTORY_COLLECTION)\n const matchingIds = allIds.filter(id => matchesPrefix(id, collection, recordId))\n\n const now = new Date().toISOString()\n let count = 0\n for (const id of matchingIds) {\n const env = await adapter.get(vault, HISTORY_COLLECTION, id)\n if (!env) continue\n // Already a tombstone (no body and no wrapped CEK)? Skip — idempotent.\n if (!env._data && env._cek === undefined) continue\n const tombstone: EncryptedEnvelope = {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: env._v,\n _ts: now,\n _iv: '',\n _data: '',\n ...(actor ? { _by: actor } : {}),\n }\n await adapter.put(vault, HISTORY_COLLECTION, id, tombstone)\n count++\n }\n return count\n}\n","/**\n * Time-machine queries — point-in-time reads reconstructed from the\n * existing history + ledger infrastructure.\n *\n * ## Usage\n *\n * ```ts\n * const vault = await db.openVault('acme', { passphrase })\n * const q1End = vault.at('2026-03-31T23:59:59Z')\n * const invoice = await q1End.collection<Invoice>('invoices').get('inv-001')\n * // → the record as it stood at the close of Q1 2026\n * ```\n *\n * ## How it works\n *\n * Every write path already fans out into two persistence lanes:\n *\n * 1. `saveHistory(...)` persists a **full encrypted envelope snapshot**\n * per version under the `_history` collection (one envelope per\n * version, keyed by `{collection}:{id}:{paddedVersion}`). Each\n * envelope carries its own `_ts` (the write timestamp).\n * 2. `ledger.append(...)` appends a hash-chained audit entry that\n * records the `op` (put / delete), `version`, and `ts`.\n *\n * Reconstruction at a target timestamp T is therefore:\n *\n * - Find the newest history envelope for `(collection, id)` whose\n * `_ts ≤ T` — that's the state the record was in at T.\n * - Check the ledger for any `op: 'delete'` entry for the same\n * `(collection, id)` with `entry.ts` in `(latestEnvelope._ts, T]` —\n * if present, the record was deleted before T, so return `null`.\n * - Decrypt the surviving envelope with the current collection DEK\n * (DEKs are per-collection but stable across versions — the same\n * key encrypts v1 and v15 of a record).\n *\n * No delta replay. The existing `history.ts` module already stores\n * complete snapshots; we just pick the right one.\n *\n * ## Read-only contract\n *\n * Every write method on `CollectionInstant` throws\n * {@link ReadOnlyAtInstantError}. A historical view is a *read*\n * surface — mutating the past would require either a branch/shadow\n * mechanism (tracked under shadow vaults) or a rewrite of\n * history, which breaks the ledger's tamper-evidence guarantee.\n *\n * @module\n */\nimport type { EncryptedEnvelope, NoydbStore } from '../types.js'\nimport type { LedgerStore } from './ledger/store.js'\nimport { getHistory } from './history.js'\nimport { decrypt } from '../crypto.js'\nimport { ReadOnlyAtInstantError } from '../errors.js'\n\n/**\n * Narrow view of a {@link Vault}'s internals that\n * {@link VaultInstant} needs. Passed in by `Vault.at()` rather than\n * constructed here so all crypto + adapter access stays inside the\n * Vault class.\n *\n * Not exported from the public barrel — consumers should get a\n * `VaultInstant` via `vault.at(ts)`, never by constructing one\n * directly.\n */\nexport interface VaultEngine {\n readonly adapter: NoydbStore\n /** Vault name (the compartment). */\n readonly name: string\n /**\n * `true` when the vault was opened with a passphrase (the normal\n * case). `false` in plaintext-mode vaults (`encrypt: false`) — in\n * that case `envelope._data` is raw JSON and we skip the DEK lookup.\n */\n readonly encrypted: boolean\n /**\n * Resolves the DEK used to decrypt a given collection's envelopes.\n * Not called when `encrypted` is false.\n */\n getDEK(collection: string): Promise<CryptoKey>\n /**\n * Lazily-initialised ledger. We consult it to detect deletes that\n * happened between the latest history snapshot and the target\n * timestamp. `null` when history is disabled for this vault — in\n * that case time-machine reads fall back to history-only\n * reconstruction (which may miss deletes).\n */\n getLedger(): LedgerStore | null\n}\n\n/**\n * A vault at a fixed instant. Produced by `vault.at(timestamp)`.\n * Carries no session state of its own — every read is a fresh\n * lookup through the vault's adapter.\n *\n * Cheap to construct; safe to throw away. Create one per query.\n */\nexport class VaultInstant {\n constructor(\n private readonly engine: VaultEngine,\n /** Fully-resolved target timestamp (ISO-8601 UTC). */\n public readonly timestamp: string,\n ) {}\n\n /** Get a point-in-time view of a collection. */\n collection<T = unknown>(name: string): CollectionInstant<T> {\n return new CollectionInstant<T>(this.engine, this.timestamp, name)\n }\n}\n\n/**\n * A read-only collection view anchored to a past instant.\n *\n * Every write method throws {@link ReadOnlyAtInstantError} — see the\n * module docstring for why. The read surface is intentionally smaller\n * than the live {@link Collection}: `get` and `list` cover the\n * \"what did the books look like on date X\" use case without pulling\n * in the full query DSL / joins / aggregates at this stage. Follow-up\n * work tracked under.\n */\nexport class CollectionInstant<T = unknown> {\n constructor(\n private readonly engine: VaultEngine,\n private readonly targetTs: string,\n public readonly name: string,\n ) {}\n\n /**\n * Return the record as it existed at the target timestamp, or\n * `null` if the record had not been created yet or had already been\n * deleted by then.\n */\n async get(id: string): Promise<T | null> {\n const envelope = await this.resolveEnvelope(id)\n if (!envelope) return null\n const plaintext = this.engine.encrypted\n ? await decrypt(envelope._iv, envelope._data, await this.engine.getDEK(this.name))\n : envelope._data\n return JSON.parse(plaintext) as T\n }\n\n /**\n * IDs of records that existed (had at least one `put` and were not\n * subsequently deleted) at the target timestamp.\n *\n * Implemented as a linear scan over history + ledger. Performance\n * is bounded by total history size (not live-vault size), so the\n * memory-first vault-scale cap (1K–50K records × average history\n * depth) still applies.\n */\n async list(): Promise<string[]> {\n const historyIds = await collectHistoryIds(this.engine.adapter, this.engine.name, this.name)\n const liveIds = await this.engine.adapter.list(this.engine.name, this.name)\n const candidateIds = new Set<string>([...historyIds, ...liveIds])\n const alive: string[] = []\n for (const id of candidateIds) {\n const env = await this.resolveEnvelope(id)\n if (env) alive.push(id)\n }\n return alive.sort()\n }\n\n // ── write guards ───────────────────────────────────────────────────\n\n async put(_id: string, _record: T): Promise<never> {\n throw new ReadOnlyAtInstantError('put', this.targetTs)\n }\n async delete(_id: string): Promise<never> {\n throw new ReadOnlyAtInstantError('delete', this.targetTs)\n }\n async update(_id: string, _patch: Partial<T>): Promise<never> {\n throw new ReadOnlyAtInstantError('update', this.targetTs)\n }\n\n // ── internals ─────────────────────────────────────────────────────\n\n /**\n * Return the envelope that represents the record's state at\n * `targetTs`, accounting for deletes. `null` if the record didn't\n * exist at that instant.\n *\n * ## Why we use the ledger as the authoritative timeline\n *\n * The per-version history snapshots saved by `saveHistory()` do\n * carry a `_ts` field, but that timestamp is the moment the\n * snapshot was *captured* (i.e. the instant right before the\n * subsequent overwrite), not the original write time. The ledger,\n * by contrast, records `ts` at the moment of each `put` / `delete`\n * — it's the only source that tracks the real timeline. So:\n *\n * 1. Walk the ledger; find the latest entry for `(collection, id)`\n * with `ts ≤ targetTs`.\n * 2. If that entry is a `delete`, the record was gone at the\n * target instant — return null.\n * 3. Otherwise it's a `put` with a specific `version`. Load the\n * envelope for that version from history, falling back to the\n * live collection for the most recent version.\n *\n * ## Fallback when the ledger is disabled\n *\n * If the vault has history disabled, `getLedger()` returns null and\n * we fall back to comparing envelope `_ts` fields. This is\n * approximate and gets the *last write* right but may confuse the\n * intermediate versions; adopters needing accurate time-machine\n * reads should leave history enabled.\n */\n private async resolveEnvelope(id: string): Promise<EncryptedEnvelope | null> {\n const ledger = this.engine.getLedger()\n if (ledger) {\n return this.resolveViaLedger(id, ledger)\n }\n return this.resolveViaEnvelopeTs(id)\n }\n\n private async resolveViaLedger(id: string, ledger: LedgerStore): Promise<EncryptedEnvelope | null> {\n const entries = await ledger.entries()\n // Entries are already ordered by index which is the mutation order.\n let latest: { op: 'put' | 'delete'; version: number } | null = null\n for (const e of entries) {\n if (e.collection !== this.name || e.id !== id) continue\n if (e.ts > this.targetTs) break // entries are time-ordered by index\n // `amendment` + `lifecycle` entries are audit-only summaries — they\n // carry no (collection, id) tuple of their own and would never match\n // the filter above. The narrow here is a type guard, not a runtime\n // skip.\n // `forget` is a subject-erasure summary with empty (collection, id) —\n // never matches the filter above; the narrow is a type guard.\n if (e.op === 'amendment' || e.op === 'lifecycle' || e.op === 'forget') continue\n // `migration` is a record rewrite (cutover) — resolve it like a put.\n latest = { op: e.op === 'migration' ? 'put' : e.op, version: e.version }\n }\n if (!latest) return null\n if (latest.op === 'delete') return null\n return this.loadVersion(id, latest.version)\n }\n\n private async resolveViaEnvelopeTs(id: string): Promise<EncryptedEnvelope | null> {\n const history = await getHistory(\n this.engine.adapter, this.engine.name, this.name, id,\n )\n const live = await this.engine.adapter.get(this.engine.name, this.name, id)\n const byVersion = new Map<number, EncryptedEnvelope>()\n for (const e of history) byVersion.set(e._v, e)\n if (live) byVersion.set(live._v, live)\n const sorted = [...byVersion.values()].sort((a, b) =>\n a._ts < b._ts ? 1 : a._ts > b._ts ? -1 : 0,\n )\n return sorted.find((e) => e._ts <= this.targetTs) ?? null\n }\n\n /**\n * Fetch the envelope for a specific version. The live record (most\n * recent put) lives in the main collection; prior versions live in\n * `_history`. We check live first because the common case after a\n * delete is that we're trying to load the last-live version from\n * history, and skipping live for the current-version case avoids a\n * redundant lookup.\n */\n private async loadVersion(id: string, version: number): Promise<EncryptedEnvelope | null> {\n const live = await this.engine.adapter.get(this.engine.name, this.name, id)\n if (live && live._v === version) return live\n\n // Direct lookup by (collection, id, version) — avoids scanning all history.\n const historyId = `${this.name}:${id}:${String(version).padStart(10, '0')}`\n return await this.engine.adapter.get(this.engine.name, '_history', historyId)\n }\n}\n\n/**\n * Scan the `_history` collection once and collect every distinct\n * `recordId` for the given collection. History keys follow the\n * shape `<collection>:<recordId>:<paddedVersion>`; we split on the\n * last two colons (delimiter-safe because `paddedVersion` is\n * exactly 10 digits).\n */\nasync function collectHistoryIds(\n adapter: NoydbStore,\n vault: string,\n collection: string,\n): Promise<string[]> {\n const all = await adapter.list(vault, '_history')\n const prefix = `${collection}:`\n const seen = new Set<string>()\n for (const key of all) {\n if (!key.startsWith(prefix)) continue\n const lastColon = key.lastIndexOf(':')\n if (lastColon <= prefix.length) continue\n const middle = key.slice(prefix.length, lastColon)\n seen.add(middle)\n }\n return [...seen]\n}\n","/**\n * Zero-dependency JSON diff.\n * Produces a flat list of changes between two plain objects.\n */\n\nexport type ChangeType = 'added' | 'removed' | 'changed'\n\nexport interface DiffEntry {\n /** Dot-separated path to the changed field (e.g. \"address.city\"). */\n readonly path: string\n /** Type of change. */\n readonly type: ChangeType\n /** Previous value (undefined for 'added'). */\n readonly from?: unknown\n /** New value (undefined for 'removed'). */\n readonly to?: unknown\n}\n\n/**\n * Compute differences between two objects.\n * Returns an array of DiffEntry describing each changed field.\n * Returns empty array if objects are identical.\n */\nexport function diff(oldObj: unknown, newObj: unknown, basePath = ''): DiffEntry[] {\n const changes: DiffEntry[] = []\n\n // Both primitives or nulls\n if (oldObj === newObj) return changes\n\n // One is null/undefined\n if (oldObj == null && newObj != null) {\n return [{ path: basePath || '(root)', type: 'added', to: newObj }]\n }\n if (oldObj != null && newObj == null) {\n return [{ path: basePath || '(root)', type: 'removed', from: oldObj }]\n }\n\n // Different types\n if (typeof oldObj !== typeof newObj) {\n return [{ path: basePath || '(root)', type: 'changed', from: oldObj, to: newObj }]\n }\n\n // Both primitives (and not equal — checked above)\n if (typeof oldObj !== 'object') {\n return [{ path: basePath || '(root)', type: 'changed', from: oldObj, to: newObj }]\n }\n\n // Both arrays\n if (Array.isArray(oldObj) && Array.isArray(newObj)) {\n const maxLen = Math.max(oldObj.length, newObj.length)\n for (let i = 0; i < maxLen; i++) {\n const p = basePath ? `${basePath}[${i}]` : `[${i}]`\n if (i >= oldObj.length) {\n changes.push({ path: p, type: 'added', to: newObj[i] })\n } else if (i >= newObj.length) {\n changes.push({ path: p, type: 'removed', from: oldObj[i] })\n } else {\n changes.push(...diff(oldObj[i], newObj[i], p))\n }\n }\n return changes\n }\n\n // Both objects\n const oldRecord = oldObj as Record<string, unknown>\n const newRecord = newObj as Record<string, unknown>\n const allKeys = new Set([...Object.keys(oldRecord), ...Object.keys(newRecord)])\n\n for (const key of allKeys) {\n const p = basePath ? `${basePath}.${key}` : key\n if (!(key in oldRecord)) {\n changes.push({ path: p, type: 'added', to: newRecord[key] })\n } else if (!(key in newRecord)) {\n changes.push({ path: p, type: 'removed', from: oldRecord[key] })\n } else {\n changes.push(...diff(oldRecord[key], newRecord[key], p))\n }\n }\n\n return changes\n}\n\n/** Format a diff as a human-readable string. */\nexport function formatDiff(changes: DiffEntry[]): string {\n if (changes.length === 0) return '(no changes)'\n return changes.map(c => {\n switch (c.type) {\n case 'added':\n return `+ ${c.path}: ${JSON.stringify(c.to)}`\n case 'removed':\n return `- ${c.path}: ${JSON.stringify(c.from)}`\n case 'changed':\n return `~ ${c.path}: ${JSON.stringify(c.from)} → ${JSON.stringify(c.to)}`\n }\n }).join('\\n')\n}\n"],"mappings":";;;;;;;;;;;AAUA,IAAM,qBAAqB;AAC3B,IAAM,cAAc;AAEpB,SAAS,UAAU,YAAoB,UAAkB,SAAyB;AAChF,SAAO,GAAG,UAAU,IAAI,QAAQ,IAAI,OAAO,OAAO,EAAE,SAAS,aAAa,GAAG,CAAC;AAChF;AAkBA,SAAS,cAAc,IAAY,YAAoB,UAA4B;AACjF,MAAI,UAAU;AACZ,WAAO,GAAG,WAAW,GAAG,UAAU,IAAI,QAAQ,GAAG;AAAA,EACnD;AACA,SAAO,GAAG,WAAW,GAAG,UAAU,GAAG;AACvC;AAGA,eAAsB,YACpB,SACA,OACA,YACA,UACA,UACe;AACf,QAAM,KAAK,UAAU,YAAY,UAAU,SAAS,EAAE;AACtD,QAAM,QAAQ,IAAI,OAAO,oBAAoB,IAAI,QAAQ;AAC3D;AAGA,eAAsB,WACpB,SACA,OACA,YACA,UACA,SAC8B;AAC9B,QAAM,SAAS,MAAM,QAAQ,KAAK,OAAO,kBAAkB;AAC3D,QAAM,cAAc,OACjB,OAAO,QAAM,cAAc,IAAI,YAAY,QAAQ,CAAC,EACpD,KAAK,EACL,QAAQ;AAEX,QAAM,UAA+B,CAAC;AAEtC,aAAW,MAAM,aAAa;AAC5B,UAAM,WAAW,MAAM,QAAQ,IAAI,OAAO,oBAAoB,EAAE;AAChE,QAAI,CAAC,SAAU;AAGf,QAAI,SAAS,QAAQ,SAAS,MAAM,QAAQ,KAAM;AAClD,QAAI,SAAS,MAAM,SAAS,MAAM,QAAQ,GAAI;AAE9C,YAAQ,KAAK,QAAQ;AAErB,QAAI,SAAS,SAAS,QAAQ,UAAU,QAAQ,MAAO;AAAA,EACzD;AAEA,SAAO;AACT;AAGA,eAAsB,mBACpB,SACA,OACA,YACA,UACA,SACmC;AACnC,QAAM,KAAK,UAAU,YAAY,UAAU,OAAO;AAClD,SAAO,QAAQ,IAAI,OAAO,oBAAoB,EAAE;AAClD;AAGA,eAAsB,aACpB,SACA,OACA,YACA,UACA,SACiB;AACjB,QAAM,SAAS,MAAM,QAAQ,KAAK,OAAO,kBAAkB;AAC3D,QAAM,cAAc,OACjB,OAAO,QAAM,WAAW,cAAc,IAAI,YAAY,QAAQ,IAAI,cAAc,IAAI,UAAU,CAAC,EAC/F,KAAK;AAER,MAAI,WAAqB,CAAC;AAE1B,MAAI,QAAQ,iBAAiB,QAAW;AAEtC,UAAM,OAAO,QAAQ;AACrB,QAAI,YAAY,SAAS,MAAM;AAC7B,iBAAW,YAAY,MAAM,GAAG,YAAY,SAAS,IAAI;AAAA,IAC3D;AAAA,EACF;AAEA,MAAI,QAAQ,YAAY;AAEtB,eAAW,MAAM,aAAa;AAC5B,UAAI,SAAS,SAAS,EAAE,EAAG;AAC3B,YAAM,WAAW,MAAM,QAAQ,IAAI,OAAO,oBAAoB,EAAE;AAChE,UAAI,YAAY,SAAS,MAAM,QAAQ,YAAY;AACjD,iBAAS,KAAK,EAAE;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC;AAE3C,aAAW,MAAM,eAAe;AAC9B,UAAM,QAAQ,OAAO,OAAO,oBAAoB,EAAE;AAAA,EACpD;AAEA,SAAO,cAAc;AACvB;AAGA,eAAsB,aACpB,SACA,OACA,YACA,UACiB;AACjB,QAAM,SAAS,MAAM,QAAQ,KAAK,OAAO,kBAAkB;AAC3D,MAAI;AAEJ,MAAI,cAAc,UAAU;AAC1B,eAAW,OAAO,OAAO,QAAM,cAAc,IAAI,YAAY,QAAQ,CAAC;AAAA,EACxE,WAAW,YAAY;AACrB,eAAW,OAAO,OAAO,QAAM,cAAc,IAAI,UAAU,CAAC;AAAA,EAC9D,OAAO;AACL,eAAW;AAAA,EACb;AAEA,aAAW,MAAM,UAAU;AACzB,UAAM,QAAQ,OAAO,OAAO,oBAAoB,EAAE;AAAA,EACpD;AAEA,SAAO,SAAS;AAClB;AAiBA,eAAsB,iBACpB,SACA,OACA,YACA,UACA,OACiB;AACjB,QAAM,SAAS,MAAM,QAAQ,KAAK,OAAO,kBAAkB;AAC3D,QAAM,cAAc,OAAO,OAAO,QAAM,cAAc,IAAI,YAAY,QAAQ,CAAC;AAE/E,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,MAAI,QAAQ;AACZ,aAAW,MAAM,aAAa;AAC5B,UAAM,MAAM,MAAM,QAAQ,IAAI,OAAO,oBAAoB,EAAE;AAC3D,QAAI,CAAC,IAAK;AAEV,QAAI,CAAC,IAAI,SAAS,IAAI,SAAS,OAAW;AAC1C,UAAM,YAA+B;AAAA,MACnC,QAAQ;AAAA,MACR,IAAI,IAAI;AAAA,MACR,KAAK;AAAA,MACL,KAAK;AAAA,MACL,OAAO;AAAA,MACP,GAAI,QAAQ,EAAE,KAAK,MAAM,IAAI,CAAC;AAAA,IAChC;AACA,UAAM,QAAQ,IAAI,OAAO,oBAAoB,IAAI,SAAS;AAC1D;AAAA,EACF;AACA,SAAO;AACT;;;ACjHO,IAAM,eAAN,MAAmB;AAAA,EACxB,YACmB,QAED,WAChB;AAHiB;AAED;AAAA,EACf;AAAA,EAHgB;AAAA,EAED;AAAA;AAAA,EAIlB,WAAwB,MAAoC;AAC1D,WAAO,IAAI,kBAAqB,KAAK,QAAQ,KAAK,WAAW,IAAI;AAAA,EACnE;AACF;AAYO,IAAM,oBAAN,MAAqC;AAAA,EAC1C,YACmB,QACA,UACD,MAChB;AAHiB;AACA;AACD;AAAA,EACf;AAAA,EAHgB;AAAA,EACA;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQlB,MAAM,IAAI,IAA+B;AACvC,UAAM,WAAW,MAAM,KAAK,gBAAgB,EAAE;AAC9C,QAAI,CAAC,SAAU,QAAO;AACtB,UAAM,YAAY,KAAK,OAAO,YAC1B,MAAM,QAAQ,SAAS,KAAK,SAAS,OAAO,MAAM,KAAK,OAAO,OAAO,KAAK,IAAI,CAAC,IAC/E,SAAS;AACb,WAAO,KAAK,MAAM,SAAS;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,OAA0B;AAC9B,UAAM,aAAa,MAAM,kBAAkB,KAAK,OAAO,SAAS,KAAK,OAAO,MAAM,KAAK,IAAI;AAC3F,UAAM,UAAU,MAAM,KAAK,OAAO,QAAQ,KAAK,KAAK,OAAO,MAAM,KAAK,IAAI;AAC1E,UAAM,eAAe,oBAAI,IAAY,CAAC,GAAG,YAAY,GAAG,OAAO,CAAC;AAChE,UAAM,QAAkB,CAAC;AACzB,eAAW,MAAM,cAAc;AAC7B,YAAM,MAAM,MAAM,KAAK,gBAAgB,EAAE;AACzC,UAAI,IAAK,OAAM,KAAK,EAAE;AAAA,IACxB;AACA,WAAO,MAAM,KAAK;AAAA,EACpB;AAAA;AAAA,EAIA,MAAM,IAAI,KAAa,SAA4B;AACjD,UAAM,IAAI,uBAAuB,OAAO,KAAK,QAAQ;AAAA,EACvD;AAAA,EACA,MAAM,OAAO,KAA6B;AACxC,UAAM,IAAI,uBAAuB,UAAU,KAAK,QAAQ;AAAA,EAC1D;AAAA,EACA,MAAM,OAAO,KAAa,QAAoC;AAC5D,UAAM,IAAI,uBAAuB,UAAU,KAAK,QAAQ;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCA,MAAc,gBAAgB,IAA+C;AAC3E,UAAM,SAAS,KAAK,OAAO,UAAU;AACrC,QAAI,QAAQ;AACV,aAAO,KAAK,iBAAiB,IAAI,MAAM;AAAA,IACzC;AACA,WAAO,KAAK,qBAAqB,EAAE;AAAA,EACrC;AAAA,EAEA,MAAc,iBAAiB,IAAY,QAAwD;AACjG,UAAM,UAAU,MAAM,OAAO,QAAQ;AAErC,QAAI,SAA2D;AAC/D,eAAW,KAAK,SAAS;AACvB,UAAI,EAAE,eAAe,KAAK,QAAQ,EAAE,OAAO,GAAI;AAC/C,UAAI,EAAE,KAAK,KAAK,SAAU;AAO1B,UAAI,EAAE,OAAO,eAAe,EAAE,OAAO,eAAe,EAAE,OAAO,SAAU;AAEvE,eAAS,EAAE,IAAI,EAAE,OAAO,cAAc,QAAQ,EAAE,IAAI,SAAS,EAAE,QAAQ;AAAA,IACzE;AACA,QAAI,CAAC,OAAQ,QAAO;AACpB,QAAI,OAAO,OAAO,SAAU,QAAO;AACnC,WAAO,KAAK,YAAY,IAAI,OAAO,OAAO;AAAA,EAC5C;AAAA,EAEA,MAAc,qBAAqB,IAA+C;AAChF,UAAM,UAAU,MAAM;AAAA,MACpB,KAAK,OAAO;AAAA,MAAS,KAAK,OAAO;AAAA,MAAM,KAAK;AAAA,MAAM;AAAA,IACpD;AACA,UAAM,OAAO,MAAM,KAAK,OAAO,QAAQ,IAAI,KAAK,OAAO,MAAM,KAAK,MAAM,EAAE;AAC1E,UAAM,YAAY,oBAAI,IAA+B;AACrD,eAAW,KAAK,QAAS,WAAU,IAAI,EAAE,IAAI,CAAC;AAC9C,QAAI,KAAM,WAAU,IAAI,KAAK,IAAI,IAAI;AACrC,UAAM,SAAS,CAAC,GAAG,UAAU,OAAO,CAAC,EAAE;AAAA,MAAK,CAAC,GAAG,MAC9C,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK;AAAA,IAC3C;AACA,WAAO,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,QAAQ,KAAK;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,YAAY,IAAY,SAAoD;AACxF,UAAM,OAAO,MAAM,KAAK,OAAO,QAAQ,IAAI,KAAK,OAAO,MAAM,KAAK,MAAM,EAAE;AAC1E,QAAI,QAAQ,KAAK,OAAO,QAAS,QAAO;AAGxC,UAAMA,aAAY,GAAG,KAAK,IAAI,IAAI,EAAE,IAAI,OAAO,OAAO,EAAE,SAAS,IAAI,GAAG,CAAC;AACzE,WAAO,MAAM,KAAK,OAAO,QAAQ,IAAI,KAAK,OAAO,MAAM,YAAYA,UAAS;AAAA,EAC9E;AACF;AASA,eAAe,kBACb,SACA,OACA,YACmB;AACnB,QAAM,MAAM,MAAM,QAAQ,KAAK,OAAO,UAAU;AAChD,QAAM,SAAS,GAAG,UAAU;AAC5B,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,OAAO,KAAK;AACrB,QAAI,CAAC,IAAI,WAAW,MAAM,EAAG;AAC7B,UAAM,YAAY,IAAI,YAAY,GAAG;AACrC,QAAI,aAAa,OAAO,OAAQ;AAChC,UAAM,SAAS,IAAI,MAAM,OAAO,QAAQ,SAAS;AACjD,SAAK,IAAI,MAAM;AAAA,EACjB;AACA,SAAO,CAAC,GAAG,IAAI;AACjB;;;AC3QO,SAAS,KAAK,QAAiB,QAAiB,WAAW,IAAiB;AACjF,QAAM,UAAuB,CAAC;AAG9B,MAAI,WAAW,OAAQ,QAAO;AAG9B,MAAI,UAAU,QAAQ,UAAU,MAAM;AACpC,WAAO,CAAC,EAAE,MAAM,YAAY,UAAU,MAAM,SAAS,IAAI,OAAO,CAAC;AAAA,EACnE;AACA,MAAI,UAAU,QAAQ,UAAU,MAAM;AACpC,WAAO,CAAC,EAAE,MAAM,YAAY,UAAU,MAAM,WAAW,MAAM,OAAO,CAAC;AAAA,EACvE;AAGA,MAAI,OAAO,WAAW,OAAO,QAAQ;AACnC,WAAO,CAAC,EAAE,MAAM,YAAY,UAAU,MAAM,WAAW,MAAM,QAAQ,IAAI,OAAO,CAAC;AAAA,EACnF;AAGA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO,CAAC,EAAE,MAAM,YAAY,UAAU,MAAM,WAAW,MAAM,QAAQ,IAAI,OAAO,CAAC;AAAA,EACnF;AAGA,MAAI,MAAM,QAAQ,MAAM,KAAK,MAAM,QAAQ,MAAM,GAAG;AAClD,UAAM,SAAS,KAAK,IAAI,OAAO,QAAQ,OAAO,MAAM;AACpD,aAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,YAAM,IAAI,WAAW,GAAG,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC;AAChD,UAAI,KAAK,OAAO,QAAQ;AACtB,gBAAQ,KAAK,EAAE,MAAM,GAAG,MAAM,SAAS,IAAI,OAAO,CAAC,EAAE,CAAC;AAAA,MACxD,WAAW,KAAK,OAAO,QAAQ;AAC7B,gBAAQ,KAAK,EAAE,MAAM,GAAG,MAAM,WAAW,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,MAC5D,OAAO;AACL,gBAAQ,KAAK,GAAG,KAAK,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;AAAA,MAC/C;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,QAAM,YAAY;AAClB,QAAM,YAAY;AAClB,QAAM,UAAU,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,SAAS,GAAG,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC;AAE9E,aAAW,OAAO,SAAS;AACzB,UAAM,IAAI,WAAW,GAAG,QAAQ,IAAI,GAAG,KAAK;AAC5C,QAAI,EAAE,OAAO,YAAY;AACvB,cAAQ,KAAK,EAAE,MAAM,GAAG,MAAM,SAAS,IAAI,UAAU,GAAG,EAAE,CAAC;AAAA,IAC7D,WAAW,EAAE,OAAO,YAAY;AAC9B,cAAQ,KAAK,EAAE,MAAM,GAAG,MAAM,WAAW,MAAM,UAAU,GAAG,EAAE,CAAC;AAAA,IACjE,OAAO;AACL,cAAQ,KAAK,GAAG,KAAK,UAAU,GAAG,GAAG,UAAU,GAAG,GAAG,CAAC,CAAC;AAAA,IACzD;AAAA,EACF;AAEA,SAAO;AACT;AAGO,SAAS,WAAW,SAA8B;AACvD,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SAAO,QAAQ,IAAI,OAAK;AACtB,YAAQ,EAAE,MAAM;AAAA,MACd,KAAK;AACH,eAAO,KAAK,EAAE,IAAI,KAAK,KAAK,UAAU,EAAE,EAAE,CAAC;AAAA,MAC7C,KAAK;AACH,eAAO,KAAK,EAAE,IAAI,KAAK,KAAK,UAAU,EAAE,IAAI,CAAC;AAAA,MAC/C,KAAK;AACH,eAAO,KAAK,EAAE,IAAI,KAAK,KAAK,UAAU,EAAE,IAAI,CAAC,WAAM,KAAK,UAAU,EAAE,EAAE,CAAC;AAAA,IAC3E;AAAA,EACF,CAAC,EAAE,KAAK,IAAI;AACd;","names":["historyId"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TierNotGrantedError
3
- } from "./chunk-535SSHBS.js";
3
+ } from "./chunk-HMFC6M2G.js";
4
4
 
5
5
  // src/team/tiers.ts
6
6
  function dekKey(collection, tier) {
@@ -31,4 +31,4 @@ export {
31
31
  effectiveClearance,
32
32
  assertTierAccess
33
33
  };
34
- //# sourceMappingURL=chunk-4TBBMHVC.js.map
34
+ //# sourceMappingURL=chunk-6YEC7LLO.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  FieldFrozenError,
3
3
  InvariantError
4
- } from "./chunk-535SSHBS.js";
4
+ } from "./chunk-HMFC6M2G.js";
5
5
 
6
6
  // src/guards/executor.ts
7
7
  var GuardExecutor = {
@@ -77,4 +77,4 @@ function deepEqual(a, b) {
77
77
  export {
78
78
  GuardExecutor
79
79
  };
80
- //# sourceMappingURL=chunk-ZNQYHJXX.js.map
80
+ //# sourceMappingURL=chunk-AB7JF2KF.js.map
@@ -1,14 +1,17 @@
1
1
  // src/guards/read-only-facade.ts
2
2
  var ReadOnlyVaultFacade = class {
3
3
  _vault;
4
- constructor(vault) {
4
+ _layer;
5
+ constructor(vault, layer = "read") {
5
6
  this._vault = vault;
7
+ this._layer = layer;
6
8
  }
7
9
  collection(name) {
8
10
  const c = this._vault.collection(name);
11
+ const layer = this._layer;
9
12
  return {
10
- get: (id) => c.get(id),
11
- list: () => c.list(),
13
+ get: (id) => c.get(id, { _layer: layer }),
14
+ list: () => c.list({ _layer: layer }),
12
15
  query: () => c.query()
13
16
  };
14
17
  }
@@ -17,4 +20,4 @@ var ReadOnlyVaultFacade = class {
17
20
  export {
18
21
  ReadOnlyVaultFacade
19
22
  };
20
- //# sourceMappingURL=chunk-UMLVJTYV.js.map
23
+ //# sourceMappingURL=chunk-ADB7GPM3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/guards/read-only-facade.ts"],"sourcesContent":["import type { Vault } from '../vault.js'\nimport type { Query } from '../query/builder.js'\nimport type { Layer } from '../i18n/policy.js'\nimport type { ReadOnlyVaultFacade as ReadOnlyVaultFacadeContract } from './types.js'\n\n/**\n * Minimal read-only wrapper over a `Vault`. Used as `ctx.vault` inside\n * guard / derivation callbacks so they can fetch related records without\n * acquiring any write capability.\n *\n * The `layer` tags every `get`/`list` read with the resolution layer it\n * belongs to (#285). A guard-seeded facade reads at `'guard'`, a\n * derivation-seeded one at `'derivation'`, so i18nText / dictKey fields\n * resolve under that layer's `onMissing` policy instead of the `'read'`\n * policy — e.g. a guard read can `substitute` a missing locale (lenient\n * default) while the same field `throw`s on an ordinary app read.\n *\n * `query()` is left untagged: the query/aggregate pipeline reads raw\n * `{locale}` maps (no resolution call site), so a layer tag there would be\n * inert. Routing `mv`/`join` resolution through the pipeline is tracked\n * separately (#285 D2/D3).\n */\nexport class ReadOnlyVaultFacade implements ReadOnlyVaultFacadeContract {\n private readonly _vault: Vault\n private readonly _layer: Layer\n\n constructor(vault: Vault, layer: Layer = 'read') {\n this._vault = vault\n this._layer = layer\n }\n\n collection<T = unknown>(name: string): {\n get(id: string): Promise<T | null>\n list(): Promise<T[]>\n query(): Query<T>\n } {\n const c = this._vault.collection<T>(name)\n const layer = this._layer\n return {\n get: (id: string) => c.get(id, { _layer: layer }),\n list: () => c.list({ _layer: layer }),\n query: () => c.query(),\n }\n }\n}\n"],"mappings":";AAsBO,IAAM,sBAAN,MAAiE;AAAA,EACrD;AAAA,EACA;AAAA,EAEjB,YAAY,OAAc,QAAe,QAAQ;AAC/C,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,WAAwB,MAItB;AACA,UAAM,IAAI,KAAK,OAAO,WAAc,IAAI;AACxC,UAAM,QAAQ,KAAK;AACnB,WAAO;AAAA,MACL,KAAK,CAAC,OAAe,EAAE,IAAI,IAAI,EAAE,QAAQ,MAAM,CAAC;AAAA,MAChD,MAAM,MAAM,EAAE,KAAK,EAAE,QAAQ,MAAM,CAAC;AAAA,MACpC,OAAO,MAAM,EAAE,MAAM;AAAA,IACvB;AAAA,EACF;AACF;","names":[]}
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  NOYDB_FORMAT_VERSION
3
- } from "./chunk-F3BPIPLS.js";
3
+ } from "./chunk-LGPSCKWZ.js";
4
4
  import {
5
5
  encrypt
6
- } from "./chunk-YULZKK4F.js";
6
+ } from "./chunk-QJKZ5WUP.js";
7
7
 
8
8
  // src/blobs/export-blobs.ts
9
9
  var ExportBlobsAbortedError = class extends Error {
@@ -258,4 +258,4 @@ export {
258
258
  BLOB_EVICTION_AUDIT_COLLECTION,
259
259
  runCompaction
260
260
  };
261
- //# sourceMappingURL=chunk-XL35NSEN.js.map
261
+ //# sourceMappingURL=chunk-BUBJYIZ7.js.map
@@ -0,0 +1,125 @@
1
+ import {
2
+ NOYDB_FORMAT_VERSION
3
+ } from "./chunk-LGPSCKWZ.js";
4
+ import {
5
+ decrypt,
6
+ encrypt
7
+ } from "./chunk-QJKZ5WUP.js";
8
+
9
+ // src/forget/strategy.ts
10
+ var NO_FORGET = { subjects: {} };
11
+ function withForgetCascade(opts) {
12
+ return { subjects: { ...opts.subjects } };
13
+ }
14
+
15
+ // src/forget/subject-index.ts
16
+ var SUBJECT_INDEX_COLLECTION = "_subject_index";
17
+ async function sha256HexString(input) {
18
+ const bytes = new TextEncoder().encode(input);
19
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
20
+ return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
21
+ }
22
+ async function subjectKey(subjectId) {
23
+ return sha256HexString(subjectId);
24
+ }
25
+ async function readRefs(adapter, vault, getDEK, encrypted, key) {
26
+ const env = await adapter.get(vault, SUBJECT_INDEX_COLLECTION, key);
27
+ if (!env || !env._data) return [];
28
+ if (!encrypted) return JSON.parse(env._data);
29
+ const dek = await getDEK(SUBJECT_INDEX_COLLECTION);
30
+ const json = await decrypt(env._iv, env._data, dek);
31
+ return JSON.parse(json);
32
+ }
33
+ async function writeRefs(adapter, vault, getDEK, encrypted, key, refs) {
34
+ const json = JSON.stringify(refs);
35
+ let env;
36
+ if (!encrypted) {
37
+ env = { _noydb: NOYDB_FORMAT_VERSION, _v: 1, _ts: (/* @__PURE__ */ new Date()).toISOString(), _iv: "", _data: json };
38
+ } else {
39
+ const dek = await getDEK(SUBJECT_INDEX_COLLECTION);
40
+ const { iv, data } = await encrypt(json, dek);
41
+ env = { _noydb: NOYDB_FORMAT_VERSION, _v: 1, _ts: (/* @__PURE__ */ new Date()).toISOString(), _iv: iv, _data: data };
42
+ }
43
+ await adapter.put(vault, SUBJECT_INDEX_COLLECTION, key, env);
44
+ }
45
+ async function addSubjectRef(adapter, vault, getDEK, encrypted, subjectId, ref) {
46
+ const key = await subjectKey(subjectId);
47
+ const refs = await readRefs(adapter, vault, getDEK, encrypted, key);
48
+ if (refs.some((r) => r.collection === ref.collection && r.id === ref.id)) return;
49
+ refs.push(ref);
50
+ await writeRefs(adapter, vault, getDEK, encrypted, key, refs);
51
+ }
52
+ async function removeSubjectRef(adapter, vault, getDEK, encrypted, subjectId, ref) {
53
+ const key = await subjectKey(subjectId);
54
+ const refs = await readRefs(adapter, vault, getDEK, encrypted, key);
55
+ const next = refs.filter((r) => !(r.collection === ref.collection && r.id === ref.id));
56
+ if (next.length === refs.length) return;
57
+ if (next.length === 0) {
58
+ await adapter.delete(vault, SUBJECT_INDEX_COLLECTION, key);
59
+ return;
60
+ }
61
+ await writeRefs(adapter, vault, getDEK, encrypted, key, next);
62
+ }
63
+ async function lookupSubject(adapter, vault, getDEK, encrypted, subjectId) {
64
+ const key = await subjectKey(subjectId);
65
+ return readRefs(adapter, vault, getDEK, encrypted, key);
66
+ }
67
+ async function rebuildSubjectIndex(adapter, vault, getDEK, encrypted, subjects, decodeRecord) {
68
+ const existing = await adapter.list(vault, SUBJECT_INDEX_COLLECTION);
69
+ for (const k of existing) {
70
+ await adapter.delete(vault, SUBJECT_INDEX_COLLECTION, k);
71
+ }
72
+ const bySubject = /* @__PURE__ */ new Map();
73
+ for (const [collection, field] of Object.entries(subjects)) {
74
+ const ids = await adapter.list(vault, collection);
75
+ for (const id of ids) {
76
+ if (id.startsWith("_")) continue;
77
+ const env = await adapter.get(vault, collection, id);
78
+ if (!env || !env._data) continue;
79
+ const record = await decodeRecord(collection, id, env);
80
+ if (record === null) continue;
81
+ const subjectValue = readDottedPath(record, field);
82
+ if (subjectValue === void 0 || subjectValue === null) continue;
83
+ const subjectId = coerceSubjectId(subjectValue);
84
+ const list = bySubject.get(subjectId) ?? [];
85
+ list.push({ collection, id });
86
+ bySubject.set(subjectId, list);
87
+ }
88
+ }
89
+ let entries = 0;
90
+ for (const [subjectId, refs] of bySubject) {
91
+ const key = await subjectKey(subjectId);
92
+ await writeRefs(adapter, vault, getDEK, encrypted, key, refs);
93
+ entries++;
94
+ }
95
+ return entries;
96
+ }
97
+ function coerceSubjectId(value) {
98
+ if (typeof value === "string") return value;
99
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
100
+ return String(value);
101
+ }
102
+ return JSON.stringify(value);
103
+ }
104
+ function readDottedPath(record, field) {
105
+ if (!field.includes(".")) return record[field];
106
+ let cursor = record;
107
+ for (const segment of field.split(".")) {
108
+ if (cursor === null || cursor === void 0) return void 0;
109
+ cursor = cursor[segment];
110
+ }
111
+ return cursor;
112
+ }
113
+
114
+ export {
115
+ NO_FORGET,
116
+ withForgetCascade,
117
+ SUBJECT_INDEX_COLLECTION,
118
+ addSubjectRef,
119
+ removeSubjectRef,
120
+ lookupSubject,
121
+ rebuildSubjectIndex,
122
+ coerceSubjectId,
123
+ readDottedPath
124
+ };
125
+ //# sourceMappingURL=chunk-C2OYWD5S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/forget/strategy.ts","../src/forget/subject-index.ts"],"sourcesContent":["/**\n * `withForgetCascade` — declaration surface for GDPR right-to-erasure via\n * per-record CEK crypto-shred (#304, step 2 of the CEK security epic).\n *\n * This file holds only the *declaration* shape and the disabled sentinel.\n * The actual erasure machinery lives in:\n * - `subject-index.ts` — the encrypted `_subject_index` reserved collection\n * - `vault.ts` `forget()` — the per-record tombstone + ledger flow\n * - `collection.ts` `_writeTombstone` — the envelope rewrite\n *\n * A `ForgetStrategy` declares which collections carry erasable subject data\n * and the (dotted-path) field on each record that names the data subject.\n * Declaring a collection here ALSO forces `perRecordKeys: true` for it (a\n * shred can only erase a record whose body is keyed off a per-record CEK),\n * so adopters opt into the CEK foundation transitively.\n *\n * @module\n */\nimport type { LedgerEntry } from '../history/ledger/entry.js'\n\n/**\n * User-supplied declaration passed to {@link withForgetCascade}. Maps a\n * collection name to the record field (dotted path supported, e.g.\n * `'billing.buyerId'`) that identifies the data subject for erasure.\n *\n * ```ts\n * withForgetCascade({ subjects: { invoices: 'buyerId', contacts: 'id' } })\n * ```\n */\nexport interface SubjectDeclaration {\n readonly subjects: Record<string, string>\n}\n\n/**\n * Resolved forget strategy threaded through Noydb → every Vault. Carries\n * the same `subjects` map the user declared. `NO_FORGET` (empty map) is the\n * off-by-default sentinel; `vault.forget()` throws\n * `ForgetStrategyNotConfiguredError` when the map is empty.\n */\nexport interface ForgetStrategy {\n /** Collection → subject-field (dotted path). Empty under `NO_FORGET`. */\n readonly subjects: Readonly<Record<string, string>>\n}\n\n/**\n * Disabled sentinel — no collections declare a subject field. `vault.forget()`\n * refuses with `ForgetStrategyNotConfiguredError`; no write hooks register; no\n * collection is forced into `perRecordKeys`. Non-adopters pay nothing.\n */\nexport const NO_FORGET: ForgetStrategy = { subjects: {} }\n\n/**\n * Declare GDPR crypto-shred for one or more collections.\n *\n * Each declared collection is forced to `perRecordKeys: true` (a shred can\n * only guarantee erasure of a record whose body is keyed off a per-record\n * CEK). On write, Noydb extracts `record[subjectField]` and maintains an\n * encrypted `_subject_index` mapping `subject → [{collection, id}]`, so\n * `vault.forget(subjectId)` can find every record for a subject and rewrite\n * each to a tombstone (body + history permanently undecryptable) while the\n * collection DEK and every other record stay intact.\n *\n * @example\n * ```ts\n * createNoydb({\n * secret, user,\n * forgetStrategy: withForgetCascade({ subjects: { invoices: 'buyerId' } }),\n * })\n * const result = await vault.forget('buyer-123')\n * // → { subject, recordsShredded, historyVersionsShredded, collections, … }\n * ```\n */\nexport function withForgetCascade(opts: SubjectDeclaration): ForgetStrategy {\n return { subjects: { ...opts.subjects } }\n}\n\n/**\n * The outcome of a `vault.forget(subjectId)` call.\n *\n * `unmigratedRecords` lists `collection:id` pairs that were tombstoned but\n * whose body had NOT been migrated to a per-record CEK at shred time (legacy\n * body still under the shared collection DEK). Those records are tombstoned\n * (live envelope + history stripped) but their pre-shred ciphertext, if it\n * leaked into a backup before migration, remains decryptable under the\n * collection DEK — so erasure-completeness is NOT guaranteed for them. Run\n * the per-record-CEK migration pass, then re-forget, to close the gap.\n *\n * Blob attachments (#365): a shredded record's **erasable** blobs (on a\n * `perRecordKeys` collection) are crypto-shredded inline — `blobsShredded`\n * counts those taken to refCount 0 (BlobObject deleted → chunks permanently\n * undecryptable), `blobsRetainedShared` counts those still referenced by\n * another record (shared content legitimately persists for its other owner).\n * `blobResidueCollections` now lists only collections with blobs that could\n * NOT be crypto-shredded: **legacy** blobs (no per-blob `_cek`, chunks under\n * the shared `_blob` DEK — migrate them), or a session without the blob\n * subsystem loaded. An all-erasable subject yields an empty residue list.\n */\nexport interface ForgetResult {\n /** The subject id passed to `forget()`. Echoed for caller convenience. */\n readonly subject: string\n /** Count of live records rewritten to a tombstone. */\n readonly recordsShredded: number\n /** Count of `_history` envelopes tombstoned across all shredded records. */\n readonly historyVersionsShredded: number\n /** Distinct collections that had at least one record shredded. */\n readonly collections: readonly string[]\n /** `collection:id` pairs shredded while still un-migrated (see type docs). */\n readonly unmigratedRecords: readonly string[]\n /** Count of erasable blobs crypto-shredded (refCount → 0, BlobObject deleted). */\n readonly blobsShredded: number\n /** Count of erasable blobs retained because still referenced elsewhere (shared). */\n readonly blobsRetainedShared: number\n /** Collections with blobs that could NOT be crypto-shredded — legacy (no `_cek`) or blobs disabled (see type docs). */\n readonly blobResidueCollections: readonly string[]\n /** The single `op:'forget'` ledger entry appended for this erasure. */\n readonly ledgerEntry: LedgerEntry\n}\n","/**\n * The encrypted subject index (#304).\n *\n * GDPR crypto-shred needs to answer \"which records belong to data subject\n * X?\" portably (the index must travel with the vault/bundle) WITHOUT leaking\n * subject-equivalence to the store. The rejected alternative — an unencrypted\n * subject tag in envelope metadata — would let anyone with store access see\n * which records share a subject. Instead we keep a reserved `_subject_index`\n * collection, encrypted under its OWN DEK (`getDEK('_subject_index')`):\n *\n * - record id = `sha256Hex(subjectId)` — the raw subject id never appears\n * as a key, so the store can't correlate index entries to a known subject.\n * - record body = AES-GCM(JSON `[{ collection, id }]`) under the index DEK.\n *\n * ## Concurrency (RISK #3 — known v1 limitation)\n *\n * `addSubjectRef` / `removeSubjectRef` are read-modify-write with no CAS. The\n * design assumes a SINGLE WRITER (the noy-db single-process write model). Two\n * concurrent writers racing on the SAME subject can lose an entry (last-write\n * wins on the ref list). This is documented, not fixed in v1:\n * `rebuildSubjectIndex` performs a full scan to recover a correct index from\n * the canonical records, so a lost ref is recoverable. A CAS-backed index is\n * deferred to a later slice.\n *\n * @module\n */\nimport { encrypt, decrypt } from '../crypto.js'\nimport type { NoydbStore, EncryptedEnvelope } from '../types.js'\nimport { NOYDB_FORMAT_VERSION } from '../types.js'\n\n/** Reserved collection holding the encrypted subject → records index. */\nexport const SUBJECT_INDEX_COLLECTION = '_subject_index'\n\n/** A single record reference held in a subject's index entry. */\nexport interface SubjectRef {\n readonly collection: string\n readonly id: string\n}\n\ntype GetDEK = (collectionName: string) => Promise<CryptoKey>\n\n/** SHA-256 hex of a UTF-8 string. The subject-index record key derivation. */\nasync function sha256HexString(input: string): Promise<string> {\n const bytes = new TextEncoder().encode(input)\n const digest = await globalThis.crypto.subtle.digest('SHA-256', bytes)\n return Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/** Stable subject-index record id for a subject id. */\nexport async function subjectKey(subjectId: string): Promise<string> {\n return sha256HexString(subjectId)\n}\n\n/** Read + decrypt the ref list for a subject. Returns `[]` when absent. */\nasync function readRefs(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n key: string,\n): Promise<SubjectRef[]> {\n const env = await adapter.get(vault, SUBJECT_INDEX_COLLECTION, key)\n if (!env || !env._data) return []\n if (!encrypted) return JSON.parse(env._data) as SubjectRef[]\n const dek = await getDEK(SUBJECT_INDEX_COLLECTION)\n const json = await decrypt(env._iv, env._data, dek)\n return JSON.parse(json) as SubjectRef[]\n}\n\n/** Encrypt + write a ref list for a subject under its derived key. */\nasync function writeRefs(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n key: string,\n refs: SubjectRef[],\n): Promise<void> {\n const json = JSON.stringify(refs)\n let env: EncryptedEnvelope\n if (!encrypted) {\n env = { _noydb: NOYDB_FORMAT_VERSION, _v: 1, _ts: new Date().toISOString(), _iv: '', _data: json }\n } else {\n const dek = await getDEK(SUBJECT_INDEX_COLLECTION)\n const { iv, data } = await encrypt(json, dek)\n env = { _noydb: NOYDB_FORMAT_VERSION, _v: 1, _ts: new Date().toISOString(), _iv: iv, _data: data }\n }\n await adapter.put(vault, SUBJECT_INDEX_COLLECTION, key, env)\n}\n\n/**\n * Add a `{ collection, id }` ref to a subject's index entry (idempotent —\n * a duplicate ref is not appended). Read-modify-write; see the concurrency\n * note in the module docstring.\n */\nexport async function addSubjectRef(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n subjectId: string,\n ref: SubjectRef,\n): Promise<void> {\n const key = await subjectKey(subjectId)\n const refs = await readRefs(adapter, vault, getDEK, encrypted, key)\n if (refs.some((r) => r.collection === ref.collection && r.id === ref.id)) return\n refs.push(ref)\n await writeRefs(adapter, vault, getDEK, encrypted, key, refs)\n}\n\n/**\n * Remove a `{ collection, id }` ref from a subject's index entry. When the\n * last ref is removed the (now empty) entry is deleted so the store holds no\n * residual key for an erased subject.\n */\nexport async function removeSubjectRef(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n subjectId: string,\n ref: SubjectRef,\n): Promise<void> {\n const key = await subjectKey(subjectId)\n const refs = await readRefs(adapter, vault, getDEK, encrypted, key)\n const next = refs.filter((r) => !(r.collection === ref.collection && r.id === ref.id))\n if (next.length === refs.length) return\n if (next.length === 0) {\n await adapter.delete(vault, SUBJECT_INDEX_COLLECTION, key)\n return\n }\n await writeRefs(adapter, vault, getDEK, encrypted, key, next)\n}\n\n/** Look up every record ref for a subject. Returns `[]` when none exist. */\nexport async function lookupSubject(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n subjectId: string,\n): Promise<SubjectRef[]> {\n const key = await subjectKey(subjectId)\n return readRefs(adapter, vault, getDEK, encrypted, key)\n}\n\n/**\n * Rebuild the entire subject index from the canonical records (the recovery\n * path for the documented read-modify-write race). Scans each declared\n * collection, reads `record[subjectField]` (dotted path), and rewrites the\n * index from scratch. Tombstoned (already-shredded) records contribute no\n * ref — their body is gone, so they cannot be re-indexed.\n *\n * `decodeRecord` decrypts an envelope to a plain object (or returns null for\n * a tombstone / unreadable record); supplied by the caller so this module\n * stays free of Collection internals.\n */\nexport async function rebuildSubjectIndex(\n adapter: NoydbStore,\n vault: string,\n getDEK: GetDEK,\n encrypted: boolean,\n subjects: Readonly<Record<string, string>>,\n decodeRecord: (collection: string, id: string, env: EncryptedEnvelope) => Promise<Record<string, unknown> | null>,\n): Promise<number> {\n // Drop every existing index entry first so removed refs don't linger.\n const existing = await adapter.list(vault, SUBJECT_INDEX_COLLECTION)\n for (const k of existing) {\n await adapter.delete(vault, SUBJECT_INDEX_COLLECTION, k)\n }\n\n // subjectId → refs, accumulated across all declared collections.\n const bySubject = new Map<string, SubjectRef[]>()\n for (const [collection, field] of Object.entries(subjects)) {\n const ids = await adapter.list(vault, collection)\n for (const id of ids) {\n if (id.startsWith('_')) continue\n const env = await adapter.get(vault, collection, id)\n if (!env || !env._data) continue // missing or tombstone\n const record = await decodeRecord(collection, id, env)\n if (record === null) continue\n const subjectValue = readDottedPath(record, field)\n if (subjectValue === undefined || subjectValue === null) continue\n const subjectId = coerceSubjectId(subjectValue)\n const list = bySubject.get(subjectId) ?? []\n list.push({ collection, id })\n bySubject.set(subjectId, list)\n }\n }\n\n let entries = 0\n for (const [subjectId, refs] of bySubject) {\n const key = await subjectKey(subjectId)\n await writeRefs(adapter, vault, getDEK, encrypted, key, refs)\n entries++\n }\n return entries\n}\n\n/**\n * Coerce a read subject-field value to a stable string id. Primitives use\n * their natural string form; objects/arrays are JSON-stringified so structural\n * subjects still get a deterministic key (avoids the `[object Object]` trap).\n */\nexport function coerceSubjectId(value: unknown): string {\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n return String(value)\n }\n return JSON.stringify(value)\n}\n\n/** Read a (possibly dotted) field path from a plain record. */\nexport function readDottedPath(record: Record<string, unknown>, field: string): unknown {\n if (!field.includes('.')) return record[field]\n let cursor: unknown = record\n for (const segment of field.split('.')) {\n if (cursor === null || cursor === undefined) return undefined\n cursor = (cursor as Record<string, unknown>)[segment]\n }\n return cursor\n}\n"],"mappings":"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","names":[]}