@devframes/next 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.
- package/dist/client.d.mts +3 -3
- package/dist/client.mjs +2 -2
- package/dist/hub-client.d.mts +1 -1
- package/dist/hub-client.mjs +1 -1
- package/dist/hub.d.mts +25 -13
- package/dist/hub.mjs +8 -5
- package/dist/index.mjs +1 -1
- package/dist/single.d.mts +4 -4
- package/dist/single.mjs +10 -1
- package/package.json +7 -7
package/dist/client.d.mts
CHANGED
|
@@ -5,7 +5,7 @@ import { ConnectionMeta } from "devframe";
|
|
|
5
5
|
interface DevframeRpcState {
|
|
6
6
|
/** The connected client, or `null` while the initial connect is in flight. */
|
|
7
7
|
rpc: DevframeRpcClient | null;
|
|
8
|
-
/** Live connection status
|
|
8
|
+
/** Live connection status, `'connecting'` until the client resolves. */
|
|
9
9
|
status: DevframeConnectionStatus;
|
|
10
10
|
/** The latest connection error, or `null`. */
|
|
11
11
|
error: Error | null;
|
|
@@ -25,8 +25,8 @@ interface RpcProviderProps {
|
|
|
25
25
|
connectionMeta?: ConnectionMeta;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* Connect to the devframe RPC backend once and provide the client
|
|
29
|
-
* connection status
|
|
28
|
+
* Connect to the devframe RPC backend once and provide the client, plus live
|
|
29
|
+
* connection status, to the tree. The React counterpart to `@devframes/nuxt`'s
|
|
30
30
|
* client plugin.
|
|
31
31
|
*
|
|
32
32
|
* Children render immediately (before the connection resolves), so your shell
|
package/dist/client.mjs
CHANGED
|
@@ -10,8 +10,8 @@ const INITIAL = {
|
|
|
10
10
|
error: null
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
* Connect to the devframe RPC backend once and provide the client
|
|
14
|
-
* connection status
|
|
13
|
+
* Connect to the devframe RPC backend once and provide the client, plus live
|
|
14
|
+
* connection status, to the tree. The React counterpart to `@devframes/nuxt`'s
|
|
15
15
|
* client plugin.
|
|
16
16
|
*
|
|
17
17
|
* Children render immediately (before the connection resolves), so your shell
|
package/dist/hub-client.d.mts
CHANGED
|
@@ -10,7 +10,7 @@ interface UseDevframeHubClientOptions extends DevframeClientRuntimeOptions$1 {
|
|
|
10
10
|
base?: string;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Boot the devframes-hub **client runtime** inside a React (Next.js) page
|
|
13
|
+
* Boot the devframes-hub **client runtime** inside a React (Next.js) page:
|
|
14
14
|
* the browser half of {@link import('./hub').nextDevframeHub}. Connects RPC to
|
|
15
15
|
* the hub (defaulting `base` to `/__devframes/`), assembles the shared
|
|
16
16
|
* `DevframeClientContext`, imports each dock's client script into the page,
|
package/dist/hub-client.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { createDevframeClientRuntime } from "@devframes/hub/client";
|
|
|
4
4
|
import { DEVFRAMES_HUB_BASE } from "@devframes/hub/constants";
|
|
5
5
|
//#region src/hub-client.tsx
|
|
6
6
|
/**
|
|
7
|
-
* Boot the devframes-hub **client runtime** inside a React (Next.js) page
|
|
7
|
+
* Boot the devframes-hub **client runtime** inside a React (Next.js) page:
|
|
8
8
|
* the browser half of {@link import('./hub').nextDevframeHub}. Connects RPC to
|
|
9
9
|
* the hub (defaulting `base` to `/__devframes/`), assembles the shared
|
|
10
10
|
* `DevframeClientContext`, imports each dock's client script into the page,
|
package/dist/hub.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DevframeHubUi, HubInstance, InitHubOptions } from "@devframes/hub/initiate";
|
|
2
|
-
import { ConnectionMeta, DevframeHost, DevframeNodeContext, DevframeStorageScope } from "devframe";
|
|
2
|
+
import { ConnectionMeta, DevframeHost, DevframeNodeContext, DevframeStorageScope, McpAuthorization } from "devframe";
|
|
3
3
|
//#region src/host.d.ts
|
|
4
4
|
interface CreateDevframeNextHostOptions {
|
|
5
5
|
/**
|
|
@@ -16,12 +16,21 @@ interface CreateDevframeNextHostOptions {
|
|
|
16
16
|
/**
|
|
17
17
|
* Initial connection meta served at every base registered via
|
|
18
18
|
* {@link DevframeHost.mountConnectionMeta}. Usually unknown until the
|
|
19
|
-
* side-car RPC/WS server has started
|
|
19
|
+
* side-car RPC/WS server has started, so publish it later with
|
|
20
20
|
* {@link DevframeNextHost.setConnectionMeta}.
|
|
21
21
|
*/
|
|
22
22
|
connectionMeta?: ConnectionMeta;
|
|
23
23
|
}
|
|
24
24
|
interface DevframeNextHostMcpOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Optional identity check layered on the origin gate. Defaults to
|
|
27
|
+
* origin-only (`false`), trusting same-machine callers. A bearer token
|
|
28
|
+
* string (matched in constant time) or a `(request) => boolean` callback
|
|
29
|
+
* hardens the route when a same-machine process is not your trust boundary;
|
|
30
|
+
* see {@link McpAuthorization}. Back a bearer with an environment variable,
|
|
31
|
+
* never a literal.
|
|
32
|
+
*/
|
|
33
|
+
authorization?: McpAuthorization;
|
|
25
34
|
/** Name reported in the MCP handshake. Default: `'devframe (next)'`. */
|
|
26
35
|
serverName?: string;
|
|
27
36
|
/** Version reported in the MCP handshake. Default: `'0.0.0'`. */
|
|
@@ -31,7 +40,8 @@ interface DevframeNextHostMcpOptions {
|
|
|
31
40
|
/**
|
|
32
41
|
* Origin allow-list beyond the loopback default. `false` disables the
|
|
33
42
|
* origin gate entirely. Note the MCP route rejects `Origin`-less requests
|
|
34
|
-
* (see `createMcpFetchHandler`).
|
|
43
|
+
* (see `createMcpFetchHandler`). This hardens the request; `authorization`
|
|
44
|
+
* proves identity.
|
|
35
45
|
*/
|
|
36
46
|
allowedOrigins?: readonly string[] | false;
|
|
37
47
|
}
|
|
@@ -44,7 +54,7 @@ interface DevframeNextHost {
|
|
|
44
54
|
host: DevframeHost;
|
|
45
55
|
/**
|
|
46
56
|
* A WHATWG-`fetch` handler that serves every mounted SPA (with SPA
|
|
47
|
-
* fallback, correct content types, and path-traversal guarding
|
|
57
|
+
* fallback, correct content types, and path-traversal guarding, all from
|
|
48
58
|
* devframe's own `serveStaticHandler`) and answers `<base>/__connection.json`
|
|
49
59
|
* for each base registered via `mountConnectionMeta`. Delegate a Next App
|
|
50
60
|
* Router route handler straight to it:
|
|
@@ -63,12 +73,12 @@ interface DevframeNextHost {
|
|
|
63
73
|
*/
|
|
64
74
|
setConnectionMeta: (meta: ConnectionMeta) => void;
|
|
65
75
|
/**
|
|
66
|
-
* Serve an MCP Streamable-HTTP endpoint at `path` **in-process
|
|
76
|
+
* Serve an MCP Streamable-HTTP endpoint at `path` **in-process**, on the
|
|
67
77
|
* Next app's own origin, through the same catch-all route as the SPAs (the
|
|
68
78
|
* `/_next/mcp` shape). Built on `createMcpFetchHandler` from
|
|
69
79
|
* `devframe/adapters/mcp` (imported lazily: `@modelcontextprotocol/server`
|
|
70
80
|
* stays an optional peer). Advertise the path in the connection meta
|
|
71
|
-
* (`mcp: { path }
|
|
81
|
+
* (`mcp: { path }`, same origin, no port) and register the instance via
|
|
72
82
|
* `registerDevframeInstance` so `devframe connect` can discover it.
|
|
73
83
|
*/
|
|
74
84
|
mountMcp: (ctx: DevframeNodeContext, path: string, options?: DevframeNextHostMcpOptions) => Promise<{
|
|
@@ -81,7 +91,7 @@ interface DevframeNextHost {
|
|
|
81
91
|
* route delegates to.
|
|
82
92
|
*
|
|
83
93
|
* This is the hosted-adapter counterpart to `devframeViteBridge` for the Next
|
|
84
|
-
* runtime, which
|
|
94
|
+
* runtime, which (being webpack/Turbopack rather than Vite) can't reuse the
|
|
85
95
|
* Vite middleware path. Instead of hand-rolling static serving in a route
|
|
86
96
|
* handler, static mounts are registered on an internal h3 app and served
|
|
87
97
|
* through devframe's shared `serveStaticHandler` (`app.fetch` makes h3 a
|
|
@@ -95,7 +105,7 @@ declare function createDevframeNextHost(options: CreateDevframeNextHostOptions):
|
|
|
95
105
|
//#region src/hub.d.ts
|
|
96
106
|
interface NextDevframeHubOptions {
|
|
97
107
|
/**
|
|
98
|
-
* Mount base the hub answers under
|
|
108
|
+
* Mount base the hub answers under; every frame lives at `<base><id>/`,
|
|
99
109
|
* so the App Router needs one catch-all route under it. Default:
|
|
100
110
|
* `/__devframes/`.
|
|
101
111
|
*/
|
|
@@ -113,7 +123,7 @@ interface NextDevframeHubOptions {
|
|
|
113
123
|
/**
|
|
114
124
|
* Devframes to mount. Load built-in plugin packages through a
|
|
115
125
|
* bundler-ignored dynamic `import()` (their node code + `import.meta.url`
|
|
116
|
-
* dist lookups don't survive static Next bundling) and pass them here
|
|
126
|
+
* dist lookups don't survive static Next bundling) and pass them here, where
|
|
117
127
|
* `initHub` resolves async/factory entries.
|
|
118
128
|
*/
|
|
119
129
|
devframes?: InitHubOptions['devframes'];
|
|
@@ -133,8 +143,9 @@ interface NextDevframeHubOptions {
|
|
|
133
143
|
/** The hub's single auth gate. Gates by default; `false` opts out. */
|
|
134
144
|
auth?: InitHubOptions['auth'];
|
|
135
145
|
/**
|
|
136
|
-
* Expose the aggregate MCP endpoint at `<base>__mcp`.
|
|
137
|
-
*
|
|
146
|
+
* Expose the aggregate MCP endpoint at `<base>__mcp`. Disabled by default;
|
|
147
|
+
* `true` mounts it with the loopback origin gate (trusting same-machine
|
|
148
|
+
* callers), or pass an object to opt into an `authorization` identity check.
|
|
138
149
|
*/
|
|
139
150
|
mcp?: InitHubOptions['mcp'];
|
|
140
151
|
/** Public origin the Next app is reachable at. Default: derived from `PORT`. */
|
|
@@ -152,12 +163,13 @@ interface NextDevframeHubOptions {
|
|
|
152
163
|
* Build a devframes-hub for a Next.js App Router app: one `initHub()` call
|
|
153
164
|
* mounting every devframe under `<base><id>/` behind one web-standard
|
|
154
165
|
* `handler`, with the RPC socket on a side-car (Next routes can't accept WS
|
|
155
|
-
* upgrades) and the aggregate MCP route
|
|
166
|
+
* upgrades) and the aggregate MCP route opt-in (pass `mcp` to enable it). The
|
|
167
|
+
* UI defaults to
|
|
156
168
|
* `@devframes/hub-ui`'s `createUi()`, loaded lazily via a bundler-ignored
|
|
157
169
|
* dynamic `import()` so its asset lookups resolve at request time; pass `ui`
|
|
158
170
|
* to swap it or `ui: false` for a headless hub.
|
|
159
171
|
*
|
|
160
|
-
* Prefer {@link nextDevframeHub} at a route module
|
|
172
|
+
* Prefer {@link nextDevframeHub} at a route module: it memoizes this on
|
|
161
173
|
* `globalThis` so Next's dev-time route re-evaluation reuses one instance
|
|
162
174
|
* instead of leaking a side-car per reload.
|
|
163
175
|
*/
|
package/dist/hub.mjs
CHANGED
|
@@ -16,7 +16,7 @@ function stripTrailingSlash(base) {
|
|
|
16
16
|
* route delegates to.
|
|
17
17
|
*
|
|
18
18
|
* This is the hosted-adapter counterpart to `devframeViteBridge` for the Next
|
|
19
|
-
* runtime, which
|
|
19
|
+
* runtime, which (being webpack/Turbopack rather than Vite) can't reuse the
|
|
20
20
|
* Vite middleware path. Instead of hand-rolling static serving in a route
|
|
21
21
|
* handler, static mounts are registered on an internal h3 app and served
|
|
22
22
|
* through devframe's shared `serveStaticHandler` (`app.fetch` makes h3 a
|
|
@@ -66,6 +66,7 @@ function createDevframeNextHost(options) {
|
|
|
66
66
|
serverName: mcpOptions.serverName ?? "devframe (next)",
|
|
67
67
|
serverVersion: mcpOptions.serverVersion ?? "0.0.0",
|
|
68
68
|
exposeSharedState: mcpOptions.exposeSharedState ?? true,
|
|
69
|
+
authorization: mcpOptions.authorization,
|
|
69
70
|
allowedOrigins: mcpOptions.allowedOrigins
|
|
70
71
|
});
|
|
71
72
|
const key = stripTrailingSlash(path);
|
|
@@ -83,12 +84,13 @@ function createDevframeNextHost(options) {
|
|
|
83
84
|
* Build a devframes-hub for a Next.js App Router app: one `initHub()` call
|
|
84
85
|
* mounting every devframe under `<base><id>/` behind one web-standard
|
|
85
86
|
* `handler`, with the RPC socket on a side-car (Next routes can't accept WS
|
|
86
|
-
* upgrades) and the aggregate MCP route
|
|
87
|
+
* upgrades) and the aggregate MCP route opt-in (pass `mcp` to enable it). The
|
|
88
|
+
* UI defaults to
|
|
87
89
|
* `@devframes/hub-ui`'s `createUi()`, loaded lazily via a bundler-ignored
|
|
88
90
|
* dynamic `import()` so its asset lookups resolve at request time; pass `ui`
|
|
89
91
|
* to swap it or `ui: false` for a headless hub.
|
|
90
92
|
*
|
|
91
|
-
* Prefer {@link nextDevframeHub} at a route module
|
|
93
|
+
* Prefer {@link nextDevframeHub} at a route module: it memoizes this on
|
|
92
94
|
* `globalThis` so Next's dev-time route re-evaluation reuses one instance
|
|
93
95
|
* instead of leaking a side-car per reload.
|
|
94
96
|
*/
|
|
@@ -101,8 +103,9 @@ async function createNextDevframeHub(options = {}) {
|
|
|
101
103
|
...options.host != null ? { host: options.host } : {},
|
|
102
104
|
...options.origin != null ? { origin: options.origin } : {},
|
|
103
105
|
auth: options.auth,
|
|
106
|
+
/** Next route handlers can't accept WS upgrades, so always a side-car socket. */
|
|
104
107
|
ws: options.port != null ? { port: options.port } : { sidecar: true },
|
|
105
|
-
mcp: options.mcp
|
|
108
|
+
...options.mcp !== void 0 ? { mcp: options.mcp } : {},
|
|
106
109
|
...ui ? { ui } : {},
|
|
107
110
|
...options.renderers ? { renderers: options.renderers } : {},
|
|
108
111
|
...options.rpcDeclarations ? { rpcDeclarations: options.rpcDeclarations } : {},
|
|
@@ -170,7 +173,7 @@ function nextDevframeHub(options = {}) {
|
|
|
170
173
|
* Load `@devframes/hub-ui`'s default UI through a bundler-ignored dynamic
|
|
171
174
|
* `import()`: `createUi()` resolves its prebuilt assets via `import.meta.url`,
|
|
172
175
|
* which only points at the published `dist` when Node loads the package at
|
|
173
|
-
* request time
|
|
176
|
+
* request time, since a static import would be rewritten into a Next server chunk.
|
|
174
177
|
*/
|
|
175
178
|
async function loadDefaultUi() {
|
|
176
179
|
return (await import(
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
//#region src/index.ts
|
|
2
|
-
throw new Error("[@devframes/next] has no root export. Import from a scoped subpath instead:\n • \"@devframes/next/single\" (+ \"/single/client\")
|
|
2
|
+
throw new Error("[@devframes/next] has no root export. Import from a scoped subpath instead:\n • \"@devframes/next/single\" (+ \"/single/client\"): host one devframe's SPA\n • \"@devframes/next/hub\" (+ \"/hub/client\"): mount a devframes-hub\n");
|
|
3
3
|
//#endregion
|
|
4
4
|
export {};
|
package/dist/single.d.mts
CHANGED
|
@@ -33,7 +33,7 @@ declare function withDevframe<T extends DevframeNextConfig>(nextConfig?: T): T;
|
|
|
33
33
|
//#region src/handler.d.ts
|
|
34
34
|
interface CreateDevframeNextHandlerOptions {
|
|
35
35
|
/**
|
|
36
|
-
* Mount base for the SPA. Defaults to `def.basePath ?? '/__<id>/'
|
|
36
|
+
* Mount base for the SPA. Defaults to `def.basePath ?? '/__<id>/'`, the
|
|
37
37
|
* hosted-adapter default, so the devframe shares the Next app's origin
|
|
38
38
|
* without colliding with its routes.
|
|
39
39
|
*/
|
|
@@ -57,9 +57,9 @@ interface CreateDevframeNextHandlerOptions {
|
|
|
57
57
|
/** Override where persisted devframe state lives (defaults under the cwd / home). */
|
|
58
58
|
getStorageDir?: (scope: DevframeStorageScope) => string;
|
|
59
59
|
/**
|
|
60
|
-
* Expose the route-based MCP server (Streamable-HTTP) at `<base>__mcp
|
|
60
|
+
* Expose the route-based MCP server (Streamable-HTTP) at `<base>__mcp`,
|
|
61
61
|
* on the Next app's own origin, through the same catch-all route as the
|
|
62
|
-
* SPA
|
|
62
|
+
* SPA, and advertise it in the handler's `__connection.json`. Overrides
|
|
63
63
|
* `def.cli?.mcp`, `undefined` falls through to it, `false` disables the
|
|
64
64
|
* route regardless.
|
|
65
65
|
*/
|
|
@@ -85,7 +85,7 @@ interface DevframeNextHandler {
|
|
|
85
85
|
close: () => Promise<void>;
|
|
86
86
|
}
|
|
87
87
|
/**
|
|
88
|
-
* Host a **single** devframe from a Next.js App Router app
|
|
88
|
+
* Host a **single** devframe from a Next.js App Router app: the Next
|
|
89
89
|
* counterpart to `devframeViteBridge`, reduced to memoization + defaults over
|
|
90
90
|
* `initDevframe` (Next's route handlers can't accept WS upgrades, so the
|
|
91
91
|
* RPC socket lives on the instance's side-car port, advertised at
|
package/dist/single.mjs
CHANGED
|
@@ -52,7 +52,7 @@ function defaultGetStorageDir(scope) {
|
|
|
52
52
|
return join(homedir(), ".devframe");
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* Host a **single** devframe from a Next.js App Router app
|
|
55
|
+
* Host a **single** devframe from a Next.js App Router app: the Next
|
|
56
56
|
* counterpart to `devframeViteBridge`, reduced to memoization + defaults over
|
|
57
57
|
* `initDevframe` (Next's route handlers can't accept WS upgrades, so the
|
|
58
58
|
* RPC socket lives on the instance's side-car port, advertised at
|
|
@@ -85,8 +85,17 @@ function createDevframeNextHandler(def, options = {}) {
|
|
|
85
85
|
distDir,
|
|
86
86
|
host: options.host,
|
|
87
87
|
flags: options.flags,
|
|
88
|
+
/**
|
|
89
|
+
* Gate by default: an unset `auth` defers to the instance (devframe's
|
|
90
|
+
* interactive OTP unless `cli.auth` opts out). `false` opts out.
|
|
91
|
+
*/
|
|
88
92
|
auth: options.auth,
|
|
89
93
|
mcp: options.mcp,
|
|
94
|
+
/**
|
|
95
|
+
* Next's route handlers never see WebSocket upgrades, so the RPC socket
|
|
96
|
+
* lives on a side-car server (on `options.port` when pinned, otherwise
|
|
97
|
+
* a free port), advertised via `<base>__connection.json`.
|
|
98
|
+
*/
|
|
90
99
|
ws: options.port != null ? { port: options.port } : { sidecar: true },
|
|
91
100
|
...options.resolveOrigin ? { origin: options.resolveOrigin } : {},
|
|
92
101
|
getStorageDir: options.getStorageDir ?? defaultGetStorageDir
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devframes/next",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.9",
|
|
5
5
|
"description": "Next.js host integration that serves mounted devframes from an App Router route.",
|
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"dist"
|
|
48
48
|
],
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@devframes/hub": "0.9.
|
|
51
|
-
"@devframes/hub-ui": "0.9.
|
|
52
|
-
"devframe": "0.9.
|
|
50
|
+
"@devframes/hub": "0.9.9",
|
|
51
|
+
"@devframes/hub-ui": "0.9.9",
|
|
52
|
+
"devframe": "0.9.9",
|
|
53
53
|
"next": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
54
54
|
"react": "^18.0.0 || ^19.0.0"
|
|
55
55
|
},
|
|
@@ -71,11 +71,11 @@
|
|
|
71
71
|
"h3": "^2.0.1-rc.29"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
|
-
"@devframes/hub": "0.9.
|
|
75
|
-
"@devframes/hub-ui": "0.9.
|
|
74
|
+
"@devframes/hub": "0.9.9",
|
|
75
|
+
"@devframes/hub-ui": "0.9.9",
|
|
76
76
|
"@types/node": "^26.4.0",
|
|
77
77
|
"@types/react": "^19.2.18",
|
|
78
|
-
"devframe": "0.9.
|
|
78
|
+
"devframe": "0.9.9",
|
|
79
79
|
"react": "^19.2.8",
|
|
80
80
|
"tsdown": "^0.22.14"
|
|
81
81
|
},
|