@bugspotter/sdk 0.1.0-alpha.1

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 (67) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/LICENSE +21 -0
  3. package/README.md +639 -0
  4. package/dist/bugspotter.min.js +2 -0
  5. package/dist/bugspotter.min.js.LICENSE.txt +14 -0
  6. package/dist/capture/base-capture.d.ts +34 -0
  7. package/dist/capture/base-capture.js +23 -0
  8. package/dist/capture/capture-lifecycle.d.ts +24 -0
  9. package/dist/capture/capture-lifecycle.js +2 -0
  10. package/dist/capture/console.d.ts +29 -0
  11. package/dist/capture/console.js +107 -0
  12. package/dist/capture/metadata.d.ts +21 -0
  13. package/dist/capture/metadata.js +76 -0
  14. package/dist/capture/network.d.ts +32 -0
  15. package/dist/capture/network.js +135 -0
  16. package/dist/capture/screenshot.d.ts +19 -0
  17. package/dist/capture/screenshot.js +52 -0
  18. package/dist/collectors/dom.d.ts +67 -0
  19. package/dist/collectors/dom.js +164 -0
  20. package/dist/collectors/index.d.ts +2 -0
  21. package/dist/collectors/index.js +5 -0
  22. package/dist/core/buffer.d.ts +50 -0
  23. package/dist/core/buffer.js +88 -0
  24. package/dist/core/circular-buffer.d.ts +42 -0
  25. package/dist/core/circular-buffer.js +77 -0
  26. package/dist/core/compress.d.ts +49 -0
  27. package/dist/core/compress.js +245 -0
  28. package/dist/core/offline-queue.d.ts +76 -0
  29. package/dist/core/offline-queue.js +301 -0
  30. package/dist/core/transport.d.ts +73 -0
  31. package/dist/core/transport.js +352 -0
  32. package/dist/core/upload-helpers.d.ts +32 -0
  33. package/dist/core/upload-helpers.js +79 -0
  34. package/dist/core/uploader.d.ts +70 -0
  35. package/dist/core/uploader.js +185 -0
  36. package/dist/index.d.ts +140 -0
  37. package/dist/index.esm.js +205 -0
  38. package/dist/index.js +244 -0
  39. package/dist/utils/logger.d.ts +28 -0
  40. package/dist/utils/logger.js +84 -0
  41. package/dist/utils/sanitize-patterns.d.ts +103 -0
  42. package/dist/utils/sanitize-patterns.js +282 -0
  43. package/dist/utils/sanitize.d.ts +73 -0
  44. package/dist/utils/sanitize.js +254 -0
  45. package/dist/widget/button.d.ts +33 -0
  46. package/dist/widget/button.js +143 -0
  47. package/dist/widget/components/dom-element-cache.d.ts +62 -0
  48. package/dist/widget/components/dom-element-cache.js +105 -0
  49. package/dist/widget/components/form-validator.d.ts +66 -0
  50. package/dist/widget/components/form-validator.js +115 -0
  51. package/dist/widget/components/pii-detection-display.d.ts +64 -0
  52. package/dist/widget/components/pii-detection-display.js +142 -0
  53. package/dist/widget/components/redaction-canvas.d.ts +95 -0
  54. package/dist/widget/components/redaction-canvas.js +230 -0
  55. package/dist/widget/components/screenshot-processor.d.ts +44 -0
  56. package/dist/widget/components/screenshot-processor.js +191 -0
  57. package/dist/widget/components/style-manager.d.ts +37 -0
  58. package/dist/widget/components/style-manager.js +296 -0
  59. package/dist/widget/components/template-manager.d.ts +66 -0
  60. package/dist/widget/components/template-manager.js +198 -0
  61. package/dist/widget/modal.d.ts +62 -0
  62. package/dist/widget/modal.js +299 -0
  63. package/docs/CDN.md +213 -0
  64. package/docs/FRAMEWORK_INTEGRATION.md +1104 -0
  65. package/docs/PUBLISHING.md +550 -0
  66. package/docs/SESSION_REPLAY.md +381 -0
  67. package/package.json +90 -0
