@devframes/vite 0.9.8 → 0.9.9

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.
@@ -10,7 +10,7 @@ interface MountDevframeHubClientOptions extends DevframeClientRuntimeOptions$1 {
10
10
  base?: string;
11
11
  }
12
12
  /**
13
- * Boot the devframes-hub **client runtime** in the host page — the browser
13
+ * Boot the devframes-hub **client runtime** in the host page: the browser
14
14
  * half of {@link import('./hub').viteDevframeHub}. Connects RPC to the hub
15
15
  * (defaulting `base` to `/__devframes/`), assembles the shared
16
16
  * `DevframeClientContext`, and imports each dock's client script into the
@@ -2,7 +2,7 @@ import { createDevframeClientRuntime } from "@devframes/hub/client";
2
2
  import { DEVFRAMES_HUB_BASE } from "@devframes/hub/constants";
3
3
  //#region src/hub-client.ts
4
4
  /**
5
- * Boot the devframes-hub **client runtime** in the host page — the browser
5
+ * Boot the devframes-hub **client runtime** in the host page: the browser
6
6
  * half of {@link import('./hub').viteDevframeHub}. Connects RPC to the hub
7
7
  * (defaulting `base` to `/__devframes/`), assembles the shared
8
8
  * `DevframeClientContext`, and imports each dock's client script into the
package/dist/hub.d.mts CHANGED
@@ -5,7 +5,7 @@ import { Plugin } from "vite";
5
5
  //#region src/hub.d.ts
6
6
  interface ViteDevframeHubOptions {
7
7
  /**
8
- * Mount base the hub answers under — every frame lives at `<base><id>/`.
8
+ * Mount base the hub answers under; every frame lives at `<base><id>/`.
9
9
  * Default: `/__devframes/`.
10
10
  */
11
11
  base?: string;
