@alxia/react-router 0.7.4 → 0.8.0

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.
@@ -7,12 +7,12 @@
7
7
  "/**\n * The server build, self-contained: every dependency bundled into\n * `build/server/index.js`, so that running it needs `build/` and Bun, and\n * no `node_modules`. A Docker image's final stage copies `build/` alone.\n */\nimport type { EnvironmentOptions } from 'vite';\nimport { bunEnvironment } from './bun';\n\n/**\n * What the plugin adds to the `ssr` environment under `react-router build`,\n * given its options as the config and the plugins left them:\n * `resolve.noExternal: true`, every package bundled. Never in dev, where\n * Vite's SSR runner loads the packages from `node_modules`.\n *\n * What the app set wins:\n *\n * - `ssr.external: ['sharp']`, or the same on `environments.ssr.resolve`,\n * keeps those packages external, imported from `node_modules` at\n * runtime: Vite reads `external` before `noExternal`. Bun's own modules,\n * `bun` and `bun:*`, and Node's are builtins, external whatever this says.\n * - `ssr.external: true` keeps every package external, Vite's own default:\n * the plugin adds nothing then.\n * - `ssr.noExternal`, a list, is a subset of everything: it changes nothing.\n *\n * React Router's own plugin reads `noExternal: true` and adds no externals\n * of its own; it runs after this one, which is `enforce: 'pre'`.\n */\nexport function bundledEnvironment(\n\toptions: EnvironmentOptions,\n): EnvironmentOptions | undefined {\n\tif (options.resolve?.external === true) return undefined;\n\treturn { resolve: { noExternal: true } };\n}\n\n/**\n * Everything the plugin adds to the `ssr` environment: built for Bun under\n * either command, and self-contained under `build` alone. In dev, Vite's\n * SSR runner loads the packages from `node_modules`.\n */\nexport function ssrEnvironment(\n\toptions: EnvironmentOptions,\n\tcommand: 'build' | 'serve',\n): EnvironmentOptions {\n\tconst added = bunEnvironment(options);\n\tconst bundled = command === 'build' ? bundledEnvironment(options) : undefined;\n\tif (bundled === undefined) return added;\n\treturn { ...added, resolve: { ...added.resolve, ...bundled.resolve } };\n}\n",
8
8
  "/**\n * What the plugin reads of Vite's and React Router's config: the server\n * file, the client folder, and the server build's bundler options.\n */\nimport { existsSync } from 'node:fs';\nimport { dirname, isAbsolute, join, relative, resolve } from 'node:path';\nimport type { ResolvedConfig } from 'vite';\nimport { NAME } from './entry';\n\n/** The server build's input, and in dev the module the requests go to. */\nexport const SERVER = 'virtual:alxia-react-router/server';\n/** The same, when there is no server file: `createServer()` as it is. */\nexport const DEFAULT = `${SERVER}-default`;\n\n/** What the plugin reads of React Router's own config. */\nexport interface ReactRouterConfig {\n\treadonly appDirectory: string;\n\treadonly buildDirectory: string;\n\treadonly serverBuildFile: string;\n\treadonly ssr: boolean;\n\treadonly serverBundles?: unknown;\n}\n\n/** React Router's config, which its plugin puts on Vite's. */\nexport function contextOf(config: object): ReactRouterConfig {\n\tconst context = (\n\t\tconfig as {\n\t\t\treadonly __reactRouterPluginContext?: {\n\t\t\t\treadonly reactRouterConfig: ReactRouterConfig;\n\t\t\t};\n\t\t}\n\t).__reactRouterPluginContext;\n\tif (context === undefined) {\n\t\tthrow new Error(\n\t\t\t`${NAME}: React Router's Vite plugin is not in this config. Add reactRouter() from @react-router/dev/vite beside alxia() in vite.config.ts.`,\n\t\t);\n\t}\n\treturn context.reactRouterConfig;\n}\n\n/** React Router's child compiler: a Vite server without its plugin, cached apart. */\nexport function isChildCompiler(config: ResolvedConfig): boolean {\n\treturn (\n\t\t(config as { readonly __reactRouterPluginContext?: unknown })\n\t\t\t.__reactRouterPluginContext === undefined &&\n\t\tconfig.cacheDir.endsWith('.vite-child-compiler')\n\t);\n}\n\n/**\n * The server file: `entry`, which must exist, or `app/server.ts` when it\n * does, or `undefined` for the default server.\n */\nexport function serverFile(\n\tentry: string | undefined,\n\tconfig: ResolvedConfig,\n): string | undefined {\n\tif (entry !== undefined) {\n\t\tconst file = isAbsolute(entry) ? entry : resolve(config.root, entry);\n\t\tif (!existsSync(file)) {\n\t\t\tthrow new Error(\n\t\t\t\t`${NAME}: the entry ${entry} does not exist. Create it, or leave entry out to use app/server.ts, or the default server without it.`,\n\t\t\t);\n\t\t}\n\t\treturn file;\n\t}\n\tconst file = join(contextOf(config).appDirectory, 'server.ts');\n\treturn existsSync(file) ? file : undefined;\n}\n\n/** The built server, absolute: `build/server/index.js`. */\nexport function serverBuildPath(config: ResolvedConfig): string {\n\tconst rr = contextOf(config);\n\tconst outDir = resolve(\n\t\tconfig.root,\n\t\tconfig.environments['ssr']?.build.outDir ??\n\t\t\tjoin(rr.buildDirectory, 'server'),\n\t);\n\treturn join(outDir, rr.serverBuildFile);\n}\n\n/** `build/client`, relative to the built `build/server/index.js`. */\nexport function clientPath(config: ResolvedConfig): string {\n\tconst built = dirname(serverBuildPath(config));\n\tconst path = relative(\n\t\tbuilt,\n\t\tjoin(contextOf(config).buildDirectory, 'client'),\n\t);\n\treturn path.startsWith('.') ? path : `./${path}`;\n}\n\n/**\n * The ssr build's options: one file, `build/server/index.js`, the server\n * and React Router's build together. Rolldown, under Vite 8, names the\n * option otherwise.\n */\nexport function serverBuildOptions(rolldown: boolean): object {\n\treturn rolldown\n\t\t? {\n\t\t\t\trolldownOptions: {\n\t\t\t\t\tinput: SERVER,\n\t\t\t\t\toutput: { codeSplitting: false },\n\t\t\t\t},\n\t\t\t}\n\t\t: {\n\t\t\t\trollupOptions: {\n\t\t\t\t\tinput: SERVER,\n\t\t\t\t\toutput: { inlineDynamicImports: true },\n\t\t\t\t},\n\t\t\t};\n}\n",
