@thisbefine/analytics 0.3.0 → 0.3.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 +161 -3
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -169,6 +169,38 @@ analytics.log('Cache miss for user preferences', 'debug', {
|
|
|
169
169
|
});
|
|
170
170
|
```
|
|
171
171
|
|
|
172
|
+
### Lifecycle Events
|
|
173
|
+
|
|
174
|
+
Track key SaaS milestones with built-in methods. These use reserved event names (prefixed with `$`) and typed properties for consistent analytics.
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// User lifecycle
|
|
178
|
+
analytics.signup({ method: 'google', plan: 'free' });
|
|
179
|
+
analytics.login({ method: 'passkey', isNewDevice: true });
|
|
180
|
+
analytics.logout({ reason: 'manual' });
|
|
181
|
+
analytics.accountDeleted({ reason: 'not_using', tenure: 45 });
|
|
182
|
+
|
|
183
|
+
// Subscription events
|
|
184
|
+
analytics.subscriptionStarted({ plan: 'pro', interval: 'monthly', mrr: 29 });
|
|
185
|
+
analytics.subscriptionCancelled({ plan: 'pro', reason: 'too_expensive', mrr: 29 });
|
|
186
|
+
analytics.subscriptionRenewed({ plan: 'pro', renewalCount: 12 });
|
|
187
|
+
|
|
188
|
+
// Plan changes
|
|
189
|
+
analytics.planUpgraded({ fromPlan: 'starter', toPlan: 'pro', mrrChange: 20 });
|
|
190
|
+
analytics.planDowngraded({ fromPlan: 'pro', toPlan: 'starter', reason: 'budget' });
|
|
191
|
+
|
|
192
|
+
// Trials
|
|
193
|
+
analytics.trialStarted({ plan: 'pro', trialDays: 14 });
|
|
194
|
+
analytics.trialEnded({ plan: 'pro', converted: true });
|
|
195
|
+
|
|
196
|
+
// Team/collaboration
|
|
197
|
+
analytics.inviteSent({ inviteEmail: 'teammate@company.com', role: 'editor' });
|
|
198
|
+
analytics.inviteAccepted({ invitedBy: 'user_123', role: 'editor' });
|
|
199
|
+
|
|
200
|
+
// Feature adoption
|
|
201
|
+
analytics.featureActivated({ feature: 'dark_mode', isFirstTime: true });
|
|
202
|
+
```
|
|
203
|
+
|
|
172
204
|
### Privacy Controls
|
|
173
205
|
|
|
174
206
|
Because being creepy is bad for business.
|
|
@@ -187,6 +219,36 @@ if (analytics.isOptedOut()) {
|
|
|
187
219
|
analytics.optIn();
|
|
188
220
|
```
|
|
189
221
|
|
|
222
|
+
### Consent Management
|
|
223
|
+
|
|
224
|
+
Granular control over tracking categories for GDPR/CCPA compliance.
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// Configure consent categories on init
|
|
228
|
+
const analytics = createAnalytics({
|
|
229
|
+
apiKey: 'tbf_xxx',
|
|
230
|
+
consent: {
|
|
231
|
+
categories: ['analytics', 'marketing', 'functional'],
|
|
232
|
+
defaultConsent: false, // Don't track until explicit consent
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Check if a category is enabled
|
|
237
|
+
if (analytics.hasConsent('marketing')) {
|
|
238
|
+
// Show personalized content
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Get all consented categories
|
|
242
|
+
const categories = analytics.getConsentedCategories();
|
|
243
|
+
|
|
244
|
+
// Set consent (replaces current consent)
|
|
245
|
+
analytics.setConsent(['analytics', 'functional']);
|
|
246
|
+
|
|
247
|
+
// Grant/revoke individual categories
|
|
248
|
+
analytics.grantConsent('marketing');
|
|
249
|
+
analytics.revokeConsent('marketing');
|
|
250
|
+
```
|
|
251
|
+
|
|
190
252
|
## React Hooks
|
|
191
253
|
|
|
192
254
|
All hooks are available from both `@thisbefine/analytics/react` and `@thisbefine/analytics/next`.
|
|
@@ -289,9 +351,10 @@ const analytics = createAnalytics({
|
|
|
289
351
|
// Required
|
|
290
352
|
apiKey: 'tbf_xxx',
|
|
291
353
|
|
|
292
|
-
// Optional
|
|
354
|
+
// Optional - Basic
|
|
293
355
|
host: 'https://thisbefine.com', // API endpoint
|
|
294
356
|
debug: false, // Console logging
|
|
357
|
+
structuredLogging: false, // Output debug logs as JSON
|
|
295
358
|
flushAt: 20, // Batch size before sending
|
|
296
359
|
flushInterval: 10000, // Ms between flushes
|
|
297
360
|
sessionTimeout: 1800000, // 30 min session timeout
|
|
@@ -299,12 +362,46 @@ const analytics = createAnalytics({
|
|
|
299
362
|
respectDNT: true, // Honor Do Not Track
|
|
300
363
|
maxRetries: 3, // Retry failed requests
|
|
301
364
|
|
|
302
|
-
// Error tracking
|
|
365
|
+
// Error tracking
|
|
303
366
|
errors: {
|
|
304
367
|
enabled: true,
|
|
305
368
|
captureUnhandled: true,
|
|
306
369
|
captureConsoleErrors: true,
|
|
307
370
|
},
|
|
371
|
+
|
|
372
|
+
// Lifecycle hooks
|
|
373
|
+
onFlushError: (error, failedEvents) => {
|
|
374
|
+
console.error('Failed to send events:', error);
|
|
375
|
+
// Log to your error tracking service
|
|
376
|
+
},
|
|
377
|
+
beforeSend: (event) => {
|
|
378
|
+
// Scrub PII from event properties
|
|
379
|
+
if (event.type === 'track' && event.properties?.email) {
|
|
380
|
+
const { email, ...rest } = event.properties;
|
|
381
|
+
return { ...event, properties: rest };
|
|
382
|
+
}
|
|
383
|
+
// Return null to discard the event
|
|
384
|
+
return event;
|
|
385
|
+
},
|
|
386
|
+
|
|
387
|
+
// Queue persistence (crash recovery)
|
|
388
|
+
persistQueue: true, // Save queue to localStorage
|
|
389
|
+
maxPersistedEvents: 1000, // Max events to persist
|
|
390
|
+
|
|
391
|
+
// Privacy & consent
|
|
392
|
+
anonymousIdMaxAge: 2592000000, // Rotate anonymous ID every 30 days
|
|
393
|
+
consent: {
|
|
394
|
+
categories: ['analytics', 'marketing', 'functional'],
|
|
395
|
+
defaultConsent: true, // Track by default (respects DNT)
|
|
396
|
+
},
|
|
397
|
+
|
|
398
|
+
// Rate limiting & sampling
|
|
399
|
+
maxEventsPerSecond: 100, // Drop events exceeding this rate
|
|
400
|
+
sampleRate: 1, // 1 = 100%, 0.5 = 50% of events
|
|
401
|
+
|
|
402
|
+
// Circuit breaker (stops hammering failed servers)
|
|
403
|
+
circuitBreakerThreshold: 5, // Open after N consecutive failures
|
|
404
|
+
circuitBreakerResetTimeout: 30000, // Try again after 30s
|
|
308
405
|
});
|
|
309
406
|
```
|
|
310
407
|
|
|
@@ -334,12 +431,44 @@ const analytics = createAnalytics({
|
|
|
334
431
|
| `page(name?, properties?)` | Track a page view |
|
|
335
432
|
| `group(accountId, traits?)` | Associate user with account |
|
|
336
433
|
| `reset()` | Clear user data (call on logout) |
|
|
337
|
-
| `flush()` | Force send queued events |
|
|
434
|
+
| `flush()` | Force send queued events (returns `FlushResult`) |
|
|
435
|
+
| `destroy()` | Clean up resources, flush remaining events |
|
|
338
436
|
| `optOut()` | Disable tracking |
|
|
339
437
|
| `optIn()` | Re-enable tracking |
|
|
340
438
|
| `isOptedOut()` | Check opt-out status |
|
|
341
439
|
| `getUser()` | Get current user state |
|
|
342
440
|
|
|
441
|
+
### Consent Methods
|
|
442
|
+
|
|
443
|
+
| Method | Description |
|
|
444
|
+
|--------|-------------|
|
|
445
|
+
| `hasConsent(category)` | Check if a category is enabled |
|
|
446
|
+
| `getConsentedCategories()` | Get all consented categories |
|
|
447
|
+
| `setConsent(categories)` | Set consent (replaces current) |
|
|
448
|
+
| `grantConsent(category)` | Enable a category |
|
|
449
|
+
| `revokeConsent(category)` | Disable a category |
|
|
450
|
+
|
|
451
|
+
Categories: `analytics` | `marketing` | `functional`
|
|
452
|
+
|
|
453
|
+
### Lifecycle Methods
|
|
454
|
+
|
|
455
|
+
| Method | Description |
|
|
456
|
+
|--------|-------------|
|
|
457
|
+
| `signup(props?)` | Track user signup |
|
|
458
|
+
| `login(props?)` | Track user login |
|
|
459
|
+
| `logout(props?)` | Track user logout |
|
|
460
|
+
| `accountDeleted(props?)` | Track account deletion |
|
|
461
|
+
| `subscriptionStarted(props)` | Track subscription start |
|
|
462
|
+
| `subscriptionCancelled(props)` | Track subscription cancellation |
|
|
463
|
+
| `subscriptionRenewed(props)` | Track subscription renewal |
|
|
464
|
+
| `planUpgraded(props)` | Track plan upgrade |
|
|
465
|
+
| `planDowngraded(props)` | Track plan downgrade |
|
|
466
|
+
| `trialStarted(props)` | Track trial start |
|
|
467
|
+
| `trialEnded(props)` | Track trial end |
|
|
468
|
+
| `inviteSent(props?)` | Track invite sent |
|
|
469
|
+
| `inviteAccepted(props?)` | Track invite accepted |
|
|
470
|
+
| `featureActivated(props)` | Track feature activation |
|
|
471
|
+
|
|
343
472
|
### Error Tracking Methods
|
|
344
473
|
|
|
345
474
|
| Method | Description |
|
|
@@ -376,11 +505,40 @@ Full type definitions included:
|
|
|
376
505
|
|
|
377
506
|
```typescript
|
|
378
507
|
import type {
|
|
508
|
+
// Core types
|
|
379
509
|
Analytics,
|
|
380
510
|
AnalyticsConfig,
|
|
381
511
|
UserState,
|
|
382
512
|
UserTraits,
|
|
383
513
|
AccountTraits,
|
|
514
|
+
FlushResult,
|
|
515
|
+
|
|
516
|
+
// Event types
|
|
517
|
+
AnalyticsEvent,
|
|
518
|
+
TrackEvent,
|
|
519
|
+
IdentifyEvent,
|
|
520
|
+
PageEvent,
|
|
521
|
+
GroupEvent,
|
|
522
|
+
|
|
523
|
+
// Hooks
|
|
524
|
+
BeforeSend,
|
|
525
|
+
OnFlushError,
|
|
526
|
+
|
|
527
|
+
// Lifecycle event props
|
|
528
|
+
SignupProps,
|
|
529
|
+
LoginProps,
|
|
530
|
+
LogoutProps,
|
|
531
|
+
AccountDeletedProps,
|
|
532
|
+
SubscriptionStartedProps,
|
|
533
|
+
SubscriptionCancelledProps,
|
|
534
|
+
SubscriptionRenewedProps,
|
|
535
|
+
PlanUpgradedProps,
|
|
536
|
+
PlanDowngradedProps,
|
|
537
|
+
TrialStartedProps,
|
|
538
|
+
TrialEndedProps,
|
|
539
|
+
InviteSentProps,
|
|
540
|
+
InviteAcceptedProps,
|
|
541
|
+
FeatureActivatedProps,
|
|
384
542
|
} from '@thisbefine/analytics';
|
|
385
543
|
```
|
|
386
544
|
|
package/dist/core/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.3.
|
|
1
|
+
export declare const VERSION = "0.3.2";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/core/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thisbefine/analytics",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Track events, catch errors, and pretend everything's fine. Lightweight analytics for indie SaaS.",
|
|
5
5
|
"author": "Thisbefine <hello@thisbefine.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"homepage": "https://thisbefine.com",
|
|
7
|
+
"homepage": "https://thisbefine.com/docs",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
10
|
"url": "git+https://github.com/thisbefine/analytics.git"
|