@rhythmjs/router 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -77,15 +77,17 @@ Everything above (`RhythmRouter`, `ctx.response`, etc.) is runtime-agnostic. Two
77
77
 
78
78
  ## Deploying per runtime
79
79
 
80
- One app definition; each runtime has its own adapter under `@rhythmjs/router/adapters/*`, hono-style: import `handle` from your target's adapter and export what the platform expects.
80
+ One app definition; each runtime has its own adapter under `@rhythmjs/router/adapters/*`, hono-style: import from your target's adapter and export what the platform expects. Runtimes that speak web-standard `Request`/`Response` natively (Bun, Deno, Vercel) can equally use `toFetchHandler(app)` from `@rhythmjs/router/fetch` — their adapters are aliases for it.
81
81
 
82
- **Node**
82
+ Every adapter maps errors thrown in the middleware chain to a response (`500`, or the error's own `status`) instead of crashing, and accepts `{ onError }` to replace that mapping: `handle(app, { onError: (error) => new Response("down", { status: 503 }) })`. Platform metadata (Cloudflare `env`/`ctx`, the Netlify context) is readable in middleware via `getRuntime(ctx.request)` from `@rhythmjs/router/context`.
83
+
84
+ **Node** — `getRequestListener` returns a listener for your own `node:http` server:
83
85
 
84
86
  ```ts
85
87
  import { createServer } from "node:http";
86
- import { handle } from "@rhythmjs/router/adapters/node";
88
+ import { getRequestListener } from "@rhythmjs/router/adapters/node";
87
89
 
88
- createServer(handle(app, { maxRequestBodySize: 1024 * 1024 })).listen(3000);
90
+ createServer(getRequestListener(app, { maxRequestBodySize: 1024 * 1024 })).listen(3000);
89
91
  ```
90
92
 
91
93
  (Or skip the adapter entirely and use `serve(app, { port: 3000 })`.)
@@ -1,7 +1,8 @@
1
- import { RhythmHttpContext } from "../context.js";
1
+ import { t as RhythmHttpContext } from "../context-ChHlG-q0.js";
2
+ import { t as AdapterOptions } from "../base--TyruAfY.js";
2
3
  import { AWSLambdaHandler } from "srvx/aws-lambda";
3
4
  import { Rhythm } from "@rhythmjs/rhythm";
4
5
  //#region src/adapters/aws-lambda.d.ts
5
- export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>): AWSLambdaHandler;
6
+ export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>, options?: AdapterOptions): AWSLambdaHandler;
6
7
  //#endregion
7
- export type { AWSLambdaHandler };
8
+ export type { AWSLambdaHandler, AdapterOptions };
@@ -1,8 +1,9 @@
1
- import { toFetchHandler } from "../fetch.js";
1
+ import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
2
2
  import { toLambdaHandler } from "srvx/aws-lambda";
3
3
  //#region src/adapters/aws-lambda.ts
4
- function handle(app) {
5
- return toLambdaHandler({ fetch: toFetchHandler(app) });
4
+ const fetchHandle = createFetchAdapter();
5
+ function handle(app, options = {}) {
6
+ return toLambdaHandler({ fetch: fetchHandle(app, options) });
6
7
  }
7
8
  //#endregion
8
9
  export { handle };
@@ -1,5 +1,5 @@
1
- import { RhythmHttpContext } from "../context.js";
2
- import { Rhythm } from "@rhythmjs/rhythm";
1
+ import { n as FetchAdapter, t as AdapterOptions } from "../base--TyruAfY.js";
3
2
  //#region src/adapters/bun.d.ts
4
- export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>): (request: Request) => Promise<Response>;
5
- //#endregion
3
+ export declare const handle: FetchAdapter;
4
+ //#endregion
5
+ export type { AdapterOptions };
@@ -1,7 +1,5 @@
1
- import { toFetchHandler } from "../fetch.js";
1
+ import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
2
2
  //#region src/adapters/bun.ts
3
- function handle(app) {
4
- return toFetchHandler(app);
5
- }
3
+ const handle = createFetchAdapter();
6
4
  //#endregion
7
5
  export { handle };
@@ -1,5 +1,5 @@
1
- import { RhythmHttpContext } from "../context.js";
2
- import { Rhythm } from "@rhythmjs/rhythm";
1
+ import { n as FetchAdapter, t as AdapterOptions } from "../base--TyruAfY.js";
3
2
  //#region src/adapters/cloudflare.d.ts
