@fluojs/runtime 1.1.8 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.ko.md +292 -21
  2. package/README.md +292 -21
  3. package/dist/abort.d.ts +6 -1
  4. package/dist/abort.d.ts.map +1 -1
  5. package/dist/abort.js +18 -2
  6. package/dist/adapters/internal-request-response-factory.d.ts +1 -1
  7. package/dist/adapters/internal-request-response-factory.d.ts.map +1 -1
  8. package/dist/adapters/internal-request-response-factory.js +1 -1
  9. package/dist/adapters/request-response-factory.d.ts +20 -1
  10. package/dist/adapters/request-response-factory.d.ts.map +1 -1
  11. package/dist/adapters/request-response-factory.js +75 -22
  12. package/dist/bootstrap.d.ts +3 -9
  13. package/dist/bootstrap.d.ts.map +1 -1
  14. package/dist/bootstrap.js +181 -76
  15. package/dist/devtools/contracts.d.ts +3 -135
  16. package/dist/devtools/contracts.d.ts.map +1 -1
  17. package/dist/devtools/index.d.ts +2 -3
  18. package/dist/devtools/index.d.ts.map +1 -1
  19. package/dist/devtools/index.js +1 -2
  20. package/dist/devtools/snapshot.d.ts +1 -1
  21. package/dist/devtools/snapshot.d.ts.map +1 -1
  22. package/dist/devtools/snapshot.js +18 -17
  23. package/dist/devtools/studio-request-observer.d.ts +14 -0
  24. package/dist/devtools/studio-request-observer.d.ts.map +1 -0
  25. package/dist/devtools/studio-request-observer.js +112 -0
  26. package/dist/devtools/studio-runtime-config.d.ts +25 -0
  27. package/dist/devtools/studio-runtime-config.d.ts.map +1 -0
  28. package/dist/devtools/studio-runtime-config.js +59 -0
  29. package/dist/devtools/studio-runtime.d.ts +12 -18
  30. package/dist/devtools/studio-runtime.d.ts.map +1 -1
  31. package/dist/devtools/studio-runtime.js +25 -169
  32. package/dist/errors.d.ts +26 -0
  33. package/dist/errors.d.ts.map +1 -1
  34. package/dist/errors.js +38 -0
  35. package/dist/health/health.d.ts +18 -4
  36. package/dist/health/health.d.ts.map +1 -1
  37. package/dist/health/health.js +5 -2
  38. package/dist/http-adapter-shared.d.ts +1 -1
  39. package/dist/http-adapter-shared.d.ts.map +1 -1
  40. package/dist/http-adapter-shared.js +1 -1
  41. package/dist/index.d.ts +6 -3
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +4 -1
  44. package/dist/internal/route-inspection-metadata.d.ts +30 -0
  45. package/dist/internal/route-inspection-metadata.d.ts.map +1 -0
  46. package/dist/internal/route-inspection-metadata.js +68 -0
  47. package/dist/internal.d.ts +6 -1
  48. package/dist/internal.d.ts.map +1 -1
  49. package/dist/internal.js +4 -1
  50. package/dist/module-definition.d.ts +10 -0
  51. package/dist/module-definition.d.ts.map +1 -0
  52. package/dist/module-definition.js +12 -0
  53. package/dist/module-graph.d.ts +42 -1
  54. package/dist/module-graph.d.ts.map +1 -1
  55. package/dist/module-graph.js +112 -16
  56. package/dist/multipart.d.ts +68 -4
  57. package/dist/multipart.d.ts.map +1 -1
  58. package/dist/multipart.js +666 -103
  59. package/dist/platform-component-registry.d.ts +9 -0
  60. package/dist/platform-component-registry.d.ts.map +1 -0
  61. package/dist/platform-component-registry.js +70 -0
  62. package/dist/platform-diagnostic-retention.d.ts +13 -0
  63. package/dist/platform-diagnostic-retention.d.ts.map +1 -0
  64. package/dist/platform-diagnostic-retention.js +43 -0
  65. package/dist/platform-shell-probe-reports.d.ts +8 -0
  66. package/dist/platform-shell-probe-reports.d.ts.map +1 -0
  67. package/dist/platform-shell-probe-reports.js +95 -0
  68. package/dist/platform-shell-probes.d.ts +16 -0
  69. package/dist/platform-shell-probes.d.ts.map +1 -0
  70. package/dist/platform-shell-probes.js +141 -0
  71. package/dist/platform-shell.d.ts +7 -13
  72. package/dist/platform-shell.d.ts.map +1 -1
  73. package/dist/platform-shell.js +58 -310
  74. package/dist/retryable-shutdown.d.ts +7 -0
  75. package/dist/retryable-shutdown.d.ts.map +1 -0
  76. package/dist/retryable-shutdown.js +20 -0
  77. package/dist/route-inspection.d.ts +56 -0
  78. package/dist/route-inspection.d.ts.map +1 -0
  79. package/dist/route-inspection.js +80 -0
  80. package/dist/tokens.d.ts +6 -4
  81. package/dist/tokens.d.ts.map +1 -1
  82. package/dist/tokens.js +5 -0
  83. package/dist/types.d.ts +53 -8
  84. package/dist/types.d.ts.map +1 -1
  85. package/dist/web.d.ts +22 -9
  86. package/dist/web.d.ts.map +1 -1
  87. package/dist/web.js +80 -34
  88. package/package.json +13 -26
  89. package/dist/internal-node.d.ts +0 -2
  90. package/dist/internal-node.d.ts.map +0 -1
  91. package/dist/internal-node.js +0 -1
  92. package/dist/logging/json-logger.d.ts +0 -8
  93. package/dist/logging/json-logger.d.ts.map +0 -1
  94. package/dist/logging/json-logger.js +0 -45
  95. package/dist/logging/logger.d.ts +0 -37
  96. package/dist/logging/logger.d.ts.map +0 -1
  97. package/dist/logging/logger.js +0 -103
  98. package/dist/node/internal-node-compression.d.ts +0 -22
  99. package/dist/node/internal-node-compression.d.ts.map +0 -1
  100. package/dist/node/internal-node-compression.js +0 -84
  101. package/dist/node/internal-node-request.d.ts +0 -162
  102. package/dist/node/internal-node-request.d.ts.map +0 -1
  103. package/dist/node/internal-node-request.js +0 -475
  104. package/dist/node/internal-node-response.d.ts +0 -28
  105. package/dist/node/internal-node-response.d.ts.map +0 -1
  106. package/dist/node/internal-node-response.js +0 -205
  107. package/dist/node/internal-node-shutdown.d.ts +0 -34
  108. package/dist/node/internal-node-shutdown.d.ts.map +0 -1
  109. package/dist/node/internal-node-shutdown.js +0 -83
  110. package/dist/node/internal-node.d.ts +0 -117
  111. package/dist/node/internal-node.d.ts.map +0 -1
  112. package/dist/node/internal-node.js +0 -283
  113. package/dist/node/node-compression.d.ts +0 -2
  114. package/dist/node/node-compression.d.ts.map +0 -1
  115. package/dist/node/node-compression.js +0 -1
  116. package/dist/node/node-request.d.ts +0 -2
  117. package/dist/node/node-request.d.ts.map +0 -1
  118. package/dist/node/node-request.js +0 -1
  119. package/dist/node/node-response.d.ts +0 -2
  120. package/dist/node/node-response.d.ts.map +0 -1
  121. package/dist/node/node-response.js +0 -1
  122. package/dist/node/node-shutdown.d.ts +0 -2
  123. package/dist/node/node-shutdown.d.ts.map +0 -1
  124. package/dist/node/node-shutdown.js +0 -1
  125. package/dist/node/node.d.ts +0 -2
  126. package/dist/node/node.d.ts.map +0 -1
  127. package/dist/node/node.js +0 -1
  128. package/dist/node.d.ts +0 -5
  129. package/dist/node.d.ts.map +0 -1
  130. package/dist/node.js +0 -3
