@principal-ai/storybook-addon-otel 0.3.2 → 0.3.3

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 (2) hide show
  1. package/collector.js +94 -4
  2. package/package.json +1 -1
package/collector.js CHANGED
@@ -1,9 +1,99 @@
1
1
  /**
2
2
  * TelemetryCollector Export (for manual instrumentation in stories)
3
3
  *
4
- * This file exports only the collector without the decorator registration,
5
- * preventing the "loaded twice" issue when importing in stories.
4
+ * Standalone browser-compatible collector without @storybook/* dependencies.
5
+ * This prevents bundler errors and the "loaded twice" issue.
6
6
  */
7
7
 
8
- // Re-export the collector from the compiled version
9
- export { TelemetryCollector } from './dist/collector.js';
8
+ const ADDON_ID = 'principal-ai/storybook-addon-otel';
9
+ const EVENTS = {
10
+ TELEMETRY_UPDATE: `${ADDON_ID}/telemetry-update`,
11
+ CLEAR_TELEMETRY: `${ADDON_ID}/clear-telemetry`,
12
+ };
13
+
14
+ class TelemetryCollectorImpl {
15
+ constructor() {
16
+ this.spans = [];
17
+ this.spanIdCounter = 0;
18
+ this.activeSpans = new Map();
19
+ this.channel = null;
20
+
21
+ // Get communication channel with manager (if available)
22
+ if (typeof window !== 'undefined' && window.__STORYBOOK_ADDONS_CHANNEL) {
23
+ this.channel = window.__STORYBOOK_ADDONS_CHANNEL;
24
+ }
25
+ }
26
+
27
+ startSpan(name, attributes = {}, parentId) {
28
+ const span = {
29
+ id: `span-${++this.spanIdCounter}`,
30
+ name,
31
+ parentId,
32
+ startTime: Date.now(),
33
+ attributes: {
34
+ 'component.name': name,
35
+ ...attributes,
36
+ },
37
+ events: [],
38
+ status: 'OK',
39
+ };
40
+
41
+ this.spans.push(span);
42
+ this.activeSpans.set(span.id, span);
43
+ console.log('[TelemetryCollector] Started span:', name, 'Total spans:', this.spans.length);
44
+ this.emit();
45
+
46
+ return span;
47
+ }
48
+
49
+ addEvent(span, eventName, attributes = {}) {
50
+ span.events.push({
51
+ time: Date.now(),
52
+ name: eventName,
53
+ attributes,
54
+ });
55
+ this.emit();
56
+ }
57
+
58
+ endSpan(span) {
59
+ span.endTime = Date.now();
60
+ span.duration = span.endTime - span.startTime;
61
+ this.activeSpans.delete(span.id);
62
+ this.emit();
63
+ }
64
+
65
+ markError(span, error) {
66
+ span.status = 'ERROR';
67
+ span.errorMessage = typeof error === 'string' ? error : error.message;
68
+ span.attributes['error'] = true;
69
+ span.attributes['error.message'] = span.errorMessage;
70
+ this.emit();
71
+ }
72
+
73
+ getSpans() {
74
+ return [...this.spans];
75
+ }
76
+
77
+ clear() {
78
+ this.spans = [];
79
+ this.spanIdCounter = 0;
80
+ this.activeSpans.clear();
81
+ this.emit();
82
+ }
83
+
84
+ emit() {
85
+ console.log('[TelemetryCollector] Emitting update, spans:', this.spans.length, 'has channel:', !!this.channel);
86
+ if (this.channel) {
87
+ this.channel.emit(EVENTS.TELEMETRY_UPDATE, this.getSpans());
88
+ }
89
+ }
90
+
91
+ exportJson() {
92
+ // End any active spans
93
+ this.activeSpans.forEach(span => this.endSpan(span));
94
+ return JSON.stringify(this.spans, null, 2);
95
+ }
96
+ }
97
+
98
+ // Singleton instance
99
+ export const TelemetryCollector = new TelemetryCollectorImpl();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ai/storybook-addon-otel",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Storybook addon for capturing and visualizing OpenTelemetry data from story interactions",
5
5
  "main": "preset.js",
6
6
  "files": [