diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 46fc1a810..2414020f1 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -517,6 +517,11 @@ jobs: - project: production shard: 2 shardTotal: 2 + - project: preload-dev + config: playwright.preload.config.ts + - project: preload-production + config: playwright.preload.config.ts + noDeps: true # HMR tests run serially (workers=1) to avoid filesystem interference. # hmr-routes (route-types-hmr.test.ts) is intentionally absent: it is # test.skip(isCI)'d because the file watcher is unreliable on GitHub @@ -570,6 +575,10 @@ jobs: # HOST_ONLY in playwright.config.ts, skips the heavy test-app servers). RANGO_E2E_HOST: ${{ matrix.project == 'host' && '1' || '' }} run: | + CONFIG_FLAG="" + if [ -n "${{ matrix.config }}" ]; then + CONFIG_FLAG="--config=${{ matrix.config }}" + fi WORKERS_FLAG="" if [ -n "${{ matrix.workers }}" ]; then WORKERS_FLAG="--workers=${{ matrix.workers }}" @@ -578,13 +587,13 @@ jobs: # so skip dependency projects (dev, build, warmup) that would # re-run hundreds of unrelated tests and blow the timeout. NO_DEPS_FLAG="" - if [[ "${{ matrix.project }}" == hmr-* ]]; then + if [ -n "${{ matrix.noDeps }}" ] || [[ "${{ matrix.project }}" == hmr-* ]]; then NO_DEPS_FLAG="--no-deps" fi if [ -n "${{ matrix.shard }}" ]; then - pnpm --filter @rangojs/router test --project=${{ matrix.project }} --shard=${{ matrix.shard }}/${{ matrix.shardTotal }} $WORKERS_FLAG $NO_DEPS_FLAG + pnpm --filter @rangojs/router test $CONFIG_FLAG --project=${{ matrix.project }} --shard=${{ matrix.shard }}/${{ matrix.shardTotal }} $WORKERS_FLAG $NO_DEPS_FLAG else - pnpm --filter @rangojs/router test --project=${{ matrix.project }} $WORKERS_FLAG $NO_DEPS_FLAG + pnpm --filter @rangojs/router test $CONFIG_FLAG --project=${{ matrix.project }} $WORKERS_FLAG $NO_DEPS_FLAG fi - name: Upload test results @@ -639,6 +648,11 @@ jobs: shard: 2 shardTotal: 2 noDeps: true + - project: preload-dev + config: playwright.preload.config.ts + - project: preload-production + config: playwright.preload.config.ts + noDeps: true # HMR runs in its own job: --no-deps (its deps are the full dev + # production suites) and workers=1. workers=1 is load-bearing, not # cosmetic: hmr.test.ts and hmr-route-mutations.test.ts both git-checkout @@ -682,6 +696,10 @@ jobs: env: TEST_DEBUG: "1" run: | + CONFIG_FLAG="" + if [ -n "${{ matrix.config }}" ]; then + CONFIG_FLAG="--config=${{ matrix.config }}" + fi SHARD_FLAG="" if [ -n "${{ matrix.shard }}" ]; then SHARD_FLAG="--shard=${{ matrix.shard }}/${{ matrix.shardTotal }}" @@ -697,7 +715,7 @@ jobs: if [ -n "${{ matrix.noDeps }}" ]; then NO_DEPS_FLAG="--no-deps" fi - pnpm --filter cloudflare-basic test:e2e --project=${{ matrix.project }} $SHARD_FLAG $WORKERS_FLAG $NO_DEPS_FLAG + pnpm --filter cloudflare-basic test:e2e $CONFIG_FLAG --project=${{ matrix.project }} $SHARD_FLAG $WORKERS_FLAG $NO_DEPS_FLAG - name: Upload test results uses: actions/upload-artifact@v6 diff --git a/package.json b/package.json index 1fc9819e9..71570d27c 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "test:unit": "pnpm -r --if-present run test:unit", "test:unit:rsc": "pnpm -r --if-present run test:unit:rsc", "test:unit:all": "pnpm run test:unit && pnpm run test:unit:rsc", - "test:e2e": "pnpm --filter @rangojs/router test && pnpm --filter vite-rsc-demo test:full && pnpm --filter cloudflare-basic test:e2e && pnpm --filter cloudflare-basic-nonce test:e2e && pnpm --filter cloudflare-multi-router test:e2e && pnpm --filter react-experimental test:e2e && pnpm --filter no-typescript test:e2e && pnpm --filter rangojs-vercel-basic test:e2e", + "test:e2e": "pnpm --filter @rangojs/router test && pnpm --filter @rangojs/router test:preload && pnpm --filter vite-rsc-demo test:full && pnpm --filter cloudflare-basic test:e2e && pnpm --filter cloudflare-basic test:e2e:preload && pnpm --filter cloudflare-basic-nonce test:e2e && pnpm --filter cloudflare-multi-router test:e2e && pnpm --filter react-experimental test:e2e && pnpm --filter no-typescript test:e2e && pnpm --filter rangojs-vercel-basic test:e2e", "test:hmr-local": "pnpm --filter @rangojs/router build && pnpm --filter @rangojs/router run test:hmr-local && pnpm --filter cloudflare-basic run test:e2e:hmr-local", "build-router": "pnpm --filter @rangojs/router build", "prepare": "lefthook install" diff --git a/packages/rangojs-router/docs/design/ppr-shell-resume.md b/packages/rangojs-router/docs/design/ppr-shell-resume.md index 9ca9c93cf..207305adb 100644 --- a/packages/rangojs-router/docs/design/ppr-shell-resume.md +++ b/packages/rangojs-router/docs/design/ppr-shell-resume.md @@ -17,7 +17,7 @@ render and every upstream read it needs. React 19.2 shipped Partial Pre-rendering in **stable**: `prerender` from `react-dom/static` returns `{ prelude, postponed }` when aborted mid-suspense, and `resume` from `react-dom/server` continues that exact render, emitting only -the postponed holes. The repo's pinned react/react-dom/vendored RSD (19.2.6) +the postponed holes. The repo's pinned react/react-dom/vendored RSD (19.2.8) all carry the full surface — verified by runtime probe, not just export lists. So: cache the rendered HTML **prelude** plus the postponed state, serve those diff --git a/packages/rangojs-router/e2e/client-package-resolution.test.ts b/packages/rangojs-router/e2e/client-package-resolution.test.ts new file mode 100644 index 000000000..f137d44f5 --- /dev/null +++ b/packages/rangojs-router/e2e/client-package-resolution.test.ts @@ -0,0 +1,61 @@ +import { expect, test } from "@playwright/test"; +import { useFixture } from "./fixture"; +import { expectNoPageError, testId, waitForHydration } from "./helper"; + +test.describe("client package resolution", () => { + const f = useFixture({ root: "./e2e/test-app", mode: "dev" }); + + test("preserves the deep context in server HTML", async ({ request }) => { + const response = await request.get(f.url("/client-package-resolution"), { + headers: { Accept: "text/html,application/xhtml+xml" }, + }); + expect(response.status()).toBe(200); + + const html = await response.text(); + expect(html).toContain("deep-context-value"); + expect(html).not.toContain("NOT_FOUND"); + }); + + test("preserves the deep context after hydration", async ({ page }) => { + using _ = expectNoPageError(page); + + await page.goto(f.url("/client-package-resolution")); + await waitForHydration(page); + + await expect(testId(page, "deep-context-value")).toHaveText( + "deep-context-value", + ); + await expect(testId(page, "deep-context-value")).not.toHaveText( + "NOT_FOUND", + ); + }); +}); + +test.describe("client package resolution (production)", () => { + const f = useFixture({ root: "./e2e/test-app", mode: "build" }); + + test("preserves the deep context in server HTML", async ({ request }) => { + const response = await request.get(f.url("/client-package-resolution"), { + headers: { Accept: "text/html,application/xhtml+xml" }, + }); + expect(response.status()).toBe(200); + + const html = await response.text(); + expect(html).toContain("deep-context-value"); + expect(html).not.toContain("NOT_FOUND"); + }); + + test("preserves the deep context after hydration", async ({ page }) => { + using _ = expectNoPageError(page); + + await page.goto(f.url("/client-package-resolution")); + await waitForHydration(page); + + await expect(testId(page, "deep-context-value")).toHaveText( + "deep-context-value", + ); + await expect(testId(page, "deep-context-value")).not.toHaveText( + "NOT_FOUND", + ); + }); +}); diff --git a/packages/rangojs-router/e2e/head-script-preload-warmup.setup.ts b/packages/rangojs-router/e2e/head-script-preload-warmup.setup.ts new file mode 100644 index 000000000..47dc4b6dd --- /dev/null +++ b/packages/rangojs-router/e2e/head-script-preload-warmup.setup.ts @@ -0,0 +1,17 @@ +import { test as setup, expect } from "@playwright/test"; + +setup("warmup preload dev server", async ({ page, baseURL }) => { + setup.setTimeout(60_000); + + await expect(async () => { + const first = await page.goto(new URL("/", baseURL).href); + expect(first?.ok()).toBe(true); + + const second = await page.reload(); + expect(second?.ok()).toBe(true); + await page.waitForFunction( + () => document.documentElement.hasAttribute("data-hydrated"), + { timeout: 10_000 }, + ); + }).toPass({ timeout: 45_000, intervals: [2_000, 3_000, 5_000] }); +}); diff --git a/packages/rangojs-router/e2e/head-script-preload.test.ts b/packages/rangojs-router/e2e/head-script-preload.test.ts new file mode 100644 index 000000000..ba8acbcad --- /dev/null +++ b/packages/rangojs-router/e2e/head-script-preload.test.ts @@ -0,0 +1,88 @@ +import test, { expect, type Page } from "@playwright/test"; +import { + fetchDocument, + modulepreloadHrefs, + scriptAndLinkTags, +} from "@shared/e2e"; +import { blockPrefetch } from "@rangojs/router/testing/e2e"; +import { useFixture } from "./fixture"; +import { expectNoPageError, waitForHydration } from "./helper"; + +function assertPreloadDocument( + html: string, + requireClientReferenceHint: boolean, +): void { + const headEnd = html.indexOf(""); + expect(headEnd).toBeGreaterThan(0); + const head = html.slice(0, headEnd); + const externalModuleScripts = scriptAndLinkTags(head).filter( + (tag) => + tag.startsWith("]*>([\s\S]*?)<\/script>/, + ); + expect( + bootstrap, + "the inline fizz bootstrap script is present", + ).not.toBeNull(); + const tagEnd = bootstrap![0].indexOf(">"); + const tag = bootstrap![0].slice(0, tagEnd + 1); + expect(tag).not.toContain('src="'); + const entryImport = bootstrap![1]!.match( + /\bimport\(\s*(["'])([^"']+)\1\s*\)/, + ); + expect( + entryImport, + "the inline bootstrap imports the browser entry", + ).not.toBeNull(); + + if (requireClientReferenceHint) { + const browserEntryUrl = entryImport![2]!; + const clientReferenceHrefs = modulepreloadHrefs(html).filter( + (href) => href !== browserEntryUrl, + ); + expect(clientReferenceHrefs.length).toBeGreaterThan(0); + } +} + +async function expectCleanHydration(page: Page, url: string): Promise { + using _ = expectNoPageError(page); + await blockPrefetch(page); + const consoleErrors: string[] = []; + page.on("console", (message) => { + if (message.type() === "error") consoleErrors.push(message.text()); + }); + + await page.goto(url); + await waitForHydration(page); + expect(consoleErrors).toEqual([]); +} + +test.describe("head-script-preload", () => { + const f = useFixture({ root: "./e2e/test-app", mode: "dev" }); + + test("uses an inline bootstrap without executing external head scripts", async () => { + assertPreloadDocument(await fetchDocument(f.url("/")), false); + }); + + test("hydrates without browser errors", async ({ page }) => { + await expectCleanHydration(page, f.url("/")); + }); +}); + +test.describe("head-script-preload (production)", () => { + const f = useFixture({ root: "./e2e/test-app", mode: "build" }); + + test("keeps client-reference hints with an inline bootstrap", async () => { + assertPreloadDocument(await fetchDocument(f.url("/")), true); + }); + + test("hydrates without browser errors", async ({ page }) => { + await expectCleanHydration(page, f.url("/")); + }); +}); diff --git a/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/index.d.ts b/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/index.d.ts new file mode 100644 index 000000000..40a09f224 --- /dev/null +++ b/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/index.d.ts @@ -0,0 +1,10 @@ +import type { ReactNode } from "react"; + +export interface DeepContextServerWrapperProps { + children: ReactNode; + value: string; +} + +export function DeepContextServerWrapper( + props: DeepContextServerWrapperProps, +): ReactNode; diff --git a/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/index.js b/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/index.js new file mode 100644 index 000000000..3ca338afe --- /dev/null +++ b/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/index.js @@ -0,0 +1,6 @@ +import { createElement } from "react"; +import { DeepContextProvider } from "./internal/context.js"; + +export function DeepContextServerWrapper({ children, value }) { + return createElement(DeepContextProvider, { value }, children); +} diff --git a/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/internal/context.d.ts b/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/internal/context.d.ts new file mode 100644 index 000000000..ae2051c3b --- /dev/null +++ b/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/internal/context.d.ts @@ -0,0 +1,9 @@ +import type { ReactNode } from "react"; + +export interface DeepContextProviderProps { + children: ReactNode; + value: string; +} + +export function DeepContextProvider(props: DeepContextProviderProps): ReactNode; +export function useDeepContext(): string | undefined; diff --git a/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/internal/context.js b/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/internal/context.js new file mode 100644 index 000000000..393cb826d --- /dev/null +++ b/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/internal/context.js @@ -0,0 +1,13 @@ +"use client"; + +import { createContext, createElement, useContext } from "react"; + +const DeepContext = createContext(undefined); + +export function DeepContextProvider({ children, value }) { + return createElement(DeepContext.Provider, { value }, children); +} + +export function useDeepContext() { + return useContext(DeepContext); +} diff --git a/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/package.json b/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/package.json new file mode 100644 index 000000000..3815fd53d --- /dev/null +++ b/packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib/package.json @@ -0,0 +1,18 @@ +{ + "name": "rango-e2e-deep-context-lib", + "version": "1.0.0", + "type": "module", + "exports": { + ".": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "./context": { + "types": "./internal/context.d.ts", + "default": "./internal/context.js" + } + }, + "peerDependencies": { + "react": ">=19" + } +} diff --git a/packages/rangojs-router/e2e/test-app/package.json b/packages/rangojs-router/e2e/test-app/package.json index 350507b9d..cc14de188 100644 --- a/packages/rangojs-router/e2e/test-app/package.json +++ b/packages/rangojs-router/e2e/test-app/package.json @@ -15,6 +15,7 @@ "dependencies": { "@rangojs/router": "workspace:*", "fake-context-lib": "file:__test_packages__/fake-context-lib", + "rango-e2e-deep-context-lib": "file:__test_packages__/rango-e2e-deep-context-lib", "react": "catalog:", "react-dom": "catalog:" }, diff --git a/packages/rangojs-router/e2e/test-app/src/components/ClientPackageResolutionConsumer.tsx b/packages/rangojs-router/e2e/test-app/src/components/ClientPackageResolutionConsumer.tsx new file mode 100644 index 000000000..6a8a0f62e --- /dev/null +++ b/packages/rangojs-router/e2e/test-app/src/components/ClientPackageResolutionConsumer.tsx @@ -0,0 +1,10 @@ +"use client"; + +import { useDeepContext } from "rango-e2e-deep-context-lib/context"; +import type { ReactNode } from "react"; + +export function ClientPackageResolutionConsumer(): ReactNode { + return ( +

