diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index fb28314f..78db2f6b 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -86,6 +86,7 @@ function examplesItems(prefix: string) { { text: 'next-runtime-snapshot', link: `${prefix}/examples/next-runtime-snapshot` }, { text: 'vite-devframe-hub', link: `${prefix}/examples/vite-devframe-hub` }, { text: 'next-devframe-hub', link: `${prefix}/examples/next-devframe-hub` }, + { text: 'rsbuild-devframe-hub', link: `${prefix}/examples/rsbuild-devframe-hub` }, ] satisfies DefaultTheme.NavItemWithLink[] } diff --git a/docs/examples/index.md b/docs/examples/index.md index 7fc4351d..f6a2c51c 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -14,6 +14,7 @@ End-to-end examples that exercise the full adapter surface, each a runnable app | [next-runtime-snapshot](./next-runtime-snapshot) | React (Next.js) | A Next.js App Router SPA over RPC, surfacing the host Node runtime. | | [vite-devframe-hub](./vite-devframe-hub) | Vanilla TypeScript (Vite) | A ~120-line Vite host wiring `@devframes/hub` end to end. | | [next-devframe-hub](./next-devframe-hub) | React (Next.js) | The same hub protocol, hosted from a Next.js route handler. | +| [rsbuild-devframe-hub](./rsbuild-devframe-hub) | React (Rsbuild) | The same hub protocol, hosted from an Rsbuild (Rspack) dev server. | ## Run any example diff --git a/docs/examples/rsbuild-devframe-hub.md b/docs/examples/rsbuild-devframe-hub.md new file mode 100644 index 00000000..99b72f15 --- /dev/null +++ b/docs/examples/rsbuild-devframe-hub.md @@ -0,0 +1,33 @@ +--- +outline: deep +--- + +# rsbuild-devframe-hub + +The same hub protocol as the [Vite host](./vite-devframe-hub), hosted from an **Rsbuild** (Rspack) dev server with a **React** browser UI. It wires [`@devframes/hub`](/guide/hub) through a small Rsbuild plugin that registers connect middleware and starts a side-car RPC / WebSocket server — proof that the hub is host-runtime-agnostic. + +Package: `rsbuild-devframe-hub` · framework: **React (Rsbuild)** + +## What it proves + +- `createHubContext()` boots a hub without any bundler-specific code path. +- A `DevframeHost` implementation plugs framework specifics (static mounts, connection meta, storage, origin resolution) into the hub uniformly. +- Because `rsbuild.config.ts` runs in Node — not through Rspack — the built-in plugins are imported directly, exactly like the Vite host; no bundler-ignored dynamic `import()` is needed. +- `mountDevframe(ctx, def)` registers any `DevframeDefinition` as a dock, serving both its SPA and its `__connection.json`. +- The built-in `hub:commands:execute` RPC dispatches any registered server command, regardless of how the host was constructed. +- The browser-side `connectDevframe({ baseURL: '/__hub/' })` discovers the WS endpoint via the plugin's `/__hub/__connection.json` middleware. +- The [JSON-render](/guide/json-render) hub integration with **registry replacement**: the host authors a view and projects it onto a `json-render` dock, and the React client renders it with the mini React registry **shared with the [Next host](./next-devframe-hub)** (rather than the Vue `@devframes/json-render-ui`). +- [Client-only docks](/guide/client-context#client-only-docks) the page registers itself with `context.docks.register()`: an iframe dock rendered from a Blob URL, and an interactive `json-render` dock whose spec is authored in the browser and carried inline in the dock entry (`view: { spec }`) — rendered by the same React registry as the server-authored view. + +## Run it + +```sh +pnpm install +pnpm --filter rsbuild-devframe-hub dev +``` + +Open the printed URL to see the docks, commands, messages, and terminals lists, plus a button that dispatches a sample command through `hub:commands:execute`. + +## Source + +[`examples/rsbuild-devframe-hub`](https://github.com/devframes/devframe/tree/main/examples/rsbuild-devframe-hub) diff --git a/examples/rsbuild-devframe-hub/README.md b/examples/rsbuild-devframe-hub/README.md new file mode 100644 index 00000000..900df09f --- /dev/null +++ b/examples/rsbuild-devframe-hub/README.md @@ -0,0 +1,46 @@ +# Rsbuild Devframe Hub + +A tiny, copyable **vite-devtools-style hub on Rsbuild**. [vite-devtools](https://github.com/vitejs/devtools) is the full viewer that docks many integrations behind one icon rail on top of `@devframes/hub`; this example wears the same shape — an icon dock, an iframe stage, and a drawer of hub subsystems — but hosts it from an [Rsbuild](https://rsbuild.rs) (Rspack) dev server, with a **React** browser UI. + +`src/rsbuild-devframe-hub.ts` is the entire host: a small Rsbuild plugin that wires `@devframes/hub` into an Rsbuild dev server. Because `rsbuild.config.ts` runs in Node — not through Rspack — the built-in plugins are imported directly, exactly like the Vite host; none of a bundled server's dynamic-`import()` dance is needed. + +## Run it + +```sh +pnpm install +pnpm --filter rsbuild-devframe-hub dev +``` + +Open the printed URL. The dock on the left lists every mounted tool with its icon: + +- **Git**, **Terminals**, **Code Server**, **RPC & State Inspector**, **A11y Inspector** — the built-in plugins, each a published `DevframeDefinition` mounted with `mountDevframe` +- **Rsbuild Demo Tool** / **Rsbuild Demo Tool B** — two trivial static SPAs that show the bare mount path + +Selecting a tool loads its SPA in the stage. The bottom drawer mirrors the hub's **Commands**, **Messages**, and **Terminals** subsystems, plus a button that dispatches a command through `hub:commands:execute`. + +The A11y Inspector shows a live axe-core report of this hub's own page. Rsbuild has no Vite `/@fs/`, so the host serves the plugin's in-page agent module same-origin from its own directory (`DevframeHost.mountStatic`) and attaches it as the a11y dock's `clientScript`; the hub client runtime — `createDevframeClientHost()` booted in `src/client/index.tsx` — imports it into the host page. Panel and agent share the Rsbuild origin their BroadcastChannel rides; hover a violation to ring the offending element in the hub UI. + +The **RPC & State Inspector** carries an **Instances** tab that lists every devframe dev server running on your machine. The host registers itself in the shared registry (`~/.devframe/instances/`) on startup via `registerDevframeInstance()`, so it shows up as "this instance"; start another example (`pnpm --filter vite-devframe-hub dev`, or any `node bin.mjs` CLI example) in a second terminal and it appears there too, each linking to its own SPA. Its **Data** tab also exposes the live `RsbuildDevServer` and its normalized config as a data source. + +## What the example proves + +- `createHubContext()` boots a hub with no bundler-specific code path; a `DevframeHost` impl plugs framework specifics (static mounts, connection meta, storage, origin) in uniformly +- `mountDevframe(ctx, def)` registers any `DevframeDefinition` as a dock and serves both its SPA and its `__connection.json`, so the embedded SPA connects straight back to the hub +- Real integrations work end to end through the mount path — the inspector lists every plugin's RPC functions live, terminals stream over the hub, and code-server launches an authenticated editor +- The browser reads `devframe:docks` / `devframe:commands` shared state and dispatches commands over RPC — no hub classes imported on the client +- `createDevframeClientHost()` boots the hub's framework-level client runtime in the host page: it publishes the shared client context and imports each dock's `clientScript` (here, the a11y agent) so plugins run code in the page being inspected +- The opt-in [JSON-render](https://devframe.dev) hub integration renders through a mini **React** registry **shared verbatim with the Next hub example** — a React host rendering a server-authored spec with its own components (the "registry replacement" path) instead of the Vue reference frontend + +## Build your own + +The dock UI is React in `src/client/`. To skin your own viewer, read the same shared-state keys and render them however you like. The host file is the part worth copying verbatim. + +## Files + +| File | Role | +|---|---| +| `src/rsbuild-devframe-hub.ts` | The Rsbuild host — hub context, static + connection-meta mounts, side-car WS, instance-registry registration | +| `rsbuild.config.ts` | Mounts the built-in plugins via the host's `devframes` option; serves + attaches the a11y agent as its dock's `clientScript`; registers the JSON-render and tabbed-tool docks | +| `src/client/index.tsx` | Boots the React app and the hub client runtime | +| `src/client/Page.tsx` | The React UI that consumes the hub protocol | +| `src/client/icons.ts` | Offline Phosphor icons for the dock | diff --git a/examples/rsbuild-devframe-hub/package.json b/examples/rsbuild-devframe-hub/package.json new file mode 100644 index 00000000..739c48a3 --- /dev/null +++ b/examples/rsbuild-devframe-hub/package.json @@ -0,0 +1,45 @@ +{ + "name": "rsbuild-devframe-hub", + "type": "module", + "version": "0.8.1", + "private": true, + "description": "Protocol-witness example — a tiny Rsbuild Devframe Hub built on @devframes/hub that exercises every hub subsystem end-to-end.", + "homepage": "https://github.com/devframes/devframe/tree/main/examples/rsbuild-devframe-hub", + "scripts": { + "dev": "pnpm -C ../.. run build && rsbuild dev", + "build": "rsbuild build", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@antfu/design": "catalog:frontend", + "@devframes/hub": "workspace:*", + "@devframes/json-render": "workspace:*", + "@devframes/plugin-a11y": "workspace:*", + "@devframes/plugin-assets": "workspace:*", + "@devframes/plugin-code-server": "workspace:*", + "@devframes/plugin-data-inspector": "workspace:*", + "@devframes/plugin-git": "workspace:*", + "@devframes/plugin-inspect": "workspace:*", + "@devframes/plugin-messages": "workspace:*", + "@devframes/plugin-og": "workspace:*", + "@devframes/plugin-terminals": "workspace:*", + "@json-render/react": "catalog:frontend", + "colorjs.io": "catalog:frontend", + "devframe": "workspace:*", + "dompurify": "catalog:frontend", + "json-render": "workspace:*", + "react": "catalog:frontend", + "react-dom": "catalog:frontend" + }, + "devDependencies": { + "@iconify-json/ph": "catalog:frontend", + "@rsbuild/core": "catalog:build", + "@rsbuild/plugin-react": "catalog:build", + "@types/react": "catalog:types", + "@types/react-dom": "catalog:types", + "@unocss/postcss": "catalog:frontend", + "get-port-please": "catalog:deps", + "pathe": "catalog:deps", + "unocss": "catalog:frontend" + } +} diff --git a/examples/rsbuild-devframe-hub/postcss.config.mjs b/examples/rsbuild-devframe-hub/postcss.config.mjs new file mode 100644 index 00000000..5db5b5d5 --- /dev/null +++ b/examples/rsbuild-devframe-hub/postcss.config.mjs @@ -0,0 +1,8 @@ +import UnoCSS from '@unocss/postcss' + +// Rsbuild's PostCSS loader resolves plugins eagerly, so pass the plugin +// instance directly (the string form leaves the ESM namespace unresolved — +// "[object Module] is not a PostCSS plugin"). +export default { + plugins: [UnoCSS()], +} diff --git a/examples/rsbuild-devframe-hub/public/data/notes.md b/examples/rsbuild-devframe-hub/public/data/notes.md new file mode 100644 index 00000000..f6a716fa --- /dev/null +++ b/examples/rsbuild-devframe-hub/public/data/notes.md @@ -0,0 +1,8 @@ +# Vite hub assets + +These files live in the Vite hub's `public/` directory, served by Vite at +the site root (`/`). The **Assets** dock manages this same directory, so: + +- previews load from the host's real URLs (`/logo.svg`, `/images/…`), +- editing, renaming, deleting, and uploading all round-trip to disk, +- the listing refreshes live as files change. diff --git a/examples/rsbuild-devframe-hub/public/data/site.json b/examples/rsbuild-devframe-hub/public/data/site.json new file mode 100644 index 00000000..8cb2d983 --- /dev/null +++ b/examples/rsbuild-devframe-hub/public/data/site.json @@ -0,0 +1,12 @@ +{ + "name": "Devframe Assets", + "description": "Sample fixtures for the assets plugin dev server.", + "theme": { + "primary": "#3a6a45", + "surface": "#ffffff" + }, + "nav": [ + { "label": "Home", "href": "/" }, + { "label": "Docs", "href": "/docs" } + ] +} diff --git a/examples/rsbuild-devframe-hub/public/favicon.svg b/examples/rsbuild-devframe-hub/public/favicon.svg new file mode 100644 index 00000000..1f91f717 --- /dev/null +++ b/examples/rsbuild-devframe-hub/public/favicon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/examples/rsbuild-devframe-hub/public/images/banner.svg b/examples/rsbuild-devframe-hub/public/images/banner.svg new file mode 100644 index 00000000..dcb53b02 --- /dev/null +++ b/examples/rsbuild-devframe-hub/public/images/banner.svg @@ -0,0 +1,10 @@ + + + + + + + + + Assets + diff --git a/examples/rsbuild-devframe-hub/public/images/tile-green.png b/examples/rsbuild-devframe-hub/public/images/tile-green.png new file mode 100644 index 00000000..8d0ca233 Binary files /dev/null and b/examples/rsbuild-devframe-hub/public/images/tile-green.png differ diff --git a/examples/rsbuild-devframe-hub/public/images/tile-sage.png b/examples/rsbuild-devframe-hub/public/images/tile-sage.png new file mode 100644 index 00000000..0877fe73 Binary files /dev/null and b/examples/rsbuild-devframe-hub/public/images/tile-sage.png differ diff --git a/examples/rsbuild-devframe-hub/public/logo.svg b/examples/rsbuild-devframe-hub/public/logo.svg new file mode 100644 index 00000000..d645a0bf --- /dev/null +++ b/examples/rsbuild-devframe-hub/public/logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/rsbuild-devframe-hub/public/robots.txt b/examples/rsbuild-devframe-hub/public/robots.txt new file mode 100644 index 00000000..c2a49f4f --- /dev/null +++ b/examples/rsbuild-devframe-hub/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Allow: / diff --git a/examples/rsbuild-devframe-hub/public/styles/theme.css b/examples/rsbuild-devframe-hub/public/styles/theme.css new file mode 100644 index 00000000..c75667c3 --- /dev/null +++ b/examples/rsbuild-devframe-hub/public/styles/theme.css @@ -0,0 +1,11 @@ +:root { + --color-primary: #3a6a45; + --color-surface: #ffffff; + --radius: 0.5rem; +} + +.button { + background: var(--color-primary); + border-radius: var(--radius); + color: #fff; +} diff --git a/examples/rsbuild-devframe-hub/rsbuild.config.ts b/examples/rsbuild-devframe-hub/rsbuild.config.ts new file mode 100644 index 00000000..53364de4 --- /dev/null +++ b/examples/rsbuild-devframe-hub/rsbuild.config.ts @@ -0,0 +1,122 @@ +import type { RsbuildPlugin } from '@rsbuild/core' +import { mountDevframe } from '@devframes/hub/node' +import { toJsonRenderDockEntry } from '@devframes/json-render/hub' +import a11yDevframe, { a11yAgentBundlePath } from '@devframes/plugin-a11y' +import assetsDevframe from '@devframes/plugin-assets' +import codeServerDevframe from '@devframes/plugin-code-server' +import dataInspectorDevframe from '@devframes/plugin-data-inspector' +import { registerDataSource } from '@devframes/plugin-data-inspector/registry' +import gitDevframe from '@devframes/plugin-git' +import inspectDevframe from '@devframes/plugin-inspect' +import messagesDevframe from '@devframes/plugin-messages' +import ogDevframe from '@devframes/plugin-og' +import terminalsDevframe from '@devframes/plugin-terminals' +import { defineConfig } from '@rsbuild/core' +import { pluginReact } from '@rsbuild/plugin-react' +import { createDashboardView } from 'json-render/dashboard' +import { basename, dirname } from 'pathe' +import { alias } from '../../alias' +import demoDevframe from './src/devframe' +import demoDevframeB from './src/devframe-b' +import { rsbuildDevframeHub } from './src/rsbuild-devframe-hub' +import tabbedToolDevframe from './src/tabbed-tool' + +// The host registers the live Rsbuild dev server as a data-inspector source — +// the registry is process-global, so this works from any plugin hook. Mirrors +// the Vite host's `vite:server` source. +function dataSources(): RsbuildPlugin { + return { + name: 'rsbuild-devframe-hub:data-sources', + setup(api) { + api.onBeforeStartDevServer(({ server }) => { + registerDataSource({ + id: 'rsbuild:server', + title: 'Rsbuild Dev Server', + description: 'The live RsbuildDevServer + normalized config serving this hub.', + icon: 'i-ph:lightning-duotone', + data: () => ({ port: server.port, config: api.getNormalizedConfig() }), + queries: [ + { title: 'Dev server port', query: 'port' }, + { title: 'Environment names', query: 'config.environments' }, + { + title: 'Resolved config (clean)', + query: 'config', + excludeFunctions: true, + excludeUnderscoreProps: true, + }, + ], + }) + }) + }, + } +} + +export default defineConfig({ + resolve: { alias }, + source: { + entry: { index: './src/client/index.tsx' }, + }, + html: { + template: './src/client/index.html', + }, + plugins: [ + pluginReact(), + dataSources(), + rsbuildDevframeHub({ + devframes: [ + demoDevframe, + demoDevframeB, + // Every built-in plugin, dogfooded end-to-end through the hub mount + // path — the same set a full viewer like vite-devtools would surface. + gitDevframe, + terminalsDevframe, + codeServerDevframe, + inspectDevframe, + dataInspectorDevframe, + a11yDevframe, + messagesDevframe, + ogDevframe, + assetsDevframe, + ], + // Attach the a11y inspector's in-page agent as its dock's client script. + // The hub client runtime (booted in src/client/index.tsx) imports it into + // this page so the docked panel scans the host live — no bespoke injection + // plugin needed. Rsbuild has no Vite `/@fs/`, so the host serves the built + // agent module same-origin from its own directory (see the host's + // `mountStatic`), and points the client script at that URL. + clientScripts: { + [a11yDevframe.id]: { importFrom: `/__rsbuild-a11y-agent/${basename(a11yAgentBundlePath)}` }, + }, + // Dogfood the opt-in JSON-render hub integration: author a view on the + // hub context and project it onto a `json-render` dock. The client host + // (src/client/index.tsx) renders it with a mini React registry shared with + // the Next hub example. + onContextReady: async (context) => { + // Serve the a11y agent module same-origin so the client script above + // resolves. `mountStatic` is the same host seam the mounted SPAs use. + context.host.mountStatic('/__rsbuild-a11y-agent/', dirname(a11yAgentBundlePath)) + + const view = createDashboardView(context) + context.docks.register(toJsonRenderDockEntry(view, { + id: 'example:json-render', + title: 'JSON Render', + icon: 'ph:layout-duotone', + category: 'app', + })) + + // Shared-iframe soft-navigation demo. mountDevframe serves the SPA and + // registers its iframe dock; the `dock` override marks it a `subTabs` + // anchor (a shared `frameId` + the postmessage protocol) so the client + // host attaches the frame-nav adapter, materializing one client-only + // dock per tab the SPA's shim reports — all sharing this one iframe. + await mountDevframe(context, tabbedToolDevframe, { + dock: { + category: 'app', + frameId: 'rsbuild-tabbed-tool', + subTabs: { protocol: 'postmessage' }, + }, + }) + }, + }), + ], +}) diff --git a/examples/rsbuild-devframe-hub/spa/rsbuild-demo-tool-b/index.html b/examples/rsbuild-devframe-hub/spa/rsbuild-demo-tool-b/index.html new file mode 100644 index 00000000..d311db84 --- /dev/null +++ b/examples/rsbuild-devframe-hub/spa/rsbuild-demo-tool-b/index.html @@ -0,0 +1,22 @@ + + + + + + Rsbuild Demo Tool B + + + +

