@dunx/http 0.1.0 → 0.1.1

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/dist/index.js.map CHANGED
@@ -2,33 +2,33 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/route/marker.ts", "../src/route/decorators.ts", "../src/route/metadata.ts", "../src/route/discover.ts", "../src/server/client-address.ts", "../src/server/context.ts", "../src/server/status.ts", "../src/server/cors.ts", "../src/server/errors.ts", "../src/server/factory.ts", "../src/ws/envelope.ts", "../src/ws/runtime.ts", "../src/ws/marker.ts", "../src/ws/adapter.ts", "../src/ws/discover.ts", "../src/ws/pubsub.ts", "../src/ws/relay.ts", "../src/server/application.ts", "../src/server/request-logging.ts", "../src/server/routes.ts", "../src/server/input.ts", "../src/server/middleware.ts", "../src/server/settings.ts", "../src/ws/decorators.ts", "../src/ws/redis-relay.ts"],
4
4
  "sourcesContent": [
5
- "// Symbol.for, so two copies of @dunx/http in a tree still agree on the key. The\n// marker goes on the method function itself nothing accumulates at class\n// definition time, so there is no ordering dependence and no cross-file leak.\n// See docs/ARCHITECTURE.md, \"Route discovery\".\nimport type { RouteSchemas } from './schema.js';\n\nconst ROUTE = Symbol.for('dunx.route');\nconst CONTROLLER = Symbol.for('dunx.controller');\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\nexport interface RouteMeta {\n readonly method: HttpMethod;\n readonly path: string;\n /** The decorator's second argument. `buildRoutes` resolves it once, at boot. */\n readonly options?: RouteSchemas | undefined;\n}\n\ninterface RouteMarked {\n readonly [ROUTE]?: RouteMeta;\n}\n\ninterface ControllerMarked {\n readonly [CONTROLLER]?: string;\n}\n\nexport const markRoute = (target: object, meta: RouteMeta): void => {\n Object.defineProperty(target, ROUTE, { value: meta, configurable: true });\n};\n\nexport const routeMetaOf = (value: unknown): RouteMeta | undefined =>\n typeof value === 'function' ? (value as RouteMarked)[ROUTE] : undefined;\n\nexport const markController = (target: object, prefix: string): void => {\n Object.defineProperty(target, CONTROLLER, {\n value: prefix,\n configurable: true,\n });\n};\n\n// Plain lookup, not Object.hasOwn: a subclass inherits its base's prefix, so two\n// subclasses of one decorated base collide loudly instead of silently mounting at\n// the root.\nexport const prefixOf = (target: object): string =>\n (target as ControllerMarked)[CONTROLLER] ?? '';\n",
6
- "import { markController, markRoute, type HttpMethod } from './marker.js';\nimport type { Input, RouteSchemas } from './schema.js';\n\ntype ControllerTarget = abstract new (...args: never[]) => object;\n\nexport const Controller =\n (prefix = '') =>\n <T extends ControllerTarget>(target: T): T => {\n markController(target, prefix);\n return target;\n };\n\n/**\n * `const O` is load-bearing: without it `{ body: CreateNote, status: 201 }` widens\n * to `RouteSchemas` and `Input<typeof opts>` degrades to bare `{ req }`, taking the\n * type check with it.\n *\n * The `M` constraint is the guarantee. A wrongly annotated `input` is a\n * `TS1241` + `TS1270` naming the mismatched property; an unannotated one is\n * `TS7006`. Inference is impossible here see docs/ARCHITECTURE.md, \"A route\n * decorator can *check* a handler's input type but cannot *infer* it\".\n */\nconst verb =\n (method: HttpMethod) =>\n <const O extends RouteSchemas>(path = '/', options?: O) =>\n <M extends (input: Input<O>) => unknown>(\n value: M,\n _context: ClassMethodDecoratorContext,\n ): M => {\n markRoute(value, { method, path, options });\n return value;\n };\n\nexport const Get = verb('GET');\nexport const Post = verb('POST');\nexport const Put = verb('PUT');\nexport const Patch = verb('PATCH');\nexport const Delete = verb('DELETE');\n",
7
- "// The same technique as marker.ts: a decorator sets a symbol property on the\n// function or the class it receives and returns it. Nothing accumulates at class\n// definition time, so there is no ordering dependence and no cross-file leak.\n// See docs/ARCHITECTURE.md, \"Route discovery\".\nimport type { Ctor } from '@dunx/core';\nimport type { Middleware } from '../server/middleware.js';\n\n// Symbol.for for the two storage slots, so two copies of @dunx/http in one tree\n// still read each other's records. The keys themselves are unique see metaKey.\nconst META = Symbol.for('dunx.meta');\nconst GUARDS = Symbol.for('dunx.guards');\n\n/** What a route's decorators resolved to, keyed by `MetaKey.id`. */\nexport type MetaRecord = ReadonlyMap<symbol, unknown>;\n\nexport interface MetaKey<T> {\n /** For error messages and debugging only. Identity is the symbol. */\n readonly name: string;\n readonly id: symbol;\n // Phantom. Never assigned it exists so MetaKey<readonly string[]> and\n // MetaKey<boolean> are distinct types rather than both being { name, id }.\n readonly reads?: T;\n}\n\n/**\n * A fresh unique symbol per call, so two libraries that both name a key `roles`\n * never read each other's value. Two `metaKey('roles')` calls are two keys.\n */\nexport const metaKey = <T>(name: string): MetaKey<T> => ({\n name,\n id: Symbol(name),\n});\n\ninterface MetaMarked {\n readonly [META]?: MetaRecord;\n}\n\ninterface GuardMarked {\n readonly [GUARDS]?: readonly Ctor<Middleware>[];\n}\n\n/**\n * Copy-on-write, defined as an **own** property. The seed is read with plain\n * lookup, so a subclass starts from its base's record but the base's Map is\n * never mutated, which is what keeps two subclasses of one base independent.\n */\nconst write = <T>(target: object, key: MetaKey<T>, value: T): void => {\n const record = new Map<symbol, unknown>((target as MetaMarked)[META]);\n record.set(key.id, value);\n Object.defineProperty(target, META, { value: record, configurable: true });\n};\n\n/**\n * The generic setter, valid on a method or on a class. `@Roles` and `@Public` are\n * thin wrappers over it; a user's own key needs nothing else.\n */\nexport const meta =\n <T>(key: MetaKey<T>, value: T) =>\n <F extends object>(target: F): F => {\n write(target, key, value);\n return target;\n };\n\nexport const ROLES: MetaKey<readonly string[]> = metaKey('roles');\nexport const PUBLIC: MetaKey<boolean> = metaKey('public');\n\nexport const Roles = (...roles: readonly string[]) => meta(ROLES, roles);\nexport const Public = () => meta(PUBLIC, true);\n\n/**\n * Guards are middleware, so they compose rather than override which is why they\n * are not a `MetaKey`. Valid on a method or on a class.\n */\nexport const UseGuards =\n (...guards: readonly Ctor<Middleware>[]) =>\n <F extends object>(target: F): F => {\n const existing = (target as GuardMarked)[GUARDS] ?? [];\n // An own record means a second @UseGuards on the same target: decorators apply\n // bottom-up, so the later-applied one goes in front and the list reads\n // top-to-bottom. An inherited one means a subclass, whose guards run after\n // the base's and defineProperty leaves the base's array untouched.\n const merged = Object.hasOwn(target, GUARDS)\n ? [...guards, ...existing]\n : [...existing, ...guards];\n Object.defineProperty(target, GUARDS, {\n value: merged,\n configurable: true,\n });\n return target;\n };\n\nexport const guardsOf = (target: object): readonly Ctor<Middleware>[] =>\n (target as GuardMarked)[GUARDS] ?? [];\n\nexport const metaOf = (target: object): MetaRecord | undefined =>\n (target as MetaMarked)[META];\n\n/**\n * Later targets win, so `mergeMeta(klass, handler)` is the handler-then-class\n * resolution `RouteContext.get` exposes. Called once per route at boot.\n */\nexport const mergeMeta = (...targets: readonly object[]): MetaRecord => {\n const merged = new Map<symbol, unknown>();\n for (const target of targets) {\n const record = (target as MetaMarked)[META];\n if (record) for (const [id, value] of record) merged.set(id, value);\n }\n return merged;\n};\n",
5
+ "// Symbol.for, so two copies of @dunx/http in a tree still agree on the key. The\n// marker goes on the method function itself - nothing accumulates at class\n// definition time, so there is no ordering dependence and no cross-file leak.\n// See docs/ARCHITECTURE.md, \"Route discovery\".\nimport type { RouteSchemas } from './schema.js';\n\nconst ROUTE = Symbol.for('dunx.route');\nconst CONTROLLER = Symbol.for('dunx.controller');\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\nexport interface RouteMeta {\n readonly method: HttpMethod;\n readonly path: string;\n /** The decorator's second argument. `buildRoutes` resolves it once, at boot. */\n readonly options?: RouteSchemas | undefined;\n}\n\ninterface RouteMarked {\n readonly [ROUTE]?: RouteMeta;\n}\n\ninterface ControllerMarked {\n readonly [CONTROLLER]?: string;\n}\n\nexport const markRoute = (target: object, meta: RouteMeta): void => {\n Object.defineProperty(target, ROUTE, { value: meta, configurable: true });\n};\n\nexport const routeMetaOf = (value: unknown): RouteMeta | undefined =>\n typeof value === 'function' ? (value as RouteMarked)[ROUTE] : undefined;\n\nexport const markController = (target: object, prefix: string): void => {\n Object.defineProperty(target, CONTROLLER, {\n value: prefix,\n configurable: true,\n });\n};\n\n// Plain lookup, not Object.hasOwn: a subclass inherits its base's prefix, so two\n// subclasses of one decorated base collide loudly instead of silently mounting at\n// the root.\nexport const prefixOf = (target: object): string =>\n (target as ControllerMarked)[CONTROLLER] ?? '';\n",
6
+ "import { markController, markRoute, type HttpMethod } from './marker.js';\nimport type { Input, RouteSchemas } from './schema.js';\n\ntype ControllerTarget = abstract new (...args: never[]) => object;\n\nexport const Controller =\n (prefix = '') =>\n <T extends ControllerTarget>(target: T): T => {\n markController(target, prefix);\n return target;\n };\n\n/**\n * `const O` is load-bearing: without it `{ body: CreateNote, status: 201 }` widens\n * to `RouteSchemas` and `Input<typeof opts>` degrades to bare `{ req }`, taking the\n * type check with it.\n *\n * The `M` constraint is the guarantee. A wrongly annotated `input` is a\n * `TS1241` + `TS1270` naming the mismatched property; an unannotated one is\n * `TS7006`. Inference is impossible here - see docs/ARCHITECTURE.md, \"A route\n * decorator can *check* a handler's input type but cannot *infer* it\".\n */\nconst verb =\n (method: HttpMethod) =>\n <const O extends RouteSchemas>(path = '/', options?: O) =>\n <M extends (input: Input<O>) => unknown>(\n value: M,\n _context: ClassMethodDecoratorContext,\n ): M => {\n markRoute(value, { method, path, options });\n return value;\n };\n\nexport const Get = verb('GET');\nexport const Post = verb('POST');\nexport const Put = verb('PUT');\nexport const Patch = verb('PATCH');\nexport const Delete = verb('DELETE');\n",
7
+ "// The same technique as marker.ts: a decorator sets a symbol property on the\n// function or the class it receives and returns it. Nothing accumulates at class\n// definition time, so there is no ordering dependence and no cross-file leak.\n// See docs/ARCHITECTURE.md, \"Route discovery\".\nimport type { Ctor } from '@dunx/core';\nimport type { Middleware } from '../server/middleware.js';\n\n// Symbol.for for the two storage slots, so two copies of @dunx/http in one tree\n// still read each other's records. The keys themselves are unique - see metaKey.\nconst META = Symbol.for('dunx.meta');\nconst GUARDS = Symbol.for('dunx.guards');\n\n/** What a route's decorators resolved to, keyed by `MetaKey.id`. */\nexport type MetaRecord = ReadonlyMap<symbol, unknown>;\n\nexport interface MetaKey<T> {\n /** For error messages and debugging only. Identity is the symbol. */\n readonly name: string;\n readonly id: symbol;\n // Phantom. Never assigned - it exists so MetaKey<readonly string[]> and\n // MetaKey<boolean> are distinct types rather than both being { name, id }.\n readonly reads?: T;\n}\n\n/**\n * A fresh unique symbol per call, so two libraries that both name a key `roles`\n * never read each other's value. Two `metaKey('roles')` calls are two keys.\n */\nexport const metaKey = <T>(name: string): MetaKey<T> => ({\n name,\n id: Symbol(name),\n});\n\ninterface MetaMarked {\n readonly [META]?: MetaRecord;\n}\n\ninterface GuardMarked {\n readonly [GUARDS]?: readonly Ctor<Middleware>[];\n}\n\n/**\n * Copy-on-write, defined as an **own** property. The seed is read with plain\n * lookup, so a subclass starts from its base's record - but the base's Map is\n * never mutated, which is what keeps two subclasses of one base independent.\n */\nconst write = <T>(target: object, key: MetaKey<T>, value: T): void => {\n const record = new Map<symbol, unknown>((target as MetaMarked)[META]);\n record.set(key.id, value);\n Object.defineProperty(target, META, { value: record, configurable: true });\n};\n\n/**\n * The generic setter, valid on a method or on a class. `@Roles` and `@Public` are\n * thin wrappers over it; a user's own key needs nothing else.\n */\nexport const meta =\n <T>(key: MetaKey<T>, value: T) =>\n <F extends object>(target: F): F => {\n write(target, key, value);\n return target;\n };\n\nexport const ROLES: MetaKey<readonly string[]> = metaKey('roles');\nexport const PUBLIC: MetaKey<boolean> = metaKey('public');\n\nexport const Roles = (...roles: readonly string[]) => meta(ROLES, roles);\nexport const Public = () => meta(PUBLIC, true);\n\n/**\n * Guards are middleware, so they compose rather than override - which is why they\n * are not a `MetaKey`. Valid on a method or on a class.\n */\nexport const UseGuards =\n (...guards: readonly Ctor<Middleware>[]) =>\n <F extends object>(target: F): F => {\n const existing = (target as GuardMarked)[GUARDS] ?? [];\n // An own record means a second @UseGuards on the same target: decorators apply\n // bottom-up, so the later-applied one goes in front and the list reads\n // top-to-bottom. An inherited one means a subclass, whose guards run after\n // the base's - and defineProperty leaves the base's array untouched.\n const merged = Object.hasOwn(target, GUARDS)\n ? [...guards, ...existing]\n : [...existing, ...guards];\n Object.defineProperty(target, GUARDS, {\n value: merged,\n configurable: true,\n });\n return target;\n };\n\nexport const guardsOf = (target: object): readonly Ctor<Middleware>[] =>\n (target as GuardMarked)[GUARDS] ?? [];\n\nexport const metaOf = (target: object): MetaRecord | undefined =>\n (target as MetaMarked)[META];\n\n/**\n * Later targets win, so `mergeMeta(klass, handler)` is the handler-then-class\n * resolution `RouteContext.get` exposes. Called once per route at boot.\n */\nexport const mergeMeta = (...targets: readonly object[]): MetaRecord => {\n const merged = new Map<symbol, unknown>();\n for (const target of targets) {\n const record = (target as MetaMarked)[META];\n if (record) for (const [id, value] of record) merged.set(id, value);\n }\n return merged;\n};\n",
8
8
  "import type { Ctor } from '@dunx/core';\nimport type { Middleware } from '../server/middleware.js';\nimport { prefixOf, routeMetaOf, type HttpMethod } from './marker.js';\nimport { guardsOf, mergeMeta, type MetaRecord } from './metadata.js';\nimport type { RouteInput, RouteSchemas } from './schema.js';\n\nexport interface DiscoveredRoute {\n readonly method: HttpMethod;\n readonly path: string;\n readonly controller: string;\n readonly handlerName: string;\n readonly handler: (input: RouteInput) => unknown;\n /** Schemas and status from the decorator, carried through to `buildRoutes`. */\n readonly options?: RouteSchemas | undefined;\n /** The class's metadata merged under the handler's, which wins. Resolved here, once. */\n readonly meta?: MetaRecord | undefined;\n /** Class-level `@UseGuards` first, then method-level. `buildRoutes` resolves them. */\n readonly guards?: readonly Ctor<Middleware>[] | undefined;\n}\n\nexport const joinPath = (prefix: string, path: string): string => {\n const joined = `/${prefix}/${path}`.replace(/\\/{2,}/g, '/');\n return joined.length > 1 ? joined.replace(/\\/$/, '') : '/';\n};\n\n/**\n * Walks the prototype chain of a constructed controller and collects every marked\n * method. Most-derived wins on a repeated name; an undecorated override does not\n * shadow its decorated base, and dispatch still lands on the override because the\n * handler is bound off the instance.\n */\nexport const discoverRoutes = (\n instance: object,\n): readonly DiscoveredRoute[] => {\n const klass = instance.constructor;\n const prefix = prefixOf(klass);\n const classGuards = guardsOf(klass);\n const members = instance as Record<string, (input: RouteInput) => unknown>;\n const routes: DiscoveredRoute[] = [];\n const seen = new Set<string>();\n\n for (\n let proto = Object.getPrototypeOf(instance) as object | null;\n proto !== null && proto !== Object.prototype;\n proto = Object.getPrototypeOf(proto) as object | null\n ) {\n for (const [name, descriptor] of Object.entries(\n Object.getOwnPropertyDescriptors(proto),\n )) {\n if (name === 'constructor' || seen.has(name)) continue;\n\n const meta = routeMetaOf(descriptor.value);\n if (!meta) continue;\n\n seen.add(name);\n // The marked function, not the instance member: a decorator wrote onto this\n // object, and it is the only place its metadata can have come from.\n const marked = descriptor.value as object;\n routes.push({\n method: meta.method,\n path: joinPath(prefix, meta.path),\n controller: klass.name,\n handlerName: name,\n handler: members[name]!.bind(instance),\n options: meta.options,\n meta: mergeMeta(klass, marked),\n guards: [...classGuards, ...guardsOf(marked)],\n });\n }\n }\n\n return routes;\n};\n",
9
9
  "import type { BunRequest, Server } from 'bun';\nimport { AppError } from '@dunx/core';\n\nexport interface AddressSource {\n readonly server: Server<unknown>;\n readonly trustProxy: boolean;\n}\n\n// Kept off the class so `ClientAddress`'s public shape stays `of(req)`. Per\n// instance rather than module-level, because two apps in one process (every test\n// file) must not share a server.\nconst sources = new WeakMap<ClientAddress, AddressSource>();\n\n/**\n * The client's address, honouring the `'trust proxy'` setting. Every class is\n * injectable, so `inject(ClientAddress)` in a middleware or controller needs no\n * registration; `app.clientIp(req)` is the same instance.\n */\nexport class ClientAddress {\n of(req: BunRequest): string | undefined {\n const source = sources.get(this);\n if (!source) {\n throw new AppError(\n 'ClientAddress has no server yet. The address comes from the live Bun ' +\n 'server, so it is only available once listen() has run.',\n );\n }\n\n if (source.trustProxy) {\n const forwarded = req.headers\n .get('x-forwarded-for')\n ?.split(',')[0]\n ?.trim();\n if (forwarded) return forwarded;\n }\n return source.server.requestIP(req)?.address;\n }\n}\n\n/** Internal: `listen()` hands the bound server to the resolved singleton. */\nexport const attachAddressSource = (\n target: ClientAddress,\n source: AddressSource,\n): void => {\n sources.set(target, source);\n};\n",
10
- "import type { DiscoveredRoute } from '../route/discover.js';\nimport type { HttpMethod } from '../route/marker.js';\nimport type { MetaKey, MetaRecord } from '../route/metadata.js';\n\n/**\n * Which route the middleware is running for, and what that route's decorators\n * declared. `get` resolves the handler's metadata first and the controller class's\n * second the same override direction as Nest's `getAllAndOverride`.\n */\nexport interface RouteContext {\n readonly controller: string;\n readonly handler: string;\n readonly method: HttpMethod;\n readonly path: string;\n get<T>(key: MetaKey<T>): T | undefined;\n}\n\nconst EMPTY: MetaRecord = new Map();\n\n/**\n * One frozen context per route, built when the table is built and closed over by\n * the chain. The merge already happened at discovery, so `get` is a Map lookup —\n * not a prototype walk, and nothing is read per request.\n */\nexport const buildContext = (route: DiscoveredRoute): RouteContext => {\n const record = route.meta ?? EMPTY;\n return Object.freeze({\n controller: route.controller,\n handler: route.handlerName,\n method: route.method,\n path: route.path,\n get: <T>(key: MetaKey<T>): T | undefined =>\n record.get(key.id) as T | undefined,\n });\n};\n",
11
- "/**\n * Frozen object plus an indexed-access union, not an `enum`. An enum emits a\n * runtime object that no other syntax can produce, which is why the repo bans it —\n * see CLAUDE.md. This gives the same `HttpStatusCode.NOT_FOUND` ergonomics, a\n * narrower type, and erases cleanly.\n */\nexport const HttpStatusCode = Object.freeze({\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n GONE: 410,\n PRECONDITION_FAILED: 412,\n PAYLOAD_TOO_LARGE: 413,\n URI_TOO_LONG: 414,\n UNSUPPORTED_MEDIA_TYPE: 415,\n IM_A_TEAPOT: 418,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n} as const);\n\n/** The status numbers: `200 | 201 | ...`. */\nexport type HttpStatusCode =\n (typeof HttpStatusCode)[keyof typeof HttpStatusCode];\n\n/** The names: `'OK' | 'CREATED' | ...`. */\nexport type HttpStatusName = keyof typeof HttpStatusCode;\n",
12
- "import type { RouteHandler } from './middleware.js';\nimport { HttpStatusCode } from './status.js';\n\nexport type CorsOrigin =\n | string\n | readonly string[]\n | ((origin: string) => boolean);\n\nexport interface CorsOptions {\n /**\n * `'*'` by default. A concrete string, a list, or a predicate all answer with the\n * caller's own origin only when it is allowed a request from anywhere else gets\n * no CORS headers at all, which is what makes the browser block it.\n */\n readonly origin?: CorsOrigin;\n /** Defaults to the methods actually declared on the path. */\n readonly methods?: readonly string[];\n /** Echoes `Access-Control-Request-Headers` when omitted. */\n readonly allowedHeaders?: readonly string[];\n readonly exposedHeaders?: readonly string[];\n readonly credentials?: boolean;\n /** Seconds a browser may cache the preflight for. */\n readonly maxAge?: number;\n}\n\nconst ORIGIN = 'access-control-allow-origin';\n\n/**\n * `*` is illegal alongside credentials a browser rejects the pair so a\n * credentialed wildcard reflects the caller instead.\n */\nconst allowedOrigin = (\n options: CorsOptions,\n requested: string | null,\n): string | undefined => {\n const origin = options.origin ?? '*';\n\n if (typeof origin === 'string') {\n if (origin !== '*') return origin === requested ? origin : undefined;\n if (!options.credentials) return '*';\n return requested ?? undefined;\n }\n if (requested === null) return undefined;\n\n const allowed =\n typeof origin === 'function'\n ? origin(requested)\n : origin.includes(requested);\n return allowed ? requested : undefined;\n};\n\nconst applyCors = (\n options: CorsOptions,\n req: Request,\n response: Response,\n): Response => {\n const origin = allowedOrigin(options, req.headers.get('origin'));\n if (origin === undefined) return response;\n\n response.headers.set(ORIGIN, origin);\n // The response body varies by request origin unless every origin gets the same\n // wildcard, so a shared cache must not serve one origin's copy to another.\n if (origin !== '*') response.headers.append('vary', 'Origin');\n if (options.credentials) {\n response.headers.set('access-control-allow-credentials', 'true');\n }\n if (options.exposedHeaders?.length) {\n response.headers.set(\n 'access-control-expose-headers',\n options.exposedHeaders.join(', '),\n );\n }\n return response;\n};\n\n/** Adds the response-side CORS headers. One extra closure per route, at boot. */\nexport const withCors = (\n options: CorsOptions,\n handler: RouteHandler,\n): RouteHandler => {\n return async (req) => applyCors(options, req, await handler(req));\n};\n\n/**\n * `Bun.serve({ routes })` answers a method miss with 404, so a preflight cannot be\n * inferred every CORS-enabled path gets its own `OPTIONS` handler, built at boot\n * from the methods that path actually declares.\n */\nexport const preflight = (\n options: CorsOptions,\n methods: readonly string[],\n): RouteHandler => {\n const allowMethods = (options.methods ?? methods).join(', ');\n\n return async (req) => {\n const response = applyCors(\n options,\n req,\n new Response(null, { status: HttpStatusCode.NO_CONTENT }),\n );\n // Origin not allowed: 204 with no CORS headers, which fails the preflight.\n if (!response.headers.has(ORIGIN)) return response;\n\n response.headers.set('access-control-allow-methods', allowMethods);\n\n const allowHeaders =\n options.allowedHeaders ??\n (req.headers.get('access-control-request-headers') ?? '')\n .split(',')\n .map((header) => header.trim())\n .filter((header) => header.length > 0);\n if (allowHeaders.length > 0) {\n response.headers.set(\n 'access-control-allow-headers',\n allowHeaders.join(', '),\n );\n }\n if (options.maxAge !== undefined) {\n response.headers.set('access-control-max-age', String(options.maxAge));\n }\n return response;\n };\n};\n",
13
- "import { AppError } from '@dunx/core';\nimport { HttpStatusCode } from './status.js';\n\nexport class HttpError extends AppError {\n override name = 'HttpError';\n\n constructor(\n readonly status: number,\n message: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n }\n}\nObject.defineProperty(HttpError, Symbol.for('dunx.deps'), {\n value: () => [{ unresolved: \"readonly status: number\" }, { unresolved: \"message: string\" }, ErrorOptions],\n});\n\n/** Which declared schema rejected the request. */\nexport type InputSource = 'body' | 'query' | 'params';\n\n/** A Standard Schema issue, flattened: `path` is dotted, or absent at the root. */\nexport interface ValidationIssue {\n readonly message: string;\n readonly path?: string;\n}\n\n/**\n * A declared schema rejected the input. Always a 400, and the issues survive into\n * the response body a caller cannot fix what it cannot see.\n */\nexport class ValidationError extends HttpError {\n override name = 'ValidationError';\n\n constructor(\n readonly source: InputSource,\n readonly issues: readonly ValidationIssue[],\n ) {\n super(HttpStatusCode.BAD_REQUEST, `Invalid ${source}`);\n }\n}\nObject.defineProperty(ValidationError, Symbol.for('dunx.deps'), {\n value: () => [{ unresolved: \"readonly source: InputSource\" }, { unresolved: \"readonly issues: readonly ValidationIssue[]\" }],\n});\n\nexport type ErrorMapper = (error: unknown, req: Request) => Response;\n\nexport const defaultErrorMapper: ErrorMapper = (error) => {\n if (error instanceof ValidationError) {\n return Response.json(\n { error: error.message, status: error.status, issues: error.issues },\n { status: error.status },\n );\n }\n if (error instanceof HttpError) {\n return Response.json(\n { error: error.message, status: error.status },\n { status: error.status },\n );\n }\n console.error(error);\n return Response.json(\n {\n error: 'Internal Server Error',\n status: HttpStatusCode.INTERNAL_SERVER_ERROR,\n },\n { status: HttpStatusCode.INTERNAL_SERVER_ERROR },\n );\n};\n",
10
+ "import type { DiscoveredRoute } from '../route/discover.js';\nimport type { HttpMethod } from '../route/marker.js';\nimport type { MetaKey, MetaRecord } from '../route/metadata.js';\n\n/**\n * Which route the middleware is running for, and what that route's decorators\n * declared. `get` resolves the handler's metadata first and the controller class's\n * second - the same override direction as Nest's `getAllAndOverride`.\n */\nexport interface RouteContext {\n readonly controller: string;\n readonly handler: string;\n readonly method: HttpMethod;\n readonly path: string;\n get<T>(key: MetaKey<T>): T | undefined;\n}\n\nconst EMPTY: MetaRecord = new Map();\n\n/**\n * One frozen context per route, built when the table is built and closed over by\n * the chain. The merge already happened at discovery, so `get` is a Map lookup -\n * not a prototype walk, and nothing is read per request.\n */\nexport const buildContext = (route: DiscoveredRoute): RouteContext => {\n const record = route.meta ?? EMPTY;\n return Object.freeze({\n controller: route.controller,\n handler: route.handlerName,\n method: route.method,\n path: route.path,\n get: <T>(key: MetaKey<T>): T | undefined =>\n record.get(key.id) as T | undefined,\n });\n};\n",
11
+ "/**\n * Frozen object plus an indexed-access union, not an `enum`. An enum emits a\n * runtime object that no other syntax can produce, which is why the repo bans it -\n * see CLAUDE.md. This gives the same `HttpStatusCode.NOT_FOUND` ergonomics, a\n * narrower type, and erases cleanly.\n */\nexport const HttpStatusCode = Object.freeze({\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n GONE: 410,\n PRECONDITION_FAILED: 412,\n PAYLOAD_TOO_LARGE: 413,\n URI_TOO_LONG: 414,\n UNSUPPORTED_MEDIA_TYPE: 415,\n IM_A_TEAPOT: 418,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n} as const);\n\n/** The status numbers: `200 | 201 | ...`. */\nexport type HttpStatusCode =\n (typeof HttpStatusCode)[keyof typeof HttpStatusCode];\n\n/** The names: `'OK' | 'CREATED' | ...`. */\nexport type HttpStatusName = keyof typeof HttpStatusCode;\n",
12
+ "import type { RouteHandler } from './middleware.js';\nimport { HttpStatusCode } from './status.js';\n\nexport type CorsOrigin =\n | string\n | readonly string[]\n | ((origin: string) => boolean);\n\nexport interface CorsOptions {\n /**\n * `'*'` by default. A concrete string, a list, or a predicate all answer with the\n * caller's own origin only when it is allowed - a request from anywhere else gets\n * no CORS headers at all, which is what makes the browser block it.\n */\n readonly origin?: CorsOrigin;\n /** Defaults to the methods actually declared on the path. */\n readonly methods?: readonly string[];\n /** Echoes `Access-Control-Request-Headers` when omitted. */\n readonly allowedHeaders?: readonly string[];\n readonly exposedHeaders?: readonly string[];\n readonly credentials?: boolean;\n /** Seconds a browser may cache the preflight for. */\n readonly maxAge?: number;\n}\n\nconst ORIGIN = 'access-control-allow-origin';\n\n/**\n * `*` is illegal alongside credentials - a browser rejects the pair - so a\n * credentialed wildcard reflects the caller instead.\n */\nconst allowedOrigin = (\n options: CorsOptions,\n requested: string | null,\n): string | undefined => {\n const origin = options.origin ?? '*';\n\n if (typeof origin === 'string') {\n if (origin !== '*') return origin === requested ? origin : undefined;\n if (!options.credentials) return '*';\n return requested ?? undefined;\n }\n if (requested === null) return undefined;\n\n const allowed =\n typeof origin === 'function'\n ? origin(requested)\n : origin.includes(requested);\n return allowed ? requested : undefined;\n};\n\nconst applyCors = (\n options: CorsOptions,\n req: Request,\n response: Response,\n): Response => {\n const origin = allowedOrigin(options, req.headers.get('origin'));\n if (origin === undefined) return response;\n\n response.headers.set(ORIGIN, origin);\n // The response body varies by request origin unless every origin gets the same\n // wildcard, so a shared cache must not serve one origin's copy to another.\n if (origin !== '*') response.headers.append('vary', 'Origin');\n if (options.credentials) {\n response.headers.set('access-control-allow-credentials', 'true');\n }\n if (options.exposedHeaders?.length) {\n response.headers.set(\n 'access-control-expose-headers',\n options.exposedHeaders.join(', '),\n );\n }\n return response;\n};\n\n/** Adds the response-side CORS headers. One extra closure per route, at boot. */\nexport const withCors = (\n options: CorsOptions,\n handler: RouteHandler,\n): RouteHandler => {\n return async (req) => applyCors(options, req, await handler(req));\n};\n\n/**\n * `Bun.serve({ routes })` answers a method miss with 404, so a preflight cannot be\n * inferred - every CORS-enabled path gets its own `OPTIONS` handler, built at boot\n * from the methods that path actually declares.\n */\nexport const preflight = (\n options: CorsOptions,\n methods: readonly string[],\n): RouteHandler => {\n const allowMethods = (options.methods ?? methods).join(', ');\n\n return async (req) => {\n const response = applyCors(\n options,\n req,\n new Response(null, { status: HttpStatusCode.NO_CONTENT }),\n );\n // Origin not allowed: 204 with no CORS headers, which fails the preflight.\n if (!response.headers.has(ORIGIN)) return response;\n\n response.headers.set('access-control-allow-methods', allowMethods);\n\n const allowHeaders =\n options.allowedHeaders ??\n (req.headers.get('access-control-request-headers') ?? '')\n .split(',')\n .map((header) => header.trim())\n .filter((header) => header.length > 0);\n if (allowHeaders.length > 0) {\n response.headers.set(\n 'access-control-allow-headers',\n allowHeaders.join(', '),\n );\n }\n if (options.maxAge !== undefined) {\n response.headers.set('access-control-max-age', String(options.maxAge));\n }\n return response;\n };\n};\n",
13
+ "import { AppError } from '@dunx/core';\nimport { HttpStatusCode } from './status.js';\n\nexport class HttpError extends AppError {\n override name = 'HttpError';\n\n constructor(\n readonly status: number,\n message: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n }\n}\nObject.defineProperty(HttpError, Symbol.for('dunx.deps'), {\n value: () => [{ unresolved: \"readonly status: number\" }, { unresolved: \"message: string\" }, ErrorOptions],\n});\n\n/** Which declared schema rejected the request. */\nexport type InputSource = 'body' | 'query' | 'params';\n\n/** A Standard Schema issue, flattened: `path` is dotted, or absent at the root. */\nexport interface ValidationIssue {\n readonly message: string;\n readonly path?: string;\n}\n\n/**\n * A declared schema rejected the input. Always a 400, and the issues survive into\n * the response body - a caller cannot fix what it cannot see.\n */\nexport class ValidationError extends HttpError {\n override name = 'ValidationError';\n\n constructor(\n readonly source: InputSource,\n readonly issues: readonly ValidationIssue[],\n ) {\n super(HttpStatusCode.BAD_REQUEST, `Invalid ${source}`);\n }\n}\nObject.defineProperty(ValidationError, Symbol.for('dunx.deps'), {\n value: () => [{ unresolved: \"readonly source: InputSource\" }, { unresolved: \"readonly issues: readonly ValidationIssue[]\" }],\n});\n\nexport type ErrorMapper = (error: unknown, req: Request) => Response;\n\nexport const defaultErrorMapper: ErrorMapper = (error) => {\n if (error instanceof ValidationError) {\n return Response.json(\n { error: error.message, status: error.status, issues: error.issues },\n { status: error.status },\n );\n }\n if (error instanceof HttpError) {\n return Response.json(\n { error: error.message, status: error.status },\n { status: error.status },\n );\n }\n console.error(error);\n return Response.json(\n {\n error: 'Internal Server Error',\n status: HttpStatusCode.INTERNAL_SERVER_ERROR,\n },\n { status: HttpStatusCode.INTERNAL_SERVER_ERROR },\n );\n};\n",
14
14
  "import {\n collectModules,\n AppError,\n AppFactory,\n Logger,\n provide,\n readControllers,\n RequestContext,\n type DynamicModule,\n type ModuleRef,\n} from '@dunx/core';\nimport { discoverRoutes, type DiscoveredRoute } from '../route/discover.js';\nimport { buildWebSocket } from '../ws/adapter.js';\nimport { discoverGateways } from '../ws/discover.js';\nimport { PubSub } from '../ws/pubsub.js';\nimport {\n HttpApplication,\n type HttpApp,\n type HttpOptions,\n} from './application.js';\nimport { RequestLoggingMiddleware } from './request-logging.js';\nimport { assertNoCollisions } from './routes.js';\n\nexport type { HttpApp, HttpOptions } from './application.js';\n\n// Bound around the user's root so `PubSub` is injectable without importing\n// anything. Its name is what a duplicate binding of PubSub would be reported\n// against, which is why it is a named class and not an object literal.\nclass HttpModule {}\n\nexport class HttpFactory {\n /**\n * Boots the container, discovers every controller's routes and every gateway's\n * handlers, and rejects a collision in either. The `Bun.serve` route table itself\n * is built by `listen()`, so `setGlobalPrefix`, `use`, `set` and `enableCors` can\n * still affect it.\n */\n static async create(\n root: ModuleRef,\n options: HttpOptions = {},\n ): Promise<HttpApp> {\n // Bound here rather than left to self-binding, because its constructor takes\n // the options object as well as two injectables. `Logger` and\n // `RequestContext` always resolve: @dunx/core binds a default for each.\n const logging = provide(RequestLoggingMiddleware, {\n useFactory: (logger: Logger, context: RequestContext) =>\n new RequestLoggingMiddleware(\n logger,\n context,\n typeof options.requestLogging === 'object'\n ? options.requestLogging\n : {},\n ),\n inject: [Logger, RequestContext] as const,\n });\n\n const scope: DynamicModule = {\n module: HttpModule,\n imports: [root],\n providers:\n options.requestLogging === false ? [PubSub] : [PubSub, logging],\n };\n // Spread rather than passed through, because `exactOptionalPropertyTypes`\n // separates an absent `overrides` from one explicitly set to undefined.\n const app = await AppFactory.create(\n scope,\n options.overrides ? { overrides: options.overrides } : {},\n );\n const modules = collectModules(scope);\n\n const discovered: DiscoveredRoute[] = [];\n for (const module of modules) {\n for (const controller of readControllers(module)) {\n const routes = discoverRoutes(app.get(controller) as object);\n if (routes.length === 0) {\n throw new AppError(\n `${controller.name} is registered as a controller but declares no routes. ` +\n 'Add a @Get/@Post/... method, or move it to providers.',\n );\n }\n discovered.push(...routes);\n }\n }\n // Eagerly, so a wiring error still surfaces from create() rather than waiting\n // for listen(). A uniform global prefix cannot introduce a new one.\n assertNoCollisions(discovered);\n\n const gateways = discoverGateways(modules, (token) => app.get(token));\n // Handler collisions and two gateways on one path are boot errors too, and the\n // websocket object is built once here rather than per connection.\n const websocket =\n gateways.length > 0\n ? buildWebSocket(gateways, options.websocket)\n : undefined;\n\n return new HttpApplication(app, discovered, options, websocket);\n }\n}\n",
15
- "/**\n * The whole wire protocol: one JSON object, an event name, and a payload. It is\n * only ever read for a gateway that declares at least one `@OnMessage(event)`\n * handler a gateway with only a raw `@OnMessage()` never parses anything.\n */\nexport interface Envelope {\n readonly event: string;\n readonly data?: unknown;\n}\n\nexport const encode = (event: string, data: unknown): string =>\n JSON.stringify({ event, data });\n\n/**\n * `undefined` for anything that is not an envelope binary frames, invalid JSON,\n * a non-object, or a missing `event`. Those fall through to the raw handler\n * instead of being rejected here.\n */\nexport const decode = (message: string | Buffer): Envelope | undefined => {\n if (typeof message !== 'string') return undefined;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(message);\n } catch {\n return undefined;\n }\n\n if (typeof parsed !== 'object' || parsed === null) return undefined;\n const { event, data } = parsed as { event?: unknown; data?: unknown };\n return typeof event === 'string' ? { event, data } : undefined;\n};\n",
16
- "import { AppError } from '@dunx/core';\nimport type {\n DiscoveredGateway,\n DiscoveredHandler,\n Invoke,\n} from './discover.js';\nimport { HandlerKind } from './marker.js';\n\n/**\n * One gateway reduced to direct references, built once at boot. Dispatch reads\n * these fields and nothing else no lookup, no metadata, no DI per message.\n */\nexport interface GatewayRuntime {\n readonly name: string;\n readonly path: string;\n readonly upgrade: Invoke | undefined;\n readonly open: Invoke | undefined;\n readonly close: Invoke | undefined;\n readonly drain: Invoke | undefined;\n readonly ping: Invoke | undefined;\n readonly pong: Invoke | undefined;\n /** The raw `@OnMessage()` catch-all: every frame no named event claimed. */\n readonly raw: Invoke | undefined;\n readonly events: ReadonlyMap<string, Invoke>;\n}\n\n/** What two handlers would have to share to be a collision. */\nconst slotOf = (handler: DiscoveredHandler): string =>\n handler.kind === HandlerKind.MESSAGE && handler.event !== undefined\n ? `message ${JSON.stringify(handler.event)}`\n : handler.kind;\n\nexport const buildRuntime = (gateway: DiscoveredGateway): GatewayRuntime => {\n if (gateway.handlers.length === 0) {\n throw new AppError(\n `${gateway.name} is registered as a gateway but declares no handlers. ` +\n 'Add an @OnMessage/@OnOpen/... method, or drop the @Gateway decorator.',\n );\n }\n\n const owners = new Map<string, DiscoveredHandler>();\n const events = new Map<string, Invoke>();\n\n for (const handler of gateway.handlers) {\n const slot = slotOf(handler);\n const existing = owners.get(slot);\n if (existing) {\n throw new AppError(\n `Handler collision in ${gateway.name}: ${slot} is claimed by ` +\n `${existing.method}() and by ${handler.method}(). One handler per event.`,\n );\n }\n owners.set(slot, handler);\n if (handler.kind === HandlerKind.MESSAGE && handler.event !== undefined) {\n events.set(handler.event, handler.invoke);\n }\n }\n\n const at = (slot: string): Invoke | undefined => owners.get(slot)?.invoke;\n\n return {\n name: gateway.name,\n path: gateway.path,\n upgrade: at(HandlerKind.UPGRADE),\n open: at(HandlerKind.OPEN),\n close: at(HandlerKind.CLOSE),\n drain: at(HandlerKind.DRAIN),\n ping: at(HandlerKind.PING),\n pong: at(HandlerKind.PONG),\n raw: at(HandlerKind.MESSAGE),\n events,\n };\n};\n\n/**\n * One route per gateway path, so two gateways on one path would mean one of them\n * could never receive a connection. That is a boot error naming both.\n */\nexport const buildGateways = (\n discovered: readonly DiscoveredGateway[],\n): ReadonlyMap<string, GatewayRuntime> => {\n const byPath = new Map<string, GatewayRuntime>();\n\n for (const gateway of discovered) {\n const existing = byPath.get(gateway.path);\n if (existing) {\n throw new AppError(\n `Gateway path collision: ${gateway.path} is served by ${existing.name} ` +\n `and by ${gateway.name}. One gateway per path.`,\n );\n }\n byPath.set(gateway.path, buildRuntime(gateway));\n }\n\n return byPath;\n};\n\nexport const someHandler = (\n gateways: Iterable<GatewayRuntime>,\n pick: (gateway: GatewayRuntime) => Invoke | undefined,\n): boolean => {\n for (const gateway of gateways) if (pick(gateway) !== undefined) return true;\n return false;\n};\n",
17
- "// Symbol.for, so two copies of @dunx/http in a tree still agree on the key. The\n// marker goes on the method function itself nothing accumulates at class\n// definition time, so there is no ordering dependence and no cross-file leak.\n// Same technique as the route marker; see docs/ARCHITECTURE.md,\n// \"Route discovery\".\nconst HANDLER = Symbol.for('dunx.ws.handler');\nconst GATEWAY = Symbol.for('dunx.ws.gateway');\n\nexport const HandlerKind = Object.freeze({\n UPGRADE: 'upgrade',\n OPEN: 'open',\n MESSAGE: 'message',\n CLOSE: 'close',\n DRAIN: 'drain',\n PING: 'ping',\n PONG: 'pong',\n} as const);\nexport type HandlerKind = (typeof HandlerKind)[keyof typeof HandlerKind];\n\nexport interface HandlerMeta {\n readonly kind: HandlerKind;\n /**\n * Only meaningful for a message handler: the envelope event it claims.\n * `undefined` is the raw catch-all that sees every unrouted frame.\n */\n readonly event: string | undefined;\n}\n\ninterface HandlerMarked {\n readonly [HANDLER]?: HandlerMeta;\n}\n\ninterface GatewayMarked {\n readonly [GATEWAY]?: string;\n}\n\nexport const markHandler = (target: object, meta: HandlerMeta): void => {\n Object.defineProperty(target, HANDLER, { value: meta, configurable: true });\n};\n\nexport const handlerMetaOf = (value: unknown): HandlerMeta | undefined =>\n typeof value === 'function' ? (value as HandlerMarked)[HANDLER] : undefined;\n\nexport const markGateway = (target: object, path: string): void => {\n Object.defineProperty(target, GATEWAY, { value: path, configurable: true });\n};\n\n// Plain lookup, not Object.hasOwn: a subclass inherits its base's path, so two\n// subclasses of one decorated base collide loudly instead of silently sharing\n// the root path.\nexport const gatewayPathOf = (target: object): string =>\n (target as GatewayMarked)[GATEWAY] ?? '/';\n\n/**\n * `@Gateway` is what separates a gateway from every other provider in the same\n * module, so unlike `@Controller` it is required rather than decorative.\n */\nexport const isGateway = (target: object): boolean =>\n (target as GatewayMarked)[GATEWAY] !== undefined;\n",
15
+ "/**\n * The whole wire protocol: one JSON object, an event name, and a payload. It is\n * only ever read for a gateway that declares at least one `@OnMessage(event)`\n * handler - a gateway with only a raw `@OnMessage()` never parses anything.\n */\nexport interface Envelope {\n readonly event: string;\n readonly data?: unknown;\n}\n\nexport const encode = (event: string, data: unknown): string =>\n JSON.stringify({ event, data });\n\n/**\n * `undefined` for anything that is not an envelope - binary frames, invalid JSON,\n * a non-object, or a missing `event`. Those fall through to the raw handler\n * instead of being rejected here.\n */\nexport const decode = (message: string | Buffer): Envelope | undefined => {\n if (typeof message !== 'string') return undefined;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(message);\n } catch {\n return undefined;\n }\n\n if (typeof parsed !== 'object' || parsed === null) return undefined;\n const { event, data } = parsed as { event?: unknown; data?: unknown };\n return typeof event === 'string' ? { event, data } : undefined;\n};\n",
16
+ "import { AppError } from '@dunx/core';\nimport type {\n DiscoveredGateway,\n DiscoveredHandler,\n Invoke,\n} from './discover.js';\nimport { HandlerKind } from './marker.js';\n\n/**\n * One gateway reduced to direct references, built once at boot. Dispatch reads\n * these fields and nothing else - no lookup, no metadata, no DI per message.\n */\nexport interface GatewayRuntime {\n readonly name: string;\n readonly path: string;\n readonly upgrade: Invoke | undefined;\n readonly open: Invoke | undefined;\n readonly close: Invoke | undefined;\n readonly drain: Invoke | undefined;\n readonly ping: Invoke | undefined;\n readonly pong: Invoke | undefined;\n /** The raw `@OnMessage()` catch-all: every frame no named event claimed. */\n readonly raw: Invoke | undefined;\n readonly events: ReadonlyMap<string, Invoke>;\n}\n\n/** What two handlers would have to share to be a collision. */\nconst slotOf = (handler: DiscoveredHandler): string =>\n handler.kind === HandlerKind.MESSAGE && handler.event !== undefined\n ? `message ${JSON.stringify(handler.event)}`\n : handler.kind;\n\nexport const buildRuntime = (gateway: DiscoveredGateway): GatewayRuntime => {\n if (gateway.handlers.length === 0) {\n throw new AppError(\n `${gateway.name} is registered as a gateway but declares no handlers. ` +\n 'Add an @OnMessage/@OnOpen/... method, or drop the @Gateway decorator.',\n );\n }\n\n const owners = new Map<string, DiscoveredHandler>();\n const events = new Map<string, Invoke>();\n\n for (const handler of gateway.handlers) {\n const slot = slotOf(handler);\n const existing = owners.get(slot);\n if (existing) {\n throw new AppError(\n `Handler collision in ${gateway.name}: ${slot} is claimed by ` +\n `${existing.method}() and by ${handler.method}(). One handler per event.`,\n );\n }\n owners.set(slot, handler);\n if (handler.kind === HandlerKind.MESSAGE && handler.event !== undefined) {\n events.set(handler.event, handler.invoke);\n }\n }\n\n const at = (slot: string): Invoke | undefined => owners.get(slot)?.invoke;\n\n return {\n name: gateway.name,\n path: gateway.path,\n upgrade: at(HandlerKind.UPGRADE),\n open: at(HandlerKind.OPEN),\n close: at(HandlerKind.CLOSE),\n drain: at(HandlerKind.DRAIN),\n ping: at(HandlerKind.PING),\n pong: at(HandlerKind.PONG),\n raw: at(HandlerKind.MESSAGE),\n events,\n };\n};\n\n/**\n * One route per gateway path, so two gateways on one path would mean one of them\n * could never receive a connection. That is a boot error naming both.\n */\nexport const buildGateways = (\n discovered: readonly DiscoveredGateway[],\n): ReadonlyMap<string, GatewayRuntime> => {\n const byPath = new Map<string, GatewayRuntime>();\n\n for (const gateway of discovered) {\n const existing = byPath.get(gateway.path);\n if (existing) {\n throw new AppError(\n `Gateway path collision: ${gateway.path} is served by ${existing.name} ` +\n `and by ${gateway.name}. One gateway per path.`,\n );\n }\n byPath.set(gateway.path, buildRuntime(gateway));\n }\n\n return byPath;\n};\n\nexport const someHandler = (\n gateways: Iterable<GatewayRuntime>,\n pick: (gateway: GatewayRuntime) => Invoke | undefined,\n): boolean => {\n for (const gateway of gateways) if (pick(gateway) !== undefined) return true;\n return false;\n};\n",
17
+ "// Symbol.for, so two copies of @dunx/http in a tree still agree on the key. The\n// marker goes on the method function itself - nothing accumulates at class\n// definition time, so there is no ordering dependence and no cross-file leak.\n// Same technique as the route marker; see docs/ARCHITECTURE.md,\n// \"Route discovery\".\nconst HANDLER = Symbol.for('dunx.ws.handler');\nconst GATEWAY = Symbol.for('dunx.ws.gateway');\n\nexport const HandlerKind = Object.freeze({\n UPGRADE: 'upgrade',\n OPEN: 'open',\n MESSAGE: 'message',\n CLOSE: 'close',\n DRAIN: 'drain',\n PING: 'ping',\n PONG: 'pong',\n} as const);\nexport type HandlerKind = (typeof HandlerKind)[keyof typeof HandlerKind];\n\nexport interface HandlerMeta {\n readonly kind: HandlerKind;\n /**\n * Only meaningful for a message handler: the envelope event it claims.\n * `undefined` is the raw catch-all that sees every unrouted frame.\n */\n readonly event: string | undefined;\n}\n\ninterface HandlerMarked {\n readonly [HANDLER]?: HandlerMeta;\n}\n\ninterface GatewayMarked {\n readonly [GATEWAY]?: string;\n}\n\nexport const markHandler = (target: object, meta: HandlerMeta): void => {\n Object.defineProperty(target, HANDLER, { value: meta, configurable: true });\n};\n\nexport const handlerMetaOf = (value: unknown): HandlerMeta | undefined =>\n typeof value === 'function' ? (value as HandlerMarked)[HANDLER] : undefined;\n\nexport const markGateway = (target: object, path: string): void => {\n Object.defineProperty(target, GATEWAY, { value: path, configurable: true });\n};\n\n// Plain lookup, not Object.hasOwn: a subclass inherits its base's path, so two\n// subclasses of one decorated base collide loudly instead of silently sharing\n// the root path.\nexport const gatewayPathOf = (target: object): string =>\n (target as GatewayMarked)[GATEWAY] ?? '/';\n\n/**\n * `@Gateway` is what separates a gateway from every other provider in the same\n * module, so unlike `@Controller` it is required rather than decorative.\n */\nexport const isGateway = (target: object): boolean =>\n (target as GatewayMarked)[GATEWAY] !== undefined;\n",
18
18
  "import type { BunRequest, Server, WebSocketHandler } from 'bun';\nimport type { DiscoveredGateway, Invoke } from './discover.js';\nimport { decode, encode } from './envelope.js';\nimport { buildGateways, someHandler, type GatewayRuntime } from './runtime.js';\nimport type {\n Socket,\n SocketData,\n SocketErrorHandler,\n SocketOptions,\n} from './socket.js';\n\n// The gateway a socket belongs to travels with the socket, so dispatch is a\n// property read rather than a path lookup. Symbol-keyed, so it stays out of\n// anything that enumerates `socket.data`.\nconst RUNTIME: unique symbol = Symbol.for('dunx.ws.runtime');\n\ninterface Routed extends SocketData<unknown> {\n readonly [RUNTIME]: GatewayRuntime;\n}\n\n/**\n * A gateway's entry in the server's route table. Returning `undefined` is how Bun\n * is told the socket was upgraded; a `Response` is `426` for a request that was not\n * an upgrade, or whatever `@OnUpgrade` refused with.\n */\nexport type UpgradeHandler = (\n req: BunRequest,\n server: Server<SocketData>,\n) => Response | undefined | Promise<Response | undefined>;\n\n/**\n * Everything the one `Bun.serve` call needs from the websocket side, built once at\n * boot: the handler object, and one native route per gateway path. Nothing here\n * calls `Bun.serve` itself.\n */\nexport interface WebSocketRuntime {\n readonly websocket: WebSocketHandler<SocketData>;\n /** Merged into the HTTP route table by `listen()`, keyed by gateway path. */\n readonly routes: ReadonlyMap<string, UpgradeHandler>;\n readonly paths: readonly string[];\n}\n\nconst defaultOnError: SocketErrorHandler = (error, socket) => {\n console.error(`[dunx/http] ${socket.data.path} handler failed:`, error);\n};\n\nconst runtimeOf = (socket: Socket): GatewayRuntime =>\n (socket.data as Routed)[RUNTIME];\n\nconst isBinary = (value: unknown): value is Bun.BufferSource =>\n value instanceof ArrayBuffer || ArrayBuffer.isView(value);\n\nconst replyRaw = (socket: Socket, value: unknown): void => {\n if (value === undefined) return;\n socket.send(\n typeof value === 'string' || isBinary(value)\n ? value\n : JSON.stringify(value),\n );\n};\n\n/**\n * A handler may be sync or async. `then` is what turns a returned value into a\n * frame, and it runs inside the same error path either way.\n */\nconst settle = (\n result: unknown,\n socket: Socket,\n onError: SocketErrorHandler,\n then: ((value: unknown) => void) | undefined,\n): void => {\n if (result instanceof Promise) {\n void result.then(\n (value: unknown) => {\n if (!then) return;\n try {\n then(value);\n } catch (error) {\n onError(error, socket);\n }\n },\n (error: unknown) => onError(error, socket),\n );\n return;\n }\n if (then) then(result);\n};\n\nexport const buildWebSocket = (\n discovered: readonly DiscoveredGateway[],\n options: SocketOptions = {},\n): WebSocketRuntime => {\n const byPath = buildGateways(discovered);\n const gateways = [...byPath.values()];\n const onError = options.onError ?? defaultOnError;\n // The rest is exactly the set of keys Bun's WebSocketHandler accepts.\n const { onError: _onError, ...socketOptions } = options;\n\n const run = (\n invoke: Invoke,\n args: readonly unknown[],\n ws: Socket,\n then: ((value: unknown) => void) | undefined,\n ): void => {\n try {\n settle(invoke(...args), ws, onError, then);\n } catch (error) {\n onError(error, ws);\n }\n };\n\n const websocket: WebSocketHandler<SocketData> = {\n ...socketOptions,\n\n message(ws, message) {\n const gateway = runtimeOf(ws);\n if (gateway.events.size > 0) {\n const envelope = decode(message);\n const handler = envelope && gateway.events.get(envelope.event);\n if (envelope && handler) {\n run(handler, [envelope.data, ws], ws, (value) => {\n if (value !== undefined) ws.send(encode(envelope.event, value));\n });\n return;\n }\n }\n if (gateway.raw) {\n run(gateway.raw, [message, ws], ws, (value) => replyRaw(ws, value));\n }\n },\n\n ...(someHandler(gateways, (g) => g.open) && {\n open(ws: Socket) {\n const { open } = runtimeOf(ws);\n if (open) run(open, [ws], ws, undefined);\n },\n }),\n\n ...(someHandler(gateways, (g) => g.close) && {\n close(ws: Socket, code: number, reason: string) {\n const { close } = runtimeOf(ws);\n if (close) run(close, [ws, code, reason], ws, undefined);\n },\n }),\n\n ...(someHandler(gateways, (g) => g.drain) && {\n drain(ws: Socket) {\n const { drain } = runtimeOf(ws);\n if (drain) run(drain, [ws], ws, undefined);\n },\n }),\n\n // Only installed when a gateway asks for them: Bun answers a ping with a pong\n // on its own, and overriding the handler with a no-op would take that away.\n ...(someHandler(gateways, (g) => g.ping) && {\n ping(ws: Socket, data: Buffer) {\n const { ping } = runtimeOf(ws);\n if (ping) run(ping, [data, ws], ws, undefined);\n },\n }),\n\n ...(someHandler(gateways, (g) => g.pong) && {\n pong(ws: Socket, data: Buffer) {\n const { pong } = runtimeOf(ws);\n if (pong) run(pong, [data, ws], ws, undefined);\n },\n }),\n };\n\n const accept = (\n req: Request,\n server: Server<SocketData>,\n gateway: GatewayRuntime,\n context: unknown,\n ): Response | undefined => {\n const data: Routed = { path: gateway.path, context, [RUNTIME]: gateway };\n return server.upgrade(req, { data })\n ? undefined\n : new Response('Expected a WebSocket upgrade', { status: 426 });\n };\n\n // One closure per gateway, built here rather than per request. `@OnUpgrade` is\n // handed the BunRequest, so a path pattern's `req.params` is readable.\n const upgradeHandler =\n (gateway: GatewayRuntime): UpgradeHandler =>\n (req, server) => {\n if (!gateway.upgrade) return accept(req, server, gateway, undefined);\n\n const result = gateway.upgrade(req);\n if (result instanceof Promise) {\n return result.then((value: unknown) =>\n value instanceof Response\n ? value\n : accept(req, server, gateway, value),\n );\n }\n return result instanceof Response\n ? result\n : accept(req, server, gateway, result);\n };\n\n return {\n websocket,\n routes: new Map(\n gateways.map((gateway) => [gateway.path, upgradeHandler(gateway)]),\n ),\n paths: [...byPath.keys()],\n };\n};\n",
19
- "import {\n AppError,\n type Ctor,\n type InjectionToken,\n type ProviderEntry,\n type ResolvedModule,\n} from '@dunx/core';\nimport {\n gatewayPathOf,\n handlerMetaOf,\n isGateway,\n type HandlerKind,\n type HandlerMeta,\n} from './marker.js';\n\n/**\n * A discovered handler, already bound to its instance. Every kind has a different\n * signature, so the runtime holds them loosely and the decorators are what keep\n * the declared shapes honest.\n */\nexport type Invoke = (...args: readonly unknown[]) => unknown;\n\nexport interface DiscoveredHandler {\n readonly kind: HandlerKind;\n readonly event: string | undefined;\n readonly method: string;\n readonly invoke: Invoke;\n}\n\nexport interface DiscoveredGateway {\n readonly name: string;\n readonly path: string;\n readonly handlers: readonly DiscoveredHandler[];\n}\n\n/** `chat` and `/chat/` both become `/chat`; an empty path becomes `/`. */\nexport const normalizePath = (path: string): string => {\n const joined = `/${path}`.replace(/\\/{2,}/g, '/');\n return joined.length > 1 ? joined.replace(/\\/$/, '') : '/';\n};\n\n/** Every marked method on a prototype chain, most-derived first, names deduped. */\nconst eachHandler = (\n start: object | null,\n): readonly [string, HandlerMeta][] => {\n const found: [string, HandlerMeta][] = [];\n const seen = new Set<string>();\n\n for (\n let proto = start;\n proto !== null && proto !== Object.prototype;\n proto = Object.getPrototypeOf(proto) as object | null\n ) {\n for (const [name, descriptor] of Object.entries(\n Object.getOwnPropertyDescriptors(proto),\n )) {\n if (name === 'constructor' || seen.has(name)) continue;\n\n const meta = handlerMetaOf(descriptor.value);\n if (!meta) continue;\n\n seen.add(name);\n found.push([name, meta]);\n }\n }\n\n return found;\n};\n\n/**\n * Walks the prototype chain of a constructed gateway and collects every marked\n * method. Most-derived wins on a repeated name; an undecorated override does not\n * shadow its decorated base, and dispatch still lands on the override because the\n * handler is bound off the instance.\n */\nexport const discoverGateway = (instance: object): DiscoveredGateway => {\n const klass = instance.constructor;\n const members = instance as Record<string, Invoke>;\n\n return {\n name: klass.name,\n path: normalizePath(gatewayPathOf(klass)),\n handlers: eachHandler(Object.getPrototypeOf(instance) as object | null).map(\n ([name, meta]) => ({\n kind: meta.kind,\n event: meta.event,\n method: name,\n invoke: members[name]!.bind(instance),\n }),\n ),\n };\n};\n\n/**\n * The name of the first handler a class declares, without constructing it. A\n * provider that declares one but is not a gateway would silently never receive a\n * frame, so that becomes a boot error naming the method.\n */\nexport const findHandlerMethod = (ctor: Ctor<unknown>): string | undefined =>\n eachHandler(ctor.prototype as object | null)[0]?.[0];\n\n/** The class a `providers` entry would construct, or nothing for value/factory. */\nconst classOf = (\n entry: ProviderEntry,\n): { token: InjectionToken<unknown>; ctor: Ctor<unknown> } | undefined => {\n if (typeof entry === 'function') return { token: entry, ctor: entry };\n return entry.provider.kind === 'class'\n ? { token: entry.token, ctor: entry.provider.ctor }\n : undefined;\n};\n\n/**\n * Gateways are declared in `@Module({ providers })` like any other injectable and\n * found here by their marker the same discovery-by-inspection controllers get,\n * with no second registration key to keep in step.\n */\nexport const discoverGateways = (\n modules: readonly ResolvedModule[],\n resolve: (token: InjectionToken<unknown>) => unknown,\n): readonly DiscoveredGateway[] => {\n const discovered: DiscoveredGateway[] = [];\n\n for (const module of modules) {\n for (const entry of module.options.providers ?? []) {\n const candidate = classOf(entry);\n if (!candidate) continue;\n\n if (isGateway(candidate.ctor)) {\n discovered.push(discoverGateway(resolve(candidate.token) as object));\n continue;\n }\n // Otherwise its handlers could never run, and nothing would say so.\n const orphan = findHandlerMethod(candidate.ctor);\n if (orphan !== undefined) {\n throw new AppError(\n `${candidate.ctor.name}.${orphan}() is a websocket handler, but ` +\n `${candidate.ctor.name} is not a gateway. Decorate the class with ` +\n '@Gateway(path), or drop the handler decorator.',\n );\n }\n }\n }\n\n return discovered;\n};\n",
20
- "import { AppError } from '@dunx/core';\nimport type { Server } from 'bun';\nimport { encode } from './envelope.js';\nimport {\n decodeRelay,\n DEFAULT_RELAY_CHANNEL,\n defaultRelayError,\n encodeRelay,\n type PubSubRelay,\n type RelayOptions,\n type RelayPhase,\n} from './relay.js';\nimport type { SocketData } from './socket.js';\n\n/**\n * Server-wide publish, delegating to Bun's own pub/sub. Topics live in the\n * runtime, not in a JavaScript registry: `socket.subscribe(topic)` is what joins\n * one, and Bun does the fan-out.\n *\n * Injectable `HttpFactory` binds it, so a service can publish without holding a\n * socket and without registering anything.\n *\n * With a {@link PubSubRelay} attached the same publish also reaches the other\n * nodes. Without one the default nothing here touches a broker and the cost is\n * exactly Bun's.\n */\nexport class PubSub {\n /**\n * Identifies this process on the wire, so a frame this node published and the\n * broker echoed back is recognised and dropped instead of being fanned out\n * locally a second time. `Bun.randomUUIDv7` rather than a counter: two nodes\n * booted in the same millisecond must not collide.\n */\n readonly #origin = Bun.randomUUIDv7();\n #server: Server<SocketData> | undefined;\n #relay: PubSubRelay | undefined;\n #channel = DEFAULT_RELAY_CHANNEL;\n #onRelayError = defaultRelayError;\n /** So a broker that is down is reported once, not once per publish. */\n #relayFailing = false;\n #resubscribeTimer: ReturnType<typeof setTimeout> | undefined;\n #resubscribeLeft = 0;\n #resubscribeDelay = 0;\n\n /** Called with the live server by `listen()`; also usable directly. */\n attach(server: Server<SocketData>): void {\n this.#server = server;\n }\n\n get attached(): boolean {\n return this.#server !== undefined;\n }\n\n /** This process's id on the relay channel. Stable for the process's lifetime. */\n get origin(): string {\n return this.#origin;\n }\n\n get relaying(): boolean {\n return this.#relay !== undefined;\n }\n\n /**\n * Opt into multi-node fan-out: every `publish` from here on also goes to\n * `relay`, and everything other nodes put on the channel is fanned out locally.\n *\n * `HttpFactory.create(root, { relay })` is the shorthand `listen()` calls this.\n * Call it directly when the relay has to come out of the container, which is the\n * case for an app reusing its own `@dunx/infra/redis` connection:\n * `app.get(PubSub).relayThrough(app.get(RedisConnection))` before `listen()`.\n *\n * A broker that cannot be reached is reported through `onError` and left alone —\n * local fan-out is unaffected, and the app boots either way.\n */\n async relayThrough(\n relay: PubSubRelay,\n options: RelayOptions = {},\n ): Promise<void> {\n if (this.#relay) {\n throw new AppError(\n 'PubSub already relays. Two subscriptions on one channel would deliver ' +\n 'every relayed message twice pass HttpOptions.relay or call ' +\n 'relayThrough(), not both.',\n );\n }\n this.#relay = relay;\n this.#channel = options.channel ?? DEFAULT_RELAY_CHANNEL;\n this.#onRelayError = options.onError ?? defaultRelayError;\n this.#resubscribeLeft = options.resubscribe?.attempts ?? 5;\n this.#resubscribeDelay = options.resubscribe?.delayMs ?? 500;\n\n await this.#trySubscribe();\n }\n\n /**\n * One subscribe attempt, scheduling the next on failure. Separate from\n * `relayThrough` because a retry has to run the identical path including the\n * synchronous-throw handling, which Bun's client needs.\n */\n async #trySubscribe(): Promise<void> {\n const relay = this.#relay;\n if (!relay) return;\n\n try {\n // Bun's client throws synchronously for some states, so the call is inside\n // the try rather than only the await.\n await relay.subscribe(this.#channel, (message) => {\n this.#inbound(message);\n });\n this.#relayFailing = false;\n this.#resubscribeLeft = 0;\n } catch (error) {\n this.#degrade(error, 'subscribe');\n this.#scheduleResubscribe();\n }\n }\n\n #scheduleResubscribe(): void {\n if (this.#resubscribeLeft <= 0 || this.#relay === undefined) return;\n this.#resubscribeLeft -= 1;\n const delay = this.#resubscribeDelay;\n // Capped so a long-dead broker settles into a slow poll instead of growing\n // unboundedly; unref'd so it can never be the reason a process stays up.\n this.#resubscribeDelay = Math.min(delay * 2, 30_000);\n this.#resubscribeTimer = setTimeout(() => {\n void this.#trySubscribe();\n }, delay);\n this.#resubscribeTimer.unref?.();\n }\n\n /** Bytes sent locally, `0` if the message was dropped, `-1` under backpressure. */\n publish(\n topic: string,\n data: string | Bun.BufferSource,\n compress?: boolean,\n ): number {\n const sent = this.#live().publish(topic, data, compress);\n // Unconditional, and after the local fan-out: a topic with no subscriber on\n // this node may have thousands on another.\n this.#outbound(topic, data);\n return sent;\n }\n\n /** The same envelope `@OnMessage(event)` reads, published to a topic. */\n publishEvent(topic: string, event: string, data?: unknown): number {\n return this.publish(topic, encode(event, data));\n }\n\n /** Subscribers on **this** node. Bun counts its own sockets and nothing else. */\n subscriberCount(topic: string): number {\n return this.#live().subscriberCount(topic);\n }\n\n /**\n * Releases a relay this `PubSub` was given, if the relay owns connections.\n *\n * The server reference goes too, which is what makes a relay the *app* owns safe\n * to leave subscribed: `PubSubRelay` has no unsubscribe, so a frame may still\n * arrive on a shared connection after this node stopped, and with no server\n * there is nothing for it to fan out to.\n */\n async close(): Promise<void> {\n const relay = this.#relay;\n this.#relay = undefined;\n // Before anything can await: a pending retry must not fire against a relay\n // this call is closing.\n this.#resubscribeLeft = 0;\n if (this.#resubscribeTimer !== undefined) {\n clearTimeout(this.#resubscribeTimer);\n this.#resubscribeTimer = undefined;\n }\n this.#server = undefined;\n if (!relay?.close) return;\n try {\n await relay.close();\n } catch (error) {\n this.#degrade(error, 'close');\n }\n }\n\n #outbound(topic: string, data: string | Bun.BufferSource): void {\n const relay = this.#relay;\n if (!relay) return;\n try {\n const result = relay.publish(\n this.#channel,\n encodeRelay(this.#origin, topic, data),\n );\n if (result instanceof Promise) {\n void result.then(\n () => {\n this.#relayFailing = false;\n },\n (error: unknown) => {\n this.#degrade(error, 'publish');\n },\n );\n return;\n }\n this.#relayFailing = false;\n } catch (error) {\n this.#degrade(error, 'publish');\n }\n }\n\n /**\n * Local fan-out only, and that is the whole rule: republishing to the relay here\n * would put the frame back on the channel that delivered it and loop forever.\n */\n #inbound(message: string): void {\n const frame = decodeRelay(message);\n if (!frame || frame.origin === this.#origin) return;\n this.#server?.publish(frame.topic, frame.data);\n }\n\n #degrade(error: unknown, phase: RelayPhase): void {\n if (this.#relayFailing) return;\n this.#relayFailing = true;\n this.#onRelayError(error, phase);\n }\n\n #live(): Server<SocketData> {\n if (!this.#server) {\n throw new AppError(\n 'PubSub has no server yet. Publish once the server is listening: ' +\n 'HttpApp.listen() is what attaches it.',\n );\n }\n return this.#server;\n }\n}\n",
21
- "/**\n * What `PubSub` needs from something that carries a message to the other nodes:\n * publish, and subscribe. Nothing else, so anything that already talks to a\n * broker satisfies it `@dunx/infra/redis`'s `RedisConnection` does, structurally\n * and with no adapter, and so does a bare `Bun.RedisClient` pair.\n *\n * The return types are `unknown` rather than `Promise<void>` deliberately: Bun's\n * `publish` resolves the subscriber count, `@dunx/infra`'s resolves nothing, and a\n * synchronous in-memory bus resolves at all. A returned promise is awaited by\n * `subscribe` and watched for rejection by `publish`; anything else is taken as\n * having succeeded.\n */\nexport interface PubSubRelay {\n /** Hand `message` to every node subscribed to `channel`, this one included. */\n publish(channel: string, message: string): unknown;\n /**\n * Deliver every message published to `channel` to `listener`. Called once, with\n * one channel pattern subscription is not used, because Bun's `psubscribe`\n * does not work (see docs/bun-apis.md).\n */\n subscribe(channel: string, listener: (message: string) => void): unknown;\n /**\n * Release whatever this relay opened. Implement it only for connections the\n * relay itself owns: a relay that is the application's own shared\n * `RedisConnection` must leave closing to the container, and simply omitting\n * this method is how it says so.\n */\n close?(): unknown;\n}\n\n/** Which relay call failed, so one message can say what degraded. */\nexport type RelayPhase = 'publish' | 'subscribe' | 'close';\n\nexport interface RelayOptions {\n /**\n * The one broker channel every topic's frames travel on.\n *\n * One channel rather than one per topic, because a node cannot know which\n * topics its sockets joined `socket.subscribe()` goes straight into Bun and\n * `psubscribe` is unusable. The cost is that every node reads every relayed\n * frame and drops the ones for topics it has no local subscriber on, which is a\n * `server.publish` returning `0`. Two apps sharing a Redis need two channels.\n *\n * @default 'dunx:ws'\n */\n readonly channel?: string;\n /**\n * Where a relay failure goes. Called once when the relay starts failing and not\n * again until it works, so an unreachable broker cannot flood the log.\n *\n * @default console.warn\n */\n readonly onError?: (error: unknown, phase: RelayPhase) => void;\n /**\n * What to do when the **boot** subscribe fails. Publishing recovers on its own —\n * every publish retries the broker but a failed subscribe used to be retried\n * by nothing, so the node stayed permanently deaf to other nodes while still\n * looking healthy.\n *\n * Bounded rather than infinite, and the timer is unref'd, so a broker that never\n * comes back cannot hold the process open or spin forever.\n */\n readonly resubscribe?: {\n /** Retries after the first failure. `0` disables them. @default 5 */\n readonly attempts?: number;\n /** First delay; doubles each attempt, capped at 30s. @default 500 */\n readonly delayMs?: number;\n };\n}\n\nexport const DEFAULT_RELAY_CHANNEL = 'dunx:ws';\n\nexport const defaultRelayError = (error: unknown, phase: RelayPhase): void => {\n console.warn(\n `[dunx/http] the websocket relay could not ${phase}. Fan-out is local to ` +\n 'this process until it recovers:',\n error,\n );\n};\n\n/**\n * One relayed publish: which process published it, which topic it belongs to, and\n * the frame itself. `origin` is the whole duplicate-delivery defence the broker\n * echoes a publish back to the publisher, and fanning that out locally a second\n * time would give every client on the originating node the message twice.\n */\nexport interface RelayFrame {\n readonly origin: string;\n readonly topic: string;\n readonly data: string | Uint8Array<ArrayBufferLike>;\n}\n\nconst toBytes = (data: Bun.BufferSource): Uint8Array<ArrayBufferLike> =>\n ArrayBuffer.isView(data)\n ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength)\n : new Uint8Array(data);\n\nexport const encodeRelay = (\n origin: string,\n topic: string,\n data: string | Bun.BufferSource,\n): string =>\n typeof data === 'string'\n ? JSON.stringify({ o: origin, t: topic, d: data })\n : // Base64 through Buffer, which Bun implements natively. A binary frame has\n // to survive a text channel, and Redis pub/sub payloads are text here\n // because Bun's buffer-mode subscription is not implemented.\n JSON.stringify({\n o: origin,\n t: topic,\n d: Buffer.from(toBytes(data)).toString('base64'),\n b: 1,\n });\n\n/** `undefined` for anything that is not one of our frames, which is then ignored. */\nexport const decodeRelay = (message: string): RelayFrame | undefined => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(message);\n } catch {\n return undefined;\n }\n if (typeof parsed !== 'object' || parsed === null) return undefined;\n\n const { o, t, d, b } = parsed as {\n o?: unknown;\n t?: unknown;\n d?: unknown;\n b?: unknown;\n };\n if (typeof o !== 'string' || typeof t !== 'string' || typeof d !== 'string') {\n return undefined;\n }\n return { origin: o, topic: t, data: b ? Buffer.from(d, 'base64') : d };\n};\n",
22
- "import type { BunRequest, Server } from 'bun';\nimport {\n AppError,\n Logger,\n type App,\n type AppOptions,\n type Ctor,\n type InjectionToken,\n type ShutdownSignal,\n} from '@dunx/core';\nimport { joinPath, type DiscoveredRoute } from '../route/discover.js';\nimport type { WebSocketRuntime } from '../ws/adapter.js';\nimport { PubSub } from '../ws/pubsub.js';\nimport type { PubSubRelay, RelayPhase } from '../ws/relay.js';\nimport type { SocketData, SocketOptions } from '../ws/socket.js';\nimport { attachAddressSource, ClientAddress } from './client-address.js';\nimport type { CorsOptions } from './cors.js';\nimport { defaultErrorMapper, type ErrorMapper } from './errors.js';\nimport type { Middleware } from './middleware.js';\nimport {\n RequestLoggingMiddleware,\n type RequestLoggingOptions,\n} from './request-logging.js';\nimport {\n assertNoGatewayCollisions,\n buildFallback,\n buildRoutes,\n withUpgradeRoutes,\n} from './routes.js';\nimport { defaultSettings, type AppSettings } from './settings.js';\n\nexport interface HttpOptions extends AppOptions {\n readonly port?: number;\n /** Resolved from the container, so middleware can inject(). */\n readonly middleware?: readonly Ctor<Middleware>[];\n readonly onError?: ErrorMapper;\n /**\n * One structured entry per request, on by default. `false` removes it; an\n * options object tunes what it records. See {@link RequestLoggingMiddleware}.\n *\n * It is the **outermost** middleware, ahead of anything `middleware` declares,\n * so a request rejected by a guard is still logged with the status it got.\n */\n readonly requestLogging?: boolean | RequestLoggingOptions;\n /**\n * Bun's `websocket` options, plus where a throwing handler goes. Server-wide, so\n * they live here next to `middleware` rather than on a module: gateways\n * themselves are declared in `@Module({ providers })`.\n */\n readonly websocket?: SocketOptions;\n /**\n * Multi-node websocket fan-out. Absent — the default — means `PubSub` publishes\n * to this process only, which is exactly Bun's native pub/sub and costs nothing.\n *\n * `new RedisRelay({ url })` is the batteries-included one. Anything with a\n * `publish` and a `subscribe` fits, including `@dunx/infra`'s `RedisConnection`,\n * which has to come out of the container and so goes through\n * `app.get(PubSub).relayThrough(...)` instead of this option.\n */\n readonly relay?: PubSubRelay;\n /** The broker channel the relay carries frames on. @default 'dunx:ws' */\n readonly relayChannel?: string;\n}\n\n/**\n * Everything below `listen()` configures the route table, which is built exactly\n * once — when the server binds. Calling any of them afterwards throws rather than\n * being quietly dropped.\n */\nexport interface HttpApp extends App {\n /** Prefixes every discovered route. Last call wins. */\n setGlobalPrefix(prefix: string): this;\n /** Appends middleware, after anything `HttpOptions.middleware` declared. */\n use(...middleware: readonly Ctor<Middleware>[]): this;\n set<K extends keyof AppSettings>(key: K, value: AppSettings[K]): this;\n setting<K extends keyof AppSettings>(key: K): AppSettings[K];\n /** Mounts an `OPTIONS` preflight per path. Last call wins. */\n enableCors(options?: CorsOptions): this;\n /** The same `inject(ClientAddress)` singleton — honours `'trust proxy'`. */\n clientIp(req: BunRequest): string | undefined;\n /** Every gateway path this app upgrades on, exactly as mounted. */\n readonly gatewayPaths: readonly string[];\n listen(port?: number): Promise<string>;\n}\n\nexport class HttpApplication implements HttpApp {\n readonly closed: Promise<void>;\n readonly gatewayPaths: readonly string[];\n readonly #app: App;\n readonly #discovered: readonly DiscoveredRoute[];\n readonly #middleware: Ctor<Middleware>[];\n readonly #settings: AppSettings = defaultSettings();\n readonly #onError: ErrorMapper;\n readonly #port: number;\n readonly #websocket: WebSocketRuntime | undefined;\n readonly #relay: PubSubRelay | undefined;\n readonly #relayChannel: string | undefined;\n #globalPrefix = '';\n #cors: CorsOptions | undefined;\n #started = false;\n #server: Server<SocketData> | undefined;\n #resolveClosed: (() => void) | undefined;\n #shuttingDown: Promise<void> | undefined;\n #hooked = false;\n\n constructor(\n app: App,\n discovered: readonly DiscoveredRoute[],\n options: HttpOptions,\n websocket?: WebSocketRuntime,\n ) {\n this.#app = app;\n this.#discovered = discovered;\n this.#middleware = [\n ...(options.requestLogging === false ? [] : [RequestLoggingMiddleware]),\n ...(options.middleware ?? []),\n ];\n this.#onError = options.onError ?? defaultErrorMapper;\n this.#port = options.port ?? 3000;\n this.#websocket = websocket;\n this.#relay = options.relay;\n this.#relayChannel = options.relayChannel;\n this.gatewayPaths = websocket?.paths ?? [];\n this.closed = new Promise<void>((resolve) => {\n this.#resolveClosed = resolve;\n });\n }\n\n get<T>(token: InjectionToken<T>): T {\n return this.#app.get(token);\n }\n\n setGlobalPrefix(prefix: string): this {\n this.#assertNotStarted('setGlobalPrefix()');\n this.#globalPrefix = prefix;\n return this;\n }\n\n use(...middleware: readonly Ctor<Middleware>[]): this {\n this.#assertNotStarted('use()');\n this.#middleware.push(...middleware);\n return this;\n }\n\n set<K extends keyof AppSettings>(key: K, value: AppSettings[K]): this {\n this.#assertNotStarted('set()');\n this.#settings[key] = value;\n return this;\n }\n\n setting<K extends keyof AppSettings>(key: K): AppSettings[K] {\n return this.#settings[key];\n }\n\n enableCors(options: CorsOptions = {}): this {\n this.#assertNotStarted('enableCors()');\n this.#cors = options;\n return this;\n }\n\n clientIp(req: BunRequest): string | undefined {\n return this.#app.get(ClientAddress).of(req);\n }\n\n /**\n * The one `Bun.serve` call. A gateway's upgrade is a native `GET` route in the\n * same table, so Bun's router — not a hand-written `fetch` fallback — is what\n * matches an upgrade, and no `fetch` handler is needed at all.\n */\n async listen(port = this.#port): Promise<string> {\n this.#assertNotStarted('listen()');\n this.#started = true;\n\n const middleware = this.#middleware.map((entry) => this.#app.get(entry));\n const prefixed = this.#prefixed();\n // A `@UseGuards` class comes from the container too, so a guard injects exactly\n // like global middleware does.\n const routes = buildRoutes(\n prefixed,\n middleware,\n this.#onError,\n this.#cors,\n (guard) => this.#app.get(guard),\n );\n\n const ws = this.#websocket;\n if (ws) assertNoGatewayCollisions(prefixed, ws.paths);\n\n // Bun's own 404 never reaches the middleware chain, so an unmatched path is\n // invisible to request logging. This runs only after Bun has matched nothing,\n // so Bun is still the router — it just puts the global middleware in front of\n // the 404 and returns it in the framework's error shape.\n const fetch = buildFallback(middleware, this.#onError, this.#cors);\n\n // Two literals, one call: a route that may answer `undefined` because it\n // upgraded is only a valid route table when `websocket` is there to receive it,\n // and Bun's own types say so.\n const options: Bun.Serve.Options<SocketData> = ws\n ? {\n port,\n fetch,\n routes: withUpgradeRoutes(routes, ws.routes),\n websocket: ws.websocket,\n }\n : { port, fetch, routes };\n this.#server = Bun.serve(options);\n\n attachAddressSource(this.#app.get(ClientAddress), {\n server: this.#server,\n trustProxy: this.#settings['trust proxy'],\n });\n const pubsub = this.#app.get(PubSub);\n pubsub.attach(this.#server);\n // After attach, so a frame that arrives during the subscribe already has a\n // server to fan out on. Awaited so a two-node deployment is subscribed by the\n // time listen() resolves; an unreachable broker fails fast and degrades.\n if (this.#relay) {\n const logger = this.#app.get(Logger);\n await pubsub.relayThrough(this.#relay, {\n ...(this.#relayChannel !== undefined && {\n channel: this.#relayChannel,\n }),\n onError: (error: unknown, phase: RelayPhase) => {\n logger.warn(\n `the websocket relay could not ${phase}. Fan-out is local to this ` +\n 'process until it recovers.',\n { error },\n );\n },\n });\n }\n return this.#server.url.href;\n }\n\n // Not delegated to the core app: the server has to stop before providers tear\n // down, so the signal handler must land here. With a gateway the stop is forced —\n // a graceful stop waits for open connections and a WebSocket does not close on\n // its own, so it would hang. Those clients see a 1006 close.\n async shutdown(): Promise<void> {\n this.#shuttingDown ??= (async () => {\n await this.#server?.stop(this.#websocket !== undefined);\n this.#server = undefined;\n // Before the container: a relay this app owns holds two Redis sockets, and\n // `maxRetries: 0` means nothing else will ever close them.\n await this.#app.get(PubSub).close();\n await this.#app.shutdown();\n this.#resolveClosed?.();\n })();\n return this.#shuttingDown;\n }\n\n enableShutdownHooks(\n signals: readonly ShutdownSignal[] = ['SIGTERM', 'SIGINT'],\n ): this {\n if (this.#hooked) return this;\n this.#hooked = true;\n for (const signal of signals) {\n process.once(signal, () => void this.shutdown());\n }\n return this;\n }\n\n // Collision detection re-runs inside buildRoutes on these final paths.\n #prefixed(): readonly DiscoveredRoute[] {\n if (this.#globalPrefix === '') return this.#discovered;\n return this.#discovered.map((route) => ({\n ...route,\n path: joinPath(this.#globalPrefix, route.path),\n }));\n }\n\n // #started rather than #server, which shutdown() clears — a hook called after\n // the server stopped is just as ineffective as one called while it ran.\n #assertNotStarted(hook: string): void {\n if (!this.#started) return;\n throw new AppError(\n `${hook} must be called before listen(). The route table and the middleware ` +\n 'chain are folded into one closure per route when the server binds, so ' +\n 'this call could not take effect.',\n );\n }\n}\nObject.defineProperty(HttpApplication, Symbol.for('dunx.deps'), {\n value: () => [{ unresolved: \"app: App\" }, { unresolved: \"discovered: readonly DiscoveredRoute[]\" }, { unresolved: \"options: HttpOptions\" }, { unresolved: \"websocket?: WebSocketRuntime\" }],\n});\n",
23
- "import { Logger, RequestContext } from '@dunx/core';\nimport type { BunRequest } from 'bun';\nimport type { RouteContext } from './context.js';\nimport { HttpError } from './errors.js';\nimport type { Middleware, Next } from './middleware.js';\nimport { HttpStatusCode } from './status.js';\n\nexport const REQUEST_ID_HEADER = 'x-request-id';\n\nexport interface RequestLoggingOptions {\n /** Bodies past this many characters are logged as a size. Default 2048. `0` omits them. */\n readonly maxBodyLength?: number;\n /**\n * Log the request body. Default **`false`**.\n *\n * Reading it means `req.clone().text()` a second copy of every payload,\n * buffered and parsed, on the hot path. Measured on the `validate` scenario in\n * `tools/bench`, turning both body options on costs roughly two thirds of the\n * throughput. It is also the field most likely to contain a password.\n *\n * Turn it on in development, where seeing the payload is the point.\n */\n readonly requestBody?: boolean;\n /** Log the response body. Default **`false`** same clone-and-buffer cost. */\n readonly responseBody?: boolean;\n /** Paths to skip entirely a health check polled every second, say. */\n readonly ignore?: readonly string[];\n}\n\nconst parse = (text: string, limit: number): unknown => {\n if (limit === 0) return undefined;\n if (text.length === 0) return undefined;\n if (text.length > limit) return `[${text.length} bytes]`;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n};\n\nconst elapsedMs = (started: number): number =>\n Math.round((Bun.nanoseconds() - started) / 1e6);\n\n/** What the entry's `request` field carries, built in the order it is logged. */\ntype RequestFields = Record<string, unknown>;\n\n/**\n * One structured entry per request, carrying the request and its response.\n *\n * Installed by `HttpFactory.create` unless `requestLogging: false`. It injects\n * `Logger` and `RequestContext` both `@dunx/core` contracts, both bound by\n * default so it works with no logging module imported, and picks up\n * `@arkv/logger` automatically once `@dunx/infra/logger` is.\n *\n * **One entry, not two.** Nest needs a middleware for the inbound half and an\n * interceptor for the outbound one, because they are different classes and the\n * interceptor cannot see what the middleware saw. Here they are the same\n * closure, so there is no pair to correlate by `requestId` to find out how a\n * call ended. A 4xx is the same line at `warn`, a 5xx at `error`.\n *\n * Everything the handler logs in between carries `requestId`, `method`, `event`\n * and `context` without being passed anything, because the whole call runs\n * inside `runWithContext`.\n *\n * **Nothing here is `async`.** Reading the request or the response body are the\n * only steps that can ever wait, both are off by default, and both are adopted\n * with `.then` rather than awaited the same rule `input.ts` follows, for the\n * same measured reason. An `async` scope callback alone cost 0.44 µs/request\n * against a synchronous one on raw `Bun.serve`.\n */\nexport class RequestLoggingMiddleware implements Middleware {\n readonly #limit: number;\n readonly #requestBody: boolean;\n readonly #responseBody: boolean;\n readonly #ignore: ReadonlySet<string>;\n\n constructor(\n private readonly logger: Logger,\n private readonly context: RequestContext,\n options: RequestLoggingOptions = {},\n ) {\n this.#limit = options.maxBodyLength ?? 2048;\n this.#requestBody = options.requestBody ?? false;\n this.#responseBody = options.responseBody ?? false;\n this.#ignore = new Set(options.ignore ?? []);\n }\n\n handle(req: BunRequest, ctx: RouteContext, next: Next): Promise<Response> {\n // `new URL(req.url)` parses the scheme, host, port, query and hash to reach one\n // string. This finds the same two offsets once and slices both the pathname and\n // the query out of them, which is what every request needs and all that most of\n // them need.\n const url = req.url;\n const from = url.indexOf('/', url.indexOf('://') + 3);\n const mark = from === -1 ? -1 : url.indexOf('?', from);\n const path =\n from === -1 ? '/' : mark === -1 ? url.slice(from) : url.slice(from, mark);\n if (this.#ignore.size > 0 && this.#ignore.has(path)) return next();\n\n const started = Bun.nanoseconds();\n // An inbound id is honoured so a trace survives across services; otherwise\n // this is where one is minted.\n const requestId = req.headers.get(REQUEST_ID_HEADER) ?? crypto.randomUUID();\n\n return this.context.runWithContext(\n {\n requestId,\n method: ctx.method,\n event: path,\n flow: 'http',\n context: `${ctx.controller}.${ctx.handler}`,\n },\n () => {\n const request: RequestFields = {};\n if (mark !== -1) {\n request['query'] = Object.fromEntries(\n new URLSearchParams(url.slice(mark + 1)),\n );\n }\n const body = this.#body(req);\n if (body === undefined) {\n request['userAgent'] = req.headers.get('user-agent');\n return this.#dispatch(req, path, requestId, started, request, next);\n }\n return body.then((value) => {\n if (value !== undefined) request['body'] = value;\n request['userAgent'] = req.headers.get('user-agent');\n return this.#dispatch(req, path, requestId, started, request, next);\n });\n },\n );\n }\n\n #dispatch(\n req: BunRequest,\n path: string,\n requestId: string,\n started: number,\n request: RequestFields,\n next: Next,\n ): Promise<Response> {\n // `next()` is only ever a promise once the chain bottoms out in a route, but a\n // user middleware ahead of the route may throw out of `handle` synchronously,\n // and that request is still one this middleware promised to log.\n let settled: Promise<Response>;\n try {\n settled = next();\n } catch (error) {\n this.#failed(req, path, started, request, error);\n throw error;\n }\n return settled.then(\n (response) =>\n this.#succeeded(req, path, requestId, started, request, response),\n (error: unknown) => {\n this.#failed(req, path, started, request, error);\n throw error;\n },\n );\n }\n\n /**\n * Logged and rethrown: the error mapper still owns the status and the response\n * shape. A 404 or a rejected body is the caller's fault, and logging every probe\n * at `error` would drown the ones that matter.\n */\n #failed(\n req: BunRequest,\n path: string,\n started: number,\n request: RequestFields,\n error: unknown,\n ): void {\n const status =\n error instanceof HttpError\n ? error.status\n : HttpStatusCode.INTERNAL_SERVER_ERROR;\n const entry = {\n request,\n err: error,\n statusCode: status,\n elapsedMs: elapsedMs(started),\n };\n const line = `${req.method} ${path} ${status}`;\n if (status < HttpStatusCode.INTERNAL_SERVER_ERROR) {\n this.logger.warn(line, entry);\n } else {\n this.logger.error(line, entry);\n }\n }\n\n #succeeded(\n req: BunRequest,\n path: string,\n requestId: string,\n started: number,\n request: RequestFields,\n response: Response,\n ): Response | Promise<Response> {\n const body = this.#responseFields(response);\n if (body === undefined) {\n this.logger.info(`${req.method} ${path} ${response.status}`, {\n request,\n statusCode: response.status,\n elapsedMs: elapsedMs(started),\n });\n response.headers.set(REQUEST_ID_HEADER, requestId);\n return response;\n }\n return body.then((value) => {\n this.logger.info(`${req.method} ${path} ${response.status}`, {\n request,\n statusCode: response.status,\n ...(value === undefined ? {} : { responseBody: value }),\n elapsedMs: elapsedMs(started),\n });\n response.headers.set(REQUEST_ID_HEADER, requestId);\n return response;\n });\n }\n\n /**\n * `undefined` the default means there is nothing to read, and the caller\n * stays on the synchronous path. Clones when there is, so the handler's own\n * stream is never the one that was consumed.\n */\n #body(req: BunRequest): Promise<unknown> | undefined {\n if (!this.#requestBody) return undefined;\n if (req.method === 'GET' || req.method === 'HEAD') return undefined;\n if (!(req.headers.get('content-type') ?? '').includes('application/json')) {\n return undefined;\n }\n return req\n .clone()\n .text()\n .then((text) => parse(text, this.#limit));\n }\n\n #responseFields(response: Response): Promise<unknown> | undefined {\n if (!this.#responseBody) return undefined;\n if (\n !(response.headers.get('content-type') ?? '').includes('application/json')\n ) {\n return undefined;\n }\n return response\n .clone()\n .text()\n .then((text) => parse(text, this.#limit));\n }\n}\nObject.defineProperty(RequestLoggingMiddleware, Symbol.for('dunx.deps'), {\n value: () => [Logger, RequestContext, { unresolved: \"options: RequestLoggingOptions = {}\" }],\n});\n",
24
- "import { AppError, type Ctor } from '@dunx/core';\nimport type { BunRequest } from 'bun';\nimport type { DiscoveredRoute } from '../route/discover.js';\nimport type { HttpMethod } from '../route/marker.js';\nimport type { RouteInput } from '../route/schema.js';\nimport type { UpgradeHandler } from '../ws/adapter.js';\nimport { buildContext, type RouteContext } from './context.js';\nimport { preflight, withCors, type CorsOptions } from './cors.js';\nimport { defaultErrorMapper, HttpError, type ErrorMapper } from './errors.js';\nimport { buildInputReader, type InputReader } from './input.js';\nimport {\n compose,\n type Middleware,\n type RouteHandler,\n type ServedHandler,\n} from './middleware.js';\nimport { HttpStatusCode } from './status.js';\n\n/** How a `@UseGuards` class becomes an instance. `listen()` passes `app.get`. */\nexport type GuardResolver = (guard: Ctor<Middleware>) => Middleware;\n\nconst construct: GuardResolver = (guard) =>\n new (guard as new () => Middleware)();\n\n/** `OPTIONS` is never a `@Get`-style route — only CORS mounts one. */\nexport type RouteMethod = HttpMethod | 'OPTIONS';\n\nexport type BunRoutes = Record<\n string,\n Partial<Record<RouteMethod, ServedHandler>>\n>;\n\n/**\n * What `listen()` hands `Bun.serve`: the HTTP table plus one `GET` per gateway,\n * whose handler may answer `undefined` because the socket was upgraded.\n */\nexport type ServeRoutes = Record<\n string,\n Partial<Record<RouteMethod, ServedHandler | UpgradeHandler>>\n>;\n\n/**\n * A `Response` passes through untouched — that is the escape hatch, and nothing\n * about it is worth second-guessing. Nothing at all is a 204: `Response.json(null)`\n * would be a body claiming to be no body.\n */\nconst toResponse = (value: unknown, status: number): Response => {\n if (value instanceof Response) return value;\n if (value === undefined || value === null) {\n return new Response(null, { status: HttpStatusCode.NO_CONTENT });\n }\n return Response.json(value, { status });\n};\n\n/** Nest's rule: an explicit `status`, else 201 for POST, else 200. */\nconst statusFor = (route: DiscoveredRoute): number =>\n route.options?.status ??\n (route.method === 'POST' ? HttpStatusCode.CREATED : HttpStatusCode.OK);\n\n/**\n * Bun silently lets one route win on a collision, so a duplicate method+path is a\n * boot error naming both handlers. Run twice: once at `create()` on the discovered\n * paths, and again from `buildRoutes` at `listen()` on the final, prefixed ones.\n */\nexport const assertNoCollisions = (\n discovered: readonly DiscoveredRoute[],\n): void => {\n const owners = new Map<string, string>();\n\n for (const route of discovered) {\n const key = `${route.method} ${route.path}`;\n const owner = `${route.controller}.${route.handlerName}`;\n const existing = owners.get(key);\n\n if (existing !== undefined) {\n throw new AppError(\n `Route collision: ${key} is declared by ${existing} and by ${owner}. ` +\n 'Bun would keep only one of them.',\n );\n }\n owners.set(key, owner);\n }\n};\n\n/**\n * A gateway's upgrade is a native route like any other, so a path claimed by both a\n * controller and a gateway would lose one of them when the two tables merge.\n */\nexport const assertNoGatewayCollisions = (\n discovered: readonly DiscoveredRoute[],\n gatewayPaths: readonly string[],\n): void => {\n const gateways = new Set(gatewayPaths);\n\n for (const route of discovered) {\n if (gateways.has(route.path)) {\n throw new AppError(\n `Gateway path collision: ${route.path} is served by a gateway and by ` +\n `${route.controller}.${route.handlerName}(). The upgrade is a route too, ` +\n 'so one of them would be dropped.',\n );\n }\n }\n};\n\n/**\n * The two tables in one. A gateway's `GET` is what Bun's router matches on an\n * upgrade — the reason no `fetch` handler is needed for a socket to connect.\n */\nexport const withUpgradeRoutes = (\n routes: BunRoutes,\n gateways: ReadonlyMap<string, UpgradeHandler>,\n): ServeRoutes => {\n const merged: ServeRoutes = { ...routes };\n for (const [path, upgrade] of gateways) merged[path] = { GET: upgrade };\n return merged;\n};\n\n/**\n * The context an unmatched request gets. There is no controller and no handler,\n * and saying so is more useful to a log line than an empty string.\n */\nconst unmatchedContext = (req: Request): RouteContext =>\n Object.freeze({\n controller: '(unmatched)',\n handler: '(none)',\n method: req.method as HttpMethod,\n path: new URL(req.url).pathname,\n get: () => undefined,\n });\n\n/**\n * Bun answers an unmatched path itself, so nothing in the middleware chain ever\n * sees it — which makes a 404 invisible to request logging, metrics and tracing.\n *\n * This is the only `fetch` handler dunx installs, and it is not a router: Bun\n * still does all the matching, and this runs only once Bun has decided nothing\n * matched. It puts the global middleware in front of a 404 in the framework's\n * own error shape.\n *\n * Composed per request rather than at boot, because the context names the path\n * that missed. That allocation is on the 404 path only.\n */\nexport const buildFallback = (\n middleware: readonly Middleware[] = [],\n onError: ErrorMapper = defaultErrorMapper,\n cors?: CorsOptions,\n): RouteHandler => {\n // The canonical status name, not a sentence naming the path back at the\n // caller: an unmatched path is the one place where echoing the request would\n // tell a prober something about the surface it just failed to find.\n const miss: RouteHandler = () => {\n throw new HttpError(HttpStatusCode.NOT_FOUND, 'NOT_FOUND');\n };\n\n const run: RouteHandler = async (req) => {\n try {\n return await compose(middleware, unmatchedContext(req), miss)(req);\n } catch (error) {\n return onError(error, req);\n }\n };\n\n return cors ? withCors(cors, run) : run;\n};\n\n/**\n * The direct path, taken when a route has no middleware and no CORS. Nothing here\n * is `async`: every step looks at what it got and only allocates a promise when\n * there is genuinely something to wait for.\n *\n * The general path is `async (req) => toResponse(await handler(await read(req)))`\n * inside an `async` try/catch — four `await`s across two async frames, on values\n * that are usually not thenable at all. A route with no declared schemas awaits\n * nothing; a route with only `query` or `params` awaits nothing either, because\n * every Standard Schema validator worth using is synchronous. Even a `body` route,\n * which really does have to wait for `req.json()`, pays one promise link instead of\n * six frames.\n *\n * Worth ~6 points of throughput against raw `Bun.serve` on the `params` scenario\n * when it covered only schema-less routes, and a further ~5 on `validate` when it\n * was extended to cover reading ones — which is most of what separated dunx from\n * Elysia, whose whole trick is compiling this shape ahead of time.\n *\n * A handler or a validator that *does* return a promise still works: it is adopted\n * here rather than awaited by a wrapper.\n */\nconst directOr = (\n guarded: RouteHandler,\n route: DiscoveredRoute,\n read: InputReader,\n status: number,\n onError: ErrorMapper,\n noMiddleware: boolean,\n): ServedHandler => {\n if (!noMiddleware) return guarded;\n\n // `toResponse` throws on a value `JSON.stringify` cannot take, so it is inside\n // the mapper's reach on every branch — including the `then` callbacks, where a\n // throw would otherwise escape as an unhandled rejection instead of a 500.\n const settle = (value: unknown, req: BunRequest): Response => {\n try {\n return toResponse(value, status);\n } catch (error) {\n return onError(error, req);\n }\n };\n\n const invoke = (\n input: RouteInput,\n req: BunRequest,\n ): Response | Promise<Response> => {\n try {\n const value = route.handler(input);\n return value instanceof Promise\n ? value.then(\n (resolved) => settle(resolved, req),\n (error: unknown) => onError(error, req),\n )\n : settle(value, req);\n } catch (error) {\n return onError(error, req);\n }\n };\n\n return (req) => {\n try {\n const input = read(req);\n return input instanceof Promise\n ? input.then(\n (resolved) => invoke(resolved, req),\n (error: unknown) => onError(error, req),\n )\n : invoke(input, req);\n } catch (error) {\n return onError(error, req);\n }\n };\n};\n\nexport const buildRoutes = (\n discovered: readonly DiscoveredRoute[],\n middleware: readonly Middleware[] = [],\n onError: ErrorMapper = defaultErrorMapper,\n cors?: CorsOptions,\n resolve: GuardResolver = construct,\n): BunRoutes => {\n assertNoCollisions(discovered);\n const routes: BunRoutes = {};\n // One instance per guard class for the whole table — what the container returns,\n // and what the default resolver has to match to be interchangeable with it.\n const instances = new Map<Ctor<Middleware>, Middleware>();\n const guardOf = (guard: Ctor<Middleware>): Middleware => {\n const existing = instances.get(guard);\n if (existing) return existing;\n const created = resolve(guard);\n instances.set(guard, created);\n return created;\n };\n\n for (const route of discovered) {\n // Schemas, parsers, the status and the route context resolve here, once. What\n // survives into the request path is one closure that reads no metadata.\n const read = buildInputReader(route.options);\n const status = statusFor(route);\n // Global outermost, then the controller's guards, then the method's.\n const chain = [...middleware, ...(route.guards ?? []).map(guardOf)];\n const chained = compose(chain, buildContext(route), async (req) =>\n toResponse(await route.handler(await read(req)), status),\n );\n const guarded: RouteHandler = async (req) => {\n try {\n return await chained(req);\n } catch (error) {\n return onError(error, req);\n }\n };\n\n const byMethod = (routes[route.path] ??= {});\n // Outside the error mapper, so a mapped 500 still carries the CORS headers the\n // browser needs in order to show it.\n byMethod[route.method] = cors\n ? withCors(cors, guarded)\n : directOr(guarded, route, read, status, onError, chain.length === 0);\n }\n\n if (cors) {\n for (const byMethod of Object.values(routes)) {\n byMethod.OPTIONS = preflight(cors, Object.keys(byMethod));\n }\n }\n\n return routes;\n};\n",
25
- "import type { BunRequest } from 'bun';\nimport type {\n RouteInput,\n RouteSchemas,\n StandardSchemaIssue,\n StandardSchemaResult,\n StandardSchemaV1,\n} from '../route/schema.js';\nimport {\n HttpError,\n ValidationError,\n type InputSource,\n type ValidationIssue,\n} from './errors.js';\nimport { HttpStatusCode } from './status.js';\n\n/**\n * Built once per route at boot. A route that declares nothing gets the identity\n * reader no parse, no validation, not even a promise.\n *\n * A reader **returns a promise only when it has something to wait for**. A `body`\n * schema always does; `query` and `params` against a synchronous validator which\n * zod, Valibot and ArkType all are resolve without one.\n */\nexport type InputReader = (req: BunRequest) => RouteInput | Promise<RouteInput>;\n\ninterface InputDraft {\n req: BunRequest;\n body?: unknown;\n query?: unknown;\n params?: unknown;\n}\n\n/**\n * One declared schema's contribution to the draft, returning the draft so the\n * steps chain without a wrapper. A bare `InputDraft` means it finished\n * synchronously, which is the common case and the reason this is not `async`:\n * Standard Schema *permits* a promise, so awaiting unconditionally costs an async\n * frame and a microtask tick per schema for a validator that never returns one.\n */\ntype Fill = (draft: InputDraft) => InputDraft | Promise<InputDraft>;\ntype BodyParser = (req: BunRequest) => Promise<unknown>;\n\n/** What `URLSearchParams` and `FormData` both offer, and all {@link grouped} needs. */\ninterface Enumerable {\n forEach(visit: (value: unknown, key: string) => void): void;\n}\n\n/**\n * A repeated key becomes an array, so `?tag=a&tag=b` reaches the schema whole\n * instead of silently losing `a`. Shared by query strings, urlencoded bodies and\n * multipart form data.\n *\n * `forEach` rather than `for…of`: both collections implement it natively, and\n * destructuring an iterator allocates a two-element array per entry. Measured at\n * ~150 ns/request cheaper on a three-pair query string.\n */\nconst grouped = (entries: Enumerable): Record<string, unknown> => {\n const collected: Record<string, unknown> = {};\n\n entries.forEach((value, key) => {\n const existing = collected[key];\n if (existing === undefined) collected[key] = value;\n else if (Array.isArray(existing)) (existing as unknown[]).push(value);\n else collected[key] = [existing, value];\n });\n\n return collected;\n};\n\nconst asJson: BodyParser = (req) => req.json();\nconst asUrlEncoded: BodyParser = async (req) =>\n grouped(new URLSearchParams(await req.text()));\nconst asMultipart: BodyParser = async (req) => grouped(await req.formData());\nconst asText: BodyParser = (req) => req.text();\n\n/** `application/vnd.api+json` and friends parse as JSON; `text/csv` as text. */\nconst parserFor = (media: string): BodyParser | undefined => {\n if (media === 'application/json' || media.endsWith('+json')) return asJson;\n if (media === 'application/x-www-form-urlencoded') return asUrlEncoded;\n if (media === 'multipart/form-data') return asMultipart;\n if (media.startsWith('text/')) return asText;\n return undefined;\n};\n\nconst JSON_MEDIA = 'application/json';\n\n// No content-type reads as JSON: fetch omits the header for a bodyless request and\n// a 415 there would be useless, since the schema is about to reject `undefined`.\nconst mediaTypeOf = (req: BunRequest): string => {\n const header = req.headers.get('content-type');\n // The header almost every JSON client sends, verbatim worth not slicing,\n // trimming and lowercasing on the hot path.\n if (header === JSON_MEDIA || header === null) return JSON_MEDIA;\n const end = header.indexOf(';');\n const media = (end === -1 ? header : header.slice(0, end)).trim();\n return media === '' ? JSON_MEDIA : media.toLowerCase();\n};\n\nconst flatten = (issue: StandardSchemaIssue): ValidationIssue => {\n const path = issue.path\n ?.map((segment) =>\n String(typeof segment === 'object' ? segment.key : segment),\n )\n .join('.');\n\n return path === undefined || path === ''\n ? { message: issue.message }\n : { message: issue.message, path };\n};\n\n/** A rejected schema is a 400 carrying every issue, path flattened to dots. */\nconst accept = (source: InputSource, result: StandardSchemaResult<unknown>) => {\n if (result.issues !== undefined) {\n throw new ValidationError(source, result.issues.map(flatten));\n }\n return result.value;\n};\n\n/**\n * Validates, assigns, and hands the draft back. Returning the draft rather than\n * `void` is what lets the reader be `(req) => fill({ req })`: a body route then\n * costs one promise link in total, where threading the draft back through a second\n * `then` cost two worth ~120 ns per request, measured.\n */\nconst fillWith = (\n draft: InputDraft,\n source: InputSource,\n schema: StandardSchemaV1,\n value: unknown,\n): InputDraft | Promise<InputDraft> => {\n const result = schema['~standard'].validate(value);\n\n if (result instanceof Promise) {\n return result.then((settled) => {\n draft[source] = accept(source, settled);\n return draft;\n });\n }\n draft[source] = accept(source, result);\n return draft;\n};\n\nconst bodyFill =\n (schema: StandardSchemaV1): Fill =>\n (draft) => {\n const media = mediaTypeOf(draft.req);\n const parse = parserFor(media);\n\n if (parse === undefined) {\n throw new HttpError(\n HttpStatusCode.UNSUPPORTED_MEDIA_TYPE,\n `Unsupported content type \"${media}\". Declared bodies accept ` +\n 'application/json, application/x-www-form-urlencoded, multipart/form-data or text/*.',\n );\n }\n\n // Both handlers on one `then`, so the parse costs a single promise link. A\n // `ValidationError` from the success handler is deliberately not visible to the\n // rejection handler only an unreadable or mangled body is a parse failure.\n return parse(draft.req).then(\n (value) => fillWith(draft, 'body', schema, value),\n (error: unknown) => {\n // A body the caller mangled is a 400. Only an unreadable stream would be ours.\n throw new HttpError(\n HttpStatusCode.BAD_REQUEST,\n `Malformed ${media} body`,\n { cause: error },\n );\n },\n );\n };\n\n/**\n * The query string, without parsing the whole URL to reach it. `new URL(req.url)`\n * resolves scheme, host, port, path and fragment to hand back a `searchParams`, and\n * measured **~1,000 ns of the ~1,500 ns** a `query` route used to cost more than\n * the entire body reader. `RequestLoggingMiddleware` took the same slice for the\n * same reason.\n *\n * The fragment is stripped even though a client is not supposed to send one, because\n * `new URL` stripped it and a hostile request-target should not change what a schema\n * sees.\n */\nconst searchOf = (url: string): string => {\n const start = url.indexOf('?');\n if (start === -1) return '';\n const end = url.indexOf('#', start + 1);\n return end === -1 ? url.slice(start + 1) : url.slice(start + 1, end);\n};\n\nconst queryFill =\n (schema: StandardSchemaV1): Fill =>\n (draft) => {\n const params = new URLSearchParams(searchOf(draft.req.url));\n return fillWith(draft, 'query', schema, grouped(params));\n };\n\nconst paramsFill =\n (schema: StandardSchemaV1): Fill =>\n (draft) =>\n fillWith(draft, 'params', schema, draft.req.params);\n\n/** Sequential, and stays sequential without a promise unless one is produced. */\nconst then =\n (first: Fill, second: Fill): Fill =>\n (draft) => {\n const started = first(draft);\n return started instanceof Promise ? started.then(second) : second(started);\n };\n\n/**\n * Folds the declared schemas into a single closure, the way `compose` folds\n * middleware: which parsers and validators run is decided here, at boot, so per\n * request there is no metadata to read and no branch left to take.\n */\nexport const buildInputReader = (\n options: RouteSchemas | undefined,\n): InputReader => {\n const fills: Fill[] = [];\n if (options?.body !== undefined) fills.push(bodyFill(options.body));\n if (options?.query !== undefined) fills.push(queryFill(options.query));\n if (options?.params !== undefined) fills.push(paramsFill(options.params));\n\n if (fills.length === 0) return (req) => ({ req });\n\n const fill = fills.reduce(then);\n return (req) => fill({ req });\n};\n",
26
- "import type { BunRequest } from 'bun';\nimport type { RouteContext } from './context.js';\n\nexport type Next = () => Promise<Response>;\n\n/**\n * The single extension point. A guard is middleware that throws, an interceptor\n * wraps `next()`, a filter is the error mapper. `ctx` names the route and carries\n * what its decorators declared, resolved at boot so a guard costs a Map lookup.\n */\nexport interface Middleware {\n handle(req: BunRequest, ctx: RouteContext, next: Next): Promise<Response>;\n}\n\nexport type RouteHandler = (req: BunRequest) => Promise<Response>;\n\n/**\n * What goes into the `Bun.serve` route table. Wider than `RouteHandler` because\n * Bun accepts a plain `Response`, which is what lets a route with nothing to\n * await skip promises altogether see `buildRoutes`.\n */\nexport type ServedHandler = (req: BunRequest) => Response | Promise<Response>;\n\n/** Folded into one closure per route at boot no per-request array iteration. */\nexport const compose = (\n middleware: readonly Middleware[],\n ctx: RouteContext,\n handler: RouteHandler,\n): RouteHandler =>\n middleware.reduceRight<RouteHandler>(\n (next, current) => (req) => current.handle(req, ctx, () => next(req)),\n handler,\n );\n",
27
- "/**\n * The settings `app.set()` accepts. A key has to be declared here to be settable,\n * so the map is checked at compile time instead of being a string bag a typo is\n * a type error, not a setting that silently never applies.\n */\nexport interface AppSettings {\n /**\n * Resolve the client address from `X-Forwarded-For` rather than the socket. Only\n * turn it on behind a proxy that rewrites the header: a direct client can send\n * whatever it likes.\n */\n 'trust proxy': boolean;\n}\n\nexport const defaultSettings = (): AppSettings => ({ 'trust proxy': false });\n",
19
+ "import {\n AppError,\n type Ctor,\n type InjectionToken,\n type ProviderEntry,\n type ResolvedModule,\n} from '@dunx/core';\nimport {\n gatewayPathOf,\n handlerMetaOf,\n isGateway,\n type HandlerKind,\n type HandlerMeta,\n} from './marker.js';\n\n/**\n * A discovered handler, already bound to its instance. Every kind has a different\n * signature, so the runtime holds them loosely and the decorators are what keep\n * the declared shapes honest.\n */\nexport type Invoke = (...args: readonly unknown[]) => unknown;\n\nexport interface DiscoveredHandler {\n readonly kind: HandlerKind;\n readonly event: string | undefined;\n readonly method: string;\n readonly invoke: Invoke;\n}\n\nexport interface DiscoveredGateway {\n readonly name: string;\n readonly path: string;\n readonly handlers: readonly DiscoveredHandler[];\n}\n\n/** `chat` and `/chat/` both become `/chat`; an empty path becomes `/`. */\nexport const normalizePath = (path: string): string => {\n const joined = `/${path}`.replace(/\\/{2,}/g, '/');\n return joined.length > 1 ? joined.replace(/\\/$/, '') : '/';\n};\n\n/** Every marked method on a prototype chain, most-derived first, names deduped. */\nconst eachHandler = (\n start: object | null,\n): readonly [string, HandlerMeta][] => {\n const found: [string, HandlerMeta][] = [];\n const seen = new Set<string>();\n\n for (\n let proto = start;\n proto !== null && proto !== Object.prototype;\n proto = Object.getPrototypeOf(proto) as object | null\n ) {\n for (const [name, descriptor] of Object.entries(\n Object.getOwnPropertyDescriptors(proto),\n )) {\n if (name === 'constructor' || seen.has(name)) continue;\n\n const meta = handlerMetaOf(descriptor.value);\n if (!meta) continue;\n\n seen.add(name);\n found.push([name, meta]);\n }\n }\n\n return found;\n};\n\n/**\n * Walks the prototype chain of a constructed gateway and collects every marked\n * method. Most-derived wins on a repeated name; an undecorated override does not\n * shadow its decorated base, and dispatch still lands on the override because the\n * handler is bound off the instance.\n */\nexport const discoverGateway = (instance: object): DiscoveredGateway => {\n const klass = instance.constructor;\n const members = instance as Record<string, Invoke>;\n\n return {\n name: klass.name,\n path: normalizePath(gatewayPathOf(klass)),\n handlers: eachHandler(Object.getPrototypeOf(instance) as object | null).map(\n ([name, meta]) => ({\n kind: meta.kind,\n event: meta.event,\n method: name,\n invoke: members[name]!.bind(instance),\n }),\n ),\n };\n};\n\n/**\n * The name of the first handler a class declares, without constructing it. A\n * provider that declares one but is not a gateway would silently never receive a\n * frame, so that becomes a boot error naming the method.\n */\nexport const findHandlerMethod = (ctor: Ctor<unknown>): string | undefined =>\n eachHandler(ctor.prototype as object | null)[0]?.[0];\n\n/** The class a `providers` entry would construct, or nothing for value/factory. */\nconst classOf = (\n entry: ProviderEntry,\n): { token: InjectionToken<unknown>; ctor: Ctor<unknown> } | undefined => {\n if (typeof entry === 'function') return { token: entry, ctor: entry };\n return entry.provider.kind === 'class'\n ? { token: entry.token, ctor: entry.provider.ctor }\n : undefined;\n};\n\n/**\n * Gateways are declared in `@Module({ providers })` like any other injectable and\n * found here by their marker - the same discovery-by-inspection controllers get,\n * with no second registration key to keep in step.\n */\nexport const discoverGateways = (\n modules: readonly ResolvedModule[],\n resolve: (token: InjectionToken<unknown>) => unknown,\n): readonly DiscoveredGateway[] => {\n const discovered: DiscoveredGateway[] = [];\n\n for (const module of modules) {\n for (const entry of module.options.providers ?? []) {\n const candidate = classOf(entry);\n if (!candidate) continue;\n\n if (isGateway(candidate.ctor)) {\n discovered.push(discoverGateway(resolve(candidate.token) as object));\n continue;\n }\n // Otherwise its handlers could never run, and nothing would say so.\n const orphan = findHandlerMethod(candidate.ctor);\n if (orphan !== undefined) {\n throw new AppError(\n `${candidate.ctor.name}.${orphan}() is a websocket handler, but ` +\n `${candidate.ctor.name} is not a gateway. Decorate the class with ` +\n '@Gateway(path), or drop the handler decorator.',\n );\n }\n }\n }\n\n return discovered;\n};\n",
20
+ "import { AppError } from '@dunx/core';\nimport type { Server } from 'bun';\nimport { encode } from './envelope.js';\nimport {\n decodeRelay,\n DEFAULT_RELAY_CHANNEL,\n defaultRelayError,\n encodeRelay,\n type PubSubRelay,\n type RelayOptions,\n type RelayPhase,\n} from './relay.js';\nimport type { SocketData } from './socket.js';\n\n/**\n * Server-wide publish, delegating to Bun's own pub/sub. Topics live in the\n * runtime, not in a JavaScript registry: `socket.subscribe(topic)` is what joins\n * one, and Bun does the fan-out.\n *\n * Injectable - `HttpFactory` binds it, so a service can publish without holding a\n * socket and without registering anything.\n *\n * With a {@link PubSubRelay} attached the same publish also reaches the other\n * nodes. Without one - the default - nothing here touches a broker and the cost is\n * exactly Bun's.\n */\nexport class PubSub {\n /**\n * Identifies this process on the wire, so a frame this node published and the\n * broker echoed back is recognised and dropped instead of being fanned out\n * locally a second time. `Bun.randomUUIDv7` rather than a counter: two nodes\n * booted in the same millisecond must not collide.\n */\n readonly #origin = Bun.randomUUIDv7();\n #server: Server<SocketData> | undefined;\n #relay: PubSubRelay | undefined;\n #channel = DEFAULT_RELAY_CHANNEL;\n #onRelayError = defaultRelayError;\n /** So a broker that is down is reported once, not once per publish. */\n #relayFailing = false;\n #resubscribeTimer: ReturnType<typeof setTimeout> | undefined;\n #resubscribeLeft = 0;\n #resubscribeDelay = 0;\n\n /** Called with the live server by `listen()`; also usable directly. */\n attach(server: Server<SocketData>): void {\n this.#server = server;\n }\n\n get attached(): boolean {\n return this.#server !== undefined;\n }\n\n /** This process's id on the relay channel. Stable for the process's lifetime. */\n get origin(): string {\n return this.#origin;\n }\n\n get relaying(): boolean {\n return this.#relay !== undefined;\n }\n\n /**\n * Opt into multi-node fan-out: every `publish` from here on also goes to\n * `relay`, and everything other nodes put on the channel is fanned out locally.\n *\n * `HttpFactory.create(root, { relay })` is the shorthand - `listen()` calls this.\n * Call it directly when the relay has to come out of the container, which is the\n * case for an app reusing its own `@dunx/infra/redis` connection:\n * `app.get(PubSub).relayThrough(app.get(RedisConnection))` before `listen()`.\n *\n * A broker that cannot be reached is reported through `onError` and left alone -\n * local fan-out is unaffected, and the app boots either way.\n */\n async relayThrough(\n relay: PubSubRelay,\n options: RelayOptions = {},\n ): Promise<void> {\n if (this.#relay) {\n throw new AppError(\n 'PubSub already relays. Two subscriptions on one channel would deliver ' +\n 'every relayed message twice - pass HttpOptions.relay or call ' +\n 'relayThrough(), not both.',\n );\n }\n this.#relay = relay;\n this.#channel = options.channel ?? DEFAULT_RELAY_CHANNEL;\n this.#onRelayError = options.onError ?? defaultRelayError;\n this.#resubscribeLeft = options.resubscribe?.attempts ?? 5;\n this.#resubscribeDelay = options.resubscribe?.delayMs ?? 500;\n\n await this.#trySubscribe();\n }\n\n /**\n * One subscribe attempt, scheduling the next on failure. Separate from\n * `relayThrough` because a retry has to run the identical path - including the\n * synchronous-throw handling, which Bun's client needs.\n */\n async #trySubscribe(): Promise<void> {\n const relay = this.#relay;\n if (!relay) return;\n\n try {\n // Bun's client throws synchronously for some states, so the call is inside\n // the try rather than only the await.\n await relay.subscribe(this.#channel, (message) => {\n this.#inbound(message);\n });\n this.#relayFailing = false;\n this.#resubscribeLeft = 0;\n } catch (error) {\n this.#degrade(error, 'subscribe');\n this.#scheduleResubscribe();\n }\n }\n\n #scheduleResubscribe(): void {\n if (this.#resubscribeLeft <= 0 || this.#relay === undefined) return;\n this.#resubscribeLeft -= 1;\n const delay = this.#resubscribeDelay;\n // Capped so a long-dead broker settles into a slow poll instead of growing\n // unboundedly; unref'd so it can never be the reason a process stays up.\n this.#resubscribeDelay = Math.min(delay * 2, 30_000);\n this.#resubscribeTimer = setTimeout(() => {\n void this.#trySubscribe();\n }, delay);\n this.#resubscribeTimer.unref?.();\n }\n\n /** Bytes sent locally, `0` if the message was dropped, `-1` under backpressure. */\n publish(\n topic: string,\n data: string | Bun.BufferSource,\n compress?: boolean,\n ): number {\n const sent = this.#live().publish(topic, data, compress);\n // Unconditional, and after the local fan-out: a topic with no subscriber on\n // this node may have thousands on another.\n this.#outbound(topic, data);\n return sent;\n }\n\n /** The same envelope `@OnMessage(event)` reads, published to a topic. */\n publishEvent(topic: string, event: string, data?: unknown): number {\n return this.publish(topic, encode(event, data));\n }\n\n /** Subscribers on **this** node. Bun counts its own sockets and nothing else. */\n subscriberCount(topic: string): number {\n return this.#live().subscriberCount(topic);\n }\n\n /**\n * Releases a relay this `PubSub` was given, if the relay owns connections.\n *\n * The server reference goes too, which is what makes a relay the *app* owns safe\n * to leave subscribed: `PubSubRelay` has no unsubscribe, so a frame may still\n * arrive on a shared connection after this node stopped, and with no server\n * there is nothing for it to fan out to.\n */\n async close(): Promise<void> {\n const relay = this.#relay;\n this.#relay = undefined;\n // Before anything can await: a pending retry must not fire against a relay\n // this call is closing.\n this.#resubscribeLeft = 0;\n if (this.#resubscribeTimer !== undefined) {\n clearTimeout(this.#resubscribeTimer);\n this.#resubscribeTimer = undefined;\n }\n this.#server = undefined;\n if (!relay?.close) return;\n try {\n await relay.close();\n } catch (error) {\n this.#degrade(error, 'close');\n }\n }\n\n #outbound(topic: string, data: string | Bun.BufferSource): void {\n const relay = this.#relay;\n if (!relay) return;\n try {\n const result = relay.publish(\n this.#channel,\n encodeRelay(this.#origin, topic, data),\n );\n if (result instanceof Promise) {\n void result.then(\n () => {\n this.#relayFailing = false;\n },\n (error: unknown) => {\n this.#degrade(error, 'publish');\n },\n );\n return;\n }\n this.#relayFailing = false;\n } catch (error) {\n this.#degrade(error, 'publish');\n }\n }\n\n /**\n * Local fan-out only, and that is the whole rule: republishing to the relay here\n * would put the frame back on the channel that delivered it and loop forever.\n */\n #inbound(message: string): void {\n const frame = decodeRelay(message);\n if (!frame || frame.origin === this.#origin) return;\n this.#server?.publish(frame.topic, frame.data);\n }\n\n #degrade(error: unknown, phase: RelayPhase): void {\n if (this.#relayFailing) return;\n this.#relayFailing = true;\n this.#onRelayError(error, phase);\n }\n\n #live(): Server<SocketData> {\n if (!this.#server) {\n throw new AppError(\n 'PubSub has no server yet. Publish once the server is listening: ' +\n 'HttpApp.listen() is what attaches it.',\n );\n }\n return this.#server;\n }\n}\n",
21
+ "/**\n * What `PubSub` needs from something that carries a message to the other nodes:\n * publish, and subscribe. Nothing else, so anything that already talks to a\n * broker satisfies it - `@dunx/infra/redis`'s `RedisConnection` does, structurally\n * and with no adapter, and so does a bare `Bun.RedisClient` pair.\n *\n * The return types are `unknown` rather than `Promise<void>` deliberately: Bun's\n * `publish` resolves the subscriber count, `@dunx/infra`'s resolves nothing, and a\n * synchronous in-memory bus resolves at all. A returned promise is awaited by\n * `subscribe` and watched for rejection by `publish`; anything else is taken as\n * having succeeded.\n */\nexport interface PubSubRelay {\n /** Hand `message` to every node subscribed to `channel`, this one included. */\n publish(channel: string, message: string): unknown;\n /**\n * Deliver every message published to `channel` to `listener`. Called once, with\n * one channel - pattern subscription is not used, because Bun's `psubscribe`\n * does not work (see docs/bun-apis.md).\n */\n subscribe(channel: string, listener: (message: string) => void): unknown;\n /**\n * Release whatever this relay opened. Implement it only for connections the\n * relay itself owns: a relay that is the application's own shared\n * `RedisConnection` must leave closing to the container, and simply omitting\n * this method is how it says so.\n */\n close?(): unknown;\n}\n\n/** Which relay call failed, so one message can say what degraded. */\nexport type RelayPhase = 'publish' | 'subscribe' | 'close';\n\nexport interface RelayOptions {\n /**\n * The one broker channel every topic's frames travel on.\n *\n * One channel rather than one per topic, because a node cannot know which\n * topics its sockets joined - `socket.subscribe()` goes straight into Bun - and\n * `psubscribe` is unusable. The cost is that every node reads every relayed\n * frame and drops the ones for topics it has no local subscriber on, which is a\n * `server.publish` returning `0`. Two apps sharing a Redis need two channels.\n *\n * @default 'dunx:ws'\n */\n readonly channel?: string;\n /**\n * Where a relay failure goes. Called once when the relay starts failing and not\n * again until it works, so an unreachable broker cannot flood the log.\n *\n * @default console.warn\n */\n readonly onError?: (error: unknown, phase: RelayPhase) => void;\n /**\n * What to do when the **boot** subscribe fails. Publishing recovers on its own -\n * every publish retries the broker - but a failed subscribe used to be retried\n * by nothing, so the node stayed permanently deaf to other nodes while still\n * looking healthy.\n *\n * Bounded rather than infinite, and the timer is unref'd, so a broker that never\n * comes back cannot hold the process open or spin forever.\n */\n readonly resubscribe?: {\n /** Retries after the first failure. `0` disables them. @default 5 */\n readonly attempts?: number;\n /** First delay; doubles each attempt, capped at 30s. @default 500 */\n readonly delayMs?: number;\n };\n}\n\nexport const DEFAULT_RELAY_CHANNEL = 'dunx:ws';\n\nexport const defaultRelayError = (error: unknown, phase: RelayPhase): void => {\n console.warn(\n `[dunx/http] the websocket relay could not ${phase}. Fan-out is local to ` +\n 'this process until it recovers:',\n error,\n );\n};\n\n/**\n * One relayed publish: which process published it, which topic it belongs to, and\n * the frame itself. `origin` is the whole duplicate-delivery defence - the broker\n * echoes a publish back to the publisher, and fanning that out locally a second\n * time would give every client on the originating node the message twice.\n */\nexport interface RelayFrame {\n readonly origin: string;\n readonly topic: string;\n readonly data: string | Uint8Array<ArrayBufferLike>;\n}\n\nconst toBytes = (data: Bun.BufferSource): Uint8Array<ArrayBufferLike> =>\n ArrayBuffer.isView(data)\n ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength)\n : new Uint8Array(data);\n\nexport const encodeRelay = (\n origin: string,\n topic: string,\n data: string | Bun.BufferSource,\n): string =>\n typeof data === 'string'\n ? JSON.stringify({ o: origin, t: topic, d: data })\n : // Base64 through Buffer, which Bun implements natively. A binary frame has\n // to survive a text channel, and Redis pub/sub payloads are text here\n // because Bun's buffer-mode subscription is not implemented.\n JSON.stringify({\n o: origin,\n t: topic,\n d: Buffer.from(toBytes(data)).toString('base64'),\n b: 1,\n });\n\n/** `undefined` for anything that is not one of our frames, which is then ignored. */\nexport const decodeRelay = (message: string): RelayFrame | undefined => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(message);\n } catch {\n return undefined;\n }\n if (typeof parsed !== 'object' || parsed === null) return undefined;\n\n const { o, t, d, b } = parsed as {\n o?: unknown;\n t?: unknown;\n d?: unknown;\n b?: unknown;\n };\n if (typeof o !== 'string' || typeof t !== 'string' || typeof d !== 'string') {\n return undefined;\n }\n return { origin: o, topic: t, data: b ? Buffer.from(d, 'base64') : d };\n};\n",
22
+ "import type { BunRequest, Server } from 'bun';\nimport {\n AppError,\n Logger,\n type App,\n type AppOptions,\n type Ctor,\n type InjectionToken,\n type ShutdownSignal,\n} from '@dunx/core';\nimport { joinPath, type DiscoveredRoute } from '../route/discover.js';\nimport type { WebSocketRuntime } from '../ws/adapter.js';\nimport { PubSub } from '../ws/pubsub.js';\nimport type { PubSubRelay, RelayPhase } from '../ws/relay.js';\nimport type { SocketData, SocketOptions } from '../ws/socket.js';\nimport { attachAddressSource, ClientAddress } from './client-address.js';\nimport type { CorsOptions } from './cors.js';\nimport { defaultErrorMapper, type ErrorMapper } from './errors.js';\nimport type { Middleware } from './middleware.js';\nimport {\n RequestLoggingMiddleware,\n type RequestLoggingOptions,\n} from './request-logging.js';\nimport {\n assertNoGatewayCollisions,\n buildFallback,\n buildRoutes,\n withUpgradeRoutes,\n} from './routes.js';\nimport { defaultSettings, type AppSettings } from './settings.js';\n\nexport interface HttpOptions extends AppOptions {\n readonly port?: number;\n /** Resolved from the container, so middleware can inject(). */\n readonly middleware?: readonly Ctor<Middleware>[];\n readonly onError?: ErrorMapper;\n /**\n * One structured entry per request, on by default. `false` removes it; an\n * options object tunes what it records. See {@link RequestLoggingMiddleware}.\n *\n * It is the **outermost** middleware, ahead of anything `middleware` declares,\n * so a request rejected by a guard is still logged with the status it got.\n */\n readonly requestLogging?: boolean | RequestLoggingOptions;\n /**\n * Bun's `websocket` options, plus where a throwing handler goes. Server-wide, so\n * they live here next to `middleware` rather than on a module: gateways\n * themselves are declared in `@Module({ providers })`.\n */\n readonly websocket?: SocketOptions;\n /**\n * Multi-node websocket fan-out. Absent - the default - means `PubSub` publishes\n * to this process only, which is exactly Bun's native pub/sub and costs nothing.\n *\n * `new RedisRelay({ url })` is the batteries-included one. Anything with a\n * `publish` and a `subscribe` fits, including `@dunx/infra`'s `RedisConnection`,\n * which has to come out of the container and so goes through\n * `app.get(PubSub).relayThrough(...)` instead of this option.\n */\n readonly relay?: PubSubRelay;\n /** The broker channel the relay carries frames on. @default 'dunx:ws' */\n readonly relayChannel?: string;\n}\n\n/**\n * Everything below `listen()` configures the route table, which is built exactly\n * once - when the server binds. Calling any of them afterwards throws rather than\n * being quietly dropped.\n */\nexport interface HttpApp extends App {\n /** Prefixes every discovered route. Last call wins. */\n setGlobalPrefix(prefix: string): this;\n /** Appends middleware, after anything `HttpOptions.middleware` declared. */\n use(...middleware: readonly Ctor<Middleware>[]): this;\n set<K extends keyof AppSettings>(key: K, value: AppSettings[K]): this;\n setting<K extends keyof AppSettings>(key: K): AppSettings[K];\n /** Mounts an `OPTIONS` preflight per path. Last call wins. */\n enableCors(options?: CorsOptions): this;\n /** The same `inject(ClientAddress)` singleton - honours `'trust proxy'`. */\n clientIp(req: BunRequest): string | undefined;\n /** Every gateway path this app upgrades on, exactly as mounted. */\n readonly gatewayPaths: readonly string[];\n listen(port?: number): Promise<string>;\n}\n\nexport class HttpApplication implements HttpApp {\n readonly closed: Promise<void>;\n readonly gatewayPaths: readonly string[];\n readonly #app: App;\n readonly #discovered: readonly DiscoveredRoute[];\n readonly #middleware: Ctor<Middleware>[];\n readonly #settings: AppSettings = defaultSettings();\n readonly #onError: ErrorMapper;\n readonly #port: number;\n readonly #websocket: WebSocketRuntime | undefined;\n readonly #relay: PubSubRelay | undefined;\n readonly #relayChannel: string | undefined;\n #globalPrefix = '';\n #cors: CorsOptions | undefined;\n #started = false;\n #server: Server<SocketData> | undefined;\n #resolveClosed: (() => void) | undefined;\n #shuttingDown: Promise<void> | undefined;\n #hooked = false;\n\n constructor(\n app: App,\n discovered: readonly DiscoveredRoute[],\n options: HttpOptions,\n websocket?: WebSocketRuntime,\n ) {\n this.#app = app;\n this.#discovered = discovered;\n this.#middleware = [\n ...(options.requestLogging === false ? [] : [RequestLoggingMiddleware]),\n ...(options.middleware ?? []),\n ];\n this.#onError = options.onError ?? defaultErrorMapper;\n this.#port = options.port ?? 3000;\n this.#websocket = websocket;\n this.#relay = options.relay;\n this.#relayChannel = options.relayChannel;\n this.gatewayPaths = websocket?.paths ?? [];\n this.closed = new Promise<void>((resolve) => {\n this.#resolveClosed = resolve;\n });\n }\n\n get<T>(token: InjectionToken<T>): T {\n return this.#app.get(token);\n }\n\n setGlobalPrefix(prefix: string): this {\n this.#assertNotStarted('setGlobalPrefix()');\n this.#globalPrefix = prefix;\n return this;\n }\n\n use(...middleware: readonly Ctor<Middleware>[]): this {\n this.#assertNotStarted('use()');\n this.#middleware.push(...middleware);\n return this;\n }\n\n set<K extends keyof AppSettings>(key: K, value: AppSettings[K]): this {\n this.#assertNotStarted('set()');\n this.#settings[key] = value;\n return this;\n }\n\n setting<K extends keyof AppSettings>(key: K): AppSettings[K] {\n return this.#settings[key];\n }\n\n enableCors(options: CorsOptions = {}): this {\n this.#assertNotStarted('enableCors()');\n this.#cors = options;\n return this;\n }\n\n clientIp(req: BunRequest): string | undefined {\n return this.#app.get(ClientAddress).of(req);\n }\n\n /**\n * The one `Bun.serve` call. A gateway's upgrade is a native `GET` route in the\n * same table, so Bun's router - not a hand-written `fetch` fallback - is what\n * matches an upgrade, and no `fetch` handler is needed at all.\n */\n async listen(port = this.#port): Promise<string> {\n this.#assertNotStarted('listen()');\n this.#started = true;\n\n const middleware = this.#middleware.map((entry) => this.#app.get(entry));\n const prefixed = this.#prefixed();\n // A `@UseGuards` class comes from the container too, so a guard injects exactly\n // like global middleware does.\n const routes = buildRoutes(\n prefixed,\n middleware,\n this.#onError,\n this.#cors,\n (guard) => this.#app.get(guard),\n );\n\n const ws = this.#websocket;\n if (ws) assertNoGatewayCollisions(prefixed, ws.paths);\n\n // Bun's own 404 never reaches the middleware chain, so an unmatched path is\n // invisible to request logging. This runs only after Bun has matched nothing,\n // so Bun is still the router - it just puts the global middleware in front of\n // the 404 and returns it in the framework's error shape.\n const fetch = buildFallback(middleware, this.#onError, this.#cors);\n\n // Two literals, one call: a route that may answer `undefined` because it\n // upgraded is only a valid route table when `websocket` is there to receive it,\n // and Bun's own types say so.\n const options: Bun.Serve.Options<SocketData> = ws\n ? {\n port,\n fetch,\n routes: withUpgradeRoutes(routes, ws.routes),\n websocket: ws.websocket,\n }\n : { port, fetch, routes };\n this.#server = Bun.serve(options);\n\n attachAddressSource(this.#app.get(ClientAddress), {\n server: this.#server,\n trustProxy: this.#settings['trust proxy'],\n });\n const pubsub = this.#app.get(PubSub);\n pubsub.attach(this.#server);\n // After attach, so a frame that arrives during the subscribe already has a\n // server to fan out on. Awaited so a two-node deployment is subscribed by the\n // time listen() resolves; an unreachable broker fails fast and degrades.\n if (this.#relay) {\n const logger = this.#app.get(Logger);\n await pubsub.relayThrough(this.#relay, {\n ...(this.#relayChannel !== undefined && {\n channel: this.#relayChannel,\n }),\n onError: (error: unknown, phase: RelayPhase) => {\n logger.warn(\n `the websocket relay could not ${phase}. Fan-out is local to this ` +\n 'process until it recovers.',\n { error },\n );\n },\n });\n }\n return this.#server.url.href;\n }\n\n // Not delegated to the core app: the server has to stop before providers tear\n // down, so the signal handler must land here. With a gateway the stop is forced -\n // a graceful stop waits for open connections and a WebSocket does not close on\n // its own, so it would hang. Those clients see a 1006 close.\n async shutdown(): Promise<void> {\n this.#shuttingDown ??= (async () => {\n await this.#server?.stop(this.#websocket !== undefined);\n this.#server = undefined;\n // Before the container: a relay this app owns holds two Redis sockets, and\n // `maxRetries: 0` means nothing else will ever close them.\n await this.#app.get(PubSub).close();\n await this.#app.shutdown();\n this.#resolveClosed?.();\n })();\n return this.#shuttingDown;\n }\n\n enableShutdownHooks(\n signals: readonly ShutdownSignal[] = ['SIGTERM', 'SIGINT'],\n ): this {\n if (this.#hooked) return this;\n this.#hooked = true;\n for (const signal of signals) {\n process.once(signal, () => void this.shutdown());\n }\n return this;\n }\n\n // Collision detection re-runs inside buildRoutes on these final paths.\n #prefixed(): readonly DiscoveredRoute[] {\n if (this.#globalPrefix === '') return this.#discovered;\n return this.#discovered.map((route) => ({\n ...route,\n path: joinPath(this.#globalPrefix, route.path),\n }));\n }\n\n // #started rather than #server, which shutdown() clears - a hook called after\n // the server stopped is just as ineffective as one called while it ran.\n #assertNotStarted(hook: string): void {\n if (!this.#started) return;\n throw new AppError(\n `${hook} must be called before listen(). The route table and the middleware ` +\n 'chain are folded into one closure per route when the server binds, so ' +\n 'this call could not take effect.',\n );\n }\n}\nObject.defineProperty(HttpApplication, Symbol.for('dunx.deps'), {\n value: () => [{ unresolved: \"app: App\" }, { unresolved: \"discovered: readonly DiscoveredRoute[]\" }, { unresolved: \"options: HttpOptions\" }, { unresolved: \"websocket?: WebSocketRuntime\" }],\n});\n",
23
+ "import { Logger, RequestContext } from '@dunx/core';\nimport type { BunRequest } from 'bun';\nimport type { RouteContext } from './context.js';\nimport { HttpError } from './errors.js';\nimport type { Middleware, Next } from './middleware.js';\nimport { HttpStatusCode } from './status.js';\n\nexport const REQUEST_ID_HEADER = 'x-request-id';\n\nexport interface RequestLoggingOptions {\n /** Bodies past this many characters are logged as a size. Default 2048. `0` omits them. */\n readonly maxBodyLength?: number;\n /**\n * Log the request body. Default **`false`**.\n *\n * Reading it means `req.clone().text()` - a second copy of every payload,\n * buffered and parsed, on the hot path. Measured on the `validate` scenario in\n * `tools/bench`, turning both body options on costs roughly two thirds of the\n * throughput. It is also the field most likely to contain a password.\n *\n * Turn it on in development, where seeing the payload is the point.\n */\n readonly requestBody?: boolean;\n /** Log the response body. Default **`false`** - same clone-and-buffer cost. */\n readonly responseBody?: boolean;\n /** Paths to skip entirely - a health check polled every second, say. */\n readonly ignore?: readonly string[];\n}\n\nconst parse = (text: string, limit: number): unknown => {\n if (limit === 0) return undefined;\n if (text.length === 0) return undefined;\n if (text.length > limit) return `[${text.length} bytes]`;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n};\n\nconst elapsedMs = (started: number): number =>\n Math.round((Bun.nanoseconds() - started) / 1e6);\n\n/** What the entry's `request` field carries, built in the order it is logged. */\ntype RequestFields = Record<string, unknown>;\n\n/**\n * One structured entry per request, carrying the request and its response.\n *\n * Installed by `HttpFactory.create` unless `requestLogging: false`. It injects\n * `Logger` and `RequestContext` - both `@dunx/core` contracts, both bound by\n * default - so it works with no logging module imported, and picks up\n * `@arkv/logger` automatically once `@dunx/infra/logger` is.\n *\n * **One entry, not two.** Nest needs a middleware for the inbound half and an\n * interceptor for the outbound one, because they are different classes and the\n * interceptor cannot see what the middleware saw. Here they are the same\n * closure, so there is no pair to correlate by `requestId` to find out how a\n * call ended. A 4xx is the same line at `warn`, a 5xx at `error`.\n *\n * Everything the handler logs in between carries `requestId`, `method`, `event`\n * and `context` without being passed anything, because the whole call runs\n * inside `runWithContext`.\n *\n * **Nothing here is `async`.** Reading the request or the response body are the\n * only steps that can ever wait, both are off by default, and both are adopted\n * with `.then` rather than awaited - the same rule `input.ts` follows, for the\n * same measured reason. An `async` scope callback alone cost 0.44 µs/request\n * against a synchronous one on raw `Bun.serve`.\n */\nexport class RequestLoggingMiddleware implements Middleware {\n readonly #limit: number;\n readonly #requestBody: boolean;\n readonly #responseBody: boolean;\n readonly #ignore: ReadonlySet<string>;\n\n constructor(\n private readonly logger: Logger,\n private readonly context: RequestContext,\n options: RequestLoggingOptions = {},\n ) {\n this.#limit = options.maxBodyLength ?? 2048;\n this.#requestBody = options.requestBody ?? false;\n this.#responseBody = options.responseBody ?? false;\n this.#ignore = new Set(options.ignore ?? []);\n }\n\n handle(req: BunRequest, ctx: RouteContext, next: Next): Promise<Response> {\n // `new URL(req.url)` parses the scheme, host, port, query and hash to reach one\n // string. This finds the same two offsets once and slices both the pathname and\n // the query out of them, which is what every request needs and all that most of\n // them need.\n const url = req.url;\n const from = url.indexOf('/', url.indexOf('://') + 3);\n const mark = from === -1 ? -1 : url.indexOf('?', from);\n const path =\n from === -1 ? '/' : mark === -1 ? url.slice(from) : url.slice(from, mark);\n if (this.#ignore.size > 0 && this.#ignore.has(path)) return next();\n\n const started = Bun.nanoseconds();\n // An inbound id is honoured so a trace survives across services; otherwise\n // this is where one is minted.\n const requestId = req.headers.get(REQUEST_ID_HEADER) ?? crypto.randomUUID();\n\n return this.context.runWithContext(\n {\n requestId,\n method: ctx.method,\n event: path,\n flow: 'http',\n context: `${ctx.controller}.${ctx.handler}`,\n },\n () => {\n const request: RequestFields = {};\n if (mark !== -1) {\n request['query'] = Object.fromEntries(\n new URLSearchParams(url.slice(mark + 1)),\n );\n }\n const body = this.#body(req);\n if (body === undefined) {\n request['userAgent'] = req.headers.get('user-agent');\n return this.#dispatch(req, path, requestId, started, request, next);\n }\n return body.then((value) => {\n if (value !== undefined) request['body'] = value;\n request['userAgent'] = req.headers.get('user-agent');\n return this.#dispatch(req, path, requestId, started, request, next);\n });\n },\n );\n }\n\n #dispatch(\n req: BunRequest,\n path: string,\n requestId: string,\n started: number,\n request: RequestFields,\n next: Next,\n ): Promise<Response> {\n // `next()` is only ever a promise once the chain bottoms out in a route, but a\n // user middleware ahead of the route may throw out of `handle` synchronously,\n // and that request is still one this middleware promised to log.\n let settled: Promise<Response>;\n try {\n settled = next();\n } catch (error) {\n this.#failed(req, path, started, request, error);\n throw error;\n }\n return settled.then(\n (response) =>\n this.#succeeded(req, path, requestId, started, request, response),\n (error: unknown) => {\n this.#failed(req, path, started, request, error);\n throw error;\n },\n );\n }\n\n /**\n * Logged and rethrown: the error mapper still owns the status and the response\n * shape. A 404 or a rejected body is the caller's fault, and logging every probe\n * at `error` would drown the ones that matter.\n */\n #failed(\n req: BunRequest,\n path: string,\n started: number,\n request: RequestFields,\n error: unknown,\n ): void {\n const status =\n error instanceof HttpError\n ? error.status\n : HttpStatusCode.INTERNAL_SERVER_ERROR;\n const entry = {\n request,\n err: error,\n statusCode: status,\n elapsedMs: elapsedMs(started),\n };\n const line = `${req.method} ${path} ${status}`;\n if (status < HttpStatusCode.INTERNAL_SERVER_ERROR) {\n this.logger.warn(line, entry);\n } else {\n this.logger.error(line, entry);\n }\n }\n\n #succeeded(\n req: BunRequest,\n path: string,\n requestId: string,\n started: number,\n request: RequestFields,\n response: Response,\n ): Response | Promise<Response> {\n const body = this.#responseFields(response);\n if (body === undefined) {\n this.logger.info(`${req.method} ${path} ${response.status}`, {\n request,\n statusCode: response.status,\n elapsedMs: elapsedMs(started),\n });\n response.headers.set(REQUEST_ID_HEADER, requestId);\n return response;\n }\n return body.then((value) => {\n this.logger.info(`${req.method} ${path} ${response.status}`, {\n request,\n statusCode: response.status,\n ...(value === undefined ? {} : { responseBody: value }),\n elapsedMs: elapsedMs(started),\n });\n response.headers.set(REQUEST_ID_HEADER, requestId);\n return response;\n });\n }\n\n /**\n * `undefined` - the default - means there is nothing to read, and the caller\n * stays on the synchronous path. Clones when there is, so the handler's own\n * stream is never the one that was consumed.\n */\n #body(req: BunRequest): Promise<unknown> | undefined {\n if (!this.#requestBody) return undefined;\n if (req.method === 'GET' || req.method === 'HEAD') return undefined;\n if (!(req.headers.get('content-type') ?? '').includes('application/json')) {\n return undefined;\n }\n return req\n .clone()\n .text()\n .then((text) => parse(text, this.#limit));\n }\n\n #responseFields(response: Response): Promise<unknown> | undefined {\n if (!this.#responseBody) return undefined;\n if (\n !(response.headers.get('content-type') ?? '').includes('application/json')\n ) {\n return undefined;\n }\n return response\n .clone()\n .text()\n .then((text) => parse(text, this.#limit));\n }\n}\nObject.defineProperty(RequestLoggingMiddleware, Symbol.for('dunx.deps'), {\n value: () => [Logger, RequestContext, { unresolved: \"options: RequestLoggingOptions = {}\" }],\n});\n",
24
+ "import { AppError, type Ctor } from '@dunx/core';\nimport type { BunRequest } from 'bun';\nimport type { DiscoveredRoute } from '../route/discover.js';\nimport type { HttpMethod } from '../route/marker.js';\nimport type { RouteInput } from '../route/schema.js';\nimport type { UpgradeHandler } from '../ws/adapter.js';\nimport { buildContext, type RouteContext } from './context.js';\nimport { preflight, withCors, type CorsOptions } from './cors.js';\nimport { defaultErrorMapper, HttpError, type ErrorMapper } from './errors.js';\nimport { buildInputReader, type InputReader } from './input.js';\nimport {\n compose,\n type Middleware,\n type RouteHandler,\n type ServedHandler,\n} from './middleware.js';\nimport { HttpStatusCode } from './status.js';\n\n/** How a `@UseGuards` class becomes an instance. `listen()` passes `app.get`. */\nexport type GuardResolver = (guard: Ctor<Middleware>) => Middleware;\n\nconst construct: GuardResolver = (guard) =>\n new (guard as new () => Middleware)();\n\n/** `OPTIONS` is never a `@Get`-style route - only CORS mounts one. */\nexport type RouteMethod = HttpMethod | 'OPTIONS';\n\nexport type BunRoutes = Record<\n string,\n Partial<Record<RouteMethod, ServedHandler>>\n>;\n\n/**\n * What `listen()` hands `Bun.serve`: the HTTP table plus one `GET` per gateway,\n * whose handler may answer `undefined` because the socket was upgraded.\n */\nexport type ServeRoutes = Record<\n string,\n Partial<Record<RouteMethod, ServedHandler | UpgradeHandler>>\n>;\n\n/**\n * A `Response` passes through untouched - that is the escape hatch, and nothing\n * about it is worth second-guessing. Nothing at all is a 204: `Response.json(null)`\n * would be a body claiming to be no body.\n */\nconst toResponse = (value: unknown, status: number): Response => {\n if (value instanceof Response) return value;\n if (value === undefined || value === null) {\n return new Response(null, { status: HttpStatusCode.NO_CONTENT });\n }\n return Response.json(value, { status });\n};\n\n/** Nest's rule: an explicit `status`, else 201 for POST, else 200. */\nconst statusFor = (route: DiscoveredRoute): number =>\n route.options?.status ??\n (route.method === 'POST' ? HttpStatusCode.CREATED : HttpStatusCode.OK);\n\n/**\n * Bun silently lets one route win on a collision, so a duplicate method+path is a\n * boot error naming both handlers. Run twice: once at `create()` on the discovered\n * paths, and again from `buildRoutes` at `listen()` on the final, prefixed ones.\n */\nexport const assertNoCollisions = (\n discovered: readonly DiscoveredRoute[],\n): void => {\n const owners = new Map<string, string>();\n\n for (const route of discovered) {\n const key = `${route.method} ${route.path}`;\n const owner = `${route.controller}.${route.handlerName}`;\n const existing = owners.get(key);\n\n if (existing !== undefined) {\n throw new AppError(\n `Route collision: ${key} is declared by ${existing} and by ${owner}. ` +\n 'Bun would keep only one of them.',\n );\n }\n owners.set(key, owner);\n }\n};\n\n/**\n * A gateway's upgrade is a native route like any other, so a path claimed by both a\n * controller and a gateway would lose one of them when the two tables merge.\n */\nexport const assertNoGatewayCollisions = (\n discovered: readonly DiscoveredRoute[],\n gatewayPaths: readonly string[],\n): void => {\n const gateways = new Set(gatewayPaths);\n\n for (const route of discovered) {\n if (gateways.has(route.path)) {\n throw new AppError(\n `Gateway path collision: ${route.path} is served by a gateway and by ` +\n `${route.controller}.${route.handlerName}(). The upgrade is a route too, ` +\n 'so one of them would be dropped.',\n );\n }\n }\n};\n\n/**\n * The two tables in one. A gateway's `GET` is what Bun's router matches on an\n * upgrade - the reason no `fetch` handler is needed for a socket to connect.\n */\nexport const withUpgradeRoutes = (\n routes: BunRoutes,\n gateways: ReadonlyMap<string, UpgradeHandler>,\n): ServeRoutes => {\n const merged: ServeRoutes = { ...routes };\n for (const [path, upgrade] of gateways) merged[path] = { GET: upgrade };\n return merged;\n};\n\n/**\n * The context an unmatched request gets. There is no controller and no handler,\n * and saying so is more useful to a log line than an empty string.\n */\nconst unmatchedContext = (req: Request): RouteContext =>\n Object.freeze({\n controller: '(unmatched)',\n handler: '(none)',\n method: req.method as HttpMethod,\n path: new URL(req.url).pathname,\n get: () => undefined,\n });\n\n/**\n * Bun answers an unmatched path itself, so nothing in the middleware chain ever\n * sees it - which makes a 404 invisible to request logging, metrics and tracing.\n *\n * This is the only `fetch` handler dunx installs, and it is not a router: Bun\n * still does all the matching, and this runs only once Bun has decided nothing\n * matched. It puts the global middleware in front of a 404 in the framework's\n * own error shape.\n *\n * Composed per request rather than at boot, because the context names the path\n * that missed. That allocation is on the 404 path only.\n */\nexport const buildFallback = (\n middleware: readonly Middleware[] = [],\n onError: ErrorMapper = defaultErrorMapper,\n cors?: CorsOptions,\n): RouteHandler => {\n // The canonical status name, not a sentence naming the path back at the\n // caller: an unmatched path is the one place where echoing the request would\n // tell a prober something about the surface it just failed to find.\n const miss: RouteHandler = () => {\n throw new HttpError(HttpStatusCode.NOT_FOUND, 'NOT_FOUND');\n };\n\n const run: RouteHandler = async (req) => {\n try {\n return await compose(middleware, unmatchedContext(req), miss)(req);\n } catch (error) {\n return onError(error, req);\n }\n };\n\n return cors ? withCors(cors, run) : run;\n};\n\n/**\n * The direct path, taken when a route has no middleware and no CORS. Nothing here\n * is `async`: every step looks at what it got and only allocates a promise when\n * there is genuinely something to wait for.\n *\n * The general path is `async (req) => toResponse(await handler(await read(req)))`\n * inside an `async` try/catch - four `await`s across two async frames, on values\n * that are usually not thenable at all. A route with no declared schemas awaits\n * nothing; a route with only `query` or `params` awaits nothing either, because\n * every Standard Schema validator worth using is synchronous. Even a `body` route,\n * which really does have to wait for `req.json()`, pays one promise link instead of\n * six frames.\n *\n * Worth ~6 points of throughput against raw `Bun.serve` on the `params` scenario\n * when it covered only schema-less routes, and a further ~5 on `validate` when it\n * was extended to cover reading ones - which is most of what separated dunx from\n * Elysia, whose whole trick is compiling this shape ahead of time.\n *\n * A handler or a validator that *does* return a promise still works: it is adopted\n * here rather than awaited by a wrapper.\n */\nconst directOr = (\n guarded: RouteHandler,\n route: DiscoveredRoute,\n read: InputReader,\n status: number,\n onError: ErrorMapper,\n noMiddleware: boolean,\n): ServedHandler => {\n if (!noMiddleware) return guarded;\n\n // `toResponse` throws on a value `JSON.stringify` cannot take, so it is inside\n // the mapper's reach on every branch - including the `then` callbacks, where a\n // throw would otherwise escape as an unhandled rejection instead of a 500.\n const settle = (value: unknown, req: BunRequest): Response => {\n try {\n return toResponse(value, status);\n } catch (error) {\n return onError(error, req);\n }\n };\n\n const invoke = (\n input: RouteInput,\n req: BunRequest,\n ): Response | Promise<Response> => {\n try {\n const value = route.handler(input);\n return value instanceof Promise\n ? value.then(\n (resolved) => settle(resolved, req),\n (error: unknown) => onError(error, req),\n )\n : settle(value, req);\n } catch (error) {\n return onError(error, req);\n }\n };\n\n return (req) => {\n try {\n const input = read(req);\n return input instanceof Promise\n ? input.then(\n (resolved) => invoke(resolved, req),\n (error: unknown) => onError(error, req),\n )\n : invoke(input, req);\n } catch (error) {\n return onError(error, req);\n }\n };\n};\n\nexport const buildRoutes = (\n discovered: readonly DiscoveredRoute[],\n middleware: readonly Middleware[] = [],\n onError: ErrorMapper = defaultErrorMapper,\n cors?: CorsOptions,\n resolve: GuardResolver = construct,\n): BunRoutes => {\n assertNoCollisions(discovered);\n const routes: BunRoutes = {};\n // One instance per guard class for the whole table - what the container returns,\n // and what the default resolver has to match to be interchangeable with it.\n const instances = new Map<Ctor<Middleware>, Middleware>();\n const guardOf = (guard: Ctor<Middleware>): Middleware => {\n const existing = instances.get(guard);\n if (existing) return existing;\n const created = resolve(guard);\n instances.set(guard, created);\n return created;\n };\n\n for (const route of discovered) {\n // Schemas, parsers, the status and the route context resolve here, once. What\n // survives into the request path is one closure that reads no metadata.\n const read = buildInputReader(route.options);\n const status = statusFor(route);\n // Global outermost, then the controller's guards, then the method's.\n const chain = [...middleware, ...(route.guards ?? []).map(guardOf)];\n const chained = compose(chain, buildContext(route), async (req) =>\n toResponse(await route.handler(await read(req)), status),\n );\n const guarded: RouteHandler = async (req) => {\n try {\n return await chained(req);\n } catch (error) {\n return onError(error, req);\n }\n };\n\n const byMethod = (routes[route.path] ??= {});\n // Outside the error mapper, so a mapped 500 still carries the CORS headers the\n // browser needs in order to show it.\n byMethod[route.method] = cors\n ? withCors(cors, guarded)\n : directOr(guarded, route, read, status, onError, chain.length === 0);\n }\n\n if (cors) {\n for (const byMethod of Object.values(routes)) {\n byMethod.OPTIONS = preflight(cors, Object.keys(byMethod));\n }\n }\n\n return routes;\n};\n",
25
+ "import type { BunRequest } from 'bun';\nimport type {\n RouteInput,\n RouteSchemas,\n StandardSchemaIssue,\n StandardSchemaResult,\n StandardSchemaV1,\n} from '../route/schema.js';\nimport {\n HttpError,\n ValidationError,\n type InputSource,\n type ValidationIssue,\n} from './errors.js';\nimport { HttpStatusCode } from './status.js';\n\n/**\n * Built once per route at boot. A route that declares nothing gets the identity\n * reader - no parse, no validation, not even a promise.\n *\n * A reader **returns a promise only when it has something to wait for**. A `body`\n * schema always does; `query` and `params` against a synchronous validator - which\n * zod, Valibot and ArkType all are - resolve without one.\n */\nexport type InputReader = (req: BunRequest) => RouteInput | Promise<RouteInput>;\n\ninterface InputDraft {\n req: BunRequest;\n body?: unknown;\n query?: unknown;\n params?: unknown;\n}\n\n/**\n * One declared schema's contribution to the draft, returning the draft so the\n * steps chain without a wrapper. A bare `InputDraft` means it finished\n * synchronously, which is the common case and the reason this is not `async`:\n * Standard Schema *permits* a promise, so awaiting unconditionally costs an async\n * frame and a microtask tick per schema for a validator that never returns one.\n */\ntype Fill = (draft: InputDraft) => InputDraft | Promise<InputDraft>;\ntype BodyParser = (req: BunRequest) => Promise<unknown>;\n\n/** What `URLSearchParams` and `FormData` both offer, and all {@link grouped} needs. */\ninterface Enumerable {\n forEach(visit: (value: unknown, key: string) => void): void;\n}\n\n/**\n * A repeated key becomes an array, so `?tag=a&tag=b` reaches the schema whole\n * instead of silently losing `a`. Shared by query strings, urlencoded bodies and\n * multipart form data.\n *\n * `forEach` rather than `for…of`: both collections implement it natively, and\n * destructuring an iterator allocates a two-element array per entry. Measured at\n * ~150 ns/request cheaper on a three-pair query string.\n */\nconst grouped = (entries: Enumerable): Record<string, unknown> => {\n const collected: Record<string, unknown> = {};\n\n entries.forEach((value, key) => {\n const existing = collected[key];\n if (existing === undefined) collected[key] = value;\n else if (Array.isArray(existing)) (existing as unknown[]).push(value);\n else collected[key] = [existing, value];\n });\n\n return collected;\n};\n\nconst asJson: BodyParser = (req) => req.json();\nconst asUrlEncoded: BodyParser = async (req) =>\n grouped(new URLSearchParams(await req.text()));\nconst asMultipart: BodyParser = async (req) => grouped(await req.formData());\nconst asText: BodyParser = (req) => req.text();\n\n/** `application/vnd.api+json` and friends parse as JSON; `text/csv` as text. */\nconst parserFor = (media: string): BodyParser | undefined => {\n if (media === 'application/json' || media.endsWith('+json')) return asJson;\n if (media === 'application/x-www-form-urlencoded') return asUrlEncoded;\n if (media === 'multipart/form-data') return asMultipart;\n if (media.startsWith('text/')) return asText;\n return undefined;\n};\n\nconst JSON_MEDIA = 'application/json';\n\n// No content-type reads as JSON: fetch omits the header for a bodyless request and\n// a 415 there would be useless, since the schema is about to reject `undefined`.\nconst mediaTypeOf = (req: BunRequest): string => {\n const header = req.headers.get('content-type');\n // The header almost every JSON client sends, verbatim - worth not slicing,\n // trimming and lowercasing on the hot path.\n if (header === JSON_MEDIA || header === null) return JSON_MEDIA;\n const end = header.indexOf(';');\n const media = (end === -1 ? header : header.slice(0, end)).trim();\n return media === '' ? JSON_MEDIA : media.toLowerCase();\n};\n\nconst flatten = (issue: StandardSchemaIssue): ValidationIssue => {\n const path = issue.path\n ?.map((segment) =>\n String(typeof segment === 'object' ? segment.key : segment),\n )\n .join('.');\n\n return path === undefined || path === ''\n ? { message: issue.message }\n : { message: issue.message, path };\n};\n\n/** A rejected schema is a 400 carrying every issue, path flattened to dots. */\nconst accept = (source: InputSource, result: StandardSchemaResult<unknown>) => {\n if (result.issues !== undefined) {\n throw new ValidationError(source, result.issues.map(flatten));\n }\n return result.value;\n};\n\n/**\n * Validates, assigns, and hands the draft back. Returning the draft rather than\n * `void` is what lets the reader be `(req) => fill({ req })`: a body route then\n * costs one promise link in total, where threading the draft back through a second\n * `then` cost two - worth ~120 ns per request, measured.\n */\nconst fillWith = (\n draft: InputDraft,\n source: InputSource,\n schema: StandardSchemaV1,\n value: unknown,\n): InputDraft | Promise<InputDraft> => {\n const result = schema['~standard'].validate(value);\n\n if (result instanceof Promise) {\n return result.then((settled) => {\n draft[source] = accept(source, settled);\n return draft;\n });\n }\n draft[source] = accept(source, result);\n return draft;\n};\n\nconst bodyFill =\n (schema: StandardSchemaV1): Fill =>\n (draft) => {\n const media = mediaTypeOf(draft.req);\n const parse = parserFor(media);\n\n if (parse === undefined) {\n throw new HttpError(\n HttpStatusCode.UNSUPPORTED_MEDIA_TYPE,\n `Unsupported content type \"${media}\". Declared bodies accept ` +\n 'application/json, application/x-www-form-urlencoded, multipart/form-data or text/*.',\n );\n }\n\n // Both handlers on one `then`, so the parse costs a single promise link. A\n // `ValidationError` from the success handler is deliberately not visible to the\n // rejection handler - only an unreadable or mangled body is a parse failure.\n return parse(draft.req).then(\n (value) => fillWith(draft, 'body', schema, value),\n (error: unknown) => {\n // A body the caller mangled is a 400. Only an unreadable stream would be ours.\n throw new HttpError(\n HttpStatusCode.BAD_REQUEST,\n `Malformed ${media} body`,\n { cause: error },\n );\n },\n );\n };\n\n/**\n * The query string, without parsing the whole URL to reach it. `new URL(req.url)`\n * resolves scheme, host, port, path and fragment to hand back a `searchParams`, and\n * measured **~1,000 ns of the ~1,500 ns** a `query` route used to cost - more than\n * the entire body reader. `RequestLoggingMiddleware` took the same slice for the\n * same reason.\n *\n * The fragment is stripped even though a client is not supposed to send one, because\n * `new URL` stripped it and a hostile request-target should not change what a schema\n * sees.\n */\nconst searchOf = (url: string): string => {\n const start = url.indexOf('?');\n if (start === -1) return '';\n const end = url.indexOf('#', start + 1);\n return end === -1 ? url.slice(start + 1) : url.slice(start + 1, end);\n};\n\nconst queryFill =\n (schema: StandardSchemaV1): Fill =>\n (draft) => {\n const params = new URLSearchParams(searchOf(draft.req.url));\n return fillWith(draft, 'query', schema, grouped(params));\n };\n\nconst paramsFill =\n (schema: StandardSchemaV1): Fill =>\n (draft) =>\n fillWith(draft, 'params', schema, draft.req.params);\n\n/** Sequential, and stays sequential without a promise unless one is produced. */\nconst then =\n (first: Fill, second: Fill): Fill =>\n (draft) => {\n const started = first(draft);\n return started instanceof Promise ? started.then(second) : second(started);\n };\n\n/**\n * Folds the declared schemas into a single closure, the way `compose` folds\n * middleware: which parsers and validators run is decided here, at boot, so per\n * request there is no metadata to read and no branch left to take.\n */\nexport const buildInputReader = (\n options: RouteSchemas | undefined,\n): InputReader => {\n const fills: Fill[] = [];\n if (options?.body !== undefined) fills.push(bodyFill(options.body));\n if (options?.query !== undefined) fills.push(queryFill(options.query));\n if (options?.params !== undefined) fills.push(paramsFill(options.params));\n\n if (fills.length === 0) return (req) => ({ req });\n\n const fill = fills.reduce(then);\n return (req) => fill({ req });\n};\n",
26
+ "import type { BunRequest } from 'bun';\nimport type { RouteContext } from './context.js';\n\nexport type Next = () => Promise<Response>;\n\n/**\n * The single extension point. A guard is middleware that throws, an interceptor\n * wraps `next()`, a filter is the error mapper. `ctx` names the route and carries\n * what its decorators declared, resolved at boot - so a guard costs a Map lookup.\n */\nexport interface Middleware {\n handle(req: BunRequest, ctx: RouteContext, next: Next): Promise<Response>;\n}\n\nexport type RouteHandler = (req: BunRequest) => Promise<Response>;\n\n/**\n * What goes into the `Bun.serve` route table. Wider than `RouteHandler` because\n * Bun accepts a plain `Response`, which is what lets a route with nothing to\n * await skip promises altogether - see `buildRoutes`.\n */\nexport type ServedHandler = (req: BunRequest) => Response | Promise<Response>;\n\n/** Folded into one closure per route at boot - no per-request array iteration. */\nexport const compose = (\n middleware: readonly Middleware[],\n ctx: RouteContext,\n handler: RouteHandler,\n): RouteHandler =>\n middleware.reduceRight<RouteHandler>(\n (next, current) => (req) => current.handle(req, ctx, () => next(req)),\n handler,\n );\n",
27
+ "/**\n * The settings `app.set()` accepts. A key has to be declared here to be settable,\n * so the map is checked at compile time instead of being a string bag - a typo is\n * a type error, not a setting that silently never applies.\n */\nexport interface AppSettings {\n /**\n * Resolve the client address from `X-Forwarded-For` rather than the socket. Only\n * turn it on behind a proxy that rewrites the header: a direct client can send\n * whatever it likes.\n */\n 'trust proxy': boolean;\n}\n\nexport const defaultSettings = (): AppSettings => ({ 'trust proxy': false });\n",
28
28
  "import { HandlerKind, markGateway, markHandler } from './marker.js';\n\ntype GatewayTarget = abstract new (...args: never[]) => object;\n// never[] is what makes an arbitrary method signature assignable, so a handler\n// may declare the payload type it expects. See the README, \"Typed payloads\".\ntype HandlerMethod = (...args: never[]) => unknown;\n\nexport const Gateway =\n (path = '/') =>\n <T extends GatewayTarget>(target: T): T => {\n markGateway(target, path);\n return target;\n };\n\nconst lifecycle =\n (kind: HandlerKind) =>\n () =>\n <T extends HandlerMethod>(value: T): T => {\n markHandler(value, { kind, event: undefined });\n return value;\n };\n\n/** Runs before the socket exists. Return a `Response` to refuse the upgrade. */\nexport const OnUpgrade = lifecycle(HandlerKind.UPGRADE);\nexport const OnOpen = lifecycle(HandlerKind.OPEN);\nexport const OnClose = lifecycle(HandlerKind.CLOSE);\nexport const OnDrain = lifecycle(HandlerKind.DRAIN);\nexport const OnPing = lifecycle(HandlerKind.PING);\nexport const OnPong = lifecycle(HandlerKind.PONG);\n\n/**\n * With an event name, the handler is routed the `data` of any\n * `{\"event\":\"<name>\",\"data\":...}` frame. With none, it is the raw catch-all and\n * receives every frame no named handler claimed.\n */\nexport const OnMessage =\n (event?: string) =>\n <T extends HandlerMethod>(value: T): T => {\n markHandler(value, { kind: HandlerKind.MESSAGE, event });\n return value;\n };\n",
29
- "import { AppError } from '@dunx/core';\nimport type { PubSubRelay } from './relay.js';\n\n/**\n * The schemes `Bun.RedisClient` accepts. Checked here because Bun takes any string\n * and only fails later, at connect time, as an opaque `Connection closed` which\n * an absence-tolerant relay would swallow, turning a typo into silent single-node\n * fan-out.\n */\nconst PROTOCOLS: readonly string[] = [\n 'redis:',\n 'rediss:',\n 'valkey:',\n 'valkeys:',\n 'redis+tls:',\n 'redis+unix:',\n 'redis+tls+unix:',\n];\n\n/** The same fallback chain `Bun.RedisClient` uses when given no URL. */\nexport const defaultRelayUrl = (): string =>\n process.env['VALKEY_URL'] ??\n process.env['REDIS_URL'] ??\n 'redis://localhost:6379';\n\nexport interface RedisRelayOptions {\n /** @default `$VALKEY_URL`, `$REDIS_URL`, then `redis://localhost:6379` */\n readonly url?: string;\n /**\n * Bun's reconnection budget.\n *\n * `0` by default, and that default is not a preference: a `Bun.RedisClient` that\n * never connects keeps an internal retry timer alive past `close()`, and the\n * process then never exits. A relay is exactly the connection most likely to be\n * absent a single-node deployment with `REDIS_URL` left over from staging —\n * so the default has to be the one that lets the app boot, degrade, and still\n * exit. Raise it when Redis is a hard requirement and you want Bun to reconnect\n * for you.\n *\n * @default 0\n */\n readonly maxRetries?: number;\n /** @default 10000 */\n readonly connectionTimeout?: number;\n readonly tls?: boolean | Bun.TLSOptions;\n}\n\nconst assertUrl = (url: string): string => {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new AppError(\n `${JSON.stringify(url)} is not a valid URL for the websocket relay. ` +\n 'Expected something like redis://localhost:6379.',\n );\n }\n if (!PROTOCOLS.includes(parsed.protocol)) {\n throw new AppError(\n `Unsupported protocol ${JSON.stringify(parsed.protocol)} in ` +\n `${JSON.stringify(url)}. Expected one of ${PROTOCOLS.join(', ')}.`,\n );\n }\n return url;\n};\n\n/**\n * A {@link PubSubRelay} on `Bun.RedisClient` a Bun global, so this costs\n * `@dunx/http` no dependency at all.\n *\n * **Two connections, not one.** A client in subscriber mode rejects every data\n * command, and throws synchronously doing it, so the subscription cannot share the\n * socket that publishes. This is the same split the socket.io Redis adapter makes\n * with its `pubClient` / `subClient`.\n *\n * Both are opened lazily, on the first call that needs them, and a failed one is\n * discarded so the next call builds a fresh connection rather than reusing a dead\n * one.\n */\nexport class RedisRelay implements PubSubRelay {\n readonly #url: string;\n readonly #options: Bun.RedisOptions;\n #pub: Bun.RedisClient | undefined;\n #sub: Bun.RedisClient | undefined;\n /** Remembered only so `close()` can leave subscriber mode. See `close()`. */\n #channel: string | undefined;\n\n constructor(options: RedisRelayOptions = {}) {\n this.#url = assertUrl(options.url ?? defaultRelayUrl());\n this.#options = {\n maxRetries: options.maxRetries ?? 0,\n ...(options.connectionTimeout !== undefined && {\n connectionTimeout: options.connectionTimeout,\n }),\n ...(options.tls !== undefined && { tls: options.tls }),\n };\n }\n\n /** The URL with any password removed, for logs and error messages. */\n get url(): string {\n const parsed = new URL(this.#url);\n if (parsed.password) parsed.password = '***';\n return parsed.toString();\n }\n\n async publish(channel: string, message: string): Promise<number> {\n const client = (this.#pub ??= new Bun.RedisClient(\n this.#url,\n this.#options,\n ));\n try {\n return await client.publish(channel, message);\n } catch (error) {\n if (this.#pub === client) {\n this.#pub = undefined;\n client.close();\n }\n throw error;\n }\n }\n\n async subscribe(\n channel: string,\n listener: (message: string) => void,\n ): Promise<void> {\n const client = (this.#sub ??= new Bun.RedisClient(\n this.#url,\n this.#options,\n ));\n try {\n // `connect()` before `subscribe()`, and that order is load-bearing too:\n // measured on Bun 1.3.14, a `subscribe()` that cannot reach the server\n // leaves the client holding the event loop open even after `close()` and\n // even with `maxRetries: 0`, so an app pointed at an absent broker would\n // never exit. Failing at `connect()` instead releases cleanly, and says\n // `Connection closed` rather than `Max reconnection attempts reached`.\n await client.connect();\n await client.subscribe(channel, listener);\n this.#channel = channel;\n } catch (error) {\n if (this.#sub === client) {\n this.#sub = undefined;\n client.close();\n }\n throw error;\n }\n }\n\n /**\n * `UNSUBSCRIBE` before `close()`, and that order is load-bearing: measured on\n * Bun 1.3.14, a `Bun.RedisClient` left in subscriber mode keeps the process\n * alive after `close()`, so an app that shut down cleanly would never exit.\n * Leaving subscriber mode first fixes it. Recorded in docs/bun-apis.md.\n */\n async close(): Promise<void> {\n const sub = this.#sub;\n const channel = this.#channel;\n this.#pub?.close();\n this.#pub = undefined;\n this.#sub = undefined;\n this.#channel = undefined;\n if (!sub) return;\n if (channel !== undefined) {\n try {\n await sub.unsubscribe(channel);\n } catch {\n // A socket that is already gone is not in subscriber mode either, and\n // throwing here would leave the connection below unclosed.\n }\n }\n sub.close();\n }\n}\nObject.defineProperty(RedisRelay, Symbol.for('dunx.deps'), {\n value: () => [{ unresolved: \"options: RedisRelayOptions = {}\" }],\n});\n"
29
+ "import { AppError } from '@dunx/core';\nimport type { PubSubRelay } from './relay.js';\n\n/**\n * The schemes `Bun.RedisClient` accepts. Checked here because Bun takes any string\n * and only fails later, at connect time, as an opaque `Connection closed` - which\n * an absence-tolerant relay would swallow, turning a typo into silent single-node\n * fan-out.\n */\nconst PROTOCOLS: readonly string[] = [\n 'redis:',\n 'rediss:',\n 'valkey:',\n 'valkeys:',\n 'redis+tls:',\n 'redis+unix:',\n 'redis+tls+unix:',\n];\n\n/** The same fallback chain `Bun.RedisClient` uses when given no URL. */\nexport const defaultRelayUrl = (): string =>\n process.env['VALKEY_URL'] ??\n process.env['REDIS_URL'] ??\n 'redis://localhost:6379';\n\nexport interface RedisRelayOptions {\n /** @default `$VALKEY_URL`, `$REDIS_URL`, then `redis://localhost:6379` */\n readonly url?: string;\n /**\n * Bun's reconnection budget.\n *\n * `0` by default, and that default is not a preference: a `Bun.RedisClient` that\n * never connects keeps an internal retry timer alive past `close()`, and the\n * process then never exits. A relay is exactly the connection most likely to be\n * absent - a single-node deployment with `REDIS_URL` left over from staging -\n * so the default has to be the one that lets the app boot, degrade, and still\n * exit. Raise it when Redis is a hard requirement and you want Bun to reconnect\n * for you.\n *\n * @default 0\n */\n readonly maxRetries?: number;\n /** @default 10000 */\n readonly connectionTimeout?: number;\n readonly tls?: boolean | Bun.TLSOptions;\n}\n\nconst assertUrl = (url: string): string => {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new AppError(\n `${JSON.stringify(url)} is not a valid URL for the websocket relay. ` +\n 'Expected something like redis://localhost:6379.',\n );\n }\n if (!PROTOCOLS.includes(parsed.protocol)) {\n throw new AppError(\n `Unsupported protocol ${JSON.stringify(parsed.protocol)} in ` +\n `${JSON.stringify(url)}. Expected one of ${PROTOCOLS.join(', ')}.`,\n );\n }\n return url;\n};\n\n/**\n * A {@link PubSubRelay} on `Bun.RedisClient` - a Bun global, so this costs\n * `@dunx/http` no dependency at all.\n *\n * **Two connections, not one.** A client in subscriber mode rejects every data\n * command, and throws synchronously doing it, so the subscription cannot share the\n * socket that publishes. This is the same split the socket.io Redis adapter makes\n * with its `pubClient` / `subClient`.\n *\n * Both are opened lazily, on the first call that needs them, and a failed one is\n * discarded so the next call builds a fresh connection rather than reusing a dead\n * one.\n */\nexport class RedisRelay implements PubSubRelay {\n readonly #url: string;\n readonly #options: Bun.RedisOptions;\n #pub: Bun.RedisClient | undefined;\n #sub: Bun.RedisClient | undefined;\n /** Remembered only so `close()` can leave subscriber mode. See `close()`. */\n #channel: string | undefined;\n\n constructor(options: RedisRelayOptions = {}) {\n this.#url = assertUrl(options.url ?? defaultRelayUrl());\n this.#options = {\n maxRetries: options.maxRetries ?? 0,\n ...(options.connectionTimeout !== undefined && {\n connectionTimeout: options.connectionTimeout,\n }),\n ...(options.tls !== undefined && { tls: options.tls }),\n };\n }\n\n /** The URL with any password removed, for logs and error messages. */\n get url(): string {\n const parsed = new URL(this.#url);\n if (parsed.password) parsed.password = '***';\n return parsed.toString();\n }\n\n async publish(channel: string, message: string): Promise<number> {\n const client = (this.#pub ??= new Bun.RedisClient(\n this.#url,\n this.#options,\n ));\n try {\n return await client.publish(channel, message);\n } catch (error) {\n if (this.#pub === client) {\n this.#pub = undefined;\n client.close();\n }\n throw error;\n }\n }\n\n async subscribe(\n channel: string,\n listener: (message: string) => void,\n ): Promise<void> {\n const client = (this.#sub ??= new Bun.RedisClient(\n this.#url,\n this.#options,\n ));\n try {\n // `connect()` before `subscribe()`, and that order is load-bearing too:\n // measured on Bun 1.3.14, a `subscribe()` that cannot reach the server\n // leaves the client holding the event loop open even after `close()` and\n // even with `maxRetries: 0`, so an app pointed at an absent broker would\n // never exit. Failing at `connect()` instead releases cleanly, and says\n // `Connection closed` rather than `Max reconnection attempts reached`.\n await client.connect();\n await client.subscribe(channel, listener);\n this.#channel = channel;\n } catch (error) {\n if (this.#sub === client) {\n this.#sub = undefined;\n client.close();\n }\n throw error;\n }\n }\n\n /**\n * `UNSUBSCRIBE` before `close()`, and that order is load-bearing: measured on\n * Bun 1.3.14, a `Bun.RedisClient` left in subscriber mode keeps the process\n * alive after `close()`, so an app that shut down cleanly would never exit.\n * Leaving subscriber mode first fixes it. Recorded in docs/bun-apis.md.\n */\n async close(): Promise<void> {\n const sub = this.#sub;\n const channel = this.#channel;\n this.#pub?.close();\n this.#pub = undefined;\n this.#sub = undefined;\n this.#channel = undefined;\n if (!sub) return;\n if (channel !== undefined) {\n try {\n await sub.unsubscribe(channel);\n } catch {\n // A socket that is already gone is not in subscriber mode either, and\n // throwing here would leave the connection below unclosed.\n }\n }\n sub.close();\n }\n}\nObject.defineProperty(RedisRelay, Symbol.for('dunx.deps'), {\n value: () => [{ unresolved: \"options: RedisRelayOptions = {}\" }],\n});\n"
30
30
  ],
31
- "mappings": "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",
32
- "debugId": "B2F007DAD14DC76D64756E2164756E21",
31
+ "mappings": "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",
32
+ "debugId": "1EC09309FBB1CF1964756E2164756E21",
33
33
  "names": []
34
34
  }