@attryio/react-native 0.1.7 → 0.1.9

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 (3) hide show
  1. package/README.md +4 -0
  2. package/dist/index.js +72 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -47,6 +47,10 @@ The SDK starts with practical defaults:
47
47
  - Requests Apple AdServices attribution tokens on iOS when the native module is available.
48
48
  - Batches events and retries failed requests through the shared Attry SDK engine.
49
49
 
50
+ ## React Native compatibility
51
+
52
+ The SDK avoids importing the root `react-native` namespace at runtime. Instead, it loads only the React Native APIs it needs, which prevents deprecated core export getters from being touched in newer React Native versions.
53
+
50
54
  ## Track custom events
51
55
 
52
56
  Use `track` for app-specific actions. Event names should be stable `snake_case`; details belong in `properties`.
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { Attry, ATTRY_EVENTS, MemoryStorage, parseAttryUrl } from "@attryio/sdk-core";
2
2
  const SDK_NAME = "attry-react-native";
3
- const SDK_VERSION = "0.1.7";
3
+ const SDK_VERSION = "0.1.9";
4
4
  export { parseAttryUrl };
5
5
  export async function createAttryReactNative(config) {
6
- const rn = await loadReactNative();
6
+ const rn = loadReactNative();
7
7
  const platform = rn?.Platform?.OS === "ios" || rn?.Platform?.OS === "android"
8
8
  ? rn.Platform.OS
9
9
  : "unknown";
@@ -30,7 +30,7 @@ export async function createAttryReactNative(config) {
30
30
  return client;
31
31
  }
32
32
  export async function collectReactNativeContext(rn, configuredContext = {}) {
33
- const native = rn ?? (await loadReactNative());
33
+ const native = rn ?? loadReactNative();
34
34
  const modules = native?.NativeModules;
35
35
  const deviceInfo = modules?.RNDeviceInfo;
36
36
  const expoConstants = modules?.ExpoConstants ?? modules?.ExponentConstants;
@@ -131,7 +131,7 @@ export async function collectReactNativeContext(rn, configuredContext = {}) {
131
131
  });
132
132
  }
133
133
  export async function attachReactNativeLifecycleTracking(client, rn, storage = new MemoryStorage(), options) {
134
- const native = rn ?? (await loadReactNative());
134
+ const native = rn ?? loadReactNative();
135
135
  const installKey = `attry.${options.appId}.install_tracked`;
136
136
  const sessionStartedAt = Date.now();
137
137
  const sessionId = `ses_${sessionStartedAt.toString(36)}`;
@@ -210,7 +210,7 @@ export async function attachReactNativeLifecycleTracking(client, rn, storage = n
210
210
  });
211
211
  }
212
212
  export async function attachDeepLinkTracking(client, rn) {
213
- const native = rn ?? (await loadReactNative());
213
+ const native = rn ?? loadReactNative();
214
214
  const initialUrl = await native?.Linking?.getInitialURL?.();
215
215
  if (initialUrl) {
216
216
  await trackDeepLinkOpen(client, initialUrl, "initial_url", native);
@@ -220,15 +220,15 @@ export async function attachDeepLinkTracking(client, rn) {
220
220
  });
221
221
  }
222
222
  export async function collectInstallAttribution(client, rn) {
223
- const native = rn ?? (await loadReactNative());
223
+ const native = rn ?? loadReactNative();
224
224
  if (native?.Platform?.OS === "ios") {
225
225
  const token = await native.NativeModules?.AttryAppleAds?.attributionToken?.();
226
226
  if (token) {
227
227
  const response = await client.submitAppleAdsToken(token);
228
228
  await client.track("apple_ads_token_collected", {
229
- attribution: response?.attribution ?? {
230
- source: "apple_ads_adservices",
231
- confidence: "deterministic"
229
+ properties: {
230
+ exchangeStatus: response?.exchangeStatus ?? "unknown",
231
+ attributed: Boolean(response?.attribution)
232
232
  }
233
233
  });
234
234
  }
@@ -252,7 +252,7 @@ export async function collectInstallAttribution(client, rn) {
252
252
  }
253
253
  }
254
254
  async function trackDeepLinkOpen(client, url, openType, rn) {
255
- const native = rn ?? (await loadReactNative());
255
+ const native = rn ?? loadReactNative();
256
256
  const parsed = parseAttryUrl(url);
257
257
  const openedFromUniversalLink = native?.Platform?.OS === "ios";
258
258
  const openedFromAndroidAppLink = native?.Platform?.OS === "android";
@@ -385,14 +385,74 @@ function safeTimezone() {
385
385
  return undefined;
386
386
  }
387
387
  }
388
- async function loadReactNative() {
388
+ function loadReactNative() {
389
+ // Avoid importing the root "react-native" namespace. In RN 0.81+, namespace
390
+ // imports can touch deprecated core export getters such as PushNotificationIOS.
391
+ const native = {
392
+ AppState: requireAppState(),
393
+ Dimensions: requireDimensions(),
394
+ I18nManager: requireI18nManager(),
395
+ Linking: requireLinking(),
396
+ NativeModules: requireNativeModules(),
397
+ Platform: requirePlatform()
398
+ };
399
+ return Object.values(native).some(Boolean) ? native : undefined;
400
+ }
401
+ function requireAppState() {
402
+ try {
403
+ return defaultExport(require("react-native/Libraries/AppState/AppState"));
404
+ }
405
+ catch {
406
+ return undefined;
407
+ }
408
+ }
409
+ function requireDimensions() {
389
410
  try {
390
- return (await import("react-native"));
411
+ return defaultExport(require("react-native/Libraries/Utilities/Dimensions"));
391
412
  }
392
413
  catch {
393
414
  return undefined;
394
415
  }
395
416
  }
417
+ function requireI18nManager() {
418
+ try {
419
+ return defaultExport(require("react-native/Libraries/ReactNative/I18nManager"));
420
+ }
421
+ catch {
422
+ return undefined;
423
+ }
424
+ }
425
+ function requireLinking() {
426
+ try {
427
+ return defaultExport(require("react-native/Libraries/Linking/Linking"));
428
+ }
429
+ catch {
430
+ return undefined;
431
+ }
432
+ }
433
+ function requireNativeModules() {
434
+ try {
435
+ return defaultExport(require("react-native/Libraries/BatchedBridge/NativeModules"));
436
+ }
437
+ catch {
438
+ return undefined;
439
+ }
440
+ }
441
+ function requirePlatform() {
442
+ try {
443
+ return defaultExport(require("react-native/Libraries/Utilities/Platform"));
444
+ }
445
+ catch {
446
+ return undefined;
447
+ }
448
+ }
449
+ function defaultExport(moduleValue) {
450
+ if (!moduleValue) {
451
+ return undefined;
452
+ }
453
+ const maybeDefault = moduleValue;
454
+ return maybeDefault.default ?? moduleValue;
455
+ }
396
456
  async function createAsyncStorageAdapter() {
397
457
  try {
398
458
  const asyncStorageModule = (await import("@react-native-async-storage/async-storage"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@attryio/react-native",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "React Native SDK for Attry mobile app analytics, attribution, deep links, deferred deep links, and revenue events.",
5
5
  "private": false,
6
6
  "license": "Apache-2.0",