@hyperfrontend/features/server

Server

Dev server and debug UI for testing host/hostee interactions — per-app static hosting plus display-mode, resize, message-log, and security controls.

Quick start

Start a dev server from a resolved hf-dev.config.*:

import { resolveDevConfig, startDevServer } from '@hyperfrontend/features/server'

const config = await resolveDevConfig({ cwd: process.cwd(), flags })
const handle = await startDevServer(config)

console.log(handle.debugUrl) // http://localhost:4280/
handle.apps.forEach((app) => console.log(app.name, app.url))

await handle.close()

How it serves

Each configured app is served by its own static server bound to its port, so apps load at distinct origins — letting the host/hostee message channel and security envelope be exercised cross-origin, exactly as in production. The debug UI is hosted at / on a separate control server (default port 4280), which also exposes the running-app manifest at /__apps and the compiled debug-UI assets under /__debug/.

API

ExportPurpose
resolveDevConfigResolve hf-dev.config.* + CLI flags into concrete app servers.
startDevServerStart the app servers and the debug-UI control server.
validateDevConfig / validateApps / validateDevAppRuntime validation of the config shape.
createStaticHandler / serveFileStatic-file request handling used by the app servers.

The config schema (apps, debug) and the defineDevConfig() authoring helper live in the main @hyperfrontend/features entry.

API Reference

ƒ Functions

§function

createStaticHandler(root: string, deps: StaticHandlerDeps): (req: IncomingMessage, res: ServerResponse) => void

Builds an HTTP request handler that serves static files from a single root.

Parameters

NameTypeDescription
§root
string
The absolute directory files are served from.
§deps
StaticHandlerDeps
Optional file-system overrides.
(default: {})

Returns

(req: IncomingMessage, res: ServerResponse) => void
A request handler suitable for http.createServer.

Example

Serving a compiled app directory

const server = createServer(createStaticHandler('/abs/dist'))
§function

requestPath(url: string): string

Extracts the path portion of a request URL, defaulting a missing URL to / and dropping any query string.

Parameters

NameTypeDescription
§url
string
The raw request URL (req.url), which may be undefined.

Returns

string
The path with no query string.

Example

Stripping a query string

requestPath('/app.js?v=2') // '/app.js'
§function

resolveDevConfig(options: ResolveDevConfigOptions): Promise<ResolvedDevConfig>

Resolves the effective hf-dev.config.* into concrete app servers and debug settings, applying config file < flags precedence: --apps replaces the apps array, --port sets the debug-UI port, and --config selects the file.

Parameters

NameTypeDescription
§options
ResolveDevConfigOptions
The working directory, parsed flags, and injectable deps.

Returns

Promise<ResolvedDevConfig>
The resolved apps, debug toggles, debug port, and source path.

Example

Resolving a discovered dev config

const resolved = await resolveDevConfig({ cwd: process.cwd(), flags })
§function

serveFile(root: string, urlPath: string, res: ServerResponse, deps: StaticHandlerDeps): void

Serves a single static file from root to the response, sending 403 on a traversal attempt and 404 when the file is missing.

Parameters

NameTypeDescription
§root
string
The absolute directory files are served from.
§urlPath
string
The request path (with or without a query string).
§res
ServerResponse
The HTTP response to write.
§deps
StaticHandlerDeps
Optional file-system overrides.
(default: {})

Example

Serving an app's `index.html`

serveFile('/abs/dist', '/', res)
§function

startDevServer(config: ResolvedDevConfig, deps: DevServerDeps): Promise<DevServerHandle>

Starts the dev server: one static server per app (each on its own port for a distinct origin) plus, when enabled, the control server hosting the debug UI.

Parameters

NameTypeDescription
§config
ResolvedDevConfig
The resolved dev-server config.
§deps
DevServerDeps
Optional server-creation, asset-location, and file-system overrides.
(default: {})

Returns

Promise<DevServerHandle>
A handle exposing the running apps, the manifest, the debug URL, and a teardown.

Example

Starting a dev server from a resolved config

const handle = await startDevServer(resolved)
console.log(handle.debugUrl)
await handle.close()
§function

validateApps(value: unknown, sourcePath: string): DevAppConfig[]

Validates an unknown value as a dev-server apps array.

Parameters

NameTypeDescription
§value
unknown
The candidate apps array.
§sourcePath
string
The file the array came from, used in error messages.

Returns

DevAppConfig[]
The validated, non-empty apps array.

Example

Validating an apps array loaded from `--apps`

const apps = validateApps([{ name: 'clock', outputDir: './dist' }], '/p/apps.json')
§function

