@noy-db/hub 0.2.0-pre.17 → 0.2.0-pre.19

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 (301) hide show
  1. package/dist/aggregate/index.cjs +227 -3
  2. package/dist/aggregate/index.cjs.map +1 -1
  3. package/dist/aggregate/index.d.cts +3 -3
  4. package/dist/aggregate/index.d.ts +3 -3
  5. package/dist/aggregate/index.js +5 -4
  6. package/dist/aggregate/index.js.map +1 -1
  7. package/dist/attestation/index.cjs.map +1 -1
  8. package/dist/attestation/index.d.cts +5 -5
  9. package/dist/attestation/index.d.ts +5 -5
  10. package/dist/attestation/index.js +6 -6
  11. package/dist/blobs/index.cjs +4 -10
  12. package/dist/blobs/index.cjs.map +1 -1
  13. package/dist/blobs/index.d.cts +6 -6
  14. package/dist/blobs/index.d.ts +6 -6
  15. package/dist/blobs/index.js +6 -6
  16. package/dist/bundle/index.cjs +1587 -392
  17. package/dist/bundle/index.cjs.map +1 -1
  18. package/dist/bundle/index.d.cts +7 -7
  19. package/dist/bundle/index.d.ts +7 -7
  20. package/dist/bundle/index.js +10 -10
  21. package/dist/{chunk-NBBMMJ2H.js → chunk-3FSMVWBN.js} +4 -4
  22. package/dist/{chunk-HGVSHKZW.js → chunk-3Q2AOPLT.js} +100 -29
  23. package/dist/chunk-3Q2AOPLT.js.map +1 -0
  24. package/dist/{chunk-SHX5QBCI.js → chunk-4ULLGYPA.js} +3 -3
  25. package/dist/{chunk-CD2AVTEM.js → chunk-5IGWRMEC.js} +5 -5
  26. package/dist/{chunk-QO6RGLLD.js → chunk-6KESZO5D.js} +35 -7
  27. package/dist/chunk-6KESZO5D.js.map +1 -0
  28. package/dist/{chunk-GP3SDSH2.js → chunk-6OSOE6BY.js} +15 -2
  29. package/dist/chunk-6OSOE6BY.js.map +1 -0
  30. package/dist/{chunk-F4G63NTZ.js → chunk-7C6VFNIY.js} +2 -2
  31. package/dist/{chunk-XJV6OB4D.js → chunk-7HD67R6U.js} +2 -2
  32. package/dist/{chunk-UMLVJTYV.js → chunk-ADB7GPM3.js} +7 -4
  33. package/dist/chunk-ADB7GPM3.js.map +1 -0
  34. package/dist/{chunk-NYSYPFXJ.js → chunk-B6E5IRPJ.js} +3 -3
  35. package/dist/chunk-CYNTFU2D.js +129 -0
  36. package/dist/chunk-CYNTFU2D.js.map +1 -0
  37. package/dist/{chunk-ZEGSDPB7.js → chunk-DJF3FXW5.js} +35 -1
  38. package/dist/chunk-DJF3FXW5.js.map +1 -0
  39. package/dist/{chunk-3G3W65EQ.js → chunk-DY3EOJEN.js} +2 -2
  40. package/dist/{chunk-YYVZYTWW.js → chunk-E66DSTJP.js} +3 -3
  41. package/dist/{chunk-5LIROIDM.js → chunk-FBLAWK6A.js} +2 -2
  42. package/dist/{chunk-E77UKJYL.js → chunk-FPHRTW2Z.js} +5 -5
  43. package/dist/{state-vault-W2OEABNO.js → chunk-G4PYA575.js} +24 -7
  44. package/dist/chunk-G4PYA575.js.map +1 -0
  45. package/dist/{chunk-U5QCMH3W.js → chunk-GKQAU52M.js} +4 -4
  46. package/dist/{chunk-2FU2FTXD.js → chunk-GYAWXHFO.js} +2 -2
  47. package/dist/{chunk-ROPJVUG3.js → chunk-H42KZXNV.js} +5 -210
  48. package/dist/chunk-H42KZXNV.js.map +1 -0
  49. package/dist/{chunk-XPIHJ34I.js → chunk-IBVTH4JR.js} +4 -4
  50. package/dist/{chunk-C3HYQPV4.js → chunk-IVP5IVON.js} +2 -2
  51. package/dist/{chunk-BL5GYANC.js → chunk-KEDJDWWQ.js} +3 -3
  52. package/dist/{chunk-I5IUYN7B.js → chunk-KNKNOJFS.js} +3 -3
  53. package/dist/chunk-KNKNOJFS.js.map +1 -0
  54. package/dist/{chunk-D77ZQSQQ.js → chunk-KYGGXXT6.js} +829 -170
  55. package/dist/chunk-KYGGXXT6.js.map +1 -0
  56. package/dist/{chunk-J7RWBXFY.js → chunk-LSIIPKYT.js} +2 -2
  57. package/dist/{chunk-BSZOCSDZ.js → chunk-M3FPNTO2.js} +4 -4
  58. package/dist/{chunk-XMVHEWF6.js → chunk-MI36HL5G.js} +4 -4
  59. package/dist/{chunk-ROVO6NPJ.js → chunk-NN6IISZO.js} +58 -3
  60. package/dist/chunk-NN6IISZO.js.map +1 -0
  61. package/dist/{chunk-7H2GEJ3O.js → chunk-OBMYMKGO.js} +29 -6
  62. package/dist/{chunk-7H2GEJ3O.js.map → chunk-OBMYMKGO.js.map} +1 -1
  63. package/dist/{chunk-UNTGHX5A.js → chunk-OKOKPYWH.js} +2 -2
  64. package/dist/{chunk-WV7WV6JO.js → chunk-OY7RX2VL.js} +9 -15
  65. package/dist/chunk-OY7RX2VL.js.map +1 -0
  66. package/dist/{chunk-H2MRGONI.js → chunk-PTGQPWMV.js} +2 -2
  67. package/dist/{chunk-BJSLBUJ7.js → chunk-PWFTQHYX.js} +2 -2
  68. package/dist/{chunk-5AXTH4QZ.js → chunk-Q5MCHUXZ.js} +2 -2
  69. package/dist/{chunk-QHM6XEAH.js → chunk-S22UOMHM.js} +6 -6
  70. package/dist/{chunk-WIAOUFFB.js → chunk-S3XA7G35.js} +2 -2
  71. package/dist/{chunk-SISBMAPO.js → chunk-SHIUFIPW.js} +1 -1
  72. package/dist/chunk-SHIUFIPW.js.map +1 -0
  73. package/dist/{chunk-KCEHMDZF.js → chunk-U7JNBSS3.js} +3 -3
  74. package/dist/{chunk-ZNGPEV5J.js → chunk-V3VIRTTE.js} +3 -3
  75. package/dist/{chunk-TIDXB5DF.js → chunk-V5FZWQNN.js} +4 -4
  76. package/dist/chunk-VEIVAYJ7.js +361 -0
  77. package/dist/chunk-VEIVAYJ7.js.map +1 -0
  78. package/dist/{chunk-AEIKD3PP.js → chunk-VNUE6FHP.js} +3 -3
  79. package/dist/{chunk-DYYYUW5D.js → chunk-WFK2EVYU.js} +10 -2
  80. package/dist/chunk-WFK2EVYU.js.map +1 -0
  81. package/dist/{chunk-XMHUK5PN.js → chunk-X7FJMKT3.js} +2 -2
  82. package/dist/{chunk-FEJDVE3Z.js → chunk-XPH3FWME.js} +7 -2
  83. package/dist/{chunk-FEJDVE3Z.js.map → chunk-XPH3FWME.js.map} +1 -1
  84. package/dist/{chunk-SNMJ7SB3.js → chunk-Y5J63SMF.js} +5 -5
  85. package/dist/{chunk-M476FOQ7.js → chunk-YLRRU72W.js} +2 -2
  86. package/dist/{chunk-DWEBTE2W.js → chunk-YX333DPS.js} +4 -4
  87. package/dist/{chunk-BH3X5L6A.js → chunk-YZE6C3TQ.js} +3 -3
  88. package/dist/consent/index.cjs.map +1 -1
  89. package/dist/consent/index.d.cts +6 -6
  90. package/dist/consent/index.d.ts +6 -6
  91. package/dist/consent/index.js +3 -3
  92. package/dist/{crypto-7BN2HDWG.js → crypto-B46VNH6X.js} +3 -3
  93. package/dist/{delegation-MGH5SODX.js → delegation-5HON72PV.js} +5 -5
  94. package/dist/derivations/index.cjs +82 -2
  95. package/dist/derivations/index.cjs.map +1 -1
  96. package/dist/derivations/index.d.cts +7 -7
  97. package/dist/derivations/index.d.ts +7 -7
  98. package/dist/derivations/index.js +8 -6
  99. package/dist/{dev-unlock-iXbYFAWl.d.cts → dev-unlock-BR1rMOS-.d.cts} +1 -1
  100. package/dist/{dev-unlock-CI1ijTML.d.ts → dev-unlock-whL49sxV.d.ts} +1 -1
  101. package/dist/{errors-Dz64FA65.d.cts → errors-DL-zTrrF.d.cts} +29 -1
  102. package/dist/{errors-Dz64FA65.d.ts → errors-DL-zTrrF.d.ts} +29 -1
  103. package/dist/executor-44R5CUS2.js +12 -0
  104. package/dist/executor-AOACUK7Z.js +8 -0
  105. package/dist/executor-OKFLQCDW.js +8 -0
  106. package/dist/{fanout-sidecar-FIJJ46YG.js → fanout-sidecar-DCQWJQ6S.js} +2 -2
  107. package/dist/forget/index.cjs.map +1 -1
  108. package/dist/forget/index.d.cts +1 -1
  109. package/dist/forget/index.d.ts +1 -1
  110. package/dist/forget/index.js +4 -4
  111. package/dist/guards/index.cjs +80 -3
  112. package/dist/guards/index.cjs.map +1 -1
  113. package/dist/guards/index.d.cts +7 -7
  114. package/dist/guards/index.d.ts +7 -7
  115. package/dist/guards/index.js +8 -4
  116. package/dist/{hash-tEcM5fnv.d.cts → hash-BEUBmmI4.d.cts} +1 -1
  117. package/dist/{hash-blk7Bkes.d.ts → hash-Dtb7FwWd.d.ts} +1 -1
  118. package/dist/history/index.cjs.map +1 -1
  119. package/dist/history/index.d.cts +7 -7
  120. package/dist/history/index.d.ts +7 -7
  121. package/dist/history/index.js +5 -5
  122. package/dist/i18n/index.cjs +149 -132
  123. package/dist/i18n/index.cjs.map +1 -1
  124. package/dist/i18n/index.d.cts +6 -6
  125. package/dist/i18n/index.d.ts +6 -6
  126. package/dist/i18n/index.js +14 -14
  127. package/dist/{index-u-kWzSrL.d.cts → index-BM7O48Ur.d.cts} +85 -9
  128. package/dist/{index-C-SSRIxP.d.cts → index-BMmajblo.d.cts} +14 -0
  129. package/dist/{index-C-SSRIxP.d.ts → index-BMmajblo.d.ts} +14 -0
  130. package/dist/{index-DpU6KWof.d.ts → index-BelbyUwz.d.ts} +85 -9
  131. package/dist/index.cjs +2206 -992
  132. package/dist/index.cjs.map +1 -1
  133. package/dist/index.d.cts +29 -16
  134. package/dist/index.d.ts +29 -16
  135. package/dist/index.js +76 -54
  136. package/dist/index.js.map +1 -1
  137. package/dist/indexing/index.cjs.map +1 -1
  138. package/dist/indexing/index.js +4 -4
  139. package/dist/issue-EPA2PSWP.js +12 -0
  140. package/dist/{ledger-LFVLHE5H.js → ledger-LS6GXCBP.js} +5 -5
  141. package/dist/materialized-views/index.cjs +257 -4
  142. package/dist/materialized-views/index.cjs.map +1 -1
  143. package/dist/materialized-views/index.d.cts +7 -7
  144. package/dist/materialized-views/index.d.ts +7 -7
  145. package/dist/materialized-views/index.js +8 -7
  146. package/dist/noydb-BVKFP74P.js +38 -0
  147. package/dist/overlay-views/index.cjs.map +1 -1
  148. package/dist/overlay-views/index.d.cts +7 -7
  149. package/dist/overlay-views/index.d.ts +7 -7
  150. package/dist/overlay-views/index.js +4 -4
  151. package/dist/periods/index.cjs.map +1 -1
  152. package/dist/periods/index.d.cts +6 -6
  153. package/dist/periods/index.d.ts +6 -6
  154. package/dist/periods/index.js +5 -5
  155. package/dist/{public-envelope-RXZNP3V6.js → public-envelope-AGU6SS4Z.js} +4 -4
  156. package/dist/query/index.cjs +320 -28
  157. package/dist/query/index.cjs.map +1 -1
  158. package/dist/query/index.d.cts +3 -3
  159. package/dist/query/index.d.ts +3 -3
  160. package/dist/query/index.js +7 -6
  161. package/dist/read-only-facade-EX6WZZBP.js +7 -0
  162. package/dist/registry-ERNAMRDE.js +8 -0
  163. package/dist/registry-EXTHSXQW.js +8 -0
  164. package/dist/{registry-SECUWSGY.js → registry-RDPTFXQ7.js} +3 -3
  165. package/dist/{revoke-B54H2S2W.js → revoke-IFLXEZA5.js} +6 -6
  166. package/dist/sealed-record/index.cjs.map +1 -1
  167. package/dist/sealed-record/index.d.cts +1 -1
  168. package/dist/sealed-record/index.d.ts +1 -1
  169. package/dist/sealed-record/index.js +2 -2
  170. package/dist/session/index.cjs.map +1 -1
  171. package/dist/session/index.d.cts +7 -7
  172. package/dist/session/index.d.ts +7 -7
  173. package/dist/session/index.js +3 -3
  174. package/dist/shadow/index.cjs.map +1 -1
  175. package/dist/shadow/index.d.cts +6 -6
  176. package/dist/shadow/index.d.ts +6 -6
  177. package/dist/shadow/index.js +2 -2
  178. package/dist/{signer-YSXZT574.js → signer-UNWOUJAK.js} +5 -5
  179. package/dist/snapshots/index.cjs.map +1 -1
  180. package/dist/snapshots/index.d.cts +6 -6
  181. package/dist/snapshots/index.d.ts +6 -6
  182. package/dist/snapshots/index.js +4 -4
  183. package/dist/{stale-TOA36SRK.js → stale-NTEV5SLX.js} +2 -2
  184. package/dist/state-vault-TUTFRTOA.js +14 -0
  185. package/dist/state-vault-TUTFRTOA.js.map +1 -0
  186. package/dist/store/index.cjs +8 -0
  187. package/dist/store/index.cjs.map +1 -1
  188. package/dist/store/index.d.cts +13 -6
  189. package/dist/store/index.d.ts +13 -6
  190. package/dist/store/index.js +2 -2
  191. package/dist/{strategy-4M9jo172.d.ts → strategy-BDxQnnTX.d.ts} +315 -4
  192. package/dist/{strategy-CLC1j79g.d.cts → strategy-C5ol6NdV.d.cts} +315 -4
  193. package/dist/sync/index.cjs.map +1 -1
  194. package/dist/sync/index.d.cts +5 -5
  195. package/dist/sync/index.d.ts +5 -5
  196. package/dist/sync/index.js +4 -4
  197. package/dist/team/index.cjs.map +1 -1
  198. package/dist/team/index.d.cts +6 -6
  199. package/dist/team/index.d.ts +6 -6
  200. package/dist/team/index.js +8 -8
  201. package/dist/transition-guard-B1N82hMf.d.cts +165 -0
  202. package/dist/transition-guard-C__YeF3_.d.ts +165 -0
  203. package/dist/tx/index.cjs.map +1 -1
  204. package/dist/tx/index.d.cts +6 -6
  205. package/dist/tx/index.d.ts +6 -6
  206. package/dist/tx/index.js +3 -3
  207. package/dist/{types-CljIHm_J.d.ts → types-CraiZOyO.d.ts} +609 -305
  208. package/dist/{types-CrSpRDuG.d.cts → types-D-gr5t0G.d.cts} +609 -305
  209. package/dist/{ulid-CrI7PPbA.d.cts → ulid-DQnSAP5W.d.cts} +1 -1
  210. package/dist/{ulid-CWfL2Vfv.d.ts → ulid-FFRRHkVf.d.ts} +1 -1
  211. package/dist/util/index.cjs.map +1 -1
  212. package/dist/util/index.js +1 -1
  213. package/dist/{vault-group-DHAHFX2A.js → vault-group-27EV7KB4.js} +205 -8
  214. package/dist/vault-group-27EV7KB4.js.map +1 -0
  215. package/dist/{with-materialized-view-NzF71cG_.d.cts → with-materialized-view-BboqxyV3.d.cts} +1 -1
  216. package/dist/{with-materialized-view-B892zYZV.d.ts → with-materialized-view-CguCeVcT.d.ts} +1 -1
  217. package/dist/{with-overlayed-view-CR6m7CHe.d.ts → with-overlayed-view-DO08u_tx.d.ts} +1 -1
  218. package/dist/{with-overlayed-view-UI8qSGL4.d.cts → with-overlayed-view-mmsg5Of3.d.cts} +1 -1
  219. package/dist/with-rollup-_TyBzz3T.d.ts +47 -0
  220. package/dist/with-rollup-aaxOZcIb.d.cts +47 -0
  221. package/package.json +3 -3
  222. package/dist/chunk-D77ZQSQQ.js.map +0 -1
  223. package/dist/chunk-DYYYUW5D.js.map +0 -1
  224. package/dist/chunk-GP3SDSH2.js.map +0 -1
  225. package/dist/chunk-HGVSHKZW.js.map +0 -1
  226. package/dist/chunk-I5IUYN7B.js.map +0 -1
  227. package/dist/chunk-JDWE6JMX.js +0 -139
  228. package/dist/chunk-JDWE6JMX.js.map +0 -1
  229. package/dist/chunk-PDULVIBY.js +0 -63
  230. package/dist/chunk-PDULVIBY.js.map +0 -1
  231. package/dist/chunk-QO6RGLLD.js.map +0 -1
  232. package/dist/chunk-ROPJVUG3.js.map +0 -1
  233. package/dist/chunk-ROVO6NPJ.js.map +0 -1
  234. package/dist/chunk-SISBMAPO.js.map +0 -1
  235. package/dist/chunk-UMLVJTYV.js.map +0 -1
  236. package/dist/chunk-WV7WV6JO.js.map +0 -1
  237. package/dist/chunk-ZEGSDPB7.js.map +0 -1
  238. package/dist/executor-3W63Y44O.js +0 -11
  239. package/dist/executor-CFFWPWBJ.js +0 -8
  240. package/dist/executor-VDQQOR4F.js +0 -8
  241. package/dist/immutable-guard-B5M95nbq.d.ts +0 -82
  242. package/dist/immutable-guard-qN3zF8o1.d.cts +0 -82
  243. package/dist/issue-TTMGHQ2J.js +0 -12
  244. package/dist/noydb-36S6GQNC.js +0 -37
  245. package/dist/read-only-facade-ITU6L7BL.js +0 -7
  246. package/dist/registry-3YFLZ7WD.js +0 -8
  247. package/dist/registry-TGZISEWC.js +0 -8
  248. package/dist/state-vault-W2OEABNO.js.map +0 -1
  249. package/dist/vault-group-DHAHFX2A.js.map +0 -1
  250. package/dist/with-derivation-BZ2y4bzF.d.ts +0 -13
  251. package/dist/with-derivation-Bozs8DmD.d.cts +0 -13
  252. /package/dist/{chunk-NBBMMJ2H.js.map → chunk-3FSMVWBN.js.map} +0 -0
  253. /package/dist/{chunk-SHX5QBCI.js.map → chunk-4ULLGYPA.js.map} +0 -0
  254. /package/dist/{chunk-CD2AVTEM.js.map → chunk-5IGWRMEC.js.map} +0 -0
  255. /package/dist/{chunk-F4G63NTZ.js.map → chunk-7C6VFNIY.js.map} +0 -0
  256. /package/dist/{chunk-XJV6OB4D.js.map → chunk-7HD67R6U.js.map} +0 -0
  257. /package/dist/{chunk-NYSYPFXJ.js.map → chunk-B6E5IRPJ.js.map} +0 -0
  258. /package/dist/{chunk-3G3W65EQ.js.map → chunk-DY3EOJEN.js.map} +0 -0
  259. /package/dist/{chunk-YYVZYTWW.js.map → chunk-E66DSTJP.js.map} +0 -0
  260. /package/dist/{chunk-5LIROIDM.js.map → chunk-FBLAWK6A.js.map} +0 -0
  261. /package/dist/{chunk-E77UKJYL.js.map → chunk-FPHRTW2Z.js.map} +0 -0
  262. /package/dist/{chunk-U5QCMH3W.js.map → chunk-GKQAU52M.js.map} +0 -0
  263. /package/dist/{chunk-2FU2FTXD.js.map → chunk-GYAWXHFO.js.map} +0 -0
  264. /package/dist/{chunk-XPIHJ34I.js.map → chunk-IBVTH4JR.js.map} +0 -0
  265. /package/dist/{chunk-C3HYQPV4.js.map → chunk-IVP5IVON.js.map} +0 -0
  266. /package/dist/{chunk-BL5GYANC.js.map → chunk-KEDJDWWQ.js.map} +0 -0
  267. /package/dist/{chunk-J7RWBXFY.js.map → chunk-LSIIPKYT.js.map} +0 -0
  268. /package/dist/{chunk-BSZOCSDZ.js.map → chunk-M3FPNTO2.js.map} +0 -0
  269. /package/dist/{chunk-XMVHEWF6.js.map → chunk-MI36HL5G.js.map} +0 -0
  270. /package/dist/{chunk-UNTGHX5A.js.map → chunk-OKOKPYWH.js.map} +0 -0
  271. /package/dist/{chunk-H2MRGONI.js.map → chunk-PTGQPWMV.js.map} +0 -0
  272. /package/dist/{chunk-BJSLBUJ7.js.map → chunk-PWFTQHYX.js.map} +0 -0
  273. /package/dist/{chunk-5AXTH4QZ.js.map → chunk-Q5MCHUXZ.js.map} +0 -0
  274. /package/dist/{chunk-QHM6XEAH.js.map → chunk-S22UOMHM.js.map} +0 -0
  275. /package/dist/{chunk-WIAOUFFB.js.map → chunk-S3XA7G35.js.map} +0 -0
  276. /package/dist/{chunk-KCEHMDZF.js.map → chunk-U7JNBSS3.js.map} +0 -0
  277. /package/dist/{chunk-ZNGPEV5J.js.map → chunk-V3VIRTTE.js.map} +0 -0
  278. /package/dist/{chunk-TIDXB5DF.js.map → chunk-V5FZWQNN.js.map} +0 -0
  279. /package/dist/{chunk-AEIKD3PP.js.map → chunk-VNUE6FHP.js.map} +0 -0
  280. /package/dist/{chunk-XMHUK5PN.js.map → chunk-X7FJMKT3.js.map} +0 -0
  281. /package/dist/{chunk-SNMJ7SB3.js.map → chunk-Y5J63SMF.js.map} +0 -0
  282. /package/dist/{chunk-M476FOQ7.js.map → chunk-YLRRU72W.js.map} +0 -0
  283. /package/dist/{chunk-DWEBTE2W.js.map → chunk-YX333DPS.js.map} +0 -0
  284. /package/dist/{chunk-BH3X5L6A.js.map → chunk-YZE6C3TQ.js.map} +0 -0
  285. /package/dist/{crypto-7BN2HDWG.js.map → crypto-B46VNH6X.js.map} +0 -0
  286. /package/dist/{delegation-MGH5SODX.js.map → delegation-5HON72PV.js.map} +0 -0
  287. /package/dist/{executor-3W63Y44O.js.map → executor-44R5CUS2.js.map} +0 -0
  288. /package/dist/{executor-CFFWPWBJ.js.map → executor-AOACUK7Z.js.map} +0 -0
  289. /package/dist/{executor-VDQQOR4F.js.map → executor-OKFLQCDW.js.map} +0 -0
  290. /package/dist/{fanout-sidecar-FIJJ46YG.js.map → fanout-sidecar-DCQWJQ6S.js.map} +0 -0
  291. /package/dist/{issue-TTMGHQ2J.js.map → issue-EPA2PSWP.js.map} +0 -0
  292. /package/dist/{ledger-LFVLHE5H.js.map → ledger-LS6GXCBP.js.map} +0 -0
  293. /package/dist/{noydb-36S6GQNC.js.map → noydb-BVKFP74P.js.map} +0 -0
  294. /package/dist/{public-envelope-RXZNP3V6.js.map → public-envelope-AGU6SS4Z.js.map} +0 -0
  295. /package/dist/{read-only-facade-ITU6L7BL.js.map → read-only-facade-EX6WZZBP.js.map} +0 -0
  296. /package/dist/{registry-3YFLZ7WD.js.map → registry-ERNAMRDE.js.map} +0 -0
  297. /package/dist/{registry-SECUWSGY.js.map → registry-EXTHSXQW.js.map} +0 -0
  298. /package/dist/{registry-TGZISEWC.js.map → registry-RDPTFXQ7.js.map} +0 -0
  299. /package/dist/{revoke-B54H2S2W.js.map → revoke-IFLXEZA5.js.map} +0 -0
  300. /package/dist/{signer-YSXZT574.js.map → signer-UNWOUJAK.js.map} +0 -0
  301. /package/dist/{stale-TOA36SRK.js.map → stale-NTEV5SLX.js.map} +0 -0
