@bugspotter/sdk 0.1.0-alpha.2 → 0.1.2-alpha.5

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/CHANGELOG.md CHANGED
@@ -5,6 +5,52 @@ All notable changes to the BugSpotter SDK will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.2-alpha.5](https://github.com/apexbridge-tech/bugspotter/compare/sdk-v0.1.1-alpha.5...sdk-v0.1.2-alpha.5) (2025-11-12)
9
+
10
+ ### Bug Fixes
11
+
12
+ - **ci:** update SDK publish workflow to support prerelease tags ([#221](https://github.com/apexbridge-tech/bugspotter/issues/221)) ([dc4d7f2](https://github.com/apexbridge-tech/bugspotter/commit/dc4d7f2ef519afcf232704f05295729c6402008c))
13
+
14
+ ## [0.1.1-alpha.5](https://github.com/apexbridge-tech/bugspotter/compare/sdk-v0.1.0-alpha.5...sdk-v0.1.1-alpha.5) (2025-11-12)
15
+
16
+ ### Features
17
+
18
+ - add exponential backoff retry and offline queue support ([c3c2106](https://github.com/apexbridge-tech/bugspotter/commit/c3c21063b777da37011449b89431a63f987ea777))
19
+ - add FloatingButton widget and fix UMD exports ([b7e170e](https://github.com/apexbridge-tech/bugspotter/commit/b7e170eea47c7883722e59038a0d16b911c59588))
20
+ - add FloatingButton widget with refactored architecture ([87a3d0e](https://github.com/apexbridge-tech/bugspotter/commit/87a3d0e69cea86db01e2847323440f296f045b16))
21
+ - add gzip compression reducing payloads by 70-90% ([489e182](https://github.com/apexbridge-tech/bugspotter/commit/489e182ea072e3ffc43b58700b60288f6a255c22))
22
+ - add gzip compression reducing payloads by 70-90% ([c545acf](https://github.com/apexbridge-tech/bugspotter/commit/c545acf6fe9a973c74a54f63a560b4fd96465e83))
23
+ - add screenshot capture with html-to-image ([fae3eb7](https://github.com/apexbridge-tech/bugspotter/commit/fae3eb70fbf52d5b7c217f4d6d001735b661159d))
24
+ - add session replay with rrweb ([175bd74](https://github.com/apexbridge-tech/bugspotter/commit/175bd74765d7f49b4be681c02eae0d7bbe8b1bc4))
25
+ - add type safety system with shared types, Zod validation, and contract tests ([a3e436a](https://github.com/apexbridge-tech/bugspotter/commit/a3e436a931abda2cf30c85b32e5af2e011b7b3d9))
26
+ - complete BugSpotter v0.1.0 with full documentation ([651153b](https://github.com/apexbridge-tech/bugspotter/commit/651153b2d4c86b9653df6164539991ea92c41942))
27
+ - complete core SDK with all capture modules ([54fe97a](https://github.com/apexbridge-tech/bugspotter/commit/54fe97af32b2ee1aa09f5657b28b89e40454cb0a))
28
+ - fixed bug in NetworkCapture + eslint + prettier ([75e2d92](https://github.com/apexbridge-tech/bugspotter/commit/75e2d9290d82ea3f9b377e3b189ce933f7e3e336))
29
+ - initial project structure ([7109dc2](https://github.com/apexbridge-tech/bugspotter/commit/7109dc2e284ea8692081965e4b5a9cce4dc1b1e0))
30
+ - **sdk:** bump to 0.1.0-alpha.5 with improved release workflow ([#219](https://github.com/apexbridge-tech/bugspotter/issues/219)) ([a191b7b](https://github.com/apexbridge-tech/bugspotter/commit/a191b7b998863f00df4bd24f529057e4c4160a73))
31
+ - vitest configured + unit tests for capture ([381d11e](https://github.com/apexbridge-tech/bugspotter/commit/381d11e8ea45376c56ded0d62c2c37a726002acf))
32
+
33
+ ### Bug Fixes
34
+
35
+ - increase browser test timeout and add GitHub release permissions ([#142](https://github.com/apexbridge-tech/bugspotter/issues/142)) ([301600e](https://github.com/apexbridge-tech/bugspotter/commit/301600e5fa6c01e0a6ef0e3281a0c27206cc00e2))
36
+ - remove await from background queue processing ([174889d](https://github.com/apexbridge-tech/bugspotter/commit/174889d9df5541d0494b736d9b8c44bbcbdfbb7e))
37
+ - **sdk:** remove unused @bugspotter/types workspace dependency ([#146](https://github.com/apexbridge-tech/bugspotter/issues/146)) ([7fed00b](https://github.com/apexbridge-tech/bugspotter/commit/7fed00bafab22f1854b78f861a90069b96a665c1))
38
+
39
+ ### Code Refactoring
40
+
41
+ - Addressed comments on PR; ([fcb4888](https://github.com/apexbridge-tech/bugspotter/commit/fcb488813cd36147f6292c36f4540b23b7759e20))
42
+ - improve capture classes with options, types, and performance ([616bd35](https://github.com/apexbridge-tech/bugspotter/commit/616bd3502c7620f65494ae813ea39e87781b5a2f))
43
+ - improve transport and offline queue architecture ([01a27f3](https://github.com/apexbridge-tech/bugspotter/commit/01a27f3cc24d1211c65e4f0992fc969f40294e70))
44
+ - optimize demo & documentation structure ([22c2171](https://github.com/apexbridge-tech/bugspotter/commit/22c21712229f19b1280d1406c2fac60655d41c4a))
45
+ - Phase 2 - Extract shared capture architecture ([48d007c](https://github.com/apexbridge-tech/bugspotter/commit/48d007cecfc4651ded10a8c7fd4651fcec499fbd))
46
+ - Phase 2 - Extract shared capture architecture ([ea88dda](https://github.com/apexbridge-tech/bugspotter/commit/ea88dda3cdbb07d72f96d707a3ebb97edf93379c))
47
+ - Phase 2 - Extract shared capture architecture ([72f2425](https://github.com/apexbridge-tech/bugspotter/commit/72f242575c46c3c813bf15234ca95d5624b7d7d4))
48
+ - remove deprecated code and unused variables ([392bbb9](https://github.com/apexbridge-tech/bugspotter/commit/392bbb9c91e3d57a49b9650782b778aea9607d50))
49
+
50
+ ### Tests
51
+
52
+ - Add comprehensive edge case tests for DOM collector ([24b56b3](https://github.com/apexbridge-tech/bugspotter/commit/24b56b3317edd6df656f551c7d22db3cc03df7ac))
53
+
8
54
  ## [0.1.0] - 2025-11-01
9
55
 
10
56
  ### Added
package/README.md CHANGED
@@ -57,8 +57,12 @@ import BugSpotter from '@bugspotter/sdk';
57
57
 
58
58
  // Initialize with auto-widget
59
59
  const bugSpotter = BugSpotter.init({
60
- apiKey: 'bgs_your_api_key',
61
- endpoint: 'https://api.bugspotter.com',
60
+ endpoint: 'https://api.bugspotter.com/api/v1/reports',
61
+ auth: {
62
+ type: 'api-key',
63
+ apiKey: 'bgs_your_api_key',
64
+ projectId: 'your-project-uuid',
65
+ },
62
66
  showWidget: true,
63
67
  });
64
68
  ```
@@ -69,8 +73,12 @@ const bugSpotter = BugSpotter.init({
69
73
  const BugSpotter = require('@bugspotter/sdk');
70
74
 
71
75
  const bugSpotter = BugSpotter.init({
72
- apiKey: 'bgs_your_api_key',
73
- endpoint: 'https://api.bugspotter.com',
76
+ endpoint: 'https://api.bugspotter.com/api/v1/reports',
77
+ auth: {
78
+ type: 'api-key',
79
+ apiKey: 'bgs_your_api_key',
80
+ projectId: 'your-project-uuid',
81
+ },
74
82
  showWidget: true,
75
83
  });
76
84
  ```
@@ -82,79 +90,82 @@ const bugSpotter = BugSpotter.init({
82
90
  <script>
83
91
  // Initialize with auto-widget
84
92
  const bugSpotter = BugSpotter.init({
85
- apiKey: 'bgs_your_api_key',
86
- endpoint: 'https://api.bugspotter.com',
93
+ endpoint: 'https://api.bugspotter.com/api/v1/reports',
94
+ auth: {
95
+ type: 'api-key',
96
+ apiKey: 'bgs_your_api_key',
97
+ projectId: 'your-project-uuid',
98
+ },
87
99
  showWidget: true,
88
100
  });
89
101
  </script>
90
102
  ```
91
103
 
92
- ### Direct File Uploads (Presigned URLs)
104
+ ### How It Works
93
105
 
94
- For better performance with large files, use `DirectUploader` to upload files directly to storage:
106
+ The SDK automatically uses an **optimized presigned URL upload flow** (40% fewer HTTP requests):
95
107
 
96
108
  ```javascript
97
- import { DirectUploader, compressReplayEvents } from '@bugspotter/sdk';
98
-
99
- // 1. Create bug report (metadata only)
100
- const response = await fetch('https://api.example.com/api/v1/reports', {
101
- method: 'POST',
102
- headers: {
103
- 'Content-Type': 'application/json',
104
- 'x-api-key': 'bgs_your_api_key',
105
- },
106
- body: JSON.stringify({
107
- project_id: 'project-uuid',
108
- title: 'Bug title',
109
- description: 'Bug description',
110
- }),
111
- });
112
- const { id: bugId } = await response.json();
113
-
114
- // 2. Initialize DirectUploader
115
- const uploader = new DirectUploader({
116
- apiEndpoint: 'https://api.example.com',
117
- apiKey: 'bgs_your_api_key',
118
- projectId: 'project-uuid',
119
- bugId,
120
- });
109
+ import BugSpotter from '@bugspotter/sdk';
121
110
 
122
- // 3. Upload screenshot with progress tracking
123
- const screenshotBlob = await fetch(screenshotDataUrl).then((r) => r.blob());
124
- await uploader.uploadScreenshot(screenshotBlob, (progress) => {
125
- console.log(`Upload: ${progress.percentage}%`);
111
+ // 1. Initialize SDK with required auth
112
+ const bugSpotter = BugSpotter.init({
113
+ endpoint: 'https://api.bugspotter.com/api/v1/reports',
114
+ auth: {
115
+ type: 'api-key',
116
+ apiKey: 'bgs_your_api_key',
117
+ projectId: 'your-project-uuid', // Required for file uploads
118
+ },
119
+ showWidget: true,
126
120
  });
127
121
 
128
- // 4. Compress and upload replay
129
- const compressedReplay = await compressReplayEvents(replayEvents);
130
- await uploader.uploadReplay(compressedReplay);
131
-
132
- console.log('All uploads complete!');
122
+ // 2. Submit a bug report (SDK handles everything automatically)
123
+ // Optimized flow (3 HTTP requests instead of 5):
124
+ // - Step 1: POST /api/v1/reports with hasScreenshot/hasReplay flags
125
+ // → Returns bug ID + presigned URLs for screenshot & replay
126
+ // - Step 2: PUT to S3 presigned URLs (parallel uploads)
127
+ // - Step 3: POST /api/v1/reports/{id}/confirm-upload (confirm each file)
133
128
  ```
134
129
 
135
130
  **Benefits:**
136
131
 
137
- - 97% memory reduction (3.33MB 100KB API payload)
138
- - 3x faster uploads (direct to storage)
139
- - Progress tracking for large files
140
- - Automatic compression for replays
132
+ - **40% fewer HTTP requests** - 3 requests vs 5 in legacy flow
133
+ - Files upload directly to S3 (faster, no API bottleneck)
134
+ - Automatic compression for replay events
135
+ - Concurrent uploads (screenshot + replay in parallel)
136
+ - Reduced server load
141
137
 
142
- ### Manual Capture
138
+ ### Manual Capture & Programmatic Submission
143
139
 
144
140
  ```javascript
145
141
  // Initialize without widget
146
142
  const bugSpotter = BugSpotter.init({
147
- apiKey: 'your-api-key',
148
- endpoint: 'https://api.example.com/bugs',
143
+ endpoint: 'https://api.bugspotter.com/api/v1/reports',
144
+ auth: {
145
+ type: 'api-key',
146
+ apiKey: 'bgs_your_api_key',
147
+ projectId: 'your-project-uuid',
148
+ },
149
149
  showWidget: false,
150
150
  });
151
151
 
152
- // Capture bug report manually
153
- async function reportBug() {
154
- const report = await bugSpotter.capture();
155
- console.log('Captured:', report);
156
- // report contains: screenshot, console, network, metadata
157
- }
152
+ // Capture bug report data
153
+ const report = await bugSpotter.capture();
154
+ console.log('Captured:', report);
155
+ // report contains: screenshot, console, network, metadata, replay
156
+
157
+ // Submit programmatically (SDK handles presigned URL uploads)
158
+ await bugSpotter.submit({
159
+ title: 'Application crashed',
160
+ description: 'Error occurred during form submission',
161
+ priority: 'high',
162
+ report,
163
+ });
164
+ // ✅ SDK automatically:
165
+ // 1. Detects hasScreenshot/hasReplay from report data
166
+ // 2. Gets presigned URLs from backend
167
+ // 3. Uploads screenshot + replay to S3 (parallel)
168
+ // 4. Confirms uploads with backend
158
169
  ```
159
170
 
160
171
  ## 🎨 Using the Widget
@@ -164,8 +175,12 @@ async function reportBug() {
164
175
  ```javascript
165
176
  // Widget appears automatically with showWidget: true
166
177
  const bugSpotter = BugSpotter.init({
167
- apiKey: 'demo-key',
168
- endpoint: 'http://localhost:4000/api/bugs',
178
+ endpoint: 'https://api.bugspotter.com/api/v1/reports',
179
+ auth: {
180
+ type: 'api-key',
181
+ apiKey: 'bgs_your_api_key',
182
+ projectId: 'your-project-uuid',
183
+ },
169
184
  showWidget: true,
170
185
  widgetOptions: {
171
186
  position: 'bottom-right',
@@ -179,17 +194,35 @@ const bugSpotter = BugSpotter.init({
179
194
  ### Custom Widget
180
195
 
181
196
  ```javascript
182
- // Create custom floating button
197
+ // Default professional SVG icon (recommended)
183
198
  const button = new BugSpotter.FloatingButton({
199
+ position: 'bottom-right',
200
+ // icon: 'svg' is default - professional bug icon
201
+ backgroundColor: '#2563eb', // Professional blue (default)
202
+ tooltip: 'Report an Issue',
203
+ });
204
+
205
+ // Custom emoji/text icon
206
+ const button2 = new BugSpotter.FloatingButton({
184
207
  position: 'bottom-right',
185
208
  icon: '🐛',
186
209
  backgroundColor: '#ff4444',
187
210
  size: 56,
188
211
  offset: { x: 24, y: 24 },
189
- style: {
190
- boxShadow: '0 2px 8px rgba(0,0,0,0.2)',
191
- border: '2px solid white',
192
- },
212
+ });
213
+
214
+ // Custom SVG icon
215
+ const button3 = new BugSpotter.FloatingButton({
216
+ position: 'bottom-left',
217
+ customSvg: `
218
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
219
+ <path d="M12 2L2 7l10 5 10-5-10-5z"/>
220
+ <path d="M2 17l10 5 10-5M2 12l10 5 10-5"/>
221
+ </svg>
222
+ `,
223
+ tooltip: 'Custom Report Button',
224
+ backgroundColor: '#1a365d',
225
+ size: 48,
193
226
  });
194
227
 
195
228
  // Handle click
@@ -198,26 +231,16 @@ button.onClick(async () => {
198
231
 
199
232
  const modal = new BugSpotter.BugReportModal({
200
233
  onSubmit: async (data) => {
201
- // data.title, data.description
202
- const response = await fetch('https://api.example.com/bugs', {
203
- method: 'POST',
204
- headers: {
205
- 'Content-Type': 'application/json',
206
- Authorization: `Bearer ${apiKey}`,
207
- },
208
- body: JSON.stringify({
209
- ...data,
210
- report,
211
- }),
234
+ // Use SDK's submit() method for automatic presigned URL uploads
235
+ await bugSpotter.submit({
236
+ ...data, // title, description, priority
237
+ report,
212
238
  });
213
-
214
- if (!response.ok) {
215
- throw new Error('Submission failed');
216
- }
239
+ // ✅ SDK handles presigned URLs and S3 uploads automatically
217
240
  },
218
241
  });
219
242
 
220
- modal.show(report.screenshot);
243
+ modal.show(report._screenshotPreview || '');
221
244
  });
222
245
 
223
246
  // Control button
@@ -258,8 +281,13 @@ Initialize the SDK.
258
281
 
259
282
  ```typescript
260
283
  interface BugSpotterConfig {
261
- apiKey?: string; // API key for authentication
262
- endpoint?: string; // Backend API URL
284
+ endpoint: string; // Required: Backend API URL
285
+ auth: {
286
+ // Required: Authentication configuration
287
+ type: 'api-key';
288
+ apiKey: string; // API key (bgs_...)
289
+ projectId: string; // Project UUID (required for file uploads)
290
+ };
263
291
  showWidget?: boolean; // Auto-show widget (default: true)
264
292
  widgetOptions?: FloatingButtonOptions;
265
293
  replay?: {
@@ -290,6 +318,46 @@ interface BugSpotterConfig {
290
318
 
291
319
  **Returns:** `BugSpotter` instance
292
320
 
321
+ #### `bugSpotter.submit(payload)`
322
+
323
+ Submit a bug report with automatic file uploads via presigned URLs.
324
+
325
+ **Parameters:**
326
+
327
+ ```typescript
328
+ interface BugReportPayload {
329
+ title: string; // Bug title (required)
330
+ description?: string; // Bug description (optional)
331
+ priority?: 'low' | 'medium' | 'high' | 'critical';
332
+ report: BugReport; // Report data from capture()
333
+ }
334
+ ```
335
+
336
+ **Returns:** `Promise<void>`
337
+
338
+ **Throws:** Error if submission fails
339
+
340
+ **Example:**
341
+
342
+ ```typescript
343
+ const report = await bugSpotter.capture();
344
+
345
+ await bugSpotter.submit({
346
+ title: 'Button not responding',
347
+ description: 'Submit button does not work on checkout page',
348
+ priority: 'high',
349
+ report,
350
+ });
351
+ ```
352
+
353
+ **What it does:**
354
+
355
+ 1. Detects screenshot and replay from report data
356
+ 2. Requests presigned URLs from backend
357
+ 3. Uploads files directly to S3 (parallel)
358
+ 4. Confirms uploads with backend
359
+ 5. Handles errors and retries automatically
360
+
293
361
  #### `bugSpotter.capture()`
294
362
 
295
363
  Capture current bug report data.
@@ -298,11 +366,13 @@ Capture current bug report data.
298
366
 
299
367
  ```typescript
300
368
  interface BugReport {
301
- screenshot: string; // Base64 PNG data URL
369
+ screenshotKey?: string; // Storage key after presigned URL upload
302
370
  console: ConsoleLog[]; // Array of console entries
303
371
  network: NetworkRequest[]; // Array of network requests
304
372
  metadata: BrowserMetadata; // Browser/system info
305
- replay: eventWithTime[]; // Session replay events (rrweb format)
373
+ replay?: eventWithTime[]; // Session replay events (rrweb format)
374
+ replayKey?: string; // Storage key after presigned URL upload
375
+ _screenshotPreview?: string; // Internal: screenshot preview for modal (not sent to API)
306
376
  }
307
377
 
308
378
  interface ConsoleLog {
@@ -350,10 +420,12 @@ new FloatingButton(options?: FloatingButtonOptions)
350
420
 
351
421
  interface FloatingButtonOptions {
352
422
  position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
353
- icon?: string; // Emoji or text
354
- backgroundColor?: string; // CSS color
355
- size?: number; // Size in pixels
423
+ icon?: string; // 'svg' for default bug icon, or custom emoji/text
424
+ customSvg?: string; // Custom SVG icon (overrides icon if provided)
425
+ backgroundColor?: string; // CSS color (default: '#2563eb' professional blue)
426
+ size?: number; // Size in pixels (default: 56)
356
427
  offset?: { x: number; y: number };
428
+ tooltip?: string; // Custom tooltip text (default: 'Report an Issue')
357
429
  style?: Record<string, string>; // Additional CSS
358
430
  }
359
431
  ```