@formo/analytics 1.13.4 → 1.14.2

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 (124) hide show
  1. package/.github/workflows/ci.yml +51 -0
  2. package/CONTRIBUTING.md +1 -1
  3. package/dist/cjs/src/FormoAnalytics.d.ts +6 -5
  4. package/dist/cjs/src/FormoAnalytics.d.ts.map +1 -1
  5. package/dist/cjs/src/FormoAnalytics.js +88 -83
  6. package/dist/cjs/src/FormoAnalytics.js.map +1 -1
  7. package/dist/cjs/src/FormoAnalyticsProvider.d.ts +4 -5
  8. package/dist/cjs/src/FormoAnalyticsProvider.d.ts.map +1 -1
  9. package/dist/cjs/src/FormoAnalyticsProvider.js +39 -62
  10. package/dist/cjs/src/FormoAnalyticsProvider.js.map +1 -1
  11. package/dist/cjs/src/constants/base.d.ts +3 -0
  12. package/dist/cjs/src/constants/base.d.ts.map +1 -0
  13. package/dist/cjs/src/constants/base.js +6 -0
  14. package/dist/cjs/src/constants/base.js.map +1 -0
  15. package/dist/cjs/src/constants/config.d.ts +1 -1
  16. package/dist/cjs/src/constants/config.js +58 -58
  17. package/dist/cjs/src/constants/config.js.map +1 -1
  18. package/dist/cjs/src/constants/index.d.ts +4 -2
  19. package/dist/cjs/src/constants/index.d.ts.map +1 -1
  20. package/dist/cjs/src/constants/index.js +2 -0
  21. package/dist/cjs/src/constants/index.js.map +1 -1
  22. package/dist/cjs/src/constants/regex.d.ts +4 -0
  23. package/dist/cjs/src/constants/regex.d.ts.map +1 -0
  24. package/dist/cjs/src/constants/regex.js +7 -0
  25. package/dist/cjs/src/constants/regex.js.map +1 -0
  26. package/dist/cjs/src/lib/fingerprint.d.ts +4 -0
  27. package/dist/cjs/src/lib/fingerprint.d.ts.map +1 -0
  28. package/dist/cjs/src/lib/fingerprint.js +63 -0
  29. package/dist/cjs/src/lib/fingerprint.js.map +1 -0
  30. package/dist/cjs/src/lib/index.d.ts +3 -0
  31. package/dist/cjs/src/lib/index.d.ts.map +1 -0
  32. package/dist/cjs/src/lib/index.js +24 -0
  33. package/dist/cjs/src/lib/index.js.map +1 -0
  34. package/dist/cjs/src/lib/queue.d.ts +33 -0
  35. package/dist/cjs/src/lib/queue.d.ts.map +1 -0
  36. package/dist/cjs/src/lib/queue.js +319 -0
  37. package/dist/cjs/src/lib/queue.js.map +1 -0
  38. package/dist/cjs/src/lib/session-storage.d.ts +11 -0
  39. package/dist/cjs/src/lib/session-storage.d.ts.map +1 -0
  40. package/dist/cjs/src/lib/session-storage.js +52 -0
  41. package/dist/cjs/src/lib/session-storage.js.map +1 -0
  42. package/dist/cjs/src/lib/utils.d.ts +6 -0
  43. package/dist/cjs/src/lib/utils.d.ts.map +1 -1
  44. package/dist/cjs/src/lib/utils.js +32 -0
  45. package/dist/cjs/src/lib/utils.js.map +1 -1
  46. package/dist/cjs/src/types/base.d.ts +8 -2
  47. package/dist/cjs/src/types/base.d.ts.map +1 -1
  48. package/dist/cjs/src/types/events.d.ts +7 -0
  49. package/dist/cjs/src/types/events.d.ts.map +1 -1
  50. package/dist/cjs/src/types/events.js.map +1 -1
  51. package/dist/cjs/test/lib.spec.js +11 -3
  52. package/dist/cjs/test/lib.spec.js.map +1 -1
  53. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  54. package/dist/esm/src/FormoAnalytics.d.ts +6 -5
  55. package/dist/esm/src/FormoAnalytics.d.ts.map +1 -1
  56. package/dist/esm/src/FormoAnalytics.js +87 -79
  57. package/dist/esm/src/FormoAnalytics.js.map +1 -1
  58. package/dist/esm/src/FormoAnalyticsProvider.d.ts +4 -5
  59. package/dist/esm/src/FormoAnalyticsProvider.d.ts.map +1 -1
  60. package/dist/esm/src/FormoAnalyticsProvider.js +40 -63
  61. package/dist/esm/src/FormoAnalyticsProvider.js.map +1 -1
  62. package/dist/esm/src/constants/base.d.ts +3 -0
  63. package/dist/esm/src/constants/base.d.ts.map +1 -0
  64. package/dist/esm/src/constants/base.js +3 -0
  65. package/dist/esm/src/constants/base.js.map +1 -0
  66. package/dist/esm/src/constants/config.d.ts +1 -1
  67. package/dist/esm/src/constants/config.js +58 -58
  68. package/dist/esm/src/constants/config.js.map +1 -1
  69. package/dist/esm/src/constants/index.d.ts +4 -2
  70. package/dist/esm/src/constants/index.d.ts.map +1 -1
  71. package/dist/esm/src/constants/index.js +4 -2
  72. package/dist/esm/src/constants/index.js.map +1 -1
  73. package/dist/esm/src/constants/regex.d.ts +4 -0
  74. package/dist/esm/src/constants/regex.d.ts.map +1 -0
  75. package/dist/esm/src/constants/regex.js +4 -0
  76. package/dist/esm/src/constants/regex.js.map +1 -0
  77. package/dist/esm/src/lib/fingerprint.d.ts +4 -0
  78. package/dist/esm/src/lib/fingerprint.d.ts.map +1 -0
  79. package/dist/esm/src/lib/fingerprint.js +60 -0
  80. package/dist/esm/src/lib/fingerprint.js.map +1 -0
  81. package/dist/esm/src/lib/index.d.ts +3 -0
  82. package/dist/esm/src/lib/index.d.ts.map +1 -0
  83. package/dist/esm/src/lib/index.js +3 -0
  84. package/dist/esm/src/lib/index.js.map +1 -0
  85. package/dist/esm/src/lib/queue.d.ts +33 -0
  86. package/dist/esm/src/lib/queue.d.ts.map +1 -0
  87. package/dist/esm/src/lib/queue.js +313 -0
  88. package/dist/esm/src/lib/queue.js.map +1 -0
  89. package/dist/esm/src/lib/session-storage.d.ts +11 -0
  90. package/dist/esm/src/lib/session-storage.d.ts.map +1 -0
  91. package/dist/esm/src/lib/session-storage.js +49 -0
  92. package/dist/esm/src/lib/session-storage.js.map +1 -0
  93. package/dist/esm/src/lib/utils.d.ts +6 -0
  94. package/dist/esm/src/lib/utils.d.ts.map +1 -1
  95. package/dist/esm/src/lib/utils.js +25 -0
  96. package/dist/esm/src/lib/utils.js.map +1 -1
  97. package/dist/esm/src/types/base.d.ts +8 -2
  98. package/dist/esm/src/types/base.d.ts.map +1 -1
  99. package/dist/esm/src/types/events.d.ts +7 -0
  100. package/dist/esm/src/types/events.d.ts.map +1 -1
  101. package/dist/esm/src/types/events.js.map +1 -1
  102. package/dist/esm/test/lib.spec.js +9 -1
  103. package/dist/esm/test/lib.spec.js.map +1 -1
  104. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  105. package/dist/index.umd.min.js +1 -1
  106. package/dist/index.umd.min.js.LICENSE.txt +0 -12
  107. package/dist/index.umd.min.js.map +1 -1
  108. package/package.json +7 -6
  109. package/src/FormoAnalytics.ts +86 -66
  110. package/src/FormoAnalyticsProvider.tsx +32 -67
  111. package/src/constants/base.ts +2 -0
  112. package/src/constants/config.ts +58 -58
  113. package/src/constants/index.ts +4 -2
  114. package/src/constants/regex.ts +3 -0
  115. package/src/lib/fingerprint.ts +9 -0
  116. package/src/lib/index.ts +2 -0
  117. package/src/lib/queue.ts +310 -0
  118. package/src/lib/session-storage.ts +53 -0
  119. package/src/lib/utils.ts +31 -0
  120. package/src/types/base.ts +12 -5
  121. package/src/types/events.ts +15 -7
  122. package/test/lib.spec.ts +13 -1
  123. package/dist/387.index.umd.min.js +0 -125
  124. package/dist/387.index.umd.min.js.map +0 -1
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@formo/analytics",
3
- "version": "1.13.4",
3
+ "version": "1.14.2",
4
4
  "repository": {
5
5
  "type": "git",
6
- "url": "https://github.com/getformo/sdk.git"
6
+ "url": "git+https://github.com/getformo/sdk.git"
7
7
  },
