@noy-db/hub 0.7.0 → 0.8.0-pre.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 (616) hide show
  1. package/CHANGELOG.md +105 -14
  2. package/LICENSE +202 -21
  3. package/NOTICE +1 -0
  4. package/README.md +27 -10
  5. package/codemods/0.8.0-pre.json +61 -0
  6. package/dist/api-GVYEKSJE.js +19 -0
  7. package/dist/as/index.js +11 -11
  8. package/dist/at/index.js +9 -9
  9. package/dist/attestation/index.js +20 -20
  10. package/dist/{backup-IJTB4S4M.js → backup-7TFRVFLH.js} +21 -15
  11. package/dist/backup-7TFRVFLH.js.map +1 -0
  12. package/dist/blobs/index.js +13 -13
  13. package/dist/broker/index.js +12 -12
  14. package/dist/by/index.js +2 -2
  15. package/dist/cargo/index.js +39 -36
  16. package/dist/{chunk-7O3Y4PPD.js → chunk-244VXYPG.js} +140 -16
  17. package/dist/chunk-244VXYPG.js.map +1 -0
  18. package/dist/{chunk-BUE2D7PX.js → chunk-32YV3TJT.js} +2 -2
  19. package/dist/{chunk-3RCJJBNR.js → chunk-3ELRMVJK.js} +12 -12
  20. package/dist/{chunk-6GMZ7HEE.js → chunk-3F7GLNAE.js} +6 -6
  21. package/dist/{chunk-2Y4IMKA6.js → chunk-3H5KLDZN.js} +4 -4
  22. package/dist/{chunk-VTFVLCUH.js → chunk-3JWHAR6E.js} +2 -2
  23. package/dist/{chunk-YMUFFJCO.js → chunk-3TDUWVWB.js} +5 -2
  24. package/dist/chunk-3TDUWVWB.js.map +1 -0
  25. package/dist/{chunk-JBDFMYKQ.js → chunk-4AF3TUMP.js} +2 -2
  26. package/dist/{chunk-ZORTV6NH.js → chunk-4I522ERM.js} +88 -4
  27. package/dist/chunk-4I522ERM.js.map +1 -0
  28. package/dist/{chunk-MUM7IANK.js → chunk-4MXI3ODD.js} +4 -4
  29. package/dist/chunk-4MXI3ODD.js.map +1 -0
  30. package/dist/{chunk-BLN54W3L.js → chunk-5FDLC6G7.js} +56 -3
  31. package/dist/chunk-5FDLC6G7.js.map +1 -0
  32. package/dist/chunk-5O7D6ZTW.js +53 -0
  33. package/dist/chunk-5O7D6ZTW.js.map +1 -0
  34. package/dist/{chunk-J6FXAEUG.js → chunk-6B3VNR4P.js} +12 -12
  35. package/dist/{chunk-TUFM4UZP.js → chunk-6K7DPM7D.js} +2 -2
  36. package/dist/{chunk-K6LHRFBL.js → chunk-6LMQ5R26.js} +7 -7
  37. package/dist/{chunk-SPXXX5E4.js → chunk-6LNL42F5.js} +94 -32
  38. package/dist/chunk-6LNL42F5.js.map +1 -0
  39. package/dist/{chunk-XLMEZIAJ.js → chunk-6OWXYZK2.js} +2 -2
  40. package/dist/{chunk-BOWNCWZT.js → chunk-6QSQQLSE.js} +3 -3
  41. package/dist/chunk-7JE7BDYJ.js +1558 -0
  42. package/dist/chunk-7JE7BDYJ.js.map +1 -0
  43. package/dist/{chunk-KG7TZKZG.js → chunk-7VCXZDA4.js} +5 -5
  44. package/dist/chunk-7VCXZDA4.js.map +1 -0
  45. package/dist/{chunk-NQKIUNW5.js → chunk-A6IJU4TK.js} +2 -2
  46. package/dist/{chunk-BM5TWITZ.js → chunk-ANWPSTZU.js} +38 -9
  47. package/dist/chunk-ANWPSTZU.js.map +1 -0
  48. package/dist/{chunk-QIZPZMUI.js → chunk-AOWGXU6D.js} +2 -2
  49. package/dist/{chunk-CUZLNGD5.js → chunk-B2YY6WDD.js} +1 -1
  50. package/dist/chunk-B2YY6WDD.js.map +1 -0
  51. package/dist/{chunk-SFAWCTEM.js → chunk-B57AFBY2.js} +2 -2
  52. package/dist/{chunk-GPEQUXHL.js → chunk-B6SJIBQK.js} +4 -4
  53. package/dist/chunk-BJ2IXQ5Q.js +100 -0
  54. package/dist/chunk-BJ2IXQ5Q.js.map +1 -0
  55. package/dist/{chunk-Q2PU57HC.js → chunk-BK2HHQGN.js} +2 -2
  56. package/dist/chunk-BKT776R5.js +1 -0
  57. package/dist/{chunk-KUX3OB6D.js → chunk-BP6DARYA.js} +33 -5
  58. package/dist/chunk-BP6DARYA.js.map +1 -0
  59. package/dist/{chunk-FXBIP2WD.js → chunk-BUDAGWL5.js} +6 -6
  60. package/dist/chunk-CF5UU4S7.js +757 -0
  61. package/dist/chunk-CF5UU4S7.js.map +1 -0
  62. package/dist/{chunk-BOET4NA4.js → chunk-CKNGS5MH.js} +3 -3
  63. package/dist/chunk-CY2CYVWZ.js +41 -0
  64. package/dist/chunk-CY2CYVWZ.js.map +1 -0
  65. package/dist/{chunk-2577DKXB.js → chunk-DC5QVPV7.js} +2 -2
  66. package/dist/chunk-DC5QVPV7.js.map +1 -0
  67. package/dist/{chunk-YSRUYAVU.js → chunk-DE4DH2RZ.js} +2 -2
  68. package/dist/{chunk-6I2RQCET.js → chunk-DF73H4UN.js} +4 -4
  69. package/dist/{chunk-4GVM6QZA.js → chunk-ENAG3IY7.js} +2 -2
  70. package/dist/chunk-ENAG3IY7.js.map +1 -0
  71. package/dist/{chunk-K7NTTA6P.js → chunk-EOVMT6TB.js} +2 -2
  72. package/dist/chunk-F24ZZTHQ.js +193 -0
  73. package/dist/chunk-F24ZZTHQ.js.map +1 -0
  74. package/dist/chunk-F2TDU7MQ.js +456 -0
  75. package/dist/chunk-F2TDU7MQ.js.map +1 -0
  76. package/dist/chunk-F6NCB7KT.js +13 -0
  77. package/dist/chunk-F6NCB7KT.js.map +1 -0
  78. package/dist/{chunk-SPYWXKJN.js → chunk-F7XGHL5O.js} +3 -3
  79. package/dist/chunk-F7XGHL5O.js.map +1 -0
  80. package/dist/{chunk-XTXOCYOJ.js → chunk-FCKWQE2H.js} +5 -5
  81. package/dist/{chunk-U4FOQDY4.js → chunk-FH2L2E34.js} +4 -4
  82. package/dist/chunk-FH2L2E34.js.map +1 -0
  83. package/dist/{chunk-4OZNXTO4.js → chunk-FN5EBVTQ.js} +2 -2
  84. package/dist/chunk-FQ54DWUQ.js +270 -0
  85. package/dist/chunk-FQ54DWUQ.js.map +1 -0
  86. package/dist/{chunk-NKHRDYOR.js → chunk-FQ5VRHIB.js} +4 -4
  87. package/dist/{chunk-FAHMLERK.js → chunk-FW22ZCXT.js} +2 -2
  88. package/dist/chunk-FXQBGFOX.js +524 -0
  89. package/dist/chunk-FXQBGFOX.js.map +1 -0
  90. package/dist/{chunk-AO42KJO6.js → chunk-GF5BZ7D4.js} +45 -9
  91. package/dist/chunk-GF5BZ7D4.js.map +1 -0
  92. package/dist/{chunk-TRGTKX5E.js → chunk-GHLTDZRS.js} +5 -3
  93. package/dist/{chunk-TRGTKX5E.js.map → chunk-GHLTDZRS.js.map} +1 -1
  94. package/dist/{chunk-5WDXHNSW.js → chunk-HBPPGWUM.js} +5 -5
  95. package/dist/chunk-HBPPGWUM.js.map +1 -0
  96. package/dist/{chunk-KTFRCC5C.js → chunk-HBRLNOHL.js} +82 -8
  97. package/dist/chunk-HBRLNOHL.js.map +1 -0
  98. package/dist/chunk-HLEK5VAN.js +275 -0
  99. package/dist/chunk-HLEK5VAN.js.map +1 -0
  100. package/dist/{chunk-RMS3NEA3.js → chunk-HT2AHGQI.js} +2 -2
  101. package/dist/{chunk-CHJBLCOG.js → chunk-HVSCEIYL.js} +7 -7
  102. package/dist/{chunk-UXWB3FPF.js → chunk-I3JDRCMW.js} +150 -22
  103. package/dist/chunk-I3JDRCMW.js.map +1 -0
  104. package/dist/{chunk-GY4WYNNG.js → chunk-ID6Z6E66.js} +2 -2
  105. package/dist/{chunk-EYBQEIUY.js → chunk-IEX7NK2K.js} +3 -3
  106. package/dist/{chunk-KUJDV5QH.js → chunk-ISZQJBML.js} +5 -5
  107. package/dist/{chunk-LWBCUYZW.js → chunk-IT22PWKV.js} +2 -2
  108. package/dist/{chunk-EQEYOJBM.js → chunk-IUWCVHQ7.js} +3 -3
  109. package/dist/chunk-IUWCVHQ7.js.map +1 -0
  110. package/dist/{chunk-7V4TP3AF.js → chunk-J6UOHJY5.js} +4 -4
  111. package/dist/{chunk-JMGDHKQF.js → chunk-JCN44NCY.js} +2 -2
  112. package/dist/{chunk-CARABLSQ.js → chunk-K6W7BVZ6.js} +3 -3
  113. package/dist/{chunk-77K4PG6P.js → chunk-KJFW62P4.js} +29 -11
  114. package/dist/chunk-KJFW62P4.js.map +1 -0
  115. package/dist/{chunk-453F654R.js → chunk-L7DOS3TE.js} +2 -2
  116. package/dist/chunk-LGNDFRYC.js +23 -0
  117. package/dist/chunk-LGNDFRYC.js.map +1 -0
  118. package/dist/{chunk-WEQEYLCS.js → chunk-LGRLME4M.js} +7 -7
  119. package/dist/{chunk-RMF67KCG.js → chunk-LQ4ZHOKP.js} +2 -2
  120. package/dist/{chunk-ZVO4QVPD.js → chunk-M522UYZ2.js} +5 -5
  121. package/dist/{chunk-G56KBWFY.js → chunk-M7NI3IWE.js} +45 -12
  122. package/dist/chunk-M7NI3IWE.js.map +1 -0
  123. package/dist/chunk-MDWKM2XC.js +293 -0
  124. package/dist/chunk-MDWKM2XC.js.map +1 -0
  125. package/dist/chunk-MKXXMNJH.js +204 -0
  126. package/dist/chunk-MKXXMNJH.js.map +1 -0
  127. package/dist/{chunk-SKGMN35F.js → chunk-MLPHLJIQ.js} +3 -3
  128. package/dist/chunk-MLPHLJIQ.js.map +1 -0
  129. package/dist/{chunk-2N4GY74U.js → chunk-MTL7MXGR.js} +6 -6
  130. package/dist/{chunk-TFR7DSOV.js → chunk-MVZ2TPVP.js} +2 -2
  131. package/dist/{chunk-CPWQB3N5.js → chunk-N5DNADLQ.js} +7 -7
  132. package/dist/{chunk-ELNXJMGB.js → chunk-NNARWO72.js} +6 -6
  133. package/dist/{chunk-PT43Y56J.js → chunk-NRT6QZQB.js} +102 -16
  134. package/dist/chunk-NRT6QZQB.js.map +1 -0
  135. package/dist/{chunk-QIBVIOXO.js → chunk-NWHBJQAL.js} +99 -8
  136. package/dist/chunk-NWHBJQAL.js.map +1 -0
  137. package/dist/chunk-NYMLINRP.js +28 -0
  138. package/dist/chunk-NYMLINRP.js.map +1 -0
  139. package/dist/{chunk-7MG7SJT7.js → chunk-ODVPTDPK.js} +1 -1
  140. package/dist/chunk-ODVPTDPK.js.map +1 -0
  141. package/dist/chunk-ORDURZBU.js +461 -0
  142. package/dist/chunk-ORDURZBU.js.map +1 -0
  143. package/dist/{chunk-6YXCPL4T.js → chunk-PDCG6PR5.js} +2 -2
  144. package/dist/{chunk-REDOOY2Q.js → chunk-PSIV7CJV.js} +2 -2
  145. package/dist/{chunk-NA2NIJZI.js → chunk-QBBUZ3I3.js} +126 -19
  146. package/dist/chunk-QBBUZ3I3.js.map +1 -0
  147. package/dist/{chunk-5VCRVKOZ.js → chunk-QOOUUR4A.js} +6 -4
  148. package/dist/{chunk-5VCRVKOZ.js.map → chunk-QOOUUR4A.js.map} +1 -1
  149. package/dist/{chunk-ANATMFIO.js → chunk-QWFHIOD2.js} +5 -5
  150. package/dist/{chunk-X2DLENDQ.js → chunk-QWGU66MP.js} +3 -3
  151. package/dist/chunk-RHVMZSUU.js +7 -0
  152. package/dist/chunk-RHVMZSUU.js.map +1 -0
  153. package/dist/{chunk-BSFNRLK2.js → chunk-S57HTZ6X.js} +5 -5
  154. package/dist/{chunk-SZJ3DLZA.js → chunk-SEE332EV.js} +2 -2
  155. package/dist/{chunk-YYP7WSEB.js → chunk-SI3V7D4G.js} +2 -2
  156. package/dist/{chunk-UGTBXF5U.js → chunk-SOIQ4MM4.js} +3 -3
  157. package/dist/chunk-SUZKW6UR.js +25 -0
  158. package/dist/chunk-SUZKW6UR.js.map +1 -0
  159. package/dist/{chunk-VXGSWL6L.js → chunk-SYVZW77S.js} +6 -6
  160. package/dist/{chunk-6GOE5PGN.js → chunk-T2LBQ5DV.js} +883 -227
  161. package/dist/chunk-T2LBQ5DV.js.map +1 -0
  162. package/dist/chunk-T52GX4SA.js +215 -0
  163. package/dist/chunk-T52GX4SA.js.map +1 -0
  164. package/dist/{chunk-MVMXZYXT.js → chunk-TKUOEU2F.js} +2 -2
  165. package/dist/chunk-TOPYQ6GA.js +31 -0
  166. package/dist/chunk-TOPYQ6GA.js.map +1 -0
  167. package/dist/{chunk-SMH6SRX7.js → chunk-TROR3ALR.js} +2 -2
  168. package/dist/{chunk-2C3AQB46.js → chunk-UD5EVGZ7.js} +42 -389
  169. package/dist/chunk-UD5EVGZ7.js.map +1 -0
  170. package/dist/{chunk-KJIMGIWO.js → chunk-UPD5NWI5.js} +65 -17
  171. package/dist/chunk-UPD5NWI5.js.map +1 -0
  172. package/dist/{chunk-SL3JAAKN.js → chunk-UYB234ZR.js} +30 -2
  173. package/dist/chunk-UYB234ZR.js.map +1 -0
  174. package/dist/chunk-VHM7HCKB.js +220 -0
  175. package/dist/chunk-VHM7HCKB.js.map +1 -0
  176. package/dist/{chunk-DGOZ4UZD.js → chunk-VNNRUGMM.js} +2 -2
  177. package/dist/{chunk-HDOU6I2Y.js → chunk-VNPEWFPD.js} +4 -4
  178. package/dist/{chunk-L7CIOOBW.js → chunk-WNJ4AVGE.js} +2 -2
  179. package/dist/{chunk-FMZY5Q6L.js → chunk-WX5ADGTZ.js} +3 -3
  180. package/dist/{chunk-VXANTWBJ.js → chunk-WY2XXTET.js} +92 -6
  181. package/dist/{chunk-VXANTWBJ.js.map → chunk-WY2XXTET.js.map} +1 -1
  182. package/dist/{chunk-6X6SEMEE.js → chunk-X25NWUZB.js} +33 -8
  183. package/dist/chunk-X25NWUZB.js.map +1 -0
  184. package/dist/{chunk-Q7HZX3IF.js → chunk-X4773RBR.js} +2 -2
  185. package/dist/chunk-XBKH4FOC.js +195 -0
  186. package/dist/chunk-XBKH4FOC.js.map +1 -0
  187. package/dist/{chunk-ANSIZYEG.js → chunk-YNIUIERI.js} +3 -3
  188. package/dist/chunk-YSK2CU2Q.js +936 -0
  189. package/dist/chunk-YSK2CU2Q.js.map +1 -0
  190. package/dist/{chunk-UXVWEX5L.js → chunk-Z5HTYMMQ.js} +6 -2
  191. package/dist/chunk-Z5HTYMMQ.js.map +1 -0
  192. package/dist/{chunk-RRNRNANG.js → chunk-ZE4CHIED.js} +66 -75
  193. package/dist/chunk-ZE4CHIED.js.map +1 -0
  194. package/dist/chunk-ZSX4S5XB.js +1289 -0
  195. package/dist/chunk-ZSX4S5XB.js.map +1 -0
  196. package/dist/{chunk-BZ3534YM.js → chunk-ZUVBC32X.js} +2 -2
  197. package/dist/{chunk-L742JPKZ.js → chunk-ZXABPVM6.js} +6 -6
  198. package/dist/classified/index.js +5 -5
  199. package/dist/{classified-marker-LI2SF2E4.js → classified-marker-W3USLL5M.js} +3 -3
  200. package/dist/collection-facade-QU6IJBN3.js +48 -0
  201. package/dist/{computed-VPOKQK4N.js → computed-TPFBX7U4.js} +3 -3
  202. package/dist/consent/index.js +9 -9
  203. package/dist/cover/index.js +10 -10
  204. package/dist/coverage/index.js +306 -0
  205. package/dist/coverage/index.js.map +1 -0
  206. package/dist/custody/index.js +12 -12
  207. package/dist/{dead-filter-TSWZQRR5.js → dead-filter-U2UYKSZL.js} +2 -2
  208. package/dist/debug/index.js +1 -1
  209. package/dist/{delegation-OVIFFPG4.js → delegation-S3AEPW2T.js} +11 -11
  210. package/dist/derivations/index.js +25 -22
  211. package/dist/derive-OX7F6TGG.js +21 -0
  212. package/dist/directory/index.js +10 -10
  213. package/dist/{dispatch-WC6X2M6C.js → dispatch-3CQDJV5Q.js} +5 -5
  214. package/dist/{dispatch-S73TK3IY.js → dispatch-RH4LHKBH.js} +21 -21
  215. package/dist/{enclave-KJOTOH7X.js → enclave-27SMF6GF.js} +15 -9
  216. package/dist/executor-B6SRO2QS.js +36 -0
  217. package/dist/executor-BI5CHWRY.js +8 -0
  218. package/dist/executor-RBKM5W5K.js +8 -0
  219. package/dist/export-accessible-VMA3YM5V.js +22 -0
  220. package/dist/extract-partition-NF7PXGPP.js +37 -0
  221. package/dist/{fanout-sidecar-WUFXNYP4.js → fanout-sidecar-OT6RYLOL.js} +9 -9
  222. package/dist/find-LZMP26KF.js +10 -0
  223. package/dist/forget/index.js +9 -9
  224. package/dist/guards/index.js +4 -4
  225. package/dist/history/index.js +13 -13
  226. package/dist/i18n/index.js +14 -14
  227. package/dist/index.d.ts +29 -6
  228. package/dist/index.js +999 -191
  229. package/dist/index.js.map +1 -1
  230. package/dist/indexing/index.js +13 -5
  231. package/dist/indexing/index.js.map +1 -1
  232. package/dist/introspection/index.js +11 -11
  233. package/dist/issue-IHARXWW5.js +18 -0
  234. package/dist/ivf-flat-UZ6DQDLS.js +314 -0
  235. package/dist/ivf-flat-UZ6DQDLS.js.map +1 -0
  236. package/dist/{json-schema-V3M5MUCM.js → json-schema-3SHX72CC.js} +2 -1
  237. package/dist/json-schema-3SHX72CC.js.map +1 -0
  238. package/dist/kernel/collection-config.d.ts +4 -20
  239. package/dist/kernel/collection.d.ts +29 -8
  240. package/dist/kernel/enclave/crypto.d.ts +16 -0
  241. package/dist/kernel/enclave/index.d.ts +1 -1
  242. package/dist/kernel/enclave/record-keys/record-codec.d.ts +25 -0
  243. package/dist/kernel/errors.d.ts +227 -36
  244. package/dist/kernel/generation-map.d.ts +48 -0
  245. package/dist/kernel/memory-store.d.ts +35 -7
  246. package/dist/kernel/noydb.d.ts +6 -1
  247. package/dist/kernel/present-cache.d.ts +58 -0
  248. package/dist/kernel/query/all.d.ts +7 -0
  249. package/dist/kernel/query/builder.d.ts +601 -270
  250. package/dist/kernel/query/civil-date.d.ts +64 -0
  251. package/dist/kernel/query/cursor.d.ts +40 -0
  252. package/dist/kernel/query/distinct-key.d.ts +98 -0
  253. package/dist/kernel/query/hydration.d.ts +76 -0
  254. package/dist/kernel/query/index.d.ts +31 -15
  255. package/dist/kernel/query/internal/core.d.ts +30 -0
  256. package/dist/kernel/query/internal/hooks.d.ts +22 -0
  257. package/dist/kernel/query/internal/maintenance.d.ts +43 -0
  258. package/dist/kernel/query/live/incremental.d.ts +314 -0
  259. package/dist/kernel/query/live/index.d.ts +22 -0
  260. package/dist/kernel/query/live/install.d.ts +2 -0
  261. package/dist/kernel/query/{live.d.ts → live/live.d.ts} +39 -9
  262. package/dist/kernel/query/live/methods.d.ts +107 -0
  263. package/dist/kernel/query/predicate.d.ts +119 -1
  264. package/dist/kernel/query/reduce/date-trunc.d.ts +75 -0
  265. package/dist/kernel/query/reduce/index.d.ts +36 -0
  266. package/dist/kernel/query/reduce/install.d.ts +2 -0
  267. package/dist/kernel/query/reduce/methods.d.ts +259 -0
  268. package/dist/kernel/query/reduce/scan-methods.d.ts +121 -0
  269. package/dist/kernel/query/relate/explain.d.ts +199 -0
  270. package/dist/kernel/query/relate/index.d.ts +48 -0
  271. package/dist/kernel/query/relate/install.d.ts +2 -0
  272. package/dist/kernel/query/relate/join-on.d.ts +126 -0
  273. package/dist/kernel/query/relate/join-reduce.d.ts +16 -0
  274. package/dist/kernel/query/relate/join.d.ts +452 -0
  275. package/dist/kernel/query/relate/methods.d.ts +426 -0
  276. package/dist/kernel/query/relate/partition.d.ts +87 -0
  277. package/dist/kernel/query/relate/scan-methods.d.ts +163 -0
  278. package/dist/kernel/query/relate/traverse.d.ts +109 -0
  279. package/dist/kernel/query/scan-builder.d.ts +79 -176
  280. package/dist/kernel/query/sort-key.d.ts +52 -0
  281. package/dist/kernel/tx-write-gate.d.ts +77 -0
  282. package/dist/kernel/types.d.ts +71 -3
  283. package/dist/kernel/validation.d.ts +27 -10
  284. package/dist/kernel/vault.d.ts +9 -4
  285. package/dist/kernel/via/compose.d.ts +3 -0
  286. package/dist/kernel/via/index.d.ts +56 -0
  287. package/dist/kernel/via/pipeline.d.ts +48 -0
  288. package/dist/{ledger-F33ZVMTK.js → ledger-KZPCMVZY.js} +11 -11
  289. package/dist/liberate-GRLCZMW4.js +24 -0
  290. package/dist/link-set-JCMJ7ULP.js +30 -0
  291. package/dist/{managed-secret-PQYKSR6T.js → managed-secret-S3MQ6SH6.js} +10 -10
  292. package/dist/materialized-views/index.js +30 -23
  293. package/dist/{migrate-cek-5ENH64AA.js → migrate-cek-V7GKJZ7O.js} +2 -2
  294. package/dist/money/index.js +5 -5
  295. package/dist/noydb-SWQJ3MZS.js +97 -0
  296. package/dist/overlay-views/index.js +4 -4
  297. package/dist/periods/index.js +12 -12
  298. package/dist/pod/index.js +75 -68
  299. package/dist/{pod-handle-Q736KYON.js → pod-handle-WGDFB4C2.js} +9 -9
  300. package/dist/policy/index.js +10 -10
  301. package/dist/port/with/blob-strategy.d.ts +9 -0
  302. package/dist/port/with/collection-options.d.ts +5 -0
  303. package/dist/port/with/coverage-strategy.d.ts +83 -0
  304. package/dist/port/with/service-bus.d.ts +46 -0
  305. package/dist/port/with/strategies.d.ts +2 -0
  306. package/dist/portability/index.js +8 -8
  307. package/dist/{post-register-LNE2FE2A.js → post-register-SLSXIPBV.js} +6 -6
  308. package/dist/query/all/index.js +31 -0
  309. package/dist/query/index.js +20 -32
  310. package/dist/query/live/index.js +21 -0
  311. package/dist/query/live/index.js.map +1 -0
  312. package/dist/query/reduce/index.js +33 -0
  313. package/dist/query/reduce/index.js.map +1 -0
  314. package/dist/query/relate/index.js +56 -0
  315. package/dist/query/relate/index.js.map +1 -0
  316. package/dist/reduce/index.js +72 -18
  317. package/dist/reduce/index.js.map +1 -1
  318. package/dist/register-F3OYE7MJ.js +31 -0
  319. package/dist/registry-CILQFXFK.js +8 -0
  320. package/dist/registry-XNNYQVKV.js +8 -0
  321. package/dist/registry-YCDZV3VW.js +35 -0
  322. package/dist/registry-ZGYS33TE.js +24 -0
  323. package/dist/request-withdrawal-Z5NC6TXT.js +30 -0
  324. package/dist/{reveal-67RDQRIN.js → reveal-4BCKPEC2.js} +6 -6
  325. package/dist/revoke-ZL62WC2D.js +23 -0
  326. package/dist/satellites/index.js +1 -1
  327. package/dist/schema-update/index.js +2 -2
  328. package/dist/sealed-record/index.js +12 -12
  329. package/dist/search/index.js +11 -5
  330. package/dist/{seed-G42JYN56.js → seed-4JS2RJ4A.js} +12 -12
  331. package/dist/sequence/index.js +9 -9
  332. package/dist/session/index.js +9 -9
  333. package/dist/shadow/index.js +2 -2
  334. package/dist/signer-MBZZMXTC.js +24 -0
  335. package/dist/snapshots/index.js +10 -10
  336. package/dist/{stale-DDL7WQEZ.js → stale-TJ3DYZMQ.js} +10 -10
  337. package/dist/storage-SVMKRGCW.js +22 -0
  338. package/dist/{store-coordination-provider-MEQ2MJQG.js → store-coordination-provider-2O2VUHKW.js} +10 -10
  339. package/dist/sync/index.js +10 -10
  340. package/dist/team/index.js +17 -15
  341. package/dist/tiers/index.js +13 -11
  342. package/dist/to/index.js +2 -2
  343. package/dist/transactions/index.js +3 -3
  344. package/dist/util/index.js +1 -1
  345. package/dist/vault-head/index.js +8 -8
  346. package/dist/{verify-KOV2G5D6.js → verify-RVT67IMH.js} +5 -5
  347. package/dist/via/blob/index.d.ts +1 -0
  348. package/dist/via/geo/binding.d.ts +31 -0
  349. package/dist/via/geo/descriptor.d.ts +54 -0
  350. package/dist/via/geo/geohash.d.ts +95 -0
  351. package/dist/via/geo/index.d.ts +13 -0
  352. package/dist/via/geo/where.d.ts +50 -0
  353. package/dist/via/i18n/core.d.ts +1 -1
  354. package/dist/via/lookup/registry.d.ts +1 -1
  355. package/dist/via/lookup/snapshot.d.ts +3 -3
  356. package/dist/walk-HJ42EISE.js +21 -0
  357. package/dist/walk-HJ42EISE.js.map +1 -0
  358. package/dist/with-audit/coverage/accounting.d.ts +112 -0
  359. package/dist/with-audit/coverage/active.d.ts +29 -0
  360. package/dist/with-audit/coverage/index.d.ts +61 -0
  361. package/dist/with-audit/coverage/sketch.d.ts +75 -0
  362. package/dist/with-audit/periods/periods.d.ts +55 -7
  363. package/dist/with-audit/periods/reserved-collections.d.ts +3 -0
  364. package/dist/with-audit/periods/vault-facade.d.ts +17 -0
  365. package/dist/with-audit/tiers/index.d.ts +51 -0
  366. package/dist/with-audit/tiers/strategy.d.ts +8 -0
  367. package/dist/with-cargo/floor.d.ts +2 -2
  368. package/dist/with-commit/tx/invariants.d.ts +1 -1
  369. package/dist/with-commit/tx/transaction.d.ts +13 -3
  370. package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +4 -3
  371. package/dist/with-formula/materialized-views/emit-memo.d.ts +40 -0
  372. package/dist/with-formula/materialized-views/executor.d.ts +8 -0
  373. package/dist/with-formula/materialized-views/index.d.ts +1 -1
  374. package/dist/with-formula/materialized-views/registry.d.ts +15 -0
  375. package/dist/with-formula/materialized-views/types.d.ts +106 -14
  376. package/dist/with-formula/materialized-views/window-stage.d.ts +11 -0
  377. package/dist/with-formula/overlay-views/types.d.ts +1 -1
  378. package/dist/with-formula/overlay-views/virtual-collection.d.ts +13 -4
  379. package/dist/with-lookup/embeddings/chunks.d.ts +79 -0
  380. package/dist/with-lookup/embeddings/descriptor.d.ts +21 -0
  381. package/dist/with-lookup/embeddings/index.d.ts +3 -0
  382. package/dist/with-lookup/embeddings/ivf-flat.d.ts +93 -0
  383. package/dist/with-lookup/embeddings/vector-index.d.ts +73 -0
  384. package/dist/with-lookup/embeddings/vector-set.d.ts +94 -1
  385. package/dist/with-lookup/embeddings/with-vector-index.d.ts +67 -0
  386. package/dist/with-lookup/indexing/collection-facade.d.ts +85 -2
  387. package/dist/with-lookup/indexing/compound-indexes.d.ts +129 -0
  388. package/dist/with-lookup/indexing/eager-indexes.d.ts +170 -1
  389. package/dist/with-lookup/indexing/index-snapshot.d.ts +62 -0
  390. package/dist/with-lookup/indexing/lazy-builder.d.ts +33 -0
  391. package/dist/with-lookup/indexing/persisted-field-indexes.d.ts +104 -0
  392. package/dist/with-lookup/indexing/persisted-indexes.d.ts +12 -0
  393. package/dist/with-lookup/indexing/sorted-indexes.d.ts +117 -0
  394. package/dist/with-lookup/indexing/unique-constraints.d.ts +106 -23
  395. package/dist/with-lookup/reduce/active.d.ts +2 -24
  396. package/dist/with-lookup/reduce/group-core.d.ts +43 -0
  397. package/dist/with-lookup/reduce/groupby.d.ts +195 -36
  398. package/dist/with-lookup/reduce/incremental-group.d.ts +153 -0
  399. package/dist/with-lookup/reduce/index.d.ts +26 -5
  400. package/dist/with-lookup/reduce/reducers.d.ts +255 -1
  401. package/dist/with-lookup/reduce/reduction.d.ts +44 -13
  402. package/dist/with-lookup/reduce/strategy.d.ts +43 -3
  403. package/dist/with-lookup/reduce/window.d.ts +262 -0
  404. package/dist/with-lookup/search/collection-facade.d.ts +44 -8
  405. package/dist/with-lookup/search/index-store.d.ts +5 -3
  406. package/dist/with-lookup/search/index.d.ts +4 -2
  407. package/dist/with-lookup/search/inverted-index.d.ts +38 -2
  408. package/dist/with-lookup/search/persisted-index-store.d.ts +5 -2
  409. package/dist/with-lookup/search/phrase.d.ts +28 -0
  410. package/dist/with-lookup/search/retrieve-types.d.ts +57 -1
  411. package/dist/with-lookup/search/serialize.d.ts +29 -3
  412. package/dist/with-lookup/search/strategy.d.ts +2 -6
  413. package/dist/with-party/directory/cover/index.d.ts +1 -1
  414. package/dist/with-party/directory/cover/storage.d.ts +1 -1
  415. package/dist/with-party/directory/cover/types.d.ts +1 -1
  416. package/dist/with-party/directory/index.d.ts +1 -1
  417. package/dist/with-party/directory/types.d.ts +1 -1
  418. package/dist/with-party/directory/user-envelope/api.d.ts +1 -1
  419. package/dist/with-party/policy/engine.d.ts +1 -1
  420. package/dist/with-party/policy/index.d.ts +1 -1
  421. package/dist/with-party/policy/presets.d.ts +1 -1
  422. package/dist/with-party/team/authenticators.d.ts +91 -1
  423. package/dist/with-party/team/index.d.ts +3 -2
  424. package/dist/with-party/team/keyring.d.ts +13 -6
  425. package/dist/with-party/team/managed-secret.d.ts +1 -1
  426. package/dist/with-party/team/noydb-facade.d.ts +12 -3
  427. package/dist/with-party/team/wrapped-deks.d.ts +4 -4
  428. package/dist/with-pod/format.d.ts +1 -1
  429. package/dist/with-pod/pod.d.ts +5 -5
  430. package/dist/with-shape/blobs/blob-compaction.d.ts +16 -0
  431. package/dist/with-shape/blobs/blob-set.d.ts +21 -2
  432. package/dist/with-shape/blobs/legacy-sweep.d.ts +35 -0
  433. package/dist/with-shape/introspection/describe.d.ts +6 -0
  434. package/dist/with-shape/introspection/field-meta.d.ts +18 -0
  435. package/dist/with-shape/introspection/types.d.ts +57 -1
  436. package/dist/with-shape/links/vault-facade.d.ts +1 -1
  437. package/dist/with-store/partitioned/index.d.ts +337 -0
  438. package/dist/with-sync/change-broadcast.d.ts +153 -0
  439. package/dist/withdraw-accessible-5NZUPAVA.js +27 -0
  440. package/dist/withdraw-accessible-5NZUPAVA.js.map +1 -0
  441. package/package.json +37 -10
  442. package/dist/api-TXFOVOXX.js +0 -19
  443. package/dist/backup-IJTB4S4M.js.map +0 -1
  444. package/dist/chunk-2577DKXB.js.map +0 -1
  445. package/dist/chunk-2C3AQB46.js.map +0 -1
  446. package/dist/chunk-4GVM6QZA.js.map +0 -1
  447. package/dist/chunk-5WDXHNSW.js.map +0 -1
  448. package/dist/chunk-6GOE5PGN.js.map +0 -1
  449. package/dist/chunk-6X6SEMEE.js.map +0 -1
  450. package/dist/chunk-77K4PG6P.js.map +0 -1
  451. package/dist/chunk-7MG2LHO5.js +0 -1616
  452. package/dist/chunk-7MG2LHO5.js.map +0 -1
  453. package/dist/chunk-7MG7SJT7.js.map +0 -1
  454. package/dist/chunk-7O3Y4PPD.js.map +0 -1
  455. package/dist/chunk-AO42KJO6.js.map +0 -1
  456. package/dist/chunk-ATL3ZVXT.js +0 -151
  457. package/dist/chunk-ATL3ZVXT.js.map +0 -1
  458. package/dist/chunk-BLN54W3L.js.map +0 -1
  459. package/dist/chunk-BM5TWITZ.js.map +0 -1
  460. package/dist/chunk-CUZLNGD5.js.map +0 -1
  461. package/dist/chunk-EQEYOJBM.js.map +0 -1
  462. package/dist/chunk-G56KBWFY.js.map +0 -1
  463. package/dist/chunk-I3ISCYT7.js +0 -159
  464. package/dist/chunk-I3ISCYT7.js.map +0 -1
  465. package/dist/chunk-KG7TZKZG.js.map +0 -1
  466. package/dist/chunk-KJIMGIWO.js.map +0 -1
  467. package/dist/chunk-KTFRCC5C.js.map +0 -1
  468. package/dist/chunk-KUX3OB6D.js.map +0 -1
  469. package/dist/chunk-MUM7IANK.js.map +0 -1
  470. package/dist/chunk-NA2NIJZI.js.map +0 -1
  471. package/dist/chunk-NSITFOCJ.js +0 -99
  472. package/dist/chunk-NSITFOCJ.js.map +0 -1
  473. package/dist/chunk-PT43Y56J.js.map +0 -1
  474. package/dist/chunk-QIBVIOXO.js.map +0 -1
  475. package/dist/chunk-RRNRNANG.js.map +0 -1
  476. package/dist/chunk-RTBJ5IOO.js +0 -87
  477. package/dist/chunk-RTBJ5IOO.js.map +0 -1
  478. package/dist/chunk-SKGMN35F.js.map +0 -1
  479. package/dist/chunk-SL3JAAKN.js.map +0 -1
  480. package/dist/chunk-SPXXX5E4.js.map +0 -1
  481. package/dist/chunk-SPYWXKJN.js.map +0 -1
  482. package/dist/chunk-U4FOQDY4.js.map +0 -1
  483. package/dist/chunk-UXVWEX5L.js.map +0 -1
  484. package/dist/chunk-UXWB3FPF.js.map +0 -1
  485. package/dist/chunk-YMUFFJCO.js.map +0 -1
  486. package/dist/chunk-ZN4FD4PE.js +0 -364
  487. package/dist/chunk-ZN4FD4PE.js.map +0 -1
  488. package/dist/chunk-ZORTV6NH.js.map +0 -1
  489. package/dist/collection-facade-4GRREZ6C.js +0 -45
  490. package/dist/derive-6O5SWQKN.js +0 -21
  491. package/dist/executor-5NIMLSKZ.js +0 -8
  492. package/dist/executor-AQVXV5GZ.js +0 -8
  493. package/dist/executor-PUAO6AKJ.js +0 -29
  494. package/dist/export-accessible-72EQNBMR.js +0 -22
  495. package/dist/extract-partition-PUYNU3UF.js +0 -37
  496. package/dist/find-2ABFCZX4.js +0 -10
  497. package/dist/issue-SIDORTSZ.js +0 -18
  498. package/dist/json-schema-V3M5MUCM.js.map +0 -1
  499. package/dist/kernel/query/join.d.ts +0 -232
  500. package/dist/liberate-LCDPNAG2.js +0 -24
  501. package/dist/link-set-FKNWAYKS.js +0 -30
  502. package/dist/noydb-DUXZPKSN.js +0 -90
  503. package/dist/register-I2DZXGAR.js +0 -31
  504. package/dist/registry-23WF3TGH.js +0 -8
  505. package/dist/registry-4AYVUNXK.js +0 -8
  506. package/dist/registry-VSSQPIGF.js +0 -18
  507. package/dist/registry-YLEWMGAC.js +0 -32
  508. package/dist/request-withdrawal-KFQHEZ25.js +0 -30
  509. package/dist/revoke-DQDZAZZM.js +0 -23
  510. package/dist/signer-WAMDZHEN.js +0 -24
  511. package/dist/storage-FLR73HHF.js +0 -22
  512. package/dist/walk-3UQBRMDV.js +0 -21
  513. package/dist/withdraw-accessible-EL5GXZBS.js +0 -27
  514. /package/dist/{api-TXFOVOXX.js.map → api-GVYEKSJE.js.map} +0 -0
  515. /package/dist/{chunk-BUE2D7PX.js.map → chunk-32YV3TJT.js.map} +0 -0
  516. /package/dist/{chunk-3RCJJBNR.js.map → chunk-3ELRMVJK.js.map} +0 -0
  517. /package/dist/{chunk-6GMZ7HEE.js.map → chunk-3F7GLNAE.js.map} +0 -0
  518. /package/dist/{chunk-2Y4IMKA6.js.map → chunk-3H5KLDZN.js.map} +0 -0
  519. /package/dist/{chunk-VTFVLCUH.js.map → chunk-3JWHAR6E.js.map} +0 -0
  520. /package/dist/{chunk-JBDFMYKQ.js.map → chunk-4AF3TUMP.js.map} +0 -0
  521. /package/dist/{chunk-J6FXAEUG.js.map → chunk-6B3VNR4P.js.map} +0 -0
  522. /package/dist/{chunk-TUFM4UZP.js.map → chunk-6K7DPM7D.js.map} +0 -0
  523. /package/dist/{chunk-K6LHRFBL.js.map → chunk-6LMQ5R26.js.map} +0 -0
  524. /package/dist/{chunk-XLMEZIAJ.js.map → chunk-6OWXYZK2.js.map} +0 -0
  525. /package/dist/{chunk-BOWNCWZT.js.map → chunk-6QSQQLSE.js.map} +0 -0
  526. /package/dist/{chunk-NQKIUNW5.js.map → chunk-A6IJU4TK.js.map} +0 -0
  527. /package/dist/{chunk-QIZPZMUI.js.map → chunk-AOWGXU6D.js.map} +0 -0
  528. /package/dist/{chunk-SFAWCTEM.js.map → chunk-B57AFBY2.js.map} +0 -0
  529. /package/dist/{chunk-GPEQUXHL.js.map → chunk-B6SJIBQK.js.map} +0 -0
  530. /package/dist/{chunk-Q2PU57HC.js.map → chunk-BK2HHQGN.js.map} +0 -0
  531. /package/dist/{collection-facade-4GRREZ6C.js.map → chunk-BKT776R5.js.map} +0 -0
  532. /package/dist/{chunk-FXBIP2WD.js.map → chunk-BUDAGWL5.js.map} +0 -0
  533. /package/dist/{chunk-BOET4NA4.js.map → chunk-CKNGS5MH.js.map} +0 -0
  534. /package/dist/{chunk-YSRUYAVU.js.map → chunk-DE4DH2RZ.js.map} +0 -0
  535. /package/dist/{chunk-6I2RQCET.js.map → chunk-DF73H4UN.js.map} +0 -0
  536. /package/dist/{chunk-K7NTTA6P.js.map → chunk-EOVMT6TB.js.map} +0 -0
  537. /package/dist/{chunk-XTXOCYOJ.js.map → chunk-FCKWQE2H.js.map} +0 -0
  538. /package/dist/{chunk-4OZNXTO4.js.map → chunk-FN5EBVTQ.js.map} +0 -0
  539. /package/dist/{chunk-NKHRDYOR.js.map → chunk-FQ5VRHIB.js.map} +0 -0
  540. /package/dist/{chunk-FAHMLERK.js.map → chunk-FW22ZCXT.js.map} +0 -0
  541. /package/dist/{chunk-RMS3NEA3.js.map → chunk-HT2AHGQI.js.map} +0 -0
  542. /package/dist/{chunk-CHJBLCOG.js.map → chunk-HVSCEIYL.js.map} +0 -0
  543. /package/dist/{chunk-GY4WYNNG.js.map → chunk-ID6Z6E66.js.map} +0 -0
  544. /package/dist/{chunk-EYBQEIUY.js.map → chunk-IEX7NK2K.js.map} +0 -0
  545. /package/dist/{chunk-KUJDV5QH.js.map → chunk-ISZQJBML.js.map} +0 -0
  546. /package/dist/{chunk-LWBCUYZW.js.map → chunk-IT22PWKV.js.map} +0 -0
  547. /package/dist/{chunk-7V4TP3AF.js.map → chunk-J6UOHJY5.js.map} +0 -0
  548. /package/dist/{chunk-JMGDHKQF.js.map → chunk-JCN44NCY.js.map} +0 -0
  549. /package/dist/{chunk-CARABLSQ.js.map → chunk-K6W7BVZ6.js.map} +0 -0
  550. /package/dist/{chunk-453F654R.js.map → chunk-L7DOS3TE.js.map} +0 -0
  551. /package/dist/{chunk-WEQEYLCS.js.map → chunk-LGRLME4M.js.map} +0 -0
  552. /package/dist/{chunk-RMF67KCG.js.map → chunk-LQ4ZHOKP.js.map} +0 -0
  553. /package/dist/{chunk-ZVO4QVPD.js.map → chunk-M522UYZ2.js.map} +0 -0
  554. /package/dist/{chunk-2N4GY74U.js.map → chunk-MTL7MXGR.js.map} +0 -0
  555. /package/dist/{chunk-TFR7DSOV.js.map → chunk-MVZ2TPVP.js.map} +0 -0
  556. /package/dist/{chunk-CPWQB3N5.js.map → chunk-N5DNADLQ.js.map} +0 -0
  557. /package/dist/{chunk-ELNXJMGB.js.map → chunk-NNARWO72.js.map} +0 -0
  558. /package/dist/{chunk-6YXCPL4T.js.map → chunk-PDCG6PR5.js.map} +0 -0
  559. /package/dist/{chunk-REDOOY2Q.js.map → chunk-PSIV7CJV.js.map} +0 -0
  560. /package/dist/{chunk-ANATMFIO.js.map → chunk-QWFHIOD2.js.map} +0 -0
  561. /package/dist/{chunk-X2DLENDQ.js.map → chunk-QWGU66MP.js.map} +0 -0
  562. /package/dist/{chunk-BSFNRLK2.js.map → chunk-S57HTZ6X.js.map} +0 -0
  563. /package/dist/{chunk-SZJ3DLZA.js.map → chunk-SEE332EV.js.map} +0 -0
  564. /package/dist/{chunk-YYP7WSEB.js.map → chunk-SI3V7D4G.js.map} +0 -0
  565. /package/dist/{chunk-UGTBXF5U.js.map → chunk-SOIQ4MM4.js.map} +0 -0
  566. /package/dist/{chunk-VXGSWL6L.js.map → chunk-SYVZW77S.js.map} +0 -0
  567. /package/dist/{chunk-MVMXZYXT.js.map → chunk-TKUOEU2F.js.map} +0 -0
  568. /package/dist/{chunk-SMH6SRX7.js.map → chunk-TROR3ALR.js.map} +0 -0
  569. /package/dist/{chunk-DGOZ4UZD.js.map → chunk-VNNRUGMM.js.map} +0 -0
  570. /package/dist/{chunk-HDOU6I2Y.js.map → chunk-VNPEWFPD.js.map} +0 -0
  571. /package/dist/{chunk-L7CIOOBW.js.map → chunk-WNJ4AVGE.js.map} +0 -0
  572. /package/dist/{chunk-FMZY5Q6L.js.map → chunk-WX5ADGTZ.js.map} +0 -0
  573. /package/dist/{chunk-Q7HZX3IF.js.map → chunk-X4773RBR.js.map} +0 -0
  574. /package/dist/{chunk-ANSIZYEG.js.map → chunk-YNIUIERI.js.map} +0 -0
  575. /package/dist/{chunk-BZ3534YM.js.map → chunk-ZUVBC32X.js.map} +0 -0
  576. /package/dist/{chunk-L742JPKZ.js.map → chunk-ZXABPVM6.js.map} +0 -0
  577. /package/dist/{classified-marker-LI2SF2E4.js.map → classified-marker-W3USLL5M.js.map} +0 -0
  578. /package/dist/{computed-VPOKQK4N.js.map → collection-facade-QU6IJBN3.js.map} +0 -0
  579. /package/dist/{derive-6O5SWQKN.js.map → computed-TPFBX7U4.js.map} +0 -0
  580. /package/dist/{dead-filter-TSWZQRR5.js.map → dead-filter-U2UYKSZL.js.map} +0 -0
  581. /package/dist/{delegation-OVIFFPG4.js.map → delegation-S3AEPW2T.js.map} +0 -0
  582. /package/dist/{enclave-KJOTOH7X.js.map → derive-OX7F6TGG.js.map} +0 -0
  583. /package/dist/{dispatch-WC6X2M6C.js.map → dispatch-3CQDJV5Q.js.map} +0 -0
  584. /package/dist/{dispatch-S73TK3IY.js.map → dispatch-RH4LHKBH.js.map} +0 -0
  585. /package/dist/{executor-5NIMLSKZ.js.map → enclave-27SMF6GF.js.map} +0 -0
  586. /package/dist/{executor-AQVXV5GZ.js.map → executor-B6SRO2QS.js.map} +0 -0
  587. /package/dist/{executor-PUAO6AKJ.js.map → executor-BI5CHWRY.js.map} +0 -0
  588. /package/dist/{export-accessible-72EQNBMR.js.map → executor-RBKM5W5K.js.map} +0 -0
  589. /package/dist/{extract-partition-PUYNU3UF.js.map → export-accessible-VMA3YM5V.js.map} +0 -0
  590. /package/dist/{find-2ABFCZX4.js.map → extract-partition-NF7PXGPP.js.map} +0 -0
  591. /package/dist/{fanout-sidecar-WUFXNYP4.js.map → fanout-sidecar-OT6RYLOL.js.map} +0 -0
  592. /package/dist/{issue-SIDORTSZ.js.map → find-LZMP26KF.js.map} +0 -0
  593. /package/dist/{ledger-F33ZVMTK.js.map → issue-IHARXWW5.js.map} +0 -0
  594. /package/dist/{liberate-LCDPNAG2.js.map → ledger-KZPCMVZY.js.map} +0 -0
  595. /package/dist/{link-set-FKNWAYKS.js.map → liberate-GRLCZMW4.js.map} +0 -0
  596. /package/dist/{managed-secret-PQYKSR6T.js.map → link-set-JCMJ7ULP.js.map} +0 -0
  597. /package/dist/{noydb-DUXZPKSN.js.map → managed-secret-S3MQ6SH6.js.map} +0 -0
  598. /package/dist/{migrate-cek-5ENH64AA.js.map → migrate-cek-V7GKJZ7O.js.map} +0 -0
  599. /package/dist/{register-I2DZXGAR.js.map → noydb-SWQJ3MZS.js.map} +0 -0
  600. /package/dist/{pod-handle-Q736KYON.js.map → pod-handle-WGDFB4C2.js.map} +0 -0
  601. /package/dist/{post-register-LNE2FE2A.js.map → post-register-SLSXIPBV.js.map} +0 -0
  602. /package/dist/{registry-23WF3TGH.js.map → query/all/index.js.map} +0 -0
  603. /package/dist/{registry-4AYVUNXK.js.map → register-F3OYE7MJ.js.map} +0 -0
  604. /package/dist/{registry-VSSQPIGF.js.map → registry-CILQFXFK.js.map} +0 -0
  605. /package/dist/{registry-YLEWMGAC.js.map → registry-XNNYQVKV.js.map} +0 -0
  606. /package/dist/{request-withdrawal-KFQHEZ25.js.map → registry-YCDZV3VW.js.map} +0 -0
  607. /package/dist/{revoke-DQDZAZZM.js.map → registry-ZGYS33TE.js.map} +0 -0
  608. /package/dist/{signer-WAMDZHEN.js.map → request-withdrawal-Z5NC6TXT.js.map} +0 -0
  609. /package/dist/{reveal-67RDQRIN.js.map → reveal-4BCKPEC2.js.map} +0 -0
  610. /package/dist/{stale-DDL7WQEZ.js.map → revoke-ZL62WC2D.js.map} +0 -0
  611. /package/dist/{seed-G42JYN56.js.map → seed-4JS2RJ4A.js.map} +0 -0
  612. /package/dist/{storage-FLR73HHF.js.map → signer-MBZZMXTC.js.map} +0 -0
  613. /package/dist/{walk-3UQBRMDV.js.map → stale-TJ3DYZMQ.js.map} +0 -0
  614. /package/dist/{withdraw-accessible-EL5GXZBS.js.map → storage-SVMKRGCW.js.map} +0 -0
  615. /package/dist/{store-coordination-provider-MEQ2MJQG.js.map → store-coordination-provider-2O2VUHKW.js.map} +0 -0
  616. /package/dist/{verify-KOV2G5D6.js.map → verify-RVT67IMH.js.map} +0 -0
