@syntropysoft/syntropyfront 0.1.0-alpha.1 โ 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +317 -219
- package/dist/index.cjs +308 -3234
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +309 -3231
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +14 -12
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="./assets/syntropysoft-logo.png" alt="
|
|
2
|
+
<img src="./assets/syntropysoft-logo.png" alt="SyntropySoft Logo" width="170"/>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">SyntropyFront</h1>
|
|
@@ -9,314 +9,412 @@
|
|
|
9
9
|
<br />
|
|
10
10
|
The Observability Framework for High-Performance Teams
|
|
11
11
|
</p>
|
|
12
|
+
|
|
12
13
|
<p align="center">
|
|
13
|
-
|
|
14
|
-
<
|
|
14
|
+
<a href="https://www.npmjs.com/package/@syntropysoft/syntropyfront"><img src="https://img.shields.io/npm/v/@syntropysoft/syntropyfront.svg" alt="NPM Version"></a>
|
|
15
|
+
<a href="https://github.com/Syntropysoft/SyntropyLog/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@syntropysoft/syntropyfront.svg" alt="License"></a>
|
|
16
|
+
<a href="#"><img src="https://img.shields.io/badge/status-ready%20for%20production-brightgreen.svg" alt="Ready for Production"></a>
|
|
15
17
|
</p>
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
---
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
- **โก Worker Architecture** - Non-blocking data collection and processing
|
|
21
|
-
- **๐ก๏ธ Circular Reference Handling** - Robust serialization for complex objects
|
|
22
|
-
- **๐ฏ Configuration Presets** - Pre-configured setups for different use cases
|
|
23
|
-
- **๐ฆ Lazy Loading** - Dynamic module loading for optimal bundle size
|
|
24
|
-
- **๐ Framework Agnostic** - Works with any JavaScript framework
|
|
25
|
-
- **๐ Breadcrumb System** - Comprehensive user action tracking
|
|
26
|
-
- **๐ Automatic Retry** - Exponential backoff with persistent buffer
|
|
27
|
-
- **๐ Privacy First** - Granular context collection with opt-in sensitive data
|
|
21
|
+
๐ **Observability library with automatic capture - Just 1 line of code!**
|
|
28
22
|
|
|
29
|
-
|
|
23
|
+
SyntropyFront automatically captures user interactions, errors, HTTP calls, and console logs, providing comprehensive observability for your web applications with minimal setup.
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
## โจ Features
|
|
26
|
+
|
|
27
|
+
- ๐ฏ **Automatic click capture** - Tracks all user interactions
|
|
28
|
+
- ๐จ **Error detection** - Catches uncaught exceptions and promise rejections
|
|
29
|
+
- ๐ **HTTP monitoring** - Intercepts fetch calls automatically
|
|
30
|
+
- ๐ **Console logging** - Records console.log, console.error, console.warn
|
|
31
|
+
- ๐พ **Smart storage** - Keeps the last N events (configurable)
|
|
32
|
+
- ๐ค **Flexible posting** - Posts errors to your endpoint or logs to console
|
|
33
|
+
- โก **Zero configuration** - Works out of the box with just an import
|
|
34
|
+
|
|
35
|
+
## ๐ Quick Start
|
|
36
|
+
|
|
37
|
+
### Basic Usage (1 line of code!)
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
import syntropyFront from 'syntropyfront';
|
|
41
|
+
// That's it! Auto-initializes and captures everything automatically
|
|
33
42
|
```
|
|
34
43
|
|
|
35
|
-
|
|
44
|
+
### With Custom Configuration
|
|
36
45
|
|
|
37
46
|
```javascript
|
|
38
|
-
import
|
|
47
|
+
import syntropyFront from 'syntropyfront';
|
|
39
48
|
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
agent: {
|
|
44
|
-
endpoint: 'https://your-api.com/errors'
|
|
45
|
-
}
|
|
49
|
+
// Option 1: Console only (default)
|
|
50
|
+
syntropyFront.configure({
|
|
51
|
+
maxEvents: 50
|
|
46
52
|
});
|
|
47
53
|
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
// Option 2: With endpoint (automatic fetch)
|
|
55
|
+
syntropyFront.configure({
|
|
56
|
+
maxEvents: 50,
|
|
57
|
+
fetch: {
|
|
58
|
+
url: 'https://your-api.com/errors',
|
|
59
|
+
options: {
|
|
60
|
+
headers: {
|
|
61
|
+
'Authorization': 'Bearer your-token',
|
|
62
|
+
'Content-Type': 'application/json'
|
|
63
|
+
},
|
|
64
|
+
mode: 'cors'
|
|
65
|
+
}
|
|
66
|
+
}
|
|
52
67
|
});
|
|
53
68
|
|
|
54
|
-
//
|
|
55
|
-
|
|
69
|
+
// Option 3: With custom error handler (maximum flexibility)
|
|
70
|
+
syntropyFront.configure({
|
|
71
|
+
maxEvents: 50,
|
|
72
|
+
onError: (errorPayload) => {
|
|
73
|
+
// You can do anything with the error:
|
|
74
|
+
// - Send to your API
|
|
75
|
+
// - Save to localStorage
|
|
76
|
+
// - Send to a repository
|
|
77
|
+
// - Upload to cloud
|
|
78
|
+
// - Whatever you want!
|
|
79
|
+
console.log('Error captured:', errorPayload);
|
|
80
|
+
|
|
81
|
+
// Example: send to multiple places
|
|
82
|
+
fetch('https://api1.com/errors', {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
body: JSON.stringify(errorPayload)
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Also save locally
|
|
88
|
+
localStorage.setItem('lastError', JSON.stringify(errorPayload));
|
|
89
|
+
}
|
|
90
|
+
});
|
|
56
91
|
```
|
|
57
92
|
|
|
58
|
-
##
|
|
93
|
+
## ๐ฆ Installation
|
|
59
94
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
preset: 'safe',
|
|
64
|
-
agent: { endpoint: 'https://api.com/errors' }
|
|
65
|
-
});
|
|
66
|
-
```
|
|
67
|
-
- **Use case**: Production environments with privacy concerns
|
|
68
|
-
- **Features**: Errors only, minimal context, no tracking
|
|
69
|
-
- **Bundle size**: ~25KB
|
|
95
|
+
```bash
|
|
96
|
+
npm install syntropyfront
|
|
97
|
+
## ๐ฏ How It Works
|
|
70
98
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
99
|
+
SyntropyFront automatically:
|
|
100
|
+
|
|
101
|
+
1. **Captures clicks** - Records element info, coordinates, and timestamps
|
|
102
|
+
2. **Detects errors** - Intercepts `window.onerror` and `window.onunhandledrejection`
|
|
103
|
+
3. **Monitors HTTP** - Wraps `window.fetch` to track requests and responses
|
|
104
|
+
4. **Logs console** - Intercepts console methods to capture debug info
|
|
105
|
+
5. **Maintains context** - Keeps the last N events as breadcrumbs
|
|
106
|
+
6. **Posts errors** - Sends error data with full context to your endpoint
|
|
107
|
+
|
|
108
|
+
## ๐ What Gets Captured
|
|
109
|
+
|
|
110
|
+
### Error Payload Structure
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"type": "uncaught_exception",
|
|
115
|
+
"error": {
|
|
116
|
+
"message": "Error message",
|
|
117
|
+
"source": "file.js",
|
|
118
|
+
"lineno": 42,
|
|
119
|
+
"colno": 15,
|
|
120
|
+
"stack": "Error stack trace..."
|
|
121
|
+
},
|
|
122
|
+
"breadcrumbs": [
|
|
123
|
+
{
|
|
124
|
+
"category": "user",
|
|
125
|
+
"message": "click",
|
|
126
|
+
"data": {
|
|
127
|
+
"element": "BUTTON",
|
|
128
|
+
"id": "submit-btn",
|
|
129
|
+
"className": "btn-primary",
|
|
130
|
+
"x": 100,
|
|
131
|
+
"y": 200
|
|
132
|
+
},
|
|
133
|
+
"timestamp": "2024-01-01T12:00:00.000Z"
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"timestamp": "2024-01-01T12:00:00.000Z"
|
|
137
|
+
}
|
|
77
138
|
```
|
|
78
|
-
- **Use case**: General production use
|
|
79
|
-
- **Features**: Periodic sending, curated context, moderate tracking
|
|
80
|
-
- **Bundle size**: ~60KB
|
|
81
139
|
|
|
82
|
-
###
|
|
140
|
+
### Breadcrumb Categories
|
|
141
|
+
|
|
142
|
+
- **`user`** - Click events, form submissions, etc.
|
|
143
|
+
- **`http`** - Fetch requests, responses, and errors
|
|
144
|
+
- **`console`** - Console.log, console.error, console.warn
|
|
145
|
+
- **`error`** - Manual error reports
|
|
146
|
+
|
|
147
|
+
## โ๏ธ Configuration Options
|
|
148
|
+
|
|
149
|
+
SyntropyFront uses a priority system for error handling:
|
|
150
|
+
|
|
151
|
+
1. **Custom Error Handler** (`onError`) - Maximum flexibility
|
|
152
|
+
2. **Endpoint** (`fetch`) - Automatic posting
|
|
153
|
+
3. **Console** - Default fallback
|
|
154
|
+
|
|
155
|
+
### Basic Configuration (Console Only)
|
|
156
|
+
|
|
83
157
|
```javascript
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
agent: { endpoint: 'https://api.com/errors' }
|
|
158
|
+
syntropyFront.configure({
|
|
159
|
+
maxEvents: 50 // Number of events to keep in memory
|
|
87
160
|
});
|
|
88
161
|
```
|
|
89
|
-
- **Use case**: Development and debugging
|
|
90
|
-
- **Features**: Frequent sending, full context, complete tracking
|
|
91
|
-
- **Bundle size**: ~60KB
|
|
92
162
|
|
|
93
|
-
###
|
|
163
|
+
### With Endpoint (Automatic Fetch)
|
|
164
|
+
|
|
94
165
|
```javascript
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
166
|
+
syntropyFront.configure({
|
|
167
|
+
maxEvents: 50,
|
|
168
|
+
fetch: {
|
|
169
|
+
url: 'https://your-api.com/errors',
|
|
170
|
+
options: {
|
|
171
|
+
headers: {
|
|
172
|
+
'Authorization': 'Bearer your-token',
|
|
173
|
+
'X-API-Key': 'your-api-key',
|
|
174
|
+
'Content-Type': 'application/json'
|
|
175
|
+
},
|
|
176
|
+
mode: 'cors',
|
|
177
|
+
credentials: 'include'
|
|
178
|
+
}
|
|
179
|
+
}
|
|
98
180
|
});
|
|
99
181
|
```
|
|
100
|
-
- **Use case**: High-performance applications
|
|
101
|
-
- **Features**: Critical errors only, minimal overhead
|
|
102
|
-
- **Bundle size**: ~25KB
|
|
103
|
-
|
|
104
|
-
## ๐ Reactive Object Tracking
|
|
105
182
|
|
|
106
|
-
|
|
183
|
+
### With Custom Error Handler (Maximum Flexibility)
|
|
107
184
|
|
|
108
185
|
```javascript
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
186
|
+
syntropyFront.configure({
|
|
187
|
+
maxEvents: 50,
|
|
188
|
+
onError: (errorPayload) => {
|
|
189
|
+
// You have complete control over what to do with the error
|
|
190
|
+
|
|
191
|
+
// Send to your API
|
|
192
|
+
fetch('https://your-api.com/errors', {
|
|
193
|
+
method: 'POST',
|
|
194
|
+
body: JSON.stringify(errorPayload)
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// Save to localStorage
|
|
198
|
+
localStorage.setItem('lastError', JSON.stringify(errorPayload));
|
|
199
|
+
|
|
200
|
+
// Send to multiple services
|
|
201
|
+
Promise.all([
|
|
202
|
+
fetch('https://service1.com/errors', { method: 'POST', body: JSON.stringify(errorPayload) }),
|
|
203
|
+
fetch('https://service2.com/errors', { method: 'POST', body: JSON.stringify(errorPayload) })
|
|
204
|
+
]);
|
|
205
|
+
|
|
206
|
+
// Upload to cloud storage
|
|
207
|
+
// Send to repository
|
|
208
|
+
// Log to file
|
|
209
|
+
// Whatever you want!
|
|
210
|
+
}
|
|
113
211
|
});
|
|
114
|
-
|
|
115
|
-
// Changes are automatically tracked
|
|
116
|
-
userProfile.name = 'Jane Doe';
|
|
117
|
-
userProfile.preferences.theme = 'light';
|
|
118
|
-
|
|
119
|
-
// Get tracking history
|
|
120
|
-
const history = SyntropyFront.getProxyObjectHistory('userProfile');
|
|
121
|
-
const currentState = SyntropyFront.getProxyObjectState('userProfile');
|
|
122
212
|
```
|
|
123
213
|
|
|
124
|
-
##
|
|
214
|
+
## ๐ง API Reference
|
|
125
215
|
|
|
126
|
-
|
|
216
|
+
### Core Methods
|
|
127
217
|
|
|
128
218
|
```javascript
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
useWorker: true,
|
|
132
|
-
// ... other config
|
|
133
|
-
});
|
|
219
|
+
// Add custom breadcrumb
|
|
220
|
+
syntropyFront.addBreadcrumb('user', 'Custom action', { data: 'value' });
|
|
134
221
|
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
const status = SyntropyFront.getWorkerStatus();
|
|
138
|
-
```
|
|
222
|
+
// Send manual error
|
|
223
|
+
syntropyFront.sendError(new Error('Custom error'));
|
|
139
224
|
|
|
140
|
-
|
|
225
|
+
// Get current breadcrumbs
|
|
226
|
+
const breadcrumbs = syntropyFront.getBreadcrumbs();
|
|
141
227
|
|
|
142
|
-
|
|
228
|
+
// Clear breadcrumbs
|
|
229
|
+
syntropyFront.clearBreadcrumbs();
|
|
143
230
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
obj.self = obj;
|
|
148
|
-
|
|
149
|
-
// SyntropyFront handles this automatically
|
|
150
|
-
SyntropyFront.sendError(new Error('Test'), { context: obj });
|
|
231
|
+
// Get statistics
|
|
232
|
+
const stats = syntropyFront.getStats();
|
|
233
|
+
// Returns: { breadcrumbs: 5, errors: 2, isActive: true, maxEvents: 50, endpoint: 'console' }
|
|
151
234
|
```
|
|
152
235
|
|
|
153
|
-
##
|
|
236
|
+
## ๐ฏ Extending SyntropyFront
|
|
237
|
+
|
|
238
|
+
SyntropyFront captures the essentials by default, but you can extend it to capture any DOM events you want:
|
|
154
239
|
|
|
155
|
-
|
|
240
|
+
### Adding Custom Event Capture
|
|
156
241
|
|
|
157
242
|
```javascript
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
243
|
+
import syntropyFront from 'syntropyfront';
|
|
244
|
+
|
|
245
|
+
// Add scroll tracking
|
|
246
|
+
window.addEventListener('scroll', () => {
|
|
247
|
+
syntropyFront.addBreadcrumb('user', 'scroll', {
|
|
248
|
+
scrollY: window.scrollY,
|
|
249
|
+
scrollX: window.scrollX
|
|
250
|
+
});
|
|
162
251
|
});
|
|
163
252
|
|
|
164
|
-
//
|
|
165
|
-
|
|
166
|
-
|
|
253
|
+
// Add form submissions
|
|
254
|
+
document.addEventListener('submit', (event) => {
|
|
255
|
+
syntropyFront.addBreadcrumb('user', 'form_submit', {
|
|
256
|
+
formId: event.target.id,
|
|
257
|
+
formAction: event.target.action
|
|
258
|
+
});
|
|
259
|
+
});
|
|
167
260
|
|
|
168
|
-
|
|
261
|
+
// Add window resize
|
|
262
|
+
window.addEventListener('resize', () => {
|
|
263
|
+
syntropyFront.addBreadcrumb('system', 'window_resize', {
|
|
264
|
+
width: window.innerWidth,
|
|
265
|
+
height: window.innerHeight
|
|
266
|
+
});
|
|
267
|
+
});
|
|
169
268
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
agent: { endpoint: 'https://api.com/errors' }
|
|
269
|
+
// Add custom business events
|
|
270
|
+
function trackPurchase(productId, amount) {
|
|
271
|
+
syntropyFront.addBreadcrumb('business', 'purchase', {
|
|
272
|
+
productId,
|
|
273
|
+
amount,
|
|
274
|
+
timestamp: new Date().toISOString()
|
|
177
275
|
});
|
|
178
|
-
}
|
|
276
|
+
}
|
|
179
277
|
```
|
|
180
278
|
|
|
181
|
-
###
|
|
182
|
-
```javascript
|
|
183
|
-
// In your main.js
|
|
184
|
-
import { createApp } from 'vue';
|
|
185
|
-
import App from './App.vue';
|
|
279
|
+
### Common Events You Can Track
|
|
186
280
|
|
|
187
|
-
|
|
281
|
+
- **User interactions**: `click`, `scroll`, `keydown`, `focus`, `blur`
|
|
282
|
+
- **Form events**: `submit`, `input`, `change`, `reset`
|
|
283
|
+
- **System events**: `resize`, `online`, `offline`, `visibilitychange`
|
|
284
|
+
- **Custom events**: Any business logic or user actions
|
|
285
|
+
- **Performance**: `load`, `DOMContentLoaded`, timing events
|
|
188
286
|
|
|
189
|
-
|
|
190
|
-
SyntropyFront.init({
|
|
191
|
-
preset: 'balanced',
|
|
192
|
-
agent: { endpoint: 'https://api.com/errors' }
|
|
193
|
-
});
|
|
287
|
+
## ๐ CORS Configuration
|
|
194
288
|
|
|
195
|
-
|
|
289
|
+
To use with your API, ensure your server allows CORS:
|
|
290
|
+
|
|
291
|
+
```javascript
|
|
292
|
+
// Express.js example
|
|
293
|
+
app.use(cors({
|
|
294
|
+
origin: 'http://localhost:3000',
|
|
295
|
+
credentials: true
|
|
296
|
+
}));
|
|
297
|
+
|
|
298
|
+
// Or in headers
|
|
299
|
+
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
|
|
300
|
+
res.setHeader('Access-Control-Allow-Methods', 'POST');
|
|
301
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
196
302
|
```
|
|
197
303
|
|
|
198
|
-
|
|
199
|
-
```typescript
|
|
200
|
-
// In your main.ts
|
|
201
|
-
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
|
202
|
-
import { AppModule } from './app/app.module';
|
|
304
|
+
## ๐ฑ Framework Support
|
|
203
305
|
|
|
204
|
-
|
|
205
|
-
SyntropyFront.init({
|
|
206
|
-
preset: 'balanced',
|
|
207
|
-
agent: { endpoint: 'https://api.com/errors' }
|
|
208
|
-
});
|
|
306
|
+
SyntropyFront works with any JavaScript framework:
|
|
209
307
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
308
|
+
- โ
**React** - Works out of the box
|
|
309
|
+
- โ
**Vue** - Works out of the box
|
|
310
|
+
- โ
**Angular** - Works out of the box
|
|
311
|
+
- โ
**Svelte** - Works out of the box
|
|
312
|
+
- โ
**Vanilla JS** - Works out of the box
|
|
214
313
|
|
|
215
|
-
|
|
314
|
+
## ๐ฏ Examples
|
|
216
315
|
|
|
217
|
-
|
|
218
|
-
Initialize SyntropyFront with configuration.
|
|
316
|
+
### React Example
|
|
219
317
|
|
|
220
|
-
|
|
221
|
-
|
|
318
|
+
```jsx
|
|
319
|
+
import React from 'react';
|
|
320
|
+
import syntropyFront from 'syntropyfront';
|
|
222
321
|
|
|
223
|
-
|
|
224
|
-
|
|
322
|
+
function App() {
|
|
323
|
+
// SyntropyFront auto-initializes on import
|
|
324
|
+
return (
|
|
325
|
+
<div>
|
|
326
|
+
<button onClick={() => console.log('Button clicked')}>
|
|
327
|
+
Click me!
|
|
328
|
+
</button>
|
|
329
|
+
</div>
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
```
|
|
225
333
|
|
|
226
|
-
|
|
227
|
-
Add a breadcrumb entry.
|
|
334
|
+
### Vue Example
|
|
228
335
|
|
|
229
|
-
|
|
230
|
-
|
|
336
|
+
```vue
|
|
337
|
+
<template>
|
|
338
|
+
<button @click="handleClick">Click me!</button>
|
|
339
|
+
</template>
|
|
231
340
|
|
|
232
|
-
|
|
341
|
+
<script>
|
|
342
|
+
import syntropyFront from 'syntropyfront';
|
|
233
343
|
|
|
234
|
-
|
|
235
|
-
{
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
batchTimeout: 10000,
|
|
240
|
-
batchSize: 20,
|
|
241
|
-
maxRetries: 3,
|
|
242
|
-
usePersistentBuffer: true
|
|
243
|
-
},
|
|
244
|
-
proxyTracking: {
|
|
245
|
-
enabled: true,
|
|
246
|
-
maxStates: 10,
|
|
247
|
-
trackNested: true,
|
|
248
|
-
trackArrays: true
|
|
249
|
-
},
|
|
250
|
-
useWorker: true,
|
|
251
|
-
maxBreadcrumbs: 50,
|
|
252
|
-
context: {
|
|
253
|
-
device: true,
|
|
254
|
-
window: true,
|
|
255
|
-
session: true,
|
|
256
|
-
ui: true,
|
|
257
|
-
network: true
|
|
344
|
+
export default {
|
|
345
|
+
methods: {
|
|
346
|
+
handleClick() {
|
|
347
|
+
console.log('Button clicked');
|
|
348
|
+
}
|
|
258
349
|
}
|
|
259
350
|
}
|
|
351
|
+
</script>
|
|
260
352
|
```
|
|
261
353
|
|
|
262
|
-
|
|
354
|
+
### Manual Error Reporting
|
|
263
355
|
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
npm test
|
|
356
|
+
```javascript
|
|
357
|
+
import syntropyFront from 'syntropyfront';
|
|
267
358
|
|
|
268
|
-
|
|
269
|
-
|
|
359
|
+
try {
|
|
360
|
+
// Your code here
|
|
361
|
+
} catch (error) {
|
|
362
|
+
// SyntropyFront will automatically capture this
|
|
363
|
+
throw error;
|
|
364
|
+
}
|
|
270
365
|
|
|
271
|
-
|
|
272
|
-
|
|
366
|
+
// Or manually report
|
|
367
|
+
syntropyFront.sendError(new Error('Something went wrong'));
|
|
273
368
|
```
|
|
274
369
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
```bash
|
|
278
|
-
# Install dependencies
|
|
279
|
-
npm install
|
|
370
|
+
### Extending with Custom Events
|
|
280
371
|
|
|
281
|
-
|
|
282
|
-
|
|
372
|
+
```javascript
|
|
373
|
+
import syntropyFront from 'syntropyfront';
|
|
283
374
|
|
|
284
|
-
|
|
285
|
-
|
|
375
|
+
// Add your custom event listeners
|
|
376
|
+
window.addEventListener('scroll', () => {
|
|
377
|
+
syntropyFront.addBreadcrumb('user', 'scroll', {
|
|
378
|
+
scrollY: window.scrollY,
|
|
379
|
+
scrollX: window.scrollX
|
|
380
|
+
});
|
|
381
|
+
});
|
|
286
382
|
|
|
287
|
-
|
|
288
|
-
|
|
383
|
+
// Track business events
|
|
384
|
+
function userCompletedCheckout(orderId, total) {
|
|
385
|
+
syntropyFront.addBreadcrumb('business', 'checkout_completed', {
|
|
386
|
+
orderId,
|
|
387
|
+
total,
|
|
388
|
+
timestamp: new Date().toISOString()
|
|
389
|
+
});
|
|
390
|
+
}
|
|
289
391
|
|
|
290
|
-
|
|
291
|
-
|
|
392
|
+
// Track performance
|
|
393
|
+
window.addEventListener('load', () => {
|
|
394
|
+
syntropyFront.addBreadcrumb('performance', 'page_loaded', {
|
|
395
|
+
loadTime: performance.now()
|
|
396
|
+
});
|
|
397
|
+
});
|
|
292
398
|
```
|
|
293
399
|
|
|
294
|
-
##
|
|
295
|
-
|
|
296
|
-
The build process generates multiple formats:
|
|
400
|
+
## ๐ Debugging
|
|
297
401
|
|
|
298
|
-
|
|
299
|
-
- **CommonJS** (`dist/index.cjs`) - Node.js compatibility
|
|
300
|
-
- **IIFE** (`dist/index.min.js`) - Browser-ready minified bundle
|
|
402
|
+
SyntropyFront logs helpful information to the console:
|
|
301
403
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
4. Add tests
|
|
308
|
-
5. Submit a pull request
|
|
404
|
+
```
|
|
405
|
+
๐ SyntropyFront: Initialized with automatic capture
|
|
406
|
+
โ
SyntropyFront: Configured - maxEvents: 50, endpoint: https://your-api.com/errors
|
|
407
|
+
โ Error: { type: "uncaught_exception", error: {...}, breadcrumbs: [...] }
|
|
408
|
+
```
|
|
309
409
|
|
|
310
410
|
## ๐ License
|
|
311
411
|
|
|
312
|
-
Apache 2.0
|
|
412
|
+
Apache 2.0
|
|
313
413
|
|
|
314
|
-
##
|
|
414
|
+
## ๐ค Contributing
|
|
315
415
|
|
|
316
|
-
|
|
317
|
-
- ๐ [Issues](https://github.com/Syntropysoft/syntropyfront/issues)
|
|
318
|
-
- ๐ฌ [Discussions](https://github.com/Syntropysoft/syntropyfront/discussions)
|
|
416
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
319
417
|
|
|
320
418
|
---
|
|
321
419
|
|
|
322
|
-
Made with โค๏ธ
|
|
420
|
+
**Made with โค๏ธ for better web observability**
|