4
- export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>): (request: Request, env?: unknown, context?: unknown) => Promise<Response>;
5
- //#endregion
3
+ export declare const handle: FetchAdapter<[env?: unknown, context?: unknown]>;
4
+ //#endregion
5
+ export type { AdapterOptions };
@@ -1,20 +1,13 @@
1
- import { toFetchHandler } from "../fetch.js";
1
+ import { n as setRuntime, t as createFetchAdapter } from "../base-B8GEu3z4.js";
2
2
  //#region src/adapters/cloudflare.ts
3
- function handle(app) {
4
- const handler = toFetchHandler(app);
5
- return (request, env, context) => {
6
- if (env !== void 0 || context !== void 0) Object.defineProperty(request, "runtime", {
7
- value: {
8
- name: "cloudflare",
9
- cloudflare: {
10
- env,
11
- context
12
- }
13
- },
14
- configurable: true
15
- });
16
- return handler(request);
17
- };
18
- }
3
+ const handle = createFetchAdapter((request, env, context) => {
4
+ if (env !== void 0 || context !== void 0) setRuntime(request, {
5
+ name: "cloudflare",
6
+ cloudflare: {
7
+ env,
8
+ context
9
+ }
10
+ });
11
+ });
19
12
  //#endregion
20
13
  export { handle };
@@ -1,5 +1,5 @@
1
- import { RhythmHttpContext } from "../context.js";
2
- import { Rhythm } from "@rhythmjs/rhythm";
1
+ import { n as FetchAdapter, t as AdapterOptions } from "../base--TyruAfY.js";
3
2
  //#region src/adapters/deno.d.ts
4
- export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>): (request: Request) => Promise<Response>;
5
- //#endregion
3
+ export declare const handle: FetchAdapter;
4
+ //#endregion
5
+ export type { AdapterOptions };
@@ -1,7 +1,5 @@
1
- import { toFetchHandler } from "../fetch.js";
1
+ import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
2
2
  //#region src/adapters/deno.ts
3
- function handle(app) {
4
- return toFetchHandler(app);
5
- }
3
+ const handle = createFetchAdapter();
6
4
  //#endregion
7
5
  export { handle };
@@ -1,5 +1,5 @@
1
- import { RhythmHttpContext } from "../context.js";
2
- import { Rhythm } from "@rhythmjs/rhythm";
1
+ import { n as FetchAdapter, t as AdapterOptions } from "../base--TyruAfY.js";
3
2
  //#region src/adapters/netlify.d.ts
4
- export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>): (request: Request, context?: unknown) => Promise<Response>;
5
- //#endregion
3
+ export declare const handle: FetchAdapter<[context?: unknown]>;
4
+ //#endregion
5
+ export type { AdapterOptions };
@@ -1,17 +1,10 @@
1
- import { toFetchHandler } from "../fetch.js";
1
+ import { n as setRuntime, t as createFetchAdapter } from "../base-B8GEu3z4.js";
2
2
  //#region src/adapters/netlify.ts
3
- function handle(app) {
4
- const handler = toFetchHandler(app);
5
- return (request, context) => {
6
- if (context !== void 0) Object.defineProperty(request, "runtime", {
7
- value: {
8
- name: "netlify",
9
- netlify: { context }
10
- },
11
- configurable: true
12
- });
13
- return handler(request);
14
- };
15
- }
3
+ const handle = createFetchAdapter((request, context) => {
4
+ if (context !== void 0) setRuntime(request, {
5
+ name: "netlify",
6
+ netlify: { context }
7
+ });
8
+ });
16
9
  //#endregion
17
10
  export { handle };
@@ -1,9 +1,11 @@
1
- import { RhythmHttpContext } from "../context.js";
2
- import { NodeHttpHandler } from "srvx";
1
+ import { t as RhythmHttpContext } from "../context-ChHlG-q0.js";
2
+ import { t as AdapterOptions } from "../base--TyruAfY.js";
3
+ import { NodeHttp1Handler, NodeHttp2Handler } from "srvx";
3
4
  import { Rhythm } from "@rhythmjs/rhythm";
4
5
  //#region src/adapters/node.d.ts
5
- export interface NodeHandlerOptions {
6
+ export interface NodeHandlerOptions extends AdapterOptions {
6
7
  maxRequestBodySize?: number;
7
8
  }
8
- export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>, options?: NodeHandlerOptions): NodeHttpHandler;
9
+ export type NodeHandler = NodeHttp1Handler & NodeHttp2Handler;
10
+ export declare function getRequestListener<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>, options?: NodeHandlerOptions): NodeHandler;
9
11
  //#endregion
@@ -1,17 +1,9 @@
1
- import { toFetchHandler } from "../fetch.js";
2
- import { errorToResponse } from "../serve.js";
1
+ import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
3
2
  import { toNodeHandler } from "srvx/node";
4
3
  //#region src/adapters/node.ts
