From e1f33868e9ea14cee5e3d9c547eec14a2bde256a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9stor?= Date: Thu, 17 Sep 2026 15:38:41 +0100 Subject: [PATCH 1/5] feat: scaffold TanStack Module Federation plugin --- .changeset/config.json | 11 + .github/workflows/ci.yml | 38 + .github/workflows/pkg-pr-new.yml | 24 + .github/workflows/pr.yml | 21 + .github/workflows/release-pull-request.yml | 46 + .github/workflows/release.yml | 100 + .gitignore | 8 + .npmrc | 2 + .prettierignore | 4 + .prettierrc.json | 6 + LICENSE | 21 + README.md | 53 +- docs/RELEASING.md | 46 + package.json | 26 + packages/tanstack/CHANGELOG.md | 5 + packages/tanstack/LICENSE | 21 + packages/tanstack/README.md | 41 + packages/tanstack/package.json | 71 + packages/tanstack/src/index.ts | 48 + packages/tanstack/tsconfig.json | 22 + packages/tanstack/tsdown.config.ts | 19 + pnpm-lock.yaml | 2367 ++++++++++++++++++++ pnpm-workspace.yaml | 3 + test/release-artifacts.test.mjs | 44 + test/release-contracts.test.mjs | 116 + tsconfig.json | 5 + turbo.json | 19 + 27 files changed, 3186 insertions(+), 1 deletion(-) create mode 100644 .changeset/config.json create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/pkg-pr-new.yml create mode 100644 .github/workflows/pr.yml create mode 100644 .github/workflows/release-pull-request.yml create mode 100644 .github/workflows/release.yml create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 .prettierignore create mode 100644 .prettierrc.json create mode 100644 LICENSE create mode 100644 docs/RELEASING.md create mode 100644 package.json create mode 100644 packages/tanstack/CHANGELOG.md create mode 100644 packages/tanstack/LICENSE create mode 100644 packages/tanstack/README.md create mode 100644 packages/tanstack/package.json create mode 100644 packages/tanstack/src/index.ts create mode 100644 packages/tanstack/tsconfig.json create mode 100644 packages/tanstack/tsdown.config.ts create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 test/release-artifacts.test.mjs create mode 100644 test/release-contracts.test.mjs create mode 100644 tsconfig.json create mode 100644 turbo.json diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..dbb2ecb --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [["@module-federation/tanstack"]], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..3a5cd73 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,38 @@ +name: CI + +on: + pull_request: + branches: [main] + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + verify: + name: Verify (Node ${{ matrix.node }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node: ["22.18.0", "24", "26"] + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: pnpm/action-setup@b0f76dfb45f55f8421693e4803ac7bb65143bd34 # v6 + with: + version: 10.15.0 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 + with: + node-version: ${{ matrix.node }} + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm format:check + - run: pnpm typecheck + - run: pnpm build + - run: pnpm test + - run: pnpm pack:tanstack diff --git a/.github/workflows/pkg-pr-new.yml b/.github/workflows/pkg-pr-new.yml new file mode 100644 index 0000000..1dc317d --- /dev/null +++ b/.github/workflows/pkg-pr-new.yml @@ -0,0 +1,24 @@ +name: pkg-pr-new + +on: + push: + branches: [main] + pull_request: + +permissions: {} + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: pnpm/action-setup@b0f76dfb45f55f8421693e4803ac7bb65143bd34 # v6 + with: + version: 10.15.0 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm build:package + - run: pnpm dlx pkg-pr-new@0.0.54 publish --compact ./packages/tanstack diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..c0e9964 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,21 @@ +name: Validate PR title + +on: + pull_request: + branches: [main] + +permissions: + pull-requests: read + +jobs: + semantic-pr: + runs-on: ubuntu-latest + steps: + - name: Accept generated release title + if: ${{ startsWith(github.event.pull_request.title, 'Release ') }} + run: echo "Generated release PR title accepted." + + - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 + if: ${{ !startsWith(github.event.pull_request.title, 'Release ') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-pull-request.yml b/.github/workflows/release-pull-request.yml new file mode 100644 index 0000000..996f614 --- /dev/null +++ b/.github/workflows/release-pull-request.yml @@ -0,0 +1,46 @@ +name: Release Pull Request + +on: + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +concurrency: + group: release-pull-request + cancel-in-progress: false + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Validate release request + env: + REPO_SCOPED_TOKEN: ${{ secrets.REPO_SCOPED_TOKEN }} + run: | + test "$GITHUB_REF" = "refs/heads/main" || { echo "Release PRs are main-only."; exit 1; } + test -n "$REPO_SCOPED_TOKEN" || { echo "REPO_SCOPED_TOKEN is required."; exit 1; } + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + fetch-depth: 10 + token: ${{ secrets.REPO_SCOPED_TOKEN }} + - uses: pnpm/action-setup@b0f76dfb45f55f8421693e4803ac7bb65143bd34 # v6 + with: + version: 10.15.0 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile --ignore-scripts + - uses: module-federation/actions@842df3a7740093a5ff44de2b9a890106046b8e32 # v2 + with: + version: latest + versionNumber: auto + type: pull request + tools: changeset + coreNpmName: "@module-federation/tanstack" + env: + GITHUB_TOKEN: ${{ secrets.REPO_SCOPED_TOKEN }} + REPOSITORY: ${{ github.repository }} + REF: ${{ github.ref }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..2043550 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,100 @@ +name: Release + +on: + release: + types: [published] + workflow_dispatch: + inputs: + version: + type: choice + required: true + default: next + options: [latest, next] + branch: + required: true + default: main + +permissions: + contents: read + id-token: write + +concurrency: + group: publish-module-federation-tanstack + cancel-in-progress: false + +jobs: + publish: + runs-on: ubuntu-latest + environment: Publish + steps: + - name: Validate manual target + if: github.event_name == 'workflow_dispatch' + env: + RELEASE_BRANCH: ${{ inputs.branch }} + run: test "$RELEASE_BRANCH" = "main" || { echo "Releases are main-only."; exit 1; } + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + fetch-depth: 0 + ref: ${{ github.event.release.tag_name || inputs.branch }} + - name: Verify source branch + run: | + git fetch --no-tags origin main:refs/remotes/origin/main + git merge-base --is-ancestor HEAD origin/main || { echo "Source is not on main."; exit 1; } + - uses: pnpm/action-setup@b0f76dfb45f55f8421693e4803ac7bb65143bd34 # v6 + with: + version: 10.15.0 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 + with: + node-version: 24 + cache: pnpm + registry-url: https://registry.npmjs.org/ + - run: pnpm install --frozen-lockfile + - name: Verify release tag + if: github.event_name == 'release' + env: + RELEASE_TAG: ${{ github.event.release.tag_name }} + run: | + test "${RELEASE_TAG#v}" = "$RELEASE_TAG" || { echo "Tags must not start with v."; exit 1; } + test "$(node -p "require('./packages/tanstack/package.json').version")" = "$RELEASE_TAG" || { echo "Tag/version mismatch."; exit 1; } + - name: Generate preview version + if: github.event_name == 'workflow_dispatch' && inputs.version == 'next' + run: | + pnpm changeset version --snapshot next + SNAPSHOT_VERSION="$(node -p "require('./packages/tanstack/package.json').version")" + BASE_VERSION="${SNAPSHOT_VERSION%%-*}" + npm pkg set version="${BASE_VERSION}-next.${GITHUB_RUN_ID}" --prefix packages/tanstack + - run: pnpm format:check + - run: pnpm typecheck + - run: pnpm build + - run: pnpm test + - run: pnpm pack:tanstack + - name: Compute dist-tag + id: dist + env: + INPUT_VERSION: ${{ inputs.version }} + PRERELEASE: ${{ github.event.release.prerelease || false }} + run: | + TAG=latest + if [ "$INPUT_VERSION" = "next" ] || [ "$PRERELEASE" = "true" ]; then TAG=next; fi + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + - name: Refuse conflicting republish + id: publish-check + env: + PACKAGE: "@module-federation/tanstack" + DIST_TAG: ${{ steps.dist.outputs.tag }} + run: | + VERSION="$(node -p "require('./packages/tanstack/package.json').version")" + EXISTING="$(npm view "$PACKAGE@$VERSION" version --json 2>/dev/null || true)" + EXISTING="${EXISTING#\"}"; EXISTING="${EXISTING%\"}" + if [ "$EXISTING" = "$VERSION" ]; then + CURRENT="$(npm view "$PACKAGE" "dist-tags.$DIST_TAG" --json 2>/dev/null || true)" + CURRENT="${CURRENT#\"}"; CURRENT="${CURRENT%\"}" + test "$CURRENT" = "$VERSION" || { echo "Existing version has conflicting dist-tag."; exit 1; } + echo "publish=false" >> "$GITHUB_OUTPUT" + else + echo "publish=true" >> "$GITHUB_OUTPUT" + fi + - name: Publish to npm + if: steps.publish-check.outputs.publish == 'true' + working-directory: packages/tanstack + run: npm publish --provenance --tag "${{ steps.dist.outputs.tag }}" --access public diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a62c8b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +node_modules/ +dist/ +.turbo/ +*.log +pnpm-debug.log* +coverage/ +*.tgz +.DS_Store diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..90edf5a --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +auto-install-peers=false +prefer-frozen-lockfile=true diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..b3bc6ae --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +dist +node_modules +pnpm-lock.yaml +.turbo diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..bccee91 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "printWidth": 100 +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b0cebd8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Module Federation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 5ad6652..87b7e89 100644 --- a/README.md +++ b/README.md @@ -1 +1,52 @@ -# tanstack \ No newline at end of file +# @module-federation/tanstack + +Module Federation support for TanStack Start, built on the Vite integration. + +## Install + +```bash +pnpm add @module-federation/tanstack @tanstack/react-start +``` + +## Configure + +The federation wrapper must come before `tanstackStart()` so Module Federation +can normalize TanStack's client and SSR entrypoints: + +```ts +import { tanstackStartModuleFederation } from "@module-federation/tanstack"; +import { tanstackStart } from "@tanstack/react-start/plugin/vite"; +import react from "@vitejs/plugin-react"; +import { nitro } from "nitro/vite"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [ + tanstackStartModuleFederation({ + name: "host", + remotes: { + remote: { + type: "module", + name: "remote", + entry: "https://example.test/remoteEntry.js", + }, + }, + }), + tanstackStart(), + react(), + nitro(), + ], +}); +``` + +Defaults are `remoteEntry.js`, `manifest: true`, and +`hostInitInjectLocation: "entry"`. React and `react-dom` are shared singleton +defaults; any explicit entries in `shared` take precedence. + +Do not set a global Module Federation `target`. TanStack Start builds client +and SSR environments from one Vite configuration, so the wrapper leaves target +selection to `@module-federation/vite` for each environment. + +The package supports Node 22.18+, 24.11+, and 26+, plus Vite 7/8 and TanStack +Start 1.x. Use Vite 8 when developing SSR hosts that load remotes; Vite 7 +remains supported for production builds. diff --git a/docs/RELEASING.md b/docs/RELEASING.md new file mode 100644 index 0000000..e7538a7 --- /dev/null +++ b/docs/RELEASING.md @@ -0,0 +1,46 @@ +--- +title: Releasing +summary: Release and trusted npm publishing for @module-federation/tanstack. +read_when: + - Preparing a release + - Updating release automation +updated_at: 2026-09-16 +--- + +# Releasing + +Add a Changeset to every user-visible package change: + +```bash +pnpm changeset +``` + +Run the complete local gate before merging: + +```bash +pnpm install --frozen-lockfile +pnpm format:check +pnpm typecheck +pnpm build +pnpm test +pnpm pack:tanstack +``` + +The `Release Pull Request` workflow versions the package and updates its +changelog. After merging that PR, publish from `main` with a GitHub Release +whose tag exactly matches `packages/tanstack/package.json` (without a `v`), or +dispatch `Release` with `version=latest`. Preview dispatches use `version=next` +and publish to npm's `next` dist-tag. + +GitHub prerelease tags must match the prerelease version already committed in +`packages/tanstack/package.json`. The workflow publishes that exact version to +the `next` dist-tag. + +The publish workflow reruns the gate, checks that the source is reachable from +`main`, uses npm provenance, and refuses to republish an existing version under +a different dist-tag. Configure npm trusted publishing for repository +`module-federation/tanstack`, workflow `release.yml`, environment `Publish`. + +There are no committed app fixtures yet. The next integration matrix should +cover TanStack Start client and SSR builds on Vite 7 and 8, host/remote module +entries, manifest output, React singleton identity, and Nitro externalization. diff --git a/package.json b/package.json new file mode 100644 index 0000000..7ef2a35 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "mf-tanstack", + "private": true, + "packageManager": "pnpm@10.15.0", + "engines": { + "node": "^22.18.0 || ^24.11.0 || >=26.0.0" + }, + "scripts": { + "build": "turbo run build", + "build:package": "pnpm --filter @module-federation/tanstack build", + "dev": "turbo run dev", + "test": "pnpm build:package && node --test --test-concurrency=1 test/*.test.mjs", + "typecheck": "turbo run typecheck", + "format": "prettier --write .", + "format:check": "prettier --check .", + "pack:tanstack": "pnpm --filter @module-federation/tanstack pack:dry", + "changeset": "changeset", + "changeset:status": "changeset status" + }, + "devDependencies": { + "@changesets/cli": "3.0.3", + "prettier": "3.9.7", + "turbo": "2.10.13", + "typescript": "6.0.3" + } +} diff --git a/packages/tanstack/CHANGELOG.md b/packages/tanstack/CHANGELOG.md new file mode 100644 index 0000000..ff942c3 --- /dev/null +++ b/packages/tanstack/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 0.1.0 + +- Initial TanStack Start integration for Module Federation. diff --git a/packages/tanstack/LICENSE b/packages/tanstack/LICENSE new file mode 100644 index 0000000..b0cebd8 --- /dev/null +++ b/packages/tanstack/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Module Federation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/tanstack/README.md b/packages/tanstack/README.md new file mode 100644 index 0000000..dad41f7 --- /dev/null +++ b/packages/tanstack/README.md @@ -0,0 +1,41 @@ +# @module-federation/tanstack + +TanStack Start integration for Module Federation. It delegates to +`@module-federation/vite` and supplies defaults needed by TanStack's client and +SSR environments. + +```ts +import { tanstackStartModuleFederation } from "@module-federation/tanstack"; +import { tanstackStart } from "@tanstack/react-start/plugin/vite"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [ + tanstackStartModuleFederation({ + name: "host", + remotes: { + remote: { + type: "module", + name: "remote", + entry: "https://example.test/remoteEntry.js", + }, + }, + }), + tanstackStart(), + ], +}); +``` + +Place the federation wrapper before `tanstackStart()`, followed by React and +Nitro plugins. Defaults: `filename: "remoteEntry.js"`, `manifest: true`, +`hostInitInjectLocation: "entry"`, and singleton `react`/`react-dom` shared +entries. User-provided `shared` entries override those defaults. + +The wrapper intentionally omits the global Module Federation `target` option. +TanStack Start's client and SSR environments need `@module-federation/vite` to +select `web` and `node` independently. + +Production builds support Vite 7 and 8. Vite 8 is required for SSR remote +loading during development. + +Supported Node releases are 22.18+, 24.11+, and 26+. diff --git a/packages/tanstack/package.json b/packages/tanstack/package.json new file mode 100644 index 0000000..4a637b3 --- /dev/null +++ b/packages/tanstack/package.json @@ -0,0 +1,71 @@ +{ + "name": "@module-federation/tanstack", + "version": "0.1.0", + "type": "module", + "description": "TanStack Start integration for Module Federation", + "license": "MIT", + "sideEffects": false, + "main": "./dist/index.mjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.mts", + "exports": { + ".": { + "types": "./dist/index.d.mts", + "import": "./dist/index.mjs", + "default": "./dist/index.mjs" + }, + "./package.json": "./package.json" + }, + "files": [ + "dist/**/*", + "README.md", + "CHANGELOG.md", + "LICENSE" + ], + "publishConfig": { + "access": "public", + "provenance": true + }, + "repository": { + "type": "git", + "url": "git+https://github.com/module-federation/tanstack.git", + "directory": "packages/tanstack" + }, + "bugs": { + "url": "https://github.com/module-federation/tanstack/issues" + }, + "homepage": "https://github.com/module-federation/tanstack#readme", + "keywords": [ + "tanstack", + "tanstack-start", + "module-federation", + "microfrontend" + ], + "engines": { + "node": "^22.18.0 || ^24.11.0 || >=26.0.0" + }, + "scripts": { + "build": "tsdown", + "dev": "tsdown --watch --no-clean", + "pack:dry": "npm pack --dry-run", + "prepack": "pnpm run build", + "prepublishOnly": "pnpm run typecheck && pnpm run build", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "@module-federation/vite": "1.22.0" + }, + "peerDependencies": { + "@tanstack/react-start": "^1.0.0", + "vite": "^7.0.0 || ^8.0.0" + }, + "devDependencies": { + "@tanstack/react-start": "1.168.54", + "@types/node": "24.10.1", + "react": "19.3.0", + "react-dom": "19.3.0", + "tsdown": "0.23.0", + "typescript": "6.0.3", + "vite": "8.3.0" + } +} diff --git a/packages/tanstack/src/index.ts b/packages/tanstack/src/index.ts new file mode 100644 index 0000000..393d29b --- /dev/null +++ b/packages/tanstack/src/index.ts @@ -0,0 +1,48 @@ +import { federation, type ModuleFederationOptions } from "@module-federation/vite"; + +export type TanStackStartModuleFederationOptions = Omit; + +const defaultShared = { + react: { singleton: true }, + "react-dom": { singleton: true }, +} as const; + +type SharedOptions = NonNullable; +type SharedRecord = Exclude; + +function resolveShared(shared: SharedOptions | undefined): SharedRecord { + if (!Array.isArray(shared)) { + return { + ...defaultShared, + ...shared, + }; + } + + const additionalShared = Object.fromEntries( + shared + .filter((packageName) => !Object.hasOwn(defaultShared, packageName)) + .map((packageName) => [packageName, {}]), + ); + + return { + ...defaultShared, + ...additionalShared, + }; +} + +/** Creates one Module Federation plugin set for TanStack Start's client and SSR environments. */ +export function tanstackStartModuleFederation(options: TanStackStartModuleFederationOptions) { + const { + shared, + target: _environmentSpecificTarget, + ...configured + } = options as ModuleFederationOptions; + + return federation({ + ...configured, + filename: configured.filename ?? "remoteEntry.js", + manifest: configured.manifest ?? true, + hostInitInjectLocation: configured.hostInitInjectLocation ?? "entry", + shared: resolveShared(shared), + }); +} diff --git a/packages/tanstack/tsconfig.json b/packages/tanstack/tsconfig.json new file mode 100644 index 0000000..ae76cb7 --- /dev/null +++ b/packages/tanstack/tsconfig.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "allowImportingTsExtensions": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "noUncheckedIndexedAccess": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "esModuleInterop": true, + "skipLibCheck": true, + "noEmit": true, + "verbatimModuleSyntax": true + }, + "include": ["src/**/*.ts"], + "exclude": ["dist"] +} diff --git a/packages/tanstack/tsdown.config.ts b/packages/tanstack/tsdown.config.ts new file mode 100644 index 0000000..a6d6a0b --- /dev/null +++ b/packages/tanstack/tsdown.config.ts @@ -0,0 +1,19 @@ +import { builtinModules } from "node:module"; +import { defineConfig } from "tsdown"; + +const external = [ + ...builtinModules, + ...builtinModules.map((name) => `node:${name}`), + "@module-federation/vite", + "@module-federation/vite/*", +]; + +export default defineConfig({ + clean: true, + deps: { neverBundle: external }, + dts: { sourcemap: true }, + entry: { index: "./src/index.ts" }, + format: ["esm"], + outDir: "dist", + sourcemap: true, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..1e2b0d4 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2367 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: false + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@changesets/cli': + specifier: 3.0.3 + version: 3.0.3 + prettier: + specifier: 3.9.7 + version: 3.9.7 + turbo: + specifier: 2.10.13 + version: 2.10.13 + typescript: + specifier: 6.0.3 + version: 6.0.3 + + packages/tanstack: + dependencies: + '@module-federation/vite': + specifier: 1.22.0 + version: 1.22.0(typescript@6.0.3)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + devDependencies: + '@tanstack/react-start': + specifier: 1.168.54 + version: 1.168.54(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@types/node': + specifier: 24.10.1 + version: 24.10.1 + react: + specifier: 19.3.0 + version: 19.3.0 + react-dom: + specifier: 19.3.0 + version: 19.3.0(react@19.3.0) + tsdown: + specifier: 0.23.0 + version: 0.23.0(typescript@6.0.3) + typescript: + specifier: 6.0.3 + version: 6.0.3 + vite: + specifier: 8.3.0 + version: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + +packages: + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.7': + resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.7': + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.8': + resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.29.7': + resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.29.7': + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.29.7': + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.29.7': + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.7': + resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.8': + resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.8': + resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} + engines: {node: '>=6.9.0'} + + '@changesets/apply-release-plan@8.1.1': + resolution: {integrity: sha512-nk2Hbq3M9NeHMdaIRBDvawKrQJzXB9sGyBUE5yWnIKtvdcNCPj75zBekJYr0gTT2ecJH3eFeTrc8eisPImcv0Q==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/assemble-release-plan@7.0.0': + resolution: {integrity: sha512-oEW8BxdA604kGGtDSCiHr5w9Tv4UWe9I2k61IBNZzCOE1kbYaJj4v+lFQNgcEZFkUc2pV/+hASErGDvpJOZCTg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/changelog-git@1.0.0': + resolution: {integrity: sha512-3Dst2Ime2Op5nd4XmWJLPIgp11ZFqJqSkVug9izK6TDcIV4YlhPS4ECbEVR+eGI0bk0r1ItogD4j2Oli87bJrA==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/cli@3.0.3': + resolution: {integrity: sha512-L1i67bMfkK6iC/kDejuNO4pFgTRcWIObsD6Qof2woP1I4M8tj17DGlcpRaTzTv1DYSP5EMwWdEtR8X0Pj5Jg3Q==} + engines: {node: ^22.11 || ^24 || >=26, npm: '>=10.9.0', pnpm: '>=10.0.0', yarn: '>=4.5.2'} + hasBin: true + + '@changesets/config@4.0.1': + resolution: {integrity: sha512-PxpxSQLQSLDjceAgRq+4FWlU+HflDIw03mmPVipxoQx9xrXFUjmqTy3SE+n/2t+DqPdpPiLWVr5NRiLZvjyLwg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/errors@1.0.0': + resolution: {integrity: sha512-ElN/mEzn6zmETgjwf5MclCMa9ef59sAR0lfO8VSYIsiRvbC2FbLB/92EoYw10Sl0kGixxHFiJZUSv7dA+YpR8g==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/format@0.1.2': + resolution: {integrity: sha512-Caez5XtNXCFS/G5bwyav3wuXL0tMxVd2ZGbaumWbzN08tyzO21asCw7JZhNtVsAZDCvDRUzZN+Iit9SyRITSYA==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/get-dependents-graph@3.0.0': + resolution: {integrity: sha512-ji/t5wFA1zREKXRUePE6Qi+Qu2UgxCeSSGQrphezwvQZrp49B7sJ+8+wvM0tA7zPeSxYKCojDy3WWgrl+s+awg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/git@4.0.1': + resolution: {integrity: sha512-6vWpIAC4LkpmlqaIu37ViT5enyd9+uBwAiGqCGhASvkSHBgx4PrtTGXWTMFYpDmZbjgyonyVgMciPrW4MqtJsA==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/parse@1.0.0': + resolution: {integrity: sha512-P0iaMb9p9CRYZiTgAllEIF9AUMQHIy1G72tKlcIqJp61icZSsKQNiOPdxAMZG8m/DvZwt/oz5xEbTpike//dWg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/pre@3.0.0': + resolution: {integrity: sha512-Zm/6YliV/a2oeWTqHJf6KxLrQwgcK1i/BRDl2m0EKZvbnxV5fG9QRhwJJGshjsZTUTS6dkfURQ2K6aAvgNw/3Q==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/read@1.0.1': + resolution: {integrity: sha512-nzvSC6RcTiWf/dsuwZFXpLzGGsRHYCL68U3uHV7srsulU93aVWY7u2GEJiDZ+4GIIElfaW5EqtKC0UHroY+LTQ==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/should-skip-package@1.0.0': + resolution: {integrity: sha512-pwqoJmbONn1XgXmZXPEExgAaT+HdZLjALFTDgIm+PnS5KeO2nLtzA2/Q+4aMFY14kFMuXKG30MObhvDzWgzDgg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/types@7.0.0': + resolution: {integrity: sha512-c5GoiQyt3pxiXjrWSNoP8/GRf4kG+VnKzovx1OQM8dYYALlSwgedmkPmJ+ZqGxqwg9D3Bkj85Uo4KLd5BN3A0w==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/write@1.0.1': + resolution: {integrity: sha512-q/ThtP9gcnEP6xlv7LrY26C2mHqdGBti/MmOVngt/M/oIGYkssmQGxPK9WzBNt2juVcH/vml2WQ+ra8LXYOTaA==} + engines: {node: ^22.11 || ^24 || >=26} + + '@clack/core@1.5.1': + resolution: {integrity: sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ==} + engines: {node: '>= 20.12.0'} + + '@clack/prompts@1.8.1': + resolution: {integrity: sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==} + engines: {node: '>= 20.12.0'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@manypkg/find-root@3.1.0': + resolution: {integrity: sha512-BcSqCyKhBVZ5YkSzOiheMCV41kqAFptW6xGqYSTjkVTl9XQpr+pqHhwgGCOHQtjDCv7Is6EFyA14Sm5GVbVABA==} + engines: {node: '>=20.0.0'} + + '@manypkg/get-packages@3.1.0': + resolution: {integrity: sha512-0TbBVyvPrP7xGYBI/cP8UP+yl/z+HtbTttAD7FMAJgn/kXOTwh5/60TsqP9ZYY710forNfyV0N8P/IE/ujGZJg==} + engines: {node: '>=20.0.0'} + + '@manypkg/tools@2.1.2': + resolution: {integrity: sha512-6QEf6yqFbETdwGITKq57aYoPfX/3K8XFNwsAlx0C1M7o8cb79sv1M3w+tWuWvIcSbNqrLF7OD7YpZMVVz335hQ==} + engines: {node: '>=20.0.0'} + + '@module-federation/dts-plugin@2.9.0': + resolution: {integrity: sha512-uMGqEG/p9odG2BVr7WRbBe2OgrvzBd3LPzcp5WP+bm3djBdUJ4PZ3ozqKp6qpy+NFnlh6vnM815Xn6AXkKy1Vw==} + peerDependencies: + typescript: ^4.9.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + vue-tsc: '>=1.0.24' + peerDependenciesMeta: + vue-tsc: + optional: true + + '@module-federation/error-codes@2.9.0': + resolution: {integrity: sha512-IGpd+VRlji3NyGOGGTsk7YEmPRKcDoBK4YHqIuP+OQwyb2YhHCUHO2vW9RXeQxCuKwi+c6xkTweRYG+Umy+0Zw==} + + '@module-federation/managers@2.9.0': + resolution: {integrity: sha512-8KhB2PF4g+M0hGaethU1H4GVWabLn5sF5TvnM6VxgAcDL4TfLY8aC/YobAXHG/SV0jpU5lsGe6s6xy6ccV0MQw==} + + '@module-federation/runtime-core@2.9.0': + resolution: {integrity: sha512-dLykRYfpbEJBTdk2NlbNoVVTB196O3qujawTBguLABJkPCWETJNk60NR1yZO34eI+DTH+eGwHU3m7FddAWnbnw==} + + '@module-federation/runtime@2.9.0': + resolution: {integrity: sha512-3cyAav0hWP+dNvB7qrcK9CKxQn+JvkbRvLtZz3zS2g0EyxtDFDjgbHY0Afcf7oHf8IHhKeEdzb/3Kjr1Pjmr7A==} + + '@module-federation/sdk@2.9.0': + resolution: {integrity: sha512-IMjObgBGQTXd33jTTCYcxvz8iOQGLsZ2QIPOj90rDxuBtJsN4WJwYyXqligrhY/e5p/BipUPdbIgKmWL7zFhTw==} + + '@module-federation/third-party-dts-extractor@2.9.0': + resolution: {integrity: sha512-R1Xuqnqzw6wQxWV3yU9fX1FydXAeZF2TNVFAVo1N1oLBA2j5y7aUO/Fc3VSNgd9/gxMzJgTVBdA+nMiD2SFCgg==} + + '@module-federation/vite@1.22.0': + resolution: {integrity: sha512-113KQtubRIg2ezPs8R2+q+sTKY/8IEePqaGsNAdeSHvQvtP8TUW0YvBvpNFgiPz/7VG0FhI7XYGraBekBZUzMA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@oozcitak/dom@2.0.2': + resolution: {integrity: sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w==} + engines: {node: '>=20.0'} + + '@oozcitak/infra@2.0.2': + resolution: {integrity: sha512-2g+E7hoE2dgCz/APPOEK5s3rMhJvNxSMBrP+U+j1OWsIbtSpWxxlUjq1lU8RIsFJNYv7NMlnVsCuHcUzJW+8vA==} + engines: {node: '>=20.0'} + + '@oozcitak/url@3.0.0': + resolution: {integrity: sha512-ZKfET8Ak1wsLAiLWNfFkZc/BraDccuTJKR6svTYc7sVjbR+Iu0vtXdiDMY4o6jaFl5TW2TlS7jbLl4VovtAJWQ==} + engines: {node: '>=20.0'} + + '@oozcitak/util@10.0.0': + resolution: {integrity: sha512-hAX0pT/73190NLqBPPWSdBVGtbY6VOhWYK3qqHqtXQ1gK7kS2yz4+ivsN07hpJ6I3aeMtKP6J6npsEKOAzuTLA==} + engines: {node: '>=20.0'} + + '@oxc-project/types@0.150.0': + resolution: {integrity: sha512-rDS5/31E9HfPl/CIzGrn0DOlvBbXFseQ5URJ9sYMfstbKLD/c6Gm9vmRzRGDdAXyOIL4zmO37lc9RIwYqVruZw==} + + '@pnpm/deps.graph-sequencer@1100.0.1': + resolution: {integrity: sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==} + engines: {node: '>=22.13'} + + '@quansync/fs@1.1.0': + resolution: {integrity: sha512-qAPG/t3HqML1TlN7sY/pTbEjzFVAKsMjNNMGheyDosro+kT4iw2KCUoHcVdmliwWjorm4elZbgNQyU2eD97eDg==} + + '@rolldown/binding-android-arm-eabi@1.2.9': + resolution: {integrity: sha512-tNISae1QEf/vkb3xkRcjV5SEdzPE97We5IVaa2Z8jSszQPZ8U60B/YCYpw4QI7VidYsBtKavczXf+DyDs9WGxw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@rolldown/binding-android-arm64@1.2.9': + resolution: {integrity: sha512-YC8YsI30o606GTZi0VyzYlsDKFP8W61i/QzayHDkLbNEz/IShqAmTa+hsJRj13xTHA0H+6fk4b2UmGn+Q/cMlg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.9': + resolution: {integrity: sha512-IwhlH3qK5urrY8hZiEgGkHKEFN901p/p2bjxCxJlr4GyNnF7wYpUvK+Y43uaRYuC4hpfjzbR3SJC3arX1jGvmw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.9': + resolution: {integrity: sha512-XxpJfVzFh+jilRxIXUqcfYAYcunIc/XEzIizsOL1fcJee5Sf7H3mH8WlLmfHfluz5amqR88QQo9izKtmMlavAw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.9': + resolution: {integrity: sha512-kSfvhmgeWyfkbT3p/1s5vSgboogoah2zkm9fX2zjg2hHxSV7T4KhMWRUUaRk4OXNqoD3QAUeRqLcs1aZOK4U1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.9': + resolution: {integrity: sha512-1RVzG17pxqbTfYLC352JlLt6kKLG+6Hr30n8DlIJqsnV5luUDd2Qdx9Ayw1Cabfyb1K9k0jXEZ7evxkRoT+uiw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.9': + resolution: {integrity: sha512-BXqPvZ2drqVD+/Z8UpKwcs4Mp7grM+eGFku4CAEKrEtcbAsUpzREphK1sogCRZGreVPiMkiiBtw0n3TPteuqvw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-musl@1.2.9': + resolution: {integrity: sha512-11vWvo8YDwLzukt27J3aYDWU+gg2P7J+ZOmiJ0hkF5BXZDW7pVya7r40MXDy6ya0i9KamoENSVKIugvJNgFXIA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-ppc64-gnu@1.2.9': + resolution: {integrity: sha512-a1tijMkdwsIARtc0F39ApURROkf3NwqinI6TOiSSWCTR7dT96dffNvMUtDHnq64wKNTIZOIlzKrFvvFUznJiyw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + + '@rolldown/binding-linux-s390x-gnu@1.2.9': + resolution: {integrity: sha512-x6SQNdAvv4c3hWqTMaWuawzMX9myaCs/yEmlGsxJzkdClnHW7FbrjQuSiRDhuSYzEYoEMhsaJy9qHG/XNemJPQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@1.2.9': + resolution: {integrity: sha512-9s0AZ8BFK5/n7B/TBoa2yJE3gI3KURrbXcPBlsAsvjU4VeJKgE90y1YtNxyEUIcHPQkg6/yfF3qihUrcM/Kf0Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@1.2.9': + resolution: {integrity: sha512-P7VWAmV+WdJluH7ovnRGoiv2i8To7GAZ+kGzfGup635cyL7SyYl3lSUaA3Gp5THf0n/Co5EyEqb2zbqq+nMOHQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-openharmony-arm64@1.2.9': + resolution: {integrity: sha512-1qixtsE4BK8h+yS3BfmZ09UhA7O/N4IACva6YBr7EBvCJraByTuRcgOTaiA62Tm0vey3UcKXLOaoGHtYmNGEVg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.9': + resolution: {integrity: sha512-ok8IQjcEPs1AKZfuEUznVBrJw+gK4soq+bx8b1X2XoMqVClarc1q5JDmVtWXY1xfr6ZuHTAsPXHTgTrqKTZeww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.9': + resolution: {integrity: sha512-Ip2mXoU0hM0boq3Rf+ekuT653OROSo6aSYcPT1VHE4q52KvyxgFkQgrgb/IEsxOuvQ2fZZbs8khJAyCEPM24/g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@tanstack/history@1.162.4': + resolution: {integrity: sha512-utTS5L2OkeYUzXGohL1Z8sefu1GLNOJcxe8Hd6iIdc/Xo1K1nDB2JEp4iSFhvYh33xKC9V91TxrS8qfrpoKobQ==} + engines: {node: '>=20.19'} + + '@tanstack/react-router@1.170.36': + resolution: {integrity: sha512-AbgcI/xO8AJY1r6y5tF7TZyHH0VKm0XcfY3QVIVCrHq8k04Hkj1N4nfLL+1xCGC3VnMI3AYGAVWkatnqE2dxAQ==} + engines: {node: '>=20.19'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-start-client@1.168.34': + resolution: {integrity: sha512-rNwogcDo5A9xeKmGHIocI50nlqtlEr5lcgbcdW9gCtDEloXALdwFtXriEj3kHZe7BLvn9FItZESZcC3xo4/71w==} + engines: {node: '>=22.12.0'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-start-rsc@0.1.53': + resolution: {integrity: sha512-Hzwpd74HyvTFU4rEY9PpbUaYJ7BA3deCg0p+Dyj3NTFsTnULD+/Eba87u1QPl5UEVsKWyIG9J7g4J6JZpxFWSg==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@rspack/core': '>=2.0.0-0' + '@vitejs/plugin-rsc': '>=0.5.30' + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + react-server-dom-rspack: '>=0.0.2' + peerDependenciesMeta: + '@rspack/core': + optional: true + '@vitejs/plugin-rsc': + optional: true + react-server-dom-rspack: + optional: true + + '@tanstack/react-start-server@1.167.41': + resolution: {integrity: sha512-ng4M05+vPug8rJH4OzF6u45JRSn+MThpjGCzkXmBgW3w/6TRkzWHQMO5/tBzpERJhUHp+uk178ZfFJVw0SWYpA==} + engines: {node: '>=22.12.0'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-start@1.168.54': + resolution: {integrity: sha512-x0GWvFm1e4WtgETxDE0xVWa39HdEnoinKQ9SU8pvO187SDsSpudYuhr8StfWdLE5iRhziGchLqlPl6UccUZ46w==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@rsbuild/core': ^2.0.0 + '@vitejs/plugin-rsc': '*' + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@vitejs/plugin-rsc': + optional: true + vite: + optional: true + + '@tanstack/react-store@0.11.1': + resolution: {integrity: sha512-HaIGKI3YLmjBYIvy5DFDY23oNaYZIsTZfngey07Uh5iLVJgM3bIGCnZeOFOqzjFld9JHWcaHJnasD/bKoGKwJQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/router-core@1.171.30': + resolution: {integrity: sha512-wtS1yCAb/k5CJBauvrCyqf2n4/kRc3aiz81tFBJ1QXH4Utsu81xFTMq15AdmNWgWmt2UstUSMfWi4Ua7ph2F+w==} + engines: {node: '>=20.19'} + + '@tanstack/router-generator@1.167.36': + resolution: {integrity: sha512-9Sjm1j8fkurviVIcbAXVdoyqAT8tlurY1tD9Na9Y59/BW5uWT5/5U+eU4Nv/d5grBKyosiJCP7/pcADvstnEgg==} + engines: {node: '>=20.19'} + + '@tanstack/router-plugin@1.168.38': + resolution: {integrity: sha512-0SWwASONOiy7biNBvzdmfhKWwhxa+oJUZHIAdsAEAK+H1sftLWcE3b4sil5omjIIAlPmBJLk2JuUnfBWrn0iIg==} + engines: {node: '>=20.19'} + peerDependencies: + '@rsbuild/core': '>=1.0.2 || ^2.0.0' + '@tanstack/react-router': ^1.170.36 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' + vite-plugin-solid: ^2.11.10 || ^3.0.0-0 + webpack: '>=5.92.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@tanstack/react-router': + optional: true + vite: + optional: true + vite-plugin-solid: + optional: true + webpack: + optional: true + + '@tanstack/router-utils@1.162.3': + resolution: {integrity: sha512-Icb0xGuG1+54IV0WMLRcc3ErTx2HeJWyPG661FkQ8UT6guoBq1FJjFRqlG/JS0xi4mFFkBhvwO7tbLa32f3yxA==} + engines: {node: '>=20.19'} + + '@tanstack/start-client-core@1.170.30': + resolution: {integrity: sha512-eyNrOJumsx68Od+//eVWgQdQAdleY9bzbJ/N9/q5x/pqHdtaSxHYqMERPAmB7XcYrMoF0Bo9LcP1TfXqvqk69g==} + engines: {node: '>=22.12.0'} + + '@tanstack/start-fn-stubs@1.162.0': + resolution: {integrity: sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ==} + engines: {node: '>=22.12.0'} + + '@tanstack/start-plugin-core@1.171.44': + resolution: {integrity: sha512-xSUlXNpA/k1cNHoIcPFqBw8kehQelUn7qN8dCVMvNEjSRA63jWbFVZNrkMXAKsY0sTMM+i4qoOmCleKT1ha7nA==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@rsbuild/core': ^2.0.0 + vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + vite: + optional: true + + '@tanstack/start-server-core@1.169.35': + resolution: {integrity: sha512-xy6DB1EFznF9d7r+lqj35+Gz0alreCh8tO9+yPepANab+WZagQEDjFwHSY9vrv3lzBWbMlRrkkGG1OZWOSL48w==} + engines: {node: '>=22.12.0'} + + '@tanstack/start-storage-context@1.167.32': + resolution: {integrity: sha512-Di2mLQPXy1oPFU0o9jb0oMA/XXX9sJc+FEMJo3PMiSyB6cPnbAjsR1VgvavfsCBMi7kOE+ctdK+ELDX2MwKvIA==} + engines: {node: '>=22.12.0'} + + '@tanstack/store@0.11.1': + resolution: {integrity: sha512-mzTOBhypOuDJAy/D8n2MfUZ1HFkXnmSETviRyhqEC8LUE7/IZQExOTxMANj3KjTofYTkFNpBY67qaVrT41YccA==} + + '@tanstack/virtual-file-routes@1.162.0': + resolution: {integrity: sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA==} + engines: {node: '>=20.19'} + + '@turbo/darwin-64@2.10.13': + resolution: {integrity: sha512-m5DBcpkxmcKpEJHHFUfqf9GLUjSmw3cDnBJM9nghPW3kjCNb5OyNKmzG7/yT5x5AwzOO+HMwKN+UI4iVKL87YA==} + cpu: [x64] + os: [darwin] + + '@turbo/darwin-arm64@2.10.13': + resolution: {integrity: sha512-vfKPvSuoY8BJGj8M8yN+a7aq1g+CejbEacDSDlJLDkSbPN3J/U1DbYAmPG8Ype5XvImI0SgfvUhIorNnFj67zw==} + cpu: [arm64] + os: [darwin] + + '@turbo/linux-64@2.10.13': + resolution: {integrity: sha512-Zp0N5M6j9iEjJtFLTA2L+52TLuYy0VbXT3zLZzfMeqqdKSUJ7pDo2pA1NhqjoQcF2dIsktZ8xZRW3pGI6T81fw==} + cpu: [x64] + os: [android, linux] + + '@turbo/linux-arm64@2.10.13': + resolution: {integrity: sha512-M8XcfWdS2D4EP3wzd5ehUyCANucMIOsRE6gZuV0Mr2NIn+FpsUjXFCh7r9HY7GnNcjXH4tUnT76OsCDg2c0Fng==} + cpu: [arm64] + os: [android, linux] + + '@turbo/windows-64@2.10.13': + resolution: {integrity: sha512-QFd3KBMpBBCc31TbxMnxgdBivie8lxJXV8EqmanH8fg8l2e1BdCLWpZJbxk48VNvcF4LHUnwO0FJOq+veKN1cw==} + cpu: [x64] + os: [win32] + + '@turbo/windows-arm64@2.10.13': + resolution: {integrity: sha512-rM+cFO1P8iAHXdasOdMyK9nDk0UGII7VEFLIA8+jwv/+rh48pnVBbF2OSjJDBOw57pxNLIOEDA0JyKcarTBcIw==} + cpu: [arm64] + os: [win32] + + '@types/node@24.10.1': + resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} + + '@yuku-codegen/binding-android-arm64@0.10.2': + resolution: {integrity: sha512-Oc2KInVkPfUjEB4PeV6X0NvIoyYTzDe/WmqFrTwBqKs6YKnz4A7XwWQvJTb7M0rLz9a6WgpUUiiS5QKaCi4O/g==} + cpu: [arm64] + os: [android] + + '@yuku-codegen/binding-darwin-arm64@0.10.2': + resolution: {integrity: sha512-3H7eNPIHJndUJXZ4QUGBPq1zC6RGcUZfm7bymJes+/N7wTVWUn1bxZ9JcozYHpkWQNm9f23G8YWbaHD9aYH72A==} + cpu: [arm64] + os: [darwin] + + '@yuku-codegen/binding-darwin-x64@0.10.2': + resolution: {integrity: sha512-AJOUpR2s3LF9AWiiub/Uyc/UoXNTWcq8hK3cVI6fUSXtwh34dG21J6hRuNlO6JVJFTo4o3ScVvZOrh/YFfUEAA==} + cpu: [x64] + os: [darwin] + + '@yuku-codegen/binding-freebsd-x64@0.10.2': + resolution: {integrity: sha512-ms7DcZu87u5CiK/wMwvpKAvAmtaqKjCQIXNweMLypG6qbuiaOMQf1jpbB5+j46xBcgCovo8TQMcv0bCQLKIL9w==} + cpu: [x64] + os: [freebsd] + + '@yuku-codegen/binding-linux-arm-gnu@0.10.2': + resolution: {integrity: sha512-xJDpYAsKV5+eaiBhTYl05fvT6sst4PsCeuIFMRu9b0/WCSrNQPfCDtAQ5/MS6xNpsdujdZEPR+gmfWk3ZG5i3A==} + cpu: [arm] + os: [linux] + + '@yuku-codegen/binding-linux-arm-musl@0.10.2': + resolution: {integrity: sha512-qfTkgd7AEx61l4K9VtXWCGTxc/fmXJ4ZheDz3i+/AAJUtg4sa0bPrc0VBxPggB/rayR8Z3+JfrBItuyanBJJ9Q==} + cpu: [arm] + os: [linux] + + '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': + resolution: {integrity: sha512-4e6Mifm/4UdjtU3D8mATIrvgP+xEiH8xtQOjd0zpd72XKWT7ug3sdyhq2utkkZFP6BvYp7SgZrI+aR4VeIOHdw==} + cpu: [arm64] + os: [linux] + + '@yuku-codegen/binding-linux-arm64-musl@0.10.2': + resolution: {integrity: sha512-RdsJrUfDYFVV3JOmWFUWwSu31fa1APn12xDeIKxgl/YWxrabwtxsDBNjF2561c7tmcbiewdCUvngqRs8AyGVLA==} + cpu: [arm64] + os: [linux] + + '@yuku-codegen/binding-linux-x64-gnu@0.10.2': + resolution: {integrity: sha512-mVzWimEPPreaPyXIUvxsHoJzvO7ckZ5j0LgQFHz04zQIRwt9A9T2hA7K5/jYjJKkMxWG/U2VjhGNwVhtyU+uqg==} + cpu: [x64] + os: [linux] + + '@yuku-codegen/binding-linux-x64-musl@0.10.2': + resolution: {integrity: sha512-Y77fyISurmr2mvO1yeq3u+x/WJbACgPR4w+lzEVx30ViCxZzIGrZPRN1yEdZ9xUNPNsIO5thBHIdRNG+UGUG+Q==} + cpu: [x64] + os: [linux] + + '@yuku-codegen/binding-win32-arm64@0.10.2': + resolution: {integrity: sha512-1+tGLyG0u5YYy0lev4ck7/0sd8xJ9SZde0dLut7qLDPZV5WVTV8x6OxNXUne/PGuHZyO1vK+txPQzzHOyXHGSw==} + cpu: [arm64] + os: [win32] + + '@yuku-codegen/binding-win32-x64@0.10.2': + resolution: {integrity: sha512-8a2SExRohRbwC0MY4VpOF0/RSckrJ2ASZqAor5/RYSJJaeadR93n10gZzcKT6pY9ukiSOIZCRKVRD2tH73T0qA==} + cpu: [x64] + os: [win32] + + '@yuku-parser/binding-android-arm64@0.10.2': + resolution: {integrity: sha512-2VPBU9fRGRAQ2xPAvghnec3oou5Nrxm2Bezhf+13UMspAxQSkF/32r+ySKXSwIPA5/RivumDJDxAxc301Sgicw==} + cpu: [arm64] + os: [android] + + '@yuku-parser/binding-darwin-arm64@0.10.2': + resolution: {integrity: sha512-LD+PMZE51tCYTOss5HBkm3/AE39MvcMDBfWJx7A4yDcjfNbAQDnHZKtzSOuqrswx+TQHY0ws5xn6+fWOwtmfBA==} + cpu: [arm64] + os: [darwin] + + '@yuku-parser/binding-darwin-x64@0.10.2': + resolution: {integrity: sha512-mmZ8cND+AoIIMRERyMinlg5ApHxP23B9jH2B5wT7T+dliPa9rubLxneB/SUjFwyUjGaFnB5G7t4YvpfbO5zbkQ==} + cpu: [x64] + os: [darwin] + + '@yuku-parser/binding-freebsd-x64@0.10.2': + resolution: {integrity: sha512-gVIjaaIddbRfAhHlC8N809wQWml7mxfSVnzaLtzGXObTeFTPAg/YVnQXt1UOhPM1ah5eG/8Y0RUlNpB4GVe7eQ==} + cpu: [x64] + os: [freebsd] + + '@yuku-parser/binding-linux-arm-gnu@0.10.2': + resolution: {integrity: sha512-q/XPPQQAPdlw05aPj30ygBhekmQryGOwxVraBgApjKK8yY1kNQgqq6XCYLF1WHSee+lhxclrTO7W0/bt7dR1GA==} + cpu: [arm] + os: [linux] + + '@yuku-parser/binding-linux-arm-musl@0.10.2': + resolution: {integrity: sha512-A+Cb0I1hFF4wilTQpWs79k1aNnj4B2tkrHx3zsuUNF9BtVY2zPZ4yeQEM/zjXrS/qJlNMZVK9NrWJjwdpnTrfg==} + cpu: [arm] + os: [linux] + + '@yuku-parser/binding-linux-arm64-gnu@0.10.2': + resolution: {integrity: sha512-aGNSzqIqqphFwAdIFwVvKIyXD1Iy3CxrEJVIZAT87Ecyi4vCmmDD2v2l9h+Gd3/wSy3JZlOI792LJbKAjyy9rQ==} + cpu: [arm64] + os: [linux] + + '@yuku-parser/binding-linux-arm64-musl@0.10.2': + resolution: {integrity: sha512-Ddl1sF0rtuCXyHGSOV6dcmdx+ETv1iD+IVFqQuOjzkJZWclxJxdBWX6ZJMRtTiGqGUTbqLEKiTXxpR/Bvqk+2A==} + cpu: [arm64] + os: [linux] + + '@yuku-parser/binding-linux-x64-gnu@0.10.2': + resolution: {integrity: sha512-/nlcpR6IF5U+0m5L9wvAIXeQa2DT+BXuvqKDsTcOTlcc0B4dHNyqE5hTXsS4hAyimpy2ZK8A1zMNF5hTrjg2cg==} + cpu: [x64] + os: [linux] + + '@yuku-parser/binding-linux-x64-musl@0.10.2': + resolution: {integrity: sha512-GX80dxTQD/M/OryyuxJcFzFENzry3cDFPvCFTyWogNWQH3fSHfMrNfpwpl1YzMos1eV9NygK5GSDG7VArQlb4w==} + cpu: [x64] + os: [linux] + + '@yuku-parser/binding-win32-arm64@0.10.2': + resolution: {integrity: sha512-agePQBV4VHewiGU0ACSjscZ/hJd283f9JfAF19Gf1rI5+wy5tTgx4GS36i0b3xim15AQ4RCpDRosEvhLZ4zAOw==} + cpu: [arm64] + os: [win32] + + '@yuku-parser/binding-win32-x64@0.10.2': + resolution: {integrity: sha512-s8//CMpgL5+y1lvDCdyh1rwGI5+ytDJywFJRe1vnhI7n0j+caxshNucurikYLLVeQ2SYFex6aPrzgQxkabBQRA==} + cpu: [x64] + os: [win32] + + '@yuku-toolchain/types@0.10.2': + resolution: {integrity: sha512-sSeo4SSSToiS+sSD+bwn/s94EEcaLJ7tG5LCp8gFYC1G5VzxzX7fqB6m9RU1yMD8KTpu6zdU/I1NlQf8hVBJ9Q==} + + adm-zip@0.6.0: + resolution: {integrity: sha512-XleryMhbuksdKtofnWZ9Sk+4CUTbms4Mb/EU32SZwToAyZ5RgVos/ki8n+yr0LWHOGKuakbXTuuYNHLQjhddgg==} + engines: {node: '>=14.0'} + + ansis@4.4.0: + resolution: {integrity: sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA==} + engines: {node: '>=14'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + babel-dead-code-elimination@1.0.12: + resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} + + baseline-browser-mapping@2.11.24: + resolution: {integrity: sha512-hYrgxie335U08WqICoGqKRzV1HFXv6zdxwJE4ekCb80CM9a0SVVsN4QPwT67RraRo+9h8IATk6uxHJw7QSkdOg==} + engines: {node: '>=6.0.0'} + hasBin: true + + browserslist@4.29.0: + resolution: {integrity: sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} + + caniuse-lite@1.0.30001810: + resolution: {integrity: sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + + dts-resolver@3.0.0: + resolution: {integrity: sha512-1T1f+z+4tl9XD+m+0HBgWoL/nm0bOIffyWaUuUSBlFg/86IWvfx+wjNaO/ybU0AJzG9/Mi5hBUgGV6zCmWEN7Q==} + engines: {node: ^22.18.0 || >=24.0.0} + peerDependencies: + oxc-resolver: '>=11.0.0' + peerDependenciesMeta: + oxc-resolver: + optional: true + + electron-to-chromium@1.5.430: + resolution: {integrity: sha512-e1QEj72Y4zd8RlNZVmoTg+iCOSVwpk05IOiiQwdrkwCSVlZfPthevErhE+nckGd2YbsXfp1SkisznhGVIXP2NQ==} + + empathic@2.0.1: + resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} + engines: {node: '>=14'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + exsolve@1.1.1: + resolution: {integrity: sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==} + + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fetchdts@0.1.7: + resolution: {integrity: sha512-YoZjBdafyLIop9lSxXVI33oLD5kN31q4Td+CasofLLYeLXRFeOsuOw0Uo+XNRi9PZlbfdlN2GmRtm4tCEQ9/KA==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-tsconfig@5.0.0-beta.6: + resolution: {integrity: sha512-X6fBC0pmImC70gvX2zm56go9hx0MyoGVdG0tUCkg/D+Xnh5TJsOZ7iDbOdI3PvmtrDxnu1YdDufpK2QJX1Meqw==} + engines: {node: '>=20.20.0'} + + h3@2.0.1-rc.20: + resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==} + engines: {node: '>=20.11.1'} + hasBin: true + peerDependencies: + crossws: ^0.4.1 + peerDependenciesMeta: + crossws: + optional: true + + hookable@6.1.1: + resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} + + human-id@4.2.1: + resolution: {integrity: sha512-zPGsiS+dWoTZtZ4AtpA9Y+BdSFSNWvnouNlWNoUFyAM6xHOHmdCvqO3k8AIbdamCOv4gUFUVNPf6rJFfc4UiJw==} + hasBin: true + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + + import-without-cache@0.4.1: + resolution: {integrity: sha512-vXoV9PjKHEednCUu01e98TkImxy67e3BJXbTIOmIq4Hyzw3IAwYRcuPkfeTzJzwyyts4kjuA73x+pWJLc4f86A==} + engines: {node: ^22.18.0 || >=24.0.0} + + isbot@5.2.2: + resolution: {integrity: sha512-iQcBXcd+Rv/pkubRyGh2utW2j1oPG5hZY6TUhVPpqK4G+o3IbxpJNx04hgksjc/N7GK5pEorUxDeg31cFgEk/w==} + engines: {node: '>=18'} + + isomorphic-ws@5.0.0: + resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + peerDependencies: + ws: '*' + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.3.2: + resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + launch-editor@2.14.1: + resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} + + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.19: + resolution: {integrity: sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-releases@2.0.55: + resolution: {integrity: sha512-mIrE/Cw9y+9Au6dS5vDKDhQza9YvG6w+ZrS6X+ZzA7yFW/soAeaups4Qzn1bL6g5FVy8WtP79+0j82oPIbqRjQ==} + engines: {node: '>=18'} + + obug@2.2.1: + resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} + engines: {node: '>=12.20.0'} + + obug@3.0.0: + resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} + engines: {node: '>=12.20.0'} + + package-manager-detector@1.8.0: + resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + + postcss@8.5.28: + resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} + engines: {node: ^10 || ^12 || >=14} + + prettier@3.9.7: + resolution: {integrity: sha512-T3mF5P7HFzZVLDQuCUNtJj6WK1pcpLMweMNUVwGb01bLNkH9AkKxtZvmInw8K6bnn2O3d6/5RHl6zSHiBAD0Og==} + engines: {node: '>=14'} + hasBin: true + + quansync@1.0.0: + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + + react-dom@19.3.0: + resolution: {integrity: sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==} + peerDependencies: + react: ^19.3.0 + + react@19.3.0: + resolution: {integrity: sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==} + engines: {node: '>=0.10.0'} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + rolldown-plugin-dts@0.28.6: + resolution: {integrity: sha512-qKrFtBfRfR2hP233m7Ic9zf3wv6MSYdZghWKMdEO6dRYZGlNfINJAa1P5ZVvyHh3mrcd7IJQvIY8L9vnm+v5rQ==} + engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} + peerDependencies: + '@typescript/native-preview': '*' + '@volar/typescript': ~2.4.0 + '@vue/language-core': ~3.2.0 || ~3.3.0 + rolldown: ^1.2.0 + typescript: ^5.0.0 || ^6.0.0 || ~7.0.0 + vue-tsc: ~3.2.0 || ~3.3.0 + peerDependenciesMeta: + '@typescript/native-preview': + optional: true + '@volar/typescript': + optional: true + '@vue/language-core': + optional: true + typescript: + optional: true + vue-tsc: + optional: true + + rolldown@1.2.9: + resolution: {integrity: sha512-hx/Pv0N1haXRb11qkfnK5MXB/iqr7i0yjWQqmO9uHqZpBgQSqzc8UsSnEpalsh+j1I8qQ2CkXAkJC8Br3dKSlg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rou3@0.8.1: + resolution: {integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==} + + scheduler@0.28.0: + resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + seroval-plugins@1.6.7: + resolution: {integrity: sha512-4Nk35ttD3DTDJW4hgw5StsVAPeU6qnDFnULAouw6tQ7oLTV/ICXrWpsXo2EE52eSP2joUMazbVf52mFEcADqRw==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.6.7: + resolution: {integrity: sha512-AeDcLh0yO2SFm9W71essgnSzLV9DI8ZH0x0knXn2DMnUZj728mpLbxjlbB6IqKCmqh8JA3cEqRyGoNkt584JcQ==} + engines: {node: '>=10'} + + shell-quote@1.10.0: + resolution: {integrity: sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==} + engines: {node: '>= 0.4'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + srvx@0.11.22: + resolution: {integrity: sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==} + engines: {node: '>=20.16.0'} + hasBin: true + + tinyexec@1.3.1: + resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + tsdown@0.23.0: + resolution: {integrity: sha512-BaT+ep1xnj5hdyICLd5r5SYYE+TXnI1ATePLykv9vcKpHpFTWUWRH+x1AF/E2qcu3YB6+vI8IdyxIIIffEqw5Q==} + engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} + hasBin: true + peerDependencies: + '@arethetypeswrong/core': ^0.18.1 + '@tsdown/css': 0.23.0 + '@tsdown/exe': 0.23.0 + '@vitejs/devtools': '*' + publint: ^0.3.8 + tsx: '*' + typescript: ^5.0.0 || ^6.0.0 || ^7.0.0 + unplugin-unused: '>=0.5.0' + unrun: '*' + peerDependenciesMeta: + '@arethetypeswrong/core': + optional: true + '@tsdown/css': + optional: true + '@tsdown/exe': + optional: true + '@vitejs/devtools': + optional: true + publint: + optional: true + tsx: + optional: true + typescript: + optional: true + unplugin-unused: + optional: true + unrun: + optional: true + + turbo@2.10.13: + resolution: {integrity: sha512-69MkPbjk+G8oyC7pC2DeBk0rPdbLz51wuH5eAT0Q4BVJkzq/b1XM4kUUidsARbmDjwIELSJwd1ezITULY9kWNw==} + hasBin: true + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + unconfig-core@7.5.0: + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + undici@7.29.0: + resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==} + engines: {node: '>=20.18.1'} + + unplugin@3.4.0: + resolution: {integrity: sha512-9skdIFlCsPdFV7wUfZxNsFInlW+7nJmGu2gkTu0OUhF56aXGsHab9x52/QhdJ4lC7ZDPWTxbiC4ANqVlsuaW3w==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@farmfe/core': '*' + '@rsbuild/core': '*' + '@rspack/core': '*' + bun-types-no-globals: '*' + esbuild: '*' + rolldown: '*' + rollup: '*' + unloader: '*' + vite: '*' + webpack: '*' + peerDependenciesMeta: + '@farmfe/core': + optional: true + '@rsbuild/core': + optional: true + '@rspack/core': + optional: true + bun-types-no-globals: + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + unloader: + optional: true + vite: + optional: true + webpack: + optional: true + + update-browserslist-db@1.3.3: + resolution: {integrity: sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + use-sync-external-store@1.7.0: + resolution: {integrity: sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + verkit@0.4.0: + resolution: {integrity: sha512-sXMwN6DMHeouPfCxkxWkKAmxphWKEenHYY5H1nIBzU3PmDsmJp6kBXJdshjVdpMZuWCmL9SH7KFRx29AylpP6g==} + engines: {node: '>=18.12.0'} + + vite@8.3.0: + resolution: {integrity: sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.7.1 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitefu@1.1.3: + resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + vite: + optional: true + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xmlbuilder2@4.0.3: + resolution: {integrity: sha512-bx8Q1STctnNaaDymWnkfQLKofs0mGNN7rLLapJlGuV3VlvegD7Ls4ggMjE3aUSWItCCzU0PEv45lI87iSigiCA==} + engines: {node: '>=20.0'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yaml@2.9.1: + resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} + engines: {node: '>= 14.6'} + hasBin: true + + yuku-ast@0.10.2: + resolution: {integrity: sha512-UnG9mA6giglCvSErft2/40TVFX750Sj1xgwddPLpG7J7rlr/P1wPADg9G2RK+d/1tNLtRVoLdMMOMVBB9561TQ==} + + yuku-codegen@0.10.2: + resolution: {integrity: sha512-hentl2dtrF6cPjiAirtkfxfFZBA6Hdm61UqRJ7cA0qrlDNMk9PZGOjw5w1mx3E0hu/6pHcJF4dJW+D0SXHPZOA==} + + yuku-parser@0.10.2: + resolution: {integrity: sha512-CgaU0/PPjCAIEZ3WQroosOxTY3eeKldAN3h+vk8pMNz4+jl1CZzBR4pW+K/rRPF112VooCL5FdjJoiMNjDrL2A==} + + zod@4.6.5: + resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} + +snapshots: + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.7': {} + + '@babel/core@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-compilation-targets': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helpers': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.8': + dependencies: + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.29.7': + dependencies: + '@babel/compat-data': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + browserslist: 4.29.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.29.7': {} + + '@babel/helper-module-imports@7.29.7': + dependencies: + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/helper-validator-option@7.29.7': {} + + '@babel/helpers@7.29.7': + dependencies: + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + + '@babel/parser@7.29.8': + dependencies: + '@babel/types': 7.29.8 + + '@babel/template@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + + '@babel/traverse@7.29.8': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@changesets/apply-release-plan@8.1.1': + dependencies: + '@changesets/config': 4.0.1 + '@changesets/format': 0.1.2 + '@changesets/git': 4.0.1 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + import-meta-resolve: 4.2.0 + jsonc-parser: 3.3.1 + semver: 7.8.5 + + '@changesets/assemble-release-plan@7.0.0': + dependencies: + '@changesets/errors': 1.0.0 + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + semver: 7.8.5 + + '@changesets/changelog-git@1.0.0': + dependencies: + '@changesets/types': 7.0.0 + + '@changesets/cli@3.0.3': + dependencies: + '@changesets/apply-release-plan': 8.1.1 + '@changesets/assemble-release-plan': 7.0.0 + '@changesets/changelog-git': 1.0.0 + '@changesets/config': 4.0.1 + '@changesets/errors': 1.0.0 + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/git': 4.0.1 + '@changesets/pre': 3.0.0 + '@changesets/read': 1.0.1 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + '@changesets/write': 1.0.1 + '@clack/prompts': 1.8.1 + '@manypkg/get-packages': 3.1.0 + '@pnpm/deps.graph-sequencer': 1100.0.1 + cac: 7.0.0 + import-meta-resolve: 4.2.0 + launch-editor: 2.14.1 + package-manager-detector: 1.8.0 + semver: 7.8.5 + tinyexec: 1.3.1 + + '@changesets/config@4.0.1': + dependencies: + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + picomatch: 4.0.7 + + '@changesets/errors@1.0.0': {} + + '@changesets/format@0.1.2': + dependencies: + package-manager-detector: 1.8.0 + tinyexec: 1.3.1 + + '@changesets/get-dependents-graph@3.0.0': + dependencies: + '@changesets/types': 7.0.0 + semver: 7.8.5 + + '@changesets/git@4.0.1': + dependencies: + '@changesets/errors': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + picomatch: 4.0.7 + tinyexec: 1.3.1 + + '@changesets/parse@1.0.0': + dependencies: + '@changesets/types': 7.0.0 + yaml: 2.9.1 + + '@changesets/pre@3.0.0': + dependencies: + '@changesets/errors': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + + '@changesets/read@1.0.1': + dependencies: + '@changesets/git': 4.0.1 + '@changesets/parse': 1.0.0 + '@changesets/types': 7.0.0 + + '@changesets/should-skip-package@1.0.0': + dependencies: + '@changesets/types': 7.0.0 + + '@changesets/types@7.0.0': {} + + '@changesets/write@1.0.1': + dependencies: + '@changesets/format': 0.1.2 + '@changesets/types': 7.0.0 + human-id: 4.2.1 + + '@clack/core@1.5.1': + dependencies: + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@clack/prompts@1.8.1': + dependencies: + '@clack/core': 1.5.1 + fast-string-width: 3.0.2 + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.6.0': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@manypkg/find-root@3.1.0': + dependencies: + '@manypkg/tools': 2.1.2 + + '@manypkg/get-packages@3.1.0': + dependencies: + '@manypkg/find-root': 3.1.0 + '@manypkg/tools': 2.1.2 + + '@manypkg/tools@2.1.2': + dependencies: + jju: 1.4.0 + tinyglobby: 0.2.17 + yaml: 2.9.1 + + '@module-federation/dts-plugin@2.9.0(typescript@6.0.3)': + dependencies: + '@module-federation/error-codes': 2.9.0 + '@module-federation/managers': 2.9.0 + '@module-federation/sdk': 2.9.0 + '@module-federation/third-party-dts-extractor': 2.9.0 + adm-zip: 0.6.0 + isomorphic-ws: 5.0.0(ws@8.21.0) + typescript: 6.0.3 + undici: 7.29.0 + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@module-federation/error-codes@2.9.0': {} + + '@module-federation/managers@2.9.0': + dependencies: + '@module-federation/sdk': 2.9.0 + + '@module-federation/runtime-core@2.9.0': + dependencies: + '@module-federation/error-codes': 2.9.0 + '@module-federation/sdk': 2.9.0 + + '@module-federation/runtime@2.9.0': + dependencies: + '@module-federation/error-codes': 2.9.0 + '@module-federation/runtime-core': 2.9.0 + '@module-federation/sdk': 2.9.0 + + '@module-federation/sdk@2.9.0': {} + + '@module-federation/third-party-dts-extractor@2.9.0': {} + + '@module-federation/vite@1.22.0(typescript@6.0.3)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@module-federation/dts-plugin': 2.9.0(typescript@6.0.3) + '@module-federation/runtime': 2.9.0 + '@module-federation/sdk': 2.9.0 + vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - vue-tsc + + '@oozcitak/dom@2.0.2': + dependencies: + '@oozcitak/infra': 2.0.2 + '@oozcitak/url': 3.0.0 + '@oozcitak/util': 10.0.0 + + '@oozcitak/infra@2.0.2': + dependencies: + '@oozcitak/util': 10.0.0 + + '@oozcitak/url@3.0.0': + dependencies: + '@oozcitak/infra': 2.0.2 + '@oozcitak/util': 10.0.0 + + '@oozcitak/util@10.0.0': {} + + '@oxc-project/types@0.150.0': {} + + '@pnpm/deps.graph-sequencer@1100.0.1': {} + + '@quansync/fs@1.1.0': + dependencies: + quansync: 1.0.0 + + '@rolldown/binding-android-arm-eabi@1.2.9': + optional: true + + '@rolldown/binding-android-arm64@1.2.9': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.9': + optional: true + + '@rolldown/binding-darwin-x64@1.2.9': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.9': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.9': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.9': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.9': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.9': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.9': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.9': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.9': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.9': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.9': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.9': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@tanstack/history@1.162.4': {} + + '@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/history': 1.162.4 + '@tanstack/react-store': 0.11.1(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/router-core': 1.171.30 + isbot: 5.2.2 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + + '@tanstack/react-start-client@1.168.34(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/router-core': 1.171.30 + '@tanstack/start-client-core': 1.170.30 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + + '@tanstack/react-start-rsc@0.1.53(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/router-core': 1.171.30 + '@tanstack/router-utils': 1.162.3 + '@tanstack/start-client-core': 1.170.30 + '@tanstack/start-fn-stubs': 1.162.0 + '@tanstack/start-plugin-core': 1.171.44(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/start-storage-context': 1.167.32 + pathe: 2.0.3 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - bun-types-no-globals + - crossws + - esbuild + - rolldown + - rollup + - supports-color + - unloader + - vite + - vite-plugin-solid + - webpack + + '@tanstack/react-start-server@1.167.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/router-core': 1.171.30 + '@tanstack/start-server-core': 1.169.35 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + transitivePeerDependencies: + - crossws + + '@tanstack/react-start@1.168.54(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/react-start-client': 1.168.34(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/react-start-rsc': 0.1.53(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/react-start-server': 1.167.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/router-utils': 1.162.3 + '@tanstack/start-client-core': 1.170.30 + '@tanstack/start-plugin-core': 1.171.44(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/start-server-core': 1.169.35 + pathe: 2.0.3 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + optionalDependencies: + vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - crossws + - esbuild + - react-server-dom-rspack + - rolldown + - rollup + - supports-color + - unloader + - vite-plugin-solid + - webpack + + '@tanstack/react-store@0.11.1(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/store': 0.11.1 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + use-sync-external-store: 1.7.0(react@19.3.0) + + '@tanstack/router-core@1.171.30': + dependencies: + '@tanstack/history': 1.162.4 + cookie-es: 3.1.1 + seroval: 1.6.7 + seroval-plugins: 1.6.7(seroval@1.6.7) + + '@tanstack/router-generator@1.167.36': + dependencies: + '@babel/types': 7.29.8 + '@tanstack/router-core': 1.171.30 + '@tanstack/router-utils': 1.162.3 + '@tanstack/virtual-file-routes': 1.162.0 + jiti: 2.7.0 + magic-string: 0.30.21 + prettier: 3.9.7 + zod: 4.6.5 + transitivePeerDependencies: + - supports-color + + '@tanstack/router-plugin@1.168.38(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@babel/core': 7.29.7 + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + '@tanstack/router-core': 1.171.30 + '@tanstack/router-generator': 1.167.36 + '@tanstack/router-utils': 1.162.3 + chokidar: 5.0.0 + unplugin: 3.4.0(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + zod: 4.6.5 + optionalDependencies: + '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - supports-color + - unloader + + '@tanstack/router-utils@1.162.3': + dependencies: + '@babel/generator': 7.29.8 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + ansis: 4.4.0 + babel-dead-code-elimination: 1.0.12 + diff: 8.0.4 + pathe: 2.0.3 + tinyglobby: 0.2.17 + transitivePeerDependencies: + - supports-color + + '@tanstack/start-client-core@1.170.30': + dependencies: + '@tanstack/router-core': 1.171.30 + '@tanstack/start-fn-stubs': 1.162.0 + '@tanstack/start-storage-context': 1.167.32 + seroval: 1.6.7 + + '@tanstack/start-fn-stubs@1.162.0': {} + + '@tanstack/start-plugin-core@1.171.44(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/core': 7.29.7 + '@babel/types': 7.29.8 + '@jridgewell/remapping': 2.3.5 + '@tanstack/router-core': 1.171.30 + '@tanstack/router-generator': 1.167.36 + '@tanstack/router-plugin': 1.168.38(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/router-utils': 1.162.3 + '@tanstack/start-server-core': 1.169.35 + exsolve: 1.1.1 + lightningcss: 1.33.0 + pathe: 2.0.3 + picomatch: 4.0.7 + seroval: 1.6.7 + source-map: 0.7.6 + srvx: 0.11.22 + tinyglobby: 0.2.17 + ufo: 1.6.4 + vitefu: 1.1.3(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + xmlbuilder2: 4.0.3 + zod: 4.6.5 + optionalDependencies: + vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - '@tanstack/react-router' + - bun-types-no-globals + - crossws + - esbuild + - rolldown + - rollup + - supports-color + - unloader + - vite-plugin-solid + - webpack + + '@tanstack/start-server-core@1.169.35': + dependencies: + '@tanstack/history': 1.162.4 + '@tanstack/router-core': 1.171.30 + '@tanstack/start-client-core': 1.170.30 + '@tanstack/start-storage-context': 1.167.32 + fetchdts: 0.1.7 + h3-v2: h3@2.0.1-rc.20 + seroval: 1.6.7 + transitivePeerDependencies: + - crossws + + '@tanstack/start-storage-context@1.167.32': + dependencies: + '@tanstack/router-core': 1.171.30 + + '@tanstack/store@0.11.1': {} + + '@tanstack/virtual-file-routes@1.162.0': {} + + '@turbo/darwin-64@2.10.13': + optional: true + + '@turbo/darwin-arm64@2.10.13': + optional: true + + '@turbo/linux-64@2.10.13': + optional: true + + '@turbo/linux-arm64@2.10.13': + optional: true + + '@turbo/windows-64@2.10.13': + optional: true + + '@turbo/windows-arm64@2.10.13': + optional: true + + '@types/node@24.10.1': + dependencies: + undici-types: 7.16.0 + + '@yuku-codegen/binding-android-arm64@0.10.2': + optional: true + + '@yuku-codegen/binding-darwin-arm64@0.10.2': + optional: true + + '@yuku-codegen/binding-darwin-x64@0.10.2': + optional: true + + '@yuku-codegen/binding-freebsd-x64@0.10.2': + optional: true + + '@yuku-codegen/binding-linux-arm-gnu@0.10.2': + optional: true + + '@yuku-codegen/binding-linux-arm-musl@0.10.2': + optional: true + + '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': + optional: true + + '@yuku-codegen/binding-linux-arm64-musl@0.10.2': + optional: true + + '@yuku-codegen/binding-linux-x64-gnu@0.10.2': + optional: true + + '@yuku-codegen/binding-linux-x64-musl@0.10.2': + optional: true + + '@yuku-codegen/binding-win32-arm64@0.10.2': + optional: true + + '@yuku-codegen/binding-win32-x64@0.10.2': + optional: true + + '@yuku-parser/binding-android-arm64@0.10.2': + optional: true + + '@yuku-parser/binding-darwin-arm64@0.10.2': + optional: true + + '@yuku-parser/binding-darwin-x64@0.10.2': + optional: true + + '@yuku-parser/binding-freebsd-x64@0.10.2': + optional: true + + '@yuku-parser/binding-linux-arm-gnu@0.10.2': + optional: true + + '@yuku-parser/binding-linux-arm-musl@0.10.2': + optional: true + + '@yuku-parser/binding-linux-arm64-gnu@0.10.2': + optional: true + + '@yuku-parser/binding-linux-arm64-musl@0.10.2': + optional: true + + '@yuku-parser/binding-linux-x64-gnu@0.10.2': + optional: true + + '@yuku-parser/binding-linux-x64-musl@0.10.2': + optional: true + + '@yuku-parser/binding-win32-arm64@0.10.2': + optional: true + + '@yuku-parser/binding-win32-x64@0.10.2': + optional: true + + '@yuku-toolchain/types@0.10.2': {} + + adm-zip@0.6.0: {} + + ansis@4.4.0: {} + + argparse@2.0.1: {} + + babel-dead-code-elimination@1.0.12: + dependencies: + '@babel/core': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + baseline-browser-mapping@2.11.24: {} + + browserslist@4.29.0: + dependencies: + baseline-browser-mapping: 2.11.24 + caniuse-lite: 1.0.30001810 + electron-to-chromium: 1.5.430 + node-releases: 2.0.55 + update-browserslist-db: 1.3.3(browserslist@4.29.0) + + cac@7.0.0: {} + + caniuse-lite@1.0.30001810: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + + convert-source-map@2.0.0: {} + + cookie-es@3.1.1: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + defu@6.1.7: {} + + detect-libc@2.1.2: {} + + diff@8.0.4: {} + + dts-resolver@3.0.0: {} + + electron-to-chromium@1.5.430: {} + + empathic@2.0.1: {} + + escalade@3.2.0: {} + + exsolve@1.1.1: {} + + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + + fast-wrap-ansi@0.2.2: + dependencies: + fast-string-width: 3.0.2 + + fdir@6.5.0(picomatch@4.0.7): + optionalDependencies: + picomatch: 4.0.7 + + fetchdts@0.1.7: {} + + fsevents@2.3.3: + optional: true + + gensync@1.0.0-beta.2: {} + + get-tsconfig@5.0.0-beta.6: + dependencies: + resolve-pkg-maps: 1.0.0 + + h3@2.0.1-rc.20: + dependencies: + rou3: 0.8.1 + srvx: 0.11.22 + + hookable@6.1.1: {} + + human-id@4.2.1: {} + + import-meta-resolve@4.2.0: {} + + import-without-cache@0.4.1: {} + + isbot@5.2.2: {} + + isomorphic-ws@5.0.0(ws@8.21.0): + dependencies: + ws: 8.21.0 + + jiti@2.7.0: {} + + jju@1.4.0: {} + + js-tokens@4.0.0: {} + + js-yaml@4.3.2: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json5@2.2.3: {} + + jsonc-parser@3.3.1: {} + + launch-editor@2.14.1: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.10.0 + + lightningcss-android-arm64@1.33.0: + optional: true + + lightningcss-darwin-arm64@1.33.0: + optional: true + + lightningcss-darwin-x64@1.33.0: + optional: true + + lightningcss-freebsd-x64@1.33.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + + lightningcss-linux-arm64-gnu@1.33.0: + optional: true + + lightningcss-linux-arm64-musl@1.33.0: + optional: true + + lightningcss-linux-x64-gnu@1.33.0: + optional: true + + lightningcss-linux-x64-musl@1.33.0: + optional: true + + lightningcss-win32-arm64-msvc@1.33.0: + optional: true + + lightningcss-win32-x64-msvc@1.33.0: + optional: true + + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + ms@2.1.3: {} + + nanoid@3.3.19: {} + + node-releases@2.0.55: {} + + obug@2.2.1: {} + + obug@3.0.0: {} + + package-manager-detector@1.8.0: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.7: {} + + postcss@8.5.28: + dependencies: + nanoid: 3.3.19 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@3.9.7: {} + + quansync@1.0.0: {} + + react-dom@19.3.0(react@19.3.0): + dependencies: + react: 19.3.0 + scheduler: 0.28.0 + + react@19.3.0: {} + + readdirp@5.1.1: {} + + resolve-pkg-maps@1.0.0: {} + + rolldown-plugin-dts@0.28.6(rolldown@1.2.9)(typescript@6.0.3): + dependencies: + dts-resolver: 3.0.0 + get-tsconfig: 5.0.0-beta.6 + obug: 3.0.0 + rolldown: 1.2.9 + yuku-ast: 0.10.2 + yuku-codegen: 0.10.2 + yuku-parser: 0.10.2 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - oxc-resolver + + rolldown@1.2.9: + dependencies: + '@oxc-project/types': 0.150.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.9 + '@rolldown/binding-android-arm64': 1.2.9 + '@rolldown/binding-darwin-arm64': 1.2.9 + '@rolldown/binding-darwin-x64': 1.2.9 + '@rolldown/binding-freebsd-x64': 1.2.9 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.9 + '@rolldown/binding-linux-arm64-gnu': 1.2.9 + '@rolldown/binding-linux-arm64-musl': 1.2.9 + '@rolldown/binding-linux-ppc64-gnu': 1.2.9 + '@rolldown/binding-linux-s390x-gnu': 1.2.9 + '@rolldown/binding-linux-x64-gnu': 1.2.9 + '@rolldown/binding-linux-x64-musl': 1.2.9 + '@rolldown/binding-openharmony-arm64': 1.2.9 + '@rolldown/binding-win32-arm64-msvc': 1.2.9 + '@rolldown/binding-win32-x64-msvc': 1.2.9 + + rou3@0.8.1: {} + + scheduler@0.28.0: {} + + semver@6.3.1: {} + + semver@7.8.5: {} + + seroval-plugins@1.6.7(seroval@1.6.7): + dependencies: + seroval: 1.6.7 + + seroval@1.6.7: {} + + shell-quote@1.10.0: {} + + sisteransi@1.0.5: {} + + source-map-js@1.2.1: {} + + source-map@0.7.6: {} + + srvx@0.11.22: {} + + tinyexec@1.3.1: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + + tree-kill@1.2.2: {} + + tsdown@0.23.0(typescript@6.0.3): + dependencies: + cac: 7.0.0 + defu: 6.1.7 + empathic: 2.0.1 + hookable: 6.1.1 + import-without-cache: 0.4.1 + obug: 2.2.1 + picomatch: 4.0.7 + rolldown: 1.2.9 + rolldown-plugin-dts: 0.28.6(rolldown@1.2.9)(typescript@6.0.3) + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + tree-kill: 1.2.2 + unconfig-core: 7.5.0 + verkit: 0.4.0 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - '@typescript/native-preview' + - '@volar/typescript' + - '@vue/language-core' + - oxc-resolver + - vue-tsc + + turbo@2.10.13: + optionalDependencies: + '@turbo/darwin-64': 2.10.13 + '@turbo/darwin-arm64': 2.10.13 + '@turbo/linux-64': 2.10.13 + '@turbo/linux-arm64': 2.10.13 + '@turbo/windows-64': 2.10.13 + '@turbo/windows-arm64': 2.10.13 + + typescript@6.0.3: {} + + ufo@1.6.4: {} + + unconfig-core@7.5.0: + dependencies: + '@quansync/fs': 1.1.0 + quansync: 1.0.0 + + undici-types@7.16.0: {} + + undici@7.29.0: {} + + unplugin@3.4.0(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)): + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.7 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + rolldown: 1.2.9 + vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + + update-browserslist-db@1.3.3(browserslist@4.29.0): + dependencies: + browserslist: 4.29.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + use-sync-external-store@1.7.0(react@19.3.0): + dependencies: + react: 19.3.0 + + verkit@0.4.0: {} + + vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1): + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.7 + postcss: 8.5.28 + rolldown: 1.2.9 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 24.10.1 + fsevents: 2.3.3 + jiti: 2.7.0 + yaml: 2.9.1 + + vitefu@1.1.3(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)): + optionalDependencies: + vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + + webpack-virtual-modules@0.6.2: {} + + ws@8.21.0: {} + + xmlbuilder2@4.0.3: + dependencies: + '@oozcitak/dom': 2.0.2 + '@oozcitak/infra': 2.0.2 + '@oozcitak/util': 10.0.0 + js-yaml: 4.3.2 + + yallist@3.1.1: {} + + yaml@2.9.1: {} + + yuku-ast@0.10.2: + dependencies: + '@yuku-toolchain/types': 0.10.2 + + yuku-codegen@0.10.2: + dependencies: + '@yuku-toolchain/types': 0.10.2 + optionalDependencies: + '@yuku-codegen/binding-android-arm64': 0.10.2 + '@yuku-codegen/binding-darwin-arm64': 0.10.2 + '@yuku-codegen/binding-darwin-x64': 0.10.2 + '@yuku-codegen/binding-freebsd-x64': 0.10.2 + '@yuku-codegen/binding-linux-arm-gnu': 0.10.2 + '@yuku-codegen/binding-linux-arm-musl': 0.10.2 + '@yuku-codegen/binding-linux-arm64-gnu': 0.10.2 + '@yuku-codegen/binding-linux-arm64-musl': 0.10.2 + '@yuku-codegen/binding-linux-x64-gnu': 0.10.2 + '@yuku-codegen/binding-linux-x64-musl': 0.10.2 + '@yuku-codegen/binding-win32-arm64': 0.10.2 + '@yuku-codegen/binding-win32-x64': 0.10.2 + + yuku-parser@0.10.2: + dependencies: + '@yuku-toolchain/types': 0.10.2 + yuku-ast: 0.10.2 + optionalDependencies: + '@yuku-parser/binding-android-arm64': 0.10.2 + '@yuku-parser/binding-darwin-arm64': 0.10.2 + '@yuku-parser/binding-darwin-x64': 0.10.2 + '@yuku-parser/binding-freebsd-x64': 0.10.2 + '@yuku-parser/binding-linux-arm-gnu': 0.10.2 + '@yuku-parser/binding-linux-arm-musl': 0.10.2 + '@yuku-parser/binding-linux-arm64-gnu': 0.10.2 + '@yuku-parser/binding-linux-arm64-musl': 0.10.2 + '@yuku-parser/binding-linux-x64-gnu': 0.10.2 + '@yuku-parser/binding-linux-x64-musl': 0.10.2 + '@yuku-parser/binding-win32-arm64': 0.10.2 + '@yuku-parser/binding-win32-x64': 0.10.2 + + zod@4.6.5: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..286cf7f --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +packages: + - apps/* + - packages/* diff --git a/test/release-artifacts.test.mjs b/test/release-artifacts.test.mjs new file mode 100644 index 0000000..e8f6555 --- /dev/null +++ b/test/release-artifacts.test.mjs @@ -0,0 +1,44 @@ +import assert from "node:assert/strict"; +import { spawnSync } from "node:child_process"; +import { existsSync, readFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import test from "node:test"; + +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); +const packageRoot = join(root, "packages", "tanstack"); +const dist = join(packageRoot, "dist"); + +test("published declarations reference an included source map", () => { + const declarationName = "index.d.mts"; + const declaration = readFileSync(join(dist, declarationName), "utf8"); + const sourceMap = declaration.match(/\/\/[#@]\s*sourceMappingURL=([^\s]+)\s*$/m)?.[1]; + + assert.ok(sourceMap, `${declarationName} has no source map reference`); + assert.ok( + existsSync(join(dist, sourceMap)), + `${declarationName} references missing source map ${sourceMap}`, + ); +}); + +test("npm package contains only runtime, metadata, and documentation files", () => { + const packed = spawnSync("npm", ["pack", "--dry-run", "--json", "--ignore-scripts"], { + cwd: packageRoot, + encoding: "utf8", + }); + + assert.equal(packed.status, 0, packed.stderr); + const [manifest] = JSON.parse(packed.stdout); + const files = manifest.files.map(({ path }) => path).sort(); + + assert.deepEqual(files, [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "dist/index.d.mts", + "dist/index.d.mts.map", + "dist/index.mjs", + "dist/index.mjs.map", + "package.json", + ]); +}); diff --git a/test/release-contracts.test.mjs b/test/release-contracts.test.mjs new file mode 100644 index 0000000..d7739ed --- /dev/null +++ b/test/release-contracts.test.mjs @@ -0,0 +1,116 @@ +import assert from "node:assert/strict"; +import { existsSync, readFileSync } from "node:fs"; +import { createRequire } from "node:module"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import test from "node:test"; + +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); +const packageRoot = join(root, "packages", "tanstack"); +const packageRequire = createRequire(join(packageRoot, "package.json")); +const packageJson = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf8")); +const rootPackageJson = JSON.parse(readFileSync(join(root, "package.json"), "utf8")); +const ciWorkflow = readFileSync(join(root, ".github", "workflows", "ci.yml"), "utf8"); +const releaseWorkflow = readFileSync(join(root, ".github", "workflows", "release.yml"), "utf8"); +const { tanstackStartModuleFederation } = await import(join(packageRoot, "dist", "index.mjs")); + +function upstreamOptions(options) { + const plugins = tanstackStartModuleFederation(options); + assert.ok(Array.isArray(plugins), "federation wrapper returns Vite plugins"); + const upstream = plugins.filter((plugin) => plugin.name === "module-federation-vite"); + assert.equal(upstream.length, 1, "wrapper delegates to one federation instance"); + assert.ok(upstream[0]._options, "upstream plugin exposes normalized options"); + return upstream[0]._options; +} + +test("applies TanStack-safe defaults", () => { + const options = upstreamOptions({ + name: "host", + filename: undefined, + manifest: undefined, + hostInitInjectLocation: undefined, + }); + assert.equal(options.filename, "remoteEntry.js"); + assert.equal(options.manifest, true); + assert.equal(options.hostInitInjectLocation, "entry"); + assert.equal(options.shared.react.shareConfig.singleton, true); + assert.equal(options.shared["react-dom"].shareConfig.singleton, true); +}); + +test("preserves explicit federation settings and shared entries", () => { + const options = upstreamOptions({ + name: "remote", + filename: "custom-entry.js", + manifest: false, + hostInitInjectLocation: "html", + shared: { + react: { singleton: false, requiredVersion: "^19.0.0" }, + lodash: { singleton: true }, + }, + }); + assert.equal(options.filename, "custom-entry.js"); + assert.equal(options.manifest, false); + assert.equal(options.hostInitInjectLocation, "html"); + assert.equal(options.shared.react.shareConfig.singleton, false); + assert.equal(options.shared.react.shareConfig.requiredVersion, "^19.0.0"); + assert.equal(options.shared.lodash.shareConfig.singleton, true); + assert.ok(options.shared["react-dom"], "unconfigured React DOM remains shared"); +}); + +test("does not mutate the caller's options", () => { + const options = { + name: "host", + shared: { react: { singleton: false } }, + remotes: { remote: { type: "module", name: "remote", entry: "remoteEntry.js" } }, + }; + const before = structuredClone(options); + upstreamOptions(options); + assert.deepEqual(options, before); +}); + +test("accepts the upstream array form", () => { + const options = upstreamOptions({ name: "remote", shared: ["lodash", "react"] }); + assert.deepEqual(Object.keys(options.shared).sort(), ["lodash", "react", "react-dom"]); + assert.equal(options.shared.react.shareConfig.singleton, true); + assert.equal(options.shared["react-dom"].shareConfig.singleton, true); +}); + +test("leaves the build target to each TanStack environment", () => { + const options = upstreamOptions({ name: "host", target: "node" }); + assert.equal(options.target, undefined); +}); + +test("published metadata points to ESM build and declaration map", () => { + assert.equal(packageJson.type, "module"); + assert.equal(packageJson.exports["."].import, "./dist/index.mjs"); + assert.equal(packageJson.exports["."].types, "./dist/index.d.mts"); + assert.equal( + packageRequire.resolve("@module-federation/tanstack"), + join(packageRoot, "dist", "index.mjs"), + ); + for (const file of ["index.mjs", "index.mjs.map", "index.d.mts", "index.d.mts.map"]) { + assert.ok(existsSync(join(packageRoot, "dist", file)), `dist/${file} exists`); + } +}); + +test("CI uses Node versions supported by the package build toolchain", () => { + const supportedNode = "^22.18.0 || ^24.11.0 || >=26.0.0"; + assert.equal(rootPackageJson.engines.node, supportedNode); + assert.equal(packageJson.engines.node, supportedNode); + assert.match(ciWorkflow, /node: \["22\.18\.0", "24", "26"\]/); + assert.doesNotMatch(ciWorkflow, /22\.12\.0/); +}); + +test("GitHub prereleases publish the version validated against their tag", () => { + assert.match(releaseWorkflow, /Tag\/version mismatch/); + assert.doesNotMatch(releaseWorkflow, /Set deterministic prerelease version/); + assert.doesNotMatch( + releaseWorkflow, + /github\.event\.release\.prerelease[\s\S]*npm pkg set version/, + ); +}); + +test("npm publications share one package-wide concurrency queue", () => { + assert.match(releaseWorkflow, /group: publish-module-federation-tanstack/); + assert.doesNotMatch(releaseWorkflow, /group:.*github\.(?:ref|run)/); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8de1016 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "files": [], + "references": [{ "path": "./packages/tanstack/tsconfig.json" }] +} diff --git a/turbo.json b/turbo.json new file mode 100644 index 0000000..882620b --- /dev/null +++ b/turbo.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://turborepo.com/schema.json", + "tasks": { + "build": { + "dependsOn": ["^build"], + "inputs": ["$TURBO_DEFAULT$", ".env*"], + "outputs": [".output/**", "dist/**"] + }, + "dev": { + "cache": false, + "persistent": true + }, + "typecheck": { + "dependsOn": ["^build", "^typecheck"], + "inputs": ["$TURBO_DEFAULT$", ".env*"], + "outputs": [] + } + } +} From cd00f8d0b6603dab6fa4c481fb9247a8a1be0d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9stor?= Date: Fri, 18 Sep 2026 09:44:41 +0200 Subject: [PATCH 2/5] feat: add federated TanStack Start examples --- .github/workflows/pkg-pr-new.yml | 2 +- .gitignore | 1 + .prettierignore | 1 + README.md | 13 + apps/README.md | 20 ++ apps/host/package.json | 28 ++ apps/host/src/remote.d.ts | 6 + apps/host/src/routeTree.gen.ts | 68 ++++ apps/host/src/router.tsx | 16 + apps/host/src/routes/__root.tsx | 37 ++ apps/host/src/routes/index.tsx | 37 ++ apps/host/src/styles.css | 139 +++++++ apps/host/tsconfig.json | 20 ++ apps/host/vite.config.ts | 30 ++ apps/remote/package.json | 28 ++ apps/remote/src/components/StatusCard.css | 77 ++++ apps/remote/src/components/StatusCard.tsx | 27 ++ apps/remote/src/routeTree.gen.ts | 68 ++++ apps/remote/src/router.tsx | 16 + apps/remote/src/routes/__root.tsx | 37 ++ apps/remote/src/routes/index.tsx | 22 ++ apps/remote/src/styles.css | 59 +++ apps/remote/tsconfig.json | 20 ++ apps/remote/vite.config.ts | 32 ++ docs/RELEASING.md | 6 +- package.json | 5 +- pnpm-lock.yaml | 418 ++++++++++++++++++++++ test/example-build.test.mjs | 53 +++ test/example-runtime.test.mjs | 99 +++++ test/release-contracts.test.mjs | 6 + tsconfig.json | 6 +- turbo.json | 4 + 32 files changed, 1394 insertions(+), 7 deletions(-) create mode 100644 apps/README.md create mode 100644 apps/host/package.json create mode 100644 apps/host/src/remote.d.ts create mode 100644 apps/host/src/routeTree.gen.ts create mode 100644 apps/host/src/router.tsx create mode 100644 apps/host/src/routes/__root.tsx create mode 100644 apps/host/src/routes/index.tsx create mode 100644 apps/host/src/styles.css create mode 100644 apps/host/tsconfig.json create mode 100644 apps/host/vite.config.ts create mode 100644 apps/remote/package.json create mode 100644 apps/remote/src/components/StatusCard.css create mode 100644 apps/remote/src/components/StatusCard.tsx create mode 100644 apps/remote/src/routeTree.gen.ts create mode 100644 apps/remote/src/router.tsx create mode 100644 apps/remote/src/routes/__root.tsx create mode 100644 apps/remote/src/routes/index.tsx create mode 100644 apps/remote/src/styles.css create mode 100644 apps/remote/tsconfig.json create mode 100644 apps/remote/vite.config.ts create mode 100644 test/example-build.test.mjs create mode 100644 test/example-runtime.test.mjs diff --git a/.github/workflows/pkg-pr-new.yml b/.github/workflows/pkg-pr-new.yml index 1dc317d..5fad24d 100644 --- a/.github/workflows/pkg-pr-new.yml +++ b/.github/workflows/pkg-pr-new.yml @@ -21,4 +21,4 @@ jobs: cache: pnpm - run: pnpm install --frozen-lockfile - run: pnpm build:package - - run: pnpm dlx pkg-pr-new@0.0.54 publish --compact ./packages/tanstack + - run: pnpm dlx pkg-pr-new@0.0.54 publish ./packages/tanstack diff --git a/.gitignore b/.gitignore index a62c8b7..09af92d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ dist/ pnpm-debug.log* coverage/ *.tgz +*.tsbuildinfo .DS_Store diff --git a/.prettierignore b/.prettierignore index b3bc6ae..77c3854 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,4 @@ dist node_modules pnpm-lock.yaml .turbo +**/routeTree.gen.ts diff --git a/README.md b/README.md index 87b7e89..514a256 100644 --- a/README.md +++ b/README.md @@ -50,3 +50,16 @@ selection to `@module-federation/vite` for each environment. The package supports Node 22.18+, 24.11+, and 26+, plus Vite 7/8 and TanStack Start 1.x. Use Vite 8 when developing SSR hosts that load remotes; Vite 7 remains supported for production builds. + +## Example + +The workspace includes two TanStack Start apps. `apps/remote` exposes a +stateful React card, and `apps/host` consumes it through this package. + +```bash +pnpm install +pnpm start +``` + +Open the host at http://localhost:3000. The remote also runs as its own +TanStack Start application at http://localhost:3001. diff --git a/apps/README.md b/apps/README.md new file mode 100644 index 0000000..113a75b --- /dev/null +++ b/apps/README.md @@ -0,0 +1,20 @@ +# TanStack Start example + +Both sides of this example are TanStack Start applications. + +- `remote` exposes `./StatusCard` from its Module Federation container and also + renders the component on its own `/` route. +- `host` loads `tanstack_remote/StatusCard` from the remote running on port 3001. Its own application runs on port 3000. + +From the repository root: + +```bash +pnpm start +``` + +The federation wrapper must precede `tanstackStart()` in both Vite configs. +React and React DOM use the wrapper's singleton defaults. + +Each package's `start` script runs Vite's development server. In Vite's CLI, +the bare `vite` command means “start”; the literal `vite start` command would +treat `start` as a project directory. diff --git a/apps/host/package.json b/apps/host/package.json new file mode 100644 index 0000000..1dbba92 --- /dev/null +++ b/apps/host/package.json @@ -0,0 +1,28 @@ +{ + "name": "tanstack-start-host", + "private": true, + "sideEffects": false, + "type": "module", + "scripts": { + "build": "vite build", + "dev": "vite dev --port 3000 --strictPort", + "start": "vite --host 127.0.0.1 --port 3000 --strictPort", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@module-federation/runtime": "2.9.0", + "@tanstack/react-router": "1.170.38", + "@tanstack/react-start": "1.168.56", + "react": "19.3.0", + "react-dom": "19.3.0" + }, + "devDependencies": { + "@module-federation/tanstack": "workspace:*", + "@types/node": "24.10.1", + "@types/react": "19.3.0", + "@types/react-dom": "19.3.0", + "@vitejs/plugin-react": "6.1.1", + "typescript": "6.0.3", + "vite": "8.3.0" + } +} diff --git a/apps/host/src/remote.d.ts b/apps/host/src/remote.d.ts new file mode 100644 index 0000000..e950d84 --- /dev/null +++ b/apps/host/src/remote.d.ts @@ -0,0 +1,6 @@ +declare module "tanstack_remote/StatusCard" { + import type { ComponentType } from "react"; + + const StatusCard: ComponentType; + export default StatusCard; +} diff --git a/apps/host/src/routeTree.gen.ts b/apps/host/src/routeTree.gen.ts new file mode 100644 index 0000000..dceedff --- /dev/null +++ b/apps/host/src/routeTree.gen.ts @@ -0,0 +1,68 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as IndexRouteImport } from './routes/index' + +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: '/' + fileRoutesByTo: FileRoutesByTo + to: '/' + id: '__root__' | '/' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() + +import type { getRouter } from './router.tsx' +import type { createStart } from '@tanstack/react-start' +declare module '@tanstack/react-start' { + interface Register { + ssr: true + router: Awaited> + } +} diff --git a/apps/host/src/router.tsx b/apps/host/src/router.tsx new file mode 100644 index 0000000..f8bf919 --- /dev/null +++ b/apps/host/src/router.tsx @@ -0,0 +1,16 @@ +import { createRouter } from "@tanstack/react-router"; +import { routeTree } from "./routeTree.gen"; + +export function getRouter() { + return createRouter({ + routeTree, + defaultPreload: "intent", + scrollRestoration: true, + }); +} + +declare module "@tanstack/react-router" { + interface Register { + router: ReturnType; + } +} diff --git a/apps/host/src/routes/__root.tsx b/apps/host/src/routes/__root.tsx new file mode 100644 index 0000000..ab2e206 --- /dev/null +++ b/apps/host/src/routes/__root.tsx @@ -0,0 +1,37 @@ +import { createRootRoute, HeadContent, Outlet, Scripts } from "@tanstack/react-router"; +import type { ReactNode } from "react"; +import stylesHref from "../styles.css?url"; + +export const Route = createRootRoute({ + head: () => ({ + links: [{ rel: "stylesheet", href: stylesHref }], + meta: [ + { charSet: "utf-8" }, + { name: "viewport", content: "width=device-width, initial-scale=1" }, + { title: "TanStack Start federation host" }, + ], + }), + component: RootComponent, +}); + +function RootComponent() { + return ( + + + + ); +} + +function RootDocument({ children }: { children: ReactNode }) { + return ( + + + + + + {children} + + + + ); +} diff --git a/apps/host/src/routes/index.tsx b/apps/host/src/routes/index.tsx new file mode 100644 index 0000000..bacdfcd --- /dev/null +++ b/apps/host/src/routes/index.tsx @@ -0,0 +1,37 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { lazy, Suspense } from "react"; + +const RemoteStatusCard = lazy(() => import("tanstack_remote/StatusCard")); + +export const Route = createFileRoute("/")({ + loader: () => import("tanstack_remote/StatusCard").then(() => null), + component: Home, +}); + +function Home() { + return ( +
+
+

TanStack Start × Module Federation

+

Two full-stack apps. One React tree.

+

+ This page belongs to the host on port 3000. The interactive card below is owned and built + by a second TanStack Start application on port 3001. +

+
+ +
+
+ 01 +

Host route

+

Rendered by TanStack Start

+

The route, document shell, and server response come from the host app.

+
+ + Loading the remote app…}> + + +
+
+ ); +} diff --git a/apps/host/src/styles.css b/apps/host/src/styles.css new file mode 100644 index 0000000..47b0470 --- /dev/null +++ b/apps/host/src/styles.css @@ -0,0 +1,139 @@ +:root { + color: #e9efe9; + background: #101411; + font-family: "Avenir Next", "Trebuchet MS", sans-serif; + font-synthesis: none; +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + min-width: 320px; + min-height: 100vh; + background: + linear-gradient(rgba(143, 255, 184, 0.045) 1px, transparent 1px), + linear-gradient(90deg, rgba(143, 255, 184, 0.045) 1px, transparent 1px), + radial-gradient(circle at 82% 8%, rgba(62, 133, 91, 0.24), transparent 35%), #101411; + background-size: + 40px 40px, + 40px 40px, + auto; +} + +button { + font: inherit; +} + +.page-shell { + width: min(1120px, calc(100% - 40px)); + margin: 0 auto; + padding: 88px 0 72px; +} + +.hero { + max-width: 820px; + animation: rise 520ms ease-out both; +} + +.eyebrow, +.card-label, +.card-index { + font-family: "SFMono-Regular", Consolas, monospace; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.eyebrow { + color: #8fffb8; + font-size: 0.78rem; +} + +h1 { + margin: 18px 0 20px; + max-width: 760px; + font-size: clamp(3rem, 8vw, 6.8rem); + line-height: 0.94; + letter-spacing: -0.065em; +} + +.lede { + max-width: 650px; + color: #aeb9b1; + font-size: 1.08rem; + line-height: 1.7; +} + +.proof-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 18px; + margin-top: 64px; +} + +.host-card, +.remote-loading { + min-height: 300px; + border: 1px solid #344239; + padding: 30px; +} + +.host-card { + position: relative; + background: rgba(20, 28, 23, 0.82); +} + +.card-index { + position: absolute; + top: 24px; + right: 26px; + color: #617066; + font-size: 0.72rem; +} + +.card-label { + margin: 0 0 70px; + color: #8fffb8; + font-size: 0.72rem; +} + +.host-card h2 { + margin: 0 0 14px; + font-size: 1.8rem; +} + +.host-card p:last-child { + max-width: 390px; + color: #96a39a; + line-height: 1.65; +} + +.remote-loading { + display: grid; + place-items: center; + color: #8fffb8; + font-family: "SFMono-Regular", Consolas, monospace; +} + +@keyframes rise { + from { + opacity: 0; + transform: translateY(16px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@media (max-width: 760px) { + .page-shell { + padding-top: 56px; + } + + .proof-grid { + grid-template-columns: 1fr; + } +} diff --git a/apps/host/tsconfig.json b/apps/host/tsconfig.json new file mode 100644 index 0000000..189cae2 --- /dev/null +++ b/apps/host/tsconfig.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "include": ["src/**/*.ts", "src/**/*.tsx", "vite.config.ts"], + "compilerOptions": { + "allowImportingTsExtensions": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["DOM", "DOM.Iterable", "ES2022"], + "module": "ESNext", + "moduleResolution": "Bundler", + "noEmit": true, + "noUncheckedIndexedAccess": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2022", + "types": ["node", "vite/client"], + "verbatimModuleSyntax": true + } +} diff --git a/apps/host/vite.config.ts b/apps/host/vite.config.ts new file mode 100644 index 0000000..03ecd37 --- /dev/null +++ b/apps/host/vite.config.ts @@ -0,0 +1,30 @@ +import { tanstackStartModuleFederation } from "@module-federation/tanstack"; +import { tanstackStart } from "@tanstack/react-start/plugin/vite"; +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [ + tanstackStartModuleFederation({ + name: "tanstack_host", + dts: false, + remotes: { + tanstack_remote: { + type: "module", + name: "tanstack_remote", + entry: "http://127.0.0.1:3001/remoteEntry.js", + }, + }, + }), + tanstackStart(), + react(), + ], + server: { + port: 3000, + }, + ssr: { + optimizeDeps: { + include: ["react", "react-dom"], + }, + }, +}); diff --git a/apps/remote/package.json b/apps/remote/package.json new file mode 100644 index 0000000..3a5c6a8 --- /dev/null +++ b/apps/remote/package.json @@ -0,0 +1,28 @@ +{ + "name": "tanstack-start-remote", + "private": true, + "sideEffects": false, + "type": "module", + "scripts": { + "build": "vite build", + "dev": "vite dev --port 3001 --strictPort", + "start": "vite --host 127.0.0.1 --port 3001 --strictPort", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@module-federation/runtime": "2.9.0", + "@tanstack/react-router": "1.170.38", + "@tanstack/react-start": "1.168.56", + "react": "19.3.0", + "react-dom": "19.3.0" + }, + "devDependencies": { + "@module-federation/tanstack": "workspace:*", + "@types/node": "24.10.1", + "@types/react": "19.3.0", + "@types/react-dom": "19.3.0", + "@vitejs/plugin-react": "6.1.1", + "typescript": "6.0.3", + "vite": "8.3.0" + } +} diff --git a/apps/remote/src/components/StatusCard.css b/apps/remote/src/components/StatusCard.css new file mode 100644 index 0000000..c8ab085 --- /dev/null +++ b/apps/remote/src/components/StatusCard.css @@ -0,0 +1,77 @@ +.remote-card { + position: relative; + min-height: 300px; + border: 1px solid #7b4d26; + background: #241b14; + color: #e9efe9; + padding: 30px; + box-shadow: 14px 14px 0 #0a0d0b; + font-family: "Avenir Next", "Trebuchet MS", sans-serif; +} + +.remote-card .card-index, +.remote-card .card-label, +.remote-card .remote-status, +.remote-card button { + font-family: "SFMono-Regular", Consolas, monospace; +} + +.remote-card .card-index, +.remote-card .card-label, +.remote-card .remote-status { + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.remote-card .card-index { + position: absolute; + top: 24px; + right: 26px; + color: #8f6d4e; + font-size: 0.72rem; +} + +.remote-card .card-label { + margin: 0 0 58px; + color: #f4a95f; + font-size: 0.75rem; +} + +.remote-card .remote-status { + display: flex; + align-items: center; + gap: 8px; + color: #c4cfca; + font-size: 0.66rem; +} + +.remote-card .status-dot { + width: 7px; + height: 7px; + border-radius: 50%; + background: #8fffb8; + box-shadow: 0 0 10px rgba(143, 255, 184, 0.72); +} + +.remote-card h2 { + margin: 22px 0 12px; + font-size: 1.8rem; +} + +.remote-card > p:not(.card-label) { + color: #aeb9b1; + line-height: 1.65; +} + +.remote-card button { + margin-top: 24px; + border: 0; + background: #f4a95f; + color: #17120e; + cursor: pointer; + padding: 12px 16px; +} + +.remote-card button:hover { + background: #ffc27f; +} diff --git a/apps/remote/src/components/StatusCard.tsx b/apps/remote/src/components/StatusCard.tsx new file mode 100644 index 0000000..bb5efaf --- /dev/null +++ b/apps/remote/src/components/StatusCard.tsx @@ -0,0 +1,27 @@ +import { useEffect, useState } from "react"; +import "./StatusCard.css"; + +export default function StatusCard() { + const [count, setCount] = useState(0); + const [hydrated, setHydrated] = useState(false); + + useEffect(() => { + setHydrated(true); + }, []); + + return ( +
+ 02 +

Federated route module

+
+ + {hydrated ? "Hydrated on the host" : "Rendered on the server"} +
+

Owned by the remote app

+

This component crossed an application boundary while React stayed a shared singleton.

+ +
+ ); +} diff --git a/apps/remote/src/routeTree.gen.ts b/apps/remote/src/routeTree.gen.ts new file mode 100644 index 0000000..dceedff --- /dev/null +++ b/apps/remote/src/routeTree.gen.ts @@ -0,0 +1,68 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as IndexRouteImport } from './routes/index' + +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: '/' + fileRoutesByTo: FileRoutesByTo + to: '/' + id: '__root__' | '/' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() + +import type { getRouter } from './router.tsx' +import type { createStart } from '@tanstack/react-start' +declare module '@tanstack/react-start' { + interface Register { + ssr: true + router: Awaited> + } +} diff --git a/apps/remote/src/router.tsx b/apps/remote/src/router.tsx new file mode 100644 index 0000000..f8bf919 --- /dev/null +++ b/apps/remote/src/router.tsx @@ -0,0 +1,16 @@ +import { createRouter } from "@tanstack/react-router"; +import { routeTree } from "./routeTree.gen"; + +export function getRouter() { + return createRouter({ + routeTree, + defaultPreload: "intent", + scrollRestoration: true, + }); +} + +declare module "@tanstack/react-router" { + interface Register { + router: ReturnType; + } +} diff --git a/apps/remote/src/routes/__root.tsx b/apps/remote/src/routes/__root.tsx new file mode 100644 index 0000000..ad43dab --- /dev/null +++ b/apps/remote/src/routes/__root.tsx @@ -0,0 +1,37 @@ +import { createRootRoute, HeadContent, Outlet, Scripts } from "@tanstack/react-router"; +import type { ReactNode } from "react"; +import stylesHref from "../styles.css?url"; + +export const Route = createRootRoute({ + head: () => ({ + links: [{ rel: "stylesheet", href: stylesHref }], + meta: [ + { charSet: "utf-8" }, + { name: "viewport", content: "width=device-width, initial-scale=1" }, + { title: "TanStack Start federation remote" }, + ], + }), + component: RootComponent, +}); + +function RootComponent() { + return ( + + + + ); +} + +function RootDocument({ children }: { children: ReactNode }) { + return ( + + + + + + {children} + + + + ); +} diff --git a/apps/remote/src/routes/index.tsx b/apps/remote/src/routes/index.tsx new file mode 100644 index 0000000..b1a59cd --- /dev/null +++ b/apps/remote/src/routes/index.tsx @@ -0,0 +1,22 @@ +import { createFileRoute } from "@tanstack/react-router"; +import StatusCard from "../components/StatusCard"; + +export const Route = createFileRoute("/")({ + component: Home, +}); + +function Home() { + return ( +
+
+

Standalone remote

+

This is a complete TanStack Start app.

+

+ It owns a route and a server build, then exposes the same component to the host through + Module Federation. +

+
+ +
+ ); +} diff --git a/apps/remote/src/styles.css b/apps/remote/src/styles.css new file mode 100644 index 0000000..2db3a3d --- /dev/null +++ b/apps/remote/src/styles.css @@ -0,0 +1,59 @@ +:root { + color: #e9efe9; + background: #101411; + font-family: "Avenir Next", "Trebuchet MS", sans-serif; + font-synthesis: none; +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + min-width: 320px; + min-height: 100vh; + background: radial-gradient(circle at 75% 12%, rgba(231, 155, 76, 0.2), transparent 32%), #101411; +} + +button { + font: inherit; +} + +.remote-page { + display: grid; + grid-template-columns: minmax(0, 1.2fr) minmax(320px, 0.8fr); + align-items: center; + gap: 70px; + width: min(1050px, calc(100% - 40px)); + min-height: 100vh; + margin: 0 auto; +} + +.eyebrow { + font-family: "SFMono-Regular", Consolas, monospace; + color: #f4a95f; + font-size: 0.75rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +h1 { + margin: 18px 0 20px; + font-size: clamp(3rem, 6vw, 5.8rem); + line-height: 0.96; + letter-spacing: -0.06em; +} + +.lede { + color: #aeb9b1; + line-height: 1.65; +} + +@media (max-width: 780px) { + .remote-page { + grid-template-columns: 1fr; + gap: 40px; + padding: 56px 0; + } +} diff --git a/apps/remote/tsconfig.json b/apps/remote/tsconfig.json new file mode 100644 index 0000000..189cae2 --- /dev/null +++ b/apps/remote/tsconfig.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "include": ["src/**/*.ts", "src/**/*.tsx", "vite.config.ts"], + "compilerOptions": { + "allowImportingTsExtensions": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["DOM", "DOM.Iterable", "ES2022"], + "module": "ESNext", + "moduleResolution": "Bundler", + "noEmit": true, + "noUncheckedIndexedAccess": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2022", + "types": ["node", "vite/client"], + "verbatimModuleSyntax": true + } +} diff --git a/apps/remote/vite.config.ts b/apps/remote/vite.config.ts new file mode 100644 index 0000000..146faf2 --- /dev/null +++ b/apps/remote/vite.config.ts @@ -0,0 +1,32 @@ +import { tanstackStartModuleFederation } from "@module-federation/tanstack"; +import { tanstackStart } from "@tanstack/react-start/plugin/vite"; +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [ + tanstackStartModuleFederation({ + name: "tanstack_remote", + dts: false, + exposes: { + "./StatusCard": "./src/components/StatusCard.tsx", + }, + }), + tanstackStart(), + react(), + ], + server: { + port: 3001, + cors: true, + origin: "http://127.0.0.1:3001", + }, + preview: { + port: 3001, + cors: true, + }, + ssr: { + optimizeDeps: { + include: ["react", "react-dom"], + }, + }, +}); diff --git a/docs/RELEASING.md b/docs/RELEASING.md index e7538a7..1119725 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -41,6 +41,6 @@ The publish workflow reruns the gate, checks that the source is reachable from a different dist-tag. Configure npm trusted publishing for repository `module-federation/tanstack`, workflow `release.yml`, environment `Publish`. -There are no committed app fixtures yet. The next integration matrix should -cover TanStack Start client and SSR builds on Vite 7 and 8, host/remote module -entries, manifest output, React singleton identity, and Nitro externalization. +The release gate builds both TanStack Start examples and checks the host server +bundle plus the remote federation manifest and entries. Browser-level coverage +for SSR markup, hydration, and remote failure recovery remains follow-up work. diff --git a/package.json b/package.json index 7ef2a35..f423342 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,13 @@ "scripts": { "build": "turbo run build", "build:package": "pnpm --filter @module-federation/tanstack build", - "dev": "turbo run dev", - "test": "pnpm build:package && node --test --test-concurrency=1 test/*.test.mjs", + "dev": "pnpm build:package && turbo run dev", + "test": "pnpm build && node --test --test-concurrency=1 test/*.test.mjs", "typecheck": "turbo run typecheck", "format": "prettier --write .", "format:check": "prettier --check .", "pack:tanstack": "pnpm --filter @module-federation/tanstack pack:dry", + "start": "pnpm build:package && turbo run start", "changeset": "changeset", "changeset:status": "changeset status" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1e2b0d4..8c8b656 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,6 +21,86 @@ importers: specifier: 6.0.3 version: 6.0.3 + apps/host: + dependencies: + '@module-federation/runtime': + specifier: 2.9.0 + version: 2.9.0 + '@tanstack/react-router': + specifier: 1.170.38 + version: 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/react-start': + specifier: 1.168.56 + version: 1.168.56(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + react: + specifier: 19.3.0 + version: 19.3.0 + react-dom: + specifier: 19.3.0 + version: 19.3.0(react@19.3.0) + devDependencies: + '@module-federation/tanstack': + specifier: workspace:* + version: link:../../packages/tanstack + '@types/node': + specifier: 24.10.1 + version: 24.10.1 + '@types/react': + specifier: 19.3.0 + version: 19.3.0 + '@types/react-dom': + specifier: 19.3.0 + version: 19.3.0(@types/react@19.3.0) + '@vitejs/plugin-react': + specifier: 6.1.1 + version: 6.1.1(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + typescript: + specifier: 6.0.3 + version: 6.0.3 + vite: + specifier: 8.3.0 + version: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + + apps/remote: + dependencies: + '@module-federation/runtime': + specifier: 2.9.0 + version: 2.9.0 + '@tanstack/react-router': + specifier: 1.170.38 + version: 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/react-start': + specifier: 1.168.56 + version: 1.168.56(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + react: + specifier: 19.3.0 + version: 19.3.0 + react-dom: + specifier: 19.3.0 + version: 19.3.0(react@19.3.0) + devDependencies: + '@module-federation/tanstack': + specifier: workspace:* + version: link:../../packages/tanstack + '@types/node': + specifier: 24.10.1 + version: 24.10.1 + '@types/react': + specifier: 19.3.0 + version: 19.3.0 + '@types/react-dom': + specifier: 19.3.0 + version: 19.3.0(@types/react@19.3.0) + '@vitejs/plugin-react': + specifier: 6.1.1 + version: 6.1.1(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + typescript: + specifier: 6.0.3 + version: 6.0.3 + vite: + specifier: 8.3.0 + version: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + packages/tanstack: dependencies: '@module-federation/vite': @@ -378,6 +458,13 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-router@1.170.38': + resolution: {integrity: sha512-iHM9b0aDJbuvftmkiQXawzoqsdV68p2Re2safbVLCnxafe+iLKV++2i3hI/BMAP6uR92/Mjw94JKJJfD7pbwHQ==} + engines: {node: '>=20.19'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-start-client@1.168.34': resolution: {integrity: sha512-rNwogcDo5A9xeKmGHIocI50nlqtlEr5lcgbcdW9gCtDEloXALdwFtXriEj3kHZe7BLvn9FItZESZcC3xo4/71w==} engines: {node: '>=22.12.0'} @@ -385,6 +472,13 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-start-client@1.168.36': + resolution: {integrity: sha512-TRXZKag/Ng0TqVfcN4cbEDVJhEZYosHZ9/VAEhK3PK/YqznytK+bcoonE4jP5NCXMdH2YRTMsrWKrApEuWz0Cg==} + engines: {node: '>=22.12.0'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-start-rsc@0.1.53': resolution: {integrity: sha512-Hzwpd74HyvTFU4rEY9PpbUaYJ7BA3deCg0p+Dyj3NTFsTnULD+/Eba87u1QPl5UEVsKWyIG9J7g4J6JZpxFWSg==} engines: {node: '>=22.12.0'} @@ -402,6 +496,23 @@ packages: react-server-dom-rspack: optional: true + '@tanstack/react-start-rsc@0.1.55': + resolution: {integrity: sha512-qfW89LMrewtMLHMCumMP3+3mf2gPezFE7FZ7CHPJis4paxt2A6Jl7eCpE6whYgc5DFiifUv9qdfbC22HIP0HAw==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@rspack/core': '>=2.0.0-0' + '@vitejs/plugin-rsc': '>=0.5.30' + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + react-server-dom-rspack: '>=0.0.2' + peerDependenciesMeta: + '@rspack/core': + optional: true + '@vitejs/plugin-rsc': + optional: true + react-server-dom-rspack: + optional: true + '@tanstack/react-start-server@1.167.41': resolution: {integrity: sha512-ng4M05+vPug8rJH4OzF6u45JRSn+MThpjGCzkXmBgW3w/6TRkzWHQMO5/tBzpERJhUHp+uk178ZfFJVw0SWYpA==} engines: {node: '>=22.12.0'} @@ -409,6 +520,13 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-start-server@1.167.43': + resolution: {integrity: sha512-/Fc1mOEBAyXmqxnihIkS1DrCcJX8ffrJ+xyc8nnFmO9YuCdrnZJskd48R1ZiOhM7u3vCPzDxUycIhKo8HlKn2g==} + engines: {node: '>=22.12.0'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-start@1.168.54': resolution: {integrity: sha512-x0GWvFm1e4WtgETxDE0xVWa39HdEnoinKQ9SU8pvO187SDsSpudYuhr8StfWdLE5iRhziGchLqlPl6UccUZ46w==} engines: {node: '>=22.12.0'} @@ -426,6 +544,23 @@ packages: vite: optional: true + '@tanstack/react-start@1.168.56': + resolution: {integrity: sha512-b/jVJS+yt7J0IKwXfVoA2mlhIi92sWfwCYrCVked0WERzgbYAad6xrOwNTljz9OKyeajofGrmMdKJgRzK1Lt2w==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@rsbuild/core': ^2.0.0 + '@vitejs/plugin-rsc': '*' + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@vitejs/plugin-rsc': + optional: true + vite: + optional: true + '@tanstack/react-store@0.11.1': resolution: {integrity: sha512-HaIGKI3YLmjBYIvy5DFDY23oNaYZIsTZfngey07Uh5iLVJgM3bIGCnZeOFOqzjFld9JHWcaHJnasD/bKoGKwJQ==} peerDependencies: @@ -436,10 +571,18 @@ packages: resolution: {integrity: sha512-wtS1yCAb/k5CJBauvrCyqf2n4/kRc3aiz81tFBJ1QXH4Utsu81xFTMq15AdmNWgWmt2UstUSMfWi4Ua7ph2F+w==} engines: {node: '>=20.19'} + '@tanstack/router-core@1.171.32': + resolution: {integrity: sha512-X86Jqk3vB2KJcUfS6oLi7B7yxbaa59QEhZRPPP1fRx3k+Jw/Fu1UYVBcRtdwK/OccQnrlQdVoKvNO3QXmyEBOw==} + engines: {node: '>=20.19'} + '@tanstack/router-generator@1.167.36': resolution: {integrity: sha512-9Sjm1j8fkurviVIcbAXVdoyqAT8tlurY1tD9Na9Y59/BW5uWT5/5U+eU4Nv/d5grBKyosiJCP7/pcADvstnEgg==} engines: {node: '>=20.19'} + '@tanstack/router-generator@1.167.38': + resolution: {integrity: sha512-lkqgFleDgfkW+QONVMKBs+ZGDUF0v9R9FkplS/GZvKDFpfnu+tZxmGlV2pryU1TDxyuSyjh56AtIla3NMrlScw==} + engines: {node: '>=20.19'} + '@tanstack/router-plugin@1.168.38': resolution: {integrity: sha512-0SWwASONOiy7biNBvzdmfhKWwhxa+oJUZHIAdsAEAK+H1sftLWcE3b4sil5omjIIAlPmBJLk2JuUnfBWrn0iIg==} engines: {node: '>=20.19'} @@ -461,6 +604,27 @@ packages: webpack: optional: true + '@tanstack/router-plugin@1.168.40': + resolution: {integrity: sha512-ifiXjjR4uivxwRDhgYAcfyrcu+Mwx+vlG0QjjQ7N5C5sKmzpt5UtsL21TNVvZDSZl2Vae8DcL84Z02fOs8ZZMQ==} + engines: {node: '>=20.19'} + peerDependencies: + '@rsbuild/core': '>=1.0.2 || ^2.0.0' + '@tanstack/react-router': ^1.170.38 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' + vite-plugin-solid: ^2.11.10 || ^3.0.0-0 + webpack: '>=5.92.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@tanstack/react-router': + optional: true + vite: + optional: true + vite-plugin-solid: + optional: true + webpack: + optional: true + '@tanstack/router-utils@1.162.3': resolution: {integrity: sha512-Icb0xGuG1+54IV0WMLRcc3ErTx2HeJWyPG661FkQ8UT6guoBq1FJjFRqlG/JS0xi4mFFkBhvwO7tbLa32f3yxA==} engines: {node: '>=20.19'} @@ -469,6 +633,10 @@ packages: resolution: {integrity: sha512-eyNrOJumsx68Od+//eVWgQdQAdleY9bzbJ/N9/q5x/pqHdtaSxHYqMERPAmB7XcYrMoF0Bo9LcP1TfXqvqk69g==} engines: {node: '>=22.12.0'} + '@tanstack/start-client-core@1.170.32': + resolution: {integrity: sha512-kawgeg3Ej/JvGeEN7txFdVN9kXOST9wl7yPojOGESiomwiubHKRdYUS6sBskW91j44H+HirQUppP4+Ha7kjb4A==} + engines: {node: '>=22.12.0'} + '@tanstack/start-fn-stubs@1.162.0': resolution: {integrity: sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ==} engines: {node: '>=22.12.0'} @@ -485,14 +653,34 @@ packages: vite: optional: true + '@tanstack/start-plugin-core@1.171.46': + resolution: {integrity: sha512-d/cDPZNDdRl824mOamt6USO1ja5JAaIwkuT2FIBRkBdrKZgQ8GJWv5pqpkXMbKANc49V8bUBBOTjgiCdC7YsPw==} + engines: {node: '>=22.12.0'} + peerDependencies: + '@rsbuild/core': ^2.0.0 + vite: '>=7.0.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + vite: + optional: true + '@tanstack/start-server-core@1.169.35': resolution: {integrity: sha512-xy6DB1EFznF9d7r+lqj35+Gz0alreCh8tO9+yPepANab+WZagQEDjFwHSY9vrv3lzBWbMlRrkkGG1OZWOSL48w==} engines: {node: '>=22.12.0'} + '@tanstack/start-server-core@1.169.37': + resolution: {integrity: sha512-CjYMXg2XISMEJt9UVR4lbMRsnRyWPrdyuF8iuJ4gxTc1sVNRciwMVpMPVGQG2KuIma3ewlNxw8+Tpx2tnS3zRA==} + engines: {node: '>=22.12.0'} + '@tanstack/start-storage-context@1.167.32': resolution: {integrity: sha512-Di2mLQPXy1oPFU0o9jb0oMA/XXX9sJc+FEMJo3PMiSyB6cPnbAjsR1VgvavfsCBMi7kOE+ctdK+ELDX2MwKvIA==} engines: {node: '>=22.12.0'} + '@tanstack/start-storage-context@1.167.34': + resolution: {integrity: sha512-cRPE0kjt1CnOIhepmNOvRFwCGhDAnCRohPD3HmzqJJThPkixLBRuLDvIYp4hRPtM1TJ9hiKbYl24IxAhjZO5TA==} + engines: {node: '>=22.12.0'} + '@tanstack/store@0.11.1': resolution: {integrity: sha512-mzTOBhypOuDJAy/D8n2MfUZ1HFkXnmSETviRyhqEC8LUE7/IZQExOTxMANj3KjTofYTkFNpBY67qaVrT41YccA==} @@ -533,6 +721,30 @@ packages: '@types/node@24.10.1': resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} + '@types/react-dom@19.3.0': + resolution: {integrity: sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==} + peerDependencies: + '@types/react': ^19.3.0 + + '@types/react@19.3.0': + resolution: {integrity: sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==} + + '@vitejs/plugin-react@6.1.1': + resolution: {integrity: sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + oxc-transform-react: ^0.145.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + oxc-transform-react: + optional: true + '@yuku-codegen/binding-android-arm64@0.10.2': resolution: {integrity: sha512-Oc2KInVkPfUjEB4PeV6X0NvIoyYTzDe/WmqFrTwBqKs6YKnz4A7XwWQvJTb7M0rLz9a6WgpUUiiS5QKaCi4O/g==} cpu: [arm64] @@ -697,6 +909,9 @@ packages: cookie-es@3.1.1: resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1638,6 +1853,15 @@ snapshots: react: 19.3.0 react-dom: 19.3.0(react@19.3.0) + '@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/history': 1.162.4 + '@tanstack/react-store': 0.11.1(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/router-core': 1.171.32 + isbot: 5.2.2 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + '@tanstack/react-start-client@1.168.34(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': dependencies: '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) @@ -1646,6 +1870,14 @@ snapshots: react: 19.3.0 react-dom: 19.3.0(react@19.3.0) + '@tanstack/react-start-client@1.168.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/react-router': 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/router-core': 1.171.32 + '@tanstack/start-client-core': 1.170.32 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + '@tanstack/react-start-rsc@0.1.53(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) @@ -1672,6 +1904,32 @@ snapshots: - vite-plugin-solid - webpack + '@tanstack/react-start-rsc@0.1.55(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@tanstack/react-router': 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/router-core': 1.171.32 + '@tanstack/router-utils': 1.162.3 + '@tanstack/start-client-core': 1.170.32 + '@tanstack/start-fn-stubs': 1.162.0 + '@tanstack/start-plugin-core': 1.171.46(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/start-storage-context': 1.167.34 + pathe: 2.0.3 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + transitivePeerDependencies: + - '@farmfe/core' + - '@rsbuild/core' + - bun-types-no-globals + - crossws + - esbuild + - rolldown + - rollup + - supports-color + - unloader + - vite + - vite-plugin-solid + - webpack + '@tanstack/react-start-server@1.167.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': dependencies: '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) @@ -1682,6 +1940,16 @@ snapshots: transitivePeerDependencies: - crossws + '@tanstack/react-start-server@1.167.43(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + dependencies: + '@tanstack/react-router': 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/router-core': 1.171.32 + '@tanstack/start-server-core': 1.169.37 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + transitivePeerDependencies: + - crossws + '@tanstack/react-start@1.168.54(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) @@ -1711,6 +1979,35 @@ snapshots: - vite-plugin-solid - webpack + '@tanstack/react-start@1.168.56(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@tanstack/react-router': 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/react-start-client': 1.168.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/react-start-rsc': 0.1.55(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/react-start-server': 1.167.43(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/router-utils': 1.162.3 + '@tanstack/start-client-core': 1.170.32 + '@tanstack/start-plugin-core': 1.171.46(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/start-server-core': 1.169.37 + pathe: 2.0.3 + react: 19.3.0 + react-dom: 19.3.0(react@19.3.0) + optionalDependencies: + vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - crossws + - esbuild + - react-server-dom-rspack + - rolldown + - rollup + - supports-color + - unloader + - vite-plugin-solid + - webpack + '@tanstack/react-store@0.11.1(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': dependencies: '@tanstack/store': 0.11.1 @@ -1725,6 +2022,13 @@ snapshots: seroval: 1.6.7 seroval-plugins: 1.6.7(seroval@1.6.7) + '@tanstack/router-core@1.171.32': + dependencies: + '@tanstack/history': 1.162.4 + cookie-es: 3.1.1 + seroval: 1.6.7 + seroval-plugins: 1.6.7(seroval@1.6.7) + '@tanstack/router-generator@1.167.36': dependencies: '@babel/types': 7.29.8 @@ -1738,6 +2042,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@tanstack/router-generator@1.167.38': + dependencies: + '@babel/types': 7.29.8 + '@tanstack/router-core': 1.171.32 + '@tanstack/router-utils': 1.162.3 + '@tanstack/virtual-file-routes': 1.162.0 + jiti: 2.7.0 + magic-string: 0.30.21 + prettier: 3.9.7 + zod: 4.6.5 + transitivePeerDependencies: + - supports-color + '@tanstack/router-plugin@1.168.38(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@babel/core': 7.29.7 @@ -1762,6 +2079,30 @@ snapshots: - supports-color - unloader + '@tanstack/router-plugin@1.168.40(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@babel/core': 7.29.7 + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + '@tanstack/router-core': 1.171.32 + '@tanstack/router-generator': 1.167.38 + '@tanstack/router-utils': 1.162.3 + chokidar: 5.0.0 + unplugin: 3.4.0(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + zod: 4.6.5 + optionalDependencies: + '@tanstack/react-router': 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup + - supports-color + - unloader + '@tanstack/router-utils@1.162.3': dependencies: '@babel/generator': 7.29.8 @@ -1782,6 +2123,13 @@ snapshots: '@tanstack/start-storage-context': 1.167.32 seroval: 1.6.7 + '@tanstack/start-client-core@1.170.32': + dependencies: + '@tanstack/router-core': 1.171.32 + '@tanstack/start-fn-stubs': 1.162.0 + '@tanstack/start-storage-context': 1.167.34 + seroval: 1.6.7 + '@tanstack/start-fn-stubs@1.162.0': {} '@tanstack/start-plugin-core@1.171.44(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': @@ -1823,6 +2171,45 @@ snapshots: - vite-plugin-solid - webpack + '@tanstack/start-plugin-core@1.171.46(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/core': 7.29.7 + '@babel/types': 7.29.8 + '@jridgewell/remapping': 2.3.5 + '@tanstack/router-core': 1.171.32 + '@tanstack/router-generator': 1.167.38 + '@tanstack/router-plugin': 1.168.40(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/router-utils': 1.162.3 + '@tanstack/start-server-core': 1.169.37 + exsolve: 1.1.1 + lightningcss: 1.33.0 + pathe: 2.0.3 + picomatch: 4.0.7 + seroval: 1.6.7 + source-map: 0.7.6 + srvx: 0.11.22 + tinyglobby: 0.2.17 + ufo: 1.6.4 + vitefu: 1.1.3(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + xmlbuilder2: 4.0.3 + zod: 4.6.5 + optionalDependencies: + vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - '@tanstack/react-router' + - bun-types-no-globals + - crossws + - esbuild + - rolldown + - rollup + - supports-color + - unloader + - vite-plugin-solid + - webpack + '@tanstack/start-server-core@1.169.35': dependencies: '@tanstack/history': 1.162.4 @@ -1835,10 +2222,26 @@ snapshots: transitivePeerDependencies: - crossws + '@tanstack/start-server-core@1.169.37': + dependencies: + '@tanstack/history': 1.162.4 + '@tanstack/router-core': 1.171.32 + '@tanstack/start-client-core': 1.170.32 + '@tanstack/start-storage-context': 1.167.34 + fetchdts: 0.1.7 + h3-v2: h3@2.0.1-rc.20 + seroval: 1.6.7 + transitivePeerDependencies: + - crossws + '@tanstack/start-storage-context@1.167.32': dependencies: '@tanstack/router-core': 1.171.30 + '@tanstack/start-storage-context@1.167.34': + dependencies: + '@tanstack/router-core': 1.171.32 + '@tanstack/store@0.11.1': {} '@tanstack/virtual-file-routes@1.162.0': {} @@ -1865,6 +2268,19 @@ snapshots: dependencies: undici-types: 7.16.0 + '@types/react-dom@19.3.0(@types/react@19.3.0)': + dependencies: + '@types/react': 19.3.0 + + '@types/react@19.3.0': + dependencies: + csstype: 3.2.3 + + '@vitejs/plugin-react@6.1.1(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + dependencies: + '@rolldown/pluginutils': 1.0.1 + vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + '@yuku-codegen/binding-android-arm64@0.10.2': optional: true @@ -1976,6 +2392,8 @@ snapshots: cookie-es@3.1.1: {} + csstype@3.2.3: {} + debug@4.4.3: dependencies: ms: 2.1.3 diff --git a/test/example-build.test.mjs b/test/example-build.test.mjs new file mode 100644 index 0000000..7ed7d7d --- /dev/null +++ b/test/example-build.test.mjs @@ -0,0 +1,53 @@ +import assert from "node:assert/strict"; +import { existsSync, readFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import test from "node:test"; + +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); +const hostDist = join(root, "apps", "host", "dist"); +const remoteDist = join(root, "apps", "remote", "dist"); + +function readJson(path) { + return JSON.parse(readFileSync(path, "utf8")); +} + +test("both TanStack Start apps produce client and server builds", () => { + for (const [name, dist] of [ + ["host", hostDist], + ["remote", remoteDist], + ]) { + assert.ok(existsSync(join(dist, "client", ".vite", "manifest.json")), `${name} client`); + assert.ok(existsSync(join(dist, "server", "server.js")), `${name} server`); + } +}); + +test("remote publishes browser and server federation entries", () => { + const client = join(remoteDist, "client"); + assert.ok(existsSync(join(client, "remoteEntry.js"))); + assert.ok(existsSync(join(client, "remoteEntry.ssr.js"))); + + const manifest = readJson(join(client, "mf-manifest.json")); + assert.equal(manifest.name, "tanstack_remote"); + assert.equal(manifest.metaData.remoteEntry.name, "remoteEntry.js"); + assert.equal(manifest.metaData.ssrRemoteEntry.name, "remoteEntry.ssr.js"); + + const statusCard = manifest.exposes.find(({ path }) => path === "./StatusCard"); + assert.ok(statusCard, "StatusCard expose is listed"); + assert.ok(statusCard.assets.css.sync.length > 0, "StatusCard CSS is published"); + + for (const dependency of ["react", "react-dom"]) { + const shared = manifest.shared.find(({ name }) => name === dependency); + assert.equal(shared?.singleton, true, `${dependency} is a singleton`); + } +}); + +test("host records the TanStack remote and server-side loader", () => { + const manifest = readJson(join(hostDist, "client", "mf-manifest.json")); + const remote = manifest.remotes.find(({ alias }) => alias === "tanstack_remote"); + assert.equal(remote?.moduleName, "StatusCard"); + + const serverFiles = readFileSync(join(hostDist, "server", ".vite", "manifest.json"), "utf8"); + assert.match(serverFiles, /ssrEntryLoader/); + assert.match(serverFiles, /tanstack_remote/); +}); diff --git a/test/example-runtime.test.mjs b/test/example-runtime.test.mjs new file mode 100644 index 0000000..b4f92cd --- /dev/null +++ b/test/example-runtime.test.mjs @@ -0,0 +1,99 @@ +import assert from "node:assert/strict"; +import { spawn } from "node:child_process"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import test from "node:test"; + +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); + +function startApp(name) { + const child = spawn("pnpm", ["--filter", name, "start"], { + cwd: root, + detached: true, + env: { ...process.env, NODE_ENV: "development" }, + stdio: ["ignore", "pipe", "pipe"], + }); + child.output = ""; + + for (const stream of [child.stdout, child.stderr]) { + stream.on("data", (chunk) => { + child.output = `${child.output}${chunk}`.slice(-12_000); + }); + } + + return child; +} + +async function waitForResponse(url, child, predicate = () => true) { + const deadline = Date.now() + 20_000; + let lastError; + let lastResponse; + + while (Date.now() < deadline) { + if (child.exitCode !== null || child.signalCode !== null) { + assert.fail(`server stopped while waiting for ${url}\n${child.output}`); + } + + try { + const response = await fetch(url, { signal: AbortSignal.timeout(2_000) }); + lastResponse = { body: await response.text(), status: response.status }; + if (predicate(lastResponse)) return lastResponse; + } catch (error) { + lastError = error; + } + + await new Promise((resolve) => setTimeout(resolve, 150)); + } + + assert.fail( + [ + `timed out waiting for ${url}`, + lastResponse ? `last status: ${lastResponse.status}` : undefined, + lastError ? `last error: ${lastError.message}` : undefined, + child.output, + ] + .filter(Boolean) + .join("\n"), + ); +} + +async function stopApp(child) { + if (child.exitCode !== null || child.signalCode !== null) return; + process.kill(-child.pid, "SIGTERM"); + + await Promise.race([ + new Promise((resolve) => child.once("exit", resolve)), + new Promise((resolve) => setTimeout(resolve, 3_000)), + ]); + + if (child.exitCode === null && child.signalCode === null) { + process.kill(-child.pid, "SIGKILL"); + } +} + +test("host server-renders a component from the TanStack remote", async () => { + const remote = startApp("tanstack-start-remote"); + let host; + + try { + const remoteEntry = await waitForResponse( + "http://127.0.0.1:3001/remoteEntry.js", + remote, + ({ status }) => status === 200, + ); + assert.match(remoteEntry.body, /virtual:mf-exposes/); + + host = startApp("tanstack-start-host"); + const response = await waitForResponse( + "http://127.0.0.1:3000/", + host, + ({ body, status }) => status === 200 && body.includes("Owned by the remote app"), + ); + + assert.match(response.body, /Two full-stack apps\. One React tree\./); + assert.match(response.body, /Rendered on the server/); + } finally { + if (host) await stopApp(host); + await stopApp(remote); + } +}); diff --git a/test/release-contracts.test.mjs b/test/release-contracts.test.mjs index d7739ed..9413310 100644 --- a/test/release-contracts.test.mjs +++ b/test/release-contracts.test.mjs @@ -11,6 +11,7 @@ const packageRequire = createRequire(join(packageRoot, "package.json")); const packageJson = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf8")); const rootPackageJson = JSON.parse(readFileSync(join(root, "package.json"), "utf8")); const ciWorkflow = readFileSync(join(root, ".github", "workflows", "ci.yml"), "utf8"); +const previewWorkflow = readFileSync(join(root, ".github", "workflows", "pkg-pr-new.yml"), "utf8"); const releaseWorkflow = readFileSync(join(root, ".github", "workflows", "release.yml"), "utf8"); const { tanstackStartModuleFederation } = await import(join(packageRoot, "dist", "index.mjs")); @@ -114,3 +115,8 @@ test("npm publications share one package-wide concurrency queue", () => { assert.match(releaseWorkflow, /group: publish-module-federation-tanstack/); assert.doesNotMatch(releaseWorkflow, /group:.*github\.(?:ref|run)/); }); + +test("first package preview does not require an existing npm release", () => { + assert.match(previewWorkflow, /pkg-pr-new@0\.0\.54 publish \.\/packages\/tanstack/); + assert.doesNotMatch(previewWorkflow, /--compact/); +}); diff --git a/tsconfig.json b/tsconfig.json index 8de1016..2aa37eb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,9 @@ { "$schema": "https://json.schemastore.org/tsconfig", "files": [], - "references": [{ "path": "./packages/tanstack/tsconfig.json" }] + "references": [ + { "path": "./packages/tanstack/tsconfig.json" }, + { "path": "./apps/host/tsconfig.json" }, + { "path": "./apps/remote/tsconfig.json" } + ] } diff --git a/turbo.json b/turbo.json index 882620b..5c6afdd 100644 --- a/turbo.json +++ b/turbo.json @@ -10,6 +10,10 @@ "cache": false, "persistent": true }, + "start": { + "cache": false, + "persistent": true + }, "typecheck": { "dependsOn": ["^build", "^typecheck"], "inputs": ["$TURBO_DEFAULT$", ".env*"], From 895417c527f03dd75d32c4147dccedfd80338dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9stor?= Date: Fri, 18 Sep 2026 10:34:02 +0200 Subject: [PATCH 3/5] feat: add Rsbuild adapter and interop examples --- .gitignore | 2 + README.md | 60 +- apps/README.md | 9 +- apps/host/src/remote.d.ts | 7 + apps/host/src/routes/index.tsx | 21 +- apps/host/vite.config.ts | 5 + apps/rsbuild-host/package.json | 29 + apps/rsbuild-host/rsbuild.config.ts | 24 + apps/rsbuild-host/src/assets.d.ts | 4 + .../src/components/RemoteCardSlot.tsx | 38 + apps/rsbuild-host/src/routeTree.gen.ts | 68 + apps/rsbuild-host/src/router.tsx | 16 + apps/rsbuild-host/src/routes/__root.tsx | 36 + apps/rsbuild-host/src/routes/index.tsx | 21 + apps/rsbuild-host/src/styles.css | 32 + apps/rsbuild-host/tsconfig.json | 20 + apps/rsbuild-remote/package.json | 29 + apps/rsbuild-remote/rsbuild.config.ts | 24 + apps/rsbuild-remote/src/assets.d.ts | 6 + .../src/components/StatusCard.css | 23 + .../src/components/StatusCard.tsx | 16 + apps/rsbuild-remote/src/routeTree.gen.ts | 68 + apps/rsbuild-remote/src/router.tsx | 12 + apps/rsbuild-remote/src/routes/__root.tsx | 36 + apps/rsbuild-remote/src/routes/index.tsx | 14 + apps/rsbuild-remote/src/styles.css | 22 + apps/rsbuild-remote/tsconfig.json | 20 + docs/RELEASING.md | 8 +- packages/tanstack/README.md | 50 +- packages/tanstack/package.json | 71 +- packages/tanstack/rslib.config.ts | 36 + packages/tanstack/src/index.ts | 52 +- packages/tanstack/src/rsbuild.ts | 177 ++ packages/tanstack/src/shared.ts | 31 + packages/tanstack/src/vite.ts | 21 + packages/tanstack/tsconfig.json | 1 + packages/tanstack/tsdown.config.ts | 19 - pnpm-lock.yaml | 1602 +++++++++-------- test/example-build.test.mjs | 54 +- test/example-runtime.test.mjs | 45 + test/release-artifacts.test.mjs | 54 +- test/release-contracts.test.mjs | 217 ++- tsconfig.json | 4 +- 43 files changed, 2218 insertions(+), 886 deletions(-) create mode 100644 apps/rsbuild-host/package.json create mode 100644 apps/rsbuild-host/rsbuild.config.ts create mode 100644 apps/rsbuild-host/src/assets.d.ts create mode 100644 apps/rsbuild-host/src/components/RemoteCardSlot.tsx create mode 100644 apps/rsbuild-host/src/routeTree.gen.ts create mode 100644 apps/rsbuild-host/src/router.tsx create mode 100644 apps/rsbuild-host/src/routes/__root.tsx create mode 100644 apps/rsbuild-host/src/routes/index.tsx create mode 100644 apps/rsbuild-host/src/styles.css create mode 100644 apps/rsbuild-host/tsconfig.json create mode 100644 apps/rsbuild-remote/package.json create mode 100644 apps/rsbuild-remote/rsbuild.config.ts create mode 100644 apps/rsbuild-remote/src/assets.d.ts create mode 100644 apps/rsbuild-remote/src/components/StatusCard.css create mode 100644 apps/rsbuild-remote/src/components/StatusCard.tsx create mode 100644 apps/rsbuild-remote/src/routeTree.gen.ts create mode 100644 apps/rsbuild-remote/src/router.tsx create mode 100644 apps/rsbuild-remote/src/routes/__root.tsx create mode 100644 apps/rsbuild-remote/src/routes/index.tsx create mode 100644 apps/rsbuild-remote/src/styles.css create mode 100644 apps/rsbuild-remote/tsconfig.json create mode 100644 packages/tanstack/rslib.config.ts create mode 100644 packages/tanstack/src/rsbuild.ts create mode 100644 packages/tanstack/src/shared.ts create mode 100644 packages/tanstack/src/vite.ts delete mode 100644 packages/tanstack/tsdown.config.ts diff --git a/.gitignore b/.gitignore index 09af92d..cc0b184 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ node_modules/ dist/ .turbo/ +.mf/ +@mf-types/ *.log pnpm-debug.log* coverage/ diff --git a/README.md b/README.md index 514a256..daa6e7c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # @module-federation/tanstack -Module Federation support for TanStack Start, built on the Vite integration. +Module Federation support for TanStack Start on Vite and Rsbuild. Rsbuild uses +Rspack under the hood. ## Install @@ -8,16 +9,24 @@ Module Federation support for TanStack Start, built on the Vite integration. pnpm add @module-federation/tanstack @tanstack/react-start ``` +Install the adapter for the bundler you use. They are optional peers so an +Rsbuild-only application does not install or resolve the Vite adapter, and a +Vite-only application does not install or resolve the Rsbuild adapter. + +```bash +pnpm add @module-federation/vite vite # Vite +pnpm add @module-federation/rsbuild-plugin @rsbuild/core # Rsbuild +``` + ## Configure The federation wrapper must come before `tanstackStart()` so Module Federation can normalize TanStack's client and SSR entrypoints: ```ts -import { tanstackStartModuleFederation } from "@module-federation/tanstack"; +import { tanstackStartModuleFederation } from "@module-federation/tanstack/vite"; import { tanstackStart } from "@tanstack/react-start/plugin/vite"; import react from "@vitejs/plugin-react"; -import { nitro } from "nitro/vite"; import { defineConfig } from "vite"; export default defineConfig({ @@ -34,7 +43,6 @@ export default defineConfig({ }), tanstackStart(), react(), - nitro(), ], }); ``` @@ -51,15 +59,51 @@ The package supports Node 22.18+, 24.11+, and 26+, plus Vite 7/8 and TanStack Start 1.x. Use Vite 8 when developing SSR hosts that load remotes; Vite 7 remains supported for production builds. +The package root remains a Vite compatibility export. New Vite projects can +import `/vite` explicitly. Rsbuild projects must import `/rsbuild`: + +```ts +import { defineConfig } from "@rsbuild/core"; +import { pluginReact } from "@rsbuild/plugin-react"; +import { tanstackStart } from "@tanstack/react-start/plugin/rsbuild"; +import { tanstackStartModuleFederation } from "@module-federation/tanstack/rsbuild"; + +export default defineConfig({ + plugins: [ + pluginReact(), + tanstackStart(), + ...tanstackStartModuleFederation({ + federation: { + name: "host", + remotes: { remote: "remote@https://example.test/mf-manifest.json" }, + }, + }), + ], +}); +``` + +The Rsbuild adapter registers browser and SSR federation plugins by default. It +emits script-compatible browser output and async-node CommonJS SSR output so +its manifest can be consumed by Vite and Rsbuild hosts. The wrapper adds eager, +singleton `react` and `react-dom` entries without changing the caller's config +object. Set `server: false` for browser-only remotes. + +Server federation mode emits `dist/server/index.cjs`; browser-only mode keeps +TanStack Start's standard `dist/server/index.js` entry. + ## Example -The workspace includes two TanStack Start apps. `apps/remote` exposes a -stateful React card, and `apps/host` consumes it through this package. +The workspace includes Vite and Rsbuild pairs. `apps/remote` exposes a +stateful React card to `apps/host`. `apps/rsbuild-remote` exposes a second card +to the Vite host, while `apps/rsbuild-host` consumes the Vite remote. Both +cross-bundler links use manifest URLs. They render after hydration, so this is +browser interop coverage, not an unverified SSR interoperability claim. ```bash pnpm install pnpm start ``` -Open the host at http://localhost:3000. The remote also runs as its own -TanStack Start application at http://localhost:3001. +This starts all four applications so both same-bundler and cross-bundler paths +are available. Open the Vite host at http://localhost:3000 or the Rsbuild host +at http://localhost:3003. diff --git a/apps/README.md b/apps/README.md index 113a75b..7f41b71 100644 --- a/apps/README.md +++ b/apps/README.md @@ -1,4 +1,4 @@ -# TanStack Start example +# TanStack Start examples Both sides of this example are TanStack Start applications. @@ -18,3 +18,10 @@ React and React DOM use the wrapper's singleton defaults. Each package's `start` script runs Vite's development server. In Vite's CLI, the bare `vite` command means “start”; the literal `vite start` command would treat `start` as a project directory. + +`rsbuild-remote` exposes the same kind of card through Rspack with a browser +manifest. Both hosts consume both remotes by manifest URL after hydration. +These examples exercise same-bundler and cross-bundler client interoperability; +they do not claim that cross-bundler SSR remote rendering is supported. + +`pnpm start` runs all four applications on ports 3000 through 3003. diff --git a/apps/host/src/remote.d.ts b/apps/host/src/remote.d.ts index e950d84..fe82049 100644 --- a/apps/host/src/remote.d.ts +++ b/apps/host/src/remote.d.ts @@ -4,3 +4,10 @@ declare module "tanstack_remote/StatusCard" { const StatusCard: ComponentType; export default StatusCard; } + +declare module "tanstack_rsbuild_remote/StatusCard" { + import type { ComponentType } from "react"; + + const StatusCard: ComponentType; + export default StatusCard; +} diff --git a/apps/host/src/routes/index.tsx b/apps/host/src/routes/index.tsx index bacdfcd..7a03a21 100644 --- a/apps/host/src/routes/index.tsx +++ b/apps/host/src/routes/index.tsx @@ -1,7 +1,8 @@ import { createFileRoute } from "@tanstack/react-router"; -import { lazy, Suspense } from "react"; +import { lazy, Suspense, useEffect, useState } from "react"; const RemoteStatusCard = lazy(() => import("tanstack_remote/StatusCard")); +const RsbuildStatusCard = lazy(() => import("tanstack_rsbuild_remote/StatusCard")); export const Route = createFileRoute("/")({ loader: () => import("tanstack_remote/StatusCard").then(() => null), @@ -31,7 +32,25 @@ function Home() { Loading the remote app…}> + + ); } + +function RsbuildRemoteSlot() { + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) return
Rsbuild remote loads after hydration
; + + return ( + Loading the Rsbuild remote…}> + + + ); +} diff --git a/apps/host/vite.config.ts b/apps/host/vite.config.ts index 03ecd37..6832e5a 100644 --- a/apps/host/vite.config.ts +++ b/apps/host/vite.config.ts @@ -14,6 +14,11 @@ export default defineConfig({ name: "tanstack_remote", entry: "http://127.0.0.1:3001/remoteEntry.js", }, + tanstack_rsbuild_remote: { + type: "global", + name: "tanstack_rsbuild_remote", + entry: "http://127.0.0.1:3002/mf-manifest.json", + }, }, }), tanstackStart(), diff --git a/apps/rsbuild-host/package.json b/apps/rsbuild-host/package.json new file mode 100644 index 0000000..7491972 --- /dev/null +++ b/apps/rsbuild-host/package.json @@ -0,0 +1,29 @@ +{ + "name": "tanstack-start-rsbuild-host", + "private": true, + "sideEffects": false, + "type": "module", + "scripts": { + "build": "rsbuild build", + "dev": "rsbuild dev --port 3003 --strict-port", + "start": "rsbuild dev --host 127.0.0.1 --port 3003 --strict-port", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@module-federation/runtime": "2.9.0", + "@tanstack/react-router": "1.170.38", + "@tanstack/react-start": "1.168.56", + "react": "19.3.0", + "react-dom": "19.3.0" + }, + "devDependencies": { + "@module-federation/rsbuild-plugin": "2.9.0", + "@module-federation/tanstack": "workspace:*", + "@rsbuild/core": "2.2.8", + "@rsbuild/plugin-react": "2.1.0", + "@types/node": "24.10.1", + "@types/react": "19.3.0", + "@types/react-dom": "19.3.0", + "typescript": "6.0.3" + } +} diff --git a/apps/rsbuild-host/rsbuild.config.ts b/apps/rsbuild-host/rsbuild.config.ts new file mode 100644 index 0000000..713e8b7 --- /dev/null +++ b/apps/rsbuild-host/rsbuild.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from "@rsbuild/core"; +import { pluginReact } from "@rsbuild/plugin-react"; +import { tanstackStart } from "@tanstack/react-start/plugin/rsbuild"; +import { tanstackStartModuleFederation } from "@module-federation/tanstack/rsbuild"; + +export default defineConfig({ + dev: { lazyCompilation: false }, + server: { host: "127.0.0.1", port: 3003 }, + plugins: [ + pluginReact(), + tanstackStart(), + ...tanstackStartModuleFederation({ + federation: { + dts: false, + name: "tanstack_rsbuild_host", + remotes: { + tanstack_remote: "tanstack_remote@http://127.0.0.1:3001/mf-manifest.json", + tanstack_rsbuild_remote: "tanstack_rsbuild_remote@http://127.0.0.1:3002/mf-manifest.json", + }, + }, + server: false, + }), + ], +}); diff --git a/apps/rsbuild-host/src/assets.d.ts b/apps/rsbuild-host/src/assets.d.ts new file mode 100644 index 0000000..596a189 --- /dev/null +++ b/apps/rsbuild-host/src/assets.d.ts @@ -0,0 +1,4 @@ +declare module "*.css?url" { + const href: string; + export default href; +} diff --git a/apps/rsbuild-host/src/components/RemoteCardSlot.tsx b/apps/rsbuild-host/src/components/RemoteCardSlot.tsx new file mode 100644 index 0000000..c99449f --- /dev/null +++ b/apps/rsbuild-host/src/components/RemoteCardSlot.tsx @@ -0,0 +1,38 @@ +import { loadRemote } from "@module-federation/runtime"; +import { useEffect, useState, type ComponentType } from "react"; + +type RemoteModule = { + default: ComponentType; +}; + +export function RemoteCardSlot({ fallback, remote }: { fallback: string; remote: string }) { + const [RemoteCard, setRemoteCard] = useState(null); + const [failed, setFailed] = useState(false); + + useEffect(() => { + let active = true; + setRemoteCard(null); + setFailed(false); + + loadRemote(remote) + .then((remoteModule) => { + if (!active) return; + if (remoteModule?.default) { + setRemoteCard(() => remoteModule.default); + } else { + setFailed(true); + } + }) + .catch(() => { + if (active) setFailed(true); + }); + + return () => { + active = false; + }; + }, [remote]); + + if (failed) return
Remote unavailable
; + if (!RemoteCard) return
{fallback}
; + return ; +} diff --git a/apps/rsbuild-host/src/routeTree.gen.ts b/apps/rsbuild-host/src/routeTree.gen.ts new file mode 100644 index 0000000..dceedff --- /dev/null +++ b/apps/rsbuild-host/src/routeTree.gen.ts @@ -0,0 +1,68 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as IndexRouteImport } from './routes/index' + +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: '/' + fileRoutesByTo: FileRoutesByTo + to: '/' + id: '__root__' | '/' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() + +import type { getRouter } from './router.tsx' +import type { createStart } from '@tanstack/react-start' +declare module '@tanstack/react-start' { + interface Register { + ssr: true + router: Awaited> + } +} diff --git a/apps/rsbuild-host/src/router.tsx b/apps/rsbuild-host/src/router.tsx new file mode 100644 index 0000000..6982ebb --- /dev/null +++ b/apps/rsbuild-host/src/router.tsx @@ -0,0 +1,16 @@ +import { createRouter } from "@tanstack/react-router"; +import { routeTree } from "./routeTree.gen"; + +export function getRouter() { + return createRouter({ + defaultPreload: "intent", + routeTree, + scrollRestoration: true, + }); +} + +declare module "@tanstack/react-router" { + interface Register { + router: ReturnType; + } +} diff --git a/apps/rsbuild-host/src/routes/__root.tsx b/apps/rsbuild-host/src/routes/__root.tsx new file mode 100644 index 0000000..2eb5fe8 --- /dev/null +++ b/apps/rsbuild-host/src/routes/__root.tsx @@ -0,0 +1,36 @@ +import { createRootRoute, HeadContent, Outlet, Scripts } from "@tanstack/react-router"; +import type { ReactNode } from "react"; +import stylesHref from "../styles.css?url"; + +export const Route = createRootRoute({ + head: () => ({ + links: [{ href: stylesHref, rel: "stylesheet" }], + meta: [ + { charSet: "utf-8" }, + { name: "viewport", content: "width=device-width, initial-scale=1" }, + ], + }), + component: Root, +}); + +function Root() { + return ( + + + + ); +} + +function Document({ children }: { children: ReactNode }) { + return ( + + + + + + {children} + + + + ); +} diff --git a/apps/rsbuild-host/src/routes/index.tsx b/apps/rsbuild-host/src/routes/index.tsx new file mode 100644 index 0000000..8a5c075 --- /dev/null +++ b/apps/rsbuild-host/src/routes/index.tsx @@ -0,0 +1,21 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { RemoteCardSlot } from "../components/RemoteCardSlot"; + +export const Route = createFileRoute("/")({ component: Home }); + +function Home() { + return ( +
+

Rsbuild host

+

Rspack host, two remote formats.

+

This TanStack Start app loads both remotes through the browser runtime.

+
+ + +
+
+ ); +} diff --git a/apps/rsbuild-host/src/styles.css b/apps/rsbuild-host/src/styles.css new file mode 100644 index 0000000..e379e6a --- /dev/null +++ b/apps/rsbuild-host/src/styles.css @@ -0,0 +1,32 @@ +:root { + background: #111; + color: #edf6ef; + font-family: system-ui, sans-serif; +} +body { + margin: 0; +} +.page-shell { + width: min(760px, calc(100% - 40px)); + margin: 0 auto; + padding: 80px 0; +} +.eyebrow { + color: #91f1b0; + font-family: monospace; + text-transform: uppercase; +} +h1 { + font-size: clamp(3rem, 10vw, 6rem); + margin: 12px 0; +} +.remote-loading { + border: 1px solid #4b6653; + margin-top: 36px; + padding: 30px; +} +.remote-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 20px; +} diff --git a/apps/rsbuild-host/tsconfig.json b/apps/rsbuild-host/tsconfig.json new file mode 100644 index 0000000..0416574 --- /dev/null +++ b/apps/rsbuild-host/tsconfig.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "include": ["src/**/*.ts", "src/**/*.tsx", "rsbuild.config.ts"], + "compilerOptions": { + "allowImportingTsExtensions": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["DOM", "DOM.Iterable", "ES2022"], + "module": "ESNext", + "moduleResolution": "Bundler", + "noEmit": true, + "noUncheckedIndexedAccess": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2022", + "types": ["node"], + "verbatimModuleSyntax": true + } +} diff --git a/apps/rsbuild-remote/package.json b/apps/rsbuild-remote/package.json new file mode 100644 index 0000000..82947ab --- /dev/null +++ b/apps/rsbuild-remote/package.json @@ -0,0 +1,29 @@ +{ + "name": "tanstack-start-rsbuild-remote", + "private": true, + "sideEffects": false, + "type": "module", + "scripts": { + "build": "rsbuild build", + "dev": "rsbuild dev --port 3002 --strict-port", + "start": "rsbuild dev --host 127.0.0.1 --port 3002 --strict-port", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@module-federation/runtime": "2.9.0", + "@tanstack/react-router": "1.170.38", + "@tanstack/react-start": "1.168.56", + "react": "19.3.0", + "react-dom": "19.3.0" + }, + "devDependencies": { + "@module-federation/rsbuild-plugin": "2.9.0", + "@module-federation/tanstack": "workspace:*", + "@rsbuild/core": "2.2.8", + "@rsbuild/plugin-react": "2.1.0", + "@types/node": "24.10.1", + "@types/react": "19.3.0", + "@types/react-dom": "19.3.0", + "typescript": "6.0.3" + } +} diff --git a/apps/rsbuild-remote/rsbuild.config.ts b/apps/rsbuild-remote/rsbuild.config.ts new file mode 100644 index 0000000..73bbc22 --- /dev/null +++ b/apps/rsbuild-remote/rsbuild.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from "@rsbuild/core"; +import { pluginReact } from "@rsbuild/plugin-react"; +import { tanstackStart } from "@tanstack/react-start/plugin/rsbuild"; +import { tanstackStartModuleFederation } from "@module-federation/tanstack/rsbuild"; + +export default defineConfig({ + dev: { lazyCompilation: false }, + server: { + cors: { origin: ["http://127.0.0.1:3000", "http://127.0.0.1:3003"] }, + host: "127.0.0.1", + port: 3002, + }, + plugins: [ + pluginReact(), + tanstackStart(), + ...tanstackStartModuleFederation({ + federation: { + exposes: { "./StatusCard": "./src/components/StatusCard.tsx" }, + name: "tanstack_rsbuild_remote", + }, + server: false, + }), + ], +}); diff --git a/apps/rsbuild-remote/src/assets.d.ts b/apps/rsbuild-remote/src/assets.d.ts new file mode 100644 index 0000000..18e9eca --- /dev/null +++ b/apps/rsbuild-remote/src/assets.d.ts @@ -0,0 +1,6 @@ +declare module "*.css"; + +declare module "*.css?url" { + const href: string; + export default href; +} diff --git a/apps/rsbuild-remote/src/components/StatusCard.css b/apps/rsbuild-remote/src/components/StatusCard.css new file mode 100644 index 0000000..f055223 --- /dev/null +++ b/apps/rsbuild-remote/src/components/StatusCard.css @@ -0,0 +1,23 @@ +.remote-card { + border: 1px solid #83502a; + background: #291c13; + color: #fff3e8; + padding: 30px; +} + +.remote-card .eyebrow { + color: #ffbc7c; + font-family: monospace; + text-transform: uppercase; +} + +.remote-card h2 { + font-size: 2rem; +} + +.remote-card button { + background: #ffbc7c; + border: 0; + cursor: pointer; + padding: 12px; +} diff --git a/apps/rsbuild-remote/src/components/StatusCard.tsx b/apps/rsbuild-remote/src/components/StatusCard.tsx new file mode 100644 index 0000000..20fedfb --- /dev/null +++ b/apps/rsbuild-remote/src/components/StatusCard.tsx @@ -0,0 +1,16 @@ +import { useState } from "react"; +import "./StatusCard.css"; + +export default function StatusCard() { + const [count, setCount] = useState(0); + return ( +
+

Federated from Rsbuild

+

One component, either host.

+

This card is built by Rspack and shared with the Vite host.

+ +
+ ); +} diff --git a/apps/rsbuild-remote/src/routeTree.gen.ts b/apps/rsbuild-remote/src/routeTree.gen.ts new file mode 100644 index 0000000..dceedff --- /dev/null +++ b/apps/rsbuild-remote/src/routeTree.gen.ts @@ -0,0 +1,68 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as IndexRouteImport } from './routes/index' + +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: '/' + fileRoutesByTo: FileRoutesByTo + to: '/' + id: '__root__' | '/' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() + +import type { getRouter } from './router.tsx' +import type { createStart } from '@tanstack/react-start' +declare module '@tanstack/react-start' { + interface Register { + ssr: true + router: Awaited> + } +} diff --git a/apps/rsbuild-remote/src/router.tsx b/apps/rsbuild-remote/src/router.tsx new file mode 100644 index 0000000..673839e --- /dev/null +++ b/apps/rsbuild-remote/src/router.tsx @@ -0,0 +1,12 @@ +import { createRouter } from "@tanstack/react-router"; +import { routeTree } from "./routeTree.gen"; + +export function getRouter() { + return createRouter({ defaultPreload: "intent", routeTree, scrollRestoration: true }); +} + +declare module "@tanstack/react-router" { + interface Register { + router: ReturnType; + } +} diff --git a/apps/rsbuild-remote/src/routes/__root.tsx b/apps/rsbuild-remote/src/routes/__root.tsx new file mode 100644 index 0000000..2eb5fe8 --- /dev/null +++ b/apps/rsbuild-remote/src/routes/__root.tsx @@ -0,0 +1,36 @@ +import { createRootRoute, HeadContent, Outlet, Scripts } from "@tanstack/react-router"; +import type { ReactNode } from "react"; +import stylesHref from "../styles.css?url"; + +export const Route = createRootRoute({ + head: () => ({ + links: [{ href: stylesHref, rel: "stylesheet" }], + meta: [ + { charSet: "utf-8" }, + { name: "viewport", content: "width=device-width, initial-scale=1" }, + ], + }), + component: Root, +}); + +function Root() { + return ( + + + + ); +} + +function Document({ children }: { children: ReactNode }) { + return ( + + + + + + {children} + + + + ); +} diff --git a/apps/rsbuild-remote/src/routes/index.tsx b/apps/rsbuild-remote/src/routes/index.tsx new file mode 100644 index 0000000..9cfe99e --- /dev/null +++ b/apps/rsbuild-remote/src/routes/index.tsx @@ -0,0 +1,14 @@ +import { createFileRoute } from "@tanstack/react-router"; +import StatusCard from "../components/StatusCard"; + +export const Route = createFileRoute("/")({ component: Home }); + +function Home() { + return ( +
+

Rsbuild remote

+

Rspack-built remote.

+ +
+ ); +} diff --git a/apps/rsbuild-remote/src/styles.css b/apps/rsbuild-remote/src/styles.css new file mode 100644 index 0000000..fbab7d3 --- /dev/null +++ b/apps/rsbuild-remote/src/styles.css @@ -0,0 +1,22 @@ +:root { + background: #16110d; + color: #fff3e8; + font-family: system-ui, sans-serif; +} +body { + margin: 0; +} +.page-shell { + width: min(760px, calc(100% - 40px)); + margin: 0 auto; + padding: 80px 0; +} +.eyebrow { + color: #ffbc7c; + font-family: monospace; + text-transform: uppercase; +} +h1 { + font-size: clamp(3rem, 10vw, 6rem); + margin: 12px 0 48px; +} diff --git a/apps/rsbuild-remote/tsconfig.json b/apps/rsbuild-remote/tsconfig.json new file mode 100644 index 0000000..0416574 --- /dev/null +++ b/apps/rsbuild-remote/tsconfig.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "include": ["src/**/*.ts", "src/**/*.tsx", "rsbuild.config.ts"], + "compilerOptions": { + "allowImportingTsExtensions": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "jsx": "react-jsx", + "lib": ["DOM", "DOM.Iterable", "ES2022"], + "module": "ESNext", + "moduleResolution": "Bundler", + "noEmit": true, + "noUncheckedIndexedAccess": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2022", + "types": ["node"], + "verbatimModuleSyntax": true + } +} diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 1119725..909b926 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -41,6 +41,8 @@ The publish workflow reruns the gate, checks that the source is reachable from a different dist-tag. Configure npm trusted publishing for repository `module-federation/tanstack`, workflow `release.yml`, environment `Publish`. -The release gate builds both TanStack Start examples and checks the host server -bundle plus the remote federation manifest and entries. Browser-level coverage -for SSR markup, hydration, and remote failure recovery remains follow-up work. +The release gate builds the Vite and Rsbuild example pairs. It checks the Vite +host server bundle and both directions of client manifest interoperability. The +Rsbuild example remote is browser-only; package tests cover the adapter's +async-node CommonJS SSR configuration. Browser-level coverage for hydrated +cross-bundler rendering remains follow-up work. diff --git a/packages/tanstack/README.md b/packages/tanstack/README.md index dad41f7..fee8af5 100644 --- a/packages/tanstack/README.md +++ b/packages/tanstack/README.md @@ -1,11 +1,14 @@ # @module-federation/tanstack -TanStack Start integration for Module Federation. It delegates to -`@module-federation/vite` and supplies defaults needed by TanStack's client and -SSR environments. +TanStack Start integration for Module Federation on Vite and Rsbuild. The +adapter packages are optional peers, so importing one adapter does not resolve +the other. + +The root import remains compatible with existing Vite configurations. New Vite +projects can use `/vite` explicitly: ```ts -import { tanstackStartModuleFederation } from "@module-federation/tanstack"; +import { tanstackStartModuleFederation } from "@module-federation/tanstack/vite"; import { tanstackStart } from "@tanstack/react-start/plugin/vite"; import { defineConfig } from "vite"; @@ -26,8 +29,8 @@ export default defineConfig({ }); ``` -Place the federation wrapper before `tanstackStart()`, followed by React and -Nitro plugins. Defaults: `filename: "remoteEntry.js"`, `manifest: true`, +Place the federation wrapper before `tanstackStart()`, followed by the React +plugin. Defaults: `filename: "remoteEntry.js"`, `manifest: true`, `hostInitInjectLocation: "entry"`, and singleton `react`/`react-dom` shared entries. User-provided `shared` entries override those defaults. @@ -38,4 +41,39 @@ select `web` and `node` independently. Production builds support Vite 7 and 8. Vite 8 is required for SSR remote loading during development. +For TanStack Start's Rsbuild integration, use the dedicated adapter. It adds +separate browser and SSR Module Federation plugins so Rspack emits a browser +script remote and async-node CommonJS SSR remote. For a browser-only remote, +pass `server: false`: + +```ts +import { defineConfig } from "@rsbuild/core"; +import { pluginReact } from "@rsbuild/plugin-react"; +import { tanstackStart } from "@tanstack/react-start/plugin/rsbuild"; +import { tanstackStartModuleFederation } from "@module-federation/tanstack/rsbuild"; + +export default defineConfig({ + plugins: [ + pluginReact(), + tanstackStart(), + ...tanstackStartModuleFederation({ + federation: { + name: "remote", + exposes: { "./StatusCard": "./src/StatusCard.tsx" }, + }, + }), + ], +}); +``` + +Install `@module-federation/vite` with Vite projects, or +`@module-federation/rsbuild-plugin` and `@rsbuild/core` with Rsbuild projects. +Those packages, plus `@tanstack/react-start`, are optional peers because each +adapter is loaded only by its matching subpath. + +The default Rsbuild server adapter changes TanStack Start's server output to +async-node CommonJS. Start that build with `node dist/server/index.cjs`. Passing +`server: false` keeps TanStack Start's standard `dist/server/index.js` output +for browser-only federation. + Supported Node releases are 22.18+, 24.11+, and 26+. diff --git a/packages/tanstack/package.json b/packages/tanstack/package.json index 4a637b3..660843a 100644 --- a/packages/tanstack/package.json +++ b/packages/tanstack/package.json @@ -5,14 +5,39 @@ "description": "TanStack Start integration for Module Federation", "license": "MIT", "sideEffects": false, - "main": "./dist/index.mjs", - "module": "./dist/index.mjs", - "types": "./dist/index.d.mts", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", "exports": { ".": { - "types": "./dist/index.d.mts", - "import": "./dist/index.mjs", - "default": "./dist/index.mjs" + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + }, + "./vite": { + "import": { + "types": "./dist/vite.d.ts", + "default": "./dist/vite.js" + }, + "require": { + "types": "./dist/vite.d.cts", + "default": "./dist/vite.cjs" + } + }, + "./rsbuild": { + "import": { + "types": "./dist/rsbuild.d.ts", + "default": "./dist/rsbuild.js" + }, + "require": { + "types": "./dist/rsbuild.d.cts", + "default": "./dist/rsbuild.cjs" + } }, "./package.json": "./package.json" }, @@ -45,26 +70,46 @@ "node": "^22.18.0 || ^24.11.0 || >=26.0.0" }, "scripts": { - "build": "tsdown", - "dev": "tsdown --watch --no-clean", + "build": "rslib build --lib esm && rslib build --lib cjs --no-clean", + "dev": "rslib build --watch", "pack:dry": "npm pack --dry-run", "prepack": "pnpm run build", "prepublishOnly": "pnpm run typecheck && pnpm run build", "typecheck": "tsc -p tsconfig.json --noEmit" }, - "dependencies": { - "@module-federation/vite": "1.22.0" - }, "peerDependencies": { "@tanstack/react-start": "^1.0.0", + "@module-federation/rsbuild-plugin": "^2.9.0", + "@module-federation/vite": "^1.22.0", + "@rsbuild/core": "^2.0.0", "vite": "^7.0.0 || ^8.0.0" }, + "peerDependenciesMeta": { + "@tanstack/react-start": { + "optional": true + }, + "@module-federation/rsbuild-plugin": { + "optional": true + }, + "@module-federation/vite": { + "optional": true + }, + "@rsbuild/core": { + "optional": true + }, + "vite": { + "optional": true + } + }, "devDependencies": { - "@tanstack/react-start": "1.168.54", + "@module-federation/rsbuild-plugin": "2.9.0", + "@module-federation/vite": "1.22.0", + "@rsbuild/core": "2.2.8", + "@rslib/core": "1.0.1", + "@tanstack/react-start": "1.168.56", "@types/node": "24.10.1", "react": "19.3.0", "react-dom": "19.3.0", - "tsdown": "0.23.0", "typescript": "6.0.3", "vite": "8.3.0" } diff --git a/packages/tanstack/rslib.config.ts b/packages/tanstack/rslib.config.ts new file mode 100644 index 0000000..a0cfbe7 --- /dev/null +++ b/packages/tanstack/rslib.config.ts @@ -0,0 +1,36 @@ +import { defineConfig } from "@rslib/core"; + +const entry = { + index: "./src/index.ts", + rsbuild: "./src/rsbuild.ts", + shared: "./src/shared.ts", + vite: "./src/vite.ts", +}; + +const output = { + distPath: { root: "./dist" }, + sourceMap: { js: "source-map" }, + target: "node", +} as const; + +export default defineConfig({ + lib: [ + { + bundle: false, + dts: { autoExtension: true }, + format: "esm", + output, + redirect: { dts: { extension: true } }, + source: { entry }, + syntax: "es2022", + }, + { + bundle: false, + dts: { autoExtension: true }, + format: "cjs", + output, + source: { entry }, + syntax: "es2022", + }, + ], +}); diff --git a/packages/tanstack/src/index.ts b/packages/tanstack/src/index.ts index 393d29b..24f205b 100644 --- a/packages/tanstack/src/index.ts +++ b/packages/tanstack/src/index.ts @@ -1,48 +1,4 @@ -import { federation, type ModuleFederationOptions } from "@module-federation/vite"; - -export type TanStackStartModuleFederationOptions = Omit; - -const defaultShared = { - react: { singleton: true }, - "react-dom": { singleton: true }, -} as const; - -type SharedOptions = NonNullable; -type SharedRecord = Exclude; - -function resolveShared(shared: SharedOptions | undefined): SharedRecord { - if (!Array.isArray(shared)) { - return { - ...defaultShared, - ...shared, - }; - } - - const additionalShared = Object.fromEntries( - shared - .filter((packageName) => !Object.hasOwn(defaultShared, packageName)) - .map((packageName) => [packageName, {}]), - ); - - return { - ...defaultShared, - ...additionalShared, - }; -} - -/** Creates one Module Federation plugin set for TanStack Start's client and SSR environments. */ -export function tanstackStartModuleFederation(options: TanStackStartModuleFederationOptions) { - const { - shared, - target: _environmentSpecificTarget, - ...configured - } = options as ModuleFederationOptions; - - return federation({ - ...configured, - filename: configured.filename ?? "remoteEntry.js", - manifest: configured.manifest ?? true, - hostInitInjectLocation: configured.hostInitInjectLocation ?? "entry", - shared: resolveShared(shared), - }); -} +// The root entrypoint remains Vite-compatible. Rsbuild users should import +// `@module-federation/tanstack/rsbuild` so their installation never resolves +// the Vite adapter. +export { tanstackStartModuleFederation, type TanStackStartModuleFederationOptions } from "./vite"; diff --git a/packages/tanstack/src/rsbuild.ts b/packages/tanstack/src/rsbuild.ts new file mode 100644 index 0000000..96d78f3 --- /dev/null +++ b/packages/tanstack/src/rsbuild.ts @@ -0,0 +1,177 @@ +import { + pluginModuleFederation, + type ModuleFederationOptions, +} from "@module-federation/rsbuild-plugin"; +import type { RsbuildPlugin } from "@rsbuild/core"; +import { eagerShared, resolveShared } from "./shared"; + +type ModuleFederationOverride = Partial; + +type ClientFederationOptions = ModuleFederationOverride & { + chunkLoadingGlobal?: string; + environment?: string; + forceScriptOutput?: boolean; +}; + +type ServerFederationOptions = + | false + | (ModuleFederationOverride & { + chunkFilename?: string; + entryFilename?: string; + environment?: string; + forceCommonJsOutput?: boolean; + }); + +export type TanStackStartRsbuildModuleFederationOptions = { + client?: ClientFederationOptions; + federation: ModuleFederationOptions; + server?: ServerFederationOptions; +}; + +/** Creates browser and SSR federation adapters for TanStack Start's Rsbuild integration. */ +export function tanstackStartModuleFederation({ + client = {}, + federation, + server = {}, +}: TanStackStartRsbuildModuleFederationOptions): RsbuildPlugin[] { + const { + chunkLoadingGlobal, + environment: clientEnvironment = "client", + forceScriptOutput = true, + ...clientOverrides + } = client; + const clientFederationOptions = withDefaults({ ...federation, ...clientOverrides }); + const federationName = clientFederationOptions.name; + + if (!federationName) throw new Error("federation.name is required"); + + const plugins: RsbuildPlugin[] = [ + pluginModuleFederation(clientFederationOptions, { + environment: clientEnvironment, + target: "web", + }), + clientCompatibilityPlugin({ + chunkLoadingGlobal: chunkLoadingGlobal ?? `chunk_${federationName}`, + environment: clientEnvironment, + forceScriptOutput, + name: federationName, + }), + ]; + + if (server === false) return plugins; + + const { + chunkFilename, + entryFilename, + environment: serverEnvironment = "ssr", + forceCommonJsOutput = true, + ...serverOverrides + } = server; + const serverFederationOptions = withDefaults( + { ...federation, ...serverOverrides }, + forceCommonJsOutput ? "serverRemoteEntry.cjs" : "serverRemoteEntry.js", + ); + + return [ + ...plugins, + pluginModuleFederation(serverFederationOptions, { + environment: serverEnvironment, + target: "node", + }), + serverCompatibilityPlugin({ + chunkFilename: + chunkFilename ?? (forceCommonJsOutput ? `[id].${federationName}.cjs` : undefined), + entryFilename: entryFilename ?? (forceCommonJsOutput ? "[name].cjs" : undefined), + environment: serverEnvironment, + forceCommonJsOutput, + }), + ]; +} + +export const pluginTanStackStartModuleFederation = tanstackStartModuleFederation; + +function withDefaults( + options: ModuleFederationOptions, + filename = "remoteEntry.js", +): ModuleFederationOptions { + return { + ...options, + filename: options.filename ?? filename, + manifest: options.manifest ?? true, + shared: resolveShared(options.shared, eagerShared) as ModuleFederationOptions["shared"], + }; +} + +function clientCompatibilityPlugin({ + chunkLoadingGlobal, + environment, + forceScriptOutput, + name, +}: { + chunkLoadingGlobal: string; + environment: string; + forceScriptOutput: boolean; + name: string; +}): RsbuildPlugin { + return { + name: "tanstack-start-federation-client-compat", + setup(api) { + api.onBeforeCreateCompiler(({ bundlerConfigs }) => { + for (const config of bundlerConfigs ?? []) { + if (config.name !== environment) continue; + + config.output ||= {}; + config.output.chunkFormat = "array-push"; + config.output.chunkLoading = "jsonp"; + config.output.chunkLoadingGlobal = chunkLoadingGlobal; + config.output.uniqueName ??= name; + + if (forceScriptOutput) { + config.output.module = false; + const experiments = (config.experiments ??= {}) as { outputModule?: boolean }; + experiments.outputModule = false; + } + } + }); + }, + }; +} + +function serverCompatibilityPlugin({ + chunkFilename, + entryFilename, + environment, + forceCommonJsOutput, +}: { + chunkFilename?: string; + entryFilename?: string; + environment: string; + forceCommonJsOutput: boolean; +}): RsbuildPlugin { + return { + name: "tanstack-start-federation-ssr-compat", + setup(api) { + api.onBeforeCreateCompiler(({ bundlerConfigs }) => { + for (const config of bundlerConfigs ?? []) { + if (config.name !== environment) continue; + + config.output ||= {}; + if (forceCommonJsOutput) { + config.output.filename = entryFilename ?? "[name].cjs"; + config.output.chunkFilename = + chunkFilename ?? `[id].${config.output.uniqueName ?? "server"}.cjs`; + config.target = "async-node"; + config.output.module = false; + config.output.chunkFormat = "commonjs"; + config.output.chunkLoading = "async-node"; + config.output.library = { type: "commonjs2" }; + delete config.output.chunkLoadingGlobal; + } else { + if (entryFilename) config.output.filename = entryFilename; + if (chunkFilename) config.output.chunkFilename = chunkFilename; + } + } + }); + }, + }; +} diff --git a/packages/tanstack/src/shared.ts b/packages/tanstack/src/shared.ts new file mode 100644 index 0000000..20c04ec --- /dev/null +++ b/packages/tanstack/src/shared.ts @@ -0,0 +1,31 @@ +export const defaultShared = { + react: { singleton: true }, + "react-dom": { singleton: true }, +} as const; + +export const eagerShared = { + react: { eager: true, singleton: true }, + "react-dom": { eager: true, singleton: true }, +} as const; + +export function resolveShared( + shared: unknown, + defaults: Record = defaultShared, +): Record { + if (Array.isArray(shared)) { + return { + ...defaults, + ...Object.fromEntries( + shared + .filter((packageName): packageName is string => typeof packageName === "string") + .filter((packageName) => !Object.hasOwn(defaults, packageName)) + .map((packageName) => [packageName, {}]), + ), + }; + } + + return { + ...defaults, + ...(shared && typeof shared === "object" ? shared : {}), + }; +} diff --git a/packages/tanstack/src/vite.ts b/packages/tanstack/src/vite.ts new file mode 100644 index 0000000..ca1b162 --- /dev/null +++ b/packages/tanstack/src/vite.ts @@ -0,0 +1,21 @@ +import { federation, type ModuleFederationOptions } from "@module-federation/vite"; +import { resolveShared } from "./shared"; + +export type TanStackStartModuleFederationOptions = Omit; + +/** Creates one Vite federation plugin set for TanStack Start's client and SSR environments. */ +export function tanstackStartModuleFederation(options: TanStackStartModuleFederationOptions) { + const { + shared, + target: _environmentSpecificTarget, + ...configured + } = options as ModuleFederationOptions; + + return federation({ + ...configured, + filename: configured.filename ?? "remoteEntry.js", + manifest: configured.manifest ?? true, + hostInitInjectLocation: configured.hostInitInjectLocation ?? "entry", + shared: resolveShared(shared) as ModuleFederationOptions["shared"], + }); +} diff --git a/packages/tanstack/tsconfig.json b/packages/tanstack/tsconfig.json index ae76cb7..058e070 100644 --- a/packages/tanstack/tsconfig.json +++ b/packages/tanstack/tsconfig.json @@ -9,6 +9,7 @@ "moduleResolution": "Bundler", "strict": true, "noUncheckedIndexedAccess": true, + "rootDir": "./src", "declaration": true, "declarationMap": true, "sourceMap": true, diff --git a/packages/tanstack/tsdown.config.ts b/packages/tanstack/tsdown.config.ts deleted file mode 100644 index a6d6a0b..0000000 --- a/packages/tanstack/tsdown.config.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { builtinModules } from "node:module"; -import { defineConfig } from "tsdown"; - -const external = [ - ...builtinModules, - ...builtinModules.map((name) => `node:${name}`), - "@module-federation/vite", - "@module-federation/vite/*", -]; - -export default defineConfig({ - clean: true, - deps: { neverBundle: external }, - dts: { sourcemap: true }, - entry: { index: "./src/index.ts" }, - format: ["esm"], - outDir: "dist", - sourcemap: true, -}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c8b656..38a72c0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,7 +31,7 @@ importers: version: 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) '@tanstack/react-start': specifier: 1.168.56 - version: 1.168.56(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + version: 1.168.56(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) react: specifier: 19.3.0 version: 19.3.0 @@ -71,7 +71,7 @@ importers: version: 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) '@tanstack/react-start': specifier: 1.168.56 - version: 1.168.56(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + version: 1.168.56(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) react: specifier: 19.3.0 version: 19.3.0 @@ -101,15 +101,109 @@ importers: specifier: 8.3.0 version: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) - packages/tanstack: + apps/rsbuild-host: + dependencies: + '@module-federation/runtime': + specifier: 2.9.0 + version: 2.9.0 + '@tanstack/react-router': + specifier: 1.170.38 + version: 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/react-start': + specifier: 1.168.56 + version: 1.168.56(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + react: + specifier: 19.3.0 + version: 19.3.0 + react-dom: + specifier: 19.3.0 + version: 19.3.0(react@19.3.0) + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: 2.9.0 + version: 2.9.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) + '@module-federation/tanstack': + specifier: workspace:* + version: link:../../packages/tanstack + '@rsbuild/core': + specifier: 2.2.8 + version: 2.2.8(@module-federation/runtime-tools@2.9.0) + '@rsbuild/plugin-react': + specifier: 2.1.0 + version: 2.1.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23)) + '@types/node': + specifier: 24.10.1 + version: 24.10.1 + '@types/react': + specifier: 19.3.0 + version: 19.3.0 + '@types/react-dom': + specifier: 19.3.0 + version: 19.3.0(@types/react@19.3.0) + typescript: + specifier: 6.0.3 + version: 6.0.3 + + apps/rsbuild-remote: dependencies: + '@module-federation/runtime': + specifier: 2.9.0 + version: 2.9.0 + '@tanstack/react-router': + specifier: 1.170.38 + version: 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) + '@tanstack/react-start': + specifier: 1.168.56 + version: 1.168.56(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + react: + specifier: 19.3.0 + version: 19.3.0 + react-dom: + specifier: 19.3.0 + version: 19.3.0(react@19.3.0) + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: 2.9.0 + version: 2.9.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) + '@module-federation/tanstack': + specifier: workspace:* + version: link:../../packages/tanstack + '@rsbuild/core': + specifier: 2.2.8 + version: 2.2.8(@module-federation/runtime-tools@2.9.0) + '@rsbuild/plugin-react': + specifier: 2.1.0 + version: 2.1.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23)) + '@types/node': + specifier: 24.10.1 + version: 24.10.1 + '@types/react': + specifier: 19.3.0 + version: 19.3.0 + '@types/react-dom': + specifier: 19.3.0 + version: 19.3.0(@types/react@19.3.0) + typescript: + specifier: 6.0.3 + version: 6.0.3 + + packages/tanstack: + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: 2.9.0 + version: 2.9.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) '@module-federation/vite': specifier: 1.22.0 version: 1.22.0(typescript@6.0.3)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) - devDependencies: + '@rsbuild/core': + specifier: 2.2.8 + version: 2.2.8(@module-federation/runtime-tools@2.9.0) + '@rslib/core': + specifier: 1.0.1 + version: 1.0.1(@module-federation/runtime-tools@2.9.0)(typescript@6.0.3) '@tanstack/react-start': - specifier: 1.168.54 - version: 1.168.54(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + specifier: 1.168.56 + version: 1.168.56(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) '@types/node': specifier: 24.10.1 version: 24.10.1 @@ -119,9 +213,6 @@ importers: react-dom: specifier: 19.3.0 version: 19.3.0(react@19.3.0) - tsdown: - specifier: 0.23.0 - version: 0.23.0(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -131,6 +222,64 @@ importers: packages: + '@ast-grep/napi-darwin-arm64@0.45.3': + resolution: {integrity: sha512-rMZJ6frSpR/xSbeV4hiA9WR5hHqk3rVYX8lOqEoUCaUnjEuFXvHdGN4WawJ8pVDq/IqM1UnTtsDSYgUdVmO5DA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@ast-grep/napi-darwin-x64@0.45.3': + resolution: {integrity: sha512-tIclZ5pM+YSgk8NNTBoTkaclbS39cU5lbVfSrFWX4LUnxXfUPG+F+ppxyFjKwJTBELsGHEO4LdX3/Lc+FDwPNA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@ast-grep/napi-linux-arm64-gnu@0.45.3': + resolution: {integrity: sha512-Bm8F7/oRHQkDXbjH+gBi9oB5huJ0q12r/AIOMIypf5PWlAVvh206Tsw468phw4Oh6kd4Ad1Z+gflNW1MutgK2g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@ast-grep/napi-linux-arm64-musl@0.45.3': + resolution: {integrity: sha512-yr5xcRerV41GeRxmZ8SKbfGeyZRhQePoNNCgTAb4OrWMelWwbMI80aY7/IlF2bo1sN40BSW4hZdGIO/akTd1RQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@ast-grep/napi-linux-x64-gnu@0.45.3': + resolution: {integrity: sha512-lluRK3hxfHMQdFuVID6seAKVx4FH0kEwF6rCh5/I40Sf3EtNR2UCBXAqd6RBA6hqlSckktvBxCfw+h4aescDmg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@ast-grep/napi-linux-x64-musl@0.45.3': + resolution: {integrity: sha512-09wJQKq86LqILqQtw0+X09SzhcPwUnMVFKyia7S3XLbLqSeQpAMF55Y+zll53JRQ1dCzFEZJyvTT/7j9vwfE3w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@ast-grep/napi-win32-arm64-msvc@0.45.3': + resolution: {integrity: sha512-/HiVgw2cdtzXLDLoG4eBBcauekNXewfagy7qiVbjkVu/KcCH8dJ9lpj8DzeWwuBNtZxuD8jpiwP0M1pz3Bc3uw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@ast-grep/napi-win32-ia32-msvc@0.45.3': + resolution: {integrity: sha512-/gwJrJQUw65uNtAFcG2rtSTr117Gqqy3bfjaljCPKsa65dTeRcMMnjKLlZ6V9/g8z+4Xf78kdhp5ECbir4yfSw==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@ast-grep/napi-win32-x64-msvc@0.45.3': + resolution: {integrity: sha512-CEZAMAsaDoQoVE3MT2c/ry3/ydfyaqlTjxv8DK5PG355SrdAYPgevGC2Me6tz4dhphJin89Y20VsnrS5UrYV5Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@ast-grep/napi@0.45.3': + resolution: {integrity: sha512-bjJsUt0g3UCwbn9bjv7MnoR15rszSm79yPCXn4DWWK0NuYUUqBU/srtNMR4WnpfR7TnfBRdYFoqSNx0pGCNWJg==} + engines: {node: '>= 10'} + '@babel/code-frame@7.29.7': resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} @@ -267,6 +416,15 @@ packages: resolution: {integrity: sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==} engines: {node: '>= 20.12.0'} + '@emnapi/core@1.11.3': + resolution: {integrity: sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==} + + '@emnapi/runtime@1.11.3': + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + + '@emnapi/wasi-threads@1.2.3': + resolution: {integrity: sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -295,6 +453,14 @@ packages: resolution: {integrity: sha512-6QEf6yqFbETdwGITKq57aYoPfX/3K8XFNwsAlx0C1M7o8cb79sv1M3w+tWuWvIcSbNqrLF7OD7YpZMVVz335hQ==} engines: {node: '>=20.0.0'} + '@module-federation/bridge-react-webpack-plugin@2.9.0': + resolution: {integrity: sha512-hv3fuQkGERQ/COBKTVbFV1GWovReSg/bzJzDuxWR1F84h6NYtbYMWQqX8Egvb7HKMtn9Rflzw0GeaLr8F08vDg==} + + '@module-federation/cli@2.9.0': + resolution: {integrity: sha512-r9RdlLRy3zWxuWQRonif48xdDu1reBGx18QpkZwLQ4JfSrOARjycNIGY2Y7QaUw7dedzxyee4FtKFeX/kOVLYQ==} + engines: {node: '>=16.0.0'} + hasBin: true + '@module-federation/dts-plugin@2.9.0': resolution: {integrity: sha512-uMGqEG/p9odG2BVr7WRbBe2OgrvzBd3LPzcp5WP+bm3djBdUJ4PZ3ozqKp6qpy+NFnlh6vnM815Xn6AXkKy1Vw==} peerDependencies: @@ -304,15 +470,70 @@ packages: vue-tsc: optional: true + '@module-federation/enhanced@2.9.0': + resolution: {integrity: sha512-Jd/JHoFL9fNKL4Nnzo/9hf6FD/oQo3gKpE8xt6EGuhxmrvg6wM0radPtqgHiSSWLMW7CiXr2agNjKvquKd83rw==} + hasBin: true + peerDependencies: + typescript: ^4.9.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + vue-tsc: '>=1.0.24' + webpack: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + vue-tsc: + optional: true + webpack: + optional: true + '@module-federation/error-codes@2.9.0': resolution: {integrity: sha512-IGpd+VRlji3NyGOGGTsk7YEmPRKcDoBK4YHqIuP+OQwyb2YhHCUHO2vW9RXeQxCuKwi+c6xkTweRYG+Umy+0Zw==} + '@module-federation/inject-external-runtime-core-plugin@2.9.0': + resolution: {integrity: sha512-k3wCSZsY21HjYQ61wmIJUQleOgcHgqx/sX4qXYw0XnJnzHuFo64rzMvgr+TuBIgZ1peAQtfILLlTnWyTRjtZHw==} + peerDependencies: + '@module-federation/runtime-tools': 2.9.0 + '@module-federation/managers@2.9.0': resolution: {integrity: sha512-8KhB2PF4g+M0hGaethU1H4GVWabLn5sF5TvnM6VxgAcDL4TfLY8aC/YobAXHG/SV0jpU5lsGe6s6xy6ccV0MQw==} + '@module-federation/manifest@2.9.0': + resolution: {integrity: sha512-Zhm9luVOw9XPou50eTwsvdgr208CszoQ6cGORQDCPAMhjpGb5oYFtilJ+LKW7hQ1LktD15bEZmGhC1anvgXEiQ==} + + '@module-federation/node@2.7.50': + resolution: {integrity: sha512-mbpQRdafyeWgsmYoJfdhOQf76zS6onOGpC2X1ELpWXB1Y4BcZGloL0CLjNMNon9m3ucfpc99tOGAQqFzQVkSBQ==} + peerDependencies: + webpack: ^5.40.0 + peerDependenciesMeta: + webpack: + optional: true + + '@module-federation/rsbuild-plugin@2.9.0': + resolution: {integrity: sha512-CaWAxZg+zOMw/BfgRXQdNBQZ/e5U7DBZvE13LzG13GEclt7yxaMQgKH0si3uOsq9f/X2NC8UnuhNHLIkloqlqA==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@rsbuild/core': ^1.3.21 || ^2.0.0-0 + peerDependenciesMeta: + '@rsbuild/core': + optional: true + + '@module-federation/rspack@2.9.0': + resolution: {integrity: sha512-9zSlmQYKRHKVWqhlZSMyjstp2A3VVrQV2Of8mrF5NXhngFemNx7Hw35+MTo+gsRfF5glpN8bAzLyIokRUo1Cog==} + peerDependencies: + '@rspack/core': ^0.7.0 || ^1.0.0 || ^2.0.0-0 + typescript: ^4.9.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + vue-tsc: '>=1.0.24' + peerDependenciesMeta: + typescript: + optional: true + vue-tsc: + optional: true + '@module-federation/runtime-core@2.9.0': resolution: {integrity: sha512-dLykRYfpbEJBTdk2NlbNoVVTB196O3qujawTBguLABJkPCWETJNk60NR1yZO34eI+DTH+eGwHU3m7FddAWnbnw==} + '@module-federation/runtime-tools@2.9.0': + resolution: {integrity: sha512-u2puqsaHiw1bVvLNk1uh98iPo6UzaBuci/aTvOFwKvbT/RF18C3vGGnm+ShHPKQEnoN6ctPtnygyOZDPR+8cgg==} + '@module-federation/runtime@2.9.0': resolution: {integrity: sha512-3cyAav0hWP+dNvB7qrcK9CKxQn+JvkbRvLtZz3zS2g0EyxtDFDjgbHY0Afcf7oHf8IHhKeEdzb/3Kjr1Pjmr7A==} @@ -328,6 +549,15 @@ packages: peerDependencies: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + '@module-federation/webpack-bundler-runtime@2.9.0': + resolution: {integrity: sha512-MdU6NQibT57MaJG3KPBjC30IVBrz5eU7IcjHoVDYnMh7OmASw3stagBu7hYjdMTP31luNdtzUn85s9axvdwTlw==} + + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@oozcitak/dom@2.0.2': resolution: {integrity: sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w==} engines: {node: '>=20.0'} @@ -351,9 +581,6 @@ packages: resolution: {integrity: sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==} engines: {node: '>=22.13'} - '@quansync/fs@1.1.0': - resolution: {integrity: sha512-qAPG/t3HqML1TlN7sY/pTbEjzFVAKsMjNNMGheyDosro+kT4iw2KCUoHcVdmliwWjorm4elZbgNQyU2eD97eDg==} - '@rolldown/binding-android-arm-eabi@1.2.9': resolution: {integrity: sha512-tNISae1QEf/vkb3xkRcjV5SEdzPE97We5IVaa2Z8jSszQPZ8U60B/YCYpw4QI7VidYsBtKavczXf+DyDs9WGxw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -447,17 +674,137 @@ packages: '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + '@rsbuild/core@2.2.8': + resolution: {integrity: sha512-/htjYpZiqZFB/fELguE8nkqKDT/DqHXeXUgdf+X4UlP5BJc1EeolZ9ksDpCw9WNTlcn3zsPOj7UZ0dUUB4FAFA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + core-js: '>= 3.0.0' + peerDependenciesMeta: + core-js: + optional: true + + '@rsbuild/plugin-react@2.1.0': + resolution: {integrity: sha512-RQTIAWB/CwPjoWt9iAl+8HixeQVgZ7kEIBrWPCixfITyHdiD84h0YpUTpEUuz6kGHw1KXT9mHZ3Rwy6WG7aRDA==} + peerDependencies: + '@rsbuild/core': ^2.0.0 + peerDependenciesMeta: + '@rsbuild/core': + optional: true + + '@rslib/core@1.0.1': + resolution: {integrity: sha512-FsUgiFALdgPQDM41OEYmt18J4061Vcm/fW2RXkZcwlO56PNaAEu2vtk+i8iH0lPEpCK79OaJPYjUzygOj4pPpA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7 + typescript: ^5 || ^6 || ^7 + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + typescript: + optional: true + + '@rspack/binding-darwin-arm64@2.2.6': + resolution: {integrity: sha512-y8I8MAeKAOYuLqEKYQSmNFcW4dI1u5O+xYQcjT1L3Gby02KEt0YxlmSPvzElSQJUjsJ8PkKqU3U1suDjA6xvkg==} + cpu: [arm64] + os: [darwin] + + '@rspack/binding-darwin-x64@2.2.6': + resolution: {integrity: sha512-+zhtUAP+nZON1lSlqOFJWW2VpIXRZ4/NQskYe0xohELI4Fr6xun/Oh8dIMt+Nviamvo7lbO9XURrFio1+Fziog==} + cpu: [x64] + os: [darwin] + + '@rspack/binding-linux-arm64-gnu@2.2.6': + resolution: {integrity: sha512-7GI9xlkzVMAp9dbNvynvAreMjQQNw01b+khYYfmoQOgWXTUwrtzR7/JhJ3tijVQTXkyiYAKJ0RPvz57yD+p1vQ==} + cpu: [arm64] + os: [linux] + + '@rspack/binding-linux-arm64-musl@2.2.6': + resolution: {integrity: sha512-klkjpGdeROzRiGSk2amfeZBAh0vWu0GjX5xKKQfRR4IqKQxURGCQafbvl3VX5XrHEUnKFzag89Lyv+ZVx5eTCw==} + cpu: [arm64] + os: [linux] + + '@rspack/binding-linux-ppc64-gnu@2.2.6': + resolution: {integrity: sha512-TpLZr49oU31EuEqVDczpbfLZ6c976zu8HspBuUWYj1Ra4SNeOHhINKE1i42OVw2DCEMpsz8Tv3tYyLVACGC8JA==} + cpu: [ppc64] + os: [linux] + + '@rspack/binding-linux-riscv64-gnu@2.2.6': + resolution: {integrity: sha512-gU3Ki8Lt6cE4qRM62959/28GG3XQUZsnvstgDULJpkHR5QFGYXUhOoPe2fpyWYrLw6+t9lWXBuI/gUez1zc8Sg==} + cpu: [riscv64] + os: [linux] + + '@rspack/binding-linux-riscv64-musl@2.2.6': + resolution: {integrity: sha512-OQRvU8HT9rGmtgdpieO722IrGViDlR0D6yjqbt7S51b+saBPwJ8Nf3fwMtpZnBo1djV2BGXK00L34jYypeChrw==} + cpu: [riscv64] + os: [linux] + + '@rspack/binding-linux-s390x-gnu@2.2.6': + resolution: {integrity: sha512-pus4Z76+J1iRO5Gutc6pq1LkyVhXqi0Sw6o5Dxwtl3sSbVy+F5PJkxtAT+DEg07pQy5m3dCymz2CIpiFlwYLTQ==} + cpu: [s390x] + os: [linux] + + '@rspack/binding-linux-x64-gnu@2.2.6': + resolution: {integrity: sha512-M0Efi9ny2cJ6VdhHxsZbcwdRCQ0HqBAsnPxPB8Ulknj+VtRlWnTlX/DlqMaHFuCb0MOWS6DXGGEAZ8veEil0BA==} + cpu: [x64] + os: [linux] + + '@rspack/binding-linux-x64-musl@2.2.6': + resolution: {integrity: sha512-614vRMr6VAqUXQm9TY7FCamcB08XJOv51WAwIlfEpoKTYxzNiQvrTYBYPgStUH20ywLwVoN6EJ++WCmHaebGWw==} + cpu: [x64] + os: [linux] + + '@rspack/binding-wasm32-wasi@2.2.6': + resolution: {integrity: sha512-p995VmOEcHWPKw/Eek0CYUjmXWhfyWOPoKtE51Dy0/jqHcs7uRy53igDd277yHTuKCHibmwU+cjSKUe6b/aBZg==} + cpu: [wasm32] + + '@rspack/binding-win32-arm64-msvc@2.2.6': + resolution: {integrity: sha512-xC8nHMqVzQWqVW95HOcf9qTsM445ui7QNfUTDui6oTiHcBtsyfK1CEdXsc50bdi/FrJ2ueOps3M5gxbM8Ttl/A==} + cpu: [arm64] + os: [win32] + + '@rspack/binding-win32-ia32-msvc@2.2.6': + resolution: {integrity: sha512-sfqP/LSnMwAHpTA+Cfbkhvx/IvUr23Z7S+miOkaMT/j2XJYCBrPZK0ZYm8+LUNDQ2ij8/XCJT4pVpQbtc/SMPw==} + cpu: [ia32] + os: [win32] + + '@rspack/binding-win32-x64-msvc@2.2.6': + resolution: {integrity: sha512-b1ERY5QydZWJKA13AYsoMPZycG5AGoUc3sOMqLszO0gs84aMnLbK7lBiyeZCvEcHEa7gSFQlLQr9p+Xk7HPO4Q==} + cpu: [x64] + os: [win32] + + '@rspack/binding@2.2.6': + resolution: {integrity: sha512-bCB4a7KKaQpPNlkExf27AmLJabeGjpjXlhnCdvmSIHHlT3YfpYz2CSKOLLLI/BcBez8zUBNDVmvswm3ggCCRqA==} + + '@rspack/core@2.2.6': + resolution: {integrity: sha512-sqN75Fgf6v3tCmt8GAG/rdcYHOUDv/YZbQf24YCGDoMLmdNlXCosCHkBYWI8qdLs9IqSnGt7XgbcA39Zilg6UQ==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@module-federation/runtime-tools': ^0.24.1 || ^2.0.0 + '@swc/helpers': ^0.5.23 + peerDependenciesMeta: + '@module-federation/runtime-tools': + optional: true + '@swc/helpers': + optional: true + + '@rspack/plugin-react-refresh@2.0.2': + resolution: {integrity: sha512-dGNZiCxQxgAUI9sah7gd8u+O7OJZRCmqtEJNDOd8xW5RqcieC86F7p5qcShyw6onH5pKf57evpr2VjGbaFGkZg==} + peerDependencies: + '@rspack/core': ^2.0.0 + react-refresh: '>=0.10.0 <1.0.0' + peerDependenciesMeta: + '@rspack/core': + optional: true + + '@swc/helpers@0.5.23': + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} + '@tanstack/history@1.162.4': resolution: {integrity: sha512-utTS5L2OkeYUzXGohL1Z8sefu1GLNOJcxe8Hd6iIdc/Xo1K1nDB2JEp4iSFhvYh33xKC9V91TxrS8qfrpoKobQ==} engines: {node: '>=20.19'} - '@tanstack/react-router@1.170.36': - resolution: {integrity: sha512-AbgcI/xO8AJY1r6y5tF7TZyHH0VKm0XcfY3QVIVCrHq8k04Hkj1N4nfLL+1xCGC3VnMI3AYGAVWkatnqE2dxAQ==} - engines: {node: '>=20.19'} - peerDependencies: - react: '>=18.0.0 || >=19.0.0' - react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-router@1.170.38': resolution: {integrity: sha512-iHM9b0aDJbuvftmkiQXawzoqsdV68p2Re2safbVLCnxafe+iLKV++2i3hI/BMAP6uR92/Mjw94JKJJfD7pbwHQ==} engines: {node: '>=20.19'} @@ -465,13 +812,6 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start-client@1.168.34': - resolution: {integrity: sha512-rNwogcDo5A9xeKmGHIocI50nlqtlEr5lcgbcdW9gCtDEloXALdwFtXriEj3kHZe7BLvn9FItZESZcC3xo4/71w==} - engines: {node: '>=22.12.0'} - peerDependencies: - react: '>=18.0.0 || >=19.0.0' - react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start-client@1.168.36': resolution: {integrity: sha512-TRXZKag/Ng0TqVfcN4cbEDVJhEZYosHZ9/VAEhK3PK/YqznytK+bcoonE4jP5NCXMdH2YRTMsrWKrApEuWz0Cg==} engines: {node: '>=22.12.0'} @@ -479,23 +819,6 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start-rsc@0.1.53': - resolution: {integrity: sha512-Hzwpd74HyvTFU4rEY9PpbUaYJ7BA3deCg0p+Dyj3NTFsTnULD+/Eba87u1QPl5UEVsKWyIG9J7g4J6JZpxFWSg==} - engines: {node: '>=22.12.0'} - peerDependencies: - '@rspack/core': '>=2.0.0-0' - '@vitejs/plugin-rsc': '>=0.5.30' - react: '>=18.0.0 || >=19.0.0' - react-dom: '>=18.0.0 || >=19.0.0' - react-server-dom-rspack: '>=0.0.2' - peerDependenciesMeta: - '@rspack/core': - optional: true - '@vitejs/plugin-rsc': - optional: true - react-server-dom-rspack: - optional: true - '@tanstack/react-start-rsc@0.1.55': resolution: {integrity: sha512-qfW89LMrewtMLHMCumMP3+3mf2gPezFE7FZ7CHPJis4paxt2A6Jl7eCpE6whYgc5DFiifUv9qdfbC22HIP0HAw==} engines: {node: '>=22.12.0'} @@ -513,13 +836,6 @@ packages: react-server-dom-rspack: optional: true - '@tanstack/react-start-server@1.167.41': - resolution: {integrity: sha512-ng4M05+vPug8rJH4OzF6u45JRSn+MThpjGCzkXmBgW3w/6TRkzWHQMO5/tBzpERJhUHp+uk178ZfFJVw0SWYpA==} - engines: {node: '>=22.12.0'} - peerDependencies: - react: '>=18.0.0 || >=19.0.0' - react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start-server@1.167.43': resolution: {integrity: sha512-/Fc1mOEBAyXmqxnihIkS1DrCcJX8ffrJ+xyc8nnFmO9YuCdrnZJskd48R1ZiOhM7u3vCPzDxUycIhKo8HlKn2g==} engines: {node: '>=22.12.0'} @@ -527,23 +843,6 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' - '@tanstack/react-start@1.168.54': - resolution: {integrity: sha512-x0GWvFm1e4WtgETxDE0xVWa39HdEnoinKQ9SU8pvO187SDsSpudYuhr8StfWdLE5iRhziGchLqlPl6UccUZ46w==} - engines: {node: '>=22.12.0'} - peerDependencies: - '@rsbuild/core': ^2.0.0 - '@vitejs/plugin-rsc': '*' - react: '>=18.0.0 || >=19.0.0' - react-dom: '>=18.0.0 || >=19.0.0' - vite: '>=7.0.0' - peerDependenciesMeta: - '@rsbuild/core': - optional: true - '@vitejs/plugin-rsc': - optional: true - vite: - optional: true - '@tanstack/react-start@1.168.56': resolution: {integrity: sha512-b/jVJS+yt7J0IKwXfVoA2mlhIi92sWfwCYrCVked0WERzgbYAad6xrOwNTljz9OKyeajofGrmMdKJgRzK1Lt2w==} engines: {node: '>=22.12.0'} @@ -567,43 +866,14 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/router-core@1.171.30': - resolution: {integrity: sha512-wtS1yCAb/k5CJBauvrCyqf2n4/kRc3aiz81tFBJ1QXH4Utsu81xFTMq15AdmNWgWmt2UstUSMfWi4Ua7ph2F+w==} - engines: {node: '>=20.19'} - '@tanstack/router-core@1.171.32': resolution: {integrity: sha512-X86Jqk3vB2KJcUfS6oLi7B7yxbaa59QEhZRPPP1fRx3k+Jw/Fu1UYVBcRtdwK/OccQnrlQdVoKvNO3QXmyEBOw==} engines: {node: '>=20.19'} - '@tanstack/router-generator@1.167.36': - resolution: {integrity: sha512-9Sjm1j8fkurviVIcbAXVdoyqAT8tlurY1tD9Na9Y59/BW5uWT5/5U+eU4Nv/d5grBKyosiJCP7/pcADvstnEgg==} - engines: {node: '>=20.19'} - '@tanstack/router-generator@1.167.38': resolution: {integrity: sha512-lkqgFleDgfkW+QONVMKBs+ZGDUF0v9R9FkplS/GZvKDFpfnu+tZxmGlV2pryU1TDxyuSyjh56AtIla3NMrlScw==} engines: {node: '>=20.19'} - '@tanstack/router-plugin@1.168.38': - resolution: {integrity: sha512-0SWwASONOiy7biNBvzdmfhKWwhxa+oJUZHIAdsAEAK+H1sftLWcE3b4sil5omjIIAlPmBJLk2JuUnfBWrn0iIg==} - engines: {node: '>=20.19'} - peerDependencies: - '@rsbuild/core': '>=1.0.2 || ^2.0.0' - '@tanstack/react-router': ^1.170.36 - vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' - vite-plugin-solid: ^2.11.10 || ^3.0.0-0 - webpack: '>=5.92.0' - peerDependenciesMeta: - '@rsbuild/core': - optional: true - '@tanstack/react-router': - optional: true - vite: - optional: true - vite-plugin-solid: - optional: true - webpack: - optional: true - '@tanstack/router-plugin@1.168.40': resolution: {integrity: sha512-ifiXjjR4uivxwRDhgYAcfyrcu+Mwx+vlG0QjjQ7N5C5sKmzpt5UtsL21TNVvZDSZl2Vae8DcL84Z02fOs8ZZMQ==} engines: {node: '>=20.19'} @@ -629,10 +899,6 @@ packages: resolution: {integrity: sha512-Icb0xGuG1+54IV0WMLRcc3ErTx2HeJWyPG661FkQ8UT6guoBq1FJjFRqlG/JS0xi4mFFkBhvwO7tbLa32f3yxA==} engines: {node: '>=20.19'} - '@tanstack/start-client-core@1.170.30': - resolution: {integrity: sha512-eyNrOJumsx68Od+//eVWgQdQAdleY9bzbJ/N9/q5x/pqHdtaSxHYqMERPAmB7XcYrMoF0Bo9LcP1TfXqvqk69g==} - engines: {node: '>=22.12.0'} - '@tanstack/start-client-core@1.170.32': resolution: {integrity: sha512-kawgeg3Ej/JvGeEN7txFdVN9kXOST9wl7yPojOGESiomwiubHKRdYUS6sBskW91j44H+HirQUppP4+Ha7kjb4A==} engines: {node: '>=22.12.0'} @@ -641,18 +907,6 @@ packages: resolution: {integrity: sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ==} engines: {node: '>=22.12.0'} - '@tanstack/start-plugin-core@1.171.44': - resolution: {integrity: sha512-xSUlXNpA/k1cNHoIcPFqBw8kehQelUn7qN8dCVMvNEjSRA63jWbFVZNrkMXAKsY0sTMM+i4qoOmCleKT1ha7nA==} - engines: {node: '>=22.12.0'} - peerDependencies: - '@rsbuild/core': ^2.0.0 - vite: '>=7.0.0' - peerDependenciesMeta: - '@rsbuild/core': - optional: true - vite: - optional: true - '@tanstack/start-plugin-core@1.171.46': resolution: {integrity: sha512-d/cDPZNDdRl824mOamt6USO1ja5JAaIwkuT2FIBRkBdrKZgQ8GJWv5pqpkXMbKANc49V8bUBBOTjgiCdC7YsPw==} engines: {node: '>=22.12.0'} @@ -665,18 +919,10 @@ packages: vite: optional: true - '@tanstack/start-server-core@1.169.35': - resolution: {integrity: sha512-xy6DB1EFznF9d7r+lqj35+Gz0alreCh8tO9+yPepANab+WZagQEDjFwHSY9vrv3lzBWbMlRrkkGG1OZWOSL48w==} - engines: {node: '>=22.12.0'} - '@tanstack/start-server-core@1.169.37': resolution: {integrity: sha512-CjYMXg2XISMEJt9UVR4lbMRsnRyWPrdyuF8iuJ4gxTc1sVNRciwMVpMPVGQG2KuIma3ewlNxw8+Tpx2tnS3zRA==} engines: {node: '>=22.12.0'} - '@tanstack/start-storage-context@1.167.32': - resolution: {integrity: sha512-Di2mLQPXy1oPFU0o9jb0oMA/XXX9sJc+FEMJo3PMiSyB6cPnbAjsR1VgvavfsCBMi7kOE+ctdK+ELDX2MwKvIA==} - engines: {node: '>=22.12.0'} - '@tanstack/start-storage-context@1.167.34': resolution: {integrity: sha512-cRPE0kjt1CnOIhepmNOvRFwCGhDAnCRohPD3HmzqJJThPkixLBRuLDvIYp4hRPtM1TJ9hiKbYl24IxAhjZO5TA==} engines: {node: '>=22.12.0'} @@ -718,160 +964,54 @@ packages: cpu: [arm64] os: [win32] - '@types/node@24.10.1': - resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} - - '@types/react-dom@19.3.0': - resolution: {integrity: sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==} - peerDependencies: - '@types/react': ^19.3.0 - - '@types/react@19.3.0': - resolution: {integrity: sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==} - - '@vitejs/plugin-react@6.1.1': - resolution: {integrity: sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 - babel-plugin-react-compiler: ^1.0.0 - oxc-transform-react: ^0.145.0 - vite: ^8.0.0 - peerDependenciesMeta: - '@rolldown/plugin-babel': - optional: true - babel-plugin-react-compiler: - optional: true - oxc-transform-react: - optional: true - - '@yuku-codegen/binding-android-arm64@0.10.2': - resolution: {integrity: sha512-Oc2KInVkPfUjEB4PeV6X0NvIoyYTzDe/WmqFrTwBqKs6YKnz4A7XwWQvJTb7M0rLz9a6WgpUUiiS5QKaCi4O/g==} - cpu: [arm64] - os: [android] - - '@yuku-codegen/binding-darwin-arm64@0.10.2': - resolution: {integrity: sha512-3H7eNPIHJndUJXZ4QUGBPq1zC6RGcUZfm7bymJes+/N7wTVWUn1bxZ9JcozYHpkWQNm9f23G8YWbaHD9aYH72A==} - cpu: [arm64] - os: [darwin] - - '@yuku-codegen/binding-darwin-x64@0.10.2': - resolution: {integrity: sha512-AJOUpR2s3LF9AWiiub/Uyc/UoXNTWcq8hK3cVI6fUSXtwh34dG21J6hRuNlO6JVJFTo4o3ScVvZOrh/YFfUEAA==} - cpu: [x64] - os: [darwin] - - '@yuku-codegen/binding-freebsd-x64@0.10.2': - resolution: {integrity: sha512-ms7DcZu87u5CiK/wMwvpKAvAmtaqKjCQIXNweMLypG6qbuiaOMQf1jpbB5+j46xBcgCovo8TQMcv0bCQLKIL9w==} - cpu: [x64] - os: [freebsd] - - '@yuku-codegen/binding-linux-arm-gnu@0.10.2': - resolution: {integrity: sha512-xJDpYAsKV5+eaiBhTYl05fvT6sst4PsCeuIFMRu9b0/WCSrNQPfCDtAQ5/MS6xNpsdujdZEPR+gmfWk3ZG5i3A==} - cpu: [arm] - os: [linux] - - '@yuku-codegen/binding-linux-arm-musl@0.10.2': - resolution: {integrity: sha512-qfTkgd7AEx61l4K9VtXWCGTxc/fmXJ4ZheDz3i+/AAJUtg4sa0bPrc0VBxPggB/rayR8Z3+JfrBItuyanBJJ9Q==} - cpu: [arm] - os: [linux] - - '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': - resolution: {integrity: sha512-4e6Mifm/4UdjtU3D8mATIrvgP+xEiH8xtQOjd0zpd72XKWT7ug3sdyhq2utkkZFP6BvYp7SgZrI+aR4VeIOHdw==} - cpu: [arm64] - os: [linux] - - '@yuku-codegen/binding-linux-arm64-musl@0.10.2': - resolution: {integrity: sha512-RdsJrUfDYFVV3JOmWFUWwSu31fa1APn12xDeIKxgl/YWxrabwtxsDBNjF2561c7tmcbiewdCUvngqRs8AyGVLA==} - cpu: [arm64] - os: [linux] - - '@yuku-codegen/binding-linux-x64-gnu@0.10.2': - resolution: {integrity: sha512-mVzWimEPPreaPyXIUvxsHoJzvO7ckZ5j0LgQFHz04zQIRwt9A9T2hA7K5/jYjJKkMxWG/U2VjhGNwVhtyU+uqg==} - cpu: [x64] - os: [linux] - - '@yuku-codegen/binding-linux-x64-musl@0.10.2': - resolution: {integrity: sha512-Y77fyISurmr2mvO1yeq3u+x/WJbACgPR4w+lzEVx30ViCxZzIGrZPRN1yEdZ9xUNPNsIO5thBHIdRNG+UGUG+Q==} - cpu: [x64] - os: [linux] - - '@yuku-codegen/binding-win32-arm64@0.10.2': - resolution: {integrity: sha512-1+tGLyG0u5YYy0lev4ck7/0sd8xJ9SZde0dLut7qLDPZV5WVTV8x6OxNXUne/PGuHZyO1vK+txPQzzHOyXHGSw==} - cpu: [arm64] - os: [win32] - - '@yuku-codegen/binding-win32-x64@0.10.2': - resolution: {integrity: sha512-8a2SExRohRbwC0MY4VpOF0/RSckrJ2ASZqAor5/RYSJJaeadR93n10gZzcKT6pY9ukiSOIZCRKVRD2tH73T0qA==} - cpu: [x64] - os: [win32] - - '@yuku-parser/binding-android-arm64@0.10.2': - resolution: {integrity: sha512-2VPBU9fRGRAQ2xPAvghnec3oou5Nrxm2Bezhf+13UMspAxQSkF/32r+ySKXSwIPA5/RivumDJDxAxc301Sgicw==} - cpu: [arm64] - os: [android] - - '@yuku-parser/binding-darwin-arm64@0.10.2': - resolution: {integrity: sha512-LD+PMZE51tCYTOss5HBkm3/AE39MvcMDBfWJx7A4yDcjfNbAQDnHZKtzSOuqrswx+TQHY0ws5xn6+fWOwtmfBA==} - cpu: [arm64] - os: [darwin] + '@tybys/wasm-util@0.10.4': + resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==} - '@yuku-parser/binding-darwin-x64@0.10.2': - resolution: {integrity: sha512-mmZ8cND+AoIIMRERyMinlg5ApHxP23B9jH2B5wT7T+dliPa9rubLxneB/SUjFwyUjGaFnB5G7t4YvpfbO5zbkQ==} - cpu: [x64] - os: [darwin] + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@yuku-parser/binding-freebsd-x64@0.10.2': - resolution: {integrity: sha512-gVIjaaIddbRfAhHlC8N809wQWml7mxfSVnzaLtzGXObTeFTPAg/YVnQXt1UOhPM1ah5eG/8Y0RUlNpB4GVe7eQ==} - cpu: [x64] - os: [freebsd] - - '@yuku-parser/binding-linux-arm-gnu@0.10.2': - resolution: {integrity: sha512-q/XPPQQAPdlw05aPj30ygBhekmQryGOwxVraBgApjKK8yY1kNQgqq6XCYLF1WHSee+lhxclrTO7W0/bt7dR1GA==} - cpu: [arm] - os: [linux] - - '@yuku-parser/binding-linux-arm-musl@0.10.2': - resolution: {integrity: sha512-A+Cb0I1hFF4wilTQpWs79k1aNnj4B2tkrHx3zsuUNF9BtVY2zPZ4yeQEM/zjXrS/qJlNMZVK9NrWJjwdpnTrfg==} - cpu: [arm] - os: [linux] - - '@yuku-parser/binding-linux-arm64-gnu@0.10.2': - resolution: {integrity: sha512-aGNSzqIqqphFwAdIFwVvKIyXD1Iy3CxrEJVIZAT87Ecyi4vCmmDD2v2l9h+Gd3/wSy3JZlOI792LJbKAjyy9rQ==} - cpu: [arm64] - os: [linux] - - '@yuku-parser/binding-linux-arm64-musl@0.10.2': - resolution: {integrity: sha512-Ddl1sF0rtuCXyHGSOV6dcmdx+ETv1iD+IVFqQuOjzkJZWclxJxdBWX6ZJMRtTiGqGUTbqLEKiTXxpR/Bvqk+2A==} - cpu: [arm64] - os: [linux] - - '@yuku-parser/binding-linux-x64-gnu@0.10.2': - resolution: {integrity: sha512-/nlcpR6IF5U+0m5L9wvAIXeQa2DT+BXuvqKDsTcOTlcc0B4dHNyqE5hTXsS4hAyimpy2ZK8A1zMNF5hTrjg2cg==} - cpu: [x64] - os: [linux] - - '@yuku-parser/binding-linux-x64-musl@0.10.2': - resolution: {integrity: sha512-GX80dxTQD/M/OryyuxJcFzFENzry3cDFPvCFTyWogNWQH3fSHfMrNfpwpl1YzMos1eV9NygK5GSDG7VArQlb4w==} - cpu: [x64] - os: [linux] - - '@yuku-parser/binding-win32-arm64@0.10.2': - resolution: {integrity: sha512-agePQBV4VHewiGU0ACSjscZ/hJd283f9JfAF19Gf1rI5+wy5tTgx4GS36i0b3xim15AQ4RCpDRosEvhLZ4zAOw==} - cpu: [arm64] - os: [win32] + '@types/node@24.10.1': + resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} - '@yuku-parser/binding-win32-x64@0.10.2': - resolution: {integrity: sha512-s8//CMpgL5+y1lvDCdyh1rwGI5+ytDJywFJRe1vnhI7n0j+caxshNucurikYLLVeQ2SYFex6aPrzgQxkabBQRA==} - cpu: [x64] - os: [win32] + '@types/react-dom@19.3.0': + resolution: {integrity: sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==} + peerDependencies: + '@types/react': ^19.3.0 + + '@types/react@19.3.0': + resolution: {integrity: sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==} - '@yuku-toolchain/types@0.10.2': - resolution: {integrity: sha512-sSeo4SSSToiS+sSD+bwn/s94EEcaLJ7tG5LCp8gFYC1G5VzxzX7fqB6m9RU1yMD8KTpu6zdU/I1NlQf8hVBJ9Q==} + '@vitejs/plugin-react@6.1.1': + resolution: {integrity: sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + oxc-transform-react: ^0.145.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + oxc-transform-react: + optional: true adm-zip@0.6.0: resolution: {integrity: sha512-XleryMhbuksdKtofnWZ9Sk+4CUTbms4Mb/EU32SZwToAyZ5RgVos/ki8n+yr0LWHOGKuakbXTuuYNHLQjhddgg==} engines: {node: '>=14.0'} + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + ansis@4.4.0: resolution: {integrity: sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA==} engines: {node: '>=14'} @@ -903,6 +1043,10 @@ packages: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -921,9 +1065,6 @@ packages: supports-color: optional: true - defu@6.1.7: - resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} - detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -932,21 +1073,11 @@ packages: resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} engines: {node: '>=0.3.1'} - dts-resolver@3.0.0: - resolution: {integrity: sha512-1T1f+z+4tl9XD+m+0HBgWoL/nm0bOIffyWaUuUSBlFg/86IWvfx+wjNaO/ybU0AJzG9/Mi5hBUgGV6zCmWEN7Q==} - engines: {node: ^22.18.0 || >=24.0.0} - peerDependencies: - oxc-resolver: '>=11.0.0' - peerDependenciesMeta: - oxc-resolver: - optional: true - electron-to-chromium@1.5.430: resolution: {integrity: sha512-e1QEj72Y4zd8RlNZVmoTg+iCOSVwpk05IOiiQwdrkwCSVlZfPthevErhE+nckGd2YbsXfp1SkisznhGVIXP2NQ==} - empathic@2.0.1: - resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} - engines: {node: '>=14'} + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} @@ -955,12 +1086,18 @@ packages: exsolve@1.1.1: resolution: {integrity: sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-string-truncated-width@3.0.3: resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + fast-uri@3.1.8: + resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} + fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -985,10 +1122,6 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - get-tsconfig@5.0.0-beta.6: - resolution: {integrity: sha512-X6fBC0pmImC70gvX2zm56go9hx0MyoGVdG0tUCkg/D+Xnh5TJsOZ7iDbOdI3PvmtrDxnu1YdDufpK2QJX1Meqw==} - engines: {node: '>=20.20.0'} - h3@2.0.1-rc.20: resolution: {integrity: sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==} engines: {node: '>=20.11.1'} @@ -999,20 +1132,17 @@ packages: crossws: optional: true - hookable@6.1.1: - resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} - human-id@4.2.1: resolution: {integrity: sha512-zPGsiS+dWoTZtZ4AtpA9Y+BdSFSNWvnouNlWNoUFyAM6xHOHmdCvqO3k8AIbdamCOv4gUFUVNPf6rJFfc4UiJw==} hasBin: true + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + import-meta-resolve@4.2.0: resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} - import-without-cache@0.4.1: - resolution: {integrity: sha512-vXoV9PjKHEednCUu01e98TkImxy67e3BJXbTIOmIq4Hyzw3IAwYRcuPkfeTzJzwyyts4kjuA73x+pWJLc4f86A==} - engines: {node: ^22.18.0 || >=24.0.0} - isbot@5.2.2: resolution: {integrity: sha512-iQcBXcd+Rv/pkubRyGh2utW2j1oPG5hZY6TUhVPpqK4G+o3IbxpJNx04hgksjc/N7GK5pEorUxDeg31cFgEk/w==} engines: {node: '>=18'} @@ -1022,6 +1152,10 @@ packages: peerDependencies: ws: '*' + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true @@ -1041,6 +1175,9 @@ packages: engines: {node: '>=6'} hasBin: true + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -1136,18 +1273,19 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-releases@2.0.55: resolution: {integrity: sha512-mIrE/Cw9y+9Au6dS5vDKDhQza9YvG6w+ZrS6X+ZzA7yFW/soAeaups4Qzn1bL6g5FVy8WtP79+0j82oPIbqRjQ==} engines: {node: '>=18'} - obug@2.2.1: - resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} - engines: {node: '>=12.20.0'} - - obug@3.0.0: - resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} - engines: {node: '>=12.20.0'} - package-manager-detector@1.8.0: resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} @@ -1170,14 +1308,15 @@ packages: engines: {node: '>=14'} hasBin: true - quansync@1.0.0: - resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} - react-dom@19.3.0: resolution: {integrity: sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==} peerDependencies: react: ^19.3.0 + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + react@19.3.0: resolution: {integrity: sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==} engines: {node: '>=0.10.0'} @@ -1186,30 +1325,9 @@ packages: resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} engines: {node: '>= 20.19.0'} - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - rolldown-plugin-dts@0.28.6: - resolution: {integrity: sha512-qKrFtBfRfR2hP233m7Ic9zf3wv6MSYdZghWKMdEO6dRYZGlNfINJAa1P5ZVvyHh3mrcd7IJQvIY8L9vnm+v5rQ==} - engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} - peerDependencies: - '@typescript/native-preview': '*' - '@volar/typescript': ~2.4.0 - '@vue/language-core': ~3.2.0 || ~3.3.0 - rolldown: ^1.2.0 - typescript: ^5.0.0 || ^6.0.0 || ~7.0.0 - vue-tsc: ~3.2.0 || ~3.3.0 - peerDependenciesMeta: - '@typescript/native-preview': - optional: true - '@volar/typescript': - optional: true - '@vue/language-core': - optional: true - typescript: - optional: true - vue-tsc: - optional: true + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} rolldown@1.2.9: resolution: {integrity: sha512-hx/Pv0N1haXRb11qkfnK5MXB/iqr7i0yjWQqmO9uHqZpBgQSqzc8UsSnEpalsh+j1I8qQ2CkXAkJC8Br3dKSlg==} @@ -1219,9 +1337,29 @@ packages: rou3@0.8.1: resolution: {integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==} + rsbuild-plugin-dts@1.0.1: + resolution: {integrity: sha512-vzLhs8v1SuRd0qyIWue5caaM2A1lGImuH+cQAX71KnNpS9BZHyHRBHHXBFp9jp610XJnLlkBATyPclqUfGtCAA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@microsoft/api-extractor': ^7 + '@rsbuild/core': ^2.0.0 + typescript: ^5 || ^6 || ^7 + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + typescript: + optional: true + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + scheduler@0.28.0: resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==} + schema-utils@4.3.0: + resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} + engines: {node: '>= 10.13.0'} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -1261,6 +1399,10 @@ packages: engines: {node: '>=20.16.0'} hasBin: true + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + tinyexec@1.3.1: resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==} engines: {node: '>=18'} @@ -1269,43 +1411,11 @@ packages: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tsdown@0.23.0: - resolution: {integrity: sha512-BaT+ep1xnj5hdyICLd5r5SYYE+TXnI1ATePLykv9vcKpHpFTWUWRH+x1AF/E2qcu3YB6+vI8IdyxIIIffEqw5Q==} - engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} - hasBin: true - peerDependencies: - '@arethetypeswrong/core': ^0.18.1 - '@tsdown/css': 0.23.0 - '@tsdown/exe': 0.23.0 - '@vitejs/devtools': '*' - publint: ^0.3.8 - tsx: '*' - typescript: ^5.0.0 || ^6.0.0 || ^7.0.0 - unplugin-unused: '>=0.5.0' - unrun: '*' - peerDependenciesMeta: - '@arethetypeswrong/core': - optional: true - '@tsdown/css': - optional: true - '@tsdown/exe': - optional: true - '@vitejs/devtools': - optional: true - publint: - optional: true - tsx: - optional: true - typescript: - optional: true - unplugin-unused: - optional: true - unrun: - optional: true + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} turbo@2.10.13: resolution: {integrity: sha512-69MkPbjk+G8oyC7pC2DeBk0rPdbLz51wuH5eAT0Q4BVJkzq/b1XM4kUUidsARbmDjwIELSJwd1ezITULY9kWNw==} @@ -1319,9 +1429,6 @@ packages: ufo@1.6.4: resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} - unconfig-core@7.5.0: - resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} - undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} @@ -1376,10 +1483,6 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - verkit@0.4.0: - resolution: {integrity: sha512-sXMwN6DMHeouPfCxkxWkKAmxphWKEenHYY5H1nIBzU3PmDsmJp6kBXJdshjVdpMZuWCmL9SH7KFRx29AylpP6g==} - engines: {node: '>=18.12.0'} - vite@8.3.0: resolution: {integrity: sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1431,9 +1534,15 @@ packages: vite: optional: true + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + ws@8.21.0: resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} engines: {node: '>=10.0.0'} @@ -1458,20 +1567,50 @@ packages: engines: {node: '>= 14.6'} hasBin: true - yuku-ast@0.10.2: - resolution: {integrity: sha512-UnG9mA6giglCvSErft2/40TVFX750Sj1xgwddPLpG7J7rlr/P1wPADg9G2RK+d/1tNLtRVoLdMMOMVBB9561TQ==} - - yuku-codegen@0.10.2: - resolution: {integrity: sha512-hentl2dtrF6cPjiAirtkfxfFZBA6Hdm61UqRJ7cA0qrlDNMk9PZGOjw5w1mx3E0hu/6pHcJF4dJW+D0SXHPZOA==} - - yuku-parser@0.10.2: - resolution: {integrity: sha512-CgaU0/PPjCAIEZ3WQroosOxTY3eeKldAN3h+vk8pMNz4+jl1CZzBR4pW+K/rRPF112VooCL5FdjJoiMNjDrL2A==} - zod@4.6.5: resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} snapshots: + '@ast-grep/napi-darwin-arm64@0.45.3': + optional: true + + '@ast-grep/napi-darwin-x64@0.45.3': + optional: true + + '@ast-grep/napi-linux-arm64-gnu@0.45.3': + optional: true + + '@ast-grep/napi-linux-arm64-musl@0.45.3': + optional: true + + '@ast-grep/napi-linux-x64-gnu@0.45.3': + optional: true + + '@ast-grep/napi-linux-x64-musl@0.45.3': + optional: true + + '@ast-grep/napi-win32-arm64-msvc@0.45.3': + optional: true + + '@ast-grep/napi-win32-ia32-msvc@0.45.3': + optional: true + + '@ast-grep/napi-win32-x64-msvc@0.45.3': + optional: true + + '@ast-grep/napi@0.45.3': + optionalDependencies: + '@ast-grep/napi-darwin-arm64': 0.45.3 + '@ast-grep/napi-darwin-x64': 0.45.3 + '@ast-grep/napi-linux-arm64-gnu': 0.45.3 + '@ast-grep/napi-linux-arm64-musl': 0.45.3 + '@ast-grep/napi-linux-x64-gnu': 0.45.3 + '@ast-grep/napi-linux-x64-musl': 0.45.3 + '@ast-grep/napi-win32-arm64-msvc': 0.45.3 + '@ast-grep/napi-win32-ia32-msvc': 0.45.3 + '@ast-grep/napi-win32-x64-msvc': 0.45.3 + '@babel/code-frame@7.29.7': dependencies: '@babel/helper-validator-identifier': 7.29.7 @@ -1688,6 +1827,22 @@ snapshots: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 + '@emnapi/core@1.11.3': + dependencies: + '@emnapi/wasi-threads': 1.2.3 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.3': + dependencies: + tslib: 2.8.1 + optional: true + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.6.0 @@ -1722,6 +1877,22 @@ snapshots: tinyglobby: 0.2.17 yaml: 2.9.1 + '@module-federation/bridge-react-webpack-plugin@2.9.0': + dependencies: + '@module-federation/sdk': 2.9.0 + + '@module-federation/cli@2.9.0(typescript@6.0.3)': + dependencies: + '@module-federation/dts-plugin': 2.9.0(typescript@6.0.3) + '@module-federation/sdk': 2.9.0 + commander: 11.1.0 + jiti: 2.4.2 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - vue-tsc + '@module-federation/dts-plugin@2.9.0(typescript@6.0.3)': dependencies: '@module-federation/error-codes': 2.9.0 @@ -1737,17 +1908,105 @@ snapshots: - bufferutil - utf-8-validate + '@module-federation/enhanced@2.9.0(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3)': + dependencies: + '@module-federation/bridge-react-webpack-plugin': 2.9.0 + '@module-federation/cli': 2.9.0(typescript@6.0.3) + '@module-federation/dts-plugin': 2.9.0(typescript@6.0.3) + '@module-federation/error-codes': 2.9.0 + '@module-federation/inject-external-runtime-core-plugin': 2.9.0(@module-federation/runtime-tools@2.9.0) + '@module-federation/managers': 2.9.0 + '@module-federation/manifest': 2.9.0(typescript@6.0.3) + '@module-federation/rspack': 2.9.0(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) + '@module-federation/runtime-tools': 2.9.0 + '@module-federation/sdk': 2.9.0 + '@module-federation/webpack-bundler-runtime': 2.9.0 + schema-utils: 4.3.0 + tapable: 2.3.0 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - '@rspack/core' + - bufferutil + - utf-8-validate + '@module-federation/error-codes@2.9.0': {} + '@module-federation/inject-external-runtime-core-plugin@2.9.0(@module-federation/runtime-tools@2.9.0)': + dependencies: + '@module-federation/runtime-tools': 2.9.0 + '@module-federation/managers@2.9.0': dependencies: '@module-federation/sdk': 2.9.0 + '@module-federation/manifest@2.9.0(typescript@6.0.3)': + dependencies: + '@module-federation/dts-plugin': 2.9.0(typescript@6.0.3) + '@module-federation/managers': 2.9.0 + '@module-federation/sdk': 2.9.0 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - vue-tsc + + '@module-federation/node@2.7.50(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3)': + dependencies: + '@module-federation/enhanced': 2.9.0(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) + '@module-federation/runtime': 2.9.0 + '@module-federation/sdk': 2.9.0 + encoding: 0.1.13 + node-fetch: 2.7.0(encoding@0.1.13) + tapable: 2.3.0 + transitivePeerDependencies: + - '@rspack/core' + - bufferutil + - typescript + - utf-8-validate + - vue-tsc + + '@module-federation/rsbuild-plugin@2.9.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3)': + dependencies: + '@module-federation/enhanced': 2.9.0(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) + '@module-federation/node': 2.7.50(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) + '@module-federation/sdk': 2.9.0 + optionalDependencies: + '@rsbuild/core': 2.2.8(@module-federation/runtime-tools@2.9.0) + transitivePeerDependencies: + - '@rspack/core' + - bufferutil + - typescript + - utf-8-validate + - vue-tsc + - webpack + + '@module-federation/rspack@2.9.0(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3)': + dependencies: + '@module-federation/bridge-react-webpack-plugin': 2.9.0 + '@module-federation/dts-plugin': 2.9.0(typescript@6.0.3) + '@module-federation/inject-external-runtime-core-plugin': 2.9.0(@module-federation/runtime-tools@2.9.0) + '@module-federation/managers': 2.9.0 + '@module-federation/manifest': 2.9.0(typescript@6.0.3) + '@module-federation/runtime-tools': 2.9.0 + '@module-federation/sdk': 2.9.0 + '@rspack/core': 2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23) + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@module-federation/runtime-core@2.9.0': dependencies: '@module-federation/error-codes': 2.9.0 '@module-federation/sdk': 2.9.0 + '@module-federation/runtime-tools@2.9.0': + dependencies: + '@module-federation/runtime': 2.9.0 + '@module-federation/webpack-bundler-runtime': 2.9.0 + '@module-federation/runtime@2.9.0': dependencies: '@module-federation/error-codes': 2.9.0 @@ -1770,6 +2029,19 @@ snapshots: - utf-8-validate - vue-tsc + '@module-federation/webpack-bundler-runtime@2.9.0': + dependencies: + '@module-federation/error-codes': 2.9.0 + '@module-federation/runtime': 2.9.0 + '@module-federation/sdk': 2.9.0 + + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)': + dependencies: + '@emnapi/core': 1.11.3 + '@emnapi/runtime': 1.11.3 + '@tybys/wasm-util': 0.10.4 + optional: true + '@oozcitak/dom@2.0.2': dependencies: '@oozcitak/infra': 2.0.2 @@ -1791,10 +2063,6 @@ snapshots: '@pnpm/deps.graph-sequencer@1100.0.1': {} - '@quansync/fs@1.1.0': - dependencies: - quansync: 1.0.0 - '@rolldown/binding-android-arm-eabi@1.2.9': optional: true @@ -1842,16 +2110,113 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@tanstack/history@1.162.4': {} + '@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0)': + dependencies: + '@rspack/core': 2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23) + '@swc/helpers': 0.5.23 + transitivePeerDependencies: + - '@module-federation/runtime-tools' + + '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))': + dependencies: + '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) + react-refresh: 0.18.0 + optionalDependencies: + '@rsbuild/core': 2.2.8(@module-federation/runtime-tools@2.9.0) + transitivePeerDependencies: + - '@rspack/core' + + '@rslib/core@1.0.1(@module-federation/runtime-tools@2.9.0)(typescript@6.0.3)': + dependencies: + '@rsbuild/core': 2.2.8(@module-federation/runtime-tools@2.9.0) + rsbuild-plugin-dts: 1.0.1(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(typescript@6.0.3) + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - '@module-federation/runtime-tools' + - core-js + + '@rspack/binding-darwin-arm64@2.2.6': + optional: true + + '@rspack/binding-darwin-x64@2.2.6': + optional: true + + '@rspack/binding-linux-arm64-gnu@2.2.6': + optional: true + + '@rspack/binding-linux-arm64-musl@2.2.6': + optional: true + + '@rspack/binding-linux-ppc64-gnu@2.2.6': + optional: true + + '@rspack/binding-linux-riscv64-gnu@2.2.6': + optional: true + + '@rspack/binding-linux-riscv64-musl@2.2.6': + optional: true + + '@rspack/binding-linux-s390x-gnu@2.2.6': + optional: true + + '@rspack/binding-linux-x64-gnu@2.2.6': + optional: true + + '@rspack/binding-linux-x64-musl@2.2.6': + optional: true + + '@rspack/binding-wasm32-wasi@2.2.6': + dependencies: + '@emnapi/core': 1.11.3 + '@emnapi/runtime': 1.11.3 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3) + optional: true + + '@rspack/binding-win32-arm64-msvc@2.2.6': + optional: true + + '@rspack/binding-win32-ia32-msvc@2.2.6': + optional: true + + '@rspack/binding-win32-x64-msvc@2.2.6': + optional: true + + '@rspack/binding@2.2.6': + optionalDependencies: + '@rspack/binding-darwin-arm64': 2.2.6 + '@rspack/binding-darwin-x64': 2.2.6 + '@rspack/binding-linux-arm64-gnu': 2.2.6 + '@rspack/binding-linux-arm64-musl': 2.2.6 + '@rspack/binding-linux-ppc64-gnu': 2.2.6 + '@rspack/binding-linux-riscv64-gnu': 2.2.6 + '@rspack/binding-linux-riscv64-musl': 2.2.6 + '@rspack/binding-linux-s390x-gnu': 2.2.6 + '@rspack/binding-linux-x64-gnu': 2.2.6 + '@rspack/binding-linux-x64-musl': 2.2.6 + '@rspack/binding-wasm32-wasi': 2.2.6 + '@rspack/binding-win32-arm64-msvc': 2.2.6 + '@rspack/binding-win32-ia32-msvc': 2.2.6 + '@rspack/binding-win32-x64-msvc': 2.2.6 + + '@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23)': + dependencies: + '@rspack/binding': 2.2.6 + optionalDependencies: + '@module-federation/runtime-tools': 2.9.0 + '@swc/helpers': 0.5.23 + + '@rspack/plugin-react-refresh@2.0.2(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0)': + dependencies: + react-refresh: 0.18.0 + optionalDependencies: + '@rspack/core': 2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23) - '@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': + '@swc/helpers@0.5.23': dependencies: - '@tanstack/history': 1.162.4 - '@tanstack/react-store': 0.11.1(react-dom@19.3.0(react@19.3.0))(react@19.3.0) - '@tanstack/router-core': 1.171.30 - isbot: 5.2.2 - react: 19.3.0 - react-dom: 19.3.0(react@19.3.0) + tslib: 2.8.1 + + '@tanstack/history@1.162.4': {} '@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': dependencies: @@ -1862,14 +2227,6 @@ snapshots: react: 19.3.0 react-dom: 19.3.0(react@19.3.0) - '@tanstack/react-start-client@1.168.34(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': - dependencies: - '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) - '@tanstack/router-core': 1.171.30 - '@tanstack/start-client-core': 1.170.30 - react: 19.3.0 - react-dom: 19.3.0(react@19.3.0) - '@tanstack/react-start-client@1.168.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': dependencies: '@tanstack/react-router': 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) @@ -1878,44 +2235,20 @@ snapshots: react: 19.3.0 react-dom: 19.3.0(react@19.3.0) - '@tanstack/react-start-rsc@0.1.53(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': - dependencies: - '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) - '@tanstack/router-core': 1.171.30 - '@tanstack/router-utils': 1.162.3 - '@tanstack/start-client-core': 1.170.30 - '@tanstack/start-fn-stubs': 1.162.0 - '@tanstack/start-plugin-core': 1.171.44(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) - '@tanstack/start-storage-context': 1.167.32 - pathe: 2.0.3 - react: 19.3.0 - react-dom: 19.3.0(react@19.3.0) - transitivePeerDependencies: - - '@farmfe/core' - - '@rsbuild/core' - - bun-types-no-globals - - crossws - - esbuild - - rolldown - - rollup - - supports-color - - unloader - - vite - - vite-plugin-solid - - webpack - - '@tanstack/react-start-rsc@0.1.55(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + '@tanstack/react-start-rsc@0.1.55(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@tanstack/react-router': 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) '@tanstack/router-core': 1.171.32 '@tanstack/router-utils': 1.162.3 '@tanstack/start-client-core': 1.170.32 '@tanstack/start-fn-stubs': 1.162.0 - '@tanstack/start-plugin-core': 1.171.46(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/start-plugin-core': 1.171.46(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) '@tanstack/start-storage-context': 1.167.34 pathe: 2.0.3 react: 19.3.0 react-dom: 19.3.0(react@19.3.0) + optionalDependencies: + '@rspack/core': 2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23) transitivePeerDependencies: - '@farmfe/core' - '@rsbuild/core' @@ -1930,16 +2263,6 @@ snapshots: - vite-plugin-solid - webpack - '@tanstack/react-start-server@1.167.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': - dependencies: - '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) - '@tanstack/router-core': 1.171.30 - '@tanstack/start-server-core': 1.169.35 - react: 19.3.0 - react-dom: 19.3.0(react@19.3.0) - transitivePeerDependencies: - - crossws - '@tanstack/react-start-server@1.167.43(react-dom@19.3.0(react@19.3.0))(react@19.3.0)': dependencies: '@tanstack/react-router': 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) @@ -1950,49 +2273,21 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/react-start@1.168.54(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': - dependencies: - '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) - '@tanstack/react-start-client': 1.168.34(react-dom@19.3.0(react@19.3.0))(react@19.3.0) - '@tanstack/react-start-rsc': 0.1.53(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) - '@tanstack/react-start-server': 1.167.41(react-dom@19.3.0(react@19.3.0))(react@19.3.0) - '@tanstack/router-utils': 1.162.3 - '@tanstack/start-client-core': 1.170.30 - '@tanstack/start-plugin-core': 1.171.44(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) - '@tanstack/start-server-core': 1.169.35 - pathe: 2.0.3 - react: 19.3.0 - react-dom: 19.3.0(react@19.3.0) - optionalDependencies: - vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - crossws - - esbuild - - react-server-dom-rspack - - rolldown - - rollup - - supports-color - - unloader - - vite-plugin-solid - - webpack - - '@tanstack/react-start@1.168.56(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + '@tanstack/react-start@1.168.56(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@tanstack/react-router': 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) '@tanstack/react-start-client': 1.168.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) - '@tanstack/react-start-rsc': 0.1.55(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/react-start-rsc': 0.1.55(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) '@tanstack/react-start-server': 1.167.43(react-dom@19.3.0(react@19.3.0))(react@19.3.0) '@tanstack/router-utils': 1.162.3 '@tanstack/start-client-core': 1.170.32 - '@tanstack/start-plugin-core': 1.171.46(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/start-plugin-core': 1.171.46(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) '@tanstack/start-server-core': 1.169.37 pathe: 2.0.3 react: 19.3.0 react-dom: 19.3.0(react@19.3.0) optionalDependencies: + '@rsbuild/core': 2.2.8(@module-federation/runtime-tools@2.9.0) vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) transitivePeerDependencies: - '@farmfe/core' @@ -2015,13 +2310,6 @@ snapshots: react-dom: 19.3.0(react@19.3.0) use-sync-external-store: 1.7.0(react@19.3.0) - '@tanstack/router-core@1.171.30': - dependencies: - '@tanstack/history': 1.162.4 - cookie-es: 3.1.1 - seroval: 1.6.7 - seroval-plugins: 1.6.7(seroval@1.6.7) - '@tanstack/router-core@1.171.32': dependencies: '@tanstack/history': 1.162.4 @@ -2029,19 +2317,6 @@ snapshots: seroval: 1.6.7 seroval-plugins: 1.6.7(seroval@1.6.7) - '@tanstack/router-generator@1.167.36': - dependencies: - '@babel/types': 7.29.8 - '@tanstack/router-core': 1.171.30 - '@tanstack/router-utils': 1.162.3 - '@tanstack/virtual-file-routes': 1.162.0 - jiti: 2.7.0 - magic-string: 0.30.21 - prettier: 3.9.7 - zod: 4.6.5 - transitivePeerDependencies: - - supports-color - '@tanstack/router-generator@1.167.38': dependencies: '@babel/types': 7.29.8 @@ -2055,31 +2330,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.168.38(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': - dependencies: - '@babel/core': 7.29.7 - '@babel/template': 7.29.7 - '@babel/types': 7.29.8 - '@tanstack/router-core': 1.171.30 - '@tanstack/router-generator': 1.167.36 - '@tanstack/router-utils': 1.162.3 - chokidar: 5.0.0 - unplugin: 3.4.0(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) - zod: 4.6.5 - optionalDependencies: - '@tanstack/react-router': 1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0) - vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - esbuild - - rolldown - - rollup - - supports-color - - unloader - - '@tanstack/router-plugin@1.168.40(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + '@tanstack/router-plugin@1.168.40(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@babel/core': 7.29.7 '@babel/template': 7.29.7 @@ -2088,9 +2339,10 @@ snapshots: '@tanstack/router-generator': 1.167.38 '@tanstack/router-utils': 1.162.3 chokidar: 5.0.0 - unplugin: 3.4.0(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + unplugin: 3.4.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) zod: 4.6.5 optionalDependencies: + '@rsbuild/core': 2.2.8(@module-federation/runtime-tools@2.9.0) '@tanstack/react-router': 1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0) vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) transitivePeerDependencies: @@ -2116,13 +2368,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/start-client-core@1.170.30': - dependencies: - '@tanstack/router-core': 1.171.30 - '@tanstack/start-fn-stubs': 1.162.0 - '@tanstack/start-storage-context': 1.167.32 - seroval: 1.6.7 - '@tanstack/start-client-core@1.170.32': dependencies: '@tanstack/router-core': 1.171.32 @@ -2132,46 +2377,7 @@ snapshots: '@tanstack/start-fn-stubs@1.162.0': {} - '@tanstack/start-plugin-core@1.171.44(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/core': 7.29.7 - '@babel/types': 7.29.8 - '@jridgewell/remapping': 2.3.5 - '@tanstack/router-core': 1.171.30 - '@tanstack/router-generator': 1.167.36 - '@tanstack/router-plugin': 1.168.38(@tanstack/react-router@1.170.36(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) - '@tanstack/router-utils': 1.162.3 - '@tanstack/start-server-core': 1.169.35 - exsolve: 1.1.1 - lightningcss: 1.33.0 - pathe: 2.0.3 - picomatch: 4.0.7 - seroval: 1.6.7 - source-map: 0.7.6 - srvx: 0.11.22 - tinyglobby: 0.2.17 - ufo: 1.6.4 - vitefu: 1.1.3(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) - xmlbuilder2: 4.0.3 - zod: 4.6.5 - optionalDependencies: - vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - '@tanstack/react-router' - - bun-types-no-globals - - crossws - - esbuild - - rolldown - - rollup - - supports-color - - unloader - - vite-plugin-solid - - webpack - - '@tanstack/start-plugin-core@1.171.46(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': + '@tanstack/start-plugin-core@1.171.46(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1))': dependencies: '@babel/code-frame': 7.29.7 '@babel/core': 7.29.7 @@ -2179,7 +2385,7 @@ snapshots: '@jridgewell/remapping': 2.3.5 '@tanstack/router-core': 1.171.32 '@tanstack/router-generator': 1.167.38 - '@tanstack/router-plugin': 1.168.40(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) + '@tanstack/router-plugin': 1.168.40(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(@tanstack/react-router@1.170.38(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) '@tanstack/router-utils': 1.162.3 '@tanstack/start-server-core': 1.169.37 exsolve: 1.1.1 @@ -2195,6 +2401,7 @@ snapshots: xmlbuilder2: 4.0.3 zod: 4.6.5 optionalDependencies: + '@rsbuild/core': 2.2.8(@module-federation/runtime-tools@2.9.0) vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) transitivePeerDependencies: - '@farmfe/core' @@ -2210,18 +2417,6 @@ snapshots: - vite-plugin-solid - webpack - '@tanstack/start-server-core@1.169.35': - dependencies: - '@tanstack/history': 1.162.4 - '@tanstack/router-core': 1.171.30 - '@tanstack/start-client-core': 1.170.30 - '@tanstack/start-storage-context': 1.167.32 - fetchdts: 0.1.7 - h3-v2: h3@2.0.1-rc.20 - seroval: 1.6.7 - transitivePeerDependencies: - - crossws - '@tanstack/start-server-core@1.169.37': dependencies: '@tanstack/history': 1.162.4 @@ -2234,10 +2429,6 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/start-storage-context@1.167.32': - dependencies: - '@tanstack/router-core': 1.171.30 - '@tanstack/start-storage-context@1.167.34': dependencies: '@tanstack/router-core': 1.171.32 @@ -2264,6 +2455,13 @@ snapshots: '@turbo/windows-arm64@2.10.13': optional: true + '@tybys/wasm-util@0.10.4': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/json-schema@7.0.15': {} + '@types/node@24.10.1': dependencies: undici-types: 7.16.0 @@ -2281,81 +2479,23 @@ snapshots: '@rolldown/pluginutils': 1.0.1 vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) - '@yuku-codegen/binding-android-arm64@0.10.2': - optional: true - - '@yuku-codegen/binding-darwin-arm64@0.10.2': - optional: true - - '@yuku-codegen/binding-darwin-x64@0.10.2': - optional: true - - '@yuku-codegen/binding-freebsd-x64@0.10.2': - optional: true - - '@yuku-codegen/binding-linux-arm-gnu@0.10.2': - optional: true - - '@yuku-codegen/binding-linux-arm-musl@0.10.2': - optional: true - - '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': - optional: true - - '@yuku-codegen/binding-linux-arm64-musl@0.10.2': - optional: true - - '@yuku-codegen/binding-linux-x64-gnu@0.10.2': - optional: true - - '@yuku-codegen/binding-linux-x64-musl@0.10.2': - optional: true - - '@yuku-codegen/binding-win32-arm64@0.10.2': - optional: true - - '@yuku-codegen/binding-win32-x64@0.10.2': - optional: true - - '@yuku-parser/binding-android-arm64@0.10.2': - optional: true - - '@yuku-parser/binding-darwin-arm64@0.10.2': - optional: true - - '@yuku-parser/binding-darwin-x64@0.10.2': - optional: true - - '@yuku-parser/binding-freebsd-x64@0.10.2': - optional: true - - '@yuku-parser/binding-linux-arm-gnu@0.10.2': - optional: true - - '@yuku-parser/binding-linux-arm-musl@0.10.2': - optional: true - - '@yuku-parser/binding-linux-arm64-gnu@0.10.2': - optional: true - - '@yuku-parser/binding-linux-arm64-musl@0.10.2': - optional: true - - '@yuku-parser/binding-linux-x64-gnu@0.10.2': - optional: true - - '@yuku-parser/binding-linux-x64-musl@0.10.2': - optional: true - - '@yuku-parser/binding-win32-arm64@0.10.2': - optional: true + adm-zip@0.6.0: {} - '@yuku-parser/binding-win32-x64@0.10.2': - optional: true + ajv-formats@2.1.1: + dependencies: + ajv: 8.20.0 - '@yuku-toolchain/types@0.10.2': {} + ajv-keywords@5.1.0(ajv@8.20.0): + dependencies: + ajv: 8.20.0 + fast-deep-equal: 3.1.3 - adm-zip@0.6.0: {} + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.8 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 ansis@4.4.0: {} @@ -2388,6 +2528,8 @@ snapshots: dependencies: readdirp: 5.1.1 + commander@11.1.0: {} + convert-source-map@2.0.0: {} cookie-es@3.1.1: {} @@ -2398,28 +2540,30 @@ snapshots: dependencies: ms: 2.1.3 - defu@6.1.7: {} - detect-libc@2.1.2: {} diff@8.0.4: {} - dts-resolver@3.0.0: {} - electron-to-chromium@1.5.430: {} - empathic@2.0.1: {} + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 escalade@3.2.0: {} exsolve@1.1.1: {} + fast-deep-equal@3.1.3: {} + fast-string-truncated-width@3.0.3: {} fast-string-width@3.0.2: dependencies: fast-string-truncated-width: 3.0.3 + fast-uri@3.1.8: {} + fast-wrap-ansi@0.2.2: dependencies: fast-string-width: 3.0.2 @@ -2435,22 +2579,18 @@ snapshots: gensync@1.0.0-beta.2: {} - get-tsconfig@5.0.0-beta.6: - dependencies: - resolve-pkg-maps: 1.0.0 - h3@2.0.1-rc.20: dependencies: rou3: 0.8.1 srvx: 0.11.22 - hookable@6.1.1: {} - human-id@4.2.1: {} - import-meta-resolve@4.2.0: {} + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 - import-without-cache@0.4.1: {} + import-meta-resolve@4.2.0: {} isbot@5.2.2: {} @@ -2458,6 +2598,8 @@ snapshots: dependencies: ws: 8.21.0 + jiti@2.4.2: {} + jiti@2.7.0: {} jju@1.4.0: {} @@ -2470,6 +2612,8 @@ snapshots: jsesc@3.1.0: {} + json-schema-traverse@1.0.0: {} + json5@2.2.3: {} jsonc-parser@3.3.1: {} @@ -2540,11 +2684,13 @@ snapshots: nanoid@3.3.19: {} - node-releases@2.0.55: {} - - obug@2.2.1: {} + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 - obug@3.0.0: {} + node-releases@2.0.55: {} package-manager-detector@1.8.0: {} @@ -2562,32 +2708,18 @@ snapshots: prettier@3.9.7: {} - quansync@1.0.0: {} - react-dom@19.3.0(react@19.3.0): dependencies: react: 19.3.0 scheduler: 0.28.0 + react-refresh@0.18.0: {} + react@19.3.0: {} readdirp@5.1.1: {} - resolve-pkg-maps@1.0.0: {} - - rolldown-plugin-dts@0.28.6(rolldown@1.2.9)(typescript@6.0.3): - dependencies: - dts-resolver: 3.0.0 - get-tsconfig: 5.0.0-beta.6 - obug: 3.0.0 - rolldown: 1.2.9 - yuku-ast: 0.10.2 - yuku-codegen: 0.10.2 - yuku-parser: 0.10.2 - optionalDependencies: - typescript: 6.0.3 - transitivePeerDependencies: - - oxc-resolver + require-from-string@2.0.2: {} rolldown@1.2.9: dependencies: @@ -2612,8 +2744,24 @@ snapshots: rou3@0.8.1: {} + rsbuild-plugin-dts@1.0.1(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(typescript@6.0.3): + dependencies: + '@ast-grep/napi': 0.45.3 + '@rsbuild/core': 2.2.8(@module-federation/runtime-tools@2.9.0) + optionalDependencies: + typescript: 6.0.3 + + safer-buffer@2.1.2: {} + scheduler@0.28.0: {} + schema-utils@4.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.20.0 + ajv-formats: 2.1.1 + ajv-keywords: 5.1.0(ajv@8.20.0) + semver@6.3.1: {} semver@7.8.5: {} @@ -2634,6 +2782,8 @@ snapshots: srvx@0.11.22: {} + tapable@2.3.0: {} + tinyexec@1.3.1: {} tinyglobby@0.2.17: @@ -2641,32 +2791,9 @@ snapshots: fdir: 6.5.0(picomatch@4.0.7) picomatch: 4.0.7 - tree-kill@1.2.2: {} + tr46@0.0.3: {} - tsdown@0.23.0(typescript@6.0.3): - dependencies: - cac: 7.0.0 - defu: 6.1.7 - empathic: 2.0.1 - hookable: 6.1.1 - import-without-cache: 0.4.1 - obug: 2.2.1 - picomatch: 4.0.7 - rolldown: 1.2.9 - rolldown-plugin-dts: 0.28.6(rolldown@1.2.9)(typescript@6.0.3) - tinyexec: 1.3.1 - tinyglobby: 0.2.17 - tree-kill: 1.2.2 - unconfig-core: 7.5.0 - verkit: 0.4.0 - optionalDependencies: - typescript: 6.0.3 - transitivePeerDependencies: - - '@typescript/native-preview' - - '@volar/typescript' - - '@vue/language-core' - - oxc-resolver - - vue-tsc + tslib@2.8.1: {} turbo@2.10.13: optionalDependencies: @@ -2681,21 +2808,18 @@ snapshots: ufo@1.6.4: {} - unconfig-core@7.5.0: - dependencies: - '@quansync/fs': 1.1.0 - quansync: 1.0.0 - undici-types@7.16.0: {} undici@7.29.0: {} - unplugin@3.4.0(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)): + unplugin@3.4.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(rolldown@1.2.9)(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)): dependencies: '@jridgewell/remapping': 2.3.5 picomatch: 4.0.7 webpack-virtual-modules: 0.6.2 optionalDependencies: + '@rsbuild/core': 2.2.8(@module-federation/runtime-tools@2.9.0) + '@rspack/core': 2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23) rolldown: 1.2.9 vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) @@ -2709,8 +2833,6 @@ snapshots: dependencies: react: 19.3.0 - verkit@0.4.0: {} - vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1): dependencies: lightningcss: 1.33.0 @@ -2728,8 +2850,15 @@ snapshots: optionalDependencies: vite: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) + webidl-conversions@3.0.1: {} + webpack-virtual-modules@0.6.2: {} + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + ws@8.21.0: {} xmlbuilder2@4.0.3: @@ -2743,43 +2872,4 @@ snapshots: yaml@2.9.1: {} - yuku-ast@0.10.2: - dependencies: - '@yuku-toolchain/types': 0.10.2 - - yuku-codegen@0.10.2: - dependencies: - '@yuku-toolchain/types': 0.10.2 - optionalDependencies: - '@yuku-codegen/binding-android-arm64': 0.10.2 - '@yuku-codegen/binding-darwin-arm64': 0.10.2 - '@yuku-codegen/binding-darwin-x64': 0.10.2 - '@yuku-codegen/binding-freebsd-x64': 0.10.2 - '@yuku-codegen/binding-linux-arm-gnu': 0.10.2 - '@yuku-codegen/binding-linux-arm-musl': 0.10.2 - '@yuku-codegen/binding-linux-arm64-gnu': 0.10.2 - '@yuku-codegen/binding-linux-arm64-musl': 0.10.2 - '@yuku-codegen/binding-linux-x64-gnu': 0.10.2 - '@yuku-codegen/binding-linux-x64-musl': 0.10.2 - '@yuku-codegen/binding-win32-arm64': 0.10.2 - '@yuku-codegen/binding-win32-x64': 0.10.2 - - yuku-parser@0.10.2: - dependencies: - '@yuku-toolchain/types': 0.10.2 - yuku-ast: 0.10.2 - optionalDependencies: - '@yuku-parser/binding-android-arm64': 0.10.2 - '@yuku-parser/binding-darwin-arm64': 0.10.2 - '@yuku-parser/binding-darwin-x64': 0.10.2 - '@yuku-parser/binding-freebsd-x64': 0.10.2 - '@yuku-parser/binding-linux-arm-gnu': 0.10.2 - '@yuku-parser/binding-linux-arm-musl': 0.10.2 - '@yuku-parser/binding-linux-arm64-gnu': 0.10.2 - '@yuku-parser/binding-linux-arm64-musl': 0.10.2 - '@yuku-parser/binding-linux-x64-gnu': 0.10.2 - '@yuku-parser/binding-linux-x64-musl': 0.10.2 - '@yuku-parser/binding-win32-arm64': 0.10.2 - '@yuku-parser/binding-win32-x64': 0.10.2 - zod@4.6.5: {} diff --git a/test/example-build.test.mjs b/test/example-build.test.mjs index 7ed7d7d..7d05edc 100644 --- a/test/example-build.test.mjs +++ b/test/example-build.test.mjs @@ -7,18 +7,23 @@ import test from "node:test"; const root = join(dirname(fileURLToPath(import.meta.url)), ".."); const hostDist = join(root, "apps", "host", "dist"); const remoteDist = join(root, "apps", "remote", "dist"); +const rsbuildHostDist = join(root, "apps", "rsbuild-host", "dist"); +const rsbuildRemoteDist = join(root, "apps", "rsbuild-remote", "dist"); function readJson(path) { return JSON.parse(readFileSync(path, "utf8")); } -test("both TanStack Start apps produce client and server builds", () => { +test("all TanStack Start apps produce client and server builds", () => { for (const [name, dist] of [ ["host", hostDist], ["remote", remoteDist], + ["rsbuild host", rsbuildHostDist], + ["rsbuild remote", rsbuildRemoteDist], ]) { - assert.ok(existsSync(join(dist, "client", ".vite", "manifest.json")), `${name} client`); - assert.ok(existsSync(join(dist, "server", "server.js")), `${name} server`); + assert.ok(existsSync(join(dist, "client", "mf-manifest.json")), `${name} client`); + const serverEntry = name.startsWith("rsbuild") ? "index.js" : "server.js"; + assert.ok(existsSync(join(dist, "server", serverEntry)), `${name} server`); } }); @@ -51,3 +56,46 @@ test("host records the TanStack remote and server-side loader", () => { assert.match(serverFiles, /ssrEntryLoader/); assert.match(serverFiles, /tanstack_remote/); }); + +test("Vite and Rsbuild publish reciprocal client interoperability contracts", () => { + const viteHostManifest = readJson(join(hostDist, "client", "mf-manifest.json")); + const rsbuildHostManifest = readJson(join(rsbuildHostDist, "client", "mf-manifest.json")); + const rsbuildRemoteClient = readJson(join(rsbuildRemoteDist, "client", "mf-manifest.json")); + + assert.equal( + viteHostManifest.remotes.find(({ alias }) => alias === "tanstack_rsbuild_remote")?.moduleName, + "StatusCard", + ); + assert.equal( + rsbuildHostManifest.remotes.find(({ alias }) => alias === "tanstack_remote")?.entry, + "http://127.0.0.1:3001/mf-manifest.json", + ); + assert.equal( + rsbuildHostManifest.remotes.find(({ alias }) => alias === "tanstack_rsbuild_remote")?.entry, + "http://127.0.0.1:3002/mf-manifest.json", + ); + assert.equal(rsbuildRemoteClient.metaData.remoteEntry.type, "global"); + assert.equal(rsbuildRemoteClient.metaData.remoteEntry.name, "remoteEntry.js"); + const statusCard = rsbuildRemoteClient.exposes.find(({ path }) => path === "./StatusCard"); + assert.ok(statusCard?.assets.css.sync.length > 0, "Rsbuild StatusCard CSS is published"); + assert.equal( + existsSync(join(rsbuildRemoteDist, "server", "serverRemoteEntry.cjs")), + false, + "client-only cross-bundler remote does not publish an unused SSR container", + ); + assert.equal( + existsSync(join(rsbuildHostDist, "server", "mf-manifest.json")), + false, + "client-only cross-bundler host does not initialize remotes during SSR", + ); + + for (const manifest of [rsbuildRemoteClient]) { + for (const dependency of ["react", "react-dom"]) { + assert.equal( + manifest.shared.find(({ name }) => name === dependency)?.singleton, + true, + `${dependency} is a singleton`, + ); + } + } +}); diff --git a/test/example-runtime.test.mjs b/test/example-runtime.test.mjs index b4f92cd..54b5a67 100644 --- a/test/example-runtime.test.mjs +++ b/test/example-runtime.test.mjs @@ -97,3 +97,48 @@ test("host server-renders a component from the TanStack remote", async () => { await stopApp(remote); } }); + +test("Vite and Rsbuild hosts serve reciprocal browser-interoperability shells", async () => { + const viteRemote = startApp("tanstack-start-remote"); + const rsbuildRemote = startApp("tanstack-start-rsbuild-remote"); + let viteHost; + let rsbuildHost; + + try { + await waitForResponse( + "http://127.0.0.1:3001/remoteEntry.js", + viteRemote, + ({ status }) => status === 200, + ); + const manifest = await waitForResponse( + "http://127.0.0.1:3002/mf-manifest.json", + rsbuildRemote, + ({ status }) => status === 200, + ); + assert.match(manifest.body, /tanstack_rsbuild_remote/); + + viteHost = startApp("tanstack-start-host"); + rsbuildHost = startApp("tanstack-start-rsbuild-host"); + + const viteResponse = await waitForResponse( + "http://127.0.0.1:3000/", + viteHost, + ({ status }) => status === 200, + ); + const rsbuildResponse = await waitForResponse( + "http://127.0.0.1:3003/", + rsbuildHost, + ({ status }) => status === 200, + ); + + assert.match(viteResponse.body, /Rsbuild remote loads after hydration/); + assert.match(rsbuildResponse.body, /Rspack host, two remote formats/); + assert.match(rsbuildResponse.body, /Loading the Rsbuild remote/); + assert.match(rsbuildResponse.body, /Loading the Vite remote/); + } finally { + if (rsbuildHost) await stopApp(rsbuildHost); + if (viteHost) await stopApp(viteHost); + await stopApp(rsbuildRemote); + await stopApp(viteRemote); + } +}); diff --git a/test/release-artifacts.test.mjs b/test/release-artifacts.test.mjs index e8f6555..f87a4b4 100644 --- a/test/release-artifacts.test.mjs +++ b/test/release-artifacts.test.mjs @@ -9,16 +9,24 @@ const root = join(dirname(fileURLToPath(import.meta.url)), ".."); const packageRoot = join(root, "packages", "tanstack"); const dist = join(packageRoot, "dist"); -test("published declarations reference an included source map", () => { - const declarationName = "index.d.mts"; - const declaration = readFileSync(join(dist, declarationName), "utf8"); - const sourceMap = declaration.match(/\/\/[#@]\s*sourceMappingURL=([^\s]+)\s*$/m)?.[1]; +test("published declarations reference included source maps", () => { + for (const declarationName of [ + "index.d.cts", + "index.d.ts", + "rsbuild.d.cts", + "rsbuild.d.ts", + "vite.d.cts", + "vite.d.ts", + ]) { + const declaration = readFileSync(join(dist, declarationName), "utf8"); + const sourceMap = declaration.match(/\/\/[#@]\s*sourceMappingURL=([^\s]+)\s*$/m)?.[1]; - assert.ok(sourceMap, `${declarationName} has no source map reference`); - assert.ok( - existsSync(join(dist, sourceMap)), - `${declarationName} references missing source map ${sourceMap}`, - ); + assert.ok(sourceMap, `${declarationName} has no source map reference`); + assert.ok( + existsSync(join(dist, sourceMap)), + `${declarationName} references missing source map ${sourceMap}`, + ); + } }); test("npm package contains only runtime, metadata, and documentation files", () => { @@ -31,14 +39,22 @@ test("npm package contains only runtime, metadata, and documentation files", () const [manifest] = JSON.parse(packed.stdout); const files = manifest.files.map(({ path }) => path).sort(); - assert.deepEqual(files, [ - "CHANGELOG.md", - "LICENSE", - "README.md", - "dist/index.d.mts", - "dist/index.d.mts.map", - "dist/index.mjs", - "dist/index.mjs.map", - "package.json", - ]); + const runtimeFiles = ["index", "rsbuild", "shared", "vite"].flatMap((entry) => { + const sourceMaps = entry === "index" ? [] : [`dist/${entry}.js.map`]; + return [ + `dist/${entry}.cjs`, + `dist/${entry}.cjs.map`, + `dist/${entry}.d.cts`, + `dist/${entry}.d.cts.map`, + `dist/${entry}.d.ts`, + `dist/${entry}.d.ts.map`, + `dist/${entry}.js`, + ...sourceMaps, + ]; + }); + + assert.deepEqual( + files, + ["CHANGELOG.md", "LICENSE", "README.md", ...runtimeFiles, "package.json"].sort(), + ); }); diff --git a/test/release-contracts.test.mjs b/test/release-contracts.test.mjs index 9413310..b38f9e3 100644 --- a/test/release-contracts.test.mjs +++ b/test/release-contracts.test.mjs @@ -1,8 +1,19 @@ import assert from "node:assert/strict"; -import { existsSync, readFileSync } from "node:fs"; +import { spawnSync } from "node:child_process"; +import { + cpSync, + existsSync, + mkdirSync, + mkdtempSync, + readFileSync, + rmSync, + symlinkSync, + writeFileSync, +} from "node:fs"; import { createRequire } from "node:module"; import { dirname, join } from "node:path"; -import { fileURLToPath } from "node:url"; +import { tmpdir } from "node:os"; +import { fileURLToPath, pathToFileURL } from "node:url"; import test from "node:test"; const root = join(dirname(fileURLToPath(import.meta.url)), ".."); @@ -13,7 +24,15 @@ const rootPackageJson = JSON.parse(readFileSync(join(root, "package.json"), "utf const ciWorkflow = readFileSync(join(root, ".github", "workflows", "ci.yml"), "utf8"); const previewWorkflow = readFileSync(join(root, ".github", "workflows", "pkg-pr-new.yml"), "utf8"); const releaseWorkflow = readFileSync(join(root, ".github", "workflows", "release.yml"), "utf8"); -const { tanstackStartModuleFederation } = await import(join(packageRoot, "dist", "index.mjs")); +const { tanstackStartModuleFederation } = await import( + pathToFileURL(join(packageRoot, "dist", "index.js")).href +); +const { eagerShared, resolveShared } = await import( + pathToFileURL(join(packageRoot, "dist", "shared.js")).href +); +const { tanstackStartModuleFederation: tanstackStartRsbuildModuleFederation } = await import( + pathToFileURL(join(packageRoot, "dist", "rsbuild.js")).href +); function upstreamOptions(options) { const plugins = tanstackStartModuleFederation(options); @@ -35,6 +54,7 @@ test("applies TanStack-safe defaults", () => { assert.equal(options.manifest, true); assert.equal(options.hostInitInjectLocation, "entry"); assert.equal(options.shared.react.shareConfig.singleton, true); + assert.equal(options.shared.react.shareConfig.eager, false, "Vite defaults stay non-eager"); assert.equal(options.shared["react-dom"].shareConfig.singleton, true); }); @@ -81,19 +101,187 @@ test("leaves the build target to each TanStack environment", () => { assert.equal(options.target, undefined); }); -test("published metadata points to ESM build and declaration map", () => { +test("Rsbuild defaults make synchronous React shares eager without mutating overrides", () => { + const callerShared = { react: { eager: false, singleton: false } }; + const before = structuredClone(callerShared); + const shared = resolveShared(callerShared, eagerShared); + + assert.deepEqual(callerShared, before); + assert.deepEqual(shared.react, { eager: false, singleton: false }); + assert.deepEqual(shared["react-dom"], { eager: true, singleton: true }); +}); + +test("Rsbuild configures separate browser and async-node federation environments", () => { + const plugins = tanstackStartRsbuildModuleFederation({ + federation: { name: "test_remote" }, + }); + + assert.deepEqual( + plugins.map(({ name }) => name), + [ + "rsbuild:module-federation-enhanced", + "tanstack-start-federation-client-compat", + "rsbuild:module-federation-enhanced", + "tanstack-start-federation-ssr-compat", + ], + ); + + const clientConfig = { name: "client", output: {} }; + const serverConfig = { + name: "ssr", + output: { chunkLoadingGlobal: "stale" }, + }; + applyCompilerHook( + plugins.find(({ name }) => name === "tanstack-start-federation-client-compat"), + [clientConfig, serverConfig], + ); + applyCompilerHook( + plugins.find(({ name }) => name === "tanstack-start-federation-ssr-compat"), + [clientConfig, serverConfig], + ); + + assert.deepEqual(clientConfig.output, { + chunkFormat: "array-push", + chunkLoading: "jsonp", + chunkLoadingGlobal: "chunk_test_remote", + module: false, + uniqueName: "test_remote", + }); + assert.equal(serverConfig.target, "async-node"); + assert.deepEqual(serverConfig.output, { + chunkFilename: "[id].test_remote.cjs", + chunkFormat: "commonjs", + chunkLoading: "async-node", + filename: "[name].cjs", + library: { type: "commonjs2" }, + module: false, + }); + + assert.equal( + tanstackStartRsbuildModuleFederation({ + federation: { name: "browser_only" }, + server: false, + }).length, + 2, + ); + + const esmPlugins = tanstackStartRsbuildModuleFederation({ + federation: { name: "esm_server" }, + server: { forceCommonJsOutput: false }, + }); + const esmServerConfig = { + name: "ssr", + output: { chunkFilename: "[id].js", filename: "[name].js" }, + }; + applyCompilerHook( + esmPlugins.find(({ name }) => name === "tanstack-start-federation-ssr-compat"), + [esmServerConfig], + ); + assert.deepEqual(esmServerConfig, { + name: "ssr", + output: { chunkFilename: "[id].js", filename: "[name].js" }, + }); +}); + +function applyCompilerHook(plugin, bundlerConfigs) { + let hook; + plugin.setup({ + onBeforeCreateCompiler(callback) { + hook = callback; + }, + }); + assert.ok(hook, `${plugin.name} registers a compiler hook`); + hook({ bundlerConfigs }); +} + +test("published metadata selects ESM and CommonJS builds with matching types", () => { assert.equal(packageJson.type, "module"); - assert.equal(packageJson.exports["."].import, "./dist/index.mjs"); - assert.equal(packageJson.exports["."].types, "./dist/index.d.mts"); + assert.equal(packageJson.exports["."].import.default, "./dist/index.js"); + assert.equal(packageJson.exports["."].import.types, "./dist/index.d.ts"); + assert.equal(packageJson.exports["."].require.default, "./dist/index.cjs"); + assert.equal(packageJson.exports["."].require.types, "./dist/index.d.cts"); assert.equal( packageRequire.resolve("@module-federation/tanstack"), - join(packageRoot, "dist", "index.mjs"), + join(packageRoot, "dist", "index.cjs"), ); - for (const file of ["index.mjs", "index.mjs.map", "index.d.mts", "index.d.mts.map"]) { + for (const file of ["index.cjs", "index.js", "index.d.cts", "index.d.ts"]) { assert.ok(existsSync(join(packageRoot, "dist", file)), `dist/${file} exists`); } }); +test("clean consumers resolve CJS and ESM entrypoints without the other adapter", () => { + const viteConsumer = createConsumer(["@module-federation/vite"]); + const rsbuildConsumer = createConsumer(["@module-federation/rsbuild-plugin", "@rsbuild/core"]); + + try { + const viteRequire = createRequire(join(viteConsumer, "consumer.cjs")); + const rsbuildRequire = createRequire(join(rsbuildConsumer, "consumer.cjs")); + const cjsRoot = viteRequire("@module-federation/tanstack"); + const cjsRsbuild = rsbuildRequire("@module-federation/tanstack/rsbuild"); + + assert.equal(typeof cjsRoot.tanstackStartModuleFederation, "function"); + assert.equal(typeof cjsRsbuild.tanstackStartModuleFederation, "function"); + assertConsumerImport(viteConsumer, "@module-federation/tanstack"); + assertConsumerImport(viteConsumer, "@module-federation/tanstack/vite"); + assertConsumerImport(rsbuildConsumer, "@module-federation/tanstack/rsbuild"); + } finally { + rmSync(viteConsumer, { force: true, recursive: true }); + rmSync(rsbuildConsumer, { force: true, recursive: true }); + } + + assert.doesNotMatch( + readFileSync(join(packageRoot, "dist", "rsbuild.js"), "utf8"), + /@module-federation\/vite/, + ); + assert.doesNotMatch( + readFileSync(join(packageRoot, "dist", "vite.js"), "utf8"), + /@module-federation\/rsbuild-plugin/, + ); +}); + +function assertConsumerImport(consumer, specifier) { + const entry = join(consumer, "consumer.mjs"); + writeFileSync( + entry, + `import { tanstackStartModuleFederation } from ${JSON.stringify(specifier)};\n` + + `if (typeof tanstackStartModuleFederation !== "function") process.exit(2);\n`, + ); + const result = spawnSync(process.execPath, [entry], { + cwd: consumer, + encoding: "utf8", + }); + assert.equal(result.status, 0, result.stderr); +} + +function createConsumer(adapterPackages) { + const consumer = mkdtempSync(join(tmpdir(), "mf-tanstack-consumer-")); + const packageTarget = join(consumer, "node_modules", "@module-federation", "tanstack"); + mkdirSync(dirname(packageTarget), { recursive: true }); + cpSync(packageRoot, packageTarget, { + filter: (source) => !source.includes("/node_modules/") && !source.includes("/.turbo/"), + recursive: true, + }); + + for (const packageName of adapterPackages) { + const adapterRoot = findPackageRoot(packageRequire.resolve(packageName)); + const adapterTarget = join(consumer, "node_modules", ...packageName.split("/")); + mkdirSync(dirname(adapterTarget), { recursive: true }); + symlinkSync(adapterRoot, adapterTarget); + } + + return consumer; +} + +function findPackageRoot(entryPoint) { + let directory = dirname(entryPoint); + while (!existsSync(join(directory, "package.json"))) { + const parent = dirname(directory); + if (parent === directory) throw new Error(`Could not find package root for ${entryPoint}`); + directory = parent; + } + return directory; +} + test("CI uses Node versions supported by the package build toolchain", () => { const supportedNode = "^22.18.0 || ^24.11.0 || >=26.0.0"; assert.equal(rootPackageJson.engines.node, supportedNode); @@ -102,6 +290,19 @@ test("CI uses Node versions supported by the package build toolchain", () => { assert.doesNotMatch(ciWorkflow, /22\.12\.0/); }); +test("bundler adapters are isolated optional peers", () => { + for (const dependency of [ + "@module-federation/rsbuild-plugin", + "@module-federation/vite", + "@rsbuild/core", + "vite", + ]) { + assert.ok(packageJson.peerDependencies[dependency], `${dependency} has a peer range`); + assert.equal(packageJson.peerDependenciesMeta[dependency]?.optional, true); + } + assert.equal(packageJson.optionalDependencies, undefined); +}); + test("GitHub prereleases publish the version validated against their tag", () => { assert.match(releaseWorkflow, /Tag\/version mismatch/); assert.doesNotMatch(releaseWorkflow, /Set deterministic prerelease version/); diff --git a/tsconfig.json b/tsconfig.json index 2aa37eb..2292037 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,6 +4,8 @@ "references": [ { "path": "./packages/tanstack/tsconfig.json" }, { "path": "./apps/host/tsconfig.json" }, - { "path": "./apps/remote/tsconfig.json" } + { "path": "./apps/remote/tsconfig.json" }, + { "path": "./apps/rsbuild-host/tsconfig.json" }, + { "path": "./apps/rsbuild-remote/tsconfig.json" } ] } From 6f60ba934bc3bd457301012899ef3a052af29937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9stor?= Date: Fri, 18 Sep 2026 10:43:44 +0200 Subject: [PATCH 4/5] refactor: rename Vite examples --- README.md | 4 +- apps/README.md | 5 +- apps/rsbuild-host/rsbuild.config.ts | 2 +- apps/rsbuild-host/src/routes/index.tsx | 5 +- apps/{host => vite-host}/package.json | 2 +- apps/{host => vite-host}/src/remote.d.ts | 2 +- apps/{host => vite-host}/src/routeTree.gen.ts | 0 apps/{host => vite-host}/src/router.tsx | 0 .../src/routes/__root.tsx | 2 +- apps/{host => vite-host}/src/routes/index.tsx | 8 +-- apps/{host => vite-host}/src/styles.css | 0 apps/{host => vite-host}/tsconfig.json | 0 apps/{host => vite-host}/vite.config.ts | 6 +- apps/{remote => vite-remote}/package.json | 2 +- .../src/components/StatusCard.css | 0 .../src/components/StatusCard.tsx | 0 .../src/routeTree.gen.ts | 0 apps/{remote => vite-remote}/src/router.tsx | 0 .../src/routes/__root.tsx | 2 +- .../src/routes/index.tsx | 0 apps/{remote => vite-remote}/src/styles.css | 0 apps/{remote => vite-remote}/tsconfig.json | 0 apps/{remote => vite-remote}/vite.config.ts | 2 +- docs/RELEASING.md | 2 +- pnpm-lock.yaml | 68 +++++++++---------- test/example-build.test.mjs | 26 +++---- test/example-runtime.test.mjs | 10 +-- tsconfig.json | 4 +- 28 files changed, 78 insertions(+), 74 deletions(-) rename apps/{host => vite-host}/package.json (94%) rename apps/{host => vite-host}/src/remote.d.ts (84%) rename apps/{host => vite-host}/src/routeTree.gen.ts (100%) rename apps/{host => vite-host}/src/router.tsx (100%) rename apps/{remote => vite-host}/src/routes/__root.tsx (93%) rename apps/{host => vite-host}/src/routes/index.tsx (82%) rename apps/{host => vite-host}/src/styles.css (100%) rename apps/{host => vite-host}/tsconfig.json (100%) rename apps/{host => vite-host}/vite.config.ts (88%) rename apps/{remote => vite-remote}/package.json (94%) rename apps/{remote => vite-remote}/src/components/StatusCard.css (100%) rename apps/{remote => vite-remote}/src/components/StatusCard.tsx (100%) rename apps/{remote => vite-remote}/src/routeTree.gen.ts (100%) rename apps/{remote => vite-remote}/src/router.tsx (100%) rename apps/{host => vite-remote}/src/routes/__root.tsx (93%) rename apps/{remote => vite-remote}/src/routes/index.tsx (100%) rename apps/{remote => vite-remote}/src/styles.css (100%) rename apps/{remote => vite-remote}/tsconfig.json (100%) rename apps/{remote => vite-remote}/vite.config.ts (94%) diff --git a/README.md b/README.md index daa6e7c..a49299a 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,8 @@ TanStack Start's standard `dist/server/index.js` entry. ## Example -The workspace includes Vite and Rsbuild pairs. `apps/remote` exposes a -stateful React card to `apps/host`. `apps/rsbuild-remote` exposes a second card +The workspace includes Vite and Rsbuild pairs. `apps/vite-remote` exposes a +stateful React card to `apps/vite-host`. `apps/rsbuild-remote` exposes a second card to the Vite host, while `apps/rsbuild-host` consumes the Vite remote. Both cross-bundler links use manifest URLs. They render after hydration, so this is browser interop coverage, not an unverified SSR interoperability claim. diff --git a/apps/README.md b/apps/README.md index 7f41b71..dbce32d 100644 --- a/apps/README.md +++ b/apps/README.md @@ -2,9 +2,10 @@ Both sides of this example are TanStack Start applications. -- `remote` exposes `./StatusCard` from its Module Federation container and also +- `vite-remote` exposes `./StatusCard` from its Module Federation container and also renders the component on its own `/` route. -- `host` loads `tanstack_remote/StatusCard` from the remote running on port 3001. Its own application runs on port 3000. +- `vite-host` loads `tanstack_vite_remote/StatusCard` from the remote running on + port 3001. Its own application runs on port 3000. From the repository root: diff --git a/apps/rsbuild-host/rsbuild.config.ts b/apps/rsbuild-host/rsbuild.config.ts index 713e8b7..73ad455 100644 --- a/apps/rsbuild-host/rsbuild.config.ts +++ b/apps/rsbuild-host/rsbuild.config.ts @@ -14,7 +14,7 @@ export default defineConfig({ dts: false, name: "tanstack_rsbuild_host", remotes: { - tanstack_remote: "tanstack_remote@http://127.0.0.1:3001/mf-manifest.json", + tanstack_vite_remote: "tanstack_vite_remote@http://127.0.0.1:3001/mf-manifest.json", tanstack_rsbuild_remote: "tanstack_rsbuild_remote@http://127.0.0.1:3002/mf-manifest.json", }, }, diff --git a/apps/rsbuild-host/src/routes/index.tsx b/apps/rsbuild-host/src/routes/index.tsx index 8a5c075..41b643c 100644 --- a/apps/rsbuild-host/src/routes/index.tsx +++ b/apps/rsbuild-host/src/routes/index.tsx @@ -14,7 +14,10 @@ function Home() { fallback="Loading the Rsbuild remote…" remote="tanstack_rsbuild_remote/StatusCard" /> - + ); diff --git a/apps/host/package.json b/apps/vite-host/package.json similarity index 94% rename from apps/host/package.json rename to apps/vite-host/package.json index 1dbba92..65015fb 100644 --- a/apps/host/package.json +++ b/apps/vite-host/package.json @@ -1,5 +1,5 @@ { - "name": "tanstack-start-host", + "name": "tanstack-start-vite-host", "private": true, "sideEffects": false, "type": "module", diff --git a/apps/host/src/remote.d.ts b/apps/vite-host/src/remote.d.ts similarity index 84% rename from apps/host/src/remote.d.ts rename to apps/vite-host/src/remote.d.ts index fe82049..a2c6621 100644 --- a/apps/host/src/remote.d.ts +++ b/apps/vite-host/src/remote.d.ts @@ -1,4 +1,4 @@ -declare module "tanstack_remote/StatusCard" { +declare module "tanstack_vite_remote/StatusCard" { import type { ComponentType } from "react"; const StatusCard: ComponentType; diff --git a/apps/host/src/routeTree.gen.ts b/apps/vite-host/src/routeTree.gen.ts similarity index 100% rename from apps/host/src/routeTree.gen.ts rename to apps/vite-host/src/routeTree.gen.ts diff --git a/apps/host/src/router.tsx b/apps/vite-host/src/router.tsx similarity index 100% rename from apps/host/src/router.tsx rename to apps/vite-host/src/router.tsx diff --git a/apps/remote/src/routes/__root.tsx b/apps/vite-host/src/routes/__root.tsx similarity index 93% rename from apps/remote/src/routes/__root.tsx rename to apps/vite-host/src/routes/__root.tsx index ad43dab..0571218 100644 --- a/apps/remote/src/routes/__root.tsx +++ b/apps/vite-host/src/routes/__root.tsx @@ -8,7 +8,7 @@ export const Route = createRootRoute({ meta: [ { charSet: "utf-8" }, { name: "viewport", content: "width=device-width, initial-scale=1" }, - { title: "TanStack Start federation remote" }, + { title: "TanStack Start federation Vite host" }, ], }), component: RootComponent, diff --git a/apps/host/src/routes/index.tsx b/apps/vite-host/src/routes/index.tsx similarity index 82% rename from apps/host/src/routes/index.tsx rename to apps/vite-host/src/routes/index.tsx index 7a03a21..f124c7c 100644 --- a/apps/host/src/routes/index.tsx +++ b/apps/vite-host/src/routes/index.tsx @@ -1,11 +1,11 @@ import { createFileRoute } from "@tanstack/react-router"; import { lazy, Suspense, useEffect, useState } from "react"; -const RemoteStatusCard = lazy(() => import("tanstack_remote/StatusCard")); +const RemoteStatusCard = lazy(() => import("tanstack_vite_remote/StatusCard")); const RsbuildStatusCard = lazy(() => import("tanstack_rsbuild_remote/StatusCard")); export const Route = createFileRoute("/")({ - loader: () => import("tanstack_remote/StatusCard").then(() => null), + loader: () => import("tanstack_vite_remote/StatusCard").then(() => null), component: Home, }); @@ -16,8 +16,8 @@ function Home() {

TanStack Start × Module Federation

Two full-stack apps. One React tree.

- This page belongs to the host on port 3000. The interactive card below is owned and built - by a second TanStack Start application on port 3001. + This page belongs to the Vite host on port 3000. The interactive card below is owned and + built by a second TanStack Start application on port 3001.

diff --git a/apps/host/src/styles.css b/apps/vite-host/src/styles.css similarity index 100% rename from apps/host/src/styles.css rename to apps/vite-host/src/styles.css diff --git a/apps/host/tsconfig.json b/apps/vite-host/tsconfig.json similarity index 100% rename from apps/host/tsconfig.json rename to apps/vite-host/tsconfig.json diff --git a/apps/host/vite.config.ts b/apps/vite-host/vite.config.ts similarity index 88% rename from apps/host/vite.config.ts rename to apps/vite-host/vite.config.ts index 6832e5a..20fbedc 100644 --- a/apps/host/vite.config.ts +++ b/apps/vite-host/vite.config.ts @@ -6,12 +6,12 @@ import { defineConfig } from "vite"; export default defineConfig({ plugins: [ tanstackStartModuleFederation({ - name: "tanstack_host", + name: "tanstack_vite_host", dts: false, remotes: { - tanstack_remote: { + tanstack_vite_remote: { type: "module", - name: "tanstack_remote", + name: "tanstack_vite_remote", entry: "http://127.0.0.1:3001/remoteEntry.js", }, tanstack_rsbuild_remote: { diff --git a/apps/remote/package.json b/apps/vite-remote/package.json similarity index 94% rename from apps/remote/package.json rename to apps/vite-remote/package.json index 3a5c6a8..74045fe 100644 --- a/apps/remote/package.json +++ b/apps/vite-remote/package.json @@ -1,5 +1,5 @@ { - "name": "tanstack-start-remote", + "name": "tanstack-start-vite-remote", "private": true, "sideEffects": false, "type": "module", diff --git a/apps/remote/src/components/StatusCard.css b/apps/vite-remote/src/components/StatusCard.css similarity index 100% rename from apps/remote/src/components/StatusCard.css rename to apps/vite-remote/src/components/StatusCard.css diff --git a/apps/remote/src/components/StatusCard.tsx b/apps/vite-remote/src/components/StatusCard.tsx similarity index 100% rename from apps/remote/src/components/StatusCard.tsx rename to apps/vite-remote/src/components/StatusCard.tsx diff --git a/apps/remote/src/routeTree.gen.ts b/apps/vite-remote/src/routeTree.gen.ts similarity index 100% rename from apps/remote/src/routeTree.gen.ts rename to apps/vite-remote/src/routeTree.gen.ts diff --git a/apps/remote/src/router.tsx b/apps/vite-remote/src/router.tsx similarity index 100% rename from apps/remote/src/router.tsx rename to apps/vite-remote/src/router.tsx diff --git a/apps/host/src/routes/__root.tsx b/apps/vite-remote/src/routes/__root.tsx similarity index 93% rename from apps/host/src/routes/__root.tsx rename to apps/vite-remote/src/routes/__root.tsx index ab2e206..987b3fc 100644 --- a/apps/host/src/routes/__root.tsx +++ b/apps/vite-remote/src/routes/__root.tsx @@ -8,7 +8,7 @@ export const Route = createRootRoute({ meta: [ { charSet: "utf-8" }, { name: "viewport", content: "width=device-width, initial-scale=1" }, - { title: "TanStack Start federation host" }, + { title: "TanStack Start federation Vite remote" }, ], }), component: RootComponent, diff --git a/apps/remote/src/routes/index.tsx b/apps/vite-remote/src/routes/index.tsx similarity index 100% rename from apps/remote/src/routes/index.tsx rename to apps/vite-remote/src/routes/index.tsx diff --git a/apps/remote/src/styles.css b/apps/vite-remote/src/styles.css similarity index 100% rename from apps/remote/src/styles.css rename to apps/vite-remote/src/styles.css diff --git a/apps/remote/tsconfig.json b/apps/vite-remote/tsconfig.json similarity index 100% rename from apps/remote/tsconfig.json rename to apps/vite-remote/tsconfig.json diff --git a/apps/remote/vite.config.ts b/apps/vite-remote/vite.config.ts similarity index 94% rename from apps/remote/vite.config.ts rename to apps/vite-remote/vite.config.ts index 146faf2..9fd7628 100644 --- a/apps/remote/vite.config.ts +++ b/apps/vite-remote/vite.config.ts @@ -6,7 +6,7 @@ import { defineConfig } from "vite"; export default defineConfig({ plugins: [ tanstackStartModuleFederation({ - name: "tanstack_remote", + name: "tanstack_vite_remote", dts: false, exposes: { "./StatusCard": "./src/components/StatusCard.tsx", diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 909b926..7f536c6 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -42,7 +42,7 @@ a different dist-tag. Configure npm trusted publishing for repository `module-federation/tanstack`, workflow `release.yml`, environment `Publish`. The release gate builds the Vite and Rsbuild example pairs. It checks the Vite -host server bundle and both directions of client manifest interoperability. The +Vite host server bundle and both directions of client manifest interoperability. The Rsbuild example remote is browser-only; package tests cover the adapter's async-node CommonJS SSR configuration. Browser-level coverage for hydrated cross-bundler rendering remains follow-up work. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 38a72c0..0262cbd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,7 +21,7 @@ importers: specifier: 6.0.3 version: 6.0.3 - apps/host: + apps/rsbuild-host: dependencies: '@module-federation/runtime': specifier: 2.9.0 @@ -39,9 +39,18 @@ importers: specifier: 19.3.0 version: 19.3.0(react@19.3.0) devDependencies: + '@module-federation/rsbuild-plugin': + specifier: 2.9.0 + version: 2.9.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) '@module-federation/tanstack': specifier: workspace:* version: link:../../packages/tanstack + '@rsbuild/core': + specifier: 2.2.8 + version: 2.2.8(@module-federation/runtime-tools@2.9.0) + '@rsbuild/plugin-react': + specifier: 2.1.0 + version: 2.1.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23)) '@types/node': specifier: 24.10.1 version: 24.10.1 @@ -51,17 +60,11 @@ importers: '@types/react-dom': specifier: 19.3.0 version: 19.3.0(@types/react@19.3.0) - '@vitejs/plugin-react': - specifier: 6.1.1 - version: 6.1.1(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) typescript: specifier: 6.0.3 version: 6.0.3 - vite: - specifier: 8.3.0 - version: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) - apps/remote: + apps/rsbuild-remote: dependencies: '@module-federation/runtime': specifier: 2.9.0 @@ -79,9 +82,18 @@ importers: specifier: 19.3.0 version: 19.3.0(react@19.3.0) devDependencies: + '@module-federation/rsbuild-plugin': + specifier: 2.9.0 + version: 2.9.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) '@module-federation/tanstack': specifier: workspace:* version: link:../../packages/tanstack + '@rsbuild/core': + specifier: 2.2.8 + version: 2.2.8(@module-federation/runtime-tools@2.9.0) + '@rsbuild/plugin-react': + specifier: 2.1.0 + version: 2.1.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23)) '@types/node': specifier: 24.10.1 version: 24.10.1 @@ -91,17 +103,11 @@ importers: '@types/react-dom': specifier: 19.3.0 version: 19.3.0(@types/react@19.3.0) - '@vitejs/plugin-react': - specifier: 6.1.1 - version: 6.1.1(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) typescript: specifier: 6.0.3 version: 6.0.3 - vite: - specifier: 8.3.0 - version: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) - apps/rsbuild-host: + apps/vite-host: dependencies: '@module-federation/runtime': specifier: 2.9.0 @@ -119,18 +125,9 @@ importers: specifier: 19.3.0 version: 19.3.0(react@19.3.0) devDependencies: - '@module-federation/rsbuild-plugin': - specifier: 2.9.0 - version: 2.9.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) '@module-federation/tanstack': specifier: workspace:* version: link:../../packages/tanstack - '@rsbuild/core': - specifier: 2.2.8 - version: 2.2.8(@module-federation/runtime-tools@2.9.0) - '@rsbuild/plugin-react': - specifier: 2.1.0 - version: 2.1.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23)) '@types/node': specifier: 24.10.1 version: 24.10.1 @@ -140,11 +137,17 @@ importers: '@types/react-dom': specifier: 19.3.0 version: 19.3.0(@types/react@19.3.0) + '@vitejs/plugin-react': + specifier: 6.1.1 + version: 6.1.1(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) typescript: specifier: 6.0.3 version: 6.0.3 + vite: + specifier: 8.3.0 + version: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) - apps/rsbuild-remote: + apps/vite-remote: dependencies: '@module-federation/runtime': specifier: 2.9.0 @@ -162,18 +165,9 @@ importers: specifier: 19.3.0 version: 19.3.0(react@19.3.0) devDependencies: - '@module-federation/rsbuild-plugin': - specifier: 2.9.0 - version: 2.9.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23))(typescript@6.0.3) '@module-federation/tanstack': specifier: workspace:* version: link:../../packages/tanstack - '@rsbuild/core': - specifier: 2.2.8 - version: 2.2.8(@module-federation/runtime-tools@2.9.0) - '@rsbuild/plugin-react': - specifier: 2.1.0 - version: 2.1.0(@rsbuild/core@2.2.8(@module-federation/runtime-tools@2.9.0))(@rspack/core@2.2.6(@module-federation/runtime-tools@2.9.0)(@swc/helpers@0.5.23)) '@types/node': specifier: 24.10.1 version: 24.10.1 @@ -183,9 +177,15 @@ importers: '@types/react-dom': specifier: 19.3.0 version: 19.3.0(@types/react@19.3.0) + '@vitejs/plugin-react': + specifier: 6.1.1 + version: 6.1.1(vite@8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1)) typescript: specifier: 6.0.3 version: 6.0.3 + vite: + specifier: 8.3.0 + version: 8.3.0(@types/node@24.10.1)(jiti@2.7.0)(yaml@2.9.1) packages/tanstack: devDependencies: diff --git a/test/example-build.test.mjs b/test/example-build.test.mjs index 7d05edc..d362d90 100644 --- a/test/example-build.test.mjs +++ b/test/example-build.test.mjs @@ -5,8 +5,8 @@ import { fileURLToPath } from "node:url"; import test from "node:test"; const root = join(dirname(fileURLToPath(import.meta.url)), ".."); -const hostDist = join(root, "apps", "host", "dist"); -const remoteDist = join(root, "apps", "remote", "dist"); +const viteHostDist = join(root, "apps", "vite-host", "dist"); +const viteRemoteDist = join(root, "apps", "vite-remote", "dist"); const rsbuildHostDist = join(root, "apps", "rsbuild-host", "dist"); const rsbuildRemoteDist = join(root, "apps", "rsbuild-remote", "dist"); @@ -16,8 +16,8 @@ function readJson(path) { test("all TanStack Start apps produce client and server builds", () => { for (const [name, dist] of [ - ["host", hostDist], - ["remote", remoteDist], + ["Vite host", viteHostDist], + ["Vite remote", viteRemoteDist], ["rsbuild host", rsbuildHostDist], ["rsbuild remote", rsbuildRemoteDist], ]) { @@ -28,12 +28,12 @@ test("all TanStack Start apps produce client and server builds", () => { }); test("remote publishes browser and server federation entries", () => { - const client = join(remoteDist, "client"); + const client = join(viteRemoteDist, "client"); assert.ok(existsSync(join(client, "remoteEntry.js"))); assert.ok(existsSync(join(client, "remoteEntry.ssr.js"))); const manifest = readJson(join(client, "mf-manifest.json")); - assert.equal(manifest.name, "tanstack_remote"); + assert.equal(manifest.name, "tanstack_vite_remote"); assert.equal(manifest.metaData.remoteEntry.name, "remoteEntry.js"); assert.equal(manifest.metaData.ssrRemoteEntry.name, "remoteEntry.ssr.js"); @@ -47,18 +47,18 @@ test("remote publishes browser and server federation entries", () => { } }); -test("host records the TanStack remote and server-side loader", () => { - const manifest = readJson(join(hostDist, "client", "mf-manifest.json")); - const remote = manifest.remotes.find(({ alias }) => alias === "tanstack_remote"); +test("Vite host records the TanStack remote and server-side loader", () => { + const manifest = readJson(join(viteHostDist, "client", "mf-manifest.json")); + const remote = manifest.remotes.find(({ alias }) => alias === "tanstack_vite_remote"); assert.equal(remote?.moduleName, "StatusCard"); - const serverFiles = readFileSync(join(hostDist, "server", ".vite", "manifest.json"), "utf8"); + const serverFiles = readFileSync(join(viteHostDist, "server", ".vite", "manifest.json"), "utf8"); assert.match(serverFiles, /ssrEntryLoader/); - assert.match(serverFiles, /tanstack_remote/); + assert.match(serverFiles, /tanstack_vite_remote/); }); test("Vite and Rsbuild publish reciprocal client interoperability contracts", () => { - const viteHostManifest = readJson(join(hostDist, "client", "mf-manifest.json")); + const viteHostManifest = readJson(join(viteHostDist, "client", "mf-manifest.json")); const rsbuildHostManifest = readJson(join(rsbuildHostDist, "client", "mf-manifest.json")); const rsbuildRemoteClient = readJson(join(rsbuildRemoteDist, "client", "mf-manifest.json")); @@ -67,7 +67,7 @@ test("Vite and Rsbuild publish reciprocal client interoperability contracts", () "StatusCard", ); assert.equal( - rsbuildHostManifest.remotes.find(({ alias }) => alias === "tanstack_remote")?.entry, + rsbuildHostManifest.remotes.find(({ alias }) => alias === "tanstack_vite_remote")?.entry, "http://127.0.0.1:3001/mf-manifest.json", ); assert.equal( diff --git a/test/example-runtime.test.mjs b/test/example-runtime.test.mjs index 54b5a67..a09ba30 100644 --- a/test/example-runtime.test.mjs +++ b/test/example-runtime.test.mjs @@ -71,8 +71,8 @@ async function stopApp(child) { } } -test("host server-renders a component from the TanStack remote", async () => { - const remote = startApp("tanstack-start-remote"); +test("Vite host server-renders a component from the Vite remote", async () => { + const remote = startApp("tanstack-start-vite-remote"); let host; try { @@ -83,7 +83,7 @@ test("host server-renders a component from the TanStack remote", async () => { ); assert.match(remoteEntry.body, /virtual:mf-exposes/); - host = startApp("tanstack-start-host"); + host = startApp("tanstack-start-vite-host"); const response = await waitForResponse( "http://127.0.0.1:3000/", host, @@ -99,7 +99,7 @@ test("host server-renders a component from the TanStack remote", async () => { }); test("Vite and Rsbuild hosts serve reciprocal browser-interoperability shells", async () => { - const viteRemote = startApp("tanstack-start-remote"); + const viteRemote = startApp("tanstack-start-vite-remote"); const rsbuildRemote = startApp("tanstack-start-rsbuild-remote"); let viteHost; let rsbuildHost; @@ -117,7 +117,7 @@ test("Vite and Rsbuild hosts serve reciprocal browser-interoperability shells", ); assert.match(manifest.body, /tanstack_rsbuild_remote/); - viteHost = startApp("tanstack-start-host"); + viteHost = startApp("tanstack-start-vite-host"); rsbuildHost = startApp("tanstack-start-rsbuild-host"); const viteResponse = await waitForResponse( diff --git a/tsconfig.json b/tsconfig.json index 2292037..50148eb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,8 +3,8 @@ "files": [], "references": [ { "path": "./packages/tanstack/tsconfig.json" }, - { "path": "./apps/host/tsconfig.json" }, - { "path": "./apps/remote/tsconfig.json" }, + { "path": "./apps/vite-host/tsconfig.json" }, + { "path": "./apps/vite-remote/tsconfig.json" }, { "path": "./apps/rsbuild-host/tsconfig.json" }, { "path": "./apps/rsbuild-remote/tsconfig.json" } ] From c73cf94bda433eb90cbfffa4471857b91a1a40ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9stor?= Date: Fri, 18 Sep 2026 11:16:19 +0200 Subject: [PATCH 5/5] docs: detail SSR completion work --- TODO.md | 285 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..47d2940 --- /dev/null +++ b/TODO.md @@ -0,0 +1,285 @@ +# SSR completion TODO + +This file tracks the work required before `@module-federation/tanstack` can +claim SSR support across both Vite and Rsbuild/Rspack. + +Assessment date: 2026-09-18. + +## Current support boundary + +| Host | Remote | Federated SSR status | Current proof | +| ------- | ------- | -------------------- | ------------------------------------------------------------------------------- | +| Vite | Vite | Supported | The Vite host response contains remote markup before hydration. | +| Vite | Rsbuild | Not supported | The Rsbuild remote loads in the browser after hydration. | +| Rsbuild | Vite | Not supported | The Vite remote loads through the browser runtime after hydration. | +| Rsbuild | Rsbuild | Not yet supported | The adapter can build a server container, but no end-to-end SSR fixture exists. | + +The Rsbuild examples are TanStack Start SSR applications, so their local route +shells render on the server. Their Module Federation configuration passes +`server: false`; federated components are client-only. Do not describe that as +federated SSR. + +The supported claim today is: + +> Vite-to-Vite federated SSR, plus Vite/Rsbuild browser interoperability. + +## Evidence behind this boundary + +### Vite-to-Vite SSR works + +- [`packages/tanstack/src/vite.ts`](packages/tanstack/src/vite.ts) registers one + Vite federation plugin for TanStack Start's client and server environments. +- The wrapper leaves `target` unset so `@module-federation/vite` selects `web` + for the client and `node` for SSR. +- `hostInitInjectLocation: "entry"` initializes federation before TanStack + hydrates an application without an `index.html` entry. +- `module-federation/vite` enables its SSR entry loader for every production + build and for Vite 8 development. Vite 7 development does not have the + ModuleRunner support required by this path. +- Vite remotes emit a separate ESM `remoteEntry.ssr.js` and include it in + `mf-manifest.json` as `metaData.ssrRemoteEntry`. +- The Vite SSR loader resolves the manifest entry, links shared packages to the + host, and evaluates the remote through Vite ModuleRunner, `vm.SourceTextModule`, + or a temporary ESM graph. +- [`test/example-runtime.test.mjs`](test/example-runtime.test.mjs) verifies that + the Vite host's initial HTML contains `Owned by the remote app` and + `Rendered on the server`. + +Reference implementation paths: + +- `module-federation/vite/src/utils/ssrCapabilities.ts` +- `module-federation/vite/src/plugins/pluginSSRRemoteEntry.ts` +- `module-federation/vite/src/utils/ssrEntryLoader.ts` +- `module-federation/vite/src/plugins/pluginAddEntry.ts` +- `module-federation/vite/src/virtualModules/virtualRuntimeInitStatus.ts` + +### Rsbuild has the required pieces, but not the proof + +- [`packages/tanstack/src/rsbuild.ts`](packages/tanstack/src/rsbuild.ts) installs + separate `web` and `node` federation plugins for TanStack Start's `client` + and `ssr` environments. +- The browser compiler emits script/JSONP-compatible output. +- The server compiler can emit async-node CommonJS output with + `serverRemoteEntry.cjs` and `dist/server/index.cjs`. +- React and React DOM default to eager singletons for Rsbuild. TanStack's server + bundle imports React synchronously, and Core reports `RUNTIME-006` when those + shares are lazy. +- Core's `target: "node"` path changes the compiler target to `async-node`, + creates a CommonJS server container, and injects + `@module-federation/node/runtimePlugin`. +- Core only installs its startup dependency handling when + `experiments.asyncStartup` is enabled. The TanStack adapter does not default + this option today. +- Both committed Rsbuild examples pass `server: false`, so the server adapter is + covered by compiler-contract tests, not by a running host/remote pair. + +Reference implementation paths: + +- `module-federation/core/packages/rsbuild-plugin/src/cli/index.ts` +- `module-federation/core/packages/rsbuild-plugin/src/utils/ssr.ts` +- `module-federation/core/packages/node/src/runtimePlugin.ts` +- `module-federation/core/packages/enhanced/src/lib/container/ModuleFederationPlugin.ts` +- `module-federation/core/packages/webpack-bundler-runtime/src/installInitialConsumes.ts` + +### Cross-bundler SSR needs an explicit transport contract + +The two server entry formats differ: + +- Vite emits an ESM SSR entry and an ESM dependency graph. +- The current Rsbuild adapter emits a CommonJS container and async-node chunks. + +The Vite loader can `require()` a local CommonJS entry. For an HTTP CommonJS +entry, `createRequire()` cannot load the URL, and the loader falls through to +paths designed around ESM source. That is not a reliable Rsbuild remote loader. + +In the other direction, Core's Node runtime has ESM loading support, but this +repository does not prove that an Rsbuild host can load Vite's manifest-declared +ESM SSR entry, preserve the host React instance, and hydrate the result. + +## Phase 1: finish Rsbuild-to-Rsbuild SSR + +### Adapter defaults + +- [ ] Merge `experiments.asyncStartup: true` into the Rsbuild browser and server + federation options. +- [ ] Preserve an explicit `experiments.asyncStartup: false` override. +- [ ] Keep `react` and `react-dom` eager singletons by default. +- [ ] Cover React subpaths used by the compiled application, including + `react/jsx-runtime` and `react-dom/client`, without creating a second React + instance. +- [ ] Assert that Core's node target injects the Node runtime plugin exactly + once. +- [ ] Confirm that two environment-scoped Rsbuild plugins continue to install + one browser container and one server container. + +### Server-enabled fixtures + +- [ ] Add a dedicated Rsbuild remote with the server adapter enabled. +- [ ] Expose a stateful component from both `remoteEntry.js` and + `serverRemoteEntry.cjs`. +- [ ] Add a dedicated Rsbuild host with the server adapter enabled. +- [ ] Import the remote through a route loader or another real async boundary. +- [ ] Start the production remote from `dist/server/index.cjs`. +- [ ] Serve the client manifest, server entry, server chunks, JavaScript, CSS, + and federated type archive from stable URLs. +- [ ] Start the production host from `dist/server/index.cjs`. +- [ ] Ensure development and production use the same remote naming and share + scope. + +### Rsbuild SSR acceptance criteria + +- [ ] The host's initial HTML contains remote component markup. +- [ ] The initial HTML does not contain only a loading placeholder. +- [ ] Hydration completes without warnings or subtree replacement. +- [ ] A remote button remains interactive after hydration. +- [ ] Host context and hooks work inside the remote component. +- [ ] React and React DOM resolve to one physical host-owned instance. +- [ ] No `RUNTIME-006`, `RUNTIME-001`, or missing chunk error appears. +- [ ] The remote manifest declares a `commonjs-module` server entry. +- [ ] Every server entry import and async chunk is reachable in production. +- [ ] The built server output contains no build-machine absolute paths. + +## Phase 2: support a Vite host with an Rsbuild SSR remote + +Choose and document one server-entry strategy before implementing this path. + +### Option A: emit an ESM SSR entry from Rsbuild + +This aligns the remote with the existing Vite SSR loader. + +- [ ] Determine whether the Rsbuild server compiler can emit a second ESM + container without changing the CommonJS entry used by Rsbuild hosts. +- [ ] Decide how the manifest identifies both server formats. The current + manifest has one `ssrRemoteEntry` slot. +- [ ] Keep server chunks portable and reachable over HTTP. +- [ ] Verify that Vite's temporary-file and VM strategies can link the emitted + graph. + +### Option B: teach the Vite loader to evaluate HTTP CommonJS containers + +This aligns the host with the existing Rsbuild server output. + +- [ ] Add a bounded HTTP CommonJS loader rather than passing an HTTP URL to + `createRequire()`. +- [ ] Reuse Core's Node chunk-loading behavior where possible. +- [ ] Resolve relative async chunks from the remote public path. +- [ ] Preserve Node module-cache identity for React and other singletons. +- [ ] Apply the same fetch timeout and maximum-body limits used by the ESM + loader. +- [ ] Avoid unrestricted `eval` or unbounded code fetching. + +### Vite-host acceptance criteria + +- [ ] Vite 8 development renders the Rsbuild remote into initial HTML. +- [ ] Vite 8 production renders and hydrates the same remote. +- [ ] Vite 7 production works, or the package documents a narrower requirement. +- [ ] Remote CSS appears before or during hydration without a layout flash. +- [ ] Manifest revalidation replaces a changed remote without restarting the + host process. + +## Phase 3: support an Rsbuild host with a Vite SSR remote + +- [ ] Confirm that Core's Node runtime selects `metaData.ssrRemoteEntry` instead + of the browser entry in a Vite manifest. +- [ ] Confirm support for a manifest entry whose type is `module`. +- [ ] Load Vite's transitive ESM chunks without Node network-import flags. +- [ ] Map shared package imports to the Rsbuild host share scope. +- [ ] Remove any dependency on `--experimental-vm-modules` from the supported + default path. +- [ ] Verify development against Vite's `/__mf_ssr__/` and ModuleRunner + endpoints. +- [ ] Verify production against the built `remoteEntry.ssr.js` graph. + +### Rsbuild-host acceptance criteria + +- [ ] The Rsbuild host's initial HTML contains Vite remote markup. +- [ ] Hydration preserves that markup and remote state. +- [ ] The Node runtime reports no missing module, VM import, or chunk execution + error. +- [ ] A remote outage returns a controlled fallback instead of a 500 response. + +## Phase 4: shared identity and recovery hardening + +### Shared dependencies + +- [ ] Test React context created by the host and consumed by every remote. +- [ ] Test `useState`, `useEffect`, Suspense, and error boundaries across the + federation boundary. +- [ ] Test React 18 and React 19 if both remain in the support range. +- [ ] Validate version mismatch warnings for incompatible React majors. +- [ ] Ensure `import: false` fails at startup when the host cannot provide the + required package. + +### Remote lifecycle + +- [ ] Start the host while the remote is unavailable. +- [ ] Bring the remote online and prove that a later request recovers. +- [ ] Restart the remote with a new manifest and server entry. +- [ ] Revalidate without serving a stale container or stale shared module. +- [ ] Test concurrent first requests while the remote entry is loading. +- [ ] Test cyclic imports in the server remote graph. + +### Error reporting + +- [ ] Preserve the original network or execution error. +- [ ] Distinguish manifest failure, entry failure, chunk failure, and shared + dependency failure. +- [ ] Add optional observability reports for raw runtime codes that do not + contain enough context. + +## Required test matrix + +| Host | Remote | Development | Production | Initial remote HTML | Hydration and interaction | +| --------- | --------- | ------------ | ---------- | ------------------- | ------------------------- | +| Vite 8 | Vite 8 | Existing | Existing | Existing | Add browser assertion | +| Vite 7 | Vite 7 | Not required | Add | Add | Add | +| Rsbuild 2 | Rsbuild 2 | Add | Add | Add | Add | +| Vite 8 | Rsbuild 2 | Add | Add | Add | Add | +| Rsbuild 2 | Vite 8 | Add | Add | Add | Add | + +Run the production matrix on every supported Node line: + +- [ ] Node 22.18 +- [ ] Node 24 +- [ ] Node 26 + +Each matrix row must verify: + +- [ ] manifest and remote entry return 200; +- [ ] every manifest-referenced asset returns 200; +- [ ] initial HTML contains the expected remote marker; +- [ ] hydration produces no console errors or mismatch warnings; +- [ ] remote interaction updates state; +- [ ] host and remote use one React dispatcher; +- [ ] shutting down the remote produces the documented fallback; +- [ ] restarting the remote allows recovery. + +## Documentation and release work + +- [ ] Update the root README only after a matrix row satisfies every acceptance + criterion. +- [ ] Document `server: false` as browser-only federation, not SSR federation. +- [ ] Document `dist/server/index.cjs` when the CommonJS Rsbuild server adapter + is enabled. +- [ ] Document the chosen cross-bundler server-entry format. +- [ ] Keep Vite 8 as the development SSR requirement unless Vite 7 gains an + equivalent ModuleRunner path. +- [ ] Add a Changeset for any new supported SSR combination. +- [ ] Include the tested bundler and Node version matrix in the release notes. + +## Definition of done + +SSR support for a host/remote combination is complete only when: + +- [ ] the remote is rendered into the host's initial HTML; +- [ ] the same markup hydrates without replacement; +- [ ] the remote remains interactive; +- [ ] shared React identity is proven; +- [ ] development and production both pass where claimed; +- [ ] remote outage and recovery behavior are tested; +- [ ] server entries and all chunks are deployable without local paths; +- [ ] the supported versions are documented; +- [ ] CI runs the proof on every supported Node line. + +Until then, keep the package description precise: Vite-to-Vite SSR is supported; +Rsbuild and cross-bundler SSR are in progress.