@amplitude/analytics-react-native 0.2.2 → 0.3.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 (46) hide show
  1. package/android/src/main/java/com/amplitude/reactnative/AmplitudeReactNativeModule.kt +2 -1
  2. package/android/src/main/java/com/amplitude/reactnative/AndroidContextProvider.kt +5 -0
  3. package/lib/commonjs/config.js +12 -15
  4. package/lib/commonjs/config.js.map +1 -1
  5. package/lib/commonjs/index.js +45 -106
  6. package/lib/commonjs/index.js.map +1 -1
  7. package/lib/commonjs/plugins/context.js +4 -0
  8. package/lib/commonjs/plugins/context.js.map +1 -1
  9. package/lib/commonjs/react-native-client.js +40 -228
  10. package/lib/commonjs/react-native-client.js.map +1 -1
  11. package/lib/commonjs/utils/query-params.js +18 -6
  12. package/lib/commonjs/utils/query-params.js.map +1 -1
  13. package/lib/commonjs/version.js +1 -1
  14. package/lib/commonjs/version.js.map +1 -1
  15. package/lib/module/config.js +12 -15
  16. package/lib/module/config.js.map +1 -1
  17. package/lib/module/index.js +23 -1
  18. package/lib/module/index.js.map +1 -1
  19. package/lib/module/plugins/context.js +4 -0
  20. package/lib/module/plugins/context.js.map +1 -1
  21. package/lib/module/react-native-client.js +34 -210
  22. package/lib/module/react-native-client.js.map +1 -1
  23. package/lib/module/utils/query-params.js +14 -4
  24. package/lib/module/utils/query-params.js.map +1 -1
  25. package/lib/module/version.js +1 -1
  26. package/lib/module/version.js.map +1 -1
  27. package/lib/typescript/attribution/campaign-tracker.d.ts +3 -0
  28. package/lib/typescript/attribution/campaign-tracker.d.ts.map +1 -1
  29. package/lib/typescript/config.d.ts +4 -32
  30. package/lib/typescript/config.d.ts.map +1 -1
  31. package/lib/typescript/index.d.ts +2 -1
  32. package/lib/typescript/index.d.ts.map +1 -1
  33. package/lib/typescript/plugins/context.d.ts +1 -0
  34. package/lib/typescript/plugins/context.d.ts.map +1 -1
  35. package/lib/typescript/react-native-client.d.ts +4 -190
  36. package/lib/typescript/react-native-client.d.ts.map +1 -1
  37. package/lib/typescript/utils/query-params.d.ts +1 -0
  38. package/lib/typescript/utils/query-params.d.ts.map +1 -1
  39. package/lib/typescript/version.d.ts +1 -1
  40. package/package.json +4 -4
  41. package/src/config.ts +14 -17
  42. package/src/index.ts +5 -2
  43. package/src/plugins/context.ts +3 -0
  44. package/src/react-native-client.ts +35 -208
  45. package/src/utils/query-params.ts +13 -5
  46. package/src/version.ts +1 -1
@@ -1,5 +1,5 @@
1
1
  import { AmplitudeCore } from '@amplitude/analytics-core';
2
- import { ReactNativeConfig, ReactNativeOptions, AdditionalReactNativeOptions, AttributionReactNativeOptions } from '@amplitude/analytics-types';
2
+ import { ReactNativeConfig, ReactNativeOptions, AdditionalReactNativeOptions, AttributionReactNativeOptions, ReactNativeClient } from '@amplitude/analytics-types';
3
3
  export declare class AmplitudeReactNative extends AmplitudeCore<ReactNativeConfig> {
4
4
  init(apiKey: string, userId?: string, options?: ReactNativeOptions & AdditionalReactNativeOptions): Promise<void>;
5
5
  runAttributionStrategy(attributionConfig?: AttributionReactNativeOptions, isNewSession?: boolean): Promise<void>;
@@ -11,193 +11,7 @@ export declare class AmplitudeReactNative extends AmplitudeCore<ReactNativeConfi
11
11
  getSessionId(): number | undefined;
12
12
  setSessionId(sessionId: number): void;
13
13
  }
