@noy-db/hub 0.2.0-pre.17 → 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 (284) hide show
  1. package/dist/aggregate/index.cjs.map +1 -1
  2. package/dist/aggregate/index.d.cts +3 -3
  3. package/dist/aggregate/index.d.ts +3 -3
  4. package/dist/aggregate/index.js +4 -4
  5. package/dist/attestation/index.cjs.map +1 -1
  6. package/dist/attestation/index.d.cts +4 -4
  7. package/dist/attestation/index.d.ts +4 -4
  8. package/dist/attestation/index.js +6 -6
  9. package/dist/blobs/index.cjs.map +1 -1
  10. package/dist/blobs/index.d.cts +5 -5
  11. package/dist/blobs/index.d.ts +5 -5
  12. package/dist/blobs/index.js +6 -6
  13. package/dist/bundle/index.cjs +994 -273
  14. package/dist/bundle/index.cjs.map +1 -1
  15. package/dist/bundle/index.d.cts +6 -6
  16. package/dist/bundle/index.d.ts +6 -6
  17. package/dist/bundle/index.js +10 -10
  18. package/dist/{chunk-SHX5QBCI.js → chunk-2U226RDC.js} +3 -3
  19. package/dist/{chunk-7H2GEJ3O.js → chunk-32XVU2LT.js} +3 -3
  20. package/dist/{chunk-XJV6OB4D.js → chunk-33DAO2XG.js} +2 -2
  21. package/dist/{chunk-U5QCMH3W.js → chunk-45643PAU.js} +4 -4
  22. package/dist/{chunk-BH3X5L6A.js → chunk-4UI5T3K7.js} +3 -3
  23. package/dist/{chunk-2FU2FTXD.js → chunk-5KKNBDCT.js} +2 -2
  24. package/dist/{chunk-HGVSHKZW.js → chunk-647TFNYL.js} +30 -7
  25. package/dist/chunk-647TFNYL.js.map +1 -0
  26. package/dist/{chunk-CD2AVTEM.js → chunk-6FHCU3QO.js} +5 -5
  27. package/dist/{chunk-NBBMMJ2H.js → chunk-6Q5XRLKG.js} +4 -4
  28. package/dist/{chunk-XPIHJ34I.js → chunk-6XEGHIBA.js} +4 -4
  29. package/dist/{chunk-5LIROIDM.js → chunk-6YEC7LLO.js} +2 -2
  30. package/dist/{chunk-C3HYQPV4.js → chunk-AB7JF2KF.js} +2 -2
  31. package/dist/{chunk-UMLVJTYV.js → chunk-ADB7GPM3.js} +7 -4
  32. package/dist/chunk-ADB7GPM3.js.map +1 -0
  33. package/dist/{chunk-KCEHMDZF.js → chunk-BUBJYIZ7.js} +3 -3
  34. package/dist/{chunk-I5IUYN7B.js → chunk-C2OYWD5S.js} +3 -3
  35. package/dist/{chunk-WV7WV6JO.js → chunk-CMISAJAE.js} +5 -5
  36. package/dist/{chunk-SNMJ7SB3.js → chunk-DKMPR76W.js} +5 -5
  37. package/dist/{chunk-XMVHEWF6.js → chunk-DR5I7Q6N.js} +4 -4
  38. package/dist/{chunk-D77ZQSQQ.js → chunk-F2IJ2HGD.js} +652 -152
  39. package/dist/chunk-F2IJ2HGD.js.map +1 -0
  40. package/dist/{chunk-BSZOCSDZ.js → chunk-FQRAYDS4.js} +4 -4
  41. package/dist/{chunk-ZEGSDPB7.js → chunk-HMFC6M2G.js} +19 -1
  42. package/dist/chunk-HMFC6M2G.js.map +1 -0
  43. package/dist/{chunk-M476FOQ7.js → chunk-HOO5I3VG.js} +2 -2
  44. package/dist/{chunk-F4G63NTZ.js → chunk-HWK75CYX.js} +2 -2
  45. package/dist/{chunk-FEJDVE3Z.js → chunk-HZOEBM67.js} +2 -2
  46. package/dist/{chunk-QHM6XEAH.js → chunk-IQ4GMEYZ.js} +6 -6
  47. package/dist/{chunk-5AXTH4QZ.js → chunk-K3NYRK7U.js} +2 -2
  48. package/dist/{chunk-ROPJVUG3.js → chunk-KOURQXIU.js} +5 -5
  49. package/dist/chunk-KOURQXIU.js.map +1 -0
  50. package/dist/{chunk-GP3SDSH2.js → chunk-KQ523X3A.js} +15 -2
  51. package/dist/chunk-KQ523X3A.js.map +1 -0
  52. package/dist/{chunk-3G3W65EQ.js → chunk-KTZ2MHQK.js} +2 -2
  53. package/dist/{chunk-SISBMAPO.js → chunk-LGPSCKWZ.js} +1 -1
  54. package/dist/chunk-LGPSCKWZ.js.map +1 -0
  55. package/dist/{chunk-E77UKJYL.js → chunk-LQ3GD5LL.js} +5 -5
  56. package/dist/{chunk-JDWE6JMX.js → chunk-M3H7VSRV.js} +2 -2
  57. package/dist/{chunk-DWEBTE2W.js → chunk-MGB67HKX.js} +4 -4
  58. package/dist/{chunk-AEIKD3PP.js → chunk-P57D4KBG.js} +3 -3
  59. package/dist/{chunk-YYVZYTWW.js → chunk-PGVEL5IZ.js} +3 -3
  60. package/dist/{chunk-UNTGHX5A.js → chunk-QJKZ5WUP.js} +2 -2
  61. package/dist/{chunk-BJSLBUJ7.js → chunk-QPJ7Z4L3.js} +2 -2
  62. package/dist/{chunk-NYSYPFXJ.js → chunk-RQFG2YSV.js} +3 -3
  63. package/dist/{chunk-J7RWBXFY.js → chunk-RZWQNMMP.js} +2 -2
  64. package/dist/{chunk-BL5GYANC.js → chunk-T4T5I5L6.js} +3 -3
  65. package/dist/{chunk-ZNGPEV5J.js → chunk-TFAN3NFD.js} +3 -3
  66. package/dist/{chunk-DYYYUW5D.js → chunk-TPOHMOGX.js} +2 -2
  67. package/dist/{chunk-XMHUK5PN.js → chunk-TTS3RWL5.js} +2 -2
  68. package/dist/{chunk-TIDXB5DF.js → chunk-VVDSDOVV.js} +4 -4
  69. package/dist/{chunk-WIAOUFFB.js → chunk-WZCG3EZ6.js} +2 -2
  70. package/dist/{chunk-QO6RGLLD.js → chunk-Y5XVB75E.js} +4 -4
  71. package/dist/chunk-YWYW2YNO.js +129 -0
  72. package/dist/chunk-YWYW2YNO.js.map +1 -0
  73. package/dist/{chunk-H2MRGONI.js → chunk-Z3BE5BRK.js} +2 -2
  74. package/dist/{chunk-ROVO6NPJ.js → chunk-Z3I2WNGF.js} +58 -3
  75. package/dist/chunk-Z3I2WNGF.js.map +1 -0
  76. package/dist/{state-vault-W2OEABNO.js → chunk-ZJ67TB4S.js} +24 -7
  77. package/dist/chunk-ZJ67TB4S.js.map +1 -0
  78. package/dist/consent/index.cjs.map +1 -1
  79. package/dist/consent/index.d.cts +5 -5
  80. package/dist/consent/index.d.ts +5 -5
  81. package/dist/consent/index.js +3 -3
  82. package/dist/{crypto-7BN2HDWG.js → crypto-FNK3XPCS.js} +3 -3
  83. package/dist/{delegation-MGH5SODX.js → delegation-FMXNUWE6.js} +5 -5
  84. package/dist/derivations/index.cjs +82 -2
  85. package/dist/derivations/index.cjs.map +1 -1
  86. package/dist/derivations/index.d.cts +6 -6
  87. package/dist/derivations/index.d.ts +6 -6
  88. package/dist/derivations/index.js +8 -6
  89. package/dist/{dev-unlock-iXbYFAWl.d.cts → dev-unlock-3_2b_vo6.d.cts} +1 -1
  90. package/dist/{dev-unlock-CI1ijTML.d.ts → dev-unlock-BMvwPr_E.d.ts} +1 -1
  91. package/dist/{errors-Dz64FA65.d.ts → errors-DUTlAt3Y.d.cts} +16 -1
  92. package/dist/{errors-Dz64FA65.d.cts → errors-DUTlAt3Y.d.ts} +16 -1
  93. package/dist/executor-IZ2NVXCY.js +11 -0
  94. package/dist/executor-THSEYEJG.js +8 -0
  95. package/dist/executor-WLFDUTOM.js +8 -0
  96. package/dist/{fanout-sidecar-FIJJ46YG.js → fanout-sidecar-JGHXAJO5.js} +2 -2
  97. package/dist/forget/index.js +4 -4
  98. package/dist/guards/index.cjs +80 -3
  99. package/dist/guards/index.cjs.map +1 -1
  100. package/dist/guards/index.d.cts +6 -6
  101. package/dist/guards/index.d.ts +6 -6
  102. package/dist/guards/index.js +8 -4
  103. package/dist/{hash-blk7Bkes.d.ts → hash-BThBJFO1.d.ts} +1 -1
  104. package/dist/{hash-tEcM5fnv.d.cts → hash-BnWnL9bQ.d.cts} +1 -1
  105. package/dist/history/index.cjs.map +1 -1
  106. package/dist/history/index.d.cts +6 -6
  107. package/dist/history/index.d.ts +6 -6
  108. package/dist/history/index.js +5 -5
  109. package/dist/i18n/index.cjs.map +1 -1
  110. package/dist/i18n/index.d.cts +5 -5
  111. package/dist/i18n/index.d.ts +5 -5
  112. package/dist/i18n/index.js +6 -6
  113. package/dist/{index-u-kWzSrL.d.cts → index-C6lgoUhK.d.cts} +40 -3
  114. package/dist/{index-DpU6KWof.d.ts → index-DP1JTWHZ.d.ts} +40 -3
  115. package/dist/index.cjs +1202 -322
  116. package/dist/index.cjs.map +1 -1
  117. package/dist/index.d.cts +14 -14
  118. package/dist/index.d.ts +14 -14
  119. package/dist/index.js +65 -47
  120. package/dist/index.js.map +1 -1
  121. package/dist/indexing/index.cjs.map +1 -1
  122. package/dist/indexing/index.js +4 -4
  123. package/dist/issue-R2MWQO6K.js +12 -0
  124. package/dist/{ledger-LFVLHE5H.js → ledger-GXC2YA3A.js} +5 -5
  125. package/dist/materialized-views/index.cjs.map +1 -1
  126. package/dist/materialized-views/index.d.cts +6 -6
  127. package/dist/materialized-views/index.d.ts +6 -6
  128. package/dist/materialized-views/index.js +7 -7
  129. package/dist/noydb-RJL6FQ4B.js +37 -0
  130. package/dist/overlay-views/index.cjs.map +1 -1
  131. package/dist/overlay-views/index.d.cts +6 -6
  132. package/dist/overlay-views/index.d.ts +6 -6
  133. package/dist/overlay-views/index.js +4 -4
  134. package/dist/periods/index.cjs.map +1 -1
  135. package/dist/periods/index.d.cts +5 -5
  136. package/dist/periods/index.d.ts +5 -5
  137. package/dist/periods/index.js +5 -5
  138. package/dist/{public-envelope-RXZNP3V6.js → public-envelope-HXOFHY4N.js} +4 -4
  139. package/dist/query/index.cjs +26 -3
  140. package/dist/query/index.cjs.map +1 -1
  141. package/dist/query/index.d.cts +3 -3
  142. package/dist/query/index.d.ts +3 -3
  143. package/dist/query/index.js +6 -6
  144. package/dist/read-only-facade-EX6WZZBP.js +7 -0
  145. package/dist/registry-3T2RZC5A.js +8 -0
  146. package/dist/registry-DMS7OKBM.js +8 -0
  147. package/dist/{registry-SECUWSGY.js → registry-WVXO6NH5.js} +3 -3
  148. package/dist/{revoke-B54H2S2W.js → revoke-7LCWE2AH.js} +6 -6
  149. package/dist/sealed-record/index.cjs.map +1 -1
  150. package/dist/sealed-record/index.d.cts +1 -1
  151. package/dist/sealed-record/index.d.ts +1 -1
  152. package/dist/sealed-record/index.js +2 -2
  153. package/dist/session/index.cjs.map +1 -1
  154. package/dist/session/index.d.cts +6 -6
  155. package/dist/session/index.d.ts +6 -6
  156. package/dist/session/index.js +3 -3
  157. package/dist/shadow/index.cjs.map +1 -1
  158. package/dist/shadow/index.d.cts +5 -5
  159. package/dist/shadow/index.d.ts +5 -5
  160. package/dist/shadow/index.js +2 -2
  161. package/dist/{signer-YSXZT574.js → signer-HAVDLGOK.js} +5 -5
  162. package/dist/snapshots/index.cjs.map +1 -1
  163. package/dist/snapshots/index.d.cts +5 -5
  164. package/dist/snapshots/index.d.ts +5 -5
  165. package/dist/snapshots/index.js +4 -4
  166. package/dist/{stale-TOA36SRK.js → stale-PGTEGJDI.js} +2 -2
  167. package/dist/state-vault-QKQKN3H3.js +14 -0
  168. package/dist/state-vault-QKQKN3H3.js.map +1 -0
  169. package/dist/store/index.cjs.map +1 -1
  170. package/dist/store/index.d.cts +5 -5
  171. package/dist/store/index.d.ts +5 -5
  172. package/dist/store/index.js +2 -2
  173. package/dist/{strategy-4M9jo172.d.ts → strategy-Diwh5lzS.d.ts} +1 -1
  174. package/dist/{strategy-CLC1j79g.d.cts → strategy-nuyN8K5N.d.cts} +1 -1
  175. package/dist/sync/index.cjs.map +1 -1
  176. package/dist/sync/index.d.cts +4 -4
  177. package/dist/sync/index.d.ts +4 -4
  178. package/dist/sync/index.js +4 -4
  179. package/dist/team/index.cjs.map +1 -1
  180. package/dist/team/index.d.cts +5 -5
  181. package/dist/team/index.d.ts +5 -5
  182. package/dist/team/index.js +8 -8
  183. package/dist/transition-guard--t3exQHF.d.cts +165 -0
  184. package/dist/transition-guard-BlI9Oy5K.d.ts +165 -0
  185. package/dist/tx/index.cjs.map +1 -1
  186. package/dist/tx/index.d.cts +5 -5
  187. package/dist/tx/index.d.ts +5 -5
  188. package/dist/tx/index.js +3 -3
  189. package/dist/{types-CrSpRDuG.d.cts → types-BpLPqyaO.d.cts} +487 -25
  190. package/dist/{types-CljIHm_J.d.ts → types-Diqc2caK.d.ts} +487 -25
  191. package/dist/{ulid-CWfL2Vfv.d.ts → ulid-B1zNV8r9.d.ts} +1 -1
  192. package/dist/{ulid-CrI7PPbA.d.cts → ulid-DNiRB4Mx.d.cts} +1 -1
  193. package/dist/util/index.cjs.map +1 -1
  194. package/dist/util/index.js +1 -1
  195. package/dist/{vault-group-DHAHFX2A.js → vault-group-DPZVFRI5.js} +182 -6
  196. package/dist/vault-group-DPZVFRI5.js.map +1 -0
  197. package/dist/{with-materialized-view-NzF71cG_.d.cts → with-materialized-view-BdH_A_r6.d.cts} +1 -1
  198. package/dist/{with-materialized-view-B892zYZV.d.ts → with-materialized-view-CzAgp_HJ.d.ts} +1 -1
  199. package/dist/{with-overlayed-view-CR6m7CHe.d.ts → with-overlayed-view-BJbqQnsR.d.ts} +1 -1
  200. package/dist/{with-overlayed-view-UI8qSGL4.d.cts → with-overlayed-view-C40rDPlu.d.cts} +1 -1
  201. package/dist/with-rollup-Bopu5UDZ.d.cts +47 -0
  202. package/dist/with-rollup-DrlGkxiE.d.ts +47 -0
  203. package/package.json +3 -3
  204. package/dist/chunk-D77ZQSQQ.js.map +0 -1
  205. package/dist/chunk-GP3SDSH2.js.map +0 -1
  206. package/dist/chunk-HGVSHKZW.js.map +0 -1
  207. package/dist/chunk-PDULVIBY.js +0 -63
  208. package/dist/chunk-PDULVIBY.js.map +0 -1
  209. package/dist/chunk-ROPJVUG3.js.map +0 -1
  210. package/dist/chunk-ROVO6NPJ.js.map +0 -1
  211. package/dist/chunk-SISBMAPO.js.map +0 -1
  212. package/dist/chunk-UMLVJTYV.js.map +0 -1
  213. package/dist/chunk-ZEGSDPB7.js.map +0 -1
  214. package/dist/executor-3W63Y44O.js +0 -11
  215. package/dist/executor-CFFWPWBJ.js +0 -8
  216. package/dist/executor-VDQQOR4F.js +0 -8
  217. package/dist/immutable-guard-B5M95nbq.d.ts +0 -82
  218. package/dist/immutable-guard-qN3zF8o1.d.cts +0 -82
  219. package/dist/issue-TTMGHQ2J.js +0 -12
  220. package/dist/noydb-36S6GQNC.js +0 -37
  221. package/dist/read-only-facade-ITU6L7BL.js +0 -7
  222. package/dist/registry-3YFLZ7WD.js +0 -8
  223. package/dist/registry-TGZISEWC.js +0 -8
  224. package/dist/state-vault-W2OEABNO.js.map +0 -1
  225. package/dist/vault-group-DHAHFX2A.js.map +0 -1
  226. package/dist/with-derivation-BZ2y4bzF.d.ts +0 -13
  227. package/dist/with-derivation-Bozs8DmD.d.cts +0 -13
  228. /package/dist/{chunk-SHX5QBCI.js.map → chunk-2U226RDC.js.map} +0 -0
  229. /package/dist/{chunk-7H2GEJ3O.js.map → chunk-32XVU2LT.js.map} +0 -0
  230. /package/dist/{chunk-XJV6OB4D.js.map → chunk-33DAO2XG.js.map} +0 -0
  231. /package/dist/{chunk-U5QCMH3W.js.map → chunk-45643PAU.js.map} +0 -0
  232. /package/dist/{chunk-BH3X5L6A.js.map → chunk-4UI5T3K7.js.map} +0 -0
  233. /package/dist/{chunk-2FU2FTXD.js.map → chunk-5KKNBDCT.js.map} +0 -0
  234. /package/dist/{chunk-CD2AVTEM.js.map → chunk-6FHCU3QO.js.map} +0 -0
  235. /package/dist/{chunk-NBBMMJ2H.js.map → chunk-6Q5XRLKG.js.map} +0 -0
  236. /package/dist/{chunk-XPIHJ34I.js.map → chunk-6XEGHIBA.js.map} +0 -0
  237. /package/dist/{chunk-5LIROIDM.js.map → chunk-6YEC7LLO.js.map} +0 -0
  238. /package/dist/{chunk-C3HYQPV4.js.map → chunk-AB7JF2KF.js.map} +0 -0
  239. /package/dist/{chunk-KCEHMDZF.js.map → chunk-BUBJYIZ7.js.map} +0 -0
  240. /package/dist/{chunk-I5IUYN7B.js.map → chunk-C2OYWD5S.js.map} +0 -0
  241. /package/dist/{chunk-WV7WV6JO.js.map → chunk-CMISAJAE.js.map} +0 -0
  242. /package/dist/{chunk-SNMJ7SB3.js.map → chunk-DKMPR76W.js.map} +0 -0
  243. /package/dist/{chunk-XMVHEWF6.js.map → chunk-DR5I7Q6N.js.map} +0 -0
  244. /package/dist/{chunk-BSZOCSDZ.js.map → chunk-FQRAYDS4.js.map} +0 -0
  245. /package/dist/{chunk-M476FOQ7.js.map → chunk-HOO5I3VG.js.map} +0 -0
  246. /package/dist/{chunk-F4G63NTZ.js.map → chunk-HWK75CYX.js.map} +0 -0
  247. /package/dist/{chunk-FEJDVE3Z.js.map → chunk-HZOEBM67.js.map} +0 -0
  248. /package/dist/{chunk-QHM6XEAH.js.map → chunk-IQ4GMEYZ.js.map} +0 -0
  249. /package/dist/{chunk-5AXTH4QZ.js.map → chunk-K3NYRK7U.js.map} +0 -0
  250. /package/dist/{chunk-3G3W65EQ.js.map → chunk-KTZ2MHQK.js.map} +0 -0
  251. /package/dist/{chunk-E77UKJYL.js.map → chunk-LQ3GD5LL.js.map} +0 -0
  252. /package/dist/{chunk-JDWE6JMX.js.map → chunk-M3H7VSRV.js.map} +0 -0
  253. /package/dist/{chunk-DWEBTE2W.js.map → chunk-MGB67HKX.js.map} +0 -0
  254. /package/dist/{chunk-AEIKD3PP.js.map → chunk-P57D4KBG.js.map} +0 -0
  255. /package/dist/{chunk-YYVZYTWW.js.map → chunk-PGVEL5IZ.js.map} +0 -0
  256. /package/dist/{chunk-UNTGHX5A.js.map → chunk-QJKZ5WUP.js.map} +0 -0
  257. /package/dist/{chunk-BJSLBUJ7.js.map → chunk-QPJ7Z4L3.js.map} +0 -0
  258. /package/dist/{chunk-NYSYPFXJ.js.map → chunk-RQFG2YSV.js.map} +0 -0
  259. /package/dist/{chunk-J7RWBXFY.js.map → chunk-RZWQNMMP.js.map} +0 -0
  260. /package/dist/{chunk-BL5GYANC.js.map → chunk-T4T5I5L6.js.map} +0 -0
  261. /package/dist/{chunk-ZNGPEV5J.js.map → chunk-TFAN3NFD.js.map} +0 -0
  262. /package/dist/{chunk-DYYYUW5D.js.map → chunk-TPOHMOGX.js.map} +0 -0
  263. /package/dist/{chunk-XMHUK5PN.js.map → chunk-TTS3RWL5.js.map} +0 -0
  264. /package/dist/{chunk-TIDXB5DF.js.map → chunk-VVDSDOVV.js.map} +0 -0
  265. /package/dist/{chunk-WIAOUFFB.js.map → chunk-WZCG3EZ6.js.map} +0 -0
  266. /package/dist/{chunk-QO6RGLLD.js.map → chunk-Y5XVB75E.js.map} +0 -0
  267. /package/dist/{chunk-H2MRGONI.js.map → chunk-Z3BE5BRK.js.map} +0 -0
  268. /package/dist/{crypto-7BN2HDWG.js.map → crypto-FNK3XPCS.js.map} +0 -0
  269. /package/dist/{delegation-MGH5SODX.js.map → delegation-FMXNUWE6.js.map} +0 -0
  270. /package/dist/{executor-3W63Y44O.js.map → executor-IZ2NVXCY.js.map} +0 -0
  271. /package/dist/{executor-CFFWPWBJ.js.map → executor-THSEYEJG.js.map} +0 -0
  272. /package/dist/{executor-VDQQOR4F.js.map → executor-WLFDUTOM.js.map} +0 -0
  273. /package/dist/{fanout-sidecar-FIJJ46YG.js.map → fanout-sidecar-JGHXAJO5.js.map} +0 -0
  274. /package/dist/{issue-TTMGHQ2J.js.map → issue-R2MWQO6K.js.map} +0 -0
  275. /package/dist/{ledger-LFVLHE5H.js.map → ledger-GXC2YA3A.js.map} +0 -0
  276. /package/dist/{noydb-36S6GQNC.js.map → noydb-RJL6FQ4B.js.map} +0 -0
  277. /package/dist/{public-envelope-RXZNP3V6.js.map → public-envelope-HXOFHY4N.js.map} +0 -0
  278. /package/dist/{read-only-facade-ITU6L7BL.js.map → read-only-facade-EX6WZZBP.js.map} +0 -0
  279. /package/dist/{registry-3YFLZ7WD.js.map → registry-3T2RZC5A.js.map} +0 -0
  280. /package/dist/{registry-SECUWSGY.js.map → registry-DMS7OKBM.js.map} +0 -0
  281. /package/dist/{registry-TGZISEWC.js.map → registry-WVXO6NH5.js.map} +0 -0
  282. /package/dist/{revoke-B54H2S2W.js.map → revoke-7LCWE2AH.js.map} +0 -0
  283. /package/dist/{signer-YSXZT574.js.map → signer-HAVDLGOK.js.map} +0 -0
  284. /package/dist/{stale-TOA36SRK.js.map → stale-PGTEGJDI.js.map} +0 -0
