@devskin/browser-sdk 1.0.0

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 ADDED
@@ -0,0 +1,298 @@
1
+ # DevSkin Browser SDK
2
+
3
+ Comprehensive browser monitoring SDK for collecting user analytics, performance metrics, errors, and session recordings.
4
+
5
+ ## Features
6
+
7
+ - 📊 **Product Analytics**: Track custom events, page views, and user behavior
8
+ - 🎯 **Session Recording**: Record and replay user sessions with privacy controls
9
+ - ⚡ **Performance Monitoring**: Collect Core Web Vitals (LCP, FID, CLS, FCP, TTFB)
10
+ - 🐛 **Error Tracking**: Automatic error capture with breadcrumbs and context
11
+ - 🌐 **Network Monitoring**: Track all network requests (fetch, XHR)
12
+ - 📱 **Device Detection**: Comprehensive device, browser, and OS information
13
+ - 🌍 **Geolocation**: Optional location tracking with user permission
14
+ - 🔒 **Privacy-First**: Built-in privacy controls and data masking
15
+
16
+ ## Installation
17
+
18
+ ### Via CDN
19
+
20
+ ```html
21
+ <script src="https://cdn.devskin.com/sdk/devskin.umd.min.js"></script>
22
+ <script>
23
+ DevSkin.init({
24
+ apiKey: 'your-api-key',
25
+ appId: 'your-app-id',
26
+ });
27
+ </script>
28
+ ```
29
+
30
+ ### Via npm
31
+
32
+ ```bash
33
+ npm install @devskin/browser-sdk
34
+ ```
35
+
36
+ ```javascript
37
+ import DevSkin from '@devskin/browser-sdk';
38
+
39
+ DevSkin.init({
40
+ apiKey: 'your-api-key',
41
+ appId: 'your-app-id',
42
+ });
43
+ ```
44
+
45
+ ## Configuration
46
+
47
+ ```javascript
48
+ DevSkin.init({
49
+ // Required
50
+ apiKey: 'your-api-key',
51
+ appId: 'your-app-id',
52
+
53
+ // Optional
54
+ apiUrl: 'https://api.devskin.com',
55
+ debug: false,
56
+ environment: 'production',
57
+ release: '1.0.0',
58
+
59
+ // Feature flags
60
+ captureWebVitals: true,
61
+ captureNetworkRequests: true,
62
+ captureErrors: true,
63
+ captureUserAgent: true,
64
+ captureLocation: true,
65
+ captureDevice: true,
66
+
67
+ // Session Recording
68
+ sessionRecording: {
69
+ enabled: true,
70
+ maskAllInputs: true,
71
+ maskTextSelector: '.sensitive',
72
+ blockSelector: '.private',
73
+ sampling: 0.1, // Record 10% of sessions
74
+ recordCanvas: false,
75
+ recordCrossOriginIframes: false,
76
+ ignoreClass: 'devskin-block',
77
+ },
78
+
79
+ // Heatmap & User Behavior
80
+ heatmapOptions: {
81
+ enabled: true,
82
+ trackClicks: true, // Track click heatmaps
83
+ trackScroll: true, // Track scroll depth
84
+ trackMouseMovement: false, // Track mouse movement (can be heavy)
85
+ mouseMoveSampling: 0.1, // Sample 10% of mouse movements
86
+ },
87
+
88
+ // Network options
89
+ networkRequestOptions: {
90
+ ignoreUrls: [/analytics\.google\.com/],
91
+ captureHeaders: false,
92
+ captureBody: false,
93
+ captureFailedOnly: false,
94
+ },
95
+
96
+ // Error options
97
+ errorOptions: {
98
+ ignoreErrors: [/Script error/i],
99
+ denyUrls: [/extensions\//],
100
+ includeLocalVariables: true,
101
+ maxBreadcrumbs: 30,
102
+ },
103
+
104
+ // Privacy
105
+ privacy: {
106
+ respectDoNotTrack: true,
107
+ cookieConsent: false,
108
+ },
109
+
110
+ // Long task threshold (ms)
111
+ longTaskThreshold: 50,
112
+
113
+ // Callbacks
114
+ beforeSend: (event) => {
115
+ // Modify or filter events before sending
116
+ return event;
117
+ },
118
+ });
119
+ ```
120
+
121
+ ## Usage
122
+
123
+ ### Track Events
124
+
125
+ ```javascript
126
+ // Track a custom event
127
+ DevSkin.track('button_clicked', {
128
+ buttonId: 'signup',
129
+ page: '/landing',
130
+ });
131
+
132
+ // Track page view
133
+ DevSkin.trackPageView({
134
+ title: 'Home Page',
135
+ });
136
+ ```
137
+
138
+ ### Identify Users
139
+
140
+ ```javascript
141
+ DevSkin.identify('user-123', {
142
+ name: 'John Doe',
143
+ email: 'john@example.com',
144
+ plan: 'premium',
145
+ });
146
+ ```
147
+
148
+ ### Capture Errors
149
+
150
+ ```javascript
151
+ try {
152
+ // Your code
153
+ } catch (error) {
154
+ DevSkin.captureError(error, {
155
+ context: 'checkout_process',
156
+ step: 'payment',
157
+ });
158
+ }
159
+ ```
160
+
161
+ ### Add Breadcrumbs
162
+
163
+ ```javascript
164
+ DevSkin.addBreadcrumb({
165
+ category: 'ui',
166
+ message: 'User clicked submit button',
167
+ level: 'info',
168
+ data: {
169
+ formId: 'checkout-form',
170
+ },
171
+ });
172
+ ```
173
+
174
+ ### Control Recording
175
+
176
+ ```javascript
177
+ // Start recording
178
+ DevSkin.startRecording();
179
+
180
+ // Stop recording
181
+ DevSkin.stopRecording();
182
+ ```
183
+
184
+ ### Privacy Controls
185
+
186
+ ```javascript
187
+ // Opt out
188
+ DevSkin.optOut();
189
+
190
+ // Opt in
191
+ DevSkin.optIn();
192
+ ```
193
+
194
+ ## Data Collected
195
+
196
+ ### Automatic Data Collection
197
+
198
+ The SDK automatically collects:
199
+
200
+ - **Browser Info**: Name, version, engine, language, viewport size
201
+ - **Device Info**: Type (mobile/tablet/desktop), OS, screen resolution, memory, CPU cores
202
+ - **Location Info**: URL, hostname, pathname, referrer, timezone
203
+ - **Performance Metrics**: Core Web Vitals, navigation timing, resource timing
204
+ - **Network Requests**: URL, method, status, duration, size
205
+ - **Errors**: Message, stack trace, breadcrumbs, context
206
+ - **User Actions**: Clicks, navigation, console logs
207
+ - **Heatmap Data**: Click positions, scroll depth, mouse movement (if enabled)
208
+
209
+ ### Optional Data Collection
210
+
211
+ With user permission:
212
+ - **Geolocation**: Country, region, city, latitude, longitude
213
+ - **Session Recordings**: Full DOM replay with privacy controls
214
+
215
+ ## Privacy & Security
216
+
217
+ ### Data Masking
218
+
219
+ - All password inputs are automatically masked
220
+ - Email addresses are masked by default
221
+ - Use CSS classes to mask sensitive data:
222
+ - `.devskin-mask` - Mask text content
223
+ - `.devskin-block` - Completely block element from recording
224
+
225
+ ### Sampling
226
+
227
+ Record only a percentage of sessions to reduce data collection:
228
+
229
+ ```javascript
230
+ sessionRecording: {
231
+ enabled: true,
232
+ sampling: 0.1, // Record 10% of sessions
233
+ }
234
+ ```
235
+
236
+ ### Do Not Track
237
+
238
+ Respect browser DNT settings:
239
+
240
+ ```javascript
241
+ privacy: {
242
+ respectDoNotTrack: true,
243
+ }
244
+ ```
245
+
246
+ ### Cookie Consent
247
+
248
+ Wait for cookie consent before tracking:
249
+
250
+ ```javascript
251
+ privacy: {
252
+ cookieConsent: true,
253
+ }
254
+
255
+ // Later, after consent is given:
256
+ DevSkin.optIn();
257
+ ```
258
+
259
+ ## Browser Support
260
+
261
+ - Chrome/Edge: Latest 2 versions
262
+ - Firefox: Latest 2 versions
263
+ - Safari: Latest 2 versions
264
+ - Mobile browsers: iOS Safari 12+, Chrome Android
265
+
266
+ ## Performance Impact
267
+
268
+ The SDK is designed for minimal performance impact:
269
+
270
+ - Async initialization
271
+ - Efficient event batching
272
+ - Lazy loading of features
273
+ - Compressed payloads
274
+ - ~15KB gzipped
275
+
276
+ ## Development
277
+
278
+ ```bash
279
+ # Install dependencies
280
+ npm install
281
+
282
+ # Development build with watch
283
+ npm run dev
284
+
285
+ # Production build
286
+ npm run build
287
+
288
+ # Type checking
289
+ npm run type-check
290
+ ```
291
+
292
+ ## License
293
+
294
+ MIT License
295
+
296
+ ## Support
297
+
298
+ For issues and questions, please visit: https://github.com/devskin/browser-sdk
@@ -0,0 +1,11 @@
1
+ import { DevSkinConfig, BrowserInfo } from '../types';
2
+ export declare class BrowserCollector {
3
+ private config;
4
+ constructor(config: DevSkinConfig);
5
+ collect(): BrowserInfo;
6
+ private getBrowserName;
7
+ private getBrowserVersion;
8
+ private getEngine;
9
+ private getDoNotTrack;
10
+ }
11
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/collectors/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEtD,qBAAa,gBAAgB;IACf,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEzC,OAAO,IAAI,WAAW;IAmBtB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,aAAa;CAStB"}
@@ -0,0 +1,16 @@
1
+ import { DevSkinConfig, DeviceInfo } from '../types';
2
+ export declare class DeviceCollector {
3
+ private config;
4
+ constructor(config: DevSkinConfig);
5
+ collect(): DeviceInfo;
6
+ private getDeviceType;
7
+ private getVendor;
8
+ private getModel;
9
+ private getOS;
10
+ private getScreenInfo;
11
+ private getOrientation;
12
+ private getMemory;
13
+ private getCores;
14
+ private getConnection;
15
+ }
16
+ //# sourceMappingURL=device.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/collectors/device.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAErD,qBAAa,eAAe;IACd,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEzC,OAAO,IAAI,UAAU;IAarB,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,KAAK;IAoCb,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,aAAa;CAatB"}
@@ -0,0 +1,23 @@
1
+ import { DevSkinConfig, Breadcrumb } from '../types';
2
+ import { Transport } from '../transport';
3
+ export declare class ErrorCollector {
4
+ private config;
5
+ private transport;
6
+ private breadcrumbs;
7
+ private maxBreadcrumbs;
8
+ constructor(config: DevSkinConfig, transport: Transport);
9
+ start(): void;
10
+ captureError(error: Error | string, context?: Record<string, any>): void;
11
+ addBreadcrumb(breadcrumb: {
12
+ category: string;
13
+ message: string;
14
+ level?: 'info' | 'warning' | 'error';
15
+ data?: Record<string, any>;
16
+ }): void;
17
+ private handleError;
18
+ private shouldIgnoreError;
19
+ private setupAutomaticBreadcrumbs;
20
+ private wrapConsole;
21
+ getBreadcrumbs(): Breadcrumb[];
22
+ }
23
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/collectors/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAa,UAAU,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,qBAAa,cAAc;IAKvB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS;IALnB,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,cAAc,CAAS;gBAGrB,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS;IAK9B,KAAK,IAAI,IAAI;IAqBb,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAIxE,aAAa,CAAC,UAAU,EAAE;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;QACrC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAC5B,GAAG,IAAI;IAqBR,OAAO,CAAC,WAAW;IA2EnB,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,yBAAyB;IAwDjC,OAAO,CAAC,WAAW;IAsBnB,cAAc,IAAI,UAAU,EAAE;CAG/B"}
@@ -0,0 +1,21 @@
1
+ import { DevSkinConfig } from '../types';
2
+ import { Transport } from '../transport';
3
+ export declare class HeatmapCollector {
4
+ private config;
5
+ private transport;
6
+ private clickData;
7
+ private scrollData;
8
+ private mouseMoveData;
9
+ private maxScrollDepth;
10
+ private flushInterval;
11
+ private mouseMoveSampling;
12
+ constructor(config: DevSkinConfig, transport: Transport);
13
+ start(): void;
14
+ stop(): void;
15
+ private trackClicks;
16
+ private trackScrollDepth;
17
+ private trackMouseMovement;
18
+ private flush;
19
+ private getElementSelector;
20
+ }
21
+ //# sourceMappingURL=heatmap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heatmap.d.ts","sourceRoot":"","sources":["../../src/collectors/heatmap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAkCzC,qBAAa,gBAAgB;IASzB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS;IATnB,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,iBAAiB,CAAO;gBAGtB,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS;IAG9B,KAAK,IAAI,IAAI;IAoCb,IAAI,IAAI,IAAI;IAQZ,OAAO,CAAC,WAAW;IA8CnB,OAAO,CAAC,gBAAgB;IA2CxB,OAAO,CAAC,kBAAkB;IAkC1B,OAAO,CAAC,KAAK;IA0Bb,OAAO,CAAC,kBAAkB;CAc3B"}
@@ -0,0 +1,10 @@
1
+ import { DevSkinConfig, LocationInfo } from '../types';
2
+ export declare class LocationCollector {
3
+ private config;
4
+ private geoData;
5
+ constructor(config: DevSkinConfig);
6
+ collect(): LocationInfo;
7
+ private requestGeolocation;
8
+ private reverseGeocode;
9
+ }
10
+ //# sourceMappingURL=location.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"location.d.ts","sourceRoot":"","sources":["../../src/collectors/location.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEvD,qBAAa,iBAAiB;IAUhB,OAAO,CAAC,MAAM;IAT1B,OAAO,CAAC,OAAO,CAOC;gBAEI,MAAM,EAAE,aAAa;IAMzC,OAAO,IAAI,YAAY;YAcT,kBAAkB;YAqClB,cAAc;CA6B7B"}
@@ -0,0 +1,15 @@
1
+ import { DevSkinConfig } from '../types';
2
+ import { Transport } from '../transport';
3
+ export declare class NetworkCollector {
4
+ private config;
5
+ private transport;
6
+ constructor(config: DevSkinConfig, transport: Transport);
7
+ start(): void;
8
+ private interceptFetch;
9
+ private interceptXHR;
10
+ private shouldIgnoreUrl;
11
+ private getResponseSize;
12
+ private headersToObject;
13
+ private parseResponseHeaders;
14
+ }
15
+ //# sourceMappingURL=network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/collectors/network.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS;gBADT,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS;IAG9B,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,cAAc;IA6FtB,OAAO,CAAC,YAAY;IA8HpB,OAAO,CAAC,eAAe;YAiBT,eAAe;IAS7B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,oBAAoB;CAgB7B"}
@@ -0,0 +1,15 @@
1
+ import { DevSkinConfig, PerformanceMetrics } from '../types';
2
+ import { Transport } from '../transport';
3
+ export declare class PerformanceCollector {
4
+ private config;
5
+ private transport;
6
+ private metrics;
7
+ constructor(config: DevSkinConfig, transport: Transport);
8
+ start(): void;
9
+ private handleMetric;
10
+ private collectNavigationTimings;
11
+ private collectResourceTimings;
12
+ private observeLongTasks;
13
+ getMetrics(): PerformanceMetrics;
14
+ }
15
+ //# sourceMappingURL=performance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../../src/collectors/performance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE7D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS;IAJnB,OAAO,CAAC,OAAO,CAA0B;gBAG/B,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS;IAG9B,KAAK,IAAI,IAAI;IAoBb,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,wBAAwB;IA0ChC,OAAO,CAAC,sBAAsB;IA0C9B,OAAO,CAAC,gBAAgB;IAiCxB,UAAU,IAAI,kBAAkB;CAGjC"}