@@ -28,7 +28,7 @@ interface ViteDevframeHubOptions {
28
28
  */
29
29
  clientScripts?: Record<string, ClientScriptEntry>;
30
30
  /**
31
- * Prebuilt dock-renderer modules forwarded to `initHub({ renderers })` —
31
+ * Prebuilt dock-renderer modules forwarded to `initHub({ renderers })`,
32
32
  * each served at `<base>__renderers/<type>.mjs` and published in the
33
33
  * renderer manifest (e.g. `jsonRenderUiRenderer()` from
34
34
  * `@devframes/json-render-ui/hub`).
@@ -40,13 +40,13 @@ interface ViteDevframeHubOptions {
40
40
  */
41
41
  rpcDeclarations?: InitHubOptions['rpcDeclarations'];
42
42
  /**
43
- * Runs once the context exists and every `devframes` entry is mounted —
43
+ * Runs once the context exists and every `devframes` entry is mounted;
44
44
  * register docks, commands, terminals, and messages surfaces here.
45
45
  */
46
46
  configure?: (ctx: DevframeHubContext) => void | Promise<void>;
47
47
  /**
48
48
  * The hub's UI slot. Defaults to `@devframes/hub-ui`'s `createUi()` (the
49
- * reference floating dock + standalone viewer) when omitted — install
49
+ * reference floating dock + standalone viewer) when omitted, so install
50
50
  * `@devframes/hub-ui` for that default. Pass your own {@link DevframeHubUi}
51
51
  * to swap the hub UI provider, or `false` for a headless hub (serve your own UI
52
52
  * against `@devframes/hub/client`).
@@ -81,8 +81,8 @@ interface ViteDevframeHubOptions {
81
81
  quiet?: boolean;
82
82
  }
83
83
  /**
84
- * Mount a whole **devframes-hub** — many integrations under one namespace,
85
- * one merged RPC registry, one WebSocket — inside an existing Vite dev
84
+ * Mount a whole **devframes-hub** (many integrations under one namespace,
85
+ * one merged RPC registry, one WebSocket) inside an existing Vite dev
86
86
  * server. One `initHub()` call, mounted as connect middleware; the WebSocket
87
87
  * shares Vite's own HTTP server (upgrading at `<base>__ws`) unless a `port`
88
88
  * pins a side-car. The UI defaults to `@devframes/hub-ui` (its `embedded.js`
package/dist/hub.mjs CHANGED
@@ -7,11 +7,11 @@ let recommendedViteDevtools = false;
7
7
  function recommendViteDevtools() {
8
8
  if (recommendedViteDevtools) return;
9
9
  recommendedViteDevtools = true;
10
- console.warn("[@devframes/vite/hub] Serving a devframes-hub directly inside Vite works, but Vite DevTools (`@vitejs/devtools-kit`) integrates the hub protocol natively — prefer it for a first-class, multi-integration experience. Pass `{ quiet: true }` to silence this notice.");
10
+ console.warn("[@devframes/vite/hub] Serving a devframes-hub directly inside Vite works, but Vite DevTools (`@vitejs/devtools-kit`) integrates the hub protocol natively, so prefer it for a first-class, multi-integration experience. Pass `{ quiet: true }` to silence this notice.");
11
11
  }
12
12
  /**
13
- * Mount a whole **devframes-hub** — many integrations under one namespace,
14
- * one merged RPC registry, one WebSocket — inside an existing Vite dev
13
+ * Mount a whole **devframes-hub** (many integrations under one namespace,
14
+ * one merged RPC registry, one WebSocket) inside an existing Vite dev
15
15
  * server. One `initHub()` call, mounted as connect middleware; the WebSocket
16
16
  * shares Vite's own HTTP server (upgrading at `<base>__ws`) unless a `port`
17
17
  * pins a side-car. The UI defaults to `@devframes/hub-ui` (its `embedded.js`
@@ -50,25 +50,38 @@ function viteDevframeHub(options = {}) {
50
50
  const hub = initHub({
51
51
  base,
52
52
  cwd,
53
+ /**
54
+ * Bare-specifier client scripts resolve through Vite's own module
55
+ * graph: `/@id/<specifier>` routes the import (and its transitive
56
+ * bare imports) through Vite's resolution and import-analysis.
57
+ */
53
58
  clientModuleResolution: "/@id/{specifier}",
54
59
  origin: options.origin ?? (() => {
55
60
  const resolved = server.resolvedUrls?.local?.[0];
56
61
  return resolved ? new URL(resolved).origin : "";
57
62
  }),
58
63
  auth: options.auth,
64
+ /**
65
+ * Share Vite's own HTTP server for the WS upgrade at `<base>__ws`, with no
66
+ * side-car port to discover. A pinned `port` uses a side-car instead;
67
+ * an https/http2 dev server (non-`node:http`) asks for an auto-port
68
+ * side-car. Clients discover either via `__connection.json`.
69
+ */
59
70
  server: httpServer,
60
- ...options.port != null ? { ws: { port: options.port } } : httpServer ? {} : { ws: { sidecar: true } },
61
- ...options.host != null ? { host: options.host } : {},
71
+ ...resolveWsBinding(options.port, httpServer),
62
72
  ...ui ? { ui } : {},
63
- ...options.renderers ? { renderers: options.renderers } : {},
64
- ...options.rpcDeclarations ? { rpcDeclarations: options.rpcDeclarations } : {},
65
- ...options.mcp != null ? { mcp: options.mcp } : {},
66
- ...options.register != null ? { register: options.register } : {},
67
- ...options.getStorageDir ? { getStorageDir: options.getStorageDir } : {},
68
- ...options.name != null ? { name: options.name } : {},
69
- ...options.version != null ? { version: options.version } : {},
70
73
  devframes,
71
- ...options.configure ? { configure: options.configure } : {}
74
+ ...pickDefined(options, [
75
+ "host",
76
+ "renderers",
77
+ "rpcDeclarations",
78
+ "mcp",
79
+ "register",
80
+ "getStorageDir",
81
+ "name",
82
+ "version",
83
+ "configure"
84
+ ])
72
85
  });
73
86
  instance = hub;
74
87
  embeddedSrc = ui?.embedded ? `${base}embedded.js` : void 0;
@@ -94,6 +107,24 @@ function viteDevframeHub(options = {}) {
94
107
  }
95
108
  };
96
109
  }
110
+ /**
111
+ * Share Vite's own HTTP server for the WS upgrade unless a `port` pins a
112
+ * side-car, or the dev server isn't a plain `node:http` server (https/http2),
113
+ * which needs an auto-port side-car.
114
+ */
115
+ function resolveWsBinding(port, httpServer) {
116
+ if (port != null) return { ws: { port } };
117
+ return httpServer ? {} : { ws: { sidecar: true } };
118
+ }
119
+ /** Forward only the options a caller actually set. */
120
+ function pickDefined(source, keys) {
121
+ const out = {};
122
+ for (const key of keys) {
123
+ const value = source[key];
124
+ if (value != null) out[key] = value;
125
+ }
126
+ return out;
127
+ }
97
128
  /** Lazy-load `@devframes/hub-ui`'s default UI so it stays an optional dep. */