5
- function handle(app, options = {}) {
6
- const handler = toFetchHandler(app);
7
- const safeHandler = async (request) => {
8
- try {
9
- return await handler(request);
10
- } catch (error) {
11
- return errorToResponse(error);
12
- }
13
- };
14
- return toNodeHandler(safeHandler, options);
4
+ const fetchHandle = createFetchAdapter();
5
+ function getRequestListener(app, options = {}) {
6
+ return toNodeHandler(fetchHandle(app, options), options);
15
7
  }
16
8
  //#endregion
17
- export { handle };
9
+ export { getRequestListener };
@@ -1,9 +1,11 @@
1
- import { RhythmHttpContext } from "../context.js";
1
+ import { t as RhythmHttpContext } from "../context-ChHlG-q0.js";
2
+ import { t as AdapterOptions } from "../base--TyruAfY.js";
2
3
  import { Rhythm } from "@rhythmjs/rhythm";
3
4
  //#region src/adapters/service-worker.d.ts
4
5
  interface FetchEventLike {
5
6
  readonly request: Request;
6
7
  respondWith(response: Response | Promise<Response>): void;
7
8
  }
8
- export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>): (event: FetchEventLike) => void;
9
- //#endregion
9
+ export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>, options?: AdapterOptions): (event: FetchEventLike) => void;
10
+ //#endregion
11
+ export type { AdapterOptions };
@@ -1,7 +1,8 @@
1
- import { toFetchHandler } from "../fetch.js";
1
+ import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
2
2
  //#region src/adapters/service-worker.ts
3
- function handle(app) {
4
- const handler = toFetchHandler(app);
3
+ const fetchHandle = createFetchAdapter();
4
+ function handle(app, options = {}) {
5
+ const handler = fetchHandle(app, options);
5
6
  return (event) => {
6
7
  event.respondWith(handler(event.request));
7
8
  };
@@ -1,5 +1,5 @@
1
- import { RhythmHttpContext } from "../context.js";
2
- import { Rhythm } from "@rhythmjs/rhythm";
1
+ import { n as FetchAdapter, t as AdapterOptions } from "../base--TyruAfY.js";
3
2
  //#region src/adapters/vercel.d.ts
4
- export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>): (request: Request) => Promise<Response>;
5
- //#endregion
3
+ export declare const handle: FetchAdapter;
4
+ //#endregion
5
+ export type { AdapterOptions };
@@ -1,7 +1,5 @@
1
- import { toFetchHandler } from "../fetch.js";
1
+ import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
2
2
  //#region src/adapters/vercel.ts
3
- function handle(app) {
4
- return toFetchHandler(app);
5
- }
3
+ const handle = createFetchAdapter();
6
4
  //#endregion
7
5
  export { handle };
@@ -0,0 +1,10 @@
1
+ import { t as RhythmHttpContext } from "./context-ChHlG-q0.js";
2
+ import { ErrorHandler, ServerRuntimeContext } from "srvx";
3
+ import { Rhythm } from "@rhythmjs/rhythm";
4
+ //#region src/adapters/base.d.ts
5
+ interface AdapterOptions {
6
+ onError?: ErrorHandler;
7
+ }
8
+ type FetchAdapter<TExtra extends unknown[] = []> = <TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>, options?: AdapterOptions) => (request: Request, ...extra: TExtra) => Promise<Response>;
9
+ //#endregion
10
+ export { FetchAdapter as n, AdapterOptions as t };
@@ -0,0 +1,25 @@
1
+ import { toFetchHandler } from "./fetch.js";
2
+ import { errorToResponse } from "./serve.js";
3
+ //#region src/adapters/base.ts
4
+ function setRuntime(request, runtime) {
5
+ Object.defineProperty(request, "runtime", {
6
+ value: runtime,
7
+ configurable: true
8
+ });
9
+ }
10
+ function createFetchAdapter(enrich) {
11
+ return (app, options = {}) => {
12
+ const handler = toFetchHandler(app);
13
+ const onError = options.onError ?? errorToResponse;
14
+ return async (request, ...extra) => {
15
+ try {
16
+ enrich?.(request, ...extra);
17
+ return await handler(request);
18
+ } catch (error) {
19
+ return onError(error);
20
+ }
21
+ };
22
+ };
23
+ }
24
+ //#endregion
25
+ export { setRuntime as n, createFetchAdapter as t };
@@ -0,0 +1,24 @@
1
+ import { ServerRuntimeContext } from "srvx";
2
+ //#region src/context.d.ts
3
+ type RhythmRuntime = ServerRuntimeContext;
4
+ declare function getRuntime(request: Request): RhythmRuntime | undefined;
5
+ type RhythmResponseBody = string | ArrayBuffer | Uint8Array | Blob | FormData | URLSearchParams | ReadableStream<Uint8Array> | null;
6
+ declare class RhythmResponse {
7
+ status: number;
8
+ statusText: string | undefined;
9
+ headers: Headers;
10
+ body: RhythmResponseBody;
11
+ }
12
+ interface RhythmHttpContext {
13
+ readonly request: Request;
14
+ readonly response: RhythmResponse;
15
+ json(data: unknown, status?: number): void;
16
+ text(body: string, status?: number): void;
17
+ html(body: string, status?: number): void;
18
+ error(status: number, message?: string): void;
19
+ redirect(url: string, status?: number): void;
20
+ }
21
+ declare function createHttpContext(request: Request): RhythmHttpContext;
22
+ declare function toResponse(response: RhythmResponse): Response;
23
+ //#endregion
24
+ export { createHttpContext as a, RhythmRuntime as i, RhythmResponse as n, getRuntime as o, RhythmResponseBody as r, toResponse as s, RhythmHttpContext as t };
package/dist/context.d.ts CHANGED
@@ -1,20 +1,2 @@
1
- //#region src/context.d.ts
2
- export type RhythmResponseBody = string | ArrayBuffer | Uint8Array | Blob | FormData | URLSearchParams | ReadableStream<Uint8Array> | null;
3
- export declare class RhythmResponse {
4
- status: number;
5
- statusText: string | undefined;
6
- headers: Headers;
7
- body: RhythmResponseBody;
8
- }
9
- export interface RhythmHttpContext {
10
- readonly request: Request;
11
- readonly response: RhythmResponse;
12
- json(data: unknown, status?: number): void;
13
- text(body: string, status?: number): void;
14
- html(body: string, status?: number): void;
15
- error(status: number, message?: string): void;
16
- redirect(url: string, status?: number): void;
17
- }
18
- export declare function createHttpContext(request: Request): RhythmHttpContext;
19
- export declare function toResponse(response: RhythmResponse): Response;
20
- //#endregion
1
+ import { a as createHttpContext, i as RhythmRuntime, n as RhythmResponse, o as getRuntime, r as RhythmResponseBody, s as toResponse, t as RhythmHttpContext } from "./context-ChHlG-q0.js";
2
+ export { RhythmHttpContext, RhythmResponse, RhythmResponseBody, RhythmRuntime, createHttpContext, getRuntime, toResponse };
package/dist/context.js CHANGED
@@ -1,4 +1,7 @@
1
1
  //#region src/context.ts
