@formo/analytics-react-native 1.0.0 → 1.0.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.
- package/lib/commonjs/FormoAnalytics.js +141 -12
- package/lib/commonjs/FormoAnalytics.js.map +1 -1
- package/lib/commonjs/FormoAnalyticsProvider.js +3 -0
- package/lib/commonjs/FormoAnalyticsProvider.js.map +1 -1
- package/lib/commonjs/constants/events.js +30 -3
- package/lib/commonjs/constants/events.js.map +1 -1
- package/lib/commonjs/lib/crash/index.js +121 -0
- package/lib/commonjs/lib/crash/index.js.map +1 -0
- package/lib/commonjs/lib/event/EventFactory.js +88 -8
- package/lib/commonjs/lib/event/EventFactory.js.map +1 -1
- package/lib/commonjs/lib/lifecycle/index.js +29 -6
- package/lib/commonjs/lib/lifecycle/index.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/module/FormoAnalytics.js +138 -8
- package/lib/module/FormoAnalytics.js.map +1 -1
- package/lib/module/FormoAnalyticsProvider.js +3 -0
- package/lib/module/FormoAnalyticsProvider.js.map +1 -1
- package/lib/module/constants/events.js +29 -2
- package/lib/module/constants/events.js.map +1 -1
- package/lib/module/lib/crash/index.js +117 -0
- package/lib/module/lib/crash/index.js.map +1 -0
- package/lib/module/lib/event/EventFactory.js +86 -8
- package/lib/module/lib/event/EventFactory.js.map +1 -1
- package/lib/module/lib/lifecycle/index.js +29 -6
- package/lib/module/lib/lifecycle/index.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/typescript/commonjs/FormoAnalytics.d.ts +52 -1
- package/lib/typescript/commonjs/FormoAnalytics.d.ts.map +1 -1
- package/lib/typescript/commonjs/FormoAnalyticsProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/constants/events.d.ts +23 -0
- package/lib/typescript/commonjs/constants/events.d.ts.map +1 -1
- package/lib/typescript/commonjs/lib/crash/index.d.ts +41 -0
- package/lib/typescript/commonjs/lib/crash/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/lib/event/EventFactory.d.ts +26 -7
- package/lib/typescript/commonjs/lib/event/EventFactory.d.ts.map +1 -1
- package/lib/typescript/commonjs/lib/lifecycle/index.d.ts +10 -0
- package/lib/typescript/commonjs/lib/lifecycle/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/types/base.d.ts +40 -0
- package/lib/typescript/commonjs/types/base.d.ts.map +1 -1
- package/lib/typescript/commonjs/version.d.ts +1 -1
- package/lib/typescript/module/FormoAnalytics.d.ts +52 -1
- package/lib/typescript/module/FormoAnalytics.d.ts.map +1 -1
- package/lib/typescript/module/FormoAnalyticsProvider.d.ts.map +1 -1
- package/lib/typescript/module/constants/events.d.ts +23 -0
- package/lib/typescript/module/constants/events.d.ts.map +1 -1
- package/lib/typescript/module/lib/crash/index.d.ts +41 -0
- package/lib/typescript/module/lib/crash/index.d.ts.map +1 -0
- package/lib/typescript/module/lib/event/EventFactory.d.ts +26 -7
- package/lib/typescript/module/lib/event/EventFactory.d.ts.map +1 -1
- package/lib/typescript/module/lib/lifecycle/index.d.ts +10 -0
- package/lib/typescript/module/lib/lifecycle/index.d.ts.map +1 -1
- package/lib/typescript/module/types/base.d.ts +40 -0
- package/lib/typescript/module/types/base.d.ts.map +1 -1
- package/lib/typescript/module/version.d.ts +1 -1
- package/package.json +8 -8
- package/src/FormoAnalytics.ts +151 -8
- package/src/FormoAnalyticsProvider.tsx +3 -0
- package/src/constants/events.ts +32 -2
- package/src/lib/crash/index.ts +145 -0
- package/src/lib/event/EventFactory.ts +115 -21
- package/src/lib/lifecycle/index.ts +35 -6
- package/src/types/base.ts +47 -0
- package/src/version.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormoAnalyticsProvider.d.ts","sourceRoot":"","sources":["../../../src/FormoAnalyticsProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAOZ,EAAE,EACH,MAAM,OAAO,CAAC;AAIf,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"FormoAnalyticsProvider.d.ts","sourceRoot":"","sources":["../../../src/FormoAnalyticsProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAOZ,EAAE,EACH,MAAM,OAAO,CAAC;AAIf,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAyBvE,eAAO,MAAM,qBAAqB,gCACc,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,sBAAsB,EAAE,EAAE,CAAC,2BAA2B,CAwBlE,CAAC;AAgMF,eAAO,MAAM,QAAQ,QAAO,eAmB3B,CAAC"}
|
|
@@ -21,4 +21,27 @@ export type TEventChannel = Lowercase<EventChannel>;
|
|
|
21
21
|
export declare const CHANNEL: TEventChannel;
|
|
22
22
|
export declare const VERSION = "0";
|
|
23
23
|
export declare const SESSION_TIMEOUT_MS: number;
|
|
24
|
+
/**
|
|
25
|
+
* Reserved lifecycle and campaign event names, per the Segment spec that
|
|
26
|
+
* RudderStack, PostHog and Amplitude all adopted verbatim.
|
|
27
|
+
*
|
|
28
|
+
* These are ordinary `track` events on the wire — the names are what make them
|
|
29
|
+
* recognisable to downstream analytics, so they must match the spec exactly,
|
|
30
|
+
* including capitalisation and spacing.
|
|
31
|
+
*
|
|
32
|
+
* @see https://segment.com/docs/connections/spec/mobile/
|
|
33
|
+
*/
|
|
34
|
+
export declare const LIFECYCLE_EVENT: {
|
|
35
|
+
readonly APPLICATION_INSTALLED: "Application Installed";
|
|
36
|
+
readonly APPLICATION_UPDATED: "Application Updated";
|
|
37
|
+
readonly APPLICATION_OPENED: "Application Opened";
|
|
38
|
+
readonly APPLICATION_BACKGROUNDED: "Application Backgrounded";
|
|
39
|
+
readonly APPLICATION_FOREGROUNDED: "Application Foregrounded";
|
|
40
|
+
readonly APPLICATION_CRASHED: "Application Crashed";
|
|
41
|
+
readonly DEEP_LINK_OPENED: "Deep Link Opened";
|
|
42
|
+
readonly PUSH_NOTIFICATION_RECEIVED: "Push Notification Received";
|
|
43
|
+
readonly PUSH_NOTIFICATION_TAPPED: "Push Notification Tapped";
|
|
44
|
+
readonly PUSH_NOTIFICATION_BOUNCED: "Push Notification Bounced";
|
|
45
|
+
};
|
|
46
|
+
export type TLifecycleEvent = (typeof LIFECYCLE_EVENT)[keyof typeof LIFECYCLE_EVENT];
|
|
24
47
|
//# sourceMappingURL=events.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../../src/constants/events.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,KAAK,UAAU;IACf,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,KAAK,UAAU;CAChB;AAED,oBAAY,YAAY;IACtB,GAAG,QAAQ;IACX,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;AAC9C,MAAM,MAAM,aAAa,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;AAGpD,eAAO,MAAM,OAAO,EAAE,aAAwB,CAAC;AAC/C,eAAO,MAAM,OAAO,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../../src/constants/events.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,KAAK,UAAU;IACf,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,KAAK,UAAU;CAChB;AAED,oBAAY,YAAY;IACtB,GAAG,QAAQ;IACX,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;AAC9C,MAAM,MAAM,aAAa,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;AAGpD,eAAO,MAAM,OAAO,EAAE,aAAwB,CAAC;AAC/C,eAAO,MAAM,OAAO,MAAM,CAAC;AAQ3B,eAAO,MAAM,kBAAkB,QAAiB,CAAC;AAEjD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;CAWlB,CAAC;AAEX,MAAM,MAAM,eAAe,GACzB,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JavaScript crash reporting.
|
|
3
|
+
*
|
|
4
|
+
* Emits the Segment-spec `Application Crashed` event for unhandled JS errors by
|
|
5
|
+
* wrapping React Native's global error handler.
|
|
6
|
+
*
|
|
7
|
+
* Scope: JavaScript errors only. A native crash (a Swift/Kotlin exception, an
|
|
8
|
+
* OOM kill, a watchdog termination) never reaches the JS runtime, so it cannot
|
|
9
|
+
* be observed from here — that needs a native crash reporter.
|
|
10
|
+
*/
|
|
11
|
+
/** Interface for the analytics instance to avoid circular deps */
|
|
12
|
+
interface IAnalyticsInstance {
|
|
13
|
+
track(event: string, properties?: Record<string, unknown>): Promise<void>;
|
|
14
|
+
flush(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export declare class CrashReporter {
|
|
17
|
+
private analytics;
|
|
18
|
+
private previousHandler;
|
|
19
|
+
private installedHandler;
|
|
20
|
+
private started;
|
|
21
|
+
constructor(analytics: IAnalyticsInstance);
|
|
22
|
+
/**
|
|
23
|
+
* Install the global error handler.
|
|
24
|
+
*
|
|
25
|
+
* The previous handler is always called afterwards — React Native's default
|
|
26
|
+
* handler is what shows the redbox in dev and terminates the app on a fatal
|
|
27
|
+
* error in production, and a customer's crash reporter (Sentry, Bugsnag) may
|
|
28
|
+
* also be in the chain. Swallowing it would break both.
|
|
29
|
+
*/
|
|
30
|
+
start(): void;
|
|
31
|
+
private report;
|
|
32
|
+
/**
|
|
33
|
+
* Restore the previous handler.
|
|
34
|
+
*
|
|
35
|
+
* Only restores if ours is still the installed handler — if something else
|
|
36
|
+
* wrapped us afterwards, replacing the chain would unhook that too.
|
|
37
|
+
*/
|
|
38
|
+
cleanup(): void;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/crash/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAaH,kEAAkE;AAClE,UAAU,kBAAkB;IAC1B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAWD,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,OAAO,CAAS;gBAEZ,SAAS,EAAE,kBAAkB;IAIzC;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI;IA4Cb,OAAO,CAAC,MAAM;IAqBd;;;;;OAKG;IACH,OAAO,IAAI,IAAI;CAkBhB"}
|
|
@@ -20,15 +20,20 @@ import { IEventFactory } from "./types";
|
|
|
20
20
|
*/
|
|
21
21
|
export declare function getSessionId(): string;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Compose a screen view's `page_url` as `app://<bundle id>/<screen>`.
|
|
24
24
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
25
|
+
* Well-formed on purpose: the bundle id occupies the authority slot and the
|
|
26
|
+
* screen the path, so a standard URL parser yields both without any
|
|
27
|
+
* mobile-specific handling — the same shape as `https://<host>/<path>`.
|
|
28
|
+
*
|
|
29
|
+
* @param bundleId Application bundle id, e.g. "com.acme.wallet". When empty the
|
|
30
|
+
* authority is omitted (`app:///<screen>`), which still parses to a correct
|
|
31
|
+
* path; the pipeline resolves origin from context in that case.
|
|
32
|
+
* @param name Screen name. Leading slashes are stripped so a router-style name
|
|
33
|
+
* ("/tabs/leaderboard") does not produce a doubled separator.
|
|
31
34
|
*/
|
|
35
|
+
export declare function buildScreenUrl(bundleId: string, name: string): string;
|
|
36
|
+
export declare function resolveExpoDeviceType(deviceType: number | null | undefined, tabletEnumValue: number | null | undefined): "tablet" | "mobile";
|
|
32
37
|
export declare function synthesizeUserAgent(info: {
|
|
33
38
|
os_name: string;
|
|
34
39
|
os_version: string;
|
|
@@ -41,6 +46,8 @@ export declare function synthesizeUserAgent(info: {
|
|
|
41
46
|
*/
|
|
42
47
|
declare class EventFactory implements IEventFactory {
|
|
43
48
|
private options?;
|
|
49
|
+
/** Memoised device/app identity — see getDeviceInfo(). */
|
|
50
|
+
private deviceInfoPromise?;
|
|
44
51
|
constructor(options?: Options);
|
|
45
52
|
/**
|
|
46
53
|
* Get device timezone
|
|
@@ -66,7 +73,19 @@ declare class EventFactory implements IEventFactory {
|
|
|
66
73
|
* Get device information
|
|
67
74
|
* Supports both react-native-device-info (bare RN) and expo-device/expo-application (Expo Go)
|
|
68
75
|
*/
|
|
76
|
+
/**
|
|
77
|
+
* The app bundle id as it will appear in context.
|
|
78
|
+
*
|
|
79
|
+
* Must mirror generateContext's precedence: an explicitly configured
|
|
80
|
+
* `options.app.bundleId` overrides whatever the native modules report. Reading
|
|
81
|
+
* getDeviceInfo() alone would ignore that configuration and silently fall back
|
|
82
|
+
* to the authority-less URL form — and on React Native Web, where neither
|
|
83
|
+
* react-native-device-info nor expo-application resolves a bundle id, that is
|
|
84
|
+
* the ONLY value available.
|
|
85
|
+
*/
|
|
86
|
+
private resolveAppBundleId;
|
|
69
87
|
private getDeviceInfo;
|
|
88
|
+
private resolveDeviceInfo;
|
|
70
89
|
/**
|
|
71
90
|
* Generate context with mobile-specific metadata
|
|
72
91
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventFactory.d.ts","sourceRoot":"","sources":["../../../../../src/lib/event/EventFactory.ts"],"names":[],"mappings":"AAoCA,OAAO,EACL,OAAO,EACP,QAAQ,EACR,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,qBAAqB,EACrB,QAAQ,EACR,OAAO,EACP,eAAe,EACf,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAWrB,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAiBxC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAcrC;
|
|
1
|
+
{"version":3,"file":"EventFactory.d.ts","sourceRoot":"","sources":["../../../../../src/lib/event/EventFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,8 +6,15 @@
|
|
|
6
6
|
* - Application Updated (version/build changed)
|
|
7
7
|
* - Application Opened (every cold start + foreground return)
|
|
8
8
|
* - Application Backgrounded (app goes to background)
|
|
9
|
+
* - Application Foregrounded (foreground return; opt-in, see AutocaptureOptions)
|
|
9
10
|
*
|
|
10
11
|
* Detection is JS-side using AsyncStorage (no native modules required).
|
|
12
|
+
*
|
|
13
|
+
* The remaining spec events live outside this manager because they are not
|
|
14
|
+
* AppState-driven: `Deep Link Opened` is emitted from the Linking hook in
|
|
15
|
+
* FormoAnalytics, `Application Crashed` from lib/crash, and the push
|
|
16
|
+
* notification events from explicit FormoAnalytics methods (the SDK cannot
|
|
17
|
+
* observe push delivery without a native module).
|
|
11
18
|
*/
|
|
12
19
|
/** Interface for the analytics instance to avoid circular deps */
|
|
13
20
|
interface IAnalyticsInstance {
|
|
@@ -18,6 +25,7 @@ export declare class AppLifecycleManager {
|
|
|
18
25
|
private appStateSubscription;
|
|
19
26
|
private lastAppState;
|
|
20
27
|
private appVersionInfo;
|
|
28
|
+
private trackForegrounded;
|
|
21
29
|
constructor(analytics: IAnalyticsInstance);
|
|
22
30
|
/**
|
|
23
31
|
* Initialize lifecycle tracking.
|
|
@@ -26,6 +34,8 @@ export declare class AppLifecycleManager {
|
|
|
26
34
|
start(appOptions?: {
|
|
27
35
|
version?: string;
|
|
28
36
|
build?: string;
|
|
37
|
+
}, options?: {
|
|
38
|
+
trackForegrounded?: boolean;
|
|
29
39
|
}): Promise<void>;
|
|
30
40
|
/**
|
|
31
41
|
* Compare stored version/build with current to detect install or update.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/lifecycle/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/lifecycle/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAYH,kEAAkE;AAClE,UAAU,kBAAkB;IAC1B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E;AAgDD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,oBAAoB,CAAuC;IACnE,OAAO,CAAC,YAAY,CAAyC;IAC7D,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,iBAAiB,CAAS;gBAEtB,SAAS,EAAE,kBAAkB;IAIzC;;;OAGG;IACG,KAAK,CACT,UAAU,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EACjD,OAAO,CAAC,EAAE;QAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,GACxC,OAAO,CAAC,IAAI,CAAC;IAkChB;;;;OAIG;YACW,qBAAqB;IAkDnC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAoD5B;;OAEG;IACH,OAAO,IAAI,IAAI;CAOhB"}
|
|
@@ -49,6 +49,9 @@ export interface IFormoAnalytics {
|
|
|
49
49
|
rdns?: string;
|
|
50
50
|
}, properties?: IFormoEventProperties, context?: IFormoEventContext, callback?: (...args: unknown[]) => void): Promise<void>;
|
|
51
51
|
track(event: string, properties?: IFormoEventProperties, context?: IFormoEventContext, callback?: (...args: unknown[]) => void): Promise<void>;
|
|
52
|
+
pushNotificationReceived(properties?: IFormoEventProperties): Promise<void>;
|
|
53
|
+
pushNotificationTapped(properties?: IFormoEventProperties): Promise<void>;
|
|
54
|
+
pushNotificationBounced(properties?: IFormoEventProperties): Promise<void>;
|
|
52
55
|
flush(): Promise<void>;
|
|
53
56
|
setTrafficSourceFromUrl(url: string): void;
|
|
54
57
|
optOutTracking(): void;
|
|
@@ -99,6 +102,43 @@ export interface AutocaptureOptions {
|
|
|
99
102
|
* @default true
|
|
100
103
|
*/
|
|
101
104
|
lifecycle?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Emit `Application Foregrounded` on every background → active transition,
|
|
107
|
+
* in addition to the `Application Opened` (with `from_background: true`) that
|
|
108
|
+
* already fires there.
|
|
109
|
+
*
|
|
110
|
+
* Off by default because it doubles foreground event volume and adds no
|
|
111
|
+
* information: `Application Opened` with `from_background: true` already
|
|
112
|
+
* marks the same transition. Enable it if you consume the Segment spec's
|
|
113
|
+
* `Application Foregrounded` name directly — e.g. when migrating dashboards
|
|
114
|
+
* or destinations from Segment or RudderStack. Requires `lifecycle`.
|
|
115
|
+
* @default false
|
|
116
|
+
*/
|
|
117
|
+
foregrounded?: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Track `Deep Link Opened` when the app is launched or resumed via a deep
|
|
120
|
+
* link or universal link, with the `url` property.
|
|
121
|
+
*
|
|
122
|
+
* Independent of `attribution.deeplinks`, which controls whether the link's
|
|
123
|
+
* UTM/referral parameters are parsed into event context. This option is only
|
|
124
|
+
* about emitting the event; the SDK still needs `attribution.deeplinks` to
|
|
125
|
+
* observe links at all.
|
|
126
|
+
* @default true
|
|
127
|
+
*/
|
|
128
|
+
deepLinks?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Track `Application Crashed` on unhandled JavaScript errors, with the error
|
|
131
|
+
* message, stack, and whether React Native considered it fatal.
|
|
132
|
+
*
|
|
133
|
+
* Off by default because enabling it installs a global error handler
|
|
134
|
+
* (`ErrorUtils.setGlobalHandler`). The previous handler is always invoked
|
|
135
|
+
* afterwards, so React Native's redbox and any crash reporter you already use
|
|
136
|
+
* keep working — but installing one implicitly on an SDK upgrade is a
|
|
137
|
+
* surprise, so it is opt-in. Covers JS errors only: native crashes need a
|
|
138
|
+
* native crash reporter.
|
|
139
|
+
* @default false
|
|
140
|
+
*/
|
|
141
|
+
crashes?: boolean;
|
|
102
142
|
}
|
|
103
143
|
/**
|
|
104
144
|
* Configuration options for attribution capture.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/types/base.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/types/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "1.0.
|
|
1
|
+
export declare const version = "1.0.2";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formo/analytics-react-native",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Formo Analytics SDK for React Native - Track wallet events and user analytics in mobile dApps",
|
|
5
5
|
"packageManager": "pnpm@11.1.1",
|
|
6
6
|
"repository": {
|
|
@@ -99,24 +99,24 @@
|
|
|
99
99
|
"ethereum-cryptography": "3.2.0"
|
|
100
100
|
},
|
|
101
101
|
"devDependencies": {
|
|
102
|
-
"@babel/preset-env": "^
|
|
103
|
-
"@babel/preset-react": "^
|
|
102
|
+
"@babel/preset-env": "^8.0.2",
|
|
103
|
+
"@babel/preset-react": "^8.0.1",
|
|
104
104
|
"@babel/preset-typescript": "^7.28.5",
|
|
105
105
|
"@react-native-async-storage/async-storage": "^1.21.0",
|
|
106
|
-
"@react-native/babel-preset": "^0.
|
|
106
|
+
"@react-native/babel-preset": "^0.86.0",
|
|
107
107
|
"@types/jest": "^30.0.0",
|
|
108
108
|
"@types/react": "^19.2.14",
|
|
109
109
|
"@typescript-eslint/eslint-plugin": "^8.59.3",
|
|
110
110
|
"@typescript-eslint/parser": "^8.59.3",
|
|
111
111
|
"babel-jest": "^30.4.1",
|
|
112
112
|
"eslint": "^10.3.0",
|
|
113
|
-
"expo-application": "^
|
|
114
|
-
"expo-device": "^
|
|
113
|
+
"expo-application": "^57.0.2",
|
|
114
|
+
"expo-device": "^57.0.1",
|
|
115
115
|
"jest": "^30.4.1",
|
|
116
116
|
"react": "^19.2.6",
|
|
117
|
-
"react-native": "^0.
|
|
117
|
+
"react-native": "^0.86.0",
|
|
118
118
|
"react-native-builder-bob": "^0.41.0",
|
|
119
|
-
"react-native-device-info": "^
|
|
119
|
+
"react-native-device-info": "^15.0.2",
|
|
120
120
|
"typescript": "^6.0.3",
|
|
121
121
|
"typescript-eslint": "^8.59.3"
|
|
122
122
|
},
|
package/src/FormoAnalytics.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
CONSENT_OPT_OUT_KEY,
|
|
15
15
|
TEventType,
|
|
16
16
|
} from "./constants";
|
|
17
|
+
import { LIFECYCLE_EVENT } from "./constants/events";
|
|
17
18
|
import { initStorageManager, storage, AsyncStorageInterface } from "./lib/storage";
|
|
18
19
|
import { EventManager, EventQueue, IEventManager } from "./lib/event";
|
|
19
20
|
import { logger, Logger } from "./lib/logger";
|
|
@@ -25,6 +26,7 @@ import {
|
|
|
25
26
|
import { FormoAnalyticsSession } from "./lib/session";
|
|
26
27
|
import { WagmiEventHandler } from "./lib/wagmi";
|
|
27
28
|
import { AppLifecycleManager } from "./lib/lifecycle";
|
|
29
|
+
import { CrashReporter } from "./lib/crash";
|
|
28
30
|
import {
|
|
29
31
|
Address,
|
|
30
32
|
ChainID,
|
|
@@ -42,12 +44,21 @@ import { parseTrafficSource, updateStoredTrafficSource } from "./utils/trafficSo
|
|
|
42
44
|
import { captureInstallReferrer } from "./lib/installReferrer";
|
|
43
45
|
import { Linking, EmitterSubscription } from "react-native";
|
|
44
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Autocapture behaviors that are OFF unless explicitly enabled, because
|
|
49
|
+
* turning them on by default would change how an existing app behaves after a
|
|
50
|
+
* routine SDK upgrade. See AutocaptureOptions for the reasoning per option.
|
|
51
|
+
*/
|
|
52
|
+
const OPT_IN_AUTOCAPTURE = new Set<string>(["foregrounded", "crashes"]);
|
|
53
|
+
|
|
45
54
|
export class FormoAnalytics implements IFormoAnalytics {
|
|
46
55
|
private session: FormoAnalyticsSession;
|
|
47
56
|
private eventManager: IEventManager;
|
|
48
57
|
private eventQueue: EventQueue;
|
|
49
58
|
private wagmiHandler?: WagmiEventHandler;
|
|
50
59
|
private lifecycleManager?: AppLifecycleManager;
|
|
60
|
+
private crashReporter?: CrashReporter;
|
|
61
|
+
private initialDeepLinkUrl?: string;
|
|
51
62
|
private linkingSubscription?: EmitterSubscription;
|
|
52
63
|
|
|
53
64
|
config: Config;
|
|
@@ -142,7 +153,16 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
142
153
|
// is a fast native bridge call; the Android Play Install Referrer is a fast
|
|
143
154
|
// one-shot native call (and no-ops instantly when the native module or the
|
|
144
155
|
// platform isn't Android), so awaiting it does not meaningfully delay init.
|
|
145
|
-
if
|
|
156
|
+
// Hook Linking if EITHER consumer needs it. The two flags control different
|
|
157
|
+
// things — attribution.deeplinks parses UTMs into context, autocapture
|
|
158
|
+
// .deepLinks emits Deep Link Opened — but both depend on observing the link
|
|
159
|
+
// in the first place. Gating the hook on attribution alone silently
|
|
160
|
+
// disabled the event for anyone who turned attribution off, with no
|
|
161
|
+
// indication that an unrelated setting was responsible.
|
|
162
|
+
if (
|
|
163
|
+
analytics.isAttributionEnabled("deeplinks") ||
|
|
164
|
+
analytics.isAutocaptureEnabled("deepLinks")
|
|
165
|
+
) {
|
|
146
166
|
try {
|
|
147
167
|
await analytics.startDeepLinkCapture();
|
|
148
168
|
} catch (error) {
|
|
@@ -166,12 +186,32 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
166
186
|
if (analytics.isAutocaptureEnabled("lifecycle")) {
|
|
167
187
|
try {
|
|
168
188
|
analytics.lifecycleManager = new AppLifecycleManager(analytics);
|
|
169
|
-
await analytics.lifecycleManager.start(options?.app
|
|
189
|
+
await analytics.lifecycleManager.start(options?.app, {
|
|
190
|
+
trackForegrounded: analytics.isAutocaptureEnabled("foregrounded"),
|
|
191
|
+
});
|
|
170
192
|
} catch (error) {
|
|
171
193
|
logger.error("FormoAnalytics: Failed to initialize lifecycle tracking", error);
|
|
172
194
|
}
|
|
173
195
|
}
|
|
174
196
|
|
|
197
|
+
// Emit Deep Link Opened for the launch URL AFTER lifecycle tracking, so it
|
|
198
|
+
// follows Application Opened as the Segment spec orders it.
|
|
199
|
+
try {
|
|
200
|
+
await analytics.trackInitialDeepLink();
|
|
201
|
+
} catch (error) {
|
|
202
|
+
logger.error("FormoAnalytics: Failed to track initial deep link", error);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Opt-in: installs a global JS error handler (chained, never swallowing).
|
|
206
|
+
if (analytics.isAutocaptureEnabled("crashes")) {
|
|
207
|
+
try {
|
|
208
|
+
analytics.crashReporter = new CrashReporter(analytics);
|
|
209
|
+
analytics.crashReporter.start();
|
|
210
|
+
} catch (error) {
|
|
211
|
+
logger.error("FormoAnalytics: Failed to initialize crash tracking", error);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
175
215
|
// Call ready callback
|
|
176
216
|
if (options?.ready) {
|
|
177
217
|
options.ready(analytics);
|
|
@@ -188,17 +228,102 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
188
228
|
private async startDeepLinkCapture(): Promise<void> {
|
|
189
229
|
try {
|
|
190
230
|
const url = await Linking.getInitialURL();
|
|
191
|
-
if (url)
|
|
231
|
+
if (url) {
|
|
232
|
+
if (this.isAttributionEnabled("deeplinks")) {
|
|
233
|
+
this.setTrafficSourceFromUrl(url);
|
|
234
|
+
}
|
|
235
|
+
// Held, not emitted: this runs before lifecycle tracking starts, and
|
|
236
|
+
// the Segment spec orders `Deep Link Opened` after `Application
|
|
237
|
+
// Opened`. Emitted by trackInitialDeepLink() once lifecycle has fired.
|
|
238
|
+
this.initialDeepLinkUrl = url;
|
|
239
|
+
}
|
|
192
240
|
} catch (error) {
|
|
193
241
|
logger.debug("FormoAnalytics: Linking.getInitialURL failed", error);
|
|
194
242
|
}
|
|
195
243
|
|
|
196
244
|
// Runtime deep links (foreground opens, universal links).
|
|
197
245
|
this.linkingSubscription = Linking.addEventListener("url", (event) => {
|
|
198
|
-
if (event?.url)
|
|
246
|
+
if (!event?.url) return;
|
|
247
|
+
// Each behaviour checks its own flag: the hook may exist because only one
|
|
248
|
+
// of them is enabled.
|
|
249
|
+
if (this.isAttributionEnabled("deeplinks")) {
|
|
250
|
+
this.setTrafficSourceFromUrl(event.url);
|
|
251
|
+
}
|
|
252
|
+
void this.trackDeepLinkOpened(event.url);
|
|
199
253
|
});
|
|
200
254
|
}
|
|
201
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Emit `Deep Link Opened` for the URL the app was launched with, if any.
|
|
258
|
+
* Separate from capture so it can be ordered after `Application Opened`.
|
|
259
|
+
*/
|
|
260
|
+
private async trackInitialDeepLink(): Promise<void> {
|
|
261
|
+
const url = this.initialDeepLinkUrl;
|
|
262
|
+
this.initialDeepLinkUrl = undefined;
|
|
263
|
+
if (url) await this.trackDeepLinkOpened(url);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Emit the Segment-spec `Deep Link Opened` event.
|
|
268
|
+
*
|
|
269
|
+
* `provider` is deliberately omitted: the spec uses it to name the
|
|
270
|
+
* attribution provider that resolved the link (Branch, Adjust, …). The SDK
|
|
271
|
+
* reads the link straight from React Native's Linking API, so there is no
|
|
272
|
+
* provider to name, and emitting a placeholder would misreport the source.
|
|
273
|
+
*/
|
|
274
|
+
private async trackDeepLinkOpened(url: string): Promise<void> {
|
|
275
|
+
if (!this.isAutocaptureEnabled("deepLinks")) return;
|
|
276
|
+
try {
|
|
277
|
+
await this.track(LIFECYCLE_EVENT.DEEP_LINK_OPENED, { url });
|
|
278
|
+
} catch (error) {
|
|
279
|
+
logger.error("FormoAnalytics: Error tracking Deep Link Opened", error);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Track that a push notification was delivered to the device.
|
|
285
|
+
*
|
|
286
|
+
* Push delivery cannot be observed without a native module, so the SDK
|
|
287
|
+
* cannot autocapture these — call this from your push handler
|
|
288
|
+
* (`@react-native-firebase/messaging`, `expo-notifications`, …).
|
|
289
|
+
*
|
|
290
|
+
* @param properties Segment's push spec suggests `campaign_id`, `campaign_name`,
|
|
291
|
+
* `message_id`, `action` and `title`/`body`. Any properties are accepted.
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* ```tsx
|
|
295
|
+
* messaging().onMessage(async (message) => {
|
|
296
|
+
* await formo.pushNotificationReceived({ message_id: message.messageId });
|
|
297
|
+
* });
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
public async pushNotificationReceived(
|
|
301
|
+
properties?: IFormoEventProperties
|
|
302
|
+
): Promise<void> {
|
|
303
|
+
await this.track(LIFECYCLE_EVENT.PUSH_NOTIFICATION_RECEIVED, properties);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Track that the user opened the app by tapping a push notification.
|
|
308
|
+
* See {@link pushNotificationReceived} for why this is not autocaptured.
|
|
309
|
+
*/
|
|
310
|
+
public async pushNotificationTapped(
|
|
311
|
+
properties?: IFormoEventProperties
|
|
312
|
+
): Promise<void> {
|
|
313
|
+
await this.track(LIFECYCLE_EVENT.PUSH_NOTIFICATION_TAPPED, properties);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Track that a push notification was not delivered — e.g. the OS suppressed
|
|
318
|
+
* it, or the device token was rejected.
|
|
319
|
+
* See {@link pushNotificationReceived} for why this is not autocaptured.
|
|
320
|
+
*/
|
|
321
|
+
public async pushNotificationBounced(
|
|
322
|
+
properties?: IFormoEventProperties
|
|
323
|
+
): Promise<void> {
|
|
324
|
+
await this.track(LIFECYCLE_EVENT.PUSH_NOTIFICATION_BOUNCED, properties);
|
|
325
|
+
}
|
|
326
|
+
|
|
202
327
|
/**
|
|
203
328
|
* Track a screen view (mobile equivalent of page view)
|
|
204
329
|
*/
|
|
@@ -272,6 +397,11 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
272
397
|
public async cleanup(): Promise<void> {
|
|
273
398
|
logger.info("FormoAnalytics: Cleaning up resources");
|
|
274
399
|
|
|
400
|
+
if (this.crashReporter) {
|
|
401
|
+
this.crashReporter.cleanup();
|
|
402
|
+
this.crashReporter = undefined;
|
|
403
|
+
}
|
|
404
|
+
|
|
275
405
|
if (this.lifecycleManager) {
|
|
276
406
|
this.lifecycleManager.cleanup();
|
|
277
407
|
this.lifecycleManager = undefined;
|
|
@@ -631,6 +761,12 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
631
761
|
* Applies only to event-generating behaviors (wallet events, lifecycle
|
|
632
762
|
* events). Attribution is controlled separately via `options.attribution`
|
|
633
763
|
* because it enriches events rather than generating them.
|
|
764
|
+
*
|
|
765
|
+
* Most behaviors are on unless explicitly disabled. The two in
|
|
766
|
+
* {@link OPT_IN_AUTOCAPTURE} invert that and require an explicit `true`,
|
|
767
|
+
* because switching them on by default would change existing apps on a
|
|
768
|
+
* version bump: `foregrounded` doubles foreground event volume, and
|
|
769
|
+
* `crashes` installs a global error handler.
|
|
634
770
|
*/
|
|
635
771
|
public isAutocaptureEnabled(
|
|
636
772
|
eventType:
|
|
@@ -640,13 +776,20 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
640
776
|
| "transaction"
|
|
641
777
|
| "chain"
|
|
642
778
|
| "lifecycle"
|
|
779
|
+
| "foregrounded"
|
|
780
|
+
| "deepLinks"
|
|
781
|
+
| "crashes"
|
|
643
782
|
): boolean {
|
|
783
|
+
const isOptIn = OPT_IN_AUTOCAPTURE.has(eventType);
|
|
784
|
+
|
|
644
785
|
if (this.options.autocapture === undefined) {
|
|
645
|
-
return
|
|
786
|
+
return !isOptIn;
|
|
646
787
|
}
|
|
647
788
|
|
|
789
|
+
// `autocapture: true` means "the usual set", not "everything including the
|
|
790
|
+
// opt-in behaviors" — those still need naming individually.
|
|
648
791
|
if (typeof this.options.autocapture === "boolean") {
|
|
649
|
-
return this.options.autocapture;
|
|
792
|
+
return this.options.autocapture && !isOptIn;
|
|
650
793
|
}
|
|
651
794
|
|
|
652
795
|
if (
|
|
@@ -654,10 +797,10 @@ export class FormoAnalytics implements IFormoAnalytics {
|
|
|
654
797
|
typeof this.options.autocapture === "object"
|
|
655
798
|
) {
|
|
656
799
|
const eventConfig = this.options.autocapture[eventType];
|
|
657
|
-
return eventConfig !== false;
|
|
800
|
+
return isOptIn ? eventConfig === true : eventConfig !== false;
|
|
658
801
|
}
|
|
659
802
|
|
|
660
|
-
return
|
|
803
|
+
return !isOptIn;
|
|
661
804
|
}
|
|
662
805
|
|
|
663
806
|
/**
|
|
@@ -25,6 +25,9 @@ const defaultContext: IFormoAnalytics = {
|
|
|
25
25
|
transaction: () => Promise.resolve(),
|
|
26
26
|
identify: () => Promise.resolve(),
|
|
27
27
|
track: () => Promise.resolve(),
|
|
28
|
+
pushNotificationReceived: () => Promise.resolve(),
|
|
29
|
+
pushNotificationTapped: () => Promise.resolve(),
|
|
30
|
+
pushNotificationBounced: () => Promise.resolve(),
|
|
28
31
|
flush: () => Promise.resolve(),
|
|
29
32
|
setTrafficSourceFromUrl: () => {},
|
|
30
33
|
optOutTracking: () => {},
|
package/src/constants/events.ts
CHANGED
|
@@ -25,6 +25,36 @@ export type TEventChannel = Lowercase<EventChannel>;
|
|
|
25
25
|
export const CHANNEL: TEventChannel = "mobile";
|
|
26
26
|
export const VERSION = "0";
|
|
27
27
|
|
|
28
|
-
// Session inactivity timeout (30 min), matching the GA4
|
|
29
|
-
// session_id is minted once the gap since the last tracked event
|
|
28
|
+
// Session inactivity timeout (30 min), matching the GA4 default and Formo's own
|
|
29
|
+
// web SDK. A new session_id is minted once the gap since the last tracked event
|
|
30
|
+
// exceeds this. Note that mobile-first vendors run tighter: RudderStack and
|
|
31
|
+
// Amplitude both default to 5 min on mobile (vs 30 on web) and rotate on
|
|
32
|
+
// foreground rather than on inactivity. We keep 30 min so a user's mobile and
|
|
33
|
+
// web sessions are directly comparable.
|
|
30
34
|
export const SESSION_TIMEOUT_MS = 30 * 60 * 1000;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Reserved lifecycle and campaign event names, per the Segment spec that
|
|
38
|
+
* RudderStack, PostHog and Amplitude all adopted verbatim.
|
|
39
|
+
*
|
|
40
|
+
* These are ordinary `track` events on the wire — the names are what make them
|
|
41
|
+
* recognisable to downstream analytics, so they must match the spec exactly,
|
|
42
|
+
* including capitalisation and spacing.
|
|
43
|
+
*
|
|
44
|
+
* @see https://segment.com/docs/connections/spec/mobile/
|
|
45
|
+
*/
|
|
46
|
+
export const LIFECYCLE_EVENT = {
|
|
47
|
+
APPLICATION_INSTALLED: "Application Installed",
|
|
48
|
+
APPLICATION_UPDATED: "Application Updated",
|
|
49
|
+
APPLICATION_OPENED: "Application Opened",
|
|
50
|
+
APPLICATION_BACKGROUNDED: "Application Backgrounded",
|
|
51
|
+
APPLICATION_FOREGROUNDED: "Application Foregrounded",
|
|
52
|
+
APPLICATION_CRASHED: "Application Crashed",
|
|
53
|
+
DEEP_LINK_OPENED: "Deep Link Opened",
|
|
54
|
+
PUSH_NOTIFICATION_RECEIVED: "Push Notification Received",
|
|
55
|
+
PUSH_NOTIFICATION_TAPPED: "Push Notification Tapped",
|
|
56
|
+
PUSH_NOTIFICATION_BOUNCED: "Push Notification Bounced",
|
|
57
|
+
} as const;
|
|
58
|
+
|
|
59
|
+
export type TLifecycleEvent =
|
|
60
|
+
(typeof LIFECYCLE_EVENT)[keyof typeof LIFECYCLE_EVENT];
|