8
8
  "main": "dist/cjs/src/index.js",
9
9
  "types": "dist/esm/src/index.d.ts",
@@ -21,9 +21,9 @@
21
21
  },
22
22
  "license": "MIT",
23
23
  "dependencies": {
24
- "@highlight-run/react": "^7.0.2",
25
- "axios": "^1.7.7",
26
- "highlight.run": "^9.5.2",
24
+ "@fingerprintjs/fingerprintjs": "^4.6.0",
25
+ "fetch-retry": "^6.0.0",
26
+ "is-network-error": "^1.1.0",
27
27
  "mipd": "^0.0.7"
28
28
  },
29
29
  "devDependencies": {
@@ -77,7 +77,8 @@
77
77
  "test": "mocha --require ts-node/register test/**/*.ts",
78
78
  "test-watch": "nodemon --config test.nodemon.json",
79
79
  "prepare": "husky install",
80
- "commit": "git add . && cz"
80
+ "commit": "git add . && cz",
81
+ "pub": "yarn build && npm publish"
81
82
  },
82
83
  "peerDependencies": {
83
84
  "@types/react": ">=16.14.34",
@@ -1,4 +1,3 @@
1
- import axios from "axios";
2
1
  import { createStore, EIP6963ProviderDetail } from "mipd";
3
2
  import {
4
3
  COUNTRY_LIST,
@@ -6,7 +5,6 @@ import {
6
5
  EVENTS_API_URL,
7
6
  Event,
8
7
  } from "./constants";
9
- import { H } from "highlight.run";
10
8
  import {
11
9
  ChainID,
12
10
  Address,
@@ -17,8 +15,11 @@ import {
17
15
  RPCError,
18
16
  SignatureStatus,
19
17
  TransactionStatus,
18
+ RequestEvent,
20
19
  } from "./types";
21
- import { toSnakeCase } from "./lib/utils";
20
+ import { session, isLocalhost, toSnakeCase, isAddress } from "./lib";
21
+ import { SESSION_IDENTIFIED_KEY } from "./constants";
22
+ import { EventQueue } from "./lib/queue";
22
23
 
23
24
  interface IFormoAnalytics {
24
25
  page(): void;
@@ -62,19 +63,32 @@ interface IFormoAnalytics {
62
63
  export class FormoAnalytics implements IFormoAnalytics {
63
64
  private _provider?: EIP1193Provider;
64
65
  private _providerListeners: Record<string, (...args: unknown[]) => void> = {};
66
+ private session: FormoAnalyticsSession;
67
+ private eventQueue: EventQueue;
65
68
 
66
69
  config: Config;
67
70
  currentChainId?: ChainID;
68
71
  currentConnectedAddress?: Address;
69
72
 
70
73
  private constructor(
71
- public readonly apiKey: string,
74
+ public readonly writeKey: string,
72
75
  public options: Options = {}
73
76
  ) {
74
77
  this.config = {
75
- apiKey: apiKey,
78
+ writeKey,
79
+ trackLocalhost: options.trackLocalhost || false,
76
80
  };
77
81
 
82
+ this.session = new FormoAnalyticsSession();
83
+
84
+ this.eventQueue = new EventQueue(this.config.writeKey, {
85
+ url: EVENTS_API_URL,
86
+ flushAt: options.flushAt,
87
+ retryCount: options.retryCount,
88
+ maxQueueSize: options.maxQueueSize,
89
+ flushInterval: options.flushInterval,
90
+ });
91
+
78
92
  // TODO: replace with eip6963
79
93
  const provider = options.provider || window?.ethereum;
80
94
  if (provider) {
@@ -86,10 +100,10 @@ export class FormoAnalytics implements IFormoAnalytics {
86
100
  }
87
101
 
88
102
  static async init(
89
- apiKey: string,
103
+ writeKey: string,
90
104
  options?: Options
91
105
  ): Promise<FormoAnalytics> {
92
- const analytics = new FormoAnalytics(apiKey, options);
106
+ const analytics = new FormoAnalytics(writeKey, options);
93
107
 
94
108
  // Identify
95
109
  const providers = await analytics.getProviders();
@@ -264,7 +278,7 @@ export class FormoAnalytics implements IFormoAnalytics {
264
278
  }
265
279
 
266
280
  /**
267
- * Emits a identify event with current wallet address.
281
+ * Emits an identify event with current wallet address.
268
282
  * @param {Address} params.address
269
283
  * @returns {Promise<void>}
270
284
  */
@@ -273,17 +287,21 @@ export class FormoAnalytics implements IFormoAnalytics {
273
287
  providerName,
274
288
  rdns,
275
289
  }: {
276
- address: Address;
290
+ address: Address | null;
277
291
  providerName?: string;
278
292
  rdns?: string;
279
293
  }): Promise<void> {
280
- if (address) {
281
- await this.trackEvent(Event.IDENTIFY, {
282
- address,
283
- providerName,
284
- rdns,
285
- });
286
- }
294
+ if (this.session.isIdentified())
295
+ return console.warn(
296
+ "FormoAnalytics::identify: Wallet already identified in this session"
297
+ );
298
+
299
+ this.session.identify();
300
+ await this.trackEvent(Event.IDENTIFY, {
301
+ address,
302
+ providerName,
303
+ rdns,
304
+ });
287
305
  }
288
306
 
289
307
  /**
@@ -302,7 +320,7 @@ export class FormoAnalytics implements IFormoAnalytics {
302
320
 
303
321
  private trackProvider(provider: EIP1193Provider): void {
304
322
  if (provider === this._provider) {
305
- console.log("Provider already tracked.");
323
+ console.warn("FormoAnalytics::trackProvider: Provider already tracked.");
306
324
  return;
307
325
  }
308
326
 
@@ -535,8 +553,8 @@ export class FormoAnalytics implements IFormoAnalytics {
535
553
  }
536
554
 
537
555
  private async trackFirstPageHit(): Promise<void> {
538
- if (sessionStorage.getItem(CURRENT_URL_KEY) === null) {
539
- sessionStorage.setItem(CURRENT_URL_KEY, window.location.href);
556
+ if (session.get(CURRENT_URL_KEY) === null) {
557
+ session.set(CURRENT_URL_KEY, window.location.href);
540
558
  }
541
559
 
542
560
  return this.trackPageHit();
@@ -562,70 +580,48 @@ export class FormoAnalytics implements IFormoAnalytics {
562
580
  }
563
581
 
564
582
  private async onLocationChange(): Promise<void> {
565
- const currentUrl = sessionStorage.getItem(CURRENT_URL_KEY);
583
+ const currentUrl = session.get(CURRENT_URL_KEY);
566
584
 
567
585
  if (currentUrl !== window.location.href) {
568
- sessionStorage.setItem(CURRENT_URL_KEY, window.location.href);
586
+ session.set(CURRENT_URL_KEY, window.location.href);
569
587
  this.trackPageHit();
570
588
  }
571
589
  }
572
590
 
573
591
  private trackPageHit(): void {
574
592
  const pathname = window.location.pathname;
575
- const href = window.location.href;
576
593
  const hash = window.location.hash;
577
594
 
595
+ if (!this.config.trackLocalhost && isLocalhost()) {
596
+ return console.warn(
597
+ "FormoAnalytics::trackPageHit: Ignoring event because website is running locally"
598
+ );
599
+ }
600
+
578
601
  setTimeout(async () => {
579
602
  this.trackEvent(Event.PAGE, {
580
603
  pathname,
581
- href,
582
604
  hash,
583
605
  });
584
606
  }, 300);
585
607
  }
586
608
 
587
- // TODO: refactor this with event queue and flushing
588
- // https://linear.app/getformo/issue/P-835/sdk-refactor-retries-with-event-queue-and-batching
589
609
  private async trackEvent(action: string, payload: any): Promise<void> {
590
610
  const address = await this.getAddress();
591
611
 
592
- const requestData = {
593
- address: address,
612
+ const requestData: RequestEvent = {
613
+ address,
594
614
  timestamp: new Date().toISOString(),
595
615
  action,
596
616
  version: "1",
597
617
  payload: await this.buildEventPayload(toSnakeCase(payload)),
598
618
  };
599
619
 
600
- try {
601
- const response = await axios.post(
602
- EVENTS_API_URL,
603
- JSON.stringify(requestData),
604
- {
605
- headers: {
606
- "Content-Type": "application/json",
607
- Authorization: `Bearer ${this.config.apiKey}`,
608
- },
609
- }
610
- );
611
-
612
- if (response.status >= 200 && response.status < 300) {
613
- console.log(
614
- `Event sent successfully: ${this.getActionDescriptor(
615
- action,
616
- payload
617
- )}`
618
- );
619
- } else {
620
- throw new Error(`Failed with status: ${response.status}`);
621
- }
622
- } catch (error) {
623
- H.consumeError(
624
- error as Error,
625
- `Request data: ${JSON.stringify(requestData)}`
626
- );
627
- console.error(`Event "${action}" failed. Error: ${error}`);
628
- }
620
+ await this.eventQueue.enqueue(requestData, (err, _, data) => {
621
+ if (err) {
622
+ console.error(err);
623
+ } else console.log(`Events sent successfully: ${data.length} events`);
624
+ });
629
625
  }
630
626
 
631
627
  /*
@@ -646,9 +642,10 @@ export class FormoAnalytics implements IFormoAnalytics {
646
642
  }
647
643
 
648
644
  private async identifyAll(providers: EIP6963ProviderDetail[]): Promise<void> {
649
- for (const { provider, info } of providers) {
650
- try {
645
+ try {
646
+ for (const { provider, info } of providers) {
651
647
  const accounts = await this.getAccounts(provider);
648
+ // Identify with accounts
652
649
  if (accounts && accounts.length > 0) {
653
650
  for (const address of accounts) {
654
651
  await this.identify({
@@ -657,8 +654,17 @@ export class FormoAnalytics implements IFormoAnalytics {
657
654
  rdns: info.rdns,
658
655
  });
659
656
  }
657
+ } else {
658
+ // Identify without accounts
659
+ await this.identify({
660
+ address: null,
661
+ providerName: info.name,
662
+ rdns: info.rdns,
663
+ });
660
664
  }
661
- } catch (err) {}
665
+ }
666
+ } catch (err) {
667
+ console.log("identifying all => err", err);
662
668
  }
663
669
  }
664
670
 
@@ -668,7 +674,7 @@ export class FormoAnalytics implements IFormoAnalytics {
668
674
 
669
675
  private async getAddress(): Promise<Address | null> {
670
676
  if (this.currentConnectedAddress) return this.currentConnectedAddress;
671
- if (!this.provider) {
677
+ if (!this?.provider) {
672
678
  console.log("FormoAnalytics::getAddress: the provider is not set");
673
679
  return null;
674
680
  }
@@ -676,7 +682,7 @@ export class FormoAnalytics implements IFormoAnalytics {
676
682
  try {
677
683
  const accounts = await this.getAccounts();
678
684
  if (accounts && accounts.length > 0) {
679
- return accounts[0];
685
+ return isAddress(accounts[0]) ? accounts[0] : null;
680
686
  }
681
687
  } catch (err) {
682
688
  console.log("Failed to fetch accounts from provider:", err);
@@ -694,7 +700,7 @@ export class FormoAnalytics implements IFormoAnalytics {
694
700
  method: "eth_accounts",
695
701
  });
696
702
  if (!res || res.length === 0) return null;
697
- return res;
703
+ return res.filter(isAddress);
698
704
  } catch (err) {
699
705
  if ((err as any).code !== 4001) {
700
706
  console.log(
@@ -764,18 +770,19 @@ export class FormoAnalytics implements IFormoAnalytics {
764
770
 
765
771
  const location = this.getLocation();
766
772
  const language = this.getLanguage();
767
- const address = await this.getAddress();
768
773
 
769
774
  // common browser properties
770
775
  return {
771
776
  "user-agent": window.navigator.userAgent,
772
- address,
777
+ href: url.href,
773
778
  locale: language,
774
779
  location,
775
780
  referrer: document.referrer,
776
781
  utm_source: params.get("utm_source"),
777
782
  utm_medium: params.get("utm_medium"),
778
783
  utm_campaign: params.get("utm_campaign"),
784
+ utm_content: params.get("utm_content"),
785
+ utm_term: params.get("utm_term"),
779
786
  ref: params.get("ref"),
780
787
  ...eventSpecificPayload,
781
788
  };
@@ -828,8 +835,21 @@ export class FormoAnalytics implements IFormoAnalytics {
828
835
  value,
829
836
  };
830
837
  }
838
+ }
839
+
840
+ interface IFormoAnalyticsSession {
841
+ isIdentified(): boolean;
842
+ identify(): void;
843
+ }
844
+
845
+ class FormoAnalyticsSession implements IFormoAnalyticsSession {
846
+ constructor() {}
847
+
848
+ public isIdentified(): boolean {
849
+ return session.get(SESSION_IDENTIFIED_KEY) === true;
850
+ }
831
851
 
832
- private getActionDescriptor(action: string, payload: any): string {
833
- return `${action}${payload.status ? ` ${payload.status}` : ""}`;
852
+ public identify(): void {
853
+ session.set(SESSION_IDENTIFIED_KEY, true);
834
854
  }
835
855
  }
@@ -1,96 +1,61 @@
1
- import React, {
2
- createContext,
3
- useContext,
4
- useEffect,
5
- useState,
6
- useRef,
7
- } from 'react';
8
- import { FormoAnalytics } from './FormoAnalytics';
9
- import { FormoAnalyticsProviderProps } from './types';
10
- import { ErrorBoundary } from '@highlight-run/react';
11
- import { H } from 'highlight.run';
12
-
13
- const HIGHLIGHT_PROJECT_ID = process.env.REACT_APP_HIGHLIGHT_PROJECT_ID;
1
+ import { createContext, useContext, useEffect, useState, useRef } from "react";
2
+ import { FormoAnalytics } from "./FormoAnalytics";
3
+ import { FormoAnalyticsProviderProps } from "./types";
14
4
 
15
5
  export const FormoAnalyticsContext = createContext<FormoAnalytics | undefined>(
16
6
  undefined
17
7
  );
18
8
 
19
- export const FormoAnalyticsProvider = ({
20
- apiKey,
9
+ export const FormoAnalyticsProvider = (props: FormoAnalyticsProviderProps) => {
10
+ const { writeKey, disabled, children } = props;
11
+
12
+ // Keep the app running without analytics if no Write Key is provided or disabled
13
+ if (!writeKey) {
14
+ console.error("FormoAnalyticsProvider: No Write Key provided");
15
+ return children;
16
+ }
17
+
18
+ if (disabled) {
19
+ console.warn("FormoAnalytics is disabled");
20
+ return children;
21
+ }
22
+
23
+ return <InitializedAnalytics {...props} />;
24
+ };
25
+
26
+ const InitializedAnalytics = ({
27
+ writeKey,
21
28
  options,
22
- disabled,
23
29
  children,
24
30
  }: FormoAnalyticsProviderProps) => {
25
31
  const [sdk, setSdk] = useState<FormoAnalytics | undefined>();
26
- const [isInitialized, setIsInitialized] = useState(false);
27
32
  const initializedStartedRef = useRef(false);
28
33
 
29
- const initializeHighlight = async () => {
30
- if (HIGHLIGHT_PROJECT_ID) {
31
- try {
32
- H.init(HIGHLIGHT_PROJECT_ID, {
33
- serviceName: 'formo-analytics-sdk',
34
- tracingOrigins: true,
35
- networkRecording: {
36
- enabled: true,
37
- recordHeadersAndBody: true,
38
- urlBlocklist: [
39
- 'https://www.googleapis.com/identitytoolkit',
40
- 'https://securetoken.googleapis.com',
41
- ],
42
- },
43
- });
44
- console.log('Highlight.run initialized successfully');
45
- } catch (error) {
46
- console.error('Failed to initialize Highlight.run', error);
47
- }
48
- }
49
- };
50
-
51
- const initializeFormoAnalytics = async (apiKey: string, options: any) => {
34
+ const initializeFormoAnalytics = async (writeKey: string, options: any) => {
52
35
  try {
53
- const sdkInstance = await FormoAnalytics.init(apiKey, options);
36
+ const sdkInstance = await FormoAnalytics.init(writeKey, options);
54
37
  setSdk(sdkInstance);
55
- console.log('FormoAnalytics SDK initialized successfully');
38
+ console.log("FormoAnalytics SDK initialized successfully");
56
39
  } catch (error) {
57
- console.error('Failed to initialize FormoAnalytics SDK', error);
58
- } finally {
59
- setIsInitialized(true); // Ensure UI renders even after failure
40
+ console.error("Failed to initialize FormoAnalytics SDK", error);
60
41
  }
61
42
  };
62
43
 
63
44
  useEffect(() => {
64
45
  const initialize = async () => {
65
- if (!apiKey) {
66
- console.error('FormoAnalyticsProvider: No API key provided');
67
- return;
68
- }
69
- if (disabled) {
70
- console.warn('FormoAnalytics is disabled');
71
- return;
72
- }
73
46
  if (initializedStartedRef.current) return;
74
47
  initializedStartedRef.current = true;
75
48
 
76
- await initializeHighlight();
77
- await initializeFormoAnalytics(apiKey, options);
49
+ await initializeFormoAnalytics(writeKey!, options);
78
50
  };
79
51
 
80
52
  initialize();
81
- }, [apiKey, disabled, options]);
82
-
83
- if (!isInitialized) {
84
- // Optionally show a loading state until initialization attempt finishes
85
- return <div>Loading analytics...</div>;
86
- }
53
+ }, [writeKey, options]);
87
54
 
88
55
  return (
89
- <ErrorBoundary onError={(error, info) => H?.consumeError(error, info)}>
90
- <FormoAnalyticsContext.Provider value={sdk}>
91
- {children}
92
- </FormoAnalyticsContext.Provider>
93
- </ErrorBoundary>
56
+ <FormoAnalyticsContext.Provider value={sdk}>
57
+ {children}
58
+ </FormoAnalyticsContext.Provider>
94
59
  );
95
60
  };
96
61
 
@@ -98,7 +63,7 @@ export const useFormoAnalytics = () => {
98
63
  const context = useContext(FormoAnalyticsContext);
99
64
 
100
65
  if (!context) {
101
- console.warn('useFormoAnalytics called without a valid context');
66
+ console.warn("useFormoAnalytics called without a valid context");
102
67
  }
103
68
 
104
69
  return context; // Return undefined if SDK is not initialized, handle accordingly in consumer
@@ -0,0 +1,2 @@
1
+ export const SESSION_PREFIX = "f0-";
2
+ export const SESSION_IDENTIFIED_KEY = SESSION_PREFIX + "session_identified";