@noy-db/hub 0.6.0-pre.21 → 0.6.0-pre.23

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 (360) hide show
  1. package/CHANGELOG.md +238 -0
  2. package/dist/api-ETB5Y4DY.js +20 -0
  3. package/dist/attestation/index.js +16 -16
  4. package/dist/{backup-FSC36VWC.js → backup-UOLAXOJ4.js} +10 -10
  5. package/dist/blobs/index.js +20 -18
  6. package/dist/blobs/index.js.map +1 -1
  7. package/dist/broker/index.js +10 -10
  8. package/dist/cargo/index.js +28 -28
  9. package/dist/{chunk-3B6S6RSI.js → chunk-22VRCUV2.js} +2 -2
  10. package/dist/{chunk-ESKIAXO2.js → chunk-23ODLABM.js} +4 -4
  11. package/dist/{chunk-IJ46VCWD.js → chunk-2DHEBIJA.js} +2 -2
  12. package/dist/{chunk-TMBSPLUG.js → chunk-2LHPMFSR.js} +2 -2
  13. package/dist/{chunk-ONVD6GBY.js → chunk-2QN6NPV6.js} +2 -2
  14. package/dist/{chunk-NW4TY6VC.js → chunk-3UIS6O6N.js} +3 -3
  15. package/dist/{chunk-LXECF2ZR.js → chunk-3ZOER5GD.js} +6 -2
  16. package/dist/chunk-3ZOER5GD.js.map +1 -0
  17. package/dist/{chunk-EKEIEJL6.js → chunk-4UZDDS4S.js} +3 -3
  18. package/dist/{chunk-S56VYR4Q.js → chunk-5FRZ7YYU.js} +2 -2
  19. package/dist/{chunk-H3G4I3PN.js → chunk-5MU7PUNA.js} +2 -2
  20. package/dist/{chunk-NCCEDL2K.js → chunk-66X4XWTM.js} +6 -6
  21. package/dist/{chunk-TQPASLY4.js → chunk-6G4NORTR.js} +2 -2
  22. package/dist/{chunk-RKCRPPNB.js → chunk-6W3BZCW6.js} +3 -3
  23. package/dist/{chunk-DVRZYAGT.js → chunk-6ZN6X2LW.js} +4 -4
  24. package/dist/{chunk-PPCOKVFA.js → chunk-6ZTPSVY7.js} +2 -2
  25. package/dist/{chunk-MZTUTEHP.js → chunk-7DRKK5FQ.js} +3 -3
  26. package/dist/{chunk-GBBDFE6C.js → chunk-7LWBD3NO.js} +2 -2
  27. package/dist/{chunk-KX57HODD.js → chunk-7W765AVV.js} +6 -6
  28. package/dist/{chunk-LN7P6MZB.js → chunk-7ZPAL3F7.js} +2 -2
  29. package/dist/{chunk-CAGI4LLJ.js → chunk-AK6EWGDO.js} +5 -5
  30. package/dist/chunk-AK6EWGDO.js.map +1 -0
  31. package/dist/{chunk-CADUYBQD.js → chunk-ATL3ZVXT.js} +2 -2
  32. package/dist/{chunk-RSXQNFGO.js → chunk-ATSIGJRX.js} +2 -2
  33. package/dist/{chunk-MSLPDFK2.js → chunk-AZPPARMG.js} +6 -6
  34. package/dist/{chunk-NR2SUJ3H.js → chunk-B3X6S37C.js} +2 -2
  35. package/dist/{chunk-GWO2IDAB.js → chunk-BNGGSNO7.js} +2 -2
  36. package/dist/{chunk-JLYQQNY4.js → chunk-BYX3AUXH.js} +80 -22
  37. package/dist/chunk-BYX3AUXH.js.map +1 -0
  38. package/dist/{chunk-INMHEMXX.js → chunk-C7B3XUI4.js} +2 -2
  39. package/dist/{chunk-D3R7Q4QK.js → chunk-CJU3KXHJ.js} +2 -2
  40. package/dist/{chunk-RFO4UXKQ.js → chunk-CWYTN4IK.js} +5 -5
  41. package/dist/{chunk-HR5R5JOM.js → chunk-D5DZ4R7X.js} +2 -2
  42. package/dist/{chunk-6YD5SYQS.js → chunk-DEKA2MV3.js} +2 -2
  43. package/dist/{chunk-SYS46BL7.js → chunk-DG4KFJNA.js} +2 -2
  44. package/dist/{chunk-P2MR5UNE.js → chunk-DRVF2YS5.js} +55 -16
  45. package/dist/chunk-DRVF2YS5.js.map +1 -0
  46. package/dist/{chunk-B6IYATME.js → chunk-DXJXVWWE.js} +6 -6
  47. package/dist/{chunk-O742QBZZ.js → chunk-DZBZCFS7.js} +5 -5
  48. package/dist/{chunk-FW7NGYLT.js → chunk-FNCX4N7X.js} +4 -4
  49. package/dist/{chunk-OHOKBMTM.js → chunk-FUE2KPKM.js} +6 -6
  50. package/dist/{chunk-YALD3SST.js → chunk-G4577GK7.js} +4 -4
  51. package/dist/{chunk-DIZ6HM7Q.js → chunk-G6DAESDS.js} +5 -5
  52. package/dist/{chunk-HYYVT2KZ.js → chunk-GAZTPQ3D.js} +2 -2
  53. package/dist/{chunk-LX46B56Q.js → chunk-GJ5TMHKC.js} +4 -4
  54. package/dist/{chunk-KRVS7YWY.js → chunk-GNSLP7KA.js} +2 -2
  55. package/dist/{chunk-CWM4GQD2.js → chunk-HKANJAOP.js} +28 -5
  56. package/dist/chunk-HKANJAOP.js.map +1 -0
  57. package/dist/{chunk-5Q7AJ7DN.js → chunk-I3D67XD7.js} +4 -4
  58. package/dist/{chunk-GQ3BX5EA.js → chunk-I3ISCYT7.js} +2 -2
  59. package/dist/{chunk-HQSPF5IY.js → chunk-ISRAQIYY.js} +5 -5
  60. package/dist/{chunk-JWMBG5S3.js → chunk-J2KGT2A5.js} +6 -6
  61. package/dist/{chunk-BEZDLIDG.js → chunk-JMN3I4OC.js} +4 -4
  62. package/dist/{chunk-7PJ3BKHS.js → chunk-JO4MRPEY.js} +5 -5
  63. package/dist/{chunk-4N5Q23KV.js → chunk-JXFQEOAQ.js} +5 -5
  64. package/dist/{chunk-ICDHUUMQ.js → chunk-KF34JCIJ.js} +4 -4
  65. package/dist/{chunk-6KTVJ5ZZ.js → chunk-KKVVBFKW.js} +3 -3
  66. package/dist/{chunk-DXKLLKME.js → chunk-L374ZR75.js} +3 -3
  67. package/dist/{chunk-EES37S2V.js → chunk-L5PTLL7A.js} +3 -3
  68. package/dist/{chunk-2LFOMUEA.js → chunk-LBDG6FHB.js} +3 -3
  69. package/dist/{chunk-T7JGWTES.js → chunk-LIWA5ROZ.js} +51 -16
  70. package/dist/chunk-LIWA5ROZ.js.map +1 -0
  71. package/dist/{chunk-3O72ZD2E.js → chunk-LPVZDTQF.js} +135 -18
  72. package/dist/chunk-LPVZDTQF.js.map +1 -0
  73. package/dist/{chunk-OIBEJN5H.js → chunk-LYQUFIHL.js} +2 -2
  74. package/dist/{chunk-JNMTN5D5.js → chunk-LZHIYH32.js} +2 -2
  75. package/dist/{chunk-7KAE7CQ2.js → chunk-M2KVSM43.js} +2 -2
  76. package/dist/{chunk-IGJCYUT5.js → chunk-NSITFOCJ.js} +1 -1
  77. package/dist/chunk-NSITFOCJ.js.map +1 -0
  78. package/dist/{chunk-32B7VCKU.js → chunk-O2A5YCFF.js} +2 -2
  79. package/dist/{chunk-4A34KWOU.js → chunk-OGB2UTBC.js} +5 -5
  80. package/dist/{chunk-GQXFOAYZ.js → chunk-OMXUQAZJ.js} +3 -3
  81. package/dist/{chunk-45YHJ3GV.js → chunk-PFHF3A72.js} +3 -3
  82. package/dist/{chunk-KV6JM2IA.js → chunk-PUGHLCBW.js} +2 -2
  83. package/dist/{chunk-ZZXLB6AS.js → chunk-R6BGN6IY.js} +2 -2
  84. package/dist/{chunk-CLAHBPOI.js → chunk-RBBTJ2HY.js} +3 -3
  85. package/dist/{chunk-YKXZHUOW.js → chunk-RGUAY5IX.js} +4 -4
  86. package/dist/{chunk-AU3AUJIZ.js → chunk-RQQIB7CD.js} +2 -2
  87. package/dist/{chunk-TX5MKAHA.js → chunk-RTKREHPV.js} +2 -2
  88. package/dist/{chunk-BAHOV5I5.js → chunk-SIACMXFK.js} +8 -8
  89. package/dist/{chunk-6WO62AJW.js → chunk-SZFNO7L4.js} +3 -3
  90. package/dist/{chunk-4OQZNXQG.js → chunk-TA67ZQUH.js} +53 -6
  91. package/dist/chunk-TA67ZQUH.js.map +1 -0
  92. package/dist/{chunk-U27Y4DJZ.js → chunk-TWELPVXG.js} +3 -3
  93. package/dist/{chunk-WVE6YKMX.js → chunk-U5ZDYJLQ.js} +3 -3
  94. package/dist/{chunk-4YL2LMXK.js → chunk-UW5YKCE4.js} +6 -6
  95. package/dist/{chunk-E5SC6ENM.js → chunk-UWRVDBDC.js} +10 -10
  96. package/dist/{chunk-GTHVPVAR.js → chunk-VNPSPQNN.js} +10 -10
  97. package/dist/{chunk-A4TOGAUW.js → chunk-VXH5Z22C.js} +2 -2
  98. package/dist/{chunk-FS7NTGCJ.js → chunk-WBFJZCDJ.js} +2 -2
  99. package/dist/{chunk-4RAS6HN6.js → chunk-WBRLSPA7.js} +2 -2
  100. package/dist/{chunk-AUPSEJ7O.js → chunk-WG66ZPEV.js} +4 -4
  101. package/dist/{chunk-QSIEL6TL.js → chunk-XXONVJWA.js} +5 -5
  102. package/dist/{chunk-ZLHHE5XZ.js → chunk-YLIGPHN4.js} +3 -3
  103. package/dist/{chunk-VVSOPRUE.js → chunk-YNWBBHQK.js} +3 -3
  104. package/dist/{chunk-I6QKB7MT.js → chunk-Z6UMKUAI.js} +2 -2
  105. package/dist/{chunk-7LNE2N2V.js → chunk-Z7AHYSZF.js} +5 -5
  106. package/dist/{chunk-3PMFMUFX.js → chunk-ZA3RBGT3.js} +2 -2
  107. package/dist/{chunk-LGFTOU27.js → chunk-ZILONQGE.js} +95 -80
  108. package/dist/chunk-ZILONQGE.js.map +1 -0
  109. package/dist/{chunk-TDSN2O2V.js → chunk-ZKZXS352.js} +5 -5
  110. package/dist/{chunk-OMYCSTXL.js → chunk-ZLU3IWHK.js} +3 -3
  111. package/dist/{chunk-6JPGVL7X.js → chunk-ZYG4UWHF.js} +2 -2
  112. package/dist/classified/index.js +4 -4
  113. package/dist/{classified-marker-NA6HUV33.js → classified-marker-RYWYYZDB.js} +3 -3
  114. package/dist/{collection-facade-VBM35WAH.js → collection-facade-XV3IMJBO.js} +15 -15
  115. package/dist/{computed-GSTLWSY5.js → computed-M4QZVSPX.js} +3 -3
  116. package/dist/consent/index.js +7 -7
  117. package/dist/cover/index.js +7 -7
  118. package/dist/custody/index.js +9 -9
  119. package/dist/{dead-filter-UALP5DJX.js → dead-filter-DRKJDNSF.js} +2 -2
  120. package/dist/debug/index.js +1 -1
  121. package/dist/{delegation-JLNXM7KH.js → delegation-UEJN2LDC.js} +9 -9
  122. package/dist/derivations/index.js +10 -10
  123. package/dist/{derive-YUO3TQYN.js → derive-WIWSPZ5M.js} +8 -8
  124. package/dist/directory/index.js +8 -8
  125. package/dist/{dispatch-77CB75KB.js → dispatch-2ZE7Z5V2.js} +16 -16
  126. package/dist/{dispatch-4ZHLSFZQ.js → dispatch-KNWYDUYM.js} +9 -6
  127. package/dist/dispatch-KNWYDUYM.js.map +1 -0
  128. package/dist/{enclave-O4NOROCJ.js → enclave-VNHDWCB6.js} +7 -7
  129. package/dist/executor-4SMYWPSU.js +29 -0
  130. package/dist/executor-BJ7PCXCV.js +9 -0
  131. package/dist/executor-O4UP4M3C.js +9 -0
  132. package/dist/export-accessible-A3N2V4IX.js +23 -0
  133. package/dist/extract-partition-3EUJXWYG.js +38 -0
  134. package/dist/{fanout-sidecar-NLQ7QAYW.js → fanout-sidecar-PBEVZ5IQ.js} +7 -7
  135. package/dist/find-W2DL2BEE.js +11 -0
  136. package/dist/forget/index.js +7 -7
  137. package/dist/guards/index.js +4 -4
  138. package/dist/history/index.js +11 -11
  139. package/dist/i18n/index.js +12 -12
  140. package/dist/index.d.ts +1 -1
  141. package/dist/index.js +91 -89
  142. package/dist/index.js.map +1 -1
  143. package/dist/indexing/index.js +4 -4
  144. package/dist/introspection/index.js +9 -9
  145. package/dist/issue-NLJ3FCKL.js +19 -0
  146. package/dist/kernel/collection.d.ts +8 -2
  147. package/dist/kernel/errors.d.ts +26 -0
  148. package/dist/kernel/query/builder.d.ts +36 -2
  149. package/dist/kernel/query/live.d.ts +31 -9
  150. package/dist/kernel/query/predicate.d.ts +9 -0
  151. package/dist/kernel/refs.d.ts +3 -1
  152. package/dist/kernel/via/reconcile.d.ts +12 -0
  153. package/dist/{ledger-MVPNG5OS.js → ledger-DDIDLWA3.js} +9 -9
  154. package/dist/liberate-EPTCY3DF.js +24 -0
  155. package/dist/{link-set-3POMQR3I.js → link-set-2AYA6BEI.js} +9 -9
  156. package/dist/{managed-secret-IARIJJ7Q.js → managed-secret-6QTGWZTW.js} +7 -7
  157. package/dist/materialized-views/index.js +20 -20
  158. package/dist/{migrate-cek-XM2ETTZW.js → migrate-cek-YBNJDJ2Q.js} +2 -2
  159. package/dist/money/index.js +5 -5
  160. package/dist/noydb-RFBNRUHH.js +85 -0
  161. package/dist/overlay-views/index.js +4 -4
  162. package/dist/periods/index.js +10 -10
  163. package/dist/pod/index.js +54 -53
  164. package/dist/{pod-handle-MELERCKU.js → pod-handle-77YAUM4J.js} +7 -7
  165. package/dist/policy/index.js +7 -7
  166. package/dist/portability/index.js +8 -8
  167. package/dist/{post-register-Z5T7FY45.js → post-register-WBDTOLWD.js} +6 -6
  168. package/dist/query/index.js +6 -6
  169. package/dist/reduce/index.js +6 -6
  170. package/dist/{register-UZ37QPDB.js → register-VSPL7VRW.js} +13 -13
  171. package/dist/registry-A7JADQXC.js +9 -0
  172. package/dist/registry-AOPJN2V4.js +18 -0
  173. package/dist/registry-I4I3QIQ6.js +9 -0
  174. package/dist/registry-QSMKWF4O.js +19 -0
  175. package/dist/{request-withdrawal-PVFEYX57.js → request-withdrawal-VL5N623Q.js} +12 -12
  176. package/dist/{reveal-DQ2E3QAZ.js → reveal-Z2X4JW6E.js} +4 -4
  177. package/dist/{revoke-YXY6SHUH.js → revoke-XQ5STGT4.js} +9 -9
  178. package/dist/satellites/index.js +1 -1
  179. package/dist/schema-update/index.js +2 -2
  180. package/dist/sealed-record/index.js +10 -10
  181. package/dist/search/index.js +4 -4
  182. package/dist/{seed-DZ4ORU5N.js → seed-WJWCFPZL.js} +9 -9
  183. package/dist/sequence/index.js +7 -7
  184. package/dist/session/index.js +7 -7
  185. package/dist/shadow/index.js +2 -2
  186. package/dist/{signer-Q7XQBMPA.js → signer-N5TGVOTN.js} +8 -8
  187. package/dist/snapshots/index.js +8 -8
  188. package/dist/{stale-NI7SAXAZ.js → stale-MIO5KGEP.js} +8 -8
  189. package/dist/{storage-3VNGSHXS.js → storage-NLYOMCDM.js} +8 -8
  190. package/dist/{store-coordination-provider-TYKNR3OU.js → store-coordination-provider-XCX77ZBE.js} +7 -7
  191. package/dist/sync/index.js +8 -8
  192. package/dist/team/index.js +12 -12
  193. package/dist/tiers/index.js +9 -9
  194. package/dist/to/index.js +1 -1
  195. package/dist/transactions/index.js +3 -3
  196. package/dist/util/index.js +1 -1
  197. package/dist/vault-head/index.js +6 -6
  198. package/dist/{verify-6J2YLKSO.js → verify-5QI3DGO2.js} +5 -5
  199. package/dist/via/blob/index.d.ts +3 -0
  200. package/dist/walk-G5OAA3RE.js +21 -0
  201. package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +4 -0
  202. package/dist/with-formula/materialized-views/projection-legs.d.ts +59 -0
  203. package/dist/with-formula/materialized-views/registry.d.ts +50 -0
  204. package/dist/with-formula/materialized-views/types.d.ts +68 -10
  205. package/dist/with-shape/blobs/blob-compaction.d.ts +13 -0
  206. package/dist/with-shape/blobs/blob-set.d.ts +61 -7
  207. package/dist/with-shape/blobs/orphan-report.d.ts +62 -0
  208. package/dist/{withdraw-accessible-4JTDFRFZ.js → withdraw-accessible-H7G2AMSP.js} +11 -11
  209. package/package.json +3 -3
  210. package/dist/api-EYNT6KGS.js +0 -20
  211. package/dist/chunk-3O72ZD2E.js.map +0 -1
  212. package/dist/chunk-4OQZNXQG.js.map +0 -1
  213. package/dist/chunk-CAGI4LLJ.js.map +0 -1
  214. package/dist/chunk-CWM4GQD2.js.map +0 -1
  215. package/dist/chunk-IGJCYUT5.js.map +0 -1
  216. package/dist/chunk-JLYQQNY4.js.map +0 -1
  217. package/dist/chunk-LGFTOU27.js.map +0 -1
  218. package/dist/chunk-LXECF2ZR.js.map +0 -1
  219. package/dist/chunk-P2MR5UNE.js.map +0 -1
  220. package/dist/chunk-T7JGWTES.js.map +0 -1
  221. package/dist/dispatch-4ZHLSFZQ.js.map +0 -1
  222. package/dist/executor-CZDXBXKE.js +0 -29
  223. package/dist/executor-DVJAWN3B.js +0 -9
  224. package/dist/executor-VRLG4TQJ.js +0 -9
  225. package/dist/export-accessible-UXSMG7AB.js +0 -23
  226. package/dist/extract-partition-TVY7AMKH.js +0 -38
  227. package/dist/find-WSARMJBW.js +0 -11
  228. package/dist/issue-3JNJNPT3.js +0 -19
  229. package/dist/liberate-4LOJOLDT.js +0 -24
  230. package/dist/noydb-IRILUDED.js +0 -84
  231. package/dist/registry-ETJNA7PO.js +0 -9
  232. package/dist/registry-F7U6KSLX.js +0 -9
  233. package/dist/registry-L4ELKX6C.js +0 -18
  234. package/dist/registry-SDT5LIGO.js +0 -19
  235. package/dist/walk-WRA7RAPY.js +0 -21
  236. /package/dist/{api-EYNT6KGS.js.map → api-ETB5Y4DY.js.map} +0 -0
  237. /package/dist/{backup-FSC36VWC.js.map → backup-UOLAXOJ4.js.map} +0 -0
  238. /package/dist/{chunk-3B6S6RSI.js.map → chunk-22VRCUV2.js.map} +0 -0
  239. /package/dist/{chunk-ESKIAXO2.js.map → chunk-23ODLABM.js.map} +0 -0
  240. /package/dist/{chunk-IJ46VCWD.js.map → chunk-2DHEBIJA.js.map} +0 -0
  241. /package/dist/{chunk-TMBSPLUG.js.map → chunk-2LHPMFSR.js.map} +0 -0
  242. /package/dist/{chunk-ONVD6GBY.js.map → chunk-2QN6NPV6.js.map} +0 -0
  243. /package/dist/{chunk-NW4TY6VC.js.map → chunk-3UIS6O6N.js.map} +0 -0
  244. /package/dist/{chunk-EKEIEJL6.js.map → chunk-4UZDDS4S.js.map} +0 -0
  245. /package/dist/{chunk-S56VYR4Q.js.map → chunk-5FRZ7YYU.js.map} +0 -0
  246. /package/dist/{chunk-H3G4I3PN.js.map → chunk-5MU7PUNA.js.map} +0 -0
  247. /package/dist/{chunk-NCCEDL2K.js.map → chunk-66X4XWTM.js.map} +0 -0
  248. /package/dist/{chunk-TQPASLY4.js.map → chunk-6G4NORTR.js.map} +0 -0
  249. /package/dist/{chunk-RKCRPPNB.js.map → chunk-6W3BZCW6.js.map} +0 -0
  250. /package/dist/{chunk-DVRZYAGT.js.map → chunk-6ZN6X2LW.js.map} +0 -0
  251. /package/dist/{chunk-PPCOKVFA.js.map → chunk-6ZTPSVY7.js.map} +0 -0
  252. /package/dist/{chunk-MZTUTEHP.js.map → chunk-7DRKK5FQ.js.map} +0 -0
  253. /package/dist/{chunk-GBBDFE6C.js.map → chunk-7LWBD3NO.js.map} +0 -0
  254. /package/dist/{chunk-KX57HODD.js.map → chunk-7W765AVV.js.map} +0 -0
  255. /package/dist/{chunk-LN7P6MZB.js.map → chunk-7ZPAL3F7.js.map} +0 -0
  256. /package/dist/{chunk-CADUYBQD.js.map → chunk-ATL3ZVXT.js.map} +0 -0
  257. /package/dist/{chunk-RSXQNFGO.js.map → chunk-ATSIGJRX.js.map} +0 -0
  258. /package/dist/{chunk-MSLPDFK2.js.map → chunk-AZPPARMG.js.map} +0 -0
  259. /package/dist/{chunk-NR2SUJ3H.js.map → chunk-B3X6S37C.js.map} +0 -0
  260. /package/dist/{chunk-GWO2IDAB.js.map → chunk-BNGGSNO7.js.map} +0 -0
  261. /package/dist/{chunk-INMHEMXX.js.map → chunk-C7B3XUI4.js.map} +0 -0
  262. /package/dist/{chunk-D3R7Q4QK.js.map → chunk-CJU3KXHJ.js.map} +0 -0
  263. /package/dist/{chunk-RFO4UXKQ.js.map → chunk-CWYTN4IK.js.map} +0 -0
  264. /package/dist/{chunk-HR5R5JOM.js.map → chunk-D5DZ4R7X.js.map} +0 -0
  265. /package/dist/{chunk-6YD5SYQS.js.map → chunk-DEKA2MV3.js.map} +0 -0
  266. /package/dist/{chunk-SYS46BL7.js.map → chunk-DG4KFJNA.js.map} +0 -0
  267. /package/dist/{chunk-B6IYATME.js.map → chunk-DXJXVWWE.js.map} +0 -0
  268. /package/dist/{chunk-O742QBZZ.js.map → chunk-DZBZCFS7.js.map} +0 -0
  269. /package/dist/{chunk-FW7NGYLT.js.map → chunk-FNCX4N7X.js.map} +0 -0
  270. /package/dist/{chunk-OHOKBMTM.js.map → chunk-FUE2KPKM.js.map} +0 -0
  271. /package/dist/{chunk-YALD3SST.js.map → chunk-G4577GK7.js.map} +0 -0
  272. /package/dist/{chunk-DIZ6HM7Q.js.map → chunk-G6DAESDS.js.map} +0 -0
  273. /package/dist/{chunk-HYYVT2KZ.js.map → chunk-GAZTPQ3D.js.map} +0 -0
  274. /package/dist/{chunk-LX46B56Q.js.map → chunk-GJ5TMHKC.js.map} +0 -0
  275. /package/dist/{chunk-KRVS7YWY.js.map → chunk-GNSLP7KA.js.map} +0 -0
  276. /package/dist/{chunk-5Q7AJ7DN.js.map → chunk-I3D67XD7.js.map} +0 -0
  277. /package/dist/{chunk-GQ3BX5EA.js.map → chunk-I3ISCYT7.js.map} +0 -0
  278. /package/dist/{chunk-HQSPF5IY.js.map → chunk-ISRAQIYY.js.map} +0 -0
  279. /package/dist/{chunk-JWMBG5S3.js.map → chunk-J2KGT2A5.js.map} +0 -0
  280. /package/dist/{chunk-BEZDLIDG.js.map → chunk-JMN3I4OC.js.map} +0 -0
  281. /package/dist/{chunk-7PJ3BKHS.js.map → chunk-JO4MRPEY.js.map} +0 -0
  282. /package/dist/{chunk-4N5Q23KV.js.map → chunk-JXFQEOAQ.js.map} +0 -0
  283. /package/dist/{chunk-ICDHUUMQ.js.map → chunk-KF34JCIJ.js.map} +0 -0
  284. /package/dist/{chunk-6KTVJ5ZZ.js.map → chunk-KKVVBFKW.js.map} +0 -0
  285. /package/dist/{chunk-DXKLLKME.js.map → chunk-L374ZR75.js.map} +0 -0
  286. /package/dist/{chunk-EES37S2V.js.map → chunk-L5PTLL7A.js.map} +0 -0
  287. /package/dist/{chunk-2LFOMUEA.js.map → chunk-LBDG6FHB.js.map} +0 -0
  288. /package/dist/{chunk-OIBEJN5H.js.map → chunk-LYQUFIHL.js.map} +0 -0
  289. /package/dist/{chunk-JNMTN5D5.js.map → chunk-LZHIYH32.js.map} +0 -0
  290. /package/dist/{chunk-7KAE7CQ2.js.map → chunk-M2KVSM43.js.map} +0 -0
  291. /package/dist/{chunk-32B7VCKU.js.map → chunk-O2A5YCFF.js.map} +0 -0
  292. /package/dist/{chunk-4A34KWOU.js.map → chunk-OGB2UTBC.js.map} +0 -0
  293. /package/dist/{chunk-GQXFOAYZ.js.map → chunk-OMXUQAZJ.js.map} +0 -0
  294. /package/dist/{chunk-45YHJ3GV.js.map → chunk-PFHF3A72.js.map} +0 -0
  295. /package/dist/{chunk-KV6JM2IA.js.map → chunk-PUGHLCBW.js.map} +0 -0
  296. /package/dist/{chunk-ZZXLB6AS.js.map → chunk-R6BGN6IY.js.map} +0 -0
  297. /package/dist/{chunk-CLAHBPOI.js.map → chunk-RBBTJ2HY.js.map} +0 -0
  298. /package/dist/{chunk-YKXZHUOW.js.map → chunk-RGUAY5IX.js.map} +0 -0
  299. /package/dist/{chunk-AU3AUJIZ.js.map → chunk-RQQIB7CD.js.map} +0 -0
  300. /package/dist/{chunk-TX5MKAHA.js.map → chunk-RTKREHPV.js.map} +0 -0
  301. /package/dist/{chunk-BAHOV5I5.js.map → chunk-SIACMXFK.js.map} +0 -0
  302. /package/dist/{chunk-6WO62AJW.js.map → chunk-SZFNO7L4.js.map} +0 -0
  303. /package/dist/{chunk-U27Y4DJZ.js.map → chunk-TWELPVXG.js.map} +0 -0
  304. /package/dist/{chunk-WVE6YKMX.js.map → chunk-U5ZDYJLQ.js.map} +0 -0
  305. /package/dist/{chunk-4YL2LMXK.js.map → chunk-UW5YKCE4.js.map} +0 -0
  306. /package/dist/{chunk-E5SC6ENM.js.map → chunk-UWRVDBDC.js.map} +0 -0
  307. /package/dist/{chunk-GTHVPVAR.js.map → chunk-VNPSPQNN.js.map} +0 -0
  308. /package/dist/{chunk-A4TOGAUW.js.map → chunk-VXH5Z22C.js.map} +0 -0
  309. /package/dist/{chunk-FS7NTGCJ.js.map → chunk-WBFJZCDJ.js.map} +0 -0
  310. /package/dist/{chunk-4RAS6HN6.js.map → chunk-WBRLSPA7.js.map} +0 -0
  311. /package/dist/{chunk-AUPSEJ7O.js.map → chunk-WG66ZPEV.js.map} +0 -0
  312. /package/dist/{chunk-QSIEL6TL.js.map → chunk-XXONVJWA.js.map} +0 -0
  313. /package/dist/{chunk-ZLHHE5XZ.js.map → chunk-YLIGPHN4.js.map} +0 -0
  314. /package/dist/{chunk-VVSOPRUE.js.map → chunk-YNWBBHQK.js.map} +0 -0
  315. /package/dist/{chunk-I6QKB7MT.js.map → chunk-Z6UMKUAI.js.map} +0 -0
  316. /package/dist/{chunk-7LNE2N2V.js.map → chunk-Z7AHYSZF.js.map} +0 -0
  317. /package/dist/{chunk-3PMFMUFX.js.map → chunk-ZA3RBGT3.js.map} +0 -0
  318. /package/dist/{chunk-TDSN2O2V.js.map → chunk-ZKZXS352.js.map} +0 -0
  319. /package/dist/{chunk-OMYCSTXL.js.map → chunk-ZLU3IWHK.js.map} +0 -0
  320. /package/dist/{chunk-6JPGVL7X.js.map → chunk-ZYG4UWHF.js.map} +0 -0
  321. /package/dist/{classified-marker-NA6HUV33.js.map → classified-marker-RYWYYZDB.js.map} +0 -0
  322. /package/dist/{collection-facade-VBM35WAH.js.map → collection-facade-XV3IMJBO.js.map} +0 -0
  323. /package/dist/{computed-GSTLWSY5.js.map → computed-M4QZVSPX.js.map} +0 -0
  324. /package/dist/{dead-filter-UALP5DJX.js.map → dead-filter-DRKJDNSF.js.map} +0 -0
  325. /package/dist/{delegation-JLNXM7KH.js.map → delegation-UEJN2LDC.js.map} +0 -0
  326. /package/dist/{derive-YUO3TQYN.js.map → derive-WIWSPZ5M.js.map} +0 -0
  327. /package/dist/{dispatch-77CB75KB.js.map → dispatch-2ZE7Z5V2.js.map} +0 -0
  328. /package/dist/{enclave-O4NOROCJ.js.map → enclave-VNHDWCB6.js.map} +0 -0
  329. /package/dist/{executor-CZDXBXKE.js.map → executor-4SMYWPSU.js.map} +0 -0
  330. /package/dist/{executor-DVJAWN3B.js.map → executor-BJ7PCXCV.js.map} +0 -0
  331. /package/dist/{executor-VRLG4TQJ.js.map → executor-O4UP4M3C.js.map} +0 -0
  332. /package/dist/{export-accessible-UXSMG7AB.js.map → export-accessible-A3N2V4IX.js.map} +0 -0
  333. /package/dist/{extract-partition-TVY7AMKH.js.map → extract-partition-3EUJXWYG.js.map} +0 -0
  334. /package/dist/{fanout-sidecar-NLQ7QAYW.js.map → fanout-sidecar-PBEVZ5IQ.js.map} +0 -0
  335. /package/dist/{find-WSARMJBW.js.map → find-W2DL2BEE.js.map} +0 -0
  336. /package/dist/{issue-3JNJNPT3.js.map → issue-NLJ3FCKL.js.map} +0 -0
  337. /package/dist/{ledger-MVPNG5OS.js.map → ledger-DDIDLWA3.js.map} +0 -0
  338. /package/dist/{liberate-4LOJOLDT.js.map → liberate-EPTCY3DF.js.map} +0 -0
  339. /package/dist/{link-set-3POMQR3I.js.map → link-set-2AYA6BEI.js.map} +0 -0
  340. /package/dist/{managed-secret-IARIJJ7Q.js.map → managed-secret-6QTGWZTW.js.map} +0 -0
  341. /package/dist/{migrate-cek-XM2ETTZW.js.map → migrate-cek-YBNJDJ2Q.js.map} +0 -0
  342. /package/dist/{noydb-IRILUDED.js.map → noydb-RFBNRUHH.js.map} +0 -0
  343. /package/dist/{pod-handle-MELERCKU.js.map → pod-handle-77YAUM4J.js.map} +0 -0
  344. /package/dist/{post-register-Z5T7FY45.js.map → post-register-WBDTOLWD.js.map} +0 -0
  345. /package/dist/{register-UZ37QPDB.js.map → register-VSPL7VRW.js.map} +0 -0
  346. /package/dist/{registry-ETJNA7PO.js.map → registry-A7JADQXC.js.map} +0 -0
  347. /package/dist/{registry-F7U6KSLX.js.map → registry-AOPJN2V4.js.map} +0 -0
  348. /package/dist/{registry-L4ELKX6C.js.map → registry-I4I3QIQ6.js.map} +0 -0
  349. /package/dist/{registry-SDT5LIGO.js.map → registry-QSMKWF4O.js.map} +0 -0
  350. /package/dist/{request-withdrawal-PVFEYX57.js.map → request-withdrawal-VL5N623Q.js.map} +0 -0
  351. /package/dist/{reveal-DQ2E3QAZ.js.map → reveal-Z2X4JW6E.js.map} +0 -0
  352. /package/dist/{revoke-YXY6SHUH.js.map → revoke-XQ5STGT4.js.map} +0 -0
  353. /package/dist/{seed-DZ4ORU5N.js.map → seed-WJWCFPZL.js.map} +0 -0
  354. /package/dist/{signer-Q7XQBMPA.js.map → signer-N5TGVOTN.js.map} +0 -0
  355. /package/dist/{stale-NI7SAXAZ.js.map → stale-MIO5KGEP.js.map} +0 -0
  356. /package/dist/{storage-3VNGSHXS.js.map → storage-NLYOMCDM.js.map} +0 -0
  357. /package/dist/{store-coordination-provider-TYKNR3OU.js.map → store-coordination-provider-XCX77ZBE.js.map} +0 -0
  358. /package/dist/{verify-6J2YLKSO.js.map → verify-5QI3DGO2.js.map} +0 -0
  359. /package/dist/{walk-WRA7RAPY.js.map → walk-G5OAA3RE.js.map} +0 -0
  360. /package/dist/{withdraw-accessible-4JTDFRFZ.js.map → withdraw-accessible-H7G2AMSP.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/with-formula/materialized-views/dependency-analyzer.ts","../src/with-formula/materialized-views/query-hash.ts","../src/with-formula/materialized-views/projection-legs.ts","../src/with-formula/materialized-views/registry.ts"],"sourcesContent":["import type { Query, QueryPlan } from '../../kernel/query/builder.js'\nimport type { JoinContext } from '../../kernel/query/join.js'\nimport type { MaterializedViewSpec } from './types.js'\n\n/**\n * Walks a `Query<T>` plan and returns the set of source collection\n * names that any source-write should trigger a refresh on.\n *\n * Handles:\n * - root collection (the one the query was built from)\n * - FK join targets (`.join(field, { as })`)\n *\n * Also handles:\n * - cross-join targets (`.crossJoin(target, { as })`) — v3\n *\n * Deferred:\n * - `.wherePredicate(name)` — v2 predicate primitive\n * - Overlay-name expansion to {base, overlay}\n *\n * The set is materialized at MV registration time. The MV registry\n * uses it to (a) dispatch `onSourceWrite` only to MVs that actually\n * care, and (b) contribute edges to the shared cycle-detection graph.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function analyzeDependencies(query: Query<any>): Set<string> {\n const deps = new Set<string>()\n const plan = query._plan()\n const ctx = query._joinContext()\n\n // The root collection is always a dependency.\n if (ctx?.leftCollection) {\n deps.add(ctx.leftCollection)\n }\n\n // FK join targets contribute additional sources.\n for (const leg of plan.joins) {\n deps.add(leg.target)\n }\n\n // Cross-join targets are also dependency sources — writes to either side\n // must trigger MV refresh. Symmetric with FK-join target handling above.\n for (const clause of plan.clauses) {\n if (clause.type === 'crossJoin') {\n deps.add(clause.target)\n }\n }\n\n // Sub-plans inside OR clauses can carry nested joins. Walk them.\n // (Today only top-level `.join()` populates `plan.joins`, but the\n // OR-group machinery permits sub-plans, so we recurse defensively.)\n walkClausesForJoins(plan, deps, ctx)\n\n return deps\n}\n\nfunction walkClausesForJoins(\n plan: QueryPlan,\n deps: Set<string>,\n ctx: JoinContext | undefined,\n): void {\n void ctx\n // Today `plan.joins` carries all join legs at top level. Sub-plans\n // inside OR groups don't currently support nested joins, so the loop\n // below is a no-op safety net for future builder extensions.\n for (const clause of plan.clauses) {\n if (clause.type === 'group') {\n // Group clauses don't (yet) carry their own joins; this is a\n // forward-compat anchor for when OR-groups support nested\n // sources.\n }\n }\n}\n\n/**\n * Convenience: produce a stable string summary of the query plan\n * suitable for `queryHash` derivation. Captures everything the\n * dependency analyzer reads + the where/orderBy/limit/offset\n * structure that affects materialized rows.\n *\n * `joinContext` is intentionally NOT included — the join-resolution\n * function references would defeat hash determinism. The set of join\n * TARGETS (collection names) IS included via the plan.joins legs.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function summarizeQueryPlan(query: Query<any>): string {\n const plan = query._plan()\n const ctx = query._joinContext()\n return JSON.stringify({\n root: ctx?.leftCollection ?? null,\n clauses: plan.clauses.map(c => {\n if (c.type === 'crossJoin') {\n return {\n type: 'crossJoin',\n target: c.target,\n as: c.as,\n // Inline on: callback: use sentinel — drift detection disabled for this MV\n onPredicateName: c.onPredicateName ?? (c.on ? '[inline]' : null),\n maxRows: c.maxRows ?? null,\n // `outer` changes the row set, so it is part of the plan's identity\n // for drift detection, not decoration (#1130).\n outer: c.outer ?? false,\n }\n }\n return c\n }),\n orderBy: plan.orderBy,\n limit: plan.limit ?? null,\n offset: plan.offset,\n joins: plan.joins.map(j => ({ field: j.field, as: j.as, target: j.target, mode: j.mode })),\n })\n}\n\n/**\n * Canonical string description of a UNION MV's plan, used as input to\n * `computeQueryHash`.\n *\n * Asymmetry note:\n * - Arm collection names are NOT sorted. Declaration order is\n * semantically meaningful for the dedup-only UNION path —\n * `materializeUnionResult` iterates `spec.unionSources` in\n * declaration order and keeps the first-seen row per composite key\n * (tie-break precedence). If we sorted arms here, a consumer who\n * reordered `unionSources` to change precedence would compute the\n * same `queryHash`, refresh would be a no-op, and stale MV rows\n * would persist. Hashing in declaration order makes any reorder\n * trigger a refresh.\n * - `groupBy` fields ARE sorted. Multi-key groupBy buckets are\n * commutative (`canonicalGroupKey` produces the same composite key\n * regardless of field order in the input spec).\n * - `aggregate` keys ARE sorted. Reducer-spec keys are independent\n * of each other — order of declaration doesn't change output.\n *\n * Per-arm `map` functions are NOT fingerprinted; consumers must bump\n * the MV's `name` (or rely on application-level cache busting) when\n * `map` semantics change non-equivalently.\n */\nexport function summarizeUnionPlan<T extends Record<string, unknown>>(\n spec: MaterializedViewSpec<T>,\n): string {\n return `union(${summarizeUnionArms(spec)})${summarizeGroupingTail(spec)}`\n}\n\n/**\n * Canonical string description of a projection MV's plan (#810), used\n * as input to `computeQueryHash`.\n *\n * Leg descriptors ARE sorted (contrast with UNION arm order): every\n * leg attaches under a distinct `as` alias, forward legs are\n * one-to-one attachments and collect legs are independent\n * hash-grouped passes, so declaration order never changes the\n * materialized rows — a pure reorder must NOT force a refresh.\n * `from` (#1140) constrains the legal orderings (a leg must follow the\n * alias it attaches to) without making order meaningful: each descriptor\n * carries its own `@alias`, and aliases are unique, so the sorted set\n * still determines the leg graph exactly.\n *\n * The projection `map` is NOT fingerprinted (identical limitation as\n * the UNION arm `map`); consumers must bump the MV's `name` when\n * `map` semantics change non-equivalently.\n */\nexport function summarizeProjectionPlan<T extends Record<string, unknown>>(\n spec: MaterializedViewSpec<T>,\n): string {\n const projection = spec.projection!\n const legs = projection.joins\n .map(leg => {\n // #1140 — `from` changes which rows a leg attaches to, so it is part of\n // the plan's identity. Omitting it would let two structurally different\n // projections share a queryHash and silently skip a refresh.\n const at = leg.from !== undefined ? `@${leg.from}` : ''\n return 'collect' in leg\n ? `collect${at}:${leg.collect}.${leg.on}→${leg.as}`\n : `field${at}:${leg.field}→${leg.as}`\n })\n .sort()\n const body = JSON.stringify({ source: projection.source, legs })\n return `projection(${body})${summarizeGroupingTail(spec)}`\n}\n\n/** Arm descriptors for `summarizeUnionPlan` — declaration order preserved (see its doc). */\nfunction summarizeUnionArms<T extends Record<string, unknown>>(\n spec: MaterializedViewSpec<T>,\n): string {\n return (spec.unionSources ?? [])\n .map(s => {\n // Fold each arm's join legs into the summary so adding or\n // reordering joins (which changes the materialized rows) bumps\n // queryHash. Leg order is declaration-significant (legs chain), so\n // it is NOT sorted — same rationale as arm declaration order.\n const joins = s.join?.length\n ? `[${s.join.map(j => `${j.field}→${j.as}`).join(';')}]`\n : ''\n return `${s.collection}${joins}`\n })\n .join(',')\n}\n\n/**\n * Shared `|groupBy(…)|aggregate(…)|money(…)` tail for the UNION and\n * projection summaries — both feed the same post-map grouping pipeline,\n * so the same spec fields fold into both hashes with the same rules.\n */\nfunction summarizeGroupingTail<T extends Record<string, unknown>>(\n spec: MaterializedViewSpec<T>,\n): string {\n const groupBy: string = Array.isArray(spec.groupBy)\n ? [...spec.groupBy].sort().join(',')\n : typeof spec.groupBy === 'string'\n ? spec.groupBy\n : ''\n const aggKeys = spec.aggregate ? Object.keys(spec.aggregate).sort().join(',') : ''\n // `moneyFields` changes reducer semantics (float → exact BigInt), so\n // declaring / removing / re-keying it must bump queryHash. Keys are\n // sorted — they're independent of each other (one descriptor per\n // output field), same rationale as aggregate keys.\n const moneyKeys = spec.moneyFields ? Object.keys(spec.moneyFields).sort().join(',') : ''\n return `|groupBy(${groupBy})|aggregate(${aggKeys})|money(${moneyKeys})`\n}\n","/**\n * Deterministic hash of a materialized view strategy's \"shape\": MV\n * name + canonical query-plan summary + sorted dependency-set.\n *\n * Used to detect strategy drift: a row whose `_materializedFrom.queryHash`\n * doesn't match the current strategy is considered stale.\n *\n * Web Crypto SHA-256 — no extra deps. Mirrors the v1\n * `computeStrategyHash` pattern.\n */\nimport { sha256Hex } from '../../kernel/enclave/index.js'\n\nexport async function computeQueryHash(\n mvName: string,\n /**\n * Source-collection set the query depends on. Sorted before\n * canonicalization so set iteration order doesn't affect the hash.\n */\n dependencies: ReadonlySet<string>,\n /**\n * Stringified query-plan summary. The caller produces this from the\n * `Query<T>` builder — concretely: a JSON serialization of clauses +\n * orderBy + limit + offset + joins. Function bodies inside\n * `wherePredicate` are NOT included here (those carry their own\n * `predicateHash` to be folded in by a later sub-issue).\n */\n queryPlanSummary: string,\n): Promise<string> {\n const canonical = JSON.stringify({\n mvName,\n dependencies: [...dependencies].sort(),\n queryPlanSummary,\n })\n const bytes = new TextEncoder().encode(canonical)\n return sha256Hex(bytes)\n}\n\n/**\n * Canonicalize a query plan for hashing. Walks the plan structure\n * with sorted keys so insertion order doesn't perturb the result.\n * Lives here rather than in `query/builder.ts` to keep that module\n * stable across MV-specific evolutions.\n *\n * @internal exported for testing\n */\nexport function canonicalizeQueryPlan(plan: unknown): string {\n return JSON.stringify(plan, (_key, value) => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k]\n }\n return sorted\n }\n return value\n })\n}\n","/**\n * Projection-leg topology (#810, extended by #1140).\n *\n * A projection MV's legs originally all attached to the PRIMARY row: a forward\n * leg named an FK field on `projection.source`, and a reverse `collect` leg's\n * `on` field had to `ref()` the source itself. Anything two FKs away was\n * therefore inexpressible — `bill → entity → client` has no leg shape, because\n * the bill has no `clientId` and `clients.entityId` refs `entities`, not\n * `bills`.\n *\n * `from` closes that: a leg may attach to a previously-declared ALIAS instead of\n * to the primary row. This module owns the two questions that follow from it —\n * *is this leg graph well-formed?* and *which collection does a leg's rows come\n * from?* — so neither the registry nor the executor has to re-derive them.\n *\n * **Why cycles are impossible by construction, and there is no depth cap.**\n * `from` may only name an alias declared EARLIER in `joins`. A leg can therefore\n * never reach forward, the graph is a forest rooted at the primary row, and its\n * depth is bounded by the number of legs. Validation refuses an unknown or\n * not-yet-declared alias, which is the same check.\n */\n\nimport { MaterializedViewConfigError } from '../../kernel/errors.js'\nimport type { ProjectionJoinLeg, ProjectionSpec } from './types.js'\n\n/** Reverse (one-to-many) leg — discriminated on `collect`, as the type is. */\nexport function isCollectLeg(\n leg: ProjectionJoinLeg,\n): leg is Extract<ProjectionJoinLeg, { collect: string }> {\n return 'collect' in leg\n}\n\n/**\n * Refuse a malformed leg graph where `withMaterializedView()` checks the rest of\n * the leg shape — at spec CONSTRUCTION, not at vault open and not at first\n * materialization. Alias wiring is pure configuration: it needs no refs, no\n * records and no store, so the earliest failure is the best one.\n * (Ref EXISTENCE still resolves at first materialization, unchanged — refs\n * cannot exist until after `openVault()` returns.)\n */\nexport function validateProjectionLegs<T extends Record<string, unknown>>(\n mvName: string,\n projection: ProjectionSpec<T>,\n): void {\n // Non-empty and unique `as` are already refused by `withMaterializedView()`\n // itself, earlier and with its own message — not re-checked here. This\n // function owns the `from` wiring and nothing else.\n const seen = new Map<string, ProjectionJoinLeg>()\n for (const leg of projection.joins) {\n if (leg.from !== undefined) {\n const parent = seen.get(leg.from)\n if (!parent) {\n throw new MaterializedViewConfigError(\n `\"${mvName}\": projection leg \"${leg.as}\" declares from: \"${leg.from}\", which is not an ` +\n `alias declared EARLIER in \\`joins\\`. A leg may only attach to the primary row or to a ` +\n `preceding leg — that ordering rule is what makes a cycle impossible. Known so far: ` +\n `${[...seen.keys()].map(a => `\"${a}\"`).join(', ') || '(none)'}`,\n )\n }\n if (isCollectLeg(parent)) {\n throw new MaterializedViewConfigError(\n `\"${mvName}\": projection leg \"${leg.as}\" declares from: \"${leg.from}\", but \"${leg.from}\" ` +\n `is a collect leg and holds an ARRAY of rows, not one record. A leg can only hang off a ` +\n `forward leg (record | null). Attach it to the primary row instead, or collect the ` +\n `far side directly if its ref() reaches \"${projection.source}\".`,\n )\n }\n }\n seen.set(leg.as, leg)\n }\n}\n\n/**\n * The collection a leg's rows come from — the primary source for a root leg, the\n * `from` leg's own target otherwise.\n *\n * Returns `null` when a forward `ref()` somewhere along the chain is not\n * declared yet, which at registration time is the normal case rather than an\n * error: refs are declared after `openVault()` returns, so the registry retries\n * this on every dispatch until it resolves (`_pendingForwardDeps`).\n *\n * `resolveRef` is passed in rather than imported so this module stays free of\n * vault wiring — the registry hands it the ref registry's `getOutbound`, the\n * executor hands it a join context lookup. Both answer the same question.\n */\nexport type RefLookup = (collection: string, field: string) => { target: string } | null\n\nexport function resolveLegOwner(\n leg: ProjectionJoinLeg,\n joins: ReadonlyArray<ProjectionJoinLeg>,\n source: string,\n resolveRef: RefLookup,\n): string | null {\n if (leg.from === undefined) return source\n const parent = joins.find(l => l.as === leg.from)\n if (!parent) return null // refused by validateProjectionLegs; defensive here\n if (isCollectLeg(parent)) return parent.collect // refused too, same reason\n const parentOwner = resolveLegOwner(parent, joins, source, resolveRef)\n if (parentOwner === null) return null\n return resolveRef(parentOwner, parent.field)?.target ?? null\n}\n\n/**\n * The collection a FORWARD leg resolves INTO — i.e. its dependency. `null` while\n * any ref in the chain (including this leg's own) is still undeclared.\n */\nexport function resolveForwardLegTarget(\n leg: Extract<ProjectionJoinLeg, { field: string }>,\n joins: ReadonlyArray<ProjectionJoinLeg>,\n source: string,\n resolveRef: RefLookup,\n): string | null {\n const owner = resolveLegOwner(leg, joins, source, resolveRef)\n if (owner === null) return null\n return resolveRef(owner, leg.field)?.target ?? null\n}\n","import { MaterializedViewSourceUnknownError, RefNotDeclaredError } from '../../kernel/errors.js'\nimport type { ViaGraph, FieldRef, EdgeKind, Grain } from '../../kernel/via/graph.js'\nimport type { Clause, FieldClause } from '../../kernel/query/predicate.js'\nimport type { DeclaredPredicate } from '../../kernel/query/builder.js'\nimport { analyzeDependencies, summarizeQueryPlan, summarizeUnionPlan, summarizeProjectionPlan } from './dependency-analyzer.js'\nimport { computeQueryHash } from './query-hash.js'\nimport { isCollectLeg, resolveForwardLegTarget } from './projection-legs.js'\nimport type { MaterializedViewSpec, MVQueryContext } from './types.js'\n\n/**\n * Whole-record artifact-grain field marker (#638 Task 2) — MUST match\n * `derivations/registry.ts`'s and `vault.ts`'s overlay-edge marker so\n * cross-registry edges (a derivation feeding an MV, or vice versa) resolve\n * to the SAME graph node. See that file's `WHOLE_RECORD` doc comment.\n */\nconst WHOLE_RECORD = '*'\n\n/**\n * One registered MV strategy alongside its derived metadata. Stored\n * type-erased on `TRow` so the registry can hold heterogeneous MVs.\n */\nexport interface RegisteredMV {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly spec: MaterializedViewSpec<any>\n /** Output collection name (`spec.output?.collection ?? spec.name`). */\n readonly outputCollection: string\n /** Set of source collections; populated at registration via the analyzer. */\n readonly dependencies: ReadonlySet<string>\n /** Canonical `queryHash` — `_materializedFrom.queryHash` for every emitted row. */\n readonly queryHash: string\n /**\n * Top-level FieldClauses on the partition field, captured at\n * registration time. Used by the cycle detector to resolve\n * same-collection-as-source edges via the partition-discriminator\n * check. Empty when `spec.output?.partition` is undefined.\n */\n readonly partitionClauses: readonly FieldClause[]\n /**\n * #638 Task 2 — `'record'` for a row-per-source-row Query<T> or\n * `unionSources` MV, `'aggregate'` for a `.groupBy().aggregate()` MV\n * (the shape that requires explicit `sources`, since the dependency\n * analyzer can't walk an aggregate plan). Feeds `edges()`'s grain.\n */\n readonly grain: Grain\n}\n\n/**\n * Vault-internal registry of MV strategies. Owned by `Vault`; not\n * exported. Parallel to v1's `DerivationRegistry`; the two graphs share\n * a single cycle-detection pass at vault open (see `validate`).\n *\n * @internal\n */\nexport class MaterializedViewRegistry {\n /** Keyed by `spec.name`. */\n private readonly _byName = new Map<string, RegisteredMV>()\n /** Keyed by dependency source-collection → MVs that depend on it. */\n private readonly _bySource = new Map<string, RegisteredMV[]>()\n /**\n * Projection MVs (#810) whose forward-leg ref() targets could not be\n * resolved at registration time. A forward leg names only the FK\n * FIELD; its dependency is the field's ref() TARGET, declared on the\n * source collection — but registration runs at vault open, BEFORE\n * user code declares collections (and their refs). Constructing the\n * source collection here to look them up would be worse: a later\n * `vault.collection(source, { refs })` call only registers refs on a\n * cache miss, so an early construction would silently drop them.\n * Instead each entry carries a non-constructive ref-registry probe;\n * `mvsForSource` retries on every dispatch until every forward\n * target has resolved (see `_resolvePendingForwardDeps`).\n */\n private readonly _pendingForwardDeps: Array<{\n reg: RegisteredMV\n /** Forward-leg ALIASES still awaiting resolution (#1140 — a leg is identified\n * by its alias, not its field: with `from`, two legs may name the same FK\n * field on different collections). */\n aliases: Set<string>\n resolveTarget: (alias: string) => string | null\n }> = []\n\n /**\n * Query-form strategies whose `query()` callback could not be planned at\n * registration time because a `.join()` names a field whose `ref()` is not\n * declared YET (#1139).\n *\n * Registration runs inside `openVault()`; a collection's refs can only be\n * declared afterwards, so for a query-form MV that joins a declared FK there\n * is NO call ordering the consumer can choose — the plan is simply built too\n * early. Rather than failing the vault open, the strategy is parked here and\n * replanned from {@link resolvePendingPlans}, which every write dispatch and\n * `vault.refreshView()` call runs first. This is the query-form counterpart\n * of `_pendingForwardDeps`, one level up: that defers a leg's TARGET, this\n * defers the whole plan.\n *\n * Only `RefNotDeclaredError` parks a strategy. Every other planning failure\n * still throws out of `openVault()` exactly as before, so a typo'd source or\n * a malformed spec keeps its loud, early error.\n *\n * A parked strategy is invisible until it resolves: it contributes no\n * `_bySource` entries and no cycle-detection edges (same caveat as a\n * late-resolved forward target — `edges()` runs once at vault open). It also\n * cannot be dispatched, which is why {@link hasPendingPlans} forces the\n * conservative branch in `Collection._txAtomicSafe`: the atomic write path\n * skips MV dispatch, and skipping it here would mean the write that was\n * supposed to trigger the first replan is the one that gets missed.\n */\n private readonly _pendingPlans: Array<{\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n spec: MaterializedViewSpec<any>\n db: MVQueryContext\n options?: { knownCollections?: (name: string) => boolean }\n }> = []\n\n /**\n * Register an MV. Invokes `spec.query()` once at registration time to\n * read the plan + join context; the resulting `Query<T>` is discarded\n * after dependency extraction. `vault.collection(...)` must therefore\n * be functional by the time this runs — typically wired from\n * `Vault._initMaterializedViews` after collection bootstrap.\n *\n * Throws `MaterializedViewSourceUnknownError` if the analyzer\n * surfaces a dependency the vault doesn't know about (when a\n * `knownCollections` checker is supplied).\n */\n async register(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n spec: MaterializedViewSpec<any>,\n db: MVQueryContext,\n options?: { knownCollections?: (name: string) => boolean },\n ): Promise<void> {\n // Build a predicate-aware db wrapper. If `spec.predicates` is\n // declared, the wrapper intercepts `.collection().query()` and\n // attaches the predicates map to the resulting Query<T>. With no\n // predicates declared, the wrapper is the original db unchanged.\n const dbForQuery = spec.predicates ? wrapDbWithPredicates(db, spec.predicates) : db\n\n // Invoke the query callback once to inspect its plan / dependencies.\n // For Query<T> shapes the analyzer extracts deps + plan summary\n // automatically. Reduction / GroupedReduction shapes don't\n // expose the underlying Query, so the spec must declare `sources`\n // explicitly. `partitionClauses` are only populated for Query<T>\n // since same-collection-partition is a non-aggregate concern.\n // UNION-form strategies: dependencies and plan summary come\n // straight off the strategy — no `query` callback to introspect.\n // The dependency-analyzer + summarizer are bypassed entirely; the\n // executor handles materialization via `materializeUnionResult`.\n let dependencies: Set<string>\n let queryPlanSummary: string\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let qAny: any = null\n let isQuery = false\n // Projection-form (#810): forward legs whose ref() target wasn't\n // resolvable at registration time — folded in lazily, see\n // `_pendingForwardDeps`.\n const pendingForwardFields: string[] = []\n if (spec.unionSources) {\n dependencies = new Set(spec.unionSources.map(s => s.collection))\n // Per-arm joins resolve right-side collections that aren't among\n // the arm `collection`s. The consumer lists those in `sources`;\n // fold them into the dependency set so a write to a join-target\n // collection triggers MV refresh (and contributes a cycle edge).\n if (spec.sources) for (const s of spec.sources) dependencies.add(s)\n queryPlanSummary = summarizeUnionPlan(spec)\n } else if (spec.projection) {\n // Projection-form (#810): dependencies are all AUTO — the primary\n // source, every collect leg's collection (both literal names), and\n // every forward leg's ref() target. Forward targets usually can't\n // resolve yet (refs are declared after vault open) — those go\n // through the pending-resolution path below. Explicit `sources`\n // remains additive, same as the other two forms.\n const projection = spec.projection\n dependencies = new Set([projection.source])\n for (const leg of projection.joins) {\n // A collect leg's dependency is its literal collection name, whatever it\n // attaches to — which is why `from` needs no new dependency machinery on\n // that side. A forward leg's dependency is a ref() target, still unknown.\n if (isCollectLeg(leg)) dependencies.add(leg.collect)\n else pendingForwardFields.push(leg.as)\n }\n if (spec.sources) for (const s of spec.sources) dependencies.add(s)\n queryPlanSummary = summarizeProjectionPlan(spec)\n } else {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let q: any\n try {\n q = spec.query!(dbForQuery)\n } catch (e) {\n // #1139 — a join on a ref that is not declared YET. Park and replan;\n // see `_pendingPlans`. Anything else is a real registration failure.\n if (!(e instanceof RefNotDeclaredError)) throw e\n this._pendingPlans.push({ spec, db, ...(options !== undefined ? { options } : {}) })\n return\n }\n qAny = q // already `any` — see the declaration above\n isQuery = typeof qAny._plan === 'function'\n if (isQuery) {\n // `q` is the `Query` arm of the union here (runtime-confirmed via\n // `qAny._plan` above); reuse the already-`any` `qAny` the block uses\n // for `_plan()` rather than re-narrowing.\n dependencies = analyzeDependencies(qAny)\n queryPlanSummary = summarizeQueryPlan(qAny)\n // Fold `.wherePredicate(name, ctx)` references into the plan\n // summary so predicate function or ctx changes (signalled by\n // bumping `hash` or supplying a different ctx) propagate into\n // `queryHash` and force refresh on next visit.\n const predicateRefs = extractPredicateRefs(qAny._plan())\n if (predicateRefs.length > 0) {\n queryPlanSummary = JSON.stringify({ plan: queryPlanSummary, predicates: predicateRefs })\n }\n // If `sources` is ALSO declared, take the union (consumer's\n // explicit list extends the auto-analyzed set).\n if (spec.sources) for (const s of spec.sources) dependencies.add(s)\n } else {\n // Aggregate shape: require explicit `sources`.\n if (!spec.sources || spec.sources.length === 0) {\n throw new Error(\n `withMaterializedView \"${spec.name}\": query() returned an aggregate ` +\n `(Reduction or GroupedReduction) but no \\`sources\\` field is declared. ` +\n `The dependency analyzer cannot walk through groupBy().aggregate() ` +\n `back to the source — declare sources: [...] explicitly.`,\n )\n }\n dependencies = new Set(spec.sources)\n // Aggregate plans don't carry a chainable query plan for summary\n // purposes; the dep-set + spec.name serve as the queryHash inputs.\n queryPlanSummary = JSON.stringify({ aggregate: true, sources: [...spec.sources].sort() })\n }\n }\n\n // Sanity-check declared dependencies against the vault's known\n // collections. Optional — when the checker isn't supplied (test\n // wiring, in-process composition) the registration succeeds and\n // any typo surfaces at first onSourceWrite as a no-op.\n if (options?.knownCollections) {\n for (const dep of dependencies) {\n if (!options.knownCollections(dep)) {\n throw new MaterializedViewSourceUnknownError(spec.name, dep)\n }\n }\n }\n\n const outputCollection = spec.output?.collection ?? spec.name\n const queryHash = await computeQueryHash(spec.name, dependencies, queryPlanSummary)\n // For same-collection-as-source MVs, capture the where-clauses on\n // the partition field so cycle detection can prove disjointness.\n // Only applicable to Query<T> shapes — aggregate MVs don't carry\n // a chainable plan to inspect (and same-collection aggregation\n // doesn't make sense for same-collection aggregation).\n const partitionClauses: FieldClause[] = []\n const partitionField = spec.output?.partition?.field\n if (partitionField !== undefined && isQuery) {\n const plan = qAny._plan()\n for (const clause of plan.clauses) {\n if (isFieldClauseOnField(clause, partitionField)) partitionClauses.push(clause)\n }\n }\n // #638 Task 2 — 'aggregate' only for the explicit-sources aggregate shape\n // (groupBy().aggregate() with no chainable plan); a row-per-source-row\n // Query<T>, unionSources, or projection MV is 'record'.\n const grain: Grain = spec.unionSources || spec.projection || isQuery ? 'record' : 'aggregate'\n const reg: RegisteredMV = { spec, outputCollection, dependencies, queryHash, partitionClauses, grain }\n\n this._byName.set(spec.name, reg)\n for (const dep of dependencies) {\n const arr = this._bySource.get(dep)\n if (arr) arr.push(reg)\n else this._bySource.set(dep, [reg])\n }\n if (pendingForwardFields.length > 0) {\n // Non-constructive ref-registry probe: the Vault (the real\n // MVQueryContext) carries its RefRegistry as a private field,\n // reachable structurally at runtime. Test stubs without one simply\n // never resolve — forward deps then come only from explicit `sources`.\n const refRegistry = (db as unknown as {\n refRegistry?: { getOutbound(collection: string): Record<string, { target: string }> }\n }).refRegistry\n const projectionSpec = spec.projection!\n const resolveRef = (c: string, f: string): { target: string } | null =>\n refRegistry?.getOutbound(c)[f] ?? null\n this._pendingForwardDeps.push({\n reg,\n aliases: new Set(pendingForwardFields),\n resolveTarget: (alias) => {\n const leg = projectionSpec.joins.find(l => l.as === alias)\n if (!leg || isCollectLeg(leg)) return null\n // Walks the `from` chain — every hop needs its own ref declared, so a\n // two-hop leg simply resolves one dispatch later than a one-hop one.\n return resolveForwardLegTarget(leg, projectionSpec.joins, projectionSpec.source, resolveRef)\n },\n })\n // Immediate attempt — covers refs already declared by the time\n // this MV registers (re-registration flows, test wiring).\n this._resolvePendingForwardDeps()\n }\n }\n\n /**\n * `true` while any query-form strategy is still unplanned (#1139). Read by\n * `Collection._txAtomicSafe`, which must refuse the atomic write path while\n * this holds — see the `_pendingPlans` doc comment for why.\n */\n hasPendingPlans(): boolean {\n return this._pendingPlans.length > 0\n }\n\n /**\n * Replan every parked query-form strategy (#1139). Called at the head of both\n * write dispatchers and of `vault.refreshView()`, so a strategy resolves on the\n * first write or refresh after its source collection's refs are declared —\n * which is the earliest moment it could produce a correct plan, and strictly\n * before the first moment it could have any output to produce.\n *\n * Each entry is handed straight back to {@link register}, so a strategy that\n * is STILL unplannable simply re-parks itself and the next dispatch tries\n * again. Idempotent and cheap: the array empties as strategies resolve, and\n * both callers skip the await entirely once it is empty.\n *\n * A late-resolved strategy does NOT retro-feed `edges()` — the unified cycle\n * pass runs once at vault open, before refs exist. Same caveat, and the same\n * reason, as a late-resolved forward-leg target.\n */\n async resolvePendingPlans(): Promise<void> {\n if (this._pendingPlans.length === 0) return\n // Splice first: `register` re-parks anything still unplannable, and reading\n // a live array it is concurrently pushing to would loop.\n const parked = this._pendingPlans.splice(0)\n for (const entry of parked) {\n await this.register(entry.spec, entry.db, entry.options)\n }\n }\n\n /** All MVs that depend on `source`, in registration order. */\n mvsForSource(source: string): ReadonlyArray<RegisteredMV> {\n if (this._pendingForwardDeps.length > 0) this._resolvePendingForwardDeps()\n return this._bySource.get(source) ?? []\n }\n\n /**\n * Retry ref() resolution for every pending projection forward leg\n * (#810). A field resolves once its source collection's refs have\n * been declared; the target then folds into the owning MV's\n * dependency set and `_bySource`, so subsequent writes to it\n * dispatch a refresh. Idempotent and cheap — the pending list\n * empties as fields resolve, and `mvsForSource` skips the call\n * entirely once it's empty.\n *\n * Late-resolved targets do NOT retro-feed `edges()` — the cycle\n * pass runs once at vault open, before refs exist. A cycle routed\n * exclusively through a forward leg is therefore not detected at\n * open (collect + source edges, the literal names, are).\n */\n private _resolvePendingForwardDeps(): void {\n for (let i = this._pendingForwardDeps.length - 1; i >= 0; i--) {\n const entry = this._pendingForwardDeps[i]!\n for (const alias of [...entry.aliases]) {\n const target = entry.resolveTarget(alias)\n if (target === null) continue\n entry.aliases.delete(alias)\n if (entry.reg.dependencies.has(target)) continue\n // `dependencies` is declared ReadonlySet for consumers; the\n // registry owns the underlying Set and is the one writer.\n ;(entry.reg.dependencies as Set<string>).add(target)\n const arr = this._bySource.get(target)\n if (arr) arr.push(entry.reg)\n else this._bySource.set(target, [entry.reg])\n }\n if (entry.aliases.size === 0) this._pendingForwardDeps.splice(i, 1)\n }\n }\n\n /** Single MV by name, or `undefined`. */\n byName(name: string): RegisteredMV | undefined {\n return this._byName.get(name)\n }\n\n /** Iterate over every registered MV. */\n all(): ReadonlyArray<RegisteredMV> {\n return [...this._byName.values()]\n }\n\n /**\n * Graph edges for #638 Task 2: one `'mv'` edge per registered MV — target\n * = the output collection (a `WHOLE_RECORD` artifact node), sources =\n * every dependency (also `WHOLE_RECORD` nodes). Same-collection edges\n * (`dep === outputCollection`) are skipped IFF the MV declares an\n * `output.partition` discriminator AND the query has a where-clause that\n * provably excludes the partition value (`partitionDisjoint`) — the SAME\n * condition the old local DFS used. Grain comes from the registration-time\n * `RegisteredMV.grain`.\n */\n edges(): ReadonlyArray<{ readonly target: FieldRef; readonly sources: readonly FieldRef[]; readonly kind: EdgeKind; readonly grain: Grain }> {\n const out: Array<{ target: FieldRef; sources: FieldRef[]; kind: EdgeKind; grain: Grain }> = []\n for (const reg of this._byName.values()) {\n const sources: FieldRef[] = []\n for (const dep of reg.dependencies) {\n if (dep === reg.outputCollection && partitionDisjoint(reg)) continue\n sources.push({ collection: dep, field: WHOLE_RECORD })\n }\n if (sources.length === 0) continue\n out.push({ target: { collection: reg.outputCollection, field: WHOLE_RECORD }, sources, kind: 'mv', grain: reg.grain })\n }\n return out\n }\n\n /**\n * Cycle detection, delegated to `ViaGraph.assertAcyclic()` (#638 Task 2 —\n * retires the local DFS). `graph` is the caller's shared per-vault graph,\n * ALREADY carrying this registry's `edges()` AND `DerivationRegistry`'s\n * (registered by the caller — see `Vault._initMaterializedViews`, which\n * runs after `_initDerivations`, so a pure-derivation cycle already threw\n * `DerivationCycleError` there; any cycle surfacing here necessarily\n * touches an MV edge). Throws `MaterializedViewCycleError` — SAME class as\n * before.\n */\n validate(graph: ViaGraph): void {\n graph.assertAcyclic()\n }\n}\n\n/**\n * Type guard: is the clause a top-level `FieldClause` on the given\n * field? Used by the partition-disjoint check.\n *\n * @internal\n */\nfunction isFieldClauseOnField(clause: Clause, field: string): clause is FieldClause {\n return clause.type === 'field' && clause.field === field\n}\n\n/**\n * Wrap an `MVQueryContext` so its `.collection().query()` returns a\n * Query<T> with the MV's declared predicates attached. Bare Queries\n * (outside of any MV) don't gain `.wherePredicate()` — only Queries\n * obtained through this wrapped db do.\n *\n * @internal\n */\nexport function wrapDbWithPredicates(\n db: MVQueryContext,\n predicates: NonNullable<MaterializedViewSpec<Record<string, unknown>>['predicates']>,\n): MVQueryContext {\n // Build the predicate map once — the fn signature in the MV spec\n // is row-typed but the QueryBuilder casts to unknown, so we widen\n // here for the Map.\n const map = new Map<string, DeclaredPredicate>()\n for (const [name, decl] of Object.entries(predicates)) {\n map.set(name, {\n hash: decl.hash,\n fn: decl.fn as (record: unknown, ctx?: unknown) => boolean,\n })\n }\n return {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n collection<T extends Record<string, unknown>>(name: string): any {\n const c = db.collection<T>(name)\n // Return an object that delegates everything to `c` but\n // overrides `.query()` to attach predicates via the new\n // `Query._withPredicates()` accessor.\n return new Proxy(c, {\n get(target, prop, receiver) {\n if (prop === 'query') {\n return (...args: unknown[]) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const q = (target.query as any)(...args)\n // For non-aggregate Query<T>, attach predicates. For\n // legacy predicate-arg overload that returns T[] (sync\n // filter), pass through unchanged.\n \n if (q && typeof q._withPredicates === 'function') {\n return q._withPredicates(map)\n }\n return q\n }\n }\n return Reflect.get(target, prop, receiver)\n },\n })\n },\n }\n}\n\n/**\n * Walk a QueryPlan's clauses and collect predicate-reference markers\n * for `queryHash` derivation. Returns a sorted array (deterministic\n * order) of `{ name, predicateHash, ctxHash }` tuples — these are the\n * hashable identity of each `.wherePredicate()` call site.\n *\n * @internal\n */\nfunction extractPredicateRefs(\n plan: { clauses: readonly Clause[] },\n): Array<{ name: string; predicateHash: string; ctxHash: string }> {\n const refs: Array<{ name: string; predicateHash: string; ctxHash: string }> = []\n const walk = (clauses: readonly Clause[]): void => {\n for (const c of clauses) {\n if (c.type === 'wherePredicate') {\n refs.push({ name: c.name, predicateHash: c.predicateHash, ctxHash: c.ctxHash })\n } else if (c.type === 'group') {\n walk(c.clauses)\n }\n }\n }\n walk(plan.clauses)\n // Stable-sort by (name, predicateHash, ctxHash) — same predicate\n // appearing twice with different ctx hashes both flow through.\n refs.sort((a, b) => {\n if (a.name !== b.name) return a.name < b.name ? -1 : 1\n if (a.predicateHash !== b.predicateHash) return a.predicateHash < b.predicateHash ? -1 : 1\n return a.ctxHash < b.ctxHash ? -1 : a.ctxHash > b.ctxHash ? 1 : 0\n })\n return refs\n}\n\n/**\n * Provability check for the same-collection partition-discriminator.\n * Returns `true` when\n * the captured partition clauses on the MV's query provably exclude\n * the partition's value — meaning the input filter and the output\n * partition are disjoint and the same-collection edge isn't really a\n * cycle.\n *\n * Supported provability shapes (narrow on purpose — DERIV-PP30-001\n * is the load-bearing case):\n *\n * - `.where(field, '==', X)` where X !== partition.value → disjoint\n * - `.where(field, '!=', partition.value)` → disjoint\n * - `.where(field, 'in', [...])` where partition.value NOT in list → disjoint\n *\n * Anything else (no clause on the partition field, an 'in' list that\n * contains partition.value, unsupported operators) → not disjoint,\n * the cycle detector surfaces `MaterializedViewCycleError`.\n *\n * @internal\n */\nfunction partitionDisjoint(reg: RegisteredMV): boolean {\n const partition = reg.spec.output?.partition\n if (partition === undefined) return false\n const value = partition.value\n // The OR-semantics of multiple where-clauses on the same field\n // would muddy this check. v2 only treats AND-chained clauses;\n // any clause that proves disjoint is sufficient.\n for (const c of reg.partitionClauses) {\n if (c.op === '==' && c.value !== value) return true\n if (c.op === '!=' && c.value === value) return true\n if (c.op === 'in' && Array.isArray(c.value)) {\n const list = c.value as readonly unknown[]\n if (!list.includes(value)) return true\n }\n }\n return false\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  BrokerNotEnabledError
3
- } from "./chunk-CWM4GQD2.js";
3
+ } from "./chunk-HKANJAOP.js";
4
4
 
5
5
  // src/port/with/broker-strategy.ts
6
6
  var NO_BROKER = {
@@ -27,4 +27,4 @@ export {
27
27
  NO_BROKER,
28
28
  buildCredentialBrokerHandle
29
29
  };
30
- //# sourceMappingURL=chunk-OIBEJN5H.js.map
30
+ //# sourceMappingURL=chunk-LYQUFIHL.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  NoydbError
3
- } from "./chunk-CWM4GQD2.js";
3
+ } from "./chunk-HKANJAOP.js";
4
4
 
5
5
  // src/kernel/via/index.ts
6
6
  var binders = /* @__PURE__ */ new Map();
@@ -26,4 +26,4 @@ export {
26
26
  isViaInstalled,
27
27
  viaBinder
28
28
  };
29
- //# sourceMappingURL=chunk-JNMTN5D5.js.map
29
+ //# sourceMappingURL=chunk-LZHIYH32.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DerivationCapExceededError,
3
3
  DerivationOutputShapeError
4
- } from "./chunk-CWM4GQD2.js";
4
+ } from "./chunk-HKANJAOP.js";
5
5
 
