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

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/collector.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * TelemetryCollector Export (for manual instrumentation in stories)
3
+ *
4
+ * This file exports only the collector without the decorator registration,
5
+ * preventing the "loaded twice" issue when importing in stories.
6
+ */
7
+
8
+ // Re-export the collector from the compiled version
9
+ export { TelemetryCollector } from './dist/collector.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ai/storybook-addon-otel",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Storybook addon for capturing and visualizing OpenTelemetry data from story interactions",
5
5
  "main": "preset.js",
6
6
  "files": [
@@ -12,10 +12,10 @@
12
12
  "dist/decorator.js",
13
13
  "dist/index.d.ts",
14
14
  "dist/index.js",
15
- "dist/preview.js",
16
15
  "preset.js",
17
16
  "preview.js",
18
17
  "manager.js",
18
+ "collector.js",
19
19
  "README.md"
20
20
  ],
21
21
  "exports": {
@@ -31,10 +31,14 @@
31
31
  "./manager": {
32
32
  "default": "./manager.js"
33
33
  },
34
+ "./collector": {
35
+ "types": "./dist/collector.d.ts",
36
+ "default": "./collector.js"
37
+ },
34
38
  "./package.json": "./package.json"
35
39
  },
36
40
  "scripts": {
37
- "build": "tsc && node scripts/copy-browser-files.js && rm -f dist/manager.js dist/manager.d.ts dist/preset.js dist/preset.d.ts dist/components/*.js dist/components/*.d.ts",
41
+ "build": "tsc && node scripts/copy-browser-files.js && rm -f dist/manager.js dist/manager.d.ts dist/preset.js dist/preset.d.ts dist/preview.js dist/components/*.js dist/components/*.d.ts",
38
42
  "dev": "tsc --watch",
39
43
  "clean": "rm -rf dist"
40
44
  },
package/dist/preview.js DELETED
@@ -1,121 +0,0 @@
1
- /**
2
- * Preview-side entry point (runs in browser)
3
- * Must be ESM format
4
- */
5
-
6
- import React, { useEffect, useState } from 'react';
7
-
8
- // Simple telemetry collector for browser
9
- class BrowserTelemetryCollector {
10
- constructor() {
11
- this.spans = [];
12
- this.spanIdCounter = 0;
13
- this.activeSpans = new Map();
14
-
15
- // Try to get Storybook channel (might not be available immediately)
16
- if (typeof window !== 'undefined' && window.__STORYBOOK_ADDONS_CHANNEL__) {
17
- this.channel = window.__STORYBOOK_ADDONS_CHANNEL__;
18
- }
19
- }
20
-
21
- startSpan(name, attributes = {}, parentId) {
22
- const span = {
23
- id: `span-${++this.spanIdCounter}`,
24
- name,
25
- parentId,
26
- startTime: Date.now(),
27
- attributes: {
28
- 'component.name': name,
29
- ...attributes,
30
- },
31
- events: [],
32
- status: 'OK',
33
- };
34
-
35
- this.spans.push(span);
36
- this.activeSpans.set(span.id, span);
37
-
38
- console.log('[TelemetryCollector] Started span:', name, 'Total spans:', this.spans.length);
39
- this.emit();
40
-
41
- return span;
42
- }
43
-
44
- addEvent(span, eventName, attributes = {}) {
45
- span.events.push({
46
- time: Date.now(),
47
- name: eventName,
48
- attributes,
49
- });
50
- this.emit();
51
- }
52
-
53
- endSpan(span) {
54
- span.endTime = Date.now();
55
- span.duration = span.endTime - span.startTime;
56
- this.activeSpans.delete(span.id);
57
- this.emit();
58
- }
59
-
60
- getSpans() {
61
- return [...this.spans];
62
- }
63
-
64
- clear() {
65
- this.spans = [];
66
- this.spanIdCounter = 0;
67
- this.activeSpans.clear();
68
- this.emit();
69
- }
70
-
71
- emit() {
72
- // Get channel if not already set
73
- if (!this.channel && typeof window !== 'undefined' && window.__STORYBOOK_ADDONS_CHANNEL__) {
74
- this.channel = window.__STORYBOOK_ADDONS_CHANNEL__;
75
- }
76
-
77
- console.log('[TelemetryCollector] Emitting update, spans:', this.spans.length, 'has channel:', !!this.channel);
78
-
79
- if (this.channel) {
80
- this.channel.emit('storybook-addon-otel-telemetry/telemetry-update', this.getSpans());
81
- }
82
- }
83
- }
84
-
85
- // Singleton instance
86
- const TelemetryCollector = new BrowserTelemetryCollector();
87
-
88
- // Decorator
89
- export const withTelemetry = (Story, context) => {
90
- const [rootSpan, setRootSpan] = useState(null);
91
-
92
- console.log('[Telemetry Decorator] Story:', context.title + '/' + context.name);
93
-
94
- useEffect(() => {
95
- // Start root span for story
96
- const span = TelemetryCollector.startSpan(`Story: ${context.title}/${context.name}`, {
97
- 'story.id': context.id,
98
- 'story.title': context.title,
99
- 'story.name': context.name,
100
- });
101
-
102
- setRootSpan(span);
103
-
104
- TelemetryCollector.addEvent(span, 'story.mounted', {
105
- 'story.name': `${context.title}/${context.name}`,
106
- });
107
-
108
- return () => {
109
- TelemetryCollector.addEvent(span, 'story.unmounted', {});
110
- TelemetryCollector.endSpan(span);
111
- };
112
- }, [context.id]);
113
-
114
- return React.createElement(Story);
115
- };
116
-
117
- // Export decorators array
118
- export const decorators = [withTelemetry];
119
-
120
- // Export for manual use
121
- export { TelemetryCollector };