14
- /**
15
- * Initializes the Amplitude SDK with your apiKey, userId and optional configurations.
16
- * This method must be called before any other operations.
17
- *
18
- * ```typescript
19
- * await init(API_KEY, USER_ID, options).promise;
20
- * ```
21
- */
22
- export declare const init: (apiKey: string, userId?: string | undefined, options?: (ReactNativeOptions & AdditionalReactNativeOptions) | undefined) => import("@amplitude/analytics-types").AmplitudeReturn<Promise<void>>;
23
- /**
24
- * Adds a new plugin.
25
- *
26
- * ```typescript
27
- * const plugin = {...};
28
- * amplitude.add(plugin);
29
- * ```
30
- */
31
- export declare const add: (plugin: import("@amplitude/analytics-types").Plugin) => import("@amplitude/analytics-types").AmplitudeReturn<Promise<void>>;
32
- /**
33
- * Removes a plugin.
34
- *
35
- * ```typescript
36
- * amplitude.remove('myPlugin');
37
- * ```
38
- */
39
- export declare const remove: (pluginName: string) => import("@amplitude/analytics-types").AmplitudeReturn<Promise<void>>;
40
- /**
41
- * Tracks user-defined event, with specified type, optional event properties and optional overwrites.
42
- *
43
- * ```typescript
44
- * // event tracking with event type only
45
- * track('Page Load');
46
- *
47
- * // event tracking with event type and additional event properties
48
- * track('Page Load', { loadTime: 1000 });
49
- *
50
- * // event tracking with event type, additional event properties, and overwritten event options
51
- * track('Page Load', { loadTime: 1000 }, { sessionId: -1 });
52
- *
53
- * // alternatively, this tracking method is awaitable
54
- * const result = await track('Page Load').promise;
55
- * console.log(result.event); // {...}
56
- * console.log(result.code); // 200
57
- * console.log(result.message); // "Event tracked successfully"
58
- * ```
59
- */
60
- export declare const track: (eventInput: string | import("@amplitude/analytics-types").BaseEvent, eventProperties?: Record<string, any> | undefined, eventOptions?: import("@amplitude/analytics-types").EventOptions | undefined) => import("@amplitude/analytics-types").AmplitudeReturn<Promise<import("@amplitude/analytics-types").Result>>;
61
- /**
62
- * Alias for track()
63
- */
64
- export declare const logEvent: (eventInput: string | import("@amplitude/analytics-types").BaseEvent, eventProperties?: Record<string, any> | undefined, eventOptions?: import("@amplitude/analytics-types").EventOptions | undefined) => import("@amplitude/analytics-types").AmplitudeReturn<Promise<import("@amplitude/analytics-types").Result>>;
65
- /**
66
- * Sends an identify event containing user property operations
67
- *
68
- * ```typescript
69
- * const id = new Identify();
70
- * id.set('colors', ['rose', 'gold']);
71
- * identify(id);
72
- *
73
- * // alternatively, this tracking method is awaitable
74
- * const result = await identify(id).promise;
75
- * console.log(result.event); // {...}
76
- * console.log(result.code); // 200
77
- * console.log(result.message); // "Event tracked successfully"
78
- * ```
79
- */
80
- export declare const identify: (identify: import("@amplitude/analytics-types").Identify, eventOptions?: import("@amplitude/analytics-types").EventOptions | undefined) => import("@amplitude/analytics-types").AmplitudeReturn<Promise<import("@amplitude/analytics-types").Result>>;
81
- /**
82
- * Sends a group identify event containing group property operations.
83
- *
84
- * ```typescript
85
- * const id = new Identify();
86
- * id.set('skills', ['js', 'ts']);
87
- * const groupType = 'org';
88
- * const groupName = 'engineering';
89
- * groupIdentify(groupType, groupName, id);
90
- *
91
- * // alternatively, this tracking method is awaitable
92
- * const result = await groupIdentify(groupType, groupName, id).promise;
93
- * console.log(result.event); // {...}
94
- * console.log(result.code); // 200
95
- * console.log(result.message); // "Event tracked successfully"
96
- * ```
97
- */
98
- export declare const groupIdentify: (groupType: string, groupName: string | string[], identify: import("@amplitude/analytics-types").Identify, eventOptions?: import("@amplitude/analytics-types").EventOptions | undefined) => import("@amplitude/analytics-types").AmplitudeReturn<Promise<import("@amplitude/analytics-types").Result>>;
99
- export declare const setGroup: (groupType: string, groupName: string | string[]) => import("@amplitude/analytics-types").AmplitudeReturn<Promise<import("@amplitude/analytics-types").Result>>;
100
- /**
101
- * Sends a revenue event containing revenue property operations.
102
- *
103
- * ```typescript
104
- * const rev = new Revenue();
105
- * rev.setRevenue(100);
106
- * revenue(rev);
107
- *
108
- * // alternatively, this tracking method is awaitable
109
- * const result = await revenue(rev).promise;
110
- * console.log(result.event); // {...}
111
- * console.log(result.code); // 200
112
- * console.log(result.message); // "Event tracked successfully"
113
- * ```
114
- */
115
- export declare const revenue: (revenue: import("@amplitude/analytics-types").Revenue, eventOptions?: import("@amplitude/analytics-types").EventOptions | undefined) => import("@amplitude/analytics-types").AmplitudeReturn<Promise<import("@amplitude/analytics-types").Result>>;
116
- /**
117
- * Returns current user ID.
118
- *
119
- * ```typescript
120
- * const userId = getUserId();
121
- * ```
122
- */
123
- export declare const getUserId: () => string | undefined;
124
- /**
125
- * Sets a new user ID.
126
- *
127
- * ```typescript
128
- * setUserId('userId');
129
- * ```
130
- */
131
- export declare const setUserId: (userId: string | undefined) => void;
132
- /**
133
- * Returns current device ID.
134
- *
135
- * ```typescript
136
- * const deviceId = getDeviceId();
137
- * ```
138
- */
139
- export declare const getDeviceId: () => string | undefined;
140
- /**
141
- * Sets a new device ID.
142
- * When setting a custom device ID, make sure the value is sufficiently unique.
143
- * A uuid is recommended.
144
- *
145
- * ```typescript
146
- * setDeviceId('deviceId');
147
- * ```
148
- */
149
- export declare const setDeviceId: (deviceId: string) => void;
150
- /**
151
- * reset is a shortcut to anonymize users after they log out, by:
152
- * - setting userId to `undefined`
153
- * - regenerating a new random deviceId
154
- *
155
- * With an `undefined` userId and a completely new deviceId, the current user would appear as a brand new user in dashboard.
156
- *
157
- * ```typescript
158
- * reset();
159
- * ```
160
- */
161
- export declare const reset: () => void;
162
- /**
163
- * Returns current session ID.
164
- *
165
- * ```typescript
166
- * const sessionId = getSessionId();
167
- * ```
168
- */
169
- export declare const getSessionId: () => number | undefined;
170
- /**
171
- * Sets a new session ID.
172
- * When settign a custom session ID, make sure the value is in milliseconds since epoch (Unix Timestamp).
173
- *
174
- * ```typescript
175
- * setSessionId(Date.now());
176
- * ```
177
- */
178
- export declare const setSessionId: (sessionId: number) => void;
179
- /**
180
- * Sets a new optOut config value. This toggles event tracking on/off.
181
- *
182
- *```typescript
183
- * // Stops tracking
184
- * setOptOut(true);
185
- *
186
- * // Starts/resumes tracking
187
- * setOptOut(false);
188
- * ```
189
- */
190
- export declare const setOptOut: (optOut: boolean) => void;
191
- /**
192
- * Flush and send all the events which haven't been sent.
193
- *
194
- *```typescript
195
- * // Send all the unsent events
196
- * flush();
197
- *
198
- * // alternatively, this tracking method is awaitable
199
- * await flush().promise;
200
- * ```
201
- */
202
- export declare const flush: () => import("@amplitude/analytics-types").AmplitudeReturn<Promise<void>>;
14
+ export declare const createInstance: () => ReactNativeClient;
15
+ declare const _default: ReactNativeClient;
16
+ export default _default;
203
17
  //# sourceMappingURL=react-native-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"react-native-client.d.ts","sourceRoot":"","sources":["../../src/react-native-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoC,MAAM,2BAA2B,CAAC;AAC5F,OAAO,EACL,iBAAiB,EAEjB,kBAAkB,EAClB,4BAA4B,EAC5B,6BAA6B,EAC9B,MAAM,4BAA4B,CAAC;AASpC,qBAAa,oBAAqB,SAAQ,aAAa,CAAC,iBAAiB,CAAC;IAClE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,4BAA4B;IAwDjG,sBAAsB,CAAC,iBAAiB,CAAC,EAAE,6BAA6B,EAAE,YAAY,UAAQ;IAkBpG,SAAS;IAIT,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAcpC,WAAW;IAIX,WAAW,CAAC,QAAQ,EAAE,MAAM;IAc5B,KAAK;IAKL,YAAY;IAIZ,YAAY,CAAC,SAAS,EAAE,MAAM;CAO/B;AAID;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,iMAA0C,CAAC;AAE5D;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,8HAAyC,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,6FAA4C,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,KAAK,sTAA2C,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,QAAQ,sTAA8C,CAAC;AAEpE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,uPAA8C,CAAC;AAEpE;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,wSAAmD,CAAC;AAC9E,eAAO,MAAM,QAAQ,iKAA8C,CAAC;AAEpE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,OAAO,qPAA6C,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,0BAAgC,CAAC;AAEvD;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,WAlLF,MAAM,GAAG,SAAS,SAkLgB,CAAC;AAEvD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,0BAAkC,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,aApLA,MAAM,SAoL4B,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,YAA4B,CAAC;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,0BAAmC,CAAC;AAE7D;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,cA7LC,MAAM,SA6L4B,CAAC;AAE7D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,2BAAgC,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,2EAA2C,CAAC"}