6
6
  // src/with-formula/derivations/executor.ts
7
7
  var DerivationExecutor = {
@@ -121,4 +121,4 @@ var DerivationExecutor = {
121
121
  export {
122
122
  DerivationExecutor
123
123
  };
124
- //# sourceMappingURL=chunk-7KAE7CQ2.js.map
124
+ //# sourceMappingURL=chunk-M2KVSM43.js.map
@@ -96,4 +96,4 @@ export {
96
96
  evaluateClause,
97
97
  hasFnClause
98
98
  };
99
- //# sourceMappingURL=chunk-IGJCYUT5.js.map
99
+ //# sourceMappingURL=chunk-NSITFOCJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/kernel/query/predicate.ts"],"sourcesContent":["/**\n * Operator implementations for the query DSL.\n *\n * All predicates run client-side, AFTER decryption — they never see ciphertext.\n * Field clauses over a Via-covered field (e.g. money) carry their own\n * evaluator closure (see {@link FieldClause.via}), so this module has no\n * dependency on any Via feature's implementation — still tree-shakeable.\n */\n\n/** Comparison operators supported by the where() builder. */\nexport type Operator =\n | '=='\n | '!='\n | '<'\n | '<='\n | '>'\n | '>='\n | 'in'\n | 'contains'\n | 'startsWith'\n | 'between'\n\n/**\n * A single field comparison clause inside a query plan.\n * Plans are JSON-serializable, so this type uses primitives only.\n */\nexport interface FieldClause {\n readonly type: 'field'\n readonly field: string\n readonly op: Operator\n readonly value: unknown\n /**\n * Present when `field` is covered by a Via feature binding (e.g. a\n * declared money field): the opaque payload built by the binding's\n * `buildClause` at query BUILD time, plus a closure that evaluates it\n * per record via the binding's `evaluateClause`. Attached by\n * `Query.where()` / `ScanBuilder.where()` when `source.via` covers the\n * field. The closure keeps this module free of any dependency on a\n * Via feature's implementation — clauses are in-memory only, never\n * serialized, so carrying a function here is safe.\n */\n readonly via?: {\n readonly brand: string\n readonly payload: unknown\n readonly evaluate: (actual: unknown, op: string) => boolean\n /**\n * The binding's `indexProbe` result for this clause's op/payload\n * (#625) — the STORED-form operand `candidateRecords()` (`kernel/\n * query/builder.ts`) can hand to `CollectionIndexes.lookupEqual`/\n * `lookupIn` for a fast path. `undefined` (no `indexProbe` hook, or\n * the binding declined to probe this op) means the field must fall\n * back to a linear scan via `evaluate` above.\n */\n readonly indexValue?: unknown\n }\n}\n\n/**\n * A user-supplied predicate function escape hatch. Not serializable.\n *\n * The predicate accepts `unknown` at the type level so the surrounding\n * Clause type can stay non-parametric — this keeps Collection<T> covariant\n * in T at the public API surface. Builder methods cast user predicates\n * (typed `(record: T) => boolean`) into this shape on the way in.\n */\nexport interface FilterClause {\n readonly type: 'filter'\n readonly fn: (record: unknown) => boolean\n}\n\n/**\n * A declared deterministic predicate reference. The query\n * builder produces this via `.wherePredicate(name, ctx?)` when a\n * Query has been augmented with a predicates map (typically by the\n * materialized-view registry).\n *\n * `predicateHash` is the consumer-supplied stable hash for the\n * function body; `ctxHash` is the canonical-JSON SHA-256 of `ctx`.\n * Both fold into the MV's `queryHash` so a function or ctx change\n * forces refresh on next visit.\n *\n * `fn` is resolved at builder time from the predicates map and\n * embedded directly — so `evaluateClause` can fire it without a\n * runtime lookup.\n */\nexport interface WherePredicateClause {\n readonly type: 'wherePredicate'\n readonly name: string\n readonly ctx: unknown\n readonly predicateHash: string\n readonly ctxHash: string\n readonly fn: (record: unknown, ctx?: unknown) => boolean\n}\n\n/** A logical group of clauses combined by AND or OR. */\nexport interface GroupClause {\n readonly type: 'group'\n readonly op: 'and' | 'or'\n readonly clauses: readonly Clause[]\n}\n\n/**\n * Cartesian-product expansion clause. Appended to `QueryPlan.clauses`\n * by `Query.crossJoin()`. Processed in declaration order by\n * `executeClausePipeline` — NOT by `evaluateClause` (which is a\n * per-record predicate and throws on this type).\n */\nexport interface CrossJoinClause {\n readonly type: 'crossJoin'\n /** Target collection name to cross-join against. */\n readonly target: string\n /** Alias under which the right-side record is exposed on each result row. */\n readonly as: string\n /**\n * Lateral filter callback. `undefined` → full cartesian product.\n * Two call shapes:\n * - Subset: `(left) => TTarget[]` — returns the right rows for this left row\n * - Predicate: `(left) => (right) => boolean` — executor materializes then filters\n */\n readonly on?: (left: unknown) => unknown[] | ((right: unknown) => boolean)\n /** When `on:` was supplied as `{ predicate: name }`, the name is stored here for queryHash. */\n readonly onPredicateName?: string\n /** Per-clause row ceiling override. `undefined` → `DEFAULT_CROSS_JOIN_MAX_ROWS`. */\n readonly maxRows?: number\n /**\n * Left-outer mode (#1130). When the `on:` subset for a left row is empty,\n * emit that row once with `null` under `as` instead of dropping it.\n *\n * Applies to both call shapes. With `on:` the empty thing is that left\n * row's subset; without it, an empty TARGET collection is what would\n * otherwise drop every left row.\n */\n readonly outer?: boolean\n}\n\nexport type Clause = FieldClause | FilterClause | WherePredicateClause | GroupClause | CrossJoinClause\n\n/**\n * Read a possibly nested field path like \"address.city\" from a record.\n * Returns undefined if any segment is missing.\n */\nexport function readPath(record: unknown, path: string): unknown {\n if (record === null || record === undefined) return undefined\n if (!path.includes('.')) {\n return (record as Record<string, unknown>)[path]\n }\n const segments = path.split('.')\n let cursor: unknown = record\n for (const segment of segments) {\n if (cursor === null || cursor === undefined) return undefined\n cursor = (cursor as Record<string, unknown>)[segment]\n }\n return cursor\n}\n\n/**\n * Evaluate a single field clause against a record.\n * Returns false on type mismatches rather than throwing — query results\n * exclude non-matching records by definition.\n */\nexport function evaluateFieldClause(record: unknown, clause: FieldClause): boolean {\n const actual = readPath(record, clause.field)\n const { op, value } = clause\n\n // A Via-covered field (e.g. money) may store a transformed\n // representation (money: BigInt-exact in scaled-integer space) that the\n // generic paths below can't compare correctly — the operand was\n // pre-built at query BUILD time and the binding's own evaluator knows\n // how to compare it against the raw stored value.\n if (clause.via) return clause.via.evaluate(actual, op)\n\n switch (op) {\n case '==':\n return actual === value\n case '!=':\n return actual !== value\n case '<':\n return isComparable(actual, value) && (actual as number) < (value as number)\n case '<=':\n return isComparable(actual, value) && (actual as number) <= (value as number)\n case '>':\n return isComparable(actual, value) && (actual as number) > (value as number)\n case '>=':\n return isComparable(actual, value) && (actual as number) >= (value as number)\n case 'in':\n return Array.isArray(value) && value.includes(actual)\n case 'contains':\n if (typeof actual === 'string') return typeof value === 'string' && actual.includes(value)\n if (Array.isArray(actual)) return actual.includes(value)\n return false\n case 'startsWith':\n return typeof actual === 'string' && typeof value === 'string' && actual.startsWith(value)\n case 'between': {\n if (!Array.isArray(value) || value.length !== 2) return false\n const [lo, hi] = value\n if (!isComparable(actual, lo) || !isComparable(actual, hi)) return false\n return (actual as number) >= (lo as number) && (actual as number) <= (hi as number)\n }\n default: {\n // Exhaustiveness — TS will error if a new operator is added without a case.\n const _exhaustive: never = op\n void _exhaustive\n return false\n }\n }\n}\n\n/**\n * Two values are \"comparable\" if they share an order-defined runtime type.\n * Strings compare lexicographically; numbers and Dates numerically; otherwise false.\n */\nfunction isComparable(a: unknown, b: unknown): boolean {\n if (typeof a === 'number' && typeof b === 'number') return true\n if (typeof a === 'string' && typeof b === 'string') return true\n if (a instanceof Date && b instanceof Date) return true\n return false\n}\n\n/**\n * Evaluate any clause (field / filter / group) against a record.\n * The recursion depth is bounded by the user's query expression — no risk of\n * blowing the stack on a 50K-record collection.\n *\n * `fnRecord`, when provided, is the view handed to USER CALLBACK clauses\n * (`filter` / `wherePredicate`) instead of `record` — the executor passes\n * the money-decoded view there so user code never sees the stored\n * scaled-int form, while field clauses keep evaluating against the raw\n * record (their money operands are pre-quantized to that space).\n */\nexport function evaluateClause(record: unknown, clause: Clause, fnRecord?: unknown): boolean {\n switch (clause.type) {\n case 'field':\n return evaluateFieldClause(record, clause)\n case 'filter':\n return clause.fn(fnRecord !== undefined ? fnRecord : record)\n case 'wherePredicate':\n return clause.fn(fnRecord !== undefined ? fnRecord : record, clause.ctx)\n case 'crossJoin':\n throw new Error(\n `evaluateClause: 'crossJoin' clauses are expansion primitives and are not ` +\n `evaluated per-record. This is a query planner routing error — ` +\n `crossJoin clauses must be extracted from the clause list before calling ` +\n `evaluateClause or filterRecords.`,\n )\n case 'group':\n if (clause.op === 'and') {\n for (const child of clause.clauses) {\n if (!evaluateClause(record, child, fnRecord)) return false\n }\n return true\n } else {\n for (const child of clause.clauses) {\n if (evaluateClause(record, child, fnRecord)) return true\n }\n return false\n }\n }\n}\n\n/**\n * Does the clause list contain any user-callback clause (filter /\n * wherePredicate), at any group nesting depth? Used by executors to\n * decide whether the per-record decoded view needs materializing.\n */\nexport function hasFnClause(clauses: readonly Clause[]): boolean {\n for (const c of clauses) {\n if (c.type === 'filter' || c.type === 'wherePredicate') return true\n if (c.type === 'group' && hasFnClause(c.clauses)) return true\n }\n return false\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  OverlayIdMismatchError
3
- } from "./chunk-CWM4GQD2.js";
3
+ } from "./chunk-HKANJAOP.js";
4
4
 