@@ -0,0 +1,381 @@
1
+ # Session Replay Feature
2
+
3
+ ## Overview
4
+
5
+ The BugSpotter SDK now includes session replay functionality that captures DOM mutations, mouse movements, clicks, and scrolls using [rrweb](https://www.rrweb.io/). This feature maintains a circular buffer that keeps only the last 15-30 seconds of events (configurable), ensuring minimal memory footprint while providing valuable context for bug reports.
6
+
7
+ ## Key Features
8
+
9
+ - **Circular Buffer**: Time-based buffer that automatically prunes events older than the configured duration
10
+ - **Performance Optimized**: Configurable sampling rates for mousemove and scroll events
11
+ - **Automatic Recording**: Starts recording when BugSpotter initializes
12
+ - **Minimal Overhead**: Slim DOM recording options to reduce payload size
13
+ - **Serializable Events**: All events are JSON-serializable for easy transmission
14
+
15
+ ## Configuration
16
+
17
+ ### Basic Setup
18
+
19
+ By default, session replay is enabled with a 15-second buffer:
20
+
21
+ ```typescript
22
+ import { BugSpotter } from '@bugspotter/sdk';
23
+
24
+ BugSpotter.init({
25
+ apiKey: 'your-api-key',
26
+ endpoint: 'https://api.bugspotter.com',
27
+ });
28
+ ```
29
+
30
+ ### Custom Configuration
31
+
32
+ ```typescript
33
+ BugSpotter.init({
34
+ apiKey: 'your-api-key',
35
+ endpoint: 'https://api.bugspotter.com',
36
+ replay: {
37
+ enabled: true, // Enable/disable replay (default: true)
38
+ duration: 30, // Duration in seconds (default: 15, recommended max: 30)
39
+ sampling: {
40
+ mousemove: 50, // Throttle mousemove events to every 50ms (default: 50)
41
+ scroll: 100, // Throttle scroll events to every 100ms (default: 100)
42
+ },
43
+ },
44
+ });
45
+ ```
46
+
47
+ ### Disabling Replay
48
+
49
+ ```typescript
50
+ BugSpotter.init({
51
+ apiKey: 'your-api-key',
52
+ replay: {
53
+ enabled: false,
54
+ },
55
+ });
56
+ ```
57
+
58
+ ## How It Works
59
+
60
+ ### 1. Automatic Recording
61
+
62
+ When BugSpotter initializes, the DOM collector automatically starts recording if replay is enabled:
63
+
64
+ ```typescript
65
+ const bugspotter = BugSpotter.init(config);
66
+ // Recording starts automatically!
67
+ ```
68
+
69
+ ### 2. Circular Buffer
70
+
71
+ The circular buffer maintains only recent events:
72
+
73
+ - Events are timestamped as they're captured
74
+ - When new events are added, old events are automatically pruned
75
+ - Only events within the configured duration are kept
76
+
77
+ ### 3. Bug Report Inclusion
78
+
79
+ When a bug is reported, the last N seconds of events are included:
80
+
81
+ ```typescript
82
+ const report = await bugspotter.capture();
83
+ console.log(report.replay); // Array of rrweb events
84
+ ```
85
+
86
+ ### 4. Event Transmission
87
+
88
+ The replay events are included in the bug report payload:
89
+
90
+ ```typescript
91
+ {
92
+ title: "Bug title",
93
+ description: "Bug description",
94
+ report: {
95
+ screenshot: "...",
96
+ console: [...],
97
+ network: [...],
98
+ metadata: {...},
99
+ replay: [...] // rrweb events
100
+ }
101
+ }
102
+ ```
103
+
104
+ ## Event Types
105
+
106
+ The DOM collector captures the following event types:
107
+
108
+ - **DOM Mutations**: Element additions, removals, and attribute changes
109
+ - **Mouse Movements**: Throttled mousemove events
110
+ - **Mouse Interactions**: Clicks, double-clicks, context menu, etc.
111
+ - **Scroll Events**: Throttled scroll events
112
+ - **Viewport Resizes**: Window resize events
113
+ - **Input Changes**: Form input changes
114
+
115
+ ## Performance Considerations
116
+
117
+ ### Memory Usage
118
+
119
+ - The circular buffer automatically prunes old events
120
+ - Recommended duration: 15-30 seconds
121
+ - Longer durations = more memory usage
122
+
123
+ ### Sampling Rates
124
+
125
+ Default sampling rates are optimized for performance:
126
+
127
+ - **Mousemove**: 50ms (20 events/second)
128
+ - **Scroll**: 100ms (10 events/second)
129
+
130
+ Adjust these based on your needs:
131
+
132
+ ```typescript
133
+ replay: {
134
+ sampling: {
135
+ mousemove: 100, // Reduce to 10 events/second for better performance
136
+ scroll: 200, // Reduce to 5 events/second
137
+ }
138
+ }
139
+ ```
140
+
141
+ ### Slim DOM Options
142
+
143
+ The collector uses slim DOM options by default:
144
+
145
+ - Doesn't record script tags
146
+ - Doesn't record comments
147
+ - Doesn't record certain meta tags
148
+ - Doesn't inline images (reduces payload size)
149
+
150
+ ## Advanced Usage
151
+
152
+ ### Direct Access to DOM Collector
153
+
154
+ You can access the DOM collector directly for advanced use cases:
155
+
156
+ ```typescript
157
+ import { DOMCollector } from '@bugspotter/sdk';
158
+
159
+ const collector = new DOMCollector({
160
+ duration: 20,
161
+ sampling: {
162
+ mousemove: 100,
163
+ scroll: 200,
164
+ },
165
+ });
166
+
167
+ // Start recording
168
+ collector.startRecording();
169
+
170
+ // Get events
171
+ const events = collector.getEvents();
172
+
173
+ // Clear buffer
174
+ collector.clearBuffer();
175
+
176
+ // Stop recording
177
+ collector.stopRecording();
178
+
179
+ // Clean up
180
+ collector.destroy();
181
+ ```
182
+
183
+ ### Direct Access to Circular Buffer
184
+
185
+ ```typescript
186
+ import { CircularBuffer } from '@bugspotter/sdk';
187
+
188
+ const buffer = new CircularBuffer({
189
+ duration: 30, // 30 seconds
190
+ });
191
+
192
+ // Add events
193
+ buffer.add(event);
194
+ buffer.addBatch([event1, event2, event3]);
195
+
196
+ // Get events
197
+ const events = buffer.getEvents();
198
+
199
+ // Change duration
200
+ buffer.setDuration(60); // Change to 60 seconds
201
+
202
+ // Clear buffer
203
+ buffer.clear();
204
+ ```
205
+
206
+ ## Edge Cases
207
+
208
+ ### Iframes
209
+
210
+ The collector handles iframes gracefully:
211
+
212
+ - Cross-origin iframes are not recorded by default (security restriction)
213
+ - Same-origin iframes can be recorded with `recordCrossOriginIframes: true`
214
+
215
+ ### Shadow DOM
216
+
217
+ Shadow DOM is handled automatically by rrweb.
218
+
219
+ ### Single Page Applications
220
+
221
+ The collector works seamlessly with SPAs - it captures all DOM changes regardless of routing.
222
+
223
+ ## Troubleshooting
224
+
225
+ ### High Memory Usage
226
+
227
+ If you're experiencing high memory usage:
228
+
229
+ 1. Reduce the buffer duration: `duration: 10`
230
+ 2. Increase sampling rates: `mousemove: 200, scroll: 300`
231
+ 3. Check for memory leaks in your application
232
+
233
+ ### Missing Events
234
+
235
+ If events seem to be missing:
236
+
237
+ 1. Verify replay is enabled: `replay.enabled: true`
238
+ 2. Check the buffer duration is sufficient
239
+ 3. Verify events are within the time window
240
+
241
+ ### Performance Issues
242
+
243
+ If you're experiencing performance issues:
244
+
245
+ 1. Increase sampling rates to reduce event frequency
246
+ 2. Reduce buffer duration
247
+ 3. Consider disabling replay in development mode
248
+
249
+ ## Browser Compatibility
250
+
251
+ Session replay works in all modern browsers that support:
252
+
253
+ - MutationObserver API
254
+ - ES6 features
255
+ - Proxy API
256
+
257
+ Tested on:
258
+
259
+ - Chrome/Edge 90+
260
+ - Firefox 88+
261
+ - Safari 14+
262
+
263
+ ## Dependencies
264
+
265
+ - `rrweb@^2.0.0-alpha.4`: Core recording library
266
+ - `rrweb-snapshot@^2.0.0-alpha.4`: DOM snapshot library
267
+ - `@rrweb/types@^2.0.0-alpha.18`: TypeScript types
268
+
269
+ ## API Reference
270
+
271
+ ### BugSpotterConfig.replay
272
+
273
+ ```typescript
274
+ interface ReplayConfig {
275
+ enabled?: boolean; // Default: true
276
+ duration?: number; // Default: 15 seconds
277
+ sampling?: {
278
+ mousemove?: number; // Default: 50ms
279
+ scroll?: number; // Default: 100ms
280
+ };
281
+ }
282
+ ```
283
+
284
+ ### DOMCollector
285
+
286
+ ```typescript
287
+ class DOMCollector {
288
+ constructor(config?: DOMCollectorConfig);
289
+ startRecording(): void;
290
+ stopRecording(): void;
291
+ getEvents(): eventWithTime[];
292
+ getCompressedEvents(): eventWithTime[];
293
+ clearBuffer(): void;
294
+ isCurrentlyRecording(): boolean;
295
+ getBufferSize(): number;
296
+ setDuration(seconds: number): void;
297
+ getDuration(): number;
298
+ destroy(): void;
299
+ }
300
+ ```
301
+
302
+ ### CircularBuffer
303
+
304
+ ```typescript
305
+ class CircularBuffer {
306
+ constructor(config: CircularBufferConfig);
307
+ add(event: eventWithTime): void;
308
+ addBatch(events: eventWithTime[]): void;
309
+ getEvents(): eventWithTime[];
310
+ getCompressedEvents(): eventWithTime[];
311
+ clear(): void;
312
+ size(): number;
313
+ setDuration(seconds: number): void;
314
+ getDuration(): number;
315
+ }
316
+ ```
317
+
318
+ ## Examples
319
+
320
+ ### Example 1: Capturing a Bug Report
321
+
322
+ ```typescript
323
+ const bugspotter = BugSpotter.init({
324
+ apiKey: 'your-api-key',
325
+ replay: {
326
+ duration: 20,
327
+ },
328
+ });
329
+
330
+ // ... user interacts with the app ...
331
+
332
+ // When user reports a bug
333
+ const report = await bugspotter.capture();
334
+ console.log(report.replay.length); // Number of events captured
335
+ ```
336
+
337
+ ### Example 2: Custom Sampling
338
+
339
+ ```typescript
340
+ BugSpotter.init({
341
+ apiKey: 'your-api-key',
342
+ replay: {
343
+ duration: 15,
344
+ sampling: {
345
+ mousemove: 200, // Less frequent mousemove events
346
+ scroll: 300, // Less frequent scroll events
347
+ },
348
+ },
349
+ });
350
+ ```
351
+
352
+ ### Example 3: Programmatic Control
353
+
354
+ ```typescript
355
+ import { BugSpotter, DOMCollector } from '@bugspotter/sdk';
356
+
357
+ // Initialize without auto-start
358
+ const bugspotter = BugSpotter.init({
359
+ apiKey: 'your-api-key',
360
+ replay: {
361
+ enabled: false,
362
+ },
363
+ });
364
+
365
+ // Manually create and control collector
366
+ const collector = new DOMCollector({ duration: 30 });
367
+
368
+ // Start recording when needed
369
+ document.getElementById('start-btn').addEventListener('click', () => {
370
+ collector.startRecording();
371
+ });
372
+
373
+ // Stop recording when needed
374
+ document.getElementById('stop-btn').addEventListener('click', () => {
375
+ collector.stopRecording();
376
+ });
377
+ ```
378
+
379
+ ## License
380
+
381
+ See main package LICENSE file.
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@bugspotter/sdk",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "Professional bug reporting SDK with screenshots, session replay, and automatic error capture for web applications",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "browser": "dist/bugspotter.min.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.esm.js",
13
+ "require": "./dist/index.js",
14
+ "browser": "./dist/bugspotter.min.js"
15
+ }
16
+ },
17
+ "scripts": {
18
+ "dev": "webpack --watch --mode development",
19
+ "build": "npm run build:webpack && npm run build:esm && npm run build:cjs",
20
+ "build:webpack": "webpack --mode production",
21
+ "build:esm": "tsc --project tsconfig.build.json --module ES2020 --outDir dist/esm && shx mv dist/esm/index.js dist/index.esm.js && shx rm -rf dist/esm",
22
+ "build:cjs": "tsc --project tsconfig.build.json --module CommonJS --outDir dist",
23
+ "prepublishOnly": "npm run build && npm test",
24
+ "lint": "eslint \"src/**/*.{ts,js}\"",
25
+ "lint:fix": "eslint \"src/**/*.{ts,js}\" --fix",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest",
28
+ "test:ui": "vitest --ui",
29
+ "test:coverage": "vitest run --coverage",
30
+ "test:e2e": "vitest run --config vitest.e2e.config.ts",
31
+ "test:e2e:watch": "vitest --config vitest.e2e.config.ts",
32
+ "test:playwright": "playwright test",
33
+ "test:playwright:ui": "playwright test --ui"
34
+ },
35
+ "keywords": [
36
+ "bug-reporting",
37
+ "error-tracking",
38
+ "session-replay",
39
+ "screenshot",
40
+ "error-capture",
41
+ "debugging",
42
+ "monitoring",
43
+ "frontend",
44
+ "react",
45
+ "vue",
46
+ "angular",
47
+ "typescript"
48
+ ],
49
+ "author": "Apex Bridge Technology",
50
+ "license": "MIT",
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "https://github.com/apexbridge-tech/bugspotter.git",
54
+ "directory": "packages/sdk"
55
+ },
56
+ "bugs": {
57
+ "url": "https://github.com/apexbridge-tech/bugspotter/issues"
58
+ },
59
+ "homepage": "https://github.com/apexbridge-tech/bugspotter#readme",
60
+ "engines": {
61
+ "node": ">=16.0.0"
62
+ },
63
+ "publishConfig": {
64
+ "access": "public",
65
+ "registry": "https://registry.npmjs.org/"
66
+ },
67
+ "dependencies": {
68
+ "@bugspotter/types": "workspace:*",
69
+ "@rrweb/types": "2.0.0-alpha.18",
70
+ "html-to-image": "^1.11.13",
71
+ "pako": "^2.1.0",
72
+ "rrweb": "2.0.0-alpha.4",
73
+ "rrweb-snapshot": "2.0.0-alpha.4"
74
+ },
75
+ "devDependencies": {
76
+ "@playwright/test": "^1.48.0",
77
+ "@types/node": "^20.11.0",
78
+ "@types/pako": "^2.0.4",
79
+ "@vitest/coverage-v8": "^3.2.4",
80
+ "@vitest/ui": "^3.2.4",
81
+ "happy-dom": "^19.0.2",
82
+ "jsdom": "^24.1.0",
83
+ "shx": "^0.4.0",
84
+ "ts-loader": "^9.5.1",
85
+ "typescript": "^5.3.3",
86
+ "vitest": "^3.2.4",
87
+ "webpack": "^5.90.0",
88
+ "webpack-cli": "^5.1.4"
89
+ }
90
+ }