From 266bbb6bf5ccc14b8cb1e842eed696e9316e16d8 Mon Sep 17 00:00:00 2001 From: AugustoOM Date: Sun, 7 Jun 2026 19:33:53 -0300 Subject: [PATCH 01/43] Se actualizaron todas las dependencias, se incluye node 22 --- .github/workflows/desktop-release.yml | 12 +- apps/desktop/package.json | 18 +- apps/desktop/src-tauri/Cargo.lock | 220 +- apps/web/package.json | 18 +- apps/web/src/AppHeader.vue | 2 +- env.d.ts | 2 + package.json | 14 +- packages/core/package.json | 12 +- packages/core/src/graph.ts | 10 +- packages/core/src/validation.ts | 18 +- packages/file-io/package.json | 12 +- packages/jff/package.json | 14 +- packages/simulator/package.json | 12 +- packages/ui/package.json | 10 +- packages/ui/src/components/HomePage.vue | 2 +- packages/ui/src/components/InspectorPanel.vue | 2 +- .../ui/src/components/SimulationControls.vue | 2 +- packages/ui/src/components/ThemeToggle.vue | 2 +- packages/ui/src/components/Toolbar.vue | 2 +- packages/ui/src/index.ts | 2 +- pnpm-lock.yaml | 2913 ++++++----------- 21 files changed, 1270 insertions(+), 2029 deletions(-) diff --git a/.github/workflows/desktop-release.yml b/.github/workflows/desktop-release.yml index a3033b3..2af7a52 100644 --- a/.github/workflows/desktop-release.yml +++ b/.github/workflows/desktop-release.yml @@ -32,13 +32,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Enable pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v6 - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 cache: pnpm @@ -59,7 +59,7 @@ jobs: run: pnpm tauri build ${{ matrix.args }} - name: Upload native installers - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: jauto-${{ matrix.label }} if-no-files-found: error @@ -79,10 +79,10 @@ jobs: RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref_name }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Download native installers - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: path: release-assets diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 120d2fd..a81173e 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -12,17 +12,17 @@ }, "dependencies": { "@jauto/core": "workspace:*", - "@jauto/ui": "workspace:*", "@jauto/file-io": "workspace:*", - "@tauri-apps/api": "^2", - "vue": "^3", - "pinia": "^3" + "@jauto/ui": "workspace:*", + "@tauri-apps/api": "^2.11.0", + "pinia": "^3.0.4", + "vue": "^3.5.35" }, "devDependencies": { - "@tauri-apps/cli": "^2", - "@vitejs/plugin-vue": "^5", - "vite": "^6", - "typescript": "^5.8", - "vue-tsc": "^2" + "@tauri-apps/cli": "^2.11.2", + "@vitejs/plugin-vue": "^6.0.7", + "typescript": "^6.0.3", + "vite": "^8.0.16", + "vue-tsc": "^3.3.3" } } diff --git a/apps/desktop/src-tauri/Cargo.lock b/apps/desktop/src-tauri/Cargo.lock index 59b22a3..7250c10 100644 --- a/apps/desktop/src-tauri/Cargo.lock +++ b/apps/desktop/src-tauri/Cargo.lock @@ -253,9 +253,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base64" @@ -292,9 +292,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" dependencies = [ "serde_core", ] @@ -332,9 +332,9 @@ dependencies = [ [[package]] name = "brotli" -version = "8.0.2" +version = "8.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +checksum = "8119e4516436f5708bbc474a9d395bf12f1b5395e93a92a56e647ac3388c8610" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -343,9 +343,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "5.0.0" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +checksum = "5962523e1b92ce1b5e793d9169b9943eece10d39f62550bc04bb605d75b94924" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -362,9 +362,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytemuck" @@ -393,7 +393,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cairo-sys-rs", "glib", "libc", @@ -456,9 +456,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.62" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", "shlex", @@ -499,9 +499,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "num-traits", @@ -560,7 +560,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "core-foundation", "core-graphics-types", "foreign-types", @@ -573,7 +573,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "core-foundation", "libc", ] @@ -773,7 +773,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "block2", "libc", "objc2", @@ -781,9 +781,9 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", @@ -1351,7 +1351,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "futures-channel", "futures-core", "futures-executor", @@ -1518,9 +1518,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" dependencies = [ "bytes", "itoa", @@ -1557,9 +1557,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -1870,9 +1870,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ "cfg-if", "futures-util", @@ -1908,7 +1908,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "serde", "unicode-segmentation", ] @@ -1980,9 +1980,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ "libc", ] @@ -2010,9 +2010,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" [[package]] name = "markup5ever" @@ -2027,9 +2027,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "memoffset" @@ -2058,9 +2058,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -2069,9 +2069,9 @@ dependencies = [ [[package]] name = "muda" -version = "0.19.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae8844f63b5b118e334e205585b8c5c17b984121dbdb179d44aeb087ffad3cb" +checksum = "47a2e3dff89cd322c66647942668faee0a2b1f88ea6cbb4d374b4a8d7e92528c" dependencies = [ "crossbeam-channel", "dpi", @@ -2094,7 +2094,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "jni-sys 0.3.1", "log", "ndk-sys", @@ -2171,7 +2171,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "block2", "objc2", "objc2-core-foundation", @@ -2184,7 +2184,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "objc2", "objc2-foundation", ] @@ -2205,7 +2205,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "dispatch2", "objc2", ] @@ -2216,7 +2216,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "dispatch2", "objc2", "objc2-core-foundation", @@ -2249,7 +2249,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "objc2", "objc2-core-foundation", "objc2-core-graphics", @@ -2276,7 +2276,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "block2", "objc2", "objc2-core-foundation", @@ -2288,7 +2288,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "objc2", "objc2-core-foundation", ] @@ -2299,7 +2299,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "objc2", "objc2-core-foundation", "objc2-foundation", @@ -2311,7 +2311,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "block2", "objc2", "objc2-cloud-kit", @@ -2342,7 +2342,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "block2", "objc2", "objc2-app-kit", @@ -2540,7 +2540,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "crc32fast", "fdeflate", "flate2", @@ -2633,7 +2633,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.11+spec-1.1.0", + "toml_edit 0.25.12+spec-1.1.0", ] [[package]] @@ -2740,7 +2740,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", ] [[package]] @@ -2805,9 +2805,9 @@ checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ "base64 0.22.1", "bytes", @@ -2882,7 +2882,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys", @@ -2973,7 +2973,7 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cssparser", "derive_more", "log", @@ -3051,9 +3051,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -3093,9 +3093,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" +checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c" dependencies = [ "base64 0.22.1", "bs58", @@ -3113,9 +3113,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" +checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660" dependencies = [ "darling", "proc-macro2", @@ -3167,9 +3167,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook-registry" @@ -3207,9 +3207,9 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -3366,11 +3366,11 @@ dependencies = [ [[package]] name = "tao" -version = "0.35.2" +version = "0.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33f7f9e486ade65fcf1e45c440f9236c904f5c1002cdc7fc6ae582777345ce4" +checksum = "d1c93047acf68669466a34690ac58cca7010bd1b201e1ec86f1fd0a75d3dd4a9" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "block2", "core-foundation", "core-graphics", @@ -3875,9 +3875,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap 2.14.0", "toml_datetime 1.1.1+spec-1.1.0", @@ -3921,7 +3921,7 @@ version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "bytes", "futures-util", "http", @@ -4012,9 +4012,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "uds_windows" @@ -4076,9 +4076,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-xid" @@ -4131,9 +4131,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.23.1" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -4218,9 +4218,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -4231,9 +4231,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.71" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ "js-sys", "wasm-bindgen", @@ -4241,9 +4241,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4251,9 +4251,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -4264,9 +4264,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] @@ -4312,7 +4312,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "hashbrown 0.15.5", "indexmap 2.14.0", "semver", @@ -4338,7 +4338,7 @@ version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "rustix", "wayland-backend", "wayland-scanner", @@ -4350,7 +4350,7 @@ version = "0.32.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4380,9 +4380,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.98" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", @@ -4929,7 +4929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.1", + "bitflags 2.13.0", "indexmap 2.14.0", "log", "serde", @@ -5032,9 +5032,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -5055,9 +5055,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.15.0" +version = "5.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3bcbf15c8708d7fc1be0c993622e0a5cbd5e8b52bfa40afa4c3e0cd8d724ac1" +checksum = "eee682d202a77e4a9f3b2c2bdf48a7b28af5c08c34ddf66f98c93e5e39464285" dependencies = [ "async-broadcast", "async-executor", @@ -5090,9 +5090,9 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.15.0" +version = "5.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51fa5406ad9175a8c825a931f8cf347116b531b3634fcb0b627c290f1f2516ff" +checksum = "adf1bd45a81a103745b1757754762a26e8cd01e4532e4d6c8ec431624b80d1d6" dependencies = [ "proc-macro-crate 3.5.0", "proc-macro2", @@ -5116,18 +5116,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" dependencies = [ "proc-macro2", "quote", @@ -5196,9 +5196,9 @@ checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" [[package]] name = "zvariant" -version = "5.11.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c1567a6ec68df868cbbfde844cfc6d81649fe5109a62b116b19fabd53e618ee" +checksum = "a192a0bde63360d77a7523c833d4b4ce6070a927e2c53246e4c540b1a3e27be0" dependencies = [ "endi", "enumflags2", @@ -5211,9 +5211,9 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "5.11.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d5b780599bbde114e39d9a0799577fad1ced5105d38515745f7b3099d8ceda" +checksum = "90bc6cde9c01c511074be97f7ccb6c19d0da89e3f8662e812e999dcfd4638737" dependencies = [ "proc-macro-crate 3.5.0", "proc-macro2", @@ -5224,9 +5224,9 @@ dependencies = [ [[package]] name = "zvariant_utils" -version = "3.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d464f5733ffa07a3164d656f18533caace9d0638596721355d73256a410d691" +checksum = "1e8535915cfa75547e559d8c68e8139909a4aeee076831e4ef7fc59d8172c4d6" dependencies = [ "proc-macro2", "quote", diff --git a/apps/web/package.json b/apps/web/package.json index 9a51a3c..d69a5aa 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -12,17 +12,17 @@ }, "dependencies": { "@jauto/core": "workspace:*", - "@jauto/ui": "workspace:*", "@jauto/file-io": "workspace:*", - "lucide-vue-next": "^1", - "vue": "^3", - "pinia": "^3", - "vue-router": "^4" + "@jauto/ui": "workspace:*", + "@lucide/vue": "^1.17.0", + "pinia": "^3.0.4", + "vue": "^3.5.35", + "vue-router": "^5.1.0" }, "devDependencies": { - "@vitejs/plugin-vue": "^5", - "vite": "^6", - "typescript": "^5.8", - "vue-tsc": "^2" + "@vitejs/plugin-vue": "^6.0.7", + "typescript": "^6.0.3", + "vite": "^8.0.16", + "vue-tsc": "^3.3.3" } } diff --git a/apps/web/src/AppHeader.vue b/apps/web/src/AppHeader.vue index d6ee607..64d8bb8 100644 --- a/apps/web/src/AppHeader.vue +++ b/apps/web/src/AppHeader.vue @@ -1,6 +1,6 @@ diff --git a/packages/ui/src/stores/simulation.ts b/packages/ui/src/stores/simulation.ts index c2f90ff..352b94d 100644 --- a/packages/ui/src/stores/simulation.ts +++ b/packages/ui/src/stores/simulation.ts @@ -1,9 +1,10 @@ import { defineStore } from 'pinia'; -import { ref, computed, watch } from 'vue'; +import { computed, ref, watch } from 'vue'; import type { SimulationRunner, StepResult, SimulationStatus } from '@jauto/simulator'; import { createDFARunner, createNFARunner, createPDARunner, createTMRunner } from '@jauto/simulator'; import { isDeterministic } from '@jauto/core'; import type { AnyAutomaton, AnyTransition, PushdownAutomaton, TuringMachine } from '@jauto/core'; +import { useDocumentStore } from './document'; export interface TransitionHighlight { transitionId: string; @@ -13,19 +14,21 @@ export interface TransitionHighlight { } export const useSimulationStore = defineStore('simulation', () => { + const document = useDocumentStore(); const input = ref(''); const isRunning = ref(false); const status = ref(null); const errorMessage = ref(null); const stepIndex = ref(0); const highlightedStates = ref>(new Set()); - const transitionHighlights = ref([]); const activeTraceIndex = ref(-1); const speed = ref(500); // eslint-disable-next-line @typescript-eslint/no-explicit-any let runner: SimulationRunner | null = null; let activeAutomaton: AnyAutomaton | null = null; + let activeSemanticSignature: string | null = null; + let executionStatus: SimulationStatus | null = null; let intervalId: ReturnType | null = null; // eslint-disable-next-line @typescript-eslint/no-explicit-any const traceSteps = ref[]>([]); @@ -33,9 +36,7 @@ export const useSimulationStore = defineStore('simulation', () => { function createRunnerFor(automaton: AnyAutomaton, inputStr: string) { switch (automaton.kind) { case 'fa': - return isDeterministic(automaton) - ? createDFARunner(automaton, inputStr) - : createNFARunner(automaton, inputStr); + return isDeterministic(automaton) ? createDFARunner(automaton, inputStr) : createNFARunner(automaton, inputStr); case 'pda': return createPDARunner(automaton as PushdownAutomaton, inputStr); case 'turing': @@ -43,32 +44,34 @@ export const useSimulationStore = defineStore('simulation', () => { } } - const activeTransition = computed(() => { - if (activeTraceIndex.value < 0) return null; - return transitionHighlights.value[activeTraceIndex.value] ?? null; + const activeSnapshot = computed(() => traceSteps.value[activeTraceIndex.value] ?? null); + const executionIndex = computed(() => traceSteps.value.length - 1); + const transitionHighlights = computed(() => { + if (!activeAutomaton || !activeSnapshot.value) return []; + const ids = new Set(activeSnapshot.value.transitionIds); + return activeAutomaton.transitions.filter((transition) => ids.has(transition.id)).map(toHighlight); }); + const activeTransition = computed(() => transitionHighlights.value[0] ?? null); + const activeConfigurations = computed(() => activeSnapshot.value?.configurations ?? []); + const acceptingPath = computed(() => activeSnapshot.value?.acceptingPath ?? []); - function updateHighlights() { - if (!runner) { - highlightedStates.value = new Set(); - return; - } - - if (activeTransition.value) { - highlightedStates.value = new Set([ - activeTransition.value.sourceStateId, - activeTransition.value.targetStateId, - ]); - return; - } + function toHighlight(transition: AnyTransition): TransitionHighlight { + return { transitionId: transition.id, sourceStateId: transition.from, targetStateId: transition.to, label: getTransitionLabel(transition) }; + } - const config = runner.currentConfig; + function displaySnapshot(index: number) { + const snapshot = traceSteps.value[index]; + if (!snapshot) return; + activeTraceIndex.value = index; + stepIndex.value = snapshot.stepIndex; + status.value = snapshot.status; const states = new Set(); - if ('currentState' in config && config.currentState) { - states.add(config.currentState as string); - } - if ('activeStates' in config && config.activeStates instanceof Set) { - for (const s of config.activeStates) states.add(s as string); + for (const branch of snapshot.configurations) { + const config = branch.config as Record; + if (typeof config.currentState === 'string' && config.currentState) states.add(config.currentState); + if (config.activeStates instanceof Set) { + for (const state of config.activeStates) if (typeof state === 'string') states.add(state); + } } highlightedStates.value = states; } @@ -78,61 +81,48 @@ export const useSimulationStore = defineStore('simulation', () => { try { runner = createRunnerFor(automaton, input.value); activeAutomaton = automaton; + activeSemanticSignature = semanticSignature(automaton); } catch (error) { status.value = 'invalid'; errorMessage.value = error instanceof Error ? error.message : String(error); return; } - status.value = runner.isAccepted ? 'accepted' : runner.isHalted ? 'rejected' : 'running'; - stepIndex.value = 0; - traceSteps.value = []; - transitionHighlights.value = []; - activeTraceIndex.value = -1; - updateHighlights(); + const initial = runner.currentStep; + traceSteps.value = [initial]; + executionStatus = initial.status; + errorMessage.value = null; + displaySnapshot(0); } - function step(automaton: AnyAutomaton) { - if (!runner || status.value !== 'running') return; - const previousConfig = runner.currentConfig; + function executeStep() { + if (!runner || executionStatus !== 'running') return; const result = runner.step(); - const highlight = inferTransitionHighlight(automaton, previousConfig, result.config); traceSteps.value = [...traceSteps.value, result]; - transitionHighlights.value = highlight - ? [...transitionHighlights.value, highlight] - : transitionHighlights.value; - activeTraceIndex.value = transitionHighlights.value.length - 1; - stepIndex.value = result.stepIndex; - status.value = result.status; - updateHighlights(); + executionStatus = result.status; + displaySnapshot(traceSteps.value.length - 1); } function nextStep(automaton: AnyAutomaton) { - if (activeTraceIndex.value < transitionHighlights.value.length - 1) { - activeTraceIndex.value++; - stepIndex.value = activeTraceIndex.value + 1; - updateHighlights(); + activeAutomaton = automaton; + if (activeTraceIndex.value < executionIndex.value) { + displaySnapshot(activeTraceIndex.value + 1); return; } - step(automaton); + executeStep(); } function previousStep() { - if (activeTraceIndex.value <= 0) return; - activeTraceIndex.value--; - stepIndex.value = activeTraceIndex.value + 1; - updateHighlights(); + if (activeTraceIndex.value > 0) displaySnapshot(activeTraceIndex.value - 1); } function play(automaton: AnyAutomaton) { if (!runner) start(automaton); - if (status.value !== 'running') return; + if (!runner || (activeTraceIndex.value >= executionIndex.value && executionStatus !== 'running')) return; activeAutomaton = automaton; isRunning.value = true; intervalId = setInterval(() => { - if (activeAutomaton) step(activeAutomaton); - if (status.value !== 'running') { - pause(); - } + if (activeAutomaton) nextStep(activeAutomaton); + if (activeTraceIndex.value >= executionIndex.value && executionStatus !== 'running') pause(); }, speed.value); } @@ -149,147 +139,72 @@ export const useSimulationStore = defineStore('simulation', () => { runner?.cancel(); runner = null; activeAutomaton = null; + activeSemanticSignature = null; + executionStatus = null; status.value = null; errorMessage.value = null; stepIndex.value = 0; traceSteps.value = []; - transitionHighlights.value = []; activeTraceIndex.value = -1; highlightedStates.value = new Set(); } + function invalidate(message = 'The machine changed. Restart the simulation to use the new definition.') { + if (!runner) return; + pause(); + runner.cancel(); + runner = null; + executionStatus = 'invalid'; + status.value = 'invalid'; + errorMessage.value = message; + } + function reset(automaton: AnyAutomaton) { stop(); start(automaton); } watch(speed, () => { - if (isRunning.value && intervalId !== null) { - clearInterval(intervalId); - intervalId = setInterval(() => { - if (activeAutomaton) step(activeAutomaton); - if (status.value !== 'running') pause(); - }, speed.value); - } + if (!isRunning.value || intervalId === null) return; + clearInterval(intervalId); + intervalId = setInterval(() => { + if (activeAutomaton) nextStep(activeAutomaton); + if (activeTraceIndex.value >= executionIndex.value && executionStatus !== 'running') pause(); + }, speed.value); + }); + + watch(() => document.automaton, (automaton) => { + if (!runner || activeSemanticSignature === null) return; + const nextSignature = semanticSignature(automaton); + if (nextSignature !== activeSemanticSignature) invalidate(); + else activeAutomaton = automaton; }); const isActive = computed(() => status.value !== null); const canGoPrevious = computed(() => activeTraceIndex.value > 0); - const canGoNext = computed( - () => activeTraceIndex.value < transitionHighlights.value.length - 1 || status.value === 'running', - ); - - function inferTransitionHighlight( - automaton: AnyAutomaton, - previousConfig: unknown, - nextConfig: unknown, - ): TransitionHighlight | null { - const transition = findTransitionForStep(automaton, previousConfig, nextConfig); - if (!transition) return null; - return { - transitionId: transition.id, - sourceStateId: transition.from, - targetStateId: transition.to, - label: getTransitionLabel(transition), - }; - } - - function findTransitionForStep( - automaton: AnyAutomaton, - previousConfig: unknown, - nextConfig: unknown, - ): AnyTransition | null { - if (!hasCurrentState(previousConfig) || !hasCurrentState(nextConfig)) return null; - const candidates = automaton.transitions.filter( - (t) => t.from === previousConfig.currentState && t.to === nextConfig.currentState, - ); - if (candidates.length === 0) return null; - - if (automaton.kind === 'fa' || automaton.kind === 'pda') { - const consumed = getInputIndex(nextConfig) - getInputIndex(previousConfig); - const read = consumed > 0 ? getRemainingInput(previousConfig)[0] ?? '' : ''; - return candidates.find((t) => 'read' in t && t.read === read) ?? candidates[0] ?? null; - } - - if (automaton.kind === 'turing') { - const read = getTapeSymbol(previousConfig); - return ( - candidates.find((t) => 'read' in t && (t.read || '\u25A1') === read) ?? - candidates[0] ?? - null - ); - } - - return candidates[0] ?? null; - } + const canGoNext = computed(() => activeTraceIndex.value < executionIndex.value || executionStatus === 'running'); - function hasCurrentState(config: unknown): config is { currentState: string } { - return typeof config === 'object' && config !== null && 'currentState' in config; + function semanticSignature(automaton: AnyAutomaton): string { + return JSON.stringify({ + kind: automaton.kind, + tapes: automaton.kind === 'turing' ? automaton.tapes : undefined, + states: automaton.states.map(({ x: _x, y: _y, ...state }) => state), + transitions: automaton.transitions.map(({ controlX: _controlX, controlY: _controlY, ...transition }) => transition), + }); } - function getInputIndex(config: unknown): number { - if (typeof config === 'object' && config !== null && 'inputIndex' in config) { - return Number(config.inputIndex) || 0; - } - return 0; - } - - function getRemainingInput(config: unknown): string { - if (typeof config === 'object' && config !== null && 'remainingInput' in config) { - return String(config.remainingInput ?? ''); - } - return ''; - } - - function getTapeSymbol(config: unknown): string { - if ( - typeof config === 'object' && - config !== null && - 'tape' in config && - 'headPosition' in config && - Array.isArray(config.tape) - ) { - return String(config.tape[Number(config.headPosition)] ?? '\u25A1'); - } - return '\u25A1'; - } - - function getTransitionLabel(t: AnyTransition): string { - const read = t.read || '\u03B5'; - if ('pop' in t && 'push' in t) { - const pop = t.pop || '\u03B5'; - const push = t.push || '\u03B5'; - return `${read}, ${pop} -> ${push}`; - } - if ('write' in t && 'move' in t) { - const write = t.write || '\u25A1'; - return `${read} -> ${write}, ${t.move}`; - } + function getTransitionLabel(transition: AnyTransition): string { + const read = transition.read || 'ε'; + if ('pop' in transition && 'push' in transition) return `${read}, ${transition.pop || 'ε'} -> ${transition.push || 'ε'}`; + if ('write' in transition && 'move' in transition) return `${read} -> ${transition.write || '□'}, ${transition.move}`; return read; } return { - input, - isRunning, - isActive, - status, - errorMessage, - stepIndex, - highlightedStates, - activeTransition, - activeTraceIndex, - transitionHighlights, - canGoPrevious, - canGoNext, - speed, - traceSteps, - start, - step, - nextStep, - previousStep, - play, - pause, - stop, - reset, + input, isRunning, isActive, status, errorMessage, stepIndex, highlightedStates, + activeTransition, activeConfigurations, activeSnapshot, acceptingPath, + activeTraceIndex, executionIndex, transitionHighlights, canGoPrevious, canGoNext, + speed, traceSteps, start, step: (_automaton: AnyAutomaton) => executeStep(), nextStep, + previousStep, play, pause, stop, invalidate, reset, }; }); From f1c2fc1aedbb0ee9ca5f67e530b258c1ef056cd6 Mon Sep 17 00:00:00 2001 From: AugustoOM Date: Sun, 6 Sep 2026 11:46:07 -0300 Subject: [PATCH 21/43] feat(ui): add batch input testing --- packages/ui/__tests__/simulation.test.ts | 14 ++++++ .../ui/src/components/SimulationControls.vue | 43 +++++++++++++++++++ packages/ui/src/stores/simulation.ts | 25 ++++++++++- 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/packages/ui/__tests__/simulation.test.ts b/packages/ui/__tests__/simulation.test.ts index 5e68f92..70480d7 100644 --- a/packages/ui/__tests__/simulation.test.ts +++ b/packages/ui/__tests__/simulation.test.ts @@ -98,4 +98,18 @@ describe('simulation store finite-automaton routing', () => { expect(simulation.status).toBe('invalid'); expect(simulation.errorMessage).toContain('machine changed'); }); + + it('tests multiple inputs and preserves distinct outcomes', () => { + const simulation = useSimulationStore(); + const automaton = finiteAutomaton([ + { id: 'first', from: 'q0', to: 'q1', read: 'a' }, + { id: 'second', from: 'q1', to: 'q2', read: 'b' }, + ]); + simulation.batchInput = 'ab\na\n'; + simulation.runBatch(automaton); + + expect(simulation.batchResults.map((result) => [result.input, result.outcome])).toEqual([ + ['ab', 'accepted'], ['a', 'rejected'], ['', 'rejected'], + ]); + }); }); diff --git a/packages/ui/src/components/SimulationControls.vue b/packages/ui/src/components/SimulationControls.vue index 992cc08..bffcd06 100644 --- a/packages/ui/src/components/SimulationControls.vue +++ b/packages/ui/src/components/SimulationControls.vue @@ -156,6 +156,20 @@ function remainingText(config: Record): string { /> {{ sim.speed }}ms +
+ Batch input testing + +