5
5
  // src/with-formula/overlay-views/virtual-collection.ts
6
6
  var OverlayedCollection = class {
@@ -206,4 +206,4 @@ var OverlayedCollection = class {
206
206
  export {
207
207
  OverlayedCollection
208
208
  };
209
- //# sourceMappingURL=chunk-32B7VCKU.js.map
209
+ //# sourceMappingURL=chunk-O2A5YCFF.js.map
@@ -7,21 +7,21 @@ import {
7
7
  hashEntry,
8
8
  paddedIndex,
9
9
  sha256Hex
10
- } from "./chunk-ZLHHE5XZ.js";
10
+ } from "./chunk-YLIGPHN4.js";
11
11
  import {
12
12
  buildRecordAad,
13
13
  openEnvelopeJson
14
- } from "./chunk-OHOKBMTM.js";
14
+ } from "./chunk-FUE2KPKM.js";
15
15
  import {
16
16
  buildRecordEnvelope
17
17
  } from "./chunk-PENPHA45.js";
18
18
  import {
19
19
  encrypt
20
- } from "./chunk-AU3AUJIZ.js";
20
+ } from "./chunk-RQQIB7CD.js";
21
21
  import {
22
22
  LedgerContentionError,
23
23
  isConflictError
24
- } from "./chunk-CWM4GQD2.js";
24
+ } from "./chunk-HKANJAOP.js";
25
25
 