2
+ function getRuntime(request) {
3
+ return request.runtime;
4
+ }
2
5
  var RhythmResponse = class {
3
6
  status = 200;
4
7
  statusText = void 0;
@@ -63,4 +66,4 @@ function toResponse(response) {
63
66
  });
64
67
  }
65
68
  //#endregion
66
- export { RhythmResponse, createHttpContext, toResponse };
69
+ export { RhythmResponse, createHttpContext, getRuntime, toResponse };
package/dist/fetch.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { RhythmHttpContext } from "./context.js";
1
+ import { t as RhythmHttpContext } from "./context-ChHlG-q0.js";
2
2
  import { Rhythm } from "@rhythmjs/rhythm";
3
3
  //#region src/fetch.d.ts
4
4
  export declare function toFetchHandler<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>): (request: Request) => Promise<Response>;
@@ -1,4 +1,4 @@
1
- import { RhythmHttpContext } from "./context.js";
1
+ import { t as RhythmHttpContext } from "./context-ChHlG-q0.js";
2
2
  import { DeriveMiddleware, Middleware } from "@rhythmjs/rhythm/types";
3
3
  //#region src/rhythm-router.d.ts
4
4
  export interface RhythmRouterContext {
package/dist/serve.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { RhythmHttpContext } from "./context.js";
1
+ import { t as RhythmHttpContext } from "./context-ChHlG-q0.js";
2
2
  import { ErrorHandler, Server, ServerMiddleware, ServerOptions, ServerPlugin } from "srvx";
3
3
  import { Rhythm } from "@rhythmjs/rhythm";
4
4
  //#region src/serve.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhythmjs/router",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "Radix-tree HTTP router for the Rhythm middleware kernel, with Bun, Node, and Deno adapters.",
5
5
  "homepage": "https://rhythm.js.org/router",
6
6
  "license": "ISC",
@@ -78,7 +78,7 @@
78
78
  },
79
79
  "dependencies": {
80
80
  "srvx": "^1.0.5",
81
- "@rhythmjs/rhythm": "0.0.8"
81
+ "@rhythmjs/rhythm": "0.0.9"
82
82
  },
83
83
  "devDependencies": {
84
84
  "@types/node": "^26.6.3",