{useDeepContext() ?? "NOT_FOUND"}

+ ); +} diff --git a/packages/rangojs-router/e2e/test-app/src/components/layouts/ClientPackageResolutionLayout.tsx b/packages/rangojs-router/e2e/test-app/src/components/layouts/ClientPackageResolutionLayout.tsx new file mode 100644 index 000000000..85f15e88a --- /dev/null +++ b/packages/rangojs-router/e2e/test-app/src/components/layouts/ClientPackageResolutionLayout.tsx @@ -0,0 +1,11 @@ +import { Outlet } from "@rangojs/router/client"; +import { DeepContextServerWrapper } from "rango-e2e-deep-context-lib"; +import type { ReactNode } from "react"; + +export function ClientPackageResolutionLayout(): ReactNode { + return ( + + + + ); +} diff --git a/packages/rangojs-router/e2e/test-app/src/router.named-routes.gen.ts b/packages/rangojs-router/e2e/test-app/src/router.named-routes.gen.ts index 99f6c8e30..4108f55f8 100644 --- a/packages/rangojs-router/e2e/test-app/src/router.named-routes.gen.ts +++ b/packages/rangojs-router/e2e/test-app/src/router.named-routes.gen.ts @@ -85,6 +85,7 @@ export const NamedRoutes = { "clientIntercept.detail": "/client-urls-intercept/detail/:itemId", "clientIntercept.index": "/client-urls-intercept", "clientIntercept.item": "/client-urls-intercept/items/:itemId", + "clientPackageResolution.clientPackageResolutionIndex": "/client-package-resolution", "clientTransition.item": "/client-urls-transition/items/:itemId", "clientTransition.plain": "/client-urls-transition/plain/:itemId", "colocatedFr.index": "/colocated-fr", diff --git a/packages/rangojs-router/e2e/test-app/src/urls.tsx b/packages/rangojs-router/e2e/test-app/src/urls.tsx index e92c6584e..88031c742 100644 --- a/packages/rangojs-router/e2e/test-app/src/urls.tsx +++ b/packages/rangojs-router/e2e/test-app/src/urls.tsx @@ -96,6 +96,7 @@ import { alsScopePatterns } from "./urls/als-scope.js"; import { streamModePatterns } from "./urls/stream-mode.js"; import { devDebugPatterns, devInfoHandler } from "./urls/dev-routes.js"; import { contextDedupPatterns } from "./urls/context-dedup.js"; +import { clientPackageResolutionPatterns } from "./urls/client-package-resolution.js"; import { parallelMetaPatterns } from "./urls/parallel-meta.js"; import { parallelMetaStalePatterns } from "./urls/parallel-meta-stale.js"; import { renderedBarrierPatterns } from "./urls/rendered-barrier.js"; @@ -1599,6 +1600,10 @@ export const urlpatterns = urls( name: "contextDedup", }), + include("/client-package-resolution", clientPackageResolutionPatterns, { + name: "clientPackageResolution", + }), + // @meta parallel slot pattern (handles from parallel slots) include("/parallel-meta", parallelMetaPatterns, { name: "parallelMeta", diff --git a/packages/rangojs-router/e2e/test-app/src/urls/client-package-resolution.tsx b/packages/rangojs-router/e2e/test-app/src/urls/client-package-resolution.tsx new file mode 100644 index 000000000..8364104f2 --- /dev/null +++ b/packages/rangojs-router/e2e/test-app/src/urls/client-package-resolution.tsx @@ -0,0 +1,11 @@ +import { urls } from "@rangojs/router"; +import { ClientPackageResolutionConsumer } from "../components/ClientPackageResolutionConsumer.js"; +import { ClientPackageResolutionLayout } from "../components/layouts/ClientPackageResolutionLayout.js"; + +export const clientPackageResolutionPatterns = urls(({ path, layout }) => [ + layout(ClientPackageResolutionLayout, () => [ + path("/", () => , { + name: "clientPackageResolutionIndex", + }), + ]), +]); diff --git a/packages/rangojs-router/e2e/test-app/vite.config.ts b/packages/rangojs-router/e2e/test-app/vite.config.ts index 73a6b3d46..dadcac1ff 100644 --- a/packages/rangojs-router/e2e/test-app/vite.config.ts +++ b/packages/rangojs-router/e2e/test-app/vite.config.ts @@ -6,6 +6,15 @@ import devtoolsJson from "vite-plugin-devtools-json"; import { analyze } from "../../../../tools/bundle-analyze"; import { productionDefines } from "../../../../tools/vite-define"; +function testHeadScripts(): "preload" | undefined { + const value = process.env.RANGO_E2E_HEAD_SCRIPTS; + if (!value) return; + if (value === "preload") return value; + throw new Error(`Invalid RANGO_E2E_HEAD_SCRIPTS value: ${value}`); +} + +const headScripts = testHeadScripts(); + // A third-party-style resolver: maps the "@parity/*" specifier to ./src/parity/* // via a resolveId hook, deliberately WITHOUT a matching resolve.alias entry. // This mirrors how vite-tsconfig-paths resolves tsconfig `paths` (issue #500) @@ -35,7 +44,7 @@ export default defineConfig(({ command }) => ({ plugins: [ parityAliasPlugin(), react(), - rango(), + rango(headScripts ? { headScripts } : undefined), devtoolsJson(), poke(), ...analyze(), diff --git a/packages/rangojs-router/package.json b/packages/rangojs-router/package.json index cfcdcad59..2471a9f56 100644 --- a/packages/rangojs-router/package.json +++ b/packages/rangojs-router/package.json @@ -182,6 +182,7 @@ "prepublishOnly": "pnpm build", "typecheck": "tsc --noEmit && tsc -p tsconfig.strict-check.json --noEmit && tsc -p tsconfig.augment-check.json --noEmit", "test": "playwright test", + "test:preload": "playwright test --config=playwright.preload.config.ts", "test:ui": "playwright test --ui", "test:hmr-local": "playwright test --project=dev-warmup --project=hmr-basename --project=hmr-prerender --no-deps --workers=1 && RANGO_E2E_ROUTE_HMR_ONLY=1 playwright test --project=hmr-routes --no-deps --workers=1", "test:hmr-routes-local": "RANGO_E2E_ROUTE_HMR_ONLY=1 playwright test --project=hmr-routes --no-deps --workers=1", @@ -191,7 +192,7 @@ }, "dependencies": { "@types/debug": "^4.1.12", - "@vitejs/plugin-rsc": "^0.5.30", + "@vitejs/plugin-rsc": "^0.5.31", "debug": "^4.4.1", "magic-string": "^0.30.17", "picomatch": "^4.0.4", @@ -224,9 +225,9 @@ "@playwright/test": "^1.49.1", "@testing-library/react": ">=16", "@vercel/functions": "^3.0.0", - "@vitejs/plugin-rsc": "^0.5.30", - "react": ">=19.2.6 <20", - "react-dom": ">=19.2.6 <20", + "@vitejs/plugin-rsc": "^0.5.31", + "react": ">=19.2.8 <20", + "react-dom": ">=19.2.8 <20", "vite": "^8.0.16", "vitest": ">=3" }, diff --git a/packages/rangojs-router/playwright.config.ts b/packages/rangojs-router/playwright.config.ts index cf566be99..a6dea2164 100644 --- a/packages/rangojs-router/playwright.config.ts +++ b/packages/rangojs-router/playwright.config.ts @@ -131,6 +131,7 @@ export default defineConfig({ "**/prerender-hmr.test.ts", "**/basename-hmr.test.ts", "**/refresh-cmd.test.ts", + "**/head-script-preload.test.ts", "**/*.setup.ts", // mini is a Vitest dogfood app nested under e2e/; its vitest // test/*.test.tsx files must not be collected by Playwright. @@ -144,7 +145,11 @@ export default defineConfig({ { name: "production", grep: /\(production/, - testIgnore: ["**/smoke.test.ts", "**/mini/**"], + testIgnore: [ + "**/smoke.test.ts", + "**/head-script-preload.test.ts", + "**/mini/**", + ], use: { ...browserConfig, baseURL: `http://localhost:${PREVIEW_SERVER_PORT}`, @@ -273,6 +278,7 @@ export default defineConfig({ "**/prerender-hmr.test.ts", "**/basename-hmr.test.ts", "**/refresh-cmd.test.ts", + "**/head-script-preload.test.ts", "**/*.setup.ts", // host-routing runs in its own `host` project (with its own servers), // not the sharded dev bucket -- see the RUN_HOST block above. @@ -294,6 +300,7 @@ export default defineConfig({ "**/smoke.test.ts", // host-routing "(production)" runs in the `host` project. "**/host-routing.test.ts", + "**/head-script-preload.test.ts", "**/mini/**", ], use: { diff --git a/packages/rangojs-router/playwright.preload.config.ts b/packages/rangojs-router/playwright.preload.config.ts new file mode 100644 index 000000000..5893c2cae --- /dev/null +++ b/packages/rangojs-router/playwright.preload.config.ts @@ -0,0 +1,84 @@ +import { defineConfig, devices } from "@playwright/test"; +import { checkoutPortOffset } from "@shared/e2e"; + +const PORT_OFFSET = checkoutPortOffset(); +const DEV_PORT = 5308 + PORT_OFFSET; +const PREVIEW_PORT = 5309 + PORT_OFFSET; +const CACHE_DIR = "node_modules/.vite-e2e-test-app-preload"; +const SERVER_ENV = { + ...process.env, + RANGO_E2E_HEAD_SCRIPTS: "preload", + RANGO_E2E_VITE_CACHE_DIR: CACHE_DIR, +}; +const browserConfig = { + ...devices["Desktop Chrome"], + viewport: null, + deviceScaleFactor: undefined, +}; + +export default defineConfig({ + testDir: "e2e", + fullyParallel: true, + globalTimeout: 600_000, + timeout: process.env.CI ? 60_000 : 30_000, + webServer: [ + { + command: `pnpm build && rm -rf ${CACHE_DIR} && pnpm dev --port ${DEV_PORT}`, + cwd: "./e2e/test-app", + port: DEV_PORT, + reuseExistingServer: false, + env: SERVER_ENV, + }, + { + command: `pnpm preview --port ${PREVIEW_PORT}`, + cwd: "./e2e/test-app", + port: PREVIEW_PORT, + reuseExistingServer: false, + env: SERVER_ENV, + }, + ], + use: { + screenshot: "only-on-failure", + trace: "on-all-retries", + }, + expect: { + timeout: 10_000, + toPass: { timeout: 10_000 }, + }, + projects: [ + { + name: "preload-dev-warmup", + testMatch: "**/head-script-preload-warmup.setup.ts", + use: { + ...browserConfig, + baseURL: `http://localhost:${DEV_PORT}`, + }, + }, + { + name: "preload-dev", + testMatch: "**/head-script-preload.test.ts", + grep: /^(?!.*\(production\))/, + use: { + ...browserConfig, + baseURL: `http://localhost:${DEV_PORT}`, + }, + dependencies: ["preload-dev-warmup"], + }, + { + name: "preload-production", + testMatch: "**/head-script-preload.test.ts", + grep: /\(production\)/, + use: { + ...browserConfig, + baseURL: `http://localhost:${PREVIEW_PORT}`, + }, + }, + ], + workers: 2, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + reporter: [ + ["list"], + ...(process.env.CI ? [["github"], ["html", { open: "never" }]] : []), + ] as import("@playwright/test").ReporterDescription[], +}); diff --git a/packages/rangojs-router/src/cache/__tests__/segment-codec.test.ts b/packages/rangojs-router/src/cache/__tests__/segment-codec.test.ts index 01e84e65d..b5ad71fda 100644 --- a/packages/rangojs-router/src/cache/__tests__/segment-codec.test.ts +++ b/packages/rangojs-router/src/cache/__tests__/segment-codec.test.ts @@ -5,19 +5,38 @@ * chunk boundary — decode identically. * * @vitejs/plugin-rsc/rsc is a virtual module unresolvable in the unit runner; - * it is mocked only so segment-codec.ts can be imported (streamToString itself - * uses none of it). + * it is mocked so segment-codec.ts can be imported and decoder arguments can be + * inspected (streamToString itself uses none of it). */ -import { describe, it, expect, vi } from "vitest"; +import { beforeEach, describe, it, expect, vi } from "vitest"; + +const { + createFromReadableStreamSpy, + createTemporaryReferenceSetSpy, + temporaryReferences, +} = vi.hoisted(() => { + const temporaryReferences = {}; + return { + createFromReadableStreamSpy: vi.fn(async () => "decoded"), + createTemporaryReferenceSetSpy: vi.fn(() => temporaryReferences), + temporaryReferences, + }; +}); vi.mock("@vitejs/plugin-rsc/rsc", () => ({ renderToReadableStream: vi.fn(), - createTemporaryReferenceSet: vi.fn(), - createFromReadableStream: vi.fn(), + createTemporaryReferenceSet: createTemporaryReferenceSetSpy, + createFromReadableStream: createFromReadableStreamSpy, })); -import { streamToString } from "../segment-codec.js"; +import { + deserializeResult, + deserializeSegments, + rscDeserialize, + streamToString, +} from "../segment-codec.js"; +import type { SerializedSegmentData } from "../types.js"; function streamOf(chunks: Uint8Array[]): ReadableStream { let i = 0; @@ -59,3 +78,45 @@ describe("streamToString (C3)", () => { expect(await streamToString(streamOf(chunks))).toBe("€!"); }); }); + +describe("Flight decoder options", () => { + beforeEach(() => { + createFromReadableStreamSpy.mockClear(); + createTemporaryReferenceSetSpy.mockClear(); + }); + + it("preserves server references in rscDeserialize", async () => { + await rscDeserialize("encoded-value"); + + expect(createFromReadableStreamSpy).toHaveBeenCalledWith( + expect.any(ReadableStream), + expect.objectContaining({ temporaryReferences }), + { preserveServerReferences: true }, + ); + }); + + it("preserves server references in deserializeResult", async () => { + await deserializeResult("encoded-result"); + + expect(createFromReadableStreamSpy).toHaveBeenCalledWith( + expect.any(ReadableStream), + expect.objectContaining({ temporaryReferences }), + { preserveServerReferences: true }, + ); + }); + + it("preserves server references in deserializeSegments", async () => { + const segment = { + encoded: "encoded-component", + metadata: { id: "segment" }, + } as SerializedSegmentData; + + await deserializeSegments([segment]); + + expect(createFromReadableStreamSpy).toHaveBeenCalledWith( + expect.any(ReadableStream), + expect.objectContaining({ temporaryReferences }), + { preserveServerReferences: true }, + ); + }); +}); diff --git a/packages/rangojs-router/src/vite/__tests__/client-ref-dedup.test.ts b/packages/rangojs-router/src/vite/__tests__/client-ref-dedup.test.ts index 11d048123..350b44590 100644 --- a/packages/rangojs-router/src/vite/__tests__/client-ref-dedup.test.ts +++ b/packages/rangojs-router/src/vite/__tests__/client-ref-dedup.test.ts @@ -1,4 +1,7 @@ -import { describe, it, expect, vi, beforeEach } from "vitest"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { dirname, join } from "node:path"; import { extractPackageName, clientRefDedup, @@ -60,9 +63,12 @@ describe("clientRefDedup plugin", () => { function createPlugin() { const plugin = clientRefDedup(); + const resolver = vi.fn(async () => undefined); // Simulate configResolved with empty exclude (plugin as any).configResolved({ + root: "/project", + createResolver: vi.fn(() => resolver), environments: { client: { optimizeDeps: { exclude: [] }, @@ -76,8 +82,11 @@ describe("clientRefDedup plugin", () => { function createPluginWithExclude(exclude: string[]) { const plugin = clientRefDedup(); + const resolver = vi.fn(async () => undefined); (plugin as any).configResolved({ + root: "/project", + createResolver: vi.fn(() => resolver), environments: { client: { optimizeDeps: { exclude }, @@ -97,32 +106,32 @@ describe("clientRefDedup plugin", () => { }); describe("resolveId", () => { - it("redirects absolute node_modules import from proxy in client env", () => { + it("skips an absolute package source without package metadata", async () => { const plugin = createPlugin(); const resolveId = (plugin as any).resolveId.bind({ environment: { name: "client" }, }); - const result = resolveId( + const result = await resolveId( "/project/node_modules/fake-context-lib/internal/context.js", PROXY_IMPORTER, {}, ); - expect(result).toBe("\0rango:dedup/fake-context-lib"); + expect(result).toBeUndefined(); }); - it("redirects scoped package imports", () => { + it("skips a scoped package source without package metadata", async () => { const plugin = createPlugin(); const resolveId = (plugin as any).resolveId.bind({ environment: { name: "client" }, }); - const result = resolveId( + const result = await resolveId( "/project/node_modules/@mantine/core/esm/MantineProvider.mjs", PROXY_IMPORTER, {}, ); - expect(result).toBe("\0rango:dedup/@mantine/core"); + expect(result).toBeUndefined(); }); it("skips non-client environments", () => { @@ -207,7 +216,10 @@ describe("clientRefDedup plugin", () => { it("falls back to top-level optimizeDeps.exclude", () => { const plugin = clientRefDedup(); + const resolver = vi.fn(async () => undefined); (plugin as any).configResolved({ + root: "/project", + createResolver: vi.fn(() => resolver), environments: {}, optimizeDeps: { exclude: ["fake-context-lib"] }, }); @@ -223,12 +235,463 @@ describe("clientRefDedup plugin", () => { ); expect(result).toBeUndefined(); }); + + describe("public package specifiers", () => { + let root: string; + + beforeEach(() => { + root = mkdtempSync(join(tmpdir(), "rango-client-ref-dedup-")); + }); + + afterEach(() => { + rmSync(root, { recursive: true, force: true }); + }); + + function writePackage( + packageRoot: string, + name: string, + exports: unknown, + ): void { + mkdirSync(packageRoot, { recursive: true }); + writeFileSync( + join(packageRoot, "package.json"), + JSON.stringify({ name, exports }), + ); + } + + function writeModule(source: string): void { + mkdirSync(dirname(source), { recursive: true }); + writeFileSync(source, "export const value = true;\n"); + } + + function createResolutionPlugin(resolver: ReturnType): { + plugin: ReturnType; + createResolver: ReturnType; + } { + const plugin = clientRefDedup(); + const createResolver = vi.fn(() => resolver); + (plugin as any).configResolved({ + root, + createResolver, + environments: { client: { optimizeDeps: { exclude: [] } } }, + optimizeDeps: { exclude: [] }, + }); + return { plugin, createResolver }; + } + + async function resolveSource( + plugin: ReturnType, + source: string, + optimizedResolve = vi.fn(), + ): Promise { + return (plugin as any).resolveId.call( + { + environment: { name: "client" }, + resolve: optimizedResolve, + }, + source, + PROXY_IMPORTER, + {}, + ); + } + + it("uses an explicit unscoped public subpath resolving to the source", async () => { + const packageRoot = join(root, "node_modules", "deep-lib"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "deep-lib", { + ".": "./index.js", + "./context": "./internal/context.js", + }); + writeModule(source); + + const resolver = vi.fn(async (id: string) => + id === "deep-lib/context" + ? `${source}?v=fixture` + : join(packageRoot, "index.js"), + ); + const optimizedResolve = vi.fn(async () => "/node_modules/.vite/deps"); + const { plugin, createResolver } = createResolutionPlugin(resolver); + + await expect( + resolveSource(plugin, source, optimizedResolve), + ).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("deep-lib/context")}`, + ); + expect(createResolver).toHaveBeenCalledWith({ scan: true }); + expect(resolver).toHaveBeenCalledWith( + "deep-lib/context", + join(root, "index.html"), + ); + expect(optimizedResolve).not.toHaveBeenCalled(); + }); + + it("uses an explicit scoped public subpath resolving to the source", async () => { + const packageRoot = join(root, "node_modules", "@scope", "deep-lib"); + const source = join(packageRoot, "dist", "context.js"); + writePackage(packageRoot, "@scope/deep-lib", { + ".": "./index.js", + "./context": "./dist/context.js", + }); + writeModule(source); + + const resolver = vi.fn(async (id: string) => + id === "@scope/deep-lib/context" + ? source + : join(packageRoot, "index.js"), + ); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("@scope/deep-lib/context")}`, + ); + }); + + it("uses the installed alias for an explicit public subpath", async () => { + const packageRoot = join(root, "node_modules", "ui-alias"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "ui-lib", { + ".": "./index.js", + "./context": "./internal/context.js", + }); + writeModule(source); + + const resolver = vi.fn(async (id: string) => + id === "ui-alias/context" ? source : undefined, + ); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("ui-alias/context")}`, + ); + expect(resolver).toHaveBeenCalledTimes(1); + expect(resolver).toHaveBeenCalledWith( + "ui-alias/context", + join(root, "index.html"), + ); + }); + + it("uses the installed alias for the root-barrel fallback", async () => { + const packageRoot = join(root, "node_modules", "ui-alias"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "ui-lib", { ".": "./index.js" }); + writeModule(source); + + const resolver = vi.fn(async (id: string) => + id === "ui-alias" ? join(packageRoot, "index.js") : undefined, + ); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("ui-alias")}`, + ); + expect(resolver).toHaveBeenCalledTimes(1); + expect(resolver).toHaveBeenCalledWith( + "ui-alias", + join(root, "index.html"), + ); + }); + + it("falls back to the self-name when the alias root probe throws", async () => { + const packageRoot = join(root, "node_modules", "ui-alias"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "ui-lib", { ".": "./index.js" }); + writeModule(source); + + const resolver = vi.fn(async (id: string) => { + if (id === "ui-alias") throw new Error("alias is unavailable"); + return id === "ui-lib" ? join(packageRoot, "index.js") : undefined; + }); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("ui-lib")}`, + ); + expect(resolver).toHaveBeenNthCalledWith( + 1, + "ui-alias", + join(root, "index.html"), + ); + expect(resolver).toHaveBeenNthCalledWith( + 2, + "ui-lib", + join(root, "index.html"), + ); + }); + + it("continues after an earlier explicit export probe throws", async () => { + const packageRoot = join(root, "node_modules", "deep-lib"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "deep-lib", { + ".": "./index.js", + "./unavailable": "./internal/context.js", + "./context": "./internal/context.js", + }); + writeModule(source); + + const resolver = vi.fn(async (id: string) => { + if (id === "deep-lib/unavailable") { + throw new Error("export is unavailable"); + } + return id === "deep-lib/context" + ? source + : join(packageRoot, "index.js"); + }); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("deep-lib/context")}`, + ); + expect(resolver).toHaveBeenNthCalledWith( + 1, + "deep-lib/unavailable", + join(root, "index.html"), + ); + expect(resolver).toHaveBeenNthCalledWith( + 2, + "deep-lib/context", + join(root, "index.html"), + ); + }); + + it("delegates conditional export selection to the unoptimized resolver", async () => { + const packageRoot = join(root, "node_modules", "conditional-lib"); + const source = join(packageRoot, "client", "context.js"); + writePackage(packageRoot, "conditional-lib", { + "./context": { + "react-server": "./server/context.js", + default: "./client/context.js", + }, + }); + writeModule(source); + + const resolver = vi.fn(async () => source); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("conditional-lib/context")}`, + ); + expect(resolver).toHaveBeenCalledWith( + "conditional-lib/context", + join(root, "index.html"), + ); + }); + + it("does not probe unrelated exact exports", async () => { + const packageRoot = join(root, "node_modules", "deep-lib"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "deep-lib", { + ".": "./index.js", + "./button": "./components/button.js", + "./context": "./internal/context.js", + "./input": "./components/input.js", + }); + writeModule(source); + + const resolver = vi.fn(async (id: string) => { + if (id === "deep-lib/context") return source; + throw new Error(`unexpected export probe: ${id}`); + }); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("deep-lib/context")}`, + ); + expect(resolver).toHaveBeenCalledTimes(1); + expect(resolver).toHaveBeenCalledWith( + "deep-lib/context", + join(root, "index.html"), + ); + }); + + it("maps a simple wildcard export to the exact source", async () => { + const packageRoot = join(root, "node_modules", "wildcard-lib"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "wildcard-lib", { + ".": "./index.js", + "./features/*": "./internal/*.js", + }); + writeModule(source); + + const resolver = vi.fn(async (id: string) => + id === "wildcard-lib/features/context" + ? source + : join(packageRoot, "index.js"), + ); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("wildcard-lib/features/context")}`, + ); + }); + + it("memoizes concurrent and repeated successful resolution", async () => { + const packageRoot = join(root, "node_modules", "deep-lib"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "deep-lib", { + "./context": "./internal/context.js", + }); + writeModule(source); + + let release: (() => void) | undefined; + const gate = new Promise((resolve) => { + release = resolve; + }); + const resolver = vi.fn(async () => { + await gate; + return source; + }); + const { plugin } = createResolutionPlugin(resolver); + const expected = `\0rango:dedup/${encodeURIComponent("deep-lib/context")}`; + + const first = resolveSource(plugin, source); + const second = resolveSource(plugin, source); + release!(); + + await expect(Promise.all([first, second])).resolves.toEqual([ + expected, + expected, + ]); + await expect(resolveSource(plugin, source)).resolves.toBe(expected); + expect(resolver).toHaveBeenCalledTimes(1); + }); + + it("keeps the same-package root-barrel fallback", async () => { + const packageRoot = join(root, "node_modules", "barrel-lib"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "barrel-lib", { ".": "./index.js" }); + writeModule(source); + + const resolver = vi.fn(async () => join(packageRoot, "index.js")); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("barrel-lib")}`, + ); + expect(resolver).toHaveBeenCalledWith( + "barrel-lib", + join(root, "index.html"), + ); + }); + + it("uses the root-barrel fallback after unrelated export probes throw", async () => { + const packageRoot = join(root, "node_modules", "barrel-lib"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "barrel-lib", { + ".": "./index.js", + "./button": "./internal/context.js", + "./input": "./internal/context.js", + }); + writeModule(source); + + const resolver = vi.fn(async (id: string) => { + if (id !== "barrel-lib") throw new Error("export is unavailable"); + return join(packageRoot, "index.js"); + }); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("barrel-lib")}`, + ); + expect(resolver).toHaveBeenNthCalledWith( + 3, + "barrel-lib", + join(root, "index.html"), + ); + }); + + it("preserves the absolute source when package metadata is missing", async () => { + const source = join( + root, + "node_modules", + "missing-lib", + "internal", + "context.js", + ); + writeModule(source); + const resolver = vi.fn(async () => undefined); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBeUndefined(); + expect(resolver).not.toHaveBeenCalled(); + }); + + it("retries after root resolution is absent", async () => { + const packageRoot = join(root, "node_modules", "absent-lib"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "absent-lib", { ".": "./index.js" }); + writeModule(source); + + let available = false; + const resolver = vi.fn(async () => + available ? join(packageRoot, "index.js") : undefined, + ); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBeUndefined(); + available = true; + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("absent-lib")}`, + ); + expect(resolver).toHaveBeenCalledTimes(2); + }); + + it("retries after the app root resolves another package instance", async () => { + const packageRoot = join( + root, + "node_modules", + "host-lib", + "node_modules", + "nested-lib", + ); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "nested-lib", { ".": "./index.js" }); + writeModule(source); + + const appPackageRoot = join(root, "node_modules", "nested-lib"); + writePackage(appPackageRoot, "nested-lib", { ".": "./index.js" }); + let resolveNested = false; + const resolver = vi.fn(async () => + join(resolveNested ? packageRoot : appPackageRoot, "index.js"), + ); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBeUndefined(); + resolveNested = true; + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("nested-lib")}`, + ); + expect(resolver).toHaveBeenCalledTimes(2); + }); + + it("retries after the root package probe throws", async () => { + const packageRoot = join(root, "node_modules", "throwing-lib"); + const source = join(packageRoot, "internal", "context.js"); + writePackage(packageRoot, "throwing-lib", { ".": "./index.js" }); + writeModule(source); + + let shouldThrow = true; + const resolver = vi.fn(async () => { + if (shouldThrow) throw new Error("resolution failed"); + return join(packageRoot, "index.js"); + }); + const { plugin } = createResolutionPlugin(resolver); + + await expect(resolveSource(plugin, source)).resolves.toBeUndefined(); + shouldThrow = false; + await expect(resolveSource(plugin, source)).resolves.toBe( + `\0rango:dedup/${encodeURIComponent("throwing-lib")}`, + ); + expect(resolver).toHaveBeenCalledTimes(2); + }); + }); }); describe("load", () => { it("generates bare specifier re-exports for dedup modules", () => { const plugin = createPlugin(); - const result = (plugin as any).load("\0rango:dedup/@mantine/core"); + const result = (plugin as any).load( + `\0rango:dedup/${encodeURIComponent("@mantine/core")}`, + ); expect(result).toContain('export * from "@mantine/core"'); expect(result).toContain('import * as __all__ from "@mantine/core"'); @@ -244,6 +707,16 @@ describe("clientRefDedup plugin", () => { expect(result).toContain("export default __all__.default"); }); + it("decodes deep public specifiers from virtual IDs", () => { + const plugin = createPlugin(); + const result = (plugin as any).load( + `\0rango:dedup/${encodeURIComponent("deep-lib/context")}`, + ); + + expect(result).toContain('export * from "deep-lib/context"'); + expect(result).toContain('import * as __all__ from "deep-lib/context"'); + }); + it("skips non-dedup module IDs", () => { const plugin = createPlugin(); const result = (plugin as any).load("/project/src/App.tsx"); diff --git a/packages/rangojs-router/src/vite/__tests__/expose-action-id.test.ts b/packages/rangojs-router/src/vite/__tests__/expose-action-id.test.ts index 9ce0aac24..ef23b2b64 100644 --- a/packages/rangojs-router/src/vite/__tests__/expose-action-id.test.ts +++ b/packages/rangojs-router/src/vite/__tests__/expose-action-id.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, afterAll } from "vitest"; +import { describe, it, expect, afterAll, afterEach, vi } from "vitest"; import { exposeActionId } from "../plugins/expose-action-id.js"; import fs from "node:fs"; import path from "node:path"; @@ -14,13 +14,21 @@ function createPlugin() { }; } -// Minimal mock of RSC plugin API with serverReferenceMetaMap -function mockRscPluginApi(metaMap: Record = {}) { +type ManagerShape = "legacy" | "nested"; + +// Minimal mock of the released and nested RSC plugin manager shapes +function mockRscPluginApi( + metaMap: Record = {}, + managerShape: ManagerShape = "legacy", + name = "rsc:minimal", +) { return { - name: "rsc:minimal", + name, api: { manager: { - serverReferenceMetaMap: metaMap, + ...(managerShape === "nested" + ? { serverReferences: { metaMap: new Map(Object.entries(metaMap)) } } + : { serverReferenceMetaMap: metaMap }), config: {}, }, }, @@ -39,9 +47,14 @@ function initDev(root = "/project") { return plugin; } -function initBuild(root = "/project", metaMap: Record = {}) { +function initBuild( + root = "/project", + metaMap: Record = {}, + managerShape: ManagerShape = "legacy", + pluginName = "rsc:minimal", +) { const plugin = createPlugin(); - const rscPlugin = mockRscPluginApi(metaMap); + const rscPlugin = mockRscPluginApi(metaMap, managerShape, pluginName); plugin.configResolved({ command: "build", root, @@ -52,6 +65,10 @@ function initBuild(root = "/project", metaMap: Record = {}) { } describe("exposeActionId", () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + // ---- Dev mode: transform ---- describe("dev mode transform", () => { @@ -223,14 +240,17 @@ const remove = createServerReference("src/actions.ts#remove", callServer); fs.rmSync(tmpDir, { recursive: true, force: true }); }); - function initRscBuild() { + function initRscBuild( + managerShape: ManagerShape = "legacy", + pluginName = "rsc:minimal", + ) { const metaMap: Record = {}; metaMap[actionsFile] = { importId: "src/actions.ts", referenceKey: "abc123", exportNames: ["addTodo", "removeTodo"], }; - return initBuild(tmpDir, metaMap); + return initBuild(tmpDir, metaMap, managerShape, pluginName); } it("replaces hash with file path for createServerReference $$id in RSC env", () => { @@ -246,6 +266,39 @@ const remove = createServerReference("src/actions.ts#remove", callServer); ); }); + it("reads server reference metadata from the nested manager map", () => { + const plugin = initRscBuild("nested"); + const code = `const action = createServerReference("abc123#addTodo", callServer);`; + const chunk = { fileName: "chunk-rsc.js" }; + const ctx = { environment: { name: "rsc" } }; + const result = plugin.renderChunk.call(ctx, code, chunk); + expect(result).toBeDefined(); + expect(result.code).toMatch( + /fn\.\$\$id\s*=\s*"src\/actions\.ts#addTodo"/, + ); + }); + + it.each(["legacy", "nested"] as const)( + "discovers a renamed plugin with the %s manager shape", + (managerShape) => { + const warn = vi.spyOn(console, "warn").mockImplementation(() => {}); + const plugin = initRscBuild(managerShape, "wrapped:rsc-minimal"); + const code = `const action = createServerReference("abc123#addTodo", callServer);`; + const chunk = { fileName: "chunk-rsc.js" }; + const ctx = { environment: { name: "rsc" } }; + const result = plugin.renderChunk.call(ctx, code, chunk); + + expect(warn).toHaveBeenCalledWith( + '[rango:expose-action-id] RSC plugin found by API structure (name: "wrapped:rsc-minimal"). ' + + "Consider updating the name lookup if the plugin was renamed.", + ); + expect(result).toBeDefined(); + expect(result.code).toMatch( + /fn\.\$\$id\s*=\s*"src\/actions\.ts#addTodo"/, + ); + }, + ); + it("wraps registerServerReference with $id (single dollar) in RSC env", () => { const plugin = initRscBuild(); const code = `registerServerReference(addTodoFn, "abc123", "addTodo");`; @@ -394,6 +447,25 @@ const remove = createServerReference("src/actions.ts#remove", callServer); // ---- Plugin lifecycle ---- describe("plugin configuration", () => { + it("throws if the RSC manager has no supported metadata shape", () => { + const plugin = createPlugin(); + plugin.configResolved({ + command: "build", + root: "/project", + plugins: [ + { + name: "rsc:minimal", + api: { manager: { config: {} } }, + }, + ], + }); + + expect(() => plugin.buildStart()).toThrow( + "[rango] Unsupported @vitejs/plugin-rsc server reference metadata shape. " + + "Expected manager.serverReferences.metaMap or manager.serverReferenceMetaMap.", + ); + }); + it("throws if RSC plugin is missing", () => { const plugin = createPlugin(); plugin.configResolved({ diff --git a/packages/rangojs-router/src/vite/__tests__/react-dedupe-config.test.ts b/packages/rangojs-router/src/vite/__tests__/react-dedupe-config.test.ts index 05819bdfa..4f0ba9931 100644 --- a/packages/rangojs-router/src/vite/__tests__/react-dedupe-config.test.ts +++ b/packages/rangojs-router/src/vite/__tests__/react-dedupe-config.test.ts @@ -88,7 +88,7 @@ describe("react peer dependency contract", () => { // floor is held at a current security-patched release: React 18 and older // React 19 patches are unsupported, future 19.x patch/minor releases are // allowed, React 20 is excluded. - const RANGE = ">=19.2.6 <20"; + const RANGE = ">=19.2.8 <20"; expect(pkg.peerDependencies.react).toBe(RANGE); expect(pkg.peerDependencies.react).not.toContain("18"); diff --git a/packages/rangojs-router/src/vite/plugins/client-ref-dedup.ts b/packages/rangojs-router/src/vite/plugins/client-ref-dedup.ts index 2e4c8334f..d048fedf4 100644 --- a/packages/rangojs-router/src/vite/plugins/client-ref-dedup.ts +++ b/packages/rangojs-router/src/vite/plugins/client-ref-dedup.ts @@ -1,3 +1,5 @@ +import { existsSync, readFileSync } from "node:fs"; +import { isAbsolute, join, normalize, relative } from "node:path"; import type { Plugin, ResolvedConfig } from "vite"; import { createRangoDebugger, NS } from "../debug.js"; @@ -5,23 +7,21 @@ const debug = createRangoDebugger(NS.transform); const CLIENT_IN_SERVER_PROXY_PREFIX = "virtual:vite-rsc/client-in-server-package-proxy/"; +const DEDUP_PREFIX = "\0rango:dedup/"; + +interface PackageMetadata { + root: string; + selfName: string; + exports: unknown; +} + +type PackageResolver = ReturnType; /** * Extract the bare package name from an absolute node_modules path. * Handles scoped packages (@org/name) and nested node_modules. * Returns null if the path doesn't contain a valid package reference. * - * NOTE: This is a lossy transformation. It maps a specific submodule path - * (e.g., pkg/internal/context.js) to the package root (pkg). The load() - * hook then re-exports via the bare specifier, which resolves to the - * package entry point. This works for packages that barrel-export their - * "use client" symbols from the root, which covers the common case - * (component libraries like @mantine/core, @chakra-ui/react, etc.). - * Packages whose client symbols are only available from deep subpaths - * (not re-exported from the root) would lose those symbols after the - * rewrite. A more precise approach would resolve through the package's - * exports map to find the correct entry point, but that adds significant - * complexity for a rare edge case. * See: https://github.com/cloudflare/vinext/pull/413 */ export function extractPackageName(absolutePath: string): string | null { @@ -44,6 +44,219 @@ export function extractPackageName(absolutePath: string): string | null { return name || null; } +function stripQueryAndHash(id: string): string { + const suffixIndex = id.search(/[?#]/); + return suffixIndex === -1 ? id : id.slice(0, suffixIndex); +} + +function getPackageRoot(source: string): string | undefined { + const packageName = extractPackageName(source); + if (!packageName) return; + + const marker = "/node_modules/"; + const markerIndex = source.lastIndexOf(marker); + return source.slice(0, markerIndex + marker.length) + packageName; +} + +function readPackageMetadata( + source: string, + cache: Map, +): PackageMetadata | undefined { + const root = getPackageRoot(source); + if (!root) return; + + const cached = cache.get(root); + if (cached !== undefined) return cached ?? undefined; + + const packageJsonPath = join(root, "package.json"); + if (!existsSync(packageJsonPath)) { + cache.set(root, null); + return; + } + + try { + const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8")) as { + name?: unknown; + exports?: unknown; + }; + if (typeof packageJson.name !== "string" || !packageJson.name) { + cache.set(root, null); + return; + } + const metadata = { + root, + selfName: packageJson.name, + exports: packageJson.exports, + } satisfies PackageMetadata; + cache.set(root, metadata); + return metadata; + } catch { + cache.set(root, null); + return; + } +} + +function collectStringTargets(value: unknown, targets: string[]): void { + if (typeof value === "string") { + targets.push(value); + return; + } + if (Array.isArray(value)) { + for (const item of value) collectStringTargets(item, targets); + return; + } + if (typeof value !== "object" || value === null) return; + for (const target of Object.values(value)) { + collectStringTargets(target, targets); + } +} + +function singleStarParts(value: string): [string, string] | undefined { + const starIndex = value.indexOf("*"); + if (starIndex === -1 || value.indexOf("*", starIndex + 1) !== -1) return; + return [value.slice(0, starIndex), value.slice(starIndex + 1)]; +} + +function targetCanMapToSource(target: string, sourceRelative: string): boolean { + const targetStar = singleStarParts(target); + if (!targetStar) return target === sourceRelative; + const [prefix, suffix] = targetStar; + return ( + sourceRelative.startsWith(prefix) && + sourceRelative.endsWith(suffix) && + sourceRelative.length >= prefix.length + suffix.length + ); +} + +function getPublicSpecifierCandidates( + metadata: PackageMetadata, + packageSpecifier: string, + source: string, +): string[] { + if ( + typeof metadata.exports !== "object" || + metadata.exports === null || + Array.isArray(metadata.exports) + ) { + return []; + } + + const candidates = new Set(); + const sourceRelative = `./${relative(metadata.root, source).replaceAll("\\", "/")}`; + if ( + sourceRelative.startsWith("./../") || + isAbsolute(sourceRelative.slice(2)) + ) { + return []; + } + + for (const [exportKey, target] of Object.entries(metadata.exports)) { + if (!exportKey.startsWith("./") || exportKey === ".") continue; + + const keyStar = singleStarParts(exportKey); + if (!keyStar) { + const targets: string[] = []; + collectStringTargets(target, targets); + if ( + targets.some((target) => targetCanMapToSource(target, sourceRelative)) + ) { + candidates.add(`${packageSpecifier}${exportKey.slice(1)}`); + } + continue; + } + + const captures = new Set(); + const targets: string[] = []; + collectStringTargets(target, targets); + for (const targetPattern of targets) { + const targetStar = singleStarParts(targetPattern); + if (!targetStar) continue; + const [prefix, suffix] = targetStar; + if ( + !sourceRelative.startsWith(prefix) || + !sourceRelative.endsWith(suffix) || + sourceRelative.length < prefix.length + suffix.length + ) { + continue; + } + captures.add( + sourceRelative.slice( + prefix.length, + sourceRelative.length - suffix.length, + ), + ); + } + + if (captures.size === 1) { + const capture = captures.values().next().value; + if (capture !== undefined) { + const publicSubpath = `${keyStar[0]}${capture}${keyStar[1]}`; + candidates.add(`${packageSpecifier}${publicSubpath.slice(1)}`); + } + } + } + + return [...candidates]; +} + +function belongsToPackage(resolvedId: string, packageRoot: string): boolean { + return normalize(getPackageRoot(resolvedId) ?? "") === normalize(packageRoot); +} + +async function resolvePublicSpecifier( + source: string, + metadata: PackageMetadata, + installedSpecifier: string, + resolvePackage: PackageResolver, + importer: string, +): Promise { + const packageSpecifiers = + installedSpecifier === metadata.selfName + ? [installedSpecifier] + : [installedSpecifier, metadata.selfName]; + + for (const packageSpecifier of packageSpecifiers) { + for (const candidate of getPublicSpecifierCandidates( + metadata, + packageSpecifier, + source, + )) { + try { + const resolved = await resolvePackage(candidate, importer); + if (!resolved) continue; + const resolvedId = stripQueryAndHash(resolved); + if ( + normalize(resolvedId) === normalize(source) && + belongsToPackage(resolvedId, metadata.root) + ) { + return candidate; + } + } catch { + continue; + } + } + + // Fallback: the pre-exports-map behavior, and it is LOSSY. When no public + // subpath maps back to this exact file, re-export from the bare package + // root — correct only for packages that barrel-export their "use client" + // symbols from the entry point (the common component-library shape). + // A deep module whose symbols are NOT re-exported from the root loses + // them silently after this rewrite; the exports-map resolution above + // exists precisely to make that case rare. + try { + const rootResolved = await resolvePackage(packageSpecifier, importer); + if ( + rootResolved && + belongsToPackage(stripQueryAndHash(rootResolved), metadata.root) + ) { + return packageSpecifier; + } + } catch { + continue; + } + } +} + /** * Vite plugin that deduplicates client references from third-party packages * in dev mode. @@ -65,7 +278,11 @@ export function extractPackageName(absolutePath: string): string | null { */ export function clientRefDedup(): Plugin { let clientExclude: string[] = []; + let rootImporter = ""; + let resolvePackage: PackageResolver | undefined; const dedupedPackages = new Set(); + const packageMetadataCache = new Map(); + const publicSpecifierCache = new Map>(); return { name: "@rangojs/router:client-ref-dedup", @@ -76,6 +293,8 @@ export function clientRefDedup(): Plugin { const clientEnv = config.environments?.["client"]; clientExclude = clientEnv?.optimizeDeps?.exclude ?? config.optimizeDeps?.exclude ?? []; + rootImporter = join(config.root, "index.html"); + resolvePackage = config.createResolver({ scan: true }); }, buildEnd() { @@ -95,24 +314,67 @@ export function clientRefDedup(): Plugin { if (!source.includes("/node_modules/")) return; - const packageName = extractPackageName(source); - if (!packageName) return; + const cleanSource = stripQueryAndHash(source); + const packageName = extractPackageName(cleanSource); + if (!packageName || !resolvePackage) return; if (clientExclude.includes(packageName)) return; - if (debug) dedupedPackages.add(packageName); + const metadata = readPackageMetadata(cleanSource, packageMetadataCache); + if (!metadata || clientExclude.includes(metadata.selfName)) return; + + let specifierPromise = publicSpecifierCache.get(cleanSource); + if (!specifierPromise) { + specifierPromise = resolvePublicSpecifier( + cleanSource, + metadata, + packageName, + resolvePackage, + rootImporter, + ); + publicSpecifierCache.set(cleanSource, specifierPromise); + // Only SUCCESSFUL resolutions stay cached. A failed one is evicted so + // the next resolveId retries — deliberate: dev-time failures can be + // transient (a dependency installed mid-session, an exports map fixed + // on disk). The cost is a repeated candidate scan per unresolvable + // module, bounded by resolveId call frequency in dev. + void specifierPromise.then( + (specifier) => { + if ( + !specifier && + publicSpecifierCache.get(cleanSource) === specifierPromise + ) { + publicSpecifierCache.delete(cleanSource); + } + }, + () => { + if (publicSpecifierCache.get(cleanSource) === specifierPromise) { + publicSpecifierCache.delete(cleanSource); + } + }, + ); + } - return `\0rango:dedup/${packageName}`; + return specifierPromise.then((specifier) => { + if (!specifier) return; + if (debug) dedupedPackages.add(packageName); + return `${DEDUP_PREFIX}${encodeURIComponent(specifier)}`; + }); }, load(id) { - if (!id.startsWith("\0rango:dedup/")) return; + if (!id.startsWith(DEDUP_PREFIX)) return; - const packageName = id.slice("\0rango:dedup/".length); + let specifier: string; + try { + specifier = decodeURIComponent(id.slice(DEDUP_PREFIX.length)); + } catch { + return; + } return [ - `export * from ${JSON.stringify(packageName)};`, - `import * as __all__ from ${JSON.stringify(packageName)};`, + `export * from ${JSON.stringify(specifier)};`, + `import * as __all__ from ${JSON.stringify(specifier)};`, `export default __all__.default;`, ].join("\n"); }, diff --git a/packages/rangojs-router/src/vite/plugins/expose-action-id.ts b/packages/rangojs-router/src/vite/plugins/expose-action-id.ts index 8f38d3fe6..fd6ff40ac 100644 --- a/packages/rangojs-router/src/vite/plugins/expose-action-id.ts +++ b/packages/rangojs-router/src/vite/plugins/expose-action-id.ts @@ -1,4 +1,5 @@ import type { Plugin, ResolvedConfig } from "vite"; +import { getPluginApi } from "@vitejs/plugin-rsc"; import MagicString from "magic-string"; import path from "node:path"; import fs from "node:fs"; @@ -8,15 +9,15 @@ import { createRangoDebugger, createCounter, NS } from "../debug.js"; const debug = createRangoDebugger(NS.transform); +interface ServerReferenceMeta { + importId: string; + referenceKey: string; + exportNames: string[]; +} + interface RscPluginManager { - serverReferenceMetaMap: Record< - string, - { - importId: string; - referenceKey: string; - exportNames: string[]; - } - >; + serverReferenceMetaMap?: Record; + serverReferences?: { metaMap: Map }; config: ResolvedConfig; } @@ -24,21 +25,44 @@ interface RscPluginApi { manager: RscPluginManager; } +function getServerReferenceMetaEntries( + manager: RscPluginManager | undefined, +): Iterable<[string, ServerReferenceMeta]> { + if (manager?.serverReferences?.metaMap) { + return manager.serverReferences.metaMap; + } + + if (manager?.serverReferenceMetaMap) { + return Object.entries(manager.serverReferenceMetaMap); + } + + throw new Error( + "[rango] Unsupported @vitejs/plugin-rsc server reference metadata shape. " + + "Expected manager.serverReferences.metaMap or manager.serverReferenceMetaMap.", + ); +} + function getRscPluginApi(config: ResolvedConfig): RscPluginApi | undefined { - let plugin = config.plugins.find((p) => p.name === "rsc:minimal"); + const pluginApi = getPluginApi(config) as RscPluginApi | undefined; + if (pluginApi) { + return pluginApi; + } - if (!plugin) { - plugin = config.plugins.find( - (p) => - (p.api as RscPluginApi | undefined)?.manager?.serverReferenceMetaMap !== - undefined, - ); - if (plugin) { - console.warn( - `[rango:expose-action-id] RSC plugin found by API structure (name: "${plugin.name}"). ` + - `Consider updating the name lookup if the plugin was renamed.`, + const plugin = config.plugins.find((p) => { + try { + getServerReferenceMetaEntries( + (p.api as RscPluginApi | undefined)?.manager, ); + return true; + } catch { + return false; } + }); + if (plugin) { + console.warn( + `[rango:expose-action-id] RSC plugin found by API structure (name: "${plugin.name}"). ` + + `Consider updating the name lookup if the plugin was renamed.`, + ); } return plugin?.api as RscPluginApi | undefined; @@ -233,10 +257,8 @@ export function exposeActionId(): Plugin { if (!isBuild) return; hashToFileMap = new Map(); - const { serverReferenceMetaMap } = rscPluginApi.manager; - - for (const [absolutePath, meta] of Object.entries( - serverReferenceMetaMap, + for (const [absolutePath, meta] of getServerReferenceMetaEntries( + rscPluginApi.manager, )) { // Only include module-level "use server" files // Inline actions (defined in RSC components) should keep hashed IDs for client security diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7eb4ec45..ceb737011 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,17 +25,17 @@ catalogs: specifier: ^6.0.0 version: 6.0.2 '@vitejs/plugin-rsc': - specifier: ^0.5.30 - version: 0.5.30 + specifier: ^0.5.31 + version: 0.5.31 babel-plugin-react-compiler: specifier: ^1.0.0 version: 1.0.0 react: - specifier: ^19.2.6 - version: 19.2.6 + specifier: ^19.2.8 + version: 19.2.8 react-dom: - specifier: ^19.2.6 - version: 19.2.6 + specifier: ^19.2.8 + version: 19.2.8 overrides: react-experimental>react: 0.0.0-experimental-247fbb45-20260622 @@ -90,10 +90,10 @@ importers: version: 5.2.7 '@icons-pack/react-simple-icons': specifier: 13.13.0 - version: 13.13.0(react@19.2.6) + version: 13.13.0(react@19.2.8) '@mdx-js/react': specifier: ^3.1.1 - version: 3.1.1(@types/react@19.2.7)(react@19.2.6) + version: 3.1.1(@types/react@19.2.7)(react@19.2.8) '@mdx-js/rollup': specifier: ^3.1.1 version: 3.1.1(rollup@4.62.2) @@ -108,10 +108,10 @@ importers: version: 4.3.1 '@streamdown/cjk': specifier: 1.0.3 - version: 1.0.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(react@19.2.6)(unified@11.0.5) + version: 1.0.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(react@19.2.8)(unified@11.0.5) '@streamdown/code': specifier: 1.1.1 - version: 1.1.1(react@19.2.6) + version: 1.1.1(react@19.2.8) '@tailwindcss/typography': specifier: 0.5.20 version: 0.5.20(tailwindcss@4.3.1) @@ -135,7 +135,7 @@ importers: version: 6.0.2(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0)) '@vitejs/plugin-rsc': specifier: 'catalog:' - version: 0.5.30(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0)) + version: 0.5.31(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0)) class-variance-authority: specifier: 0.7.1 version: 0.7.1 @@ -144,13 +144,13 @@ importers: version: 2.1.1 cmdk: specifier: 1.1.1 - version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) dexie: specifier: 4.4.4 version: 4.4.4 dexie-react-hooks: specifier: 4.4.0 - version: 4.4.0(dexie@4.4.4)(react@19.2.6) + version: 4.4.0(dexie@4.4.4)(react@19.2.8) feed: specifier: 5.2.1 version: 5.2.1 @@ -162,31 +162,31 @@ importers: version: 4.0.3 jotai: specifier: 2.20.1 - version: 2.20.1(@babel/core@7.29.7)(@babel/template@7.29.7)(@types/react@19.2.7)(react@19.2.6) + version: 2.20.1(@babel/core@7.29.7)(@babel/template@7.29.7)(@types/react@19.2.7)(react@19.2.8) lucide-react: specifier: 1.21.0 - version: 1.21.0(react@19.2.6) + version: 1.21.0(react@19.2.8) mermaid: specifier: 11.15.0 version: 11.15.0 motion: specifier: 12.40.0 - version: 12.40.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 12.40.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) nanoid: specifier: 5.1.16 version: 5.1.16 radix-ui: specifier: 1.6.0 - version: 1.6.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 1.6.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) react-player: specifier: 3.4.0 - version: 3.4.0(@svta/cml-cta@1.0.6(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0))(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 3.4.0(@svta/cml-cta@1.0.6(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0))(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) rehype-autolink-headings: specifier: ^7.1.0 version: 7.1.0 @@ -204,10 +204,10 @@ importers: version: 3.19.0 sonner: specifier: 2.0.7 - version: 2.0.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 2.0.7(react-dom@19.2.8(react@19.2.8))(react@19.2.8) streamdown: specifier: 2.5.0 - version: 2.5.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 2.5.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) tailwind-merge: specifier: 3.6.0 version: 3.6.0 @@ -222,10 +222,10 @@ importers: version: 6.0.3 use-stick-to-bottom: specifier: 1.1.6 - version: 1.1.6(react@19.2.6) + version: 1.1.6(react@19.2.8) vaul: specifier: 1.1.2 - version: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) vite: specifier: ^8.0.16 version: 8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0) @@ -243,10 +243,10 @@ importers: version: link:../../packages/rangojs-router react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@cloudflare/vite-plugin': specifier: ^1.44.0 @@ -286,10 +286,10 @@ importers: version: link:../../packages/rangojs-router react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@cloudflare/vite-plugin': specifier: ^1.44.0 @@ -338,10 +338,10 @@ importers: version: 2.1.3(@opentelemetry/api-logs@0.219.0)(@opentelemetry/api@1.9.1)(@opentelemetry/instrumentation@0.219.0(@opentelemetry/api@1.9.1))(@opentelemetry/resources@2.9.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-logs@0.219.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-metrics@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.9.0(@opentelemetry/api@1.9.1)) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@playwright/test': specifier: ^1.49.1 @@ -378,10 +378,10 @@ importers: version: 3.7.5(ws@8.21.0) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@playwright/test': specifier: ^1.49.1 @@ -420,8 +420,8 @@ importers: specifier: ^3.0.0 version: 3.7.5(ws@8.21.0) '@vitejs/plugin-rsc': - specifier: ^0.5.30 - version: 0.5.30(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0)) + specifier: ^0.5.31 + version: 0.5.31(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0)) debug: specifier: ^4.4.1 version: 4.4.3 @@ -467,7 +467,7 @@ importers: version: 10.4.1 '@testing-library/react': specifier: ^16.3.2 - version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@types/node': specifier: ^24.10.1 version: 24.10.4 @@ -488,10 +488,10 @@ importers: version: 2.7.0 react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) vitest: specifier: ^4.1.9 version: 4.1.9(@opentelemetry/api@1.9.1)(@types/node@24.10.4)(happy-dom@20.10.1)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0)) @@ -503,10 +503,10 @@ importers: version: link:../.. react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@babel/core': specifier: 'catalog:' @@ -543,10 +543,10 @@ importers: version: link:../.. react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@types/react': specifier: 'catalog:' @@ -568,14 +568,14 @@ importers: version: link:../.. react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@testing-library/react': specifier: ^16.3.2 - version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@types/node': specifier: ^24.10.1 version: 24.10.4 @@ -605,10 +605,10 @@ importers: version: link:../.. react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@types/react': specifier: 'catalog:' @@ -633,13 +633,16 @@ importers: version: link:../.. fake-context-lib: specifier: file:__test_packages__/fake-context-lib - version: file:packages/rangojs-router/e2e/test-app/__test_packages__/fake-context-lib(react@19.2.6) + version: file:packages/rangojs-router/e2e/test-app/__test_packages__/fake-context-lib(react@19.2.8) + rango-e2e-deep-context-lib: + specifier: file:__test_packages__/rango-e2e-deep-context-lib + version: file:packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib(react@19.2.8) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@types/react': specifier: 'catalog:' @@ -668,15 +671,18 @@ importers: '@shared/docs': specifier: workspace:* version: link:../shared-docs + rango-e2e-deep-context-lib: + specifier: file:__test_packages__/rango-e2e-deep-context-lib + version: file:tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib(react@19.2.8) react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) spin-delay: specifier: ^2.0.1 - version: 2.0.1(react@19.2.6) + version: 2.0.1(react@19.2.8) devDependencies: '@babel/core': specifier: 'catalog:' @@ -698,7 +704,7 @@ importers: version: link:../shared-e2e '@testing-library/react': specifier: ^16.3.2 - version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@types/babel__core': specifier: 'catalog:' version: 7.20.5 @@ -743,10 +749,10 @@ importers: version: link:../../packages/rangojs-router react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@cloudflare/vite-plugin': specifier: ^1.44.0 @@ -795,10 +801,10 @@ importers: version: link:../../packages/rangojs-router react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@playwright/test': specifier: ^1.49.1 @@ -860,7 +866,7 @@ importers: version: link:../../packages/rangojs-router react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 devDependencies: '@types/react': specifier: 'catalog:' @@ -889,10 +895,10 @@ importers: version: link:../../packages/rangojs-router react: specifier: 'catalog:' - version: 19.2.6 + version: 19.2.8 react-dom: specifier: 'catalog:' - version: 19.2.6(react@19.2.6) + version: 19.2.8(react@19.2.8) devDependencies: '@babel/core': specifier: 'catalog:' @@ -905,7 +911,7 @@ importers: version: 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0)) '@testing-library/react': specifier: ^16.3.2 - version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@types/babel__core': specifier: 'catalog:' version: 7.20.5 @@ -3421,8 +3427,8 @@ packages: babel-plugin-react-compiler: optional: true - '@vitejs/plugin-rsc@0.5.30': - resolution: {integrity: sha512-q4fje/9heG/Mx3m5hEC9fpP1bUcpVtpq1sSZ7pWcVrYVxkMNBEEfcILwmUIo2EtMwbBp0/aPzVBsXcA8mG777A==} + '@vitejs/plugin-rsc@0.5.31': + resolution: {integrity: sha512-Gvym0sYiNSUYefj7ToizyB6QLBPyP+wqwlh+S5lhHPyaaGcOd7AByY5/3a77oCLJqtpksVD6uMnalrRoO9Id3g==} peerDependencies: react: '*' react-dom: '*' @@ -5000,15 +5006,25 @@ packages: '@types/react-dom': optional: true + rango-e2e-deep-context-lib@file:packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib: + resolution: {directory: packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib, type: directory} + peerDependencies: + react: '>=19' + + rango-e2e-deep-context-lib@file:tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib: + resolution: {directory: tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib, type: directory} + peerDependencies: + react: '>=19' + react-dom@0.0.0-experimental-247fbb45-20260622: resolution: {integrity: sha512-aU7oTVjr1Hfc9hv8mGDspPBHe7dCN+lbD2lCRGJMGDUn7vu1uB6T67peIp9DxKT0d1GwJQaySlRVJN5An2EWAA==} peerDependencies: react: 0.0.0-experimental-247fbb45-20260622 - react-dom@19.2.6: - resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} + react-dom@19.2.8: + resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==} peerDependencies: - react: ^19.2.6 + react: ^19.2.8 react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -5057,8 +5073,8 @@ packages: resolution: {integrity: sha512-vqRCxIRqaxexsuP23wkY5uk2ifay186BLNfV28S4x4UmbRXWxgASbG2Hmis09h9zQe6ynC8xvj2V14UzvKIN6w==} engines: {node: '>=0.10.0'} - react@19.2.6: - resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} + react@19.2.8: + resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==} engines: {node: '>=0.10.0'} recma-build-jsx@1.0.0: @@ -5282,8 +5298,8 @@ packages: engines: {node: '>=20.16.0'} hasBin: true - srvx@0.11.22: - resolution: {integrity: sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==} + srvx@0.12.4: + resolution: {integrity: sha512-RixzFlMn3dvzDTpKIAXhXrqL4cy6vScNCP0VVwgVbUBU94o+DiXLsFnAZetbyKAEnK6Ox3hzHXWGsyv/Iibv7g==} engines: {node: '>=20.16.0'} hasBin: true @@ -6016,11 +6032,11 @@ snapshots: '@floating-ui/core': 1.7.5 '@floating-ui/utils': 0.2.11 - '@floating-ui/react-dom@2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@floating-ui/react-dom@2.1.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@floating-ui/dom': 1.7.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) '@floating-ui/utils@0.2.11': {} @@ -6038,9 +6054,9 @@ snapshots: '@iconify/types': 2.0.0 import-meta-resolve: 4.2.0 - '@icons-pack/react-simple-icons@13.13.0(react@19.2.6)': + '@icons-pack/react-simple-icons@13.13.0(react@19.2.8)': dependencies: - react: 19.2.6 + react: 19.2.8 '@img/colour@1.0.0': {} @@ -6192,11 +6208,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.6)': + '@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.8)': dependencies: '@types/mdx': 2.0.14 '@types/react': 19.2.7 - react: 19.2.6 + react: 19.2.8 '@mdx-js/rollup@3.1.1(rollup@4.62.2)': dependencies: @@ -6220,23 +6236,23 @@ snapshots: dependencies: mux-embed: 5.18.1 - '@mux/mux-player-react@3.13.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mux/mux-player-react@3.13.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@mux/mux-player': 3.13.0(react@19.2.6) + '@mux/mux-player': 3.13.0(react@19.2.8) '@mux/playback-core': 0.35.0 prop-types: 15.8.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@mux/mux-player@3.13.0(react@19.2.6)': + '@mux/mux-player@3.13.0(react@19.2.8)': dependencies: '@mux/mux-video': 0.31.0 '@mux/playback-core': 0.35.0 - media-chrome: 4.19.2(react@19.2.6) - player.style: 0.3.4(react@19.2.6) + media-chrome: 4.19.2(react@19.2.8) + player.style: 0.3.4(react@19.2.8) transitivePeerDependencies: - react @@ -6474,805 +6490,805 @@ snapshots: '@radix-ui/primitive@1.1.4': {} - '@radix-ui/react-accessible-icon@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-accessible-icon@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-accordion@1.2.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-accordion@1.2.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-collapsible': 1.1.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-collapsible': 1.1.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-alert-dialog@1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-alert-dialog@1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dialog': 1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dialog': 1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-arrow@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-arrow@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-aspect-ratio@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-aspect-ratio@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-avatar@1.2.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-avatar@1.2.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-is-hydrated': 0.1.1(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-is-hydrated': 0.1.1(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-checkbox@1.3.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-checkbox@1.3.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-collapsible@1.1.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-collapsible@1.1.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-collection@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-collection@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-compose-refs@1.1.3(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-compose-refs@1.1.3(@types/react@19.2.7)(react@19.2.8)': dependencies: - react: 19.2.6 + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-context-menu@2.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-context-menu@2.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-menu': 2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-menu': 2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-context@1.1.4(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-context@1.1.4(@types/react@19.2.7)(react@19.2.8)': dependencies: - react: 19.2.6 + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-dialog@1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-dialog@1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-focus-scope': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) aria-hidden: 1.2.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-dialog@1.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-dialog@1.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-portal': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-focus-scope': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-portal': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) aria-hidden: 1.2.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-direction@1.1.2(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-direction@1.1.2(@types/react@19.2.7)(react@19.2.8)': dependencies: - react: 19.2.6 + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-dismissable-layer@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-dismissable-layer@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-escape-keydown': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-escape-keydown': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-dismissable-layer@1.1.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-dismissable-layer@1.1.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-dropdown-menu@2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-dropdown-menu@2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-menu': 2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-menu': 2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-focus-guards@1.1.4(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-focus-guards@1.1.4(@types/react@19.2.7)(react@19.2.8)': dependencies: - react: 19.2.6 + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-focus-scope@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-focus-scope@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-focus-scope@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-focus-scope@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-form@0.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-form@0.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-label': 2.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-label': 2.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-hover-card@1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-hover-card@1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-id@1.1.2(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-id@1.1.2(@types/react@19.2.7)(react@19.2.8)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-label@2.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-label@2.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-menu@2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-menu@2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) + '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-focus-scope': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) aria-hidden: 1.2.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-menubar@1.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-menubar@1.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-menu': 2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-menu': 2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-navigation-menu@1.2.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-navigation-menu@1.2.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-one-time-password-field@0.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-one-time-password-field@0.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/number': 1.1.2 '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-is-hydrated': 0.1.1(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-is-hydrated': 0.1.1(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-password-toggle-field@0.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-password-toggle-field@0.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-is-hydrated': 0.1.1(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-is-hydrated': 0.1.1(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-popover@1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-popover@1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-focus-scope': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) aria-hidden: 1.2.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-popper@1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-arrow': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-rect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.6) + '@radix-ui/react-popper@1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-arrow': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-rect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.8) '@radix-ui/rect': 1.1.2 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-portal@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-portal@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-portal@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-portal@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-presence@1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-presence@1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-primitive@2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-primitive@2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-primitive@2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-primitive@2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-progress@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-progress@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-radio-group@1.4.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-radio-group@1.4.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-roving-focus@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-roving-focus@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-scroll-area@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-scroll-area@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/number': 1.1.2 '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-select@2.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-select@2.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/number': 1.1.2 '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-focus-scope': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) aria-hidden: 1.2.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + react-remove-scroll: 2.7.2(@types/react@19.2.7)(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-separator@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-separator@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-slider@1.4.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-slider@1.4.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/number': 1.1.2 '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-slot@1.3.0(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-slot@1.3.0(@types/react@19.2.7)(react@19.2.8)': dependencies: - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-switch@1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-switch@1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-tabs@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-tabs@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-toast@1.2.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-toast@1.2.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-toggle-group@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-toggle-group@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-toggle': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-toggle': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-toggle@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-toggle@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-toolbar@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-toolbar@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-separator': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-toggle-group': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-separator': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-toggle-group': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-tooltip@1.2.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-tooltip@1.2.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) - '@radix-ui/react-use-callback-ref@1.1.2(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-use-callback-ref@1.1.2(@types/react@19.2.7)(react@19.2.8)': dependencies: - react: 19.2.6 + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-use-controllable-state@1.2.3(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-use-controllable-state@1.2.3(@types/react@19.2.7)(react@19.2.8)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 + '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-use-effect-event@0.0.3(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-use-effect-event@0.0.3(@types/react@19.2.7)(react@19.2.8)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-use-escape-keydown@1.1.2(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-use-escape-keydown@1.1.2(@types/react@19.2.7)(react@19.2.8)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-use-is-hydrated@0.1.1(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-use-is-hydrated@0.1.1(@types/react@19.2.7)(react@19.2.8)': dependencies: - react: 19.2.6 + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-use-layout-effect@1.1.2(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-use-layout-effect@1.1.2(@types/react@19.2.7)(react@19.2.8)': dependencies: - react: 19.2.6 + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-use-previous@1.1.2(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-use-previous@1.1.2(@types/react@19.2.7)(react@19.2.8)': dependencies: - react: 19.2.6 + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-use-rect@1.1.2(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-use-rect@1.1.2(@types/react@19.2.7)(react@19.2.8)': dependencies: '@radix-ui/rect': 1.1.2 - react: 19.2.6 + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-use-size@1.1.2(@types/react@19.2.7)(react@19.2.6)': + '@radix-ui/react-use-size@1.1.2(@types/react@19.2.7)(react@19.2.8)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - react: 19.2.6 + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + react: 19.2.8 optionalDependencies: '@types/react': 19.2.7 - '@radix-ui/react-visually-hidden@1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-visually-hidden@1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) @@ -7508,9 +7524,9 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@streamdown/cjk@1.0.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(react@19.2.6)(unified@11.0.5)': + '@streamdown/cjk@1.0.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(react@19.2.8)(unified@11.0.5)': dependencies: - react: 19.2.6 + react: 19.2.8 remark-cjk-friendly: 2.3.1(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5) remark-cjk-friendly-gfm-strikethrough: 2.3.1(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5) unist-util-visit: 5.1.0 @@ -7521,9 +7537,9 @@ snapshots: - supports-color - unified - '@streamdown/code@1.1.1(react@19.2.6)': + '@streamdown/code@1.1.1(react@19.2.8)': dependencies: - react: 19.2.6 + react: 19.2.8 shiki: 3.19.0 '@svta/cml-608@1.0.2': {} @@ -7652,12 +7668,12 @@ snapshots: picocolors: 1.1.1 pretty-format: 27.5.1 - '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@babel/runtime': 7.29.7 '@testing-library/dom': 10.4.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) @@ -7938,15 +7954,15 @@ snapshots: '@rolldown/plugin-babel': 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0)) babel-plugin-react-compiler: 1.0.0 - '@vitejs/plugin-rsc@0.5.30(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0))': + '@vitejs/plugin-rsc@0.5.31(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vite@8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0))': dependencies: '@rolldown/pluginutils': 1.0.1 es-module-lexer: 2.3.1 estree-walker: 3.0.3 magic-string: 0.30.21 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - srvx: 0.11.22 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + srvx: 0.12.4 strip-literal: 3.1.0 turbo-stream: 3.2.0 vite: 8.0.16(@types/node@24.10.4)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.21.0) @@ -8103,9 +8119,9 @@ snapshots: ccount@2.0.1: {} - ce-la-react@0.3.2(react@19.2.6): + ce-la-react@0.3.2(react@19.2.8): dependencies: - react: 19.2.6 + react: 19.2.8 chai@6.2.2: {} @@ -8146,14 +8162,14 @@ snapshots: clsx@2.1.1: {} - cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dialog': 1.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dialog': 1.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) transitivePeerDependencies: - '@types/react' - '@types/react-dom' @@ -8456,10 +8472,10 @@ snapshots: dependencies: dequal: 2.0.3 - dexie-react-hooks@4.4.0(dexie@4.4.4)(react@19.2.6): + dexie-react-hooks@4.4.0(dexie@4.4.4)(react@19.2.8): dependencies: dexie: 4.4.4 - react: 19.2.6 + react: 19.2.8 dexie@4.4.4: {} @@ -8617,9 +8633,9 @@ snapshots: extend@3.0.2: {} - fake-context-lib@file:packages/rangojs-router/e2e/test-app/__test_packages__/fake-context-lib(react@19.2.6): + fake-context-lib@file:packages/rangojs-router/e2e/test-app/__test_packages__/fake-context-lib(react@19.2.8): dependencies: - react: 19.2.6 + react: 19.2.8 fast-deep-equal@3.1.3: {} @@ -8645,14 +8661,14 @@ snapshots: format@0.2.2: {} - framer-motion@12.42.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + framer-motion@12.42.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: motion-dom: 12.42.2 motion-utils: 12.39.0 tslib: 2.8.1 optionalDependencies: - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) fsevents@2.3.2: optional: true @@ -8958,12 +8974,12 @@ snapshots: jose@5.10.0: {} - jotai@2.20.1(@babel/core@7.29.7)(@babel/template@7.29.7)(@types/react@19.2.7)(react@19.2.6): + jotai@2.20.1(@babel/core@7.29.7)(@babel/template@7.29.7)(@types/react@19.2.7)(react@19.2.8): optionalDependencies: '@babel/core': 7.29.7 '@babel/template': 7.29.7 '@types/react': 19.2.7 - react: 19.2.6 + react: 19.2.8 js-tokens@4.0.0: {} @@ -9110,9 +9126,9 @@ snapshots: dependencies: yallist: 3.1.1 - lucide-react@1.21.0(react@19.2.6): + lucide-react@1.21.0(react@19.2.8): dependencies: - react: 19.2.6 + react: 19.2.8 lz-string@1.5.0: {} @@ -9328,9 +9344,9 @@ snapshots: dependencies: '@types/mdast': 4.0.4 - media-chrome@4.19.2(react@19.2.6): + media-chrome@4.19.2(react@19.2.8): dependencies: - ce-la-react: 0.3.2(react@19.2.6) + ce-la-react: 0.3.2(react@19.2.8) transitivePeerDependencies: - react @@ -9709,13 +9725,13 @@ snapshots: motion-utils@12.39.0: {} - motion@12.40.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + motion@12.40.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: - framer-motion: 12.42.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + framer-motion: 12.42.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) tslib: 2.8.1 optionalDependencies: - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) ms@2.1.3: {} @@ -9840,9 +9856,9 @@ snapshots: picomatch@4.0.5: {} - player.style@0.3.4(react@19.2.6): + player.style@0.3.4(react@19.2.8): dependencies: - media-chrome: 4.19.2(react@19.2.6) + media-chrome: 4.19.2(react@19.2.8) transitivePeerDependencies: - react @@ -9892,92 +9908,100 @@ snapshots: property-information@7.2.0: {} - radix-ui@1.6.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + radix-ui@1.6.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: '@radix-ui/primitive': 1.1.4 - '@radix-ui/react-accessible-icon': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-accordion': 1.2.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-alert-dialog': 1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-arrow': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-aspect-ratio': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-avatar': 1.2.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-checkbox': 1.3.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-collapsible': 1.1.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-context-menu': 2.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-dialog': 1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-dropdown-menu': 2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-form': 0.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-hover-card': 1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-label': 2.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-menu': 2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-menubar': 1.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-navigation-menu': 1.2.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-one-time-password-field': 0.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-password-toggle-field': 0.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-popover': 1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-progress': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-radio-group': 1.4.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-scroll-area': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-select': 2.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-separator': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slider': 1.4.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-switch': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-tabs': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-toast': 1.2.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-toggle': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-toggle-group': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-toolbar': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-tooltip': 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-escape-keydown': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-is-hydrated': 0.1.1(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.6) - '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-accessible-icon': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-accordion': 1.2.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-alert-dialog': 1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-arrow': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-aspect-ratio': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-avatar': 1.2.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-checkbox': 1.3.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-collapsible': 1.1.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-collection': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-context-menu': 2.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-dialog': 1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-dropdown-menu': 2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-focus-scope': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-form': 0.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-hover-card': 1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-label': 2.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-menu': 2.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-menubar': 1.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-navigation-menu': 1.2.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-one-time-password-field': 0.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-password-toggle-field': 0.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-popover': 1.1.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-popper': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-portal': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-presence': 1.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-progress': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-radio-group': 1.4.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-roving-focus': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-scroll-area': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-select': 2.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-separator': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-slider': 1.4.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-switch': 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-tabs': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-toast': 1.2.17(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-toggle': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-toggle-group': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-toolbar': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-tooltip': 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-escape-keydown': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-is-hydrated': 0.1.1(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.7)(react@19.2.8) + '@radix-ui/react-visually-hidden': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) + rango-e2e-deep-context-lib@file:packages/rangojs-router/e2e/test-app/__test_packages__/rango-e2e-deep-context-lib(react@19.2.8): + dependencies: + react: 19.2.8 + + rango-e2e-deep-context-lib@file:tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib(react@19.2.8): + dependencies: + react: 19.2.8 + react-dom@0.0.0-experimental-247fbb45-20260622(react@0.0.0-experimental-247fbb45-20260622): dependencies: react: 0.0.0-experimental-247fbb45-20260622 scheduler: 0.0.0-experimental-247fbb45-20260622 - react-dom@19.2.6(react@19.2.6): + react-dom@19.2.8(react@19.2.8): dependencies: - react: 19.2.6 + react: 19.2.8 scheduler: 0.27.0 react-is@16.13.1: {} react-is@17.0.2: {} - react-player@3.4.0(@svta/cml-cta@1.0.6(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0))(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-player@3.4.0(@svta/cml-cta@1.0.6(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0))(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: - '@mux/mux-player-react': 3.13.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mux/mux-player-react': 3.13.0(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@types/react': 19.2.7 cloudflare-video-element: 1.3.5 dash-video-element: 0.3.2(@svta/cml-cta@1.0.6(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0))(@svta/cml-structured-field-values@1.1.3(@svta/cml-utils@1.5.0))(@svta/cml-utils@1.5.0) hls-video-element: 1.5.11 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) spotify-audio-element: 1.0.4 tiktok-video-element: 0.1.2 twitch-video-element: 0.1.6 @@ -9990,36 +10014,36 @@ snapshots: - '@svta/cml-utils' - '@types/react-dom' - react-remove-scroll-bar@2.3.8(@types/react@19.2.7)(react@19.2.6): + react-remove-scroll-bar@2.3.8(@types/react@19.2.7)(react@19.2.8): dependencies: - react: 19.2.6 - react-style-singleton: 2.2.3(@types/react@19.2.7)(react@19.2.6) + react: 19.2.8 + react-style-singleton: 2.2.3(@types/react@19.2.7)(react@19.2.8) tslib: 2.8.1 optionalDependencies: '@types/react': 19.2.7 - react-remove-scroll@2.7.2(@types/react@19.2.7)(react@19.2.6): + react-remove-scroll@2.7.2(@types/react@19.2.7)(react@19.2.8): dependencies: - react: 19.2.6 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.7)(react@19.2.6) - react-style-singleton: 2.2.3(@types/react@19.2.7)(react@19.2.6) + react: 19.2.8 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.7)(react@19.2.8) + react-style-singleton: 2.2.3(@types/react@19.2.7)(react@19.2.8) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.7)(react@19.2.6) - use-sidecar: 1.1.3(@types/react@19.2.7)(react@19.2.6) + use-callback-ref: 1.3.3(@types/react@19.2.7)(react@19.2.8) + use-sidecar: 1.1.3(@types/react@19.2.7)(react@19.2.8) optionalDependencies: '@types/react': 19.2.7 - react-style-singleton@2.2.3(@types/react@19.2.7)(react@19.2.6): + react-style-singleton@2.2.3(@types/react@19.2.7)(react@19.2.8): dependencies: get-nonce: 1.0.1 - react: 19.2.6 + react: 19.2.8 tslib: 2.8.1 optionalDependencies: '@types/react': 19.2.7 react@0.0.0-experimental-247fbb45-20260622: {} - react@19.2.6: {} + react@19.2.8: {} recma-build-jsx@1.0.0: dependencies: @@ -10348,10 +10372,10 @@ snapshots: signal-exit@3.0.7: {} - sonner@2.0.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + sonner@2.0.7(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) source-map-js@1.2.1: {} @@ -10359,9 +10383,9 @@ snapshots: space-separated-tokens@2.0.2: {} - spin-delay@2.0.1(react@19.2.6): + spin-delay@2.0.1(react@19.2.8): dependencies: - react: 19.2.6 + react: 19.2.8 spotify-audio-element@1.0.4: {} @@ -10369,21 +10393,21 @@ snapshots: srvx@0.11.15: {} - srvx@0.11.22: {} + srvx@0.12.4: {} stackback@0.0.2: {} std-env@4.1.0: {} - streamdown@2.5.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + streamdown@2.5.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: clsx: 2.1.1 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 marked: 17.0.6 mermaid: 11.15.0 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) rehype-harden: 1.1.8 rehype-raw: 7.0.0 rehype-sanitize: 6.0.0 @@ -10560,24 +10584,24 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - use-callback-ref@1.3.3(@types/react@19.2.7)(react@19.2.6): + use-callback-ref@1.3.3(@types/react@19.2.7)(react@19.2.8): dependencies: - react: 19.2.6 + react: 19.2.8 tslib: 2.8.1 optionalDependencies: '@types/react': 19.2.7 - use-sidecar@1.1.3(@types/react@19.2.7)(react@19.2.6): + use-sidecar@1.1.3(@types/react@19.2.7)(react@19.2.8): dependencies: detect-node-es: 1.1.0 - react: 19.2.6 + react: 19.2.8 tslib: 2.8.1 optionalDependencies: '@types/react': 19.2.7 - use-stick-to-bottom@1.1.6(react@19.2.6): + use-stick-to-bottom@1.1.6(react@19.2.8): dependencies: - react: 19.2.6 + react: 19.2.8 util-deprecate@1.0.2: {} @@ -10585,11 +10609,11 @@ snapshots: uuid@11.1.1: {} - vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: - '@radix-ui/react-dialog': 1.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + '@radix-ui/react-dialog': 1.1.18(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) transitivePeerDependencies: - '@types/react' - '@types/react-dom' diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index bc564072c..bd23607d7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -11,9 +11,9 @@ packages: catalog: "@vitejs/plugin-react": ^6.0.0 - "@vitejs/plugin-rsc": ^0.5.30 - react: ^19.2.6 - react-dom: ^19.2.6 + "@vitejs/plugin-rsc": ^0.5.31 + react: ^19.2.8 + react-dom: ^19.2.8 "@types/react": ^19.2.7 "@types/react-dom": ^19.2.3 vite: ^8.0.16 @@ -66,8 +66,9 @@ minimumReleaseAge: 1440 # cooldown window. The exact override above keeps installs from following a # freshly moved dist-tag. minimumReleaseAgeExclude: - # Reviewed release required for cache-hit server-reference preservation. - - "@vitejs/plugin-rsc@0.5.30" + # Reviewed releases: 0.5.30 (cache-hit server-reference preservation), + # 0.5.31 (#1310 pluggable server-function registration — the claims API). + - "@vitejs/plugin-rsc@0.5.31" - react - react-dom - react-is diff --git a/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/index.d.ts b/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/index.d.ts new file mode 100644 index 000000000..40a09f224 --- /dev/null +++ b/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/index.d.ts @@ -0,0 +1,10 @@ +import type { ReactNode } from "react"; + +export interface DeepContextServerWrapperProps { + children: ReactNode; + value: string; +} + +export function DeepContextServerWrapper( + props: DeepContextServerWrapperProps, +): ReactNode; diff --git a/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/index.js b/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/index.js new file mode 100644 index 000000000..3ca338afe --- /dev/null +++ b/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/index.js @@ -0,0 +1,6 @@ +import { createElement } from "react"; +import { DeepContextProvider } from "./internal/context.js"; + +export function DeepContextServerWrapper({ children, value }) { + return createElement(DeepContextProvider, { value }, children); +} diff --git a/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/internal/context.d.ts b/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/internal/context.d.ts new file mode 100644 index 000000000..ae2051c3b --- /dev/null +++ b/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/internal/context.d.ts @@ -0,0 +1,9 @@ +import type { ReactNode } from "react"; + +export interface DeepContextProviderProps { + children: ReactNode; + value: string; +} + +export function DeepContextProvider(props: DeepContextProviderProps): ReactNode; +export function useDeepContext(): string | undefined; diff --git a/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/internal/context.js b/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/internal/context.js new file mode 100644 index 000000000..393cb826d --- /dev/null +++ b/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/internal/context.js @@ -0,0 +1,13 @@ +"use client"; + +import { createContext, createElement, useContext } from "react"; + +const DeepContext = createContext(undefined); + +export function DeepContextProvider({ children, value }) { + return createElement(DeepContext.Provider, { value }, children); +} + +export function useDeepContext() { + return useContext(DeepContext); +} diff --git a/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/package.json b/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/package.json new file mode 100644 index 000000000..3815fd53d --- /dev/null +++ b/tests/cloudflare-basic/__test_packages__/rango-e2e-deep-context-lib/package.json @@ -0,0 +1,18 @@ +{ + "name": "rango-e2e-deep-context-lib", + "version": "1.0.0", + "type": "module", + "exports": { + ".": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "./context": { + "types": "./internal/context.d.ts", + "default": "./internal/context.js" + } + }, + "peerDependencies": { + "react": ">=19" + } +} diff --git a/tests/cloudflare-basic/e2e/client-package-resolution.test.ts b/tests/cloudflare-basic/e2e/client-package-resolution.test.ts new file mode 100644 index 000000000..2776a16d3 --- /dev/null +++ b/tests/cloudflare-basic/e2e/client-package-resolution.test.ts @@ -0,0 +1,61 @@ +import { expect, test } from "@playwright/test"; +import { useFixture } from "./fixture"; +import { expectNoPageError, testId, waitForHydration } from "./helper"; + +test.describe("client package resolution", () => { + const f = useFixture({ root: ".", mode: "dev" }); + + test("preserves the deep context in server HTML", async ({ request }) => { + const response = await request.get(f.url("/client-package-resolution"), { + headers: { Accept: "text/html,application/xhtml+xml" }, + }); + expect(response.status()).toBe(200); + + const html = await response.text(); + expect(html).toContain("deep-context-value"); + expect(html).not.toContain("NOT_FOUND"); + }); + + test("preserves the deep context after hydration", async ({ page }) => { + using _ = expectNoPageError(page); + + await page.goto(f.url("/client-package-resolution")); + await waitForHydration(page); + + await expect(testId(page, "deep-context-value")).toHaveText( + "deep-context-value", + ); + await expect(testId(page, "deep-context-value")).not.toHaveText( + "NOT_FOUND", + ); + }); +}); + +test.describe("client package resolution (production)", () => { + const f = useFixture({ root: ".", mode: "build" }); + + test("preserves the deep context in server HTML", async ({ request }) => { + const response = await request.get(f.url("/client-package-resolution"), { + headers: { Accept: "text/html,application/xhtml+xml" }, + }); + expect(response.status()).toBe(200); + + const html = await response.text(); + expect(html).toContain("deep-context-value"); + expect(html).not.toContain("NOT_FOUND"); + }); + + test("preserves the deep context after hydration", async ({ page }) => { + using _ = expectNoPageError(page); + + await page.goto(f.url("/client-package-resolution")); + await waitForHydration(page); + + await expect(testId(page, "deep-context-value")).toHaveText( + "deep-context-value", + ); + await expect(testId(page, "deep-context-value")).not.toHaveText( + "NOT_FOUND", + ); + }); +}); diff --git a/tests/cloudflare-basic/e2e/head-script-preload-warmup.setup.ts b/tests/cloudflare-basic/e2e/head-script-preload-warmup.setup.ts new file mode 100644 index 000000000..47dc4b6dd --- /dev/null +++ b/tests/cloudflare-basic/e2e/head-script-preload-warmup.setup.ts @@ -0,0 +1,17 @@ +import { test as setup, expect } from "@playwright/test"; + +setup("warmup preload dev server", async ({ page, baseURL }) => { + setup.setTimeout(60_000); + + await expect(async () => { + const first = await page.goto(new URL("/", baseURL).href); + expect(first?.ok()).toBe(true); + + const second = await page.reload(); + expect(second?.ok()).toBe(true); + await page.waitForFunction( + () => document.documentElement.hasAttribute("data-hydrated"), + { timeout: 10_000 }, + ); + }).toPass({ timeout: 45_000, intervals: [2_000, 3_000, 5_000] }); +}); diff --git a/tests/cloudflare-basic/e2e/head-script-preload.test.ts b/tests/cloudflare-basic/e2e/head-script-preload.test.ts new file mode 100644 index 000000000..7c93f25f6 --- /dev/null +++ b/tests/cloudflare-basic/e2e/head-script-preload.test.ts @@ -0,0 +1,88 @@ +import test, { expect, type Page } from "@playwright/test"; +import { + fetchDocument, + modulepreloadHrefs, + scriptAndLinkTags, +} from "@shared/e2e"; +import { blockPrefetch } from "@rangojs/router/testing/e2e"; +import { useFixture } from "./fixture"; +import { expectNoPageError, waitForHydration } from "./helper"; + +function assertPreloadDocument( + html: string, + requireClientReferenceHint: boolean, +): void { + const headEnd = html.indexOf(""); + expect(headEnd).toBeGreaterThan(0); + const head = html.slice(0, headEnd); + const externalModuleScripts = scriptAndLinkTags(head).filter( + (tag) => + tag.startsWith("]*>([\s\S]*?)<\/script>/, + ); + expect( + bootstrap, + "the inline fizz bootstrap script is present", + ).not.toBeNull(); + const tagEnd = bootstrap![0].indexOf(">"); + const tag = bootstrap![0].slice(0, tagEnd + 1); + expect(tag).not.toContain('src="'); + const entryImport = bootstrap![1]!.match( + /\bimport\(\s*(["'])([^"']+)\1\s*\)/, + ); + expect( + entryImport, + "the inline bootstrap imports the browser entry", + ).not.toBeNull(); + + if (requireClientReferenceHint) { + const browserEntryUrl = entryImport![2]!; + const clientReferenceHrefs = modulepreloadHrefs(html).filter( + (href) => href !== browserEntryUrl, + ); + expect(clientReferenceHrefs.length).toBeGreaterThan(0); + } +} + +async function expectCleanHydration(page: Page, url: string): Promise { + using _ = expectNoPageError(page); + await blockPrefetch(page); + const consoleErrors: string[] = []; + page.on("console", (message) => { + if (message.type() === "error") consoleErrors.push(message.text()); + }); + + await page.goto(url); + await waitForHydration(page); + expect(consoleErrors).toEqual([]); +} + +test.describe("head-script-preload", () => { + const f = useFixture({ root: ".", mode: "dev" }); + + test("uses an inline bootstrap without executing external head scripts", async () => { + assertPreloadDocument(await fetchDocument(f.url("/")), false); + }); + + test("hydrates without browser errors", async ({ page }) => { + await expectCleanHydration(page, f.url("/")); + }); +}); + +test.describe("head-script-preload (production)", () => { + const f = useFixture({ root: ".", mode: "build" }); + + test("keeps client-reference hints with an inline bootstrap", async () => { + assertPreloadDocument(await fetchDocument(f.url("/")), true); + }); + + test("hydrates without browser errors", async ({ page }) => { + await expectCleanHydration(page, f.url("/")); + }); +}); diff --git a/tests/cloudflare-basic/package.json b/tests/cloudflare-basic/package.json index 81ad68f69..127e9b323 100644 --- a/tests/cloudflare-basic/package.json +++ b/tests/cloudflare-basic/package.json @@ -11,6 +11,7 @@ "deploy": "wrangler deploy", "typecheck": "tsc --noEmit && tsc -p tsconfig.test.json", "test:e2e": "playwright test", + "test:e2e:preload": "playwright test --config=playwright.preload.config.ts", "test:e2e:ui": "playwright test --ui", "test:e2e:hmr-local": "playwright test --project=hmr --no-deps --workers=1", "test:unit": "vitest run", @@ -20,6 +21,7 @@ "dependencies": { "@rangojs/router": "workspace:*", "@shared/docs": "workspace:*", + "rango-e2e-deep-context-lib": "file:__test_packages__/rango-e2e-deep-context-lib", "react": "catalog:", "react-dom": "catalog:", "spin-delay": "^2.0.1" diff --git a/tests/cloudflare-basic/playwright.config.ts b/tests/cloudflare-basic/playwright.config.ts index fe7f5b407..624fbe0a6 100644 --- a/tests/cloudflare-basic/playwright.config.ts +++ b/tests/cloudflare-basic/playwright.config.ts @@ -82,7 +82,11 @@ export default defineConfig({ { name: "dev", grep: /^(?!.*\(production\))/, - testIgnore: ["**/hmr*.test.ts", "**/*.setup.ts"], + testIgnore: [ + "**/hmr*.test.ts", + "**/head-script-preload.test.ts", + "**/*.setup.ts", + ], use: { ...devices["Desktop Chrome"], baseURL: `http://localhost:${DEV_PORT}`, @@ -91,7 +95,7 @@ export default defineConfig({ { name: "production", grep: /\(production\)/, - testIgnore: ["**/*.setup.ts"], + testIgnore: ["**/head-script-preload.test.ts", "**/*.setup.ts"], use: { ...devices["Desktop Chrome"], baseURL: `http://localhost:${PREVIEW_PORT}`, @@ -116,7 +120,11 @@ export default defineConfig({ { name: "dev", grep: /^(?!.*\(production\))/, - testIgnore: ["**/hmr*.test.ts", "**/*.setup.ts"], + testIgnore: [ + "**/hmr*.test.ts", + "**/head-script-preload.test.ts", + "**/*.setup.ts", + ], use: { ...devices["Desktop Chrome"], baseURL: `http://localhost:${DEV_PORT}`, @@ -126,7 +134,7 @@ export default defineConfig({ { name: "production", grep: /\(production\)/, - testIgnore: ["**/*.setup.ts"], + testIgnore: ["**/head-script-preload.test.ts", "**/*.setup.ts"], use: { ...devices["Desktop Chrome"], baseURL: `http://localhost:${PREVIEW_PORT}`, diff --git a/tests/cloudflare-basic/playwright.preload.config.ts b/tests/cloudflare-basic/playwright.preload.config.ts new file mode 100644 index 000000000..8c93a8db2 --- /dev/null +++ b/tests/cloudflare-basic/playwright.preload.config.ts @@ -0,0 +1,78 @@ +import { defineConfig, devices } from "@playwright/test"; +import { checkoutPortOffset } from "@shared/e2e"; + +const PORT_OFFSET = checkoutPortOffset(); +const DEV_PORT = 5318 + PORT_OFFSET; +const PREVIEW_PORT = 5319 + PORT_OFFSET; +const CACHE_DIR = "node_modules/.vite-cloudflare-basic-preload"; +const SERVER_ENV = { + ...process.env, + RANGO_E2E_HEAD_SCRIPTS: "preload", + RANGO_E2E_VITE_CACHE_DIR: CACHE_DIR, + RANGO_MANIFEST_TEXT: "1", + RANGO_E2E_RENDER_TIMEOUT: "1", +}; +const browserConfig = { ...devices["Desktop Chrome"] }; + +export default defineConfig({ + testDir: "./e2e", + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : 2, + reporter: [ + ["list"], + ...(process.env.CI ? [["github"], ["html", { open: "never" }]] : []), + ] as import("@playwright/test").ReporterDescription[], + globalTimeout: process.env.CI ? 14 * 60 * 1000 : undefined, + timeout: process.env.CI ? 60_000 : 30_000, + use: { + trace: "on-first-retry", + actionTimeout: process.env.CI ? 30_000 : 15_000, + }, + webServer: [ + { + command: `pnpm build && rm -rf ${CACHE_DIR} && pnpm dev --port ${DEV_PORT}`, + cwd: ".", + port: DEV_PORT, + reuseExistingServer: false, + env: SERVER_ENV, + }, + { + command: `pnpm preview --port ${PREVIEW_PORT}`, + cwd: ".", + port: PREVIEW_PORT, + reuseExistingServer: false, + env: SERVER_ENV, + }, + ], + projects: [ + { + name: "preload-dev-warmup", + testMatch: "**/head-script-preload-warmup.setup.ts", + use: { + ...browserConfig, + baseURL: `http://localhost:${DEV_PORT}`, + }, + }, + { + name: "preload-dev", + testMatch: "**/head-script-preload.test.ts", + grep: /^(?!.*\(production\))/, + use: { + ...browserConfig, + baseURL: `http://localhost:${DEV_PORT}`, + }, + dependencies: ["preload-dev-warmup"], + }, + { + name: "preload-production", + testMatch: "**/head-script-preload.test.ts", + grep: /\(production\)/, + use: { + ...browserConfig, + baseURL: `http://localhost:${PREVIEW_PORT}`, + }, + }, + ], +}); diff --git a/tests/cloudflare-basic/src/components/ClientPackageResolutionConsumer.tsx b/tests/cloudflare-basic/src/components/ClientPackageResolutionConsumer.tsx new file mode 100644 index 000000000..6a8a0f62e --- /dev/null +++ b/tests/cloudflare-basic/src/components/ClientPackageResolutionConsumer.tsx @@ -0,0 +1,10 @@ +"use client"; + +import { useDeepContext } from "rango-e2e-deep-context-lib/context"; +import type { ReactNode } from "react"; + +export function ClientPackageResolutionConsumer(): ReactNode { + return ( +

