@beignet/core 0.0.27 → 0.0.28
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/CHANGELOG.md +8 -0
- package/README.md +27 -6
- package/dist/idempotency/index.d.ts +2 -2
- package/dist/idempotency/index.d.ts.map +1 -1
- package/dist/idempotency/index.js +17 -9
- package/dist/idempotency/index.js.map +1 -1
- package/dist/server/hooks/idempotency.d.ts +7 -6
- package/dist/server/hooks/idempotency.d.ts.map +1 -1
- package/dist/server/hooks/idempotency.js +16 -11
- package/dist/server/hooks/idempotency.js.map +1 -1
- package/dist/server/hooks/rate-limit.d.ts +5 -4
- package/dist/server/hooks/rate-limit.d.ts.map +1 -1
- package/dist/server/hooks/rate-limit.js +5 -4
- package/dist/server/hooks/rate-limit.js.map +1 -1
- package/dist/server/http.d.ts +7 -5
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/internal-hooks.d.ts +25 -0
- package/dist/server/internal-hooks.d.ts.map +1 -0
- package/dist/server/internal-hooks.js +5 -0
- package/dist/server/internal-hooks.js.map +1 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +99 -40
- package/dist/server/server.js.map +1 -1
- package/package.json +1 -1
- package/src/idempotency/index.ts +21 -13
- package/src/providers/instrumentation.ts +13 -0
- package/src/server/hooks/idempotency.ts +28 -10
- package/src/server/hooks/rate-limit.ts +5 -4
- package/src/server/http.ts +31 -5
- package/src/server/index.ts +2 -0
- package/src/server/instrumentation.ts +10 -1
- package/src/server/internal-hooks.ts +49 -0
- package/src/server/server.ts +285 -64
package/src/server/http.ts
CHANGED
|
@@ -340,6 +340,26 @@ export type BeforeSendHook<
|
|
|
340
340
|
native?: boolean;
|
|
341
341
|
}) => MaybePromise<HttpResponseLike | undefined>;
|
|
342
342
|
|
|
343
|
+
/**
|
|
344
|
+
* Per-stage timing breakdown of one request, in milliseconds.
|
|
345
|
+
*
|
|
346
|
+
* Stages are measured around the pipeline phases in execution order:
|
|
347
|
+
* `onRequest` hooks, request parsing/validation, context creation, route
|
|
348
|
+
* hooks plus `beforeHandle` hooks, the route handler, and response
|
|
349
|
+
* preparation (`beforeSend`, response validation, and finalizers). Stages
|
|
350
|
+
* that did not run for a request — parsing on raw routes, the handler after
|
|
351
|
+
* a hook short-circuit — report `0`. The stages do not sum exactly to the
|
|
352
|
+
* request `durationMs`; routing and bookkeeping live in the gaps.
|
|
353
|
+
*/
|
|
354
|
+
export type RequestStageTimings = {
|
|
355
|
+
onRequestMs: number;
|
|
356
|
+
parseMs: number;
|
|
357
|
+
contextMs: number;
|
|
358
|
+
beforeHandleMs: number;
|
|
359
|
+
handlerMs: number;
|
|
360
|
+
sendMs: number;
|
|
361
|
+
};
|
|
362
|
+
|
|
343
363
|
/**
|
|
344
364
|
* Hook that runs after the response has been prepared.
|
|
345
365
|
*
|
|
@@ -360,6 +380,10 @@ export type AfterSendHook<
|
|
|
360
380
|
response: HttpResponseLike;
|
|
361
381
|
error?: unknown;
|
|
362
382
|
durationMs: number;
|
|
383
|
+
/**
|
|
384
|
+
* Per-stage timing breakdown of this request.
|
|
385
|
+
*/
|
|
386
|
+
stages: RequestStageTimings;
|
|
363
387
|
}) => MaybePromise<void>;
|
|
364
388
|
|
|
365
389
|
/**
|
|
@@ -402,10 +426,12 @@ export type ServerUnhandledErrorMapper<
|
|
|
402
426
|
/**
|
|
403
427
|
* Server lifecycle hook collection.
|
|
404
428
|
*
|
|
405
|
-
* Hooks run in the order they are registered
|
|
406
|
-
* before context creation;
|
|
407
|
-
*
|
|
408
|
-
*
|
|
429
|
+
* Hooks run in the order they are registered within each server-hook phase.
|
|
430
|
+
* `onRequest` can short-circuit before context creation; route hooks resolve
|
|
431
|
+
* route-scoped context before server `beforeHandle`; `beforeHandle` can replace
|
|
432
|
+
* context or short-circuit; `beforeSend` can replace the outgoing response, and
|
|
433
|
+
* route-owned replacements are contract-validated before send; `afterSend`
|
|
434
|
+
* observes the final response.
|
|
409
435
|
*/
|
|
410
436
|
export interface ServerHook<Ctx, Ports extends AnyPorts = AnyPorts> {
|
|
411
437
|
/**
|
|
@@ -427,7 +453,7 @@ export interface ServerHook<Ctx, Ports extends AnyPorts = AnyPorts> {
|
|
|
427
453
|
*/
|
|
428
454
|
onRequest?: OnRequestHook<Ports>;
|
|
429
455
|
/**
|
|
430
|
-
* Runs after request parsing and
|
|
456
|
+
* Runs after request parsing, context creation, and route hook resolution.
|
|
431
457
|
*/
|
|
432
458
|
beforeHandle?: BeforeHandleHook<Ctx>;
|
|
433
459
|
/**
|
package/src/server/index.ts
CHANGED
|
@@ -371,7 +371,15 @@ export function createServerInstrumentation<Ctx>(
|
|
|
371
371
|
},
|
|
372
372
|
};
|
|
373
373
|
},
|
|
374
|
-
afterSend: ({
|
|
374
|
+
afterSend: ({
|
|
375
|
+
req,
|
|
376
|
+
ctx,
|
|
377
|
+
contract,
|
|
378
|
+
response,
|
|
379
|
+
error,
|
|
380
|
+
durationMs,
|
|
381
|
+
stages,
|
|
382
|
+
}) => {
|
|
375
383
|
try {
|
|
376
384
|
if (!port) return;
|
|
377
385
|
|
|
@@ -414,6 +422,7 @@ export function createServerInstrumentation<Ctx>(
|
|
|
414
422
|
responseOwner,
|
|
415
423
|
status: response.status,
|
|
416
424
|
durationMs,
|
|
425
|
+
stages,
|
|
417
426
|
details: {
|
|
418
427
|
headers: requestHeadersToRecord(req.headers),
|
|
419
428
|
route: {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { HttpContractConfig } from "../contracts/index.js";
|
|
2
|
+
import type {
|
|
3
|
+
HttpRequestLike,
|
|
4
|
+
HttpResponseLike,
|
|
5
|
+
MaybePromise,
|
|
6
|
+
} from "./http.js";
|
|
7
|
+
|
|
8
|
+
export const responseFinalizerHook = Symbol(
|
|
9
|
+
"@beignet/core/server/responseFinalizer",
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export type ResponseFinalizerResponseOwner =
|
|
13
|
+
| "route"
|
|
14
|
+
| "framework"
|
|
15
|
+
| "transport";
|
|
16
|
+
|
|
17
|
+
export type ResponseFinalizerValidationState =
|
|
18
|
+
| "validated"
|
|
19
|
+
| "disabled"
|
|
20
|
+
| "not-applicable";
|
|
21
|
+
|
|
22
|
+
export type ResponseFinalizerHookArgs<Ctx> = {
|
|
23
|
+
req: HttpRequestLike;
|
|
24
|
+
ctx?: Ctx;
|
|
25
|
+
contract: HttpContractConfig;
|
|
26
|
+
path?: unknown;
|
|
27
|
+
query?: unknown;
|
|
28
|
+
headers?: unknown;
|
|
29
|
+
body?: unknown;
|
|
30
|
+
response: HttpResponseLike;
|
|
31
|
+
error?: unknown;
|
|
32
|
+
native?: boolean;
|
|
33
|
+
owner: ResponseFinalizerResponseOwner;
|
|
34
|
+
responseValidation: ResponseFinalizerValidationState;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type ResponseFinalizerHook<Ctx> = (
|
|
38
|
+
args: ResponseFinalizerHookArgs<Ctx>,
|
|
39
|
+
) => MaybePromise<void>;
|
|
40
|
+
|
|
41
|
+
export type ResponseFinalizerServerHook<Ctx> = {
|
|
42
|
+
[responseFinalizerHook]?: ResponseFinalizerHook<Ctx>;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export function getResponseFinalizerHook<Ctx>(
|
|
46
|
+
hook: unknown,
|
|
47
|
+
): ResponseFinalizerHook<Ctx> | undefined {
|
|
48
|
+
return (hook as ResponseFinalizerServerHook<Ctx>)[responseFinalizerHook];
|
|
49
|
+
}
|