@appmetrica/react-native-analytics 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/src/main/AndroidManifest.xml +4 -0
  3. package/android/src/main/AndroidManifestNew.xml +5 -0
  4. package/android/src/main/java/io/appmetrica/analytics/reactnative/AppMetricaModule.java +60 -6
  5. package/android/src/main/java/io/appmetrica/analytics/reactnative/AppMetricaPackage.java +1 -0
  6. package/android/src/main/java/io/appmetrica/analytics/reactnative/ExceptionSerializer.java +91 -0
  7. package/android/src/main/java/io/appmetrica/analytics/reactnative/ExternalAttributionSerializer.java +16 -9
  8. package/android/src/main/java/io/appmetrica/analytics/reactnative/ReactNativeDeferredDeeplinkListener.java +48 -0
  9. package/android/src/main/java/io/appmetrica/analytics/reactnative/ReactNativeDeferredDeeplinkParametersListener.java +53 -0
  10. package/android/src/main/java/io/appmetrica/analytics/reactnative/ReporterModule.java +130 -0
  11. package/android/src/main/java/io/appmetrica/analytics/reactnative/Utils.java +58 -2
  12. package/appmetrica-react-native-analytics.podspec +1 -1
  13. package/ios/AMARNAppMetrica.m +77 -7
  14. package/ios/AMARNAppMetricaUtils.h +1 -0
  15. package/ios/AMARNAppMetricaUtils.m +49 -0
  16. package/ios/AMARNExceptionSerializer.h +6 -0
  17. package/ios/AMARNExceptionSerializer.m +65 -0
  18. package/ios/AMARNReporter.h +6 -0
  19. package/ios/AMARNReporter.m +131 -0
  20. package/lib/commonjs/deferredDeeplink.js +2 -0
  21. package/lib/commonjs/deferredDeeplink.js.map +1 -0
  22. package/lib/commonjs/error.js +71 -0
  23. package/lib/commonjs/error.js.map +1 -0
  24. package/lib/commonjs/index.js +53 -1
  25. package/lib/commonjs/index.js.map +1 -1
  26. package/lib/commonjs/reporter.js +69 -0
  27. package/lib/commonjs/reporter.js.map +1 -0
  28. package/lib/commonjs/revenue.js +1 -0
  29. package/lib/commonjs/revenue.js.map +1 -1
  30. package/lib/module/deferredDeeplink.js +2 -0
  31. package/lib/module/deferredDeeplink.js.map +1 -0
  32. package/lib/module/error.js +63 -0
  33. package/lib/module/error.js.map +1 -0
  34. package/lib/module/index.js +42 -1
  35. package/lib/module/index.js.map +1 -1
  36. package/lib/module/reporter.js +62 -0
  37. package/lib/module/reporter.js.map +1 -0
  38. package/lib/module/revenue.js +1 -0
  39. package/lib/module/revenue.js.map +1 -1
  40. package/lib/typescript/src/deferredDeeplink.d.ts +10 -0
  41. package/lib/typescript/src/deferredDeeplink.d.ts.map +1 -0
  42. package/lib/typescript/src/error.d.ts +19 -0
  43. package/lib/typescript/src/error.d.ts.map +1 -0
  44. package/lib/typescript/src/index.d.ts +19 -1
  45. package/lib/typescript/src/index.d.ts.map +1 -1
  46. package/lib/typescript/src/reporter.d.ts +51 -0
  47. package/lib/typescript/src/reporter.d.ts.map +1 -0
  48. package/lib/typescript/src/revenue.d.ts +1 -0
  49. package/lib/typescript/src/revenue.d.ts.map +1 -1
  50. package/package.json +3 -1
  51. package/src/deferredDeeplink.ts +11 -0
  52. package/src/error.ts +87 -0
  53. package/src/index.ts +79 -2
  54. package/src/reporter.ts +126 -0
  55. package/src/revenue.ts +1 -0
