@tracelog/lib 0.12.0 → 0.12.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 +172 -146
- package/dist/browser/tracelog.esm.js +433 -423
- package/dist/browser/tracelog.esm.js.map +1 -1
- package/dist/browser/tracelog.js +2 -2
- package/dist/browser/tracelog.js.map +1 -1
- package/dist/public-api.cjs +117 -77
- package/dist/public-api.cjs.map +1 -1
- package/dist/public-api.d.mts +8 -35
- package/dist/public-api.d.ts +8 -35
- package/dist/public-api.js +117 -73
- package/dist/public-api.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,6 +11,12 @@ Lightweight web analytics library for tracking user behavior. Works standalone o
|
|
|
11
11
|
- **Event-driven** - Subscribe via `on()`/`off()` for real-time events
|
|
12
12
|
- **Lightweight** - Single dependency (`web-vitals`), 15KB gzipped
|
|
13
13
|
|
|
14
|
+
## Live Demo
|
|
15
|
+
|
|
16
|
+
[https://nacorga.github.io/tracelog-lib](https://nacorga.github.io/tracelog-lib)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
14
20
|
## Installation
|
|
15
21
|
|
|
16
22
|
### NPM (Recommended)
|
|
@@ -51,236 +57,256 @@ await tracelog.init({
|
|
|
51
57
|
## Quick Start
|
|
52
58
|
|
|
53
59
|
```typescript
|
|
54
|
-
//
|
|
60
|
+
// 1. Initialize (standalone mode - no backend required)
|
|
55
61
|
await tracelog.init();
|
|
56
62
|
|
|
57
|
-
//
|
|
58
|
-
tracelog.event('
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
// 2. Track custom events
|
|
64
|
+
tracelog.event('button_clicked', {
|
|
65
|
+
buttonId: 'signup-cta',
|
|
66
|
+
source: 'homepage'
|
|
61
67
|
});
|
|
62
68
|
|
|
63
|
-
// Subscribe to events
|
|
69
|
+
// 3. Subscribe to events (real-time)
|
|
64
70
|
tracelog.on('event', (event) => {
|
|
65
71
|
console.log(event.type, event);
|
|
66
72
|
});
|
|
67
73
|
|
|
68
|
-
// Cleanup
|
|
69
|
-
|
|
74
|
+
// 4. Cleanup (on consent revoke or app unmount)
|
|
75
|
+
tracelog.destroy();
|
|
70
76
|
```
|
|
71
77
|
|
|
78
|
+
**That's it!** TraceLog now automatically tracks:
|
|
79
|
+
- Page views & navigation (including SPA routes)
|
|
80
|
+
- Click interactions
|
|
81
|
+
- Scroll behavior
|
|
82
|
+
- User sessions
|
|
83
|
+
- Web Vitals (LCP, INP, CLS, FCP, TTFB)
|
|
84
|
+
- JavaScript errors
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Core API
|
|
89
|
+
|
|
90
|
+
| Method | Description |
|
|
91
|
+
|--------|-------------|
|
|
92
|
+
| `init(config?)` | Initialize tracking (see [Configuration](#configuration)) |
|
|
93
|
+
| `event(name, metadata?)` | Track custom events |
|
|
94
|
+
| `on(event, callback)` | Subscribe to events (`'event'` or `'queue'`) |
|
|
95
|
+
| `off(event, callback)` | Unsubscribe from events |
|
|
96
|
+
| `isInitialized()` | Check initialization status |
|
|
97
|
+
| `setQaMode(enabled)` | Enable/disable QA mode (console logging) |
|
|
98
|
+
| `destroy()` | Stop tracking and cleanup |
|
|
99
|
+
|
|
100
|
+
**→ [Complete API Reference](./API_REFERENCE.md)**
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
72
104
|
## Configuration
|
|
73
105
|
|
|
106
|
+
All configuration is **optional**. TraceLog works out-of-the-box with sensible defaults.
|
|
107
|
+
|
|
74
108
|
```typescript
|
|
75
109
|
await tracelog.init({
|
|
76
110
|
// Session
|
|
77
|
-
sessionTimeout: 900000,
|
|
78
|
-
|
|
79
|
-
// Sampling
|
|
80
|
-
samplingRate: 1.0, // 100% (default)
|
|
81
|
-
errorSampling: 1.0, // 100% (default)
|
|
111
|
+
sessionTimeout: 900000, // 15 min (default)
|
|
82
112
|
|
|
83
113
|
// Privacy
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// Web Vitals filtering (controls which performance metrics are tracked)
|
|
87
|
-
webVitalsMode: 'needs-improvement', // 'all' | 'needs-improvement' | 'poor' (default: 'needs-improvement')
|
|
88
|
-
webVitalsThresholds: { // Optional: override default thresholds
|
|
89
|
-
LCP: 3000, // Custom threshold in milliseconds
|
|
90
|
-
FCP: 2000
|
|
91
|
-
},
|
|
114
|
+
samplingRate: 1.0, // 100% (default)
|
|
115
|
+
sensitiveQueryParams: ['token'], // Add to defaults
|
|
92
116
|
|
|
93
|
-
// Integrations
|
|
117
|
+
// Integrations (pick one or none)
|
|
94
118
|
integrations: {
|
|
95
|
-
tracelog: { projectId: 'your-id' },
|
|
96
|
-
custom: { collectApiUrl: 'https://api.
|
|
97
|
-
googleAnalytics: { measurementId: 'G-XXXXXX' }
|
|
119
|
+
tracelog: { projectId: 'your-id' }, // TraceLog SaaS
|
|
120
|
+
custom: { collectApiUrl: 'https://api.com' }, // Custom backend
|
|
121
|
+
googleAnalytics: { measurementId: 'G-XXXXXX' } // GA4 forwarding
|
|
98
122
|
},
|
|
99
123
|
|
|
100
|
-
//
|
|
124
|
+
// Web Vitals filtering
|
|
125
|
+
webVitalsMode: 'needs-improvement', // 'all' | 'needs-improvement' | 'poor'
|
|
126
|
+
|
|
127
|
+
// Viewport tracking (element visibility)
|
|
101
128
|
viewport: {
|
|
102
|
-
elements: [
|
|
103
|
-
{ selector: '.cta-button', id: 'pricing-cta', name: 'Pricing CTA' }
|
|
104
|
-
],
|
|
129
|
+
elements: [{ selector: '.cta', id: 'hero-cta' }],
|
|
105
130
|
threshold: 0.5, // 50% visible
|
|
106
131
|
minDwellTime: 1000 // 1 second
|
|
107
132
|
}
|
|
108
133
|
});
|
|
109
134
|
```
|
|
110
135
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
- `init(config?)` - Initialize tracking
|
|
114
|
-
- `event(name, metadata?)` - Send custom event
|
|
115
|
-
- `on(event, callback)` - Subscribe to events
|
|
116
|
-
- `off(event, callback)` - Unsubscribe
|
|
117
|
-
- `destroy()` - Cleanup
|
|
136
|
+
**→ [Full Configuration Guide](./API_REFERENCE.md#configuration)**
|
|
118
137
|
|
|
119
|
-
|
|
138
|
+
---
|
|
120
139
|
|
|
121
|
-
|
|
140
|
+
## Automatic Event Types
|
|
122
141
|
|
|
123
|
-
|
|
124
|
-
|------|-------------|
|
|
125
|
-
| `PAGE_VIEW` | `page_view.{title, pathname, referrer}` |
|
|
126
|
-
| `CLICK` | `click_data.{x, y, tag, id, text, href}` |
|
|
127
|
-
| `SCROLL` | `scroll_data.{depth, direction, velocity, is_primary}` |
|
|
128
|
-
| `SESSION_START` | Session initialization |
|
|
129
|
-
| `SESSION_END` | `session_end_reason` |
|
|
130
|
-
| `CUSTOM` | `custom_event.{name, metadata}` |
|
|
131
|
-
| `WEB_VITALS` | `web_vitals.{type, value}` (LCP, CLS, INP, FCP, TTFB) |
|
|
132
|
-
| `ERROR` | `error_data.{type, message, filename, line}` |
|
|
133
|
-
| `VIEWPORT_VISIBLE` | `viewport_data.{selector, dwellTime, visibilityRatio}` |
|
|
142
|
+
TraceLog captures these events automatically (no code required):
|
|
134
143
|
|
|
135
|
-
|
|
144
|
+
| Event Type | What It Tracks |
|
|
145
|
+
|------------|----------------|
|
|
146
|
+
| `PAGE_VIEW` | Navigation, SPA route changes |
|
|
147
|
+
| `CLICK` | User interactions with elements |
|
|
148
|
+
| `SCROLL` | Scroll depth, velocity, engagement |
|
|
149
|
+
| `SESSION_START` | New session creation |
|
|
150
|
+
| `SESSION_END` | Session termination (timeout, page unload) |
|
|
151
|
+
| `WEB_VITALS` | Core Web Vitals (LCP, INP, CLS, FCP, TTFB) |
|
|
152
|
+
| `ERROR` | JavaScript errors, promise rejections |
|
|
153
|
+
| `VIEWPORT_VISIBLE` | Element visibility (requires `viewport` config) |
|
|
136
154
|
|
|
137
|
-
|
|
155
|
+
**Custom Events:**
|
|
138
156
|
```typescript
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
157
|
+
tracelog.event('purchase_completed', {
|
|
158
|
+
orderId: 'ord-123',
|
|
159
|
+
total: 99.99,
|
|
160
|
+
currency: 'USD'
|
|
142
161
|
});
|
|
162
|
+
```
|
|
143
163
|
|
|
144
|
-
|
|
145
|
-
console.log('Queued:', batch.events.length);
|
|
146
|
-
});
|
|
164
|
+
**→ [Event Types Reference](./API_REFERENCE.md#event-types)**
|
|
147
165
|
|
|
148
|
-
|
|
149
|
-
```
|
|
166
|
+
---
|
|
150
167
|
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
// Exclude sensitive elements
|
|
154
|
-
<div data-tlog-ignore>
|
|
155
|
-
<input type="password">
|
|
156
|
-
</div>
|
|
168
|
+
## Integration Modes
|
|
157
169
|
|
|
158
|
-
|
|
159
|
-
await tracelog.init({
|
|
160
|
-
sensitiveQueryParams: ['affiliate_id', 'promo'],
|
|
161
|
-
samplingRate: 0.5 // Track 50% of users
|
|
162
|
-
});
|
|
163
|
-
```
|
|
170
|
+
TraceLog supports multiple integration modes. Choose what fits your needs:
|
|
164
171
|
|
|
165
|
-
###
|
|
172
|
+
### 1. Standalone (No Backend)
|
|
166
173
|
```typescript
|
|
174
|
+
await tracelog.init();
|
|
175
|
+
|
|
176
|
+
// Consume events locally
|
|
167
177
|
tracelog.on('event', (event) => {
|
|
168
|
-
|
|
169
|
-
console.log('Main content scroll:', event.scroll_data.depth);
|
|
170
|
-
}
|
|
178
|
+
myAnalytics.track(event);
|
|
171
179
|
});
|
|
172
180
|
```
|
|
173
181
|
|
|
174
|
-
###
|
|
182
|
+
### 2. TraceLog SaaS
|
|
175
183
|
```typescript
|
|
176
|
-
// Default: Track metrics needing improvement or worse (balanced approach)
|
|
177
|
-
await tracelog.init({
|
|
178
|
-
webVitalsMode: 'needs-improvement'
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// Track all metrics (for full trend analysis and P75 calculations)
|
|
182
184
|
await tracelog.init({
|
|
183
|
-
|
|
185
|
+
integrations: {
|
|
186
|
+
tracelog: { projectId: 'your-project-id' }
|
|
187
|
+
}
|
|
184
188
|
});
|
|
189
|
+
```
|
|
185
190
|
|
|
186
|
-
|
|
191
|
+
### 3. Custom Backend
|
|
192
|
+
```typescript
|
|
187
193
|
await tracelog.init({
|
|
188
|
-
|
|
194
|
+
integrations: {
|
|
195
|
+
custom: {
|
|
196
|
+
collectApiUrl: 'https://api.example.com/collect',
|
|
197
|
+
allowHttp: false // Only true for local testing
|
|
198
|
+
}
|
|
199
|
+
}
|
|
189
200
|
});
|
|
201
|
+
```
|
|
190
202
|
|
|
191
|
-
|
|
203
|
+
### 4. Google Analytics
|
|
204
|
+
```typescript
|
|
192
205
|
await tracelog.init({
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
LCP: 3000, // Stricter than default 2500ms
|
|
196
|
-
FCP: 2500, // Stricter than default 1800ms
|
|
197
|
-
CLS: 0.15 // Stricter than default 0.1
|
|
206
|
+
integrations: {
|
|
207
|
+
googleAnalytics: { measurementId: 'G-XXXXXX' }
|
|
198
208
|
}
|
|
199
209
|
});
|
|
200
210
|
```
|
|
201
211
|
|
|
202
|
-
|
|
212
|
+
**→ [Integration Setup Guide](./API_REFERENCE.md#integration-configuration)**
|
|
203
213
|
|
|
204
|
-
|
|
205
|
-
|--------|-------|-------------------------------|--------|
|
|
206
|
-
| LCP | Track all | > 2500ms | > 4000ms |
|
|
207
|
-
| FCP | Track all | > 1800ms | > 3000ms |
|
|
208
|
-
| CLS | Track all | > 0.1 | > 0.25 |
|
|
209
|
-
| INP | Track all | > 200ms | > 500ms |
|
|
210
|
-
| TTFB | Track all | > 800ms | > 1800ms |
|
|
211
|
-
|
|
212
|
-
### Global Disable
|
|
213
|
-
```typescript
|
|
214
|
-
window.__traceLogDisabled = true;
|
|
215
|
-
```
|
|
214
|
+
---
|
|
216
215
|
|
|
217
216
|
## Privacy & Security
|
|
218
217
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
- **
|
|
222
|
-
- **
|
|
223
|
-
- **
|
|
218
|
+
TraceLog is **privacy-first** by design:
|
|
219
|
+
|
|
220
|
+
- ✅ **PII Sanitization** - Auto-redacts emails, phones, credit cards, API keys
|
|
221
|
+
- ✅ **Input Protection** - Never captures `<input>`, `<textarea>`, `<select>` values
|
|
222
|
+
- ✅ **URL Filtering** - Removes sensitive query params (15 defaults + custom)
|
|
223
|
+
- ✅ **Element Exclusion** - Use `data-tlog-ignore` to exclude sensitive areas
|
|
224
|
+
- ✅ **Client-Side Controls** - All sampling and validation happens in browser
|
|
225
|
+
|
|
226
|
+
**Example:**
|
|
227
|
+
```html
|
|
228
|
+
<!-- Exclude sensitive forms -->
|
|
229
|
+
<div data-tlog-ignore>
|
|
230
|
+
<input type="password" name="password">
|
|
231
|
+
<input type="text" name="credit_card">
|
|
232
|
+
</div>
|
|
233
|
+
```
|
|
224
234
|
|
|
225
235
|
**Your Responsibilities:**
|
|
226
|
-
- Get user consent before calling `init()` (GDPR)
|
|
227
|
-
- Sanitize custom event metadata
|
|
236
|
+
- Get user consent before calling `init()` (GDPR/CCPA)
|
|
237
|
+
- Sanitize custom event metadata (avoid PII)
|
|
228
238
|
- Call `destroy()` on consent revoke
|
|
229
239
|
|
|
230
|
-
[
|
|
240
|
+
**→ [Complete Security Guide](./SECURITY.md)**
|
|
231
241
|
|
|
232
|
-
|
|
242
|
+
---
|
|
233
243
|
|
|
234
|
-
|
|
244
|
+
## QA Mode
|
|
235
245
|
|
|
236
|
-
|
|
237
|
-
- **Permanent errors (4xx)** - Events discarded immediately (invalid data won't succeed on retry)
|
|
238
|
-
- **Temporary errors (5xx/network)** - Events removed from queue and persisted to localStorage
|
|
239
|
-
- **Recovery** - Persisted events automatically recovered and retried on next page load
|
|
240
|
-
- **Expiration** - Persisted events expire after 2 hours
|
|
241
|
-
- **Page unload** - Uses `sendBeacon()` for synchronous delivery of session end events
|
|
246
|
+
Enable QA mode for debugging and development:
|
|
242
247
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
- Natural recovery on page navigation (common in SPAs)
|
|
248
|
-
|
|
249
|
-
## Debug
|
|
248
|
+
### URL Activation
|
|
249
|
+
```bash
|
|
250
|
+
# Enable
|
|
251
|
+
?tlog_mode=qa
|
|
250
252
|
|
|
251
|
-
|
|
253
|
+
# Disable
|
|
254
|
+
?tlog_mode=qa_off
|
|
255
|
+
```
|
|
252
256
|
|
|
257
|
+
### Programmatic API
|
|
253
258
|
```typescript
|
|
254
|
-
|
|
259
|
+
tracelog.setQaMode(true); // Enable
|
|
260
|
+
tracelog.setQaMode(false); // Disable
|
|
255
261
|
```
|
|
256
262
|
|
|
257
|
-
|
|
263
|
+
**Features:**
|
|
264
|
+
- Custom events logged to browser console
|
|
265
|
+
- Strict validation (throws errors instead of warnings)
|
|
266
|
+
- Session state visible in console
|
|
267
|
+
- Persistent across page reloads (sessionStorage)
|
|
258
268
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
npm run check # Lint + format
|
|
263
|
-
npm run test # All tests
|
|
264
|
-
npm run test:coverage # With coverage
|
|
265
|
-
```
|
|
269
|
+
**→ [QA Mode Documentation](./API_REFERENCE.md#setqamodeenabled-boolean-void)**
|
|
270
|
+
|
|
271
|
+
---
|
|
266
272
|
|
|
267
273
|
## Browser Support
|
|
268
274
|
|
|
269
|
-
Chrome 60
|
|
275
|
+
- Chrome 60+
|
|
276
|
+
- Firefox 55+
|
|
277
|
+
- Safari 12+
|
|
278
|
+
- Edge 79+
|
|
279
|
+
|
|
280
|
+
**SSR/SSG Compatible:** Safe to import in Angular Universal, Next.js, Nuxt, SvelteKit (no-ops in Node.js).
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Development
|
|
270
285
|
|
|
271
|
-
|
|
286
|
+
```bash
|
|
287
|
+
npm install # Install dependencies
|
|
288
|
+
npm run build:all # Build ESM + CJS + Browser bundles
|
|
289
|
+
npm run check # Lint + format validation
|
|
290
|
+
npm run test # Run all tests
|
|
291
|
+
npm run test:coverage # Generate coverage report
|
|
292
|
+
```
|
|
272
293
|
|
|
273
|
-
|
|
294
|
+
**→ [Contributing Guide](./CONTRIBUTING.md)**
|
|
274
295
|
|
|
275
|
-
|
|
276
|
-
Register listeners AFTER init() in browser-only lifecycle hooks.
|
|
296
|
+
---
|
|
277
297
|
|
|
278
298
|
## Documentation
|
|
279
299
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
300
|
+
| Document | Description |
|
|
301
|
+
|----------|-------------|
|
|
302
|
+
| **[API Reference](./API_REFERENCE.md)** | Complete API documentation with all methods, config options, and event types |
|
|
303
|
+
| **[Best Practices](./BEST_PRACTICES.md)** | Patterns, anti-patterns, and optimization tips |
|
|
304
|
+
| **[Security Guide](./SECURITY.md)** | Privacy, GDPR compliance, and security best practices |
|
|
305
|
+
| **[Changelog](./CHANGELOG.md)** | Release history and migration guides |
|
|
306
|
+
| **[Handlers](./src/handlers/README.md)** | Event capture implementation details |
|
|
307
|
+
| **[Managers](./src/managers/README.md)** | Core component architecture |
|
|
308
|
+
|
|
309
|
+
---
|
|
284
310
|
|
|
285
311
|
## License
|
|
286
312
|
|