@noy-db/hub 0.2.0-pre.2 → 0.2.0-pre.21

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 (368) hide show
  1. package/README.md +126 -0
  2. package/dist/aggregate/index.cjs +643 -37
  3. package/dist/aggregate/index.cjs.map +1 -1
  4. package/dist/aggregate/index.d.cts +3 -2
  5. package/dist/aggregate/index.d.ts +3 -2
  6. package/dist/aggregate/index.js +9 -8
  7. package/dist/aggregate/index.js.map +1 -1
  8. package/dist/attestation/index.cjs.map +1 -1
  9. package/dist/attestation/index.d.cts +7 -5
  10. package/dist/attestation/index.d.ts +7 -5
  11. package/dist/attestation/index.js +6 -6
  12. package/dist/blobs/index.cjs +509 -22
  13. package/dist/blobs/index.cjs.map +1 -1
  14. package/dist/blobs/index.d.cts +9 -7
  15. package/dist/blobs/index.d.ts +9 -7
  16. package/dist/blobs/index.js +11 -6
  17. package/dist/blobs/index.js.map +1 -1
  18. package/dist/bundle/index.cjs +7886 -841
  19. package/dist/bundle/index.cjs.map +1 -1
  20. package/dist/bundle/index.d.cts +20 -18
  21. package/dist/bundle/index.d.ts +20 -18
  22. package/dist/bundle/index.js +24 -13
  23. package/dist/bundle/index.js.map +1 -1
  24. package/dist/{chunk-PFSNOPBQ.js → chunk-2XA2ZML4.js} +31 -3
  25. package/dist/chunk-2XA2ZML4.js.map +1 -0
  26. package/dist/{chunk-2PAQNPE3.js → chunk-37VGJM3T.js} +37 -2
  27. package/dist/chunk-37VGJM3T.js.map +1 -0
  28. package/dist/{chunk-7BRE6EUA.js → chunk-3HNKR65T.js} +4 -4
  29. package/dist/chunk-3HNKR65T.js.map +1 -0
  30. package/dist/{chunk-Y2RKOPNC.js → chunk-5YTXYPES.js} +46 -10
  31. package/dist/chunk-5YTXYPES.js.map +1 -0
  32. package/dist/{chunk-OVZDFEOR.js → chunk-6QAZ5O6X.js} +2 -2
  33. package/dist/chunk-6QAZ5O6X.js.map +1 -0
  34. package/dist/{chunk-RTZVQAJ7.js → chunk-6QE4DUYC.js} +19 -4
  35. package/dist/chunk-6QE4DUYC.js.map +1 -0
  36. package/dist/{chunk-7Q5PLD5C.js → chunk-7MRT7EPB.js} +3 -3
  37. package/dist/{chunk-E535SAN4.js → chunk-7PH4OPBZ.js} +4258 -520
  38. package/dist/chunk-7PH4OPBZ.js.map +1 -0
  39. package/dist/{chunk-PEULZC6M.js → chunk-A3JMGXPG.js} +8 -1
  40. package/dist/chunk-A3JMGXPG.js.map +1 -0
  41. package/dist/{chunk-UMLVJTYV.js → chunk-ADB7GPM3.js} +7 -4
  42. package/dist/chunk-ADB7GPM3.js.map +1 -0
  43. package/dist/{chunk-G6FRSBKK.js → chunk-AI4USDRI.js} +4 -4
  44. package/dist/chunk-BZW5IL43.js +151 -0
  45. package/dist/chunk-BZW5IL43.js.map +1 -0
  46. package/dist/chunk-C2RJVZZL.js +123 -0
  47. package/dist/chunk-C2RJVZZL.js.map +1 -0
  48. package/dist/{chunk-UND4XIB6.js → chunk-C6W5KVDV.js} +52 -38
  49. package/dist/chunk-C6W5KVDV.js.map +1 -0
  50. package/dist/chunk-CQYEDODS.js +125 -0
  51. package/dist/chunk-CQYEDODS.js.map +1 -0
  52. package/dist/{chunk-NWZ3I6R6.js → chunk-EYK72OTL.js} +5 -5
  53. package/dist/{chunk-7BUTTVMR.js → chunk-F5GWNSE2.js} +2 -2
  54. package/dist/{chunk-AHPFONIL.js → chunk-F5ILTHMU.js} +5 -5
  55. package/dist/{chunk-Q6W2CMEJ.js → chunk-FRRJIUSI.js} +18 -5
  56. package/dist/chunk-FRRJIUSI.js.map +1 -0
  57. package/dist/{chunk-YMYK7US4.js → chunk-GJTKMME7.js} +2 -2
  58. package/dist/chunk-GJTKMME7.js.map +1 -0
  59. package/dist/{chunk-EUYOGYGV.js → chunk-HYJMAV53.js} +6 -6
  60. package/dist/chunk-HYJMAV53.js.map +1 -0
  61. package/dist/{chunk-QPEXPHJR.js → chunk-I3IYTUUI.js} +4 -4
  62. package/dist/{chunk-3QAKZ37R.js → chunk-IVZWHIEK.js} +5 -5
  63. package/dist/{chunk-PLI5TV7N.js → chunk-IW4L4X65.js} +2 -2
  64. package/dist/chunk-IW4L4X65.js.map +1 -0
  65. package/dist/{chunk-3Z2TPHC4.js → chunk-IY24WS2P.js} +69 -5
  66. package/dist/chunk-IY24WS2P.js.map +1 -0
  67. package/dist/{chunk-HXJXPZRE.js → chunk-J6RGRZOY.js} +10 -3
  68. package/dist/chunk-J6RGRZOY.js.map +1 -0
  69. package/dist/{chunk-3S4BJX25.js → chunk-JBBWALNI.js} +2 -2
  70. package/dist/chunk-JBBWALNI.js.map +1 -0
  71. package/dist/{chunk-7Z23ZFLV.js → chunk-JDCPRJVS.js} +5 -5
  72. package/dist/chunk-JDCPRJVS.js.map +1 -0
  73. package/dist/{chunk-243PNUA6.js → chunk-JOK73NDT.js} +3 -3
  74. package/dist/chunk-JTI57WRT.js +164 -0
  75. package/dist/chunk-JTI57WRT.js.map +1 -0
  76. package/dist/{chunk-VRBCTEKQ.js → chunk-JYNH4FIM.js} +233 -11
  77. package/dist/chunk-JYNH4FIM.js.map +1 -0
  78. package/dist/{chunk-TBKOGSYR.js → chunk-KOAJ3TZM.js} +27 -5
  79. package/dist/chunk-KOAJ3TZM.js.map +1 -0
  80. package/dist/{chunk-YTXSFG3C.js → chunk-MBXKRHSS.js} +50 -20
  81. package/dist/chunk-MBXKRHSS.js.map +1 -0
  82. package/dist/{chunk-MUWOSVEP.js → chunk-NSXNXLYM.js} +10 -2
  83. package/dist/chunk-NSXNXLYM.js.map +1 -0
  84. package/dist/{chunk-J4KLMEUL.js → chunk-NV4IHBZS.js} +664 -51
  85. package/dist/chunk-NV4IHBZS.js.map +1 -0
  86. package/dist/{chunk-LRAZDV5X.js → chunk-O5XKZCUD.js} +31 -8
  87. package/dist/chunk-O5XKZCUD.js.map +1 -0
  88. package/dist/{chunk-W3XXT26A.js → chunk-OTWT6BAJ.js} +358 -3
  89. package/dist/chunk-OTWT6BAJ.js.map +1 -0
  90. package/dist/{chunk-XG3PTSCD.js → chunk-PDVP3C2I.js} +1 -1
  91. package/dist/chunk-PDVP3C2I.js.map +1 -0
  92. package/dist/{chunk-GIV6DWBG.js → chunk-S45MDEEF.js} +44 -5
  93. package/dist/chunk-S45MDEEF.js.map +1 -0
  94. package/dist/{chunk-VK5EER6C.js → chunk-SQKAECUL.js} +2 -2
  95. package/dist/{chunk-FAQVNJD4.js → chunk-SQOK5UM6.js} +12 -2
  96. package/dist/{chunk-FAQVNJD4.js.map → chunk-SQOK5UM6.js.map} +1 -1
  97. package/dist/chunk-STNPB3UM.js +9 -0
  98. package/dist/chunk-STNPB3UM.js.map +1 -0
  99. package/dist/{chunk-YS3POABP.js → chunk-TA6HPKWQ.js} +1 -1
  100. package/dist/chunk-TA6HPKWQ.js.map +1 -0
  101. package/dist/{chunk-4HIL6AHQ.js → chunk-TAMRU7A2.js} +4 -4
  102. package/dist/{chunk-QXQRKXCU.js → chunk-TGIJTNM3.js} +2 -2
  103. package/dist/chunk-TNH5SLCD.js +361 -0
  104. package/dist/chunk-TNH5SLCD.js.map +1 -0
  105. package/dist/{chunk-VPSUZLOJ.js → chunk-TYMDCIQM.js} +31 -5
  106. package/dist/chunk-TYMDCIQM.js.map +1 -0
  107. package/dist/chunk-U2XSUCDF.js +524 -0
  108. package/dist/chunk-U2XSUCDF.js.map +1 -0
  109. package/dist/{chunk-3Y53S2SA.js → chunk-UU6M64HI.js} +4 -4
  110. package/dist/{chunk-VCGTOS2A.js → chunk-WE2BUQD2.js} +3 -3
  111. package/dist/chunk-WE2BUQD2.js.map +1 -0
  112. package/dist/{chunk-JYQTXEIO.js → chunk-WWVJXBOT.js} +449 -29
  113. package/dist/chunk-WWVJXBOT.js.map +1 -0
  114. package/dist/chunk-YPIOFSN3.js +129 -0
  115. package/dist/chunk-YPIOFSN3.js.map +1 -0
  116. package/dist/chunk-ZC7J6ZYV.js +7 -0
  117. package/dist/chunk-ZC7J6ZYV.js.map +1 -0
  118. package/dist/{chunk-5ZGZ6HIZ.js → chunk-ZONKSLF2.js} +30 -7
  119. package/dist/chunk-ZONKSLF2.js.map +1 -0
  120. package/dist/consent/index.cjs.map +1 -1
  121. package/dist/consent/index.d.cts +8 -6
  122. package/dist/consent/index.d.ts +8 -6
  123. package/dist/consent/index.js +3 -3
  124. package/dist/{crypto-5ZDIY3NG.js → crypto-456N7UVX.js} +7 -3
  125. package/dist/{delegation-QYXZW25W.js → delegation-DP4COTXB.js} +5 -5
  126. package/dist/derivations/index.cjs +124 -6
  127. package/dist/derivations/index.cjs.map +1 -1
  128. package/dist/derivations/index.d.cts +11 -9
  129. package/dist/derivations/index.d.ts +11 -9
  130. package/dist/derivations/index.js +8 -6
  131. package/dist/{dev-unlock-DQCNDfFp.d.cts → dev-unlock-CY0HIZA0.d.cts} +1 -1
  132. package/dist/{dev-unlock-utkybTKb.d.ts → dev-unlock-CpKSkl2c.d.ts} +1 -1
  133. package/dist/discriminant-BN9REW3o.d.cts +60 -0
  134. package/dist/discriminant-BN9REW3o.d.ts +60 -0
  135. package/dist/errors-Dkc_fi-S.d.cts +1467 -0
  136. package/dist/errors-Dkc_fi-S.d.ts +1467 -0
  137. package/dist/executor-4IEW4KG5.js +8 -0
  138. package/dist/executor-KYJCJCIN.js +12 -0
  139. package/dist/executor-W7VIBOBZ.js +8 -0
  140. package/dist/{fanout-sidecar-VJ52RIEY.js → fanout-sidecar-YXNAEZ33.js} +2 -2
  141. package/dist/fanout-sidecar-YXNAEZ33.js.map +1 -0
  142. package/dist/forget/index.cjs +43 -0
  143. package/dist/forget/index.cjs.map +1 -0
  144. package/dist/forget/index.d.cts +1 -0
  145. package/dist/forget/index.d.ts +1 -0
  146. package/dist/forget/index.js +14 -0
  147. package/dist/guards/index.cjs +144 -4
  148. package/dist/guards/index.cjs.map +1 -1
  149. package/dist/guards/index.d.cts +16 -8
  150. package/dist/guards/index.d.ts +16 -8
  151. package/dist/guards/index.js +13 -7
  152. package/dist/{hash-jDowCrK2.d.cts → hash-BSd0-_L8.d.cts} +1 -1
  153. package/dist/{hash-DcoYWfJ_.d.ts → hash-BnBQx39y.d.ts} +1 -1
  154. package/dist/history/index.cjs +28 -5
  155. package/dist/history/index.cjs.map +1 -1
  156. package/dist/history/index.d.cts +9 -7
  157. package/dist/history/index.d.ts +9 -7
  158. package/dist/history/index.js +9 -7
  159. package/dist/history/index.js.map +1 -1
  160. package/dist/i18n/index.cjs +356 -26
  161. package/dist/i18n/index.cjs.map +1 -1
  162. package/dist/i18n/index.d.cts +8 -6
  163. package/dist/i18n/index.d.ts +8 -6
  164. package/dist/i18n/index.js +36 -15
  165. package/dist/i18n/index.js.map +1 -1
  166. package/dist/index-BMmajblo.d.cts +362 -0
  167. package/dist/index-BMmajblo.d.ts +362 -0
  168. package/dist/{index-BCKdioeh.d.ts → index-Bm9hIY7t.d.ts} +169 -1127
  169. package/dist/{index-BMjrzNZr.d.cts → index-tZqVB9g5.d.cts} +169 -1127
  170. package/dist/index.cjs +10286 -2168
  171. package/dist/index.cjs.map +1 -1
  172. package/dist/index.d.cts +258 -23
  173. package/dist/index.d.ts +258 -23
  174. package/dist/index.js +443 -110
  175. package/dist/index.js.map +1 -1
  176. package/dist/indexing/index.cjs +97 -32
  177. package/dist/indexing/index.cjs.map +1 -1
  178. package/dist/indexing/index.d.cts +3 -3
  179. package/dist/indexing/index.d.ts +3 -3
  180. package/dist/indexing/index.js +4 -4
  181. package/dist/issue-JXC6T2QR.js +12 -0
  182. package/dist/{lazy-builder-Rpd-V3jP.d.ts → lazy-builder-ChSqcF5t.d.ts} +2 -2
  183. package/dist/{lazy-builder-C-rPfWG0.d.cts → lazy-builder-eYZzLEL1.d.cts} +2 -2
  184. package/dist/{ledger-3IU5GMXA.js → ledger-I7JUYP4L.js} +6 -6
  185. package/dist/materialized-views/index.cjs +687 -13
  186. package/dist/materialized-views/index.cjs.map +1 -1
  187. package/dist/materialized-views/index.d.cts +23 -20
  188. package/dist/materialized-views/index.d.ts +23 -20
  189. package/dist/materialized-views/index.js +8 -7
  190. package/dist/mime-magic-BnJCGJzB.d.cts +103 -0
  191. package/dist/mime-magic-CjSyakO4.d.ts +103 -0
  192. package/dist/noydb-ZZCRF6TE.js +38 -0
  193. package/dist/overlay-views/index.cjs +58 -18
  194. package/dist/overlay-views/index.cjs.map +1 -1
  195. package/dist/overlay-views/index.d.cts +32 -12
  196. package/dist/overlay-views/index.d.ts +32 -12
  197. package/dist/overlay-views/index.js +6 -6
  198. package/dist/periods/index.cjs.map +1 -1
  199. package/dist/periods/index.d.cts +8 -6
  200. package/dist/periods/index.d.ts +8 -6
  201. package/dist/periods/index.js +6 -6
  202. package/dist/{predicate-Dnu81tsS.d.cts → predicate-BmhBSPCH.d.cts} +87 -5
  203. package/dist/{predicate-Dnu81tsS.d.ts → predicate-BmhBSPCH.d.ts} +87 -5
  204. package/dist/{public-envelope-U3CMEOMV.js → public-envelope-5XRTUNKF.js} +4 -4
  205. package/dist/query/index.cjs +1438 -130
  206. package/dist/query/index.cjs.map +1 -1
  207. package/dist/query/index.d.cts +4 -3
  208. package/dist/query/index.d.ts +4 -3
  209. package/dist/query/index.js +13 -6
  210. package/dist/read-only-facade-EX6WZZBP.js +7 -0
  211. package/dist/registry-ATRHOG5B.js +8 -0
  212. package/dist/registry-DKEXOJVO.js +7 -0
  213. package/dist/registry-LEHB26TY.js +8 -0
  214. package/dist/{registry-3ALP62P6.js → registry-NWHOLD5M.js} +3 -3
  215. package/dist/{revoke-KY2GB4KP.js → revoke-5IEK22KT.js} +6 -6
  216. package/dist/sealed-record/index.cjs +139 -0
  217. package/dist/sealed-record/index.cjs.map +1 -0
  218. package/dist/sealed-record/index.d.cts +123 -0
  219. package/dist/sealed-record/index.d.ts +123 -0
  220. package/dist/sealed-record/index.js +42 -0
  221. package/dist/sealed-record/index.js.map +1 -0
  222. package/dist/session/index.cjs.map +1 -1
  223. package/dist/session/index.d.cts +9 -7
  224. package/dist/session/index.d.ts +9 -7
  225. package/dist/session/index.js +3 -3
  226. package/dist/shadow/index.cjs.map +1 -1
  227. package/dist/shadow/index.d.cts +8 -6
  228. package/dist/shadow/index.d.ts +8 -6
  229. package/dist/shadow/index.js +2 -2
  230. package/dist/{signer-GRI5TZKH.js → signer-I6YARZQA.js} +5 -5
  231. package/dist/snapshots/index.cjs +937 -0
  232. package/dist/snapshots/index.cjs.map +1 -0
  233. package/dist/snapshots/index.d.cts +30 -0
  234. package/dist/snapshots/index.d.ts +30 -0
  235. package/dist/snapshots/index.js +152 -0
  236. package/dist/snapshots/index.js.map +1 -0
  237. package/dist/{stale-OTOF3FH7.js → stale-CPESGAPL.js} +2 -2
  238. package/dist/stale-CPESGAPL.js.map +1 -0
  239. package/dist/state-vault-JR3CFGNP.js +14 -0
  240. package/dist/state-vault-JR3CFGNP.js.map +1 -0
  241. package/dist/store/index.cjs +8 -0
  242. package/dist/store/index.cjs.map +1 -1
  243. package/dist/store/index.d.cts +15 -6
  244. package/dist/store/index.d.ts +15 -6
  245. package/dist/store/index.js +2 -2
  246. package/dist/{strategy-DSTrsZ8t.d.ts → strategy-54eIwox5.d.ts} +456 -7
  247. package/dist/{strategy-DSTrsZ8t.d.cts → strategy-WtB-jXYv.d.cts} +456 -7
  248. package/dist/sync/index.cjs.map +1 -1
  249. package/dist/sync/index.d.cts +7 -5
  250. package/dist/sync/index.d.ts +7 -5
  251. package/dist/sync/index.js +4 -4
  252. package/dist/team/index.cjs +1 -1
  253. package/dist/team/index.cjs.map +1 -1
  254. package/dist/team/index.d.cts +8 -6
  255. package/dist/team/index.d.ts +8 -6
  256. package/dist/team/index.js +8 -8
  257. package/dist/transition-guard-D4bfIAiW.d.ts +165 -0
  258. package/dist/transition-guard-Dmpqzg-_.d.cts +165 -0
  259. package/dist/tx/index.cjs +155 -5
  260. package/dist/tx/index.cjs.map +1 -1
  261. package/dist/tx/index.d.cts +27 -9
  262. package/dist/tx/index.d.ts +27 -9
  263. package/dist/tx/index.js +61 -4
  264. package/dist/tx/index.js.map +1 -1
  265. package/dist/{types-BoFFiskX.d.ts → types-DLfWFr6U.d.ts} +3997 -1262
  266. package/dist/{types-DJG8HG6F.d.cts → types-DyOI6XZ_.d.cts} +3997 -1262
  267. package/dist/{ulid-BmBgooGm.d.ts → ulid-B2L_aqVA.d.ts} +19 -19
  268. package/dist/{ulid-C7ms9oli.d.cts → ulid-LaxfH2tK.d.cts} +19 -19
  269. package/dist/util/index.cjs +7 -0
  270. package/dist/util/index.cjs.map +1 -1
  271. package/dist/util/index.d.cts +2 -0
  272. package/dist/util/index.d.ts +2 -0
  273. package/dist/util/index.js +5 -1
  274. package/dist/util/index.js.map +1 -1
  275. package/dist/vault-group-BB246VIM.js +804 -0
  276. package/dist/vault-group-BB246VIM.js.map +1 -0
  277. package/dist/{with-materialized-view-CqnRwI2S.d.ts → with-materialized-view-CeZYGJVf.d.cts} +2 -2
  278. package/dist/{with-materialized-view-BbEPFIIJ.d.cts → with-materialized-view-DNULSxoP.d.ts} +2 -2
  279. package/dist/{with-overlayed-view-Ct1fSJt-.d.ts → with-overlayed-view-C9joG7UZ.d.ts} +2 -2
  280. package/dist/{with-overlayed-view-bwlmmFjx.d.cts → with-overlayed-view-kdcPGHih.d.cts} +2 -2
  281. package/dist/with-rollup-DJDbrxjf.d.ts +47 -0
  282. package/dist/with-rollup-s58XAeWO.d.cts +47 -0
  283. package/package.json +35 -4
  284. package/dist/chunk-2PAQNPE3.js.map +0 -1
  285. package/dist/chunk-3S4BJX25.js.map +0 -1
  286. package/dist/chunk-3XHOCQK4.js +0 -118
  287. package/dist/chunk-3XHOCQK4.js.map +0 -1
  288. package/dist/chunk-3Z2TPHC4.js.map +0 -1
  289. package/dist/chunk-5ZGZ6HIZ.js.map +0 -1
  290. package/dist/chunk-7BRE6EUA.js.map +0 -1
  291. package/dist/chunk-7Z23ZFLV.js.map +0 -1
  292. package/dist/chunk-CXSCDO5T.js +0 -51
  293. package/dist/chunk-CXSCDO5T.js.map +0 -1
  294. package/dist/chunk-E535SAN4.js.map +0 -1
  295. package/dist/chunk-EUYOGYGV.js.map +0 -1
  296. package/dist/chunk-GIV6DWBG.js.map +0 -1
  297. package/dist/chunk-HXJXPZRE.js.map +0 -1
  298. package/dist/chunk-J4KLMEUL.js.map +0 -1
  299. package/dist/chunk-JYQTXEIO.js.map +0 -1
  300. package/dist/chunk-LRAZDV5X.js.map +0 -1
  301. package/dist/chunk-MRIBLZL3.js +0 -86
  302. package/dist/chunk-MRIBLZL3.js.map +0 -1
  303. package/dist/chunk-MUWOSVEP.js.map +0 -1
  304. package/dist/chunk-OVZDFEOR.js.map +0 -1
  305. package/dist/chunk-PEULZC6M.js.map +0 -1
  306. package/dist/chunk-PFSNOPBQ.js.map +0 -1
  307. package/dist/chunk-PLI5TV7N.js.map +0 -1
  308. package/dist/chunk-Q6W2CMEJ.js.map +0 -1
  309. package/dist/chunk-RTZVQAJ7.js.map +0 -1
  310. package/dist/chunk-TBKOGSYR.js.map +0 -1
  311. package/dist/chunk-UMLVJTYV.js.map +0 -1
  312. package/dist/chunk-UND4XIB6.js.map +0 -1
  313. package/dist/chunk-VCGTOS2A.js.map +0 -1
  314. package/dist/chunk-VE6YVP32.js +0 -19
  315. package/dist/chunk-VE6YVP32.js.map +0 -1
  316. package/dist/chunk-VPSUZLOJ.js.map +0 -1
  317. package/dist/chunk-VRBCTEKQ.js.map +0 -1
  318. package/dist/chunk-W3XXT26A.js.map +0 -1
  319. package/dist/chunk-XG3PTSCD.js.map +0 -1
  320. package/dist/chunk-Y2RKOPNC.js.map +0 -1
  321. package/dist/chunk-YMYK7US4.js.map +0 -1
  322. package/dist/chunk-YS3POABP.js.map +0 -1
  323. package/dist/chunk-YTXSFG3C.js.map +0 -1
  324. package/dist/executor-AS2IDHKZ.js +0 -11
  325. package/dist/executor-HLXFXNFM.js +0 -8
  326. package/dist/executor-HN6YBHZ5.js +0 -8
  327. package/dist/fanout-sidecar-VJ52RIEY.js.map +0 -1
  328. package/dist/issue-ORP37MVW.js +0 -12
  329. package/dist/mime-magic-CBBSOkjm.d.cts +0 -50
  330. package/dist/mime-magic-CBBSOkjm.d.ts +0 -50
  331. package/dist/noydb-5H3C24GG.js +0 -34
  332. package/dist/read-only-facade-ITU6L7BL.js +0 -7
  333. package/dist/registry-7HE6VJGC.js +0 -8
  334. package/dist/registry-PSIPG2QR.js +0 -8
  335. package/dist/registry-RFGGMVNJ.js +0 -7
  336. package/dist/with-derivation-BKXXa8Vt.d.ts +0 -13
  337. package/dist/with-derivation-BjQ7q4NE.d.cts +0 -13
  338. package/dist/with-guard-C25yNjzd.d.ts +0 -18
  339. package/dist/with-guard-DQme5DKE.d.cts +0 -18
  340. /package/dist/{chunk-7Q5PLD5C.js.map → chunk-7MRT7EPB.js.map} +0 -0
  341. /package/dist/{chunk-G6FRSBKK.js.map → chunk-AI4USDRI.js.map} +0 -0
  342. /package/dist/{chunk-NWZ3I6R6.js.map → chunk-EYK72OTL.js.map} +0 -0
  343. /package/dist/{chunk-7BUTTVMR.js.map → chunk-F5GWNSE2.js.map} +0 -0
  344. /package/dist/{chunk-AHPFONIL.js.map → chunk-F5ILTHMU.js.map} +0 -0
  345. /package/dist/{chunk-QPEXPHJR.js.map → chunk-I3IYTUUI.js.map} +0 -0
  346. /package/dist/{chunk-3QAKZ37R.js.map → chunk-IVZWHIEK.js.map} +0 -0
  347. /package/dist/{chunk-243PNUA6.js.map → chunk-JOK73NDT.js.map} +0 -0
  348. /package/dist/{chunk-VK5EER6C.js.map → chunk-SQKAECUL.js.map} +0 -0
  349. /package/dist/{chunk-4HIL6AHQ.js.map → chunk-TAMRU7A2.js.map} +0 -0
  350. /package/dist/{chunk-QXQRKXCU.js.map → chunk-TGIJTNM3.js.map} +0 -0
  351. /package/dist/{chunk-3Y53S2SA.js.map → chunk-UU6M64HI.js.map} +0 -0
  352. /package/dist/{crypto-5ZDIY3NG.js.map → crypto-456N7UVX.js.map} +0 -0
  353. /package/dist/{delegation-QYXZW25W.js.map → delegation-DP4COTXB.js.map} +0 -0
  354. /package/dist/{executor-AS2IDHKZ.js.map → executor-4IEW4KG5.js.map} +0 -0
  355. /package/dist/{executor-HLXFXNFM.js.map → executor-KYJCJCIN.js.map} +0 -0
  356. /package/dist/{executor-HN6YBHZ5.js.map → executor-W7VIBOBZ.js.map} +0 -0
  357. /package/dist/{issue-ORP37MVW.js.map → forget/index.js.map} +0 -0
  358. /package/dist/{ledger-3IU5GMXA.js.map → issue-JXC6T2QR.js.map} +0 -0
  359. /package/dist/{noydb-5H3C24GG.js.map → ledger-I7JUYP4L.js.map} +0 -0
  360. /package/dist/{public-envelope-U3CMEOMV.js.map → noydb-ZZCRF6TE.js.map} +0 -0
  361. /package/dist/{read-only-facade-ITU6L7BL.js.map → public-envelope-5XRTUNKF.js.map} +0 -0
  362. /package/dist/{registry-3ALP62P6.js.map → read-only-facade-EX6WZZBP.js.map} +0 -0
  363. /package/dist/{registry-7HE6VJGC.js.map → registry-ATRHOG5B.js.map} +0 -0
  364. /package/dist/{registry-PSIPG2QR.js.map → registry-DKEXOJVO.js.map} +0 -0
  365. /package/dist/{registry-RFGGMVNJ.js.map → registry-LEHB26TY.js.map} +0 -0
  366. /package/dist/{revoke-KY2GB4KP.js.map → registry-NWHOLD5M.js.map} +0 -0
  367. /package/dist/{signer-GRI5TZKH.js.map → revoke-5IEK22KT.js.map} +0 -0
  368. /package/dist/{stale-OTOF3FH7.js.map → signer-I6YARZQA.js.map} +0 -0
