react-native-test-adx 0.1.2 → 0.1.3
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/README.md +11 -33
- package/lib/module/config/ApiConstants.js +1 -1
- package/lib/module/config/StorageKeys.js +1 -1
- package/lib/module/core/AdaxonClient.js +1 -3
- package/lib/module/platform/reactNative.js +60 -67
- package/lib/module/services/device/DeviceInfoService.js +59 -10
- package/lib/module/services/event/EventBuilder.js +1 -2
- package/lib/typescript/src/config/ApiConstants.d.ts +1 -1
- package/lib/typescript/src/platform/types.d.ts +1 -0
- package/lib/typescript/src/services/device/DeviceInfoService.d.ts +11 -1
- package/lib/typescript/src/services/event/EventBuilder.d.ts +0 -2
- package/package.json +1 -1
- package/lib/module/storage/AnonymousIdService.js +0 -31
- package/lib/typescript/src/storage/AnonymousIdService.d.ts +0 -11
package/README.md
CHANGED
|
@@ -36,8 +36,6 @@ import { AdaxonProvider, useAdaxon } from 'react-native-test-adx';
|
|
|
36
36
|
|
|
37
37
|
Both packages expose the same API. Only the npm name differs.
|
|
38
38
|
|
|
39
|
-
`expo-secure-store` is **not** required. The SDK does not depend on it.
|
|
40
|
-
|
|
41
39
|
## Quick start (React Native)
|
|
42
40
|
|
|
43
41
|
Wrap the app in `AdaxonProvider`. Screens use `useAdaxon()`.
|
|
@@ -52,7 +50,7 @@ The SDK owns the tracker host and API paths (`/event/tracking`, `/api/mts/recomm
|
|
|
52
50
|
|---|---|---|
|
|
53
51
|
| `appId` | **Yes** | None. MTS app id (`adx_…`). |
|
|
54
52
|
| `sdkKey` | **Yes** | None. Sent as the `x-sdk-key` header. |
|
|
55
|
-
| `storage` | No | In-memory
|
|
53
|
+
| `storage` | No | In-memory event queue and anonymous id. Offline events and the generated id are lost on app restart. |
|
|
56
54
|
| `timeoutMs` | No | `10000` |
|
|
57
55
|
| `testMode` | No | `false` (`sdk_version` gets a `-test` suffix when true) |
|
|
58
56
|
| `externalUserId` | No | Unset |
|
|
@@ -146,40 +144,20 @@ function HomeScreen() {
|
|
|
146
144
|
|
|
147
145
|
Do **not** pass device or app fields. The SDK attaches `device` and `app` automatically on every event.
|
|
148
146
|
|
|
147
|
+
### Anonymous id
|
|
148
|
+
|
|
149
|
+
`user.anonymous_id` is generated by the SDK. It reads a unique id from React Native `NativeModules` when the host exposes one, otherwise it generates a UUID. The value is cached for the process and written to the configured `storage` adapter so the same id is reused across app launches. No third-party device-info package is required.
|
|
150
|
+
|
|
149
151
|
### Storage
|
|
150
152
|
|
|
151
|
-
`storage` is optional.
|
|
153
|
+
`storage` is optional. It persists the **event queue** (offline / pending events) and the **anonymous id**. Only `appId` and `sdkKey` are required.
|
|
152
154
|
|
|
153
155
|
| What you pass | What happens |
|
|
154
156
|
|---|---|
|
|
155
|
-
| No `storage` |
|
|
156
|
-
| A storage adapter |
|
|
157
|
-
|
|
158
|
-
The adapter is only `getItem` / `setItem` / `removeItem`. You do not implement the queue. Any store works: Expo SecureStore, AsyncStorage, MMKV, or your own.
|
|
159
|
-
|
|
160
|
-
Optional SecureStore helper (not required):
|
|
161
|
-
|
|
162
|
-
```sh
|
|
163
|
-
npx expo install expo-secure-store
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
```tsx
|
|
167
|
-
import * as SecureStore from 'expo-secure-store';
|
|
168
|
-
|
|
169
|
-
<AdaxonProvider
|
|
170
|
-
configuration={{
|
|
171
|
-
appId: 'adx_your_app_id',
|
|
172
|
-
sdkKey: 'your_sdk_key',
|
|
173
|
-
storage: {
|
|
174
|
-
getItem: (key) => SecureStore.getItemAsync(key),
|
|
175
|
-
setItem: (key, value) => SecureStore.setItemAsync(key, value),
|
|
176
|
-
removeItem: (key) => SecureStore.deleteItemAsync(key),
|
|
177
|
-
},
|
|
178
|
-
}}
|
|
179
|
-
>
|
|
180
|
-
```
|
|
157
|
+
| No `storage` | The queue and anonymous id stay in memory. Tracking still works. Both are lost if the app closes. |
|
|
158
|
+
| A storage adapter | Queued events and the anonymous id survive restart. |
|
|
181
159
|
|
|
182
|
-
|
|
160
|
+
The adapter is only `getItem` / `setItem` / `removeItem`. You do not implement the queue.
|
|
183
161
|
|
|
184
162
|
### Non-component boot
|
|
185
163
|
|
|
@@ -289,7 +267,7 @@ Values come from React Native `Platform` (`src/platform/reactNative.ts`). They a
|
|
|
289
267
|
"app": {
|
|
290
268
|
"package_name": "com.example.app",
|
|
291
269
|
"app_version": "2.4.1",
|
|
292
|
-
"sdk_version": "0.1.
|
|
270
|
+
"sdk_version": "0.1.3"
|
|
293
271
|
}
|
|
294
272
|
}
|
|
295
273
|
```
|
|
@@ -325,7 +303,7 @@ MTS tracker
|
|
|
325
303
|
| `src/platform/` | Android/iOS fields. **Only `react-native` import** |
|
|
326
304
|
| `src/config/` | Tracker host, API paths, timeouts, storage key rules |
|
|
327
305
|
| `src/validation/` | Event name, property, and batch-size rules |
|
|
328
|
-
| `src/storage/` |
|
|
306
|
+
| `src/storage/` | Persistent event queue |
|
|
329
307
|
| `example/src/` | Demo app: `App.tsx`, `screens/`, `components/` |
|
|
330
308
|
|
|
331
309
|
Screens belong in the **host app**, not in the SDK.
|
|
@@ -4,7 +4,7 @@ export const ANONYMOUS_ID_KEY_PREFIX = 'adaxon_sdk.anonymous_id.';
|
|
|
4
4
|
export const EVENT_QUEUE_META_KEY_PREFIX = 'adaxon_sdk.event_queue.meta.';
|
|
5
5
|
export const EVENT_QUEUE_ITEM_KEY_PREFIX = 'adaxon_sdk.event_queue.item.';
|
|
6
6
|
|
|
7
|
-
//
|
|
7
|
+
// Queue adapters (and Keychain-backed stores) only accept alphanumerics
|
|
8
8
|
// plus `.`, `-` and `_`, so app ids are sanitized before use as a key.
|
|
9
9
|
const UNSAFE_STORAGE_KEY_CHARS = /[^A-Za-z0-9._-]/g;
|
|
10
10
|
export function sanitizeStorageId(appId) {
|
|
@@ -11,7 +11,6 @@ import { EventService } from "../services/event/EventService.js";
|
|
|
11
11
|
import { ApiClient } from "../services/network/ApiClient.js";
|
|
12
12
|
import { NetworkInfoService } from "../services/network/NetworkInfoService.js";
|
|
13
13
|
import { NetworkService } from "../services/network/NetworkService.js";
|
|
14
|
-
import { AnonymousIdService } from "../storage/AnonymousIdService.js";
|
|
15
14
|
import { EventQueueStorage } from "../storage/EventQueueStorage.js";
|
|
16
15
|
import { EventValidator } from "../validation/EventValidator.js";
|
|
17
16
|
export class AdaxonClient {
|
|
@@ -27,10 +26,9 @@ export class AdaxonClient {
|
|
|
27
26
|
const networkInfo = new NetworkInfoService(config.networkInfoReader);
|
|
28
27
|
this.builder = new EventBuilder({
|
|
29
28
|
appId: auth.appId,
|
|
30
|
-
deviceInfo: new DeviceInfoService(config.platform ?? 'web', config.deviceInfoReader),
|
|
29
|
+
deviceInfo: new DeviceInfoService(config.platform ?? 'web', config.deviceInfoReader, config.storage, auth.appId),
|
|
31
30
|
appInfo: new AppInfoService(Boolean(config.testMode), config.appInfoReader),
|
|
32
31
|
networkInfo,
|
|
33
|
-
anonymousId: new AnonymousIdService(auth.appId, config.storage),
|
|
34
32
|
validator: this.validator,
|
|
35
33
|
externalUserId: config.externalUserId
|
|
36
34
|
});
|
|
@@ -7,6 +7,28 @@ import { appFieldsFromNative } from "./app.js";
|
|
|
7
7
|
import { deviceFieldsFromAndroid } from "./android.js";
|
|
8
8
|
import { deviceFieldsFromIos } from "./ios.js";
|
|
9
9
|
import { connectionTypeFromNativeState, ipAddressFromNativeState, isOnlineFromNativeState, usableIpAddress } from "./network.js";
|
|
10
|
+
function nativeModule(name) {
|
|
11
|
+
return (NativeModules ?? {})[name];
|
|
12
|
+
}
|
|
13
|
+
async function callNative(method, arg) {
|
|
14
|
+
if (typeof method !== 'function') {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
return await method(arg);
|
|
19
|
+
} catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function safeUnsubscribe(remove) {
|
|
24
|
+
return () => {
|
|
25
|
+
try {
|
|
26
|
+
remove?.();
|
|
27
|
+
} catch {
|
|
28
|
+
// Native unsubscribe can throw after the module is torn down.
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
10
32
|
export function detectReactNativePlatform() {
|
|
11
33
|
return Platform.OS === 'ios' || Platform.OS === 'android' ? Platform.OS : 'web';
|
|
12
34
|
}
|
|
@@ -27,45 +49,21 @@ function collectFromReactNative(platform) {
|
|
|
27
49
|
Object.assign(device, readLocaleFields());
|
|
28
50
|
return device;
|
|
29
51
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
readAppInfo: () => appFieldsFromNative(readNativeAppConstants())
|
|
35
|
-
};
|
|
36
|
-
export const reactNativeNetworkInfoReader = {
|
|
37
|
-
readNetworkInfo: collectFromNativeNetwork
|
|
38
|
-
};
|
|
39
|
-
export const reactNativeNetworkStatusReader = {
|
|
40
|
-
getIsOnline: readIsOnlineFromNative,
|
|
41
|
-
subscribe: subscribeNativeNetworkStatus
|
|
42
|
-
};
|
|
43
|
-
export const reactNativeUrlOpener = Linking;
|
|
52
|
+
async function readUniqueIdFromNative() {
|
|
53
|
+
const deviceInfo = nativeModule('RNDeviceInfo');
|
|
54
|
+
return nonEmptyString(await callNative(deviceInfo?.getUniqueId)) ?? '';
|
|
55
|
+
}
|
|
44
56
|
function readNativeAppConstants() {
|
|
45
|
-
const modules = NativeModules ?? {};
|
|
46
|
-
const expoApp = modules.ExpoApplication;
|
|
47
|
-
const expoConstants = modules.ExponentConstants;
|
|
48
|
-
const deviceInfo = modules.RNDeviceInfo;
|
|
49
57
|
return {
|
|
50
|
-
...
|
|
51
|
-
...
|
|
52
|
-
...
|
|
58
|
+
...nativeModule('RNDeviceInfo'),
|
|
59
|
+
...nativeModule('ExponentConstants'),
|
|
60
|
+
...nativeModule('ExpoApplication')
|
|
53
61
|
};
|
|
54
62
|
}
|
|
55
63
|
function nativeNetworkModules() {
|
|
56
|
-
const modules = NativeModules ?? {};
|
|
57
64
|
return {
|
|
58
|
-
netInfo:
|
|
59
|
-
expoNetwork:
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
function safeUnsubscribe(remove) {
|
|
63
|
-
return () => {
|
|
64
|
-
try {
|
|
65
|
-
remove?.();
|
|
66
|
-
} catch {
|
|
67
|
-
// Native unsubscribe can throw after the module is torn down.
|
|
68
|
-
}
|
|
65
|
+
netInfo: nativeModule('RNCNetInfo'),
|
|
66
|
+
expoNetwork: nativeModule('ExpoNetwork')
|
|
69
67
|
};
|
|
70
68
|
}
|
|
71
69
|
async function readIsOnlineFromNative() {
|
|
@@ -73,18 +71,11 @@ async function readIsOnlineFromNative() {
|
|
|
73
71
|
netInfo,
|
|
74
72
|
expoNetwork
|
|
75
73
|
} = nativeNetworkModules();
|
|
76
|
-
const
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
if (online !== null) {
|
|
80
|
-
return online;
|
|
81
|
-
}
|
|
74
|
+
const fromNetInfo = isOnlineFromNativeState(await callNative(netInfo?.getCurrentState, null));
|
|
75
|
+
if (fromNetInfo !== null) {
|
|
76
|
+
return fromNetInfo;
|
|
82
77
|
}
|
|
83
|
-
|
|
84
|
-
if (typeof getNetworkState === 'function') {
|
|
85
|
-
return isOnlineFromNativeState(await readOptionalNative(getNetworkState));
|
|
86
|
-
}
|
|
87
|
-
return null;
|
|
78
|
+
return isOnlineFromNativeState(await callNative(expoNetwork?.getNetworkStateAsync));
|
|
88
79
|
}
|
|
89
80
|
function subscribeNativeNetworkStatus(listener) {
|
|
90
81
|
const {
|
|
@@ -99,9 +90,8 @@ function subscribeNativeNetworkStatus(listener) {
|
|
|
99
90
|
const subscription = new NativeEventEmitter(NativeModules.RNCNetInfo).addListener('netInfo.networkStatusDidChange', onState);
|
|
100
91
|
return safeUnsubscribe(() => subscription.remove());
|
|
101
92
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const subscription = addListener.call(expoNetwork, 'onNetworkStateChanged', onState);
|
|
93
|
+
if (expoNetwork && typeof expoNetwork.addListener === 'function') {
|
|
94
|
+
const subscription = expoNetwork.addListener('onNetworkStateChanged', onState);
|
|
105
95
|
return safeUnsubscribe(() => subscription?.remove?.());
|
|
106
96
|
}
|
|
107
97
|
} catch (error) {
|
|
@@ -109,32 +99,35 @@ function subscribeNativeNetworkStatus(listener) {
|
|
|
109
99
|
}
|
|
110
100
|
return () => undefined;
|
|
111
101
|
}
|
|
112
|
-
async function readOptionalNative(read) {
|
|
113
|
-
try {
|
|
114
|
-
return await read();
|
|
115
|
-
} catch {
|
|
116
|
-
return undefined;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
102
|
async function collectFromNativeNetwork() {
|
|
120
103
|
const network = {};
|
|
121
104
|
const {
|
|
122
105
|
netInfo,
|
|
123
106
|
expoNetwork
|
|
124
107
|
} = nativeNetworkModules();
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
setIfPresent(network, '
|
|
130
|
-
}
|
|
131
|
-
const getNetworkState = expoNetwork?.getNetworkStateAsync;
|
|
132
|
-
if (!network.connection_type && typeof getNetworkState === 'function') {
|
|
133
|
-
setIfPresent(network, 'connection_type', connectionTypeFromNativeState(await readOptionalNative(getNetworkState)));
|
|
108
|
+
const state = await callNative(netInfo?.getCurrentState, null);
|
|
109
|
+
setIfPresent(network, 'connection_type', connectionTypeFromNativeState(state));
|
|
110
|
+
setIfPresent(network, 'ip_address', ipAddressFromNativeState(state));
|
|
111
|
+
if (!network.connection_type) {
|
|
112
|
+
setIfPresent(network, 'connection_type', connectionTypeFromNativeState(await callNative(expoNetwork?.getNetworkStateAsync)));
|
|
134
113
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
setIfPresent(network, 'ip_address', usableIpAddress(nonEmptyString(await readOptionalNative(getIpAddress))));
|
|
114
|
+
if (!network.ip_address) {
|
|
115
|
+
setIfPresent(network, 'ip_address', usableIpAddress(nonEmptyString(await callNative(expoNetwork?.getIpAddressAsync))));
|
|
138
116
|
}
|
|
139
117
|
return network;
|
|
140
|
-
}
|
|
118
|
+
}
|
|
119
|
+
export const reactNativeDeviceReader = {
|
|
120
|
+
readDeviceInfo: collectFromReactNative,
|
|
121
|
+
getUniqueId: readUniqueIdFromNative
|
|
122
|
+
};
|
|
123
|
+
export const reactNativeAppInfoReader = {
|
|
124
|
+
readAppInfo: () => appFieldsFromNative(readNativeAppConstants())
|
|
125
|
+
};
|
|
126
|
+
export const reactNativeNetworkInfoReader = {
|
|
127
|
+
readNetworkInfo: collectFromNativeNetwork
|
|
128
|
+
};
|
|
129
|
+
export const reactNativeNetworkStatusReader = {
|
|
130
|
+
getIsOnline: readIsOnlineFromNative,
|
|
131
|
+
subscribe: subscribeNativeNetworkStatus
|
|
132
|
+
};
|
|
133
|
+
export const reactNativeUrlOpener = Linking;
|
|
@@ -1,22 +1,71 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
import { ANONYMOUS_ID_KEY_PREFIX, sanitizeStorageId } from "../../config/StorageKeys.js";
|
|
4
|
+
import { nonEmptyString } from "../../utils/strings.js";
|
|
5
|
+
import { createUuid } from "../../utils/uuid.js";
|
|
3
6
|
export class DeviceInfoService {
|
|
4
|
-
constructor(platform, reader) {
|
|
7
|
+
constructor(platform, reader, storage, appId) {
|
|
5
8
|
this.platform = platform;
|
|
6
9
|
this.reader = reader;
|
|
10
|
+
this.storage = storage;
|
|
11
|
+
this.anonymousIdKey = storage && appId ? `${ANONYMOUS_ID_KEY_PREFIX}${sanitizeStorageId(appId)}` : undefined;
|
|
7
12
|
}
|
|
8
13
|
getDeviceInfo() {
|
|
9
14
|
if (!this.cached) {
|
|
10
|
-
|
|
11
|
-
this.cached = this.reader?.readDeviceInfo(this.platform) ?? {
|
|
12
|
-
platform: this.platform
|
|
13
|
-
};
|
|
14
|
-
} catch {
|
|
15
|
-
this.cached = {
|
|
16
|
-
platform: this.platform
|
|
17
|
-
};
|
|
18
|
-
}
|
|
15
|
+
this.cached = this.readDeviceInfo();
|
|
19
16
|
}
|
|
20
17
|
return this.cached;
|
|
21
18
|
}
|
|
19
|
+
getUniqueId() {
|
|
20
|
+
if (!this.uniqueIdPromise) {
|
|
21
|
+
this.uniqueIdPromise = this.resolveUniqueId();
|
|
22
|
+
}
|
|
23
|
+
return this.uniqueIdPromise;
|
|
24
|
+
}
|
|
25
|
+
readDeviceInfo() {
|
|
26
|
+
const fallback = {
|
|
27
|
+
platform: this.platform
|
|
28
|
+
};
|
|
29
|
+
try {
|
|
30
|
+
return this.reader?.readDeviceInfo(this.platform) ?? fallback;
|
|
31
|
+
} catch {
|
|
32
|
+
return fallback;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async resolveUniqueId() {
|
|
36
|
+
const stored = await this.readStoredId();
|
|
37
|
+
if (stored) {
|
|
38
|
+
return stored;
|
|
39
|
+
}
|
|
40
|
+
const uniqueId = (await this.readNativeId()) ?? createUuid();
|
|
41
|
+
await this.writeStoredId(uniqueId);
|
|
42
|
+
return uniqueId;
|
|
43
|
+
}
|
|
44
|
+
async readNativeId() {
|
|
45
|
+
try {
|
|
46
|
+
return nonEmptyString(await this.reader?.getUniqueId?.());
|
|
47
|
+
} catch {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async readStoredId() {
|
|
52
|
+
if (!this.storage || !this.anonymousIdKey) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
return nonEmptyString(await this.storage.getItem(this.anonymousIdKey));
|
|
57
|
+
} catch {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async writeStoredId(uniqueId) {
|
|
62
|
+
if (!this.storage || !this.anonymousIdKey) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
await this.storage.setItem(this.anonymousIdKey, uniqueId);
|
|
67
|
+
} catch {
|
|
68
|
+
// Persistence must not block tracking.
|
|
69
|
+
}
|
|
70
|
+
}
|
|
22
71
|
}
|
|
@@ -15,14 +15,13 @@ export class EventBuilder {
|
|
|
15
15
|
const {
|
|
16
16
|
validator,
|
|
17
17
|
appId,
|
|
18
|
-
anonymousId,
|
|
19
18
|
deviceInfo,
|
|
20
19
|
appInfo,
|
|
21
20
|
networkInfo
|
|
22
21
|
} = this.config;
|
|
23
22
|
validator.validateTrackInput(input);
|
|
24
23
|
const user = {
|
|
25
|
-
anonymous_id: await
|
|
24
|
+
anonymous_id: await deviceInfo.getUniqueId()
|
|
26
25
|
};
|
|
27
26
|
setIfPresent(user, 'external_user_id', nonEmptyString(this.externalUserId));
|
|
28
27
|
return {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AdaxonAppContext, AdaxonDeviceContext, AdaxonNetworkContext, AdaxonPlatform } from '../types/EventTypes.js';
|
|
2
2
|
export interface DeviceInfoReader {
|
|
3
3
|
readDeviceInfo(platform: AdaxonPlatform): AdaxonDeviceContext;
|
|
4
|
+
getUniqueId?(): Promise<string>;
|
|
4
5
|
}
|
|
5
6
|
export interface AppInfoReader {
|
|
6
7
|
readAppInfo(): AdaxonAppContext;
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import type { DeviceInfoReader } from '../../platform/types.js';
|
|
2
|
+
import type { AdaxonStorageAdapter } from '../../types/AdaxonConfig.js';
|
|
2
3
|
import type { AdaxonDeviceContext, AdaxonPlatform } from '../../types/EventTypes.js';
|
|
3
4
|
export declare class DeviceInfoService {
|
|
4
5
|
private readonly platform;
|
|
5
6
|
private readonly reader?;
|
|
7
|
+
private readonly storage?;
|
|
6
8
|
private cached?;
|
|
7
|
-
|
|
9
|
+
private uniqueIdPromise?;
|
|
10
|
+
private readonly anonymousIdKey?;
|
|
11
|
+
constructor(platform: AdaxonPlatform, reader?: DeviceInfoReader | undefined, storage?: AdaxonStorageAdapter | undefined, appId?: string);
|
|
8
12
|
getDeviceInfo(): AdaxonDeviceContext;
|
|
13
|
+
getUniqueId(): Promise<string>;
|
|
14
|
+
private readDeviceInfo;
|
|
15
|
+
private resolveUniqueId;
|
|
16
|
+
private readNativeId;
|
|
17
|
+
private readStoredId;
|
|
18
|
+
private writeStoredId;
|
|
9
19
|
}
|
|
10
20
|
//# sourceMappingURL=DeviceInfoService.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { AppInfoService } from '../app/AppInfoService.js';
|
|
2
2
|
import type { DeviceInfoService } from '../device/DeviceInfoService.js';
|
|
3
3
|
import type { NetworkInfoService } from '../network/NetworkInfoService.js';
|
|
4
|
-
import type { AnonymousIdService } from '../../storage/AnonymousIdService.js';
|
|
5
4
|
import type { EventPayload, TrackEventInput } from '../../types/EventTypes.js';
|
|
6
5
|
import type { EventValidator } from '../../validation/EventValidator.js';
|
|
7
6
|
interface EventBuilderConfig {
|
|
@@ -9,7 +8,6 @@ interface EventBuilderConfig {
|
|
|
9
8
|
deviceInfo: DeviceInfoService;
|
|
10
9
|
appInfo: AppInfoService;
|
|
11
10
|
networkInfo: NetworkInfoService;
|
|
12
|
-
anonymousId: AnonymousIdService;
|
|
13
11
|
validator: EventValidator;
|
|
14
12
|
externalUserId?: string;
|
|
15
13
|
}
|
package/package.json
CHANGED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { ANONYMOUS_ID_KEY_PREFIX, sanitizeStorageId } from "../config/StorageKeys.js";
|
|
4
|
-
import { createUuid } from "../utils/uuid.js";
|
|
5
|
-
export class AnonymousIdService {
|
|
6
|
-
constructor(appId, storage) {
|
|
7
|
-
this.appId = appId;
|
|
8
|
-
this.storage = storage;
|
|
9
|
-
}
|
|
10
|
-
getAnonymousId() {
|
|
11
|
-
if (!this.anonymousIdPromise) {
|
|
12
|
-
this.anonymousIdPromise = this.loadOrCreate().catch(error => {
|
|
13
|
-
this.anonymousIdPromise = undefined;
|
|
14
|
-
throw error;
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
return this.anonymousIdPromise;
|
|
18
|
-
}
|
|
19
|
-
get storageKey() {
|
|
20
|
-
return `${ANONYMOUS_ID_KEY_PREFIX}${sanitizeStorageId(this.appId)}`;
|
|
21
|
-
}
|
|
22
|
-
async loadOrCreate() {
|
|
23
|
-
const stored = await this.storage?.getItem(this.storageKey);
|
|
24
|
-
if (stored) {
|
|
25
|
-
return stored;
|
|
26
|
-
}
|
|
27
|
-
const anonymousId = createUuid();
|
|
28
|
-
await this.storage?.setItem(this.storageKey, anonymousId);
|
|
29
|
-
return anonymousId;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { AdaxonStorageAdapter } from '../types/AdaxonConfig.js';
|
|
2
|
-
export declare class AnonymousIdService {
|
|
3
|
-
private readonly appId;
|
|
4
|
-
private readonly storage?;
|
|
5
|
-
private anonymousIdPromise?;
|
|
6
|
-
constructor(appId: string, storage?: AdaxonStorageAdapter | undefined);
|
|
7
|
-
getAnonymousId(): Promise<string>;
|
|
8
|
-
private get storageKey();
|
|
9
|
-
private loadOrCreate;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=AnonymousIdService.d.ts.map
|