@principal-ai/principal-view-react 0.7.9 → 0.7.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/GraphRenderer.d.ts +5 -0
- package/dist/components/GraphRenderer.d.ts.map +1 -1
- package/dist/components/GraphRenderer.js +23 -7
- package/dist/components/GraphRenderer.js.map +1 -1
- package/dist/components/LayerPanel.d.ts +31 -0
- package/dist/components/LayerPanel.d.ts.map +1 -0
- package/dist/components/LayerPanel.js +207 -0
- package/dist/components/LayerPanel.js.map +1 -0
- package/dist/components/TestEventPanel.d.ts +26 -0
- package/dist/components/TestEventPanel.d.ts.map +1 -0
- package/dist/components/TestEventPanel.js +131 -0
- package/dist/components/TestEventPanel.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/nodes/CustomNode.d.ts +1 -0
- package/dist/nodes/CustomNode.d.ts.map +1 -1
- package/dist/nodes/CustomNode.js +33 -7
- package/dist/nodes/CustomNode.js.map +1 -1
- package/package.json +2 -2
- package/src/components/GraphRenderer.tsx +36 -5
- package/src/components/TestEventPanel.tsx +287 -0
- package/src/index.ts +3 -0
- package/src/nodes/CustomNode.tsx +39 -6
- package/src/stories/MultiConfig.stories.tsx +1 -1
- package/src/stories/MultiDirectionalConnections.stories.tsx +0 -1
- package/src/stories/RealTestExecution.stories.tsx +280 -0
- package/src/stories/ValidatedExecution.stories.tsx +158 -0
- package/src/stories/data/graph-converter-test-execution.json +225 -0
- package/src/stories/data/graph-converter-validated-execution.json +58 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import { GraphRenderer } from '../components/GraphRenderer';
|
|
4
|
+
import { TestEventPanel } from '../components/TestEventPanel';
|
|
5
|
+
import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
|
|
6
|
+
import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
|
|
7
|
+
import executionCanvas from '../../../../.principal-views/graph-converter-execution.otel.canvas';
|
|
8
|
+
import validatedSpans from './data/graph-converter-validated-execution.json';
|
|
9
|
+
|
|
10
|
+
const meta = {
|
|
11
|
+
title: 'Features/Validated Execution',
|
|
12
|
+
component: GraphRenderer,
|
|
13
|
+
parameters: {
|
|
14
|
+
layout: 'fullscreen',
|
|
15
|
+
docs: {
|
|
16
|
+
description: {
|
|
17
|
+
component:
|
|
18
|
+
'Demonstrates type-safe event emission with schema validation. The canvas defines expected events, and production code is validated against this schema. Shows how events match the schema defined in graph-converter-execution.otel.canvas.',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
tags: ['autodocs'],
|
|
23
|
+
decorators: [
|
|
24
|
+
(Story) => (
|
|
25
|
+
<ThemeProvider theme={defaultEditorTheme}>
|
|
26
|
+
<div style={{ width: '100vw', height: '100vh', background: '#0a0a0a' }}>
|
|
27
|
+
<Story />
|
|
28
|
+
</div>
|
|
29
|
+
</ThemeProvider>
|
|
30
|
+
),
|
|
31
|
+
],
|
|
32
|
+
} satisfies Meta<typeof GraphRenderer>;
|
|
33
|
+
|
|
34
|
+
export default meta;
|
|
35
|
+
type Story = StoryObj<typeof meta>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Graph visualization of the execution flow with event schema definitions.
|
|
39
|
+
*
|
|
40
|
+
* This canvas defines:
|
|
41
|
+
* - `graph-converter` node with 5 event types
|
|
42
|
+
* - `validation` node with 2 event types
|
|
43
|
+
* - `graph-output` node with 1 event type
|
|
44
|
+
*
|
|
45
|
+
* Each event type has a schema defining:
|
|
46
|
+
* - Required/optional fields
|
|
47
|
+
* - Field types (string, number, boolean, etc.)
|
|
48
|
+
* - Field descriptions
|
|
49
|
+
*
|
|
50
|
+
* See `.principal-views/graph-converter-execution.otel.canvas` for the full schema.
|
|
51
|
+
*/
|
|
52
|
+
export const ExecutionFlow: Story = {
|
|
53
|
+
args: {
|
|
54
|
+
canvas: executionCanvas as ExtendedCanvas,
|
|
55
|
+
showControls: true,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Event panel showing validated execution data.
|
|
61
|
+
*
|
|
62
|
+
* These events were emitted using `createValidatedSpanEmitter()` which:
|
|
63
|
+
* - Validates events against the canvas schema
|
|
64
|
+
* - Ensures required fields are present
|
|
65
|
+
* - Checks field types match the schema
|
|
66
|
+
* - Throws errors in strict mode if validation fails
|
|
67
|
+
*
|
|
68
|
+
* All events in this panel passed schema validation.
|
|
69
|
+
*/
|
|
70
|
+
export const ValidatedEvents: Story = {
|
|
71
|
+
render: () => (
|
|
72
|
+
<div style={{ width: '800px', height: '100vh' }}>
|
|
73
|
+
<TestEventPanel
|
|
74
|
+
spans={validatedSpans as any}
|
|
75
|
+
currentSpanIndex={0}
|
|
76
|
+
currentEventIndex={10} // Show all events
|
|
77
|
+
highlightedPhase={undefined}
|
|
78
|
+
/>
|
|
79
|
+
</div>
|
|
80
|
+
),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Side-by-side view of execution flow and validated events.
|
|
85
|
+
*
|
|
86
|
+
* **How it works:**
|
|
87
|
+
* 1. Canvas defines event schemas (what events should be emitted)
|
|
88
|
+
* 2. Tests use `createValidatedSpanEmitter()` to emit events
|
|
89
|
+
* 3. Events are validated against the schema in strict mode
|
|
90
|
+
* 4. If validation fails, test throws `EventValidationError`
|
|
91
|
+
* 5. If validation passes, events are emitted and collected
|
|
92
|
+
*
|
|
93
|
+
* This ensures production code emits events that match the architecture.
|
|
94
|
+
*/
|
|
95
|
+
export const FlowWithValidation: Story = {
|
|
96
|
+
render: () => (
|
|
97
|
+
<div style={{ display: 'flex', width: '100%', height: '100%' }}>
|
|
98
|
+
{/* Graph Visualization - Left Side */}
|
|
99
|
+
<div style={{ flex: '0 0 60%', height: '100%', position: 'relative' }}>
|
|
100
|
+
<GraphRenderer
|
|
101
|
+
canvas={executionCanvas as ExtendedCanvas}
|
|
102
|
+
showControls={true}
|
|
103
|
+
/>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
{/* Event Panel - Right Side */}
|
|
107
|
+
<div style={{ flex: '0 0 40%', height: '100%', borderLeft: '1px solid #333' }}>
|
|
108
|
+
<div style={{ padding: '20px', color: '#fff', borderBottom: '1px solid #333' }}>
|
|
109
|
+
<h3 style={{ margin: '0 0 10px 0', fontSize: '16px' }}>
|
|
110
|
+
Type-Safe Validated Events
|
|
111
|
+
</h3>
|
|
112
|
+
<p style={{ margin: 0, fontSize: '12px', color: '#888' }}>
|
|
113
|
+
Events validated against canvas schema. See{' '}
|
|
114
|
+
<code>.principal-views/graph-converter-execution.otel.canvas</code>
|
|
115
|
+
</p>
|
|
116
|
+
</div>
|
|
117
|
+
<TestEventPanel
|
|
118
|
+
spans={validatedSpans as any}
|
|
119
|
+
currentSpanIndex={0}
|
|
120
|
+
currentEventIndex={10}
|
|
121
|
+
highlightedPhase={undefined}
|
|
122
|
+
/>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
),
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Canvas with event schema definitions (JSON view).
|
|
130
|
+
*
|
|
131
|
+
* Shows the raw canvas structure including event schemas.
|
|
132
|
+
* Notice the `pv.events` property on each node defining:
|
|
133
|
+
* - Event names (e.g., "conversion.started")
|
|
134
|
+
* - Event descriptions
|
|
135
|
+
* - Field schemas with types and requirements
|
|
136
|
+
*/
|
|
137
|
+
export const CanvasSchema: Story = {
|
|
138
|
+
render: () => (
|
|
139
|
+
<div
|
|
140
|
+
style={{
|
|
141
|
+
padding: '20px',
|
|
142
|
+
color: '#fff',
|
|
143
|
+
fontFamily: 'monospace',
|
|
144
|
+
fontSize: '12px',
|
|
145
|
+
overflow: 'auto',
|
|
146
|
+
height: '100vh',
|
|
147
|
+
}}
|
|
148
|
+
>
|
|
149
|
+
<h2>Event Schema Definition</h2>
|
|
150
|
+
<p>
|
|
151
|
+
This canvas defines event schemas for type-safe telemetry validation.
|
|
152
|
+
</p>
|
|
153
|
+
<pre style={{ background: '#1e1e1e', padding: '20px', borderRadius: '8px' }}>
|
|
154
|
+
{JSON.stringify(executionCanvas, null, 2)}
|
|
155
|
+
</pre>
|
|
156
|
+
</div>
|
|
157
|
+
),
|
|
158
|
+
};
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "span-1",
|
|
4
|
+
"name": "should convert simple config to nodes and edges",
|
|
5
|
+
"startTime": 1767808091637,
|
|
6
|
+
"attributes": {
|
|
7
|
+
"span.kind": "test.case",
|
|
8
|
+
"test.name": "should convert simple config to nodes and edges",
|
|
9
|
+
"test.framework": "bun",
|
|
10
|
+
"test.file": "GraphConverter.test.ts",
|
|
11
|
+
"test.suite": "GraphConverter",
|
|
12
|
+
"test.result": "pass"
|
|
13
|
+
},
|
|
14
|
+
"events": [
|
|
15
|
+
{
|
|
16
|
+
"time": 1767808091637,
|
|
17
|
+
"name": "setup.started",
|
|
18
|
+
"attributes": {
|
|
19
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
20
|
+
"code.lineno": 28,
|
|
21
|
+
"description": "Creating test configuration with 2 nodes and 1 edge"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"time": 1767808091637,
|
|
26
|
+
"name": "setup.complete",
|
|
27
|
+
"attributes": {
|
|
28
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
29
|
+
"code.lineno": 68,
|
|
30
|
+
"config.nodes": 2,
|
|
31
|
+
"config.edges": 1
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"time": 1767808091637,
|
|
36
|
+
"name": "execution.started",
|
|
37
|
+
"attributes": {
|
|
38
|
+
"code.filepath": "GraphConverter.ts",
|
|
39
|
+
"code.lineno": 15,
|
|
40
|
+
"action": "GraphConverter.configToGraph()"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"time": 1767808091637,
|
|
45
|
+
"name": "execution.complete",
|
|
46
|
+
"attributes": {
|
|
47
|
+
"code.filepath": "GraphConverter.ts",
|
|
48
|
+
"code.lineno": 43,
|
|
49
|
+
"result.nodes.count": 2,
|
|
50
|
+
"result.edges.count": 1
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"time": 1767808091637,
|
|
55
|
+
"name": "assertion.started",
|
|
56
|
+
"attributes": {
|
|
57
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
58
|
+
"code.lineno": 91,
|
|
59
|
+
"assertions": "Verifying nodes and edges structure"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"time": 1767808091637,
|
|
64
|
+
"name": "assertion.complete",
|
|
65
|
+
"attributes": {
|
|
66
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
67
|
+
"code.lineno": 114,
|
|
68
|
+
"assertions.passed": 11,
|
|
69
|
+
"assertions.failed": 0
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"status": "OK",
|
|
74
|
+
"endTime": 1767808091637,
|
|
75
|
+
"duration": 0
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "span-2",
|
|
79
|
+
"name": "should extract manual positions from node types",
|
|
80
|
+
"startTime": 1767808091637,
|
|
81
|
+
"attributes": {
|
|
82
|
+
"span.kind": "test.case",
|
|
83
|
+
"test.name": "should extract manual positions from node types",
|
|
84
|
+
"test.framework": "bun",
|
|
85
|
+
"test.file": "GraphConverter.test.ts",
|
|
86
|
+
"test.suite": "GraphConverter",
|
|
87
|
+
"test.result": "pass"
|
|
88
|
+
},
|
|
89
|
+
"events": [
|
|
90
|
+
{
|
|
91
|
+
"time": 1767808091637,
|
|
92
|
+
"name": "setup.started",
|
|
93
|
+
"attributes": {
|
|
94
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
95
|
+
"code.lineno": 138,
|
|
96
|
+
"description": "Creating config with manual node positions"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"time": 1767808091637,
|
|
101
|
+
"name": "setup.complete",
|
|
102
|
+
"attributes": {
|
|
103
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
104
|
+
"code.lineno": 165,
|
|
105
|
+
"config.nodes": 2,
|
|
106
|
+
"positions.defined": true
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"time": 1767808091637,
|
|
111
|
+
"name": "execution.started",
|
|
112
|
+
"attributes": {
|
|
113
|
+
"code.filepath": "GraphConverter.ts",
|
|
114
|
+
"code.lineno": 15,
|
|
115
|
+
"action": "GraphConverter.configToGraph()"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"time": 1767808091637,
|
|
120
|
+
"name": "execution.complete",
|
|
121
|
+
"attributes": {
|
|
122
|
+
"code.filepath": "GraphConverter.ts",
|
|
123
|
+
"code.lineno": 43,
|
|
124
|
+
"result.nodes.count": 2
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"time": 1767808091637,
|
|
129
|
+
"name": "assertion.started",
|
|
130
|
+
"attributes": {
|
|
131
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
132
|
+
"code.lineno": 184,
|
|
133
|
+
"assertions": "Verifying positions preserved"
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"time": 1767808091637,
|
|
138
|
+
"name": "assertion.complete",
|
|
139
|
+
"attributes": {
|
|
140
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
141
|
+
"code.lineno": 191,
|
|
142
|
+
"assertions.passed": 2,
|
|
143
|
+
"assertions.failed": 0
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"status": "OK",
|
|
148
|
+
"endTime": 1767808091637,
|
|
149
|
+
"duration": 0
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"id": "span-3",
|
|
153
|
+
"name": "should handle nodes without positions",
|
|
154
|
+
"startTime": 1767808091637,
|
|
155
|
+
"attributes": {
|
|
156
|
+
"span.kind": "test.case",
|
|
157
|
+
"test.name": "should handle nodes without positions",
|
|
158
|
+
"test.framework": "bun",
|
|
159
|
+
"test.file": "GraphConverter.test.ts",
|
|
160
|
+
"test.suite": "GraphConverter",
|
|
161
|
+
"test.result": "pass"
|
|
162
|
+
},
|
|
163
|
+
"events": [
|
|
164
|
+
{
|
|
165
|
+
"time": 1767808091637,
|
|
166
|
+
"name": "setup.started",
|
|
167
|
+
"attributes": {
|
|
168
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
169
|
+
"code.lineno": 215,
|
|
170
|
+
"description": "Creating config without positions"
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"time": 1767808091637,
|
|
175
|
+
"name": "setup.complete",
|
|
176
|
+
"attributes": {
|
|
177
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
178
|
+
"code.lineno": 235,
|
|
179
|
+
"config.nodes": 1,
|
|
180
|
+
"positions.defined": false
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"time": 1767808091637,
|
|
185
|
+
"name": "execution.started",
|
|
186
|
+
"attributes": {
|
|
187
|
+
"code.filepath": "GraphConverter.ts",
|
|
188
|
+
"code.lineno": 15,
|
|
189
|
+
"action": "GraphConverter.configToGraph()"
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"time": 1767808091637,
|
|
194
|
+
"name": "execution.complete",
|
|
195
|
+
"attributes": {
|
|
196
|
+
"code.filepath": "GraphConverter.ts",
|
|
197
|
+
"code.lineno": 43,
|
|
198
|
+
"result.nodes.count": 1
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"time": 1767808091637,
|
|
203
|
+
"name": "assertion.started",
|
|
204
|
+
"attributes": {
|
|
205
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
206
|
+
"code.lineno": 254,
|
|
207
|
+
"assertions": "Verifying position is undefined"
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"time": 1767808091637,
|
|
212
|
+
"name": "assertion.complete",
|
|
213
|
+
"attributes": {
|
|
214
|
+
"code.filepath": "GraphConverter.test.ts",
|
|
215
|
+
"code.lineno": 260,
|
|
216
|
+
"assertions.passed": 1,
|
|
217
|
+
"assertions.failed": 0
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
],
|
|
221
|
+
"status": "OK",
|
|
222
|
+
"endTime": 1767808091637,
|
|
223
|
+
"duration": 0
|
|
224
|
+
}
|
|
225
|
+
]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "span-1",
|
|
4
|
+
"name": "graph conversion with validation",
|
|
5
|
+
"startTime": 1767809672129,
|
|
6
|
+
"attributes": {
|
|
7
|
+
"span.kind": "test.case",
|
|
8
|
+
"test.name": "graph conversion with validation",
|
|
9
|
+
"test.framework": "bun",
|
|
10
|
+
"test.file": "event-validation.test.ts",
|
|
11
|
+
"test.suite": "Event Schema Validation"
|
|
12
|
+
},
|
|
13
|
+
"events": [
|
|
14
|
+
{
|
|
15
|
+
"time": 1767809672129,
|
|
16
|
+
"name": "conversion.started",
|
|
17
|
+
"attributes": {
|
|
18
|
+
"code.filepath": "GraphConverter.ts",
|
|
19
|
+
"code.lineno": 15,
|
|
20
|
+
"config.nodeTypes": 2,
|
|
21
|
+
"config.edgeTypes": 1
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"time": 1767809672129,
|
|
26
|
+
"name": "conversion.processingNodes",
|
|
27
|
+
"attributes": {
|
|
28
|
+
"code.filepath": "GraphConverter.ts",
|
|
29
|
+
"code.lineno": 28,
|
|
30
|
+
"nodes.count": 2
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"time": 1767809672129,
|
|
35
|
+
"name": "conversion.processingEdges",
|
|
36
|
+
"attributes": {
|
|
37
|
+
"code.filepath": "GraphConverter.ts",
|
|
38
|
+
"code.lineno": 45,
|
|
39
|
+
"edges.count": 1
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"time": 1767809672129,
|
|
44
|
+
"name": "conversion.complete",
|
|
45
|
+
"attributes": {
|
|
46
|
+
"code.filepath": "GraphConverter.ts",
|
|
47
|
+
"code.lineno": 60,
|
|
48
|
+
"result.nodes.count": 2,
|
|
49
|
+
"result.edges.count": 1,
|
|
50
|
+
"duration.ms": 5
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"status": "OK",
|
|
55
|
+
"endTime": 1767809672129,
|
|
56
|
+
"duration": 0
|
|
57
|
+
}
|
|
58
|
+
]
|