@formo/analytics 1.16.7 → 1.16.8

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 (132) hide show
  1. package/dist/cjs/src/FormoAnalytics.d.ts +5 -48
  2. package/dist/cjs/src/FormoAnalytics.d.ts.map +1 -1
  3. package/dist/cjs/src/FormoAnalytics.js +41 -21
  4. package/dist/cjs/src/FormoAnalytics.js.map +1 -1
  5. package/dist/cjs/src/FormoAnalyticsProvider.d.ts +3 -4
  6. package/dist/cjs/src/FormoAnalyticsProvider.d.ts.map +1 -1
  7. package/dist/cjs/src/FormoAnalyticsProvider.js +14 -2
  8. package/dist/cjs/src/FormoAnalyticsProvider.js.map +1 -1
  9. package/dist/cjs/src/constants/base.d.ts +5 -4
  10. package/dist/cjs/src/constants/base.d.ts.map +1 -1
  11. package/dist/cjs/src/constants/base.js +6 -7
  12. package/dist/cjs/src/constants/base.js.map +1 -1
  13. package/dist/cjs/src/constants/config.d.ts.map +1 -1
  14. package/dist/cjs/src/lib/event/EventFactory.d.ts +4 -1
  15. package/dist/cjs/src/lib/event/EventFactory.d.ts.map +1 -1
  16. package/dist/cjs/src/lib/event/EventFactory.js +52 -10
  17. package/dist/cjs/src/lib/event/EventFactory.js.map +1 -1
  18. package/dist/cjs/src/lib/event/EventManager.d.ts +2 -1
  19. package/dist/cjs/src/lib/event/EventManager.d.ts.map +1 -1
  20. package/dist/cjs/src/lib/event/EventManager.js +2 -2
  21. package/dist/cjs/src/lib/event/EventManager.js.map +1 -1
  22. package/dist/cjs/src/lib/event/utils.d.ts +1 -1
  23. package/dist/cjs/src/lib/event/utils.d.ts.map +1 -1
  24. package/dist/cjs/src/lib/event/utils.js +3 -4
  25. package/dist/cjs/src/lib/event/utils.js.map +1 -1
  26. package/dist/cjs/src/lib/ramda/internal/_curry1.d.ts.map +1 -1
  27. package/dist/cjs/src/lib/ramda/internal/_curry2.d.ts.map +1 -1
  28. package/dist/cjs/src/lib/ramda/internal/_curry3.d.ts.map +1 -1
  29. package/dist/cjs/src/lib/storage/index.d.ts +2 -0
  30. package/dist/cjs/src/lib/storage/index.d.ts.map +1 -1
  31. package/dist/cjs/src/lib/storage/index.js +18 -1
  32. package/dist/cjs/src/lib/storage/index.js.map +1 -1
  33. package/dist/cjs/src/lib/storage/key.d.ts +9 -0
  34. package/dist/cjs/src/lib/storage/key.d.ts.map +1 -0
  35. package/dist/cjs/src/lib/storage/key.js +15 -0
  36. package/dist/cjs/src/lib/storage/key.js.map +1 -0
  37. package/dist/cjs/src/lib/storage/native.js +1 -1
  38. package/dist/cjs/src/lib/storage/native.js.map +1 -1
  39. package/dist/cjs/src/lib/storage/type.d.ts +4 -0
  40. package/dist/cjs/src/lib/storage/type.d.ts.map +1 -0
  41. package/dist/cjs/src/lib/storage/type.js +3 -0
  42. package/dist/cjs/src/lib/storage/type.js.map +1 -0
  43. package/dist/cjs/src/lib/version.d.ts +1 -1
  44. package/dist/cjs/src/lib/version.js +1 -1
  45. package/dist/cjs/src/types/base.d.ts +44 -0
  46. package/dist/cjs/src/types/base.d.ts.map +1 -1
  47. package/dist/cjs/src/types/events.d.ts +11 -1
  48. package/dist/cjs/src/types/events.d.ts.map +1 -1
  49. package/dist/cjs/src/types/events.js.map +1 -1
  50. package/dist/cjs/src/utils/address.d.ts.map +1 -1
  51. package/dist/cjs/src/utils/base.d.ts.map +1 -1
  52. package/dist/cjs/src/utils/converter.d.ts.map +1 -1
  53. package/dist/cjs/src/utils/timestamp.d.ts.map +1 -1
  54. package/dist/cjs/src/validators/address.d.ts.map +1 -1
  55. package/dist/cjs/src/validators/checks.d.ts.map +1 -1
  56. package/dist/cjs/src/validators/object.d.ts.map +1 -1
  57. package/dist/cjs/src/validators/string.d.ts.map +1 -1
  58. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  59. package/dist/esm/src/FormoAnalytics.d.ts +5 -48
  60. package/dist/esm/src/FormoAnalytics.d.ts.map +1 -1
  61. package/dist/esm/src/FormoAnalytics.js +42 -22
  62. package/dist/esm/src/FormoAnalytics.js.map +1 -1
  63. package/dist/esm/src/FormoAnalyticsProvider.d.ts +3 -4
  64. package/dist/esm/src/FormoAnalyticsProvider.d.ts.map +1 -1
  65. package/dist/esm/src/FormoAnalyticsProvider.js +15 -3
  66. package/dist/esm/src/FormoAnalyticsProvider.js.map +1 -1
  67. package/dist/esm/src/constants/base.d.ts +5 -4
  68. package/dist/esm/src/constants/base.d.ts.map +1 -1
  69. package/dist/esm/src/constants/base.js +5 -6
  70. package/dist/esm/src/constants/base.js.map +1 -1
  71. package/dist/esm/src/constants/config.d.ts.map +1 -1
  72. package/dist/esm/src/lib/event/EventFactory.d.ts +4 -1
  73. package/dist/esm/src/lib/event/EventFactory.d.ts.map +1 -1
  74. package/dist/esm/src/lib/event/EventFactory.js +54 -12
  75. package/dist/esm/src/lib/event/EventFactory.js.map +1 -1
  76. package/dist/esm/src/lib/event/EventManager.d.ts +2 -1
  77. package/dist/esm/src/lib/event/EventManager.d.ts.map +1 -1
  78. package/dist/esm/src/lib/event/EventManager.js +2 -2
  79. package/dist/esm/src/lib/event/EventManager.js.map +1 -1
  80. package/dist/esm/src/lib/event/utils.d.ts +1 -1
  81. package/dist/esm/src/lib/event/utils.d.ts.map +1 -1
  82. package/dist/esm/src/lib/event/utils.js +3 -4
  83. package/dist/esm/src/lib/event/utils.js.map +1 -1
  84. package/dist/esm/src/lib/ramda/internal/_curry1.d.ts.map +1 -1
  85. package/dist/esm/src/lib/ramda/internal/_curry2.d.ts.map +1 -1
  86. package/dist/esm/src/lib/ramda/internal/_curry3.d.ts.map +1 -1
  87. package/dist/esm/src/lib/storage/index.d.ts +2 -0
  88. package/dist/esm/src/lib/storage/index.d.ts.map +1 -1
  89. package/dist/esm/src/lib/storage/index.js +2 -0
  90. package/dist/esm/src/lib/storage/index.js.map +1 -1
  91. package/dist/esm/src/lib/storage/key.d.ts +9 -0
  92. package/dist/esm/src/lib/storage/key.d.ts.map +1 -0
  93. package/dist/esm/src/lib/storage/key.js +12 -0
  94. package/dist/esm/src/lib/storage/key.js.map +1 -0
  95. package/dist/esm/src/lib/storage/native.js +1 -1
  96. package/dist/esm/src/lib/storage/native.js.map +1 -1
  97. package/dist/esm/src/lib/storage/type.d.ts +4 -0
  98. package/dist/esm/src/lib/storage/type.d.ts.map +1 -0
  99. package/dist/esm/src/lib/storage/type.js +2 -0
  100. package/dist/esm/src/lib/storage/type.js.map +1 -0
  101. package/dist/esm/src/lib/version.d.ts +1 -1
  102. package/dist/esm/src/lib/version.js +1 -1
  103. package/dist/esm/src/types/base.d.ts +44 -0
  104. package/dist/esm/src/types/base.d.ts.map +1 -1
  105. package/dist/esm/src/types/events.d.ts +11 -1
  106. package/dist/esm/src/types/events.d.ts.map +1 -1
  107. package/dist/esm/src/types/events.js.map +1 -1
  108. package/dist/esm/src/utils/address.d.ts.map +1 -1
  109. package/dist/esm/src/utils/base.d.ts.map +1 -1
  110. package/dist/esm/src/utils/converter.d.ts.map +1 -1
  111. package/dist/esm/src/utils/timestamp.d.ts.map +1 -1
  112. package/dist/esm/src/validators/address.d.ts.map +1 -1
  113. package/dist/esm/src/validators/checks.d.ts.map +1 -1
  114. package/dist/esm/src/validators/object.d.ts.map +1 -1
  115. package/dist/esm/src/validators/string.d.ts.map +1 -1
  116. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  117. package/dist/index.umd.min.js +1 -1
  118. package/dist/index.umd.min.js.map +1 -1
  119. package/package.json +1 -1
  120. package/src/FormoAnalytics.ts +82 -116
  121. package/src/FormoAnalyticsProvider.tsx +18 -6
  122. package/src/constants/base.ts +5 -12
  123. package/src/lib/event/EventFactory.ts +89 -15
  124. package/src/lib/event/EventManager.ts +3 -2
  125. package/src/lib/event/utils.ts +3 -4
  126. package/src/lib/storage/index.ts +2 -0
  127. package/src/lib/storage/key.ts +16 -0
  128. package/src/lib/storage/native.ts +1 -1
  129. package/src/lib/storage/type.ts +3 -0
  130. package/src/lib/version.ts +1 -1
  131. package/src/types/base.ts +83 -0
  132. package/src/types/events.ts +11 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formo/analytics",
