@fluojs/runtime 1.0.0-beta.1

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 (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.ko.md +182 -0
  3. package/README.md +182 -0
  4. package/dist/abort.d.ts +19 -0
  5. package/dist/abort.d.ts.map +1 -0
  6. package/dist/abort.js +39 -0
  7. package/dist/adapters/internal-http-adapter.d.ts +2 -0
  8. package/dist/adapters/internal-http-adapter.d.ts.map +1 -0
  9. package/dist/adapters/internal-http-adapter.js +1 -0
  10. package/dist/adapters/internal-request-response-factory.d.ts +2 -0
  11. package/dist/adapters/internal-request-response-factory.d.ts.map +1 -0
  12. package/dist/adapters/internal-request-response-factory.js +1 -0
  13. package/dist/adapters/request-response-factory.d.ts +17 -0
  14. package/dist/adapters/request-response-factory.d.ts.map +1 -0
  15. package/dist/adapters/request-response-factory.js +27 -0
  16. package/dist/bootstrap.d.ts +73 -0
  17. package/dist/bootstrap.d.ts.map +1 -0
  18. package/dist/bootstrap.js +870 -0
  19. package/dist/errors.d.ts +39 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +88 -0
  22. package/dist/health/diagnostics.d.ts +56 -0
  23. package/dist/health/diagnostics.d.ts.map +1 -0
  24. package/dist/health/diagnostics.js +155 -0
  25. package/dist/health/health.d.ts +18 -0
  26. package/dist/health/health.d.ts.map +1 -0
  27. package/dist/health/health.js +82 -0
  28. package/dist/http-adapter-shared.d.ts +88 -0
  29. package/dist/http-adapter-shared.d.ts.map +1 -0
  30. package/dist/http-adapter-shared.js +199 -0
  31. package/dist/index.d.ts +11 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +8 -0
  34. package/dist/internal-http-adapter.d.ts +2 -0
  35. package/dist/internal-http-adapter.d.ts.map +1 -0
  36. package/dist/internal-http-adapter.js +1 -0
  37. package/dist/internal-node.d.ts +2 -0
  38. package/dist/internal-node.d.ts.map +1 -0
  39. package/dist/internal-node.js +1 -0
  40. package/dist/internal-request-response-factory.d.ts +2 -0
  41. package/dist/internal-request-response-factory.d.ts.map +1 -0
  42. package/dist/internal-request-response-factory.js +1 -0
  43. package/dist/internal.d.ts +2 -0
  44. package/dist/internal.d.ts.map +1 -0
  45. package/dist/internal.js +1 -0
  46. package/dist/logging/json-logger.d.ts +3 -0
  47. package/dist/logging/json-logger.d.ts.map +1 -0
  48. package/dist/logging/json-logger.js +39 -0
  49. package/dist/logging/logger.d.ts +3 -0
  50. package/dist/logging/logger.d.ts.map +1 -0
  51. package/dist/logging/logger.js +36 -0
  52. package/dist/module-graph.d.ts +26 -0
  53. package/dist/module-graph.d.ts.map +1 -0
  54. package/dist/module-graph.js +248 -0
  55. package/dist/multipart.d.ts +45 -0
  56. package/dist/multipart.d.ts.map +1 -0
  57. package/dist/multipart.js +195 -0
  58. package/dist/node/internal-node-compression.d.ts +7 -0
  59. package/dist/node/internal-node-compression.d.ts.map +1 -0
  60. package/dist/node/internal-node-compression.js +68 -0
  61. package/dist/node/internal-node-request.d.ts +34 -0
  62. package/dist/node/internal-node-request.d.ts.map +1 -0
  63. package/dist/node/internal-node-request.js +195 -0
  64. package/dist/node/internal-node-response.d.ts +8 -0
  65. package/dist/node/internal-node-response.d.ts.map +1 -0
  66. package/dist/node/internal-node-response.js +166 -0
  67. package/dist/node/internal-node-shutdown.d.ts +34 -0
  68. package/dist/node/internal-node-shutdown.d.ts.map +1 -0
  69. package/dist/node/internal-node-shutdown.js +83 -0
  70. package/dist/node/internal-node.d.ts +80 -0
  71. package/dist/node/internal-node.d.ts.map +1 -0
  72. package/dist/node/internal-node.js +209 -0
  73. package/dist/node/node-compression.d.ts +2 -0
  74. package/dist/node/node-compression.d.ts.map +1 -0
  75. package/dist/node/node-compression.js +1 -0
  76. package/dist/node/node-request.d.ts +2 -0
  77. package/dist/node/node-request.d.ts.map +1 -0
  78. package/dist/node/node-request.js +1 -0
  79. package/dist/node/node-response.d.ts +2 -0
  80. package/dist/node/node-response.d.ts.map +1 -0
  81. package/dist/node/node-response.js +1 -0
  82. package/dist/node/node-shutdown.d.ts +2 -0
  83. package/dist/node/node-shutdown.d.ts.map +1 -0
  84. package/dist/node/node-shutdown.js +1 -0
  85. package/dist/node/node.d.ts +2 -0
  86. package/dist/node/node.d.ts.map +1 -0
  87. package/dist/node/node.js +1 -0
  88. package/dist/node.d.ts +5 -0
  89. package/dist/node.d.ts.map +1 -0
  90. package/dist/node.js +3 -0
  91. package/dist/platform-contract.d.ts +140 -0
  92. package/dist/platform-contract.d.ts.map +1 -0
  93. package/dist/platform-contract.js +1 -0
  94. package/dist/platform-shell.d.ts +45 -0
  95. package/dist/platform-shell.d.ts.map +1 -0
  96. package/dist/platform-shell.js +368 -0
  97. package/dist/request-transaction.d.ts +17 -0
  98. package/dist/request-transaction.d.ts.map +1 -0
  99. package/dist/request-transaction.js +39 -0
  100. package/dist/tokens.d.ts +27 -0
  101. package/dist/tokens.d.ts.map +1 -0
  102. package/dist/tokens.js +24 -0
  103. package/dist/types.d.ts +161 -0
  104. package/dist/types.d.ts.map +1 -0
  105. package/dist/types.js +1 -0
  106. package/dist/web.d.ts +58 -0
  107. package/dist/web.d.ts.map +1 -0
  108. package/dist/web.js +431 -0
  109. package/package.json +86 -0
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Shared configuration knobs understood by runtime platform components.
3
+ */
4
+ export interface PlatformOptionsBase {
5
+ id?: string;
6
+ enabled?: boolean;
7
+ readiness?: {
8
+ critical?: boolean;
9
+ timeoutMs?: number;
10
+ };
11
+ shutdown?: {
12
+ timeoutMs?: number;
13
+ };
14
+ diagnostics?: {
15
+ expose?: boolean;
16
+ tags?: Record<string, string>;
17
+ };
18
+ telemetry?: {
19
+ namespace?: string;
20
+ tags?: Record<string, string>;
21
+ };
22
+ }
23
+ /** Lifecycle states emitted by platform components and the platform shell. */
24
+ export type PlatformState = 'created' | 'validated' | 'starting' | 'ready' | 'degraded' | 'stopping' | 'stopped' | 'failed';
25
+ /**
26
+ * Runtime-managed infrastructure component that participates in validation,
27
+ * startup, readiness, health, diagnostics, and shutdown orchestration.
28
+ */
29
+ export interface PlatformComponent {
30
+ id: string;
31
+ kind: string;
32
+ state(): PlatformState;
33
+ validate(): Promise<PlatformValidationResult> | PlatformValidationResult;
34
+ start(): Promise<void>;
35
+ ready(): Promise<PlatformReadinessReport>;
36
+ health(): Promise<PlatformHealthReport>;
37
+ snapshot(): PlatformSnapshot;
38
+ stop(): Promise<void>;
39
+ }
40
+ /** Registration wrapper used when a component declares platform dependencies. */
41
+ export interface PlatformComponentRegistration {
42
+ component: PlatformComponent;
43
+ dependencies?: readonly string[];
44
+ }
45
+ /** Component registration input accepted by runtime bootstrap options. */
46
+ export type PlatformComponentInput = PlatformComponent | PlatformComponentRegistration;
47
+ /** Outcome for one named readiness or health probe inside a platform report. */
48
+ export interface PlatformCheckResult {
49
+ name: string;
50
+ status: 'pass' | 'fail' | 'degraded';
51
+ message?: string;
52
+ }
53
+ /**
54
+ * Readiness semantics for one component or the aggregated platform shell.
55
+ */
56
+ export interface PlatformReadinessReport {
57
+ status: 'ready' | 'not-ready' | 'degraded';
58
+ critical: boolean;
59
+ reason?: string;
60
+ checks?: PlatformCheckResult[];
61
+ }
62
+ /**
63
+ * Health semantics for one component or the aggregated platform shell.
64
+ */
65
+ export interface PlatformHealthReport {
66
+ status: 'healthy' | 'unhealthy' | 'degraded';
67
+ reason?: string;
68
+ checks?: PlatformCheckResult[];
69
+ }
70
+ /** Snapshot payload stored when persistence-backed platform status is exported. */
71
+ export interface PersistencePlatformStatusSnapshot {
72
+ readiness: PlatformReadinessReport;
73
+ health: PlatformHealthReport;
74
+ ownership: PlatformSnapshot['ownership'];
75
+ details: Record<string, unknown>;
76
+ }
77
+ /** Machine-readable diagnostic issue reported during platform validation. */
78
+ export interface PlatformDiagnosticIssue {
79
+ code: string;
80
+ severity: 'error' | 'warning' | 'info';
81
+ componentId: string;
82
+ message: string;
83
+ cause?: string;
84
+ fixHint?: string;
85
+ dependsOn?: string[];
86
+ docsUrl?: string;
87
+ }
88
+ /** Validation result returned before platform startup proceeds. */
89
+ export interface PlatformValidationResult {
90
+ ok: boolean;
91
+ issues: PlatformDiagnosticIssue[];
92
+ warnings?: PlatformDiagnosticIssue[];
93
+ }
94
+ /** Immutable component snapshot included in runtime diagnostics and telemetry. */
95
+ export interface PlatformSnapshot {
96
+ id: string;
97
+ kind: string;
98
+ state: PlatformState;
99
+ readiness: {
100
+ status: PlatformReadinessReport['status'];
101
+ critical: boolean;
102
+ reason?: string;
103
+ };
104
+ health: {
105
+ status: PlatformHealthReport['status'];
106
+ reason?: string;
107
+ };
108
+ dependencies: string[];
109
+ telemetry: {
110
+ namespace: string;
111
+ tags: Record<string, string>;
112
+ };
113
+ ownership: {
114
+ ownsResources: boolean;
115
+ externallyManaged: boolean;
116
+ };
117
+ details: Record<string, unknown>;
118
+ }
119
+ /**
120
+ * Aggregate platform snapshot emitted by the shell after collecting component
121
+ * health, readiness, and validation diagnostics.
122
+ */
123
+ export interface PlatformShellSnapshot {
124
+ generatedAt: string;
125
+ readiness: PlatformReadinessReport;
126
+ health: PlatformHealthReport;
127
+ components: PlatformSnapshot[];
128
+ diagnostics: PlatformDiagnosticIssue[];
129
+ }
130
+ /**
131
+ * High-level runtime facade that coordinates platform components as one unit.
132
+ */
133
+ export interface PlatformShell {
134
+ start(): Promise<void>;
135
+ stop(): Promise<void>;
136
+ ready(): Promise<PlatformReadinessReport>;
137
+ health(): Promise<PlatformHealthReport>;
138
+ snapshot(): Promise<PlatformShellSnapshot>;
139
+ }
140
+ //# sourceMappingURL=platform-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-contract.d.ts","sourceRoot":"","sources":["../src/platform-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,45 @@
1
+ import type { PlatformComponent, PlatformComponentInput, PlatformHealthReport, PlatformReadinessReport, PlatformShell, PlatformShellSnapshot } from './platform-contract.js';
2
+ interface RegisteredPlatformComponent {
3
+ component: PlatformComponent;
4
+ dependencies: readonly string[];
5
+ }
6
+ /**
7
+ * A runtime implementation of the {@link PlatformShell} that manages the lifecycle
8
+ * of registered platform components, including dependency ordering and diagnostics.
9
+ */
10
+ export declare class RuntimePlatformShell implements PlatformShell {
11
+ private readonly registeredComponents;
12
+ private started;
13
+ private stopped;
14
+ private orderedComponents;
15
+ private rollbackPendingComponents;
16
+ private readonly diagnostics;
17
+ constructor(registeredComponents: RegisteredPlatformComponent[]);
18
+ /**
19
+ * Creates a {@link RuntimePlatformShell} from an optional array of platform component inputs.
20
+ *
21
+ * @param components - The platform component inputs to register in the shell.
22
+ * @returns A new {@link RuntimePlatformShell} instance.
23
+ */
24
+ static fromInputs(components: readonly PlatformComponentInput[] | undefined): RuntimePlatformShell;
25
+ hasRegisteredComponents(): boolean;
26
+ start(): Promise<void>;
27
+ stop(): Promise<void>;
28
+ ready(): Promise<PlatformReadinessReport>;
29
+ health(): Promise<PlatformHealthReport>;
30
+ snapshot(): Promise<PlatformShellSnapshot>;
31
+ assertCriticalReadiness(): Promise<void>;
32
+ private validateIdentityAndDependencies;
33
+ private validateComponents;
34
+ private orderByDependency;
35
+ private stopStartedComponents;
36
+ }
37
+ /**
38
+ * Creates a {@link RuntimePlatformShell} instance to manage platform component lifecycles.
39
+ *
40
+ * @param components - The platform component inputs to register in the shell.
41
+ * @returns A new {@link RuntimePlatformShell} instance.
42
+ */
43
+ export declare function createRuntimePlatformShell(components: readonly PlatformComponentInput[] | undefined): RuntimePlatformShell;
44
+ export {};
45
+ //# sourceMappingURL=platform-shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-shell.d.ts","sourceRoot":"","sources":["../src/platform-shell.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EACjB,sBAAsB,EAGtB,oBAAoB,EACpB,uBAAuB,EACvB,aAAa,EACb,qBAAqB,EAGtB,MAAM,wBAAwB,CAAC;AAEhC,UAAU,2BAA2B;IACnC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAkHD;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,aAAa;IAO5C,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IANjD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,iBAAiB,CAAqC;IAC9D,OAAO,CAAC,yBAAyB,CAAqC;IACtE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;gBAEhC,oBAAoB,EAAE,2BAA2B,EAAE;IAEhF;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,SAAS,sBAAsB,EAAE,GAAG,SAAS,GAAG,oBAAoB;IAIlG,uBAAuB,IAAI,OAAO;IAI5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiDtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBrB,KAAK,IAAI,OAAO,CAAC,uBAAuB,CAAC;IA2BzC,MAAM,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAyBvC,QAAQ,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAmD1C,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;IAU9C,OAAO,CAAC,+BAA+B;YAgCzB,kBAAkB;IA4BhC,OAAO,CAAC,iBAAiB;YAsCX,qBAAqB;CAgBpC;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,SAAS,sBAAsB,EAAE,GAAG,SAAS,GAAG,oBAAoB,CAE1H"}
@@ -0,0 +1,368 @@
1
+ import { InvariantError } from '@fluojs/core';
2
+ function isRegistration(value) {
3
+ return typeof value === 'object' && value !== null && 'component' in value;
4
+ }
5
+ function normalizeRegistration(input) {
6
+ if (isRegistration(input)) {
7
+ return {
8
+ component: input.component,
9
+ dependencies: [...(input.dependencies ?? [])]
10
+ };
11
+ }
12
+ return {
13
+ component: input,
14
+ dependencies: []
15
+ };
16
+ }
17
+ function toRegisteredComponents(components) {
18
+ return (components ?? []).map(component => normalizeRegistration(component));
19
+ }
20
+ function createUnknownFailureIssue(componentId, phase, error) {
21
+ return {
22
+ cause: error instanceof Error ? error.message : String(error),
23
+ code: 'RUNTIME_PLATFORM_COMPONENT_FAILURE',
24
+ componentId,
25
+ fixHint: 'Inspect component implementation and ensure validate/start/ready/health/snapshot contracts are deterministic.',
26
+ message: `Platform component failed during ${phase}.`,
27
+ severity: 'error'
28
+ };
29
+ }
30
+ function aggregateReadiness(reports) {
31
+ const hasCriticalNotReady = reports.some(report => report.critical && report.status === 'not-ready');
32
+ const hasNotReady = reports.some(report => report.status === 'not-ready');
33
+ const hasDegraded = reports.some(report => report.status === 'degraded');
34
+ const hasCritical = reports.some(report => report.critical);
35
+ if (hasCriticalNotReady) {
36
+ const reason = reports.find(report => report.critical && report.status === 'not-ready')?.reason;
37
+ return {
38
+ critical: hasCritical,
39
+ reason: reason ?? 'One or more critical platform components are not ready.',
40
+ status: 'not-ready'
41
+ };
42
+ }
43
+ if (hasNotReady || hasDegraded) {
44
+ const reason = reports.find(report => report.status !== 'ready')?.reason;
45
+ return {
46
+ critical: hasCritical,
47
+ reason: reason ?? 'One or more platform components are degraded or not ready.',
48
+ status: 'degraded'
49
+ };
50
+ }
51
+ return {
52
+ critical: hasCritical,
53
+ status: 'ready'
54
+ };
55
+ }
56
+ function aggregateHealth(reports) {
57
+ const hasUnhealthy = reports.some(report => report.status === 'unhealthy');
58
+ const hasDegraded = reports.some(report => report.status === 'degraded');
59
+ if (hasUnhealthy) {
60
+ const reason = reports.find(report => report.status === 'unhealthy')?.reason;
61
+ return {
62
+ reason: reason ?? 'One or more platform components are unhealthy.',
63
+ status: 'unhealthy'
64
+ };
65
+ }
66
+ if (hasDegraded) {
67
+ const reason = reports.find(report => report.status === 'degraded')?.reason;
68
+ return {
69
+ reason: reason ?? 'One or more platform components are degraded.',
70
+ status: 'degraded'
71
+ };
72
+ }
73
+ return {
74
+ status: 'healthy'
75
+ };
76
+ }
77
+ function createEmptyShellSnapshot(diagnostics) {
78
+ return {
79
+ components: [],
80
+ diagnostics,
81
+ generatedAt: new Date().toISOString(),
82
+ health: {
83
+ status: 'healthy'
84
+ },
85
+ readiness: {
86
+ critical: false,
87
+ status: 'ready'
88
+ }
89
+ };
90
+ }
91
+ function normalizeSnapshot(snapshot, component, dependencies) {
92
+ return {
93
+ ...snapshot,
94
+ dependencies: [...dependencies],
95
+ id: component.id,
96
+ kind: component.kind
97
+ };
98
+ }
99
+
100
+ /**
101
+ * A runtime implementation of the {@link PlatformShell} that manages the lifecycle
102
+ * of registered platform components, including dependency ordering and diagnostics.
103
+ */
104
+ export class RuntimePlatformShell {
105
+ started = false;
106
+ stopped = false;
107
+ orderedComponents = [];
108
+ rollbackPendingComponents = [];
109
+ diagnostics = [];
110
+ constructor(registeredComponents) {
111
+ this.registeredComponents = registeredComponents;
112
+ }
113
+
114
+ /**
115
+ * Creates a {@link RuntimePlatformShell} from an optional array of platform component inputs.
116
+ *
117
+ * @param components - The platform component inputs to register in the shell.
118
+ * @returns A new {@link RuntimePlatformShell} instance.
119
+ */
120
+ static fromInputs(components) {
121
+ return new RuntimePlatformShell(toRegisteredComponents(components));
122
+ }
123
+ hasRegisteredComponents() {
124
+ return this.registeredComponents.length > 0;
125
+ }
126
+ async start() {
127
+ if (!this.hasRegisteredComponents() || this.started) {
128
+ return;
129
+ }
130
+ if (this.rollbackPendingComponents.length > 0) {
131
+ await this.stop();
132
+ }
133
+ this.validateIdentityAndDependencies();
134
+ const validationFailures = await this.validateComponents();
135
+ if (validationFailures.length > 0) {
136
+ throw new InvariantError(`Platform shell validation failed: ${validationFailures.map(issue => `${issue.componentId}:${issue.code}`).join(', ')}`);
137
+ }
138
+ this.orderedComponents = this.orderByDependency();
139
+ const startedComponents = [];
140
+ for (const component of this.orderedComponents) {
141
+ try {
142
+ await component.component.start();
143
+ startedComponents.push(component);
144
+ } catch (error) {
145
+ this.diagnostics.push(createUnknownFailureIssue(component.component.id, 'start', error));
146
+ const startFailure = new InvariantError(`Platform component "${component.component.id}" failed to start: ${error instanceof Error ? error.message : String(error)}`, {
147
+ cause: error
148
+ });
149
+ try {
150
+ await this.stopStartedComponents(startedComponents);
151
+ this.rollbackPendingComponents = [];
152
+ } catch (rollbackError) {
153
+ this.rollbackPendingComponents = [...startedComponents];
154
+ this.diagnostics.push(createUnknownFailureIssue(component.component.id, 'start-rollback', rollbackError));
155
+ }
156
+ throw startFailure;
157
+ }
158
+ }
159
+ this.started = true;
160
+ this.stopped = false;
161
+ this.rollbackPendingComponents = [];
162
+ }
163
+ async stop() {
164
+ const hasRollbackPending = this.rollbackPendingComponents.length > 0;
165
+ if (!this.started && !hasRollbackPending || this.stopped) {
166
+ return;
167
+ }
168
+ const toStop = hasRollbackPending ? [...this.rollbackPendingComponents] : this.orderedComponents.length > 0 ? [...this.orderedComponents] : [...this.registeredComponents];
169
+ await this.stopStartedComponents(toStop);
170
+ this.rollbackPendingComponents = [];
171
+ this.started = false;
172
+ this.stopped = true;
173
+ }
174
+ async ready() {
175
+ if (!this.hasRegisteredComponents()) {
176
+ return {
177
+ critical: false,
178
+ status: 'ready'
179
+ };
180
+ }
181
+ const reports = [];
182
+ for (const component of this.registeredComponents) {
183
+ try {
184
+ reports.push(await component.component.ready());
185
+ } catch (error) {
186
+ const issue = createUnknownFailureIssue(component.component.id, 'ready', error);
187
+ this.diagnostics.push(issue);
188
+ reports.push({
189
+ critical: true,
190
+ reason: issue.cause,
191
+ status: 'not-ready'
192
+ });
193
+ }
194
+ }
195
+ return aggregateReadiness(reports);
196
+ }
197
+ async health() {
198
+ if (!this.hasRegisteredComponents()) {
199
+ return {
200
+ status: 'healthy'
201
+ };
202
+ }
203
+ const reports = [];
204
+ for (const component of this.registeredComponents) {
205
+ try {
206
+ reports.push(await component.component.health());
207
+ } catch (error) {
208
+ const issue = createUnknownFailureIssue(component.component.id, 'health', error);
209
+ this.diagnostics.push(issue);
210
+ reports.push({
211
+ reason: issue.cause,
212
+ status: 'unhealthy'
213
+ });
214
+ }
215
+ }
216
+ return aggregateHealth(reports);
217
+ }
218
+ async snapshot() {
219
+ if (!this.hasRegisteredComponents()) {
220
+ return createEmptyShellSnapshot([...this.diagnostics]);
221
+ }
222
+ const components = [];
223
+ for (const registration of this.registeredComponents) {
224
+ try {
225
+ const snapshot = registration.component.snapshot();
226
+ components.push(normalizeSnapshot(snapshot, registration.component, registration.dependencies));
227
+ } catch (error) {
228
+ const issue = createUnknownFailureIssue(registration.component.id, 'snapshot', error);
229
+ this.diagnostics.push(issue);
230
+ components.push({
231
+ dependencies: [...registration.dependencies],
232
+ details: {},
233
+ health: {
234
+ reason: issue.cause,
235
+ status: 'unhealthy'
236
+ },
237
+ id: registration.component.id,
238
+ kind: registration.component.kind,
239
+ ownership: {
240
+ externallyManaged: false,
241
+ ownsResources: false
242
+ },
243
+ readiness: {
244
+ critical: true,
245
+ reason: issue.cause,
246
+ status: 'not-ready'
247
+ },
248
+ state: 'failed',
249
+ telemetry: {
250
+ namespace: 'fluo.platform',
251
+ tags: {}
252
+ }
253
+ });
254
+ }
255
+ }
256
+ const [readiness, health] = await Promise.all([this.ready(), this.health()]);
257
+ return {
258
+ components,
259
+ diagnostics: [...this.diagnostics],
260
+ generatedAt: new Date().toISOString(),
261
+ health,
262
+ readiness
263
+ };
264
+ }
265
+ async assertCriticalReadiness() {
266
+ const readiness = await this.ready();
267
+ if (readiness.status === 'not-ready') {
268
+ throw new InvariantError(`Runtime platform shell is not ready: ${readiness.reason ?? 'critical platform component is unavailable.'}`);
269
+ }
270
+ }
271
+ validateIdentityAndDependencies() {
272
+ const ids = new Set();
273
+ for (const registration of this.registeredComponents) {
274
+ if (!registration.component.id || registration.component.id.trim().length === 0) {
275
+ throw new InvariantError('Platform component id must be a non-empty string.');
276
+ }
277
+ if (ids.has(registration.component.id)) {
278
+ throw new InvariantError(`Duplicate platform component id "${registration.component.id}" is not allowed.`);
279
+ }
280
+ ids.add(registration.component.id);
281
+ }
282
+ for (const registration of this.registeredComponents) {
283
+ for (const dependency of registration.dependencies) {
284
+ if (!ids.has(dependency)) {
285
+ throw new InvariantError(`Platform component "${registration.component.id}" depends on unknown component "${dependency}".`);
286
+ }
287
+ if (dependency === registration.component.id) {
288
+ throw new InvariantError(`Platform component "${registration.component.id}" cannot depend on itself.`);
289
+ }
290
+ }
291
+ }
292
+ }
293
+ async validateComponents() {
294
+ const failures = [];
295
+ for (const registration of this.registeredComponents) {
296
+ let result;
297
+ try {
298
+ result = await registration.component.validate();
299
+ } catch (error) {
300
+ const issue = createUnknownFailureIssue(registration.component.id, 'validate', error);
301
+ this.diagnostics.push(issue);
302
+ failures.push(issue);
303
+ continue;
304
+ }
305
+ if (result.warnings) {
306
+ this.diagnostics.push(...result.warnings);
307
+ }
308
+ if (!result.ok || result.issues.some(issue => issue.severity === 'error')) {
309
+ this.diagnostics.push(...result.issues);
310
+ failures.push(...result.issues);
311
+ }
312
+ }
313
+ return failures;
314
+ }
315
+ orderByDependency() {
316
+ const byId = new Map(this.registeredComponents.map(registration => [registration.component.id, registration]));
317
+ const visiting = new Set();
318
+ const visited = new Set();
319
+ const ordered = [];
320
+ const visit = id => {
321
+ if (visited.has(id)) {
322
+ return;
323
+ }
324
+ if (visiting.has(id)) {
325
+ throw new InvariantError(`Platform component dependency cycle detected at "${id}".`);
326
+ }
327
+ visiting.add(id);
328
+ const registration = byId.get(id);
329
+ if (!registration) {
330
+ throw new InvariantError(`Platform component "${id}" is missing from runtime registration.`);
331
+ }
332
+ for (const dependency of registration.dependencies) {
333
+ visit(dependency);
334
+ }
335
+ visiting.delete(id);
336
+ visited.add(id);
337
+ ordered.push(registration);
338
+ };
339
+ for (const registration of this.registeredComponents) {
340
+ visit(registration.component.id);
341
+ }
342
+ return ordered;
343
+ }
344
+ async stopStartedComponents(startedComponents) {
345
+ const errors = [];
346
+ for (const component of [...startedComponents].reverse()) {
347
+ try {
348
+ await component.component.stop();
349
+ } catch (error) {
350
+ errors.push(error);
351
+ this.diagnostics.push(createUnknownFailureIssue(component.component.id, 'stop', error));
352
+ }
353
+ }
354
+ if (errors.length > 0) {
355
+ throw new AggregateError(errors, 'One or more platform components failed to stop cleanly.');
356
+ }
357
+ }
358
+ }
359
+
360
+ /**
361
+ * Creates a {@link RuntimePlatformShell} instance to manage platform component lifecycles.
362
+ *
363
+ * @param components - The platform component inputs to register in the shell.
364
+ * @returns A new {@link RuntimePlatformShell} instance.
365
+ */
366
+ export function createRuntimePlatformShell(components) {
367
+ return RuntimePlatformShell.fromInputs(components);
368
+ }
@@ -0,0 +1,17 @@
1
+ export type RequestAbortContext = {
2
+ controller: AbortController;
3
+ cleanup(): void;
4
+ signal: AbortSignal;
5
+ };
6
+ export type ActiveRequestTransaction = {
7
+ abort(reason?: unknown): void;
8
+ settled: Promise<void>;
9
+ };
10
+ export type ActiveRequestTransactionHandle = {
11
+ active: ActiveRequestTransaction;
12
+ settle(): void;
13
+ };
14
+ export declare function createRequestAbortContext(signal?: AbortSignal): RequestAbortContext;
15
+ export declare function trackActiveRequestTransaction(activeRequestTransactions: Set<ActiveRequestTransaction>, controller: AbortController): ActiveRequestTransactionHandle;
16
+ export declare function untrackActiveRequestTransaction(activeRequestTransactions: Set<ActiveRequestTransaction>, handle: ActiveRequestTransactionHandle): void;
17
+ //# sourceMappingURL=request-transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-transaction.d.ts","sourceRoot":"","sources":["../src/request-transaction.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,eAAe,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,MAAM,EAAE,wBAAwB,CAAC;IACjC,MAAM,IAAI,IAAI,CAAC;CAChB,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,mBAAmB,CAiBnF;AAED,wBAAgB,6BAA6B,CAC3C,yBAAyB,EAAE,GAAG,CAAC,wBAAwB,CAAC,EACxD,UAAU,EAAE,eAAe,GAC1B,8BAA8B,CAgBhC;AAED,wBAAgB,+BAA+B,CAC7C,yBAAyB,EAAE,GAAG,CAAC,wBAAwB,CAAC,EACxD,MAAM,EAAE,8BAA8B,GACrC,IAAI,CAGN"}
@@ -0,0 +1,39 @@
1
+ export function createRequestAbortContext(signal) {
2
+ const controller = new AbortController();
3
+ const forwardAbort = () => controller.abort(signal?.reason);
4
+ if (signal?.aborted) {
5
+ forwardAbort();
6
+ } else {
7
+ signal?.addEventListener('abort', forwardAbort, {
8
+ once: true
9
+ });
10
+ }
11
+ return {
12
+ controller,
13
+ cleanup: () => {
14
+ signal?.removeEventListener('abort', forwardAbort);
15
+ },
16
+ signal: controller.signal
17
+ };
18
+ }
19
+ export function trackActiveRequestTransaction(activeRequestTransactions, controller) {
20
+ let settle;
21
+ const settled = new Promise(resolve => {
22
+ settle = resolve;
23
+ });
24
+ const active = {
25
+ abort(reason) {
26
+ controller.abort(reason);
27
+ },
28
+ settled
29
+ };
30
+ activeRequestTransactions.add(active);
31
+ return {
32
+ active,
33
+ settle
34
+ };
35
+ }
36
+ export function untrackActiveRequestTransaction(activeRequestTransactions, handle) {
37
+ activeRequestTransactions.delete(handle.active);
38
+ handle.settle();
39
+ }
@@ -0,0 +1,27 @@
1
+ import type { Token } from '@fluojs/core';
2
+ import type { Container } from '@fluojs/di';
3
+ import type { HttpApplicationAdapter } from '@fluojs/http';
4
+ import type { ApplicationLogger } from './types.js';
5
+ import type { CompiledModule } from './types.js';
6
+ import type { PlatformShell } from './platform-contract.js';
7
+ /**
8
+ * Injection token for the application logger.
9
+ */
10
+ export declare const APPLICATION_LOGGER: Token<ApplicationLogger>;
11
+ /**
12
+ * Injection token for the runtime container.
13
+ */
14
+ export declare const RUNTIME_CONTAINER: Token<Container>;
15
+ /**
16
+ * Injection token for the compiled module list.
17
+ */
18
+ export declare const COMPILED_MODULES: Token<readonly CompiledModule[]>;
19
+ /**
20
+ * Injection token for the HTTP application adapter.
21
+ */
22
+ export declare const HTTP_APPLICATION_ADAPTER: Token<HttpApplicationAdapter>;
23
+ /**
24
+ * Injection token for the platform shell.
25
+ */
26
+ export declare const PLATFORM_SHELL: Token<PlatformShell>;
27
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,iBAAiB,CAAiD,CAAC;AAE1G;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,SAAS,CAA+B,CAAC;AAE/E;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,SAAS,cAAc,EAAE,CAA8B,CAAC;AAE7F;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,KAAK,CAAC,sBAAsB,CAAsC,CAAC;AAE1G;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,aAAa,CAA4B,CAAC"}
package/dist/tokens.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Injection token for the application logger.
3
+ */
4
+ export const APPLICATION_LOGGER = Symbol.for('fluo.runtime.application-logger');
5
+
6
+ /**
7
+ * Injection token for the runtime container.
8
+ */
9
+ export const RUNTIME_CONTAINER = Symbol('RUNTIME_CONTAINER');
10
+
11
+ /**
12
+ * Injection token for the compiled module list.
13
+ */
14
+ export const COMPILED_MODULES = Symbol('COMPILED_MODULES');
15
+
16
+ /**
17
+ * Injection token for the HTTP application adapter.
18
+ */
19
+ export const HTTP_APPLICATION_ADAPTER = Symbol('HTTP_APPLICATION_ADAPTER');
20
+
21
+ /**
22
+ * Injection token for the platform shell.
23
+ */
24
+ export const PLATFORM_SHELL = Symbol('PLATFORM_SHELL');