@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.
Files changed (31) hide show
  1. package/dist/dispatch/dispatch-response-policy.d.ts +1 -1
  2. package/dist/dispatch/dispatch-response-policy.d.ts.map +1 -1
  3. package/dist/dispatch/dispatch-response-policy.js +3 -4
  4. package/dist/dispatch/dispatch-routing-policy.d.ts.map +1 -1
  5. package/dist/dispatch/dispatch-routing-policy.js +6 -4
  6. package/dist/dispatch/dispatcher.d.ts +18 -6
  7. package/dist/dispatch/dispatcher.d.ts.map +1 -1
  8. package/dist/dispatch/dispatcher.js +252 -21
  9. package/dist/dispatch/fast-path/debug-visibility.d.ts +18 -0
  10. package/dist/dispatch/fast-path/debug-visibility.d.ts.map +1 -0
  11. package/dist/dispatch/fast-path/debug-visibility.js +39 -0
  12. package/dist/dispatch/fast-path/eligibility-checker.d.ts +22 -0
  13. package/dist/dispatch/fast-path/eligibility-checker.d.ts.map +1 -0
  14. package/dist/dispatch/fast-path/eligibility-checker.js +110 -0
  15. package/dist/dispatch/fast-path/eligibility.d.ts +61 -0
  16. package/dist/dispatch/fast-path/eligibility.d.ts.map +1 -0
  17. package/dist/dispatch/fast-path/eligibility.js +23 -0
  18. package/dist/dispatch/fast-path/fast-path-executor.d.ts +21 -0
  19. package/dist/dispatch/fast-path/fast-path-executor.d.ts.map +1 -0
  20. package/dist/dispatch/fast-path/fast-path-executor.js +80 -0
  21. package/dist/dispatch/fast-path/index.d.ts +6 -0
  22. package/dist/dispatch/fast-path/index.d.ts.map +1 -0
  23. package/dist/dispatch/fast-path/index.js +4 -0
  24. package/dist/dispatch/native-route-handoff.d.ts.map +1 -1
  25. package/dist/dispatch/native-route-handoff.js +8 -5
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +1 -0
  29. package/dist/types.d.ts +12 -0
  30. package/dist/types.d.ts.map +1 -1
  31. 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): Promise<void>;
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,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,OAAO,EACd,kBAAkB,EAAE,0BAA0B,GAAG,SAAS,GACzD,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,CAAC;AACzD,YAAY,EAAE,0BAA0B,EAAE,CAAC"}
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 async function writeSuccessResponse(handler, request, response, value, contentNegotiation) {
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
- await response.sendSimpleJson(value);
83
- return;
82
+ return response.sendSimpleJson(value);
84
83
  }
85
84
  const responseBody = formatter ? formatter.format(value) : value;
