blinker-sdk 1.0.0 → 1.0.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.
- package/README.md +159 -35
- package/dist/Blinker.d.ts +20 -2
- package/dist/Blinker.d.ts.map +1 -1
- package/dist/blinker.min.js +1 -1
- package/dist/index.cjs.js +89 -6
- package/dist/index.d.ts +19 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +89 -6
- package/dist/types.d.ts +32 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@ Universal JavaScript SDK for error tracking and event capture. Works with **any
|
|
|
7
7
|
- 🚀 **Zero dependencies** - Lightweight and fast
|
|
8
8
|
- 🌐 **Universal** - Works in any JavaScript environment
|
|
9
9
|
- 🔄 **Automatic error capture** - Catches global errors and unhandled rejections
|
|
10
|
+
- 🧠 **Smart filtering** - Ignores common non-bugs (401, 403, ResizeObserver) by default
|
|
10
11
|
- 📊 **Custom events** - Track any event you need
|
|
11
12
|
- 📦 **Multiple formats** - ESM, CommonJS, and UMD (CDN)
|
|
12
13
|
- 🔒 **Type-safe** - Full TypeScript support
|
|
@@ -29,7 +30,7 @@ pnpm add blinker-sdk
|
|
|
29
30
|
<script src="https://unpkg.com/blinker-sdk/dist/blinker.min.js"></script>
|
|
30
31
|
<script>
|
|
31
32
|
const { blinker } = BlinkerSDK;
|
|
32
|
-
blinker.init({ token: 'your-token'
|
|
33
|
+
blinker.init({ token: 'your-token' });
|
|
33
34
|
</script>
|
|
34
35
|
```
|
|
35
36
|
|
|
@@ -38,13 +39,12 @@ pnpm add blinker-sdk
|
|
|
38
39
|
```javascript
|
|
39
40
|
import { blinker } from 'blinker-sdk';
|
|
40
41
|
|
|
41
|
-
// Initialize the SDK
|
|
42
|
-
blinker.init({
|
|
43
|
-
token: 'your-blinker-token',
|
|
44
|
-
api: 'https://api.example.com'
|
|
45
|
-
});
|
|
42
|
+
// Initialize the SDK - just pass your token!
|
|
43
|
+
blinker.init({ token: 'your-blinker-token' });
|
|
46
44
|
|
|
47
45
|
// That's it! Errors are now automatically captured.
|
|
46
|
+
// ✅ Ignores 401/403 errors by default
|
|
47
|
+
// ✅ Filters out common browser noise (ResizeObserver, Script error)
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
## Usage
|
|
@@ -54,15 +54,126 @@ blinker.init({
|
|
|
54
54
|
```javascript
|
|
55
55
|
import { blinker } from 'blinker-sdk';
|
|
56
56
|
|
|
57
|
+
// Minimal setup - just the token!
|
|
58
|
+
blinker.init({ token: 'your-blinker-token' });
|
|
59
|
+
|
|
60
|
+
// Or with custom options
|
|
57
61
|
blinker.init({
|
|
58
62
|
token: 'your-blinker-token', // Required: Your API token
|
|
59
|
-
api: 'https://api.example.com', // Required: API endpoint
|
|
60
63
|
captureErrors: true, // Optional: Auto-capture errors (default: true)
|
|
61
64
|
captureRejections: true, // Optional: Auto-capture promise rejections (default: true)
|
|
62
65
|
debug: false // Optional: Enable debug logging (default: false)
|
|
63
66
|
});
|
|
64
67
|
```
|
|
65
68
|
|
|
69
|
+
### Error Filters (Smart Defaults)
|
|
70
|
+
|
|
71
|
+
The SDK comes with **intelligent default filters** that ignore common non-bug errors. This prevents your error tracking from being cluttered with expected behaviors like authentication failures.
|
|
72
|
+
|
|
73
|
+
#### Default Behavior
|
|
74
|
+
|
|
75
|
+
By default, the SDK **ignores**:
|
|
76
|
+
- `401` and `403` HTTP errors (authentication/authorization - usually expected behavior)
|
|
77
|
+
- `ResizeObserver loop` errors (benign browser behavior)
|
|
78
|
+
- `Script error` (cross-origin errors with no useful info)
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
// Minimal initialization - all defaults applied automatically!
|
|
82
|
+
blinker.init({ token: 'your-token' });
|
|
83
|
+
// ✅ Automatically ignores: 401, 403, ResizeObserver loop, Script error
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Capture Everything
|
|
87
|
+
|
|
88
|
+
If you want to capture ALL errors including auth failures:
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
blinker.init({
|
|
92
|
+
token: 'your-token',
|
|
93
|
+
filters: { captureAll: true }
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### Custom HTTP Code Filters
|
|
98
|
+
|
|
99
|
+
Customize which HTTP codes to ignore:
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
// Only ignore 401 (capture 403)
|
|
103
|
+
blinker.init({
|
|
104
|
+
token: 'your-token',
|
|
105
|
+
filters: { ignoreHttpCodes: [401] }
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Ignore more codes
|
|
109
|
+
blinker.init({
|
|
110
|
+
token: 'your-token',
|
|
111
|
+
filters: { ignoreHttpCodes: [401, 403, 404, 429] }
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Capture ALL HTTP errors (empty array)
|
|
115
|
+
blinker.init({
|
|
116
|
+
token: 'your-token',
|
|
117
|
+
filters: { ignoreHttpCodes: [] }
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### Ignore Specific Error Types
|
|
122
|
+
|
|
123
|
+
Filter out specific JavaScript error types:
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
blinker.init({
|
|
127
|
+
token: 'your-token',
|
|
128
|
+
filters: { ignoreErrorTypes: ['TypeError', 'SyntaxError'] }
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### Ignore Message Patterns
|
|
133
|
+
|
|
134
|
+
Filter errors by message content (case-insensitive substring matching):
|
|
135
|
+
|
|
136
|
+
```javascript
|
|
137
|
+
blinker.init({
|
|
138
|
+
token: 'your-token',
|
|
139
|
+
filters: {
|
|
140
|
+
ignoreMessagePatterns: [
|
|
141
|
+
'ResizeObserver loop', // Default
|
|
142
|
+
'Script error', // Default
|
|
143
|
+
'ChunkLoadError', // Webpack chunk loading
|
|
144
|
+
'Loading chunk', // Next.js chunk loading
|
|
145
|
+
'Network request failed', // Offline users
|
|
146
|
+
'AbortError' // Cancelled requests
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Full Filter Configuration
|
|
153
|
+
|
|
154
|
+
All filter options together:
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
blinker.init({
|
|
158
|
+
token: 'your-token',
|
|
159
|
+
filters: {
|
|
160
|
+
ignoreHttpCodes: [401, 403, 404],
|
|
161
|
+
ignoreErrorTypes: ['AbortError'],
|
|
162
|
+
ignoreMessagePatterns: ['ResizeObserver loop', 'Script error', 'ChunkLoadError'],
|
|
163
|
+
captureAll: false
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### Check Current Filters
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
// Get the current filter configuration
|
|
172
|
+
const filters = blinker.getFilters();
|
|
173
|
+
console.log(filters);
|
|
174
|
+
// { ignoreHttpCodes: [401, 403], ignoreErrorTypes: [], ... }
|
|
175
|
+
```
|
|
176
|
+
|
|
66
177
|
### Track Custom Events
|
|
67
178
|
|
|
68
179
|
```javascript
|
|
@@ -123,10 +234,7 @@ blinker.destroy();
|
|
|
123
234
|
// app.jsx or index.jsx
|
|
124
235
|
import { blinker } from 'blinker-sdk';
|
|
125
236
|
|
|
126
|
-
blinker.init({
|
|
127
|
-
token: process.env.REACT_APP_BLINKER_TOKEN,
|
|
128
|
-
api: process.env.REACT_APP_BLINKER_API
|
|
129
|
-
});
|
|
237
|
+
blinker.init({ token: process.env.REACT_APP_BLINKER_TOKEN });
|
|
130
238
|
|
|
131
239
|
function App() {
|
|
132
240
|
const handleClick = () => {
|
|
@@ -148,10 +256,7 @@ import { blinker } from 'blinker-sdk';
|
|
|
148
256
|
|
|
149
257
|
export default function RootLayout({ children }) {
|
|
150
258
|
useEffect(() => {
|
|
151
|
-
blinker.init({
|
|
152
|
-
token: process.env.NEXT_PUBLIC_BLINKER_TOKEN,
|
|
153
|
-
api: process.env.NEXT_PUBLIC_BLINKER_API
|
|
154
|
-
});
|
|
259
|
+
blinker.init({ token: process.env.NEXT_PUBLIC_BLINKER_TOKEN });
|
|
155
260
|
}, []);
|
|
156
261
|
|
|
157
262
|
return (
|
|
@@ -170,10 +275,7 @@ import { createApp } from 'vue';
|
|
|
170
275
|
import { blinker } from 'blinker-sdk';
|
|
171
276
|
import App from './App.vue';
|
|
172
277
|
|
|
173
|
-
blinker.init({
|
|
174
|
-
token: import.meta.env.VITE_BLINKER_TOKEN,
|
|
175
|
-
api: import.meta.env.VITE_BLINKER_API
|
|
176
|
-
});
|
|
278
|
+
blinker.init({ token: import.meta.env.VITE_BLINKER_TOKEN });
|
|
177
279
|
|
|
178
280
|
createApp(App).mount('#app');
|
|
179
281
|
```
|
|
@@ -184,10 +286,7 @@ createApp(App).mount('#app');
|
|
|
184
286
|
// app.module.ts
|
|
185
287
|
import { blinker } from 'blinker-sdk';
|
|
186
288
|
|
|
187
|
-
blinker.init({
|
|
188
|
-
token: environment.blinkerToken,
|
|
189
|
-
api: environment.blinkerApi
|
|
190
|
-
});
|
|
289
|
+
blinker.init({ token: environment.blinkerToken });
|
|
191
290
|
|
|
192
291
|
@NgModule({
|
|
193
292
|
// ...
|
|
@@ -209,10 +308,7 @@ export class AppModule {}
|
|
|
209
308
|
<script>
|
|
210
309
|
const { blinker } = BlinkerSDK;
|
|
211
310
|
|
|
212
|
-
blinker.init({
|
|
213
|
-
token: 'your-token',
|
|
214
|
-
api: 'https://api.example.com'
|
|
215
|
-
});
|
|
311
|
+
blinker.init({ token: 'your-token' });
|
|
216
312
|
|
|
217
313
|
document.getElementById('myButton').addEventListener('click', () => {
|
|
218
314
|
blinker.track('click', 'Button clicked');
|
|
@@ -231,10 +327,19 @@ Initialize the SDK with configuration options.
|
|
|
231
327
|
| Option | Type | Default | Description |
|
|
232
328
|
|--------|------|---------|-------------|
|
|
233
329
|
| `token` | `string` | **required** | Your Blinker API token |
|
|
234
|
-
| `api` | `string` | **required** | API endpoint URL |
|
|
235
330
|
| `captureErrors` | `boolean` | `true` | Auto-capture window errors |
|
|
236
331
|
| `captureRejections` | `boolean` | `true` | Auto-capture unhandled rejections |
|
|
237
332
|
| `debug` | `boolean` | `false` | Enable debug logging |
|
|
333
|
+
| `filters` | `FilterSettings` | see below | Error filter configuration |
|
|
334
|
+
|
|
335
|
+
#### FilterSettings
|
|
336
|
+
|
|
337
|
+
| Option | Type | Default | Description |
|
|
338
|
+
|--------|------|---------|-------------|
|
|
339
|
+
| `ignoreHttpCodes` | `number[]` | `[401, 403]` | HTTP status codes to ignore |
|
|
340
|
+
| `ignoreErrorTypes` | `string[]` | `[]` | JS error types to ignore (e.g., 'TypeError') |
|
|
341
|
+
| `ignoreMessagePatterns` | `string[]` | `['ResizeObserver loop', 'Script error']` | Message patterns to ignore |
|
|
342
|
+
| `captureAll` | `boolean` | `false` | When true, disables all filters |
|
|
238
343
|
|
|
239
344
|
### `blinker.track(type, message, payload?)`
|
|
240
345
|
|
|
@@ -274,6 +379,15 @@ Check if SDK is initialized. Returns `boolean`.
|
|
|
274
379
|
|
|
275
380
|
Get current configuration (without token). Returns config object or `null`.
|
|
276
381
|
|
|
382
|
+
### `blinker.getFilters()`
|
|
383
|
+
|
|
384
|
+
Get current filter settings. Returns `FilterSettings` object.
|
|
385
|
+
|
|
386
|
+
```javascript
|
|
387
|
+
const filters = blinker.getFilters();
|
|
388
|
+
// { ignoreHttpCodes: [401, 403], ignoreErrorTypes: [], ignoreMessagePatterns: [...], captureAll: false }
|
|
389
|
+
```
|
|
390
|
+
|
|
277
391
|
### `blinker.destroy()`
|
|
278
392
|
|
|
279
393
|
Remove error handlers and reset SDK state.
|
|
@@ -300,28 +414,38 @@ Events sent to the API have the following structure:
|
|
|
300
414
|
The SDK is written in TypeScript and includes type definitions.
|
|
301
415
|
|
|
302
416
|
```typescript
|
|
303
|
-
import { blinker, BlinkerConfig,
|
|
417
|
+
import { blinker, BlinkerConfig, FilterSettings } from 'blinker-sdk';
|
|
304
418
|
|
|
419
|
+
// Minimal config - just the token!
|
|
420
|
+
blinker.init({ token: 'your-token' });
|
|
421
|
+
|
|
422
|
+
// Or with full typed config
|
|
305
423
|
const config: BlinkerConfig = {
|
|
306
424
|
token: 'your-token',
|
|
307
|
-
|
|
425
|
+
filters: {
|
|
426
|
+
ignoreHttpCodes: [401, 403, 404],
|
|
427
|
+
captureAll: false
|
|
428
|
+
}
|
|
308
429
|
};
|
|
309
430
|
|
|
310
431
|
blinker.init(config);
|
|
432
|
+
|
|
433
|
+
// Get typed filters
|
|
434
|
+
const filters: FilterSettings = blinker.getFilters();
|
|
311
435
|
```
|
|
312
436
|
|
|
313
437
|
## Multiple Instances
|
|
314
438
|
|
|
315
|
-
If you need multiple SDK instances:
|
|
439
|
+
If you need multiple SDK instances (e.g., different tokens for different app sections):
|
|
316
440
|
|
|
317
441
|
```javascript
|
|
318
442
|
import { Blinker } from 'blinker-sdk';
|
|
319
443
|
|
|
320
|
-
const
|
|
321
|
-
const
|
|
444
|
+
const frontendErrors = new Blinker();
|
|
445
|
+
const backendErrors = new Blinker();
|
|
322
446
|
|
|
323
|
-
|
|
324
|
-
|
|
447
|
+
frontendErrors.init({ token: 'frontend-token' });
|
|
448
|
+
backendErrors.init({ token: 'backend-token' });
|
|
325
449
|
```
|
|
326
450
|
|
|
327
451
|
## Browser Support
|
package/dist/Blinker.d.ts
CHANGED
|
@@ -2,15 +2,29 @@
|
|
|
2
2
|
* Blinker SDK Main Class
|
|
3
3
|
* Universal JavaScript SDK for error tracking and event capture
|
|
4
4
|
*/
|
|
5
|
-
import type { BlinkerConfig, SendResult } from './types';
|
|
5
|
+
import type { BlinkerConfig, SendResult, FilterSettings } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Default filter settings
|
|
8
|
+
* These are sensible defaults that ignore common non-bug errors
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_FILTERS: Required<FilterSettings>;
|
|
6
11
|
export declare class Blinker {
|
|
7
12
|
private config;
|
|
8
13
|
private initialized;
|
|
14
|
+
private filters;
|
|
9
15
|
/**
|
|
10
16
|
* Initialize the Blinker SDK
|
|
11
17
|
* @param config Configuration options
|
|
12
18
|
*/
|
|
13
19
|
init(config: BlinkerConfig): void;
|
|
20
|
+
/**
|
|
21
|
+
* Check if an error should be captured based on filter settings
|
|
22
|
+
* @param message Error message
|
|
23
|
+
* @param errorType Optional JS error type (e.g., 'TypeError')
|
|
24
|
+
* @param httpCode Optional HTTP status code
|
|
25
|
+
* @returns true if the error should be captured, false if filtered out
|
|
26
|
+
*/
|
|
27
|
+
private shouldCapture;
|
|
14
28
|
/**
|
|
15
29
|
* Track a custom event
|
|
16
30
|
* @param type Event type (e.g., 'click', 'pageview', 'custom')
|
|
@@ -21,7 +35,7 @@ export declare class Blinker {
|
|
|
21
35
|
/**
|
|
22
36
|
* Track an error manually
|
|
23
37
|
* @param error Error object or message
|
|
24
|
-
* @param additionalPayload Optional additional data
|
|
38
|
+
* @param additionalPayload Optional additional data (can include httpCode for filtering)
|
|
25
39
|
*/
|
|
26
40
|
captureError(error: Error | string, additionalPayload?: Record<string, unknown>): Promise<SendResult>;
|
|
27
41
|
/**
|
|
@@ -43,5 +57,9 @@ export declare class Blinker {
|
|
|
43
57
|
* Removes error handlers and resets state
|
|
44
58
|
*/
|
|
45
59
|
destroy(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Get current filter settings
|
|
62
|
+
*/
|
|
63
|
+
getFilters(): FilterSettings;
|
|
46
64
|
}
|
|
47
65
|
//# sourceMappingURL=Blinker.d.ts.map
|
package/dist/Blinker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Blinker.d.ts","sourceRoot":"","sources":["../src/Blinker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAwB,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Blinker.d.ts","sourceRoot":"","sources":["../src/Blinker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAwB,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAU/F;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,cAAc,CAapD,CAAC;AAEF,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,OAAO,CAAoD;IAEnE;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IA2DjC;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAwCrB;;;;;OAKG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAoB5F;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAyBrG;;;;OAIG;IACH,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IASlG;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,GAAG,IAAI;IAOhD;;;OAGG;IACH,OAAO,IAAI,IAAI;IAaf;;OAEG;IACH,UAAU,IAAI,cAAc;CAG7B"}
|
package/dist/blinker.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var BlinkerSDK=(()=>{var
|
|
1
|
+
"use strict";var BlinkerSDK=(()=>{var h=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var T=(u,e)=>{for(var n in e)h(u,n,{get:e[n],enumerable:!0})},P=(u,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of S(e))!C.call(u,t)&&t!==n&&h(u,t,{get:()=>e[t],enumerable:!(r=R(e,t))||r.enumerable});return u};var j=u=>P(h({},"__esModule",{value:!0}),u);var F={};T(F,{Blinker:()=>k,DEFAULT_FILTERS:()=>c,blinker:()=>b,default:()=>x});async function m(u,e,n,r=!1){let t=`${u.replace(/\/$/,"")}/events`,i=async()=>{try{let s=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json","x-blinker-token":e},body:JSON.stringify({type:n.type,message:n.message,payload:n.payload||{},timestamp:n.timestamp,url:n.url,userAgent:n.userAgent})});if(!s.ok){let o=await s.text().catch(()=>"Unknown error");return r&&console.error(`[Blinker] Failed to send event: ${s.status} - ${o}`),{success:!1,error:`HTTP ${s.status}: ${o}`}}return r&&console.log("[Blinker] Event sent successfully:",n.type),{success:!0}}catch(s){let o=s instanceof Error?s.message:"Unknown error";return r&&console.error("[Blinker] Error sending event:",o),{success:!1,error:o}}},l=await i();return!l.success&&typeof navigator!="undefined"&&!navigator.onLine&&(r&&console.log("[Blinker] Offline, waiting for connection to retry..."),await new Promise(a=>{let d=setTimeout(()=>a(!1),3e4),f=()=>{clearTimeout(d),typeof window!="undefined"&&window.removeEventListener("online",f),a(!0)};typeof window!="undefined"?window.addEventListener("online",f):a(!1)}))?(r&&console.log("[Blinker] Back online, retrying..."),i()):l}var g=null,p=null,E=!1;function v(u,e={}){let{captureErrors:n=!0,captureRejections:r=!0,debug:t=!1}=e;if(E){t&&console.warn("[Blinker] Error handlers already set up");return}if(typeof window=="undefined"){t&&console.log("[Blinker] Not in browser environment, skipping error handlers");return}n&&(g=window.onerror,window.onerror=function(i,l,s,o,a){let d=typeof i=="string"?i:i.type||"Unknown error",f={source:l,lineno:s,colno:o,stack:a==null?void 0:a.stack,errorType:a==null?void 0:a.name};return t&&console.log("[Blinker] Captured error:",d),u("error",d,f),typeof g=="function"?g.call(window,i,l,s,o,a):!1}),r&&(p=window.onunhandledrejection,window.onunhandledrejection=function(i){let l="Unhandled Rejection",s={},o=i.reason;if(o instanceof Error)l=o.message||l,s.stack=o.stack,s.errorType=o.name;else if(typeof o=="string")l=o;else if(o!=null)try{l=JSON.stringify(o)}catch(a){l=String(o)}t&&console.log("[Blinker] Captured unhandled rejection:",l),u("error",l,s),typeof p=="function"&&p.call(window,i)}),E=!0}function B(){typeof window!="undefined"&&(g!==void 0&&(window.onerror=g),p!==void 0&&(window.onunhandledrejection=p),g=null,p=null,E=!1)}var O="https://api.blinker.live",c={ignoreHttpCodes:[401,403],ignoreErrorTypes:[],ignoreMessagePatterns:["ResizeObserver loop","Script error","ResizeObserver loop completed"],captureAll:!1},k=class{constructor(){this.config=null;this.initialized=!1;this.filters={...c}}init(e){var n,r,t,i,l,s,o,a;if(this.initialized){e.debug&&console.warn("[Blinker] SDK already initialized");return}if(!e.token)throw new Error("[Blinker] Token is required");this.config={captureErrors:!0,captureRejections:!0,debug:!1,...e},this.filters={ignoreHttpCodes:(r=(n=e.filters)==null?void 0:n.ignoreHttpCodes)!=null?r:c.ignoreHttpCodes,ignoreErrorTypes:(i=(t=e.filters)==null?void 0:t.ignoreErrorTypes)!=null?i:c.ignoreErrorTypes,ignoreMessagePatterns:(s=(l=e.filters)==null?void 0:l.ignoreMessagePatterns)!=null?s:c.ignoreMessagePatterns,captureAll:(a=(o=e.filters)==null?void 0:o.captureAll)!=null?a:c.captureAll},this.config.debug&&console.log("[Blinker] Filters configured:",this.filters),(this.config.captureErrors||this.config.captureRejections)&&v((d,f,w)=>{var y;this.shouldCapture(f,w==null?void 0:w.errorType)?this.track(d,f,w):(y=this.config)!=null&&y.debug&&console.log("[Blinker] Error filtered out:",f)},{captureErrors:this.config.captureErrors,captureRejections:this.config.captureRejections,debug:this.config.debug}),this.initialized=!0,this.config.debug&&console.log("[Blinker] SDK initialized successfully")}shouldCapture(e,n,r){if(this.filters.captureAll)return!0;if(r!==void 0&&this.filters.ignoreHttpCodes.includes(r)||n&&this.filters.ignoreErrorTypes.includes(n))return!1;for(let t of this.filters.ignoreMessagePatterns)if(e.toLowerCase().includes(t.toLowerCase()))return!1;if(r===void 0){let t=e.match(/(?:HTTP\s*|status[:\s]*)?(\d{3})(?:\s|$|:)/i);if(t){let i=parseInt(t[1],10);if(i>=100&&i<600&&this.filters.ignoreHttpCodes.includes(i))return!1}}return!0}track(e,n,r){var i;if(!this.initialized||!this.config)return(i=this.config)!=null&&i.debug&&console.warn("[Blinker] SDK not initialized. Call blinker.init() first."),Promise.resolve({success:!1,error:"SDK not initialized"});let t={type:e,message:n,payload:r,timestamp:new Date().toISOString(),url:typeof window!="undefined"?window.location.href:void 0,userAgent:typeof navigator!="undefined"?navigator.userAgent:void 0};return m(O,this.config.token,t,this.config.debug)}captureError(e,n){var s;let r=e instanceof Error?e.message:e,t=e instanceof Error?e.name:void 0,i=n==null?void 0:n.httpCode;if(!this.shouldCapture(r,t,i))return(s=this.config)!=null&&s.debug&&console.log("[Blinker] Error filtered out:",{message:r,errorType:t,httpCode:i}),Promise.resolve({success:!0,error:"Filtered out by settings"});let l={...n};return e instanceof Error&&(l.stack=e.stack,l.errorType=e.name),this.track("error",r,l)}trackPageView(e,n){let r=e||(typeof window!="undefined"?window.location.pathname:"unknown");return this.track("pageview",r,{...n,referrer:typeof document!="undefined"?document.referrer:void 0})}isInitialized(){return this.initialized}getConfig(){if(!this.config)return null;let{token:e,...n}=this.config;return n}destroy(){var n;let e=(n=this.config)==null?void 0:n.debug;B(),this.config=null,this.initialized=!1,this.filters={...c},e&&console.log("[Blinker] SDK destroyed")}getFilters(){return{...this.filters}}};var b=new k;var x=b;return j(F);})();
|
package/dist/index.cjs.js
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
Blinker: () => Blinker,
|
|
24
|
+
DEFAULT_FILTERS: () => DEFAULT_FILTERS,
|
|
24
25
|
blinker: () => blinker,
|
|
25
26
|
default: () => index_default
|
|
26
27
|
});
|
|
@@ -181,16 +182,36 @@ function teardownErrorHandlers() {
|
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
// src/Blinker.ts
|
|
185
|
+
var BLINKER_API = "https://api.blinker.live";
|
|
186
|
+
var DEFAULT_FILTERS = {
|
|
187
|
+
// Auth/permission errors are usually expected behavior, not bugs
|
|
188
|
+
ignoreHttpCodes: [401, 403],
|
|
189
|
+
// All JS error types are captured by default
|
|
190
|
+
ignoreErrorTypes: [],
|
|
191
|
+
// Common benign browser errors that aren't actionable
|
|
192
|
+
ignoreMessagePatterns: [
|
|
193
|
+
"ResizeObserver loop",
|
|
194
|
+
// Common benign browser error
|
|
195
|
+
"Script error",
|
|
196
|
+
// Cross-origin script errors (no useful info)
|
|
197
|
+
"ResizeObserver loop completed"
|
|
198
|
+
// Another variant of ResizeObserver
|
|
199
|
+
],
|
|
200
|
+
// By default, respect the filters
|
|
201
|
+
captureAll: false
|
|
202
|
+
};
|
|
184
203
|
var Blinker = class {
|
|
185
204
|
constructor() {
|
|
186
205
|
this.config = null;
|
|
187
206
|
this.initialized = false;
|
|
207
|
+
this.filters = { ...DEFAULT_FILTERS };
|
|
188
208
|
}
|
|
189
209
|
/**
|
|
190
210
|
* Initialize the Blinker SDK
|
|
191
211
|
* @param config Configuration options
|
|
192
212
|
*/
|
|
193
213
|
init(config) {
|
|
214
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
194
215
|
if (this.initialized) {
|
|
195
216
|
if (config.debug) {
|
|
196
217
|
console.warn("[Blinker] SDK already initialized");
|
|
@@ -200,19 +221,30 @@ var Blinker = class {
|
|
|
200
221
|
if (!config.token) {
|
|
201
222
|
throw new Error("[Blinker] Token is required");
|
|
202
223
|
}
|
|
203
|
-
if (!config.api) {
|
|
204
|
-
throw new Error("[Blinker] API endpoint is required");
|
|
205
|
-
}
|
|
206
224
|
this.config = {
|
|
207
225
|
captureErrors: true,
|
|
208
226
|
captureRejections: true,
|
|
209
227
|
debug: false,
|
|
210
228
|
...config
|
|
211
229
|
};
|
|
230
|
+
this.filters = {
|
|
231
|
+
ignoreHttpCodes: (_b = (_a = config.filters) == null ? void 0 : _a.ignoreHttpCodes) != null ? _b : DEFAULT_FILTERS.ignoreHttpCodes,
|
|
232
|
+
ignoreErrorTypes: (_d = (_c = config.filters) == null ? void 0 : _c.ignoreErrorTypes) != null ? _d : DEFAULT_FILTERS.ignoreErrorTypes,
|
|
233
|
+
ignoreMessagePatterns: (_f = (_e = config.filters) == null ? void 0 : _e.ignoreMessagePatterns) != null ? _f : DEFAULT_FILTERS.ignoreMessagePatterns,
|
|
234
|
+
captureAll: (_h = (_g = config.filters) == null ? void 0 : _g.captureAll) != null ? _h : DEFAULT_FILTERS.captureAll
|
|
235
|
+
};
|
|
236
|
+
if (this.config.debug) {
|
|
237
|
+
console.log("[Blinker] Filters configured:", this.filters);
|
|
238
|
+
}
|
|
212
239
|
if (this.config.captureErrors || this.config.captureRejections) {
|
|
213
240
|
setupErrorHandlers(
|
|
214
241
|
(type, message, payload) => {
|
|
215
|
-
|
|
242
|
+
var _a2;
|
|
243
|
+
if (this.shouldCapture(message, payload == null ? void 0 : payload.errorType)) {
|
|
244
|
+
this.track(type, message, payload);
|
|
245
|
+
} else if ((_a2 = this.config) == null ? void 0 : _a2.debug) {
|
|
246
|
+
console.log("[Blinker] Error filtered out:", message);
|
|
247
|
+
}
|
|
216
248
|
},
|
|
217
249
|
{
|
|
218
250
|
captureErrors: this.config.captureErrors,
|
|
@@ -226,6 +258,41 @@ var Blinker = class {
|
|
|
226
258
|
console.log("[Blinker] SDK initialized successfully");
|
|
227
259
|
}
|
|
228
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Check if an error should be captured based on filter settings
|
|
263
|
+
* @param message Error message
|
|
264
|
+
* @param errorType Optional JS error type (e.g., 'TypeError')
|
|
265
|
+
* @param httpCode Optional HTTP status code
|
|
266
|
+
* @returns true if the error should be captured, false if filtered out
|
|
267
|
+
*/
|
|
268
|
+
shouldCapture(message, errorType, httpCode) {
|
|
269
|
+
if (this.filters.captureAll) {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
if (httpCode !== void 0 && this.filters.ignoreHttpCodes.includes(httpCode)) {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
if (errorType && this.filters.ignoreErrorTypes.includes(errorType)) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
for (const pattern of this.filters.ignoreMessagePatterns) {
|
|
279
|
+
if (message.toLowerCase().includes(pattern.toLowerCase())) {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (httpCode === void 0) {
|
|
284
|
+
const httpCodeMatch = message.match(/(?:HTTP\s*|status[:\s]*)?(\d{3})(?:\s|$|:)/i);
|
|
285
|
+
if (httpCodeMatch) {
|
|
286
|
+
const extractedCode = parseInt(httpCodeMatch[1], 10);
|
|
287
|
+
if (extractedCode >= 100 && extractedCode < 600) {
|
|
288
|
+
if (this.filters.ignoreHttpCodes.includes(extractedCode)) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
229
296
|
/**
|
|
230
297
|
* Track a custom event
|
|
231
298
|
* @param type Event type (e.g., 'click', 'pageview', 'custom')
|
|
@@ -248,15 +315,24 @@ var Blinker = class {
|
|
|
248
315
|
url: typeof window !== "undefined" ? window.location.href : void 0,
|
|
249
316
|
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0
|
|
250
317
|
};
|
|
251
|
-
return sendEvent(
|
|
318
|
+
return sendEvent(BLINKER_API, this.config.token, event, this.config.debug);
|
|
252
319
|
}
|
|
253
320
|
/**
|
|
254
321
|
* Track an error manually
|
|
255
322
|
* @param error Error object or message
|
|
256
|
-
* @param additionalPayload Optional additional data
|
|
323
|
+
* @param additionalPayload Optional additional data (can include httpCode for filtering)
|
|
257
324
|
*/
|
|
258
325
|
captureError(error, additionalPayload) {
|
|
326
|
+
var _a;
|
|
259
327
|
const message = error instanceof Error ? error.message : error;
|
|
328
|
+
const errorType = error instanceof Error ? error.name : void 0;
|
|
329
|
+
const httpCode = additionalPayload == null ? void 0 : additionalPayload.httpCode;
|
|
330
|
+
if (!this.shouldCapture(message, errorType, httpCode)) {
|
|
331
|
+
if ((_a = this.config) == null ? void 0 : _a.debug) {
|
|
332
|
+
console.log("[Blinker] Error filtered out:", { message, errorType, httpCode });
|
|
333
|
+
}
|
|
334
|
+
return Promise.resolve({ success: true, error: "Filtered out by settings" });
|
|
335
|
+
}
|
|
260
336
|
const payload = {
|
|
261
337
|
...additionalPayload
|
|
262
338
|
};
|
|
@@ -302,10 +378,17 @@ var Blinker = class {
|
|
|
302
378
|
teardownErrorHandlers();
|
|
303
379
|
this.config = null;
|
|
304
380
|
this.initialized = false;
|
|
381
|
+
this.filters = { ...DEFAULT_FILTERS };
|
|
305
382
|
if (wasDebug) {
|
|
306
383
|
console.log("[Blinker] SDK destroyed");
|
|
307
384
|
}
|
|
308
385
|
}
|
|
386
|
+
/**
|
|
387
|
+
* Get current filter settings
|
|
388
|
+
*/
|
|
389
|
+
getFilters() {
|
|
390
|
+
return { ...this.filters };
|
|
391
|
+
}
|
|
309
392
|
};
|
|
310
393
|
|
|
311
394
|
// src/index.ts
|
package/dist/index.d.ts
CHANGED
|
@@ -3,25 +3,33 @@
|
|
|
3
3
|
* Universal JavaScript SDK for error tracking and event capture
|
|
4
4
|
*
|
|
5
5
|
* @example
|
|
6
|
+
* // Minimal setup - just pass your token!
|
|
6
7
|
* import { blinker } from 'blinker-sdk';
|
|
7
8
|
*
|
|
8
|
-
* blinker.init({
|
|
9
|
-
* token: 'your-token',
|
|
10
|
-
* api: 'https://api.blinker.io'
|
|
11
|
-
* });
|
|
9
|
+
* blinker.init({ token: 'your-token' });
|
|
12
10
|
*
|
|
11
|
+
* // That's it! Errors are now automatically captured.
|
|
12
|
+
* // ✅ Ignores 401/403 errors by default
|
|
13
|
+
* // ✅ Filters out common browser noise
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
13
16
|
* // Track custom events
|
|
14
17
|
* blinker.track('click', 'Button clicked', { buttonId: 'submit' });
|
|
15
18
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* @example
|
|
20
|
+
* // With custom filters (for advanced users)
|
|
21
|
+
* blinker.init({
|
|
22
|
+
* token: 'your-token',
|
|
23
|
+
* filters: {
|
|
24
|
+
* ignoreHttpCodes: [401], // Only ignore 401
|
|
25
|
+
* captureAll: false // Respect filters
|
|
26
|
+
* }
|
|
27
|
+
* });
|
|
21
28
|
*/
|
|
22
|
-
import { Blinker } from './Blinker';
|
|
23
|
-
export type { BlinkerConfig, BlinkerEvent, BlinkerEventInternal, BlinkerErrorPayload, SendResult } from './types';
|
|
29
|
+
import { Blinker, DEFAULT_FILTERS } from './Blinker';
|
|
30
|
+
export type { BlinkerConfig, BlinkerEvent, BlinkerEventInternal, BlinkerErrorPayload, SendResult, FilterSettings } from './types';
|
|
24
31
|
export { Blinker };
|
|
32
|
+
export { DEFAULT_FILTERS };
|
|
25
33
|
declare const blinker: Blinker;
|
|
26
34
|
export { blinker };
|
|
27
35
|
export default blinker;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAGrD,YAAY,EACV,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,cAAc,EACf,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,OAAO,EAAE,CAAC;AAGnB,OAAO,EAAE,eAAe,EAAE,CAAC;AAG3B,QAAA,MAAM,OAAO,SAAgB,CAAC;AAE9B,OAAO,EAAE,OAAO,EAAE,CAAC;AAGnB,eAAe,OAAO,CAAC"}
|
package/dist/index.esm.js
CHANGED
|
@@ -153,16 +153,36 @@ function teardownErrorHandlers() {
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
// src/Blinker.ts
|
|
156
|
+
var BLINKER_API = "https://api.blinker.live";
|
|
157
|
+
var DEFAULT_FILTERS = {
|
|
158
|
+
// Auth/permission errors are usually expected behavior, not bugs
|
|
159
|
+
ignoreHttpCodes: [401, 403],
|
|
160
|
+
// All JS error types are captured by default
|
|
161
|
+
ignoreErrorTypes: [],
|
|
162
|
+
// Common benign browser errors that aren't actionable
|
|
163
|
+
ignoreMessagePatterns: [
|
|
164
|
+
"ResizeObserver loop",
|
|
165
|
+
// Common benign browser error
|
|
166
|
+
"Script error",
|
|
167
|
+
// Cross-origin script errors (no useful info)
|
|
168
|
+
"ResizeObserver loop completed"
|
|
169
|
+
// Another variant of ResizeObserver
|
|
170
|
+
],
|
|
171
|
+
// By default, respect the filters
|
|
172
|
+
captureAll: false
|
|
173
|
+
};
|
|
156
174
|
var Blinker = class {
|
|
157
175
|
constructor() {
|
|
158
176
|
this.config = null;
|
|
159
177
|
this.initialized = false;
|
|
178
|
+
this.filters = { ...DEFAULT_FILTERS };
|
|
160
179
|
}
|
|
161
180
|
/**
|
|
162
181
|
* Initialize the Blinker SDK
|
|
163
182
|
* @param config Configuration options
|
|
164
183
|
*/
|
|
165
184
|
init(config) {
|
|
185
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
166
186
|
if (this.initialized) {
|
|
167
187
|
if (config.debug) {
|
|
168
188
|
console.warn("[Blinker] SDK already initialized");
|
|
@@ -172,19 +192,30 @@ var Blinker = class {
|
|
|
172
192
|
if (!config.token) {
|
|
173
193
|
throw new Error("[Blinker] Token is required");
|
|
174
194
|
}
|
|
175
|
-
if (!config.api) {
|
|
176
|
-
throw new Error("[Blinker] API endpoint is required");
|
|
177
|
-
}
|
|
178
195
|
this.config = {
|
|
179
196
|
captureErrors: true,
|
|
180
197
|
captureRejections: true,
|
|
181
198
|
debug: false,
|
|
182
199
|
...config
|
|
183
200
|
};
|
|
201
|
+
this.filters = {
|
|
202
|
+
ignoreHttpCodes: (_b = (_a = config.filters) == null ? void 0 : _a.ignoreHttpCodes) != null ? _b : DEFAULT_FILTERS.ignoreHttpCodes,
|
|
203
|
+
ignoreErrorTypes: (_d = (_c = config.filters) == null ? void 0 : _c.ignoreErrorTypes) != null ? _d : DEFAULT_FILTERS.ignoreErrorTypes,
|
|
204
|
+
ignoreMessagePatterns: (_f = (_e = config.filters) == null ? void 0 : _e.ignoreMessagePatterns) != null ? _f : DEFAULT_FILTERS.ignoreMessagePatterns,
|
|
205
|
+
captureAll: (_h = (_g = config.filters) == null ? void 0 : _g.captureAll) != null ? _h : DEFAULT_FILTERS.captureAll
|
|
206
|
+
};
|
|
207
|
+
if (this.config.debug) {
|
|
208
|
+
console.log("[Blinker] Filters configured:", this.filters);
|
|
209
|
+
}
|
|
184
210
|
if (this.config.captureErrors || this.config.captureRejections) {
|
|
185
211
|
setupErrorHandlers(
|
|
186
212
|
(type, message, payload) => {
|
|
187
|
-
|
|
213
|
+
var _a2;
|
|
214
|
+
if (this.shouldCapture(message, payload == null ? void 0 : payload.errorType)) {
|
|
215
|
+
this.track(type, message, payload);
|
|
216
|
+
} else if ((_a2 = this.config) == null ? void 0 : _a2.debug) {
|
|
217
|
+
console.log("[Blinker] Error filtered out:", message);
|
|
218
|
+
}
|
|
188
219
|
},
|
|
189
220
|
{
|
|
190
221
|
captureErrors: this.config.captureErrors,
|
|
@@ -198,6 +229,41 @@ var Blinker = class {
|
|
|
198
229
|
console.log("[Blinker] SDK initialized successfully");
|
|
199
230
|
}
|
|
200
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Check if an error should be captured based on filter settings
|
|
234
|
+
* @param message Error message
|
|
235
|
+
* @param errorType Optional JS error type (e.g., 'TypeError')
|
|
236
|
+
* @param httpCode Optional HTTP status code
|
|
237
|
+
* @returns true if the error should be captured, false if filtered out
|
|
238
|
+
*/
|
|
239
|
+
shouldCapture(message, errorType, httpCode) {
|
|
240
|
+
if (this.filters.captureAll) {
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
if (httpCode !== void 0 && this.filters.ignoreHttpCodes.includes(httpCode)) {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
if (errorType && this.filters.ignoreErrorTypes.includes(errorType)) {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
for (const pattern of this.filters.ignoreMessagePatterns) {
|
|
250
|
+
if (message.toLowerCase().includes(pattern.toLowerCase())) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (httpCode === void 0) {
|
|
255
|
+
const httpCodeMatch = message.match(/(?:HTTP\s*|status[:\s]*)?(\d{3})(?:\s|$|:)/i);
|
|
256
|
+
if (httpCodeMatch) {
|
|
257
|
+
const extractedCode = parseInt(httpCodeMatch[1], 10);
|
|
258
|
+
if (extractedCode >= 100 && extractedCode < 600) {
|
|
259
|
+
if (this.filters.ignoreHttpCodes.includes(extractedCode)) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
201
267
|
/**
|
|
202
268
|
* Track a custom event
|
|
203
269
|
* @param type Event type (e.g., 'click', 'pageview', 'custom')
|
|
@@ -220,15 +286,24 @@ var Blinker = class {
|
|
|
220
286
|
url: typeof window !== "undefined" ? window.location.href : void 0,
|
|
221
287
|
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0
|
|
222
288
|
};
|
|
223
|
-
return sendEvent(
|
|
289
|
+
return sendEvent(BLINKER_API, this.config.token, event, this.config.debug);
|
|
224
290
|
}
|
|
225
291
|
/**
|
|
226
292
|
* Track an error manually
|
|
227
293
|
* @param error Error object or message
|
|
228
|
-
* @param additionalPayload Optional additional data
|
|
294
|
+
* @param additionalPayload Optional additional data (can include httpCode for filtering)
|
|
229
295
|
*/
|
|
230
296
|
captureError(error, additionalPayload) {
|
|
297
|
+
var _a;
|
|
231
298
|
const message = error instanceof Error ? error.message : error;
|
|
299
|
+
const errorType = error instanceof Error ? error.name : void 0;
|
|
300
|
+
const httpCode = additionalPayload == null ? void 0 : additionalPayload.httpCode;
|
|
301
|
+
if (!this.shouldCapture(message, errorType, httpCode)) {
|
|
302
|
+
if ((_a = this.config) == null ? void 0 : _a.debug) {
|
|
303
|
+
console.log("[Blinker] Error filtered out:", { message, errorType, httpCode });
|
|
304
|
+
}
|
|
305
|
+
return Promise.resolve({ success: true, error: "Filtered out by settings" });
|
|
306
|
+
}
|
|
232
307
|
const payload = {
|
|
233
308
|
...additionalPayload
|
|
234
309
|
};
|
|
@@ -274,10 +349,17 @@ var Blinker = class {
|
|
|
274
349
|
teardownErrorHandlers();
|
|
275
350
|
this.config = null;
|
|
276
351
|
this.initialized = false;
|
|
352
|
+
this.filters = { ...DEFAULT_FILTERS };
|
|
277
353
|
if (wasDebug) {
|
|
278
354
|
console.log("[Blinker] SDK destroyed");
|
|
279
355
|
}
|
|
280
356
|
}
|
|
357
|
+
/**
|
|
358
|
+
* Get current filter settings
|
|
359
|
+
*/
|
|
360
|
+
getFilters() {
|
|
361
|
+
return { ...this.filters };
|
|
362
|
+
}
|
|
281
363
|
};
|
|
282
364
|
|
|
283
365
|
// src/index.ts
|
|
@@ -285,6 +367,7 @@ var blinker = new Blinker();
|
|
|
285
367
|
var index_default = blinker;
|
|
286
368
|
export {
|
|
287
369
|
Blinker,
|
|
370
|
+
DEFAULT_FILTERS,
|
|
288
371
|
blinker,
|
|
289
372
|
index_default as default
|
|
290
373
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,20 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Blinker SDK Types
|
|
3
3
|
*/
|
|
4
|
+
/**
|
|
5
|
+
* Filter settings for controlling which errors are captured
|
|
6
|
+
* All settings are optional and come with sensible defaults
|
|
7
|
+
*/
|
|
8
|
+
export interface FilterSettings {
|
|
9
|
+
/**
|
|
10
|
+
* HTTP status codes to ignore (not capture)
|
|
11
|
+
* Default: [401, 403] - Auth/permission errors are usually expected, not bugs
|
|
12
|
+
*/
|
|
13
|
+
ignoreHttpCodes?: number[];
|
|
14
|
+
/**
|
|
15
|
+
* JavaScript error types to ignore (e.g., 'TypeError', 'SyntaxError')
|
|
16
|
+
* Default: [] - All error types are captured by default
|
|
17
|
+
*/
|
|
18
|
+
ignoreErrorTypes?: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Message patterns to ignore (substring matching)
|
|
21
|
+
* Default: ['ResizeObserver loop', 'Script error'] - Common benign browser errors
|
|
22
|
+
*/
|
|
23
|
+
ignoreMessagePatterns?: string[];
|
|
24
|
+
/**
|
|
25
|
+
* When true, disables ALL filters and captures everything
|
|
26
|
+
* Default: false
|
|
27
|
+
*/
|
|
28
|
+
captureAll?: boolean;
|
|
29
|
+
}
|
|
4
30
|
/**
|
|
5
31
|
* Configuration options for initializing the Blinker SDK
|
|
6
32
|
*/
|
|
7
33
|
export interface BlinkerConfig {
|
|
8
|
-
/** The authentication token for the Blinker API */
|
|
34
|
+
/** The authentication token for the Blinker API (REQUIRED) */
|
|
9
35
|
token: string;
|
|
10
|
-
/** The base URL of the Blinker API endpoint */
|
|
11
|
-
api: string;
|
|
12
36
|
/** Enable automatic error capture (default: true) */
|
|
13
37
|
captureErrors?: boolean;
|
|
14
38
|
/** Enable automatic unhandled rejection capture (default: true) */
|
|
15
39
|
captureRejections?: boolean;
|
|
16
40
|
/** Enable debug mode for logging (default: false) */
|
|
17
41
|
debug?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Filter settings for controlling which errors are captured
|
|
44
|
+
* By default, ignores common non-bug errors like 401, 403, ResizeObserver, etc.
|
|
45
|
+
*/
|
|
46
|
+
filters?: FilterSettings;
|
|
18
47
|
}
|
|
19
48
|
/**
|
|
20
49
|
* Event payload to be sent to the Blinker API
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAClE,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blinker-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Universal JavaScript SDK for error tracking and event capture - works with any framework",
|
|
5
5
|
"author": "Blinker",
|
|
6
6
|
"license": "MIT",
|
|
@@ -63,11 +63,10 @@
|
|
|
63
63
|
},
|
|
64
64
|
"repository": {
|
|
65
65
|
"type": "git",
|
|
66
|
-
"url": "https://github.com/blinker/blinker-sdk.git"
|
|
66
|
+
"url": "git+https://github.com/blinker/blinker-sdk.git"
|
|
67
67
|
},
|
|
68
68
|
"bugs": {
|
|
69
69
|
"url": "https://github.com/blinker/blinker-sdk/issues"
|
|
70
70
|
},
|
|
71
71
|
"homepage": "https://github.com/blinker/blinker-sdk#readme"
|
|
72
72
|
}
|
|
73
|
-
|