diff --git a/packages/sdks/react-native/index.ts b/packages/sdks/react-native/index.ts index 9044c692f..8884ac726 100644 --- a/packages/sdks/react-native/index.ts +++ b/packages/sdks/react-native/index.ts @@ -5,13 +5,32 @@ import type { } from '@openpanel/sdk'; import { OpenPanel as OpenPanelBase } from '@openpanel/sdk'; import * as Application from 'expo-application'; -import Constants from 'expo-constants'; +import * as ExpoConstants from 'expo-constants'; import { AppState, Platform } from 'react-native'; export * from '@openpanel/sdk'; const QUEUE_STORAGE_KEY = '@openpanel/offline_queue'; +/** + * Metro/CJS interop can nest the real module under `.default` when this + * package is consumed as ESM. Prefer the same `import *` shape we already + * use for expo-application, and fall back if the helper is missing so init + * never crashes (e.g. Expo SDK 55+ with previously unmet peers). + */ +function getWebViewUserAgent(): Promise { + const mod = ExpoConstants as typeof ExpoConstants & { + default?: typeof ExpoConstants; + }; + const constants = (mod.default ?? mod) as { + getWebViewUserAgentAsync?: () => Promise; + }; + if (typeof constants.getWebViewUserAgentAsync !== 'function') { + return Promise.resolve(null); + } + return constants.getWebViewUserAgentAsync(); +} + interface StorageLike { getItem(key: string): Promise; setItem(key: string, value: string): Promise; @@ -59,7 +78,7 @@ export class OpenPanel extends OpenPanelBase { sdkVersion: process.env.REACT_NATIVE_VERSION!, }); - this.api.addHeader('User-Agent', Constants.getWebViewUserAgentAsync()); + this.api.addHeader('User-Agent', getWebViewUserAgent()); this.storage = options.storage; if (options.networkInfo) { diff --git a/packages/sdks/react-native/package.json b/packages/sdks/react-native/package.json index fcca7fa79..258ba9d53 100644 --- a/packages/sdks/react-native/package.json +++ b/packages/sdks/react-native/package.json @@ -20,8 +20,8 @@ "typescript": "catalog:" }, "peerDependencies": { - "expo-application": "5 - 7", - "expo-constants": "14 - 18", + "expo-application": "5 - 7 || 50 - 55", + "expo-constants": "14 - 18 || 50 - 55", "react-native": "*" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a88b23d96..4119cc874 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1844,10 +1844,10 @@ importers: specifier: workspace:1.3.1-local version: link:../sdk expo-application: - specifier: 5 - 7 + specifier: 5 - 7 || 50 - 55 version: 5.3.1(expo@50.0.7(@babel/core@7.29.0(supports-color@10.2.0))(@react-native/babel-preset@0.73.21(@babel/core@7.29.0(supports-color@10.2.0))(@babel/preset-env@7.23.9(@babel/core@7.29.0(supports-color@10.2.0))(supports-color@10.2.0))(supports-color@10.2.0))(bluebird@3.7.2)(react-native@0.73.6(@babel/core@7.29.0(supports-color@10.2.0))(@babel/preset-env@7.23.9(@babel/core@7.29.0(supports-color@10.2.0))(supports-color@10.2.0))(react@18.2.0)(supports-color@10.2.0))(react@18.2.0)(supports-color@10.2.0)) expo-constants: - specifier: 14 - 18 + specifier: 14 - 18 || 50 - 55 version: 15.4.5(expo@50.0.7(@babel/core@7.29.0(supports-color@10.2.0))(@react-native/babel-preset@0.73.21(@babel/core@7.29.0(supports-color@10.2.0))(@babel/preset-env@7.23.9(@babel/core@7.29.0(supports-color@10.2.0))(supports-color@10.2.0))(supports-color@10.2.0))(bluebird@3.7.2)(react-native@0.73.6(@babel/core@7.29.0(supports-color@10.2.0))(@babel/preset-env@7.23.9(@babel/core@7.29.0(supports-color@10.2.0))(supports-color@10.2.0))(react@18.2.0)(supports-color@10.2.0))(react@18.2.0)(supports-color@10.2.0))(supports-color@10.2.0) react-native: specifier: '*'