From f242ba4b28994ecc894a5410a757e555699636fb Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Thu, 10 Jul 2025 17:20:08 +0800 Subject: [PATCH 01/26] feat: support react compiler --- Cargo.lock | 13 + examples/react-compiler/eslint.config.mjs | 26 + examples/react-compiler/lynx.config.ts | 22 + examples/react-compiler/package.json | 28 + examples/react-compiler/src/App.css | 119 ++++ examples/react-compiler/src/App.tsx | 52 ++ examples/react-compiler/src/assets/arrow.png | Bin 0 -> 80333 bytes .../react-compiler/src/assets/lynx-logo.png | Bin 0 -> 35354 bytes .../react-compiler/src/assets/react-logo.png | Bin 0 -> 33569 bytes examples/react-compiler/src/index.tsx | 11 + examples/react-compiler/src/rspeedy-env.d.ts | 1 + examples/react-compiler/tsconfig.json | 19 + packages/react/transform/Cargo.toml | 2 +- packages/react/transform/index.d.ts | 2 + packages/react/transform/src/lib.rs | 67 +- packages/rspeedy/plugin-react/package.json | 1 + .../plugin-react/src/pluginReactLynx.ts | 12 + .../rspeedy/plugin-react/src/reactCompiler.ts | 23 + pnpm-lock.yaml | 667 +++++++++++++++++- 19 files changed, 1039 insertions(+), 26 deletions(-) create mode 100644 examples/react-compiler/eslint.config.mjs create mode 100644 examples/react-compiler/lynx.config.ts create mode 100644 examples/react-compiler/package.json create mode 100644 examples/react-compiler/src/App.css create mode 100644 examples/react-compiler/src/App.tsx create mode 100644 examples/react-compiler/src/assets/arrow.png create mode 100644 examples/react-compiler/src/assets/lynx-logo.png create mode 100644 examples/react-compiler/src/assets/react-logo.png create mode 100644 examples/react-compiler/src/index.tsx create mode 100644 examples/react-compiler/src/rspeedy-env.d.ts create mode 100644 examples/react-compiler/tsconfig.json create mode 100644 packages/rspeedy/plugin-react/src/reactCompiler.ts diff --git a/Cargo.lock b/Cargo.lock index a6bdca6a76..ea69757863 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2021,6 +2021,7 @@ dependencies = [ "swc_ecma_minifier", "swc_ecma_parser", "swc_ecma_quote_macros", + "swc_ecma_react_compiler", "swc_ecma_transforms_base", "swc_ecma_transforms_optimization", "swc_ecma_transforms_react", @@ -2557,6 +2558,18 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "swc_ecma_react_compiler" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71288c2a921d0e7913fe21afe2076c4cb6ef6475c941e330c623c1da26e3b637" +dependencies = [ + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_visit", +] + [[package]] name = "swc_ecma_testing" version = "10.0.0" diff --git a/examples/react-compiler/eslint.config.mjs b/examples/react-compiler/eslint.config.mjs new file mode 100644 index 0000000000..58228afc9a --- /dev/null +++ b/examples/react-compiler/eslint.config.mjs @@ -0,0 +1,26 @@ +// import { fixupConfigRules } from '@eslint/compat'; +import js from '@eslint/js'; +// import preactJsx from 'eslint-config-preact'; +import reactHooks from 'eslint-plugin-react-hooks'; +import globals from 'globals'; +import ts from 'typescript-eslint'; + +// console.log('preactJsx', preactJsx) + +export default [ + { languageOptions: { globals: globals.browser } }, + js.configs.recommended, + ...ts.configs.recommended, + // ...fixupConfigRules([ + // preactJsx, + // ]), + { + plugins: { + 'react-hooks': reactHooks, + }, + rules: { + ...reactHooks.configs.recommended.rules, + }, + }, + { ignores: ['dist/'] }, +]; diff --git a/examples/react-compiler/lynx.config.ts b/examples/react-compiler/lynx.config.ts new file mode 100644 index 0000000000..b0453b040c --- /dev/null +++ b/examples/react-compiler/lynx.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from '@lynx-js/rspeedy'; +import { pluginQRCode } from '@lynx-js/qrcode-rsbuild-plugin'; +import { pluginReactLynx } from '@lynx-js/react-rsbuild-plugin'; + +const enableBundleAnalysis = !!process.env['RSPEEDY_BUNDLE_ANALYSIS']; + +export default defineConfig({ + plugins: [ + pluginReactLynx({ + experimental_enableReactCompiler: true, + }), + pluginQRCode({ + schema(url) { + // We use `?fullscreen=true` to open the page in LynxExplorer in full screen mode + return `${url}?fullscreen=true`; + }, + }), + ], + performance: { + profile: enableBundleAnalysis, + }, +}); diff --git a/examples/react-compiler/package.json b/examples/react-compiler/package.json new file mode 100644 index 0000000000..fa863f92ce --- /dev/null +++ b/examples/react-compiler/package.json @@ -0,0 +1,28 @@ +{ + "name": "@lynx-js/example-react", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "rspeedy build", + "dev": "rspeedy dev" + }, + "dependencies": { + "@lynx-js/react": "workspace:*" + }, + "devDependencies": { + "@eslint/compat": "^1.3.1", + "@eslint/js": "^9.29.0", + "@lynx-js/qrcode-rsbuild-plugin": "workspace:*", + "@lynx-js/react-rsbuild-plugin": "workspace:*", + "@lynx-js/rspeedy": "workspace:*", + "@lynx-js/types": "3.3.0", + "@types/react": "^18.3.23", + "babel-plugin-react-compiler": "0.0.0-experimental-0566679-20250709", + "eslint": "^9.30.0", + "eslint-config-preact": "^1.5.0", + "eslint-plugin-react-hooks": "5.2.0", + "react-compiler-runtime": "0.0.0-experimental-0566679-20250709", + "typescript-eslint": "^8.34.1" + } +} diff --git a/examples/react-compiler/src/App.css b/examples/react-compiler/src/App.css new file mode 100644 index 0000000000..650e423282 --- /dev/null +++ b/examples/react-compiler/src/App.css @@ -0,0 +1,119 @@ +:root { + background-color: #000; + --color-text: #fff; +} + +.Background { + position: fixed; + background: radial-gradient( + 71.43% 62.3% at 46.43% 36.43%, + rgba(18, 229, 229, 0) 15%, + rgba(239, 155, 255, 0.3) 56.35%, + #ff6448 100% + ); + box-shadow: 0px 12.93px 28.74px 0px #ffd28db2 inset; + border-radius: 50%; + width: 200vw; + height: 200vw; + top: -60vw; + left: -14.27vw; + transform: rotate(15.25deg); +} + +.App { + position: relative; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +text { + color: var(--color-text); +} + +.Banner { + flex: 5; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 100; +} + +.Logo { + flex-direction: column; + align-items: center; + justify-content: center; + margin-bottom: 8px; +} + +.Logo--react { + width: 100px; + height: 100px; + animation: Logo--spin infinite 20s linear; +} + +.Logo--lynx { + width: 100px; + height: 100px; + animation: Logo--shake infinite 0.5s ease; +} + +@keyframes Logo--spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@keyframes Logo--shake { + 0% { + transform: scale(1); + } + 50% { + transform: scale(0.9); + } + 100% { + transform: scale(1); + } +} + +.Content { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.Arrow { + width: 24px; + height: 24px; +} + +.Title { + font-size: 36px; + font-weight: 700; +} + +.Subtitle { + font-style: italic; + font-size: 22px; + font-weight: 600; + margin-bottom: 8px; +} + +.Description { + font-size: 20px; + color: rgba(255, 255, 255, 0.85); + margin: 15rpx; +} + +.Hint { + font-size: 12px; + margin: 5px; + color: rgba(255, 255, 255, 0.65); +} diff --git a/examples/react-compiler/src/App.tsx b/examples/react-compiler/src/App.tsx new file mode 100644 index 0000000000..671297259b --- /dev/null +++ b/examples/react-compiler/src/App.tsx @@ -0,0 +1,52 @@ +import { useCallback, useEffect, useState } from '@lynx-js/react'; + +import './App.css'; +import arrow from './assets/arrow.png'; +import lynxLogo from './assets/lynx-logo.png'; +import reactLynxLogo from './assets/react-logo.png'; + +export function App() { + const [alterLogo, setAlterLogo] = useState(false); + + useEffect(() => { + console.info('Hello, ReactLynx'); + }, []); + + const onTap = useCallback(() => { + 'background-only'; + setAlterLogo(!alterLogo); + }, [alterLogo]); + + return ( + + + + + + {alterLogo + ? + : } + + React + on Lynx + + + + Tap the logo and have fun! + + Edit + {' src/App.tsx '} + + to see updates! + + + + + + ); +} diff --git a/examples/react-compiler/src/assets/arrow.png b/examples/react-compiler/src/assets/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..435c8ad4d1eac4ac17b6133bbcfd0abee2e2ea9a GIT binary patch literal 80333 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%0A{#O-bl;goc^6E=|qMXXm? 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 CZ&Bj_ literal 0 HcmV?d00001 diff --git a/examples/react-compiler/src/assets/react-logo.png b/examples/react-compiler/src/assets/react-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4ad12a6b55ca84c90d321bf6bc0cb074ecf12929 GIT binary patch literal 33569 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 RnhUdH2+Cq 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, +); + +if (import.meta.webpackHot) { + import.meta.webpackHot.accept(); +} diff --git a/examples/react-compiler/src/rspeedy-env.d.ts b/examples/react-compiler/src/rspeedy-env.d.ts new file mode 100644 index 0000000000..1c813a68b0 --- /dev/null +++ b/examples/react-compiler/src/rspeedy-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/examples/react-compiler/tsconfig.json b/examples/react-compiler/tsconfig.json new file mode 100644 index 0000000000..8abbe05638 --- /dev/null +++ b/examples/react-compiler/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "@lynx-js/react", + "noEmit": true, + + "allowJs": true, + "checkJs": true, + "isolatedDeclarations": false, + }, + "include": ["src", "lynx.config.ts", "test"], + "references": [ + { "path": "../../packages/react/tsconfig.json" }, + { "path": "../../packages/rspeedy/core/tsconfig.build.json" }, + { "path": "../../packages/rspeedy/plugin-qrcode/tsconfig.build.json" }, + { "path": "../../packages/rspeedy/plugin-react/tsconfig.build.json" }, + ], +} diff --git a/packages/react/transform/Cargo.toml b/packages/react/transform/Cargo.toml index 8cba113cdb..14466e254a 100644 --- a/packages/react/transform/Cargo.toml +++ b/packages/react/transform/Cargo.toml @@ -19,7 +19,7 @@ rustc-hash = "2.1.1" serde = "1.0.217" serde_json = { version = "1.0.134", features = ["preserve_order"] } sha-1 = "0.10.1" -swc_core = { version = "23.2.0", features = ["base", "ecma_codegen", "ecma_parser", "ecma_minifier", "ecma_transforms_typescript", "ecma_utils", "ecma_quote", "ecma_transforms_react", "ecma_transforms_optimization", "css_parser", "css_ast", "css_visit", "css_codegen", "__visit", "__testing_transform"] } +swc_core = { version = "23.2.0", features = ["base", "ecma_codegen", "ecma_parser", "ecma_minifier", "ecma_transforms_typescript", "ecma_utils", "ecma_quote", "ecma_transforms_react", "ecma_transforms_optimization", "css_parser", "css_ast", "css_visit", "css_codegen", "__visit", "__testing_transform", "swc_ecma_react_compiler"] } version-compare = "0.2.0" [target."cfg(all(target_arch = \"wasm32\", target_os = \"unknown\"))".dependencies.getrandom] diff --git a/packages/react/transform/index.d.ts b/packages/react/transform/index.d.ts index 8cad2293dc..5d890d5151 100644 --- a/packages/react/transform/index.d.ts +++ b/packages/react/transform/index.d.ts @@ -618,3 +618,5 @@ export function transformReactLynxSync(code: string, options?: TransformNodiffOp export function transformReactLynx(code: string, options?: TransformNodiffOptions | undefined | null): Promise export function transformBundleResultSync(code: string, options?: TransformNodiffBundleOptions | undefined | null): TransformNodiffBundleOutput export function transformBundleResult(code: string, options?: TransformNodiffBundleOptions | undefined | null): Promise +export function isReactCompilerRequired(code: Buffer, signal?: AbortSignal | undefined | null): Promise +export function isReactCompilerRequiredSync(code: Buffer): boolean diff --git a/packages/react/transform/src/lib.rs b/packages/react/transform/src/lib.rs index 88fbf4723f..c869d0ac6a 100644 --- a/packages/react/transform/src/lib.rs +++ b/packages/react/transform/src/lib.rs @@ -24,7 +24,10 @@ mod utils; use std::vec; -use napi::{bindgen_prelude::AsyncTask, Either, Env, Task}; +use napi::{ + bindgen_prelude::{AbortSignal, AsyncTask, Buffer}, + Either, Env, Task, +}; use rustc_hash::FxBuildHasher; @@ -45,6 +48,7 @@ use swc_core::{ ast::*, codegen, parser::{Syntax, TsSyntax}, + react_compiler, transforms::{ base::{ fixer::fixer, @@ -761,6 +765,67 @@ pub fn transform_bundle_result( })) } +// from swc: bindings/binding_react_compiler_node/src/support.rs +pub struct IsReactCompilerRequiredTask { + code: String, +} + +#[napi] +impl Task for IsReactCompilerRequiredTask { + type JsValue = bool; + type Output = bool; + + fn compute(&mut self) -> napi::Result { + Ok(is_react_compiler_required_inner(&self.code)) + } + + fn resolve(&mut self, _env: napi::Env, output: Self::Output) -> napi::Result { + Ok(output) + } +} + +fn is_react_compiler_required_inner(code: &str) -> bool { + let cm = Lrc::new(SourceMap::default()); + let fm = cm.new_source_file(FileName::Anon.into(), code.to_string()); + + let program = swc_core::ecma::parser::parse_file_as_program( + &fm, + Syntax::Typescript(swc_core::ecma::parser::TsSyntax { + decorators: true, + tsx: true, + ..Default::default() + }), + EsVersion::latest(), + None, + &mut vec![], + ); + + let Ok(program) = program else { + return false; + }; + + react_compiler::fast_check::is_required(&program) +} + +#[napi] +pub fn is_react_compiler_required( + code: Buffer, + signal: Option, +) -> AsyncTask { + let code = String::from_utf8_lossy(code.as_ref()).to_string(); + + let task = IsReactCompilerRequiredTask { code }; + + AsyncTask::with_optional_signal(task, signal) +} + +#[napi] +pub fn is_react_compiler_required_sync(code: Buffer) -> napi::Result { + let code = String::from_utf8_lossy(code.as_ref()).to_string(); + + Ok(is_react_compiler_required_inner(&code)) +} + #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] mod wasm { use getrandom::register_custom_getrandom; diff --git a/packages/rspeedy/plugin-react/package.json b/packages/rspeedy/plugin-react/package.json index b3a185faf3..5036e2fdda 100644 --- a/packages/rspeedy/plugin-react/package.json +++ b/packages/rspeedy/plugin-react/package.json @@ -54,6 +54,7 @@ "@microsoft/api-extractor": "catalog:", "@rollup/plugin-typescript": "^12.1.4", "@rsbuild/core": "catalog:rsbuild", + "@rsbuild/plugin-babel": "1.0.5", "@rsbuild/plugin-sass": "1.3.3", "@rsbuild/plugin-typed-css-modules": "1.0.2", "@rsbuild/plugin-webpack-swc": "1.1.1", diff --git a/packages/rspeedy/plugin-react/src/pluginReactLynx.ts b/packages/rspeedy/plugin-react/src/pluginReactLynx.ts index 2c6e8e3aeb..3207f18355 100644 --- a/packages/rspeedy/plugin-react/src/pluginReactLynx.ts +++ b/packages/rspeedy/plugin-react/src/pluginReactLynx.ts @@ -27,6 +27,7 @@ import { applyEntry } from './entry.js' import { applyGenerator } from './generator.js' import { applyLazy } from './lazy.js' import { applyLoaders } from './loaders.js' +import { applyReactCompiler } from './reactCompiler.js' import { applyRefresh } from './refresh.js' import { applySplitChunksRule } from './splitChunks.js' import { applySWC } from './swc.js' @@ -305,6 +306,13 @@ export interface PluginReactLynxOptions { * @alpha */ experimental_isLazyBundle?: boolean + + /** + * Enable React Compiler for this build. + * + * @link https://react.dev/learn/react-compiler + */ + experimental_enableReactCompiler?: boolean } /** @@ -355,6 +363,7 @@ export function pluginReactLynx( extractStr: false, experimental_isLazyBundle: false, + experimental_enableReactCompiler: false, } const resolvedOptions = Object.assign(defaultOptions, userOptions, { // Use `engineVersion` to override the default values @@ -414,6 +423,9 @@ export function pluginReactLynx( if (resolvedOptions.experimental_isLazyBundle) { applyLazy(api) } + if (resolvedOptions.experimental_enableReactCompiler) { + await applyReactCompiler(api) + } const rspeedyAPIs = api.useExposed( Symbol.for('rspeedy.api'), diff --git a/packages/rspeedy/plugin-react/src/reactCompiler.ts b/packages/rspeedy/plugin-react/src/reactCompiler.ts new file mode 100644 index 0000000000..913078c642 --- /dev/null +++ b/packages/rspeedy/plugin-react/src/reactCompiler.ts @@ -0,0 +1,23 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import type { RsbuildPluginAPI } from '@rsbuild/core' +import { pluginBabel } from '@rsbuild/plugin-babel' + +const ReactCompilerConfig = { + target: '17', // '17' | '18' | '19' +} + +export function applyReactCompiler( + api: RsbuildPluginAPI, +): void | Promise { + return pluginBabel({ + include: /\.(?:jsx|tsx)$/, + babelLoaderOptions(opts) { + opts.plugins?.unshift([ + 'babel-plugin-react-compiler', + ReactCompilerConfig, + ]) + }, + }).setup(api) +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index daade50c94..459789c8ab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -97,7 +97,7 @@ importers: version: 1.3.3(eslint@9.30.0(jiti@2.4.2)) eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) + version: 2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) eslint-plugin-n: specifier: ^17.20.0 version: 17.20.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) @@ -157,6 +157,52 @@ importers: specifier: ^18.3.23 version: 18.3.23 + examples/react-compiler: + dependencies: + '@lynx-js/react': + specifier: workspace:* + version: link:../../packages/react + devDependencies: + '@eslint/compat': + specifier: ^1.3.1 + version: 1.3.1(eslint@9.30.0(jiti@2.4.2)) + '@eslint/js': + specifier: ^9.29.0 + version: 9.30.0 + '@lynx-js/qrcode-rsbuild-plugin': + specifier: workspace:* + version: link:../../packages/rspeedy/plugin-qrcode + '@lynx-js/react-rsbuild-plugin': + specifier: workspace:* + version: link:../../packages/rspeedy/plugin-react + '@lynx-js/rspeedy': + specifier: workspace:* + version: link:../../packages/rspeedy/core + '@lynx-js/types': + specifier: 3.3.0 + version: 3.3.0 + '@types/react': + specifier: ^18.3.23 + version: 18.3.23 + babel-plugin-react-compiler: + specifier: 0.0.0-experimental-0566679-20250709 + version: 0.0.0-experimental-0566679-20250709 + eslint: + specifier: ^9.30.0 + version: 9.30.0(jiti@2.4.2) + eslint-config-preact: + specifier: ^1.5.0 + version: 1.5.0(eslint@9.30.0(jiti@2.4.2)) + eslint-plugin-react-hooks: + specifier: 5.2.0 + version: 5.2.0(eslint@9.30.0(jiti@2.4.2)) + react-compiler-runtime: + specifier: 0.0.0-experimental-0566679-20250709 + version: 0.0.0-experimental-0566679-20250709(react@19.1.0) + typescript-eslint: + specifier: ^8.34.1 + version: 8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) + examples/tailwindcss: dependencies: '@lynx-js/react': @@ -457,6 +503,9 @@ importers: '@rsbuild/core': specifier: catalog:rsbuild version: 1.4.5 + '@rsbuild/plugin-babel': + specifier: 1.0.5 + version: 1.0.5(@rsbuild/core@1.4.5) '@rsbuild/plugin-sass': specifier: 1.3.3 version: 1.3.3(@rsbuild/core@1.4.5) @@ -1293,28 +1342,77 @@ packages: resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} engines: {node: '>=6.9.0'} + '@babel/eslint-parser@7.28.0': + resolution: {integrity: sha512-N4ntErOlKvcbTt01rr5wj3y55xnIdx1ymrfIr8C2WnM1Y9glFgWaGDEULJIazOX3XM9NRzhfJ6zZnQ1sBNWU+w==} + engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} + peerDependencies: + '@babel/core': ^7.11.0 + eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 + '@babel/generator@7.27.5': resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.0': resolution: {integrity: sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==} engines: {node: '>=6.9.0'} + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.25.9': resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.26.0': resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.27.3': + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.25.9': resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -1327,6 +1425,10 @@ packages: resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + '@babel/helpers@7.27.0': resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==} engines: {node: '>=6.9.0'} @@ -1336,6 +1438,12 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/plugin-proposal-decorators@7.28.0': + resolution: {integrity: sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-async-generators@7.8.4': resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: @@ -1357,6 +1465,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-decorators@7.27.1': + resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-attributes@7.24.7': resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} engines: {node: '>=6.9.0'} @@ -1379,6 +1493,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: @@ -1427,6 +1547,36 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.27.1': + resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.0': + resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.27.1': + resolution: {integrity: sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/runtime@7.25.4': resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==} engines: {node: '>=6.9.0'} @@ -1975,6 +2125,15 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@eslint/compat@1.3.1': + resolution: {integrity: sha512-k8MHony59I5EPic6EQTCNOuPoVBnoYXkP+20xvwFjN7t0qI3ImyvyBgg+hIVPwC8JaxVjjUZld+cLfBLFDLucg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.40 || 9 + peerDependenciesMeta: + eslint: + optional: true + '@eslint/config-array@0.21.0': resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2135,6 +2294,9 @@ packages: resolution: {integrity: sha512-o4ZC8J9OmFT6Ar8hhObWrFe7M7TRFuskm8ROhroZZWdQ+/V1+RswP74wJkkDKY/VDcteKYCACq2PblifRRnj1g==} engines: {node: '>=20.0.0'} + '@mdn/browser-compat-data@5.7.6': + resolution: {integrity: sha512-7xdrMX0Wk7grrTZQwAoy1GkvPMFoizStUoL+VmtUkAxegbCCec+3FKwOM6yc/uGU5+BEczQHXAlWiqvM8JeENg==} + '@mdx-js/loader@3.1.0': resolution: {integrity: sha512-xU/lwKdOyfXtQGqn3VnJjlDrmKXEvMi1mgYxVmukEUtVycIz1nh7oQ40bKTd4cA7rLStqu0740pnhGYxGoqsCg==} peerDependencies: @@ -2266,6 +2428,9 @@ packages: '@napi-rs/wasm-runtime@0.2.11': resolution: {integrity: sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==} + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': + resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2433,6 +2598,11 @@ packages: engines: {node: '>=16.10.0'} hasBin: true + '@rsbuild/plugin-babel@1.0.5': + resolution: {integrity: sha512-g6kZsAREO7c3KEBXRnLbOovIEL/TQDMls2QQFpaGxHx1K7pJB5nNmY1XpTzLCch62xfmBV4crOde0Dow6NAshg==} + peerDependencies: + '@rsbuild/core': 1.x + '@rsbuild/plugin-check-syntax@1.3.0': resolution: {integrity: sha512-lHrd6hToPFVOGWr0U/Ox7pudHWdhPSFsr2riWpjNRlUuwiXdU2SYMROaVUCrLJvYFzJyEMsFOi1w59rBQCG2HQ==} peerDependencies: @@ -2923,6 +3093,18 @@ packages: '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.7': + resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@types/body-parser@1.19.5': resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} @@ -3538,6 +3720,10 @@ packages: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + array.prototype.findlastindex@1.2.6: resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} engines: {node: '>= 0.4'} @@ -3550,6 +3736,10 @@ packages: resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} engines: {node: '>= 0.4'} + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + arraybuffer.prototype.slice@1.0.4: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} @@ -3558,6 +3748,9 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-metadata-inferer@0.8.1: + resolution: {integrity: sha512-ht3Dm6Zr7SXv6t1Ra6gFo0+kLDglHGrEbYihTkcycrbHw7WCcuhBzPlJYHEsIpycaUwzsJHje+vUcxXUX4ztTA==} + ast-v8-to-istanbul@0.3.3: resolution: {integrity: sha512-MuXMrSLVVoA6sYN/6Hke18vMzrT4TZNbZIj/hvh0fnYFpO+/kFXcLIaiPwXXWaQUPg4yJD8fj+lfJ7/1EBconw==} @@ -3583,6 +3776,9 @@ packages: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} + babel-plugin-react-compiler@0.0.0-experimental-0566679-20250709: + resolution: {integrity: sha512-hmaX7GAsWRy4dSEX8eE0KJqLPJKEhHxj9dULwsVM1H2K0wB9PZ+Quj+RZ3G9hLeUmK882nwe1yb+P9hDbMM5Lg==} + babel-preset-current-node-syntax@1.1.0: resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} peerDependencies: @@ -4402,6 +4598,10 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es-iterator-helpers@1.2.1: + resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} @@ -4469,6 +4669,11 @@ packages: peerDependencies: eslint: '>=6.0.0' + eslint-config-preact@1.5.0: + resolution: {integrity: sha512-ELK0QvBNwfdzhjzpKAioqemoupXk/WQocGXMc8aLxKC0//sQwKAhIzAXTHKSYuelG/op45uiTQEq51KCVHkN+A==} + peerDependencies: + eslint: 6.x || 7.x || 8.x + eslint-import-context@0.1.8: resolution: {integrity: sha512-bq+F7nyc65sKpZGT09dY0S0QrOnQtuDVIfyTGQ8uuvtMIF7oHp6CEP3mouN0rrnYF3Jqo6Ke0BfU/5wASZue1w==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -4515,6 +4720,12 @@ packages: eslint-import-resolver-webpack: optional: true + eslint-plugin-compat@4.2.0: + resolution: {integrity: sha512-RDKSYD0maWy5r7zb5cWQS+uSPc26mgOzdORJ8hxILmWM7S/Ncwky7BcAtXVY5iRbKjBdHsWU8Yg7hfoZjtkv7w==} + engines: {node: '>=14.x'} + peerDependencies: + eslint: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint-plugin-es-x@7.8.0: resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -4543,6 +4754,24 @@ packages: peerDependencies: eslint: '>=8.23.0' + eslint-plugin-react-hooks@4.6.2: + resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + eslint-plugin-regexp@2.9.0: resolution: {integrity: sha512-9WqJMnOq8VlE/cK+YAo9C9YHhkOtcEtEk9d12a+H7OSZFwlpI6stiHmYPGa2VE0QhTzodJyhlyprUaXDZLgHBw==} engines: {node: ^18 || >=20} @@ -4563,6 +4792,10 @@ packages: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5520,6 +5753,10 @@ packages: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -5659,6 +5896,10 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -5763,6 +6004,10 @@ packages: longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + loupe@3.1.4: resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} @@ -6193,6 +6438,10 @@ packages: resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + object.fromentries@2.0.8: resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} engines: {node: '>= 0.4'} @@ -6705,6 +6954,9 @@ packages: resolution: {integrity: sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==} engines: {node: '>=8'} + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + property-information@6.5.0: resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} @@ -6752,11 +7004,19 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} + react-compiler-runtime@0.0.0-experimental-0566679-20250709: + resolution: {integrity: sha512-1PTP+pyVfqpjdti2KVo0SrlA18DRYEwuO/zOh83g7qM/8iUttGgxEtMBLByqtHnnNi2RkkC4UQVXQN0Y99Z/WA==} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental + react-dom@19.1.0: resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} peerDependencies: react: ^19.1.0 + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -6942,6 +7202,10 @@ packages: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -7450,6 +7714,13 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + string.prototype.trim@1.2.10: resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} @@ -7916,6 +8187,10 @@ packages: unrs-resolver@1.9.2: resolution: {integrity: sha512-VUyWiTNQD7itdiMuJy+EuLEErLj3uwX/EpHQF8EOf33Dq3Ju6VW1GXm+swk6+1h7a49uv9fKZ+dft9jU7esdLA==} + upath@2.0.1: + resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} + engines: {node: '>=4'} + update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -8380,6 +8655,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/eslint-parser@7.28.0(@babel/core@7.26.10)(eslint@9.30.0(jiti@2.4.2))': + dependencies: + '@babel/core': 7.26.10 + '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 + eslint: 9.30.0(jiti@2.4.2) + eslint-visitor-keys: 2.1.0 + semver: 6.3.1 + '@babel/generator@7.27.5': dependencies: '@babel/parser': 7.27.5 @@ -8388,6 +8671,10 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.27.6 + '@babel/helper-compilation-targets@7.27.0': dependencies: '@babel/compat-data': 7.26.8 @@ -8396,6 +8683,26 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.26.10) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.27.4 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.27.1': + dependencies: + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-imports@7.25.9': dependencies: '@babel/traverse': 7.27.4 @@ -8403,6 +8710,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 @@ -8412,14 +8726,47 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.27.3(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.27.6 + '@babel/helper-plugin-utils@7.25.9': {} + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-replace-supers@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.27.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.27.4 + '@babel/types': 7.27.6 + transitivePeerDependencies: + - supports-color + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.27.1': {} '@babel/helper-validator-option@7.25.9': {} + '@babel/helper-validator-option@7.27.1': {} + '@babel/helpers@7.27.0': dependencies: '@babel/template': 7.27.2 @@ -8429,91 +8776,153 @@ snapshots: dependencies: '@babel/types': 7.27.6 + '@babel/plugin-proposal-decorators@7.28.0(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.26.10) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.26.10) + transitivePeerDependencies: + - supports-color + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-typescript@7.25.4(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.25.9 + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.26.10) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.26.10) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.26.10) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.26.10) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.27.1(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.26.10) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.26.10) + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.26.10) + transitivePeerDependencies: + - supports-color + '@babel/runtime@7.25.4': dependencies: regenerator-runtime: 0.14.1 @@ -8989,6 +9398,10 @@ snapshots: '@eslint-community/regexpp@4.12.1': {} + '@eslint/compat@1.3.1(eslint@9.30.0(jiti@2.4.2))': + optionalDependencies: + eslint: 9.30.0(jiti@2.4.2) + '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 @@ -9198,6 +9611,8 @@ snapshots: js-yaml: 4.1.0 tinyglobby: 0.2.14 + '@mdn/browser-compat-data@5.7.6': {} + '@mdx-js/loader@3.1.0(acorn@8.15.0)(webpack@5.99.9)': dependencies: '@mdx-js/mdx': 3.1.0(acorn@8.15.0) @@ -9384,6 +9799,10 @@ snapshots: '@tybys/wasm-util': 0.9.0 optional: true + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': + dependencies: + eslint-scope: 5.1.1 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -9505,6 +9924,20 @@ snapshots: core-js: 3.44.0 jiti: 2.4.2 + '@rsbuild/plugin-babel@1.0.5(@rsbuild/core@1.4.5)': + dependencies: + '@babel/core': 7.26.10 + '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.26.10) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.26.10) + '@babel/preset-typescript': 7.27.1(@babel/core@7.26.10) + '@rsbuild/core': 1.4.5 + '@types/babel__core': 7.20.5 + deepmerge: 4.3.1 + reduce-configs: 1.1.0 + upath: 2.0.1 + transitivePeerDependencies: + - supports-color + '@rsbuild/plugin-check-syntax@1.3.0(@rsbuild/core@1.4.5)': dependencies: acorn: 8.15.0 @@ -10268,6 +10701,27 @@ snapshots: '@types/aria-query@5.0.4': {} + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.7 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.27.6 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.27.5 + '@babel/types': 7.27.6 + + '@types/babel__traverse@7.20.7': + dependencies: + '@babel/types': 7.27.6 + '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 @@ -10966,6 +11420,15 @@ snapshots: array-union@2.1.0: {} + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + array.prototype.findlastindex@1.2.6: dependencies: call-bind: 1.0.8 @@ -10990,6 +11453,14 @@ snapshots: es-abstract: 1.24.0 es-shim-unscopables: 1.1.0 + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + arraybuffer.prototype.slice@1.0.4: dependencies: array-buffer-byte-length: 1.0.2 @@ -11002,6 +11473,10 @@ snapshots: assertion-error@2.0.1: {} + ast-metadata-inferer@0.8.1: + dependencies: + '@mdn/browser-compat-data': 5.7.6 + ast-v8-to-istanbul@0.3.3: dependencies: '@jridgewell/trace-mapping': 0.3.25 @@ -11028,7 +11503,7 @@ snapshots: babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -11036,6 +11511,10 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-react-compiler@0.0.0-experimental-0566679-20250709: + dependencies: + '@babel/types': 7.27.6 + babel-preset-current-node-syntax@1.1.0(@babel/core@7.26.10): dependencies: '@babel/core': 7.26.10 @@ -11910,6 +12389,25 @@ snapshots: es-errors@1.3.0: {} + es-iterator-helpers@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + safe-array-concat: 1.1.3 + es-module-lexer@1.7.0: {} es-object-atoms@1.1.1: @@ -12021,6 +12519,19 @@ snapshots: eslint: 9.30.0(jiti@2.4.2) semver: 7.7.2 + eslint-config-preact@1.5.0(eslint@9.30.0(jiti@2.4.2)): + dependencies: + '@babel/core': 7.26.10 + '@babel/eslint-parser': 7.28.0(@babel/core@7.26.10)(eslint@9.30.0(jiti@2.4.2)) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.10) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.26.10) + eslint: 9.30.0(jiti@2.4.2) + eslint-plugin-compat: 4.2.0(eslint@9.30.0(jiti@2.4.2)) + eslint-plugin-react: 7.37.5(eslint@9.30.0(jiti@2.4.2)) + eslint-plugin-react-hooks: 4.6.2(eslint@9.30.0(jiti@2.4.2)) + transitivePeerDependencies: + - supports-color + eslint-import-context@0.1.8(unrs-resolver@1.9.2): dependencies: get-tsconfig: 4.10.1 @@ -12047,21 +12558,31 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.9.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) + eslint-plugin-import: 2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): + eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.30.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.30.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color + eslint-plugin-compat@4.2.0(eslint@9.30.0(jiti@2.4.2)): + dependencies: + '@mdn/browser-compat-data': 5.7.6 + ast-metadata-inferer: 0.8.1 + browserslist: 4.24.4 + caniuse-lite: 1.0.30001718 + eslint: 9.30.0(jiti@2.4.2) + find-up: 5.0.0 + lodash.memoize: 4.1.2 + semver: 7.7.2 + eslint-plugin-es-x@7.8.0(eslint@9.30.0(jiti@2.4.2)): dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.0(jiti@2.4.2)) @@ -12073,7 +12594,7 @@ snapshots: dependencies: eslint: 9.30.0(jiti@2.4.2) - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): + eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -12084,7 +12605,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.30.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) + eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -12095,8 +12616,6 @@ snapshots: semver: 6.3.1 string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -12119,6 +12638,36 @@ snapshots: - supports-color - typescript + eslint-plugin-react-hooks@4.6.2(eslint@9.30.0(jiti@2.4.2)): + dependencies: + eslint: 9.30.0(jiti@2.4.2) + + eslint-plugin-react-hooks@5.2.0(eslint@9.30.0(jiti@2.4.2)): + dependencies: + eslint: 9.30.0(jiti@2.4.2) + + eslint-plugin-react@7.37.5(eslint@9.30.0(jiti@2.4.2)): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 9.30.0(jiti@2.4.2) + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + eslint-plugin-regexp@2.9.0(eslint@9.30.0(jiti@2.4.2)): dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.0(jiti@2.4.2)) @@ -12161,6 +12710,8 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-visitor-keys@2.1.0: {} + eslint-visitor-keys@3.4.3: {} eslint-visitor-keys@4.2.1: {} @@ -13290,6 +13841,15 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -13482,6 +14042,13 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -13587,6 +14154,10 @@ snapshots: longest-streak@3.1.0: {} + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + loupe@3.1.4: {} lower-case@2.0.2: @@ -14273,6 +14844,13 @@ snapshots: has-symbols: 1.1.0 object-keys: 1.1.1 + object.entries@1.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + object.fromentries@2.0.8: dependencies: call-bind: 1.0.8 @@ -14761,6 +15339,12 @@ snapshots: dependencies: fromentries: 1.3.2 + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + property-information@6.5.0: {} property-information@7.0.0: {} @@ -14807,11 +15391,17 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 + react-compiler-runtime@0.0.0-experimental-0566679-20250709(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom@19.1.0(react@19.1.0): dependencies: react: 19.1.0 scheduler: 0.26.0 + react-is@16.13.1: {} + react-is@17.0.2: {} react-is@18.3.1: {} @@ -15069,6 +15659,12 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + restore-cursor@3.1.0: dependencies: onetime: 5.1.2 @@ -15644,6 +16240,27 @@ snapshots: get-east-asian-width: 1.2.0 strip-ansi: 7.1.0 + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.0 + string.prototype.trim@1.2.10: dependencies: call-bind: 1.0.8 @@ -16185,6 +16802,8 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.9.2 '@unrs/resolver-binding-win32-x64-msvc': 1.9.2 + upath@2.0.1: {} + update-browserslist-db@1.1.1(browserslist@4.24.4): dependencies: browserslist: 4.24.4 From 3dd46d9e3599585d945c7648cace523c00a2922a Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Thu, 10 Jul 2025 19:40:55 +0800 Subject: [PATCH 02/26] feat: using isReactCompilerRequiredSync --- .changeset/plenty-baboons-tan.md | 5 + .changeset/sour-weeks-wait.md | 15 + packages/react/transform/index.d.ts | 4 +- packages/react/transform/src/lib.rs | 13 +- packages/rspeedy/plugin-react/src/loaders.ts | 3 + .../webpack/react-webpack-plugin/package.json | 3 + .../src/ReactWebpackPlugin.ts | 3 +- .../src/loaders/react-compiler.ts | 47 ++++ pnpm-lock.yaml | 265 ++++++++++++++---- 9 files changed, 290 insertions(+), 68 deletions(-) create mode 100644 .changeset/plenty-baboons-tan.md create mode 100644 .changeset/sour-weeks-wait.md create mode 100644 packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts diff --git a/.changeset/plenty-baboons-tan.md b/.changeset/plenty-baboons-tan.md new file mode 100644 index 0000000000..a405cd64bb --- /dev/null +++ b/.changeset/plenty-baboons-tan.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/react-webpack-plugin": patch +--- + +Add React Compiler loader, which uses `babel-plugin-react-compiler` to transform user code to optimized code before ReactLynx transform. diff --git a/.changeset/sour-weeks-wait.md b/.changeset/sour-weeks-wait.md new file mode 100644 index 0000000000..f80f536713 --- /dev/null +++ b/.changeset/sour-weeks-wait.md @@ -0,0 +1,15 @@ +--- +"@lynx-js/react-rsbuild-plugin": patch +--- + +Support [React Compiler](https://react.dev/learn/react-compiler) for ReactLynx, enable it by set `experimental_enableReactCompiler` to `true` in `lynx.config.js`: + +```js +export default defineConfig({ + plugins: [ + pluginReactLynx({ + experimental_enableReactCompiler: true, + }), + ], +}); +``` diff --git a/packages/react/transform/index.d.ts b/packages/react/transform/index.d.ts index 5d890d5151..4635dca3c8 100644 --- a/packages/react/transform/index.d.ts +++ b/packages/react/transform/index.d.ts @@ -618,5 +618,5 @@ export function transformReactLynxSync(code: string, options?: TransformNodiffOp export function transformReactLynx(code: string, options?: TransformNodiffOptions | undefined | null): Promise export function transformBundleResultSync(code: string, options?: TransformNodiffBundleOptions | undefined | null): TransformNodiffBundleOutput export function transformBundleResult(code: string, options?: TransformNodiffBundleOptions | undefined | null): Promise -export function isReactCompilerRequired(code: Buffer, signal?: AbortSignal | undefined | null): Promise -export function isReactCompilerRequiredSync(code: Buffer): boolean +export function isReactCompilerRequired(code: string, signal?: AbortSignal | undefined | null): Promise +export function isReactCompilerRequiredSync(code: string): boolean diff --git a/packages/react/transform/src/lib.rs b/packages/react/transform/src/lib.rs index c869d0ac6a..8ad414bd5e 100644 --- a/packages/react/transform/src/lib.rs +++ b/packages/react/transform/src/lib.rs @@ -25,7 +25,7 @@ mod utils; use std::vec; use napi::{ - bindgen_prelude::{AbortSignal, AsyncTask, Buffer}, + bindgen_prelude::{AbortSignal, AsyncTask}, Either, Env, Task, }; @@ -809,20 +809,17 @@ fn is_react_compiler_required_inner(code: &str) -> bool { #[napi] pub fn is_react_compiler_required( - code: Buffer, + _env: Env, + code: String, signal: Option, ) -> AsyncTask { - let code = String::from_utf8_lossy(code.as_ref()).to_string(); - let task = IsReactCompilerRequiredTask { code }; AsyncTask::with_optional_signal(task, signal) } #[napi] -pub fn is_react_compiler_required_sync(code: Buffer) -> napi::Result { - let code = String::from_utf8_lossy(code.as_ref()).to_string(); - +pub fn is_react_compiler_required_sync(_env: Env, code: String) -> napi::Result { Ok(is_react_compiler_required_inner(&code)) } @@ -895,6 +892,8 @@ mod wasm { let _ = exports.create_named_method("transformBundleResultSync", crate::__napi__transform_bundle_result_sync); let _ = exports.create_named_method("transformReactLynx", crate::__napi__transform_react_lynx); let _ = exports.create_named_method("transformBundleResult", crate::__napi__transform_bundle_result); + let _ = exports.create_named_method("isReactCompilerRequiredSync", crate::__napi__is_react_compiler_required_sync); + let _ = exports.create_named_method("isReactCompilerRequired", crate::__napi__is_react_compiler_required); } } } diff --git a/packages/rspeedy/plugin-react/src/loaders.ts b/packages/rspeedy/plugin-react/src/loaders.ts index 5184e1a69e..33cfb46013 100644 --- a/packages/rspeedy/plugin-react/src/loaders.ts +++ b/packages/rspeedy/plugin-react/src/loaders.ts @@ -110,5 +110,8 @@ export function applyLoaders( // Clear the Rsbuild default loader. // Otherwise, the JSX will be transformed by the `builtin:swc-loader`. rule.uses.clear() + + rule.use('react-compiler') + .loader(ReactWebpackPlugin.loaders.REACT_COMPILER) }) } diff --git a/packages/webpack/react-webpack-plugin/package.json b/packages/webpack/react-webpack-plugin/package.json index 4a86bfd7e1..f443fa305b 100644 --- a/packages/webpack/react-webpack-plugin/package.json +++ b/packages/webpack/react-webpack-plugin/package.json @@ -41,6 +41,8 @@ "tiny-invariant": "^1.3.3" }, "devDependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-syntax-jsx": "^7.27.1", "@lynx-js/css-extract-webpack-plugin": "workspace:*", "@lynx-js/react": "workspace:*", "@lynx-js/template-webpack-plugin": "workspace:*", @@ -48,6 +50,7 @@ "@lynx-js/vitest-setup": "workspace:*", "@microsoft/api-extractor": "catalog:", "@rspack/core": "catalog:rspack", + "babel-plugin-react-compiler": "0.0.0-experimental-0566679-20250709", "css-loader": "^7.1.2", "swc-loader": "^0.2.6", "webpack": "^5.99.9" diff --git a/packages/webpack/react-webpack-plugin/src/ReactWebpackPlugin.ts b/packages/webpack/react-webpack-plugin/src/ReactWebpackPlugin.ts index d0faac535c..5914c8cf2e 100644 --- a/packages/webpack/react-webpack-plugin/src/ReactWebpackPlugin.ts +++ b/packages/webpack/react-webpack-plugin/src/ReactWebpackPlugin.ts @@ -114,9 +114,10 @@ class ReactWebpackPlugin { * * @public */ - static loaders: Record = { + static loaders: Record = { BACKGROUND: require.resolve('../lib/loaders/background.js'), MAIN_THREAD: require.resolve('../lib/loaders/main-thread.js'), + REACT_COMPILER: require.resolve('../lib/loaders/react-compiler.js'), }; constructor( diff --git a/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts b/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts new file mode 100644 index 0000000000..5d1e5c0691 --- /dev/null +++ b/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts @@ -0,0 +1,47 @@ +// Copyright 2025 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import { createRequire } from 'node:module'; + +import babel from '@babel/core'; +import type { LoaderContext } from '@rspack/core'; +import BabelPluginReactCompiler from 'babel-plugin-react-compiler'; + +import type { ReactLoaderOptions } from './options.js'; + +function reactCompilerLoader( + this: LoaderContext, + content: string, +): void { + const require = createRequire(import.meta.url); + const { transformPath = '@lynx-js/react/transform' } = this.getOptions(); + const { isReactCompilerRequiredSync } = require( + transformPath, + ) as typeof import('@lynx-js/react/transform'); + if (/\.(?:jsx|tsx)$/.test(this.resourcePath)) { + const isReactCompilerRequired = isReactCompilerRequiredSync(content); + if (isReactCompilerRequired) { + const result = babel.transformSync(content, { + plugins: [ + [BabelPluginReactCompiler, { target: '17' }], + '@babel/plugin-syntax-jsx', + ], + filename: this.resourcePath, + ast: false, + sourceMaps: true, + }); + if (result?.code && result?.map) { + this.callback(null, result.code, JSON.stringify(result.map)); + return; + } else { + this.callback( + new Error('babel-plugin-react-compiler transform failed'), + ); + return; + } + } + } + this.callback(null, content); +} + +export default reactCompilerLoader; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 459789c8ab..de07da312c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -97,7 +97,7 @@ importers: version: 1.3.3(eslint@9.30.0(jiti@2.4.2)) eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) + version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) eslint-plugin-n: specifier: ^17.20.0 version: 17.20.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) @@ -1029,6 +1029,24 @@ importers: specifier: ^1.3.3 version: 1.3.3 devDependencies: + '@babel/core': + specifier: ^7.28.0 + version: 7.28.0 + '@babel/generator': + specifier: ^7.28.0 + version: 7.28.0 + '@babel/parser': + specifier: ^7.28.0 + version: 7.28.0 + '@babel/plugin-syntax-jsx': + specifier: ^7.27.1 + version: 7.27.1(@babel/core@7.28.0) + '@babel/traverse': + specifier: ^7.28.0 + version: 7.28.0 + '@babel/types': + specifier: ^7.28.0 + version: 7.28.0 '@lynx-js/css-extract-webpack-plugin': specifier: workspace:* version: link:../css-extract-webpack-plugin @@ -1050,6 +1068,18 @@ importers: '@rspack/core': specifier: 1.4.5 version: 1.4.5(@swc/helpers@0.5.17) + '@types/babel__core': + specifier: ^7.20.5 + version: 7.20.5 + '@types/babel__generator': + specifier: ^7.27.0 + version: 7.27.0 + '@types/babel__traverse': + specifier: ^7.20.7 + version: 7.20.7 + babel-plugin-react-compiler: + specifier: 0.0.0-experimental-0566679-20250709 + version: 0.0.0-experimental-0566679-20250709 css-loader: specifier: ^7.1.2 version: 7.1.2(@rspack/core@1.4.5(@swc/helpers@0.5.17))(webpack@5.99.9(@swc/core@1.7.35(@swc/helpers@0.5.17))) @@ -1338,10 +1368,18 @@ packages: resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.28.0': + resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} + engines: {node: '>=6.9.0'} + '@babel/core@7.26.10': resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} engines: {node: '>=6.9.0'} + '@babel/core@7.28.0': + resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} + engines: {node: '>=6.9.0'} + '@babel/eslint-parser@7.28.0': resolution: {integrity: sha512-N4ntErOlKvcbTt01rr5wj3y55xnIdx1ymrfIr8C2WnM1Y9glFgWaGDEULJIazOX3XM9NRzhfJ6zZnQ1sBNWU+w==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} @@ -1353,6 +1391,10 @@ packages: resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==} engines: {node: '>=6.9.0'} + '@babel/generator@7.28.0': + resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} @@ -1361,12 +1403,20 @@ packages: resolution: {integrity: sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==} engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-create-class-features-plugin@7.27.1': resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@7.27.1': resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} engines: {node: '>=6.9.0'} @@ -1395,10 +1445,6 @@ packages: resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.25.9': - resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} - engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.27.1': resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} @@ -1433,11 +1479,20 @@ packages: resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==} engines: {node: '>=6.9.0'} + '@babel/helpers@7.27.6': + resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.27.5': resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.28.0': + resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-proposal-decorators@7.28.0': resolution: {integrity: sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==} engines: {node: '>=6.9.0'} @@ -1487,12 +1542,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.25.9': - resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.27.1': resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} engines: {node: '>=6.9.0'} @@ -1589,10 +1638,18 @@ packages: resolution: {integrity: sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.28.0': + resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} + engines: {node: '>=6.9.0'} + '@babel/types@7.27.6': resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.0': + resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} @@ -2225,6 +2282,9 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/gen-mapping@0.3.12': + resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -2246,6 +2306,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.29': + resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@jsonjoy.com/base64@1.1.2': resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} engines: {node: '>=10.0'} @@ -8635,6 +8698,8 @@ snapshots: '@babel/compat-data@7.26.8': {} + '@babel/compat-data@7.28.0': {} + '@babel/core@7.26.10': dependencies: '@ampproject/remapping': 2.3.0 @@ -8643,10 +8708,30 @@ snapshots: '@babel/helper-compilation-targets': 7.27.0 '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) '@babel/helpers': 7.27.0 - '@babel/parser': 7.27.5 + '@babel/parser': 7.28.0 '@babel/template': 7.27.2 '@babel/traverse': 7.27.4 - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.28.0': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@babel/helpers': 7.27.6 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 convert-source-map: 2.0.0 debug: 4.4.1 gensync: 1.0.0-beta.2 @@ -8665,15 +8750,23 @@ snapshots: '@babel/generator@7.27.5': dependencies: - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 + '@babel/generator@7.28.0': + dependencies: + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 '@babel/helper-compilation-targets@7.27.0': dependencies: @@ -8683,6 +8776,14 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 @@ -8691,29 +8792,31 @@ snapshots: '@babel/helper-optimise-call-expression': 7.27.1 '@babel/helper-replace-supers': 7.27.1(@babel/core@7.26.10) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.27.4 + '@babel/traverse': 7.28.0 semver: 6.3.1 transitivePeerDependencies: - supports-color + '@babel/helper-globals@7.28.0': {} + '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.27.4 - '@babel/types': 7.27.6 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.25.9': dependencies: - '@babel/traverse': 7.27.4 - '@babel/types': 7.27.6 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.27.4 - '@babel/types': 7.27.6 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color @@ -8722,7 +8825,7 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-module-imports': 7.25.9 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.27.4 + '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color @@ -8731,15 +8834,22 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.27.4 + '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-optimise-call-expression@7.27.1': + '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': dependencies: - '@babel/types': 7.27.6 + '@babel/core': 7.28.0 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.0 + transitivePeerDependencies: + - supports-color - '@babel/helper-plugin-utils@7.25.9': {} + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.28.0 '@babel/helper-plugin-utils@7.27.1': {} @@ -8748,14 +8858,14 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.27.4 + '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.27.4 - '@babel/types': 7.27.6 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color @@ -8770,11 +8880,20 @@ snapshots: '@babel/helpers@7.27.0': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 + + '@babel/helpers@7.27.6': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.0 '@babel/parser@7.27.5': dependencies: - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 + + '@babel/parser@7.28.0': + dependencies: + '@babel/types': 7.28.0 '@babel/plugin-proposal-decorators@7.28.0(@babel/core@7.26.10)': dependencies: @@ -8825,14 +8944,14 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.26.10)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.10)': @@ -8878,7 +8997,7 @@ snapshots: '@babel/plugin-syntax-typescript@7.25.4(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.26.10)': dependencies: @@ -8930,26 +9049,43 @@ snapshots: '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 '@babel/traverse@7.27.4': dependencies: '@babel/code-frame': 7.27.1 '@babel/generator': 7.27.5 - '@babel/parser': 7.27.5 + '@babel/parser': 7.28.0 '@babel/template': 7.27.2 - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 debug: 4.4.1 globals: 11.12.0 transitivePeerDependencies: - supports-color + '@babel/traverse@7.28.0': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/types': 7.28.0 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + '@babel/types@7.27.6': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@7.28.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@bcoe/v8-coverage@1.0.2': {} '@biomejs/biome@1.9.4': @@ -9532,6 +9668,11 @@ snapshots: '@types/yargs': 17.0.33 chalk: 4.1.2 + '@jridgewell/gen-mapping@0.3.12': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.29 + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -9554,6 +9695,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.29': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': dependencies: tslib: 2.8.1 @@ -10703,24 +10849,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.7 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 '@types/babel__traverse@7.20.7': dependencies: - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 '@types/body-parser@1.19.5': dependencies: @@ -11513,7 +11659,7 @@ snapshots: babel-plugin-react-compiler@0.0.0-experimental-0566679-20250709: dependencies: - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 babel-preset-current-node-syntax@1.1.0(@babel/core@7.26.10): dependencies: @@ -12558,14 +12704,15 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.9.2 optionalDependencies: - eslint-plugin-import: 2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: + '@typescript-eslint/parser': 8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.30.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.30.0(jiti@2.4.2)) @@ -12594,7 +12741,7 @@ snapshots: dependencies: eslint: 9.30.0(jiti@2.4.2) - eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -12605,7 +12752,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.30.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -12616,6 +12763,8 @@ snapshots: semver: 6.3.1 string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13788,7 +13937,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.26.10 - '@babel/parser': 7.27.5 + '@babel/parser': 7.28.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -13798,7 +13947,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 7.26.10 - '@babel/parser': 7.27.5 + '@babel/parser': 7.28.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.7.2 @@ -13912,9 +14061,9 @@ snapshots: dependencies: '@babel/core': 7.26.10 '@babel/generator': 7.27.5 - '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.26.10) '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.26.10) - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 @@ -14185,7 +14334,7 @@ snapshots: magicast@0.3.5: dependencies: '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 source-map-js: 1.2.1 make-dir@3.1.0: From da7ffeb38a9468e5242ded0e2105fa1b066044b6 Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Thu, 10 Jul 2025 19:51:57 +0800 Subject: [PATCH 03/26] chore: clean files --- examples/react-compiler/eslint.config.mjs | 7 ------ .../rspeedy/plugin-react/src/reactCompiler.ts | 23 ------------------- 2 files changed, 30 deletions(-) delete mode 100644 packages/rspeedy/plugin-react/src/reactCompiler.ts diff --git a/examples/react-compiler/eslint.config.mjs b/examples/react-compiler/eslint.config.mjs index 58228afc9a..e6e67b6635 100644 --- a/examples/react-compiler/eslint.config.mjs +++ b/examples/react-compiler/eslint.config.mjs @@ -1,19 +1,12 @@ -// import { fixupConfigRules } from '@eslint/compat'; import js from '@eslint/js'; -// import preactJsx from 'eslint-config-preact'; import reactHooks from 'eslint-plugin-react-hooks'; import globals from 'globals'; import ts from 'typescript-eslint'; -// console.log('preactJsx', preactJsx) - export default [ { languageOptions: { globals: globals.browser } }, js.configs.recommended, ...ts.configs.recommended, - // ...fixupConfigRules([ - // preactJsx, - // ]), { plugins: { 'react-hooks': reactHooks, diff --git a/packages/rspeedy/plugin-react/src/reactCompiler.ts b/packages/rspeedy/plugin-react/src/reactCompiler.ts deleted file mode 100644 index 913078c642..0000000000 --- a/packages/rspeedy/plugin-react/src/reactCompiler.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2024 The Lynx Authors. All rights reserved. -// Licensed under the Apache License Version 2.0 that can be found in the -// LICENSE file in the root directory of this source tree. -import type { RsbuildPluginAPI } from '@rsbuild/core' -import { pluginBabel } from '@rsbuild/plugin-babel' - -const ReactCompilerConfig = { - target: '17', // '17' | '18' | '19' -} - -export function applyReactCompiler( - api: RsbuildPluginAPI, -): void | Promise { - return pluginBabel({ - include: /\.(?:jsx|tsx)$/, - babelLoaderOptions(opts) { - opts.plugins?.unshift([ - 'babel-plugin-react-compiler', - ReactCompilerConfig, - ]) - }, - }).setup(api) -} From acc732c57c200a8ac577d29b96a493c791e9905a Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Mon, 14 Jul 2025 18:08:11 +0800 Subject: [PATCH 04/26] feat: using @babel/core from user project --- examples/react-compiler/package.json | 2 + packages/rspeedy/plugin-react/src/loaders.ts | 3 - .../plugin-react/src/pluginReactLynx.ts | 2 +- .../rspeedy/plugin-react/src/reactCompiler.ts | 27 ++ .../webpack/react-webpack-plugin/package.json | 2 +- .../src/loaders/react-compiler.ts | 80 +++-- pnpm-lock.yaml | 327 ++++++------------ 7 files changed, 193 insertions(+), 250 deletions(-) create mode 100644 packages/rspeedy/plugin-react/src/reactCompiler.ts diff --git a/examples/react-compiler/package.json b/examples/react-compiler/package.json index fa863f92ce..f34ac77ec5 100644 --- a/examples/react-compiler/package.json +++ b/examples/react-compiler/package.json @@ -11,6 +11,8 @@ "@lynx-js/react": "workspace:*" }, "devDependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-syntax-jsx": "^7.27.1", "@eslint/compat": "^1.3.1", "@eslint/js": "^9.29.0", "@lynx-js/qrcode-rsbuild-plugin": "workspace:*", diff --git a/packages/rspeedy/plugin-react/src/loaders.ts b/packages/rspeedy/plugin-react/src/loaders.ts index 33cfb46013..5184e1a69e 100644 --- a/packages/rspeedy/plugin-react/src/loaders.ts +++ b/packages/rspeedy/plugin-react/src/loaders.ts @@ -110,8 +110,5 @@ export function applyLoaders( // Clear the Rsbuild default loader. // Otherwise, the JSX will be transformed by the `builtin:swc-loader`. rule.uses.clear() - - rule.use('react-compiler') - .loader(ReactWebpackPlugin.loaders.REACT_COMPILER) }) } diff --git a/packages/rspeedy/plugin-react/src/pluginReactLynx.ts b/packages/rspeedy/plugin-react/src/pluginReactLynx.ts index 3207f18355..906493e80a 100644 --- a/packages/rspeedy/plugin-react/src/pluginReactLynx.ts +++ b/packages/rspeedy/plugin-react/src/pluginReactLynx.ts @@ -424,7 +424,7 @@ export function pluginReactLynx( applyLazy(api) } if (resolvedOptions.experimental_enableReactCompiler) { - await applyReactCompiler(api) + applyReactCompiler(api, resolvedOptions) } const rspeedyAPIs = api.useExposed( diff --git a/packages/rspeedy/plugin-react/src/reactCompiler.ts b/packages/rspeedy/plugin-react/src/reactCompiler.ts new file mode 100644 index 0000000000..0fdfa39697 --- /dev/null +++ b/packages/rspeedy/plugin-react/src/reactCompiler.ts @@ -0,0 +1,27 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import type { RsbuildPluginAPI } from '@rsbuild/core' + +import { ReactWebpackPlugin } from '@lynx-js/react-webpack-plugin' + +import type { PluginReactLynxOptions } from './pluginReactLynx.js' + +export function applyReactCompiler( + api: RsbuildPluginAPI, + options: Required, +): void { + const { + experimental_enableReactCompiler, + } = options + + api.modifyBundlerChain((chain, { CHAIN_ID }) => { + const rule = chain.module.rules.get(CHAIN_ID.RULE.JS) + + if (experimental_enableReactCompiler) { + rule.use('react-compiler') + .loader(ReactWebpackPlugin.loaders.REACT_COMPILER) + .end() + } + }) +} diff --git a/packages/webpack/react-webpack-plugin/package.json b/packages/webpack/react-webpack-plugin/package.json index f443fa305b..6f035014dc 100644 --- a/packages/webpack/react-webpack-plugin/package.json +++ b/packages/webpack/react-webpack-plugin/package.json @@ -41,7 +41,6 @@ "tiny-invariant": "^1.3.3" }, "devDependencies": { - "@babel/core": "^7.28.0", "@babel/plugin-syntax-jsx": "^7.27.1", "@lynx-js/css-extract-webpack-plugin": "workspace:*", "@lynx-js/react": "workspace:*", @@ -50,6 +49,7 @@ "@lynx-js/vitest-setup": "workspace:*", "@microsoft/api-extractor": "catalog:", "@rspack/core": "catalog:rspack", + "@types/babel__core": "^7.20.5", "babel-plugin-react-compiler": "0.0.0-experimental-0566679-20250709", "css-loader": "^7.1.2", "swc-loader": "^0.2.6", diff --git a/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts b/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts index 5d1e5c0691..ea79fbcb8d 100644 --- a/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts +++ b/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts @@ -3,45 +3,77 @@ // LICENSE file in the root directory of this source tree. import { createRequire } from 'node:module'; -import babel from '@babel/core'; import type { LoaderContext } from '@rspack/core'; -import BabelPluginReactCompiler from 'babel-plugin-react-compiler'; import type { ReactLoaderOptions } from './options.js'; -function reactCompilerLoader( +async function reactCompilerLoader( this: LoaderContext, content: string, -): void { +): Promise { + const callback = this.async(); const require = createRequire(import.meta.url); const { transformPath = '@lynx-js/react/transform' } = this.getOptions(); - const { isReactCompilerRequiredSync } = require( + const { isReactCompilerRequired } = require( transformPath, ) as typeof import('@lynx-js/react/transform'); if (/\.(?:jsx|tsx)$/.test(this.resourcePath)) { - const isReactCompilerRequired = isReactCompilerRequiredSync(content); - if (isReactCompilerRequired) { - const result = babel.transformSync(content, { - plugins: [ - [BabelPluginReactCompiler, { target: '17' }], + const needReactCompiler = await isReactCompilerRequired(content); + if (needReactCompiler) { + try { + const missingBabelPackages: string[] = []; + const [ + babelPath, + babelPluginReactCompilerPath, + babelPluginSyntaxJsxPath, + ] = [ + '@babel/core', + 'babel-plugin-react-compiler', '@babel/plugin-syntax-jsx', - ], - filename: this.resourcePath, - ast: false, - sourceMaps: true, - }); - if (result?.code && result?.map) { - this.callback(null, result.code, JSON.stringify(result.map)); - return; - } else { - this.callback( - new Error('babel-plugin-react-compiler transform failed'), - ); - return; + ].map((name) => { + try { + return require.resolve(name, { + paths: [this.rootContext], + }); + } catch { + missingBabelPackages.push(name); + } + return ''; + }); + if (missingBabelPackages.length > 0) { + throw new Error( + `With \`experimental_enableReactCompiler\` enabled, you need to install \`${ + missingBabelPackages.join( + '`, `', + ) + }\` in your project root to use React Compiler.`, + ); + } + + const babel = require(babelPath!) as typeof import('@babel/core'); + + const result = babel.transformSync(content, { + plugins: [ + [babelPluginReactCompilerPath!, { target: '17' }], + babelPluginSyntaxJsxPath!, + ], + filename: this.resourcePath, + ast: false, + sourceMaps: true, + }); + if (result?.code && result?.map) { + return callback(null, result.code, JSON.stringify(result.map)); + } else { + return callback( + new Error('babel-plugin-react-compiler transform failed'), + ); + } + } catch (e) { + return callback(e as Error); } } } - this.callback(null, content); + return callback(null, content); } export default reactCompilerLoader; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index de07da312c..b8a0645a93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -97,7 +97,7 @@ importers: version: 1.3.3(eslint@9.30.0(jiti@2.4.2)) eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) + version: 2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) eslint-plugin-n: specifier: ^17.20.0 version: 17.20.0(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) @@ -163,6 +163,12 @@ importers: specifier: workspace:* version: link:../../packages/react devDependencies: + '@babel/core': + specifier: ^7.28.0 + version: 7.28.0 + '@babel/plugin-syntax-jsx': + specifier: ^7.27.1 + version: 7.27.1(@babel/core@7.28.0) '@eslint/compat': specifier: ^1.3.1 version: 1.3.1(eslint@9.30.0(jiti@2.4.2)) @@ -1029,24 +1035,9 @@ importers: specifier: ^1.3.3 version: 1.3.3 devDependencies: - '@babel/core': - specifier: ^7.28.0 - version: 7.28.0 - '@babel/generator': - specifier: ^7.28.0 - version: 7.28.0 - '@babel/parser': - specifier: ^7.28.0 - version: 7.28.0 '@babel/plugin-syntax-jsx': specifier: ^7.27.1 version: 7.27.1(@babel/core@7.28.0) - '@babel/traverse': - specifier: ^7.28.0 - version: 7.28.0 - '@babel/types': - specifier: ^7.28.0 - version: 7.28.0 '@lynx-js/css-extract-webpack-plugin': specifier: workspace:* version: link:../css-extract-webpack-plugin @@ -1071,12 +1062,6 @@ importers: '@types/babel__core': specifier: ^7.20.5 version: 7.20.5 - '@types/babel__generator': - specifier: ^7.27.0 - version: 7.27.0 - '@types/babel__traverse': - specifier: ^7.20.7 - version: 7.20.7 babel-plugin-react-compiler: specifier: 0.0.0-experimental-0566679-20250709 version: 0.0.0-experimental-0566679-20250709 @@ -1364,18 +1349,10 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.8': - resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} - engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.0': resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} engines: {node: '>=6.9.0'} - '@babel/core@7.26.10': - resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} - engines: {node: '>=6.9.0'} - '@babel/core@7.28.0': resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} engines: {node: '>=6.9.0'} @@ -1399,10 +1376,6 @@ packages: resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.0': - resolution: {integrity: sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==} - engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.27.2': resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} @@ -1421,20 +1394,10 @@ packages: resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.25.9': - resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} - engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.27.1': resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.26.0': - resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-module-transforms@7.27.3': resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} engines: {node: '>=6.9.0'} @@ -1467,18 +1430,10 @@ packages: resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.9': - resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.27.0': - resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==} - engines: {node: '>=6.9.0'} - '@babel/helpers@7.27.6': resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} engines: {node: '>=6.9.0'} @@ -8696,30 +8651,8 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.26.8': {} - '@babel/compat-data@7.28.0': {} - '@babel/core@7.26.10': - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.27.5 - '@babel/helper-compilation-targets': 7.27.0 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) - '@babel/helpers': 7.27.0 - '@babel/parser': 7.28.0 - '@babel/template': 7.27.2 - '@babel/traverse': 7.27.4 - '@babel/types': 7.28.0 - convert-source-map: 2.0.0 - debug: 4.4.1 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/core@7.28.0': dependencies: '@ampproject/remapping': 2.3.0 @@ -8740,9 +8673,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/eslint-parser@7.28.0(@babel/core@7.26.10)(eslint@9.30.0(jiti@2.4.2))': + '@babel/eslint-parser@7.28.0(@babel/core@7.28.0)(eslint@9.30.0(jiti@2.4.2))': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 eslint: 9.30.0(jiti@2.4.2) eslint-visitor-keys: 2.1.0 @@ -8768,14 +8701,6 @@ snapshots: dependencies: '@babel/types': 7.28.0 - '@babel/helper-compilation-targets@7.27.0': - dependencies: - '@babel/compat-data': 7.26.8 - '@babel/helper-validator-option': 7.25.9 - browserslist: 4.24.4 - lru-cache: 5.1.1 - semver: 6.3.1 - '@babel/helper-compilation-targets@7.27.2': dependencies: '@babel/compat-data': 7.28.0 @@ -8784,13 +8709,13 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.26.10)': + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.26.10) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.0) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 '@babel/traverse': 7.28.0 semver: 6.3.1 @@ -8806,13 +8731,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.25.9': - dependencies: - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.0 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.28.0 @@ -8820,24 +8738,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.27.3(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.0 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -8853,9 +8753,9 @@ snapshots: '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-replace-supers@7.27.1(@babel/core@7.26.10)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 '@babel/traverse': 7.28.0 @@ -8873,15 +8773,8 @@ snapshots: '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-option@7.25.9': {} - '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.27.0': - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.0 - '@babel/helpers@7.27.6': dependencies: '@babel/template': 7.27.2 @@ -8895,58 +8788,53 @@ snapshots: dependencies: '@babel/types': 7.28.0 - '@babel/plugin-proposal-decorators@7.28.0(@babel/core@7.26.10)': + '@babel/plugin-proposal-decorators@7.28.0(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.26.10) + '@babel/core': 7.28.0 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.26.10) + '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.28.0) transitivePeerDependencies: - supports-color - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.26.10)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.27.1 - - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.10)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.10)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.26.10)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.26.10)': + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.10)': + '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.26.10)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': @@ -8954,91 +8842,91 @@ snapshots: '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.10)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.10)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.10)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.10)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.10)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.25.4(@babel/core@7.26.10)': + '@babel/plugin-syntax-typescript@7.25.4(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.26.10)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.26.10)': + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.26.10) + '@babel/core': 7.28.0 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.26.10)': + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.26.10) + '@babel/core': 7.28.0 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.26.10)': + '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.26.10) + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.26.10) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.0) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.27.1(@babel/core@7.26.10)': + '@babel/preset-typescript@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.26.10) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.26.10) - '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.26.10) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.0) + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.0) transitivePeerDependencies: - supports-color @@ -9641,7 +9529,7 @@ snapshots: '@jest/transform@29.7.0': dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 @@ -10072,10 +9960,10 @@ snapshots: '@rsbuild/plugin-babel@1.0.5(@rsbuild/core@1.4.5)': dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.26.10) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.26.10) - '@babel/preset-typescript': 7.27.1(@babel/core@7.26.10) + '@babel/core': 7.28.0 + '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.0) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.0) + '@babel/preset-typescript': 7.27.1(@babel/core@7.28.0) '@rsbuild/core': 1.4.5 '@types/babel__core': 7.20.5 deepmerge: 4.3.1 @@ -11661,24 +11549,24 @@ snapshots: dependencies: '@babel/types': 7.28.0 - babel-preset-current-node-syntax@1.1.0(@babel/core@7.26.10): - dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.26.10) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.10) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.26.10) - '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.26.10) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.10) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.26.10) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.26.10) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.26.10) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.10) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.26.10) + babel-preset-current-node-syntax@1.1.0(@babel/core@7.28.0): + dependencies: + '@babel/core': 7.28.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.0) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.28.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.0) bail@2.0.2: {} @@ -12667,10 +12555,10 @@ snapshots: eslint-config-preact@1.5.0(eslint@9.30.0(jiti@2.4.2)): dependencies: - '@babel/core': 7.26.10 - '@babel/eslint-parser': 7.28.0(@babel/core@7.26.10)(eslint@9.30.0(jiti@2.4.2)) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.10) - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.26.10) + '@babel/core': 7.28.0 + '@babel/eslint-parser': 7.28.0(@babel/core@7.28.0)(eslint@9.30.0(jiti@2.4.2)) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.0) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) eslint: 9.30.0(jiti@2.4.2) eslint-plugin-compat: 4.2.0(eslint@9.30.0(jiti@2.4.2)) eslint-plugin-react: 7.37.5(eslint@9.30.0(jiti@2.4.2)) @@ -12704,15 +12592,14 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.9.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) + eslint-plugin-import: 2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): + eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.30.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.30.0(jiti@2.4.2)) @@ -12741,7 +12628,7 @@ snapshots: dependencies: eslint: 9.30.0(jiti@2.4.2) - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): + eslint-plugin-import@2.32.0(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -12752,7 +12639,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.30.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) + eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.30.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -12763,8 +12650,6 @@ snapshots: semver: 6.3.1 string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.35.1(eslint@9.30.0(jiti@2.4.2))(typescript@5.8.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13936,7 +13821,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/parser': 7.28.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 @@ -13946,7 +13831,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/parser': 7.28.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 @@ -14059,15 +13944,15 @@ snapshots: jest-snapshot@29.7.0: dependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 '@babel/generator': 7.27.5 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.26.10) - '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.26.10) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) + '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.28.0) '@babel/types': 7.28.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.10) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.28.0) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 From cfcc7271a8404bd9639cb6a3cf05f9403f852be5 Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Mon, 14 Jul 2025 21:55:42 +0800 Subject: [PATCH 05/26] feat: add basic test for react compiler --- examples/react-compiler/package.json | 3 +- examples/react-compiler/src/App.tsx | 15 +++ .../testing-library/src/vitest.config.js | 105 +++++++++++++++++- .../testing-library/types/vitest-config.d.ts | 10 +- .../examples/react-compiler/.gitignore | 7 ++ .../examples/react-compiler/lynx.config.ts | 14 +++ .../examples/react-compiler/package.json | 23 ++++ .../examples/react-compiler/src/App.tsx | 19 ++++ .../src/__tests__/expectLogs.jsx | 17 +++ .../src/__tests__/hello.test.jsx | 103 +++++++++++++++++ .../src/__tests__/index.test.tsx | 58 ++++++++++ .../examples/react-compiler/src/index.tsx | 4 + .../react-compiler/src/rspeedy-env.d.ts | 1 + .../examples/react-compiler/tsconfig.json | 11 ++ .../examples/react-compiler/vitest.config.ts | 14 +++ .../src/loaders/react-compiler.ts | 7 +- pnpm-lock.yaml | 44 ++++++-- 17 files changed, 439 insertions(+), 16 deletions(-) create mode 100644 packages/testing-library/examples/react-compiler/.gitignore create mode 100644 packages/testing-library/examples/react-compiler/lynx.config.ts create mode 100644 packages/testing-library/examples/react-compiler/package.json create mode 100644 packages/testing-library/examples/react-compiler/src/App.tsx create mode 100644 packages/testing-library/examples/react-compiler/src/__tests__/expectLogs.jsx create mode 100644 packages/testing-library/examples/react-compiler/src/__tests__/hello.test.jsx create mode 100644 packages/testing-library/examples/react-compiler/src/__tests__/index.test.tsx create mode 100644 packages/testing-library/examples/react-compiler/src/index.tsx create mode 100644 packages/testing-library/examples/react-compiler/src/rspeedy-env.d.ts create mode 100644 packages/testing-library/examples/react-compiler/tsconfig.json create mode 100644 packages/testing-library/examples/react-compiler/vitest.config.ts diff --git a/examples/react-compiler/package.json b/examples/react-compiler/package.json index f34ac77ec5..0fb41f5bf0 100644 --- a/examples/react-compiler/package.json +++ b/examples/react-compiler/package.json @@ -1,5 +1,5 @@ { - "name": "@lynx-js/example-react", + "name": "@lynx-js/example-react-compiler", "version": "0.0.0", "private": true, "type": "module", @@ -13,6 +13,7 @@ "devDependencies": { "@babel/core": "^7.28.0", "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", "@eslint/compat": "^1.3.1", "@eslint/js": "^9.29.0", "@lynx-js/qrcode-rsbuild-plugin": "workspace:*", diff --git a/examples/react-compiler/src/App.tsx b/examples/react-compiler/src/App.tsx index 671297259b..82e88e04b3 100644 --- a/examples/react-compiler/src/App.tsx +++ b/examples/react-compiler/src/App.tsx @@ -5,6 +5,20 @@ import arrow from './assets/arrow.png'; import lynxLogo from './assets/lynx-logo.png'; import reactLynxLogo from './assets/react-logo.png'; +function Hello({ name }: { + name: string; +}) { + const items = [1, 2, 3].map(item => { + return Item {item}; + }); + return ( + + Hello {name} + {items} + + ); +} + export function App() { const [alterLogo, setAlterLogo] = useState(false); @@ -29,6 +43,7 @@ export function App() { React on Lynx + diff --git a/packages/react/testing-library/src/vitest.config.js b/packages/react/testing-library/src/vitest.config.js index 4f38a7dc35..0747ed02a5 100644 --- a/packages/react/testing-library/src/vitest.config.js +++ b/packages/react/testing-library/src/vitest.config.js @@ -61,6 +61,104 @@ export const createVitestConfig = async (options) => { runtimeAlias = generateAlias(runtimePkgName, runtimeDir, __dirname); } const preactAlias = generateAlias('preact', preactDir, runtimeOSSDir); + const reactAlias = [ + { + find: /^react$/, + replacement: require.resolve(runtimeOSSPkgName, { + paths: [runtimeDir], + }), + }, + ]; + const reactCompilerRuntimeAlias = [ + { + find: /^react-compiler-runtime$/, + replacement: path.posix.join( + path.posix.dirname(require.resolve('react-compiler-runtime/package.json', { + paths: [process.cwd()], + })), + // Use ts to ensure `react` can be aliased to `@lynx-js/react` + 'src/index.ts', + ), + }, + ]; + console.log('reactCompilerRuntimeAlias', reactCompilerRuntimeAlias); + + function transformReactCompilerPlugin() { + return { + name: 'transformReactCompilerPlugin', + enforce: 'pre', + async transform(sourceText, sourcePath) { + const id = sourcePath; + if ( + id.endsWith('.css') || id.endsWith('.less') || id.endsWith('.scss') + ) { + if (process.env['DEBUG']) { + console.log('ignoring css file', id); + } + return ''; + } + + const { isReactCompilerRequired } = require( + '@lynx-js/react/transform', + ); + if (/\.(?:jsx|tsx)$/.test(sourcePath)) { + const needReactCompiler = await isReactCompilerRequired(sourceText); + if (needReactCompiler) { + try { + const missingBabelPackages = []; + const [ + babelPath, + babelPluginReactCompilerPath, + babelPluginSyntaxJsxPath, + ] = [ + '@babel/core', + 'babel-plugin-react-compiler', + '@babel/plugin-syntax-jsx', + ].map((name) => { + try { + return require.resolve(name, { + paths: [process.cwd()], + }); + } catch { + missingBabelPackages.push(name); + } + return ''; + }); + if (missingBabelPackages.length > 0) { + throw `With \`experimental_enableReactCompiler\` enabled, you need to install \`${ + missingBabelPackages.join( + '`, `', + ) + }\` in your project root to use React Compiler.`; + } + + const babel = require(babelPath); + + const result = babel.transformSync(sourceText, { + plugins: [ + [babelPluginReactCompilerPath, { target: '17' }], + babelPluginSyntaxJsxPath, + ], + filename: sourcePath, + ast: false, + sourceMaps: true, + }); + if (result?.code && result?.map) { + return { + code: result.code, + map: result.map, + }; + } else { + this.error('babel-plugin-react-compiler transform failed'); + } + } catch (e) { + this.error(e); + } + } + } + }, + }; + } function transformReactLynxPlugin() { return { @@ -146,6 +244,11 @@ export const createVitestConfig = async (options) => { }, }, plugins: [ + ...(options?.experimental_enableReactCompiler + ? [ + transformReactCompilerPlugin(), + ] + : []), transformReactLynxPlugin(), ], test: { @@ -154,7 +257,7 @@ export const createVitestConfig = async (options) => { ), globals: true, setupFiles: [path.join(__dirname, 'vitest-global-setup')], - alias: [...runtimeOSSAlias, ...runtimeAlias, ...preactAlias], + alias: [...runtimeOSSAlias, ...runtimeAlias, ...preactAlias, ...reactAlias, ...reactCompilerRuntimeAlias], }, }); }; diff --git a/packages/react/testing-library/types/vitest-config.d.ts b/packages/react/testing-library/types/vitest-config.d.ts index 472c2f22c7..3b20fe6013 100644 --- a/packages/react/testing-library/types/vitest-config.d.ts +++ b/packages/react/testing-library/types/vitest-config.d.ts @@ -4,9 +4,17 @@ export interface CreateVitestConfigOptions { /** * The package name of the ReactLynx runtime package. * - * @default `@lynx-js/react` + * @defaultValue `@lynx-js/react` */ runtimePkgName?: string; + /** + * Enable React Compiler for this build. + * + * @link https://react.dev/learn/react-compiler + * + * @defaultValue false + */ + experimental_enableReactCompiler?: boolean; } export function createVitestConfig(options?: CreateVitestConfigOptions): Promise; diff --git a/packages/testing-library/examples/react-compiler/.gitignore b/packages/testing-library/examples/react-compiler/.gitignore new file mode 100644 index 0000000000..35ff3006b1 --- /dev/null +++ b/packages/testing-library/examples/react-compiler/.gitignore @@ -0,0 +1,7 @@ +/dist +/node_modules + +*.log +log +output +.DS_Store diff --git a/packages/testing-library/examples/react-compiler/lynx.config.ts b/packages/testing-library/examples/react-compiler/lynx.config.ts new file mode 100644 index 0000000000..58f6feb59c --- /dev/null +++ b/packages/testing-library/examples/react-compiler/lynx.config.ts @@ -0,0 +1,14 @@ +import { pluginReactLynx } from '@lynx-js/react-rsbuild-plugin'; +import { defineConfig } from '@lynx-js/rspeedy'; + +export default defineConfig({ + source: { + entry: './src/index.tsx', + }, + plugins: [ + pluginReactLynx({ + enableRemoveCSSScope: true, + experimental_enableReactCompiler: true, + }), + ], +}); diff --git a/packages/testing-library/examples/react-compiler/package.json b/packages/testing-library/examples/react-compiler/package.json new file mode 100644 index 0000000000..55ab3b2bdc --- /dev/null +++ b/packages/testing-library/examples/react-compiler/package.json @@ -0,0 +1,23 @@ +{ + "name": "@lynx-js/testing-library-example-react-compiler", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "rspeedy build", + "dev": "rspeedy dev", + "test": "vitest" + }, + "dependencies": { + "@lynx-js/react": "workspace:*" + }, + "devDependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@lynx-js/react-rsbuild-plugin": "workspace:*", + "@lynx-js/rspeedy": "workspace:*", + "@testing-library/jest-dom": "^6.6.3", + "babel-plugin-react-compiler": "0.0.0-experimental-0566679-20250709", + "react-compiler-runtime": "0.0.0-experimental-0566679-20250709" + } +} diff --git a/packages/testing-library/examples/react-compiler/src/App.tsx b/packages/testing-library/examples/react-compiler/src/App.tsx new file mode 100644 index 0000000000..15c69d1623 --- /dev/null +++ b/packages/testing-library/examples/react-compiler/src/App.tsx @@ -0,0 +1,19 @@ +import { Component } from '@lynx-js/react'; + +export interface IProps { + onMounted?: () => void; +} + +export class App extends Component { + override componentDidMount(): void { + this.props?.onMounted?.(); + } + + override render(): JSX.Element { + return ( + + Hello World! + + ); + } +} diff --git a/packages/testing-library/examples/react-compiler/src/__tests__/expectLogs.jsx b/packages/testing-library/examples/react-compiler/src/__tests__/expectLogs.jsx new file mode 100644 index 0000000000..7e00bd5014 --- /dev/null +++ b/packages/testing-library/examples/react-compiler/src/__tests__/expectLogs.jsx @@ -0,0 +1,17 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const logs = []; + +export function log(message) { + logs.push(message); +} + +export function expectLogsAndClear(expected) { + expect(logs).toEqual(expected); + logs.length = 0; +} diff --git a/packages/testing-library/examples/react-compiler/src/__tests__/hello.test.jsx b/packages/testing-library/examples/react-compiler/src/__tests__/hello.test.jsx new file mode 100644 index 0000000000..95862ccf71 --- /dev/null +++ b/packages/testing-library/examples/react-compiler/src/__tests__/hello.test.jsx @@ -0,0 +1,103 @@ +import { + render, + getQueriesForElement, + act, +} from '@lynx-js/react/testing-library'; +import { expectLogsAndClear, log } from './expectLogs'; +import { useState } from '@lynx-js/react'; + +function Hello({ name }) { + const items = [1, 2, 3].map(item => { + log(`recomputing ${item}`); + return
Item {item}
; + }); + return ( +
+ Hello{name} + {items} +
+ ); +} + +test('hello', () => { + let setName; + const Comp = () => { + const [name, _setName] = useState('World'); + setName = _setName; + return ; + }; + + let { container } = render(); + + expect(container).toMatchInlineSnapshot(` + +
+ Hello + + World + + +
+ Item + + 1 + +
+
+ Item + + 2 + +
+
+ Item + + 3 + +
+
+
+
+ `); + + expectLogsAndClear(['recomputing 1', 'recomputing 2', 'recomputing 3']); + + act(() => { + setName('Universe'); + }); + + expect(container).toMatchInlineSnapshot(` + +
+ Hello + + Universe + + +
+ Item + + 1 + +
+
+ Item + + 2 + +
+
+ Item + + 3 + +
+
+
+
+ `); + + expectLogsAndClear( + [], + ); +}); diff --git a/packages/testing-library/examples/react-compiler/src/__tests__/index.test.tsx b/packages/testing-library/examples/react-compiler/src/__tests__/index.test.tsx new file mode 100644 index 0000000000..d877834a08 --- /dev/null +++ b/packages/testing-library/examples/react-compiler/src/__tests__/index.test.tsx @@ -0,0 +1,58 @@ +// Copyright 2024 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import '@testing-library/jest-dom'; +import { expect, test, vi } from 'vitest'; +import { render, getQueriesForElement } from '@lynx-js/react/testing-library'; +// @ts-expect-error preact is aliased to the dep of @lynx-js/react +import { Component as PreacComponent } from 'preact'; +import { Component } from '@lynx-js/react'; + +import { App } from '../App.jsx'; + +test('App', async () => { + const cb = vi.fn(); + + render( + { + cb(`__MAIN_THREAD__: ${__MAIN_THREAD__}`); + }} + />, + ); + expect(cb).toBeCalledTimes(1); + expect(cb.mock.calls).toMatchInlineSnapshot(` + [ + [ + "__MAIN_THREAD__: false", + ], + ] + `); + expect(elementTree.root).toMatchInlineSnapshot(` + + + + Hello World! + + + + `); + const { + findByText, + } = getQueriesForElement(elementTree.root!); + const element = await findByText('Hello World!'); + expect(element).toBeInTheDocument(); + expect(element).toMatchInlineSnapshot(` + + Hello World! + + `); +}); + +test('preact is aliased correctly', () => { + expect(PreacComponent).toBe(Component); +}); diff --git a/packages/testing-library/examples/react-compiler/src/index.tsx b/packages/testing-library/examples/react-compiler/src/index.tsx new file mode 100644 index 0000000000..028f3b473b --- /dev/null +++ b/packages/testing-library/examples/react-compiler/src/index.tsx @@ -0,0 +1,4 @@ +import { App } from './App.jsx'; +import { root } from '@lynx-js/react'; + +root.render(); diff --git a/packages/testing-library/examples/react-compiler/src/rspeedy-env.d.ts b/packages/testing-library/examples/react-compiler/src/rspeedy-env.d.ts new file mode 100644 index 0000000000..1c813a68b0 --- /dev/null +++ b/packages/testing-library/examples/react-compiler/src/rspeedy-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/testing-library/examples/react-compiler/tsconfig.json b/packages/testing-library/examples/react-compiler/tsconfig.json new file mode 100644 index 0000000000..e2ec0132e2 --- /dev/null +++ b/packages/testing-library/examples/react-compiler/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../../tsconfig.json", + "compilerOptions": { + /* Specify what JSX code is generated. */ + "jsx": "preserve", + + /* Disable emitting files from a compilation. */ + "noEmit": true, + }, + "include": ["src"], +} diff --git a/packages/testing-library/examples/react-compiler/vitest.config.ts b/packages/testing-library/examples/react-compiler/vitest.config.ts new file mode 100644 index 0000000000..f0cebebb97 --- /dev/null +++ b/packages/testing-library/examples/react-compiler/vitest.config.ts @@ -0,0 +1,14 @@ +import { defineConfig, mergeConfig } from 'vitest/config'; +import { createVitestConfig } from '@lynx-js/react/testing-library/vitest-config'; + +const defaultConfig = await createVitestConfig({ + runtimePkgName: '@lynx-js/react', + experimental_enableReactCompiler: true, +}); +const config = defineConfig({ + test: { + name: 'testing-library/examples/basic', + }, +}); + +export default mergeConfig(defaultConfig, config); diff --git a/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts b/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts index ea79fbcb8d..99f861636a 100644 --- a/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts +++ b/packages/webpack/react-webpack-plugin/src/loaders/react-compiler.ts @@ -18,6 +18,8 @@ async function reactCompilerLoader( transformPath, ) as typeof import('@lynx-js/react/transform'); if (/\.(?:jsx|tsx)$/.test(this.resourcePath)) { + const isTSX = this.resourcePath.endsWith('.tsx'); + const needReactCompiler = await isReactCompilerRequired(content); if (needReactCompiler) { try { @@ -26,10 +28,12 @@ async function reactCompilerLoader( babelPath, babelPluginReactCompilerPath, babelPluginSyntaxJsxPath, + babelPluginSyntaxTypescriptPath, ] = [ '@babel/core', 'babel-plugin-react-compiler', '@babel/plugin-syntax-jsx', + '@babel/plugin-syntax-typescript', ].map((name) => { try { return require.resolve(name, { @@ -56,10 +60,11 @@ async function reactCompilerLoader( plugins: [ [babelPluginReactCompilerPath!, { target: '17' }], babelPluginSyntaxJsxPath!, + isTSX ? [babelPluginSyntaxTypescriptPath, { isTSX: true }] : null, ], filename: this.resourcePath, ast: false, - sourceMaps: true, + sourceMaps: this.sourceMap, }); if (result?.code && result?.map) { return callback(null, result.code, JSON.stringify(result.map)); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b8a0645a93..b1d2a65749 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -169,6 +169,9 @@ importers: '@babel/plugin-syntax-jsx': specifier: ^7.27.1 version: 7.27.1(@babel/core@7.28.0) + '@babel/plugin-syntax-typescript': + specifier: ^7.27.1 + version: 7.27.1(@babel/core@7.28.0) '@eslint/compat': specifier: ^1.3.1 version: 1.3.1(eslint@9.30.0(jiti@2.4.2)) @@ -645,6 +648,34 @@ importers: specifier: ^6.6.3 version: 6.6.3 + packages/testing-library/examples/react-compiler: + dependencies: + '@lynx-js/react': + specifier: workspace:* + version: link:../../../react + devDependencies: + '@babel/core': + specifier: ^7.28.0 + version: 7.28.0 + '@babel/plugin-syntax-jsx': + specifier: ^7.27.1 + version: 7.27.1(@babel/core@7.28.0) + '@lynx-js/react-rsbuild-plugin': + specifier: workspace:* + version: link:../../../rspeedy/plugin-react + '@lynx-js/rspeedy': + specifier: workspace:* + version: link:../../../rspeedy/core + '@testing-library/jest-dom': + specifier: ^6.6.3 + version: 6.6.3 + babel-plugin-react-compiler: + specifier: 0.0.0-experimental-0566679-20250709 + version: 0.0.0-experimental-0566679-20250709 + react-compiler-runtime: + specifier: 0.0.0-experimental-0566679-20250709 + version: 0.0.0-experimental-0566679-20250709(react@19.1.0) + packages/testing-library/testing-environment: devDependencies: '@testing-library/jest-dom': @@ -1545,12 +1576,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.25.4': - resolution: {integrity: sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.27.1': resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} engines: {node: '>=6.9.0'} @@ -8882,11 +8907,6 @@ snapshots: '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.25.4(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -13947,7 +13967,7 @@ snapshots: '@babel/core': 7.28.0 '@babel/generator': 7.27.5 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.28.0) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.0) '@babel/types': 7.28.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 From 5b579e8f549a75607a6c9259162e7f13c61e0025 Mon Sep 17 00:00:00 2001 From: Yiming Li Date: Tue, 15 Jul 2025 17:37:43 +0800 Subject: [PATCH 06/26] feat: migrate all test cases from react to examples/react-compiler --- .changeset/quick-turtles-make.md | 5 + .changeset/tame-forks-agree.md | 17 +++ .../src/__tests__/rerender.test.jsx | 13 +- packages/react/testing-library/src/pure.jsx | 36 +++-- .../testing-library/src/vitest.config.js | 1 - .../react/testing-library/types/entry.d.ts | 1 + .../examples/react-compiler/LICENSE | 22 +++ .../examples/react-compiler/package.json | 2 + .../src/__tests__/constant-prop.test.jsx | 129 ++++++++++++++++++ .../src/__tests__/expectLogs.jsx | 9 +- .../src/__tests__/hello.test.jsx | 86 ++++++------ .../src/__tests__/index.test.tsx | 1 + .../src/__tests__/update-button.test.jsx | 64 +++++++++ .../src/__tests__/update-expressions.test.jsx | 44 ++++++ .../src/__tests__/use-state.test.jsx | 78 +++++++++++ .../examples/react-compiler/tsconfig.json | 4 +- .../vitest.config.compiler-disabled.ts | 16 +++ .../vitest.config.compiler-enabled.ts | 16 +++ .../examples/react-compiler/vitest.config.ts | 14 +- pnpm-lock.yaml | 6 + vitest.workspace.json | 2 + 21 files changed, 486 insertions(+), 80 deletions(-) create mode 100644 .changeset/quick-turtles-make.md create mode 100644 .changeset/tame-forks-agree.md create mode 100644 packages/testing-library/examples/react-compiler/LICENSE create mode 100644 packages/testing-library/examples/react-compiler/src/__tests__/constant-prop.test.jsx create mode 100644 packages/testing-library/examples/react-compiler/src/__tests__/update-button.test.jsx create mode 100644 packages/testing-library/examples/react-compiler/src/__tests__/update-expressions.test.jsx create mode 100644 packages/testing-library/examples/react-compiler/src/__tests__/use-state.test.jsx create mode 100644 packages/testing-library/examples/react-compiler/vitest.config.compiler-disabled.ts create mode 100644 packages/testing-library/examples/react-compiler/vitest.config.compiler-enabled.ts diff --git a/.changeset/quick-turtles-make.md b/.changeset/quick-turtles-make.md new file mode 100644 index 0000000000..06be9fa921 --- /dev/null +++ b/.changeset/quick-turtles-make.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/react": patch +--- + +Fix the `rerender` function in the testing library to keep the current `` element used. After this fix it will behavior the same with `react-testing-library`'s `rerender` function. diff --git a/.changeset/tame-forks-agree.md b/.changeset/tame-forks-agree.md new file mode 100644 index 0000000000..60d14514e8 --- /dev/null +++ b/.changeset/tame-forks-agree.md @@ -0,0 +1,17 @@ +--- +"@lynx-js/react": patch +--- + +Support testing React Compiler in testing library. Enable React Compiler by setting the `experimental_enableReactCompiler` option of `createVitestConfig` to `true`. + +```js +import { defineConfig, mergeConfig } from 'vitest/config'; +import { createVitestConfig } from '@lynx-js/react/testing-library/vitest-config'; + +const defaultConfig = await createVitestConfig({ + runtimePkgName: '@lynx-js/react', + experimental_enableReactCompiler: true, +}); + +export default mergeConfig(defaultConfig, config); +``` diff --git a/packages/react/testing-library/src/__tests__/rerender.test.jsx b/packages/react/testing-library/src/__tests__/rerender.test.jsx index 753b990ff0..e533ab19a7 100644 --- a/packages/react/testing-library/src/__tests__/rerender.test.jsx +++ b/packages/react/testing-library/src/__tests__/rerender.test.jsx @@ -5,7 +5,7 @@ import { useEffect, useState } from '@lynx-js/react'; test('rerender will re-render the element', async () => { const Greeting = (props) => {props.message}; - const { container, rerender } = render(); + const { container, rerender, asFragment } = render(); expect(container).toMatchInlineSnapshot(` @@ -16,15 +16,16 @@ test('rerender will re-render the element', async () => { expect(container.firstChild).toHaveTextContent('hi'); { - const { container } = rerender(); + rerender(); + const container = asFragment(); expect(container.firstChild).toHaveTextContent('hey'); expect(container).toMatchInlineSnapshot(` - + hey - + `); } }); @@ -42,8 +43,8 @@ test('rerender will flush pending hooks effects', async () => { return value; }; - const { rerender } = render(); - const { findByText } = rerender(); + const { rerender, findByText } = render(); + rerender(); vi.spyOn(lynx.getNativeApp(), 'callLepusMethod'); const callLepusMethod = lynxTestingEnv.backgroundThread.lynx.getNativeApp().callLepusMethod; expect(callLepusMethod.mock.calls).toMatchInlineSnapshot(`[]`); diff --git a/packages/react/testing-library/src/pure.jsx b/packages/react/testing-library/src/pure.jsx index bed2f562d4..c6f1534cbd 100644 --- a/packages/react/testing-library/src/pure.jsx +++ b/packages/react/testing-library/src/pure.jsx @@ -43,6 +43,7 @@ export function render( wrapper: WrapperComponent, enableMainThread = false, enableBackgroundThread = true, + isRerender = false, } = {}, ) { if (!enableMainThread && !enableBackgroundThread) { @@ -58,11 +59,14 @@ export function render( const compMainThread = cloneElement(comp); const compBackgroundThread = cloneElement(comp); - globalThis.lynxTestingEnv.switchToMainThread(); - __root.__jsx = enableMainThread ? compMainThread : null; - act(() => { - renderPage(); - }); + // We should keep using current element on rerender + if (!isRerender) { + globalThis.lynxTestingEnv.switchToMainThread(); + __root.__jsx = enableMainThread ? compMainThread : null; + act(() => { + renderPage(); + }); + } if (enableBackgroundThread) { globalThis.lynxTestingEnv.switchToBackgroundThread(); act(() => { @@ -75,14 +79,30 @@ export function render( container: lynxTestingEnv.mainThread.elementTree.root, unmount: cleanup, rerender: (rerenderUi) => { - lynxTestingEnv.reset(); - return render(wrapUiIfNeeded(rerenderUi), { - queries, + act(() => {}); + // Intentionally do not return anything to avoid unnecessarily complicating the API. + // folks can use all the same utilities we return in the first place that are bound to + // the container + render(rerenderUi, { wrapper: WrapperComponent, enableMainThread, enableBackgroundThread, + isRerender: true, }); }, + asFragment: () => { + const { document } = lynxTestingEnv.jsdom.window; + const container = lynxTestingEnv.mainThread.elementTree.root; + if (typeof document.createRange === 'function') { + return document + .createRange() + .createContextualFragment(container.innerHTML); + } else { + const template = document.createElement('template'); + template.innerHTML = container.innerHTML; + return template.content; + } + }, ...getQueriesForElement(lynxTestingEnv.mainThread.elementTree.root, queries), }; } diff --git a/packages/react/testing-library/src/vitest.config.js b/packages/react/testing-library/src/vitest.config.js index 0747ed02a5..b85156a0a1 100644 --- a/packages/react/testing-library/src/vitest.config.js +++ b/packages/react/testing-library/src/vitest.config.js @@ -81,7 +81,6 @@ export const createVitestConfig = async (options) => { ), }, ]; - console.log('reactCompilerRuntimeAlias', reactCompilerRuntimeAlias); function transformReactCompilerPlugin() { return { diff --git a/packages/react/testing-library/types/entry.d.ts b/packages/react/testing-library/types/entry.d.ts index 5408234a70..b5e0ca6fc5 100644 --- a/packages/react/testing-library/types/entry.d.ts +++ b/packages/react/testing-library/types/entry.d.ts @@ -97,6 +97,7 @@ export type RenderResult = { container: LynxElement; rerender: (ui: ComponentChild) => void; unmount: () => boolean; + asFragment: () => DocumentFragment; } & { [P in keyof Q]: BoundFunction }; /** diff --git a/packages/testing-library/examples/react-compiler/LICENSE b/packages/testing-library/examples/react-compiler/LICENSE new file mode 100644 index 0000000000..5385eea6f4 --- /dev/null +++ b/packages/testing-library/examples/react-compiler/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) Meta Platforms, Inc. and affiliates. +Copyright (c) 2025 Lynx Authors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/testing-library/examples/react-compiler/package.json b/packages/testing-library/examples/react-compiler/package.json index 55ab3b2bdc..b701ea4ae6 100644 --- a/packages/testing-library/examples/react-compiler/package.json +++ b/packages/testing-library/examples/react-compiler/package.json @@ -16,7 +16,9 @@ "@babel/plugin-syntax-jsx": "^7.27.1", "@lynx-js/react-rsbuild-plugin": "workspace:*", "@lynx-js/rspeedy": "workspace:*", + "@lynx-js/types": "3.3.0", "@testing-library/jest-dom": "^6.6.3", + "@types/react": "^18.3.23", "babel-plugin-react-compiler": "0.0.0-experimental-0566679-20250709", "react-compiler-runtime": "0.0.0-experimental-0566679-20250709" } diff --git a/packages/testing-library/examples/react-compiler/src/__tests__/constant-prop.test.jsx b/packages/testing-library/examples/react-compiler/src/__tests__/constant-prop.test.jsx new file mode 100644 index 0000000000..1851bc5d67 --- /dev/null +++ b/packages/testing-library/examples/react-compiler/src/__tests__/constant-prop.test.jsx @@ -0,0 +1,129 @@ +// Copyright 2025 The Lynx Authors. All rights reserved. +// Licensed under the MIT license that can be found in the +// LICENSE file in the root directory of this source tree. + +import { render } from '@lynx-js/react/testing-library'; + +globalThis.constantValue = 'global test value'; + +test('literal-constant-propagation', () => { + function Component() { + 'use memo'; + const x = 'test value 1'; + return {x}; + } + const { asFragment, rerender } = render(); + + expect(asFragment()).toMatchInlineSnapshot(` + + + test value 1 + + + `); + + rerender(); + + expect(asFragment()).toMatchInlineSnapshot(` + + + test value 1 + + + `); +}); + +test('global-constant-propagation', () => { + function Component() { + 'use memo'; + const x = constantValue; + + return {x}; + } + const { asFragment, rerender } = render(); + + expect(asFragment()).toMatchInlineSnapshot(` + + + global test value + + + `); + + rerender(); + + expect(asFragment()).toMatchInlineSnapshot(` + + + global test value + + + `); +}); + +test('lambda-constant-propagation', () => { + function Component() { + 'use memo'; + const x = 'test value 1'; + const getText = () => {x}; + return getText(); + } + const { asFragment, rerender } = render(); + + expect(asFragment()).toMatchInlineSnapshot(` + + + test value 1 + + + `); + + rerender(); + + expect(asFragment()).toMatchInlineSnapshot(` + + + test value 1 + + + `); +}); + +test('lambda-constant-propagation-of-phi-node', () => { + function Component({ noopCallback }) { + 'use memo'; + const x = 'test value 1'; + if (constantValue) { + noopCallback(); + } + for (let i = 0; i < 5; i++) { + if (!constantValue) { + noopCallback(); + } + } + const getText = () => {x}; + return getText(); + } + + const { asFragment, rerender } = render( + {}} />, + ); + + expect(asFragment()).toMatchInlineSnapshot(` + + + test value 1 + + + `); + + rerender( {}} />); + + expect(asFragment()).toMatchInlineSnapshot(` + + + test value 1 + + + `); +}); diff --git a/packages/testing-library/examples/react-compiler/src/__tests__/expectLogs.jsx b/packages/testing-library/examples/react-compiler/src/__tests__/expectLogs.jsx index 7e00bd5014..0f593ebe54 100644 --- a/packages/testing-library/examples/react-compiler/src/__tests__/expectLogs.jsx +++ b/packages/testing-library/examples/react-compiler/src/__tests__/expectLogs.jsx @@ -1,9 +1,6 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ +// Copyright 2025 The Lynx Authors. All rights reserved. +// Licensed under the MIT license that can be found in the +// LICENSE file in the root directory of this source tree. const logs = []; diff --git a/packages/testing-library/examples/react-compiler/src/__tests__/hello.test.jsx b/packages/testing-library/examples/react-compiler/src/__tests__/hello.test.jsx index 95862ccf71..fc28c40116 100644 --- a/packages/testing-library/examples/react-compiler/src/__tests__/hello.test.jsx +++ b/packages/testing-library/examples/react-compiler/src/__tests__/hello.test.jsx @@ -1,103 +1,93 @@ -import { - render, - getQueriesForElement, - act, -} from '@lynx-js/react/testing-library'; +// Copyright 2025 The Lynx Authors. All rights reserved. +// Licensed under the MIT license that can be found in the +// LICENSE file in the root directory of this source tree. + +import { render } from '@lynx-js/react/testing-library'; import { expectLogsAndClear, log } from './expectLogs'; -import { useState } from '@lynx-js/react'; function Hello({ name }) { const items = [1, 2, 3].map(item => { log(`recomputing ${item}`); - return
Item {item}
; + return Item {item}; }); return ( -
- Hello{name} + + Hello{name} {items} -
+
); } test('hello', () => { - let setName; - const Comp = () => { - const [name, _setName] = useState('World'); - setName = _setName; - return ; - }; - - let { container } = render(); + let { asFragment, rerender } = render(); - expect(container).toMatchInlineSnapshot(` - -
+ expect(asFragment()).toMatchInlineSnapshot(` + + Hello - + World - + -
+ Item 1 -
-
+ + Item 2 -
-
+ + Item 3 -
+
-
-
+ + `); expectLogsAndClear(['recomputing 1', 'recomputing 2', 'recomputing 3']); - act(() => { - setName('Universe'); - }); + rerender(); - expect(container).toMatchInlineSnapshot(` - -
+ expect(asFragment()).toMatchInlineSnapshot(` + + Hello - + Universe - + -
+ Item 1 -
-
+ + Item 2 -
-
+ + Item 3 -
+
-
-
+ + `); expectLogsAndClear( - [], + __FORGET__ ? [] : ['recomputing 1', 'recomputing 2', 'recomputing 3'], ); }); diff --git a/packages/testing-library/examples/react-compiler/src/__tests__/index.test.tsx b/packages/testing-library/examples/react-compiler/src/__tests__/index.test.tsx index d877834a08..1628e39323 100644 --- a/packages/testing-library/examples/react-compiler/src/__tests__/index.test.tsx +++ b/packages/testing-library/examples/react-compiler/src/__tests__/index.test.tsx @@ -1,6 +1,7 @@ // Copyright 2024 The Lynx Authors. All rights reserved. // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. + import '@testing-library/jest-dom'; import { expect, test, vi } from 'vitest'; import { render, getQueriesForElement } from '@lynx-js/react/testing-library'; diff --git a/packages/testing-library/examples/react-compiler/src/__tests__/update-button.test.jsx b/packages/testing-library/examples/react-compiler/src/__tests__/update-button.test.jsx new file mode 100644 index 0000000000..a599b7459b --- /dev/null +++ b/packages/testing-library/examples/react-compiler/src/__tests__/update-button.test.jsx @@ -0,0 +1,64 @@ +// Copyright 2025 The Lynx Authors. All rights reserved. +// Licensed under the MIT license that can be found in the +// LICENSE file in the root directory of this source tree. + +import { render } from '@lynx-js/react/testing-library'; + +function Button({ label }) { + const theme = useTheme(); + const style = computeStyle(theme); + return {label}; +} + +let currentTheme = 'light'; +function useTheme() { + 'use memo'; + return currentTheme; +} + +let styleComputations = 0; +function computeStyle(theme) { + styleComputations++; + return theme === 'light' ? 'white' : 'black'; +} + +test('update-button', () => { + const { asFragment, rerender } = render(