@nifrajs/core 3.1.0 → 3.2.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 +21 -0
- package/dist/durable-adapters.d.ts.map +1 -1
- package/dist/durable-adapters.js +26 -3
- package/dist/durable-adapters.js.map +1 -1
- package/dist/durable-approval.d.ts +56 -0
- package/dist/durable-approval.d.ts.map +1 -0
- package/dist/durable-approval.js +233 -0
- package/dist/durable-approval.js.map +1 -0
- package/dist/durable-effect.d.ts +42 -0
- package/dist/durable-effect.d.ts.map +1 -0
- package/dist/durable-effect.js +234 -0
- package/dist/durable-effect.js.map +1 -0
- package/dist/durable-execution.d.ts +8 -346
- package/dist/durable-execution.d.ts.map +1 -1
- package/dist/durable-execution.js +7 -1150
- package/dist/durable-execution.js.map +1 -1
- package/dist/durable-saga.d.ts +94 -0
- package/dist/durable-saga.d.ts.map +1 -0
- package/dist/durable-saga.js +550 -0
- package/dist/durable-saga.js.map +1 -0
- package/dist/edge-kit.d.ts +2 -2
- package/dist/edge-kit.d.ts.map +1 -1
- package/dist/edge-kit.js +2 -2
- package/dist/edge-kit.js.map +1 -1
- package/dist/index.d.ts +23 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -2
- package/dist/index.js.map +1 -1
- package/dist/internal/durable-approval-protocol.d.ts +1 -1
- package/dist/internal/durable-approval-protocol.d.ts.map +1 -1
- package/dist/internal/durable-effect-protocol.d.ts +1 -1
- package/dist/internal/durable-effect-protocol.d.ts.map +1 -1
- package/dist/internal/durable-saga-protocol.d.ts +1 -1
- package/dist/internal/durable-saga-protocol.d.ts.map +1 -1
- package/dist/internal/durable-shared.d.ts +26 -0
- package/dist/internal/durable-shared.d.ts.map +1 -0
- package/dist/internal/durable-shared.js +131 -0
- package/dist/internal/durable-shared.js.map +1 -0
- package/dist/internal/durable-types.d.ts +159 -0
- package/dist/internal/durable-types.d.ts.map +1 -0
- package/dist/internal/durable-types.js +2 -0
- package/dist/internal/durable-types.js.map +1 -0
- package/dist/internal/route-compiler.d.ts +61 -0
- package/dist/internal/route-compiler.d.ts.map +1 -0
- package/dist/internal/route-compiler.js +121 -0
- package/dist/internal/route-compiler.js.map +1 -0
- package/dist/internal/route-execution.d.ts +6 -4
- package/dist/internal/route-execution.d.ts.map +1 -1
- package/dist/internal/route-execution.js +2 -17
- package/dist/internal/route-execution.js.map +1 -1
- package/dist/internal/route-lanes.d.ts +35 -0
- package/dist/internal/route-lanes.d.ts.map +1 -0
- package/dist/internal/route-lanes.js +150 -0
- package/dist/internal/route-lanes.js.map +1 -0
- package/dist/internal/route-program.d.ts +67 -0
- package/dist/internal/route-program.d.ts.map +1 -0
- package/dist/internal/route-program.js +199 -0
- package/dist/internal/route-program.js.map +1 -0
- package/dist/server/bare-error-lane.d.ts +1 -1
- package/dist/server/bare-error-lane.d.ts.map +1 -1
- package/dist/server/bare-error-lane.js +3 -3
- package/dist/server/bare-error-lane.js.map +1 -1
- package/dist/server/body-lane.d.ts +13 -0
- package/dist/server/body-lane.d.ts.map +1 -0
- package/dist/server/body-lane.js +134 -0
- package/dist/server/body-lane.js.map +1 -0
- package/dist/server/contract.d.ts +40 -14
- package/dist/server/contract.d.ts.map +1 -1
- package/dist/server/contract.js +7 -0
- package/dist/server/contract.js.map +1 -1
- package/dist/server/cookies.d.ts.map +1 -1
- package/dist/server/cookies.js +16 -2
- package/dist/server/cookies.js.map +1 -1
- package/dist/server/plugin.d.ts +2 -2
- package/dist/server/plugin.d.ts.map +1 -1
- package/dist/server/plugin.js +6 -1
- package/dist/server/plugin.js.map +1 -1
- package/dist/server/registry.d.ts +40 -12
- package/dist/server/registry.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +4 -28
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +10 -185
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/respond.d.ts.map +1 -1
- package/dist/server/respond.js +39 -2
- package/dist/server/respond.js.map +1 -1
- package/dist/server/runtime-core.d.ts +18 -2
- package/dist/server/runtime-core.d.ts.map +1 -1
- package/dist/server/runtime-core.js +0 -23
- package/dist/server/runtime-core.js.map +1 -1
- package/dist/server/server-types.d.ts +3 -0
- package/dist/server/server-types.d.ts.map +1 -1
- package/dist/server/server.d.ts +113 -84
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +506 -639
- package/dist/server/server.js.map +1 -1
- package/dist/server/validation.d.ts +5 -0
- package/dist/server/validation.d.ts.map +1 -0
- package/dist/server/validation.js +13 -0
- package/dist/server/validation.js.map +1 -0
- package/dist/server/ws-bun.d.ts +11 -3
- package/dist/server/ws-bun.d.ts.map +1 -1
- package/dist/server/ws-bun.js +42 -12
- package/dist/server/ws-bun.js.map +1 -1
- package/dist/server/ws-hook.d.ts +3 -2
- package/dist/server/ws-hook.d.ts.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/single-copy.d.ts.map +1 -1
- package/dist/single-copy.js +3 -1
- package/dist/single-copy.js.map +1 -1
- package/package.json +6 -3
- package/src/durable-adapters.ts +20 -0
- package/src/durable-approval.ts +281 -0
- package/src/durable-effect.ts +300 -0
- package/src/durable-execution.ts +8 -1627
- package/src/durable-saga.ts +744 -0
- package/src/edge-kit.ts +2 -2
- package/src/index.ts +129 -2
- package/src/internal/durable-approval-protocol.ts +1 -1
- package/src/internal/durable-effect-protocol.ts +1 -1
- package/src/internal/durable-saga-protocol.ts +1 -1
- package/src/internal/durable-shared.ts +157 -0
- package/src/internal/durable-types.ts +194 -0
- package/src/internal/route-compiler.ts +234 -0
- package/src/internal/route-execution.ts +34 -84
- package/src/internal/route-lanes.ts +221 -0
- package/src/internal/route-program.ts +404 -0
- package/src/server/bare-error-lane.ts +3 -2
- package/src/server/body-lane.ts +203 -0
- package/src/server/contract.ts +70 -20
- package/src/server/cookies.ts +16 -2
- package/src/server/plugin.ts +11 -5
- package/src/server/registry.ts +71 -16
- package/src/server/request-context.ts +7 -262
- package/src/server/respond.ts +45 -2
- package/src/server/runtime-core.ts +28 -2
- package/src/server/server-types.ts +3 -0
- package/src/server/server.ts +1152 -1260
- package/src/server/validation.ts +19 -0
- package/src/server/ws-bun.ts +44 -11
- package/src/server/ws-hook.ts +3 -2
- package/src/server.ts +7 -2
- package/src/single-copy.ts +3 -1
package/src/server/respond.ts
CHANGED
|
@@ -122,6 +122,8 @@ function staticJsonResponse(
|
|
|
122
122
|
contentType,
|
|
123
123
|
)
|
|
124
124
|
}
|
|
125
|
+
// lgtm [js/stack-trace-exposure] `body` is already serialized; ordinary thrown errors are replaced
|
|
126
|
+
// with the fixed internal-error envelope before reaching this response boundary.
|
|
125
127
|
return new Response(body, init)
|
|
126
128
|
}
|
|
127
129
|
|
|
@@ -160,6 +162,7 @@ function withStaticHeaderInit(
|
|
|
160
162
|
// portable constructor path there and select the Deno-specific shape only for Web responses that
|
|
161
163
|
// carry a plain record. The first request lazily probes Deno's native JSON content-type so this
|
|
162
164
|
// preserves the runtime's Response.json contract instead of baking in Bun's charset suffix.
|
|
165
|
+
const IS_BUN = typeof (globalThis as { Bun?: unknown }).Bun !== "undefined"
|
|
163
166
|
const IS_DENO = typeof (globalThis as { Deno?: unknown }).Deno !== "undefined"
|
|
164
167
|
let denoJsonContentType: string | undefined
|
|
165
168
|
|
|
@@ -176,6 +179,8 @@ function denoResponseWithJsonBody(
|
|
|
176
179
|
headers: Record<string, string>,
|
|
177
180
|
defaultContentType = responseJsonContentType(),
|
|
178
181
|
): Response {
|
|
182
|
+
// lgtm [js/stack-trace-exposure] this body is serialized data; ordinary thrown errors are replaced
|
|
183
|
+
// with the fixed internal-error envelope before reaching this response boundary.
|
|
179
184
|
const response = new Response(body, { status })
|
|
180
185
|
let hasContentType = false
|
|
181
186
|
for (const [name, value] of Object.entries(headers)) {
|
|
@@ -188,6 +193,24 @@ function denoResponseWithJsonBody(
|
|
|
188
193
|
return response
|
|
189
194
|
}
|
|
190
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Render a JSON value with caller-owned headers on the runtimes where mutating the response is
|
|
198
|
+
* cheaper than asking the Response constructor to ingest a record. Node deliberately stays on the
|
|
199
|
+
* record path: its undici implementation is a little faster there, and its production HTTP adapter
|
|
200
|
+
* normally uses the direct node outcome anyway. The two operations are equivalent at the Web
|
|
201
|
+
* boundary: Response.json supplies the same default content type, then the caller's headers override
|
|
202
|
+
* it exactly as `withJsonContentType` did.
|
|
203
|
+
*/
|
|
204
|
+
function jsonResponseWithOwnHeaders(
|
|
205
|
+
result: object,
|
|
206
|
+
status: number,
|
|
207
|
+
headers: Record<string, string>,
|
|
208
|
+
): Response {
|
|
209
|
+
const response = status === 200 ? Response.json(result) : Response.json(result, { status })
|
|
210
|
+
for (const name of Object.keys(headers)) response.headers.set(name, headers[name]!)
|
|
211
|
+
return stamped(response)
|
|
212
|
+
}
|
|
213
|
+
|
|
191
214
|
// The framework-buffered-body marker shared with the Node adapter: a Response carrying it exposes
|
|
192
215
|
// its already-serialized bytes without draining. On the Web serving paths it exists ONLY when a
|
|
193
216
|
// registered body/raw hook needs it, so hook-less apps pay nothing.
|
|
@@ -438,6 +461,24 @@ export function toResponse(
|
|
|
438
461
|
if (status === 204 || status === 205 || status === 304) {
|
|
439
462
|
return stamped(new Response(null, headers === undefined ? { status } : { status, headers }))
|
|
440
463
|
}
|
|
464
|
+
// Bun and Deno both make a JSON response first and then accept a few header mutations more cheaply
|
|
465
|
+
// than ingesting the same plain record in the constructor. This is the common dynamic-header
|
|
466
|
+
// shape (`c.set.headers`) after all cookies/static-header/tagging cases have been excluded. Keep the
|
|
467
|
+
// Node record path unchanged: its Web constructor wins by a small margin, and the native Node
|
|
468
|
+
// adapter's normal route finalizer does not build this Response in the first place.
|
|
469
|
+
if (
|
|
470
|
+
own !== undefined &&
|
|
471
|
+
!(own instanceof Headers) &&
|
|
472
|
+
statics === undefined &&
|
|
473
|
+
(set._cookies === undefined || set._cookies.length === 0) &&
|
|
474
|
+
(IS_BUN || IS_DENO) &&
|
|
475
|
+
!tagResponseBody &&
|
|
476
|
+
result !== undefined &&
|
|
477
|
+
typeof result === "object" &&
|
|
478
|
+
result !== null
|
|
479
|
+
) {
|
|
480
|
+
return jsonResponseWithOwnHeaders(result, status, own)
|
|
481
|
+
}
|
|
441
482
|
if (own === undefined && result !== undefined) {
|
|
442
483
|
// Fast respond (profiled ~50 ns/req faster on every plain-JSON return): `JSON.stringify` + a
|
|
443
484
|
// prebuilt init beats `Response.json`'s internal init handling. Output is byte-identical -
|
|
@@ -451,7 +492,8 @@ export function toResponse(
|
|
|
451
492
|
: { status, headers: jsonCtHeaders }
|
|
452
493
|
return tagged(
|
|
453
494
|
statics === undefined
|
|
454
|
-
?
|
|
495
|
+
? // lgtm [js/stack-trace-exposure] the serialized body is not a caught error stack.
|
|
496
|
+
new Response(body, init)
|
|
455
497
|
: staticJsonResponse(body, status, statics, JSON_CONTENT_TYPE, init),
|
|
456
498
|
body,
|
|
457
499
|
tagResponseBody,
|
|
@@ -471,7 +513,8 @@ export function toResponse(
|
|
|
471
513
|
headers as Record<string, string>,
|
|
472
514
|
JSON_CT_HEADERS.get("content-type") ?? "application/json;charset=utf-8",
|
|
473
515
|
)
|
|
474
|
-
:
|
|
516
|
+
: // lgtm [js/stack-trace-exposure] the serialized body is not a caught error stack.
|
|
517
|
+
new Response(body, { status, headers: withJsonContentType(headers) })
|
|
475
518
|
return tagged(
|
|
476
519
|
response,
|
|
477
520
|
body,
|
|
@@ -64,6 +64,22 @@ export interface ResponseResult {
|
|
|
64
64
|
readonly plain?: PlainRender
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Type-only metadata carried by {@link status}. The symbol is declared, not created, so this brand
|
|
69
|
+
* adds no runtime property and no per-response allocation. It lets the registry distinguish a typed
|
|
70
|
+
* early response from an ordinary handler value while preserving the existing ResponseResult marker.
|
|
71
|
+
*/
|
|
72
|
+
export declare const STATUS_RESPONSE_TYPE: unique symbol
|
|
73
|
+
|
|
74
|
+
/** A status-bearing response whose code and body remain visible to TypeScript. */
|
|
75
|
+
export interface StatusResponse<Code extends number = number, Body = unknown>
|
|
76
|
+
extends ResponseResult {
|
|
77
|
+
readonly [STATUS_RESPONSE_TYPE]: {
|
|
78
|
+
readonly code: Code
|
|
79
|
+
readonly body: Body
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
67
83
|
export function isResponseResult(value: unknown): value is ResponseResult {
|
|
68
84
|
return (
|
|
69
85
|
typeof value === "object" &&
|
|
@@ -114,11 +130,21 @@ export function plainRenderHeaders(
|
|
|
114
130
|
* The body is serialized by the lane that renders it, exactly like a handler's plain return, so the
|
|
115
131
|
* response carries a `content-length` rather than falling to chunked, and queued cookies still apply.
|
|
116
132
|
*/
|
|
133
|
+
export function status<const Code extends number>(
|
|
134
|
+
code: Code,
|
|
135
|
+
body?: undefined,
|
|
136
|
+
init?: { readonly headers?: Readonly<Record<string, string>> },
|
|
137
|
+
): StatusResponse<Code, undefined>
|
|
138
|
+
export function status<const Code extends number, const Body>(
|
|
139
|
+
code: Code,
|
|
140
|
+
body: Body,
|
|
141
|
+
init?: { readonly headers?: Readonly<Record<string, string>> },
|
|
142
|
+
): StatusResponse<Code, Body>
|
|
117
143
|
export function status(
|
|
118
144
|
code: number,
|
|
119
145
|
body?: unknown,
|
|
120
146
|
init?: { readonly headers?: Readonly<Record<string, string>> },
|
|
121
|
-
):
|
|
147
|
+
): StatusResponse<number, unknown> {
|
|
122
148
|
// The range `Response` accepts, enforced HERE so the plain lane cannot outrun it. A plain render
|
|
123
149
|
// is written straight to the socket by the Node adapter, where `writeHead` takes 100-999 - so a
|
|
124
150
|
// status this rejects would otherwise ship on Node and throw on every Web runtime, from the same
|
|
@@ -141,7 +167,7 @@ export function status(
|
|
|
141
167
|
headers["content-type"] ??= "application/json;charset=utf-8"
|
|
142
168
|
return new Response(JSON.stringify(body), { status: code, headers })
|
|
143
169
|
},
|
|
144
|
-
}
|
|
170
|
+
} as StatusResponse<number, unknown>
|
|
145
171
|
}
|
|
146
172
|
|
|
147
173
|
/** The concrete `Request` for a source - itself when a real `Request` was passed (the Web path), or the
|
|
@@ -256,6 +256,9 @@ export interface RunningServer {
|
|
|
256
256
|
readonly hostname: string
|
|
257
257
|
readonly pendingRequests: number
|
|
258
258
|
stop(closeActiveConnections?: boolean): void
|
|
259
|
+
/** Bun's native topic broadcast, present on the Bun `Server` handle. `app.publish` delegates to it
|
|
260
|
+
* in native-pubsub mode; absent on other runtimes' running-server views. */
|
|
261
|
+
publish?(topic: string, data: string | ArrayBufferView | ArrayBuffer): number
|
|
259
262
|
}
|
|
260
263
|
|
|
261
264
|
/**
|