@traffical/js-client 0.17.0 → 0.19.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 +65 -9
- package/dist/client.d.ts +3 -3
- package/dist/client.js +2 -2
- package/dist/exposure-dedup.d.ts +1 -1
- package/dist/exposure-dedup.js +1 -1
- package/dist/global.d.ts +2 -1
- package/dist/global.d.ts.map +1 -1
- package/dist/global.js +4 -1
- package/dist/global.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/plugins/auto-attributes.d.ts +51 -0
- package/dist/plugins/auto-attributes.d.ts.map +1 -0
- package/dist/plugins/auto-attributes.js +234 -0
- package/dist/plugins/auto-attributes.js.map +1 -0
- package/dist/plugins/debug.d.ts +24 -0
- package/dist/plugins/debug.d.ts.map +1 -1
- package/dist/plugins/debug.js +61 -2
- package/dist/plugins/debug.js.map +1 -1
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +1 -0
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/redirect.d.ts.map +1 -1
- package/dist/plugins/redirect.js +9 -0
- package/dist/plugins/redirect.js.map +1 -1
- package/dist/traffical.min.js +2 -2
- package/dist/traffical.min.js.map +4 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ const traffical = await createTrafficalClient({
|
|
|
29
29
|
orgId: 'org_xxx',
|
|
30
30
|
projectId: 'proj_xxx',
|
|
31
31
|
env: 'production',
|
|
32
|
-
apiKey: '
|
|
32
|
+
apiKey: 'traffical_pk_…',
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
// Get parameters
|
|
@@ -67,7 +67,7 @@ traffical.track('checkout_complete', { value: 1 }, { decisionId: decision.decisi
|
|
|
67
67
|
orgId: 'org_xxx',
|
|
68
68
|
projectId: 'proj_xxx',
|
|
69
69
|
env: 'production',
|
|
70
|
-
apiKey: '
|
|
70
|
+
apiKey: 'traffical_pk_…',
|
|
71
71
|
}).then(function(traffical) {
|
|
72
72
|
var params = traffical.getParams({
|
|
73
73
|
context: { userId: 'user_123' },
|
|
@@ -167,7 +167,7 @@ The Traffical DevTools debug plugin uses these methods to let developers force p
|
|
|
167
167
|
## Features
|
|
168
168
|
|
|
169
169
|
- **Error Boundary** - SDK errors never crash your app
|
|
170
|
-
- **Exposure Deduplication** - Same user/
|
|
170
|
+
- **Exposure Deduplication** - Same user/allocation = 1 exposure event per session
|
|
171
171
|
- **Smart Batching** - Events batched and flushed efficiently
|
|
172
172
|
- **Beacon on Unload** - Events sent reliably on page close
|
|
173
173
|
- **Auto Stable ID** - Anonymous user identification via localStorage/cookie
|
|
@@ -187,7 +187,7 @@ const traffical = await createTrafficalClient({
|
|
|
187
187
|
orgId: 'org_xxx',
|
|
188
188
|
projectId: 'proj_xxx',
|
|
189
189
|
env: 'production',
|
|
190
|
-
apiKey: '
|
|
190
|
+
apiKey: 'traffical_pk_…',
|
|
191
191
|
plugins: [
|
|
192
192
|
createDOMBindingPlugin({
|
|
193
193
|
observeMutations: true, // Watch for DOM changes (SPA support)
|
|
@@ -218,7 +218,7 @@ The plugin:
|
|
|
218
218
|
|
|
219
219
|
### Redirect Plugin
|
|
220
220
|
|
|
221
|
-
Run URL split tests (redirect
|
|
221
|
+
Run URL split tests (redirect policies) where visitors are redirected to different landing page allocations. The redirect plugin automatically triggers a decision on init, performs the redirect, and sets an attribution cookie. The attribution plugin ensures conversions on the destination page are attributed back to the policy.
|
|
222
222
|
|
|
223
223
|
```typescript
|
|
224
224
|
import {
|
|
@@ -231,7 +231,7 @@ const traffical = await createTrafficalClient({
|
|
|
231
231
|
orgId: 'org_xxx',
|
|
232
232
|
projectId: 'proj_xxx',
|
|
233
233
|
env: 'production',
|
|
234
|
-
apiKey: '
|
|
234
|
+
apiKey: 'traffical_pk_…',
|
|
235
235
|
plugins: [
|
|
236
236
|
createRedirectPlugin(),
|
|
237
237
|
createRedirectAttributionPlugin(),
|
|
@@ -242,7 +242,7 @@ const traffical = await createTrafficalClient({
|
|
|
242
242
|
// On entry pages, it redirects. On other pages, it's a no-op.
|
|
243
243
|
|
|
244
244
|
// Track goals as usual — the attribution plugin injects
|
|
245
|
-
// redirect
|
|
245
|
+
// redirect policy metadata into every track() call.
|
|
246
246
|
traffical.track('add_to_cart', { value: 29.99 });
|
|
247
247
|
```
|
|
248
248
|
|
|
@@ -281,9 +281,9 @@ Track goal events from a separate GTM tag (e.g., triggered on "Add to Cart" clic
|
|
|
281
281
|
|
|
282
282
|
1. **Init** — The redirect plugin's `onInitialize` hook receives the client and calls `decide()` automatically.
|
|
283
283
|
|
|
284
|
-
2. **Entry page** — `onBeforeDecision` injects `url.pathname` into the context. The policy condition (e.g., `url.pathname startsWith /products/pillow`) matches, `redirect.url` resolves to the
|
|
284
|
+
2. **Entry page** — `onBeforeDecision` injects `url.pathname` into the context. The policy condition (e.g., `url.pathname startsWith /products/pillow`) matches, `redirect.url` resolves to the allocation's URL. `onDecision` writes an attribution cookie (`traffical_rdr`) and calls `window.location.replace()`.
|
|
285
285
|
|
|
286
|
-
3. **
|
|
286
|
+
3. **Destination page** — The SDK loads again, `decide()` runs, but the policy condition doesn't match the new URL, so `redirect.url` stays empty and no redirect happens. The redirect-attribution plugin reads the `traffical_rdr` cookie and injects the policy metadata into every `track()` call.
|
|
287
287
|
|
|
288
288
|
#### Configuration
|
|
289
289
|
|
|
@@ -310,6 +310,62 @@ The redirect plugin automatically adds these context fields:
|
|
|
310
310
|
|
|
311
311
|
Use `url.pathname` in policy conditions to target specific pages.
|
|
312
312
|
|
|
313
|
+
### Auto Attributes Plugin
|
|
314
|
+
|
|
315
|
+
Opt-in plugin that derives browser, page, UTM and locale attributes and injects them into every decision context via `onBeforeDecision` (the same hook the redirect plugin uses). All keys live in the reserved `$` namespace so they never collide with your own context keys. The dashboard registers them as **system attributes** (`managedBy: system`, source `plugin:web`), so they appear in the condition editor's key picker as soon as the plugin is in use.
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
import { createTrafficalClient, autoAttributesPlugin } from '@traffical/js-client';
|
|
319
|
+
|
|
320
|
+
const traffical = await createTrafficalClient({
|
|
321
|
+
orgId: 'org_xxx',
|
|
322
|
+
projectId: 'proj_xxx',
|
|
323
|
+
env: 'production',
|
|
324
|
+
apiKey: 'traffical_pk_…',
|
|
325
|
+
plugins: [autoAttributesPlugin()],
|
|
326
|
+
});
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Via the CDN build: `Traffical.autoAttributesPlugin()` (`Traffical.createAutoAttributesPlugin` is an alias).
|
|
330
|
+
|
|
331
|
+
#### Keys
|
|
332
|
+
|
|
333
|
+
| Key | Type | Values / source |
|
|
334
|
+
|-----|------|-----------------|
|
|
335
|
+
| `$browser` | enum | `chrome`, `edge`, `firefox`, `safari`, `other` — UA class only, no versions |
|
|
336
|
+
| `$os` | enum | `ios`, `android`, `macos`, `windows`, `linux`, `other` — UA class; iPadOS desktop UAs are detected via touch points |
|
|
337
|
+
| `$device_type` | enum | `mobile`, `tablet`, `desktop` — UA class first; desktop-class UAs with a coarse pointer fall back to width (`< 768` mobile, `< 1024` tablet) |
|
|
338
|
+
| `$url` | string (url) | `location.href` |
|
|
339
|
+
| `$host` | string | `location.host` |
|
|
340
|
+
| `$path` | string | `location.pathname` |
|
|
341
|
+
| `$query` | string | `location.search` without the leading `?`; omitted when empty |
|
|
342
|
+
| `$referrer` | string | `document.referrer`; omitted when empty |
|
|
343
|
+
| `$page_title` | string | `document.title`; omitted when empty |
|
|
344
|
+
| `$utm_source`, `$utm_medium`, `$utm_campaign`, `$utm_term`, `$utm_content` | string | From the query string; persisted in `sessionStorage` (`traffical:utm`) and re-read on later pages of the session whose URL has none |
|
|
345
|
+
| `$locale` | string | `navigator.language` (BCP 47, e.g. `en-GB`) |
|
|
346
|
+
| `$timezone` | string | `Intl.DateTimeFormat().resolvedOptions().timeZone` (IANA, e.g. `Europe/Berlin`) |
|
|
347
|
+
|
|
348
|
+
Rules:
|
|
349
|
+
|
|
350
|
+
- **Caller wins.** Context you pass to `decide()` / `getParams()` overrides any derived key of the same name.
|
|
351
|
+
- **Nothing empty.** A key that cannot be derived is omitted, never sent as `""`.
|
|
352
|
+
- **Re-derived on every decision**, so SPA navigation is covered without patching `history`.
|
|
353
|
+
- **SSR-safe.** Without a `window` the context passes through untouched.
|
|
354
|
+
|
|
355
|
+
#### Configuration
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
autoAttributesPlugin({
|
|
359
|
+
include?: AutoAttributeKey[], // only derive these keys (default: all)
|
|
360
|
+
exclude?: AutoAttributeKey[], // never derive these keys (applied after include)
|
|
361
|
+
persistUtm?: boolean, // default true — sessionStorage-backed utm persistence
|
|
362
|
+
});
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
`AUTO_ATTRIBUTE_KEYS` (the full key list) and the `AutoAttributeKey` type are exported for building `include` / `exclude` lists.
|
|
366
|
+
|
|
367
|
+
Mobile SDKs emit the same `$` keys from their device-info providers (`$os`, `$os_version`, `$app_version`, `$locale`, `$timezone`, `$device_model`, `$device_type`): `DefaultDeviceInfoProvider` on iOS and `defaultDeviceInfoProvider` in `@traffical/react-native`.
|
|
368
|
+
|
|
313
369
|
## Type-Safe Event Tracking
|
|
314
370
|
|
|
315
371
|
Use `@traffical/cli generate-types` to generate TypeScript interfaces for your event schemas. This lets you create a strictly typed `track` function that catches invalid event names and properties at compile time.
|
package/dist/client.d.ts
CHANGED
|
@@ -151,7 +151,7 @@ export interface TrafficalClientOptions {
|
|
|
151
151
|
disableCloudEvents?: boolean;
|
|
152
152
|
/**
|
|
153
153
|
* When true, assignment logger calls are deduplicated per session
|
|
154
|
-
* (same unit+policy+
|
|
154
|
+
* (same unit+policy+allocation won't fire again). Default: true.
|
|
155
155
|
*/
|
|
156
156
|
deduplicateAssignmentLogger?: boolean;
|
|
157
157
|
/**
|
|
@@ -275,7 +275,7 @@ export declare class TrafficalClient<TEvents extends TrackEventMap = TrackEventM
|
|
|
275
275
|
decide<T extends Record<string, ParameterValue>>(options: DecideOptions<T>): DecisionResult;
|
|
276
276
|
/**
|
|
277
277
|
* Tracks an exposure event.
|
|
278
|
-
* Automatically deduplicates
|
|
278
|
+
* Automatically deduplicates exposure events for the same user/allocation.
|
|
279
279
|
*
|
|
280
280
|
* Skips layers marked `attributionOnly` — those were resolved for
|
|
281
281
|
* attribution/assignment purposes only (no parameters were requested
|
|
@@ -419,7 +419,7 @@ export declare class TrafficalClient<TEvents extends TrackEventMap = TrackEventM
|
|
|
419
419
|
* - "cumulative": Collects layers from ALL cached decisions for this unit,
|
|
420
420
|
* deduplicated by layerId:policyId (last-write-wins). This ensures cross-page
|
|
421
421
|
* funnels (e.g., catalog -> PDP -> checkout) attribute correctly to all
|
|
422
|
-
*
|
|
422
|
+
* policies the user is exposed to. For per-entity dynamic allocation
|
|
423
423
|
* policies, only the most recent allocation is kept to avoid attributing
|
|
424
424
|
* rewards to allocations from other entities (e.g., different products).
|
|
425
425
|
*
|
package/dist/client.js
CHANGED
|
@@ -464,7 +464,7 @@ export class TrafficalClient {
|
|
|
464
464
|
// ===========================================================================
|
|
465
465
|
/**
|
|
466
466
|
* Tracks an exposure event.
|
|
467
|
-
* Automatically deduplicates
|
|
467
|
+
* Automatically deduplicates exposure events for the same user/allocation.
|
|
468
468
|
*
|
|
469
469
|
* Skips layers marked `attributionOnly` — those were resolved for
|
|
470
470
|
* attribution/assignment purposes only (no parameters were requested
|
|
@@ -1065,7 +1065,7 @@ export class TrafficalClient {
|
|
|
1065
1065
|
* - "cumulative": Collects layers from ALL cached decisions for this unit,
|
|
1066
1066
|
* deduplicated by layerId:policyId (last-write-wins). This ensures cross-page
|
|
1067
1067
|
* funnels (e.g., catalog -> PDP -> checkout) attribute correctly to all
|
|
1068
|
-
*
|
|
1068
|
+
* policies the user is exposed to. For per-entity dynamic allocation
|
|
1069
1069
|
* policies, only the most recent allocation is kept to avoid attributing
|
|
1070
1070
|
* rewards to allocations from other entities (e.g., different products).
|
|
1071
1071
|
*
|
package/dist/exposure-dedup.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ExposureDeduplicator - Prevents duplicate exposure events.
|
|
3
3
|
*
|
|
4
|
-
* Same user seeing same
|
|
4
|
+
* Same user seeing the same allocation should only count as 1 exposure.
|
|
5
5
|
* Uses session-based deduplication with localStorage persistence.
|
|
6
6
|
*/
|
|
7
7
|
import type { StorageProvider } from "./storage.js";
|
package/dist/exposure-dedup.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ExposureDeduplicator - Prevents duplicate exposure events.
|
|
3
3
|
*
|
|
4
|
-
* Same user seeing same
|
|
4
|
+
* Same user seeing the same allocation should only count as 1 exposure.
|
|
5
5
|
* Uses session-based deduplication with localStorage persistence.
|
|
6
6
|
*/
|
|
7
7
|
const STORAGE_KEY = "exposure_dedup";
|
package/dist/global.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { createDOMBindingPlugin, type DOMBindingPlugin, type DOMBindingPluginOpt
|
|
|
18
18
|
import { createRedirectPlugin, type RedirectPluginOptions } from "./plugins/redirect.js";
|
|
19
19
|
import { createRedirectAttributionPlugin, type RedirectAttributionPluginOptions } from "./plugins/redirect-attribution.js";
|
|
20
20
|
import { createDebugPlugin, type DebugPluginOptions } from "./plugins/debug.js";
|
|
21
|
+
import { autoAttributesPlugin, createAutoAttributesPlugin, AUTO_ATTRIBUTE_KEYS, type AutoAttributeKey, type AutoAttributesPluginOptions } from "./plugins/auto-attributes.js";
|
|
21
22
|
/**
|
|
22
23
|
* Initialize the Traffical client (async).
|
|
23
24
|
* Returns the client instance.
|
|
@@ -37,5 +38,5 @@ declare function instance(): TrafficalClient | null;
|
|
|
37
38
|
* Destroy the singleton instance.
|
|
38
39
|
*/
|
|
39
40
|
declare function destroy(): void;
|
|
40
|
-
export { init, initSync, instance, destroy, TrafficalClient, type TrafficalClientOptions, type TrafficalPlugin, createDOMBindingPlugin, type DOMBindingPlugin, type DOMBindingPluginOptions, createRedirectPlugin, type RedirectPluginOptions, createRedirectAttributionPlugin, type RedirectAttributionPluginOptions, createDebugPlugin, type DebugPluginOptions, };
|
|
41
|
+
export { init, initSync, instance, destroy, TrafficalClient, type TrafficalClientOptions, type TrafficalPlugin, createDOMBindingPlugin, type DOMBindingPlugin, type DOMBindingPluginOptions, createRedirectPlugin, type RedirectPluginOptions, createRedirectAttributionPlugin, type RedirectAttributionPluginOptions, createDebugPlugin, type DebugPluginOptions, autoAttributesPlugin, createAutoAttributesPlugin, AUTO_ATTRIBUTE_KEYS, type AutoAttributeKey, type AutoAttributesPluginOptions, };
|
|
41
42
|
//# sourceMappingURL=global.d.ts.map
|
package/dist/global.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,eAAe,EAGf,KAAK,sBAAsB,EAC5B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EACL,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,KAAK,qBAAqB,EAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,+BAA+B,EAC/B,KAAK,gCAAgC,EACtC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,eAAe,EAGf,KAAK,sBAAsB,EAC5B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EACL,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,KAAK,qBAAqB,EAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,+BAA+B,EAC/B,KAAK,gCAAgC,EACtC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,2BAA2B,EACjC,MAAM,8BAA8B,CAAC;AAKtC;;;GAGG;AACH,iBAAe,IAAI,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,eAAe,CAAC,CAQ7E;AAED;;;GAGG;AACH,iBAAS,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CAclE;AAED;;;GAGG;AACH,iBAAS,QAAQ,IAAI,eAAe,GAAG,IAAI,CAE1C;AAED;;GAEG;AACH,iBAAS,OAAO,IAAI,IAAI,CAKvB;AAGD,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,eAAe,EACf,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EAEpB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAE5B,oBAAoB,EACpB,KAAK,qBAAqB,EAC1B,+BAA+B,EAC/B,KAAK,gCAAgC,EAErC,iBAAiB,EACjB,KAAK,kBAAkB,EAEvB,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,2BAA2B,GACjC,CAAC"}
|
package/dist/global.js
CHANGED
|
@@ -17,6 +17,7 @@ import { createDOMBindingPlugin, } from "./plugins/dom-binding.js";
|
|
|
17
17
|
import { createRedirectPlugin, } from "./plugins/redirect.js";
|
|
18
18
|
import { createRedirectAttributionPlugin, } from "./plugins/redirect-attribution.js";
|
|
19
19
|
import { createDebugPlugin, } from "./plugins/debug.js";
|
|
20
|
+
import { autoAttributesPlugin, createAutoAttributesPlugin, AUTO_ATTRIBUTE_KEYS, } from "./plugins/auto-attributes.js";
|
|
20
21
|
// Global state for singleton pattern
|
|
21
22
|
let _instance = null;
|
|
22
23
|
/**
|
|
@@ -70,5 +71,7 @@ createDOMBindingPlugin,
|
|
|
70
71
|
// Redirect plugins
|
|
71
72
|
createRedirectPlugin, createRedirectAttributionPlugin,
|
|
72
73
|
// Debug plugin
|
|
73
|
-
createDebugPlugin,
|
|
74
|
+
createDebugPlugin,
|
|
75
|
+
// Auto attributes plugin
|
|
76
|
+
autoAttributesPlugin, createAutoAttributesPlugin, AUTO_ATTRIBUTE_KEYS, };
|
|
74
77
|
//# sourceMappingURL=global.js.map
|
package/dist/global.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.js","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,yBAAyB,GAE1B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,sBAAsB,GAGvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,GAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,+BAA+B,GAEhC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,GAElB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"global.js","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,yBAAyB,GAE1B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,sBAAsB,GAGvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,GAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,+BAA+B,GAEhC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,GAElB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,GAGpB,MAAM,8BAA8B,CAAC;AAEtC,qCAAqC;AACrC,IAAI,SAAS,GAA2B,IAAI,CAAC;AAE7C;;;GAGG;AACH,KAAK,UAAU,IAAI,CAAC,OAA+B;IACjD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;QACrF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,SAAS,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,OAA+B;IAC/C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;QACrF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,SAAS,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAE/C,2CAA2C;IAC3C,SAAS,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACrC,OAAO,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ;IACf,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,OAAO;IACd,IAAI,SAAS,EAAE,CAAC;QACd,SAAS,CAAC,OAAO,EAAE,CAAC;QACpB,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;AACH,CAAC;AAED,qCAAqC;AACrC,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,eAAe;AAGf,qBAAqB;AACrB,sBAAsB;AAGtB,mBAAmB;AACnB,oBAAoB,EAEpB,+BAA+B;AAE/B,eAAe;AACf,iBAAiB;AAEjB,yBAAyB;AACzB,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,GAGpB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Features:
|
|
7
7
|
* - Error boundary wrapping (P0) - SDK errors never crash your app
|
|
8
|
-
* - Exposure deduplication (P0) - Same user/
|
|
8
|
+
* - Exposure deduplication (P0) - Same user/allocation = 1 exposure event
|
|
9
9
|
* - Smart event batching (P1) - Batches events, uses sendBeacon on unload
|
|
10
10
|
* - Plugin system (P2) - Extensible via plugins
|
|
11
11
|
* - DOM binding plugin - Auto-apply parameters to DOM elements
|
|
@@ -46,5 +46,6 @@ export { type LifecycleProvider, type VisibilityState, type VisibilityCallback,
|
|
|
46
46
|
export { PluginManager, type TrafficalPlugin, type PluginOptions } from "./plugins/index.js";
|
|
47
47
|
export { createDOMBindingPlugin, type DOMBindingPlugin, type DOMBindingPluginOptions, } from "./plugins/dom-binding.js";
|
|
48
48
|
export { createWarehouseNativeLoggerPlugin, createWarehouseNativeLogger, type WarehouseNativeLoggerOptions, type JitsuDestination, type AnalyticsLike, } from "./plugins/warehouse-native-logger.js";
|
|
49
|
+
export { autoAttributesPlugin, createAutoAttributesPlugin, AUTO_ATTRIBUTE_KEYS, type AutoAttributeKey, type AutoAttributesPluginOptions, type AutoBrowser, type AutoOS, type AutoDeviceType, } from "./plugins/auto-attributes.js";
|
|
49
50
|
export { createDebugPlugin, type DebugPluginOptions, type TrafficalDebugRegistry, type TrafficalDebugInstance, type DebugState, type DebugEvent, type RegistryEvent, } from "./plugins/debug.js";
|
|
50
51
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,cAAc,iBAAiB,CAAC;AAGhC,cAAc,oBAAoB,CAAC;AAGnC,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,aAAa,CAAC;AAGrB;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,8BAA8B,GAC/B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG7F,OAAO,EACL,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,iCAAiC,EACjC,2BAA2B,EAC3B,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EACL,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,cAAc,iBAAiB,CAAC;AAGhC,cAAc,oBAAoB,CAAC;AAGnC,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,aAAa,CAAC;AAGrB;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,8BAA8B,GAC/B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG7F,OAAO,EACL,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,iCAAiC,EACjC,2BAA2B,EAC3B,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,2BAA2B,EAChC,KAAK,WAAW,EAChB,KAAK,MAAM,EACX,KAAK,cAAc,GACpB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Features:
|
|
7
7
|
* - Error boundary wrapping (P0) - SDK errors never crash your app
|
|
8
|
-
* - Exposure deduplication (P0) - Same user/
|
|
8
|
+
* - Exposure deduplication (P0) - Same user/allocation = 1 exposure event
|
|
9
9
|
* - Smart event batching (P1) - Batches events, uses sendBeacon on unload
|
|
10
10
|
* - Plugin system (P2) - Extensible via plugins
|
|
11
11
|
* - DOM binding plugin - Auto-apply parameters to DOM elements
|
|
@@ -54,6 +54,8 @@ export { PluginManager } from "./plugins/index.js";
|
|
|
54
54
|
export { createDOMBindingPlugin, } from "./plugins/dom-binding.js";
|
|
55
55
|
// Export warehouse-native logger
|
|
56
56
|
export { createWarehouseNativeLoggerPlugin, createWarehouseNativeLogger, } from "./plugins/warehouse-native-logger.js";
|
|
57
|
+
// Export auto-attributes plugin ($-prefixed web context keys)
|
|
58
|
+
export { autoAttributesPlugin, createAutoAttributesPlugin, AUTO_ATTRIBUTE_KEYS, } from "./plugins/auto-attributes.js";
|
|
57
59
|
// Export debug plugin
|
|
58
60
|
export { createDebugPlugin, } from "./plugins/debug.js";
|
|
59
61
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,iCAAiC;AACjC,cAAc,iBAAiB,CAAC;AAEhC,6CAA6C;AAC7C,cAAc,oBAAoB,CAAC;AAEnC,gBAAgB;AAChB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,yBAAyB,GAE1B,MAAM,aAAa,CAAC;AAErB,uCAAuC;AACvC;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAA6B,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAA2B,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAoC,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAgC,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,GAEtB,MAAM,cAAc,CAAC;AAEtB,+BAA+B;AAC/B,OAAO,EAIL,8BAA8B,GAC/B,MAAM,gBAAgB,CAAC;AAExB,uBAAuB;AACvB,OAAO,EAAE,aAAa,EAA4C,MAAM,oBAAoB,CAAC;AAE7F,4BAA4B;AAC5B,OAAO,EACL,sBAAsB,GAGvB,MAAM,0BAA0B,CAAC;AAElC,iCAAiC;AACjC,OAAO,EACL,iCAAiC,EACjC,2BAA2B,GAI5B,MAAM,sCAAsC,CAAC;AAE9C,sBAAsB;AACtB,OAAO,EACL,iBAAiB,GAOlB,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,iCAAiC;AACjC,cAAc,iBAAiB,CAAC;AAEhC,6CAA6C;AAC7C,cAAc,oBAAoB,CAAC;AAEnC,gBAAgB;AAChB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,yBAAyB,GAE1B,MAAM,aAAa,CAAC;AAErB,uCAAuC;AACvC;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAA6B,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAA2B,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAoC,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAgC,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,GAEtB,MAAM,cAAc,CAAC;AAEtB,+BAA+B;AAC/B,OAAO,EAIL,8BAA8B,GAC/B,MAAM,gBAAgB,CAAC;AAExB,uBAAuB;AACvB,OAAO,EAAE,aAAa,EAA4C,MAAM,oBAAoB,CAAC;AAE7F,4BAA4B;AAC5B,OAAO,EACL,sBAAsB,GAGvB,MAAM,0BAA0B,CAAC;AAElC,iCAAiC;AACjC,OAAO,EACL,iCAAiC,EACjC,2BAA2B,GAI5B,MAAM,sCAAsC,CAAC;AAE9C,8DAA8D;AAC9D,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,GAMpB,MAAM,8BAA8B,CAAC;AAEtC,sBAAsB;AACtB,OAAO,EACL,iBAAiB,GAOlB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { TrafficalPlugin } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Every context key the auto-attributes plugin can derive. All keys live in the
|
|
4
|
+
* reserved `$` namespace so they never collide with customer keys; the
|
|
5
|
+
* dashboard registers them as system attributes (`managedBy: system`,
|
|
6
|
+
* `source: plugin:web`).
|
|
7
|
+
*/
|
|
8
|
+
export declare const AUTO_ATTRIBUTE_KEYS: readonly ["$browser", "$os", "$device_type", "$url", "$host", "$path", "$query", "$referrer", "$page_title", "$utm_source", "$utm_medium", "$utm_campaign", "$utm_term", "$utm_content", "$locale", "$timezone"];
|
|
9
|
+
export type AutoAttributeKey = (typeof AUTO_ATTRIBUTE_KEYS)[number];
|
|
10
|
+
export type AutoBrowser = "chrome" | "edge" | "firefox" | "safari" | "other";
|
|
11
|
+
export type AutoOS = "ios" | "android" | "macos" | "windows" | "linux" | "other";
|
|
12
|
+
export type AutoDeviceType = "mobile" | "tablet" | "desktop";
|
|
13
|
+
export interface AutoAttributesPluginOptions {
|
|
14
|
+
/** Only derive these keys. Default: every key in `AUTO_ATTRIBUTE_KEYS`. */
|
|
15
|
+
include?: AutoAttributeKey[];
|
|
16
|
+
/** Never derive these keys. Applied after `include`. */
|
|
17
|
+
exclude?: AutoAttributeKey[];
|
|
18
|
+
/**
|
|
19
|
+
* Persist `$utm_*` values in `sessionStorage` (key `traffical:utm`) when the
|
|
20
|
+
* landing URL carries them, and re-read them on later pages of the same
|
|
21
|
+
* session whose URL has none. Default: true.
|
|
22
|
+
*/
|
|
23
|
+
persistUtm?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function classifyBrowser(ua: string): AutoBrowser;
|
|
26
|
+
export declare function classifyOS(ua: string, maxTouchPoints?: number): AutoOS;
|
|
27
|
+
export declare function classifyDeviceType(ua: string, opts: {
|
|
28
|
+
coarsePointer: boolean;
|
|
29
|
+
width: number;
|
|
30
|
+
maxTouchPoints?: number;
|
|
31
|
+
}): AutoDeviceType;
|
|
32
|
+
/**
|
|
33
|
+
* Auto-collected web attributes. Injects `$`-prefixed browser/page/UTM/locale
|
|
34
|
+
* keys into every decision context via `onBeforeDecision` (same hook as the
|
|
35
|
+
* redirect plugin). Caller-supplied context always wins; keys that cannot be
|
|
36
|
+
* derived are omitted rather than sent empty. Re-derived on every decision so
|
|
37
|
+
* SPA navigation is covered without patching `history`. SSR-safe: without a
|
|
38
|
+
* `window` the context passes through untouched.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const client = await createTrafficalClient({
|
|
43
|
+
* …,
|
|
44
|
+
* plugins: [autoAttributesPlugin({ exclude: ["$page_title"] })],
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function autoAttributesPlugin(options?: AutoAttributesPluginOptions): TrafficalPlugin;
|
|
49
|
+
/** Alias with the `create*Plugin` naming used by the other bundled plugins. */
|
|
50
|
+
export declare const createAutoAttributesPlugin: typeof autoAttributesPlugin;
|
|
51
|
+
//# sourceMappingURL=auto-attributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-attributes.d.ts","sourceRoot":"","sources":["../../src/plugins/auto-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,kNAiBtB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAC7E,MAAM,MAAM,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AACjF,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE7D,MAAM,WAAW,2BAA2B;IAC1C,2EAA2E;IAC3E,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,wDAAwD;IACxD,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAiBD,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,CAOvD;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,MAAM,CASjE;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;IAAE,aAAa,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE,cAAc,CAWhB;AA0GD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,2BAAgC,GAAG,eAAe,CA2B/F;AAED,+EAA+E;AAC/E,eAAO,MAAM,0BAA0B,6BAAuB,CAAC"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every context key the auto-attributes plugin can derive. All keys live in the
|
|
3
|
+
* reserved `$` namespace so they never collide with customer keys; the
|
|
4
|
+
* dashboard registers them as system attributes (`managedBy: system`,
|
|
5
|
+
* `source: plugin:web`).
|
|
6
|
+
*/
|
|
7
|
+
export const AUTO_ATTRIBUTE_KEYS = [
|
|
8
|
+
"$browser",
|
|
9
|
+
"$os",
|
|
10
|
+
"$device_type",
|
|
11
|
+
"$url",
|
|
12
|
+
"$host",
|
|
13
|
+
"$path",
|
|
14
|
+
"$query",
|
|
15
|
+
"$referrer",
|
|
16
|
+
"$page_title",
|
|
17
|
+
"$utm_source",
|
|
18
|
+
"$utm_medium",
|
|
19
|
+
"$utm_campaign",
|
|
20
|
+
"$utm_term",
|
|
21
|
+
"$utm_content",
|
|
22
|
+
"$locale",
|
|
23
|
+
"$timezone",
|
|
24
|
+
];
|
|
25
|
+
const UTM_STORAGE_KEY = "traffical:utm";
|
|
26
|
+
const UTM_KEYS = [
|
|
27
|
+
"$utm_source",
|
|
28
|
+
"$utm_medium",
|
|
29
|
+
"$utm_campaign",
|
|
30
|
+
"$utm_term",
|
|
31
|
+
"$utm_content",
|
|
32
|
+
];
|
|
33
|
+
/* ------------------------------------------------------------------ */
|
|
34
|
+
/* UA classification — deliberately coarse; UA-class only, no versions */
|
|
35
|
+
/* ------------------------------------------------------------------ */
|
|
36
|
+
export function classifyBrowser(ua) {
|
|
37
|
+
if (/\bEdg(?:e|A|iOS)?\//.test(ua))
|
|
38
|
+
return "edge";
|
|
39
|
+
if (/\bOPR\/|\bOpera\b/.test(ua))
|
|
40
|
+
return "other";
|
|
41
|
+
if (/\bFirefox\/|\bFxiOS\//.test(ua))
|
|
42
|
+
return "firefox";
|
|
43
|
+
if (/\bChrome\/|\bCriOS\/|\bChromium\//.test(ua))
|
|
44
|
+
return "chrome";
|
|
45
|
+
if (/\bSafari\//.test(ua) && /\bVersion\/|\bMobile\//.test(ua))
|
|
46
|
+
return "safari";
|
|
47
|
+
return "other";
|
|
48
|
+
}
|
|
49
|
+
export function classifyOS(ua, maxTouchPoints = 0) {
|
|
50
|
+
if (/\b(?:iPhone|iPad|iPod)\b/.test(ua))
|
|
51
|
+
return "ios";
|
|
52
|
+
// iPadOS 13+ reports a desktop Macintosh UA but is the only "Mac" with touch.
|
|
53
|
+
if (/\bMacintosh\b/.test(ua) && maxTouchPoints > 1)
|
|
54
|
+
return "ios";
|
|
55
|
+
if (/\bAndroid\b/.test(ua))
|
|
56
|
+
return "android";
|
|
57
|
+
if (/\bWindows\b/.test(ua))
|
|
58
|
+
return "windows";
|
|
59
|
+
if (/\bMac OS X\b|\bMacintosh\b/.test(ua))
|
|
60
|
+
return "macos";
|
|
61
|
+
if (/\bCrOS\b|\bLinux\b|\bX11\b/.test(ua))
|
|
62
|
+
return "linux";
|
|
63
|
+
return "other";
|
|
64
|
+
}
|
|
65
|
+
export function classifyDeviceType(ua, opts) {
|
|
66
|
+
if (/\biPad\b/.test(ua))
|
|
67
|
+
return "tablet";
|
|
68
|
+
if (/\bMacintosh\b/.test(ua) && (opts.maxTouchPoints ?? 0) > 1)
|
|
69
|
+
return "tablet";
|
|
70
|
+
if (/\biPhone\b|\biPod\b/.test(ua))
|
|
71
|
+
return "mobile";
|
|
72
|
+
if (/\bAndroid\b/.test(ua))
|
|
73
|
+
return /\bMobile\b/.test(ua) ? "mobile" : "tablet";
|
|
74
|
+
if (/\bMobi\b/.test(ua))
|
|
75
|
+
return "mobile";
|
|
76
|
+
if (opts.coarsePointer) {
|
|
77
|
+
if (opts.width < 768)
|
|
78
|
+
return "mobile";
|
|
79
|
+
if (opts.width < 1024)
|
|
80
|
+
return "tablet";
|
|
81
|
+
}
|
|
82
|
+
return "desktop";
|
|
83
|
+
}
|
|
84
|
+
/* ------------------------------------------------------------------ */
|
|
85
|
+
function readStoredUtm(win) {
|
|
86
|
+
try {
|
|
87
|
+
const raw = win.sessionStorage?.getItem(UTM_STORAGE_KEY);
|
|
88
|
+
if (!raw)
|
|
89
|
+
return null;
|
|
90
|
+
const parsed = JSON.parse(raw);
|
|
91
|
+
if (!parsed || typeof parsed !== "object")
|
|
92
|
+
return null;
|
|
93
|
+
const out = {};
|
|
94
|
+
for (const k of UTM_KEYS) {
|
|
95
|
+
const v = parsed[k];
|
|
96
|
+
if (typeof v === "string" && v)
|
|
97
|
+
out[k] = v;
|
|
98
|
+
}
|
|
99
|
+
return Object.keys(out).length ? out : null;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function writeStoredUtm(win, utm) {
|
|
106
|
+
try {
|
|
107
|
+
win.sessionStorage?.setItem(UTM_STORAGE_KEY, JSON.stringify(utm));
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// storage may be unavailable (private mode, quota, disabled)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function utmFromSearch(search) {
|
|
114
|
+
const out = {};
|
|
115
|
+
let params;
|
|
116
|
+
try {
|
|
117
|
+
params = new URLSearchParams(search);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
for (const k of UTM_KEYS) {
|
|
123
|
+
const v = params.get(k.slice(1)); // "$utm_source" → "utm_source"
|
|
124
|
+
if (v)
|
|
125
|
+
out[k] = v;
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
function deriveAll(win, persistUtm) {
|
|
130
|
+
const nav = win.navigator;
|
|
131
|
+
const loc = win.location;
|
|
132
|
+
const doc = win.document;
|
|
133
|
+
const ua = nav?.userAgent ?? "";
|
|
134
|
+
const maxTouchPoints = typeof nav?.maxTouchPoints === "number" ? nav.maxTouchPoints : 0;
|
|
135
|
+
let coarsePointer = false;
|
|
136
|
+
try {
|
|
137
|
+
coarsePointer = typeof win.matchMedia === "function" && win.matchMedia("(pointer: coarse)").matches;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// matchMedia may throw in exotic embeddings
|
|
141
|
+
}
|
|
142
|
+
const width = typeof win.innerWidth === "number" && win.innerWidth > 0 ? win.innerWidth : 1024;
|
|
143
|
+
const search = loc?.search ?? "";
|
|
144
|
+
let utm = utmFromSearch(search);
|
|
145
|
+
if (persistUtm) {
|
|
146
|
+
if (Object.keys(utm).length) {
|
|
147
|
+
writeStoredUtm(win, utm);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
utm = readStoredUtm(win) ?? {};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
let locale = nav?.language || undefined;
|
|
154
|
+
let timezone;
|
|
155
|
+
try {
|
|
156
|
+
timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || undefined;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
timezone = undefined;
|
|
160
|
+
}
|
|
161
|
+
if (locale === undefined) {
|
|
162
|
+
try {
|
|
163
|
+
locale = Intl.DateTimeFormat().resolvedOptions().locale || undefined;
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
locale = undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const query = search.startsWith("?") ? search.slice(1) : search;
|
|
170
|
+
return {
|
|
171
|
+
$browser: classifyBrowser(ua),
|
|
172
|
+
$os: classifyOS(ua, maxTouchPoints),
|
|
173
|
+
$device_type: classifyDeviceType(ua, { coarsePointer, width, maxTouchPoints }),
|
|
174
|
+
$url: loc?.href || undefined,
|
|
175
|
+
$host: loc?.host || undefined,
|
|
176
|
+
$path: loc?.pathname || undefined,
|
|
177
|
+
$query: query || undefined,
|
|
178
|
+
$referrer: doc?.referrer || undefined,
|
|
179
|
+
$page_title: doc?.title || undefined,
|
|
180
|
+
$utm_source: utm.$utm_source,
|
|
181
|
+
$utm_medium: utm.$utm_medium,
|
|
182
|
+
$utm_campaign: utm.$utm_campaign,
|
|
183
|
+
$utm_term: utm.$utm_term,
|
|
184
|
+
$utm_content: utm.$utm_content,
|
|
185
|
+
$locale: locale,
|
|
186
|
+
$timezone: timezone,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Auto-collected web attributes. Injects `$`-prefixed browser/page/UTM/locale
|
|
191
|
+
* keys into every decision context via `onBeforeDecision` (same hook as the
|
|
192
|
+
* redirect plugin). Caller-supplied context always wins; keys that cannot be
|
|
193
|
+
* derived are omitted rather than sent empty. Re-derived on every decision so
|
|
194
|
+
* SPA navigation is covered without patching `history`. SSR-safe: without a
|
|
195
|
+
* `window` the context passes through untouched.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```ts
|
|
199
|
+
* const client = await createTrafficalClient({
|
|
200
|
+
* …,
|
|
201
|
+
* plugins: [autoAttributesPlugin({ exclude: ["$page_title"] })],
|
|
202
|
+
* });
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
export function autoAttributesPlugin(options = {}) {
|
|
206
|
+
const persistUtm = options.persistUtm ?? true;
|
|
207
|
+
const active = new Set(options.include ? options.include.filter((k) => AUTO_ATTRIBUTE_KEYS.includes(k)) : AUTO_ATTRIBUTE_KEYS);
|
|
208
|
+
for (const k of options.exclude ?? [])
|
|
209
|
+
active.delete(k);
|
|
210
|
+
return {
|
|
211
|
+
name: "auto-attributes",
|
|
212
|
+
onBeforeDecision(context) {
|
|
213
|
+
if (typeof window === "undefined")
|
|
214
|
+
return context;
|
|
215
|
+
let derived;
|
|
216
|
+
try {
|
|
217
|
+
derived = deriveAll(window, persistUtm);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return context;
|
|
221
|
+
}
|
|
222
|
+
const out = {};
|
|
223
|
+
for (const k of active) {
|
|
224
|
+
const v = derived[k];
|
|
225
|
+
if (v !== undefined)
|
|
226
|
+
out[k] = v;
|
|
227
|
+
}
|
|
228
|
+
return { ...out, ...context };
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
/** Alias with the `create*Plugin` naming used by the other bundled plugins. */
|
|
233
|
+
export const createAutoAttributesPlugin = autoAttributesPlugin;
|
|
234
|
+
//# sourceMappingURL=auto-attributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-attributes.js","sourceRoot":"","sources":["../../src/plugins/auto-attributes.ts"],"names":[],"mappings":"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"}
|
package/dist/plugins/debug.d.ts
CHANGED
|
@@ -53,6 +53,18 @@ export interface DebugState {
|
|
|
53
53
|
lastDecisionId: string | null;
|
|
54
54
|
/** Parameter overrides currently applied by the debug plugin. */
|
|
55
55
|
overrides: Record<string, unknown>;
|
|
56
|
+
/**
|
|
57
|
+
* Context attributes the debug plugin merges into every decision's context
|
|
58
|
+
* (on top of whatever the host app passes). Lets an inspector satisfy
|
|
59
|
+
* targeting conditions the app itself never sets, e.g. `testMode exists`.
|
|
60
|
+
*/
|
|
61
|
+
contextOverrides: Record<string, unknown>;
|
|
62
|
+
/**
|
|
63
|
+
* The context of the last real decision, as the app passed it (after the
|
|
64
|
+
* client's unit-key enrichment, before context overrides). `null` until the
|
|
65
|
+
* app has decided at least once.
|
|
66
|
+
*/
|
|
67
|
+
lastContext: Record<string, unknown> | null;
|
|
56
68
|
}
|
|
57
69
|
export interface TrafficalDebugInstance {
|
|
58
70
|
readonly id: string;
|
|
@@ -72,6 +84,18 @@ export interface TrafficalDebugInstance {
|
|
|
72
84
|
clearOverride(key: string): void;
|
|
73
85
|
clearAllOverrides(): void;
|
|
74
86
|
getOverrides(): Record<string, unknown>;
|
|
87
|
+
/**
|
|
88
|
+
* Replace the context attributes merged into every decision. Re-decides
|
|
89
|
+
* immediately. Pass `{}` to clear.
|
|
90
|
+
*/
|
|
91
|
+
setContextOverrides(context: Record<string, unknown>): void;
|
|
92
|
+
getContextOverrides(): Record<string, unknown>;
|
|
93
|
+
/**
|
|
94
|
+
* Re-run the app's last decision (same context and parameter set) so the
|
|
95
|
+
* inspector shows what the app would resolve right now. If the page uses
|
|
96
|
+
* the OpenFeature provider, the OpenFeature context is re-set so hooks
|
|
97
|
+
* bound to `PROVIDER_CONTEXT_CHANGED` re-render too.
|
|
98
|
+
*/
|
|
75
99
|
reDecide(): void;
|
|
76
100
|
refresh(): Promise<void>;
|
|
77
101
|
}
|