26
26
  // src/with-commit/history/ledger/patch.ts
27
27
  function computePatch(prev, next) {
@@ -699,4 +699,4 @@ export {
699
699
  applyPatch,
700
700
  LedgerStore
701
701
  };
702
- //# sourceMappingURL=chunk-4A34KWOU.js.map
702
+ //# sourceMappingURL=chunk-OGB2UTBC.js.map
@@ -2,10 +2,10 @@ import {
2
2
  base64ToBuffer,
3
3
  decryptBytesWithAAD,
4
4
  encryptBytesWithAAD
5
- } from "./chunk-AU3AUJIZ.js";
5
+ } from "./chunk-RQQIB7CD.js";
6
6
  import {
7
7
  TamperedError
8
- } from "./chunk-CWM4GQD2.js";
8
+ } from "./chunk-HKANJAOP.js";
9
9
 
10
10
  // src/kernel/enclave/classify/compare.ts
11
11
  var subtle = globalThis.crypto.subtle;
@@ -92,4 +92,4 @@ export {
92
92
  openVdigPayload,
93
93
  evaluateKofN
94
94
  };
95
- //# sourceMappingURL=chunk-GQXFOAYZ.js.map
95
+ //# sourceMappingURL=chunk-OMXUQAZJ.js.map
@@ -10,14 +10,14 @@ import {
10
10
  verifyPrompt,
11
11
  verifyRoster,
12
12
  verifyTypedEcho
13
- } from "./chunk-CAGI4LLJ.js";
13
+ } from "./chunk-AK6EWGDO.js";
14
14
  import {
15
15
  NoAccessError,
16
16
  NoydbError,
17
17
  ValidationError,
18
18
  WrongEchoError,
19
19
  WrongPromptError
20
- } from "./chunk-CWM4GQD2.js";
20
+ } from "./chunk-HKANJAOP.js";
21
21
 