@@ -1,28 +1,25 @@
1
- import { createStudioLiveSnapshot, handlerToStudioRouteDescriptor } from './snapshot.js';
1
+ import { createStudioLiveSnapshot } from './snapshot.js';
2
+ import { StudioRequestObserver } from './studio-request-observer.js';
3
+ import { captureStudioDevtoolsConfig } from './studio-runtime-config.js';
2
4
  const runtimePerformance = globalThis.performance ?? {
3
5
  now: () => Date.now()
4
6
  };
5
7
  const processStart = runtimePerformance.now();
6
8
 
7
9
  /**
8
- * Describes Studio Devtools Runtime Transport data used by the Studio devtool.
10
+ * Host-owned transport that receives live Studio events.
11
+ *
12
+ * Transport failures are ignored so Studio instrumentation remains observational.
9
13
  */
10
14
 
11
15
  /**
12
- * Describes Studio Devtools Runtime Options data used by the Studio devtool.
16
+ * Options for a host-owned Studio bridge.
13
17
  */
14
18
 
15
19
  /**
16
20
  * Describes Studio Bootstrap Snapshot Input data used by the Studio devtool.
17
21
  */
18
22
 
19
- /**
20
- * Describes Studio Devtools Config data used by the Studio devtool.
21
- */
22
-
23
- function isEnabled(value) {
24
- return value === '1' || value === 'true' || value === 'yes';
25
- }
26
23
  function createEpoch() {
27
24
  if (typeof globalThis.crypto?.randomUUID === 'function') {
28
25
  return globalThis.crypto.randomUUID();
@@ -32,77 +29,6 @@ function createEpoch() {
32
29
  function createAppId() {
33
30
  return `app-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
34
31
  }
35
- function createRequestId() {
36
- return `req-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
37
- }
38
- function normalizeRuntime(value) {
39
- if (value === 'node' || value === 'bun' || value === 'deno' || value === 'worker') {
40
- return value;
41
- }
42
- return 'node';
43
- }
44
- function isRecord(value) {
45
- return typeof value === 'object' && value !== null;
46
- }
47
- function resolveEndpoint(env) {
48
- if (env.FLUO_STUDIO_ENDPOINT) {
49
- return env.FLUO_STUDIO_ENDPOINT;
50
- }
51
- if (!env.FLUO_STUDIO_URL) {
52
- return undefined;
53
- }
54
- try {
55
- return new URL('/api/runtime/events', env.FLUO_STUDIO_URL).toString();
56
- } catch {
57
- return undefined;
58
- }
59
- }
60
- function toErrorPayload(error) {
61
- if (error instanceof Error) {
62
- return {
63
- message: error.message,
64
- name: error.name
65
- };
66
- }
67
- return {
68
- message: String(error)
69
- };
70
- }
71
- function sanitizeRequestUrl(value) {
72
- try {
73
- const parsed = new URL(value, 'http://fluo.local');
74
- return parsed.pathname || '/';
75
- } catch {
76
- return value.split('#', 1)[0]?.split('?', 1)[0] || value;
77
- }
78
- }
79
- function traceToPayload(trace, statusCode) {
80
- const payload = {
81
- method: trace.method,
82
- path: trace.path,
83
- requestId: trace.requestId,
84
- startedAt: trace.startedAt,
85
- status: trace.status,
86
- url: trace.url
87
- };
88
- if (trace.handler) {
89
- const route = handlerToStudioRouteDescriptor(trace.handler);
90
- payload.controller = route.controller;
91
- payload.handler = route.handler;
92
- payload.routeId = route.id;
93
- }
94
- if (trace.error) {
95
- payload.error = trace.error;
96
- }
97
- if (statusCode !== undefined) {
98
- payload.statusCode = statusCode;
99
- }
100
- if (trace.status === 'succeeded' || trace.status === 'failed' || trace.status === 'finished') {
101
- payload.finishedAt = new Date().toISOString();
102
- payload.durationMs = Number((runtimePerformance.now() - trace.startMs).toFixed(3));
103
- }
104
- return payload;
105
- }
106
32
  class FetchStudioTransport {
107
33
  constructor(endpoint, token) {
108
34
  this.endpoint = endpoint;
@@ -119,73 +45,13 @@ class FetchStudioTransport {
119
45
  });
120
46
  }
121
47
  }
122
- class StudioRequestObserver {
123
- traces = new WeakMap();
124
- constructor(runtime) {
125
- this.runtime = runtime;
126
- }
127
- onRequestStart(context) {
128
- const request = context.requestContext.request;
129
- const requestId = request.requestId ?? (typeof request.headers['x-request-id'] === 'string' ? request.headers['x-request-id'] : undefined) ?? createRequestId();
130
- const trace = {
131
- method: request.method,
132
- path: request.path,
133
- requestId,
134
- startedAt: new Date().toISOString(),
135
- startMs: runtimePerformance.now(),
136
- status: 'started',
137
- url: sanitizeRequestUrl(request.url)
138
- };
139
- this.traces.set(context.requestContext, trace);
140
- this.runtime.publish('request', traceToPayload(trace));
141
- }
142
- onHandlerMatched(context) {
143
- const trace = this.ensureTrace(context);
144
- trace.handler = context.handler;
145
- trace.status = 'matched';
146
- this.runtime.publish('request', traceToPayload(trace));
147
- }
148
- onRequestSuccess(context) {
149
- const trace = this.ensureTrace(context);
150
- trace.handler = context.handler ?? trace.handler;
151
- trace.status = 'succeeded';
152
- }
153
- onRequestError(context, error) {
154
- const trace = this.ensureTrace(context);
155
- trace.handler = context.handler ?? trace.handler;
156
- trace.error = toErrorPayload(error);
157
- trace.status = 'failed';
158
- this.runtime.publish('request', traceToPayload(trace, context.requestContext.response.statusCode));
159
- }
160
- onRequestFinish(context) {
161
- const trace = this.ensureTrace(context);
162
- trace.handler = context.handler ?? trace.handler;
163
- if (trace.status !== 'failed' && trace.status !== 'succeeded') {
164
- trace.status = 'finished';
165
- }
166
- this.runtime.publish('request', traceToPayload(trace, context.requestContext.response.statusCode));
167
- }
168
- ensureTrace(context) {
169
- const existing = this.traces.get(context.requestContext);
170
- if (existing) {
171
- return existing;
172
- }
173
- const request = context.requestContext.request;
174
- const trace = {
175
- method: request.method,
176
- path: request.path,
177
- requestId: request.requestId ?? createRequestId(),
178
- startedAt: new Date().toISOString(),
179
- startMs: runtimePerformance.now(),
180
- status: 'started',
181
- url: sanitizeRequestUrl(request.url)
182
- };
183
- this.traces.set(context.requestContext, trace);
184
- return trace;
185
- }
186
- }
187
48
 
188
- /** Process-local runtime bridge used only when Studio env injection is present. */
49
+ /**
50
+ * Host-owned bridge for publishing live Studio bootstrap and request events.
51
+ *
52
+ * Pass an instance as `studioDevtools` to application or context bootstrap.
53
+ * Event delivery is observational: transport throws and rejections never alter runtime behavior.
54
+ */
189
55
  export class StudioDevtoolsRuntime {
190
56
  epoch;
191
57
  observer = new StudioRequestObserver(this);
@@ -215,7 +81,11 @@ export class StudioDevtoolsRuntime {
215
81
  type,
216
82
  version: 1
217
83
  };
218
- void Promise.resolve(this.options.transport.publish(event)).catch(() => undefined);
84
+ try {
85
+ void Promise.resolve(this.options.transport.publish(event)).catch(() => undefined);
86
+ } catch {
87
+ // Studio instrumentation must remain observational when a host transport throws.
88
+ }
219
89
  }
220
90
  publishBootstrapSnapshot(input) {
221
91
  const snapshot = createStudioLiveSnapshot({
@@ -237,17 +107,6 @@ export class StudioDevtoolsRuntime {
237
107
  });
238
108
  }
239
109
  }
240
- const STUDIO_DEVTOOLS_GLOBAL_CONFIG_KEY = '__FLUO_STUDIO_DEVTOOLS_CONFIG__';
241
- function isStudioDevtoolsConfig(value) {
242
- if (!isRecord(value)) {
243
- return false;
244
- }
245
- return value.FLUO_STUDIO === undefined || typeof value.FLUO_STUDIO === 'string';
246
- }
247
- function readInjectedStudioDevtoolsConfig() {
248
- const value = globalThis[STUDIO_DEVTOOLS_GLOBAL_CONFIG_KEY];
249
- return isStudioDevtoolsConfig(value) ? value : undefined;
250
- }
251
110
 
252
111
  /**
253
112
  * Creates the Studio runtime bridge from explicit CLI-injected config.
@@ -256,20 +115,17 @@ function readInjectedStudioDevtoolsConfig() {
256
115
  * @param config Explicit Studio config injected by the application boundary.
257
116
  * @returns Studio runtime bridge, or `undefined` when Studio is disabled or incomplete.
258
117
  */
259
- export function createStudioDevtoolsRuntimeFromConfig(config = readInjectedStudioDevtoolsConfig()) {
260
- if (!config || !isEnabled(config.FLUO_STUDIO)) {
261
- return undefined;
262
- }
263
- const endpoint = resolveEndpoint(config);
264
- if (!endpoint || !config.FLUO_STUDIO_TOKEN || typeof globalThis.fetch !== 'function') {
118
+ export function createStudioDevtoolsRuntimeFromConfig(config) {
119
+ const snapshot = captureStudioDevtoolsConfig(config);
120
+ if (!snapshot || typeof globalThis.fetch !== 'function') {
265
121
  return undefined;
266
122
  }
267
- const epoch = config.FLUO_STUDIO_EPOCH ?? createEpoch();
123
+ const epoch = snapshot.epoch ?? createEpoch();
268
124
  return new StudioDevtoolsRuntime({
269
- appId: config.FLUO_STUDIO_APP_ID ?? createAppId(),
125
+ appId: snapshot.appId ?? createAppId(),
270
126
  epoch,
271
- runtime: normalizeRuntime(config.FLUO_STUDIO_RUNTIME),
272
- transport: new FetchStudioTransport(endpoint, config.FLUO_STUDIO_TOKEN)
127
+ runtime: snapshot.runtime,
128
+ transport: new FetchStudioTransport(snapshot.endpoint, snapshot.token)
273
129
  });
274
130
  }
275
131
 
package/dist/errors.d.ts CHANGED
@@ -1,4 +1,30 @@
1
1
  import { FluoError } from '@fluojs/core';
2
+ /**
3
+ * Public lifecycle operations supported by {@link PlatformLifecycleConflictError}.
4
+ */
5
+ export type PlatformLifecycleOperation = 'start' | 'stop';
6
+ /**
7
+ * Error returned when a platform shell lifecycle request overlaps an active transition.
8
+ *
9
+ * @remarks
10
+ * Platform shell lifecycle transitions are strictly exclusive. Callers can inspect
11
+ * {@link PlatformLifecycleConflictError.activeOperation} and
12
+ * {@link PlatformLifecycleConflictError.requestedOperation}, wait for their own active
13
+ * operation to settle, and then retry explicitly.
14
+ */
15
+ export declare class PlatformLifecycleConflictError extends FluoError {
16
+ /** Lifecycle operation that currently owns the platform shell transition. */
17
+ readonly activeOperation: PlatformLifecycleOperation;
18
+ /** Lifecycle operation rejected because another transition is active. */
19
+ readonly requestedOperation: PlatformLifecycleOperation;
20
+ /**
21
+ * Creates a platform lifecycle conflict error.
22
+ *
23
+ * @param activeOperation Lifecycle operation that currently owns the transition.
24
+ * @param requestedOperation Overlapping lifecycle operation that was rejected.
25
+ */
26
+ constructor(activeOperation: PlatformLifecycleOperation, requestedOperation: PlatformLifecycleOperation);
27
+ }
2
28
  /**
3
29
  * Structured context for runtime-level errors.
4
30
  */
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAmB,MAAM,cAAc,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,4CAA4C;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,gDAAgD;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAuCD;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,SAAS;gBACjC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAS3D;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;gBACtC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAS3D;AAED;;GAEG;AACH,qBAAa,4BAA6B,SAAQ,SAAS;gBAC7C,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAS3D;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;gBACvC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAS3D"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAmB,MAAM,cAAc,CAAC;AAE1D;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1D;;;;;;;;GAQG;AACH,qBAAa,8BAA+B,SAAQ,SAAS;IAC3D,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,EAAE,0BAA0B,CAAC;IACrD,yEAAyE;IACzE,QAAQ,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;IAExD;;;;;OAKG;gBACS,eAAe,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,0BAA0B;CAWxG;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,4CAA4C;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,gDAAgD;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAuCD;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,SAAS;gBACjC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAS3D;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;gBACtC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAS3D;AAED;;GAEG;AACH,qBAAa,4BAA6B,SAAQ,SAAS;gBAC7C,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAS3D;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;gBACvC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAS3D"}
package/dist/errors.js CHANGED
@@ -1,5 +1,43 @@
1
1
  import { FluoError, formatTokenName } from '@fluojs/core';
2
2
 
3
+ /**
4
+ * Public lifecycle operations supported by {@link PlatformLifecycleConflictError}.
5
+ */
6
+
7
+ /**
8
+ * Error returned when a platform shell lifecycle request overlaps an active transition.
9
+ *
10
+ * @remarks
11
+ * Platform shell lifecycle transitions are strictly exclusive. Callers can inspect
12
+ * {@link PlatformLifecycleConflictError.activeOperation} and
13
+ * {@link PlatformLifecycleConflictError.requestedOperation}, wait for their own active
14
+ * operation to settle, and then retry explicitly.
15
+ */
16
+ export class PlatformLifecycleConflictError extends FluoError {
17
+ /** Lifecycle operation that currently owns the platform shell transition. */
18
+ activeOperation;
19
+ /** Lifecycle operation rejected because another transition is active. */
20
+ requestedOperation;
21
+
22
+ /**
23
+ * Creates a platform lifecycle conflict error.
24
+ *
25
+ * @param activeOperation Lifecycle operation that currently owns the transition.
26
+ * @param requestedOperation Overlapping lifecycle operation that was rejected.
27
+ */
28
+ constructor(activeOperation, requestedOperation) {
29
+ super(`Cannot ${requestedOperation} the platform shell while ${activeOperation} is active.`, {
30
+ code: 'PLATFORM_LIFECYCLE_CONFLICT',
31
+ meta: {
32
+ activeOperation,
33
+ requestedOperation
34
+ }
35
+ });
36
+ this.activeOperation = activeOperation;
37
+ this.requestedOperation = requestedOperation;
38
+ }
39
+ }
40
+
3
41
  /**
4
42
  * Structured context for runtime-level errors.
5
43
  */
@@ -1,3 +1,5 @@
1
+ import type { Constructor } from '@fluojs/core';
2
+ import { type Middleware } from '@fluojs/http/portable';
1
3
  import type { ModuleType } from '../types.js';
2
4
  /**
3
5
  * Describes the health status contract.
@@ -22,13 +24,25 @@ export interface ReadinessStatus {
22
24
  * Describes the health module options contract.
23
25
  */
24
26
  export interface HealthModuleOptions {
25
- healthCheck?: (ctx: import('@fluojs/http').RequestContext) => HealthStatus | HealthCheckResponse | Promise<HealthStatus | HealthCheckResponse>;
27
+ /** Class-based middleware applied only to the generated `/health` and `/ready` endpoints. */
28
+ endpointMiddleware?: readonly Constructor<Middleware>[];
29
+ healthCheck?: (ctx: import('@fluojs/http/portable').RequestContext) => HealthStatus | HealthCheckResponse | Promise<HealthStatus | HealthCheckResponse>;
26
30
  path?: string;
27
31
  }
28
32
  /**
29
33
  * Defines the readiness check type.
30
34
  */
31
- export type ReadinessCheck = (ctx: import('@fluojs/http').RequestContext) => boolean | Promise<boolean>;
35
+ export type ReadinessCheck = (ctx: import('@fluojs/http/portable').RequestContext) => boolean | Promise<boolean>;
36
+ /** Runtime-owned health module class returned by `HealthModule.forRoot(...)`. */
37
+ export interface RuntimeHealthModule extends ModuleType {
38
+ readonly name: string;
39
+ /** Register an additional readiness predicate for the module-owned `/ready` route. */
40
+ addReadinessCheck(fn: ReadinessCheck): void;
41
+ /** Mark the module-owned `/ready` route as ready after bootstrap completes. */
42
+ markReady(): void;
43
+ /** Mark the module-owned `/ready` route as starting before or during shutdown. */
44
+ markStarting(): void;
45
+ }
32
46
  /**
33
47
  * Runtime health module facade for application module imports.
34
48
  */
@@ -39,7 +53,7 @@ export declare class HealthModule {
39
53
  * @param options Runtime health endpoint options.
40
54
  * @returns A module class that can be imported into an application module.
41
55
  */
42
- static forRoot(options?: HealthModuleOptions): ModuleType;
56
+ static forRoot(options?: HealthModuleOptions): RuntimeHealthModule;
43
57
  }
44
58
  /**
45
59
  * Creates a runtime-owned `/health` and `/ready` module.
@@ -48,5 +62,5 @@ export declare class HealthModule {
48
62
  * @param options Runtime health endpoint options.
49
63
  * @returns A module class that can be imported into an application module.
50
64
  */
51
- export declare function createHealthModule(options?: HealthModuleOptions): ModuleType;
65
+ export declare function createHealthModule(options?: HealthModuleOptions): RuntimeHealthModule;
52
66
  //# sourceMappingURL=health.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/health/health.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,IAAI,GAAG,aAAa,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,aAAa,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,cAAc,EAAE,cAAc,KACrD,YAAY,GACZ,mBAAmB,GACnB,OAAO,CAAC,YAAY,GAAG,mBAAmB,CAAC,CAAC;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,OAAO,cAAc,EAAE,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAkFxG;;GAEG;AACH,qBAAa,YAAY;IACvB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,mBAAwB,GAAG,UAAU;CAG9D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,UAAU,CAEhF"}
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/health/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAA8B,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,IAAI,GAAG,aAAa,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,aAAa,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6FAA6F;IAC7F,kBAAkB,CAAC,EAAE,SAAS,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;IACxD,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,uBAAuB,EAAE,cAAc,KAC9D,YAAY,GACZ,mBAAmB,GACnB,OAAO,CAAC,YAAY,GAAG,mBAAmB,CAAC,CAAC;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,OAAO,uBAAuB,EAAE,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjH,iFAAiF;AACjF,MAAM,WAAW,mBAAoB,SAAQ,UAAU;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5C,+EAA+E;IAC/E,SAAS,IAAI,IAAI,CAAC;IAClB,kFAAkF;IAClF,YAAY,IAAI,IAAI,CAAC;CACtB;AAqFD;;GAEG;AACH,qBAAa,YAAY;IACvB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,mBAAwB,GAAG,mBAAmB;CAGvE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,mBAAmB,CAEzF"}
@@ -3,7 +3,7 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
3
3
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
4
  function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
5
5
  function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
6
- import { Controller, Get } from '@fluojs/http';
6
+ import { Controller, forRoutes, Get } from '@fluojs/http/portable';
7
7
  import { defineModule } from '../bootstrap.js';
8
8
 
9
9
  /**
@@ -26,6 +26,8 @@ import { defineModule } from '../bootstrap.js';
26
26
  * Defines the readiness check type.
27
27
  */
28
28
 
29
+ /** Runtime-owned health module class returned by `HealthModule.forRoot(...)`. */
30
+
29
31
  function createRuntimeHealthModule(options = {}) {
30
32
  let _initProto, _initClass;
31
33
  const basePath = options.path ?? '';
@@ -100,7 +102,8 @@ function createRuntimeHealthModule(options = {}) {
100
102
  value: 'HealthModule'
101
103
  });
102
104
  defineModule(RuntimeHealthModule, {
103
- controllers: [_HealthController]
105
+ controllers: [_HealthController],
106
+ middleware: (options.endpointMiddleware ?? []).map(middlewareClass => forRoutes(middlewareClass, `${basePath}/health`, `${basePath}/ready`))
104
107
  });
105
108
  return RuntimeHealthModule;
106
109
  }
@@ -1,4 +1,4 @@
1
- import { type CorsOptions, type HttpApplicationAdapter, type MiddlewareLike, type SecurityHeadersOptions } from '@fluojs/http';
1
+ import { type CorsOptions, type HttpApplicationAdapter, type MiddlewareLike, type SecurityHeadersOptions } from '@fluojs/http/portable';
2
2
  import { createDefaultApplicationLogger } from './logging/default-logger.js';
3
3
  import type { Application, ApplicationLogger, CreateApplicationOptions, ModuleType } from './types.js';
4
4
  export { createDefaultApplicationLogger };
@@ -1 +1 @@
1
- {"version":3,"file":"http-adapter-shared.d.ts","sourceRoot":"","sources":["../src/http-adapter-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAKhB,KAAK,sBAAsB,EAE3B,KAAK,cAAc,EAKnB,KAAK,sBAAsB,EAC5B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEvG,OAAO,EAAE,8BAA8B,EAAE,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,WAAW,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,0CAA0C;IAC1C,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,6DAA6D;IAC7D,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,qCAAqC;IACrC,eAAe,CAAC,EAAE,KAAK,GAAG,sBAAsB,CAAC;CAClD;AAED;;GAEG;AACH,MAAM,WAAW,sCACf,SAAQ,IAAI,CAAC,wBAAwB,EAAE,SAAS,GAAG,YAAY,CAAC,EAC9D,4BAA4B;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,gCAAiC,SAAQ,sCAAsC;IAC9F,4FAA4F;IAC5F,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0CAA0C;IAC1C,oBAAoB,CAAC,EAAE,+BAA+B,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,MAAM,+BAA+B,GAAG,CAC5C,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,iBAAiB,EACzB,kBAAkB,CAAC,EAAE,MAAM,KACxB,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;AAEzB,KAAK,6BAA6B,GAAG,sBAAsB,GAAG;IAC5D,eAAe,IAAI,uBAAuB,CAAC;CAC5C,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,+BAA+B,CACnD,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,sCAAsC,EAC/C,OAAO,EAAE,sBAAsB,EAC/B,MAAM,GAAE,iBAAoD,GAC3D,OAAO,CAAC,WAAW,CAAC,CAQtB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,4BAA4B,GAAG,cAAc,EAAE,CAkBnG;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,uBAAuB,GAAG,MAAM,CAItF;AAED;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,gCAAgC,EACzC,OAAO,EAAE,6BAA6B,EACtC,MAAM,GAAE,iBAAoD,GAC3D,OAAO,CAAC,WAAW,CAAC,CA8EtB"}
1
+ {"version":3,"file":"http-adapter-shared.d.ts","sourceRoot":"","sources":["../src/http-adapter-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAKhB,KAAK,sBAAsB,EAE3B,KAAK,cAAc,EAKnB,KAAK,sBAAsB,EAC5B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEvG,OAAO,EAAE,8BAA8B,EAAE,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,WAAW,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,0CAA0C;IAC1C,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,6DAA6D;IAC7D,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,qCAAqC;IACrC,eAAe,CAAC,EAAE,KAAK,GAAG,sBAAsB,CAAC;CAClD;AAED;;GAEG;AACH,MAAM,WAAW,sCACf,SAAQ,IAAI,CAAC,wBAAwB,EAAE,SAAS,GAAG,YAAY,CAAC,EAC9D,4BAA4B;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,gCAAiC,SAAQ,sCAAsC;IAC9F,4FAA4F;IAC5F,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0CAA0C;IAC1C,oBAAoB,CAAC,EAAE,+BAA+B,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,MAAM,+BAA+B,GAAG,CAC5C,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,iBAAiB,EACzB,kBAAkB,CAAC,EAAE,MAAM,KACxB,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;AAEzB,KAAK,6BAA6B,GAAG,sBAAsB,GAAG;IAC5D,eAAe,IAAI,uBAAuB,CAAC;CAC5C,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,+BAA+B,CACnD,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,sCAAsC,EAC/C,OAAO,EAAE,sBAAsB,EAC/B,MAAM,GAAE,iBAAoD,GAC3D,OAAO,CAAC,WAAW,CAAC,CAQtB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,4BAA4B,GAAG,cAAc,EAAE,CAkBnG;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,uBAAuB,GAAG,MAAM,CAItF;AAED;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,gCAAgC,EACzC,OAAO,EAAE,6BAA6B,EACtC,MAAM,GAAE,iBAAoD,GAC3D,OAAO,CAAC,WAAW,CAAC,CA8EtB"}
@@ -1,4 +1,4 @@
1
- import { createCorsMiddleware, createErrorResponse, createSecurityHeadersMiddleware, matchRoutePattern, NotFoundException, normalizeRoutePattern } from '@fluojs/http';
1
+ import { createCorsMiddleware, createErrorResponse, createSecurityHeadersMiddleware, matchRoutePattern, NotFoundException, normalizeRoutePattern } from '@fluojs/http/portable';
2
2
  import { bootstrapApplication } from './bootstrap.js';
3
3
  import { createDefaultApplicationLogger } from './logging/default-logger.js';
4
4
  export { createDefaultApplicationLogger };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,15 @@
1
1
  export * from './abort.js';
2
2
  export * from './bootstrap.js';
3
- export { createBootstrapTimingDiagnostics, createRuntimeDiagnosticsGraph, } from './health/diagnostics.js';
4
- export type { BootstrapTimingDiagnostics, BootstrapTimingPhase, RuntimeDiagnosticsGraph, RuntimeDiagnosticsModule, RuntimeDiagnosticsProvider, RuntimeDiagnosticsRelationships, } from './health/diagnostics.js';
5
3
  export * from './errors.js';
4
+ export type { BootstrapTimingDiagnostics, BootstrapTimingPhase, RuntimeDiagnosticsGraph, RuntimeDiagnosticsModule, RuntimeDiagnosticsProvider, RuntimeDiagnosticsRelationships, } from './health/diagnostics.js';
5
+ export { createBootstrapTimingDiagnostics, createRuntimeDiagnosticsGraph, } from './health/diagnostics.js';
6
6
  export * from './health/health.js';
7
- export type { MultipartOptions, MultipartRequestLike, MultipartResult, UploadedFile, } from './multipart.js';
7
+ export { ModuleGraphCompileCache } from './module-graph.js';
8
+ export type { MultipartFieldPart, MultipartFilePart, MultipartOptions, MultipartPart, MultipartRequestLike, MultipartResult, UploadedFile, } from './multipart.js';
9
+ export { MultipartBodyConsumedError } from './multipart.js';
8
10
  export type { PersistencePlatformStatusSnapshot, PlatformCheckResult, PlatformComponent, PlatformComponentInput, PlatformComponentRegistration, PlatformDiagnosticIssue, PlatformHealthReport, PlatformOptionsBase, PlatformReadinessReport, PlatformShell, PlatformShellSnapshot, PlatformSnapshot, PlatformState, PlatformValidationResult, } from './platform-contract.js';
9
11
  export * from './request-transaction.js';
12
+ export * from './route-inspection.js';
10
13
  export { APPLICATION_LOGGER, PLATFORM_SHELL } from './tokens.js';
11
14
  export * from './types.js';
12
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,0BAA0B,EAC1B,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,iCAAiC,EACjC,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,6BAA6B,EAC7B,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,YAAY,EACV,0BAA0B,EAC1B,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EACV,iCAAiC,EACjC,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,6BAA6B,EAC7B,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,11 @@
1
1
  export * from './abort.js';
2
2
  export * from './bootstrap.js';
3
- export { createBootstrapTimingDiagnostics, createRuntimeDiagnosticsGraph } from './health/diagnostics.js';
4
3
  export * from './errors.js';
4
+ export { createBootstrapTimingDiagnostics, createRuntimeDiagnosticsGraph } from './health/diagnostics.js';
5
5
  export * from './health/health.js';
6
+ export { ModuleGraphCompileCache } from './module-graph.js';
7
+ export { MultipartBodyConsumedError } from './multipart.js';
6
8
  export * from './request-transaction.js';
9
+ export * from './route-inspection.js';
7
10
  export { APPLICATION_LOGGER, PLATFORM_SHELL } from './tokens.js';
8
11
  export * from './types.js';
@@ -0,0 +1,30 @@
1
+ import type { MetadataPropertyKey } from '@fluojs/core';
2
+ /** Describes package-integration metadata that classifies a compiled runtime route. */
3
+ export interface RuntimeRouteInspectionMetadata {
4
+ readonly kind: string;
5
+ }
6
+ /**
7
+ * Records route inspection metadata in a TC39 standard decorator metadata bag.
8
+ *
9
+ * @param metadata Standard decorator metadata bag that owns the route marker.
10
+ * @param propertyKey Controller method key associated with the route.
11
+ * @param value Route inspection metadata to store as an immutable snapshot.
12
+ */
13
+ export declare function defineStandardRuntimeRouteInspectionMetadata(metadata: unknown, propertyKey: MetadataPropertyKey, value: RuntimeRouteInspectionMetadata): void;
14
+ /**
15
+ * Records route inspection metadata for legacy decorator-call compatibility.
16
+ *
17
+ * @param target Controller prototype that owns the decorated route.
18
+ * @param propertyKey Controller method key associated with the route.
19
+ * @param value Route inspection metadata to store as an immutable snapshot.
20
+ */
21
+ export declare function defineLegacyRuntimeRouteInspectionMetadata(target: object, propertyKey: MetadataPropertyKey, value: RuntimeRouteInspectionMetadata): void;
22
+ /**
23
+ * Reads the immutable route inspection marker for a compiled controller method.
24
+ *
25
+ * @param controllerToken Controller class that owns the route handler.
26
+ * @param propertyKey Controller method key associated with the route.
27
+ * @returns The normalized route metadata when a package integration recorded one.
28
+ */
29
+ export declare function getRuntimeRouteInspectionMetadata(controllerToken: Function, propertyKey: MetadataPropertyKey): RuntimeRouteInspectionMetadata | undefined;
30
+ //# sourceMappingURL=route-inspection-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-inspection-metadata.d.ts","sourceRoot":"","sources":["../../src/internal/route-inspection-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAUxD,uFAAuF;AACvF,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAwBD;;;;;;GAMG;AACH,wBAAgB,4CAA4C,CAC1D,QAAQ,EAAE,OAAO,EACjB,WAAW,EAAE,mBAAmB,EAChC,KAAK,EAAE,8BAA8B,GACpC,IAAI,CAEN;AAED;;;;;;GAMG;AACH,wBAAgB,0CAA0C,CACxD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,mBAAmB,EAChC,KAAK,EAAE,8BAA8B,GACpC,IAAI,CASN;AAWD;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAC/C,eAAe,EAAE,QAAQ,EACzB,WAAW,EAAE,mBAAmB,GAC/B,8BAA8B,GAAG,SAAS,CAO5C"}
@@ -0,0 +1,68 @@
1
+ import { getStandardMetadataBag } from '@fluojs/core/internal';
2
+ const runtimeRouteInspectionMetadataKey = Symbol.for('fluo.runtime.route-inspection');
3
+ const legacyRouteInspectionMetadataStore = new WeakMap();
4
+
5
+ /** Describes package-integration metadata that classifies a compiled runtime route. */
6
+
7
+ function cloneMetadata(metadata) {
8
+ return Object.freeze({
9
+ kind: metadata.kind
10
+ });
11
+ }
12
+ function getMetadataMap(metadata) {
13
+ const metadataBag = typeof metadata === 'object' && metadata !== null ? metadata : {};
14
+ const current = Object.hasOwn(metadataBag, runtimeRouteInspectionMetadataKey) ? Reflect.get(metadataBag, runtimeRouteInspectionMetadataKey) : undefined;
15
+ if (current instanceof Map) {
16
+ return current;
17
+ }
18
+ const inherited = Reflect.get(metadataBag, runtimeRouteInspectionMetadataKey);
19
+ const created = inherited instanceof Map ? new Map(inherited) : new Map();
20
+ Reflect.set(metadataBag, runtimeRouteInspectionMetadataKey, created);
21
+ return created;
22
+ }
23
+
24
+ /**
25
+ * Records route inspection metadata in a TC39 standard decorator metadata bag.
26
+ *
27
+ * @param metadata Standard decorator metadata bag that owns the route marker.
28
+ * @param propertyKey Controller method key associated with the route.
29
+ * @param value Route inspection metadata to store as an immutable snapshot.
30
+ */
31
+ export function defineStandardRuntimeRouteInspectionMetadata(metadata, propertyKey, value) {
32
+ getMetadataMap(metadata).set(propertyKey, cloneMetadata(value));
33
+ }
34
+
35
+ /**
36
+ * Records route inspection metadata for legacy decorator-call compatibility.
37
+ *
38
+ * @param target Controller prototype that owns the decorated route.
39
+ * @param propertyKey Controller method key associated with the route.
40
+ * @param value Route inspection metadata to store as an immutable snapshot.
41
+ */
42
+ export function defineLegacyRuntimeRouteInspectionMetadata(target, propertyKey, value) {
43
+ let routeMap = legacyRouteInspectionMetadataStore.get(target);
44
+ if (!routeMap) {
45
+ routeMap = new Map();
46
+ legacyRouteInspectionMetadataStore.set(target, routeMap);
47
+ }
48
+ routeMap.set(propertyKey, cloneMetadata(value));
49
+ }
50
+ function isRuntimeRouteInspectionMetadata(value) {
51
+ const kind = typeof value === 'object' && value !== null ? Reflect.get(value, 'kind') : undefined;
52
+ return typeof value === 'object' && value !== null && typeof kind === 'string' && kind.length > 0;
53
+ }
54
+
55
+ /**
56
+ * Reads the immutable route inspection marker for a compiled controller method.
57
+ *
58
+ * @param controllerToken Controller class that owns the route handler.
59
+ * @param propertyKey Controller method key associated with the route.
60
+ * @returns The normalized route metadata when a package integration recorded one.
61
+ */
62
+ export function getRuntimeRouteInspectionMetadata(controllerToken, propertyKey) {
63
+ const legacyMetadata = legacyRouteInspectionMetadataStore.get(controllerToken.prototype)?.get(propertyKey);
64
+ const standardRouteMap = getStandardMetadataBag(controllerToken)?.[runtimeRouteInspectionMetadataKey];
65
+ const standardMetadata = standardRouteMap instanceof Map ? standardRouteMap.get(propertyKey) : undefined;
66
+ const metadata = legacyMetadata ?? standardMetadata;
67
+ return isRuntimeRouteInspectionMetadata(metadata) ? cloneMetadata(metadata) : undefined;
68
+ }
@@ -1,4 +1,9 @@
1
1
  export { getRuntimeClassDiMetadata } from './internal/core-metadata.js';
2
+ export type { RuntimeRouteInspectionMetadata } from './internal/route-inspection-metadata.js';
3
+ export { defineLegacyRuntimeRouteInspectionMetadata, defineStandardRuntimeRouteInspectionMetadata, getRuntimeRouteInspectionMetadata, } from './internal/route-inspection-metadata.js';
4
+ export { defineModule } from './module-definition.js';
5
+ export { createRuntimeRouteInspection } from './route-inspection.js';
2
6
  export type { BootstrapReadySignal } from './tokens.js';
3
- export { APPLICATION_LOGGER, BOOTSTRAP_READY_SIGNAL, COMPILED_MODULES, HTTP_APPLICATION_ADAPTER, PLATFORM_SHELL, RUNTIME_CLEANUP_REGISTRATION, RUNTIME_CONTAINER, } from './tokens.js';
7
+ export { APPLICATION_LOGGER, BOOTSTRAP_PROVIDER_TOKENS, BOOTSTRAP_READY_SIGNAL, COMPILED_MODULES, HTTP_APPLICATION_ADAPTER, PLATFORM_SHELL, RUNTIME_CLEANUP_REGISTRATION, RUNTIME_CONTAINER, } from './tokens.js';
8
+ export type { ModuleDefinition, ModuleType } from './types.js';
4
9
  //# sourceMappingURL=internal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,EACxB,cAAc,EACd,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AAC9F,OAAO,EACL,0CAA0C,EAC1C,4CAA4C,EAC5C,iCAAiC,GAClC,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AACrE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,EACxB,cAAc,EACd,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
package/dist/internal.js CHANGED
@@ -1,2 +1,5 @@
1
1
  export { getRuntimeClassDiMetadata } from './internal/core-metadata.js';
2
- export { APPLICATION_LOGGER, BOOTSTRAP_READY_SIGNAL, COMPILED_MODULES, HTTP_APPLICATION_ADAPTER, PLATFORM_SHELL, RUNTIME_CLEANUP_REGISTRATION, RUNTIME_CONTAINER } from './tokens.js';
2
+ export { defineLegacyRuntimeRouteInspectionMetadata, defineStandardRuntimeRouteInspectionMetadata, getRuntimeRouteInspectionMetadata } from './internal/route-inspection-metadata.js';
3
+ export { defineModule } from './module-definition.js';
4
+ export { createRuntimeRouteInspection } from './route-inspection.js';
5
+ export { APPLICATION_LOGGER, BOOTSTRAP_PROVIDER_TOKENS, BOOTSTRAP_READY_SIGNAL, COMPILED_MODULES, HTTP_APPLICATION_ADAPTER, PLATFORM_SHELL, RUNTIME_CLEANUP_REGISTRATION, RUNTIME_CONTAINER } from './tokens.js';
@@ -0,0 +1,10 @@
1
+ import type { ModuleDefinition, ModuleType } from './types.js';
2
+ /**
3
+ * Associates a portable module definition with a module type.
4
+ *
5
+ * @param moduleType Module class that should receive runtime module metadata.
6
+ * @param definition Module definition contract (`imports`, `providers`, `controllers`, `exports`, etc.).
7
+ * @returns The same `moduleType` reference for fluent helper composition.
8
+ */
9
+ export declare function defineModule<T extends ModuleType>(moduleType: T, definition: ModuleDefinition): T;
10
+ //# sourceMappingURL=module-definition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-definition.d.ts","sourceRoot":"","sources":["../src/module-definition.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,gBAAgB,GAAG,CAAC,CAIjG"}
@@ -0,0 +1,12 @@
1
+ import { defineRuntimeModuleMetadata } from './internal/core-metadata.js';
2
+ /**
3
+ * Associates a portable module definition with a module type.
4
+ *
5
+ * @param moduleType Module class that should receive runtime module metadata.
6
+ * @param definition Module definition contract (`imports`, `providers`, `controllers`, `exports`, etc.).
7
+ * @returns The same `moduleType` reference for fluent helper composition.
8
+ */
9
+ export function defineModule(moduleType, definition) {
10
+ defineRuntimeModuleMetadata(moduleType, definition);
11
+ return moduleType;
12
+ }