@flareapp/react-native 2.9.0 → 2.11.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.
package/dist/index.cjs CHANGED
@@ -23,71 +23,71 @@ function loadExpoModules() {
23
23
  } catch {}
24
24
  return mods;
25
25
  }
26
- /** Maps Expo's `DeviceType` enum (UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4) to a label. */
26
+ /** Expo's `DeviceType` enum (UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4). */
27
27
  const DEVICE_TYPE_LABELS = {
28
28
  1: "phone",
29
29
  2: "tablet",
30
30
  3: "desktop",
31
31
  4: "tv"
32
32
  };
33
- /**
34
- * Turn the synchronous Expo constants into report attributes. Only present (non-null) fields are emitted.
35
- * Async Expo getters are not used, since the context collector is synchronous.
36
- */
37
- function projectExpoContext(expo) {
38
- const attrs = {};
33
+ /** Normalise the synchronous Expo constants into `DeviceInfo`. Only present (non-null) fields are set. */
34
+ function expoToDeviceInfo(expo) {
35
+ const info = {};
39
36
  const device = expo.device;
40
37
  if (device) {
41
- if (device.modelName != null) attrs["device.model.name"] = device.modelName;
42
- if (device.osName != null) attrs["os.name"] = device.osName;
43
- if (device.osVersion != null) attrs["os.version"] = device.osVersion;
44
- if (device.deviceType != null) {
45
- const label = DEVICE_TYPE_LABELS[device.deviceType];
46
- if (label) attrs["device.type"] = label;
47
- }
38
+ const os = {};
39
+ if (device.osName != null) os.name = device.osName;
40
+ if (device.osVersion != null) os.version = device.osVersion;
41
+ if (Object.keys(os).length > 0) info.os = os;
42
+ const target = {};
43
+ if (device.modelName != null) target.model = device.modelName;
44
+ if (device.deviceType != null && DEVICE_TYPE_LABELS[device.deviceType]) target.type = DEVICE_TYPE_LABELS[device.deviceType];
45
+ if (Object.keys(target).length > 0) info.device = target;
48
46
  }
49
47
  const application = expo.application;
50
48
  if (application) {
51
- if (application.nativeApplicationVersion != null) attrs["app.version"] = application.nativeApplicationVersion;
52
- if (application.applicationId != null) attrs["app.id"] = application.applicationId;
49
+ const app = {};
50
+ if (application.nativeApplicationVersion != null) app.version = application.nativeApplicationVersion;
51
+ if (application.applicationId != null) app.id = application.applicationId;
52
+ if (Object.keys(app).length > 0) info.app = app;
53
53
  }
54
- return attrs;
54
+ return info;
55
55
  }
56
56
 
57
57
  //#endregion
58
- //#region src/context/collectReactNative.ts
59
- /**
60
- * Two layers: RN core (`Platform`, `Dimensions`) read per call, and Expo constants resolved once and
61
- * absent on bare RN. Expo's `osName`/`osVersion` override the RN values where present.
62
- *
63
- * `Platform.Version` is a string on iOS and a number on Android, hence the stringify. `Platform.OS` maps
64
- * to `os.name`, not `os.type`, which is the kernel family.
65
- */
66
- function makeReactNativeContextCollector(expo = loadExpoModules()) {
67
- const expoAttrs = projectExpoContext(expo);
68
- return (_config) => {
58
+ //#region src/context/deviceInfo.ts
59
+ /** Expo constants (resolved once) override the per-call RN-core `Platform`/`Dimensions` values. */
60
+ var ReactNativeDeviceInfoProvider = class {
61
+ expoInfo;
62
+ constructor(expo = loadExpoModules()) {
63
+ this.expoInfo = expoToDeviceInfo(expo);
64
+ }
65
+ collect() {
69
66
  const screen = react_native.Dimensions.get("window");
70
- const attrs = {
71
- "os.name": react_native.Platform.OS,
72
- "os.version": String(react_native.Platform.Version),
73
- "device.screen.width": screen.width,
74
- "device.screen.height": screen.height,
75
- "device.screen.scale": screen.scale,
76
- ...expoAttrs
67
+ const device = {
68
+ screen: {
69
+ width: screen.width,
70
+ height: screen.height,
71
+ scale: screen.scale
72
+ },
73
+ ...this.expoInfo.device
77
74
  };
78
- if (attrs["device.model.name"] == null) {
75
+ if (device.model == null) {
79
76
  const model = nativeModelName();
80
- if (model) attrs["device.model.name"] = model;
77
+ if (model != null) device.model = model;
81
78
  }
82
- const device = buildDeviceContext(attrs);
83
- if (Object.keys(device).length > 0) attrs["context.device"] = device;
84
- return attrs;
85
- };
86
- }
87
- /**
88
- * Native device model from `Platform.constants`, maker-prefixed when available (e.g. `Google Pixel 7`).
89
- * Android exposes `Model`/`Manufacturer`/`Brand`; iOS core surfaces none (needs `expo-device`), so undefined.
90
- */
79
+ const info = {
80
+ os: {
81
+ name: this.expoInfo.os?.name ?? react_native.Platform.OS,
82
+ version: this.expoInfo.os?.version ?? String(react_native.Platform.Version)
83
+ },
84
+ device
85
+ };
86
+ if (this.expoInfo.app) info.app = this.expoInfo.app;
87
+ return info;
88
+ }
89
+ };
90
+ /** Android device model from `Platform.constants`, maker-prefixed (e.g. `Google Pixel 7`). iOS core exposes none. */
91
91
  function nativeModelName() {
92
92
  if (react_native.Platform.OS !== "android") return;
93
93
  const constants = react_native.Platform.constants;
@@ -95,22 +95,12 @@ function nativeModelName() {
95
95
  const maker = constants.Manufacturer ?? constants.Brand;
96
96
  return maker ? `${maker} ${constants.Model}` : constants.Model;
97
97
  }
98
- /**
99
- * Build a human-readable `context.device` group from the semantic attributes. Only present fields are
100
- * included, so bare RN (no Expo) omits `model`/`appVersion`/`appId`.
101
- */
102
- function buildDeviceContext(attrs) {
103
- const device = {};
104
- if (attrs["device.model.name"] != null) device.model = attrs["device.model.name"];
105
- const os = [attrs["os.name"], attrs["os.version"]].filter((v) => v != null).join(" ");
106
- if (os) device.OS = os;
107
- const width = attrs["device.screen.width"];
108
- const height = attrs["device.screen.height"];
109
- const scale = attrs["device.screen.scale"];
110
- if (width != null && height != null) device.screen = scale != null ? `${width} × ${height} @ ${scale}x` : `${width} × ${height}`;
111
- if (attrs["app.version"] != null) device.appVersion = attrs["app.version"];
112
- if (attrs["app.id"] != null) device.appId = attrs["app.id"];
113
- return device;
98
+
99
+ //#endregion
100
+ //#region src/context/collectReactNative.ts
101
+ function makeReactNativeContextCollector(expo = loadExpoModules()) {
102
+ const provider = new ReactNativeDeviceInfoProvider(expo);
103
+ return (_config) => (0, _flareapp_core.deviceInfoToAttributes)(provider.collect());
114
104
  }
115
105
 
116
106
  //#endregion
@@ -276,7 +266,7 @@ var ReactNativeFlushScheduler = class {
276
266
  //#endregion
277
267
  //#region src/Flare.ts
278
268
  const RN_SDK_NAME = "@flareapp/react-native";
279
- const RN_SDK_VERSION = "2.9.0";
269
+ const RN_SDK_VERSION = "2.11.0";
280
270
  /** How long a fatal JS crash holds the app open to drain the transport before RN's default handler runs. */
281
271
  const FATAL_FLUSH_TIMEOUT_MS = 2e3;
282
272
  /**
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRequire } from "node:module";
2
- import { Api, DEFAULT_URL_DENYLIST, Flare, Flare as Flare$1, FrameworkName, GlobalScopeProvider, GlobalScopeProvider as GlobalScopeProvider$1, NullFileReader, NullFileReader as NullFileReader$1, convertToError, convertToError as convertToError$1, redactUrlQuery, resolveDenylist, routeRejection } from "@flareapp/core";
2
+ import { Api, DEFAULT_URL_DENYLIST, Flare, Flare as Flare$1, FrameworkName, GlobalScopeProvider, GlobalScopeProvider as GlobalScopeProvider$1, NullFileReader, NullFileReader as NullFileReader$1, convertToError, convertToError as convertToError$1, deviceInfoToAttributes, redactUrlQuery, resolveDenylist, routeRejection } from "@flareapp/core";
3
3
  import { AppState, Dimensions, Platform } from "react-native";
4
4
  import { FlareErrorBoundary as FlareErrorBoundary$1 } from "@flareapp/react/inject";
5
5
  import { createElement } from "react";
@@ -27,71 +27,71 @@ function loadExpoModules() {
27
27
  } catch {}
28
28
  return mods;
29
29
  }
30
- /** Maps Expo's `DeviceType` enum (UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4) to a label. */
30
+ /** Expo's `DeviceType` enum (UNKNOWN=0, PHONE=1, TABLET=2, DESKTOP=3, TV=4). */
31
31
  const DEVICE_TYPE_LABELS = {
32
32
  1: "phone",
33
33
  2: "tablet",
34
34
  3: "desktop",
35
35
  4: "tv"
36
36
  };
37
- /**
38
- * Turn the synchronous Expo constants into report attributes. Only present (non-null) fields are emitted.
39
- * Async Expo getters are not used, since the context collector is synchronous.
40
- */
41
- function projectExpoContext(expo) {
42
- const attrs = {};
37
+ /** Normalise the synchronous Expo constants into `DeviceInfo`. Only present (non-null) fields are set. */
38
+ function expoToDeviceInfo(expo) {
39
+ const info = {};
43
40
  const device = expo.device;
44
41
  if (device) {
45
- if (device.modelName != null) attrs["device.model.name"] = device.modelName;
46
- if (device.osName != null) attrs["os.name"] = device.osName;
47
- if (device.osVersion != null) attrs["os.version"] = device.osVersion;
48
- if (device.deviceType != null) {
49
- const label = DEVICE_TYPE_LABELS[device.deviceType];
50
- if (label) attrs["device.type"] = label;
51
- }
42
+ const os = {};
43
+ if (device.osName != null) os.name = device.osName;
44
+ if (device.osVersion != null) os.version = device.osVersion;
45
+ if (Object.keys(os).length > 0) info.os = os;
46
+ const target = {};
47
+ if (device.modelName != null) target.model = device.modelName;
48
+ if (device.deviceType != null && DEVICE_TYPE_LABELS[device.deviceType]) target.type = DEVICE_TYPE_LABELS[device.deviceType];
49
+ if (Object.keys(target).length > 0) info.device = target;
52
50
  }
53
51
  const application = expo.application;
54
52
  if (application) {
55
- if (application.nativeApplicationVersion != null) attrs["app.version"] = application.nativeApplicationVersion;
56
- if (application.applicationId != null) attrs["app.id"] = application.applicationId;
53
+ const app = {};
54
+ if (application.nativeApplicationVersion != null) app.version = application.nativeApplicationVersion;
55
+ if (application.applicationId != null) app.id = application.applicationId;
56
+ if (Object.keys(app).length > 0) info.app = app;
57
57
  }
58
- return attrs;
58
+ return info;
59
59
  }
60
60
 
61
61
  //#endregion
62
- //#region src/context/collectReactNative.ts
63
- /**
64
- * Two layers: RN core (`Platform`, `Dimensions`) read per call, and Expo constants resolved once and
65
- * absent on bare RN. Expo's `osName`/`osVersion` override the RN values where present.
66
- *
67
- * `Platform.Version` is a string on iOS and a number on Android, hence the stringify. `Platform.OS` maps
68
- * to `os.name`, not `os.type`, which is the kernel family.
69
- */
70
- function makeReactNativeContextCollector(expo = loadExpoModules()) {
71
- const expoAttrs = projectExpoContext(expo);
72
- return (_config) => {
62
+ //#region src/context/deviceInfo.ts
63
+ /** Expo constants (resolved once) override the per-call RN-core `Platform`/`Dimensions` values. */
64
+ var ReactNativeDeviceInfoProvider = class {
65
+ expoInfo;
66
+ constructor(expo = loadExpoModules()) {
67
+ this.expoInfo = expoToDeviceInfo(expo);
68
+ }
69
+ collect() {
73
70
  const screen = Dimensions.get("window");
74
- const attrs = {
75
- "os.name": Platform.OS,
76
- "os.version": String(Platform.Version),
77
- "device.screen.width": screen.width,
78
- "device.screen.height": screen.height,
79
- "device.screen.scale": screen.scale,
80
- ...expoAttrs
71
+ const device = {
72
+ screen: {
73
+ width: screen.width,
74
+ height: screen.height,
75
+ scale: screen.scale
76
+ },
77
+ ...this.expoInfo.device
81
78
  };
82
- if (attrs["device.model.name"] == null) {
79
+ if (device.model == null) {
83
80
  const model = nativeModelName();
84
- if (model) attrs["device.model.name"] = model;
81
+ if (model != null) device.model = model;
85
82
  }
86
- const device = buildDeviceContext(attrs);
87
- if (Object.keys(device).length > 0) attrs["context.device"] = device;
88
- return attrs;
89
- };
90
- }
91
- /**
92
- * Native device model from `Platform.constants`, maker-prefixed when available (e.g. `Google Pixel 7`).
93
- * Android exposes `Model`/`Manufacturer`/`Brand`; iOS core surfaces none (needs `expo-device`), so undefined.
94
- */
83
+ const info = {
84
+ os: {
85
+ name: this.expoInfo.os?.name ?? Platform.OS,
86
+ version: this.expoInfo.os?.version ?? String(Platform.Version)
87
+ },
88
+ device
89
+ };
90
+ if (this.expoInfo.app) info.app = this.expoInfo.app;
91
+ return info;
92
+ }
93
+ };
94
+ /** Android device model from `Platform.constants`, maker-prefixed (e.g. `Google Pixel 7`). iOS core exposes none. */
95
95
  function nativeModelName() {
96
96
  if (Platform.OS !== "android") return;
97
97
  const constants = Platform.constants;
@@ -99,22 +99,12 @@ function nativeModelName() {
99
99
  const maker = constants.Manufacturer ?? constants.Brand;
100
100
  return maker ? `${maker} ${constants.Model}` : constants.Model;
101
101
  }
102
- /**
103
- * Build a human-readable `context.device` group from the semantic attributes. Only present fields are
104
- * included, so bare RN (no Expo) omits `model`/`appVersion`/`appId`.
105
- */
106
- function buildDeviceContext(attrs) {
107
- const device = {};
108
- if (attrs["device.model.name"] != null) device.model = attrs["device.model.name"];
109
- const os = [attrs["os.name"], attrs["os.version"]].filter((v) => v != null).join(" ");
110
- if (os) device.OS = os;
111
- const width = attrs["device.screen.width"];
112
- const height = attrs["device.screen.height"];
113
- const scale = attrs["device.screen.scale"];
114
- if (width != null && height != null) device.screen = scale != null ? `${width} × ${height} @ ${scale}x` : `${width} × ${height}`;
115
- if (attrs["app.version"] != null) device.appVersion = attrs["app.version"];
116
- if (attrs["app.id"] != null) device.appId = attrs["app.id"];
117
- return device;
102
+
103
+ //#endregion
104
+ //#region src/context/collectReactNative.ts
105
+ function makeReactNativeContextCollector(expo = loadExpoModules()) {
106
+ const provider = new ReactNativeDeviceInfoProvider(expo);
107
+ return (_config) => deviceInfoToAttributes(provider.collect());
118
108
  }
119
109
 
120
110
  //#endregion
@@ -280,7 +270,7 @@ var ReactNativeFlushScheduler = class {
280
270
  //#endregion
281
271
  //#region src/Flare.ts
282
272
  const RN_SDK_NAME = "@flareapp/react-native";
283
- const RN_SDK_VERSION = "2.9.0";
273
+ const RN_SDK_VERSION = "2.11.0";
284
274
  /** How long a fatal JS crash holds the app open to drain the transport before RN's default handler runs. */
285
275
  const FATAL_FLUSH_TIMEOUT_MS = 2e3;
286
276
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flareapp/react-native",
3
- "version": "2.9.0",
3
+ "version": "2.11.0",
4
4
  "description": "React Native SDK for flareapp.io",
5
5
  "homepage": "https://flareapp.io",
6
6
  "bugs": {
@@ -49,7 +49,7 @@
49
49
  "release": "release-it"
50
50
  },
51
51
  "dependencies": {
52
- "@flareapp/core": "2.9.0"
52
+ "@flareapp/core": "2.11.0"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@flareapp/react": "^2.5.0",