1
+ {"version":3,"file":"react-native-client.d.ts","sourceRoot":"","sources":["../../src/react-native-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoC,MAAM,2BAA2B,CAAC;AAC5F,OAAO,EACL,iBAAiB,EAEjB,kBAAkB,EAClB,4BAA4B,EAC5B,6BAA6B,EAC7B,iBAAiB,EAClB,MAAM,4BAA4B,CAAC;AASpC,qBAAa,oBAAqB,SAAQ,aAAa,CAAC,iBAAiB,CAAC;IAClE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,4BAA4B;IAgEjG,sBAAsB,CAAC,iBAAiB,CAAC,EAAE,6BAA6B,EAAE,YAAY,UAAQ;IAkBpG,SAAS;IAIT,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAcpC,WAAW;IAIX,WAAW,CAAC,QAAQ,EAAE,MAAM;IAc5B,KAAK;IAKL,YAAY;IAIZ,YAAY,CAAC,SAAS,EAAE,MAAM;CAO/B;AAED,eAAO,MAAM,cAAc,QAAO,iBAsBjC,CAAC;;AAEF,wBAAgC"}
@@ -1,2 +1,3 @@
1
1
  export declare const getQueryParams: () => Record<string, string | undefined>;
2
+ export declare const tryDecodeURIComponent: (value?: string) => string;
2
3
  //# sourceMappingURL=query-params.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-params.d.ts","sourceRoot":"","sources":["../../../src/utils/query-params.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,QAAO,OAAO,MAAM,EAAE,MAAM,GAAG,SAAS,CAelE,CAAC"}
1
+ {"version":3,"file":"query-params.d.ts","sourceRoot":"","sources":["../../../src/utils/query-params.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,QAAO,OAAO,MAAM,EAAE,MAAM,GAAG,SAAS,CAiBlE,CAAC;AAEF,eAAO,MAAM,qBAAqB,4BAMjC,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.2.2";
1
+ export declare const VERSION = "0.3.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amplitude/analytics-react-native",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Official React Native SDK",
5
5
  "keywords": [
6
6
  "analytics",
@@ -58,8 +58,8 @@
58
58
  },
59
59
  "dependencies": {
60
60
  "@amplitude/analytics-connector": "1.4.5",
61
- "@amplitude/analytics-core": "^0.6.5",
62
- "@amplitude/analytics-types": "^0.6.1",
61
+ "@amplitude/analytics-core": "^0.8.0",
62
+ "@amplitude/analytics-types": "^0.8.0",
63
63
  "@amplitude/ua-parser-js": "^0.7.31",
64
64
  "@react-native-async-storage/async-storage": "^1.17.7",
65
65
  "tslib": "^2.3.1"
@@ -89,5 +89,5 @@
89
89
  ]
90
90
  ]
91
91
  },
92
- "gitHead": "196d18de7dd7a3e855073cc01880498e6190b739"
92
+ "gitHead": "c701a2b7ada6c8817bf28894f4d68cfa5dd0c403"
93
93
  }
