@affiliateo/web 4.2.0 → 4.4.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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Client-side bot detection. Mirrors Datafast / PostHog / Plausible's
2
+ * Client-side bot detection. Mirrors PostHog / Plausible's
3
3
  * approach: catch the obvious automation tools at SDK init so they
4
4
  * never fire a single network request.
5
5
  *
@@ -20,8 +20,8 @@
20
20
  * layer 3 (kicks in on the request), then layer 2 (server checks before
21
21
  * writing). If any one layer rejects, the event drops.
22
22
  *
23
- * Patterns sourced from the Datafast script tag + npm SDK (publicly
24
- * inspectable). We include their full list because it represents years
23
+ * Patterns sourced from widely-used analytics SDKs (publicly
24
+ * inspectable). We include a comprehensive list because it represents years
25
25
  * of accumulated bot-shape knowledge that's expensive to reproduce.
26
26
  */
27
27
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Client-side bot detection. Mirrors Datafast / PostHog / Plausible's
2
+ * Client-side bot detection. Mirrors PostHog / Plausible's
3
3
  * approach: catch the obvious automation tools at SDK init so they
4
4
  * never fire a single network request.
5
5
  *
@@ -20,8 +20,8 @@
20
20
  * layer 3 (kicks in on the request), then layer 2 (server checks before
21
21
  * writing). If any one layer rejects, the event drops.
22
22
  *
23
- * Patterns sourced from the Datafast script tag + npm SDK (publicly
24
- * inspectable). We include their full list because it represents years
23
+ * Patterns sourced from widely-used analytics SDKs (publicly
24
+ * inspectable). We include a comprehensive list because it represents years
25
25
  * of accumulated bot-shape knowledge that's expensive to reproduce.
26
26
  */
27
27
  // Selenium/WebDriver/headless flags set on window or navigator. Modern
package/dist/provider.js CHANGED
@@ -8,12 +8,12 @@ const DEFAULT_API_URL = 'https://affiliateo.com';
8
8
  const LS_VISITOR_ID = 'affiliateo_visitor_id';
9
9
  const LS_REF = 'affiliateo_ref';
10
10
  const LS_CAMPAIGN_ID = 'affiliateo_campaign_id';
11
- // Persistent opt-out flag. Mirrors Datafast's DATAFAST_IGNORE_TRACKING key —
11
+ // Persistent opt-out flag (affiliateo_opt_out) —
12
12
  // when set to "true" the SDK silently noops every outbound call. Survives
13
13
  // page reloads. removed by optIn(). Checked at init time so a previously
14
14
  // opted-out visitor never re-fires auto-pageviews after a refresh.
15
15
  const LS_OPT_OUT = 'affiliateo_opt_out';
16
- // Client-owned session id (Datafast-style). The BROWSER owns the session,
16
+ // Client-owned session id. The BROWSER owns the session,
17
17
  // not the server. One id is reused for every event within a sliding
18
18
  // 10-minute activity window, then a fresh one is minted. Because the id is
19
19
  // generated here and sent on each event, a burst of pageviews (a redirect
@@ -26,7 +26,7 @@ const SESSION_WINDOW_MS = 10 * 60 * 1000;
26
26
  // Same-URL pageview throttle, persisted in sessionStorage so it survives
27
27
  // hard navigations / redirect bounces (the old in-memory throttle reset on
28
28
  // every fresh page context, which let a 3-hop bounce fire 3 pageviews).
29
- // Different URLs are never throttled against each other. Mirrors Datafast's
29
+ // Different URLs are never throttled against each other, with a
30
30
  // 60s same-URL suppression.
31
31
  const SS_PV_THROTTLE = 'affiliateo_pv_throttle';
32
32
  const PV_THROTTLE_MS = 60 * 1000;