@@ -1,1118 +1,6 @@
1
- import { C as CollectionIndexes, a as Clause, O as Operator } from './predicate-Dnu81tsS.js';
2
- import { A as AggregateStrategy, b as AggregateSpec, c as Aggregation, a as AggregateResult, g as GroupedQuery, h as GroupedQueryN } from './strategy-DSTrsZ8t.js';
3
-
4
- /**
5
- * All NOYDB error classes — a single import surface for `catch` blocks and
6
- * `instanceof` checks.
7
- *
8
- * ## Class hierarchy
9
- *
10
- * ```
11
- * Error
12
- * └─ NoydbError (code: string)
13
- * ├─ Crypto errors
14
- * │ ├─ DecryptionError — AES-GCM tag failure
15
- * │ ├─ TamperedError — ciphertext modified after write
16
- * │ └─ InvalidKeyError — wrong passphrase / corrupt keyring
17
- * ├─ Access errors
18
- * │ ├─ NoAccessError — no DEK for this collection
19
- * │ ├─ ReadOnlyError — ro permission, write attempted
20
- * │ ├─ PermissionDeniedError — role too low for operation
21
- * │ ├─ PrivilegeEscalationError — grant wider than grantor holds
22
- * │ └─ StoreCapabilityError — optional store method missing
23
- * ├─ Sync errors
24
- * │ ├─ ConflictError — optimistic-lock version mismatch
25
- * │ ├─ BundleVersionConflictError — bundle push rejected by remote
26
- * │ └─ NetworkError — push/pull network failure
27
- * ├─ Data errors
28
- * │ ├─ NotFoundError — get(id) on missing record
29
- * │ ├─ ValidationError — application-level guard failed
30
- * │ └─ SchemaValidationError — Standard Schema v1 rejection
31
- * ├─ Query errors
32
- * │ ├─ JoinTooLargeError — join row ceiling exceeded
33
- * │ ├─ DanglingReferenceError — strict ref() points at nothing
34
- * │ ├─ GroupCardinalityError — groupBy bucket cap exceeded
35
- * │ ├─ IndexRequiredError — lazy-mode query touches unindexed field
36
- * │ └─ IndexWriteFailureError — index side-car put/delete failed post-main
37
- * ├─ i18n / Dictionary errors
38
- * │ ├─ ReservedCollectionNameError
39
- * │ ├─ DictKeyMissingError
40
- * │ ├─ DictKeyInUseError
41
- * │ ├─ MissingTranslationError
42
- * │ ├─ LocaleNotSpecifiedError
43
- * │ └─ TranslatorNotConfiguredError
44
- * ├─ Backup errors
45
- * │ ├─ BackupLedgerError — hash-chain verification failed
46
- * │ └─ BackupCorruptedError — envelope hash mismatch in dump
47
- * ├─ Bundle errors
48
- * │ └─ BundleIntegrityError — .noydb body sha256 mismatch
49
- * └─ Session errors
50
- * ├─ SessionExpiredError
51
- * ├─ SessionNotFoundError
52
- * └─ SessionPolicyError
53
- * ```
54
- *
55
- * ## Catching all NOYDB errors
56
- *
57
- * ```ts
58
- * import { NoydbError, InvalidKeyError, ConflictError } from '@noy-db/hub'
59
- *
60
- * try {
61
- * await vault.unlock(passphrase)
62
- * } catch (e) {
63
- * if (e instanceof InvalidKeyError) { showBadPassphraseUI(); return }
64
- * if (e instanceof NoydbError) { logToSentry(e.code, e); return }
65
- * throw e // unexpected — re-throw
66
- * }
67
- * ```
68
- *
69
- * @module
70
- */
71
- /**
72
- * Base class for all NOYDB errors.
73
- *
74
- * Every error thrown by `@noy-db/hub` extends this class, so consumers can
75
- * catch all NOYDB errors in a single `catch (e) { if (e instanceof NoydbError) ... }`
76
- * block. The `code` field is a machine-readable string (e.g. `'DECRYPTION_FAILED'`)
77
- * suitable for `switch` statements and logging pipelines.
78
- */
79
- declare class NoydbError extends Error {
80
- /** Machine-readable error code. Stable across library versions. */
81
- readonly code: string;
82
- constructor(code: string, message: string);
83
- }
84
- /**
85
- * Thrown when AES-GCM decryption fails.
86
- *
87
- * The most common cause is a wrong passphrase or a corrupted ciphertext.
88
- * A `DecryptionError` at the wrong passphrase level is caught internally
89
- * and re-thrown as `InvalidKeyError` — so in practice this surfaces for
90
- * per-record corruption rather than authentication failures.
91
- */
92
- declare class DecryptionError extends NoydbError {
93
- constructor(message?: string);
94
- }
95
- /**
96
- * Thrown when GCM tag verification fails, indicating the ciphertext was
97
- * modified after encryption.
98
- *
99
- * AES-256-GCM is authenticated encryption — the tag over the ciphertext
100
- * is checked on every decrypt. If any byte was flipped (accidental
101
- * corruption or deliberate tampering), decryption throws this error.
102
- * Treat it as a security alert: the stored bytes are not what NOYDB wrote.
103
- */
104
- declare class TamperedError extends NoydbError {
105
- constructor(message?: string);
106
- }
107
- /**
108
- * Thrown when key unwrapping fails, typically because the passphrase is wrong
109
- * or the keyring file is corrupted.
110
- *
111
- * NOYDB uses AES-KW (RFC 3394) to wrap DEKs with the KEK. If AES-KW
112
- * unwrapping fails, it means either the KEK was derived from the wrong
113
- * passphrase (PBKDF2 with 600K iterations) or the keyring bytes are
114
- * corrupted. This is the error shown to the user on a failed unlock attempt.
115
- */
116
- declare class InvalidKeyError extends NoydbError {
117
- constructor(message?: string);
118
- }
119
- /**
120
- * Thrown when a keyring's wrapped-DEK set unwraps partially — at least
121
- * one DEK succeeds (proving the KEK is correct) but at least one fails.
122
- * The passphrase is right; the failed entries are corrupted.
123
- *
124
- * This is distinct from {@link InvalidKeyError} so that
125
- * `NoydbOptions.onInvalidKey: 'reset'` does NOT fire — resetting on
126
- * partial corruption would destroy the still-valid DEKs and the data
127
- * they protect, which is silent data loss in response to a feature
128
- * designed for stale-credential recovery.
129
- */
130
- declare class KeyringCorruptError extends NoydbError {
131
- readonly failedCollections: readonly string[];
132
- readonly intactCount: number;
133
- constructor(opts: {
134
- failedCollections: readonly string[];
135
- intactCount: number;
136
- message?: string;
137
- });
138
- }
139
- /**
140
- * Thrown when the authenticated user does not have a DEK for the requested
141
- * collection — i.e. the collection is not in their keyring at all.
142
- *
143
- * This is the "no key for this door" error. It is different from
144
- * `ReadOnlyError` (user has a key but it only grants ro) and from
145
- * `PermissionDeniedError` (user's role doesn't allow the operation).
146
- */
147
- declare class NoAccessError extends NoydbError {
148
- constructor(message?: string);
149
- }
150
- /**
151
- * Thrown when a user with read-only (`ro`) permission attempts a write
152
- * operation (`put` or `delete`) on a collection.
153
- *
154
- * The user has a DEK for the collection (they can decrypt and read), but
155
- * their keyring grants only `ro`. To fix: re-grant the user with `rw`
156
- * permission, or do not attempt writes as a viewer/client role.
157
- */
158
- declare class ReadOnlyError extends NoydbError {
159
- constructor(message?: string);
160
- }
161
- /**
162
- * Thrown when a write is attempted against a historical view produced
163
- * by `vault.at(timestamp)`. Time-machine views are read-only by
164
- * contract — mutating the past would require either the shadow-vault
165
- * mechanism or a ledger-history rewrite (which breaks
166
- * the tamper-evidence guarantee).
167
- *
168
- * Distinct from {@link ReadOnlyError} (keyring-level) and
169
- * {@link PermissionDeniedError} (role-level): this error is about the
170
- * *view* being historical, independent of the caller's permissions.
171
- */
172
- declare class ReadOnlyAtInstantError extends NoydbError {
173
- constructor(operation: string, timestamp: string);
174
- }
175
- /**
176
- * Thrown when a write is attempted against a shadow-vault frame
177
- * produced by `vault.frame()`. Frames are read-only by contract —
178
- * the use case is screen-sharing / demos / compliance review where
179
- * the operator wants to prevent accidental edits.
180
- *
181
- * Behavioural enforcement only — the underlying keyring still holds
182
- * write-capable DEKs. See {@link VaultFrame} for the full caveat.
183
- */
184
- declare class ReadOnlyFrameError extends NoydbError {
185
- constructor(operation: string);
186
- }
187
- /**
188
- * Thrown when the authenticated user's role does not permit the requested
189
- * operation — e.g. a `viewer` calling `grantAccess()`, or an `operator`
190
- * calling `rotateKeys()`.
191
- *
192
- * This is a role-level check (what the user's role allows), distinct from
193
- * `NoAccessError` (collection not in keyring) and `ReadOnlyError` (in
194
- * keyring, but write not allowed).
195
- */
196
- declare class PermissionDeniedError extends NoydbError {
197
- constructor(message?: string);
198
- }
199
- /**
200
- * Thrown when an `@noy-db/as-*` export is attempted without the
201
- * required capability bit on the invoking keyring.
202
- *
203
- * Two sub-cases discriminated by the `tier` field:
204
- *
205
- * - `tier: 'plaintext'` — a plaintext-tier export (`as-xlsx`,
206
- * `as-csv`, `as-blob`, `as-zip`, …) was attempted but the
207
- * keyring's `exportCapability.plaintext` does not include the
208
- * requested `format` (nor the `'*'` wildcard). Default for every
209
- * role is `plaintext: []` — the owner must positively grant.
210
- * - `tier: 'bundle'` — an encrypted `as-noydb` bundle export was
211
- * attempted but the keyring's `exportCapability.bundle` is
212
- * `false`. Default for `owner`/`admin` is `true`; for
213
- * `operator`/`viewer`/`client` it is `false`.
214
- *
215
- * Distinct from `PermissionDeniedError` (role-level check) and
216
- * `NoAccessError` (collection not readable). Surfaces separately so
217
- * UI layers can show a "request the export capability from your
218
- * admin" flow rather than a generic permission error.
219
- */
220
- declare class ExportCapabilityError extends NoydbError {
221
- readonly tier: 'plaintext' | 'bundle';
222
- readonly format?: string;
223
- readonly userId: string;
224
- constructor(opts: {
225
- tier: 'plaintext' | 'bundle';
226
- userId: string;
227
- format?: string;
228
- message?: string;
229
- });
230
- }
231
- /**
232
- * Thrown when a keyring file's `expires_at` cutoff has passed.
233
- * Surfaced by `loadKeyring` before any DEK unwrap is attempted —
234
- * past the cutoff the slot refuses to open even with the right
235
- * passphrase. Distinct from PBKDF2 / unwrap errors so consumer code
236
- * can show a precise "this bundle slot has expired" message instead
237
- * of the generic decryption-failure UX.
238
- *
239
- * Used predominantly on `BundleRecipient` slots produced by
240
- * `writeNoydbBundle({ recipients: [...] })` to time-box audit access.
241
- */
242
- declare class KeyringExpiredError extends NoydbError {
243
- readonly userId: string;
244
- readonly expiresAt: string;
245
- constructor(opts: {
246
- userId: string;
247
- expiresAt: string;
248
- });
249
- }
250
- /**
251
- * Thrown when an `@noy-db/as-*` import is attempted but the invoking
252
- * keyring lacks the required import-capability bit.
253
- *
254
- * - `tier: 'plaintext'` — a plaintext-tier import (`as-csv`, `as-json`,
255
- * `as-ndjson`, `as-zip`, …) was attempted but the keyring's
256
- * `importCapability.plaintext` does not include the requested
257
- * `format` (nor the `'*'` wildcard).
258
- * - `tier: 'bundle'` — a `.noydb` bundle import was attempted but the
259
- * keyring's `importCapability.bundle` is not `true`.
260
- *
261
- * Default for every role on every dimension is closed — owners and
262
- * admins must positively grant the capability. Distinct from
263
- * `PermissionDeniedError` and `NoAccessError` so UI layers can show a
264
- * specific "request the import capability" flow.
265
- */
266
- declare class ImportCapabilityError extends NoydbError {
267
- readonly tier: 'plaintext' | 'bundle';
268
- readonly format?: string;
269
- readonly userId: string;
270
- constructor(opts: {
271
- tier: 'plaintext' | 'bundle';
272
- userId: string;
273
- format?: string;
274
- message?: string;
275
- });
276
- }
277
- /**
278
- * Thrown when a grant would give the grantee a permission the grantor
279
- * does not themselves hold — the "admin cannot grant what admin cannot
280
- * do" rule from the admin-delegation work.
281
- *
282
- * Distinct from `PermissionDeniedError` so callers can tell the two
283
- * cases apart in logs and tests:
284
- *
285
- * - `PermissionDeniedError` — "you are not allowed to perform this
286
- * operation at all" (wrong role).
287
- * - `PrivilegeEscalationError` — "you are allowed to grant, but not
288
- * with these specific permissions" (widening attempt).
289
- *
290
- * Under the admin model the grantee of an admin-grants-admin call
291
- * inherits the caller's entire DEK set by construction, so this error
292
- * is structurally unreachable in typical flows. The check and error
293
- * class exist so that future per-collection admin scoping cannot
294
- * accidentally bypass the subset rule — the guard is already wired in.
295
- *
296
- * `offendingCollection` carries the first collection name that failed
297
- * the subset check, to make the violation actionable in error output.
298
- */
299
- /**
300
- * Thrown when a caller invokes an API that requires an optional
301
- * store capability the active store does not implement.
302
- *
303
- * Today the only call site is `Noydb.listAccessibleVaults()`,
304
- * which depends on the optional `NoydbStore.listVaults()`
305
- * method. The error message names the missing method and the calling
306
- * API so consumers know exactly which combination is unsupported,
307
- * and the `capability` field is machine-readable so library code can
308
- * pattern-match in catch blocks (e.g. fall back to a candidate-list
309
- * shape).
310
- *
311
- * The class lives in `errors.ts` rather than as a generic
312
- * `ValidationError` because the diagnostic shape is different: a
313
- * `ValidationError` says "the inputs you passed are wrong"; this
314
- * error says "the inputs are fine, but the store you wired up
315
- * doesn't support what you're asking for." Different fix, different
316
- * documentation.
317
- */
318
- declare class StoreCapabilityError extends NoydbError {
319
- /** The store method/capability that was missing. */
320
- readonly capability: string;
321
- constructor(capability: string, callerApi: string, storeName?: string);
322
- }
323
- declare class PrivilegeEscalationError extends NoydbError {
324
- readonly offendingCollection: string;
325
- constructor(offendingCollection: string, message?: string);
326
- }
327
- /**
328
- * Thrown by `Collection.put` / `.delete` when the target record's
329
- * envelope `_ts` falls within a closed accounting period.
330
- *
331
- * Distinct from `ReadOnlyError` (keyring-level), `ReadOnlyAtInstantError`
332
- * (historical view), and `ReadOnlyFrameError` (shadow vault): this
333
- * error is about the STORED RECORD being sealed by an operator call
334
- * to `vault.closePeriod()`, independent of caller permissions or
335
- * view type. The `periodName` and `endDate` fields name the sealing
336
- * period so audit UIs can surface a "this record is locked in
337
- * FY2026-Q1 (closed 2026-03-31)" message without parsing the error
338
- * string.
339
- *
340
- * To apply a correction after close, book a compensating entry in a
341
- * new period rather than unlocking the old one. Re-opening a closed
342
- * period is deliberately unsupported.
343
- */
344
- declare class PeriodClosedError extends NoydbError {
345
- readonly periodName: string;
346
- readonly endDate: string;
347
- readonly recordTs: string;
348
- constructor(periodName: string, endDate: string, recordTs: string);
349
- }
350
- /**
351
- * Thrown when a `put()` or `delete()` is rejected by a guard's `check`
352
- * function. The `reason` is the message the guard supplied — typically a
353
- * short business description (e.g. "invoice is issued"). The full
354
- * collection + id are surfaced so audit UIs can link back to the record.
355
- */
356
- declare class RecordLockedError extends NoydbError {
357
- readonly collection: string;
358
- readonly id: string;
359
- readonly reason: string;
360
- constructor(collection: string, id: string, reason: string);
361
- }
362
- /**
363
- * Thrown when a `put()` changes one or more fields that are frozen by a
364
- * `frozenFields` guard. The `fields` list contains the specific paths
365
- * that were detected as changed.
366
- */
367
- declare class FieldFrozenError extends NoydbError {
368
- readonly collection: string;
369
- readonly id: string;
370
- readonly fields: readonly string[];
371
- constructor(collection: string, id: string, fields: readonly string[]);
372
- }
373
- /**
374
- * Thrown by an amendment invariant when the proposed change-set violates
375
- * the declared business rule (e.g. disbursement total not preserved).
376
- * Triggers a full transaction rollback via the existing revert pass.
377
- */
378
- declare class InvariantError extends NoydbError {
379
- constructor(message: string);
380
- }
381
- /**
382
- * Thrown at `withTransactions({ amendment: true })` open if the caller's
383
- * role is not in the guard's allowed amendment roles. Fail-fast: thrown
384
- * before any writes are attempted.
385
- */
386
- declare class AmendmentForbiddenError extends NoydbError {
387
- readonly userId: string;
388
- readonly role: string;
389
- constructor(userId: string, role: string);
390
- }
391
- /**
392
- * Thrown by `listUsersWithEnvelopes` when the vault's user directory
393
- * has been disabled (via `db.setDirectoryEnabled(vault, false)`) and
394
- * the caller's role is neither `owner` nor `admin`. Owner/admin can
395
- * still enumerate users — the toggle is a UX privacy switch, not a
396
- * security boundary.
397
- *
398
- * Honest caveat: this is a UX flag, not a privacy guarantee. The
399
- * envelope ciphertext is still in the store, the keyring file is
400
- * still listed at `_keyring/*`, and anyone with direct store read
401
- * access can count keyrings without going through the hub. See
402
- * `docs/subsystems/user-envelope.md` → "Directory visibility".
403
- */
404
- declare class DirectoryDisabledError extends NoydbError {
405
- readonly vault: string;
406
- constructor(vault: string);
407
- }
408
- /**
409
- * Thrown when a user tries to act at a tier they are not cleared for.
410
- *
411
- * This is the umbrella error for tier write refusals:
412
- * - `put({ tier: N })` when the user's keyring lacks tier-N DEK.
413
- * - `elevate(id, N)` when the caller cannot reach tier N.
414
- *
415
- * Distinct from `TierAccessDeniedError` which covers *read* refusals on
416
- * the invisibility/ghost path.
417
- */
418
- declare class TierNotGrantedError extends NoydbError {
419
- readonly tier: number;
420
- readonly collection: string;
421
- constructor(collection: string, tier: number);
422
- }
423
- /**
424
- * Thrown when an elevated-handle operation runs after the elevation's
425
- * TTL expired. Reads continue at the original tier; only writes
426
- * through the scoped handle flip to throwing once expired.
427
- */
428
- declare class ElevationExpiredError extends NoydbError {
429
- readonly tier: number;
430
- readonly expiresAt: number;
431
- constructor(opts: {
432
- tier: number;
433
- expiresAt: number;
434
- });
435
- }
436
- /**
437
- * Thrown by `vault.elevate(...)` when an elevation is already active
438
- * on the vault. Adopters must `release()` the existing handle before
439
- * starting a new elevation.
440
- */
441
- declare class AlreadyElevatedError extends NoydbError {
442
- readonly activeTier: number;
443
- constructor(activeTier: number);
444
- }
445
- /**
446
- * Thrown when `demote()` is called by someone who is not the original
447
- * elevator and not an owner.
448
- */
449
- declare class TierDemoteDeniedError extends NoydbError {
450
- constructor(id: string, tier: number);
451
- }
452
- /**
453
- * Thrown when `db.delegate()` is called against a user that has no
454
- * keyring in the target vault — the delegation token cannot be
455
- * constructed without the target user's KEK wrap.
456
- */
457
- declare class DelegationTargetMissingError extends NoydbError {
458
- readonly toUser: string;
459
- constructor(toUser: string);
460
- }
461
- /**
462
- * Thrown when a `put()` detects an optimistic concurrency conflict.
463
- *
464
- * NOYDB uses version numbers (`_v`) for optimistic locking. If a `put()`
465
- * is called with `expectedVersion: N` but the stored record is at version
466
- * `M ≠ N`, the write is rejected and the caller must re-read, re-apply their
467
- * change, and retry. The `version` field carries the actual stored version
468
- * so callers can decide whether to retry or surface the conflict to the user.
469
- */
470
- declare class ConflictError extends NoydbError {
471
- /** The actual stored version at the time of conflict. */
472
- readonly version: number;
473
- constructor(version: number, message?: string);
474
- }
475
- /**
476
- * Thrown by `LedgerStore.append()` after exhausting its CAS retry
477
- * budget under multi-writer contention. Two browser tabs, a
478
- * web app + an offline mobile peer, or a server worker pool all
479
- * producing ledger entries against the same vault can race on the
480
- * "read head, write head+1" cycle; the optimistic-CAS retry loop
481
- * resolves the race for `casAtomic: true` stores, but pathological
482
- * contention (or a buggy peer) can still exhaust the budget. When
483
- * that happens, the chain is intact — the failed writer simply
484
- * couldn't claim a slot. Caller's choice whether to retry, queue,
485
- * or surface the failure to the user.
486
- */
487
- declare class LedgerContentionError extends NoydbError {
488
- readonly attempts: number;
489
- constructor(attempts: number);
490
- }
491
- /**
492
- * Thrown when a bundle push is rejected because the remote has been updated
493
- * since the local bundle was last pulled.
494
- *
495
- * Unlike `ConflictError` (per-record), this is a whole-bundle conflict —
496
- * the remote's bundle handle has changed. The caller must pull the new
497
- * bundle, merge, and re-push. `remoteVersion` is the handle of the newer
498
- * remote bundle for use in diagnostics.
499
- */
500
- declare class BundleVersionConflictError extends NoydbError {
501
- /** The bundle handle of the newer remote version that rejected the push. */
502
- readonly remoteVersion: string;
503
- constructor(remoteVersion: string, message?: string);
504
- }
505
- /**
506
- * Thrown when a sync operation (push or pull) fails due to a network error.
507
- *
508
- * NOYDB's offline-first design means network errors are expected during sync.
509
- * Callers should catch `NetworkError`, surface connectivity status in the UI,
510
- * and rely on the `SyncScheduler` to retry when connectivity is restored.
511
- */
512
- declare class NetworkError extends NoydbError {
513
- constructor(message?: string);
514
- }
515
- /**
516
- * Thrown when `collection.get(id)` is called with an ID that does not exist.
517
- *
518
- * NOYDB collections are memory-first, so this error is synchronous and cheap —
519
- * it does not make a network round-trip. Callers that expect the record to be
520
- * absent should use `collection.getOrNull(id)` instead.
521
- */
522
- declare class NotFoundError extends NoydbError {
523
- constructor(message?: string);
524
- }
525
- /**
526
- * Thrown when application-level validation fails before encryption.
527
- *
528
- * Distinct from `SchemaValidationError` (Standard Schema v1 validator)
529
- * and `MissingTranslationError` (i18nText). `ValidationError` is the
530
- * general-purpose validation base — use it for custom guards in `put()`
531
- * hooks or store middleware.
532
- */
533
- declare class ValidationError extends NoydbError {
534
- constructor(message?: string);
535
- }
536
- /**
537
- * Thrown when a Standard Schema v1 validator rejects a record on
538
- * `put()` (input validation) or on read (output validation). Carries
539
- * the raw issue list so callers can render field-level errors.
540
- *
541
- * `direction` distinguishes the two cases:
542
- * - `'input'`: the user passed bad data into `put()`. This is a
543
- * normal error case that application code should handle — typically
544
- * by showing validation messages in the UI.
545
- * - `'output'`: stored data does not match the current schema. This
546
- * indicates a schema drift (the schema was changed without
547
- * migrating the existing records) and should be treated as a bug
548
- * — the application should not swallow it silently.
549
- *
550
- * The `issues` type is deliberately `readonly unknown[]` on this class
551
- * so that `errors.ts` doesn't need to import from `schema.ts` (and
552
- * create a dependency cycle). Callers who know they're holding a
553
- * `SchemaValidationError` can cast to the more precise
554
- * `readonly StandardSchemaV1Issue[]` from `schema.ts`.
555
- */
556
- declare class SchemaValidationError extends NoydbError {
557
- readonly issues: readonly unknown[];
558
- readonly direction: 'input' | 'output';
559
- constructor(message: string, issues: readonly unknown[], direction: 'input' | 'output');
560
- }
561
- /**
562
- * Thrown when `.groupBy().aggregate()` produces more than the hard
563
- * cardinality cap (default 100_000 groups)..
564
- *
565
- * The cap exists because `.groupBy()` materializes one bucket per
566
- * distinct key value in memory, and runaway cardinality — a groupBy
567
- * on a high-uniqueness field like `id` or `createdAt` — is almost
568
- * always a query mistake rather than legitimate use. A hard error is
569
- * better than silent OOM: the consumer sees an actionable message
570
- * naming the field and the observed cardinality, with guidance to
571
- * either narrow the query with `.where()` or accept the ceiling
572
- * override.
573
- *
574
- * A separate one-shot warning fires at 10% of the cap (10_000
575
- * groups) so consumers get a heads-up before the hard error — same
576
- * pattern as `JoinTooLargeError` and the `.join()` row ceiling.
577
- *
578
- * **Not overridable in.** The 100k cap is a fixed constant so
579
- * the failure mode is consistent across the codebase; a
580
- * `{ maxGroups }` override can be added later without a break if a
581
- * real consumer asks.
582
- */
583
- declare class GroupCardinalityError extends NoydbError {
584
- /** The field being grouped on. */
585
- readonly field: string;
586
- /** Observed number of distinct groups at the moment the cap tripped. */
587
- readonly cardinality: number;
588
- /** The cap that was exceeded. */
589
- readonly maxGroups: number;
590
- constructor(field: string, cardinality: number, maxGroups: number);
591
- }
592
- /**
593
- * Thrown in lazy mode when a `.query()` / `.where()` / `.orderBy()` clause
594
- * references a field that does not have a declared index.
595
- *
596
- * Lazy-mode queries only work when every touched field is indexed.
597
- * This is deliberate — silent scan-fallback would hide the performance
598
- * cliff that lazy-mode indexes exist to prevent.
599
- *
600
- * Payload:
601
- * - `collection` — name of the collection queried
602
- * - `touchedFields` — every field referenced by the query (filter + order)
603
- * - `missingFields` — subset of `touchedFields` that have no declared index
604
- */
605
- declare class IndexRequiredError extends NoydbError {
606
- readonly collection: string;
607
- readonly touchedFields: readonly string[];
608
- readonly missingFields: readonly string[];
609
- constructor(args: {
610
- collection: string;
611
- touchedFields: readonly string[];
612
- missingFields: readonly string[];
613
- });
614
- }
615
- /**
616
- * Thrown (or surfaced via the `index:write-partial` event) when one or more
617
- * per-indexed-field side-car writes fail after the main record write has
618
- * already succeeded.
619
- *
620
- * Not thrown out of `.put()` / `.delete()` directly — those succeed when the
621
- * main record succeeds. Instead, `IndexWriteFailureError` instances are collected
622
- * into the session-scoped reconcile queue and emitted on the Collection
623
- * emitter as `index:write-partial`.
624
- *
625
- * Payload:
626
- * - `recordId` — the id of the main record whose side-car writes failed
627
- * - `field` — the indexed field whose side-car write failed
628
- * - `op` — `'put'` or `'delete'`, indicating which mutation was in flight
629
- * - `cause` — the underlying error from the store
630
- */
631
- declare class IndexWriteFailureError extends NoydbError {
632
- readonly recordId: string;
633
- readonly field: string;
634
- readonly op: 'put' | 'delete';
635
- readonly cause: unknown;
636
- constructor(args: {
637
- recordId: string;
638
- field: string;
639
- op: 'put' | 'delete';
640
- cause: unknown;
641
- });
642
- }
643
- /**
644
- * Thrown by `readNoydbBundle()` when the body bytes don't match
645
- * the integrity hash declared in the bundle header — i.e. someone
646
- * modified the bytes between write and read.
647
- *
648
- * Distinct from a generic `Error` (which would be thrown for
649
- * format violations like a missing magic prefix or malformed
650
- * header JSON) so consumers can pattern-match the corruption case
651
- * and handle it differently from a producer bug. A
652
- * `BundleIntegrityError` indicates "the bytes you got are not
653
- * what was written"; a plain `Error` from `parsePrefixAndHeader`
654
- * indicates "what was written wasn't a valid bundle in the first
655
- * place."
656
- *
657
- * Also thrown when decompression fails after the integrity hash
658
- * passed — that's a producer bug (the wrong algorithm byte was
659
- * written) but it surfaces with the same error class because the
660
- * end result is "the body cannot be turned back into a dump."
661
- */
662
- declare class BundleIntegrityError extends NoydbError {
663
- constructor(message: string);
664
- }
665
- /**
666
- * Thrown by `readNoydbBundle` (#197) when the bundle carries
667
- * sealed per-user passphrases but no supplied `SealingKeyProvider`
668
- * has a `.id` (= `pid`) matching the sealed entry's `pid`.
669
- *
670
- * Carries the failing pid + the user id so the recipient can
671
- * surface an actionable prompt:
672
- *
673
- * ```
674
- * BundleSealMismatchError: bundle carries sealed passphrase for user "alice"
675
- * under provider "macos-keychain:com.acme.app/alice@acme.example",
676
- * but no registered provider matches that pid.
677
- * ```
678
- *
679
- * Three resolution paths the message names (per foundation §11.9.4):
680
- *
681
- * 1. Configure a provider matching the pid and retry import.
682
- * 2. Pass `attemptUnsealAcrossProviders: true` to try each
683
- * registered provider regardless of pid.
684
- * 3. Inspect without unsealing — pass no `sealingProviders` to
685
- * receive the sealed entries unmodified for offline analysis.
686
- */
687
- declare class BundleSealMismatchError extends NoydbError {
688
- readonly userId: string;
689
- readonly pid: string;
690
- constructor(userId: string, pid: string);
691
- }
692
- /**
693
- * Thrown when `vault.collection()` is called with a name that is
694
- * reserved for NOYDB internal use (any name starting with `_dict_`).
695
- *
696
- * Dictionary collections are accessed exclusively via
697
- * `vault.dictionary(name)` — attempting to open one as a regular
698
- * collection would bypass the dictionary invariants (ACL, rename
699
- * tracking, reserved-name policy).
700
- */
701
- declare class ReservedCollectionNameError extends NoydbError {
702
- /** The rejected collection name. */
703
- readonly collectionName: string;
704
- constructor(collectionName: string);
705
- }
706
- /**
707
- * Thrown by `DictionaryHandle.get()` and `DictionaryHandle.delete()` when
708
- * the requested key does not exist in the dictionary.
709
- *
710
- * Distinct from `NotFoundError` (which is for data records) so callers
711
- * can distinguish "data record missing" from "dictionary key missing"
712
- * without inspecting error messages.
713
- */
714
- declare class DictKeyMissingError extends NoydbError {
715
- /** The dictionary name. */
716
- readonly dictionaryName: string;
717
- /** The key that was not found. */
718
- readonly key: string;
719
- constructor(dictionaryName: string, key: string);
720
- }
721
- /**
722
- * Thrown by `DictionaryHandle.delete()` in strict mode when the key to
723
- * be deleted is still referenced by one or more records.
724
- *
725
- * The caller must either rename the key first (the only sanctioned
726
- * mass-mutation path) or pass `{ mode: 'warn' }` to skip the check
727
- * (development only).
728
- */
729
- declare class DictKeyInUseError extends NoydbError {
730
- /** The dictionary name. */
731
- readonly dictionaryName: string;
732
- /** The key that is still referenced. */
733
- readonly key: string;
734
- /** Name of the first collection found to reference this key. */
735
- readonly usedBy: string;
736
- /** Number of records in `usedBy` that reference this key. */
737
- readonly count: number;
738
- constructor(dictionaryName: string, key: string, usedBy: string, count: number);
739
- }
740
- /**
741
- * Thrown by `Collection.put()` when an `i18nText` field is missing one
742
- * or more required translations.
743
- *
744
- * The `missing` array names each locale code that was absent from the
745
- * field value. The `field` property names the field so callers can
746
- * render a field-level error message without parsing the string.
747
- */
748
- declare class MissingTranslationError extends NoydbError {
749
- /** The field name whose translation(s) are missing. */
750
- readonly field: string;
751
- /** Locale codes that were required but absent. */
752
- readonly missing: readonly string[];
753
- constructor(field: string, missing: readonly string[], message?: string);
754
- }
755
- /**
756
- * Thrown when reading an `i18nText` field without specifying a locale —
757
- * either at the call site (`get(id, { locale })`) or on the vault
758
- * (`openVault(name, { locale })`).
759
- *
760
- * Also thrown when `resolveI18nText()` exhausts the fallback chain and
761
- * no translation is available for the requested locale.
762
- *
763
- * The `field` property names the field that triggered the error so the
764
- * caller can surface it in the UI.
765
- */
766
- declare class LocaleNotSpecifiedError extends NoydbError {
767
- /** The field name that required a locale. */
768
- readonly field: string;
769
- constructor(field: string, message?: string);
770
- }
771
- /**
772
- * Thrown when a collection has an `i18nText` field with
773
- * `autoTranslate: true` but no `plaintextTranslator` was configured
774
- * on `createNoydb()`.
775
- *
776
- * The error is raised at `put()` time (not at schema construction) so
777
- * the mis-configuration is surfaced by the first write rather than
778
- * silently at startup.
779
- */
780
- declare class TranslatorNotConfiguredError extends NoydbError {
781
- /** The field that requested auto-translation. */
782
- readonly field: string;
783
- /** The collection the put was targeting. */
784
- readonly collection: string;
785
- constructor(field: string, collection: string);
786
- }
787
- /**
788
- * Thrown when `Vault.load()` finds that a backup's hash chain
789
- * doesn't verify, or that its embedded `ledgerHead.hash` doesn't
790
- * match the chain head reconstructed from the loaded entries.
791
- *
792
- * Distinct from `BackupCorruptedError` so callers can choose to
793
- * recover from one but not the other (e.g., a corrupted JSON file is
794
- * unrecoverable; a chain mismatch might mean the backup is from an
795
- * incompatible noy-db version).
796
- */
797
- declare class BackupLedgerError extends NoydbError {
798
- /** First-broken-entry index, if known. */
799
- readonly divergedAt?: number;
800
- constructor(message: string, divergedAt?: number);
801
- }
802
- /**
803
- * Thrown when `Vault.load()` finds that the backup's data
804
- * collection content doesn't match the ledger's recorded
805
- * `payloadHash`es. This is the "envelope was tampered with after
806
- * dump" detection — the chain itself can be intact, but if any
807
- * encrypted record bytes were swapped, this check catches it.
808
- */
809
- declare class BackupCorruptedError extends NoydbError {
810
- /** The (collection, id) pair whose envelope failed the hash check. */
811
- readonly collection: string;
812
- readonly id: string;
813
- constructor(collection: string, id: string, message: string);
814
- }
815
- /**
816
- * Thrown by partition-extraction primitives (#198 epic) when the
817
- * transitive-closure walk fails — e.g. the FK graph is deeper than
818
- * `maxDepth`, signalling a runaway or unexpectedly cyclic graph.
819
- */
820
- declare class PartitionExtractionError extends NoydbError {
821
- constructor(message: string);
822
- }
823
- /**
824
- * Thrown by `adoptPartition` (#207) when the transfer seal can't be
825
- * opened — a wrong/short transfer key (AES-GCM auth-tag failure) or a
826
- * malformed sealed payload.
827
- */
828
- declare class TransferSealError extends NoydbError {
829
- constructor(message: string);
830
- }
831
- /**
832
- * Thrown when an adoption-lifecycle precondition fails — re-adopting a
833
- * partition already consumed in this store (#207), or owner-creation on a
834
- * vault that isn't in the adopted-unowned state (#208).
835
- */
836
- declare class AdoptionStateError extends NoydbError {
837
- constructor(message: string);
838
- }
839
- /** Document-attestation failures: undeclared field-schema, non-owner issue, missing field, signer failure. */
840
- declare class AttestationError extends NoydbError {
841
- constructor(message: string);
842
- }
843
- /**
844
- * Thrown by `resolveSession()` when the session token's `expiresAt`
845
- * timestamp is in the past. The session key is also removed from the
846
- * in-memory store when this is thrown, so retrying with the same sessionId
847
- * will produce `SessionNotFoundError`.
848
- *
849
- * Separate from `SessionNotFoundError` so callers can distinguish between
850
- * "session is gone" (key store cleared, tab reloaded) and "session is
851
- * still in the store but has exceeded its lifetime" (idle timeout, absolute
852
- * timeout, policy-driven expiry). The remediation differs: expired sessions
853
- * should prompt a fresh unlock; not-found sessions may indicate a bug or a
854
- * cross-tab scenario where the session was never established.
855
- */
856
- declare class SessionExpiredError extends NoydbError {
857
- readonly sessionId: string;
858
- constructor(sessionId: string);
859
- }
860
- /**
861
- * Thrown by `resolveSession()` when the session key cannot be found in
862
- * the module-level store. This happens when:
863
- * - The session was explicitly revoked via `revokeSession()`.
864
- * - The JS context was reloaded (tab navigation, page refresh, worker restart).
865
- * - `Noydb.close()` was called (which calls `revokeAllSessions()`).
866
- * - The sessionId is wrong or was generated by a different JS context.
867
- *
868
- * The session token (if the caller holds it) is permanently useless after
869
- * this error — the key is gone and cannot be recovered.
870
- */
871
- declare class SessionNotFoundError extends NoydbError {
872
- readonly sessionId: string;
873
- constructor(sessionId: string);
874
- }
875
- /**
876
- * Thrown when a session policy blocks an operation — for example,
877
- * `requireReAuthFor: ['export']` is set and the caller attempts to
878
- * call `exportStream()` without re-authenticating for this session.
879
- *
880
- * The `operation` field names the specific operation that was blocked
881
- * (e.g. `'export'`, `'grant'`, `'rotate'`) so the caller can surface
882
- * a targeted prompt ("Please re-enter your passphrase to export data").
883
- */
884
- declare class SessionPolicyError extends NoydbError {
885
- readonly operation: string;
886
- constructor(operation: string, message?: string);
887
- }
888
- /**
889
- * Thrown when a `.join()` would exceed its configured row ceiling on
890
- * either side. The ceiling defaults to 50,000 per side and can be
891
- * overridden via the `{ maxRows }` option on `.join()`.
892
- *
893
- * Carries both row counts so the error message can show which side
894
- * tripped the limit (e.g. "left had 60,000 rows, right had 1,200,
895
- * max was 50,000"). The `side` field is machine-readable so test
896
- * code and devtools can match on it without regex-parsing the
897
- * message.
898
- *
899
- * The row ceiling exists because joins are bounded in-memory
900
- * operations over materialized record sets. Consumers whose
901
- * collections genuinely exceed the ceiling should track
902
- * (streaming joins over `scan()`) or filter the left side further
903
- * with `where()` / `limit()` before joining.
904
- */
905
- declare class JoinTooLargeError extends NoydbError {
906
- readonly leftRows: number;
907
- readonly rightRows: number;
908
- readonly maxRows: number;
909
- readonly side: 'left' | 'right';
910
- constructor(opts: {
911
- leftRows: number;
912
- rightRows: number;
913
- maxRows: number;
914
- side: 'left' | 'right';
915
- message: string;
916
- });
917
- }
918
- /**
919
- * Thrown by `.join()` in strict `ref()` mode when a left-side record
920
- * points at a right-side id that does not exist in the target
921
- * collection.
922
- *
923
- * Distinct from `RefIntegrityError` so test code can pattern-match
924
- * on the *read-time* dangling case without catching *write-time*
925
- * integrity violations. Both indicate "ref points at nothing" but
926
- * happen at different lifecycle phases and deserve different
927
- * remediation in documentation: a RefIntegrityError on `put()`
928
- * means the input is invalid; a DanglingReferenceError on `.join()`
929
- * means stored data has drifted and `vault.checkIntegrity()`
930
- * is the right tool to find the full set of orphans.
931
- */
932
- declare class DanglingReferenceError extends NoydbError {
933
- readonly field: string;
934
- readonly target: string;
935
- readonly refId: string;
936
- constructor(opts: {
937
- field: string;
938
- target: string;
939
- refId: string;
940
- message: string;
941
- });
942
- }
943
- /**
944
- * Thrown by {@link sanitizeFilename} when an input filename cannot be
945
- * made safe — NUL byte, empty after normalization, missing
946
- * `opaqueId` for the opaque profile, `..` segment, or a `maxBytes`
947
- * cap too small to hold a single code point.
948
- */
949
- declare class FilenameSanitizationError extends NoydbError {
950
- constructor(message: string);
951
- }
952
- /**
953
- * Thrown when a write target resolves OUTSIDE the requested
954
- * directory after sanitization — the canonical Zip-Slip class. The
955
- * sanitizer's job is to strip path-traversal segments; this error
956
- * is the defense-in-depth fallback at the FS write site.
957
- */
958
- declare class PathEscapeError extends NoydbError {
959
- readonly attempted: string;
960
- readonly targetDir: string;
961
- constructor(opts: {
962
- attempted: string;
963
- targetDir: string;
964
- });
965
- }
966
- /**
967
- * Thrown at vault open if the derivation graph contains a cycle.
968
- * `path` is the offending chain (e.g. `['a', 'b', 'c', 'a']`).
969
- */
970
- declare class DerivationCycleError extends NoydbError {
971
- readonly path: readonly string[];
972
- constructor(path: readonly string[]);
973
- }
974
- /**
975
- * Thrown when a cascade of source → output → source → … exceeds the
976
- * configured `maxDepth` (default 5).
977
- */
978
- declare class DerivationDepthError extends NoydbError {
979
- readonly limit: number;
980
- readonly attempted: number;
981
- constructor(limit: number, attempted: number);
982
- }
983
- /**
984
- * Thrown at registration if a `withDerivation` strategy references an
985
- * output `collection` that isn't otherwise declared (no schema, no use
986
- * elsewhere). Surfacing this early catches typos in collection names.
987
- */
988
- declare class DerivationOutputUnknownError extends NoydbError {
989
- readonly collection: string;
990
- constructor(collection: string);
991
- }
992
- /**
993
- * Thrown when the user's `derive` function returns a value that doesn't
994
- * match the declared output spec (e.g. wrong shape, wrong key set).
995
- */
996
- declare class DerivationOutputShapeError extends NoydbError {
997
- readonly outputKey: string;
998
- constructor(outputKey: string, detail: string);
999
- }
1000
- /**
1001
- * Thrown by array-shape derivations (#200) when the `derive` function
1002
- * returns more rows than the output's `maxFanout` cap. The cap exists
1003
- * to keep dispatch cost bounded — without it a single source-row
1004
- * update could fan out to thousands of derived rows, dominating the
1005
- * write path.
1006
- *
1007
- * Defaults to `maxFanout: 64`. Raise on the output spec for
1008
- * carry-forward expansion cases (e.g. monthly rows across multi-year
1009
- * contracts).
1010
- */
1011
- declare class DerivationCapExceededError extends NoydbError {
1012
- readonly outputKey: string;
1013
- readonly returned: number;
1014
- readonly maxFanout: number;
1015
- constructor(outputKey: string, returned: number, maxFanout: number);
1016
- }
1017
- /**
1018
- * Thrown at vault open if the materialized-view graph contains a
1019
- * cycle. `path` is the offending chain (e.g. `['a-mv', 'b-mv', 'a-mv']`).
1020
- * Detected by the same shared DFS that catches `DerivationCycleError`;
1021
- * surfaces with a distinct error type so consumers can disambiguate.
1022
- */
1023
- declare class MaterializedViewCycleError extends NoydbError {
1024
- readonly path: readonly string[];
1025
- constructor(path: readonly string[]);
1026
- }
1027
- /**
1028
- * Thrown at MV registration if the query references a source
1029
- * collection that isn't declared on the vault. Surfacing this early
1030
- * catches typos in collection names.
1031
- */
1032
- declare class MaterializedViewSourceUnknownError extends NoydbError {
1033
- readonly mvName: string;
1034
- readonly collection: string;
1035
- constructor(mvName: string, collection: string);
1036
- }
1037
- /**
1038
- * Thrown by the MV executor when a refresh produces more rows than
1039
- * the configured ceiling. Default ceiling is 100k rows; override
1040
- * per-MV via `maxRows`. Mirrors `JoinTooLargeError` /
1041
- * `GroupCardinalityError` from the query DSL — the explosion is
1042
- * detected BEFORE writes hit the store, so the source-write
1043
- * transaction can roll back cleanly via strict-mode.
1044
- */
1045
- declare class MaterializedViewTooLargeError extends NoydbError {
1046
- readonly mvName: string;
1047
- readonly expected: number;
1048
- readonly limit: number;
1049
- constructor(mvName: string, expected: number, limit: number);
1050
- }
1051
- /**
1052
- * Thrown by `withMaterializedView()` at registration time when the
1053
- * strategy is structurally malformed. Distinct from
1054
- * `MaterializedViewSourceUnknownError` (the source list is well-formed
1055
- * but names a collection the vault doesn't know) and
1056
- * `MaterializedViewCycleError` (the source graph has a cycle): this
1057
- * error fires before either check, at the moment the spec is being
1058
- * normalized.
1059
- *
1060
- * Today the trigger cases are all about the `query` / `unionSources`
1061
- * dichotomy introduced by #165:
1062
- * - both `query` and `unionSources` were set (mutually exclusive),
1063
- * - neither `query` nor `unionSources` was set,
1064
- * - `unionSources` has fewer than 2 arms,
1065
- * - two arms in `unionSources` reference the same `collection`.
1066
- *
1067
- * The error message is prefixed with `[noy-db] withMaterializedView:`
1068
- * so it's grep-friendly in logs and looks consistent with the existing
1069
- * `ValidationError` messages from the same factory.
1070
- */
1071
- declare class MaterializedViewConfigError extends NoydbError {
1072
- constructor(message: string);
1073
- }
1074
- /**
1075
- * Thrown at vault open when a `withOverlayedView` declaration uses
1076
- * another virtual-overlay name as its `base`. Multi-overlay stacking
1077
- * is a v2 non-goal — the shallow expansion in
1078
- * `QueryDependencyAnalyzer` would truncate at the inner overlay
1079
- * name, leaving downstream MVs silently stale.
1080
- */
1081
- declare class OverlayBaseIsVirtualError extends NoydbError {
1082
- readonly overlayName: string;
1083
- readonly base: string;
1084
- constructor(overlayName: string, base: string);
1085
- }
1086
- /**
1087
- * Thrown at vault open when a `withOverlayedView`'s `overlay`
1088
- * references an unknown collection or an MV-owned collection. The
1089
- * overlay collection is user-writable; MV-owned collections aren't.
1090
- */
1091
- declare class OverlayCollectionUnavailableError extends NoydbError {
1092
- readonly overlayName: string;
1093
- readonly overlay: string;
1094
- constructor(overlayName: string, overlay: string);
1095
- }
1096
- /**
1097
- * Thrown at vault open when a `withOverlayedView`'s virtual `name`
1098
- * collides with an MV output or a concrete source collection.
1099
- */
1100
- declare class OverlayNameCollisionError extends NoydbError {
1101
- readonly overlayName: string;
1102
- constructor(overlayName: string);
1103
- }
1104
- /**
1105
- * Thrown by the virtual overlay's `put(id, record)` when the
1106
- * consumer-supplied `id` doesn't match `rowKey(record)`. Catches
1107
- * fat-finger separator typos that would otherwise silently produce
1108
- * orphaned overlay rows. Direct writes to the underlying overlay
1109
- * collection (bypass the virtual layer) skip this validation.
1110
- */
1111
- declare class OverlayIdMismatchError extends NoydbError {
1112
- readonly actual: string;
1113
- readonly expected: string;
1114
- constructor(actual: string, expected: string);
1115
- }
1
+ import { C as CollectionIndexes, a as Clause, O as Operator } from './predicate-BmhBSPCH.js';
2
+ import { N as NoydbError } from './errors-Dkc_fi-S.js';
3
+ import { a as I18nTextDescriptor, N as MoneyDescriptor, A as AggregateStrategy, j as AggregateSpec, k as Aggregation, h as AggregateResult, o as GroupedQuery, p as GroupedQueryN } from './strategy-54eIwox5.js';
1116
4
 
