@fluojs/studio 1.0.8 → 2.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.
@@ -0,0 +1 @@
1
+ :root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;color:#e5e7eb;background:#070b16;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}*{box-sizing:border-box}body{color:#e5e7eb;background:radial-gradient(circle at 0 0,#3b82f638,#0000 34rem),radial-gradient(circle at 80% 10%,#0ea5e929,#0000 28rem),linear-gradient(#07101f 0%,#0b1020 55%,#070b16 100%);min-height:100vh;margin:0}button,input{font:inherit}main{width:min(1480px,100vw - 32px);margin:0 auto;padding:28px 0 48px}h1,h2,h3,h4,p{margin-top:0}h1{letter-spacing:-.065em;margin-bottom:12px;font-size:clamp(34px,5vw,68px);line-height:.95}h2{letter-spacing:-.03em;margin-bottom:10px;font-size:22px}h3{margin-bottom:8px}p{line-height:1.65}code{color:#bfdbfe;background:#0f172ad1;border:1px solid #94a3b842;border-radius:8px;padding:2px 7px}.studio-hero{background:linear-gradient(135deg,#0f172ac2,#1e293b94);border:1px solid #93c5fd33;border-radius:28px;grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:24px;margin-bottom:18px;padding:32px;display:grid;box-shadow:0 28px 90px #00000047}.studio-hero p{color:#b6c4d8;max-width:820px}.hero-command{white-space:nowrap;background:#0f172ae6;border:1px solid #60a5fa6b;border-radius:18px;padding:14px 18px;box-shadow:inset 0 1px #ffffff0d}.card{background:linear-gradient(#0f172ae0,#111827d1);border:1px solid #94a3b833;border-radius:22px;margin-bottom:16px;padding:18px;box-shadow:0 20px 80px #00000038}.section-title-row{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.eyebrow{color:#93c5fd;letter-spacing:.12em;text-transform:uppercase;margin:0 0 6px;font-size:12px;font-weight:800}.mode-badge,.status-pill,.chip{color:#cbd5e1;background:#0f172ab8;border:1px solid #94a3b83d;border-radius:999px;align-items:center;padding:5px 10px;font-size:12px;line-height:1.2;display:inline-flex}.mode-badge{color:#bfdbfe}.status-pill-success{color:#bbf7d0;border-color:#22c55e5c}.status-pill-warning{color:#fde68a;border-color:#f59e0b6b}.status-pill-danger{color:#fecaca;border-color:#f871716b}.status-pill-accent{color:#bfdbfe;border-color:#60a5fa6b}.status-pill-muted{color:#94a3b8}.chips{flex-wrap:wrap;gap:7px;margin-bottom:10px;display:flex}.muted{color:#94a3b8}.notice{color:#93c5fd;margin:12px 0 0}.actions{flex-wrap:wrap;gap:8px;margin-top:12px;display:flex}button{color:#fff;cursor:pointer;background:linear-gradient(#2563eb,#1d4ed8);border:1px solid #60a5fa52;border-radius:12px;padding:9px 13px}button:disabled{cursor:not-allowed;background:#475569;border-color:#64748b47}button:hover:not(:disabled),button:focus-visible:not(:disabled){border-color:#93c5fdcc;outline:none;transform:translateY(-1px)}label{margin-bottom:10px;display:block}input[type=text]{color:#e5e7eb;background:#0f172ad1;border:1px solid #94a3b847;border-radius:12px;width:100%;margin-top:6px;padding:10px 12px}input[type=file]{border:1px dashed #94a3b85c;border-radius:14px;width:100%;padding:16px}.filter-row{flex-wrap:wrap;align-items:center;gap:8px 12px;margin-bottom:10px;display:flex}.filter-row span{color:#cbd5e1;font-weight:700}.uploader.drag-active{border-color:#60a5fa;box-shadow:inset 0 0 0 2px #60a5fa59}.live-connection{position:relative;overflow:hidden}.live-connection:before{content:"";pointer-events:none;background:radial-gradient(circle at 0 0,#22d3ee24,#0000 26rem);position:absolute;inset:0}.live-status-main{justify-content:space-between;align-items:flex-start;gap:18px;display:flex;position:relative}.connection-orb-wrap{text-transform:uppercase;justify-items:center;gap:8px;min-width:120px;display:grid}.connection-orb{background:#64748b;border-radius:999px;width:22px;height:22px;display:block;box-shadow:0 0 30px #64748bcc}.connection-connected .connection-orb{background:#22c55e;box-shadow:0 0 35px #22c55ec7}.connection-connecting .connection-orb,.connection-reconnecting .connection-orb,.connection-restarting .connection-orb{background:#f59e0b;box-shadow:0 0 35px #f59e0bcc}.connection-stale .connection-orb,.connection-error .connection-orb,.connection-disconnected .connection-orb{background:#ef4444;box-shadow:0 0 35px #ef4444c7}.dashboard-grid{grid-template-columns:minmax(0,1.25fr) minmax(360px,.75fr);align-items:start;gap:16px;display:grid}.live-graph-card,.timing-card,.live-diagnostics-card{grid-column:1/-1}.live-graph-layout,.routes-layout,.request-layout{grid-template-columns:minmax(0,1fr) minmax(280px,.34fr);gap:16px;display:grid}.live-graph-canvas,#graph-host{background:#020617ad;border:1px solid #94a3b82e;border-radius:18px;min-height:320px;overflow:auto}.live-graph-canvas svg,#graph-host svg{width:100%;min-width:780px}.live-edge{stroke:#64748b99;stroke-width:1.4px}.live-edge-highlighted{stroke:#f59e0b;stroke-width:2.4px}.live-edge-arrow{fill:#64748b}.live-edge-label{fill:#fde68a;paint-order:stroke;stroke:#020617;stroke-width:3px;font-size:11px}.live-node rect{fill:#1e293bf5;stroke:#94a3b873;stroke-width:1.2px}.live-node text{fill:#e5e7eb;text-anchor:middle;pointer-events:none;font-size:11px}.live-node .live-node-kind{fill:#94a3b8;font-size:10px}.live-node-module rect,.live-node-active rect{fill:#1e40afeb}.live-node-provider rect{fill:#14532de0}.live-node-controller rect{fill:#5b21b6e0}.live-node-route rect{fill:#0c4a6ee0}.live-node-external rect,.live-node-platform rect{fill:#475569e0}.live-node-selected rect{stroke:#fbbf24;stroke-width:3px}.live-node-related rect{stroke:#38bdf8;stroke-width:2.2px}.live-graph-details,.route-detail,.request-detail{background:#0f172aa8;border:1px solid #94a3b82e;border-radius:18px;padding:14px}.edge-list,.route-list,.request-timeline{gap:8px;display:grid}.edge-row,.route-row,.request-row,.connection-button{color:#e5e7eb;text-align:left;background:#0f172adb;border-color:#94a3b82e;gap:4px;width:100%;display:grid}.edge-row span,.route-row small,.request-row small,.connection-button small{color:#94a3b8}.route-row-selected,.request-row-selected{border-color:#60a5fa;box-shadow:inset 0 0 0 1px #60a5fa3d}.method{color:#bfdbfe;background:#60a5fa29;border-radius:999px;width:fit-content;padding:3px 7px;font-size:11px;font-weight:800}.request-row-danger{border-color:#f871716b}.request-row-success{border-color:#22c55e52}.request-row-accent{border-color:#60a5fa5c}.timing-grid{grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:16px;display:grid}.timing-total{background:#0f172aa8;border:1px solid #94a3b82e;border-radius:14px;justify-content:space-between;align-items:baseline;margin-bottom:10px;padding:10px 12px;display:flex}table{border-collapse:collapse;width:100%}th,td{text-align:left;border-bottom:1px solid #94a3b82e;padding:8px 6px;font-size:13px}pre{background:#020617b8;border:1px solid #94a3b82e;border-radius:14px;max-height:340px;padding:14px;overflow:auto}.split-grid,.section-pair{grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:16px;display:grid}.empty-state{color:#94a3b8;border:1px dashed #94a3b852;border-radius:16px;place-items:start;gap:4px;padding:18px;display:grid}.empty-state strong{color:#e5e7eb}.edge-line{stroke:#64748b;stroke-width:1.6px}.edge-selected{stroke:#f59e0b;stroke-width:2.6px}.edge-arrow{fill:#64748b}.module-node{fill:#1e293b;stroke:#64748b;stroke-width:1.5px;cursor:pointer}.module-node:focus-visible{stroke:#60a5fa;stroke-width:3px;outline:none}.module-root{stroke:#3b82f6;stroke-width:2.6px}.component-ready{fill:#14532d}.component-degraded{fill:#7c2d12}.component-not-ready{fill:#7f1d1d}.component-external{fill:#312e81;cursor:default}.module-selected{stroke:#f59e0b;stroke-width:3px}.module-neighbor{stroke:#38bdf8;stroke-width:2.6px}.module-dependent{stroke:#a78bfa;stroke-width:2.6px}.module-label{fill:#e5e7eb;pointer-events:none;font-size:11px}.diagnostics-list{gap:12px;display:grid}.issue{margin-bottom:0}.issue.severity-error,.inline-diagnostic.severity-error{border-color:#ef4444}.issue.severity-warning{border-color:#f59e0b}.issue.severity-info{border-color:#3b82f6}.inline-diagnostic{background:#7f1d1d3d;border:1px solid #f8717161;border-radius:14px;padding:12px}a{color:#93c5fd}.inspector-card{background:linear-gradient(135deg,#0f172af5,#111827eb)}.connection-hero{background:#0f172ad1;border:1px solid #94a3b833;border-radius:16px;flex-wrap:wrap;justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:14px;padding:14px;display:flex}.connection-metrics{flex-wrap:wrap;gap:8px;display:flex}.connection-metrics span,.connection-pill{color:#cbd5e1;background:#111827e0;border:1px solid #94a3b83d;border-radius:999px;padding:6px 10px;font-size:12px}.connection-grid{grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px;display:grid}.connection-group h4{margin:0 0 8px}.connection-button:hover,.connection-button:focus-visible{border-color:#60a5fa;outline:none}.connection-button span,.connection-button small{display:block}.external-pill{margin:0 6px 6px 0;display:inline-block}.connection-diagnostic{border-left:3px solid #64748b;margin-bottom:8px;padding:8px 0 8px 10px}.connection-diagnostic.severity-error{border-left-color:#ef4444}.connection-diagnostic.severity-warning{border-left-color:#f59e0b}.connection-diagnostic.severity-info{border-left-color:#3b82f6}.connection-diagnostic span{color:#94a3b8;margin-top:2px;font-size:12px;display:block}.connection-diagnostic p{margin:6px 0 0}@media (width<=960px){main{width:min(100vw - 20px,920px);padding-top:14px}.studio-hero,.dashboard-grid,.live-graph-layout,.routes-layout,.request-layout{grid-template-columns:1fr}.hero-command{width:fit-content}}
@@ -1,11 +1,91 @@
1
- import type { BootstrapTimingDiagnostics, PlatformDiagnosticIssue, PlatformShellSnapshot, PlatformSnapshot } from '@fluojs/runtime';
2
- export type { PlatformDiagnosticIssue, PlatformShellSnapshot } from '@fluojs/runtime';
3
1
  /**
4
- * Readiness statuses supported by Studio snapshot filtering and graph annotations.
2
+ * Runtime-neutral diagnostics contract consumed by Studio inspect artifacts.
3
+ *
4
+ * Runtime produces values with this structural shape, but Studio owns the
5
+ * consumer-side declaration so its Node engine support is not coupled to the
6
+ * runtime package's engine range.
5
7
  */
