unspaghettit 0.2.0 → 0.4.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/README.md +56 -18
- package/build/client/_app/immutable/assets/0.DCOD5ne_.css +1 -0
- package/build/client/_app/immutable/assets/0.DCOD5ne_.css.br +0 -0
- package/build/client/_app/immutable/assets/0.DCOD5ne_.css.gz +0 -0
- package/build/client/_app/immutable/assets/12.nv0I59TU.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.B3akUL9A.css.gz +0 -0
- package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css +1 -0
- package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css.br +0 -0
- package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css.gz +0 -0
- package/build/client/_app/immutable/chunks/B3vnQs252.js +1 -0
- package/build/client/_app/immutable/chunks/B3vnQs252.js.br +0 -0
- package/build/client/_app/immutable/chunks/B3vnQs252.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CxyLMlpt2.js → BANF9BhQ2.js} +1 -1
- package/build/client/_app/immutable/chunks/BANF9BhQ2.js.br +0 -0
- package/build/client/_app/immutable/chunks/BANF9BhQ2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BJdTO_n6.js +1 -0
- package/build/client/_app/immutable/chunks/BJdTO_n6.js.br +0 -0
- package/build/client/_app/immutable/chunks/BJdTO_n6.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BPl9BITm.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BQ9GodWX2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bcyn5YUg.js +4 -0
- package/build/client/_app/immutable/chunks/Bcyn5YUg.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bcyn5YUg.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bfc9rQXP.js +1 -0
- package/build/client/_app/immutable/chunks/Bfc9rQXP.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bfc9rQXP.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BfMYiIUi.js → BjxqhpPG.js} +1 -1
- package/build/client/_app/immutable/chunks/BjxqhpPG.js.br +0 -0
- package/build/client/_app/immutable/chunks/BjxqhpPG.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ByaoVvNB.js +1 -0
- package/build/client/_app/immutable/chunks/ByaoVvNB.js.br +0 -0
- package/build/client/_app/immutable/chunks/ByaoVvNB.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BzLd0mTH.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C8b3IMj8.js +1 -0
- package/build/client/_app/immutable/chunks/C8b3IMj8.js.br +0 -0
- package/build/client/_app/immutable/chunks/C8b3IMj8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CXvvf4uQ.js +1 -0
- package/build/client/_app/immutable/chunks/CXvvf4uQ.js.br +0 -0
- package/build/client/_app/immutable/chunks/CXvvf4uQ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Cl7Z3e6-.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ClC4qR7W2.js +2 -0
- package/build/client/_app/immutable/chunks/ClC4qR7W2.js.br +0 -0
- package/build/client/_app/immutable/chunks/ClC4qR7W2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CuGlh1c2.js +1 -0
- package/build/client/_app/immutable/chunks/CuGlh1c2.js.br +0 -0
- package/build/client/_app/immutable/chunks/CuGlh1c2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CwzIdrQR.js +1 -0
- package/build/client/_app/immutable/chunks/CwzIdrQR.js.br +0 -0
- package/build/client/_app/immutable/chunks/CwzIdrQR.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D5speDV82.js +908 -0
- package/build/client/_app/immutable/chunks/D5speDV82.js.br +0 -0
- package/build/client/_app/immutable/chunks/D5speDV82.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D64sGJRN.js +1 -0
- package/build/client/_app/immutable/chunks/D64sGJRN.js.br +0 -0
- package/build/client/_app/immutable/chunks/D64sGJRN.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DNaA4QRO2.js +1 -0
- package/build/client/_app/immutable/chunks/DNaA4QRO2.js.br +0 -0
- package/build/client/_app/immutable/chunks/DNaA4QRO2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Da59TXPe.js +1 -0
- package/build/client/_app/immutable/chunks/Da59TXPe.js.br +2 -0
- package/build/client/_app/immutable/chunks/Da59TXPe.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DhTiE3j02.js +2 -0
- package/build/client/_app/immutable/chunks/DhTiE3j02.js.br +0 -0
- package/build/client/_app/immutable/chunks/DhTiE3j02.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dhqg7r_2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DmyaDy4d2.js +1 -0
- package/build/client/_app/immutable/chunks/DmyaDy4d2.js.br +0 -0
- package/build/client/_app/immutable/chunks/DmyaDy4d2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DryaQyjN2.js +1 -0
- package/build/client/_app/immutable/chunks/DryaQyjN2.js.br +0 -0
- package/build/client/_app/immutable/chunks/DryaQyjN2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DtK8qK5Q2.js +1 -0
- package/build/client/_app/immutable/chunks/DtK8qK5Q2.js.br +0 -0
- package/build/client/_app/immutable/chunks/DtK8qK5Q2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DtblIi6X2.js +1 -0
- package/build/client/_app/immutable/chunks/DtblIi6X2.js.br +1 -0
- package/build/client/_app/immutable/chunks/DtblIi6X2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/UkzDDeO42.js +1 -0
- package/build/client/_app/immutable/chunks/UkzDDeO42.js.br +0 -0
- package/build/client/_app/immutable/chunks/UkzDDeO42.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Vu8LzrwP2.js +1 -0
- package/build/client/_app/immutable/chunks/Vu8LzrwP2.js.br +0 -0
- package/build/client/_app/immutable/chunks/Vu8LzrwP2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/_b612aVb.js +1 -0
- package/build/client/_app/immutable/chunks/_b612aVb.js.br +0 -0
- package/build/client/_app/immutable/chunks/_b612aVb.js.gz +0 -0
- package/build/client/_app/immutable/chunks/aNMRV4sP2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/cMamJTsF.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ib21i2T_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/kNaey6uv.js.gz +0 -0
- package/build/client/_app/immutable/chunks/oVMDLirx.js +1 -0
- package/build/client/_app/immutable/chunks/oVMDLirx.js.br +0 -0
- package/build/client/_app/immutable/chunks/oVMDLirx.js.gz +0 -0
- package/build/client/_app/immutable/chunks/olAc024e.js +1 -0
- package/build/client/_app/immutable/chunks/olAc024e.js.br +0 -0
- package/build/client/_app/immutable/chunks/olAc024e.js.gz +0 -0
- package/build/client/_app/immutable/chunks/suTxxv1t.js.gz +0 -0
- package/build/client/_app/immutable/chunks/wXIHzLMQ2.js +1 -0
- package/build/client/_app/immutable/chunks/wXIHzLMQ2.js.br +0 -0
- package/build/client/_app/immutable/chunks/wXIHzLMQ2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/wrqalH0a.js +1 -0
- package/build/client/_app/immutable/chunks/wrqalH0a.js.br +0 -0
- package/build/client/_app/immutable/chunks/wrqalH0a.js.gz +0 -0
- package/build/client/_app/immutable/chunks/x60Tn5kT.js +1 -0
- package/build/client/_app/immutable/chunks/x60Tn5kT.js.br +0 -0
- package/build/client/_app/immutable/chunks/x60Tn5kT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/xihTtKlq.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BOrLmFwJ.js → yShDxCNj.js} +1 -1
- package/build/client/_app/immutable/chunks/yShDxCNj.js.br +2 -0
- package/build/client/_app/immutable/chunks/yShDxCNj.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.Etd-exTb.js +2 -0
- package/build/client/_app/immutable/entry/app.Etd-exTb.js.br +0 -0
- package/build/client/_app/immutable/entry/app.Etd-exTb.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.DY2B3u4g.js +1 -0
- package/build/client/_app/immutable/entry/start.DY2B3u4g.js.br +0 -0
- package/build/client/_app/immutable/entry/start.DY2B3u4g.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.tKfYV3__.js +8 -0
- package/build/client/_app/immutable/nodes/0.tKfYV3__.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.tKfYV3__.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.KYdA6ppX.js → 1.CER5ICKt.js} +1 -1
- package/build/client/_app/immutable/nodes/1.CER5ICKt.js.br +1 -0
- package/build/client/_app/immutable/nodes/1.CER5ICKt.js.gz +0 -0
- package/build/client/_app/immutable/nodes/10.rT7cD8kX.js +1 -0
- package/build/client/_app/immutable/nodes/10.rT7cD8kX.js.br +0 -0
- package/build/client/_app/immutable/nodes/10.rT7cD8kX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/11.BAnV_Y5Y.js +2 -0
- package/build/client/_app/immutable/nodes/11.BAnV_Y5Y.js.br +0 -0
- package/build/client/_app/immutable/nodes/11.BAnV_Y5Y.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{9.CMW6a2Lg.js → 12.DCTRFMqo.js} +4 -3
- package/build/client/_app/immutable/nodes/12.DCTRFMqo.js.br +0 -0
- package/build/client/_app/immutable/nodes/12.DCTRFMqo.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{2.DBz20KgG.js → 2.CF488WWF.js} +1 -1
- package/build/client/_app/immutable/nodes/2.CF488WWF.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CF488WWF.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.CP7CPPVH.js +1 -0
- package/build/client/_app/immutable/nodes/3.CP7CPPVH.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CP7CPPVH.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.D1bxCSiM.js +3 -0
- package/build/client/_app/immutable/nodes/4.D1bxCSiM.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.D1bxCSiM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.D6jZgh9y.js +48 -0
- package/build/client/_app/immutable/nodes/5.D6jZgh9y.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.D6jZgh9y.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.BrBFUA0s.js +1 -0
- package/build/client/_app/immutable/nodes/6.BrBFUA0s.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BrBFUA0s.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.pajo8MfM.js +3 -0
- package/build/client/_app/immutable/nodes/7.pajo8MfM.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.pajo8MfM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.Cc80_Igi.js +5 -0
- package/build/client/_app/immutable/nodes/8.Cc80_Igi.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.Cc80_Igi.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{7.CemgNJfw.js → 9.D72NaL3l.js} +1 -1
- package/build/client/_app/immutable/nodes/9.D72NaL3l.js.br +1 -0
- package/build/client/_app/immutable/nodes/9.D72NaL3l.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/client/lyriks_logo.svg +148 -0
- package/build/client/lyriks_logo.svg.br +0 -0
- package/build/client/lyriks_logo.svg.gz +0 -0
- package/build/server/chunks/0-8YZc572z.js +15 -0
- package/build/server/chunks/0-8YZc572z.js.map +1 -0
- package/build/server/chunks/1-DxkfSJLu.js +9 -0
- package/build/server/chunks/{1-DPpKAKXV.js.map → 1-DxkfSJLu.js.map} +1 -1
- package/build/server/chunks/10-DkObdGtU.js +9 -0
- package/build/server/chunks/10-DkObdGtU.js.map +1 -0
- package/build/server/chunks/11-DL94HxpZ.js +9 -0
- package/build/server/chunks/11-DL94HxpZ.js.map +1 -0
- package/build/server/chunks/12-CI74sCkt.js +9 -0
- package/build/server/chunks/12-CI74sCkt.js.map +1 -0
- package/build/server/chunks/2-qhWwQ4eL.js +9 -0
- package/build/server/chunks/2-qhWwQ4eL.js.map +1 -0
- package/build/server/chunks/3-CzoZtSTp.js +16 -0
- package/build/server/chunks/3-CzoZtSTp.js.map +1 -0
- package/build/server/chunks/4-CDa9DBsh.js +16 -0
- package/build/server/chunks/4-CDa9DBsh.js.map +1 -0
- package/build/server/chunks/5-qD2xxOrq.js +9 -0
- package/build/server/chunks/5-qD2xxOrq.js.map +1 -0
- package/build/server/chunks/6-B4mWzvDn.js +9 -0
- package/build/server/chunks/6-B4mWzvDn.js.map +1 -0
- package/build/server/chunks/7-zExv-fTN.js +9 -0
- package/build/server/chunks/7-zExv-fTN.js.map +1 -0
- package/build/server/chunks/8-BVrGdQg4.js +9 -0
- package/build/server/chunks/{6-QQ7r8Rd5.js.map → 8-BVrGdQg4.js.map} +1 -1
- package/build/server/chunks/9-BnZLRMYA.js +9 -0
- package/build/server/chunks/9-BnZLRMYA.js.map +1 -0
- package/build/server/chunks/BehaviorGraph-C-9z37Sm.js +788 -0
- package/build/server/chunks/BehaviorGraph-C-9z37Sm.js.map +1 -0
- package/build/server/chunks/Clock-BfMWQpmJ.js +5 -0
- package/build/server/chunks/Clock-BfMWQpmJ.js.map +1 -0
- package/build/server/chunks/DeleteDomain-BvHEgAyp.js +24 -0
- package/build/server/chunks/DeleteDomain-BvHEgAyp.js.map +1 -0
- package/build/server/chunks/{FeatureValidator-B8qEjAUW.js → DeleteFeature-DnK8sBJI.js} +142 -77
- package/build/server/chunks/DeleteFeature-DnK8sBJI.js.map +1 -0
- package/build/server/chunks/DeleteProject-BXZcehHZ.js +41 -0
- package/build/server/chunks/DeleteProject-BXZcehHZ.js.map +1 -0
- package/build/server/chunks/Effect-BJtLR-6l.js +46 -0
- package/build/server/chunks/Effect-BJtLR-6l.js.map +1 -0
- package/build/server/chunks/{FeatureCard-BQOY6gJQ.js → FeatureCard-Bb50FEfp.js} +4 -4
- package/build/server/chunks/{FeatureCard-BQOY6gJQ.js.map → FeatureCard-Bb50FEfp.js.map} +1 -1
- package/build/server/chunks/{FeatureJson-Bv-qiOSf.js → FeatureJson-DYvMEAub.js} +2 -2
- package/build/server/chunks/{FeatureJson-Bv-qiOSf.js.map → FeatureJson-DYvMEAub.js.map} +1 -1
- package/build/server/chunks/{FeatureTransforms-UWDHmWEg.js → FeatureTransforms-B0aI_CJD.js} +10 -3
- package/build/server/chunks/FeatureTransforms-B0aI_CJD.js.map +1 -0
- package/build/server/chunks/{ManageTagsDialog-DBxA3tM2.js → ManageTagsDialog-D5xbAVNB.js} +5 -5
- package/build/server/chunks/ManageTagsDialog-D5xbAVNB.js.map +1 -0
- package/build/server/chunks/{ProgressBar-CfhccQ83.js → ProgressBar-CUC2EZqG.js} +3 -3
- package/build/server/chunks/ProgressBar-CUC2EZqG.js.map +1 -0
- package/build/server/chunks/{ProjectsIndex-CoDrvRya.js → ProjectsIndex-FgIu9dBp.js} +135 -14
- package/build/server/chunks/ProjectsIndex-FgIu9dBp.js.map +1 -0
- package/build/server/chunks/{RenameTag-BuWLMl1m.js → RenameTag-DWIIR4Bx.js} +3 -6
- package/build/server/chunks/RenameTag-DWIIR4Bx.js.map +1 -0
- package/build/server/chunks/ScenarioApplier-YPKECfZe.js +55 -0
- package/build/server/chunks/ScenarioApplier-YPKECfZe.js.map +1 -0
- package/build/server/chunks/SimulatorEngine-DM1F9nCO.js +1391 -0
- package/build/server/chunks/SimulatorEngine-DM1F9nCO.js.map +1 -0
- package/build/server/chunks/StateValue-BBjWox8f.js +105 -0
- package/build/server/chunks/StateValue-BBjWox8f.js.map +1 -0
- package/build/server/chunks/{TagDotStrip-B1XQ0m0Y.js → TagDotStrip-0rn-IJVE.js} +4 -4
- package/build/server/chunks/TagDotStrip-0rn-IJVE.js.map +1 -0
- package/build/server/chunks/{TagFilterSelect-DbO0Qduh.js → TagFilterSelect-Dbu-7Dg4.js} +5 -5
- package/build/server/chunks/{TagFilterSelect-DbO0Qduh.js.map → TagFilterSelect-Dbu-7Dg4.js.map} +1 -1
- package/build/server/chunks/{TagPalette-CtMNYCmu.js → TagPalette-CpdTiC_7.js} +101 -9
- package/build/server/chunks/TagPalette-CpdTiC_7.js.map +1 -0
- package/build/server/chunks/TransitionCatalog-CYXUANy6.js +271 -0
- package/build/server/chunks/TransitionCatalog-CYXUANy6.js.map +1 -0
- package/build/server/chunks/_layout.svelte-pSSG85WT.js +1342 -0
- package/build/server/chunks/_layout.svelte-pSSG85WT.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BKTveFAj.js → _page.svelte-BNH3szkk.js} +22 -17
- package/build/server/chunks/{_page.svelte-BKTveFAj.js.map → _page.svelte-BNH3szkk.js.map} +1 -1
- package/build/server/chunks/_page.svelte-BcuGvUt1.js +37 -0
- package/build/server/chunks/{_page.svelte-B7hT3P8E.js.map → _page.svelte-BcuGvUt1.js.map} +1 -1
- package/build/server/chunks/_page.svelte-BoOMG5Y0.js +37 -0
- package/build/server/chunks/{_page.svelte-De508ek8.js.map → _page.svelte-BoOMG5Y0.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-BqSC-1vK.js → _page.svelte-C4PRh_wP.js} +104 -54
- package/build/server/chunks/_page.svelte-C4PRh_wP.js.map +1 -0
- package/build/server/chunks/_page.svelte-Cqn34NXy.js +74 -0
- package/build/server/chunks/_page.svelte-Cqn34NXy.js.map +1 -0
- package/build/server/chunks/{_page.svelte-B1s7jxaQ.js → _page.svelte-DSCeOGv7.js} +15 -10
- package/build/server/chunks/_page.svelte-DSCeOGv7.js.map +1 -0
- package/build/server/chunks/_page.svelte-DqWdGt48.js +182 -0
- package/build/server/chunks/_page.svelte-DqWdGt48.js.map +1 -0
- package/build/server/chunks/_page.svelte-DsQHSEl4.js +49 -0
- package/build/server/chunks/_page.svelte-DsQHSEl4.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BKKCa9H5.js → _page.svelte-Uioz8hsG.js} +18 -11
- package/build/server/chunks/{_page.svelte-BKKCa9H5.js.map → _page.svelte-Uioz8hsG.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-Zf9H4KOP.js → _page.svelte-p38jot9e.js} +81 -478
- package/build/server/chunks/_page.svelte-p38jot9e.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BtI2zZ_Z.js → _page.svelte-yN5kzgJ9.js} +251 -447
- package/build/server/chunks/_page.svelte-yN5kzgJ9.js.map +1 -0
- package/build/server/chunks/{_server.ts-DsbbVoOn.js → _server.ts-1CtrHhte.js} +4 -4
- package/build/server/chunks/{_server.ts-DsbbVoOn.js.map → _server.ts-1CtrHhte.js.map} +1 -1
- package/build/server/chunks/{_server.ts-CWvU15tL.js → _server.ts-71Qx1lQb.js} +4 -4
- package/build/server/chunks/{_server.ts-CWvU15tL.js.map → _server.ts-71Qx1lQb.js.map} +1 -1
- package/build/server/chunks/_server.ts-BAyekGHB.js +961 -0
- package/build/server/chunks/_server.ts-BAyekGHB.js.map +1 -0
- package/build/server/chunks/{_server.ts-BihpbxOW.js → _server.ts-BLWhU22T.js} +4 -4
- package/build/server/chunks/{_server.ts-BihpbxOW.js.map → _server.ts-BLWhU22T.js.map} +1 -1
- package/build/server/chunks/{_server.ts-YnfXkeMJ.js → _server.ts-C7EVZVxv.js} +22 -13
- package/build/server/chunks/_server.ts-C7EVZVxv.js.map +1 -0
- package/build/server/chunks/{_server.ts-vcaqdwxS.js → _server.ts-CGjYuLmo.js} +12 -7
- package/build/server/chunks/_server.ts-CGjYuLmo.js.map +1 -0
- package/build/server/chunks/{_server.ts-Dy5zQHe2.js → _server.ts-CX6H8fSE.js} +8 -31
- package/build/server/chunks/_server.ts-CX6H8fSE.js.map +1 -0
- package/build/server/chunks/{_server.ts-BuoQ02BW.js → _server.ts-CyEdTCLr.js} +4 -4
- package/build/server/chunks/{_server.ts-BuoQ02BW.js.map → _server.ts-CyEdTCLr.js.map} +1 -1
- package/build/server/chunks/_server.ts-DKVTM9Pj.js +77 -0
- package/build/server/chunks/_server.ts-DKVTM9Pj.js.map +1 -0
- package/build/server/chunks/{_server.ts-0uNTZKwF.js → _server.ts-Dip65hLJ.js} +15 -9
- package/build/server/chunks/_server.ts-Dip65hLJ.js.map +1 -0
- package/build/server/chunks/{_server.ts-D4EO0VHu.js → _server.ts-Dm0tCs2i.js} +5 -5
- package/build/server/chunks/{_server.ts-D4EO0VHu.js.map → _server.ts-Dm0tCs2i.js.map} +1 -1
- package/build/server/chunks/{_server.ts-BIBWjQI-.js → _server.ts-DsYwK_uW.js} +4 -4
- package/build/server/chunks/{_server.ts-BIBWjQI-.js.map → _server.ts-DsYwK_uW.js.map} +1 -1
- package/build/server/chunks/{_server.ts-DDa0Nk_S.js → _server.ts-RCEgegYU.js} +4 -4
- package/build/server/chunks/{_server.ts-DDa0Nk_S.js.map → _server.ts-RCEgegYU.js.map} +1 -1
- package/build/server/chunks/_server.ts-XOLAT4dd.js +146 -0
- package/build/server/chunks/_server.ts-XOLAT4dd.js.map +1 -0
- package/build/server/chunks/_server.ts-afh_zLVi.js +69 -0
- package/build/server/chunks/_server.ts-afh_zLVi.js.map +1 -0
- package/build/server/chunks/{browserContainer-CNX7ANld.js → browserContainer-BdldtueJ.js} +71 -1378
- package/build/server/chunks/browserContainer-BdldtueJ.js.map +1 -0
- package/build/server/chunks/buildSearchDocs-Cyfrnw9G.js +337 -0
- package/build/server/chunks/buildSearchDocs-Cyfrnw9G.js.map +1 -0
- package/build/server/chunks/{builderModeStore.svelte-ihupr-3p.js → builderModeStore.svelte-BEZMQEqn.js} +223 -11
- package/build/server/chunks/builderModeStore.svelte-BEZMQEqn.js.map +1 -0
- package/build/server/chunks/client-C9Cat4DK.js +51 -0
- package/build/server/chunks/{client-DfpLcAZ9.js.map → client-C9Cat4DK.js.map} +1 -1
- package/build/server/chunks/{error.svelte-C35KOpru.js → error.svelte-CzVR_A6P.js} +5 -5
- package/build/server/chunks/{error.svelte-C35KOpru.js.map → error.svelte-CzVR_A6P.js.map} +1 -1
- package/build/server/chunks/featureQueueContext-DuXpyTdC.js +32 -0
- package/build/server/chunks/featureQueueContext-DuXpyTdC.js.map +1 -0
- package/build/server/chunks/featureStore.svelte-DHZf88gu.js +162 -0
- package/build/server/chunks/featureStore.svelte-DHZf88gu.js.map +1 -0
- package/build/server/chunks/{projectsStore.svelte-QDz5PchX.js → featuresStore.svelte-bUyQBg1-.js} +95 -3
- package/build/server/chunks/featuresStore.svelte-bUyQBg1-.js.map +1 -0
- package/build/server/chunks/{hooks.server-Rv301GTB.js → hooks.server-y3jdg_sB.js} +6 -2
- package/build/server/chunks/hooks.server-y3jdg_sB.js.map +1 -0
- package/build/server/chunks/humanize-CkCPfeWi.js +53 -0
- package/build/server/chunks/humanize-CkCPfeWi.js.map +1 -0
- package/build/server/chunks/{index-server-7H0jzj0M.js → index-server-DvBux_Gf.js} +47 -2
- package/build/server/chunks/{index-server-7H0jzj0M.js.map → index-server-DvBux_Gf.js.map} +1 -1
- package/build/server/chunks/{internal-BPKrFkK1.js → internal-BFt8yDlf.js} +5 -5
- package/build/server/chunks/{internal-BPKrFkK1.js.map → internal-BFt8yDlf.js.map} +1 -1
- package/build/server/chunks/projectBundleClient-BtvWPh87.js +168 -0
- package/build/server/chunks/projectBundleClient-BtvWPh87.js.map +1 -0
- package/build/server/chunks/projectContextStore.svelte-jRJGJZ42.js +141 -0
- package/build/server/chunks/projectContextStore.svelte-jRJGJZ42.js.map +1 -0
- package/build/server/chunks/projectFeaturesStore.svelte-BwNEtDIL.js +87 -0
- package/build/server/chunks/projectFeaturesStore.svelte-BwNEtDIL.js.map +1 -0
- package/build/server/chunks/projectStore.svelte-BNuLNxk_.js +230 -0
- package/build/server/chunks/projectStore.svelte-BNuLNxk_.js.map +1 -0
- package/build/server/chunks/{reconcile-Dv7jS3C8.js → reconcile-CVG2LSlW.js} +54 -267
- package/build/server/chunks/reconcile-CVG2LSlW.js.map +1 -0
- package/build/server/chunks/registry-DqAn_hVE.js +21 -0
- package/build/server/chunks/registry-DqAn_hVE.js.map +1 -0
- package/build/server/chunks/{snapshotRepository-BPXCjX92.js → snapshotRepository-8f-2wTrb.js} +30 -5
- package/build/server/chunks/snapshotRepository-8f-2wTrb.js.map +1 -0
- package/build/server/chunks/{state-CpLVNZq7.js → state-CZZtjXLE.js} +3 -3
- package/build/server/chunks/{state-CpLVNZq7.js.map → state-CZZtjXLE.js.map} +1 -1
- package/build/server/chunks/{sync-DZ3dn761.js → sync-Bn6eSUhC.js} +3 -3
- package/build/server/chunks/{sync-DZ3dn761.js.map → sync-Bn6eSUhC.js.map} +1 -1
- package/build/server/chunks/{syncBridge-BwXzPdjJ.js → syncAwareRepositories-DvUjq5Q6.js} +27 -3
- package/build/server/chunks/syncAwareRepositories-DvUjq5Q6.js.map +1 -0
- package/build/server/chunks/{tagPaletteStore.svelte-DfZOBvgY.js → tagPaletteStore.svelte-C71bdzDl.js} +4 -4
- package/build/server/chunks/{tagPaletteStore.svelte-DfZOBvgY.js.map → tagPaletteStore.svelte-C71bdzDl.js.map} +1 -1
- package/build/server/index.js +2 -2
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +74 -29
- package/build/server/manifest.js.map +1 -1
- package/cli/README.md +70 -2
- package/cli/commands/check.ts +190 -0
- package/cli/commands/ci.ts +71 -0
- package/cli/commands/coverage-ingest.ts +112 -0
- package/cli/commands/dashboard.ts +14 -0
- package/cli/commands/init.ts +26 -0
- package/cli/commands/scenarios-adapter.ts +96 -0
- package/cli/commands/theme.ts +62 -0
- package/cli/scenarios/adapter-scaffold.ts +99 -0
- package/cli/scenarios/codegen.ts +7 -1
- package/cli/scenarios/results.ts +85 -0
- package/cli/skills/unspa-audit/SKILL.md +19 -0
- package/cli/skills/unspa-edit/SKILL.md +20 -3
- package/cli/skills/unspa-implement/SKILL.md +28 -0
- package/cli/unspa.ts +136 -2
- package/cli/util/context-files.ts +18 -2
- package/cli/util/theme.ts +34 -0
- package/mcp-server/bin.ts +104 -104
- package/mcp-server/migrate-defaults.ts +164 -164
- package/mcp-server/repo-link.ts +142 -134
- package/mcp-server/resources/guide.ts +24 -4
- package/mcp-server/resources/operations.ts +3 -0
- package/mcp-server/seed-snapshots.ts +22 -22
- package/mcp-server/server.ts +8 -4
- package/mcp-server/sync-aware-repos.ts +79 -79
- package/mcp-server/sync-notifier.ts +180 -127
- package/mcp-server/tools/_codegen.ts +115 -115
- package/mcp-server/tools/_entity_builders.ts +30 -0
- package/mcp-server/tools/_shared.ts +210 -210
- package/mcp-server/tools/action.ts +210 -210
- package/mcp-server/tools/batch.ts +29 -5
- package/mcp-server/tools/effect.ts +139 -135
- package/mcp-server/tools/entity.ts +132 -132
- package/mcp-server/tools/entityField.ts +132 -132
- package/mcp-server/tools/event.ts +116 -116
- package/mcp-server/tools/feature.ts +264 -264
- package/mcp-server/tools/invariant.ts +275 -275
- package/mcp-server/tools/persona.ts +141 -141
- package/mcp-server/tools/project.ts +500 -391
- package/mcp-server/tools/reachabilityGoal.ts +97 -0
- package/mcp-server/tools/read.ts +526 -483
- package/mcp-server/tools/reorder.ts +114 -114
- package/mcp-server/tools/resource.ts +194 -194
- package/mcp-server/tools/rule.ts +302 -302
- package/mcp-server/tools/scenario.ts +4 -1
- package/mcp-server/tools/specGaps.ts +221 -221
- package/mcp-server/tools/state.ts +10 -2
- package/mcp-server/tools/surface.ts +102 -102
- package/mcp-server/tools/transition.ts +96 -96
- package/mcp-server/tools/verification.ts +131 -0
- package/package.json +15 -2
- package/src/app.css +208 -9
- package/src/app.html +15 -1
- package/src/features/behavior-model/application/ports/FeatureRepository.ts +16 -16
- package/src/features/behavior-model/application/use-cases/CreateFeature.ts +24 -24
- package/src/features/behavior-model/application/use-cases/DeleteFeature.ts +8 -8
- package/src/features/behavior-model/application/use-cases/GetFeature.ts +9 -9
- package/src/features/behavior-model/application/use-cases/ListFeatures.ts +10 -10
- package/src/features/behavior-model/application/use-cases/MutateFeature.ts +90 -90
- package/src/features/behavior-model/application/use-cases/SaveFeature.ts +31 -31
- package/src/features/behavior-model/domain/entities/Entity.ts +45 -45
- package/src/features/behavior-model/domain/entities/EventDefinition.ts +35 -35
- package/src/features/behavior-model/domain/entities/Feature.ts +10 -0
- package/src/features/behavior-model/domain/entities/Persona.ts +33 -33
- package/src/features/behavior-model/domain/entities/ReachabilityGoal.ts +39 -0
- package/src/features/behavior-model/domain/entities/Resource.ts +54 -54
- package/src/features/behavior-model/domain/entities/Scenario.ts +15 -0
- package/src/features/behavior-model/domain/entities/StateDefinition.ts +13 -0
- package/src/features/behavior-model/domain/entities/Surface.ts +75 -75
- package/src/features/behavior-model/domain/entities/index.ts +9 -9
- package/src/features/behavior-model/domain/services/BehaviorGraphModel.ts +556 -0
- package/src/features/behavior-model/domain/services/DerivedState.ts +67 -0
- package/src/features/behavior-model/domain/services/EffectApplier.ts +112 -3
- package/src/features/behavior-model/domain/services/EffectiveEntities.ts +166 -166
- package/src/features/behavior-model/domain/services/EntityDeducer.ts +83 -83
- package/src/features/behavior-model/domain/services/EventCatalog.ts +141 -141
- package/src/features/behavior-model/domain/services/FeatureExpressionNormalizer.ts +43 -5
- package/src/features/behavior-model/domain/services/FeatureSharedStateNormalizer.ts +24 -3
- package/src/features/behavior-model/domain/services/FeatureTransforms.ts +33 -0
- package/src/features/behavior-model/domain/services/FeatureValidator.ts +124 -16
- package/src/features/behavior-model/domain/services/PersonaApplier.ts +39 -39
- package/src/features/behavior-model/domain/services/ResourceDeducer.ts +64 -64
- package/src/features/behavior-model/domain/services/ResourceUsage.ts +79 -79
- package/src/features/behavior-model/domain/services/ScenarioApplier.ts +40 -40
- package/src/features/behavior-model/domain/services/SharedStateDefinitions.ts +32 -32
- package/src/features/behavior-model/domain/services/StatePathReferences.ts +249 -217
- package/src/features/behavior-model/domain/services/TransitionCatalog.ts +173 -173
- package/src/features/behavior-model/domain/value-objects/Effect.ts +100 -3
- package/src/features/behavior-model/domain/value-objects/EntityFieldType.ts +57 -57
- package/src/features/behavior-model/domain/value-objects/Expression.ts +22 -2
- package/src/features/behavior-model/domain/value-objects/ParameterType.ts +57 -57
- package/src/features/behavior-model/domain/value-objects/Resource.ts +210 -210
- package/src/features/behavior-model/domain/value-objects/RuleCategory.ts +57 -57
- package/src/features/behavior-model/domain/value-objects/RuleCondition.ts +52 -1
- package/src/features/behavior-model/domain/value-objects/SimulationClock.ts +35 -0
- package/src/features/behavior-model/domain/value-objects/ids.ts +2 -0
- package/src/features/behavior-model/infrastructure/io/FeatureJson.ts +89 -89
- package/src/features/behavior-model/infrastructure/persistence/HttpFeatureRepository.ts +43 -43
- package/src/features/behavior-model/infrastructure/persistence/JsonFolderFeatureRepository.ts +10 -0
- package/src/features/behavior-model/infrastructure/persistence/snapshot-discovery.ts +76 -76
- package/src/features/behavior-model/infrastructure/seed/seedStorefront.ts +967 -967
- package/src/features/behavior-model/presentation/adapters/VisBehaviorGraphRenderer.ts +501 -0
- package/src/features/behavior-model/presentation/components/ActionEditor.svelte +683 -682
- package/src/features/behavior-model/presentation/components/ActionsEditor.svelte +232 -232
- package/src/features/behavior-model/presentation/components/BehaviorGraph.svelte +568 -0
- package/src/features/behavior-model/presentation/components/EffectEditor.svelte +168 -168
- package/src/features/behavior-model/presentation/components/EntityEditor.svelte +241 -248
- package/src/features/behavior-model/presentation/components/EntityFieldRow.svelte +180 -181
- package/src/features/behavior-model/presentation/components/EntityManager.svelte +252 -251
- package/src/features/behavior-model/presentation/components/EventsManager.svelte +373 -372
- package/src/features/behavior-model/presentation/components/FeatureEditor.svelte +396 -348
- package/src/features/behavior-model/presentation/components/FeatureHeader.svelte +165 -148
- package/src/features/behavior-model/presentation/components/FeatureHealthStrip.svelte +110 -110
- package/src/features/behavior-model/presentation/components/HistoryPanel.svelte +154 -154
- package/src/features/behavior-model/presentation/components/NewFeatureForm.svelte +66 -66
- package/src/features/behavior-model/presentation/components/ParameterNameSelect.svelte +84 -84
- package/src/features/behavior-model/presentation/components/ParametersEditor.svelte +411 -411
- package/src/features/behavior-model/presentation/components/PersonaEditor.svelte +244 -244
- package/src/features/behavior-model/presentation/components/PersonasManager.svelte +130 -130
- package/src/features/behavior-model/presentation/components/ReachabilityGoalEditor.svelte +230 -0
- package/src/features/behavior-model/presentation/components/ReachabilityGoalsEditor.svelte +86 -0
- package/src/features/behavior-model/presentation/components/ResourcesManager.svelte +291 -290
- package/src/features/behavior-model/presentation/components/ScenariosEditor.svelte +496 -496
- package/src/features/behavior-model/presentation/components/StateDefinitionsEditor.svelte +356 -356
- package/src/features/behavior-model/presentation/components/SurfaceEntitiesView.svelte +88 -88
- package/src/features/behavior-model/presentation/components/SurfaceInvariantsEditor.svelte +76 -76
- package/src/features/behavior-model/presentation/components/SurfaceList.svelte +300 -300
- package/src/features/behavior-model/presentation/components/SurfaceMetaEditor.svelte +158 -156
- package/src/features/behavior-model/presentation/components/SurfacePanel.svelte +198 -198
- package/src/features/behavior-model/presentation/components/SurfacePersonasView.svelte +122 -122
- package/src/features/behavior-model/presentation/components/SurfaceResourcesView.svelte +113 -113
- package/src/features/behavior-model/presentation/components/SurfaceRulesEditor.svelte +69 -69
- package/src/features/behavior-model/presentation/components/TransitionsManager.svelte +322 -321
- package/src/features/behavior-model/presentation/context/featureQueueContext.ts +78 -0
- package/src/features/behavior-model/presentation/stores/editorStore.svelte.ts +132 -131
- package/src/features/behavior-model/presentation/stores/featureStore.svelte.ts +177 -177
- package/src/features/behavior-model/presentation/stores/featuresStore.svelte.ts +98 -98
- package/src/features/behavior-model/presentation/view-models/BehaviorGraphTheme.ts +44 -0
- package/src/features/behavior-model/presentation/view-models/factories.ts +181 -132
- package/src/features/builder-mode/domain/BuilderModeDashboard.ts +7 -1
- package/src/features/builder-mode/presentation/components/BuilderModeDashboard.svelte +78 -16
- package/src/features/builder-mode/presentation/components/BuilderTagChips.svelte +25 -0
- package/src/features/builder-mode/presentation/stores/builderModeStore.svelte.ts +247 -3
- package/src/features/domains/infrastructure/persistence/JsonFolderDomainRepository.ts +9 -0
- package/src/features/global-search/application/use-cases/LoadSearchIndex.ts +70 -0
- package/src/features/global-search/domain/SearchDoc.ts +111 -0
- package/src/features/global-search/domain/buildSearchDocs.ts +483 -0
- package/src/features/global-search/domain/searchNav.ts +58 -0
- package/src/features/global-search/domain/searchScoring.ts +81 -0
- package/src/features/global-search/infrastructure/adapters/defaultSearchHost.ts +28 -0
- package/src/features/global-search/presentation/components/GlobalSearch.svelte +262 -0
- package/src/features/global-search/presentation/ports/SearchHostPorts.ts +41 -0
- package/src/features/global-search/presentation/searchKindMeta.ts +108 -0
- package/src/features/global-search/presentation/stores/globalSearchStore.svelte.ts +171 -0
- package/src/features/implementation-queue/presentation/components/FloatingQueueWidget.svelte +264 -0
- package/src/features/implementation-queue/presentation/stores/globalQueueStore.svelte.ts +172 -0
- package/src/features/implementation-status/application/ports/ImplementationStatusRepository.ts +8 -8
- package/src/features/implementation-status/application/use-cases/GetImplementationStatus.ts +8 -8
- package/src/features/implementation-status/domain/ApplyCapturedToSpec.ts +323 -322
- package/src/features/implementation-status/domain/FieldDiff.ts +238 -236
- package/src/features/implementation-status/infrastructure/persistence/InMemoryImplementationStatusRepository.ts +21 -21
- package/src/features/implementation-status/presentation/components/ImplementationStatusPanel.svelte +831 -831
- package/src/features/implementation-status/presentation/stores/implementationStatusStore.svelte.ts +97 -97
- package/src/features/library/application/use-cases/ApplyBlueprintsToFeature.ts +33 -33
- package/src/features/library/domain/services/BlueprintApplier.ts +94 -94
- package/src/features/library/infrastructure/blueprints/auth/ResetPasswordBlueprint.ts +332 -332
- package/src/features/library/infrastructure/blueprints/auth/SignInBlueprint.ts +281 -281
- package/src/features/library/infrastructure/blueprints/auth/SignUpBlueprint.ts +299 -299
- package/src/features/library/infrastructure/blueprints/auth/VerifyEmailBlueprint.ts +288 -288
- package/src/features/library/infrastructure/blueprints/auth/shared.ts +146 -146
- package/src/features/library/infrastructure/blueprints/commerce/CartBlueprint.ts +222 -222
- package/src/features/library/infrastructure/blueprints/commerce/CatalogBlueprint.ts +190 -190
- package/src/features/library/infrastructure/blueprints/commerce/CheckoutBlueprint.ts +322 -322
- package/src/features/library/infrastructure/blueprints/commerce/OrderConfirmationBlueprint.ts +172 -172
- package/src/features/library/infrastructure/blueprints/commerce/ProductDetailsBlueprint.ts +290 -290
- package/src/features/library/infrastructure/blueprints/content/ReviewsBlueprint.ts +392 -392
- package/src/features/library/infrastructure/blueprints/onboarding/OnboardingWizardBlueprint.ts +344 -344
- package/src/features/library/infrastructure/blueprints/utility/CanvasBlueprint.ts +419 -419
- package/src/features/library/infrastructure/blueprints/utility/CookieConsentBlueprint.ts +195 -195
- package/src/features/library/infrastructure/blueprints/utility/NotFoundBlueprint.ts +86 -86
- package/src/features/library/infrastructure/blueprints/utility/SearchPaletteBlueprint.ts +192 -192
- package/src/features/library/infrastructure/blueprints/utility/StoreLocatorBlueprint.ts +221 -221
- package/src/features/library/infrastructure/blueprints/utility/TaskBoardBlueprint.ts +196 -196
- package/src/features/maturity/application/use-cases/ScoreFeature.ts +7 -7
- package/src/features/maturity/domain/MaturityReport.ts +70 -70
- package/src/features/maturity/domain/MaturityScorer.ts +1001 -985
- package/src/features/maturity/presentation/components/MaturityPanel.svelte +376 -372
- package/src/features/mcp-tools/application/tools/dryRunSimulate.ts +24 -24
- package/src/features/mcp-tools/application/tools/findStateReferences.ts +19 -19
- package/src/features/mcp-tools/application/tools/generateTypes.ts +0 -1
- package/src/features/mcp-tools/application/tools/getAction.ts +165 -165
- package/src/features/mcp-tools/application/tools/getFeature.ts +5 -5
- package/src/features/mcp-tools/application/tools/getFeatureIndex.ts +79 -79
- package/src/features/mcp-tools/application/tools/getNeighborhood.ts +319 -319
- package/src/features/mcp-tools/application/tools/getSurface.ts +86 -86
- package/src/features/mcp-tools/application/tools/index.ts +56 -56
- package/src/features/mcp-tools/application/tools/listActions.ts +49 -49
- package/src/features/mcp-tools/application/tools/listFeatures.ts +7 -7
- package/src/features/mcp-tools/application/tools/scoreFeature.ts +153 -153
- package/src/features/projects/application/ports/ProjectRepository.ts +14 -14
- package/src/features/projects/application/use-cases/AddFeatureToProject.ts +23 -23
- package/src/features/projects/application/use-cases/CreateProject.ts +16 -16
- package/src/features/projects/application/use-cases/FindProjectContainingFeature.ts +23 -23
- package/src/features/projects/application/use-cases/GetProjectAggregate.ts +131 -131
- package/src/features/projects/application/use-cases/ImportProjectBundle.ts +45 -0
- package/src/features/projects/application/use-cases/MoveFeatureInProject.ts +36 -36
- package/src/features/projects/application/use-cases/RemoveFeatureFromProject.ts +23 -23
- package/src/features/projects/domain/entities/Project.ts +12 -0
- package/src/features/projects/domain/services/InheritedFromProject.ts +130 -130
- package/src/features/projects/infrastructure/persistence/JsonFolderProjectRepository.ts +9 -0
- package/src/features/projects/presentation/components/ProjectCard.svelte +27 -8
- package/src/features/projects/presentation/components/ProjectEditor.svelte +23 -19
- package/src/features/projects/presentation/components/ProjectFeaturesPanel.svelte +433 -433
- package/src/features/projects/presentation/components/ProjectsIndex.svelte +54 -10
- package/src/features/projects/presentation/stores/projectContextStore.svelte.ts +170 -170
- package/src/features/projects/presentation/stores/projectFeaturesStore.svelte.ts +114 -114
- package/src/features/projects/presentation/stores/projectStore.svelte.ts +265 -266
- package/src/features/projects/presentation/stores/projectsStore.svelte.ts +134 -134
- package/src/features/simulator/application/use-cases/RunScenarios.ts +27 -1
- package/src/features/simulator/application/use-cases/SimulateAction.ts +47 -47
- package/src/features/simulator/domain/SimulationResult.ts +79 -79
- package/src/features/simulator/domain/SimulatorEngine.ts +43 -9
- package/src/features/simulator/domain/StateExplorer.ts +369 -0
- package/src/features/simulator/domain/SurfaceReachability.ts +130 -0
- package/src/features/simulator/presentation/components/ParameterInputs.svelte +277 -277
- package/src/features/simulator/presentation/components/PersonaPicker.svelte +52 -52
- package/src/features/simulator/presentation/components/ScenarioPicker.svelte +42 -45
- package/src/features/simulator/presentation/components/SidePanel.svelte +170 -170
- package/src/features/simulator/presentation/components/SimulationResultView.svelte +394 -394
- package/src/features/simulator/presentation/components/SimulatorPanel.svelte +293 -293
- package/src/features/simulator/presentation/components/StateInspector.svelte +101 -101
- package/src/features/simulator/presentation/stores/simulatorStore.svelte.ts +268 -268
- package/src/features/tutorial/presentation/components/CodeBlock.svelte +5 -1
- package/src/features/verification/application/ports/BehavioralIndexReader.ts +12 -0
- package/src/features/verification/application/use-cases/VerifyFeatures.ts +151 -0
- package/src/features/verification/domain/DriftReport.ts +37 -0
- package/src/features/verification/domain/EventCoherenceReport.ts +27 -0
- package/src/features/verification/domain/IndexedImplementation.ts +27 -0
- package/src/features/verification/domain/VerificationReport.ts +59 -0
- package/src/features/verification/domain/VerificationThresholds.ts +52 -0
- package/src/features/verification/domain/VerificationVerdict.ts +43 -0
- package/src/features/verification/domain/aggregateVerdict.ts +244 -0
- package/src/features/verification/domain/analyzeEventCoherence.ts +43 -0
- package/src/features/verification/domain/detectDrift.ts +166 -0
- package/src/features/verification/domain/verifiedCoverage.ts +37 -0
- package/src/features/verification/infrastructure/persistence/FileBehavioralIndexReader.ts +81 -0
- package/src/features/verification/infrastructure/persistence/StaticBehavioralIndexReader.ts +15 -0
- package/src/features/verification/presentation/components/VerifyPanel.svelte +74 -0
- package/src/features/verification/presentation/stores/verificationStore.svelte.ts +64 -0
- package/src/hooks.server.ts +11 -1
- package/src/lib/server/openLocalDirectory.ts +40 -0
- package/src/lib/server/searchIndex.ts +161 -0
- package/src/lib/server/snapshotRepository.ts +37 -37
- package/src/lib/server/sync/YDocManager.ts +391 -391
- package/src/lib/server/sync/historyStore.ts +276 -276
- package/src/lib/server/sync/wsServer.ts +1 -1
- package/src/lib/sync/protocol.ts +147 -147
- package/src/lib/sync/roomId.ts +33 -33
- package/src/lib/theme/registry.ts +77 -0
- package/src/lib/theme/themeStore.svelte.ts +64 -0
- package/src/routes/+layout.svelte +288 -30
- package/src/routes/api/domains/[id]/+server.ts +7 -3
- package/src/routes/api/projects/[id]/+server.ts +14 -4
- package/src/routes/api/projects/import/+server.ts +16 -38
- package/src/routes/api/search-index/+server.ts +16 -0
- package/src/routes/api/snapshots/[id]/+server.ts +56 -44
- package/src/routes/api/snapshots/[id]/implementation-status/+server.ts +13 -13
- package/src/routes/api/snapshots/[id]/verify/+server.ts +37 -0
- package/src/routes/api/sync/reload/+server.ts +157 -157
- package/src/routes/api/system/hub-directory/+server.ts +24 -0
- package/src/routes/features/+page.svelte +484 -484
- package/src/routes/features/[id]/+page.svelte +55 -49
- package/src/routes/features/[id]/graph/+page.svelte +39 -0
- package/src/routes/features/[id]/verify/+page.svelte +89 -0
- package/src/routes/mcp/+page.svelte +16 -1
- package/src/routes/projects/[id]/+page.svelte +70 -70
- package/src/routes/projects/[id]/graph/+page.svelte +79 -0
- package/src/routes/tutorial/+page.svelte +3 -2
- package/src/shared/infrastructure/browserContainer.ts +61 -61
- package/src/shared/presentation/components/KebabMenu.svelte +95 -0
- package/src/shared/presentation/components/MenuItem.svelte +29 -0
- package/src/shared/presentation/components/ProgressBar.svelte +1 -1
- package/src/shared/presentation/toast/SyncToast.svelte +14 -3
- package/src/shared/presentation/toast/viewLinkResolver.ts +32 -0
- package/static/lyriks_logo.svg +148 -0
- package/vite.config.ts +47 -47
- package/build/client/_app/immutable/assets/0.DFMDYAU9.css +0 -1
- package/build/client/_app/immutable/assets/0.DFMDYAU9.css.br +0 -0
- package/build/client/_app/immutable/assets/0.DFMDYAU9.css.gz +0 -0
- package/build/client/_app/immutable/assets/9.nv0I59TU.css.gz +0 -0
- package/build/client/_app/immutable/chunks/BO66rBOa2.js +0 -1
- package/build/client/_app/immutable/chunks/BO66rBOa2.js.br +0 -0
- package/build/client/_app/immutable/chunks/BO66rBOa2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BOrLmFwJ.js.br +0 -0
- package/build/client/_app/immutable/chunks/BOrLmFwJ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BfMYiIUi.js.br +0 -0
- package/build/client/_app/immutable/chunks/BfMYiIUi.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bp2_Vghh.js +0 -1
- package/build/client/_app/immutable/chunks/Bp2_Vghh.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bp2_Vghh.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bp8HpEPe2.js +0 -4
- package/build/client/_app/immutable/chunks/Bp8HpEPe2.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bp8HpEPe2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C8rRKIXT.js +0 -1
- package/build/client/_app/immutable/chunks/C8rRKIXT.js.br +0 -0
- package/build/client/_app/immutable/chunks/C8rRKIXT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CJjJLwzv2.js +0 -1
- package/build/client/_app/immutable/chunks/CJjJLwzv2.js.br +0 -0
- package/build/client/_app/immutable/chunks/CJjJLwzv2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CxyLMlpt2.js.br +0 -0
- package/build/client/_app/immutable/chunks/CxyLMlpt2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D6jhrpTg.js +0 -1
- package/build/client/_app/immutable/chunks/D6jhrpTg.js.br +0 -0
- package/build/client/_app/immutable/chunks/D6jhrpTg.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D8YEa1po.js +0 -1
- package/build/client/_app/immutable/chunks/D8YEa1po.js.br +0 -0
- package/build/client/_app/immutable/chunks/D8YEa1po.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D9dKmajw.js +0 -1
- package/build/client/_app/immutable/chunks/D9dKmajw.js.br +0 -0
- package/build/client/_app/immutable/chunks/D9dKmajw.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DBJWcC6Y.js +0 -1
- package/build/client/_app/immutable/chunks/DBJWcC6Y.js.br +0 -0
- package/build/client/_app/immutable/chunks/DBJWcC6Y.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DHoA038D.js +0 -1
- package/build/client/_app/immutable/chunks/DHoA038D.js.br +0 -2
- package/build/client/_app/immutable/chunks/DHoA038D.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DKgYpi6_.js +0 -1
- package/build/client/_app/immutable/chunks/DKgYpi6_.js.br +0 -0
- package/build/client/_app/immutable/chunks/DKgYpi6_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DatGSObE.js +0 -1
- package/build/client/_app/immutable/chunks/DatGSObE.js.br +0 -0
- package/build/client/_app/immutable/chunks/DatGSObE.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dg0acPpT.js +0 -1
- package/build/client/_app/immutable/chunks/Dg0acPpT.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dg0acPpT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DjWKKtqp.js +0 -1
- package/build/client/_app/immutable/chunks/DjWKKtqp.js.br +0 -1
- package/build/client/_app/immutable/chunks/DjWKKtqp.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dq0DUAz1.js +0 -1
- package/build/client/_app/immutable/chunks/Dq0DUAz1.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dq0DUAz1.js.gz +0 -0
- package/build/client/_app/immutable/chunks/HKLi1Yz3.js +0 -1
- package/build/client/_app/immutable/chunks/HKLi1Yz3.js.br +0 -0
- package/build/client/_app/immutable/chunks/HKLi1Yz3.js.gz +0 -0
- package/build/client/_app/immutable/chunks/N7PXjlRH.js +0 -1
- package/build/client/_app/immutable/chunks/N7PXjlRH.js.br +0 -0
- package/build/client/_app/immutable/chunks/N7PXjlRH.js.gz +0 -0
- package/build/client/_app/immutable/chunks/hpWJNn0t2.js +0 -2
- package/build/client/_app/immutable/chunks/hpWJNn0t2.js.br +0 -0
- package/build/client/_app/immutable/chunks/hpWJNn0t2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/iQu0D9Ux.js +0 -1
- package/build/client/_app/immutable/chunks/iQu0D9Ux.js.br +0 -0
- package/build/client/_app/immutable/chunks/iQu0D9Ux.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CLgh6Mx_.js +0 -2
- package/build/client/_app/immutable/entry/app.CLgh6Mx_.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CLgh6Mx_.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.D5GPCQZD.js +0 -1
- package/build/client/_app/immutable/entry/start.D5GPCQZD.js.br +0 -0
- package/build/client/_app/immutable/entry/start.D5GPCQZD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.BOoI-hsu.js +0 -4
- package/build/client/_app/immutable/nodes/0.BOoI-hsu.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.BOoI-hsu.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.KYdA6ppX.js.br +0 -2
- package/build/client/_app/immutable/nodes/1.KYdA6ppX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.DBz20KgG.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.DBz20KgG.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.19DIoFtw.js +0 -1
- package/build/client/_app/immutable/nodes/3.19DIoFtw.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.19DIoFtw.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.BvMzqBJj.js +0 -3
- package/build/client/_app/immutable/nodes/4.BvMzqBJj.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.BvMzqBJj.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.Dq6obSGG.js +0 -42
- package/build/client/_app/immutable/nodes/5.Dq6obSGG.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.Dq6obSGG.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.BOHISqs-.js +0 -5
- package/build/client/_app/immutable/nodes/6.BOHISqs-.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BOHISqs-.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.CemgNJfw.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.CemgNJfw.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.DejSfIYh.js +0 -5
- package/build/client/_app/immutable/nodes/8.DejSfIYh.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.DejSfIYh.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.CMW6a2Lg.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.CMW6a2Lg.js.gz +0 -0
- package/build/server/chunks/0-C_o0oz-N.js +0 -15
- package/build/server/chunks/0-C_o0oz-N.js.map +0 -1
- package/build/server/chunks/1-DPpKAKXV.js +0 -9
- package/build/server/chunks/2-AlfFqtL1.js +0 -9
- package/build/server/chunks/2-AlfFqtL1.js.map +0 -1
- package/build/server/chunks/3-vbjUt_51.js +0 -16
- package/build/server/chunks/3-vbjUt_51.js.map +0 -1
- package/build/server/chunks/4-BNow4x6D.js +0 -16
- package/build/server/chunks/4-BNow4x6D.js.map +0 -1
- package/build/server/chunks/5-D7OCJpxD.js +0 -9
- package/build/server/chunks/5-D7OCJpxD.js.map +0 -1
- package/build/server/chunks/6-QQ7r8Rd5.js +0 -9
- package/build/server/chunks/7-CbPLGaIG.js +0 -9
- package/build/server/chunks/7-CbPLGaIG.js.map +0 -1
- package/build/server/chunks/8-CVO-E-sf.js +0 -9
- package/build/server/chunks/8-CVO-E-sf.js.map +0 -1
- package/build/server/chunks/9-DxT1baO5.js +0 -9
- package/build/server/chunks/9-DxT1baO5.js.map +0 -1
- package/build/server/chunks/FeatureTransforms-UWDHmWEg.js.map +0 -1
- package/build/server/chunks/FeatureValidator-B8qEjAUW.js.map +0 -1
- package/build/server/chunks/ManageTagsDialog-DBxA3tM2.js.map +0 -1
- package/build/server/chunks/ProgressBar-CfhccQ83.js.map +0 -1
- package/build/server/chunks/ProjectsIndex-CoDrvRya.js.map +0 -1
- package/build/server/chunks/RenameTag-BuWLMl1m.js.map +0 -1
- package/build/server/chunks/TagDotStrip-B1XQ0m0Y.js.map +0 -1
- package/build/server/chunks/TagPalette-CtMNYCmu.js.map +0 -1
- package/build/server/chunks/_layout.svelte-BREws55o.js +0 -616
- package/build/server/chunks/_layout.svelte-BREws55o.js.map +0 -1
- package/build/server/chunks/_page.svelte-B1s7jxaQ.js.map +0 -1
- package/build/server/chunks/_page.svelte-B7hT3P8E.js +0 -29
- package/build/server/chunks/_page.svelte-BqSC-1vK.js.map +0 -1
- package/build/server/chunks/_page.svelte-BtI2zZ_Z.js.map +0 -1
- package/build/server/chunks/_page.svelte-De508ek8.js +0 -29
- package/build/server/chunks/_page.svelte-Zf9H4KOP.js.map +0 -1
- package/build/server/chunks/_server.ts-0uNTZKwF.js.map +0 -1
- package/build/server/chunks/_server.ts-DcZPhyhK.js +0 -59
- package/build/server/chunks/_server.ts-DcZPhyhK.js.map +0 -1
- package/build/server/chunks/_server.ts-Dy5zQHe2.js.map +0 -1
- package/build/server/chunks/_server.ts-YnfXkeMJ.js.map +0 -1
- package/build/server/chunks/_server.ts-vcaqdwxS.js.map +0 -1
- package/build/server/chunks/browserContainer-CNX7ANld.js.map +0 -1
- package/build/server/chunks/builderModeStore.svelte-ihupr-3p.js.map +0 -1
- package/build/server/chunks/client-DfpLcAZ9.js +0 -24
- package/build/server/chunks/featuresStore.svelte-DR1gYZyu.js +0 -98
- package/build/server/chunks/featuresStore.svelte-DR1gYZyu.js.map +0 -1
- package/build/server/chunks/hooks.server-Rv301GTB.js.map +0 -1
- package/build/server/chunks/identityStore.svelte-IIvW2_3b.js +0 -59
- package/build/server/chunks/identityStore.svelte-IIvW2_3b.js.map +0 -1
- package/build/server/chunks/projectsStore.svelte-QDz5PchX.js.map +0 -1
- package/build/server/chunks/reconcile-Dv7jS3C8.js.map +0 -1
- package/build/server/chunks/snapshotRepository-BPXCjX92.js.map +0 -1
- package/build/server/chunks/syncBridge-BwXzPdjJ.js.map +0 -1
- package/src/features/implementation-queue/presentation/components/QueuePanel.svelte +0 -204
- package/src/features/implementation-queue/presentation/stores/queueStore.svelte.ts +0 -143
- /package/build/client/_app/immutable/assets/{9.nv0I59TU.css → 12.nv0I59TU.css} +0 -0
- /package/build/client/_app/immutable/assets/{9.nv0I59TU.css.br → 12.nv0I59TU.css.br} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { Effect, SetStateEffect } from '../value-objects/Effect';
|
|
1
|
+
import type { Effect, ListItemMatch, SetStateEffect } from '../value-objects/Effect';
|
|
2
2
|
import {
|
|
3
|
+
deepEqualValue,
|
|
3
4
|
isExpression,
|
|
4
5
|
resolveValueOrExpression,
|
|
5
6
|
type EvaluationContext,
|
|
@@ -8,7 +9,9 @@ import {
|
|
|
8
9
|
import { humanizeStatePath } from '../value-objects/humanize';
|
|
9
10
|
import type { EffectId, SurfaceId } from '../value-objects/ids';
|
|
10
11
|
import type { EventName } from '../value-objects/EventName';
|
|
11
|
-
import
|
|
12
|
+
import type { StateValue } from '../value-objects/StateValue';
|
|
13
|
+
import { advanceClock } from '../value-objects/SimulationClock';
|
|
14
|
+
import { readPath, writePath, type StateSnapshot, type StatePath } from '../value-objects/StatePath';
|
|
12
15
|
|
|
13
16
|
export type AppliedEffectRecord = {
|
|
14
17
|
readonly effectId: EffectId;
|
|
@@ -96,9 +99,40 @@ const summarize = (effect: Effect): string => {
|
|
|
96
99
|
return 'allow';
|
|
97
100
|
case 'transition_surface':
|
|
98
101
|
return `transition to surface ${effect.target}`;
|
|
102
|
+
case 'append_to_list':
|
|
103
|
+
return `append to ${humanizeStatePath(effect.path)}`;
|
|
104
|
+
case 'remove_from_list':
|
|
105
|
+
return `remove from ${humanizeStatePath(effect.path)}${effect.where ? ` where ${effect.where.field} matches` : ''}`;
|
|
106
|
+
case 'update_list_item':
|
|
107
|
+
return `set ${effect.field} on ${humanizeStatePath(effect.path)} items where ${effect.where.field} matches`;
|
|
108
|
+
case 'advance_time':
|
|
109
|
+
return `advance time by ${isExpression(effect.by) ? `<expr:${effect.by.kind}>` : JSON.stringify(effect.by)}`;
|
|
99
110
|
}
|
|
100
111
|
};
|
|
101
112
|
|
|
113
|
+
/** Read the array at `path`, or `null` when the slot is absent or not an array. */
|
|
114
|
+
const readArray = (snapshot: StateSnapshot, path: StatePath): readonly StateValue[] | null => {
|
|
115
|
+
const current = readPath(snapshot, path);
|
|
116
|
+
return Array.isArray(current) ? current : null;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* True when `element` is an object whose `match.field` deep-equals the
|
|
121
|
+
* resolved `match.equals`. Non-object elements never match (the predicate is
|
|
122
|
+
* field-based). The comparand resolves against the running snapshot + params so
|
|
123
|
+
* "where productId equals the productId param" works.
|
|
124
|
+
*/
|
|
125
|
+
const elementMatches = (
|
|
126
|
+
element: StateValue,
|
|
127
|
+
match: ListItemMatch,
|
|
128
|
+
context: EvaluationContext
|
|
129
|
+
): boolean => {
|
|
130
|
+
if (!element || typeof element !== 'object' || Array.isArray(element)) return false;
|
|
131
|
+
const field = (element as { [k: string]: StateValue })[match.field];
|
|
132
|
+
const target = resolveValueOrExpression(match.equals, context);
|
|
133
|
+
return deepEqualValue(field, target);
|
|
134
|
+
};
|
|
135
|
+
|
|
102
136
|
/**
|
|
103
137
|
* Apply an effect. `parameters` defaults to empty so existing call-sites
|
|
104
138
|
* (and tests that only deal with literal effects) keep working. Pass real
|
|
@@ -208,6 +242,80 @@ export const applyEffect = (
|
|
|
208
242
|
transition: effect.target
|
|
209
243
|
};
|
|
210
244
|
}
|
|
245
|
+
case 'append_to_list': {
|
|
246
|
+
// List mutations follow set_state's block discipline: once a rule has
|
|
247
|
+
// blocked, no state lands.
|
|
248
|
+
if (current.blocked) {
|
|
249
|
+
return { ...current, applied: [...current.applied, record] };
|
|
250
|
+
}
|
|
251
|
+
const context: EvaluationContext = { snapshot: current.snapshot, parameters };
|
|
252
|
+
const item = resolveValueOrExpression(effect.item, context);
|
|
253
|
+
// An item that can't be resolved (missing param / non-computable expr)
|
|
254
|
+
// is skipped rather than pushing `undefined` and poisoning the array.
|
|
255
|
+
if (item === undefined) {
|
|
256
|
+
return { ...current, applied: [...current.applied, record] };
|
|
257
|
+
}
|
|
258
|
+
const existing = readArray(current.snapshot, effect.path) ?? [];
|
|
259
|
+
const nextSnapshot = writePath(current.snapshot, effect.path, [...existing, item]);
|
|
260
|
+
return { ...current, snapshot: nextSnapshot, applied: [...current.applied, record] };
|
|
261
|
+
}
|
|
262
|
+
case 'remove_from_list': {
|
|
263
|
+
if (current.blocked) {
|
|
264
|
+
return { ...current, applied: [...current.applied, record] };
|
|
265
|
+
}
|
|
266
|
+
const existing = readArray(current.snapshot, effect.path);
|
|
267
|
+
// No array → nothing to remove. Record the attempt and move on.
|
|
268
|
+
if (existing === null) {
|
|
269
|
+
return { ...current, applied: [...current.applied, record] };
|
|
270
|
+
}
|
|
271
|
+
const context: EvaluationContext = { snapshot: current.snapshot, parameters };
|
|
272
|
+
let kept: readonly StateValue[];
|
|
273
|
+
if (effect.where !== undefined) {
|
|
274
|
+
kept = existing.filter((el) => !elementMatches(el, effect.where!, context));
|
|
275
|
+
} else if (effect.value !== undefined) {
|
|
276
|
+
const target = resolveValueOrExpression(effect.value, context);
|
|
277
|
+
// Unresolvable comparand removes nothing (safer than removing all).
|
|
278
|
+
kept =
|
|
279
|
+
target === undefined ? existing : existing.filter((el) => !deepEqualValue(el, target));
|
|
280
|
+
} else {
|
|
281
|
+
// No selector: never implicitly clear the whole list.
|
|
282
|
+
kept = existing;
|
|
283
|
+
}
|
|
284
|
+
const nextSnapshot = writePath(current.snapshot, effect.path, [...kept]);
|
|
285
|
+
return { ...current, snapshot: nextSnapshot, applied: [...current.applied, record] };
|
|
286
|
+
}
|
|
287
|
+
case 'update_list_item': {
|
|
288
|
+
if (current.blocked) {
|
|
289
|
+
return { ...current, applied: [...current.applied, record] };
|
|
290
|
+
}
|
|
291
|
+
const existing = readArray(current.snapshot, effect.path);
|
|
292
|
+
if (existing === null) {
|
|
293
|
+
return { ...current, applied: [...current.applied, record] };
|
|
294
|
+
}
|
|
295
|
+
const context: EvaluationContext = { snapshot: current.snapshot, parameters };
|
|
296
|
+
const value = resolveValueOrExpression(effect.value, context);
|
|
297
|
+
// Unresolvable value → leave every element untouched (don't write undefined).
|
|
298
|
+
if (value === undefined) {
|
|
299
|
+
return { ...current, applied: [...current.applied, record] };
|
|
300
|
+
}
|
|
301
|
+
const nextArray = existing.map((el) =>
|
|
302
|
+
elementMatches(el, effect.where, context)
|
|
303
|
+
? { ...(el as { [k: string]: StateValue }), [effect.field]: value }
|
|
304
|
+
: el
|
|
305
|
+
);
|
|
306
|
+
const nextSnapshot = writePath(current.snapshot, effect.path, nextArray);
|
|
307
|
+
return { ...current, snapshot: nextSnapshot, applied: [...current.applied, record] };
|
|
308
|
+
}
|
|
309
|
+
case 'advance_time': {
|
|
310
|
+
if (current.blocked) {
|
|
311
|
+
return { ...current, applied: [...current.applied, record] };
|
|
312
|
+
}
|
|
313
|
+
const context: EvaluationContext = { snapshot: current.snapshot, parameters };
|
|
314
|
+
const by = resolveValueOrExpression(effect.by, context);
|
|
315
|
+
// Non-numeric / unresolvable duration → no-op (advanceClock clamps).
|
|
316
|
+
const nextSnapshot = advanceClock(current.snapshot, typeof by === 'number' ? by : 0);
|
|
317
|
+
return { ...current, snapshot: nextSnapshot, applied: [...current.applied, record] };
|
|
318
|
+
}
|
|
211
319
|
default: {
|
|
212
320
|
// An unrecognized effect type means malformed data slipped past the
|
|
213
321
|
// Zod schema (the only legitimate route into `Effect`). Falling through
|
|
@@ -218,7 +326,8 @@ export const applyEffect = (
|
|
|
218
326
|
const unknown = effect as { type?: string };
|
|
219
327
|
throw new Error(
|
|
220
328
|
`EffectApplier: unknown effect type "${unknown.type ?? '<missing>'}". ` +
|
|
221
|
-
`Valid types: set_state, show_message, emit_event, block_action, allow_action,
|
|
329
|
+
`Valid types: set_state, show_message, emit_event, block_action, allow_action, ` +
|
|
330
|
+
`transition_surface, append_to_list, remove_from_list, update_list_item, advance_time.`
|
|
222
331
|
);
|
|
223
332
|
}
|
|
224
333
|
}
|
|
@@ -1,166 +1,166 @@
|
|
|
1
|
-
import type { Entity, EntityField } from '../entities/Entity';
|
|
2
|
-
import type { Feature } from '../entities/Feature';
|
|
3
|
-
import type { EntityFieldType } from '../value-objects/EntityFieldType';
|
|
4
|
-
import type { EntityFieldId, EntityId, ResourceId } from '../value-objects/ids';
|
|
5
|
-
import type { StatePath } from '../value-objects/StatePath';
|
|
6
|
-
import { humanizeStatePath } from '../value-objects/humanize';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Where each piece of an EffectiveEntities came from. Deduced fields are inferred
|
|
10
|
-
* from state-path namespaces; declared fields were explicitly authored on a
|
|
11
|
-
* Entity entity.
|
|
12
|
-
*/
|
|
13
|
-
export type FieldSource = 'deduced' | 'declared';
|
|
14
|
-
|
|
15
|
-
export type EffectiveDataField = {
|
|
16
|
-
readonly id?: EntityFieldId;
|
|
17
|
-
readonly name: string;
|
|
18
|
-
readonly path: StatePath;
|
|
19
|
-
readonly type: EntityFieldType;
|
|
20
|
-
readonly source: FieldSource;
|
|
21
|
-
/** type='object' nested fields (declared only). */
|
|
22
|
-
readonly fields?: readonly EntityField[];
|
|
23
|
-
/** type='array' element schema (declared only). */
|
|
24
|
-
readonly items?: EntityField;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The unified view of a Entity entity that the UI consumes. Combines:
|
|
29
|
-
* - state-path namespaces in the feature (always present), and
|
|
30
|
-
* - any explicitly authored Entity record (optional overrides).
|
|
31
|
-
*
|
|
32
|
-
* "Materialized" means a `Entity` record exists in `feature.entities`. Editing
|
|
33
|
-
* an unmaterialized entry should lazily create one so the metadata
|
|
34
|
-
* (description, resource link, custom name) has somewhere to live.
|
|
35
|
-
*/
|
|
36
|
-
export type EffectiveEntities = {
|
|
37
|
-
readonly id?: EntityId;
|
|
38
|
-
readonly name: string;
|
|
39
|
-
readonly namespace: string;
|
|
40
|
-
readonly description?: string;
|
|
41
|
-
readonly resourceId?: ResourceId;
|
|
42
|
-
readonly fields: readonly EffectiveDataField[];
|
|
43
|
-
readonly isMaterialized: boolean;
|
|
44
|
-
readonly usedBySurfaces: readonly string[];
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const capitalize = (s: string): string =>
|
|
48
|
-
s.length === 0 ? s : s.charAt(0).toUpperCase() + s.slice(1);
|
|
49
|
-
|
|
50
|
-
const fieldNameFromPath = (path: string): string => {
|
|
51
|
-
const segments = path.split('.');
|
|
52
|
-
if (segments.length <= 1) return path;
|
|
53
|
-
return segments[segments.length - 1] as string;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Produce the list of all Entity entities visible in the feature. Every
|
|
58
|
-
* state-path namespace, enriched with metadata from any matching authored
|
|
59
|
-
* `Entity` record. Authored entries with no matching state paths still appear
|
|
60
|
-
* (so the user doesn't lose explicit work).
|
|
61
|
-
*/
|
|
62
|
-
export const getEffectiveEntities = (feature: Feature): readonly EffectiveEntities[] => {
|
|
63
|
-
type DeducedAcc = {
|
|
64
|
-
readonly fields: Map<string, EffectiveDataField>;
|
|
65
|
-
readonly surfaces: Set<string>;
|
|
66
|
-
};
|
|
67
|
-
const deduced = new Map<string, DeducedAcc>();
|
|
68
|
-
|
|
69
|
-
for (const surface of feature.surfaces) {
|
|
70
|
-
for (const def of surface.stateDefinitions) {
|
|
71
|
-
const namespace = def.path.split('.')[0] ?? def.path;
|
|
72
|
-
let acc = deduced.get(namespace);
|
|
73
|
-
if (!acc) {
|
|
74
|
-
acc = { fields: new Map(), surfaces: new Set() };
|
|
75
|
-
deduced.set(namespace, acc);
|
|
76
|
-
}
|
|
77
|
-
if (!acc.fields.has(def.path)) {
|
|
78
|
-
acc.fields.set(def.path, {
|
|
79
|
-
name: fieldNameFromPath(def.path),
|
|
80
|
-
path: def.path,
|
|
81
|
-
type: def.type,
|
|
82
|
-
source: 'deduced'
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
acc.surfaces.add(surface.name);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const declaredByNamespace = new Map<string, Entity>();
|
|
90
|
-
for (const data of feature.entities) {
|
|
91
|
-
declaredByNamespace.set(data.namespace, data);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const namespaces = new Set<string>([
|
|
95
|
-
...deduced.keys(),
|
|
96
|
-
...declaredByNamespace.keys()
|
|
97
|
-
]);
|
|
98
|
-
|
|
99
|
-
const results: EffectiveEntities[] = [];
|
|
100
|
-
for (const namespace of namespaces) {
|
|
101
|
-
const declared = declaredByNamespace.get(namespace);
|
|
102
|
-
const acc = deduced.get(namespace);
|
|
103
|
-
|
|
104
|
-
// Build the field map. Start with deduced fields, then layer declared
|
|
105
|
-
// fields. A declared field with the same path overrides type/name and
|
|
106
|
-
// marks the source as "declared".
|
|
107
|
-
const fieldByPath = new Map<string, EffectiveDataField>();
|
|
108
|
-
if (acc) {
|
|
109
|
-
for (const [path, f] of acc.fields) fieldByPath.set(path, f);
|
|
110
|
-
}
|
|
111
|
-
if (declared) {
|
|
112
|
-
for (const f of declared.fields) {
|
|
113
|
-
// Declared fields without a path can't surface in the effective view
|
|
114
|
-
// (they live inside an object/array and don't map to a state path).
|
|
115
|
-
if (!f.path) continue;
|
|
116
|
-
fieldByPath.set(String(f.path), {
|
|
117
|
-
id: f.id,
|
|
118
|
-
name: f.name,
|
|
119
|
-
path: f.path,
|
|
120
|
-
type: f.type,
|
|
121
|
-
source: 'declared',
|
|
122
|
-
fields: f.fields,
|
|
123
|
-
items: f.items
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const fields = Array.from(fieldByPath.values()).sort((a, b) =>
|
|
129
|
-
a.path.localeCompare(b.path)
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
results.push({
|
|
133
|
-
id: declared?.id,
|
|
134
|
-
// Display name is always derived from the namespace. There's no
|
|
135
|
-
// authored override, the namespace is the canonical identity.
|
|
136
|
-
name: capitalize(humanizeStatePath(namespace)),
|
|
137
|
-
namespace,
|
|
138
|
-
description: declared?.description,
|
|
139
|
-
resourceId: declared?.resourceId,
|
|
140
|
-
fields,
|
|
141
|
-
isMaterialized: declared !== undefined,
|
|
142
|
-
usedBySurfaces: acc ? Array.from(acc.surfaces).sort() : []
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
results.sort((a, b) => a.namespace.localeCompare(b.namespace));
|
|
146
|
-
return results;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Promote an effective data entry into a stored `Entity` record. Used when the
|
|
151
|
-
* user wants to attach metadata (description, resource link, …). The resulting
|
|
152
|
-
* `Entity` carries every effective field exactly as displayed.
|
|
153
|
-
*/
|
|
154
|
-
export const materializeFields = (
|
|
155
|
-
effective: EffectiveEntities,
|
|
156
|
-
newFieldId: () => EntityFieldId
|
|
157
|
-
): readonly EntityField[] => {
|
|
158
|
-
return effective.fields.map((f) => ({
|
|
159
|
-
id: f.id ?? newFieldId(),
|
|
160
|
-
name: f.name,
|
|
161
|
-
path: f.path,
|
|
162
|
-
type: f.type,
|
|
163
|
-
fields: f.fields,
|
|
164
|
-
items: f.items
|
|
165
|
-
}));
|
|
166
|
-
};
|
|
1
|
+
import type { Entity, EntityField } from '../entities/Entity';
|
|
2
|
+
import type { Feature } from '../entities/Feature';
|
|
3
|
+
import type { EntityFieldType } from '../value-objects/EntityFieldType';
|
|
4
|
+
import type { EntityFieldId, EntityId, ResourceId } from '../value-objects/ids';
|
|
5
|
+
import type { StatePath } from '../value-objects/StatePath';
|
|
6
|
+
import { humanizeStatePath } from '../value-objects/humanize';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Where each piece of an EffectiveEntities came from. Deduced fields are inferred
|
|
10
|
+
* from state-path namespaces; declared fields were explicitly authored on a
|
|
11
|
+
* Entity entity.
|
|
12
|
+
*/
|
|
13
|
+
export type FieldSource = 'deduced' | 'declared';
|
|
14
|
+
|
|
15
|
+
export type EffectiveDataField = {
|
|
16
|
+
readonly id?: EntityFieldId;
|
|
17
|
+
readonly name: string;
|
|
18
|
+
readonly path: StatePath;
|
|
19
|
+
readonly type: EntityFieldType;
|
|
20
|
+
readonly source: FieldSource;
|
|
21
|
+
/** type='object' nested fields (declared only). */
|
|
22
|
+
readonly fields?: readonly EntityField[];
|
|
23
|
+
/** type='array' element schema (declared only). */
|
|
24
|
+
readonly items?: EntityField;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The unified view of a Entity entity that the UI consumes. Combines:
|
|
29
|
+
* - state-path namespaces in the feature (always present), and
|
|
30
|
+
* - any explicitly authored Entity record (optional overrides).
|
|
31
|
+
*
|
|
32
|
+
* "Materialized" means a `Entity` record exists in `feature.entities`. Editing
|
|
33
|
+
* an unmaterialized entry should lazily create one so the metadata
|
|
34
|
+
* (description, resource link, custom name) has somewhere to live.
|
|
35
|
+
*/
|
|
36
|
+
export type EffectiveEntities = {
|
|
37
|
+
readonly id?: EntityId;
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly namespace: string;
|
|
40
|
+
readonly description?: string;
|
|
41
|
+
readonly resourceId?: ResourceId;
|
|
42
|
+
readonly fields: readonly EffectiveDataField[];
|
|
43
|
+
readonly isMaterialized: boolean;
|
|
44
|
+
readonly usedBySurfaces: readonly string[];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const capitalize = (s: string): string =>
|
|
48
|
+
s.length === 0 ? s : s.charAt(0).toUpperCase() + s.slice(1);
|
|
49
|
+
|
|
50
|
+
const fieldNameFromPath = (path: string): string => {
|
|
51
|
+
const segments = path.split('.');
|
|
52
|
+
if (segments.length <= 1) return path;
|
|
53
|
+
return segments[segments.length - 1] as string;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Produce the list of all Entity entities visible in the feature. Every
|
|
58
|
+
* state-path namespace, enriched with metadata from any matching authored
|
|
59
|
+
* `Entity` record. Authored entries with no matching state paths still appear
|
|
60
|
+
* (so the user doesn't lose explicit work).
|
|
61
|
+
*/
|
|
62
|
+
export const getEffectiveEntities = (feature: Feature): readonly EffectiveEntities[] => {
|
|
63
|
+
type DeducedAcc = {
|
|
64
|
+
readonly fields: Map<string, EffectiveDataField>;
|
|
65
|
+
readonly surfaces: Set<string>;
|
|
66
|
+
};
|
|
67
|
+
const deduced = new Map<string, DeducedAcc>();
|
|
68
|
+
|
|
69
|
+
for (const surface of feature.surfaces) {
|
|
70
|
+
for (const def of surface.stateDefinitions) {
|
|
71
|
+
const namespace = def.path.split('.')[0] ?? def.path;
|
|
72
|
+
let acc = deduced.get(namespace);
|
|
73
|
+
if (!acc) {
|
|
74
|
+
acc = { fields: new Map(), surfaces: new Set() };
|
|
75
|
+
deduced.set(namespace, acc);
|
|
76
|
+
}
|
|
77
|
+
if (!acc.fields.has(def.path)) {
|
|
78
|
+
acc.fields.set(def.path, {
|
|
79
|
+
name: fieldNameFromPath(def.path),
|
|
80
|
+
path: def.path,
|
|
81
|
+
type: def.type,
|
|
82
|
+
source: 'deduced'
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
acc.surfaces.add(surface.name);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const declaredByNamespace = new Map<string, Entity>();
|
|
90
|
+
for (const data of feature.entities) {
|
|
91
|
+
declaredByNamespace.set(data.namespace, data);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const namespaces = new Set<string>([
|
|
95
|
+
...deduced.keys(),
|
|
96
|
+
...declaredByNamespace.keys()
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
const results: EffectiveEntities[] = [];
|
|
100
|
+
for (const namespace of namespaces) {
|
|
101
|
+
const declared = declaredByNamespace.get(namespace);
|
|
102
|
+
const acc = deduced.get(namespace);
|
|
103
|
+
|
|
104
|
+
// Build the field map. Start with deduced fields, then layer declared
|
|
105
|
+
// fields. A declared field with the same path overrides type/name and
|
|
106
|
+
// marks the source as "declared".
|
|
107
|
+
const fieldByPath = new Map<string, EffectiveDataField>();
|
|
108
|
+
if (acc) {
|
|
109
|
+
for (const [path, f] of acc.fields) fieldByPath.set(path, f);
|
|
110
|
+
}
|
|
111
|
+
if (declared) {
|
|
112
|
+
for (const f of declared.fields) {
|
|
113
|
+
// Declared fields without a path can't surface in the effective view
|
|
114
|
+
// (they live inside an object/array and don't map to a state path).
|
|
115
|
+
if (!f.path) continue;
|
|
116
|
+
fieldByPath.set(String(f.path), {
|
|
117
|
+
id: f.id,
|
|
118
|
+
name: f.name,
|
|
119
|
+
path: f.path,
|
|
120
|
+
type: f.type,
|
|
121
|
+
source: 'declared',
|
|
122
|
+
fields: f.fields,
|
|
123
|
+
items: f.items
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const fields = Array.from(fieldByPath.values()).sort((a, b) =>
|
|
129
|
+
a.path.localeCompare(b.path)
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
results.push({
|
|
133
|
+
id: declared?.id,
|
|
134
|
+
// Display name is always derived from the namespace. There's no
|
|
135
|
+
// authored override, the namespace is the canonical identity.
|
|
136
|
+
name: capitalize(humanizeStatePath(namespace)),
|
|
137
|
+
namespace,
|
|
138
|
+
description: declared?.description,
|
|
139
|
+
resourceId: declared?.resourceId,
|
|
140
|
+
fields,
|
|
141
|
+
isMaterialized: declared !== undefined,
|
|
142
|
+
usedBySurfaces: acc ? Array.from(acc.surfaces).sort() : []
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
results.sort((a, b) => a.namespace.localeCompare(b.namespace));
|
|
146
|
+
return results;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Promote an effective data entry into a stored `Entity` record. Used when the
|
|
151
|
+
* user wants to attach metadata (description, resource link, …). The resulting
|
|
152
|
+
* `Entity` carries every effective field exactly as displayed.
|
|
153
|
+
*/
|
|
154
|
+
export const materializeFields = (
|
|
155
|
+
effective: EffectiveEntities,
|
|
156
|
+
newFieldId: () => EntityFieldId
|
|
157
|
+
): readonly EntityField[] => {
|
|
158
|
+
return effective.fields.map((f) => ({
|
|
159
|
+
id: f.id ?? newFieldId(),
|
|
160
|
+
name: f.name,
|
|
161
|
+
path: f.path,
|
|
162
|
+
type: f.type,
|
|
163
|
+
fields: f.fields,
|
|
164
|
+
items: f.items
|
|
165
|
+
}));
|
|
166
|
+
};
|
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
import type { Feature } from '../entities/Feature';
|
|
2
|
-
import type { StatePath } from '../value-objects/StatePath';
|
|
3
|
-
import type { StateType } from '../value-objects/StateValue';
|
|
4
|
-
import { humanizeStatePath } from '../value-objects/humanize';
|
|
5
|
-
|
|
6
|
-
export type DeducedField = {
|
|
7
|
-
readonly name: string;
|
|
8
|
-
readonly path: StatePath;
|
|
9
|
-
readonly type: StateType;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export type DeducedDataCandidate = {
|
|
13
|
-
/** First segment of the dot-path; the proposed entity's namespace. */
|
|
14
|
-
readonly namespace: string;
|
|
15
|
-
/** Suggested human-friendly name (e.g. "User", "Cart"). */
|
|
16
|
-
readonly proposedName: string;
|
|
17
|
-
readonly fields: readonly DeducedField[];
|
|
18
|
-
readonly usedBySurfaces: readonly string[];
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const capitalize = (s: string): string =>
|
|
22
|
-
s.length === 0 ? s : s.charAt(0).toUpperCase() + s.slice(1);
|
|
23
|
-
|
|
24
|
-
const fieldNameFromPath = (path: string): string => {
|
|
25
|
-
const segments = path.split('.');
|
|
26
|
-
if (segments.length <= 1) return path;
|
|
27
|
-
// Everything after the namespace becomes the field name. If there are
|
|
28
|
-
// multiple sub-segments (e.g. "user.address.city"), use the last one.
|
|
29
|
-
return segments[segments.length - 1] as string;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Walk every state definition across every surface and group by the first
|
|
34
|
-
* path segment (namespace). Each unique namespace becomes a candidate Entity
|
|
35
|
-
* entity. Namespaces that already have a materialized Entity entry are skipped.
|
|
36
|
-
*
|
|
37
|
-
* Output is sorted alphabetically for stable rendering.
|
|
38
|
-
*/
|
|
39
|
-
export const deduceDataCandidates = (
|
|
40
|
-
feature: Feature
|
|
41
|
-
): readonly DeducedDataCandidate[] => {
|
|
42
|
-
const existingNamespaces = new Set(feature.entities.map((d) => d.namespace));
|
|
43
|
-
|
|
44
|
-
type Acc = {
|
|
45
|
-
fields: Map<string, DeducedField>; // path -> field (dedup)
|
|
46
|
-
surfaces: Set<string>;
|
|
47
|
-
};
|
|
48
|
-
const byNamespace = new Map<string, Acc>();
|
|
49
|
-
|
|
50
|
-
for (const surface of feature.surfaces) {
|
|
51
|
-
for (const def of surface.stateDefinitions) {
|
|
52
|
-
const segments = def.path.split('.');
|
|
53
|
-
const namespace = segments[0] ?? def.path;
|
|
54
|
-
if (existingNamespaces.has(namespace)) continue;
|
|
55
|
-
|
|
56
|
-
let acc = byNamespace.get(namespace);
|
|
57
|
-
if (!acc) {
|
|
58
|
-
acc = { fields: new Map(), surfaces: new Set() };
|
|
59
|
-
byNamespace.set(namespace, acc);
|
|
60
|
-
}
|
|
61
|
-
if (!acc.fields.has(def.path)) {
|
|
62
|
-
acc.fields.set(def.path, {
|
|
63
|
-
name: fieldNameFromPath(def.path),
|
|
64
|
-
path: def.path,
|
|
65
|
-
type: def.type
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
acc.surfaces.add(surface.name);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const candidates: DeducedDataCandidate[] = [];
|
|
73
|
-
for (const [namespace, acc] of byNamespace) {
|
|
74
|
-
candidates.push({
|
|
75
|
-
namespace,
|
|
76
|
-
proposedName: capitalize(humanizeStatePath(namespace)),
|
|
77
|
-
fields: Array.from(acc.fields.values()).sort((a, b) => a.path.localeCompare(b.path)),
|
|
78
|
-
usedBySurfaces: Array.from(acc.surfaces).sort()
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
candidates.sort((a, b) => a.namespace.localeCompare(b.namespace));
|
|
82
|
-
return candidates;
|
|
83
|
-
};
|
|
1
|
+
import type { Feature } from '../entities/Feature';
|
|
2
|
+
import type { StatePath } from '../value-objects/StatePath';
|
|
3
|
+
import type { StateType } from '../value-objects/StateValue';
|
|
4
|
+
import { humanizeStatePath } from '../value-objects/humanize';
|
|
5
|
+
|
|
6
|
+
export type DeducedField = {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly path: StatePath;
|
|
9
|
+
readonly type: StateType;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type DeducedDataCandidate = {
|
|
13
|
+
/** First segment of the dot-path; the proposed entity's namespace. */
|
|
14
|
+
readonly namespace: string;
|
|
15
|
+
/** Suggested human-friendly name (e.g. "User", "Cart"). */
|
|
16
|
+
readonly proposedName: string;
|
|
17
|
+
readonly fields: readonly DeducedField[];
|
|
18
|
+
readonly usedBySurfaces: readonly string[];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const capitalize = (s: string): string =>
|
|
22
|
+
s.length === 0 ? s : s.charAt(0).toUpperCase() + s.slice(1);
|
|
23
|
+
|
|
24
|
+
const fieldNameFromPath = (path: string): string => {
|
|
25
|
+
const segments = path.split('.');
|
|
26
|
+
if (segments.length <= 1) return path;
|
|
27
|
+
// Everything after the namespace becomes the field name. If there are
|
|
28
|
+
// multiple sub-segments (e.g. "user.address.city"), use the last one.
|
|
29
|
+
return segments[segments.length - 1] as string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Walk every state definition across every surface and group by the first
|
|
34
|
+
* path segment (namespace). Each unique namespace becomes a candidate Entity
|
|
35
|
+
* entity. Namespaces that already have a materialized Entity entry are skipped.
|
|
36
|
+
*
|
|
37
|
+
* Output is sorted alphabetically for stable rendering.
|
|
38
|
+
*/
|
|
39
|
+
export const deduceDataCandidates = (
|
|
40
|
+
feature: Feature
|
|
41
|
+
): readonly DeducedDataCandidate[] => {
|
|
42
|
+
const existingNamespaces = new Set(feature.entities.map((d) => d.namespace));
|
|
43
|
+
|
|
44
|
+
type Acc = {
|
|
45
|
+
fields: Map<string, DeducedField>; // path -> field (dedup)
|
|
46
|
+
surfaces: Set<string>;
|
|
47
|
+
};
|
|
48
|
+
const byNamespace = new Map<string, Acc>();
|
|
49
|
+
|
|
50
|
+
for (const surface of feature.surfaces) {
|
|
51
|
+
for (const def of surface.stateDefinitions) {
|
|
52
|
+
const segments = def.path.split('.');
|
|
53
|
+
const namespace = segments[0] ?? def.path;
|
|
54
|
+
if (existingNamespaces.has(namespace)) continue;
|
|
55
|
+
|
|
56
|
+
let acc = byNamespace.get(namespace);
|
|
57
|
+
if (!acc) {
|
|
58
|
+
acc = { fields: new Map(), surfaces: new Set() };
|
|
59
|
+
byNamespace.set(namespace, acc);
|
|
60
|
+
}
|
|
61
|
+
if (!acc.fields.has(def.path)) {
|
|
62
|
+
acc.fields.set(def.path, {
|
|
63
|
+
name: fieldNameFromPath(def.path),
|
|
64
|
+
path: def.path,
|
|
65
|
+
type: def.type
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
acc.surfaces.add(surface.name);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const candidates: DeducedDataCandidate[] = [];
|
|
73
|
+
for (const [namespace, acc] of byNamespace) {
|
|
74
|
+
candidates.push({
|
|
75
|
+
namespace,
|
|
76
|
+
proposedName: capitalize(humanizeStatePath(namespace)),
|
|
77
|
+
fields: Array.from(acc.fields.values()).sort((a, b) => a.path.localeCompare(b.path)),
|
|
78
|
+
usedBySurfaces: Array.from(acc.surfaces).sort()
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
candidates.sort((a, b) => a.namespace.localeCompare(b.namespace));
|
|
82
|
+
return candidates;
|
|
83
|
+
};
|