diff --git a/.changeset/brave-symbols-laugh.md b/.changeset/brave-symbols-laugh.md new file mode 100644 index 0000000000..853d812bb3 --- /dev/null +++ b/.changeset/brave-symbols-laugh.md @@ -0,0 +1,3 @@ +--- + +--- diff --git a/.changeset/config.json b/.changeset/config.json index 930c3a01a4..b10a60e348 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -35,7 +35,6 @@ }, "ignore": [ "@lynx-js/web-tests", - "@lynx-js/eco-ci", "@lynx-js/example-react" ], "changedFilePatterns": [ diff --git a/.changeset/fast-goats-mix.md b/.changeset/fast-goats-mix.md new file mode 100644 index 0000000000..e0ba7ad136 --- /dev/null +++ b/.changeset/fast-goats-mix.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/rspeedy": patch +--- + +Bump Rsbuild v1.3.17 with Rspack v1.3.9. diff --git a/.changeset/full-rocks-smoke.md b/.changeset/full-rocks-smoke.md new file mode 100644 index 0000000000..db46c27343 --- /dev/null +++ b/.changeset/full-rocks-smoke.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/react-rsbuild-plugin": patch +--- + +Enable runtime profiling when `performance.profile` is set to true. diff --git a/.changeset/good-eagles-laugh.md b/.changeset/good-eagles-laugh.md new file mode 100644 index 0000000000..afe82c3c2e --- /dev/null +++ b/.changeset/good-eagles-laugh.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/react-webpack-plugin": patch +--- + +Add the `profile` option to control whether `__PROFILE__` is enabled. diff --git a/.github/actions/eco-ci/LICENSE.txt b/.github/actions/eco-ci/LICENSE.txt deleted file mode 100644 index ce66b4c3a7..0000000000 --- a/.github/actions/eco-ci/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023-2024 The Lynx Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/.github/actions/eco-ci/Notice.txt b/.github/actions/eco-ci/Notice.txt deleted file mode 100644 index 3ff8881bfd..0000000000 --- a/.github/actions/eco-ci/Notice.txt +++ /dev/null @@ -1 +0,0 @@ -Copyright 2023-2024 The Lynx Authors. All rights reserved. \ No newline at end of file diff --git a/.github/actions/eco-ci/action.yml b/.github/actions/eco-ci/action.yml deleted file mode 100644 index 5d193d848f..0000000000 --- a/.github/actions/eco-ci/action.yml +++ /dev/null @@ -1,10 +0,0 @@ -name: lynx-js/eco-ci -description: "This Github action scans the current pr thread to check if there are command in comments" -inputs: - token: - description: token - required: false - default: ${{ github.token }} -runs: - using: "node20" - main: "index.js" diff --git a/.github/actions/eco-ci/index.js b/.github/actions/eco-ci/index.js deleted file mode 100644 index 1d673a2388..0000000000 --- a/.github/actions/eco-ci/index.js +++ /dev/null @@ -1,57 +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. -// @ts-check -import fs from 'node:fs/promises'; -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; - -import * as core from '@actions/core'; -import { context, getOctokit } from '@actions/github'; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -const workspace = path.resolve(__dirname, '..', '..', '..'); -async function addCommentReaction() { - const commentId = context.payload.comment?.id; - const user = context.payload.sender?.login; - if (user && commentId) { - const octokit = getOctokit(core.getInput('token')); - const comment = await octokit.rest.pulls.getReviewComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: commentId, - }); - if (comment.data.body_text?.includes('$eco-ci')) { - await octokit.rest.reactions.createForIssueComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: commentId, - content: 'rocket', - }); - return true; - } - } else { - core.debug(`empty ${user ? '' : 'user'} ${commentId ? '' : 'comment-id'}`); - } - return false; -} - -/** - * @returns {Promise>} - */ -async function readPackages() { - const fileBinary = await fs.readFile(path.join(workspace, 'eco-ci.json')); - const pkgResult = JSON.parse(fileBinary.toString()); - return Object.fromEntries(pkgResult.map((e) => [e.name, e.url])); -} - -async function run() { - const shouldRunEcoCi = await addCommentReaction(); - if (shouldRunEcoCi) { - const pkgs = await readPackages(); - console.info(pkgs); - } -} - -run(); diff --git a/.github/actions/eco-ci/package.json b/.github/actions/eco-ci/package.json deleted file mode 100644 index 743e4a5112..0000000000 --- a/.github/actions/eco-ci/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@lynx-js/eco-ci", - "version": "0.0.0", - "private": true, - "license": "Apache-2.0", - "type": "module", - "main": "index.js", - "dependencies": { - "@actions/core": "^1.11.1", - "@actions/github": "^6.0.0" - } -} diff --git a/.github/workflows/deploy-main.yml b/.github/workflows/deploy-main.yml index 6af3986183..af290e52de 100644 --- a/.github/workflows/deploy-main.yml +++ b/.github/workflows/deploy-main.yml @@ -1,4 +1,4 @@ -name: deploy-main +name: Deploy on: push: @@ -19,14 +19,14 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'lynx-family/lynx-stack' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions-rust-lang/setup-rust-toolchain@9d7e65c320fdb52dcd45ffaa68deb6c02c8754d9 # v1 with: target: wasm32-unknown-unknown cache: false - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "22" - name: Install @@ -38,7 +38,7 @@ jobs: run: | corepack pnpm turbo --filter !@lynx-js/web-tests build --summarize - name: Save Turbo Result - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: deploy-${{ github.sha }} path: .turbo @@ -59,6 +59,11 @@ jobs: benchmark: needs: build-all uses: ./.github/workflows/workflow-bench.yml + bundle-analysis: + permissions: {} + needs: build-all + uses: ./.github/workflows/workflow-bundle-analysis.yml + if: github.repository == 'lynx-family/lynx-stack' coverage: needs: build-all uses: ./.github/workflows/workflow-test.yml @@ -77,24 +82,6 @@ jobs: --no-cache --logHeapUsage --silent - rust-coverage: - uses: ./.github/workflows/rust.yml - if: github.repository == 'lynx-family/lynx-stack' - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - playwright-linux: - needs: build-all - uses: ./.github/workflows/workflow-test.yml - secrets: inherit - with: - runs-on: lynx-ubuntu-24.04-xlarge - is-web: true - codecov-flags: "e2e" - run: | - export NODE_OPTIONS="--max-old-space-size=32768" - export PLAYWRIGHT_JUNIT_OUTPUT_NAME=test-report.junit.xml - pnpm --filter @lynx-js/web-tests run test --reporter='github,dot,junit,html' - pnpm --filter @lynx-js/web-tests run coverage:ci publish: needs: build runs-on: ubuntu-latest @@ -111,10 +98,10 @@ jobs: # See: https://docs.npmjs.com/generating-provenance-statements#publishing-packages-with-provenance-via-github-actions id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "22" registry-url: "https://registry.npmjs.org" @@ -124,7 +111,7 @@ jobs: corepack enable && corepack prepare corepack pnpm install --frozen-lockfile - name: Download Turbo Cache - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 timeout-minutes: 5 with: name: deploy-${{ github.sha }} @@ -157,10 +144,10 @@ jobs: # See: https://docs.npmjs.com/generating-provenance-statements#publishing-packages-with-provenance-via-github-actions id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "22" registry-url: "https://registry.npmjs.org" @@ -170,7 +157,7 @@ jobs: corepack enable && corepack prepare corepack pnpm install --frozen-lockfile - name: Download Turbo Cache - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 timeout-minutes: 5 with: name: deploy-${{ github.sha }} @@ -211,4 +198,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4 diff --git a/.github/workflows/nodejs-dependencies.yml b/.github/workflows/nodejs-dependencies.yml index e0cf28b11e..768c1b4ff7 100644 --- a/.github/workflows/nodejs-dependencies.yml +++ b/.github/workflows/nodejs-dependencies.yml @@ -17,9 +17,9 @@ jobs: sherif: runs-on: lynx-ubuntu-24.04-medium steps: - - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "22" - run: | diff --git a/.github/workflows/relative-ci.yml b/.github/workflows/relative-ci.yml new file mode 100644 index 0000000000..1ee2ec2953 --- /dev/null +++ b/.github/workflows/relative-ci.yml @@ -0,0 +1,35 @@ +name: RelativeCI + +on: + # zizmor: ignore[dangerous-triggers] This is a dangerous trigger, but it's ok because we're not using it to trigger other workflows + # See: https://relative-ci.com/documentation/setup/agent/github-action/#workflow_run-event + workflow_run: + workflows: ["Bundle Analysis", "Deploy", "Test"] + types: + - completed + +permissions: {} + +jobs: + upload: + strategy: + matrix: + project: + - path: ./examples/react + name: example-react + key: RELATIVE_CI_PROJECT_EXAMPLES_REACT_KEY + - path: ./packages/web-platform/web-explorer + name: web-explorer + key: RELATIVE_CI_PROJECT_WEB_EXPLORER_KEY + runs-on: lynx-ubuntu-24.04-medium + name: Upload ${{ matrix.project.name }} + env: + RELATIVE_CI_PROJECT_EXAMPLES_REACT_KEY: ${{ secrets.RELATIVE_CI_PROJECT_EXAMPLES_REACT_KEY }} + RELATIVE_CI_PROJECT_WEB_EXPLORER_KEY: ${{ secrets.RELATIVE_CI_PROJECT_WEB_EXPLORER_KEY }} + steps: + - name: Send bundle stats and build information to RelativeCI - ${{ matrix.project.name }} + uses: relative-ci/agent-action@38328454d6a23942175eba485fca4fbb807b1f03 #v2 + with: + artifactName: ${{ matrix.project.name }}-relative-ci-artifacts + key: ${{ env[matrix.project.key] }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 2508bbe8e8..ae8c42978d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,4 +1,9 @@ +name: Rust + on: + push: + branches: + - main workflow_call: secrets: CODECOV_TOKEN: @@ -14,12 +19,12 @@ jobs: test: runs-on: lynx-ubuntu-24.04-xlarge steps: - - uses: actions/checkout@v4 - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions-rust-lang/setup-rust-toolchain@9d7e65c320fdb52dcd45ffaa68deb6c02c8754d9 # v1 with: cache-key: test-${{ runner.os }} - name: Install llvm-cov and nextest - uses: taiki-e/install-action@f1390fd0d8205ae79e5e57b1d1e300dceeb4163e # v2 + uses: taiki-e/install-action@97a83ae1347bc407f550a16fb0694d6f446eec88 # v2 with: tool: cargo-llvm-cov,cargo-nextest - name: Test @@ -27,12 +32,12 @@ jobs: export CARGO_LLVM_COV_FLAGS_NO_RUNNER='--no-sparse' cargo llvm-cov nextest --profile ci --config-file .cargo/nextest.toml --lcov --output-path lcov.info --release - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5 with: token: ${{ secrets.CODECOV_TOKEN }} - name: Upload test results to Codecov if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 + uses: codecov/test-results-action@f2dba722c67b86c6caa034178c6e4d35335f6706 # v1 with: token: ${{ secrets.CODECOV_TOKEN }} files: target/nextest/ci/test-report.junit.xml @@ -40,8 +45,8 @@ jobs: rustfmt: runs-on: lynx-ubuntu-24.04-medium steps: - - uses: actions/checkout@v4 - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions-rust-lang/setup-rust-toolchain@9d7e65c320fdb52dcd45ffaa68deb6c02c8754d9 # v1 with: components: rustfmt cache-key: test-${{ runner.os }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 4d4b1fb0ae..5e8d8bca93 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -7,7 +7,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v9 + - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9 if: github.repository == 'lynx-family/lynx-stack' with: days-before-stale: 60 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e3dc9d2c12..100e83cd03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,11 +21,11 @@ jobs: code-style-check: runs-on: lynx-ubuntu-24.04-medium steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: # We need full history for changeset status check fetch-depth: 0 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "22" - name: Install @@ -53,14 +53,7 @@ jobs: uses: ./.github/workflows/workflow-bench.yml bundle-analysis: needs: build - uses: ./.github/workflows/workflow-test.yml - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - with: - runs-on: lynx-ubuntu-24.04-medium - run: | - pnpm --filter @lynx-js/web-explorer run build - pnpm --filter @lynx-js/example-react run build + uses: ./.github/workflows/workflow-bundle-analysis.yml test-rspeedy: needs: build uses: ./.github/workflows/workflow-test.yml @@ -229,7 +222,7 @@ jobs: with: runs-on: lynx-ubuntu-24.04-xlarge is-web: true - codecov-flags: "e2e" + codecov-flags: "e2e,all-on-ui" run: | export NODE_OPTIONS="--max-old-space-size=32768" export PLAYWRIGHT_JUNIT_OUTPUT_NAME=test-report.junit.xml @@ -287,17 +280,17 @@ jobs: security-events: write steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 - name: Run zizmor 🌈 run: uvx zizmor --format=sarif . > results.sarif env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3 with: sarif_file: results.sarif category: zizmor diff --git a/.github/workflows/workflow-bench.yml b/.github/workflows/workflow-bench.yml index 64e411111f..623af78d39 100644 --- a/.github/workflows/workflow-bench.yml +++ b/.github/workflows/workflow-bench.yml @@ -13,8 +13,8 @@ jobs: if: github.event_name != 'merge_group' runs-on: lynx-ubuntu-24.04-xlarge steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "22" - name: Install diff --git a/.github/workflows/workflow-build.yml b/.github/workflows/workflow-build.yml index 68dd678654..33e4f81703 100644 --- a/.github/workflows/workflow-build.yml +++ b/.github/workflows/workflow-build.yml @@ -18,7 +18,7 @@ jobs: outputs: merge-base: ${{ steps.merge-base.outputs.merge-base }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: ref: ${{ env.HEAD_REF }} repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} @@ -63,8 +63,8 @@ jobs: runs-on: lynx-ubuntu-24.04-xlarge needs: get-merge-base steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "22" - name: TurboCache @@ -98,7 +98,7 @@ jobs: continue-on-error: true - name: Upload turbo summary if: runner.debug == '1' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: turbo-summary-${{ github.sha }} path: .turbo/runs/*.json @@ -107,7 +107,7 @@ jobs: include-hidden-files: true - name: Setup Rust and retry build if failed if: steps.build.outcome == 'failure' - uses: actions-rust-lang/setup-rust-toolchain@v1 + uses: actions-rust-lang/setup-rust-toolchain@9d7e65c320fdb52dcd45ffaa68deb6c02c8754d9 # v1 with: target: wasm32-unknown-unknown cache-key: test-${{ runner.os }} diff --git a/.github/workflows/workflow-bundle-analysis.yml b/.github/workflows/workflow-bundle-analysis.yml new file mode 100644 index 0000000000..04577f93c7 --- /dev/null +++ b/.github/workflows/workflow-bundle-analysis.yml @@ -0,0 +1,50 @@ +name: Bundle Analysis + +on: + workflow_call: + +permissions: {} + +env: + CI: 1 + TURBO_TELEMETRY_DISABLED: 1 +jobs: + build: + runs-on: lynx-ubuntu-24.04-medium + strategy: + matrix: + project: + - path: ./examples/react + name: example-react + - path: ./packages/web-platform/web-explorer + name: web-explorer + name: Build ${{ matrix.project.name }} + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + persist-credentials: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: "22" + - name: TurboCache + uses: lynx-infra/cache@558d7c999f9f97ac02ed7e711503bb81d82ff8ee + with: + path: .turbo + # We have to be strict here to make sure getting the cache of build-all + key: turbo-v3-${{ hashFiles('**/packages/**/src/**/*.rs') }}-${{ github.sha }} + fail-on-cache-miss: true + - name: Install + run: | + npm install -g corepack@latest + corepack enable + pnpm install --frozen-lockfile + - name: Build + run: | + pnpm turbo build --summarize + - name: Build ${{ matrix.project.name }} + run: | + pnpm --filter ${{ matrix.project.path }} run build + - uses: relative-ci/agent-upload-artifact-action@a2b5741b4f7e6a989c84ec1a3059696b23c152e5 #v2 + with: + artifactName: ${{ matrix.project.name }}-relative-ci-artifacts + webpackStatsFile: ${{ matrix.project.path }}/dist/stats.json diff --git a/.github/workflows/workflow-test.yml b/.github/workflows/workflow-test.yml index a767fb6afc..36aa34b255 100644 --- a/.github/workflows/workflow-test.yml +++ b/.github/workflows/workflow-test.yml @@ -28,11 +28,11 @@ jobs: check: runs-on: ${{ inputs.runs-on }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: # Codecov requires fetch-depth: 0 fetch-depth: 0 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "22" - name: TurboCache @@ -64,19 +64,20 @@ jobs: LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }} run: ${{ inputs.run }} - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5 with: token: ${{ secrets.CODECOV_TOKEN }} flags: ${{ inputs.codecov-flags }} - name: Upload test results to Codecov if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 + uses: codecov/test-results-action@f2dba722c67b86c6caa034178c6e4d35335f6706 # v1 with: token: ${{ secrets.CODECOV_TOKEN }} flags: ${{ inputs.codecov-flags }} + override_branch: ${{ github.event_name == 'merge_queue' && 'main' || '' }} - name: Upload Test Result if: ${{ inputs.is-web && failure() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: playwright-report path: packages/web-platform/web-tests/playwright-report diff --git a/.github/workflows/workflow-website.yml b/.github/workflows/workflow-website.yml index d88be853a2..a1a151c75a 100644 --- a/.github/workflows/workflow-website.yml +++ b/.github/workflows/workflow-website.yml @@ -10,8 +10,8 @@ jobs: build: runs-on: lynx-ubuntu-24.04-medium steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: "22" - name: TurboCache @@ -21,7 +21,7 @@ jobs: key: turbo-v3-${{ hashFiles('**/packages/**/src/**/*.rs') }}-${{ github.sha }} fail-on-cache-miss: true - name: Setup Pages - uses: actions/configure-pages@v5 + uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5 - name: Install run: | npm install -g corepack@latest @@ -31,6 +31,6 @@ jobs: run: | pnpm turbo --filter website build:docs - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3 with: path: website/doc_build diff --git a/examples/react/lynx.config.js b/examples/react/lynx.config.js index 51b1112135..0b9358008b 100644 --- a/examples/react/lynx.config.js +++ b/examples/react/lynx.config.js @@ -16,6 +16,9 @@ export default defineConfig({ }, }), ], + performance: { + profile: true, + }, tools: { rspack: { plugins: [ diff --git a/package.json b/package.json index 732ef468f7..222d5a0fda 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@vitest/coverage-v8": "^3.1.3", "@vitest/eslint-plugin": "^1.1.44", "@vitest/ui": "^3.1.3", - "cspell": "^9.0.0", + "cspell": "^9.0.1", "dprint": "^0.49.1", "eslint": "^9.26.0", "eslint-import-resolver-typescript": "^4.3.4", @@ -37,7 +37,7 @@ "eslint-plugin-n": "^17.17.0", "eslint-plugin-regexp": "^2.7.0", "eslint-plugin-unicorn": "^59.0.1", - "globals": "^16.0.0", + "globals": "^16.1.0", "husky": "^9.1.7", "lint-staged": "^15.5.2", "sort-package-json": "^3.2.0", diff --git a/packages/react/README.md b/packages/react/README.md index cf1c3df00b..62d2701e27 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -28,6 +28,7 @@ ## Content +- [Content](#content) - [Getting Started](#getting-started) - [Documentation](#documentation) - [Community and Support](#community-and-support) @@ -67,6 +68,7 @@ ReactLynx is [Apache License 2.0](https://github.com/lynx-family/lynx-stack/blob Thanks to: -- [Preact](https://preactjs.com/) for creating a lightweight and efficient UI library that served as a foundation for the ReactLynx project. -- [React](https://react.dev/) for creating a comprehensive and intuitive library for building user interfaces and providing the inspiration for ReactLynx's development model. +- [Preact](https://preactjs.com/) for creating a lightweight and efficient implementation of React's APIs that served as the foundation for ReactLynx runtime. +- [React](https://react.dev/) for creating a gaming-changing UI library and programming model that has inspired a generation of declarative UI technologies. +- [Reanimated](https://docs.swmansion.com/react-native-reanimated/), [React Server Component](https://react.dev/reference/rsc/server-components) and [Web Worklet](https://developer.mozilla.org/en-US/docs/Web/API/Worklet) for inspiring ReactLynx's dual-threaded programming models such as [Main Thread Scripting](https://lynxjs.org/react/main-thread-script.html). - [SWC](https://github.com/swc-project/swc) project created by [@kdy1](https://github.com/kdy1), which turbocharges ReactLynx's code transformation with Rust-powered efficiency, achieving sub-second build times and frictionless developer experience. diff --git a/packages/react/runtime/package.json b/packages/react/runtime/package.json index 0bf2044169..e401b87d37 100644 --- a/packages/react/runtime/package.json +++ b/packages/react/runtime/package.json @@ -2,7 +2,7 @@ "name": "@lynx-js/react-runtime", "version": "0.100.1", "private": true, - "description": "All-in-one package for React on Lynx (3.0)", + "description": "All-in-one package for React on Lynx", "type": "module", "main": "src/index.ts", "module": "src/index.ts", diff --git a/packages/react/runtime/src/backgroundSnapshot.ts b/packages/react/runtime/src/backgroundSnapshot.ts index af32041379..cc27f82b48 100644 --- a/packages/react/runtime/src/backgroundSnapshot.ts +++ b/packages/react/runtime/src/backgroundSnapshot.ts @@ -1,31 +1,38 @@ // 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. + +/** + * Background snapshot implementation that runs in the background thread. + * + * This is the mirror of main thread's {@link SnapshotInstance}: + */ + import type { Worklet } from '@lynx-js/react/worklet-runtime/bindings'; +import { processGestureBackground } from './gesture/processGestureBagkround.js'; +import type { GestureKind } from './gesture/types.js'; import { diffArrayAction, diffArrayLepus } from './hydrate.js'; import { globalBackgroundSnapshotInstancesToRemove } from './lifecycle/patch/commit.js'; -import { markRefToRemove } from './snapshot/ref.js'; -import { transformSpread } from './snapshot/spread.js'; -import { - DynamicPartType, - backgroundSnapshotInstanceManager, - snapshotManager, - traverseSnapshotInstance, -} from './snapshot.js'; -import type { SerializedSnapshotInstance } from './snapshot.js'; +import type { SnapshotPatch } from './lifecycle/patch/snapshotPatch.js'; import { SnapshotOperation, __globalSnapshotPatch, initGlobalSnapshotPatch, takeGlobalSnapshotPatch, } from './lifecycle/patch/snapshotPatch.js'; -import type { SnapshotPatch } from './lifecycle/patch/snapshotPatch.js'; +import { globalPipelineOptions } from './lynx/performance.js'; +import type { SerializedSnapshotInstance } from './snapshot.js'; +import { + DynamicPartType, + backgroundSnapshotInstanceManager, + snapshotManager, + traverseSnapshotInstance, +} from './snapshot.js'; +import { markRefToRemove } from './snapshot/ref.js'; +import { transformSpread } from './snapshot/spread.js'; import { isDirectOrDeepEqual } from './utils.js'; import { onPostWorkletCtx } from './worklet/ctx.js'; -import { processGestureBackground } from './gesture/processGestureBagkround.js'; -import type { GestureKind } from './gesture/types.js'; -import { globalPipelineOptions } from './lynx/performance.js'; export class BackgroundSnapshotInstance { constructor(public type: string) { diff --git a/packages/react/runtime/src/document.ts b/packages/react/runtime/src/document.ts index 437122d140..a326180c05 100644 --- a/packages/react/runtime/src/document.ts +++ b/packages/react/runtime/src/document.ts @@ -4,8 +4,35 @@ import { BackgroundSnapshotInstance } from './backgroundSnapshot.js'; import { SnapshotInstance } from './snapshot.js'; -const document: any = {}; +/** + * This module implements an Interface Adapter Pattern to integrate Preact's + * rendering system with Lynx's custom Snapshot-based virtual DOM. + * + * It works by: + * 1. Defining a minimal {@link Document}-like interface that Preact expects + * 2. Implementing this interface to return our {@link Snapshot} instances + * 3. Maintaining the same method signatures as the standard DOM API + * + * This allows Preact to build its virtual tree using our Snapshot system + * without knowing it's not working with a real DOM. + */ +/** + * Defines the minimal document interface that Preact expects, depending on + * which thread is running. + */ +interface SnapshotDocumentAdapter { + createElement(type: string): BackgroundSnapshotInstance | SnapshotInstance; + createElementNS(ns: string | null, type: string): BackgroundSnapshotInstance | SnapshotInstance; + createTextNode(text: string): BackgroundSnapshotInstance | SnapshotInstance; +} + +const document: SnapshotDocumentAdapter = {} as SnapshotDocumentAdapter; + +/** + * Sets up the document interface for the background thread. + * All DOM operations are intercepted to create {@link BackgroundSnapshotInstance}. + */ function setupBackgroundDocument(): void { document.createElement = function(type: string) { return new BackgroundSnapshotInstance(type); @@ -25,6 +52,10 @@ function setupBackgroundDocument(): void { }; } +/** + * Sets up the document interface for the main thread. + * All DOM operations are intercepted to create {@link SnapshotInstance}. + */ function setupDocument(): void { document.createElement = function(type: string) { return new SnapshotInstance(type); @@ -50,4 +81,4 @@ function setupDocument(): void { // setupDocument(); // } -export { setupBackgroundDocument, setupDocument, document }; +export { document, setupBackgroundDocument, setupDocument }; diff --git a/packages/react/runtime/src/lifecycle/delayUnmount.ts b/packages/react/runtime/src/lifecycle/delayUnmount.ts index b4e266aab5..b95dce426c 100644 --- a/packages/react/runtime/src/lifecycle/delayUnmount.ts +++ b/packages/react/runtime/src/lifecycle/delayUnmount.ts @@ -1,8 +1,8 @@ // 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 { options } from 'preact'; import type { VNode } from 'preact'; +import { options } from 'preact'; import { CATCH_ERROR, COMPONENT, DIFF, VNODE } from '../renderToOpcodes/constants.js'; @@ -74,4 +74,4 @@ function initDelayUnmount(): void { }; } -export { initDelayUnmount, takeDelayedUnmounts, runDelayedUnmounts }; +export { initDelayUnmount, runDelayedUnmounts, takeDelayedUnmounts }; diff --git a/packages/react/runtime/src/lifecycle/patch/commit.ts b/packages/react/runtime/src/lifecycle/patch/commit.ts index 2a50f4a768..ad3937e3f2 100644 --- a/packages/react/runtime/src/lifecycle/patch/commit.ts +++ b/packages/react/runtime/src/lifecycle/patch/commit.ts @@ -1,12 +1,28 @@ // 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. + +/** + * Implements the commit phase of the rendering lifecycle. + * This module patches Preact's commit phase to integrate with the snapshot system, + * handling the collection and transmission of patches between threads. + * + * The commit phase is responsible for: + * - Collecting patches from the snapshot system + * - Managing commit tasks and their execution + * - Coordinating with the native layer for updates + * - Handling performance timing and pipeline options + */ + +/** + * This module patches Preact's commit phase by hacking into the internal of + * its [options](https://preactjs.com/guide/v10/options/) API + */ + import type { VNode } from 'preact'; import { options } from 'preact'; import type { Component } from 'preact/compat'; -import type { SnapshotPatch } from './snapshotPatch.js'; -import { takeGlobalSnapshotPatch } from './snapshotPatch.js'; import { LifecycleConstant } from '../../lifecycleConstant.js'; import { PerformanceTimingKeys, @@ -16,12 +32,14 @@ import { setPipeline, } from '../../lynx/performance.js'; import { CATCH_ERROR, COMMIT, RENDER_CALLBACKS, VNODE } from '../../renderToOpcodes/constants.js'; -import { updateBackgroundRefs } from '../../snapshot/ref.js'; import { backgroundSnapshotInstanceManager } from '../../snapshot.js'; +import { updateBackgroundRefs } from '../../snapshot/ref.js'; import { isEmptyObject } from '../../utils.js'; import { takeWorkletRefInitValuePatch } from '../../worklet/workletRefPool.js'; import { runDelayedUnmounts, takeDelayedUnmounts } from '../delayUnmount.js'; import { getReloadVersion } from '../pass.js'; +import type { SnapshotPatch } from './snapshotPatch.js'; +import { takeGlobalSnapshotPatch } from './snapshotPatch.js'; let globalFlushOptions: FlushOptions = {}; @@ -30,34 +48,50 @@ let nextCommitTaskId = 1; let globalBackgroundSnapshotInstancesToRemove: number[] = []; +/** + * A single patch operation. + */ interface Patch { id: number; snapshotPatch?: SnapshotPatch; workletRefInitValuePatch?: [id: number, value: unknown][]; } +/** + * List of patches to be applied in a single update cycle with flush options. + */ interface PatchList { patchList: Patch[]; flushOptions?: FlushOptions; } +/** + * Configuration options for patch operations + */ interface PatchOptions { pipelineOptions?: PipelineOptions; reloadVersion: number; isHydration?: boolean; } +/** + * Replaces Preact's default commit hook with our custom implementation + */ function replaceCommitHook(): void { - const oldCommit = options[COMMIT]; + const originalPreactCommit = options[COMMIT]; const commit = async (vnode: VNode, commitQueue: any[]) => { - if (__LEPUS__) { + // Skip commit phase for MT runtime + if (__MAIN_THREAD__) { // for testing only commitQueue.length = 0; return; } + // Mark the end of virtual DOM diffing phase for performance tracking markTimingLegacy(PerformanceTimingKeys.updateDiffVdomEnd); markTiming(PerformanceTimingKeys.diffVdomEnd); + + // The callback functions to be called after components are rendered. const renderCallbacks = commitQueue.map((component: Component) => { const ret = { component, @@ -68,16 +102,19 @@ function replaceCommitHook(): void { return ret; }); commitQueue.length = 0; + const delayedUnmounts = takeDelayedUnmounts(); const backgroundSnapshotInstancesToRemove = globalBackgroundSnapshotInstancesToRemove; globalBackgroundSnapshotInstancesToRemove = []; const commitTaskId = genCommitTaskId(); + + // Register the commit task globalCommitTaskMap.set(commitTaskId, () => { updateBackgroundRefs(commitTaskId); runDelayedUnmounts(delayedUnmounts); - oldCommit?.(vnode, renderCallbacks); + originalPreactCommit?.(vnode, renderCallbacks); renderCallbacks.some(wrapper => { try { wrapper[RENDER_CALLBACKS].some((cb: (this: Component) => void) => { @@ -96,6 +133,7 @@ function replaceCommitHook(): void { } }); + // Collect patches for this update const snapshotPatch = takeGlobalSnapshotPatch(); const flushOptions = globalFlushOptions; const workletRefInitValuePatch = takeWorkletRefInitValuePatch(); @@ -123,6 +161,7 @@ function replaceCommitHook(): void { } const obj = commitPatchUpdate(patchList, {}); + // Send the update to the native layer lynx.getNativeApp().callLepusMethod(LifecycleConstant.patchUpdate, obj, () => { const commitTask = globalCommitTaskMap.get(commitTaskId); if (commitTask) { @@ -134,6 +173,9 @@ function replaceCommitHook(): void { options[COMMIT] = commit as ((...args: Parameters) => void); } +/** + * Prepares the patch update for transmission to the native layer + */ function commitPatchUpdate(patchList: PatchList, patchOptions: Omit): { data: string; patchOptions: PatchOptions; @@ -169,9 +211,16 @@ function commitPatchUpdate(patchList: PatchList, patchOptions: Omit(code: string): T { return new Function(`return ${code}`)(); diff --git a/packages/react/runtime/src/lifecycle/reload.ts b/packages/react/runtime/src/lifecycle/reload.ts index b8d1bf9f03..7ffd950e0b 100644 --- a/packages/react/runtime/src/lifecycle/reload.ts +++ b/packages/react/runtime/src/lifecycle/reload.ts @@ -1,17 +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. + +/** + * Implements the reload (thinking of "refresh" in browser) for both main thread + * and background thread. + */ + import { render } from 'preact'; import { hydrate } from '../hydrate.js'; import { LifecycleConstant } from '../lifecycleConstant.js'; import { __pendingListUpdates } from '../list.js'; import { __root, setRoot } from '../root.js'; -import { takeGlobalRefPatchMap } from '../snapshot/ref.js'; import { SnapshotInstance, __page, snapshotInstanceManager } from '../snapshot.js'; +import { takeGlobalRefPatchMap } from '../snapshot/ref.js'; import { isEmptyObject } from '../utils.js'; -import { destroyBackground } from './destroy.js'; import { destroyWorklet } from '../worklet/destroy.js'; +import { destroyBackground } from './destroy.js'; import { clearJSReadyEventIdSwap, isJSReady } from './event/jsReady.js'; import { increaseReloadVersion } from './pass.js'; import { deinitGlobalSnapshotPatch } from './patch/snapshotPatch.js'; diff --git a/packages/react/runtime/src/lifecycle/render.ts b/packages/react/runtime/src/lifecycle/render.ts index c7823a72fa..1b47af534d 100644 --- a/packages/react/runtime/src/lifecycle/render.ts +++ b/packages/react/runtime/src/lifecycle/render.ts @@ -1,6 +1,11 @@ // 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. + +/** + * Implements the IFR (Instant First-Frame Rendering) on main thread. + */ + import { render } from 'preact'; import { renderOpcodesInto } from '../opcodes.js'; diff --git a/packages/react/runtime/src/lynx-api.ts b/packages/react/runtime/src/lynx-api.ts index 3c369b795a..379c08d74a 100644 --- a/packages/react/runtime/src/lynx-api.ts +++ b/packages/react/runtime/src/lynx-api.ts @@ -43,13 +43,13 @@ export interface Root { * return ... * } * - * if (__LEPUS__) { + * if (__MAIN_THREAD__) { * root.render( * * * * ); - * } else if (__JS__) { + * } else if (__BACKGROUND__) { * fetchData().then((data) => { * root.render( * @@ -82,7 +82,7 @@ export interface Root { */ export const root: Root = { render: (jsx: ReactNode): void => { - if (__LEPUS__) { + if (__MAIN_THREAD__) { __root.__jsx = jsx; } else { __root.__jsx = jsx; @@ -370,7 +370,7 @@ export interface Lynx { registerDataProcessors: (dataProcessorDefinition?: DataProcessorDefinition) => void; } -export { runOnMainThread } from './worklet/runOnMainThread.js'; +export { useLynxGlobalEventListener } from './hooks/useLynxGlobalEventListener.js'; export { runOnBackground } from './worklet/runOnBackground.js'; +export { runOnMainThread } from './worklet/runOnMainThread.js'; export { MainThreadRef, useMainThreadRef } from './worklet/workletRef.js'; -export { useLynxGlobalEventListener } from './hooks/useLynxGlobalEventListener.js'; diff --git a/packages/react/runtime/src/lynx.ts b/packages/react/runtime/src/lynx.ts index 7ad7474499..73232e3a8b 100644 --- a/packages/react/runtime/src/lynx.ts +++ b/packages/react/runtime/src/lynx.ts @@ -18,14 +18,14 @@ import { injectTt } from './lynx/tt.js'; export { runWithForce } from './lynx/runWithForce.js'; // @ts-expect-error Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature -if (__LEPUS__ && typeof globalThis.processEvalResult === 'undefined') { +if (__MAIN_THREAD__ && typeof globalThis.processEvalResult === 'undefined') { // @ts-expect-error Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature globalThis.processEvalResult = (result: ((schema: string) => T) | undefined, schema: string) => { return result?.(schema); }; } -if (__LEPUS__) { +if (__MAIN_THREAD__) { injectCalledByNative(); injectUpdateMainThread(); if (__DEV__) { @@ -39,8 +39,9 @@ if (__PROFILE__) { initProfileHook(); } -if (__JS__) { - options.document = document; +if (__BACKGROUND__) { + // Trick Preact and TypeScript to accept our custom document adapter. + options.document = document as any; setupBackgroundDocument(); injectTt(); diff --git a/packages/react/runtime/src/renderToOpcodes/index.ts b/packages/react/runtime/src/renderToOpcodes/index.ts index 929b55bbf8..0a08d5778d 100644 --- a/packages/react/runtime/src/renderToOpcodes/index.ts +++ b/packages/react/runtime/src/renderToOpcodes/index.ts @@ -2,7 +2,12 @@ // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. -// modified from preact-render-to-string@6.0.3 +/** + * Implements rendering to opcodes. + * This module is modified from preact-render-to-string@6.0.3 to generate + * opcodes instead of HTML strings for Lynx. + */ + // @ts-nocheck import { Fragment, h, options } from 'preact'; diff --git a/packages/react/runtime/src/root.ts b/packages/react/runtime/src/root.ts index f4bb58f7d1..93c17ce102 100644 --- a/packages/react/runtime/src/root.ts +++ b/packages/react/runtime/src/root.ts @@ -4,15 +4,19 @@ import { BackgroundSnapshotInstance } from './backgroundSnapshot.js'; import { SnapshotInstance } from './snapshot.js'; +/** + * The internal ReactLynx's root. + * {@link @lynx-js/react!Root | root}. + */ let __root: (SnapshotInstance | BackgroundSnapshotInstance) & { __jsx?: React.ReactNode; __opcodes?: any[] }; function setRoot(root: typeof __root): void { __root = root; } -if (__LEPUS__) { +if (__MAIN_THREAD__) { setRoot(new SnapshotInstance('root')); -} else if (__JS__) { +} else if (__BACKGROUND__) { setRoot(new BackgroundSnapshotInstance('root')); } diff --git a/packages/react/runtime/src/snapshot.ts b/packages/react/runtime/src/snapshot.ts index 71344dd5b0..30ece552d1 100644 --- a/packages/react/runtime/src/snapshot.ts +++ b/packages/react/runtime/src/snapshot.ts @@ -1,26 +1,44 @@ // 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. + +/** + * Core snapshot system that implements a compiler-hinted virtual DOM. + * + * Key components: + * 1. {@link Snapshot}: Template definition generated at compile time + * 2. {@link SnapshotInstance}: Runtime instance in the main thread + * 3. {@link BackgroundSnapshotInstance}: Runtime instance in the background thread + * + * The system uses static analysis to identify dynamic parts and generate + * optimized update instructions, avoiding full virtual DOM diffing. + */ + import type { Worklet, WorkletRefImpl } from '@lynx-js/react/worklet-runtime/bindings'; import type { BackgroundSnapshotInstance } from './backgroundSnapshot.js'; +import { SnapshotOperation, __globalSnapshotPatch } from './lifecycle/patch/snapshotPatch.js'; import { ListUpdateInfoRecording, __pendingListUpdates, snapshotDestroyList } from './list.js'; import { unref } from './snapshot/ref.js'; -import { SnapshotOperation, __globalSnapshotPatch } from './lifecycle/patch/snapshotPatch.js'; import { isDirectOrDeepEqual } from './utils.js'; +/** + * Types of dynamic parts that can be updated in a snapshot + * These are determined at compile time through static analysis + */ export const enum DynamicPartType { - Attr = 0, - Spread, - Slot, - // Component, - Children, - ListChildren, - - // Used by compat layer - MultiChildren, + Attr = 0, // Regular attribute updates + Spread, // Spread operator in JSX + Slot, // Slot for component children + Children, // Regular children updates + ListChildren, // List/array children updates + MultiChildren, // Multiple children updates (compat layer) } +/** + * A snapshot definition that contains all the information needed to create and update elements + * This is generated at compile time through static analysis of the JSX + */ interface Snapshot { create: null | ((ctx: SnapshotInstance) => FiberElement[]); update: null | ((ctx: SnapshotInstance, index: number, oldValue: any) => void)[]; @@ -234,6 +252,13 @@ export interface SerializedSnapshotInstance { const DEFAULT_ENTRY_NAME = '__Card__'; const DEFAULT_CSS_ID = 0; +/** + * The runtime instance of a {@link Snapshot} on the main thread that manages + * the actual elements and handles updates to dynamic parts. + * + * This class is designed to be compatible with Preact's {@link ContainerNode} + * interface for Preact's renderer to operate upon. + */ export class SnapshotInstance { __id: number; __snapshot_def: Snapshot; diff --git a/packages/react/runtime/src/snapshot/ref.ts b/packages/react/runtime/src/snapshot/ref.ts index 632de3067a..248be086af 100644 --- a/packages/react/runtime/src/snapshot/ref.ts +++ b/packages/react/runtime/src/snapshot/ref.ts @@ -137,12 +137,12 @@ function markRefToRemove(sign: string, ref: unknown): void { } export { - updateRef, - takeGlobalRefPatchMap, - updateBackgroundRefs, - unref, - transformRef, globalRefsToRemove, globalRefsToSet, markRefToRemove, + takeGlobalRefPatchMap, + transformRef, + unref, + updateBackgroundRefs, + updateRef, }; diff --git a/packages/react/runtime/src/snapshot/spread.ts b/packages/react/runtime/src/snapshot/spread.ts index 2d06a78512..678c39ea55 100644 --- a/packages/react/runtime/src/snapshot/spread.ts +++ b/packages/react/runtime/src/snapshot/spread.ts @@ -1,16 +1,24 @@ // 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. + +/** + * Handles JSX spread operator in the snapshot system. + * + * Spread operators in JSX (e.g.,
) are transformed into + * optimized attribute updates at compile time, avoiding runtime object spreads. + */ + +import { BackgroundSnapshotInstance } from '../backgroundSnapshot.js'; +import { __pendingListUpdates, ListUpdateInfoRecording } from '../list.js'; import { SnapshotInstance } from '../snapshot.js'; +import { isDirectOrDeepEqual, isEmptyObject, pick } from '../utils.js'; import { updateEvent } from './event.js'; -import { BackgroundSnapshotInstance } from '../backgroundSnapshot.js'; +import { updateGesture } from './gesture.js'; +import { platformInfoAttributes, updateListItemPlatformInfo } from './platformInfo.js'; import { transformRef, updateRef } from './ref.js'; import { updateWorkletEvent } from './workletEvent.js'; import { updateWorkletRef } from './workletRef.js'; -import { updateGesture } from './gesture.js'; -import { platformInfoAttributes, updateListItemPlatformInfo } from './platformInfo.js'; -import { isDirectOrDeepEqual, isEmptyObject, pick } from '../utils.js'; -import { __pendingListUpdates, ListUpdateInfoRecording } from '../list.js'; const eventRegExp = /^(([A-Za-z-]*):)?(bind|catch|capture-bind|capture-catch|global-bind)([A-Za-z]+)$/; const eventTypeMap: Record = { @@ -284,4 +292,4 @@ function transformSpread( return result; } -export { updateSpread, transformSpread }; +export { transformSpread, updateSpread }; diff --git a/packages/react/runtime/types/types.d.ts b/packages/react/runtime/types/types.d.ts index 496097f4b0..aca626ee45 100644 --- a/packages/react/runtime/types/types.d.ts +++ b/packages/react/runtime/types/types.d.ts @@ -182,6 +182,7 @@ declare global { dsl: string; stage: string; } + declare let lynxCoreInject: any; interface ISystemInfo { diff --git a/packages/rspeedy/core/package.json b/packages/rspeedy/core/package.json index 3439fec491..089addb782 100644 --- a/packages/rspeedy/core/package.json +++ b/packages/rspeedy/core/package.json @@ -75,7 +75,7 @@ "rsbuild-plugin-publint": "0.3.1", "tiny-invariant": "^1.3.3", "ts-blank-space": "^0.6.1", - "type-fest": "^4.40.1", + "type-fest": "^4.41.0", "typia": "9.1.1", "typia-rspack-plugin": "2.0.1", "vitest": "^3.1.3", diff --git a/packages/rspeedy/core/src/config/source/entry.ts b/packages/rspeedy/core/src/config/source/entry.ts index 52040df7b3..c844e60f39 100644 --- a/packages/rspeedy/core/src/config/source/entry.ts +++ b/packages/rspeedy/core/src/config/source/entry.ts @@ -44,7 +44,9 @@ export interface EntryDescription { * ```js * import { defineConfig } from '@lynx-js/rspeedy' * export default defineConfig({ - * entry: './src/pages/main/index.js', + * source: { + * entry: './src/pages/main/index.js', + * } * }) * ``` * @@ -55,7 +57,9 @@ export interface EntryDescription { * ```js * import { defineConfig } from '@lynx-js/rspeedy' * export default defineConfig({ - * entry: ['./src/prefetch.js', './src/pages/main/index.js'], + * source: { + * entry: ['./src/prefetch.js', './src/pages/main/index.js'], + * } * }) * ``` * @@ -66,10 +70,12 @@ export interface EntryDescription { * ```js * import { defineConfig } from '@lynx-js/rspeedy' * export default defineConfig({ - * entry: { - * foo: './src/pages/foo/index.js', - * bar: ['./src/pages/bar/index.js', './src/post.js'], // multiple entry modules is allowed - * }, + * source: { + * entry: { + * foo: './src/pages/foo/index.js', + * bar: ['./src/pages/bar/index.js', './src/post.js'], // multiple entry modules is allowed + * } + * } * }) * ``` * @@ -80,12 +86,14 @@ export interface EntryDescription { * ```js * import { defineConfig } from '@lynx-js/rspeedy' * export default defineConfig({ - * entry: { - * foo: './src/pages/foo/index.js', - * bar: { - * import: ['./src/prefetch.js', './src/pages/bar'], - * }, - * }, + * source: { + * entry: { + * foo: './src/pages/foo/index.js', + * bar: { + * import: ['./src/prefetch.js', './src/pages/bar'], + * } + * } + * } * }) * ``` * @public diff --git a/packages/rspeedy/plugin-react/package.json b/packages/rspeedy/plugin-react/package.json index 4ce3e0b5d2..9e5f9546b1 100644 --- a/packages/rspeedy/plugin-react/package.json +++ b/packages/rspeedy/plugin-react/package.json @@ -59,7 +59,7 @@ "@rsbuild/webpack": "catalog:rsbuild", "@samchon/openapi": "4.1.0", "tailwindcss": "^3.4.17", - "type-fest": "^4.40.1", + "type-fest": "^4.41.0", "typia": "9.1.1", "typia-rspack-plugin": "2.0.1" }, diff --git a/packages/rspeedy/plugin-react/src/entry.ts b/packages/rspeedy/plugin-react/src/entry.ts index 83f13b8b8d..12ea3a2ab7 100644 --- a/packages/rspeedy/plugin-react/src/entry.ts +++ b/packages/rspeedy/plugin-react/src/entry.ts @@ -233,6 +233,8 @@ export function applyEntry( .end() } + const rsbuildConfig = api.getRsbuildConfig() + chain .plugin(PLUGIN_NAME_REACT) .after(PLUGIN_NAME_TEMPLATE) @@ -244,6 +246,7 @@ export function applyEntry( mainThreadChunks, extractStr, experimental_isLazyBundle, + profile: rsbuildConfig.performance?.profile, }]) }) } diff --git a/packages/rspeedy/plugin-react/test/config.test.ts b/packages/rspeedy/plugin-react/test/config.test.ts index 9edb3c4be3..a52a8099d1 100644 --- a/packages/rspeedy/plugin-react/test/config.test.ts +++ b/packages/rspeedy/plugin-react/test/config.test.ts @@ -1615,6 +1615,118 @@ describe('Config', () => { vi.unstubAllEnvs() }) }) + + describe('Profile', () => { + test('default', async () => { + vi.stubEnv('DEBUG', '') + + const { pluginReactLynx } = await import('../src/pluginReactLynx.js') + + const rspeedy = await createRspeedy({ + rspeedyConfig: { + plugins: [ + pluginReactLynx(), + ], + }, + }) + + const [config] = await rspeedy.initConfigs() + + const ReactLynxWebpackPlugin = config?.plugins?.find(( + p, + ): p is ReactWebpackPlugin => + p?.constructor.name === 'ReactWebpackPlugin' + ) + + // @ts-expect-error private field + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + expect(ReactLynxWebpackPlugin?.options.profile).toBe(false) + }) + + test('with DEBUG', async () => { + vi.stubEnv('DEBUG', 'rspeedy') + + const { pluginReactLynx } = await import('../src/pluginReactLynx.js') + + const rspeedy = await createRspeedy({ + rspeedyConfig: { + plugins: [ + pluginReactLynx(), + ], + }, + }) + + const [config] = await rspeedy.initConfigs() + + const ReactLynxWebpackPlugin = config?.plugins?.find(( + p, + ): p is ReactWebpackPlugin => + p?.constructor.name === 'ReactWebpackPlugin' + ) + + // @ts-expect-error private field + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + expect(ReactLynxWebpackPlugin?.options.profile).toBe(true) + }) + + test('with performance.profile: true', async () => { + vi.stubEnv('DEBUG', '') + + const { pluginReactLynx } = await import('../src/pluginReactLynx.js') + + const rspeedy = await createRspeedy({ + rspeedyConfig: { + performance: { + profile: true, + }, + plugins: [ + pluginReactLynx(), + ], + }, + }) + + const [config] = await rspeedy.initConfigs() + + const ReactLynxWebpackPlugin = config?.plugins?.find(( + p, + ): p is ReactWebpackPlugin => + p?.constructor.name === 'ReactWebpackPlugin' + ) + + // @ts-expect-error private field + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + expect(ReactLynxWebpackPlugin?.options.profile).toBe(true) + }) + + test('with performance.profile: false', async () => { + vi.stubEnv('DEBUG', '') + + const { pluginReactLynx } = await import('../src/pluginReactLynx.js') + + const rspeedy = await createRspeedy({ + rspeedyConfig: { + performance: { + profile: false, + }, + plugins: [ + pluginReactLynx(), + ], + }, + }) + + const [config] = await rspeedy.initConfigs() + + const ReactLynxWebpackPlugin = config?.plugins?.find(( + p, + ): p is ReactWebpackPlugin => + p?.constructor.name === 'ReactWebpackPlugin' + ) + + // @ts-expect-error private field + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + expect(ReactLynxWebpackPlugin?.options.profile).toBe(false) + }) + }) }) describe('MPA Config', () => { diff --git a/packages/rspeedy/upgrade-rspeedy/package.json b/packages/rspeedy/upgrade-rspeedy/package.json index 1e195e84d6..eb082d16df 100644 --- a/packages/rspeedy/upgrade-rspeedy/package.json +++ b/packages/rspeedy/upgrade-rspeedy/package.json @@ -49,7 +49,7 @@ "picocolors": "^1.1.1", "rsbuild-plugin-tailwindcss": "0.2.1", "rslog": "^1.2.3", - "type-fest": "^4.40.1" + "type-fest": "^4.41.0" }, "engines": { "node": ">=18" diff --git a/packages/webpack/react-webpack-plugin/src/ReactWebpackPlugin.ts b/packages/webpack/react-webpack-plugin/src/ReactWebpackPlugin.ts index 49f3fad5e6..78c6c45de0 100644 --- a/packages/webpack/react-webpack-plugin/src/ReactWebpackPlugin.ts +++ b/packages/webpack/react-webpack-plugin/src/ReactWebpackPlugin.ts @@ -73,6 +73,13 @@ interface ReactWebpackPluginOptions { * @alpha */ experimental_isLazyBundle?: boolean; + + /** + * Whether to enable profile. + * + * @defaultValue `false` when production, `true` when development + */ + profile?: boolean | undefined; } /** @@ -145,6 +152,7 @@ class ReactWebpackPlugin { mainThreadChunks: [], extractStr: false, experimental_isLazyBundle: false, + profile: undefined, }); /** @@ -180,7 +188,9 @@ class ReactWebpackPlugin { // We enable profile by default in development. // It can also be disabled by environment variable `REACT_PROFILE=false` __PROFILE__: JSON.stringify( - process.env['REACT_PROFILE'] ?? compiler.options.mode === 'development', + options.profile + ?? process.env['REACT_PROFILE'] + ?? compiler.options.mode === 'development', ), __EXTRACT_STR__: JSON.stringify(Boolean(options.extractStr)), __FIRST_SCREEN_SYNC_TIMING__: JSON.stringify( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a14e57ecf..69638059de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,8 +11,8 @@ catalogs: version: 7.52.7 rsbuild: '@rsbuild/core': - specifier: 1.3.15 - version: 1.3.15 + specifier: 1.3.17 + version: 1.3.17 '@rsbuild/plugin-less': specifier: 1.2.4 version: 1.2.4 @@ -92,8 +92,8 @@ importers: specifier: ^3.1.3 version: 3.1.3(vitest@3.1.3) cspell: - specifier: ^9.0.0 - version: 9.0.0 + specifier: ^9.0.1 + version: 9.0.1 dprint: specifier: ^0.49.1 version: 0.49.1 @@ -122,8 +122,8 @@ importers: specifier: ^59.0.1 version: 59.0.1(eslint@9.26.0(jiti@2.4.2)) globals: - specifier: ^16.0.0 - version: 16.0.0 + specifier: ^16.1.0 + version: 16.1.0 husky: specifier: ^9.1.7 version: 9.1.7 @@ -149,15 +149,6 @@ importers: specifier: ^3.1.3 version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.3)(@vitest/ui@3.1.3)(jsdom@26.1.0)(sass-embedded@1.86.0)(terser@5.31.6) - .github/actions/eco-ci: - dependencies: - '@actions/core': - specifier: ^1.11.1 - version: 1.11.1 - '@actions/github': - specifier: ^6.0.0 - version: 6.0.0 - examples/react: dependencies: '@lynx-js/react': @@ -292,13 +283,13 @@ importers: version: link:../websocket '@rsbuild/core': specifier: catalog:rsbuild - version: 1.3.15 + version: 1.3.17 '@rsbuild/plugin-css-minimizer': specifier: 1.0.2 - version: 1.0.2(@rsbuild/core@1.3.15)(webpack@5.99.8) + version: 1.0.2(@rsbuild/core@1.3.17)(webpack@5.99.8) '@rsdoctor/rspack-plugin': specifier: 1.0.2 - version: 1.0.2(@rsbuild/core@1.3.15)(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) + version: 1.0.2(@rsbuild/core@1.3.17)(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) typescript: specifier: 5.1.6 - 5.8.x version: 5.8.3 @@ -314,7 +305,7 @@ importers: version: 12.1.2(patch_hash=926ba262ec682d27369f1a8648a0dfb657fb5f1b28539ca3628d292276c91c3d)(rollup@4.34.9)(tslib@2.8.1)(typescript@5.8.3) '@rsbuild/webpack': specifier: catalog:rsbuild - version: 1.3.0(@rsbuild/core@1.3.15)(@rspack/core@1.3.9(@swc/helpers@0.5.17)) + version: 1.3.0(@rsbuild/core@1.3.17)(@rspack/core@1.3.9(@swc/helpers@0.5.17)) '@samchon/openapi': specifier: 4.1.0 version: 4.1.0 @@ -341,7 +332,7 @@ importers: version: 1.1.1 rsbuild-plugin-publint: specifier: 0.3.1 - version: 0.3.1(@rsbuild/core@1.3.15) + version: 0.3.1(@rsbuild/core@1.3.17) tiny-invariant: specifier: ^1.3.3 version: 1.3.3 @@ -349,8 +340,8 @@ importers: specifier: ^0.6.1 version: 0.6.1 type-fest: - specifier: ^4.40.1 - version: 4.40.1 + specifier: ^4.41.0 + version: 4.41.0 typia: specifier: 9.1.1 version: 9.1.1(@samchon/openapi@4.1.0)(typescript@5.8.3) @@ -396,7 +387,7 @@ importers: version: 7.52.7(@types/node@22.15.3) '@rsbuild/core': specifier: catalog:rsbuild - version: 1.3.15 + version: 1.3.17 picocolors: specifier: ^1.1.1 version: 1.1.1 @@ -448,19 +439,19 @@ importers: version: 12.1.2(patch_hash=926ba262ec682d27369f1a8648a0dfb657fb5f1b28539ca3628d292276c91c3d)(rollup@4.34.9)(tslib@2.8.1)(typescript@5.8.3) '@rsbuild/core': specifier: catalog:rsbuild - version: 1.3.15 + version: 1.3.17 '@rsbuild/plugin-sass': specifier: catalog:rsbuild - version: 1.3.1(@rsbuild/core@1.3.15) + version: 1.3.1(@rsbuild/core@1.3.17) '@rsbuild/plugin-typed-css-modules': specifier: 1.0.2 - version: 1.0.2(@rsbuild/core@1.3.15) + version: 1.0.2(@rsbuild/core@1.3.17) '@rsbuild/plugin-webpack-swc': specifier: catalog:rsbuild - version: 1.1.0(@rsbuild/core@1.3.15) + version: 1.1.0(@rsbuild/core@1.3.17) '@rsbuild/webpack': specifier: catalog:rsbuild - version: 1.3.0(@rsbuild/core@1.3.15)(@rspack/core@1.3.9(@swc/helpers@0.5.17)) + version: 1.3.0(@rsbuild/core@1.3.17)(@rspack/core@1.3.9(@swc/helpers@0.5.17)) '@samchon/openapi': specifier: 4.1.0 version: 4.1.0 @@ -468,8 +459,8 @@ importers: specifier: ^3.4.17 version: 3.4.17 type-fest: - specifier: ^4.40.1 - version: 4.40.1 + specifier: ^4.41.0 + version: 4.41.0 typia: specifier: 9.1.1 version: 9.1.1(@samchon/openapi@4.1.0)(typescript@5.8.3) @@ -497,7 +488,7 @@ importers: version: 7.52.7(@types/node@22.15.3) '@rsbuild/core': specifier: catalog:rsbuild - version: 1.3.15 + version: 1.3.17 packages/rspeedy/upgrade-rspeedy: devDependencies: @@ -524,10 +515,10 @@ importers: version: link:../../web-platform/web-elements '@rsbuild/plugin-less': specifier: catalog:rsbuild - version: 1.2.4(@rsbuild/core@1.3.16) + version: 1.2.4(@rsbuild/core@1.3.17) '@rsbuild/plugin-sass': specifier: catalog:rsbuild - version: 1.3.1(@rsbuild/core@1.3.16) + version: 1.3.1(@rsbuild/core@1.3.17) commander: specifier: ^13.1.0 version: 13.1.0 @@ -542,13 +533,13 @@ importers: version: 1.1.1 rsbuild-plugin-tailwindcss: specifier: 0.2.1 - version: 0.2.1(@rsbuild/core@1.3.16)(tailwindcss@3.4.17) + version: 0.2.1(@rsbuild/core@1.3.17)(tailwindcss@3.4.17) rslog: specifier: ^1.2.3 version: 1.2.3 type-fest: - specifier: ^4.40.1 - version: 4.40.1 + specifier: ^4.41.0 + version: 4.41.0 packages/rspeedy/websocket: dependencies: @@ -592,7 +583,7 @@ importers: version: 21.1.7 rsbuild-plugin-publint: specifier: 0.3.1 - version: 0.3.1(@rsbuild/core@1.3.16) + version: 0.3.1(@rsbuild/core@1.3.17) packages/third-party/tailwind-preset: devDependencies: @@ -709,10 +700,10 @@ importers: version: link:../web-rsbuild-plugin '@rsbuild/core': specifier: catalog:rsbuild - version: 1.3.15 + version: 1.3.17 '@rsdoctor/rspack-plugin': specifier: 1.0.2 - version: 1.0.2(@rsbuild/core@1.3.15)(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) + version: 1.0.2(@rsbuild/core@1.3.17)(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -746,7 +737,7 @@ importers: version: link:../web-elements '@rsbuild/core': specifier: catalog:rsbuild - version: 1.3.15 + version: 1.3.17 '@types/loader-utils': specifier: ^2.0.6 version: 2.0.6 @@ -1590,28 +1581,28 @@ packages: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 vitest: '>=1.2.2' - '@cspell/cspell-bundled-dicts@9.0.0': - resolution: {integrity: sha512-S2nM8iWGY252XrEOt9qAVMDgBBiQYcv7cxi/g1sBZL4sx/lDF02QSn926aVLYF9LNsGxjjliV7bbYoIU2oDjtQ==} + '@cspell/cspell-bundled-dicts@9.0.1': + resolution: {integrity: sha512-h7gTqg0VF4N8VhOPk66XewuSsT56OP2ujgxtAyYQ4H+NuYd3HMfS0h/I3/y9uBhllwOEamaeAzYhc5JF/qIrsQ==} engines: {node: '>=20'} - '@cspell/cspell-json-reporter@9.0.0': - resolution: {integrity: sha512-6ooEVbicB148ScT475aGMPlgRLO/XlLC/yNecrnVlB/sbERCgDYqi+iJHgE4+BjpVQ8Ant/VRCWrncWMAH6D8g==} + '@cspell/cspell-json-reporter@9.0.1': + resolution: {integrity: sha512-Rpn7Tuq9t8bZpXZFV43NkhCl0LaPDJZSON4/JFxGbOcH16ryXfrx7oObUTIIyxSxO3fGkzaJZHIwGibRJSsbNQ==} engines: {node: '>=20'} - '@cspell/cspell-pipe@9.0.0': - resolution: {integrity: sha512-ur1m4SOs9GP0eIC7n+II/Ea2xuEBWVI438d/zcoC+DWMElQD99OPxVVpPmGoMIPx4YzNlXWQH4kcygnG2a3ogg==} + '@cspell/cspell-pipe@9.0.1': + resolution: {integrity: sha512-bhFcvF2a8KYKVh/OebCfJ8LFw5GYHyUsUjAbxnznTBrYOFSIclDjwUwT29yVDXwnQkJkB6Px5Y9e2VvtFizVFg==} engines: {node: '>=20'} - '@cspell/cspell-resolver@9.0.0': - resolution: {integrity: sha512-D2bPNpKNmwJM7r28cK6gDpgZKslGALNeyjpg9jFJLfstvHyn9m6vXsZbDuOJLKoEU3CLhkDSmRyNiEb2n18xhA==} + '@cspell/cspell-resolver@9.0.1': + resolution: {integrity: sha512-AhIXAhX1qt7Y3EyiP/5rAk7Ow7DJpAyB44wPbfdF9p1vhnk6oQ7RslnD3G6S9o/vNxZ0DWFPREMWx19J/3c+hw==} engines: {node: '>=20'} - '@cspell/cspell-service-bus@9.0.0': - resolution: {integrity: sha512-KcvYBh/MrODNgavbjKTiWpI9BklGy9/suMCC/ZThUrjWpbndwHjxcbge4DLlKyVqYbe78B0KjKgZsuqQvOqJjg==} + '@cspell/cspell-service-bus@9.0.1': + resolution: {integrity: sha512-DoW6hLkFIO3BXePtUYQEax3FTH9fkwCUbf6qphAEXnr4PjoyPZsgBhR6iCrZd4DyhuFiRvK3Cgpq2o3O0NdODQ==} engines: {node: '>=20'} - '@cspell/cspell-types@9.0.0': - resolution: {integrity: sha512-iBtN+AVC1v/V35qGOzHLyIvFJEr3pljtJgB4pM0TIZuzPQrm9lr3vV+WSCeOXqiTuY8DEXeMCZN+30QOi4ElNQ==} + '@cspell/cspell-types@9.0.1': + resolution: {integrity: sha512-8FRmvyV1AYEepJB3J7jji1ZYG9yOK0eYr4WuUVPfUJa6N3HyeZjWKhxbVvqedmEI74f5Ls3cQKHY1T2Yvqk/ag==} engines: {node: '>=20'} '@cspell/dict-ada@4.1.0': @@ -1659,14 +1650,14 @@ packages: '@cspell/dict-elixir@4.0.7': resolution: {integrity: sha512-MAUqlMw73mgtSdxvbAvyRlvc3bYnrDqXQrx5K9SwW8F7fRYf9V4vWYFULh+UWwwkqkhX9w03ZqFYRTdkFku6uA==} - '@cspell/dict-en-common-misspellings@2.0.10': - resolution: {integrity: sha512-80mXJLtr0tVEtzowrI7ycVae/ULAYImZUlr0kUTpa8i57AUk7Zy3pYBs44EYIKW7ZC9AHu4Qjjfq4vriAtyTDQ==} + '@cspell/dict-en-common-misspellings@2.0.11': + resolution: {integrity: sha512-xFQjeg0wFHh9sFhshpJ+5BzWR1m9Vu8pD0CGPkwZLK9oii8AD8RXNchabLKy/O5VTLwyqPOi9qpyp1cxm3US4Q==} - '@cspell/dict-en-gb-mit@3.0.3': - resolution: {integrity: sha512-usV5ddTBRTFCHoN9Swo1Vt9U4uPNRHS9oLtjOTWJtVj5O0OxJ+NxCXCZjjCm0afe6gw/GuvlnE4Ji7Vf53ObfQ==} + '@cspell/dict-en-gb-mit@3.0.6': + resolution: {integrity: sha512-QYDwuXi9Yh+AvU1omhz8sWX+A1SxWI3zeK1HdGfTrICZavhp8xxcQGTa5zxTTFRCcQc483YzUH2Dl+6Zd50tJg==} - '@cspell/dict-en_us@4.4.6': - resolution: {integrity: sha512-9QFpNzyvqNkCc3QCJb2RmG87rXz2Iz3R6o9fknOyzN7HL/LRMwipuksricriPYPs+h3ZSQm4Jtgc+sX4gWY5vg==} + '@cspell/dict-en_us@4.4.8': + resolution: {integrity: sha512-OkNUVuU9Q+Sf827/61YPkk6ya6dSsllzeYniBFqNW9TkoqQXT3vggkgmtCE1aEhSvVctMwxpPYoC8pZgn1TeSA==} '@cspell/dict-filetypes@3.0.12': resolution: {integrity: sha512-+ds5wgNdlUxuJvhg8A1TjuSpalDFGCh7SkANCWvIplg6QZPXL4j83lqxP7PgjHpx7PsBUS7vw0aiHPjZy9BItw==} @@ -1689,8 +1680,8 @@ packages: '@cspell/dict-git@3.0.4': resolution: {integrity: sha512-C44M+m56rYn6QCsLbiKiedyPTMZxlDdEYAsPwwlL5bhMDDzXZ3Ic8OCQIhMbiunhCOJJT+er4URmOmM+sllnjg==} - '@cspell/dict-golang@6.0.20': - resolution: {integrity: sha512-b7nd9XXs+apMMzNSWorjirQsbmlwcTC0ViQJU8u+XNose3z0y7oNeEpbTPTVoN1+1sO9aOHuFwfwoOMFCDS14Q==} + '@cspell/dict-golang@6.0.21': + resolution: {integrity: sha512-D3wG1MWhFx54ySFJ00CS1MVjR4UiBVsOWGIjJ5Av+HamnguqEshxbF9mvy+BX0KqzdLVzwFkoLBs8QeOID56HA==} '@cspell/dict-google@1.0.8': resolution: {integrity: sha512-BnMHgcEeaLyloPmBs8phCqprI+4r2Jb8rni011A8hE+7FNk7FmLE3kiwxLFrcZnnb7eqM0agW4zUaNoB0P+z8A==} @@ -1772,8 +1763,8 @@ packages: '@cspell/dict-shell@1.1.0': resolution: {integrity: sha512-D/xHXX7T37BJxNRf5JJHsvziFDvh23IF/KvkZXNSh8VqcRdod3BAz9VGHZf6VDqcZXr1VRqIYR3mQ8DSvs3AVQ==} - '@cspell/dict-software-terms@5.0.7': - resolution: {integrity: sha512-6ttSc0/EzDN44DF2Bk/37cr3IntzuNcZ4MbUy/zEhfhDMiuQoXslILpAs/9FoKEuFpsm6A+8manT2GytWwr/HA==} + '@cspell/dict-software-terms@5.0.8': + resolution: {integrity: sha512-VsJesitvaHZpMgNwHHms3yDsZz7LNToC2HuSAnyt1znn37ribiJF1ty0jWhVQO6fv7K4PM1KsKTJIwqBwc446g==} '@cspell/dict-sql@2.2.0': resolution: {integrity: sha512-MUop+d1AHSzXpBvQgQkCiok8Ejzb+nrzyG16E8TvKL2MQeDwnIvMe3bv90eukP6E1HWb+V/MA/4pnq0pcJWKqQ==} @@ -1793,20 +1784,20 @@ packages: '@cspell/dict-vue@3.0.4': resolution: {integrity: sha512-0dPtI0lwHcAgSiQFx8CzvqjdoXROcH+1LyqgROCpBgppommWpVhbQ0eubnKotFEXgpUCONVkeZJ6Ql8NbTEu+w==} - '@cspell/dynamic-import@9.0.0': - resolution: {integrity: sha512-SE7RFKH4FlXzLFli/vGMayteUVyXDbaZpb1bqymO3uAHO9ZgY+faid4vV/qoVMUgKK+P7hIq5e3MB7swmFAZBg==} + '@cspell/dynamic-import@9.0.1': + resolution: {integrity: sha512-BoWzHwkufo90ubMZUN8Jy4HQYYWFW7psVCdG/4RUgfvVnazkPfLxWBbsPQsLrlIP0utaqei7D9FU0K7r7mpl4A==} engines: {node: '>=20'} - '@cspell/filetypes@9.0.0': - resolution: {integrity: sha512-PL6ty0Xdn1UmRXwIwkze3IizgVbJSCvP0yMQF5xRQixTfidBfxrvnqjAWOGNuQifgIk1PVyFvik7ubLG0skw3w==} + '@cspell/filetypes@9.0.1': + resolution: {integrity: sha512-swZu3ra2AueyjEz/bPsvwFuHGYhjWZBx1K9FSvZA/yDIX5RVr6orQSuf9zvXNFui6Nyk0tudLnn3y9jT0LHk8A==} engines: {node: '>=20'} - '@cspell/strong-weak-map@9.0.0': - resolution: {integrity: sha512-LQw0f8nm1C7my6JqjtvTkFQ9Mt561vay0za5Vh5J9yCZxGbOvZ+/Doe925WM5NaqaxC3/wGUdEK1HxMxi9fyBA==} + '@cspell/strong-weak-map@9.0.1': + resolution: {integrity: sha512-u87PWr1xACqs/F3HibZ4Eb0Za/ghWIa6WLvEKV9OaiLfEUQuczbrXPVgHmGr83H0XXWUKy8FvVbWGFmXwiw+gQ==} engines: {node: '>=20'} - '@cspell/url@9.0.0': - resolution: {integrity: sha512-l30nTnD35w6wzABJry38tYuwMNaR9VweZb2go78F3vh8V15kGOpi1gWd7s6K2M8An7kqDS4L3Bgp019s7CJQQQ==} + '@cspell/url@9.0.1': + resolution: {integrity: sha512-8xaLrsQ742dmwXwS6tjreps3NpSQe6WEZFPQQT2DprVJXGZnfQR8ob0c+kPhD0hu9A6PwShJsRsfh3DQGKCqAw==} engines: {node: '>=20'} '@csstools/color-helpers@5.0.1': @@ -2696,13 +2687,13 @@ packages: engines: {node: '>=16.10.0'} hasBin: true - '@rsbuild/core@1.3.15': - resolution: {integrity: sha512-hI4gMzigWXaCkfmCYkxegindckQ6lcVsMcNR5qrPaWjtUC9KL6s/c1DK93J7Ui/LgkeLkBu0fMKfO8M/SDxqQQ==} + '@rsbuild/core@1.3.16': + resolution: {integrity: sha512-LGr+IcaIWMxpt2bE5A+iPV8Ui44oDPxfBMuC9dQB3NuA5GQgJsgGRmWCNbWBN1hmL7eMcN/DFP19iNafTDf3dQ==} engines: {node: '>=16.10.0'} hasBin: true - '@rsbuild/core@1.3.16': - resolution: {integrity: sha512-LGr+IcaIWMxpt2bE5A+iPV8Ui44oDPxfBMuC9dQB3NuA5GQgJsgGRmWCNbWBN1hmL7eMcN/DFP19iNafTDf3dQ==} + '@rsbuild/core@1.3.17': + resolution: {integrity: sha512-vDRUjPws7vUcdn2uXOSOknGRF9Jt0wQRH6AU0G7O0GsX8liUmE/I7+EpYvhuQIRp2ekOz1cmmSTrRntEjp7WoQ==} engines: {node: '>=16.10.0'} hasBin: true @@ -4234,42 +4225,42 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - cspell-config-lib@9.0.0: - resolution: {integrity: sha512-JVjKeQz/kdt/bxdFRzyvNjJKJ3eaIUtP5gWq+HtNMqCpBFlwCiR+M8jSsIXVOTTT5mqJ5IsBU/jZ+FvrixNYnQ==} + cspell-config-lib@9.0.1: + resolution: {integrity: sha512-hbeyU6cY4NPKh69L4QpBZgGz00f7rLk10xPlCo6MxEmCqSOTuXXvDEUR51d2ED69G+GyFAeZi5VU9IdJ4jhvzQ==} engines: {node: '>=20'} - cspell-dictionary@9.0.0: - resolution: {integrity: sha512-+fWdlzTqqjRsAfImcC2UIvSeDTn0HItw1WuYqARuRRA+UlsdDA2uARDyiH4gBnc+0/GOIhQaItYBS5XXljWEpw==} + cspell-dictionary@9.0.1: + resolution: {integrity: sha512-I9gjRpfV4djxN0i2p9OzWIrkjtUaGUyVE9atvRbkHUMeqDUhC2Qt0Mb9tnF8I7qnHeZt+U44vUa9Dg7yrJ+k4Q==} engines: {node: '>=20'} - cspell-gitignore@9.0.0: - resolution: {integrity: sha512-qHt2yXIIOYJBvhx7vO6shcIH8LN+9QoY/+iqNZm4OagWtmpPRqMCsZQj6PUuzcBMGhOQ0U10f/m5OzIIBGwKvQ==} + cspell-gitignore@9.0.1: + resolution: {integrity: sha512-xjgOmeGbHEaeF0erRQ2QXwqxWqGDiI4mu+NjCL7ZHPoAM5y8PEO6IbxVNabIB1xC4QAborbtEQ/8ydDWLJcPoQ==} engines: {node: '>=20'} hasBin: true - cspell-glob@9.0.0: - resolution: {integrity: sha512-9xBcpFy7oHxELFLqvMs5WPT/ThU/NyrKYfuNcLUkBtxz/qGbqykWIcmdLl130fLwpcIGdq31rVSni6NsMGSriw==} + cspell-glob@9.0.1: + resolution: {integrity: sha512-dQU/ln6J9Qe31zk1cLJnq/WNAjRrTUig1GG8WA2oK1jHZKY9VbyJLb5DUFnDUx35cI0jdOEnGSCWi8qNjHSc1Q==} engines: {node: '>=20'} - cspell-grammar@9.0.0: - resolution: {integrity: sha512-nTvYmxvlwnAeVZtd8rw6/3c3QsUZqDGlFtGIQMk6sKdH4n8eDPFH2K3Hag1aPOzPQJQF8XTxzgGmRnCWkPhdYg==} + cspell-grammar@9.0.1: + resolution: {integrity: sha512-FZ1z1p3pslfotZT/W/VRZjB4S+z0ETrTbNmQ5pGmhdY0nm7Slmg+8nIJluLEjBneBGTJIOcLjYykwS2vI6jzxw==} engines: {node: '>=20'} hasBin: true - cspell-io@9.0.0: - resolution: {integrity: sha512-LtyqO0bDPCKCb/3zy/IvF4nL+FuU9GeLQ9G5bnSMFOYU/kD7w5UqzE1erzC/UublMRDRyKMlSDl8QutXCeq7zw==} + cspell-io@9.0.1: + resolution: {integrity: sha512-L5fZY0glVeQb6nmt1WL1wKzZzoHJUkBQ9BGCrwqSXIrjZrYmBNSKixCjo6o9n2keRUwpNjsvZj1TQDKDV+FsXA==} engines: {node: '>=20'} - cspell-lib@9.0.0: - resolution: {integrity: sha512-5ocoFmsrW1ju954kPzm1/mhAgnIQFjFjSS8YaQ6ylxCsqV9lCadf9tT2nnC2HrZB9ILVWElsrhxkQWt2DpZQsQ==} + cspell-lib@9.0.1: + resolution: {integrity: sha512-F4vJG6GmAGVAuhgcepO12UtG7yev7Rcfa31MLIyYNTrd5NeORzM+GTHnL970FlEflwYPYjcSTGwkyowQ+ZbmDg==} engines: {node: '>=20'} - cspell-trie-lib@9.0.0: - resolution: {integrity: sha512-2s/an4sbIR8NAfkjuH6/ngap3BmfTVjxPCY2PwrzIm1WNUbEuYkY3vb1Rc4rOJ7nCTBpdu0o7/sI9ZGpMUcUzQ==} + cspell-trie-lib@9.0.1: + resolution: {integrity: sha512-gIupiHwLdsQun79biJgiqmXffKUGzFjGLFEeVptI2Zy5Oa3XhRJsHap4PyeleErONkpzxMG1tgpOWzhOqwl65Q==} engines: {node: '>=20'} - cspell@9.0.0: - resolution: {integrity: sha512-z/HtX5DvLn7iixniOwzDqxpg0wL08obTdbZ2xj4aSZCcaJVIypFoli0FhiH0wHX2whiUTk0NTSp9X9eN7aoOKg==} + cspell@9.0.1: + resolution: {integrity: sha512-AJqsX+3eSTz9GmIuyEZUzCCTbvCPw6+Nv7UYa4PCn7vNV3XEb5LHTp5i9y2i65fNaeNEcQXLrLYoY/JcBFmUSQ==} engines: {node: '>=20'} hasBin: true @@ -5301,8 +5292,8 @@ packages: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} - globals@16.0.0: - resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==} + globals@16.1.0: + resolution: {integrity: sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==} engines: {node: '>=18'} globalthis@1.0.4: @@ -8209,8 +8200,8 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} - type-fest@4.40.1: - resolution: {integrity: sha512-9YvLNnORDpI+vghLU/Nf+zSv0kL47KbVJ1o3sKgoTefl6i+zebxbiDQWoe/oWWqPhIgQdRZRT1KA9sCPL810SA==} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} type-is@1.6.18: @@ -9239,7 +9230,7 @@ snapshots: transitivePeerDependencies: - debug - '@cspell/cspell-bundled-dicts@9.0.0': + '@cspell/cspell-bundled-dicts@9.0.1': dependencies: '@cspell/dict-ada': 4.1.0 '@cspell/dict-al': 1.1.0 @@ -9256,9 +9247,9 @@ snapshots: '@cspell/dict-docker': 1.1.14 '@cspell/dict-dotnet': 5.0.9 '@cspell/dict-elixir': 4.0.7 - '@cspell/dict-en-common-misspellings': 2.0.10 - '@cspell/dict-en-gb-mit': 3.0.3 - '@cspell/dict-en_us': 4.4.6 + '@cspell/dict-en-common-misspellings': 2.0.11 + '@cspell/dict-en-gb-mit': 3.0.6 + '@cspell/dict-en_us': 4.4.8 '@cspell/dict-filetypes': 3.0.12 '@cspell/dict-flutter': 1.1.0 '@cspell/dict-fonts': 4.0.4 @@ -9266,7 +9257,7 @@ snapshots: '@cspell/dict-fullstack': 3.2.6 '@cspell/dict-gaming-terms': 1.1.1 '@cspell/dict-git': 3.0.4 - '@cspell/dict-golang': 6.0.20 + '@cspell/dict-golang': 6.0.21 '@cspell/dict-google': 1.0.8 '@cspell/dict-haskell': 4.0.5 '@cspell/dict-html': 4.0.11 @@ -9292,7 +9283,7 @@ snapshots: '@cspell/dict-rust': 4.0.11 '@cspell/dict-scala': 5.0.7 '@cspell/dict-shell': 1.1.0 - '@cspell/dict-software-terms': 5.0.7 + '@cspell/dict-software-terms': 5.0.8 '@cspell/dict-sql': 2.2.0 '@cspell/dict-svelte': 1.0.6 '@cspell/dict-swift': 2.0.5 @@ -9300,19 +9291,19 @@ snapshots: '@cspell/dict-typescript': 3.2.1 '@cspell/dict-vue': 3.0.4 - '@cspell/cspell-json-reporter@9.0.0': + '@cspell/cspell-json-reporter@9.0.1': dependencies: - '@cspell/cspell-types': 9.0.0 + '@cspell/cspell-types': 9.0.1 - '@cspell/cspell-pipe@9.0.0': {} + '@cspell/cspell-pipe@9.0.1': {} - '@cspell/cspell-resolver@9.0.0': + '@cspell/cspell-resolver@9.0.1': dependencies: global-directory: 4.0.1 - '@cspell/cspell-service-bus@9.0.0': {} + '@cspell/cspell-service-bus@9.0.1': {} - '@cspell/cspell-types@9.0.0': {} + '@cspell/cspell-types@9.0.1': {} '@cspell/dict-ada@4.1.0': {} @@ -9346,11 +9337,11 @@ snapshots: '@cspell/dict-elixir@4.0.7': {} - '@cspell/dict-en-common-misspellings@2.0.10': {} + '@cspell/dict-en-common-misspellings@2.0.11': {} - '@cspell/dict-en-gb-mit@3.0.3': {} + '@cspell/dict-en-gb-mit@3.0.6': {} - '@cspell/dict-en_us@4.4.6': {} + '@cspell/dict-en_us@4.4.8': {} '@cspell/dict-filetypes@3.0.12': {} @@ -9366,7 +9357,7 @@ snapshots: '@cspell/dict-git@3.0.4': {} - '@cspell/dict-golang@6.0.20': {} + '@cspell/dict-golang@6.0.21': {} '@cspell/dict-google@1.0.8': {} @@ -9425,7 +9416,7 @@ snapshots: '@cspell/dict-shell@1.1.0': {} - '@cspell/dict-software-terms@5.0.7': {} + '@cspell/dict-software-terms@5.0.8': {} '@cspell/dict-sql@2.2.0': {} @@ -9439,16 +9430,16 @@ snapshots: '@cspell/dict-vue@3.0.4': {} - '@cspell/dynamic-import@9.0.0': + '@cspell/dynamic-import@9.0.1': dependencies: - '@cspell/url': 9.0.0 + '@cspell/url': 9.0.1 import-meta-resolve: 4.1.0 - '@cspell/filetypes@9.0.0': {} + '@cspell/filetypes@9.0.1': {} - '@cspell/strong-weak-map@9.0.0': {} + '@cspell/strong-weak-map@9.0.1': {} - '@cspell/url@9.0.0': {} + '@cspell/url@9.0.1': {} '@csstools/color-helpers@5.0.1': {} @@ -10235,7 +10226,7 @@ snapshots: core-js: 3.41.0 jiti: 2.4.2 - '@rsbuild/core@1.3.15': + '@rsbuild/core@1.3.16': dependencies: '@rspack/core': 1.3.9(@swc/helpers@0.5.17) '@rspack/lite-tapable': 1.0.1 @@ -10243,7 +10234,7 @@ snapshots: core-js: 3.42.0 jiti: 2.4.2 - '@rsbuild/core@1.3.16': + '@rsbuild/core@1.3.17': dependencies: '@rspack/core': 1.3.9(@swc/helpers@0.5.17) '@rspack/lite-tapable': 1.0.1 @@ -10251,7 +10242,7 @@ snapshots: core-js: 3.42.0 jiti: 2.4.2 - '@rsbuild/plugin-check-syntax@1.3.0(@rsbuild/core@1.3.15)': + '@rsbuild/plugin-check-syntax@1.3.0(@rsbuild/core@1.3.17)': dependencies: acorn: 8.14.1 browserslist-to-es-version: 1.0.0 @@ -10259,14 +10250,14 @@ snapshots: picocolors: 1.1.1 source-map: 0.7.4 optionalDependencies: - '@rsbuild/core': 1.3.15 + '@rsbuild/core': 1.3.17 - '@rsbuild/plugin-css-minimizer@1.0.2(@rsbuild/core@1.3.15)(webpack@5.99.8)': + '@rsbuild/plugin-css-minimizer@1.0.2(@rsbuild/core@1.3.17)(webpack@5.99.8)': dependencies: css-minimizer-webpack-plugin: 5.0.1(webpack@5.99.8) reduce-configs: 1.1.0 optionalDependencies: - '@rsbuild/core': 1.3.15 + '@rsbuild/core': 1.3.17 transitivePeerDependencies: - '@parcel/css' - '@swc/css' @@ -10276,9 +10267,9 @@ snapshots: - lightningcss - webpack - '@rsbuild/plugin-less@1.2.4(@rsbuild/core@1.3.16)': + '@rsbuild/plugin-less@1.2.4(@rsbuild/core@1.3.17)': dependencies: - '@rsbuild/core': 1.3.16 + '@rsbuild/core': 1.3.17 deepmerge: 4.3.1 reduce-configs: 1.1.0 @@ -10290,18 +10281,18 @@ snapshots: transitivePeerDependencies: - webpack-hot-middleware - '@rsbuild/plugin-sass@1.3.1(@rsbuild/core@1.3.15)': + '@rsbuild/plugin-sass@1.3.1(@rsbuild/core@1.3.16)': dependencies: - '@rsbuild/core': 1.3.15 + '@rsbuild/core': 1.3.16 deepmerge: 4.3.1 loader-utils: 2.0.4 postcss: 8.5.3 reduce-configs: 1.1.0 sass-embedded: 1.86.0 - '@rsbuild/plugin-sass@1.3.1(@rsbuild/core@1.3.16)': + '@rsbuild/plugin-sass@1.3.1(@rsbuild/core@1.3.17)': dependencies: - '@rsbuild/core': 1.3.16 + '@rsbuild/core': 1.3.17 deepmerge: 4.3.1 loader-utils: 2.0.4 postcss: 8.5.3 @@ -10320,18 +10311,18 @@ snapshots: - '@rspack/core' - typescript - '@rsbuild/plugin-typed-css-modules@1.0.2(@rsbuild/core@1.3.15)': - optionalDependencies: - '@rsbuild/core': 1.3.15 - '@rsbuild/plugin-typed-css-modules@1.0.2(@rsbuild/core@1.3.16)': optionalDependencies: '@rsbuild/core': 1.3.16 - '@rsbuild/plugin-webpack-swc@1.1.0(@rsbuild/core@1.3.15)': + '@rsbuild/plugin-typed-css-modules@1.0.2(@rsbuild/core@1.3.17)': + optionalDependencies: + '@rsbuild/core': 1.3.17 + + '@rsbuild/plugin-webpack-swc@1.1.0(@rsbuild/core@1.3.17)': dependencies: '@modern-js/swc-plugins': 0.6.11(@swc/helpers@0.5.17) - '@rsbuild/core': 1.3.15 + '@rsbuild/core': 1.3.17 '@swc/helpers': 0.5.17 core-js: 3.41.0 deepmerge: 4.3.1 @@ -10339,9 +10330,9 @@ snapshots: picocolors: 1.1.1 semver: 7.7.1 - '@rsbuild/webpack@1.3.0(@rsbuild/core@1.3.15)(@rspack/core@1.3.9(@swc/helpers@0.5.17))': + '@rsbuild/webpack@1.3.0(@rsbuild/core@1.3.17)(@rspack/core@1.3.9(@swc/helpers@0.5.17))': dependencies: - '@rsbuild/core': 1.3.15 + '@rsbuild/core': 1.3.17 copy-webpack-plugin: 11.0.0(webpack@5.99.8) html-webpack-plugin: 5.6.3(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) mini-css-extract-plugin: 2.9.2(webpack@5.99.8) @@ -10358,9 +10349,9 @@ snapshots: '@rsdoctor/client@1.0.2': {} - '@rsdoctor/core@1.0.2(@rsbuild/core@1.3.15)(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8)': + '@rsdoctor/core@1.0.2(@rsbuild/core@1.3.17)(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8)': dependencies: - '@rsbuild/plugin-check-syntax': 1.3.0(@rsbuild/core@1.3.15) + '@rsbuild/plugin-check-syntax': 1.3.0(@rsbuild/core@1.3.17) '@rsdoctor/graph': 1.0.2(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) '@rsdoctor/sdk': 1.0.2(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) '@rsdoctor/types': 1.0.2(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) @@ -10398,9 +10389,9 @@ snapshots: - utf-8-validate - webpack - '@rsdoctor/rspack-plugin@1.0.2(@rsbuild/core@1.3.15)(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8)': + '@rsdoctor/rspack-plugin@1.0.2(@rsbuild/core@1.3.17)(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8)': dependencies: - '@rsdoctor/core': 1.0.2(@rsbuild/core@1.3.15)(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) + '@rsdoctor/core': 1.0.2(@rsbuild/core@1.3.17)(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) '@rsdoctor/graph': 1.0.2(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) '@rsdoctor/sdk': 1.0.2(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) '@rsdoctor/types': 1.0.2(@rspack/core@1.3.9(@swc/helpers@0.5.17))(webpack@5.99.8) @@ -12147,58 +12138,58 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - cspell-config-lib@9.0.0: + cspell-config-lib@9.0.1: dependencies: - '@cspell/cspell-types': 9.0.0 + '@cspell/cspell-types': 9.0.1 comment-json: 4.2.5 yaml: 2.7.1 - cspell-dictionary@9.0.0: + cspell-dictionary@9.0.1: dependencies: - '@cspell/cspell-pipe': 9.0.0 - '@cspell/cspell-types': 9.0.0 - cspell-trie-lib: 9.0.0 + '@cspell/cspell-pipe': 9.0.1 + '@cspell/cspell-types': 9.0.1 + cspell-trie-lib: 9.0.1 fast-equals: 5.2.2 - cspell-gitignore@9.0.0: + cspell-gitignore@9.0.1: dependencies: - '@cspell/url': 9.0.0 - cspell-glob: 9.0.0 - cspell-io: 9.0.0 + '@cspell/url': 9.0.1 + cspell-glob: 9.0.1 + cspell-io: 9.0.1 - cspell-glob@9.0.0: + cspell-glob@9.0.1: dependencies: - '@cspell/url': 9.0.0 + '@cspell/url': 9.0.1 picomatch: 4.0.2 - cspell-grammar@9.0.0: + cspell-grammar@9.0.1: dependencies: - '@cspell/cspell-pipe': 9.0.0 - '@cspell/cspell-types': 9.0.0 + '@cspell/cspell-pipe': 9.0.1 + '@cspell/cspell-types': 9.0.1 - cspell-io@9.0.0: + cspell-io@9.0.1: dependencies: - '@cspell/cspell-service-bus': 9.0.0 - '@cspell/url': 9.0.0 + '@cspell/cspell-service-bus': 9.0.1 + '@cspell/url': 9.0.1 - cspell-lib@9.0.0: + cspell-lib@9.0.1: dependencies: - '@cspell/cspell-bundled-dicts': 9.0.0 - '@cspell/cspell-pipe': 9.0.0 - '@cspell/cspell-resolver': 9.0.0 - '@cspell/cspell-types': 9.0.0 - '@cspell/dynamic-import': 9.0.0 - '@cspell/filetypes': 9.0.0 - '@cspell/strong-weak-map': 9.0.0 - '@cspell/url': 9.0.0 + '@cspell/cspell-bundled-dicts': 9.0.1 + '@cspell/cspell-pipe': 9.0.1 + '@cspell/cspell-resolver': 9.0.1 + '@cspell/cspell-types': 9.0.1 + '@cspell/dynamic-import': 9.0.1 + '@cspell/filetypes': 9.0.1 + '@cspell/strong-weak-map': 9.0.1 + '@cspell/url': 9.0.1 clear-module: 4.1.2 comment-json: 4.2.5 - cspell-config-lib: 9.0.0 - cspell-dictionary: 9.0.0 - cspell-glob: 9.0.0 - cspell-grammar: 9.0.0 - cspell-io: 9.0.0 - cspell-trie-lib: 9.0.0 + cspell-config-lib: 9.0.1 + cspell-dictionary: 9.0.1 + cspell-glob: 9.0.1 + cspell-grammar: 9.0.1 + cspell-io: 9.0.1 + cspell-trie-lib: 9.0.1 env-paths: 3.0.0 fast-equals: 5.2.2 gensequence: 7.0.0 @@ -12208,27 +12199,27 @@ snapshots: vscode-uri: 3.1.0 xdg-basedir: 5.1.0 - cspell-trie-lib@9.0.0: + cspell-trie-lib@9.0.1: dependencies: - '@cspell/cspell-pipe': 9.0.0 - '@cspell/cspell-types': 9.0.0 + '@cspell/cspell-pipe': 9.0.1 + '@cspell/cspell-types': 9.0.1 gensequence: 7.0.0 - cspell@9.0.0: + cspell@9.0.1: dependencies: - '@cspell/cspell-json-reporter': 9.0.0 - '@cspell/cspell-pipe': 9.0.0 - '@cspell/cspell-types': 9.0.0 - '@cspell/dynamic-import': 9.0.0 - '@cspell/url': 9.0.0 + '@cspell/cspell-json-reporter': 9.0.1 + '@cspell/cspell-pipe': 9.0.1 + '@cspell/cspell-types': 9.0.1 + '@cspell/dynamic-import': 9.0.1 + '@cspell/url': 9.0.1 chalk: 5.4.1 chalk-template: 1.1.0 commander: 13.1.0 - cspell-dictionary: 9.0.0 - cspell-gitignore: 9.0.0 - cspell-glob: 9.0.0 - cspell-io: 9.0.0 - cspell-lib: 9.0.0 + cspell-dictionary: 9.0.1 + cspell-gitignore: 9.0.1 + cspell-glob: 9.0.1 + cspell-io: 9.0.1 + cspell-lib: 9.0.1 fast-json-stable-stringify: 2.1.0 file-entry-cache: 9.1.0 semver: 7.7.1 @@ -12921,7 +12912,7 @@ snapshots: eslint: 9.26.0(jiti@2.4.2) esquery: 1.6.0 find-up-simple: 1.0.1 - globals: 16.0.0 + globals: 16.1.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 jsesc: 3.1.0 @@ -13487,7 +13478,7 @@ snapshots: globals@15.15.0: {} - globals@16.0.0: {} + globals@16.1.0: {} globalthis@1.0.4: dependencies: @@ -15996,25 +15987,18 @@ snapshots: '@microsoft/api-extractor': 7.52.7(@types/node@22.15.3) typescript: 5.8.3 - rsbuild-plugin-publint@0.3.1(@rsbuild/core@1.3.15): - dependencies: - picocolors: 1.1.1 - publint: 0.3.9 - optionalDependencies: - '@rsbuild/core': 1.3.15 - - rsbuild-plugin-publint@0.3.1(@rsbuild/core@1.3.16): + rsbuild-plugin-publint@0.3.1(@rsbuild/core@1.3.17): dependencies: picocolors: 1.1.1 publint: 0.3.9 optionalDependencies: - '@rsbuild/core': 1.3.16 + '@rsbuild/core': 1.3.17 - rsbuild-plugin-tailwindcss@0.2.1(@rsbuild/core@1.3.16)(tailwindcss@3.4.17): + rsbuild-plugin-tailwindcss@0.2.1(@rsbuild/core@1.3.17)(tailwindcss@3.4.17): dependencies: tailwindcss: 3.4.17 optionalDependencies: - '@rsbuild/core': 1.3.16 + '@rsbuild/core': 1.3.17 rslog@1.2.3: {} @@ -16885,7 +16869,7 @@ snapshots: type-fest@0.8.1: {} - type-fest@4.40.1: {} + type-fest@4.41.0: {} type-is@1.6.18: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5cf6b94a17..23cbcc0204 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,4 @@ packages: - - .github/actions/eco-ci - examples/* - packages/react - packages/react/refresh @@ -25,7 +24,7 @@ catalog: catalogs: # Rsbuild monorepo packages rsbuild: - "@rsbuild/core": "1.3.15" + "@rsbuild/core": "1.3.17" "@rsbuild/webpack": "1.3.0" "@rsbuild/plugin-less": "1.2.4" "@rsbuild/plugin-sass": "1.3.1"