9
9
  "/**\n * The few lines between Vite's dev and preview servers, which speak\n * `node:http`, and an alxia app, which speaks `Request` and `Response`: no\n * dependency, Bun's own `node:http` and `node:stream` underneath.\n */\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport { Readable } from 'node:stream';\n\n/** What Connect, Vite's middleware stack, adds to a request: the URL before any rewrite. */\ntype ConnectRequest = IncomingMessage & {\n\treadonly originalUrl?: string | undefined;\n};\n\n/** The `Request` a Node request stands for. Aborted when the client goes away. */\nexport function toRequest(req: ConnectRequest, res: ServerResponse): Request {\n\tconst secure = (req.socket as { encrypted?: boolean }).encrypted === true;\n\tconst url = new URL(\n\t\treq.originalUrl ?? req.url ?? '/',\n\t\t`${secure ? 'https' : 'http'}://${req.headers.host ?? 'localhost'}`,\n\t);\n\tconst headers = new Headers();\n\tconst raw = req.rawHeaders;\n\tfor (let i = 0; i + 1 < raw.length; i += 2) {\n\t\tconst name = raw[i] as string;\n\t\t// HTTP/2's pseudo-headers (`:path`, `:method`) are not headers.\n\t\tif (!name.startsWith(':')) headers.append(name, raw[i + 1] as string);\n\t}\n\tconst controller = new AbortController();\n\tres.once('close', () => {\n\t\tif (!res.writableFinished) controller.abort();\n\t});\n\tconst method = req.method ?? 'GET';\n\tconst init: RequestInit & { duplex?: 'half' } = {\n\t\tmethod,\n\t\theaders,\n\t\tsignal: controller.signal,\n\t};\n\tif (method !== 'GET' && method !== 'HEAD') {\n\t\tinit.body = Readable.toWeb(req) as unknown as ReadableStream<Uint8Array>;\n\t\tinit.duplex = 'half';\n\t}\n\treturn new Request(url, init);\n}\n\n/** Writes `response` to `res`, streaming its body chunk by chunk as it comes. */\nexport async function send(\n\tres: ServerResponse,\n\tresponse: Response,\n): Promise<void> {\n\tres.statusCode = response.status;\n\tif (response.statusText !== '') res.statusMessage = response.statusText;\n\tfor (const [name, value] of response.headers) {\n\t\tif (name !== 'set-cookie') res.setHeader(name, value);\n\t}\n\tconst cookies = response.headers.getSetCookie();\n\tif (cookies.length > 0) res.setHeader('set-cookie', cookies);\n\tif (response.body === null) {\n\t\tres.end();\n\t\treturn;\n\t}\n\tres.flushHeaders();\n\tconst reader = response.body.getReader();\n\tconst cancel = () => void reader.cancel().catch(() => {});\n\tres.once('close', cancel);\n\ttry {\n\t\tfor (;;) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tif (res.destroyed) return;\n\t\t\tif (!res.write(value)) {\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\tconst go = () => {\n\t\t\t\t\t\tres.off('drain', go);\n\t\t\t\t\t\tres.off('close', go);\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t};\n\t\t\t\t\tres.on('drain', go);\n\t\t\t\t\tres.on('close', go);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tres.end();\n\t} finally {\n\t\tres.off('close', cancel);\n\t}\n}\n",
