@formo/analytics 1.29.0 → 1.30.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.
Files changed (48) hide show
  1. package/dist/cjs/src/FormoAnalytics.d.ts +52 -3
  2. package/dist/cjs/src/FormoAnalytics.js +262 -51
  3. package/dist/cjs/src/constants/base.d.ts +9 -0
  4. package/dist/cjs/src/constants/base.js +10 -1
  5. package/dist/cjs/src/constants/config.d.ts +3 -58
  6. package/dist/cjs/src/constants/config.js +3 -73
  7. package/dist/cjs/src/event/EventFactory.d.ts +1 -1
  8. package/dist/cjs/src/event/EventFactory.js +12 -6
  9. package/dist/cjs/src/event/EventManager.d.ts +2 -0
  10. package/dist/cjs/src/event/EventManager.js +4 -0
  11. package/dist/cjs/src/event/type.d.ts +1 -0
  12. package/dist/cjs/src/event/utils.js +1 -1
  13. package/dist/cjs/src/queue/EventQueue.d.ts +8 -0
  14. package/dist/cjs/src/queue/EventQueue.js +52 -6
  15. package/dist/cjs/src/queue/type.d.ts +1 -0
  16. package/dist/cjs/src/session/index.js +16 -8
  17. package/dist/cjs/src/storage/cookiePolicy.d.ts +16 -0
  18. package/dist/cjs/src/storage/cookiePolicy.js +19 -0
  19. package/dist/cjs/src/types/base.d.ts +0 -1
  20. package/dist/cjs/src/types/events.d.ts +0 -1
  21. package/dist/cjs/src/version.d.ts +1 -1
  22. package/dist/cjs/src/version.js +1 -1
  23. package/dist/cjs/src/wagmi/WagmiEventHandler.js +38 -15
  24. package/dist/esm/src/FormoAnalytics.d.ts +52 -3
  25. package/dist/esm/src/FormoAnalytics.js +265 -54
  26. package/dist/esm/src/constants/base.d.ts +9 -0
  27. package/dist/esm/src/constants/base.js +9 -0
  28. package/dist/esm/src/constants/config.d.ts +3 -58
  29. package/dist/esm/src/constants/config.js +3 -73
  30. package/dist/esm/src/event/EventFactory.d.ts +1 -1
  31. package/dist/esm/src/event/EventFactory.js +12 -6
  32. package/dist/esm/src/event/EventManager.d.ts +2 -0
  33. package/dist/esm/src/event/EventManager.js +4 -0
  34. package/dist/esm/src/event/type.d.ts +1 -0
  35. package/dist/esm/src/event/utils.js +2 -2
  36. package/dist/esm/src/queue/EventQueue.d.ts +8 -0
  37. package/dist/esm/src/queue/EventQueue.js +52 -6
  38. package/dist/esm/src/queue/type.d.ts +1 -0
  39. package/dist/esm/src/session/index.js +16 -8
  40. package/dist/esm/src/storage/cookiePolicy.d.ts +16 -0
  41. package/dist/esm/src/storage/cookiePolicy.js +18 -0
  42. package/dist/esm/src/types/base.d.ts +0 -1
  43. package/dist/esm/src/types/events.d.ts +0 -1
  44. package/dist/esm/src/version.d.ts +1 -1
  45. package/dist/esm/src/version.js +1 -1
  46. package/dist/esm/src/wagmi/WagmiEventHandler.js +38 -15
  47. package/dist/index.umd.min.js +1 -1
  48. package/package.json +13 -23
