@devframes/next 0.7.14

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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-PRESENT Anthony Fu <https://github.com/antfu>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,62 @@
1
+ import { DevframeConnectionStatus, DevframeRpcClient } from "devframe/client";
2
+ import { ReactNode } from "react";
3
+ import { ConnectionMeta } from "devframe/types";
4
+ //#region src/client.d.ts
5
+ interface DevframeRpcState {
6
+ /** The connected client, or `null` while the initial connect is in flight. */
7
+ rpc: DevframeRpcClient | null;
8
+ /** Live connection status — `'connecting'` until the client resolves. */
9
+ status: DevframeConnectionStatus;
10
+ /** The latest connection error, or `null`. */
11
+ error: Error | null;
12
+ }
13
+ interface RpcProviderProps {
14
+ children: ReactNode;
15
+ /**
16
+ * Base URL the SPA discovers `__connection.json` under, relative to the
17
+ * running page. Defaults to `'./'` (resolved against `document.baseURI`), so
18
+ * a devframe mounted at `/__<id>/` connects without extra configuration.
19
+ */
20
+ baseURL?: string;
21
+ /**
22
+ * Pre-resolved connection meta. Pass this to skip the `__connection.json`
23
+ * fetch entirely (e.g. when the host already knows the WS endpoint).
24
+ */
25
+ connectionMeta?: ConnectionMeta;
26
+ }
27
+ /**
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
+ * client plugin.
31
+ *
32
+ * Children render immediately (before the connection resolves), so your shell
33
+ * and a connection indicator stay visible throughout; read the client with
34
+ * {@link useRpc} and the status with {@link useRpcStatus}.
35
+ *
36
+ * ```tsx
37
+ * 'use client'
38
+ * import { RpcProvider } from '@devframes/next/client'
39
+ *
40
+ * export function Providers({ children }: { children: React.ReactNode }) {
41
+ * return <RpcProvider baseURL="/__my-tool/">{children}</RpcProvider>
42
+ * }
43
+ * ```
44
+ */
45
+ declare function RpcProvider({ children, baseURL, connectionMeta }: RpcProviderProps): ReactNode;
46
+ /**
47
+ * Read the connected {@link DevframeRpcClient}, or `null` while connecting.
48
+ * Scope it to your tool's RPC namespace with `useRpc()?.scope('my-tool:')`.
49
+ *
50
+ * Throws when called outside a `<RpcProvider>`.
51
+ */
52
+ declare function useRpc(): DevframeRpcClient | null;
53
+ /**
54
+ * Read the live connection `status` and latest `error`, for a connection
55
+ * indicator. Throws when called outside a `<RpcProvider>`.
56
+ */
57
+ declare function useRpcStatus(): {
58
+ status: DevframeConnectionStatus;
59
+ error: Error | null;
60
+ };
61
+ //#endregion
62
+ export { DevframeRpcState, RpcProvider, RpcProviderProps, useRpc, useRpcStatus };
@@ -0,0 +1,95 @@
1
+ "use client";
2
+ import { connectDevframe } from "devframe/client";
3
+ import { createContext, useContext, useEffect, useState } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/client.tsx
6
+ const RpcContext = createContext(null);
7
+ const INITIAL = {
8
+ rpc: null,
9
+ status: "connecting",
10
+ error: null
11
+ };
12
+ /**
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
+ * client plugin.
16
+ *
17
+ * Children render immediately (before the connection resolves), so your shell
18
+ * and a connection indicator stay visible throughout; read the client with
19
+ * {@link useRpc} and the status with {@link useRpcStatus}.
20
+ *
21
+ * ```tsx
22
+ * 'use client'
23
+ * import { RpcProvider } from '@devframes/next/client'
24
+ *
25
+ * export function Providers({ children }: { children: React.ReactNode }) {
26
+ * return <RpcProvider baseURL="/__my-tool/">{children}</RpcProvider>
27
+ * }
28
+ * ```
29
+ */
30
+ function RpcProvider({ children, baseURL = "./", connectionMeta }) {
31
+ const [state, setState] = useState(INITIAL);
32
+ useEffect(() => {
33
+ let active = true;
34
+ let client;
35
+ const sync = () => {
36
+ if (active && client) setState({
37
+ rpc: client,
38
+ status: client.status,
39
+ error: client.connectionError
40
+ });
41
+ };
42
+ const offs = [];
43
+ connectDevframe({
44
+ baseURL,
45
+ connectionMeta
46
+ }).then((c) => {
47
+ if (!active) return;
48
+ client = c;
49
+ sync();
50
+ offs.push(c.events.on("connection:status", sync));
51
+ offs.push(c.events.on("connection:error", sync));
52
+ }, (err) => {
53
+ if (active) setState({
54
+ rpc: null,
55
+ status: "error",
56
+ error: err instanceof Error ? err : new Error(String(err))
57
+ });
58
+ });
59
+ return () => {
60
+ active = false;
61
+ for (const off of offs) off();
62
+ };
63
+ }, [baseURL]);
64
+ return /* @__PURE__ */ jsx(RpcContext.Provider, {
65
+ value: state,
66
+ children
67
+ });
68
+ }
69
+ function useDevframeState() {
70
+ const state = useContext(RpcContext);
71
+ if (!state) throw new Error("[@devframes/next] useRpc()/useRpcStatus() must be called inside a <RpcProvider>.");
72
+ return state;
73
+ }
74
+ /**
75
+ * Read the connected {@link DevframeRpcClient}, or `null` while connecting.
76
+ * Scope it to your tool's RPC namespace with `useRpc()?.scope('my-tool:')`.
77
+ *
78
+ * Throws when called outside a `<RpcProvider>`.
79
+ */
80
+ function useRpc() {
81
+ return useDevframeState().rpc;
82
+ }
83
+ /**
84
+ * Read the live connection `status` and latest `error`, for a connection
85
+ * indicator. Throws when called outside a `<RpcProvider>`.
86
+ */
87
+ function useRpcStatus() {
88
+ const { status, error } = useDevframeState();
89
+ return {
90
+ status,
91
+ error
92
+ };
93
+ }
94
+ //#endregion
95
+ export { RpcProvider, useRpc, useRpcStatus };
@@ -0,0 +1,173 @@
1
+ import { CreateDevServerOptions } from "devframe/adapters/dev";
2
+ import { ConnectionMeta, DevframeDefinition, DevframeHost, DevframeStorageScope } from "devframe/types";
3
+ //#region src/config.d.ts
4
+ /**
5
+ * Minimal shape of the bits of `next.config` this helper reads/writes, so the
6
+ * package doesn't pull Next's full config type graph into its `.d.ts` bundle.
7
+ * Any real `NextConfig` structurally satisfies it.
8
+ */
9
+ interface DevframeNextConfig {
10
+ skipTrailingSlashRedirect?: boolean;
11
+ [key: string]: unknown;
12
+ }
13
+ /**
14
+ * Apply the Next config settings a devframe **host** requires, preserving
15
+ * everything else.
16
+ *
17
+ * Sets `skipTrailingSlashRedirect: true`: mounted devframe SPAs are served at
18
+ * `/__<id>/` and reference their assets relatively (`./_next/…`). Next's
19
+ * default trailing-slash redirect (`/__git/` → `/__git`) would re-root those
20
+ * relative paths and 404 every asset, leaving the panel unstyled and unable to
21
+ * connect. Serving the base path verbatim keeps relative resolution intact.
22
+ *
23
+ * ```js [next.config.mjs]
24
+ * import { withDevframe } from '@devframes/next'
25
+ *
26
+ * export default withDevframe({
27
+ * // ...your own Next config
28
+ * })
29
+ * ```
30
+ */
31
+ declare function withDevframe<T extends DevframeNextConfig>(nextConfig?: T): T;
32
+ //#endregion
33
+ //#region src/handler.d.ts
34
+ interface CreateDevframeNextHandlerOptions {
35
+ /**
36
+ * Mount base for the SPA. Defaults to `def.basePath ?? '/__<id>/'` — the
37
+ * hosted-adapter default, so the devframe shares the Next app's origin
38
+ * without colliding with its routes.
39
+ */
40
+ base?: string;
41
+ /** Bind host for the side-car RPC/WS server. Default: `def.cli?.host ?? 'localhost'`. */
42
+ host?: string;
43
+ /** Pin the side-car port. Default: resolved from `def.cli?.port` via `get-port-please`. */
44
+ port?: number;
45
+ /** Flag bag forwarded to `def.setup(ctx, { flags })`. */
46
+ flags?: Record<string, unknown>;
47
+ /**
48
+ * Whether the side-car runs its own auth gate. Defaults to `false`: this is a
49
+ * hosted adapter and the Next app owns authentication. Pass `true` for
50
+ * devframe's interactive gate or a handler for a custom scheme.
51
+ */
52
+ auth?: CreateDevServerOptions['auth'];
53
+ /** Origin the Next app is reachable at, for docks needing an absolute URL. */
54
+ resolveOrigin?: () => string;
55
+ /** Override where persisted devframe state lives (defaults under the cwd / home). */
56
+ getStorageDir?: (scope: DevframeStorageScope) => string;
57
+ /**
58
+ * Expose the side-car's route-based MCP server (Streamable-HTTP) and
59
+ * advertise it in the handler's `__connection.json`. Forwarded to
60
+ * `createDevServer`: overrides `def.cli?.mcp`, `undefined` falls through to
61
+ * it, `false` disables the route regardless. The endpoint lives on the
62
+ * side-car's own port, so the advertised meta carries `{ port, path }`.
63
+ *
64
+ * @experimental
65
+ */
66
+ mcp?: CreateDevServerOptions['mcp'];
67
+ }
68
+ interface DevframeNextHandler {
69
+ /**
70
+ * WHATWG-`fetch` handler for the catch-all App Router route. Serves the
71
+ * plugin's built SPA at `base` and answers `<base>/__connection.json` with
72
+ * the side-car WS endpoint. Awaits {@link DevframeNextHandler.ready} so the
73
+ * first request doesn't race the server boot.
74
+ */
75
+ fetch: (request: Request) => Promise<Response>;
76
+ /** Resolves once the side-car RPC/WS server is listening. */
77
+ ready: Promise<void>;
78
+ /** Shut the side-car server down (call from an app-lifecycle hook / test). */
79
+ close: () => Promise<void>;
80
+ }
81
+ /**
82
+ * Host a **single** devframe from a Next.js App Router app — the convenience
83
+ * wrapper over {@link createDevframeNextHost} for the common case of mounting
84
+ * one plugin (the Next counterpart to `viteDevBridge`'s bridge mode).
85
+ *
86
+ * It statically serves `def.cli.distDir` at `base` through the Next route and
87
+ * starts a side-car RPC/WS dev server (via `createDevServer` in bridge mode) on
88
+ * its own port, advertising that endpoint at `<base>/__connection.json` so the
89
+ * SPA's `connectDevframe()` can dial back in.
90
+ *
91
+ * ```ts [app/__my-tool/[[...path]]/route.ts]
92
+ * import myDevframe from '@/devframe'
93
+ * import { createDevframeNextHandler } from '@devframes/next'
94
+ *
95
+ * export const runtime = 'nodejs'
96
+ * export const dynamic = 'force-dynamic'
97
+ *
98
+ * const handler = createDevframeNextHandler(myDevframe)
99
+ * export const GET = handler.fetch
100
+ * ```
101
+ *
102
+ * For a hub hosting many devframes at once, use {@link createDevframeNextHost}
103
+ * directly with `@devframes/hub`.
104
+ */
105
+ declare function createDevframeNextHandler(def: DevframeDefinition, options?: CreateDevframeNextHandlerOptions): DevframeNextHandler;
106
+ //#endregion
107
+ //#region src/host.d.ts
108
+ interface CreateDevframeNextHostOptions {
109
+ /**
110
+ * Public origin the Next app is reachable at, e.g. `http://localhost:3000`.
111
+ * Surfaced through {@link DevframeHost.resolveOrigin} for docks that need an
112
+ * absolute iframe URL.
113
+ */
114
+ resolveOrigin: () => string;
115
+ /**
116
+ * Resolve a directory the host owns for persisted devframe state, per
117
+ * {@link DevframeHost.getStorageDir}.
118
+ */
119
+ getStorageDir: (scope: DevframeStorageScope) => string;
120
+ /**
121
+ * Initial connection meta served at every base registered via
122
+ * {@link DevframeHost.mountConnectionMeta}. Usually unknown until the
123
+ * side-car RPC/WS server has started — publish it later with
124
+ * {@link DevframeNextHost.setConnectionMeta}.
125
+ */
126
+ connectionMeta?: ConnectionMeta;
127
+ }
128
+ interface DevframeNextHost {
129
+ /**
130
+ * The {@link DevframeHost} to hand to `createHubContext` / `createHostContext`.
131
+ * Its `mountStatic` / `mountConnectionMeta` calls accumulate into the
132
+ * {@link DevframeNextHost.fetch} handler below.
133
+ */
134
+ host: DevframeHost;
135
+ /**
136
+ * A WHATWG-`fetch` handler that serves every mounted SPA (with SPA
137
+ * fallback, correct content types, and path-traversal guarding — all from
138
+ * devframe's own `serveStaticHandler`) and answers `<base>/__connection.json`
139
+ * for each base registered via `mountConnectionMeta`. Delegate a Next App
140
+ * Router route handler straight to it:
141
+ *
142
+ * ```ts
143
+ * export async function GET(request: Request) {
144
+ * return (await ensureHub()).fetch(request)
145
+ * }
146
+ * ```
147
+ */
148
+ fetch: (request: Request) => Promise<Response>;
149
+ /**
150
+ * Publish the live connection meta once the RPC/WS server is up. Until this
151
+ * is called (and without an initial `connectionMeta`), meta requests answer
152
+ * `503` so a racing client retries rather than caching a wrong endpoint.
153
+ */
154
+ setConnectionMeta: (meta: ConnectionMeta) => void;
155
+ }
156
+ /**
157
+ * Build a Node-runtime {@link DevframeHost} for a Next.js App Router app that
158
+ * hosts one or more devframes, plus the single `fetch` handler its catch-all
159
+ * route delegates to.
160
+ *
161
+ * This is the hosted-adapter counterpart to `viteDevBridge` for the Next
162
+ * runtime, which — being webpack/Turbopack rather than Vite — can't reuse the
163
+ * Vite middleware path. Instead of hand-rolling static serving in a route
164
+ * handler, static mounts are registered on an internal h3 app and served
165
+ * through devframe's shared `serveStaticHandler` (`app.fetch` makes h3 a
166
+ * WHATWG-`fetch` handler, exactly what an App Router route returns).
167
+ *
168
+ * Pins Node runtime (`export const runtime = 'nodejs'` in the route) because
169
+ * the static handler streams from the filesystem.
170
+ */
171
+ declare function createDevframeNextHost(options: CreateDevframeNextHostOptions): DevframeNextHost;
172
+ //#endregion
173
+ export { type CreateDevframeNextHandlerOptions, type CreateDevframeNextHostOptions, type DevframeNextConfig, type DevframeNextHandler, type DevframeNextHost, createDevframeNextHandler, createDevframeNextHost, withDevframe };
package/dist/index.mjs ADDED
@@ -0,0 +1,170 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ import process from "node:process";
4
+ import { createDevServer, resolveDevServerPort, resolveMcpConnectionMeta } from "devframe/adapters/dev";
5
+ import { DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_WS_ROUTE } from "devframe/constants";
6
+ import { serveStaticHandler } from "devframe/utils/serve-static";
7
+ import { H3 } from "h3";
8
+ //#region src/config.ts
9
+ /**
10
+ * Apply the Next config settings a devframe **host** requires, preserving
11
+ * everything else.
12
+ *
13
+ * Sets `skipTrailingSlashRedirect: true`: mounted devframe SPAs are served at
14
+ * `/__<id>/` and reference their assets relatively (`./_next/…`). Next's
15
+ * default trailing-slash redirect (`/__git/` → `/__git`) would re-root those
16
+ * relative paths and 404 every asset, leaving the panel unstyled and unable to
17
+ * connect. Serving the base path verbatim keeps relative resolution intact.
18
+ *
19
+ * ```js [next.config.mjs]
20
+ * import { withDevframe } from '@devframes/next'
21
+ *
22
+ * export default withDevframe({
23
+ * // ...your own Next config
24
+ * })
25
+ * ```
26
+ */
27
+ function withDevframe(nextConfig = {}) {
28
+ return {
29
+ ...nextConfig,
30
+ skipTrailingSlashRedirect: nextConfig.skipTrailingSlashRedirect ?? true
31
+ };
32
+ }
33
+ //#endregion
34
+ //#region src/host.ts
35
+ const META_SUFFIX = `/${DEVFRAME_CONNECTION_META_FILENAME}`;
36
+ /** Drop trailing slashes from a mount base (`/__git/` → `/__git`). */
37
+ function stripTrailingSlash(base) {
38
+ return base.replace(/\/+$/, "");
39
+ }
40
+ /**
41
+ * Build a Node-runtime {@link DevframeHost} for a Next.js App Router app that
42
+ * hosts one or more devframes, plus the single `fetch` handler its catch-all
43
+ * route delegates to.
44
+ *
45
+ * This is the hosted-adapter counterpart to `viteDevBridge` for the Next
46
+ * runtime, which — being webpack/Turbopack rather than Vite — can't reuse the
47
+ * Vite middleware path. Instead of hand-rolling static serving in a route
48
+ * handler, static mounts are registered on an internal h3 app and served
49
+ * through devframe's shared `serveStaticHandler` (`app.fetch` makes h3 a
50
+ * WHATWG-`fetch` handler, exactly what an App Router route returns).
51
+ *
52
+ * Pins Node runtime (`export const runtime = 'nodejs'` in the route) because
53
+ * the static handler streams from the filesystem.
54
+ */
55
+ function createDevframeNextHost(options) {
56
+ const app = new H3();
57
+ const metaBases = /* @__PURE__ */ new Set();
58
+ let connectionMeta = options.connectionMeta;
59
+ const host = {
60
+ mountStatic(base, distDir) {
61
+ const staticApp = new H3();
62
+ staticApp.use(serveStaticHandler(distDir));
63
+ app.mount(stripTrailingSlash(base), staticApp);
64
+ },
65
+ mountConnectionMeta(base) {
66
+ metaBases.add(stripTrailingSlash(base));
67
+ },
68
+ resolveOrigin: options.resolveOrigin,
69
+ getStorageDir: options.getStorageDir
70
+ };
71
+ async function fetch(request) {
72
+ const { pathname } = new URL(request.url);
73
+ if (pathname.endsWith(META_SUFFIX) && metaBases.has(pathname.slice(0, -META_SUFFIX.length))) {
74
+ if (!connectionMeta) return new Response(null, { status: 503 });
75
+ return Response.json(connectionMeta);
76
+ }
77
+ const response = await app.fetch(request);
78
+ if (response.status === 404) return new Response(null, { status: 404 });
79
+ return response;
80
+ }
81
+ return {
82
+ host,
83
+ fetch,
84
+ setConnectionMeta(meta) {
85
+ connectionMeta = meta;
86
+ }
87
+ };
88
+ }
89
+ //#endregion
90
+ //#region src/handler.ts
91
+ /** Ensure a mount base has a single leading and trailing slash. */
92
+ function normalizeBase(base) {
93
+ return `/${base}/`.replace(/\/{2,}/g, "/");
94
+ }
95
+ function defaultGetStorageDir(scope) {
96
+ const cwd = process.cwd();
97
+ if (scope === "workspace") return join(cwd, ".devframe");
98
+ if (scope === "project") return join(cwd, "node_modules/.devframe");
99
+ return join(homedir(), ".devframe");
100
+ }
101
+ /**
102
+ * Host a **single** devframe from a Next.js App Router app — the convenience
103
+ * wrapper over {@link createDevframeNextHost} for the common case of mounting
104
+ * one plugin (the Next counterpart to `viteDevBridge`'s bridge mode).
105
+ *
106
+ * It statically serves `def.cli.distDir` at `base` through the Next route and
107
+ * starts a side-car RPC/WS dev server (via `createDevServer` in bridge mode) on
108
+ * its own port, advertising that endpoint at `<base>/__connection.json` so the
109
+ * SPA's `connectDevframe()` can dial back in.
110
+ *
111
+ * ```ts [app/__my-tool/[[...path]]/route.ts]
112
+ * import myDevframe from '@/devframe'
113
+ * import { createDevframeNextHandler } from '@devframes/next'
114
+ *
115
+ * export const runtime = 'nodejs'
116
+ * export const dynamic = 'force-dynamic'
117
+ *
118
+ * const handler = createDevframeNextHandler(myDevframe)
119
+ * export const GET = handler.fetch
120
+ * ```
121
+ *
122
+ * For a hub hosting many devframes at once, use {@link createDevframeNextHost}
123
+ * directly with `@devframes/hub`.
124
+ */
125
+ function createDevframeNextHandler(def, options = {}) {
126
+ const distDir = def.cli?.distDir;
127
+ if (!distDir) throw new Error(`[@devframes/next] createDevframeNextHandler("${def.id}") needs a built SPA to serve, but "cli.distDir" is not set on the devframe definition.`);
128
+ const base = normalizeBase(options.base ?? def.basePath ?? `/__${def.id}/`);
129
+ const hostName = options.host ?? def.cli?.host;
130
+ const nextHost = createDevframeNextHost({
131
+ resolveOrigin: options.resolveOrigin ?? (() => ""),
132
+ getStorageDir: options.getStorageDir ?? defaultGetStorageDir
133
+ });
134
+ nextHost.host.mountStatic(base, distDir);
135
+ nextHost.host.mountConnectionMeta?.(base);
136
+ let started;
137
+ const ready = (async () => {
138
+ const port = options.port ?? await resolveDevServerPort(def, { host: hostName });
139
+ started = await createDevServer(def, {
140
+ host: hostName,
141
+ port,
142
+ flags: options.flags,
143
+ openBrowser: false,
144
+ auth: options.auth ?? false,
145
+ mcp: options.mcp
146
+ });
147
+ const mcpMeta = resolveMcpConnectionMeta(def, options.mcp, port);
148
+ nextHost.setConnectionMeta({
149
+ backend: "websocket",
150
+ websocket: {
151
+ port,
152
+ path: `/${DEVFRAME_WS_ROUTE}`
153
+ },
154
+ ...mcpMeta ? { mcp: mcpMeta } : {}
155
+ });
156
+ })();
157
+ return {
158
+ async fetch(request) {
159
+ await ready;
160
+ return nextHost.fetch(request);
161
+ },
162
+ ready,
163
+ async close() {
164
+ await ready.catch(() => {});
165
+ await started?.close();
166
+ }
167
+ };
168
+ }
169
+ //#endregion
170
+ export { createDevframeNextHandler, createDevframeNextHost, withDevframe };
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@devframes/next",
3
+ "type": "module",
4
+ "version": "0.7.14",
5
+ "description": "Next.js host integration for Devframe — serve mounted devframe SPAs and connection meta from an App Router route (experimental)",
6
+ "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/devframes/devframe#readme",
9
+ "repository": {
10
+ "directory": "packages/next",
11
+ "type": "git",
12
+ "url": "git+https://github.com/devframes/devframe.git"
13
+ },
14
+ "bugs": "https://github.com/devframes/devframe/issues",
15
+ "keywords": [
16
+ "devframe",
17
+ "next",
18
+ "nextjs",
19
+ "devtools"
20
+ ],
21
+ "sideEffects": false,
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.mts",
25
+ "default": "./dist/index.mjs"
26
+ },
27
+ "./client": {
28
+ "types": "./dist/client.d.mts",
29
+ "default": "./dist/client.mjs"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "types": "./dist/index.d.mts",
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "peerDependencies": {
38
+ "next": "^14.0.0 || ^15.0.0 || ^16.0.0",
39
+ "react": "^18.0.0 || ^19.0.0",
40
+ "devframe": "0.7.14"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "next": {
44
+ "optional": true
45
+ },
46
+ "react": {
47
+ "optional": true
48
+ }
49
+ },
50
+ "dependencies": {
51
+ "h3": "^2.0.1-rc.22"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^26.1.1",
55
+ "@types/react": "^19.2.17",
56
+ "react": "^19.2.8",
57
+ "tsdown": "^0.22.14",
58
+ "devframe": "0.7.14"
59
+ },
60
+ "scripts": {
61
+ "build": "tsdown",
62
+ "watch": "tsdown --watch",
63
+ "typecheck": "tsc --noEmit"
64
+ }
65
+ }