@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
@@ -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
@@ -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>;
@@ -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;
@@ -230,9 +231,14 @@ var EventFactory = /** @class */ (function () {
230
231
  EventFactory.prototype.getLocation = function () {
231
232
  try {
232
233
  var timezone = this.getTimezone();
233
- if (timezone in constants_1.COUNTRY_LIST)
234
- return constants_1.COUNTRY_LIST[timezone];
235
- 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
+ : "";
236
242
  }
237
243
  catch (error) {
238
244
  logger_1.logger.error("Error resolving location:", error);
@@ -413,12 +419,12 @@ var EventFactory = /** @class */ (function () {
413
419
  });
414
420
  });
415
421
  };
416
- EventFactory.prototype.generateSignatureEvent = function (status, chainId, address, message, signatureHash, properties, context) {
422
+ EventFactory.prototype.generateSignatureEvent = function (status, chainId, address, message, properties, context) {
417
423
  return __awaiter(this, void 0, void 0, function () {
418
424
  var signatureEvent;
419
425
  return __generator(this, function (_a) {
420
426
  signatureEvent = {
421
- properties: __assign(__assign({ status: status, chainId: chainId, message: message }, (signatureHash && { signatureHash: signatureHash })), properties),
427
+ properties: __assign({ status: status, chainId: chainId, message: message }, properties),
422
428
  address: address,
423
429
  type: "signature",
424
430
  };
@@ -506,7 +512,7 @@ var EventFactory = /** @class */ (function () {
506
512
  case 12:
507
513
  formoEvent = _b.sent();
508
514
  return [3 /*break*/, 19];
509
- case 13: return [4 /*yield*/, this.generateSignatureEvent(event.status, event.chainId, event.address, event.message, event.signatureHash, event.properties, event.context)];
515
+ case 13: return [4 /*yield*/, this.generateSignatureEvent(event.status, event.chainId, event.address, event.message, event.properties, event.context)];
510
516
  case 14:
511
517
  formoEvent = _b.sent();
512
518
  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
@@ -96,6 +96,10 @@ var EventManager = /** @class */ (function () {
96
96
  });
97
97
  });
98
98
  };
99
+ /** Drop any buffered events (consent withdrawal / teardown). */
100
+ EventManager.prototype.clear = function () {
101
+ this.eventQueue.clear();
102
+ };
99
103
  return EventManager;
100
104
  }());
101
105
  exports.EventManager = 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>;
@@ -26,7 +26,7 @@ var generateAnonymousId = function (key, crossSubdomainCookies) {
26
26
  // domain. Note: host-only cookies on other hosts (e.g. a cookie set on
27
27
  // example.com is not visible from app.example.com) cannot be migrated
28
28
  // until the user revisits that host.
29
- (0, storage_1.cookie)().set(key, anonymousId, __assign({ expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365).toUTCString(), path: "/" }, (domain ? { domain: domain } : {})));
29
+ (0, storage_1.cookie)().set(key, anonymousId, __assign(__assign({ expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365).toUTCString(), path: "/" }, (0, cookiePolicy_1.getIdentityCookieSecurity)()), (domain ? { domain: domain } : {})));
30
30
  return anonymousId;
31
31
  };
32
32
  exports.generateAnonymousId = 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
  /**
@@ -87,6 +87,7 @@ var EventQueue = /** @class */ (function () {
87
87
  function EventQueue(writeKey, options) {
88
88
  var _this = this;
89
89
  this.queue = [];
90
+ this.queueByteSize = 0; // running total of queued items' byteSize
90
91
  this.payloadHashes = new Set();
91
92
  this.onPageLeave = function (callback) {
92
93
  // To ensure the callback is only called once even if more than one events
@@ -142,6 +143,7 @@ var EventQueue = /** @class */ (function () {
142
143
  this.queue = [];
143
144
  this.writeKey = writeKey;
144
145
  this.apiHost = options.apiHost;
146
+ this.canSend = options.canSend;
145
147
  this.retryCount = (0, utils_1.clampNumber)(options.retryCount || DEFAULT_RETRY, MAX_RETRY, MIN_RETRY);
146
148
  this.flushAt = (0, utils_1.clampNumber)(options.flushAt || DEFAULT_FLUSH_AT, MAX_FLUSH_AT, MIN_FLUSH_AT);
147
149
  this.maxQueueSize = (0, utils_1.clampNumber)(options.maxQueueSize || DEFAULT_QUEUE_SIZE, MAX_QUEUE_SIZE, MIN_QUEUE_SIZE);
@@ -175,13 +177,31 @@ var EventQueue = /** @class */ (function () {
175
177
  });
176
178
  });
177
179
  };
180
+ /**
181
+ * Drop all queued data and cancel the flush timer. Called on consent
182
+ * withdrawal / SDK teardown so nothing buffered can be sent later.
183
+ */
184
+ EventQueue.prototype.clear = function () {
185
+ if (this.timer) {
186
+ clearTimeout(this.timer);
187
+ this.timer = null;
188
+ }
189
+ this.queue = [];
190
+ this.queueByteSize = 0;
191
+ this.payloadHashes.clear();
192
+ };
178
193
  EventQueue.prototype.enqueue = function (event, callback) {
179
194
  return __awaiter(this, void 0, void 0, function () {
180
- var message_id, hasReachedFlushAt, hasReachedQueueSize;
195
+ var message_id, queueItem, hasReachedFlushAt, hasReachedQueueSize;
181
196
  return __generator(this, function (_a) {
182
197
  switch (_a.label) {
183
198
  case 0:
184
199
  callback = callback || noop;
200
+ // Refuse to buffer anything once consent is withdrawn.
201
+ if (this.canSend && !this.canSend()) {
202
+ this.clear();
203
+ return [2 /*return*/];
204
+ }
185
205
  return [4 /*yield*/, this.generateMessageId(event)];
186
206
  case 1:
187
207
  message_id = _a.sent();
@@ -190,10 +210,18 @@ var EventQueue = /** @class */ (function () {
190
210
  logger_1.logger.warn("Event already enqueued, try again after ".concat((0, utils_1.millisecondsToSecond)(this.flushIntervalMs), " seconds."));
191
211
  return [2 /*return*/];
192
212
  }
193
- this.queue.push({
213
+ queueItem = {
194
214
  message: __assign(__assign({}, event), { message_id: message_id }),
195
215
  callback: callback,
196
- });
216
+ byteSize: 0,
217
+ };
218
+ // Measure once here (message only — JSON.stringify drops the
219
+ // callback function anyway), then track the total incrementally.
220
+ queueItem.byteSize = JSON.stringify({
221
+ message: queueItem.message,
222
+ }).length;
223
+ this.queue.push(queueItem);
224
+ this.queueByteSize += queueItem.byteSize;
197
225
  logger_1.logger.log("Event enqueued: ".concat((0, utils_1.getActionDescriptor)(event.type, event.properties)));
198
226
  if (!this.flushed) {
199
227
  this.flushed = true;
@@ -201,8 +229,7 @@ var EventQueue = /** @class */ (function () {
201
229
  return [2 /*return*/];
202
230
  }
203
231
  hasReachedFlushAt = this.queue.length >= this.flushAt;
204
- hasReachedQueueSize = this.queue.reduce(function (acc, item) { return acc + JSON.stringify(item).length; }, 0) >=
205
- this.maxQueueSize;
232
+ hasReachedQueueSize = this.queueByteSize >= this.maxQueueSize;
206
233
  if (hasReachedFlushAt || hasReachedQueueSize) {
207
234
  this.flush();
208
235
  return [2 /*return*/];
@@ -228,6 +255,13 @@ var EventQueue = /** @class */ (function () {
228
255
  clearTimeout(this.timer);
229
256
  this.timer = null;
230
257
  }
258
+ // Final consent gate: a timer/pagehide flush may have been scheduled
259
+ // before opt-out. Drop everything rather than send post-withdrawal.
260
+ if (this.canSend && !this.canSend()) {
261
+ this.clear();
262
+ callback();
263
+ return [2 /*return*/, Promise.resolve()];
264
+ }
231
265
  if (!this.queue.length) {
232
266
  callback();
233
267
  return [2 /*return*/, Promise.resolve()];
@@ -241,11 +275,17 @@ var EventQueue = /** @class */ (function () {
241
275
  case 2:
242
276
  items = this.queue.splice(0, drainAll ? this.queue.length : this.flushAt);
243
277
  // Only remove hashes for flushed items so duplicate detection remains
244
- // active for events still in the queue.
278
+ // active for events still in the queue. Also decrement the running
279
+ // byte total by exactly what left the queue.
245
280
  for (_i = 0, items_1 = items; _i < items_1.length; _i++) {
246
281
  item = items_1[_i];
247
282
  this.payloadHashes.delete(item.message.message_id);
283
+ this.queueByteSize -= item.byteSize;
248
284
  }
285
+ // Re-anchor to the exact invariant when the queue empties, so any
286
+ // accumulated drift can never wedge the size gate.
287
+ if (this.queue.length === 0)
288
+ this.queueByteSize = 0;
249
289
  sentAt = new Date().toISOString();
250
290
  data = items.map(function (item) { return (__assign(__assign({}, item.message), { sent_at: sentAt })); });
251
291
  batches = this.splitIntoBatches(items, data);
@@ -348,6 +388,12 @@ var EventQueue = /** @class */ (function () {
348
388
  case 1:
349
389
  if (!(_i < batches_1.length)) return [3 /*break*/, 6];
350
390
  batch = batches_1[_i];
391
+ // Consent can be withdrawn while a flush is already in flight:
392
+ // batches were spliced before opt-out, and split batches / retry
393
+ // backoff span seconds. Re-check before every send and abandon
394
+ // the remaining batches if consent was revoked mid-flush.
395
+ if (this.canSend && !this.canSend())
396
+ return [3 /*break*/, 6];
351
397
  _a.label = 2;
352
398
  case 2:
353
399
  _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
@@ -5,9 +5,21 @@
5
5
  * Handles tracking of detected wallets and identified wallet-address pairs
6
6
  * using cookies to maintain state across page loads within a session.
7
7
  */
8
+ var __assign = (this && this.__assign) || function () {
9
+ __assign = Object.assign || function(t) {
10
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
11
+ s = arguments[i];
12
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
13
+ t[p] = s[p];
14
+ }
15
+ return t;
16
+ };
17
+ return __assign.apply(this, arguments);
18
+ };
8
19
  Object.defineProperty(exports, "__esModule", { value: true });
9
20
  exports.FormoAnalyticsSession = exports.SESSION_WALLET_IDENTIFIED_KEY = exports.SESSION_WALLET_DETECTED_KEY = void 0;
10
21
  var storage_1 = require("../storage");
22
+ var cookiePolicy_1 = require("../storage/cookiePolicy");
11
23
  var logger_1 = require("../logger");
12
24
  /**
13
25
  * Cookie keys for session tracking
@@ -66,11 +78,9 @@ var FormoAnalyticsSession = /** @class */ (function () {
66
78
  if (rdnses.length > MAX_SESSION_ENTRIES) {
67
79
  rdnses.splice(0, rdnses.length - MAX_SESSION_ENTRIES);
68
80
  }
69
- (0, storage_1.cookie)().set(exports.SESSION_WALLET_DETECTED_KEY, rdnses.join(","), {
81
+ (0, storage_1.cookie)().set(exports.SESSION_WALLET_DETECTED_KEY, rdnses.join(","), __assign({
70
82
  // Expires by the end of the day
71
- expires: new Date(Date.now() + 86400 * 1000).toUTCString(),
72
- path: "/",
73
- });
83
+ expires: new Date(Date.now() + 86400 * 1000).toUTCString(), path: "/" }, (0, cookiePolicy_1.getIdentityCookieSecurity)()));
74
84
  }
75
85
  };
76
86
  /**
@@ -110,11 +120,9 @@ var FormoAnalyticsSession = /** @class */ (function () {
110
120
  identifiedWallets.splice(0, identifiedWallets.length - MAX_SESSION_ENTRIES);
111
121
  }
112
122
  var newValue = identifiedWallets.join(",");
113
- (0, storage_1.cookie)().set(exports.SESSION_WALLET_IDENTIFIED_KEY, newValue, {
123
+ (0, storage_1.cookie)().set(exports.SESSION_WALLET_IDENTIFIED_KEY, newValue, __assign({
114
124
  // Expires by the end of the day
115
- expires: new Date(Date.now() + 86400 * 1000).toUTCString(),
116
- path: "/",
117
- });
125
+ expires: new Date(Date.now() + 86400 * 1000).toUTCString(), path: "/" }, (0, cookiePolicy_1.getIdentityCookieSecurity)()));
118
126
  logger_1.logger.debug("Session: Marked wallet as identified", {
119
127
  identifiedKey: identifiedKey,
120
128
  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
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getIdentityCookieDomain = getIdentityCookieDomain;
4
+ exports.getIdentityCookieSecurity = getIdentityCookieSecurity;
4
5
  /**
5
6
  * Cookie domain policy — centralizes the decision of whether identity
6
7
  * cookies should be host-scoped or apex-scoped.
@@ -24,4 +25,22 @@ function getIdentityCookieDomain(crossSubdomain) {
24
25
  var domain = (0, domain_1.getApexDomain)();
25
26
  return domain ? ".".concat(domain) : "";
26
27
  }
28
+ /**
29
+ * Security attributes for identity/session cookies (user-id,
30
+ * active-wallet, wallet-detected/identified).
31
+ *
32
+ * - `sameSite: "lax"` — first-party analytics identity. Lax keeps the
33
+ * cookie on top-level navigations (so attribution survives a click-in
34
+ * from another site) while blocking it on cross-site subrequests.
35
+ * Strict would silently drop identity on inbound navigation.
36
+ * - `secure` — only on HTTPS. Setting Secure over plain HTTP (local dev)
37
+ * makes the browser reject the cookie outright, so it must be
38
+ * conditional.
39
+ */
40
+ function getIdentityCookieSecurity() {
41
+ var _a;
42
+ var isHttps = typeof window !== "undefined" &&
43
+ ((_a = window.location) === null || _a === void 0 ? void 0 : _a.protocol) === "https:";
44
+ return { sameSite: "lax", secure: isHttps };
45
+ }
27
46
  //# 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;