22
22
  // src/with-party/team/echo-ceremony.ts
23
23
  async function beginEchoUnlock(store, vault, opts) {
@@ -122,4 +122,4 @@ export {
122
122
  MemoryDeviceSealProvider,
123
123
  withTeam
124
124
  };
125
- //# sourceMappingURL=chunk-45YHJ3GV.js.map
125
+ //# sourceMappingURL=chunk-PFHF3A72.js.map
@@ -2,7 +2,7 @@ import {
2
2
  decrypt,
3
3
  deriveSealedFieldKey,
4
4
  deriveSealedFieldKeyFromCek
5
- } from "./chunk-AU3AUJIZ.js";
5
+ } from "./chunk-RQQIB7CD.js";
6
6
 
7
7
  // src/kernel/enclave/record-keys/sealed-slot.ts
8
8
  function parseSealedSlot(blob) {
@@ -26,4 +26,4 @@ export {
26
26
  parseSealedSlot,
27
27
  dualReadSealedSlot
28
28
  };
29
- //# sourceMappingURL=chunk-KV6JM2IA.js.map
29
+ //# sourceMappingURL=chunk-PUGHLCBW.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  PortabilityNotEnabledError
3
- } from "./chunk-CWM4GQD2.js";
3
+ } from "./chunk-HKANJAOP.js";
4
4
 
