@formo/analytics 1.28.6 → 1.29.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.
@@ -192,7 +192,7 @@ exports.COUNTRY_LIST = {
192
192
  "America/Panama": "PA",
193
193
  "America/Pangnirtung": "CA",
194
194
  "America/Paramaribo": "SR",
195
- "America/Phoenix": "US,CA",
195
+ "America/Phoenix": "US",
196
196
  "America/Port-au-Prince": "HT",
197
197
  "America/Port_of_Spain": "TT",
198
198
  "America/Porto_Acre": "BR",
@@ -298,6 +298,7 @@ exports.COUNTRY_LIST = {
298
298
  "Asia/Katmandu": "NP",
299
299
  "Asia/Khandyga": "RU",
300
300
  "Asia/Kolkata": "IN",
301
+ "Asia/Kostanay": "KZ",
301
302
  "Asia/Krasnoyarsk": "RU",
302
303
  "Asia/Kuala_Lumpur": "MY",
303
304
  "Asia/Kuching": "MY",
@@ -399,59 +400,15 @@ exports.COUNTRY_LIST = {
399
400
  "Canada/Pacific": "CA",
400
401
  "Canada/Saskatchewan": "CA",
401
402
  "Canada/Yukon": "CA",
402
- // CET
403
- CET: "CET",
404
403
  // Chile
405
404
  "Chile/Continental": "CL",
406
405
  "Chile/EasterIsland": "CL",
407
- // CST6CDT
408
- CST6CDT: "CST6CDT",
409
406
  // Cuba
410
407
  Cuba: "CU",
411
- // EET
412
- EET: "EET",
413
408
  // Egypt
414
409
  Egypt: "EG",
415
410
  // Eire
416
411
  Eire: "IE",
417
- // EST
418
- EST: "EST",
419
- EST5EDT: "EST5EDT",
420
- "Etc/GMT": "Etc/GMT",
421
- "Etc/GMT+0": "Etc/GMT+0",
422
- "Etc/GMT+1": "Etc/GMT+1",
423
- "Etc/GMT+10": "Etc/GMT+10",
424
- "Etc/GMT+11": "Etc/GMT+11",
425
- "Etc/GMT+12": "Etc/GMT+12",
426
- "Etc/GMT+2": "Etc/GMT+2",
427
- "Etc/GMT+3": "Etc/GMT+3",
428
- "Etc/GMT+4": "Etc/GMT+4",
429
- "Etc/GMT+5": "Etc/GMT+5",
430
- "Etc/GMT+6": "Etc/GMT+6",
431
- "Etc/GMT+7": "Etc/GMT+7",
432
- "Etc/GMT+8": "Etc/GMT+8",
433
- "Etc/GMT+9": "Etc/GMT+9",
434
- "Etc/GMT-0": "Etc/GMT-0",
435
- "Etc/GMT-1": "Etc/GMT-1",
436
- "Etc/GMT-10": "Etc/GMT-10",
437
- "Etc/GMT-11": "Etc/GMT-11",
438
- "Etc/GMT-12": "Etc/GMT-12",
439
- "Etc/GMT-13": "Etc/GMT-13",
440
- "Etc/GMT-14": "Etc/GMT-14",
441
- "Etc/GMT-2": "Etc/GMT-2",
442
- "Etc/GMT-3": "Etc/GMT-3",
443
- "Etc/GMT-4": "Etc/GMT-4",
444
- "Etc/GMT-5": "Etc/GMT-5",
445
- "Etc/GMT-6": "Etc/GMT-6",
446
- "Etc/GMT-7": "Etc/GMT-7",
447
- "Etc/GMT-8": "Etc/GMT-8",
448
- "Etc/GMT-9": "Etc/GMT-9",
449
- "Etc/GMT0": "Etc/GMT0",
450
- "Etc/Greenwich": "Etc/Greenwich",
451
- "Etc/UCT": "Etc/UCT",
452
- "Etc/UTC": "Etc/UTC",
453
- "Etc/Universal": "Etc/Universal",
454
- "Etc/Zulu": "Etc/Zulu",
455
412
  // Europe
456
413
  "Europe/Amsterdam": "NL",
457
414
  "Europe/Andorra": "AD",
@@ -517,21 +474,11 @@ exports.COUNTRY_LIST = {
517
474
  "Europe/Zagreb": "HR",
518
475
  "Europe/Zaporozhye": "UA",
519
476
  "Europe/Zurich": "CH",
520
- // Factory
521
- Factory: "Factory",
522
477
  // GB
523
478
  GB: "GB",
524
479
  "GB-Eire": "GB",
525
- // GMT
526
- GMT: "GMT",
527
- "GMT+0": "GMT+0",
528
- "GMT-0": "GMT-0",
529
- GMT0: "GMT0",
530
- Greenwich: "Greenwich",
531
480
  // HK
532
481
  Hongkong: "HK",
533
- // HST
534
- HST: "HST",
535
482
  // Iceland
536
483
  Iceland: "IS",
537
484
  // Indian
@@ -558,15 +505,10 @@ exports.COUNTRY_LIST = {
558
505
  Kwajalein: "MH",
559
506
  // Libya
560
507
  Libya: "LY",
561
- // MET
562
- MET: "MET",
563
508
  // Mexico
564
509
  "Mexico/BajaNorte": "MX",
565
510
  "Mexico/BajaSur": "MX",
566
511
  "Mexico/General": "MX",
567
- // MST
568
- MST: "MST",
569
- MST7MDT: "MST7MDT",
570
512
  // Navajo
571
513
  Navajo: "US",
572
514
  // NZ
@@ -587,7 +529,7 @@ exports.COUNTRY_LIST = {
587
529
  "Pacific/Galapagos": "EC",
588
530
  "Pacific/Gambier": "PF",
589
531
  "Pacific/Guadalcanal": "SB",
590
- "Pacific/Guam": "GU,MP",
532
+ "Pacific/Guam": "GU",
591
533
  "Pacific/Honolulu": "US",
592
534
  "Pacific/Johnston": "UM",
593
535
  "Pacific/Kanton": "KI",
@@ -623,8 +565,6 @@ exports.COUNTRY_LIST = {
623
565
  Portugal: "PT",
624
566
  // PRC
625
567
  PRC: "CN",
626
- // PST8PDT
627
- PST8PDT: "PST8PDT",
628
568
  // ROC
629
569
  ROC: "TW",
630
570
  // ROK
@@ -633,10 +573,6 @@ exports.COUNTRY_LIST = {
633
573
  Singapore: "SG",
634
574
  // Turkey
635
575
  Turkey: "TR",
636
- // UCT
637
- UCT: "UCT",
638
- // Universal
639
- Universal: "Universal",
640
576
  // US
641
577
  "US/Alaska": "US",
642
578
  "US/Aleutian": "US",
@@ -650,13 +586,7 @@ exports.COUNTRY_LIST = {
650
586
  "US/Mountain": "US",
651
587
  "US/Pacific": "US",
652
588
  "US/Samoa": "AS",
653
- // UTC
654
- UTC: "UTC",
655
589
  // W-SU
656
590
  "W-SU": "RU",
657
- // WET
658
- WET: "WET",
659
- // Zulu
660
- Zulu: "Zulu",
661
591
  };
662
592
  //# sourceMappingURL=config.js.map
@@ -17,6 +17,7 @@ declare class EventFactory implements IEventFactory {
17
17
  private getLanguage;
18
18
  private getLibraryVersion;
19
19
  private extractUTMParameters;
20
+ private extractClickIdParameters;
20
21
  private extractReferralParameter;
21
22
  private getTrafficSources;
22
23
  private getScreen;
@@ -63,6 +63,7 @@ var version_1 = require("../version");
63
63
  var constants_2 = require("./constants");
64
64
  var utils_2 = require("./utils");
65
65
  var browsers_1 = require("../browser/browsers");
66
+ var ISO_3166_ALPHA_2_REGEX = /^[A-Z]{2}$/;
66
67
  var EventFactory = /** @class */ (function () {
67
68
  function EventFactory(options) {
68
69
  var _this = this;
@@ -87,6 +88,15 @@ var EventFactory = /** @class */ (function () {
87
88
  catch (_a) { }
88
89
  return result;
89
90
  };
91
+ this.extractClickIdParameters = function (urlObj) {
92
+ var result = {};
93
+ for (var _i = 0, CLICK_ID_PARAMS_1 = constants_2.CLICK_ID_PARAMS; _i < CLICK_ID_PARAMS_1.length; _i++) {
94
+ var param = CLICK_ID_PARAMS_1[_i];
95
+ var value = urlObj.searchParams.get(param);
96
+ result[param] = value ? value.trim() : "";
97
+ }
98
+ return result;
99
+ };
90
100
  this.extractReferralParameter = function (urlObj) {
91
101
  var _a, _b, _c;
92
102
  // Strategy: Check query params first, then check path pattern if configured
@@ -119,25 +129,23 @@ var EventFactory = /** @class */ (function () {
119
129
  };
120
130
  this.getTrafficSources = function (url) {
121
131
  var urlObj = new URL(url);
122
- var contextTrafficSources = __assign(__assign({}, _this.extractUTMParameters(url)), { ref: _this.extractReferralParameter(urlObj), referrer: document.referrer });
132
+ var contextTrafficSources = __assign(__assign(__assign({}, _this.extractUTMParameters(url)), _this.extractClickIdParameters(urlObj)), { ref: _this.extractReferralParameter(urlObj), referrer: document.referrer });
123
133
  var storedTrafficSources = (0, storage_1.session)().get(constants_1.SESSION_TRAFFIC_SOURCE_KEY) || {};
124
- var finalTrafficSources = {
125
- ref: contextTrafficSources.ref || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.ref) || "",
126
- referrer: contextTrafficSources.referrer || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.referrer) || "",
127
- utm_campaign: contextTrafficSources.utm_campaign ||
134
+ var mergedClickIds = {};
135
+ for (var _i = 0, CLICK_ID_PARAMS_2 = constants_2.CLICK_ID_PARAMS; _i < CLICK_ID_PARAMS_2.length; _i++) {
136
+ var p = CLICK_ID_PARAMS_2[_i];
137
+ mergedClickIds[p] =
138
+ contextTrafficSources[p] || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources[p]) || "";
139
+ }
140
+ var finalTrafficSources = __assign({ ref: contextTrafficSources.ref || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.ref) || "", referrer: contextTrafficSources.referrer || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.referrer) || "", utm_campaign: contextTrafficSources.utm_campaign ||
128
141
  (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_campaign) ||
129
- "",
130
- utm_content: contextTrafficSources.utm_content ||
142
+ "", utm_content: contextTrafficSources.utm_content ||
131
143
  (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_content) ||
132
- "",
133
- utm_medium: contextTrafficSources.utm_medium ||
144
+ "", utm_medium: contextTrafficSources.utm_medium ||
134
145
  (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_medium) ||
135
- "",
136
- utm_source: contextTrafficSources.utm_source ||
146
+ "", utm_source: contextTrafficSources.utm_source ||
137
147
  (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_source) ||
138
- "",
139
- utm_term: contextTrafficSources.utm_term || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_term) || "",
140
- };
148
+ "", utm_term: contextTrafficSources.utm_term || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_term) || "" }, mergedClickIds);
141
149
  // Store to session
142
150
  var sessionStoredTrafficSources = Object.keys(finalTrafficSources).reduce(function (res, key) {
143
151
  var value = finalTrafficSources[key];
@@ -223,9 +231,14 @@ var EventFactory = /** @class */ (function () {
223
231
  EventFactory.prototype.getLocation = function () {
224
232
  try {
225
233
  var timezone = this.getTimezone();
226
- if (timezone in constants_1.COUNTRY_LIST)
227
- return constants_1.COUNTRY_LIST[timezone];
228
- return timezone;
234
+ if (!timezone)
235
+ return "";
236
+ var mapped = constants_1.COUNTRY_LIST[timezone];
237
+ // Only emit ISO-3166 alpha-2. Anything else (including the raw
238
+ // timezone string) is treated as unknown.
239
+ return typeof mapped === "string" && ISO_3166_ALPHA_2_REGEX.test(mapped)
240
+ ? mapped
241
+ : "";
229
242
  }
230
243
  catch (error) {
231
244
  logger_1.logger.error("Error resolving location:", error);
@@ -1,11 +1,17 @@
1
1
  declare const CHANNEL = "web";
2
2
  declare const VERSION = "0";
3
+ /**
4
+ * Paid-attribution click IDs captured from the landing-page URL and persisted
5
+ * across the session alongside UTM parameters. Keep the ClickIdParameters type
6
+ * in src/types/events.ts derived from this array.
7
+ */
8
+ declare const CLICK_ID_PARAMS: readonly ["gclid", "gad_source", "fbclid", "msclkid", "twclid", "li_fat_id", "rdt_cid", "ttclid"];
3
9
  /**
4
10
  * Fields that should be excluded from page event properties parsing
5
11
  * These are either:
6
- * - Already captured in event context (UTM params, referral params)
12
+ * - Already captured in event context (UTM params, referral params, click IDs)
7
13
  * - Semantic event properties that should not be overridden by URL params
8
14
  */
9
15
  declare const PAGE_PROPERTIES_EXCLUDED_FIELDS: Set<string>;
10
- export { CHANNEL, VERSION, PAGE_PROPERTIES_EXCLUDED_FIELDS };
16
+ export { CHANNEL, VERSION, CLICK_ID_PARAMS, PAGE_PROPERTIES_EXCLUDED_FIELDS };
11
17
  //# sourceMappingURL=constants.d.ts.map
@@ -1,17 +1,42 @@
1
1
  "use strict";
2
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
+ if (ar || !(i in from)) {
5
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6
+ ar[i] = from[i];
7
+ }
8
+ }
9
+ return to.concat(ar || Array.prototype.slice.call(from));
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PAGE_PROPERTIES_EXCLUDED_FIELDS = exports.VERSION = exports.CHANNEL = void 0;
12
+ exports.PAGE_PROPERTIES_EXCLUDED_FIELDS = exports.CLICK_ID_PARAMS = exports.VERSION = exports.CHANNEL = void 0;
4
13
  var CHANNEL = "web";
5
14
  exports.CHANNEL = CHANNEL;
6
15
  var VERSION = "0";
7
16
  exports.VERSION = VERSION;
17
+ /**
18
+ * Paid-attribution click IDs captured from the landing-page URL and persisted
19
+ * across the session alongside UTM parameters. Keep the ClickIdParameters type
20
+ * in src/types/events.ts derived from this array.
21
+ */
22
+ var CLICK_ID_PARAMS = [
23
+ "gclid", // Google Ads
24
+ "gad_source", // Google Ads (newer)
25
+ "fbclid", // Meta (Facebook/Instagram)
26
+ "msclkid", // Microsoft Ads (Bing)
27
+ "twclid", // Twitter/X Ads
28
+ "li_fat_id", // LinkedIn Ads
29
+ "rdt_cid", // Reddit Ads
30
+ "ttclid", // TikTok Ads
31
+ ];
32
+ exports.CLICK_ID_PARAMS = CLICK_ID_PARAMS;
8
33
  /**
9
34
  * Fields that should be excluded from page event properties parsing
10
35
  * These are either:
11
- * - Already captured in event context (UTM params, referral params)
36
+ * - Already captured in event context (UTM params, referral params, click IDs)
12
37
  * - Semantic event properties that should not be overridden by URL params
13
38
  */
14
- var PAGE_PROPERTIES_EXCLUDED_FIELDS = new Set([
39
+ var PAGE_PROPERTIES_EXCLUDED_FIELDS = new Set(__spreadArray(__spreadArray([
15
40
  // Context fields (already captured in event context)
16
41
  'utm_source',
17
42
  'utm_medium',
@@ -21,7 +46,8 @@ var PAGE_PROPERTIES_EXCLUDED_FIELDS = new Set([
21
46
  'ref',
22
47
  'referral',
23
48
  'refcode',
24
- 'referrer',
49
+ 'referrer'
50
+ ], CLICK_ID_PARAMS, true), [
25
51
  // Semantic event properties (should not be overridden by URL params)
26
52
  'category',
27
53
  'name',
@@ -29,6 +55,6 @@ var PAGE_PROPERTIES_EXCLUDED_FIELDS = new Set([
29
55
  'path',
30
56
  'hash',
31
57
  'query',
32
- ]);
58
+ ], false));
33
59
  exports.PAGE_PROPERTIES_EXCLUDED_FIELDS = PAGE_PROPERTIES_EXCLUDED_FIELDS;
34
60
  //# sourceMappingURL=constants.js.map
@@ -1,6 +1,7 @@
1
1
  import { UUID } from "crypto";
2
2
  import { Address, ChainID, Nullable } from "./base";
3
3
  import { TEventChannel, TEventType } from "../constants";
4
+ import { CLICK_ID_PARAMS } from "../event/constants";
4
5
  export type AnonymousID = UUID;
5
6
  export interface ICommonProperties {
6
7
  anonymous_id: AnonymousID;
@@ -21,7 +22,10 @@ export type UTMParameters = {
21
22
  utm_term: string;
22
23
  utm_content: string;
23
24
  };
24
- export type ITrafficSource = UTMParameters & {
25
+ export type ClickIdParameters = {
26
+ [K in (typeof CLICK_ID_PARAMS)[number]]: string;
27
+ };
28
+ export type ITrafficSource = UTMParameters & ClickIdParameters & {
25
29
  ref: string;
26
30
  referrer: string;
27
31
  };
@@ -1,2 +1,2 @@
1
- export declare const version = "1.28.6";
1
+ export declare const version = "1.29.1";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
4
  // This file is auto-generated by scripts/update-version.js during npm version
5
5
  // Do not edit manually - it will be overwritten
6
- exports.version = '1.28.6';
6
+ exports.version = '1.29.1';
7
7
  //# sourceMappingURL=version.js.map
@@ -52,6 +52,12 @@ export declare class FormoAnalytics implements IFormoAnalytics {
52
52
  private isEvmDisabled;
53
53
  /** Instance-level flag so multiple SDK instances don't interfere. */
54
54
  private crossSubdomainCookies;
55
+ /** In-memory URL used to deduplicate SPA pageview events. */
56
+ private _currentUrl;
57
+ /** Page-hit hooks installed in trackPageHits() so cleanup() can undo them. */
58
+ private _onPopStateListener?;
59
+ private _onLocationChangeListener?;
60
+ private _pageHooksDisposed;
55
61
  config: Config;
56
62
  currentChainId?: ChainID;
57
63
  currentAddress?: Address;
@@ -270,6 +276,12 @@ export declare class FormoAnalytics implements IFormoAnalytics {
270
276
  private registerRequestListeners;
271
277
  private onLocationChange;
272
278
  private trackPageHits;
279
+ /**
280
+ * Wrap history.pushState / replaceState exactly once per `history` object,
281
+ * regardless of how many SDK instances are constructed. Uses a Symbol
282
+ * marker so we recognize our own wrapper across module reloads in HMR.
283
+ */
284
+ private static installHistoryHooksOnce;
273
285
  private trackPageHit;
274
286
  private trackEvent;
275
287
  /**
@@ -310,6 +322,15 @@ export declare class FormoAnalytics implements IFormoAnalytics {
310
322
  private getCurrentChainId;
311
323
  private buildSignatureEventPayload;
312
324
  private buildTransactionEventPayload;
325
+ /**
326
+ * Persist an EVM address discovered through autocapture (signature / transaction)
327
+ * as the current EVM address when none is currently set. This lets subsequent
328
+ * track()/page() calls carry the address even when the underlying wallet never
329
+ * fires an EIP-1193 `accountsChanged` event (embedded wallets, smart accounts,
330
+ * social-login wrappers). If `accountsChanged` later fires it overwrites this
331
+ * value in the normal way; existing connections are never clobbered.
332
+ */
333
+ private backfillActiveWallet;
313
334
  /**
314
335
  * Polls for transaction receipt and emits tx.status = CONFIRMED or REVERTED.
315
336
  */
@@ -365,6 +386,19 @@ export declare class FormoAnalytics implements IFormoAnalytics {
365
386
  * Last-connected-chain-wins: _activeNamespace takes precedence.
366
387
  */
367
388
  private syncDerivedState;
389
+ /**
390
+ * Persist (or clear) the current wallet snapshot in a cookie so that the
391
+ * SDK can repopulate `currentAddress`/`currentChainId` at init on the next
392
+ * page load — closing the gap between page-show and wagmi/EIP-1193
393
+ * reconnection during which track()/page() events would otherwise ship
394
+ * with an empty address.
395
+ */
396
+ private persistActiveWallet;
397
+ /**
398
+ * Seed `currentAddress`/`currentChainId` from the persisted snapshot, if
399
+ * any. Called once during construction before the first page hit fires.
400
+ */
401
+ private loadActiveWallet;
368
402
  /**
369
403
  * Helper method to clear the active provider state
370
404
  * Centralizes provider clearing logic for consistency