@@ -0,0 +1,1289 @@
1
+ import {
2
+ DEFAULT_CROSS_JOIN_MAX_ROWS,
3
+ DEFAULT_JOIN_MAX_ROWS,
4
+ applyJoins,
5
+ bucketByRefKey,
6
+ coerceRefKey,
7
+ joinsDropLeftRows,
8
+ orderReferencesJoinAlias,
9
+ splitAroundJoins
10
+ } from "./chunk-4I522ERM.js";
11
+ import {
12
+ describeJoinOn,
13
+ joinOnDispatch,
14
+ normalizeJoinOn
15
+ } from "./chunk-MKXXMNJH.js";
16
+ import {
17
+ ScanBuilder
18
+ } from "./chunk-F24ZZTHQ.js";
19
+ import {
20
+ installMethods
21
+ } from "./chunk-F6NCB7KT.js";
22
+ import {
23
+ Query,
24
+ indexableClauses,
25
+ installRelateHooks,
26
+ isRangeOperator,
27
+ pickCompound,
28
+ pickCompoundOrder,
29
+ viaOrdersField
30
+ } from "./chunk-7JE7BDYJ.js";
31
+ import {
32
+ gateTerminal
33
+ } from "./chunk-5O7D6ZTW.js";
34
+ import {
35
+ readPath
36
+ } from "./chunk-HLEK5VAN.js";
37
+ import {
38
+ isViaPrefixProbe
39
+ } from "./chunk-Z5HTYMMQ.js";
40
+ import {
41
+ CrossJoinTooLargeError,
42
+ DanglingReferenceError,
43
+ RefNotDeclaredError,
44
+ TraversalCycleError
45
+ } from "./chunk-244VXYPG.js";
46
+
47
+ // src/kernel/query/relate/explain.ts
48
+ var WARN_FRACTION = 0.8;
49
+ function tupleSourceOf(indexes) {
50
+ return { compoundTuples: () => indexes.compoundTuples?.() ?? [] };
51
+ }
52
+ function indexDispatchFor(source, clauses) {
53
+ const indexes = source.getIndexes?.();
54
+ if (!indexes || !source.lookupById || clauses.length === 0) return null;
55
+ const compound = compoundDispatchFor(source, indexes, clauses);
56
+ if (compound) return compound;
57
+ const prefixed = prefixDispatchFor(indexes, clauses);
58
+ if (prefixed) return prefixed;
59
+ for (let i = 0; i < clauses.length; i++) {
60
+ const clause = clauses[i];
61
+ if (clause.type !== "field") continue;
62
+ if (!indexes.has(clause.field) && indexes.hasSorted?.(clause.field) !== true) continue;
63
+ if (clause.via && clause.via.indexValue === void 0) continue;
64
+ const probeValue = clause.via ? clause.via.indexValue : clause.value;
65
+ let ids = null;
66
+ let dispatch = "index:hash";
67
+ if (clause.op === "==") {
68
+ ids = indexes.lookupEqual(clause.field, probeValue);
69
+ } else if (clause.op === "in" && Array.isArray(probeValue)) {
70
+ ids = indexes.lookupIn(clause.field, probeValue);
71
+ } else if (clause.via === void 0 && isRangeOperator(clause.op)) {
72
+ ids = indexes.lookupRange?.(clause.field, clause.op, clause.value) ?? null;
73
+ dispatch = "index:range";
74
+ }
75
+ if (ids !== null) return { consumed: /* @__PURE__ */ new Map([[i, dispatch]]), rows: ids.size };
76
+ }
77
+ return null;
78
+ }
79
+ function prefixDispatchFor(indexes, clauses) {
80
+ for (let i = 0; i < clauses.length; i++) {
81
+ const clause = clauses[i];
82
+ if (clause.type !== "field" || clause.via === void 0) continue;
83
+ const probe = clause.via.indexValue;
84
+ if (!isViaPrefixProbe(probe)) continue;
85
+ if (indexes.hasSorted?.(clause.field) !== true) continue;
86
+ const ids = /* @__PURE__ */ new Set();
87
+ for (const prefix of probe.prefixes) {
88
+ const hit = indexes.lookupRange?.(clause.field, "startsWith", prefix) ?? null;
89
+ if (hit === null) return null;
90
+ for (const id of hit) ids.add(id);
91
+ }
92
+ return { consumed: /* @__PURE__ */ new Map([[i, "index:prefix"]]), rows: ids.size };
93
+ }
94
+ return null;
95
+ }
96
+ function compoundDispatchFor(source, indexes, clauses) {
97
+ const pick = pickCompound(tupleSourceOf(indexes), clauses);
98
+ if (!pick) return null;
99
+ if (indexes.compoundSize?.(pick.fields) !== source.snapshot().length) return null;
100
+ const ids = indexes.lookupCompound?.(pick.fields, pick.values, pick.range) ?? null;
101
+ if (!ids) return null;
102
+ const consumed = /* @__PURE__ */ new Map();
103
+ for (const at of pick.consumed) consumed.set(at, "index:compound");
104
+ return { consumed, rows: ids.size };
105
+ }
106
+ function orderedIndexPick(source, plan) {
107
+ const limit = plan.limit;
108
+ if (limit === void 0 || plan.orderBy.length !== 1) return null;
109
+ const [order] = plan.orderBy;
110
+ if (!order || order.by === "label") return null;
111
+ const indexes = source.getIndexes?.();
112
+ if (!indexes || !source.lookupById) return null;
113
+ if (viaOrdersField(source.via, order.field)) return null;
114
+ const snapshotRows = source.snapshot().length;
115
+ if (plan.clauses.length === 0) {
116
+ if (indexes.hasSorted?.(order.field) !== true) return null;
117
+ if (indexes.sortedSize?.(order.field) !== snapshotRows) return null;
118
+ const ids2 = indexes.orderedIds?.(order.field, order.direction) ?? null;
119
+ if (!ids2) return null;
120
+ return { rows: pageOf(ids2.length, plan.offset, limit), clauseDispatch: null, detail: `sorted index on "${order.field}"` };
121
+ }
122
+ const { eq } = indexableClauses(plan.clauses);
123
+ if (eq.size !== plan.clauses.length) return null;
124
+ const match = pickCompoundOrder(tupleSourceOf(indexes), eq, order.field);
125
+ if (!match) return null;
126
+ if (indexes.compoundSize?.(match.fields) !== snapshotRows) return null;
127
+ const ids = indexes.compoundOrderedIds?.(match.fields, match.values, order.direction) ?? null;
128
+ if (!ids) return null;
129
+ return {
130
+ rows: pageOf(ids.length, plan.offset, limit),
131
+ clauseDispatch: "index:compound",
132
+ detail: `compound index on (${match.fields.join(", ")})`
133
+ };
134
+ }
135
+ function pageOf(total, offset, limit) {
136
+ return Math.min(Math.max(0, total - offset), limit);
137
+ }
138
+ function isSupersetDispatch(dispatch, clause) {
139
+ if (dispatch === "index:prefix" || dispatch === "index:compound") return true;
140
+ if (dispatch !== "index:hash") return false;
141
+ return clause.type === "field" && (clause.op === "==" || clause.op === "in");
142
+ }
143
+ function describeClause(clause) {
144
+ switch (clause.type) {
145
+ case "field": {
146
+ const detail = clause.subquery !== void 0 ? `${clause.field} ${clause.op} subquery(${clause.subquery.from}) \u2192 ${clause.subquery.ids} ids` : `${clause.field} ${clause.op} ${formatValue(clause.value)}`;
147
+ return { op: "where", detail };
148
+ }
149
+ case "group":
150
+ return { op: "group", detail: `${clause.op} (${clause.clauses.length} clause${clause.clauses.length === 1 ? "" : "s"})` };
151
+ case "filter":
152
+ return { op: "filter", detail: "fn" };
153
+ case "wherePredicate":
154
+ return { op: "wherePredicate", detail: clause.name };
155
+ case "crossJoin":
156
+ return {
157
+ op: clause.leftAs === void 0 ? "crossJoin" : "crossJoinWith",
158
+ detail: (clause.leftAs === void 0 ? `${clause.as} x ${clause.target}` : `${clause.leftAs} x ${clause.as} (self ${clause.target})`) + `${clause.on ? " on fn" : ""}${clause.outer === true ? " outer" : ""}`
159
+ };
160
+ }
161
+ }
162
+ function formatValue(value) {
163
+ if (typeof value === "bigint") return `${value.toString()}n`;
164
+ try {
165
+ const json = JSON.stringify(value);
166
+ return json === void 0 ? String(value) : json;
167
+ } catch {
168
+ return "[unserializable]";
169
+ }
170
+ }
171
+ function referencedFields(plan) {
172
+ const out = [];
173
+ const walk = (clauses) => {
174
+ for (const c of clauses) {
175
+ if (c.type === "field") out.push(c.field);
176
+ else if (c.type === "group") walk(c.clauses);
177
+ }
178
+ };
179
+ walk(plan.clauses);
180
+ for (const o of plan.orderBy) out.push(o.field);
181
+ return [...new Set(out)];
182
+ }
183
+ function capStatus(observed, limit) {
184
+ if (observed > limit) return "exceeded";
185
+ if (observed > limit * WARN_FRACTION) return "warn";
186
+ return "ok";
187
+ }
188
+ function explainPlan(source, plan, joinContext) {
189
+ const nodes = [];
190
+ const caps = [];
191
+ const indexes = source.getIndexes?.() ?? null;
192
+ const indexedFields = indexes ? indexes.fields() : [];
193
+ const sourceRows = source.snapshot().length;
194
+ let rows = sourceRows;
195
+ const reducerRewrite = collectReducerRewrites(source.via, referencedFields(plan));
196
+ const sourceNotes = [];
197
+ const notHydrated = source.hydration?.isHydrated() === false;
198
+ if (notHydrated) {
199
+ sourceNotes.push(
200
+ "collection not hydrated \u2014 this plan's row estimates are not authoritative; call `await collection.list()` / `await collection.get(id)` first"
201
+ );
202
+ }
203
+ for (const r of reducerRewrite) {
204
+ sourceNotes.push(`reducer rewrite: ${r.brand}("${r.field}")`);
205
+ }
206
+ nodes.push({
207
+ op: "source",
208
+ dispatch: "source",
209
+ detail: notHydrated ? `snapshot (NOT HYDRATED \u2014 nothing has been read yet${indexedFields.length > 0 ? `; indexes: ${indexedFields.join(", ")}` : ""})` : indexedFields.length > 0 ? `snapshot (indexes: ${indexedFields.join(", ")})` : "snapshot (no indexes)",
210
+ estimatedRows: sourceRows,
211
+ notes: sourceNotes,
212
+ children: []
213
+ });
214
+ const hasCrossJoin = plan.clauses.some((c) => c.type === "crossJoin");
215
+ const { preJoin, postJoin } = splitAroundJoins(plan.clauses, plan.joins);
216
+ const orderPostJoin = orderReferencesJoinAlias(plan.orderBy, plan.joins);
217
+ const runsPostJoin = postJoin.length > 0 || orderPostJoin;
218
+ const innerSplit = !runsPostJoin && plan.joins.length > 0 && joinsDropLeftRows(plan.joins);
219
+ let ordered = null;
220
+ if (hasCrossJoin) {
221
+ for (const clause of plan.clauses) {
222
+ if (clause.type === "crossJoin") {
223
+ const rightRows = joinContext?.resolveSource(clause.target)?.snapshot().length;
224
+ const limit = clause.maxRows ?? DEFAULT_CROSS_JOIN_MAX_ROWS;
225
+ const product = rows !== void 0 && rightRows !== void 0 ? rows * rightRows : void 0;
226
+ const { op, detail } = describeClause(clause);
227
+ const notes = [
228
+ rightRows === void 0 ? "right side unresolved" : `right side ${rightRows} rows`,
229
+ `cap ${limit}`
230
+ ];
231
+ nodes.push({ op, dispatch: "crossJoin", detail, estimatedRows: product, notes, children: [] });
232
+ if (product !== void 0) {
233
+ caps.push({ name: `crossJoin:${clause.as}`, limit, observed: product, status: capStatus(product, limit) });
234
+ }
235
+ rows = product;
236
+ } else {
237
+ nodes.push(scanNode(clause, rows, ["index fast path unavailable: the plan carries a crossJoin"]));
238
+ }
239
+ }
240
+ } else {
241
+ ordered = runsPostJoin || innerSplit ? null : orderedIndexPick(source, plan);
242
+ const pick = ordered ? null : indexDispatchFor(source, preJoin);
243
+ if (ordered) rows = ordered.rows;
244
+ preJoin.forEach((clause, i) => {
245
+ const dispatch = ordered ? ordered.clauseDispatch : pick?.consumed.get(i) ?? null;
246
+ if (dispatch !== null) {
247
+ const { op, detail } = describeClause(clause);
248
+ if (pick) rows = pick.rows;
249
+ const notes = isSupersetDispatch(dispatch, clause) ? [`${dispatch === "index:prefix" ? "prefix cover" : "index match"} is a superset: the clause still filters the candidates exactly`] : [];
250
+ nodes.push({ op, dispatch, detail, estimatedRows: rows, notes, children: [] });
251
+ return;
252
+ }
253
+ nodes.push(scanNode(clause, rows, scanReason(clause, indexes, pick !== null)));
254
+ });
255
+ }
256
+ const emitJoins = () => {
257
+ for (const leg of plan.joins) {
258
+ nodes.push(joinNode(leg, joinContext, rows, caps));
259
+ }
260
+ };
261
+ if (runsPostJoin) {
262
+ emitJoins();
263
+ for (const clause of postJoin) {
264
+ nodes.push(scanNode(clause, rows, ["post-join: addresses a join alias, so no index can serve it"]));
265
+ }
266
+ }
267
+ const placement = plan.joins.length === 0 ? void 0 : runsPostJoin ? "post-join" : "pre-join";
268
+ if (plan.orderBy.length > 0) {
269
+ const orderNotes = placement ? [placement] : [];
270
+ if (ordered) orderNotes.push(`ordered index page off the ${ordered.detail}: no sort runs`);
271
+ nodes.push({
272
+ op: "orderBy",
273
+ dispatch: ordered ? "index:ordered" : "sort",
274
+ detail: plan.orderBy.map((o) => `${o.field} ${o.direction}${o.by === "label" ? " by label" : ""}`).join(", "),
275
+ estimatedRows: rows,
276
+ notes: orderNotes,
277
+ children: []
278
+ });
279
+ }
280
+ if (innerSplit) emitJoins();
281
+ if (plan.offset > 0 || plan.limit !== void 0) {
282
+ const afterOffset = rows === void 0 ? void 0 : Math.max(0, rows - plan.offset);
283
+ const paged = afterOffset === void 0 ? void 0 : plan.limit === void 0 ? afterOffset : Math.min(afterOffset, plan.limit);
284
+ nodes.push({
285
+ op: "page",
286
+ dispatch: "page",
287
+ detail: `offset=${plan.offset} limit=${plan.limit ?? "none"}`,
288
+ estimatedRows: paged,
289
+ notes: [
290
+ ...innerSplit ? ["post-join"] : placement ? [placement] : [],
291
+ ...ordered ? ["consumed by the ordered index walk; no rows are materialized past the page"] : []
292
+ ],
293
+ children: []
294
+ });
295
+ rows = paged;
296
+ }
297
+ if (!runsPostJoin && !innerSplit) emitJoins();
298
+ return { nodes, caps, reducerRewrite, text: renderExplainText(nodes) };
299
+ }
300
+ function scanReason(clause, indexes, indexAlreadyUsed) {
301
+ if (indexAlreadyUsed) {
302
+ const residual = "residual: an earlier clause is already index-served";
303
+ return clause.type === "field" && indexes !== null && !indexes.has(clause.field) ? [residual, `no index on "${clause.field}"`] : [residual];
304
+ }
305
+ if (clause.type !== "field") return [`${clause.type} clauses are never index-served`];
306
+ if (!indexes) return ["linear scan: no index store on this source"];
307
+ const sorted = indexes.hasSorted?.(clause.field) === true;
308
+ if (!indexes.has(clause.field) && !sorted) return [`linear scan: no index on "${clause.field}"`];
309
+ if (clause.op !== "==" && clause.op !== "in") {
310
+ if (!isRangeOperator(clause.op)) {
311
+ return [`linear scan: no index serves ${clause.op} on "${clause.field}"`];
312
+ }
313
+ if (!sorted) {
314
+ return [
315
+ `linear scan: the hash index on "${clause.field}" serves == and in only \u2014 declare a sorted index on it to serve ${clause.op}`
316
+ ];
317
+ }
318
+ if (clause.via !== void 0) {
319
+ return [`linear scan: "${clause.field}" is Via-covered, and a Via range operand is evaluated per record`];
320
+ }
321
+ return [`linear scan: the sorted index on "${clause.field}" could not order this operand`];
322
+ }
323
+ return [`linear scan: the index on "${clause.field}" could not serve this operand`];
324
+ }
325
+ function scanNode(clause, rows, notes) {
326
+ const { op, detail } = describeClause(clause);
327
+ return {
328
+ op,
329
+ dispatch: "scan",
330
+ detail,
331
+ estimatedRows: rows,
332
+ notes: [...notes, ...rows === void 0 ? [] : ["estimate is an upper bound"]],
333
+ children: clause.type === "group" ? clause.clauses.map((c) => scanNode(c, rows, ["inside a group: evaluated per record"])) : []
334
+ };
335
+ }
336
+ function joinNode(leg, joinContext, leftRows, caps) {
337
+ const right = leg.isDictJoin === true ? joinContext?.resolveDictSource?.(leg.field) : joinContext?.resolveSource(leg.target);
338
+ const rightRows = right?.snapshot().length;
339
+ const strategy = leg.strategy ?? (right?.lookupById ? "nested" : "hash");
340
+ const limit = leg.maxRows ?? DEFAULT_JOIN_MAX_ROWS;
341
+ const direction = leg.direction ?? "left";
342
+ const notes = [
343
+ rightRows === void 0 ? "right side unresolved" : `right side ${rightRows} rows`,
344
+ `cap ${limit}`,
345
+ `ref mode ${leg.mode}`
346
+ ];
347
+ if (direction !== "left") {
348
+ notes.push("reverse index over the left rows; right snapshot drives");
349
+ }
350
+ if (leg.inner === true) {
351
+ notes.push("inner: unmatched left rows are dropped, so the estimate is an upper bound");
352
+ }
353
+ if (leg.strategy !== void 0) notes.push("strategy overridden by the caller");
354
+ if (leftRows !== void 0) {
355
+ caps.push({ name: `join:${leg.as}:left`, limit, observed: leftRows, status: capStatus(leftRows, limit) });
356
+ }
357
+ if (rightRows !== void 0) {
358
+ caps.push({ name: `join:${leg.as}:right`, limit, observed: rightRows, status: capStatus(rightRows, limit) });
359
+ }
360
+ if (leg.on !== void 0) {
361
+ notes.splice(notes.findIndex((n) => n.startsWith("ref mode")), 1);
362
+ notes.push(
363
+ leg.on.kind === "composite" ? "declared composite `on`: one hash pass over the right snapshot, keyed on the field tuple" : "declared range `on`: the right snapshot is sorted once, then binary-searched per left row"
364
+ );
365
+ notes.push("many-to-many: one row per match, so the estimate is a lower bound and the output ceiling applies");
366
+ return {
367
+ op: "join",
368
+ dispatch: joinOnDispatch(leg.on),
369
+ detail: `${leg.as} <- ${describeJoinOn(leg.on)} (${leg.target})`,
370
+ estimatedRows: leftRows,
371
+ notes,
372
+ children: []
373
+ };
374
+ }
375
+ const label = direction === "left" ? "" : direction === "right" ? " right outer" : " full outer";
376
+ const estimatedRows = direction === "left" ? leftRows : leftRows === void 0 || rightRows === void 0 ? void 0 : leftRows + rightRows;
377
+ return {
378
+ op: "join",
379
+ dispatch: direction === "left" ? `join:${strategy}` : "join:reverse-index",
380
+ detail: `${leg.as} <- ${leg.field} (${leg.target})${label}`,
381
+ estimatedRows,
382
+ notes,
383
+ children: []
384
+ };
385
+ }
386
+ function collectReducerRewrites(via, fields) {
387
+ if (!via) return [];
388
+ const out = [];
389
+ for (const field of fields) {
390
+ for (const binding of via.bindings) {
391
+ if (binding.wrapReducers && binding.covers?.(field) === true) out.push({ brand: binding.brand, field });
392
+ }
393
+ }
394
+ return out;
395
+ }
396
+ function renderExplainText(nodes) {
397
+ const lines = [];
398
+ const walk = (ns, depth) => {
399
+ for (const n of ns) {
400
+ const rows = n.estimatedRows === void 0 ? "" : ` rows=${n.estimatedRows}`;
401
+ const notes = n.notes.length > 0 ? ` -- ${n.notes.join("; ")}` : "";
402
+ lines.push(`${" ".repeat(depth)}${n.op} ${n.detail} [${n.dispatch}]${rows}${notes}`);
403
+ walk(n.children, depth + 1);
404
+ }
405
+ };
406
+ walk(nodes, 0);
407
+ return lines.join("\n");
408
+ }
409
+
410
+ // src/kernel/query/relate/traverse.ts
411
+ function entriesOf(source) {
412
+ const paired = source.snapshotEntries?.();
413
+ if (paired !== void 0) return paired;
414
+ const out = [];
415
+ for (const record of source.snapshot()) {
416
+ const id = coerceRefKey(readPath(record, "id"));
417
+ if (id !== null) out.push({ id, record });
418
+ }
419
+ return out;
420
+ }
421
+ function runTraversal(source, field, seeds, opts) {
422
+ const { direction, maxDepth } = opts;
423
+ if (!Number.isInteger(maxDepth) || maxDepth < 0) {
424
+ throw new Error(
425
+ `.traverse("${field}"): maxDepth must be a non-negative integer, got ${String(maxDepth)}. It is required and has no default \u2014 an unbounded walk over a large collection is a denial of service against your own UI.`
426
+ );
427
+ }
428
+ const onCycle = opts.onCycle ?? "stop";
429
+ const entries = entriesOf(source);
430
+ const lookup = source.lookupById !== void 0 ? (id) => source.lookupById?.(id) : (() => {
431
+ const byId = new Map(entries.map((e) => [e.id, e.record]));
432
+ return (id) => byId.get(id);
433
+ })();
434
+ const children = direction === "down" ? bucketByRefKey(entries, (e) => readPath(e.record, field)) : void 0;
435
+ const emitted = /* @__PURE__ */ new Set();
436
+ const out = [];
437
+ let frontier = [];
438
+ for (const seedId of seeds) {
439
+ if (emitted.has(seedId)) continue;
440
+ const record = lookup(seedId);
441
+ if (record === void 0) continue;
442
+ emitted.add(seedId);
443
+ const node = { id: seedId, record, depth: 0, path: [seedId] };
444
+ out.push(node);
445
+ frontier.push(node);
446
+ }
447
+ for (let depth = 1; depth <= maxDepth && frontier.length > 0; depth++) {
448
+ const next = [];
449
+ for (const current of frontier) {
450
+ for (const { id, record } of neighboursOf(current, field, direction, lookup, children)) {
451
+ if (current.path.includes(id)) {
452
+ if (onCycle === "throw") {
453
+ throw new TraversalCycleError({ field, cycle: [...current.path, id] });
454
+ }
455
+ continue;
456
+ }
457
+ if (emitted.has(id)) continue;
458
+ emitted.add(id);
459
+ const node = { id, record, depth, path: [...current.path, id] };
460
+ out.push(node);
461
+ next.push(node);
462
+ }
463
+ }
464
+ frontier = next;
465
+ }
466
+ return out;
467
+ }
468
+ function neighboursOf(current, field, direction, lookup, children) {
469
+ if (direction === "down") return children?.get(current.id) ?? [];
470
+ const parentId = coerceRefKey(readPath(current.record, field));
471
+ if (parentId === null) return [];
472
+ const parent = lookup(parentId);
473
+ if (parent === void 0) return [];
474
+ return [{ id: parentId, record: parent }];
475
+ }
476
+
477
+ // src/kernel/query/relate/methods.ts
478
+ var RelateMethods = class {
479
+ // The implementation signature spans both overloads: the alias is
480
+ // non-nullable only under `mode: 'inner'`, and TS needs a return type both
481
+ // published shapes are assignable to.
482
+ join(field, opts) {
483
+ return this.withJoinLeg(field, opts, "left");
484
+ }
485
+ joinOn(target, opts) {
486
+ if (!this.joinContext) {
487
+ throw new Error(
488
+ `Query.joinOn() 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).`
489
+ );
490
+ }
491
+ const on = normalizeJoinOn(opts.on, target);
492
+ const leg = {
493
+ // The driving left field. Not a ref — it exists so error messages and
494
+ // `explain()` have something to name, and it is derivable from `on`.
495
+ field: on.kind === "composite" ? on.pairs[0][0] : on.left,
496
+ as: opts.as,
497
+ target,
498
+ // There is no ref(), so there is no dangling-ref policy to apply.
499
+ // 'cascade' is the mode that attaches null silently, which is exactly
500
+ // the left-outer behaviour a declared join wants.
501
+ mode: "cascade",
502
+ strategy: void 0,
503
+ maxRows: opts.maxRows,
504
+ ...opts.mode === "inner" ? { inner: true } : {},
505
+ on,
506
+ partitionScope: "all"
507
+ };
508
+ return new Query(
509
+ this.source,
510
+ { ...this.plan, joins: [...this.plan.joins, leg] },
511
+ this.joinContext,
512
+ this.reduceStrategy,
513
+ this.predicates
514
+ );
515
+ }
516
+ /**
517
+ * RIGHT outer join (#1289): every record of the TARGET collection appears,
518
+ * including one no left row points at. The mirror of `.join()`, which is
519
+ * and always was the left outer join.
520
+ *
521
+ * ```ts
522
+ * invoices.query().rightJoin<'client', Client>('clientId', { as: 'client' })
523
+ * // → one row per invoice/client match, PLUS { client } for every client
524
+ * // no invoice references. An invoice whose clientId matches nothing is
525
+ * // dropped — that is what makes it a right join.
526
+ * ```
527
+ *
528
+ * **The row shape is not `T`.** A right-only row carries the alias and
529
+ * nothing else, so the left fields are typed `Partial<T>` — SQL's "the left
530
+ * columns are NULL" in an object language. Read them defensively; a row
531
+ * where `amount` is `undefined` is a real, correct result, not a bug.
532
+ *
533
+ * **Cost.** A forward leg follows the left row's FK and is O(1) per row. A
534
+ * right leg cannot: the rows it must produce are exactly the ones no FK
535
+ * names. It builds a reverse index — the left rows bucketed by FK value —
536
+ * and walks the right snapshot against it. That is one extra pass over the
537
+ * left set and one `Map` the size of the distinct FK values; both sides are
538
+ * fully materialized either way, and both row ceilings still apply.
539
+ *
540
+ * **Ordering.** Like `.join()`, legs run AFTER `orderBy`/`limit`/`offset`
541
+ * unless the ordering addresses the alias (#1337),
542
+ * so those narrow the LEFT side. Rows are emitted in right-snapshot order.
543
+ *
544
+ * A left row whose non-null FK resolves to nothing is dropped, but the
545
+ * ref-mode check still runs on it: `strict` still throws
546
+ * `DanglingReferenceError`. Corruption should not become invisible because
547
+ * the caller changed join direction.
548
+ */
549
+ rightJoin(field, opts) {
550
+ return this.withJoinLeg(field, opts, "right");
551
+ }
552
+ /**
553
+ * FULL outer join (#1289): the union of `.join()` and `.rightJoin()` —
554
+ * every left row, every right record, matched where they meet.
555
+ *
556
+ * ```ts
557
+ * invoices.query().fullOuterJoin<'client', Client>('clientId', { as: 'client' })
558
+ * // → matched rows, plus { client: null, ...invoice } for an unreferenced
559
+ * // invoice, plus { client } for a client no invoice points at.
560
+ * ```
561
+ *
562
+ * The alias is `R | null` and the left fields are `Partial<T>`, because a
563
+ * row can be missing either side — never both. Same reverse index, same
564
+ * ordering and same ref-mode semantics as {@link rightJoin}; the only
565
+ * difference is that the unmatched LEFT rows are emitted (after the
566
+ * right-driven ones) instead of dropped.
567
+ */
568
+ fullOuterJoin(field, opts) {
569
+ return this.withJoinLeg(field, opts, "full");
570
+ }
571
+ /**
572
+ * The one place a `JoinLeg` is built. `.join()`, `.rightJoin()` and
573
+ * `.fullOuterJoin()` differ ONLY in `direction` and in the type they
574
+ * publish — keeping the plan-time validation (ref declared? dict join?
575
+ * join context?) in a single body is what stops the three from drifting on
576
+ * which errors they raise.
577
+ */
578
+ withJoinLeg(field, opts, direction) {
579
+ if (!this.joinContext) {
580
+ throw new Error(
581
+ `Query.join() requires a join context (same for .rightJoin() and .fullOuterJoin()). 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).`
582
+ );
583
+ }
584
+ const descriptor = this.joinContext.resolveRef(field);
585
+ const isDictJoinField = !descriptor && this.joinContext.resolveDictSource?.(field) != null;
586
+ if (!descriptor && !isDictJoinField) {
587
+ throw new RefNotDeclaredError({
588
+ collection: this.joinContext.leftCollection,
589
+ field,
590
+ 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.`
591
+ });
592
+ }
593
+ const directionField = direction === "left" ? {} : { direction };
594
+ const innerField = opts.mode === "inner" ? { inner: true } : {};
595
+ const leg = descriptor ? {
596
+ field,
597
+ as: opts.as,
598
+ target: descriptor.target,
599
+ mode: descriptor.mode,
600
+ strategy: opts.strategy,
601
+ maxRows: opts.maxRows,
602
+ ...directionField,
603
+ ...innerField,
604
+ // The partition seam — always 'all'. Do not remove, and do not
605
+ // populate without reading JoinLeg.partitionScope's two
606
+ // constraints (#1342): this value is inside every stored MV
607
+ // queryHash. Pinned by __tests__/query-partition-scope.test.ts.
608
+ partitionScope: "all"
609
+ } : {
610
+ // Dict join leg
611
+ field,
612
+ as: opts.as,
613
+ target: field,
614
+ // dict name = field name for dictKey
615
+ mode: "strict",
616
+ strategy: opts.strategy,
617
+ maxRows: opts.maxRows,
618
+ partitionScope: "all",
619
+ ...directionField,
620
+ ...innerField,
621
+ isDictJoin: true
622
+ };
623
+ return new Query(
624
+ this.source,
625
+ { ...this.plan, joins: [...this.plan.joins, leg] },
626
+ this.joinContext,
627
+ this.reduceStrategy,
628
+ this.predicates
629
+ );
630
+ }
631
+ /**
632
+ * Cartesian-product cross-join against `target` collection. Each result row
633
+ * carries the original `T` fields plus `result[as]` populated from every
634
+ * right-side row (or the filtered subset when `on:` is supplied).
635
+ *
636
+ * **⚠️ INNER-join semantics — an empty right subset DROPS the left row.**
637
+ * Each left row is emitted once per matching right row, so when `on:`
638
+ * yields nothing the row vanishes with no error, no warning and no count
639
+ * mismatch. This bites hardest on a reverse FK, where `.join()` (which is
640
+ * forward-only, and already a genuine LEFT outer join) does not apply and
641
+ * `.crossJoin()` is the only tool. To keep the row, return a one-element
642
+ * array holding `null`:
643
+ *
644
+ * ```ts
645
+ * .crossJoin('clients', { as: 'client', on: (b) => byEntity.get(b.entityId) ?? [null] })
646
+ * // ^^^^^^^^
647
+ * // the ONLY thing preserving the row
648
+ * ```
649
+ *
650
+ * **Prefer `outer: true`**, which does exactly this and types the alias as
651
+ * `TTarget | null`:
652
+ *
653
+ * ```ts
654
+ * .crossJoin('clients', { as: 'client', outer: true, on: (b) => byEntity.get(b.entityId) ?? [] })
655
+ * ```
656
+ *
657
+ * The `?? [null]` form remains valid and is what `outer` does internally, but
658
+ * it is invisible intent: it types the alias as non-null while the row can
659
+ * hold null, and a later "simplification" that drops it silently
660
+ * reintroduces the row loss.
661
+ *
662
+ * **Order matters:** `.where().crossJoin()` filters BEFORE expanding (cheaper);
663
+ * `.crossJoin().where('alias.field', ...)` filters AFTER (required when the
664
+ * where clause references the aliased fields).
665
+ *
666
+ * **Cost ceiling:** `CrossJoinTooLargeError` fires before allocation when
667
+ * `leftRows × rightRows` (or the cumulative lateral count) exceeds the limit.
668
+ * Default: 50,000 rows. Override per-clause with `{ maxRows: N }`.
669
+ *
670
+ * **`on:` shapes:**
671
+ * - `on: (left) => TTarget[]` — subset form (most efficient)
672
+ * - `on: (left) => (right) => boolean` — predicate form
673
+ * - `on: { predicate: 'name' }` — MV-safe, hash-tracked form
674
+ * (requires the Query to have been augmented via `_withPredicates`)
675
+ *
676
+ * Requires a JoinContext (constructed via `collection.query()`).
677
+ */
678
+ crossJoin(target, opts) {
679
+ if (!this.joinContext) {
680
+ throw new Error(
681
+ `Query.crossJoin("${target}"): requires a join context. Use collection.query() to construct a cross-join-capable Query instead of the Query constructor directly.`
682
+ );
683
+ }
684
+ let onFn;
685
+ let onPredicateName;
686
+ if (opts.on !== void 0) {
687
+ if (typeof opts.on === "function") {
688
+ onFn = opts.on;
689
+ if (this.predicates) {
690
+ console.warn(
691
+ `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.`
692
+ );
693
+ }
694
+ } else {
695
+ const predName = opts.on.predicate;
696
+ if (!this.predicates) {
697
+ throw new Error(
698
+ `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 } }.`
699
+ );
700
+ }
701
+ const decl = this.predicates.get(predName);
702
+ if (!decl) {
703
+ throw new Error(
704
+ `Query.crossJoin("${target}"): predicate "${predName}" not registered. Available: ${[...this.predicates.keys()].join(", ") || "(none)"}.`
705
+ );
706
+ }
707
+ const as = opts.as;
708
+ const predicateFn = decl.fn;
709
+ onFn = (_left) => (right) => predicateFn({ ..._left, [as]: right });
710
+ onPredicateName = predName;
711
+ }
712
+ }
713
+ const clause = {
714
+ type: "crossJoin",
715
+ target,
716
+ as: opts.as,
717
+ ...onFn !== void 0 && { on: onFn },
718
+ ...onPredicateName !== void 0 && { onPredicateName },
719
+ ...opts.maxRows !== void 0 && { maxRows: opts.maxRows },
720
+ ...opts.outer === true && { outer: true }
721
+ };
722
+ return new Query(
723
+ this.source,
724
+ { ...this.plan, clauses: [...this.plan.clauses, clause] },
725
+ this.joinContext,
726
+ this.reduceStrategy,
727
+ this.predicates
728
+ );
729
+ }
730
+ /**
731
+ * Self cross-join with BOTH sides aliased (#1289).
732
+ *
733
+ * ```ts
734
+ * const pairs = trades.query()
735
+ * .crossJoinWith({ leftAs: 'a', rightAs: 'b', on: (t) => laterThan(t) })
736
+ * .toArray()
737
+ * // → [{ a: Trade, b: Trade }, ...] — no field at the top level
738
+ * ```
739
+ *
740
+ * `.crossJoin('trades', { as: 'other' })` can already pair a collection
741
+ * with itself, but only ASYMMETRICALLY: the left row's fields stay at the
742
+ * top level and only the right side gets a name. Every comparison then
743
+ * reads `r.amount` against `r.other.amount`, which is exactly the shape
744
+ * that makes an accidentally-transposed pair invisible.
745
+ *
746
+ * ⚠️ **The cost is not the join, it is the Via dressing.** Aliasing the
747
+ * left row moves every field off the top level, and the money / i18n /
748
+ * lookup pipeline keys by BARE FIELD NAME — so the plain top-level decode
749
+ * `toArray()` applies cannot see either side. Both aliases are therefore
750
+ * dressed explicitly, through the source's own Via result decode, before
751
+ * the rows are returned. Silently serving raw money under an alias is the
752
+ * failure this method exists to not have; `dressAliases` is where it is
753
+ * prevented and `__tests__/query-outer-join.test.ts` is what proves it.
754
+ *
755
+ * `on:` takes the same subset / predicate shapes as `.crossJoin()`, and the
756
+ * same `maxRows` ceiling applies to the product. The target is always this
757
+ * query's own collection — a cross-join against a DIFFERENT collection is
758
+ * `.crossJoin()`, which needs no left alias to stay unambiguous.
759
+ *
760
+ * The returned `Query` drops this query's schema / queryable / money field
761
+ * parameters. That is not laziness: those parameters name TOP-LEVEL fields,
762
+ * and after `crossJoinWith` there are no top-level fields — only the two
763
+ * aliases. Carrying them would let `where('amount', ...)` type-check on a
764
+ * row where `amount` does not exist.
765
+ */
766
+ crossJoinWith(opts) {
767
+ if (!this.joinContext) {
768
+ throw new Error(
769
+ `Query.crossJoinWith(): requires a join context. Use collection.query() to construct a cross-join-capable Query instead of the Query constructor directly.`
770
+ );
771
+ }
772
+ if (opts.leftAs === opts.rightAs) {
773
+ throw new Error(
774
+ `Query.crossJoinWith({ leftAs: "${opts.leftAs}", rightAs: "${opts.rightAs}" }): the two aliases must differ \u2014 a self cross-join whose sides share a name would emit the right row under both and silently lose the left one.`
775
+ );
776
+ }
777
+ const built = this.crossJoin(this.joinContext.leftCollection, {
778
+ as: opts.rightAs,
779
+ ...opts.on !== void 0 && { on: opts.on },
780
+ ...opts.maxRows !== void 0 && { maxRows: opts.maxRows }
781
+ });
782
+ const plan = built._plan();
783
+ const last = plan.clauses[plan.clauses.length - 1];
784
+ const clauses = [...plan.clauses.slice(0, -1), { ...last, leftAs: opts.leftAs }];
785
+ return new Query(
786
+ this.source,
787
+ { ...plan, clauses },
788
+ this.joinContext,
789
+ this.reduceStrategy,
790
+ this.predicates
791
+ );
792
+ }
793
+ /**
794
+ * Describe how this plan WOULD run (#1348): the dispatch per clause
795
+ * (`index:hash` vs `scan`, and why), row estimates taken from real index
796
+ * cardinalities, join strategy and side sizes against the row ceiling,
797
+ * whether ordering/pagination lands pre- or post-join, and which
798
+ * cardinality caps are close to tripping. `.text` renders one line per
799
+ * node.
800
+ *
801
+ * ⛔ Purely observational — it probes index buckets and reads snapshot
802
+ * sizes, never executes the plan. A terminal returns the same thing
803
+ * whether or not `explain()` was called. See `query/explain.ts`.
804
+ */
805
+ explain() {
806
+ return explainPlan(this.source, this.plan, this.joinContext);
807
+ }
808
+ /**
809
+ * Recursive traversal over ONE declared, self-referencing `ref()` field
810
+ * (#1352) — the org-chart / bill-of-materials / parent-client shape that
811
+ * otherwise forces the consumer to hand-roll recursion.
812
+ *
813
+ * ```ts
814
+ * people.query().where('name', '==', 'Dana')
815
+ * .traverse('parentId', { direction: 'up', maxDepth: 10 })
816
+ * // → [{ id: 'dana', record, depth: 0, path: ['dana'] },
817
+ * // { id: 'bea', record, depth: 1, path: ['dana', 'bea'] }, …]
818
+ * ```
819
+ *
820
+ * **A TERMINAL.** It returns rows, not a `Query`, so it composes with
821
+ * `where()` / `orderBy()` / `limit()` on the way IN, not on the way out.
822
+ *
823
+ * **Seeds are this query's matched records** — the clauses choose the roots
824
+ * of the walk, not which nodes the walk may pass through. A traversal from
825
+ * one seed is `ancestorsOf` / `descendantsOf` below.
826
+ *
827
+ * **`maxDepth` is required**, with no default: an unbounded walk over a
828
+ * large collection is a denial of service against your own UI, and a
829
+ * silent default would truncate a result without saying so.
830
+ *
831
+ * **Cycles terminate.** A parent chain can be circular through user error,
832
+ * and an unguarded BFS hangs the tab. The default `{ onCycle: 'stop' }`
833
+ * prunes a node the walk is already standing on; `'throw'` raises
834
+ * `TraversalCycleError` for hierarchies that are supposed to be acyclic.
835
+ *
836
+ * **A node is emitted once**, at its shallowest depth — so a diamond (two
837
+ * seeds converging on one ancestor) yields ONE row for that ancestor,
838
+ * carrying the path of whichever branch reached it first.
839
+ *
840
+ * **Declared refs only.** This is not a general graph engine: the field
841
+ * must carry a `ref()` whose target is this same collection.
842
+ *
843
+ * **Cost.** Every hop reads the vault's already-decrypted in-memory cache
844
+ * (`query()` is eager-mode only), so a depth-5 traversal costs
845
+ * `depth × frontier` Map lookups and ZERO additional decrypts — the
846
+ * AES-GCM work was paid once at `openVault()`. `direction: 'down'` adds one
847
+ * O(n) pass to build the reverse-FK index; `'up'` adds nothing.
848
+ *
849
+ * ⛔ **Not an `explain()` node.** `explain()` describes the plan, and a
850
+ * traversal is a terminal over the plan's result rather than a clause in
851
+ * it — the same reason `.window()` and #1336's post-group ops are absent.
852
+ * `explain()` on the seed query still describes how the SEEDS are found.
853
+ */
854
+ traverse(field, opts) {
855
+ this.assertSelfRef(field, "traverse");
856
+ const _h = this.source.hydration;
857
+ if (_h !== void 0 && !_h.isHydrated()) return gateTerminal(_h, "traverse", () => this.traverse(field, opts));
858
+ return this.runTraverse(field, this.ids(), opts);
859
+ }
860
+ /**
861
+ * `.traverse()` sugar: every ancestor of one record, that record included
862
+ * at `depth: 0`. See {@link traverse} for the full contract.
863
+ *
864
+ * Refused on a query that already carries clauses — the seed is named
865
+ * explicitly here, so a `where()` would silently do nothing. Use
866
+ * `.traverse()` when the seeds come from a query.
867
+ */
868
+ ancestorsOf(id, field, opts) {
869
+ return this.traverseFromId(id, field, "up", opts);
870
+ }
871
+ /**
872
+ * `.traverse()` sugar: every descendant of one record, that record included
873
+ * at `depth: 0`. See {@link traverse} for the full contract.
874
+ */
875
+ descendantsOf(id, field, opts) {
876
+ return this.traverseFromId(id, field, "down", opts);
877
+ }
878
+ traverseFromId(id, field, direction, opts) {
879
+ const _h = this.source.hydration;
880
+ if (_h !== void 0 && !_h.isHydrated()) return gateTerminal(_h, direction === "up" ? "ancestorsOf" : "descendantsOf", () => this.traverseFromId(id, field, direction, opts));
881
+ const sugar = direction === "up" ? "ancestorsOf" : "descendantsOf";
882
+ const plan = this.plan;
883
+ if (plan.clauses.length > 0 || plan.orderBy.length > 0 || plan.joins.length > 0 || plan.limit !== void 0 || plan.offset !== 0) {
884
+ throw new Error(
885
+ `Query.${sugar}("${id}"): this query already carries clauses, but ${sugar}() seeds from the id you passed \u2014 the clauses would silently do nothing. Use .traverse("${field}", { direction: '${direction}', \u2026 }), whose seeds ARE the query's matched records, or call ${sugar}() on a bare collection.query().`
886
+ );
887
+ }
888
+ this.assertSelfRef(field, sugar);
889
+ return this.runTraverse(field, [id], { ...opts, direction });
890
+ }
891
+ /**
892
+ * The one place a traversal runs. Both entry points share it so they cannot
893
+ * drift on Via decoding or on which source view the walk reads.
894
+ */
895
+ runTraverse(field, seeds, opts) {
896
+ const rows = runTraversal(this.source, field, seeds, opts);
897
+ return rows.map((row) => ({ ...row, record: this.decodeVia([row.record])[0] }));
898
+ }
899
+ /**
900
+ * Plan-time validation shared by `.traverse()` and its sugar: the field must
901
+ * carry a `ref()`, and that ref must point back at this same collection.
902
+ *
903
+ * The second half is what keeps this from becoming a general graph engine.
904
+ * A ref to ANOTHER collection has no second hop — the target's records do
905
+ * not carry this field — so a two-collection "traversal" is a `.join()`
906
+ * wearing the wrong name, and would walk exactly one level before stopping
907
+ * for reasons the caller could not see.
908
+ */
909
+ assertSelfRef(field, caller) {
910
+ if (!this.joinContext) {
911
+ throw new Error(
912
+ `Query.${caller}(): requires a collection-backed query. Use collection.query() instead of the Query constructor directly (the direct constructor is only used for tests with plain-object sources).`
913
+ );
914
+ }
915
+ const descriptor = this.joinContext.resolveRef(field);
916
+ if (!descriptor) {
917
+ throw new RefNotDeclaredError({
918
+ collection: this.joinContext.leftCollection,
919
+ field,
920
+ message: `Query.${caller}(): no ref() declared for field "${field}" on collection "${this.joinContext.leftCollection}". Traversal walks DECLARED refs only \u2014 add refs: { ${field}: ref('${this.joinContext.leftCollection}') } to the collection options, then retry.`
921
+ });
922
+ }
923
+ if (descriptor.target !== this.joinContext.leftCollection) {
924
+ throw new Error(
925
+ `Query.${caller}(): field "${field}" refs "${descriptor.target}", but traversal requires a self-referencing ref \u2014 one whose target is the collection being queried ("${this.joinContext.leftCollection}"). A ref across collections has no second hop; use .join("${field}", { as: \u2026 }) for that.`
926
+ );
927
+ }
928
+ }
929
+ };
930
+ function applyCrossJoin(leftRel, clause, rightSource) {
931
+ const rightRows = rightSource.snapshot();
932
+ const maxRows = clause.maxRows ?? DEFAULT_CROSS_JOIN_MAX_ROWS;
933
+ const { as } = clause;
934
+ const outer = clause.outer === true;
935
+ const { leftAs } = clause;
936
+ const emit = leftAs === void 0 ? (left, right) => ({ ...left, [as]: right }) : (left, right) => ({ [leftAs]: left, [as]: right });
937
+ if (!clause.on) {
938
+ const rightSide = outer && rightRows.length === 0 ? [null] : rightRows;
939
+ const product = leftRel.length * rightSide.length;
940
+ if (product > maxRows) {
941
+ throw new CrossJoinTooLargeError({ target: clause.target, expected: product, limit: maxRows });
942
+ }
943
+ const expanded2 = [];
944
+ for (const left of leftRel) {
945
+ const leftObj = left;
946
+ for (const right of rightSide) {
947
+ expanded2.push(emit(leftObj, right));
948
+ }
949
+ }
950
+ return expanded2;
951
+ }
952
+ const expanded = [];
953
+ let cumulative = 0;
954
+ for (const left of leftRel) {
955
+ const callbackResult = clause.on(left);
956
+ let filteredRight;
957
+ if (Array.isArray(callbackResult)) {
958
+ filteredRight = callbackResult;
959
+ } else {
960
+ filteredRight = rightRows.filter(
961
+ callbackResult
962
+ );
963
+ }
964
+ if (outer && filteredRight.length === 0) filteredRight = [null];
965
+ cumulative += filteredRight.length;
966
+ if (cumulative > maxRows) {
967
+ throw new CrossJoinTooLargeError({
968
+ target: clause.target,
969
+ expected: cumulative,
970
+ limit: maxRows
971
+ });
972
+ }
973
+ const leftObj = left;
974
+ for (const right of filteredRight) {
975
+ expanded.push(emit(leftObj, right));
976
+ }
977
+ }
978
+ return expanded;
979
+ }
980
+
981
+ // src/kernel/query/relate/scan-methods.ts
982
+ var ScanRelateMethods = class {
983
+ /**
984
+ * Resolve a `ref()`-declared foreign key per record as the scan
985
+ * stream flows, attaching the right-side record (or null) under
986
+ * `opts.as`. — streaming joins over `scan()`.
987
+ *
988
+ * ```ts
989
+ * for await (const inv of invoices.scan().join('clientId', { as: 'client' })) {
990
+ * await processInvoice(inv) // inv.client is attached
991
+ * }
992
+ *
993
+ * // Or terminate with .aggregate() for streaming joined aggregation
994
+ * const { total } = await invoices.scan()
995
+ * .where('status', '==', 'open')
996
+ * .join('clientId', { as: 'client' })
997
+ * .aggregate({ total: sum('amount') })
998
+ * ```
999
+ *
1000
+ * **The key difference from eager `.join()`:** the LEFT
1001
+ * side streams page-by-page from the adapter and is never
1002
+ * materialized. Memory ceiling on the left is O(pageSize), not
1003
+ * O(rowCount). This is what makes streaming joins suitable for
1004
+ * collections that exceed the eager join's 50_000-row ceiling.
1005
+ *
1006
+ * **Right-side strategy** is auto-selected per leg:
1007
+ * - **Indexed** — right source exposes `lookupById`, so each
1008
+ * left row costs O(1). This is the common path for
1009
+ * Collection right sides, which back `lookupById` with a Map
1010
+ * lookup over the in-memory cache. The right collection must
1011
+ * be in eager mode (the same constraint as eager join's
1012
+ * `querySourceForJoin` from ).
1013
+ * - **Hash** — right source has only `snapshot()`. Build a
1014
+ * `Map<id, record>` once at iteration start, probe per left
1015
+ * row. Same correctness, same per-row cost as the indexed
1016
+ * path; the difference is the upfront cost of materializing
1017
+ * the right side once.
1018
+ *
1019
+ * Both strategies hold the right side in memory for the duration
1020
+ * of the iteration. The "streaming" property applies to the LEFT
1021
+ * side only — true left-and-right streaming joins (where neither
1022
+ * side fits in memory) require a sort-merge join planner that's
1023
+ * out of scope for.
1024
+ *
1025
+ * **Ref-mode semantics** match eager `.join()` exactly:
1026
+ * - `strict` → throws `DanglingReferenceError` mid-stream
1027
+ * when a left record points at a non-existent right id.
1028
+ * The throw aborts the async iterator — consumers should
1029
+ * wrap the `for await` in try/catch if they want to recover.
1030
+ * - `warn` → attaches `null` and emits a one-shot warning
1031
+ * per unique dangling pair (deduped via the same warn
1032
+ * channel as eager join).
1033
+ * - `cascade` → attaches `null` silently. A delete-time mode;
1034
+ * dangling refs at read time are mid-flight or pre-existing
1035
+ * orphans, not a DSL error.
1036
+ *
1037
+ * Left records with null/undefined FK values attach `null`
1038
+ * regardless of mode — same "no reference at all" policy as
1039
+ * eager join and write-time `enforceRefsOnPut`.
1040
+ *
1041
+ * **Multi-FK chaining** is supported via repeated `.join()`
1042
+ * calls: each leg resolves an independent ref. Each leg
1043
+ * independently picks its right-side strategy and applies its
1044
+ * own ref mode.
1045
+ *
1046
+ * **Joins are NOT applied** to a `.aggregate()` terminal that
1047
+ * doesn't reference joined fields — wait, that's not quite
1048
+ * right. The streaming path actually DOES apply joins before
1049
+ * `.aggregate()` because the join attaches a field that the
1050
+ * spec might reference. Unlike `Query.aggregate()` (which skips
1051
+ * joins entirely as a projection-only short-circuit), the
1052
+ * streaming aggregation can't know whether the spec touches a
1053
+ * joined field, so it always applies joins. Consumers who want
1054
+ * unjoined streaming aggregation should leave `.join()` off the
1055
+ * chain — the chain is composable for a reason.
1056
+ *
1057
+ * Every JoinLeg carries `partitionScope: 'all'`, plumbed through but never
1058
+ * read. Same seam as the eager join — see {@link JoinLeg.partitionScope}.
1059
+ */
1060
+ join(field, opts) {
1061
+ if (!this.joinContext) {
1062
+ throw new Error(
1063
+ `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).`
1064
+ );
1065
+ }
1066
+ const descriptor = this.joinContext.resolveRef(field);
1067
+ if (!descriptor) {
1068
+ throw new RefNotDeclaredError({
1069
+ collection: this.joinContext.leftCollection,
1070
+ field,
1071
+ 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.`
1072
+ });
1073
+ }
1074
+ const leg = {
1075
+ field,
1076
+ as: opts.as,
1077
+ target: descriptor.target,
1078
+ mode: descriptor.mode,
1079
+ strategy: void 0,
1080
+ maxRows: void 0,
1081
+ // Always 'all', never read by the streaming executor. This is the
1082
+ // path where partition pruning would actually pay (every listPage()
1083
+ // page is decrypted) — and the path blocked on a store-contract
1084
+ // change. See JoinLeg.partitionScope constraint 2 (#1342).
1085
+ partitionScope: "all"
1086
+ };
1087
+ return new ScanBuilder(
1088
+ this.pageProvider,
1089
+ this.pageSize,
1090
+ this.clauses,
1091
+ [...this.joins, leg],
1092
+ this.joinContext,
1093
+ this.via
1094
+ );
1095
+ }
1096
+ /**
1097
+ * Iterate the scan as an async iterable. Walks the page
1098
+ * provider's cursors forward until exhaustion, applying every
1099
+ * clause per record — only matching records are yielded.
1100
+ *
1101
+ * Backward-compatible with the previous async-generator `scan()`
1102
+ * return type for `for await … of` consumers.
1103
+ */
1104
+ /**
1105
+ * Per-leg right-side resolution state. Built once at iteration
1106
+ * start and reused for every left record. Two strategies:
1107
+ *
1108
+ * - `lookupById`: present when the right source exposes the
1109
+ * hook directly (typical Collection right side). Per-row
1110
+ * cost is O(1).
1111
+ * - `hashByPrimaryKey`: built from `snapshot()` when no
1112
+ * lookupById. Per-row cost is O(1) after the upfront O(N)
1113
+ * materialization. Same as eager join's hash strategy.
1114
+ *
1115
+ * `warnedKeys` is the per-leg dedup set for ref-mode 'warn'. We
1116
+ * key on `field→target:refId` so the same dangling pair only
1117
+ * warns once per iteration. The dedup is per-iteration, not
1118
+ * per-process — a long-running scan that re-iterates would warn
1119
+ * again, which is the desired behavior (the data may have
1120
+ * changed between iterations).
1121
+ */
1122
+ buildJoinResolvers() {
1123
+ if (!this.joinContext) {
1124
+ throw new Error(
1125
+ `ScanBuilder iterator: ${this.joins.length} join leg(s) present but no JoinContext attached. Use collection.scan() to construct a join-capable scan.`
1126
+ );
1127
+ }
1128
+ const resolvers = [];
1129
+ for (const leg of this.joins) {
1130
+ if (leg.on !== void 0) {
1131
+ throw new Error(
1132
+ `ScanBuilder: the declared \`on\` join leg "${leg.as}" cannot stream \u2014 it emits one row per match, while scan() yields one row per stored record. Use collection.query().joinOn().`
1133
+ );
1134
+ }
1135
+ const source = this.joinContext.resolveSource(leg.target);
1136
+ if (!source) {
1137
+ throw new Error(
1138
+ `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.`
1139
+ );
1140
+ }
1141
+ let lookupById = null;
1142
+ let hashByPrimaryKey = null;
1143
+ if (source.lookupById) {
1144
+ const fn = source.lookupById.bind(source);
1145
+ lookupById = (id) => fn(id);
1146
+ } else {
1147
+ const map = /* @__PURE__ */ new Map();
1148
+ for (const record of source.snapshot()) {
1149
+ const rawId = readPath(record, "id");
1150
+ const key = coerceRefKey(rawId);
1151
+ if (key !== null) map.set(key, record);
1152
+ }
1153
+ hashByPrimaryKey = map;
1154
+ }
1155
+ resolvers.push({
1156
+ leg,
1157
+ source,
1158
+ lookupById,
1159
+ hashByPrimaryKey,
1160
+ warnedKeys: /* @__PURE__ */ new Set()
1161
+ });
1162
+ }
1163
+ return resolvers;
1164
+ }
1165
+ /**
1166
+ * Resolve a single join leg for one left record and return the
1167
+ * left record with the joined field attached under
1168
+ * `leg.as`. Pure function over `(left, resolver)`; never
1169
+ * mutates the input.
1170
+ *
1171
+ * Ref-mode dispatch matches eager `applyJoins` from :
1172
+ * - null/undefined FK → attach null silently (always allowed)
1173
+ * - dangling FK + strict → throw `DanglingReferenceError`
1174
+ * - dangling FK + warn → attach null, warn-once per pair
1175
+ * - dangling FK + cascade → attach null silently
1176
+ */
1177
+ applyOneJoinStreaming(left, resolver) {
1178
+ if (left === null || typeof left !== "object") {
1179
+ return left;
1180
+ }
1181
+ const { leg } = resolver;
1182
+ const rawId = readPath(left, leg.field);
1183
+ const refKey = coerceRefKey(rawId);
1184
+ let right = void 0;
1185
+ if (refKey !== null) {
1186
+ if (resolver.lookupById !== null) {
1187
+ right = resolver.lookupById(refKey);
1188
+ } else if (resolver.hashByPrimaryKey !== null) {
1189
+ right = resolver.hashByPrimaryKey.get(refKey);
1190
+ }
1191
+ }
1192
+ const merged = {
1193
+ ...left
1194
+ };
1195
+ if (right === void 0) {
1196
+ if (refKey !== null && leg.mode === "strict") {
1197
+ throw new DanglingReferenceError({
1198
+ field: leg.field,
1199
+ target: leg.target,
1200
+ refId: refKey,
1201
+ 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.`
1202
+ });
1203
+ }
1204
+ if (refKey !== null && leg.mode === "warn") {
1205
+ const dedupKey = `${leg.field}\u2192${leg.target}:${refKey}`;
1206
+ if (!resolver.warnedKeys.has(dedupKey)) {
1207
+ resolver.warnedKeys.add(dedupKey);
1208
+ console.warn(
1209
+ `[noy-db] ScanBuilder.join() encountered dangling ref in 'warn' mode: field "${leg.field}" \u2192 "${leg.target}:${refKey}" not found. Attaching null.`
1210
+ );
1211
+ }
1212
+ }
1213
+ merged[leg.as] = null;
1214
+ } else {
1215
+ merged[leg.as] = right;
1216
+ }
1217
+ return merged;
1218
+ }
1219
+ /**
1220
+ * Reduce the scan stream through a named set of reducers and
1221
+ * return the final aggregated shape.
1222
+ *
1223
+ * Memory is O(reducers): one mutable state slot per spec key.
1224
+ * Records flow through the pipeline one at a time via
1225
+ * `for await` and are discarded after their `step()` is applied
1226
+ * — never collected into an array. This is the distinguishing
1227
+ * property from `Query.aggregate()`, which materializes the full
1228
+ * match set first.
1229
+ *
1230
+ * Reuses the same reducer protocol as `Query.aggregate()`,
1231
+ * so `count()`, `sum(field)`, `avg(field)`, `min(field)`,
1232
+ * `max(field)` all work unchanged. The `{ seed }` parameter
1233
+ * plumbing from constraint #2 is honored transparently — the
1234
+ * factories ignore it in and the scan executor never
1235
+ * touches the per-reducer state construction.
1236
+ *
1237
+ * **Returns a Promise**, unlike `Query.aggregate().run()` which
1238
+ * is synchronous. The scan is inherently async because it walks
1239
+ * adapter pages, so the terminal has to be too. Consumers
1240
+ * destructure with await:
1241
+ *
1242
+ * ```ts
1243
+ * const { total, n } = await invoices.scan()
1244
+ * .where('year', '==', 2025)
1245
+ * .aggregate({ total: sum('amount'), n: count() })
1246
+ * ```
1247
+ *
1248
+ * **No `.live()` in.** `scan().aggregate().live()` would
1249
+ * require reconciling an unbounded streaming iteration with a
1250
+ * change-stream subscription — a design problem, not just a code
1251
+ * one. Consumers with huge collections and live needs should
1252
+ * narrow with `.where()` enough to fit in the 50k `query()`
1253
+ * limit and use `query().aggregate().live()` instead.
1254
+ *
1255
+ * Consults the Via pipeline's posture before reducing (#629 Task 8 review
1256
+ * fix wave 1): a reducer over a field whose posture is `queryable: 'none'`
1257
+ * throws `FieldNotQueryableError` here, metadata-only — via
1258
+ * `ViaPipeline.refuseUnqueryableReducers`, NOT the full `wrapReducers`
1259
+ * (which would also activate money's exact-reducer rewrite, a path this
1260
+ * method has never run and must not start running as a side effect of
1261
+ * this gate).
1262
+ */
1263
+ // `const` so an inline `[specA, specB]` infers as a TUPLE, not a `Spec[]` —
1264
+ // that is what makes `const [a, b] = await …` land on the right shapes.
1265
+ };
1266
+
1267
+ // src/kernel/query/relate/install.ts
1268
+ var done = false;
1269
+ function installRelate() {
1270
+ if (done) return;
1271
+ done = true;
1272
+ installMethods(Query.prototype, RelateMethods);
1273
+ installMethods(ScanBuilder.prototype, ScanRelateMethods);
1274
+ installRelateHooks({
1275
+ applyJoins,
1276
+ splitAroundJoins,
1277
+ orderReferencesJoinAlias,
1278
+ joinsDropLeftRows,
1279
+ applyCrossJoin
1280
+ });
1281
+ }
1282
+
1283
+ export {
1284
+ explainPlan,
1285
+ renderExplainText,
1286
+ runTraversal,
1287
+ installRelate
1288
+ };
1289
+ //# sourceMappingURL=chunk-ZSX4S5XB.js.map