@drakkar.software/sunglasses-react-native 0.12.0 → 0.13.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.d.mts CHANGED
@@ -64,26 +64,6 @@ declare function SunglassesProvider({ client, autoCaptureErrors, children, }: Su
64
64
  */
65
65
  declare function useSunglasses(): ISunglassesClient;
66
66
 
67
- /**
68
- * Expo Router screen tracking hook.
69
- *
70
- * Tracks screen changes by observing the `pathname` from Expo Router.
71
- * Place this hook inside your root `_layout.tsx`.
72
- *
73
- * **Requires**: `expo-router` to be installed in your project.
74
- *
75
- * @example
76
- * ```tsx
77
- * // app/_layout.tsx
78
- * import { useExpoRouterScreenTracking } from '@drakkar.software/sunglasses-react-native';
79
- *
80
- * export default function RootLayout() {
81
- * const client = useSunglasses();
82
- * useExpoRouterScreenTracking(client);
83
- * return <Stack />;
84
- * }
85
- * ```
86
- */
87
67
  declare function useExpoRouterScreenTracking(client: ISunglassesClient, options?: Pick<ScreenTrackingOptions, 'screenNameMapper'>): void;
88
68
 
89
69
  interface NavigationState {
package/dist/index.d.ts CHANGED
@@ -64,26 +64,6 @@ declare function SunglassesProvider({ client, autoCaptureErrors, children, }: Su
64
64
  */
65
65
  declare function useSunglasses(): ISunglassesClient;
66
66
 
67
- /**
68
- * Expo Router screen tracking hook.
69
- *
70
- * Tracks screen changes by observing the `pathname` from Expo Router.
71
- * Place this hook inside your root `_layout.tsx`.
72
- *
73
- * **Requires**: `expo-router` to be installed in your project.
74
- *
75
- * @example
76
- * ```tsx
77
- * // app/_layout.tsx
78
- * import { useExpoRouterScreenTracking } from '@drakkar.software/sunglasses-react-native';
79
- *
80
- * export default function RootLayout() {
81
- * const client = useSunglasses();
82
- * useExpoRouterScreenTracking(client);
83
- * return <Stack />;
84
- * }
85
- * ```
86
- */
87
67
  declare function useExpoRouterScreenTracking(client: ISunglassesClient, options?: Pick<ScreenTrackingOptions, 'screenNameMapper'>): void;
88
68
 
89
69
  interface NavigationState {
package/dist/index.js CHANGED
@@ -91,7 +91,12 @@ function reasonOf(event) {
91
91
  }
92
92
  function attachUnhandledRejectionHandler(client, options = {}) {
93
93
  const onUnhandled = (error) => {
94
- (0, import_sunglasses_core.captureException)(client, error, { handled: false, ...options });
94
+ (0, import_sunglasses_core.captureException)(client, error, {
95
+ handled: false,
96
+ ...options,
97
+ source: "rejection",
98
+ fatal: false
99
+ });
95
100
  (0, import_sunglasses_core.publishGlobalError)({ error, fatal: false, kind: "rejection" });
96
101
  };
97
102
  const tracking = rejectionTracking;
@@ -149,7 +154,12 @@ function SunglassesProvider({
149
154
  if (options.globalHandlers !== false && typeof ErrorUtils !== "undefined" && ErrorUtils.setGlobalHandler) {
150
155
  const previous = ErrorUtils.getGlobalHandler?.();
151
156
  ErrorUtils.setGlobalHandler((error, isFatal) => {
152
- (0, import_sunglasses_core2.captureException)(client, error, { handled: false, ...options });
157
+ (0, import_sunglasses_core2.captureException)(client, error, {
158
+ handled: false,
159
+ ...options,
160
+ fatal: isFatal !== false,
161
+ source: "global"
162
+ });
153
163
  (0, import_sunglasses_core2.publishGlobalError)({ error, fatal: isFatal !== false, kind: "error" });
154
164
  previous?.(error, isFatal);
155
165
  });
@@ -182,14 +192,26 @@ function SunglassesProvider({
182
192
 
183
193
  // src/useExpoRouterScreenTracking.ts
184
194
  var import_react3 = require("react");
195
+
196
+ // src/expoRouterCompat.ts
197
+ var _useGlobalSearchParams = null;
198
+ var _usePathname = null;
199
+ try {
200
+ const expoRouter = require("expo-router");
201
+ _useGlobalSearchParams = expoRouter.useGlobalSearchParams;
202
+ _usePathname = expoRouter.usePathname;
203
+ } catch {
204
+ }
205
+ var useGlobalSearchParams = _useGlobalSearchParams;
206
+ var usePathname = _usePathname;
207
+
208
+ // src/useExpoRouterScreenTracking.ts
209
+ function _noopPathname() {
210
+ return "";
211
+ }
212
+ var _impl = usePathname ?? _noopPathname;
185
213
  function useExpoRouterScreenTracking(client, options = {}) {
186
- let pathname;
187
- try {
188
- const { usePathname: usePathname2 } = require("expo-router");
189
- pathname = usePathname2();
190
- } catch {
191
- return;
192
- }
214
+ const pathname = _impl();
193
215
  const { screenNameMapper } = options;
194
216
  (0, import_react3.useEffect)(() => {
195
217
  if (!pathname) return;
@@ -277,20 +299,6 @@ function useLinkingUtmCapture(client) {
277
299
 
278
300
  // src/useExpoRouterUtmCapture.ts
279
301
  var import_react6 = require("react");
280
-
281
- // src/expoRouterCompat.ts
282
- var _useGlobalSearchParams = null;
283
- var _usePathname = null;
284
- try {
285
- const expoRouter = require("expo-router");
286
- _useGlobalSearchParams = expoRouter.useGlobalSearchParams;
287
- _usePathname = expoRouter.usePathname;
288
- } catch {
289
- }
290
- var useGlobalSearchParams = _useGlobalSearchParams;
291
- var usePathname = _usePathname;
292
-
293
- // src/useExpoRouterUtmCapture.ts
294
302
  function useExpoRouterUtmCapture(client) {
295
303
  if (!useGlobalSearchParams) return;
296
304
  const params = useGlobalSearchParams();
@@ -322,9 +330,14 @@ var ErrorBoundaryInner = class extends import_react7.default.Component {
322
330
  static getDerivedStateFromError() {
323
331
  return { hasError: true };
324
332
  }
325
- componentDidCatch(error) {
333
+ componentDidCatch(error, errorInfo) {
326
334
  const { client, config } = this.props;
327
- (0, import_sunglasses_core3.captureException)(client, error, { handled: true, ...config });
335
+ (0, import_sunglasses_core3.captureException)(client, error, {
336
+ handled: true,
337
+ ...config,
338
+ componentStack: errorInfo.componentStack ?? void 0,
339
+ source: "boundary"
340
+ });
328
341
  }
329
342
  render() {
330
343
  if (this.state.hasError) return this.props.fallback ?? null;
@@ -355,14 +368,20 @@ var GlobalErrorBoundaryInner = class extends import_react8.default.Component {
355
368
  return { hasError: true };
356
369
  }
357
370
  componentDidMount() {
371
+ if (typeof import_sunglasses_core4.subscribeGlobalError !== "function") return;
358
372
  this.unsubscribe = (0, import_sunglasses_core4.subscribeGlobalError)((info) => this.handleGlobalError(info));
359
373
  }
360
374
  componentWillUnmount() {
361
375
  this.unsubscribe?.();
362
376
  }
363
- componentDidCatch(error) {
377
+ componentDidCatch(error, errorInfo) {
364
378
  const { client, config } = this.props;
365
- (0, import_sunglasses_core4.captureException)(client, error, { handled: true, ...config });
379
+ (0, import_sunglasses_core4.captureException)(client, error, {
380
+ handled: true,
381
+ ...config,
382
+ componentStack: errorInfo.componentStack ?? void 0,
383
+ source: "boundary"
384
+ });
366
385
  }
367
386
  /**
368
387
  * React to a global error published by the provider's auto-capture handlers.
@@ -417,6 +436,9 @@ function wrapExpoRouterErrorBoundary(Boundary, options = {}) {
417
436
  (0, import_sunglasses_core5.captureException)(client, error, {
418
437
  handled: true,
419
438
  ...options.config,
439
+ // Expo Router passes only { error, retry } — no errorInfo is available,
440
+ // so $error_component_stack cannot be captured here.
441
+ source: "boundary",
420
442
  properties: { ...routeProps, ...options.config?.properties }
421
443
  });
422
444
  }, [client, error, pathname]);
package/dist/index.mjs CHANGED
@@ -47,7 +47,12 @@ function reasonOf(event) {
47
47
  }
48
48
  function attachUnhandledRejectionHandler(client, options = {}) {
49
49
  const onUnhandled = (error) => {
50
- captureException(client, error, { handled: false, ...options });
50
+ captureException(client, error, {
51
+ handled: false,
52
+ ...options,
53
+ source: "rejection",
54
+ fatal: false
55
+ });
51
56
  publishGlobalError({ error, fatal: false, kind: "rejection" });
52
57
  };
53
58
  const tracking = rejectionTracking;
@@ -105,7 +110,12 @@ function SunglassesProvider({
105
110
  if (options.globalHandlers !== false && typeof ErrorUtils !== "undefined" && ErrorUtils.setGlobalHandler) {
106
111
  const previous = ErrorUtils.getGlobalHandler?.();
107
112
  ErrorUtils.setGlobalHandler((error, isFatal) => {
108
- captureException2(client, error, { handled: false, ...options });
113
+ captureException2(client, error, {
114
+ handled: false,
115
+ ...options,
116
+ fatal: isFatal !== false,
117
+ source: "global"
118
+ });
109
119
  publishGlobalError2({ error, fatal: isFatal !== false, kind: "error" });
110
120
  previous?.(error, isFatal);
111
121
  });
@@ -138,14 +148,26 @@ function SunglassesProvider({
138
148
 
139
149
  // src/useExpoRouterScreenTracking.ts
140
150
  import { useEffect as useEffect2 } from "react";
151
+
152
+ // src/expoRouterCompat.ts
153
+ var _useGlobalSearchParams = null;
154
+ var _usePathname = null;
155
+ try {
156
+ const expoRouter = __require("expo-router");
157
+ _useGlobalSearchParams = expoRouter.useGlobalSearchParams;
158
+ _usePathname = expoRouter.usePathname;
159
+ } catch {
160
+ }
161
+ var useGlobalSearchParams = _useGlobalSearchParams;
162
+ var usePathname = _usePathname;
163
+
164
+ // src/useExpoRouterScreenTracking.ts
165
+ function _noopPathname() {
166
+ return "";
167
+ }
168
+ var _impl = usePathname ?? _noopPathname;
141
169
  function useExpoRouterScreenTracking(client, options = {}) {
142
- let pathname;
143
- try {
144
- const { usePathname: usePathname2 } = __require("expo-router");
145
- pathname = usePathname2();
146
- } catch {
147
- return;
148
- }
170
+ const pathname = _impl();
149
171
  const { screenNameMapper } = options;
150
172
  useEffect2(() => {
151
173
  if (!pathname) return;
@@ -233,20 +255,6 @@ function useLinkingUtmCapture(client) {
233
255
 
234
256
  // src/useExpoRouterUtmCapture.ts
235
257
  import { useEffect as useEffect5 } from "react";
236
-
237
- // src/expoRouterCompat.ts
238
- var _useGlobalSearchParams = null;
239
- var _usePathname = null;
240
- try {
241
- const expoRouter = __require("expo-router");
242
- _useGlobalSearchParams = expoRouter.useGlobalSearchParams;
243
- _usePathname = expoRouter.usePathname;
244
- } catch {
245
- }
246
- var useGlobalSearchParams = _useGlobalSearchParams;
247
- var usePathname = _usePathname;
248
-
249
- // src/useExpoRouterUtmCapture.ts
250
258
  function useExpoRouterUtmCapture(client) {
251
259
  if (!useGlobalSearchParams) return;
252
260
  const params = useGlobalSearchParams();
@@ -278,9 +286,14 @@ var ErrorBoundaryInner = class extends React2.Component {
278
286
  static getDerivedStateFromError() {
279
287
  return { hasError: true };
280
288
  }
281
- componentDidCatch(error) {
289
+ componentDidCatch(error, errorInfo) {
282
290
  const { client, config } = this.props;
283
- captureException3(client, error, { handled: true, ...config });
291
+ captureException3(client, error, {
292
+ handled: true,
293
+ ...config,
294
+ componentStack: errorInfo.componentStack ?? void 0,
295
+ source: "boundary"
296
+ });
284
297
  }
285
298
  render() {
286
299
  if (this.state.hasError) return this.props.fallback ?? null;
@@ -311,14 +324,20 @@ var GlobalErrorBoundaryInner = class extends React3.Component {
311
324
  return { hasError: true };
312
325
  }
313
326
  componentDidMount() {
327
+ if (typeof subscribeGlobalError !== "function") return;
314
328
  this.unsubscribe = subscribeGlobalError((info) => this.handleGlobalError(info));
315
329
  }
316
330
  componentWillUnmount() {
317
331
  this.unsubscribe?.();
318
332
  }
319
- componentDidCatch(error) {
333
+ componentDidCatch(error, errorInfo) {
320
334
  const { client, config } = this.props;
321
- captureException4(client, error, { handled: true, ...config });
335
+ captureException4(client, error, {
336
+ handled: true,
337
+ ...config,
338
+ componentStack: errorInfo.componentStack ?? void 0,
339
+ source: "boundary"
340
+ });
322
341
  }
323
342
  /**
324
343
  * React to a global error published by the provider's auto-capture handlers.
@@ -373,6 +392,9 @@ function wrapExpoRouterErrorBoundary(Boundary, options = {}) {
373
392
  captureException5(client, error, {
374
393
  handled: true,
375
394
  ...options.config,
395
+ // Expo Router passes only { error, retry } — no errorInfo is available,
396
+ // so $error_component_stack cannot be captured here.
397
+ source: "boundary",
376
398
  properties: { ...routeProps, ...options.config?.properties }
377
399
  });
378
400
  }, [client, error, pathname]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drakkar.software/sunglasses-react-native",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "React Native / Expo provider and hooks for SunGlasses event tracking",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -16,7 +16,7 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@drakkar.software/sunglasses-core": "0.12.0"
19
+ "@drakkar.software/sunglasses-core": "0.13.0"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "expo-router": ">=3.0.0",