Skip to content

Commit 96b2b31

Browse files
antfubotopencode
andcommitted
refactor(devframe)!: slim devframe/node to the context surface; drop isObject
Per API-surface review: - Remove `isObject` from the public API entirely (unused internally; trivial to inline). - Move the server-assembly primitives `createH3DevframeHost` (+ its options) and `startHttpAndWs` (+ `StartedServer`, options) from `devframe/node` to the unstable `devframe/internal` surface. `devframe/node` now exposes only the context-building API: `createHostContext`, `createStorage`, `RpcFunctionsHost`. - `createDevServer` stays — it's the standalone-server adapter (built on `initDevframe`, used by `createCac` and consumer CLIs), a different layer from the `initDevframe` handler core. The hub, plugin test harnesses, the a11y demo, storybook, and host examples now import `createH3DevframeHost` / `startHttpAndWs` from `devframe/internal`. Migration guide, plan, and tsnapi snapshots updated. Co-authored-by: opencode <noreply@opencode.ai>
1 parent 0458941 commit 96b2b31

26 files changed

Lines changed: 89 additions & 102 deletions

File tree

docs/guide/migration-0.9.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,32 +125,34 @@ Two utility subpaths with no integration consumers are removed:
125125

126126
The other `devframe/utils/*` helpers — `colors`, `open`, `launch-editor`, `hash`, `nanoid`, `crypto-token`, `structured-clone`, `events`, `shared-state`, `streaming-channel`, `when`, `simple-schema`, `serve-static`, `agent-tool-name` — are unchanged.
127127

128-
## `devframe/node` is slimmed to the server-assembly surface
128+
## `devframe/node` is slimmed to the context surface
129129

130-
`devframe/node` keeps the server-assembly API hosts actually use `createHostContext`, `createH3DevframeHost`, `startHttpAndWs` (+ `StartedServer`), `createStorage`, and the `RpcFunctionsHost` type.
130+
`devframe/node` keeps just the context-building API — `createHostContext` (+ `CreateHostContextOptions`), `createStorage` (+ `CreateStorageOptions`), and the `RpcFunctionsHost` type. Serve a devframe through the adapters (`createDevServer`, `createBuild`, `createCac`) or [`devframe/initiate`](../adapters/initiate); build a context to embed one with `createHostContext`.
131131

132-
The internal host implementations and low-level factories are no longer exported:
132+
The internal host implementations and low-level factories are no longer exported at all:
133133

134134
| Removed from `devframe/node` | Notes |
135135
|---|---|
136136
| `DevframeDiagnosticsHost`, `DevframeServicesHostImpl`, `DevframeViewHost` (classes) | Internal host implementations. The same-named **types** remain on `devframe/types`. |
137137
| `createRpcSharedStateServerHost`, `createRpcStreamingServerHost` | Wired internally by `createContextRpcServer`. |
138138
| `createScopedNodeContext`, `createNodeSettings` | Internal to context assembly. |
139-
| `toDialableHost`, `formatHostForUrl` | Internal host-URL helpers. |
139+
| `toDialableHost`, `formatHostForUrl`, `isObject` | Internal helpers (`isObject` is removed entirely — inline `typeof x === 'object' && x !== null`). |
140140

141141
## Cross-package internals move to `devframe/internal`
142142

143143
The low-level primitives shared between `devframe` and its first-party integrations (`@devframes/hub`, the inspect plugin, `@vitejs/devtools`, custom hosts) now live at the new `devframe/internal` entry point, which is explicitly **unstable** (it can change in any minor release). They were previously on `devframe/node`:
144144

145145
| Moved | From | To |
146146
|---|---|---|
147+
| `createH3DevframeHost` (+ `CreateH3DevframeHostOptions`) | `devframe/node` | `devframe/internal` |
148+
| `startHttpAndWs` (+ `StartedServer`, `StartHttpAndWsOptions`) | `devframe/node` | `devframe/internal` |
147149
| `createContextRpcServer` (+ `ContextRpcServer`, `CreateContextRpcServerOptions`) | `devframe/node` | `devframe/internal` |
148150
| `DevframeAgentHost` (class) | `devframe/node` | `devframe/internal` |
149151
| `coerceAgentPositionalArgs` (+ `AgentArgsFallback`) | `devframe/node` | `devframe/internal` |
150152
| `registerDevframeInstance` / `listLiveDevframeInstances` (+ `DevframeInstanceRecord`, `DevframeInstanceRegistration`) | `devframe/node` | `devframe/internal` |
151-
| `isObject`, `normalizeHttpServerUrl` | `devframe/node` | `devframe/internal` |
153+
| `normalizeHttpServerUrl` | `devframe/node` | `devframe/internal` |
152154