Rsbuild Demo Tool B

+

Served from

+

A second demo devframe, mounted alongside the first to demonstrate dock switching.

+ + + diff --git a/examples/rsbuild-devframe-hub/spa/rsbuild-demo-tool/index.html b/examples/rsbuild-devframe-hub/spa/rsbuild-demo-tool/index.html new file mode 100644 index 00000000..8128c8be --- /dev/null +++ b/examples/rsbuild-devframe-hub/spa/rsbuild-demo-tool/index.html @@ -0,0 +1,22 @@ + + + + + + Rsbuild Demo Tool + + + +

Rsbuild Demo Tool

+

Served from

+

This SPA is mounted by rsbuild-devframe-hub via DevframeHost.mountStatic().

+ + + diff --git a/examples/rsbuild-devframe-hub/spa/rsbuild-tabbed-tool/index.html b/examples/rsbuild-devframe-hub/spa/rsbuild-tabbed-tool/index.html new file mode 100644 index 00000000..01023fe3 --- /dev/null +++ b/examples/rsbuild-devframe-hub/spa/rsbuild-tabbed-tool/index.html @@ -0,0 +1,175 @@ + + + + + + Tabbed Tool + + + +
+ Tabbed Tool + +
+
+
+

Overview

+

+ One iframe, many hub docks. This SPA hosts its own internal views + (Overview · Components · Timeline · Settings) + and exposes each as a first-class hub dock that shares + this single iframe. Switching docks soft-navigates here — no + reload — via the devframe:frame-nav postMessage protocol. +

+
+
Shared frameframeId · rsbuild-tabbed-tool
+
Transportwindow.postMessage
+
Docksclient-only, from manifest
+
Navbidirectional
+
+
+ +
+

Components

+

A stand-in view. Selecting the Components dock in the hub posts + navigate to this frame, which routes here client-side.

+
+
<Button />12 usages
+
<Dialog />4 usages
+
<Tabs />7 usages
+
+
+ +
+

Timeline

+

Navigate inside this frame (the tab bar above) and watch the + hub's active dock follow — the frame posts navigated back.

+
    +
  1. 10:02 — build started
  2. +
  3. 10:02 — 214 modules transformed
  4. +
  5. 10:03 — page reload
  6. +
+
+ +
+

Settings

+

The manifest each tab reports (title, icon, + navTarget) becomes a client-only dock in the hub — never + written to the devframe:docks shared state.

+
+
Themefollows OS
+
Telemetryoff
+
+
+
+ + + + diff --git a/examples/rsbuild-devframe-hub/src/client/Page.tsx b/examples/rsbuild-devframe-hub/src/client/Page.tsx new file mode 100644 index 00000000..07c14c02 --- /dev/null +++ b/examples/rsbuild-devframe-hub/src/client/Page.tsx @@ -0,0 +1,547 @@ +import type { DevframeRpcClient } from '@devframes/hub/client' +import type { + DevframeCommandEntry, + DevframeDockEntry, + DevframeMessageEntry, + DevframeTerminalSession, + DevframeViewIframe, +} from '@devframes/hub/types' +import type { DevframeJsonRenderSpec } from '@devframes/json-render' +import type { DevframeJsonRenderDockEntry } from '@devframes/json-render/hub' +import { connectDevframe, createDevframeClientHost, FRAME_NAV_CHANNEL } from '@devframes/hub/client' +import { useEffect, useMemo, useRef, useState } from 'react' +// The mini React json-render registry is shared verbatim with the Next hub +// example — a React host renders a server-authored spec with its own components +// (the "registry replacement" path) instead of the Vue reference frontend. +import { createReactJsonRenderDockRenderer } from '../../../next-devframe-hub/src/client/json-render/dock-renderer' +import { dockIconSvg } from './icons' + +const HUB_BASE = '/__hub/' + +interface Status { + text: string + kind?: 'ready' | 'error' +} + +type IframeDock = DevframeDockEntry & { type: 'iframe', url: string } +type TerminalSummary = Pick +type ClientHost = Awaited> + +function isIframeDock(d: DevframeDockEntry): d is IframeDock { + return d.type === 'iframe' && typeof (d as { url?: unknown }).url === 'string' +} + +// A dock this shell can display: an iframe, or one with a registered renderer +// (the json-render dock, rendered by the mini React registry). +const RENDERER_TYPES = new Set(['json-render']) +function isRenderableDock(d: DevframeDockEntry): boolean { + return isIframeDock(d) || RENDERER_TYPES.has(d.type) +} + +// One iframe is kept alive per `frameId` (shared-frame docks) or per dock id +// (plain iframe docks), so shared-frame member docks reuse the same element and +// soft-navigate rather than reload. +function frameKeyOf(e: DevframeDockEntry): string { + return (e as DevframeViewIframe).frameId ?? e.id +} + +// A self-contained document for the client-only dock, rendered from a Blob URL +// so the whole dock is synthesized in the browser with no server route. +function createClientNotesUrl(): string { + const html = ` + +

