@tracetail/react 2.3.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 +419 -0
- package/dist/index.d.ts +162 -0
- package/dist/index.esm.js +280 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +293 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
# @tracetail/react
|
|
2
|
+
|
|
3
|
+
> React hooks for TraceTail enterprise browser fingerprinting with **over 99.5% accuracy**. Built for React 18 with full TypeScript support.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@tracetail/react)
|
|
6
|
+
[](https://www.npmjs.com/package/@tracetail/react)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://reactjs.org/)
|
|
9
|
+
|
|
10
|
+
## 🚀 Quick Start
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @tracetail/react
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import { useTraceTail } from '@tracetail/react';
|
|
18
|
+
|
|
19
|
+
function App() {
|
|
20
|
+
const { fingerprint, loading, error } = useTraceTail({
|
|
21
|
+
apiKey: 'your-api-key',
|
|
22
|
+
immediate: true
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (loading) return <div>Generating fingerprint...</div>;
|
|
26
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
27
|
+
|
|
28
|
+
return <div>Visitor ID: {fingerprint?.visitorId}</div>;
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## ✨ Features
|
|
33
|
+
|
|
34
|
+
- **🎯 Over 99.5% accuracy** - Industry-leading device identification
|
|
35
|
+
- **⚡ React optimized** - Built specifically for React with hooks
|
|
36
|
+
- **🔒 Enterprise security** - Bank-grade fraud detection hooks
|
|
37
|
+
- **📱 Cross-platform** - Works on all browsers and devices
|
|
38
|
+
- **🔧 TypeScript** - Full type safety and IntelliSense
|
|
39
|
+
- **🌐 Incognito consistent** - Same ID across normal and private browsing
|
|
40
|
+
- **🚀 Performance optimized** - < 25ms fingerprint generation
|
|
41
|
+
- **🎣 React 18 ready** - Supports concurrent features and Suspense
|
|
42
|
+
|
|
43
|
+
## 🎣 Hooks Reference
|
|
44
|
+
|
|
45
|
+
### `useTraceTail`
|
|
46
|
+
|
|
47
|
+
Basic fingerprinting hook for visitor identification.
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { useTraceTail } from '@tracetail/react';
|
|
51
|
+
|
|
52
|
+
function MyComponent() {
|
|
53
|
+
const { fingerprint, loading, error, generate, regenerate } = useTraceTail({
|
|
54
|
+
apiKey: 'tt_prod_...',
|
|
55
|
+
immediate: true, // Generate on mount
|
|
56
|
+
caching: true, // Cache results
|
|
57
|
+
debug: false // Enable debug logging
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div>
|
|
62
|
+
{loading && <p>Generating fingerprint...</p>}
|
|
63
|
+
{error && <p>Error: {error.message}</p>}
|
|
64
|
+
{fingerprint && (
|
|
65
|
+
<div>
|
|
66
|
+
<p>Visitor ID: {fingerprint.visitorId}</p>
|
|
67
|
+
<p>Confidence: {(fingerprint.confidence * 100).toFixed(1)}%</p>
|
|
68
|
+
<p>Processing Time: {fingerprint.processingTime}ms</p>
|
|
69
|
+
</div>
|
|
70
|
+
)}
|
|
71
|
+
<button onClick={regenerate} disabled={loading}>
|
|
72
|
+
Regenerate Fingerprint
|
|
73
|
+
</button>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### `useEnhancedTraceTail`
|
|
80
|
+
|
|
81
|
+
Enhanced fingerprinting with fraud detection capabilities.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import { useEnhancedTraceTail } from '@tracetail/react';
|
|
85
|
+
|
|
86
|
+
function SecurityComponent() {
|
|
87
|
+
const { fingerprint, loading, error } = useEnhancedTraceTail({
|
|
88
|
+
apiKey: 'your-api-key',
|
|
89
|
+
immediate: true
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (loading) return <div>Analyzing security...</div>;
|
|
93
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<div>
|
|
97
|
+
<div className={`alert ${fingerprint?.threatLevel}`}>
|
|
98
|
+
<h3>Security Analysis</h3>
|
|
99
|
+
<p>Risk Level: {fingerprint?.threatLevel}</p>
|
|
100
|
+
<p>Risk Score: {(fingerprint?.riskScore * 100).toFixed(1)}%</p>
|
|
101
|
+
<p>Bot Probability: {(fingerprint?.botProbability * 100).toFixed(1)}%</p>
|
|
102
|
+
|
|
103
|
+
{fingerprint?.fraudSignals.length > 0 && (
|
|
104
|
+
<div>
|
|
105
|
+
<h4>Fraud Signals:</h4>
|
|
106
|
+
<ul>
|
|
107
|
+
{fingerprint.fraudSignals.map((signal, i) => (
|
|
108
|
+
<li key={i}>{signal}</li>
|
|
109
|
+
))}
|
|
110
|
+
</ul>
|
|
111
|
+
</div>
|
|
112
|
+
)}
|
|
113
|
+
|
|
114
|
+
{fingerprint?.geolocation && (
|
|
115
|
+
<p>Location: {fingerprint.geolocation.city}, {fingerprint.geolocation.country}</p>
|
|
116
|
+
)}
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `useVisitorId`
|
|
124
|
+
|
|
125
|
+
Simplified hook focused on visitor identification with persistence.
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
import { useVisitorId } from '@tracetail/react';
|
|
129
|
+
|
|
130
|
+
function UserTrackingComponent() {
|
|
131
|
+
const {
|
|
132
|
+
visitorId,
|
|
133
|
+
isReturningVisitor,
|
|
134
|
+
loading,
|
|
135
|
+
error,
|
|
136
|
+
refresh
|
|
137
|
+
} = useVisitorId({
|
|
138
|
+
apiKey: 'your-api-key',
|
|
139
|
+
storageKey: 'my_app_visitor_id' // Custom localStorage key
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<div>
|
|
144
|
+
{loading && <p>Identifying visitor...</p>}
|
|
145
|
+
{error && <p>Error: {error.message}</p>}
|
|
146
|
+
{visitorId && (
|
|
147
|
+
<div>
|
|
148
|
+
<p>Visitor ID: {visitorId}</p>
|
|
149
|
+
<p>Status: {isReturningVisitor ? '🔄 Returning' : '✨ New'} visitor</p>
|
|
150
|
+
<button onClick={refresh}>Refresh ID</button>
|
|
151
|
+
</div>
|
|
152
|
+
)}
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### `useFraudDetection`
|
|
159
|
+
|
|
160
|
+
Specialized hook for fraud detection with configurable thresholds.
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
import { useFraudDetection } from '@tracetail/react';
|
|
164
|
+
|
|
165
|
+
function FraudCheck() {
|
|
166
|
+
const {
|
|
167
|
+
isFraudulent,
|
|
168
|
+
riskLevel,
|
|
169
|
+
riskScore,
|
|
170
|
+
botProbability,
|
|
171
|
+
fraudSignals,
|
|
172
|
+
loading,
|
|
173
|
+
recheck
|
|
174
|
+
} = useFraudDetection({
|
|
175
|
+
apiKey: 'your-api-key',
|
|
176
|
+
riskThreshold: 0.7, // Fraud threshold (0-1)
|
|
177
|
+
botThreshold: 0.5 // Bot detection threshold (0-1)
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
if (loading) return <div>🔍 Checking for fraud...</div>;
|
|
181
|
+
|
|
182
|
+
if (isFraudulent) {
|
|
183
|
+
return (
|
|
184
|
+
<div className="fraud-alert">
|
|
185
|
+
<h3>⚠️ High Risk Detected</h3>
|
|
186
|
+
<p>Additional verification required</p>
|
|
187
|
+
<p>Risk Score: {(riskScore * 100).toFixed(1)}%</p>
|
|
188
|
+
<p>Bot Probability: {(botProbability * 100).toFixed(1)}%</p>
|
|
189
|
+
<button onClick={recheck}>Recheck</button>
|
|
190
|
+
</div>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
<div className="fraud-clear">
|
|
196
|
+
<h3>✅ Security Check Passed</h3>
|
|
197
|
+
<p>Risk Level: {riskLevel}</p>
|
|
198
|
+
<p>Score: {(riskScore * 100).toFixed(1)}%</p>
|
|
199
|
+
</div>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## 🌟 Advanced Usage
|
|
205
|
+
|
|
206
|
+
### Server-Side Rendering (SSR)
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
import { useEffect, useState } from 'react';
|
|
210
|
+
import { useTraceTail } from '@tracetail/react';
|
|
211
|
+
|
|
212
|
+
function SSRSafeComponent() {
|
|
213
|
+
const [isClient, setIsClient] = useState(false);
|
|
214
|
+
|
|
215
|
+
// Only run fingerprinting on client-side
|
|
216
|
+
const { fingerprint, loading } = useTraceTail({
|
|
217
|
+
apiKey: 'your-api-key',
|
|
218
|
+
immediate: isClient
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
useEffect(() => {
|
|
222
|
+
setIsClient(true);
|
|
223
|
+
}, []);
|
|
224
|
+
|
|
225
|
+
if (!isClient) {
|
|
226
|
+
return <div>Loading...</div>;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<div>
|
|
231
|
+
{loading ? 'Generating...' : `ID: ${fingerprint?.visitorId}`}
|
|
232
|
+
</div>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Custom Hook Pattern
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
import { useEnhancedTraceTail } from '@tracetail/react';
|
|
241
|
+
|
|
242
|
+
function useSecurityCheck() {
|
|
243
|
+
const { fingerprint, loading, error } = useEnhancedTraceTail({
|
|
244
|
+
apiKey: process.env.REACT_APP_TRACETAIL_KEY!,
|
|
245
|
+
immediate: true
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
const securityStatus = fingerprint ? {
|
|
249
|
+
isSecure: fingerprint.riskScore < 0.3,
|
|
250
|
+
needsVerification: fingerprint.riskScore > 0.7,
|
|
251
|
+
isBot: fingerprint.botProbability > 0.5,
|
|
252
|
+
level: fingerprint.threatLevel
|
|
253
|
+
} : null;
|
|
254
|
+
|
|
255
|
+
return { securityStatus, loading, error };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Usage
|
|
259
|
+
function App() {
|
|
260
|
+
const { securityStatus, loading } = useSecurityCheck();
|
|
261
|
+
|
|
262
|
+
if (loading) return <div>Security check...</div>;
|
|
263
|
+
|
|
264
|
+
return (
|
|
265
|
+
<div>
|
|
266
|
+
{securityStatus?.needsVerification ? (
|
|
267
|
+
<AdditionalVerification />
|
|
268
|
+
) : (
|
|
269
|
+
<MainContent />
|
|
270
|
+
)}
|
|
271
|
+
</div>
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Integration with React Query
|
|
277
|
+
|
|
278
|
+
```tsx
|
|
279
|
+
import { useQuery } from '@tanstack/react-query';
|
|
280
|
+
import { useTraceTail } from '@tracetail/react';
|
|
281
|
+
|
|
282
|
+
function useUserProfile() {
|
|
283
|
+
const { fingerprint } = useTraceTail({
|
|
284
|
+
apiKey: 'your-api-key',
|
|
285
|
+
immediate: true
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
return useQuery({
|
|
289
|
+
queryKey: ['userProfile', fingerprint?.visitorId],
|
|
290
|
+
queryFn: () => fetchUserProfile(fingerprint?.visitorId),
|
|
291
|
+
enabled: !!fingerprint?.visitorId
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## 🔧 TypeScript Support
|
|
297
|
+
|
|
298
|
+
Full TypeScript definitions included:
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
import type {
|
|
302
|
+
FingerprintResult,
|
|
303
|
+
EnhancedFingerprintResult,
|
|
304
|
+
UseTraceTailReturn
|
|
305
|
+
} from '@tracetail/react';
|
|
306
|
+
|
|
307
|
+
const MyComponent: React.FC = () => {
|
|
308
|
+
const result: UseTraceTailReturn = useTraceTail({
|
|
309
|
+
apiKey: 'your-key',
|
|
310
|
+
immediate: true
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// Full type safety
|
|
314
|
+
const visitorId: string | null = result.fingerprint?.visitorId || null;
|
|
315
|
+
const confidence: number = result.fingerprint?.confidence || 0;
|
|
316
|
+
|
|
317
|
+
return <div>{visitorId}</div>;
|
|
318
|
+
};
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## ⚡ Performance Optimization
|
|
322
|
+
|
|
323
|
+
### Lazy Loading
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
import { lazy, Suspense } from 'react';
|
|
327
|
+
|
|
328
|
+
const FingerprintComponent = lazy(() => import('./FingerprintComponent'));
|
|
329
|
+
|
|
330
|
+
function App() {
|
|
331
|
+
return (
|
|
332
|
+
<Suspense fallback={<div>Loading security...</div>}>
|
|
333
|
+
<FingerprintComponent />
|
|
334
|
+
</Suspense>
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Conditional Loading
|
|
340
|
+
|
|
341
|
+
```tsx
|
|
342
|
+
function ConditionalFingerprinting() {
|
|
343
|
+
const [needsFingerprint, setNeedsFingerprint] = useState(false);
|
|
344
|
+
|
|
345
|
+
const { fingerprint, loading } = useTraceTail({
|
|
346
|
+
apiKey: 'your-api-key',
|
|
347
|
+
immediate: needsFingerprint // Only when needed
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
return (
|
|
351
|
+
<div>
|
|
352
|
+
<button onClick={() => setNeedsFingerprint(true)}>
|
|
353
|
+
Enable Security Check
|
|
354
|
+
</button>
|
|
355
|
+
{needsFingerprint && (
|
|
356
|
+
<div>
|
|
357
|
+
{loading ? 'Checking...' : `ID: ${fingerprint?.visitorId}`}
|
|
358
|
+
</div>
|
|
359
|
+
)}
|
|
360
|
+
</div>
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## 🌐 Browser Support
|
|
366
|
+
|
|
367
|
+
- Chrome 80+
|
|
368
|
+
- Firefox 75+
|
|
369
|
+
- Safari 13+
|
|
370
|
+
- Edge 80+
|
|
371
|
+
- React Native WebView
|
|
372
|
+
- Electron
|
|
373
|
+
|
|
374
|
+
## 🔄 Migration Guide
|
|
375
|
+
|
|
376
|
+
### From @tracetail/js
|
|
377
|
+
|
|
378
|
+
```tsx
|
|
379
|
+
// Before (vanilla JS)
|
|
380
|
+
import { TraceTail } from '@tracetail/js';
|
|
381
|
+
const tracetail = new TraceTail({ apiKey: 'key' });
|
|
382
|
+
const fingerprint = await tracetail.generateFingerprint();
|
|
383
|
+
|
|
384
|
+
// After (React hooks)
|
|
385
|
+
import { useTraceTail } from '@tracetail/react';
|
|
386
|
+
const { fingerprint, loading } = useTraceTail({
|
|
387
|
+
apiKey: 'key',
|
|
388
|
+
immediate: true
|
|
389
|
+
});
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### From other libraries
|
|
393
|
+
|
|
394
|
+
```tsx
|
|
395
|
+
// Replace custom fingerprinting hooks
|
|
396
|
+
const { fingerprint } = useTraceTail({
|
|
397
|
+
apiKey: 'your-key',
|
|
398
|
+
immediate: true
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
// Same visitor ID across sessions and devices
|
|
402
|
+
const visitorId = fingerprint?.visitorId;
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
## 📞 Support
|
|
406
|
+
|
|
407
|
+
- **Documentation:** https://tracetail.io/docs
|
|
408
|
+
- **API Reference:** https://tracetail.io/api-docs
|
|
409
|
+
- **Issues:** https://github.com/sirrodgepodge/TraceTail/issues
|
|
410
|
+
- **Discord:** https://discord.gg/tracetail
|
|
411
|
+
- **Email:** support@tracetail.io
|
|
412
|
+
|
|
413
|
+
## 📝 License
|
|
414
|
+
|
|
415
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
**[Get your API key](https://tracetail.io/auth) • [View Documentation](https://tracetail.io/docs) • [Try Live Demo](https://tracetail.io/live-demo)**
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @tracetail/react - React Hooks for Enterprise Browser Fingerprinting
|
|
3
|
+
* Version: 2.3.1
|
|
4
|
+
*
|
|
5
|
+
* Over 99.5% accuracy browser fingerprinting with React hooks.
|
|
6
|
+
* Perfect for fraud detection, user analytics, and security applications.
|
|
7
|
+
*/
|
|
8
|
+
import type { FC, ReactNode } from 'react';
|
|
9
|
+
import { FingerprintOptions, FingerprintResult, EnhancedFingerprintResult } from '@tracetail/js';
|
|
10
|
+
export interface UseTraceTailOptions extends FingerprintOptions {
|
|
11
|
+
immediate?: boolean;
|
|
12
|
+
suspense?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface UseTraceTailReturn {
|
|
15
|
+
fingerprint: FingerprintResult | null;
|
|
16
|
+
loading: boolean;
|
|
17
|
+
error: Error | null;
|
|
18
|
+
generate: () => Promise<FingerprintResult>;
|
|
19
|
+
regenerate: () => Promise<FingerprintResult>;
|
|
20
|
+
}
|
|
21
|
+
export interface UseEnhancedTraceTailReturn {
|
|
22
|
+
fingerprint: EnhancedFingerprintResult | null;
|
|
23
|
+
loading: boolean;
|
|
24
|
+
error: Error | null;
|
|
25
|
+
generate: () => Promise<EnhancedFingerprintResult>;
|
|
26
|
+
regenerate: () => Promise<EnhancedFingerprintResult>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* React hook for basic browser fingerprinting
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* import { useTraceTail } from '@tracetail/react';
|
|
34
|
+
*
|
|
35
|
+
* function MyComponent() {
|
|
36
|
+
* const { fingerprint, loading, error } = useTraceTail({
|
|
37
|
+
* apiKey: 'your-api-key',
|
|
38
|
+
* immediate: true
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* if (loading) return <div>Generating fingerprint...</div>;
|
|
42
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
43
|
+
*
|
|
44
|
+
* return <div>Visitor ID: {fingerprint?.visitorId}</div>;
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function useTraceTail(options: UseTraceTailOptions): UseTraceTailReturn;
|
|
49
|
+
/**
|
|
50
|
+
* React hook for enhanced browser fingerprinting with fraud detection
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import { useEnhancedTraceTail } from '@tracetail/react';
|
|
55
|
+
*
|
|
56
|
+
* function SecurityComponent() {
|
|
57
|
+
* const { fingerprint, loading, error } = useEnhancedTraceTail({
|
|
58
|
+
* apiKey: 'your-api-key',
|
|
59
|
+
* immediate: true
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* if (loading) return <div>Analyzing security...</div>;
|
|
63
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
64
|
+
*
|
|
65
|
+
* const riskLevel = fingerprint?.threatLevel || 'unknown';
|
|
66
|
+
* return (
|
|
67
|
+
* <div>
|
|
68
|
+
* <p>Risk Level: {riskLevel}</p>
|
|
69
|
+
* <p>Bot Probability: {(fingerprint?.botProbability * 100).toFixed(1)}%</p>
|
|
70
|
+
* </div>
|
|
71
|
+
* );
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare function useEnhancedTraceTail(options: UseTraceTailOptions): UseEnhancedTraceTailReturn;
|
|
76
|
+
/**
|
|
77
|
+
* React hook for visitor identification with persistent storage
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* import { useVisitorId } from '@tracetail/react';
|
|
82
|
+
*
|
|
83
|
+
* function UserTrackingComponent() {
|
|
84
|
+
* const { visitorId, isReturningVisitor, loading } = useVisitorId({
|
|
85
|
+
* apiKey: 'your-api-key',
|
|
86
|
+
* storageKey: 'app_visitor_id'
|
|
87
|
+
* });
|
|
88
|
+
*
|
|
89
|
+
* return (
|
|
90
|
+
* <div>
|
|
91
|
+
* <p>Visitor: {visitorId}</p>
|
|
92
|
+
* <p>Status: {isReturningVisitor ? 'Returning' : 'New'} visitor</p>
|
|
93
|
+
* </div>
|
|
94
|
+
* );
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export declare function useVisitorId(options: UseTraceTailOptions & {
|
|
99
|
+
storageKey?: string;
|
|
100
|
+
}): {
|
|
101
|
+
visitorId: string | null;
|
|
102
|
+
isReturningVisitor: boolean;
|
|
103
|
+
loading: boolean;
|
|
104
|
+
error: Error | null;
|
|
105
|
+
refresh: () => Promise<void>;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* React hook for fraud detection with configurable thresholds
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* import { useFraudDetection } from '@tracetail/react';
|
|
113
|
+
*
|
|
114
|
+
* function SecurityCheck() {
|
|
115
|
+
* const { isFraudulent, riskLevel, loading } = useFraudDetection({
|
|
116
|
+
* apiKey: 'your-api-key',
|
|
117
|
+
* riskThreshold: 0.7,
|
|
118
|
+
* botThreshold: 0.5
|
|
119
|
+
* });
|
|
120
|
+
*
|
|
121
|
+
* if (isFraudulent) {
|
|
122
|
+
* return <div>⚠️ High risk detected - additional verification required</div>;
|
|
123
|
+
* }
|
|
124
|
+
*
|
|
125
|
+
* return <div>✅ Security check passed (Risk: {riskLevel})</div>;
|
|
126
|
+
* }
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export declare function useFraudDetection(options: UseTraceTailOptions & {
|
|
130
|
+
riskThreshold?: number;
|
|
131
|
+
botThreshold?: number;
|
|
132
|
+
}): {
|
|
133
|
+
isFraudulent: boolean;
|
|
134
|
+
riskLevel: 'low' | 'medium' | 'high' | null;
|
|
135
|
+
riskScore: number;
|
|
136
|
+
botProbability: number;
|
|
137
|
+
fraudSignals: string[];
|
|
138
|
+
loading: boolean;
|
|
139
|
+
error: Error | null;
|
|
140
|
+
recheck: () => Promise<void>;
|
|
141
|
+
};
|
|
142
|
+
export type { FingerprintOptions, FingerprintResult, EnhancedFingerprintResult, ComponentData } from '@tracetail/js';
|
|
143
|
+
export { TraceTail } from '@tracetail/js';
|
|
144
|
+
interface TraceTailProviderProps {
|
|
145
|
+
children: ReactNode;
|
|
146
|
+
apiKey: string;
|
|
147
|
+
options?: Partial<FingerprintOptions>;
|
|
148
|
+
}
|
|
149
|
+
export declare const TraceTailProvider: FC<TraceTailProviderProps>;
|
|
150
|
+
/**
|
|
151
|
+
* Get the current React package version
|
|
152
|
+
*/
|
|
153
|
+
export declare const getVersion: () => string;
|
|
154
|
+
declare const _default: {
|
|
155
|
+
useTraceTail: typeof useTraceTail;
|
|
156
|
+
useEnhancedTraceTail: typeof useEnhancedTraceTail;
|
|
157
|
+
useVisitorId: typeof useVisitorId;
|
|
158
|
+
useFraudDetection: typeof useFraudDetection;
|
|
159
|
+
TraceTailProvider: FC<TraceTailProviderProps>;
|
|
160
|
+
getVersion: () => string;
|
|
161
|
+
};
|
|
162
|
+
export default _default;
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
|
+
import { TraceTail } from '@tracetail/js';
|
|
4
|
+
export { TraceTail } from '@tracetail/js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* React hook for basic browser fingerprinting
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { useTraceTail } from '@tracetail/react';
|
|
12
|
+
*
|
|
13
|
+
* function MyComponent() {
|
|
14
|
+
* const { fingerprint, loading, error } = useTraceTail({
|
|
15
|
+
* apiKey: 'your-api-key',
|
|
16
|
+
* immediate: true
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* if (loading) return <div>Generating fingerprint...</div>;
|
|
20
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
21
|
+
*
|
|
22
|
+
* return <div>Visitor ID: {fingerprint?.visitorId}</div>;
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
function useTraceTail(options) {
|
|
27
|
+
const [fingerprint, setFingerprint] = useState(null);
|
|
28
|
+
const [loading, setLoading] = useState(false);
|
|
29
|
+
const [error, setError] = useState(null);
|
|
30
|
+
const traceTailRef = useRef(null);
|
|
31
|
+
// Initialize TraceTail instance
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (!traceTailRef.current) {
|
|
34
|
+
traceTailRef.current = new TraceTail(options);
|
|
35
|
+
}
|
|
36
|
+
}, [options.apiKey, options.endpoint]);
|
|
37
|
+
const generate = useCallback(async () => {
|
|
38
|
+
if (!traceTailRef.current) {
|
|
39
|
+
throw new Error('TraceTail not initialized');
|
|
40
|
+
}
|
|
41
|
+
setLoading(true);
|
|
42
|
+
setError(null);
|
|
43
|
+
try {
|
|
44
|
+
const result = await traceTailRef.current.generateFingerprint({
|
|
45
|
+
includeComponents: true
|
|
46
|
+
});
|
|
47
|
+
setFingerprint(result);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const error = err instanceof Error ? err : new Error('Unknown error');
|
|
52
|
+
setError(error);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
setLoading(false);
|
|
57
|
+
}
|
|
58
|
+
}, []);
|
|
59
|
+
const regenerate = useCallback(async () => {
|
|
60
|
+
setFingerprint(null);
|
|
61
|
+
return generate();
|
|
62
|
+
}, [generate]);
|
|
63
|
+
// Auto-generate on mount if immediate is true
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (options.immediate && !fingerprint && !loading) {
|
|
66
|
+
generate().catch(() => {
|
|
67
|
+
// Error is already handled in generate function
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}, [options.immediate, fingerprint, loading, generate]);
|
|
71
|
+
return {
|
|
72
|
+
fingerprint,
|
|
73
|
+
loading,
|
|
74
|
+
error,
|
|
75
|
+
generate,
|
|
76
|
+
regenerate
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* React hook for enhanced browser fingerprinting with fraud detection
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* import { useEnhancedTraceTail } from '@tracetail/react';
|
|
85
|
+
*
|
|
86
|
+
* function SecurityComponent() {
|
|
87
|
+
* const { fingerprint, loading, error } = useEnhancedTraceTail({
|
|
88
|
+
* apiKey: 'your-api-key',
|
|
89
|
+
* immediate: true
|
|
90
|
+
* });
|
|
91
|
+
*
|
|
92
|
+
* if (loading) return <div>Analyzing security...</div>;
|
|
93
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
94
|
+
*
|
|
95
|
+
* const riskLevel = fingerprint?.threatLevel || 'unknown';
|
|
96
|
+
* return (
|
|
97
|
+
* <div>
|
|
98
|
+
* <p>Risk Level: {riskLevel}</p>
|
|
99
|
+
* <p>Bot Probability: {(fingerprint?.botProbability * 100).toFixed(1)}%</p>
|
|
100
|
+
* </div>
|
|
101
|
+
* );
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
function useEnhancedTraceTail(options) {
|
|
106
|
+
const [fingerprint, setFingerprint] = useState(null);
|
|
107
|
+
const [loading, setLoading] = useState(false);
|
|
108
|
+
const [error, setError] = useState(null);
|
|
109
|
+
const traceTailRef = useRef(null);
|
|
110
|
+
// Initialize TraceTail instance
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
if (!traceTailRef.current) {
|
|
113
|
+
traceTailRef.current = new TraceTail(options);
|
|
114
|
+
}
|
|
115
|
+
}, [options.apiKey, options.endpoint]);
|
|
116
|
+
const generate = useCallback(async () => {
|
|
117
|
+
if (!traceTailRef.current) {
|
|
118
|
+
throw new Error('TraceTail not initialized');
|
|
119
|
+
}
|
|
120
|
+
setLoading(true);
|
|
121
|
+
setError(null);
|
|
122
|
+
try {
|
|
123
|
+
const result = await traceTailRef.current.generateEnhancedFingerprint({
|
|
124
|
+
includeComponents: true,
|
|
125
|
+
fraudDetection: true
|
|
126
|
+
});
|
|
127
|
+
setFingerprint(result);
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
const error = err instanceof Error ? err : new Error('Unknown error');
|
|
132
|
+
setError(error);
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
setLoading(false);
|
|
137
|
+
}
|
|
138
|
+
}, []);
|
|
139
|
+
const regenerate = useCallback(async () => {
|
|
140
|
+
setFingerprint(null);
|
|
141
|
+
return generate();
|
|
142
|
+
}, [generate]);
|
|
143
|
+
// Auto-generate on mount if immediate is true
|
|
144
|
+
useEffect(() => {
|
|
145
|
+
if (options.immediate && !fingerprint && !loading) {
|
|
146
|
+
generate().catch(() => {
|
|
147
|
+
// Error is already handled in generate function
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}, [options.immediate, fingerprint, loading, generate]);
|
|
151
|
+
return {
|
|
152
|
+
fingerprint,
|
|
153
|
+
loading,
|
|
154
|
+
error,
|
|
155
|
+
generate,
|
|
156
|
+
regenerate
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* React hook for visitor identification with persistent storage
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* import { useVisitorId } from '@tracetail/react';
|
|
165
|
+
*
|
|
166
|
+
* function UserTrackingComponent() {
|
|
167
|
+
* const { visitorId, isReturningVisitor, loading } = useVisitorId({
|
|
168
|
+
* apiKey: 'your-api-key',
|
|
169
|
+
* storageKey: 'app_visitor_id'
|
|
170
|
+
* });
|
|
171
|
+
*
|
|
172
|
+
* return (
|
|
173
|
+
* <div>
|
|
174
|
+
* <p>Visitor: {visitorId}</p>
|
|
175
|
+
* <p>Status: {isReturningVisitor ? 'Returning' : 'New'} visitor</p>
|
|
176
|
+
* </div>
|
|
177
|
+
* );
|
|
178
|
+
* }
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
function useVisitorId(options) {
|
|
182
|
+
const storageKey = options.storageKey || 'tracetail_visitor_id';
|
|
183
|
+
const [visitorId, setVisitorId] = useState(null);
|
|
184
|
+
const [isReturningVisitor, setIsReturningVisitor] = useState(false);
|
|
185
|
+
const { fingerprint, loading, error, generate } = useTraceTail({
|
|
186
|
+
...options,
|
|
187
|
+
immediate: true
|
|
188
|
+
});
|
|
189
|
+
// Update visitor ID when fingerprint changes
|
|
190
|
+
useEffect(() => {
|
|
191
|
+
if (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.visitorId) {
|
|
192
|
+
const storedVisitorId = localStorage.getItem(storageKey);
|
|
193
|
+
if (storedVisitorId) {
|
|
194
|
+
setIsReturningVisitor(storedVisitorId === fingerprint.visitorId);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
setIsReturningVisitor(false);
|
|
198
|
+
}
|
|
199
|
+
setVisitorId(fingerprint.visitorId);
|
|
200
|
+
localStorage.setItem(storageKey, fingerprint.visitorId);
|
|
201
|
+
}
|
|
202
|
+
}, [fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.visitorId, storageKey]);
|
|
203
|
+
const refresh = useCallback(async () => {
|
|
204
|
+
await generate();
|
|
205
|
+
}, [generate]);
|
|
206
|
+
return {
|
|
207
|
+
visitorId,
|
|
208
|
+
isReturningVisitor,
|
|
209
|
+
loading,
|
|
210
|
+
error,
|
|
211
|
+
refresh
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* React hook for fraud detection with configurable thresholds
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```typescript
|
|
219
|
+
* import { useFraudDetection } from '@tracetail/react';
|
|
220
|
+
*
|
|
221
|
+
* function SecurityCheck() {
|
|
222
|
+
* const { isFraudulent, riskLevel, loading } = useFraudDetection({
|
|
223
|
+
* apiKey: 'your-api-key',
|
|
224
|
+
* riskThreshold: 0.7,
|
|
225
|
+
* botThreshold: 0.5
|
|
226
|
+
* });
|
|
227
|
+
*
|
|
228
|
+
* if (isFraudulent) {
|
|
229
|
+
* return <div>⚠️ High risk detected - additional verification required</div>;
|
|
230
|
+
* }
|
|
231
|
+
*
|
|
232
|
+
* return <div>✅ Security check passed (Risk: {riskLevel})</div>;
|
|
233
|
+
* }
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
function useFraudDetection(options) {
|
|
237
|
+
const riskThreshold = options.riskThreshold || 0.7;
|
|
238
|
+
const botThreshold = options.botThreshold || 0.5;
|
|
239
|
+
const { fingerprint, loading, error, generate } = useEnhancedTraceTail({
|
|
240
|
+
...options,
|
|
241
|
+
immediate: true
|
|
242
|
+
});
|
|
243
|
+
const isFraudulent = fingerprint ?
|
|
244
|
+
fingerprint.riskScore > riskThreshold || fingerprint.botProbability > botThreshold :
|
|
245
|
+
false;
|
|
246
|
+
const recheck = useCallback(async () => {
|
|
247
|
+
await generate();
|
|
248
|
+
}, [generate]);
|
|
249
|
+
return {
|
|
250
|
+
isFraudulent,
|
|
251
|
+
riskLevel: (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.threatLevel) || null,
|
|
252
|
+
riskScore: (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.riskScore) || 0,
|
|
253
|
+
botProbability: (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.botProbability) || 0,
|
|
254
|
+
fraudSignals: (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.fraudSignals) || [],
|
|
255
|
+
loading,
|
|
256
|
+
error,
|
|
257
|
+
recheck
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
const TraceTailProvider = ({ children }) => {
|
|
261
|
+
// This is a simple provider that could be extended with context
|
|
262
|
+
// For now, it just renders children since hooks manage their own instances
|
|
263
|
+
return jsx(Fragment, { children: children });
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Get the current React package version
|
|
267
|
+
*/
|
|
268
|
+
const getVersion = () => '2.3.1';
|
|
269
|
+
// Default export
|
|
270
|
+
var index = {
|
|
271
|
+
useTraceTail,
|
|
272
|
+
useEnhancedTraceTail,
|
|
273
|
+
useVisitorId,
|
|
274
|
+
useFraudDetection,
|
|
275
|
+
TraceTailProvider,
|
|
276
|
+
getVersion
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export { TraceTailProvider, index as default, getVersion, useEnhancedTraceTail, useFraudDetection, useTraceTail, useVisitorId };
|
|
280
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/index.tsx"],"sourcesContent":["/**\n * @tracetail/react - React Hooks for Enterprise Browser Fingerprinting\n * Version: 2.3.1\n * \n * Over 99.5% accuracy browser fingerprinting with React hooks.\n * Perfect for fraud detection, user analytics, and security applications.\n */\n\nimport { useEffect, useState, useCallback, useRef } from 'react';\nimport type { FC, ReactNode } from 'react';\nimport { TraceTail, FingerprintOptions, FingerprintResult, EnhancedFingerprintResult } from '@tracetail/js';\n\nexport interface UseTraceTailOptions extends FingerprintOptions {\n immediate?: boolean;\n suspense?: boolean;\n}\n\nexport interface UseTraceTailReturn {\n fingerprint: FingerprintResult | null;\n loading: boolean;\n error: Error | null;\n generate: () => Promise<FingerprintResult>;\n regenerate: () => Promise<FingerprintResult>;\n}\n\nexport interface UseEnhancedTraceTailReturn {\n fingerprint: EnhancedFingerprintResult | null;\n loading: boolean;\n error: Error | null;\n generate: () => Promise<EnhancedFingerprintResult>;\n regenerate: () => Promise<EnhancedFingerprintResult>;\n}\n\n/**\n * React hook for basic browser fingerprinting\n * \n * @example\n * ```typescript\n * import { useTraceTail } from '@tracetail/react';\n * \n * function MyComponent() {\n * const { fingerprint, loading, error } = useTraceTail({\n * apiKey: 'your-api-key',\n * immediate: true\n * });\n * \n * if (loading) return <div>Generating fingerprint...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * \n * return <div>Visitor ID: {fingerprint?.visitorId}</div>;\n * }\n * ```\n */\nexport function useTraceTail(options: UseTraceTailOptions): UseTraceTailReturn {\n const [fingerprint, setFingerprint] = useState<FingerprintResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n \n const traceTailRef = useRef<TraceTail | null>(null);\n \n // Initialize TraceTail instance\n useEffect(() => {\n if (!traceTailRef.current) {\n traceTailRef.current = new TraceTail(options);\n }\n }, [options.apiKey, options.endpoint]);\n\n const generate = useCallback(async (): Promise<FingerprintResult> => {\n if (!traceTailRef.current) {\n throw new Error('TraceTail not initialized');\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await traceTailRef.current.generateFingerprint({\n includeComponents: true\n });\n setFingerprint(result);\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Unknown error');\n setError(error);\n throw error;\n } finally {\n setLoading(false);\n }\n }, []);\n\n const regenerate = useCallback(async (): Promise<FingerprintResult> => {\n setFingerprint(null);\n return generate();\n }, [generate]);\n\n // Auto-generate on mount if immediate is true\n useEffect(() => {\n if (options.immediate && !fingerprint && !loading) {\n generate().catch(() => {\n // Error is already handled in generate function\n });\n }\n }, [options.immediate, fingerprint, loading, generate]);\n\n return {\n fingerprint,\n loading,\n error,\n generate,\n regenerate\n };\n}\n\n/**\n * React hook for enhanced browser fingerprinting with fraud detection\n * \n * @example\n * ```typescript\n * import { useEnhancedTraceTail } from '@tracetail/react';\n * \n * function SecurityComponent() {\n * const { fingerprint, loading, error } = useEnhancedTraceTail({\n * apiKey: 'your-api-key',\n * immediate: true\n * });\n * \n * if (loading) return <div>Analyzing security...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * \n * const riskLevel = fingerprint?.threatLevel || 'unknown';\n * return (\n * <div>\n * <p>Risk Level: {riskLevel}</p>\n * <p>Bot Probability: {(fingerprint?.botProbability * 100).toFixed(1)}%</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useEnhancedTraceTail(options: UseTraceTailOptions): UseEnhancedTraceTailReturn {\n const [fingerprint, setFingerprint] = useState<EnhancedFingerprintResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n \n const traceTailRef = useRef<TraceTail | null>(null);\n \n // Initialize TraceTail instance\n useEffect(() => {\n if (!traceTailRef.current) {\n traceTailRef.current = new TraceTail(options);\n }\n }, [options.apiKey, options.endpoint]);\n\n const generate = useCallback(async (): Promise<EnhancedFingerprintResult> => {\n if (!traceTailRef.current) {\n throw new Error('TraceTail not initialized');\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await traceTailRef.current.generateEnhancedFingerprint({\n includeComponents: true,\n fraudDetection: true\n });\n setFingerprint(result);\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Unknown error');\n setError(error);\n throw error;\n } finally {\n setLoading(false);\n }\n }, []);\n\n const regenerate = useCallback(async (): Promise<EnhancedFingerprintResult> => {\n setFingerprint(null);\n return generate();\n }, [generate]);\n\n // Auto-generate on mount if immediate is true\n useEffect(() => {\n if (options.immediate && !fingerprint && !loading) {\n generate().catch(() => {\n // Error is already handled in generate function\n });\n }\n }, [options.immediate, fingerprint, loading, generate]);\n\n return {\n fingerprint,\n loading,\n error,\n generate,\n regenerate\n };\n}\n\n/**\n * React hook for visitor identification with persistent storage\n * \n * @example\n * ```typescript\n * import { useVisitorId } from '@tracetail/react';\n * \n * function UserTrackingComponent() {\n * const { visitorId, isReturningVisitor, loading } = useVisitorId({\n * apiKey: 'your-api-key',\n * storageKey: 'app_visitor_id'\n * });\n * \n * return (\n * <div>\n * <p>Visitor: {visitorId}</p>\n * <p>Status: {isReturningVisitor ? 'Returning' : 'New'} visitor</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useVisitorId(options: UseTraceTailOptions & {\n storageKey?: string;\n}): {\n visitorId: string | null;\n isReturningVisitor: boolean;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n} {\n const storageKey = options.storageKey || 'tracetail_visitor_id';\n const [visitorId, setVisitorId] = useState<string | null>(null);\n const [isReturningVisitor, setIsReturningVisitor] = useState(false);\n \n const { fingerprint, loading, error, generate } = useTraceTail({\n ...options,\n immediate: true\n });\n\n // Update visitor ID when fingerprint changes\n useEffect(() => {\n if (fingerprint?.visitorId) {\n const storedVisitorId = localStorage.getItem(storageKey);\n \n if (storedVisitorId) {\n setIsReturningVisitor(storedVisitorId === fingerprint.visitorId);\n } else {\n setIsReturningVisitor(false);\n }\n \n setVisitorId(fingerprint.visitorId);\n localStorage.setItem(storageKey, fingerprint.visitorId);\n }\n }, [fingerprint?.visitorId, storageKey]);\n\n const refresh = useCallback(async () => {\n await generate();\n }, [generate]);\n\n return {\n visitorId,\n isReturningVisitor,\n loading,\n error,\n refresh\n };\n}\n\n/**\n * React hook for fraud detection with configurable thresholds\n * \n * @example\n * ```typescript\n * import { useFraudDetection } from '@tracetail/react';\n * \n * function SecurityCheck() {\n * const { isFraudulent, riskLevel, loading } = useFraudDetection({\n * apiKey: 'your-api-key',\n * riskThreshold: 0.7,\n * botThreshold: 0.5\n * });\n * \n * if (isFraudulent) {\n * return <div>⚠️ High risk detected - additional verification required</div>;\n * }\n * \n * return <div>✅ Security check passed (Risk: {riskLevel})</div>;\n * }\n * ```\n */\nexport function useFraudDetection(options: UseTraceTailOptions & {\n riskThreshold?: number;\n botThreshold?: number;\n}): {\n isFraudulent: boolean;\n riskLevel: 'low' | 'medium' | 'high' | null;\n riskScore: number;\n botProbability: number;\n fraudSignals: string[];\n loading: boolean;\n error: Error | null;\n recheck: () => Promise<void>;\n} {\n const riskThreshold = options.riskThreshold || 0.7;\n const botThreshold = options.botThreshold || 0.5;\n \n const { fingerprint, loading, error, generate } = useEnhancedTraceTail({\n ...options,\n immediate: true\n });\n\n const isFraudulent = fingerprint ? \n fingerprint.riskScore > riskThreshold || fingerprint.botProbability > botThreshold : \n false;\n\n const recheck = useCallback(async () => {\n await generate();\n }, [generate]);\n\n return {\n isFraudulent,\n riskLevel: fingerprint?.threatLevel || null,\n riskScore: fingerprint?.riskScore || 0,\n botProbability: fingerprint?.botProbability || 0,\n fraudSignals: fingerprint?.fraudSignals || [],\n loading,\n error,\n recheck\n };\n}\n\n// Re-export types and utilities from the base package\nexport type {\n FingerprintOptions,\n FingerprintResult,\n EnhancedFingerprintResult,\n ComponentData\n} from '@tracetail/js';\n\nexport { TraceTail } from '@tracetail/js';\n\n// React-specific utilities\ninterface TraceTailProviderProps {\n children: ReactNode;\n apiKey: string;\n options?: Partial<FingerprintOptions>;\n}\n\nexport const TraceTailProvider: FC<TraceTailProviderProps> = ({ children }) => {\n // This is a simple provider that could be extended with context\n // For now, it just renders children since hooks manage their own instances\n return <>{children}</>;\n};\n\n/**\n * Get the current React package version\n */\nexport const getVersion = (): string => '2.3.1';\n\n// Default export\nexport default {\n useTraceTail,\n useEnhancedTraceTail,\n useVisitorId,\n useFraudDetection,\n TraceTailProvider,\n getVersion\n};"],"names":["_jsx","_Fragment"],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var react = require('react');
|
|
7
|
+
var js = require('@tracetail/js');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* React hook for basic browser fingerprinting
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { useTraceTail } from '@tracetail/react';
|
|
15
|
+
*
|
|
16
|
+
* function MyComponent() {
|
|
17
|
+
* const { fingerprint, loading, error } = useTraceTail({
|
|
18
|
+
* apiKey: 'your-api-key',
|
|
19
|
+
* immediate: true
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* if (loading) return <div>Generating fingerprint...</div>;
|
|
23
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
24
|
+
*
|
|
25
|
+
* return <div>Visitor ID: {fingerprint?.visitorId}</div>;
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function useTraceTail(options) {
|
|
30
|
+
const [fingerprint, setFingerprint] = react.useState(null);
|
|
31
|
+
const [loading, setLoading] = react.useState(false);
|
|
32
|
+
const [error, setError] = react.useState(null);
|
|
33
|
+
const traceTailRef = react.useRef(null);
|
|
34
|
+
// Initialize TraceTail instance
|
|
35
|
+
react.useEffect(() => {
|
|
36
|
+
if (!traceTailRef.current) {
|
|
37
|
+
traceTailRef.current = new js.TraceTail(options);
|
|
38
|
+
}
|
|
39
|
+
}, [options.apiKey, options.endpoint]);
|
|
40
|
+
const generate = react.useCallback(async () => {
|
|
41
|
+
if (!traceTailRef.current) {
|
|
42
|
+
throw new Error('TraceTail not initialized');
|
|
43
|
+
}
|
|
44
|
+
setLoading(true);
|
|
45
|
+
setError(null);
|
|
46
|
+
try {
|
|
47
|
+
const result = await traceTailRef.current.generateFingerprint({
|
|
48
|
+
includeComponents: true
|
|
49
|
+
});
|
|
50
|
+
setFingerprint(result);
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
const error = err instanceof Error ? err : new Error('Unknown error');
|
|
55
|
+
setError(error);
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
setLoading(false);
|
|
60
|
+
}
|
|
61
|
+
}, []);
|
|
62
|
+
const regenerate = react.useCallback(async () => {
|
|
63
|
+
setFingerprint(null);
|
|
64
|
+
return generate();
|
|
65
|
+
}, [generate]);
|
|
66
|
+
// Auto-generate on mount if immediate is true
|
|
67
|
+
react.useEffect(() => {
|
|
68
|
+
if (options.immediate && !fingerprint && !loading) {
|
|
69
|
+
generate().catch(() => {
|
|
70
|
+
// Error is already handled in generate function
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}, [options.immediate, fingerprint, loading, generate]);
|
|
74
|
+
return {
|
|
75
|
+
fingerprint,
|
|
76
|
+
loading,
|
|
77
|
+
error,
|
|
78
|
+
generate,
|
|
79
|
+
regenerate
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* React hook for enhanced browser fingerprinting with fraud detection
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* import { useEnhancedTraceTail } from '@tracetail/react';
|
|
88
|
+
*
|
|
89
|
+
* function SecurityComponent() {
|
|
90
|
+
* const { fingerprint, loading, error } = useEnhancedTraceTail({
|
|
91
|
+
* apiKey: 'your-api-key',
|
|
92
|
+
* immediate: true
|
|
93
|
+
* });
|
|
94
|
+
*
|
|
95
|
+
* if (loading) return <div>Analyzing security...</div>;
|
|
96
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
97
|
+
*
|
|
98
|
+
* const riskLevel = fingerprint?.threatLevel || 'unknown';
|
|
99
|
+
* return (
|
|
100
|
+
* <div>
|
|
101
|
+
* <p>Risk Level: {riskLevel}</p>
|
|
102
|
+
* <p>Bot Probability: {(fingerprint?.botProbability * 100).toFixed(1)}%</p>
|
|
103
|
+
* </div>
|
|
104
|
+
* );
|
|
105
|
+
* }
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
function useEnhancedTraceTail(options) {
|
|
109
|
+
const [fingerprint, setFingerprint] = react.useState(null);
|
|
110
|
+
const [loading, setLoading] = react.useState(false);
|
|
111
|
+
const [error, setError] = react.useState(null);
|
|
112
|
+
const traceTailRef = react.useRef(null);
|
|
113
|
+
// Initialize TraceTail instance
|
|
114
|
+
react.useEffect(() => {
|
|
115
|
+
if (!traceTailRef.current) {
|
|
116
|
+
traceTailRef.current = new js.TraceTail(options);
|
|
117
|
+
}
|
|
118
|
+
}, [options.apiKey, options.endpoint]);
|
|
119
|
+
const generate = react.useCallback(async () => {
|
|
120
|
+
if (!traceTailRef.current) {
|
|
121
|
+
throw new Error('TraceTail not initialized');
|
|
122
|
+
}
|
|
123
|
+
setLoading(true);
|
|
124
|
+
setError(null);
|
|
125
|
+
try {
|
|
126
|
+
const result = await traceTailRef.current.generateEnhancedFingerprint({
|
|
127
|
+
includeComponents: true,
|
|
128
|
+
fraudDetection: true
|
|
129
|
+
});
|
|
130
|
+
setFingerprint(result);
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
const error = err instanceof Error ? err : new Error('Unknown error');
|
|
135
|
+
setError(error);
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
setLoading(false);
|
|
140
|
+
}
|
|
141
|
+
}, []);
|
|
142
|
+
const regenerate = react.useCallback(async () => {
|
|
143
|
+
setFingerprint(null);
|
|
144
|
+
return generate();
|
|
145
|
+
}, [generate]);
|
|
146
|
+
// Auto-generate on mount if immediate is true
|
|
147
|
+
react.useEffect(() => {
|
|
148
|
+
if (options.immediate && !fingerprint && !loading) {
|
|
149
|
+
generate().catch(() => {
|
|
150
|
+
// Error is already handled in generate function
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}, [options.immediate, fingerprint, loading, generate]);
|
|
154
|
+
return {
|
|
155
|
+
fingerprint,
|
|
156
|
+
loading,
|
|
157
|
+
error,
|
|
158
|
+
generate,
|
|
159
|
+
regenerate
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* React hook for visitor identification with persistent storage
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* import { useVisitorId } from '@tracetail/react';
|
|
168
|
+
*
|
|
169
|
+
* function UserTrackingComponent() {
|
|
170
|
+
* const { visitorId, isReturningVisitor, loading } = useVisitorId({
|
|
171
|
+
* apiKey: 'your-api-key',
|
|
172
|
+
* storageKey: 'app_visitor_id'
|
|
173
|
+
* });
|
|
174
|
+
*
|
|
175
|
+
* return (
|
|
176
|
+
* <div>
|
|
177
|
+
* <p>Visitor: {visitorId}</p>
|
|
178
|
+
* <p>Status: {isReturningVisitor ? 'Returning' : 'New'} visitor</p>
|
|
179
|
+
* </div>
|
|
180
|
+
* );
|
|
181
|
+
* }
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
function useVisitorId(options) {
|
|
185
|
+
const storageKey = options.storageKey || 'tracetail_visitor_id';
|
|
186
|
+
const [visitorId, setVisitorId] = react.useState(null);
|
|
187
|
+
const [isReturningVisitor, setIsReturningVisitor] = react.useState(false);
|
|
188
|
+
const { fingerprint, loading, error, generate } = useTraceTail({
|
|
189
|
+
...options,
|
|
190
|
+
immediate: true
|
|
191
|
+
});
|
|
192
|
+
// Update visitor ID when fingerprint changes
|
|
193
|
+
react.useEffect(() => {
|
|
194
|
+
if (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.visitorId) {
|
|
195
|
+
const storedVisitorId = localStorage.getItem(storageKey);
|
|
196
|
+
if (storedVisitorId) {
|
|
197
|
+
setIsReturningVisitor(storedVisitorId === fingerprint.visitorId);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
setIsReturningVisitor(false);
|
|
201
|
+
}
|
|
202
|
+
setVisitorId(fingerprint.visitorId);
|
|
203
|
+
localStorage.setItem(storageKey, fingerprint.visitorId);
|
|
204
|
+
}
|
|
205
|
+
}, [fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.visitorId, storageKey]);
|
|
206
|
+
const refresh = react.useCallback(async () => {
|
|
207
|
+
await generate();
|
|
208
|
+
}, [generate]);
|
|
209
|
+
return {
|
|
210
|
+
visitorId,
|
|
211
|
+
isReturningVisitor,
|
|
212
|
+
loading,
|
|
213
|
+
error,
|
|
214
|
+
refresh
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* React hook for fraud detection with configurable thresholds
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```typescript
|
|
222
|
+
* import { useFraudDetection } from '@tracetail/react';
|
|
223
|
+
*
|
|
224
|
+
* function SecurityCheck() {
|
|
225
|
+
* const { isFraudulent, riskLevel, loading } = useFraudDetection({
|
|
226
|
+
* apiKey: 'your-api-key',
|
|
227
|
+
* riskThreshold: 0.7,
|
|
228
|
+
* botThreshold: 0.5
|
|
229
|
+
* });
|
|
230
|
+
*
|
|
231
|
+
* if (isFraudulent) {
|
|
232
|
+
* return <div>⚠️ High risk detected - additional verification required</div>;
|
|
233
|
+
* }
|
|
234
|
+
*
|
|
235
|
+
* return <div>✅ Security check passed (Risk: {riskLevel})</div>;
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
function useFraudDetection(options) {
|
|
240
|
+
const riskThreshold = options.riskThreshold || 0.7;
|
|
241
|
+
const botThreshold = options.botThreshold || 0.5;
|
|
242
|
+
const { fingerprint, loading, error, generate } = useEnhancedTraceTail({
|
|
243
|
+
...options,
|
|
244
|
+
immediate: true
|
|
245
|
+
});
|
|
246
|
+
const isFraudulent = fingerprint ?
|
|
247
|
+
fingerprint.riskScore > riskThreshold || fingerprint.botProbability > botThreshold :
|
|
248
|
+
false;
|
|
249
|
+
const recheck = react.useCallback(async () => {
|
|
250
|
+
await generate();
|
|
251
|
+
}, [generate]);
|
|
252
|
+
return {
|
|
253
|
+
isFraudulent,
|
|
254
|
+
riskLevel: (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.threatLevel) || null,
|
|
255
|
+
riskScore: (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.riskScore) || 0,
|
|
256
|
+
botProbability: (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.botProbability) || 0,
|
|
257
|
+
fraudSignals: (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.fraudSignals) || [],
|
|
258
|
+
loading,
|
|
259
|
+
error,
|
|
260
|
+
recheck
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
const TraceTailProvider = ({ children }) => {
|
|
264
|
+
// This is a simple provider that could be extended with context
|
|
265
|
+
// For now, it just renders children since hooks manage their own instances
|
|
266
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: children });
|
|
267
|
+
};
|
|
268
|
+
/**
|
|
269
|
+
* Get the current React package version
|
|
270
|
+
*/
|
|
271
|
+
const getVersion = () => '2.3.1';
|
|
272
|
+
// Default export
|
|
273
|
+
var index = {
|
|
274
|
+
useTraceTail,
|
|
275
|
+
useEnhancedTraceTail,
|
|
276
|
+
useVisitorId,
|
|
277
|
+
useFraudDetection,
|
|
278
|
+
TraceTailProvider,
|
|
279
|
+
getVersion
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
Object.defineProperty(exports, "TraceTail", {
|
|
283
|
+
enumerable: true,
|
|
284
|
+
get: function () { return js.TraceTail; }
|
|
285
|
+
});
|
|
286
|
+
exports.TraceTailProvider = TraceTailProvider;
|
|
287
|
+
exports.default = index;
|
|
288
|
+
exports.getVersion = getVersion;
|
|
289
|
+
exports.useEnhancedTraceTail = useEnhancedTraceTail;
|
|
290
|
+
exports.useFraudDetection = useFraudDetection;
|
|
291
|
+
exports.useTraceTail = useTraceTail;
|
|
292
|
+
exports.useVisitorId = useVisitorId;
|
|
293
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.tsx"],"sourcesContent":["/**\n * @tracetail/react - React Hooks for Enterprise Browser Fingerprinting\n * Version: 2.3.1\n * \n * Over 99.5% accuracy browser fingerprinting with React hooks.\n * Perfect for fraud detection, user analytics, and security applications.\n */\n\nimport { useEffect, useState, useCallback, useRef } from 'react';\nimport type { FC, ReactNode } from 'react';\nimport { TraceTail, FingerprintOptions, FingerprintResult, EnhancedFingerprintResult } from '@tracetail/js';\n\nexport interface UseTraceTailOptions extends FingerprintOptions {\n immediate?: boolean;\n suspense?: boolean;\n}\n\nexport interface UseTraceTailReturn {\n fingerprint: FingerprintResult | null;\n loading: boolean;\n error: Error | null;\n generate: () => Promise<FingerprintResult>;\n regenerate: () => Promise<FingerprintResult>;\n}\n\nexport interface UseEnhancedTraceTailReturn {\n fingerprint: EnhancedFingerprintResult | null;\n loading: boolean;\n error: Error | null;\n generate: () => Promise<EnhancedFingerprintResult>;\n regenerate: () => Promise<EnhancedFingerprintResult>;\n}\n\n/**\n * React hook for basic browser fingerprinting\n * \n * @example\n * ```typescript\n * import { useTraceTail } from '@tracetail/react';\n * \n * function MyComponent() {\n * const { fingerprint, loading, error } = useTraceTail({\n * apiKey: 'your-api-key',\n * immediate: true\n * });\n * \n * if (loading) return <div>Generating fingerprint...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * \n * return <div>Visitor ID: {fingerprint?.visitorId}</div>;\n * }\n * ```\n */\nexport function useTraceTail(options: UseTraceTailOptions): UseTraceTailReturn {\n const [fingerprint, setFingerprint] = useState<FingerprintResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n \n const traceTailRef = useRef<TraceTail | null>(null);\n \n // Initialize TraceTail instance\n useEffect(() => {\n if (!traceTailRef.current) {\n traceTailRef.current = new TraceTail(options);\n }\n }, [options.apiKey, options.endpoint]);\n\n const generate = useCallback(async (): Promise<FingerprintResult> => {\n if (!traceTailRef.current) {\n throw new Error('TraceTail not initialized');\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await traceTailRef.current.generateFingerprint({\n includeComponents: true\n });\n setFingerprint(result);\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Unknown error');\n setError(error);\n throw error;\n } finally {\n setLoading(false);\n }\n }, []);\n\n const regenerate = useCallback(async (): Promise<FingerprintResult> => {\n setFingerprint(null);\n return generate();\n }, [generate]);\n\n // Auto-generate on mount if immediate is true\n useEffect(() => {\n if (options.immediate && !fingerprint && !loading) {\n generate().catch(() => {\n // Error is already handled in generate function\n });\n }\n }, [options.immediate, fingerprint, loading, generate]);\n\n return {\n fingerprint,\n loading,\n error,\n generate,\n regenerate\n };\n}\n\n/**\n * React hook for enhanced browser fingerprinting with fraud detection\n * \n * @example\n * ```typescript\n * import { useEnhancedTraceTail } from '@tracetail/react';\n * \n * function SecurityComponent() {\n * const { fingerprint, loading, error } = useEnhancedTraceTail({\n * apiKey: 'your-api-key',\n * immediate: true\n * });\n * \n * if (loading) return <div>Analyzing security...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * \n * const riskLevel = fingerprint?.threatLevel || 'unknown';\n * return (\n * <div>\n * <p>Risk Level: {riskLevel}</p>\n * <p>Bot Probability: {(fingerprint?.botProbability * 100).toFixed(1)}%</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useEnhancedTraceTail(options: UseTraceTailOptions): UseEnhancedTraceTailReturn {\n const [fingerprint, setFingerprint] = useState<EnhancedFingerprintResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n \n const traceTailRef = useRef<TraceTail | null>(null);\n \n // Initialize TraceTail instance\n useEffect(() => {\n if (!traceTailRef.current) {\n traceTailRef.current = new TraceTail(options);\n }\n }, [options.apiKey, options.endpoint]);\n\n const generate = useCallback(async (): Promise<EnhancedFingerprintResult> => {\n if (!traceTailRef.current) {\n throw new Error('TraceTail not initialized');\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await traceTailRef.current.generateEnhancedFingerprint({\n includeComponents: true,\n fraudDetection: true\n });\n setFingerprint(result);\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Unknown error');\n setError(error);\n throw error;\n } finally {\n setLoading(false);\n }\n }, []);\n\n const regenerate = useCallback(async (): Promise<EnhancedFingerprintResult> => {\n setFingerprint(null);\n return generate();\n }, [generate]);\n\n // Auto-generate on mount if immediate is true\n useEffect(() => {\n if (options.immediate && !fingerprint && !loading) {\n generate().catch(() => {\n // Error is already handled in generate function\n });\n }\n }, [options.immediate, fingerprint, loading, generate]);\n\n return {\n fingerprint,\n loading,\n error,\n generate,\n regenerate\n };\n}\n\n/**\n * React hook for visitor identification with persistent storage\n * \n * @example\n * ```typescript\n * import { useVisitorId } from '@tracetail/react';\n * \n * function UserTrackingComponent() {\n * const { visitorId, isReturningVisitor, loading } = useVisitorId({\n * apiKey: 'your-api-key',\n * storageKey: 'app_visitor_id'\n * });\n * \n * return (\n * <div>\n * <p>Visitor: {visitorId}</p>\n * <p>Status: {isReturningVisitor ? 'Returning' : 'New'} visitor</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useVisitorId(options: UseTraceTailOptions & {\n storageKey?: string;\n}): {\n visitorId: string | null;\n isReturningVisitor: boolean;\n loading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n} {\n const storageKey = options.storageKey || 'tracetail_visitor_id';\n const [visitorId, setVisitorId] = useState<string | null>(null);\n const [isReturningVisitor, setIsReturningVisitor] = useState(false);\n \n const { fingerprint, loading, error, generate } = useTraceTail({\n ...options,\n immediate: true\n });\n\n // Update visitor ID when fingerprint changes\n useEffect(() => {\n if (fingerprint?.visitorId) {\n const storedVisitorId = localStorage.getItem(storageKey);\n \n if (storedVisitorId) {\n setIsReturningVisitor(storedVisitorId === fingerprint.visitorId);\n } else {\n setIsReturningVisitor(false);\n }\n \n setVisitorId(fingerprint.visitorId);\n localStorage.setItem(storageKey, fingerprint.visitorId);\n }\n }, [fingerprint?.visitorId, storageKey]);\n\n const refresh = useCallback(async () => {\n await generate();\n }, [generate]);\n\n return {\n visitorId,\n isReturningVisitor,\n loading,\n error,\n refresh\n };\n}\n\n/**\n * React hook for fraud detection with configurable thresholds\n * \n * @example\n * ```typescript\n * import { useFraudDetection } from '@tracetail/react';\n * \n * function SecurityCheck() {\n * const { isFraudulent, riskLevel, loading } = useFraudDetection({\n * apiKey: 'your-api-key',\n * riskThreshold: 0.7,\n * botThreshold: 0.5\n * });\n * \n * if (isFraudulent) {\n * return <div>⚠️ High risk detected - additional verification required</div>;\n * }\n * \n * return <div>✅ Security check passed (Risk: {riskLevel})</div>;\n * }\n * ```\n */\nexport function useFraudDetection(options: UseTraceTailOptions & {\n riskThreshold?: number;\n botThreshold?: number;\n}): {\n isFraudulent: boolean;\n riskLevel: 'low' | 'medium' | 'high' | null;\n riskScore: number;\n botProbability: number;\n fraudSignals: string[];\n loading: boolean;\n error: Error | null;\n recheck: () => Promise<void>;\n} {\n const riskThreshold = options.riskThreshold || 0.7;\n const botThreshold = options.botThreshold || 0.5;\n \n const { fingerprint, loading, error, generate } = useEnhancedTraceTail({\n ...options,\n immediate: true\n });\n\n const isFraudulent = fingerprint ? \n fingerprint.riskScore > riskThreshold || fingerprint.botProbability > botThreshold : \n false;\n\n const recheck = useCallback(async () => {\n await generate();\n }, [generate]);\n\n return {\n isFraudulent,\n riskLevel: fingerprint?.threatLevel || null,\n riskScore: fingerprint?.riskScore || 0,\n botProbability: fingerprint?.botProbability || 0,\n fraudSignals: fingerprint?.fraudSignals || [],\n loading,\n error,\n recheck\n };\n}\n\n// Re-export types and utilities from the base package\nexport type {\n FingerprintOptions,\n FingerprintResult,\n EnhancedFingerprintResult,\n ComponentData\n} from '@tracetail/js';\n\nexport { TraceTail } from '@tracetail/js';\n\n// React-specific utilities\ninterface TraceTailProviderProps {\n children: ReactNode;\n apiKey: string;\n options?: Partial<FingerprintOptions>;\n}\n\nexport const TraceTailProvider: FC<TraceTailProviderProps> = ({ children }) => {\n // This is a simple provider that could be extended with context\n // For now, it just renders children since hooks manage their own instances\n return <>{children}</>;\n};\n\n/**\n * Get the current React package version\n */\nexport const getVersion = (): string => '2.3.1';\n\n// Default export\nexport default {\n useTraceTail,\n useEnhancedTraceTail,\n useVisitorId,\n useFraudDetection,\n TraceTailProvider,\n getVersion\n};"],"names":["useState","useRef","useEffect","TraceTail","useCallback","_jsx","_Fragment"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tracetail/react",
|
|
3
|
+
"version": "2.3.1",
|
|
4
|
+
"description": "React hooks for TraceTail enterprise browser fingerprinting with over 99.5% accuracy. TypeScript support and React 18 compatibility.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"keywords": [
|
|
13
|
+
"react",
|
|
14
|
+
"hooks",
|
|
15
|
+
"fingerprinting",
|
|
16
|
+
"browser",
|
|
17
|
+
"fraud-detection",
|
|
18
|
+
"security",
|
|
19
|
+
"authentication",
|
|
20
|
+
"device-identification",
|
|
21
|
+
"privacy",
|
|
22
|
+
"enterprise",
|
|
23
|
+
"typescript"
|
|
24
|
+
],
|
|
25
|
+
"author": "TraceTail",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"homepage": "https://tracetail.io",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/sirrodgepodge/TraceTail.git",
|
|
31
|
+
"directory": "packages/react"
|
|
32
|
+
},
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/sirrodgepodge/TraceTail/issues"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=14"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "rollup -c",
|
|
41
|
+
"dev": "rollup -c -w",
|
|
42
|
+
"test": "jest",
|
|
43
|
+
"prepublishOnly": "npm run build"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"react": ">=16.8.0"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@tracetail/js": "^2.3.1"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
|
53
|
+
"@types/jest": "^29.5.11",
|
|
54
|
+
"@types/react": "^18.3.11",
|
|
55
|
+
"jest": "^29.7.0",
|
|
56
|
+
"react": "^18.3.1",
|
|
57
|
+
"rollup": "^4.9.6",
|
|
58
|
+
"typescript": "^5.3.3"
|
|
59
|
+
}
|
|
60
|
+
}
|