10
- "/**\n * Under `react-router dev` and `vite preview`: the app's WebSocket routes. Vite's server is a\n * `node:http` one, and an alxia socket is `Bun.serve`'s upgrade, so each\n * upgrade Vite leaves is relayed, bytes as they come, to a `Bun.serve` of\n * the app's own on a loopback port: its middlewares, its validation, its socket\n * handlers, exactly as `listen` runs them.\n */\nimport type { IncomingMessage } from 'node:http';\nimport { connect, type Socket } from 'node:net';\nimport type { DevApp } from './dev';\nimport { NAME } from './entry';\n\n/** The subprotocols of Vite's own socket, the HMR one and its ping: Vite answers them. */\nconst VITE = new Set(['vite-hmr', 'vite-ping']);\n\n/** Whether the upgrade asks for Vite's own socket. */\nexport function isVites(req: Pick<IncomingMessage, 'headers'>): boolean {\n\tconst protocols = req.headers['sec-websocket-protocol'];\n\tif (protocols === undefined) return false;\n\treturn protocols.split(',').some((protocol) => VITE.has(protocol.trim()));\n}\n\n/** One entry of Vite's `server.proxy`, as far as its sockets go. */\ntype ProxyEntry = string | { readonly ws?: boolean; readonly target?: unknown };\n\n/**\n * Whether Vite's `server.proxy` relays this upgrade itself: an entry whose\n * context matches the URL, as Vite matches it (`^…` a RegExp, otherwise a\n * prefix), and that proxies sockets (`ws: true`, or a `ws:`/`wss:` target).\n */\nexport function isProxied(\n\turl: string,\n\tproxy: Readonly<Record<string, ProxyEntry>> | undefined,\n): boolean {\n\tfor (const [context, entry] of Object.entries(proxy ?? {})) {\n\t\tconst matches =\n\t\t\t(context.startsWith('^') && new RegExp(context).test(url)) ||\n\t\t\turl.startsWith(context);\n\t\tif (!matches) continue;\n\t\tconst options = typeof entry === 'string' ? { target: entry } : entry;\n\t\tconst target = String(options.target ?? '');\n\t\tif (\n\t\t\toptions.ws === true ||\n\t\t\ttarget.startsWith('ws:') ||\n\t\t\ttarget.startsWith('wss:')\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/** The request line and headers of `req`, as they came: what the side server reads. */\nexport function head(\n\treq: Pick<IncomingMessage, 'method' | 'url' | 'rawHeaders'>,\n): string {\n\tconst lines = [`${req.method ?? 'GET'} ${req.url ?? '/'} HTTP/1.1`];\n\tconst raw = req.rawHeaders;\n\tfor (let i = 0; i + 1 < raw.length; i += 2) {\n\t\tlines.push(`${raw[i]}: ${raw[i + 1]}`);\n\t}\n\treturn `${lines.join('\\r\\n')}\\r\\n\\r\\n`;\n}\n\n/** The side servers: the current app's, and those an edit retired, until their sockets close. */\nexport interface Sides {\n\tcurrent:\n\t\t| { readonly app: DevApp; readonly side: Bun.Server<unknown> }\n\t\t| undefined;\n\treadonly retired: Set<Bun.Server<unknown>>;\n}\n\n/**\n * The side server of `app`, started on its first upgrade. A new app, an\n * edit's, retires the previous one: no new connection, and the sockets open\n * on it stay, with the handlers they opened with, until they close.\n */\nexport function sideFor(sides: Sides, app: DevApp): Bun.Server<unknown> {\n\tif (sides.current?.app === app) return sides.current.side;\n\tconst side = Bun.serve({\n\t\tport: 0,\n\t\thostname: '127.0.0.1',\n\t\tfetch: (request, bun) => app.fetch(request, bun),\n\t\twebsocket: app.websocket,\n\t} as Bun.Serve.Options<never>) as Bun.Server<unknown>;\n\tconst old = sides.current?.side;\n\tif (old !== undefined) {\n\t\tsides.retired.add(old);\n\t\tvoid old.stop().then(() => sides.retired.delete(old));\n\t}\n\tsides.current = { app, side };\n\treturn side;\n}\n\n/** Stops every side server, open sockets and all: Vite's server closed. */\nexport function closeAll(sides: Sides): void {\n\tfor (const side of [...sides.retired, sides.current?.side]) {\n\t\tvoid side?.stop(true);\n\t}\n\tsides.current = undefined;\n\tsides.retired.clear();\n}\n\n/** Relays the upgrade on `socket` to the side server on `port`, both ways. */\nfunction relay(\n\treq: IncomingMessage,\n\tsocket: Socket,\n\tbytes: Buffer,\n\tport: number,\n): void {\n\tconst upstream = connect(port, '127.0.0.1', () => {\n\t\tupstream.write(head(req));\n\t\tif (bytes.length > 0) upstream.write(bytes);\n\t\tupstream.pipe(socket);\n\t\tsocket.pipe(upstream);\n\t});\n\tupstream.on('error', () => socket.destroy());\n\tupstream.on('close', () => socket.destroy());\n\tsocket.on('close', () => upstream.destroy());\n}\n\n/** What the relay listens to on Vite's HTTP server, HTTP/1 or HTTP/2 alike. */\ninterface Upgrades {\n\ton(\n\t\tevent: 'upgrade',\n\t\tlistener: (req: IncomingMessage, socket: Socket, bytes: Buffer) => void,\n\t): unknown;\n\tonce(event: 'close', listener: () => void): unknown;\n}\n\n/** What the relay needs of the server it listens on: Vite's dev server or its preview. */\nexport interface Bridge {\n\t/** Vite's `server.proxy` (or `preview.proxy`): the upgrades it relays are its own. */\n\treadonly proxy: Readonly<Record<string, ProxyEntry>> | undefined;\n\t/** The app, as it is now. */\n\treadonly load: () => Promise<DevApp>;\n\t/** Where an upgrade that failed is printed: Vite's logger. */\n\treadonly logger: { error(message: string): void };\n\t/** Maps an error's stack to the source, as Vite's `ssrFixStacktrace` does. */\n\treadonly fix?: (error: Error) => void;\n}\n\n/** An upgrade the app could not take: reported, and a 500 to the client. */\nfunction refuse(bridge: Bridge, socket: Socket, error: unknown): void {\n\tif (error instanceof Error) bridge.fix?.(error);\n\tbridge.logger.error(\n\t\t`${NAME}: a WebSocket upgrade failed: ${error instanceof Error ? (error.stack ?? error.message) : String(error)}`,\n\t);\n\tif (socket.writable) {\n\t\tsocket.end(\n\t\t\t'HTTP/1.1 500 Internal Server Error\\r\\nConnection: close\\r\\nContent-Length: 0\\r\\n\\r\\n',\n\t\t);\n\t}\n}\n\n/**\n * Relays the app's upgrades on Vite's HTTP server to a side server of the\n * app. Vite's own socket and the sockets its proxy relays are left to\n * Vite. Without an HTTP server (Vite's middleware mode), there is nothing\n * to listen on.\n */\nexport function bridgeSockets(http: Upgrades | null, bridge: Bridge): void {\n\tif (http === null) return;\n\tconst sides: Sides = { current: undefined, retired: new Set() };\n\thttp.on('upgrade', (req: IncomingMessage, socket: Socket, bytes: Buffer) => {\n\t\tif (isVites(req) || isProxied(req.url ?? '/', bridge.proxy)) return;\n\t\tsocket.on('error', () => socket.destroy());\n\t\tbridge\n\t\t\t.load()\n\t\t\t.then((app) => {\n\t\t\t\tif (socket.destroyed) return;\n\t\t\t\trelay(req, socket, bytes, sideFor(sides, app).port as number);\n\t\t\t})\n\t\t\t.catch((error: unknown) => refuse(bridge, socket, error));\n\t});\n\thttp.once('close', () => closeAll(sides));\n}\n",
11
- "/**\n * Under `react-router dev`: a request Vite left, answered by the server,\n * loaded through the ssr environment's module runner.\n */\nimport type { ViteDevServer } from 'vite';\nimport { DEFAULT, SERVER, serverFile } from './config';\nimport { NAME } from './entry';\nimport { send, toRequest } from './node';\nimport { bridgeSockets } from './socket';\n\n/** What the dev server module exports: the alxia app, as `server.create` made it. */\nexport interface DevApp {\n\tfetch(request: Request, server?: Bun.Server<unknown>): Promise<Response>;\n\treadonly websocket: Bun.WebSocketHandler<never>;\n}\n\n/**\n * The app, as the server file is now: the runner keeps the module until an\n * edit invalidates it, so an edit is a new app.\n */\nexport async function loadApp(\n\tserver: ViteDevServer,\n\tentry: string | undefined,\n): Promise<DevApp> {\n\t// Duck-typed rather than Vite's `isRunnableDevEnvironment`: the app's\n\t// Vite may be another copy than the one this package would import.\n\tconst runner = (\n\t\tserver.environments.ssr as\n\t\t\t| { readonly runner?: { readonly import?: unknown } }\n\t\t\t| undefined\n\t)?.runner;\n\tif (typeof runner?.import !== 'function') {\n\t\tthrow new Error(\n\t\t\t`${NAME}: Vite's ssr environment does not run modules in this process, so the server cannot be loaded.`,\n\t\t);\n\t}\n\t// Chosen on each request: a server file created or deleted while the\n\t// dev server runs is used from the next one.\n\tconst id = serverFile(entry, server.config) === undefined ? DEFAULT : SERVER;\n\tconst module = (await (runner.import as (id: string) => Promise<unknown>)(\n\t\tid,\n\t)) as { readonly default: DevApp };\n\treturn module.default;\n}\n\nexport async function serveFromEntry(\n\tserver: ViteDevServer,\n\tentry: string | undefined,\n\treq: Parameters<typeof toRequest>[0],\n\tres: Parameters<typeof toRequest>[1],\n): Promise<void> {\n\tconst app = await loadApp(server, entry);\n\tawait send(res, await app.fetch(toRequest(req, res)));\n}\n\n/**\n * `react-router dev`: the app's sockets on Vite's server now, and, returned\n * for after Vite's own middlewares, every request Vite leaves to the app.\n */\nexport function serveDev(\n\tserver: ViteDevServer,\n\tentry: string | undefined,\n): () => void {\n\tbridgeSockets(server.httpServer, {\n\t\tproxy: server.config.server.proxy,\n\t\tload: () => loadApp(server, entry),\n\t\tlogger: server.config.logger,\n\t\tfix: (error) => server.ssrFixStacktrace(error),\n\t});\n\treturn () => {\n\t\tserver.middlewares.use((req, res, next) => {\n\t\t\tserveFromEntry(server, entry, req, res).catch((error: unknown) => {\n\t\t\t\tif (error instanceof Error) server.ssrFixStacktrace(error);\n\t\t\t\tnext(error);\n\t\t\t});\n\t\t});\n\t};\n}\n",
12
- "/**\n * Under `vite preview`, and React Router's prerendering, which runs on it:\n * every request goes to the built server, `build/server/index.js`'s\n * default export, as `bun build/server/index.js` would answer it — its\n * middlewares, its `/api`, the client's files and the pages.\n */\nimport { existsSync } from 'node:fs';\nimport { relative } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { PreviewServer } from 'vite';\nimport { serverBuildPath } from './config';\nimport type { DevApp } from './dev';\nimport { NAME } from './entry';\nimport { send, toRequest } from './node';\nimport { bridgeSockets } from './socket';\n\n/** What the built server's default export is: the alxia app. */\ninterface Fetcher {\n\tfetch(request: Request): Response | Promise<Response>;\n}\n\n/** The built server's app, or an error saying why there is none. */\nasync function load(file: string, label: string): Promise<Fetcher> {\n\tif (!existsSync(file)) {\n\t\tthrow new Error(\n\t\t\t`${NAME}: ${label} does not exist. Run react-router build before vite preview.`,\n\t\t);\n\t}\n\tconst module = (await import(pathToFileURL(file).href)) as {\n\t\treadonly default?: Partial<Fetcher>;\n\t};\n\tif (typeof module.default?.fetch !== 'function') {\n\t\tthrow new Error(\n\t\t\t`${NAME}: ${label} is not alxia's server: its default export has no fetch. Build it with alxia() in vite.config.ts's plugins, then run vite preview again.`,\n\t\t);\n\t}\n\treturn module.default as Fetcher;\n}\n\n/**\n * Hands every request to the built server, before Vite's own files: the\n * app serves `build/client` itself, with its middlewares and cache headers. Its\n * WebSocket routes connect too, relayed as under `react-router dev`.\n */\nexport function servePreview(server: PreviewServer): void {\n\tconst file = serverBuildPath(server.config);\n\tconst label = relative(server.config.root, file);\n\t// Loaded on the first request, as `bun build/server/index.js` would be\n\t// at startup; a failed load is tried again on the next, after a build.\n\tlet app: Promise<Fetcher> | undefined;\n\tconst current = (): Promise<Fetcher> => {\n\t\tapp ??= load(file, label);\n\t\treturn app;\n\t};\n\tbridgeSockets(server.httpServer, {\n\t\tproxy: server.config.preview.proxy,\n\t\t// The built server's default export is the alxia app, `websocket` and all.\n\t\tload: () =>\n\t\t\tcurrent().catch((error: unknown) => {\n\t\t\t\tapp = undefined;\n\t\t\t\tthrow error;\n\t\t\t}) as Promise<DevApp>,\n\t\tlogger: server.config.logger,\n\t});\n\tserver.middlewares.use((req, res, next) => {\n\t\tcurrent().then(\n\t\t\tasync (loaded) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait send(res, await loaded.fetch(toRequest(req, res)));\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Mid-body, the response has started: end it rather than answer twice.\n\t\t\t\t\tif (res.headersSent) res.destroy(error as Error);\n\t\t\t\t\telse next(error);\n\t\t\t\t}\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tapp = undefined;\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tserver.config.logger.error(message);\n\t\t\t\tres.statusCode = 500;\n\t\t\t\tres.setHeader('content-type', 'text/plain; charset=utf-8');\n\t\t\t\tres.end(message);\n\t\t\t},\n\t\t);\n\t});\n}\n",
10
+ "/**\n * Under `react-router dev` and `vite preview`: the app's WebSocket routes. Vite's server is a\n * `node:http` one, and an alxia socket is `Bun.serve`'s upgrade, so each\n * upgrade Vite leaves is relayed, bytes as they come, to a `Bun.serve` of\n * the app's own on a loopback port: its middlewares, its validation, its socket\n * handlers, exactly as `listen` runs them.\n */\nimport type { IncomingMessage } from 'node:http';\nimport { connect, type Socket } from 'node:net';\nimport type { DevApp } from './dev';\nimport { NAME } from './entry';\n\n/** The subprotocols of Vite's own socket, the HMR one and its ping: Vite answers them. */\nconst VITE = new Set(['vite-hmr', 'vite-ping']);\n\n/** Whether the upgrade asks for Vite's own socket. */\nexport function isVites(req: Pick<IncomingMessage, 'headers'>): boolean {\n\tconst protocols = req.headers['sec-websocket-protocol'];\n\tif (protocols === undefined) return false;\n\treturn protocols.split(',').some((protocol) => VITE.has(protocol.trim()));\n}\n\n/** One entry of Vite's `server.proxy`, as far as its sockets go. */\ntype ProxyEntry = string | { readonly ws?: boolean; readonly target?: unknown };\n\n/**\n * Whether Vite's `server.proxy` relays this upgrade itself: an entry whose\n * context matches the URL, as Vite matches it (`^…` a RegExp, otherwise a\n * prefix), and that proxies sockets (`ws: true`, or a `ws:`/`wss:` target).\n */\nexport function isProxied(\n\turl: string,\n\tproxy: Readonly<Record<string, ProxyEntry>> | undefined,\n): boolean {\n\tfor (const [context, entry] of Object.entries(proxy ?? {})) {\n\t\tconst matches =\n\t\t\t(context.startsWith('^') && new RegExp(context).test(url)) ||\n\t\t\turl.startsWith(context);\n\t\tif (!matches) continue;\n\t\tconst options = typeof entry === 'string' ? { target: entry } : entry;\n\t\tconst target = String(options.target ?? '');\n\t\tif (\n\t\t\toptions.ws === true ||\n\t\t\ttarget.startsWith('ws:') ||\n\t\t\ttarget.startsWith('wss:')\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/** The request line and headers of `req`, as they came: what the side server reads. */\nexport function head(\n\treq: Pick<IncomingMessage, 'method' | 'url' | 'rawHeaders'>,\n): string {\n\tconst lines = [`${req.method ?? 'GET'} ${req.url ?? '/'} HTTP/1.1`];\n\tconst raw = req.rawHeaders;\n\tfor (let i = 0; i + 1 < raw.length; i += 2) {\n\t\tlines.push(`${raw[i]}: ${raw[i + 1]}`);\n\t}\n\treturn `${lines.join('\\r\\n')}\\r\\n\\r\\n`;\n}\n\n/** The side servers: the current app's, and those an edit retired, until their sockets close. */\nexport interface Sides {\n\tcurrent:\n\t\t| { readonly app: DevApp; readonly side: Bun.Server<unknown> }\n\t\t| undefined;\n\treadonly retired: Set<Bun.Server<unknown>>;\n}\n\n/**\n * The side server of `app`, started on its first upgrade. A new app, an\n * edit's, retires the previous one: no new connection, and the sockets open\n * on it stay, with the handlers they opened with, until they close.\n */\nexport function sideFor(sides: Sides, app: DevApp): Bun.Server<unknown> {\n\tif (sides.current?.app === app) return sides.current.side;\n\tconst side = Bun.serve({\n\t\tport: 0,\n\t\thostname: '127.0.0.1',\n\t\tfetch: (request, bun) => app.fetch(request, bun),\n\t\twebsocket: app.websocket,\n\t} as Bun.Serve.Options<never>) as Bun.Server<unknown>;\n\tconst old = sides.current?.side;\n\tif (old !== undefined) {\n\t\tsides.retired.add(old);\n\t\tvoid old.stop().then(() => sides.retired.delete(old));\n\t}\n\tsides.current = { app, side };\n\treturn side;\n}\n\n/** Stops every side server, open sockets and all: Vite's server closed. */\nexport function closeAll(sides: Sides): void {\n\tfor (const side of [...sides.retired, sides.current?.side]) {\n\t\tvoid side?.stop(true);\n\t}\n\tsides.current = undefined;\n\tsides.retired.clear();\n}\n\n/** Relays the upgrade on `socket` to the side server on `port`, both ways. */\nfunction relay(\n\treq: IncomingMessage,\n\tsocket: Socket,\n\tbytes: Buffer,\n\tport: number,\n): void {\n\tconst upstream = connect(port, '127.0.0.1', () => {\n\t\tupstream.write(head(req));\n\t\tif (bytes.length > 0) upstream.write(bytes);\n\t\tupstream.pipe(socket);\n\t\tsocket.pipe(upstream);\n\t});\n\tupstream.on('error', () => socket.destroy());\n\tupstream.on('close', () => socket.destroy());\n\tsocket.on('close', () => upstream.destroy());\n}\n\n/** The side server of an app, which its sockets are open on: what `bridgeSockets` returns. */\nexport type SideOf = (app: DevApp) => Bun.Server<unknown> | undefined;\n\n/** What the relay listens to on Vite's HTTP server, HTTP/1 or HTTP/2 alike. */\ninterface Upgrades {\n\ton(\n\t\tevent: 'upgrade',\n\t\tlistener: (req: IncomingMessage, socket: Socket, bytes: Buffer) => void,\n\t): unknown;\n\tonce(event: 'close', listener: () => void): unknown;\n}\n\n/** What the relay needs of the server it listens on: Vite's dev server or its preview. */\nexport interface Bridge {\n\t/** Vite's `server.proxy` (or `preview.proxy`): the upgrades it relays are its own. */\n\treadonly proxy: Readonly<Record<string, ProxyEntry>> | undefined;\n\t/** The app, as it is now. */\n\treadonly load: () => Promise<DevApp>;\n\t/** Where an upgrade that failed is printed: Vite's logger. */\n\treadonly logger: { error(message: string): void };\n\t/** Maps an error's stack to the source, as Vite's `ssrFixStacktrace` does. */\n\treadonly fix?: (error: Error) => void;\n}\n\n/** An upgrade the app could not take: reported, and a 500 to the client. */\nfunction refuse(bridge: Bridge, socket: Socket, error: unknown): void {\n\tif (error instanceof Error) bridge.fix?.(error);\n\tbridge.logger.error(\n\t\t`${NAME}: a WebSocket upgrade failed: ${error instanceof Error ? (error.stack ?? error.message) : String(error)}`,\n\t);\n\tif (socket.writable) {\n\t\tsocket.end(\n\t\t\t'HTTP/1.1 500 Internal Server Error\\r\\nConnection: close\\r\\nContent-Length: 0\\r\\n\\r\\n',\n\t\t);\n\t}\n}\n\n/**\n * Relays the app's upgrades on Vite's HTTP server to a side server of the\n * app. Vite's own socket and the sockets its proxy relays are left to\n * Vite. Without an HTTP server (Vite's middleware mode), there is nothing\n * to listen on.\n *\n * Returns the side server of an app, for its HTTP requests' `ctx.server`:\n * the server its sockets are open on, so that a `publish` from a loader or\n * an action reaches them. `undefined` in middleware mode, and once Vite's\n * server closed.\n */\nexport function bridgeSockets(http: Upgrades | null, bridge: Bridge): SideOf {\n\tif (http === null) return () => undefined;\n\tconst sides: Sides = { current: undefined, retired: new Set() };\n\tlet closed = false;\n\thttp.on('upgrade', (req: IncomingMessage, socket: Socket, bytes: Buffer) => {\n\t\tif (isVites(req) || isProxied(req.url ?? '/', bridge.proxy)) return;\n\t\tsocket.on('error', () => socket.destroy());\n\t\tbridge\n\t\t\t.load()\n\t\t\t.then((app) => {\n\t\t\t\tif (socket.destroyed) return;\n\t\t\t\trelay(req, socket, bytes, sideFor(sides, app).port as number);\n\t\t\t})\n\t\t\t.catch((error: unknown) => refuse(bridge, socket, error));\n\t});\n\thttp.once('close', () => {\n\t\tclosed = true;\n\t\tcloseAll(sides);\n\t});\n\treturn (app) => (closed ? undefined : sideFor(sides, app));\n}\n",
11
+ "/**\n * Under `react-router dev`: a request Vite left, answered by the server,\n * loaded through the ssr environment's module runner.\n */\nimport type { ViteDevServer } from 'vite';\nimport { DEFAULT, SERVER, serverFile } from './config';\nimport { NAME } from './entry';\nimport { send, toRequest } from './node';\nimport { bridgeSockets, type SideOf } from './socket';\n\n/** What the dev server module exports: the alxia app, as `server.create` made it. */\nexport interface DevApp {\n\tfetch(request: Request, server?: Bun.Server<unknown>): Promise<Response>;\n\treadonly websocket: Bun.WebSocketHandler<never>;\n}\n\n/**\n * The app, as the server file is now: the runner keeps the module until an\n * edit invalidates it, so an edit is a new app.\n */\nexport async function loadApp(\n\tserver: ViteDevServer,\n\tentry: string | undefined,\n): Promise<DevApp> {\n\t// Duck-typed rather than Vite's `isRunnableDevEnvironment`: the app's\n\t// Vite may be another copy than the one this package would import.\n\tconst runner = (\n\t\tserver.environments.ssr as\n\t\t\t| { readonly runner?: { readonly import?: unknown } }\n\t\t\t| undefined\n\t)?.runner;\n\tif (typeof runner?.import !== 'function') {\n\t\tthrow new Error(\n\t\t\t`${NAME}: Vite's ssr environment does not run modules in this process, so the server cannot be loaded.`,\n\t\t);\n\t}\n\t// Chosen on each request: a server file created or deleted while the\n\t// dev server runs is used from the next one.\n\tconst id = serverFile(entry, server.config) === undefined ? DEFAULT : SERVER;\n\tconst module = (await (runner.import as (id: string) => Promise<unknown>)(\n\t\tid,\n\t)) as { readonly default: DevApp };\n\treturn module.default;\n}\n\n/**\n * One request Vite left, answered by the app as the server file is now,\n * given the side server its sockets are open on as `ctx.server`.\n */\nexport async function serveFromEntry(\n\tserver: ViteDevServer,\n\tentry: string | undefined,\n\tsideOf: SideOf,\n\treq: Parameters<typeof toRequest>[0],\n\tres: Parameters<typeof toRequest>[1],\n): Promise<void> {\n\tconst app = await loadApp(server, entry);\n\tawait send(res, await app.fetch(toRequest(req, res), sideOf(app)));\n}\n\n/**\n * `react-router dev`: the app's sockets on Vite's server now, and, returned\n * for after Vite's own middlewares, every request Vite leaves to the app.\n */\nexport function serveDev(\n\tserver: ViteDevServer,\n\tentry: string | undefined,\n): () => void {\n\tconst sideOf = bridgeSockets(server.httpServer, {\n\t\tproxy: server.config.server.proxy,\n\t\tload: () => loadApp(server, entry),\n\t\tlogger: server.config.logger,\n\t\tfix: (error) => server.ssrFixStacktrace(error),\n\t});\n\treturn () => {\n\t\tserver.middlewares.use((req, res, next) => {\n\t\t\tserveFromEntry(server, entry, sideOf, req, res).catch(\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tif (error instanceof Error) server.ssrFixStacktrace(error);\n\t\t\t\t\tnext(error);\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t};\n}\n",
12
+ "/**\n * Under `vite preview`, and React Router's prerendering, which runs on it:\n * every request goes to the built server, `build/server/index.js`'s\n * default export, as `bun build/server/index.js` would answer it — its\n * middlewares, its `/api`, the client's files and the pages.\n */\nimport { existsSync } from 'node:fs';\nimport { relative } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { PreviewServer } from 'vite';\nimport { serverBuildPath } from './config';\nimport type { DevApp } from './dev';\nimport { NAME } from './entry';\nimport { send, toRequest } from './node';\nimport { bridgeSockets } from './socket';\n\n/** What the built server's default export is: the alxia app. */\ninterface Fetcher {\n\tfetch(\n\t\trequest: Request,\n\t\tserver?: Bun.Server<unknown>,\n\t): Response | Promise<Response>;\n}\n\n/** The built server's app, or an error saying why there is none. */\nasync function load(file: string, label: string): Promise<Fetcher> {\n\tif (!existsSync(file)) {\n\t\tthrow new Error(\n\t\t\t`${NAME}: ${label} does not exist. Run react-router build before vite preview.`,\n\t\t);\n\t}\n\tconst module = (await import(pathToFileURL(file).href)) as {\n\t\treadonly default?: Partial<Fetcher>;\n\t};\n\tif (typeof module.default?.fetch !== 'function') {\n\t\tthrow new Error(\n\t\t\t`${NAME}: ${label} is not alxia's server: its default export has no fetch. Build it with alxia() in vite.config.ts's plugins, then run vite preview again.`,\n\t\t);\n\t}\n\treturn module.default as Fetcher;\n}\n\n/**\n * Hands every request to the built server, before Vite's own files: the\n * app serves `build/client` itself, with its middlewares and cache headers. Its\n * WebSocket routes connect too, relayed as under `react-router dev`.\n */\nexport function servePreview(server: PreviewServer): void {\n\tconst file = serverBuildPath(server.config);\n\tconst label = relative(server.config.root, file);\n\t// Loaded on the first request, as `bun build/server/index.js` would be\n\t// at startup; a failed load is tried again on the next, after a build.\n\tlet app: Promise<Fetcher> | undefined;\n\tconst current = (): Promise<Fetcher> => {\n\t\tapp ??= load(file, label);\n\t\treturn app;\n\t};\n\tconst sideOf = bridgeSockets(server.httpServer, {\n\t\tproxy: server.config.preview.proxy,\n\t\t// The built server's default export is the alxia app, `websocket` and all.\n\t\tload: () =>\n\t\t\tcurrent().catch((error: unknown) => {\n\t\t\t\tapp = undefined;\n\t\t\t\tthrow error;\n\t\t\t}) as Promise<DevApp>,\n\t\tlogger: server.config.logger,\n\t});\n\tserver.middlewares.use((req, res, next) => {\n\t\tcurrent().then(\n\t\t\tasync (loaded) => {\n\t\t\t\ttry {\n\t\t\t\t\t// The side server its sockets are open on, as `ctx.server`:\n\t\t\t\t\t// the built app, `websocket` and all, as `load` above reads it.\n\t\t\t\t\tconst side = sideOf(loaded as DevApp);\n\t\t\t\t\tawait send(res, await loaded.fetch(toRequest(req, res), side));\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Mid-body, the response has started: end it rather than answer twice.\n\t\t\t\t\tif (res.headersSent) res.destroy(error as Error);\n\t\t\t\t\telse next(error);\n\t\t\t\t}\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tapp = undefined;\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tserver.config.logger.error(message);\n\t\t\t\tres.statusCode = 500;\n\t\t\t\tres.setHeader('content-type', 'text/plain; charset=utf-8');\n\t\t\t\tres.end(message);\n\t\t\t},\n\t\t);\n\t});\n}\n",
13
13
  "import { NAME } from './entry';\n\n/**\n * Refuses, with what to do, a dev or preview server running on Node. The\n * React Router CLI's `#!/usr/bin/env node` runs it on Node whenever a node\n * is installed, even from `bun run dev`, and alxia's server then fails on\n * its first request with `ReferenceError: Bun is not defined`.\n */\nexport function requireBun(\n\tcommand: string,\n\thint = `bun --bun ${command}`,\n\tonBun = (globalThis as { Bun?: unknown }).Bun !== undefined,\n): void {\n\tif (onBun) return;\n\tthrow new Error(\n\t\t`${NAME}: ${command} is running on Node, and alxia's server runs on Bun. Add a bunfig.toml beside package.json with \"[run]\" and \"bun = true\", so bun run starts it on Bun, or run it as ${hint}.`,\n\t);\n}\n"