6
- export type PlatformReadinessStatus = PlatformSnapshot['readiness']['status'];
8
+ export type PlatformReadinessStatus = 'ready' | 'not-ready' | 'degraded';
9
+ /** Health statuses supported by Studio snapshot parsing. */
10
+ export type PlatformHealthStatus = 'healthy' | 'unhealthy' | 'degraded';
11
+ /** Lifecycle states supported by Studio component diagnostics. */
12
+ export type PlatformState = 'created' | 'validated' | 'starting' | 'ready' | 'degraded' | 'stopping' | 'stopped' | 'failed';
13
+ /** Outcome for one named readiness or health probe in a platform report. */
14
+ export interface PlatformCheckResult {
15
+ name: string;
16
+ status: 'pass' | 'fail' | 'degraded';
17
+ message?: string;
18
+ }
19
+ /** Readiness semantics consumed from a platform inspection artifact. */
20
+ export interface PlatformReadinessReport {
21
+ status: PlatformReadinessStatus;
22
+ critical: boolean;
23
+ reason?: string;
24
+ checks?: PlatformCheckResult[];
25
+ }
26
+ /** Health semantics consumed from a platform inspection artifact. */
27
+ export interface PlatformHealthReport {
28
+ status: PlatformHealthStatus;
29
+ reason?: string;
30
+ checks?: PlatformCheckResult[];
31
+ }
32
+ /** Machine-readable issue emitted in a platform inspection artifact. */
33
+ export interface PlatformDiagnosticIssue {
34
+ code: string;
35
+ severity: 'error' | 'warning' | 'info';
36
+ componentId: string;
37
+ message: string;
38
+ cause?: string;
39
+ fixHint?: string;
40
+ dependsOn?: string[];
41
+ docsUrl?: string;
42
+ }
43
+ /** Component snapshot consumed by Studio graph and diagnostics views. */
44
+ export interface PlatformSnapshot {
45
+ id: string;
46
+ kind: string;
47
+ state: PlatformState;
48
+ readiness: {
49
+ status: PlatformReadinessStatus;
50
+ critical: boolean;
51
+ reason?: string;
52
+ };
53
+ health: {
54
+ status: PlatformHealthStatus;
55
+ reason?: string;
56
+ };
57
+ dependencies: string[];
58
+ telemetry: {
59
+ namespace: string;
60
+ tags: Record<string, string>;
61
+ };
62
+ ownership: {
63
+ ownsResources: boolean;
64
+ externallyManaged: boolean;
65
+ };
66
+ details: Record<string, unknown>;
67
+ }
68
+ /** Aggregate platform snapshot consumed by Studio static diagnostics. */
69
+ export interface PlatformShellSnapshot {
70
+ generatedAt: string;
71
+ readiness: PlatformReadinessReport;
72
+ health: PlatformHealthReport;
73
+ components: PlatformSnapshot[];
74
+ diagnostics: PlatformDiagnosticIssue[];
75
+ }
76
+ /** One bootstrap timing phase represented in a Studio artifact. */
77
+ export interface BootstrapTimingPhase {
78
+ durationMs: number;
79
+ name: 'bootstrap_module' | 'register_runtime_tokens' | 'resolve_lifecycle_instances' | 'run_bootstrap_lifecycle' | 'create_dispatcher';
80
+ }
81
+ /** Bootstrap timing diagnostics consumed by Studio reports and live events. */
82
+ export interface BootstrapTimingDiagnostics {
83
+ phases: BootstrapTimingPhase[];
84
+ totalMs: number;
85
+ version: 1;
86
+ }
7
87
  /**
8
- * Diagnostic severities supported by Studio snapshot filtering.
88
+ * Readiness statuses supported by Studio snapshot filtering and graph annotations.
9
89
  */
