diff --git a/docs/kit/dock-system.md b/docs/kit/dock-system.md index 596fbb741..83e4eab34 100644 --- a/docs/kit/dock-system.md +++ b/docs/kit/dock-system.md @@ -130,6 +130,28 @@ The [File Explorer example](/kit/examples#file-explorer) is a complete iframe-do To skip bundling a dist with your plugin, an iframe dock can point at a hosted website that connects back to the local dev server over WebSocket. See [Remote Client](./remote-client). +### Shared-iframe soft navigation + +A multi-tab integration — say a devtool with its own Modules / Timeline / Plugins views inside one SPA — can surface each of its tabs as its own DevTools dock while all of them share **one** live iframe and switch views by client-side (soft) navigation, with no reload. + +Flag the iframe dock as an **anchor** with `subTabs` and give it a `frameId`: + +```ts +ctx.docks.register({ + id: 'nuxt-devtools', + type: 'iframe', + title: 'Nuxt DevTools', + icon: 'i-logos:nuxt-icon', + url: 'http://localhost:3000/__nuxt_devtools__/', + frameId: 'nuxt-devtools', // the shared iframe these docks render into + subTabs: { protocol: 'postmessage' }, // opt into the frame-nav adapter +}) +``` + +When the anchor's iframe mounts, Vite DevTools attaches the hub's frame-nav adapter. It runs a versioned, origin-locked `postMessage` handshake with the embedded app, turns the tab manifest the app reports into one **member dock** per tab (id `:`), and drives the loop both ways: selecting a member soft-navigates the shared frame, and the app's own navigation moves the DevTools highlight to match. Members are first-class docks — they honor `title`, `icon`, `order`, `category`, `when`, `badge`, and grouping (`frameId` and `groupId` are independent axes). + +The embedded app stays decoupled: it ships a small `postMessage` nav shim and takes no hub or RPC dependency, so this works cross-origin and in static builds. When no shim answers within the handshake window, the anchor renders as a single plain iframe dock. The protocol, the member-dock data model, and the shim contract live in devframe's [shared-iframe soft-navigation design](https://github.com/devframes/devframe/blob/main/plans/shared-iframe-soft-nav.md). + ## Action buttons Action buttons run a client-side script when clicked. They suit: diff --git a/packages/core/src/client/webcomponents/components/views/ViewIframe.vue b/packages/core/src/client/webcomponents/components/views/ViewIframe.vue index 8502130cc..421890842 100644 --- a/packages/core/src/client/webcomponents/components/views/ViewIframe.vue +++ b/packages/core/src/client/webcomponents/components/views/ViewIframe.vue @@ -57,8 +57,16 @@ const currentUrl = ref(props.entry.url) const editingUrl = ref(props.entry.url) const isEditing = ref(false) +// Shared-iframe soft navigation: an anchor iframe dock and each of its member +// docks share one `frameId`, so they must render into the *same* live pane. +// Keying on `frameId` (when present) keeps that single iframe alive across +// switches — its navigation/scroll/JS state is preserved and the hub's +// frame-nav adapter soft-navigates it — falling back to the entry id for plain +// iframe docks that own their frame exclusively. +const paneKey = computed(() => props.entry.frameId ?? props.entry.id) + const iframeElement = computed(() => { - return props.panes.get(props.entry.id)?.iframe + return props.panes.get(paneKey.value)?.iframe }) // Get current page's origin for comparison @@ -186,10 +194,12 @@ function refresh() { let onIframeLoad: (() => void) | undefined onMounted(() => { - const existed = props.panes.has(props.entry.id) + const existed = props.panes.has(paneKey.value) // `src` is only assigned when the pane is first created, so re-mounting an - // existing iframe (tab switch) preserves its navigation/scroll/JS state. - const pane = props.panes.ensure(props.entry.id, { + // existing iframe (tab switch) preserves its navigation/scroll/JS state. For + // a shared frame this is also the boot deep-link: the first member (or the + // anchor) to become visible seeds the src, and every later switch soft-navs. + const pane = props.panes.ensure(paneKey.value, { src: props.entry.url, style: { boxShadow: 'none', outline: 'none' }, }) @@ -236,10 +246,16 @@ onMounted(() => { }) onUnmounted(() => { - const pane = props.panes.get(props.entry.id) + const pane = props.panes.get(paneKey.value) if (pane && onIframeLoad) pane.iframe?.removeEventListener('load', onIframeLoad) - pane?.unmount() + // Only unmount if this view still owns the pane. When switching between two + // docks sharing a `frameId`, the incoming view may re-mount the shared pane + // onto its own container before this outgoing view tears down — unmounting + // then would wrongly hide the just-revealed iframe. Guarding on the current + // target makes the handoff order-independent. + if (pane && pane.target === viewFrame.value) + pane.unmount() }) diff --git a/packages/core/src/client/webcomponents/state/__tests__/frame-nav.test.ts b/packages/core/src/client/webcomponents/state/__tests__/frame-nav.test.ts new file mode 100644 index 000000000..039adfa86 --- /dev/null +++ b/packages/core/src/client/webcomponents/state/__tests__/frame-nav.test.ts @@ -0,0 +1,236 @@ +import type { DevToolsDockEntry } from '@vitejs/devtools-kit' +import type { DevToolsRpcClient } from '@vitejs/devtools-kit/client' +import { DEFAULT_STATE_USER_SETTINGS } from '@vitejs/devtools-kit/constants' +import { createSharedState } from 'devframe/utils/shared-state' +import { afterEach, describe, expect, it } from 'vitest' +import { nextTick } from 'vue' +import { createDocksContext } from '../context' + +function createMockRpc(entries: DevToolsDockEntry[] = []): DevToolsRpcClient { + const docksState = createSharedState({ initialValue: entries, enablePatches: false }) + const settingsState = createSharedState({ initialValue: DEFAULT_STATE_USER_SETTINGS(), enablePatches: false }) + const commandsState = createSharedState({ initialValue: [] as any[], enablePatches: false }) + + return { + client: { register: () => () => {} }, + sharedState: { + get: async (key: string) => { + if (key === 'devframe:docks') + return docksState as any + if (key === 'devframe:user-settings') + return settingsState as any + if (key === 'devframe:commands') + return commandsState as any + throw new Error(`Unexpected shared state key: ${key}`) + }, + }, + } as unknown as DevToolsRpcClient +} + +/** + * The frame-nav adapter listens for `message` events on `globalThis`. These + * tests run in the node environment (no DOM), so stub the listener registry and + * drive it with synthetic events — this exercises the viewer wiring we own + * (auto-attach, member materialization, the nav loop) without a DOM dependency. + */ +function stubMessageBus() { + const listeners = new Set<(ev: any) => void>() + const origAdd = (globalThis as any).addEventListener + const origRemove = (globalThis as any).removeEventListener; + (globalThis as any).addEventListener = (type: string, cb: any) => { + if (type === 'message') + listeners.add(cb) + } + ;(globalThis as any).removeEventListener = (type: string, cb: any) => { + if (type === 'message') + listeners.delete(cb) + } + return { + emit(data: unknown, origin = 'http://localhost:5173') { + for (const cb of [...listeners]) cb({ origin, data }) + }, + get size() { + return listeners.size + }, + restore() { + ;(globalThis as any).addEventListener = origAdd + ;(globalThis as any).removeEventListener = origRemove + }, + } +} + +function makeFakeIframe(src: string) { + const posted: { msg: any, origin: string }[] = [] + const iframe = { + src, + contentWindow: { + postMessage: (msg: any, origin: string) => posted.push({ msg, origin }), + }, + } + return { iframe: iframe as unknown as HTMLIFrameElement, posted } +} + +const ANCHOR_URL = 'http://localhost:5173/__nuxt__/' + +function anchorEntry(): DevToolsDockEntry { + return { + id: 'nuxt', + type: 'iframe', + title: 'Nuxt DevTools', + icon: 'i-logos:nuxt-icon', + url: ANCHOR_URL, + frameId: 'nuxt', + subTabs: { protocol: 'postmessage' }, + } as DevToolsDockEntry +} + +const READY_TABS = [ + { id: 'modules', title: 'Modules', navTarget: { path: '/modules' } }, + { id: 'timeline', title: 'Timeline', navTarget: { path: '/timeline' } }, +] + +function frameMessage(type: string, payload: Record = {}) { + return { channel: 'devframe:frame-nav', v: 1, frameId: 'nuxt', from: 'frame', type, ...payload } +} + +describe('client-only dock registration', () => { + it('materializes an entry state synchronously so getStateById works right after register', async () => { + const context = await createDocksContext('embedded', createMockRpc()) + + const handle = context.docks.register({ + id: 'tab:one', + type: 'iframe', + title: 'One', + icon: 'i', + url: '/one', + } as DevToolsDockEntry) + + // The adapter subscribes to activation immediately after registering — the + // state must exist synchronously, not on the next reactive flush. + const state = context.docks.getStateById('tab:one') + expect(state).toBeDefined() + + let activated = false + state!.events.on('entry:activated', () => { + activated = true + }) + await context.docks.switchEntry('tab:one') + expect(activated).toBe(true) + + handle.dispose() + }) + + it('clears the selection and drops the state when the active client dock is disposed', async () => { + const context = await createDocksContext('embedded', createMockRpc()) + const handle = context.docks.register({ + id: 'tab:two', + type: 'iframe', + title: 'Two', + icon: 'i', + url: '/two', + } as DevToolsDockEntry) + + await context.docks.switchEntry('tab:two') + expect(context.docks.selectedId).toBe('tab:two') + + handle.dispose() + expect(context.docks.getStateById('tab:two')).toBeUndefined() + expect(context.docks.selectedId).toBeNull() + }) +}) + +describe('shared-iframe soft navigation', () => { + let bus: ReturnType | undefined + + afterEach(() => { + bus?.restore() + bus = undefined + }) + + it('attaches the frame-nav adapter and posts hello when the anchor iframe mounts', async () => { + bus = stubMessageBus() + const context = await createDocksContext('embedded', createMockRpc([anchorEntry()])) + const { iframe, posted } = makeFakeIframe(ANCHOR_URL) + + const state = context.docks.getStateById('nuxt')! + state.domElements.iframe = iframe + await nextTick() + + expect(bus.size).toBe(1) + expect(posted.some(p => p.msg.type === 'hello')).toBe(true) + expect(posted.every(p => p.origin === 'http://localhost:5173')).toBe(true) + }) + + it('materializes one member dock per reported tab and selects the current one', async () => { + bus = stubMessageBus() + const context = await createDocksContext('embedded', createMockRpc([anchorEntry()])) + const { iframe } = makeFakeIframe(ANCHOR_URL) + + context.docks.getStateById('nuxt')!.domElements.iframe = iframe + await nextTick() + + bus.emit(frameMessage('ready', { tabs: READY_TABS, current: 'modules' })) + + const ids = context.docks.entries.map(e => e.id) + expect(ids).toContain('nuxt:modules') + expect(ids).toContain('nuxt:timeline') + // Member docks share the anchor's frame + carry their own nav target. + const modules = context.docks.entries.find(e => e.id === 'nuxt:modules') as any + expect(modules.frameId).toBe('nuxt') + expect(modules.navTarget).toEqual({ path: '/modules' }) + expect(context.docks.selectedId).toBe('nuxt:modules') + }) + + it('posts navigate when a member is selected in the dock bar', async () => { + bus = stubMessageBus() + const context = await createDocksContext('embedded', createMockRpc([anchorEntry()])) + const { iframe, posted } = makeFakeIframe(ANCHOR_URL) + + context.docks.getStateById('nuxt')!.domElements.iframe = iframe + await nextTick() + bus.emit(frameMessage('ready', { tabs: READY_TABS, current: 'modules' })) + + posted.length = 0 + await context.docks.switchEntry('nuxt:timeline') + + const navigate = posted.find(p => p.msg.type === 'navigate') + expect(navigate).toBeDefined() + expect(navigate!.msg.tabId).toBe('timeline') + expect(navigate!.msg.navTarget).toEqual({ path: '/timeline' }) + }) + + it('moves the dock highlight when the frame reports internal navigation', async () => { + bus = stubMessageBus() + const context = await createDocksContext('embedded', createMockRpc([anchorEntry()])) + const { iframe, posted } = makeFakeIframe(ANCHOR_URL) + + context.docks.getStateById('nuxt')!.domElements.iframe = iframe + await nextTick() + bus.emit(frameMessage('ready', { tabs: READY_TABS, current: 'modules' })) + + posted.length = 0 + bus.emit(frameMessage('navigated', { tabId: 'timeline' })) + + expect(context.docks.selectedId).toBe('nuxt:timeline') + // The highlight-only update must not echo a navigate back to the frame. + expect(posted.some(p => p.msg.type === 'navigate')).toBe(false) + }) + + it('removes member docks and clears selection when the manifest empties', async () => { + bus = stubMessageBus() + const context = await createDocksContext('embedded', createMockRpc([anchorEntry()])) + const { iframe } = makeFakeIframe(ANCHOR_URL) + + context.docks.getStateById('nuxt')!.domElements.iframe = iframe + await nextTick() + bus.emit(frameMessage('ready', { tabs: READY_TABS, current: 'modules' })) + expect(context.docks.selectedId).toBe('nuxt:modules') + + bus.emit(frameMessage('manifest', { tabs: [] })) + + const ids = context.docks.entries.map(e => e.id) + expect(ids).not.toContain('nuxt:modules') + expect(ids).not.toContain('nuxt:timeline') + expect(context.docks.selectedId).toBeNull() + }) +}) diff --git a/packages/core/src/client/webcomponents/state/context.ts b/packages/core/src/client/webcomponents/state/context.ts index f485aecaa..20892cb48 100644 --- a/packages/core/src/client/webcomponents/state/context.ts +++ b/packages/core/src/client/webcomponents/state/context.ts @@ -1,11 +1,12 @@ -import type { DevToolsClientCommand, DevToolsDockEntry, DevToolsDockUserEntry, DevToolsRpcClientFunctions } from '@vitejs/devtools-kit' +import type { DevToolsClientCommand, DevToolsDockEntry, DevToolsDockUserEntry, DevToolsRpcClientFunctions, DevToolsViewIframe } from '@vitejs/devtools-kit' import type { CommandsContext, DevToolsRpcClient, DockClientScriptContext, DockEntryState, DockPanelStorage, DockRegistration, DocksContext } from '@vitejs/devtools-kit/client' import type { SharedState } from 'devframe/utils/shared-state' import type { WhenContext } from 'devframe/utils/when' import type { Ref } from 'vue' import type { DevToolsDocksUserSettings } from './dock-settings' +import { attachDevToolsFrameNav } from '@vitejs/devtools-kit/client' import { DEFAULT_STATE_USER_SETTINGS } from '@vitejs/devtools-kit/constants' -import { computed, markRaw, reactive, ref, toRefs, watchEffect } from 'vue' +import { computed, markRaw, reactive, ref, toRefs, watch, watchEffect } from 'vue' import { BUILTIN_ENTRIES } from '../constants' import { createCommandsContext } from './commands' import { docksGroupByCategories, getCategoryLabel, getGroupMembers, getGroupMembersGrouped, getRegisteredGroupIds, resolveCommandIcon } from './dock-settings' @@ -50,10 +51,38 @@ export async function createDocksContext( return merged }) + const selectedId = ref(null) + const selected = computed( + () => entries.value.find(entry => entry.id === selectedId.value) + ?? BUILTIN_ENTRIES.find(entry => entry.id === selectedId.value) + ?? null, + ) + + const dockEntryStateMap: Map = reactive(new Map()) + watchEffect(() => { + for (const entry of entries.value) { + if (dockEntryStateMap.has(entry.id)) { + dockEntryStateMap.get(entry.id)!.entryMeta = entry + continue + } + dockEntryStateMap.set( + entry.id, + createDockEntryState(entry, selected), + ) + } + }) + const registerClientDock = (entry: T, force = false): DockRegistration => { if (clientDocks.has(entry.id) && !force) throw new Error(`[@vitejs/devtools] a client dock "${entry.id}" is already registered — pass force to overwrite`) clientDocks.set(entry.id, entry) + // Eagerly materialize the entry's DockEntryState. The reactive watchEffect + // above only creates states on its next flush, but a caller such as the + // shared-iframe frame-nav adapter subscribes to `entry:activated` (via + // `getStateById`) synchronously right after registering — so the state has + // to exist immediately, mirroring hub's synchronous client-host reconcile. + if (!dockEntryStateMap.has(entry.id)) + dockEntryStateMap.set(entry.id, createDockEntryState(entry, selected)) return { update: (patch: Partial) => { if (patch.id != null && patch.id !== entry.id) @@ -63,7 +92,14 @@ export async function createDocksContext( clientDocks.set(entry.id, { ...existing, ...patch } as DevToolsDockEntry) }, dispose: () => { - clientDocks.delete(entry.id) + if (!clientDocks.delete(entry.id)) + return + dockEntryStateMap.delete(entry.id) + // Clearing the selection when the active member vanishes matches the + // hub reconcile behavior for a removed selected entry (shared-iframe + // soft-nav §7.5). + if (selectedId.value === entry.id) + selectedId.value = null }, } } @@ -73,27 +109,6 @@ export async function createDocksContext( clientDocks.set(entry.id, entry as DevToolsDockEntry) } - const selectedId = ref(null) - const selected = computed( - () => entries.value.find(entry => entry.id === selectedId.value) - ?? BUILTIN_ENTRIES.find(entry => entry.id === selectedId.value) - ?? null, - ) - - const dockEntryStateMap: Map = reactive(new Map()) - watchEffect(() => { - for (const entry of entries.value) { - if (dockEntryStateMap.has(entry.id)) { - dockEntryStateMap.get(entry.id)!.entryMeta = entry - continue - } - dockEntryStateMap.set( - entry.id, - createDockEntryState(entry, selected), - ) - } - }) - panelStore ||= ref(DEFAULT_DOCK_PANEL_STORE()) let docksContext: DocksContext @@ -161,6 +176,71 @@ export async function createDocksContext( return switchEntry(id) } + // Shared-iframe soft navigation (devframe 0.7.11). An iframe dock flagged + // `subTabs` is an *anchor* that owns one live iframe (its `frameId`); the + // embedded app ships a small `postMessage` nav shim. When the anchor's iframe + // mounts we attach the hub-shipped frame-nav adapter, which runs the ready + // handshake, turns the reported tab manifest into client-only member docks, + // and drives the bidirectional nav loop (selecting a member soft-navigates + // the shared frame; the app's `navigated` report moves the dock highlight). + // + // Our shell runs its own dock machinery instead of hub's `createDevframeClientHost`, + // so we replicate the host's `maybeAttachFrameNav`: one adapter per `frameId`, + // torn down when the anchor is removed. + const frameNavAdapters = new Map void>() + const frameNavAnchors = new Map() + + const attachFrameNav = (anchor: DevToolsViewIframe, state: DockEntryState) => { + const frameId = anchor.frameId ?? anchor.id + const start = (iframe: HTMLIFrameElement) => { + if (frameNavAdapters.has(frameId)) + return + const adapter = attachDevToolsFrameNav({ + frameId, + anchor, + iframe, + docks: { + register: registerClientDock, + switchEntry, + getStateById: (id: string) => dockEntryStateMap.get(id), + }, + }) + frameNavAdapters.set(frameId, adapter.dispose) + } + if (state.domElements.iframe) + start(state.domElements.iframe) + state.events.on('dom:iframe:mounted', start) + } + + watch( + entries, + (list) => { + const seen = new Set() + for (const meta of list) { + if (meta.type !== 'iframe' || !meta.subTabs) + continue + seen.add(meta.id) + if (frameNavAnchors.has(meta.id)) + continue + const state = dockEntryStateMap.get(meta.id) + if (!state) + continue + frameNavAnchors.set(meta.id, meta.frameId ?? meta.id) + attachFrameNav(meta, state) + } + // An anchor that disappeared tears down its adapter, which disposes every + // member dock it registered and detaches the `postMessage` listener. + for (const [anchorId, frameId] of [...frameNavAnchors]) { + if (seen.has(anchorId)) + continue + frameNavAnchors.delete(anchorId) + frameNavAdapters.get(frameId)?.() + frameNavAdapters.delete(frameId) + } + }, + { immediate: true }, + ) + // Honor cross-iframe dock-activation requests (devframe 0.7.3). A mounted // plugin — or our own launcher's "View in Terminal" action — calls the // `hub:docks:activate` RPC; the hub broadcasts `devframe:docks:activate` to diff --git a/packages/kit/src/client/frame-nav.ts b/packages/kit/src/client/frame-nav.ts new file mode 100644 index 000000000..e64badc8f --- /dev/null +++ b/packages/kit/src/client/frame-nav.ts @@ -0,0 +1,19 @@ +// Shared-iframe soft navigation — the viewer-side half of the host↔iframe +// `postMessage` protocol shipped in `@devframes/hub`. A `subTabs` anchor iframe +// dock owns one live iframe (its `frameId`); the embedded app ships a tiny nav +// shim, and this adapter turns the reported tab manifest into client-only member +// docks and drives the bidirectional nav loop. Re-exported under the kit's +// `DevTools*` names so Vite DevTools wires it without reaching into hub directly. +export { + attachFrameNavClient as attachDevToolsFrameNav, + type FrameNavClient as DevToolsFrameNavClient, + type FrameNavClientOptions as DevToolsFrameNavClientOptions, + type FrameNavEnvelope as DevToolsFrameNavEnvelope, + type FrameNavFrameMessage as DevToolsFrameNavFrameMessage, + type FrameNavHostMessage as DevToolsFrameNavHostMessage, + type FrameNavHostPayload as DevToolsFrameNavHostPayload, + type FrameNavListenTarget as DevToolsFrameNavListenTarget, + type FrameTab as DevToolsFrameTab, + FRAME_NAV_CHANNEL, + FRAME_NAV_VERSION, +} from '@devframes/hub/client' diff --git a/packages/kit/src/client/index.ts b/packages/kit/src/client/index.ts index 64d31c935..420af4857 100644 --- a/packages/kit/src/client/index.ts +++ b/packages/kit/src/client/index.ts @@ -2,6 +2,7 @@ export * from './client-script' export * from './connection' export * from './context' export * from './docks' +export * from './frame-nav' export * from './remote' export { diff --git a/packages/kit/src/node/context.ts b/packages/kit/src/node/context.ts index 779f92412..1a30252ae 100644 --- a/packages/kit/src/node/context.ts +++ b/packages/kit/src/node/context.ts @@ -67,14 +67,13 @@ export async function createKitContext(options: CreateKitContextOptions): Promis * The handle's methods are defined non-enumerably so the whole object stays * serializable when carried on a dock entry's `ui` field — the docks * shared-state projection walks only enumerable own keys, so the live - * closures never reach the wire while `_stateKey` / `upstreamVersion` do. + * closures never reach the wire while `_stateKey` does. */ function createJsonRenderer(context: KitNodeContext, spec: JsonRenderSpec): JsonRenderer { const view = createJsonRenderView(context, { id: `kit-${nanoid()}`, spec }) const handle = { _stateKey: view.ref.stateKey, - upstreamVersion: view.ref.upstreamVersion, view: view.ref, } as JsonRenderer diff --git a/packages/kit/src/types/docks.ts b/packages/kit/src/types/docks.ts index 93d783a3a..98686dc83 100644 --- a/packages/kit/src/types/docks.ts +++ b/packages/kit/src/types/docks.ts @@ -11,6 +11,8 @@ export type { DevframeDocksHost as DevToolsDockHost, DevframeDocksActiveState as DevToolsDocksActiveState, DevframeDockUserEntry as DevToolsDockUserEntry, + FrameSubTabsConfig as DevToolsFrameSubTabsConfig, + NavTarget as DevToolsNavTarget, DevframeViewAction as DevToolsViewAction, DevframeViewBuiltin as DevToolsViewBuiltin, DevframeViewCustomRender as DevToolsViewCustomRender, diff --git a/packages/kit/src/types/json-render.ts b/packages/kit/src/types/json-render.ts index 45645279d..2bd9cd2f3 100644 --- a/packages/kit/src/types/json-render.ts +++ b/packages/kit/src/types/json-render.ts @@ -25,8 +25,8 @@ export type { JsonRenderView, JsonRenderViewRef } * * Its methods are defined non-enumerably so the handle stays fully * serializable when carried on a `json-render` dock entry's `ui` field — - * only the plain string metadata (`_stateKey`, `upstreamVersion`) crosses - * the wire to the client, which subscribes through `_stateKey`. + * only the plain string metadata (`_stateKey`) crosses the wire to the + * client, which subscribes through it. */ export interface JsonRenderer { /** Replace the entire spec. */ @@ -37,8 +37,6 @@ export interface JsonRenderer { dispose: () => void /** Shared-state key the client subscribes to for the live spec + state. */ readonly _stateKey: string - /** Upstream `@json-render/*` version the view was authored against. */ - readonly upstreamVersion: string /** The serializable reference to the underlying view. */ readonly view: JsonRenderViewRef } diff --git a/playgrounds/core/src/pages/mock-nuxt-devtools.vue b/playgrounds/core/src/pages/mock-nuxt-devtools.vue new file mode 100644 index 000000000..77b41fa74 --- /dev/null +++ b/playgrounds/core/src/pages/mock-nuxt-devtools.vue @@ -0,0 +1,159 @@ + + + diff --git a/playgrounds/core/typed-router.d.ts b/playgrounds/core/typed-router.d.ts index 51d7f0c7e..b7b2d3813 100644 --- a/playgrounds/core/typed-router.d.ts +++ b/playgrounds/core/typed-router.d.ts @@ -45,6 +45,13 @@ declare module 'vue-router/auto-routes' { Record, | never >, + '/mock-nuxt-devtools': RouteRecordInfo< + '/mock-nuxt-devtools', + '/mock-nuxt-devtools', + Record, + Record, + | never + >, } /** @@ -74,6 +81,14 @@ declare module 'vue-router/auto-routes' { pathParamNames: | never } + 'src/pages/mock-nuxt-devtools.vue': { + routes: + | '/mock-nuxt-devtools' + views: + | never + pathParamNames: + | never + } } /** diff --git a/playgrounds/core/vite.config.ts b/playgrounds/core/vite.config.ts index 3d2ad133c..c47f0bce1 100644 --- a/playgrounds/core/vite.config.ts +++ b/playgrounds/core/vite.config.ts @@ -166,16 +166,23 @@ export default defineConfig({ remote: true, }) - // Docked group: collapse several sub-tools under a single button. - // Mirrors how a framework like Nuxt could surface its features as - // individually-pluggable Vite DevTools entries under one umbrella. + // Shared-iframe soft navigation (devframe 0.7.11). A single anchor + // iframe dock owns one live iframe; the embedded SPA + // (`src/pages/mock-nuxt-devtools.vue`) ships the `devframe:frame-nav` + // postMessage shim that announces its internal tabs. The frame-nav + // adapter materializes one dock per reported tab (Overview / Pages / + // Components / Modules) — they inherit this anchor's `groupId`, so + // they collapse under the one "Nuxt" button and soft-navigate the + // shared frame with no reload. `defaultChildId` points at the anchor + // so opening the group reliably boots the frame; the tabs then appear + // in the popover. ctx.docks.register({ id: 'nuxt', type: 'group', title: 'Nuxt', icon: 'vscode-icons:file-type-nuxt', category: 'framework', - defaultChildId: 'nuxt:overview', + defaultChildId: 'nuxt-devtools', }) ctx.docks.register({ id: 'playground', @@ -183,22 +190,16 @@ export default defineConfig({ title: 'Playground', icon: 'ph:flask-duotone', }) - const nuxtFeatures = [ - ['nuxt:overview', 'Overview', 'ph:gauge-duotone'], - ['nuxt:pages', 'Pages', 'ph:files-duotone'], - ['nuxt:components', 'Components', 'ph:puzzle-piece-duotone'], - ['nuxt:modules', 'Modules', 'ph:plugs-connected-duotone'], - ] as const - nuxtFeatures.forEach(([id, title, icon], index) => { - ctx.docks.register({ - id, - type: 'iframe', - url: '/devtools/', - title, - icon, - groupId: 'nuxt', - defaultOrder: index, - }) + ctx.docks.register({ + id: 'nuxt-devtools', + type: 'iframe', + url: '/mock-nuxt-devtools', + title: 'Nuxt DevTools', + icon: 'vscode-icons:file-type-nuxt', + groupId: 'nuxt', + frameId: 'nuxt', + subTabs: { protocol: 'postmessage' }, + defaultOrder: -1, }) ctx.docks.register({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a4eec6b09..f120cda80 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,20 +44,20 @@ catalogs: version: 0.3.1 deps: '@devframes/hub': - specifier: ^0.7.10 - version: 0.7.10 + specifier: ^0.7.11 + version: 0.7.11 '@devframes/json-render': - specifier: ^0.7.9 - version: 0.7.9 + specifier: ^0.7.11 + version: 0.7.11 '@devframes/plugin-inspect': - specifier: ^0.7.9 - version: 0.7.9 + specifier: ^0.7.11 + version: 0.7.11 '@devframes/plugin-messages': - specifier: ^0.7.9 - version: 0.7.9 + specifier: ^0.7.11 + version: 0.7.11 '@devframes/plugin-terminals': - specifier: ^0.7.9 - version: 0.7.9 + specifier: ^0.7.11 + version: 0.7.11 actionspack: specifier: ^0.1.5 version: 0.1.5 @@ -65,8 +65,8 @@ catalogs: specifier: ^4.0.0 version: 4.0.0 devframe: - specifier: ^0.7.9 - version: 0.7.9 + specifier: ^0.7.11 + version: 0.7.11 diff: specifier: ^9.0.0 version: 9.0.0 @@ -655,7 +655,7 @@ importers: version: 5.0.2(change-case@5.4.4)(focus-trap@8.2.2)(fuse.js@7.5.0)(idb-keyval@6.3.0)(vite@8.1.5(@types/node@25.0.3)(@vitejs/devtools@packages+core)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0))(vitepress@2.0.0-alpha.18(@types/node@25.0.3)(@vitejs/devtools@packages+core)(change-case@5.4.4)(esbuild@0.28.1)(fuse.js@7.5.0)(idb-keyval@6.3.0)(jiti@2.7.0)(postcss@8.5.20)(terser@5.44.1)(tsx@4.23.1)(typescript@6.0.3)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3)) devframe: specifier: catalog:deps - version: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + version: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) mermaid: specifier: catalog:docs version: 11.16.0 @@ -799,16 +799,16 @@ importers: dependencies: '@devframes/hub': specifier: catalog:deps - version: 0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + version: 0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) '@devframes/plugin-inspect': specifier: catalog:deps - version: 0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5) + version: 0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5) '@devframes/plugin-messages': specifier: catalog:deps - version: 0.7.9(@devframes/hub@0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(vite@8.1.5) + version: 0.7.11(@devframes/hub@0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(vite@8.1.5) '@devframes/plugin-terminals': specifier: catalog:deps - version: 0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(typescript@6.0.3)(vite@8.1.5) + version: 0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(typescript@6.0.3)(vite@8.1.5) '@vitejs/devtools-kit': specifier: workspace:* version: link:../kit @@ -823,7 +823,7 @@ importers: version: 7.0.0 devframe: specifier: catalog:deps - version: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + version: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) h3: specifier: catalog:deps version: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.22)) @@ -902,13 +902,13 @@ importers: dependencies: '@devframes/hub': specifier: catalog:deps - version: 0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + version: 0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) '@devframes/json-render': specifier: catalog:deps - version: 0.7.9(@devframes/hub@0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + version: 0.7.11(@devframes/hub@0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) devframe: specifier: catalog:deps - version: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + version: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) local-pkg: specifier: catalog:deps version: 1.2.1 @@ -945,7 +945,7 @@ importers: version: 7.0.0 devframe: specifier: catalog:deps - version: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + version: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) local-pkg: specifier: catalog:deps version: 1.2.1 @@ -1085,7 +1085,7 @@ importers: version: 3.1.2 devframe: specifier: catalog:deps - version: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + version: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) diff-match-patch-es: specifier: catalog:frontend version: 2.0.0 @@ -1215,7 +1215,7 @@ importers: version: 3.1.2 devframe: specifier: catalog:deps - version: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + version: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) diff-match-patch-es: specifier: catalog:frontend version: 2.0.0 @@ -1280,7 +1280,7 @@ importers: devDependencies: tsdown: specifier: catalog:build - version: 0.22.13(@vitejs/devtools@0.4.3)(@volar/typescript@2.4.28)(oxc-resolver@11.23.0)(publint@0.3.21)(tsx@4.23.1)(typescript@6.0.3)(unrun@0.3.1(synckit@0.11.13))(vue-tsc@3.3.7(typescript@6.0.3)) + version: 0.22.13(@vitejs/devtools@0.4.4)(@volar/typescript@2.4.28)(oxc-resolver@11.23.0)(publint@0.3.21)(tsx@4.23.1)(typescript@6.0.3)(unrun@0.3.1(synckit@0.11.13))(vue-tsc@3.3.7(typescript@6.0.3)) tsx: specifier: catalog:build version: 4.23.1 @@ -1327,7 +1327,7 @@ importers: version: 6.0.8(vite@8.1.5(@types/node@25.0.3)(@vitejs/devtools@packages+core)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.40(typescript@5.9.3)) devframe: specifier: catalog:deps - version: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@5.9.3) + version: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@5.9.3) storybook: specifier: catalog:storybook version: 10.5.3(@types/react@19.2.17)(prettier@2.8.8)(react@19.2.8) @@ -1655,10 +1655,19 @@ packages: peerDependencies: devframe: 0.7.10 - '@devframes/hub@0.7.9': - resolution: {integrity: sha512-+tARSZfwkzez6RKA8ShlntAmfKTn7Z+IM2xwDilNMze5YO+E4n/WmaJBYZL2VvXdDiWB0cJbbwHto+vsrEQB9g==} + '@devframes/hub@0.7.11': + resolution: {integrity: sha512-r+qyGg0Hu1w1q7mNDCmuZUryeZAi2sUC8FTwEbwjqPT5SGjWnIoj1rMmRbJIOIBaC+2ofOejTGel4jklmzHc3w==} peerDependencies: - devframe: 0.7.9 + devframe: 0.7.11 + + '@devframes/json-render@0.7.11': + resolution: {integrity: sha512-Iza65fq6U9OSxKUEhGokfpfMz21ISLkWF9jeS0bQHugTLKRGcPRO/tu3YE+nTe6EiKP3kQFBvSNZ1FcZ1FPfSg==} + peerDependencies: + '@devframes/hub': 0.7.11 + devframe: 0.7.11 + peerDependenciesMeta: + '@devframes/hub': + optional: true '@devframes/json-render@0.7.9': resolution: {integrity: sha512-VgUBkxyCG60wTMvihZpGwX9RZwhmhNf+znh/R0Dlwz602E74HtCD2J8jdWqKje4aia4KmmHFLLwWC/itmkfJZg==} @@ -1669,6 +1678,16 @@ packages: '@devframes/hub': optional: true + '@devframes/plugin-inspect@0.7.11': + resolution: {integrity: sha512-eL1zFUqr65PFORTlBmdJuV7VlqUed5AXRG8SB9ofRyyiauvEWX31PUMD5g6DnZyJBztq97pCxiB0X4AIXNGmeg==} + hasBin: true + peerDependencies: + devframe: 0.7.11 + vite: ^8.1.5 + peerDependenciesMeta: + vite: + optional: true + '@devframes/plugin-inspect@0.7.9': resolution: {integrity: sha512-pDt/cjOvc8hF0Qj4WwBo+drnGD9yy1ck/CCFr2wno+d6AlM+00rxTgP1cCecAckVRNPxeVzSmQ7rFo8Ep/zPIw==} hasBin: true @@ -1679,6 +1698,17 @@ packages: vite: optional: true + '@devframes/plugin-messages@0.7.11': + resolution: {integrity: sha512-7Hbgtlo84g6gp5xUOzxKWuBVVBQmT5QswzQ3K2Ax6nZyYO9kGdjDrdGrIWxH5D3acEvzxJw1ixgoRDHPmNtQSQ==} + hasBin: true + peerDependencies: + '@devframes/hub': 0.7.11 + devframe: 0.7.11 + vite: ^8.1.5 + peerDependenciesMeta: + vite: + optional: true + '@devframes/plugin-messages@0.7.9': resolution: {integrity: sha512-WcKRQEPw+VAjbubEZx7gHZdaKMkN4FwGkGBHCoAfe/4rbY2Sl2l/KEIW6+og0y8luoxHWxmnmrus1Jkc9mRZow==} hasBin: true @@ -1690,6 +1720,16 @@ packages: vite: optional: true + '@devframes/plugin-terminals@0.7.11': + resolution: {integrity: sha512-eeUvY0IyBJ2Ao529Wwn/7tgXIrtVyXs5kfPRtsLiFq9/gAl4fmS0Lj4FXX0fpFFrbjraazj7Z9AIlBaPLVp83A==} + hasBin: true + peerDependencies: + devframe: 0.7.11 + vite: ^8.1.5 + peerDependenciesMeta: + vite: + optional: true + '@devframes/plugin-terminals@0.7.9': resolution: {integrity: sha512-rvDtNCzZyMRvtd89IV8UHImI0fHGqa88DzP87zHVAUoscL1WSHv9bE8zXW5yKj/tJMpJziVIeGJKTbto07tIrQ==} hasBin: true @@ -4641,28 +4681,28 @@ packages: peerDependencies: vite: ^8.1.5 - '@vitejs/devtools-kit@0.4.3': - resolution: {integrity: sha512-FjETJwshQQwa9DNeCYtjzfQhvye3e4XMAkDSVmdDicPj8dJM6lJapKTHvNU7SUoxgm8e5tc7OcFyQYaq1xDH3A==} + '@vitejs/devtools-kit@0.4.4': + resolution: {integrity: sha512-HwCjEzuCwCSkv3X4ZJCvQcO9qCaLm9uImYTw6TQ3z71jJTmqYn0UcJx8tqY23KgF/jPPbaYBSHYG3QSGZWqMNA==} peerDependencies: vite: ^8.1.5 - '@vitejs/devtools-oxc@0.4.3': - resolution: {integrity: sha512-fBFQmg323Rxn68K3ouf1SwuxZ8rBm7h/TvOOubXbHM+5mypYR/XrZQsX9yCBWFpTwVgzgNbxArd1TPPqu/y3qw==} + '@vitejs/devtools-oxc@0.4.4': + resolution: {integrity: sha512-kOVwEGgItG4SppMKF36iG1VccZLDAE+iE+A5litv8prek2NadRzP0pvrIuIHN3hPg6uUgcXyGiS9Oa2Qspucog==} hasBin: true '@vitejs/devtools-rolldown@0.3.4': resolution: {integrity: sha512-5MFcRpZIqL50A6Kb31jHaRDt1jg7WkdQUKx53deFZdp8DxRezzzwGBaYH00kK7fWJC1UDvlwROByHgavC/O52A==} - '@vitejs/devtools-rolldown@0.4.3': - resolution: {integrity: sha512-8/OXV4dSOlULP581JmoEzFDWruf96q9MpIChXpOfRob/79jIb38s+sAgOhCMFg7vSkOM+NdDRMSez9uc/kPxog==} + '@vitejs/devtools-rolldown@0.4.4': + resolution: {integrity: sha512-NvrX280YnZAnK8RJZIaHrv9SF16VsdukdJEAyen/C7FqFt93MkXTYWL4He2j1Jk/jwg0aos9Qn9lIgkpzymSnQ==} - '@vitejs/devtools-vite@0.4.3': - resolution: {integrity: sha512-mLGvWMxbY6l2+NX3rsPznXWN8WpNVE2hPDy57rjZEbbzQkm0BtIm3/B0FwOTuNsgjnYEaDZBIEO8Mj68sqY5iw==} + '@vitejs/devtools-vite@0.4.4': + resolution: {integrity: sha512-hAsOLpap8jBlNYdXvn5CgiEUeH+jJg/KTZeITdBHfO57Zk7LD4HhaOd3y/ImEt8W41azXwAj9LYNeUwoBY3ZaQ==} peerDependencies: vite: ^8.1.5 - '@vitejs/devtools-vitest@0.4.3': - resolution: {integrity: sha512-PI8iWimwNDSDY7KZv1Y/OVRqrXoSHcHV1f7yLi5XPJnoRd7E9vSwenX0PB7xClXeMefFzURNf84w87SITQtiow==} + '@vitejs/devtools-vitest@0.4.4': + resolution: {integrity: sha512-1j0HUIWVnVi78fqbnaCaLy44Tl5lPn35WWAIA0k0qyCIlni27gH27DLtk1QJhUEizSDYe4Qn0n2p4t4ShIgavw==} peerDependencies: vitest: '*' peerDependenciesMeta: @@ -4675,14 +4715,14 @@ packages: peerDependencies: vite: ^8.1.5 - '@vitejs/devtools@0.4.3': - resolution: {integrity: sha512-+CEeUTVsRdCUMiy4YeOBOuuMPaYA9o0cA7O/gVIqBiT+WgkXEHHiMQH5MaqtaEMgoH0ii/8W1nQrtstorlELrQ==} + '@vitejs/devtools@0.4.4': + resolution: {integrity: sha512-mNNEMYBHNg3EzIIADgZlOhqqeaXN1EUguxsh14pxZz4BiEfdXTcNy9KTWuOSfa0GKgMbWP4H7uUFNq6cz5gbog==} hasBin: true peerDependencies: - '@vitejs/devtools-oxc': ^0.4.3 - '@vitejs/devtools-rolldown': ^0.4.3 - '@vitejs/devtools-vite': ^0.4.3 - '@vitejs/devtools-vitest': ^0.4.3 + '@vitejs/devtools-oxc': ^0.4.4 + '@vitejs/devtools-rolldown': ^0.4.4 + '@vitejs/devtools-vite': ^0.4.4 + '@vitejs/devtools-vitest': ^0.4.4 vite: ^8.1.5 peerDependenciesMeta: '@vitejs/devtools-oxc': @@ -6009,6 +6049,17 @@ packages: '@modelcontextprotocol/sdk': optional: true + devframe@0.7.11: + resolution: {integrity: sha512-EC65NA7B1Q1H0daTMiPn2BLCjekIVC8V1WvoPyXAM/pBhNGGlRRaSVSfmAsaYmqSDT3osD8nWZ6KYhExU2KOfA==} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.0.0 + cac: ^7.0.0 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + cac: + optional: true + devframe@0.7.9: resolution: {integrity: sha512-ZWSHN5uk6KwCsrCXhu373kdBnk5kxkgxmGpD8tvv5DablgUOfWz+JrP4ufufTrns6PtQFP1Nh5S7sffWoLLp8w==} peerDependencies: @@ -10182,68 +10233,95 @@ snapshots: perfect-debounce: 2.1.0 tinyexec: 1.2.4 zigpty: 0.2.1 + optional: true - '@devframes/hub@0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))': + '@devframes/hub@0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))': dependencies: birpc: 4.0.0 destr: 2.0.5 - devframe: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + devframe: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) nostics: 1.2.0 pathe: 2.0.3 perfect-debounce: 2.1.0 tinyexec: 1.2.4 zigpty: 0.2.1 - optional: true - '@devframes/json-render@0.7.9(@devframes/hub@0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))': + '@devframes/json-render@0.7.11(@devframes/hub@0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))': dependencies: '@json-render/core': 0.19.0(zod@4.3.6) - devframe: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + devframe: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) nostics: 1.2.0 zod: 4.3.6 optionalDependencies: - '@devframes/hub': 0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + '@devframes/hub': 0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) - '@devframes/json-render@0.7.9(@devframes/hub@0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))': + '@devframes/json-render@0.7.9(@devframes/hub@0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))': dependencies: '@json-render/core': 0.19.0(zod@4.3.6) devframe: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) nostics: 1.2.0 zod: 4.3.6 optionalDependencies: - '@devframes/hub': 0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + '@devframes/hub': 0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) optional: true - '@devframes/plugin-inspect@0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5)': + '@devframes/plugin-inspect@0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5)': dependencies: '@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3)) cac: 7.0.0 - devframe: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + devframe: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) nostics: 1.2.0 optionalDependencies: vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.3.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) transitivePeerDependencies: - valibot - '@devframes/plugin-messages@0.7.9(@devframes/hub@0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(vite@8.1.5)': + '@devframes/plugin-inspect@0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5)': dependencies: - '@devframes/hub': 0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + '@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3)) cac: 7.0.0 devframe: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) nostics: 1.2.0 + optionalDependencies: + vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) + transitivePeerDependencies: + - valibot + optional: true + + '@devframes/plugin-messages@0.7.11(@devframes/hub@0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(vite@8.1.5)': + dependencies: + '@devframes/hub': 0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + cac: 7.0.0 + devframe: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + nostics: 1.2.0 optionalDependencies: vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.3.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) - '@devframes/plugin-messages@0.7.9(@devframes/hub@0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(vite@8.1.5)': + '@devframes/plugin-messages@0.7.9(@devframes/hub@0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(vite@8.1.5)': dependencies: - '@devframes/hub': 0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + '@devframes/hub': 0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) cac: 7.0.0 devframe: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) nostics: 1.2.0 optionalDependencies: - vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.3)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) optional: true + '@devframes/plugin-terminals@0.7.11(devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(typescript@6.0.3)(vite@8.1.5)': + dependencies: + '@xterm/addon-fit': 0.11.0 + '@xterm/xterm': 6.0.0 + cac: 7.0.0 + devframe: 0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) + nostics: 1.2.0 + pathe: 2.0.3 + valibot: 1.4.2(typescript@6.0.3) + zigpty: 0.2.1 + optionalDependencies: + vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.3.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) + transitivePeerDependencies: + - typescript + '@devframes/plugin-terminals@0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(typescript@6.0.3)(vite@8.1.5)': dependencies: '@xterm/addon-fit': 0.11.0 @@ -10255,9 +10333,10 @@ snapshots: valibot: 1.4.2(typescript@6.0.3) zigpty: 0.2.1 optionalDependencies: - vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.3.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) transitivePeerDependencies: - typescript + optional: true '@docsearch/css@4.6.3': {} @@ -13316,16 +13395,16 @@ snapshots: - srvx - typescript - '@vitejs/devtools-kit@0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)': + '@vitejs/devtools-kit@0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)': dependencies: - '@devframes/hub': 0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) - '@devframes/json-render': 0.7.9(@devframes/hub@0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + '@devframes/hub': 0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + '@devframes/json-render': 0.7.9(@devframes/hub@0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) devframe: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) local-pkg: 1.2.1 mlly: 1.8.2 nostics: 1.2.0 nypm: 0.6.8 - vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.3)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) transitivePeerDependencies: - '@modelcontextprotocol/sdk' - cac @@ -13333,9 +13412,9 @@ snapshots: - typescript optional: true - '@vitejs/devtools-oxc@0.4.3(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)': + '@vitejs/devtools-oxc@0.4.4(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)': dependencies: - '@vitejs/devtools-kit': 0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) + '@vitejs/devtools-kit': 0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) cac: 7.0.0 devframe: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) local-pkg: 1.2.1 @@ -13409,11 +13488,11 @@ snapshots: - webpack optional: true - '@vitejs/devtools-rolldown@0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)(vue@3.5.40(typescript@6.0.3))': + '@vitejs/devtools-rolldown@0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)(vue@3.5.40(typescript@6.0.3))': dependencies: '@floating-ui/dom': 1.8.0 '@rolldown/debug': 1.2.0 - '@vitejs/devtools-kit': 0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) + '@vitejs/devtools-kit': 0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) d3-shape: 3.2.0 diff: 9.0.0 nostics: 1.2.0 @@ -13428,16 +13507,16 @@ snapshots: - vue optional: true - '@vitejs/devtools-vite@0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)': + '@vitejs/devtools-vite@0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)': dependencies: '@floating-ui/dom': 1.8.0 - '@vitejs/devtools-kit': 0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) + '@vitejs/devtools-kit': 0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) d3-shape: 3.2.0 envinfo: 7.21.0 nostics: 1.2.0 pathe: 2.0.3 perfect-debounce: 2.1.0 - vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.3)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) transitivePeerDependencies: - '@modelcontextprotocol/sdk' - cac @@ -13445,9 +13524,9 @@ snapshots: - typescript optional: true - '@vitejs/devtools-vitest@0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)(vitest@4.1.10)': + '@vitejs/devtools-vitest@0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)(vitest@4.1.10)': dependencies: - '@vitejs/devtools-kit': 0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) + '@vitejs/devtools-kit': 0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) get-port-please: 3.2.0 local-pkg: 1.2.1 nostics: 1.2.0 @@ -13516,13 +13595,13 @@ snapshots: - webpack optional: true - '@vitejs/devtools@0.4.3(@vitejs/devtools-oxc@0.4.3)(@vitejs/devtools-rolldown@0.4.3)(@vitejs/devtools-vite@0.4.3)(@vitejs/devtools-vitest@0.4.3)(crossws@0.4.10(srvx@0.11.22))(srvx@0.11.22)(typescript@6.0.3)(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5)': + '@vitejs/devtools@0.4.4(@vitejs/devtools-oxc@0.4.4)(@vitejs/devtools-rolldown@0.4.4)(@vitejs/devtools-vite@0.4.4)(@vitejs/devtools-vitest@0.4.4)(crossws@0.4.10(srvx@0.11.22))(srvx@0.11.22)(typescript@6.0.3)(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5)': dependencies: - '@devframes/hub': 0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) + '@devframes/hub': 0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)) '@devframes/plugin-inspect': 0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5) - '@devframes/plugin-messages': 0.7.9(@devframes/hub@0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(vite@8.1.5) + '@devframes/plugin-messages': 0.7.9(@devframes/hub@0.7.10(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)))(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(vite@8.1.5) '@devframes/plugin-terminals': 0.7.9(devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3))(typescript@6.0.3)(vite@8.1.5) - '@vitejs/devtools-kit': 0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) + '@vitejs/devtools-kit': 0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) birpc: 4.0.0 cac: 7.0.0 devframe: 0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3) @@ -13532,13 +13611,13 @@ snapshots: nostics: 1.2.0 obug: 2.1.4 pathe: 2.0.3 - vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.3)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) vue: 3.5.40(typescript@6.0.3) optionalDependencies: - '@vitejs/devtools-oxc': 0.4.3(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) - '@vitejs/devtools-rolldown': 0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)(vue@3.5.40(typescript@6.0.3)) - '@vitejs/devtools-vite': 0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) - '@vitejs/devtools-vitest': 0.4.3(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)(vitest@4.1.10) + '@vitejs/devtools-oxc': 0.4.4(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) + '@vitejs/devtools-rolldown': 0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)(vue@3.5.40(typescript@6.0.3)) + '@vitejs/devtools-vite': 0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5) + '@vitejs/devtools-vitest': 0.4.4(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3)(vite@8.1.5)(vitest@4.1.10) transitivePeerDependencies: - '@modelcontextprotocol/sdk' - crossws @@ -15003,7 +15082,7 @@ snapshots: - srvx - typescript - devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@5.9.3): + devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@5.9.3): dependencies: '@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3)) birpc: 4.0.0 @@ -15021,6 +15100,24 @@ snapshots: - srvx - typescript + devframe@0.7.11(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3): + dependencies: + '@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3)) + birpc: 4.0.0 + crossws: 0.4.10(srvx@0.11.22) + destr: 2.0.5 + h3: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.22)) + mrmime: 2.0.1 + nostics: 1.2.0 + pathe: 2.0.3 + ufo: 1.6.4 + valibot: 1.4.2(typescript@6.0.3) + optionalDependencies: + cac: 7.0.0 + transitivePeerDependencies: + - srvx + - typescript + devframe@0.7.9(cac@7.0.0)(srvx@0.11.22)(typescript@6.0.3): dependencies: '@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3)) @@ -15038,6 +15135,7 @@ snapshots: transitivePeerDependencies: - srvx - typescript + optional: true devlop@1.1.0: dependencies: @@ -18649,7 +18747,7 @@ snapshots: - oxc-resolver - vue-tsc - tsdown@0.22.13(@vitejs/devtools@0.4.3)(@volar/typescript@2.4.28)(oxc-resolver@11.23.0)(publint@0.3.21)(tsx@4.23.1)(typescript@6.0.3)(unrun@0.3.1(synckit@0.11.13))(vue-tsc@3.3.7(typescript@6.0.3)): + tsdown@0.22.13(@vitejs/devtools@0.4.4)(@volar/typescript@2.4.28)(oxc-resolver@11.23.0)(publint@0.3.21)(tsx@4.23.1)(typescript@6.0.3)(unrun@0.3.1(synckit@0.11.13))(vue-tsc@3.3.7(typescript@6.0.3)): dependencies: ansis: 4.3.1 cac: 7.0.0 @@ -18667,7 +18765,7 @@ snapshots: unconfig-core: 7.5.0 verkit: 0.1.2 optionalDependencies: - '@vitejs/devtools': 0.4.3(@vitejs/devtools-oxc@0.4.3)(@vitejs/devtools-rolldown@0.4.3)(@vitejs/devtools-vite@0.4.3)(@vitejs/devtools-vitest@0.4.3)(crossws@0.4.10(srvx@0.11.22))(srvx@0.11.22)(typescript@6.0.3)(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5) + '@vitejs/devtools': 0.4.4(@vitejs/devtools-oxc@0.4.4)(@vitejs/devtools-rolldown@0.4.4)(@vitejs/devtools-vite@0.4.4)(@vitejs/devtools-vitest@0.4.4)(crossws@0.4.10(srvx@0.11.22))(srvx@0.11.22)(typescript@6.0.3)(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5) publint: 0.3.21 tsx: 4.23.1 typescript: 6.0.3 @@ -19281,7 +19379,7 @@ snapshots: tsx: 4.23.1 yaml: 2.9.0 - vite@8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.3)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0): + vite@8.1.5(@types/node@25.0.3)(@vitejs/devtools@0.4.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.5 @@ -19290,7 +19388,7 @@ snapshots: tinyglobby: 0.2.17 optionalDependencies: '@types/node': 25.0.3 - '@vitejs/devtools': 0.4.3(@vitejs/devtools-oxc@0.4.3)(@vitejs/devtools-rolldown@0.4.3)(@vitejs/devtools-vite@0.4.3)(@vitejs/devtools-vitest@0.4.3)(crossws@0.4.10(srvx@0.11.22))(srvx@0.11.22)(typescript@6.0.3)(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5) + '@vitejs/devtools': 0.4.4(@vitejs/devtools-oxc@0.4.4)(@vitejs/devtools-rolldown@0.4.4)(@vitejs/devtools-vite@0.4.4)(@vitejs/devtools-vitest@0.4.4)(crossws@0.4.10(srvx@0.11.22))(srvx@0.11.22)(typescript@6.0.3)(valibot@1.4.2(typescript@6.0.3))(vite@8.1.5) esbuild: 0.28.1 fsevents: 2.3.3 jiti: 2.7.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c532f4a69..a5661d245 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -61,16 +61,16 @@ catalogs: unrun: ^0.3.1 vite: ^8.1.5 deps: - '@devframes/hub': ^0.7.10 - '@devframes/json-render': ^0.7.9 - '@devframes/plugin-inspect': ^0.7.9 - '@devframes/plugin-messages': ^0.7.9 - '@devframes/plugin-terminals': ^0.7.9 + '@devframes/hub': ^0.7.11 + '@devframes/json-render': ^0.7.11 + '@devframes/plugin-inspect': ^0.7.11 + '@devframes/plugin-messages': ^0.7.11 + '@devframes/plugin-terminals': ^0.7.11 '@rolldown/debug': ^1.2.0 actionspack: ^0.1.5 birpc: ^4.0.0 cac: ^7.0.0 - devframe: ^0.7.9 + devframe: ^0.7.11 diff: ^9.0.0 envinfo: ^7.21.0 get-port-please: ^3.2.0 diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.d.ts index a86a7736a..c5032edc4 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.d.ts @@ -11,11 +11,20 @@ export declare const CLIENT_CONTEXT_KEY: string; // #endregion // #region Other +export { attachDevToolsFrameNav } export { CommandsContext } export { connectRemoteDevTools } export { ConnectRemoteDevToolsOptions } export { DevToolsClientContext } export { DevToolsClientRpcHost } +export { DevToolsFrameNavClient } +export { DevToolsFrameNavClientOptions } +export { DevToolsFrameNavEnvelope } +export { DevToolsFrameNavFrameMessage } +export { DevToolsFrameNavHostMessage } +export { DevToolsFrameNavHostPayload } +export { DevToolsFrameNavListenTarget } +export { DevToolsFrameTab } export { DevToolsRpcClient } export { DevToolsRpcClientCall } export { DevToolsRpcClientCallEvent } @@ -36,6 +45,8 @@ export { DockRenderersContext } export { DocksContext } export { DocksEntriesContext } export { DocksPanelContext } +export { FRAME_NAV_CHANNEL } +export { FRAME_NAV_VERSION } export { parseRemoteConnection } export { RpcClientEvents } export { RpcStreamingClientHost } diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.js b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.js index d86ff5d9d..bb324ec1b 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.js +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/client.snapshot.js @@ -11,6 +11,9 @@ export var CLIENT_CONTEXT_KEY /* const */ // #endregion // #region Other +export { attachDevToolsFrameNav } export { connectRemoteDevTools } +export { FRAME_NAV_CHANNEL } +export { FRAME_NAV_VERSION } export { parseRemoteConnection } // #endregion \ No newline at end of file diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/index.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/index.snapshot.d.ts index 0ad0cb43b..c05eb04dc 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/index.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/index.snapshot.d.ts @@ -35,7 +35,6 @@ export interface JsonRenderer { updateState: (_: Record) => void; dispose: () => void; readonly _stateKey: string; - readonly upstreamVersion: string; readonly view: JsonRenderViewRef; } export interface KitNodeContext extends Omit { @@ -94,6 +93,7 @@ export { DevToolsDockHost } export { DevToolsDocksActiveState } export { DevToolsDocksUserSettings } export { DevToolsDockUserEntry } +export { DevToolsFrameSubTabsConfig } export { DevToolsHost } export { DevToolsMessageElementPosition } export { DevToolsMessageEntry } @@ -104,6 +104,7 @@ export { DevToolsMessageHandle } export { DevToolsMessageLevel } export { DevToolsMessagesClient } export { DevToolsMessagesHost } +export { DevToolsNavTarget } export { DevToolsNodeContext } export { DevToolsNodeRpcSession } export { DevToolsRpcClientFunctions }