package/src/error.ts ADDED
@@ -0,0 +1,87 @@
1
+ import { Platform } from 'react-native';
2
+ import React from 'react';
3
+
4
+ const traceRegex = /^\s*at (.*?) ?\((.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
5
+
6
+ function parseTraceLine(line: string): StackTraceItem | undefined {
7
+ const parts = traceRegex.exec(line);
8
+ if (parts === null) {
9
+ return undefined;
10
+ }
11
+ return {
12
+ fileName: parts[2],
13
+ methodName: parts[1],
14
+ column: parts[3],
15
+ line: parts[4],
16
+ };
17
+ }
18
+
19
+ function getRNVersion(): string {
20
+ const versions = Platform.constants.reactNativeVersion;
21
+ return versions.major + '.' + versions.minor + '.' + versions.patch;
22
+ }
23
+
24
+ function getReactVersion(): string {
25
+ return React.version;
26
+ }
27
+
28
+ function getPluginEnvironment(): Record<string, string> | undefined {
29
+ return {
30
+ reactVersion: getReactVersion(),
31
+ };
32
+ }
33
+
34
+ function parseStackTrace(
35
+ stackTrace?: string
36
+ ): Array<StackTraceItem> | undefined {
37
+ if (stackTrace === undefined) {
38
+ return undefined;
39
+ }
40
+ try {
41
+ const lines = stackTrace.split('\n');
42
+ const array: Array<StackTraceItem> = [];
43
+ lines?.forEach((line: string) => {
44
+ const item = parseTraceLine(line);
45
+ if (item !== undefined) {
46
+ array.push(item);
47
+ }
48
+ });
49
+ return array;
50
+ } catch(e) {
51
+ console.log(e);
52
+ return undefined;
53
+ }
54
+ }
55
+
56
+ type StackTraceItem = {
57
+ fileName?: string;
58
+ className?: string;
59
+ methodName?: string;
60
+ line?: string;
61
+ column?: string;
62
+ };
63
+
64
+ export class AppMetricaError {
65
+ message?: string;
66
+ stackTrace?: Array<StackTraceItem>;
67
+ errorName?: string;
68
+ pluginEnvironment?: Record<string, string>;
69
+ virtualMachineVersion?: string;
70
+
71
+ constructor(errorName?: string, message?: string) {
72
+ this.errorName = errorName;
73
+ this.message = message;
74
+ this.pluginEnvironment = getPluginEnvironment();
75
+ this.virtualMachineVersion = getRNVersion();
76
+ }
77
+
78
+ static withError(error: Error): AppMetricaError {
79
+ const newError = new AppMetricaError(error.name, error.message);
80
+ newError.stackTrace = parseStackTrace(error.stack);
81
+ return newError;
82
+ }
83
+
84
+ static withObject(error?: Object): AppMetricaError {
85
+ return new AppMetricaError(undefined, JSON.stringify(error));
86
+ }
87
+ }
package/src/index.ts CHANGED
@@ -4,6 +4,12 @@ import type { AdRevenue, Revenue } from './revenue';
4
4
  import type { UserProfile } from './userProfile';
5
5
  import type { ExternalAttribution } from './externalAttribution';
6
6
  import { normalizeAdRevenue } from './utils';
7
+ import { AppMetricaError } from './error';
8
+ import { Reporter, type IReporter, type ReporterConfig } from './reporter';
9
+ import type {
10
+ DeferredDeeplinkListener,
11
+ DeferredDeeplinkParametersListener,
12
+ } from './deferredDeeplink';
7
13
 
8
14
  const LINKING_ERROR =
9
15
  `The package '@appmetrica/react-native-analytics' doesn't seem to be linked. Make sure: \n\n` +
@@ -57,6 +63,9 @@ export type AppMetricaConfig = {
57
63
  userProfileID?: string;
58
64
 
59
65
  errorEnvironment?: Record<string, string | undefined>;
66
+ appEnvironment?: Record<string, string | undefined>;
67
+ maxReportsCount?: number;
68
+ dispatchPeriodSeconds?: number;
60
69
  };
61
70
 
62
71
  export type PreloadInfo = {
@@ -95,8 +104,13 @@ export * from './ecommerce';
95
104
  export * from './revenue';
96
105
  export * from './userProfile';
97
106
  export * from './externalAttribution';
107
+ export type { IReporter, ReporterConfig } from './reporter';
108
+ export * from './deferredDeeplink';
98
109
 
99
110
  export default class AppMetrica {
111
+
112
+ private static reporters: Map<string, Reporter> = new Map();
113
+
100
114
  static activate(config: AppMetricaConfig) {
101
115
  if (!activated) {
102
116
  AppMetricaNative.activate(config);
@@ -124,8 +138,24 @@ export default class AppMetrica {
124
138
  AppMetricaNative.reportAppOpen(deeplink);
125
139
  }
126
140
 
127
- static reportError(identifier: string, message: string, _reason?: Object) {
128
- AppMetricaNative.reportError(identifier, message);
141
+ static reportError(
142
+ identifier: string,
143
+ message?: string,
144
+ _reason?: Error | Object
145
+ ) {
146
+ AppMetricaNative.reportError(
147
+ identifier,
148
+ message,
149
+ _reason instanceof Error ? AppMetricaError.withError(_reason) : AppMetricaError.withObject(_reason)
150
+ );
151
+ }
152
+
153
+ static reportUnhandledException(error: Error) {
154
+ AppMetricaNative.reportUnhandledException(AppMetricaError.withError(error));
155
+ }
156
+
157
+ static reportErrorWithoutIdentifier(message: string | undefined, error: Error) {
158
+ AppMetricaNative.reportErrorWithoutIdentifier(message, AppMetricaError.withError(error));
129
159
  }
130
160
 
131
161
  static reportEvent(eventName: string, attributes?: Record<string, any>) {
@@ -186,4 +216,51 @@ export default class AppMetrica {
186
216
  static reportExternalAttribution(attribution: ExternalAttribution) {
187
217
  AppMetricaNative.reportExternalAttribution(attribution);
188
218
  }
219
+
220
+ static putAppEnvironmentValue(key: string, value?: string) {
221
+ AppMetricaNative.putAppEnvironmentValue(key, value);
222
+ }
223
+
224
+ static clearAppEnvironment() {
225
+ AppMetricaNative.clearAppEnvironment();
226
+ }
227
+
228
+ static getReporter(apiKey: string): IReporter {
229
+ if (AppMetrica.reporters.has(apiKey)) {
230
+ return AppMetrica.reporters.get(apiKey)!;
231
+ } else {
232
+ AppMetricaNative.touchReporter(apiKey);
233
+ const reporter = new Reporter(apiKey);
234
+ AppMetrica.reporters.set(apiKey, reporter);
235
+ return reporter;
236
+ }
237
+ }
238
+
239
+ static activateReporter(config: ReporterConfig) {
240
+ AppMetricaNative.activateReporter(config);
241
+ }
242
+
243
+ static getDeviceId(): Promise<string | null> {
244
+ return AppMetricaNative.getDeviceId();
245
+ }
246
+
247
+ static getUuid(): Promise<string | null> {
248
+ return AppMetricaNative.getUuid();
249
+ }
250
+
251
+ static requestDeferredDeeplink(listener: DeferredDeeplinkListener) {
252
+ AppMetricaNative.requestDeferredDeeplink(
253
+ listener.onFailure,
254
+ listener.onSuccess
255
+ );
256
+ }
257
+
258
+ static requestDeferredDeeplinkParameters(
259
+ listener: DeferredDeeplinkParametersListener
260
+ ) {
261
+ AppMetricaNative.requestDeferredDeeplinkParameters(
262
+ listener.onFailure,
263
+ listener.onSuccess
264
+ );
265
+ }
189
266
  }
@@ -0,0 +1,126 @@
1
+ import { NativeModules, Platform } from 'react-native';
2
+ import type { UserProfile } from './userProfile';
3
+ import type { AdRevenue, Revenue } from './revenue';
4
+ import type { ECommerceEvent } from './ecommerce';
5
+ import { AppMetricaError } from './error';
6
+
7
+ const LINKING_ERROR =
8
+ `The package '@appmetrica/react-native-analytics' doesn't seem to be linked. Make sure: \n\n` +
9
+ Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
10
+ '- You rebuilt the app after installing the package\n' +
11
+ '- You are not using Expo Go\n';
12
+
13
+ const ReporterNativeModule = NativeModules.AppMetricaReporter
14
+ ? NativeModules.AppMetricaReporter
15
+ : new Proxy(
16
+ {},
17
+ {
18
+ get() {
19
+ throw new Error(LINKING_ERROR);
20
+ },
21
+ }
22
+ );
23
+
24
+ export interface IReporter {
25
+ reportError(identifier: string, message?: string, _reason?: Error | Object): void;
26
+ reportErrorWithoutIdentifier(message: string | undefined, error: Error): void;
27
+ reportUnhandledException(error: Error): void;
28
+ reportEvent(eventName: string, attributes?: Record<string, any>): void;
29
+ pauseSession(): void;
30
+ resumeSession(): void;
31
+ sendEventsBuffer(): void;
32
+ clearAppEnvironment(): void;
33
+ putAppEnvironmentValue(key: string, value?: string): void;
34
+ setUserProfileID(userProfileID?: string): void;
35
+ setDataSendingEnabled(enabled: boolean): void;
36
+ reportUserProfile(userProfile: UserProfile): void;
37
+ reportAdRevenue(adRevenue: AdRevenue): void;
38
+ reportECommerce(event: ECommerceEvent): void;
39
+ reportRevenue(revenue: Revenue): void;
40
+ }
41
+
42
+ export class Reporter implements IReporter {
43
+
44
+ private apiKey: string;
45
+
46
+ constructor(apiKey: string) {
47
+ this.apiKey = apiKey;
48
+ }
49
+
50
+ reportError(identifier: string, message?: string, _reason?: Error | Object) {
51
+ ReporterNativeModule.reportError(
52
+ this.apiKey,
53
+ identifier,
54
+ message,
55
+ _reason instanceof Error ? AppMetricaError.withError(_reason) : AppMetricaError.withObject(_reason)
56
+ );
57
+ }
58
+
59
+ reportErrorWithoutIdentifier(message: string | undefined, error: Error) {
60
+ ReporterNativeModule.reportErrorWithoutIdentifier(this.apiKey, message, AppMetricaError.withError(error));
61
+ }
62
+
63
+ reportUnhandledException(error: Error) {
64
+ ReporterNativeModule.reportUnhandledException(this.apiKey, AppMetricaError.withError(error));
65
+ }
66
+
67
+ reportEvent(eventName: string, attributes?: Record<string, any>) {
68
+ ReporterNativeModule.reportEvent(this.apiKey, eventName, attributes);
69
+ }
70
+
71
+ pauseSession() {
72
+ ReporterNativeModule.pauseSession(this.apiKey);
73
+ }
74
+
75
+ resumeSession() {
76
+ ReporterNativeModule.resumeSession(this.apiKey);
77
+ }
78
+
79
+ sendEventsBuffer() {
80
+ ReporterNativeModule.sendEventsBuffer(this.apiKey);
81
+ }
82
+
83
+ clearAppEnvironment() {
84
+ ReporterNativeModule.clearAppEnvironment(this.apiKey);
85
+ }
86
+
87
+ putAppEnvironmentValue(key: string, value?: string) {
88
+ ReporterNativeModule.putAppEnvironmentValue(this.apiKey, key, value);
89
+ }
90
+
91
+ setUserProfileID(userProfileID: string) {
92
+ ReporterNativeModule.setUserProfileID(this.apiKey, userProfileID);
93
+ }
94
+
95
+ setDataSendingEnabled(enabled: boolean) {
96
+ ReporterNativeModule.setDataSendingEnabled(this.apiKey, enabled);
97
+ }
98
+
99
+ reportUserProfile(profile: UserProfile) {
100
+ ReporterNativeModule.reportUserProfile(this.apiKey, profile);
101
+ }
102
+
103
+ reportAdRevenue(adRevenue: AdRevenue) {
104
+ ReporterNativeModule.reportAdRevenue(this.apiKey, adRevenue);
105
+ }
106
+
107
+ reportECommerce(ecommerce: ECommerceEvent) {
108
+ ReporterNativeModule.reportECommerce(this.apiKey, ecommerce);
109
+ }
110
+
111
+ reportRevenue(revenue: Revenue) {
112
+ ReporterNativeModule.reportRevenue(this.apiKey, revenue)
113
+ }
114
+ }
115
+
116
+ export type ReporterConfig = {
117
+ apiKey: string;
118
+ logs?: boolean;
119
+ maxReportsInDatabaseCount?: number;
120
+ sessionTimeout?: number;
121
+ dataSendingEnabled?: boolean;
122
+ appEnvironment?: Record<string, string | undefined>;
123
+ dispatchPeriodSeconds?: number;
124
+ userProfileID?: string;
125
+ maxReportsCount?: number;
126
+ }
package/src/revenue.ts CHANGED
@@ -32,5 +32,6 @@ export enum AdType {
32
32
  MREC = 'mrec',
33
33
  INTERSTITIAL = 'interstitial',
34
34
  REWARDED = 'rewarded',
35
+ APP_OPEN = 'app_open',
35
36
  OTHER = 'other',
36
37
  }