Client-only dock

+

This dock was registered in the browser with + host.context.docks.register(). It lives only in this page — it + never enters the devframe:docks shared state, so it is not synced + to the hub server or to any other connected viewer.

+

Patch it live through the returned handle with update() (its + badge was set that way), or remove it with dispose().

` + return URL.createObjectURL(new Blob([html], { type: 'text/html' })) +} + +// An *interactive* json-render spec synthesized entirely in the browser — the +// client-only counterpart to a server-authored view. Interactivity needs no +// server and no shared state: `{ $bindState }` inputs write straight into the +// view's own `state`, `{ $state }` reads mirror it live, and the buttons use the +// framework's built-in state actions (`pushState` / `setState`) to mutate that +// state — every change re-renders through the mini React registry. +function createClientPlaygroundSpec(clientType: string): DevframeJsonRenderSpec { + return { + root: 'root', + elements: { + root: { type: 'Stack', props: { gap: 14 }, children: ['head', 'hello', 'notes', 'env'] }, + + head: { type: 'Stack', props: { direction: 'row', gap: 8, align: 'center' }, children: ['icon', 'title', 'badge'] }, + icon: { type: 'Icon', props: { name: 'ph:sliders-horizontal-duotone', size: 22 }, children: [] }, + title: { type: 'Text', props: { text: 'Client Playground', variant: 'heading' }, children: [] }, + badge: { type: 'Badge', props: { text: 'client-only', variant: 'info' }, children: [] }, + + // ── Two-way binding: type a name, see it echoed live; toggle a switch ── + hello: { type: 'Card', props: { title: 'Say hello' }, children: ['helloBody'] }, + helloBody: { type: 'Stack', props: { gap: 10 }, children: ['nameInput', 'greetRow', 'compact'] }, + nameInput: { type: 'TextInput', props: { label: 'Your name', placeholder: 'Type your name…', value: { $bindState: '/form/name' } }, children: [] }, + greetRow: { type: 'Stack', props: { direction: 'row', gap: 6, align: 'center' }, children: ['greetLabel', 'greetName'] }, + greetLabel: { type: 'Text', props: { text: 'Hello,', variant: 'body', color: 'muted' }, children: [] }, + greetName: { type: 'Text', props: { text: { $state: '/form/name' }, variant: 'body', color: 'primary' }, children: [] }, + compact: { type: 'Switch', props: { label: 'Compact mode', value: { $bindState: '/prefs/compact' } }, children: [] }, + + // ── Actions mutate state → the DataTable re-renders ── + notes: { type: 'Card', props: { title: 'Notes' }, children: ['notesBody'] }, + notesBody: { type: 'Stack', props: { gap: 10 }, children: ['draftRow', 'notesTable', 'clearBtn'] }, + draftRow: { type: 'Stack', props: { direction: 'row', gap: 8, align: 'end' }, children: ['draftInput', 'addBtn'] }, + draftInput: { type: 'TextInput', props: { label: 'New note', placeholder: 'Write something…', value: { $bindState: '/draft' } }, children: [] }, + addBtn: { + type: 'Button', + props: { label: 'Add', variant: 'primary', icon: 'ph:plus' }, + // Built-in `pushState`: append the typed draft to /notes, then clear the input. + on: { press: { action: 'pushState', params: { statePath: '/notes', value: { text: { $state: '/draft' } }, clearStatePath: '/draft' } } }, + children: [], + }, + notesTable: { + type: 'DataTable', + props: { columns: [{ key: 'text', label: 'Note' }], rows: { $state: '/notes' }, height: 160 }, + children: [], + }, + clearBtn: { + type: 'Button', + props: { label: 'Clear all', variant: 'ghost', icon: 'ph:trash' }, + // Built-in `setState`: replace /notes with an empty array. + on: { press: { action: 'setState', params: { statePath: '/notes', value: [] } } }, + children: [], + }, + + env: { type: 'Card', props: { title: 'Environment', collapsible: true, defaultCollapsed: true }, children: ['envTable'] }, + envTable: { + type: 'KeyValueTable', + props: { + data: { + clientType, + language: navigator.language, + viewport: `${window.innerWidth}×${window.innerHeight}`, + }, + }, + children: [], + }, + }, + state: { + form: { name: '' }, + prefs: { compact: false }, + draft: '', + notes: [{ text: 'Authored entirely in the browser' }], + }, + } +} + +/** Fetches (and caches, for the component's lifetime) a dock icon's sanitized SVG. */ +function useDockIconSvg(icon: DevframeDockEntry['icon']): string | undefined { + const [svg, setSvg] = useState(undefined) + const key = typeof icon === 'string' ? icon : icon?.light + + useEffect(() => { + let cancelled = false + setSvg(undefined) + void dockIconSvg(icon).then((resolved) => { + if (!cancelled) + setSvg(resolved) + }) + return () => { + cancelled = true + } + // Re-fetch only when the icon id itself changes, not on every `icon` object identity. + }, [key]) + + return svg +} + +/** Render a dock icon, falling back to the title's initial while it loads or when unmapped. */ +function DockIcon({ entry }: { entry: DevframeDockEntry }) { + const svg = useDockIconSvg(entry.icon) + if (svg) + return + const initial = (entry.title?.[0] ?? '?').toUpperCase() + return {initial} +} + +export function Page() { + const [status, setStatus] = useState({ text: 'Connecting…' }) + const [docks, setDocks] = useState([]) + const [commands, setCommands] = useState([]) + const [messages, setMessages] = useState([]) + const [terminals, setTerminals] = useState([]) + const [pingResult, setPingResult] = useState('Run ping') + const [selectedDockId, setSelectedDockId] = useState(null) + const rpcRef = useRef(null) + const hostRef = useRef(null) + // The stage holds the kept-alive iframe pool; the panel hosts renderer docks. + const stageRef = useRef(null) + const panelRef = useRef(null) + const iframePoolRef = useRef>(new Map()) + const wiredRef = useRef>(new Set()) + + useEffect(() => { + let cancelled = false + let cleanup: (() => void) | undefined + + async function run() { + try { + const rpc = await connectDevframe({ baseURL: HUB_BASE }) + if (cancelled) + return + + rpcRef.current = rpc + setStatus({ text: `Connected · backend=${rpc.connectionMeta.backend}`, kind: 'ready' }) + + // Boot the framework-level client host: it builds the shared client + // context and imports each dock's client script into this page — e.g. + // the a11y inspector's in-page agent, which then scans this hub live. + // + // Register a mini React json-render renderer so the hub can display the + // `json-render` dock authored server-side via @devframes/json-render. + const clientHost = await createDevframeClientHost({ + rpc, + renderers: { 'json-render': createReactJsonRenderDockRenderer() }, + }) + hostRef.current = clientHost + const ctx = clientHost.context + + // Register a *client-only* dock — one this page synthesizes itself. + // Unlike the server-authored docks, it's registered on the client host + // context, so it never enters the `devframe:docks` shared state: it + // stays local to this page and is not synced to the hub server or other + // viewers. It merges into `ctx.docks.entries` alongside the server + // docks. `force` lets React StrictMode re-run this effect without + // tripping the duplicate-id guard. + const clientDock = ctx.docks.register({ + id: 'client-notes', + title: 'Client Notes', + icon: 'ph:note-pencil-duotone', + type: 'iframe', + url: createClientNotesUrl(), + category: 'app', + }, true) + // Patch it in place with the returned handle (the id is immutable). + clientDock.update({ badge: ctx.clientType }) + + // Register a second client-only dock — this one a *json-render* view the + // page authors itself, the richer sibling of the iframe dock above. Its + // spec is carried **inline** in the dock entry (`view.spec`), so it needs + // no shared state at all: it lives only in this page yet renders — and + // stays fully interactive (inputs, toggles, and buttons that mutate its + // state) — through the same `json-render` dock renderer (the mini React + // registry) as a server-authored view. `force` lets React StrictMode + // re-run this effect safely. + const clientJsonRenderDock = clientHost.context.docks.register({ + id: 'client-playground', + title: 'Client Playground', + icon: 'ph:sliders-horizontal-duotone', + type: 'json-render', + view: { spec: createClientPlaygroundSpec(clientHost.context.clientType) }, + category: 'app', + }, true) + + const docksState = await rpc.sharedState.get( + 'devframe:docks', + { initialValue: [] }, + ) + const commandsState = await rpc.sharedState.get( + 'devframe:commands', + { initialValue: [] }, + ) + + // Mirror the merged dock list (server docks + client-only docks) and the + // host's current selection into React state. Selection is owned by the + // client host (`switchEntry`) — that is what lets the frame-nav adapter + // hear a dock's `entry:activated` and drive shared-frame soft-navigation. + const syncDocks = () => setDocks([...ctx.docks.entries]) + const syncSelected = () => setSelectedDockId(ctx.docks.selectedId) + const renderCommands = () => setCommands([...(commandsState.value() ?? [])] as DevframeCommandEntry[]) + docksState.on('updated', syncDocks) + commandsState.on('updated', renderCommands) + syncDocks() + syncSelected() + renderCommands() + + // The frame-nav adapter registers/updates client-only member docks in + // response to a shared-frame anchor's manifest; re-sync (after it has + // reconciled, hence the microtask) so those docks appear in the list. + const onMessage = (event: MessageEvent) => { + const data = event.data as { channel?: string, from?: string } | undefined + if (data?.channel === FRAME_NAV_CHANNEL && data.from === 'frame') { + queueMicrotask(() => { + syncDocks() + syncSelected() + }) + } + } + window.addEventListener('message', onMessage) + + const refreshMessages = async () => { + const entries = await rpc.call( + 'example:rsbuild-devframe-hub:messages:list' as any, + ) as DevframeMessageEntry[] + if (!cancelled) + setMessages(entries) + } + + const refreshTerminals = async () => { + const sessions = await rpc.call( + 'example:rsbuild-devframe-hub:terminals:list' as any, + ) as TerminalSummary[] + if (!cancelled) + setTerminals(sessions) + } + + await refreshMessages() + await refreshTerminals() + + const interval = window.setInterval(() => { + void refreshMessages() + void refreshTerminals() + }, 2000) + + cleanup = () => { + window.clearInterval(interval) + window.removeEventListener('message', onMessage) + // Remove the client-only docks, then tear down the host + local DOM. + clientDock.dispose() + clientJsonRenderDock.dispose() + clientHost.dispose() + wiredRef.current.clear() + for (const el of iframePoolRef.current.values()) el.remove() + iframePoolRef.current.clear() + } + } + catch (err) { + if (!cancelled) + setStatus({ text: `Failed: ${(err as Error).message}`, kind: 'error' }) + } + } + + void run() + + return () => { + cancelled = true + cleanup?.() + rpcRef.current = null + } + }, []) + + const renderableDocks = useMemo(() => docks.filter(isRenderableDock), [docks]) + + // Wire each dock's state once so a selection change — from a click, or from + // the frame-nav adapter reacting to in-frame navigation — updates the UI. + useEffect(() => { + const ctx = hostRef.current?.context + if (!ctx) + return + for (const entry of docks) { + if (wiredRef.current.has(entry.id)) + continue + const state = ctx.docks.getStateById(entry.id) + if (!state) + continue + wiredRef.current.add(entry.id) + state.events.on('entry:activated', () => setSelectedDockId(ctx.docks.selectedId)) + } + }, [docks]) + + // Drive selection through the client host, and auto-select the first dock. + useEffect(() => { + const ctx = hostRef.current?.context + if (!ctx) + return + if (!selectedDockId && renderableDocks.length > 0) + void ctx.docks.switchEntry(renderableDocks[0].id) + }, [renderableDocks, selectedDockId]) + + const selectedDock = renderableDocks.find(d => d.id === selectedDockId) ?? null + const selectedIsIframe = selectedDock ? isIframeDock(selectedDock) : false + + // Keep-alive iframe pool: ensure + show the iframe for the selected dock's + // frame, hide the rest. Creating an iframe hands it to the client host + // (`domElements.iframe` + `dom:iframe:mounted`) so the frame-nav adapter can + // attach to a `subTabs` anchor. + useEffect(() => { + const ctx = hostRef.current?.context + const stage = stageRef.current + if (!ctx || !stage) + return + const pool = iframePoolRef.current + + if (selectedDock && isIframeDock(selectedDock)) { + const key = frameKeyOf(selectedDock) + let el = pool.get(key) + if (!el) { + el = document.createElement('iframe') + el.title = selectedDock.title + el.className = 'absolute inset-0 block h-full w-full border-0 bg-base' + el.src = selectedDock.url + stage.appendChild(el) + pool.set(key, el) + const state = ctx.docks.getStateById(selectedDock.id) + if (state) { + state.domElements.iframe = el + state.events.emit('dom:iframe:mounted', el) + } + } + for (const other of pool.values()) other.hidden = other !== el + } + else { + for (const other of pool.values()) other.hidden = true + } + }, [selectedDockId, docks, selectedDock]) + + // Mount a renderer dock (json-render) into the panel via the client host's + // renderer registry, disposing when the selection changes. + useEffect(() => { + const host = hostRef.current + const dock = selectedDock + const container = panelRef.current + if (!host || !dock || isIframeDock(dock) || !container) + return + let alive = true + let dispose: (() => void) | undefined + void host.context.renderers.mount(dock, container).then((d) => { + if (alive) + dispose = d + else d() + }) + return () => { + alive = false + dispose?.() + } + }, [selectedDockId, selectedIsIframe]) + + async function ping() { + if (!rpcRef.current) + return + try { + const result = await rpcRef.current.call( + 'hub:commands:execute' as any, + 'example:rsbuild-devframe-hub:ping', + ) + setPingResult(`Ping returned ${JSON.stringify(result)}`) + } + catch (err) { + setPingResult(`Error: ${(err as Error).message}`) + } + } + + const statusDot = status.kind === 'ready' ? 'bg-success' : status.kind === 'error' ? 'bg-error' : 'bg-neutral-400' + const titleClass = 'mb2 text-[0.68rem] uppercase tracking-wider color-muted' + const rowClass = 'rounded-lg border border-base bg-base px2.5 py1.5 text-xs font-mono' + + return ( +
+
+

+ + Rsbuild Devframe Hub +

+

+ + {status.text} +

+
+ +
+ + +
+ {/* Iframe docks are pooled here (one kept-alive iframe per frameId), + shown/hidden on switch so shared-frame tabs soft-navigate. */} +
+
+ +
+
+

Commands

+
    + {commands.length === 0 + ?
  • Waiting for snapshot…
  • + : commands.map(command => ( +
  • + {command.title} + {' '} + {command.id} +
  • + ))} +
+
+ +
+
+ +
+

Messages

+
    + {messages.length === 0 + ?
  • No messages yet.
  • + : messages.map(message => ( +
  • + + [ + {message.level} + ] + + {' '} + {message.message} +
  • + ))} +
+
+ +
+

Terminals

+
    + {terminals.length === 0 + ?
  • No terminal sessions.
  • + : terminals.map(terminal => ( +
  • + {terminal.title} + {' '} + {terminal.id} + {' '} + · + {' '} + {terminal.status} +
  • + ))} +
+
+
+
+ ) +} diff --git a/examples/rsbuild-devframe-hub/src/client/env.d.ts b/examples/rsbuild-devframe-hub/src/client/env.d.ts new file mode 100644 index 00000000..b58fd936 --- /dev/null +++ b/examples/rsbuild-devframe-hub/src/client/env.d.ts @@ -0,0 +1,3 @@ +// Side-effect CSS imports (`./uno.css`, `@antfu/design/styles.css`) carry no +// types — declare the module so `tsc` resolves them. +declare module '*.css' {} diff --git a/examples/rsbuild-devframe-hub/src/client/icons.ts b/examples/rsbuild-devframe-hub/src/client/icons.ts new file mode 100644 index 00000000..606d0e34 --- /dev/null +++ b/examples/rsbuild-devframe-hub/src/client/icons.ts @@ -0,0 +1,5 @@ +// Re-exports the shared devframe dock-icon resolver (see +// `design/dock-icon.ts`, a port of @antfu/design's `DisplayIconifyRemoteIcon`) +// so this surface stays in lockstep with every other hub shell instead of +// hand-maintaining its own icon table. +export { dockIconSvg } from '../../../../design/dock-icon' diff --git a/examples/rsbuild-devframe-hub/src/client/index.html b/examples/rsbuild-devframe-hub/src/client/index.html new file mode 100644 index 00000000..4175799a --- /dev/null +++ b/examples/rsbuild-devframe-hub/src/client/index.html @@ -0,0 +1,18 @@ + + + + + + Rsbuild Devframe Hub + + + +
+ + diff --git a/examples/rsbuild-devframe-hub/src/client/index.tsx b/examples/rsbuild-devframe-hub/src/client/index.tsx new file mode 100644 index 00000000..e6c13442 --- /dev/null +++ b/examples/rsbuild-devframe-hub/src/client/index.tsx @@ -0,0 +1,12 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import { Page } from './Page' +import './uno.css' +import '@antfu/design/styles.css' + +const container = document.getElementById('root')! +createRoot(container).render( + + + , +) diff --git a/examples/rsbuild-devframe-hub/src/client/uno.css b/examples/rsbuild-devframe-hub/src/client/uno.css new file mode 100644 index 00000000..cf9299f1 --- /dev/null +++ b/examples/rsbuild-devframe-hub/src/client/uno.css @@ -0,0 +1,7 @@ +/* The hub UI's design tokens, base layer, and semantic class vocabulary come + from @antfu/design. `@unocss` is replaced by UnoCSS (via `@unocss/postcss`, + see ../../postcss.config.mjs) with the generated preflights + utilities; + `@antfu/design/styles.css` (imported after this file in index.tsx) supplies + the token values + base element styling. */ + +@unocss; diff --git a/examples/rsbuild-devframe-hub/src/devframe-b.ts b/examples/rsbuild-devframe-hub/src/devframe-b.ts new file mode 100644 index 00000000..494ed422 --- /dev/null +++ b/examples/rsbuild-devframe-hub/src/devframe-b.ts @@ -0,0 +1,35 @@ +import type { DevframeHubContext } from '@devframes/hub/node' +import { fileURLToPath } from 'node:url' +import { defineDevframe } from 'devframe/types' +import pkg from '../package.json' with { type: 'json' } + +export default defineDevframe({ + id: 'example:rsbuild-demo-tool-b', + name: 'Rsbuild Demo Tool B', + version: pkg.version, + packageName: pkg.name, + homepage: pkg.homepage, + description: 'A second demo devframe — proves the dock switcher has more than one option.', + icon: 'ph:wrench-duotone', + basePath: '/__rsbuild-demo-tool-b/', + cli: { + distDir: fileURLToPath(new URL('../spa/rsbuild-demo-tool-b/', import.meta.url)), + }, + async setup(rawCtx) { + const ctx = rawCtx as unknown as DevframeHubContext + + ctx.commands.register({ + id: 'example:rsbuild-demo-tool-b:say-hello', + title: 'Demo B · Say Hello', + icon: 'ph:hand-waving-duotone', + category: 'demo', + handler: () => 'Hello from rsbuild-demo-tool-b!', + }) + + await ctx.messages.add({ + level: 'info', + message: 'Second demo devframe loaded', + description: 'A second mountDevframe() call — proves the switcher has more than one option.', + }) + }, +}) diff --git a/examples/rsbuild-devframe-hub/src/devframe.ts b/examples/rsbuild-devframe-hub/src/devframe.ts new file mode 100644 index 00000000..e32cef0d --- /dev/null +++ b/examples/rsbuild-devframe-hub/src/devframe.ts @@ -0,0 +1,44 @@ +import type { DevframeHubContext } from '@devframes/hub/node' +import { fileURLToPath } from 'node:url' +import { defineDevframe } from 'devframe/types' +import pkg from '../package.json' with { type: 'json' } + +/** + * A tiny demo devframe — proves a portable devframe can plug into the + * hub via {@link mountDevframe} and register its own docks / commands / + * messages on top of the host-provided subsystems. + * + * The `ctx` cast is the same one `@vitejs/devtools-kit`'s + * `createPluginFromDevframe` does today; the kit-level mount primitive + * threads a hub-augmented context through `d.setup`. + */ +export default defineDevframe({ + id: 'example:rsbuild-demo-tool', + name: 'Rsbuild Demo Tool', + version: pkg.version, + packageName: pkg.name, + homepage: pkg.homepage, + description: 'A tiny demo devframe that plugs into the hub via mountDevframe().', + icon: 'ph:rocket-duotone', + basePath: '/__rsbuild-demo-tool/', + cli: { + distDir: fileURLToPath(new URL('../spa/rsbuild-demo-tool/', import.meta.url)), + }, + async setup(rawCtx) { + const ctx = rawCtx as unknown as DevframeHubContext + + ctx.commands.register({ + id: 'example:rsbuild-demo-tool:say-hello', + title: 'Demo · Say Hello', + icon: 'ph:hand-waving-duotone', + category: 'demo', + handler: () => 'Hello from the demo command!', + }) + + await ctx.messages.add({ + level: 'info', + message: 'Demo devframe loaded', + description: 'Registered via mountDevframe(). Proves the devframe ↔ hub plug-in path works.', + }) + }, +}) diff --git a/examples/rsbuild-devframe-hub/src/rsbuild-devframe-hub.ts b/examples/rsbuild-devframe-hub/src/rsbuild-devframe-hub.ts new file mode 100644 index 00000000..1dff46d1 --- /dev/null +++ b/examples/rsbuild-devframe-hub/src/rsbuild-devframe-hub.ts @@ -0,0 +1,229 @@ +import type { DevframeHubContext } from '@devframes/hub/node' +import type { ClientScriptEntry } from '@devframes/hub/types' +import type { RsbuildPlugin } from '@rsbuild/core' +import type { DevframeInstanceRegistration, StartedServer } from 'devframe/node' +import type { DevframeDefinition, DevframeHost } from 'devframe/types' +import { homedir } from 'node:os' +import process from 'node:process' +import { defineHubRpcFunction } from '@devframes/hub' +import { createHubContext, mountDevframe } from '@devframes/hub/node' +import { DEVFRAME_CONNECTION_META_FILENAME } from 'devframe/constants' +import { registerDevframeInstance, startHttpAndWs } from 'devframe/node' +import { serveStaticNodeMiddleware } from 'devframe/utils/serve-static' +import { getPort } from 'get-port-please' +import { join } from 'pathe' + +export interface RsbuildDevframeHubOptions { + /** Mount path for the hub's connection-meta endpoint. Default: `/__hub/`. */ + base?: string + /** Preferred port for the side-car RPC/WS server. Default: a free port near 9787. */ + port?: number + /** Devframes to mount as docks. */ + devframes?: DevframeDefinition[] + /** + * Per-dock client scripts, keyed by devframe id. Attached to the mounted + * iframe dock so the hub client runtime imports them into the host page + * (e.g. the a11y inspector's in-page agent). + */ + clientScripts?: Record + /** + * Called once the hub context is created (after devframes are mounted), + * before the server starts. Lets the composition register extra surfaces on + * the context — e.g. a `json-render` dock via `@devframes/json-render`. + */ + onContextReady?: (context: DevframeHubContext) => void | Promise +} + +// Minimal hub-local RPCs — used by the UI for read-side data. A more +// ambitious hub host might hoist these into `@devframes/hub` itself. +const rsbuildHubMessagesList = defineHubRpcFunction({ + name: 'example:rsbuild-devframe-hub:messages:list', + type: 'static', + jsonSerializable: true, + setup: (ctx: DevframeHubContext) => ({ + async handler() { + return Array.from(ctx.messages.entries.values()) + }, + }), +}) + +const rsbuildHubTerminalsList = defineHubRpcFunction({ + name: 'example:rsbuild-devframe-hub:terminals:list', + type: 'static', + jsonSerializable: true, + setup: (ctx: DevframeHubContext) => ({ + async handler() { + return Array.from(ctx.terminals.sessions.values()).map(s => ({ + id: s.id, + title: s.title, + description: s.description, + status: s.status, + })) + }, + }), +}) + +/** + * A deliberately tiny Rsbuild plugin that wires `@devframes/hub` into an + * Rsbuild dev server: creates a hub context, implements the framework-neutral + * `DevframeHost` surface, and exposes the side-car WS endpoint to the browser + * via connect middleware at `__connection.json`. + * + * This file is the entire Rsbuild host — every other framework's hub host is + * the same shape: a thin layer that adapts a framework's dev server to the hub. + * Because `rsbuild.config.ts` runs in Node (not through Rspack), the built-in + * plugins are imported directly here, exactly like the Vite host — none of + * Next's bundler-ignored dynamic `import()` dance is needed. + */ +export function rsbuildDevframeHub(options: RsbuildDevframeHubOptions = {}): RsbuildPlugin { + const base = normalizeBase(options.base ?? '/__hub/') + + return { + name: 'rsbuild-devframe-hub', + + setup(api) { + let started: StartedServer | undefined + let registration: DevframeInstanceRegistration | undefined + + const teardown = async (): Promise => { + registration?.unregister() + registration = undefined + await started?.close().catch(() => {}) + started = undefined + } + + // `onBeforeStartDevServer` runs before Rsbuild registers its own + // middlewares, so the routes added here take precedence — the hub's + // `__connection.json` and every mounted SPA under `/__/` are + // served before Rsbuild's history-API fallback can claim them. + api.onBeforeStartDevServer(async ({ server }) => { + // Tear down any previous server first (a config edit restarts the dev + // server) so we neither leak the WS port nor leave a ghost registry + // record behind. + await teardown() + + const cwd = api.context.rootPath + // Prefer 9787 but keep booting when it's taken (e.g. a lingering + // previous instance) — walk the range, then fall back to a random free + // port. Clients discover whatever was chosen via `__connection.json`. + const port = options.port ?? await getPort({ port: 9787, portRange: [9787, 9887] }) + + // Serve the side-car's connection meta (`__connection.json`) at a URL + // base so a browser loaded there can discover the WS endpoint via + // `connectDevframe()`'s relative `./__connection.json` fetch. + const serveConnectionMeta = (metaBase: string): void => { + const metaPath = `${metaBase}${DEVFRAME_CONNECTION_META_FILENAME}` + server.middlewares.use(metaPath, (_req, res) => { + res.setHeader('Content-Type', 'application/json') + res.end(JSON.stringify({ backend: 'websocket', websocket: port })) + }) + } + + // Rsbuild resolves the dev server port before listening, so it is known + // here — the origin the browser loads the hub from, and the origin the + // mounted SPAs' relative asset URLs resolve against. + const origin = `http://localhost:${server.port}` + + const host: DevframeHost = { + mountStatic(base, distDir) { + server.middlewares.use(base, serveStaticNodeMiddleware(distDir)) + }, + // Serve `__connection.json` for each mounted devframe so its + // SPA connects to the hub without relying on same-origin parent-window + // inheritance — which breaks for cross-origin / sandboxed iframes. + mountConnectionMeta(base) { + serveConnectionMeta(base) + }, + resolveOrigin() { + return origin + }, + getStorageDir(scope) { + if (scope === 'workspace') + return join(cwd, '.devframe') + if (scope === 'project') + return join(cwd, 'node_modules/.rsbuild-devframe-hub') + return join(homedir(), '.rsbuild-devframe-hub') + }, + } + + const context = await createHubContext({ + cwd, + workspaceRoot: cwd, + mode: 'dev', + host, + builtinRpcDeclarations: [ + // The minimal hub ships its own `messages:list` and `terminals:list` + // RPCs so the UI has something to read. A full hub kit would likely + // standardise these (alongside the built-in `hub:commands:execute`) + // but for the demo we keep them kit-local. + rsbuildHubMessagesList, + rsbuildHubTerminalsList, + ], + }) + + // Seed a sample command directly on the hub so the UI shows something + // even without any plugged-in devframes. + context.commands.register({ + id: 'example:rsbuild-devframe-hub:ping', + title: 'Rsbuild Hub · Ping', + icon: 'ph:bell-duotone', + category: 'kit', + handler: () => 'pong', + }) + await context.messages.add({ + level: 'success', + message: 'Rsbuild Devframe Hub started', + description: `Side-car WS on port ${port}. ${options.devframes?.length ?? 0} devframe(s) registered.`, + }) + + for (const def of options.devframes ?? []) { + const clientScript = options.clientScripts?.[def.id] + await mountDevframe(context, def, clientScript ? { dock: { clientScript } } : undefined) + } + + await options.onContextReady?.(context) + + started = await startHttpAndWs({ + context, + port, + // Single-user localhost demo: the side-car is reachable only on + // loopback, so it opts out of the gate for a no-friction dev + // experience. A hub reachable beyond localhost should gate (see + // `docs/guide/security.md`). + auth: false, + }) + + // Tell the hub UI (served at `base`) where to find the WS endpoint. + serveConnectionMeta(base) + + // Record this hub in the global instance registry (`~/.devframe/instances/`) + // so discovery tooling — `devframe connect` and the inspector's Instances + // tab — lists it like any standalone devframe. `createDevServer` registers + // automatically; an in-process host like this one registers explicitly, + // reusing the Rsbuild dev server's own origin (where `__connection.json` + // is served). + const url = new URL(origin) + registration = registerDevframeInstance({ + pid: process.pid, + port: Number(url.port) || (url.protocol === 'https:' ? 443 : 80), + origin, + basePath: base, + id: 'example:rsbuild-devframe-hub', + name: 'Rsbuild Devframe Hub', + rootDir: cwd, + mcp: null, + startedAt: Date.now(), + }) + }) + + api.onCloseDevServer(teardown) + }, + } +} + +function normalizeBase(base: string): string { + let out = base.startsWith('/') ? base : `/${base}` + if (!out.endsWith('/')) + out = `${out}/` + return out +} diff --git a/examples/rsbuild-devframe-hub/src/tabbed-tool.ts b/examples/rsbuild-devframe-hub/src/tabbed-tool.ts new file mode 100644 index 00000000..6a6c9370 --- /dev/null +++ b/examples/rsbuild-devframe-hub/src/tabbed-tool.ts @@ -0,0 +1,35 @@ +import type { DevframeHubContext } from '@devframes/hub/node' +import { fileURLToPath } from 'node:url' +import { defineDevframe } from 'devframe/types' +import pkg from '../package.json' with { type: 'json' } + +/** + * A demo of **shared-iframe soft navigation**. This devframe is a single SPA + * with several internal views (Overview / Components / Timeline / Settings). + * Mounted as a `subTabs` anchor (see `rsbuild.config.ts`), the hub's client host + * attaches its frame-nav adapter: the SPA's `postMessage` shim reports its tabs, + * each becomes a client-only hub dock sharing this one iframe, and switching + * docks soft-navigates inside it instead of reloading — a unified home for a + * multi-tab tool like Nuxt DevTools. + */ +export default defineDevframe({ + id: 'example:rsbuild-tabbed-tool', + name: 'Tabbed Tool', + version: pkg.version, + packageName: pkg.name, + homepage: pkg.homepage, + description: 'A multi-view SPA hosted as shared-iframe hub docks with soft navigation.', + icon: 'ph:squares-four-duotone', + basePath: '/__rsbuild-tabbed-tool/', + cli: { + distDir: fileURLToPath(new URL('../spa/rsbuild-tabbed-tool/', import.meta.url)), + }, + async setup(rawCtx) { + const ctx = rawCtx as unknown as DevframeHubContext + await ctx.messages.add({ + level: 'info', + message: 'Tabbed Tool mounted as a shared-iframe anchor', + description: 'Its tabs surface as client-only docks that soft-navigate one iframe.', + }) + }, +}) diff --git a/examples/rsbuild-devframe-hub/tsconfig.json b/examples/rsbuild-devframe-hub/tsconfig.json new file mode 100644 index 00000000..94fa930c --- /dev/null +++ b/examples/rsbuild-devframe-hub/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "module": "ESNext", + "moduleResolution": "Bundler", + "noEmit": true, + "esModuleInterop": true, + "isolatedDeclarations": false + }, + "include": ["src", "rsbuild.config.ts", "uno.config.ts"] +} diff --git a/examples/rsbuild-devframe-hub/uno.config.ts b/examples/rsbuild-devframe-hub/uno.config.ts new file mode 100644 index 00000000..5ef0e23f --- /dev/null +++ b/examples/rsbuild-devframe-hub/uno.config.ts @@ -0,0 +1,26 @@ +import { fileURLToPath } from 'node:url' +import { mergeConfigs } from 'unocss' +import { designConfig } from '../../design/uno.config' + +// The hub UI composes the shared devframe base (see `design/uno.config.ts`). +// `@unocss/postcss` (see postcss.config.mjs) loads this config; absolute globs +// keep class extraction working regardless of the directory PostCSS runs in. +const client = fileURLToPath(new URL('./src/client', import.meta.url)) +// The mini React json-render registry is shared with the Next hub example — +// scan it too so its class strings are extracted here. +const nextJsonRender = fileURLToPath(new URL('../next-devframe-hub/src/client/json-render', import.meta.url)) + +export default mergeConfigs([ + designConfig, + { + // The mini React json-render registry sets `badge-color-` from a fixed + // set — these literals live in source, but safelist them to be explicit. + safelist: ['badge-color-green', 'badge-color-amber', 'badge-color-red', 'badge-color-blue'], + content: { + filesystem: [ + `${client}/**/*.{ts,tsx,html}`, + `${nextJsonRender}/**/*.{ts,tsx}`, + ], + }, + }, +]) diff --git a/knip.jsonc b/knip.jsonc index e6c64bc5..57029e75 100644 --- a/knip.jsonc +++ b/knip.jsonc @@ -61,6 +61,18 @@ "config": ["src/client/postcss.config.mjs"] } }, + "examples/rsbuild-devframe-hub": { + // The root-level PostCSS config drives `@unocss/postcss`; knip's postcss + // plugin only treats it as an entry once the config location is declared. + "postcss": { + "config": ["postcss.config.mjs"] + }, + // The mini React json-render registry is imported from the Next hub + // example's source (shared verbatim). Knip attributes `@json-render/react` + // usage to that workspace, but this example bundles it and depends on it + // at runtime. + "ignoreDependencies": ["@json-render/react"] + }, "packages/devframe": { // Every `package.json#exports` subpath maps to one of these source // files (see `tsdown.config.ts`'s `serverEntries`/`clientEntries`). diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c3d9fca..dc033a71 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,6 +12,12 @@ catalogs: '@preact/preset-vite': specifier: ^2.10.6 version: 2.10.6 + '@rsbuild/core': + specifier: ^2.1.10 + version: 2.1.10 + '@rsbuild/plugin-react': + specifier: ^2.1.0 + version: 2.1.0 '@vitejs/plugin-vue': specifier: ^6.0.8 version: 6.0.8 @@ -681,6 +687,94 @@ importers: specifier: catalog:deps version: 8.21.1 + examples/rsbuild-devframe-hub: + dependencies: + '@antfu/design': + specifier: catalog:frontend + version: 0.3.2(@antfu/utils@9.3.0)(@iconify-json/catppuccin@1.2.17)(@tanstack/vue-virtual@3.13.30(vue@3.5.40(typescript@6.0.3)))(@unocss/core@66.7.5)(colorjs.io@0.7.1)(dompurify@3.4.12)(floating-vue@5.2.2(vue@3.5.40(typescript@6.0.3)))(playwright@1.62.0)(reka-ui@2.10.1(vue@3.5.40(typescript@6.0.3)))(splitpanes@4.1.2(vue@3.5.40(typescript@6.0.3)))(unocss@66.7.5(@unocss/postcss@66.7.5(postcss@8.5.23))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vue@3.5.40(typescript@6.0.3)) + '@devframes/hub': + specifier: workspace:* + version: link:../../packages/hub + '@devframes/json-render': + specifier: workspace:* + version: link:../../packages/json-render + '@devframes/plugin-a11y': + specifier: workspace:* + version: link:../../plugins/a11y + '@devframes/plugin-assets': + specifier: workspace:* + version: link:../../plugins/assets + '@devframes/plugin-code-server': + specifier: workspace:* + version: link:../../plugins/code-server + '@devframes/plugin-data-inspector': + specifier: workspace:* + version: link:../../plugins/data-inspector + '@devframes/plugin-git': + specifier: workspace:* + version: link:../../plugins/git + '@devframes/plugin-inspect': + specifier: workspace:* + version: link:../../plugins/inspect + '@devframes/plugin-messages': + specifier: workspace:* + version: link:../../plugins/messages + '@devframes/plugin-og': + specifier: workspace:* + version: link:../../plugins/og + '@devframes/plugin-terminals': + specifier: workspace:* + version: link:../../plugins/terminals + '@json-render/react': + specifier: catalog:frontend + version: 0.19.0(react@19.2.8)(zod@4.4.3) + colorjs.io: + specifier: catalog:frontend + version: 0.7.1 + devframe: + specifier: workspace:* + version: link:../../packages/devframe + dompurify: + specifier: catalog:frontend + version: 3.4.12 + json-render: + specifier: workspace:* + version: link:../json-render + react: + specifier: catalog:frontend + version: 19.2.8 + react-dom: + specifier: catalog:frontend + version: 19.2.8(react@19.2.8) + devDependencies: + '@iconify-json/ph': + specifier: catalog:frontend + version: 1.2.2 + '@rsbuild/core': + specifier: catalog:build + version: 2.1.10 + '@rsbuild/plugin-react': + specifier: catalog:build + version: 2.1.0(@rsbuild/core@2.1.10)(@rspack/core@2.1.8(@swc/helpers@0.5.23)) + '@types/react': + specifier: catalog:types + version: 19.2.17 + '@types/react-dom': + specifier: catalog:types + version: 19.2.3(@types/react@19.2.17) + '@unocss/postcss': + specifier: catalog:frontend + version: 66.7.5(postcss@8.5.23) + get-port-please: + specifier: catalog:deps + version: 3.2.0 + pathe: + specifier: catalog:deps + version: 2.0.3 + unocss: + specifier: catalog:frontend + version: 66.7.5(@unocss/postcss@66.7.5(postcss@8.5.23))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + examples/streaming-chat: dependencies: '@antfu/design': @@ -1031,7 +1125,7 @@ importers: devDependencies: '@nuxt/kit': specifier: catalog:build - version: 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + version: 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) '@types/node': specifier: catalog:types version: 26.1.2 @@ -1040,7 +1134,7 @@ importers: version: link:../devframe nuxt: specifier: catalog:build - version: 4.5.1(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@parcel/watcher@2.5.6)(@types/node@26.1.2)(@vue/compiler-sfc@3.5.40)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.8.0(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(oxc-parser@0.140.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.0)(rollup@4.60.3))(rollup@4.60.3)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(tsx@4.23.1)(typescript@6.0.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(yaml@2.9.0) + version: 4.5.1(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@parcel/watcher@2.5.6)(@rspack/core@2.1.8(@swc/helpers@0.5.23))(@types/node@26.1.2)(@vue/compiler-sfc@3.5.40)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.8.0(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(oxc-parser@0.140.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.0)(rollup@4.60.3))(rollup@4.60.3)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(tsx@4.23.1)(typescript@6.0.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(yaml@2.9.0) tsdown: specifier: catalog:build version: 0.22.14(@volar/typescript@2.4.28)(oxc-resolver@11.24.2)(tsx@4.23.1)(typescript@6.0.3) @@ -2097,6 +2191,9 @@ packages: '@emnapi/core@1.11.2': resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} + '@emnapi/core@1.11.3': + resolution: {integrity: sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==} + '@emnapi/core@1.9.2': resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} @@ -2112,6 +2209,9 @@ packages: '@emnapi/runtime@1.11.2': resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} + '@emnapi/runtime@1.11.3': + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + '@emnapi/runtime@1.9.2': resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} @@ -2121,6 +2221,9 @@ packages: '@emnapi/wasi-threads@1.2.2': resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@emnapi/wasi-threads@1.2.3': + resolution: {integrity: sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==} + '@es-joy/jsdoccomment@0.88.0': resolution: {integrity: sha512-GK/HL/claLLNo5KG705auIlZMwEtmn88ofSGuLsmVZwKBqMPJhW9DiznYNq07QEqz9BPtA3LBfYImtZmhVvRAw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -4356,6 +4459,113 @@ packages: cpu: [x64] os: [win32] + '@rsbuild/core@2.1.10': + resolution: {integrity: sha512-lwxC5w88U2AMv6aNwG3VH7+AV33N4JJQjD//egVWFsMbV+OE/bnfCsurSpX8s3lGyRYkJMwUVN+YXMbmmYZFfw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + core-js: '>= 3.0.0' + peerDependenciesMeta: + core-js: + optional: true + + '@rsbuild/plugin-react@2.1.0': + resolution: {integrity: sha512-RQTIAWB/CwPjoWt9iAl+8HixeQVgZ7kEIBrWPCixfITyHdiD84h0YpUTpEUuz6kGHw1KXT9mHZ3Rwy6WG7aRDA==} + peerDependencies: + '@rsbuild/core': ^2.0.0 + peerDependenciesMeta: + '@rsbuild/core': + optional: true + + '@rspack/binding-darwin-arm64@2.1.8': + resolution: {integrity: sha512-kia+eWtyWPvR4ntg1bWYoVU8nLPbUg2fG3zgBEocsTcsh5ZENSiEPxEKymDgMyIMONUqj611E0775cdUBoNmqw==} + cpu: [arm64] + os: [darwin] + + '@rspack/binding-darwin-x64@2.1.8': + resolution: {integrity: sha512-08pBkFhlD3Y3Qzh94w/Fc3skaIE3e96kl2P14m8+tnYTcglpOfpA2OwS3iHt9fOqy0HjoAVe6/MW3cBgs5iabA==} + cpu: [x64] + os: [darwin] + + '@rspack/binding-linux-arm64-gnu@2.1.8': + resolution: {integrity: sha512-KLniMc9GzhKpVqhPzaJo3KJwzdAllXVVqZIk/uL1QipXOxs57fgM4u7IexKPFVla0o/u1PQG/Ah2YLDmda24Ow==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rspack/binding-linux-arm64-musl@2.1.8': + resolution: {integrity: sha512-yUKAxHNGnICtw5RnxFWu4dHtsz/tdt7rbeFcsINNVre9HcrRxf5XP+FbOGL/SMxd9oM9XCo10paU2WckTKwbEA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rspack/binding-linux-riscv64-gnu@2.1.8': + resolution: {integrity: sha512-gg4S1jaitwYPHR9HZ3zNGH1EK2GXINm66p4kEpOP1gbc+akyOouVF/dMcu9NGPlRg58FbEhVRZYKu7Z/zcpKHg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rspack/binding-linux-riscv64-musl@2.1.8': + resolution: {integrity: sha512-b/aU5j1h368SLNyz5u+flqpZVhzSZ1UIslaj9sZJuAvqkGWv3xsjc/28/PTo/RYXCxd0FNVAxTxWHKvRiAAS8w==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rspack/binding-linux-x64-gnu@2.1.8': + resolution: {integrity: sha512-EyegohSx0BJRqieCg9f/caCqFARRWkqI5hwJt6k530MoOTLeq8I3vsbeg24/2MktwIC1dmJi8bl0+WhPKQs4eQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rspack/binding-linux-x64-musl@2.1.8': + resolution: {integrity: sha512-I6E+goN+UQ297q4r1qdbiAyNCI3t0+a5Y0xDIAPOZfRDRxDTnH/LF8/y65gjsJoKRKyn7zxRC0T/NURTkRNQ9A==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rspack/binding-wasm32-wasi@2.1.8': + resolution: {integrity: sha512-om7GAKWAU3lcSvbCon2m7mzw8v9OTrO2LW2MZ1lGe/uVJJmwGGkl9HVoXFyWFLrN6YVFyx8iP+AkN4owDWB9Cw==} + cpu: [wasm32] + + '@rspack/binding-win32-arm64-msvc@2.1.8': + resolution: {integrity: sha512-WDnsP/SUb9zbxyGX9XjPw5AXrX86u5oidn0MDdfJduOOqdCSpHwmRjlQ8NUJhbBq9WqVJMFlcab7NwZVWX/yyg==} + cpu: [arm64] + os: [win32] + + '@rspack/binding-win32-ia32-msvc@2.1.8': + resolution: {integrity: sha512-QiMQMPNDiY3dhhaIdaFPzcPDC06cEYkNY89ea+EmDvNVgZq6V+2mFS/WnzZVMeEbGAYJCjsv/ABhhLT1hlYMvg==} + cpu: [ia32] + os: [win32] + + '@rspack/binding-win32-x64-msvc@2.1.8': + resolution: {integrity: sha512-b7sA5eB64vo2mbsuc//MOYzVLeCKHPn0dfP/GmNEoHdWbhRgZ/orZLWurYMQj04ELTLW6YCJEy59g5KRzNYHfw==} + cpu: [x64] + os: [win32] + + '@rspack/binding@2.1.8': + resolution: {integrity: sha512-tmAyHzDbPiy8V7HvQqtuPsbs6dPgwV0YjzW5XrPRV9gzf+Hdm7pvsZJKE1QKO9WV5RuvGYav98xIX6O+abZxzQ==} + + '@rspack/core@2.1.8': + resolution: {integrity: sha512-na1kyA6Mj8/LWw9O3A8NsrG9rNKN3Iq2WiXrEuIwsU5r/Nl/evm3hO7bWKHxgsRyydI6W7okwx3MXgf8rzel6g==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@module-federation/runtime-tools': ^0.24.1 || ^2.0.0 + '@swc/helpers': ^0.5.23 + peerDependenciesMeta: + '@module-federation/runtime-tools': + optional: true + '@swc/helpers': + optional: true + + '@rspack/plugin-react-refresh@2.0.2': + resolution: {integrity: sha512-dGNZiCxQxgAUI9sah7gd8u+O7OJZRCmqtEJNDOd8xW5RqcieC86F7p5qcShyw6onH5pKf57evpr2VjGbaFGkZg==} + peerDependencies: + '@rspack/core': ^2.0.0 + react-refresh: '>=0.10.0 <1.0.0' + peerDependenciesMeta: + '@rspack/core': + optional: true + '@shikijs/core@4.3.1': resolution: {integrity: sha512-ANMDxuaPsNMdDC1m4vfvhlDmJweMwkE5XitTwrq2rWHx5jM+dlm4MmHt2PP6t0uejfR77SuhrhJ0zEijIF/uhA==} engines: {node: '>=20'} @@ -4552,6 +4762,9 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@swc/helpers@0.5.23': + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} + '@tanstack/virtual-core@3.17.2': resolution: {integrity: sha512-w43MvWvmShpb6kIC9MOoLyUkLmRTLPjt61bHWs+X29hACSpX+n8DvgZ3qM7cUfflKlRRcHR9KVJE6TmcqnQvcA==} @@ -8206,6 +8419,10 @@ packages: react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + react@19.2.8: resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==} engines: {node: '>=0.10.0'} @@ -9981,17 +10198,17 @@ snapshots: '@docsearch/sidepanel-js@4.6.3': {} - '@dxup/nuxt@0.5.3(esbuild@0.28.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))': + '@dxup/nuxt@0.5.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))': dependencies: '@dxup/unimport': 0.1.2 - '@nuxt/kit': 4.5.1(magic-string@0.30.21)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + '@nuxt/kit': 4.5.1(magic-string@0.30.21)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) '@vue/compiler-dom': 3.5.40 chokidar: 5.0.0 knitwork: 1.3.0 magic-string: 0.30.21 pathe: 2.0.3 tinyglobby: 0.2.17 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) transitivePeerDependencies: - '@farmfe/core' - '@rspack/core' @@ -10039,6 +10256,12 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/core@1.11.3': + dependencies: + '@emnapi/wasi-threads': 1.2.3 + tslib: 2.8.1 + optional: true + '@emnapi/core@1.9.2': dependencies: '@emnapi/wasi-threads': 1.2.1 @@ -10065,6 +10288,11 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.9.2': dependencies: tslib: 2.8.1 @@ -10080,6 +10308,11 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/wasi-threads@1.2.3': + dependencies: + tslib: 2.8.1 + optional: true + '@es-joy/jsdoccomment@0.88.0': dependencies: '@types/estree': 1.0.9 @@ -10567,6 +10800,13 @@ snapshots: '@tybys/wasm-util': 0.10.3 optional: true + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)': + dependencies: + '@emnapi/core': 1.11.3 + '@emnapi/runtime': 1.11.3 + '@tybys/wasm-util': 0.10.3 + optional: true + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': dependencies: '@emnapi/core': 1.9.2 @@ -10652,9 +10892,9 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@3.3.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))': + '@nuxt/devtools-kit@3.3.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))': dependencies: - '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) execa: 8.0.1 vite: 8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0) transitivePeerDependencies: @@ -10675,11 +10915,11 @@ snapshots: pkg-types: 2.3.1 semver: 7.8.5 - '@nuxt/devtools@3.3.1(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(srvx@0.11.22)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': + '@nuxt/devtools@3.3.1(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(srvx@0.11.22)(supports-color@10.2.2)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': dependencies: - '@nuxt/devtools-kit': 3.3.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + '@nuxt/devtools-kit': 3.3.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) '@nuxt/devtools-wizard': 3.3.1 - '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) '@vue/devtools-core': 8.1.2(vue@3.5.40(typescript@6.0.3)) '@vue/devtools-kit': 8.1.5 birpc: 4.0.0 @@ -10707,7 +10947,7 @@ snapshots: tinyglobby: 0.2.17 unstorage: 1.17.5(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(srvx@0.11.22) vite: 8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0) - vite-plugin-inspect: 11.3.3(@nuxt/kit@4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))))(supports-color@10.2.2)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + vite-plugin-inspect: 11.3.3(@nuxt/kit@4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))))(supports-color@10.2.2)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) vite-plugin-vue-tracer: 1.3.0(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) which: 6.0.1 ws: 8.21.1 @@ -10741,7 +10981,7 @@ snapshots: - utf-8-validate - vue - '@nuxt/kit@4.5.1(magic-string@0.30.21)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))': + '@nuxt/kit@4.5.1(magic-string@0.30.21)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))': dependencies: c12: 3.3.4(magicast@0.5.2) consola: 3.4.2 @@ -10761,7 +11001,7 @@ snapshots: scule: 1.3.0 tinyglobby: 0.2.17 ufo: 1.6.4 - unctx: 3.0.0(magic-string@0.30.21)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + unctx: 3.0.0(magic-string@0.30.21)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) untyped: 2.0.0 verkit: 0.2.0 transitivePeerDependencies: @@ -10771,7 +11011,7 @@ snapshots: - rolldown - unplugin - '@nuxt/kit@4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))': + '@nuxt/kit@4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))': dependencies: c12: 3.3.4(magicast@0.5.2) consola: 3.4.2 @@ -10791,7 +11031,7 @@ snapshots: scule: 1.3.0 tinyglobby: 0.2.17 ufo: 1.6.4 - unctx: 3.0.0(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + unctx: 3.0.0(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) untyped: 2.0.0 verkit: 0.2.0 transitivePeerDependencies: @@ -10801,11 +11041,11 @@ snapshots: - rolldown - unplugin - '@nuxt/nitro-server@4.5.1(71bc86bb730f85a69e3066bf13024c10)': + '@nuxt/nitro-server@4.5.1(0f35f3b419903b84781fca0188e19e5e)': dependencies: '@nuxt/devalue': 2.0.2 - '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) - '@unhead/vue': 3.2.3(esbuild@0.28.0)(lightningcss@1.32.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) + '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + '@unhead/vue': 3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(lightningcss@1.32.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) '@vue/shared': 3.5.40 consola: 3.4.2 defu: 6.1.7 @@ -10815,19 +11055,19 @@ snapshots: escape-string-regexp: 5.0.0 exsolve: 1.1.0 h3: 1.15.11(srvx@0.11.22) - impound: 1.1.6(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + impound: 1.1.6(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) klona: 2.0.6 mocked-exports: 0.1.1 - nitropack: 2.13.4(oxc-parser@0.140.0)(rolldown@1.2.0)(srvx@0.11.22)(supports-color@10.2.2)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + nitropack: 2.13.4(@rspack/core@2.1.8(@swc/helpers@0.5.23))(oxc-parser@0.140.0)(rolldown@1.2.0)(srvx@0.11.22)(supports-color@10.2.2)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) nostics: 1.2.0 - nuxt: 4.5.1(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@parcel/watcher@2.5.6)(@types/node@26.1.2)(@vue/compiler-sfc@3.5.40)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.8.0(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(oxc-parser@0.140.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.0)(rollup@4.60.3))(rollup@4.60.3)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(tsx@4.23.1)(typescript@6.0.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(yaml@2.9.0) + nuxt: 4.5.1(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@parcel/watcher@2.5.6)(@rspack/core@2.1.8(@swc/helpers@0.5.23))(@types/node@26.1.2)(@vue/compiler-sfc@3.5.40)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.8.0(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(oxc-parser@0.140.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.0)(rollup@4.60.3))(rollup@4.60.3)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(tsx@4.23.1)(typescript@6.0.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(yaml@2.9.0) nypm: 0.6.8 ohash: 2.0.11 pathe: 2.0.3 rou3: 0.9.1 std-env: 4.2.0 ufo: 1.6.4 - unctx: 3.0.0(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + unctx: 3.0.0(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) unstorage: 1.17.5(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(srvx@0.11.22) vue: 3.5.40(typescript@6.0.3) vue-bundle-renderer: 2.3.1 @@ -10893,18 +11133,18 @@ snapshots: pkg-types: 2.3.1 std-env: 4.2.0 - '@nuxt/telemetry@2.8.0(@nuxt/kit@4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))))': + '@nuxt/telemetry@2.8.0(@nuxt/kit@4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))))': dependencies: - '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) citty: 0.2.2 consola: 3.4.2 ofetch: 2.0.0-alpha.3 rc9: 3.0.1 std-env: 4.2.0 - '@nuxt/vite-builder@4.5.1(abf4b1bdbb10956a12cdcb700c0fc641)': + '@nuxt/vite-builder@4.5.1(e970ea1de816f5673f22f4c8acce1d37)': dependencies: - '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) '@vitejs/plugin-vue': 6.0.8(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) '@vitejs/plugin-vue-jsx': 5.1.6(supports-color@10.2.2)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) autoprefixer: 10.5.4(postcss@8.5.23) @@ -10920,7 +11160,7 @@ snapshots: knitwork: 1.3.0 mlly: 1.8.2 mocked-exports: 0.1.1 - nuxt: 4.5.1(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@parcel/watcher@2.5.6)(@types/node@26.1.2)(@vue/compiler-sfc@3.5.40)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.8.0(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(oxc-parser@0.140.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.0)(rollup@4.60.3))(rollup@4.60.3)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(tsx@4.23.1)(typescript@6.0.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(yaml@2.9.0) + nuxt: 4.5.1(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@parcel/watcher@2.5.6)(@rspack/core@2.1.8(@swc/helpers@0.5.23))(@types/node@26.1.2)(@vue/compiler-sfc@3.5.40)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.8.0(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(oxc-parser@0.140.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.0)(rollup@4.60.3))(rollup@4.60.3)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(tsx@4.23.1)(typescript@6.0.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(yaml@2.9.0) nypm: 0.6.8 pathe: 2.0.3 pkg-types: 2.3.1 @@ -11897,6 +12137,89 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.60.3': optional: true + '@rsbuild/core@2.1.10': + dependencies: + '@rspack/core': 2.1.8(@swc/helpers@0.5.23) + '@swc/helpers': 0.5.23 + transitivePeerDependencies: + - '@module-federation/runtime-tools' + + '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.10)(@rspack/core@2.1.8(@swc/helpers@0.5.23))': + dependencies: + '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.1.8(@swc/helpers@0.5.23))(react-refresh@0.18.0) + react-refresh: 0.18.0 + optionalDependencies: + '@rsbuild/core': 2.1.10 + transitivePeerDependencies: + - '@rspack/core' + + '@rspack/binding-darwin-arm64@2.1.8': + optional: true + + '@rspack/binding-darwin-x64@2.1.8': + optional: true + + '@rspack/binding-linux-arm64-gnu@2.1.8': + optional: true + + '@rspack/binding-linux-arm64-musl@2.1.8': + optional: true + + '@rspack/binding-linux-riscv64-gnu@2.1.8': + optional: true + + '@rspack/binding-linux-riscv64-musl@2.1.8': + optional: true + + '@rspack/binding-linux-x64-gnu@2.1.8': + optional: true + + '@rspack/binding-linux-x64-musl@2.1.8': + optional: true + + '@rspack/binding-wasm32-wasi@2.1.8': + dependencies: + '@emnapi/core': 1.11.3 + '@emnapi/runtime': 1.11.3 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3) + optional: true + + '@rspack/binding-win32-arm64-msvc@2.1.8': + optional: true + + '@rspack/binding-win32-ia32-msvc@2.1.8': + optional: true + + '@rspack/binding-win32-x64-msvc@2.1.8': + optional: true + + '@rspack/binding@2.1.8': + optionalDependencies: + '@rspack/binding-darwin-arm64': 2.1.8 + '@rspack/binding-darwin-x64': 2.1.8 + '@rspack/binding-linux-arm64-gnu': 2.1.8 + '@rspack/binding-linux-arm64-musl': 2.1.8 + '@rspack/binding-linux-riscv64-gnu': 2.1.8 + '@rspack/binding-linux-riscv64-musl': 2.1.8 + '@rspack/binding-linux-x64-gnu': 2.1.8 + '@rspack/binding-linux-x64-musl': 2.1.8 + '@rspack/binding-wasm32-wasi': 2.1.8 + '@rspack/binding-win32-arm64-msvc': 2.1.8 + '@rspack/binding-win32-ia32-msvc': 2.1.8 + '@rspack/binding-win32-x64-msvc': 2.1.8 + + '@rspack/core@2.1.8(@swc/helpers@0.5.23)': + dependencies: + '@rspack/binding': 2.1.8 + optionalDependencies: + '@swc/helpers': 0.5.23 + + '@rspack/plugin-react-refresh@2.0.2(@rspack/core@2.1.8(@swc/helpers@0.5.23))(react-refresh@0.18.0)': + dependencies: + react-refresh: 0.18.0 + optionalDependencies: + '@rspack/core': 2.1.8(@swc/helpers@0.5.23) + '@shikijs/core@4.3.1': dependencies: '@shikijs/primitive': 4.3.1 @@ -12134,6 +12457,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@swc/helpers@0.5.23': + dependencies: + tslib: 2.8.1 + '@tanstack/virtual-core@3.17.2': {} '@tanstack/vue-virtual@3.13.30(vue@3.5.40(typescript@6.0.3))': @@ -12506,15 +12833,15 @@ snapshots: '@ungap/structured-clone@1.3.1': {} - '@unhead/bundler@3.2.3(esbuild@0.28.0)(lightningcss@1.32.0)(rolldown@1.2.0)(rollup@4.60.3)(unhead@3.2.3(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))': + '@unhead/bundler@3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(lightningcss@1.32.0)(rolldown@1.2.0)(rollup@4.60.3)(unhead@3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))': dependencies: '@vitejs/devtools-kit': 0.4.9(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) magic-string: 1.0.0 oxc-parser: 0.140.0 - oxc-walker: 1.0.0(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + oxc-walker: 1.0.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) ufo: 1.6.4 - unhead: 3.2.3(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unhead: 3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) optionalDependencies: esbuild: 0.28.0 lightningcss: 1.32.0 @@ -12527,12 +12854,12 @@ snapshots: - rollup - unloader - '@unhead/vue@3.2.3(esbuild@0.28.0)(lightningcss@1.32.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': + '@unhead/vue@3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(lightningcss@1.32.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': dependencies: - '@unhead/bundler': 3.2.3(esbuild@0.28.0)(lightningcss@1.32.0)(rolldown@1.2.0)(rollup@4.60.3)(unhead@3.2.3(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + '@unhead/bundler': 3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(lightningcss@1.32.0)(rolldown@1.2.0)(rollup@4.60.3)(unhead@3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) hookable: 6.1.1 - unhead: 3.2.3(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unhead: 3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) vue: 3.5.40(typescript@6.0.3) optionalDependencies: vite: 8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0) @@ -14607,12 +14934,12 @@ snapshots: import-without-cache@0.4.0: {} - impound@1.1.6(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): + impound@1.1.6(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): dependencies: '@jridgewell/trace-mapping': 0.3.31 es-module-lexer: 2.1.0 pathe: 2.0.3 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) unplugin-utils: 0.3.2 transitivePeerDependencies: - '@farmfe/core' @@ -14971,12 +15298,12 @@ snapshots: ufo: 1.6.4 unplugin: 2.3.11 - magic-regexp@0.11.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): + magic-regexp@0.11.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): dependencies: magic-string: 0.30.21 regexp-tree: 0.1.27 type-level-regexp: 0.1.17 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) transitivePeerDependencies: - '@farmfe/core' - '@rspack/core' @@ -15496,7 +15823,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - nitropack@2.13.4(oxc-parser@0.140.0)(rolldown@1.2.0)(srvx@0.11.22)(supports-color@10.2.2)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): + nitropack@2.13.4(@rspack/core@2.1.8(@swc/helpers@0.5.23))(oxc-parser@0.140.0)(rolldown@1.2.0)(srvx@0.11.22)(supports-color@10.2.2)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): dependencies: '@cloudflare/kv-asset-handler': 0.4.2 '@rollup/plugin-alias': 6.0.0(rollup@4.60.3) @@ -15561,7 +15888,7 @@ snapshots: uncrypto: 0.1.3 unctx: 2.5.0 unenv: 2.0.0-rc.24 - unimport: 6.3.1(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unimport: 6.3.1(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) unplugin-utils: 0.3.2 unstorage: 1.17.5(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(srvx@0.11.22) untyped: 2.0.0 @@ -15652,17 +15979,17 @@ snapshots: dependencies: boolbase: 1.0.0 - nuxt@4.5.1(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@parcel/watcher@2.5.6)(@types/node@26.1.2)(@vue/compiler-sfc@3.5.40)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.8.0(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(oxc-parser@0.140.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.0)(rollup@4.60.3))(rollup@4.60.3)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(tsx@4.23.1)(typescript@6.0.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(yaml@2.9.0): + nuxt@4.5.1(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0(supports-color@10.2.2)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.0(supports-color@10.2.2)))(@parcel/watcher@2.5.6)(@rspack/core@2.1.8(@swc/helpers@0.5.23))(@types/node@26.1.2)(@vue/compiler-sfc@3.5.40)(db0@0.3.4)(esbuild@0.28.0)(eslint@10.8.0(jiti@2.7.0)(supports-color@10.2.2))(ioredis@5.10.1(supports-color@10.2.2))(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(oxc-parser@0.140.0)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.0)(rollup@4.60.3))(rollup@4.60.3)(srvx@0.11.22)(supports-color@10.2.2)(terser@5.47.1)(tsx@4.23.1)(typescript@6.0.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(yaml@2.9.0): dependencies: - '@dxup/nuxt': 0.5.3(esbuild@0.28.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + '@dxup/nuxt': 0.5.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) '@nuxt/cli': 3.37.0(@nuxt/schema@4.5.1)(magicast@0.5.2)(supports-color@10.2.2) - '@nuxt/devtools': 3.3.1(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(srvx@0.11.22)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) - '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) - '@nuxt/nitro-server': 4.5.1(71bc86bb730f85a69e3066bf13024c10) + '@nuxt/devtools': 3.3.1(db0@0.3.4)(ioredis@5.10.1(supports-color@10.2.2))(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(srvx@0.11.22)(supports-color@10.2.2)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) + '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + '@nuxt/nitro-server': 4.5.1(0f35f3b419903b84781fca0188e19e5e) '@nuxt/schema': 4.5.1 - '@nuxt/telemetry': 2.8.0(@nuxt/kit@4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))) - '@nuxt/vite-builder': 4.5.1(abf4b1bdbb10956a12cdcb700c0fc641) - '@unhead/vue': 3.2.3(esbuild@0.28.0)(lightningcss@1.32.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) + '@nuxt/telemetry': 2.8.0(@nuxt/kit@4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)))) + '@nuxt/vite-builder': 4.5.1(e970ea1de816f5673f22f4c8acce1d37) + '@unhead/vue': 3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(lightningcss@1.32.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) '@vue/shared': 3.5.40 chokidar: 5.0.0 compatx: 0.2.0 @@ -15676,7 +16003,7 @@ snapshots: fnv1a-64: 0.1.1 hookable: 6.1.1 ignore: 7.0.6 - impound: 1.1.6(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + impound: 1.1.6(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) jiti: 2.7.0 klona: 2.0.6 knitwork: 1.3.0 @@ -15689,7 +16016,7 @@ snapshots: ofetch: 1.5.1 ohash: 2.0.11 on-change: 6.0.2 - oxc-walker: 1.0.0(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + oxc-walker: 1.0.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) pathe: 2.0.3 perfect-debounce: 2.1.0 picomatch: 4.0.5 @@ -15703,16 +16030,16 @@ snapshots: ufo: 1.6.4 ultrahtml: 1.7.0 uncrypto: 0.1.3 - unctx: 3.0.0(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + unctx: 3.0.0(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) undici: 8.9.0 - unhead: 3.2.3(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) - unimport: 6.3.1(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unhead: 3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unimport: 6.3.1(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) unrouting: 0.2.2 untyped: 2.0.0 verkit: 0.2.0 vue: 3.5.40(typescript@6.0.3) - vue-router: 5.2.0(@vue/compiler-sfc@3.5.40)(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) + vue-router: 5.2.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(@vue/compiler-sfc@3.5.40)(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) optionalDependencies: '@parcel/watcher': 2.5.6 '@types/node': 26.1.2 @@ -16032,9 +16359,9 @@ snapshots: magic-regexp: 0.10.0 oxc-parser: 0.131.0 - oxc-walker@1.0.0(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): + oxc-walker@1.0.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): dependencies: - magic-regexp: 0.11.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + magic-regexp: 0.11.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) optionalDependencies: oxc-parser: 0.140.0 rolldown: 1.2.0 @@ -16476,6 +16803,8 @@ snapshots: react-is@17.0.2: {} + react-refresh@0.18.0: {} + react@19.2.8: {} readable-stream@2.3.8: @@ -17309,19 +17638,19 @@ snapshots: magic-string: 0.30.21 unplugin: 2.3.11 - unctx@3.0.0(magic-string@0.30.21)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))): + unctx@3.0.0(magic-string@0.30.21)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))): optionalDependencies: magic-string: 0.30.21 oxc-parser: 0.140.0 rolldown: 1.2.0 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) - unctx@3.0.0(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))): + unctx@3.0.0(magic-string@1.0.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))): optionalDependencies: magic-string: 1.0.0 oxc-parser: 0.140.0 rolldown: 1.2.0 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) undici-types@8.3.0: {} @@ -17331,10 +17660,10 @@ snapshots: dependencies: pathe: 2.0.3 - unhead@3.2.3(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): + unhead@3.2.3(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): dependencies: hookable: 6.1.1 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) optionalDependencies: vite: 8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0) transitivePeerDependencies: @@ -17351,7 +17680,7 @@ snapshots: unicorn-magic@0.4.0: {} - unimport@6.3.1(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): + unimport@6.3.1(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(oxc-parser@0.140.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): dependencies: acorn: 8.16.0 escape-string-regexp: 5.0.0 @@ -17365,7 +17694,7 @@ snapshots: scule: 1.3.0 strip-literal: 3.1.0 tinyglobby: 0.2.17 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) unplugin-utils: 0.3.2 optionalDependencies: oxc-parser: 0.140.0 @@ -17444,12 +17773,13 @@ snapshots: picomatch: 4.0.5 webpack-virtual-modules: 0.6.2 - unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): + unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): dependencies: '@jridgewell/remapping': 2.3.5 picomatch: 4.0.5 webpack-virtual-modules: 0.6.2 optionalDependencies: + '@rspack/core': 2.1.8(@swc/helpers@0.5.23) esbuild: 0.28.0 rolldown: 1.2.0 rollup: 4.60.3 @@ -17589,7 +17919,7 @@ snapshots: dependencies: vite: 8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0) - vite-plugin-inspect@11.3.3(@nuxt/kit@4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))))(supports-color@10.2.2)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): + vite-plugin-inspect@11.3.3(@nuxt/kit@4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))))(supports-color@10.2.2)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)): dependencies: ansis: 4.3.1 debug: 4.4.3(supports-color@10.2.2) @@ -17602,7 +17932,7 @@ snapshots: vite: 8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0) vite-dev-rpc: 1.1.0(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) optionalDependencies: - '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) + '@nuxt/kit': 4.5.1(magic-string@1.0.0)(magicast@0.5.2)(oxc-parser@0.140.0)(rolldown@1.2.0)(unplugin@3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))) transitivePeerDependencies: - supports-color @@ -17804,7 +18134,7 @@ snapshots: dependencies: vue: 3.5.40(typescript@6.0.3) - vue-router@5.2.0(@vue/compiler-sfc@3.5.40)(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)): + vue-router@5.2.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(@vue/compiler-sfc@3.5.40)(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)): dependencies: '@babel/generator': 8.0.0 '@vue-macros/common': 3.1.4(vue@3.5.40(typescript@6.0.3)) @@ -17821,7 +18151,7 @@ snapshots: picomatch: 4.0.5 scule: 1.3.0 tinyglobby: 0.2.17 - unplugin: 3.3.0(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) + unplugin: 3.3.0(@rspack/core@2.1.8(@swc/helpers@0.5.23))(esbuild@0.28.0)(rolldown@1.2.0)(rollup@4.60.3)(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.47.1)(tsx@4.23.1)(yaml@2.9.0)) unplugin-utils: 0.3.2 vue: 3.5.40(typescript@6.0.3) yaml: 2.9.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 813d2b1d..5b328b01 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -16,6 +16,21 @@ minimumReleaseAgeExclude: - tsdown@0.22.14 - verkit@0.3.0 - structured-clone-es@2.0.1 + - '@rsbuild/core@2.1.10' + - '@rspack/binding-darwin-arm64@2.1.8' + - '@rspack/binding-darwin-x64@2.1.8' + - '@rspack/binding-linux-arm64-gnu@2.1.8' + - '@rspack/binding-linux-arm64-musl@2.1.8' + - '@rspack/binding-linux-riscv64-gnu@2.1.8' + - '@rspack/binding-linux-riscv64-musl@2.1.8' + - '@rspack/binding-linux-x64-gnu@2.1.8' + - '@rspack/binding-linux-x64-musl@2.1.8' + - '@rspack/binding-wasm32-wasi@2.1.8' + - '@rspack/binding-win32-arm64-msvc@2.1.8' + - '@rspack/binding-win32-ia32-msvc@2.1.8' + - '@rspack/binding-win32-x64-msvc@2.1.8' + - '@rspack/binding@2.1.8' + - '@rspack/core@2.1.8' shamefullyHoist: true shellEmulator: true strictPeerDependencies: false @@ -61,6 +76,8 @@ catalogs: build: '@nuxt/kit': *nuxt '@preact/preset-vite': ^2.10.6 + '@rsbuild/core': ^2.1.10 + '@rsbuild/plugin-react': ^2.1.0 '@vitejs/plugin-vue': ^6.0.8 mlly: ^1.8.2 nuxt: ^4.5.1 diff --git a/turbo.json b/turbo.json index 963a5a8a..5d378dbf 100644 --- a/turbo.json +++ b/turbo.json @@ -100,6 +100,23 @@ ], "outputs": ["src/client/.next/**", "!src/client/.next/cache/**"] }, + "rsbuild-devframe-hub#build": { + "outputLogs": "new-only", + "dependsOn": [ + "@devframes/hub#build", + "devframe#build", + "@devframes/plugin-git#build", + "@devframes/plugin-terminals#build", + "@devframes/plugin-code-server#build", + "@devframes/plugin-inspect#build", + "@devframes/plugin-og#build", + "@devframes/plugin-data-inspector#build", + "@devframes/plugin-a11y#build", + "@devframes/plugin-messages#build", + "@devframes/plugin-assets#build" + ], + "outputs": ["dist/**"] + }, "@devframes/storybook#build": { "outputLogs": "new-only", "dependsOn": ["@devframes/hub#build", "devframe#build", "@devframes/plugin-terminals#build"],