1117
5
  /**
1118
6
  * Foreign-key references — the soft-FK mechanism.
@@ -1171,7 +59,19 @@ type RefMode = 'strict' | 'warn' | 'cascade';
1171
59
  interface RefDescriptor {
1172
60
  readonly target: string;
1173
61
  readonly mode: RefMode;
62
+ /**
63
+ * Present and `true` only for an array ref (#377-A, `refArray()`): the
64
+ * field holds an ARRAY of ids, each validated against `target`
65
+ * independently (M:N). Absent for a scalar `ref()`. The same `mode`
66
+ * semantics apply per element — strict rejects on a missing element at
67
+ * put + blocks delete of a referenced target; cascade deletes every
68
+ * record whose array contains the deleted id; warn surfaces orphans
69
+ * only via `checkIntegrity()`.
70
+ */
71
+ readonly isArray?: true;
1174
72
  }
73
+ /** Runtime predicate: is this an array ref (`refArray()`) vs a scalar `ref()`? */
74
+ declare function isRefArray(desc: RefDescriptor): boolean;
1175
75
  /**
1176
76
  * Thrown when a strict reference is violated — either `put()` with a
1177
77
  * missing target id, or `delete()` of a target that still has
@@ -1214,6 +114,30 @@ declare class RefScopeError extends NoydbError {
1214
114
  * fails at collection construction time, not at the first put.
1215
115
  */