validateDevApp(value: unknown, index: number, sourcePath: string): DevAppConfig

Validates one app entry, asserting name/outputDir strings and an optional numeric port.

Parameters

NameTypeDescription
§value
unknown
The candidate app entry.
§index
number
The entry's index, used to locate problems in the error message.
§sourcePath
string
The file the entry came from, used in the error message.

Returns

DevAppConfig
The validated app entry.

Example

Validating a single app entry

const app = validateDevApp({ name: 'clock', outputDir: './dist' }, 0, '/p/hf-dev.config.json')
§function

validateDevConfig(value: unknown, sourcePath: string): DevConfig

Validates an unknown value as a DevConfig.

Parameters

NameTypeDescription
§value
unknown
The loaded config value.
§sourcePath
string
The config path, used in error messages.

Returns

DevConfig
The validated config.

Example

Validating a loaded dev config

const config = validateDevConfig({ apps: [{ name: 'clock', outputDir: './dist' }] }, '/p/hf-dev.config.json')

Interfaces

§interface

DevManifest

The manifest the debug UI reads to discover the running apps and its own toggles.

Properties

§readonly apps:unknown
Each running app's name and origin URL.
§readonly debug:ResolvedDevDebug
The resolved debug-UI toggles.
§interface

DevManifestApp

A running app as advertised to the debug UI.

Properties

§readonly name:string
App name, matched against the feature name.
§readonly url:string
The origin URL the app is served from.
§interface

DevServerApp

A single running app static server.

Properties

§readonly name:string
App name, matched against the feature name.
§readonly port:number
The port the app is actually listening on.
§readonly url:string
The origin URL the app is served from.
§interface

DevServerDeps

Injectable boundaries for startDevServer, defaulted for production.

Properties

§readonly assetRoot?:string
Directory the compiled debug-UI assets are read from; defaults to the assets shipped beside this module.
§readonly createServer?:(handler: (req: IncomingMessage, res: ServerResponse) => void) => Server
Creates an HTTP server from a request handler.
§readonly isFile?:(filePath: string) => boolean
Reports whether a path is a readable file.
§readonly readFile?:(filePath: string) => Buffer
Reads a file's bytes.
§interface

DevServerHandle

A running dev server: the app servers, the debug UI, and a teardown.

Properties

§readonly apps:unknown
The running app static servers.
§readonly debugUrl?:string
The debug-UI URL, present only when the debug UI is enabled.
§readonly manifest:DevManifest
The manifest exposed to the debug UI.
§interface

ResolvedDevApp

A single dev-server app with its serving directory and port resolved to concrete values.

Properties

§readonly name:string
App name, matched against the feature name.
§readonly outputDir:string
Absolute directory the built app is served from.
§readonly port:number
Port the app's static server listens on.
§interface

ResolvedDevConfig

A fully-resolved hf-dev.config.*: concrete app servers plus debug settings.

Properties

§readonly apps:unknown
The app static servers to start.
§readonly debug:ResolvedDevDebug
The resolved debug-UI toggles.
§readonly debugPort:number
Port the debug-UI control server listens on.
§readonly sourcePath:string
Absolute path of the config file that was loaded.
§interface

ResolvedDevDebug

Fully-resolved debug-UI toggles with every option defaulted.

Properties

§readonly enabled:boolean
Whether the debug UI is served at all.
§readonly messageLog:boolean
Whether the message-log panel is shown.
§readonly securityView:boolean
Whether the security-inspector panel is shown.
§interface

ResolveDevConfigDeps

Injectable boundaries for resolveDevConfig, defaulted for production.

Properties

§readonly discover?:(directory: string, baseName: string) => string
Discovers the dev-server config file under a directory.
§readonly loadConfig?:(absolutePath: string) => Promise<unknown>
Loads a resolved config or apps file.
§interface

ResolveDevConfigOptions

Inputs for resolveDevConfig.

Properties

§readonly cwd:string
Working directory the config and apps paths resolve against.
§readonly discover?:(directory: string, baseName: string) => string
Discovers the dev-server config file under a directory.
§readonly flags:CliFlags
Parsed CLI flags, applied with the highest precedence.
§readonly loadConfig?:(absolutePath: string) => Promise<unknown>
Loads a resolved config or apps file.
§interface

StaticHandlerDeps

Injectable file-system boundaries for the static handler, defaulted for production.

Properties

§readonly isFile?:(filePath: string) => boolean
Reports whether a path is a readable file.
§readonly readFile?:(filePath: string) => Buffer
Reads a file's bytes.