5
5
  // src/with-audit/portability/strategy.ts
6
6
  var NO_PORTABILITY = {
@@ -27,4 +27,4 @@ var NO_PORTABILITY = {
27
27
  export {
28
28
  NO_PORTABILITY
29
29
  };
30
- //# sourceMappingURL=chunk-ZZXLB6AS.js.map
30
+ //# sourceMappingURL=chunk-R6BGN6IY.js.map
@@ -4,13 +4,13 @@ import {
4
4
  import {
5
5
  base64ToBuffer,
6
6
  bufferToBase64
7
- } from "./chunk-AU3AUJIZ.js";
7
+ } from "./chunk-RQQIB7CD.js";
8
8
  import {
9
9
  SessionExpiredError,
10
10
  SessionNotFoundError,
11
11
  SessionPolicyError,
12
12
  ValidationError
13
- } from "./chunk-CWM4GQD2.js";
13
+ } from "./chunk-HKANJAOP.js";
14
14
 
15
15
  // src/with-party/session/session.ts
16
16
  var subtle = globalThis.crypto.subtle;
@@ -364,4 +364,4 @@ export {
364
364
  clearDevUnlock,
365
365
  isDevUnlockActive
366
366
  };
367
- //# sourceMappingURL=chunk-CLAHBPOI.js.map
367
+ //# sourceMappingURL=chunk-RBBTJ2HY.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  ViaGraph
3
- } from "./chunk-RSXQNFGO.js";
3
+ } from "./chunk-ATSIGJRX.js";
4
4
  import {
5
5
  sha256Hex
6
- } from "./chunk-AU3AUJIZ.js";
6
+ } from "./chunk-RQQIB7CD.js";
7
7
  import {
8
8
  DerivationCycleError,
9
9
  DuplicateBehaviorNameError
10
- } from "./chunk-CWM4GQD2.js";
10
+ } from "./chunk-HKANJAOP.js";
11
11
 