1216
116
  declare function ref(target: string, mode?: RefMode): RefDescriptor;
117
+ /**
118
+ * Array reference (#377-A) — the many-to-many soft-FK. The field holds an
119
+ * array of ids; each element is validated against `target` independently.
120
+ *
121
+ * ```ts
122
+ * const orders = company.collection<Order>('orders', {
123
+ * refs: { productIds: refArray('products', 'warn') },
124
+ * })
125
+ * ```
126
+ *
127
+ * Same three `mode` semantics as `ref()`, applied per element:
128
+ * - **strict** — `put()` rejects if ANY element's target is missing;
129
+ * `delete()` of a target is blocked while any record's array still
130
+ * contains its id.
131
+ * - **warn** — both succeed; orphaned elements surface via
132
+ * `vault.checkIntegrity()` (one violation per dangling element).
133
+ * - **cascade** — `delete()` of a target deletes every record whose
134
+ * array contains its id (cycle-safe, like scalar cascade).
135
+ *
136
+ * A `null`/`undefined` field is allowed (no links). Non-array values, or
137
+ * non-string/number elements, are an integrity error. Cross-vault targets
138
+ * are rejected exactly as in `ref()`.
139
+ */
140
+ declare function refArray(target: string, mode?: RefMode): RefDescriptor;
1217
141
  /**
1218
142
  * Per-vault registry of reference declarations.
1219
143
  *
@@ -1256,6 +180,7 @@ declare class RefRegistry {
1256
180
  collection: string;
1257
181
  field: string;
1258
182
  mode: RefMode;
183
+ isArray?: true;
1259
184
  }>;
1260
185
  /**
1261
186
  * Iterate every (collection → refs) pair that has at least one
@@ -1390,6 +315,23 @@ interface JoinLeg {
1390
315
  interface JoinableSource {
1391
316
  snapshot(): readonly unknown[];
1392
317
  lookupById?(id: string): unknown;
318
+ /**
319
+ * Default locale a label-resolving query falls back to when the query
320
+ * itself is locale-less. Set by a `staticDict()`-backed source from its
321
+ * `displayLocale` so `{ by: 'label' }` resolves under a locale-less read
322
+ * (#291). Plain `_dict_*`-backed sources omit it.
323
+ */
324
+ readonly displayLocale?: string;
325
+ /**
326
+ * i18nText descriptors of the right-side collection (#285 §3, `join`
327
+ * layer). When present and the query carries a locale, each joined
328
+ * right-side record's i18n fields resolve to that locale at the `join`
329
+ * layer (`resolvePolicy(onMissing, 'join')`) BEFORE it is attached under
330
+ * the leg's alias — so a joined `i18nText` field is a resolved string, not
331
+ * a raw `{ locale }` map. Locale-less queries leave joined fields raw
332
+ * (consistent with a locale-less read).
333
+ */
334
+ readonly i18nFields?: Record<string, I18nTextDescriptor>;
1393
335
  /**
1394
336
  * Subscribe to mutations on this source. The callback fires
1395
337
  * AFTER the underlying record set has been updated. Returns an
@@ -1412,6 +354,13 @@ interface JoinableSource {
1412
354
  interface JoinContext {
1413
355
  /** Name of the left-side (owning) collection. */
