|
| 1 | +import type { KitNodeContext } from '@vitejs/devtools-kit/node' |
1 | 2 | import type { Plugin } from 'vite' |
2 | 3 | import { createInspectDevframe } from '@devframes/plugin-inspect' |
3 | 4 | import { createMessagesDevframe } from '@devframes/plugin-messages' |
4 | 5 | import { createTerminalsDevframe } from '@devframes/plugin-terminals' |
| 6 | +import { DEVTOOLS_INSPECTOR_DOCK_ID } from '@vitejs/devtools-kit/constants' |
5 | 7 | import { createPluginFromDevframe } from '@vitejs/devtools-kit/node' |
6 | 8 | import { DevToolsBuild } from './build' |
7 | 9 | import { DevToolsInjection } from './injection' |
@@ -58,24 +60,81 @@ export async function DevTools(options: DevToolsOptions = {}): Promise<Plugin[]> |
58 | 60 | // dock — rather than the `~viteplus` group (which collects integrations |
59 | 61 | // like Rolldown). The hub's own `~terminals` / `~messages` docks are |
60 | 62 | // suppressed via `builtinDocks` in `createDevToolsContext`. |
61 | | - plugins.push(createPluginFromDevframe(createTerminalsDevframe(), { |
| 63 | + // |
| 64 | + // The hub's built-in `~terminals` / `~messages` docks auto-hid themselves |
| 65 | + // when empty; the plugin-mounted iframe docks that replaced them carry no |
| 66 | + // such rule, so we restore it here — the dock is filtered out of the bar |
| 67 | + // (`when: 'false'`) whenever there are no sessions / messages. |
| 68 | + const terminalsDevframe = createTerminalsDevframe() |
| 69 | + plugins.push(createPluginFromDevframe(terminalsDevframe, { |
62 | 70 | dock: { category: '~builtin' }, |
| 71 | + setup(ctx) { |
| 72 | + hideDockWhenEmpty( |
| 73 | + ctx, |
| 74 | + terminalsDevframe.id, |
| 75 | + () => ctx.terminals.sessions.size === 0, |
| 76 | + refresh => ctx.terminals.events.on('terminal:session:updated', refresh), |
| 77 | + ) |
| 78 | + }, |
63 | 79 | })) |
64 | | - plugins.push(createPluginFromDevframe(createMessagesDevframe(), { |
| 80 | + const messagesDevframe = createMessagesDevframe() |
| 81 | + plugins.push(createPluginFromDevframe(messagesDevframe, { |
65 | 82 | dock: { category: '~builtin' }, |
| 83 | + setup(ctx) { |
| 84 | + hideDockWhenEmpty( |
| 85 | + ctx, |
| 86 | + messagesDevframe.id, |
| 87 | + () => ctx.messages.entries.size === 0, |
| 88 | + (refresh) => { |
| 89 | + ctx.messages.events.on('message:added', refresh) |
| 90 | + ctx.messages.events.on('message:updated', refresh) |
| 91 | + ctx.messages.events.on('message:removed', refresh) |
| 92 | + ctx.messages.events.on('message:cleared', refresh) |
| 93 | + }, |
| 94 | + ) |
| 95 | + }, |
66 | 96 | })) |
67 | 97 |
|
68 | 98 | // Meta-introspection ("DevTools for the DevTools"), provided by the |
69 | 99 | // official devframe inspector plugin (replaces the former |
70 | | - // `@vitejs/devtools-self-inspect` package). |
71 | | - plugins.push(createPluginFromDevframe(createInspectDevframe(), { |
| 100 | + // `@vitejs/devtools-self-inspect` package). Pinned to a stable id so the |
| 101 | + // client can gate it behind the `showDevframeInspector` user setting; |
| 102 | + // hidden by default (opt in via Settings → Advanced). |
| 103 | + plugins.push(createPluginFromDevframe(createInspectDevframe({ id: DEVTOOLS_INSPECTOR_DOCK_ID }), { |
72 | 104 | dock: { category: '~builtin', icon: 'ph:stethoscope-duotone' }, |
73 | 105 | })) |
74 | 106 | } |
75 | 107 |
|
76 | 108 | return plugins |
77 | 109 | } |
78 | 110 |
|
| 111 | +/** |
| 112 | + * Keep a dock entry out of the dock bar while its backing collection is empty. |
| 113 | + * |
| 114 | + * Mirrors the hub's built-in `~terminals` / `~messages` auto-hide: sets the |
| 115 | + * dock's `when` clause to `'false'` (unconditionally hidden) when `isEmpty()` |
| 116 | + * and clears it otherwise, re-evaluating whenever the passed `subscribe` |
| 117 | + * callback fires. Each `docks.update` re-broadcasts the dock shared state. |
| 118 | + */ |
| 119 | +function hideDockWhenEmpty( |
| 120 | + ctx: KitNodeContext, |
| 121 | + dockId: string, |
| 122 | + isEmpty: () => boolean, |
| 123 | + subscribe: (refresh: () => void) => void, |
| 124 | +): void { |
| 125 | + const sync = (): void => { |
| 126 | + const view = ctx.docks.views.get(dockId) |
| 127 | + if (!view) |
| 128 | + return |
| 129 | + const when = isEmpty() ? 'false' : undefined |
| 130 | + if (view.when === when) |
| 131 | + return |
| 132 | + ctx.docks.update({ ...view, when }) |
| 133 | + } |
| 134 | + subscribe(sync) |
| 135 | + sync() |
| 136 | +} |
| 137 | + |
79 | 138 | export { |
80 | 139 | DevToolsBuild, |
81 | 140 | DevToolsInjection, |
|
0 commit comments