@noy-db/hub 0.7.1-pre.0 → 0.8.0

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 (812) hide show
  1. package/CHANGELOG.md +147 -14
  2. package/LICENSE +202 -21
  3. package/NOTICE +1 -0
  4. package/README.md +5 -5
  5. package/codemods/0.8.0-pre.json +61 -0
  6. package/dist/api-OS747DS4.js +18 -0
  7. package/dist/as/index.js +11 -12
  8. package/dist/as/index.js.map +1 -1
  9. package/dist/at/index.js +9 -10
  10. package/dist/attestation/index.js +37 -26
  11. package/dist/attestation/index.js.map +1 -1
  12. package/dist/{backup-XKCXVKV3.js → backup-YE2VQ26S.js} +15 -16
  13. package/dist/backup-YE2VQ26S.js.map +1 -0
  14. package/dist/blobs/index.js +13 -14
  15. package/dist/blobs/index.js.map +1 -1
  16. package/dist/broker/index.js +12 -13
  17. package/dist/broker/index.js.map +1 -1
  18. package/dist/by/index.js +2 -2
  19. package/dist/capsule/contract.d.ts +159 -0
  20. package/dist/capsule/contract.js +95 -0
  21. package/dist/capsule/enclave-aes/bound.d.ts +52 -0
  22. package/dist/capsule/enclave-aes/capabilities.d.ts +2 -0
  23. package/dist/capsule/enclave-aes/classify/compare.d.ts +20 -0
  24. package/dist/{kernel/enclave → capsule/enclave-aes}/classify/find.d.ts +1 -1
  25. package/dist/{kernel/enclave → capsule/enclave-aes}/classify/reveal.d.ts +1 -1
  26. package/dist/{kernel/enclave → capsule/enclave-aes}/classify/verify.d.ts +2 -2
  27. package/dist/{kernel/enclave → capsule/enclave-aes}/classify/write.d.ts +1 -1
  28. package/dist/{kernel/enclave → capsule/enclave-aes}/crypto.d.ts +33 -129
  29. package/dist/capsule/enclave-aes/index.d.ts +113 -0
  30. package/dist/capsule/enclave-aes/index.js +335 -0
  31. package/dist/capsule/enclave-aes/index.js.map +1 -0
  32. package/dist/capsule/enclave-aes/primitives.d.ts +29 -0
  33. package/dist/capsule/index.d.ts +27 -0
  34. package/dist/capsule/plumbing/ct-equal.d.ts +11 -0
  35. package/dist/{kernel/enclave/record-keys → capsule/plumbing}/deterministic.d.ts +8 -21
  36. package/dist/capsule/plumbing/digest.d.ts +122 -0
  37. package/dist/{kernel/enclave/record-keys → capsule/plumbing}/envelope-body.d.ts +44 -48
  38. package/dist/capsule/plumbing/index.d.ts +100 -0
  39. package/dist/capsule/plumbing/lifecycle.d.ts +50 -0
  40. package/dist/{kernel/enclave/record-keys → capsule/plumbing}/record-codec.d.ts +80 -20
  41. package/dist/{kernel/enclave → capsule/plumbing}/record-envelope.d.ts +1 -1
  42. package/dist/capsule/plumbing/rekey-blob.d.ts +33 -0
  43. package/dist/capsule/plumbing/rekey.d.ts +44 -0
  44. package/dist/capsule/plumbing/sealed-slot.d.ts +22 -0
  45. package/dist/capsule/plumbing/sealed-slots.d.ts +37 -0
  46. package/dist/capsule/plumbing/sealing.d.ts +29 -0
  47. package/dist/capsule/plumbing/sign.d.ts +9 -0
  48. package/dist/{kernel/enclave/record-keys → capsule/plumbing}/tombstone.d.ts +2 -2
  49. package/dist/capsule-VOLX3QRQ.js +209 -0
  50. package/dist/cargo/index.js +39 -36
  51. package/dist/{chunk-Q2MPFCQ7.js → chunk-23D6M6VM.js} +5 -5
  52. package/dist/chunk-23D6M6VM.js.map +1 -0
  53. package/dist/{chunk-R7BX2NB3.js → chunk-244QBK7Z.js} +4 -4
  54. package/dist/chunk-244QBK7Z.js.map +1 -0
  55. package/dist/chunk-2AFX33YA.js +936 -0
  56. package/dist/chunk-2AFX33YA.js.map +1 -0
  57. package/dist/{chunk-MVMXZYXT.js → chunk-2GHDLTPE.js} +2 -2
  58. package/dist/{chunk-GYGLAVCX.js → chunk-2MG3SW7Q.js} +6 -2
  59. package/dist/chunk-2MG3SW7Q.js.map +1 -0
  60. package/dist/{chunk-XLMEZIAJ.js → chunk-2ODVB6LZ.js} +2 -2
  61. package/dist/{chunk-HJUWN7JN.js → chunk-2PVXF5CS.js} +33 -8
  62. package/dist/chunk-2PVXF5CS.js.map +1 -0
  63. package/dist/{chunk-YJRT5UQM.js → chunk-2RH777HH.js} +21 -20
  64. package/dist/{chunk-YJRT5UQM.js.map → chunk-2RH777HH.js.map} +1 -1
  65. package/dist/{chunk-7O3Y4PPD.js → chunk-37EPTBBR.js} +153 -16
  66. package/dist/chunk-37EPTBBR.js.map +1 -0
  67. package/dist/{chunk-2ENE6445.js → chunk-3A5DUZ56.js} +102 -16
  68. package/dist/chunk-3A5DUZ56.js.map +1 -0
  69. package/dist/chunk-3EWS67C7.js +461 -0
  70. package/dist/chunk-3EWS67C7.js.map +1 -0
  71. package/dist/{chunk-SGZAIJCV.js → chunk-3L2NBKDR.js} +4 -8
  72. package/dist/chunk-3L2NBKDR.js.map +1 -0
  73. package/dist/{chunk-YMUFFJCO.js → chunk-3TDUWVWB.js} +5 -2
  74. package/dist/chunk-3TDUWVWB.js.map +1 -0
  75. package/dist/{chunk-4GVM6QZA.js → chunk-3XJQBBZD.js} +26 -28
  76. package/dist/chunk-3XJQBBZD.js.map +1 -0
  77. package/dist/{chunk-4ZS56W5S.js → chunk-42ALPZ2B.js} +672 -664
  78. package/dist/chunk-42ALPZ2B.js.map +1 -0
  79. package/dist/chunk-4CIQDWRB.js +524 -0
  80. package/dist/chunk-4CIQDWRB.js.map +1 -0
  81. package/dist/{chunk-RMS3NEA3.js → chunk-4JPMZTJY.js} +2 -2
  82. package/dist/{chunk-P3MG6QCN.js → chunk-4T3SE27M.js} +5 -9
  83. package/dist/chunk-4T3SE27M.js.map +1 -0
  84. package/dist/chunk-4V3Q35WG.js +204 -0
  85. package/dist/chunk-4V3Q35WG.js.map +1 -0
  86. package/dist/{chunk-NQKIUNW5.js → chunk-52MGURXO.js} +2 -2
  87. package/dist/{chunk-EQEYOJBM.js → chunk-5A4345TG.js} +4 -4
  88. package/dist/chunk-5A4345TG.js.map +1 -0
  89. package/dist/{chunk-334WSVOW.js → chunk-5FE75J4S.js} +6 -6
  90. package/dist/chunk-5FE75J4S.js.map +1 -0
  91. package/dist/chunk-5KC7QYEC.js +565 -0
  92. package/dist/chunk-5KC7QYEC.js.map +1 -0
  93. package/dist/{chunk-RSGLUIO6.js → chunk-5UMK7GRI.js} +13 -12
  94. package/dist/chunk-5UMK7GRI.js.map +1 -0
  95. package/dist/chunk-5WWDGFOS.js +275 -0
  96. package/dist/chunk-5WWDGFOS.js.map +1 -0
  97. package/dist/{chunk-QPQUVOZ2.js → chunk-6QVKPHBF.js} +3 -5
  98. package/dist/chunk-6QVKPHBF.js.map +1 -0
  99. package/dist/{chunk-ACAQ2DSG.js → chunk-747G6CT3.js} +2 -2
  100. package/dist/chunk-747G6CT3.js.map +1 -0
  101. package/dist/{chunk-QTQUH4DS.js → chunk-7R2Q7CPL.js} +16 -16
  102. package/dist/chunk-7R2Q7CPL.js.map +1 -0
  103. package/dist/{chunk-UGTBXF5U.js → chunk-7XMHMVTS.js} +3 -3
  104. package/dist/{chunk-YJX7EOJD.js → chunk-A4XMIZT3.js} +6 -6
  105. package/dist/{chunk-YJX7EOJD.js.map → chunk-A4XMIZT3.js.map} +1 -1
  106. package/dist/{chunk-A66I4JOA.js → chunk-AEQGFRU4.js} +4 -4
  107. package/dist/chunk-AEQGFRU4.js.map +1 -0
  108. package/dist/chunk-AL6ML4LA.js +1558 -0
  109. package/dist/chunk-AL6ML4LA.js.map +1 -0
  110. package/dist/{chunk-BZ3534YM.js → chunk-AUKKUPVB.js} +2 -2
  111. package/dist/{chunk-CUZLNGD5.js → chunk-B2YY6WDD.js} +1 -1
  112. package/dist/chunk-B2YY6WDD.js.map +1 -0
  113. package/dist/chunk-BKT776R5.js +1 -0
  114. package/dist/chunk-BNWA3WG5.js +22 -0
  115. package/dist/chunk-BNWA3WG5.js.map +1 -0
  116. package/dist/{chunk-VXANTWBJ.js → chunk-BPWYQ25R.js} +92 -6
  117. package/dist/{chunk-VXANTWBJ.js.map → chunk-BPWYQ25R.js.map} +1 -1
  118. package/dist/{chunk-6LKOJBV6.js → chunk-BVCUTXE3.js} +2 -2
  119. package/dist/chunk-CY2CYVWZ.js +41 -0
  120. package/dist/chunk-CY2CYVWZ.js.map +1 -0
  121. package/dist/{chunk-M4YPHYEH.js → chunk-DHHGL42E.js} +70 -25
  122. package/dist/chunk-DHHGL42E.js.map +1 -0
  123. package/dist/{chunk-VTFVLCUH.js → chunk-DIZLQVAA.js} +2 -2
  124. package/dist/{chunk-G73UVHCA.js → chunk-DLD5LGDS.js} +11 -12
  125. package/dist/chunk-DLD5LGDS.js.map +1 -0
  126. package/dist/{chunk-WQBG4SZS.js → chunk-DQESF6RP.js} +60 -49
  127. package/dist/chunk-DQESF6RP.js.map +1 -0
  128. package/dist/{chunk-LWBCUYZW.js → chunk-E2N2T5ZO.js} +2 -2
  129. package/dist/{chunk-3PGS7TYR.js → chunk-EGVJ7TM4.js} +29 -32
  130. package/dist/chunk-EGVJ7TM4.js.map +1 -0
  131. package/dist/{chunk-JVIBCBC7.js → chunk-EJLV62NI.js} +2 -2
  132. package/dist/{chunk-KKEESNPE.js → chunk-EYG2CY2X.js} +126 -19
  133. package/dist/chunk-EYG2CY2X.js.map +1 -0
  134. package/dist/{enclave-55PAM4YO.js → chunk-EZGV6F47.js} +83 -56
  135. package/dist/chunk-EZGV6F47.js.map +1 -0
  136. package/dist/{chunk-CHQCZZWC.js → chunk-EZOAKKTB.js} +36 -27
  137. package/dist/chunk-EZOAKKTB.js.map +1 -0
  138. package/dist/chunk-F6NCB7KT.js +13 -0
  139. package/dist/chunk-F6NCB7KT.js.map +1 -0
  140. package/dist/chunk-FFJFE4T7.js +100 -0
  141. package/dist/chunk-FFJFE4T7.js.map +1 -0
  142. package/dist/{chunk-JMGDHKQF.js → chunk-FLPCETP6.js} +2 -2
  143. package/dist/chunk-FOEDQATO.js +53 -0
  144. package/dist/chunk-FOEDQATO.js.map +1 -0
  145. package/dist/{chunk-DGOZ4UZD.js → chunk-FVH5QYY2.js} +2 -2
  146. package/dist/{chunk-HIWCKBEY.js → chunk-G2MVBDFP.js} +54 -28
  147. package/dist/chunk-G2MVBDFP.js.map +1 -0
  148. package/dist/chunk-GMKGGY7V.js +234 -0
  149. package/dist/chunk-GMKGGY7V.js.map +1 -0
  150. package/dist/{chunk-EIPVYUEP.js → chunk-GQ4MF3CM.js} +3 -3
  151. package/dist/chunk-GQ4MF3CM.js.map +1 -0
  152. package/dist/{chunk-PEOZ34EM.js → chunk-GSAK56VF.js} +1 -1
  153. package/dist/chunk-GSAK56VF.js.map +1 -0
  154. package/dist/{chunk-5VCRVKOZ.js → chunk-GUZET4SG.js} +12 -4
  155. package/dist/chunk-GUZET4SG.js.map +1 -0
  156. package/dist/{chunk-JBDFMYKQ.js → chunk-GZT3NQRA.js} +2 -2
  157. package/dist/{chunk-K23VKTN4.js → chunk-H23XHRTT.js} +19 -34
  158. package/dist/chunk-H23XHRTT.js.map +1 -0
  159. package/dist/{chunk-TFR7DSOV.js → chunk-H427H63K.js} +2 -2
  160. package/dist/{chunk-DFMWUOU5.js → chunk-H7JBY4P7.js} +23 -32
  161. package/dist/chunk-H7JBY4P7.js.map +1 -0
  162. package/dist/{chunk-SKGMN35F.js → chunk-HS554XAF.js} +3 -3
  163. package/dist/chunk-HS554XAF.js.map +1 -0
  164. package/dist/{chunk-HK67PX4J.js → chunk-HW7CMKUG.js} +1 -1
  165. package/dist/chunk-HW7CMKUG.js.map +1 -0
  166. package/dist/{chunk-3BVH633C.js → chunk-IMQKWR46.js} +5 -7
  167. package/dist/chunk-IMQKWR46.js.map +1 -0
  168. package/dist/{chunk-R42NSZI6.js → chunk-IUBMZPHM.js} +7 -7
  169. package/dist/chunk-IUBMZPHM.js.map +1 -0
  170. package/dist/{chunk-CUQPWYRX.js → chunk-IUT3GWP3.js} +75 -386
  171. package/dist/chunk-IUT3GWP3.js.map +1 -0
  172. package/dist/{chunk-RF6D3Y5E.js → chunk-JDEYF3PJ.js} +4 -8
  173. package/dist/{chunk-RF6D3Y5E.js.map → chunk-JDEYF3PJ.js.map} +1 -1
  174. package/dist/{chunk-PPTHY5QO.js → chunk-JIBUPZHA.js} +99 -8
  175. package/dist/chunk-JIBUPZHA.js.map +1 -0
  176. package/dist/{chunk-SMH6SRX7.js → chunk-JOSPH3E5.js} +2 -2
  177. package/dist/chunk-JQYKPKG6.js +193 -0
  178. package/dist/chunk-JQYKPKG6.js.map +1 -0
  179. package/dist/{chunk-7APJ6CO6.js → chunk-JSMTXZR3.js} +45 -13
  180. package/dist/chunk-JSMTXZR3.js.map +1 -0
  181. package/dist/chunk-JWWYRR4Q.js +12 -0
  182. package/dist/chunk-JWWYRR4Q.js.map +1 -0
  183. package/dist/{chunk-BVN6KXL2.js → chunk-KZXDLBY6.js} +14 -9
  184. package/dist/chunk-KZXDLBY6.js.map +1 -0
  185. package/dist/chunk-LGNDFRYC.js +23 -0
  186. package/dist/chunk-LGNDFRYC.js.map +1 -0
  187. package/dist/{chunk-XKWGNJ26.js → chunk-LIOVX5TJ.js} +7 -11
  188. package/dist/chunk-LIOVX5TJ.js.map +1 -0
  189. package/dist/{chunk-AYX7AINO.js → chunk-LNSVGRHO.js} +5 -7
  190. package/dist/chunk-LNSVGRHO.js.map +1 -0
  191. package/dist/chunk-M5B2W6YY.js +293 -0
  192. package/dist/chunk-M5B2W6YY.js.map +1 -0
  193. package/dist/chunk-MBMTND6D.js +456 -0
  194. package/dist/chunk-MBMTND6D.js.map +1 -0
  195. package/dist/{chunk-3BZZJJMQ.js → chunk-MILI22XQ.js} +3 -3
  196. package/dist/{chunk-A2HKRLPV.js → chunk-MXKI4ABF.js} +18 -59
  197. package/dist/chunk-MXKI4ABF.js.map +1 -0
  198. package/dist/{chunk-ZYIYHJ5R.js → chunk-MXOQ5JCG.js} +869 -238
  199. package/dist/chunk-MXOQ5JCG.js.map +1 -0
  200. package/dist/{chunk-V7ZRRCRJ.js → chunk-N7EVQD5S.js} +9 -13
  201. package/dist/chunk-N7EVQD5S.js.map +1 -0
  202. package/dist/chunk-N7UDP5VU.js +757 -0
  203. package/dist/chunk-N7UDP5VU.js.map +1 -0
  204. package/dist/chunk-NBQ3KK6X.js +270 -0
  205. package/dist/chunk-NBQ3KK6X.js.map +1 -0
  206. package/dist/{chunk-ZORTV6NH.js → chunk-NCO25JZO.js} +88 -4
  207. package/dist/chunk-NCO25JZO.js.map +1 -0
  208. package/dist/chunk-NH2UOV3B.js +18 -0
  209. package/dist/chunk-NH2UOV3B.js.map +1 -0
  210. package/dist/chunk-NYMLINRP.js +28 -0
  211. package/dist/chunk-NYMLINRP.js.map +1 -0
  212. package/dist/{chunk-YYP7WSEB.js → chunk-O2IMQSNA.js} +2 -2
  213. package/dist/chunk-O46CHQT7.js +215 -0
  214. package/dist/chunk-O46CHQT7.js.map +1 -0
  215. package/dist/chunk-OIEO4WDL.js +27 -0
  216. package/dist/chunk-OIEO4WDL.js.map +1 -0
  217. package/dist/{chunk-TRGTKX5E.js → chunk-OKSTSITU.js} +27 -4
  218. package/dist/chunk-OKSTSITU.js.map +1 -0
  219. package/dist/chunk-OYW3I5M4.js +31 -0
  220. package/dist/chunk-OYW3I5M4.js.map +1 -0
  221. package/dist/{chunk-Q7HZX3IF.js → chunk-PD64727P.js} +2 -2
  222. package/dist/chunk-PD64727P.js.map +1 -0
  223. package/dist/{chunk-FET5XCAT.js → chunk-PP3K67AJ.js} +34 -6
  224. package/dist/chunk-PP3K67AJ.js.map +1 -0
  225. package/dist/chunk-Q2XRFWOI.js +40 -0
  226. package/dist/chunk-Q2XRFWOI.js.map +1 -0
  227. package/dist/{chunk-QIZPZMUI.js → chunk-Q4UHJ5SN.js} +2 -2
  228. package/dist/{chunk-FAHMLERK.js → chunk-QBLT6POL.js} +2 -2
  229. package/dist/chunk-QMWY2FDS.js +157 -0
  230. package/dist/chunk-QMWY2FDS.js.map +1 -0
  231. package/dist/{chunk-LH5A3ZPG.js → chunk-RB4DOPGZ.js} +150 -22
  232. package/dist/chunk-RB4DOPGZ.js.map +1 -0
  233. package/dist/chunk-RHVMZSUU.js +7 -0
  234. package/dist/chunk-RHVMZSUU.js.map +1 -0
  235. package/dist/{chunk-BUE2D7PX.js → chunk-SMV2HRDU.js} +2 -2
  236. package/dist/chunk-SUZKW6UR.js +25 -0
  237. package/dist/chunk-SUZKW6UR.js.map +1 -0
  238. package/dist/{chunk-7MG7SJT7.js → chunk-SV2PM2OY.js} +1 -1
  239. package/dist/chunk-SV2PM2OY.js.map +1 -0
  240. package/dist/{chunk-UXVWEX5L.js → chunk-SYNY3VB5.js} +6 -2
  241. package/dist/chunk-SYNY3VB5.js.map +1 -0
  242. package/dist/{chunk-4GFX6MPA.js → chunk-TEHHROZL.js} +6 -8
  243. package/dist/chunk-TEHHROZL.js.map +1 -0
  244. package/dist/chunk-TKVUE4JF.js +1289 -0
  245. package/dist/chunk-TKVUE4JF.js.map +1 -0
  246. package/dist/{chunk-SFAWCTEM.js → chunk-TZZBXPZK.js} +2 -2
  247. package/dist/{chunk-F3W6YMDC.js → chunk-U2FZNEWJ.js} +4 -4
  248. package/dist/chunk-U2FZNEWJ.js.map +1 -0
  249. package/dist/{chunk-BLN54W3L.js → chunk-UA372JHH.js} +56 -3
  250. package/dist/chunk-UA372JHH.js.map +1 -0
  251. package/dist/{chunk-6YXCPL4T.js → chunk-UEFOQH74.js} +2 -2
  252. package/dist/chunk-UEFOQH74.js.map +1 -0
  253. package/dist/{chunk-2N5ML6HT.js → chunk-UIYESRD6.js} +9 -11
  254. package/dist/chunk-UIYESRD6.js.map +1 -0
  255. package/dist/{chunk-UHHPLO3I.js → chunk-V3RWOOSO.js} +4 -4
  256. package/dist/{chunk-KTFRCC5C.js → chunk-V7ADQF5O.js} +82 -8
  257. package/dist/chunk-V7ADQF5O.js.map +1 -0
  258. package/dist/{chunk-453F654R.js → chunk-VAORSCSU.js} +3 -3
  259. package/dist/chunk-VAORSCSU.js.map +1 -0
  260. package/dist/{chunk-GPNTB4Y7.js → chunk-VFHCKG5M.js} +6 -10
  261. package/dist/chunk-VFHCKG5M.js.map +1 -0
  262. package/dist/{chunk-2577DKXB.js → chunk-VHBKYN2J.js} +3 -3
  263. package/dist/chunk-VHBKYN2J.js.map +1 -0
  264. package/dist/chunk-VHM7HCKB.js +220 -0
  265. package/dist/chunk-VHM7HCKB.js.map +1 -0
  266. package/dist/{chunk-ZHKOPKE3.js → chunk-VKI2EB3N.js} +3 -3
  267. package/dist/chunk-VKI2EB3N.js.map +1 -0
  268. package/dist/{chunk-UDHWDSRL.js → chunk-VMV5SBE4.js} +16 -17
  269. package/dist/chunk-VMV5SBE4.js.map +1 -0
  270. package/dist/{chunk-SPYWXKJN.js → chunk-VQDZYB2B.js} +3 -3
  271. package/dist/chunk-VQDZYB2B.js.map +1 -0
  272. package/dist/{chunk-Q2PU57HC.js → chunk-VVOLDVIR.js} +2 -2
  273. package/dist/{chunk-3VF3WQ4F.js → chunk-WPOYWFSE.js} +7 -7
  274. package/dist/{chunk-3VF3WQ4F.js.map → chunk-WPOYWFSE.js.map} +1 -1
  275. package/dist/{chunk-OTQZ7ZWU.js → chunk-WXE4W2U6.js} +7 -11
  276. package/dist/chunk-WXE4W2U6.js.map +1 -0
  277. package/dist/chunk-XBKH4FOC.js +195 -0
  278. package/dist/chunk-XBKH4FOC.js.map +1 -0
  279. package/dist/{chunk-TUFM4UZP.js → chunk-XQRFSKYM.js} +2 -2
  280. package/dist/{chunk-3V4KWFX7.js → chunk-XSPFDUDG.js} +58 -53
  281. package/dist/chunk-XSPFDUDG.js.map +1 -0
  282. package/dist/{chunk-GY4WYNNG.js → chunk-Y2RKVFKR.js} +2 -2
  283. package/dist/{chunk-UP4BECPY.js → chunk-Y3LPTBG7.js} +89 -27
  284. package/dist/chunk-Y3LPTBG7.js.map +1 -0
  285. package/dist/{chunk-4OZNXTO4.js → chunk-YRXFFWG4.js} +2 -2
  286. package/dist/classified/index.js +5 -5
  287. package/dist/{classified-marker-BWOFVYAC.js → classified-marker-SIYKUU5L.js} +3 -3
  288. package/dist/classified-marker-SIYKUU5L.js.map +1 -0
  289. package/dist/collection-facade-CS7CA2XO.js +47 -0
  290. package/dist/{computed-VPOKQK4N.js → computed-FAD7SED4.js} +3 -3
  291. package/dist/consent/index.js +10 -11
  292. package/dist/consent/index.js.map +1 -1
  293. package/dist/cover/index.js +10 -11
  294. package/dist/coverage/index.js +306 -0
  295. package/dist/coverage/index.js.map +1 -0
  296. package/dist/custody/index.js +12 -13
  297. package/dist/{dead-filter-PKQDLOT4.js → dead-filter-4F3LWYKH.js} +11 -3
  298. package/dist/dead-filter-4F3LWYKH.js.map +1 -0
  299. package/dist/debug/index.js +11 -2
  300. package/dist/debug/index.js.map +1 -1
  301. package/dist/{delegation-DS5NRILW.js → delegation-NANZDG4N.js} +13 -16
  302. package/dist/delegation-NANZDG4N.js.map +1 -0
  303. package/dist/derivations/index.js +25 -23
  304. package/dist/derive-XLOJVXPU.js +20 -0
  305. package/dist/directory/index.js +10 -11
  306. package/dist/{dispatch-IEPAVQUM.js → dispatch-H4HV32AM.js} +5 -5
  307. package/dist/{dispatch-Q6MWLOJY.js → dispatch-JDZNGEB3.js} +20 -21
  308. package/dist/dispatch-JDZNGEB3.js.map +1 -0
  309. package/dist/executor-FMPVN6DT.js +35 -0
  310. package/dist/executor-LBBBRTN5.js +8 -0
  311. package/dist/executor-OSRZST2U.js +8 -0
  312. package/dist/export-accessible-RAOJAAU5.js +22 -0
  313. package/dist/extract-partition-JD5CUSTG.js +37 -0
  314. package/dist/{fanout-sidecar-S3QL53YX.js → fanout-sidecar-L7NHPIOC.js} +13 -15
  315. package/dist/fanout-sidecar-L7NHPIOC.js.map +1 -0
  316. package/dist/find-JRN4RNQ5.js +10 -0
  317. package/dist/forget/index.js +9 -10
  318. package/dist/forget/index.js.map +1 -1
  319. package/dist/guards/index.js +4 -4
  320. package/dist/history/index.js +13 -14
  321. package/dist/history/index.js.map +1 -1
  322. package/dist/i18n/index.js +14 -15
  323. package/dist/i18n/index.js.map +1 -1
  324. package/dist/index.d.ts +36 -14
  325. package/dist/index.js +970 -163
  326. package/dist/index.js.map +1 -1
  327. package/dist/indexing/index.js +13 -5
  328. package/dist/indexing/index.js.map +1 -1
  329. package/dist/introspection/index.js +11 -12
  330. package/dist/issue-YIVBZUTH.js +19 -0
  331. package/dist/ivf-flat-UZ6DQDLS.js +314 -0
  332. package/dist/ivf-flat-UZ6DQDLS.js.map +1 -0
  333. package/dist/{json-schema-V3M5MUCM.js → json-schema-3SHX72CC.js} +2 -1
  334. package/dist/json-schema-3SHX72CC.js.map +1 -0
  335. package/dist/kernel/attestation-types.d.ts +62 -0
  336. package/dist/kernel/collection-config.d.ts +5 -68
  337. package/dist/kernel/collection.d.ts +30 -9
  338. package/dist/kernel/cutover-transform.d.ts +1 -1
  339. package/dist/kernel/errors.d.ts +257 -38
  340. package/dist/kernel/generation-map.d.ts +48 -0
  341. package/dist/kernel/merge-authority.d.ts +1 -1
  342. package/dist/kernel/noydb.d.ts +6 -1
  343. package/dist/kernel/paths.d.ts +29 -5
  344. package/dist/kernel/prepared-write.d.ts +1 -1
  345. package/dist/kernel/present-cache.d.ts +58 -0
  346. package/dist/kernel/query/all.d.ts +7 -0
  347. package/dist/kernel/query/builder.d.ts +601 -270
  348. package/dist/kernel/query/civil-date.d.ts +64 -0
  349. package/dist/kernel/query/cursor.d.ts +40 -0
  350. package/dist/kernel/query/distinct-key.d.ts +98 -0
  351. package/dist/kernel/query/hydration.d.ts +76 -0
  352. package/dist/kernel/query/index.d.ts +31 -15
  353. package/dist/kernel/query/internal/core.d.ts +30 -0
  354. package/dist/kernel/query/internal/hooks.d.ts +22 -0
  355. package/dist/kernel/query/internal/maintenance.d.ts +43 -0
  356. package/dist/kernel/query/live/incremental.d.ts +314 -0
  357. package/dist/kernel/query/live/index.d.ts +22 -0
  358. package/dist/kernel/query/live/install.d.ts +2 -0
  359. package/dist/kernel/query/{live.d.ts → live/live.d.ts} +39 -9
  360. package/dist/kernel/query/live/methods.d.ts +107 -0
  361. package/dist/kernel/query/predicate.d.ts +119 -1
  362. package/dist/kernel/query/reduce/date-trunc.d.ts +75 -0
  363. package/dist/kernel/query/reduce/index.d.ts +36 -0
  364. package/dist/kernel/query/reduce/install.d.ts +2 -0
  365. package/dist/kernel/query/reduce/methods.d.ts +259 -0
  366. package/dist/kernel/query/reduce/scan-methods.d.ts +121 -0
  367. package/dist/kernel/query/relate/explain.d.ts +199 -0
  368. package/dist/kernel/query/relate/index.d.ts +48 -0
  369. package/dist/kernel/query/relate/install.d.ts +2 -0
  370. package/dist/kernel/query/relate/join-on.d.ts +126 -0
  371. package/dist/kernel/query/relate/join-reduce.d.ts +16 -0
  372. package/dist/kernel/query/relate/join.d.ts +452 -0
  373. package/dist/kernel/query/relate/methods.d.ts +426 -0
  374. package/dist/kernel/query/relate/partition.d.ts +87 -0
  375. package/dist/kernel/query/relate/scan-methods.d.ts +163 -0
  376. package/dist/kernel/query/relate/traverse.d.ts +109 -0
  377. package/dist/kernel/query/scan-builder.d.ts +79 -176
  378. package/dist/kernel/query/sort-key.d.ts +52 -0
  379. package/dist/kernel/secret-mode.d.ts +1 -1
  380. package/dist/kernel/tx-write-gate.d.ts +77 -0
  381. package/dist/kernel/types.d.ts +113 -8
  382. package/dist/kernel/validation.d.ts +27 -10
  383. package/dist/kernel/vault.d.ts +11 -6
  384. package/dist/kernel/via/compose.d.ts +3 -0
  385. package/dist/kernel/via/index.d.ts +56 -0
  386. package/dist/kernel/via/pipeline.d.ts +48 -0
  387. package/dist/kernel/write-queue.d.ts +17 -0
  388. package/dist/{ledger-EDXFFZQL.js → ledger-5ZMGE44K.js} +11 -12
  389. package/dist/liberate-WZSZM2W6.js +24 -0
  390. package/dist/link-set-MFXC24VK.js +29 -0
  391. package/dist/{managed-secret-NCWEMPUQ.js → managed-secret-MFTFT22X.js} +10 -11
  392. package/dist/materialized-views/index.js +30 -24
  393. package/dist/{migrate-cek-5ENH64AA.js → migrate-cek-DZRFFOHW.js} +2 -2
  394. package/dist/money/index.js +5 -5
  395. package/dist/noydb-ITIGNKUF.js +96 -0
  396. package/dist/overlay-views/index.js +4 -4
  397. package/dist/periods/index.js +12 -13
  398. package/dist/pod/index.js +74 -67
  399. package/dist/{pod-handle-ECVCDIXW.js → pod-handle-A3LET7NO.js} +10 -11
  400. package/dist/pod-handle-A3LET7NO.js.map +1 -0
  401. package/dist/policy/index.js +10 -11
  402. package/dist/port/on/index.d.ts +1 -1
  403. package/dist/port/to/index.d.ts +1 -1
  404. package/dist/port/with/blob-strategy.d.ts +10 -1
  405. package/dist/port/with/classified-strategy.d.ts +1 -1
  406. package/dist/port/with/collection-options.d.ts +6 -1
  407. package/dist/port/with/collection-registries.d.ts +1 -1
  408. package/dist/port/with/coverage-strategy.d.ts +83 -0
  409. package/dist/port/with/lookup-strategy.d.ts +2 -2
  410. package/dist/port/with/service-bus.d.ts +46 -0
  411. package/dist/port/with/strategies.d.ts +2 -0
  412. package/dist/portability/index.js +8 -8
  413. package/dist/{post-register-3IPCSG6Q.js → post-register-7ND27CF2.js} +6 -6
  414. package/dist/post-register-7ND27CF2.js.map +1 -0
  415. package/dist/query/all/index.js +31 -0
  416. package/dist/query/index.js +20 -32
  417. package/dist/query/live/index.js +21 -0
  418. package/dist/query/live/index.js.map +1 -0
  419. package/dist/query/reduce/index.js +33 -0
  420. package/dist/query/reduce/index.js.map +1 -0
  421. package/dist/query/relate/index.js +56 -0
  422. package/dist/query/relate/index.js.map +1 -0
  423. package/dist/reduce/index.js +72 -18
  424. package/dist/reduce/index.js.map +1 -1
  425. package/dist/register-DT5HZ2LZ.js +30 -0
  426. package/dist/registry-BHRZGZHF.js +8 -0
  427. package/dist/registry-ET6ZFFWA.js +34 -0
  428. package/dist/registry-HXFGLGTG.js +8 -0
  429. package/dist/registry-THCPDEOD.js +23 -0
  430. package/dist/request-withdrawal-AV2MJJKY.js +30 -0
  431. package/dist/{reveal-QZDHSGD4.js → reveal-B2TLP4JQ.js} +10 -9
  432. package/dist/reveal-B2TLP4JQ.js.map +1 -0
  433. package/dist/revoke-6DWIEOCV.js +24 -0
  434. package/dist/satellites/index.js +1 -1
  435. package/dist/schema-update/index.js +2 -2
  436. package/dist/sealed-record/index.js +16 -18
  437. package/dist/sealed-record/index.js.map +1 -1
  438. package/dist/search/index.js +11 -5
  439. package/dist/{seed-X5CC22CQ.js → seed-XNSE4U3S.js} +15 -18
  440. package/dist/seed-XNSE4U3S.js.map +1 -0
  441. package/dist/sequence/index.js +9 -10
  442. package/dist/session/index.js +9 -10
  443. package/dist/session/index.js.map +1 -1
  444. package/dist/shadow/index.js +2 -2
  445. package/dist/signer-MHGW3OIL.js +23 -0
  446. package/dist/snapshots/index.js +11 -11
  447. package/dist/stale-6GCFMOOR.js +28 -0
  448. package/dist/storage-BYN5LO6Z.js +21 -0
  449. package/dist/storage-BYN5LO6Z.js.map +1 -0
  450. package/dist/store/index.js +1 -1
  451. package/dist/{store-coordination-provider-4WZAIRHC.js → store-coordination-provider-C4BPT5XF.js} +11 -12
  452. package/dist/store-coordination-provider-C4BPT5XF.js.map +1 -0
  453. package/dist/sync/index.js +10 -11
  454. package/dist/sync/index.js.map +1 -1
  455. package/dist/team/index.js +17 -16
  456. package/dist/tiers/index.js +13 -12
  457. package/dist/to/index.js +2 -2
  458. package/dist/transactions/index.js +3 -3
  459. package/dist/util/index.js +1 -1
  460. package/dist/vault-head/index.js +11 -14
  461. package/dist/vault-head/index.js.map +1 -1
  462. package/dist/{verify-6MDTIUEV.js → verify-UKALW7C2.js} +14 -12
  463. package/dist/verify-UKALW7C2.js.map +1 -0
  464. package/dist/via/blob/index.d.ts +1 -0
  465. package/dist/via/classified/binding.d.ts +2 -2
  466. package/dist/via/classified/config-drift.d.ts +2 -2
  467. package/dist/via/classified/errors.d.ts +1 -1
  468. package/dist/via/geo/binding.d.ts +31 -0
  469. package/dist/via/geo/descriptor.d.ts +54 -0
  470. package/dist/via/geo/geohash.d.ts +95 -0
  471. package/dist/via/geo/index.d.ts +13 -0
  472. package/dist/via/geo/where.d.ts +50 -0
  473. package/dist/via/i18n/core.d.ts +1 -1
  474. package/dist/via/lookup/handle.d.ts +4 -4
  475. package/dist/via/lookup/registry.d.ts +1 -1
  476. package/dist/via/lookup/snapshot.d.ts +3 -3
  477. package/dist/walk-4VPK7AS4.js +20 -0
  478. package/dist/walk-4VPK7AS4.js.map +1 -0
  479. package/dist/with-audit/attestation/index.d.ts +2 -1
  480. package/dist/with-audit/attestation/issue.d.ts +2 -2
  481. package/dist/with-audit/attestation/revoke.d.ts +2 -2
  482. package/dist/with-audit/attestation/scheme.d.ts +7 -0
  483. package/dist/with-audit/attestation/signer.d.ts +1 -1
  484. package/dist/with-audit/attestation/strategy.d.ts +2 -2
  485. package/dist/with-audit/attestation/types.d.ts +10 -0
  486. package/dist/with-audit/attestation/vault-facade.d.ts +2 -2
  487. package/dist/with-audit/attestation/verifier.d.ts +6 -0
  488. package/dist/with-audit/consent/consent.d.ts +1 -1
  489. package/dist/with-audit/consent/strategy.d.ts +1 -1
  490. package/dist/with-audit/coverage/accounting.d.ts +112 -0
  491. package/dist/with-audit/coverage/active.d.ts +29 -0
  492. package/dist/with-audit/coverage/index.d.ts +61 -0
  493. package/dist/with-audit/coverage/sketch.d.ts +75 -0
  494. package/dist/with-audit/forget/subject-index.d.ts +1 -1
  495. package/dist/with-audit/periods/periods.d.ts +55 -7
  496. package/dist/with-audit/periods/reserved-collections.d.ts +3 -0
  497. package/dist/with-audit/periods/vault-facade.d.ts +18 -1
  498. package/dist/with-audit/sealed-record/index.d.ts +2 -2
  499. package/dist/with-audit/sealed-record/strategy.d.ts +1 -1
  500. package/dist/with-audit/tiers/index.d.ts +53 -2
  501. package/dist/with-audit/tiers/strategy.d.ts +8 -0
  502. package/dist/with-cargo/adopt-partition.d.ts +1 -1
  503. package/dist/with-cargo/extract-partition.d.ts +1 -1
  504. package/dist/with-cargo/floor.d.ts +3 -3
  505. package/dist/with-commit/history/history.d.ts +2 -2
  506. package/dist/with-commit/history/index.d.ts +1 -1
  507. package/dist/with-commit/history/ledger/store.d.ts +1 -1
  508. package/dist/with-commit/history/strategy.d.ts +1 -1
  509. package/dist/with-commit/history/time-machine.d.ts +1 -1
  510. package/dist/with-commit/numbering/index.d.ts +1 -1
  511. package/dist/with-commit/sequence/index.d.ts +1 -1
  512. package/dist/with-commit/tx/invariants.d.ts +1 -1
  513. package/dist/with-commit/tx/transaction.d.ts +13 -3
  514. package/dist/with-commit/vault-head/head.d.ts +1 -1
  515. package/dist/with-commit/vault-head/index.d.ts +1 -1
  516. package/dist/with-commit/vault-head/strategy.d.ts +1 -1
  517. package/dist/with-commit/vault-head/verify.d.ts +1 -1
  518. package/dist/with-formula/derivations/dispatch.d.ts +1 -1
  519. package/dist/with-formula/derivations/fanout-sidecar.d.ts +1 -1
  520. package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +4 -3
  521. package/dist/with-formula/materialized-views/emit-memo.d.ts +40 -0
  522. package/dist/with-formula/materialized-views/executor.d.ts +8 -0
  523. package/dist/with-formula/materialized-views/index.d.ts +1 -1
  524. package/dist/with-formula/materialized-views/registry.d.ts +15 -0
  525. package/dist/with-formula/materialized-views/types.d.ts +106 -14
  526. package/dist/with-formula/materialized-views/window-stage.d.ts +11 -0
  527. package/dist/with-formula/overlay-views/types.d.ts +1 -1
  528. package/dist/with-formula/overlay-views/virtual-collection.d.ts +13 -4
  529. package/dist/with-lookup/embeddings/chunks.d.ts +79 -0
  530. package/dist/with-lookup/embeddings/descriptor.d.ts +21 -0
  531. package/dist/with-lookup/embeddings/index.d.ts +3 -0
  532. package/dist/with-lookup/embeddings/ivf-flat.d.ts +93 -0
  533. package/dist/with-lookup/embeddings/vector-index.d.ts +73 -0
  534. package/dist/with-lookup/embeddings/vector-set.d.ts +94 -1
  535. package/dist/with-lookup/embeddings/with-vector-index.d.ts +67 -0
  536. package/dist/with-lookup/indexing/collection-facade.d.ts +86 -3
  537. package/dist/with-lookup/indexing/compound-indexes.d.ts +129 -0
  538. package/dist/with-lookup/indexing/eager-indexes.d.ts +170 -1
  539. package/dist/with-lookup/indexing/index-snapshot.d.ts +62 -0
  540. package/dist/with-lookup/indexing/lazy-builder.d.ts +33 -0
  541. package/dist/with-lookup/indexing/persisted-field-indexes.d.ts +104 -0
  542. package/dist/with-lookup/indexing/persisted-indexes.d.ts +12 -0
  543. package/dist/with-lookup/indexing/sorted-indexes.d.ts +117 -0
  544. package/dist/with-lookup/indexing/unique-constraints.d.ts +106 -23
  545. package/dist/with-lookup/reduce/active.d.ts +2 -24
  546. package/dist/with-lookup/reduce/group-core.d.ts +43 -0
  547. package/dist/with-lookup/reduce/groupby.d.ts +195 -36
  548. package/dist/with-lookup/reduce/incremental-group.d.ts +153 -0
  549. package/dist/with-lookup/reduce/index.d.ts +26 -5
  550. package/dist/with-lookup/reduce/reducers.d.ts +255 -1
  551. package/dist/with-lookup/reduce/reduction.d.ts +44 -13
  552. package/dist/with-lookup/reduce/strategy.d.ts +43 -3
  553. package/dist/with-lookup/reduce/window.d.ts +262 -0
  554. package/dist/with-lookup/search/collection-facade.d.ts +45 -9
  555. package/dist/with-lookup/search/index-store.d.ts +5 -3
  556. package/dist/with-lookup/search/index.d.ts +4 -2
  557. package/dist/with-lookup/search/inverted-index.d.ts +38 -2
  558. package/dist/with-lookup/search/persisted-index-store.d.ts +5 -2
  559. package/dist/with-lookup/search/phrase.d.ts +28 -0
  560. package/dist/with-lookup/search/retrieve-types.d.ts +57 -1
  561. package/dist/with-lookup/search/serialize.d.ts +29 -3
  562. package/dist/with-lookup/search/strategy.d.ts +2 -6
  563. package/dist/with-party/broker/index.d.ts +3 -3
  564. package/dist/with-party/directory/cover/index.d.ts +1 -1
  565. package/dist/with-party/directory/cover/storage.d.ts +1 -1
  566. package/dist/with-party/directory/cover/types.d.ts +1 -1
  567. package/dist/with-party/directory/index.d.ts +1 -1
  568. package/dist/with-party/directory/types.d.ts +1 -1
  569. package/dist/with-party/directory/user-envelope/api.d.ts +1 -1
  570. package/dist/with-party/directory/user-envelope/storage.d.ts +1 -1
  571. package/dist/with-party/policy/engine.d.ts +1 -1
  572. package/dist/with-party/policy/index.d.ts +1 -1
  573. package/dist/with-party/policy/presets.d.ts +1 -1
  574. package/dist/with-party/team/authenticators.d.ts +91 -1
  575. package/dist/with-party/team/delegation.d.ts +1 -1
  576. package/dist/with-party/team/echo-secret.d.ts +2 -2
  577. package/dist/with-party/team/index.d.ts +4 -3
  578. package/dist/with-party/team/keyring.d.ts +2 -2
  579. package/dist/with-party/team/magic-link-grant.d.ts +1 -1
  580. package/dist/with-party/team/managed-secret.d.ts +1 -1
  581. package/dist/with-party/team/noydb-facade.d.ts +12 -3
  582. package/dist/with-party/team/recovery.d.ts +1 -1
  583. package/dist/with-party/team/roster-tag.d.ts +1 -1
  584. package/dist/with-party/team/rotate-recover.d.ts +1 -1
  585. package/dist/with-party/team/wrapped-deks.d.ts +1 -1
  586. package/dist/with-pod/format.d.ts +1 -1
  587. package/dist/with-pod/index.d.ts +1 -1
  588. package/dist/with-pod/pod.d.ts +1 -1
  589. package/dist/with-shape/blobs/blob-compaction.d.ts +17 -1
  590. package/dist/with-shape/blobs/blob-intent.d.ts +1 -1
  591. package/dist/with-shape/blobs/blob-set.d.ts +23 -4
  592. package/dist/with-shape/blobs/legacy-sweep.d.ts +35 -0
  593. package/dist/with-shape/introspection/describe.d.ts +7 -1
  594. package/dist/with-shape/introspection/field-meta.d.ts +18 -0
  595. package/dist/with-shape/introspection/types.d.ts +57 -1
  596. package/dist/with-shape/introspection/walk.d.ts +1 -1
  597. package/dist/with-shape/links/lazy-handle.d.ts +1 -1
  598. package/dist/with-shape/links/link-set.d.ts +1 -1
  599. package/dist/with-shape/links/vault-facade.d.ts +1 -1
  600. package/dist/with-shape/manifest/derive.d.ts +1 -1
  601. package/dist/with-shape/manifest/storage.d.ts +1 -1
  602. package/dist/with-shape/persisted-schemas/register.d.ts +1 -1
  603. package/dist/with-shape/persisted-schemas/storage.d.ts +1 -1
  604. package/dist/with-shape/satellites/dead-filter.d.ts +1 -1
  605. package/dist/with-shape/satellites/declare.d.ts +1 -1
  606. package/dist/with-shape/satellites/marker.d.ts +1 -1
  607. package/dist/with-shape/satellites/post-register.d.ts +1 -1
  608. package/dist/with-store/partitioned/index.d.ts +337 -0
  609. package/dist/with-sync/change-broadcast.d.ts +153 -0
  610. package/dist/with-sync/presence.d.ts +5 -10
  611. package/dist/withdraw-accessible-HL7GACUE.js +27 -0
  612. package/dist/withdraw-accessible-HL7GACUE.js.map +1 -0
  613. package/package.json +48 -12
  614. package/dist/api-WYW4YEQG.js +0 -19
  615. package/dist/backup-XKCXVKV3.js.map +0 -1
  616. package/dist/chunk-2577DKXB.js.map +0 -1
  617. package/dist/chunk-2ENE6445.js.map +0 -1
  618. package/dist/chunk-2N5ML6HT.js.map +0 -1
  619. package/dist/chunk-334WSVOW.js.map +0 -1
  620. package/dist/chunk-3BVH633C.js.map +0 -1
  621. package/dist/chunk-3PGS7TYR.js.map +0 -1
  622. package/dist/chunk-3V4KWFX7.js.map +0 -1
  623. package/dist/chunk-453F654R.js.map +0 -1
  624. package/dist/chunk-4GFX6MPA.js.map +0 -1
  625. package/dist/chunk-4GVM6QZA.js.map +0 -1
  626. package/dist/chunk-4ZS56W5S.js.map +0 -1
  627. package/dist/chunk-5VCRVKOZ.js.map +0 -1
  628. package/dist/chunk-6YXCPL4T.js.map +0 -1
  629. package/dist/chunk-7APJ6CO6.js.map +0 -1
  630. package/dist/chunk-7MG2LHO5.js +0 -1616
  631. package/dist/chunk-7MG2LHO5.js.map +0 -1
  632. package/dist/chunk-7MG7SJT7.js.map +0 -1
  633. package/dist/chunk-7O3Y4PPD.js.map +0 -1
  634. package/dist/chunk-A2HKRLPV.js.map +0 -1
  635. package/dist/chunk-A66I4JOA.js.map +0 -1
  636. package/dist/chunk-ACAQ2DSG.js.map +0 -1
  637. package/dist/chunk-ATL3ZVXT.js +0 -151
  638. package/dist/chunk-ATL3ZVXT.js.map +0 -1
  639. package/dist/chunk-AYX7AINO.js.map +0 -1
  640. package/dist/chunk-BLN54W3L.js.map +0 -1
  641. package/dist/chunk-BRLKZUBT.js +0 -95
  642. package/dist/chunk-BRLKZUBT.js.map +0 -1
  643. package/dist/chunk-BTDR2PXY.js +0 -29
  644. package/dist/chunk-BTDR2PXY.js.map +0 -1
  645. package/dist/chunk-BVN6KXL2.js.map +0 -1
  646. package/dist/chunk-CHQCZZWC.js.map +0 -1
  647. package/dist/chunk-CUQPWYRX.js.map +0 -1
  648. package/dist/chunk-CUZLNGD5.js.map +0 -1
  649. package/dist/chunk-DFMWUOU5.js.map +0 -1
  650. package/dist/chunk-EIPVYUEP.js.map +0 -1
  651. package/dist/chunk-EQEYOJBM.js.map +0 -1
  652. package/dist/chunk-F3W6YMDC.js.map +0 -1
  653. package/dist/chunk-FET5XCAT.js.map +0 -1
  654. package/dist/chunk-G73UVHCA.js.map +0 -1
  655. package/dist/chunk-GPNTB4Y7.js.map +0 -1
  656. package/dist/chunk-GYGLAVCX.js.map +0 -1
  657. package/dist/chunk-HIWCKBEY.js.map +0 -1
  658. package/dist/chunk-HJUWN7JN.js.map +0 -1
  659. package/dist/chunk-HK67PX4J.js.map +0 -1
  660. package/dist/chunk-HPVZCW43.js +0 -479
  661. package/dist/chunk-HPVZCW43.js.map +0 -1
  662. package/dist/chunk-I3ISCYT7.js +0 -159
  663. package/dist/chunk-I3ISCYT7.js.map +0 -1
  664. package/dist/chunk-K23VKTN4.js.map +0 -1
  665. package/dist/chunk-KKEESNPE.js.map +0 -1
  666. package/dist/chunk-KTFRCC5C.js.map +0 -1
  667. package/dist/chunk-LH5A3ZPG.js.map +0 -1
  668. package/dist/chunk-LP7BEXCT.js +0 -32
  669. package/dist/chunk-LP7BEXCT.js.map +0 -1
  670. package/dist/chunk-M4YPHYEH.js.map +0 -1
  671. package/dist/chunk-NSITFOCJ.js +0 -99
  672. package/dist/chunk-NSITFOCJ.js.map +0 -1
  673. package/dist/chunk-OTQZ7ZWU.js.map +0 -1
  674. package/dist/chunk-P3MG6QCN.js.map +0 -1
  675. package/dist/chunk-PEOZ34EM.js.map +0 -1
  676. package/dist/chunk-PPTHY5QO.js.map +0 -1
  677. package/dist/chunk-Q2MPFCQ7.js.map +0 -1
  678. package/dist/chunk-Q7HZX3IF.js.map +0 -1
  679. package/dist/chunk-QPQUVOZ2.js.map +0 -1
  680. package/dist/chunk-QTQUH4DS.js.map +0 -1
  681. package/dist/chunk-R42NSZI6.js.map +0 -1
  682. package/dist/chunk-R7BX2NB3.js.map +0 -1
  683. package/dist/chunk-RSGLUIO6.js.map +0 -1
  684. package/dist/chunk-RTBJ5IOO.js +0 -87
  685. package/dist/chunk-RTBJ5IOO.js.map +0 -1
  686. package/dist/chunk-SGZAIJCV.js.map +0 -1
  687. package/dist/chunk-SKGMN35F.js.map +0 -1
  688. package/dist/chunk-SPYWXKJN.js.map +0 -1
  689. package/dist/chunk-SZJ3DLZA.js +0 -66
  690. package/dist/chunk-SZJ3DLZA.js.map +0 -1
  691. package/dist/chunk-TRGTKX5E.js.map +0 -1
  692. package/dist/chunk-UDHWDSRL.js.map +0 -1
  693. package/dist/chunk-UP4BECPY.js.map +0 -1
  694. package/dist/chunk-UXVWEX5L.js.map +0 -1
  695. package/dist/chunk-V7ZRRCRJ.js.map +0 -1
  696. package/dist/chunk-WQBG4SZS.js.map +0 -1
  697. package/dist/chunk-XKWGNJ26.js.map +0 -1
  698. package/dist/chunk-YMUFFJCO.js.map +0 -1
  699. package/dist/chunk-ZHKOPKE3.js.map +0 -1
  700. package/dist/chunk-ZN4FD4PE.js +0 -364
  701. package/dist/chunk-ZN4FD4PE.js.map +0 -1
  702. package/dist/chunk-ZORTV6NH.js.map +0 -1
  703. package/dist/chunk-ZYIYHJ5R.js.map +0 -1
  704. package/dist/classified-marker-BWOFVYAC.js.map +0 -1
  705. package/dist/collection-facade-JSJYIKS4.js +0 -45
  706. package/dist/dead-filter-PKQDLOT4.js.map +0 -1
  707. package/dist/delegation-DS5NRILW.js.map +0 -1
  708. package/dist/derive-E642AOUB.js +0 -21
  709. package/dist/dispatch-Q6MWLOJY.js.map +0 -1
  710. package/dist/executor-5NIMLSKZ.js +0 -8
  711. package/dist/executor-7UQ3BZ4F.js +0 -29
  712. package/dist/executor-AQVXV5GZ.js +0 -8
  713. package/dist/export-accessible-ORMKLA3E.js +0 -22
  714. package/dist/extract-partition-NKYO3WNG.js +0 -37
  715. package/dist/fanout-sidecar-S3QL53YX.js.map +0 -1
  716. package/dist/find-NOGJ25VX.js +0 -10
  717. package/dist/issue-3DTQ7VJJ.js +0 -18
  718. package/dist/json-schema-V3M5MUCM.js.map +0 -1
  719. package/dist/kernel/enclave/classify/compare.d.ts +0 -10
  720. package/dist/kernel/enclave/index.d.ts +0 -87
  721. package/dist/kernel/enclave/record-keys/lifecycle.d.ts +0 -124
  722. package/dist/kernel/enclave/record-keys/rekey-blob.d.ts +0 -88
  723. package/dist/kernel/enclave/record-keys/rekey.d.ts +0 -91
  724. package/dist/kernel/enclave/record-keys/sealed-slot.d.ts +0 -14
  725. package/dist/kernel/enclave/record-keys/sealed-slots.d.ts +0 -123
  726. package/dist/kernel/enclave/record-keys/sealing.d.ts +0 -70
  727. package/dist/kernel/query/join.d.ts +0 -232
  728. package/dist/liberate-V35QUHJP.js +0 -24
  729. package/dist/link-set-2TTM3IZC.js +0 -30
  730. package/dist/noydb-62MX4QUG.js +0 -90
  731. package/dist/pod-handle-ECVCDIXW.js.map +0 -1
  732. package/dist/post-register-3IPCSG6Q.js.map +0 -1
  733. package/dist/register-HHLXEQDN.js +0 -31
  734. package/dist/registry-23WF3TGH.js +0 -8
  735. package/dist/registry-4AYVUNXK.js +0 -8
  736. package/dist/registry-JS3YFQQM.js +0 -18
  737. package/dist/registry-XX2Z7B46.js +0 -32
  738. package/dist/request-withdrawal-CHPATE4G.js +0 -30
  739. package/dist/reveal-QZDHSGD4.js.map +0 -1
  740. package/dist/revoke-7M2VW4ON.js +0 -23
  741. package/dist/seed-X5CC22CQ.js.map +0 -1
  742. package/dist/signer-SJQJVSM6.js +0 -24
  743. package/dist/stale-BZS6H2RY.js +0 -29
  744. package/dist/storage-RW4QBS23.js +0 -22
  745. package/dist/store-coordination-provider-4WZAIRHC.js.map +0 -1
  746. package/dist/verify-6MDTIUEV.js.map +0 -1
  747. package/dist/walk-ZURCH6RZ.js +0 -21
  748. package/dist/withdraw-accessible-PXR4IXDX.js +0 -27
  749. /package/dist/{api-WYW4YEQG.js.map → api-OS747DS4.js.map} +0 -0
  750. /package/dist/{computed-VPOKQK4N.js.map → capsule/contract.js.map} +0 -0
  751. /package/dist/{kernel/enclave → capsule/enclave-aes}/broker/proof.d.ts +0 -0
  752. /package/dist/{kernel/enclave → capsule/enclave-aes}/classify/bidx.d.ts +0 -0
  753. /package/dist/{kernel/enclave → capsule/enclave-aes}/classify/digest.d.ts +0 -0
  754. /package/dist/{kernel/enclave → capsule/enclave-aes}/classify/vdig.d.ts +0 -0
  755. /package/dist/{kernel/enclave/classify → capsule/plumbing}/kofn.d.ts +0 -0
  756. /package/dist/{kernel/enclave/classify → capsule/plumbing}/normalize.d.ts +0 -0
  757. /package/dist/{kernel/enclave → capsule/plumbing}/record-aad.d.ts +0 -0
  758. /package/dist/{collection-facade-JSJYIKS4.js.map → capsule-VOLX3QRQ.js.map} +0 -0
  759. /package/dist/{chunk-MVMXZYXT.js.map → chunk-2GHDLTPE.js.map} +0 -0
  760. /package/dist/{chunk-XLMEZIAJ.js.map → chunk-2ODVB6LZ.js.map} +0 -0
  761. /package/dist/{chunk-RMS3NEA3.js.map → chunk-4JPMZTJY.js.map} +0 -0
  762. /package/dist/{chunk-NQKIUNW5.js.map → chunk-52MGURXO.js.map} +0 -0
  763. /package/dist/{chunk-UGTBXF5U.js.map → chunk-7XMHMVTS.js.map} +0 -0
  764. /package/dist/{chunk-BZ3534YM.js.map → chunk-AUKKUPVB.js.map} +0 -0
  765. /package/dist/{derive-E642AOUB.js.map → chunk-BKT776R5.js.map} +0 -0
  766. /package/dist/{chunk-6LKOJBV6.js.map → chunk-BVCUTXE3.js.map} +0 -0
  767. /package/dist/{chunk-VTFVLCUH.js.map → chunk-DIZLQVAA.js.map} +0 -0
  768. /package/dist/{chunk-LWBCUYZW.js.map → chunk-E2N2T5ZO.js.map} +0 -0
  769. /package/dist/{chunk-JVIBCBC7.js.map → chunk-EJLV62NI.js.map} +0 -0
  770. /package/dist/{chunk-JMGDHKQF.js.map → chunk-FLPCETP6.js.map} +0 -0
  771. /package/dist/{chunk-DGOZ4UZD.js.map → chunk-FVH5QYY2.js.map} +0 -0
  772. /package/dist/{chunk-JBDFMYKQ.js.map → chunk-GZT3NQRA.js.map} +0 -0
  773. /package/dist/{chunk-TFR7DSOV.js.map → chunk-H427H63K.js.map} +0 -0
  774. /package/dist/{chunk-SMH6SRX7.js.map → chunk-JOSPH3E5.js.map} +0 -0
  775. /package/dist/{chunk-3BZZJJMQ.js.map → chunk-MILI22XQ.js.map} +0 -0
  776. /package/dist/{chunk-YYP7WSEB.js.map → chunk-O2IMQSNA.js.map} +0 -0
  777. /package/dist/{chunk-QIZPZMUI.js.map → chunk-Q4UHJ5SN.js.map} +0 -0
  778. /package/dist/{chunk-FAHMLERK.js.map → chunk-QBLT6POL.js.map} +0 -0
  779. /package/dist/{chunk-BUE2D7PX.js.map → chunk-SMV2HRDU.js.map} +0 -0
  780. /package/dist/{chunk-SFAWCTEM.js.map → chunk-TZZBXPZK.js.map} +0 -0
  781. /package/dist/{chunk-UHHPLO3I.js.map → chunk-V3RWOOSO.js.map} +0 -0
  782. /package/dist/{chunk-Q2PU57HC.js.map → chunk-VVOLDVIR.js.map} +0 -0
  783. /package/dist/{chunk-TUFM4UZP.js.map → chunk-XQRFSKYM.js.map} +0 -0
  784. /package/dist/{chunk-GY4WYNNG.js.map → chunk-Y2RKVFKR.js.map} +0 -0
  785. /package/dist/{chunk-4OZNXTO4.js.map → chunk-YRXFFWG4.js.map} +0 -0
  786. /package/dist/{enclave-55PAM4YO.js.map → collection-facade-CS7CA2XO.js.map} +0 -0
  787. /package/dist/{executor-5NIMLSKZ.js.map → computed-FAD7SED4.js.map} +0 -0
  788. /package/dist/{executor-7UQ3BZ4F.js.map → derive-XLOJVXPU.js.map} +0 -0
  789. /package/dist/{dispatch-IEPAVQUM.js.map → dispatch-H4HV32AM.js.map} +0 -0
  790. /package/dist/{executor-AQVXV5GZ.js.map → executor-FMPVN6DT.js.map} +0 -0
  791. /package/dist/{export-accessible-ORMKLA3E.js.map → executor-LBBBRTN5.js.map} +0 -0
  792. /package/dist/{extract-partition-NKYO3WNG.js.map → executor-OSRZST2U.js.map} +0 -0
  793. /package/dist/{find-NOGJ25VX.js.map → export-accessible-RAOJAAU5.js.map} +0 -0
  794. /package/dist/{issue-3DTQ7VJJ.js.map → extract-partition-JD5CUSTG.js.map} +0 -0
  795. /package/dist/{ledger-EDXFFZQL.js.map → find-JRN4RNQ5.js.map} +0 -0
  796. /package/dist/{liberate-V35QUHJP.js.map → issue-YIVBZUTH.js.map} +0 -0
  797. /package/dist/{link-set-2TTM3IZC.js.map → ledger-5ZMGE44K.js.map} +0 -0
  798. /package/dist/{managed-secret-NCWEMPUQ.js.map → liberate-WZSZM2W6.js.map} +0 -0
  799. /package/dist/{noydb-62MX4QUG.js.map → link-set-MFXC24VK.js.map} +0 -0
  800. /package/dist/{register-HHLXEQDN.js.map → managed-secret-MFTFT22X.js.map} +0 -0
  801. /package/dist/{migrate-cek-5ENH64AA.js.map → migrate-cek-DZRFFOHW.js.map} +0 -0
  802. /package/dist/{registry-23WF3TGH.js.map → noydb-ITIGNKUF.js.map} +0 -0
  803. /package/dist/{registry-4AYVUNXK.js.map → query/all/index.js.map} +0 -0
  804. /package/dist/{registry-JS3YFQQM.js.map → register-DT5HZ2LZ.js.map} +0 -0
  805. /package/dist/{registry-XX2Z7B46.js.map → registry-BHRZGZHF.js.map} +0 -0
  806. /package/dist/{request-withdrawal-CHPATE4G.js.map → registry-ET6ZFFWA.js.map} +0 -0
  807. /package/dist/{revoke-7M2VW4ON.js.map → registry-HXFGLGTG.js.map} +0 -0
  808. /package/dist/{signer-SJQJVSM6.js.map → registry-THCPDEOD.js.map} +0 -0
  809. /package/dist/{stale-BZS6H2RY.js.map → request-withdrawal-AV2MJJKY.js.map} +0 -0
  810. /package/dist/{storage-RW4QBS23.js.map → revoke-6DWIEOCV.js.map} +0 -0
  811. /package/dist/{walk-ZURCH6RZ.js.map → signer-MHGW3OIL.js.map} +0 -0
  812. /package/dist/{withdraw-accessible-PXR4IXDX.js.map → stale-6GCFMOOR.js.map} +0 -0