153-
A host that binds its own transport composes from `createContextRpcServer` (`devframe/internal`) plus `devframe/rpc/server`, `devframe/rpc/transports/*`, and `devframe/node/hub-internals`the path `@devframes/hub`'s `initHub` takes. A custom host advertises itself with `registerDevframeInstance`, and a devtool enumerates running instances with `listLiveDevframeInstances`. Application code should prefer the adapters and `devframe/node`.
155+
A host that stands up its own server composes from `devframe/internal``createH3DevframeHost` for the node `DevframeHost`, `startHttpAndWs` (or `createContextRpcServer` + `devframe/rpc/server` + `devframe/rpc/transports/*`) to bind a transport — plus `devframe/node`'s `createHostContext` and `devframe/node/hub-internals`. This is the path `@devframes/hub`'s `initHub` takes. A custom host advertises itself with `registerDevframeInstance`, and a devtool enumerates running instances with `listLiveDevframeInstances`. Application code should prefer the adapters and `devframe/initiate`.
154156

155157
## `@devframes/hub` category order lives only on `/constants`
156158

examples/a11y-messages-playground/src/a11y-messages-playground.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import { homedir } from 'node:os'
77
import process from 'node:process'
88
import { createHubContext, mountDevframe } from '@devframes/hub/node'
99
import { DEVFRAME_CONNECTION_META_FILENAME } from 'devframe/constants'
10-
import { registerDevframeInstance } from 'devframe/internal'
11-
import { startHttpAndWs } from 'devframe/node'
10+
import { registerDevframeInstance, startHttpAndWs } from 'devframe/internal'
1211
import { serveStaticNodeMiddleware } from 'devframe/utils/serve-static'
1312
import { getPort } from 'get-port-please'
1413
import { join } from 'pathe'

examples/files-inspector/tests/_utils.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { StartedServer } from 'devframe/node'
1+
import type { StartedServer } from 'devframe/internal'
22
import { existsSync } from 'node:fs'
33
import { mkdtemp, writeFile } from 'node:fs/promises'
44
import os from 'node:os'
@@ -7,11 +7,8 @@ import { fileURLToPath } from 'node:url'
77
import {
88
DEVFRAME_CONNECTION_META_FILENAME,
99
} from 'devframe/constants'
10-
import {
11-
createH3DevframeHost,
12-
createHostContext,
13-
startHttpAndWs,
14-
} from 'devframe/node'
10+
import { createH3DevframeHost, startHttpAndWs } from 'devframe/internal'
11+
import { createHostContext } from 'devframe/node'
1512
import { mountStaticHandler } from 'devframe/utils/serve-static'
1613
import { getPort } from 'get-port-please'
1714
import { H3 } from 'h3'

examples/next-runtime-snapshot/tests/_utils.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
import type { StartedServer } from 'devframe/node'
1+
import type { StartedServer } from 'devframe/internal'
22
import process from 'node:process'
33
import { DEVFRAME_CONNECTION_META_FILENAME } from 'devframe/constants'
4-
import {
5-
createH3DevframeHost,
6-
createHostContext,
7-
startHttpAndWs,
8-
} from 'devframe/node'
4+
import { createH3DevframeHost, startHttpAndWs } from 'devframe/internal'
5+
import { createHostContext } from 'devframe/node'
96
import { mountStaticHandler } from 'devframe/utils/serve-static'
107
import { getPort } from 'get-port-please'
118
import { H3 } from 'h3'

examples/streaming-chat/tests/_utils.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
import type { DevframeNodeContext } from 'devframe'
2-
import type { StartedServer } from 'devframe/node'
2+
import type { StartedServer } from 'devframe/internal'
33
import { existsSync } from 'node:fs'
44
import path from 'node:path'
55
import process from 'node:process'
66
import {
77
DEVFRAME_CONNECTION_META_FILENAME,
88
} from 'devframe/constants'
9-
import {
10-
createH3DevframeHost,
11-
createHostContext,
12-
startHttpAndWs,
13-
} from 'devframe/node'
9+
import { createH3DevframeHost, startHttpAndWs } from 'devframe/internal'
10+
import { createHostContext } from 'devframe/node'
1411
import { mountStaticHandler } from 'devframe/utils/serve-static'
1512
import { getPort } from 'get-port-please'
1613
import { H3 } from 'h3'

examples/streaming-chat/tests/streaming-chat.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { DevframeNodeContext } from 'devframe'
2-
import type { StartedServer } from 'devframe/node'
2+
import type { StartedServer } from 'devframe/internal'
33
import type { ChatHistory } from '../src/devframe'
44
import { createRpcStreamingClientHost } from 'devframe/client'
55
import { createRpcClient } from 'devframe/rpc/client'

