@fluojs/http 1.0.0-beta.5 → 1.0.0-beta.7
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/dispatch/dispatch-response-policy.d.ts +1 -1
- package/dist/dispatch/dispatch-response-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-response-policy.js +3 -4
- package/dist/dispatch/dispatch-routing-policy.d.ts.map +1 -1
- package/dist/dispatch/dispatch-routing-policy.js +6 -4
- package/dist/dispatch/dispatcher.d.ts +18 -6
- package/dist/dispatch/dispatcher.d.ts.map +1 -1
- package/dist/dispatch/dispatcher.js +252 -21
- package/dist/dispatch/fast-path/debug-visibility.d.ts +18 -0
- package/dist/dispatch/fast-path/debug-visibility.d.ts.map +1 -0
- package/dist/dispatch/fast-path/debug-visibility.js +39 -0
- package/dist/dispatch/fast-path/eligibility-checker.d.ts +22 -0
- package/dist/dispatch/fast-path/eligibility-checker.d.ts.map +1 -0
- package/dist/dispatch/fast-path/eligibility-checker.js +110 -0
- package/dist/dispatch/fast-path/eligibility.d.ts +61 -0
- package/dist/dispatch/fast-path/eligibility.d.ts.map +1 -0
- package/dist/dispatch/fast-path/eligibility.js +23 -0
- package/dist/dispatch/fast-path/fast-path-executor.d.ts +21 -0
- package/dist/dispatch/fast-path/fast-path-executor.d.ts.map +1 -0
- package/dist/dispatch/fast-path/fast-path-executor.js +80 -0
- package/dist/dispatch/fast-path/index.d.ts +6 -0
- package/dist/dispatch/fast-path/index.d.ts.map +1 -0
- package/dist/dispatch/fast-path/index.js +4 -0
- package/dist/dispatch/native-route-handoff.d.ts.map +1 -1
- package/dist/dispatch/native-route-handoff.js +8 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -11,7 +11,7 @@ import type { FrameworkRequest, FrameworkResponse, HandlerDescriptor } from '../
|
|
|
11
11
|
* @param contentNegotiation The content negotiation.
|
|
12
12
|
* @returns The write success response result.
|
|
13
13
|
*/
|
|
14
|
-
export declare function writeSuccessResponse(handler: HandlerDescriptor, request: FrameworkRequest, response: FrameworkResponse, value: unknown, contentNegotiation: ResolvedContentNegotiation | undefined):
|
|
14
|
+
export declare function writeSuccessResponse(handler: HandlerDescriptor, request: FrameworkRequest, response: FrameworkResponse, value: unknown, contentNegotiation: ResolvedContentNegotiation | undefined): ReturnType<FrameworkResponse['send']> | void;
|
|
15
15
|
export { resolveContentNegotiation, writeErrorResponse };
|
|
16
16
|
export type { ResolvedContentNegotiation };
|
|
17
17
|
//# sourceMappingURL=dispatch-response-policy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-response-policy.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatch-response-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EAEzB,KAAK,0BAA0B,EAChC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAgErB;;;;;;;;;GASG;AACH,
|
|
1
|
+
{"version":3,"file":"dispatch-response-policy.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatch-response-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EAEzB,KAAK,0BAA0B,EAChC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAgErB;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,OAAO,EACd,kBAAkB,EAAE,0BAA0B,GAAG,SAAS,GACzD,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAwC9C;AAED,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,CAAC;AACzD,YAAY,EAAE,0BAA0B,EAAE,CAAC"}
|
|
@@ -50,7 +50,7 @@ function isJsonContentType(contentType) {
|
|
|
50
50
|
* @param contentNegotiation The content negotiation.
|
|
51
51
|
* @returns The write success response result.
|
|
52
52
|
*/
|
|
53
|
-
export
|
|
53
|
+
export function writeSuccessResponse(handler, request, response, value, contentNegotiation) {
|
|
54
54
|
if (response.committed) {
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
@@ -79,10 +79,9 @@ export async function writeSuccessResponse(handler, request, response, value, co
|
|
|
79
79
|
response.setStatus(resolveDefaultSuccessStatus(handler, value));
|
|
80
80
|
}
|
|
81
81
|
if (!formatter && hasSimpleJsonResponseWriter(response) && canUseSimpleJsonFastPath(response, value)) {
|
|
82
|
-
|
|
83
|
-
return;
|
|
82
|
+
return response.sendSimpleJson(value);
|
|
84
83
|
}
|
|
85
84
|
const responseBody = formatter ? formatter.format(value) : value;
|
|
86
|
-
|
|
85
|
+
return response.send(responseBody);
|
|
87
86
|
}
|
|
88
87
|
export { resolveContentNegotiation, writeErrorResponse };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-routing-policy.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatch-routing-policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElG;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAQ3G;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"dispatch-routing-policy.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatch-routing-policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElG;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAQ3G;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAOlH"}
|
|
@@ -21,8 +21,10 @@ export function matchHandlerOrThrow(handlerMapping, request) {
|
|
|
21
21
|
* @param params The params.
|
|
22
22
|
*/
|
|
23
23
|
export function updateRequestParams(requestContext, params) {
|
|
24
|
-
requestContext.request
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
Object.defineProperty(requestContext.request, 'params', {
|
|
25
|
+
configurable: true,
|
|
26
|
+
enumerable: true,
|
|
27
|
+
value: params,
|
|
28
|
+
writable: true
|
|
29
|
+
});
|
|
28
30
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { Container } from '@fluojs/di';
|
|
2
2
|
import type { Binder, ContentNegotiationOptions, ConverterLike, Dispatcher, DispatcherLogger, FrameworkRequest, FrameworkResponse, HandlerMapping, InterceptorLike, MiddlewareLike, RequestObserverLike } from '../types.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { type FastPathStats } from './fast-path/index.js';
|
|
4
|
+
export type { FastPathEligibility, FastPathStats } from './fast-path/index.js';
|
|
5
|
+
export { FAST_PATH_ELIGIBILITY_SYMBOL, FAST_PATH_STATS_SYMBOL } from './fast-path/index.js';
|
|
6
|
+
/** Type definition for a global HTTP error handler function. */
|
|
6
7
|
export type ErrorHandler = (error: unknown, request: FrameworkRequest, response: FrameworkResponse, requestId?: string) => Promise<boolean | void> | boolean | void;
|
|
7
|
-
/**
|
|
8
|
-
* Options for creating an HTTP {@link Dispatcher}.
|
|
9
|
-
*/
|
|
8
|
+
/** Options for creating an HTTP {@link Dispatcher}. */
|
|
10
9
|
export interface CreateDispatcherOptions {
|
|
11
10
|
/** Global middleware applied to all requests. */
|
|
12
11
|
appMiddleware?: MiddlewareLike[];
|
|
@@ -20,6 +19,8 @@ export interface CreateDispatcherOptions {
|
|
|
20
19
|
interceptors?: InterceptorLike[];
|
|
21
20
|
/** Global request observers for telemetry and logging. */
|
|
22
21
|
observers?: RequestObserverLike[];
|
|
22
|
+
/** Emits per-response fast-path debug headers when enabled. */
|
|
23
|
+
fastPathDebugHeaders?: boolean;
|
|
23
24
|
/** Optional global error handler. */
|
|
24
25
|
onError?: ErrorHandler;
|
|
25
26
|
/** Request-scope optimization hints supplied by runtime bootstrap. */
|
|
@@ -27,9 +28,12 @@ export interface CreateDispatcherOptions {
|
|
|
27
28
|
/** Global DTO converters used by the default binder. */
|
|
28
29
|
converterDefinitions?: readonly ConverterLike[];
|
|
29
30
|
};
|
|
31
|
+
/** Logger used for non-fatal dispatcher failures. */
|
|
30
32
|
logger?: DispatcherLogger;
|
|
31
33
|
/** Root DI container for creating request scopes. */
|
|
32
34
|
rootContainer: Container;
|
|
35
|
+
/** Human-readable adapter label included in fast-path observability output. */
|
|
36
|
+
adapter?: string;
|
|
33
37
|
}
|
|
34
38
|
/**
|
|
35
39
|
* Creates an HTTP dispatcher instance for processing requests.
|
|
@@ -38,4 +42,12 @@ export interface CreateDispatcherOptions {
|
|
|
38
42
|
* @returns A {@link Dispatcher} capable of routing {@link FrameworkRequest}s.
|
|
39
43
|
*/
|
|
40
44
|
export declare function createDispatcher(options: CreateDispatcherOptions): Dispatcher;
|
|
45
|
+
/**
|
|
46
|
+
* Reads automatic fast-path eligibility statistics attached to a dispatcher.
|
|
47
|
+
*
|
|
48
|
+
* @param dispatcher Dispatcher returned by {@link createDispatcher}.
|
|
49
|
+
* @returns Fast-path statistics when available.
|
|
50
|
+
*/
|
|
51
|
+
export declare function getDispatcherFastPathStats(dispatcher: Dispatcher): FastPathStats | undefined;
|
|
52
|
+
export { formatFastPathStats } from './fast-path/index.js';
|
|
41
53
|
//# sourceMappingURL=dispatcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAyB,MAAM,YAAY,CAAC;AAQnE,OAAO,KAAK,EACV,MAAM,EACN,yBAAyB,EACzB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EAIjB,cAAc,
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAyB,MAAM,YAAY,CAAC;AAQnE,OAAO,KAAK,EACV,MAAM,EACN,yBAAyB,EACzB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EAIjB,cAAc,EAEd,eAAe,EAEf,cAAc,EAId,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAKL,KAAK,aAAa,EAOnB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE5F,gEAAgE;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;AAEpK,uDAAuD;AACvD,MAAM,WAAW,uBAAuB;IACtC,iDAAiD;IACjD,aAAa,CAAC,EAAE,cAAc,EAAE,CAAC;IACjC,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;IAC/C,sDAAsD;IACtD,cAAc,EAAE,cAAc,CAAC;IAC/B,2DAA2D;IAC3D,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,0DAA0D;IAC1D,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC,+DAA+D;IAC/D,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qCAAqC;IACrC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,sEAAsE;IACtE,YAAY,CAAC,EAAE;QACb,wDAAwD;QACxD,oBAAoB,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;KACjD,CAAC;IACF,qDAAqD;IACrD,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,qDAAqD;IACrD,aAAa,EAAE,SAAS,CAAC;IACzB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAoyBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,UAAU,CAuF7E;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,GAAG,SAAS,CAE5F;AAED,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -8,16 +8,16 @@ import { isMiddlewareRouteConfig, matchRoutePattern, runMiddlewareChain } from '
|
|
|
8
8
|
import { invokeControllerHandler } from './dispatch-handler-policy.js';
|
|
9
9
|
import { resolveContentNegotiation, writeErrorResponse, writeSuccessResponse } from './dispatch-response-policy.js';
|
|
10
10
|
import { matchHandlerOrThrow, updateRequestParams } from './dispatch-routing-policy.js';
|
|
11
|
-
import { readFrameworkRequestNativeRouteHandoff } from './native-route-handoff.js';
|
|
11
|
+
import { attachFrameworkRequestNativeRouteHandoff, readFrameworkRequestNativeRouteHandoff } from './native-route-handoff.js';
|
|
12
|
+
import { compileFastPathEligibility, getHandlerFastPathEligibility, setHandlerFastPathEligibility, FAST_PATH_STATS_SYMBOL, addPathDebugHeader, createFastPathStats, createPathDebugInfo, executeFastPath, shouldUseFastPathForRequest } from './fast-path/index.js';
|
|
13
|
+
export { FAST_PATH_ELIGIBILITY_SYMBOL, FAST_PATH_STATS_SYMBOL } from './fast-path/index.js';
|
|
12
14
|
|
|
13
|
-
/**
|
|
14
|
-
* Type definition for a global HTTP error handler function.
|
|
15
|
-
*/
|
|
15
|
+
/** Type definition for a global HTTP error handler function. */
|
|
16
16
|
|
|
17
|
-
/**
|
|
18
|
-
* Options for creating an HTTP {@link Dispatcher}.
|
|
19
|
-
*/
|
|
17
|
+
/** Options for creating an HTTP {@link Dispatcher}. */
|
|
20
18
|
|
|
19
|
+
const EMPTY_NATIVE_FAST_PATH_HANDLER_EXECUTION_PLANS = new WeakMap();
|
|
20
|
+
const EMPTY_NATIVE_FAST_PATH_OBSERVERS = [];
|
|
21
21
|
function logDispatchFailure(logger, message, error) {
|
|
22
22
|
if (logger) {
|
|
23
23
|
logger.error(message, error, 'HttpDispatcher');
|
|
@@ -26,15 +26,41 @@ function logDispatchFailure(logger, message, error) {
|
|
|
26
26
|
console.error(`[fluo][HttpDispatcher] ${message}`, error);
|
|
27
27
|
}
|
|
28
28
|
function createDispatchRequest(request) {
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
const dispatchRequest = {
|
|
30
|
+
get cookies() {
|
|
31
|
+
return request.cookies;
|
|
32
|
+
},
|
|
33
|
+
get headers() {
|
|
34
|
+
return request.headers;
|
|
35
|
+
},
|
|
36
|
+
get query() {
|
|
37
|
+
return request.query;
|
|
38
|
+
},
|
|
39
|
+
body: request.body,
|
|
40
|
+
method: request.method,
|
|
31
41
|
params: {
|
|
32
42
|
...request.params
|
|
33
|
-
}
|
|
43
|
+
},
|
|
44
|
+
path: request.path,
|
|
45
|
+
raw: request.raw,
|
|
46
|
+
rawBody: request.rawBody,
|
|
47
|
+
requestId: request.requestId,
|
|
48
|
+
signal: request.signal,
|
|
49
|
+
url: request.url
|
|
34
50
|
};
|
|
51
|
+
const nativeRouteHandoff = readFrameworkRequestNativeRouteHandoff(request);
|
|
52
|
+
const files = request.files;
|
|
53
|
+
const principal = request.principal;
|
|
54
|
+
if (files !== undefined) {
|
|
55
|
+
dispatchRequest.files = files;
|
|
56
|
+
}
|
|
57
|
+
if (principal !== undefined) {
|
|
58
|
+
dispatchRequest.principal = principal;
|
|
59
|
+
}
|
|
60
|
+
return nativeRouteHandoff ? attachFrameworkRequestNativeRouteHandoff(dispatchRequest, nativeRouteHandoff) : dispatchRequest;
|
|
35
61
|
}
|
|
36
62
|
function cloneHandlerDescriptor(descriptor) {
|
|
37
|
-
|
|
63
|
+
const cloned = {
|
|
38
64
|
...descriptor,
|
|
39
65
|
metadata: {
|
|
40
66
|
...descriptor.metadata,
|
|
@@ -54,8 +80,16 @@ function cloneHandlerDescriptor(descriptor) {
|
|
|
54
80
|
} : undefined
|
|
55
81
|
}
|
|
56
82
|
};
|
|
83
|
+
const eligibility = getHandlerFastPathEligibility(descriptor);
|
|
84
|
+
if (eligibility) {
|
|
85
|
+
setHandlerFastPathEligibility(cloned, eligibility);
|
|
86
|
+
}
|
|
87
|
+
return cloned;
|
|
57
88
|
}
|
|
58
89
|
function readRequestId(request) {
|
|
90
|
+
if (request.requestId) {
|
|
91
|
+
return request.requestId;
|
|
92
|
+
}
|
|
59
93
|
const raw = request.headers['x-request-id'] ?? request.headers['X-Request-Id'];
|
|
60
94
|
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
61
95
|
const normalized = value?.trim();
|
|
@@ -72,16 +106,53 @@ function createDispatchContext(request, response, container, promoteOnContainerA
|
|
|
72
106
|
if (!promoteOnContainerAccess) {
|
|
73
107
|
return context;
|
|
74
108
|
}
|
|
109
|
+
|
|
110
|
+
// Wrap the container to only promote to request scope when resolve() is actually called.
|
|
111
|
+
// This allows fast-path handlers to check ctx.container without triggering scope creation.
|
|
75
112
|
let activeContainer = container;
|
|
113
|
+
let wrappedContainer;
|
|
114
|
+
let promoted = false;
|
|
115
|
+
const ensurePromoted = () => {
|
|
116
|
+
if (!promoted) {
|
|
117
|
+
activeContainer = promoteOnContainerAccess();
|
|
118
|
+
promoted = true;
|
|
119
|
+
}
|
|
120
|
+
return activeContainer;
|
|
121
|
+
};
|
|
122
|
+
const getWrappedContainer = () => {
|
|
123
|
+
if (!wrappedContainer) {
|
|
124
|
+
wrappedContainer = {
|
|
125
|
+
async resolve(token) {
|
|
126
|
+
const targetContainer = ensurePromoted();
|
|
127
|
+
return targetContainer.resolve(token);
|
|
128
|
+
},
|
|
129
|
+
async dispose() {
|
|
130
|
+
// If promotion never happened, this is a no-op.
|
|
131
|
+
// This prevents accidentally disposing the root container when a
|
|
132
|
+
// captured container reference is used after a singleton-only request.
|
|
133
|
+
if (!promoted) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
return activeContainer.dispose();
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return wrappedContainer;
|
|
141
|
+
};
|
|
76
142
|
Object.defineProperty(context, 'container', {
|
|
77
143
|
configurable: true,
|
|
78
144
|
enumerable: true,
|
|
79
145
|
get() {
|
|
80
|
-
|
|
81
|
-
|
|
146
|
+
// If promotion has already occurred, return the actual container.
|
|
147
|
+
if (promoted) {
|
|
148
|
+
return activeContainer;
|
|
149
|
+
}
|
|
150
|
+
// Return the wrapped container that will promote on resolve().
|
|
151
|
+
return getWrappedContainer();
|
|
82
152
|
},
|
|
83
153
|
set(value) {
|
|
84
154
|
activeContainer = value;
|
|
155
|
+
promoted = true;
|
|
85
156
|
}
|
|
86
157
|
});
|
|
87
158
|
return context;
|
|
@@ -177,10 +248,38 @@ function ensureRequestScope(context) {
|
|
|
177
248
|
context.requestContext.container = context.dispatchScope.container;
|
|
178
249
|
}
|
|
179
250
|
function ensureRequestNotAborted(request) {
|
|
180
|
-
if (request
|
|
251
|
+
if (isRequestAborted(request)) {
|
|
181
252
|
throw new RequestAbortedError();
|
|
182
253
|
}
|
|
183
254
|
}
|
|
255
|
+
function isRequestAborted(request) {
|
|
256
|
+
return request.isAborted?.() ?? request.signal?.aborted === true;
|
|
257
|
+
}
|
|
258
|
+
function resolveFastPathHandlerRuntimeCache(handler, cache) {
|
|
259
|
+
const cached = cache.get(handler);
|
|
260
|
+
if (cached) {
|
|
261
|
+
return cached;
|
|
262
|
+
}
|
|
263
|
+
const method = handler.controllerToken.prototype[handler.methodName];
|
|
264
|
+
const compiled = {
|
|
265
|
+
method: typeof method === 'function' ? method : undefined
|
|
266
|
+
};
|
|
267
|
+
cache.set(handler, compiled);
|
|
268
|
+
return compiled;
|
|
269
|
+
}
|
|
270
|
+
function resolveFastPathController(handler, controllerContainer, runtimeCache) {
|
|
271
|
+
if (runtimeCache.controller) {
|
|
272
|
+
return runtimeCache.controller;
|
|
273
|
+
}
|
|
274
|
+
runtimeCache.controllerPromise ??= controllerContainer.resolve(handler.controllerToken).then(controller => {
|
|
275
|
+
runtimeCache.controller = controller;
|
|
276
|
+
return controller;
|
|
277
|
+
});
|
|
278
|
+
return runtimeCache.controllerPromise;
|
|
279
|
+
}
|
|
280
|
+
function isPromiseLike(value) {
|
|
281
|
+
return typeof value === 'object' && value !== null && 'then' in value && typeof value.then === 'function';
|
|
282
|
+
}
|
|
184
283
|
function isRequestObserver(value) {
|
|
185
284
|
return typeof value === 'object' && value !== null;
|
|
186
285
|
}
|
|
@@ -252,6 +351,59 @@ function resolveHandlerExecutionPlan(handler, executionPlans, options) {
|
|
|
252
351
|
executionPlans.set(handler, compiled);
|
|
253
352
|
return compiled;
|
|
254
353
|
}
|
|
354
|
+
async function dispatchNativeFastRoute(match, request, response, options, contentNegotiation, fastPathRuntimeCache) {
|
|
355
|
+
const eligibility = getHandlerFastPathEligibility(match.descriptor);
|
|
356
|
+
if (!shouldUseFastPathForRequest(eligibility, request)) {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
const dispatchRequest = request;
|
|
360
|
+
const dispatchScope = createRootDispatchScope(options.rootContainer);
|
|
361
|
+
let phaseContext;
|
|
362
|
+
let containerPromotionOpen = true;
|
|
363
|
+
const requestContext = createDispatchContext(dispatchRequest, response, dispatchScope.container, () => {
|
|
364
|
+
if (!containerPromotionOpen) {
|
|
365
|
+
return phaseContext.dispatchScope.container;
|
|
366
|
+
}
|
|
367
|
+
ensureRequestScope(phaseContext);
|
|
368
|
+
return phaseContext.dispatchScope.container;
|
|
369
|
+
});
|
|
370
|
+
phaseContext = {
|
|
371
|
+
contentNegotiation,
|
|
372
|
+
dispatchScope,
|
|
373
|
+
fastPathRuntimeCache,
|
|
374
|
+
handlerExecutionPlans: EMPTY_NATIVE_FAST_PATH_HANDLER_EXECUTION_PLANS,
|
|
375
|
+
observers: EMPTY_NATIVE_FAST_PATH_OBSERVERS,
|
|
376
|
+
options,
|
|
377
|
+
requestContext,
|
|
378
|
+
response
|
|
379
|
+
};
|
|
380
|
+
phaseContext.matchedHandler = match.descriptor;
|
|
381
|
+
updateRequestParams(phaseContext.requestContext, match.params);
|
|
382
|
+
await runWithRequestContext(phaseContext.requestContext, async () => {
|
|
383
|
+
try {
|
|
384
|
+
ensureRequestNotAborted(phaseContext.requestContext.request);
|
|
385
|
+
const fastPathSuccess = await tryFastPathExecution(match.descriptor, phaseContext);
|
|
386
|
+
if (!fastPathSuccess) {
|
|
387
|
+
throw new Error(`Native route ${match.descriptor.route.method}:${match.descriptor.route.path} was not fast-path executable.`);
|
|
388
|
+
}
|
|
389
|
+
} catch (error) {
|
|
390
|
+
await handleDispatchError(phaseContext, error);
|
|
391
|
+
} finally {
|
|
392
|
+
if (!phaseContext.dispatchScope.requestScoped) {
|
|
393
|
+
phaseContext.requestContext.container = phaseContext.dispatchScope.container;
|
|
394
|
+
}
|
|
395
|
+
containerPromotionOpen = false;
|
|
396
|
+
if (phaseContext.dispatchScope.requestScoped) {
|
|
397
|
+
try {
|
|
398
|
+
await phaseContext.dispatchScope.container.dispose();
|
|
399
|
+
} catch (error) {
|
|
400
|
+
logDispatchFailure(options.logger, 'Request-scoped container dispose threw an error.', error);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
255
407
|
async function notifyRequestStart(context) {
|
|
256
408
|
await notifyObserversSafely(context.observers, context.requestContext, async (observer, observationContext) => {
|
|
257
409
|
await observer.onRequestStart?.(observationContext);
|
|
@@ -272,6 +424,36 @@ async function notifyRequestFinish(context) {
|
|
|
272
424
|
await observer.onRequestFinish?.(observationContext);
|
|
273
425
|
}, context.options.logger, context.matchedHandler);
|
|
274
426
|
}
|
|
427
|
+
async function tryFastPathExecution(handler, context) {
|
|
428
|
+
const eligibility = getHandlerFastPathEligibility(handler);
|
|
429
|
+
if (!eligibility || eligibility.executionPath !== 'fast') {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
if (typeof context.dispatchScope.container.resolve !== 'function') {
|
|
433
|
+
ensureRequestScope(context);
|
|
434
|
+
}
|
|
435
|
+
const runtimeCache = resolveFastPathHandlerRuntimeCache(handler, context.fastPathRuntimeCache);
|
|
436
|
+
const controllerOrPromise = resolveFastPathController(handler, context.dispatchScope.container, runtimeCache);
|
|
437
|
+
const controller = isPromiseLike(controllerOrPromise) ? await controllerOrPromise : controllerOrPromise;
|
|
438
|
+
const fastPathResult = await executeFastPath({
|
|
439
|
+
binder: context.options.binder,
|
|
440
|
+
contentNegotiation: context.contentNegotiation,
|
|
441
|
+
controller,
|
|
442
|
+
controllerContainer: context.dispatchScope.container,
|
|
443
|
+
handler,
|
|
444
|
+
method: runtimeCache.method,
|
|
445
|
+
request: context.requestContext.request,
|
|
446
|
+
requestContext: context.requestContext,
|
|
447
|
+
response: context.response
|
|
448
|
+
});
|
|
449
|
+
if (fastPathResult.executed) {
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
if (fastPathResult.error) {
|
|
453
|
+
throw fastPathResult.error;
|
|
454
|
+
}
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
275
457
|
async function runDispatchPipeline(context) {
|
|
276
458
|
ensureRequestNotAborted(context.requestContext.request);
|
|
277
459
|
const appMiddlewareContext = {
|
|
@@ -279,17 +461,28 @@ async function runDispatchPipeline(context) {
|
|
|
279
461
|
requestContext: context.requestContext,
|
|
280
462
|
response: context.response
|
|
281
463
|
};
|
|
282
|
-
|
|
464
|
+
const dispatchMatchedRoute = async () => {
|
|
283
465
|
if (context.response.committed) {
|
|
284
466
|
return;
|
|
285
467
|
}
|
|
286
468
|
const match = readFrameworkRequestNativeRouteHandoff(appMiddlewareContext.request) ?? matchHandlerOrThrow(context.options.handlerMapping, appMiddlewareContext.request);
|
|
287
469
|
context.matchedHandler = match.descriptor;
|
|
470
|
+
updateRequestParams(context.requestContext, match.params);
|
|
471
|
+
const eligibility = getHandlerFastPathEligibility(match.descriptor);
|
|
472
|
+
if (context.options.fastPathDebugHeaders === true && eligibility && !context.response.committed) {
|
|
473
|
+
const debugInfo = createPathDebugInfo(eligibility);
|
|
474
|
+
addPathDebugHeader(context.response.setHeader.bind(context.response), debugInfo);
|
|
475
|
+
}
|
|
476
|
+
if (shouldUseFastPathForRequest(eligibility, appMiddlewareContext.request)) {
|
|
477
|
+
const fastPathSuccess = await tryFastPathExecution(match.descriptor, context);
|
|
478
|
+
if (fastPathSuccess) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
288
482
|
const executionPlan = resolveHandlerExecutionPlan(match.descriptor, context.handlerExecutionPlans, context.options);
|
|
289
483
|
if (handlerMayRequireRequestScope(executionPlan, appMiddlewareContext.request)) {
|
|
290
484
|
ensureRequestScope(context);
|
|
291
485
|
}
|
|
292
|
-
updateRequestParams(context.requestContext, match.params);
|
|
293
486
|
await notifyHandlerMatched(context, match.descriptor);
|
|
294
487
|
const moduleMiddlewareContext = {
|
|
295
488
|
request: context.requestContext.request,
|
|
@@ -299,10 +492,16 @@ async function runDispatchPipeline(context) {
|
|
|
299
492
|
await runMiddlewareChain(match.descriptor.metadata.moduleMiddleware ?? [], moduleMiddlewareContext, async () => {
|
|
300
493
|
await dispatchMatchedHandler(match.descriptor, executionPlan, context.requestContext, context.dispatchScope.container, context.observers, context.contentNegotiation, context.options.binder, context.options.logger);
|
|
301
494
|
});
|
|
302
|
-
}
|
|
495
|
+
};
|
|
496
|
+
const appMiddleware = context.options.appMiddleware ?? [];
|
|
497
|
+
if (appMiddleware.length === 0) {
|
|
498
|
+
await dispatchMatchedRoute();
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
await runMiddlewareChain(appMiddleware, appMiddlewareContext, dispatchMatchedRoute);
|
|
303
502
|
}
|
|
304
503
|
async function handleDispatchError(context, error) {
|
|
305
|
-
if (error instanceof RequestAbortedError || context.requestContext.request
|
|
504
|
+
if (error instanceof RequestAbortedError || isRequestAborted(context.requestContext.request)) {
|
|
306
505
|
return;
|
|
307
506
|
}
|
|
308
507
|
await notifyRequestError(context, error);
|
|
@@ -324,14 +523,26 @@ export function createDispatcher(options) {
|
|
|
324
523
|
const observers = options.observers ?? [];
|
|
325
524
|
const appMiddleware = options.appMiddleware ?? [];
|
|
326
525
|
const dispatchStartPlan = compileDispatchStartPlan(observers, appMiddleware);
|
|
526
|
+
const fastPathRuntimeCache = new WeakMap();
|
|
327
527
|
const handlerExecutionPlans = new WeakMap();
|
|
528
|
+
const adapter = options.adapter ?? 'default';
|
|
529
|
+
const fastPathEligibilities = [];
|
|
328
530
|
for (const descriptor of options.handlerMapping.descriptors) {
|
|
329
531
|
handlerExecutionPlans.set(descriptor, compileHandlerExecutionPlan(descriptor, options));
|
|
532
|
+
const {
|
|
533
|
+
eligibility
|
|
534
|
+
} = compileFastPathEligibility(descriptor, options, adapter);
|
|
535
|
+
setHandlerFastPathEligibility(descriptor, eligibility);
|
|
536
|
+
fastPathEligibilities.push(eligibility);
|
|
330
537
|
}
|
|
538
|
+
const fastPathStats = createFastPathStats(fastPathEligibilities);
|
|
331
539
|
const dispatcher = {
|
|
332
540
|
describeRoutes() {
|
|
333
541
|
return options.handlerMapping.descriptors.map(descriptor => cloneHandlerDescriptor(descriptor));
|
|
334
542
|
},
|
|
543
|
+
async dispatchNativeRoute(match, request, response) {
|
|
544
|
+
return dispatchNativeFastRoute(match, request, response, options, contentNegotiation, fastPathRuntimeCache);
|
|
545
|
+
},
|
|
335
546
|
async dispatch(request, response) {
|
|
336
547
|
const dispatchRequest = createDispatchRequest(request);
|
|
337
548
|
const dispatchScope = dispatchStartMayRequireRequestScope(dispatchStartPlan, dispatchRequest) ? createRequestDispatchScope(options.rootContainer) : createRootDispatchScope(options.rootContainer);
|
|
@@ -347,6 +558,7 @@ export function createDispatcher(options) {
|
|
|
347
558
|
phaseContext = {
|
|
348
559
|
contentNegotiation,
|
|
349
560
|
dispatchScope,
|
|
561
|
+
fastPathRuntimeCache,
|
|
350
562
|
handlerExecutionPlans,
|
|
351
563
|
observers,
|
|
352
564
|
options,
|
|
@@ -355,12 +567,19 @@ export function createDispatcher(options) {
|
|
|
355
567
|
};
|
|
356
568
|
await runWithRequestContext(phaseContext.requestContext, async () => {
|
|
357
569
|
try {
|
|
358
|
-
|
|
570
|
+
if (observers.length > 0) {
|
|
571
|
+
await notifyRequestStart(phaseContext);
|
|
572
|
+
}
|
|
359
573
|
await runDispatchPipeline(phaseContext);
|
|
360
574
|
} catch (error) {
|
|
361
575
|
await handleDispatchError(phaseContext, error);
|
|
362
576
|
} finally {
|
|
363
|
-
|
|
577
|
+
if (observers.length > 0) {
|
|
578
|
+
await notifyRequestFinish(phaseContext);
|
|
579
|
+
}
|
|
580
|
+
if (!phaseContext.dispatchScope.requestScoped) {
|
|
581
|
+
phaseContext.requestContext.container = phaseContext.dispatchScope.container;
|
|
582
|
+
}
|
|
364
583
|
containerPromotionOpen = false;
|
|
365
584
|
if (phaseContext.dispatchScope.requestScoped) {
|
|
366
585
|
try {
|
|
@@ -373,5 +592,17 @@ export function createDispatcher(options) {
|
|
|
373
592
|
});
|
|
374
593
|
}
|
|
375
594
|
};
|
|
595
|
+
dispatcher[FAST_PATH_STATS_SYMBOL] = fastPathStats;
|
|
376
596
|
return dispatcher;
|
|
377
|
-
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Reads automatic fast-path eligibility statistics attached to a dispatcher.
|
|
601
|
+
*
|
|
602
|
+
* @param dispatcher Dispatcher returned by {@link createDispatcher}.
|
|
603
|
+
* @returns Fast-path statistics when available.
|
|
604
|
+
*/
|
|
605
|
+
export function getDispatcherFastPathStats(dispatcher) {
|
|
606
|
+
return dispatcher[FAST_PATH_STATS_SYMBOL];
|
|
607
|
+
}
|
|
608
|
+
export { formatFastPathStats } from './fast-path/index.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FastPathEligibility, FastPathStats } from './eligibility.js';
|
|
2
|
+
interface PathDebugInfo {
|
|
3
|
+
executionPath: 'fast' | 'full';
|
|
4
|
+
fallbackReason?: string;
|
|
5
|
+
routeId: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function createPathDebugInfo(eligibility: FastPathEligibility): PathDebugInfo;
|
|
8
|
+
export declare function addPathDebugHeader(setHeader: (name: string, value: string) => void, info: PathDebugInfo): void;
|
|
9
|
+
export declare function createFastPathStats(eligibilities: readonly FastPathEligibility[]): FastPathStats;
|
|
10
|
+
/**
|
|
11
|
+
* Formats dispatcher fast-path statistics for debug logs and benchmark output.
|
|
12
|
+
*
|
|
13
|
+
* @param stats Fast-path statistics returned by {@link getDispatcherFastPathStats}.
|
|
14
|
+
* @returns A human-readable route breakdown.
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatFastPathStats(stats: FastPathStats): string;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=debug-visibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-visibility.d.ts","sourceRoot":"","sources":["../../../src/dispatch/fast-path/debug-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAI3E,UAAU,aAAa;IACrB,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,mBAAmB,GAAG,aAAa,CAMnF;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,EAChD,IAAI,EAAE,aAAa,GAClB,IAAI,CAMN;AAED,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,SAAS,mBAAmB,EAAE,GAAG,aAAa,CAShG;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAuBhE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const DEBUG_HEADER_NAME = 'X-Fluo-Path';
|
|
2
|
+
export function createPathDebugInfo(eligibility) {
|
|
3
|
+
return {
|
|
4
|
+
executionPath: eligibility.executionPath,
|
|
5
|
+
fallbackReason: eligibility.fallbackReason,
|
|
6
|
+
routeId: eligibility.routeId
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function addPathDebugHeader(setHeader, info) {
|
|
10
|
+
const value = info.executionPath === 'fast' ? `fast; route=${info.routeId}` : `full; route=${info.routeId}; reason=${info.fallbackReason ?? 'none'}`;
|
|
11
|
+
setHeader(DEBUG_HEADER_NAME, value);
|
|
12
|
+
}
|
|
13
|
+
export function createFastPathStats(eligibilities) {
|
|
14
|
+
const fastPathRoutes = eligibilities.filter(e => e.executionPath === 'fast').length;
|
|
15
|
+
return {
|
|
16
|
+
fastPathRoutes,
|
|
17
|
+
fullPathRoutes: eligibilities.length - fastPathRoutes,
|
|
18
|
+
routes: eligibilities,
|
|
19
|
+
totalRoutes: eligibilities.length
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Formats dispatcher fast-path statistics for debug logs and benchmark output.
|
|
25
|
+
*
|
|
26
|
+
* @param stats Fast-path statistics returned by {@link getDispatcherFastPathStats}.
|
|
27
|
+
* @returns A human-readable route breakdown.
|
|
28
|
+
*/
|
|
29
|
+
export function formatFastPathStats(stats) {
|
|
30
|
+
const fastPathPercent = stats.totalRoutes === 0 ? '0.0' : (stats.fastPathRoutes / stats.totalRoutes * 100).toFixed(1);
|
|
31
|
+
const fullPathPercent = stats.totalRoutes === 0 ? '0.0' : (stats.fullPathRoutes / stats.totalRoutes * 100).toFixed(1);
|
|
32
|
+
const lines = ['=== Fast Path Statistics ===', `Total routes: ${String(stats.totalRoutes)}`, `Fast path: ${String(stats.fastPathRoutes)} (${fastPathPercent}%)`, `Full path: ${String(stats.fullPathRoutes)} (${fullPathPercent}%)`, '', 'Route breakdown:'];
|
|
33
|
+
for (const route of stats.routes) {
|
|
34
|
+
const status = route.executionPath === 'fast' ? 'FAST' : 'FULL';
|
|
35
|
+
const reason = route.fallbackReason ? ` (${route.fallbackReason})` : '';
|
|
36
|
+
lines.push(` [${status}] ${route.routeId}${reason}`);
|
|
37
|
+
}
|
|
38
|
+
return lines.join('\n');
|
|
39
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Container } from '@fluojs/di';
|
|
2
|
+
import type { Binder, HandlerDescriptor } from '../../types.js';
|
|
3
|
+
import type { CreateDispatcherOptions } from '../dispatcher.js';
|
|
4
|
+
import { type FastPathEligibility } from './eligibility.js';
|
|
5
|
+
interface CompiledEligibilityPlan {
|
|
6
|
+
eligibility: FastPathEligibility;
|
|
7
|
+
isEligible: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function compileFastPathEligibility(handler: HandlerDescriptor, options: CreateDispatcherOptions, adapter: string): CompiledEligibilityPlan;
|
|
10
|
+
export declare function getHandlerFastPathEligibility(handler: HandlerDescriptor): FastPathEligibility | undefined;
|
|
11
|
+
export declare function setHandlerFastPathEligibility(handler: HandlerDescriptor, eligibility: FastPathEligibility): void;
|
|
12
|
+
export interface FastPathExecutorOptions {
|
|
13
|
+
binder?: Binder;
|
|
14
|
+
rootContainer: Container;
|
|
15
|
+
}
|
|
16
|
+
export interface FastPathExecutionResult {
|
|
17
|
+
executed: boolean;
|
|
18
|
+
result?: unknown;
|
|
19
|
+
error?: unknown;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=eligibility-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eligibility-checker.d.ts","sourceRoot":"","sources":["../../../src/dispatch/fast-path/eligibility-checker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,KAAK,EACV,MAAM,EACN,iBAAiB,EAElB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,KAAK,mBAAmB,EAAgC,MAAM,kBAAkB,CAAC;AAM1F,UAAU,uBAAuB;IAC/B,WAAW,EAAE,mBAAmB,CAAC;IACjC,UAAU,EAAE,OAAO,CAAC;CACrB;AA0DD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE,MAAM,GACd,uBAAuB,CAgEzB;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,iBAAiB,GACzB,mBAAmB,GAAG,SAAS,CAIjC;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,iBAAiB,EAC1B,WAAW,EAAE,mBAAmB,GAC/B,IAAI,CAGN;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { getCompiledDtoBindingPlan } from '../../adapters/dto-binding-plan.js';
|
|
2
|
+
import { FAST_PATH_ELIGIBILITY_SYMBOL } from './eligibility.js';
|
|
3
|
+
function hasRequestScopeInspector(container) {
|
|
4
|
+
return typeof container === 'object' && container !== null && 'hasRequestScopedDependency' in container && typeof container.hasRequestScopedDependency === 'function';
|
|
5
|
+
}
|
|
6
|
+
function requestDtoMayRequireRequestScope(handler, options) {
|
|
7
|
+
if (!handler.route.request) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
if ((options.requestScope?.converterDefinitions ?? []).length > 0) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
if (options.binder) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
const plan = getCompiledDtoBindingPlan(handler.route.request);
|
|
17
|
+
return plan.entries.some(entry => entry.converter !== undefined);
|
|
18
|
+
}
|
|
19
|
+
function determineRequestScopeRequirement(handler, options) {
|
|
20
|
+
if (handler.route.guards && handler.route.guards.length > 0) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
if (handler.route.interceptors && handler.route.interceptors.length > 0) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
if (handler.metadata.moduleMiddleware && handler.metadata.moduleMiddleware.length > 0) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
if (requestDtoMayRequireRequestScope(handler, options)) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
if (hasRequestScopeInspector(options.rootContainer)) {
|
|
33
|
+
return options.rootContainer.hasRequestScopedDependency(handler.controllerToken);
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
function determineMiddlewareRequirement(handler, appMiddleware) {
|
|
38
|
+
if (appMiddleware.length > 0) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
const moduleMiddleware = handler.metadata.moduleMiddleware;
|
|
42
|
+
return moduleMiddleware !== undefined && moduleMiddleware.length > 0;
|
|
43
|
+
}
|
|
44
|
+
export function compileFastPathEligibility(handler, options, adapter) {
|
|
45
|
+
const routeId = `${handler.route.method}:${handler.route.path}`;
|
|
46
|
+
const hasGuard = (handler.route.guards?.length ?? 0) > 0;
|
|
47
|
+
const hasInterceptor = (handler.route.interceptors?.length ?? 0) > 0 || (options.interceptors?.length ?? 0) > 0;
|
|
48
|
+
const hasPipe = handler.route.request !== undefined;
|
|
49
|
+
const hasRequestScopedDI = determineRequestScopeRequirement(handler, options);
|
|
50
|
+
const hasMiddleware = determineMiddlewareRequirement(handler, options.appMiddleware ?? []);
|
|
51
|
+
const hasContentNegotiation = options.contentNegotiation?.formatters !== undefined && options.contentNegotiation.formatters.length > 0;
|
|
52
|
+
const eligibility = {
|
|
53
|
+
adapter,
|
|
54
|
+
executionPath: 'full',
|
|
55
|
+
hasAdapterPluginInfluence: false,
|
|
56
|
+
hasCustomBodyParser: options.binder !== undefined,
|
|
57
|
+
hasCustomErrorFilter: options.onError !== undefined,
|
|
58
|
+
hasGlobalHook: (options.observers?.length ?? 0) > 0,
|
|
59
|
+
hasGuard,
|
|
60
|
+
hasInterceptor,
|
|
61
|
+
hasMiddleware,
|
|
62
|
+
hasPipe,
|
|
63
|
+
hasRequestScopedDI,
|
|
64
|
+
routeId
|
|
65
|
+
};
|
|
66
|
+
const blockingReasons = [];
|
|
67
|
+
if (eligibility.hasGuard) {
|
|
68
|
+
blockingReasons.push('guards');
|
|
69
|
+
}
|
|
70
|
+
if (eligibility.hasInterceptor) {
|
|
71
|
+
blockingReasons.push('interceptors');
|
|
72
|
+
}
|
|
73
|
+
if (eligibility.hasPipe) {
|
|
74
|
+
blockingReasons.push('pipes/DTO binding');
|
|
75
|
+
}
|
|
76
|
+
if (eligibility.hasRequestScopedDI) {
|
|
77
|
+
blockingReasons.push('request-scoped DI');
|
|
78
|
+
}
|
|
79
|
+
if (eligibility.hasMiddleware) {
|
|
80
|
+
blockingReasons.push('middleware');
|
|
81
|
+
}
|
|
82
|
+
if (eligibility.hasGlobalHook) {
|
|
83
|
+
blockingReasons.push('request observers');
|
|
84
|
+
}
|
|
85
|
+
if (eligibility.hasCustomErrorFilter) {
|
|
86
|
+
blockingReasons.push('custom error filter');
|
|
87
|
+
}
|
|
88
|
+
if (eligibility.hasCustomBodyParser) {
|
|
89
|
+
blockingReasons.push('custom binder');
|
|
90
|
+
}
|
|
91
|
+
if (hasContentNegotiation) {
|
|
92
|
+
blockingReasons.push('content negotiation');
|
|
93
|
+
}
|
|
94
|
+
const isEligible = blockingReasons.length === 0;
|
|
95
|
+
if (!isEligible) {
|
|
96
|
+
eligibility.fallbackReason = `Full path required due to: ${blockingReasons.join(', ')}`;
|
|
97
|
+
} else {
|
|
98
|
+
eligibility.executionPath = 'fast';
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
eligibility,
|
|
102
|
+
isEligible
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export function getHandlerFastPathEligibility(handler) {
|
|
106
|
+
return handler[FAST_PATH_ELIGIBILITY_SYMBOL];
|
|
107
|
+
}
|
|
108
|
+
export function setHandlerFastPathEligibility(handler, eligibility) {
|
|
109
|
+
handler[FAST_PATH_ELIGIBILITY_SYMBOL] = eligibility;
|
|
110
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-route capability model used to decide whether a route can safely bypass
|
|
3
|
+
* optional framework overhead and execute through the fast path.
|
|
4
|
+
*
|
|
5
|
+
* Fast path selection is automatic and conservative: if safety cannot be proven,
|
|
6
|
+
* the route uses the full path with all framework features enabled.
|
|
7
|
+
*/
|
|
8
|
+
export interface FastPathEligibility {
|
|
9
|
+
/** Stable identifier for the route being analyzed. */
|
|
10
|
+
readonly routeId: string;
|
|
11
|
+
/** Active runtime adapter such as Fastify or Bun. */
|
|
12
|
+
readonly adapter: string;
|
|
13
|
+
/** Benchmark or runtime scenario associated with the route. */
|
|
14
|
+
readonly scenario?: string;
|
|
15
|
+
/** Whether a global hook may affect route execution. */
|
|
16
|
+
readonly hasGlobalHook: boolean;
|
|
17
|
+
/** Whether middleware applies to the route. */
|
|
18
|
+
readonly hasMiddleware: boolean;
|
|
19
|
+
/** Whether guard logic applies to the route. */
|
|
20
|
+
readonly hasGuard: boolean;
|
|
21
|
+
/** Whether pipe or validation logic applies to the route. */
|
|
22
|
+
readonly hasPipe: boolean;
|
|
23
|
+
/** Whether interceptor logic applies to the route. */
|
|
24
|
+
readonly hasInterceptor: boolean;
|
|
25
|
+
/** Whether request-scoped dependency resolution is needed. */
|
|
26
|
+
readonly hasRequestScopedDI: boolean;
|
|
27
|
+
/** Whether body parsing behavior has been customized. */
|
|
28
|
+
readonly hasCustomBodyParser: boolean;
|
|
29
|
+
/** Whether a custom exception filter applies. */
|
|
30
|
+
readonly hasCustomErrorFilter: boolean;
|
|
31
|
+
/** Whether adapter-level plugin behavior may affect execution. */
|
|
32
|
+
readonly hasAdapterPluginInfluence: boolean;
|
|
33
|
+
/** Resolved execution path, either 'fast' or 'full'. */
|
|
34
|
+
executionPath: 'fast' | 'full';
|
|
35
|
+
/** Explanation for full-path fallback when fast path is not selected. */
|
|
36
|
+
fallbackReason?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Statistics collected about fast path decisions for observability.
|
|
40
|
+
*/
|
|
41
|
+
export interface FastPathStats {
|
|
42
|
+
/** Total number of routes analyzed. */
|
|
43
|
+
totalRoutes: number;
|
|
44
|
+
/** Number of routes eligible for fast path. */
|
|
45
|
+
fastPathRoutes: number;
|
|
46
|
+
/** Number of routes using full path. */
|
|
47
|
+
fullPathRoutes: number;
|
|
48
|
+
/** Per-route eligibility details. */
|
|
49
|
+
routes: ReadonlyArray<Readonly<FastPathEligibility>>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Symbol used to attach fast path eligibility metadata to handler descriptors.
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
export declare const FAST_PATH_ELIGIBILITY_SYMBOL: unique symbol;
|
|
56
|
+
/**
|
|
57
|
+
* Symbol used to attach fast path execution stats to dispatcher.
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
export declare const FAST_PATH_STATS_SYMBOL: unique symbol;
|
|
61
|
+
//# sourceMappingURL=eligibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eligibility.d.ts","sourceRoot":"","sources":["../../../src/dispatch/fast-path/eligibility.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,qDAAqD;IACrD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,wDAAwD;IACxD,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAEhC,+CAA+C;IAC/C,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAEhC,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,sDAAsD;IACtD,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IAEjC,8DAA8D;IAC9D,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IAErC,yDAAyD;IACzD,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IAEtC,iDAAiD;IACjD,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IAEvC,kEAAkE;IAClE,QAAQ,CAAC,yBAAyB,EAAE,OAAO,CAAC;IAE5C,wDAAwD;IACxD,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IAE/B,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IAEpB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAC;IAEvB,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;IAEvB,qCAAqC;IACrC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC;CACtD;AAED;;;GAGG;AACH,eAAO,MAAM,4BAA4B,eAAgC,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,sBAAsB,eAA0B,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-route capability model used to decide whether a route can safely bypass
|
|
3
|
+
* optional framework overhead and execute through the fast path.
|
|
4
|
+
*
|
|
5
|
+
* Fast path selection is automatic and conservative: if safety cannot be proven,
|
|
6
|
+
* the route uses the full path with all framework features enabled.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Statistics collected about fast path decisions for observability.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Symbol used to attach fast path eligibility metadata to handler descriptors.
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export const FAST_PATH_ELIGIBILITY_SYMBOL = Symbol('fastPathEligibility');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Symbol used to attach fast path execution stats to dispatcher.
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export const FAST_PATH_STATS_SYMBOL = Symbol('fastPathStats');
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { RequestScopeContainer } from '@fluojs/di';
|
|
2
|
+
import { type ResolvedContentNegotiation } from '../dispatch-response-policy.js';
|
|
3
|
+
import type { Binder, FrameworkRequest, FrameworkResponse, HandlerDescriptor, RequestContext } from '../../types.js';
|
|
4
|
+
import type { FastPathExecutionResult } from './eligibility-checker.js';
|
|
5
|
+
interface ExecuteFastPathOptions {
|
|
6
|
+
binder?: Binder;
|
|
7
|
+
contentNegotiation?: ResolvedContentNegotiation;
|
|
8
|
+
controllerContainer: RequestScopeContainer;
|
|
9
|
+
controller?: object;
|
|
10
|
+
handler: HandlerDescriptor;
|
|
11
|
+
method?: (this: object, input: unknown, requestContext: RequestContext) => unknown;
|
|
12
|
+
request: FrameworkRequest;
|
|
13
|
+
requestContext: RequestContext;
|
|
14
|
+
response: FrameworkResponse;
|
|
15
|
+
}
|
|
16
|
+
export declare function executeFastPath(options: ExecuteFastPathOptions): Promise<FastPathExecutionResult>;
|
|
17
|
+
export declare function shouldUseFastPathForRequest(eligibility: {
|
|
18
|
+
executionPath: 'fast' | 'full';
|
|
19
|
+
} | undefined, request: FrameworkRequest): boolean;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=fast-path-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fast-path-executor.d.ts","sourceRoot":"","sources":["../../../src/dispatch/fast-path/fast-path-executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAOxD,OAAO,EAAE,KAAK,0BAA0B,EAAwB,MAAM,gCAAgC,CAAC;AACvG,OAAO,KAAK,EACV,MAAM,EACN,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AASxE,UAAU,sBAAsB;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,0BAA0B,CAAC;IAChD,mBAAmB,EAAE,qBAAqB,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,KAAK,OAAO,CAAC;IACnF,OAAO,EAAE,gBAAgB,CAAC;IAC1B,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,uBAAuB,CAAC,CAoDlC;AASD,wBAAgB,2BAA2B,CACzC,WAAW,EAAE;IAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,SAAS,EAC3D,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAWT"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { DefaultBinder } from '../../adapters/binding.js';
|
|
2
|
+
import { getCompiledDtoBindingPlan } from '../../adapters/dto-binding-plan.js';
|
|
3
|
+
import { HttpDtoValidationAdapter } from '../../adapters/dto-validation-adapter.js';
|
|
4
|
+
import { SseResponse } from '../../context/sse.js';
|
|
5
|
+
import { RequestAbortedError } from '../../errors.js';
|
|
6
|
+
import { writeSuccessResponse } from '../dispatch-response-policy.js';
|
|
7
|
+
const defaultBinder = new DefaultBinder();
|
|
8
|
+
const defaultValidator = new HttpDtoValidationAdapter();
|
|
9
|
+
export async function executeFastPath(options) {
|
|
10
|
+
const {
|
|
11
|
+
binder,
|
|
12
|
+
contentNegotiation,
|
|
13
|
+
controllerContainer,
|
|
14
|
+
handler,
|
|
15
|
+
request,
|
|
16
|
+
requestContext,
|
|
17
|
+
response
|
|
18
|
+
} = options;
|
|
19
|
+
try {
|
|
20
|
+
const controller = options.controller ?? (await controllerContainer.resolve(handler.controllerToken));
|
|
21
|
+
const method = options.method ?? controller[handler.methodName];
|
|
22
|
+
if (typeof method !== 'function') {
|
|
23
|
+
return {
|
|
24
|
+
error: new Error(`Controller ${handler.controllerToken.name} does not expose handler method ${handler.methodName}.`),
|
|
25
|
+
executed: false
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const requestDto = handler.route.request;
|
|
29
|
+
let input;
|
|
30
|
+
if (requestDto) {
|
|
31
|
+
const bindingPlan = getCompiledDtoBindingPlan(requestDto);
|
|
32
|
+
const activeBinder = binder ?? defaultBinder;
|
|
33
|
+
input = await activeBinder.bind(requestDto, {
|
|
34
|
+
handler,
|
|
35
|
+
requestContext
|
|
36
|
+
});
|
|
37
|
+
if (bindingPlan.needsValidation) {
|
|
38
|
+
await defaultValidator.validate(input, requestDto);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const maybeResult = method.call(controller, input, requestContext);
|
|
42
|
+
const result = isThenable(maybeResult) ? await maybeResult : maybeResult;
|
|
43
|
+
if (isRequestAborted(request)) {
|
|
44
|
+
throw new RequestAbortedError();
|
|
45
|
+
}
|
|
46
|
+
if (!(result instanceof SseResponse) && !response.committed) {
|
|
47
|
+
const writeResult = writeSuccessResponse(handler, request, response, result, contentNegotiation);
|
|
48
|
+
if (isThenable(writeResult)) {
|
|
49
|
+
await writeResult;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
executed: true,
|
|
54
|
+
result
|
|
55
|
+
};
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return {
|
|
58
|
+
error,
|
|
59
|
+
executed: false
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function isThenable(value) {
|
|
64
|
+
return typeof value === 'object' && value !== null && 'then' in value && typeof value.then === 'function';
|
|
65
|
+
}
|
|
66
|
+
export function shouldUseFastPathForRequest(eligibility, request) {
|
|
67
|
+
if (!eligibility) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
if (eligibility.executionPath !== 'fast') {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (isRequestAborted(request)) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
function isRequestAborted(request) {
|
|
79
|
+
return request.isAborted?.() ?? request.signal?.aborted === true;
|
|
80
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { FastPathEligibility, FastPathStats } from './eligibility.js';
|
|
2
|
+
export { FAST_PATH_ELIGIBILITY_SYMBOL, FAST_PATH_STATS_SYMBOL } from './eligibility.js';
|
|
3
|
+
export { compileFastPathEligibility, getHandlerFastPathEligibility, setHandlerFastPathEligibility, type FastPathExecutionResult, } from './eligibility-checker.js';
|
|
4
|
+
export { executeFastPath, shouldUseFastPathForRequest } from './fast-path-executor.js';
|
|
5
|
+
export { addPathDebugHeader, createFastPathStats, createPathDebugInfo, formatFastPathStats, } from './debug-visibility.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dispatch/fast-path/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,EAC7B,KAAK,uBAAuB,GAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { FAST_PATH_ELIGIBILITY_SYMBOL, FAST_PATH_STATS_SYMBOL } from './eligibility.js';
|
|
2
|
+
export { compileFastPathEligibility, getHandlerFastPathEligibility, setHandlerFastPathEligibility } from './eligibility-checker.js';
|
|
3
|
+
export { executeFastPath, shouldUseFastPathForRequest } from './fast-path-executor.js';
|
|
4
|
+
export { addPathDebugHeader, createFastPathStats, createPathDebugInfo, formatFastPathStats } from './debug-visibility.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-route-handoff.d.ts","sourceRoot":"","sources":["../../src/dispatch/native-route-handoff.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"native-route-handoff.d.ts","sourceRoot":"","sources":["../../src/dispatch/native-route-handoff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA2BlE,wFAAwF;AACxF,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAEtG;AAED;;;;;;;;;GASG;AACH,wBAAgB,mCAAmC,CAAC,UAAU,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CAavG;AAED;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,kBAAkB,GAC1B,gBAAgB,CAYlB;AAED;;;;;GAKG;AACH,wBAAgB,sCAAsC,CACpD,OAAO,EAAE,gBAAgB,GACxB,kBAAkB,GAAG,SAAS,CAWhC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvE"}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { normalizeRoutePath } from '../route-path.js';
|
|
2
1
|
const FRAMEWORK_REQUEST_NATIVE_ROUTE_HANDOFF = Symbol('fluo.http.nativeRouteHandoff');
|
|
3
2
|
const RAW_REQUEST_NATIVE_ROUTE_HANDOFFS = new WeakMap();
|
|
3
|
+
const EMPTY_ROUTE_PARAMS = Object.freeze({});
|
|
4
4
|
function cloneNativeRouteHandoff(handoff) {
|
|
5
5
|
return {
|
|
6
6
|
descriptor: handoff.descriptor,
|
|
7
|
-
params:
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
params: cloneRouteParams(handoff.params)
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function cloneRouteParams(params) {
|
|
11
|
+
return Object.keys(params).length === 0 ? EMPTY_ROUTE_PARAMS : {
|
|
12
|
+
...params
|
|
10
13
|
};
|
|
11
14
|
}
|
|
12
15
|
|
|
@@ -90,5 +93,5 @@ export function readFrameworkRequestNativeRouteHandoff(request) {
|
|
|
90
93
|
* @returns `true` when normalization would change the incoming path.
|
|
91
94
|
*/
|
|
92
95
|
export function isRoutePathNormalizationSensitive(path) {
|
|
93
|
-
return
|
|
96
|
+
return path.length > 1 && path.endsWith('/') || path.includes('//');
|
|
94
97
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export * from './middleware/correlation.js';
|
|
|
3
3
|
export * from './middleware/cors.js';
|
|
4
4
|
export { All, Controller, Convert, Delete, FromBody, FromCookie, FromHeader, FromPath, FromQuery, Get, Head, Header, HttpCode, Optional, Options, Patch, Post, Produces, Put, Redirect, RequestDto, UseGuards, UseInterceptors, Version, } from './decorators.js';
|
|
5
5
|
export * from './dispatch/dispatcher.js';
|
|
6
|
+
export type { FastPathEligibility, FastPathStats } from './dispatch/fast-path/index.js';
|
|
7
|
+
export { FAST_PATH_ELIGIBILITY_SYMBOL, FAST_PATH_STATS_SYMBOL, formatFastPathStats, getDispatcherFastPathStats, } from './dispatch/dispatcher.js';
|
|
6
8
|
export * from './errors.js';
|
|
7
9
|
export * from './exceptions.js';
|
|
8
10
|
export * from './mapping.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,OAAO,EACL,GAAG,EACH,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAQ,EACR,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,EACT,GAAG,EACH,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,GAAG,EACH,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,OAAO,GACR,MAAM,iBAAiB,CAAC;AACzB,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,OAAO,EACL,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,4BAA4B,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,OAAO,EACL,GAAG,EACH,UAAU,EACV,OAAO,EACP,MAAM,EACN,QAAQ,EACR,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,EACT,GAAG,EACH,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,GAAG,EACH,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,EACf,OAAO,GACR,MAAM,iBAAiB,CAAC;AACzB,cAAc,0BAA0B,CAAC;AACzC,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACxF,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,0BAA0B,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,OAAO,EACL,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,4BAA4B,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export * from './middleware/correlation.js';
|
|
|
3
3
|
export * from './middleware/cors.js';
|
|
4
4
|
export { All, Controller, Convert, Delete, FromBody, FromCookie, FromHeader, FromPath, FromQuery, Get, Head, Header, HttpCode, Optional, Options, Patch, Post, Produces, Put, Redirect, RequestDto, UseGuards, UseInterceptors, Version } from './decorators.js';
|
|
5
5
|
export * from './dispatch/dispatcher.js';
|
|
6
|
+
export { FAST_PATH_ELIGIBILITY_SYMBOL, FAST_PATH_STATS_SYMBOL, formatFastPathStats, getDispatcherFastPathStats } from './dispatch/dispatcher.js';
|
|
6
7
|
export * from './errors.js';
|
|
7
8
|
export * from './exceptions.js';
|
|
8
9
|
export * from './mapping.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -26,8 +26,12 @@ export interface FrameworkRequest {
|
|
|
26
26
|
cookies: Readonly<Record<string, string | undefined>>;
|
|
27
27
|
params: Readonly<Record<string, string>>;
|
|
28
28
|
body?: unknown;
|
|
29
|
+
/** Adapter-snapshotted inbound request id used without forcing header normalization. */
|
|
30
|
+
requestId?: string;
|
|
29
31
|
rawBody?: Uint8Array;
|
|
30
32
|
raw: unknown;
|
|
33
|
+
/** Adapter-owned abort probe used by internal fast paths without forcing AbortSignal allocation. */
|
|
34
|
+
isAborted?: () => boolean;
|
|
31
35
|
signal?: AbortSignal;
|
|
32
36
|
}
|
|
33
37
|
/**
|
|
@@ -182,6 +186,14 @@ export type VersioningOptions = {
|
|
|
182
186
|
/** Runtime dispatcher that executes the full HTTP request lifecycle. */
|
|
183
187
|
export interface Dispatcher {
|
|
184
188
|
dispatch(request: FrameworkRequest, response: FrameworkResponse): Promise<void>;
|
|
189
|
+
/**
|
|
190
|
+
* Executes a pre-matched native route through the fast path when safe.
|
|
191
|
+
*
|
|
192
|
+
* @internal Platform adapters may use this to avoid duplicate dispatcher
|
|
193
|
+
* scaffolding for routes already selected by their native router. It returns
|
|
194
|
+
* `false` when the route must fall back to the normal dispatch lifecycle.
|
|
195
|
+
*/
|
|
196
|
+
dispatchNativeRoute?(match: HandlerMatch, request: FrameworkRequest, response: FrameworkResponse): Promise<boolean>;
|
|
185
197
|
/**
|
|
186
198
|
* Returns the mapped route descriptors known to this dispatcher when the
|
|
187
199
|
* implementation can expose them without changing dispatch behavior.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"controller",
|
|
11
11
|
"rest"
|
|
12
12
|
],
|
|
13
|
-
"version": "1.0.0-beta.
|
|
13
|
+
"version": "1.0.0-beta.7",
|
|
14
14
|
"private": false,
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"repository": {
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"dist"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@fluojs/
|
|
44
|
+
"@fluojs/di": "^1.0.0-beta.5",
|
|
45
45
|
"@fluojs/validation": "^1.0.0-beta.1",
|
|
46
|
-
"@fluojs/
|
|
46
|
+
"@fluojs/core": "^1.0.0-beta.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"vitest": "^3.2.4"
|