1414
356
  readonly leftCollection: string;
357
+ /**
358
+ * The owning collection's default locale (#285 §3). Used to resolve joined
359
+ * i18n fields at the `join` layer when a terminal call doesn't pass an
360
+ * explicit locale — so `openVault({ locale })` flows to joins like it does
361
+ * to `get`/`list`. A per-call `toArray({ locale })` overrides it.
362
+ */
363
+ readonly defaultLocale?: string;
1415
364
  /** Look up a `RefDescriptor` by field name on the left collection. */
1416
365
  resolveRef(field: string): RefDescriptor | null;
1417
366
  /** Resolve a right-side source by target collection name. */
@@ -1453,7 +402,7 @@ interface JoinContext {
1453
402
  * query like `.join('a', { maxRows: 100_000 }).join('b', { maxRows: 50 })`,
1454
403
  * which should throw on the second leg if the left set exceeds 50.
1455
404
  */
1456
- declare function applyJoins(rows: readonly unknown[], joins: readonly JoinLeg[], context: JoinContext): unknown[];
405
+ declare function applyJoins(rows: readonly unknown[], joins: readonly JoinLeg[], context: JoinContext, locale?: string): unknown[];
1457
406
  /**
1458
407
  * Test-only: reset the join warning deduplication state between
1459
408
  * tests. Production code never calls this — the dedup state is
@@ -1584,6 +533,13 @@ declare function buildLiveQuery<T>(recompute: () => T[], upstreams: readonly Liv
1584
533
  interface OrderBy {
1585
534
  readonly field: string;
1586
535
  readonly direction: 'asc' | 'desc';
536
+ /**
537
+ * Sort key for a `dictKey`/`staticDict` field (#285): `'value'` (default)
538
+ * sorts by the stored code; `'label'` sorts by the code's resolved label at
539
+ * the query locale (`toArray({ locale })`, or a `staticDict` `displayLocale`).
540
+ * Falls back to the code when no label resolves.
541
+ */
542
+ readonly by?: 'value' | 'label';
1587
543
  }
