-
Notifications
You must be signed in to change notification settings - Fork 1
P-1925 P-1926 Enhance analytics API with optional parameters and referral config #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
d738ebb
ff8c13a
edeabeb
de6f846
ef1557b
cdf7205
9c5ce9c
4389c28
3af3d57
d0c2623
67b0728
a71b986
57a0d80
75e5fd4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ import { | |
| } from "./lib/consent"; | ||
| import { FormoAnalyticsSession } from "./lib/session"; | ||
| import { WagmiEventHandler } from "./lib/wagmi"; | ||
| import { AppLifecycleManager } from "./lib/lifecycle"; | ||
| import { | ||
| Address, | ||
| ChainID, | ||
|
|
@@ -35,12 +36,14 @@ import { | |
| TransactionStatus, | ||
| } from "./types"; | ||
| import { toChecksumAddress, getValidAddress } from "./utils"; | ||
| import { parseTrafficSource, storeTrafficSource } from "./utils/trafficSource"; | ||
|
|
||
| export class FormoAnalytics implements IFormoAnalytics { | ||
| private session: FormoAnalyticsSession; | ||
| private eventManager: IEventManager; | ||
| private eventQueue: EventQueue; | ||
| private wagmiHandler?: WagmiEventHandler; | ||
| private lifecycleManager?: AppLifecycleManager; | ||
|
|
||
| config: Config; | ||
| currentChainId?: ChainID; | ||
|
|
@@ -125,6 +128,17 @@ export class FormoAnalytics implements IFormoAnalytics { | |
|
|
||
| const analytics = new FormoAnalytics(writeKey, options); | ||
|
|
||
| // Initialize lifecycle tracking if enabled | ||
| // Wrapped in try-catch so a transient storage failure doesn't prevent SDK init | ||
| if (analytics.isAutocaptureEnabled("lifecycle")) { | ||
| try { | ||
| analytics.lifecycleManager = new AppLifecycleManager(analytics); | ||
| await analytics.lifecycleManager.start(options?.app); | ||
| } catch (error) { | ||
| logger.error("FormoAnalytics: Failed to initialize lifecycle tracking", error); | ||
| } | ||
| } | ||
|
|
||
| // Call ready callback | ||
| if (options?.ready) { | ||
| options.ready(analytics); | ||
|
|
@@ -138,14 +152,15 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| */ | ||
| public async screen( | ||
| name: string, | ||
| category?: string, | ||
| properties?: IFormoEventProperties, | ||
|
Comment on lines
153
to
156
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Changing Useful? React with 👍 / 👎.
Comment on lines
153
to
156
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Adding Useful? React with 👍 / 👎.
Comment on lines
154
to
156
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Changing Useful? React with 👍 / 👎. |
||
| context?: IFormoEventContext, | ||
| callback?: (...args: unknown[]) => void | ||
| ): Promise<void> { | ||
| // Note: shouldTrack() is called in trackEvent() - no need to check here | ||
| await this.trackEvent( | ||
| EventType.SCREEN, | ||
| { name }, | ||
| { name, ...(category && { category }) }, | ||
| properties, | ||
| context, | ||
| callback | ||
|
|
@@ -175,8 +190,11 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| * ``` | ||
| */ | ||
| public setTrafficSourceFromUrl(url: string): void { | ||
| const { parseTrafficSource, storeTrafficSource } = require("./utils/trafficSource"); | ||
| const trafficSource = parseTrafficSource(url); | ||
| const trafficSource = parseTrafficSource( | ||
| url, | ||
| this.options.referral?.queryParams, | ||
| this.options.referral?.pathPattern | ||
| ); | ||
| storeTrafficSource(trafficSource); | ||
| logger.debug("Traffic source set from URL:", trafficSource); | ||
| } | ||
|
|
@@ -197,6 +215,11 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| public async cleanup(): Promise<void> { | ||
| logger.info("FormoAnalytics: Cleaning up resources"); | ||
|
|
||
| if (this.lifecycleManager) { | ||
| this.lifecycleManager.cleanup(); | ||
| this.lifecycleManager = undefined; | ||
| } | ||
|
|
||
| if (this.wagmiHandler) { | ||
| this.wagmiHandler.cleanup(); | ||
| this.wagmiHandler = undefined; | ||
|
|
@@ -325,7 +348,7 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| signatureHash, | ||
| }: { | ||
| status: SignatureStatus; | ||
| chainId: ChainID; | ||
| chainId?: ChainID; | ||
| address: Address; | ||
| message: string; | ||
| signatureHash?: string; | ||
|
|
@@ -334,10 +357,6 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| context?: IFormoEventContext, | ||
| callback?: (...args: unknown[]) => void | ||
| ): Promise<void> { | ||
| if (chainId === null || chainId === undefined || Number(chainId) === 0) { | ||
| logger.warn("Signature: Chain ID cannot be null, undefined, or 0"); | ||
| return; | ||
| } | ||
| if (!address) { | ||
| logger.warn("Signature: Address cannot be empty"); | ||
| return; | ||
|
|
@@ -346,7 +365,7 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| EventType.SIGNATURE, | ||
| { | ||
| status, | ||
| chainId, | ||
| ...(chainId !== undefined && chainId !== null && { chainId }), | ||
| address, | ||
| message, | ||
| ...(signatureHash && { signatureHash }), | ||
|
|
@@ -369,6 +388,8 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| to, | ||
| value, | ||
| transactionHash, | ||
| function_name, | ||
| function_args, | ||
| }: { | ||
| status: TransactionStatus; | ||
| chainId: ChainID; | ||
|
|
@@ -377,6 +398,8 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| to?: string; | ||
| value?: string; | ||
| transactionHash?: string; | ||
| function_name?: string; | ||
| function_args?: Record<string, unknown>; | ||
| }, | ||
| properties?: IFormoEventProperties, | ||
| context?: IFormoEventContext, | ||
|
|
@@ -400,6 +423,8 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| to, | ||
| value, | ||
| ...(transactionHash && { transactionHash }), | ||
| ...(function_name && { function_name }), | ||
| ...(function_args && { function_args }), | ||
| }, | ||
| properties, | ||
| context, | ||
|
|
@@ -544,7 +569,7 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| * Check if autocapture is enabled for event type | ||
| */ | ||
| public isAutocaptureEnabled( | ||
| eventType: "connect" | "disconnect" | "signature" | "transaction" | "chain" | ||
| eventType: "connect" | "disconnect" | "signature" | "transaction" | "chain" | "lifecycle" | ||
| ): boolean { | ||
| if (this.options.autocapture === undefined) { | ||
| return true; | ||
|
|
@@ -596,6 +621,13 @@ export class FormoAnalytics implements IFormoAnalytics { | |
| ); | ||
| } catch (error) { | ||
| logger.error("Error tracking event:", error); | ||
| if (this.options.errorHandler) { | ||
| try { | ||
| this.options.errorHandler(error instanceof Error ? error : new Error(String(error))); | ||
| } catch (handlerError) { | ||
| logger.error("Error in errorHandler callback:", handlerError); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 New The PR adds two new options to (Refers to lines 140-160) Prompt for agentsWas this helpful? React with 👍 or 👎 to provide feedback. |
Uh oh!
There was an error while loading. Please reload this page.