@@ -7,10 +7,10 @@ import {
7
7
  import {
8
8
  TxContext,
9
9
  revertExecuted
10
- } from "./chunk-ZNGPEV5J.js";
10
+ } from "./chunk-TFAN3NFD.js";
11
11
  import {
12
12
  OverlayedCollection
13
- } from "./chunk-XMHUK5PN.js";
13
+ } from "./chunk-TTS3RWL5.js";
14
14
  import {
15
15
  NO_AGGREGATE,
16
16
  Query,
@@ -20,36 +20,36 @@ import {
20
20
  decodeMoneyFields,
21
21
  quantizeMoneyFields,
22
22
  validateMoneyFieldPaths
23
- } from "./chunk-HGVSHKZW.js";
23
+ } from "./chunk-647TFNYL.js";
24
24
  import {
25
25
  EXPORT_AUDIT_COLLECTION,
26
26
  createExportBlobsHandle,
27
27
  runCompaction
28
- } from "./chunk-KCEHMDZF.js";
28
+ } from "./chunk-BUBJYIZ7.js";
29
29
  import {
30
30
  LazyQuery,
31
31
  decodeIdxId,
32
32
  encodeIdxId
33
- } from "./chunk-NYSYPFXJ.js";
33
+ } from "./chunk-RQFG2YSV.js";
34
34
  import {
35
35
  canonicalGroupKey
36
- } from "./chunk-7H2GEJ3O.js";
36
+ } from "./chunk-32XVU2LT.js";
37
37
  import {
38
38
  readPath
39
- } from "./chunk-J7RWBXFY.js";
39
+ } from "./chunk-RZWQNMMP.js";
40
40
  import {
41
41
  SCHEMAS_COLLECTION,
42
42
  loadPersistedSchema,
43
43
  resolveManagedSecret,
44
44
  savePersistedSchema,
45
45
  saveSealedPassphrase
46
- } from "./chunk-AEIKD3PP.js";
46
+ } from "./chunk-P57D4KBG.js";
47
47
  import {
48
48
  loadPublicEnvelope,
49
49
  readPublicEnvelope,
50
50
  savePublicEnvelope,
51
51
  validatePublicEnvelopeInput
52
- } from "./chunk-YYVZYTWW.js";
52
+ } from "./chunk-PGVEL5IZ.js";
53
53
  import {
54
54
  buildTombstone,
55
55
  isTombstone,
@@ -58,17 +58,17 @@ import {
58
58
  rewrapBodyToDek,
59
59
  rotateRecordCek,
60
60
  sealRecordToHost
61
- } from "./chunk-U5QCMH3W.js";
61
+ } from "./chunk-45643PAU.js";
62
62
  import {
63
63
  PERIODS_COLLECTION
64
- } from "./chunk-BH3X5L6A.js";
64
+ } from "./chunk-4UI5T3K7.js";
65
65
  import {
66
66
  getAtPath,
67
67
  isDictCollectionName,
68
68
  isStaticDictDescriptor,
69
69
  resolvePolicy,
70
70
  setAtPathInPlace
71
- } from "./chunk-ROPJVUG3.js";
71
+ } from "./chunk-KOURQXIU.js";
72
72
  import {
73
73
  ManagedRecoveryNotEnrolledError,
74
74
  PolicyDeniedError,
@@ -90,11 +90,11 @@ import {
90
90
  saveShamirRecoveryEntries,
91
91
  updateAuthenticator,
92
92
  writeMagicLinkGrant
93
- } from "./chunk-QHM6XEAH.js";
93
+ } from "./chunk-IQ4GMEYZ.js";
94
94
  import {
95
95
  assertTierAccess,
96
96
  dekKey
97
- } from "./chunk-5LIROIDM.js";
97
+ } from "./chunk-6YEC7LLO.js";
98
98
  import {
99
99
  USER_ENVELOPE_COLLECTION,
100
100
  assertKeyringOpenAllowed,
@@ -119,7 +119,7 @@ import {
119
119
  rotateKeys,
120
120
  saveUserEnvelope,
121
121
  updateKeyringIdentity
122
- } from "./chunk-BSZOCSDZ.js";
122
+ } from "./chunk-FQRAYDS4.js";
123
123
  import {
124
124
  INDEXED_STORE_POLICY
125
125
  } from "./chunk-2QR2PQTT.js";