packages/devframe/src/internal/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,18 @@
1414
// - `registerDevframeInstance` / `listLiveDevframeInstances` — the instance
1515
// registry: a custom host advertises itself; a devtool (the inspect plugin's
1616
// Instances tab, the connector) enumerates what's running.
17-
// - `isObject` / `normalizeHttpServerUrl` — small host-side helpers a
18-
// hand-rolled host reuses to match devframe's own config/URL handling.
17+
// - `createH3DevframeHost` — the node/standalone `DevframeHost` implementation
18+
// (filesystem storage paths + origin resolution) passed to `createHostContext`.
19+
// - `startHttpAndWs` — the low-level "listen on a port + attach the WS
20+
// transport" primitive the adapters and `initHub` are built on.
21+
// - `normalizeHttpServerUrl` — a small host-side URL helper.
1922
export { coerceAgentPositionalArgs } from '../node/agent-args'
2023
export type { AgentArgsFallback } from '../node/agent-args'
2124
export { DevframeAgentHost } from '../node/host-agent'
25+
export * from '../node/host-h3'
2226
export { listLiveDevframeInstances, registerDevframeInstance } from '../node/instance-registry'
2327
export type { DevframeInstanceRecord, DevframeInstanceRegistration } from '../node/instance-registry'
2428
export { createContextRpcServer } from '../node/rpc-core'
2529
export type { ContextRpcServer, CreateContextRpcServerOptions } from '../node/rpc-core'
26-
export { isObject, normalizeHttpServerUrl } from '../node/utils'
30+
export * from '../node/server'
31+
export { normalizeHttpServerUrl } from '../node/utils'
Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
// Node-side public API for hosts that wire up their own runtime — the
2-
// server-assembly surface (`createHostContext` → `createH3DevframeHost` →
3-
// `startHttpAndWs`) and storage.
1+
// Node-side public API for building a devframe context: `createHostContext`
2+
// (the context assembler) and `createStorage`.
43
//
5-
// Everything lower-level lives at `devframe/internal` (an explicitly-unstable
4+
// The server-assembly primitives (`createH3DevframeHost`, `startHttpAndWs`) and
5+
// everything lower-level live at `devframe/internal` (an explicitly-unstable
66
// cross-package surface): the transport-agnostic RPC core, the agent host, the
7-
// instance registry (host self-registration + live discovery), and the
8-
// `isObject` / `normalizeHttpServerUrl` helpers. The diagnostics/services/views
9-
// hosts, the streaming/shared-state/scope/settings factories, and the internal
7+
// instance registry, and the `normalizeHttpServerUrl` helper. Application code
8+
// serves a devframe through the adapters (`createDevServer`, `createBuild`,
9+
// `createCac`) or `devframe/initiate`. The diagnostics/services/views hosts,
10+
// the streaming/shared-state/scope/settings factories, and the internal
1011
// host-URL helpers stay fully internal (relative imports only).
1112
// `toAgentToolName` lives at `devframe/utils/agent-tool-name`.
1213
export * from './context'
1314
// `RpcFunctionsHostImpl` stays internal; expose only the structural
1415
// `RpcFunctionsHost` type so consumers can type/cast `ctx.rpc` without
1516
// pulling in the implementation's `@internal` members.
1617
export type { RpcFunctionsHost } from './host-functions'
17-
export * from './host-h3'
18-
export * from './server'
1918
export * from './storage'

packages/devframe/src/node/utils.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
import { isIP } from 'node:net'
22

3-
export function isObject(value: unknown): value is Record<string, any> {
4-
return Object.prototype.toString.call(value) === '[object Object]'
5-
}
6-
73
// Wildcard bind addresses (`0.0.0.0` / `::`) mean "listen on every interface";
84
// they are not themselves dialable from a browser. When advertising a URL for a
95
// client to open (banner, browser-open, dock entries), fall back to loopback —

packages/hub/src/node/__tests__/context.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import type { DevframeDockEntry } from '../../types/docks'
22
import { mkdtempSync } from 'node:fs'
33
import { tmpdir } from 'node:os'
44
import { join } from 'node:path'
5-
import { createHostContext, startHttpAndWs } from 'devframe/node'
5+
import { startHttpAndWs } from 'devframe/internal'
6+
import { createHostContext } from 'devframe/node'
67
import { getInternalContext } from 'devframe/node/hub-internals'
78
import { describe, expect, it, vi } from 'vitest'
89
import { createHubContext } from '../context'

0 commit comments

Comments
 (0)