@devframes/hub 0.9.8 → 0.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assemble-Hj36CCzH.mjs +103 -0
- package/dist/client/index.d.mts +64 -50
- package/dist/client/index.mjs +136 -42
- package/dist/{constants-DJrPlLi0.d.mts → constants-Bz4yclHo.d.mts} +14 -5
- package/dist/{constants-D1zicoJ4.mjs → constants-Da23JxCZ.mjs} +12 -5
- package/dist/constants.d.mts +1 -1
- package/dist/constants.mjs +1 -1
- package/dist/{context-DYUkd3il.mjs → context-BWaW6N53.mjs} +259 -225
- package/dist/{context-BJFGlcf8.d.mts → context-Di-fhMKP.d.mts} +17 -17
- package/dist/{index-OpSX0dK5.d.mts → index-faD2d5iX.d.mts} +2 -2
- package/dist/index.d.mts +3 -3
- package/dist/node/build.d.mts +74 -0
- package/dist/node/build.mjs +167 -0
- package/dist/node/index.d.mts +28 -19
- package/dist/node/index.mjs +3 -3
- package/dist/node/initiate.d.mts +39 -32
- package/dist/node/initiate.mjs +60 -122
- package/dist/{remote-url-Bgc7gtsP.mjs → remote-url-UClKLQ5_.mjs} +34 -39
- package/dist/{settings-DwxCyeI6.d.mts → settings-CWHPzCWS.d.mts} +59 -38
- package/dist/types/index.d.mts +3 -3
- package/package.json +4 -3
- package/dist/{dist-R0T2g9Vw.mjs → dist-BP3CGpgZ.mjs} +1 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { a as resolveClientModuleSpecifier } from "./remote-url-UClKLQ5_.mjs";
|
|
2
|
+
import { b as diagnostics, v as prepareDevframe, y as skippedInStaticBuild } from "./context-BWaW6N53.mjs";
|
|
3
|
+
import { joinURL, withTrailingSlash } from "ufo";
|
|
4
|
+
import { DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_DOCK_IMPORTS_FILENAME, DEVFRAME_MCP_ROUTE, DEVFRAME_WS_ROUTE } from "devframe/constants";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { resolve } from "pathe";
|
|
7
|
+
//#region src/node/assemble.ts
|
|
8
|
+
/** Reserved filenames directly under the hub base; a frame id can't shadow them. */
|
|
9
|
+
const RESERVED_HUB_PATHS = [
|
|
10
|
+
DEVFRAME_CONNECTION_META_FILENAME,
|
|
11
|
+
DEVFRAME_DOCK_IMPORTS_FILENAME,
|
|
12
|
+
DEVFRAME_WS_ROUTE,
|
|
13
|
+
DEVFRAME_MCP_ROUTE,
|
|
14
|
+
"__index.json",
|
|
15
|
+
"__renderers",
|
|
16
|
+
"embedded.js"
|
|
17
|
+
];
|
|
18
|
+
function normalizeDevframeEntry(entry) {
|
|
19
|
+
return "devframe" in entry ? entry : { devframe: entry };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Flatten the `devframes` input: await every thenable, call every factory,
|
|
23
|
+
* spread the arrays, and drop the empty slots, so a host can build the list
|
|
24
|
+
* conditionally (`isDev && loadInspect()`) without filtering it first.
|
|
25
|
+
*/
|
|
26
|
+
function resolveDevframesInput(input) {
|
|
27
|
+
return Promise.all(input.map(async (entry) => {
|
|
28
|
+
const resolved = await (typeof entry === "function" ? entry() : entry);
|
|
29
|
+
return (Array.isArray(resolved) ? resolved : [resolved]).filter((slot) => slot != null).map(normalizeDevframeEntry);
|
|
30
|
+
})).then((arrays) => arrays.flat());
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Validate the renderer-module registrations fail-fast: route-safe types
|
|
34
|
+
* (each becomes the `<base>__renderers/<type>.mjs` URL segment), one module
|
|
35
|
+
* per type, and an existing bundle file (renderer packages are prebuilt).
|
|
36
|
+
*/
|
|
37
|
+
function resolveRendererRegistrations(registrations) {
|
|
38
|
+
const seen = /* @__PURE__ */ new Set();
|
|
39
|
+
return registrations.map((registration) => {
|
|
40
|
+
if (!/^[\w.-]+$/.test(registration.type)) throw diagnostics.DF8110({ type: registration.type });
|
|
41
|
+
if (seen.has(registration.type)) throw diagnostics.DF8108({ type: registration.type });
|
|
42
|
+
seen.add(registration.type);
|
|
43
|
+
const file = resolve(registration.file);
|
|
44
|
+
if (!existsSync(file)) throw diagnostics.DF8109({
|
|
45
|
+
type: registration.type,
|
|
46
|
+
file
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
...registration,
|
|
50
|
+
file
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Render the dock client-script import map as an ES module: one dynamic
|
|
56
|
+
* import thunk per dock that carries a client script (`clientScript` on
|
|
57
|
+
* iframe docks, `action`, `renderer`). External viewers import this module
|
|
58
|
+
* from `<base>__client-imports.js` to load per-dock client code into the
|
|
59
|
+
* host page; `importFrom` values are URL paths the host serves, or bare npm
|
|
60
|
+
* specifiers resolved through the host's `clientModuleResolution` template.
|
|
61
|
+
*/
|
|
62
|
+
function renderClientImportsModule(ctx) {
|
|
63
|
+
const template = ctx.staticConfig.dock?.clientModuleResolution;
|
|
64
|
+
const entries = [];
|
|
65
|
+
for (const [id, view] of ctx.docks.views) {
|
|
66
|
+
const scripts = [];
|
|
67
|
+
const anyView = view;
|
|
68
|
+
if (anyView.clientScript) scripts.push(anyView.clientScript);
|
|
69
|
+
if (anyView.action) scripts.push(anyView.action);
|
|
70
|
+
if (anyView.renderer) scripts.push(anyView.renderer);
|
|
71
|
+
if (scripts.length === 0) continue;
|
|
72
|
+
const thunks = scripts.map((script) => `() => import(${JSON.stringify(resolveClientModuleSpecifier(script.importFrom, { template }))})`);
|
|
73
|
+
entries.push(` ${JSON.stringify(id)}: [${thunks.join(", ")}],`);
|
|
74
|
+
}
|
|
75
|
+
return `// Generated by @devframes/hub: dock client-script import map.\nexport const clientImports = {\n${entries.join("\n")}\n}\nexport default clientImports\n`;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Pass 1: mount each devframe under `<base><id>/` (SPA, meta, iframe dock)
|
|
79
|
+
* and queue its declared services, guarding the id against reserved hub
|
|
80
|
+
* filenames and route-pattern characters. Returns the deferred setup thunks.
|
|
81
|
+
*/
|
|
82
|
+
async function mountDevframes(ctx, devframes, base, frames, hubMcpEnabled) {
|
|
83
|
+
const setups = [];
|
|
84
|
+
for (const { devframe: def, dock } of devframes) {
|
|
85
|
+
if (RESERVED_HUB_PATHS.includes(def.id)) throw diagnostics.DF8000({ id: def.id });
|
|
86
|
+
if (!/^[\w.-]+$/.test(def.id)) throw diagnostics.DF8004({ id: def.id });
|
|
87
|
+
if (!hubMcpEnabled && def.cli?.mcp) diagnostics.DF8005({ id: def.id });
|
|
88
|
+
const frameBase = withTrailingSlash(joinURL(base, def.id));
|
|
89
|
+
const run = await prepareDevframe(ctx, def, {
|
|
90
|
+
base: frameBase,
|
|
91
|
+
...dock ? { dock } : {}
|
|
92
|
+
});
|
|
93
|
+
if (run) setups.push(run);
|
|
94
|
+
if (!skippedInStaticBuild(ctx, def)) frames.push({
|
|
95
|
+
id: def.id,
|
|
96
|
+
base: frameBase,
|
|
97
|
+
title: def.name
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return setups;
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
export { resolveRendererRegistrations as i, renderClientImportsModule as n, resolveDevframesInput as r, mountDevframes as t };
|
package/dist/client/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as DevframeMessageEntryInput, O as DevframeMessagesClient } from "../context-
|
|
2
|
-
import { A as DevframeViewIframe, C as DevframeDockUserEntry, F as RemoteConnectionInfo, P as NavTarget, S as DevframeDockPanelState, _ as DevframeDockEntry, a as DevframeCommandEntry, b as DevframeDockEntryIcon, g as DevframeDockEntriesGrouped, n as DevframeClientCommand, p as ClientScriptEntry, s as DevframeCommandKeybinding, t as DevframeDocksUserSettings } from "../settings-
|
|
3
|
-
import "../index-
|
|
1
|
+
import { C as DevframeMessageEntryInput, O as DevframeMessagesClient } from "../context-Di-fhMKP.mjs";
|
|
2
|
+
import { A as DevframeViewIframe, C as DevframeDockUserEntry, F as RemoteConnectionInfo, P as NavTarget, S as DevframeDockPanelState, _ as DevframeDockEntry, a as DevframeCommandEntry, b as DevframeDockEntryIcon, g as DevframeDockEntriesGrouped, n as DevframeClientCommand, p as ClientScriptEntry, s as DevframeCommandKeybinding, t as DevframeDocksUserSettings } from "../settings-CWHPzCWS.mjs";
|
|
3
|
+
import "../index-faD2d5iX.mjs";
|
|
4
4
|
import { DevframeClientRpcHost, DevframeConnection, DevframeConnectionStatus, DevframeRpcClient, DevframeRpcClientOptions, DevframeRpcContext, RpcClientEvents, RpcClientEvents as RpcClientEvents$1 } from "devframe/client";
|
|
5
5
|
import { EventEmitter } from "devframe/types";
|
|
6
6
|
import { SharedState } from "devframe/utils/shared-state";
|
|
@@ -12,10 +12,10 @@ export * from "devframe/client";
|
|
|
12
12
|
* specifiers pass through untouched; a **bare** specifier resolves through
|
|
13
13
|
* the explicit `resolveClientModule` callback (a viewer's own policy), then
|
|
14
14
|
* the host-advertised `template` (`ConnectionMeta.configs.dock.clientModuleResolution`,
|
|
15
|
-
* its `{specifier}` token replaced
|
|
15
|
+
* its `{specifier}` token replaced, e.g. Vite's `'/@id/{specifier}'`),
|
|
16
16
|
* resolved against `metaBaseUrl` so it targets the host's origin from any
|
|
17
|
-
* viewer. With neither, it stays unchanged
|
|
18
|
-
* cover it.
|
|
17
|
+
* viewer. With neither, it stays unchanged, since a page import map may
|
|
18
|
+
* still cover it.
|
|
19
19
|
*/
|
|
20
20
|
declare function resolveClientModuleSpecifier(specifier: string, options?: {
|
|
21
21
|
resolveClientModule?: (specifier: string) => string | undefined;
|
|
@@ -55,21 +55,21 @@ interface DockRendererInstance {
|
|
|
55
55
|
dispose?: () => void;
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
|
-
* A renderer for a dock `type`. The headless hub is renderer-agnostic
|
|
58
|
+
* A renderer for a dock `type`. The headless hub is renderer-agnostic: a
|
|
59
59
|
* host registers renderers at boot (e.g. injecting `@devframes/json-render-ui`
|
|
60
60
|
* for the `'json-render'` type) or serves them as prebuilt modules through the
|
|
61
61
|
* hub's renderer manifest (`initHub({ renderers })`). The renderer owns its
|
|
62
62
|
* framework (Vue, React, …); the hub only routes a dock type to it and
|
|
63
63
|
* disposes it on deactivation.
|
|
64
64
|
*
|
|
65
|
-
* Integration packages narrow `Entry` to export a precisely-typed contract
|
|
65
|
+
* Integration packages narrow `Entry` to export a precisely-typed contract,
|
|
66
66
|
* e.g. `@devframes/json-render/hub` exports
|
|
67
67
|
* `JsonRenderDockRenderer = DockRenderer<DevframeJsonRenderDockEntry>`.
|
|
68
68
|
*/
|
|
69
69
|
type DockRenderer<Entry extends DevframeDockEntry = DevframeDockEntry> = (options: DockRendererMountOptions<Entry>) => DockRendererInstance | Promise<DockRendererInstance>;
|
|
70
70
|
/**
|
|
71
71
|
* The outcome of {@link DockRenderersContext.mount}. A missing renderer is an
|
|
72
|
-
* expected, non-exceptional state
|
|
72
|
+
* expected, non-exceptional state: a viewer renders its "no renderer for this
|
|
73
73
|
* dock type" fallback from `missing-renderer`, and its error variant (with a
|
|
74
74
|
* retry affordance) from `load-error`.
|
|
75
75
|
*/
|
|
@@ -85,8 +85,8 @@ type DockRendererMountResult = {
|
|
|
85
85
|
/**
|
|
86
86
|
* The dock-renderer registry surfaced on the client host context. A viewer
|
|
87
87
|
* calls {@link DockRenderersContext.mount} to render a dock whose `type` has a
|
|
88
|
-
* renderer
|
|
89
|
-
* hub's renderer manifest
|
|
88
|
+
* renderer (registered locally at boot, or served as a prebuilt module by the
|
|
89
|
+
* hub's renderer manifest) into a container it owns; the host tracks the
|
|
90
90
|
* instance and disposes it when the entry deactivates.
|
|
91
91
|
*/
|
|
92
92
|
interface DockRenderersContext {
|
|
@@ -94,13 +94,13 @@ interface DockRenderersContext {
|
|
|
94
94
|
* Register a renderer for a dock `type`. Returns an unregister function.
|
|
95
95
|
* Accepts a renderer narrowed to any specific entry variant (e.g. a
|
|
96
96
|
* {@link DockRenderer}<DevframeJsonRenderDockEntry> from an integration
|
|
97
|
-
* package)
|
|
97
|
+
* package); the type routes only its own entries to it.
|
|
98
98
|
*/
|
|
99
99
|
register: (type: string, renderer: DockRenderer<any>) => () => void;
|
|
100
100
|
/** Look up the locally-registered renderer for a dock `type`, if any. */
|
|
101
101
|
get: (type: string) => DockRenderer | undefined;
|
|
102
102
|
/**
|
|
103
|
-
* Whether a renderer is available for a dock `type
|
|
103
|
+
* Whether a renderer is available for a dock `type`, registered locally
|
|
104
104
|
* **or** provided by the hub's renderer manifest. A viewer checks this
|
|
105
105
|
* before mounting to render its missing-renderer fallback declaratively.
|
|
106
106
|
*/
|
|
@@ -112,14 +112,14 @@ interface DockRenderersContext {
|
|
|
112
112
|
* registered. The mounted instance is also disposed automatically when the
|
|
113
113
|
* entry deactivates. Resolves `missing-renderer` (with a `console.warn`)
|
|
114
114
|
* when neither source has the type, and `load-error` when the module import
|
|
115
|
-
* or the renderer itself fails
|
|
115
|
+
* or the renderer itself fails. A failed import is not cached, so a retry
|
|
116
116
|
* re-imports.
|
|
117
117
|
*/
|
|
118
118
|
mount: (entry: DevframeDockEntry, container: HTMLElement) => Promise<DockRendererMountResult>;
|
|
119
119
|
}
|
|
120
120
|
/**
|
|
121
121
|
* The renderer manifest published by the hub at the
|
|
122
|
-
* `devframe:dock-renderers` shared-state slot
|
|
122
|
+
* `devframe:dock-renderers` shared-state slot: one {@link ClientScriptEntry}
|
|
123
123
|
* per dock `type`, whose `importFrom` is a URL path the hub serves
|
|
124
124
|
* (`<base>__renderers/<type>.mjs`). Mirrors the dock client-script
|
|
125
125
|
* convention: the module's `importName` export (default `'default'`) is a
|
|
@@ -130,20 +130,20 @@ type DockRendererManifest = Record<string, ClientScriptEntry>;
|
|
|
130
130
|
interface CreateDockRenderersContextOptions {
|
|
131
131
|
/** The assembled client context handed to renderers at mount. */
|
|
132
132
|
context: () => DevframeClientContext;
|
|
133
|
-
/** Renderers registered locally at boot
|
|
133
|
+
/** Renderers registered locally at boot; these win over manifest modules. */
|
|
134
134
|
local?: Record<string, DockRenderer<any>>;
|
|
135
135
|
/** The current {@link DockRendererManifest} (live getter). */
|
|
136
136
|
manifest?: () => DockRendererManifest;
|
|
137
137
|
/**
|
|
138
138
|
* Called with each successful mount's disposer so the caller can tie
|
|
139
139
|
* disposal to its own lifecycle (entry deactivation, host teardown). An
|
|
140
|
-
* optional returned cleanup runs exactly once when the mount is disposed
|
|
140
|
+
* optional returned cleanup runs exactly once when the mount is disposed,
|
|
141
141
|
* whichever side (caller or viewer) triggers it first.
|
|
142
142
|
*/
|
|
143
143
|
onMounted?: (dispose: () => void, entry: DevframeDockEntry) => (() => void) | void;
|
|
144
144
|
}
|
|
145
145
|
/**
|
|
146
|
-
* Build the {@link DockRenderersContext} shared by every hub-aware client
|
|
146
|
+
* Build the {@link DockRenderersContext} shared by every hub-aware client.
|
|
147
147
|
* `createDevframeClientRuntime` and hub UI providers that assemble their own context
|
|
148
148
|
* (`@devframes/hub-ui`) both delegate here so local-first resolution, lazy
|
|
149
149
|
* manifest imports, and the typed mount result behave identically everywhere.
|
|
@@ -164,7 +164,7 @@ interface DockPanelStorage {
|
|
|
164
164
|
* Per-tab UI state of the dock panel, distinct from the browser-shared geometry
|
|
165
165
|
* in {@link DockPanelStorage}. A hub UI provider persists this to `sessionStorage` so a
|
|
166
166
|
* reload (or the RPC auth handshake that follows one) restores the panel to
|
|
167
|
-
* exactly where the developer left it
|
|
167
|
+
* exactly where the developer left it: which dock was open, and the
|
|
168
168
|
* address-bar route of that dock's iframe. Kept `sessionStorage`-scoped (not
|
|
169
169
|
* `localStorage`) because it is per-tab navigation state: two tabs open against
|
|
170
170
|
* the same dev server each keep their own selection rather than fighting over a
|
|
@@ -183,7 +183,7 @@ interface DockSessionStorage {
|
|
|
183
183
|
selectedDockRoute: string | null;
|
|
184
184
|
/**
|
|
185
185
|
* The dock entry most recently selected from beyond the float bar's inline
|
|
186
|
-
* capacity
|
|
186
|
+
* capacity, whether from the overflow popover or from inside a dock group. A hub UI
|
|
187
187
|
* provider raises this entry into a dedicated slot between the bar's visible
|
|
188
188
|
* items and the overflow button, so deselecting it (or selecting a visible
|
|
189
189
|
* neighbour) keeps it one click away instead of folding it straight back
|
|
@@ -247,7 +247,7 @@ interface DocksConnectionContext {
|
|
|
247
247
|
/** The most recent connection-level error, or `null` when healthy. */
|
|
248
248
|
readonly error: Error | null;
|
|
249
249
|
/**
|
|
250
|
-
* The client's event emitter
|
|
250
|
+
* The client's event emitter. Subscribe to `connection:status`,
|
|
251
251
|
* `connection:error`, and `rpc:error` to react to changes.
|
|
252
252
|
*/
|
|
253
253
|
readonly events: EventEmitter<RpcClientEvents$1>;
|
|
@@ -270,7 +270,7 @@ interface DocksPanelContext {
|
|
|
270
270
|
readonly events: EventEmitter<DocksPanelEvents>;
|
|
271
271
|
store: DockPanelStorage;
|
|
272
272
|
/**
|
|
273
|
-
* Per-tab session UI state
|
|
273
|
+
* Per-tab session UI state: whether the panel is open, which dock is
|
|
274
274
|
* selected, and that dock's iframe route. Restored across reloads (and the
|
|
275
275
|
* auth handshake that follows one) by a hub UI provider that persists it to
|
|
276
276
|
* `sessionStorage`.
|
|
@@ -282,7 +282,7 @@ interface DocksPanelContext {
|
|
|
282
282
|
/**
|
|
283
283
|
* Claim the persisted {@link DockSessionStorage.selectedDockRoute boot route} for a dock
|
|
284
284
|
* id, once. Returns the saved address-bar URL only for the dock that was
|
|
285
|
-
* selected before the last reload
|
|
285
|
+
* selected before the last reload (and only on the first call for it), so a
|
|
286
286
|
* restored iframe boots deep-linked while a later switch to a different dock
|
|
287
287
|
* (whose live route isn't reflected in {@link DockSessionStorage.selectedDockRoute} yet)
|
|
288
288
|
* doesn't reuse the stale value. Returns `null` otherwise.
|
|
@@ -297,11 +297,11 @@ interface DocksEntriesContext {
|
|
|
297
297
|
entryToStateMap: Map<string, DockEntryState>;
|
|
298
298
|
groupedEntries: DevframeDockEntriesGrouped;
|
|
299
299
|
/**
|
|
300
|
-
* The resolved top-level category ordering
|
|
300
|
+
* The resolved top-level category ordering: `DEFAULT_CATEGORIES_ORDER`,
|
|
301
301
|
* overridden by every installed devframe's own `dock.categoryOrder`
|
|
302
302
|
* (`ConnectionMeta.configs.dock.categoryOrder`), overridden again by the
|
|
303
303
|
* host page's own `createDevframeClientRuntime({ categoryOrder })`. Fixed
|
|
304
|
-
* for the life of the session
|
|
304
|
+
* for the life of the session, resolved once at boot.
|
|
305
305
|
*/
|
|
306
306
|
readonly categoryOrder: Record<string, number>;
|
|
307
307
|
settings: SharedState<DevframeDocksUserSettings>;
|
|
@@ -327,7 +327,7 @@ interface DocksEntriesContext {
|
|
|
327
327
|
* {@link entries}. Unlike a dock registered on the node
|
|
328
328
|
* {@link import('../types/docks').DevframeDocksHost}, it never flows into
|
|
329
329
|
* shared state, so it stays local to this client instead of syncing to the
|
|
330
|
-
* hub or other hub UI providers
|
|
330
|
+
* hub or other hub UI providers, suiting a view the client runtime synthesizes itself.
|
|
331
331
|
*
|
|
332
332
|
* Throws when `id` already names a client dock, unless `force` is set. A
|
|
333
333
|
* client dock sharing an id with a server dock overrides it in the local
|
|
@@ -343,7 +343,7 @@ interface DocksEntriesContext {
|
|
|
343
343
|
}
|
|
344
344
|
interface DockRegistration<T extends DevframeDockEntry = DevframeDockEntry> {
|
|
345
345
|
/**
|
|
346
|
-
* Patch the registered client dock in place. The `id` is immutable
|
|
346
|
+
* Patch the registered client dock in place. The `id` is immutable, so passing
|
|
347
347
|
* a differing `id` throws.
|
|
348
348
|
*/
|
|
349
349
|
update: (patch: Partial<T>) => void;
|
|
@@ -395,6 +395,20 @@ interface CommandsContext {
|
|
|
395
395
|
* Whether the command palette is open
|
|
396
396
|
*/
|
|
397
397
|
paletteOpen: boolean;
|
|
398
|
+
/**
|
|
399
|
+
* The command whose children the palette should open drilled into, or `null`
|
|
400
|
+
* for the root list. Set by {@link CommandsContext.openPalette}; the palette
|
|
401
|
+
* reads it when it opens and clears it when it closes.
|
|
402
|
+
*/
|
|
403
|
+
paletteScopeId: string | null;
|
|
404
|
+
/**
|
|
405
|
+
* Open the command palette, optionally scoped to one command's children:
|
|
406
|
+
* e.g. a dock group with no `defaultChildId` opens the palette listing just
|
|
407
|
+
* that group's members instead of guessing one for the user.
|
|
408
|
+
*
|
|
409
|
+
* Passing no id opens the root list, the same as setting `paletteOpen` true.
|
|
410
|
+
*/
|
|
411
|
+
openPalette: (atCommandId?: string) => void;
|
|
398
412
|
}
|
|
399
413
|
//#endregion
|
|
400
414
|
//#region src/client/client-script.d.ts
|
|
@@ -407,7 +421,7 @@ interface DockClientScriptContext extends DocksContext {
|
|
|
407
421
|
*/
|
|
408
422
|
current: DockEntryState;
|
|
409
423
|
/**
|
|
410
|
-
* Messages client scoped to this dock entry
|
|
424
|
+
* Messages client scoped to this dock entry. Messages it adds default
|
|
411
425
|
* their `category` to the entry id, so the feed can attribute them.
|
|
412
426
|
*/
|
|
413
427
|
messages: DevframeMessagesClient;
|
|
@@ -440,8 +454,8 @@ declare function resolveDockIcon(icon: DevframeDockEntryIcon, connection: Devfra
|
|
|
440
454
|
/**
|
|
441
455
|
* Live location tracking for an iframe dock.
|
|
442
456
|
*
|
|
443
|
-
* An iframe dock's address bar
|
|
444
|
-
* `DockSessionStorage.selectedDockRoute`
|
|
457
|
+
* An iframe dock's address bar (and the route persisted from it into
|
|
458
|
+
* `DockSessionStorage.selectedDockRoute`) has to follow wherever the embedded
|
|
445
459
|
* app actually goes. The `load` event only covers whole-document navigations, so
|
|
446
460
|
* an SPA router moving between routes with `history.pushState()` leaves both
|
|
447
461
|
* showing the URL the frame booted with.
|
|
@@ -449,21 +463,21 @@ declare function resolveDockIcon(icon: DevframeDockEntryIcon, connection: Devfra
|
|
|
449
463
|
* {@link watchFrameLocation} closes that gap for a same-origin frame, reporting
|
|
450
464
|
* `location.href` on every navigation it can observe:
|
|
451
465
|
*
|
|
452
|
-
* - `popstate` / `hashchange
|
|
466
|
+
* - `popstate` / `hashchange`: back/forward and hash routing;
|
|
453
467
|
* - `history.pushState`/`replaceState`, wrapped in place (and restored on
|
|
454
468
|
* dispose) because those two fire no event of their own;
|
|
455
469
|
* - the [Navigation API](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API)'s
|
|
456
470
|
* `currententrychange` where it exists, which reports post-commit and so also
|
|
457
|
-
* catches what a wrapper structurally cannot
|
|
471
|
+
* catches what a wrapper structurally cannot: a router holding a reference to
|
|
458
472
|
* `pushState` captured before this watch attached;
|
|
459
473
|
* - `load`, which also re-subscribes: a document navigation swaps the frame's
|
|
460
474
|
* `history`/`navigation` objects, so the previous subscription dies with them.
|
|
461
475
|
*
|
|
462
476
|
* These sources overlap deliberately rather than being chosen between, since a
|
|
463
|
-
* report is deduped against the last href
|
|
477
|
+
* report is deduped against the last href, so the cost of hearing the same
|
|
464
478
|
* navigation twice is nothing, and the cost of missing one is a stale route.
|
|
465
479
|
*
|
|
466
|
-
* A cross-origin frame reports nothing
|
|
480
|
+
* A cross-origin frame reports nothing, because its location is unreadable by design,
|
|
467
481
|
* so the caller keeps the last URL it knew.
|
|
468
482
|
*/
|
|
469
483
|
/** The minimal `history` surface the watcher wraps. Injectable for tests. */
|
|
@@ -511,7 +525,7 @@ declare function watchFrameLocation(options: WatchFrameLocationOptions): () => v
|
|
|
511
525
|
//#endregion
|
|
512
526
|
//#region src/client/frame-nav.d.ts
|
|
513
527
|
/**
|
|
514
|
-
* Shared-iframe soft navigation
|
|
528
|
+
* Shared-iframe soft navigation: the hub-UI-provider-side half of a host-page↔iframe
|
|
515
529
|
* `postMessage` protocol.
|
|
516
530
|
*
|
|
517
531
|
* An {@link DevframeViewIframe.subTabs anchor} iframe dock owns one live iframe
|
|
@@ -527,7 +541,7 @@ declare function watchFrameLocation(options: WatchFrameLocationOptions): () => v
|
|
|
527
541
|
* highlight to match.
|
|
528
542
|
*
|
|
529
543
|
* The protocol is server-free (works cross-origin and in static builds) and
|
|
530
|
-
* decoupled
|
|
544
|
+
* decoupled, so the embedded app takes no hub/RPC dependency, only the shim.
|
|
531
545
|
*/
|
|
532
546
|
/** `postMessage` channel tag shared by both halves of the protocol. */
|
|
533
547
|
declare const FRAME_NAV_CHANNEL: string;
|
|
@@ -600,11 +614,11 @@ interface FrameNavListenTarget {
|
|
|
600
614
|
interface FrameNavClientOptions {
|
|
601
615
|
/** The shared frame id (defaults to the anchor's, else the anchor id). */
|
|
602
616
|
frameId: string;
|
|
603
|
-
/** The anchor iframe dock entry
|
|
617
|
+
/** The anchor iframe dock entry, supplying url/icon/groupId defaults. */
|
|
604
618
|
anchor: DevframeViewIframe;
|
|
605
619
|
/** The live iframe element hosting the embedded app. */
|
|
606
620
|
iframe: Pick<HTMLIFrameElement, 'contentWindow' | 'src'>;
|
|
607
|
-
/** Client docks context
|
|
621
|
+
/** Client docks context, used to register members and drive selection. */
|
|
608
622
|
docks: Pick<DocksEntriesContext, 'register' | 'switchEntry' | 'getStateById'>;
|
|
609
623
|
/**
|
|
610
624
|
* Window to receive the frame's `message` events on (the host page window).
|
|
@@ -634,7 +648,7 @@ declare function attachFrameNavClient(options: FrameNavClientOptions): FrameNavC
|
|
|
634
648
|
interface DevframeClientRuntimeOptions {
|
|
635
649
|
/**
|
|
636
650
|
* An already-connected RPC client. When omitted, one is created via
|
|
637
|
-
* `connectDevframe(connect)
|
|
651
|
+
* `connectDevframe(connect)`, so pass `connect.baseURL` to point at the hub's
|
|
638
652
|
* connection-meta mount (e.g. `/__hub/`).
|
|
639
653
|
*/
|
|
640
654
|
rpc?: DevframeRpcClient;
|
|
@@ -642,8 +656,8 @@ interface DevframeClientRuntimeOptions {
|
|
|
642
656
|
connect?: DevframeRpcClientOptions;
|
|
643
657
|
/**
|
|
644
658
|
* Environment the host runs in.
|
|
645
|
-
* - `'standalone'` (default)
|
|
646
|
-
* - `'embedded'
|
|
659
|
+
* - `'standalone'` (default): the runtime owns the whole page (a hub UI).
|
|
660
|
+
* - `'embedded'`: the runtime lives inside a user app alongside a panel.
|
|
647
661
|
*/
|
|
648
662
|
clientType?: DockClientType;
|
|
649
663
|
/**
|
|
@@ -653,7 +667,7 @@ interface DevframeClientRuntimeOptions {
|
|
|
653
667
|
loadClientScripts?: boolean;
|
|
654
668
|
/**
|
|
655
669
|
* Resolve a **bare-specifier** client script (`importFrom` naming an npm
|
|
656
|
-
* module) to a URL this page can import
|
|
670
|
+
* module) to a URL this page can import, a hub UI provider's own policy that wins
|
|
657
671
|
* over the host-advertised `ConnectionMeta.configs.dock.clientModuleResolution`
|
|
658
672
|
* template (return `undefined` to fall through to it). URL specifiers never
|
|
659
673
|
* reach this hook. E.g. on a Vite-served page:
|
|
@@ -667,11 +681,11 @@ interface DevframeClientRuntimeOptions {
|
|
|
667
681
|
* `@devframes/json-render-ui`). The hub ships none by default.
|
|
668
682
|
*
|
|
669
683
|
* Local registrations take precedence over the hub's renderer manifest
|
|
670
|
-
* (`initHub({ renderers })`)
|
|
684
|
+
* (`initHub({ renderers })`), since explicit local code beats wire config.
|
|
671
685
|
*/
|
|
672
686
|
renderers?: Record<string, DockRenderer<any>>;
|
|
673
687
|
/**
|
|
674
|
-
* Hub-wide override of the top-level dock-bar category ordering
|
|
688
|
+
* Hub-wide override of the top-level dock-bar category ordering: a map of
|
|
675
689
|
* category id → ordering weight (lower sorts earlier), mirroring the shape
|
|
676
690
|
* of {@link import('../constants').DEFAULT_CATEGORIES_ORDER}.
|
|
677
691
|
*
|
|
@@ -703,24 +717,24 @@ interface DevframeClientRuntime {
|
|
|
703
717
|
* Boot the client runtime: connect RPC, assemble the full
|
|
704
718
|
* {@link DevframeClientContext} (panel, docks, commands, when) from the hub's
|
|
705
719
|
* shared state, publish it at `__DEVFRAME_HUB_CLIENT_CONTEXT__`, and load every
|
|
706
|
-
* dock entry's client script into this page
|
|
720
|
+
* dock entry's client script into this page, the devframe equivalent of the
|
|
707
721
|
* runtime `@vitejs/devtools-kit` injects into a host app.
|
|
708
722
|
*
|
|
709
723
|
* A hub UI provider keeps rendering its own dock UI (reading the same shared state); this
|
|
710
724
|
* runtime is what gives plugin client scripts a live host context to run in.
|
|
711
725
|
*/
|
|
712
726
|
declare function createDevframeClientRuntime(options?: DevframeClientRuntimeOptions): Promise<DevframeClientRuntime>;
|
|
713
|
-
/** @deprecated Renamed
|
|
727
|
+
/** @deprecated Renamed; use {@link DevframeClientRuntimeOptions}. */
|
|
714
728
|
type DevframeClientHostOptions = DevframeClientRuntimeOptions;
|
|
715
|
-
/** @deprecated Renamed
|
|
729
|
+
/** @deprecated Renamed; use {@link DevframeClientRuntime}. */
|
|
716
730
|
type DevframeClientHost = DevframeClientRuntime;
|
|
717
|
-
/** @deprecated Renamed
|
|
731
|
+
/** @deprecated Renamed; use {@link createDevframeClientRuntime}. */
|
|
718
732
|
declare const createDevframeClientHost: typeof createDevframeClientRuntime;
|
|
719
733
|
//#endregion
|
|
720
734
|
//#region src/client/messages.d.ts
|
|
721
735
|
interface MessagesClientOptions {
|
|
722
736
|
/**
|
|
723
|
-
* Default fields merged beneath every `add()` input
|
|
737
|
+
* Default fields merged beneath every `add()` input. The client host passes
|
|
724
738
|
* `{ category: entry.id }` to scope a dock client script's messages to its
|
|
725
739
|
* entry. Fields set on the input itself win.
|
|
726
740
|
*/
|
|
@@ -759,7 +773,7 @@ declare function parseRemoteConnection(input?: string): RemoteConnectionInfo | n
|
|
|
759
773
|
* the current URL and returns a connected {@link DevframeRpcClient}.
|
|
760
774
|
*
|
|
761
775
|
* Pairs with `remote: true` on a `DevframeViewIframe` registered on the node
|
|
762
|
-
* side
|
|
776
|
+
* side, where the hub injects the descriptor into the iframe URL.
|
|
763
777
|
*
|
|
764
778
|
* @throws if no descriptor is present in the URL.
|
|
765
779
|
*/
|