98
129
  async function loadDefaultUi() {
99
130
  const { createUi } = await import("@devframes/hub-ui");
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region src/index.ts
2
- throw new Error("[@devframes/vite] has no root export. Import from a scoped subpath instead:\n • \"@devframes/vite/single\" — dev-serve one devframe's SPA with Vite\n • \"@devframes/vite/hub\" — mount a devframes-hub inside a Vite app\n");
2
+ throw new Error("[@devframes/vite] has no root export. Import from a scoped subpath instead:\n • \"@devframes/vite/single\": dev-serve one devframe's SPA with Vite\n • \"@devframes/vite/hub\": mount a devframes-hub inside a Vite app\n");
3
3
  //#endregion
4
4
  export {};
package/dist/single.d.mts CHANGED
@@ -4,7 +4,7 @@ import { DevframeDefinition, McpRouteOptions } from "devframe";
4
4
  import { DevframeAuthHandler } from "devframe/node/auth";
5
5
  //#region src/single.d.ts
6
6
  /**
7
- * The slice of a Vite dev server these plugins touch — deliberately
7
+ * The slice of a Vite dev server these plugins touch, deliberately
8
8
  * narrower than Vite's real `ViteDevServer` (which carries the module
9
9
  * graph, watcher, transform pipeline, …) so a host can hand a plugin
10
10
  * anything shaped like this, and a test double only needs to fake two
@@ -18,7 +18,7 @@ interface DevframeViteDevServerLike {
18
18
  };
19
19
  /**
20
20
  * Deliberately structural (just the one event these plugins listen for)
21
- * rather than `NodeHttpServer` — Vite's real `ViteDevServer.httpServer`
21
+ * rather than `NodeHttpServer`: Vite's real `ViteDevServer.httpServer`
22
22
  * is `http.Server | Http2SecureServer | null`, and `Http2SecureServer`
23
23
  * doesn't satisfy `http.Server`'s full shape.
24
24
  */
@@ -26,12 +26,12 @@ interface DevframeViteDevServerLike {
26
26
  once: (event: 'close', listener: () => void) => unknown;
27
27
  } | null;
28
28
  }
29
- /** A devframe Vite plugin — a real Vite `Plugin`, scoped to its `serve`-only hooks. */
29
+ /** A devframe Vite plugin: a real Vite `Plugin`, scoped to its `serve`-only hooks. */
30
30
  type DevframeVitePlugin = Plugin;