package/src/config.ts CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  ReactNativeOptions,
4
4
  ReactNativeConfig as IReactNativeConfig,
5
5
  Storage,
6
- TrackingOptions,
6
+ ReactNativeTrackingOptions,
7
7
  UserSession,
8
8
  SessionManager as ISessionManager,
9
9
  } from '@amplitude/analytics-types';
@@ -18,6 +18,17 @@ import { SessionManager } from './session-manager';
18
18
 
19
19
  export const getDefaultConfig = () => {
20
20
  const cookieStorage = new MemoryStorage<UserSession>();
21
+ const trackingOptions: Required<ReactNativeTrackingOptions> = {
22
+ adid: true,
23
+ carrier: true,
24
+ deviceManufacturer: true,
25
+ deviceModel: true,
26
+ ipAddress: true,
27
+ language: true,
28
+ osName: true,
29
+ osVersion: true,
30
+ platform: true,
31
+ };
21
32
  return {
22
33
  cookieExpiration: 365,
23
34
  cookieSameSite: 'Lax',
@@ -28,21 +39,7 @@ export const getDefaultConfig = () => {
28
39
  sessionManager: new SessionManager(cookieStorage, ''),
29
40
  sessionTimeout: 30 * 60 * 1000,
30
41
  storageProvider: new MemoryStorage<Event[]>(),
31
- trackingOptions: {
32
- city: true,
33
- country: true,
34
- carrier: true,
35
- deviceManufacturer: true,
36
- deviceModel: true,
37
- dma: true,
38
- ipAddress: true,
39
- language: true,
40
- osName: true,
41
- osVersion: true,
42
- platform: true,
43
- region: true,
44
- versionName: true,
45
- },
42
+ trackingOptions,
46
43
  transportProvider: new FetchTransport(),
47
44
  };
48
45
  };
@@ -57,7 +54,7 @@ export class ReactNativeConfig extends Config implements IReactNativeConfig {
57
54
  domain: string;
58
55
  partnerId?: string;
59
56
  sessionTimeout: number;
60
- trackingOptions: TrackingOptions;
57
+ trackingOptions: ReactNativeTrackingOptions;
61
58
  sessionManager: ISessionManager;
62
59
 
63
60
  constructor(apiKey: string, userId?: string, options?: ReactNativeOptions) {
package/src/index.ts CHANGED
@@ -1,4 +1,7 @@
1
- export {
1
+ /* eslint-disable @typescript-eslint/unbound-method */
2
+ import client from './react-native-client';
3
+ export { createInstance } from './react-native-client';
4
+ export const {
2
5
  add,
3
6
  flush,
4
7
  getDeviceId,
@@ -17,7 +20,7 @@ export {
17
20
  setSessionId,
18
21
  setUserId,
19
22
  track,
20
- } from './react-native-client';
23
+ } = client;
21
24
  export { Revenue, Identify } from '@amplitude/analytics-core';
22
25
  // Hack - react-native apps have trouble with:
23
26
  // export * as Types from '@amplitude/analytics-types
@@ -18,6 +18,7 @@ type NativeContext = {
18
18
  deviceManufacturer: string;
19
19
  deviceModel: string;
20
20
  carrier: string;
21
+ adid: string;
21
22
  };
22
23
 
23
24
  export interface AmplitudeReactNative {
@@ -73,6 +74,7 @@ export class Context implements BeforePlugin {
73
74
  const deviceModel = nativeContext?.deviceModel || this.uaResult.device.model || this.uaResult.os.name;
74
75
  const language = nativeContext?.language || getLanguage();
75
76
  const carrier = nativeContext?.carrier;
77
+ const adid = nativeContext?.adid;
76
78
 
77
79
  const event: Event = {
78
80
  user_id: this.config.userId,
@@ -88,6 +90,7 @@ export class Context implements BeforePlugin {
88
90
  ...(this.config.trackingOptions.language && { language: language }),
89
91
  ...(this.config.trackingOptions.carrier && { carrier: carrier }),
90
92
  ...(this.config.trackingOptions.ipAddress && { ip: IP_ADDRESS }),
93
+ ...(this.config.trackingOptions.adid && { adid: adid }),
91
94
  insert_id: UUID(),
92
95
  partner_id: this.config.partnerId,
93
96
  plan: this.config.plan,
@@ -1,10 +1,11 @@
1
- import { AmplitudeCore, Destination, returnWrapper, UUID } from '@amplitude/analytics-core';
1
+ import { AmplitudeCore, Destination, UUID, returnWrapper } from '@amplitude/analytics-core';
2
2
  import {
3
3
  ReactNativeConfig,
4
4
  Campaign,
5
5
  ReactNativeOptions,
6
6
  AdditionalReactNativeOptions,
7
7
  AttributionReactNativeOptions,
8
+ ReactNativeClient,
8
9
  } from '@amplitude/analytics-types';
9
10
  import { Context } from './plugins/context';
10
11
  import { useReactNativeConfig, createFlexibleStorage } from './config';
@@ -16,6 +17,12 @@ import { getAnalyticsConnector } from './utils/analytics-connector';
16
17
 
17
18
  export class AmplitudeReactNative extends AmplitudeCore<ReactNativeConfig> {
18
19
  async init(apiKey: string, userId?: string, options?: ReactNativeOptions & AdditionalReactNativeOptions) {
20
+ // Step 0: Block concurrent initialization
21
+ if (this.initializing) {
22
+ return;
23
+ }
24
+ this.initializing = true;
25
+
19
26
  // Step 1: Read cookies stored by old SDK
20
27
  const oldCookies = await parseOldCookies(apiKey, options);
21
28
 
@@ -60,6 +67,8 @@ export class AmplitudeReactNative extends AmplitudeCore<ReactNativeConfig> {
60
67
  await this.add(new IdentityEventSender());
61
68
  await this.add(new Destination());
62
69
 
70
+ this.initializing = false;
71
+
63
72
  // Step 5: Set timeline ready for processing events
64
73
  // Send existing events, which might be collected by track before init
65
74
  this.timeline.isReady = true;
@@ -143,210 +152,28 @@ export class AmplitudeReactNative extends AmplitudeCore<ReactNativeConfig> {
143
152
  }
144
153
  }
145
154
 
146
- const client = new AmplitudeReactNative();
147
-
148
- /**
149
- * Initializes the Amplitude SDK with your apiKey, userId and optional configurations.
150
- * This method must be called before any other operations.
151
- *
152
- * ```typescript
153
- * await init(API_KEY, USER_ID, options).promise;
154
- * ```
155
- */
156
- export const init = returnWrapper(client.init.bind(client));
157
-
158
- /**
159
- * Adds a new plugin.
160
- *
161
- * ```typescript
162
- * const plugin = {...};
163
- * amplitude.add(plugin);
164
- * ```
165
- */
166
- export const add = returnWrapper(client.add.bind(client));
167
-
168
- /**
169
- * Removes a plugin.
170
- *
171
- * ```typescript
172
- * amplitude.remove('myPlugin');
173
- * ```
174
- */
175
- export const remove = returnWrapper(client.remove.bind(client));
176
-
177
- /**
178
- * Tracks user-defined event, with specified type, optional event properties and optional overwrites.
179
- *
180
- * ```typescript
181
- * // event tracking with event type only
182
- * track('Page Load');
183
- *
184
- * // event tracking with event type and additional event properties
185
- * track('Page Load', { loadTime: 1000 });
186
- *
187
- * // event tracking with event type, additional event properties, and overwritten event options
188
- * track('Page Load', { loadTime: 1000 }, { sessionId: -1 });
189
- *
190
- * // alternatively, this tracking method is awaitable
191
- * const result = await track('Page Load').promise;
192
- * console.log(result.event); // {...}
193
- * console.log(result.code); // 200
194
- * console.log(result.message); // "Event tracked successfully"
195
- * ```
196
- */
197
- export const track = returnWrapper(client.track.bind(client));
198
-
199
- /**
200
- * Alias for track()
201
- */
202
- export const logEvent = returnWrapper(client.logEvent.bind(client));
203
-
204
- /**
205
- * Sends an identify event containing user property operations
206
- *
207
- * ```typescript
208
- * const id = new Identify();
209
- * id.set('colors', ['rose', 'gold']);
210
- * identify(id);
211
- *
212
- * // alternatively, this tracking method is awaitable
213
- * const result = await identify(id).promise;
214
- * console.log(result.event); // {...}
215
- * console.log(result.code); // 200
216
- * console.log(result.message); // "Event tracked successfully"
217
- * ```
218
- */
219
- export const identify = returnWrapper(client.identify.bind(client));
220
-
221
- /**
222
- * Sends a group identify event containing group property operations.
223
- *
224
- * ```typescript
225
- * const id = new Identify();
226
- * id.set('skills', ['js', 'ts']);
227
- * const groupType = 'org';
228
- * const groupName = 'engineering';
229
- * groupIdentify(groupType, groupName, id);
230
- *
231
- * // alternatively, this tracking method is awaitable
232
- * const result = await groupIdentify(groupType, groupName, id).promise;
233
- * console.log(result.event); // {...}
234
- * console.log(result.code); // 200
235
- * console.log(result.message); // "Event tracked successfully"
236
- * ```
237
- */
238
- export const groupIdentify = returnWrapper(client.groupIdentify.bind(client));
239
- export const setGroup = returnWrapper(client.setGroup.bind(client));
240
-
241
- /**
242
- * Sends a revenue event containing revenue property operations.
243
- *
244
- * ```typescript
245
- * const rev = new Revenue();
246
- * rev.setRevenue(100);
247
- * revenue(rev);
248
- *
249
- * // alternatively, this tracking method is awaitable
250
- * const result = await revenue(rev).promise;
251
- * console.log(result.event); // {...}
252
- * console.log(result.code); // 200
253
- * console.log(result.message); // "Event tracked successfully"
254
- * ```
255
- */
256
- export const revenue = returnWrapper(client.revenue.bind(client));
257
-
258
- /**
259
- * Returns current user ID.
260
- *
261
- * ```typescript
262
- * const userId = getUserId();
263
- * ```
264
- */
265
- export const getUserId = client.getUserId.bind(client);
266
-
267
- /**
268
- * Sets a new user ID.
269
- *
270
- * ```typescript
271
- * setUserId('userId');
272
- * ```
273
- */
274
- export const setUserId = client.setUserId.bind(client);
275
-
276
- /**
277
- * Returns current device ID.
278
- *
279
- * ```typescript
280
- * const deviceId = getDeviceId();
281
- * ```
282
- */
283
- export const getDeviceId = client.getDeviceId.bind(client);
284
-
285
- /**
286
- * Sets a new device ID.
287
- * When setting a custom device ID, make sure the value is sufficiently unique.
288
- * A uuid is recommended.
289
- *
290
- * ```typescript
291
- * setDeviceId('deviceId');
292
- * ```
293
- */
294
- export const setDeviceId = client.setDeviceId.bind(client);
295
-
296
- /**
297
- * reset is a shortcut to anonymize users after they log out, by:
298
- * - setting userId to `undefined`
299
- * - regenerating a new random deviceId
300
- *
301
- * With an `undefined` userId and a completely new deviceId, the current user would appear as a brand new user in dashboard.
302
- *
303
- * ```typescript
304
- * reset();
305
- * ```
306
- */
307
- export const reset = client.reset.bind(client);
308
-
309
- /**
310
- * Returns current session ID.
311
- *
312
- * ```typescript
313
- * const sessionId = getSessionId();
314
- * ```
315
- */
316
- export const getSessionId = client.getSessionId.bind(client);
317
-
318
- /**
319
- * Sets a new session ID.
320
- * When settign a custom session ID, make sure the value is in milliseconds since epoch (Unix Timestamp).
321
- *
322
- * ```typescript
323
- * setSessionId(Date.now());
324
- * ```
325
- */
326
- export const setSessionId = client.setSessionId.bind(client);
327
-
328
- /**
329
- * Sets a new optOut config value. This toggles event tracking on/off.
330
- *
331
- *```typescript
332
- * // Stops tracking
333
- * setOptOut(true);
334
- *
335
- * // Starts/resumes tracking
336
- * setOptOut(false);
337
- * ```
338
- */
339
- export const setOptOut = client.setOptOut.bind(client);
340
-
341
- /**
342
- * Flush and send all the events which haven't been sent.
343
- *
344
- *```typescript
345
- * // Send all the unsent events
346
- * flush();
347
- *
348
- * // alternatively, this tracking method is awaitable
349
- * await flush().promise;
350
- * ```
351
- */
352
- export const flush = returnWrapper(client.flush.bind(client));
155
+ export const createInstance = (): ReactNativeClient => {
156
+ const client = new AmplitudeReactNative();
157
+ return {
158
+ init: returnWrapper(client.init.bind(client)),
159
+ add: returnWrapper(client.add.bind(client)),
160
+ remove: returnWrapper(client.remove.bind(client)),
161
+ track: returnWrapper(client.track.bind(client)),
162
+ logEvent: returnWrapper(client.logEvent.bind(client)),
163
+ identify: returnWrapper(client.identify.bind(client)),
164
+ groupIdentify: returnWrapper(client.groupIdentify.bind(client)),
165
+ setGroup: returnWrapper(client.setGroup.bind(client)),
166
+ revenue: returnWrapper(client.revenue.bind(client)),
167
+ flush: returnWrapper(client.flush.bind(client)),
168
+ getUserId: client.getUserId.bind(client),
169
+ setUserId: client.setUserId.bind(client),
170
+ getDeviceId: client.getDeviceId.bind(client),
171
+ setDeviceId: client.setDeviceId.bind(client),
172
+ reset: client.reset.bind(client),
173
+ getSessionId: client.getSessionId.bind(client),
174
+ setSessionId: client.setSessionId.bind(client),
175
+ setOptOut: client.setOptOut.bind(client),
176
+ };
177
+ };
178
+
179
+ export default createInstance();
@@ -1,18 +1,26 @@
1
- import { isNative } from './platform';
2
-
3
1
  export const getQueryParams = (): Record<string, string | undefined> => {
4
2
  /* istanbul ignore if */
5
- if (isNative() || typeof window === 'undefined') {
3
+ if (typeof window === 'undefined') {
6
4
  return {};
7
5
  }
8
6
  const pairs = window.location.search.substring(1).split('&').filter(Boolean);
9
7
  const params = pairs.reduce<Record<string, string | undefined>>((acc, curr) => {
10
- const [key, value = ''] = curr.split('=', 2);
8
+ const query = curr.split('=', 2);
9
+ const key = tryDecodeURIComponent(query[0]);
10
+ const value = tryDecodeURIComponent(query[1]);
11
11
  if (!value) {
12
12
  return acc;
13
13
  }
14
- acc[decodeURIComponent(key)] = decodeURIComponent(value);
14
+ acc[key] = value;
15
15
  return acc;
16
16
  }, {});
17
17
  return params;
18
18
  };
19
+
20
+ export const tryDecodeURIComponent = (value = '') => {
21
+ try {
22
+ return decodeURIComponent(value);
23
+ } catch {
24
+ return '';
25
+ }
26
+ };
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.2.2';
1
+ export const VERSION = '0.3.0';