@@ -186,7 +186,7 @@ export declare const COUNTRY_LIST: {
186
186
  readonly "America/Panama": "PA";
187
187
  readonly "America/Pangnirtung": "CA";
188
188
  readonly "America/Paramaribo": "SR";
189
- readonly "America/Phoenix": "US,CA";
189
+ readonly "America/Phoenix": "US";
190
190
  readonly "America/Port-au-Prince": "HT";
191
191
  readonly "America/Port_of_Spain": "TT";
192
192
  readonly "America/Porto_Acre": "BR";
@@ -289,6 +289,7 @@ export declare const COUNTRY_LIST: {
289
289
  readonly "Asia/Katmandu": "NP";
290
290
  readonly "Asia/Khandyga": "RU";
291
291
  readonly "Asia/Kolkata": "IN";
292
+ readonly "Asia/Kostanay": "KZ";
292
293
  readonly "Asia/Krasnoyarsk": "RU";
293
294
  readonly "Asia/Kuala_Lumpur": "MY";
294
295
  readonly "Asia/Kuching": "MY";
@@ -386,51 +387,11 @@ export declare const COUNTRY_LIST: {
386
387
  readonly "Canada/Pacific": "CA";
387
388
  readonly "Canada/Saskatchewan": "CA";
388
389
  readonly "Canada/Yukon": "CA";
389
- readonly CET: "CET";
390
390
  readonly "Chile/Continental": "CL";
391
391
  readonly "Chile/EasterIsland": "CL";
392
- readonly CST6CDT: "CST6CDT";
393
392
  readonly Cuba: "CU";
394
- readonly EET: "EET";
395
393
  readonly Egypt: "EG";
396
394
  readonly Eire: "IE";
397
- readonly EST: "EST";
398
- readonly EST5EDT: "EST5EDT";
399
- readonly "Etc/GMT": "Etc/GMT";
400
- readonly "Etc/GMT+0": "Etc/GMT+0";
401
- readonly "Etc/GMT+1": "Etc/GMT+1";
402
- readonly "Etc/GMT+10": "Etc/GMT+10";
403
- readonly "Etc/GMT+11": "Etc/GMT+11";
404
- readonly "Etc/GMT+12": "Etc/GMT+12";
405
- readonly "Etc/GMT+2": "Etc/GMT+2";
406
- readonly "Etc/GMT+3": "Etc/GMT+3";
407
- readonly "Etc/GMT+4": "Etc/GMT+4";
408
- readonly "Etc/GMT+5": "Etc/GMT+5";
409
- readonly "Etc/GMT+6": "Etc/GMT+6";
410
- readonly "Etc/GMT+7": "Etc/GMT+7";
411
- readonly "Etc/GMT+8": "Etc/GMT+8";
412
- readonly "Etc/GMT+9": "Etc/GMT+9";
413
- readonly "Etc/GMT-0": "Etc/GMT-0";
414
- readonly "Etc/GMT-1": "Etc/GMT-1";
415
- readonly "Etc/GMT-10": "Etc/GMT-10";
416
- readonly "Etc/GMT-11": "Etc/GMT-11";
417
- readonly "Etc/GMT-12": "Etc/GMT-12";
418
- readonly "Etc/GMT-13": "Etc/GMT-13";
419
- readonly "Etc/GMT-14": "Etc/GMT-14";
420
- readonly "Etc/GMT-2": "Etc/GMT-2";
421
- readonly "Etc/GMT-3": "Etc/GMT-3";
422
- readonly "Etc/GMT-4": "Etc/GMT-4";
423
- readonly "Etc/GMT-5": "Etc/GMT-5";
424
- readonly "Etc/GMT-6": "Etc/GMT-6";
425
- readonly "Etc/GMT-7": "Etc/GMT-7";
426
- readonly "Etc/GMT-8": "Etc/GMT-8";
427
- readonly "Etc/GMT-9": "Etc/GMT-9";
428
- readonly "Etc/GMT0": "Etc/GMT0";
429
- readonly "Etc/Greenwich": "Etc/Greenwich";
430
- readonly "Etc/UCT": "Etc/UCT";
431
- readonly "Etc/UTC": "Etc/UTC";
432
- readonly "Etc/Universal": "Etc/Universal";
433
- readonly "Etc/Zulu": "Etc/Zulu";
434
395
  readonly "Europe/Amsterdam": "NL";
435
396
  readonly "Europe/Andorra": "AD";
436
397
  readonly "Europe/Astrakhan": "RU";
@@ -495,16 +456,9 @@ export declare const COUNTRY_LIST: {
495
456
  readonly "Europe/Zagreb": "HR";
496
457
  readonly "Europe/Zaporozhye": "UA";
497
458
  readonly "Europe/Zurich": "CH";
498
- readonly Factory: "Factory";
499
459
  readonly GB: "GB";
500
460
  readonly "GB-Eire": "GB";
501
- readonly GMT: "GMT";
502
- readonly "GMT+0": "GMT+0";
503
- readonly "GMT-0": "GMT-0";
504
- readonly GMT0: "GMT0";
505
- readonly Greenwich: "Greenwich";
506
461
  readonly Hongkong: "HK";
507
- readonly HST: "HST";
508
462
  readonly Iceland: "IS";
509
463
  readonly "Indian/Antananarivo": "MG";
510
464
  readonly "Indian/Chagos": "IO";
@@ -523,12 +477,9 @@ export declare const COUNTRY_LIST: {
523
477
  readonly Japan: "JP";
524
478
  readonly Kwajalein: "MH";
525
479
  readonly Libya: "LY";
526
- readonly MET: "MET";
527
480
  readonly "Mexico/BajaNorte": "MX";
528
481
  readonly "Mexico/BajaSur": "MX";
529
482
  readonly "Mexico/General": "MX";
530
- readonly MST: "MST";
531
- readonly MST7MDT: "MST7MDT";
532
483
  readonly Navajo: "US";
533
484
  readonly NZ: "NZ";
534
485
  readonly "NZ-CHAT": "NZ";
@@ -546,7 +497,7 @@ export declare const COUNTRY_LIST: {
546
497
  readonly "Pacific/Galapagos": "EC";
547
498
  readonly "Pacific/Gambier": "PF";
548
499
  readonly "Pacific/Guadalcanal": "SB";
549
- readonly "Pacific/Guam": "GU,MP";
500
+ readonly "Pacific/Guam": "GU";
550
501
  readonly "Pacific/Honolulu": "US";
551
502
  readonly "Pacific/Johnston": "UM";
552
503
  readonly "Pacific/Kanton": "KI";
@@ -579,13 +530,10 @@ export declare const COUNTRY_LIST: {
579
530
  readonly Poland: "PL";
580
531
  readonly Portugal: "PT";
581
532
  readonly PRC: "CN";
582
- readonly PST8PDT: "PST8PDT";
583
533
  readonly ROC: "TW";
584
534
  readonly ROK: "KR";
585
535
  readonly Singapore: "SG";
586
536
  readonly Turkey: "TR";
587
- readonly UCT: "UCT";
588
- readonly Universal: "Universal";
589
537
  readonly "US/Alaska": "US";
590
538
  readonly "US/Aleutian": "US";
591
539
  readonly "US/Arizona": "US";
@@ -598,9 +546,6 @@ export declare const COUNTRY_LIST: {
598
546
  readonly "US/Mountain": "US";
599
547
  readonly "US/Pacific": "US";
600
548
  readonly "US/Samoa": "AS";
601
- readonly UTC: "UTC";
602
549
  readonly "W-SU": "RU";
603
- readonly WET: "WET";
604
- readonly Zulu: "Zulu";
605
550
  };
606
551
  //# sourceMappingURL=config.d.ts.map
@@ -188,7 +188,7 @@ export var COUNTRY_LIST = {
188
188
  "America/Panama": "PA",
189
189
  "America/Pangnirtung": "CA",
190
190
  "America/Paramaribo": "SR",
191
- "America/Phoenix": "US,CA",
191
+ "America/Phoenix": "US",
192
192
  "America/Port-au-Prince": "HT",
193
193
  "America/Port_of_Spain": "TT",
194
194
  "America/Porto_Acre": "BR",
@@ -294,6 +294,7 @@ export var COUNTRY_LIST = {
294
294
  "Asia/Katmandu": "NP",
295
295
  "Asia/Khandyga": "RU",
296
296
  "Asia/Kolkata": "IN",
297
+ "Asia/Kostanay": "KZ",
297
298
  "Asia/Krasnoyarsk": "RU",
298
299
  "Asia/Kuala_Lumpur": "MY",
299
300
  "Asia/Kuching": "MY",
@@ -395,59 +396,15 @@ export var COUNTRY_LIST = {
395
396
  "Canada/Pacific": "CA",
396
397
  "Canada/Saskatchewan": "CA",
397
398
  "Canada/Yukon": "CA",
398
- // CET
399
- CET: "CET",
400
399
  // Chile
401
400
  "Chile/Continental": "CL",
402
401
  "Chile/EasterIsland": "CL",
403
- // CST6CDT
404
- CST6CDT: "CST6CDT",
405
402
  // Cuba
406
403
  Cuba: "CU",
407
- // EET
408
- EET: "EET",
409
404
  // Egypt
410
405
  Egypt: "EG",
411
406
  // Eire
412
407
  Eire: "IE",
413
- // EST
414
- EST: "EST",
415
- EST5EDT: "EST5EDT",
416
- "Etc/GMT": "Etc/GMT",
417
- "Etc/GMT+0": "Etc/GMT+0",
418
- "Etc/GMT+1": "Etc/GMT+1",
419
- "Etc/GMT+10": "Etc/GMT+10",
420
- "Etc/GMT+11": "Etc/GMT+11",
421
- "Etc/GMT+12": "Etc/GMT+12",
422
- "Etc/GMT+2": "Etc/GMT+2",
423
- "Etc/GMT+3": "Etc/GMT+3",
424
- "Etc/GMT+4": "Etc/GMT+4",
425
- "Etc/GMT+5": "Etc/GMT+5",
426
- "Etc/GMT+6": "Etc/GMT+6",
427
- "Etc/GMT+7": "Etc/GMT+7",
428
- "Etc/GMT+8": "Etc/GMT+8",
429
- "Etc/GMT+9": "Etc/GMT+9",
430
- "Etc/GMT-0": "Etc/GMT-0",
431
- "Etc/GMT-1": "Etc/GMT-1",
432
- "Etc/GMT-10": "Etc/GMT-10",
433
- "Etc/GMT-11": "Etc/GMT-11",
434
- "Etc/GMT-12": "Etc/GMT-12",
435
- "Etc/GMT-13": "Etc/GMT-13",
436
- "Etc/GMT-14": "Etc/GMT-14",
437
- "Etc/GMT-2": "Etc/GMT-2",
438
- "Etc/GMT-3": "Etc/GMT-3",
439
- "Etc/GMT-4": "Etc/GMT-4",
440
- "Etc/GMT-5": "Etc/GMT-5",
441
- "Etc/GMT-6": "Etc/GMT-6",
442
- "Etc/GMT-7": "Etc/GMT-7",
443
- "Etc/GMT-8": "Etc/GMT-8",
444
- "Etc/GMT-9": "Etc/GMT-9",
445
- "Etc/GMT0": "Etc/GMT0",
446
- "Etc/Greenwich": "Etc/Greenwich",
447
- "Etc/UCT": "Etc/UCT",
448
- "Etc/UTC": "Etc/UTC",
449
- "Etc/Universal": "Etc/Universal",
450
- "Etc/Zulu": "Etc/Zulu",
451
408
  // Europe
452
409
  "Europe/Amsterdam": "NL",
453
410
  "Europe/Andorra": "AD",
@@ -513,21 +470,11 @@ export var COUNTRY_LIST = {
513
470
  "Europe/Zagreb": "HR",
514
471
  "Europe/Zaporozhye": "UA",
515
472
  "Europe/Zurich": "CH",
516
- // Factory
517
- Factory: "Factory",
518
473
  // GB
519
474
  GB: "GB",
520
475
  "GB-Eire": "GB",
521
- // GMT
522
- GMT: "GMT",
523
- "GMT+0": "GMT+0",
524
- "GMT-0": "GMT-0",
525
- GMT0: "GMT0",
526
- Greenwich: "Greenwich",
527
476
  // HK
528
477
  Hongkong: "HK",
529
- // HST
530
- HST: "HST",
531
478
  // Iceland
532
479
  Iceland: "IS",
533
480
  // Indian
@@ -554,15 +501,10 @@ export var COUNTRY_LIST = {
554
501
  Kwajalein: "MH",
555
502
  // Libya
556
503
  Libya: "LY",
557
- // MET
558
- MET: "MET",
559
504
  // Mexico
560
505
  "Mexico/BajaNorte": "MX",
561
506
  "Mexico/BajaSur": "MX",
562
507
  "Mexico/General": "MX",
563
- // MST
564
- MST: "MST",
565
- MST7MDT: "MST7MDT",
566
508
  // Navajo
567
509
  Navajo: "US",
568
510
  // NZ
@@ -583,7 +525,7 @@ export var COUNTRY_LIST = {
583
525
  "Pacific/Galapagos": "EC",
584
526
  "Pacific/Gambier": "PF",
585
527
  "Pacific/Guadalcanal": "SB",
586
- "Pacific/Guam": "GU,MP",
528
+ "Pacific/Guam": "GU",
587
529
  "Pacific/Honolulu": "US",
588
530
  "Pacific/Johnston": "UM",
589
531
  "Pacific/Kanton": "KI",
@@ -619,8 +561,6 @@ export var COUNTRY_LIST = {
619
561
  Portugal: "PT",
620
562
  // PRC
621
563
  PRC: "CN",
622
- // PST8PDT
623
- PST8PDT: "PST8PDT",
624
564
  // ROC
625
565
  ROC: "TW",
626
566
  // ROK
@@ -629,10 +569,6 @@ export var COUNTRY_LIST = {
629
569
  Singapore: "SG",
630
570
  // Turkey
631
571
  Turkey: "TR",
632
- // UCT
633
- UCT: "UCT",
634
- // Universal
635
- Universal: "Universal",
636
572
  // US
637
573
  "US/Alaska": "US",
638
574
  "US/Aleutian": "US",
@@ -646,13 +582,7 @@ export var COUNTRY_LIST = {
646
582
  "US/Mountain": "US",
647
583
  "US/Pacific": "US",
648
584
  "US/Samoa": "AS",
649
- // UTC
650
- UTC: "UTC",
651
585
  // W-SU
652
586
  "W-SU": "RU",
653
- // WET
654
- WET: "WET",
655
- // Zulu
656
- Zulu: "Zulu",
657
587
  };
658
588
  //# sourceMappingURL=config.js.map
@@ -35,7 +35,7 @@ declare class EventFactory implements IEventFactory {
35
35
  generateConnectEvent(chainId: ChainID, address: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
36
36
  generateDisconnectEvent(chainId?: ChainID, address?: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
37
37
  generateChainChangedEvent(chainId: ChainID, address: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
38
- generateSignatureEvent(status: SignatureStatus, chainId: ChainID, address: Address, message: string, signatureHash?: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
38
+ generateSignatureEvent(status: SignatureStatus, chainId: ChainID, address: Address, message: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
39
39
  generateTransactionEvent(status: TransactionStatus, chainId: ChainID, address: Address, data?: string, to?: string, value?: string, transactionHash?: string, function_name?: string, function_args?: Record<string, unknown>, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
40
40
  generateTrackEvent(event: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
41
41
  create(event: APIEvent, address?: Address, userId?: string): Promise<IFormoEvent>;
@@ -57,6 +57,7 @@ import { version } from "../version";
57
57
  import { CHANNEL, CLICK_ID_PARAMS, PAGE_PROPERTIES_EXCLUDED_FIELDS, VERSION, } from "./constants";
58
58
  import { generateAnonymousId } from "./utils";
59
59
  import { detectBrowser } from "../browser/browsers";
60
+ var ISO_3166_ALPHA_2_REGEX = /^[A-Z]{2}$/;
60
61
  var EventFactory = /** @class */ (function () {
61
62
  function EventFactory(options) {
62
63
  var _this = this;
@@ -224,9 +225,14 @@ var EventFactory = /** @class */ (function () {
224
225
  EventFactory.prototype.getLocation = function () {
225
226
  try {
226
227
  var timezone = this.getTimezone();
227
- if (timezone in COUNTRY_LIST)
228
- return COUNTRY_LIST[timezone];
229
- return timezone;
228
+ if (!timezone)
229
+ return "";
230
+ var mapped = COUNTRY_LIST[timezone];
231
+ // Only emit ISO-3166 alpha-2. Anything else (including the raw
232
+ // timezone string) is treated as unknown.
233
+ return typeof mapped === "string" && ISO_3166_ALPHA_2_REGEX.test(mapped)
234
+ ? mapped
235
+ : "";
230
236
  }
231
237
  catch (error) {
232
238
  logger.error("Error resolving location:", error);
@@ -407,12 +413,12 @@ var EventFactory = /** @class */ (function () {
407
413
  });
408
414
  });
409
415
  };
410
- EventFactory.prototype.generateSignatureEvent = function (status, chainId, address, message, signatureHash, properties, context) {
416
+ EventFactory.prototype.generateSignatureEvent = function (status, chainId, address, message, properties, context) {
411
417
  return __awaiter(this, void 0, void 0, function () {
412
418
  var signatureEvent;
413
419
  return __generator(this, function (_a) {
414
420
  signatureEvent = {
415
- properties: __assign(__assign({ status: status, chainId: chainId, message: message }, (signatureHash && { signatureHash: signatureHash })), properties),
421
+ properties: __assign({ status: status, chainId: chainId, message: message }, properties),
416
422
  address: address,
417
423
  type: "signature",
418
424
  };
@@ -500,7 +506,7 @@ var EventFactory = /** @class */ (function () {
500
506
  case 12:
501
507
  formoEvent = _b.sent();
502
508
  return [3 /*break*/, 19];
503
- case 13: return [4 /*yield*/, this.generateSignatureEvent(event.status, event.chainId, event.address, event.message, event.signatureHash, event.properties, event.context)];
509
+ case 13: return [4 /*yield*/, this.generateSignatureEvent(event.status, event.chainId, event.address, event.message, event.properties, event.context)];
504
510
  case 14:
505
511
  formoEvent = _b.sent();
506
512
  return [3 /*break*/, 19];
@@ -18,6 +18,8 @@ declare class EventManager implements IEventManager {
18
18
  * @param event Incoming event data
19
19
  */
20
20
  addEvent(event: APIEvent, address?: Address, userId?: string): Promise<void>;
21
+ /** Drop any buffered events (consent withdrawal / teardown). */
22
+ clear(): void;
21
23
  }
22
24
  export { EventManager };
23
25
  //# sourceMappingURL=EventManager.d.ts.map
@@ -93,6 +93,10 @@ var EventManager = /** @class */ (function () {
93
93
  });
94
94
  });
95
95
  };
96
+ /** Drop any buffered events (consent withdrawal / teardown). */
97
+ EventManager.prototype.clear = function () {
98
+ this.eventQueue.clear();
99
+ };
96
100
  return EventManager;
97
101
  }());
98
102
  export { EventManager };
@@ -1,6 +1,7 @@
1
1
  import { Address, APIEvent, IFormoEvent } from "../types";
2
2
  export interface IEventManager {
3
3
  addEvent(event: APIEvent, address?: Address, userId?: string): Promise<void>;
4
+ clear(): void;
4
5
  }
5
6
  export interface IEventFactory {
6
7
  create(event: APIEvent, address?: Address, userId?: string): Promise<IFormoEvent>;
@@ -11,7 +11,7 @@ var __assign = (this && this.__assign) || function () {
11
11
  };
12
12
  import { generateNativeUUID } from "../utils";
13
13
  import { cookie } from "../storage";
14
- import { getIdentityCookieDomain } from "../storage/cookiePolicy";
14
+ import { getIdentityCookieDomain, getIdentityCookieSecurity, } from "../storage/cookiePolicy";
15
15
  var generateAnonymousId = function (key, crossSubdomainCookies) {
16
16
  var storedAnonymousId = cookie().get(key);
17
17
  var anonymousId = (storedAnonymousId && typeof storedAnonymousId === "string"
@@ -23,7 +23,7 @@ var generateAnonymousId = function (key, crossSubdomainCookies) {
23
23
  // domain. Note: host-only cookies on other hosts (e.g. a cookie set on
24
24
  // example.com is not visible from app.example.com) cannot be migrated
25
25
  // until the user revisits that host.
26
- cookie().set(key, anonymousId, __assign({ expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365).toUTCString(), path: "/" }, (domain ? { domain: domain } : {})));
26
+ cookie().set(key, anonymousId, __assign(__assign({ expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365).toUTCString(), path: "/" }, getIdentityCookieSecurity()), (domain ? { domain: domain } : {})));
27
27
  return anonymousId;
28
28
  };
29
29
  export { generateAnonymousId };
@@ -11,6 +11,7 @@ type Options = {
11
11
  retryCount?: number;
12
12
  errorHandler?: any;
13
13
  maxQueueSize?: number;
14
+ canSend?: () => boolean;
14
15
  };
15
16
  export declare class EventQueue implements IEventQueue {
16
17
  private writeKey;
@@ -21,12 +22,19 @@ export declare class EventQueue implements IEventQueue {
21
22
  private flushIntervalMs;
22
23
  private flushed;
23
24
  private maxQueueSize;
25
+ private queueByteSize;
24
26
  private errorHandler;
25
27
  private retryCount;
26
28
  private pendingFlush;
27
29
  private payloadHashes;
30
+ private canSend?;
28
31
  constructor(writeKey: string, options: Options);
29
32
  private generateMessageId;
33
+ /**
34
+ * Drop all queued data and cancel the flush timer. Called on consent
35
+ * withdrawal / SDK teardown so nothing buffered can be sent later.
36
+ */
37
+ clear(): void;
30
38
  enqueue(event: IFormoEvent, callback?: (...args: any) => void): Promise<void>;
31
39
  flush(callback?: (...args: any) => void, drainAll?: boolean): Promise<void | IFormoEventFlushPayload[]>;
32
40
  /**
@@ -81,6 +81,7 @@ var EventQueue = /** @class */ (function () {
81
81
  function EventQueue(writeKey, options) {
82
82
  var _this = this;
83
83
  this.queue = [];
84
+ this.queueByteSize = 0; // running total of queued items' byteSize
84
85
  this.payloadHashes = new Set();
85
86
  this.onPageLeave = function (callback) {
86
87
  // To ensure the callback is only called once even if more than one events
@@ -136,6 +137,7 @@ var EventQueue = /** @class */ (function () {
136
137
  this.queue = [];
137
138
  this.writeKey = writeKey;
138
139
  this.apiHost = options.apiHost;
140
+ this.canSend = options.canSend;
139
141
  this.retryCount = clampNumber(options.retryCount || DEFAULT_RETRY, MAX_RETRY, MIN_RETRY);
140
142
  this.flushAt = clampNumber(options.flushAt || DEFAULT_FLUSH_AT, MAX_FLUSH_AT, MIN_FLUSH_AT);
141
143
  this.maxQueueSize = clampNumber(options.maxQueueSize || DEFAULT_QUEUE_SIZE, MAX_QUEUE_SIZE, MIN_QUEUE_SIZE);
@@ -169,13 +171,31 @@ var EventQueue = /** @class */ (function () {
169
171
  });
170
172
  });
171
173
  };
174
+ /**
175
+ * Drop all queued data and cancel the flush timer. Called on consent
176
+ * withdrawal / SDK teardown so nothing buffered can be sent later.
177
+ */
178
+ EventQueue.prototype.clear = function () {
179
+ if (this.timer) {
180
+ clearTimeout(this.timer);
181
+ this.timer = null;
182
+ }
183
+ this.queue = [];
184
+ this.queueByteSize = 0;
185
+ this.payloadHashes.clear();
186
+ };
172
187
  EventQueue.prototype.enqueue = function (event, callback) {
173
188
  return __awaiter(this, void 0, void 0, function () {
174
- var message_id, hasReachedFlushAt, hasReachedQueueSize;
189
+ var message_id, queueItem, hasReachedFlushAt, hasReachedQueueSize;
175
190
  return __generator(this, function (_a) {
176
191
  switch (_a.label) {
177
192
  case 0:
178
193
  callback = callback || noop;
194
+ // Refuse to buffer anything once consent is withdrawn.
195
+ if (this.canSend && !this.canSend()) {
196
+ this.clear();
197
+ return [2 /*return*/];
198
+ }
179
199
  return [4 /*yield*/, this.generateMessageId(event)];
180
200
  case 1:
181
201
  message_id = _a.sent();
@@ -184,10 +204,18 @@ var EventQueue = /** @class */ (function () {
184
204
  logger.warn("Event already enqueued, try again after ".concat(millisecondsToSecond(this.flushIntervalMs), " seconds."));
185
205
  return [2 /*return*/];
186
206
  }
187
- this.queue.push({
207
+ queueItem = {
188
208
  message: __assign(__assign({}, event), { message_id: message_id }),
189
209
  callback: callback,
190
- });
210
+ byteSize: 0,
211
+ };
212
+ // Measure once here (message only — JSON.stringify drops the
213
+ // callback function anyway), then track the total incrementally.
214
+ queueItem.byteSize = JSON.stringify({
215
+ message: queueItem.message,
216
+ }).length;
217
+ this.queue.push(queueItem);
218
+ this.queueByteSize += queueItem.byteSize;
191
219
  logger.log("Event enqueued: ".concat(getActionDescriptor(event.type, event.properties)));
192
220
  if (!this.flushed) {
193
221
  this.flushed = true;
@@ -195,8 +223,7 @@ var EventQueue = /** @class */ (function () {
195
223
  return [2 /*return*/];
196
224
  }
197
225
  hasReachedFlushAt = this.queue.length >= this.flushAt;
198
- hasReachedQueueSize = this.queue.reduce(function (acc, item) { return acc + JSON.stringify(item).length; }, 0) >=
199
- this.maxQueueSize;
226
+ hasReachedQueueSize = this.queueByteSize >= this.maxQueueSize;
200
227
  if (hasReachedFlushAt || hasReachedQueueSize) {
201
228
  this.flush();
202
229
  return [2 /*return*/];
@@ -222,6 +249,13 @@ var EventQueue = /** @class */ (function () {
222
249
  clearTimeout(this.timer);
223
250
  this.timer = null;
224
251
  }
252
+ // Final consent gate: a timer/pagehide flush may have been scheduled
253
+ // before opt-out. Drop everything rather than send post-withdrawal.
254
+ if (this.canSend && !this.canSend()) {
255
+ this.clear();
256
+ callback();
257
+ return [2 /*return*/, Promise.resolve()];
258
+ }
225
259
  if (!this.queue.length) {
226
260
  callback();
227
261
  return [2 /*return*/, Promise.resolve()];
@@ -235,11 +269,17 @@ var EventQueue = /** @class */ (function () {
235
269
  case 2:
236
270
  items = this.queue.splice(0, drainAll ? this.queue.length : this.flushAt);
237
271
  // Only remove hashes for flushed items so duplicate detection remains
238
- // active for events still in the queue.
272
+ // active for events still in the queue. Also decrement the running
273
+ // byte total by exactly what left the queue.
239
274
  for (_i = 0, items_1 = items; _i < items_1.length; _i++) {
240
275
  item = items_1[_i];
241
276
  this.payloadHashes.delete(item.message.message_id);
277
+ this.queueByteSize -= item.byteSize;
242
278
  }
279
+ // Re-anchor to the exact invariant when the queue empties, so any
280
+ // accumulated drift can never wedge the size gate.
281
+ if (this.queue.length === 0)
282
+ this.queueByteSize = 0;
243
283
  sentAt = new Date().toISOString();
244
284
  data = items.map(function (item) { return (__assign(__assign({}, item.message), { sent_at: sentAt })); });
245
285
  batches = this.splitIntoBatches(items, data);
@@ -342,6 +382,12 @@ var EventQueue = /** @class */ (function () {
342
382
  case 1:
343
383
  if (!(_i < batches_1.length)) return [3 /*break*/, 6];
344
384
  batch = batches_1[_i];
385
+ // Consent can be withdrawn while a flush is already in flight:
386
+ // batches were spliced before opt-out, and split batches / retry
387
+ // backoff span seconds. Re-check before every send and abandon
388
+ // the remaining batches if consent was revoked mid-flush.
389
+ if (this.canSend && !this.canSend())
390
+ return [3 /*break*/, 6];
345
391
  _a.label = 2;
346
392
  case 2:
347
393
  _a.trys.push([2, 4, , 5]);
@@ -2,5 +2,6 @@ import { IFormoEvent } from "../types";
2
2
  export interface IEventQueue {
3
3
  enqueue(event: IFormoEvent, callback?: (...args: any) => void): Promise<void>;
4
4
  flush(callback?: (...args: any) => void): Promise<any>;
5
+ clear(): void;
5
6
  }
6
7
  //# sourceMappingURL=type.d.ts.map
@@ -4,7 +4,19 @@
4
4
  * Handles tracking of detected wallets and identified wallet-address pairs
5
5
  * using cookies to maintain state across page loads within a session.
6
6
  */
7
+ var __assign = (this && this.__assign) || function () {
8
+ __assign = Object.assign || function(t) {
9
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
10
+ s = arguments[i];
11
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
12
+ t[p] = s[p];
13
+ }
14
+ return t;
15
+ };
16
+ return __assign.apply(this, arguments);
17
+ };
7
18
  import { cookie } from "../storage";
19
+ import { getIdentityCookieSecurity } from "../storage/cookiePolicy";
8
20
  import { logger } from "../logger";
9
21
  /**
10
22
  * Cookie keys for session tracking
@@ -63,11 +75,9 @@ var FormoAnalyticsSession = /** @class */ (function () {
63
75
  if (rdnses.length > MAX_SESSION_ENTRIES) {
64
76
  rdnses.splice(0, rdnses.length - MAX_SESSION_ENTRIES);
65
77
  }
66
- cookie().set(SESSION_WALLET_DETECTED_KEY, rdnses.join(","), {
78
+ cookie().set(SESSION_WALLET_DETECTED_KEY, rdnses.join(","), __assign({
67
79
  // Expires by the end of the day
68
- expires: new Date(Date.now() + 86400 * 1000).toUTCString(),
69
- path: "/",
70
- });
80
+ expires: new Date(Date.now() + 86400 * 1000).toUTCString(), path: "/" }, getIdentityCookieSecurity()));
71
81
  }
72
82
  };
73
83
  /**
@@ -107,11 +117,9 @@ var FormoAnalyticsSession = /** @class */ (function () {
107
117
  identifiedWallets.splice(0, identifiedWallets.length - MAX_SESSION_ENTRIES);
108
118
  }
109
119
  var newValue = identifiedWallets.join(",");
110
- cookie().set(SESSION_WALLET_IDENTIFIED_KEY, newValue, {
120
+ cookie().set(SESSION_WALLET_IDENTIFIED_KEY, newValue, __assign({
111
121
  // Expires by the end of the day
112
- expires: new Date(Date.now() + 86400 * 1000).toUTCString(),
113
- path: "/",
114
- });
122
+ expires: new Date(Date.now() + 86400 * 1000).toUTCString(), path: "/" }, getIdentityCookieSecurity()));
115
123
  logger.debug("Session: Marked wallet as identified", {
116
124
  identifiedKey: identifiedKey,
117
125
  hasRdns: !!rdns,
@@ -7,4 +7,20 @@
7
7
  * @param crossSubdomain Whether cookies should be shared across subdomains.
8
8
  */
9
9
  export declare function getIdentityCookieDomain(crossSubdomain?: boolean): string;
10
+ /**
11
+ * Security attributes for identity/session cookies (user-id,
12
+ * active-wallet, wallet-detected/identified).
13
+ *
14
+ * - `sameSite: "lax"` — first-party analytics identity. Lax keeps the
15
+ * cookie on top-level navigations (so attribution survives a click-in
16
+ * from another site) while blocking it on cross-site subrequests.
17
+ * Strict would silently drop identity on inbound navigation.
18
+ * - `secure` — only on HTTPS. Setting Secure over plain HTTP (local dev)
19
+ * makes the browser reject the cookie outright, so it must be
20
+ * conditional.
21
+ */
22
+ export declare function getIdentityCookieSecurity(): {
23
+ sameSite: "lax";
24
+ secure: boolean;
25
+ };
10
26
  //# sourceMappingURL=cookiePolicy.d.ts.map
@@ -21,4 +21,22 @@ export function getIdentityCookieDomain(crossSubdomain) {
21
21
  var domain = getApexDomain();
22
22
  return domain ? ".".concat(domain) : "";
23
23
  }
24
+ /**
25
+ * Security attributes for identity/session cookies (user-id,
26
+ * active-wallet, wallet-detected/identified).
27
+ *
28
+ * - `sameSite: "lax"` — first-party analytics identity. Lax keeps the
29
+ * cookie on top-level navigations (so attribution survives a click-in
30
+ * from another site) while blocking it on cross-site subrequests.
31
+ * Strict would silently drop identity on inbound navigation.
32
+ * - `secure` — only on HTTPS. Setting Secure over plain HTTP (local dev)
33
+ * makes the browser reject the cookie outright, so it must be
34
+ * conditional.
35
+ */
36
+ export function getIdentityCookieSecurity() {
37
+ var _a;
38
+ var isHttps = typeof window !== "undefined" &&
39
+ ((_a = window.location) === null || _a === void 0 ? void 0 : _a.protocol) === "https:";
40
+ return { sameSite: "lax", secure: isHttps };
41
+ }
24
42
  //# sourceMappingURL=cookiePolicy.js.map
@@ -40,7 +40,6 @@ export interface IFormoAnalytics {
40
40
  chainId?: ChainID;
41
41
  address: Address;
42
42
  message: string;
43
- signatureHash?: string;
44
43
  }, properties?: IFormoEventProperties, context?: IFormoEventContext, callback?: (...args: unknown[]) => void): Promise<void>;
45
44
  transaction(params: {
46
45
  status: TransactionStatus;