{useDeepContext() ?? "NOT_FOUND"}

+ ); +} diff --git a/tests/cloudflare-basic/src/pages/client-package-resolution.tsx b/tests/cloudflare-basic/src/pages/client-package-resolution.tsx new file mode 100644 index 000000000..57c0eb21c --- /dev/null +++ b/tests/cloudflare-basic/src/pages/client-package-resolution.tsx @@ -0,0 +1,16 @@ +import { Outlet } from "@rangojs/router/client"; +import { DeepContextServerWrapper } from "rango-e2e-deep-context-lib"; +import type { ReactNode } from "react"; +import { ClientPackageResolutionConsumer } from "../components/ClientPackageResolutionConsumer.js"; + +export function ClientPackageResolutionLayout(): ReactNode { + return ( + + + + ); +} + +export function ClientPackageResolutionPage(): ReactNode { + return ; +} diff --git a/tests/cloudflare-basic/src/router.named-routes.gen.ts b/tests/cloudflare-basic/src/router.named-routes.gen.ts index b2b342b43..6333f1326 100644 --- a/tests/cloudflare-basic/src/router.named-routes.gen.ts +++ b/tests/cloudflare-basic/src/router.named-routes.gen.ts @@ -20,6 +20,7 @@ export const NamedRoutes = { cachedHandles: "/cached-handles", cacheLab: "/cache-lab", catchAll: "/*", + clientPackageResolution: "/client-package-resolution", "composition.detail": "/composition/detail", "composition.index": "/composition", cookieOverlay: "/cookie-overlay", diff --git a/tests/cloudflare-basic/src/urls.tsx b/tests/cloudflare-basic/src/urls.tsx index ccb27a225..2e0aee619 100644 --- a/tests/cloudflare-basic/src/urls.tsx +++ b/tests/cloudflare-basic/src/urls.tsx @@ -36,6 +36,10 @@ import { CacheLabPulseLoader } from "./cache-lab-data.js"; import { AboutPage } from "./pages/about.js"; import { ScriptsDemoPage } from "./pages/scripts-demo.js"; import { CounterPage } from "./pages/counter.js"; +import { + ClientPackageResolutionLayout, + ClientPackageResolutionPage, +} from "./pages/client-package-resolution.js"; import { PprShellLayout, PprShellPricePage, @@ -537,6 +541,11 @@ export const urlpatterns = urls( path("/", HomePage, { name: "home" }), path("/about", AboutPage, { name: "about" }), path("/counter", CounterPage, { name: "counter" }), + layout(ClientPackageResolutionLayout, () => [ + path("/client-package-resolution", ClientPackageResolutionPage, { + name: "clientPackageResolution", + }), + ]), // Mixed example: an ordinary RSC layout wrapping a clientUrls() // group mounted through include() — the layout is a Server Component; // the pages keep browser-local matching and optimistic presentation. diff --git a/tests/cloudflare-basic/vite.config.ts b/tests/cloudflare-basic/vite.config.ts index 13b1472cc..603ca40b2 100644 --- a/tests/cloudflare-basic/vite.config.ts +++ b/tests/cloudflare-basic/vite.config.ts @@ -9,6 +9,15 @@ import { analyze } from "../../tools/bundle-analyze"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); +function testHeadScripts(): "preload" | undefined { + const value = process.env.RANGO_E2E_HEAD_SCRIPTS; + if (!value) return; + if (value === "preload") return value; + throw new Error(`Invalid RANGO_E2E_HEAD_SCRIPTS value: ${value}`); +} + +const headScripts = testHeadScripts(); + // A third-party-style resolver: maps "@parity/*" to ./src/parity/* via a // resolveId hook, deliberately WITHOUT a matching resolve.alias entry. Mirrors // how vite-tsconfig-paths resolves tsconfig `paths` (issue #500) and asserts @@ -33,6 +42,7 @@ function parityAliasPlugin(): Plugin { } export default defineConfig({ + cacheDir: process.env.RANGO_E2E_VITE_CACHE_DIR ?? "node_modules/.vite", // Inline the render-timeout e2e flag at build/transform time. The worker runs // in workerd, whose `process.env` is populated from wrangler vars/bindings — // NOT the host process — so a runtime `process.env.RANGO_E2E_RENDER_TIMEOUT` @@ -68,7 +78,11 @@ export default defineConfig({ // (consumer === "client"), so it compiles client components only; ssr/rsc // are left untouched (matches the upstream example). babel({ presets: [reactCompilerPreset()] }), - rango({ preset: "cloudflare", buildEnv: "auto" }), + rango({ + preset: "cloudflare", + buildEnv: "auto", + ...(headScripts ? { headScripts } : {}), + }), cloudflare({ configPath: "./wrangler.json", viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },