@principal-ai/principal-view-core 0.5.6
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/README.md +126 -0
- package/dist/ConfigurationLoader.d.ts +76 -0
- package/dist/ConfigurationLoader.d.ts.map +1 -0
- package/dist/ConfigurationLoader.js +144 -0
- package/dist/ConfigurationLoader.js.map +1 -0
- package/dist/ConfigurationValidator.d.ts +31 -0
- package/dist/ConfigurationValidator.d.ts.map +1 -0
- package/dist/ConfigurationValidator.js +242 -0
- package/dist/ConfigurationValidator.js.map +1 -0
- package/dist/EventProcessor.d.ts +49 -0
- package/dist/EventProcessor.d.ts.map +1 -0
- package/dist/EventProcessor.js +215 -0
- package/dist/EventProcessor.js.map +1 -0
- package/dist/EventRecorderService.d.ts +305 -0
- package/dist/EventRecorderService.d.ts.map +1 -0
- package/dist/EventRecorderService.js +463 -0
- package/dist/EventRecorderService.js.map +1 -0
- package/dist/LibraryLoader.d.ts +63 -0
- package/dist/LibraryLoader.d.ts.map +1 -0
- package/dist/LibraryLoader.js +188 -0
- package/dist/LibraryLoader.js.map +1 -0
- package/dist/PathBasedEventProcessor.d.ts +90 -0
- package/dist/PathBasedEventProcessor.d.ts.map +1 -0
- package/dist/PathBasedEventProcessor.js +239 -0
- package/dist/PathBasedEventProcessor.js.map +1 -0
- package/dist/SessionManager.d.ts +194 -0
- package/dist/SessionManager.d.ts.map +1 -0
- package/dist/SessionManager.js +299 -0
- package/dist/SessionManager.js.map +1 -0
- package/dist/ValidationEngine.d.ts +31 -0
- package/dist/ValidationEngine.d.ts.map +1 -0
- package/dist/ValidationEngine.js +158 -0
- package/dist/ValidationEngine.js.map +1 -0
- package/dist/helpers/GraphInstrumentationHelper.d.ts +93 -0
- package/dist/helpers/GraphInstrumentationHelper.d.ts.map +1 -0
- package/dist/helpers/GraphInstrumentationHelper.js +248 -0
- package/dist/helpers/GraphInstrumentationHelper.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/rules/config.d.ts +57 -0
- package/dist/rules/config.d.ts.map +1 -0
- package/dist/rules/config.js +382 -0
- package/dist/rules/config.js.map +1 -0
- package/dist/rules/engine.d.ts +70 -0
- package/dist/rules/engine.d.ts.map +1 -0
- package/dist/rules/engine.js +252 -0
- package/dist/rules/engine.js.map +1 -0
- package/dist/rules/implementations/connection-type-references.d.ts +7 -0
- package/dist/rules/implementations/connection-type-references.d.ts.map +1 -0
- package/dist/rules/implementations/connection-type-references.js +104 -0
- package/dist/rules/implementations/connection-type-references.js.map +1 -0
- package/dist/rules/implementations/dead-end-states.d.ts +17 -0
- package/dist/rules/implementations/dead-end-states.d.ts.map +1 -0
- package/dist/rules/implementations/dead-end-states.js +72 -0
- package/dist/rules/implementations/dead-end-states.js.map +1 -0
- package/dist/rules/implementations/index.d.ts +24 -0
- package/dist/rules/implementations/index.d.ts.map +1 -0
- package/dist/rules/implementations/index.js +62 -0
- package/dist/rules/implementations/index.js.map +1 -0
- package/dist/rules/implementations/library-node-type-match.d.ts +17 -0
- package/dist/rules/implementations/library-node-type-match.d.ts.map +1 -0
- package/dist/rules/implementations/library-node-type-match.js +123 -0
- package/dist/rules/implementations/library-node-type-match.js.map +1 -0
- package/dist/rules/implementations/minimum-node-sources.d.ts +22 -0
- package/dist/rules/implementations/minimum-node-sources.d.ts.map +1 -0
- package/dist/rules/implementations/minimum-node-sources.js +54 -0
- package/dist/rules/implementations/minimum-node-sources.js.map +1 -0
- package/dist/rules/implementations/no-unknown-fields.d.ts +7 -0
- package/dist/rules/implementations/no-unknown-fields.d.ts.map +1 -0
- package/dist/rules/implementations/no-unknown-fields.js +211 -0
- package/dist/rules/implementations/no-unknown-fields.js.map +1 -0
- package/dist/rules/implementations/orphaned-edge-types.d.ts +7 -0
- package/dist/rules/implementations/orphaned-edge-types.d.ts.map +1 -0
- package/dist/rules/implementations/orphaned-edge-types.js +47 -0
- package/dist/rules/implementations/orphaned-edge-types.js.map +1 -0
- package/dist/rules/implementations/orphaned-node-types.d.ts +7 -0
- package/dist/rules/implementations/orphaned-node-types.d.ts.map +1 -0
- package/dist/rules/implementations/orphaned-node-types.js +50 -0
- package/dist/rules/implementations/orphaned-node-types.js.map +1 -0
- package/dist/rules/implementations/required-metadata.d.ts +7 -0
- package/dist/rules/implementations/required-metadata.d.ts.map +1 -0
- package/dist/rules/implementations/required-metadata.js +57 -0
- package/dist/rules/implementations/required-metadata.js.map +1 -0
- package/dist/rules/implementations/state-transition-references.d.ts +7 -0
- package/dist/rules/implementations/state-transition-references.d.ts.map +1 -0
- package/dist/rules/implementations/state-transition-references.js +135 -0
- package/dist/rules/implementations/state-transition-references.js.map +1 -0
- package/dist/rules/implementations/unreachable-states.d.ts +7 -0
- package/dist/rules/implementations/unreachable-states.d.ts.map +1 -0
- package/dist/rules/implementations/unreachable-states.js +80 -0
- package/dist/rules/implementations/unreachable-states.js.map +1 -0
- package/dist/rules/implementations/valid-action-patterns.d.ts +17 -0
- package/dist/rules/implementations/valid-action-patterns.d.ts.map +1 -0
- package/dist/rules/implementations/valid-action-patterns.js +109 -0
- package/dist/rules/implementations/valid-action-patterns.js.map +1 -0
- package/dist/rules/implementations/valid-color-format.d.ts +7 -0
- package/dist/rules/implementations/valid-color-format.d.ts.map +1 -0
- package/dist/rules/implementations/valid-color-format.js +91 -0
- package/dist/rules/implementations/valid-color-format.js.map +1 -0
- package/dist/rules/implementations/valid-edge-types.d.ts +7 -0
- package/dist/rules/implementations/valid-edge-types.d.ts.map +1 -0
- package/dist/rules/implementations/valid-edge-types.js +244 -0
- package/dist/rules/implementations/valid-edge-types.js.map +1 -0
- package/dist/rules/implementations/valid-node-types.d.ts +7 -0
- package/dist/rules/implementations/valid-node-types.d.ts.map +1 -0
- package/dist/rules/implementations/valid-node-types.js +175 -0
- package/dist/rules/implementations/valid-node-types.js.map +1 -0
- package/dist/rules/index.d.ts +28 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +45 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/types.d.ts +309 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +35 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/types/canvas.d.ts +409 -0
- package/dist/types/canvas.d.ts.map +1 -0
- package/dist/types/canvas.js +70 -0
- package/dist/types/canvas.js.map +1 -0
- package/dist/types/index.d.ts +311 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +13 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/library.d.ts +185 -0
- package/dist/types/library.d.ts.map +1 -0
- package/dist/types/library.js +15 -0
- package/dist/types/library.js.map +1 -0
- package/dist/types/path-based-config.d.ts +230 -0
- package/dist/types/path-based-config.d.ts.map +1 -0
- package/dist/types/path-based-config.js +9 -0
- package/dist/types/path-based-config.js.map +1 -0
- package/dist/utils/CanvasConverter.d.ts +118 -0
- package/dist/utils/CanvasConverter.d.ts.map +1 -0
- package/dist/utils/CanvasConverter.js +315 -0
- package/dist/utils/CanvasConverter.js.map +1 -0
- package/dist/utils/GraphConverter.d.ts +18 -0
- package/dist/utils/GraphConverter.d.ts.map +1 -0
- package/dist/utils/GraphConverter.js +61 -0
- package/dist/utils/GraphConverter.js.map +1 -0
- package/dist/utils/LibraryConverter.d.ts +113 -0
- package/dist/utils/LibraryConverter.d.ts.map +1 -0
- package/dist/utils/LibraryConverter.js +166 -0
- package/dist/utils/LibraryConverter.js.map +1 -0
- package/dist/utils/PathMatcher.d.ts +55 -0
- package/dist/utils/PathMatcher.d.ts.map +1 -0
- package/dist/utils/PathMatcher.js +172 -0
- package/dist/utils/PathMatcher.js.map +1 -0
- package/dist/utils/YamlParser.d.ts +36 -0
- package/dist/utils/YamlParser.d.ts.map +1 -0
- package/dist/utils/YamlParser.js +63 -0
- package/dist/utils/YamlParser.js.map +1 -0
- package/package.json +47 -0
- package/src/ConfigurationLoader.test.ts +490 -0
- package/src/ConfigurationLoader.ts +185 -0
- package/src/ConfigurationValidator.test.ts +200 -0
- package/src/ConfigurationValidator.ts +283 -0
- package/src/EventProcessor.test.ts +405 -0
- package/src/EventProcessor.ts +250 -0
- package/src/EventRecorderService.test.ts +541 -0
- package/src/EventRecorderService.ts +744 -0
- package/src/LibraryLoader.ts +215 -0
- package/src/PathBasedEventProcessor.test.ts +567 -0
- package/src/PathBasedEventProcessor.ts +332 -0
- package/src/SessionManager.test.ts +424 -0
- package/src/SessionManager.ts +470 -0
- package/src/ValidationEngine.test.ts +371 -0
- package/src/ValidationEngine.ts +196 -0
- package/src/helpers/GraphInstrumentationHelper.test.ts +340 -0
- package/src/helpers/GraphInstrumentationHelper.ts +326 -0
- package/src/index.ts +85 -0
- package/src/rules/config.test.ts +278 -0
- package/src/rules/config.ts +459 -0
- package/src/rules/engine.test.ts +332 -0
- package/src/rules/engine.ts +318 -0
- package/src/rules/implementations/connection-type-references.ts +117 -0
- package/src/rules/implementations/dead-end-states.ts +101 -0
- package/src/rules/implementations/index.ts +73 -0
- package/src/rules/implementations/library-node-type-match.ts +148 -0
- package/src/rules/implementations/minimum-node-sources.ts +82 -0
- package/src/rules/implementations/no-unknown-fields.ts +342 -0
- package/src/rules/implementations/orphaned-edge-types.ts +55 -0
- package/src/rules/implementations/orphaned-node-types.ts +58 -0
- package/src/rules/implementations/required-metadata.ts +64 -0
- package/src/rules/implementations/state-transition-references.ts +151 -0
- package/src/rules/implementations/unreachable-states.ts +94 -0
- package/src/rules/implementations/valid-action-patterns.ts +136 -0
- package/src/rules/implementations/valid-color-format.ts +140 -0
- package/src/rules/implementations/valid-edge-types.ts +258 -0
- package/src/rules/implementations/valid-node-types.ts +189 -0
- package/src/rules/index.ts +95 -0
- package/src/rules/types.ts +426 -0
- package/src/types/canvas.ts +496 -0
- package/src/types/index.ts +382 -0
- package/src/types/library.ts +233 -0
- package/src/types/path-based-config.ts +281 -0
- package/src/utils/CanvasConverter.ts +431 -0
- package/src/utils/GraphConverter.test.ts +195 -0
- package/src/utils/GraphConverter.ts +71 -0
- package/src/utils/LibraryConverter.ts +245 -0
- package/src/utils/PathMatcher.test.ts +148 -0
- package/src/utils/PathMatcher.ts +183 -0
- package/src/utils/YamlParser.ts +75 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path-Based Event Processor
|
|
3
|
+
*
|
|
4
|
+
* Converts log entries to graph events by associating logs with components
|
|
5
|
+
* based on source file paths.
|
|
6
|
+
*
|
|
7
|
+
* Milestone 1: Basic component activity events
|
|
8
|
+
* Milestone 2: Action pattern matching and edge activation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { PathMatcher } from './utils/PathMatcher';
|
|
12
|
+
import type {
|
|
13
|
+
PathBasedGraphConfiguration,
|
|
14
|
+
ComponentActivityEvent,
|
|
15
|
+
ComponentActionEvent,
|
|
16
|
+
EdgeAnimationEvent,
|
|
17
|
+
PathBasedEvent,
|
|
18
|
+
ActionPattern,
|
|
19
|
+
LogLevel
|
|
20
|
+
} from './types/path-based-config';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Log entry from logger (simplified interface to avoid circular dependency)
|
|
24
|
+
*/
|
|
25
|
+
export interface LogEntry {
|
|
26
|
+
message: string;
|
|
27
|
+
metadata: {
|
|
28
|
+
timestamp: number;
|
|
29
|
+
level: LogLevel;
|
|
30
|
+
source?: {
|
|
31
|
+
file: string;
|
|
32
|
+
line?: number;
|
|
33
|
+
column?: number;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Instance identifier for multi-instance components.
|
|
37
|
+
* Used to differentiate between multiple nodes of the same type
|
|
38
|
+
* (e.g., "client-1", "client-2" for components of type "client").
|
|
39
|
+
*/
|
|
40
|
+
instanceId?: string;
|
|
41
|
+
};
|
|
42
|
+
args?: any[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Component source mapping (componentId → source patterns)
|
|
47
|
+
*/
|
|
48
|
+
interface ComponentSourceMap {
|
|
49
|
+
componentId: string;
|
|
50
|
+
sources: string[];
|
|
51
|
+
actions?: ActionPattern[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Path-based event processor
|
|
56
|
+
*/
|
|
57
|
+
export class PathBasedEventProcessor {
|
|
58
|
+
private componentSourceMap: ComponentSourceMap[] = [];
|
|
59
|
+
private config: PathBasedGraphConfiguration;
|
|
60
|
+
|
|
61
|
+
constructor(config: PathBasedGraphConfiguration) {
|
|
62
|
+
this.config = config;
|
|
63
|
+
this.buildComponentSourceMap();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Build the component-to-source-path mapping from configuration
|
|
68
|
+
*/
|
|
69
|
+
private buildComponentSourceMap(): void {
|
|
70
|
+
this.componentSourceMap = [];
|
|
71
|
+
|
|
72
|
+
for (const [componentId, nodeType] of Object.entries(this.config.nodeTypes)) {
|
|
73
|
+
if (nodeType.sources && nodeType.sources.length > 0) {
|
|
74
|
+
this.componentSourceMap.push({
|
|
75
|
+
componentId,
|
|
76
|
+
sources: nodeType.sources,
|
|
77
|
+
actions: nodeType.actions
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Process a log entry and convert to graph event(s)
|
|
85
|
+
*
|
|
86
|
+
* @param log Log entry from enhanced logger
|
|
87
|
+
* @returns Array of graph events (can be multiple if action triggers edges)
|
|
88
|
+
*/
|
|
89
|
+
public processLog(log: LogEntry): PathBasedEvent[] {
|
|
90
|
+
const events: PathBasedEvent[] = [];
|
|
91
|
+
|
|
92
|
+
// Skip logs without source information
|
|
93
|
+
if (!log.metadata.source?.file) {
|
|
94
|
+
return events;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Find component by matching source path
|
|
98
|
+
const component = this.findComponentByPath(log.metadata.source.file);
|
|
99
|
+
|
|
100
|
+
if (!component) {
|
|
101
|
+
// Log doesn't match any configured component
|
|
102
|
+
return events;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Milestone 2: Try to match action patterns first (if enabled)
|
|
106
|
+
if (this.config.pathBasedConfig?.enableActionPatterns && component.actions) {
|
|
107
|
+
const actionEvent = this.tryMatchActionPattern(log, component);
|
|
108
|
+
if (actionEvent) {
|
|
109
|
+
events.push(actionEvent);
|
|
110
|
+
|
|
111
|
+
// Check if this action triggers any edge animations
|
|
112
|
+
const edgeEvents = this.getEdgeAnimationsForAction(
|
|
113
|
+
component.componentId,
|
|
114
|
+
actionEvent.action
|
|
115
|
+
);
|
|
116
|
+
events.push(...edgeEvents);
|
|
117
|
+
|
|
118
|
+
return events; // Action pattern matched, don't create activity event
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Milestone 1: Fallback to generic component activity event
|
|
123
|
+
const activityEvent: ComponentActivityEvent = {
|
|
124
|
+
type: 'component-activity',
|
|
125
|
+
componentId: component.componentId,
|
|
126
|
+
instanceId: log.metadata.instanceId,
|
|
127
|
+
timestamp: log.metadata.timestamp,
|
|
128
|
+
level: log.metadata.level,
|
|
129
|
+
message: log.message,
|
|
130
|
+
source: {
|
|
131
|
+
file: log.metadata.source.file,
|
|
132
|
+
line: log.metadata.source.line,
|
|
133
|
+
column: log.metadata.source.column
|
|
134
|
+
},
|
|
135
|
+
args: log.args
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
events.push(activityEvent);
|
|
139
|
+
return events;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Find component by matching source path against configured patterns
|
|
144
|
+
*/
|
|
145
|
+
private findComponentByPath(logPath: string): ComponentSourceMap | null {
|
|
146
|
+
for (const component of this.componentSourceMap) {
|
|
147
|
+
// Check if any of the component's source patterns match the log path
|
|
148
|
+
for (const sourcePattern of component.sources) {
|
|
149
|
+
if (PathMatcher.matches(logPath, sourcePattern)) {
|
|
150
|
+
return component;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Try to match log message against action patterns (Milestone 2)
|
|
160
|
+
*/
|
|
161
|
+
private tryMatchActionPattern(
|
|
162
|
+
log: LogEntry,
|
|
163
|
+
component: ComponentSourceMap
|
|
164
|
+
): ComponentActionEvent | null {
|
|
165
|
+
if (!component.actions) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
for (const actionPattern of component.actions) {
|
|
170
|
+
const regex = new RegExp(actionPattern.pattern);
|
|
171
|
+
const match = log.message.match(regex);
|
|
172
|
+
|
|
173
|
+
if (match) {
|
|
174
|
+
// Extract metadata from capture groups
|
|
175
|
+
const metadata = this.extractMetadata(match, actionPattern.metadata || {});
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
type: 'component-action',
|
|
179
|
+
componentId: component.componentId,
|
|
180
|
+
instanceId: log.metadata.instanceId,
|
|
181
|
+
action: actionPattern.event,
|
|
182
|
+
state: actionPattern.state,
|
|
183
|
+
timestamp: log.metadata.timestamp,
|
|
184
|
+
metadata,
|
|
185
|
+
source: {
|
|
186
|
+
file: log.metadata.source!.file,
|
|
187
|
+
line: log.metadata.source!.line,
|
|
188
|
+
column: log.metadata.source!.column
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Extract metadata from regex capture groups
|
|
199
|
+
*/
|
|
200
|
+
private extractMetadata(
|
|
201
|
+
match: RegExpMatchArray,
|
|
202
|
+
template: Record<string, string>
|
|
203
|
+
): Record<string, any> {
|
|
204
|
+
const metadata: Record<string, any> = {};
|
|
205
|
+
|
|
206
|
+
for (const [key, value] of Object.entries(template)) {
|
|
207
|
+
// Value is a template like "$lockId" that references a named capture group
|
|
208
|
+
if (value.startsWith('$') && match.groups) {
|
|
209
|
+
const groupName = value.slice(1);
|
|
210
|
+
metadata[key] = match.groups[groupName];
|
|
211
|
+
} else {
|
|
212
|
+
// Static value
|
|
213
|
+
metadata[key] = value;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return metadata;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Get edge animations triggered by a component action (Milestone 2)
|
|
222
|
+
*/
|
|
223
|
+
private getEdgeAnimationsForAction(
|
|
224
|
+
componentId: string,
|
|
225
|
+
action: string
|
|
226
|
+
): EdgeAnimationEvent[] {
|
|
227
|
+
const events: EdgeAnimationEvent[] = [];
|
|
228
|
+
|
|
229
|
+
// Check all edges to see if they're activated by this action
|
|
230
|
+
for (const [edgeId, edgeType] of Object.entries(this.config.edgeTypes)) {
|
|
231
|
+
if (edgeType.activatedBy) {
|
|
232
|
+
for (const trigger of edgeType.activatedBy) {
|
|
233
|
+
if (trigger.action === action) {
|
|
234
|
+
events.push({
|
|
235
|
+
type: 'edge-animation',
|
|
236
|
+
edgeId,
|
|
237
|
+
animation: trigger.animation,
|
|
238
|
+
direction: trigger.direction,
|
|
239
|
+
duration: trigger.duration || 2000,
|
|
240
|
+
timestamp: Date.now(),
|
|
241
|
+
triggeredBy: {
|
|
242
|
+
componentId,
|
|
243
|
+
action
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return events;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Batch process multiple log entries
|
|
256
|
+
*/
|
|
257
|
+
public processLogs(logs: LogEntry[]): PathBasedEvent[] {
|
|
258
|
+
const events: PathBasedEvent[] = [];
|
|
259
|
+
|
|
260
|
+
for (const log of logs) {
|
|
261
|
+
events.push(...this.processLog(log));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return events;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Get statistics about component source mappings
|
|
269
|
+
*/
|
|
270
|
+
public getStats(): {
|
|
271
|
+
totalComponents: number;
|
|
272
|
+
componentsWithSources: number;
|
|
273
|
+
componentsWithActions: number;
|
|
274
|
+
totalSourcePatterns: number;
|
|
275
|
+
totalActionPatterns: number;
|
|
276
|
+
} {
|
|
277
|
+
return {
|
|
278
|
+
totalComponents: Object.keys(this.config.nodeTypes).length,
|
|
279
|
+
componentsWithSources: this.componentSourceMap.length,
|
|
280
|
+
componentsWithActions: this.componentSourceMap.filter(c => c.actions && c.actions.length > 0).length,
|
|
281
|
+
totalSourcePatterns: this.componentSourceMap.reduce((sum, c) => sum + c.sources.length, 0),
|
|
282
|
+
totalActionPatterns: this.componentSourceMap.reduce((sum, c) => sum + (c.actions?.length || 0), 0)
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Validate configuration and return warnings/errors
|
|
288
|
+
*/
|
|
289
|
+
public validate(): Array<{ type: 'error' | 'warning'; message: string; componentId?: string }> {
|
|
290
|
+
const issues: Array<{ type: 'error' | 'warning'; message: string; componentId?: string }> = [];
|
|
291
|
+
|
|
292
|
+
// Check for overlapping source patterns
|
|
293
|
+
for (let i = 0; i < this.componentSourceMap.length; i++) {
|
|
294
|
+
for (let j = i + 1; j < this.componentSourceMap.length; j++) {
|
|
295
|
+
const comp1 = this.componentSourceMap[i];
|
|
296
|
+
const comp2 = this.componentSourceMap[j];
|
|
297
|
+
|
|
298
|
+
// Check if any patterns overlap
|
|
299
|
+
for (const pattern1 of comp1.sources) {
|
|
300
|
+
for (const pattern2 of comp2.sources) {
|
|
301
|
+
if (pattern1 === pattern2) {
|
|
302
|
+
issues.push({
|
|
303
|
+
type: 'warning',
|
|
304
|
+
message: `Components "${comp1.componentId}" and "${comp2.componentId}" both use pattern "${pattern1}". Logs will be associated with the first match.`,
|
|
305
|
+
componentId: comp1.componentId
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Validate action patterns (check for valid regex)
|
|
314
|
+
for (const component of this.componentSourceMap) {
|
|
315
|
+
if (component.actions) {
|
|
316
|
+
for (const action of component.actions) {
|
|
317
|
+
try {
|
|
318
|
+
new RegExp(action.pattern);
|
|
319
|
+
} catch (error) {
|
|
320
|
+
issues.push({
|
|
321
|
+
type: 'error',
|
|
322
|
+
message: `Invalid regex pattern in action "${action.event}": ${action.pattern}`,
|
|
323
|
+
componentId: component.componentId
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return issues;
|
|
331
|
+
}
|
|
332
|
+
}
|