@@ -88,7 +88,7 @@ function uuid() {
88
88
  // Get-or-create the current session id with a sliding 10-minute window.
89
89
  // Stored in localStorage so every tab and every page load in the same
90
90
  // browser shares one session. Each call slides the window forward (the same
91
- // way Datafast refreshes its session cookie on each event), so an actively
91
+ // way a session cookie is refreshed on each event), so an actively
92
92
  // browsing visitor keeps one id and a returning visitor past the window
93
93
  // gets a fresh one. Returns a UUID string the server stamps onto the event.
94
94
  function getSessionId() {
@@ -169,7 +169,7 @@ export function AffiliateoProvider({ campaignId, apiUrl, allowedHostnames, allow
169
169
  // Normalize autoCapturePageviews. Three shapes:
170
170
  // - undefined / true / object → auto-capture ON (with object overrides)
171
171
  // - false → auto-capture OFF entirely (host must call trackPageview)
172
- // Defaults match Datafast: captureInitialPageview true, trackHashChanges
172
+ // Sensible defaults: captureInitialPageview true, trackHashChanges
173
173
  // false, debounceMs 100.
174
174
  const autoCfg = autoCapturePageviews === false
175
175
  ? { enabled: false, captureInitialPageview: false, trackHashChanges: false, debounceMs: 100 }
@@ -299,7 +299,7 @@ export function AffiliateoProvider({ campaignId, apiUrl, allowedHostnames, allow
299
299
  }
300
300
  catch { /* swallow */ }
301
301
  }, [apiBase, log]);
302
- // Manual pageview. Mirrors Datafast's trackPageview(path?). Same payload
302
+ // Manual pageview via trackPageview(path?). Same payload
303
303
  // shape the auto-fired pageview uses (see sendPageview inside the route
304
304
  // effect below) so server-side routing / dedup / IP+UA enrichment behave
305
305
  // identically for both code paths.
@@ -339,6 +339,12 @@ export function AffiliateoProvider({ campaignId, apiUrl, allowedHostnames, allow
339
339
  utm_source: params.get('utm_source') || '',
340
340
  utm_medium: params.get('utm_medium') || '',
341
341
  utm_campaign: params.get('utm_campaign') || '',
342
+ // Ad-network click ids — set automatically on the landing URL by
343
+ // every Meta/TikTok/Google ad click. Label the sale's source and
344
+ // feed server-side conversion matching.
345
+ fbclid: params.get('fbclid') || '',
346
+ ttclid: params.get('ttclid') || '',
347
+ gclid: params.get('gclid') || '',
342
348
  screen_width: window.innerWidth,
343
349
  };
344
350
  queueRef.current?.enqueue(`${apiBase}/api/v1/web/event`, payload);
@@ -364,13 +370,13 @@ export function AffiliateoProvider({ campaignId, apiUrl, allowedHostnames, allow
364
370
  // affiliate ref so the next pageview is a brand-new anonymous visitor.
365
371
  // The campaign_id stays (it's a property of the site, not the visitor).
366
372
  //
367
- // Matches Datafast's reset() semantics for non-cookieless mode: new
373
+ // reset() semantics for non-cookieless mode: new
368
374
  // visitor, no event fired, caller handles "tell the server about it"
369
375
  // by triggering whatever pageview / navigation comes next.
370
376
  //
371
377
  // Returns a Promise so callers can `await reset()` before navigating
372
378
  // (the localStorage writes are sync but the Promise lets the API stay
373
- // consistent with Datafast's async signature, future-proofing for
379
+ // an async signature, future-proofing for
374
380
  // server-minted IDs in cookieless mode).
375
381
  const reset = useCallback(async () => {
376
382
  try {
@@ -666,6 +672,10 @@ export function AffiliateoProvider({ campaignId, apiUrl, allowedHostnames, allow
666
672
  utm_source: params.get('utm_source') || '',
667
673
  utm_medium: params.get('utm_medium') || '',
668
674
  utm_campaign: params.get('utm_campaign') || '',
675
+ // Ad-network click ids from the landing URL (see trackPageview).
676
+ fbclid: params.get('fbclid') || '',
677
+ ttclid: params.get('ttclid') || '',
678
+ gclid: params.get('gclid') || '',
669
679
  screen_width: window.innerWidth,
670
680
  });
671
681
  log('pageview', { path: window.location.pathname });
@@ -756,8 +766,8 @@ export function AffiliateoProvider({ campaignId, apiUrl, allowedHostnames, allow
756
766
  // Debouncing collapses back-to-back navigation events into one. Some
757
767
  // frameworks (Next.js, certain Vue routers) fire pushState then
758
768
  // replaceState in the same tick to canonicalize the URL; without
759
- // debouncing that's two pageviews per real navigation. Default 100ms
760
- // matches Datafast; set debounceMs to 0 to disable.
769
+ // debouncing that's two pageviews per real navigation. Default 100ms;
770
+ // set debounceMs to 0 to disable.
761
771
  let lastPath = window.location.pathname;
762
772
  let lastHash = window.location.hash;
763
773
  let pendingPageviewTimer = null;
@@ -802,7 +812,7 @@ export function AffiliateoProvider({ campaignId, apiUrl, allowedHostnames, allow
802
812
  };
803
813
  // HTML-attribute goal scanning (`data-affiliateo-goal`,
804
814
  // `data-affiliateo-scroll`) and the IntersectionObserver that drove
805
- // them were removed in 3.0.0 to match Datafast's npm SDK ergonomics:
815
+ // them were removed in 3.0.0 to streamline the npm SDK ergonomics:
806
816
  // SDK does pageview + track() + identify(); merchants fire goals
807
817
  // themselves via onClick={() => track('signup_clicked')} or by
808
818
  // wiring their own IntersectionObserver and calling track() from it.
package/dist/queue.d.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  * networks (train wifi, subway transitions, dropping 4G) merchants saw
10
10
  * ~10-15% fewer events than they should have.
11
11
  *
12
- * This queue mirrors the pattern PostHog / Segment / Amplitude / Datafast
12
+ * This queue mirrors the pattern PostHog / Segment / Amplitude
13
13
  * all converged on: in-memory queue, localStorage persistence so events
14
14
  * survive page reload, periodic auto-flush, retry on failure up to N
15
15
  * times, drop after N tries to bound memory.
@@ -37,7 +37,7 @@
37
37
  * - MAX_QUEUE_SIZE hard cap so a long network outage can't fill
38
38
  * localStorage and break the host app. Events
39
39
  * beyond the cap are dropped FIFO (oldest first).
40
- * - FLUSH_INTERVAL_MS = 5_000 matches Datafast's web SDK default
40
+ * - FLUSH_INTERVAL_MS = 5_000 a sensible web SDK default
41
41
  * - SIZE_FLUSH_THRESHOLD = 10 triggers a flush when queue grows
42
42
  * past this even before the timer fires
43
43
  */
package/dist/queue.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * networks (train wifi, subway transitions, dropping 4G) merchants saw
10
10
  * ~10-15% fewer events than they should have.
11
11
  *
12
- * This queue mirrors the pattern PostHog / Segment / Amplitude / Datafast
12
+ * This queue mirrors the pattern PostHog / Segment / Amplitude
13
13
  * all converged on: in-memory queue, localStorage persistence so events
14
14
  * survive page reload, periodic auto-flush, retry on failure up to N
15
15
  * times, drop after N tries to bound memory.
@@ -37,7 +37,7 @@
37
37
  * - MAX_QUEUE_SIZE hard cap so a long network outage can't fill
38
38
  * localStorage and break the host app. Events
39
39
  * beyond the cap are dropped FIFO (oldest first).
40
- * - FLUSH_INTERVAL_MS = 5_000 matches Datafast's web SDK default
40
+ * - FLUSH_INTERVAL_MS = 5_000 a sensible web SDK default
41
41
  * - SIZE_FLUSH_THRESHOLD = 10 triggers a flush when queue grows
42
42
  * past this even before the timer fires
43
43
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@affiliateo/web",
3
- "version": "4.2.0",
3
+ "version": "4.4.0",
4
4
  "description": "Affiliateo web SDK — affiliate attribution and tracking for web apps",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",