1588
544
  /**
1589
545
  * A complete query plan: zero-or-more clauses, optional ordering, pagination,
@@ -1608,6 +564,8 @@ interface QueryPlan {
1608
564
  */
1609
565
  readonly joins: readonly JoinLeg[];
1610
566
  }
567
+ /** Default row ceiling for cross-join expansion. Matches JoinTooLargeError's ceiling. */
568
+ declare const DEFAULT_CROSS_JOIN_MAX_ROWS = 50000;
1611
569
  /**
1612
570
  * Source of records that a query executes against.
1613
571
  *
@@ -1628,6 +586,11 @@ interface QuerySource<T> {
1628
586
  getIndexes?(): CollectionIndexes | null;
1629
587
  /** O(1) record lookup by id, used to materialize index hits. */
1630
588
  lookupById?(id: string): T | undefined;
589
+ /**
590
+ * Money field descriptors for the backing collection, used to rewrite
591
+ * `sum`/`min`/`max` over money fields into exact BigInt reducers.
592
+ */
593
+ moneyFields?: Record<string, MoneyDescriptor>;
1631
594
  }
1632
595
  /**
1633
596
  * The chainable builder. All methods return a new Query — the original
@@ -1645,7 +608,7 @@ interface QuerySource<T> {
1645
608
  * error. See `query/join.ts` for the full design.
1646
609
  */