31
31
  interface DevframeVitePluginOptions {
32
32
  /**
33
33
  * Mount base. Defaults to `def.basePath ?? '/__<id>/'` for this hosted
34
- * adapter — the devframe shares the origin with the host Vite app.
34
+ * adapter, so the devframe shares the origin with the host Vite app.
35
35
  *
36
36
  * Relative spellings like `'./'` (common for base-agnostic Nuxt builds)
37
37
  * are normalized to absolute paths so they compose with Vite's connect
@@ -42,7 +42,7 @@ interface DevframeVitePluginOptions {
42
42
  /**
43
43
  * Statically mount a devframe's built SPA (`def.clientAssets`) at
44
44
  * `options.base` inside an existing Vite dev server. No RPC server is
45
- * started — reach for {@link devframeViteBridge} when the mounted UI
45
+ * started; reach for {@link devframeViteBridge} when the mounted UI
46
46
  * needs a live RPC/WebSocket connection back to the devframe.
47
47
  *
48
48
  * Use this when the devframe ships its own pre-built UI and the host
@@ -54,7 +54,7 @@ declare function devframeVitePlugin(d: DevframeDefinition, options?: DevframeVit
54
54
  interface DevframeViteBridgeOptions {
55
55
  /**
56
56
  * Mount base. Defaults to `def.basePath ?? '/__<id>/'` for this hosted
57
- * adapter — the devframe shares the origin with the host Vite app.
57
+ * adapter, so the devframe shares the origin with the host Vite app.
58
58
  *
59
59
  * Relative spellings like `'./'` (common for base-agnostic Nuxt builds)
60
60
  * are normalized to absolute paths so they compose with Vite's connect
@@ -86,7 +86,7 @@ interface DevframeViteBridgeOptions {
86
86
  auth?: boolean | DevframeAuthHandler;
87
87
  /**
88
88
  * Expose the bridge's route-based MCP server (Streamable-HTTP) at
89
- * `<base>__mcp` — on the Vite app's own origin — and advertise it in the
89
+ * `<base>__mcp` (on the Vite app's own origin) and advertise it in the
90
90
  * bridge's `__connection.json`. Overrides `def.cli?.mcp`, `undefined`
91
91
  * falls through to it, `false` disables the route regardless.
92
92
  */
@@ -97,7 +97,7 @@ interface DevframeViteBridgeOptions {
97
97
  * server: the host app owns the SPA (`clientAssets` is never mounted), and this
98
98
  * plugin serves discovery (`<base>__connection.json`), the WebSocket RPC
99
99
  * upgrade (`<base>__ws`, shared on Vite's own HTTP server), and the
100
- * optional MCP route through {@link initDevframe}'s node middleware — so
100
+ * optional MCP route through {@link initDevframe}'s node middleware, so
101
101
  * the host-served SPA can discover the endpoint via `connectDevframe`.
102
102
  *
103
103
  * The bridge **gates by default** (devframe's interactive OTP unless the
package/dist/single.mjs CHANGED
@@ -8,7 +8,7 @@ import { join, resolve } from "pathe";
8
8
  /**
9
9
  * Statically mount a devframe's built SPA (`def.clientAssets`) at
10
10
  * `options.base` inside an existing Vite dev server. No RPC server is
11
- * started — reach for {@link devframeViteBridge} when the mounted UI
11
+ * started; reach for {@link devframeViteBridge} when the mounted UI
12
12
  * needs a live RPC/WebSocket connection back to the devframe.
13
13
  *
14
14
  * Use this when the devframe ships its own pre-built UI and the host
@@ -34,7 +34,7 @@ function devframeVitePlugin(d, options = {}) {
34
34
  * server: the host app owns the SPA (`clientAssets` is never mounted), and this
35
35
  * plugin serves discovery (`<base>__connection.json`), the WebSocket RPC
36
36
  * upgrade (`<base>__ws`, shared on Vite's own HTTP server), and the
37
- * optional MCP route through {@link initDevframe}'s node middleware — so
37
+ * optional MCP route through {@link initDevframe}'s node middleware, so
38
38
  * the host-served SPA can discover the endpoint via `connectDevframe`.
39
39
  *
40
40
  * The bridge **gates by default** (devframe's interactive OTP unless the
@@ -62,10 +62,19 @@ function devframeViteBridge(d, options = {}) {
62
62
  try {
63
63
  const created = initDevframe(d, {
64
64
  base,
65
+ /**
66
+ * The host app owns the SPA in bridge mode, so never mount the
67
+ * definition's own client assets here.
68
+ */
65
69
  distDir: false,
66
70
  flags: options.flags,
67
71
  host: options.host,
68
72
  ...options.port != null ? { ws: { port: options.port } } : server.httpServer ? { server: server.httpServer } : { ws: { sidecar: true } },
73
+ /**
74
+ * Gate by default: an unset `auth` defers to the handler
75
+ * (devframe's interactive OTP unless `cli.auth` opts out) rather
76
+ * than leaving the socket ungated. `false` opts out explicitly.
77
+ */
69
78
  auth: options.auth,
70
79
  mcp: options.mcp
71
80
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@devframes/vite",
3
3
  "type": "module",
4
- "version": "0.9.8",
4
+ "version": "0.9.9",
5
5
  "description": "Vite plugin for mounting a devframe inside any Vite-based host (Astro, SolidStart, Nuxt, plain Vite apps).",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -30,9 +30,9 @@
30
30
  "dist"
31
31
  ],
32
32
  "peerDependencies": {
33
- "@devframes/hub": "0.9.8",
34
- "@devframes/hub-ui": "0.9.8",
35
- "devframe": "0.9.8",
33
+ "@devframes/hub": "0.9.9",
34
+ "@devframes/hub-ui": "0.9.9",
35
+ "devframe": "0.9.9",
36
36
  "vite": "^7.0.0 || ^8.0.0"
37
37
  },
38
38
  "peerDependenciesMeta": {
@@ -50,11 +50,11 @@
50
50
  "pathe": "^2.0.3"
51
51
  },
52
52
  "devDependencies": {
53
- "@devframes/hub": "0.9.8",
54
- "@devframes/hub-ui": "0.9.8",
53
+ "@devframes/hub": "0.9.9",
54
+ "@devframes/hub-ui": "0.9.9",
55
55
  "@modelcontextprotocol/client": "^2.0.0",
56
56
  "@types/node": "^26.4.0",
57
- "devframe": "0.9.8",
57
+ "devframe": "0.9.9",
58
58
  "get-port-please": "^3.2.0",
59
59
  "tsdown": "^0.22.14",
60
60
  "vite": "^8.2.2",