12
12
  // src/with-formula/derivations/strategy-hash.ts
13
13
  async function computeStrategyHash(source, outputKeys, derive, sources) {
@@ -172,4 +172,4 @@ var DerivationRegistry = class {
172
172
  export {
173
173
  DerivationRegistry
174
174
  };
175
- //# sourceMappingURL=chunk-YKXZHUOW.js.map
175
+ //# sourceMappingURL=chunk-RGUAY5IX.js.map
@@ -3,7 +3,7 @@ import {
3
3
  InvalidKeyError,
4
4
  TamperedError,
5
5
  ValidationError
6
- } from "./chunk-CWM4GQD2.js";
6
+ } from "./chunk-HKANJAOP.js";
7
7
 
8
8
  // src/kernel/enclave/crypto.ts
9
9
  var PBKDF2_ITERATIONS = 6e5;
@@ -439,4 +439,4 @@ export {
439
439
  bufferToBase64,
440
440
  base64ToBuffer
441
441
  };
442
- //# sourceMappingURL=chunk-AU3AUJIZ.js.map
442
+ //# sourceMappingURL=chunk-RQQIB7CD.js.map
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  PolicyDeniedError,
7
7
  ValidationError
8
- } from "./chunk-CWM4GQD2.js";
8
+ } from "./chunk-HKANJAOP.js";
9
9
 