@@ -129,7 +129,7 @@ import {
129
129
  import {
130
130
  LEDGER_COLLECTION,
131
131
  LEDGER_DELTAS_COLLECTION
132
- } from "./chunk-DWEBTE2W.js";
132
+ } from "./chunk-MGB67HKX.js";
133
133
  import {
134
134
  sha256Hex as sha256Hex2
135
135
  } from "./chunk-PDVP3C2I.js";
@@ -141,11 +141,11 @@ import {
141
141
  readDottedPath,
142
142
  rebuildSubjectIndex,
143
143
  removeSubjectRef
144
- } from "./chunk-I5IUYN7B.js";
144
+ } from "./chunk-C2OYWD5S.js";
145
145
  import {
146
146
  NOYDB_BACKUP_VERSION,
147
147
  NOYDB_FORMAT_VERSION
148
- } from "./chunk-SISBMAPO.js";
148
+ } from "./chunk-LGPSCKWZ.js";
149
149
  import {
150
150
  decrypt,
151
151
  encrypt,
@@ -153,13 +153,14 @@ import {
153
153
  sha256Hex,
154
154
  unwrapCek,
155
155
  wrapCek
156
- } from "./chunk-UNTGHX5A.js";
156
+ } from "./chunk-QJKZ5WUP.js";
157
157
  import {
158
158
  AlreadyElevatedError,
159
159
  AttestationError,
160
160
  BackupCorruptedError,
161
161
  BackupLedgerError,
162
162
  ConflictError,
163
+ DerivationCapExceededError,
163
164
  ElevationExpiredError,
164
165
  ExportCapabilityError,
165
166
  ForgetStrategyNotConfiguredError,
@@ -191,7 +192,7 @@ import {
191
192
  UnsupportedIndexOptionError,
192
193
  ValidationError,
193
194
  VaultTemplateNotFoundError
194
- } from "./chunk-ZEGSDPB7.js";
195
+ } from "./chunk-HMFC6M2G.js";
195
196
 
196
197
  // src/policy/storage.ts
197
198
  var META_COLLECTION = "_meta";
@@ -837,7 +838,7 @@ async function resolveStaleOnRead(accessor, outputCollection, id) {
837
838
  }
838
839
  const sourceWithId = { ...source, id };
839
840
  if (DerivationExecutor === null) {
840
- ({ DerivationExecutor } = await import("./executor-CFFWPWBJ.js"));
841
+ ({ DerivationExecutor } = await import("./executor-WLFDUTOM.js"));
841
842
  }
842
843
  const ctx = { vault: accessor.getReadOnlyFacade() };
843
844
  const result = await DerivationExecutor.run(spec, sourceWithId, 0, strategyHash, ctx);
@@ -875,6 +876,15 @@ async function resolveStaleOnRead(accessor, outputCollection, id) {
875
876
  }
876
877
 
877
878
  // src/collection.ts
879
+ function selfWriteFieldEqual(a, b) {
880
+ if (a === b) return true;
881
+ if (a === null || b === null || typeof a !== "object" || typeof b !== "object") return false;
882
+ try {
883
+ return JSON.stringify(a) === JSON.stringify(b);
884
+ } catch {
885
+ return false;
886
+ }
887
+ }
878
888
  var fallbackWarned = /* @__PURE__ */ new Set();
879
889
  function warnOnceFallback(adapterName) {
880
890
  if (fallbackWarned.has(adapterName)) return;
@@ -1373,7 +1383,7 @@ var Collection = class {
1373
1383
  }
1374
1384
  }
1375
1385
  if (this.materializedViewSource !== void 0) {
1376
- const { resolveStaleMVOnRead } = await import("./stale-TOA36SRK.js");
1386
+ const { resolveStaleMVOnRead } = await import("./stale-PGTEGJDI.js");
1377
1387
  await resolveStaleMVOnRead(this.materializedViewSource, this.name);
1378
1388
  }
1379
1389
  let record;
