diff --git a/interface/package.json b/interface/package.json index 30122c905..111528624 100644 --- a/interface/package.json +++ b/interface/package.json @@ -38,7 +38,7 @@ "react": "^19.2.7", "react-dom": "^19.2.7", "react-icons": "^5.6.0", - "react-router": "^7.17.0", + "react-router": "^8.0.1", "react-toastify": "^11.1.0", "typesafe-i18n": "^5.27.1", "typescript": "^6.0.3" @@ -56,9 +56,9 @@ "prettier": "^3.8.4", "rollup-plugin-visualizer": "^7.0.1", "terser": "^5.48.0", - "typescript-eslint": "^8.61.0", + "typescript-eslint": "^8.61.1", "vite": "^8.0.16", "vite-plugin-imagemin": "^0.6.1" }, - "packageManager": "pnpm@11.7.0+sha512.19cc852c120c7125760f2443ee6be0ca5b40f9f50598de1a09a1f177503e010e57c23c77646e01e761de59bf874fb22a3398c33ab9691fc13eb946b6f0f4d620" + "packageManager": "pnpm@11.8.0+sha512.c1f5e7c4cb241c8f174b743851d82f42b802324afc8b0f116b96adb15aa06664948dde36960a3ba1079ba5b4b29dd0140135b94b5b5f5263592249d68e555f26" } diff --git a/interface/pnpm-lock.yaml b/interface/pnpm-lock.yaml index 7bf4e03e2..77e976c5a 100644 --- a/interface/pnpm-lock.yaml +++ b/interface/pnpm-lock.yaml @@ -54,8 +54,8 @@ importers: specifier: ^5.6.0 version: 5.6.0(react@19.2.7) react-router: - specifier: ^7.17.0 - version: 7.17.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + specifier: ^8.0.1 + version: 8.0.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react-toastify: specifier: ^11.1.0 version: 11.1.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) @@ -103,8 +103,8 @@ importers: specifier: ^5.48.0 version: 5.48.0 typescript-eslint: - specifier: ^8.61.0 - version: 8.61.0(eslint@10.5.0)(typescript@6.0.3) + specifier: ^8.61.1 + version: 8.61.1(eslint@10.5.0)(typescript@6.0.3) vite: specifier: ^8.0.16 version: 8.0.16(@types/node@25.9.3)(terser@5.48.0) @@ -716,63 +716,63 @@ packages: '@types/svgo@2.6.4': resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==} - '@typescript-eslint/eslint-plugin@8.61.0': - resolution: {integrity: sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==} + '@typescript-eslint/eslint-plugin@8.61.1': + resolution: {integrity: sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.61.0 + '@typescript-eslint/parser': ^8.61.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.61.0': - resolution: {integrity: sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==} + '@typescript-eslint/parser@8.61.1': + resolution: {integrity: sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.61.0': - resolution: {integrity: sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==} + '@typescript-eslint/project-service@8.61.1': + resolution: {integrity: sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.61.0': - resolution: {integrity: sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==} + '@typescript-eslint/scope-manager@8.61.1': + resolution: {integrity: sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.61.0': - resolution: {integrity: sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==} + '@typescript-eslint/tsconfig-utils@8.61.1': + resolution: {integrity: sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.61.0': - resolution: {integrity: sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==} + '@typescript-eslint/type-utils@8.61.1': + resolution: {integrity: sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.61.0': - resolution: {integrity: sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==} + '@typescript-eslint/types@8.61.1': + resolution: {integrity: sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.61.0': - resolution: {integrity: sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==} + '@typescript-eslint/typescript-estree@8.61.1': + resolution: {integrity: sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.61.0': - resolution: {integrity: sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==} + '@typescript-eslint/utils@8.61.1': + resolution: {integrity: sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.61.0': - resolution: {integrity: sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==} + '@typescript-eslint/visitor-keys@8.61.1': + resolution: {integrity: sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} acorn-jsx@5.3.2: @@ -853,8 +853,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.37: - resolution: {integrity: sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==} + baseline-browser-mapping@2.10.38: + resolution: {integrity: sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==} engines: {node: '>=6.0.0'} hasBin: true @@ -1024,9 +1024,8 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie@1.1.1: - resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} - engines: {node: '>=18'} + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -1185,8 +1184,8 @@ packages: duplexer3@0.1.5: resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} - electron-to-chromium@1.5.372: - resolution: {integrity: sha512-M3yhbAlilnwqC8D21t28UCDGHyitShTmmLRU/H+b74P6Ski16Nb9HONYEaVpMj/pwC7BEo5B95FpjODLCWbtfA==} + electron-to-chromium@1.5.375: + resolution: {integrity: sha512-ZWP5eB4BVPW/ZYo9252hQZHZ5XavtsTgpbhcmMmRwymavC5AsLWQWBPaKMeNd2LW0KGby5HPXvj7+sr4ta5j/Q==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -2160,8 +2159,8 @@ packages: node-html-parser@6.1.13: resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} - node-releases@2.0.47: - resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} + node-releases@2.0.48: + resolution: {integrity: sha512-1uz8041X6LoI6ZSdZacM9lVY28vuzDlSKitnpbSNK0RfKoIJkX29NBPVEFXhnuSuEOA9Ww0xnPJ+ILWbGAv8DA==} engines: {node: '>=18'} normalize-package-data@2.5.0: @@ -2438,12 +2437,12 @@ packages: react-is@19.2.7: resolution: {integrity: sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==} - react-router@7.17.0: - resolution: {integrity: sha512-FDELK7rTMlCHO5+reyXsPlmfr7N1F91lPHsWYfMEGQm/KQ+F4JFM8jGoeQDmDvdTs93Fw9aSilH+uKRb4/jXvQ==} - engines: {node: '>=20.0.0'} + react-router@8.0.1: + resolution: {integrity: sha512-5EL/fANovVUhRK50NLS8RYfX0BxrimoKsHWUPPy8v5UEl8i6vzF7e4POo3u+AhPItDwccUAJjMfIOmydxBJmQw==} + engines: {node: '>=22.22.0'} peerDependencies: - react: '>=18' - react-dom: '>=18' + react: '>=19.2.7' + react-dom: '>=19.2.7' peerDependenciesMeta: react-dom: optional: true @@ -2587,9 +2586,6 @@ packages: engines: {node: '>=10'} hasBin: true - set-cookie-parser@2.7.2: - resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} - set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -2827,8 +2823,8 @@ packages: peerDependencies: typescript: '>=3.5.1' - typescript-eslint@8.61.0: - resolution: {integrity: sha512-8y31Rd0eGTrDKqhy6vT0HtzhN+YLjQizwX3aA3hPXP/ynSfnrBXcQY5IzsP9/DM7+klX4IUncZZjkchP0z+rUw==} + typescript-eslint@8.61.1: + resolution: {integrity: sha512-V7PayAfJokV3pEHgN7/v03D1SpujhRfQtYLbLIiBfDDncdg4PAiRBfoS4cnCANK4jmAPncczi59QO3afiXUlNw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3631,14 +3627,14 @@ snapshots: dependencies: '@types/node': 25.9.3 - '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.61.0(eslint@10.5.0)(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.61.0 - '@typescript-eslint/type-utils': 8.61.0(eslint@10.5.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.0(eslint@10.5.0)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.61.0 + '@typescript-eslint/parser': 8.61.1(eslint@10.5.0)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.61.1 + '@typescript-eslint/type-utils': 8.61.1(eslint@10.5.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.1(eslint@10.5.0)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.1 eslint: 10.5.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -3647,41 +3643,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.61.0(eslint@10.5.0)(typescript@6.0.3)': + '@typescript-eslint/parser@8.61.1(eslint@10.5.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.61.0 - '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.61.0 + '@typescript-eslint/scope-manager': 8.61.1 + '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.1 debug: 4.4.3 eslint: 10.5.0 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.61.0(typescript@6.0.3)': + '@typescript-eslint/project-service@8.61.1(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) - '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@6.0.3) + '@typescript-eslint/types': 8.61.1 debug: 4.4.3 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.61.0': + '@typescript-eslint/scope-manager@8.61.1': dependencies: - '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/visitor-keys': 8.61.0 + '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/visitor-keys': 8.61.1 - '@typescript-eslint/tsconfig-utils@8.61.0(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.61.1(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.61.0(eslint@10.5.0)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.61.1(eslint@10.5.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.0(eslint@10.5.0)(typescript@6.0.3) + '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.1(eslint@10.5.0)(typescript@6.0.3) debug: 4.4.3 eslint: 10.5.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -3689,14 +3685,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.61.0': {} + '@typescript-eslint/types@8.61.1': {} - '@typescript-eslint/typescript-estree@8.61.0(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.61.1(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.61.0(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) - '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/visitor-keys': 8.61.0 + '@typescript-eslint/project-service': 8.61.1(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@6.0.3) + '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/visitor-keys': 8.61.1 debug: 4.4.3 minimatch: 10.2.5 semver: 7.8.4 @@ -3706,20 +3702,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@6.0.3)': + '@typescript-eslint/utils@8.61.1(eslint@10.5.0)(typescript@6.0.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0) - '@typescript-eslint/scope-manager': 8.61.0 - '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.61.1 + '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) eslint: 10.5.0 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.61.0': + '@typescript-eslint/visitor-keys@8.61.1': dependencies: - '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/types': 8.61.1 eslint-visitor-keys: 5.0.1 acorn-jsx@5.3.2(acorn@8.17.0): @@ -3784,7 +3780,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.10.37: {} + baseline-browser-mapping@2.10.38: {} bin-build@3.0.0: dependencies: @@ -3845,10 +3841,10 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.37 + baseline-browser-mapping: 2.10.38 caniuse-lite: 1.0.30001799 - electron-to-chromium: 1.5.372 - node-releases: 2.0.47 + electron-to-chromium: 1.5.375 + node-releases: 2.0.48 update-browserslist-db: 1.2.3(browserslist@4.28.2) buffer-alloc-unsafe@1.1.0: {} @@ -3983,7 +3979,7 @@ snapshots: convert-source-map@2.0.0: {} - cookie@1.1.1: {} + cookie-es@3.1.1: {} core-util-is@1.0.3: {} @@ -4202,7 +4198,7 @@ snapshots: duplexer3@0.1.5: {} - electron-to-chromium@1.5.372: {} + electron-to-chromium@1.5.375: {} emoji-regex@10.6.0: {} @@ -5132,7 +5128,7 @@ snapshots: css-select: 5.2.2 he: 1.2.0 - node-releases@2.0.47: {} + node-releases@2.0.48: {} normalize-package-data@2.5.0: dependencies: @@ -5378,11 +5374,10 @@ snapshots: react-is@19.2.7: {} - react-router@7.17.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + react-router@8.0.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - cookie: 1.1.1 + cookie-es: 3.1.1 react: 19.2.7 - set-cookie-parser: 2.7.2 optionalDependencies: react-dom: 19.2.7(react@19.2.7) @@ -5530,8 +5525,6 @@ snapshots: semver@7.8.4: {} - set-cookie-parser@2.7.2: {} - set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -5753,12 +5746,12 @@ snapshots: dependencies: typescript: 6.0.3 - typescript-eslint@8.61.0(eslint@10.5.0)(typescript@6.0.3): + typescript-eslint@8.61.1(eslint@10.5.0)(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3) - '@typescript-eslint/parser': 8.61.0(eslint@10.5.0)(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.0(eslint@10.5.0)(typescript@6.0.3) + '@typescript-eslint/eslint-plugin': 8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.1(eslint@10.5.0)(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.1(eslint@10.5.0)(typescript@6.0.3) eslint: 10.5.0 typescript: 6.0.3 transitivePeerDependencies: diff --git a/interface/pnpm-workspace.yaml b/interface/pnpm-workspace.yaml index 613c8cdaf..3626b4c8a 100644 --- a/interface/pnpm-workspace.yaml +++ b/interface/pnpm-workspace.yaml @@ -9,3 +9,4 @@ allowBuilds: minimumReleaseAgeExclude: - '@types/node@25.9.2' - '@types/react@19.2.17' + - react-router@8.0.1 diff --git a/interface/src/preact-react-shim.ts b/interface/src/preact-react-shim.ts new file mode 100644 index 000000000..5360c825b --- /dev/null +++ b/interface/src/preact-react-shim.ts @@ -0,0 +1,62 @@ +// preact/compat shim used as the `react` alias. +// +// react-router v8 statically imports/uses a couple of React 19 APIs that +// preact/compat doesn't implement. Aliasing `react` straight to preact/compat +// therefore (a) fails Rolldown's static export analysis during dependency +// optimization / build and (b) could crash at runtime. We re-export everything +// from preact/compat and add the missing pieces: +// +// - useOptimistic: called unconditionally at the top of `RouterProvider` +// (lib/components.js). The optimistic setter is only invoked when +// `unstable_useTransitions === true`, which this app doesn't enable, so a +// passthrough state + no-op setter is correct. +// - use: only invoked (on a promise) in react-router's RSC server-SSR path +// (lib/rsc/server.ssr.js), which a client-only `createBrowserRouter` app +// never executes. It still must exist as an export to avoid Rolldown's +// IMPORT_IS_UNDEFINED warning; we provide a Suspense-style promise unwrap +// just in case it is ever reached. + +// preact/compat's type declarations use CommonJS `export =`, which TypeScript +// won't let us `export *` from, but Rolldown/Vite correctly re-export its named +// members at runtime (this is what makes react-router's `React.useState` etc. +// resolve through the alias). +// @ts-expect-error -- CJS `export =` interop; valid at bundle time. +export * from 'preact/compat'; +export { default } from 'preact/compat'; + +export function useOptimistic(passthrough: S): [S, (action: unknown) => void] { + return [passthrough, () => {}]; +} + +interface TrackedThenable extends PromiseLike { + status?: 'pending' | 'fulfilled' | 'rejected'; + value?: T; + reason?: unknown; +} + +// React 19's `use`, narrowed to the promise-unwrap (Suspense) behavior that +// react-router relies on. +export function use(usable: TrackedThenable): T { + switch (usable.status) { + case 'fulfilled': + return usable.value as T; + case 'rejected': + throw usable.reason; + default: + if (usable.status === undefined) { + usable.status = 'pending'; + void usable.then( + (value) => { + usable.status = 'fulfilled'; + usable.value = value; + }, + (reason) => { + usable.status = 'rejected'; + usable.reason = reason; + } + ); + } + // eslint-disable-next-line @typescript-eslint/only-throw-error -- Suspense throws the thenable + throw usable; + } +} diff --git a/interface/vite.config.ts b/interface/vite.config.ts index e04cdde27..071ee223f 100644 --- a/interface/vite.config.ts +++ b/interface/vite.config.ts @@ -16,10 +16,18 @@ const CHUNK_SIZE_WARNING_LIMIT = 1024; const ASSETS_INLINE_LIMIT = 4096; // Common resolve aliases +// `react` points at a local shim (preact/compat + a useOptimistic stub) because +// react-router v8 statically imports useOptimistic from "react". See src/preact-react-shim.ts for details. +const REACT_SHIM = path.resolve(import.meta.dirname, 'src/preact-react-shim.ts'); +// `react/jsx-runtime` is listed before `react` so the more specific alias wins +// (a bare `react` alias would otherwise also match `react/jsx-runtime`). +// NOTE: @preact/preset-vite is configured with `reactAliasesEnabled: false` +// so these aliases (not the preset's `react -> preact/compat`) are authoritative. const RESOLVE_ALIASES = { - react: 'preact/compat', + 'react/jsx-runtime': 'preact/jsx-runtime', + 'react-dom/test-utils': 'preact/test-utils', 'react-dom': 'preact/compat', - 'react/jsx-runtime': 'preact/jsx-runtime' + react: REACT_SHIM }; // Common resolve extensions - prioritize TypeScript/React files for Windows compatibility @@ -89,42 +97,30 @@ const bundleSizeReporter = (): Plugin => { }; // Common preact plugin config -const createPreactPlugin = (devToolsEnabled: boolean) => - preact({ +const createPreactPlugin = (devToolsEnabled: boolean): PluginOption[] => { + const plugins = preact({ devToolsEnabled, - prefreshEnabled: false + prefreshEnabled: false, + // Disable the preset's built-in `react -> preact/compat` aliases so our + // RESOLVE_ALIASES (which routes `react` through the useOptimistic shim) win. + reactAliasesEnabled: false }); - -// Patch preact/compat to export stub React 19 APIs (use, useOptimistic) so that -// react-router v7 doesn't trigger IMPORT_IS_UNDEFINED warnings from Rolldown. -// Rolldown tracks the constant strings used in `React[REACT_USE]` / -// `React[USE_OPTIMISTIC]` lookups inside react-router and resolves them -// statically, so simply relying on a runtime guard is not enough — we need -// matching (stub) exports on the aliased preact/compat module. -const preactCompatPatchPlugin = (): Plugin => ({ - name: 'preact-compat-react19-patch', - transform(code, id) { - if (id.includes('preact') && id.includes('compat.module.js')) { - return { - code: - code + - '\nexport var use = undefined;\nexport var useOptimistic = undefined;\n', - map: null - }; - } - return undefined; - } -}); + // The preset always registers its devtools-only plugins (`preact:devtools` + // and `preact:transform-hook-names`); the flag only gates their work, not + // their presence. When disabled they're per-module no-ops that still run a + // hook on every module and dominate [PLUGIN_TIMINGS], so drop them entirely. + const devToolsOnly = new Set(['preact:devtools', 'preact:transform-hook-names']); + return devToolsEnabled + ? plugins + : plugins.filter((p) => !p || !devToolsOnly.has(p.name)); +}; // Common base plugins const createBasePlugins = ( devToolsEnabled: boolean, includeBundleReporter = true ): PluginOption[] => { - const plugins: PluginOption[] = [ - createPreactPlugin(devToolsEnabled), - preactCompatPatchPlugin() - ]; + const plugins: PluginOption[] = [...createPreactPlugin(devToolsEnabled)]; if (includeBundleReporter) { plugins.push(bundleSizeReporter()); } diff --git a/mock-api/package.json b/mock-api/package.json index 4cc30636b..411d57f12 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -15,5 +15,5 @@ "itty-router": "^5.0.24", "prettier": "^3.8.4" }, - "packageManager": "pnpm@11.7.0+sha512.19cc852c120c7125760f2443ee6be0ca5b40f9f50598de1a09a1f177503e010e57c23c77646e01e761de59bf874fb22a3398c33ab9691fc13eb946b6f0f4d620" + "packageManager": "pnpm@11.8.0+sha512.c1f5e7c4cb241c8f174b743851d82f42b802324afc8b0f116b96adb15aa06664948dde36960a3ba1079ba5b4b29dd0140135b94b5b5f5263592249d68e555f26" }