86
- await response.send(responseBody);
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,CAKlH"}
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
- ...requestContext.request,
26
- params
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
- * Type definition for a global HTTP error handler function.
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,EACd,eAAe,EAEf,cAAc,EAId,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAMrB;;GAEG;AACH,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;;GAEG;AACH,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,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,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,qDAAqD;IACrD,aAAa,EAAE,SAAS,CAAC;CAC1B;AAugBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,UAAU,CA+D7E"}
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
- return {
30
- ...request,
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
- return {
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
- activeContainer = promoteOnContainerAccess();
81
- return activeContainer;
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.signal?.aborted) {
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
- await runMiddlewareChain(context.options.appMiddleware ?? [], appMiddlewareContext, async () => {
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.signal?.aborted) {
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
- await notifyRequestStart(phaseContext);
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
- await notifyRequestFinish(phaseContext);
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":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAsBlE,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
+ {"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
- ...handoff.params
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 normalizeRoutePath(path) !== path;
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';
@@ -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.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAErE,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,CAAC;AAElG,qFAAqF;AACrF,oBAAY,cAAc;IACxB,GAAG,QAAQ;IACX,MAAM,WAAW;IACjB,UAAU,eAAe;IACzB,MAAM,WAAW;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;IACjE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;IAC/D,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IACtD,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,4BAA4B,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC3C,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;CACzC;AAED,kFAAkF;AAClF,MAAM,WAAW,4BAA4B;IAC3C,KAAK,CACH,IAAI,EAAE,UAAU,EAChB,OAAO,CAAC,EAAE,wCAAwC,GACjD,YAAY,CAAC,OAAO,CAAC,CAAC;CAC1B;AAED,mEAAmE;AACnE,MAAM,WAAW,wCAAwC;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,KAAK,IAAI,IAAI,CAAC;IACd,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IACpD,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;CAC5C;AAED,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACxC;AAED,iFAAiF;AACjF,MAAM,WAAW,yBAAyB;IACxC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAClC;AAED,4EAA4E;AAC5E,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,SAAS,EAAE,qBAAqB,CAAC;CAClC;AAED,qEAAqE;AACrE,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;CACrB;AAED,mFAAmF;AACnF,MAAM,MAAM,iBAAiB,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO,IAAI,CACjE,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,cAAc,KAChB,YAAY,CAAC,MAAM,CAAC,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,cAAc,EAAE,CAAC;IACnC,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,WAAW,CAAC;IAC7B,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,kFAAkF;AAClF,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC1C;AAED,oFAAoF;AACpF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IAE1C,KAAK,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,GAAG,SAAS,CAAC;CAC5D;AAED,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,WAAW,CAAC;IAC7B,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC;IACpC,UAAU,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED,uEAAuE;AACvE,MAAM,MAAM,yBAAyB,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;AAC/E,kFAAkF;AAClF,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,yBAAyB,CAAC;AAE3F;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB;IACE,IAAI,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC;CAC3B,GACD;IACE,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IACE,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC;IAC5B,SAAS,EAAE,mBAAmB,CAAC;CAChC,CAAC;AAEN,wEAAwE;AACxE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF;;;OAGG;IACH,cAAc,CAAC,IAAI,SAAS,iBAAiB,EAAE,CAAC;CACjD;AAED,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjE;AAED,kFAAkF;AAClF,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,+EAA+E;AAC/E,MAAM,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvC,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAED,4CAA4C;AAC5C,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;CACpE;AAED,kEAAkE;AAClE,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,iFAAiF;AACjF,MAAM,WAAW,KAAK;IACpB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;CAClE;AAED,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5B;AAED,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,gFAAgF;AAChF,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;CAClF;AAED,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,gBAAgB,CAAC,CAAC,OAAO,EAAE,yBAAyB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAC1E,cAAc,CAAC,CAAC,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACxF,eAAe,CAAC,CAAC,OAAO,EAAE,yBAAyB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACzE,cAAc,CAAC,CAAC,OAAO,EAAE,yBAAyB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACxE,gBAAgB,CAAC,CAAC,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;CAC3F;AAED,uEAAuE;AACvE,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,mFAAmF;AACnF,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;AAEzD,uEAAuE;AACvE,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,WAAW,CAAC;IACjB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,mBAAmB,CAAC;IACjC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+EAA+E;AAC/E,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,uBAAuB,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;CACjF;AAED,kFAAkF;AAClF,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;CACzE;AAED,qEAAqE;AACrE,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,qBAAqB,CAAC;AACpF,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;AAC7C,kFAAkF;AAClF,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;AAC/D,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAAG,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC"}
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.5",
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/core": "^1.0.0-beta.2",
44
+ "@fluojs/di": "^1.0.0-beta.5",
45
45
  "@fluojs/validation": "^1.0.0-beta.1",
46
- "@fluojs/di": "^1.0.0-beta.5"
46
+ "@fluojs/core": "^1.0.0-beta.2"
47
47
  },
48
48
  "devDependencies": {
49
49
  "vitest": "^3.2.4"