@noy-db/hub 0.4.0-pre.1 → 0.4.0-pre.11
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/README.md +3 -4
- package/dist/api-ZDKTWNBB.js +20 -0
- package/dist/attestation/index.js +18 -18
- package/dist/{backup-LU2DTZTI.js → backup-2UX7PRM5.js} +13 -13
- package/dist/blobs/index.js +30 -15
- package/dist/blobs/index.js.map +1 -1
- package/dist/broker/index.js +12 -12
- package/dist/broker/index.js.map +1 -1
- package/dist/cargo/index.js +53 -43
- package/dist/{chunk-YTGDPCPW.js → chunk-2J6UEN2V.js} +42 -18
- package/dist/chunk-2J6UEN2V.js.map +1 -0
- package/dist/{chunk-IY23KFNZ.js → chunk-35NMVJ7I.js} +3 -3
- package/dist/{chunk-S3BFKGET.js → chunk-3HUYRN24.js} +4 -4
- package/dist/chunk-3HUYRN24.js.map +1 -0
- package/dist/{walk-XS3PKM6I.js → chunk-3V3XR4S4.js} +4 -13
- package/dist/{walk-XS3PKM6I.js.map → chunk-3V3XR4S4.js.map} +1 -1
- package/dist/{chunk-RTEK4C4I.js → chunk-4JQK3L4V.js} +2 -2
- package/dist/{chunk-3ELCWU56.js → chunk-4ZKNC6A6.js} +2 -2
- package/dist/{chunk-VQNJ7UZL.js → chunk-55LKVALY.js} +106 -10
- package/dist/chunk-55LKVALY.js.map +1 -0
- package/dist/{chunk-VAIS3SOM.js → chunk-55LX6FSX.js} +2 -2
- package/dist/chunk-5D2ALSM5.js +19 -0
- package/dist/chunk-5D2ALSM5.js.map +1 -0
- package/dist/{chunk-6HPG2YNX.js → chunk-5DRROK5W.js} +2 -2
- package/dist/{chunk-S6Q37VGE.js → chunk-5GQEU4DN.js} +2 -2
- package/dist/chunk-5JOFWL4G.js +25 -0
- package/dist/chunk-5JOFWL4G.js.map +1 -0
- package/dist/{chunk-TOPYT5U5.js → chunk-63FE525P.js} +6 -6
- package/dist/chunk-6LJY7X5A.js +18 -0
- package/dist/chunk-6LJY7X5A.js.map +1 -0
- package/dist/{chunk-JVBO4SZL.js → chunk-6UBZ6I5Z.js} +2 -2
- package/dist/{chunk-BOKIKJJB.js → chunk-6ZNSB3H6.js} +5 -17
- package/dist/chunk-6ZNSB3H6.js.map +1 -0
- package/dist/{chunk-BMQWTQZ4.js → chunk-7YVBQJ7K.js} +13 -355
- package/dist/chunk-7YVBQJ7K.js.map +1 -0
- package/dist/{chunk-UFEVO57O.js → chunk-ABS7FMMD.js} +6 -6
- package/dist/chunk-AFHQATY4.js +47 -0
- package/dist/chunk-AFHQATY4.js.map +1 -0
- package/dist/{chunk-HOONYZY2.js → chunk-AKKRXT23.js} +7 -7
- package/dist/chunk-AKKRXT23.js.map +1 -0
- package/dist/{chunk-DDHM2TLX.js → chunk-AT2JJEKJ.js} +4 -4
- package/dist/chunk-AT2JJEKJ.js.map +1 -0
- package/dist/{chunk-M75ZZHSR.js → chunk-BLBAQRBM.js} +2 -2
- package/dist/{chunk-3SV2EPMN.js → chunk-BLCWSJLN.js} +88 -81
- package/dist/chunk-BLCWSJLN.js.map +1 -0
- package/dist/chunk-CADUYBQD.js +151 -0
- package/dist/chunk-CADUYBQD.js.map +1 -0
- package/dist/{chunk-G6EQYAL6.js → chunk-CI32CAFS.js} +5 -5
- package/dist/{chunk-FH52K7EG.js → chunk-CUZLNGD5.js} +2 -6
- package/dist/{chunk-FH52K7EG.js.map → chunk-CUZLNGD5.js.map} +1 -1
- package/dist/{chunk-2P7EGNKF.js → chunk-CXQW2NWO.js} +145 -3
- package/dist/chunk-CXQW2NWO.js.map +1 -0
- package/dist/{chunk-6B4DYGWO.js → chunk-DABACXEF.js} +3 -3
- package/dist/{chunk-F6T6L2UK.js → chunk-DMH3VZU5.js} +4 -4
- package/dist/chunk-DSDXAKIP.js +50 -0
- package/dist/chunk-DSDXAKIP.js.map +1 -0
- package/dist/{chunk-MQ6WOPSY.js → chunk-DZ2JXHWK.js} +5 -5
- package/dist/chunk-DZFQVICS.js +23 -0
- package/dist/chunk-DZFQVICS.js.map +1 -0
- package/dist/chunk-E23UGFVC.js +63 -0
- package/dist/chunk-E23UGFVC.js.map +1 -0
- package/dist/{chunk-UBNCR3YK.js → chunk-EE7UHLKH.js} +4 -4
- package/dist/chunk-EIPVYUEP.js +654 -0
- package/dist/chunk-EIPVYUEP.js.map +1 -0
- package/dist/{chunk-EGCRBCNA.js → chunk-EKRSCRNM.js} +3 -3
- package/dist/{chunk-YMUGBZN2.js → chunk-FQ5CHJR7.js} +1 -1
- package/dist/chunk-FQ5CHJR7.js.map +1 -0
- package/dist/{chunk-LB6OH6K2.js → chunk-FQZ6XTQ7.js} +17 -20
- package/dist/chunk-FQZ6XTQ7.js.map +1 -0
- package/dist/{chunk-IRQY7IR5.js → chunk-FRMPM7WG.js} +4 -4
- package/dist/{chunk-DVUZMT2W.js → chunk-G2JUIDFA.js} +9 -9
- package/dist/{chunk-DVUZMT2W.js.map → chunk-G2JUIDFA.js.map} +1 -1
- package/dist/{chunk-RND5ZPNP.js → chunk-G6WWZNJP.js} +13 -13
- package/dist/chunk-G6WWZNJP.js.map +1 -0
- package/dist/chunk-GJW4HX2O.js +1 -0
- package/dist/{chunk-T6GU5PPZ.js → chunk-GU3IP74F.js} +6 -6
- package/dist/{chunk-5OI6BR4H.js → chunk-GWWOGNBK.js} +308 -18
- package/dist/chunk-GWWOGNBK.js.map +1 -0
- package/dist/{chunk-UNCOC7QH.js → chunk-H2GPHUZD.js} +12 -13
- package/dist/chunk-H2GPHUZD.js.map +1 -0
- package/dist/{chunk-7CI6CP7Z.js → chunk-HMU5P6RL.js} +5 -5
- package/dist/chunk-HMU5P6RL.js.map +1 -0
- package/dist/{chunk-YJV2UZ7H.js → chunk-I5GEJX3R.js} +5 -5
- package/dist/chunk-I5GEJX3R.js.map +1 -0
- package/dist/{chunk-GWKAVKHI.js → chunk-IG6KUWBX.js} +2 -2
- package/dist/chunk-IG6KUWBX.js.map +1 -0
- package/dist/{chunk-MTQPRQHB.js → chunk-IPUG56GJ.js} +15 -5
- package/dist/{chunk-MTQPRQHB.js.map → chunk-IPUG56GJ.js.map} +1 -1
- package/dist/{chunk-SMIRGMS7.js → chunk-IXNCZTWA.js} +2 -2
- package/dist/{chunk-RM2XV574.js → chunk-IXTSNGYY.js} +3 -3
- package/dist/{chunk-KUPKLSX5.js → chunk-IYZISPGD.js} +7 -5
- package/dist/chunk-IYZISPGD.js.map +1 -0
- package/dist/{chunk-SMGEYW6G.js → chunk-JDOMW53O.js} +26 -16
- package/dist/chunk-JDOMW53O.js.map +1 -0
- package/dist/{chunk-PK6QCH2C.js → chunk-JJZGIE4U.js} +6 -5
- package/dist/{chunk-DRWBEDYO.js → chunk-JYJFGD2H.js} +2 -2
- package/dist/{chunk-TAGR72IR.js → chunk-KRCBZYTZ.js} +26 -177
- package/dist/chunk-KRCBZYTZ.js.map +1 -0
- package/dist/{chunk-HPUWOVR7.js → chunk-L2DGWBCT.js} +14 -14
- package/dist/chunk-L2DGWBCT.js.map +1 -0
- package/dist/{chunk-VEALDPHW.js → chunk-L3YYLT4E.js} +15 -2
- package/dist/chunk-L3YYLT4E.js.map +1 -0
- package/dist/{chunk-A7JJLVGH.js → chunk-LNPUSMZL.js} +29 -31
- package/dist/chunk-LNPUSMZL.js.map +1 -0
- package/dist/{chunk-KUIB4B5Q.js → chunk-LNZKOUJR.js} +2 -2
- package/dist/{chunk-IM3QVF53.js → chunk-MBKVNOJS.js} +6 -6
- package/dist/chunk-MCHBCNCE.js +367 -0
- package/dist/chunk-MCHBCNCE.js.map +1 -0
- package/dist/{chunk-VCBHAE4R.js → chunk-MHMLXJ3I.js} +2 -2
- package/dist/chunk-MHMLXJ3I.js.map +1 -0
- package/dist/{chunk-WNGGJWF7.js → chunk-MSMJJB4J.js} +2 -2
- package/dist/chunk-MSMJJB4J.js.map +1 -0
- package/dist/{chunk-T36RFODW.js → chunk-MXUT7FTE.js} +2 -2
- package/dist/chunk-MXUT7FTE.js.map +1 -0
- package/dist/{chunk-BGK233EA.js → chunk-N4BBNYIB.js} +11 -9
- package/dist/chunk-N4BBNYIB.js.map +1 -0
- package/dist/{chunk-3PF6CRDT.js → chunk-NFIBXF4V.js} +1082 -1583
- package/dist/chunk-NFIBXF4V.js.map +1 -0
- package/dist/{chunk-LOF2W3JU.js → chunk-NFNJLRY7.js} +368 -52
- package/dist/chunk-NFNJLRY7.js.map +1 -0
- package/dist/{chunk-N6WF5PKC.js → chunk-NFZGZ4AK.js} +2 -2
- package/dist/{chunk-JRBNCUNT.js → chunk-NGSJZFGL.js} +21 -4
- package/dist/chunk-NGSJZFGL.js.map +1 -0
- package/dist/chunk-NJ4DYYO5.js +81 -0
- package/dist/chunk-NJ4DYYO5.js.map +1 -0
- package/dist/{chunk-2IALOXZS.js → chunk-NM5UYF6Q.js} +2 -2
- package/dist/chunk-NM5UYF6Q.js.map +1 -0
- package/dist/{chunk-JBBSYJHP.js → chunk-NYEFP7DY.js} +4 -4
- package/dist/chunk-NYEFP7DY.js.map +1 -0
- package/dist/{chunk-CCOP5XDW.js → chunk-NZ24MX4J.js} +8 -46
- package/dist/chunk-NZ24MX4J.js.map +1 -0
- package/dist/{chunk-KWVJAOIN.js → chunk-OLEPKFTW.js} +4 -4
- package/dist/chunk-OLEPKFTW.js.map +1 -0
- package/dist/{chunk-OF75ACKS.js → chunk-PEATRIYJ.js} +9 -9
- package/dist/chunk-PEOZ34EM.js +13 -0
- package/dist/chunk-PEOZ34EM.js.map +1 -0
- package/dist/{chunk-UC2ETWF3.js → chunk-PTHKZWEH.js} +2 -14
- package/dist/{chunk-UC2ETWF3.js.map → chunk-PTHKZWEH.js.map} +1 -1
- package/dist/chunk-PVEWA2DU.js +23 -0
- package/dist/chunk-PVEWA2DU.js.map +1 -0
- package/dist/{chunk-LSASLXGC.js → chunk-QBAC3GXA.js} +1 -1
- package/dist/chunk-QBAC3GXA.js.map +1 -0
- package/dist/{chunk-RDXW3OBQ.js → chunk-QD46HPZG.js} +2 -2
- package/dist/chunk-QD46HPZG.js.map +1 -0
- package/dist/{chunk-N55W7KUL.js → chunk-QDIH2744.js} +2 -2
- package/dist/{chunk-6HY2X62D.js → chunk-QJNCB5SK.js} +2 -2
- package/dist/{chunk-4BRCIYFG.js → chunk-QX76XVQH.js} +6 -6
- package/dist/chunk-QX76XVQH.js.map +1 -0
- package/dist/{chunk-W2OG6JOL.js → chunk-QZWTRENR.js} +24 -7
- package/dist/chunk-QZWTRENR.js.map +1 -0
- package/dist/{chunk-6NQMXTYC.js → chunk-RO5NM6UI.js} +2 -2
- package/dist/chunk-RO5NM6UI.js.map +1 -0
- package/dist/chunk-SGDPRCC4.js +1075 -0
- package/dist/chunk-SGDPRCC4.js.map +1 -0
- package/dist/{chunk-2PCAVW2I.js → chunk-SHEEBRZ4.js} +2 -2
- package/dist/chunk-SMY5X46Z.js +14 -0
- package/dist/chunk-SMY5X46Z.js.map +1 -0
- package/dist/{chunk-ISMV2QVG.js → chunk-TG634KCO.js} +11 -2
- package/dist/chunk-TG634KCO.js.map +1 -0
- package/dist/{chunk-J6Q7UVQE.js → chunk-TUXQSFHZ.js} +4 -16
- package/dist/{chunk-J6Q7UVQE.js.map → chunk-TUXQSFHZ.js.map} +1 -1
- package/dist/{chunk-GULTLPFB.js → chunk-UADPR6F4.js} +3 -3
- package/dist/{chunk-GULTLPFB.js.map → chunk-UADPR6F4.js.map} +1 -1
- package/dist/{chunk-ZEQWCBCM.js → chunk-UDHBXYGG.js} +27 -5
- package/dist/chunk-UDHBXYGG.js.map +1 -0
- package/dist/{chunk-RA5VTXXG.js → chunk-V6UQZA2H.js} +2 -2
- package/dist/chunk-VG2ZSFYD.js +32 -0
- package/dist/chunk-VG2ZSFYD.js.map +1 -0
- package/dist/chunk-VKQCVU2Z.js +21 -0
- package/dist/chunk-VKQCVU2Z.js.map +1 -0
- package/dist/{chunk-QDPZWTN2.js → chunk-W3G5REIU.js} +2 -2
- package/dist/{chunk-WEYZTLXN.js → chunk-W3L64Y3J.js} +2 -2
- package/dist/{chunk-ONTBCHCP.js → chunk-W66AM5IB.js} +2 -2
- package/dist/chunk-W66AM5IB.js.map +1 -0
- package/dist/{chunk-A5BDDEXK.js → chunk-WBKZUO5V.js} +26 -43
- package/dist/chunk-WBKZUO5V.js.map +1 -0
- package/dist/{chunk-CBSY2N76.js → chunk-WLXMTYGO.js} +2 -2
- package/dist/{chunk-3U3FBR7O.js → chunk-X3F5YJG2.js} +2 -2
- package/dist/{chunk-GQNGCEP5.js → chunk-X45JYIAY.js} +3 -3
- package/dist/chunk-X45JYIAY.js.map +1 -0
- package/dist/{chunk-6XE5TMPR.js → chunk-X4MVWPHV.js} +3 -3
- package/dist/chunk-X4MVWPHV.js.map +1 -0
- package/dist/chunk-XZHEOSQ2.js +16 -0
- package/dist/chunk-XZHEOSQ2.js.map +1 -0
- package/dist/chunk-Y2NBBT6K.js +18 -0
- package/dist/chunk-Y2NBBT6K.js.map +1 -0
- package/dist/{chunk-DDATL6PU.js → chunk-Y2NJBNX3.js} +8 -8
- package/dist/{chunk-DDATL6PU.js.map → chunk-Y2NJBNX3.js.map} +1 -1
- package/dist/chunk-YMUFFJCO.js +23 -0
- package/dist/chunk-YMUFFJCO.js.map +1 -0
- package/dist/{chunk-O7WJ47EF.js → chunk-YWWQM7KP.js} +5 -14
- package/dist/chunk-YWWQM7KP.js.map +1 -0
- package/dist/{chunk-7O3AYBC7.js → chunk-YZJSJOUI.js} +235 -65
- package/dist/chunk-YZJSJOUI.js.map +1 -0
- package/dist/{chunk-5WZXVULX.js → chunk-ZTLOXFPB.js} +2 -2
- package/dist/chunk-ZTLOXFPB.js.map +1 -0
- package/dist/classified/index.js +5 -5
- package/dist/{classified-marker-WQVIJAW2.js → classified-marker-7PKJBFCG.js} +3 -3
- package/dist/collection-facade-6I5K5IOD.js +45 -0
- package/dist/{computed-DSMPXG2Y.js → computed-AB45PS4V.js} +3 -3
- package/dist/consent/index.js +13 -9
- package/dist/consent/index.js.map +1 -1
- package/dist/cover/index.js +37 -0
- package/dist/crdt/index.js +4 -0
- package/dist/crdt/index.js.map +1 -1
- package/dist/custody/index.js +26 -0
- package/dist/{dead-filter-2A7IAJ3D.js → dead-filter-FL3WIUZS.js} +2 -2
- package/dist/{chunk-GYYCX5K6.js → delegation-QXZ4MPPH.js} +12 -6
- package/dist/{chunk-GYYCX5K6.js.map → delegation-QXZ4MPPH.js.map} +1 -1
- package/dist/derivations/index.js +12 -12
- package/dist/derive-VGS7FKE3.js +22 -0
- package/dist/directory/index.js +46 -0
- package/dist/dispatch-EGGC7UD7.js +72 -0
- package/dist/dispatch-EGGC7UD7.js.map +1 -0
- package/dist/dispatch-GDSTUTVP.js +194 -0
- package/dist/dispatch-GDSTUTVP.js.map +1 -0
- package/dist/{enclave-7MW6ZGXW.js → enclave-SPEEDYZ4.js} +11 -11
- package/dist/executor-IEBLTBCW.js +9 -0
- package/dist/executor-OTF556PL.js +28 -0
- package/dist/executor-RM7XWQDU.js +9 -0
- package/dist/export-accessible-P42BQ4PB.js +23 -0
- package/dist/extract-partition-TCYXRWBN.js +38 -0
- package/dist/{fanout-sidecar-WDYQ77VB.js → fanout-sidecar-SSMRSC2L.js} +9 -9
- package/dist/find-OZMTRIK3.js +11 -0
- package/dist/forget/index.js +11 -11
- package/dist/forget/index.js.map +1 -1
- package/dist/guards/index.js +6 -6
- package/dist/history/index.js +16 -12
- package/dist/history/index.js.map +1 -1
- package/dist/i18n/index.js +16 -14
- package/dist/i18n/index.js.map +1 -1
- package/dist/index.d.ts +42 -42
- package/dist/index.js +330 -2106
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +4 -2
- package/dist/indexing/index.js.map +1 -1
- package/dist/introspection/index.js +28 -0
- package/dist/issue-FCKN5O6C.js +19 -0
- package/dist/kernel/best-effort-revert.d.ts +9 -1
- package/dist/kernel/collection-config.d.ts +12 -70
- package/dist/kernel/collection.d.ts +11 -23
- package/dist/kernel/enclave/crypto.d.ts +8 -8
- package/dist/kernel/enclave/index.d.ts +3 -3
- package/dist/kernel/errors.d.ts +41 -22
- package/dist/kernel/lazy.d.ts +30 -0
- package/dist/kernel/noydb.d.ts +81 -124
- package/dist/kernel/query/builder.d.ts +10 -10
- package/dist/kernel/query/index.d.ts +0 -6
- package/dist/kernel/query/scan-builder.d.ts +4 -4
- package/dist/kernel/sync-policy.d.ts +76 -4
- package/dist/kernel/types.d.ts +146 -86
- package/dist/kernel/validation.d.ts +33 -33
- package/dist/kernel/vault.d.ts +41 -229
- package/dist/kernel/via/dispatch.d.ts +7 -0
- package/dist/{ledger-33BC4TR7.js → ledger-6XBEVWYP.js} +11 -11
- package/dist/liberate-CYUOS4NC.js +24 -0
- package/dist/{link-set-QK22TDEX.js → link-set-NK6L2A5S.js} +11 -11
- package/dist/materialized-views/index.js +22 -19
- package/dist/money/index.js +31 -0
- package/dist/noydb-FZZIMLCI.js +81 -0
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.js +15 -13
- package/dist/pod/index.js +26 -12
- package/dist/{policy-NAHB2TUT.js → policy/index.js} +6 -6
- package/dist/port/with/archive-strategy.d.ts +31 -0
- package/dist/port/with/blob-strategy.d.ts +15 -5
- package/dist/port/with/collection-options.d.ts +171 -0
- package/dist/port/with/collection-registries.d.ts +62 -0
- package/dist/port/with/strategies.d.ts +134 -0
- package/dist/port/with/team-strategy.d.ts +3 -2
- package/dist/portability/index.js +8 -8
- package/dist/{post-register-JVTMJ6OW.js → post-register-VFIYISUK.js} +6 -6
- package/dist/query/index.js +6 -46
- package/dist/{aggregate → reduce}/index.js +24 -17
- package/dist/reduce/index.js.map +1 -0
- package/dist/register-UKU2J6MN.js +25 -0
- package/dist/registry-2VCWVHZS.js +19 -0
- package/dist/registry-7Y5WF7GS.js +9 -0
- package/dist/{registry-VW6P6A3J.js → registry-BWD2ED52.js} +2 -2
- package/dist/registry-DTWRJLSF.js +18 -0
- package/dist/request-withdrawal-JYDZ5XY2.js +31 -0
- package/dist/{reveal-LGBOM2BO.js → reveal-CL2BCW6A.js} +6 -6
- package/dist/revoke-2TSAD2T4.js +24 -0
- package/dist/satellites/index.js +1 -1
- package/dist/schema-update/index.js +26 -0
- package/dist/sealed-record/index.js +12 -12
- package/dist/search/index.js +36 -0
- package/dist/{seed-PWK45HDF.js → seed-NUVJEL7T.js} +12 -12
- package/dist/seed-NUVJEL7T.js.map +1 -0
- package/dist/sequence/index.js +30 -0
- package/dist/session/index.js +13 -9
- package/dist/session/index.js.map +1 -1
- package/dist/shadow/index.js +6 -2
- package/dist/shadow/index.js.map +1 -1
- package/dist/signer-K7Z2EOMG.js +25 -0
- package/dist/snapshots/index.js +14 -10
- package/dist/snapshots/index.js.map +1 -1
- package/dist/{stale-FJED42DM.js → stale-A4J26OIC.js} +11 -10
- package/dist/storage-YVHZUISN.js +23 -0
- package/dist/store/index.js +22 -0
- package/dist/{store-coordination-provider-APODTV4W.js → store-coordination-provider-EWRZL7XF.js} +3 -3
- package/dist/sync/index.js +15 -12
- package/dist/sync/index.js.map +1 -1
- package/dist/team/index.js +33 -48
- package/dist/tiers/index.js +10 -10
- package/dist/to/index.js +1 -1
- package/dist/{tx → transactions}/index.js +7 -3
- package/dist/transactions/index.js.map +1 -0
- package/dist/util/index.js +1 -1
- package/dist/{verify-26Y5GNMK.js → verify-7XWHJWUN.js} +5 -5
- package/dist/via/blob/active.d.ts +23 -7
- package/dist/via/blob/binding.d.ts +1 -1
- package/dist/via/blob/index.d.ts +7 -1
- package/dist/via/i18n/core.d.ts +1 -1
- package/dist/via/i18n/index.d.ts +2 -0
- package/dist/via/money/money-reducer.d.ts +2 -2
- package/dist/walk-P5D6CF4V.js +21 -0
- package/dist/with-audit/consent/index.d.ts +2 -0
- package/dist/with-audit/forget/active.d.ts +3 -3
- package/dist/with-audit/forget/index.d.ts +6 -5
- package/dist/with-audit/forget/strategy.d.ts +3 -3
- package/dist/with-audit/guards/executor.d.ts +4 -4
- package/dist/with-audit/guards/immutable-guard.d.ts +3 -3
- package/dist/with-audit/guards/index.d.ts +1 -1
- package/dist/with-audit/guards/registry.d.ts +3 -3
- package/dist/with-audit/guards/transition-guard.d.ts +3 -3
- package/dist/with-audit/guards/types.d.ts +10 -10
- package/dist/with-audit/guards/with-guard.d.ts +2 -2
- package/dist/with-audit/periods/index.d.ts +2 -0
- package/dist/with-audit/periods/vault-facade.d.ts +6 -0
- package/dist/with-audit/portability/export-accessible.d.ts +4 -4
- package/dist/with-audit/portability/request-withdrawal.d.ts +3 -3
- package/dist/with-audit/portability/withdraw-accessible.d.ts +2 -2
- package/dist/with-audit/sealed-record/strategy.d.ts +1 -1
- package/dist/with-audit/tiers/index.d.ts +1 -0
- package/dist/with-cargo/adopt-partition.d.ts +7 -7
- package/dist/{legacy/kernel.d.ts → with-cargo/floor.d.ts} +4 -4
- package/dist/with-cargo/index.d.ts +9 -2
- package/dist/with-commit/crdt/index.d.ts +2 -0
- package/dist/with-commit/history/index.d.ts +2 -0
- package/dist/with-commit/history/time-machine.d.ts +2 -2
- package/dist/with-commit/numbering/descriptor.d.ts +16 -6
- package/dist/with-commit/tx/active.d.ts +5 -5
- package/dist/with-commit/tx/index.d.ts +2 -2
- package/dist/with-commit/tx/invariants.d.ts +1 -1
- package/dist/with-commit/tx/strategy.d.ts +3 -3
- package/dist/with-fork/shadow/index.d.ts +2 -0
- package/dist/with-fork/snapshots/active.d.ts +2 -2
- package/dist/with-fork/snapshots/index.d.ts +3 -1
- package/dist/with-fork/snapshots/noydb-facade.d.ts +3 -3
- package/dist/with-fork/snapshots/strategy.d.ts +2 -2
- package/dist/with-formula/derivations/dispatch.d.ts +98 -0
- package/dist/with-formula/derivations/executor.d.ts +2 -2
- package/dist/with-formula/derivations/index.d.ts +4 -1
- package/dist/with-formula/derivations/registry.d.ts +3 -3
- package/dist/with-formula/derivations/stale.d.ts +2 -2
- package/dist/with-formula/derivations/types.d.ts +3 -3
- package/dist/with-formula/derivations/with-derivation.d.ts +2 -2
- package/dist/with-formula/derivations/with-rollup.d.ts +15 -8
- package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +3 -3
- package/dist/with-formula/materialized-views/dispatch.d.ts +75 -0
- package/dist/with-formula/materialized-views/index.d.ts +2 -1
- package/dist/with-formula/materialized-views/registry.d.ts +4 -4
- package/dist/with-formula/materialized-views/types.d.ts +11 -11
- package/dist/with-formula/materialized-views/with-materialized-view.d.ts +2 -2
- package/dist/with-formula/overlay-views/index.d.ts +1 -1
- package/dist/with-formula/overlay-views/registry.d.ts +4 -4
- package/dist/with-formula/overlay-views/types.d.ts +3 -3
- package/dist/with-formula/overlay-views/virtual-collection.d.ts +2 -2
- package/dist/with-formula/overlay-views/with-overlayed-view.d.ts +2 -2
- package/dist/with-lookup/indexing/active.d.ts +5 -5
- package/dist/with-lookup/indexing/index.d.ts +3 -1
- package/dist/with-lookup/indexing/strategy.d.ts +3 -3
- package/dist/with-lookup/{aggregate → reduce}/active.d.ts +8 -8
- package/dist/with-lookup/{aggregate → reduce}/groupby.d.ts +21 -21
- package/dist/with-lookup/reduce/index.d.ts +34 -0
- package/dist/with-lookup/{aggregate → reduce}/reducers.d.ts +11 -12
- package/dist/with-lookup/{aggregate/aggregation.d.ts → reduce/reduction.d.ts} +21 -21
- package/dist/with-lookup/{aggregate → reduce}/strategy.d.ts +15 -15
- package/dist/with-lookup/search/build-docs.d.ts +7 -2
- package/dist/with-lookup/search/index.d.ts +1 -1
- package/dist/with-party/broker/index.d.ts +1 -0
- package/dist/with-party/broker/seed.d.ts +1 -1
- package/dist/with-party/custody/liberate.d.ts +3 -3
- package/dist/with-party/directory/cover/index.d.ts +1 -5
- package/dist/with-party/directory/cover/schema.d.ts +0 -6
- package/dist/with-party/directory/cover/storage.d.ts +0 -8
- package/dist/with-party/directory/cover/types.d.ts +0 -21
- package/dist/with-party/directory/index.d.ts +2 -0
- package/dist/with-party/session/dev-unlock.d.ts +2 -2
- package/dist/with-party/session/index.d.ts +2 -0
- package/dist/with-party/session/session.d.ts +2 -2
- package/dist/with-party/team/deed.d.ts +8 -8
- package/dist/with-party/team/index.d.ts +4 -7
- package/dist/with-party/team/keyring.d.ts +83 -35
- package/dist/with-party/team/{managed-passphrase.d.ts → managed-secret.d.ts} +27 -27
- package/dist/with-party/team/noydb-facade.d.ts +43 -42
- package/dist/with-party/team/peer-recover.d.ts +13 -13
- package/dist/with-party/team/recovery.d.ts +5 -5
- package/dist/with-party/team/rotate-recover.d.ts +30 -30
- package/dist/with-pod/bundle.d.ts +30 -32
- package/dist/with-pod/format.d.ts +2 -2
- package/dist/with-pod/index.d.ts +2 -1
- package/dist/with-shape/blobs/blob-compaction.d.ts +43 -3
- package/dist/with-shape/blobs/blob-pinning.d.ts +112 -0
- package/dist/with-shape/blobs/blob-set.d.ts +86 -2
- package/dist/with-shape/introspection/index.d.ts +6 -0
- package/dist/with-shape/schema-update/index.d.ts +1 -0
- package/dist/with-store/index.d.ts +3 -2
- package/dist/with-store/route-store.d.ts +1 -1
- package/dist/{with-party/team/sync-active.d.ts → with-sync/active.d.ts} +1 -1
- package/dist/{with-party/team/sync-credentials.d.ts → with-sync/credentials.d.ts} +3 -3
- package/dist/{with-party/team/sync.d.ts → with-sync/engine.d.ts} +5 -5
- package/dist/{with-party/sync → with-sync}/index.d.ts +4 -2
- package/dist/{with-party/team/sync-period-scope.d.ts → with-sync/period-scope.d.ts} +2 -2
- package/dist/{with-party/team → with-sync}/presence.d.ts +2 -2
- package/dist/{with-party/team/sync-strategy.d.ts → with-sync/strategy.d.ts} +6 -6
- package/dist/{with-party/team/sync-transaction.d.ts → with-sync/transaction.d.ts} +3 -3
- package/dist/withdraw-accessible-A2PWF5MZ.js +28 -0
- package/package.json +45 -36
- package/dist/aggregate/index.js.map +0 -1
- package/dist/api-IQFZJSQO.js +0 -20
- package/dist/as/index.js +0 -30
- package/dist/at/index.js +0 -1
- package/dist/bundle/index.js +0 -105
- package/dist/by/index.js +0 -11
- package/dist/chunk-2IALOXZS.js.map +0 -1
- package/dist/chunk-2MUZ3LY6.js +0 -205
- package/dist/chunk-2MUZ3LY6.js.map +0 -1
- package/dist/chunk-2P7EGNKF.js.map +0 -1
- package/dist/chunk-3PF6CRDT.js.map +0 -1
- package/dist/chunk-3SV2EPMN.js.map +0 -1
- package/dist/chunk-4BRCIYFG.js.map +0 -1
- package/dist/chunk-5OI6BR4H.js.map +0 -1
- package/dist/chunk-5WZXVULX.js.map +0 -1
- package/dist/chunk-6NQMXTYC.js.map +0 -1
- package/dist/chunk-6XE5TMPR.js.map +0 -1
- package/dist/chunk-7CI6CP7Z.js.map +0 -1
- package/dist/chunk-7O3AYBC7.js.map +0 -1
- package/dist/chunk-A5BDDEXK.js.map +0 -1
- package/dist/chunk-A7JJLVGH.js.map +0 -1
- package/dist/chunk-BGK233EA.js.map +0 -1
- package/dist/chunk-BMQWTQZ4.js.map +0 -1
- package/dist/chunk-BOKIKJJB.js.map +0 -1
- package/dist/chunk-CCOP5XDW.js.map +0 -1
- package/dist/chunk-CHFZDSE4.js +0 -1
- package/dist/chunk-DDHM2TLX.js.map +0 -1
- package/dist/chunk-GQNGCEP5.js.map +0 -1
- package/dist/chunk-GVZQ4NAM.js +0 -14
- package/dist/chunk-GVZQ4NAM.js.map +0 -1
- package/dist/chunk-GWKAVKHI.js.map +0 -1
- package/dist/chunk-HOONYZY2.js.map +0 -1
- package/dist/chunk-HPUWOVR7.js.map +0 -1
- package/dist/chunk-ISMV2QVG.js.map +0 -1
- package/dist/chunk-JBBSYJHP.js.map +0 -1
- package/dist/chunk-JRBNCUNT.js.map +0 -1
- package/dist/chunk-JZWWLLVY.js +0 -99
- package/dist/chunk-JZWWLLVY.js.map +0 -1
- package/dist/chunk-KUPKLSX5.js.map +0 -1
- package/dist/chunk-KWVJAOIN.js.map +0 -1
- package/dist/chunk-LB6OH6K2.js.map +0 -1
- package/dist/chunk-LB7FD65R.js +0 -163
- package/dist/chunk-LB7FD65R.js.map +0 -1
- package/dist/chunk-LOF2W3JU.js.map +0 -1
- package/dist/chunk-LSASLXGC.js.map +0 -1
- package/dist/chunk-O7WJ47EF.js.map +0 -1
- package/dist/chunk-ONTBCHCP.js.map +0 -1
- package/dist/chunk-PT37L5DV.js +0 -255
- package/dist/chunk-PT37L5DV.js.map +0 -1
- package/dist/chunk-RDXW3OBQ.js.map +0 -1
- package/dist/chunk-RND5ZPNP.js.map +0 -1
- package/dist/chunk-S3BFKGET.js.map +0 -1
- package/dist/chunk-SMGEYW6G.js.map +0 -1
- package/dist/chunk-T36RFODW.js.map +0 -1
- package/dist/chunk-TAGR72IR.js.map +0 -1
- package/dist/chunk-UNCOC7QH.js.map +0 -1
- package/dist/chunk-VCBHAE4R.js.map +0 -1
- package/dist/chunk-VEALDPHW.js.map +0 -1
- package/dist/chunk-VQNJ7UZL.js.map +0 -1
- package/dist/chunk-W2OG6JOL.js.map +0 -1
- package/dist/chunk-WNGGJWF7.js.map +0 -1
- package/dist/chunk-YJV2UZ7H.js.map +0 -1
- package/dist/chunk-YMUGBZN2.js.map +0 -1
- package/dist/chunk-YTGDPCPW.js.map +0 -1
- package/dist/chunk-ZEQWCBCM.js.map +0 -1
- package/dist/collection-facade-MJXSC3Q6.js +0 -44
- package/dist/cover-B5SJDHR3.js +0 -52
- package/dist/delegation-A5A75KQO.js +0 -25
- package/dist/derive-HJSMH7RA.js +0 -21
- package/dist/executor-AXE4XMLT.js +0 -26
- package/dist/executor-KGNLJD6M.js +0 -9
- package/dist/executor-XGIS6CR7.js +0 -9
- package/dist/export-accessible-VVBJM3MM.js +0 -23
- package/dist/extract-partition-LGGBTQET.js +0 -38
- package/dist/find-YS6XWB46.js +0 -11
- package/dist/in/index.js +0 -1
- package/dist/issue-LSR5PS6H.js +0 -19
- package/dist/legacy/bundle.d.ts +0 -30
- package/dist/liberate-GBSAYLPJ.js +0 -24
- package/dist/noydb-MTUBMWFE.js +0 -70
- package/dist/on/index.js +0 -17
- package/dist/port/as/index.d.ts +0 -26
- package/dist/port/at/index.d.ts +0 -18
- package/dist/port/in/index.d.ts +0 -21
- package/dist/port/on/index.d.ts +0 -27
- package/dist/port/ui/index.d.ts +0 -21
- package/dist/port/with/index.d.ts +0 -18
- package/dist/register-X462DNDM.js +0 -23
- package/dist/registry-3XMCT7MQ.js +0 -18
- package/dist/registry-KHD2I3M2.js +0 -19
- package/dist/registry-NPOWJHC4.js +0 -9
- package/dist/request-withdrawal-U7K3JTMY.js +0 -31
- package/dist/revoke-OCWDSWRQ.js +0 -24
- package/dist/seed-PWK45HDF.js.map +0 -1
- package/dist/signer-3YFBLZRN.js +0 -25
- package/dist/storage-W3GURVFU.js +0 -23
- package/dist/tx/index.js.map +0 -1
- package/dist/ui/index.js +0 -1
- package/dist/with/index.js +0 -31
- package/dist/with-lookup/aggregate/index.d.ts +0 -23
- package/dist/withdraw-accessible-Y3B2535F.js +0 -28
- /package/dist/{api-IQFZJSQO.js.map → api-ZDKTWNBB.js.map} +0 -0
- /package/dist/{backup-LU2DTZTI.js.map → backup-2UX7PRM5.js.map} +0 -0
- /package/dist/{chunk-IY23KFNZ.js.map → chunk-35NMVJ7I.js.map} +0 -0
- /package/dist/{chunk-RTEK4C4I.js.map → chunk-4JQK3L4V.js.map} +0 -0
- /package/dist/{chunk-3ELCWU56.js.map → chunk-4ZKNC6A6.js.map} +0 -0
- /package/dist/{chunk-VAIS3SOM.js.map → chunk-55LX6FSX.js.map} +0 -0
- /package/dist/{chunk-6HPG2YNX.js.map → chunk-5DRROK5W.js.map} +0 -0
- /package/dist/{chunk-S6Q37VGE.js.map → chunk-5GQEU4DN.js.map} +0 -0
- /package/dist/{chunk-TOPYT5U5.js.map → chunk-63FE525P.js.map} +0 -0
- /package/dist/{chunk-JVBO4SZL.js.map → chunk-6UBZ6I5Z.js.map} +0 -0
- /package/dist/{chunk-UFEVO57O.js.map → chunk-ABS7FMMD.js.map} +0 -0
- /package/dist/{chunk-M75ZZHSR.js.map → chunk-BLBAQRBM.js.map} +0 -0
- /package/dist/{chunk-G6EQYAL6.js.map → chunk-CI32CAFS.js.map} +0 -0
- /package/dist/{chunk-6B4DYGWO.js.map → chunk-DABACXEF.js.map} +0 -0
- /package/dist/{chunk-F6T6L2UK.js.map → chunk-DMH3VZU5.js.map} +0 -0
- /package/dist/{chunk-MQ6WOPSY.js.map → chunk-DZ2JXHWK.js.map} +0 -0
- /package/dist/{chunk-UBNCR3YK.js.map → chunk-EE7UHLKH.js.map} +0 -0
- /package/dist/{chunk-EGCRBCNA.js.map → chunk-EKRSCRNM.js.map} +0 -0
- /package/dist/{chunk-IRQY7IR5.js.map → chunk-FRMPM7WG.js.map} +0 -0
- /package/dist/{as/index.js.map → chunk-GJW4HX2O.js.map} +0 -0
- /package/dist/{chunk-T6GU5PPZ.js.map → chunk-GU3IP74F.js.map} +0 -0
- /package/dist/{chunk-SMIRGMS7.js.map → chunk-IXNCZTWA.js.map} +0 -0
- /package/dist/{chunk-RM2XV574.js.map → chunk-IXTSNGYY.js.map} +0 -0
- /package/dist/{chunk-PK6QCH2C.js.map → chunk-JJZGIE4U.js.map} +0 -0
- /package/dist/{chunk-DRWBEDYO.js.map → chunk-JYJFGD2H.js.map} +0 -0
- /package/dist/{chunk-KUIB4B5Q.js.map → chunk-LNZKOUJR.js.map} +0 -0
- /package/dist/{chunk-IM3QVF53.js.map → chunk-MBKVNOJS.js.map} +0 -0
- /package/dist/{chunk-N6WF5PKC.js.map → chunk-NFZGZ4AK.js.map} +0 -0
- /package/dist/{chunk-OF75ACKS.js.map → chunk-PEATRIYJ.js.map} +0 -0
- /package/dist/{chunk-N55W7KUL.js.map → chunk-QDIH2744.js.map} +0 -0
- /package/dist/{chunk-6HY2X62D.js.map → chunk-QJNCB5SK.js.map} +0 -0
- /package/dist/{chunk-2PCAVW2I.js.map → chunk-SHEEBRZ4.js.map} +0 -0
- /package/dist/{chunk-RA5VTXXG.js.map → chunk-V6UQZA2H.js.map} +0 -0
- /package/dist/{chunk-QDPZWTN2.js.map → chunk-W3G5REIU.js.map} +0 -0
- /package/dist/{chunk-WEYZTLXN.js.map → chunk-W3L64Y3J.js.map} +0 -0
- /package/dist/{chunk-CBSY2N76.js.map → chunk-WLXMTYGO.js.map} +0 -0
- /package/dist/{chunk-3U3FBR7O.js.map → chunk-X3F5YJG2.js.map} +0 -0
- /package/dist/{classified-marker-WQVIJAW2.js.map → classified-marker-7PKJBFCG.js.map} +0 -0
- /package/dist/{at/index.js.map → collection-facade-6I5K5IOD.js.map} +0 -0
- /package/dist/{bundle/index.js.map → computed-AB45PS4V.js.map} +0 -0
- /package/dist/{by → cover}/index.js.map +0 -0
- /package/dist/{in → custody}/index.js.map +0 -0
- /package/dist/{dead-filter-2A7IAJ3D.js.map → dead-filter-FL3WIUZS.js.map} +0 -0
- /package/dist/{chunk-CHFZDSE4.js.map → derive-VGS7FKE3.js.map} +0 -0
- /package/dist/{on → directory}/index.js.map +0 -0
- /package/dist/{collection-facade-MJXSC3Q6.js.map → enclave-SPEEDYZ4.js.map} +0 -0
- /package/dist/{computed-DSMPXG2Y.js.map → executor-IEBLTBCW.js.map} +0 -0
- /package/dist/{cover-B5SJDHR3.js.map → executor-OTF556PL.js.map} +0 -0
- /package/dist/{delegation-A5A75KQO.js.map → executor-RM7XWQDU.js.map} +0 -0
- /package/dist/{derive-HJSMH7RA.js.map → export-accessible-P42BQ4PB.js.map} +0 -0
- /package/dist/{enclave-7MW6ZGXW.js.map → extract-partition-TCYXRWBN.js.map} +0 -0
- /package/dist/{fanout-sidecar-WDYQ77VB.js.map → fanout-sidecar-SSMRSC2L.js.map} +0 -0
- /package/dist/{executor-AXE4XMLT.js.map → find-OZMTRIK3.js.map} +0 -0
- /package/dist/{ui → introspection}/index.js.map +0 -0
- /package/dist/{executor-KGNLJD6M.js.map → issue-FCKN5O6C.js.map} +0 -0
- /package/dist/{executor-XGIS6CR7.js.map → ledger-6XBEVWYP.js.map} +0 -0
- /package/dist/{export-accessible-VVBJM3MM.js.map → liberate-CYUOS4NC.js.map} +0 -0
- /package/dist/{extract-partition-LGGBTQET.js.map → link-set-NK6L2A5S.js.map} +0 -0
- /package/dist/{with → money}/index.js.map +0 -0
- /package/dist/{find-YS6XWB46.js.map → noydb-FZZIMLCI.js.map} +0 -0
- /package/dist/{issue-LSR5PS6H.js.map → policy/index.js.map} +0 -0
- /package/dist/{post-register-JVTMJ6OW.js.map → post-register-VFIYISUK.js.map} +0 -0
- /package/dist/{ledger-33BC4TR7.js.map → register-UKU2J6MN.js.map} +0 -0
- /package/dist/{liberate-GBSAYLPJ.js.map → registry-2VCWVHZS.js.map} +0 -0
- /package/dist/{link-set-QK22TDEX.js.map → registry-7Y5WF7GS.js.map} +0 -0
- /package/dist/{noydb-MTUBMWFE.js.map → registry-BWD2ED52.js.map} +0 -0
- /package/dist/{policy-NAHB2TUT.js.map → registry-DTWRJLSF.js.map} +0 -0
- /package/dist/{register-X462DNDM.js.map → request-withdrawal-JYDZ5XY2.js.map} +0 -0
- /package/dist/{reveal-LGBOM2BO.js.map → reveal-CL2BCW6A.js.map} +0 -0
- /package/dist/{registry-3XMCT7MQ.js.map → revoke-2TSAD2T4.js.map} +0 -0
- /package/dist/{registry-KHD2I3M2.js.map → schema-update/index.js.map} +0 -0
- /package/dist/{registry-NPOWJHC4.js.map → search/index.js.map} +0 -0
- /package/dist/{registry-VW6P6A3J.js.map → sequence/index.js.map} +0 -0
- /package/dist/{request-withdrawal-U7K3JTMY.js.map → signer-K7Z2EOMG.js.map} +0 -0
- /package/dist/{revoke-OCWDSWRQ.js.map → stale-A4J26OIC.js.map} +0 -0
- /package/dist/{signer-3YFBLZRN.js.map → storage-YVHZUISN.js.map} +0 -0
- /package/dist/{stale-FJED42DM.js.map → store/index.js.map} +0 -0
- /package/dist/{store-coordination-provider-APODTV4W.js.map → store-coordination-provider-EWRZL7XF.js.map} +0 -0
- /package/dist/{verify-26Y5GNMK.js.map → verify-7XWHJWUN.js.map} +0 -0
- /package/dist/{storage-W3GURVFU.js.map → walk-P5D6CF4V.js.map} +0 -0
- /package/dist/with-lookup/{aggregate → reduce}/canonical-key.d.ts +0 -0
- /package/dist/{with-party → with-sync}/tab-coordination.d.ts +0 -0
- /package/dist/{with-party → with-sync}/tab-write-relay.d.ts +0 -0
- /package/dist/{withdraw-accessible-Y3B2535F.js.map → withdraw-accessible-A2PWF5MZ.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/via/money/iso4217.ts","../src/via/money/fixed-point.ts","../src/via/money/paths.ts","../src/via/money/normalize.ts","../src/via/money/where.ts","../src/via/money/money-reducer.ts","../src/via/money/binding.ts","../src/via/money/descriptor.ts","../src/via/money/arith.ts","../src/via/money/branded.ts"],"sourcesContent":["/**\n * ISO 4217 minor-unit (scale) lookup.\n *\n * Maps a currency code to the number of decimal places its minor unit\n * uses — `EUR` → 2 (cents), `JPY` → 0 (no minor unit), `BHD` → 3 (fils).\n * Only listed codes are \"known\"; an unlisted code returns `null` so the\n * descriptor layer can demand an explicit `scale` / `scaleOverrides`\n * rather than silently assuming 2. This avoids the classic bug where a\n * 0-decimal currency (JPY) is stored as if it had cents.\n *\n * Coverage is the common ISO-4217 set; exotic or non-listed codes must\n * declare scale explicitly. This table is the single source of truth for\n * default scale resolution — see {@link scaleForCurrency}.\n */\nconst MINOR_UNITS: Readonly<Record<string, number>> = {\n // 2-decimal majors\n EUR: 2, USD: 2, GBP: 2, CHF: 2, CAD: 2, AUD: 2, NZD: 2, SGD: 2,\n HKD: 2, CNY: 2, INR: 2, BRL: 2, MXN: 2, ZAR: 2, RUB: 2, TRY: 2,\n PLN: 2, SEK: 2, NOK: 2, DKK: 2, CZK: 2, HUF: 2, RON: 2, ILS: 2,\n THB: 2, PHP: 2, MYR: 2, IDR: 2, AED: 2, SAR: 2, QAR: 2, EGP: 2,\n // 0-decimal\n JPY: 0, KRW: 0, ISK: 0, CLP: 0, VND: 0, XOF: 0, XAF: 0, PYG: 0,\n // 3-decimal\n BHD: 3, KWD: 3, OMR: 3, TND: 3, JOD: 3, IQD: 3, LYD: 3,\n}\n\n/**\n * Return the ISO-4217 minor-unit scale for a currency code, or `null`\n * when the code is not in the known set (caller must supply an explicit\n * scale).\n */\nexport function scaleForCurrency(code: string): number | null {\n const v = MINOR_UNITS[code]\n return v === undefined ? null : v\n}\n","/**\n * Pure fixed-point decimal core for the money descriptor.\n *\n * All conversion goes decimal-string ⇄ scaled `BigInt`. There is no\n * floating-point arithmetic anywhere: a value like `123.45` becomes\n * `12345n` purely by string manipulation, never by `value * 100` (which\n * would reintroduce the very drift money() exists to eliminate). BigInt\n * has no magnitude ceiling, so values past `Number.MAX_SAFE_INTEGER`\n * stay exact end-to-end.\n *\n * This module knows nothing about currencies, descriptors, or storage —\n * it is the isolated, exhaustively-tested arithmetic kernel.\n */\n\nexport type RoundingMode =\n | 'half-up'\n | 'half-even'\n | 'half-down'\n | 'up'\n | 'down'\n | 'ceil'\n | 'floor'\n\nexport type ParseResult =\n | { ok: true; value: bigint }\n | { ok: false; reason: 'precision' | 'nonfinite' }\n\n/**\n * Expand exponent notation (`1e-7`, `1.5e3`) into a plain decimal\n * string. Returns the input unchanged when it carries no exponent.\n */\nfunction expandExponent(s: string): string {\n const m = /^([+-]?)(\\d+)(?:\\.(\\d+))?[eE]([+-]?\\d+)$/.exec(s)\n if (!m) return s\n const sign = m[1] === '-' ? '-' : ''\n const intp = m[2]!\n const frac = m[3] ?? ''\n const exp = Number(m[4]!)\n const digits = intp + frac\n const pointPos = intp.length + exp\n let body: string\n if (pointPos <= 0) {\n body = '0.' + '0'.repeat(-pointPos) + digits\n } else if (pointPos >= digits.length) {\n body = digits + '0'.repeat(pointPos - digits.length)\n } else {\n body = digits.slice(0, pointPos) + '.' + digits.slice(pointPos)\n }\n return sign + body\n}\n\n/**\n * Normalize an input to a canonical decimal string, or `null` if it is\n * non-finite / not a valid decimal.\n */\nfunction toCanonicalDecimalString(input: number | string): string | null {\n let s: string\n if (typeof input === 'number') {\n if (!Number.isFinite(input)) return null\n s = String(input)\n } else {\n s = input.trim()\n }\n s = expandExponent(s)\n if (s.startsWith('+')) s = s.slice(1)\n // optional sign, then digits with at most one dot, at least one digit\n if (!/^-?(\\d+(\\.\\d*)?|\\.\\d+)$/.test(s)) return null\n return s\n}\n\n/**\n * Decide whether the truncated magnitude should be incremented by one\n * minor unit, given the discarded fractional tail. Only called when the\n * tail is known to contain a non-zero digit.\n */\nfunction shouldRoundUp(\n negative: boolean,\n lastKeptDigit: number,\n firstDiscarded: number,\n hasMoreNonZeroAfterFirst: boolean,\n mode: RoundingMode,\n): boolean {\n switch (mode) {\n case 'up':\n return true\n case 'down':\n return false\n case 'ceil':\n return !negative\n case 'floor':\n return negative\n case 'half-up':\n return firstDiscarded >= 5\n case 'half-down':\n return firstDiscarded > 5 || (firstDiscarded === 5 && hasMoreNonZeroAfterFirst)\n case 'half-even':\n if (firstDiscarded > 5) return true\n if (firstDiscarded < 5) return false\n // exactly 5 leading the tail\n return hasMoreNonZeroAfterFirst || lastKeptDigit % 2 === 1\n }\n}\n\n/**\n * Parse a decimal (`number | string`) into a scaled `BigInt` at the\n * given scale. When the input carries more fractional precision than\n * `scale`:\n * - `rounding` omitted ⇒ `{ ok: false, reason: 'precision' }`\n * - `rounding` set ⇒ the tail is rounded per the mode.\n * Non-finite / unparseable input ⇒ `{ ok: false, reason: 'nonfinite' }`.\n */\nexport function parseToScaledInt(\n input: number | string,\n scale: number,\n rounding?: RoundingMode,\n): ParseResult {\n const canonical = toCanonicalDecimalString(input)\n if (canonical === null) return { ok: false, reason: 'nonfinite' }\n\n const negative = canonical.startsWith('-')\n const unsigned = negative ? canonical.slice(1) : canonical\n const dot = unsigned.indexOf('.')\n const intPart = dot === -1 ? unsigned : unsigned.slice(0, dot)\n const fracPart = dot === -1 ? '' : unsigned.slice(dot + 1)\n\n const intDigits = intPart === '' ? '0' : intPart\n\n if (fracPart.length <= scale) {\n const keep = fracPart.padEnd(scale, '0')\n const magnitude = BigInt(intDigits + keep)\n return { ok: true, value: negative && magnitude !== 0n ? -magnitude : magnitude }\n }\n\n // More precision than scale — inspect the discarded tail.\n const keep = fracPart.slice(0, scale)\n const tail = fracPart.slice(scale)\n const magnitudeDigits = intDigits + keep\n let magnitude = BigInt(magnitudeDigits)\n\n if (/^0+$/.test(tail)) {\n // tail is all zeros — exact, no rounding required.\n return { ok: true, value: negative && magnitude !== 0n ? -magnitude : magnitude }\n }\n\n if (rounding === undefined) return { ok: false, reason: 'precision' }\n\n const lastKeptDigit = Number(magnitudeDigits[magnitudeDigits.length - 1])\n const firstDiscarded = Number(tail[0])\n const hasMoreNonZeroAfterFirst = /[1-9]/.test(tail.slice(1))\n if (shouldRoundUp(negative, lastKeptDigit, firstDiscarded, hasMoreNonZeroAfterFirst, rounding)) {\n magnitude += 1n\n }\n return { ok: true, value: negative && magnitude !== 0n ? -magnitude : magnitude }\n}\n\n/**\n * Number of fractional digits in the canonical decimal rendering of\n * `input` (`'123.45'` → 2, `100` → 0, `'1e-7'` → 7), or `null` when the\n * input is non-finite / not a decimal. Used to infer the working scale\n * of arithmetic helpers from their canonical-string inputs.\n */\nexport function decimalScaleOf(input: number | string): number | null {\n const s = toCanonicalDecimalString(input)\n if (s === null) return null\n const dot = s.indexOf('.')\n return dot === -1 ? 0 : s.length - dot - 1\n}\n\n/**\n * Re-scale a scaled `BigInt` from `fromScale` to `toScale`. Scaling up\n * is exact (append zeros); scaling down rounds the discarded tail per\n * `rounding`. The rounding decision reuses the same kernel as\n * {@link parseToScaledInt}, so `rescaleScaledInt(parse('1.005', 3), 3, 2)`\n * and `parse('1.005', 2, mode)` agree for every mode.\n */\nexport function rescaleScaledInt(\n value: bigint,\n fromScale: number,\n toScale: number,\n rounding: RoundingMode = 'half-up',\n): bigint {\n if (toScale >= fromScale) return value * 10n ** BigInt(toScale - fromScale)\n const drop = fromScale - toScale\n const negative = value < 0n\n const absStr = (negative ? -value : value).toString().padStart(drop + 1, '0')\n const keptStr = absStr.slice(0, absStr.length - drop)\n const tail = absStr.slice(absStr.length - drop)\n let magnitude = BigInt(keptStr)\n if (!/^0+$/.test(tail)) {\n const lastKeptDigit = Number(keptStr[keptStr.length - 1])\n const firstDiscarded = Number(tail[0])\n const hasMoreNonZeroAfterFirst = /[1-9]/.test(tail.slice(1))\n if (shouldRoundUp(negative, lastKeptDigit, firstDiscarded, hasMoreNonZeroAfterFirst, rounding)) {\n magnitude += 1n\n }\n }\n return negative && magnitude !== 0n ? -magnitude : magnitude\n}\n\n/**\n * Render a scaled `BigInt` back to its canonical decimal string at the\n * given scale. `(12345n, 2)` → `'123.45'`; `(5n, 0)` → `'5'`;\n * `(-1n, 2)` → `'-0.01'`. Exact for any magnitude.\n */\nexport function formatScaledInt(value: bigint, scale: number): string {\n const negative = value < 0n\n const abs = (negative ? -value : value).toString()\n if (scale === 0) return (negative ? '-' : '') + abs\n const padded = abs.padStart(scale + 1, '0')\n const cut = padded.length - scale\n const intPart = padded.slice(0, cut)\n const fracPart = padded.slice(cut)\n return (negative ? '-' : '') + intPart + '.' + fracPart\n}\n","/**\n * Nested-path support for `moneyFields` declarations.\n *\n * A descriptor map key is a PATH, not just a top-level field name:\n *\n * - `'total'` — top-level scalar (the original form)\n * - `'billing.monthlyServiceFee'` — nested object member\n * - `'lineItems[].amount'` — member of every element of an array\n * - `'summary.*'` — every value of a record/map object\n * - `'income[].taxWithheld'`, `'byMonth.*.amount'` — segments compose\n *\n * Paths are parsed ONCE, at collection registration, and a syntactically\n * invalid declaration throws there — loudly, at setup time. (The\n * historical failure mode this kills: a declared-but-unreachable path\n * that was silently ignored, leaving the field un-quantized — a latent\n * 100× bug.) A path that doesn't match a given record at write time is\n * NOT an error — optional fields and empty arrays are legitimate — but\n * a path segment that hits a value of the WRONG SHAPE (`[]` on a\n * non-array, `.*` on a non-object) throws, because that means the\n * declaration and the data model disagree.\n */\n\nimport { ValidationError } from '../../kernel/errors.js'\n\nexport type MoneyPathSegment =\n | { readonly kind: 'key'; readonly key: string; readonly array: boolean }\n | { readonly kind: 'wildcard'; readonly array: boolean }\n\nconst SEGMENT_RE = /^(\\*|[^.[\\]*]+)(\\[\\])?$/\n\nconst parseCache = new Map<string, readonly MoneyPathSegment[]>()\n\n/**\n * Parse a moneyFields path into segments. Throws `ValidationError` on\n * bad syntax. Results are memoized — the same declared paths are walked\n * on every write/read.\n */\nexport function parseMoneyPath(path: string): readonly MoneyPathSegment[] {\n const cached = parseCache.get(path)\n if (cached) return cached\n\n if (typeof path !== 'string' || path.length === 0) {\n throw new ValidationError('moneyFields: path must be a non-empty string')\n }\n const segments: MoneyPathSegment[] = []\n for (const part of path.split('.')) {\n const m = SEGMENT_RE.exec(part)\n if (!m) {\n throw new ValidationError(\n `moneyFields: invalid path \"${path}\" — segment \"${part}\" must be a key, \"key[]\", \"*\", or \"*[]\"`,\n )\n }\n const array = m[2] === '[]'\n segments.push(\n m[1] === '*' ? { kind: 'wildcard', array } : { kind: 'key', key: m[1]!, array },\n )\n }\n parseCache.set(path, segments)\n return segments\n}\n\n/** True when the path is a plain top-level field name (the fast path). */\nexport function isSimpleMoneyPath(path: string): boolean {\n return !path.includes('.') && !path.includes('[') && !path.includes('*')\n}\n\n/**\n * Validate every declared path's syntax. Call at collection\n * registration so typos throw at setup, not silently no-op per write.\n */\nexport function validateMoneyFieldPaths(moneyFields: Record<string, unknown>): void {\n for (const path of Object.keys(moneyFields)) parseMoneyPath(path)\n}\n\n/**\n * The leaf visitor: receives the (already-cloned) container holding the\n * money value and the key/index of that value. Mutating the container\n * is safe — every container on a matched path is a fresh clone.\n */\nexport type MoneyLeafVisitor = (\n container: Record<string, unknown> | unknown[],\n key: string | number,\n) => void\n\n/**\n * Walk `node` along `segments`, copy-on-write-cloning every container on\n * a matched path, and call `visit` at each leaf position. Returns the\n * (possibly new) node; unmatched paths return the input untouched.\n *\n * Shape mismatches (`[]` on a non-array, `*` on a non-object) THROW on\n * the write path — the declaration and the data model disagree, and\n * writing through would store an un-quantized amount. On the READ path\n * pass `lenient: true` instead: stored data predating a declaration\n * change must stay readable, so a mismatched node is returned untouched\n * (mirrors the defensive `continue` the flat decoder always had).\n */\nexport function transformAtMoneyPath(\n node: unknown,\n path: string,\n segments: readonly MoneyPathSegment[],\n index: number,\n visit: MoneyLeafVisitor,\n lenient: boolean,\n): unknown {\n if (node === null || node === undefined) return node\n const seg = segments[index]!\n const last = index === segments.length - 1\n\n if (seg.kind === 'key') {\n if (typeof node !== 'object' || Array.isArray(node)) {\n if (lenient) return node\n throw new ValidationError(\n `moneyFields: path \"${path}\" expected an object at segment \"${seg.key}\", got ${Array.isArray(node) ? 'an array' : typeof node}`,\n )\n }\n const obj = node as Record<string, unknown>\n if (!(seg.key in obj) || obj[seg.key] === null || obj[seg.key] === undefined) return node\n\n if (seg.array) {\n const arr = obj[seg.key]\n if (!Array.isArray(arr)) {\n if (lenient) return node\n throw new ValidationError(\n `moneyFields: path \"${path}\" declares \"${seg.key}[]\" but the value is not an array`,\n )\n }\n const cloned = [...arr]\n if (last) {\n for (let i = 0; i < cloned.length; i++) visit(cloned, i)\n } else {\n for (let i = 0; i < cloned.length; i++) {\n cloned[i] = transformAtMoneyPath(cloned[i], path, segments, index + 1, visit, lenient)\n }\n }\n return { ...obj, [seg.key]: cloned }\n }\n\n const clone = { ...obj }\n if (last) {\n visit(clone, seg.key)\n } else {\n clone[seg.key] = transformAtMoneyPath(clone[seg.key], path, segments, index + 1, visit, lenient)\n }\n return clone\n }\n\n // wildcard\n if (seg.array) {\n if (!Array.isArray(node)) {\n if (lenient) return node\n throw new ValidationError(`moneyFields: path \"${path}\" declares \"*[]\" but the value is not an array`)\n }\n const cloned = [...node]\n if (last) {\n for (let i = 0; i < cloned.length; i++) visit(cloned, i)\n } else {\n for (let i = 0; i < cloned.length; i++) {\n cloned[i] = transformAtMoneyPath(cloned[i], path, segments, index + 1, visit, lenient)\n }\n }\n return cloned\n }\n if (typeof node !== 'object' || Array.isArray(node)) {\n if (lenient) return node\n throw new ValidationError(\n `moneyFields: path \"${path}\" applies \"*\" to a non-object (${Array.isArray(node) ? 'array — use \"*[]\"' : typeof node})`,\n )\n }\n const obj = node as Record<string, unknown>\n const clone: Record<string, unknown> = { ...obj }\n for (const key of Object.keys(obj)) {\n const v = clone[key]\n if (v === null || v === undefined) continue\n if (last) visit(clone, key)\n else clone[key] = transformAtMoneyPath(v, path, segments, index + 1, visit, lenient)\n }\n return clone\n}\n","/**\n * Write-side and read-side normalization for money fields.\n *\n * - **Write** ({@link quantizeMoneyFields}): user input (`number | string`,\n * or `{ amount, currency }` in multi mode) → the canonical *stored*\n * form — a scaled-integer **digit string** (`'12345'`), or\n * `{ amount: '12345', currency: 'EUR' }` in multi mode. A JSON number\n * would truncate past 2^53, so the integer is always stored as a string.\n * - **Read** ({@link decodeMoneyFields}): stored form → an exact decimal\n * string (`'123.45'`) plus, when formatting is requested, the virtual\n * `<field>Formatted` (locale currency string) and `<field>Number`\n * (convenience JS number, explicitly lossy past 2^53).\n *\n * Both return a shallow clone; neither mutates the input record.\n */\n\nimport { parseToScaledInt, formatScaledInt } from './fixed-point.js'\nimport { MoneyPrecisionError, type MoneyDescriptor } from './descriptor.js'\nimport { isSimpleMoneyPath, parseMoneyPath, transformAtMoneyPath } from './paths.js'\n\ninterface MoneyValueObject {\n amount: unknown\n currency: unknown\n}\n\nfunction isMoneyValueObject(v: unknown): v is MoneyValueObject {\n return typeof v === 'object' && v !== null && 'currency' in v\n}\n\n/** Parse one decimal input to a stored digit string at `scale`. */\nfunction quantizeAmount(\n field: string,\n input: number | string,\n scale: number,\n rounding: MoneyDescriptor['rounding'],\n): string {\n const r = parseToScaledInt(input, scale, rounding)\n if (!r.ok) {\n if (r.reason === 'precision') throw new MoneyPrecisionError(field, input, scale)\n throw new TypeError(`money: field \"${field}\" value ${JSON.stringify(input)} is not a finite decimal`)\n }\n return r.value.toString()\n}\n\n/**\n * Canonicalize a STORED-form record's money fields for an internal\n * callback boundary. Gate handlers (guard `check` /\n * `frozenFields` / `onDelete`, period guard, amendment invariants) and\n * derivation `derive(source, ctx)` callbacks are user-facing: they must\n * see the same decoded canonical decimal that `get()` returns — the\n * scaled-int storage form never escapes. Decoded with `'raw'` (no\n * `<field>Formatted`/`<field>Number` virtuals): these boundaries carry\n * no locale, and fabricating one would re-create a two-read-paths\n * skew inside comparisons.\n */\nexport function canonicalizeStoredMoney(\n record: unknown,\n moneyFields: Record<string, MoneyDescriptor> | undefined,\n): unknown {\n if (record === null || record === undefined) return record\n if (!moneyFields || Object.keys(moneyFields).length === 0) return record\n return decodeMoneyFields(record as Record<string, unknown>, moneyFields, 'raw')\n}\n\n/**\n * Canonicalize an INCOMING record's money fields at the top of the\n * write pipeline. Raw user input (pre-quantize) may hold a\n * number (`10000`), a major-unit string (`'10000.00'`), or a spread of\n * an already-decoded read. Quantize→decode folds all three to the\n * canonical decimal string, so gate handlers, computed-field\n * callbacks, and schema validation all see the `get()` shape — and\n * freeze-style guards comparing `incoming[f]` vs `existing[f]` see\n * equal values for an unchanged field. Best-effort: input that fails\n * to quantize passes through unchanged — the write path quantizes\n * again after validation and surfaces the real\n * `MoneyPrecisionError`/`TypeError`.\n */\nexport function canonicalizeIncomingMoney(\n record: unknown,\n moneyFields: Record<string, MoneyDescriptor> | undefined,\n): unknown {\n if (!moneyFields || Object.keys(moneyFields).length === 0) return record\n try {\n return decodeMoneyFields(\n quantizeMoneyFields(record as Record<string, unknown>, moneyFields),\n moneyFields,\n 'raw',\n )\n } catch {\n return record\n }\n}\n\n/** Quantize ONE field value (any nesting level) to its stored form. */\nfunction quantizeValue(field: string, raw: unknown, desc: MoneyDescriptor): unknown {\n if (desc.mode === 'fixed') {\n const currency = desc.fixedCurrency!\n return quantizeAmount(field, raw as number | string, desc.scaleFor(currency), desc.rounding)\n }\n // multi mode\n let amount: number | string\n let currency: string\n if (isMoneyValueObject(raw)) {\n currency = String(raw.currency)\n amount = raw.amount as number | string\n } else {\n const sole = desc.soleCurrency()\n if (sole === undefined) {\n throw new TypeError(\n `money: field \"${field}\" is multi-currency — write { amount, currency }, not a bare amount`,\n )\n }\n currency = sole\n amount = raw as number | string\n }\n const scale = desc.scaleFor(currency) // throws MoneyCurrencyError if disallowed\n return { amount: quantizeAmount(field, amount, scale, desc.rounding), currency }\n}\n\n/**\n * Convert money fields in `record` from user input to their canonical\n * stored form. Returns a shallow clone (deep along declared nested\n * paths). A nested path whose declared shape disagrees with the\n * data throws: writing through would store an un-quantized amount.\n */\nexport function quantizeMoneyFields<T extends Record<string, unknown>>(\n record: T,\n moneyFields: Record<string, MoneyDescriptor>,\n): T {\n let out: Record<string, unknown> = { ...record }\n for (const [path, desc] of Object.entries(moneyFields)) {\n if (isSimpleMoneyPath(path)) {\n const raw = out[path]\n if (raw === null || raw === undefined) continue\n out[path] = quantizeValue(path, raw, desc)\n continue\n }\n out = transformAtMoneyPath(out, path, parseMoneyPath(path), 0, (container, key) => {\n const raw = (container as Record<string | number, unknown>)[key]\n if (raw === null || raw === undefined) return\n ;(container as Record<string | number, unknown>)[key] = quantizeValue(path, raw, desc)\n }, /* lenient */ false) as Record<string, unknown>\n }\n return out as T\n}\n\nfunction formatCurrency(decimal: string, currency: string, scale: number, locale: string): string {\n const fmt = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n minimumFractionDigits: scale,\n maximumFractionDigits: scale,\n })\n // V8's Intl.format accepts a decimal STRING and formats it at full\n // precision (exact past 2^53). The TS lib types only declare\n // number|bigint, so cast — a number arg here would re-introduce the\n // float drift this whole feature exists to eliminate.\n return (fmt.format as unknown as (value: string) => string)(decimal)\n}\n\n/**\n * The stored scaled-integer value of a money field as a `BigInt`, for\n * exact numeric comparison (e.g. `orderBy` / sorting), or `null` when the\n * stored value is missing/malformed. Mirrors the stored form `decodeValue`\n * reads: a bare scaled-int (fixed mode) or `{ amount, currency }`\n * (multi-currency). Comparison is in scaled space and is exact within a\n * single currency/scale (the `where` / `sum` BigInt model); across\n * currencies of different scales the raw scaled comparison is best-effort.\n */\nexport function moneyScaledValue(stored: unknown, desc: MoneyDescriptor): bigint | null {\n let raw: unknown\n if (desc.mode === 'fixed') {\n raw = stored\n } else {\n if (!isMoneyValueObject(stored)) return null\n raw = stored.amount\n }\n if (typeof raw !== 'string' && typeof raw !== 'number') return null\n try {\n return BigInt(String(raw))\n } catch {\n return null\n }\n}\n\n/**\n * The `ViaBinding.canonicalizeIndexKey` implementation for money (#672) —\n * bucket an eager index's money field entries by the BigInt-normalized\n * scaled-int string, not the raw stored bytes, so a pre-declaration /\n * non-canonical value (e.g. `'0100'`) lands under the SAME key a canonical\n * write produces (`'100'`). Only FIXED-mode declared money fields\n * participate — multi-mode stores `{ amount, currency }`, which has no\n * single bucketable scalar (mirrors `moneyIndexProbe`'s fixed-only gate,\n * `via/money/where.ts`). `undefined` when `field` isn't a declared\n * fixed-mode money field, or the stored value doesn't parse — in both\n * cases the caller falls back to the raw stringified bucket, which is\n * exactly what the scan (`evaluateMoneyClause`) also treats as a\n * non-match, preserving fast-path/scan parity.\n */\nexport function canonicalizeMoneyIndexKey(\n field: string,\n rawValue: unknown,\n moneyFields: Record<string, MoneyDescriptor>,\n): string | undefined {\n const desc = moneyFields[field]\n if (!desc || desc.mode !== 'fixed') return undefined\n return moneyScaledValue(rawValue, desc)?.toString()\n}\n\n/**\n * Decode ONE stored field value to its read shape, or `null` when the\n * stored value is malformed (defensive — never brick a read).\n */\nfunction decodeValue(\n stored: unknown,\n desc: MoneyDescriptor,\n): { decoded: unknown; decimal: string; currency: string; scale: number } | null {\n let currency: string\n let scaledIntString: string\n if (desc.mode === 'fixed') {\n if (typeof stored !== 'string' && typeof stored !== 'number') return null\n currency = desc.fixedCurrency!\n scaledIntString = String(stored)\n } else {\n if (!isMoneyValueObject(stored)) return null // defensive: malformed stored value\n const amount = stored.amount\n if (typeof stored.currency !== 'string' || (typeof amount !== 'string' && typeof amount !== 'number')) return null\n currency = stored.currency\n scaledIntString = String(amount)\n }\n const scale = desc.scaleFor(currency)\n let decimal: string\n try {\n decimal = formatScaledInt(BigInt(scaledIntString), scale)\n } catch {\n return null // defensive: non-integer stored value\n }\n return {\n decoded: desc.mode === 'fixed' ? decimal : { amount: decimal, currency },\n decimal,\n currency,\n scale,\n }\n}\n\n/**\n * money's `presentLate` hook (#669) — for each field in `virtualMoney` (money ∩\n * virtual-mode computed on the SAME field), quantize the computed fn's fresh\n * MAJOR-UNITS output to the descriptor's scale (with its declared rounding)\n * and present it EXACTLY like a stored money field: the exact decimal string\n * (via {@link formatScaledInt}), plus `<field>Formatted`/`<field>Number` when\n * `locale !== 'raw'`. NEVER the scaled-int decode {@link decodeMoneyFields}\n * runs for a genuinely-stored value — that would misread a virtual field's\n * raw major-unit `21` as 21 SCALED units (`'0.21'`, the #665 corruption this\n * must not reintroduce). Runs AFTER computed's `present()` (the pipeline's\n * `presentLate` fold point, `kernel/via/pipeline.ts`), so `record[field]`\n * already holds the fn's fresh output by the time this runs.\n *\n * Absent/null value → left untouched (nothing to dress). Unparseable value\n * (fails `parseToScaledInt` — e.g. excess precision with no declared\n * rounding) → left RAW, no throw: read-time dressing must never brick a\n * read. Fixed-mode fields only — a virtual field's computed output has no\n * natural `{ amount, currency }` shape to parse for multi-currency mode.\n */\nexport function presentVirtualMoneyFields<T extends Record<string, unknown>>(\n record: T,\n moneyFields: Record<string, MoneyDescriptor>,\n virtualMoney: ReadonlySet<string>,\n locale: string | undefined,\n): T {\n let out: Record<string, unknown> = record\n const format = locale !== 'raw'\n const fmtLocale = typeof locale === 'string' && locale !== 'raw' ? locale : 'en-US'\n for (const field of virtualMoney) {\n const desc = moneyFields[field]\n if (!desc || desc.mode !== 'fixed') continue\n const raw = out[field]\n if (raw === null || raw === undefined) continue\n if (typeof raw !== 'number' && typeof raw !== 'string') continue\n const currency = desc.fixedCurrency!\n const scale = desc.scaleFor(currency)\n const r = parseToScaledInt(raw, scale, desc.rounding)\n if (!r.ok) continue // unparseable / excess precision with no rounding declared — leave raw, no throw\n if (out === record) out = { ...record }\n const decimal = formatScaledInt(r.value, scale)\n out[field] = decimal\n if (format) {\n out[`${field}Formatted`] = formatCurrency(decimal, currency, scale, fmtLocale)\n out[`${field}Number`] = Number(decimal)\n }\n }\n return out as T\n}\n\n/**\n * Convert money fields in `record` from stored form to the read shape:\n * an exact decimal string, plus `<field>Formatted` / `<field>Number`\n * virtuals when `locale !== 'raw'`. Returns a shallow clone (deep along\n * declared nested paths; virtuals land as siblings inside the\n * nested container, e.g. each `lineItems[]` element gains\n * `amountFormatted`, except for values held directly in arrays where a\n * scalar has no sibling slot). The decode walk is LENIENT: stored data\n * predating a declaration change must stay readable.\n */\nexport function decodeMoneyFields<T extends Record<string, unknown>>(\n record: T,\n moneyFields: Record<string, MoneyDescriptor>,\n locale: string | undefined,\n): T {\n let out: Record<string, unknown> = { ...record }\n const format = locale !== 'raw'\n const fmtLocale = typeof locale === 'string' && locale !== 'raw' ? locale : 'en-US'\n\n for (const [path, desc] of Object.entries(moneyFields)) {\n if (isSimpleMoneyPath(path)) {\n const stored = out[path]\n if (stored === null || stored === undefined) continue\n const r = decodeValue(stored, desc)\n if (r === null) continue\n out[path] = r.decoded\n if (format) {\n out[`${path}Formatted`] = formatCurrency(r.decimal, r.currency, r.scale, fmtLocale)\n out[`${path}Number`] = Number(r.decimal)\n }\n continue\n }\n out = transformAtMoneyPath(out, path, parseMoneyPath(path), 0, (container, key) => {\n const stored = (container as Record<string | number, unknown>)[key]\n if (stored === null || stored === undefined) return\n const r = decodeValue(stored, desc)\n if (r === null) return\n ;(container as Record<string | number, unknown>)[key] = r.decoded\n if (format && typeof key === 'string' && !Array.isArray(container)) {\n container[`${key}Formatted`] = formatCurrency(r.decimal, r.currency, r.scale, fmtLocale)\n container[`${key}Number`] = Number(r.decimal)\n }\n }, /* lenient */ true) as Record<string, unknown>\n }\n return out as T\n}\n","/**\n * Money-aware `where()` comparison.\n *\n * Query clauses evaluate against RAW stored records — money decode\n * happens on output only — so a money field's stored form is a\n * scaled-integer digit string (`'1000000'`) while the caller naturally\n * writes the operand in major units (`10000`, `'10000.00'`). Without a\n * rewrite the comparison is silently wrong by the scale factor, and a\n * string-vs-number comparison is excluded by `isComparable` anyway.\n *\n * Two halves:\n *\n * - {@link moneyFieldClause} runs at QUERY BUILD time: it quantizes the\n * caller's major-unit operand into stored scaled-int space via the\n * same `parseToScaledInt` path as writes, so a malformed operand\n * throws at `.where()` — not silently filters everything out.\n * - {@link evaluateMoneyClause} runs per record and compares\n * `BigInt`-exact in scaled space (exact past 2^53, like the rest of\n * the money service).\n *\n * Currency semantics (multi mode): an operand carries one currency —\n * explicit via `{ amount, currency }`, or the descriptor's sole allowed\n * currency for a bare amount. A record in a DIFFERENT currency has no\n * defined order against the operand: it matches `!=` and nothing else.\n */\n\nimport { parseToScaledInt } from './fixed-point.js'\nimport { MoneyUnsupportedError, type MoneyDescriptor } from './descriptor.js'\nimport type { Operator } from '../../kernel/query/predicate.js'\n\n/** One quantized operand value: scaled digit string + its currency. */\ninterface MoneyOperandEntry {\n readonly scaled: string\n readonly currency: string\n}\n\n/**\n * The opaque `via` clause payload for a `where()` over a declared money\n * field (see `ViaBinding.buildClause` in kernel/via/index.ts). `entries` holds\n * one element for comparison ops, two for `between` (lo, hi — same\n * currency), N for `in`.\n */\nexport interface MoneyWhereOperand {\n readonly mode: 'fixed' | 'multi'\n readonly entries: ReadonlyArray<MoneyOperandEntry>\n}\n\ninterface MoneyValueObject {\n amount: unknown\n currency: unknown\n}\n\nfunction isMoneyValueObject(v: unknown): v is MoneyValueObject {\n return typeof v === 'object' && v !== null && 'currency' in v\n}\n\n/** Quantize ONE operand value to scaled space, resolving its currency. */\nfunction parseOperand(field: string, raw: unknown, desc: MoneyDescriptor): MoneyOperandEntry {\n let amount: unknown\n let currency: string\n if (desc.mode === 'fixed') {\n currency = desc.fixedCurrency!\n amount = raw\n } else if (isMoneyValueObject(raw)) {\n currency = String(raw.currency)\n amount = raw.amount\n } else {\n const sole = desc.soleCurrency()\n if (sole === undefined) {\n throw new MoneyUnsupportedError(\n `where(\"${field}\"): field is multi-currency — compare against { amount, currency }, not a bare amount`,\n )\n }\n currency = sole\n amount = raw\n }\n if (typeof amount !== 'number' && typeof amount !== 'string') {\n throw new MoneyUnsupportedError(\n `where(\"${field}\"): operand ${JSON.stringify(raw)} is not a money amount`,\n )\n }\n const r = parseToScaledInt(amount, desc.scaleFor(currency), desc.rounding)\n if (!r.ok) {\n throw new MoneyUnsupportedError(\n `where(\"${field}\"): operand ${JSON.stringify(amount)} is not a finite decimal`,\n )\n }\n return { scaled: r.value.toString(), currency }\n}\n\n/**\n * Build the `via` clause payload ({@link MoneyWhereOperand}) for a\n * `where()` over a declared money field — the `ViaBinding.buildClause`\n * implementation for money. The operand is quantized into stored\n * scaled-int space NOW — build time — so typos throw at the call site.\n */\nexport function moneyFieldClause(\n field: string,\n op: Operator,\n value: unknown,\n desc: MoneyDescriptor,\n): MoneyWhereOperand {\n switch (op) {\n case '==': case '!=': case '<': case '<=': case '>': case '>=': {\n const e = parseOperand(field, value, desc)\n return { mode: desc.mode, entries: [e] }\n }\n case 'between': {\n if (!Array.isArray(value) || value.length !== 2) {\n throw new MoneyUnsupportedError(`where(\"${field}\"): 'between' needs a [lo, hi] tuple`)\n }\n const lo = parseOperand(field, value[0], desc)\n const hi = parseOperand(field, value[1], desc)\n if (lo.currency !== hi.currency) {\n throw new MoneyUnsupportedError(\n `where(\"${field}\"): 'between' bounds mix currencies (${lo.currency} vs ${hi.currency})`,\n )\n }\n return { mode: desc.mode, entries: [lo, hi] }\n }\n case 'in': {\n if (!Array.isArray(value)) {\n throw new MoneyUnsupportedError(`where(\"${field}\"): 'in' needs an array of amounts`)\n }\n return { mode: desc.mode, entries: value.map(v => parseOperand(field, v, desc)) }\n }\n default:\n // contains / startsWith — string ops have no meaning in scaled space.\n throw new MoneyUnsupportedError(\n `where(\"${field}\"): operator '${op}' is not supported on a money field`,\n )\n }\n}\n\n/**\n * The `via` index-probe operand for a `where()` over a declared money\n * field (see `ViaBinding.indexProbe` in kernel/via/index.ts) — the STORED-form\n * value `CollectionIndexes.lookupEqual`/`lookupIn` (`with-lookup/indexing/\n * eager-indexes.ts`) can bucket directly.\n *\n * Only FIXED-mode `==`/`in` are sound:\n * - fixed-mode stores a bare scaled-int digit string (no currency\n * component), and `entries[i].scaled` is built by {@link parseOperand}\n * via the exact same `parseToScaledInt(...).value.toString()` path\n * `quantizeMoneyFields` (`via-money/normalize.ts#quantizeAmount`) uses\n * to produce the STORED value — so the two strings are byte-identical\n * by construction, and `stringifyKey` (which passes a string through\n * unchanged) buckets them the same way.\n * - multi-mode stores `{ amount, currency }` — the index would stringify\n * that object to its no-match `'\\0OBJECT\\0'` sentinel — so multi-mode\n * always returns `undefined` (no sound probe).\n * - every op besides `==`/`in` (range comparisons, `between`) has no\n * single stored-form value the hash index can serve, so they return\n * `undefined` too — the caller falls back to a scan.\n *\n * MIXED-ERA DATA (#672, fixed — including the #672 review's C1 finding): a\n * record whose stored value predates the field's `money()` declaration, or\n * otherwise bypassed `quantizeMoneyFields`, may hold a NON-canonical scaled\n * string (e.g. `'0100'` instead of `'100'`). `CollectionIndexes` no longer\n * buckets it under that raw string verbatim at ANY bucket-mutation site —\n * `build`, `upsert`, and `remove` all consult the same registered\n * canonicalizer (`ViaPipeline.canonicalizeIndexKey`; money's implementation:\n * `canonicalizeMoneyIndexKey`, `via/money/normalize.ts`), which re-parses the\n * stored value the same way the scan's `evaluateMoneyClause`/`readStored`\n * does (`BigInt(actual).toString()`). So the legacy record lands in the SAME\n * bucket a canonical write produces, an `==`/`in` probe for `'100'` finds it,\n * and — because add and remove now agree on that bucket — a later `put()`\n * (update) or `delete()` of that same legacy record cleans up the correct\n * bucket instead of stranding the id under a bucket the removal could never\n * reach. The two-string byte-identity argument above still explains WHY a\n * canonical write's probe hits directly (no canonicalization needed for the\n * common case); this note covers the pre-declaration tail.\n *\n * Boundary — CLOSED for the index layer (#677): LAZY mode's\n * `PersistedCollectionIndex` (`with-lookup/indexing/persisted-indexes.ts`)\n * now consults the SAME `ViaPipeline.canonicalizeIndexKey` at every\n * bucket-mutation site (`ingest`/`upsert`/`remove`) as `CollectionIndexes`\n * does, and its query path (`with-lookup/indexing/lazy-builder.ts`'s\n * `resolveCandidateIds()`) canonicalizes the `==`/`in` probe value before\n * calling `lookupEqual`/`lookupIn` — mirroring `candidateRecords()` above\n * resolving `indexValue` before its own `lookupEqual`/`lookupIn` call. A\n * lazy-mode mixed-era record's bucket and a canonicalized probe now agree,\n * the same as eager mode.\n *\n * Residual boundary CLOSED by #684: `LazyQuery.where()` now builds\n * `clause.via` exactly like `Query.where()`/`ScanBuilder.where()` do, and\n * `LazyQuery`'s post-filter (`lazy-builder.ts`'s `toArray()`) runs it\n * against the RAW record (a dedicated raw-fetch seam on `Collection`, split\n * out of `get()`) instead of the DECODED one — `clause.via.evaluate` (this\n * file's {@link evaluateMoneyClause}) now sees the same stored-form\n * operand/actual-value space eager's `filterRecords` does, at any `scale`.\n * Only survivors are decoded (`present()`) on the way out. Money RANGE\n * clauses additionally route around `PersistedCollectionIndex.lookupRange`\n * (raw/typed, wrong space for scaled-int money) — `resolveCandidateIds()`\n * enumerates the field's indexed ids instead and lets this now-via-aware\n * post-filter apply the correct BigInt-exact comparison. `lazyQuery().\n * where()` on a money field now agrees with `scan().where()` /\n * `query().where()` at every `scale` — for `.where()` results specifically.\n * `orderBy` ordering is a separate, still-open lazy-vs-eager divergence,\n * tracked in #695.\n */\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\nexport function moneyIndexProbe(op: Operator, payload: MoneyWhereOperand): unknown | undefined {\n if (payload.mode !== 'fixed') return undefined\n if (op === '==') return payload.entries[0]?.scaled\n if (op === 'in') return payload.entries.map(e => e.scaled)\n return undefined\n}\n\n/** Read a raw STORED money value into scaled space, or null if absent/malformed. */\nfunction readStored(actual: unknown, operand: MoneyWhereOperand): MoneyOperandEntry | null {\n let amount: unknown\n let currency: string\n if (operand.mode === 'fixed') {\n if (typeof actual !== 'string' && typeof actual !== 'number') return null\n amount = actual\n currency = operand.entries[0]?.currency ?? ''\n } else {\n if (!isMoneyValueObject(actual)) return null\n if (typeof actual.currency !== 'string') return null\n amount = actual.amount\n currency = actual.currency\n }\n if (typeof amount !== 'string' && typeof amount !== 'number') return null\n try {\n return { scaled: BigInt(amount).toString(), currency }\n } catch {\n return null\n }\n}\n\n/**\n * Per-record evaluation of a money clause: BigInt-exact comparison in\n * scaled-integer space. `actual` is the RAW stored field value.\n *\n * Missing/malformed stored values and cross-currency comparisons match\n * `!=` only — consistent with the generic clause semantics where an\n * absent field is \"not equal\" and has no defined order.\n */\nexport function evaluateMoneyClause(\n actual: unknown,\n op: Operator,\n operand: MoneyWhereOperand,\n): boolean {\n const stored = readStored(actual, operand)\n if (stored === null) return op === '!='\n const a = BigInt(stored.scaled)\n\n if (op === 'in') {\n return operand.entries.some(\n e => e.currency === stored.currency && BigInt(e.scaled) === a,\n )\n }\n if (op === 'between') {\n const [lo, hi] = operand.entries\n if (!lo || !hi || lo.currency !== stored.currency) return false\n return a >= BigInt(lo.scaled) && a <= BigInt(hi.scaled)\n }\n\n const e = operand.entries[0]\n if (!e) return false\n if (e.currency !== stored.currency) return op === '!='\n const b = BigInt(e.scaled)\n switch (op) {\n case '==': return a === b\n case '!=': return a !== b\n case '<': return a < b\n case '<=': return a <= b\n case '>': return a > b\n case '>=': return a >= b\n default: return false\n }\n}\n","/**\n * Money-aware aggregation: exact `sum` / `min` / `max` over money\n * fields.\n *\n * The generic reducers (`aggregate/reducers.ts`) read a field via\n * `readNumber`, which coerces a string (the stored scaled-integer form\n * of money, e.g. `'12345'`) to `0` — so an un-wrapped money `sum` would\n * silently return zero. {@link wrapMoneyReducers} rewrites any `sum` /\n * `min` / `max` over a declared money field into a reducer that\n * accumulates per-currency `BigInt` totals of the stored integers, so\n * the result is exact for any magnitude (past `Number.MAX_SAFE_INTEGER`\n * included).\n *\n * Results are currency-aware and never silently mix currencies:\n * - **fixed** mode → a single exact decimal string.\n * - **multi** mode → an exact `Record<currency, string>` map.\n * - **`sum` with `convertTo` + `fx`** → a single exact string, with\n * each currency converted via BigInt arithmetic (no float).\n *\n * `remove()` is implemented for every money reducer so they participate\n * in incremental live-aggregation and materialized-view maintenance\n * exactly like the generic reducers they replace.\n */\n\nimport { readPath } from '../../kernel/query/predicate.js'\nimport { formatScaledInt, parseToScaledInt } from './fixed-point.js'\nimport { scaleForCurrency } from './iso4217.js'\nimport { MoneyUnsupportedError } from './descriptor.js'\nimport type { MoneyDescriptor } from './descriptor.js'\nimport type { Reducer } from '../../with-lookup/reduce/reducers.js'\nimport type { ReduceSpec } from '../../with-lookup/reduce/reduction.js'\n\nexport type FxRates = Record<string, number | string>\n\ninterface ReadMoney {\n currency: string\n value: bigint\n}\n\n/**\n * Coerce an arbitrary money-field value into its scaled `BigInt` at the\n * given `scale`. Handles the two shapes a money field can arrive in by\n * the time it reaches a reducer:\n *\n * - **stored form** — a bare scaled-integer string (`'12345'`) or a\n * `bigint`. No decimal point, so `BigInt(v)` is the fast path.\n * - **decoded form** — a canonical decimal string (`'123.45'`), which\n * is what `query().toArray()` / `decodeMoneyFields` produce (UNION\n * arms map over decoded rows). `BigInt('123.45')` throws, so these\n * route through `parseToScaledInt(v, scale)`.\n *\n * A `number` is treated as a decimal magnitude (parsed at `scale`).\n * Anything unparseable → `null`.\n */\nfunction toScaledIntFromAny(v: unknown, scale: number): bigint | null {\n if (typeof v === 'bigint') return v\n if (typeof v === 'number') {\n const r = parseToScaledInt(v, scale)\n return r.ok ? r.value : null\n }\n if (typeof v === 'string') {\n if (!v.includes('.')) {\n // Stored scaled-integer form (e.g. '12345') — no decimal point.\n try {\n return BigInt(v)\n } catch {\n return null\n }\n }\n // Decoded canonical-decimal form (e.g. '123.45').\n const r = parseToScaledInt(v, scale)\n return r.ok ? r.value : null\n }\n return null\n}\n\n/** Read the raw stored money value (scaled integer) from a record. */\nfunction readMoney(record: unknown, field: string, desc: MoneyDescriptor): ReadMoney | null {\n const raw = readPath(record, field)\n if (raw === null || raw === undefined) return null\n if (desc.mode === 'fixed') {\n const cur = desc.fixedCurrency!\n const value = toScaledIntFromAny(raw, desc.scaleFor(cur))\n return value === null ? null : { currency: cur, value }\n }\n // multi mode: stored as { amount, currency }\n if (typeof raw !== 'object') return null\n const o = raw as { amount?: unknown; currency?: unknown }\n if (typeof o.currency !== 'string') return null\n const scale = desc.allows(o.currency) ? desc.scaleFor(o.currency) : 0\n const value = toScaledIntFromAny(o.amount, scale)\n return value === null ? null : { currency: o.currency, value }\n}\n\n/** Resolve the scale to use for a target currency (may be outside the allow-list). */\nfunction targetScaleFor(desc: MoneyDescriptor, currency: string): number {\n if (desc.allows(currency)) return desc.scaleFor(currency)\n const s = scaleForCurrency(currency)\n if (s === null) {\n throw new Error(`money: cannot determine scale for conversion target \"${currency}\"`)\n }\n return s\n}\n\n/** Parse a rate (number | string) into a scaled BigInt + its scale. */\nfunction parseRate(rate: number | string): { int: bigint; scale: number } {\n const s = String(rate).trim()\n const neg = s.startsWith('-')\n const body = neg ? s.slice(1) : s\n const dot = body.indexOf('.')\n const intPart = dot === -1 ? body : body.slice(0, dot)\n const fracPart = dot === -1 ? '' : body.slice(dot + 1)\n const int = BigInt((intPart === '' ? '0' : intPart) + fracPart)\n return { int: neg ? -int : int, scale: fracPart.length }\n}\n\n/** BigInt division of `n / d` with half-even (banker's) rounding. */\nfunction divRoundHalfEven(n: bigint, d: bigint): bigint {\n const q = n / d\n const r = n % d\n const twiceR = (r < 0n ? -r : r) * 2n\n if (twiceR < d) return q\n if (twiceR > d) return q + (n < 0n ? -1n : 1n)\n return q % 2n === 0n ? q : q + (n < 0n ? -1n : 1n)\n}\n\n/** Convert a scaled integer from `srcScale` to `targetScale` applying `rate`. */\nfunction convertScaled(value: bigint, srcScale: number, rate: number | string, targetScale: number): bigint {\n const { int: rateInt, scale: rateScale } = parseRate(rate)\n const product = value * rateInt\n const curScale = srcScale + rateScale\n if (curScale === targetScale) return product\n if (curScale < targetScale) return product * 10n ** BigInt(targetScale - curScale)\n return divRoundHalfEven(product, 10n ** BigInt(curScale - targetScale))\n}\n\nfunction finalizeSum(\n state: Map<string, bigint>,\n desc: MoneyDescriptor,\n convertTo: string | undefined,\n fx: FxRates | undefined,\n): string | Record<string, string> {\n if (convertTo !== undefined) {\n if (fx === undefined) {\n throw new Error(`money: sum convertTo \"${convertTo}\" requires an fx rate map`)\n }\n const targetScale = targetScaleFor(desc, convertTo)\n let total = 0n\n for (const [cur, v] of state) {\n if (cur === convertTo) {\n total += convertScaled(v, desc.scaleFor(cur), 1, targetScale)\n continue\n }\n const rate = fx[`${cur}->${convertTo}`]\n if (rate === undefined) {\n throw new Error(`money: no fx rate for \"${cur}->${convertTo}\"`)\n }\n total += convertScaled(v, desc.scaleFor(cur), rate, targetScale)\n }\n return formatScaledInt(total, targetScale)\n }\n\n if (desc.mode === 'fixed') {\n const cur = desc.fixedCurrency!\n return formatScaledInt(state.get(cur) ?? 0n, desc.scaleFor(cur))\n }\n\n const out: Record<string, string> = {}\n for (const [cur, v] of state) out[cur] = formatScaledInt(v, desc.scaleFor(cur))\n return out\n}\n\nfunction moneySumReducer(\n field: string,\n desc: MoneyDescriptor,\n convertTo: string | undefined,\n fx: FxRates | undefined,\n): Reducer<unknown, Map<string, bigint>> {\n return {\n op: 'sum',\n field,\n init: () => new Map<string, bigint>(),\n step: (state, record) => {\n const m = readMoney(record, field, desc)\n if (m) state.set(m.currency, (state.get(m.currency) ?? 0n) + m.value)\n return state\n },\n remove: (state, record) => {\n const m = readMoney(record, field, desc)\n if (m) state.set(m.currency, (state.get(m.currency) ?? 0n) - m.value)\n return state\n },\n finalize: (state) => finalizeSum(state, desc, convertTo, fx),\n }\n}\n\nfunction extremum(values: readonly bigint[], op: 'min' | 'max'): bigint {\n let out = values[0]!\n for (let i = 1; i < values.length; i++) {\n const v = values[i]!\n if (op === 'min' ? v < out : v > out) out = v\n }\n return out\n}\n\nfunction moneyMinMaxReducer(\n op: 'min' | 'max',\n field: string,\n desc: MoneyDescriptor,\n): Reducer<unknown, Map<string, bigint[]>> {\n return {\n op,\n field,\n init: () => new Map<string, bigint[]>(),\n step: (state, record) => {\n const m = readMoney(record, field, desc)\n if (m) {\n const arr = state.get(m.currency)\n if (arr) arr.push(m.value)\n else state.set(m.currency, [m.value])\n }\n return state\n },\n remove: (state, record) => {\n const m = readMoney(record, field, desc)\n if (m) {\n const arr = state.get(m.currency)\n if (arr) {\n const idx = arr.indexOf(m.value)\n if (idx >= 0) arr.splice(idx, 1)\n }\n }\n return state\n },\n finalize: (state) => {\n if (desc.mode === 'fixed') {\n const cur = desc.fixedCurrency!\n const arr = state.get(cur)\n if (!arr || arr.length === 0) return null\n return formatScaledInt(extremum(arr, op), desc.scaleFor(cur))\n }\n const out: Record<string, string> = {}\n for (const [cur, arr] of state) {\n if (arr.length > 0) out[cur] = formatScaledInt(extremum(arr, op), desc.scaleFor(cur))\n }\n return out\n },\n }\n}\n\n/**\n * Rewrite any `sum` / `min` / `max` reducer over a declared money field\n * into its exact BigInt money-aware equivalent. Other reducers (and\n * reducers over non-money fields) pass through unchanged. Returns a new\n * spec; the input is not mutated.\n */\nexport function wrapMoneyReducers(\n spec: ReduceSpec,\n moneyFields: Record<string, MoneyDescriptor>,\n): ReduceSpec {\n let changed = false\n const out: Record<string, Reducer<unknown, unknown>> = {}\n for (const [key, reducer] of Object.entries(spec)) {\n const field = reducer.field\n const desc = field ? moneyFields[field] : undefined\n if (desc && reducer.op === 'avg') {\n throw new MoneyUnsupportedError(\n field!,\n `avg() is not supported on money field \"${field}\" in v1 — use sum() and count() and divide at the boundary.`,\n )\n }\n if (desc && (reducer.op === 'sum' || reducer.op === 'min' || reducer.op === 'max')) {\n changed = true\n out[key] =\n reducer.op === 'sum'\n ? moneySumReducer(field!, desc, reducer.convertTo, reducer.fx as FxRates | undefined)\n : (moneyMinMaxReducer(reducer.op, field!, desc) as Reducer<unknown, unknown>)\n } else {\n out[key] = reducer\n }\n }\n return changed ? out : spec\n}\n","/**\n * The money `ViaBinding` — wires the money engine (normalize/paths/where/\n * money-reducer) into the kernel's generic Via port. `money()`\n * (descriptor.ts) calls {@link linkMoneyVia} at declaration time — the\n * same #553 static-link pattern the retired `linkMoneyEngine()` /\n * `kernel/money-runtime.ts` seam used, now the only one (Task 6 cut the\n * query DSL over to this binding and deleted the legacy seam).\n */\nimport type { ViaBinding, ViaReadCtx } from '../../kernel/via/index.js'\nimport { installViaBinder } from '../../kernel/via/index.js'\nimport type { MoneyDescriptor } from './descriptor.js'\nimport { quantizeMoneyFields, decodeMoneyFields, canonicalizeStoredMoney, canonicalizeIncomingMoney, moneyScaledValue, canonicalizeMoneyIndexKey, presentVirtualMoneyFields } from './normalize.js'\nimport { validateMoneyFieldPaths } from './paths.js'\nimport { moneyFieldClause, evaluateMoneyClause, moneyIndexProbe, type MoneyWhereOperand } from './where.js'\nimport { wrapMoneyReducers } from './money-reducer.js'\nimport type { Operator } from '../../kernel/query/predicate.js'\nimport type { ReduceSpec } from '../../with-lookup/reduce/reduction.js'\n\n/** #669 — the money binder's config bag. `virtualMoneyFields` is the money∩virtual-mode-\n * computed field-name intersection (`kernel/collection-config.ts#resolveVirtualMoneyFields`);\n * absent/empty means no field on this collection composes money with a virtual computed\n * field on itself — the pre-#669 behavior (no `presentLate`, ordinary `present()` for\n * every declared money field). */\nexport interface MoneyBindingConfig {\n readonly moneyFields: Record<string, MoneyDescriptor>\n readonly virtualMoneyFields?: ReadonlySet<string>\n}\n\nexport function moneyBinding(moneyFields: Record<string, MoneyDescriptor>, virtualMoneyFields?: ReadonlySet<string>): ViaBinding {\n validateMoneyFieldPaths(moneyFields) // declaration-time (replaces sites 1 & 2)\n const hasVirtualMoney = virtualMoneyFields !== undefined && virtualMoneyFields.size > 0\n // #669 — a field that is BOTH money AND virtual-mode computed has no value yet when\n // money's ORDINARY present() runs (money is first in `_presentOrder`, computed second —\n // the #665 invariant); decodeMoneyFields already no-ops on an absent value, but the skip\n // is made explicit here so the intent reads at the call site: dressing this field happens\n // in `presentLate` below, once computed's present() has actually produced a value.\n const ordinaryPresentFields = hasVirtualMoney\n ? Object.fromEntries(Object.entries(moneyFields).filter(([f]) => !virtualMoneyFields.has(f)))\n : moneyFields\n return {\n brand: 'money',\n posture: { encryptedAtRest: 'envelope', queryable: 'ordered', exportable: true, forgettable: true },\n covers: (field) => field in moneyFields,\n ingest: (r) => canonicalizeIncomingMoney(r, moneyFields) as Record<string, unknown>,\n canonicalizeStored: (r) => canonicalizeStoredMoney(r, moneyFields) as Record<string, unknown>,\n encodeWrite: (r) => quantizeMoneyFields(r, moneyFields),\n present: (r, ctx) => decodeMoneyFields(r, ordinaryPresentFields, typeof ctx.locale === 'string' ? ctx.locale : undefined),\n ...(hasVirtualMoney\n ? {\n presentLate: (r: Record<string, unknown>, ctx: ViaReadCtx) =>\n presentVirtualMoneyFields(r, moneyFields, virtualMoneyFields, typeof ctx.locale === 'string' ? ctx.locale : undefined),\n }\n : {}),\n buildClause: (field, op, value) => {\n const desc = moneyFields[field]\n if (!desc) return undefined\n return moneyFieldClause(field, op as Operator, value, desc) // the MoneyWhereOperand payload\n },\n evaluateClause: (actual, op, payload) => evaluateMoneyClause(actual, op as Operator, payload as MoneyWhereOperand),\n indexProbe: (op, payload) => moneyIndexProbe(op as Operator, payload as MoneyWhereOperand),\n canonicalizeIndexKey: (field, rawValue) => canonicalizeMoneyIndexKey(field, rawValue, moneyFields),\n decodeResults: (r) => decodeMoneyFields(r as Record<string, unknown>, moneyFields, 'raw'),\n compareForOrder: (field, a, b) => {\n const desc = moneyFields[field]\n if (!desc) return undefined\n const av = moneyScaledValue(a, desc); const bv = moneyScaledValue(b, desc)\n if (av === null) return bv === null ? 0 : 1\n if (bv === null) return -1\n return av < bv ? -1 : av > bv ? 1 : 0\n },\n wrapReducers: (spec) => wrapMoneyReducers(spec as ReduceSpec, moneyFields),\n }\n}\n\nexport function linkMoneyVia(): void {\n installViaBinder('money', (cfg) => {\n const c = cfg as MoneyBindingConfig\n return moneyBinding(c.moneyFields, c.virtualMoneyFields)\n })\n}\n","/**\n * The `money()` field descriptor — a branded schema-layer descriptor, a\n * sibling of `i18nText()` / `dictKey()`. It owns currency, scale, and\n * rounding policy for a field; the pure arithmetic lives in\n * {@link ./fixed-point} and default scale resolution in\n * {@link ./iso4217}.\n *\n * Two modes:\n * - **fixed** `money({ currency: 'EUR' })` — one currency for the\n * field; the value stores a bare scaled-integer string.\n * - **multi** `money({ currencies: 'any' | [...] })` — currency travels\n * per record; the value stores `{ amount, currency }`.\n *\n * `currency` and `currencies` are mutually exclusive.\n */\n\nimport type { RoundingMode } from './fixed-point.js'\nimport { scaleForCurrency } from './iso4217.js'\nimport { NoydbError } from '../../kernel/errors.js'\nimport { linkMoneyVia } from './binding.js'\n\nexport interface MoneyOptionsFixed {\n currency: string\n /** Override the ISO-4217 default scale (required for unlisted codes). */\n scale?: number\n rounding?: RoundingMode\n}\n\nexport interface MoneyOptionsMulti {\n currencies: 'any' | readonly string[]\n /** Per-currency scale overrides (required for unlisted codes). */\n scaleOverrides?: Record<string, number>\n rounding?: RoundingMode\n}\n\nexport type MoneyOptions = MoneyOptionsFixed | MoneyOptionsMulti\n\nexport interface MoneyDescriptor {\n readonly _noydbMoney: true\n /** Via port brand marker — lets a `MoneyDescriptor` satisfy the kernel's opaque `ViaDescriptor`. */\n readonly _viaBrand: 'money'\n readonly mode: 'fixed' | 'multi'\n readonly options: MoneyOptions\n readonly rounding: RoundingMode | undefined\n /** The currency for fixed mode; `undefined` in multi mode. */\n readonly fixedCurrency: string | undefined\n /** Resolve the scale for a currency, throwing if not allowed / unknown. */\n scaleFor(currency: string): number\n /** Whether this descriptor permits the given currency. */\n allows(currency: string): boolean\n /**\n * The single currency this descriptor implies, if any — fixed mode, or\n * multi mode with exactly one allow-listed currency. Lets a multi field\n * accept a bare amount unambiguously. `undefined` otherwise.\n */\n soleCurrency(): string | undefined\n}\n\n/** Raised when a written value carries more precision than `scale` allows. */\nexport class MoneyPrecisionError extends NoydbError {\n constructor(\n public readonly field: string,\n public readonly value: unknown,\n public readonly scale: number,\n ) {\n super(\n 'MONEY_PRECISION',\n `money: value ${JSON.stringify(value)} for field \"${field}\" exceeds scale ${scale} ` +\n `and no rounding mode is configured`,\n )\n this.name = 'MoneyPrecisionError'\n }\n}\n\n/** Raised when a currency is disallowed or has no resolvable scale. */\nexport class MoneyCurrencyError extends NoydbError {\n constructor(\n public readonly currency: string,\n public readonly reason: 'not-allowed' | 'unknown-scale',\n public readonly field?: string,\n ) {\n super(\n 'MONEY_CURRENCY',\n reason === 'not-allowed'\n ? `money: currency \"${currency}\" is not allowed${field ? ` for field \"${field}\"` : ''}`\n : `money: no scale known for currency \"${currency}\"${field ? ` (field \"${field}\")` : ''} — ` +\n `pass an explicit scale / scaleOverrides`,\n )\n this.name = 'MoneyCurrencyError'\n }\n}\n\n/** Raised when an aggregate operation is not supported on a money field. */\nexport class MoneyUnsupportedError extends NoydbError {\n constructor(\n public readonly field: string,\n message?: string,\n ) {\n super(\n 'MONEY_UNSUPPORTED',\n message ??\n `money: operation is not supported on field \"${field}\" — use sum() and count() and divide at the boundary`,\n )\n this.name = 'MoneyUnsupportedError'\n }\n}\n\nfunction isMultiOptions(o: MoneyOptions): o is MoneyOptionsMulti {\n return 'currencies' in o\n}\n\n/** Create a {@link MoneyDescriptor}. */\nexport function money(options: MoneyOptions): MoneyDescriptor {\n // The declaration is the Via binding's opt-in unit (#553): constructing\n // a descriptor statically links normalize/paths/where/money-reducer into\n // the kernel's Via port, so every later kernel consultation (including\n // the SYNC query DSL) finds the binding already installed.\n linkMoneyVia()\n const hasFixed = 'currency' in options\n const hasMulti = 'currencies' in options\n if (hasFixed && hasMulti) {\n throw new TypeError('money: `currency` and `currencies` are mutually exclusive')\n }\n if (!hasFixed && !hasMulti) {\n throw new TypeError('money: one of `currency` or `currencies` is required')\n }\n\n const rounding = options.rounding\n\n if (isMultiOptions(options)) {\n const overrides = options.scaleOverrides ?? {}\n const allowList = options.currencies\n const allows = (c: string): boolean =>\n allowList === 'any' ? true : allowList.includes(c)\n const scaleFor = (c: string): number => {\n if (!allows(c)) throw new MoneyCurrencyError(c, 'not-allowed')\n const s = overrides[c] ?? scaleForCurrency(c)\n if (s === null || s === undefined) throw new MoneyCurrencyError(c, 'unknown-scale')\n return s\n }\n // Eagerly validate the allow-list resolves (catch typos at construction).\n if (allowList !== 'any') for (const c of allowList) scaleFor(c)\n const soleCurrency = (): string | undefined =>\n allowList !== 'any' && allowList.length === 1 ? allowList[0] : undefined\n return {\n _noydbMoney: true,\n _viaBrand: 'money',\n mode: 'multi',\n options,\n rounding,\n fixedCurrency: undefined,\n scaleFor,\n allows,\n soleCurrency,\n }\n }\n\n // fixed\n const currency = options.currency\n const resolvedScale = options.scale ?? scaleForCurrency(currency)\n if (resolvedScale === null || resolvedScale === undefined) {\n throw new MoneyCurrencyError(currency, 'unknown-scale')\n }\n return {\n _noydbMoney: true,\n _viaBrand: 'money',\n mode: 'fixed',\n options,\n rounding,\n fixedCurrency: currency,\n scaleFor(c: string): number {\n if (c !== currency) throw new MoneyCurrencyError(c, 'not-allowed')\n return resolvedScale\n },\n allows: (c: string): boolean => c === currency,\n soleCurrency: (): string | undefined => currency,\n }\n}\n\n/** Runtime predicate for detecting a {@link MoneyDescriptor}. */\nexport function isMoneyDescriptor(x: unknown): x is MoneyDescriptor {\n return (\n typeof x === 'object' &&\n x !== null &&\n (x as { _noydbMoney?: unknown })._noydbMoney === true\n )\n}\n","/**\n * Exact money arithmetic helpers — `mulRate` and `allocate`.\n *\n * Both operate on the canonical decoded string form that `get()`\n * returns (`'10000.00'`), entirely in scaled-`BigInt` space — no\n * floating-point step anywhere, exact past 2^53. They are pure\n * functions with no vault or descriptor dependency: the working scale\n * is inferred from the amount's fractional digits (a canonical money\n * string always carries exactly the field's scale) or pinned with\n * `opts.scale`.\n *\n * Why these two: app-side invariants of the form\n * `Σ parts === whole` (receipt totals, net-zero WHT pairs, proration)\n * carry ±0.01 tolerances ONLY because the math is major-unit floats +\n * round2. `mulRate` (VAT-style rate application with explicit\n * rounding) and `allocate` (largest-remainder split — parts sum to the\n * input EXACTLY, by construction) make those tolerances zero.\n */\n\nimport {\n parseToScaledInt,\n formatScaledInt,\n rescaleScaledInt,\n decimalScaleOf,\n type RoundingMode,\n} from './fixed-point.js'\nimport { MoneyUnsupportedError } from './descriptor.js'\n\nexport interface MulRateOptions {\n /**\n * Output scale (fraction digits). Defaults to the amount's own\n * fractional digits — for a canonical money string that IS the\n * field's scale.\n */\n readonly scale?: number\n /** Rounding for the final re-scale. Default `'half-up'`. */\n readonly rounding?: RoundingMode\n}\n\nexport interface AllocateOptions {\n /** Working scale. Defaults to the amount's own fractional digits. */\n readonly scale?: number\n}\n\n/** Parse `amount` at `scale` or throw the standard money TypeError. */\nfunction parseAmount(label: string, amount: number | string, scale: number, rounding?: RoundingMode): bigint {\n const r = parseToScaledInt(amount, scale, rounding)\n if (!r.ok) {\n throw new MoneyUnsupportedError(\n r.reason === 'precision'\n ? `${label}: amount ${JSON.stringify(amount)} has more precision than scale ${scale} and no rounding mode is configured`\n : `${label}: amount ${JSON.stringify(amount)} is not a finite decimal`,\n )\n }\n return r.value\n}\n\nfunction resolveScale(label: string, amount: number | string, explicit: number | undefined): number {\n if (explicit !== undefined) {\n if (!Number.isInteger(explicit) || explicit < 0) {\n throw new MoneyUnsupportedError(`${label}: scale must be a non-negative integer`)\n }\n return explicit\n }\n const inferred = decimalScaleOf(amount)\n if (inferred === null) {\n throw new MoneyUnsupportedError(`${label}: amount ${JSON.stringify(amount)} is not a finite decimal`)\n }\n return inferred\n}\n\n/**\n * Multiply a money amount by a decimal rate, exactly.\n *\n * The rate is parsed at its OWN full precision (`0.07` → `7` at scale\n * 2), the product computed in `BigInt` at `amountScale + rateScale`,\n * then re-scaled back to the output scale with the requested rounding —\n * one rounding step, at the very end.\n *\n * ```ts\n * mulRate('10000.00', 0.07) // '700.00' (VAT)\n * mulRate('33.33', '0.07') // '2.33' (half-up)\n * mulRate('33.33', 0.07, { rounding: 'floor' }) // '2.33'\n * mulRate(100, 0.07, { scale: 2 }) // '7.00'\n * ```\n */\nexport function mulRate(\n amount: number | string,\n rate: number | string,\n opts: MulRateOptions = {},\n): string {\n const scale = resolveScale('mulRate', amount, opts.scale)\n const rounding = opts.rounding ?? 'half-up'\n const a = parseAmount('mulRate', amount, scale, rounding)\n\n const rateScale = decimalScaleOf(rate)\n if (rateScale === null) {\n throw new MoneyUnsupportedError(`mulRate: rate ${JSON.stringify(rate)} is not a finite decimal`)\n }\n const r = parseToScaledInt(rate, rateScale)\n if (!r.ok) {\n throw new MoneyUnsupportedError(`mulRate: rate ${JSON.stringify(rate)} is not a finite decimal`)\n }\n\n const product = a * r.value // scaled at scale + rateScale\n return formatScaledInt(rescaleScaledInt(product, scale + rateScale, scale, rounding), scale)\n}\n\n/**\n * Split a money amount across weighted buckets with ZERO drift: the\n * returned parts sum to the input exactly, by construction\n * (largest-remainder method).\n *\n * Each bucket gets `floor(amount × weightᵢ / Σweights)`; the leftover\n * minor units (always fewer than the bucket count) go one each to the\n * buckets with the largest truncated remainders — ties broken by\n * position, earlier bucket first. Weights are parsed as exact decimals\n * (no float division anywhere); they must be non-negative with a\n * positive sum.\n *\n * ```ts\n * allocate('100.00', [1, 1, 1]) // ['33.34', '33.33', '33.33']\n * allocate('0.05', [3, 7]) // ['0.02', '0.03']\n * allocate('-100.00', [1, 1, 1]) // ['-33.34', '-33.33', '-33.33']\n * ```\n */\nexport function allocate(\n amount: number | string,\n weights: ReadonlyArray<number | string>,\n opts: AllocateOptions = {},\n): string[] {\n if (weights.length === 0) {\n throw new MoneyUnsupportedError('allocate: weights must not be empty')\n }\n const scale = resolveScale('allocate', amount, opts.scale)\n const a = parseAmount('allocate', amount, scale)\n\n // Parse every weight as an exact decimal at a common scale, so the\n // proportion arithmetic below is pure BigInt.\n let weightScale = 0\n for (const w of weights) {\n const s = decimalScaleOf(w)\n if (s === null) {\n throw new MoneyUnsupportedError(`allocate: weight ${JSON.stringify(w)} is not a finite decimal`)\n }\n if (s > weightScale) weightScale = s\n }\n const scaledWeights = weights.map(w => {\n const r = parseToScaledInt(w, weightScale)\n if (!r.ok || r.value < 0n) {\n throw new MoneyUnsupportedError(`allocate: weight ${JSON.stringify(w)} must be a non-negative decimal`)\n }\n return r.value\n })\n const sumW = scaledWeights.reduce((acc, w) => acc + w, 0n)\n if (sumW === 0n) {\n throw new MoneyUnsupportedError('allocate: weights must not all be zero')\n }\n\n // Largest-remainder over the MAGNITUDE; a negative amount negates the\n // parts at the end, so Σparts === amount holds for both signs.\n const negative = a < 0n\n const mag = negative ? -a : a\n\n const base: bigint[] = []\n const remainders: Array<{ index: number; rem: bigint }> = []\n let distributed = 0n\n for (let i = 0; i < scaledWeights.length; i++) {\n const product = mag * scaledWeights[i]!\n const share = product / sumW\n base.push(share)\n distributed += share\n remainders.push({ index: i, rem: product % sumW })\n }\n\n // Leftover minor units: strictly fewer than the bucket count.\n let leftover = mag - distributed\n remainders.sort((x, y) => (y.rem > x.rem ? 1 : y.rem < x.rem ? -1 : x.index - y.index))\n for (const { index } of remainders) {\n if (leftover === 0n) break\n base[index] = base[index]! + 1n\n leftover -= 1n\n }\n\n return base.map(p => formatScaledInt(negative && p !== 0n ? -p : p, scale))\n}\n","/**\n * Branded money output type.\n *\n * The decoded read shape of a money field is an exact decimal STRING\n * (`'10000.00'`) — but a hand-written schema types it `string | number`,\n * which is honest about the input side and unhelpful on the output\n * side: every read site hand-coerces, and a missed coercion passes\n * typecheck silently (then surfaces as a runtime template warning, or\n * worse, as `'10000.00' * 100` arithmetic).\n *\n * {@link MoneyString} is the output-side brand: a `string` that has\n * been through noy-db's decode (or {@link asMoney}'s guard). Branding\n * is type-level only — zero runtime cost on the read path.\n *\n * ## Wiring the brand through a validator (the input/output asymmetry)\n *\n * Keep the permissive `string | number` on the INPUT side so write\n * sites are untouched, and brand the OUTPUT side. With Zod:\n *\n * ```ts\n * import type { MoneyString } from '@noy-db/hub'\n *\n * const moneyValue = z.union([z.number(), z.string()]) as unknown as\n * z.ZodType<MoneyString, z.ZodTypeDef, string | number>\n *\n * const Invoice = z.object({ id: z.string(), total: moneyValue })\n * type InvoiceOut = z.output<typeof Invoice> // total: MoneyString\n * type InvoiceIn = z.input<typeof Invoice> // total: string | number\n * ```\n *\n * The cast is sound for fields declared in `moneyFields`: reads pass\n * through `decodeMoneyFields`, which always produces the canonical\n * decimal string.\n */\n\nimport { decimalScaleOf } from './fixed-point.js'\nimport { MoneyUnsupportedError } from './descriptor.js'\n\ndeclare const MONEY_BRAND: unique symbol\n\n/**\n * An exact decimal string produced by noy-db's money decode\n * (`'10000.00'`). The brand exists only at the type level — at runtime\n * a `MoneyString` is a plain string.\n */\nexport type MoneyString = string & { readonly [MONEY_BRAND]: true }\n\n/**\n * Runtime-guarded cast to {@link MoneyString}. Accepts a decimal string\n * or a number, returns the canonical decimal string branded — throws\n * `MoneyUnsupportedError` on anything non-finite / non-decimal. Use at\n * trust boundaries (deserialized JSON, route params); values read\n * through `get()`/`list()` are already canonical.\n */\nexport function asMoney(value: string | number): MoneyString {\n if (!isMoneyLike(value)) {\n throw new MoneyUnsupportedError(`asMoney: ${JSON.stringify(value)} is not a finite decimal`)\n }\n return String(value).trim() as MoneyString\n}\n\n/** Type guard: is `value` a decimal string acceptable as money? */\nexport function isMoneyString(value: unknown): value is MoneyString {\n return typeof value === 'string' && isMoneyLike(value)\n}\n\n/**\n * The ONE sanctioned escape hatch to a JS `number` — explicit because\n * the conversion is lossy past 2^53. For display math and chart axes;\n * never feed the result back into stored amounts (use `mulRate` /\n * `allocate` for exact arithmetic).\n */\nexport function moneyNumber(value: MoneyString | string | number): number {\n if (!isMoneyLike(value)) {\n throw new MoneyUnsupportedError(`moneyNumber: ${JSON.stringify(value)} is not a finite decimal`)\n }\n return Number(value)\n}\n\nfunction isMoneyLike(value: unknown): boolean {\n if (typeof value === 'number') return Number.isFinite(value)\n if (typeof value !== 'string') return false\n return decimalScaleOf(value) !== null\n}\n"],"mappings":"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","names":["keep","magnitude","obj","clone","currency","isMoneyValueObject","e","value"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SatelliteConfigError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QZWTRENR.js";
|
|
4
4
|
|
|
5
5
|
// src/with-shape/satellites/validate.ts
|
|
6
6
|
function validateSatelliteDeclaration(input) {
|
|
@@ -47,4 +47,4 @@ export {
|
|
|
47
47
|
validateSatelliteDeclaration,
|
|
48
48
|
hashFields
|
|
49
49
|
};
|
|
50
|
-
//# sourceMappingURL=chunk-
|
|
50
|
+
//# sourceMappingURL=chunk-SHEEBRZ4.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/with-fork/shadow/strategy.ts
|
|
2
|
+
var NOT_ENABLED = new Error(
|
|
3
|
+
'VaultFrame requires the shadow strategy. Import `{ withShadow }` from "@noy-db/hub/shadow" and pass it to `createNoydb({ shadowStrategy: withShadow() })`.'
|
|
4
|
+
);
|
|
5
|
+
var NO_SHADOW = {
|
|
6
|
+
buildFrame() {
|
|
7
|
+
throw NOT_ENABLED;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
NO_SHADOW
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=chunk-SMY5X46Z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/with-fork/shadow/strategy.ts"],"sourcesContent":["/**\n * Strategy seam for the optional VaultFrame snapshot primitive.\n * Core imports `ShadowStrategy` as TYPE-ONLY and `NO_SHADOW` as a\n * 4-line stub. `VaultFrame` is only constructed inside `withShadow()`\n * — consumers who never import `@noy-db/hub/shadow` ship none of\n * the ~129 LOC.\n *\n * @internal\n */\n\nimport type { VaultFrame } from './vault-frame.js'\n\n/**\n * @internal\n */\nexport interface ShadowStrategy {\n /**\n * Build a `VaultFrame` bound to the given vault. The factory type\n * is kept loose (`unknown`) to avoid a core → shadow type\n * dependency — the consumer always calls this through\n * `vault.frame()`, which returns `VaultFrame` at its surface.\n */\n buildFrame(vault: unknown): VaultFrame\n}\n\nconst NOT_ENABLED = new Error(\n 'VaultFrame requires the shadow strategy. Import `{ withShadow }` ' +\n 'from \"@noy-db/hub/shadow\" and pass it to ' +\n '`createNoydb({ shadowStrategy: withShadow() })`.',\n)\n\n/**\n * No-shadow stub.\n *\n * @internal\n */\nexport const NO_SHADOW: ShadowStrategy = {\n buildFrame() { throw NOT_ENABLED },\n}\n"],"mappings":";AAyBA,IAAM,cAAc,IAAI;AAAA,EACtB;AAGF;AAOO,IAAM,YAA4B;AAAA,EACvC,aAAa;AAAE,UAAM;AAAA,EAAY;AACnC;","names":[]}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CargoNotEnabledError,
|
|
2
3
|
QuiesceTimeoutError
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QZWTRENR.js";
|
|
5
|
+
|
|
6
|
+
// src/with-cargo/strategy.ts
|
|
7
|
+
var NO_CARGO = {
|
|
8
|
+
async extractPartition() {
|
|
9
|
+
throw new CargoNotEnabledError();
|
|
10
|
+
}
|
|
11
|
+
};
|
|
4
12
|
|
|
5
13
|
// src/port/by/types.ts
|
|
6
14
|
function isQuorum(writers, generation, excludeWriterId) {
|
|
@@ -48,7 +56,8 @@ async function runDrainBarrier(provider, o, run) {
|
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
export {
|
|
59
|
+
NO_CARGO,
|
|
51
60
|
isQuorum,
|
|
52
61
|
runDrainBarrier
|
|
53
62
|
};
|
|
54
|
-
//# sourceMappingURL=chunk-
|
|
63
|
+
//# sourceMappingURL=chunk-TG634KCO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/with-cargo/strategy.ts","../src/port/by/types.ts"],"sourcesContent":["/**\n * Cargo capability strategy (FR-6/FR-7) — the source-side, owner-level\n * partition operation that requires a live {@link Vault}: extracting a re-keyed\n * transfer-sealed partition ({@link extractPartitionCore}). The active engine\n * ({@link withCargo}) dynamically imports that engine (keeping the extraction\n * crypto out of the floor bundle); {@link NO_CARGO} throws.\n *\n * The public free function `extractPartition` (which takes a `Vault`) delegates\n * here via `vault.cargoStrategy`, so an un-opted-in caller hits `NO_CARGO`'s\n * throw.\n *\n * Carve-out (mirrors `openSealedRecord` / `liberateVault`): the recipient-side\n * free functions `adoptPartition` and `decryptExtractedPartition` operate on\n * raw bundle bytes + a destination store — they carry NO source instance to\n * gate against, so they stay ungated host-side tooling. `diffVault` is likewise\n * ungated: it's shared import/merge infrastructure the `as-*` exporters call\n * internally, not a gated cargo capability.\n * @internal\n */\nimport type { Vault } from '../kernel/vault.js'\nimport type { ExtractPartitionResult, ExtractPartitionOptions } from './extract-partition.js'\nimport { CargoNotEnabledError } from '../kernel/errors.js'\n\nexport interface CargoStrategy {\n extractPartition(vault: Vault, opts: ExtractPartitionOptions): Promise<ExtractPartitionResult>\n}\n\n/**\n * No-op stub — the floor default. The source-side cargo op throws\n * {@link CargoNotEnabledError}; opt in with `cargoStrategy: withCargo()` in\n * createNoydb. @internal\n */\nexport const NO_CARGO: CargoStrategy = {\n async extractPartition() { throw new CargoNotEnabledError() },\n}\n","/**\n * Kernel coordination port — the injected `CoordinationProvider` seam for the\n * schema-fence drain-barrier.\n *\n * The kernel defines this port; `@noy-db/by-tabs` / `@noy-db/by-peer` implement\n * it for real-time quorum, and an external orchestrator (`@klum-db/lobby`)\n * drives it through the `Noydb` handle without ever naming a `by-*` package.\n * The dependency arrow is `by-* → kernel ← klum`, the app at the apex.\n *\n * This module carries only the port TYPES plus two pure-ish helpers:\n * {@link isQuorum} (a pure quorum predicate extracted from the legacy\n * `activeQuiesced`) and {@link runDrainBarrier} (the reusable barrier protocol\n * the migration cutover and klum both call).\n *\n * @module\n */\n\nimport { QuiesceTimeoutError } from '../../kernel/errors.js'\nimport type { Unsubscribe } from '../with/write-hooks.js'\n\n/** Vault fence state (the existing FenceDoc shape). */\nexport interface FenceState {\n readonly currentSchemaVersion: number\n readonly fenceState: 'normal' | 'draining' | 'migrating' | 'complete'\n}\n\n/** A writer's presence + ack, tagged with the session that owns it. */\nexport interface WriterPresence {\n /** = today's clientId (one per tab/peer). */\n readonly writerId: string\n /** Groups one user's writers across vaults (consolidation is klum's job). */\n readonly sessionId: string\n readonly lastSeen: number\n readonly quiescedAtVersion: number | null\n}\n\n/** Session-addressable drain-barrier coordination transport. Per-vault ops. */\nexport interface CoordinationProvider {\n /** orchestrator → all writers */\n setFence(vault: string, fence: FenceState): Promise<void>\n /**\n * Fresh one-shot fence read for the write-path gate (`assertWritable`).\n * A direct read (not a cached `observeFence` snapshot) avoids a staleness\n * window and keeps the timing-sensitive cutover gate exact. The store\n * default reads `_meta/schema-fence`; `by-*` return their last-pushed fence.\n */\n readFence(vault: string): Promise<FenceState>\n /** writer observes fence changes (default: poll-emit; by-*: push) */\n observeFence(vault: string, onChange: (f: FenceState) => void): Unsubscribe\n /** writer → orchestrator: presence + ack (heartbeat + quiescedAtVersion) */\n reportPresence(vault: string, p: WriterPresence): Promise<void>\n /** orchestrator observes presence changes (default: poll-emit; by-*: push) */\n observePresence(vault: string, onChange: (writers: readonly WriterPresence[]) => void): Unsubscribe\n /** orchestrator one-shot snapshot of reachable writers (quorum input) */\n reachableWriters(vault: string, o: { staleMs: number; now: number }): Promise<readonly WriterPresence[]>\n}\n\n/**\n * Pure quorum predicate: true when every writer (other than `excludeWriterId`)\n * has acked at exactly `generation`. An empty set is trivially a quorum.\n *\n * Extracted from the legacy `activeQuiesced` store-polling check so the\n * migration cutover, the store default provider, and `by-*` real-time\n * providers all share one definition of \"everyone has drained\".\n */\nexport function isQuorum(\n writers: readonly WriterPresence[],\n generation: number,\n excludeWriterId?: string,\n): boolean {\n return writers.filter((w) => w.writerId !== excludeWriterId).every((w) => w.quiescedAtVersion === generation)\n}\n\n/** Inputs for {@link runDrainBarrier}. */\nexport interface DrainBarrierOptions {\n readonly vault: string\n readonly generation: number\n readonly writerId: string\n readonly onFlush: () => Promise<void>\n readonly staleMs: number\n readonly quiesceTimeoutMs: number\n readonly now: () => number\n /** Optional seam (mainly for deterministic tests) run before each poll tick. */\n readonly onPoll?: () => Promise<void>\n}\n\n/**\n * The reusable drain-barrier protocol shared by the migration cutover and klum:\n *\n * drain self → setFence(draining) → await quorum (presence push + isQuorum,\n * polling as a fallback, or timeout) → run() → release-by-caller.\n *\n * Resolves once every reachable writer (excluding `writerId`) has quiesced at\n * `generation`, at which point `run` is invoked exactly once. Rejects with\n * {@link QuiesceTimeoutError} if `quiesceTimeoutMs` elapses first.\n */\nexport async function runDrainBarrier(\n provider: CoordinationProvider,\n o: DrainBarrierOptions,\n run: () => Promise<void>,\n): Promise<void> {\n await provider.setFence(o.vault, { currentSchemaVersion: o.generation, fenceState: 'draining' })\n await o.onFlush()\n\n const deadline = o.now() + o.quiesceTimeoutMs\n const seeded = await provider.reachableWriters(o.vault, { staleMs: o.staleMs, now: o.now() })\n if (!isQuorum(seeded, o.generation, o.writerId)) {\n await new Promise<void>((resolve, reject) => {\n let settled = false\n const finish = (fn: () => void) => {\n if (!settled) {\n settled = true\n unsub()\n fn()\n }\n }\n const unsub = provider.observePresence(o.vault, (writers) => {\n if (isQuorum(writers, o.generation, o.writerId)) finish(resolve)\n })\n const tick = async () => {\n if (settled) return\n if (o.now() >= deadline) {\n finish(() =>\n reject(\n new QuiesceTimeoutError(\n `Cutover of vault \"${o.vault}\" to generation ${o.generation} timed out ` +\n `after ${o.quiesceTimeoutMs}ms waiting for active writers to quiesce.`,\n ),\n ),\n )\n return\n }\n if (o.onPoll) await o.onPoll()\n const w = await provider.reachableWriters(o.vault, { staleMs: o.staleMs, now: o.now() })\n if (isQuorum(w, o.generation, o.writerId)) finish(resolve)\n else setTimeout(() => void tick(), 25)\n }\n void tick()\n })\n }\n await run()\n}\n"],"mappings":";;;;;;AAgCO,IAAM,WAA0B;AAAA,EACrC,MAAM,mBAAmB;AAAE,UAAM,IAAI,qBAAqB;AAAA,EAAE;AAC9D;;;AC+BO,SAAS,SACd,SACA,YACA,iBACS;AACT,SAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,aAAa,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,UAAU;AAC9G;AAyBA,eAAsB,gBACpB,UACA,GACA,KACe;AACf,QAAM,SAAS,SAAS,EAAE,OAAO,EAAE,sBAAsB,EAAE,YAAY,YAAY,WAAW,CAAC;AAC/F,QAAM,EAAE,QAAQ;AAEhB,QAAM,WAAW,EAAE,IAAI,IAAI,EAAE;AAC7B,QAAM,SAAS,MAAM,SAAS,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,IAAI,EAAE,CAAC;AAC5F,MAAI,CAAC,SAAS,QAAQ,EAAE,YAAY,EAAE,QAAQ,GAAG;AAC/C,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,UAAI,UAAU;AACd,YAAM,SAAS,CAAC,OAAmB;AACjC,YAAI,CAAC,SAAS;AACZ,oBAAU;AACV,gBAAM;AACN,aAAG;AAAA,QACL;AAAA,MACF;AACA,YAAM,QAAQ,SAAS,gBAAgB,EAAE,OAAO,CAAC,YAAY;AAC3D,YAAI,SAAS,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAG,QAAO,OAAO;AAAA,MACjE,CAAC;AACD,YAAM,OAAO,YAAY;AACvB,YAAI,QAAS;AACb,YAAI,EAAE,IAAI,KAAK,UAAU;AACvB;AAAA,YAAO,MACL;AAAA,cACE,IAAI;AAAA,gBACF,qBAAqB,EAAE,KAAK,mBAAmB,EAAE,UAAU,oBAChD,EAAE,gBAAgB;AAAA,cAC/B;AAAA,YACF;AAAA,UACF;AACA;AAAA,QACF;AACA,YAAI,EAAE,OAAQ,OAAM,EAAE,OAAO;AAC7B,cAAM,IAAI,MAAM,SAAS,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,IAAI,EAAE,CAAC;AACvF,YAAI,SAAS,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAG,QAAO,OAAO;AAAA,YACpD,YAAW,MAAM,KAAK,KAAK,GAAG,EAAE;AAAA,MACvC;AACA,WAAK,KAAK;AAAA,IACZ,CAAC;AAAA,EACH;AACA,QAAM,IAAI;AACZ;","names":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NOYDB_FORMAT_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QBAC3GXA.js";
|
|
4
4
|
import {
|
|
5
5
|
ValidationError
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QZWTRENR.js";
|
|
7
7
|
|
|
8
8
|
// src/with-party/directory/cover/custom.ts
|
|
9
9
|
var CUSTOM_KEY_PATTERN = /^[a-z0-9]+([.-][a-z0-9]+)+$/i;
|
|
@@ -172,8 +172,6 @@ function isCover(x) {
|
|
|
172
172
|
const obj = x;
|
|
173
173
|
return obj["_noydb_public"] === 1 && typeof obj["version"] === "number";
|
|
174
174
|
}
|
|
175
|
-
var validatePublicEnvelopeInput = validateCoverInput;
|
|
176
|
-
var isPublicEnvelope = isCover;
|
|
177
175
|
|
|
178
176
|
// src/with-party/directory/cover/storage.ts
|
|
179
177
|
var COVER_RECORD_ID = "public-envelope";
|
|
@@ -222,27 +220,17 @@ function pickLocale(value, locale, defaultLocale) {
|
|
|
222
220
|
}
|
|
223
221
|
return "";
|
|
224
222
|
}
|
|
225
|
-
var PUBLIC_ENVELOPE_RECORD_ID = COVER_RECORD_ID;
|
|
226
|
-
var loadPublicEnvelope = loadCover;
|
|
227
|
-
var savePublicEnvelope = saveCover;
|
|
228
|
-
var readPublicEnvelope = readCover;
|
|
229
223
|
|
|
230
224
|
export {
|
|
231
225
|
mergeCustom,
|
|
232
226
|
validateCoverSize,
|
|
233
227
|
validateCoverInput,
|
|
234
228
|
isCover,
|
|
235
|
-
validatePublicEnvelopeInput,
|
|
236
|
-
isPublicEnvelope,
|
|
237
229
|
COVER_RECORD_ID,
|
|
238
230
|
loadCover,
|
|
239
231
|
saveCover,
|
|
240
232
|
readCover,
|
|
241
233
|
resolveLocale,
|
|
242
|
-
pickLocale
|
|
243
|
-
PUBLIC_ENVELOPE_RECORD_ID,
|
|
244
|
-
loadPublicEnvelope,
|
|
245
|
-
savePublicEnvelope,
|
|
246
|
-
readPublicEnvelope
|
|
234
|
+
pickLocale
|
|
247
235
|
};
|
|
248
|
-
//# sourceMappingURL=chunk-
|
|
236
|
+
//# sourceMappingURL=chunk-TUXQSFHZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/with-party/directory/cover/custom.ts","../src/with-party/directory/cover/schema.ts","../src/with-party/directory/cover/storage.ts"],"sourcesContent":["/**\n * The cover's namespaced `custom` extension slot (#800) — input\n * validation, the namespace-level patch merge, and the post-merge\n * size caps.\n *\n * Like everything on the cover, `custom` is plaintext, public by\n * design, and unauthenticated — payloads are hints (display defaults,\n * routing suggestions, registry pointers), never an input to\n * security, authorization, or data-integrity decisions.\n *\n * @see https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/public-envelope.md\n *\n * @module\n */\nimport { ValidationError } from '../../../kernel/errors.js'\nimport type { Cover, JsonValue, ResolvedCoverSchema } from './types.js'\n\n/**\n * Namespace keys must be reverse-DNS or package-style identifiers —\n * at least one dot/dash-separated segment (`noydb.viewer`,\n * `com.acme.registry` pass; a bare `config` fails), so two frameworks\n * can't collide on a bare word.\n */\nconst CUSTOM_KEY_PATTERN = /^[a-z0-9]+([.-][a-z0-9]+)+$/i\n\n/** Maximum nesting depth of a namespace payload (containers, not leaves). */\nconst MAX_CUSTOM_DEPTH = 8\n\n/**\n * Validate the owner-supplied `custom` input: the field must be a\n * plain object, every key must match {@link CUSTOM_KEY_PATTERN}, and\n * every value must be JSON-serializable (no functions, `undefined`,\n * symbols, bigints, or cycles) within the depth cap. `null` is\n * accepted — it is the delete-this-namespace directive and never\n * persists. Throws `ValidationError` on the first violation.\n */\nexport function validateCustomInput(custom: Record<string, JsonValue>): void {\n if (custom === null || typeof custom !== 'object' || Array.isArray(custom)) {\n throw new ValidationError(\n `setCover: custom must be a { [namespace]: value } object, got ${\n Array.isArray(custom) ? 'array' : typeof custom\n }.`,\n )\n }\n for (const [ns, value] of Object.entries(custom)) {\n if (!CUSTOM_KEY_PATTERN.test(ns)) {\n throw new ValidationError(\n `setCover: custom namespace \"${ns}\" is invalid. Keys must be ` +\n 'reverse-DNS or package-style identifiers with at least one ' +\n 'dot/dash-separated segment (e.g. \"noydb.viewer\", \"com.acme.registry\").',\n )\n }\n assertJsonValue(value, ns, 1, new Set())\n }\n}\n\nfunction assertJsonValue(\n value: unknown,\n ns: string,\n depth: number,\n seen: Set<object>,\n): void {\n if (value === null) return\n const t = typeof value\n if (t === 'string' || t === 'number' || t === 'boolean') return\n if (t !== 'object') {\n throw new ValidationError(\n `setCover: custom[\"${ns}\"] contains a non-JSON value (${t}). ` +\n 'Only strings, numbers, booleans, null, arrays, and plain objects are allowed.',\n )\n }\n const container = value as object\n if (seen.has(container)) {\n throw new ValidationError(\n `setCover: custom[\"${ns}\"] contains a circular reference.`,\n )\n }\n if (depth > MAX_CUSTOM_DEPTH) {\n throw new ValidationError(\n `setCover: custom[\"${ns}\"] nests deeper than the ${MAX_CUSTOM_DEPTH}-level cap.`,\n )\n }\n seen.add(container)\n const children = Array.isArray(container) ? container : Object.values(container)\n for (const child of children) {\n assertJsonValue(child, ns, depth + 1, seen)\n }\n seen.delete(container)\n}\n\n/**\n * Namespace-level patch merge for `setCover`: provided namespaces\n * replace their previous value, absent namespaces are preserved, and\n * an explicit `null` deletes that namespace (so `null` never persists\n * as a namespace value). A whole-`custom`-absent patch preserves the\n * previous custom, consistent with the other cover fields. Rationale:\n * framework A must never need read-modify-write of framework B's data.\n *\n * Returns a spreadable fragment — `{ custom }` when the merge leaves\n * at least one namespace, `{}` when it leaves none (the field is\n * dropped from the persisted document rather than stored empty).\n */\nexport function mergeCustom(\n existing: Record<string, JsonValue> | undefined,\n patch: Record<string, JsonValue> | undefined,\n): { custom: Record<string, JsonValue> } | Record<string, never> {\n if (patch === undefined) {\n return existing !== undefined ? { custom: existing } : {}\n }\n const merged: Record<string, JsonValue> = { ...existing }\n for (const [ns, value] of Object.entries(patch)) {\n if (value === null) {\n delete merged[ns]\n } else {\n merged[ns] = value\n }\n }\n return Object.keys(merged).length > 0 ? { custom: merged } : {}\n}\n\n/**\n * Post-merge size caps — validates the WOULD-BE-PERSISTED document\n * (after the namespace merge), so a small patch can't tip the stored\n * cover over a cap unnoticed. `maxCoverBytes` bounds the entire\n * serialized document, which also closes the unbounded locale-map\n * key-count hole for `name` / `description`. Sizes are measured as\n * `JSON.stringify` length. Throws `ValidationError` on violation.\n */\nexport function validateCoverSize(\n cover: Cover,\n schema: ResolvedCoverSchema,\n): void {\n if (cover.custom !== undefined) {\n const customSize = JSON.stringify(cover.custom).length\n if (customSize > schema.maxCustomBytes) {\n throw new ValidationError(\n `setCover: custom exceeds the ${schema.maxCustomBytes}-byte cap ` +\n `(got ${customSize} bytes serialized, after merging with the stored namespaces).`,\n )\n }\n }\n const totalSize = JSON.stringify(cover).length\n if (totalSize > schema.maxCoverBytes) {\n throw new ValidationError(\n `setCover: the cover document exceeds the ${schema.maxCoverBytes}-byte cap ` +\n `(got ${totalSize} bytes serialized).`,\n )\n }\n}\n","/**\n * Validate-on-write for the cover. Runs at every `setCover` call;\n * the developer's schema decides which fields are allowed and the\n * size caps that apply.\n *\n * @module\n */\nimport { ValidationError } from '../../../kernel/errors.js'\nimport { validateCustomInput } from './custom.js'\nimport type {\n Cover,\n CoverText,\n JsonValue,\n ResolvedCoverSchema,\n CoverField,\n} from './types.js'\n\n/** Owner-supplied input — the subset of {@link Cover} the owner can set. */\nexport interface SetCoverInput {\n readonly name?: CoverText\n readonly description?: CoverText\n readonly icon?: string\n readonly defaultLocale?: string\n /**\n * Namespace-level patch for the cover's `custom` slot (#800):\n * provided namespaces replace their previous value, absent\n * namespaces are preserved, an explicit `null` deletes that\n * namespace. Requires `'custom'` in the schema's `fields` list —\n * the `cover: true` shorthand does NOT enable it.\n */\n readonly custom?: Record<string, JsonValue>\n}\n\nconst DATA_URL_PREFIX = /^data:([a-zA-Z0-9.+-]+\\/[a-zA-Z0-9.+-]+);base64,/\n\n/**\n * Validate an owner-supplied cover input against the developer's\n * resolved schema. Throws `ValidationError` on the first violation;\n * returns void on success.\n *\n * The validator is deliberately strict: every fail mode is a hard\n * error rather than a silent drop, so the owner finds out immediately\n * which field they oversized rather than discovering a truncated\n * label months later.\n */\nexport function validateCoverInput(\n input: SetCoverInput,\n schema: ResolvedCoverSchema,\n): void {\n const allowed = new Set<CoverField>(schema.fields)\n\n // Reject any key not in the schema's allowed-field list.\n for (const key of Object.keys(input)) {\n const known: CoverField | undefined =\n key === 'name' || key === 'description' || key === 'icon' || key === 'defaultLocale' || key === 'custom'\n ? key\n : undefined\n if (!known) {\n throw new ValidationError(\n `setCover: unknown field \"${key}\". ` +\n `Allowed fields: ${[...allowed].join(', ')}.`,\n )\n }\n if (!allowed.has(known)) {\n throw new ValidationError(\n `setCover: field \"${known}\" is not enabled in this vault's schema. ` +\n `Allowed fields: ${[...allowed].join(', ')}.`,\n )\n }\n }\n\n if (input.name !== undefined) {\n validateText(input.name, 'name', schema.maxStringChars)\n }\n if (input.description !== undefined) {\n validateText(input.description, 'description', schema.maxStringChars)\n }\n if (input.icon !== undefined) {\n validateIcon(input.icon, schema)\n }\n if (input.defaultLocale !== undefined && typeof input.defaultLocale !== 'string') {\n throw new ValidationError(\n `setCover: defaultLocale must be a string (BCP-47), got ${typeof input.defaultLocale}.`,\n )\n }\n if (input.custom !== undefined) {\n validateCustomInput(input.custom)\n }\n}\n\nfunction validateText(\n value: CoverText,\n field: string,\n maxChars: number,\n): void {\n if (typeof value === 'string') {\n if (value.length > maxChars) {\n throw new ValidationError(\n `setCover: ${field} exceeds the ${maxChars}-character cap (got ${value.length}).`,\n )\n }\n return\n }\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new ValidationError(\n `setCover: ${field} must be a string or { [locale]: string } map, got ${typeof value}.`,\n )\n }\n // Locale map. Each value must be a non-empty string within the cap.\n for (const [locale, str] of Object.entries(value)) {\n if (typeof str !== 'string') {\n throw new ValidationError(\n `setCover: ${field}[${locale}] must be a string, got ${typeof str}.`,\n )\n }\n if (str.length > maxChars) {\n throw new ValidationError(\n `setCover: ${field}[${locale}] exceeds the ${maxChars}-character cap (got ${str.length}).`,\n )\n }\n }\n}\n\nfunction validateIcon(icon: string, schema: ResolvedCoverSchema): void {\n if (typeof icon !== 'string') {\n throw new ValidationError(\n `setCover: icon must be a data: URL string, got ${typeof icon}.`,\n )\n }\n if (icon.length > schema.maxIconBytes) {\n throw new ValidationError(\n `setCover: icon exceeds the ${schema.maxIconBytes}-byte cap (got ${icon.length}).`,\n )\n }\n const m = DATA_URL_PREFIX.exec(icon)\n if (!m) {\n throw new ValidationError(\n 'setCover: icon must be a base64 data URL ' +\n '(`data:image/png;base64,…` or `data:image/svg+xml;base64,…`). ' +\n 'External URLs are not supported in v1.',\n )\n }\n const mime = m[1]!\n if (!schema.iconMimeTypes.includes(mime)) {\n throw new ValidationError(\n `setCover: icon MIME type \"${mime}\" is not allowed. ` +\n `Permitted types: ${schema.iconMimeTypes.join(', ')}.`,\n )\n }\n}\n\n/**\n * Lightweight runtime predicate — used by the bundle header\n * validator to recognise a cover without requiring it. (The wire\n * discriminator keeps its frozen name: `_noydb_public: 1`.)\n */\nexport function isCover(x: unknown): x is Cover {\n if (x === null || typeof x !== 'object' || Array.isArray(x)) return false\n const obj = x as Record<string, unknown>\n return obj['_noydb_public'] === 1 && typeof obj['version'] === 'number'\n}\n\n// ─── Deprecated aliases (#799 public-envelope → cover; remove after one pre-release window) ───\n\n/** @deprecated Use {@link SetCoverInput}. */\nexport type SetPublicEnvelopeInput = SetCoverInput\n/** @deprecated Use {@link validateCoverInput}. */\nexport const validatePublicEnvelopeInput = validateCoverInput\n/** @deprecated Use {@link isCover}. */\nexport const isPublicEnvelope = isCover\n","/**\n * Persistence helpers for `_meta/public-envelope` — the cover's\n * frozen wire location. Mirrors the bypass-AES pattern used by\n * `_meta/handle` and `_meta/policy` — the document is plaintext\n * JSON, the envelope's `_iv` field is left empty.\n *\n * @module\n */\nimport type { NoydbStore, EncryptedEnvelope } from '../../../kernel/types.js'\nimport { NOYDB_FORMAT_VERSION } from '../../../kernel/types.js'\nimport type { Cover } from './types.js'\nimport { isCover } from './schema.js'\n\n/**\n * Reserved id for the vault-level cover record. The VALUE is frozen\n * wire format — the record predates the #799 rename and stays at\n * `_meta/public-envelope` so existing vaults need no migration.\n */\nexport const COVER_RECORD_ID = 'public-envelope'\n\n/**\n * Read the cover from `_meta/public-envelope`. Returns `undefined`\n * when no cover has been persisted (fresh vault, or a vault written\n * before the feature was enabled). Tolerates corrupted documents —\n * a JSON parse failure surfaces as `undefined`, not a thrown error,\n * mirroring `_meta/handle`'s contract.\n */\nexport async function loadCover(\n store: NoydbStore,\n vault: string,\n): Promise<Cover | undefined> {\n const envelope = await store.get(vault, '_meta', COVER_RECORD_ID)\n if (!envelope) return undefined\n try {\n const parsed = JSON.parse(envelope._data) as unknown\n if (!isCover(parsed)) return undefined\n return parsed\n } catch {\n return undefined\n }\n}\n\n/** Persist the cover. Idempotent — overwrites any prior write. */\nexport async function saveCover(\n store: NoydbStore,\n vault: string,\n cover: Cover,\n): Promise<void> {\n const wireEnvelope: EncryptedEnvelope = {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: 1,\n _ts: new Date().toISOString(),\n _iv: '',\n _data: JSON.stringify(cover),\n }\n await store.put(vault, '_meta', COVER_RECORD_ID, wireEnvelope)\n}\n\n/**\n * Public, no-key reader. Plain function, not a method on `Noydb` —\n * the whole point is it works without an authenticated session, so\n * a UI can show \"Acme 2026 Tax Records\" before unlocking.\n *\n * Resolves any `name` / `description` locale map through the supplied\n * `locale` (when provided). Omitting `locale` returns the raw\n * cover, which a multilingual picker can render as it pleases.\n */\nexport async function readCover(\n store: NoydbStore,\n vault: string,\n opts: { readonly locale?: string } = {},\n): Promise<Cover | undefined> {\n const raw = await loadCover(store, vault)\n if (!raw) return undefined\n if (opts.locale === undefined) return raw\n return resolveLocale(raw, opts.locale)\n}\n\n/**\n * Resolve the locale-map fields (`name`, `description`) of a cover\n * to plain strings for the requested locale, falling back through\n * `defaultLocale` and then any available translation.\n *\n * @internal\n */\nexport function resolveLocale(\n cover: Cover,\n locale: string,\n): Cover {\n return {\n ...cover,\n ...(cover.name !== undefined ? { name: pickLocale(cover.name, locale, cover.defaultLocale) } : {}),\n ...(cover.description !== undefined ? { description: pickLocale(cover.description, locale, cover.defaultLocale) } : {}),\n }\n}\n\n/**\n * Resolve a `string | { [locale]: string }` value to a string for a\n * given locale. Exported so the bundle reader can reuse it without\n * duplicating the fallback chain.\n *\n * **Looser than `resolveI18nText`** — the hub's record-field resolver\n * throws `LocaleNotSpecifiedError` when no translation matches, but\n * label semantics deliberately prefer \"show *something*\" over\n * throwing. The fallback chain is:\n * 1. Exact `locale` match.\n * 2. `defaultLocale` (when supplied on the cover).\n * 3. First non-empty value in the map.\n * 4. Empty string (only if every translation is empty — pathological).\n *\n * This deviation is documented in `https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/public-envelope.md`.\n */\nexport function pickLocale(\n value: string | Record<string, string>,\n locale: string,\n defaultLocale: string | undefined,\n): string {\n if (typeof value === 'string') return value\n if (value[locale] !== undefined && value[locale] !== '') return value[locale]\n if (defaultLocale && value[defaultLocale] !== undefined && value[defaultLocale] !== '') {\n return value[defaultLocale]\n }\n for (const v of Object.values(value)) {\n if (v !== '') return v\n }\n return ''\n}\n\n// ─── Deprecated aliases (#799 public-envelope → cover; remove after one pre-release window) ───\n\n/** @deprecated Use {@link COVER_RECORD_ID}. */\nexport const PUBLIC_ENVELOPE_RECORD_ID = COVER_RECORD_ID\n/** @deprecated Use {@link loadCover}. */\nexport const loadPublicEnvelope = loadCover\n/** @deprecated Use {@link saveCover}. */\nexport const savePublicEnvelope = saveCover\n/** @deprecated Use {@link readCover}. */\nexport const readPublicEnvelope = readCover\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/with-party/directory/cover/custom.ts","../src/with-party/directory/cover/schema.ts","../src/with-party/directory/cover/storage.ts"],"sourcesContent":["/**\n * The cover's namespaced `custom` extension slot (#800) — input\n * validation, the namespace-level patch merge, and the post-merge\n * size caps.\n *\n * Like everything on the cover, `custom` is plaintext, public by\n * design, and unauthenticated — payloads are hints (display defaults,\n * routing suggestions, registry pointers), never an input to\n * security, authorization, or data-integrity decisions.\n *\n * @see https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/public-envelope.md\n *\n * @module\n */\nimport { ValidationError } from '../../../kernel/errors.js'\nimport type { Cover, JsonValue, ResolvedCoverSchema } from './types.js'\n\n/**\n * Namespace keys must be reverse-DNS or package-style identifiers —\n * at least one dot/dash-separated segment (`noydb.viewer`,\n * `com.acme.registry` pass; a bare `config` fails), so two frameworks\n * can't collide on a bare word.\n */\nconst CUSTOM_KEY_PATTERN = /^[a-z0-9]+([.-][a-z0-9]+)+$/i\n\n/** Maximum nesting depth of a namespace payload (containers, not leaves). */\nconst MAX_CUSTOM_DEPTH = 8\n\n/**\n * Validate the owner-supplied `custom` input: the field must be a\n * plain object, every key must match {@link CUSTOM_KEY_PATTERN}, and\n * every value must be JSON-serializable (no functions, `undefined`,\n * symbols, bigints, or cycles) within the depth cap. `null` is\n * accepted — it is the delete-this-namespace directive and never\n * persists. Throws `ValidationError` on the first violation.\n */\nexport function validateCustomInput(custom: Record<string, JsonValue>): void {\n if (custom === null || typeof custom !== 'object' || Array.isArray(custom)) {\n throw new ValidationError(\n `setCover: custom must be a { [namespace]: value } object, got ${\n Array.isArray(custom) ? 'array' : typeof custom\n }.`,\n )\n }\n for (const [ns, value] of Object.entries(custom)) {\n if (!CUSTOM_KEY_PATTERN.test(ns)) {\n throw new ValidationError(\n `setCover: custom namespace \"${ns}\" is invalid. Keys must be ` +\n 'reverse-DNS or package-style identifiers with at least one ' +\n 'dot/dash-separated segment (e.g. \"noydb.viewer\", \"com.acme.registry\").',\n )\n }\n assertJsonValue(value, ns, 1, new Set())\n }\n}\n\nfunction assertJsonValue(\n value: unknown,\n ns: string,\n depth: number,\n seen: Set<object>,\n): void {\n if (value === null) return\n const t = typeof value\n if (t === 'string' || t === 'number' || t === 'boolean') return\n if (t !== 'object') {\n throw new ValidationError(\n `setCover: custom[\"${ns}\"] contains a non-JSON value (${t}). ` +\n 'Only strings, numbers, booleans, null, arrays, and plain objects are allowed.',\n )\n }\n const container = value as object\n if (seen.has(container)) {\n throw new ValidationError(\n `setCover: custom[\"${ns}\"] contains a circular reference.`,\n )\n }\n if (depth > MAX_CUSTOM_DEPTH) {\n throw new ValidationError(\n `setCover: custom[\"${ns}\"] nests deeper than the ${MAX_CUSTOM_DEPTH}-level cap.`,\n )\n }\n seen.add(container)\n const children = Array.isArray(container) ? container : Object.values(container)\n for (const child of children) {\n assertJsonValue(child, ns, depth + 1, seen)\n }\n seen.delete(container)\n}\n\n/**\n * Namespace-level patch merge for `setCover`: provided namespaces\n * replace their previous value, absent namespaces are preserved, and\n * an explicit `null` deletes that namespace (so `null` never persists\n * as a namespace value). A whole-`custom`-absent patch preserves the\n * previous custom, consistent with the other cover fields. Rationale:\n * framework A must never need read-modify-write of framework B's data.\n *\n * Returns a spreadable fragment — `{ custom }` when the merge leaves\n * at least one namespace, `{}` when it leaves none (the field is\n * dropped from the persisted document rather than stored empty).\n */\nexport function mergeCustom(\n existing: Record<string, JsonValue> | undefined,\n patch: Record<string, JsonValue> | undefined,\n): { custom: Record<string, JsonValue> } | Record<string, never> {\n if (patch === undefined) {\n return existing !== undefined ? { custom: existing } : {}\n }\n const merged: Record<string, JsonValue> = { ...existing }\n for (const [ns, value] of Object.entries(patch)) {\n if (value === null) {\n delete merged[ns]\n } else {\n merged[ns] = value\n }\n }\n return Object.keys(merged).length > 0 ? { custom: merged } : {}\n}\n\n/**\n * Post-merge size caps — validates the WOULD-BE-PERSISTED document\n * (after the namespace merge), so a small patch can't tip the stored\n * cover over a cap unnoticed. `maxCoverBytes` bounds the entire\n * serialized document, which also closes the unbounded locale-map\n * key-count hole for `name` / `description`. Sizes are measured as\n * `JSON.stringify` length. Throws `ValidationError` on violation.\n */\nexport function validateCoverSize(\n cover: Cover,\n schema: ResolvedCoverSchema,\n): void {\n if (cover.custom !== undefined) {\n const customSize = JSON.stringify(cover.custom).length\n if (customSize > schema.maxCustomBytes) {\n throw new ValidationError(\n `setCover: custom exceeds the ${schema.maxCustomBytes}-byte cap ` +\n `(got ${customSize} bytes serialized, after merging with the stored namespaces).`,\n )\n }\n }\n const totalSize = JSON.stringify(cover).length\n if (totalSize > schema.maxCoverBytes) {\n throw new ValidationError(\n `setCover: the cover document exceeds the ${schema.maxCoverBytes}-byte cap ` +\n `(got ${totalSize} bytes serialized).`,\n )\n }\n}\n","/**\n * Validate-on-write for the cover. Runs at every `setCover` call;\n * the developer's schema decides which fields are allowed and the\n * size caps that apply.\n *\n * @module\n */\nimport { ValidationError } from '../../../kernel/errors.js'\nimport { validateCustomInput } from './custom.js'\nimport type {\n Cover,\n CoverText,\n JsonValue,\n ResolvedCoverSchema,\n CoverField,\n} from './types.js'\n\n/** Owner-supplied input — the subset of {@link Cover} the owner can set. */\nexport interface SetCoverInput {\n readonly name?: CoverText\n readonly description?: CoverText\n readonly icon?: string\n readonly defaultLocale?: string\n /**\n * Namespace-level patch for the cover's `custom` slot (#800):\n * provided namespaces replace their previous value, absent\n * namespaces are preserved, an explicit `null` deletes that\n * namespace. Requires `'custom'` in the schema's `fields` list —\n * the `cover: true` shorthand does NOT enable it.\n */\n readonly custom?: Record<string, JsonValue>\n}\n\nconst DATA_URL_PREFIX = /^data:([a-zA-Z0-9.+-]+\\/[a-zA-Z0-9.+-]+);base64,/\n\n/**\n * Validate an owner-supplied cover input against the developer's\n * resolved schema. Throws `ValidationError` on the first violation;\n * returns void on success.\n *\n * The validator is deliberately strict: every fail mode is a hard\n * error rather than a silent drop, so the owner finds out immediately\n * which field they oversized rather than discovering a truncated\n * label months later.\n */\nexport function validateCoverInput(\n input: SetCoverInput,\n schema: ResolvedCoverSchema,\n): void {\n const allowed = new Set<CoverField>(schema.fields)\n\n // Reject any key not in the schema's allowed-field list.\n for (const key of Object.keys(input)) {\n const known: CoverField | undefined =\n key === 'name' || key === 'description' || key === 'icon' || key === 'defaultLocale' || key === 'custom'\n ? key\n : undefined\n if (!known) {\n throw new ValidationError(\n `setCover: unknown field \"${key}\". ` +\n `Allowed fields: ${[...allowed].join(', ')}.`,\n )\n }\n if (!allowed.has(known)) {\n throw new ValidationError(\n `setCover: field \"${known}\" is not enabled in this vault's schema. ` +\n `Allowed fields: ${[...allowed].join(', ')}.`,\n )\n }\n }\n\n if (input.name !== undefined) {\n validateText(input.name, 'name', schema.maxStringChars)\n }\n if (input.description !== undefined) {\n validateText(input.description, 'description', schema.maxStringChars)\n }\n if (input.icon !== undefined) {\n validateIcon(input.icon, schema)\n }\n if (input.defaultLocale !== undefined && typeof input.defaultLocale !== 'string') {\n throw new ValidationError(\n `setCover: defaultLocale must be a string (BCP-47), got ${typeof input.defaultLocale}.`,\n )\n }\n if (input.custom !== undefined) {\n validateCustomInput(input.custom)\n }\n}\n\nfunction validateText(\n value: CoverText,\n field: string,\n maxChars: number,\n): void {\n if (typeof value === 'string') {\n if (value.length > maxChars) {\n throw new ValidationError(\n `setCover: ${field} exceeds the ${maxChars}-character cap (got ${value.length}).`,\n )\n }\n return\n }\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new ValidationError(\n `setCover: ${field} must be a string or { [locale]: string } map, got ${typeof value}.`,\n )\n }\n // Locale map. Each value must be a non-empty string within the cap.\n for (const [locale, str] of Object.entries(value)) {\n if (typeof str !== 'string') {\n throw new ValidationError(\n `setCover: ${field}[${locale}] must be a string, got ${typeof str}.`,\n )\n }\n if (str.length > maxChars) {\n throw new ValidationError(\n `setCover: ${field}[${locale}] exceeds the ${maxChars}-character cap (got ${str.length}).`,\n )\n }\n }\n}\n\nfunction validateIcon(icon: string, schema: ResolvedCoverSchema): void {\n if (typeof icon !== 'string') {\n throw new ValidationError(\n `setCover: icon must be a data: URL string, got ${typeof icon}.`,\n )\n }\n if (icon.length > schema.maxIconBytes) {\n throw new ValidationError(\n `setCover: icon exceeds the ${schema.maxIconBytes}-byte cap (got ${icon.length}).`,\n )\n }\n const m = DATA_URL_PREFIX.exec(icon)\n if (!m) {\n throw new ValidationError(\n 'setCover: icon must be a base64 data URL ' +\n '(`data:image/png;base64,…` or `data:image/svg+xml;base64,…`). ' +\n 'External URLs are not supported in v1.',\n )\n }\n const mime = m[1]!\n if (!schema.iconMimeTypes.includes(mime)) {\n throw new ValidationError(\n `setCover: icon MIME type \"${mime}\" is not allowed. ` +\n `Permitted types: ${schema.iconMimeTypes.join(', ')}.`,\n )\n }\n}\n\n/**\n * Lightweight runtime predicate — used by the bundle header\n * validator to recognise a cover without requiring it. (The wire\n * discriminator keeps its frozen name: `_noydb_public: 1`.)\n */\nexport function isCover(x: unknown): x is Cover {\n if (x === null || typeof x !== 'object' || Array.isArray(x)) return false\n const obj = x as Record<string, unknown>\n return obj['_noydb_public'] === 1 && typeof obj['version'] === 'number'\n}\n","/**\n * Persistence helpers for `_meta/public-envelope` — the cover's\n * frozen wire location. Mirrors the bypass-AES pattern used by\n * `_meta/handle` and `_meta/policy` — the document is plaintext\n * JSON, the envelope's `_iv` field is left empty.\n *\n * @module\n */\nimport type { NoydbStore, EncryptedEnvelope } from '../../../kernel/types.js'\nimport { NOYDB_FORMAT_VERSION } from '../../../kernel/types.js'\nimport type { Cover } from './types.js'\nimport { isCover } from './schema.js'\n\n/**\n * Reserved id for the vault-level cover record. The VALUE is frozen\n * wire format — the record predates the #799 rename and stays at\n * `_meta/public-envelope` so existing vaults need no migration.\n */\nexport const COVER_RECORD_ID = 'public-envelope'\n\n/**\n * Read the cover from `_meta/public-envelope`. Returns `undefined`\n * when no cover has been persisted (fresh vault, or a vault written\n * before the feature was enabled). Tolerates corrupted documents —\n * a JSON parse failure surfaces as `undefined`, not a thrown error,\n * mirroring `_meta/handle`'s contract.\n */\nexport async function loadCover(\n store: NoydbStore,\n vault: string,\n): Promise<Cover | undefined> {\n const envelope = await store.get(vault, '_meta', COVER_RECORD_ID)\n if (!envelope) return undefined\n try {\n const parsed = JSON.parse(envelope._data) as unknown\n if (!isCover(parsed)) return undefined\n return parsed\n } catch {\n return undefined\n }\n}\n\n/** Persist the cover. Idempotent — overwrites any prior write. */\nexport async function saveCover(\n store: NoydbStore,\n vault: string,\n cover: Cover,\n): Promise<void> {\n const wireEnvelope: EncryptedEnvelope = {\n _noydb: NOYDB_FORMAT_VERSION,\n _v: 1,\n _ts: new Date().toISOString(),\n _iv: '',\n _data: JSON.stringify(cover),\n }\n await store.put(vault, '_meta', COVER_RECORD_ID, wireEnvelope)\n}\n\n/**\n * Public, no-key reader. Plain function, not a method on `Noydb` —\n * the whole point is it works without an authenticated session, so\n * a UI can show \"Acme 2026 Tax Records\" before unlocking.\n *\n * Resolves any `name` / `description` locale map through the supplied\n * `locale` (when provided). Omitting `locale` returns the raw\n * cover, which a multilingual picker can render as it pleases.\n */\nexport async function readCover(\n store: NoydbStore,\n vault: string,\n opts: { readonly locale?: string } = {},\n): Promise<Cover | undefined> {\n const raw = await loadCover(store, vault)\n if (!raw) return undefined\n if (opts.locale === undefined) return raw\n return resolveLocale(raw, opts.locale)\n}\n\n/**\n * Resolve the locale-map fields (`name`, `description`) of a cover\n * to plain strings for the requested locale, falling back through\n * `defaultLocale` and then any available translation.\n *\n * @internal\n */\nexport function resolveLocale(\n cover: Cover,\n locale: string,\n): Cover {\n return {\n ...cover,\n ...(cover.name !== undefined ? { name: pickLocale(cover.name, locale, cover.defaultLocale) } : {}),\n ...(cover.description !== undefined ? { description: pickLocale(cover.description, locale, cover.defaultLocale) } : {}),\n }\n}\n\n/**\n * Resolve a `string | { [locale]: string }` value to a string for a\n * given locale. Exported so the bundle reader can reuse it without\n * duplicating the fallback chain.\n *\n * **Looser than `resolveI18nText`** — the hub's record-field resolver\n * throws `LocaleNotSpecifiedError` when no translation matches, but\n * label semantics deliberately prefer \"show *something*\" over\n * throwing. The fallback chain is:\n * 1. Exact `locale` match.\n * 2. `defaultLocale` (when supplied on the cover).\n * 3. First non-empty value in the map.\n * 4. Empty string (only if every translation is empty — pathological).\n *\n * This deviation is documented in `https://github.com/vLannaAi/noy-db-docs/blob/main/content/docs/services/public-envelope.md`.\n */\nexport function pickLocale(\n value: string | Record<string, string>,\n locale: string,\n defaultLocale: string | undefined,\n): string {\n if (typeof value === 'string') return value\n if (value[locale] !== undefined && value[locale] !== '') return value[locale]\n if (defaultLocale && value[defaultLocale] !== undefined && value[defaultLocale] !== '') {\n return value[defaultLocale]\n }\n for (const v of Object.values(value)) {\n if (v !== '') return v\n }\n return ''\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
installViaBinder
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6UBZ6I5Z.js";
|
|
4
4
|
import {
|
|
5
5
|
LocaleNotSpecifiedError,
|
|
6
6
|
MissingTranslationError,
|
|
7
7
|
ScriptViolationError,
|
|
8
8
|
TranslatorNotConfiguredError
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QZWTRENR.js";
|
|
10
10
|
|
|
11
11
|
// src/port/with/i18n-strategy.ts
|
|
12
12
|
function notEnabled(op) {
|
|
@@ -618,4 +618,4 @@ export {
|
|
|
618
618
|
presentI18nForJoin,
|
|
619
619
|
stripI18nFilled
|
|
620
620
|
};
|
|
621
|
-
//# sourceMappingURL=chunk-
|
|
621
|
+
//# sourceMappingURL=chunk-UADPR6F4.js.map
|