@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.
- package/README.md +92 -14
- package/dist/context.d.ts +32 -2
- package/dist/context.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -5
- package/dist/index.js.map +7 -6
- package/dist/nonce.d.ts +2 -2
- package/dist/nonce.d.ts.map +1 -1
- package/dist/vite/dev.d.ts +6 -1
- package/dist/vite/dev.d.ts.map +1 -1
- package/dist/vite/index.js +17 -9
- package/dist/vite/index.js.map +5 -5
- package/dist/vite/preview.d.ts.map +1 -1
- package/dist/vite/socket.d.ts +8 -1
- package/dist/vite/socket.d.ts.map +1 -1
- package/dist/with-alxia.d.ts +36 -0
- package/dist/with-alxia.d.ts.map +1 -0
- package/docs/guide.md +136 -6
- package/docs/roadmap.md +40 -17
- package/docs/troubleshooting.md +89 -16
- package/package.json +5 -5
package/dist/vite/index.js.map
CHANGED
|
@@ -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):
|
|
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\
|
|
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(
|
|
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": "
|
|
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;
|
|
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"}
|
package/dist/vite/socket.d.ts
CHANGED
|
@@ -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):
|
|
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
|
|
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`,
|
|
161
|
-
|
|
162
|
-
|
|
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.
|
|
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`
|
|
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
|
-
|
|
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
|
-
- **`
|
|
32
|
-
|
|
33
|
-
|
|
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
|