1647
610
  /**
1648
- * Declared deterministic predicate (#153). Carries the consumer's
611
+ * Declared deterministic predicate. Carries the consumer's
1649
612
  * stable `hash` (for function-body identity), the function itself,
1650
613
  * and is keyed by name when registered on a `Query<T>` via
1651
614
  * `_withPredicates()`.
@@ -1676,12 +639,12 @@ declare class Query<T> {
1676
639
  /**
1677
640
  * @internal — clone this Query with a declared-predicate map
1678
641
  * attached. Used by the materialized-view registry to enable
1679
- * `.wherePredicate(name, ctx?)` for the MV's query callback (#153).
642
+ * `.wherePredicate(name, ctx?)` for the MV's query callback.
1680
643
  * Consumers don't call this directly.
1681
644
  */
1682
645
  _withPredicates(predicates: ReadonlyMap<string, DeclaredPredicate>): Query<T>;
1683
646
  /**
1684
- * Filter by a registered deterministic predicate (#153). Requires
647
+ * Filter by a registered deterministic predicate. Requires
1685
648
  * the Query to have been augmented with a predicates map (typically
1686
649
  * via the materialized-view registry — bare Queries constructed
1687
650
  * outside an MV throw on `.wherePredicate()`).
@@ -1692,7 +655,15 @@ declare class Query<T> {
1692
655
  * either changing forces refresh on next visit.
1693
656
  */
