@nifrajs/core 1.13.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -1
- package/dist/assurance.d.ts +11 -2
- package/dist/assurance.d.ts.map +1 -1
- package/dist/assurance.js +20 -0
- package/dist/assurance.js.map +1 -1
- package/dist/capabilities.d.ts +54 -2
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +240 -5
- package/dist/capabilities.js.map +1 -1
- package/dist/durable-adapters.d.ts +241 -0
- package/dist/durable-adapters.d.ts.map +1 -0
- package/dist/durable-adapters.js +697 -0
- package/dist/durable-adapters.js.map +1 -0
- package/dist/durable-execution.d.ts +349 -0
- package/dist/durable-execution.d.ts.map +1 -0
- package/dist/durable-execution.js +1173 -0
- package/dist/durable-execution.js.map +1 -0
- package/dist/effect-ledger.d.ts +9 -0
- package/dist/effect-ledger.d.ts.map +1 -0
- package/dist/effect-ledger.js +8 -0
- package/dist/effect-ledger.js.map +1 -0
- package/dist/effect-lifecycle.d.ts +42 -0
- package/dist/effect-lifecycle.d.ts.map +1 -0
- package/dist/effect-lifecycle.js +66 -0
- package/dist/effect-lifecycle.js.map +1 -0
- package/dist/effect-scope.d.ts +75 -0
- package/dist/effect-scope.d.ts.map +1 -0
- package/dist/effect-scope.js +177 -0
- package/dist/effect-scope.js.map +1 -0
- package/dist/idempotency-plugin.d.ts +13 -0
- package/dist/idempotency-plugin.d.ts.map +1 -0
- package/dist/idempotency-plugin.js +16 -0
- package/dist/idempotency-plugin.js.map +1 -0
- package/dist/index.d.ts +6 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -31
- package/dist/index.js.map +1 -1
- package/dist/internal/capability-runtime.d.ts +62 -1
- package/dist/internal/capability-runtime.d.ts.map +1 -1
- package/dist/internal/capability-runtime.js +11 -2
- package/dist/internal/capability-runtime.js.map +1 -1
- package/dist/internal/effect-execution.d.ts +16 -0
- package/dist/internal/effect-execution.d.ts.map +1 -0
- package/dist/internal/effect-execution.js +50 -0
- package/dist/internal/effect-execution.js.map +1 -0
- package/dist/internal/safe-equal.d.ts +20 -0
- package/dist/internal/safe-equal.d.ts.map +1 -0
- package/dist/internal/safe-equal.js +31 -0
- package/dist/internal/safe-equal.js.map +1 -0
- package/dist/ledger.d.ts +14 -6
- package/dist/ledger.d.ts.map +1 -1
- package/dist/ledger.js +31 -5
- package/dist/ledger.js.map +1 -1
- package/dist/mcp.d.ts +7 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +56 -0
- package/dist/mcp.js.map +1 -0
- package/dist/node-direct.d.ts +5 -0
- package/dist/node-direct.d.ts.map +1 -0
- package/dist/node-direct.js +27 -0
- package/dist/node-direct.js.map +1 -0
- package/dist/reconciliation-worker.d.ts +108 -0
- package/dist/reconciliation-worker.d.ts.map +1 -0
- package/dist/reconciliation-worker.js +239 -0
- package/dist/reconciliation-worker.js.map +1 -0
- package/dist/reflection.d.ts +5 -0
- package/dist/reflection.d.ts.map +1 -1
- package/dist/reflection.js +2 -0
- package/dist/reflection.js.map +1 -1
- package/dist/server/client-ip.d.ts +35 -0
- package/dist/server/client-ip.d.ts.map +1 -0
- package/dist/server/client-ip.js +42 -0
- package/dist/server/client-ip.js.map +1 -0
- package/dist/server/context.d.ts +47 -2
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/contract.d.ts +14 -4
- package/dist/server/contract.d.ts.map +1 -1
- package/dist/server/contract.js +8 -2
- package/dist/server/contract.js.map +1 -1
- package/dist/server/http.d.ts +14 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +45 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/idempotency-lane.d.ts +45 -0
- package/dist/server/idempotency-lane.d.ts.map +1 -0
- package/dist/server/idempotency-lane.js +205 -0
- package/dist/server/idempotency-lane.js.map +1 -0
- package/dist/server/install.d.ts +21 -0
- package/dist/server/install.d.ts.map +1 -0
- package/dist/server/install.js +21 -0
- package/dist/server/install.js.map +1 -0
- package/dist/server/ledger-lane.d.ts +53 -0
- package/dist/server/ledger-lane.d.ts.map +1 -0
- package/dist/server/ledger-lane.js +82 -0
- package/dist/server/ledger-lane.js.map +1 -0
- package/dist/server/mcp-hook.d.ts +28 -0
- package/dist/server/mcp-hook.d.ts.map +1 -0
- package/dist/server/mcp-hook.js +2 -0
- package/dist/server/mcp-hook.js.map +1 -0
- package/dist/server/node-outcome-hook.d.ts +9 -0
- package/dist/server/node-outcome-hook.d.ts.map +1 -0
- package/dist/server/node-outcome-hook.js +2 -0
- package/dist/server/node-outcome-hook.js.map +1 -0
- package/dist/server/node-outcome.d.ts +37 -0
- package/dist/server/node-outcome.d.ts.map +1 -0
- package/dist/server/node-outcome.js +75 -0
- package/dist/server/node-outcome.js.map +1 -0
- package/dist/server/plugin.d.ts +78 -0
- package/dist/server/plugin.d.ts.map +1 -0
- package/dist/server/plugin.js +57 -0
- package/dist/server/plugin.js.map +1 -0
- package/dist/server/query.d.ts +18 -0
- package/dist/server/query.d.ts.map +1 -0
- package/dist/server/query.js +102 -0
- package/dist/server/query.js.map +1 -0
- package/dist/server/registry.d.ts +31 -6
- package/dist/server/registry.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +51 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +184 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/server/respond.d.ts +17 -0
- package/dist/server/respond.d.ts.map +1 -0
- package/dist/server/respond.js +81 -0
- package/dist/server/respond.js.map +1 -0
- package/dist/server/runtime-core.d.ts +36 -0
- package/dist/server/runtime-core.d.ts.map +1 -0
- package/dist/server/runtime-core.js +51 -0
- package/dist/server/runtime-core.js.map +1 -0
- package/dist/server/server-types.d.ts +203 -0
- package/dist/server/server-types.d.ts.map +1 -0
- package/dist/server/server-types.js +2 -0
- package/dist/server/server-types.js.map +1 -0
- package/dist/server/server.d.ts +119 -345
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +247 -833
- package/dist/server/server.js.map +1 -1
- package/dist/server/sse-hook.d.ts +10 -0
- package/dist/server/sse-hook.d.ts.map +1 -0
- package/dist/server/sse-hook.js +2 -0
- package/dist/server/sse-hook.js.map +1 -0
- package/dist/server/sse.d.ts +7 -23
- package/dist/server/sse.d.ts.map +1 -1
- package/dist/server/sse.js +18 -0
- package/dist/server/sse.js.map +1 -1
- package/dist/server/transport-lane.d.ts +28 -0
- package/dist/server/transport-lane.d.ts.map +1 -0
- package/dist/server/transport-lane.js +106 -0
- package/dist/server/transport-lane.js.map +1 -0
- package/dist/server/websocket.d.ts +23 -1
- package/dist/server/websocket.d.ts.map +1 -1
- package/dist/server/websocket.js +10 -1
- package/dist/server/websocket.js.map +1 -1
- package/dist/server/ws-hook.d.ts +8 -11
- package/dist/server/ws-hook.d.ts.map +1 -1
- package/dist/server/ws-hook.js +7 -14
- package/dist/server/ws-hook.js.map +1 -1
- package/dist/server.d.ts +21 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +16 -0
- package/dist/server.js.map +1 -0
- package/dist/transport-codec-rich.d.ts +8 -0
- package/dist/transport-codec-rich.d.ts.map +1 -0
- package/dist/transport-codec-rich.js +14 -0
- package/dist/transport-codec-rich.js.map +1 -0
- package/dist/transport-codec.d.ts +31 -0
- package/dist/transport-codec.d.ts.map +1 -0
- package/dist/transport-codec.js +190 -0
- package/dist/transport-codec.js.map +1 -0
- package/dist/transport-plugin.d.ts +3 -0
- package/dist/transport-plugin.d.ts.map +1 -0
- package/dist/transport-plugin.js +3 -0
- package/dist/transport-plugin.js.map +1 -0
- package/dist/wire.d.ts +58 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +445 -0
- package/dist/wire.js.map +1 -0
- package/dist/ws.d.ts +16 -7
- package/dist/ws.d.ts.map +1 -1
- package/dist/ws.js +25 -10
- package/dist/ws.js.map +1 -1
- package/package.json +122 -6
- package/src/assurance.ts +36 -1
- package/src/capabilities.ts +306 -5
- package/src/durable-adapters.ts +1039 -0
- package/src/durable-execution.ts +1676 -0
- package/src/effect-ledger.ts +9 -0
- package/src/effect-lifecycle.ts +120 -0
- package/src/effect-scope.ts +267 -0
- package/src/idempotency-plugin.ts +17 -0
- package/src/index.ts +6 -133
- package/src/internal/capability-runtime.ts +87 -1
- package/src/internal/effect-execution.ts +70 -0
- package/src/internal/safe-equal.ts +27 -0
- package/src/ledger.ts +45 -11
- package/src/mcp.ts +65 -0
- package/src/node-direct.ts +37 -0
- package/src/reconciliation-worker.ts +372 -0
- package/src/reflection.ts +7 -0
- package/src/server/client-ip.ts +60 -0
- package/src/server/context.ts +50 -2
- package/src/server/contract.ts +26 -7
- package/src/server/http.ts +58 -0
- package/src/server/idempotency-lane.ts +321 -0
- package/src/server/install.ts +28 -0
- package/src/server/ledger-lane.ts +125 -0
- package/src/server/mcp-hook.ts +41 -0
- package/src/server/node-outcome-hook.ts +9 -0
- package/src/server/node-outcome.ts +112 -0
- package/src/server/plugin.ts +92 -0
- package/src/server/query.ts +119 -0
- package/src/server/registry.ts +36 -6
- package/src/server/request-context.ts +271 -0
- package/src/server/respond.ts +94 -0
- package/src/server/runtime-core.ts +74 -0
- package/src/server/server-types.ts +204 -0
- package/src/server/server.ts +448 -1314
- package/src/server/sse-hook.ts +14 -0
- package/src/server/sse.ts +26 -0
- package/src/server/transport-lane.ts +141 -0
- package/src/server/websocket.ts +35 -1
- package/src/server/ws-hook.ts +8 -19
- package/src/server.ts +92 -0
- package/src/transport-codec-rich.ts +20 -0
- package/src/transport-codec.ts +250 -0
- package/src/transport-plugin.ts +2 -0
- package/src/wire.ts +474 -0
- package/src/ws.ts +33 -10
- package/dist/invariants.d.ts +0 -70
- package/dist/invariants.d.ts.map +0 -1
- package/dist/invariants.js +0 -487
- package/dist/invariants.js.map +0 -1
- package/src/invariants.ts +0 -604
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/server/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InferOutput, StandardSchemaV1 } from "../schema/standard.js";
|
|
1
|
+
import type { InferInput, InferOutput, StandardSchemaV1 } from "../schema/standard.js";
|
|
2
2
|
import type { Params, RouteSchema } from "./context.js";
|
|
3
3
|
/**
|
|
4
4
|
* One route's input/output shape as the **client** will consume it. `query`/`body`
|
|
@@ -11,12 +11,17 @@ export interface RouteInfo {
|
|
|
11
11
|
readonly query: unknown;
|
|
12
12
|
readonly body: unknown;
|
|
13
13
|
readonly output: unknown;
|
|
14
|
-
/**
|
|
15
|
-
* route declares none.
|
|
14
|
+
/** The route's declared error bodies as a status-keyed record (from `schema.errors`, e.g.
|
|
15
|
+
* `{ 404: NotFound }`); `unknown` when the route declares none. The typed client turns this into
|
|
16
|
+
* a status-discriminated failure union. */
|
|
16
17
|
readonly errors?: unknown;
|
|
17
18
|
/** The SSE event payload type (from `schema.sse`, declared via `app.sse()`); `never` for ordinary
|
|
18
19
|
* routes. The typed client keys `.subscribe()` availability and its event type off this. */
|
|
19
20
|
readonly sse?: unknown;
|
|
21
|
+
/** The WebSocket message contract (from `app.ws()`'s `messageSchema`/`sendSchema`): `in` is what the
|
|
22
|
+
* client may send, `out` what the server pushes. Present only on WS entries (method key `"WS"`);
|
|
23
|
+
* the typed client keys `.ws()` availability and its frame types off this. */
|
|
24
|
+
readonly ws?: unknown;
|
|
20
25
|
}
|
|
21
26
|
/** The accumulated, type-level map of every route on a Server: path → method → RouteInfo. */
|
|
22
27
|
export type Registry = Record<string, Record<string, RouteInfo>>;
|
|
@@ -33,13 +38,14 @@ type RegistryQuery<S extends RouteSchema> = S extends {
|
|
|
33
38
|
type RegistryOutput<S extends RouteSchema, Output> = S extends {
|
|
34
39
|
response: infer R extends StandardSchemaV1;
|
|
35
40
|
} ? InferOutput<R> : Output;
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
41
|
+
/** A route's declared error-response body types as a STATUS-KEYED record (`schema.errors` →
|
|
42
|
+
* `{ 404: NotFound, 409: Conflict }`), so the typed client can discriminate the failure body by
|
|
43
|
+
* `status`, not just surface a union. `unknown` when the route declares no `errors`. */
|
|
38
44
|
type RegistryErrors<S extends RouteSchema> = S extends {
|
|
39
45
|
errors: infer E extends Record<number, StandardSchemaV1>;
|
|
40
46
|
} ? {
|
|
41
47
|
[K in keyof E]: E[K] extends StandardSchemaV1 ? InferOutput<E[K]> : never;
|
|
42
|
-
}
|
|
48
|
+
} : unknown;
|
|
43
49
|
/** The SSE event payload type from a route's `sse` schema; `never` for ordinary routes. */
|
|
44
50
|
type RegistrySse<S extends RouteSchema> = S extends {
|
|
45
51
|
sse: infer E extends StandardSchemaV1;
|
|
@@ -55,6 +61,25 @@ export type RouteInfoFor<Path extends string, S extends RouteSchema, Output> = {
|
|
|
55
61
|
};
|
|
56
62
|
/** The client-visible output of a handler: its awaited return, minus raw `Response`. */
|
|
57
63
|
export type OutputOf<H extends (...args: never[]) => unknown> = Exclude<Awaited<ReturnType<H>>, Response>;
|
|
64
|
+
/**
|
|
65
|
+
* The registry entry for a WebSocket route (stored under the pseudo-method key `"WS"`, so WS routes
|
|
66
|
+
* ride the same path → method map as HTTP routes - no extra Server generic). `in` is the client →
|
|
67
|
+
* server frame type: the `messageSchema`'s INPUT side, since that is what goes on the wire before
|
|
68
|
+
* validation transforms it. `out` is the server → client frame type from `sendSchema` (a type-level
|
|
69
|
+
* contract; the server's own sends are not runtime-validated). Either is `unknown` when undeclared.
|
|
70
|
+
*/
|
|
71
|
+
export type WsRouteInfoFor<Path extends string, In extends StandardSchemaV1 | undefined, Out extends StandardSchemaV1 | undefined> = {
|
|
72
|
+
readonly params: Params<Path>;
|
|
73
|
+
readonly query: never;
|
|
74
|
+
readonly body: never;
|
|
75
|
+
readonly output: never;
|
|
76
|
+
readonly errors: unknown;
|
|
77
|
+
readonly sse: never;
|
|
78
|
+
readonly ws: {
|
|
79
|
+
readonly in: In extends StandardSchemaV1 ? InferInput<In> : unknown;
|
|
80
|
+
readonly out: Out extends StandardSchemaV1 ? InferOutput<Out> : unknown;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
58
83
|
/**
|
|
59
84
|
* Merge a new route into the registry, combining methods that share a path.
|
|
60
85
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/server/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/server/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The runtime request context (`c`): the `RawContext` implementation the handler receives, its lazy
|
|
3
|
+
* `c.set` response-controls backing, and the bounded body readers behind `c.boundedBody`/`c.boundedJson`.
|
|
4
|
+
* Type-imports the kernel's spine (never its values) and pulls its primitives from `runtime-core`, so it
|
|
5
|
+
* sits below the server module in the graph.
|
|
6
|
+
*/
|
|
7
|
+
import type { RequestBudget } from "../budget.js";
|
|
8
|
+
import type { Platform } from "./context.js";
|
|
9
|
+
import { CONTEXT_SEARCH, CONTEXT_SET } from "./runtime-core.js";
|
|
10
|
+
import type { CtxSet, RawContext, RequestSource } from "./server.js";
|
|
11
|
+
export declare class RequestContext implements RawContext {
|
|
12
|
+
params: Record<string, string>;
|
|
13
|
+
body: unknown;
|
|
14
|
+
private searchValue;
|
|
15
|
+
private signalValue;
|
|
16
|
+
private budgetValue;
|
|
17
|
+
private platformValue;
|
|
18
|
+
private setValue;
|
|
19
|
+
private queryValue;
|
|
20
|
+
private queryReady;
|
|
21
|
+
private cookiesValue;
|
|
22
|
+
private readonly source;
|
|
23
|
+
private readonly maxBodyBytes;
|
|
24
|
+
constructor(source: RequestSource, params: Record<string, string>, maxBodyBytes: number);
|
|
25
|
+
constructor(source: RequestSource, params: Record<string, string>, search: string | undefined, signal: AbortSignal, budget: RequestBudget, platform: Platform | undefined, maxBodyBytes: number);
|
|
26
|
+
static native(source: RequestSource, params: Record<string, string>, maxBodyBytes: number): RequestContext;
|
|
27
|
+
[CONTEXT_SET](): CtxSet | undefined;
|
|
28
|
+
get [CONTEXT_SEARCH](): string;
|
|
29
|
+
get set(): CtxSet;
|
|
30
|
+
get signal(): AbortSignal;
|
|
31
|
+
get budget(): RequestBudget;
|
|
32
|
+
get env(): unknown;
|
|
33
|
+
get clientIp(): string | undefined;
|
|
34
|
+
get waitUntil(): (promise: Promise<unknown>) => void;
|
|
35
|
+
get req(): Request;
|
|
36
|
+
get request(): Request;
|
|
37
|
+
json(body: unknown, init?: ResponseInit | number): Response;
|
|
38
|
+
text(body: string, init?: ResponseInit | number): Response;
|
|
39
|
+
get query(): unknown;
|
|
40
|
+
set query(v: unknown);
|
|
41
|
+
get cookies(): Readonly<Record<string, string>>;
|
|
42
|
+
boundedBody(maxBytes?: number): Promise<Uint8Array>;
|
|
43
|
+
boundedJson<T = unknown>(maxBytes?: number): Promise<T>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Read a JSON body with the same byte cap used by schema validation and `c.boundedJson`.
|
|
47
|
+
* Non-chunked, framed requests with an in-cap `Content-Length` use the runtime-native `req.json()`;
|
|
48
|
+
* chunked or length-less requests fall back to the streaming byte-cap guard.
|
|
49
|
+
*/
|
|
50
|
+
export declare function readBoundedJsonSource(req: RequestSource, maxBytes: number): Promise<unknown | Response>;
|
|
51
|
+
//# sourceMappingURL=request-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAI5C,OAAO,EACL,cAAc,EACd,WAAW,EAOZ,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AA2CpE,qBAAa,cAAe,YAAW,UAAU;IAKvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,IAAI,EAAE,OAAO,CAAA;IACrB,QAAgB,WAAW,CAAoB;IAC/C,QAAgB,WAAW,CAAyB;IACpD,QAAgB,WAAW,CAA2B;IACtD,QAAgB,aAAa,CAAsB;IAEnD,QAAgB,QAAQ,CAAoB;IAC5C,QAAgB,UAAU,CAAS;IACnC,QAAgB,UAAU,CAAS;IACnC,QAAgB,YAAY,CAA8C;IAC1E,iBAAyB,MAAM,CAAe;IAC9C,iBAAyB,YAAY,CAAQ;gBAEjC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,EAAE,MAAM;gBAErF,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,YAAY,EAAE,MAAM;IAwBtB,MAAM,CAAC,MAAM,CACX,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,YAAY,EAAE,MAAM,GACnB,cAAc;IAIjB,CAAC,WAAW,CAAC,IAAI,MAAM,GAAG,SAAS;IAInC,IAAI,CAAC,cAAc,CAAC,IAAI,MAAM,CAG7B;IAED,IAAI,GAAG,IAAI,MAAM,CAGhB;IAED,IAAI,MAAM,IAAI,WAAW,CAExB;IAED,IAAI,MAAM,IAAI,aAAa,CAE1B;IAED,IAAI,GAAG,IAAI,OAAO,CAEjB;IAED,IAAI,QAAQ,IAAI,MAAM,GAAG,SAAS,CAIjC;IAED,IAAI,SAAS,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAEnD;IAED,IAAI,GAAG,IAAI,OAAO,CAEjB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,QAAQ;IAI3D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,QAAQ;IAO1D,IAAI,KAAK,IAAI,OAAO,CAMnB;IAED,IAAI,KAAK,CAAC,CAAC,EAAE,OAAO,EAGnB;IAED,IAAI,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAG9C;IAED,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAInD,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAGxD;AA4BD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC,CA8B7B"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { drainCapped, parseContentLength, readBoundedBytes } from "./body.js";
|
|
2
|
+
import { parseCookies, serializeCookie } from "./cookies.js";
|
|
3
|
+
import { jsonError } from "./http.js";
|
|
4
|
+
import { searchOf } from "./query.js";
|
|
5
|
+
import { CONTEXT_SEARCH, CONTEXT_SET, fallbackWaitUntil, getNeverAbortSignal, getUnboundedRequestBudget, headerOf, requestOf, TEXT_DECODER, } from "./runtime-core.js";
|
|
6
|
+
/** A fixed past instant for cookie deletion (`Expires`). A literal epoch - deterministic, unlike an
|
|
7
|
+
* argless `new Date()`. */
|
|
8
|
+
const EPOCH = new Date(0);
|
|
9
|
+
class LazyResponseControls {
|
|
10
|
+
status;
|
|
11
|
+
_headers;
|
|
12
|
+
_cookies;
|
|
13
|
+
get headers() {
|
|
14
|
+
this._headers ??= {};
|
|
15
|
+
return this._headers;
|
|
16
|
+
}
|
|
17
|
+
cookie(name, value, options) {
|
|
18
|
+
// Secure-by-default: HttpOnly + Secure + SameSite=Lax + Path=/, overridable per call.
|
|
19
|
+
const merged = {
|
|
20
|
+
httpOnly: true,
|
|
21
|
+
secure: true,
|
|
22
|
+
sameSite: "lax",
|
|
23
|
+
path: "/",
|
|
24
|
+
...options,
|
|
25
|
+
};
|
|
26
|
+
this._cookies ??= [];
|
|
27
|
+
this._cookies.push(serializeCookie(name, value, merged));
|
|
28
|
+
}
|
|
29
|
+
deleteCookie(name, options) {
|
|
30
|
+
// Expire immediately; default Path=/, and match the original path/domain or the browser keeps it.
|
|
31
|
+
this._cookies ??= [];
|
|
32
|
+
this._cookies.push(serializeCookie(name, "", { path: "/", ...options, maxAge: 0, expires: EPOCH }));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Coerce `c.json`/`c.text`'s second arg - a status number (the common case) or a full `ResponseInit`. */
|
|
36
|
+
function statusInit(init) {
|
|
37
|
+
return typeof init === "number" ? { status: init } : init;
|
|
38
|
+
}
|
|
39
|
+
export class RequestContext {
|
|
40
|
+
constructor(source, params, searchOrMaxBodyBytes, signal, budget, platform, maxBodyBytes) {
|
|
41
|
+
this.source = source;
|
|
42
|
+
this.params = params;
|
|
43
|
+
if (typeof searchOrMaxBodyBytes === "number") {
|
|
44
|
+
this.maxBodyBytes = searchOrMaxBodyBytes;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (searchOrMaxBodyBytes !== undefined)
|
|
48
|
+
this.searchValue = searchOrMaxBodyBytes;
|
|
49
|
+
this.signalValue = signal;
|
|
50
|
+
this.budgetValue = budget;
|
|
51
|
+
if (platform !== undefined)
|
|
52
|
+
this.platformValue = platform;
|
|
53
|
+
this.maxBodyBytes = maxBodyBytes;
|
|
54
|
+
}
|
|
55
|
+
static native(source, params, maxBodyBytes) {
|
|
56
|
+
return new RequestContext(source, params, maxBodyBytes);
|
|
57
|
+
}
|
|
58
|
+
[CONTEXT_SET]() {
|
|
59
|
+
return this.setValue;
|
|
60
|
+
}
|
|
61
|
+
get [CONTEXT_SEARCH]() {
|
|
62
|
+
this.searchValue ??= searchOf(this.source.url);
|
|
63
|
+
return this.searchValue;
|
|
64
|
+
}
|
|
65
|
+
get set() {
|
|
66
|
+
this.setValue ??= new LazyResponseControls();
|
|
67
|
+
return this.setValue;
|
|
68
|
+
}
|
|
69
|
+
get signal() {
|
|
70
|
+
return this.signalValue ?? getNeverAbortSignal();
|
|
71
|
+
}
|
|
72
|
+
get budget() {
|
|
73
|
+
return this.budgetValue ?? getUnboundedRequestBudget();
|
|
74
|
+
}
|
|
75
|
+
get env() {
|
|
76
|
+
return this.platformValue?.env;
|
|
77
|
+
}
|
|
78
|
+
get clientIp() {
|
|
79
|
+
// The server resolves the trust declaration into `platform.clientIp` before the context is built,
|
|
80
|
+
// so this getter just surfaces the already-derived value (raw socket peer by default).
|
|
81
|
+
return this.platformValue?.clientIp;
|
|
82
|
+
}
|
|
83
|
+
get waitUntil() {
|
|
84
|
+
return this.platformValue?.waitUntil ?? fallbackWaitUntil;
|
|
85
|
+
}
|
|
86
|
+
get req() {
|
|
87
|
+
return requestOf(this.source);
|
|
88
|
+
}
|
|
89
|
+
get request() {
|
|
90
|
+
return requestOf(this.source);
|
|
91
|
+
}
|
|
92
|
+
json(body, init) {
|
|
93
|
+
return Response.json(body, statusInit(init));
|
|
94
|
+
}
|
|
95
|
+
text(body, init) {
|
|
96
|
+
const i = statusInit(init);
|
|
97
|
+
// Default to text/plain; if the caller passes their own headers, they own the content-type.
|
|
98
|
+
if (i?.headers !== undefined)
|
|
99
|
+
return new Response(body, i);
|
|
100
|
+
return new Response(body, { ...i, headers: { "content-type": "text/plain; charset=utf-8" } });
|
|
101
|
+
}
|
|
102
|
+
get query() {
|
|
103
|
+
if (!this.queryReady) {
|
|
104
|
+
this.queryValue = new URLSearchParams(this[CONTEXT_SEARCH]);
|
|
105
|
+
this.queryReady = true;
|
|
106
|
+
}
|
|
107
|
+
return this.queryValue;
|
|
108
|
+
}
|
|
109
|
+
set query(v) {
|
|
110
|
+
this.queryValue = v;
|
|
111
|
+
this.queryReady = true;
|
|
112
|
+
}
|
|
113
|
+
get cookies() {
|
|
114
|
+
this.cookiesValue ??= parseCookies(headerOf(this.source, "cookie"));
|
|
115
|
+
return this.cookiesValue;
|
|
116
|
+
}
|
|
117
|
+
boundedBody(maxBytes) {
|
|
118
|
+
return readBoundedBodyOrThrow(this.source, this.maxBodyBytes, maxBytes);
|
|
119
|
+
}
|
|
120
|
+
boundedJson(maxBytes) {
|
|
121
|
+
return readBoundedJsonBodyOrThrow(this.source, this.maxBodyBytes, maxBytes);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Backs `c.boundedBody`: bounded byte read that throws a flat 413/400 `Response` (caught by
|
|
125
|
+
* `runLifecycle` as control flow, like `throw redirect(...)`), so a handler can't ignore the cap.
|
|
126
|
+
* The byte-cap itself lives in `./body.ts` (shared with the schema path and `verifyWebhook`). */
|
|
127
|
+
async function readBoundedBodyOrThrow(req, maxBodyBytes, maxBytes) {
|
|
128
|
+
const r = await readBoundedBytes(req, maxBytes ?? maxBodyBytes);
|
|
129
|
+
if (r.ok)
|
|
130
|
+
return r.bytes;
|
|
131
|
+
throw r.status === 413
|
|
132
|
+
? jsonError(413, "payload_too_large")
|
|
133
|
+
: jsonError(400, "invalid_content_length");
|
|
134
|
+
}
|
|
135
|
+
/** Backs `c.boundedJson`: `readBoundedBodyOrThrow` + `JSON.parse`, throwing a flat 400 on bad JSON. */
|
|
136
|
+
async function readBoundedJsonBodyOrThrow(req, maxBodyBytes, maxBytes) {
|
|
137
|
+
const parsed = await readBoundedJsonSource(req, maxBytes ?? maxBodyBytes);
|
|
138
|
+
if (parsed instanceof Response)
|
|
139
|
+
throw parsed;
|
|
140
|
+
return parsed;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Read a JSON body with the same byte cap used by schema validation and `c.boundedJson`.
|
|
144
|
+
* Non-chunked, framed requests with an in-cap `Content-Length` use the runtime-native `req.json()`;
|
|
145
|
+
* chunked or length-less requests fall back to the streaming byte-cap guard.
|
|
146
|
+
*/
|
|
147
|
+
export async function readBoundedJsonSource(req, maxBytes) {
|
|
148
|
+
const declared = headerOf(req, "content-length");
|
|
149
|
+
if (declared !== null) {
|
|
150
|
+
// A present Content-Length must be a non-negative integer (HTTP grammar: `1*DIGIT`). A
|
|
151
|
+
// non-numeric / negative / fractional / exponential value (`Number()` would happily accept
|
|
152
|
+
// "abc"->NaN, "-5", "1.5", "1e3", "0x10") is malformed -> 400, rather than silently falling
|
|
153
|
+
// through to the streaming guard - which is an UPPER-bound cap only, so a lying SMALLER length
|
|
154
|
+
// would otherwise be read in full. Real HTTP servers only hand us a valid framed length; this
|
|
155
|
+
// hardens hand-built Requests (tests, the in-process client) and crafted input.
|
|
156
|
+
const length = parseContentLength(declared);
|
|
157
|
+
if (length === undefined)
|
|
158
|
+
return jsonError(400, "invalid_content_length");
|
|
159
|
+
if (length > maxBytes)
|
|
160
|
+
return jsonError(413, "payload_too_large");
|
|
161
|
+
const chunked = headerOf(req, "transfer-encoding") !== null;
|
|
162
|
+
if (!chunked) {
|
|
163
|
+
try {
|
|
164
|
+
return await req.json();
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return jsonError(400, "invalid_json");
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const body = req.body;
|
|
172
|
+
if (body === null)
|
|
173
|
+
return jsonError(400, "invalid_json");
|
|
174
|
+
const drained = await drainCapped(body, maxBytes);
|
|
175
|
+
if (!drained.ok)
|
|
176
|
+
return jsonError(413, "payload_too_large");
|
|
177
|
+
try {
|
|
178
|
+
return JSON.parse(TEXT_DECODER.decode(drained.bytes));
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return jsonError(400, "invalid_json");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=request-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response construction from a handler's return value: the header/cookie init, the fused-lane
|
|
3
|
+
* responders, the fast JSON path, and cookie append. Imports only the runtime-core primitives + the
|
|
4
|
+
* spine types, so the wire-response format lives in one module distinct from the request engine.
|
|
5
|
+
*/
|
|
6
|
+
import { type HandlerResult } from "./runtime-core.js";
|
|
7
|
+
import type { CtxSet, RawContext } from "./server.js";
|
|
8
|
+
/** Fused-lane respond when `c.set` is untouched. Bun 1.3's native `Response.json` now beats the
|
|
9
|
+
* older hand-inlined stringify + Response construction on this lane while preserving the exact
|
|
10
|
+
* body/content-type contract; keep the generic fallback for non-JSON values. */
|
|
11
|
+
export declare function fusedRespondNoSet(result: unknown): Response;
|
|
12
|
+
/** Fused-lane respond with a context: read `c.set` once; untouched (the common case) -> the fast
|
|
13
|
+
* JSON respond; touched -> the generic `toResponse` with those controls (statuses, headers, cookies). */
|
|
14
|
+
export declare function fusedRespond(result: unknown, ctx: RawContext): Response;
|
|
15
|
+
export declare function toResponse(result: HandlerResult, set: CtxSet): Response;
|
|
16
|
+
export declare function appendCookiesToResponse(response: Response, set: CtxSet): Response;
|
|
17
|
+
//# sourceMappingURL=respond.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"respond.d.ts","sourceRoot":"","sources":["../../src/server/respond.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAqBrD;;gFAEgF;AAChF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,CAW3D;AAED;yGACyG;AACzG,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,GAAG,QAAQ,CAIvE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAwBvE;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAUjF"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response construction from a handler's return value: the header/cookie init, the fused-lane
|
|
3
|
+
* responders, the fast JSON path, and cookie append. Imports only the runtime-core primitives + the
|
|
4
|
+
* spine types, so the wire-response format lives in one module distinct from the request engine.
|
|
5
|
+
*/
|
|
6
|
+
import { CONTEXT_SET, EMPTY_RESPONSE_CONTROLS, isResponseResult, } from "./runtime-core.js";
|
|
7
|
+
/** Build the response headers init. The common path (no `c.set`) returns `undefined` so `Response`
|
|
8
|
+
* gets no `headers` at all. Cookies force a `Headers` object - multiple `Set-Cookie`s can't live in a
|
|
9
|
+
* `Record<string,string>` (the 2nd would overwrite the 1st), so they're `append`ed individually. */
|
|
10
|
+
function headersInit(set) {
|
|
11
|
+
const cookies = set._cookies;
|
|
12
|
+
if (cookies === undefined || cookies.length === 0)
|
|
13
|
+
return set._headers;
|
|
14
|
+
const headers = new Headers(set._headers);
|
|
15
|
+
for (const cookie of cookies)
|
|
16
|
+
headers.append("set-cookie", cookie);
|
|
17
|
+
return headers;
|
|
18
|
+
}
|
|
19
|
+
// Keep the fast JSON respond path byte-identical to `Response.json` without probing it at module
|
|
20
|
+
// scope: workerd forbids `Response.json()` during startup. A shared `Headers` is safe to reuse
|
|
21
|
+
// across responses: the Response constructor copies `init.headers` into its own list.
|
|
22
|
+
const JSON_CT_HEADERS = new Headers({
|
|
23
|
+
"content-type": "application/json;charset=utf-8",
|
|
24
|
+
});
|
|
25
|
+
const JSON_INIT_200 = { status: 200, headers: JSON_CT_HEADERS };
|
|
26
|
+
/** Fused-lane respond when `c.set` is untouched. Bun 1.3's native `Response.json` now beats the
|
|
27
|
+
* older hand-inlined stringify + Response construction on this lane while preserving the exact
|
|
28
|
+
* body/content-type contract; keep the generic fallback for non-JSON values. */
|
|
29
|
+
export function fusedRespondNoSet(result) {
|
|
30
|
+
if (result !== undefined &&
|
|
31
|
+
!(result instanceof Response) &&
|
|
32
|
+
typeof result === "object" &&
|
|
33
|
+
result !== null &&
|
|
34
|
+
!isResponseResult(result)) {
|
|
35
|
+
return Response.json(result);
|
|
36
|
+
}
|
|
37
|
+
return toResponse(result, EMPTY_RESPONSE_CONTROLS);
|
|
38
|
+
}
|
|
39
|
+
/** Fused-lane respond with a context: read `c.set` once; untouched (the common case) -> the fast
|
|
40
|
+
* JSON respond; touched -> the generic `toResponse` with those controls (statuses, headers, cookies). */
|
|
41
|
+
export function fusedRespond(result, ctx) {
|
|
42
|
+
const set = ctx[CONTEXT_SET]();
|
|
43
|
+
if (set === undefined)
|
|
44
|
+
return fusedRespondNoSet(result);
|
|
45
|
+
return toResponse(result, set);
|
|
46
|
+
}
|
|
47
|
+
export function toResponse(result, set) {
|
|
48
|
+
if (isResponseResult(result)) {
|
|
49
|
+
return appendCookiesToResponse(result.toResponse(), set);
|
|
50
|
+
}
|
|
51
|
+
if (result instanceof Response) {
|
|
52
|
+
return appendCookiesToResponse(result, set);
|
|
53
|
+
}
|
|
54
|
+
const headers = headersInit(set);
|
|
55
|
+
const status = set.status ?? (result === undefined ? 204 : 200);
|
|
56
|
+
if (headers === undefined && result !== undefined) {
|
|
57
|
+
// Fast respond (profiled ~50 ns/req faster on every plain-JSON return): `JSON.stringify` + a
|
|
58
|
+
// prebuilt init beats `Response.json`'s internal init handling. Output is byte-identical -
|
|
59
|
+
// same body bytes, same probed content-type. `undefined` from stringify (a function/symbol
|
|
60
|
+
// result) delegates to Response.json so its TypeError contract stays the single source.
|
|
61
|
+
const body = JSON.stringify(result);
|
|
62
|
+
if (body !== undefined) {
|
|
63
|
+
return new Response(body, status === 200 ? JSON_INIT_200 : { status, headers: JSON_CT_HEADERS });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const init = headers === undefined ? { status } : { status, headers };
|
|
67
|
+
return result === undefined ? new Response(null, init) : Response.json(result, init);
|
|
68
|
+
}
|
|
69
|
+
export function appendCookiesToResponse(response, set) {
|
|
70
|
+
// A handler may queue cookies (`c.set.cookie` - e.g. a session cookie) AND return its own Response
|
|
71
|
+
// (e.g. `redirect("/")` after login). Cookies accumulate additively, so append them to the
|
|
72
|
+
// returned Response - otherwise the canonical set-session-then-redirect pattern would silently drop
|
|
73
|
+
// the cookie. (Other `c.set` fields stay the returned Response's own concern.)
|
|
74
|
+
const cookies = set._cookies;
|
|
75
|
+
if (cookies !== undefined && cookies.length > 0) {
|
|
76
|
+
for (const cookie of cookies)
|
|
77
|
+
response.headers.append("set-cookie", cookie);
|
|
78
|
+
}
|
|
79
|
+
return response;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=respond.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"respond.js","sourceRoot":"","sources":["../../src/server/respond.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,WAAW,EACX,uBAAuB,EAEvB,gBAAgB,GACjB,MAAM,mBAAmB,CAAA;AAG1B;;oGAEoG;AACpG,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAA;IAC5B,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,QAAQ,CAAA;IACtE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACzC,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;IAClE,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,iGAAiG;AACjG,+FAA+F;AAC/F,sFAAsF;AACtF,MAAM,eAAe,GAAG,IAAI,OAAO,CAAC;IAClC,cAAc,EAAE,gCAAgC;CACjD,CAAC,CAAA;AACF,MAAM,aAAa,GAAiB,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,CAAA;AAE7E;;gFAEgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,MAAe;IAC/C,IACE,MAAM,KAAK,SAAS;QACpB,CAAC,CAAC,MAAM,YAAY,QAAQ,CAAC;QAC7B,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,KAAK,IAAI;QACf,CAAC,gBAAgB,CAAC,MAAM,CAAC,EACzB,CAAC;QACD,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;IACD,OAAO,UAAU,CAAC,MAAuB,EAAE,uBAAuB,CAAC,CAAA;AACrE,CAAC;AAED;yGACyG;AACzG,MAAM,UAAU,YAAY,CAAC,MAAe,EAAE,GAAe;IAC3D,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,CAAA;IAC9B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAA;IACvD,OAAO,UAAU,CAAC,MAAuB,EAAE,GAAG,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAqB,EAAE,GAAW;IAC3D,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,uBAAuB,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,CAAA;IAC1D,CAAC;IACD,IAAI,MAAM,YAAY,QAAQ,EAAE,CAAC;QAC/B,OAAO,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC7C,CAAC;IACD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC/D,IAAI,OAAO,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAClD,6FAA6F;QAC7F,2FAA2F;QAC3F,2FAA2F;QAC3F,wFAAwF;QACxF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAuB,CAAA;QACzD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,IAAI,QAAQ,CACjB,IAAI,EACJ,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,CACtE,CAAA;QACH,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAiB,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;IACnF,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;AACtF,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAAkB,EAAE,GAAW;IACrE,mGAAmG;IACnG,2FAA2F;IAC3F,oGAAoG;IACpG,+EAA+E;IAC/E,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAA;IAC5B,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;IAC7E,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-core: the small primitives shared across the server's request/response modules - the context
|
|
3
|
+
* symbols, the `ResponseResult` marker, the lazy never-abort signal / unbounded budget singletons, and
|
|
4
|
+
* the request-source accessors. Kept in one leaf (it only type-imports the server's spine types, never
|
|
5
|
+
* its values) so `request-context`, `respond`, `node-outcome`, and the kernel form a cycle-free graph.
|
|
6
|
+
*/
|
|
7
|
+
import { type RequestBudget } from "../budget.js";
|
|
8
|
+
import type { CtxSet, RequestSource } from "./server.js";
|
|
9
|
+
/** A handler returns a `Response` (used as-is) or any value (serialized to JSON). */
|
|
10
|
+
export type HandlerResult = Response | unknown;
|
|
11
|
+
export declare const RESPONSE_RESULT: unique symbol;
|
|
12
|
+
export declare const CONTEXT_SET: unique symbol;
|
|
13
|
+
export declare const CONTEXT_SEARCH: unique symbol;
|
|
14
|
+
export interface ResponseResult {
|
|
15
|
+
readonly [RESPONSE_RESULT]: true;
|
|
16
|
+
toResponse(): Response;
|
|
17
|
+
toNodeBody?(): {
|
|
18
|
+
readonly status: number;
|
|
19
|
+
readonly headers: Readonly<Record<string, string | readonly string[]>> | undefined;
|
|
20
|
+
readonly body: string | Uint8Array;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export declare function isResponseResult(value: unknown): value is ResponseResult;
|
|
24
|
+
/** The concrete `Request` for a source - itself when a real `Request` was passed (the Web path), or the
|
|
25
|
+
* lazily-built one (the Node adapter). A real `Request` IS a `RequestSource`, so no wrapper is allocated
|
|
26
|
+
* on the Web hot path. */
|
|
27
|
+
export declare function requestOf(source: RequestSource): Request;
|
|
28
|
+
export declare function headerOf(source: RequestSource, name: string): string | null;
|
|
29
|
+
/** Off-edge `waitUntil`: run the background work fire-and-forget, never leaking an unhandled
|
|
30
|
+
* rejection. Edge runtimes pass their own (Workers `ctx.waitUntil`) via the platform arg. */
|
|
31
|
+
export declare const fallbackWaitUntil: (promise: Promise<unknown>) => void;
|
|
32
|
+
export declare const EMPTY_RESPONSE_CONTROLS: CtxSet;
|
|
33
|
+
export declare const TEXT_DECODER: TextDecoder;
|
|
34
|
+
export declare const getNeverAbortSignal: () => AbortSignal;
|
|
35
|
+
export declare const getUnboundedRequestBudget: () => RequestBudget;
|
|
36
|
+
//# sourceMappingURL=runtime-core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-core.d.ts","sourceRoot":"","sources":["../../src/server/runtime-core.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAgC,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAC/E,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAExD,qFAAqF;AACrF,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE9C,eAAO,MAAM,eAAe,eAAsC,CAAA;AAClE,eAAO,MAAM,WAAW,eAA8B,CAAA;AACtD,eAAO,MAAM,cAAc,eAAiC,CAAA;AAE5D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,CAAC,eAAe,CAAC,EAAE,IAAI,CAAA;IAChC,UAAU,IAAI,QAAQ,CAAA;IACtB,UAAU,CAAC,IAAI;QACb,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,CAAA;QAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAA;KACnC,CAAA;CACF;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAOxE;AAED;;0BAE0B;AAC1B,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAExD;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE3E;AAED;6FAC6F;AAC7F,eAAO,MAAM,iBAAiB,GAAI,SAAS,OAAO,CAAC,OAAO,CAAC,KAAG,IAE7D,CAAA;AAID,eAAO,MAAM,uBAAuB,EAAwB,MAAM,CAAA;AAElE,eAAO,MAAM,YAAY,aAAoB,CAAA;AAU7C,eAAO,MAAM,mBAAmB,QAAO,WAGtC,CAAA;AACD,eAAO,MAAM,yBAAyB,QAAO,aAG5C,CAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-core: the small primitives shared across the server's request/response modules - the context
|
|
3
|
+
* symbols, the `ResponseResult` marker, the lazy never-abort signal / unbounded budget singletons, and
|
|
4
|
+
* the request-source accessors. Kept in one leaf (it only type-imports the server's spine types, never
|
|
5
|
+
* its values) so `request-context`, `respond`, `node-outcome`, and the kernel form a cycle-free graph.
|
|
6
|
+
*/
|
|
7
|
+
import { createUnboundedRequestBudget } from "../budget.js";
|
|
8
|
+
export const RESPONSE_RESULT = Symbol.for("nifra.response.result");
|
|
9
|
+
export const CONTEXT_SET = Symbol("nifra.context.set");
|
|
10
|
+
export const CONTEXT_SEARCH = Symbol("nifra.context.search");
|
|
11
|
+
export function isResponseResult(value) {
|
|
12
|
+
return (typeof value === "object" &&
|
|
13
|
+
value !== null &&
|
|
14
|
+
value[RESPONSE_RESULT] === true &&
|
|
15
|
+
typeof value.toResponse === "function");
|
|
16
|
+
}
|
|
17
|
+
/** The concrete `Request` for a source - itself when a real `Request` was passed (the Web path), or the
|
|
18
|
+
* lazily-built one (the Node adapter). A real `Request` IS a `RequestSource`, so no wrapper is allocated
|
|
19
|
+
* on the Web hot path. */
|
|
20
|
+
export function requestOf(source) {
|
|
21
|
+
return source.request ?? source;
|
|
22
|
+
}
|
|
23
|
+
export function headerOf(source, name) {
|
|
24
|
+
return source.header?.(name) ?? source.headers.get(name);
|
|
25
|
+
}
|
|
26
|
+
/** Off-edge `waitUntil`: run the background work fire-and-forget, never leaking an unhandled
|
|
27
|
+
* rejection. Edge runtimes pass their own (Workers `ctx.waitUntil`) via the platform arg. */
|
|
28
|
+
export const fallbackWaitUntil = (promise) => {
|
|
29
|
+
void promise.catch(() => { });
|
|
30
|
+
};
|
|
31
|
+
// Finalization only reads `status`, `_headers`, and `_cookies`. The user-visible mutator methods
|
|
32
|
+
// live on `LazyResponseControls`, created by the `c.set` getter only when user code touches it.
|
|
33
|
+
export const EMPTY_RESPONSE_CONTROLS = Object.freeze({});
|
|
34
|
+
export const TEXT_DECODER = new TextDecoder();
|
|
35
|
+
/**
|
|
36
|
+
* Shared never-aborting signal for `ctx.signal` when no timeout is armed - created lazily and
|
|
37
|
+
* cached. NOT a module-scope `new AbortController()`: edge runtimes (Cloudflare workerd) forbid
|
|
38
|
+
* constructing one in global scope; the first request builds it inside the handler, then it's
|
|
39
|
+
* reused at zero per-request cost.
|
|
40
|
+
*/
|
|
41
|
+
let neverAbortSignal;
|
|
42
|
+
let unboundedRequestBudget;
|
|
43
|
+
export const getNeverAbortSignal = () => {
|
|
44
|
+
neverAbortSignal ??= new AbortController().signal;
|
|
45
|
+
return neverAbortSignal;
|
|
46
|
+
};
|
|
47
|
+
export const getUnboundedRequestBudget = () => {
|
|
48
|
+
unboundedRequestBudget ??= createUnboundedRequestBudget(getNeverAbortSignal());
|
|
49
|
+
return unboundedRequestBudget;
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=runtime-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-core.js","sourceRoot":"","sources":["../../src/server/runtime-core.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,4BAA4B,EAAsB,MAAM,cAAc,CAAA;AAM/E,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;AAClE,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAA;AACtD,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAA;AAY5D,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACb,KAAkD,CAAC,eAAe,CAAC,KAAK,IAAI;QAC7E,OAAQ,KAA2C,CAAC,UAAU,KAAK,UAAU,CAC9E,CAAA;AACH,CAAC;AAED;;0BAE0B;AAC1B,MAAM,UAAU,SAAS,CAAC,MAAqB;IAC7C,OAAO,MAAM,CAAC,OAAO,IAAK,MAA6B,CAAA;AACzD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAqB,EAAE,IAAY;IAC1D,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AAC1D,CAAC;AAED;6FAC6F;AAC7F,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAyB,EAAQ,EAAE;IACnE,KAAK,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;AAC9B,CAAC,CAAA;AAED,iGAAiG;AACjG,gGAAgG;AAChG,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAW,CAAA;AAElE,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAA;AAE7C;;;;;GAKG;AACH,IAAI,gBAAyC,CAAA;AAC7C,IAAI,sBAAiD,CAAA;AACrD,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAgB,EAAE;IACnD,gBAAgB,KAAK,IAAI,eAAe,EAAE,CAAC,MAAM,CAAA;IACjD,OAAO,gBAAgB,CAAA;AACzB,CAAC,CAAA;AACD,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAkB,EAAE;IAC3D,sBAAsB,KAAK,4BAA4B,CAAC,mBAAmB,EAAE,CAAC,CAAA;IAC9E,OAAO,sBAAsB,CAAA;AAC/B,CAAC,CAAA"}
|