@@ -1,13 +1,13 @@
1
- export { w as withDerivation } from '../with-derivation-Bozs8DmD.cjs';
2
- import { aK as DerivationStrategy, aL as DerivationContext } from '../types-CrSpRDuG.cjs';
3
- export { aM as ArrayOutputSpec, aN as DerivationRegistry, aO as DerivationStrategyHandle, aP as DerivedFromMeta, aQ as OutputSpec, aR as RecordOutputSpec } from '../types-CrSpRDuG.cjs';
4
- export { h as DerivationCapExceededError, i as DerivationCycleError, j as DerivationDepthError, k as DerivationOutputShapeError, l as DerivationOutputUnknownError } from '../errors-Dz64FA65.cjs';
1
+ export { w as withDerivation, a as withRollup } from '../with-rollup-aaxOZcIb.cjs';
2
+ import { av as DerivationStrategy, aw as DerivationContext } from '../types-D-gr5t0G.cjs';
3
+ export { ax as ArrayOutputSpec, ay as DerivationRegistry, az as DerivationStrategyHandle, aA as DerivedFromMeta, aB as OutputSpec, aC as RecordOutputSpec } from '../types-D-gr5t0G.cjs';
4
+ export { i as DerivationCapExceededError, j as DerivationCycleError, k as DerivationDepthError, l as DerivationOutputShapeError, m as DerivationOutputUnknownError } from '../errors-DL-zTrrF.cjs';
5
5
  import '../lazy-builder-eYZzLEL1.cjs';