@@ -1,1616 +0,0 @@
1
- import {
2
- applyJoins,
3
- splitAroundJoins
4
- } from "./chunk-ZORTV6NH.js";
5
- import {
6
- NO_REDUCE
7
- } from "./chunk-YMUFFJCO.js";
8
- import {
9
- reducerBuilder
10
- } from "./chunk-ATL3ZVXT.js";
11
- import {
12
- evaluateClause,
13
- hasFnClause,
14
- readPath
15
- } from "./chunk-NSITFOCJ.js";
16
- import {
17
- CrossJoinSourceUnknownError,
18
- CrossJoinTooLargeError,
19
- DanglingReferenceError,
20
- FieldNotQueryableError,
21
- RefNotDeclaredError
22
- } from "./chunk-7O3Y4PPD.js";
23
-
24
- // src/kernel/query/live.ts
25
- function buildLiveQuery(recompute, upstreams) {
26
- return new LiveQueryImpl(recompute, upstreams);
27
- }
28
- var LiveQueryImpl = class {
29
- constructor(recompute, upstreams) {
30
- this.recompute = recompute;
31
- this.refresh();
32
- for (const upstream of upstreams) {
33
- try {
34
- this.unsubs.push(upstream.subscribe(this.onUpstreamChange));
35
- } catch (err) {
36
- this._error = err instanceof Error ? err : new Error(String(err));
37
- }
38
- }
39
- }
40
- recompute;
41
- _value = [];
42
- _error = null;
43
- listeners = /* @__PURE__ */ new Set();
44
- unsubs = [];
45
- stopped = false;
46
- get value() {
47
- return this._value;
48
- }
49
- get error() {
50
- return this._error;
51
- }
52
- /**
53
- * Bound change handler — used as the callback passed to every
54
- * upstream's subscribe. Bound via class field so the `this`
55
- * context survives the indirect call from arbitrary upstreams.
56
- */
57
- onUpstreamChange = () => {
58
- this.refresh();
59
- for (const cb of this.listeners) {
60
- try {
61
- cb();
62
- } catch {
63
- }
64
- }
65
- };
66
- refresh() {
67
- if (this.stopped) return;
68
- try {
69
- this._value = this.recompute();
70
- this._error = null;
71
- } catch (err) {
72
- this._error = err instanceof Error ? err : new Error(String(err));
73
- }
74
- }
75
- subscribe(cb) {
76
- if (this.stopped) return () => {
77
- };
78
- this.listeners.add(cb);
79
- return () => this.listeners.delete(cb);
80
- }
81
- stop() {
82
- if (this.stopped) return;
83
- this.stopped = true;
84
- for (const unsub of this.unsubs) {
85
- try {
86
- unsub();
87
- } catch {
88
- }
89
- }
90
- this.unsubs.length = 0;
91
- this.listeners.clear();
92
- }
93
- };
94
-
95
- // src/kernel/query/builder.ts
96
- var EMPTY_PLAN = {
97
- clauses: [],
98
- orderBy: [],
99
- limit: void 0,
100
- offset: 0,
101
- joins: []
102
- };
103
- var DEFAULT_CROSS_JOIN_MAX_ROWS = 5e4;
104
- function assertNoJoinAliasField(fields, joins, terminal) {
105
- if (joins.length === 0) return;
106
- const aliases = new Set(joins.map((leg) => leg.as));
107
- for (const field of fields) {
108
- const head = field.split(".")[0];
109
- if (!aliases.has(head)) continue;
110
- throw new Error(
111
- `Query.${terminal}(): field "${field}" addresses the join alias "${head}", but ${terminal}() does not apply join legs \u2014 it would silently group every row under undefined. Joined aggregation is not supported. Either aggregate over the left collection's own fields, or use .crossJoin("${head}", { as: \u2026 }), whose expansion IS visible to ${terminal}().`
112
- );
113
- }
114
- }
115
- var Query = class _Query {
116
- source;
117
- plan;
118
- joinContext;
119
- reduceStrategy;
120
- predicates;
121
- constructor(source, plan = EMPTY_PLAN, joinContext, reduceStrategy = NO_REDUCE, predicates) {
122
- this.source = source;
123
- this.plan = plan;
124
- this.joinContext = joinContext;
125
- this.reduceStrategy = reduceStrategy;
126
- this.predicates = predicates;
127
- }
128
- /**
129
- * @internal — accessor for the materialized-view dependency
130
- * analyzer. Not part of the public API; consumers should use the
131
- * builder methods, not inspect the plan directly.
132
- */
133
- _plan() {
134
- return this.plan;
135
- }
136
- /**
137
- * @internal — accessor for the materialized-view dependency
138
- * analyzer. Returns the join resolution context (or `undefined` for
139
- * queries constructed without a Collection backing).
140
- */
141
- _joinContext() {
142
- return this.joinContext;
143
- }
144
- /**
145
- * @internal — clone this Query with a declared-predicate map
146
- * attached. Used by the materialized-view registry to enable
147
- * `.wherePredicate(name, ctx?)` for the MV's query callback.
148
- * Consumers don't call this directly.
149
- */
150
- _withPredicates(predicates) {
151
- return new _Query(
152
- this.source,
153
- this.plan,
154
- this.joinContext,
155
- this.reduceStrategy,
156
- predicates
157
- );
158
- }
159
- /**
160
- * @internal — the ids of records matching this query's plan,
161
- * recovered by reference identity: `executePlanWithSource` returns the
162
- * ORIGINAL snapshot record references (money-decode and joins are applied
163
- * later, in `toArray`), so each matched record is found in the id-paired
164
- * `snapshotEntries()` map. Used by `collection.retrieve({ within })`.
165
- * Throws if the source is not collection-backed (no `snapshotEntries`).
166
- */
167
- _idArray() {
168
- const entries = this.source.snapshotEntries?.();
169
- if (entries === void 0) {
170
- throw new Error(
171
- "Query._idArray(): the query source has no snapshotEntries(); retrieve({ within }) requires a collection-backed query (collection.query())."
172
- );
173
- }
174
- if (this.plan.clauses.some((c) => c.type === "crossJoin")) {
175
- throw new Error(
176
- "Query._idArray(): retrieve({ within }) does not support crossJoin queries (cross-join produces new row objects, breaking id recovery). Use where/filter/and/or, or a projection .join()."
177
- );
178
- }
179
- const refToId = /* @__PURE__ */ new Map();
180
- for (const { id, record } of entries) refToId.set(record, id);
181
- const matched = executePlanWithSource(this.source, this.plan, this.joinContext);
182
- const ids = [];
183
- for (const r of matched) {
184
- const id = refToId.get(r);
185
- if (id !== void 0) ids.push(id);
186
- }
187
- return ids;
188
- }
189
- /**
190
- * Filter by a registered deterministic predicate. Requires
191
- * the Query to have been augmented with a predicates map (typically
192
- * via the materialized-view registry — bare Queries constructed
193
- * outside an MV throw on `.wherePredicate()`).
194
- *
195
- * `ctx` is an optional opaque value passed verbatim to the predicate
196
- * function. Both `predicateHash` (from the registration) and a
197
- * canonical-JSON hash of `ctx` fold into the MV's `queryHash`, so
198
- * either changing forces refresh on next visit.
199
- */
200
- wherePredicate(name, ctx) {
201
- if (!this.predicates) {
202
- throw new Error(
203
- `.wherePredicate("${name}"): no predicates registered on this Query. Function-based predicates require the Query to be obtained from inside a materialized-view query() callback whose strategy declares \`predicates: { ${name}: { hash, fn } }\`.`
204
- );
205
- }
206
- const decl = this.predicates.get(name);
207
- if (!decl) {
208
- throw new Error(
209
- `.wherePredicate("${name}"): predicate not registered. Available: ${[...this.predicates.keys()].join(", ") || "(none)"}.`
210
- );
211
- }
212
- const clause = {
213
- type: "wherePredicate",
214
- name,
215
- ctx,
216
- predicateHash: decl.hash,
217
- ctxHash: canonicalCtxHash(ctx),
218
- fn: decl.fn
219
- };
220
- return new _Query(
221
- this.source,
222
- { ...this.plan, clauses: [...this.plan.clauses, clause] },
223
- this.joinContext,
224
- this.reduceStrategy,
225
- this.predicates
226
- );
227
- }
228
- /**
229
- * Add a field comparison. Multiple where() calls are AND-combined.
230
- *
231
- * A declared money field compares in MAJOR units: the operand
232
- * (`10000`, `'10000.00'`, or `{ amount, currency }` in multi mode) is
233
- * quantized into stored scaled-int space at build time and evaluated
234
- * BigInt-exact per record. A malformed operand or a string operator
235
- * (`contains`/`startsWith`) throws here, at the call site.
236
- *
237
- * Consults the Via pipeline's posture before building a clause (#629
238
- * Task 8): a field whose posture is `queryable: 'none'` (e.g. a
239
- * `blobFields` slot) throws `FieldNotQueryableError` here, at the call
240
- * site. Every other posture is unaffected — the existing per-binding
241
- * `buildClause` machinery runs exactly as before.
242
- */
243
- where(field, op, value) {
244
- const via = this.source.via;
245
- if (via?.postureFor(field)?.queryable === "none") throw new FieldNotQueryableError(field);
246
- const viaClause = via?.buildClause(field, op, value);
247
- const clause = viaClause ? {
248
- type: "field",
249
- field,
250
- op,
251
- value,
252
- via: {
253
- brand: viaClause.brand,
254
- payload: viaClause.payload,
255
- evaluate: (actual, evalOp) => via.evaluateClause(viaClause, actual, evalOp),
256
- indexValue: via.indexProbe(viaClause, op)
257
- }
258
- } : { type: "field", field, op, value };
259
- return new _Query(
260
- this.source,
261
- { ...this.plan, clauses: [...this.plan.clauses, clause] },
262
- this.joinContext,
263
- this.reduceStrategy,
264
- this.predicates
265
- );
266
- }
267
- /**
268
- * Logical OR group. Pass a callback that builds a sub-query.
269
- * Each clause inside the callback is OR-combined; the group itself
270
- * joins the parent plan with AND.
271
- */
272
- or(builder) {
273
- const sub = builder(
274
- new _Query(this.source, EMPTY_PLAN, this.joinContext, this.reduceStrategy, this.predicates)
275
- );
276
- const group = {
277
- type: "group",
278
- op: "or",
279
- clauses: sub.plan.clauses
280
- };
281
- return new _Query(
282
- this.source,
283
- { ...this.plan, clauses: [...this.plan.clauses, group] },
284
- this.joinContext,
285
- this.reduceStrategy,
286
- this.predicates
287
- );
288
- }
289
- /**
290
- * Logical AND group. Same shape as `or()` but every clause inside the group
291
- * must match. Useful for explicit grouping inside a larger OR.
292
- */
293
- and(builder) {
294
- const sub = builder(
295
- new _Query(this.source, EMPTY_PLAN, this.joinContext, this.reduceStrategy, this.predicates)
296
- );
297
- const group = {
298
- type: "group",
299
- op: "and",
300
- clauses: sub.plan.clauses
301
- };
302
- return new _Query(
303
- this.source,
304
- { ...this.plan, clauses: [...this.plan.clauses, group] },
305
- this.joinContext,
306
- this.reduceStrategy,
307
- this.predicates
308
- );
309
- }
310
- /** Escape hatch: add an arbitrary predicate function. Not serializable. */
311
- filter(fn) {
312
- const clause = {
313
- type: "filter",
314
- fn
315
- };
316
- return new _Query(
317
- this.source,
318
- { ...this.plan, clauses: [...this.plan.clauses, clause] },
319
- this.joinContext,
320
- this.reduceStrategy,
321
- this.predicates
322
- );
323
- }
324
- /**
325
- * Sort by a field. Subsequent calls are tie-breakers. Pass
326
- * `{ by: 'label' }` to sort a `dictKey`/`staticDict` field by its resolved
327
- * label at the query locale instead of the stored code.
328
- *
329
- * Consults the Via pipeline's posture (#629 Task 8): a field whose posture
330
- * is `queryable: 'none'` throws `FieldNotQueryableError` here, at the call
331
- * site — same gate as `where()`.
332
- */
333
- orderBy(field, direction = "asc", opts) {
334
- if (this.source.via?.postureFor(field)?.queryable === "none") throw new FieldNotQueryableError(field);
335
- const entry = opts?.by === "label" ? { field, direction, by: "label" } : { field, direction };
336
- return new _Query(
337
- this.source,
338
- { ...this.plan, orderBy: [...this.plan.orderBy, entry] },
339
- this.joinContext,
340
- this.reduceStrategy,
341
- this.predicates
342
- );
343
- }
344
- /** Cap the result size. */
345
- limit(n) {
346
- return new _Query(
347
- this.source,
348
- { ...this.plan, limit: n },
349
- this.joinContext,
350
- this.reduceStrategy,
351
- this.predicates
352
- );
353
- }
354
- /** Skip the first N matching records (after ordering). */
355
- offset(n) {
356
- return new _Query(
357
- this.source,
358
- { ...this.plan, offset: n },
359
- this.joinContext,
360
- this.reduceStrategy,
361
- this.predicates
362
- );
363
- }
364
- /**
365
- * Resolve a `ref()`-declared foreign key and attach the right-side
366
- * record under `opts.as`. — eager, single-FK, intra-
367
- * vault joins.
368
- *
369
- * ```ts
370
- * const rows = invoices.query()
371
- * .where('status', '==', 'open')
372
- * .join('clientId', { as: 'client' })
373
- * .toArray()
374
- * // → [{ id, amount, client: { id, name, ... } }, ...]
375
- * ```
376
- *
377
- * Preconditions:
378
- * - The Query must have a `joinContext` (constructed via
379
- * `Collection.query()`, not `new Query`).
380
- * - `field` must have a matching `refs: { [field]: ref('<target>') }`
381
- * declaration on the left collection.
382
- * - The target collection must be reachable via the vault
383
- * (either currently open or openable on demand).
384
- *
385
- * Strategy:
386
- * - Nested-loop against `lookupById` when the target source
387
- * provides it (the common path for Collection targets).
388
- * - Hash join otherwise, or when `{ strategy: 'hash' }` is
389
- * explicitly passed for test purposes.
390
- *
391
- * Ref-mode semantics on dangling refs (left record has a non-null
392
- * FK value pointing at a right-side id that doesn't exist):
393
- * - `strict` → throws `DanglingReferenceError` with the full
394
- * field / target / refId context.
395
- * - `warn` → attaches `null` and emits a one-shot warning per
396
- * unique dangling pair.
397
- * - `cascade` → attaches `null` silently. Cascade is a
398
- * delete-time mode; dangling refs visible at read time are
399
- * either mid-flight cascades or pre-existing orphans, not a
400
- * DSL-level error.
401
- *
402
- * A left-side record whose FK field is `null` / `undefined` is NOT
403
- * a dangling ref — it's "no reference at all", always allowed
404
- * regardless of mode.
405
- *
406
- * The return type widens `T` with `Record<As, R | null>`. The `R`
407
- * parameter is optional — supply it explicitly for type-checked
408
- * access to the joined fields:
409
- *
410
- * ```ts
411
- * invoices.query().join<'client', Client>('clientId', { as: 'client' })
412
- * // ^^^^^^^^^^^^^^^^^^^ alias literal + right-side type
413
- * ```
414
- *
415
- * Without the generic, the joined field is typed as `unknown`, which
416
- * still works but requires a cast to access its properties.
417
- *
418
- * Joins stay intra-vault by construction — cross-vault
419
- * correlation goes through `Noydb.queryAcross`, not
420
- * `.join()`.
421
- */
422
- join(field, opts) {
423
- if (!this.joinContext) {
424
- throw new Error(
425
- `Query.join() requires a join context. Use collection.query() to construct a join-capable Query instead of the Query constructor directly (the direct constructor is only used for tests with plain-object sources).`
426
- );
427
- }
428
- const descriptor = this.joinContext.resolveRef(field);
429
- const isDictJoinField = !descriptor && this.joinContext.resolveDictSource?.(field) != null;
430
- if (!descriptor && !isDictJoinField) {
431
- throw new RefNotDeclaredError({
432
- collection: this.joinContext.leftCollection,
433
- field,
434
- message: `Query.join(): no ref() declared for field "${field}" on collection "${this.joinContext.leftCollection}". Add refs: { ${field}: ref('<target-collection>') } to the collection options, then retry. See the ref() docs for the full list of modes.`
435
- });
436
- }
437
- const leg = descriptor ? {
438
- field,
439
- as: opts.as,
440
- target: descriptor.target,
441
- mode: descriptor.mode,
442
- strategy: opts.strategy,
443
- maxRows: opts.maxRows,
444
- // constraint #1 — always 'all' in. Do not remove.
445
- partitionScope: "all"
446
- } : {
447
- // Dict join leg
448
- field,
449
- as: opts.as,
450
- target: field,
451
- // dict name = field name for dictKey
452
- mode: "strict",
453
- strategy: opts.strategy,
454
- maxRows: opts.maxRows,
455
- partitionScope: "all",
456
- isDictJoin: true
457
- };
458
- return new _Query(
459
- this.source,
460
- { ...this.plan, joins: [...this.plan.joins, leg] },
461
- this.joinContext,
462
- this.reduceStrategy,
463
- this.predicates
464
- );
465
- }
466
- /**
467
- * Cartesian-product cross-join against `target` collection. Each result row
468
- * carries the original `T` fields plus `result[as]` populated from every
469
- * right-side row (or the filtered subset when `on:` is supplied).
470
- *
471
- * **⚠️ INNER-join semantics — an empty right subset DROPS the left row.**
472
- * Each left row is emitted once per matching right row, so when `on:`
473
- * yields nothing the row vanishes with no error, no warning and no count
474
- * mismatch. This bites hardest on a reverse FK, where `.join()` (which is
475
- * forward-only, and already a genuine LEFT outer join) does not apply and
476
- * `.crossJoin()` is the only tool. To keep the row, return a one-element
477
- * array holding `null`:
478
- *
479
- * ```ts
480
- * .crossJoin('clients', { as: 'client', on: (b) => byEntity.get(b.entityId) ?? [null] })
481
- * // ^^^^^^^^
482
- * // the ONLY thing preserving the row
483
- * ```
484
- *
485
- * **Prefer `outer: true`**, which does exactly this and types the alias as
486
- * `TTarget | null`:
487
- *
488
- * ```ts
489
- * .crossJoin('clients', { as: 'client', outer: true, on: (b) => byEntity.get(b.entityId) ?? [] })
490
- * ```
491
- *
492
- * The `?? [null]` form remains valid and is what `outer` does internally, but
493
- * it is invisible intent: it types the alias as non-null while the row can
494
- * hold null, and a later "simplification" that drops it silently
495
- * reintroduces the row loss.
496
- *
497
- * **Order matters:** `.where().crossJoin()` filters BEFORE expanding (cheaper);
498
- * `.crossJoin().where('alias.field', ...)` filters AFTER (required when the
499
- * where clause references the aliased fields).
500
- *
501
- * **Cost ceiling:** `CrossJoinTooLargeError` fires before allocation when
502
- * `leftRows × rightRows` (or the cumulative lateral count) exceeds the limit.
503
- * Default: 50,000 rows. Override per-clause with `{ maxRows: N }`.
504
- *
505
- * **`on:` shapes:**
506
- * - `on: (left) => TTarget[]` — subset form (most efficient)
507
- * - `on: (left) => (right) => boolean` — predicate form
508
- * - `on: { predicate: 'name' }` — MV-safe, hash-tracked form
509
- * (requires the Query to have been augmented via `_withPredicates`)
510
- *
511
- * Requires a JoinContext (constructed via `collection.query()`).
512
- */
513
- crossJoin(target, opts) {
514
- if (!this.joinContext) {
515
- throw new Error(
516
- `Query.crossJoin("${target}"): requires a join context. Use collection.query() to construct a cross-join-capable Query instead of the Query constructor directly.`
517
- );
518
- }
519
- let onFn;
520
- let onPredicateName;
521
- if (opts.on !== void 0) {
522
- if (typeof opts.on === "function") {
523
- onFn = opts.on;
524
- if (this.predicates) {
525
- console.warn(
526
- `Query.crossJoin("${target}", { on: callback }): inline on: callback inside a withMaterializedView query() disables queryHash drift detection for this cross-join. Use on: { predicate: '<name>' } to enable it.`
527
- );
528
- }
529
- } else {
530
- const predName = opts.on.predicate;
531
- if (!this.predicates) {
532
- throw new Error(
533
- `Query.crossJoin("${target}", { on: { predicate: "${predName}" } }): the { predicate } form requires a predicates map. Use this form inside a withMaterializedView query() callback that declares predicates: { ${predName}: { hash, fn } }.`
534
- );
535
- }
536
- const decl = this.predicates.get(predName);
537
- if (!decl) {
538
- throw new Error(
539
- `Query.crossJoin("${target}"): predicate "${predName}" not registered. Available: ${[...this.predicates.keys()].join(", ") || "(none)"}.`
540
- );
541
- }
542
- const as = opts.as;
543
- const predicateFn = decl.fn;
544
- onFn = (_left) => (right) => predicateFn({ ..._left, [as]: right });
545
- onPredicateName = predName;
546
- }
547
- }
548
- const clause = {
549
- type: "crossJoin",
550
- target,
551
- as: opts.as,
552
- ...onFn !== void 0 && { on: onFn },
553
- ...onPredicateName !== void 0 && { onPredicateName },
554
- ...opts.maxRows !== void 0 && { maxRows: opts.maxRows },
555
- ...opts.outer === true && { outer: true }
556
- };
557
- return new _Query(
558
- this.source,
559
- { ...this.plan, clauses: [...this.plan.clauses, clause] },
560
- this.joinContext,
561
- this.reduceStrategy,
562
- this.predicates
563
- );
564
- }
565
- /**
566
- * Execute the plan and return the matching records. When the plan
567
- * carries any join legs, they are applied after `where` / `orderBy`
568
- * / `limit` / `offset` narrow the left set. See the `.join()` doc
569
- * for the ordering rationale.
570
- *
571
- * `opts.locale` resolves JOINED right-side i18n fields at the
572
- * `join` layer to that locale; without it, the owning collection's default
573
- * locale applies, and a locale-less query leaves joined i18n fields raw.
574
- * (Left/base i18n fields are resolved by `get`/`list`, not here.)
575
- */
576
- toArray(opts) {
577
- const { preJoin, postJoin } = splitAroundJoins(this.plan.clauses, this.plan.joins);
578
- if (postJoin.length === 0) {
579
- const base = this.decodeVia(executePlanWithSource(this.source, this.plan, this.joinContext, opts?.locale));
580
- if (this.plan.joins.length === 0) return base;
581
- return applyJoins(base, this.plan.joins, this.requireJoinContext("toArray"), opts?.locale);
582
- }
583
- const joinContext = this.requireJoinContext("toArray");
584
- const narrowed = this.decodeVia(
585
- executePlanWithSource(
586
- this.source,
587
- { ...this.plan, clauses: preJoin, orderBy: [], limit: void 0, offset: 0 },
588
- joinContext,
589
- opts?.locale
590
- )
591
- );
592
- const joined = applyJoins(narrowed, this.plan.joins, joinContext, opts?.locale);
593
- const filtered = filterRecords(joined, postJoin, fnViewDecoder(this.source));
594
- return applyOrderAndPage(filtered, this.plan, this.source, joinContext, opts?.locale);
595
- }
596
- /**
597
- * Joins need a `JoinContext`. Unreachable in practice — `.join()` throws
598
- * when one is missing — but belt-and-braces for a plan built through the
599
- * raw `Query` constructor with joins pre-populated.
600
- */
601
- requireJoinContext(terminal) {
602
- if (!this.joinContext) {
603
- throw new Error(
604
- `Query.${terminal}(): plan carries ${this.plan.joins.length} join leg(s) but no JoinContext is attached. This usually means the Query was constructed via the raw Query constructor with a plan that had joins pre-populated. Use collection.query().join(...) instead.`
605
- );
606
- }
607
- return this.joinContext;
608
- }
609
- /**
610
- * Decode this source's Via-covered fields on read (e.g. money: stored
611
- * scaled-int → canonical decimal), so `query().toArray()` agrees with
612
- * `get()`/`sum()` on the value. No-op when the source's Via pipeline
613
- * declares no result decode.
614
- *
615
- * The query layer carries no locale context, so money decodes with
616
- * `'raw'` — canonical decimal, WITHOUT fabricating locale-formatted
617
- * `<field>Formatted` / `<field>Number` virtuals. Producing a
618
- * guessed-locale string here would reintroduce a "two read paths
619
- * disagree" failure on the virtual field (e.g. it-IT via `get()` vs
620
- * en-US here). Consumers who need formatted money read through
621
- * `get()`/`list()` with a locale.
622
- */
623
- decodeVia(records) {
624
- const via = this.source.via;
625
- if (!via || !via.hasResultDecode) return records;
626
- return records.map((r) => via.decodeResults(r));
627
- }
628
- /** Return the first matching record, or null. Joins are applied. `opts.locale` resolves joined i18n fields. */
629
- first(opts) {
630
- const arr = this.limit(1).toArray(opts);
631
- return arr[0] ?? null;
632
- }
633
- /**
634
- * Return the number of matching records (after where/filter,
635
- * before limit). **Joins are normally NOT applied** — count() reports the
636
- * left-side cardinality, because joins are projection-only
637
- * (they attach an aliased field; they never filter). Running joins
638
- * here just to discard the aliases would be wasteful, and in strict
639
- * mode it could throw `DanglingReferenceError` for a call whose
640
- * intent is purely to count.
641
- *
642
- * The exception (#1030) is a `where` clause addressing a join alias. Then
643
- * the legs must run, because the predicate is part of what is being
644
- * counted — skipping them would report the unfiltered left cardinality.
645
- * A strict-mode `DanglingReferenceError` becomes reachable from `count()`
646
- * in exactly that case, which is acceptable: the caller asked to filter on
647
- * the joined side, so they asked for the join.
648
- */
649
- count() {
650
- if (this.plan.clauses.some((c) => c.type === "crossJoin")) {
651
- if (!this.joinContext) {
652
- throw new Error(
653
- `Query.count(): plan contains crossJoin clauses but no JoinContext is attached.`
654
- );
655
- }
656
- return executeClausePipeline(this.source, this.plan.clauses, this.joinContext).length;
657
- }
658
- const { preJoin, postJoin } = splitAroundJoins(this.plan.clauses, this.plan.joins);
659
- const { candidates, remainingClauses } = candidateRecords(this.source, preJoin);
660
- const narrowed = remainingClauses.length === 0 ? candidates : filterRecords(candidates, remainingClauses, fnViewDecoder(this.source));
661
- if (postJoin.length === 0) return narrowed.length;
662
- const joined = applyJoins(narrowed, this.plan.joins, this.requireJoinContext("count"));
663
- return filterRecords(joined, postJoin, fnViewDecoder(this.source)).length;
664
- }
665
- aggregate(specOrBuild) {
666
- let spec = typeof specOrBuild === "function" ? specOrBuild(reducerBuilder) : specOrBuild;
667
- assertNoJoinAliasField(
668
- Object.values(spec).map((r) => r.field).filter((f) => typeof f === "string"),
669
- this.plan.joins,
670
- "aggregate"
671
- );
672
- spec = this.source.via?.wrapReducers(spec) ?? spec;
673
- const source = this.source;
674
- const clauses = this.plan.clauses;
675
- const joinCtx = this.joinContext;
676
- const hasCrossJoins = clauses.some((c) => c.type === "crossJoin");
677
- const executeRecords = () => {
678
- if (hasCrossJoins) {
679
- if (!joinCtx) throw new Error("Query.aggregate(): crossJoin requires a join context");
680
- return executeClausePipeline(source, clauses, joinCtx);
681
- }
682
- const { candidates, remainingClauses } = candidateRecords(source, clauses);
683
- return remainingClauses.length === 0 ? candidates : filterRecords(candidates, remainingClauses, fnViewDecoder(source));
684
- };
685
- const upstreams = [];
686
- if (source.subscribe) {
687
- const subscribe = source.subscribe.bind(source);
688
- upstreams.push({ subscribe: (cb) => subscribe(cb) });
689
- }
690
- return this.reduceStrategy.aggregate(executeRecords, spec, upstreams);
691
- }
692
- groupBy(...fields) {
693
- if (fields.length === 0) {
694
- throw new Error(".groupBy() requires at least one field");
695
- }
696
- assertNoJoinAliasField(fields, this.plan.joins, "groupBy");
697
- const source = this.source;
698
- const clauses = this.plan.clauses;
699
- const joinCtx = this.joinContext;
700
- const hasCrossJoins = clauses.some((c) => c.type === "crossJoin");
701
- const executeRecords = () => {
702
- if (hasCrossJoins) {
703
- if (!joinCtx) throw new Error("Query.groupBy(): crossJoin requires a join context");
704
- return executeClausePipeline(source, clauses, joinCtx);
705
- }
706
- const { candidates, remainingClauses } = candidateRecords(source, clauses);
707
- return remainingClauses.length === 0 ? candidates : filterRecords(candidates, remainingClauses, fnViewDecoder(source));
708
- };
709
- const upstreams = [];
710
- if (source.subscribe) {
711
- const subscribe = source.subscribe.bind(source);
712
- upstreams.push({ subscribe: (cb) => subscribe(cb) });
713
- }
714
- if (fields.length === 1) {
715
- const field = fields[0];
716
- const dictLabelResolver = buildDictLabelResolver(this.joinContext, field);
717
- return this.reduceStrategy.groupBy(
718
- executeRecords,
719
- field,
720
- upstreams,
721
- dictLabelResolver,
722
- this.source.via
723
- );
724
- }
725
- return this.reduceStrategy.groupByN(
726
- executeRecords,
727
- fields,
728
- upstreams,
729
- this.source.via
730
- );
731
- }
732
- /**
733
- * Re-run the query whenever the source notifies of changes.
734
- * Returns an unsubscribe function. The callback receives the latest result.
735
- * Throws if the source does not support subscriptions.
736
- *
737
- * **For joined queries, prefer `.live()`** — `subscribe()`
738
- * only re-fires on LEFT-side changes, so joined data can be
739
- * stale if the right side mutates between emissions. `.live()`
740
- * merges change streams from every join target.
741
- */
742
- subscribe(cb) {
743
- if (!this.source.subscribe) {
744
- throw new Error("Query source does not support subscriptions. Pass a source with a subscribe() method.");
745
- }
746
- cb(this.toArray());
747
- return this.source.subscribe(() => cb(this.toArray()));
748
- }
749
- /**
750
- * Reactive terminal — returns a `LiveQuery<T>` that re-runs the
751
- * query and updates its `value` whenever any source feeding it
752
- * mutates..
753
- *
754
- * For non-joined queries, `.live()` is a convenience over the
755
- * existing `.subscribe()` callback shape: a hand-rolled reactive
756
- * primitive with `value` / `error` fields and a `subscribe(cb)`
757
- * notification channel. Frame-agnostic — Vue / React / Solid
758
- * adapters wrap it in their own primitive.
759
- *
760
- * For joined queries, `.live()` additionally subscribes to every
761
- * join target's change stream. Mutations on a right-side
762
- * collection (insert / update / delete of a client referenced by
763
- * an invoice) re-fire the live query and re-evaluate every
764
- * dependent left row. Right-side targets are deduped by
765
- * collection name, so a chain that joins the same target twice
766
- * (e.g. billing client + shipping client → both 'clients') only
767
- * subscribes once.
768
- *
769
- * **Ref-mode behavior on right-side disappearance** — matches the
770
- * eager `.toArray()` contract from :
771
- * - `strict` → re-run throws `DanglingReferenceError`. The
772
- * LiveQuery catches the throw, stores it in `live.error`, and
773
- * notifies listeners (the throw does NOT propagate out of
774
- * the source's change handler — that would tear down the
775
- * emitter). Consumers check `live.error` after each
776
- * notification and render an error state in the UI.
777
- * - `warn` → joined value flips to `null`; the existing
778
- * warn-channel deduplication keeps repeated re-runs from
779
- * spamming the console.
780
- * - `cascade` → no special handling needed; the cascade-
781
- * delete mechanism propagates the right-side delete into the
782
- * left collection on the next tick, and the live query
783
- * naturally re-fires with the orphaned left rows gone.
784
- *
785
- * Always call `live.stop()` when finished — it tears down every
786
- * upstream subscription. The Vue layer's `onUnmounted` hook
787
- * should call `stop()` automatically; raw consumers must do it
788
- * themselves.
789
- *
790
- * **Limitations:**
791
- * - No granular delta updates — the whole query re-runs on
792
- * every change.
793
- * - No microtask batching — bursty changes produce one re-run
794
- * per change.
795
- * - No re-planning under live mutations — the planner picks
796
- * once at subscription time and reuses the same plan.
797
- * - Streaming live joins are deferred.
798
- */
799
- live() {
800
- const upstreams = [];
801
- if (this.source.subscribe) {
802
- const leftSubscribe = this.source.subscribe.bind(this.source);
803
- upstreams.push({
804
- subscribe: (cb) => leftSubscribe(cb)
805
- });
806
- }
807
- if (this.plan.joins.length > 0 && this.joinContext) {
808
- const subscribed = /* @__PURE__ */ new Set();
809
- for (const leg of this.plan.joins) {
810
- if (subscribed.has(leg.target)) continue;
811
- subscribed.add(leg.target);
812
- const rightSource = this.joinContext.resolveSource(leg.target);
813
- if (rightSource?.subscribe) {
814
- const rightSubscribe = rightSource.subscribe.bind(rightSource);
815
- upstreams.push({
816
- subscribe: (cb) => rightSubscribe(cb)
817
- });
818
- }
819
- }
820
- }
821
- if (this.joinContext) {
822
- const subscribedCross = /* @__PURE__ */ new Set();
823
- for (const clause of this.plan.clauses) {
824
- if (clause.type !== "crossJoin") continue;
825
- if (subscribedCross.has(clause.target)) continue;
826
- subscribedCross.add(clause.target);
827
- const rightSource = this.joinContext.resolveSource(clause.target);
828
- if (rightSource?.subscribe) {
829
- const rightSubscribe = rightSource.subscribe.bind(rightSource);
830
- upstreams.push({
831
- subscribe: (cb) => rightSubscribe(cb)
832
- });
833
- }
834
- }
835
- }
836
- return buildLiveQuery(() => this.toArray(), upstreams);
837
- }
838
- /**
839
- * Return the plan as a JSON-friendly object. FilterClause entries are
840
- * stripped (their `fn` cannot be serialized) and replaced with
841
- * { type: 'filter', fn: '[function]' } so devtools can still see them.
842
- */
843
- toPlan() {
844
- return serializePlan(this.plan);
845
- }
846
- };
847
- function executePlanWithSource(source, plan, joinContext, locale) {
848
- const hasCrossJoins = plan.clauses.some((c) => c.type === "crossJoin");
849
- let result;
850
- if (hasCrossJoins) {
851
- if (!joinContext) {
852
- throw new Error(
853
- `Query.toArray(): plan contains crossJoin clauses but no JoinContext is attached. Use collection.query() instead of new Query() for cross-join support.`
854
- );
855
- }
856
- result = executeClausePipeline(source, plan.clauses, joinContext);
857
- } else {
858
- const { candidates, remainingClauses } = candidateRecords(source, plan.clauses);
859
- result = remainingClauses.length === 0 ? [...candidates] : filterRecords(candidates, remainingClauses, fnViewDecoder(source));
860
- }
861
- return applyOrderAndPage(result, plan, source, joinContext, locale);
862
- }
863
- function applyOrderAndPage(rows, plan, source, joinContext, locale) {
864
- let result = rows;
865
- if (plan.orderBy.length > 0) {
866
- const labelMaps = buildOrderLabelMaps(plan.orderBy, joinContext, locale, source.via);
867
- result = sortRecords(result, plan.orderBy, source.via, labelMaps);
868
- }
869
- if (plan.offset > 0) {
870
- result = result.slice(plan.offset);
871
- }
872
- if (plan.limit !== void 0) {
873
- result = result.slice(0, plan.limit);
874
- }
875
- return result;
876
- }
877
- function candidateRecords(source, clauses) {
878
- const indexes = source.getIndexes?.();
879
- if (!indexes || !source.lookupById || clauses.length === 0) {
880
- return { candidates: source.snapshot(), remainingClauses: clauses };
881
- }
882
- const lookupById = (id) => source.lookupById?.(id);
883
- for (let i = 0; i < clauses.length; i++) {
884
- const clause = clauses[i];
885
- if (clause.type !== "field") continue;
886
- if (!indexes.has(clause.field)) continue;
887
- if (clause.via && clause.via.indexValue === void 0) continue;
888
- const probeValue = clause.via ? clause.via.indexValue : clause.value;
889
- let ids = null;
890
- if (clause.op === "==") {
891
- ids = indexes.lookupEqual(clause.field, probeValue);
892
- } else if (clause.op === "in" && Array.isArray(probeValue)) {
893
- ids = indexes.lookupIn(clause.field, probeValue);
894
- }
895
- if (ids !== null) {
896
- const remaining = [];
897
- for (let j = 0; j < clauses.length; j++) {
898
- if (j !== i) remaining.push(clauses[j]);
899
- }
900
- return {
901
- candidates: materializeIds(ids, lookupById),
902
- remainingClauses: remaining
903
- };
904
- }
905
- }
906
- return { candidates: source.snapshot(), remainingClauses: clauses };
907
- }
908
- function materializeIds(ids, lookupById) {
909
- const out = [];
910
- for (const id of ids) {
911
- const record = lookupById(id);
912
- if (record !== void 0) out.push(record);
913
- }
914
- return out;
915
- }
916
- function executePlan(records, plan) {
917
- if (plan.clauses.some((c) => c.type === "crossJoin")) {
918
- throw new Error(
919
- `executePlan(): does not support crossJoin clauses. executePlan is a stateless pure function \u2014 it cannot resolve cross-join right-side collections. Use Query.toArray() (via collection.query()) instead.`
920
- );
921
- }
922
- let result = filterRecords(records, plan.clauses);
923
- if (plan.orderBy.length > 0) {
924
- result = sortRecords(result, plan.orderBy);
925
- }
926
- if (plan.offset > 0) {
927
- result = result.slice(plan.offset);
928
- }
929
- if (plan.limit !== void 0) {
930
- result = result.slice(0, plan.limit);
931
- }
932
- return result;
933
- }
934
- function fnViewDecoder(source) {
935
- const via = source.via;
936
- if (!via || !via.hasResultDecode) return void 0;
937
- return (r) => via.decodeResults(r);
938
- }
939
- function filterRecords(records, clauses, decodeForFns) {
940
- if (clauses.length === 0) return [...records];
941
- const needsFnView = decodeForFns !== void 0 && hasFnClause(clauses);
942
- const out = [];
943
- for (const r of records) {
944
- const fnView = needsFnView ? decodeForFns(r) : void 0;
945
- let matches = true;
946
- for (const clause of clauses) {
947
- if (!evaluateClause(r, clause, fnView)) {
948
- matches = false;
949
- break;
950
- }
951
- }
952
- if (matches) out.push(r);
953
- }
954
- return out;
955
- }
956
- function executeClausePipeline(source, clauses, joinContext) {
957
- let rel = [...source.snapshot()];
958
- let filterBatch = [];
959
- const decodeForFns = fnViewDecoder(source);
960
- for (const clause of clauses) {
961
- if (clause.type === "crossJoin") {
962
- if (filterBatch.length > 0) {
963
- rel = filterRecords(rel, filterBatch, decodeForFns);
964
- filterBatch = [];
965
- }
966
- const rightSource = joinContext.resolveSource(clause.target);
967
- if (!rightSource) {
968
- throw new CrossJoinSourceUnknownError(clause.target, joinContext.leftCollection);
969
- }
970
- rel = applyCrossJoin(rel, clause, rightSource);
971
- } else {
972
- filterBatch.push(clause);
973
- }
974
- }
975
- if (filterBatch.length > 0) {
976
- rel = filterRecords(rel, filterBatch, decodeForFns);
977
- }
978
- return rel;
979
- }
980
- function applyCrossJoin(leftRel, clause, rightSource) {
981
- const rightRows = rightSource.snapshot();
982
- const maxRows = clause.maxRows ?? DEFAULT_CROSS_JOIN_MAX_ROWS;
983
- const { as } = clause;
984
- const outer = clause.outer === true;
985
- if (!clause.on) {
986
- const rightSide = outer && rightRows.length === 0 ? [null] : rightRows;
987
- const product = leftRel.length * rightSide.length;
988
- if (product > maxRows) {
989
- throw new CrossJoinTooLargeError({ target: clause.target, expected: product, limit: maxRows });
990
- }
991
- const expanded2 = [];
992
- for (const left of leftRel) {
993
- const leftObj = left;
994
- for (const right of rightSide) {
995
- expanded2.push({ ...leftObj, [as]: right });
996
- }
997
- }
998
- return expanded2;
999
- }
1000
- const expanded = [];
1001
- let cumulative = 0;
1002
- for (const left of leftRel) {
1003
- const callbackResult = clause.on(left);
1004
- let filteredRight;
1005
- if (Array.isArray(callbackResult)) {
1006
- filteredRight = callbackResult;
1007
- } else {
1008
- filteredRight = rightRows.filter(
1009
- callbackResult
1010
- );
1011
- }
1012
- if (outer && filteredRight.length === 0) filteredRight = [null];
1013
- cumulative += filteredRight.length;
1014
- if (cumulative > maxRows) {
1015
- throw new CrossJoinTooLargeError({
1016
- target: clause.target,
1017
- expected: cumulative,
1018
- limit: maxRows
1019
- });
1020
- }
1021
- const leftObj = left;
1022
- for (const right of filteredRight) {
1023
- expanded.push({ ...leftObj, [as]: right });
1024
- }
1025
- }
1026
- return expanded;
1027
- }
1028
- function sortRecords(records, orderBy, via, labelMaps) {
1029
- return [...records].sort((a, b) => {
1030
- for (const { field, direction, by } of orderBy) {
1031
- let av = readField(a, field);
1032
- let bv = readField(b, field);
1033
- const labelResolver = by === "label" ? labelMaps?.get(field) : void 0;
1034
- if (labelResolver) {
1035
- av = (typeof av === "string" ? labelResolver(av) : void 0) ?? av;
1036
- bv = (typeof bv === "string" ? labelResolver(bv) : void 0) ?? bv;
1037
- const cmp2 = compareValues(av, bv);
1038
- if (cmp2 !== 0) return direction === "asc" ? cmp2 : -cmp2;
1039
- continue;
1040
- }
1041
- const viaCmp = via?.compareForOrder(field, av, bv);
1042
- const cmp = viaCmp !== void 0 ? viaCmp : compareValues(av, bv);
1043
- if (cmp !== 0) return direction === "asc" ? cmp : -cmp;
1044
- }
1045
- return 0;
1046
- });
1047
- }
1048
- function buildOrderLabelMaps(orderBy, joinContext, locale, via) {
1049
- let maps;
1050
- for (const { field, by } of orderBy) {
1051
- if (by !== "label") continue;
1052
- const dictSource = joinContext?.resolveDictSource?.(field);
1053
- if (dictSource) {
1054
- const loc = locale ?? dictSource.displayLocale;
1055
- if (loc === void 0) continue;
1056
- const codeToLabel = /* @__PURE__ */ new Map();
1057
- for (const entry of dictSource.snapshot()) {
1058
- const k = entry["key"];
1059
- const labels = entry["labels"];
1060
- const label = labels?.[loc];
1061
- if (typeof k === "string" && typeof label === "string") codeToLabel.set(k, label);
1062
- }
1063
- ;
1064
- (maps ??= /* @__PURE__ */ new Map()).set(field, (code) => codeToLabel.get(code));
1065
- continue;
1066
- }
1067
- if (via) {
1068
- const cache = /* @__PURE__ */ new Map();
1069
- (maps ??= /* @__PURE__ */ new Map()).set(field, (code) => {
1070
- if (!cache.has(code)) cache.set(code, via.resolveOrderLabel(field, code, locale));
1071
- return cache.get(code);
1072
- });
1073
- }
1074
- }
1075
- return maps;
1076
- }
1077
- function readField(record, field) {
1078
- if (record === null || record === void 0) return void 0;
1079
- if (!field.includes(".")) {
1080
- return record[field];
1081
- }
1082
- const segments = field.split(".");
1083
- let cursor = record;
1084
- for (const segment of segments) {
1085
- if (cursor === null || cursor === void 0) return void 0;
1086
- cursor = cursor[segment];
1087
- }
1088
- return cursor;
1089
- }
1090
- function compareValues(a, b) {
1091
- if (a === void 0 || a === null) return b === void 0 || b === null ? 0 : 1;
1092
- if (b === void 0 || b === null) return -1;
1093
- if (typeof a === "number" && typeof b === "number") return a - b;
1094
- if (typeof a === "string" && typeof b === "string") return a < b ? -1 : a > b ? 1 : 0;
1095
- if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();
1096
- return 0;
1097
- }
1098
- function serializePlan(plan) {
1099
- return {
1100
- clauses: plan.clauses.map(serializeClause),
1101
- orderBy: plan.orderBy,
1102
- limit: plan.limit,
1103
- offset: plan.offset,
1104
- joins: plan.joins
1105
- };
1106
- }
1107
- function serializeClause(clause) {
1108
- if (clause.type === "filter") {
1109
- return { type: "filter", fn: "[function]" };
1110
- }
1111
- if (clause.type === "wherePredicate") {
1112
- return {
1113
- type: "wherePredicate",
1114
- name: clause.name,
1115
- ctx: clause.ctx,
1116
- predicateHash: clause.predicateHash,
1117
- ctxHash: clause.ctxHash,
1118
- fn: "[function]"
1119
- };
1120
- }
1121
- if (clause.type === "group") {
1122
- return {
1123
- type: "group",
1124
- op: clause.op,
1125
- clauses: clause.clauses.map(serializeClause)
1126
- };
1127
- }
1128
- if (clause.type === "crossJoin") {
1129
- return {
1130
- type: "crossJoin",
1131
- target: clause.target,
1132
- as: clause.as,
1133
- on: clause.on ? "[function]" : void 0,
1134
- onPredicateName: clause.onPredicateName,
1135
- maxRows: clause.maxRows,
1136
- // Part of the identity, not decoration: `outer` changes which rows come
1137
- // back, so omitting it here would let an inner-mode plan be reused for an
1138
- // outer-mode query under the same hash (#1130).
1139
- outer: clause.outer
1140
- };
1141
- }
1142
- return clause;
1143
- }
1144
- function canonicalCtxHash(ctx) {
1145
- if (ctx === void 0) return "";
1146
- const canonical = JSON.stringify(ctx, (_key, value) => {
1147
- if (value && typeof value === "object" && !Array.isArray(value)) {
1148
- const sorted = {};
1149
- for (const k of Object.keys(value).sort()) {
1150
- sorted[k] = value[k];
1151
- }
1152
- return sorted;
1153
- }
1154
- return value;
1155
- });
1156
- let h = 5381;
1157
- for (let i = 0; i < canonical.length; i++) {
1158
- h = (h << 5) + h ^ canonical.charCodeAt(i);
1159
- }
1160
- return (h >>> 0).toString(16).padStart(8, "0");
1161
- }
1162
- function buildDictLabelResolver(joinCtx, field) {
1163
- if (!joinCtx?.resolveDictSource) return void 0;
1164
- const dictSource = joinCtx.resolveDictSource(field);
1165
- if (!dictSource) return void 0;
1166
- const snapshot = dictSource.snapshot();
1167
- const displayLocale = dictSource.displayLocale;
1168
- const dictMap = /* @__PURE__ */ new Map();
1169
- for (const entry of snapshot) {
1170
- const k = entry["key"];
1171
- const labels = entry["labels"];
1172
- if (typeof k === "string" && labels && typeof labels === "object") {
1173
- dictMap.set(k, labels);
1174
- }
1175
- }
1176
- return async (key, locale, fallback) => {
1177
- const effLocale = locale || displayLocale;
1178
- if (!effLocale) return void 0;
1179
- const labels = dictMap.get(key);
1180
- if (!labels) return void 0;
1181
- if (labels[effLocale] !== void 0) return labels[effLocale];
1182
- const chain = Array.isArray(fallback) ? fallback : fallback ? [fallback] : [];
1183
- for (const fb of chain) {
1184
- if (fb === "any") {
1185
- const any = Object.values(labels)[0];
1186
- if (any !== void 0) return any;
1187
- } else if (labels[fb] !== void 0) {
1188
- return labels[fb];
1189
- }
1190
- }
1191
- return void 0;
1192
- };
1193
- }
1194
-
1195
- // src/kernel/query/scan-builder.ts
1196
- var DEFAULT_SCAN_PAGE_SIZE = 100;
1197
- var ScanBuilder = class _ScanBuilder {
1198
- pageProvider;
1199
- pageSize;
1200
- clauses;
1201
- /**
1202
- * Zero-or-more join legs to apply per record as the stream flows.
1203
- * Each leg attaches the resolved right-side record (or null) under
1204
- * its alias. — streaming joins.
1205
- *
1206
- * Joins are evaluated AFTER clauses, so a `where()` filtered-out
1207
- * record never triggers a right-side lookup. This is the same
1208
- * ordering as `Query.toArray()` (clauses first, joins after) and
1209
- * keeps the streaming path from doing wasted work.
1210
- */
1211
- joins;
1212
- /**
1213
- * Join resolution context. Required for `.join()` to translate a
1214
- * field name into a target collection + ref mode and to resolve
1215
- * the right-side `JoinableSource`. Optional because tests
1216
- * construct ScanBuilder directly with synthetic page providers
1217
- * that don't know about ref() — calling `.join()` without a
1218
- * context throws with an actionable error.
1219
- */
1220
- joinContext;
1221
- /**
1222
- * The backing collection's compiled Via pipeline (money now; more Via
1223
- * features later). When it declares a result decode, yielded records
1224
- * are decoded (e.g. money: stored scaled-int → canonical decimal) so
1225
- * `scan()` agrees with `get()`/`list()`/`query().toArray()`. Decoded
1226
- * with `'raw'` (canonical decimal, no locale-formatted virtuals) since
1227
- * the scan stream carries no locale context, mirroring `Query.toArray()`.
1228
- */
1229
- via;
1230
- constructor(pageProvider, pageSize = DEFAULT_SCAN_PAGE_SIZE, clauses = [], joins = [], joinContext, via) {
1231
- this.pageProvider = pageProvider;
1232
- this.pageSize = pageSize;
1233
- this.clauses = clauses;
1234
- this.joins = joins;
1235
- this.joinContext = joinContext;
1236
- this.via = via;
1237
- }
1238
- /**
1239
- * Decode this scan's Via-covered fields on a record (e.g. money: stored
1240
- * scaled-int → canonical decimal). No-op when the Via pipeline declares
1241
- * no result decode. See {@link via}.
1242
- */
1243
- decodeVia(record) {
1244
- if (!this.via || !this.via.hasResultDecode) return record;
1245
- return this.via.decodeResults(record);
1246
- }
1247
- /**
1248
- * Add a field comparison. Runs per record as the scan stream
1249
- * flows through, so non-matching records are dropped before they
1250
- * reach `.aggregate()` or the iteration consumer. Multiple
1251
- * `.where()` calls are AND-combined — same semantics as
1252
- * `Query.where()`.
1253
- *
1254
- * Clauses cannot use the secondary-index fast path here because
1255
- * the scan sources records from the adapter's paginator, not from
1256
- * the in-memory cache where indexes live. Index-accelerated scans
1257
- * are a future optimization — the current implementation
1258
- * evaluates clauses per record in O(1) per clause.
1259
- *
1260
- * Consults the Via pipeline's posture before building a clause (#629
1261
- * Task 8): a field whose posture is `queryable: 'none'` throws
1262
- * `FieldNotQueryableError` here, at the call site — same gate as
1263
- * `Query.where()`.
1264
- */
1265
- where(field, op, value) {
1266
- const via = this.via;
1267
- if (via?.postureFor(field)?.queryable === "none") throw new FieldNotQueryableError(field);
1268
- const viaClause = via?.buildClause(field, op, value);
1269
- const clause = viaClause ? {
1270
- type: "field",
1271
- field,
1272
- op,
1273
- value,
1274
- via: {
1275
- brand: viaClause.brand,
1276
- payload: viaClause.payload,
1277
- evaluate: (actual, evalOp) => via.evaluateClause(viaClause, actual, evalOp)
1278
- }
1279
- } : { type: "field", field, op, value };
1280
- return new _ScanBuilder(
1281
- this.pageProvider,
1282
- this.pageSize,
1283
- [...this.clauses, clause],
1284
- this.joins,
1285
- this.joinContext,
1286
- this.via
1287
- );
1288
- }
1289
- /**
1290
- * Escape hatch: add an arbitrary predicate function. Same
1291
- * non-serializable caveat as `Query.filter()` — filter clauses
1292
- * don't round-trip through `toPlan()`. Prefer `.where()` when
1293
- * possible.
1294
- */
1295
- filter(fn) {
1296
- const clause = {
1297
- type: "filter",
1298
- fn
1299
- };
1300
- return new _ScanBuilder(
1301
- this.pageProvider,
1302
- this.pageSize,
1303
- [...this.clauses, clause],
1304
- this.joins,
1305
- this.joinContext,
1306
- this.via
1307
- );
1308
- }
1309
- /**
1310
- * Resolve a `ref()`-declared foreign key per record as the scan
1311
- * stream flows, attaching the right-side record (or null) under
1312
- * `opts.as`. — streaming joins over `scan()`.
1313
- *
1314
- * ```ts
1315
- * for await (const inv of invoices.scan().join('clientId', { as: 'client' })) {
1316
- * await processInvoice(inv) // inv.client is attached
1317
- * }
1318
- *
1319
- * // Or terminate with .aggregate() for streaming joined aggregation
1320
- * const { total } = await invoices.scan()
1321
- * .where('status', '==', 'open')
1322
- * .join('clientId', { as: 'client' })
1323
- * .aggregate({ total: sum('amount') })
1324
- * ```
1325
- *
1326
- * **The key difference from eager `.join()`:** the LEFT
1327
- * side streams page-by-page from the adapter and is never
1328
- * materialized. Memory ceiling on the left is O(pageSize), not
1329
- * O(rowCount). This is what makes streaming joins suitable for
1330
- * collections that exceed the eager join's 50_000-row ceiling.
1331
- *
1332
- * **Right-side strategy** is auto-selected per leg:
1333
- * - **Indexed** — right source exposes `lookupById`, so each
1334
- * left row costs O(1). This is the common path for
1335
- * Collection right sides, which back `lookupById` with a Map
1336
- * lookup over the in-memory cache. The right collection must
1337
- * be in eager mode (the same constraint as eager join's
1338
- * `querySourceForJoin` from ).
1339
- * - **Hash** — right source has only `snapshot()`. Build a
1340
- * `Map<id, record>` once at iteration start, probe per left
1341
- * row. Same correctness, same per-row cost as the indexed
1342
- * path; the difference is the upfront cost of materializing
1343
- * the right side once.
1344
- *
1345
- * Both strategies hold the right side in memory for the duration
1346
- * of the iteration. The "streaming" property applies to the LEFT
1347
- * side only — true left-and-right streaming joins (where neither
1348
- * side fits in memory) require a sort-merge join planner that's
1349
- * out of scope for.
1350
- *
1351
- * **Ref-mode semantics** match eager `.join()` exactly:
1352
- * - `strict` → throws `DanglingReferenceError` mid-stream
1353
- * when a left record points at a non-existent right id.
1354
- * The throw aborts the async iterator — consumers should
1355
- * wrap the `for await` in try/catch if they want to recover.
1356
- * - `warn` → attaches `null` and emits a one-shot warning
1357
- * per unique dangling pair (deduped via the same warn
1358
- * channel as eager join).
1359
- * - `cascade` → attaches `null` silently. A delete-time mode;
1360
- * dangling refs at read time are mid-flight or pre-existing
1361
- * orphans, not a DSL error.
1362
- *
1363
- * Left records with null/undefined FK values attach `null`
1364
- * regardless of mode — same "no reference at all" policy as
1365
- * eager join and write-time `enforceRefsOnPut`.
1366
- *
1367
- * **Multi-FK chaining** is supported via repeated `.join()`
1368
- * calls: each leg resolves an independent ref. Each leg
1369
- * independently picks its right-side strategy and applies its
1370
- * own ref mode.
1371
- *
1372
- * **Joins are NOT applied** to a `.aggregate()` terminal that
1373
- * doesn't reference joined fields — wait, that's not quite
1374
- * right. The streaming path actually DOES apply joins before
1375
- * `.aggregate()` because the join attaches a field that the
1376
- * spec might reference. Unlike `Query.aggregate()` (which skips
1377
- * joins entirely as a projection-only short-circuit), the
1378
- * streaming aggregation can't know whether the spec touches a
1379
- * joined field, so it always applies joins. Consumers who want
1380
- * unjoined streaming aggregation should leave `.join()` off the
1381
- * chain — the chain is composable for a reason.
1382
- *
1383
- * constraint #1 — every JoinLeg carries `partitionScope:
1384
- * 'all'` plumbed through but never read by. Same seam as
1385
- * eager join.
1386
- */
1387
- join(field, opts) {
1388
- if (!this.joinContext) {
1389
- throw new Error(
1390
- `ScanBuilder.join() requires a join context. Use collection.scan() to construct a join-capable scan instead of the ScanBuilder constructor directly (the direct constructor is only used for tests with synthetic page providers).`
1391
- );
1392
- }
1393
- const descriptor = this.joinContext.resolveRef(field);
1394
- if (!descriptor) {
1395
- throw new RefNotDeclaredError({
1396
- collection: this.joinContext.leftCollection,
1397
- field,
1398
- message: `ScanBuilder.join(): no ref() declared for field "${field}" on collection "${this.joinContext.leftCollection}". Add refs: { ${field}: ref('<target-collection>') } to the collection options, then retry.`
1399
- });
1400
- }
1401
- const leg = {
1402
- field,
1403
- as: opts.as,
1404
- target: descriptor.target,
1405
- mode: descriptor.mode,
1406
- strategy: void 0,
1407
- maxRows: void 0,
1408
- // constraint #1 — always 'all' in, never read by
1409
- // the streaming executor. partition-aware scan joins
1410
- // will populate this from where() predicates without
1411
- // changing the planner shape.
1412
- partitionScope: "all"
1413
- };
1414
- return new _ScanBuilder(
1415
- this.pageProvider,
1416
- this.pageSize,
1417
- this.clauses,
1418
- [...this.joins, leg],
1419
- this.joinContext,
1420
- this.via
1421
- );
1422
- }
1423
- /**
1424
- * Iterate the scan as an async iterable. Walks the page
1425
- * provider's cursors forward until exhaustion, applying every
1426
- * clause per record — only matching records are yielded.
1427
- *
1428
- * Backward-compatible with the previous async-generator `scan()`
1429
- * return type for `for await … of` consumers.
1430
- */
1431
- async *[Symbol.asyncIterator]() {
1432
- const joinResolvers = this.joins.length === 0 ? null : this.buildJoinResolvers();
1433
- const { preJoin, postJoin } = splitAroundJoins(this.clauses, this.joins);
1434
- let page = await this.pageProvider.listPage({ limit: this.pageSize });
1435
- while (true) {
1436
- for (const record of page.items) {
1437
- if (!this.recordMatches(record, preJoin)) continue;
1438
- const decoded = this.decodeVia(record);
1439
- if (joinResolvers === null) {
1440
- yield decoded;
1441
- } else {
1442
- let attached = decoded;
1443
- for (const resolver of joinResolvers) {
1444
- attached = this.applyOneJoinStreaming(attached, resolver);
1445
- }
1446
- if (postJoin.length > 0 && !this.recordMatches(attached, postJoin)) continue;
1447
- yield attached;
1448
- }
1449
- }
1450
- if (page.nextCursor === null) return;
1451
- page = await this.pageProvider.listPage({
1452
- cursor: page.nextCursor,
1453
- limit: this.pageSize
1454
- });
1455
- }
1456
- }
1457
- /**
1458
- * Per-leg right-side resolution state. Built once at iteration
1459
- * start and reused for every left record. Two strategies:
1460
- *
1461
- * - `lookupById`: present when the right source exposes the
1462
- * hook directly (typical Collection right side). Per-row
1463
- * cost is O(1).
1464
- * - `hashByPrimaryKey`: built from `snapshot()` when no
1465
- * lookupById. Per-row cost is O(1) after the upfront O(N)
1466
- * materialization. Same as eager join's hash strategy.
1467
- *
1468
- * `warnedKeys` is the per-leg dedup set for ref-mode 'warn'. We
1469
- * key on `field→target:refId` so the same dangling pair only
1470
- * warns once per iteration. The dedup is per-iteration, not
1471
- * per-process — a long-running scan that re-iterates would warn
1472
- * again, which is the desired behavior (the data may have
1473
- * changed between iterations).
1474
- */
1475
- buildJoinResolvers() {
1476
- if (!this.joinContext) {
1477
- throw new Error(
1478
- `ScanBuilder iterator: ${this.joins.length} join leg(s) present but no JoinContext attached. Use collection.scan() to construct a join-capable scan.`
1479
- );
1480
- }
1481
- const resolvers = [];
1482
- for (const leg of this.joins) {
1483
- const source = this.joinContext.resolveSource(leg.target);
1484
- if (!source) {
1485
- throw new Error(
1486
- `ScanBuilder.join() cannot resolve target collection "${leg.target}" (referenced from field "${leg.field}" on "${this.joinContext.leftCollection}"). Make sure the target collection has been opened via vault.collection() at least once before iterating the scan.`
1487
- );
1488
- }
1489
- let lookupById = null;
1490
- let hashByPrimaryKey = null;
1491
- if (source.lookupById) {
1492
- const fn = source.lookupById.bind(source);
1493
- lookupById = (id) => fn(id);
1494
- } else {
1495
- const map = /* @__PURE__ */ new Map();
1496
- for (const record of source.snapshot()) {
1497
- const rawId = readPath(record, "id");
1498
- const key = coerceRefKey(rawId);
1499
- if (key !== null) map.set(key, record);
1500
- }
1501
- hashByPrimaryKey = map;
1502
- }
1503
- resolvers.push({
1504
- leg,
1505
- source,
1506
- lookupById,
1507
- hashByPrimaryKey,
1508
- warnedKeys: /* @__PURE__ */ new Set()
1509
- });
1510
- }
1511
- return resolvers;
1512
- }
1513
- /**
1514
- * Resolve a single join leg for one left record and return the
1515
- * left record with the joined field attached under
1516
- * `leg.as`. Pure function over `(left, resolver)`; never
1517
- * mutates the input.
1518
- *
1519
- * Ref-mode dispatch matches eager `applyJoins` from :
1520
- * - null/undefined FK → attach null silently (always allowed)
1521
- * - dangling FK + strict → throw `DanglingReferenceError`
1522
- * - dangling FK + warn → attach null, warn-once per pair
1523
- * - dangling FK + cascade → attach null silently
1524
- */
1525
- applyOneJoinStreaming(left, resolver) {
1526
- if (left === null || typeof left !== "object") {
1527
- return left;
1528
- }
1529
- const { leg } = resolver;
1530
- const rawId = readPath(left, leg.field);
1531
- const refKey = coerceRefKey(rawId);
1532
- let right = void 0;
1533
- if (refKey !== null) {
1534
- if (resolver.lookupById !== null) {
1535
- right = resolver.lookupById(refKey);
1536
- } else if (resolver.hashByPrimaryKey !== null) {
1537
- right = resolver.hashByPrimaryKey.get(refKey);
1538
- }
1539
- }
1540
- const merged = {
1541
- ...left
1542
- };
1543
- if (right === void 0) {
1544
- if (refKey !== null && leg.mode === "strict") {
1545
- throw new DanglingReferenceError({
1546
- field: leg.field,
1547
- target: leg.target,
1548
- refId: refKey,
1549
- message: `ScanBuilder.join() strict dangling: record references "${leg.target}:${refKey}" via field "${leg.field}", but no such record exists. Use ref() mode 'warn' or 'cascade' if dangling refs are acceptable, or run vault.checkIntegrity() to find and fix the orphans.`
1550
- });
1551
- }
1552
- if (refKey !== null && leg.mode === "warn") {
1553
- const dedupKey = `${leg.field}\u2192${leg.target}:${refKey}`;
1554
- if (!resolver.warnedKeys.has(dedupKey)) {
1555
- resolver.warnedKeys.add(dedupKey);
1556
- console.warn(
1557
- `[noy-db] ScanBuilder.join() encountered dangling ref in 'warn' mode: field "${leg.field}" \u2192 "${leg.target}:${refKey}" not found. Attaching null.`
1558
- );
1559
- }
1560
- }
1561
- merged[leg.as] = null;
1562
- } else {
1563
- merged[leg.as] = right;
1564
- }
1565
- return merged;
1566
- }
1567
- async aggregate(specOrBuild) {
1568
- const spec = typeof specOrBuild === "function" ? specOrBuild(reducerBuilder) : specOrBuild;
1569
- this.via?.refuseUnqueryableReducers(spec);
1570
- const keys = Object.keys(spec);
1571
- const state = {};
1572
- for (const key of keys) {
1573
- state[key] = spec[key].init();
1574
- }
1575
- for await (const record of this) {
1576
- for (const key of keys) {
1577
- state[key] = spec[key].step(state[key], record);
1578
- }
1579
- }
1580
- const result = {};
1581
- for (const key of keys) {
1582
- result[key] = spec[key].finalize(state[key]);
1583
- }
1584
- return result;
1585
- }
1586
- /**
1587
- * Evaluate the clause list against a single record. Linear in
1588
- * the clause count; short-circuits on first false. Clauses on a
1589
- * scan are always re-evaluated per record — no index-accelerated
1590
- * path, because the stream sources records from the adapter
1591
- * paginator, not from the in-memory cache where indexes live.
1592
- */
1593
- recordMatches(record, clauses = this.clauses) {
1594
- if (clauses.length === 0) return true;
1595
- const fnView = this.via?.hasResultDecode && hasFnClause(clauses) ? this.decodeVia(record) : void 0;
1596
- for (const clause of clauses) {
1597
- if (!evaluateClause(record, clause, fnView)) return false;
1598
- }
1599
- return true;
1600
- }
1601
- };
1602
- function coerceRefKey(value) {
1603
- if (value === null || value === void 0) return null;
1604
- if (typeof value === "string") return value;
1605
- if (typeof value === "number" || typeof value === "bigint") return String(value);
1606
- return null;
1607
- }
1608
-
1609
- export {
1610
- buildLiveQuery,
1611
- DEFAULT_CROSS_JOIN_MAX_ROWS,
1612
- Query,
1613
- executePlan,
1614
- ScanBuilder
1615
- };
1616
- //# sourceMappingURL=chunk-7MG2LHO5.js.map