10
10
  // src/with-party/policy/presets.ts
11
11
  var PERSONAL_POLICY = Object.freeze({
@@ -364,4 +364,4 @@ export {
364
364
  describeGate,
365
365
  createNoydbPolicy
366
366
  };
367
- //# sourceMappingURL=chunk-TX5MKAHA.js.map
367
+ //# sourceMappingURL=chunk-RTKREHPV.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  SCHEMAS_COLLECTION
3
- } from "./chunk-6WO62AJW.js";
3
+ } from "./chunk-SZFNO7L4.js";
4
4
  import {
5
5
  assemblePodContainer,
6
6
  buildExtractedPartitionWrapper
7
- } from "./chunk-QSIEL6TL.js";
7
+ } from "./chunk-XXONVJWA.js";
8
8
  import {
9
9
  BLOB_CHUNKS_COLLECTION,
10
10
  BLOB_COLLECTION,
@@ -12,7 +12,7 @@ import {
12
12
  BLOB_INTENT_COLLECTION,
13
13
  BLOB_SLOTS_PREFIX,
14
14
  BLOB_VERSIONS_PREFIX
15
- } from "./chunk-JLYQQNY4.js";
15
+ } from "./chunk-BYX3AUXH.js";
16
16
  import {
17
17
  generateULID
18
18
  } from "./chunk-4AOERLTV.js";
@@ -23,13 +23,13 @@ import {
23
23
  canonicalJson,
24
24
  envelopePayloadHash,
25
25
  hashEntry
26
- } from "./chunk-ZLHHE5XZ.js";
26
+ } from "./chunk-YLIGPHN4.js";
27
27
  import {
28
28
  buildRecordAad,
29
29
  openEnvelopeJson,
30
30
  recordAadFor,
31
31
  writeEnvelopeBody
32
- } from "./chunk-OHOKBMTM.js";
32
+ } from "./chunk-FUE2KPKM.js";
33
33
  import {
34
34
  buildRecordEnvelope
35
35
  } from "./chunk-PENPHA45.js";
@@ -42,13 +42,13 @@ import {
42
42
  generateDEK,
43
43
  unwrapCek,
44
44
  wrapCek
45
- } from "./chunk-AU3AUJIZ.js";
45
+ } from "./chunk-RQQIB7CD.js";
46
46
  import {
47
47
  NOYDB_BACKUP_VERSION
48
48
  } from "./chunk-IGNJOJEP.js";
49
49
  import {
50
50
  PartitionExtractionError
51
- } from "./chunk-CWM4GQD2.js";
51
+ } from "./chunk-HKANJAOP.js";
52
52
 
53
53
  // src/with-cargo/walk-closure.ts
54
54
  async function walkClosure(vault, opts) {
@@ -494,4 +494,4 @@ export {
494
494
  extractPartition,
495
495
  extractPartitionCore
496
496
  };
497
- //# sourceMappingURL=chunk-BAHOV5I5.js.map
497
+ //# sourceMappingURL=chunk-SIACMXFK.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  buildRecordAad,
3
3
  openEnvelopeJson
4
- } from "./chunk-OHOKBMTM.js";
4
+ } from "./chunk-FUE2KPKM.js";
5
5
  import {
6
6
  buildRecordEnvelope
7
7
  } from "./chunk-PENPHA45.js";
8
8
  import {
9
9
  encrypt
10
- } from "./chunk-AU3AUJIZ.js";
10
+ } from "./chunk-RQQIB7CD.js";
11
11
 
12
12
  // src/with-shape/persisted-schemas/storage.ts
13
13
  var SCHEMAS_COLLECTION = "_schemas";
@@ -45,4 +45,4 @@ export {
45
45
  loadPersistedSchema,
46
46
  savePersistedSchema
47
47
  };
48
- //# sourceMappingURL=chunk-6WO62AJW.js.map
48
+ //# sourceMappingURL=chunk-SZFNO7L4.js.map
@@ -1,18 +1,22 @@
1
+ import {
2
+ BLOB_CHUNKS_COLLECTION,
3
+ BLOB_INDEX_COLLECTION
4
+ } from "./chunk-BYX3AUXH.js";
1
5
  import {
2
6
  installViaBinder
3
- } from "./chunk-JNMTN5D5.js";
7
+ } from "./chunk-LZHIYH32.js";
4
8
  import {
5
9
  buildRecordAad
6
- } from "./chunk-OHOKBMTM.js";
10
+ } from "./chunk-FUE2KPKM.js";
7
11
  import {
8
12
  buildRecordEnvelope
9
13
  } from "./chunk-PENPHA45.js";
10
14
  import {
11
15
  encrypt
12
- } from "./chunk-AU3AUJIZ.js";
16
+ } from "./chunk-RQQIB7CD.js";
13
17
  import {
14
18
  ValidationError
15
- } from "./chunk-CWM4GQD2.js";
19
+ } from "./chunk-HKANJAOP.js";
16
20
 
17
21
  // src/via/blob/binding.ts
18
22
  async function eraseBlobs(ctx, cfg) {
@@ -167,9 +171,50 @@ function generateBatchId() {
167
171
  return `batch-${Date.now().toString(36)}-${s.slice(0, 12)}`;
168
172
  }
169
173
 
174
+ // src/with-shape/blobs/orphan-report.ts
175
+ var SAMPLE_LIMIT = 10;
176
+ function parseChunkId(id) {
177
+ const cut = id.lastIndexOf("_");
178
+ if (cut <= 0 || cut === id.length - 1) return null;
179
+ const suffix = id.slice(cut + 1);
180
+ if (!/^\d+$/.test(suffix)) return null;
181
+ return { eTag: id.slice(0, cut), index: Number(suffix) };
182
+ }
183
+ async function reportOrphanBlobChunks(adapter, vault) {
184
+ const empty = { chunks: 0, eTags: 0, sampleETags: [], unparseable: 0 };
185
+ let liveETags;
186
+ let chunkIds;
187
+ try {
188
+ liveETags = new Set(await adapter.list(vault, BLOB_INDEX_COLLECTION));
189
+ chunkIds = await adapter.list(vault, BLOB_CHUNKS_COLLECTION);
190
+ } catch {
191
+ return empty;
192
+ }
193
+ let chunks = 0;
194
+ let unparseable = 0;
195
+ const orphanETags = /* @__PURE__ */ new Set();
196
+ for (const id of chunkIds) {
197
+ const parsed = parseChunkId(id);
198
+ if (parsed === null) {
199
+ unparseable += 1;
200
+ continue;
201
+ }
202
+ if (liveETags.has(parsed.eTag)) continue;
203
+ chunks += 1;
204
+ orphanETags.add(parsed.eTag);
205
+ }
206
+ return {
207
+ chunks,
208
+ eTags: orphanETags.size,
209
+ sampleETags: [...orphanETags].slice(0, SAMPLE_LIMIT),
210
+ unparseable
211
+ };
212
+ }
213
+
170
214
  // src/with-shape/blobs/blob-compaction.ts
171
215
  var BLOB_EVICTION_AUDIT_COLLECTION = "_blob_eviction_audit";
172
216
  async function runCompaction(ctx, options = {}) {
217
+ const orphanBlobChunks = await reportOrphanBlobChunks(ctx.adapter, ctx.vault);
173
218
  const now = options.now ?? /* @__PURE__ */ new Date();
174
219
  const maxEvictions = options.maxEvictions ?? Infinity;
175
220
  const dryRun = options.dryRun === true;
@@ -254,7 +299,8 @@ async function runCompaction(ctx, options = {}) {
254
299
  pinned,
255
300
  budgetEvicted,
256
301
  budgetBytesFreed,
257
- byCollection
302
+ byCollection,
303
+ orphanBlobChunks
258
304
  };
259
305
  }
260
306
  async function runBudgetPass(ctx, maxBytes, opts) {
@@ -388,7 +434,8 @@ export {
388
434
  ExportBlobsAbortedError,
389
435
  EXPORT_AUDIT_COLLECTION,
390
436
  createExportBlobsHandle,
437
+ reportOrphanBlobChunks,
391
438
  BLOB_EVICTION_AUDIT_COLLECTION,
392
439
  runCompaction
393
440
  };
394
- //# sourceMappingURL=chunk-4OQZNXQG.js.map
441
+ //# sourceMappingURL=chunk-TA67ZQUH.js.map