@@ -1783,7 +1793,7 @@ var Collection = class {
1783
1793
  if (mode === "eager") {
1784
1794
  if (executor === null) {
1785
1795
  ;
1786
- ({ MaterializedViewExecutor: executor } = await import("./executor-3W63Y44O.js"));
1796
+ ({ MaterializedViewExecutor: executor } = await import("./executor-IZ2NVXCY.js"));
1787
1797
  }
1788
1798
  await executor.refresh(reg, {
1789
1799
  getCollection: (name) => this.materializedViewSource.getCollection(name),
@@ -1792,7 +1802,7 @@ var Collection = class {
1792
1802
  });
1793
1803
  } else if (mode === "lazy") {
1794
1804
  if (staleHelpers === null) {
1795
- staleHelpers = await import("./stale-TOA36SRK.js");
1805
+ staleHelpers = await import("./stale-PGTEGJDI.js");
1796
1806
  }
1797
1807
  staleHelpers.markMVStale(registry, reg.spec.name);
1798
1808
  }
@@ -1809,6 +1819,111 @@ var Collection = class {
1809
1819
  * output (carries `_derivedFrom`) — defensive guard against missed
1810
1820
  * cycle detection.
1811
1821
  */
1822
+ /**
1823
+ * @internal #376 — the RAW stored record (canonical-money form, i18n maps
1824
+ * intact), WITHOUT the locale resolution `get()` applies. Used as the
1825
+ * patch base for self-write reverse-denorm so writing back never clobbers
1826
+ * an i18n map or re-quantizes money incorrectly. Returns null for
1827
+ * missing / tombstoned records.
1828
+ */
1829
+ async _getStoredRecord(id) {
1830
+ let raw;
1831
+ if (this.lazy && this.lru) {
1832
+ const cached = this.lru.get(id);
1833
+ if (cached) raw = cached.record;
1834
+ else {
1835
+ const env = await this.adapter.get(this.vault, this.name, id);
1836
+ if (!env || isTombstone(env, this.encrypted)) return null;
1837
+ raw = await this.decryptRecord(env, { id });
1838
+ if (raw === null) return null;
1839
+ this.lru.set(id, { record: raw, version: env._v }, estimateRecordBytes(raw));
1840
+ }
1841
+ } else {
1842
+ await this.ensureHydrated();
1843
+ raw = this.cache.get(id)?.record ?? null;
1844
+ }
1845
+ if (raw === null) return null;
1846
+ return canonicalizeStoredMoney(raw, this.moneyFields);
1847
+ }
1848
+ /**
1849
+ * @internal #376 — ids of records whose top-level `field` equals `value`.
1850
+ * Uses the FK index when the field is indexed (O(matches)); otherwise a
1851
+ * linear scan (O(N) — fine for small child sets; index the FK to scale).
1852
+ */
1853
+ async _findMatchingIds(field, value) {
1854
+ const hit = this.getIndexes()?.lookupEqual(field, value);
1855
+ if (hit) return [...hit];
1856
+ const target = String(value);
1857
+ const matches = (rec) => {
1858
+ const fv = rec[field];
1859
+ return (typeof fv === "string" || typeof fv === "number") && String(fv) === target;
1860
+ };
1861
+ if (!this.lazy) {
1862
+ await this.ensureHydrated();
1863
+ const out2 = [];
1864
+ for (const [rid, e] of this.cache) {
1865
+ if (matches(e.record)) out2.push(rid);
1866
+ }
1867
+ return out2;
1868
+ }
1869
+ const ids = await this.adapter.list(this.vault, this.name);
1870
+ const out = [];
1871
+ for (const rid of ids) {
1872
+ const raw = await this._getStoredRecord(rid);
1873
+ if (raw !== null && matches(raw)) out.push(rid);
1874
+ }
1875
+ return out;
1876
+ }
1877
+ /**
1878
+ * @internal #376 slice 2 — recompute a rollup aggregate onto the parent.
1879
+ * Gathers every child of `parentId`, runs `compute`, and patches only the
1880
+ * rollup `field` onto the parent's raw stored record (value-equality
1881
+ * guarded). No-op when the parent record does not exist.
1882
+ */
1883
+ async recomputeRollup(spec, parentId) {
1884
+ if (this.derivationSource === void 0 || spec.rollup === void 0) return;
1885
+ const { from, key, field, compute } = spec.rollup;
1886
+ const into = spec.source;
1887
+ const intoColl = this.derivationSource.getCollection(into);
1888
+ const base = await intoColl._getStoredRecord(parentId);
1889
+ if (base === null) return;
1890
+ const fromColl = this.derivationSource.getCollection(from);
1891
+ const childIds = await fromColl._findMatchingIds(key, parentId);
1892
+ const children = [];
1893
+ for (const cid of childIds) {
1894
+ const c = await fromColl.get(cid);
1895
+ if (c !== null && c !== void 0) children.push(c);
1896
+ }
1897
+ const newValue = compute(children);
1898
+ if (selfWriteFieldEqual(base[field], newValue)) return;
1899
+ const patched = { ...base, [field]: newValue };
1900
+ const txCtx = this.derivationSource.getActiveTxContext();
1901
+ if (txCtx !== null) {
1902
+ const prior = await this.adapter.get(this.vault, into, parentId);
1903
+ txCtx._executed.push({
1904
+ op: { type: "put", vaultName: this.vault, collectionName: into, id: parentId },
1905
+ priorEnvelope: prior
1906
+ });
1907
+ }
1908
+ await intoColl.put(parentId, patched);
1909
+ }
1910
+ /**
1911
+ * @internal #376 slice 2 — fire any rollups for which THIS collection is the
1912
+ * child `from`, recomputing the affected parent after a child delete. Called
1913
+ * from the delete path with the just-removed record's key value. Other
1914
+ * derivation kinds do not react to deletes (unchanged).
1915
+ */
1916
+ async dispatchRollupsOnDelete(deleted) {
1917
+ if (this.derivationSource === void 0) return;
1918
+ const registry = this.derivationSource.registry();
1919
+ const rec = deleted;
1920
+ for (const { spec } of registry.strategiesForSource(this.name)) {
1921
+ if (!spec.rollup || spec.rollup.from !== this.name) continue;
1922
+ const kv = rec[spec.rollup.key];
1923
+ if (typeof kv !== "string" && typeof kv !== "number") continue;
1924
+ await this.recomputeRollup(spec, String(kv));
1925
+ }
1926
+ }
1812
1927
  async dispatchDerivations(id, record, version) {
1813
1928
  if (this.derivationSource === void 0) return;
1814
1929
  const incoming = canonicalizeStoredMoney(record, this.moneyFields);
@@ -1819,29 +1934,60 @@ var Collection = class {
1819
1934
  let DerivationExecutor = null;
1820
1935
  for (const { spec, strategyHash } of strategies) {
1821
1936
  const mode = typeof spec.lifecycle === "string" ? spec.lifecycle : spec.lifecycle.mode;
1822
- if (mode === "eager") {
1823
- if (DerivationExecutor === null) {
1824
- ({ DerivationExecutor } = await import("./executor-CFFWPWBJ.js"));
1825
- }
1826
- let sourceWithId;
1827
- let sourceVersion = version;
1828
- if (spec.source === this.name) {
1829
- sourceWithId = { ...incoming, id };
1937
+ if (spec.rollup) {
1938
+ if (mode !== "eager") continue;
1939
+ let parentId;
1940
+ if (this.name === spec.rollup.from) {
1941
+ const kv = incoming[spec.rollup.key];
1942
+ parentId = typeof kv === "string" || typeof kv === "number" ? String(kv) : null;
1830
1943
  } else {
1831
- const primary = await this.derivationSource.getCollection(spec.source).get(id);
1832
- if (primary === null || primary === void 0) continue;
1833
- sourceWithId = { ...primary, id };
1834
- sourceVersion = 0;
1944
+ parentId = id;
1835
1945
  }
1946
+ if (parentId !== null) await this.recomputeRollup(spec, parentId);
1947
+ continue;
1948
+ }
1949
+ const isSource = spec.source === this.name;
1950
+ const isSibling = !isSource && (spec.sources?.includes(this.name) ?? false);
1951
+ const trigger = !isSource && !isSibling ? spec.triggerBy?.find((t) => t.collection === this.name) : void 0;
1952
+ const runs = [];
1953
+ if (isSource) {
1954
+ runs.push({ input: { ...incoming, id }, base: incoming, runId: id, version });
1955
+ } else if (isSibling) {
1956
+ const p = await this.derivationSource.getCollection(spec.source).get(id);
1957
+ if (p !== null && p !== void 0) {
1958
+ const raw = await this.derivationSource.getCollection(spec.source)._getStoredRecord(id);
1959
+ runs.push({ input: { ...p, id }, base: raw ?? p, runId: id, version: 0 });
1960
+ }
1961
+ } else if (trigger) {
1962
+ const srcColl = this.derivationSource.getCollection(spec.source);
1963
+ const ids = await srcColl._findMatchingIds(trigger.on, id);
1964
+ if (trigger.maxFanout !== void 0 && ids.length > trigger.maxFanout) {
1965
+ throw new DerivationCapExceededError(`triggerBy ${this.name}\u2192${spec.source}`, ids.length, trigger.maxFanout);
1966
+ }
1967
+ for (const sid of ids) {
1968
+ const raw = await srcColl._getStoredRecord(sid);
1969
+ if (raw === null) continue;
1970
+ runs.push({ input: { ...raw, id: sid }, base: raw, runId: sid, version: 0 });
1971
+ }
1972
+ }
1973
+ if (runs.length === 0) continue;
1974
+ if (mode !== "eager") {
1975
+ for (const run of runs) await markStale(registry, spec, run.runId);
1976
+ continue;
1977
+ }
1978
+ if (DerivationExecutor === null) {
1979
+ ({ DerivationExecutor } = await import("./executor-WLFDUTOM.js"));
1980
+ }
1981
+ for (const run of runs) {
1836
1982
  const ctx = { vault: this.derivationSource.getReadOnlyFacade() };
1837
- const result = await DerivationExecutor.run(spec, sourceWithId, sourceVersion, strategyHash, ctx);
1983
+ const result = await DerivationExecutor.run(spec, run.input, run.version, strategyHash, ctx);
1838
1984
  for (const key of Object.keys(spec.outputs)) {
1839
1985
  const out = result.outputs[key];
1840
1986
  if (!out) continue;
1841
1987
  if (out.kind === "failed") {
1842
1988
  const err = out.error;
1843
1989
  if (spec.strict) throw err;
1844
- console.warn(`[derivation] output "${key}" for source "${spec.source}" id="${id}" failed:`, err);
1990
+ console.warn(`[derivation] output "${key}" for source "${spec.source}" id="${run.runId}" failed:`, err);
1845
1991
  continue;
1846
1992
  }
1847
1993
  const outSpec = spec.outputs[key];
@@ -1849,12 +1995,12 @@ var Collection = class {
1849
1995
  const outputCollection = this.derivationSource.getCollection(outSpec.collection);
1850
1996
  const txCtx = this.derivationSource.getActiveTxContext();
1851
1997
  if (out.kind === "array") {
1852
- const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-FIJJ46YG.js");
1998
+ const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-JGHXAJO5.js");
1853
1999
  const prior = await loadFanoutSidecar(
1854
2000
  this.adapter,
1855
2001
  this.vault,
1856
2002
  spec.source,
1857
- id,
2003
+ run.runId,
1858
2004
  key
1859
2005
  );
1860
2006
  const prevKeys = new Set(prior?.keys ?? []);
@@ -1881,7 +2027,7 @@ var Collection = class {
1881
2027
  }
1882
2028
  await saveFanoutSidecar(this.adapter, this.vault, {
1883
2029
  source: spec.source,
1884
- sourceId: id,
2030
+ sourceId: run.runId,
1885
2031
  outputKey: key,
1886
2032
  outputCollection: outSpec.collection,
1887
2033
  keys: newKeysList
@@ -1889,25 +2035,44 @@ var Collection = class {
1889
2035
  continue;
1890
2036
  }
1891
2037
  if (out.skipped === true) {
1892
- await outputCollection._internalDelete(id, txCtx);
2038
+ await outputCollection._internalDelete(run.runId, txCtx);
2039
+ continue;
2040
+ }
2041
+ if (outSpec.shape === "record" && outSpec.denorm !== void 0 && outSpec.collection === spec.source) {
2042
+ const value = out.value;
2043
+ const patched = { ...run.base };
2044
+ let changed = false;
2045
+ for (const f of outSpec.denorm) {
2046
+ if (!selfWriteFieldEqual(run.base[f], value[f])) {
2047
+ patched[f] = value[f];
2048
+ changed = true;
2049
+ }
2050
+ }
2051
+ if (!changed) continue;
2052
+ if (txCtx !== null) {
2053
+ const prior = await this.adapter.get(this.vault, outSpec.collection, run.runId);
2054
+ txCtx._executed.push({
2055
+ op: { type: "put", vaultName: this.vault, collectionName: outSpec.collection, id: run.runId },
2056
+ priorEnvelope: prior
2057
+ });
2058
+ }
2059
+ await outputCollection.put(run.runId, patched);
1893
2060
  continue;
1894
2061
  }
1895
2062
  if (txCtx !== null) {
1896
- const prior = await this.adapter.get(this.vault, outSpec.collection, id);
2063
+ const prior = await this.adapter.get(this.vault, outSpec.collection, run.runId);
1897
2064
  txCtx._executed.push({
1898
2065
  op: {
1899
2066
  type: "put",
1900
2067
  vaultName: this.vault,
1901
2068
  collectionName: outSpec.collection,
1902
- id
2069
+ id: run.runId
1903
2070
  },
1904
2071
  priorEnvelope: prior
1905
2072
  });
1906
2073
  }
1907
- await outputCollection.put(id, out.value);
2074
+ await outputCollection.put(run.runId, out.value);
1908
2075
  }
1909
- } else {
1910
- await markStale(registry, spec, id);
1911
2076
  }
1912
2077
  }
1913
2078
  }
@@ -2124,6 +2289,7 @@ var Collection = class {
2124
2289
  if (!internal) {
2125
2290
  await this.dispatchMaterializedViewsOnDelete(id);
2126
2291
  await this.dispatchArrayDerivationsOnDelete(id);
2292
+ if (existing) await this.dispatchRollupsOnDelete(existing.record);
2127
2293
  }
2128
2294
  }
2129
2295
  /**
@@ -2192,7 +2358,7 @@ var Collection = class {
2192
2358
  for (const [outputKey, outSpec] of Object.entries(spec.outputs)) {
2193
2359
  if (outSpec.shape !== "array") continue;
2194
2360
  if (helpers === null) {
2195
- helpers = await import("./fanout-sidecar-FIJJ46YG.js");
2361
+ helpers = await import("./fanout-sidecar-JGHXAJO5.js");
2196
2362
  }
2197
2363
  const sidecar = await helpers.loadFanoutSidecar(
2198
2364
  this.adapter,
@@ -2232,7 +2398,7 @@ var Collection = class {
2232
2398
  if (mode === "eager") {
2233
2399
  if (executor === null) {
2234
2400
  ;
2235
- ({ MaterializedViewExecutor: executor } = await import("./executor-3W63Y44O.js"));
2401
+ ({ MaterializedViewExecutor: executor } = await import("./executor-IZ2NVXCY.js"));
2236
2402
  }
2237
2403
  await executor.refresh(reg, {
2238
2404
  getCollection: (name) => this.materializedViewSource.getCollection(name),
@@ -2241,7 +2407,7 @@ var Collection = class {
2241
2407
  });
2242
2408
  } else if (mode === "lazy") {
2243
2409
  if (staleHelpers === null) {
2244
- staleHelpers = await import("./stale-TOA36SRK.js");
2410
+ staleHelpers = await import("./stale-PGTEGJDI.js");
2245
2411
  }
2246
2412
  staleHelpers.markMVStale(registry, reg.spec.name);
2247
2413
  }
@@ -2264,7 +2430,7 @@ var Collection = class {
2264
2430
  );
2265
2431
  }
2266
2432
  if (this.materializedViewSource !== void 0) {
2267
- const { resolveStaleMVOnRead } = await import("./stale-TOA36SRK.js");
2433
+ const { resolveStaleMVOnRead } = await import("./stale-PGTEGJDI.js");
2268
2434
  await resolveStaleMVOnRead(this.materializedViewSource, this.name);
2269
2435
  }
2270
2436
  await this.ensureHydrated();
@@ -3178,14 +3344,15 @@ var Collection = class {
3178
3344
  (d) => isStaticDictDescriptor(d) && d.displayLocale !== void 0
3179
3345
  );
3180
3346
  if (!locale && !hasStaticDisplay) return result;
3347
+ const layer = localeOpts?._layer ?? "read";
3181
3348
  if (locale && hasI18n && this.i18nFields) {
3182
- result = this.i18nStrategy.applyI18nLocale(result, this.i18nFields, locale, localeOpts?.fallback);
3349
+ result = this.i18nStrategy.applyI18nLocale(result, this.i18nFields, locale, localeOpts?.fallback, layer);
3183
3350
  }
3184
3351
  if (hasDict && this.dictKeyFields && this.dictLabelResolver && locale !== "raw") {
3185
3352
  const withLabels = { ...result };
3186
3353
  const resolver = this.dictLabelResolver;
3187
3354
  for (const [field, desc] of Object.entries(this.dictKeyFields)) {
3188
- const policy = desc.onMissing ? resolvePolicy(desc.onMissing, "read") : "null";
3355
+ const policy = desc.onMissing ? resolvePolicy(desc.onMissing, layer) : "null";
3189
3356
  const fallback = policy === "substitute" ? localeOpts?.fallback ?? desc.substitute : localeOpts?.fallback;
3190
3357
  const effLocale = locale ?? (isStaticDictDescriptor(desc) ? desc.displayLocale : void 0);
3191
3358
  const resolveKey = async (key) => {
@@ -4026,6 +4193,38 @@ function withArchive(opts) {
4026
4193
  // src/sequence/index.ts
4027
4194
  var SEQUENCE_COLLECTION = "_sequences";
4028
4195
  var MAX_NEXT_ATTEMPTS = 16;
4196
+ var SEQ_FORMAT_TOKEN = /\{([^{}]*)\}/g;
4197
+ var SEQ_PAD_TOKEN = /^seq:0(\d+)$/;
4198
+ var SEQ_PARTITION_TOKEN = /^partition\.(\d+)$/;
4199
+ function compileSequenceFormat(format, series, partition) {
4200
+ const parts = partition ?? [];
4201
+ for (const m of format.matchAll(SEQ_FORMAT_TOKEN)) {
4202
+ const token = m[1] ?? "";
4203
+ if (token === "seq") continue;
4204
+ if (SEQ_PAD_TOKEN.test(token)) continue;
4205
+ const partMatch = SEQ_PARTITION_TOKEN.exec(token);
4206
+ if (partMatch) {
4207
+ const idx = Number(partMatch[1]);
4208
+ if (idx >= parts.length) {
4209
+ throw new ValidationError(
4210
+ `sequence("${series}"): format token "{${token}}" references partition index ${idx}, but only ${parts.length} partition component(s) were supplied.`
4211
+ );
4212
+ }
4213
+ continue;
4214
+ }
4215
+ throw new ValidationError(
4216
+ `sequence("${series}"): format contains unknown token "{${token}}". Accepted tokens: {seq}, {seq:0N}, {partition.i}.`
4217
+ );
4218
+ }
4219
+ return (serial) => format.replace(SEQ_FORMAT_TOKEN, (full, token) => {
4220
+ if (token === "seq") return String(serial);
4221
+ const padMatch = SEQ_PAD_TOKEN.exec(token);
4222
+ if (padMatch) return String(serial).padStart(Number(padMatch[1]), "0");
4223
+ const partMatch = SEQ_PARTITION_TOKEN.exec(token);
4224
+ if (partMatch) return String(parts[Number(partMatch[1])]);
4225
+ return full;
4226
+ });
4227
+ }
4029
4228
  function resolveSequenceKey(series, opts) {
4030
4229
  const partition = opts?.partition;
4031
4230
  if (!partition || partition.length === 0) return series;
@@ -4345,6 +4544,9 @@ var NO_PERIODS = {
4345
4544
  };
4346
4545
 
4347
4546
  // src/refs.ts
4547
+ function isRefArray(desc) {
4548
+ return desc.isArray === true;
4549
+ }
4348
4550
  var RefIntegrityError = class extends NoydbError {
4349
4551
  collection;
4350
4552
  id;
@@ -4381,6 +4583,17 @@ function ref(target, mode = "strict") {
4381
4583
  }
4382
4584
  return { target, mode };
4383
4585
  }
4586
+ function refArray(target, mode = "strict") {
4587
+ if (target.includes("/")) {
4588
+ throw new RefScopeError(target);
4589
+ }
4590
+ if (!target || target.startsWith("_")) {
4591
+ throw new Error(
4592
+ `refArray(): target collection name must be non-empty and cannot start with '_' (reserved for internal collections). Got "${target}".`
4593
+ );
4594
+ }
4595
+ return { target, mode, isArray: true };
4596
+ }
4384
4597
  var RefRegistry = class {
4385
4598
  outbound = /* @__PURE__ */ new Map();
4386
4599
  inbound = /* @__PURE__ */ new Map();
@@ -4405,7 +4618,7 @@ var RefRegistry = class {
4405
4618
  for (const k of existingKeys) {
4406
4619
  const a = existing[k];
4407
4620
  const b = refs[k];
4408
- if (!a || !b || a.target !== b.target || a.mode !== b.mode) {
4621
+ if (!a || !b || a.target !== b.target || a.mode !== b.mode || a.isArray !== b.isArray) {
4409
4622
  throw new Error(
4410
4623
  `RefRegistry: conflicting ref declarations for collection "${collection}" field "${k}"`
4411
4624
  );
@@ -4416,7 +4629,7 @@ var RefRegistry = class {
4416
4629
  this.outbound.set(collection, { ...refs });
4417
4630
  for (const [field, desc] of Object.entries(refs)) {
4418
4631
  const list = this.inbound.get(desc.target) ?? [];
4419
- list.push({ collection, field, mode: desc.mode });
4632
+ list.push({ collection, field, mode: desc.mode, ...desc.isArray ? { isArray: true } : {} });
4420
4633
  this.inbound.set(desc.target, list);
4421
4634
  }
4422
4635
  }
@@ -4444,6 +4657,141 @@ var RefRegistry = class {
4444
4657
  }
4445
4658
  };
4446
4659
 
4660
+ // src/links/link-set.ts
4661
+ var LINK_COLLECTION_PREFIX = "_links_";
4662
+ function linkCollectionName(name) {
4663
+ return `${LINK_COLLECTION_PREFIX}${name}`;
4664
+ }
4665
+ function isLinkCollectionName(name) {
4666
+ return name.startsWith(LINK_COLLECTION_PREFIX);
4667
+ }
4668
+ function linkRowKey(aId, bId) {
4669
+ return `${encodeURIComponent(aId)}|${encodeURIComponent(bId)}`;
4670
+ }
4671
+ var LinkSet = class {
4672
+ constructor(adapter, vault, name, spec, encrypted, getDEK, actor, emitter, endpointExists) {
4673
+ this.adapter = adapter;
4674
+ this.vault = vault;
4675
+ this.name = name;
4676
+ this.spec = spec;
4677
+ this.encrypted = encrypted;
4678
+ this.getDEK = getDEK;
4679
+ this.actor = actor;
4680
+ this.emitter = emitter;
4681
+ this.endpointExists = endpointExists;
4682
+ this.collName = linkCollectionName(name);
4683
+ }
4684
+ adapter;
4685
+ vault;
4686
+ name;
4687
+ spec;
4688
+ encrypted;
4689
+ getDEK;
4690
+ actor;
4691
+ emitter;
4692
+ endpointExists;
4693
+ collName;
4694
+ dekPromise = null;
4695
+ dek() {
4696
+ if (!this.dekPromise) this.dekPromise = this.getDEK(this.collName);
4697
+ return this.dekPromise;
4698
+ }
4699
+ async encryptEntry(entry, version) {
4700
+ const json = JSON.stringify(entry);
4701
+ const base = { _noydb: NOYDB_FORMAT_VERSION, _v: version, _ts: (/* @__PURE__ */ new Date()).toISOString(), _by: this.actor };
4702
+ if (!this.encrypted) return { ...base, _iv: "", _data: json };
4703
+ const { iv, data } = await encrypt(json, await this.dek());
4704
+ return { ...base, _iv: iv, _data: data };
4705
+ }
4706
+ async decryptEntry(env) {
4707
+ const json = this.encrypted ? await decrypt(env._iv, env._data, await this.dek()) : env._data;
4708
+ return JSON.parse(json);
4709
+ }
4710
+ async connect(aId, bId, meta) {
4711
+ if (!await this.endpointExists(this.spec.a, aId)) {
4712
+ throw new LinkEndpointError(this.name, this.spec.a, aId);
4713
+ }
4714
+ if (!await this.endpointExists(this.spec.b, bId)) {
4715
+ throw new LinkEndpointError(this.name, this.spec.b, bId);
4716
+ }
4717
+ const key = linkRowKey(aId, bId);
4718
+ const entry = meta !== void 0 ? { a: aId, b: bId, meta } : { a: aId, b: bId };
4719
+ const existing = await this.adapter.get(this.vault, this.collName, key);
4720
+ const env = await this.encryptEntry(entry, (existing?._v ?? 0) + 1);
4721
+ await this.adapter.put(this.vault, this.collName, key, env, existing?._v);
4722
+ this.emitter.emit("change", { vault: this.vault, collection: this.collName, id: key, action: "put" });
4723
+ }
4724
+ async disconnect(aId, bId) {
4725
+ const key = linkRowKey(aId, bId);
4726
+ const existing = await this.adapter.get(this.vault, this.collName, key);
4727
+ if (!existing) return;
4728
+ await this.adapter.delete(this.vault, this.collName, key);
4729
+ this.emitter.emit("change", { vault: this.vault, collection: this.collName, id: key, action: "delete" });
4730
+ }
4731
+ async has(aId, bId) {
4732
+ return await this.adapter.get(this.vault, this.collName, linkRowKey(aId, bId)) !== null;
4733
+ }
4734
+ async of(id) {
4735
+ const rows = await this.list();
4736
+ return rows.filter((r) => r.a === id || r.b === id);
4737
+ }
4738
+ async list() {
4739
+ const keys = await this.adapter.list(this.vault, this.collName);
4740
+ const out = [];
4741
+ for (const key of keys) {
4742
+ const env = await this.adapter.get(this.vault, this.collName, key);
4743
+ if (!env) continue;
4744
+ const e = await this.decryptEntry(env);
4745
+ out.push(e.meta !== void 0 ? { a: e.a, b: e.b, meta: e.meta } : { a: e.a, b: e.b });
4746
+ }
4747
+ return out;
4748
+ }
4749
+ // ── Vault-internal cascade helpers ──────────────────────────────────
4750
+ /** @internal — rows where the deleted endpoint id matches the relevant slot. */
4751
+ async _rowsTouchingEndpoint(collection, id) {
4752
+ const rows = await this.list();
4753
+ return rows.filter(
4754
+ (r) => this.spec.a === collection && r.a === id || this.spec.b === collection && r.b === id
4755
+ );
4756
+ }
4757
+ /** @internal — the storage collection name (for tx pre-image capture). */
4758
+ get _collectionName() {
4759
+ return this.collName;
4760
+ }
4761
+ };
4762
+ var LinkEndpointError = class extends NoydbError {
4763
+ link;
4764
+ endpoint;
4765
+ missingId;
4766
+ constructor(link, endpoint, missingId) {
4767
+ super(
4768
+ "LINK_ENDPOINT",
4769
+ `link("${link}").connect: endpoint "${endpoint}" has no record "${missingId}".`
4770
+ );
4771
+ this.name = "LinkEndpointError";
4772
+ this.link = link;
4773
+ this.endpoint = endpoint;
4774
+ this.missingId = missingId;
4775
+ }
4776
+ };
4777
+ var LinkIntegrityError = class extends NoydbError {
4778
+ link;
4779
+ endpoint;
4780
+ id;
4781
+ count;
4782
+ constructor(link, endpoint, id, count) {
4783
+ super(
4784
+ "LINK_INTEGRITY",
4785
+ `Cannot delete "${endpoint}"/"${id}": ${count} link(s) in "${link}" still reference it (onDelete: 'strict').`
4786
+ );
4787
+ this.name = "LinkIntegrityError";
4788
+ this.link = link;
4789
+ this.endpoint = endpoint;
4790
+ this.id = id;
4791
+ this.count = count;
4792
+ }
4793
+ };
4794
+
4447
4795
  // src/meta/user-envelope/api.ts
4448
4796
  var UserApi = class {
4449
4797
  constructor(adapter, vaultName, writerKeyringId, getDek, checkGate2) {
@@ -5468,13 +5816,17 @@ var Vault = class {
5468
5816
  */
5469
5817
  overlayedViewRegistry = null;
5470
5818
  /**
5471
- * Cached read-only facade handed to guard callbacks via `ctx.vault`,
5472
- * and to derivation callbacks via `derive(source, ctx)`. Allocated
5473
- * eagerly inside `_initGuards()` and/or `_initDerivations()` so read
5819
+ * Cached read-only facades handed to guard callbacks via `ctx.vault`
5820
+ * and to derivation callbacks via `derive(source, ctx)`. Split by
5821
+ * resolution layer (#285): the guard facade reads at `layer:'guard'`,
5822
+ * the derivation facade at `layer:'derivation'`, so i18nText / dictKey
5823
+ * fields resolve under that layer's `onMissing` policy. Allocated
5824
+ * eagerly inside `_initGuards()` / `_initDerivations()` so read
5474
5825
  * accessors stay synchronous (callers in `tx/transaction.ts` rely on
5475
- * that). Stays `null` for vaults with neither subsystem configured.
5826
+ * that). Each stays `null` for vaults without that subsystem.
5476
5827
  */
5477
- readOnlyFacade = null;
5828
+ guardFacade = null;
5829
+ derivationFacade = null;
5478
5830
  getDEK;
5479
5831
  /**
5480
5832
  * Per-principal user envelope API.
@@ -5636,6 +5988,10 @@ var Vault = class {
5636
5988
  i18nFieldRegistry = /* @__PURE__ */ new Map();
5637
5989
  /** Cache of DictionaryHandle instances, one per dictionary name. */
5638
5990
  dictionaryCache = /* @__PURE__ */ new Map();
5991
+ /** Registered link specs (#377-B), keyed by link name; set by `vault.link()`. */
5992
+ linkRegistry = /* @__PURE__ */ new Map();
5993
+ /** Cache of LinkSet handles, one per link name. */
5994
+ linkSetCache = /* @__PURE__ */ new Map();
5639
5995
  /** — subscribers for cross-tier access events. */
5640
5996
  crossTierSubs = /* @__PURE__ */ new Set();
5641
5997
  /** — currently-active elevation, or null. One per vault. */
@@ -5752,6 +6108,9 @@ var Vault = class {
5752
6108
  if (collectionName === SEQUENCE_COLLECTION) {
5753
6109
  throw new ReservedCollectionNameError(collectionName);
5754
6110
  }
6111
+ if (isLinkCollectionName(collectionName)) {
6112
+ throw new ReservedCollectionNameError(collectionName);
6113
+ }
5755
6114
  let coll = this.collectionCache.get(collectionName);
5756
6115
  if (coll && options?.moneyFields) {
5757
6116
  coll._applyMoneyFields(options.moneyFields);
@@ -5823,6 +6182,7 @@ var Vault = class {
5823
6182
  }));
5824
6183
  schemaUpdateGate = new SchemaUpdateGate(work);
5825
6184
  }
6185
+ const effectiveHistoryConfig = options?.historyConfig ?? this.historyConfig;
5826
6186
  const collOpts = {
5827
6187
  adapter: this.adapter,
5828
6188
  vault: this.name,
@@ -5838,7 +6198,7 @@ var Vault = class {
5838
6198
  schemaFence: this.schemaFence,
5839
6199
  getDEK: this.getDEK,
5840
6200
  onDirty: this.onDirty,
5841
- historyConfig: this.historyConfig,
6201
+ historyConfig: effectiveHistoryConfig,
5842
6202
  // thread the vault-wide blob strategy into every
5843
6203
  // collection. `undefined` is intentionally preserved so the
5844
6204
  // Collection constructor uses its NO_BLOBS default.
@@ -5849,7 +6209,11 @@ var Vault = class {
5849
6209
  historyStrategy: this.historyStrategy,
5850
6210
  i18nStrategy: this.i18nStrategy,
5851
6211
  syncStrategy: this.syncStrategy,
5852
- ledger: this.getLedgerOrNull() ?? void 0,
6212
+ // Per-collection ledger opt-out (#361): when this collection sets
6213
+ // `historyConfig.ledger: false`, withhold the ledger reference so all
6214
+ // four `if (this.ledger)` append sites in Collection no-op. The chain
6215
+ // stays valid — it simply never receives this collection's entries.
6216
+ ledger: effectiveHistoryConfig.ledger === false ? void 0 : this.getLedgerOrNull() ?? void 0,
5853
6217
  refEnforcer: this,
5854
6218
  joinResolver: this,
5855
6219
  defaultLocale: this.locale,
@@ -6210,6 +6574,68 @@ var Vault = class {
6210
6574
  }
6211
6575
  return handle;
6212
6576
  }
6577
+ /**
6578
+ * Declare a managed many-to-many link set (#377-B). Registers a
6579
+ * `_links_<name>` junction between two endpoint collections; access its
6580
+ * rows via `vault.links(name)`. Idempotent for an identical re-declaration;
6581
+ * a conflicting one throws. See {@link links}.
6582
+ *
6583
+ * ```ts
6584
+ * vault.link('saleLineLinks', { a: ref('saleLines'), b: ref('purchaseLines'), onDelete: 'cascade' })
6585
+ * ```
6586
+ *
6587
+ * `a` / `b` accept either a collection name or a `ref(target)` descriptor
6588
+ * (only its `target` is used — links manage their own integrity). `onDelete`
6589
+ * governs what happens to link rows when an endpoint record is deleted
6590
+ * (`'cascade'` default, `'strict'`, `'warn'`).
6591
+ */
6592
+ link(name, spec) {
6593
+ const a = typeof spec.a === "string" ? spec.a : spec.a.target;
6594
+ const b = typeof spec.b === "string" ? spec.b : spec.b.target;
6595
+ for (const [slot, target] of [["a", a], ["b", b]]) {
6596
+ if (!target || target.startsWith("_") || target.includes("/")) {
6597
+ throw new ValidationError(
6598
+ `vault.link("${name}"): endpoint "${slot}" must be a simple collection name, got "${target}".`
6599
+ );
6600
+ }
6601
+ }
6602
+ const resolved = { a, b, ...spec.onDelete ? { onDelete: spec.onDelete } : {} };
6603
+ const existing = this.linkRegistry.get(name);
6604
+ if (existing) {
6605
+ if (existing.a !== resolved.a || existing.b !== resolved.b || (existing.onDelete ?? "cascade") !== (resolved.onDelete ?? "cascade")) {
6606
+ throw new ValidationError(`vault.link("${name}"): conflicting re-declaration.`);
6607
+ }
6608
+ return;
6609
+ }
6610
+ this.linkRegistry.set(name, resolved);
6611
+ }
6612
+ /**
6613
+ * Access a declared link set (#377-B). Throws if `name` was not first
6614
+ * declared via {@link link}. Returns a cached {@link LinkSetHandle}:
6615
+ * `connect(a, b, meta?)`, `disconnect(a, b)`, `has(a, b)`, `of(id)`, `list()`.
6616
+ */
6617
+ links(name) {
6618
+ let handle = this.linkSetCache.get(name);
6619
+ if (!handle) {
6620
+ const spec = this.linkRegistry.get(name);
6621
+ if (!spec) {
6622
+ throw new ValidationError(`vault.links("${name}"): not declared. Call vault.link("${name}", { a, b }) first.`);
6623
+ }
6624
+ handle = new LinkSet(
6625
+ this.adapter,
6626
+ this.name,
6627
+ name,
6628
+ spec,
6629
+ this.encrypted,
6630
+ this.getDEK,
6631
+ this.keyring.userId,
6632
+ this.emitter,
6633
+ async (collection, id) => await this.collection(collection).get(id) !== null
6634
+ );
6635
+ this.linkSetCache.set(name, handle);
6636
+ }
6637
+ return handle;
6638
+ }
6213
6639
  /**
6214
6640
  * Build a `JoinableSource` for a dictKey field, for use in dict joins
6215
6641
  *. Returns a source whose snapshot contains `{ key, ...labels }`
@@ -6369,65 +6795,16 @@ var Vault = class {
6369
6795
  });
6370
6796
  }
6371
6797
  }
6372
- /**
6373
- * Bulk blob extraction primitive.
6374
- *
6375
- * Returns an async-iterable handle over every blob attached to
6376
- * records in the vault. Single capability check (`plaintext/blob`)
6377
- * at handle creation; single audit entry to `_export_audit` before
6378
- * the first yield. Per-blob decryption happens lazily as the
6379
- * consumer pulls tuples.
6380
- *
6381
- * ```ts
6382
- * const handle = vault.exportBlobs({
6383
- * collections: ['invoiceScans'],
6384
- * where: (rec) => (rec as { clientId?: string }).clientId === 'c-123',
6385
- * })
6386
- * for await (const { bytes, meta, recordRef } of handle) {
6387
- * await uploadToColdStorage(bytes, recordRef)
6388
- * }
6389
- * ```
6390
- *
6391
- * @see `@noy-db/hub/store/export-blobs` for the full option surface.
6392
- */
6393
- /**
6394
- * Evict blob slots per the per-collection `blobFields` retention
6395
- * policy.
6396
- *
6397
- * Iterates every collection declared with `{ blobFields: {...} }`.
6398
- * For each record, checks every configured slot against its
6399
- * policy — `retainDays` (age-based TTL) and/or `evictWhen(record)`
6400
- * (predicate) — and evicts matching slots. Every eviction writes
6401
- * one entry to `_blob_eviction_audit` (actor + eTag + reason +
6402
- * timestamp, no plaintext). Consumer-scheduled; noy-db never runs
6403
- * this on its own.
6404
- *
6405
- * ```ts
6406
- * await vault.compact() // run full pass
6407
- * await vault.compact({ dryRun: true }) // preview counts
6408
- * await vault.compact({ maxEvictions: 1000 }) // cap batch
6409
- * ```
6410
- */
6411
- /**
6412
- * Atomic, gap-free numbering. `vault.sequence('invoice-2026').next()`
6413
- * returns 1, 2, 3, … with no gaps or duplicates under concurrency, via
6414
- * an optimistic-CAS counter at `_sequences/<name>`. Each name is an
6415
- * independent sequence.
6416
- *
6417
- * **Online-only:** `next()` throws `SequenceOfflineError` unless the
6418
- * store advertises `capabilities.casAtomic` — gap-free numbering cannot
6419
- * be serialized by an offline / non-CAS writer.
6420
- *
6421
- * ```ts
6422
- * const n = await vault.sequence('invoice-2026').next() // 1, then 2, …
6423
- * const cur = await vault.sequence('invoice-2026').peek() // current value, no allocation
6424
- * ```
6425
- */
6426
6798
  sequence(series, opts) {
6427
6799
  if (series.includes("\0")) {
6428
6800
  throw new ValidationError(`sequence("${series}"): series name must not contain a null byte (\\x00).`);
6429
6801
  }
6430
6802
  if (this.numberingConfigs.has(series)) {
6803
+ if (opts?.format !== void 0) {
6804
+ throw new ValidationError(
6805
+ `sequence("${series}") is a deferred-numbering series; the format option applies to CAS sequences only.`
6806
+ );
6807
+ }
6431
6808
  const eng = this.deferred();
6432
6809
  return {
6433
6810
  next: async (nextOpts) => {
@@ -6451,7 +6828,17 @@ var Vault = class {
6451
6828
  actor: this.keyring.userId
6452
6829
  });
6453
6830
  }
6454
- return this.sequenceStore.handle(resolveSequenceKey(series, opts));
6831
+ const handle = this.sequenceStore.handle(resolveSequenceKey(series, opts));
6832
+ if (opts?.format === void 0) return handle;
6833
+ const render = compileSequenceFormat(opts.format, series, opts.partition);
6834
+ return {
6835
+ next: async (nextOpts) => {
6836
+ const serial = await handle.next(nextOpts);
6837
+ return { serial, formatted: render(serial) };
6838
+ },
6839
+ peek: () => handle.peek(),
6840
+ seedTo: (n) => handle.seedTo(n)
6841
+ };
6455
6842
  }
6456
6843
  /** @internal — lazily build the deferred-numbering engine with a cache-coherent stamp. */
6457
6844
  deferred() {
@@ -6566,12 +6953,12 @@ var Vault = class {
6566
6953
  if (!fieldSchema) {
6567
6954
  throw new AttestationError(`issueAttestation: collection '${collectionName}' has no attestation field-schema. Declare it via vault.collection('${collectionName}', { attestation: { fields: [...] } }).`);
6568
6955
  }
6569
- const { issueAttestationCore } = await import("./issue-TTMGHQ2J.js");
6956
+ const { issueAttestationCore } = await import("./issue-R2MWQO6K.js");
6570
6957
  const out = await issueAttestationCore(this.makeIssueContext(), { collection: collectionName, id, fieldSchema });
6571
6958
  return { docId: out.docId, qr: out.qr, keyId: out.keyId, publicKeyB64: out.publicKeyB64 };
6572
6959
  }
6573
6960
  async getDocumentSigningPublicKey() {
6574
- const { loadSigner, loadOrCreateSigner } = await import("./signer-YSXZT574.js");
6961
+ const { loadSigner, loadOrCreateSigner } = await import("./signer-HAVDLGOK.js");
6575
6962
  const existing = await loadSigner(this.adapter, this.name, this.getDEK);
6576
6963
  if (existing) return { keyId: existing.keyId, publicKeyB64: existing.publicKeyB64 };
6577
6964
  if (this.keyring.role !== "owner") {
@@ -6597,19 +6984,19 @@ var Vault = class {
6597
6984
  };
6598
6985
  }
6599
6986
  async revokeAttestation(docId) {
6600
- const { revokeDocCore } = await import("./revoke-B54H2S2W.js");
6987
+ const { revokeDocCore } = await import("./revoke-7LCWE2AH.js");
6601
6988
  await revokeDocCore(this.makeRevokeContext(), docId);
6602
6989
  }
6603
6990
  async unrevokeAttestation(docId) {
6604
- const { unrevokeDocCore } = await import("./revoke-B54H2S2W.js");
6991
+ const { unrevokeDocCore } = await import("./revoke-7LCWE2AH.js");
6605
6992
  await unrevokeDocCore(this.makeRevokeContext(), docId);
6606
6993
  }
6607
6994
  async getRevokedDocIds() {
6608
- const { getRevokedDocIdsCore } = await import("./revoke-B54H2S2W.js");
6995
+ const { getRevokedDocIdsCore } = await import("./revoke-7LCWE2AH.js");
6609
6996
  return getRevokedDocIdsCore(this.makeRevokeContext());
6610
6997
  }
6611
6998
  async publishRevocationList() {
6612
- const { publishRevocationListCore } = await import("./revoke-B54H2S2W.js");
6999
+ const { publishRevocationListCore } = await import("./revoke-7LCWE2AH.js");
6613
7000
  return publishRevocationListCore(this.makeRevokeContext());
6614
7001
  }
6615
7002
  makeRevokeContext() {
@@ -6678,6 +7065,43 @@ var Vault = class {
6678
7065
  if (descriptor.mode !== "strict") continue;
6679
7066
  const rawId = obj[field];
6680
7067
  if (rawId === null || rawId === void 0) continue;
7068
+ if (isRefArray(descriptor)) {
7069
+ if (!Array.isArray(rawId)) {
7070
+ throw new RefIntegrityError({
7071
+ collection: collectionName,
7072
+ id: obj["id"] ?? "<unknown>",
7073
+ field,
7074
+ refTo: descriptor.target,
7075
+ refId: null,
7076
+ message: `Array ref field "${collectionName}.${field}" must be an array, got ${typeof rawId}.`
7077
+ });
7078
+ }
7079
+ const arrTarget = this.collection(descriptor.target);
7080
+ for (const el of rawId) {
7081
+ if (typeof el !== "string" && typeof el !== "number") {
7082
+ throw new RefIntegrityError({
7083
+ collection: collectionName,
7084
+ id: obj["id"] ?? "<unknown>",
7085
+ field,
7086
+ refTo: descriptor.target,
7087
+ refId: null,
7088
+ message: `Array ref "${collectionName}.${field}" elements must be strings or numbers, got ${typeof el}.`
7089
+ });
7090
+ }
7091
+ const elId = String(el);
7092
+ if (!await arrTarget.get(elId)) {
7093
+ throw new RefIntegrityError({
7094
+ collection: collectionName,
7095
+ id: obj["id"] ?? "<unknown>",
7096
+ field,
7097
+ refTo: descriptor.target,
7098
+ refId: elId,
7099
+ message: `Strict array ref "${collectionName}.${field}" \u2192 "${descriptor.target}" cannot be satisfied: element id "${elId}" not found in "${descriptor.target}".`
7100
+ });
7101
+ }
7102
+ }
7103
+ continue;
7104
+ }
6681
7105
  if (typeof rawId !== "string" && typeof rawId !== "number") {
6682
7106
  throw new RefIntegrityError({
6683
7107
  collection: collectionName,
@@ -6727,6 +7151,11 @@ var Vault = class {
6727
7151
  const allRecords = await fromCollection.list();
6728
7152
  const matches = allRecords.filter((rec) => {
6729
7153
  const raw = rec[rule.field];
7154
+ if (rule.isArray) {
7155
+ return Array.isArray(raw) && raw.some(
7156
+ (el) => (typeof el === "string" || typeof el === "number") && String(el) === id
7157
+ );
7158
+ }
6730
7159
  if (typeof raw !== "string" && typeof raw !== "number") return false;
6731
7160
  return String(raw) === id;
6732
7161
  });
@@ -6765,10 +7194,45 @@ var Vault = class {
6765
7194
  }
6766
7195
  }
6767
7196
  }
7197
+ await this.enforceLinksOnDelete(collectionName, id);
6768
7198
  } finally {
6769
7199
  this.cascadeInProgress.delete(key);
6770
7200
  }
6771
7201
  }
7202
+ /**
7203
+ * @internal — apply link `onDelete` policy when an endpoint record is
7204
+ * deleted (#377-B). `'strict'` throws (blocks the delete), `'cascade'`
7205
+ * removes the touching link rows (tx-atomic when a transaction is active),
7206
+ * `'warn'` leaves orphans for `checkIntegrity()`.
7207
+ */
7208
+ async enforceLinksOnDelete(collectionName, id) {
7209
+ for (const [name, spec] of this.linkRegistry) {
7210
+ if (spec.a !== collectionName && spec.b !== collectionName) continue;
7211
+ const handle = this.links(name);
7212
+ const touching = await handle._rowsTouchingEndpoint(collectionName, id);
7213
+ if (touching.length === 0) continue;
7214
+ const mode = spec.onDelete ?? "cascade";
7215
+ if (mode === "warn") continue;
7216
+ if (mode === "strict") {
7217
+ throw new LinkIntegrityError(name, collectionName, id, touching.length);
7218
+ }
7219
+ const linkColl = handle._collectionName;
7220
+ const txCtx = this.noydb._activeTxContextOrNull;
7221
+ for (const row of touching) {
7222
+ const rowKey = linkRowKey(row.a, row.b);
7223
+ if (txCtx !== null) {
7224
+ const prior = await this.adapter.get(this.name, linkColl, rowKey);
7225
+ if (prior !== null) {
7226
+ txCtx._executed.push({
7227
+ op: { type: "delete", vaultName: this.name, collectionName: linkColl, id: rowKey },
7228
+ priorEnvelope: prior
7229
+ });
7230
+ }
7231
+ }
7232
+ await handle.disconnect(row.a, row.b);
7233
+ }
7234
+ }
7235
+ }
6772
7236
  // ─── Join resolver) ────────────────────
6773
7237
  /**
6774
7238
  * Look up the `RefDescriptor` the left collection declared for a
@@ -6829,6 +7293,23 @@ var Vault = class {
6829
7293
  for (const [field, descriptor] of Object.entries(refs)) {
6830
7294
  const rawId = record[field];
6831
7295
  if (rawId === null || rawId === void 0) continue;
7296
+ const target = this.collection(descriptor.target);
7297
+ if (isRefArray(descriptor)) {
7298
+ if (!Array.isArray(rawId)) {
7299
+ violations.push({ collection: collectionName, id: recId, field, refTo: descriptor.target, refId: rawId, mode: descriptor.mode });
7300
+ continue;
7301
+ }
7302
+ for (const el of rawId) {
7303
+ if (typeof el !== "string" && typeof el !== "number") {
7304
+ violations.push({ collection: collectionName, id: recId, field, refTo: descriptor.target, refId: el, mode: descriptor.mode });
7305
+ continue;
7306
+ }
7307
+ if (!await target.get(String(el))) {
7308
+ violations.push({ collection: collectionName, id: recId, field, refTo: descriptor.target, refId: el, mode: descriptor.mode });
7309
+ }
7310
+ }
7311
+ continue;
7312
+ }
6832
7313
  if (typeof rawId !== "string" && typeof rawId !== "number") {
6833
7314
  violations.push({
6834
7315
  collection: collectionName,
@@ -6841,7 +7322,6 @@ var Vault = class {
6841
7322
  continue;
6842
7323
  }
6843
7324
  const refId = String(rawId);
6844
- const target = this.collection(descriptor.target);
6845
7325
  const exists = await target.get(refId);
6846
7326
  if (!exists) {
6847
7327
  violations.push({
@@ -6856,6 +7336,19 @@ var Vault = class {
6856
7336
  }
6857
7337
  }
6858
7338
  }
7339
+ for (const [name, spec] of this.linkRegistry) {
7340
+ const linkColl = linkCollectionName(name);
7341
+ const rows = await this.links(name).list();
7342
+ for (const row of rows) {
7343
+ const rowKey = linkRowKey(row.a, row.b);
7344
+ if (await this.collection(spec.a).get(row.a) === null) {
7345
+ violations.push({ collection: linkColl, id: rowKey, field: "a", refTo: spec.a, refId: row.a, mode: spec.onDelete ?? "cascade" });
7346
+ }
7347
+ if (await this.collection(spec.b).get(row.b) === null) {
7348
+ violations.push({ collection: linkColl, id: rowKey, field: "b", refTo: spec.b, refId: row.b, mode: spec.onDelete ?? "cascade" });
7349
+ }
7350
+ }
7351
+ }
6859
7352
  return { violations };
6860
7353
  }
6861
7354
  /**
@@ -7126,12 +7619,12 @@ var Vault = class {
7126
7619
  if (handles.length === 0) return;
7127
7620
  const [{ GuardRegistry }, { ReadOnlyVaultFacade }] = await Promise.all([
7128
7621
  import("./registry-DKEXOJVO.js"),
7129
- import("./read-only-facade-ITU6L7BL.js")
7622
+ import("./read-only-facade-EX6WZZBP.js")
7130
7623
  ]);
7131
7624
  const registry = new GuardRegistry();
7132
7625
  for (const h of handles) registry.register(h.spec);
7133
7626
  this.guardRegistry = registry;
7134
- this.readOnlyFacade = new ReadOnlyVaultFacade(this);
7627
+ this.guardFacade = new ReadOnlyVaultFacade(this, "guard");
7135
7628
  }
7136
7629
  /**
7137
7630
  * @internal — The gate handler in Noydb.#registerGuardGate calls into
@@ -7153,8 +7646,8 @@ var Vault = class {
7153
7646
  async _initDerivations(handles) {
7154
7647
  if (handles.length === 0) return;
7155
7648
  const [{ DerivationRegistry }, { ReadOnlyVaultFacade }] = await Promise.all([
7156
- import("./registry-TGZISEWC.js"),
7157
- import("./read-only-facade-ITU6L7BL.js")
7649
+ import("./registry-DMS7OKBM.js"),
7650
+ import("./read-only-facade-EX6WZZBP.js")
7158
7651
  ]);
7159
7652
  const registry = new DerivationRegistry();
7160
7653
  for (const h of handles) {
@@ -7162,8 +7655,8 @@ var Vault = class {
7162
7655
  }
7163
7656
  registry.validate();
7164
7657
  this.derivationRegistry = registry;
7165
- if (this.readOnlyFacade === null) {
7166
- this.readOnlyFacade = new ReadOnlyVaultFacade(this);
7658
+ if (this.derivationFacade === null) {
7659
+ this.derivationFacade = new ReadOnlyVaultFacade(this, "derivation");
7167
7660
  }
7168
7661
  }
7169
7662
  /**
@@ -7184,7 +7677,7 @@ var Vault = class {
7184
7677
  */
7185
7678
  async _initMaterializedViews(handles) {
7186
7679
  if (handles.length === 0) return;
7187
- const { MaterializedViewRegistry } = await import("./registry-SECUWSGY.js");
7680
+ const { MaterializedViewRegistry } = await import("./registry-WVXO6NH5.js");
7188
7681
  const registry = new MaterializedViewRegistry();
7189
7682
  this.materializedViewRegistry = registry;
7190
7683
  const db = this;
@@ -7208,7 +7701,7 @@ var Vault = class {
7208
7701
  */
7209
7702
  async _initOverlayedViews(handles) {
7210
7703
  if (handles.length === 0) return;
7211
- const { OverlayedViewRegistry } = await import("./registry-3YFLZ7WD.js");
7704
+ const { OverlayedViewRegistry } = await import("./registry-3T2RZC5A.js");
7212
7705
  const registry = new OverlayedViewRegistry();
7213
7706
  const mvRegistry = this.materializedViewRegistry;
7214
7707
  const overlayNames = /* @__PURE__ */ new Set();
@@ -7255,13 +7748,13 @@ var Vault = class {
7255
7748
  if (!reg) {
7256
7749
  throw new Error(`refreshView: no MV registered with name "${name}"`);
7257
7750
  }
7258
- const { MaterializedViewExecutor } = await import("./executor-3W63Y44O.js");
7751
+ const { MaterializedViewExecutor } = await import("./executor-IZ2NVXCY.js");
7259
7752
  const result = await MaterializedViewExecutor.refresh(reg, {
7260
7753
  getCollection: (n) => this.collection(n),
7261
7754
  getActiveTxContext: () => this.noydb._activeTxContextOrNull,
7262
7755
  getQueryContext: () => this
7263
7756
  });
7264
- const { clearMVStale } = await import("./stale-TOA36SRK.js");
7757
+ const { clearMVStale } = await import("./stale-PGTEGJDI.js");
7265
7758
  clearMVStale(registry, name);
7266
7759
  return result;
7267
7760
  }
@@ -7277,10 +7770,10 @@ var Vault = class {
7277
7770
  if (registry === null) return { derived: 0, failed: 0 };
7278
7771
  const strategies = registry.strategiesForSource(sourceCollection);
7279
7772
  if (strategies.length === 0) return { derived: 0, failed: 0 };
7280
- const { DerivationExecutor } = await import("./executor-CFFWPWBJ.js");
7773
+ const { DerivationExecutor } = await import("./executor-WLFDUTOM.js");
7281
7774
  const sourceColl = this.collection(sourceCollection);
7282
7775
  const records = await sourceColl.list();
7283
- const ctx = { vault: this.readOnlyFacade ?? new (await import("./read-only-facade-ITU6L7BL.js")).ReadOnlyVaultFacade(this) };
7776
+ const ctx = { vault: this.derivationFacade ?? new (await import("./read-only-facade-EX6WZZBP.js")).ReadOnlyVaultFacade(this, "derivation") };
7284
7777
  let derived = 0;
7285
7778
  let failed = 0;
7286
7779
  for (const record of records) {
@@ -7302,7 +7795,7 @@ var Vault = class {
7302
7795
  if (!outSpec) continue;
7303
7796
  const outputColl = this.collection(outSpec.collection);
7304
7797
  if (out.kind === "array") {
7305
- const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-FIJJ46YG.js");
7798
+ const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-JGHXAJO5.js");
7306
7799
  const prior = await loadFanoutSidecar(this.adapter, this.name, spec.source, id, key);
7307
7800
  const prevKeys = new Set(prior?.keys ?? []);
7308
7801
  const newKeysList = out.entries.map((e) => e.key);
@@ -7345,17 +7838,18 @@ var Vault = class {
7345
7838
  * never see null).
7346
7839
  */
7347
7840
  _getReadOnlyFacade() {
7348
- return this.readOnlyFacade;
7841
+ return this.guardFacade;
7349
7842
  }
7350
7843
  /**
7351
- * Internal lazy-allocator for the read-only facade. Used as a
7352
- * defensive fallback; in practice `_initGuards()` eagerly
7353
- * instantiates this, so the lazy path is a no-op.
7844
+ * Internal lazy-allocator for the derivation read-only facade
7845
+ * (`layer:'derivation'`). Used as a defensive fallback; in practice
7846
+ * `_initDerivations()` eagerly instantiates this, so the lazy path is
7847
+ * a no-op.
7354
7848
  */
7355
7849
  _ensureReadOnlyFacade() {
7356
- if (this.readOnlyFacade !== null) return this.readOnlyFacade;
7850
+ if (this.derivationFacade !== null) return this.derivationFacade;
7357
7851
  throw new Error(
7358
- "Vault: guard hook fired before _initGuards() completed. This typically means the vault was opened via the sync fallback path (Noydb.vault(name)) without first calling await db.openVault(name). See issue #132."
7852
+ "Vault: derivation hook fired before _initDerivations() completed. This typically means the vault was opened via the sync fallback path (Noydb.vault(name)) without first calling await db.openVault(name). See issue #132."
7359
7853
  );
7360
7854
  }
7361
7855
  /**
@@ -7523,7 +8017,7 @@ var Vault = class {
7523
8017
  * collection.
7524
8018
  */
7525
8019
  async delegate(opts) {
7526
- const { issueDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-MGH5SODX.js");
8020
+ const { issueDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-FMXNUWE6.js");
7527
8021
  if (!this.keyring.kek) {
7528
8022
  throw new ValidationError(
7529
8023
  "issueDelegation: keyring.kek is null \u2014 issuing a delegation requires a tier-1 unlock. Re-authenticate at tier 1 (passphrase) first."
@@ -7545,7 +8039,7 @@ var Vault = class {
7545
8039
  * if the id does not exist.
7546
8040
  */
7547
8041
  async revokeDelegation(id) {
7548
- const { revokeDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-MGH5SODX.js");
8042
+ const { revokeDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-FMXNUWE6.js");
7549
8043
  await revokeDelegation(this.adapter, this.name, id);
7550
8044
  void DELEGATIONS_COLLECTION;
7551
8045
  }
@@ -8014,7 +8508,7 @@ var Vault = class {
8014
8508
  * @see docs/subsystems/public-envelope.md
8015
8509
  */
8016
8510
  async getPublicEnvelope(opts = {}) {
8017
- const { readPublicEnvelope: readPublicEnvelope2 } = await import("./public-envelope-RXZNP3V6.js");
8511
+ const { readPublicEnvelope: readPublicEnvelope2 } = await import("./public-envelope-HXOFHY4N.js");
8018
8512
  return readPublicEnvelope2(this.adapter, this.name, opts);
8019
8513
  }
8020
8514
  /**
@@ -9679,7 +10173,7 @@ var Noydb = class {
9679
10173
  if (!facade) return;
9680
10174
  const ctx = { existing, vault: facade, userId: e.userId, role: e.role };
9681
10175
  await registry.runChecks(e.collection, incoming, ctx);
9682
- const { GuardExecutor } = await import("./executor-VDQQOR4F.js");
10176
+ const { GuardExecutor } = await import("./executor-THSEYEJG.js");
9683
10177
  for (const g of guards) {
9684
10178
  await GuardExecutor.checkFrozenFields(g, e.docId, existing, incoming, e.computedFieldNames);
9685
10179
  }
@@ -10280,11 +10774,11 @@ var Noydb = class {
10280
10774
  if (name === STATE_VAULT_NAME) throw new ReservedVaultNameError(name);
10281
10775
  const template = this.vaultTemplates.get(opts.sharding.vaultTemplate);
10282
10776
  if (!template) throw new VaultTemplateNotFoundError(opts.sharding.vaultTemplate);
10283
- const { VaultGroup } = await import("./vault-group-DHAHFX2A.js");
10284
- const { StateManagementVault } = await import("./state-vault-W2OEABNO.js");
10777
+ const { VaultGroup } = await import("./vault-group-DPZVFRI5.js");
10778
+ const { StateManagementVault } = await import("./state-vault-QKQKN3H3.js");
10285
10779
  const stateVault = opts.registry ? void 0 : await StateManagementVault.open(this);
10286
10780
  const registry = opts.registry ?? stateVault.registry;
10287
- const group = new VaultGroup(this, name, registry, opts.sharding, template);
10781
+ const group = new VaultGroup(this, name, registry, opts.sharding, template, opts.migrateOnOpen ?? false);
10288
10782
  if (stateVault) {
10289
10783
  group._attachStateVault(stateVault);
10290
10784
  await stateVault.recordManifest(opts.sharding.vaultTemplate, template);
@@ -10308,7 +10802,7 @@ var Noydb = class {
10308
10802
  */
10309
10803
  async openStateManagementVault() {
10310
10804
  if (this.closed) throw new ValidationError("Instance is closed");
10311
- const { StateManagementVault } = await import("./state-vault-W2OEABNO.js");
10805
+ const { StateManagementVault } = await import("./state-vault-QKQKN3H3.js");
10312
10806
  return StateManagementVault.open(this);
10313
10807
  }
10314
10808
  /**
@@ -11810,6 +12304,7 @@ function normalizeSyncTargets(sync) {
11810
12304
 
11811
12305
  export {
11812
12306
  withArchive,
12307
+ compileSequenceFormat,
11813
12308
  resolveSequenceKey,
11814
12309
  SequenceStore,
11815
12310
  validateSchemaInput,
@@ -11817,10 +12312,15 @@ export {
11817
12312
  isZodSchema,
11818
12313
  derivePersistedSchema,
11819
12314
  persistSchemaIfNeeded,
12315
+ isRefArray,
11820
12316
  RefIntegrityError,
11821
12317
  RefScopeError,
11822
12318
  ref,
12319
+ refArray,
11823
12320
  RefRegistry,
12321
+ isLinkCollectionName,
12322
+ LinkEndpointError,
12323
+ LinkIntegrityError,
11824
12324
  QuickUnlockStore,
11825
12325
  UserApi,
11826
12326
  META_COLLECTION,
@@ -11849,4 +12349,4 @@ export {
11849
12349
  Noydb,
11850
12350
  createNoydb
11851
12351
  };
11852
- //# sourceMappingURL=chunk-D77ZQSQQ.js.map
12352
+ //# sourceMappingURL=chunk-F2IJ2HGD.js.map