1694
657
  wherePredicate(name: string, ctx?: unknown): Query<T>;
1695
- /** Add a field comparison. Multiple where() calls are AND-combined. */
658
+ /**
659
+ * Add a field comparison. Multiple where() calls are AND-combined.
660
+ *
661
+ * A declared money field compares in MAJOR units (#336): the operand
662
+ * (`10000`, `'10000.00'`, or `{ amount, currency }` in multi mode) is
663
+ * quantized into stored scaled-int space at build time and evaluated
664
+ * BigInt-exact per record. A malformed operand or a string operator
665
+ * (`contains`/`startsWith`) throws here, at the call site.
666
+ */
1696
667
  where(field: string, op: Operator, value: unknown): Query<T>;
1697
668
  /**
1698
669
  * Logical OR group. Pass a callback that builds a sub-query.
@@ -1707,8 +678,14 @@ declare class Query<T> {
1707
678
  and(builder: (q: Query<T>) => Query<T>): Query<T>;
1708
679
  /** Escape hatch: add an arbitrary predicate function. Not serializable. */
1709
680
  filter(fn: (record: T) => boolean): Query<T>;
1710
- /** Sort by a field. Subsequent calls are tie-breakers. */
1711
- orderBy(field: string, direction?: 'asc' | 'desc'): Query<T>;
681
+ /**
682
+ * Sort by a field. Subsequent calls are tie-breakers. Pass
683
+ * `{ by: 'label' }` to sort a `dictKey`/`staticDict` field by its resolved
684
+ * label at the query locale instead of the stored code (#285).
685
+ */
686
+ orderBy(field: string, direction?: 'asc' | 'desc', opts?: {
687
+ by?: 'value' | 'label';
688
+ }): Query<T>;
1712
689
  /** Cap the result size. */
1713
690
  limit(n: number): Query<T>;
1714
691
  /** Skip the first N matching records (after ordering). */
@@ -1776,15 +753,67 @@ declare class Query<T> {
1776
753
  strategy?: JoinStrategy;
1777
754
  maxRows?: number;
1778
755
  }): Query<T & Record<As, R | null>>;
756
+ /**
757
+ * Cartesian-product cross-join against `target` collection. Each result row
758
+ * carries the original `T` fields plus `result[as]` populated from every
759
+ * right-side row (or the filtered subset when `on:` is supplied).
760
+ *
761
+ * **Order matters:** `.where().crossJoin()` filters BEFORE expanding (cheaper);
762
+ * `.crossJoin().where('alias.field', ...)` filters AFTER (required when the
763
+ * where clause references the aliased fields).
764
+ *
765
+ * **Cost ceiling:** `CrossJoinTooLargeError` fires before allocation when
766
+ * `leftRows × rightRows` (or the cumulative lateral count) exceeds the limit.
767
+ * Default: 50,000 rows. Override per-clause with `{ maxRows: N }`.
768
+ *
769
+ * **`on:` shapes:**
770
+ * - `on: (left) => TTarget[]` — subset form (most efficient)
771
+ * - `on: (left) => (right) => boolean` — predicate form
772
+ * - `on: { predicate: 'name' }` — MV-safe, hash-tracked form
773
+ * (requires the Query to have been augmented via `_withPredicates`)
774
+ *
775
+ * Requires a JoinContext (constructed via `collection.query()`).
776
+ */
777
+ crossJoin<TTarget = unknown, As extends string = string>(target: string, opts: {
778
+ as: As;
779
+ on?: ((left: T) => unknown[] | ((right: TTarget) => boolean)) | {
780
+ readonly predicate: string;
781
+ };
782
+ maxRows?: number;
783
+ }): Query<T & {
784
+ [K in As]: TTarget;
785
+ }>;
1779
786
  /**
1780
787
  * Execute the plan and return the matching records. When the plan
1781
788
  * carries any join legs, they are applied after `where` / `orderBy`
1782
789
  * / `limit` / `offset` narrow the left set. See the `.join()` doc
1783
790
  * for the ordering rationale.
791
+ *
792
+ * `opts.locale` (#285 §3) resolves JOINED right-side i18n fields at the
793
+ * `join` layer to that locale; without it, the owning collection's default
794
+ * locale applies, and a locale-less query leaves joined i18n fields raw.
795
+ * (Left/base i18n fields are resolved by `get`/`list`, not here.)
1784
796
  */
1785
- toArray(): T[];
1786
- /** Return the first matching record, or null. Joins are applied. */
1787
- first(): T | null;
797
+ toArray(opts?: {
798
+ locale?: string;
799
+ }): T[];
800
+ /**
801
+ * Decode this source's money fields on read (stored scaled-int → canonical
802
+ * decimal), so `query().toArray()` agrees with `get()`/`sum()` on the value.
803
+ * No-op when the source declares no money fields.
804
+ *
805
+ * The query layer carries no locale context, so we decode with `'raw'` —
806
+ * canonical decimal, WITHOUT fabricating locale-formatted `<field>Formatted`
807
+ * / `<field>Number` virtuals. Producing a guessed-locale string here would
808
+ * just reintroduce #322's "two read paths disagree" failure on the virtual
809
+ * field (e.g. it-IT via `get()` vs en-US here). Consumers who need formatted
810
+ * money read through `get()`/`list()` with a locale.
811
+ */
812
+ private decodeMoney;
813
+ /** Return the first matching record, or null. Joins are applied. `opts.locale` resolves joined i18n fields (#285 §3). */
814
+ first(opts?: {
815
+ locale?: string;
816
+ }): T | null;
1788
817
  /**
1789
818
  * Return the number of matching records (after where/filter,
1790
819
  * before limit). **Joins are NOT applied** — count() reports the
@@ -2072,7 +1101,20 @@ declare class ScanBuilder<T> implements AsyncIterable<T> {
2072
1101
  * context throws with an actionable error.
2073
1102
  */
2074
1103
  private readonly joinContext;
2075
- constructor(pageProvider: ScanPageProvider<T>, pageSize?: number, clauses?: readonly Clause[], joins?: readonly JoinLeg[], joinContext?: JoinContext);
1104
+ /**
1105
+ * Money field descriptors for the backing collection. When present, yielded
1106
+ * records are decoded (stored scaled-int → canonical decimal) so `scan()`
1107
+ * agrees with `get()`/`list()`/`query().toArray()` — #322. Decoded with
1108
+ * `'raw'` (canonical decimal, no locale-formatted virtuals) since the scan
1109
+ * stream carries no locale context, mirroring `Query.toArray()`.
1110
+ */
1111
+ private readonly moneyFields;
1112
+ constructor(pageProvider: ScanPageProvider<T>, pageSize?: number, clauses?: readonly Clause[], joins?: readonly JoinLeg[], joinContext?: JoinContext, moneyFields?: Record<string, MoneyDescriptor>);
1113
+ /**
1114
+ * Decode this scan's money fields on a record (stored scaled-int → canonical
1115
+ * decimal). No-op when no money fields are declared. See {@link moneyFields}.
1116
+ */
1117
+ private decodeMoney;
2076
1118
  /**
2077
1119
  * Add a field comparison. Runs per record as the scan stream
2078
1120
  * flows through, so non-matching records are dropped before they
@@ -2263,4 +1305,4 @@ declare class ScanBuilder<T> implements AsyncIterable<T> {
2263
1305
  private recordMatches;
2264
1306
  }
2265
1307
 
2266
- export { type JoinLeg as $, AmendmentForbiddenError as A, BackupCorruptedError as B, ConflictError as C, DictKeyInUseError as D, DecryptionError as E, FieldFrozenError as F, DelegationTargetMissingError as G, DirectoryDisabledError as H, InvariantError as I, ElevationExpiredError as J, ExportCapabilityError as K, LocaleNotSpecifiedError as L, MissingTranslationError as M, NoydbError as N, OverlayBaseIsVirtualError as O, PartitionExtractionError as P, Query as Q, ReservedCollectionNameError as R, SessionExpiredError as S, TranslatorNotConfiguredError as T, FilenameSanitizationError as U, GroupCardinalityError as V, ImportCapabilityError as W, IndexRequiredError as X, IndexWriteFailureError as Y, InvalidKeyError as Z, type JoinContext as _, DictKeyMissingError as a, type JoinStrategy as a0, JoinTooLargeError as a1, type JoinableSource as a2, KeyringCorruptError as a3, KeyringExpiredError as a4, LedgerContentionError as a5, type LiveQuery as a6, type LiveUpstream as a7, NetworkError as a8, NoAccessError as a9, buildLiveQuery as aA, executePlan as aB, ref as aC, resetJoinWarnings as aD, NotFoundError as aa, type OrderBy as ab, PathEscapeError as ac, PeriodClosedError as ad, PermissionDeniedError as ae, PrivilegeEscalationError as af, type QueryPlan as ag, type QuerySource as ah, ReadOnlyAtInstantError as ai, ReadOnlyError as aj, ReadOnlyFrameError as ak, type RefDescriptor as al, RefIntegrityError as am, type RefMode as an, RefRegistry as ao, RefScopeError as ap, type RefViolation as aq, ScanBuilder as ar, type ScanPageProvider as as, SchemaValidationError as at, StoreCapabilityError as au, TamperedError as av, TierDemoteDeniedError as aw, TierNotGrantedError as ax, ValidationError as ay, applyJoins as az, SessionNotFoundError as b, SessionPolicyError as c, RecordLockedError as d, DerivationCapExceededError as e, DerivationCycleError as f, DerivationDepthError as g, DerivationOutputShapeError as h, DerivationOutputUnknownError as i, OverlayCollectionUnavailableError as j, OverlayIdMismatchError as k, OverlayNameCollisionError as l, AttestationError as m, AdoptionStateError as n, BackupLedgerError as o, BundleIntegrityError as p, BundleSealMismatchError as q, BundleVersionConflictError as r, TransferSealError as s, MaterializedViewConfigError as t, MaterializedViewCycleError as u, MaterializedViewSourceUnknownError as v, MaterializedViewTooLargeError as w, AlreadyElevatedError as x, DEFAULT_JOIN_MAX_ROWS as y, DanglingReferenceError as z };
1308
+ export { DEFAULT_CROSS_JOIN_MAX_ROWS as D, type JoinContext as J, type LiveQuery as L, type OrderBy as O, Query as Q, type RefDescriptor as R, ScanBuilder as S, DEFAULT_JOIN_MAX_ROWS as a, type JoinLeg as b, type JoinStrategy as c, type JoinableSource as d, type LiveUpstream as e, type QueryPlan as f, type QuerySource as g, RefIntegrityError as h, type RefMode as i, RefRegistry as j, RefScopeError as k, type RefViolation as l, type ScanPageProvider as m, applyJoins as n, buildLiveQuery as o, executePlan as p, isRefArray as q, ref as r, refArray as s, resetJoinWarnings as t };