@truxl/javascript-sdk 1.0.0
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 +491 -0
- package/dist/core/client.d.ts +21 -0
- package/dist/core/config.d.ts +40 -0
- package/dist/core/queue.d.ts +30 -0
- package/dist/identity/device.d.ts +28 -0
- package/dist/identity/identity.d.ts +48 -0
- package/dist/index.d.ts +6 -0
- package/dist/security/hmac.d.ts +1 -0
- package/dist/tracking/autocapture.d.ts +25 -0
- package/dist/tracking/events.d.ts +27 -0
- package/dist/tracking/forms.d.ts +20 -0
- package/dist/transport/beacon.d.ts +38 -0
- package/dist/transport/http.d.ts +42 -0
- package/dist/transport/transport.d.ts +9 -0
- package/dist/transport/websocket.d.ts +19 -0
- package/dist/truxl.esm.js +1409 -0
- package/dist/truxl.esm.js.map +1 -0
- package/dist/truxl.umd.js +2 -0
- package/dist/truxl.umd.js.map +1 -0
- package/dist/utils/browser.d.ts +80 -0
- package/dist/utils/geo.d.ts +18 -0
- package/dist/utils/referrer.d.ts +26 -0
- package/dist/utils/storage.d.ts +22 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
# Truxl JavaScript SDK
|
|
2
|
+
|
|
3
|
+
Lightweight browser analytics SDK for [Truxl](https://truxl.com) — track user events, identify users, and capture behavioral data with zero dependencies.
|
|
4
|
+
|
|
5
|
+
- **~8 KB** minified (UMD)
|
|
6
|
+
- Automatic page view tracking
|
|
7
|
+
- Optional autocapture (clicks, scroll, forms, rage clicks, dead clicks)
|
|
8
|
+
- Event batching with retry
|
|
9
|
+
- HMAC-SHA256 request signing
|
|
10
|
+
- TypeScript support
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
### Option 1: Script Tag (CDN)
|
|
17
|
+
|
|
18
|
+
Add this to your HTML `<head>`:
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<script src="https://sdk.truxl.com/javascript/truxl-0.1.0.umd.js"></script>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Then initialize:
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<script>
|
|
28
|
+
var truxl = new window.truxl.TruxlClient({
|
|
29
|
+
projectToken: 'YOUR_PROJECT_TOKEN',
|
|
30
|
+
clientSecret: 'YOUR_CLIENT_SECRET',
|
|
31
|
+
apiEndpoint: 'https://ingestion.api.truxl.com',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Track an event
|
|
35
|
+
truxl.track('page_view', { page: '/home' });
|
|
36
|
+
</script>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Option 2: npm
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install @truxl/javascript-sdk
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
import { TruxlClient } from '@truxl/javascript-sdk';
|
|
47
|
+
|
|
48
|
+
const truxl = new TruxlClient({
|
|
49
|
+
projectToken: 'YOUR_PROJECT_TOKEN',
|
|
50
|
+
clientSecret: 'YOUR_CLIENT_SECRET',
|
|
51
|
+
apiEndpoint: 'https://ingestion.api.truxl.com',
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Getting Your Credentials
|
|
58
|
+
|
|
59
|
+
1. Log in to the **Truxl Client Console** (http://localhost:3000)
|
|
60
|
+
2. Go to **Settings > Project Keys**
|
|
61
|
+
3. Copy the **Project Token** and **Client Secret**
|
|
62
|
+
|
|
63
|
+
| Credential | Example | Where to find |
|
|
64
|
+
|-----------|---------|---------------|
|
|
65
|
+
| Project Token | `trxl_proj_demo_123` | Settings > Project Keys |
|
|
66
|
+
| Client Secret | `demo-secret-key-256bit-...` | Settings > Project Keys |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Configuration
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
const truxl = new TruxlClient({
|
|
74
|
+
// Required
|
|
75
|
+
projectToken: 'YOUR_PROJECT_TOKEN',
|
|
76
|
+
clientSecret: 'YOUR_CLIENT_SECRET',
|
|
77
|
+
|
|
78
|
+
// Optional
|
|
79
|
+
apiEndpoint: 'https://ingestion.api.truxl.com', // Default: https://ingestion.api.stage.truxl.com
|
|
80
|
+
batchSize: 20, // Events per batch before auto-flush (default: 20)
|
|
81
|
+
flushInterval: 5000, // Auto-flush interval in ms (default: 5000)
|
|
82
|
+
maxQueueSize: 10000, // Max queued events (default: 10000)
|
|
83
|
+
retryAttempts: 5, // Retry attempts for failed requests (default: 5)
|
|
84
|
+
retryBaseDelay: 1000, // Base delay between retries in ms (default: 1000)
|
|
85
|
+
transport: 'http', // 'http' or 'websocket' (default: 'http')
|
|
86
|
+
track_pageview: true, // Auto-track page views (default: true)
|
|
87
|
+
autocapture: false, // Enable autocapture (default: false)
|
|
88
|
+
debug: false, // Log to console (default: false)
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### All Options
|
|
93
|
+
|
|
94
|
+
| Option | Type | Default | Description |
|
|
95
|
+
|--------|------|---------|-------------|
|
|
96
|
+
| `projectToken` | `string` | **required** | Project token from Client Console |
|
|
97
|
+
| `clientSecret` | `string` | **required** | Client secret for HMAC request signing |
|
|
98
|
+
| `apiEndpoint` | `string` | `https://ingestion.api.stage.truxl.com` | Ingestion Service URL |
|
|
99
|
+
| `batchSize` | `number` | `20` | Events per batch before auto-flush |
|
|
100
|
+
| `flushInterval` | `number` | `5000` | Auto-flush interval in milliseconds |
|
|
101
|
+
| `maxQueueSize` | `number` | `10000` | Max events in queue (oldest dropped when full) |
|
|
102
|
+
| `retryAttempts` | `number` | `5` | Max retries for transient failures |
|
|
103
|
+
| `retryBaseDelay` | `number` | `1000` | Base delay (ms) between retries |
|
|
104
|
+
| `transport` | `'http'` \| `'websocket'` | `'http'` | Transport protocol |
|
|
105
|
+
| `track_pageview` | `boolean` | `true` | Automatically track page views on load and URL changes |
|
|
106
|
+
| `autocapture` | `boolean` \| `AutocaptureConfig` | `false` | Enable automatic event capture |
|
|
107
|
+
| `debug` | `boolean` | `false` | Log events and config to console |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Core API
|
|
112
|
+
|
|
113
|
+
### `track(eventName, properties?)`
|
|
114
|
+
|
|
115
|
+
Track a custom event with optional properties.
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
// Simple event
|
|
119
|
+
truxl.track('button_click');
|
|
120
|
+
|
|
121
|
+
// Event with properties
|
|
122
|
+
truxl.track('add_to_cart', {
|
|
123
|
+
product_id: 'sku-42',
|
|
124
|
+
product_name: 'Running Shoes',
|
|
125
|
+
price: 129.99,
|
|
126
|
+
quantity: 1,
|
|
127
|
+
category: 'footwear',
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Page-specific event
|
|
131
|
+
truxl.track('search', {
|
|
132
|
+
query: 'running shoes',
|
|
133
|
+
result_count: 24,
|
|
134
|
+
page: '/search',
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### `identify(distinctId, userProperties?)`
|
|
139
|
+
|
|
140
|
+
Link events to a known user. Call after login or signup. All subsequent events are associated with this user.
|
|
141
|
+
|
|
142
|
+
```javascript
|
|
143
|
+
// After login
|
|
144
|
+
truxl.identify('user-123', {
|
|
145
|
+
email: 'john@example.com',
|
|
146
|
+
name: 'John Doe',
|
|
147
|
+
plan: 'pro',
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Minimal identify
|
|
151
|
+
truxl.identify('user-123');
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### `reset()`
|
|
155
|
+
|
|
156
|
+
Clear the user identity. Call on logout. Events after reset are tracked anonymously (device-level).
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
// On logout
|
|
160
|
+
truxl.reset();
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### `flush()`
|
|
164
|
+
|
|
165
|
+
Force-send all queued events immediately. Useful before navigation or page unload.
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
truxl.flush();
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### `destroy()`
|
|
172
|
+
|
|
173
|
+
Tear down the SDK — stops autocapture, clears timers, closes transport.
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
truxl.destroy();
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Autocapture
|
|
182
|
+
|
|
183
|
+
Enable automatic event capture for clicks, scroll depth, form submissions, and more — no manual instrumentation required.
|
|
184
|
+
|
|
185
|
+
### Enable All Autocapture
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
const truxl = new TruxlClient({
|
|
189
|
+
projectToken: 'YOUR_TOKEN',
|
|
190
|
+
clientSecret: 'YOUR_SECRET',
|
|
191
|
+
autocapture: true, // Enable all autocapture features
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Customize Autocapture
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
const truxl = new TruxlClient({
|
|
199
|
+
projectToken: 'YOUR_TOKEN',
|
|
200
|
+
clientSecret: 'YOUR_SECRET',
|
|
201
|
+
autocapture: {
|
|
202
|
+
pageview: 'full-url', // 'full-url' | 'path-only' | false
|
|
203
|
+
click: true, // Track button/link clicks
|
|
204
|
+
dead_click: true, // Track clicks with no DOM change
|
|
205
|
+
rage_click: true, // Track rapid repeated clicks (3+ in 1s)
|
|
206
|
+
input: true, // Track input field changes (sensitive fields redacted)
|
|
207
|
+
scroll: true, // Track scroll depth (25%, 50%, 75%, 100%)
|
|
208
|
+
submit: true, // Track form submissions
|
|
209
|
+
capture_text_content: false, // Capture element text (default: false for privacy)
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Autocapture Events
|
|
215
|
+
|
|
216
|
+
| Event | Trigger | Key Properties |
|
|
217
|
+
|-------|---------|----------------|
|
|
218
|
+
| `$pageview` | Page load, URL change (pushState/popState) | `$url`, `$path`, `$referrer`, `$title` |
|
|
219
|
+
| `$autocapture_click` | Click on `<a>`, `<button>`, or `role="button"` | `$element_tag`, `$element_id`, `$element_classes` |
|
|
220
|
+
| `$dead_click` | Click with no DOM mutation within 1 second | `$element_tag`, `$element_id` |
|
|
221
|
+
| `$rage_click` | 3+ clicks on same element within 1 second | `$element_tag`, `$click_count` |
|
|
222
|
+
| `$autocapture_input` | Input field value change | `$element_tag`, `$element_type`, `$value_redacted` |
|
|
223
|
+
| `$autocapture_scroll` | Scroll milestone reached | `$scroll_depth` (25/50/75/100) |
|
|
224
|
+
| `$form_submit` | Form submission | `$form_id`, `$form_action`, `$form_fields` |
|
|
225
|
+
|
|
226
|
+
### Privacy
|
|
227
|
+
|
|
228
|
+
- **Sensitive fields are automatically redacted** — passwords, credit cards, SSN, tokens, and hidden fields are never captured
|
|
229
|
+
- **Text content is off by default** — set `capture_text_content: true` to opt in
|
|
230
|
+
- **Input values**: only the value length is captured when `capture_text_content` is false
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Auto-Captured Fields
|
|
235
|
+
|
|
236
|
+
Every event automatically includes these fields — no manual setup required:
|
|
237
|
+
|
|
238
|
+
### Client-Side (captured by SDK)
|
|
239
|
+
|
|
240
|
+
| Field | Source | Example |
|
|
241
|
+
|-------|--------|---------|
|
|
242
|
+
| `eventName` | `track()` argument | `add_to_cart` |
|
|
243
|
+
| `distinctId` | `identify()` or `deviceId` | `user-123` |
|
|
244
|
+
| `deviceId` | Auto-generated UUID (localStorage) | `a1b2c3d4-...` |
|
|
245
|
+
| `sessionId` | Auto-generated UUID (sessionStorage) | `e5f6g7h8-...` |
|
|
246
|
+
| `timestamp` | `Date.now()` | `1710000000000` |
|
|
247
|
+
| `browser` | User-Agent parsing | `Chrome` |
|
|
248
|
+
| `browserVersion` | User-Agent parsing | `122.0` |
|
|
249
|
+
| `os` | User-Agent parsing | `macOS` |
|
|
250
|
+
| `osVersion` | User-Agent parsing | `14.3` |
|
|
251
|
+
| `deviceType` | User-Agent parsing | `desktop` |
|
|
252
|
+
| `screenWidth` | `screen.width` | `1920` |
|
|
253
|
+
| `screenHeight` | `screen.height` | `1080` |
|
|
254
|
+
| `referrer` | `document.referrer` | `https://google.com` |
|
|
255
|
+
| `initialReferrer` | First referrer in session | `https://google.com` |
|
|
256
|
+
| `searchEngine` | Parsed from referrer | `google` |
|
|
257
|
+
| `userTimezone` | `Intl.DateTimeFormat` | `Asia/Kolkata` |
|
|
258
|
+
| `utmSource` | URL query param | `google` |
|
|
259
|
+
| `utmMedium` | URL query param | `cpc` |
|
|
260
|
+
| `utmCampaign` | URL query param | `spring_sale` |
|
|
261
|
+
| `sdkVersion` | Hardcoded | `0.1.0` |
|
|
262
|
+
|
|
263
|
+
### Server-Side (enriched by Ingestion Service)
|
|
264
|
+
|
|
265
|
+
| Field | Source | Example |
|
|
266
|
+
|-------|--------|---------|
|
|
267
|
+
| `country` | GeoIP lookup | `India` |
|
|
268
|
+
| `city` | GeoIP lookup | `Mumbai` |
|
|
269
|
+
| `region` | GeoIP lookup | `Maharashtra` |
|
|
270
|
+
| `postalCode` | GeoIP lookup | `400001` |
|
|
271
|
+
| `environment` | Project key config | `production` |
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Common Integration Patterns
|
|
276
|
+
|
|
277
|
+
### E-Commerce
|
|
278
|
+
|
|
279
|
+
```javascript
|
|
280
|
+
// Product view
|
|
281
|
+
truxl.track('product_view', {
|
|
282
|
+
product_id: 'sku-42',
|
|
283
|
+
product_name: 'Running Shoes',
|
|
284
|
+
price: 129.99,
|
|
285
|
+
category: 'footwear',
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// Add to cart
|
|
289
|
+
truxl.track('add_to_cart', {
|
|
290
|
+
product_id: 'sku-42',
|
|
291
|
+
product_name: 'Running Shoes',
|
|
292
|
+
price: 129.99,
|
|
293
|
+
quantity: 1,
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// Remove from cart
|
|
297
|
+
truxl.track('remove_from_cart', {
|
|
298
|
+
product_id: 'sku-42',
|
|
299
|
+
product_name: 'Running Shoes',
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// Checkout
|
|
303
|
+
truxl.track('checkout', {
|
|
304
|
+
order_id: 'ord-12345',
|
|
305
|
+
total: 259.98,
|
|
306
|
+
item_count: 2,
|
|
307
|
+
currency: 'USD',
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Search
|
|
311
|
+
truxl.track('search', {
|
|
312
|
+
query: 'running shoes',
|
|
313
|
+
result_count: 24,
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### User Authentication
|
|
318
|
+
|
|
319
|
+
```javascript
|
|
320
|
+
// Signup
|
|
321
|
+
truxl.identify('user-456', { email: 'jane@example.com', name: 'Jane Doe' });
|
|
322
|
+
truxl.track('signup', { method: 'email' });
|
|
323
|
+
|
|
324
|
+
// Login
|
|
325
|
+
truxl.identify('user-456', { email: 'jane@example.com' });
|
|
326
|
+
truxl.track('login', { method: 'email' });
|
|
327
|
+
|
|
328
|
+
// Logout
|
|
329
|
+
truxl.track('logout');
|
|
330
|
+
truxl.reset(); // Clear identity — subsequent events are anonymous
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### SaaS / Feature Usage
|
|
334
|
+
|
|
335
|
+
```javascript
|
|
336
|
+
// Feature adoption
|
|
337
|
+
truxl.track('feature_used', {
|
|
338
|
+
feature: 'dark_mode',
|
|
339
|
+
action: 'enabled',
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Subscription change
|
|
343
|
+
truxl.track('plan_upgraded', {
|
|
344
|
+
from_plan: 'free',
|
|
345
|
+
to_plan: 'pro',
|
|
346
|
+
annual: true,
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Onboarding
|
|
350
|
+
truxl.track('onboarding_step', {
|
|
351
|
+
step: 3,
|
|
352
|
+
step_name: 'invite_team',
|
|
353
|
+
completed: true,
|
|
354
|
+
});
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Content / Media
|
|
358
|
+
|
|
359
|
+
```javascript
|
|
360
|
+
// Article read
|
|
361
|
+
truxl.track('article_read', {
|
|
362
|
+
article_id: 'post-789',
|
|
363
|
+
title: 'Getting Started with Truxl',
|
|
364
|
+
category: 'tutorial',
|
|
365
|
+
read_time_seconds: 180,
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// Video play
|
|
369
|
+
truxl.track('video_play', {
|
|
370
|
+
video_id: 'vid-001',
|
|
371
|
+
title: 'Product Demo',
|
|
372
|
+
duration_seconds: 120,
|
|
373
|
+
});
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## Data Attribute Tracking
|
|
379
|
+
|
|
380
|
+
Add `data-truxl-event` attributes to HTML elements for zero-code event naming with autocapture:
|
|
381
|
+
|
|
382
|
+
```html
|
|
383
|
+
<button data-truxl-event="cta_hero_click" class="btn-primary">
|
|
384
|
+
Get Started
|
|
385
|
+
</button>
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
When autocapture is enabled and this button is clicked, the `$custom_event_name` property will include `cta_hero_click`.
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## Security
|
|
393
|
+
|
|
394
|
+
All requests are signed with **HMAC-SHA256** using the Web Crypto API:
|
|
395
|
+
|
|
396
|
+
1. SDK serializes the event batch as JSON
|
|
397
|
+
2. Signs the payload with `clientSecret` using HMAC-SHA256
|
|
398
|
+
3. Sends the signature in the `X-Truxl-Signature` header
|
|
399
|
+
4. Ingestion Service verifies the signature server-side
|
|
400
|
+
|
|
401
|
+
The `clientSecret` is used only for signing — it is never sent to the server.
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## How It Works
|
|
406
|
+
|
|
407
|
+
```
|
|
408
|
+
Browser Ingestion Service Kafka ClickHouse
|
|
409
|
+
| | | |
|
|
410
|
+
|-- track('event') ---------> | | |
|
|
411
|
+
| (batched in queue) | | |
|
|
412
|
+
| | | |
|
|
413
|
+
|-- flush (batch of events) ->| | |
|
|
414
|
+
| + X-Project-Token |-- validate token ------> | |
|
|
415
|
+
| + X-Truxl-Signature |-- verify HMAC | |
|
|
416
|
+
| |-- check quota | |
|
|
417
|
+
| |-- enrich (UA, GeoIP) --> | |
|
|
418
|
+
| | |-- Kafka Connect>|
|
|
419
|
+
| | | |
|
|
420
|
+
|<-- 200 OK ------------------| | events table
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
1. `track()` queues events in memory
|
|
424
|
+
2. Events are flushed in batches (by `batchSize` or `flushInterval`)
|
|
425
|
+
3. Ingestion Service validates the project token, verifies HMAC signature, checks quota
|
|
426
|
+
4. Events are enriched (browser parsing, GeoIP) and published to Kafka
|
|
427
|
+
5. Kafka Connect sinks events into ClickHouse for analytics
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## Building from Source
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
cd truxl-javascript-sdk
|
|
435
|
+
npm install
|
|
436
|
+
npm run build
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
Output:
|
|
440
|
+
```
|
|
441
|
+
dist/
|
|
442
|
+
├── truxl.umd.js # UMD bundle (~8 KB minified) — for <script> tags
|
|
443
|
+
├── truxl.umd.js.map # Source map
|
|
444
|
+
├── truxl.esm.js # ES module — for bundlers (Vite, Webpack)
|
|
445
|
+
├── truxl.esm.js.map # Source map
|
|
446
|
+
└── index.d.ts # TypeScript declarations
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
## Publishing to S3
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
# First-time: create bucket
|
|
453
|
+
./truxl.sh sdk:setup
|
|
454
|
+
|
|
455
|
+
# Build + publish
|
|
456
|
+
./truxl.sh sdk:publish
|
|
457
|
+
|
|
458
|
+
# Specific version
|
|
459
|
+
./truxl.sh sdk:publish --version 1.0.0
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
S3 structure:
|
|
463
|
+
```
|
|
464
|
+
s3://truxl-sdk/javascript/truxl-0.1.0.umd.js # Versioned (immutable, 1-year cache)
|
|
465
|
+
s3://truxl-sdk/javascript/truxl-0.1.0.esm.js # ESM version for bundlers
|
|
466
|
+
s3://truxl-sdk/javascript/truxl-latest.umd.js # Latest (auto-updated, 5-min cache)
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
CDN URL (CloudFront + Route 53):
|
|
470
|
+
```
|
|
471
|
+
https://sdk.truxl.com/javascript/truxl-0.1.0.umd.js
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## Browser Support
|
|
477
|
+
|
|
478
|
+
| Browser | Version |
|
|
479
|
+
|---------|---------|
|
|
480
|
+
| Chrome | 63+ |
|
|
481
|
+
| Firefox | 57+ |
|
|
482
|
+
| Safari | 11.1+ |
|
|
483
|
+
| Edge | 79+ |
|
|
484
|
+
|
|
485
|
+
Requires: `crypto.subtle` (Web Crypto API), `localStorage`, `sessionStorage`, `fetch`.
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## License
|
|
490
|
+
|
|
491
|
+
MIT
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { TruxlConfig } from './config';
|
|
2
|
+
export declare class TruxlClient {
|
|
3
|
+
private config;
|
|
4
|
+
private queue;
|
|
5
|
+
private transport;
|
|
6
|
+
private distinctId;
|
|
7
|
+
private deviceId;
|
|
8
|
+
private initialReferrer;
|
|
9
|
+
constructor(config: TruxlConfig);
|
|
10
|
+
track(eventName: string, properties?: Record<string, unknown>): void;
|
|
11
|
+
identify(distinctId: string, userProperties?: Record<string, unknown>): void;
|
|
12
|
+
reset(): void;
|
|
13
|
+
flush(): void;
|
|
14
|
+
destroy(): void;
|
|
15
|
+
private pageviewTeardownFns;
|
|
16
|
+
private startPageviewTracking;
|
|
17
|
+
private stopPageviewTracking;
|
|
18
|
+
private loadDistinctId;
|
|
19
|
+
private getOrCreateDeviceId;
|
|
20
|
+
private getSessionId;
|
|
21
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface AutocaptureConfig {
|
|
2
|
+
/** Track page views. "full-url" captures full URL, "path-only" captures path without query params, false disables. */
|
|
3
|
+
pageview?: 'full-url' | 'path-only' | boolean;
|
|
4
|
+
/** Track clicks on buttons and links. */
|
|
5
|
+
click?: boolean;
|
|
6
|
+
/** Track clicks that produce no DOM mutation (dead clicks). */
|
|
7
|
+
dead_click?: boolean;
|
|
8
|
+
/** Track input field changes (values are redacted for sensitive fields). */
|
|
9
|
+
input?: boolean;
|
|
10
|
+
/** Track rapid repeated clicks on the same element (rage clicks). */
|
|
11
|
+
rage_click?: boolean;
|
|
12
|
+
/** Track scroll depth milestones. */
|
|
13
|
+
scroll?: boolean;
|
|
14
|
+
/** Track form submissions. */
|
|
15
|
+
submit?: boolean;
|
|
16
|
+
/** Capture text content of interacted elements. When false, text is omitted for privacy. */
|
|
17
|
+
capture_text_content?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface TruxlConfig {
|
|
20
|
+
projectToken: string;
|
|
21
|
+
clientSecret: string;
|
|
22
|
+
apiEndpoint?: string;
|
|
23
|
+
batchSize?: number;
|
|
24
|
+
flushInterval?: number;
|
|
25
|
+
/** Enable autocapture. Pass `true` for defaults, or an object to customize individual features. */
|
|
26
|
+
autocapture?: boolean | AutocaptureConfig;
|
|
27
|
+
/** Automatically track page views on load and URL changes. Independent of autocapture. */
|
|
28
|
+
track_pageview?: boolean;
|
|
29
|
+
debug?: boolean;
|
|
30
|
+
maxQueueSize?: number;
|
|
31
|
+
retryAttempts?: number;
|
|
32
|
+
retryBaseDelay?: number;
|
|
33
|
+
transport?: 'http' | 'websocket';
|
|
34
|
+
}
|
|
35
|
+
export declare const DEFAULT_AUTOCAPTURE_CONFIG: Required<AutocaptureConfig>;
|
|
36
|
+
export declare const DEFAULT_CONFIG: Required<Omit<TruxlConfig, 'projectToken' | 'clientSecret'>>;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve the autocapture option into a full config object, or null if disabled.
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolveAutocaptureConfig(autocapture: boolean | AutocaptureConfig | undefined): Required<AutocaptureConfig> | null;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { TruxlConfig } from './config';
|
|
2
|
+
import { Transport } from '../transport/transport';
|
|
3
|
+
interface QueuedEvent {
|
|
4
|
+
eventName: string;
|
|
5
|
+
distinctId: string;
|
|
6
|
+
deviceId: string;
|
|
7
|
+
timestamp: number;
|
|
8
|
+
properties: Record<string, unknown>;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
sdkVersion: string;
|
|
11
|
+
referrer: string;
|
|
12
|
+
userTimezone: string;
|
|
13
|
+
initialReferrer: string;
|
|
14
|
+
searchEngine: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class EventQueue {
|
|
17
|
+
private queue;
|
|
18
|
+
private timer;
|
|
19
|
+
private config;
|
|
20
|
+
private transport;
|
|
21
|
+
private sending;
|
|
22
|
+
constructor(config: Required<TruxlConfig>, transport: Transport);
|
|
23
|
+
enqueue(event: QueuedEvent): void;
|
|
24
|
+
flush(): Promise<void>;
|
|
25
|
+
destroy(): void;
|
|
26
|
+
private startTimer;
|
|
27
|
+
private saveToStorage;
|
|
28
|
+
private loadFromStorage;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Device ID generation and persistence.
|
|
3
|
+
*
|
|
4
|
+
* Generates a UUID-v4 device identifier and persists it in localStorage so
|
|
5
|
+
* that the same anonymous device can be recognised across sessions.
|
|
6
|
+
* Falls back to an in-memory ID when localStorage is unavailable (e.g.
|
|
7
|
+
* Safari private browsing).
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Return the current device ID, creating and persisting a new one if none
|
|
11
|
+
* exists yet.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getOrCreateDeviceId(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Retrieve the current device ID without creating one. Returns `null` when
|
|
16
|
+
* no device ID has been set yet.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getDeviceId(): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Explicitly set a device ID (e.g. when migrating from another analytics
|
|
21
|
+
* provider).
|
|
22
|
+
*/
|
|
23
|
+
export declare function setDeviceId(id: string): void;
|
|
24
|
+
/**
|
|
25
|
+
* Remove the persisted device ID. A new one will be generated on the next
|
|
26
|
+
* call to `getOrCreateDeviceId()`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function clearDeviceId(): void;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity management helpers.
|
|
3
|
+
*
|
|
4
|
+
* Provides `identify()`, `alias()`, and `reset()` functions that delegate to
|
|
5
|
+
* the TruxlClient instance for persisting user identity and emitting the
|
|
6
|
+
* appropriate tracking events.
|
|
7
|
+
*/
|
|
8
|
+
import { TruxlClient } from '../core/client';
|
|
9
|
+
/**
|
|
10
|
+
* Associate a known user ID with future events and optionally set user
|
|
11
|
+
* properties. Persists the distinct ID in localStorage so it survives page
|
|
12
|
+
* reloads.
|
|
13
|
+
*
|
|
14
|
+
* @param client The TruxlClient instance to delegate tracking to.
|
|
15
|
+
* @param distinctId A unique, stable identifier for the user (e.g. database
|
|
16
|
+
* ID, email hash).
|
|
17
|
+
* @param properties Optional user properties to attach via `$set`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function identify(client: TruxlClient, distinctId: string, properties?: Record<string, unknown>): void;
|
|
20
|
+
/**
|
|
21
|
+
* Create an alias that maps `newId` to `originalId`. This is useful when a
|
|
22
|
+
* previously anonymous user signs up and you want to link the anonymous
|
|
23
|
+
* device ID to their new authenticated ID.
|
|
24
|
+
*
|
|
25
|
+
* @param client The TruxlClient instance.
|
|
26
|
+
* @param newId The new identifier (e.g. authenticated user ID).
|
|
27
|
+
* @param originalId The original identifier (e.g. anonymous device ID).
|
|
28
|
+
*/
|
|
29
|
+
export declare function alias(client: TruxlClient, newId: string, originalId: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Reset identity state. Clears the stored distinct ID and alias so the
|
|
32
|
+
* device reverts to anonymous tracking. Typically called on logout.
|
|
33
|
+
*
|
|
34
|
+
* @param client The TruxlClient instance.
|
|
35
|
+
*/
|
|
36
|
+
export declare function reset(client: TruxlClient): void;
|
|
37
|
+
/**
|
|
38
|
+
* Retrieve the persisted distinct ID, if any. Returns `null` when the user
|
|
39
|
+
* has not been identified.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getDistinctId(): string | null;
|
|
42
|
+
/**
|
|
43
|
+
* Retrieve the persisted alias mapping, if any.
|
|
44
|
+
*/
|
|
45
|
+
export declare function getAlias(): {
|
|
46
|
+
newId: string;
|
|
47
|
+
originalId: string;
|
|
48
|
+
} | null;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { TruxlClient } from './core/client';
|
|
2
|
+
export { TruxlConfig, AutocaptureConfig } from './core/config';
|
|
3
|
+
export { Transport, TransportResult } from './transport/transport';
|
|
4
|
+
export { HttpTransport } from './transport/http';
|
|
5
|
+
export { WebSocketTransport } from './transport/websocket';
|
|
6
|
+
export { BeaconTransport } from './transport/beacon';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function signPayload(payload: string, secret: string): Promise<string>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-capture module.
|
|
3
|
+
*
|
|
4
|
+
* When enabled, automatically tracks based on the resolved AutocaptureConfig:
|
|
5
|
+
* - click: Click events on buttons and links
|
|
6
|
+
* - dead_click: Clicks that produce no DOM mutation
|
|
7
|
+
* - rage_click: Rapid repeated clicks on the same element
|
|
8
|
+
* - input: Input field value changes (sensitive fields redacted)
|
|
9
|
+
* - scroll: Scroll depth milestones (25%, 50%, 75%, 100%)
|
|
10
|
+
* - submit: Form submissions (delegates to form tracking module)
|
|
11
|
+
* - pageview: Page view events on URL changes
|
|
12
|
+
*
|
|
13
|
+
* Auto-capture is opt-in via `TruxlConfig.autocapture`.
|
|
14
|
+
*/
|
|
15
|
+
import { TruxlClient } from '../core/client';
|
|
16
|
+
import { AutocaptureConfig } from '../core/config';
|
|
17
|
+
/**
|
|
18
|
+
* Start auto-capturing interactions. Idempotent -- calling this multiple
|
|
19
|
+
* times will not register duplicate listeners.
|
|
20
|
+
*/
|
|
21
|
+
export declare function startAutocapture(client: TruxlClient, config: Required<AutocaptureConfig>): void;
|
|
22
|
+
/**
|
|
23
|
+
* Stop auto-capture and remove all registered event listeners.
|
|
24
|
+
*/
|
|
25
|
+
export declare function stopAutocapture(): void;
|