14
14
  ],
15
- "mappings": "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",
16
- "debugId": "66D983950B07D2DC64756E2164756E21",
15
+ "mappings": "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",
16
+ "debugId": "090F44FD671492F864756E2164756E21",
17
17
  "names": []
18
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/vite/preview.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AA8B1C;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAyCxD"}
1
+ {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/vite/preview.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAiC1C;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CA4CxD"}
@@ -39,6 +39,8 @@ export interface Sides {
39
39
  export declare function sideFor(sides: Sides, app: DevApp): Bun.Server<unknown>;
40
40
  /** Stops every side server, open sockets and all: Vite's server closed. */
41
41
  export declare function closeAll(sides: Sides): void;
42
+ /** The side server of an app, which its sockets are open on: what `bridgeSockets` returns. */
43
+ export type SideOf = (app: DevApp) => Bun.Server<unknown> | undefined;
42
44
  /** What the relay listens to on Vite's HTTP server, HTTP/1 or HTTP/2 alike. */
43
45
  interface Upgrades {
44
46
  on(event: 'upgrade', listener: (req: IncomingMessage, socket: Socket, bytes: Buffer) => void): unknown;
@@ -62,7 +64,12 @@ export interface Bridge {
62
64
  * app. Vite's own socket and the sockets its proxy relays are left to
63
65
  * Vite. Without an HTTP server (Vite's middleware mode), there is nothing
64
66
  * to listen on.
67
+ *
68
+ * Returns the side server of an app, for its HTTP requests' `ctx.server`:
69
+ * the server its sockets are open on, so that a `publish` from a loader or
70
+ * an action reaches them. `undefined` in middleware mode, and once Vite's
71
+ * server closed.
65
72
  */
66
- export declare function bridgeSockets(http: Upgrades | null, bridge: Bridge): void;
73
+ export declare function bridgeSockets(http: Upgrades | null, bridge: Bridge): SideOf;
67
74
  export {};
68
75
  //# sourceMappingURL=socket.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../src/vite/socket.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAMpC,sDAAsD;AACtD,wBAAgB,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,GAAG,OAAO,CAItE;AAED,oEAAoE;AACpE,KAAK,UAAU,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhF;;;;GAIG;AACH,wBAAgB,SAAS,CACxB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,GACrD,OAAO,CAiBT;AAED,uFAAuF;AACvF,wBAAgB,IAAI,CACnB,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,KAAK,GAAG,YAAY,CAAC,GACzD,MAAM,CAOR;AAED,iGAAiG;AACjG,MAAM,WAAW,KAAK;IACrB,OAAO,EACJ;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;KAAE,GAC5D,SAAS,CAAC;IACb,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;CAC3C;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAetE;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAM3C;AAoBD,+EAA+E;AAC/E,UAAU,QAAQ;IACjB,EAAE,CACD,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACrE,OAAO,CAAC;IACX,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;CACpD;AAED,0FAA0F;AAC1F,MAAM,WAAW,MAAM;IACtB,sFAAsF;IACtF,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC;IACjE,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAClD,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACtC;AAeD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAezE"}
1
+ {"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../src/vite/socket.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAMpC,sDAAsD;AACtD,wBAAgB,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,GAAG,OAAO,CAItE;AAED,oEAAoE;AACpE,KAAK,UAAU,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhF;;;;GAIG;AACH,wBAAgB,SAAS,CACxB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,GACrD,OAAO,CAiBT;AAED,uFAAuF;AACvF,wBAAgB,IAAI,CACnB,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,KAAK,GAAG,YAAY,CAAC,GACzD,MAAM,CAOR;AAED,iGAAiG;AACjG,MAAM,WAAW,KAAK;IACrB,OAAO,EACJ;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;KAAE,GAC5D,SAAS,CAAC;IACb,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;CAC3C;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAetE;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAM3C;AAoBD,8FAA8F;AAC9F,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;AAEtE,+EAA+E;AAC/E,UAAU,QAAQ;IACjB,EAAE,CACD,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACrE,OAAO,CAAC;IACX,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;CACpD;AAED,0FAA0F;AAC1F,MAAM,WAAW,MAAM;IACtB,sFAAsF;IACtF,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC;IACjE,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAClD,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACtC;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAoB3E"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * `withAlxia(fn)`: a loader, an action or a middleware handed the alxia
3
+ * context as `alxia`, typed even under the generated `Route.*Args`.
4
+ */
5
+ import type { AnyAlxia } from '@alxia/core';
6
+ import { type AlxiaContextOf, type ProviderLike, type RegisteredApp } from './context';
7
+ import type { ReactRouterServer } from './server';
8
+ /**
9
+ * What `withAlxia` adds to React Router's arguments: `alxia`, what
10
+ * `alxiaOf<App>(context)` returns. Typed by `Register` by default; name a
11
+ * server, `AlxiaArgs<typeof server>`, as `alxiaOf<typeof server>` does.
12
+ */
13
+ export interface AlxiaArgs<App extends AnyAlxia | ReactRouterServer<AnyAlxia> = RegisteredApp> {
14
+ readonly alxia: AlxiaContextOf<App>;
15
+ }
16
+ /**
17
+ * A loader, an action or a middleware given `alxia`, the alxia context, beside
18
+ * React Router's arguments. Annotate the parameter as the generated arguments
19
+ * and `AlxiaArgs`:
20
+ *
21
+ * ```ts
22
+ * export const loader = withAlxia(({ alxia, params }: Route.LoaderArgs & AlxiaArgs) => {
23
+ * return { name: alxia.user?.name ?? null, id: params.id };
24
+ * });
25
+ * ```
26
+ *
27
+ * It returns a function of React Router's arguments alone (`Args` without
28
+ * `alxia`), with `fn`'s return type, so `useLoaderData<typeof loader>` and `Route.ComponentProps` read what
29
+ * `fn` returns. A middleware's `next` is passed on. Throws `alxiaOf`'s error
30
+ * on a request that did not come through `reactRouter()`.
31
+ */
32
+ export declare function withAlxia<Args extends {
33
+ readonly alxia: unknown;
34
+ readonly context: ProviderLike;
35
+ }, Rest extends unknown[], Result>(fn: (args: Args, ...rest: Rest) => Result): (args: Omit<Args, 'alxia'>, ...rest: Rest) => Result;
36
+ //# sourceMappingURL=with-alxia.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-alxia.d.ts","sourceRoot":"","sources":["../src/with-alxia.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACN,KAAK,cAAc,EAEnB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD;;;;GAIG;AACH,MAAM,WAAW,SAAS,CACzB,GAAG,SAAS,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC,GAAG,aAAa;IAElE,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;CACpC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAGxB,IAAI,SAAS;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,EACxE,IAAI,SAAS,OAAO,EAAE,EACtB,MAAM,EAEN,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,GACvC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAGtD"}
package/docs/guide.md CHANGED
@@ -157,9 +157,10 @@ routes. The server is loaded through Vite's SSR runner, so:
157
157
  - **alxia's `ws` routes connect**: an upgrade Vite's HMR does not claim
158
158
  goes to the app, as from the build. See [WebSockets](#websockets).
159
159
 
160
- HTTP requests reach the app through `app.fetch`, as in a test, not
161
- through `listen`. So `page()` and an HTTP request's `ctx.server` are
162
- absent in dev; see [the troubleshooting entry](troubleshooting.md#ctxserver-is-undefined-under-react-router-dev).
160
+ HTTP requests reach the app through `app.fetch`, not through `listen`,
161
+ given the loopback server the sockets are relayed to as `ctx.server`
162
+ ([The server](#the-server-server)). So `page()` is not served in dev; see
163
+ [the troubleshooting entry](troubleshooting.md#a-page-is-not-served-under-react-router-dev).
163
164
 
164
165
  ### In a build
165
166
 
@@ -582,7 +583,57 @@ for what is believed and what is valid.
582
583
 
583
584
  Every request through the catch-all sets `alxiaContext`, this package's
584
585
  key, on React Router's context provider, to what alxia's middlewares built for
585
- that request. `alxiaOf(context)` reads it.
586
+ that request. Three forms read it, each the same object:
587
+
588
+ - **`withAlxia(fn)`**, for a route typed by the generated `Route.*Args`:
589
+ `fn` gets `alxia` beside React Router's arguments;
590
+ - **`alxiaOf(context)`**, inside a plain function, and with a type argument;
591
+ - **`context.alxia`**, where the arguments are typed with `react-router`'s
592
+ own `LoaderFunctionArgs` and `ActionFunctionArgs`
593
+ ([below](#the-shorthand-contextalxia)).
594
+
595
+ ### `withAlxia(fn)`
596
+
597
+ ```ts
598
+ // app/routes/account.tsx
599
+ import { type AlxiaArgs, withAlxia } from '@alxia/react-router';
600
+ import { redirect } from 'react-router';
601
+ import type { Route } from './+types/account';
602
+
603
+ export const loader = withAlxia(({ alxia, params }: Route.LoaderArgs & AlxiaArgs) => {
604
+ if (alxia.user === null) throw redirect('/login');
605
+ return { name: alxia.user.name, tab: params.tab ?? 'profile' };
606
+ });
607
+ // The page's Route.ComponentProps['loaderData']: { name: string; tab: string }
608
+ ```
609
+
610
+ Annotate `fn`'s parameter as the generated arguments and `AlxiaArgs`:
611
+ `AlxiaArgs` is `{ alxia }`, typed by `Register`, and `AlxiaArgs<typeof server>`
612
+ names a server where nothing is registered. `withAlxia` returns a function of
613
+ React Router's arguments alone, with `fn`'s return type, so the generated
614
+ `loaderData` and `actionData`, and `useLoaderData<typeof loader>`, read what
615
+ `fn` returns. An action is written the same way; a middleware too, and its
616
+ `next` is passed on:
617
+
618
+ ```ts
619
+ import { type AlxiaArgs, withAlxia } from '@alxia/react-router';
620
+ import type { Route } from './+types/admin';
621
+
622
+ export const middleware: Route.MiddlewareFunction[] = [
623
+ withAlxia(async ({ alxia }: Parameters<Route.MiddlewareFunction>[0] & AlxiaArgs, next) => {
624
+ alxia.log.info('admin');
625
+ return next();
626
+ }),
627
+ ];
628
+ ```
629
+
630
+ Why a wrapper: `context.alxia` cannot be typed under the generated
631
+ arguments ([below](#the-shorthand-contextalxia)), and a wrapper that adds a
632
+ key is the one form TypeScript infers from the annotation alone. A type
633
+ argument, `withAlxia<Route.LoaderArgs>(fn)`, would fix the arguments but
634
+ stop TypeScript inferring `fn`'s return type, since it infers no type
635
+ argument once one is given: the page's `loaderData` would be lost. On a request that did not come
636
+ through alxia it throws what `alxiaOf` throws.
586
637
 
587
638
  ### With `Register`: no type argument
588
639
 
@@ -714,11 +765,81 @@ both folders of a monorepo), their two declarations conflict, and `tsc`
714
765
  says so (`Subsequent property declarations must have the same type`).
715
766
  Give each app its own tsconfig, or use the type argument in both.
716
767
 
768
+ ### The server: `server`
769
+
770
+ `alxiaOf(context).server` is core's `ctx.server`, the `Bun.Server` serving
771
+ the request, `undefined` with none
772
+ ([Serving](https://github.com/softistx/alxia/blob/develop/packages/core/docs/guide/serving.md#the-server-ctxserver)).
773
+ It is not `Register`'s `server`, which names what `createServer()` returned
774
+ for the types. From an action, its `publish` reaches the app's
775
+ [WebSocket](#websockets) subscribers:
776
+
777
+ ```ts
778
+ // app/routes/todos.tsx
779
+ import { alxiaOf } from '@alxia/react-router';
780
+ import type { Route } from './+types/todos';
781
+
782
+ export async function action({ request, context }: Route.ActionArgs) {
783
+ const title = String((await request.formData()).get('title'));
784
+ // Bun's own publish: the bytes as given, not checked by a socket's `send` schema.
785
+ alxiaOf(context).server?.publish('todos', JSON.stringify({ added: title }));
786
+ return { added: title };
787
+ }
788
+ ```
789
+
790
+ What it is, by how the app runs:
791
+
792
+ | | `alxiaOf(context).server` |
793
+ | --- | --- |
794
+ | `bun build/server/index.js`, `server.start(app)`, `app.listen()` | the server `listen` started |
795
+ | `react-router dev`, `vite preview` | the `Bun.Server` on a loopback port that the plugin relays the app's sockets to (Vite's own server is `node:http`, not a `Bun.Server`): `publish` reaches every socket the app opened, its `url` is that port's, and `requestIP` and `timeout` know nothing of the request Vite took, so `ctx.ip` stays `undefined` there |
796
+ | Vite in middleware mode, a server of your own calling `app.fetch(request)` alone, `app.request(…)` in a test | `undefined` |
797
+
798
+ ### The shorthand: `context.alxia`
799
+
800
+ This package augments React Router's `RouterContextProvider` with a
801
+ read-only `alxia` property: the object `alxiaOf(context)` returns, with no
802
+ import and no call, typed by the same `Register` (core's, then
803
+ `BaseContext`, with none of this package's):
804
+
805
+ ```ts
806
+ import type { ActionFunctionArgs, LoaderFunctionArgs } from 'react-router';
807
+
808
+ export function loader({ context }: LoaderFunctionArgs) {
809
+ const { user, server } = context.alxia;
810
+ return { name: user?.name ?? 'anonymous', listening: server !== undefined };
811
+ }
812
+
813
+ export async function action({ context }: ActionFunctionArgs) {
814
+ context.alxia.server?.publish('todos', JSON.stringify({ changed: true }));
815
+ return { ok: true };
816
+ }
817
+ ```
818
+
819
+ **Typed with react-router's own argument types, not yet the generated
820
+ ones.** `LoaderFunctionArgs`, `ActionFunctionArgs`, `MiddlewareFunction` and
821
+ `RouterContextProvider`, imported from `react-router`, see `alxia`. The
822
+ generated `Route.LoaderArgs` does not: the `+types` files import from
823
+ `react-router/internal`, whose types (in react-router 8.4) point at its
824
+ `dist/development` build, while `react-router` itself points at
825
+ `dist/production`. That is a second declaration of `RouterContextProvider`,
826
+ which no exported path reaches, so no package can augment it. With
827
+ `Route.LoaderArgs`, `context.alxia` works at runtime and `tsc` reports
828
+ TS2339 ([Troubleshooting](troubleshooting.md#property-alxia-does-not-exist-on-type-readonlyroutercontextprovider)):
829
+ use `withAlxia` (or `alxiaOf(context)`) there, until react-router ships one declaration.
830
+
831
+ It is a getter on the provider's prototype that reads `alxiaContext`: it
832
+ holds exactly when that key is set, in dev as in production, and on a
833
+ provider no catch-all filled it throws what `alxiaOf` throws. It is the
834
+ server's alone: a `clientLoader` or a `clientAction` has no alxia context.
835
+
717
836
  ### Outside the catch-all
718
837
 
719
838
  Without the plugin, under a plain `react-router dev`, or in a unit test
720
839
  that calls a loader with a bare provider, there is no alxia context, and
721
- `alxiaOf` throws, saying so: see
840
+ `alxiaOf` and `context.alxia` throw, saying so. The getter is installed
841
+ when `@alxia/react-router` is first imported: a test whose program never
842
+ imports it reads `context.alxia` as `undefined`. See
722
843
  [the troubleshooting entry](troubleshooting.md#alxiaof-this-request-has-no-alxia-context-).
723
844
 
724
845
  ## The app's own context keys
@@ -1083,7 +1204,7 @@ leaves Vite's own socket alone: an upgrade asking for the `vite-hmr` or
1083
1204
  upgrade, except one Vite's `server.proxy` relays itself (an entry with
1084
1205
  `ws: true` or a `ws:` target, matched as Vite matches it), is relayed,
1085
1206
  byte for byte, to a `Bun.serve` of the app on a loopback port of its
1086
- own, started on the first upgrade and given
1207
+ own, started on the first upgrade or the first request and given
1087
1208
  `app.fetch` and `app.websocket`, as `listen` gives them. So in dev:
1088
1209
 
1089
1210
  - **The same middlewares, refusals and handlers run** as from the build:
@@ -1096,6 +1217,9 @@ own, started on the first upgrade and given
1096
1217
  - **A `publish` reaches the sockets opened since the same edit**: the
1097
1218
  sockets opened before it are on the previous server. Reload the pages
1098
1219
  after an edit to reconnect them.
1220
+ - **A loader's or an action's `alxiaOf(context).server` is that loopback
1221
+ server**, the one the sockets are on, so its `publish` reaches them as
1222
+ from the build: see [The server](#the-server-server).
1099
1223
  - **A socket's `ctx.ip` is the loopback address**, the relay's. The
1100
1224
  browser is local in dev, so that is usually its address anyway.
1101
1225
  - **An upgrade to a path with no `ws` route** gets what the build answers
@@ -1217,6 +1341,12 @@ Router's entry waits for the whole page before it answers a bot, so a test
1217
1341
  with Bun's own user agent never sees a page stream. An index route's action
1218
1342
  is `POST /?index`, not `POST /`.
1219
1343
 
1344
+ `app.request` runs without a server, so a loader's `alxiaOf(context).server`
1345
+ is `undefined` there, and a `publish` it guards with `?.` sends nothing.
1346
+ To test one, listen on a free port, `app.listen({ port: 0 })`, open the
1347
+ socket, then post to the action (`/todos.data`, the single-fetch URL, for
1348
+ its data rather than the page).
1349
+
1220
1350
  ## Deploying
1221
1351
 
1222
1352
  Run `bun run build`, then `bun build/server/index.js`. The build is
package/docs/roadmap.md CHANGED
@@ -7,20 +7,7 @@ number on it. Every release, with each change it made, is in
7
7
 
8
8
  ## Now
9
9
 
10
- - **Middlewares around the pages.** `beforeAll` and `configure` take
11
- `use(logger())`, `use(secureHeaders())` and the other middlewares of
12
- alxia 0.4, which run on the pages, the client's files declared after
13
- them, and every request no route matches; the request hooks they replaced,
14
- deprecated in 0.4, were removed in 0.5.
15
- - **Loaders typed by core's `Register`.** `alxiaOf(context)` reads the base
16
- `@alxia/core`'s `Register` names when this package's names no server, so
17
- an app that registers its context once types its loaders too. This
18
- package's `Register` still wins when both are declared.
19
- - **One graceful shutdown.** `start` relies on `@alxia/core`'s `listen`,
20
- which handles `SIGINT` and `SIGTERM` itself, before `onListen` as
21
- before: the requests in flight drain within `shutdownTimeout`
22
- (`listen: { shutdownTimeout }`), readiness turns 503, the `onStop`
23
- hooks run, then the process exits.
10
+ Nothing in progress.
24
11
 
25
12
  ## Next
26
13
 
@@ -28,9 +15,12 @@ Nothing scheduled yet.
28
15
 
29
16
  ## Later
30
17
 
31
- - **`ctx.server` under `react-router dev`.** An HTTP request reaches the
32
- app through `app.fetch`, so `ctx.server` and `page()` wait for the build;
33
- a socket's upgrade already has its server.
18
+ - **`context.alxia` typed under `Route.LoaderArgs`.** Once react-router's
19
+ `./internal` types and its main entry share one `RouterContextProvider`
20
+ declaration, the generated route types see the shorthand too; today
21
+ they use `withAlxia` or `alxiaOf(context)`.
22
+ - **`page()` under `react-router dev`.** An HTTP request reaches the app
23
+ through `app.fetch`, so a Bun HTML bundle waits for the build.
34
24
  - **The logger's duration of a streamed page**, to its last byte rather
35
25
  than its first.
36
26
  - **A React Router `basename`**, the app served under a path.
@@ -58,6 +48,19 @@ Nothing scheduled yet.
58
48
 
59
49
  ## Shipped
60
50
 
51
+ ### 0.8.0
52
+
53
+ - **`withAlxia(fn)`.** A loader, an action or a middleware given `alxia`,
54
+ typed by `Register`, under the generated `Route.LoaderArgs`, with the
55
+ page's `loaderData` still inferred from what it returns.
56
+ - **`context.alxia`.** The object `alxiaOf(context)` returns, on React
57
+ Router's provider with no import, typed by `Register` with
58
+ `LoaderFunctionArgs` and `ActionFunctionArgs` from `react-router`;
59
+ `alxiaOf(context)` stays the form for the generated `Route.LoaderArgs`.
60
+ - **`ctx.server` in dev.** Under `react-router dev` and `vite preview`, a
61
+ loader's `alxiaOf(context).server` is the server the app's sockets are
62
+ relayed to, so an action's `publish` reaches them as from the build.
63
+
61
64
  ### 0.7.0
62
65
 
63
66
  - **The public URL behind a proxy.** `createServer({ proxy: trustProxy({ trusted }) })`,
@@ -66,6 +69,26 @@ Nothing scheduled yet.
66
69
  trusted proxy said, and `ctx.ip` the client's; a direct client's
67
70
  forwarded headers are ignored.
68
71
 
72
+ ### 0.6.0
73
+
74
+ - **Middlewares around the pages.** `beforeAll` and `configure` take
75
+ `use(logger())`, `use(secureHeaders())` and the other middlewares of
76
+ alxia 0.4, which run on the pages, the client's files declared after
77
+ them, and every request no route matches; the request hooks they replaced,
78
+ deprecated in 0.4, were removed in 0.5.
79
+ - **One graceful shutdown.** `start` relies on `@alxia/core`'s `listen`,
80
+ which handles `SIGINT` and `SIGTERM` itself, before `onListen` as
81
+ before: the requests in flight drain within `shutdownTimeout`
82
+ (`listen: { shutdownTimeout }`), readiness turns 503, the `onStop`
83
+ hooks run, then the process exits.
84
+
85
+ ### 0.5.0
86
+
87
+ - **Loaders typed by core's `Register`.** `alxiaOf(context)` reads the base
88
+ `@alxia/core`'s `Register` names when this package's names no server, so
89
+ an app that registers its context once types its loaders too. This
90
+ package's `Register` still wins when both are declared.
91
+
69
92
  ### 0.4.0
70
93
 
71
94
  - **A self-contained build.** `react-router build` bundles every package