framefields 2.11.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +4 -0
- package/dist/audio/index.d.mts +6 -5
- package/dist/audio/index.mjs +13 -13
- package/dist/{audio-CYZkDwae.d.mts → audio-CHV33Od9.d.mts} +3 -4
- package/dist/audio-CHV33Od9.d.mts.map +1 -0
- package/dist/{audio-BuCVk1IQ.mjs → audio-DHzLQ_RG.mjs} +4 -4
- package/dist/{audio-BuCVk1IQ.mjs.map → audio-DHzLQ_RG.mjs.map} +1 -1
- package/dist/{audio-KHBadECb.mjs → audio-DS9Jg2ls.mjs} +1 -1
- package/dist/{audio-KHBadECb.mjs.map → audio-DS9Jg2ls.mjs.map} +1 -1
- package/dist/{check-result-Culfu7Nx.mjs → check-result-DZWx73V8.mjs} +1 -1
- package/dist/{check-result-Culfu7Nx.mjs.map → check-result-DZWx73V8.mjs.map} +1 -1
- package/dist/cli/check-worker.mjs +51 -51
- package/dist/cli/check-worker.mjs.map +1 -1
- package/dist/cli/local-worker.d.mts +28 -0
- package/dist/cli/local-worker.d.mts.map +1 -0
- package/dist/cli/local-worker.mjs +83 -0
- package/dist/cli/local-worker.mjs.map +1 -0
- package/dist/cli.mjs +390 -124
- package/dist/cli.mjs.map +1 -1
- package/dist/cloud/index.d.mts +16 -3
- package/dist/cloud/index.d.mts.map +1 -1
- package/dist/cloud/index.mjs +2 -2
- package/dist/cloud-Cj1TIme8.mjs +685 -0
- package/dist/cloud-Cj1TIme8.mjs.map +1 -0
- package/dist/components/index.d.mts +15 -14
- package/dist/components/index.mjs +47 -47
- package/dist/{dist-CySGkG54.mjs → dist-BSKAbyea.mjs} +2 -2
- package/dist/dist-BSKAbyea.mjs.map +1 -0
- package/dist/{dist-CNGv-JTX.mjs → dist-B_rSWeOz.mjs} +1 -1
- package/dist/{dist-Bf2_efYP.mjs → dist-C8XSqfTx.mjs} +1 -1
- package/dist/{dist-Bf2_efYP.mjs.map → dist-C8XSqfTx.mjs.map} +1 -1
- package/dist/{dist-EQX3TUUl.mjs → dist-CUNvNDS3.mjs} +129 -82
- package/dist/dist-CUNvNDS3.mjs.map +1 -0
- package/dist/dist-CiTgmfUw.mjs +502 -0
- package/dist/dist-CiTgmfUw.mjs.map +1 -0
- package/dist/{dist-CWLLnigL.mjs → dist-D3BeAZ7X.mjs} +315 -84
- package/dist/dist-D3BeAZ7X.mjs.map +1 -0
- package/dist/{dist-BIE8fvlv.mjs → dist-DgZpN6IK.mjs} +1 -1
- package/dist/{dist-BIE8fvlv.mjs.map → dist-DgZpN6IK.mjs.map} +1 -1
- package/dist/{dist-Dg9LMWoX.mjs → dist-Kbf-JTry.mjs} +2 -2
- package/dist/{dist-Dg9LMWoX.mjs.map → dist-Kbf-JTry.mjs.map} +1 -1
- package/dist/effects/index.d.mts +6 -6
- package/dist/effects/index.mjs +36 -36
- package/dist/{effects-DKLbLXF7.mjs → effects-BiDgCK1L.mjs} +3 -3
- package/dist/{effects-DKLbLXF7.mjs.map → effects-BiDgCK1L.mjs.map} +1 -1
- package/dist/fonts/index.d.mts +1 -1
- package/dist/fonts/index.mjs +3 -3
- package/dist/{fonts-gPbGbShD.mjs → fonts-DeDPWdvJ.mjs} +2 -2
- package/dist/{fonts-gPbGbShD.mjs.map → fonts-DeDPWdvJ.mjs.map} +1 -1
- package/dist/{gpu-CpkJJLQP.mjs → gpu-CWjgql4C.mjs} +11 -3
- package/dist/gpu-CWjgql4C.mjs.map +1 -0
- package/dist/index-BFTtXosj.d.mts +63 -0
- package/dist/index-BFTtXosj.d.mts.map +1 -0
- package/dist/{index-BW0Q1ygn.d.mts → index-C5sgRLlG.d.mts} +1 -1
- package/dist/{index-BW0Q1ygn.d.mts.map → index-C5sgRLlG.d.mts.map} +1 -1
- package/dist/{index-CdCrae-I.d.mts → index-CnZhBlob.d.mts} +2 -2
- package/dist/index-CnZhBlob.d.mts.map +1 -0
- package/dist/{index-D2i9J9Zq.d.mts → index-D68eGFNE.d.mts} +3 -30
- package/dist/index-D68eGFNE.d.mts.map +1 -0
- package/dist/{index-CEU_Zsb9.d.mts → index-DBh3WphX.d.mts} +25 -23
- package/dist/index-DBh3WphX.d.mts.map +1 -0
- package/dist/{index-gOVtTm-P.d.mts → index-DQ1U3HC3.d.mts} +14 -6
- package/dist/index-DQ1U3HC3.d.mts.map +1 -0
- package/dist/{index-jSDEM-uE.d.mts → index-Dibc_xpC.d.mts} +6 -6
- package/dist/{index-jSDEM-uE.d.mts.map → index-Dibc_xpC.d.mts.map} +1 -1
- package/dist/{index-Cro-818i.d.mts → index-E2IXX0Cz.d.mts} +88 -14
- package/dist/index-E2IXX0Cz.d.mts.map +1 -0
- package/dist/{index-BuiZzc6i.d.mts → index-X2u96TEo.d.mts} +162 -5
- package/dist/index-X2u96TEo.d.mts.map +1 -0
- package/dist/{index-Bly-7YM1.d.mts → index-YB9j9KUx.d.mts} +3 -3
- package/dist/{index-Bly-7YM1.d.mts.map → index-YB9j9KUx.d.mts.map} +1 -1
- package/dist/{index-COYNQ_mf.d.mts → index-a6JrbAK0.d.mts} +1 -1
- package/dist/{index-COYNQ_mf.d.mts.map → index-a6JrbAK0.d.mts.map} +1 -1
- package/dist/{index-C8YwZ6k1.d.mts → index-rtCXNxGO.d.mts} +2 -2
- package/dist/{index-C8YwZ6k1.d.mts.map → index-rtCXNxGO.d.mts.map} +1 -1
- package/dist/index.d.mts +16 -15
- package/dist/index.mjs +58 -58
- package/dist/preview/index.d.mts +5 -4
- package/dist/preview/index.mjs +12 -12
- package/dist/{preview-BToKUTtZ.mjs → preview-PDz7o2xg.mjs} +323 -35
- package/dist/preview-PDz7o2xg.mjs.map +1 -0
- package/dist/preview-engine/audio.mjs +1 -1
- package/dist/preview-engine/{chunk-QF4JWVO3.mjs → chunk-35XSD4QM.mjs} +15 -15
- package/dist/preview-engine/{chunk-ZF2MEFKO.mjs → chunk-3DOIE4DV.mjs} +1 -1
- package/dist/preview-engine/{chunk-JDB7PMRI.mjs → chunk-3IT7LHWR.mjs} +1 -1
- package/dist/preview-engine/{chunk-DNNGWS2C.mjs → chunk-3MLGWUSK.mjs} +1 -1
- package/dist/preview-engine/{chunk-KVOFO273.mjs → chunk-3QJ5GRBH.mjs} +1 -1
- package/dist/preview-engine/{chunk-54Q5CKSV.mjs → chunk-3QTHW2CD.mjs} +1 -1
- package/dist/preview-engine/chunk-44V4V5LD.mjs +1 -0
- package/dist/preview-engine/chunk-4P3MMJWD.mjs +1 -0
- package/dist/preview-engine/chunk-4YT5YJIF.mjs +1 -0
- package/dist/preview-engine/{chunk-BJXNKMSY.mjs → chunk-64L4GUOF.mjs} +20 -6
- package/dist/preview-engine/{chunk-UMJ3VGKN.mjs → chunk-6B3NOY5W.mjs} +1 -1
- package/dist/preview-engine/chunk-77MT33VR.mjs +1 -0
- package/dist/preview-engine/{chunk-BRV7TQDV.mjs → chunk-77WWW75O.mjs} +1 -1
- package/dist/preview-engine/chunk-7M5LE6EM.mjs +483 -0
- package/dist/preview-engine/chunk-A6OAPDIA.mjs +1 -0
- package/dist/preview-engine/chunk-ADLIF544.mjs +39 -0
- package/dist/preview-engine/{chunk-OLB4TQLQ.mjs → chunk-AKVRG7UU.mjs} +1 -1
- package/dist/preview-engine/{chunk-CIVEZJYF.mjs → chunk-CRBOK3JT.mjs} +1 -1
- package/dist/preview-engine/chunk-CSLSWUUT.mjs +1 -0
- package/dist/preview-engine/{chunk-ACBBBOUM.mjs → chunk-CYM75INB.mjs} +1 -1
- package/dist/preview-engine/{chunk-JSYG6OWZ.mjs → chunk-D7OMXGIZ.mjs} +1 -1
- package/dist/preview-engine/{chunk-EPRINA4V.mjs → chunk-E7BKWHOT.mjs} +10 -10
- package/dist/preview-engine/{chunk-NOKPBMIP.mjs → chunk-EWDJMJO5.mjs} +1 -1
- package/dist/preview-engine/{chunk-5KSBS3AL.mjs → chunk-EYE3GNL5.mjs} +1 -1
- package/dist/preview-engine/chunk-FRJPXWAG.mjs +1 -0
- package/dist/preview-engine/{chunk-IKVJ4MW5.mjs → chunk-G4ZTSLZU.mjs} +1 -1
- package/dist/preview-engine/{chunk-VZLIRYAL.mjs → chunk-GAMAKN5L.mjs} +1 -1
- package/dist/preview-engine/{chunk-ZIXPWP2B.mjs → chunk-ICWD36H6.mjs} +1 -1
- package/dist/preview-engine/{chunk-OELPPLML.mjs → chunk-IEEV5RB3.mjs} +1 -1
- package/dist/preview-engine/chunk-JAAFSVAG.mjs +1 -0
- package/dist/preview-engine/{chunk-YVZTRH4Y.mjs → chunk-KDCM7S3S.mjs} +1 -1
- package/dist/preview-engine/chunk-LZNHGH56.mjs +5 -0
- package/dist/preview-engine/{chunk-O63FLYWC.mjs → chunk-N2VISDTG.mjs} +1 -1
- package/dist/preview-engine/{chunk-GN3NDRLI.mjs → chunk-NCQHOGZK.mjs} +1 -1
- package/dist/preview-engine/{chunk-YKM7JDQY.mjs → chunk-NJO2BIJX.mjs} +1 -1
- package/dist/preview-engine/{chunk-7GMHSTRP.mjs → chunk-NTSALWFF.mjs} +1 -1
- package/dist/preview-engine/{chunk-PKNUTHPI.mjs → chunk-NVXFEDJS.mjs} +1 -1
- package/dist/preview-engine/{chunk-VFQH5KVS.mjs → chunk-ONHY4KNY.mjs} +1 -1
- package/dist/preview-engine/{chunk-Z24UEN4P.mjs → chunk-PD2HKW2S.mjs} +1 -1
- package/dist/preview-engine/chunk-PH3UUX6A.mjs +138 -0
- package/dist/preview-engine/chunk-PIHG6HJO.mjs +1 -0
- package/dist/preview-engine/{chunk-YHMBGJP6.mjs → chunk-QPT2Y2GZ.mjs} +1 -1
- package/dist/preview-engine/{chunk-4AGQN53P.mjs → chunk-QXLFTCLC.mjs} +1 -1
- package/dist/preview-engine/{chunk-65NANVQL.mjs → chunk-R4H52Q7S.mjs} +1 -1
- package/dist/preview-engine/{chunk-FQL4IJZN.mjs → chunk-RN7J5TRU.mjs} +1 -1
- package/dist/preview-engine/{chunk-26XWIHW3.mjs → chunk-RVCLMO5Q.mjs} +1 -1
- package/dist/preview-engine/{chunk-VQA4DYZU.mjs → chunk-RYSV44B4.mjs} +1 -1
- package/dist/preview-engine/{chunk-TEWRQKX3.mjs → chunk-SFHWP65D.mjs} +1 -1
- package/dist/preview-engine/{chunk-RDWLLITE.mjs → chunk-SMHEMYCV.mjs} +1 -1
- package/dist/preview-engine/{chunk-EXEO245X.mjs → chunk-SV3ZNZQU.mjs} +1 -1
- package/dist/preview-engine/{chunk-32WC4FRR.mjs → chunk-UE7Y65C3.mjs} +3 -3
- package/dist/preview-engine/chunk-UFPA36D2.mjs +2227 -0
- package/dist/preview-engine/{chunk-EAWJXW4J.mjs → chunk-UVEDFIPN.mjs} +1 -1
- package/dist/preview-engine/{chunk-6LTINEA4.mjs → chunk-VMXJZ4KQ.mjs} +1 -1
- package/dist/preview-engine/{chunk-IBPYV6HF.mjs → chunk-W4XR6F5G.mjs} +1 -1
- package/dist/preview-engine/{chunk-UI3VH33L.mjs → chunk-WPYWCWWL.mjs} +1 -1
- package/dist/preview-engine/{chunk-GHTG5XV6.mjs → chunk-XYCR3STG.mjs} +84 -25
- package/dist/preview-engine/{chunk-WFMUDL55.mjs → chunk-YAPGJZPI.mjs} +1 -1
- package/dist/preview-engine/{chunk-LMXMBX4J.mjs → chunk-YJ4DSRDY.mjs} +1 -1
- package/dist/preview-engine/{chunk-CCORQLMR.mjs → chunk-YOJKIMU5.mjs} +1 -1
- package/dist/preview-engine/{chunk-UGB6JKVS.mjs → chunk-ZHNEZZ6A.mjs} +1 -1
- package/dist/preview-engine/{chunk-LFNCWMKS.mjs → chunk-ZZMI3WOT.mjs} +1 -1
- package/dist/preview-engine/components.mjs +1 -1
- package/dist/preview-engine/effects.mjs +1 -1
- package/dist/preview-engine/fonts.mjs +1 -1
- package/dist/preview-engine/framefields.mjs +1 -1
- package/dist/preview-engine/player.mjs +5 -5
- package/dist/preview-engine/{renderers-53EI26GL.mjs → renderers-3FZVDYRQ.mjs} +1 -1
- package/dist/preview-engine/renderers-3KEBYOOF.mjs +1 -0
- package/dist/preview-engine/{renderers-6YVZUQOH.mjs → renderers-4RPQSUUZ.mjs} +1 -1
- package/dist/preview-engine/renderers-5EGFXFPF.mjs +1 -0
- package/dist/preview-engine/renderers-5SJHYUTM.mjs +1 -0
- package/dist/preview-engine/renderers-66MWDUN6.mjs +1 -0
- package/dist/preview-engine/{renderers-CCRZNGVK.mjs → renderers-6FENMFSC.mjs} +1 -1
- package/dist/preview-engine/renderers-77OXJ2GY.mjs +1 -0
- package/dist/preview-engine/renderers-7LI4QKHO.mjs +1 -0
- package/dist/preview-engine/renderers-AFTUFMQQ.mjs +1 -0
- package/dist/preview-engine/{renderers-CYJAVWHT.mjs → renderers-AIZRIW2R.mjs} +1 -1
- package/dist/preview-engine/{renderers-OGOW3NA4.mjs → renderers-BDI2BDBA.mjs} +1 -1
- package/dist/preview-engine/renderers-BDXCO6NR.mjs +1 -0
- package/dist/preview-engine/{renderers-EN7LXJLG.mjs → renderers-BUZ67FNZ.mjs} +1 -1
- package/dist/preview-engine/renderers-DMTGKURQ.mjs +1 -0
- package/dist/preview-engine/renderers-DU7KPFVV.mjs +1 -0
- package/dist/preview-engine/{renderers-WSABL3QO.mjs → renderers-ECXMT5BD.mjs} +1 -1
- package/dist/preview-engine/{renderers-MOEC2XZZ.mjs → renderers-EILFSWSJ.mjs} +1 -1
- package/dist/preview-engine/renderers-EPSF5CSQ.mjs +1 -0
- package/dist/preview-engine/{renderers-X6CORAES.mjs → renderers-EVEWFJ7U.mjs} +1 -1
- package/dist/preview-engine/renderers-F6PT2LON.mjs +1 -0
- package/dist/preview-engine/renderers-F7WPJXKT.mjs +1 -0
- package/dist/preview-engine/renderers-FIFF267S.mjs +1 -0
- package/dist/preview-engine/{renderers-GQM3KMV3.mjs → renderers-FQISHQEN.mjs} +1 -1
- package/dist/preview-engine/{renderers-HKLCB4U6.mjs → renderers-FXAVFNUN.mjs} +1 -1
- package/dist/preview-engine/{renderers-P2HORBZ6.mjs → renderers-GITAVRYZ.mjs} +1 -1
- package/dist/preview-engine/renderers-GTKRV225.mjs +1 -0
- package/dist/preview-engine/{renderers-KCGK33Y2.mjs → renderers-HG6JZIZO.mjs} +1 -1
- package/dist/preview-engine/{renderers-I6QKZ7CH.mjs → renderers-HHWMIDN3.mjs} +1 -1
- package/dist/preview-engine/renderers-HI3SRJVD.mjs +1 -0
- package/dist/preview-engine/{renderers-7CAHX35U.mjs → renderers-HXEDI4BD.mjs} +1 -1
- package/dist/preview-engine/{renderers-77PDUMYI.mjs → renderers-HXNSDJBY.mjs} +1 -1
- package/dist/preview-engine/{renderers-ACUJMDEK.mjs → renderers-I2ZOUFRU.mjs} +1 -1
- package/dist/preview-engine/renderers-JHFD4LHZ.mjs +1 -0
- package/dist/preview-engine/{renderers-IHGAWLUF.mjs → renderers-JMSAW7VY.mjs} +1 -1
- package/dist/preview-engine/renderers-KGVZUFHD.mjs +1 -0
- package/dist/preview-engine/{renderers-RN2MHIFK.mjs → renderers-KICDB5Y6.mjs} +1 -1
- package/dist/preview-engine/{renderers-C7SI3NIE.mjs → renderers-KKULMOV4.mjs} +1 -1
- package/dist/preview-engine/{renderers-HSFQIILN.mjs → renderers-KMVMPYY7.mjs} +1 -1
- package/dist/preview-engine/renderers-LN7WPG6I.mjs +1 -0
- package/dist/preview-engine/{renderers-BOBVXYAA.mjs → renderers-LWW4RF6D.mjs} +1 -1
- package/dist/preview-engine/renderers-LY57CZZB.mjs +1 -0
- package/dist/preview-engine/renderers-MBMJWZEW.mjs +1 -0
- package/dist/preview-engine/{renderers-VVP5WQOY.mjs → renderers-MPFU74I3.mjs} +1 -1
- package/dist/preview-engine/{renderers-H6PBHEYU.mjs → renderers-MW53LTMB.mjs} +1 -1
- package/dist/preview-engine/{renderers-PPZK6VEW.mjs → renderers-NQC4DPX4.mjs} +1 -1
- package/dist/preview-engine/renderers-OJWWIVNW.mjs +1 -0
- package/dist/preview-engine/{renderers-4IBFDW2S.mjs → renderers-PC2GOZDT.mjs} +1 -1
- package/dist/preview-engine/{renderers-UG2C3C7T.mjs → renderers-Q77UPEYE.mjs} +1 -1
- package/dist/preview-engine/renderers-QHXCFDHI.mjs +1 -0
- package/dist/preview-engine/renderers-RDYJRNAR.mjs +1 -0
- package/dist/preview-engine/renderers-RENLKAA7.mjs +1 -0
- package/dist/preview-engine/renderers-RHMRWX46.mjs +1 -0
- package/dist/preview-engine/{renderers-5XLGCEOA.mjs → renderers-RIPXT4AL.mjs} +1 -1
- package/dist/preview-engine/{renderers-FY2HOQCS.mjs → renderers-SFVFAS3C.mjs} +1 -1
- package/dist/preview-engine/{renderers-VIGZYJYX.mjs → renderers-SWQVCJHB.mjs} +1 -1
- package/dist/preview-engine/renderers-SZVDZDY7.mjs +1 -0
- package/dist/preview-engine/renderers-TTXTV4PC.mjs +228 -0
- package/dist/preview-engine/renderers-TYSLUZ53.mjs +1 -0
- package/dist/preview-engine/{renderers-6LNDAO4B.mjs → renderers-U4IXWMD6.mjs} +1 -1
- package/dist/preview-engine/renderers-VEHYARKY.mjs +1 -0
- package/dist/preview-engine/renderers-VRXAG3FR.mjs +1 -0
- package/dist/preview-engine/{renderers-33FCFHDR.mjs → renderers-VUQAZ56P.mjs} +1 -1
- package/dist/preview-engine/renderers-W5YFMLSB.mjs +1 -0
- package/dist/preview-engine/renderers-XKDWUK56.mjs +1 -0
- package/dist/preview-engine/renderers-XKSBNCLZ.mjs +1 -0
- package/dist/preview-engine/renderers-XLQXVD37.mjs +1 -0
- package/dist/preview-engine/renderers-ZHSOWEMQ.mjs +1 -0
- package/dist/preview-engine/renderers-ZMDRNYSS.mjs +1 -0
- package/dist/preview-engine/signals.mjs +1 -1
- package/dist/preview-engine/{src-4IUYUKIZ.mjs → src-YXNX4MLK.mjs} +1 -1
- package/dist/{program-Bc860ko5.mjs → program-Bn6ko_I4.mjs} +44 -17
- package/dist/program-Bn6ko_I4.mjs.map +1 -0
- package/dist/renderer/index.d.mts +4 -3
- package/dist/renderer/index.mjs +3 -3
- package/dist/{renderer-B3Dme2es.mjs → renderer--Q0pM9Vh.mjs} +5 -5
- package/dist/{renderer-B3Dme2es.mjs.map → renderer--Q0pM9Vh.mjs.map} +1 -1
- package/dist/renderer-1aSF5BmY.mjs +5 -0
- package/dist/{renderer-CAWnCsQc.mjs → renderer-45ifiDkn.mjs} +5 -5
- package/dist/{renderer-CAWnCsQc.mjs.map → renderer-45ifiDkn.mjs.map} +1 -1
- package/dist/{renderer-Cz-n883J.mjs → renderer-549d94qG.mjs} +5 -5
- package/dist/{renderer-Cz-n883J.mjs.map → renderer-549d94qG.mjs.map} +1 -1
- package/dist/{renderer-BhsrlGKp.mjs → renderer-B-LUGB9h.mjs} +74 -21
- package/dist/renderer-B-LUGB9h.mjs.map +1 -0
- package/dist/renderer-B2e4Gr9u.mjs +5 -0
- package/dist/{renderer-B1LD29TV.mjs → renderer-B5b-ehRb.mjs} +3 -3
- package/dist/{renderer-B1LD29TV.mjs.map → renderer-B5b-ehRb.mjs.map} +1 -1
- package/dist/renderer-B6fz4j50.mjs +5 -0
- package/dist/{renderer-_9gbYS-3.mjs → renderer-BCTUqJG7.mjs} +5 -5
- package/dist/{renderer-_9gbYS-3.mjs.map → renderer-BCTUqJG7.mjs.map} +1 -1
- package/dist/renderer-BEftIYw-.mjs +5 -0
- package/dist/{renderer-C9BSXyrq.mjs → renderer-BHPgkoEL.mjs} +4 -4
- package/dist/{renderer-C9BSXyrq.mjs.map → renderer-BHPgkoEL.mjs.map} +1 -1
- package/dist/renderer-BHTnO-7e.mjs +5 -0
- package/dist/{renderer-fs8f1QeE.mjs → renderer-BIieU9pY.mjs} +5 -5
- package/dist/{renderer-fs8f1QeE.mjs.map → renderer-BIieU9pY.mjs.map} +1 -1
- package/dist/{renderer-DwK9jsER.mjs → renderer-BKi6jDi_.mjs} +4 -4
- package/dist/{renderer-DwK9jsER.mjs.map → renderer-BKi6jDi_.mjs.map} +1 -1
- package/dist/renderer-BMlnQqTO.mjs +5 -0
- package/dist/{renderer-BNJ6Jk7-.mjs → renderer-BMpmmYOq.mjs} +4 -4
- package/dist/{renderer-BNJ6Jk7-.mjs.map → renderer-BMpmmYOq.mjs.map} +1 -1
- package/dist/{renderer-DkqZmfm8.mjs → renderer-BO_wuUKA.mjs} +5 -5
- package/dist/{renderer-DkqZmfm8.mjs.map → renderer-BO_wuUKA.mjs.map} +1 -1
- package/dist/renderer-BOzcFezY.mjs +5 -0
- package/dist/{renderer-Bxjb0HYU.mjs → renderer-BPOh9x5X.mjs} +4 -4
- package/dist/{renderer-Bxjb0HYU.mjs.map → renderer-BPOh9x5X.mjs.map} +1 -1
- package/dist/{renderer-Ros7XQg2.mjs → renderer-BPiWsrC2.mjs} +3 -3
- package/dist/{renderer-Ros7XQg2.mjs.map → renderer-BPiWsrC2.mjs.map} +1 -1
- package/dist/{renderer-lHNTgiOM.mjs → renderer-BUj7jE6t.mjs} +3 -3
- package/dist/{renderer-lHNTgiOM.mjs.map → renderer-BUj7jE6t.mjs.map} +1 -1
- package/dist/renderer-BVbjJIKJ.mjs +5 -0
- package/dist/renderer-BXsHKf4k.mjs +5 -0
- package/dist/{renderer-D0aAZHC7.mjs → renderer-BZgJj8Cl.mjs} +4 -4
- package/dist/{renderer-D0aAZHC7.mjs.map → renderer-BZgJj8Cl.mjs.map} +1 -1
- package/dist/{renderer-V4dhrf_h.mjs → renderer-BgjPbgbn.mjs} +6 -6
- package/dist/{renderer-V4dhrf_h.mjs.map → renderer-BgjPbgbn.mjs.map} +1 -1
- package/dist/{renderer-BaIJIfJ6.mjs → renderer-BjgFpwVK.mjs} +5 -5
- package/dist/{renderer-BaIJIfJ6.mjs.map → renderer-BjgFpwVK.mjs.map} +1 -1
- package/dist/renderer-Bks49NVl.mjs +5 -0
- package/dist/{renderer-CU8v-LxD.mjs → renderer-BlZgyBSo.mjs} +5 -5
- package/dist/{renderer-CU8v-LxD.mjs.map → renderer-BlZgyBSo.mjs.map} +1 -1
- package/dist/{renderer-B6Oeahe_.mjs → renderer-BqUAyzCZ.mjs} +5 -5
- package/dist/{renderer-B6Oeahe_.mjs.map → renderer-BqUAyzCZ.mjs.map} +1 -1
- package/dist/{renderer-h62QaJYz.mjs → renderer-Br8km655.mjs} +4 -4
- package/dist/{renderer-h62QaJYz.mjs.map → renderer-Br8km655.mjs.map} +1 -1
- package/dist/{renderer-sfqZK6L5.mjs → renderer-BsMZ5Iaq.mjs} +4 -4
- package/dist/{renderer-sfqZK6L5.mjs.map → renderer-BsMZ5Iaq.mjs.map} +1 -1
- package/dist/{renderer-g_1t2je9.mjs → renderer-BtgqTg2K.mjs} +3 -3
- package/dist/{renderer-DcvjSolU.mjs → renderer-BuvKGwk3.mjs} +11 -2
- package/dist/{renderer-DcvjSolU.mjs.map → renderer-BuvKGwk3.mjs.map} +1 -1
- package/dist/{renderer-BOrMBwQS.mjs → renderer-C-3qhk5x.mjs} +2 -2
- package/dist/{renderer-BOrMBwQS.mjs.map → renderer-C-3qhk5x.mjs.map} +1 -1
- package/dist/{renderer-CLAvn9c6.mjs → renderer-C-GTxnfv.mjs} +4 -4
- package/dist/{renderer-CLAvn9c6.mjs.map → renderer-C-GTxnfv.mjs.map} +1 -1
- package/dist/renderer-C-t7qFKr.mjs +5 -0
- package/dist/{renderer-BDZC3o3N.mjs → renderer-C1ctHdXl.mjs} +4 -4
- package/dist/{renderer-BDZC3o3N.mjs.map → renderer-C1ctHdXl.mjs.map} +1 -1
- package/dist/renderer-C24n-6CX.mjs +6 -0
- package/dist/{renderer-pNmI-A9o.mjs → renderer-C7m7Yxgc.mjs} +5 -5
- package/dist/{renderer-pNmI-A9o.mjs.map → renderer-C7m7Yxgc.mjs.map} +1 -1
- package/dist/{renderer-Bf4-N7k7.mjs → renderer-C9dqx3U7.mjs} +5 -5
- package/dist/{renderer-Bf4-N7k7.mjs.map → renderer-C9dqx3U7.mjs.map} +1 -1
- package/dist/renderer-CCReX-7M.mjs +5 -0
- package/dist/{renderer-JHByuUNb.mjs → renderer-CE4535aW.mjs} +3 -3
- package/dist/{renderer-JHByuUNb.mjs.map → renderer-CE4535aW.mjs.map} +1 -1
- package/dist/renderer-CIxFQrAm.mjs +5 -0
- package/dist/{renderer-ByjaseAo.mjs → renderer-CL-vyXgX.mjs} +5 -5
- package/dist/{renderer-ByjaseAo.mjs.map → renderer-CL-vyXgX.mjs.map} +1 -1
- package/dist/renderer-CLHBMIqJ.mjs +5 -0
- package/dist/renderer-CMJKi-Ye.mjs +5 -0
- package/dist/{renderer-B-CMRUag.mjs → renderer-CMnlgAGs.mjs} +4 -4
- package/dist/{renderer-B-CMRUag.mjs.map → renderer-CMnlgAGs.mjs.map} +1 -1
- package/dist/{renderer-BNHcwxw9.mjs → renderer-CQFMyC_c.mjs} +4 -4
- package/dist/{renderer-BNHcwxw9.mjs.map → renderer-CQFMyC_c.mjs.map} +1 -1
- package/dist/{renderer-DgPn_SOC.mjs → renderer-CYwVNbUh.mjs} +4 -4
- package/dist/{renderer-DgPn_SOC.mjs.map → renderer-CYwVNbUh.mjs.map} +1 -1
- package/dist/{renderer-DLPhfwbR.mjs → renderer-CZ5mwBW1.mjs} +3 -3
- package/dist/{renderer-DLPhfwbR.mjs.map → renderer-CZ5mwBW1.mjs.map} +1 -1
- package/dist/{renderer-4ZUv3X1I.mjs → renderer-C_1eqfI0.mjs} +5 -5
- package/dist/{renderer-4ZUv3X1I.mjs.map → renderer-C_1eqfI0.mjs.map} +1 -1
- package/dist/renderer-C_H3mHZa.mjs +5 -0
- package/dist/{renderer-B1esRxGy.mjs → renderer-CciiDHuU.mjs} +4 -4
- package/dist/{renderer-B1esRxGy.mjs.map → renderer-CciiDHuU.mjs.map} +1 -1
- package/dist/renderer-CfkTdR5B.mjs +5 -0
- package/dist/{renderer-ynFRJh7G.mjs → renderer-CgK7Q1G8.mjs} +3 -3
- package/dist/{renderer-CR0mDPYY.mjs → renderer-CnL8Cmmr.mjs} +3 -3
- package/dist/renderer-CnhkXJ0R.mjs +5 -0
- package/dist/{renderer-fwKnV9zs.mjs → renderer-Cp_HOmp7.mjs} +5 -5
- package/dist/{renderer-fwKnV9zs.mjs.map → renderer-Cp_HOmp7.mjs.map} +1 -1
- package/dist/renderer-CqpyVsq_.mjs +5 -0
- package/dist/renderer-CtWgIpTE.mjs +5 -0
- package/dist/{renderer-riIFosX6.mjs → renderer-Cu3iKMSJ.mjs} +5 -5
- package/dist/{renderer-riIFosX6.mjs.map → renderer-Cu3iKMSJ.mjs.map} +1 -1
- package/dist/{renderer-D4f8f66C.mjs → renderer-CuPAQjDK.mjs} +4 -4
- package/dist/{renderer-D4f8f66C.mjs.map → renderer-CuPAQjDK.mjs.map} +1 -1
- package/dist/{renderer-CxGx1Lhi.mjs → renderer-CwlY8Tb-.mjs} +3 -3
- package/dist/{renderer-CxGx1Lhi.mjs.map → renderer-CwlY8Tb-.mjs.map} +1 -1
- package/dist/{renderer-o68mVeyk.mjs → renderer-CxSFvKd1.mjs} +4 -4
- package/dist/{renderer-o68mVeyk.mjs.map → renderer-CxSFvKd1.mjs.map} +1 -1
- package/dist/{renderer-CrR8Mpxq.mjs → renderer-CyUiXLRa.mjs} +5 -5
- package/dist/{renderer-CrR8Mpxq.mjs.map → renderer-CyUiXLRa.mjs.map} +1 -1
- package/dist/renderer-CyuKr5ca.mjs +5 -0
- package/dist/renderer-CzgcZXKH.mjs +3 -0
- package/dist/{renderer-Bx14Wnxl.mjs → renderer-D-GWBoVT.mjs} +58 -4
- package/dist/renderer-D-GWBoVT.mjs.map +1 -0
- package/dist/{renderer-BwrfKKqw.mjs → renderer-D-fzEZfX.mjs} +4 -4
- package/dist/{renderer-BwrfKKqw.mjs.map → renderer-D-fzEZfX.mjs.map} +1 -1
- package/dist/renderer-D5yp74NL.mjs +3 -0
- package/dist/{renderer-DAn9xiQT.mjs → renderer-D8gN7aqk.mjs} +4 -4
- package/dist/{renderer-DAn9xiQT.mjs.map → renderer-D8gN7aqk.mjs.map} +1 -1
- package/dist/renderer-D9ON_1Hf.mjs +5 -0
- package/dist/renderer-DAnTgh4o.mjs +5 -0
- package/dist/{renderer-Dpl6poqD.mjs → renderer-DGOMfyh8.mjs} +2 -2
- package/dist/{renderer-Dpl6poqD.mjs.map → renderer-DGOMfyh8.mjs.map} +1 -1
- package/dist/{renderer-Rw87u1Cr.mjs → renderer-DGb_wgTW.mjs} +6 -6
- package/dist/{renderer-Rw87u1Cr.mjs.map → renderer-DGb_wgTW.mjs.map} +1 -1
- package/dist/{renderer-Co6UFbZB.mjs → renderer-DJPZs_zV.mjs} +5 -5
- package/dist/{renderer-Co6UFbZB.mjs.map → renderer-DJPZs_zV.mjs.map} +1 -1
- package/dist/renderer-DKJOon6y.d.mts +1 -0
- package/dist/{renderer-DOkbn1ot.mjs → renderer-DOZPZTxe.mjs} +5 -5
- package/dist/{renderer-DOkbn1ot.mjs.map → renderer-DOZPZTxe.mjs.map} +1 -1
- package/dist/{renderer-DaXQgGg3.mjs → renderer-DRal7Goa.mjs} +5 -5
- package/dist/{renderer-DaXQgGg3.mjs.map → renderer-DRal7Goa.mjs.map} +1 -1
- package/dist/renderer-DWgpivA3.mjs +5 -0
- package/dist/{renderer-Bo7shNdU.mjs → renderer-DXFJv_e6.mjs} +4 -4
- package/dist/{renderer-Bo7shNdU.mjs.map → renderer-DXFJv_e6.mjs.map} +1 -1
- package/dist/renderer-Dh_qNNwR.mjs +5 -0
- package/dist/renderer-DkCpXPMP.mjs +5 -0
- package/dist/{renderer-eMCTAa9e.mjs → renderer-Dp5ChuOs.mjs} +4 -4
- package/dist/{renderer-eMCTAa9e.mjs.map → renderer-Dp5ChuOs.mjs.map} +1 -1
- package/dist/{renderer-1uoKiILq.mjs → renderer-DpZballM.mjs} +3 -3
- package/dist/{renderer-1uoKiILq.mjs.map → renderer-DpZballM.mjs.map} +1 -1
- package/dist/renderer-Dre-6cDR.mjs +5 -0
- package/dist/renderer-Ds5z4_HX.mjs +5 -0
- package/dist/{renderer-7ow5Acsg.mjs → renderer-DwGlDNOV.mjs} +3 -3
- package/dist/{renderer-7ow5Acsg.mjs.map → renderer-DwGlDNOV.mjs.map} +1 -1
- package/dist/{renderer-q7q6k_cD.mjs → renderer-DxB_OfLs.mjs} +4 -4
- package/dist/{renderer-q7q6k_cD.mjs.map → renderer-DxB_OfLs.mjs.map} +1 -1
- package/dist/{renderer-DFJWPqOJ.mjs → renderer-Dz6P-rPI.mjs} +3 -3
- package/dist/{renderer-DFJWPqOJ.mjs.map → renderer-Dz6P-rPI.mjs.map} +1 -1
- package/dist/{renderer-BURhYcpA.mjs → renderer-FPiLBwj5.mjs} +4 -4
- package/dist/{renderer-BURhYcpA.mjs.map → renderer-FPiLBwj5.mjs.map} +1 -1
- package/dist/renderer-HGSCOMyP.mjs +5 -0
- package/dist/renderer-KMY8W-cJ.mjs +5 -0
- package/dist/{renderer-D-QVGphn.mjs → renderer-KgsVk9c6.mjs} +4 -4
- package/dist/{renderer-D-QVGphn.mjs.map → renderer-KgsVk9c6.mjs.map} +1 -1
- package/dist/{renderer-COcKhouz.mjs → renderer-LXhEPCmy.mjs} +5 -5
- package/dist/{renderer-COcKhouz.mjs.map → renderer-LXhEPCmy.mjs.map} +1 -1
- package/dist/{renderer-HDj9Zb-O.mjs → renderer-NBMmvqWl.mjs} +20 -7
- package/dist/renderer-NBMmvqWl.mjs.map +1 -0
- package/dist/{renderer-DE9Jik9K.mjs → renderer-Nnu32rqg.mjs} +3 -3
- package/dist/{renderer-DE9Jik9K.mjs.map → renderer-Nnu32rqg.mjs.map} +1 -1
- package/dist/renderer-R21YvXz3.mjs +5 -0
- package/dist/{renderer-celhuAL7.mjs → renderer-RAq3LnNy.mjs} +3 -3
- package/dist/{renderer-celhuAL7.mjs.map → renderer-RAq3LnNy.mjs.map} +1 -1
- package/dist/renderer-RtzCz37W.mjs +5 -0
- package/dist/{renderer-50JEMaVo.mjs → renderer-RzkU_O1i.mjs} +5 -5
- package/dist/{renderer-50JEMaVo.mjs.map → renderer-RzkU_O1i.mjs.map} +1 -1
- package/dist/{renderer-Bbxh4N8Y.mjs → renderer-S9tVGneU.mjs} +95 -80
- package/dist/renderer-S9tVGneU.mjs.map +1 -0
- package/dist/{renderer-BSELd5vU.mjs → renderer-SJyp9-62.mjs} +3 -3
- package/dist/{renderer-BSELd5vU.mjs.map → renderer-SJyp9-62.mjs.map} +1 -1
- package/dist/{renderer-jnAIhWn_.mjs → renderer-_54hiCq0.mjs} +5 -5
- package/dist/{renderer-jnAIhWn_.mjs.map → renderer-_54hiCq0.mjs.map} +1 -1
- package/dist/{renderer-88C3QpKL.d.mts → renderer-aRk849b3.d.mts} +2 -2
- package/dist/{renderer-88C3QpKL.d.mts.map → renderer-aRk849b3.d.mts.map} +1 -1
- package/dist/{renderer-BQetXCcZ.mjs → renderer-dGEMVaZ3.mjs} +4 -4
- package/dist/{renderer-BQetXCcZ.mjs.map → renderer-dGEMVaZ3.mjs.map} +1 -1
- package/dist/{renderer-RvI3qRUI.mjs → renderer-dRXP2dJU.mjs} +5 -5
- package/dist/{renderer-RvI3qRUI.mjs.map → renderer-dRXP2dJU.mjs.map} +1 -1
- package/dist/{renderer-D06HxSXO.mjs → renderer-g9SstkTz.mjs} +3 -3
- package/dist/renderer-iMrqAjix.mjs +5 -0
- package/dist/{renderer-BJ-7WRgO.mjs → renderer-opVuiAQR.mjs} +3 -3
- package/dist/{renderer-BJ-7WRgO.mjs.map → renderer-opVuiAQR.mjs.map} +1 -1
- package/dist/{renderer-KKk7myX1.mjs → renderer-puQhVfDS.mjs} +5 -5
- package/dist/{renderer-KKk7myX1.mjs.map → renderer-puQhVfDS.mjs.map} +1 -1
- package/dist/renderer-sMed1u1O.mjs +5 -0
- package/dist/renderer-tsAuo46l.mjs +5 -0
- package/dist/{renderer-TKZCA0B9.mjs → renderer-vll8LX0I.mjs} +211 -72
- package/dist/renderer-vll8LX0I.mjs.map +1 -0
- package/dist/{renderers-CP8CFWDs-DRoslK4F.mjs → renderers-CP8CFWDs-BRQyvcut.mjs} +4 -4
- package/dist/{renderers-CP8CFWDs-DRoslK4F.mjs.map → renderers-CP8CFWDs-BRQyvcut.mjs.map} +1 -1
- package/dist/sam/index.d.mts +3 -3
- package/dist/sam/index.mjs +1 -1
- package/dist/signals/index.d.mts +7 -7
- package/dist/signals/index.mjs +8 -8
- package/dist/{signals-BfJ1aqpT.mjs → signals-tiho_9fp.mjs} +4 -4
- package/dist/{signals-BfJ1aqpT.mjs.map → signals-tiho_9fp.mjs.map} +1 -1
- package/dist/{src-Bnr8DUC--BRDqRF6I.mjs → src-BU6vm9sP-DdTHmCr4.mjs} +76 -11
- package/dist/src-BU6vm9sP-DdTHmCr4.mjs.map +1 -0
- package/dist/{src-BYp6r-cS.mjs → src-BzFGotRc.mjs} +250 -30
- package/dist/src-BzFGotRc.mjs.map +1 -0
- package/dist/storage/index.d.mts +206 -0
- package/dist/storage/index.d.mts.map +1 -0
- package/dist/storage/index.mjs +3 -0
- package/package.json +67 -59
- package/dist/audio-CYZkDwae.d.mts.map +0 -1
- package/dist/cloud-xcfV4J03.mjs +0 -233
- package/dist/cloud-xcfV4J03.mjs.map +0 -1
- package/dist/dist-CWLLnigL.mjs.map +0 -1
- package/dist/dist-CySGkG54.mjs.map +0 -1
- package/dist/dist-EQX3TUUl.mjs.map +0 -1
- package/dist/gpu-CpkJJLQP.mjs.map +0 -1
- package/dist/index-BuiZzc6i.d.mts.map +0 -1
- package/dist/index-CEU_Zsb9.d.mts.map +0 -1
- package/dist/index-CdCrae-I.d.mts.map +0 -1
- package/dist/index-Cro-818i.d.mts.map +0 -1
- package/dist/index-D2i9J9Zq.d.mts.map +0 -1
- package/dist/index-gOVtTm-P.d.mts.map +0 -1
- package/dist/preview-BToKUTtZ.mjs.map +0 -1
- package/dist/preview-engine/chunk-4FY4TNST.mjs +0 -1
- package/dist/preview-engine/chunk-7LDSMOO3.mjs +0 -1
- package/dist/preview-engine/chunk-AGAZJZWI.mjs +0 -1
- package/dist/preview-engine/chunk-BXPM5SJ3.mjs +0 -1
- package/dist/preview-engine/chunk-C4M3B2Q2.mjs +0 -1
- package/dist/preview-engine/chunk-CIVJXFWH.mjs +0 -4
- package/dist/preview-engine/chunk-D73ZKPFN.mjs +0 -138
- package/dist/preview-engine/chunk-KOVN277Z.mjs +0 -1
- package/dist/preview-engine/chunk-M4QANUJI.mjs +0 -480
- package/dist/preview-engine/chunk-P4Y3PMJF.mjs +0 -1
- package/dist/preview-engine/chunk-SE2C623Z.mjs +0 -5
- package/dist/preview-engine/chunk-XF6DYP6B.mjs +0 -1974
- package/dist/preview-engine/chunk-XYGDTPO7.mjs +0 -39
- package/dist/preview-engine/chunk-YGKO4NIU.mjs +0 -1
- package/dist/preview-engine/renderers-2NGIILMI.mjs +0 -1
- package/dist/preview-engine/renderers-466Z77BH.mjs +0 -1
- package/dist/preview-engine/renderers-4KRENGZA.mjs +0 -1
- package/dist/preview-engine/renderers-4W52BQEU.mjs +0 -1
- package/dist/preview-engine/renderers-55PRAS7G.mjs +0 -1
- package/dist/preview-engine/renderers-5LLYINHW.mjs +0 -1
- package/dist/preview-engine/renderers-63N3Y2XO.mjs +0 -1
- package/dist/preview-engine/renderers-6ROVFDIN.mjs +0 -1
- package/dist/preview-engine/renderers-A4RVLPMG.mjs +0 -1
- package/dist/preview-engine/renderers-A53P4J6O.mjs +0 -1
- package/dist/preview-engine/renderers-AFJ3373L.mjs +0 -1
- package/dist/preview-engine/renderers-ATFWTA3U.mjs +0 -1
- package/dist/preview-engine/renderers-BPYJXHBU.mjs +0 -1
- package/dist/preview-engine/renderers-D3ZF7FXT.mjs +0 -1
- package/dist/preview-engine/renderers-D7YN6B4B.mjs +0 -1
- package/dist/preview-engine/renderers-DBLASKF5.mjs +0 -1
- package/dist/preview-engine/renderers-DC5ZYYHM.mjs +0 -1
- package/dist/preview-engine/renderers-J6ZEXW5L.mjs +0 -1
- package/dist/preview-engine/renderers-JV4MF46Q.mjs +0 -1
- package/dist/preview-engine/renderers-KQKH4ZIX.mjs +0 -1
- package/dist/preview-engine/renderers-MDHPQY6D.mjs +0 -1
- package/dist/preview-engine/renderers-MEITHN4N.mjs +0 -1
- package/dist/preview-engine/renderers-MN3HSBTJ.mjs +0 -1
- package/dist/preview-engine/renderers-NTG3QGNH.mjs +0 -1
- package/dist/preview-engine/renderers-OU4SFMB2.mjs +0 -1
- package/dist/preview-engine/renderers-P6TIBJIG.mjs +0 -1
- package/dist/preview-engine/renderers-POJWQ7L3.mjs +0 -1
- package/dist/preview-engine/renderers-RJ7S6VHD.mjs +0 -1
- package/dist/preview-engine/renderers-RJJAJZYN.mjs +0 -1
- package/dist/preview-engine/renderers-UEQ733VK.mjs +0 -1
- package/dist/preview-engine/renderers-ULO2AW2U.mjs +0 -1
- package/dist/preview-engine/renderers-UPVHGHCK.mjs +0 -1
- package/dist/preview-engine/renderers-UZHSNNIM.mjs +0 -1
- package/dist/preview-engine/renderers-V5KWZL2C.mjs +0 -1
- package/dist/preview-engine/renderers-WL372W36.mjs +0 -228
- package/dist/preview-engine/renderers-YMXKYOHQ.mjs +0 -1
- package/dist/preview-engine/renderers-YWDAZ2NZ.mjs +0 -1
- package/dist/program-Bc860ko5.mjs.map +0 -1
- package/dist/renderer--Ymc_4XJ.mjs +0 -5
- package/dist/renderer-B-OdV-eq.mjs +0 -5
- package/dist/renderer-B65fwoA2.mjs +0 -5
- package/dist/renderer-B92Ahkcv.mjs +0 -5
- package/dist/renderer-B9z2AK31.mjs +0 -5
- package/dist/renderer-BIF3Dg3Z.mjs +0 -5
- package/dist/renderer-BJUVaIAT.mjs +0 -5
- package/dist/renderer-BKRDMbI-.mjs +0 -5
- package/dist/renderer-BSwhyVWa.mjs +0 -5
- package/dist/renderer-BUqSZn2X.mjs +0 -5
- package/dist/renderer-BVKOQarx.d.mts +0 -99
- package/dist/renderer-BVKOQarx.d.mts.map +0 -1
- package/dist/renderer-BbmvjqK9.mjs +0 -3
- package/dist/renderer-Bbxh4N8Y.mjs.map +0 -1
- package/dist/renderer-BhsrlGKp.mjs.map +0 -1
- package/dist/renderer-Bpe4k_x6.mjs +0 -5
- package/dist/renderer-Bx14Wnxl.mjs.map +0 -1
- package/dist/renderer-C1NjG0CJ.mjs +0 -5
- package/dist/renderer-C7Puyst9.mjs +0 -5
- package/dist/renderer-CGA_7320.mjs +0 -5
- package/dist/renderer-CLnFkXO7.mjs +0 -5
- package/dist/renderer-CMQIT1Kh.mjs +0 -5
- package/dist/renderer-CQ1rwjIh.mjs +0 -5
- package/dist/renderer-CT8h0boY.mjs +0 -5
- package/dist/renderer-Cb0lszt3.mjs +0 -5
- package/dist/renderer-Ci7oLye9.mjs +0 -5
- package/dist/renderer-CjqXB3CZ.mjs +0 -5
- package/dist/renderer-CqTV04zQ.mjs +0 -5
- package/dist/renderer-CtWeRtHK.mjs +0 -5
- package/dist/renderer-CzolnwCo.mjs +0 -5
- package/dist/renderer-D6qhcx_C.mjs +0 -5
- package/dist/renderer-DDfEf0jt.mjs +0 -5
- package/dist/renderer-DDpa8ztp.mjs +0 -5
- package/dist/renderer-DbQBqzmx.mjs +0 -5
- package/dist/renderer-DfUcwMKa.mjs +0 -5
- package/dist/renderer-DgIjNANM.mjs +0 -6
- package/dist/renderer-Dsh6Tgu0.mjs +0 -3
- package/dist/renderer-DuIwR9GT.mjs +0 -5
- package/dist/renderer-Dv4u2c14.mjs +0 -5
- package/dist/renderer-HDj9Zb-O.mjs.map +0 -1
- package/dist/renderer-IE1yu3lZ.mjs +0 -5
- package/dist/renderer-PY_wnEN0.mjs +0 -5
- package/dist/renderer-TKZCA0B9.mjs.map +0 -1
- package/dist/renderer-gv24VyzO.mjs +0 -5
- package/dist/renderer-nN6lPZf9.mjs +0 -5
- package/dist/src-BYp6r-cS.mjs.map +0 -1
- package/dist/src-Bnr8DUC--BRDqRF6I.mjs.map +0 -1
- /package/dist/{chunk-W71TSjRM.mjs → chunk-DOL2i2sR.mjs} +0 -0
- /package/dist/{renderer-B6rZUBwE.mjs → renderer-Co2YqWX0.mjs} +0 -0
|
@@ -0,0 +1,685 @@
|
|
|
1
|
+
import { _ as parseStorage, c as credentialEnvNames, f as hashFile, g as parseAssets, l as credentialsFromEnv, n as Bucket, p as isAssetPath, u as downloadVerified, v as pickRemote, x as readUrl } from "./dist-CiTgmfUw.mjs";
|
|
2
|
+
import { appendFileSync, createWriteStream, existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "node:fs";
|
|
3
|
+
import path, { join, relative, resolve, sep } from "node:path";
|
|
4
|
+
import fs$1 from "node:fs/promises";
|
|
5
|
+
import { execFileSync } from "node:child_process";
|
|
6
|
+
import { Readable } from "node:stream";
|
|
7
|
+
import { pipeline } from "node:stream/promises";
|
|
8
|
+
|
|
9
|
+
//#region src/cli/config.ts
|
|
10
|
+
/**
|
|
11
|
+
* `framefields.json` at the project root: where installed components live,
|
|
12
|
+
* which fonts `framefields add` / `framefields fonts add` installed, and the
|
|
13
|
+
* project's named renders.
|
|
14
|
+
*
|
|
15
|
+
* ```json
|
|
16
|
+
* {
|
|
17
|
+
* "components": "src/components",
|
|
18
|
+
* "renders": {
|
|
19
|
+
* "film": {
|
|
20
|
+
* "title": "Launch film",
|
|
21
|
+
* "entry": "src/film.ts",
|
|
22
|
+
* "export": "buildFilm",
|
|
23
|
+
* "workers": "auto"
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* A named render is what `framefields render film --cloud`, `framefields
|
|
30
|
+
* check film`, `renderCloud({ render: "film" })` and the dashboard's New
|
|
31
|
+
* render dialog pick, so nobody chooses files and exports by hand.
|
|
32
|
+
*
|
|
33
|
+
* `storage` and `assets` pin media by content on an S3-compatible bucket
|
|
34
|
+
* (`framefields assets`; the format lives in `@framefields/storage`).
|
|
35
|
+
*/
|
|
36
|
+
const CONFIG_FILE = "framefields.json";
|
|
37
|
+
const RENDER_NAME = /^[A-Za-z0-9][\w.-]{0,63}$/;
|
|
38
|
+
const IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
|
|
39
|
+
const QUALITIES = [
|
|
40
|
+
"very_low",
|
|
41
|
+
"low",
|
|
42
|
+
"high",
|
|
43
|
+
"very_high"
|
|
44
|
+
];
|
|
45
|
+
/**
|
|
46
|
+
* The project's config, or the default it would get: `src/components` when
|
|
47
|
+
* there is a `src`. `saved` is whether the file records a components folder.
|
|
48
|
+
*/
|
|
49
|
+
function readConfig(cwd) {
|
|
50
|
+
const file = join(cwd, CONFIG_FILE);
|
|
51
|
+
const fallback = existsSync(join(cwd, "src")) ? "src/components" : "components";
|
|
52
|
+
if (!existsSync(file)) return {
|
|
53
|
+
config: { components: fallback },
|
|
54
|
+
saved: false
|
|
55
|
+
};
|
|
56
|
+
let raw;
|
|
57
|
+
try {
|
|
58
|
+
raw = JSON.parse(readFileSync(file, "utf8"));
|
|
59
|
+
} catch (err) {
|
|
60
|
+
throw new Error(`${CONFIG_FILE} is not valid JSON: ${err.message}`);
|
|
61
|
+
}
|
|
62
|
+
if (!isRecord(raw)) throw new Error(`${CONFIG_FILE} must be a JSON object`);
|
|
63
|
+
const { components, fonts, renders, storage, assets } = raw;
|
|
64
|
+
if (components !== void 0 && typeof components !== "string") throw new Error(`${CONFIG_FILE}: "components" must be a directory path`);
|
|
65
|
+
if (fonts !== void 0 && (!isRecord(fonts) || Object.values(fonts).some((v) => typeof v !== "string"))) throw new Error(`${CONFIG_FILE}: "fonts" must map roles to font file paths, e.g. { "emoji": "assets/fonts/NotoColorEmoji.ttf" }`);
|
|
66
|
+
const parsedStorage = storage === void 0 ? void 0 : parseStorage(storage);
|
|
67
|
+
return {
|
|
68
|
+
config: {
|
|
69
|
+
...raw,
|
|
70
|
+
components: components ?? fallback,
|
|
71
|
+
...renders !== void 0 && { renders: parseRenders(renders) },
|
|
72
|
+
...parsedStorage && { storage: parsedStorage },
|
|
73
|
+
...assets !== void 0 && { assets: parseAssets(assets, parsedStorage) }
|
|
74
|
+
},
|
|
75
|
+
saved: components !== void 0
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function writeConfig(cwd, config) {
|
|
79
|
+
writeFileSync(join(cwd, CONFIG_FILE), `${JSON.stringify(config, null, " ")}\n`);
|
|
80
|
+
}
|
|
81
|
+
/** Validates the `renders` map; errors name the render and field at fault. */
|
|
82
|
+
function parseRenders(value) {
|
|
83
|
+
if (!isRecord(value)) throw new Error(`${CONFIG_FILE}: "renders" must map names to renders, e.g. { "film": { "entry": "src/film.ts" } }`);
|
|
84
|
+
const out = {};
|
|
85
|
+
for (const [name, spec] of Object.entries(value)) {
|
|
86
|
+
const fail = (message) => {
|
|
87
|
+
throw new Error(`${CONFIG_FILE}: renders.${name} ${message}`);
|
|
88
|
+
};
|
|
89
|
+
if (!RENDER_NAME.test(name)) fail("has an invalid name: use letters, digits, -, _ and . (at most 64)");
|
|
90
|
+
if (!isRecord(spec)) fail("must be an object with an entry");
|
|
91
|
+
const s = spec;
|
|
92
|
+
if (!isRelativePath(s.entry)) fail("needs \"entry\": the module path inside the project, e.g. \"src/film.ts\"");
|
|
93
|
+
if (s.export !== void 0 && !(typeof s.export === "string" && IDENTIFIER.test(s.export))) fail("\"export\" must be a JavaScript identifier");
|
|
94
|
+
for (const key of [
|
|
95
|
+
"title",
|
|
96
|
+
"description",
|
|
97
|
+
"select"
|
|
98
|
+
]) if (s[key] !== void 0 && typeof s[key] !== "string") fail(`"${key}" must be a string`);
|
|
99
|
+
if (s.workers !== void 0 && s.workers !== "auto" && !isCount(s.workers)) fail("\"workers\" must be \"auto\" or a positive whole number");
|
|
100
|
+
if (s.maxWorkers !== void 0 && !isCount(s.maxWorkers)) fail("\"maxWorkers\" must be a positive whole number");
|
|
101
|
+
if (s.codec !== void 0 && s.codec !== "h264" && s.codec !== "vp9") fail("\"codec\" must be \"h264\" or \"vp9\"");
|
|
102
|
+
if (s.quality !== void 0 && !QUALITIES.includes(s.quality)) fail(`"quality" must be one of ${QUALITIES.join(", ")}`);
|
|
103
|
+
if (s.output !== void 0 && typeof s.output !== "string") fail("\"output\" must be a file path");
|
|
104
|
+
out[name] = s;
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The named render `name` of the project at `cwd`, or undefined when there
|
|
110
|
+
* is no render by that name (an entry path, say).
|
|
111
|
+
*/
|
|
112
|
+
function findRender(cwd, name) {
|
|
113
|
+
const spec = readConfig(cwd).config.renders?.[name];
|
|
114
|
+
return spec && {
|
|
115
|
+
...spec,
|
|
116
|
+
name
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function isRecord(value) {
|
|
120
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
121
|
+
}
|
|
122
|
+
function isCount(value) {
|
|
123
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 1;
|
|
124
|
+
}
|
|
125
|
+
function isRelativePath(value) {
|
|
126
|
+
return typeof value === "string" && value.length > 0 && !value.startsWith("/") && !value.split(/[/\\]/).includes("..");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region src/cli/assets.ts
|
|
131
|
+
/**
|
|
132
|
+
* `framefields assets`: media kept out of git, on an S3-compatible bucket
|
|
133
|
+
* (R2, S3, B2, MinIO), pinned by content in `framefields.json`.
|
|
134
|
+
*
|
|
135
|
+
* add <path...> hash, upload what the bucket lacks, record, gitignore
|
|
136
|
+
* push upload recorded assets the bucket lacks
|
|
137
|
+
* pull download missing assets, verified byte for byte
|
|
138
|
+
* status which assets are here, missing, or changed
|
|
139
|
+
*
|
|
140
|
+
* Reads need no keys when the remote has a `publicUrl` (a custom domain or
|
|
141
|
+
* CDN in front of the bucket); otherwise they're signed with the remote's
|
|
142
|
+
* keys. Cloud renders get signed URLs for private assets from the CLI, so
|
|
143
|
+
* the keys never leave the machine.
|
|
144
|
+
*/
|
|
145
|
+
var AssetsError = class extends Error {
|
|
146
|
+
name = "AssetsError";
|
|
147
|
+
constructor(message, code) {
|
|
148
|
+
super(message);
|
|
149
|
+
this.code = code;
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
/** Hashes and uploads files (folders: every file in them), and records them. */
|
|
153
|
+
async function addAssets(paths, options) {
|
|
154
|
+
const { cwd } = options;
|
|
155
|
+
const { config } = readConfig(cwd);
|
|
156
|
+
const { name, remote } = pickRemote(config.storage, options.remote);
|
|
157
|
+
const bucket = openBucket(config.storage, name, options);
|
|
158
|
+
const files = paths.flatMap((p) => expand(cwd, p));
|
|
159
|
+
if (files.length === 0) throw new AssetsError(`No files in ${paths.join(", ")}.`, "not_found");
|
|
160
|
+
const added = [];
|
|
161
|
+
const assets = { ...config.assets };
|
|
162
|
+
for (const file of files) {
|
|
163
|
+
const digest = await hashFile(join(cwd, file));
|
|
164
|
+
const uploaded = !await bucket.has(digest.sha256, digest.size);
|
|
165
|
+
if (uploaded) await upload(bucket, cwd, file, digest, options.log);
|
|
166
|
+
const isDefault = name === pickRemote(config.storage).name;
|
|
167
|
+
assets[file] = {
|
|
168
|
+
...digest,
|
|
169
|
+
...!isDefault && { remote: name }
|
|
170
|
+
};
|
|
171
|
+
added.push({
|
|
172
|
+
path: file,
|
|
173
|
+
size: digest.size,
|
|
174
|
+
uploaded
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
writeConfig(cwd, {
|
|
178
|
+
...config,
|
|
179
|
+
assets: sortKeys(assets)
|
|
180
|
+
});
|
|
181
|
+
ignore(cwd, files);
|
|
182
|
+
const tracked = trackedByGit(cwd, files);
|
|
183
|
+
if (tracked.length) options.log?.(`Already committed to git: ${tracked.join(", ")}. Stop tracking them with \`git rm --cached ${tracked.join(" ")}\` (the files stay here).`);
|
|
184
|
+
if (remote.publicUrl === void 0) options.log?.(`${name} has no publicUrl: cloud renders from the CLI sign reads, dashboard renders can't read it.`);
|
|
185
|
+
return added;
|
|
186
|
+
}
|
|
187
|
+
/** Uploads every recorded asset its bucket lacks, from the local file. */
|
|
188
|
+
async function pushAssets(options) {
|
|
189
|
+
const { config } = readConfig(options.cwd);
|
|
190
|
+
const uploaded = [];
|
|
191
|
+
const present = [];
|
|
192
|
+
const problems = [];
|
|
193
|
+
for (const [path$1, entry] of storedAssets(config.assets)) {
|
|
194
|
+
const bucket = openBucket(config.storage, entry.remote, options);
|
|
195
|
+
if (await bucket.has(entry.sha256, entry.size)) {
|
|
196
|
+
present.push(path$1);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const state = await localState(options.cwd, path$1, entry);
|
|
200
|
+
if (state !== "ok") {
|
|
201
|
+
problems.push(`${path$1} (${state} here)`);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
await upload(bucket, options.cwd, path$1, entry, options.log);
|
|
205
|
+
uploaded.push(path$1);
|
|
206
|
+
}
|
|
207
|
+
if (problems.length) throw new AssetsError(`Not on the bucket, and the local file doesn't match ${CONFIG_FILE}: ${problems.join(", ")}. Restore the file, or record the new version with \`framefields assets add\`.`, "not_uploaded");
|
|
208
|
+
return {
|
|
209
|
+
uploaded,
|
|
210
|
+
present
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Downloads every asset that's missing here. Files changed locally are
|
|
215
|
+
* left alone (and reported) unless `overwrite`.
|
|
216
|
+
*/
|
|
217
|
+
async function pullAssets(options) {
|
|
218
|
+
const { config } = readConfig(options.cwd);
|
|
219
|
+
const result = {
|
|
220
|
+
downloaded: [],
|
|
221
|
+
present: [],
|
|
222
|
+
changed: []
|
|
223
|
+
};
|
|
224
|
+
for (const [path$1, entry] of Object.entries(config.assets ?? {})) {
|
|
225
|
+
const state = await localState(options.cwd, path$1, entry);
|
|
226
|
+
if (state === "ok") {
|
|
227
|
+
result.present.push(path$1);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
if (state === "changed" && !options.overwrite) {
|
|
231
|
+
result.changed.push(path$1);
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const url = await readableUrl(entry, config.storage, options);
|
|
235
|
+
options.log?.(`Downloading ${path$1} (${megabytes(entry.size)})`);
|
|
236
|
+
await downloadVerified(url, join(options.cwd, path$1), entry, {
|
|
237
|
+
fetch: options.fetch,
|
|
238
|
+
signal: options.signal
|
|
239
|
+
});
|
|
240
|
+
result.downloaded.push(path$1);
|
|
241
|
+
}
|
|
242
|
+
return result;
|
|
243
|
+
}
|
|
244
|
+
/** Each recorded asset's state here: present and matching, missing, or changed. */
|
|
245
|
+
async function assetStatus(cwd) {
|
|
246
|
+
const { config } = readConfig(cwd);
|
|
247
|
+
return Promise.all(Object.entries(config.assets ?? {}).map(async ([path$1, entry]) => ({
|
|
248
|
+
path: path$1,
|
|
249
|
+
size: entry.size,
|
|
250
|
+
state: await localState(cwd, path$1, entry)
|
|
251
|
+
})));
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Before a cloud render: uploads assets the bucket lacks (when there are
|
|
255
|
+
* keys), checks public ones are reachable, and signs reads of private ones.
|
|
256
|
+
* Returns the signed URLs by sha256, for the render request.
|
|
257
|
+
*/
|
|
258
|
+
async function prepareCloudAssets(options) {
|
|
259
|
+
const { config } = readConfig(options.cwd);
|
|
260
|
+
const signed = {};
|
|
261
|
+
const missing = [];
|
|
262
|
+
for (const [path$1, entry] of storedAssets(config.assets)) {
|
|
263
|
+
const { name, remote } = pickRemote(config.storage, entry.remote);
|
|
264
|
+
const keys = credentialsFromEnv(name, options.env);
|
|
265
|
+
if (!keys) {
|
|
266
|
+
if (!remote.publicUrl) throw noCredentials(name, path$1);
|
|
267
|
+
if (!await reachable(readUrl(entry, config.storage), options.fetch)) missing.push(path$1);
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
const bucket = new Bucket(remote, keys, { fetch: options.fetch });
|
|
271
|
+
if (!await bucket.has(entry.sha256, entry.size)) {
|
|
272
|
+
if (await localState(options.cwd, path$1, entry) !== "ok") {
|
|
273
|
+
missing.push(path$1);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
await upload(bucket, options.cwd, path$1, entry, options.log);
|
|
277
|
+
}
|
|
278
|
+
if (!remote.publicUrl) signed[entry.sha256] = await bucket.presign(entry.sha256, options.expiresSec ?? 86400);
|
|
279
|
+
}
|
|
280
|
+
if (missing.length) throw new AssetsError(`Not on the bucket: ${missing.join(", ")}. Run \`framefields assets push\` from a machine that has them (and the remote's keys).`, "not_uploaded");
|
|
281
|
+
return signed;
|
|
282
|
+
}
|
|
283
|
+
/** Assets kept on a remote (not pinned to a fixed `url`). */
|
|
284
|
+
function storedAssets(assets) {
|
|
285
|
+
return Object.entries(assets ?? {}).filter(([, entry]) => !entry.url);
|
|
286
|
+
}
|
|
287
|
+
async function localState(cwd, path$1, entry) {
|
|
288
|
+
const file = join(cwd, path$1);
|
|
289
|
+
if (!existsSync(file)) return "missing";
|
|
290
|
+
if (statSync(file).size !== entry.size) return "changed";
|
|
291
|
+
return (await hashFile(file)).sha256 === entry.sha256 ? "ok" : "changed";
|
|
292
|
+
}
|
|
293
|
+
async function readableUrl(entry, storage, options) {
|
|
294
|
+
const url = readUrl(entry, storage);
|
|
295
|
+
if (url) return url;
|
|
296
|
+
return openBucket(storage, entry.remote, options).presign(entry.sha256, 3600);
|
|
297
|
+
}
|
|
298
|
+
function openBucket(storage, remoteName, options) {
|
|
299
|
+
const { name, remote } = pickRemote(storage, remoteName);
|
|
300
|
+
const keys = credentialsFromEnv(name, options.env);
|
|
301
|
+
if (!keys) throw noCredentials(name);
|
|
302
|
+
return new Bucket(remote, keys, { fetch: options.fetch });
|
|
303
|
+
}
|
|
304
|
+
function noCredentials(remote, path$1) {
|
|
305
|
+
const [id, secret] = credentialEnvNames(remote);
|
|
306
|
+
return new AssetsError(`${path$1 ? `${path$1} is on ${remote}, which` : `Remote ${remote}`} needs keys: set ${id} and ${secret} (or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY)${path$1 ? ", or give it a publicUrl" : ""}.`, "no_credentials");
|
|
307
|
+
}
|
|
308
|
+
async function upload(bucket, cwd, path$1, digest, log) {
|
|
309
|
+
log?.(`Uploading ${path$1} (${megabytes(digest.size)})`);
|
|
310
|
+
let shown = 0;
|
|
311
|
+
await bucket.upload(join(cwd, path$1), digest, ({ sent, total }) => {
|
|
312
|
+
const percent = Math.floor(sent / total * 10) * 10;
|
|
313
|
+
if (total > 64e6 && percent > shown && percent < 100) {
|
|
314
|
+
shown = percent;
|
|
315
|
+
log?.(` ${percent}%`);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
async function reachable(url, fetchImpl = fetch) {
|
|
320
|
+
return (await fetchImpl(url, { method: "HEAD" }).catch(() => void 0))?.ok ?? false;
|
|
321
|
+
}
|
|
322
|
+
/** Project-relative POSIX paths of `path`, or of every file under it. */
|
|
323
|
+
function expand(cwd, path$1) {
|
|
324
|
+
const abs = resolve(cwd, path$1);
|
|
325
|
+
const rel = relative(cwd, abs).split(sep).join("/");
|
|
326
|
+
if (!isAssetPath(rel) || rel.startsWith("../")) throw new AssetsError(`${path$1} is outside the project.`, "outside_project");
|
|
327
|
+
if (!existsSync(abs)) throw new AssetsError(`${path$1} does not exist.`, "not_found");
|
|
328
|
+
if (!statSync(abs).isDirectory()) return [rel];
|
|
329
|
+
return readdirSync(abs, { withFileTypes: true }).filter((d) => !d.name.startsWith(".")).flatMap((d) => expand(cwd, `${rel}/${d.name}`)).sort();
|
|
330
|
+
}
|
|
331
|
+
const IGNORE_HEADER = "# framefields assets: on the bucket, pinned in framefields.json";
|
|
332
|
+
/** Adds the files to .gitignore, under one marked block. */
|
|
333
|
+
function ignore(cwd, files) {
|
|
334
|
+
const file = join(cwd, ".gitignore");
|
|
335
|
+
const text = existsSync(file) ? readFileSync(file, "utf8") : "";
|
|
336
|
+
const lines = new Set(text.split("\n"));
|
|
337
|
+
const fresh = files.map((f) => `/${f}`).filter((l) => !lines.has(l));
|
|
338
|
+
if (fresh.length === 0) return;
|
|
339
|
+
const header = lines.has(IGNORE_HEADER) ? [] : [IGNORE_HEADER];
|
|
340
|
+
appendFileSync(file, `${text && !text.endsWith("\n") ? "\n" : ""}${[...header, ...fresh].join("\n")}\n`);
|
|
341
|
+
}
|
|
342
|
+
function trackedByGit(cwd, files) {
|
|
343
|
+
try {
|
|
344
|
+
return execFileSync("git", [
|
|
345
|
+
"ls-files",
|
|
346
|
+
"--",
|
|
347
|
+
...files
|
|
348
|
+
], {
|
|
349
|
+
cwd,
|
|
350
|
+
encoding: "utf8",
|
|
351
|
+
stdio: [
|
|
352
|
+
"ignore",
|
|
353
|
+
"pipe",
|
|
354
|
+
"ignore"
|
|
355
|
+
]
|
|
356
|
+
}).split("\n").filter(Boolean);
|
|
357
|
+
} catch {
|
|
358
|
+
return [];
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function sortKeys(assets) {
|
|
362
|
+
return Object.fromEntries(Object.entries(assets).sort(([a], [b]) => a.localeCompare(b)));
|
|
363
|
+
}
|
|
364
|
+
function megabytes(bytes) {
|
|
365
|
+
return `${(bytes / 1e6).toFixed(bytes < 1e7 ? 1 : 0)} MB`;
|
|
366
|
+
}
|
|
367
|
+
const ASSETS_USAGE = `Usage: framefields assets add <path...> [--remote <name>]
|
|
368
|
+
framefields assets push | pull [--overwrite] | status [--json]
|
|
369
|
+
`;
|
|
370
|
+
/** The `framefields assets` command. */
|
|
371
|
+
async function runAssets([sub, ...paths], options) {
|
|
372
|
+
const log = options.log ?? (() => {});
|
|
373
|
+
if (sub === "add" && paths.length > 0) {
|
|
374
|
+
const added = await addAssets(paths, options);
|
|
375
|
+
const sent = added.filter((a) => a.uploaded).length;
|
|
376
|
+
log(`Recorded ${added.length} asset${added.length === 1 ? "" : "s"} in ${CONFIG_FILE} (${sent} uploaded, ${added.length - sent} already on the bucket). Commit ${CONFIG_FILE} and .gitignore.`);
|
|
377
|
+
return 0;
|
|
378
|
+
}
|
|
379
|
+
if (sub === "push") {
|
|
380
|
+
const { uploaded, present } = await pushAssets(options);
|
|
381
|
+
log(`Uploaded ${uploaded.length}; ${present.length} already on the bucket.`);
|
|
382
|
+
return 0;
|
|
383
|
+
}
|
|
384
|
+
if (sub === "pull") {
|
|
385
|
+
const { downloaded, present, changed } = await pullAssets(options);
|
|
386
|
+
log(`Downloaded ${downloaded.length}; ${present.length} already here.`);
|
|
387
|
+
if (changed.length) log(`Changed here, left alone: ${changed.join(", ")}. \`framefields assets add\` records them, --overwrite restores them.`);
|
|
388
|
+
return changed.length ? 1 : 0;
|
|
389
|
+
}
|
|
390
|
+
if (sub === "status") {
|
|
391
|
+
const entries = await assetStatus(options.cwd);
|
|
392
|
+
if (options.json) log(JSON.stringify({ assets: entries }));
|
|
393
|
+
else if (entries.length === 0) log(`No assets in ${CONFIG_FILE}.`);
|
|
394
|
+
else for (const e of entries) log(`${e.state.padEnd(8)} ${e.path} (${megabytes(e.size)})`);
|
|
395
|
+
return entries.some((e) => e.state !== "ok") ? 1 : 0;
|
|
396
|
+
}
|
|
397
|
+
process.stderr.write(ASSETS_USAGE);
|
|
398
|
+
return 2;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
//#endregion
|
|
402
|
+
//#region src/cloud/git-source.ts
|
|
403
|
+
/**
|
|
404
|
+
* Where a cloud render gets the project from: the git repo the working
|
|
405
|
+
* directory is in, at the commit checked out now. Cloud workers fetch from
|
|
406
|
+
* the remote, so that commit has to be pushed; uncommitted changes are not
|
|
407
|
+
* rendered.
|
|
408
|
+
*/
|
|
409
|
+
/** Reads repo, branch, commit and folder from git, and checks the commit is pushed. */
|
|
410
|
+
function resolveGitSource(cwd, entry) {
|
|
411
|
+
const git = (...args) => execFileSync("git", args, {
|
|
412
|
+
cwd,
|
|
413
|
+
encoding: "utf8",
|
|
414
|
+
stdio: [
|
|
415
|
+
"ignore",
|
|
416
|
+
"pipe",
|
|
417
|
+
"pipe"
|
|
418
|
+
]
|
|
419
|
+
}).trim();
|
|
420
|
+
let root;
|
|
421
|
+
try {
|
|
422
|
+
root = git("rev-parse", "--show-toplevel");
|
|
423
|
+
} catch {
|
|
424
|
+
throw new Error(`${cwd} is not in a git repository. Cloud renders fetch the project from git: commit it and push it to a remote first.`);
|
|
425
|
+
}
|
|
426
|
+
const workdir = path.relative(realpathSync(root), realpathSync(cwd)).split(path.sep).join("/") || ".";
|
|
427
|
+
const relEntry = path.relative(cwd, path.resolve(cwd, entry)).split(path.sep).join("/");
|
|
428
|
+
if (relEntry.startsWith("../") || path.isAbsolute(relEntry)) throw new Error(`${entry} is outside ${cwd}; run from the project folder that contains it.`);
|
|
429
|
+
const branch = git("rev-parse", "--abbrev-ref", "HEAD");
|
|
430
|
+
const commit = git("rev-parse", "HEAD");
|
|
431
|
+
const remoteName = upstreamRemote(git, branch) ?? "origin";
|
|
432
|
+
let remoteUrl;
|
|
433
|
+
try {
|
|
434
|
+
remoteUrl = git("remote", "get-url", remoteName);
|
|
435
|
+
} catch {
|
|
436
|
+
throw new Error(`The repository has no "${remoteName}" remote. Push the project to a git host first.`);
|
|
437
|
+
}
|
|
438
|
+
if (!git("branch", "-r", "--contains", commit)) throw new Error(`Commit ${commit.slice(0, 7)} is not on ${remoteName}. Push it first (\`git push\`): cloud workers fetch the project from the remote.`);
|
|
439
|
+
const dirty = git("status", "--porcelain", "--untracked-files=no", "--", ".");
|
|
440
|
+
return {
|
|
441
|
+
source: {
|
|
442
|
+
repo: toHttps(remoteUrl),
|
|
443
|
+
...branch !== "HEAD" && { ref: branch },
|
|
444
|
+
commit,
|
|
445
|
+
workdir
|
|
446
|
+
},
|
|
447
|
+
entry: relEntry,
|
|
448
|
+
warnings: dirty ? [`Uncommitted changes are not rendered: the cloud renders commit ${commit.slice(0, 7)}.`] : []
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
function upstreamRemote(git, branch) {
|
|
452
|
+
if (branch === "HEAD") return void 0;
|
|
453
|
+
try {
|
|
454
|
+
return git("config", `branch.${branch}.remote`) || void 0;
|
|
455
|
+
} catch {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
/** `git@github.com:acme/films.git` → `https://github.com/acme/films.git`; credentials dropped. */
|
|
460
|
+
function toHttps(url) {
|
|
461
|
+
const scp = /^[\w.-]+@([^:/]+):(.+)$/.exec(url);
|
|
462
|
+
if (scp) return `https://${scp[1]}/${scp[2]}`;
|
|
463
|
+
const parsed = URL.canParse(url) ? new URL(url) : void 0;
|
|
464
|
+
if (parsed && (parsed.protocol === "ssh:" || parsed.protocol === "git:")) return `https://${parsed.hostname}${parsed.pathname}`;
|
|
465
|
+
if (parsed?.protocol === "https:" || parsed?.protocol === "http:") {
|
|
466
|
+
parsed.username = "";
|
|
467
|
+
parsed.password = "";
|
|
468
|
+
return parsed.toString();
|
|
469
|
+
}
|
|
470
|
+
return url;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
//#endregion
|
|
474
|
+
//#region src/cloud/index.ts
|
|
475
|
+
/**
|
|
476
|
+
* Cloud renders on api.framefields.dev: the project renders from git on
|
|
477
|
+
* framefields' GPU workers, billed to the account that owns the API key.
|
|
478
|
+
*
|
|
479
|
+
* ```ts
|
|
480
|
+
* import { renderCloud } from "framefields/cloud";
|
|
481
|
+
*
|
|
482
|
+
* const result = await renderCloud({
|
|
483
|
+
* render: "film", // a render named in framefields.json
|
|
484
|
+
* outputPath: "output/film.mp4",
|
|
485
|
+
* onProgress: (s) => console.log(s.status, s.progress.frames),
|
|
486
|
+
* });
|
|
487
|
+
* ```
|
|
488
|
+
*
|
|
489
|
+
* Without a framefields.json, name the module instead: `entry: "src/film.ts"`
|
|
490
|
+
* (and `export`, `workers`, …). Options passed here override the named
|
|
491
|
+
* render's.
|
|
492
|
+
*
|
|
493
|
+
* `workers: "auto"` probes the film on one worker first, then splits it into
|
|
494
|
+
* as many chunks as stay efficient: short films stay on one worker, long ones
|
|
495
|
+
* spread out up to `maxWorkers`. `dryRun: true` returns that plan with the
|
|
496
|
+
* estimated cost and renders nothing. Aborting `signal` cancels the render;
|
|
497
|
+
* GPU time already used is charged.
|
|
498
|
+
*/
|
|
499
|
+
const FRAMEFIELDS_API_URL = "https://api.framefields.dev";
|
|
500
|
+
/** A cloud render that failed, was cancelled, or was refused by the API. */
|
|
501
|
+
var CloudRenderError = class extends Error {
|
|
502
|
+
constructor(message, code, status) {
|
|
503
|
+
super(message);
|
|
504
|
+
this.code = code;
|
|
505
|
+
this.status = status;
|
|
506
|
+
this.name = "CloudRenderError";
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
const DONE = new Set([
|
|
510
|
+
"planned",
|
|
511
|
+
"completed",
|
|
512
|
+
"failed",
|
|
513
|
+
"cancelled"
|
|
514
|
+
]);
|
|
515
|
+
/** Starts a cloud render and waits for it; resolves when it completed (or was planned). */
|
|
516
|
+
async function renderCloud(options) {
|
|
517
|
+
const api = cloudClient(options);
|
|
518
|
+
const cwd = options.cwd ?? process.cwd();
|
|
519
|
+
const o = withNamedRender(cwd, options);
|
|
520
|
+
const resolved = options.source ? {
|
|
521
|
+
source: options.source,
|
|
522
|
+
entry: o.entry,
|
|
523
|
+
warnings: []
|
|
524
|
+
} : resolveGitSource(cwd, o.entry);
|
|
525
|
+
const warn = options.onWarning ?? ((m) => process.stderr.write(`framefields: ${m}\n`));
|
|
526
|
+
for (const w of resolved.warnings) warn(w);
|
|
527
|
+
const assets = await cloudAssets(cwd, options);
|
|
528
|
+
let status = await api.start({
|
|
529
|
+
source: Object.keys(assets).length ? {
|
|
530
|
+
...resolved.source,
|
|
531
|
+
assets
|
|
532
|
+
} : resolved.source,
|
|
533
|
+
target: {
|
|
534
|
+
entry: resolved.entry,
|
|
535
|
+
export: o.export ?? "buildFilm",
|
|
536
|
+
...o.args !== void 0 && { args: o.args },
|
|
537
|
+
...o.select && { select: [o.select] }
|
|
538
|
+
},
|
|
539
|
+
render: {
|
|
540
|
+
codec: o.codec ?? "h264",
|
|
541
|
+
...o.quality && { quality: o.quality }
|
|
542
|
+
},
|
|
543
|
+
workers: o.workers ?? 1,
|
|
544
|
+
...o.maxWorkers && { max_workers: o.maxWorkers },
|
|
545
|
+
dry_run: options.dryRun ?? false,
|
|
546
|
+
...o.name && { name: o.name },
|
|
547
|
+
...o.title && { title: o.title }
|
|
548
|
+
});
|
|
549
|
+
options.onProgress?.(status);
|
|
550
|
+
try {
|
|
551
|
+
while (!DONE.has(status.status)) {
|
|
552
|
+
await sleep(options.pollMs ?? 3e3, options.signal);
|
|
553
|
+
status = await api.status(status.id);
|
|
554
|
+
options.onProgress?.(status);
|
|
555
|
+
}
|
|
556
|
+
} catch (err) {
|
|
557
|
+
if (options.signal?.aborted) throw new CloudRenderError("The cloud render was cancelled.", "cancelled", await api.cancel(status.id).catch(() => status));
|
|
558
|
+
throw err;
|
|
559
|
+
}
|
|
560
|
+
if (status.status === "failed" || status.status === "cancelled") throw new CloudRenderError(status.error ? `Cloud render ${status.status}: ${status.error.message} (${status.error.code})` : `Cloud render ${status.status}.`, status.error?.code ?? status.status, status);
|
|
561
|
+
if (status.status === "completed" && options.outputPath && status.output) {
|
|
562
|
+
await download(status.output.url, options.outputPath, options.signal);
|
|
563
|
+
return {
|
|
564
|
+
...status,
|
|
565
|
+
filePath: options.outputPath
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
return status;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Uploads assets the bucket lacks and signs reads of private ones: the
|
|
572
|
+
* workers download each asset framefields.json pins at the commit.
|
|
573
|
+
*/
|
|
574
|
+
async function cloudAssets(cwd, options) {
|
|
575
|
+
try {
|
|
576
|
+
return await prepareCloudAssets({
|
|
577
|
+
cwd,
|
|
578
|
+
signal: options.signal,
|
|
579
|
+
log: options.onLog ?? ((m) => process.stderr.write(`framefields: ${m}\n`))
|
|
580
|
+
});
|
|
581
|
+
} catch (err) {
|
|
582
|
+
if (err instanceof AssetsError) throw new CloudRenderError(err.message, `assets_${err.code}`);
|
|
583
|
+
throw err;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* The options with a named render's fields filled in where the caller left
|
|
588
|
+
* them out, plus the name and title the dashboard shows.
|
|
589
|
+
*/
|
|
590
|
+
function withNamedRender(cwd, options) {
|
|
591
|
+
if (!options.render) {
|
|
592
|
+
if (!options.entry) throw new CloudRenderError("Name a render from framefields.json (render) or a module (entry).", "invalid_request");
|
|
593
|
+
return {
|
|
594
|
+
...options,
|
|
595
|
+
entry: options.entry
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
const spec = findRender(cwd, options.render);
|
|
599
|
+
if (!spec) {
|
|
600
|
+
const names = Object.keys(readConfig(cwd).config.renders ?? {});
|
|
601
|
+
throw new CloudRenderError(names.length ? `No render named "${options.render}" in ${CONFIG_FILE}. Renders: ${names.join(", ")}.` : `No render named "${options.render}": ${CONFIG_FILE} has no "renders".`, "render_not_found");
|
|
602
|
+
}
|
|
603
|
+
const defined = Object.fromEntries(Object.entries(options).filter(([, v]) => v !== void 0));
|
|
604
|
+
return {
|
|
605
|
+
entry: spec.entry,
|
|
606
|
+
export: spec.export,
|
|
607
|
+
args: spec.args,
|
|
608
|
+
select: spec.select,
|
|
609
|
+
workers: spec.workers,
|
|
610
|
+
maxWorkers: spec.maxWorkers,
|
|
611
|
+
codec: spec.codec,
|
|
612
|
+
quality: spec.quality,
|
|
613
|
+
...defined,
|
|
614
|
+
name: spec.name,
|
|
615
|
+
title: spec.title ?? spec.name
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
/** The API calls behind `renderCloud`, for callers who track renders themselves. */
|
|
619
|
+
function cloudClient(options) {
|
|
620
|
+
const key = options.apiKey ?? process.env.FRAMEFIELDS_API_KEY;
|
|
621
|
+
if (!key) throw new CloudRenderError("No API key. Set FRAMEFIELDS_API_KEY (keys at https://framefields.dev/dashboard/keys) or pass apiKey.", "invalid_api_key");
|
|
622
|
+
const base = (options.apiUrl ?? process.env.FRAMEFIELDS_API_URL ?? FRAMEFIELDS_API_URL).replace(/\/+$/, "");
|
|
623
|
+
const call = async (method, route, body) => {
|
|
624
|
+
const res = await fetch(`${base}/v1/render${route}`, {
|
|
625
|
+
method,
|
|
626
|
+
headers: {
|
|
627
|
+
Authorization: `Bearer ${key}`,
|
|
628
|
+
"Content-Type": "application/json"
|
|
629
|
+
},
|
|
630
|
+
...body !== void 0 && { body: JSON.stringify(body) }
|
|
631
|
+
});
|
|
632
|
+
const json = await res.json().catch(() => ({}));
|
|
633
|
+
if (!res.ok) throw new CloudRenderError(json.error?.message ?? `api.framefields.dev answered HTTP ${res.status}`, json.error?.type ?? `http_${res.status}`);
|
|
634
|
+
return fromApi(json);
|
|
635
|
+
};
|
|
636
|
+
return {
|
|
637
|
+
start: (body) => call("POST", "", body),
|
|
638
|
+
status: (id) => call("GET", `/${encodeURIComponent(id)}`),
|
|
639
|
+
cancel: (id) => call("DELETE", `/${encodeURIComponent(id)}`)
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
function fromApi(s) {
|
|
643
|
+
return {
|
|
644
|
+
id: s.id,
|
|
645
|
+
status: s.status,
|
|
646
|
+
workers: s.workers ?? 1,
|
|
647
|
+
...s.plan && { plan: {
|
|
648
|
+
workers: s.plan.workers,
|
|
649
|
+
workSec: s.plan.work_sec,
|
|
650
|
+
etaSec: s.plan.eta_sec,
|
|
651
|
+
chunks: s.plan.chunks
|
|
652
|
+
} },
|
|
653
|
+
progress: {
|
|
654
|
+
frames: s.progress?.frames ?? 0,
|
|
655
|
+
totalFrames: s.progress?.total_frames ?? null,
|
|
656
|
+
etaSec: s.progress?.eta_sec ?? null
|
|
657
|
+
},
|
|
658
|
+
costUsd: s.cost_usd ?? 0,
|
|
659
|
+
gpuSeconds: s.gpu_seconds ?? 0,
|
|
660
|
+
...s.estimate_usd !== void 0 && { estimateUsd: s.estimate_usd },
|
|
661
|
+
...s.sha && { sha: s.sha },
|
|
662
|
+
...s.output && { output: s.output },
|
|
663
|
+
...s.error && { error: s.error }
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
async function download(url, file, signal) {
|
|
667
|
+
const res = await fetch(url, { signal });
|
|
668
|
+
if (!res.ok || !res.body) throw new CloudRenderError(`Downloading the render failed: HTTP ${res.status}`, "download_failed");
|
|
669
|
+
await fs$1.mkdir(path.dirname(path.resolve(file)), { recursive: true });
|
|
670
|
+
await pipeline(Readable.fromWeb(res.body), createWriteStream(file));
|
|
671
|
+
}
|
|
672
|
+
function sleep(ms, signal) {
|
|
673
|
+
return new Promise((resolve$1, reject) => {
|
|
674
|
+
if (signal?.aborted) return reject(signal.reason);
|
|
675
|
+
const timer = setTimeout(resolve$1, ms);
|
|
676
|
+
signal?.addEventListener("abort", () => {
|
|
677
|
+
clearTimeout(timer);
|
|
678
|
+
reject(signal.reason);
|
|
679
|
+
}, { once: true });
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
//#endregion
|
|
684
|
+
export { withNamedRender as a, AssetsError as c, runAssets as d, CONFIG_FILE as f, writeConfig as h, renderCloud as i, megabytes as l, readConfig as m, FRAMEFIELDS_API_URL as n, resolveGitSource as o, findRender as p, cloudClient as r, toHttps as s, CloudRenderError as t, pullAssets as u };
|
|
685
|
+
//# sourceMappingURL=cloud-Cj1TIme8.mjs.map
|