@noy-db/hub 0.7.1-pre.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +147 -14
- package/LICENSE +202 -21
- package/NOTICE +1 -0
- package/README.md +5 -5
- package/codemods/0.8.0-pre.json +61 -0
- package/dist/api-OS747DS4.js +18 -0
- package/dist/as/index.js +11 -12
- package/dist/as/index.js.map +1 -1
- package/dist/at/index.js +9 -10
- package/dist/attestation/index.js +37 -26
- package/dist/attestation/index.js.map +1 -1
- package/dist/{backup-XKCXVKV3.js → backup-YE2VQ26S.js} +15 -16
- package/dist/backup-YE2VQ26S.js.map +1 -0
- package/dist/blobs/index.js +13 -14
- package/dist/blobs/index.js.map +1 -1
- package/dist/broker/index.js +12 -13
- package/dist/broker/index.js.map +1 -1
- package/dist/by/index.js +2 -2
- package/dist/capsule/contract.d.ts +159 -0
- package/dist/capsule/contract.js +95 -0
- package/dist/capsule/enclave-aes/bound.d.ts +52 -0
- package/dist/capsule/enclave-aes/capabilities.d.ts +2 -0
- package/dist/capsule/enclave-aes/classify/compare.d.ts +20 -0
- package/dist/{kernel/enclave → capsule/enclave-aes}/classify/find.d.ts +1 -1
- package/dist/{kernel/enclave → capsule/enclave-aes}/classify/reveal.d.ts +1 -1
- package/dist/{kernel/enclave → capsule/enclave-aes}/classify/verify.d.ts +2 -2
- package/dist/{kernel/enclave → capsule/enclave-aes}/classify/write.d.ts +1 -1
- package/dist/{kernel/enclave → capsule/enclave-aes}/crypto.d.ts +33 -129
- package/dist/capsule/enclave-aes/index.d.ts +113 -0
- package/dist/capsule/enclave-aes/index.js +335 -0
- package/dist/capsule/enclave-aes/index.js.map +1 -0
- package/dist/capsule/enclave-aes/primitives.d.ts +29 -0
- package/dist/capsule/index.d.ts +27 -0
- package/dist/capsule/plumbing/ct-equal.d.ts +11 -0
- package/dist/{kernel/enclave/record-keys → capsule/plumbing}/deterministic.d.ts +8 -21
- package/dist/capsule/plumbing/digest.d.ts +122 -0
- package/dist/{kernel/enclave/record-keys → capsule/plumbing}/envelope-body.d.ts +44 -48
- package/dist/capsule/plumbing/index.d.ts +100 -0
- package/dist/capsule/plumbing/lifecycle.d.ts +50 -0
- package/dist/{kernel/enclave/record-keys → capsule/plumbing}/record-codec.d.ts +80 -20
- package/dist/{kernel/enclave → capsule/plumbing}/record-envelope.d.ts +1 -1
- package/dist/capsule/plumbing/rekey-blob.d.ts +33 -0
- package/dist/capsule/plumbing/rekey.d.ts +44 -0
- package/dist/capsule/plumbing/sealed-slot.d.ts +22 -0
- package/dist/capsule/plumbing/sealed-slots.d.ts +37 -0
- package/dist/capsule/plumbing/sealing.d.ts +29 -0
- package/dist/capsule/plumbing/sign.d.ts +9 -0
- package/dist/{kernel/enclave/record-keys → capsule/plumbing}/tombstone.d.ts +2 -2
- package/dist/capsule-VOLX3QRQ.js +209 -0
- package/dist/cargo/index.js +39 -36
- package/dist/{chunk-Q2MPFCQ7.js → chunk-23D6M6VM.js} +5 -5
- package/dist/chunk-23D6M6VM.js.map +1 -0
- package/dist/{chunk-R7BX2NB3.js → chunk-244QBK7Z.js} +4 -4
- package/dist/chunk-244QBK7Z.js.map +1 -0
- package/dist/chunk-2AFX33YA.js +936 -0
- package/dist/chunk-2AFX33YA.js.map +1 -0
- package/dist/{chunk-MVMXZYXT.js → chunk-2GHDLTPE.js} +2 -2
- package/dist/{chunk-GYGLAVCX.js → chunk-2MG3SW7Q.js} +6 -2
- package/dist/chunk-2MG3SW7Q.js.map +1 -0
- package/dist/{chunk-XLMEZIAJ.js → chunk-2ODVB6LZ.js} +2 -2
- package/dist/{chunk-HJUWN7JN.js → chunk-2PVXF5CS.js} +33 -8
- package/dist/chunk-2PVXF5CS.js.map +1 -0
- package/dist/{chunk-YJRT5UQM.js → chunk-2RH777HH.js} +21 -20
- package/dist/{chunk-YJRT5UQM.js.map → chunk-2RH777HH.js.map} +1 -1
- package/dist/{chunk-7O3Y4PPD.js → chunk-37EPTBBR.js} +153 -16
- package/dist/chunk-37EPTBBR.js.map +1 -0
- package/dist/{chunk-2ENE6445.js → chunk-3A5DUZ56.js} +102 -16
- package/dist/chunk-3A5DUZ56.js.map +1 -0
- package/dist/chunk-3EWS67C7.js +461 -0
- package/dist/chunk-3EWS67C7.js.map +1 -0
- package/dist/{chunk-SGZAIJCV.js → chunk-3L2NBKDR.js} +4 -8
- package/dist/chunk-3L2NBKDR.js.map +1 -0
- package/dist/{chunk-YMUFFJCO.js → chunk-3TDUWVWB.js} +5 -2
- package/dist/chunk-3TDUWVWB.js.map +1 -0
- package/dist/{chunk-4GVM6QZA.js → chunk-3XJQBBZD.js} +26 -28
- package/dist/chunk-3XJQBBZD.js.map +1 -0
- package/dist/{chunk-4ZS56W5S.js → chunk-42ALPZ2B.js} +672 -664
- package/dist/chunk-42ALPZ2B.js.map +1 -0
- package/dist/chunk-4CIQDWRB.js +524 -0
- package/dist/chunk-4CIQDWRB.js.map +1 -0
- package/dist/{chunk-RMS3NEA3.js → chunk-4JPMZTJY.js} +2 -2
- package/dist/{chunk-P3MG6QCN.js → chunk-4T3SE27M.js} +5 -9
- package/dist/chunk-4T3SE27M.js.map +1 -0
- package/dist/chunk-4V3Q35WG.js +204 -0
- package/dist/chunk-4V3Q35WG.js.map +1 -0
- package/dist/{chunk-NQKIUNW5.js → chunk-52MGURXO.js} +2 -2
- package/dist/{chunk-EQEYOJBM.js → chunk-5A4345TG.js} +4 -4
- package/dist/chunk-5A4345TG.js.map +1 -0
- package/dist/{chunk-334WSVOW.js → chunk-5FE75J4S.js} +6 -6
- package/dist/chunk-5FE75J4S.js.map +1 -0
- package/dist/chunk-5KC7QYEC.js +565 -0
- package/dist/chunk-5KC7QYEC.js.map +1 -0
- package/dist/{chunk-RSGLUIO6.js → chunk-5UMK7GRI.js} +13 -12
- package/dist/chunk-5UMK7GRI.js.map +1 -0
- package/dist/chunk-5WWDGFOS.js +275 -0
- package/dist/chunk-5WWDGFOS.js.map +1 -0
- package/dist/{chunk-QPQUVOZ2.js → chunk-6QVKPHBF.js} +3 -5
- package/dist/chunk-6QVKPHBF.js.map +1 -0
- package/dist/{chunk-ACAQ2DSG.js → chunk-747G6CT3.js} +2 -2
- package/dist/chunk-747G6CT3.js.map +1 -0
- package/dist/{chunk-QTQUH4DS.js → chunk-7R2Q7CPL.js} +16 -16
- package/dist/chunk-7R2Q7CPL.js.map +1 -0
- package/dist/{chunk-UGTBXF5U.js → chunk-7XMHMVTS.js} +3 -3
- package/dist/{chunk-YJX7EOJD.js → chunk-A4XMIZT3.js} +6 -6
- package/dist/{chunk-YJX7EOJD.js.map → chunk-A4XMIZT3.js.map} +1 -1
- package/dist/{chunk-A66I4JOA.js → chunk-AEQGFRU4.js} +4 -4
- package/dist/chunk-AEQGFRU4.js.map +1 -0
- package/dist/chunk-AL6ML4LA.js +1558 -0
- package/dist/chunk-AL6ML4LA.js.map +1 -0
- package/dist/{chunk-BZ3534YM.js → chunk-AUKKUPVB.js} +2 -2
- package/dist/{chunk-CUZLNGD5.js → chunk-B2YY6WDD.js} +1 -1
- package/dist/chunk-B2YY6WDD.js.map +1 -0
- package/dist/chunk-BKT776R5.js +1 -0
- package/dist/chunk-BNWA3WG5.js +22 -0
- package/dist/chunk-BNWA3WG5.js.map +1 -0
- package/dist/{chunk-VXANTWBJ.js → chunk-BPWYQ25R.js} +92 -6
- package/dist/{chunk-VXANTWBJ.js.map → chunk-BPWYQ25R.js.map} +1 -1
- package/dist/{chunk-6LKOJBV6.js → chunk-BVCUTXE3.js} +2 -2
- package/dist/chunk-CY2CYVWZ.js +41 -0
- package/dist/chunk-CY2CYVWZ.js.map +1 -0
- package/dist/{chunk-M4YPHYEH.js → chunk-DHHGL42E.js} +70 -25
- package/dist/chunk-DHHGL42E.js.map +1 -0
- package/dist/{chunk-VTFVLCUH.js → chunk-DIZLQVAA.js} +2 -2
- package/dist/{chunk-G73UVHCA.js → chunk-DLD5LGDS.js} +11 -12
- package/dist/chunk-DLD5LGDS.js.map +1 -0
- package/dist/{chunk-WQBG4SZS.js → chunk-DQESF6RP.js} +60 -49
- package/dist/chunk-DQESF6RP.js.map +1 -0
- package/dist/{chunk-LWBCUYZW.js → chunk-E2N2T5ZO.js} +2 -2
- package/dist/{chunk-3PGS7TYR.js → chunk-EGVJ7TM4.js} +29 -32
- package/dist/chunk-EGVJ7TM4.js.map +1 -0
- package/dist/{chunk-JVIBCBC7.js → chunk-EJLV62NI.js} +2 -2
- package/dist/{chunk-KKEESNPE.js → chunk-EYG2CY2X.js} +126 -19
- package/dist/chunk-EYG2CY2X.js.map +1 -0
- package/dist/{enclave-55PAM4YO.js → chunk-EZGV6F47.js} +83 -56
- package/dist/chunk-EZGV6F47.js.map +1 -0
- package/dist/{chunk-CHQCZZWC.js → chunk-EZOAKKTB.js} +36 -27
- package/dist/chunk-EZOAKKTB.js.map +1 -0
- package/dist/chunk-F6NCB7KT.js +13 -0
- package/dist/chunk-F6NCB7KT.js.map +1 -0
- package/dist/chunk-FFJFE4T7.js +100 -0
- package/dist/chunk-FFJFE4T7.js.map +1 -0
- package/dist/{chunk-JMGDHKQF.js → chunk-FLPCETP6.js} +2 -2
- package/dist/chunk-FOEDQATO.js +53 -0
- package/dist/chunk-FOEDQATO.js.map +1 -0
- package/dist/{chunk-DGOZ4UZD.js → chunk-FVH5QYY2.js} +2 -2
- package/dist/{chunk-HIWCKBEY.js → chunk-G2MVBDFP.js} +54 -28
- package/dist/chunk-G2MVBDFP.js.map +1 -0
- package/dist/chunk-GMKGGY7V.js +234 -0
- package/dist/chunk-GMKGGY7V.js.map +1 -0
- package/dist/{chunk-EIPVYUEP.js → chunk-GQ4MF3CM.js} +3 -3
- package/dist/chunk-GQ4MF3CM.js.map +1 -0
- package/dist/{chunk-PEOZ34EM.js → chunk-GSAK56VF.js} +1 -1
- package/dist/chunk-GSAK56VF.js.map +1 -0
- package/dist/{chunk-5VCRVKOZ.js → chunk-GUZET4SG.js} +12 -4
- package/dist/chunk-GUZET4SG.js.map +1 -0
- package/dist/{chunk-JBDFMYKQ.js → chunk-GZT3NQRA.js} +2 -2
- package/dist/{chunk-K23VKTN4.js → chunk-H23XHRTT.js} +19 -34
- package/dist/chunk-H23XHRTT.js.map +1 -0
- package/dist/{chunk-TFR7DSOV.js → chunk-H427H63K.js} +2 -2
- package/dist/{chunk-DFMWUOU5.js → chunk-H7JBY4P7.js} +23 -32
- package/dist/chunk-H7JBY4P7.js.map +1 -0
- package/dist/{chunk-SKGMN35F.js → chunk-HS554XAF.js} +3 -3
- package/dist/chunk-HS554XAF.js.map +1 -0
- package/dist/{chunk-HK67PX4J.js → chunk-HW7CMKUG.js} +1 -1
- package/dist/chunk-HW7CMKUG.js.map +1 -0
- package/dist/{chunk-3BVH633C.js → chunk-IMQKWR46.js} +5 -7
- package/dist/chunk-IMQKWR46.js.map +1 -0
- package/dist/{chunk-R42NSZI6.js → chunk-IUBMZPHM.js} +7 -7
- package/dist/chunk-IUBMZPHM.js.map +1 -0
- package/dist/{chunk-CUQPWYRX.js → chunk-IUT3GWP3.js} +75 -386
- package/dist/chunk-IUT3GWP3.js.map +1 -0
- package/dist/{chunk-RF6D3Y5E.js → chunk-JDEYF3PJ.js} +4 -8
- package/dist/{chunk-RF6D3Y5E.js.map → chunk-JDEYF3PJ.js.map} +1 -1
- package/dist/{chunk-PPTHY5QO.js → chunk-JIBUPZHA.js} +99 -8
- package/dist/chunk-JIBUPZHA.js.map +1 -0
- package/dist/{chunk-SMH6SRX7.js → chunk-JOSPH3E5.js} +2 -2
- package/dist/chunk-JQYKPKG6.js +193 -0
- package/dist/chunk-JQYKPKG6.js.map +1 -0
- package/dist/{chunk-7APJ6CO6.js → chunk-JSMTXZR3.js} +45 -13
- package/dist/chunk-JSMTXZR3.js.map +1 -0
- package/dist/chunk-JWWYRR4Q.js +12 -0
- package/dist/chunk-JWWYRR4Q.js.map +1 -0
- package/dist/{chunk-BVN6KXL2.js → chunk-KZXDLBY6.js} +14 -9
- package/dist/chunk-KZXDLBY6.js.map +1 -0
- package/dist/chunk-LGNDFRYC.js +23 -0
- package/dist/chunk-LGNDFRYC.js.map +1 -0
- package/dist/{chunk-XKWGNJ26.js → chunk-LIOVX5TJ.js} +7 -11
- package/dist/chunk-LIOVX5TJ.js.map +1 -0
- package/dist/{chunk-AYX7AINO.js → chunk-LNSVGRHO.js} +5 -7
- package/dist/chunk-LNSVGRHO.js.map +1 -0
- package/dist/chunk-M5B2W6YY.js +293 -0
- package/dist/chunk-M5B2W6YY.js.map +1 -0
- package/dist/chunk-MBMTND6D.js +456 -0
- package/dist/chunk-MBMTND6D.js.map +1 -0
- package/dist/{chunk-3BZZJJMQ.js → chunk-MILI22XQ.js} +3 -3
- package/dist/{chunk-A2HKRLPV.js → chunk-MXKI4ABF.js} +18 -59
- package/dist/chunk-MXKI4ABF.js.map +1 -0
- package/dist/{chunk-ZYIYHJ5R.js → chunk-MXOQ5JCG.js} +869 -238
- package/dist/chunk-MXOQ5JCG.js.map +1 -0
- package/dist/{chunk-V7ZRRCRJ.js → chunk-N7EVQD5S.js} +9 -13
- package/dist/chunk-N7EVQD5S.js.map +1 -0
- package/dist/chunk-N7UDP5VU.js +757 -0
- package/dist/chunk-N7UDP5VU.js.map +1 -0
- package/dist/chunk-NBQ3KK6X.js +270 -0
- package/dist/chunk-NBQ3KK6X.js.map +1 -0
- package/dist/{chunk-ZORTV6NH.js → chunk-NCO25JZO.js} +88 -4
- package/dist/chunk-NCO25JZO.js.map +1 -0
- package/dist/chunk-NH2UOV3B.js +18 -0
- package/dist/chunk-NH2UOV3B.js.map +1 -0
- package/dist/chunk-NYMLINRP.js +28 -0
- package/dist/chunk-NYMLINRP.js.map +1 -0
- package/dist/{chunk-YYP7WSEB.js → chunk-O2IMQSNA.js} +2 -2
- package/dist/chunk-O46CHQT7.js +215 -0
- package/dist/chunk-O46CHQT7.js.map +1 -0
- package/dist/chunk-OIEO4WDL.js +27 -0
- package/dist/chunk-OIEO4WDL.js.map +1 -0
- package/dist/{chunk-TRGTKX5E.js → chunk-OKSTSITU.js} +27 -4
- package/dist/chunk-OKSTSITU.js.map +1 -0
- package/dist/chunk-OYW3I5M4.js +31 -0
- package/dist/chunk-OYW3I5M4.js.map +1 -0
- package/dist/{chunk-Q7HZX3IF.js → chunk-PD64727P.js} +2 -2
- package/dist/chunk-PD64727P.js.map +1 -0
- package/dist/{chunk-FET5XCAT.js → chunk-PP3K67AJ.js} +34 -6
- package/dist/chunk-PP3K67AJ.js.map +1 -0
- package/dist/chunk-Q2XRFWOI.js +40 -0
- package/dist/chunk-Q2XRFWOI.js.map +1 -0
- package/dist/{chunk-QIZPZMUI.js → chunk-Q4UHJ5SN.js} +2 -2
- package/dist/{chunk-FAHMLERK.js → chunk-QBLT6POL.js} +2 -2
- package/dist/chunk-QMWY2FDS.js +157 -0
- package/dist/chunk-QMWY2FDS.js.map +1 -0
- package/dist/{chunk-LH5A3ZPG.js → chunk-RB4DOPGZ.js} +150 -22
- package/dist/chunk-RB4DOPGZ.js.map +1 -0
- package/dist/chunk-RHVMZSUU.js +7 -0
- package/dist/chunk-RHVMZSUU.js.map +1 -0
- package/dist/{chunk-BUE2D7PX.js → chunk-SMV2HRDU.js} +2 -2
- package/dist/chunk-SUZKW6UR.js +25 -0
- package/dist/chunk-SUZKW6UR.js.map +1 -0
- package/dist/{chunk-7MG7SJT7.js → chunk-SV2PM2OY.js} +1 -1
- package/dist/chunk-SV2PM2OY.js.map +1 -0
- package/dist/{chunk-UXVWEX5L.js → chunk-SYNY3VB5.js} +6 -2
- package/dist/chunk-SYNY3VB5.js.map +1 -0
- package/dist/{chunk-4GFX6MPA.js → chunk-TEHHROZL.js} +6 -8
- package/dist/chunk-TEHHROZL.js.map +1 -0
- package/dist/chunk-TKVUE4JF.js +1289 -0
- package/dist/chunk-TKVUE4JF.js.map +1 -0
- package/dist/{chunk-SFAWCTEM.js → chunk-TZZBXPZK.js} +2 -2
- package/dist/{chunk-F3W6YMDC.js → chunk-U2FZNEWJ.js} +4 -4
- package/dist/chunk-U2FZNEWJ.js.map +1 -0
- package/dist/{chunk-BLN54W3L.js → chunk-UA372JHH.js} +56 -3
- package/dist/chunk-UA372JHH.js.map +1 -0
- package/dist/{chunk-6YXCPL4T.js → chunk-UEFOQH74.js} +2 -2
- package/dist/chunk-UEFOQH74.js.map +1 -0
- package/dist/{chunk-2N5ML6HT.js → chunk-UIYESRD6.js} +9 -11
- package/dist/chunk-UIYESRD6.js.map +1 -0
- package/dist/{chunk-UHHPLO3I.js → chunk-V3RWOOSO.js} +4 -4
- package/dist/{chunk-KTFRCC5C.js → chunk-V7ADQF5O.js} +82 -8
- package/dist/chunk-V7ADQF5O.js.map +1 -0
- package/dist/{chunk-453F654R.js → chunk-VAORSCSU.js} +3 -3
- package/dist/chunk-VAORSCSU.js.map +1 -0
- package/dist/{chunk-GPNTB4Y7.js → chunk-VFHCKG5M.js} +6 -10
- package/dist/chunk-VFHCKG5M.js.map +1 -0
- package/dist/{chunk-2577DKXB.js → chunk-VHBKYN2J.js} +3 -3
- package/dist/chunk-VHBKYN2J.js.map +1 -0
- package/dist/chunk-VHM7HCKB.js +220 -0
- package/dist/chunk-VHM7HCKB.js.map +1 -0
- package/dist/{chunk-ZHKOPKE3.js → chunk-VKI2EB3N.js} +3 -3
- package/dist/chunk-VKI2EB3N.js.map +1 -0
- package/dist/{chunk-UDHWDSRL.js → chunk-VMV5SBE4.js} +16 -17
- package/dist/chunk-VMV5SBE4.js.map +1 -0
- package/dist/{chunk-SPYWXKJN.js → chunk-VQDZYB2B.js} +3 -3
- package/dist/chunk-VQDZYB2B.js.map +1 -0
- package/dist/{chunk-Q2PU57HC.js → chunk-VVOLDVIR.js} +2 -2
- package/dist/{chunk-3VF3WQ4F.js → chunk-WPOYWFSE.js} +7 -7
- package/dist/{chunk-3VF3WQ4F.js.map → chunk-WPOYWFSE.js.map} +1 -1
- package/dist/{chunk-OTQZ7ZWU.js → chunk-WXE4W2U6.js} +7 -11
- package/dist/chunk-WXE4W2U6.js.map +1 -0
- package/dist/chunk-XBKH4FOC.js +195 -0
- package/dist/chunk-XBKH4FOC.js.map +1 -0
- package/dist/{chunk-TUFM4UZP.js → chunk-XQRFSKYM.js} +2 -2
- package/dist/{chunk-3V4KWFX7.js → chunk-XSPFDUDG.js} +58 -53
- package/dist/chunk-XSPFDUDG.js.map +1 -0
- package/dist/{chunk-GY4WYNNG.js → chunk-Y2RKVFKR.js} +2 -2
- package/dist/{chunk-UP4BECPY.js → chunk-Y3LPTBG7.js} +89 -27
- package/dist/chunk-Y3LPTBG7.js.map +1 -0
- package/dist/{chunk-4OZNXTO4.js → chunk-YRXFFWG4.js} +2 -2
- package/dist/classified/index.js +5 -5
- package/dist/{classified-marker-BWOFVYAC.js → classified-marker-SIYKUU5L.js} +3 -3
- package/dist/classified-marker-SIYKUU5L.js.map +1 -0
- package/dist/collection-facade-CS7CA2XO.js +47 -0
- package/dist/{computed-VPOKQK4N.js → computed-FAD7SED4.js} +3 -3
- package/dist/consent/index.js +10 -11
- package/dist/consent/index.js.map +1 -1
- package/dist/cover/index.js +10 -11
- package/dist/coverage/index.js +306 -0
- package/dist/coverage/index.js.map +1 -0
- package/dist/custody/index.js +12 -13
- package/dist/{dead-filter-PKQDLOT4.js → dead-filter-4F3LWYKH.js} +11 -3
- package/dist/dead-filter-4F3LWYKH.js.map +1 -0
- package/dist/debug/index.js +11 -2
- package/dist/debug/index.js.map +1 -1
- package/dist/{delegation-DS5NRILW.js → delegation-NANZDG4N.js} +13 -16
- package/dist/delegation-NANZDG4N.js.map +1 -0
- package/dist/derivations/index.js +25 -23
- package/dist/derive-XLOJVXPU.js +20 -0
- package/dist/directory/index.js +10 -11
- package/dist/{dispatch-IEPAVQUM.js → dispatch-H4HV32AM.js} +5 -5
- package/dist/{dispatch-Q6MWLOJY.js → dispatch-JDZNGEB3.js} +20 -21
- package/dist/dispatch-JDZNGEB3.js.map +1 -0
- package/dist/executor-FMPVN6DT.js +35 -0
- package/dist/executor-LBBBRTN5.js +8 -0
- package/dist/executor-OSRZST2U.js +8 -0
- package/dist/export-accessible-RAOJAAU5.js +22 -0
- package/dist/extract-partition-JD5CUSTG.js +37 -0
- package/dist/{fanout-sidecar-S3QL53YX.js → fanout-sidecar-L7NHPIOC.js} +13 -15
- package/dist/fanout-sidecar-L7NHPIOC.js.map +1 -0
- package/dist/find-JRN4RNQ5.js +10 -0
- package/dist/forget/index.js +9 -10
- package/dist/forget/index.js.map +1 -1
- package/dist/guards/index.js +4 -4
- package/dist/history/index.js +13 -14
- package/dist/history/index.js.map +1 -1
- package/dist/i18n/index.js +14 -15
- package/dist/i18n/index.js.map +1 -1
- package/dist/index.d.ts +36 -14
- package/dist/index.js +970 -163
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +13 -5
- package/dist/indexing/index.js.map +1 -1
- package/dist/introspection/index.js +11 -12
- package/dist/issue-YIVBZUTH.js +19 -0
- package/dist/ivf-flat-UZ6DQDLS.js +314 -0
- package/dist/ivf-flat-UZ6DQDLS.js.map +1 -0
- package/dist/{json-schema-V3M5MUCM.js → json-schema-3SHX72CC.js} +2 -1
- package/dist/json-schema-3SHX72CC.js.map +1 -0
- package/dist/kernel/attestation-types.d.ts +62 -0
- package/dist/kernel/collection-config.d.ts +5 -68
- package/dist/kernel/collection.d.ts +30 -9
- package/dist/kernel/cutover-transform.d.ts +1 -1
- package/dist/kernel/errors.d.ts +257 -38
- package/dist/kernel/generation-map.d.ts +48 -0
- package/dist/kernel/merge-authority.d.ts +1 -1
- package/dist/kernel/noydb.d.ts +6 -1
- package/dist/kernel/paths.d.ts +29 -5
- package/dist/kernel/prepared-write.d.ts +1 -1
- package/dist/kernel/present-cache.d.ts +58 -0
- package/dist/kernel/query/all.d.ts +7 -0
- package/dist/kernel/query/builder.d.ts +601 -270
- package/dist/kernel/query/civil-date.d.ts +64 -0
- package/dist/kernel/query/cursor.d.ts +40 -0
- package/dist/kernel/query/distinct-key.d.ts +98 -0
- package/dist/kernel/query/hydration.d.ts +76 -0
- package/dist/kernel/query/index.d.ts +31 -15
- package/dist/kernel/query/internal/core.d.ts +30 -0
- package/dist/kernel/query/internal/hooks.d.ts +22 -0
- package/dist/kernel/query/internal/maintenance.d.ts +43 -0
- package/dist/kernel/query/live/incremental.d.ts +314 -0
- package/dist/kernel/query/live/index.d.ts +22 -0
- package/dist/kernel/query/live/install.d.ts +2 -0
- package/dist/kernel/query/{live.d.ts → live/live.d.ts} +39 -9
- package/dist/kernel/query/live/methods.d.ts +107 -0
- package/dist/kernel/query/predicate.d.ts +119 -1
- package/dist/kernel/query/reduce/date-trunc.d.ts +75 -0
- package/dist/kernel/query/reduce/index.d.ts +36 -0
- package/dist/kernel/query/reduce/install.d.ts +2 -0
- package/dist/kernel/query/reduce/methods.d.ts +259 -0
- package/dist/kernel/query/reduce/scan-methods.d.ts +121 -0
- package/dist/kernel/query/relate/explain.d.ts +199 -0
- package/dist/kernel/query/relate/index.d.ts +48 -0
- package/dist/kernel/query/relate/install.d.ts +2 -0
- package/dist/kernel/query/relate/join-on.d.ts +126 -0
- package/dist/kernel/query/relate/join-reduce.d.ts +16 -0
- package/dist/kernel/query/relate/join.d.ts +452 -0
- package/dist/kernel/query/relate/methods.d.ts +426 -0
- package/dist/kernel/query/relate/partition.d.ts +87 -0
- package/dist/kernel/query/relate/scan-methods.d.ts +163 -0
- package/dist/kernel/query/relate/traverse.d.ts +109 -0
- package/dist/kernel/query/scan-builder.d.ts +79 -176
- package/dist/kernel/query/sort-key.d.ts +52 -0
- package/dist/kernel/secret-mode.d.ts +1 -1
- package/dist/kernel/tx-write-gate.d.ts +77 -0
- package/dist/kernel/types.d.ts +113 -8
- package/dist/kernel/validation.d.ts +27 -10
- package/dist/kernel/vault.d.ts +11 -6
- package/dist/kernel/via/compose.d.ts +3 -0
- package/dist/kernel/via/index.d.ts +56 -0
- package/dist/kernel/via/pipeline.d.ts +48 -0
- package/dist/kernel/write-queue.d.ts +17 -0
- package/dist/{ledger-EDXFFZQL.js → ledger-5ZMGE44K.js} +11 -12
- package/dist/liberate-WZSZM2W6.js +24 -0
- package/dist/link-set-MFXC24VK.js +29 -0
- package/dist/{managed-secret-NCWEMPUQ.js → managed-secret-MFTFT22X.js} +10 -11
- package/dist/materialized-views/index.js +30 -24
- package/dist/{migrate-cek-5ENH64AA.js → migrate-cek-DZRFFOHW.js} +2 -2
- package/dist/money/index.js +5 -5
- package/dist/noydb-ITIGNKUF.js +96 -0
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.js +12 -13
- package/dist/pod/index.js +74 -67
- package/dist/{pod-handle-ECVCDIXW.js → pod-handle-A3LET7NO.js} +10 -11
- package/dist/pod-handle-A3LET7NO.js.map +1 -0
- package/dist/policy/index.js +10 -11
- package/dist/port/on/index.d.ts +1 -1
- package/dist/port/to/index.d.ts +1 -1
- package/dist/port/with/blob-strategy.d.ts +10 -1
- package/dist/port/with/classified-strategy.d.ts +1 -1
- package/dist/port/with/collection-options.d.ts +6 -1
- package/dist/port/with/collection-registries.d.ts +1 -1
- package/dist/port/with/coverage-strategy.d.ts +83 -0
- package/dist/port/with/lookup-strategy.d.ts +2 -2
- package/dist/port/with/service-bus.d.ts +46 -0
- package/dist/port/with/strategies.d.ts +2 -0
- package/dist/portability/index.js +8 -8
- package/dist/{post-register-3IPCSG6Q.js → post-register-7ND27CF2.js} +6 -6
- package/dist/post-register-7ND27CF2.js.map +1 -0
- package/dist/query/all/index.js +31 -0
- package/dist/query/index.js +20 -32
- package/dist/query/live/index.js +21 -0
- package/dist/query/live/index.js.map +1 -0
- package/dist/query/reduce/index.js +33 -0
- package/dist/query/reduce/index.js.map +1 -0
- package/dist/query/relate/index.js +56 -0
- package/dist/query/relate/index.js.map +1 -0
- package/dist/reduce/index.js +72 -18
- package/dist/reduce/index.js.map +1 -1
- package/dist/register-DT5HZ2LZ.js +30 -0
- package/dist/registry-BHRZGZHF.js +8 -0
- package/dist/registry-ET6ZFFWA.js +34 -0
- package/dist/registry-HXFGLGTG.js +8 -0
- package/dist/registry-THCPDEOD.js +23 -0
- package/dist/request-withdrawal-AV2MJJKY.js +30 -0
- package/dist/{reveal-QZDHSGD4.js → reveal-B2TLP4JQ.js} +10 -9
- package/dist/reveal-B2TLP4JQ.js.map +1 -0
- package/dist/revoke-6DWIEOCV.js +24 -0
- package/dist/satellites/index.js +1 -1
- package/dist/schema-update/index.js +2 -2
- package/dist/sealed-record/index.js +16 -18
- package/dist/sealed-record/index.js.map +1 -1
- package/dist/search/index.js +11 -5
- package/dist/{seed-X5CC22CQ.js → seed-XNSE4U3S.js} +15 -18
- package/dist/seed-XNSE4U3S.js.map +1 -0
- package/dist/sequence/index.js +9 -10
- package/dist/session/index.js +9 -10
- package/dist/session/index.js.map +1 -1
- package/dist/shadow/index.js +2 -2
- package/dist/signer-MHGW3OIL.js +23 -0
- package/dist/snapshots/index.js +11 -11
- package/dist/stale-6GCFMOOR.js +28 -0
- package/dist/storage-BYN5LO6Z.js +21 -0
- package/dist/storage-BYN5LO6Z.js.map +1 -0
- package/dist/store/index.js +1 -1
- package/dist/{store-coordination-provider-4WZAIRHC.js → store-coordination-provider-C4BPT5XF.js} +11 -12
- package/dist/store-coordination-provider-C4BPT5XF.js.map +1 -0
- package/dist/sync/index.js +10 -11
- package/dist/sync/index.js.map +1 -1
- package/dist/team/index.js +17 -16
- package/dist/tiers/index.js +13 -12
- package/dist/to/index.js +2 -2
- package/dist/transactions/index.js +3 -3
- package/dist/util/index.js +1 -1
- package/dist/vault-head/index.js +11 -14
- package/dist/vault-head/index.js.map +1 -1
- package/dist/{verify-6MDTIUEV.js → verify-UKALW7C2.js} +14 -12
- package/dist/verify-UKALW7C2.js.map +1 -0
- package/dist/via/blob/index.d.ts +1 -0
- package/dist/via/classified/binding.d.ts +2 -2
- package/dist/via/classified/config-drift.d.ts +2 -2
- package/dist/via/classified/errors.d.ts +1 -1
- package/dist/via/geo/binding.d.ts +31 -0
- package/dist/via/geo/descriptor.d.ts +54 -0
- package/dist/via/geo/geohash.d.ts +95 -0
- package/dist/via/geo/index.d.ts +13 -0
- package/dist/via/geo/where.d.ts +50 -0
- package/dist/via/i18n/core.d.ts +1 -1
- package/dist/via/lookup/handle.d.ts +4 -4
- package/dist/via/lookup/registry.d.ts +1 -1
- package/dist/via/lookup/snapshot.d.ts +3 -3
- package/dist/walk-4VPK7AS4.js +20 -0
- package/dist/walk-4VPK7AS4.js.map +1 -0
- package/dist/with-audit/attestation/index.d.ts +2 -1
- package/dist/with-audit/attestation/issue.d.ts +2 -2
- package/dist/with-audit/attestation/revoke.d.ts +2 -2
- package/dist/with-audit/attestation/scheme.d.ts +7 -0
- package/dist/with-audit/attestation/signer.d.ts +1 -1
- package/dist/with-audit/attestation/strategy.d.ts +2 -2
- package/dist/with-audit/attestation/types.d.ts +10 -0
- package/dist/with-audit/attestation/vault-facade.d.ts +2 -2
- package/dist/with-audit/attestation/verifier.d.ts +6 -0
- package/dist/with-audit/consent/consent.d.ts +1 -1
- package/dist/with-audit/consent/strategy.d.ts +1 -1
- package/dist/with-audit/coverage/accounting.d.ts +112 -0
- package/dist/with-audit/coverage/active.d.ts +29 -0
- package/dist/with-audit/coverage/index.d.ts +61 -0
- package/dist/with-audit/coverage/sketch.d.ts +75 -0
- package/dist/with-audit/forget/subject-index.d.ts +1 -1
- package/dist/with-audit/periods/periods.d.ts +55 -7
- package/dist/with-audit/periods/reserved-collections.d.ts +3 -0
- package/dist/with-audit/periods/vault-facade.d.ts +18 -1
- package/dist/with-audit/sealed-record/index.d.ts +2 -2
- package/dist/with-audit/sealed-record/strategy.d.ts +1 -1
- package/dist/with-audit/tiers/index.d.ts +53 -2
- package/dist/with-audit/tiers/strategy.d.ts +8 -0
- package/dist/with-cargo/adopt-partition.d.ts +1 -1
- package/dist/with-cargo/extract-partition.d.ts +1 -1
- package/dist/with-cargo/floor.d.ts +3 -3
- package/dist/with-commit/history/history.d.ts +2 -2
- package/dist/with-commit/history/index.d.ts +1 -1
- package/dist/with-commit/history/ledger/store.d.ts +1 -1
- package/dist/with-commit/history/strategy.d.ts +1 -1
- package/dist/with-commit/history/time-machine.d.ts +1 -1
- package/dist/with-commit/numbering/index.d.ts +1 -1
- package/dist/with-commit/sequence/index.d.ts +1 -1
- package/dist/with-commit/tx/invariants.d.ts +1 -1
- package/dist/with-commit/tx/transaction.d.ts +13 -3
- package/dist/with-commit/vault-head/head.d.ts +1 -1
- package/dist/with-commit/vault-head/index.d.ts +1 -1
- package/dist/with-commit/vault-head/strategy.d.ts +1 -1
- package/dist/with-commit/vault-head/verify.d.ts +1 -1
- package/dist/with-formula/derivations/dispatch.d.ts +1 -1
- package/dist/with-formula/derivations/fanout-sidecar.d.ts +1 -1
- package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +4 -3
- package/dist/with-formula/materialized-views/emit-memo.d.ts +40 -0
- package/dist/with-formula/materialized-views/executor.d.ts +8 -0
- package/dist/with-formula/materialized-views/index.d.ts +1 -1
- package/dist/with-formula/materialized-views/registry.d.ts +15 -0
- package/dist/with-formula/materialized-views/types.d.ts +106 -14
- package/dist/with-formula/materialized-views/window-stage.d.ts +11 -0
- package/dist/with-formula/overlay-views/types.d.ts +1 -1
- package/dist/with-formula/overlay-views/virtual-collection.d.ts +13 -4
- package/dist/with-lookup/embeddings/chunks.d.ts +79 -0
- package/dist/with-lookup/embeddings/descriptor.d.ts +21 -0
- package/dist/with-lookup/embeddings/index.d.ts +3 -0
- package/dist/with-lookup/embeddings/ivf-flat.d.ts +93 -0
- package/dist/with-lookup/embeddings/vector-index.d.ts +73 -0
- package/dist/with-lookup/embeddings/vector-set.d.ts +94 -1
- package/dist/with-lookup/embeddings/with-vector-index.d.ts +67 -0
- package/dist/with-lookup/indexing/collection-facade.d.ts +86 -3
- package/dist/with-lookup/indexing/compound-indexes.d.ts +129 -0
- package/dist/with-lookup/indexing/eager-indexes.d.ts +170 -1
- package/dist/with-lookup/indexing/index-snapshot.d.ts +62 -0
- package/dist/with-lookup/indexing/lazy-builder.d.ts +33 -0
- package/dist/with-lookup/indexing/persisted-field-indexes.d.ts +104 -0
- package/dist/with-lookup/indexing/persisted-indexes.d.ts +12 -0
- package/dist/with-lookup/indexing/sorted-indexes.d.ts +117 -0
- package/dist/with-lookup/indexing/unique-constraints.d.ts +106 -23
- package/dist/with-lookup/reduce/active.d.ts +2 -24
- package/dist/with-lookup/reduce/group-core.d.ts +43 -0
- package/dist/with-lookup/reduce/groupby.d.ts +195 -36
- package/dist/with-lookup/reduce/incremental-group.d.ts +153 -0
- package/dist/with-lookup/reduce/index.d.ts +26 -5
- package/dist/with-lookup/reduce/reducers.d.ts +255 -1
- package/dist/with-lookup/reduce/reduction.d.ts +44 -13
- package/dist/with-lookup/reduce/strategy.d.ts +43 -3
- package/dist/with-lookup/reduce/window.d.ts +262 -0
- package/dist/with-lookup/search/collection-facade.d.ts +45 -9
- package/dist/with-lookup/search/index-store.d.ts +5 -3
- package/dist/with-lookup/search/index.d.ts +4 -2
- package/dist/with-lookup/search/inverted-index.d.ts +38 -2
- package/dist/with-lookup/search/persisted-index-store.d.ts +5 -2
- package/dist/with-lookup/search/phrase.d.ts +28 -0
- package/dist/with-lookup/search/retrieve-types.d.ts +57 -1
- package/dist/with-lookup/search/serialize.d.ts +29 -3
- package/dist/with-lookup/search/strategy.d.ts +2 -6
- package/dist/with-party/broker/index.d.ts +3 -3
- package/dist/with-party/directory/cover/index.d.ts +1 -1
- package/dist/with-party/directory/cover/storage.d.ts +1 -1
- package/dist/with-party/directory/cover/types.d.ts +1 -1
- package/dist/with-party/directory/index.d.ts +1 -1
- package/dist/with-party/directory/types.d.ts +1 -1
- package/dist/with-party/directory/user-envelope/api.d.ts +1 -1
- package/dist/with-party/directory/user-envelope/storage.d.ts +1 -1
- package/dist/with-party/policy/engine.d.ts +1 -1
- package/dist/with-party/policy/index.d.ts +1 -1
- package/dist/with-party/policy/presets.d.ts +1 -1
- package/dist/with-party/team/authenticators.d.ts +91 -1
- package/dist/with-party/team/delegation.d.ts +1 -1
- package/dist/with-party/team/echo-secret.d.ts +2 -2
- package/dist/with-party/team/index.d.ts +4 -3
- package/dist/with-party/team/keyring.d.ts +2 -2
- package/dist/with-party/team/magic-link-grant.d.ts +1 -1
- package/dist/with-party/team/managed-secret.d.ts +1 -1
- package/dist/with-party/team/noydb-facade.d.ts +12 -3
- package/dist/with-party/team/recovery.d.ts +1 -1
- package/dist/with-party/team/roster-tag.d.ts +1 -1
- package/dist/with-party/team/rotate-recover.d.ts +1 -1
- package/dist/with-party/team/wrapped-deks.d.ts +1 -1
- package/dist/with-pod/format.d.ts +1 -1
- package/dist/with-pod/index.d.ts +1 -1
- package/dist/with-pod/pod.d.ts +1 -1
- package/dist/with-shape/blobs/blob-compaction.d.ts +17 -1
- package/dist/with-shape/blobs/blob-intent.d.ts +1 -1
- package/dist/with-shape/blobs/blob-set.d.ts +23 -4
- package/dist/with-shape/blobs/legacy-sweep.d.ts +35 -0
- package/dist/with-shape/introspection/describe.d.ts +7 -1
- package/dist/with-shape/introspection/field-meta.d.ts +18 -0
- package/dist/with-shape/introspection/types.d.ts +57 -1
- package/dist/with-shape/introspection/walk.d.ts +1 -1
- package/dist/with-shape/links/lazy-handle.d.ts +1 -1
- package/dist/with-shape/links/link-set.d.ts +1 -1
- package/dist/with-shape/links/vault-facade.d.ts +1 -1
- package/dist/with-shape/manifest/derive.d.ts +1 -1
- package/dist/with-shape/manifest/storage.d.ts +1 -1
- package/dist/with-shape/persisted-schemas/register.d.ts +1 -1
- package/dist/with-shape/persisted-schemas/storage.d.ts +1 -1
- package/dist/with-shape/satellites/dead-filter.d.ts +1 -1
- package/dist/with-shape/satellites/declare.d.ts +1 -1
- package/dist/with-shape/satellites/marker.d.ts +1 -1
- package/dist/with-shape/satellites/post-register.d.ts +1 -1
- package/dist/with-store/partitioned/index.d.ts +337 -0
- package/dist/with-sync/change-broadcast.d.ts +153 -0
- package/dist/with-sync/presence.d.ts +5 -10
- package/dist/withdraw-accessible-HL7GACUE.js +27 -0
- package/dist/withdraw-accessible-HL7GACUE.js.map +1 -0
- package/package.json +48 -12
- package/dist/api-WYW4YEQG.js +0 -19
- package/dist/backup-XKCXVKV3.js.map +0 -1
- package/dist/chunk-2577DKXB.js.map +0 -1
- package/dist/chunk-2ENE6445.js.map +0 -1
- package/dist/chunk-2N5ML6HT.js.map +0 -1
- package/dist/chunk-334WSVOW.js.map +0 -1
- package/dist/chunk-3BVH633C.js.map +0 -1
- package/dist/chunk-3PGS7TYR.js.map +0 -1
- package/dist/chunk-3V4KWFX7.js.map +0 -1
- package/dist/chunk-453F654R.js.map +0 -1
- package/dist/chunk-4GFX6MPA.js.map +0 -1
- package/dist/chunk-4GVM6QZA.js.map +0 -1
- package/dist/chunk-4ZS56W5S.js.map +0 -1
- package/dist/chunk-5VCRVKOZ.js.map +0 -1
- package/dist/chunk-6YXCPL4T.js.map +0 -1
- package/dist/chunk-7APJ6CO6.js.map +0 -1
- package/dist/chunk-7MG2LHO5.js +0 -1616
- package/dist/chunk-7MG2LHO5.js.map +0 -1
- package/dist/chunk-7MG7SJT7.js.map +0 -1
- package/dist/chunk-7O3Y4PPD.js.map +0 -1
- package/dist/chunk-A2HKRLPV.js.map +0 -1
- package/dist/chunk-A66I4JOA.js.map +0 -1
- package/dist/chunk-ACAQ2DSG.js.map +0 -1
- package/dist/chunk-ATL3ZVXT.js +0 -151
- package/dist/chunk-ATL3ZVXT.js.map +0 -1
- package/dist/chunk-AYX7AINO.js.map +0 -1
- package/dist/chunk-BLN54W3L.js.map +0 -1
- package/dist/chunk-BRLKZUBT.js +0 -95
- package/dist/chunk-BRLKZUBT.js.map +0 -1
- package/dist/chunk-BTDR2PXY.js +0 -29
- package/dist/chunk-BTDR2PXY.js.map +0 -1
- package/dist/chunk-BVN6KXL2.js.map +0 -1
- package/dist/chunk-CHQCZZWC.js.map +0 -1
- package/dist/chunk-CUQPWYRX.js.map +0 -1
- package/dist/chunk-CUZLNGD5.js.map +0 -1
- package/dist/chunk-DFMWUOU5.js.map +0 -1
- package/dist/chunk-EIPVYUEP.js.map +0 -1
- package/dist/chunk-EQEYOJBM.js.map +0 -1
- package/dist/chunk-F3W6YMDC.js.map +0 -1
- package/dist/chunk-FET5XCAT.js.map +0 -1
- package/dist/chunk-G73UVHCA.js.map +0 -1
- package/dist/chunk-GPNTB4Y7.js.map +0 -1
- package/dist/chunk-GYGLAVCX.js.map +0 -1
- package/dist/chunk-HIWCKBEY.js.map +0 -1
- package/dist/chunk-HJUWN7JN.js.map +0 -1
- package/dist/chunk-HK67PX4J.js.map +0 -1
- package/dist/chunk-HPVZCW43.js +0 -479
- package/dist/chunk-HPVZCW43.js.map +0 -1
- package/dist/chunk-I3ISCYT7.js +0 -159
- package/dist/chunk-I3ISCYT7.js.map +0 -1
- package/dist/chunk-K23VKTN4.js.map +0 -1
- package/dist/chunk-KKEESNPE.js.map +0 -1
- package/dist/chunk-KTFRCC5C.js.map +0 -1
- package/dist/chunk-LH5A3ZPG.js.map +0 -1
- package/dist/chunk-LP7BEXCT.js +0 -32
- package/dist/chunk-LP7BEXCT.js.map +0 -1
- package/dist/chunk-M4YPHYEH.js.map +0 -1
- package/dist/chunk-NSITFOCJ.js +0 -99
- package/dist/chunk-NSITFOCJ.js.map +0 -1
- package/dist/chunk-OTQZ7ZWU.js.map +0 -1
- package/dist/chunk-P3MG6QCN.js.map +0 -1
- package/dist/chunk-PEOZ34EM.js.map +0 -1
- package/dist/chunk-PPTHY5QO.js.map +0 -1
- package/dist/chunk-Q2MPFCQ7.js.map +0 -1
- package/dist/chunk-Q7HZX3IF.js.map +0 -1
- package/dist/chunk-QPQUVOZ2.js.map +0 -1
- package/dist/chunk-QTQUH4DS.js.map +0 -1
- package/dist/chunk-R42NSZI6.js.map +0 -1
- package/dist/chunk-R7BX2NB3.js.map +0 -1
- package/dist/chunk-RSGLUIO6.js.map +0 -1
- package/dist/chunk-RTBJ5IOO.js +0 -87
- package/dist/chunk-RTBJ5IOO.js.map +0 -1
- package/dist/chunk-SGZAIJCV.js.map +0 -1
- package/dist/chunk-SKGMN35F.js.map +0 -1
- package/dist/chunk-SPYWXKJN.js.map +0 -1
- package/dist/chunk-SZJ3DLZA.js +0 -66
- package/dist/chunk-SZJ3DLZA.js.map +0 -1
- package/dist/chunk-TRGTKX5E.js.map +0 -1
- package/dist/chunk-UDHWDSRL.js.map +0 -1
- package/dist/chunk-UP4BECPY.js.map +0 -1
- package/dist/chunk-UXVWEX5L.js.map +0 -1
- package/dist/chunk-V7ZRRCRJ.js.map +0 -1
- package/dist/chunk-WQBG4SZS.js.map +0 -1
- package/dist/chunk-XKWGNJ26.js.map +0 -1
- package/dist/chunk-YMUFFJCO.js.map +0 -1
- package/dist/chunk-ZHKOPKE3.js.map +0 -1
- package/dist/chunk-ZN4FD4PE.js +0 -364
- package/dist/chunk-ZN4FD4PE.js.map +0 -1
- package/dist/chunk-ZORTV6NH.js.map +0 -1
- package/dist/chunk-ZYIYHJ5R.js.map +0 -1
- package/dist/classified-marker-BWOFVYAC.js.map +0 -1
- package/dist/collection-facade-JSJYIKS4.js +0 -45
- package/dist/dead-filter-PKQDLOT4.js.map +0 -1
- package/dist/delegation-DS5NRILW.js.map +0 -1
- package/dist/derive-E642AOUB.js +0 -21
- package/dist/dispatch-Q6MWLOJY.js.map +0 -1
- package/dist/executor-5NIMLSKZ.js +0 -8
- package/dist/executor-7UQ3BZ4F.js +0 -29
- package/dist/executor-AQVXV5GZ.js +0 -8
- package/dist/export-accessible-ORMKLA3E.js +0 -22
- package/dist/extract-partition-NKYO3WNG.js +0 -37
- package/dist/fanout-sidecar-S3QL53YX.js.map +0 -1
- package/dist/find-NOGJ25VX.js +0 -10
- package/dist/issue-3DTQ7VJJ.js +0 -18
- package/dist/json-schema-V3M5MUCM.js.map +0 -1
- package/dist/kernel/enclave/classify/compare.d.ts +0 -10
- package/dist/kernel/enclave/index.d.ts +0 -87
- package/dist/kernel/enclave/record-keys/lifecycle.d.ts +0 -124
- package/dist/kernel/enclave/record-keys/rekey-blob.d.ts +0 -88
- package/dist/kernel/enclave/record-keys/rekey.d.ts +0 -91
- package/dist/kernel/enclave/record-keys/sealed-slot.d.ts +0 -14
- package/dist/kernel/enclave/record-keys/sealed-slots.d.ts +0 -123
- package/dist/kernel/enclave/record-keys/sealing.d.ts +0 -70
- package/dist/kernel/query/join.d.ts +0 -232
- package/dist/liberate-V35QUHJP.js +0 -24
- package/dist/link-set-2TTM3IZC.js +0 -30
- package/dist/noydb-62MX4QUG.js +0 -90
- package/dist/pod-handle-ECVCDIXW.js.map +0 -1
- package/dist/post-register-3IPCSG6Q.js.map +0 -1
- package/dist/register-HHLXEQDN.js +0 -31
- package/dist/registry-23WF3TGH.js +0 -8
- package/dist/registry-4AYVUNXK.js +0 -8
- package/dist/registry-JS3YFQQM.js +0 -18
- package/dist/registry-XX2Z7B46.js +0 -32
- package/dist/request-withdrawal-CHPATE4G.js +0 -30
- package/dist/reveal-QZDHSGD4.js.map +0 -1
- package/dist/revoke-7M2VW4ON.js +0 -23
- package/dist/seed-X5CC22CQ.js.map +0 -1
- package/dist/signer-SJQJVSM6.js +0 -24
- package/dist/stale-BZS6H2RY.js +0 -29
- package/dist/storage-RW4QBS23.js +0 -22
- package/dist/store-coordination-provider-4WZAIRHC.js.map +0 -1
- package/dist/verify-6MDTIUEV.js.map +0 -1
- package/dist/walk-ZURCH6RZ.js +0 -21
- package/dist/withdraw-accessible-PXR4IXDX.js +0 -27
- /package/dist/{api-WYW4YEQG.js.map → api-OS747DS4.js.map} +0 -0
- /package/dist/{computed-VPOKQK4N.js.map → capsule/contract.js.map} +0 -0
- /package/dist/{kernel/enclave → capsule/enclave-aes}/broker/proof.d.ts +0 -0
- /package/dist/{kernel/enclave → capsule/enclave-aes}/classify/bidx.d.ts +0 -0
- /package/dist/{kernel/enclave → capsule/enclave-aes}/classify/digest.d.ts +0 -0
- /package/dist/{kernel/enclave → capsule/enclave-aes}/classify/vdig.d.ts +0 -0
- /package/dist/{kernel/enclave/classify → capsule/plumbing}/kofn.d.ts +0 -0
- /package/dist/{kernel/enclave/classify → capsule/plumbing}/normalize.d.ts +0 -0
- /package/dist/{kernel/enclave → capsule/plumbing}/record-aad.d.ts +0 -0
- /package/dist/{collection-facade-JSJYIKS4.js.map → capsule-VOLX3QRQ.js.map} +0 -0
- /package/dist/{chunk-MVMXZYXT.js.map → chunk-2GHDLTPE.js.map} +0 -0
- /package/dist/{chunk-XLMEZIAJ.js.map → chunk-2ODVB6LZ.js.map} +0 -0
- /package/dist/{chunk-RMS3NEA3.js.map → chunk-4JPMZTJY.js.map} +0 -0
- /package/dist/{chunk-NQKIUNW5.js.map → chunk-52MGURXO.js.map} +0 -0
- /package/dist/{chunk-UGTBXF5U.js.map → chunk-7XMHMVTS.js.map} +0 -0
- /package/dist/{chunk-BZ3534YM.js.map → chunk-AUKKUPVB.js.map} +0 -0
- /package/dist/{derive-E642AOUB.js.map → chunk-BKT776R5.js.map} +0 -0
- /package/dist/{chunk-6LKOJBV6.js.map → chunk-BVCUTXE3.js.map} +0 -0
- /package/dist/{chunk-VTFVLCUH.js.map → chunk-DIZLQVAA.js.map} +0 -0
- /package/dist/{chunk-LWBCUYZW.js.map → chunk-E2N2T5ZO.js.map} +0 -0
- /package/dist/{chunk-JVIBCBC7.js.map → chunk-EJLV62NI.js.map} +0 -0
- /package/dist/{chunk-JMGDHKQF.js.map → chunk-FLPCETP6.js.map} +0 -0
- /package/dist/{chunk-DGOZ4UZD.js.map → chunk-FVH5QYY2.js.map} +0 -0
- /package/dist/{chunk-JBDFMYKQ.js.map → chunk-GZT3NQRA.js.map} +0 -0
- /package/dist/{chunk-TFR7DSOV.js.map → chunk-H427H63K.js.map} +0 -0
- /package/dist/{chunk-SMH6SRX7.js.map → chunk-JOSPH3E5.js.map} +0 -0
- /package/dist/{chunk-3BZZJJMQ.js.map → chunk-MILI22XQ.js.map} +0 -0
- /package/dist/{chunk-YYP7WSEB.js.map → chunk-O2IMQSNA.js.map} +0 -0
- /package/dist/{chunk-QIZPZMUI.js.map → chunk-Q4UHJ5SN.js.map} +0 -0
- /package/dist/{chunk-FAHMLERK.js.map → chunk-QBLT6POL.js.map} +0 -0
- /package/dist/{chunk-BUE2D7PX.js.map → chunk-SMV2HRDU.js.map} +0 -0
- /package/dist/{chunk-SFAWCTEM.js.map → chunk-TZZBXPZK.js.map} +0 -0
- /package/dist/{chunk-UHHPLO3I.js.map → chunk-V3RWOOSO.js.map} +0 -0
- /package/dist/{chunk-Q2PU57HC.js.map → chunk-VVOLDVIR.js.map} +0 -0
- /package/dist/{chunk-TUFM4UZP.js.map → chunk-XQRFSKYM.js.map} +0 -0
- /package/dist/{chunk-GY4WYNNG.js.map → chunk-Y2RKVFKR.js.map} +0 -0
- /package/dist/{chunk-4OZNXTO4.js.map → chunk-YRXFFWG4.js.map} +0 -0
- /package/dist/{enclave-55PAM4YO.js.map → collection-facade-CS7CA2XO.js.map} +0 -0
- /package/dist/{executor-5NIMLSKZ.js.map → computed-FAD7SED4.js.map} +0 -0
- /package/dist/{executor-7UQ3BZ4F.js.map → derive-XLOJVXPU.js.map} +0 -0
- /package/dist/{dispatch-IEPAVQUM.js.map → dispatch-H4HV32AM.js.map} +0 -0
- /package/dist/{executor-AQVXV5GZ.js.map → executor-FMPVN6DT.js.map} +0 -0
- /package/dist/{export-accessible-ORMKLA3E.js.map → executor-LBBBRTN5.js.map} +0 -0
- /package/dist/{extract-partition-NKYO3WNG.js.map → executor-OSRZST2U.js.map} +0 -0
- /package/dist/{find-NOGJ25VX.js.map → export-accessible-RAOJAAU5.js.map} +0 -0
- /package/dist/{issue-3DTQ7VJJ.js.map → extract-partition-JD5CUSTG.js.map} +0 -0
- /package/dist/{ledger-EDXFFZQL.js.map → find-JRN4RNQ5.js.map} +0 -0
- /package/dist/{liberate-V35QUHJP.js.map → issue-YIVBZUTH.js.map} +0 -0
- /package/dist/{link-set-2TTM3IZC.js.map → ledger-5ZMGE44K.js.map} +0 -0
- /package/dist/{managed-secret-NCWEMPUQ.js.map → liberate-WZSZM2W6.js.map} +0 -0
- /package/dist/{noydb-62MX4QUG.js.map → link-set-MFXC24VK.js.map} +0 -0
- /package/dist/{register-HHLXEQDN.js.map → managed-secret-MFTFT22X.js.map} +0 -0
- /package/dist/{migrate-cek-5ENH64AA.js.map → migrate-cek-DZRFFOHW.js.map} +0 -0
- /package/dist/{registry-23WF3TGH.js.map → noydb-ITIGNKUF.js.map} +0 -0
- /package/dist/{registry-4AYVUNXK.js.map → query/all/index.js.map} +0 -0
- /package/dist/{registry-JS3YFQQM.js.map → register-DT5HZ2LZ.js.map} +0 -0
- /package/dist/{registry-XX2Z7B46.js.map → registry-BHRZGZHF.js.map} +0 -0
- /package/dist/{request-withdrawal-CHPATE4G.js.map → registry-ET6ZFFWA.js.map} +0 -0
- /package/dist/{revoke-7M2VW4ON.js.map → registry-HXFGLGTG.js.map} +0 -0
- /package/dist/{signer-SJQJVSM6.js.map → registry-THCPDEOD.js.map} +0 -0
- /package/dist/{stale-BZS6H2RY.js.map → request-withdrawal-AV2MJJKY.js.map} +0 -0
- /package/dist/{storage-RW4QBS23.js.map → revoke-6DWIEOCV.js.map} +0 -0
- /package/dist/{walk-ZURCH6RZ.js.map → signer-MHGW3OIL.js.map} +0 -0
- /package/dist/{withdraw-accessible-PXR4IXDX.js.map → stale-6GCFMOOR.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/with-lookup/reduce/reduction.ts","../src/with-lookup/reduce/group-core.ts","../src/with-lookup/reduce/incremental-group.ts","../src/with-lookup/reduce/groupby.ts"],"sourcesContent":["/**\n * Aggregate execution — the runtime behind `Query.aggregate()`.\n *\n * takes an `ReduceSpec` (a record of named reducers\n * built from `reducers.ts`) and runs every reducer over the records\n * produced by the underlying query. Two terminal surfaces:\n *\n * - `.run(): R` — synchronous one-shot reduction. Matches the\n * existing `Query.toArray()` / `.first()` / `.count()` style.\n * - `.live(): LiveReduction<R>` — reactive primitive that\n * re-runs the reduction whenever the query's source notifies of\n * a change. Since #1341 the RECORD SET it reduces is maintained\n * incrementally upstream (see `kernel/query/live/incremental.ts`), so a\n * change costs one predicate evaluation instead of a full scan — but\n * the reducers themselves still run a complete `init → step* →\n * finalize` fold over that set. Driving `remove()` per delta (the\n * reducer protocol admits it) would make a change O(1) rather than\n * O(matches); it is deliberately NOT wired, because folding the same\n * array a re-run would fold makes the incremental value bit-identical\n * to the eager one, while inverting a float `sum` does not.\n *\n * `GroupedReduction.live()` goes one step further (#1341, grouped half): its\n * BUCKETS are maintained too, so a change re-folds only the groups it touched.\n * See `incremental-group.ts`. The reasoning above is why neither path inverts\n * a reducer state.\n *\n * The `Reduction<R>` wrapper is deliberately tiny — it exists so\n * `.aggregate(spec)` can be chained with either `.run()` or `.live()`\n * without the builder needing two separate terminal methods. It\n * holds the closure over the query execution (produces the current\n * matching record set) and the spec, and stitches them together in\n * either mode.\n *\n * This file depends ONLY on `reducers.ts` — it has no knowledge of\n * the `Query` class. Tests can therefore exercise the reduction\n * surface with plain record arrays, without spinning up a Collection.\n */\n\nimport type { Reducer } from './reducers.js'\nimport type { SourceChange } from '../../kernel/query/live/incremental.js'\nimport { gateTerminal } from '../../kernel/query/hydration.js'\nimport type { HydrationGate } from '../../kernel/query/hydration.js'\n\n/**\n * A named set of reducers, keyed by output field name. Each key\n * becomes a field on the aggregated result.\n *\n * ```ts\n * const spec = {\n * total: sum('amount'),\n * n: count(),\n * avgAmount: avg('amount'),\n * }\n * ```\n */\nexport type ReduceSpec = Readonly<Record<string, Reducer<unknown, unknown>>>\n\n/**\n * Map an `ReduceSpec` to its reduced result shape — each key\n * carries the finalized result type from its reducer. A spec built\n * from `{ total: sum('amount'), n: count() }` yields a result of\n * `{ total: number, n: number }`.\n *\n * This uses a mapped type with a conditional to extract `R` from\n * each `Reducer<R, _>`. The `infer` captures the user-visible result\n * type, discarding the internal state type `S`.\n */\nexport type ReduceResult<Spec extends ReduceSpec> = {\n [K in keyof Spec]: Spec[K] extends Reducer<infer R, unknown> ? R : never\n}\n\n/**\n * Pure reduction over a record array. Runs every reducer's\n * `init → step* → finalize` pipeline exactly once over the records.\n *\n * Called by `Reduction.run()` and by the live-mode refresh path.\n * Exported for tests and for future `scan().aggregate()` reuse\n * — the streaming path will call the same reducer protocol with a\n * per-page loop instead of a single array.\n */\nexport function reduceRecords<Spec extends ReduceSpec>(\n records: readonly unknown[],\n spec: Spec,\n): ReduceResult<Spec> {\n // Per-slot state, keyed by the spec's output field name.\n const state: Record<string, unknown> = {}\n for (const key of Object.keys(spec)) {\n state[key] = spec[key]!.init()\n }\n for (const record of records) {\n for (const key of Object.keys(spec)) {\n state[key] = spec[key]!.step(state[key], record)\n }\n }\n const result: Record<string, unknown> = {}\n for (const key of Object.keys(spec)) {\n result[key] = spec[key]!.finalize(state[key])\n }\n return result as ReduceResult<Spec>\n}\n\n/**\n * A minimal reactive primitive for reduction results.\n *\n * Same spirit as the `LiveQuery` in : frame-agnostic, a plain\n * object with `value` / `error` fields and a `subscribe(cb)`\n * notification channel that Vue / React / Solid adapters wrap in\n * their own primitive. Intentionally NOT a Promise — reductions\n * have a well-defined \"current value\" at every instant, and the\n * reactive consumer wants to read that value synchronously.\n *\n * Error semantics mirror `LiveQuery`: if a re-run throws, the\n * previous successful `value` is preserved and the error is stored\n * in `error` so consumers can render an error state without losing\n * the last-known-good result. The throw does NOT propagate out of\n * the source's change handler (which would tear down the upstream\n * emitter).\n *\n * `stop()` tears down the upstream subscription. It is idempotent —\n * calling it multiple times is safe — and subscribe calls after\n * stop are no-ops (they immediately return a no-op unsubscribe).\n * Always call `stop()` when done; Vue's `onUnmounted` is the\n * canonical place. Raw consumers must do it themselves.\n */\nexport interface LiveReduction<R> {\n /** Current reduced value. Undefined only if the first compute threw. */\n readonly value: R | undefined\n /** Last execution error, if any. Cleared on the next successful run. */\n readonly error: unknown\n /** Notify on every recomputation (success or error). Returns unsubscribe. */\n subscribe(cb: () => void): () => void\n /** Tear down the upstream subscription. Idempotent. */\n stop(): void\n}\n\n/**\n * Upstream change-notification hook for live reduction.\n *\n * Matches the shape that `QuerySource.subscribe` already uses — a\n * single method that accepts a callback and returns an unsubscribe\n * function. The `Reduction` wrapper collects upstreams from the\n * query's source and wires them into a single re-run trigger.\n */\nexport interface ReductionUpstream {\n /**\n * `cb` MAY be handed the delta that caused the notification (#1341), which\n * is what lets `GroupedReduction.live()` patch the buckets a change touches\n * instead of re-grouping. Calling it with NO argument is always valid and\n * always correct — it means \"something changed, I can't say what\", and every\n * consumer answers that with a full re-run.\n */\n subscribe(cb: (change?: SourceChange) => void): () => void\n}\n\n/**\n * Internal implementation of `LiveReduction`. Not exported —\n * consumers get the interface only. The class wraps a `recompute`\n * closure (which runs the full reduction and returns the new value)\n * and a list of upstreams (sources whose changes should trigger a\n * re-run).\n *\n * Error isolation: if an individual listener callback throws, the\n * other listeners still fire and the error is logged to the warn\n * channel. This matches `LiveQuery` from and keeps one misbehaving\n * consumer from tearing down the whole live reduction.\n */\nclass LiveAggregationImpl<R> implements LiveReduction<R> {\n public value: R | undefined\n public error: unknown\n private readonly listeners = new Set<() => void>()\n private readonly unsubscribes: Array<() => void> = []\n private stopped = false\n\n constructor(\n private readonly recompute: () => R,\n upstreams: readonly ReductionUpstream[],\n ) {\n // Initial computation — surface any error through the `error`\n // field rather than letting the constructor throw, so consumers\n // can always construct a LiveReduction and check its state\n // afterwards. Throwing from a constructor would force every\n // caller to wrap in try/catch, which is the opposite of the\n // \"reactive value with error state\" ergonomics we want.\n try {\n this.value = recompute()\n this.error = undefined\n } catch (err) {\n this.value = undefined\n this.error = err\n }\n\n // Wire up upstream subscriptions. Each one triggers a full\n // recomputation; we don't attempt incremental updates in.\n for (const upstream of upstreams) {\n const unsub = upstream.subscribe(() => this.refresh())\n this.unsubscribes.push(unsub)\n }\n }\n\n private refresh(): void {\n if (this.stopped) return\n try {\n this.value = this.recompute()\n this.error = undefined\n } catch (err) {\n // Preserve the previous successful value — consumers render an\n // error state using `error` without losing the last-known-good\n // number. This matches LiveQuery's error-preservation contract.\n this.error = err\n }\n for (const listener of this.listeners) {\n try {\n listener()\n } catch (err) {\n // Isolate listener errors so one bad consumer can't tear\n // down every other subscriber on the same reduction.\n console.warn('[noy-db] LiveReduction listener threw:', err)\n }\n }\n }\n\n subscribe(cb: () => void): () => void {\n if (this.stopped) {\n // No-op after stop. Returning a harmless unsubscribe lets\n // consumers use the same teardown pattern unconditionally.\n return () => {}\n }\n this.listeners.add(cb)\n return () => {\n this.listeners.delete(cb)\n }\n }\n\n stop(): void {\n if (this.stopped) return\n this.stopped = true\n for (const unsub of this.unsubscribes) {\n try {\n unsub()\n } catch (err) {\n console.warn('[noy-db] LiveReduction upstream unsubscribe threw:', err)\n }\n }\n this.unsubscribes.length = 0\n this.listeners.clear()\n }\n}\n\n/**\n * Chainable wrapper returned by `Query.aggregate(spec)`. Holds the\n * execute-records closure and the spec; terminal methods (`run`,\n * `live`) stitch them together in either mode.\n *\n * Why a wrapper instead of two terminal methods on `Query` directly?\n *\n * The `.aggregate(spec)` call is where the spec is bound — both\n * `.run()` and `.live()` need the same spec, and the consumer's\n * fluent style is `query.where(...).aggregate(spec).run()` or\n * `.aggregate(spec).live()`. Wrapping lets the spec be named once\n * and reused for either terminal, and keeps the `Query` class\n * from growing a pair of near-duplicate method overloads\n * (`reduceRun` / `reduceLive`) that would be harder to\n * discover.\n */\nexport class Reduction<R> {\n constructor(\n private readonly executeRecords: () => readonly unknown[],\n private readonly spec: ReduceSpec,\n private readonly upstreams: readonly ReductionUpstream[],\n /**\n * #1414 — the backing collection's cold gate, when the reduction came\n * from a collection-backed query. `run()` is SYNCHRONOUS, so a reduction\n * over a never-loaded collection used to answer `0` / `null` with total\n * confidence — the shape a guard's Σ-over-siblings invariant takes.\n */\n private readonly gate?: HydrationGate,\n ) {}\n\n /**\n * Execute the query and reduce the results synchronously.\n * Returns the reduced shape matching the spec — e.g. a spec of\n * `{ total: sum('amount'), n: count() }` returns\n * `{ total: number, n: number }`.\n */\n run(): R {\n // #1414 — `await …aggregate(spec).run()` (what an async guard writes)\n // hydrates and answers; a synchronous `.run()` on a cold collection\n // refuses instead of reporting an absence as a zero.\n return gateTerminal(this.gate, 'aggregate().run', () =>\n reduceRecords(this.executeRecords(), this.spec) as unknown as R)\n }\n\n /**\n * Build a reactive `LiveReduction<R>` that re-runs the reduction\n * whenever any upstream source notifies of a change. The initial\n * value is computed eagerly in the constructor, so consumers can\n * read `live.value` immediately after calling `.live()`.\n *\n * Always call `live.stop()` when finished — it tears down the\n * upstream subscriptions. Vue's `onUnmounted` is the canonical\n * place.\n *\n * **Implementation note:** every upstream change triggers a full\n * re-reduction over the matching records — but since #1341 that record\n * set is itself maintained per delta rather than re-scanned, so the cost\n * is O(matches) rather than O(collection). Reducer-level `remove()`\n * (O(1) per delta for sum/count/avg) remains unwired; see the file\n * docstring for why folding beats inverting here.\n */\n live(): LiveReduction<R> {\n const recompute = (): R =>\n reduceRecords(this.executeRecords(), this.spec) as unknown as R\n // #1414 — the initial value is computed eagerly in the constructor, so a\n // cold collection would seed the reactive primitive with an absence.\n return gateTerminal(this.gate, 'aggregate().live', () =>\n new LiveAggregationImpl<R>(recompute, this.upstreams))\n }\n}\n\n/**\n * Build a `LiveReduction<V>` from a recompute closure and a list\n * of upstreams. Exposed so sibling files in the query DSL\n * (currently `groupby.ts`) can reuse the reactive primitive\n * without reaching into `LiveAggregationImpl` directly. This keeps\n * the implementation class private while still allowing planned\n * composition with `.groupBy().aggregate().live()`.\n */\nexport function buildLiveReduction<V>(\n recompute: () => V,\n upstreams: readonly ReductionUpstream[],\n): LiveReduction<V> {\n return new LiveAggregationImpl<V>(recompute, upstreams)\n}\n","/**\n * The parts of `.groupBy()` that BOTH the eager pipeline and the incremental\n * one need — the cardinality guards and the per-bucket fold.\n *\n * ⭐ It exists for one reason: `groupby.ts` (eager) and `incremental-group.ts`\n * (delta-maintained) must produce byte-identical rows, and the cheapest way to\n * guarantee that is for them to share the CODE rather than agree by\n * convention. Putting it here also breaks what would otherwise be an import\n * cycle between those two files.\n *\n * @internal — `groupby.ts` re-exports the public names, so the module graph\n * below this file is invisible to consumers.\n */\n\nimport type { ReduceSpec } from './reduction.js'\n\n/**\n * Cardinality thresholds for `.groupBy()`. The warn threshold gives\n * consumers a heads-up before the hard error; the cap is a fixed\n * constant (not overridable). A `{ maxGroups }` override\n * can be added later without a break if a real consumer asks.\n */\nexport const GROUPBY_WARN_CARDINALITY = 10_000\nexport const GROUPBY_MAX_CARDINALITY = 100_000\n\n/**\n * One-shot warning dedup per-field-set — reactive dashboards\n * re-executing the same grouped query should produce the warning\n * once, not once per re-fire. Keyed on the sorted JSON of grouping\n * field names so `.groupBy('a', 'b')` and `.groupBy('b', 'a')`\n * share the same dedup slot (their result tuples are isomorphic).\n */\nconst warnedCardinalityFields = new Set<string>()\n\nexport function warnCardinalityApproaching(\n fields: readonly string[],\n observed: number,\n): void {\n const key = JSON.stringify([...fields].sort())\n if (warnedCardinalityFields.has(key)) return\n warnedCardinalityFields.add(key)\n const label = `[${fields.join(', ')}]`\n console.warn(\n `[noy-db] .groupBy(${label}) produced ${observed} distinct groups, ` +\n `${Math.round((observed / GROUPBY_MAX_CARDINALITY) * 100)}% of the ` +\n `${GROUPBY_MAX_CARDINALITY}-group ceiling. Narrow the query with ` +\n `.where() before grouping, or switch to a lower-cardinality field.`,\n )\n}\n\n/**\n * Test-only: clear the per-field cardinality warning dedup between\n * tests. Production code never calls this — matching the\n * `resetJoinWarnings` pattern in `join.ts`.\n */\nexport function resetGroupByWarnings(): void {\n warnedCardinalityFields.clear()\n}\n\n/** The label a cardinality error names — `\"k\"` single-key, `[a, b]` multi. */\nexport function groupFieldLabel(fields: readonly string[]): string {\n return fields.length === 1 ? fields[0]! : `[${fields.join(', ')}]`\n}\n\n/**\n * Reduce ONE bucket into its output row: the group keys stamped first in\n * declaration order, then every reducer's finalized value.\n *\n * ⭐ The single definition of a grouped row. `groupAndReduce` calls it once per\n * bucket over the whole record set; the incremental maintainer calls it for\n * the buckets a delta touched and reuses the cached row for the rest. Because\n * the fold is `init → step* → finalize` over the SAME records in the SAME\n * order, an incrementally produced row is not merely equal to a re-run's — it\n * is the identical computation.\n */\nexport function reduceGroupRow<R>(\n fields: readonly string[],\n keyValues: Record<string, unknown>,\n records: readonly unknown[],\n spec: ReduceSpec,\n reducerKeys: readonly string[],\n): R {\n const state: Record<string, unknown> = {}\n for (const rk of reducerKeys) {\n state[rk] = spec[rk]!.init()\n }\n for (const record of records) {\n for (const rk of reducerKeys) {\n state[rk] = spec[rk]!.step(state[rk], record)\n }\n }\n // Stamp grouped fields FIRST, in declaration order — this is\n // tested via `Object.keys(row).slice(0, fields.length)`.\n const row: Record<string, unknown> = {}\n for (const f of fields) {\n row[f] = keyValues[f]\n }\n for (const rk of reducerKeys) {\n row[rk] = spec[rk]!.finalize(state[rk])\n }\n return row as unknown as R\n}\n","/**\n * Per-group incremental maintenance for `groupBy().aggregate().live()` —\n * #1341's second half.\n *\n * #1341 shipped delta maintenance for `live()` and for the UNGROUPED\n * `.aggregate().live()`: the match set is patched per change event instead of\n * re-scanned. A grouped live query got none of it — every change re-ran the\n * whole pipeline: scan N records, re-evaluate every clause, re-bucket the\n * whole match set, and re-fold every bucket. This module closes that.\n *\n * ## What is maintained, and what is not\n *\n * Two layers, and only the outer one is new:\n *\n * 1. **The match set** is maintained by `LiveMaintainer` (the #1341 engine),\n * unchanged and un-forked. Membership and snapshot sequence are ITS\n * answers, delegated exactly as the ungrouped path delegates them.\n * 2. **The buckets** are maintained here. A change reaches this layer as a\n * `PatchOutcome` — a record left the set, joined it, or both — and only\n * the one or two buckets it touches are marked dirty. A dirty bucket is\n * re-folded from its own records on the next read; every other bucket\n * serves the row it already computed.\n *\n * ⛔ **Reducer states are NOT patched, deliberately** — the same call the\n * ungrouped path made. The reducer protocol carries an optional `remove()`,\n * and inverting `sum`/`count`/`avg` per delta would make a change O(1) instead\n * of O(bucket). It is not wired, because *inverting a float `sum` does not\n * reproduce a re-run's answer*: `(a + b + c) - b !== a + c` in IEEE-754, so an\n * inverted state would drift from the eager one and the equivalence property\n * this module is built on would be false. `min`/`max` are not invertible at\n * all. Re-folding a dirty bucket from its records is bit-identical to a\n * re-run by construction, and still turns O(matches) per change into\n * O(largest touched bucket).\n *\n * ## The correctness contract\n *\n * `rows()` must equal `groupAndReduce(<the eager record set>, fields, spec)`\n * at every step. Four things buy that, and three of them are group membership\n * transitions a naive per-group patch gets wrong:\n *\n * - **Bucket CONTENTS.** A record's group key is read from the record, so a\n * write that CHANGES the key arrives here as `removed` + `inserted` with\n * the BEFORE record on one side and the AFTER record on the other. It\n * leaves the old bucket and joins the new one. Reading the key off the\n * after-state alone — the obvious shortcut — would leave a ghost row in\n * the old bucket forever.\n * - **Bucket DISAPPEARANCE.** A bucket that loses its last member is\n * deleted, not left empty: `groupAndReduce` never creates a bucket with no\n * records, so an empty bucket would emit a row that a re-run does not.\n * - **Bucket APPEARANCE, in the right PLACE.** Buckets are emitted in\n * first-seen order, which is the order of each bucket's MINIMUM snapshot\n * sequence — not the order buckets happened to be created in. Those differ\n * the moment a group key changes: with records at seq 0 (group A) and\n * seq 1 (group B), rewriting seq 0's key to C makes a re-run emit\n * `[C, B]`, while appending the new bucket would emit `[B, C]`. So each\n * bucket keeps its members ordered by sequence and the emission order is\n * recomputed from `members[0].seq` whenever a membership change could have\n * moved a minimum.\n * - **The key VALUES on the row** come from the bucket's first-seen record,\n * which is `members[0]` — re-read whenever the bucket changes, because the\n * first-seen record itself can leave.\n *\n * ## The fallback\n *\n * Anything not provably patchable rebuilds: a payload-less change event, a\n * plan `canMaintainIncrementally()` refuses (the maintainer is then never\n * built at all), a `LiveMaintainer` that rebuilt underneath us, an error\n * thrown mid-patch, or an internal inconsistency this module refuses to paper\n * over. `stats()` counts both paths so a test can assert WHICH one ran —\n * without that, a fallback that silently swallowed every case would pass every\n * behavioural test while delivering nothing.\n */\n\nimport type {\n GroupMaintenanceSource,\n MaintainedEntry,\n PatchDelta,\n PatchOutcome,\n SourceChange,\n} from '../../kernel/query/live/incremental.js'\nimport { LiveMaintainer } from '../../kernel/query/live/incremental.js'\nimport { readPath } from '../../kernel/query/predicate.js'\nimport { canonicalGroupKey } from './canonical-key.js'\nimport { GroupCardinalityError } from '../../kernel/errors.js'\nimport type { ReduceSpec } from './reduction.js'\nimport {\n GROUPBY_MAX_CARDINALITY,\n GROUPBY_WARN_CARDINALITY,\n groupFieldLabel,\n reduceGroupRow,\n warnCardinalityApproaching,\n} from './group-core.js'\n\n/** Counters exposed by {@link GroupedMaintainer.stats}. */\nexport interface GroupMaintenanceStats {\n /** Change events folded in as a patch. */\n readonly patches: number\n /** Full rebuilds of the bucket map — the fallback path. */\n readonly rebuilds: number\n /** Buckets re-folded. One per dirty bucket per read, plus one per bucket per rebuild. */\n readonly bucketsReduced: number\n /** Records stepped through a reducer. The work a full re-run would do every time. */\n readonly recordsFolded: number\n}\n\ninterface Member {\n readonly seq: number\n readonly record: unknown\n}\n\ninterface Bucket {\n /** Members in ascending snapshot-sequence order — the order a re-run folds them in. */\n members: Member[]\n /** Last computed output row; meaningless while `dirty`. */\n row: unknown\n dirty: boolean\n}\n\n/** Everything the grouped maintainer needs, supplied by `GroupedReduction`. */\nexport interface GroupedMaintainerConfig {\n readonly source: GroupMaintenanceSource\n readonly fields: readonly string[]\n readonly spec: ReduceSpec\n}\n\n/**\n * The maintained bucket map behind one grouped live reduction.\n *\n * Lifecycle mirrors `LiveMaintainer`: `attach()` when the subscription opens,\n * `apply(change)` per upstream event, `rows()` to read, `detach()` on\n * teardown. Before `attach()` (and after any fallback) `rows()` rebuilds from\n * the snapshot, so a detached maintainer is simply an eager executor.\n */\nexport class GroupedMaintainer {\n private readonly inner: LiveMaintainer\n private readonly fields: readonly string[]\n private readonly spec: ReduceSpec\n private readonly reducerKeys: readonly string[]\n private readonly fieldLabel: string\n private readonly project: (record: unknown) => unknown\n\n private buckets = new Map<string, Bucket>()\n /** Dedup keys in emission (first-seen) order. Recomputed when `orderDirty`. */\n private order: string[] = []\n private orderDirty = true\n private stale = true\n private attached = false\n\n private patches = 0\n private rebuilds = 0\n private bucketsReduced = 0\n private recordsFolded = 0\n\n constructor(cfg: GroupedMaintainerConfig) {\n this.fields = cfg.fields\n this.spec = cfg.spec\n this.reducerKeys = Object.keys(cfg.spec)\n this.fieldLabel = groupFieldLabel(cfg.fields)\n const project = cfg.source.project\n this.project = project ? (record: unknown) => project(record) : (record: unknown) => record\n this.inner = new LiveMaintainer({\n snapshotEntries: cfg.source.snapshotEntries,\n lookupById: cfg.source.lookupById,\n matches: cfg.source.matches,\n // Grouping reduces the whole match set in candidate order — it never\n // sorts, offsets, limits or decodes. Same switches the ungrouped\n // `.aggregate()` maintainer runs with.\n offset: 0,\n limit: undefined,\n })\n }\n\n /**\n * Start accepting deltas. Call in the SAME synchronous turn as the initial\n * read — `LiveReduction` computes its first value in its constructor and\n * subscribes immediately after, so attaching there is that turn.\n */\n attach(): void {\n this.attached = true\n this.inner.attach()\n }\n\n /** Stop accepting deltas; every later read rebuilds. */\n detach(): void {\n this.attached = false\n this.inner.detach()\n }\n\n /** Force the next read to rebuild. */\n invalidate(): void {\n this.stale = true\n this.inner.invalidate()\n }\n\n /** Patch/rebuild counters — the observable difference between the two paths. */\n stats(): GroupMaintenanceStats {\n return {\n patches: this.patches,\n rebuilds: this.rebuilds,\n bucketsReduced: this.bucketsReduced,\n recordsFolded: this.recordsFolded,\n }\n }\n\n /**\n * Fold one upstream change into the maintained buckets.\n *\n * The match-set layer runs first and unconditionally — even when THIS layer\n * is stale, keeping the inner maintainer current is what makes the rebuild\n * below cost O(matches) instead of O(collection).\n */\n apply(change: SourceChange | undefined): void {\n let outcome: PatchOutcome\n try {\n outcome = this.inner.apply(change)\n } catch (err) {\n this.stale = true\n throw err\n }\n if (!this.attached || this.stale) return\n if (outcome.kind === 'rebuilt') {\n this.stale = true\n return\n }\n try {\n if (outcome.removed) this.leave(outcome.removed)\n if (outcome.inserted) this.join(outcome.inserted)\n this.patches++\n } catch (err) {\n // A reducer or key read threw mid-patch: the bucket map may be\n // half-updated, so drop it rather than serve rows we cannot vouch for.\n // The rebuild on the next read runs the same code and throws the same\n // way, which is where the consumer sees it.\n this.stale = true\n throw err\n }\n }\n\n /** The current grouped rows — a fresh array on every call. */\n rows(): unknown[] {\n if (!this.attached || this.stale) this.rebuild()\n if (this.buckets.size >= GROUPBY_WARN_CARDINALITY) {\n warnCardinalityApproaching(this.fields, this.buckets.size)\n }\n if (this.orderDirty) {\n // First-seen order === ascending minimum sequence. Sequence numbers are\n // unique, so this is a total order and the sort is deterministic.\n this.order = [...this.buckets.keys()].sort(\n (a, b) => this.buckets.get(a)!.members[0]!.seq - this.buckets.get(b)!.members[0]!.seq,\n )\n this.orderDirty = false\n }\n const out: unknown[] = []\n for (const key of this.order) {\n const bucket = this.buckets.get(key)!\n if (bucket.dirty) {\n bucket.row = this.reduce(bucket)\n bucket.dirty = false\n }\n out.push(bucket.row)\n }\n return out\n }\n\n /**\n * Rebuild every bucket from the maintained match set. Equivalent to the\n * eager path by construction: the inner maintainer hands back exactly the\n * records `executeRecords()` would produce, in exactly that order, and\n * `join()` below is the same bucketing loop `groupAndReduce` runs.\n */\n private rebuild(): void {\n this.rebuilds++\n this.buckets = new Map()\n const entries: readonly MaintainedEntry[] = this.inner.maintainedEntries()\n for (const entry of entries) this.join({ seq: entry.seq, record: entry.record })\n this.orderDirty = true\n this.stale = false\n }\n\n /** A record left the match set, or left one group on its way to another. */\n private leave(delta: PatchDelta): void {\n const record = this.project(delta.record)\n const key = this.dedupKey(record)\n const bucket = this.buckets.get(key)\n if (!bucket) {\n // The record we were told left is not in the bucket we compute for it.\n // Something upstream disagrees with us; refuse to guess.\n this.stale = true\n return\n }\n const at = lowerBoundBySeq(bucket.members, delta.seq)\n if (bucket.members[at]?.seq !== delta.seq) {\n this.stale = true\n return\n }\n bucket.members.splice(at, 1)\n if (bucket.members.length === 0) {\n // A group that loses its last row DISAPPEARS. An empty bucket left in\n // place would emit a row `groupAndReduce` never produces.\n this.buckets.delete(key)\n this.orderDirty = true\n return\n }\n // Losing the first-seen member moves the bucket's minimum sequence, which\n // is what decides where it is emitted — and the key values on its row.\n if (at === 0) this.orderDirty = true\n bucket.dirty = true\n }\n\n /** A record joined the match set, or joined a new group. */\n private join(delta: PatchDelta): void {\n const record = this.project(delta.record)\n const key = this.dedupKey(record)\n let bucket = this.buckets.get(key)\n if (bucket === undefined) {\n if (this.buckets.size >= GROUPBY_MAX_CARDINALITY) {\n throw new GroupCardinalityError(\n this.fieldLabel,\n this.buckets.size + 1,\n GROUPBY_MAX_CARDINALITY,\n )\n }\n // A group that gains its first row APPEARS — but not necessarily last;\n // `orderDirty` sends `rows()` back to minimum-sequence order.\n bucket = { members: [], row: undefined, dirty: true }\n this.buckets.set(key, bucket)\n this.orderDirty = true\n }\n const at = lowerBoundBySeq(bucket.members, delta.seq)\n bucket.members.splice(at, 0, { seq: delta.seq, record })\n if (at === 0) this.orderDirty = true\n bucket.dirty = true\n }\n\n private reduce(bucket: Bucket): unknown {\n const first = bucket.members[0]!.record\n const keyValues: Record<string, unknown> = {}\n for (const f of this.fields) keyValues[f] = readPath(first, f)\n this.bucketsReduced++\n this.recordsFolded += bucket.members.length\n return reduceGroupRow(\n this.fields,\n keyValues,\n bucket.members.map(m => m.record),\n this.spec,\n this.reducerKeys,\n )\n }\n\n private dedupKey(record: unknown): string {\n const keyValues: Record<string, unknown> = {}\n for (const f of this.fields) keyValues[f] = readPath(record, f)\n return canonicalGroupKey(this.fields, keyValues)\n }\n}\n\n/** First index in `members` whose sequence is not below `seq`. */\nfunction lowerBoundBySeq(members: readonly Member[], seq: number): number {\n let lo = 0\n let hi = members.length\n while (lo < hi) {\n const mid = (lo + hi) >>> 1\n if (members[mid]!.seq < seq) lo = mid + 1\n else hi = mid\n }\n return lo\n}\n","/**\n * Query DSL `.groupBy()` —.\n *\n * Chains after `.where()` / `.filter()` / `.or()` / `.and()` on a\n * Query and before a reducer spec, so consumers can compute\n * per-bucket aggregates without folding in userland:\n *\n * ```ts\n * const byClient = invoices.query()\n * .where('status', '==', 'open')\n * .groupBy('clientId')\n * .aggregate({ total: sum('amount'), n: count() })\n * .run()\n * // → [ { clientId: 'c1', total: 5250, n: 3 }, … ]\n * ```\n *\n * Execution pipeline:\n *\n * 1. Run the query's where/filter clauses (same candidate /\n * filter pipeline as `.aggregate()` directly on Query).\n * 2. Partition the matching records into buckets keyed by\n * `readPath(record, field)`. JS `Map` preserves insertion\n * order, so the first-seen key for a bucket determines its\n * position in the result array — consumers who want a\n * specific ordering should `.sort()` downstream.\n * 3. Enforce cardinality: warn once per field at 10% of the cap\n * (10_000 buckets), throw `GroupCardinalityError` at 100% of\n * the cap (100_000 buckets).\n * 4. For each bucket, build a per-group reducer state and\n * step every record in the bucket through it.\n * 5. Emit one result row per bucket, shaped as\n * `{ [field]: key, ...reduced }`.\n *\n * **Null / undefined keys:** `Map` distinguishes `null` from\n * `undefined`, so records with a missing group field get their own\n * bucket, and records with an explicit `null` value get a separate\n * bucket from that. Consumers who want them merged can coalesce\n * upstream with `.filter()`.\n *\n * **Live mode:** `.groupBy().aggregate().live()` maintains its buckets\n * incrementally (#1341, grouped half). A change event patches the match set\n * and then re-folds only the one or two buckets it touched; every other bucket\n * serves the row it already computed. See `incremental-group.ts` — including\n * why reducer states are re-folded rather than inverted through the protocol's\n * `remove()` hook. A plan `canMaintainIncrementally()` refuses, and any\n * notification arriving without a delta, still re-runs the whole pipeline.\n *\n * **Type-level stable-key narrowing:** when\n * `dictKey` lands, `groupBy<DictField>()` will narrow the group key\n * type to the stable dictionary key rather than the resolved locale\n * label. That prevents grouping by the locale-resolved label,\n * which would produce different buckets per reader. types the\n * key as `unknown` at the result shape; the dictKey narrowing\n * layers on top without an API break.\n *\n * Partition-awareness seam: when partitioned collections land,\n * per-partition grouping will need to merge sub-results across\n * partitions. The reducer protocol's `{ seed }` parameter\n * (already plumbed through in `reducers.ts`) is the mechanism —\n * groupBy doesn't need its own seam for the moment, because it\n * delegates to the reducer protocol for all per-bucket state.\n */\n\nimport { readPath } from '../../kernel/query/predicate.js'\nimport type {\n ReduceSpec,\n ReduceResult,\n ReductionUpstream,\n LiveReduction,\n} from './reduction.js'\nimport { buildLiveReduction } from './reduction.js'\nimport type { ReducerBuilder } from './reducers.js'\nimport { bindDistinctReducers, reducerBuilder } from './reducers.js'\nimport { canonicalGroupKey } from './canonical-key.js'\nimport { GroupCardinalityError } from '../../kernel/errors.js'\nimport {\n GROUPBY_MAX_CARDINALITY,\n GROUPBY_WARN_CARDINALITY,\n groupFieldLabel,\n reduceGroupRow,\n warnCardinalityApproaching,\n} from './group-core.js'\nimport { GroupedMaintainer } from './incremental-group.js'\nimport type { GroupMaintenanceStats } from './incremental-group.js'\nimport type { GroupMaintenanceSource, SourceChange } from '../../kernel/query/live/incremental.js'\nimport type { MoneyDescriptor } from '../../via/money/descriptor.js'\nimport type { ViaPipeline } from '../../kernel/via/pipeline.js'\nimport { viaBinder } from '../../kernel/via/index.js'\nimport { applyI18nLocale, type I18nTextDescriptor } from '../../via/i18n/core.js'\n\n/**\n * The cardinality guards and the warning-reset hook live in `group-core.ts`\n * — shared verbatim with the incremental maintainer so the eager and\n * delta-maintained paths cannot enforce different caps — and are re-exported\n * here so every existing import site is unchanged.\n */\nexport {\n GROUPBY_WARN_CARDINALITY,\n GROUPBY_MAX_CARDINALITY,\n resetGroupByWarnings,\n} from './group-core.js'\n\n/**\n * Result row shape for a grouped reduction. Each row carries the\n * group key value under the grouping field name plus every reducer\n * output from the spec.\n *\n * types the group key as `unknown` at the result shape — the\n * runtime read via `readPath` can return any value, and narrowing\n * to a specific type would require the caller to assert at the\n * call site. `dictKey` narrowing layers on top of this by\n * adding an overload that constrains `F` when the grouping field\n * is a `dictKey`.\n */\nexport type GroupedRow<F extends string, R> = { [K in F]: unknown } & R\n\n/**\n * Multi-key variant — result-row shape for variadic\n * `.groupBy(...fields)`. Every grouped field name appears on the row\n * (typed as `unknown` for the same reason as `GroupedRow`), plus the\n * reducer outputs from the spec.\n */\nexport type GroupedRowN<F extends readonly string[], R> =\n { [K in F[number]]: unknown } & R\n\n/**\n * Shared base class for the chainable grouped-query wrappers. Holds\n * the constructor + protected fields that both single-key\n * `GroupedQuery<T, F>` and variadic `GroupedQueryN<T, F>` need; each\n * subclass only overrides `aggregate()` with its own result-row\n * generic.\n *\n * Not exported — implementation detail. Adding `.having()` /\n * `.live()` / `.orderByGroup()` etc. in the future lands here once\n * and both subclasses pick it up automatically.\n *\n * @internal\n */\nabstract class GroupedQueryBase {\n /**\n * Field set this grouped query buckets on. Stored in declaration\n * order — the same order is preserved on every result row by\n * `groupAndReduce`. For the single-field constructor, this is\n * `[field]`.\n */\n protected readonly fields: readonly string[]\n\n constructor(\n protected readonly executeRecords: () => readonly unknown[],\n fieldOrFields: string | readonly string[],\n protected readonly upstreams: readonly ReductionUpstream[],\n /**\n * Optional dict label resolver attached by the query builder when\n * the grouping field is a dictKey. Variadic groupings always pass\n * `undefined` — `<field>Label` projection has no meaningful shape\n * for composite keys.\n */\n protected readonly dictLabelResolver?: (\n key: string,\n locale: string,\n fallback?: string | readonly string[],\n ) => Promise<string | undefined>,\n /**\n * The backing collection's compiled Via pipeline — used to rewrite\n * `sum`/`min`/`max` over Via-covered fields (e.g. money) into exact\n * BigInt reducers when `.aggregate(spec)` is terminated.\n */\n protected readonly via?: ViaPipeline,\n /**\n * The #1341 delta-maintenance seam, supplied by `Query.groupBy()` when the\n * plan admits incremental maintenance and withheld when it does not.\n * `undefined` is the pre-#1341 behaviour: `.live()` re-runs in full.\n */\n protected readonly maintenance?: GroupMaintenanceSource,\n ) {\n this.fields =\n typeof fieldOrFields === 'string' ? [fieldOrFields] : [...fieldOrFields]\n }\n\n /** Apply Via-aware reducer rewriting (e.g. money) when the source declares one. */\n protected wrapSpec<Spec extends ReduceSpec>(spec: Spec): Spec {\n // #1347 — `countDistinct` is rebound to the collection's index-key\n // canonicalizer here too, so a grouped distinct count agrees with an\n // ungrouped one over the same Via-covered field.\n return bindDistinctReducers(this.via ? this.via.wrapReducers(spec) : spec, this.via)\n }\n}\n\n/**\n * Chainable wrapper returned by `Query.groupBy(field)`. Terminates\n * with `.aggregate(spec)` which returns a `GroupedReduction`.\n *\n * Kept minimal — the only operation on a grouped query is\n * reduction. Ordering, limiting and further filtering of the\n * REDUCED rows live one step further along the chain, on the\n * `GroupedReduction` that `.aggregate()` returns (`.having()`,\n * `.orderBy()`, `.limit()` — #1336); ordering and limiting of the\n * SOURCE RECORDS stays on the underlying `Query`, before\n * `.groupBy()`. The two are different operations and neither\n * substitutes for the other.\n */\nexport class GroupedQuery<T, F extends string, S extends keyof T = never, M extends keyof T & string = never> extends GroupedQueryBase {\n /**\n * Build a grouped reduction. Returns a `GroupedReduction`\n * with `.run()`, `.runAsync()`, and `.live()` terminals — same shape\n * as the non-grouped `.aggregate()` wrapper, just with an array\n * result (one row per bucket) instead of a single reduced object.\n *\n * The builder overload `aggregate(b => spec)` types `b` as\n * `ReducerBuilder<T, S, M>`, so field-taking reducers (`sum`, `avg`,\n * `min`, `max`) refuse any field listed in the collection's\n * `sensitive` option at compile time, and `sum`/`min`/`max` over a\n * declared `moneyFields` (`M`) member return a `MoneyString`. The\n * bare-spec overload is preserved for backward compatibility.\n */\n aggregate<Spec extends ReduceSpec>(spec: Spec): GroupedReduction<GroupedRow<F, ReduceResult<Spec>>>\n aggregate<Spec extends ReduceSpec>(build: (b: ReducerBuilder<T, S, M>) => Spec): GroupedReduction<GroupedRow<F, ReduceResult<Spec>>>\n aggregate<Spec extends ReduceSpec>(\n specOrBuild: Spec | ((b: ReducerBuilder<T, S, M>) => Spec),\n ): GroupedReduction<GroupedRow<F, ReduceResult<Spec>>> {\n const spec: Spec = typeof specOrBuild === 'function'\n ? (specOrBuild as (b: ReducerBuilder<T, S, M>) => Spec)(reducerBuilder as unknown as ReducerBuilder<T, S, M>)\n : specOrBuild\n // T is phantom on the wrapper so consumers can still see the\n // source row type on hover. Reference it to keep lint quiet.\n void undefined as T | undefined\n return new GroupedReduction<GroupedRow<F, ReduceResult<Spec>>>(\n this.executeRecords,\n this.fields,\n this.wrapSpec(spec),\n this.upstreams,\n this.dictLabelResolver,\n NO_POST_GROUP,\n this.maintenance,\n )\n }\n}\n\n/**\n * Variadic-keyed sibling of `GroupedQuery<T, F>`. Constructed by the\n * multi-arg `Query.groupBy(...fields)` overload. The runtime shape is\n * identical — only the type-level result-row narrowing differs.\n */\nexport class GroupedQueryN<T, F extends readonly string[], S extends keyof T = never, M extends keyof T & string = never> extends GroupedQueryBase {\n aggregate<Spec extends ReduceSpec>(spec: Spec): GroupedReduction<GroupedRowN<F, ReduceResult<Spec>>>\n aggregate<Spec extends ReduceSpec>(build: (b: ReducerBuilder<T, S, M>) => Spec): GroupedReduction<GroupedRowN<F, ReduceResult<Spec>>>\n aggregate<Spec extends ReduceSpec>(\n specOrBuild: Spec | ((b: ReducerBuilder<T, S, M>) => Spec),\n ): GroupedReduction<GroupedRowN<F, ReduceResult<Spec>>> {\n const spec: Spec = typeof specOrBuild === 'function'\n ? (specOrBuild as (b: ReducerBuilder<T, S, M>) => Spec)(reducerBuilder as unknown as ReducerBuilder<T, S, M>)\n : specOrBuild\n void undefined as T | undefined\n return new GroupedReduction<GroupedRowN<F, ReduceResult<Spec>>>(\n this.executeRecords,\n this.fields,\n this.wrapSpec(spec),\n this.upstreams,\n this.dictLabelResolver,\n NO_POST_GROUP,\n this.maintenance,\n )\n }\n}\n\n/**\n * Execute the group-and-reduce pipeline. Pure function over a\n * record array and a spec — shared by `GroupedReduction.run()`\n * and the live-mode refresh path. Exported for tests and for any\n * future `scan().groupBy().aggregate()` reuse.\n *\n * Enforces the cardinality cap incrementally during the partition\n * loop, so a runaway grouping throws at the moment the 100_001st\n * bucket would be created — the consumer doesn't have to wait for\n * the full partition to materialize before the error fires.\n */\nexport function groupAndReduce<R>(\n records: readonly unknown[],\n fieldOrFields: string | readonly string[],\n spec: ReduceSpec,\n moneyFields?: Record<string, MoneyDescriptor>,\n): R[] {\n const fields: readonly string[] =\n typeof fieldOrFields === 'string' ? [fieldOrFields] : fieldOrFields\n if (fields.length === 0) {\n throw new Error('.groupBy() requires at least one field')\n }\n\n // Money-aware reduction: when the caller declares money descriptors\n // for output/intermediate fields, rewrite any `sum`/`min`/`max` over\n // them into exact BigInt reducers before bucketing. Omitted → spec\n // passes through unchanged (backward compatible). The chainable\n // `GroupedQuery` path already wraps upstream via `wrapSpec`; this\n // covers direct `groupAndReduce` callers (UNION-form MVs) that have\n // no Query wrapper to do it. Builds a transient money binding via the\n // kernel's Via port rather than a Query-attached pipeline — `moneyFields`\n // here is the MV spec's OWN descriptor map, not a collection's.\n if (moneyFields) {\n const binding = viaBinder('money')({ moneyFields })\n spec = binding.wrapReducers!(spec) as ReduceSpec\n // #1347 — same binding, the other half: `countDistinct` over a declared\n // money field must dedup on the BigInt-normalized scaled int, or a UNION\n // MV counts `'0100'` and `'100'` as two values of one amount.\n spec = bindDistinctReducers(spec, {\n canonicalizeIndexKey: (f, v) => binding.canonicalizeIndexKey?.(f, v),\n })\n }\n\n // Bucket value is { keyValues, records } so the output row can stamp\n // every grouped field in DECLARATION ORDER. Map preserves insertion\n // order natively (ES2015), so first-seen keys determine ordering.\n interface Bucket {\n keyValues: Record<string, unknown>\n records: unknown[]\n }\n const buckets = new Map<string, Bucket>()\n // Field-label string for error messages — matches the variadic\n // surface (`[a, b]` for multi-key, `\"k\"` for single-key back-compat).\n const fieldLabel = groupFieldLabel(fields)\n\n for (const record of records) {\n // Read each field's value into a row object, then canonicalise.\n const keyValues: Record<string, unknown> = {}\n for (const f of fields) {\n keyValues[f] = readPath(record, f)\n }\n const dedupKey = canonicalGroupKey(fields, keyValues)\n let bucket = buckets.get(dedupKey)\n if (bucket === undefined) {\n if (buckets.size >= GROUPBY_MAX_CARDINALITY) {\n throw new GroupCardinalityError(\n fieldLabel,\n buckets.size + 1,\n GROUPBY_MAX_CARDINALITY,\n )\n }\n bucket = { keyValues, records: [] }\n buckets.set(dedupKey, bucket)\n }\n bucket.records.push(record)\n }\n\n if (buckets.size >= GROUPBY_WARN_CARDINALITY) {\n warnCardinalityApproaching(fields, buckets.size)\n }\n\n // Reduce each bucket through the spec — `reduceGroupRow` is the SAME fold\n // the incremental maintainer runs for a dirty bucket, which is what makes an\n // incrementally maintained row identical to this one rather than merely\n // equal to it. `Object.keys(spec)` is hoisted out of the loop; calling\n // `reduceRecords` per bucket would recompute it per bucket.\n const reducerKeys = Object.keys(spec)\n const out: R[] = []\n for (const bucket of buckets.values()) {\n out.push(reduceGroupRow<R>(fields, bucket.keyValues, bucket.records, spec, reducerKeys))\n }\n return out\n}\n\n/**\n * The post-group stage (#1336): `having` predicates, an ordering spec over the\n * reduced rows, and a row cap. Immutable — every builder method returns a new\n * `GroupedReduction` carrying a new `PostGroup`.\n *\n * @internal — not exported; `GroupedReduction`'s public signatures name only\n * inline function/union types, so no consumer needs this shape.\n */\ninterface PostGroup {\n readonly having: readonly ((row: unknown) => boolean)[]\n readonly orderBy: readonly { readonly key: string; readonly direction: 'asc' | 'desc' }[]\n readonly limit: number | undefined\n}\n\nconst NO_POST_GROUP: PostGroup = { having: [], orderBy: [], limit: undefined }\n\n/**\n * Decimal-numeral test for the post-group comparator. Matches the exact\n * canonical decimal strings a Via-dressed reducer finalizes to — money's\n * `sum`/`min`/`max` return `'10004.00'`, not a number and not a formatted,\n * grouped-and-symbolised label.\n */\nconst DECIMAL_NUMERAL = /^[+-]?\\d+(\\.\\d+)?$/\n\n/**\n * Compare two REDUCED values for post-group ordering.\n *\n * Deliberately NOT the row-pipeline comparator in `kernel/query/builder.ts`,\n * and one rule apart from it: when both sides are strings that are plain\n * decimal numerals, they compare by MAGNITUDE. That rule exists for exactly\n * one reason — a money `sum` finalizes to an exact decimal string, and lexical\n * order gets it wrong in the ordinary case (`'9882.00' > '10004.00'`). The\n * pre-group path solves the same problem by asking the Via pipeline\n * (`compareForOrder`), which cannot serve here: it reads the STORED\n * scaled-integer form, and a reduced value is already decoded to decimal.\n *\n * The divergence is confined to a surface introduced by #1336 — no pre-group\n * ordering changes — and it only reaches values that are numerals end to end,\n * so a group key like `'c1'` still sorts lexically.\n * ⭐ SHARED, not private: `.window()`'s in-partition ordering (#1349) faces the\n * identical exposure over the identical values — its rows are decoded, so a\n * money field is a decimal string there too — and imports this rather than\n * growing a second rule that could drift from it.\n *\n * @internal\n */\nexport function compareReduced(a: unknown, b: unknown): number {\n // Nullish last in asc order — same convention as the row pipeline.\n if (a === undefined || a === null) return b === undefined || b === null ? 0 : 1\n if (b === undefined || b === null) return -1\n if (typeof a === 'number' && typeof b === 'number') return a - b\n if (typeof a === 'bigint' && typeof b === 'bigint') return a < b ? -1 : a > b ? 1 : 0\n if (typeof a === 'string' && typeof b === 'string') {\n if (DECIMAL_NUMERAL.test(a) && DECIMAL_NUMERAL.test(b)) {\n const an = Number(a)\n const bn = Number(b)\n // Number() is lossy past 2^53; fall through to the lexical branch rather\n // than order two indistinguishable floats arbitrarily.\n if (an !== bn) return an < bn ? -1 : 1\n }\n return a < b ? -1 : a > b ? 1 : 0\n }\n if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime()\n // Mixed / unsupported: equal, so the sort stays stable. Same choice the row\n // pipeline makes.\n return 0\n}\n\n/**\n * Apply the post-group stage to a reduced row array, in the order the docs\n * promise: `having` (all predicates ANDed) → `orderBy` (successive calls are\n * tie-breakers, stable) → `limit`.\n */\nfunction applyPostGroup<R>(rows: R[], post: PostGroup): R[] {\n let out = rows\n for (const pred of post.having) {\n out = out.filter((row) => pred(row))\n }\n if (post.orderBy.length > 0) {\n // Array.prototype.sort has been stable since ES2019, so bucket\n // first-seen order survives as the final tie-break.\n out = [...out].sort((x, y) => {\n for (const { key, direction } of post.orderBy) {\n const cmp = compareReduced(\n (x as Record<string, unknown>)[key],\n (y as Record<string, unknown>)[key],\n )\n if (cmp !== 0) return direction === 'asc' ? cmp : -cmp\n }\n return 0\n })\n }\n if (post.limit !== undefined && post.limit < out.length) out = out.slice(0, post.limit)\n return out\n}\n\n/**\n * Grouped reduction wrapper — the `.groupBy(field).aggregate(spec)`\n * terminal. Shape mirrors `Reduction<R>` from aggregate.ts: two\n * terminals (`.run()` and `.live()`), spec bound at construction\n * time, upstreams collected for live mode.\n *\n * The generic `R` is the per-row result shape (i.e. a single\n * grouped row), and the terminals return `R[]` — one row per\n * bucket.\n *\n * `.having()` / `.orderBy()` / `.limit()` (#1336) post-process that array.\n * ⛔ **They do not appear in `Query.explain()` (#1348), and that is not an\n * omission.** `explain()` is a terminal on `Query`; `.groupBy()` leaves\n * `Query` for `GroupedQuery` and then `GroupedReduction`, so by the time these\n * three are reachable there is no `explain()` in the chain to add a node to.\n * Adding one would mean putting `explain()` on `GroupedReduction` — a new\n * surface, and a plan for a stage with nothing to choose: `having`/`orderBy`/\n * `limit` here have exactly one dispatch (a filter, a stable sort, a slice)\n * over rows already in memory. File an issue if a real consumer wants it.\n * ⚠️ They are POST-processing, never a memory optimization: the group pass has\n * already built and reduced every bucket by the time a `having` predicate is\n * called, so `GROUPBY_WARN_CARDINALITY` / `GROUPBY_MAX_CARDINALITY` see the\n * UNFILTERED bucket count and `having` cannot buy headroom under them. Narrow\n * with `.where()` before `.groupBy()` for that.\n */\n/**\n * What `GroupedReduction.live()` returns: a `LiveReduction` plus one window\n * onto how it is being kept up to date (#1341).\n */\nexport interface LiveGroupedReduction<R> extends LiveReduction<R> {\n /**\n * Delta-maintenance counters for this live reduction, or `undefined` when\n * the plan was refused and every change re-runs the whole grouping.\n *\n * `patches` counts change events folded in per group; `rebuilds` counts\n * falls back to a full bucket rebuild. A live reduction that reports a\n * maintainer but never patches is a live reduction whose fallback is\n * swallowing everything — which is exactly the failure this exists to make\n * visible.\n */\n maintenanceStats(): GroupMaintenanceStats | undefined\n}\n\nexport class GroupedReduction<R> {\n private readonly fields: readonly string[]\n\n constructor(\n private readonly executeRecords: () => readonly unknown[],\n fields: string | readonly string[],\n private readonly spec: ReduceSpec,\n private readonly upstreams: readonly ReductionUpstream[],\n /**\n * Optional dict label resolver for `<field>Label` projection\n *. Present when the grouping field is a dictKey.\n */\n private readonly dictLabelResolver?: (\n key: string,\n locale: string,\n fallback?: string | readonly string[],\n ) => Promise<string | undefined>,\n /**\n * The post-group stage (#1336). Optional and defaulted so every existing\n * construction site — `GroupedQuery.aggregate()`, `GroupedQueryN`, the MV\n * executor — is unchanged.\n */\n private readonly post: PostGroup = NO_POST_GROUP,\n /**\n * The #1341 delta-maintenance seam (see `GroupedQueryBase`). Present only\n * for a plan `canMaintainIncrementally()` admits.\n */\n private readonly maintenance?: GroupMaintenanceSource,\n ) {\n this.fields = typeof fields === 'string' ? [fields] : [...fields]\n }\n\n /** Clone with a replaced post-group stage. */\n private withPost(post: PostGroup): GroupedReduction<R> {\n return new GroupedReduction<R>(\n this.executeRecords,\n this.fields,\n this.spec,\n this.upstreams,\n this.dictLabelResolver,\n post,\n this.maintenance,\n )\n }\n\n /**\n * Keep only the reduced rows a predicate accepts — SQL's `HAVING` (#1336).\n *\n * ```ts\n * invoices.query()\n * .groupBy('clientId')\n * .aggregate({ total: sum('amount') })\n * .having(r => (r.total as number) > 10_000)\n * .orderBy('total', 'desc')\n * .limit(20)\n * .run()\n * ```\n *\n * The predicate sees the WHOLE reduced row — group keys (including a\n * `dateTrunc()`-derived one) and reducer outputs alike — with each value in\n * its exact reduced form: a money `sum` arrives as its canonical decimal\n * string (`'10004.00'`), never as a locale-formatted label, so comparing on\n * it is exact. Successive calls AND.\n *\n * ⚠️ Not a memory optimization. See the class docs — the buckets exist\n * already; `having` only decides what is returned.\n */\n having(predicate: (row: R) => boolean): GroupedReduction<R> {\n return this.withPost({\n ...this.post,\n having: [...this.post.having, predicate as (row: unknown) => boolean],\n })\n }\n\n /**\n * Order the REDUCED rows by one of their keys (#1336). Successive calls are\n * tie-breakers; the sort is stable, so bucket first-seen order breaks a\n * final tie.\n *\n * ⭐ Distinguished from `Query.orderBy()` by POSITION, not by name: this one\n * exists only after `.aggregate()` and sorts result rows by a reduced key or\n * a group key; `Query.orderBy()` exists only before `.groupBy()` and sorts\n * SOURCE RECORDS, which (via `.limit()`) changes which records are grouped\n * at all. Both may appear in one chain and they do not interfere.\n */\n orderBy(key: string, direction: 'asc' | 'desc' = 'asc'): GroupedReduction<R> {\n return this.withPost({\n ...this.post,\n orderBy: [...this.post.orderBy, { key, direction }],\n })\n }\n\n /**\n * Cap the number of reduced rows returned (#1336) — applied AFTER `having`\n * and `orderBy`, so `.orderBy('total', 'desc').limit(20)` is a top-20.\n *\n * A later call replaces an earlier one.\n */\n limit(n: number): GroupedReduction<R> {\n if (!Number.isInteger(n) || n < 0) {\n throw new Error(`.limit(${n}): a post-group limit must be a non-negative integer.`)\n }\n return this.withPost({ ...this.post, limit: n })\n }\n\n /**\n * Execute the query, group, reduce, and return an array of rows.\n *\n * `opts` (query-form MV grouping): when a `locale` + `i18nFields` are\n * given, the declared group-key `i18nText` fields are resolved to that locale\n * at the `mv` layer BEFORE bucketing — so an i18n group key is a stable string\n * instead of a raw `{locale}` map. The MV executor passes the MV's\n * `i18nLocale`/`i18nFields`; ordinary `.run()` callers pass nothing and are\n * unaffected.\n */\n run(opts?: { locale?: string; i18nFields?: Record<string, I18nTextDescriptor> }): R[] {\n let records = this.executeRecords()\n if (opts?.locale !== undefined && opts.i18nFields !== undefined) {\n const groupI18n: Record<string, I18nTextDescriptor> = {}\n for (const f of this.fields) {\n const d = opts.i18nFields[f]\n if (d !== undefined) groupI18n[f] = d\n }\n if (Object.keys(groupI18n).length > 0) {\n records = records.map((r) => applyI18nLocale(r as Record<string, unknown>, groupI18n, opts.locale!, undefined, 'mv'))\n }\n }\n return applyPostGroup(groupAndReduce<R>(records, this.fields, this.spec), this.post)\n }\n\n /**\n * Execute the query, group, reduce, and resolve `<field>Label` for\n * each result row when the grouping field is a `dictKey` and a\n * `locale` is provided. Returns `R[]` synchronously when\n * no locale is specified (identical to `.run()`).\n *\n * The `<field>Label` field is appended to each row. Rows whose group\n * key has no dictionary entry get `<field>Label: undefined`.\n *\n * Dict-label resolution is single-field only — multi-key groupings\n * do not produce a `<field>Label`. The resolver is only attached\n * by the builder when `fields.length === 1`.\n */\n async runAsync(opts?: {\n locale?: string\n fallback?: string | readonly string[]\n }): Promise<R[]> {\n // Post-group ops run BEFORE label resolution: `having`/`orderBy` address\n // the reduced keys, which exist already, and resolving a `<field>Label`\n // for a row that `having` then discards would be wasted async work.\n const rows = applyPostGroup(\n groupAndReduce<R>(this.executeRecords(), this.fields, this.spec),\n this.post,\n )\n if (!opts?.locale || !this.dictLabelResolver || this.fields.length !== 1) return rows\n\n const resolve = this.dictLabelResolver\n const locale = opts.locale\n const fallback = opts.fallback\n const field = this.fields[0]!\n const labelKey = `${field}Label`\n\n return Promise.all(\n rows.map(async (row) => {\n const key = (row as Record<string, unknown>)[field]\n if (typeof key !== 'string') return row\n const label = await resolve(key, locale, fallback)\n return { ...(row as Record<string, unknown>), [labelKey]: label } as unknown as R\n }),\n )\n }\n\n /**\n * Build a reactive `LiveReduction<R[]>` that updates whenever any upstream\n * source notifies of a change. Same error-isolation and idempotent-stop\n * contract as `Reduction.live()` — the implementation delegates to the same\n * `LiveAggregationImpl` class by threading a fresh recompute closure through\n * the existing constructor.\n *\n * **Incremental per-group maintenance (#1341, grouped half).** When\n * `Query.groupBy()` supplied a maintenance seam — a plan\n * `canMaintainIncrementally()` admits, over a source that can hand back a\n * snapshot and an id lookup — a change no longer re-runs the pipeline. The\n * delta patches the match set, then patches the ONE OR TWO buckets it\n * touches; every other bucket serves the row it already computed. See\n * `incremental-group.ts` for the correctness argument, including the three\n * membership transitions (a record changing group, a group emptying, a group\n * appearing) that a naive per-group patch gets wrong.\n *\n * Every other plan, and every notification that arrives without a delta,\n * re-runs the whole grouping exactly as before. Either way the emitted rows\n * are identical to `.run()`'s.\n *\n * ⚠️ `.run()` is deliberately NOT served from the maintained state: it is a\n * one-shot terminal that may be called long after a `.live()` was stopped,\n * and reading the snapshot is the only answer that cannot be stale.\n *\n * Always call `live.stop()` when finished.\n */\n live(): LiveGroupedReduction<R[]> {\n const maintainer = this.maintenance\n ? new GroupedMaintainer({\n source: this.maintenance,\n fields: this.fields,\n spec: this.spec,\n })\n : undefined\n if (!maintainer) {\n const recompute = (): R[] =>\n applyPostGroup(\n groupAndReduce<R>(this.executeRecords(), this.fields, this.spec),\n this.post,\n )\n return withStats(buildLiveReduction<R[]>(recompute, this.upstreams), undefined)\n }\n\n const recompute = (): R[] => applyPostGroup(maintainer.rows() as R[], this.post)\n // The maintainer folds the delta in BEFORE the reduction reads, which is\n // why the upstream is wrapped rather than subscribed separately —\n // callback order would otherwise decide whether the read saw the change.\n const upstreams: readonly ReductionUpstream[] = this.upstreams.map(upstream => ({\n subscribe: (cb: () => void) => {\n maintainer.attach()\n const unsubscribe = upstream.subscribe((change?: SourceChange) => {\n // A reducer or predicate that throws must not escape into the\n // emitter — the maintainer drops its state and the recompute below\n // raises the same error where `LiveReduction` can catch it.\n try {\n maintainer.apply(change)\n } catch {\n maintainer.invalidate()\n }\n cb()\n })\n // Detach on teardown: a maintainer with no subscription feeding it\n // would go quietly out of date.\n return () => {\n maintainer.detach()\n unsubscribe()\n }\n },\n }))\n return withStats(buildLiveReduction<R[]>(recompute, upstreams), maintainer)\n }\n}\n\n/**\n * Stamp the #1341 maintenance counters onto a live reduction.\n *\n * ⭐ The fallback has to be OBSERVABLE, not merely correct: a\n * correctness-preserving fallback that silently swallowed every case would\n * pass every behavioural test while delivering nothing. `maintenanceStats()`\n * is how a caller — and every test in `query-grouped-incremental*.test.ts` —\n * asks which path actually ran.\n */\nfunction withStats<R>(\n live: LiveReduction<R>,\n maintainer: GroupedMaintainer | undefined,\n): LiveGroupedReduction<R> {\n return Object.assign(live, {\n maintenanceStats: (): GroupMaintenanceStats | undefined => maintainer?.stats(),\n })\n}\n"],"mappings":"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","names":["recompute"]}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MaintenanceMethods
|
|
3
|
+
} from "./chunk-FFJFE4T7.js";
|
|
4
|
+
import {
|
|
5
|
+
installMethods
|
|
6
|
+
} from "./chunk-F6NCB7KT.js";
|
|
7
|
+
import {
|
|
8
|
+
Query
|
|
9
|
+
} from "./chunk-AL6ML4LA.js";
|
|
10
|
+
import {
|
|
11
|
+
gateTerminal
|
|
12
|
+
} from "./chunk-FOEDQATO.js";
|
|
13
|
+
|
|
14
|
+
// src/kernel/query/live/live.ts
|
|
15
|
+
function buildLiveQuery(recompute, upstreams, options) {
|
|
16
|
+
return new LiveQueryImpl(recompute, upstreams, options);
|
|
17
|
+
}
|
|
18
|
+
var LiveQueryImpl = class {
|
|
19
|
+
constructor(recompute, upstreams, options) {
|
|
20
|
+
this.recompute = recompute;
|
|
21
|
+
this.maintainer = options?.maintainer;
|
|
22
|
+
this.batch = options?.batch === true;
|
|
23
|
+
this.maintainer?.attach();
|
|
24
|
+
this.refresh();
|
|
25
|
+
for (const upstream of upstreams) {
|
|
26
|
+
try {
|
|
27
|
+
this.unsubs.push(upstream.subscribe(this.onUpstreamChange));
|
|
28
|
+
} catch (err) {
|
|
29
|
+
this._error = err instanceof Error ? err : new Error(String(err));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
recompute;
|
|
34
|
+
_value = [];
|
|
35
|
+
_error = null;
|
|
36
|
+
listeners = /* @__PURE__ */ new Set();
|
|
37
|
+
unsubs = [];
|
|
38
|
+
stopped = false;
|
|
39
|
+
maintainer;
|
|
40
|
+
batch;
|
|
41
|
+
queued = [];
|
|
42
|
+
flushScheduled = false;
|
|
43
|
+
get value() {
|
|
44
|
+
return this._value;
|
|
45
|
+
}
|
|
46
|
+
get error() {
|
|
47
|
+
return this._error;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Bound change handler — used as the callback passed to every
|
|
51
|
+
* upstream's subscribe. Bound via class field so the `this`
|
|
52
|
+
* context survives the indirect call from arbitrary upstreams.
|
|
53
|
+
*/
|
|
54
|
+
onUpstreamChange = (change) => {
|
|
55
|
+
if (this.batch) {
|
|
56
|
+
this.queued.push(change);
|
|
57
|
+
if (!this.flushScheduled) {
|
|
58
|
+
this.flushScheduled = true;
|
|
59
|
+
queueMicrotask(this.flush);
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.absorb([change]);
|
|
64
|
+
this.notify();
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Drain a coalesced burst: every queued delta is folded in, then the value
|
|
68
|
+
* is read ONCE and listeners are notified ONCE.
|
|
69
|
+
*/
|
|
70
|
+
flush = () => {
|
|
71
|
+
this.flushScheduled = false;
|
|
72
|
+
const batch = this.queued;
|
|
73
|
+
this.queued = [];
|
|
74
|
+
if (this.stopped) return;
|
|
75
|
+
this.absorb(batch);
|
|
76
|
+
this.notify();
|
|
77
|
+
};
|
|
78
|
+
absorb(changes) {
|
|
79
|
+
if (this.stopped) return;
|
|
80
|
+
if (this.maintainer) {
|
|
81
|
+
try {
|
|
82
|
+
for (const change of changes) this.maintainer.apply(change);
|
|
83
|
+
} catch {
|
|
84
|
+
this.maintainer.invalidate();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
this.refresh();
|
|
88
|
+
}
|
|
89
|
+
notify() {
|
|
90
|
+
for (const cb of this.listeners) {
|
|
91
|
+
try {
|
|
92
|
+
cb();
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
refresh() {
|
|
98
|
+
if (this.stopped) return;
|
|
99
|
+
try {
|
|
100
|
+
this._value = this.maintainer ? this.maintainer.rows() : this.recompute();
|
|
101
|
+
this._error = null;
|
|
102
|
+
} catch (err) {
|
|
103
|
+
this._error = err instanceof Error ? err : new Error(String(err));
|
|
104
|
+
this.maintainer?.invalidate();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
subscribe(cb) {
|
|
108
|
+
if (this.stopped) return () => {
|
|
109
|
+
};
|
|
110
|
+
this.listeners.add(cb);
|
|
111
|
+
return () => this.listeners.delete(cb);
|
|
112
|
+
}
|
|
113
|
+
stop() {
|
|
114
|
+
if (this.stopped) return;
|
|
115
|
+
this.stopped = true;
|
|
116
|
+
for (const unsub of this.unsubs) {
|
|
117
|
+
try {
|
|
118
|
+
unsub();
|
|
119
|
+
} catch {
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
this.unsubs.length = 0;
|
|
123
|
+
this.listeners.clear();
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// src/kernel/query/live/methods.ts
|
|
128
|
+
var LiveMethods = class {
|
|
129
|
+
/**
|
|
130
|
+
* Re-run the query whenever the source notifies of changes.
|
|
131
|
+
* Returns an unsubscribe function. The callback receives the latest result.
|
|
132
|
+
* Throws if the source does not support subscriptions.
|
|
133
|
+
*
|
|
134
|
+
* **For joined queries, prefer `.live()`** — `subscribe()`
|
|
135
|
+
* only re-fires on LEFT-side changes, so joined data can be
|
|
136
|
+
* stale if the right side mutates between emissions. `.live()`
|
|
137
|
+
* merges change streams from every join target.
|
|
138
|
+
*/
|
|
139
|
+
subscribe(cb) {
|
|
140
|
+
const _h = this.source.hydration;
|
|
141
|
+
if (_h !== void 0 && !_h.isHydrated()) return gateTerminal(_h, "subscribe", () => this.subscribe(cb));
|
|
142
|
+
if (!this.source.subscribe) {
|
|
143
|
+
throw new Error("Query source does not support subscriptions. Pass a source with a subscribe() method.");
|
|
144
|
+
}
|
|
145
|
+
cb(this.toArray());
|
|
146
|
+
return this.source.subscribe(() => cb(this.toArray()));
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Reactive terminal — returns a `LiveQuery<T>` that re-runs the
|
|
150
|
+
* query and updates its `value` whenever any source feeding it
|
|
151
|
+
* mutates..
|
|
152
|
+
*
|
|
153
|
+
* For non-joined queries, `.live()` is a convenience over the
|
|
154
|
+
* existing `.subscribe()` callback shape: a hand-rolled reactive
|
|
155
|
+
* primitive with `value` / `error` fields and a `subscribe(cb)`
|
|
156
|
+
* notification channel. Frame-agnostic — Vue / React / Solid
|
|
157
|
+
* adapters wrap it in their own primitive.
|
|
158
|
+
*
|
|
159
|
+
* For joined queries, `.live()` additionally subscribes to every
|
|
160
|
+
* join target's change stream. Mutations on a right-side
|
|
161
|
+
* collection (insert / update / delete of a client referenced by
|
|
162
|
+
* an invoice) re-fire the live query and re-evaluate every
|
|
163
|
+
* dependent left row. Right-side targets are deduped by
|
|
164
|
+
* collection name, so a chain that joins the same target twice
|
|
165
|
+
* (e.g. billing client + shipping client → both 'clients') only
|
|
166
|
+
* subscribes once.
|
|
167
|
+
*
|
|
168
|
+
* **Ref-mode behavior on right-side disappearance** — matches the
|
|
169
|
+
* eager `.toArray()` contract from :
|
|
170
|
+
* - `strict` → re-run throws `DanglingReferenceError`. The
|
|
171
|
+
* LiveQuery catches the throw, stores it in `live.error`, and
|
|
172
|
+
* notifies listeners (the throw does NOT propagate out of
|
|
173
|
+
* the source's change handler — that would tear down the
|
|
174
|
+
* emitter). Consumers check `live.error` after each
|
|
175
|
+
* notification and render an error state in the UI.
|
|
176
|
+
* - `warn` → joined value flips to `null`; the existing
|
|
177
|
+
* warn-channel deduplication keeps repeated re-runs from
|
|
178
|
+
* spamming the console.
|
|
179
|
+
* - `cascade` → no special handling needed; the cascade-
|
|
180
|
+
* delete mechanism propagates the right-side delete into the
|
|
181
|
+
* left collection on the next tick, and the live query
|
|
182
|
+
* naturally re-fires with the orphaned left rows gone.
|
|
183
|
+
*
|
|
184
|
+
* Always call `live.stop()` when finished — it tears down every
|
|
185
|
+
* upstream subscription. The Vue layer's `onUnmounted` hook
|
|
186
|
+
* should call `stop()` automatically; raw consumers must do it
|
|
187
|
+
* themselves.
|
|
188
|
+
*
|
|
189
|
+
* **Incremental maintenance (#1341).** For a plan
|
|
190
|
+
* `incrementalMaintainer()` accepts — no joins, no `.filter(fn)`, no
|
|
191
|
+
* label-sort, and nothing an index would serve in index order (an `==`/`in`
|
|
192
|
+
* probe, #1344's sorted-index range, or #1344's `orderBy(f).limit(n)`
|
|
193
|
+
* index page) — the result set is PATCHED per change
|
|
194
|
+
* event instead of re-run: one predicate evaluation for the changed record,
|
|
195
|
+
* a binary search, a splice. Everything else, and any change event that
|
|
196
|
+
* arrives without a delta, still re-runs the whole plan. Either way the
|
|
197
|
+
* emitted value is identical to `toArray()` — the maintainer reuses this
|
|
198
|
+
* query's own membership test and sort comparator.
|
|
199
|
+
*
|
|
200
|
+
* `options.batch` coalesces a burst of changes into one recompute and one
|
|
201
|
+
* notification on a microtask. It is OFF by default because it makes
|
|
202
|
+
* `live.value` stale until the microtask runs: a consumer that reads
|
|
203
|
+
* synchronously after `await put()` would see the previous value.
|
|
204
|
+
*
|
|
205
|
+
* **Limitations:**
|
|
206
|
+
* - No re-planning under live mutations — the planner picks
|
|
207
|
+
* once at subscription time and reuses the same plan.
|
|
208
|
+
* - Streaming live joins are deferred.
|
|
209
|
+
*/
|
|
210
|
+
live(options) {
|
|
211
|
+
const _h = this.source.hydration;
|
|
212
|
+
if (_h !== void 0 && !_h.isHydrated()) return gateTerminal(_h, "live", () => this.live(options));
|
|
213
|
+
const upstreams = [];
|
|
214
|
+
if (this.source.subscribe) {
|
|
215
|
+
const leftSubscribe = this.source.subscribe.bind(this.source);
|
|
216
|
+
upstreams.push({
|
|
217
|
+
subscribe: (cb) => leftSubscribe(cb)
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
if (this.plan.joins.length > 0 && this.joinContext) {
|
|
221
|
+
const subscribed = /* @__PURE__ */ new Set();
|
|
222
|
+
for (const leg of this.plan.joins) {
|
|
223
|
+
if (subscribed.has(leg.target)) continue;
|
|
224
|
+
subscribed.add(leg.target);
|
|
225
|
+
const rightSource = this.joinContext.resolveSource(leg.target);
|
|
226
|
+
if (rightSource?.subscribe) {
|
|
227
|
+
const rightSubscribe = rightSource.subscribe.bind(rightSource);
|
|
228
|
+
upstreams.push({
|
|
229
|
+
subscribe: (cb) => rightSubscribe(cb)
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (this.joinContext) {
|
|
235
|
+
const subscribedCross = /* @__PURE__ */ new Set();
|
|
236
|
+
for (const clause of this.plan.clauses) {
|
|
237
|
+
if (clause.type !== "crossJoin") continue;
|
|
238
|
+
if (subscribedCross.has(clause.target)) continue;
|
|
239
|
+
subscribedCross.add(clause.target);
|
|
240
|
+
const rightSource = this.joinContext.resolveSource(clause.target);
|
|
241
|
+
if (rightSource?.subscribe) {
|
|
242
|
+
const rightSubscribe = rightSource.subscribe.bind(rightSource);
|
|
243
|
+
upstreams.push({
|
|
244
|
+
subscribe: (cb) => rightSubscribe(cb)
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const maintainer = this.incrementalMaintainer("rows");
|
|
250
|
+
return buildLiveQuery(() => this.toArray(), upstreams, {
|
|
251
|
+
...options?.batch === true ? { batch: true } : {},
|
|
252
|
+
...maintainer ? { maintainer } : {}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
// src/kernel/query/live/install.ts
|
|
258
|
+
var done = false;
|
|
259
|
+
function installLive() {
|
|
260
|
+
if (done) return;
|
|
261
|
+
done = true;
|
|
262
|
+
installMethods(Query.prototype, MaintenanceMethods);
|
|
263
|
+
installMethods(Query.prototype, LiveMethods);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export {
|
|
267
|
+
buildLiveQuery,
|
|
268
|
+
installLive
|
|
269
|
+
};
|
|
270
|
+
//# sourceMappingURL=chunk-NBQ3KK6X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/kernel/query/live/live.ts","../src/kernel/query/live/methods.ts","../src/kernel/query/live/install.ts"],"sourcesContent":["/**\n * Reactive query primitive — `query.live()`.\n *\n * produces a `LiveQuery<T>` that re-runs the query and\n * updates its `value` whenever any source feeding it (the left\n * collection AND every right-side collection a join leg points at)\n * mutates.\n *\n * Framework-agnostic by design — core never depends on a UI\n * framework. The binding that wraps a `LiveQuery` is\n * `@noy-db/in-vue`'s `useLiveQuery(live)`: it subscribes once,\n * mirrors `value` into a `ShallowRef`, re-reads `error` on every\n * notification, and disposes via `onScopeDispose`.\n * `@noy-db/in-pinia`'s `store.liveQuery(build)` delegates to it, so\n * there is one implementation rather than two that drift (#1131).\n *\n * There is NO wrapper for `in-react`, `in-solid` or `in-svelte` — a\n * consumer on those subscribes directly (see **Error semantics**\n * below, which is the part a hand-rolled wrapper usually gets\n * wrong). Do not describe those adapters as existing until one does.\n *\n * **Error semantics.** A `.live()` query may throw at re-run time —\n * a strict-mode `DanglingReferenceError` is the most common case\n * (a right-side record was deleted out-of-band, leaving a left\n * row's FK pointing at nothing). When the re-run throws, the\n * `LiveQuery` catches the error and stores it in the `error`\n * field; it does NOT propagate the throw out of the source's\n * change handler, because doing so would tear down whatever\n * upstream emitter is dispatching. Listeners check `error` after\n * each notification and render an error state in the UI.\n *\n * **Dedup of right-side subscriptions.** A multi-FK chain that\n * joins the same target twice (e.g.\n * `.join('billingClientId').join('shippingClientId')`, both\n * pointing at `clients`) only subscribes to that target once. We\n * dedup by target collection name, on the assumption that\n * `resolveSource(name)` returns a single subscribable source per\n * vault + name. Vault's `resolveSource` reads from\n * `collectionCache` so this assumption holds.\n *\n * **Delta maintenance (#1341).** A live query over a plan\n * `canMaintainIncrementally()` admits no longer re-runs: the change event\n * carries which record moved, and `LiveMaintainer` patches the result set —\n * one predicate evaluation, a binary search, a splice. The emitted value is\n * identical to a re-run's, because the maintainer is handed the query's OWN\n * membership test and sort comparator. Every other plan, and every\n * notification that arrives without a delta, re-runs exactly as before.\n *\n * **What .live() still does NOT do:**\n * - No batching unless asked — `live({ batch: true })` coalesces a burst\n * into one recompute + one notification on a microtask; the default stays\n * one event in, one notification out, because batching makes `value`\n * stale until the microtask runs.\n * - No async notifications — every unbatched notification is synchronous\n * within the source's change handler.\n * - No re-planning under live mutations — the planner picks once\n * at subscription time and reuses the same plan for every\n * re-run.\n */\n\nimport type { LiveMaintainer, SourceChange } from './incremental.js'\n\n/**\n * The reactive primitive returned by `Query.live()`.\n *\n * Listeners can read the current `value` snapshot at any time and\n * subscribe to changes via `.subscribe(cb)`. The `error` field\n * carries the most recent re-run error, if any — read it after\n * each notification to render error state.\n *\n * Always call `stop()` when the live query is no longer needed.\n * Without it, the upstream change-stream subscriptions stay live\n * forever and the query keeps re-running on every mutation.\n */\nexport interface LiveQuery<T> {\n /**\n * Current snapshot of the query result.\n *\n * **A FRESH ARRAY on every successful re-run** — `refresh()` assigns\n * `this._value = this.recompute()`, and `recompute` is the query's own\n * `toArray()`. So the reference CHANGES on each change, and reference\n * identity is a valid change signal: a Vue `shallowRef`, a React\n * `useState`, or any `Object.is` comparison detects an update without\n * copying.\n *\n * The corollary is the part that bites: a consumer who reads `value`\n * ONCE and holds the array gets a snapshot that never updates. Read it\n * again after each notification — do not cache it.\n *\n * (An earlier version of this comment said the opposite — \"updated in\n * place… the reference returned is the same array\" — and told callers to\n * copy for change detection. Both halves were wrong, and the advice was\n * backwards. Verified against `buildLiveQuery`: two reads across a\n * notification are not `===`, and the first array still holds the old\n * contents.)\n */\n readonly value: readonly T[]\n /**\n * Most recent re-run error, or `null` on success. Set when the\n * executor throws (e.g. `DanglingReferenceError` in strict mode\n * after a right-side delete). Cleared on the next successful\n * re-run.\n */\n readonly error: Error | null\n /**\n * Register a notification callback. Fires AFTER `value` and\n * `error` have been updated for a given upstream change.\n * Returns an unsubscribe function.\n *\n * The first call to `subscribe` does NOT fire the callback\n * immediately — call sites that want the initial value should\n * read `live.value` directly before subscribing.\n */\n subscribe(cb: () => void): () => void\n /**\n * Tear down every upstream subscription and clear the listener\n * set. Idempotent — calling twice is safe. After `stop()`, the\n * query no longer re-runs and `subscribe()` becomes a no-op\n * (the returned unsubscribe is still callable and is also a\n * no-op).\n */\n stop(): void\n}\n\n/**\n * Internal subscription handle for an upstream source — left or\n * right side. The contract is just `subscribe(cb): unsubscribe`,\n * matching the existing `QuerySource.subscribe` and the new\n * `JoinableSource.subscribe` (added in ).\n */\nexport interface LiveUpstream {\n /**\n * `cb` may be handed the delta that caused the notification (#1341) so the\n * live query can patch its result set instead of re-running. Calling it with\n * NO argument is always valid and always correct — it means \"something\n * changed, I can't say what\", and the live query answers with a full re-run.\n */\n subscribe(cb: (change?: SourceChange) => void): () => void\n}\n\n/** Options for {@link buildLiveQuery}. */\nexport interface LiveBuildOptions {\n /**\n * Coalesce a burst of upstream changes into ONE recompute and ONE\n * notification, flushed on a microtask (#1341). Off by default: with it on,\n * `live.value` is stale until the microtask runs, so a consumer that reads\n * synchronously after an `await put()` would see the old value.\n */\n readonly batch?: boolean\n /**\n * Incremental maintainer for this query's result set. When present it\n * REPLACES `recompute` as the value source — it patches per delta and\n * rebuilds itself whenever a delta is not provably patchable.\n */\n readonly maintainer?: LiveMaintainer\n}\n\n/**\n * Build a LiveQuery from a `recompute` callback (typically the\n * Query's bound `toArray`) and a list of upstream sources to\n * subscribe to.\n *\n * The recompute fires once synchronously to populate the initial\n * value, then re-fires every time any upstream notifies. Errors\n * thrown by recompute are caught and stored in `error` instead of\n * propagating — see the file docstring for the rationale.\n */\nexport function buildLiveQuery<T>(\n recompute: () => T[],\n upstreams: readonly LiveUpstream[],\n options?: LiveBuildOptions,\n): LiveQuery<T> {\n return new LiveQueryImpl<T>(recompute, upstreams, options)\n}\n\nclass LiveQueryImpl<T> implements LiveQuery<T> {\n private _value: readonly T[] = []\n private _error: Error | null = null\n private readonly listeners = new Set<() => void>()\n private readonly unsubs: Array<() => void> = []\n private stopped = false\n\n private readonly maintainer: LiveMaintainer | undefined\n private readonly batch: boolean\n private queued: Array<SourceChange | undefined> = []\n private flushScheduled = false\n\n constructor(\n private readonly recompute: () => T[],\n upstreams: readonly LiveUpstream[],\n options?: LiveBuildOptions,\n ) {\n this.maintainer = options?.maintainer\n this.batch = options?.batch === true\n // From here on the maintainer is delta-driven: it patches on every event\n // and only rebuilds when it has to.\n this.maintainer?.attach()\n // Initial compute. If this throws, the constructor still\n // succeeds — we want consumers to be able to render an error\n // state from `live.error` rather than wrapping every\n // `query.live()` call in a try/catch.\n this.refresh()\n for (const upstream of upstreams) {\n try {\n this.unsubs.push(upstream.subscribe(this.onUpstreamChange))\n } catch (err) {\n // Upstream subscription failed — record it as the live\n // error and continue with the upstreams that did work.\n // The LiveQuery is now degraded (won't re-fire on this\n // upstream's changes) but isn't broken; consumers can\n // detect this via `live.error`.\n this._error = err instanceof Error ? err : new Error(String(err))\n }\n }\n }\n\n get value(): readonly T[] {\n return this._value\n }\n\n get error(): Error | null {\n return this._error\n }\n\n /**\n * Bound change handler — used as the callback passed to every\n * upstream's subscribe. Bound via class field so the `this`\n * context survives the indirect call from arbitrary upstreams.\n */\n private readonly onUpstreamChange = (change?: SourceChange): void => {\n if (this.batch) {\n this.queued.push(change)\n if (!this.flushScheduled) {\n this.flushScheduled = true\n queueMicrotask(this.flush)\n }\n return\n }\n this.absorb([change])\n this.notify()\n }\n\n /**\n * Drain a coalesced burst: every queued delta is folded in, then the value\n * is read ONCE and listeners are notified ONCE.\n */\n private readonly flush = (): void => {\n this.flushScheduled = false\n const batch = this.queued\n this.queued = []\n if (this.stopped) return\n this.absorb(batch)\n this.notify()\n }\n\n private absorb(changes: ReadonlyArray<SourceChange | undefined>): void {\n if (this.stopped) return\n if (this.maintainer) {\n try {\n for (const change of changes) this.maintainer.apply(change)\n } catch {\n // A predicate threw mid-patch. Drop the maintained state and let the\n // read below rebuild: it runs the same predicate, so the consumer sees\n // exactly the error (and the preserved last-good value) a full re-run\n // would have produced.\n this.maintainer.invalidate()\n }\n }\n this.refresh()\n }\n\n private notify(): void {\n for (const cb of this.listeners) {\n try {\n cb()\n } catch {\n // Listener errors are isolated — one buggy consumer\n // doesn't break the others or tear down the live query.\n }\n }\n }\n\n private refresh(): void {\n if (this.stopped) return\n try {\n this._value = (this.maintainer ? this.maintainer.rows() : this.recompute()) as T[]\n this._error = null\n } catch (err) {\n this._error = err instanceof Error ? err : new Error(String(err))\n // Whatever the maintainer holds is no longer trustworthy — the next\n // read pays for a rebuild rather than serving a half-patched set.\n this.maintainer?.invalidate()\n // Don't clobber the previous value on error — consumers\n // typically want to keep showing the last known good state\n // alongside the error message rather than flashing to an\n // empty list.\n }\n }\n\n subscribe(cb: () => void): () => void {\n if (this.stopped) return () => {}\n this.listeners.add(cb)\n return () => this.listeners.delete(cb)\n }\n\n stop(): void {\n if (this.stopped) return\n this.stopped = true\n for (const unsub of this.unsubs) {\n try {\n unsub()\n } catch {\n // Unsub errors are swallowed — at this point we're tearing\n // down anyway and the failure is noise.\n }\n }\n this.unsubs.length = 0\n this.listeners.clear()\n }\n}\n","/**\n * #1458 — **Live**: the same plan, re-run on change.\n *\n * `subscribe` · `live`\n *\n * Bodies moved out of `kernel/query/builder.ts` unchanged; see\n * `../relate/methods.ts` for why `this.plan` still resolves.\n */\nimport type { DeclaredPredicate, InternalSource, QueryPlan } from '../builder.js'\nimport type { JoinContext } from '../relate/join.js'\nimport type { ReduceStrategy } from '../../../with-lookup/reduce/strategy.js'\nimport type { LiveQuery, LiveUpstream } from './live.js'\nimport { buildLiveQuery } from './live.js'\nimport type { LiveMaintainer } from './incremental.js'\nimport type { DateTruncKey } from '../reduce/date-trunc.js'\nimport type { GroupMaintenanceSource } from './incremental.js'\nimport { gateTerminal } from '../hydration.js'\n\n/** @internal — the mixin whose prototype `./index.ts` copies onto `Query`. */\n /* eslint-disable @typescript-eslint/no-unused-vars -- #1458: the parameter\n list must match `Query`'s exactly (T, S, Q, M) because `declare module`\n merges this mixin's `Pick` into it, and TypeScript requires every\n declaration of an interface to carry identical type parameters. A group\n whose methods happen to use only `T` still declares all four. */\nexport class LiveMethods<\n T,\n S extends keyof T = never,\n Q extends keyof T & string = never,\n M extends keyof T & string = never,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n> {\n declare protected readonly source: InternalSource\n declare protected readonly plan: QueryPlan\n declare protected readonly joinContext: JoinContext | undefined\n declare protected readonly reduceStrategy: ReduceStrategy\n declare protected readonly predicates: ReadonlyMap<string, DeclaredPredicate> | undefined\n declare protected decodeVia: (records: readonly unknown[], locale?: string) => unknown[]\n declare protected incrementalMaintainer: (mode: 'rows' | 'records') => LiveMaintainer | undefined\n declare protected groupMaintenance: (derived: readonly DateTruncKey[]) => GroupMaintenanceSource | undefined\n declare toArray: (opts?: { locale?: string }) => T[]\n\n /**\n * Re-run the query whenever the source notifies of changes.\n * Returns an unsubscribe function. The callback receives the latest result.\n * Throws if the source does not support subscriptions.\n *\n * **For joined queries, prefer `.live()`** — `subscribe()`\n * only re-fires on LEFT-side changes, so joined data can be\n * stale if the right side mutates between emissions. `.live()`\n * merges change streams from every join target.\n */\n subscribe(cb: (result: T[]) => void): () => void {\n const _h = this.source.hydration\n if (_h !== undefined && !_h.isHydrated()) return gateTerminal(_h, 'subscribe', () => this.subscribe(cb))\n if (!this.source.subscribe) {\n throw new Error('Query source does not support subscriptions. Pass a source with a subscribe() method.')\n }\n cb(this.toArray())\n return this.source.subscribe(() => cb(this.toArray()))\n }\n\n /**\n * Reactive terminal — returns a `LiveQuery<T>` that re-runs the\n * query and updates its `value` whenever any source feeding it\n * mutates..\n *\n * For non-joined queries, `.live()` is a convenience over the\n * existing `.subscribe()` callback shape: a hand-rolled reactive\n * primitive with `value` / `error` fields and a `subscribe(cb)`\n * notification channel. Frame-agnostic — Vue / React / Solid\n * adapters wrap it in their own primitive.\n *\n * For joined queries, `.live()` additionally subscribes to every\n * join target's change stream. Mutations on a right-side\n * collection (insert / update / delete of a client referenced by\n * an invoice) re-fire the live query and re-evaluate every\n * dependent left row. Right-side targets are deduped by\n * collection name, so a chain that joins the same target twice\n * (e.g. billing client + shipping client → both 'clients') only\n * subscribes once.\n *\n * **Ref-mode behavior on right-side disappearance** — matches the\n * eager `.toArray()` contract from :\n * - `strict` → re-run throws `DanglingReferenceError`. The\n * LiveQuery catches the throw, stores it in `live.error`, and\n * notifies listeners (the throw does NOT propagate out of\n * the source's change handler — that would tear down the\n * emitter). Consumers check `live.error` after each\n * notification and render an error state in the UI.\n * - `warn` → joined value flips to `null`; the existing\n * warn-channel deduplication keeps repeated re-runs from\n * spamming the console.\n * - `cascade` → no special handling needed; the cascade-\n * delete mechanism propagates the right-side delete into the\n * left collection on the next tick, and the live query\n * naturally re-fires with the orphaned left rows gone.\n *\n * Always call `live.stop()` when finished — it tears down every\n * upstream subscription. The Vue layer's `onUnmounted` hook\n * should call `stop()` automatically; raw consumers must do it\n * themselves.\n *\n * **Incremental maintenance (#1341).** For a plan\n * `incrementalMaintainer()` accepts — no joins, no `.filter(fn)`, no\n * label-sort, and nothing an index would serve in index order (an `==`/`in`\n * probe, #1344's sorted-index range, or #1344's `orderBy(f).limit(n)`\n * index page) — the result set is PATCHED per change\n * event instead of re-run: one predicate evaluation for the changed record,\n * a binary search, a splice. Everything else, and any change event that\n * arrives without a delta, still re-runs the whole plan. Either way the\n * emitted value is identical to `toArray()` — the maintainer reuses this\n * query's own membership test and sort comparator.\n *\n * `options.batch` coalesces a burst of changes into one recompute and one\n * notification on a microtask. It is OFF by default because it makes\n * `live.value` stale until the microtask runs: a consumer that reads\n * synchronously after `await put()` would see the previous value.\n *\n * **Limitations:**\n * - No re-planning under live mutations — the planner picks\n * once at subscription time and reuses the same plan.\n * - Streaming live joins are deferred.\n */\n live(options?: { batch?: boolean }): LiveQuery<T> {\n const _h = this.source.hydration\n if (_h !== undefined && !_h.isHydrated()) return gateTerminal(_h, 'live', () => this.live(options))\n const upstreams: LiveUpstream[] = []\n\n // Left-side change stream — every live query subscribes to\n // its source if the source supports subscriptions.\n if (this.source.subscribe) {\n const leftSubscribe = this.source.subscribe.bind(this.source)\n upstreams.push({\n subscribe: (cb: () => void) => leftSubscribe(cb),\n })\n }\n\n // Right-side change streams — only for joined queries. Dedup\n // by target name so a chain joining the same target twice\n // doesn't double-subscribe and double-fire on every right-side\n // mutation.\n if (this.plan.joins.length > 0 && this.joinContext) {\n const subscribed = new Set<string>()\n for (const leg of this.plan.joins) {\n if (subscribed.has(leg.target)) continue\n subscribed.add(leg.target)\n const rightSource = this.joinContext.resolveSource(leg.target)\n if (rightSource?.subscribe) {\n const rightSubscribe = rightSource.subscribe.bind(rightSource)\n upstreams.push({\n subscribe: (cb: () => void) => rightSubscribe(cb),\n })\n }\n }\n }\n\n // Cross-join right-side change streams — symmetric with FK joins above.\n if (this.joinContext) {\n const subscribedCross = new Set<string>()\n for (const clause of this.plan.clauses) {\n if (clause.type !== 'crossJoin') continue\n if (subscribedCross.has(clause.target)) continue\n subscribedCross.add(clause.target)\n const rightSource = this.joinContext.resolveSource(clause.target)\n if (rightSource?.subscribe) {\n const rightSubscribe = rightSource.subscribe.bind(rightSource)\n upstreams.push({\n subscribe: (cb: () => void) => rightSubscribe(cb),\n })\n }\n }\n }\n\n // The recompute is just toArray bound to this query — same\n // pipeline as eager execution, including join application. It stays the\n // fallback even when a maintainer is attached.\n const maintainer = this.incrementalMaintainer('rows')\n return buildLiveQuery<T>(() => this.toArray(), upstreams, {\n ...(options?.batch === true ? { batch: true } : {}),\n ...(maintainer ? { maintainer } : {}),\n })\n }\n}\n\n/** The public Live surface — merged into `Query` by `./index.ts`. */\nexport type LiveSurface<\n T,\n S extends keyof T = never,\n Q extends keyof T & string = never,\n M extends keyof T & string = never,\n> = Pick<LiveMethods<T, S, Q, M>, 'subscribe' | 'live'>\n","/**\n * #1458 — the Live install. See `../relate/install.ts` for why this is a\n * function called from the entry rather than a module-level side effect.\n */\nimport { Query } from '../builder.js'\nimport { installMethods } from '../internal/core.js'\nimport { MaintenanceMethods } from '../internal/maintenance.js'\nimport { LiveMethods } from './methods.js'\n\nlet done = false\n\n/** Idempotent: the root barrel and the subpath entry both call it. */\nexport function installLive(): void {\n if (done) return\n done = true\n installMethods(Query.prototype, MaintenanceMethods)\n installMethods(Query.prototype, LiveMethods)\n}\n"],"mappings":"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","names":[]}
|