sitepong 0.0.4 → 0.0.6

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 CHANGED
@@ -1,6 +1,32 @@
1
- # SitePong SDK
2
-
3
- Official SDK for [SitePong](https://sitepong.com) error tracking and monitoring.
1
+ <p align="center">
2
+ <a href="https://sitepong.com">
3
+ <img src="https://sitepong.com/logo.svg" alt="SitePong" height="60">
4
+ </a>
5
+ </p>
6
+
7
+ <h1 align="center">SitePong SDK</h1>
8
+
9
+ <p align="center">
10
+ <strong>The complete observability platform for modern applications.</strong><br>
11
+ Error tracking, session replay, analytics, feature flags, and more — all in one SDK.
12
+ </p>
13
+
14
+ <p align="center">
15
+ <a href="https://www.npmjs.com/package/sitepong"><img src="https://img.shields.io/npm/v/sitepong.svg" alt="npm version"></a>
16
+ <a href="https://www.npmjs.com/package/sitepong"><img src="https://img.shields.io/npm/dm/sitepong.svg" alt="npm downloads"></a>
17
+ <a href="https://github.com/programmrz/sitepong/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/sitepong.svg" alt="license"></a>
18
+ <a href="https://sitepong.com/docs"><img src="https://img.shields.io/badge/docs-sitepong.com-blue.svg" alt="documentation"></a>
19
+ </p>
20
+
21
+ <p align="center">
22
+ <a href="#installation">Installation</a> •
23
+ <a href="#quick-start">Quick Start</a> •
24
+ <a href="#features">Features</a> •
25
+ <a href="#react-integration">React</a> •
26
+ <a href="#documentation">Docs</a>
27
+ </p>
28
+
29
+ ---
4
30
 
5
31
  ## Installation
6
32
 
@@ -24,30 +50,23 @@ sitepong.init({
24
50
  sitepong.captureError(new Error('Something went wrong'));
25
51
  ```
26
52
 
27
- ## Configuration
53
+ <p align="center">
54
+ <img src=".github/dashboard-preview.svg" alt="SitePong Dashboard" width="100%">
55
+ </p>
28
56
 
29
- ```javascript
30
- sitepong.init({
31
- apiKey: 'your-api-key', // Required
32
- endpoint: 'https://ingest.sitepong.com', // Optional
33
- environment: 'production', // Optional
34
- release: '1.0.0', // Optional
35
- autoCapture: true, // Auto-capture uncaught errors (default: true)
36
- maxBatchSize: 10, // Batch size before flush (default: 10)
37
- flushInterval: 5000, // Flush interval in ms (default: 5000)
38
- debug: false, // Enable debug logging (default: false)
39
- });
40
- ```
57
+ ---
41
58
 
42
- ## API
59
+ ## Features
43
60
 
44
- ### `init(config)`
45
- Initialize the SDK with your configuration.
61
+ ### Error Tracking
46
62
 
47
- ### `captureError(error, context?)`
48
- Manually capture an error.
63
+ Automatic error capture for uncaught exceptions and unhandled promise rejections. Works in both browser and Node.js environments.
49
64
 
50
65
  ```javascript
66
+ // Automatic capture - just initialize!
67
+ sitepong.init({ apiKey: 'your-api-key' });
68
+
69
+ // Manual capture with context
51
70
  try {
52
71
  riskyOperation();
53
72
  } catch (error) {
@@ -56,85 +75,423 @@ try {
56
75
  extra: { orderId: '12345' },
57
76
  });
58
77
  }
78
+
79
+ // Capture messages
80
+ sitepong.captureMessage('User signed up', 'info', {
81
+ user: { id: 'user-123' },
82
+ });
59
83
  ```
60
84
 
61
- ### `captureMessage(message, level?, context?)`
62
- Capture a message (info, warning, or error).
85
+ <p align="center">
86
+ <img src=".github/error-tracking.svg" alt="Error Tracking" width="100%">
87
+ </p>
88
+
89
+ ### Session Replay
90
+
91
+ Record and replay user sessions to see exactly what happened before an error. Privacy-focused with automatic input masking.
63
92
 
64
93
  ```javascript
65
- sitepong.captureMessage('User signed up', 'info', {
66
- user: { id: 'user-123' },
94
+ sitepong.init({
95
+ apiKey: 'your-api-key',
96
+ replay: {
97
+ enabled: true,
98
+ maskInputs: true, // Mask sensitive inputs
99
+ blockSelector: '.private', // Block specific elements
100
+ sampleRate: 0.5, // Record 50% of sessions
101
+ recordNetwork: true, // Capture XHR/fetch requests
102
+ recordConsole: true, // Capture console logs
103
+ },
67
104
  });
105
+
106
+ // Manual control
107
+ sitepong.startReplay();
108
+ sitepong.stopReplay();
109
+ const sessionId = sitepong.getReplaySessionId();
68
110
  ```
69
111
 
70
- ### `setUser(user)`
71
- Set user context for all subsequent errors.
112
+ <p align="center">
113
+ <img src=".github/session-replay.svg" alt="Session Replay" width="100%">
114
+ </p>
115
+
116
+ ### Feature Flags
117
+
118
+ Ship features with confidence using real-time feature flags and A/B testing.
72
119
 
73
120
  ```javascript
74
- sitepong.setUser({
75
- id: 'user-123',
76
- email: 'user@example.com',
121
+ sitepong.init({
122
+ apiKey: 'your-api-key',
123
+ enableFlags: true,
77
124
  });
125
+
126
+ // Wait for flags to load
127
+ await sitepong.waitForFlags();
128
+
129
+ // Boolean flags
130
+ if (sitepong.getFlag('new-checkout', false)) {
131
+ showNewCheckout();
132
+ }
133
+
134
+ // Multivariate flags / A/B tests
135
+ const variant = sitepong.getVariant('button-color', 'blue');
136
+ const payload = sitepong.getVariantPayload('pricing-test');
137
+
138
+ // Get all flags
139
+ const allFlags = sitepong.getAllFlags();
78
140
  ```
79
141
 
80
- ### `setTags(tags)`
81
- Set tags for all subsequent errors.
142
+ <p align="center">
143
+ <img src=".github/feature-flags.svg" alt="Feature Flags" width="100%">
144
+ </p>
145
+
146
+ ### Product Analytics
147
+
148
+ Understand user behavior with event tracking and autocapture.
82
149
 
83
150
  ```javascript
84
- sitepong.setTags({
85
- version: '2.0.0',
86
- region: 'us-east',
151
+ sitepong.init({
152
+ apiKey: 'your-api-key',
153
+ analytics: {
154
+ enabled: true,
155
+ autocapturePageviews: true,
156
+ autocaptureClicks: true,
157
+ autocaptureForms: true,
158
+ },
159
+ });
160
+
161
+ // Track custom events
162
+ sitepong.track('Purchase Completed', {
163
+ product: 'Pro Plan',
164
+ revenue: 99,
165
+ });
166
+
167
+ // Identify users
168
+ sitepong.identify('user-123', {
169
+ name: 'John Doe',
170
+ email: 'john@example.com',
171
+ plan: 'pro',
172
+ });
173
+
174
+ // Group users
175
+ sitepong.group('company-456', {
176
+ name: 'Acme Inc',
177
+ industry: 'Technology',
87
178
  });
179
+
180
+ // Manual page views
181
+ sitepong.trackPageView('/checkout');
88
182
  ```
89
183
 
90
- ### `setContext(context)`
91
- Set additional context.
184
+ <p align="center">
185
+ <img src=".github/analytics.svg" alt="Product Analytics" width="100%">
186
+ </p>
187
+
188
+ ### Device Intelligence & Fraud Detection
189
+
190
+ Identify devices and detect fraudulent activity with advanced fingerprinting.
92
191
 
93
192
  ```javascript
94
- sitepong.setContext({
95
- extra: { sessionId: 'abc123' },
193
+ sitepong.init({
194
+ apiKey: 'your-api-key',
195
+ fingerprint: {
196
+ enabled: true,
197
+ extendedSignals: true,
198
+ },
96
199
  });
200
+
201
+ // Get stable visitor ID
202
+ const { visitorId, confidence } = await sitepong.getVisitorId();
203
+
204
+ // Get device signals
205
+ const signals = await sitepong.getDeviceSignals();
206
+
207
+ // Fraud detection
208
+ const fraud = await sitepong.getFraudCheck();
209
+ if (fraud.riskScore > 0.8) {
210
+ blockTransaction();
211
+ }
97
212
  ```
98
213
 
99
- ### `flush()`
100
- Manually flush the error queue.
214
+ ### Performance Monitoring
215
+
216
+ Track performance with Web Vitals, custom transactions, and distributed tracing.
101
217
 
102
218
  ```javascript
103
- await sitepong.flush();
219
+ sitepong.init({
220
+ apiKey: 'your-api-key',
221
+ performance: {
222
+ enabled: true,
223
+ webVitals: true,
224
+ navigationTiming: true,
225
+ resourceTiming: true,
226
+ sampleRate: 1.0,
227
+ },
228
+ });
229
+
230
+ // Get Web Vitals
231
+ const vitals = sitepong.getWebVitals();
232
+ // { LCP: 1200, FID: 50, CLS: 0.1, FCP: 800, TTFB: 200 }
233
+
234
+ // Custom transactions
235
+ const txId = sitepong.startTransaction('checkout-flow');
236
+ const spanId = sitepong.startSpan(txId, 'validate-cart');
237
+ // ... do work
238
+ sitepong.endSpan(txId, spanId);
239
+ sitepong.endTransaction(txId);
240
+
241
+ // Distributed tracing
242
+ import { createTraceContext, propagateTrace } from 'sitepong';
243
+
244
+ const trace = createTraceContext();
245
+ fetch('/api/order', {
246
+ headers: propagateTrace(trace),
247
+ });
104
248
  ```
105
249
 
106
- ## Framework Integration
250
+ <p align="center">
251
+ <img src=".github/performance.svg" alt="Performance Monitoring" width="100%">
252
+ </p>
253
+
254
+ ### Cron Monitoring
107
255
 
108
- ### React
256
+ Monitor scheduled jobs and get alerted when they fail or miss a schedule.
109
257
 
110
258
  ```javascript
111
- import sitepong from 'sitepong';
112
- import { useEffect } from 'react';
259
+ sitepong.init({
260
+ apiKey: 'your-api-key',
261
+ crons: { enabled: true },
262
+ });
263
+
264
+ // Simple check-in
265
+ await sitepong.cronCheckin('daily-backup');
266
+
267
+ // Start/end pattern
268
+ const cron = sitepong.cronStart('nightly-sync');
269
+ try {
270
+ await performSync();
271
+ await cron.ok();
272
+ } catch (error) {
273
+ await cron.error();
274
+ }
275
+
276
+ // Wrap async functions
277
+ await sitepong.cronWrap('hourly-cleanup', async () => {
278
+ await cleanupOldRecords();
279
+ });
280
+ ```
281
+
282
+ ### Custom Metrics
283
+
284
+ Track business and application metrics with counters, gauges, and histograms.
285
+
286
+ ```javascript
287
+ sitepong.init({
288
+ apiKey: 'your-api-key',
289
+ metrics: { enabled: true },
290
+ });
291
+
292
+ // Counters
293
+ sitepong.metricIncrement('api.requests', 1, { tags: { endpoint: '/users' } });
294
+
295
+ // Gauges
296
+ sitepong.metricGauge('queue.size', 42);
297
+
298
+ // Histograms
299
+ sitepong.metricHistogram('response.size', 1024);
300
+
301
+ // Distributions
302
+ sitepong.metricDistribution('payment.amount', 99.99);
303
+
304
+ // Timing
305
+ await sitepong.metricTime('db.query', async () => {
306
+ return await db.query('SELECT * FROM users');
307
+ });
308
+
309
+ // Manual timer
310
+ const timer = sitepong.metricStartTimer('operation.duration');
311
+ // ... do work
312
+ timer.stop();
313
+ ```
314
+
315
+ ### Database Query Tracking
316
+
317
+ Monitor database performance and detect N+1 query patterns.
318
+
319
+ ```javascript
320
+ sitepong.init({
321
+ apiKey: 'your-api-key',
322
+ database: {
323
+ enabled: true,
324
+ slowQueryThreshold: 100, // Log queries over 100ms
325
+ redactParams: true, // Redact sensitive parameters
326
+ },
327
+ });
328
+
329
+ // Track queries
330
+ const users = await sitepong.dbTrack(
331
+ 'SELECT * FROM users WHERE id = ?',
332
+ () => db.query('SELECT * FROM users WHERE id = ?', [userId])
333
+ );
334
+
335
+ // Detect N+1 patterns
336
+ const patterns = sitepong.getDbNPlusOnePatterns();
337
+ // [{ query: 'SELECT * FROM orders WHERE user_id = ?', count: 50 }]
338
+ ```
339
+
340
+ ### Production Profiling
341
+
342
+ Profile your production code to identify performance bottlenecks.
343
+
344
+ ```javascript
345
+ sitepong.init({
346
+ apiKey: 'your-api-key',
347
+ profiling: {
348
+ enabled: true,
349
+ sampleRate: 0.1, // Profile 10% of operations
350
+ maxDuration: 30000, // Max 30s profiles
351
+ },
352
+ });
353
+
354
+ // Profile async operations
355
+ const result = await sitepong.profile('processOrder', async () => {
356
+ return await processOrder(orderId);
357
+ });
358
+
359
+ // Manual spans
360
+ const endSpan = sitepong.startProfileSpan('validate');
361
+ // ... validation logic
362
+ endSpan();
363
+ ```
364
+
365
+ ---
366
+
367
+ ## React Integration
368
+
369
+ First-class React support with components and hooks.
370
+
371
+ ```bash
372
+ import { ... } from 'sitepong/react';
373
+ ```
374
+
375
+ ### Provider & Error Boundary
376
+
377
+ ```jsx
378
+ import { SitePongProvider, SitePongErrorBoundary } from 'sitepong/react';
113
379
 
114
380
  function App() {
115
- useEffect(() => {
116
- sitepong.init({
117
- apiKey: process.env.REACT_APP_SITEPONG_KEY,
118
- environment: process.env.NODE_ENV,
119
- });
120
- }, []);
121
-
122
- return <YourApp />;
381
+ return (
382
+ <SitePongProvider
383
+ apiKey="your-api-key"
384
+ environment="production"
385
+ analytics={{ enabled: true, autocapturePageviews: true }}
386
+ replay={{ enabled: true }}
387
+ >
388
+ <SitePongErrorBoundary fallback={<ErrorPage />}>
389
+ <YourApp />
390
+ </SitePongErrorBoundary>
391
+ </SitePongProvider>
392
+ );
123
393
  }
124
394
  ```
125
395
 
396
+ ### Hooks
397
+
398
+ ```jsx
399
+ import {
400
+ // Core
401
+ useSitePong,
402
+ useCaptureException,
403
+ useSetUser,
404
+
405
+ // Feature Flags
406
+ useFeatureFlag,
407
+ useExperiment,
408
+
409
+ // Analytics
410
+ useTrack,
411
+ useIdentify,
412
+
413
+ // Fingerprinting
414
+ useVisitorId,
415
+ useFraudCheck,
416
+
417
+ // Performance
418
+ useWebVitals,
419
+ usePerformanceTransaction,
420
+
421
+ // Replay
422
+ useReplay,
423
+ } from 'sitepong/react';
424
+
425
+ function CheckoutButton() {
426
+ const track = useTrack();
427
+ const showNewDesign = useFeatureFlag('new-checkout-design', false);
428
+ const { variant } = useExperiment('button-color');
429
+
430
+ const handleClick = () => {
431
+ track('Checkout Started', { items: cart.length });
432
+ // ...
433
+ };
434
+
435
+ return (
436
+ <button
437
+ onClick={handleClick}
438
+ style={{ background: variant === 'red' ? 'red' : 'blue' }}
439
+ >
440
+ {showNewDesign ? 'Complete Purchase' : 'Checkout'}
441
+ </button>
442
+ );
443
+ }
444
+ ```
445
+
446
+ ---
447
+
448
+ ## Framework Integration
449
+
126
450
  ### Next.js
127
451
 
128
452
  ```javascript
129
- // pages/_app.js or app/layout.js
453
+ // app/providers.tsx
454
+ 'use client';
455
+
456
+ import { SitePongProvider } from 'sitepong/react';
457
+
458
+ export function Providers({ children }) {
459
+ return (
460
+ <SitePongProvider
461
+ apiKey={process.env.NEXT_PUBLIC_SITEPONG_KEY}
462
+ environment={process.env.NODE_ENV}
463
+ replay={{ enabled: true }}
464
+ >
465
+ {children}
466
+ </SitePongProvider>
467
+ );
468
+ }
469
+ ```
470
+
471
+ ### Express
472
+
473
+ ```javascript
474
+ import express from 'express';
130
475
  import sitepong from 'sitepong';
131
476
 
132
- if (typeof window !== 'undefined') {
133
- sitepong.init({
134
- apiKey: process.env.NEXT_PUBLIC_SITEPONG_KEY,
135
- environment: process.env.NODE_ENV,
477
+ const app = express();
478
+
479
+ sitepong.init({
480
+ apiKey: process.env.SITEPONG_KEY,
481
+ environment: 'production',
482
+ });
483
+
484
+ // Error handling middleware
485
+ app.use((err, req, res, next) => {
486
+ sitepong.captureError(err, {
487
+ extra: {
488
+ url: req.url,
489
+ method: req.method,
490
+ userId: req.user?.id,
491
+ },
136
492
  });
137
- }
493
+ next(err);
494
+ });
138
495
  ```
139
496
 
140
497
  ### Node.js
@@ -147,9 +504,204 @@ sitepong.init({
147
504
  environment: process.env.NODE_ENV,
148
505
  });
149
506
 
150
- // Uncaught exceptions and unhandled rejections are automatically captured
507
+ // Uncaught exceptions and unhandled rejections
508
+ // are automatically captured
151
509
  ```
152
510
 
511
+ ---
512
+
513
+ ## Configuration Reference
514
+
515
+ ```javascript
516
+ sitepong.init({
517
+ // Required
518
+ apiKey: 'your-api-key',
519
+
520
+ // Core
521
+ endpoint: 'https://ingest.sitepong.com',
522
+ environment: 'production',
523
+ release: '1.0.0',
524
+ autoCapture: true,
525
+ maxBatchSize: 10,
526
+ flushInterval: 5000,
527
+ debug: false,
528
+
529
+ // Feature Flags
530
+ enableFlags: false,
531
+ flagsEndpoint: undefined,
532
+
533
+ // Analytics
534
+ analytics: {
535
+ enabled: false,
536
+ autocapturePageviews: false,
537
+ autocaptureClicks: false,
538
+ autocaptureForms: false,
539
+ },
540
+
541
+ // Session Replay
542
+ replay: {
543
+ enabled: false,
544
+ maskInputs: true,
545
+ blockSelector: undefined,
546
+ maskSelector: undefined,
547
+ sampleRate: 1.0,
548
+ maxSessionDuration: 3600000,
549
+ recordNetwork: false,
550
+ recordConsole: false,
551
+ },
552
+
553
+ // Performance
554
+ performance: {
555
+ enabled: false,
556
+ webVitals: true,
557
+ navigationTiming: true,
558
+ resourceTiming: false,
559
+ sampleRate: 1.0,
560
+ },
561
+
562
+ // Fingerprinting
563
+ fingerprint: {
564
+ enabled: false,
565
+ extendedSignals: false,
566
+ },
567
+
568
+ // Cron Monitoring
569
+ crons: {
570
+ enabled: false,
571
+ },
572
+
573
+ // Custom Metrics
574
+ metrics: {
575
+ enabled: false,
576
+ flushInterval: 10000,
577
+ maxBatchSize: 100,
578
+ },
579
+
580
+ // Database Tracking
581
+ database: {
582
+ enabled: false,
583
+ slowQueryThreshold: 100,
584
+ redactParams: true,
585
+ },
586
+
587
+ // Profiling
588
+ profiling: {
589
+ enabled: false,
590
+ sampleRate: 0.1,
591
+ maxDuration: 30000,
592
+ },
593
+ });
594
+ ```
595
+
596
+ ---
597
+
598
+ ## API Reference
599
+
600
+ ### Core
601
+
602
+ | Method | Description |
603
+ |--------|-------------|
604
+ | `init(config)` | Initialize the SDK |
605
+ | `captureError(error, context?)` | Capture an error |
606
+ | `captureMessage(message, level?, context?)` | Capture a message |
607
+ | `setUser(user)` | Set user context |
608
+ | `setTags(tags)` | Set tags |
609
+ | `setContext(context)` | Set additional context |
610
+ | `flush()` | Flush the error queue |
611
+
612
+ ### Feature Flags
613
+
614
+ | Method | Description |
615
+ |--------|-------------|
616
+ | `getFlag(key, defaultValue?)` | Get boolean flag |
617
+ | `getVariant(key, defaultValue?)` | Get variant key |
618
+ | `getVariantPayload(key, defaultValue?)` | Get variant payload |
619
+ | `getAllFlags()` | Get all flags |
620
+ | `waitForFlags()` | Wait for flags to load |
621
+ | `areFlagsReady()` | Check if flags are loaded |
622
+ | `refreshFlags()` | Refresh flags from server |
623
+
624
+ ### Analytics
625
+
626
+ | Method | Description |
627
+ |--------|-------------|
628
+ | `track(event, properties?)` | Track custom event |
629
+ | `trackPageView(url?, properties?)` | Track page view |
630
+ | `identify(userId, traits?)` | Identify user |
631
+ | `group(groupId, traits?)` | Group users |
632
+ | `resetAnalytics()` | Reset analytics state |
633
+
634
+ ### Session Replay
635
+
636
+ | Method | Description |
637
+ |--------|-------------|
638
+ | `startReplay()` | Start recording |
639
+ | `stopReplay()` | Stop recording |
640
+ | `isReplayRecording()` | Check if recording |
641
+ | `getReplaySessionId()` | Get session ID |
642
+
643
+ ### Performance
644
+
645
+ | Method | Description |
646
+ |--------|-------------|
647
+ | `startTransaction(name, data?)` | Start transaction |
648
+ | `endTransaction(id, status?)` | End transaction |
649
+ | `startSpan(txId, name, data?)` | Start span |
650
+ | `endSpan(txId, spanId, status?)` | End span |
651
+ | `getWebVitals()` | Get Web Vitals |
652
+
653
+ ### Fingerprinting
654
+
655
+ | Method | Description |
656
+ |--------|-------------|
657
+ | `getVisitorId()` | Get visitor ID |
658
+ | `getDeviceSignals()` | Get device signals |
659
+ | `getFraudCheck()` | Run fraud check |
660
+
661
+ ### Metrics
662
+
663
+ | Method | Description |
664
+ |--------|-------------|
665
+ | `metricIncrement(name, value?, options?)` | Increment counter |
666
+ | `metricGauge(name, value, options?)` | Set gauge |
667
+ | `metricHistogram(name, value, options?)` | Record histogram |
668
+ | `metricDistribution(name, value, options?)` | Record distribution |
669
+ | `metricTime(name, fn, options?)` | Time async function |
670
+ | `metricStartTimer(name, options?)` | Start manual timer |
671
+
672
+ ### Cron Monitoring
673
+
674
+ | Method | Description |
675
+ |--------|-------------|
676
+ | `cronCheckin(slug, options?)` | Simple check-in |
677
+ | `cronStart(slug, environment?)` | Start cron job |
678
+ | `cronWrap(slug, fn, environment?)` | Wrap async function |
679
+
680
+ ### Database
681
+
682
+ | Method | Description |
683
+ |--------|-------------|
684
+ | `dbTrack(query, fn, source?)` | Track async query |
685
+ | `dbTrackSync(query, fn, source?)` | Track sync query |
686
+ | `getDbQueryCount()` | Get query count |
687
+ | `getDbNPlusOnePatterns()` | Get N+1 patterns |
688
+
689
+ ### Profiling
690
+
691
+ | Method | Description |
692
+ |--------|-------------|
693
+ | `profile(name, fn, metadata?)` | Profile async function |
694
+ | `startProfileSpan(name, metadata?)` | Start profile span |
695
+ | `getProfiles()` | Get all profiles |
696
+ | `getLatestProfile()` | Get latest profile |
697
+ | `flushProfiles()` | Flush profiles |
698
+
699
+ ---
700
+
701
+ ## Documentation
702
+
703
+ For full documentation, visit [sitepong.com/docs](https://sitepong.com/docs).
704
+
153
705
  ## License
154
706
 
155
707
  MIT