3
- "version": "1.16.7",
3
+ "version": "1.16.8",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/getformo/sdk.git"
@@ -12,16 +12,19 @@ import {
12
12
  EventManager,
13
13
  EventQueue,
14
14
  IEventManager,
15
+ IStorageKeyManager,
15
16
  local,
16
17
  logger,
17
18
  Logger,
18
19
  session,
20
+ StorageKey,
19
21
  } from "./lib";
20
22
  import {
21
23
  Address,
22
24
  ChainID,
23
25
  Config,
24
26
  EIP1193Provider,
27
+ IFormoAnalytics,
25
28
  IFormoEventContext,
26
29
  IFormoEventProperties,
27
30
  Options,
@@ -32,94 +35,17 @@ import {
32
35
  } from "./types";
33
36
  import { isAddress, isLocalhost } from "./validators";
34
37
 
35
- interface IFormoAnalytics {
36
- page(
37
- category?: string,
38
- name?: string,
39
- properties?: IFormoEventProperties,
40
- context?: IFormoEventContext,
41
- callback?: (...args: unknown[]) => void
42
- ): void;
43
- reset(): void;
44
- detect(
45
- params: { rdns: string; providerName: string },
46
- properties?: IFormoEventProperties,
47
- context?: IFormoEventContext,
48
- callback?: (...args: unknown[]) => void
49
- ): Promise<void>;
50
- connect(
51
- params: { chainId: ChainID; address: Address },
52
- properties?: IFormoEventProperties,
53
- context?: IFormoEventContext,
54
- callback?: (...args: unknown[]) => void
55
- ): Promise<void>;
56
- disconnect(
57
- params?: { chainId?: ChainID; address?: Address },
58
- properties?: IFormoEventProperties,
59
- context?: IFormoEventContext,
60
- callback?: (...args: unknown[]) => void
61
- ): Promise<void>;
62
- chain(
63
- params: { chainId: ChainID; address?: Address },
64
- properties?: IFormoEventProperties,
65
- context?: IFormoEventContext,
66
- callback?: (...args: unknown[]) => void
67
- ): Promise<void>;
68
- signature(
69
- params: {
70
- status: SignatureStatus;
71
- chainId?: ChainID;
72
- address: Address;
73
- message: string;
74
- signatureHash?: string;
75
- },
76
- properties?: IFormoEventProperties,
77
- context?: IFormoEventContext,
78
- callback?: (...args: unknown[]) => void
79
- ): Promise<void>;
80
- transaction(
81
- params: {
82
- status: TransactionStatus;
83
- chainId: ChainID;
84
- address: Address;
85
- data?: string;
86
- to?: string;
87
- value?: string;
88
- transactionHash?: string;
89
- },
90
- properties?: IFormoEventProperties,
91
- context?: IFormoEventContext,
92
- callback?: (...args: unknown[]) => void
93
- ): Promise<void>;
94
- identify(
95
- params: {
96
- address: Address;
97
- providerName?: string;
98
- userId?: string;
99
- rdns?: string;
100
- },
101
- properties?: IFormoEventProperties,
102
- context?: IFormoEventContext,
103
- callback?: (...args: unknown[]) => void
104
- ): Promise<void>;
105
- track(
106
- event: string,
107
- properties?: IFormoEventProperties,
108
- context?: IFormoEventContext,
109
- callback?: (...args: unknown[]) => void
110
- ): Promise<void>;
111
- }
112
-
113
38
  export class FormoAnalytics implements IFormoAnalytics {
114
39
  private _provider?: EIP1193Provider;
115
40
  private _providerListeners: Record<string, (...args: unknown[]) => void> = {};
116
41
  private session: FormoAnalyticsSession;
117
42
  private eventManager: IEventManager;
43
+ private storageKeyManager: IStorageKeyManager;
118
44
 
119
45
  config: Config;
120
46
  currentChainId?: ChainID;
121
- currentAddress?: Address;
122
- currentUserId?: string;
47
+ currentAddress?: Address = "";
48
+ currentUserId?: string = "";
123
49
 
124
50
  private constructor(
125
51
  public readonly writeKey: string,
@@ -130,9 +56,22 @@ export class FormoAnalytics implements IFormoAnalytics {
130
56
  trackLocalhost: options.trackLocalhost || false,
131
57
  };
132
58
 
133
- this.session = new FormoAnalyticsSession();
59
+ this.storageKeyManager = new StorageKey(this.config.writeKey);
60
+
61
+ this.session = new FormoAnalyticsSession(this.storageKeyManager);
134
62
  this.currentUserId =
135
- (session.get(SESSION_USER_ID_KEY) as string) || undefined;
63
+ (session.get(
64
+ this.storageKeyManager.getKey(SESSION_USER_ID_KEY)
65
+ ) as string) || undefined;
66
+
67
+ this.identify = this.identify.bind(this);
68
+ this.connect = this.connect.bind(this);
69
+ this.disconnect = this.disconnect.bind(this);
70
+ this.chain = this.chain.bind(this);
71
+ this.signature = this.signature.bind(this);
72
+ this.transaction = this.transaction.bind(this);
73
+ this.detect = this.detect.bind(this);
74
+ this.track = this.track.bind(this);
136
75
 
137
76
  // Initialize logger with configuration from options
138
77
  Logger.init({
@@ -147,7 +86,8 @@ export class FormoAnalytics implements IFormoAnalytics {
147
86
  retryCount: options.retryCount,
148
87
  maxQueueSize: options.maxQueueSize,
149
88
  flushInterval: options.flushInterval,
150
- })
89
+ }),
90
+ this.storageKeyManager
151
91
  );
152
92
 
153
93
  // TODO: replace with eip6963
@@ -200,8 +140,8 @@ export class FormoAnalytics implements IFormoAnalytics {
200
140
  */
201
141
  public reset(): void {
202
142
  this.currentUserId = undefined;
203
- local.remove(LOCAL_ANONYMOUS_ID_KEY);
204
- session.remove(SESSION_USER_ID_KEY);
143
+ local.remove(this.storageKeyManager.getKey(LOCAL_ANONYMOUS_ID_KEY));
144
+ session.remove(this.storageKeyManager.getKey(SESSION_USER_ID_KEY));
205
145
  }
206
146
 
207
147
  /**
@@ -429,16 +369,16 @@ export class FormoAnalytics implements IFormoAnalytics {
429
369
 
430
370
  /**
431
371
  * Emits an identify event with current wallet address and provider info.
432
- * @param {string} params.providerName
433
- * @param {string} params.rdns
434
- * @param {string} params.userId
435
372
  * @param {string} params.address
373
+ * @param {string} params.userId
374
+ * @param {string} params.rdns
375
+ * @param {string} params.providerName
436
376
  * @param {IFormoEventProperties} properties
437
377
  * @param {IFormoEventContext} context
438
378
  * @param {(...args: unknown[]) => void} callback
439
379
  * @returns {Promise<void>}
440
380
  */
441
- public async identify(
381
+ async identify(
442
382
  params: {
443
383
  address?: Address;
444
384
  providerName?: string;
@@ -449,26 +389,29 @@ export class FormoAnalytics implements IFormoAnalytics {
449
389
  context?: IFormoEventContext,
450
390
  callback?: (...args: unknown[]) => void
451
391
  ): Promise<void> {
452
- const { userId, address, providerName, rdns } = params;
392
+ try {
393
+ const { userId, address, providerName, rdns } = params;
394
+ if (address) this.currentAddress = address;
395
+ if (userId) {
396
+ this.currentUserId = userId;
397
+ session.set(this.storageKeyManager.getKey(SESSION_USER_ID_KEY), userId);
398
+ }
453
399
 
454
- this.currentAddress = address;
455
- if (userId) {
456
- this.currentUserId = userId;
457
- session.set(SESSION_USER_ID_KEY, userId);
400
+ await this.trackEvent(
401
+ EventType.IDENTIFY,
402
+ {
403
+ address,
404
+ providerName,
405
+ userId,
406
+ rdns,
407
+ },
408
+ properties,
409
+ context,
410
+ callback
411
+ );
412
+ } catch (e) {
413
+ console.log("eeeee", e);
458
414
  }
459
-
460
- await this.trackEvent(
461
- EventType.IDENTIFY,
462
- {
463
- address,
464
- providerName,
465
- userId,
466
- rdns,
467
- },
468
- properties,
469
- context,
470
- callback
471
- );
472
415
  }
473
416
 
474
417
  /**
@@ -734,7 +677,7 @@ export class FormoAnalytics implements IFormoAnalytics {
734
677
  };
735
678
  this.currentChainId = undefined;
736
679
  this.currentAddress = undefined;
737
- session.remove(SESSION_USER_ID_KEY);
680
+ session.remove(this.storageKeyManager.getKey(SESSION_USER_ID_KEY));
738
681
 
739
682
  await this.trackEvent(
740
683
  EventType.DISCONNECT,
@@ -783,8 +726,14 @@ export class FormoAnalytics implements IFormoAnalytics {
783
726
  }
784
727
 
785
728
  private async trackFirstPageHit(): Promise<void> {
786
- if (session.get(SESSION_CURRENT_URL_KEY) === null) {
787
- session.set(SESSION_CURRENT_URL_KEY, window.location.href);
729
+ if (
730
+ session.get(this.storageKeyManager.getKey(SESSION_CURRENT_URL_KEY)) ===
731
+ null
732
+ ) {
733
+ session.set(
734
+ this.storageKeyManager.getKey(SESSION_CURRENT_URL_KEY),
735
+ window.location.href
736
+ );
788
737
  }
789
738
 
790
739
  return this.trackPageHit();
@@ -810,10 +759,15 @@ export class FormoAnalytics implements IFormoAnalytics {
810
759
  }
811
760
 
812
761
  private async onLocationChange(): Promise<void> {
813
- const currentUrl = session.get(SESSION_CURRENT_URL_KEY);
762
+ const currentUrl = session.get(
763
+ this.storageKeyManager.getKey(SESSION_CURRENT_URL_KEY)
764
+ );
814
765
 
815
766
  if (currentUrl !== window.location.href) {
816
- session.set(SESSION_CURRENT_URL_KEY, window.location.href);
767
+ session.set(
768
+ this.storageKeyManager.getKey(SESSION_CURRENT_URL_KEY),
769
+ window.location.href
770
+ );
817
771
  this.trackPageHit();
818
772
  }
819
773
  }
@@ -1023,16 +977,28 @@ interface IFormoAnalyticsSession {
1023
977
  }
1024
978
 
1025
979
  class FormoAnalyticsSession implements IFormoAnalyticsSession {
1026
- constructor() {}
980
+ private storageKeyManager: IStorageKeyManager;
981
+ constructor(storageKeyManager: IStorageKeyManager) {
982
+ this.storageKeyManager = storageKeyManager;
983
+ }
1027
984
 
1028
985
  public isWalletDetected(rdns: string): boolean {
1029
- const rdnses = (session.get(SESSION_WALLET_DETECTED_KEY) as string[]) || [];
986
+ const rdnses =
987
+ (session.get(
988
+ this.storageKeyManager.getKey(SESSION_WALLET_DETECTED_KEY)
989
+ ) as string[]) || [];
1030
990
  return rdnses.includes(rdns);
1031
991
  }
1032
992
 
1033
993
  public markWalletDetected(rdns: string): void {
1034
- const rdnses = (session.get(SESSION_WALLET_DETECTED_KEY) as string[]) || [];
994
+ const rdnses =
995
+ (session.get(
996
+ this.storageKeyManager.getKey(SESSION_WALLET_DETECTED_KEY)
997
+ ) as string[]) || [];
1035
998
  rdnses.push(rdns);
1036
- session.set(SESSION_WALLET_DETECTED_KEY, rdnses);
999
+ session.set(
1000
+ this.storageKeyManager.getKey(SESSION_WALLET_DETECTED_KEY),
1001
+ rdnses
1002
+ );
1037
1003
  }
1038
1004
  }
@@ -1,11 +1,23 @@
1
- import { createContext, useContext, useEffect, useState, useRef } from "react";
1
+ import { createContext, useContext, useEffect, useRef, useState } from "react";
2
2
  import { FormoAnalytics } from "./FormoAnalytics";
3
- import { FormoAnalyticsProviderProps } from "./types";
4
3
  import { logger } from "./lib";
4
+ import { FormoAnalyticsProviderProps, IFormoAnalytics } from "./types";
5
5
 
6
- export const FormoAnalyticsContext = createContext<FormoAnalytics | undefined>(
7
- undefined
8
- );
6
+ const defaultContext: IFormoAnalytics = {
7
+ chain: () => Promise.resolve(),
8
+ page: () => Promise.resolve(),
9
+ reset: () => Promise.resolve(),
10
+ detect: () => Promise.resolve(),
11
+ connect: () => Promise.resolve(),
12
+ disconnect: () => Promise.resolve(),
13
+ signature: () => Promise.resolve(),
14
+ transaction: () => Promise.resolve(),
15
+ identify: () => Promise.resolve(),
16
+ track: () => Promise.resolve(),
17
+ };
18
+
19
+ export const FormoAnalyticsContext =
20
+ createContext<IFormoAnalytics>(defaultContext);
9
21
 
10
22
  export const FormoAnalyticsProvider = (props: FormoAnalyticsProviderProps) => {
11
23
  const { writeKey, disabled = false, children } = props;
@@ -29,7 +41,7 @@ const InitializedAnalytics = ({
29
41
  options,
30
42
  children,
31
43
  }: FormoAnalyticsProviderProps) => {
32
- const [sdk, setSdk] = useState<FormoAnalytics | undefined>();
44
+ const [sdk, setSdk] = useState<IFormoAnalytics>(defaultContext);
33
45
  const initializedStartedRef = useRef(false);
34
46
 
35
47
  const initializeFormoAnalytics = async (writeKey: string, options: any) => {
@@ -1,13 +1,6 @@
1
- const STORAGE_PREFIX = "formo-";
1
+ export const SESSION_TRAFFIC_SOURCE_KEY = "traffic-source";
2
+ export const SESSION_WALLET_DETECTED_KEY = "wallet-detected";
3
+ export const SESSION_CURRENT_URL_KEY = "analytics-current-url";
4
+ export const SESSION_USER_ID_KEY = "user-id";
2
5
 
3
- const generateStoragePrefix = (prefix: string) => `${STORAGE_PREFIX}${prefix}`;
4
-
5
- export const SESSION_WALLET_DETECTED_KEY = generateStoragePrefix(
6
- "session-wallet-detected"
7
- );
8
- export const SESSION_CURRENT_URL_KEY = generateStoragePrefix(
9
- "analytics-current-url"
10
- );
11
- export const SESSION_USER_ID_KEY = generateStoragePrefix("user-id");
12
-
13
- export const LOCAL_ANONYMOUS_ID_KEY = generateStoragePrefix("anonymous-id");
6
+ export const LOCAL_ANONYMOUS_ID_KEY = "anonymous-id";
@@ -1,4 +1,8 @@
1
- import { COUNTRY_LIST } from "../../constants";
1
+ import {
2
+ COUNTRY_LIST,
3
+ LOCAL_ANONYMOUS_ID_KEY,
4
+ SESSION_TRAFFIC_SOURCE_KEY,
5
+ } from "../../constants";
2
6
  import {
3
7
  Address,
4
8
  APIEvent,
@@ -6,6 +10,7 @@ import {
6
10
  IFormoEvent,
7
11
  IFormoEventContext,
8
12
  IFormoEventProperties,
13
+ ITrafficSource,
9
14
  Nullable,
10
15
  SignatureStatus,
11
16
  TransactionStatus,
@@ -20,14 +25,17 @@ import { getCurrentTimeFormatted } from "../../utils/timestamp";
20
25
  import { isUndefined } from "../../validators";
21
26
  import { logger } from "../logger";
22
27
  import mergeDeepRight from "../ramda/mergeDeepRight";
23
- import { local } from "../storage";
28
+ import { IStorageKeyManager, local, session } from "../storage";
24
29
  import { version } from "../version";
25
30
  import { CHANNEL, VERSION } from "./constants";
26
31
  import { IEventFactory } from "./type";
27
32
  import { generateAnonymousId } from "./utils";
28
33
 
29
34
  class EventFactory implements IEventFactory {
30
- constructor() {}
35
+ private storageKeyManager: IStorageKeyManager;
36
+ constructor(storageKeyManager: IStorageKeyManager) {
37
+ this.storageKeyManager = storageKeyManager;
38
+ }
31
39
 
32
40
  private getTimezone(): string {
33
41
  try {
@@ -68,23 +76,84 @@ class EventFactory implements IEventFactory {
68
76
  }
69
77
 
70
78
  private extractUTMParameters = (url: string): UTMParameters => {
71
- const result: UTMParameters = {};
79
+ const result: UTMParameters = {
80
+ utm_campaign: "",
81
+ utm_content: "",
82
+ utm_medium: "",
83
+ utm_source: "",
84
+ utm_term: "",
85
+ };
72
86
  try {
73
87
  const urlObj = new URL(url);
74
88
  const UTM_PREFIX = "utm_";
75
89
  urlObj.searchParams.forEach((value, sParam) => {
76
90
  if (sParam.startsWith(UTM_PREFIX)) {
77
- result[sParam] = value.trim() || "";
91
+ result[sParam as keyof UTMParameters] = value.trim();
78
92
  }
79
93
  });
80
94
  } catch (error) {}
81
95
  return result;
82
96
  };
83
97
 
98
+ private getTrafficSources = (url: string): ITrafficSource => {
99
+ const urlObj = new URL(url);
100
+ const contextTrafficSources: ITrafficSource = {
101
+ ...this.extractUTMParameters(url),
102
+ ref: urlObj.searchParams.get("ref")?.trim() || "",
103
+ referrer: document.referrer,
104
+ };
105
+ const storedTrafficSources =
106
+ (session.get(
107
+ this.storageKeyManager.getKey(SESSION_TRAFFIC_SOURCE_KEY)
108
+ ) as ITrafficSource) || {};
109
+
110
+ const finalTrafficSources: ITrafficSource = {
111
+ ref: contextTrafficSources.ref || storedTrafficSources?.ref || "",
112
+ referrer:
113
+ contextTrafficSources.referrer || storedTrafficSources?.referrer,
114
+ utm_campaign:
115
+ contextTrafficSources.utm_campaign ||
116
+ storedTrafficSources?.utm_campaign ||
117
+ "",
118
+ utm_content:
119
+ contextTrafficSources.utm_content ||
120
+ storedTrafficSources?.utm_content ||
121
+ "",
122
+ utm_medium:
123
+ contextTrafficSources.utm_medium ||
124
+ storedTrafficSources?.utm_medium ||
125
+ "",
126
+ utm_source:
127
+ contextTrafficSources.utm_source ||
128
+ storedTrafficSources?.utm_source ||
129
+ "",
130
+ utm_term:
131
+ contextTrafficSources.utm_term || storedTrafficSources?.utm_term || "",
132
+ };
133
+
134
+ // Store to session
135
+ const sessionStoredTrafficSources = Object.keys(finalTrafficSources).reduce(
136
+ (res: any, key: any) => {
137
+ const value = finalTrafficSources[key as keyof ITrafficSource];
138
+ if (!isUndefined(value) && value !== "") {
139
+ res[key as keyof ITrafficSource] = value;
140
+ }
141
+ return res;
142
+ },
143
+ {}
144
+ );
145
+
146
+ if (Object.keys(sessionStoredTrafficSources).length)
147
+ session.set(
148
+ this.storageKeyManager.getKey(SESSION_TRAFFIC_SOURCE_KEY),
149
+ sessionStoredTrafficSources
150
+ );
151
+
152
+ return finalTrafficSources;
153
+ };
154
+
84
155
  // Contextual fields that are automatically collected and populated by the Formo SDK
85
156
  private generateContext(context?: IFormoEventContext): IFormoEventContext {
86
- const url = new URL(globalThis.location.href);
87
- const params = new URLSearchParams(url.search);
88
157
  const path = globalThis.location.pathname;
89
158
  const language = this.getLanguage();
90
159
  const timezone = this.getTimezone();
@@ -97,12 +166,10 @@ class EventFactory implements IEventFactory {
97
166
  locale: language,
98
167
  timezone,
99
168
  location,
100
- referrer: document.referrer,
101
- ...this.extractUTMParameters(globalThis.location.href),
102
- ref: params.get("ref")?.trim() || "",
169
+ ...this.getTrafficSources(globalThis.location.href),
103
170
  page_path: path,
104
171
  page_title: document.title,
105
- page_url: url.href,
172
+ page_url: globalThis.location.href,
106
173
  library_name: "Formo Web SDK",
107
174
  library_version,
108
175
  };
@@ -156,7 +223,9 @@ class EventFactory implements IEventFactory {
156
223
  if (!local.isAvailable()) {
157
224
  commonEventData.anonymous_id = generateNativeUUID();
158
225
  } else {
159
- commonEventData.anonymous_id = generateAnonymousId();
226
+ commonEventData.anonymous_id = generateAnonymousId(
227
+ this.storageKeyManager.getKey(LOCAL_ANONYMOUS_ID_KEY)
228
+ );
160
229
  }
161
230
 
162
231
  if (formoEvent.address) {
@@ -354,11 +423,16 @@ class EventFactory implements IEventFactory {
354
423
  const trackEvent: Partial<IFormoEvent> = {
355
424
  properties: {
356
425
  ...properties,
357
- ...(properties?.revenue !== undefined && {
426
+ ...(properties?.revenue !== undefined && {
358
427
  revenue: Number(properties.revenue),
359
- currency: (typeof properties?.currency === "string" ? properties.currency : "USD").toLowerCase()
428
+ currency: (typeof properties?.currency === "string"
429
+ ? properties.currency
430
+ : "USD"
431
+ ).toLowerCase(),
432
+ }),
433
+ ...(properties?.points !== undefined && {
434
+ points: Number(properties.points),
360
435
  }),
361
- ...(properties?.points !== undefined && { points: Number(properties.points) }),
362
436
  },
363
437
  event,
364
438
  type: "track",
@@ -1,6 +1,7 @@
1
1
  import { Address, APIEvent } from "../../types";
2
2
  import { logger } from "../logger";
3
3
  import { IEventQueue } from "../queue";
4
+ import { IStorageKeyManager } from "../storage";
4
5
  import { EventFactory } from "./EventFactory";
5
6
  import { IEventFactory, IEventManager } from "./type";
6
7
 
@@ -15,9 +16,9 @@ class EventManager implements IEventManager {
15
16
  *
16
17
  * @param eventQueue Event queue instance
17
18
  */
18
- constructor(eventQueue: IEventQueue) {
19
+ constructor(eventQueue: IEventQueue, storageKeyManager: IStorageKeyManager) {
19
20
  this.eventQueue = eventQueue;
20
- this.eventFactory = new EventFactory();
21
+ this.eventFactory = new EventFactory(storageKeyManager);
21
22
  }
22
23
 
23
24
  /**
@@ -1,14 +1,13 @@
1
- import { LOCAL_ANONYMOUS_ID_KEY } from "../../constants";
2
1
  import { AnonymousID } from "../../types";
3
2
  import { generateNativeUUID } from "../../utils";
4
3
  import { local } from "../storage";
5
4
 
6
- const generateAnonymousId = (): AnonymousID => {
7
- const storedAnonymousId = local.get(LOCAL_ANONYMOUS_ID_KEY);
5
+ const generateAnonymousId = (key: string): AnonymousID => {
6
+ const storedAnonymousId = local.get(key);
8
7
  if (storedAnonymousId && typeof storedAnonymousId === "string")
9
8
  return storedAnonymousId as AnonymousID;
10
9
  const newAnonymousId = generateNativeUUID();
11
- local.set(LOCAL_ANONYMOUS_ID_KEY, newAnonymousId);
10
+ local.set(key, newAnonymousId);
12
11
  return newAnonymousId;
13
12
  };
14
13
 
@@ -1,2 +1,4 @@
1
+ export { StorageKey } from "./key";
1
2
  export { default as local } from "./local";
2
3
  export { default as session } from "./session";
4
+ export * from "./type";
@@ -0,0 +1,16 @@
1
+ import { IStorageKeyManager } from "./type";
2
+
3
+ class StorageKey implements IStorageKeyManager {
4
+ private readonly prefix = "formo";
5
+ private readonly writeKey: string;
6
+
7
+ constructor(writeKey: string) {
8
+ this.writeKey = writeKey;
9
+ }
10
+
11
+ getKey(name: string): string {
12
+ return this.prefix + "_" + this.writeKey + "." + name;
13
+ }
14
+ }
15
+
16
+ export { StorageKey };
@@ -60,7 +60,7 @@ export class NativeStorage {
60
60
 
61
61
  if (value.startsWith(this.json_prefix)) {
62
62
  try {
63
- return JSON.parse(value.slice(7));
63
+ return JSON.parse(value.slice(this.json_prefix.length));
64
64
  } catch (error) {
65
65
  logger.error(
66
66
  `[FORMO_ERROR] ${this.storageName} failed to parse JSON`,
@@ -0,0 +1,3 @@
1
+ export interface IStorageKeyManager {
2
+ getKey(name: string): string;
3
+ }
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '1.16.6';
2
+ export const version = '1.16.8';