10
90
  export type PlatformDiagnosticSeverity = PlatformDiagnosticIssue['severity'];
11
91
  /**
@@ -25,7 +105,7 @@ export interface StudioReportSummary {
25
105
  */
26
106
  export interface StudioReportArtifact {
27
107
  generatedAt: string;
28
- snapshot: PlatformShellSnapshot;
108
+ snapshot: StudioInspectionSnapshot;
29
109
  summary: StudioReportSummary;
30
110
  timing: BootstrapTimingDiagnostics;
31
111
  version: 1;
@@ -35,7 +115,7 @@ export interface StudioReportArtifact {
35
115
  */
36
116
  export interface StudioPayload {
37
117
  report?: StudioReportArtifact;
38
- snapshot?: PlatformShellSnapshot;
118
+ snapshot?: StudioInspectionSnapshot;
39
119
  timing?: BootstrapTimingDiagnostics;
40
120
  }
41
121
  /** Live Studio graph node kinds emitted by runtime-connected devtools. */
@@ -59,16 +139,37 @@ export interface StudioGraphEdge {
59
139
  metadata?: Record<string, unknown>;
60
140
  to: string;
61
141
  }
142
+ /** Route kinds accepted by the Studio live wire contract. */
143
+ export type StudioRouteKind = string;
62
144
  /** Route descriptor projected into the live Studio UI. */
63
145
  export interface StudioRouteDescriptor {
64
146
  controller: string;
147
+ graphNodeId?: string;
65
148
  handler: string;
66
149
  id: string;
150
+ kind?: StudioRouteKind;
67
151
  method: string;
68
152
  module?: string;
153
+ params?: string[];
69
154
  path: string;
70
155
  version?: string;
71
156
  }
157
+ /** Route descriptor returned after Studio normalizes legacy wire defaults. */
158
+ export interface StudioNormalizedRouteDescriptor extends Omit<StudioRouteDescriptor, 'graphNodeId' | 'kind' | 'params'> {
159
+ graphNodeId: string;
160
+ kind: StudioRouteKind;
161
+ params: string[];
162
+ }
163
+ /** Route descriptor emitted by Runtime producers after legacy defaults are resolved. */
164
+ export type StudioProducerRouteDescriptor = StudioNormalizedRouteDescriptor;
165
+ /** Static inspect snapshot with optional compiled route diagnostics. */
166
+ export interface StudioInspectionSnapshot extends PlatformShellSnapshot {
167
+ routes?: StudioRouteDescriptor[];
168
+ }
169
+ /** Static inspect snapshot returned after route entries are normalized. */
170
+ export interface StudioParsedInspectionSnapshot extends Omit<StudioInspectionSnapshot, 'routes'> {
171
+ routes?: StudioNormalizedRouteDescriptor[];
172
+ }
72
173
  /** Request lifecycle status understood by the live Studio request-flow panel. */
73
174
  export type StudioRequestStatus = 'started' | 'matched' | 'succeeded' | 'failed' | 'finished';
74
175
  /** Request trace emitted by runtime observers without request/response bodies. */
@@ -113,6 +214,12 @@ export interface StudioLiveSnapshot {
113
214
  timing?: BootstrapTimingDiagnostics;
114
215
  version: 1;
115
216
  }
217
+ /** Live snapshot returned after route entries are normalized. */
218
+ export interface StudioParsedLiveSnapshot extends Omit<StudioLiveSnapshot, 'routes'> {
219
+ routes: StudioNormalizedRouteDescriptor[];
220
+ }
221
+ /** Live snapshot emitted by Runtime producers with normalized route fields. */
222
+ export type StudioProducerLiveSnapshot = StudioParsedLiveSnapshot;
116
223
  /** Studio connection status presented by the live UI. */
117
224
  export type StudioConnectionStatus = 'connected' | 'connecting' | 'disconnected' | 'error' | 'reconnecting' | 'restarting' | 'stale' | 'static';
118
225
  /** Studio connection state used by sidecar/UI state machines. */
@@ -158,6 +265,10 @@ export interface StudioDisconnectPayload {
158
265
  }
159
266
  /** Event envelope exchanged between runtime, CLI sidecar, and Studio UI. */
160
267
  export type StudioLiveEvent = StudioLiveEventBase<'disconnect', StudioDisconnectPayload> | StudioLiveEventBase<'diagnostic', StudioLiveDiagnostic> | StudioLiveEventBase<'heartbeat', StudioHeartbeatPayload> | StudioLiveEventBase<'request', StudioRequestTrace> | StudioLiveEventBase<'restart', StudioRestartPayload> | StudioLiveEventBase<'snapshot', StudioLiveSnapshot> | StudioLiveEventBase<'timing', BootstrapTimingDiagnostics>;
268
+ /** Live event returned after Studio validates and normalizes its payload. */
269
+ export type StudioParsedLiveEvent = StudioLiveEventBase<'disconnect', StudioDisconnectPayload> | StudioLiveEventBase<'diagnostic', StudioLiveDiagnostic> | StudioLiveEventBase<'heartbeat', StudioHeartbeatPayload> | StudioLiveEventBase<'request', StudioRequestTrace> | StudioLiveEventBase<'restart', StudioRestartPayload> | StudioLiveEventBase<'snapshot', StudioParsedLiveSnapshot> | StudioLiveEventBase<'timing', BootstrapTimingDiagnostics>;
270
+ /** Live event emitted by Runtime producers with normalized snapshot routes. */
271
+ export type StudioProducerLiveEvent = StudioLiveEventBase<'disconnect', StudioDisconnectPayload> | StudioLiveEventBase<'diagnostic', StudioLiveDiagnostic> | StudioLiveEventBase<'heartbeat', StudioHeartbeatPayload> | StudioLiveEventBase<'request', StudioRequestTrace> | StudioLiveEventBase<'restart', StudioRestartPayload> | StudioLiveEventBase<'snapshot', StudioProducerLiveSnapshot> | StudioLiveEventBase<'timing', BootstrapTimingDiagnostics>;
161
272
  /**
162
273
  * Filter state applied to the loaded platform snapshot inside Studio.
163
274
  */
@@ -170,9 +281,19 @@ export interface FilterState {
170
281
  * Parsed Studio payload together with the original JSON source.
171
282
  */
172
283
  export interface ParsedPayload {
173
- payload: StudioPayload;
284
+ payload: StudioParsedPayload;
174
285
  rawJson: string;
175
286
  }
287
+ /** Report artifact returned after compiled route entries are normalized. */
288
+ export interface StudioParsedReportArtifact extends Omit<StudioReportArtifact, 'snapshot'> {
289
+ snapshot: StudioParsedInspectionSnapshot;
290
+ }
291
+ /** Studio payload returned after compiled route entries are normalized. */
292
+ export interface StudioParsedPayload {
293
+ report?: StudioParsedReportArtifact;
294
+ snapshot?: StudioParsedInspectionSnapshot;
295
+ timing?: BootstrapTimingDiagnostics;
296
+ }
176
297
  /**
177
298
  * Validates a runtime-connected Studio event envelope.
178
299
  *
@@ -180,14 +301,14 @@ export interface ParsedPayload {
180
301
  * @returns The typed Studio live event.
181
302
  * @throws Error when the event does not match the live Studio contract.
182
303
  */
183
- export declare function validateStudioLiveEvent(value: unknown): StudioLiveEvent;
304
+ export declare function validateStudioLiveEvent(value: unknown): StudioParsedLiveEvent;
184
305
  /**
185
306
  * Parses a live Studio event JSON envelope from the runtime sidecar stream.
186
307
  *
187
308
  * @param rawJson Raw JSON encoded event.
188
309
  * @returns The validated Studio live event.
189
310
  */
190
- export declare function parseStudioLiveEvent(rawJson: string): StudioLiveEvent;
311
+ export declare function parseStudioLiveEvent(rawJson: string): StudioParsedLiveEvent;
191
312
  /**
192
313
  * Runtime-safe type guard for Studio live event envelopes.
193
314
  *
@@ -210,7 +331,7 @@ export declare function parseStudioPayload(rawJson: string): ParsedPayload;
210
331
  * @param filter - Active readiness, severity, and query filters.
211
332
  * @returns A filtered snapshot containing only the matching components and diagnostics.
212
333
  */
213
- export declare function applyFilters(snapshot: PlatformShellSnapshot, filter: FilterState): PlatformShellSnapshot;
334
+ export declare function applyFilters<TSnapshot extends PlatformShellSnapshot>(snapshot: TSnapshot, filter: FilterState): TSnapshot;
214
335
  /**
215
336
  * Renders the loaded platform snapshot as a Mermaid dependency graph.
216
337
  *
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
package/dist/contracts.js CHANGED
@@ -1,9 +1,33 @@
1
1
  /**
2
- * Readiness statuses supported by Studio snapshot filtering and graph annotations.
2
+ * Runtime-neutral diagnostics contract consumed by Studio inspect artifacts.
3
+ *
4
+ * Runtime produces values with this structural shape, but Studio owns the
5
+ * consumer-side declaration so its Node engine support is not coupled to the
6
+ * runtime package's engine range.
3
7
  */
4
8
 
9
+ /** Health statuses supported by Studio snapshot parsing. */
10
+
11
+ /** Lifecycle states supported by Studio component diagnostics. */
12
+
13
+ /** Outcome for one named readiness or health probe in a platform report. */
14
+
15
+ /** Readiness semantics consumed from a platform inspection artifact. */
16
+
17
+ /** Health semantics consumed from a platform inspection artifact. */
18
+
19
+ /** Machine-readable issue emitted in a platform inspection artifact. */
20
+
21
+ /** Component snapshot consumed by Studio graph and diagnostics views. */
22
+
23
+ /** Aggregate platform snapshot consumed by Studio static diagnostics. */
24
+
25
+ /** One bootstrap timing phase represented in a Studio artifact. */
26
+
27
+ /** Bootstrap timing diagnostics consumed by Studio reports and live events. */
28
+
5
29
  /**
6
- * Diagnostic severities supported by Studio snapshot filtering.
30
+ * Readiness statuses supported by Studio snapshot filtering and graph annotations.
7
31
  */
8
32
 
9
33
  /**
@@ -26,8 +50,18 @@
26
50
 
27
51
  /** Serializable edge in the runtime-connected Studio dependency graph. */
28
52
 
53
+ /** Route kinds accepted by the Studio live wire contract. */
54
+
29
55
  /** Route descriptor projected into the live Studio UI. */
30
56
 
57
+ /** Route descriptor returned after Studio normalizes legacy wire defaults. */
58
+
59
+ /** Route descriptor emitted by Runtime producers after legacy defaults are resolved. */
60
+
61
+ /** Static inspect snapshot with optional compiled route diagnostics. */
62
+
63
+ /** Static inspect snapshot returned after route entries are normalized. */
64
+
31
65
  /** Request lifecycle status understood by the live Studio request-flow panel. */
32
66
 
33
67
  /** Request trace emitted by runtime observers without request/response bodies. */
@@ -36,6 +70,10 @@
36
70
 
37
71
  /** Live snapshot consumed by the React Studio shell and sidecar replay cache. */
38
72
 
73
+ /** Live snapshot returned after route entries are normalized. */
74
+
75
+ /** Live snapshot emitted by Runtime producers with normalized route fields. */
76
+
39
77
  /** Studio connection status presented by the live UI. */
40
78
 
41
79
  /** Studio connection state used by sidecar/UI state machines. */
@@ -58,6 +96,10 @@
58
96
 
59
97
  /** Event envelope exchanged between runtime, CLI sidecar, and Studio UI. */
60
98
 
99
+ /** Live event returned after Studio validates and normalizes its payload. */
100
+
101
+ /** Live event emitted by Runtime producers with normalized snapshot routes. */
102
+
61
103
  /**
62
104
  * Filter state applied to the loaded platform snapshot inside Studio.
63
105
  */
@@ -66,6 +108,10 @@
66
108
  * Parsed Studio payload together with the original JSON source.
67
109
  */
68
110
 
111
+ /** Report artifact returned after compiled route entries are normalized. */
112
+
113
+ /** Studio payload returned after compiled route entries are normalized. */
114
+
69
115
  function isRecord(value) {
70
116
  return typeof value === 'object' && value !== null;
71
117
  }
@@ -126,6 +172,16 @@ function isStudioGraphEdgeKind(value) {
126
172
  function isStudioRequestStatus(value) {
127
173
  return value === 'started' || value === 'matched' || value === 'succeeded' || value === 'failed' || value === 'finished';
128
174
  }
175
+ const bootstrapTimingPhaseNames = {
176
+ bootstrap_module: true,
177
+ register_runtime_tokens: true,
178
+ resolve_lifecycle_instances: true,
179
+ run_bootstrap_lifecycle: true,
180
+ create_dispatcher: true
181
+ };
182
+ function isBootstrapTimingPhaseName(value) {
183
+ return typeof value === 'string' && Object.hasOwn(bootstrapTimingPhaseNames, value);
184
+ }
129
185
  function validateStudioGraphNode(value) {
130
186
  if (!isRecord(value) || !isStudioGraphNodeKind(value.kind)) {
131
187
  throw new Error('Invalid Studio live graph node payload.');
@@ -171,11 +227,23 @@ function validateStudioRouteDescriptor(value) {
171
227
  if (!isRecord(value)) {
172
228
  throw new Error('Invalid Studio live route descriptor payload.');
173
229
  }
230
+ const kind = value.kind;
231
+ if (kind !== undefined && typeof kind !== 'string') {
232
+ throw new Error('Invalid Studio live route descriptor kind payload.');
233
+ }
234
+ const params = value.params;
235
+ if (params !== undefined && !isStringArray(params)) {
236
+ throw new Error('Invalid Studio live route descriptor params payload.');
237
+ }
238
+ const id = validateString(value.id, 'Invalid Studio live route descriptor payload.');
174
239
  const route = {
175
240
  controller: validateString(value.controller, 'Invalid Studio live route descriptor payload.'),
241
+ graphNodeId: validateOptionalString(value.graphNodeId, 'Invalid Studio live route descriptor graph node payload.') ?? `route:${id.replaceAll(/[^a-zA-Z0-9_.:-]/g, '_') || 'anonymous'}`,
176
242
  handler: validateString(value.handler, 'Invalid Studio live route descriptor payload.'),
177
- id: validateString(value.id, 'Invalid Studio live route descriptor payload.'),
243
+ id,
244
+ kind: kind ?? 'http',
178
245
  method: validateString(value.method, 'Invalid Studio live route descriptor payload.'),
246
+ params: params === undefined ? [] : [...params],
179
247
  path: validateString(value.path, 'Invalid Studio live route descriptor payload.')
180
248
  };
181
249
  const moduleName = validateOptionalString(value.module, 'Invalid Studio live route descriptor module payload.');
@@ -485,7 +553,14 @@ function validateSnapshot(value) {
485
553
  throw new Error('Invalid optional diagnostics issue fields in platform snapshot payload.');
486
554
  }
487
555
  }
488
- return value;
556
+ if (value.routes !== undefined && !Array.isArray(value.routes)) {
557
+ throw new Error('Invalid route diagnostics in platform snapshot payload.');
558
+ }
559
+ const snapshot = value;
560
+ return value.routes === undefined ? snapshot : {
561
+ ...snapshot,
562
+ routes: value.routes.map(route => validateStudioRouteDescriptor(route))
563
+ };
489
564
  }
490
565
  function validateTiming(value) {
491
566
  if (!isRecord(value)) {
@@ -498,7 +573,7 @@ function validateTiming(value) {
498
573
  throw new Error('Invalid bootstrap timing payload.');
499
574
  }
500
575
  for (const phase of value.phases) {
501
- if (!isRecord(phase) || typeof phase.name !== 'string' || typeof phase.durationMs !== 'number') {
576
+ if (!isRecord(phase) || !isBootstrapTimingPhaseName(phase.name) || typeof phase.durationMs !== 'number') {
502
577
  throw new Error('Invalid phase entry in bootstrap timing payload.');
503
578
  }
504
579
  }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { applyFilters, parseStudioLiveEvent, parseStudioPayload, renderMermaid, validateStudioLiveEvent, isStudioLiveEvent, type FilterState, type ParsedPayload, type PlatformDiagnosticIssue, type PlatformDiagnosticSeverity, type PlatformReadinessStatus, type StudioReportArtifact, type StudioReportSummary, type PlatformShellSnapshot, type StudioPayload, type StudioConnectionState, type StudioConnectionStatus, type StudioDisconnectPayload, type StudioGraphEdge, type StudioGraphEdgeKind, type StudioGraphNode, type StudioGraphNodeKind, type StudioHeartbeatPayload, type StudioLiveDiagnostic, type StudioLiveEvent, type StudioLiveEventBase, type StudioLiveEventSource, type StudioLiveSnapshot, type StudioRequestStatus, type StudioRequestTrace, type StudioRestartPayload, type StudioRouteDescriptor, } from './contracts.js';
1
+ export { applyFilters, type FilterState, isStudioLiveEvent, type ParsedPayload, type PlatformDiagnosticIssue, type PlatformDiagnosticSeverity, type PlatformReadinessStatus, type PlatformShellSnapshot, parseStudioLiveEvent, parseStudioPayload, renderMermaid, type StudioConnectionState, type StudioConnectionStatus, type StudioDisconnectPayload, type StudioGraphEdge, type StudioGraphEdgeKind, type StudioGraphNode, type StudioGraphNodeKind, type StudioHeartbeatPayload, type StudioInspectionSnapshot, type StudioLiveDiagnostic, type StudioLiveEvent, type StudioLiveEventBase, type StudioLiveEventSource, type StudioLiveSnapshot, type StudioNormalizedRouteDescriptor, type StudioParsedInspectionSnapshot, type StudioParsedLiveEvent, type StudioParsedLiveSnapshot, type StudioParsedPayload, type StudioParsedReportArtifact, type StudioProducerLiveEvent, type StudioProducerLiveSnapshot, type StudioProducerRouteDescriptor, type StudioPayload, type StudioReportArtifact, type StudioReportSummary, type StudioRequestStatus, type StudioRequestTrace, type StudioRestartPayload, type StudioRouteDescriptor, type StudioRouteKind, validateStudioLiveEvent, } from './contracts.js';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,KAAK,WAAW,EAChB,iBAAiB,EACjB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,+BAA+B,EACpC,KAAK,8BAA8B,EACnC,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC"}
package/dist/index.html CHANGED
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Fluo Studio</title>
7
- <script type="module" crossorigin src="./assets/index-nyR3HCaJ.js"></script>
8
- <link rel="stylesheet" crossorigin href="./assets/index-ort96Zw9.css">
7
+ <script type="module" crossorigin src="./assets/index-BKRrd1IN.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/index-C3sr4y-k.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="app"></div>
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export { applyFilters, parseStudioLiveEvent, parseStudioPayload, renderMermaid, validateStudioLiveEvent, isStudioLiveEvent } from './contracts.js';
1
+ export { applyFilters, isStudioLiveEvent, parseStudioLiveEvent, parseStudioPayload, renderMermaid, validateStudioLiveEvent } from './contracts.js';
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { runStudioViewerCli } from './viewer-server.js';
5
+ const viewerDirectory = dirname(fileURLToPath(import.meta.url));
6
+ void runStudioViewerCli(process.argv.slice(2), viewerDirectory).catch(error => {
7
+ const message = error instanceof Error ? error.message : 'Unknown Studio viewer launch error.';
8
+ process.stderr.write(`${message}\n`);
9
+ process.exitCode = 1;
10
+ });
@@ -0,0 +1,189 @@
1
+ #!/usr/bin/env node
2
+ import { readFile, realpath } from 'node:fs/promises';
3
+ import { createServer } from 'node:http';
4
+ import { extname, resolve, sep } from 'node:path';
5
+ const viewerHost = '127.0.0.1';
6
+ /** Grace period before close destroys incomplete viewer-owned connections. */
7
+ export const viewerServerCloseGracePeriodMs = 1_000;
8
+ const mimeTypes = {
9
+ '.css': 'text/css; charset=utf-8',
10
+ '.html': 'text/html; charset=utf-8',
11
+ '.js': 'text/javascript; charset=utf-8',
12
+ '.svg': 'image/svg+xml'
13
+ };
14
+
15
+ /** Supported parsed command-line request for the packaged Studio viewer. */
16
+
17
+ /** Running local HTTP server for the packaged Studio viewer. */
18
+
19
+ /**
20
+ * Parses command-line arguments for the packaged Studio viewer.
21
+ *
22
+ * @param arguments_ - Arguments passed after the viewer command name.
23
+ * @returns A help or launch request.
24
+ */
25
+ export function parseStudioViewerArguments(arguments_) {
26
+ let port = 0;
27
+ for (let index = 0; index < arguments_.length; index += 1) {
28
+ const argument = arguments_[index];
29
+ switch (argument) {
30
+ case '--help':
31
+ case '-h':
32
+ return {
33
+ kind: 'help'
34
+ };
35
+ case '--port':
36
+ {
37
+ const portArgument = arguments_[index + 1];
38
+ if (portArgument === undefined) {
39
+ throw new Error('Missing port after --port.');
40
+ }
41
+ port = parsePort(portArgument);
42
+ index += 1;
43
+ break;
44
+ }
45
+ default:
46
+ throw new Error(`Unsupported viewer option: ${argument}`);
47
+ }
48
+ }
49
+ return {
50
+ kind: 'launch',
51
+ port
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Starts an HTTP server that serves the installed Studio viewer artifacts.
57
+ *
58
+ * @param options - Local server options and the packaged artifact directory.
59
+ * @returns The running server and its local URL.
60
+ */
61
+ export async function startStudioViewerServer(options) {
62
+ const viewerDirectory = await realpath(resolve(options.viewerDirectory));
63
+ const server = createServer((request, response) => {
64
+ void serveViewerAsset(request, response, viewerDirectory).catch(() => {
65
+ if (!response.headersSent) {
66
+ response.writeHead(500);
67
+ }
68
+ response.end();
69
+ });
70
+ });
71
+ const connections = new Set();
72
+ server.on('connection', socket => {
73
+ connections.add(socket);
74
+ socket.once('close', () => connections.delete(socket));
75
+ });
76
+ await listen(server, options.port);
77
+ const address = server.address();
78
+ if (address === null || typeof address === 'string') {
79
+ throw new Error('Studio viewer did not bind to a TCP port.');
80
+ }
81
+ let terminalClose;
82
+ return {
83
+ url: new URL(`http://${viewerHost}:${String(address.port)}/`),
84
+ close: () => {
85
+ terminalClose ??= close(server, connections);
86
+ return terminalClose;
87
+ }
88
+ };
89
+ }
90
+ async function serveViewerAsset(request, response, viewerDirectory) {
91
+ if (request.method !== 'GET' && request.method !== 'HEAD') {
92
+ response.writeHead(405, {
93
+ allow: 'GET, HEAD'
94
+ }).end();
95
+ return;
96
+ }
97
+ let pathname;
98
+ try {
99
+ pathname = new URL(request.url ?? '/', `http://${viewerHost}`).pathname;
100
+ } catch {
101
+ response.writeHead(400).end();
102
+ return;
103
+ }
104
+ const relativePath = pathname === '/' ? 'index.html' : `.${pathname}`;
105
+ const assetPath = resolve(viewerDirectory, relativePath);
106
+ if (!assetPath.startsWith(`${viewerDirectory}${sep}`)) {
107
+ response.writeHead(404).end();
108
+ return;
109
+ }
110
+ try {
111
+ const resolvedAssetPath = await realpath(assetPath);
112
+ if (!resolvedAssetPath.startsWith(`${viewerDirectory}${sep}`)) {
113
+ response.writeHead(404).end();
114
+ return;
115
+ }
116
+ const content = await readFile(resolvedAssetPath);
117
+ const mimeType = mimeTypes[extname(resolvedAssetPath)] ?? 'application/octet-stream';
118
+ response.writeHead(200, {
119
+ 'content-type': mimeType
120
+ }).end(request.method === 'HEAD' ? undefined : content);
121
+ } catch {
122
+ response.writeHead(404).end();
123
+ }
124
+ }
125
+ function parsePort(value) {
126
+ const port = Number(value);
127
+ if (!Number.isSafeInteger(port) || port < 0 || port > 65_535) {
128
+ throw new Error(`Invalid port: ${value}`);
129
+ }
130
+ return port;
131
+ }
132
+ async function listen(server, port) {
133
+ await new Promise((resolveListen, rejectListen) => {
134
+ server.once('error', rejectListen);
135
+ server.listen({
136
+ host: viewerHost,
137
+ port
138
+ }, () => {
139
+ server.off('error', rejectListen);
140
+ resolveListen();
141
+ });
142
+ });
143
+ }
144
+ async function close(server, connections) {
145
+ const terminalClose = new Promise((resolveClose, rejectClose) => {
146
+ server.close(error => {
147
+ if (error === undefined) {
148
+ resolveClose();
149
+ return;
150
+ }
151
+ rejectClose(error);
152
+ });
153
+ });
154
+ const forceCloseTimer = setTimeout(() => {
155
+ for (const connection of connections) {
156
+ connection.destroy();
157
+ }
158
+ }, viewerServerCloseGracePeriodMs);
159
+ try {
160
+ await terminalClose;
161
+ } finally {
162
+ clearTimeout(forceCloseTimer);
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Runs the executable Studio viewer command against a packaged artifact directory.
168
+ *
169
+ * @param arguments_ - Arguments passed after the executable name.
170
+ * @param viewerDirectory - Installed directory containing the viewer HTML assets.
171
+ * @returns A Promise that resolves after help output or successful local server launch.
172
+ */
173
+ export async function runStudioViewerCli(arguments_, viewerDirectory) {
174
+ const request = parseStudioViewerArguments(arguments_);
175
+ switch (request.kind) {
176
+ case 'help':
177
+ process.stdout.write('Usage: fluo-studio-viewer [--port <0-65535>]\n');
178
+ return;
179
+ case 'launch':
180
+ {
181
+ const server = await startStudioViewerServer({
182
+ port: request.port,
183
+ viewerDirectory
184
+ });
185
+ process.stdout.write(`Fluo Studio viewer: ${server.url.href}\nPress Ctrl+C to stop.\n`);
186
+ return;
187
+ }
188
+ }
189
+ }