6
6
  import '../predicate-BmhBSPCH.cjs';
7
- import '../strategy-CLC1j79g.cjs';
7
+ import '../strategy-C5ol6NdV.cjs';
8
8
  import '../strategy-BSxFXGzb.cjs';
9
- import '../index-C-SSRIxP.cjs';
10
- import '../index-u-kWzSrL.cjs';
9
+ import '../index-BMmajblo.cjs';
10
+ import '../index-BM7O48Ur.cjs';
11
11
  import '@noy-db/attestation';
12
12
 
13
13
  interface RunResult {
@@ -1,13 +1,13 @@
1
- export { w as withDerivation } from '../with-derivation-BZ2y4bzF.js';
2
- import { aK as DerivationStrategy, aL as DerivationContext } from '../types-CljIHm_J.js';
3
- export { aM as ArrayOutputSpec, aN as DerivationRegistry, aO as DerivationStrategyHandle, aP as DerivedFromMeta, aQ as OutputSpec, aR as RecordOutputSpec } from '../types-CljIHm_J.js';
4
- export { h as DerivationCapExceededError, i as DerivationCycleError, j as DerivationDepthError, k as DerivationOutputShapeError, l as DerivationOutputUnknownError } from '../errors-Dz64FA65.js';
1
+ export { w as withDerivation, a as withRollup } from '../with-rollup-_TyBzz3T.js';
2
+ import { av as DerivationStrategy, aw as DerivationContext } from '../types-CraiZOyO.js';
3
+ export { ax as ArrayOutputSpec, ay as DerivationRegistry, az as DerivationStrategyHandle, aA as DerivedFromMeta, aB as OutputSpec, aC as RecordOutputSpec } from '../types-CraiZOyO.js';
4
+ export { i as DerivationCapExceededError, j as DerivationCycleError, k as DerivationDepthError, l as DerivationOutputShapeError, m as DerivationOutputUnknownError } from '../errors-DL-zTrrF.js';
5
5
  import '../lazy-builder-ChSqcF5t.js';
6
6
  import '../predicate-BmhBSPCH.js';
7
- import '../strategy-4M9jo172.js';
7
+ import '../strategy-BDxQnnTX.js';
8
8
  import '../strategy-BSxFXGzb.js';
9
- import '../index-C-SSRIxP.js';
10
- import '../index-DpU6KWof.js';
9
+ import '../index-BMmajblo.js';
10
+ import '../index-BelbyUwz.js';
11
11
  import '@noy-db/attestation';
12
12
 
13
13
  interface RunResult {
@@ -1,19 +1,20 @@
1
1
  import {
2
- withDerivation
3
- } from "../chunk-PDULVIBY.js";
2
+ withDerivation,
3
+ withRollup
4
+ } from "../chunk-CYNTFU2D.js";
4
5
  import {
5
6
  DerivationRegistry
6
- } from "../chunk-GP3SDSH2.js";
7
+ } from "../chunk-6OSOE6BY.js";
7
8
  import {
8
9
  DerivationExecutor
9
- } from "../chunk-XJV6OB4D.js";
10
+ } from "../chunk-7HD67R6U.js";
10
11
  import {
11
12
  DerivationCapExceededError,
12
13
  DerivationCycleError,
13
14
  DerivationDepthError,
14
15
  DerivationOutputShapeError,
15
16
  DerivationOutputUnknownError
16
- } from "../chunk-ZEGSDPB7.js";
17
+ } from "../chunk-DJF3FXW5.js";
17
18
  export {
18
19
  DerivationCapExceededError,
19
20
  DerivationCycleError,
@@ -22,6 +23,7 @@ export {
22
23
  DerivationOutputShapeError,
23
24
  DerivationOutputUnknownError,
24
25
  DerivationRegistry,
25
- withDerivation
26
+ withDerivation,
27
+ withRollup
26
28
  };
27
29
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { a$ as Role, b0 as UnlockedKeyring } from './types-CrSpRDuG.cjs';
1
+ import { aM as Role, aN as UnlockedKeyring } from './types-D-gr5t0G.cjs';
2
2
 
3
3
  /**
4
4
  * Session tokens —
@@ -1,4 +1,4 @@
1
- import { a$ as Role, b0 as UnlockedKeyring } from './types-CljIHm_J.js';
1
+ import { aM as Role, aN as UnlockedKeyring } from './types-CraiZOyO.js';
2
2
 
3
3
  /**
4
4
  * Session tokens —
@@ -398,6 +398,21 @@ declare class FieldFrozenError extends NoydbError {
398
398
  readonly fields: readonly string[];
399
399
  constructor(collection: string, id: string, fields: readonly string[]);
400
400
  }
401
+ /**
402
+ * Thrown by a `transitionGuard` when a write moves a state field along an
403
+ * arc that the declared transition graph does not allow — either an
404
+ * update `from → to` that is not a listed edge, or an insert whose
405
+ * initial state is not in the allowed `initial` set (reported with
406
+ * `from: '(none)'`). Override via an amendment transaction by an
407
+ * authorized role, like any guard.
408
+ */
409
+ declare class IllegalTransitionError extends NoydbError {
410
+ readonly collection: string;
411
+ readonly id: string;
412
+ readonly from: string;
413
+ readonly to: string;
414
+ constructor(collection: string, id: string, from: string, to: string);
415
+ }
401
416
  /**
402
417
  * Thrown by an amendment invariant when the proposed change-set violates
403
418
  * the declared business rule (e.g. disbursement total not preserved).
@@ -1346,6 +1361,19 @@ declare class ShardProvisioningError extends NoydbError {
1346
1361
  readonly vaultId: string;
1347
1362
  constructor(vaultId: string, partitionKey: string);
1348
1363
  }
1364
+ /**
1365
+ * Thrown by `VaultGroup.createShard` when `sharding.regionOf` resolves a
1366
+ * required region that doesn't match the placement backend's
1367
+ * `capabilities.region` — the shard would land on a non-compliant backend
1368
+ * (data-residency violation, #271). Raised BEFORE provisioning, so no
1369
+ * vault is created.
1370
+ */
1371
+ declare class DataResidencyError extends NoydbError {
1372
+ readonly vaultId: string;
1373
+ readonly requiredRegion: string;
1374
+ readonly backendRegion: string | undefined;
1375
+ constructor(vaultId: string, requiredRegion: string, backendRegion: string | undefined);
1376
+ }
1349
1377
  /** Thrown when a VaultGroup references a template name that was never registered. */
1350
1378
  declare class VaultTemplateNotFoundError extends NoydbError {
1351
1379
  readonly templateName: string;
@@ -1416,4 +1444,4 @@ declare class RecordCekNotFoundError extends NoydbError {
1416
1444
  constructor(collection: string, id: string);
1417
1445
  }
1418
1446
 
1419
- export { ForgetStrategyNotConfiguredError as $, AmendmentForbiddenError as A, BackupCorruptedError as B, MaterializedViewSourceUnknownError as C, DictKeyInUseError as D, MaterializedViewTooLargeError as E, FieldFrozenError as F, AlreadyElevatedError as G, ConflictError as H, InvariantError as I, CrossJoinSourceUnknownError as J, CrossJoinTooLargeError as K, LocaleNotSpecifiedError as L, MissingTranslationError as M, NoydbError as N, OverlayBaseIsVirtualError as O, PartitionExtractionError as P, DanglingReferenceError as Q, ReservedCollectionNameError as R, ScriptViolationError as S, TranslatorNotConfiguredError as T, UnknownDictCodeError as U, DecryptionError as V, DelegationTargetMissingError as W, DirectoryDisabledError as X, ElevationExpiredError as Y, ExportCapabilityError as Z, FilenameSanitizationError as _, DictKeyMissingError as a, GroupCardinalityError as a0, ImportCapabilityError as a1, IndexRequiredError as a2, IndexWriteFailureError as a3, InvalidKeyError as a4, JoinTooLargeError as a5, KeyringCorruptError as a6, KeyringExpiredError as a7, LedgerContentionError as a8, MigrationRequiredError as a9, UniqueConstraintError as aA, UnknownShardError as aB, UnsupportedIndexOptionError as aC, ValidationError as aD, VaultTemplateNotFoundError as aE, NetworkError as aa, NoAccessError as ab, NonAdditiveSchemaChangeError as ac, NotFoundError as ad, NumberingUncertaintyError as ae, PathEscapeError as af, PeriodClosedError as ag, PermissionDeniedError as ah, PrivilegeEscalationError as ai, QuiesceTimeoutError as aj, ReadOnlyAtInstantError as ak, ReadOnlyError as al, ReadOnlyFrameError as am, RecordCekNotFoundError as an, ReservedVaultNameError as ao, SchemaFenceError as ap, SchemaLockedError as aq, SchemaUpdateError as ar, SchemaValidationError as as, SequenceContentionError as at, SequenceOfflineError as au, ShardProvisioningError as av, StoreCapabilityError as aw, TamperedError as ax, TierDemoteDeniedError as ay, TierNotGrantedError as az, StaticDictReadonlyError as b, SessionExpiredError as c, SessionNotFoundError as d, SessionPolicyError as e, RecordLockedError as f, SnapshotNotFoundError as g, DerivationCapExceededError as h, DerivationCycleError as i, DerivationDepthError as j, DerivationOutputShapeError as k, DerivationOutputUnknownError as l, OverlayCollectionUnavailableError as m, OverlayIdMismatchError as n, OverlayNameCollisionError as o, SealedRecordExpiredError as p, SealedRecordMismatchError as q, AttestationError as r, AdoptionStateError as s, BackupLedgerError as t, BundleIntegrityError as u, BundleSealMismatchError as v, BundleVersionConflictError as w, TransferSealError as x, MaterializedViewConfigError as y, MaterializedViewCycleError as z };
1447
+ export { ExportCapabilityError as $, AmendmentForbiddenError as A, BackupCorruptedError as B, MaterializedViewCycleError as C, DictKeyInUseError as D, MaterializedViewSourceUnknownError as E, FieldFrozenError as F, MaterializedViewTooLargeError as G, AlreadyElevatedError as H, IllegalTransitionError as I, ConflictError as J, CrossJoinSourceUnknownError as K, LocaleNotSpecifiedError as L, MissingTranslationError as M, NoydbError as N, OverlayBaseIsVirtualError as O, PartitionExtractionError as P, CrossJoinTooLargeError as Q, ReservedCollectionNameError as R, ScriptViolationError as S, TranslatorNotConfiguredError as T, UnknownDictCodeError as U, DanglingReferenceError as V, DataResidencyError as W, DecryptionError as X, DelegationTargetMissingError as Y, DirectoryDisabledError as Z, ElevationExpiredError as _, DictKeyMissingError as a, FilenameSanitizationError as a0, ForgetStrategyNotConfiguredError as a1, GroupCardinalityError as a2, ImportCapabilityError as a3, IndexRequiredError as a4, IndexWriteFailureError as a5, InvalidKeyError as a6, JoinTooLargeError as a7, KeyringCorruptError as a8, KeyringExpiredError as a9, TierDemoteDeniedError as aA, TierNotGrantedError as aB, UniqueConstraintError as aC, UnknownShardError as aD, UnsupportedIndexOptionError as aE, ValidationError as aF, VaultTemplateNotFoundError as aG, LedgerContentionError as aa, MigrationRequiredError as ab, NetworkError as ac, NoAccessError as ad, NonAdditiveSchemaChangeError as ae, NotFoundError as af, NumberingUncertaintyError as ag, PathEscapeError as ah, PeriodClosedError as ai, PermissionDeniedError as aj, PrivilegeEscalationError as ak, QuiesceTimeoutError as al, ReadOnlyAtInstantError as am, ReadOnlyError as an, ReadOnlyFrameError as ao, RecordCekNotFoundError as ap, ReservedVaultNameError as aq, SchemaFenceError as ar, SchemaLockedError as as, SchemaUpdateError as at, SchemaValidationError as au, SequenceContentionError as av, SequenceOfflineError as aw, ShardProvisioningError as ax, StoreCapabilityError as ay, TamperedError as az, StaticDictReadonlyError as b, SessionExpiredError as c, SessionNotFoundError as d, SessionPolicyError as e, InvariantError as f, RecordLockedError as g, SnapshotNotFoundError as h, DerivationCapExceededError as i, DerivationCycleError as j, DerivationDepthError as k, DerivationOutputShapeError as l, DerivationOutputUnknownError as m, OverlayCollectionUnavailableError as n, OverlayIdMismatchError as o, OverlayNameCollisionError as p, SealedRecordExpiredError as q, SealedRecordMismatchError as r, AttestationError as s, AdoptionStateError as t, BackupLedgerError as u, BundleIntegrityError as v, BundleSealMismatchError as w, BundleVersionConflictError as x, TransferSealError as y, MaterializedViewConfigError as z };
@@ -398,6 +398,21 @@ declare class FieldFrozenError extends NoydbError {
398
398
  readonly fields: readonly string[];
399
399
  constructor(collection: string, id: string, fields: readonly string[]);
400
400
  }
401
+ /**
402
+ * Thrown by a `transitionGuard` when a write moves a state field along an
403
+ * arc that the declared transition graph does not allow — either an
404
+ * update `from → to` that is not a listed edge, or an insert whose
405
+ * initial state is not in the allowed `initial` set (reported with
406
+ * `from: '(none)'`). Override via an amendment transaction by an
407
+ * authorized role, like any guard.
408
+ */
409
+ declare class IllegalTransitionError extends NoydbError {
410
+ readonly collection: string;
411
+ readonly id: string;
412
+ readonly from: string;
413
+ readonly to: string;
414
+ constructor(collection: string, id: string, from: string, to: string);
415
+ }
401
416
  /**
402
417
  * Thrown by an amendment invariant when the proposed change-set violates
403
418
  * the declared business rule (e.g. disbursement total not preserved).
@@ -1346,6 +1361,19 @@ declare class ShardProvisioningError extends NoydbError {
1346
1361
  readonly vaultId: string;
1347
1362
  constructor(vaultId: string, partitionKey: string);
1348
1363
  }
1364
+ /**
1365
+ * Thrown by `VaultGroup.createShard` when `sharding.regionOf` resolves a
1366
+ * required region that doesn't match the placement backend's
1367
+ * `capabilities.region` — the shard would land on a non-compliant backend
1368
+ * (data-residency violation, #271). Raised BEFORE provisioning, so no
1369
+ * vault is created.
1370
+ */
1371
+ declare class DataResidencyError extends NoydbError {
1372
+ readonly vaultId: string;
1373
+ readonly requiredRegion: string;
1374
+ readonly backendRegion: string | undefined;
1375
+ constructor(vaultId: string, requiredRegion: string, backendRegion: string | undefined);
1376
+ }
1349
1377
  /** Thrown when a VaultGroup references a template name that was never registered. */
1350
1378
  declare class VaultTemplateNotFoundError extends NoydbError {
1351
1379
  readonly templateName: string;
@@ -1416,4 +1444,4 @@ declare class RecordCekNotFoundError extends NoydbError {
1416
1444
  constructor(collection: string, id: string);
1417
1445
  }
1418
1446
 
1419
- export { ForgetStrategyNotConfiguredError as $, AmendmentForbiddenError as A, BackupCorruptedError as B, MaterializedViewSourceUnknownError as C, DictKeyInUseError as D, MaterializedViewTooLargeError as E, FieldFrozenError as F, AlreadyElevatedError as G, ConflictError as H, InvariantError as I, CrossJoinSourceUnknownError as J, CrossJoinTooLargeError as K, LocaleNotSpecifiedError as L, MissingTranslationError as M, NoydbError as N, OverlayBaseIsVirtualError as O, PartitionExtractionError as P, DanglingReferenceError as Q, ReservedCollectionNameError as R, ScriptViolationError as S, TranslatorNotConfiguredError as T, UnknownDictCodeError as U, DecryptionError as V, DelegationTargetMissingError as W, DirectoryDisabledError as X, ElevationExpiredError as Y, ExportCapabilityError as Z, FilenameSanitizationError as _, DictKeyMissingError as a, GroupCardinalityError as a0, ImportCapabilityError as a1, IndexRequiredError as a2, IndexWriteFailureError as a3, InvalidKeyError as a4, JoinTooLargeError as a5, KeyringCorruptError as a6, KeyringExpiredError as a7, LedgerContentionError as a8, MigrationRequiredError as a9, UniqueConstraintError as aA, UnknownShardError as aB, UnsupportedIndexOptionError as aC, ValidationError as aD, VaultTemplateNotFoundError as aE, NetworkError as aa, NoAccessError as ab, NonAdditiveSchemaChangeError as ac, NotFoundError as ad, NumberingUncertaintyError as ae, PathEscapeError as af, PeriodClosedError as ag, PermissionDeniedError as ah, PrivilegeEscalationError as ai, QuiesceTimeoutError as aj, ReadOnlyAtInstantError as ak, ReadOnlyError as al, ReadOnlyFrameError as am, RecordCekNotFoundError as an, ReservedVaultNameError as ao, SchemaFenceError as ap, SchemaLockedError as aq, SchemaUpdateError as ar, SchemaValidationError as as, SequenceContentionError as at, SequenceOfflineError as au, ShardProvisioningError as av, StoreCapabilityError as aw, TamperedError as ax, TierDemoteDeniedError as ay, TierNotGrantedError as az, StaticDictReadonlyError as b, SessionExpiredError as c, SessionNotFoundError as d, SessionPolicyError as e, RecordLockedError as f, SnapshotNotFoundError as g, DerivationCapExceededError as h, DerivationCycleError as i, DerivationDepthError as j, DerivationOutputShapeError as k, DerivationOutputUnknownError as l, OverlayCollectionUnavailableError as m, OverlayIdMismatchError as n, OverlayNameCollisionError as o, SealedRecordExpiredError as p, SealedRecordMismatchError as q, AttestationError as r, AdoptionStateError as s, BackupLedgerError as t, BundleIntegrityError as u, BundleSealMismatchError as v, BundleVersionConflictError as w, TransferSealError as x, MaterializedViewConfigError as y, MaterializedViewCycleError as z };
1447
+ export { ExportCapabilityError as $, AmendmentForbiddenError as A, BackupCorruptedError as B, MaterializedViewCycleError as C, DictKeyInUseError as D, MaterializedViewSourceUnknownError as E, FieldFrozenError as F, MaterializedViewTooLargeError as G, AlreadyElevatedError as H, IllegalTransitionError as I, ConflictError as J, CrossJoinSourceUnknownError as K, LocaleNotSpecifiedError as L, MissingTranslationError as M, NoydbError as N, OverlayBaseIsVirtualError as O, PartitionExtractionError as P, CrossJoinTooLargeError as Q, ReservedCollectionNameError as R, ScriptViolationError as S, TranslatorNotConfiguredError as T, UnknownDictCodeError as U, DanglingReferenceError as V, DataResidencyError as W, DecryptionError as X, DelegationTargetMissingError as Y, DirectoryDisabledError as Z, ElevationExpiredError as _, DictKeyMissingError as a, FilenameSanitizationError as a0, ForgetStrategyNotConfiguredError as a1, GroupCardinalityError as a2, ImportCapabilityError as a3, IndexRequiredError as a4, IndexWriteFailureError as a5, InvalidKeyError as a6, JoinTooLargeError as a7, KeyringCorruptError as a8, KeyringExpiredError as a9, TierDemoteDeniedError as aA, TierNotGrantedError as aB, UniqueConstraintError as aC, UnknownShardError as aD, UnsupportedIndexOptionError as aE, ValidationError as aF, VaultTemplateNotFoundError as aG, LedgerContentionError as aa, MigrationRequiredError as ab, NetworkError as ac, NoAccessError as ad, NonAdditiveSchemaChangeError as ae, NotFoundError as af, NumberingUncertaintyError as ag, PathEscapeError as ah, PeriodClosedError as ai, PermissionDeniedError as aj, PrivilegeEscalationError as ak, QuiesceTimeoutError as al, ReadOnlyAtInstantError as am, ReadOnlyError as an, ReadOnlyFrameError as ao, RecordCekNotFoundError as ap, ReservedVaultNameError as aq, SchemaFenceError as ar, SchemaLockedError as as, SchemaUpdateError as at, SchemaValidationError as au, SequenceContentionError as av, SequenceOfflineError as aw, ShardProvisioningError as ax, StoreCapabilityError as ay, TamperedError as az, StaticDictReadonlyError as b, SessionExpiredError as c, SessionNotFoundError as d, SessionPolicyError as e, InvariantError as f, RecordLockedError as g, SnapshotNotFoundError as h, DerivationCapExceededError as i, DerivationCycleError as j, DerivationDepthError as k, DerivationOutputShapeError as l, DerivationOutputUnknownError as m, OverlayCollectionUnavailableError as n, OverlayIdMismatchError as o, OverlayNameCollisionError as p, SealedRecordExpiredError as q, SealedRecordMismatchError as r, AttestationError as s, AdoptionStateError as t, BackupLedgerError as u, BundleIntegrityError as v, BundleSealMismatchError as w, BundleVersionConflictError as x, TransferSealError as y, MaterializedViewConfigError as z };
@@ -0,0 +1,12 @@
1
+ import {
2
+ MaterializedViewExecutor
3
+ } from "./chunk-6KESZO5D.js";
4
+ import "./chunk-GYAWXHFO.js";
5
+ import "./chunk-OBMYMKGO.js";
6
+ import "./chunk-LSIIPKYT.js";
7
+ import "./chunk-VEIVAYJ7.js";
8
+ import "./chunk-DJF3FXW5.js";
9
+ export {
10
+ MaterializedViewExecutor
11
+ };
12
+ //# sourceMappingURL=executor-44R5CUS2.js.map
@@ -0,0 +1,8 @@
1
+ import {
2
+ GuardExecutor
3
+ } from "./chunk-IVP5IVON.js";
4
+ import "./chunk-DJF3FXW5.js";
5
+ export {
6
+ GuardExecutor
7
+ };
8
+ //# sourceMappingURL=executor-AOACUK7Z.js.map
@@ -0,0 +1,8 @@
1
+ import {
2
+ DerivationExecutor
3
+ } from "./chunk-7HD67R6U.js";
4
+ import "./chunk-DJF3FXW5.js";
5
+ export {
6
+ DerivationExecutor
7
+ };
8
+ //# sourceMappingURL=executor-OKFLQCDW.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NOYDB_FORMAT_VERSION
3
- } from "./chunk-SISBMAPO.js";
3
+ } from "./chunk-SHIUFIPW.js";
4
4
 
5
5
  // src/derivations/fanout-sidecar.ts
6
6
  function recordId(source, sourceId, outputKey) {
@@ -48,4 +48,4 @@ export {
48
48
  loadFanoutSidecar,
49
49
  saveFanoutSidecar
50
50
  };
51
- //# sourceMappingURL=fanout-sidecar-FIJJ46YG.js.map
51
+ //# sourceMappingURL=fanout-sidecar-DCQWJQ6S.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/forget/index.ts","../../src/forget/strategy.ts","../../src/forget/subject-index.ts"],"sourcesContent":["/**\n * `@noy-db/hub/forget` — GDPR right-to-erasure via per-record CEK crypto-shred\n * (#304). Import `withForgetCascade` and pass it to `createNoydb`:\n *\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withForgetCascade } from '@noy-db/hub/forget'\n *\n * const db = createNoydb({\n * secret, user,\n * historyStrategy: withHistory(), // ledger for the erasure proof\n * forgetStrategy: withForgetCascade({ subjects: { invoices: 'buyerId' } }),\n * })\n * const result = await db.vault('main').forget('buyer-123')\n * ```\n *\n * The erasure flow (`vault.forget`), the subject-index maintenance hooks, and\n * the tombstone rewrite live in core (`vault.ts` / `collection.ts`) because\n * they touch the write path directly; this subpath only exposes the\n * declaration factory + result types.\n *\n * @module\n */\nexport {\n withForgetCascade,\n NO_FORGET,\n} from './strategy.js'\nexport type {\n SubjectDeclaration,\n ForgetStrategy,\n ForgetResult,\n} from './strategy.js'\nexport type { SubjectRef } from './subject-index.js'\nexport { SUBJECT_INDEX_COLLECTION } from './subject-index.js'\n","/**\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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACiDO,IAAM,YAA4B,EAAE,UAAU,CAAC,EAAE;AAuBjD,SAAS,kBAAkB,MAA0C;AAC1E,SAAO,EAAE,UAAU,EAAE,GAAG,KAAK,SAAS,EAAE;AAC1C;;;AC3CO,IAAM,2BAA2B;","names":[]}
1
+ {"version":3,"sources":["../../src/forget/index.ts","../../src/forget/strategy.ts","../../src/forget/subject-index.ts"],"sourcesContent":["/**\n * `@noy-db/hub/forget` — GDPR right-to-erasure via per-record CEK crypto-shred\n * (#304). Import `withForgetCascade` and pass it to `createNoydb`:\n *\n * ```ts\n * import { createNoydb } from '@noy-db/hub'\n * import { withForgetCascade } from '@noy-db/hub/forget'\n *\n * const db = createNoydb({\n * secret, user,\n * historyStrategy: withHistory(), // ledger for the erasure proof\n * forgetStrategy: withForgetCascade({ subjects: { invoices: 'buyerId' } }),\n * })\n * const result = await db.vault('main').forget('buyer-123')\n * ```\n *\n * The erasure flow (`vault.forget`), the subject-index maintenance hooks, and\n * the tombstone rewrite live in core (`vault.ts` / `collection.ts`) because\n * they touch the write path directly; this subpath only exposes the\n * declaration factory + result types.\n *\n * @module\n */\nexport {\n withForgetCascade,\n NO_FORGET,\n} from './strategy.js'\nexport type {\n SubjectDeclaration,\n ForgetStrategy,\n ForgetResult,\n} from './strategy.js'\nexport type { SubjectRef } from './subject-index.js'\nexport { SUBJECT_INDEX_COLLECTION } from './subject-index.js'\n","/**\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 /**\n * Count of persisted `_idx/<field>/<recordId>` index side-cars hard-deleted\n * across the shredded records (#401). These live under the retained\n * collection DEK, so crypto-shred alone would leave the indexed field VALUES\n * readable — `forget()` must delete them.\n */\n readonly indexPostingsPurged: number\n /**\n * `collection:id:field` entries whose persisted `_idx` side-car could NOT be\n * deleted (#401) — index residue that still leaks the indexed value under the\n * retained collection DEK. Non-empty means erasure is INCOMPLETE: retry, or\n * purge the side-car out of band.\n */\n readonly indexResidue: 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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACiDO,IAAM,YAA4B,EAAE,UAAU,CAAC,EAAE;AAuBjD,SAAS,kBAAkB,MAA0C;AAC1E,SAAO,EAAE,UAAU,EAAE,GAAG,KAAK,SAAS,EAAE;AAC1C;;;AC3CO,IAAM,2BAA2B;","names":[]}
@@ -1 +1 @@
1
- export { b as ForgetResult, F as ForgetStrategy, N as NO_FORGET, d as SUBJECT_INDEX_COLLECTION, e as SubjectDeclaration, S as SubjectRef, w as withForgetCascade } from '../index-C-SSRIxP.cjs';
1
+ export { b as ForgetResult, F as ForgetStrategy, N as NO_FORGET, d as SUBJECT_INDEX_COLLECTION, e as SubjectDeclaration, S as SubjectRef, w as withForgetCascade } from '../index-BMmajblo.cjs';
@@ -1 +1 @@
1
- export { b as ForgetResult, F as ForgetStrategy, N as NO_FORGET, d as SUBJECT_INDEX_COLLECTION, e as SubjectDeclaration, S as SubjectRef, w as withForgetCascade } from '../index-C-SSRIxP.js';
1
+ export { b as ForgetResult, F as ForgetStrategy, N as NO_FORGET, d as SUBJECT_INDEX_COLLECTION, e as SubjectDeclaration, S as SubjectRef, w as withForgetCascade } from '../index-BMmajblo.js';
@@ -2,10 +2,10 @@ import {
2
2
  NO_FORGET,
3
3
  SUBJECT_INDEX_COLLECTION,
4
4
  withForgetCascade
5
- } from "../chunk-I5IUYN7B.js";
6
- import "../chunk-SISBMAPO.js";
7
- import "../chunk-UNTGHX5A.js";
8
- import "../chunk-ZEGSDPB7.js";
5
+ } from "../chunk-KNKNOJFS.js";
6
+ import "../chunk-SHIUFIPW.js";
7
+ import "../chunk-OKOKPYWH.js";
8
+ import "../chunk-DJF3FXW5.js";
9
9
  export {
10
10
  NO_FORGET,
11
11
  SUBJECT_INDEX_COLLECTION,
@@ -24,10 +24,12 @@ __export(guards_exports, {
24
24
  FieldFrozenError: () => FieldFrozenError,
25
25
  GuardExecutor: () => GuardExecutor,
26
26
  GuardRegistry: () => GuardRegistry,
27
+ IllegalTransitionError: () => IllegalTransitionError,
27
28
  InvariantError: () => InvariantError,
28
29
  ReadOnlyVaultFacade: () => ReadOnlyVaultFacade,
29
30
  RecordLockedError: () => RecordLockedError,
30
31
  immutableGuard: () => immutableGuard,
32
+ transitionGuard: () => transitionGuard,
31
33
  withGuard: () => withGuard
32
34
  });
33
35
  module.exports = __toCommonJS(guards_exports);
@@ -72,6 +74,23 @@ var FieldFrozenError = class extends NoydbError {
72
74
  this.fields = fields;
73
75
  }
74
76
  };
77
+ var IllegalTransitionError = class extends NoydbError {
78
+ collection;
79
+ id;
80
+ from;
81
+ to;
82
+ constructor(collection, id, from, to) {
83
+ super(
84
+ "ILLEGAL_TRANSITION",
85
+ `Cannot transition ${collection}/${id} from "${from}" to "${to}" \u2014 not a declared arc. Use withTransactions({ amendment: true, reason }) with admin/owner role to override.`
86
+ );
87
+ this.name = "IllegalTransitionError";
88
+ this.collection = collection;
89
+ this.id = id;
90
+ this.from = from;
91
+ this.to = to;
92
+ }
93
+ };
75
94
  var InvariantError = class extends NoydbError {
76
95
  constructor(message) {
77
96
  super("INVARIANT_VIOLATED", message);
@@ -156,6 +175,59 @@ function immutableGuard(config) {
156
175
  return withGuard(spec);
157
176
  }
158
177
 
178
+ // src/guards/transition-guard.ts
179
+ function recordId2(record) {
180
+ const id = record?.id;
181
+ return typeof id === "string" ? id : "";
182
+ }
183
+ function stateOf(record, field) {
184
+ const v = record[field];
185
+ return typeof v === "string" ? v : String(v);
186
+ }
187
+ function transitionGuard(config) {
188
+ const { collection, field, transitions, initial, amendmentRoles, amendmentInvariant } = config;
189
+ const allowIdempotent = config.allowIdempotent ?? true;
190
+ if (!field) {
191
+ throw new ValidationError("transitionGuard: `field` is required");
192
+ }
193
+ if (transitions === void 0 || typeof transitions !== "object") {
194
+ throw new ValidationError("transitionGuard: `transitions` must be a state\u2192states map");
195
+ }
196
+ const spec = {
197
+ collection,
198
+ check: (incoming, ctx) => {
199
+ const rec = incoming;
200
+ const to = stateOf(rec, field);
201
+ if (ctx.existing === null) {
202
+ if (initial !== void 0 && !initial.includes(to)) {
203
+ throw new IllegalTransitionError(collection, recordId2(rec), "(none)", to);
204
+ }
205
+ return;
206
+ }
207
+ const from = stateOf(ctx.existing, field);
208
+ if (from === to) {
209
+ if (allowIdempotent) return;
210
+ throw new IllegalTransitionError(collection, recordId2(rec), from, to);
211
+ }
212
+ const allowed = transitions[from] ?? [];
213
+ if (!allowed.includes(to)) {
214
+ throw new IllegalTransitionError(collection, recordId2(rec), from, to);
215
+ }
216
+ },
217
+ // The authorized override: inside an amendment transaction the check
218
+ // is skipped and the change is ledgered. By default no extra invariant
219
+ // — the amendment itself is the sanctioned exception. Callers may
220
+ // supply `amendmentInvariant` to keep a constraint inviolable even
221
+ // under amendment; a throw reverts the amendment as `InvariantError`.
222
+ amendment: {
223
+ roles: amendmentRoles ?? ["admin", "owner"],
224
+ invariant: amendmentInvariant ?? (() => {
225
+ })
226
+ }
227
+ };
228
+ return withGuard(spec);
229
+ }
230
+
159
231
  // src/guards/registry.ts
160
232
  var GuardRegistry = class {
161
233
  _byCollection = /* @__PURE__ */ new Map();
@@ -351,14 +423,17 @@ function deepEqual(a, b) {
351
423
  // src/guards/read-only-facade.ts
352
424
  var ReadOnlyVaultFacade = class {
353
425
  _vault;
354
- constructor(vault) {
426
+ _layer;
427
+ constructor(vault, layer = "read") {
355
428
  this._vault = vault;
429
+ this._layer = layer;
356
430
  }
357
431
  collection(name) {
358
432
  const c = this._vault.collection(name);
433
+ const layer = this._layer;
359
434
  return {
360
- get: (id) => c.get(id),
361
- list: () => c.list(),
435
+ get: (id) => c.get(id, { _layer: layer }),
436
+ list: () => c.list({ _layer: layer }),
362
437
  query: () => c.query()
363
438
  };
364
439
  }
@@ -369,10 +444,12 @@ var ReadOnlyVaultFacade = class {
369
444
  FieldFrozenError,
370
445
  GuardExecutor,
371
446
  GuardRegistry,
447
+ IllegalTransitionError,
372
448
  InvariantError,
373
449
  ReadOnlyVaultFacade,
374
450
  RecordLockedError,
375
451
  immutableGuard,
452
+ transitionGuard,
376
453
  withGuard
377
454
  });
378
455
  //# sourceMappingURL=index.cjs.map