@drakkar.software/sunglasses-react-native 0.8.0 → 0.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.d.mts CHANGED
@@ -1,10 +1,23 @@
1
1
  import React$1 from 'react';
2
- import { ISunglassesClient, ScreenTrackingOptions } from '@drakkar.software/sunglasses-core';
3
- export { ConsentStatus, ISunglassesClient, ScreenTrackingOptions, SunglassesConfig, SunglassesCore, SunglassesEvent } from '@drakkar.software/sunglasses-core';
2
+ import { ISunglassesClient, AutoCaptureErrorsOptions, ScreenTrackingOptions, CaptureExceptionOptions } from '@drakkar.software/sunglasses-core';
3
+ export { AutoCaptureErrorsOptions, CaptureExceptionOptions, ConsentStatus, ConsoleCaptureOptions, ISunglassesClient, ScreenTrackingOptions, SunglassesConfig, SunglassesCore, SunglassesEvent, captureException, patchConsole } from '@drakkar.software/sunglasses-core';
4
4
 
5
5
  interface SunglassesProviderProps {
6
6
  /** An initialized ISunglassesClient (from SunglassesCore.create()). */
7
7
  client: ISunglassesClient;
8
+ /**
9
+ * Automatically capture unhandled errors as `$error` events
10
+ * (`$error_handled: false`).
11
+ *
12
+ * - `true` installs a global `ErrorUtils` handler (the previous handler is
13
+ * preserved and still invoked).
14
+ * - An options object additionally lets you toggle `globalHandlers` and opt
15
+ * into `console` capture (`console.error` / `console.warn`), plus configure
16
+ * truncation / stack inclusion / ignore patterns.
17
+ *
18
+ * Default: off.
19
+ */
20
+ autoCaptureErrors?: boolean | AutoCaptureErrorsOptions;
8
21
  children: React$1.ReactNode;
9
22
  }
10
23
  /**
@@ -42,7 +55,7 @@ interface SunglassesProviderProps {
42
55
  * }
43
56
  * ```
44
57
  */
45
- declare function SunglassesProvider({ client, children, }: SunglassesProviderProps): React$1.ReactElement;
58
+ declare function SunglassesProvider({ client, autoCaptureErrors, children, }: SunglassesProviderProps): React$1.ReactElement;
46
59
 
47
60
  /**
48
61
  * Access the SunGlasses client from React context (React Native).
@@ -184,4 +197,34 @@ declare function useLinkingUtmCapture(client: ISunglassesClient): void;
184
197
  */
185
198
  declare function useExpoRouterUtmCapture(client: ISunglassesClient): void;
186
199
 
187
- export { SunglassesProvider, type SunglassesProviderProps, captureDeepLinkUtmParams, useExpoRouterScreenTracking, useExpoRouterUtmCapture, useLinkingUtmCapture, useNavigationScreenTracking, useSunglasses };
200
+ interface SunglassesErrorBoundaryProps {
201
+ /**
202
+ * SunGlasses client. Optional — defaults to the client provided by the
203
+ * nearest `<SunglassesProvider>`.
204
+ */
205
+ client?: ISunglassesClient;
206
+ /** Rendered when an error is caught. Defaults to rendering nothing. */
207
+ fallback?: React$1.ReactNode;
208
+ /** Error capture configuration forwarded to `captureException`. */
209
+ config?: CaptureExceptionOptions;
210
+ children: React$1.ReactNode;
211
+ }
212
+ /**
213
+ * React Native error boundary that captures render-phase errors as SunGlasses
214
+ * `$error` events (`$error_handled: true`).
215
+ *
216
+ * The client is read from the nearest `<SunglassesProvider>` by default; pass
217
+ * an explicit `client` prop to override.
218
+ *
219
+ * @example
220
+ * ```tsx
221
+ * <SunglassesProvider client={client}>
222
+ * <SunglassesErrorBoundary fallback={<ErrorScreen />}>
223
+ * <App />
224
+ * </SunglassesErrorBoundary>
225
+ * </SunglassesProvider>
226
+ * ```
227
+ */
228
+ declare function SunglassesErrorBoundary(props: SunglassesErrorBoundaryProps): React$1.ReactElement;
229
+
230
+ export { SunglassesErrorBoundary, type SunglassesErrorBoundaryProps, SunglassesProvider, type SunglassesProviderProps, captureDeepLinkUtmParams, useExpoRouterScreenTracking, useExpoRouterUtmCapture, useLinkingUtmCapture, useNavigationScreenTracking, useSunglasses };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,23 @@
1
1
  import React$1 from 'react';
2
- import { ISunglassesClient, ScreenTrackingOptions } from '@drakkar.software/sunglasses-core';
3
- export { ConsentStatus, ISunglassesClient, ScreenTrackingOptions, SunglassesConfig, SunglassesCore, SunglassesEvent } from '@drakkar.software/sunglasses-core';
2
+ import { ISunglassesClient, AutoCaptureErrorsOptions, ScreenTrackingOptions, CaptureExceptionOptions } from '@drakkar.software/sunglasses-core';
3
+ export { AutoCaptureErrorsOptions, CaptureExceptionOptions, ConsentStatus, ConsoleCaptureOptions, ISunglassesClient, ScreenTrackingOptions, SunglassesConfig, SunglassesCore, SunglassesEvent, captureException, patchConsole } from '@drakkar.software/sunglasses-core';
4
4
 
5
5
  interface SunglassesProviderProps {
6
6
  /** An initialized ISunglassesClient (from SunglassesCore.create()). */
7
7
  client: ISunglassesClient;
8
+ /**
9
+ * Automatically capture unhandled errors as `$error` events
10
+ * (`$error_handled: false`).
11
+ *
12
+ * - `true` installs a global `ErrorUtils` handler (the previous handler is
13
+ * preserved and still invoked).
14
+ * - An options object additionally lets you toggle `globalHandlers` and opt
15
+ * into `console` capture (`console.error` / `console.warn`), plus configure
16
+ * truncation / stack inclusion / ignore patterns.
17
+ *
18
+ * Default: off.
19
+ */
20
+ autoCaptureErrors?: boolean | AutoCaptureErrorsOptions;
8
21
  children: React$1.ReactNode;
9
22
  }
10
23
  /**
@@ -42,7 +55,7 @@ interface SunglassesProviderProps {
42
55
  * }
43
56
  * ```
44
57
  */
45
- declare function SunglassesProvider({ client, children, }: SunglassesProviderProps): React$1.ReactElement;
58
+ declare function SunglassesProvider({ client, autoCaptureErrors, children, }: SunglassesProviderProps): React$1.ReactElement;
46
59
 
47
60
  /**
48
61
  * Access the SunGlasses client from React context (React Native).
@@ -184,4 +197,34 @@ declare function useLinkingUtmCapture(client: ISunglassesClient): void;
184
197
  */
185
198
  declare function useExpoRouterUtmCapture(client: ISunglassesClient): void;
186
199
 
187
- export { SunglassesProvider, type SunglassesProviderProps, captureDeepLinkUtmParams, useExpoRouterScreenTracking, useExpoRouterUtmCapture, useLinkingUtmCapture, useNavigationScreenTracking, useSunglasses };
200
+ interface SunglassesErrorBoundaryProps {
201
+ /**
202
+ * SunGlasses client. Optional — defaults to the client provided by the
203
+ * nearest `<SunglassesProvider>`.
204
+ */
205
+ client?: ISunglassesClient;
206
+ /** Rendered when an error is caught. Defaults to rendering nothing. */
207
+ fallback?: React$1.ReactNode;
208
+ /** Error capture configuration forwarded to `captureException`. */
209
+ config?: CaptureExceptionOptions;
210
+ children: React$1.ReactNode;
211
+ }
212
+ /**
213
+ * React Native error boundary that captures render-phase errors as SunGlasses
214
+ * `$error` events (`$error_handled: true`).
215
+ *
216
+ * The client is read from the nearest `<SunglassesProvider>` by default; pass
217
+ * an explicit `client` prop to override.
218
+ *
219
+ * @example
220
+ * ```tsx
221
+ * <SunglassesProvider client={client}>
222
+ * <SunglassesErrorBoundary fallback={<ErrorScreen />}>
223
+ * <App />
224
+ * </SunglassesErrorBoundary>
225
+ * </SunglassesProvider>
226
+ * ```
227
+ */
228
+ declare function SunglassesErrorBoundary(props: SunglassesErrorBoundaryProps): React$1.ReactElement;
229
+
230
+ export { SunglassesErrorBoundary, type SunglassesErrorBoundaryProps, SunglassesProvider, type SunglassesProviderProps, captureDeepLinkUtmParams, useExpoRouterScreenTracking, useExpoRouterUtmCapture, useLinkingUtmCapture, useNavigationScreenTracking, useSunglasses };
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,14 +17,25 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var index_exports = {};
22
32
  __export(index_exports, {
23
- SunglassesCore: () => import_sunglasses_core.SunglassesCore,
33
+ SunglassesCore: () => import_sunglasses_core3.SunglassesCore,
34
+ SunglassesErrorBoundary: () => SunglassesErrorBoundary,
24
35
  SunglassesProvider: () => SunglassesProvider,
25
36
  captureDeepLinkUtmParams: () => captureDeepLinkUtmParams,
37
+ captureException: () => import_sunglasses_core3.captureException,
38
+ patchConsole: () => import_sunglasses_core3.patchConsole,
26
39
  useExpoRouterScreenTracking: () => useExpoRouterScreenTracking,
27
40
  useExpoRouterUtmCapture: () => useExpoRouterUtmCapture,
28
41
  useLinkingUtmCapture: () => useLinkingUtmCapture,
@@ -34,6 +47,7 @@ module.exports = __toCommonJS(index_exports);
34
47
  // src/SunglassesProvider.tsx
35
48
  var import_react2 = require("react");
36
49
  var import_react_native = require("react-native");
50
+ var import_sunglasses_core = require("@drakkar.software/sunglasses-core");
37
51
 
38
52
  // src/context.ts
39
53
  var import_react = require("react");
@@ -52,6 +66,7 @@ function useSunglasses() {
52
66
  var import_jsx_runtime = require("react/jsx-runtime");
53
67
  function SunglassesProvider({
54
68
  client,
69
+ autoCaptureErrors,
55
70
  children
56
71
  }) {
57
72
  (0, import_react2.useEffect)(() => {
@@ -60,6 +75,28 @@ function SunglassesProvider({
60
75
  });
61
76
  };
62
77
  }, [client]);
78
+ (0, import_react2.useEffect)(() => {
79
+ if (!autoCaptureErrors) return;
80
+ const options = typeof autoCaptureErrors === "object" ? autoCaptureErrors : {};
81
+ const cleanups = [];
82
+ if (options.globalHandlers !== false && typeof ErrorUtils !== "undefined" && ErrorUtils.setGlobalHandler) {
83
+ const previous = ErrorUtils.getGlobalHandler?.();
84
+ ErrorUtils.setGlobalHandler((error, isFatal) => {
85
+ (0, import_sunglasses_core.captureException)(client, error, { handled: false, ...options });
86
+ previous?.(error, isFatal);
87
+ });
88
+ cleanups.push(() => {
89
+ if (previous) ErrorUtils.setGlobalHandler?.(previous);
90
+ });
91
+ }
92
+ if (options.console) {
93
+ const consoleOptions = typeof options.console === "object" ? options.console : {};
94
+ cleanups.push((0, import_sunglasses_core.patchConsole)(client, consoleOptions));
95
+ }
96
+ return () => {
97
+ for (const cleanup of cleanups) cleanup();
98
+ };
99
+ }, [client, autoCaptureErrors]);
63
100
  (0, import_react2.useEffect)(() => {
64
101
  const subscription = import_react_native.AppState.addEventListener("change", (nextState) => {
65
102
  if (nextState === "background") {
@@ -198,13 +235,48 @@ function useExpoRouterUtmCapture(client) {
198
235
  }, [params, client]);
199
236
  }
200
237
 
238
+ // src/SunglassesErrorBoundary.tsx
239
+ var import_react7 = __toESM(require("react"));
240
+ var import_sunglasses_core2 = require("@drakkar.software/sunglasses-core");
241
+ var import_jsx_runtime2 = require("react/jsx-runtime");
242
+ var ErrorBoundaryInner = class extends import_react7.default.Component {
243
+ constructor() {
244
+ super(...arguments);
245
+ this.state = { hasError: false };
246
+ }
247
+ static getDerivedStateFromError() {
248
+ return { hasError: true };
249
+ }
250
+ componentDidCatch(error) {
251
+ const { client, config } = this.props;
252
+ (0, import_sunglasses_core2.captureException)(client, error, { handled: true, ...config });
253
+ }
254
+ render() {
255
+ if (this.state.hasError) return this.props.fallback ?? null;
256
+ return this.props.children;
257
+ }
258
+ };
259
+ function SunglassesErrorBoundary(props) {
260
+ const contextClient = (0, import_react7.useContext)(SunglassesContext);
261
+ const client = props.client ?? contextClient;
262
+ if (client === null) {
263
+ throw new Error(
264
+ "[SunGlasses] <SunglassesErrorBoundary> must be inside a <SunglassesProvider> or receive a `client` prop."
265
+ );
266
+ }
267
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ErrorBoundaryInner, { ...props, client });
268
+ }
269
+
201
270
  // src/index.ts
202
- var import_sunglasses_core = require("@drakkar.software/sunglasses-core");
271
+ var import_sunglasses_core3 = require("@drakkar.software/sunglasses-core");
203
272
  // Annotate the CommonJS export names for ESM import in node:
204
273
  0 && (module.exports = {
205
274
  SunglassesCore,
275
+ SunglassesErrorBoundary,
206
276
  SunglassesProvider,
207
277
  captureDeepLinkUtmParams,
278
+ captureException,
279
+ patchConsole,
208
280
  useExpoRouterScreenTracking,
209
281
  useExpoRouterUtmCapture,
210
282
  useLinkingUtmCapture,
package/dist/index.mjs CHANGED
@@ -8,6 +8,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
8
8
  // src/SunglassesProvider.tsx
9
9
  import { useEffect } from "react";
10
10
  import { AppState } from "react-native";
11
+ import { captureException, patchConsole } from "@drakkar.software/sunglasses-core";
11
12
 
12
13
  // src/context.ts
13
14
  import { createContext, useContext } from "react";
@@ -26,6 +27,7 @@ function useSunglasses() {
26
27
  import { jsx } from "react/jsx-runtime";
27
28
  function SunglassesProvider({
28
29
  client,
30
+ autoCaptureErrors,
29
31
  children
30
32
  }) {
31
33
  useEffect(() => {
@@ -34,6 +36,28 @@ function SunglassesProvider({
34
36
  });
35
37
  };
36
38
  }, [client]);
39
+ useEffect(() => {
40
+ if (!autoCaptureErrors) return;
41
+ const options = typeof autoCaptureErrors === "object" ? autoCaptureErrors : {};
42
+ const cleanups = [];
43
+ if (options.globalHandlers !== false && typeof ErrorUtils !== "undefined" && ErrorUtils.setGlobalHandler) {
44
+ const previous = ErrorUtils.getGlobalHandler?.();
45
+ ErrorUtils.setGlobalHandler((error, isFatal) => {
46
+ captureException(client, error, { handled: false, ...options });
47
+ previous?.(error, isFatal);
48
+ });
49
+ cleanups.push(() => {
50
+ if (previous) ErrorUtils.setGlobalHandler?.(previous);
51
+ });
52
+ }
53
+ if (options.console) {
54
+ const consoleOptions = typeof options.console === "object" ? options.console : {};
55
+ cleanups.push(patchConsole(client, consoleOptions));
56
+ }
57
+ return () => {
58
+ for (const cleanup of cleanups) cleanup();
59
+ };
60
+ }, [client, autoCaptureErrors]);
37
61
  useEffect(() => {
38
62
  const subscription = AppState.addEventListener("change", (nextState) => {
39
63
  if (nextState === "background") {
@@ -172,12 +196,47 @@ function useExpoRouterUtmCapture(client) {
172
196
  }, [params, client]);
173
197
  }
174
198
 
199
+ // src/SunglassesErrorBoundary.tsx
200
+ import React2, { useContext as useContext2 } from "react";
201
+ import { captureException as captureException2 } from "@drakkar.software/sunglasses-core";
202
+ import { jsx as jsx2 } from "react/jsx-runtime";
203
+ var ErrorBoundaryInner = class extends React2.Component {
204
+ constructor() {
205
+ super(...arguments);
206
+ this.state = { hasError: false };
207
+ }
208
+ static getDerivedStateFromError() {
209
+ return { hasError: true };
210
+ }
211
+ componentDidCatch(error) {
212
+ const { client, config } = this.props;
213
+ captureException2(client, error, { handled: true, ...config });
214
+ }
215
+ render() {
216
+ if (this.state.hasError) return this.props.fallback ?? null;
217
+ return this.props.children;
218
+ }
219
+ };
220
+ function SunglassesErrorBoundary(props) {
221
+ const contextClient = useContext2(SunglassesContext);
222
+ const client = props.client ?? contextClient;
223
+ if (client === null) {
224
+ throw new Error(
225
+ "[SunGlasses] <SunglassesErrorBoundary> must be inside a <SunglassesProvider> or receive a `client` prop."
226
+ );
227
+ }
228
+ return /* @__PURE__ */ jsx2(ErrorBoundaryInner, { ...props, client });
229
+ }
230
+
175
231
  // src/index.ts
176
- import { SunglassesCore } from "@drakkar.software/sunglasses-core";
232
+ import { SunglassesCore, captureException as captureException3, patchConsole as patchConsole2 } from "@drakkar.software/sunglasses-core";
177
233
  export {
178
234
  SunglassesCore,
235
+ SunglassesErrorBoundary,
179
236
  SunglassesProvider,
180
237
  captureDeepLinkUtmParams,
238
+ captureException3 as captureException,
239
+ patchConsole2 as patchConsole,
181
240
  useExpoRouterScreenTracking,
182
241
  useExpoRouterUtmCapture,
183
242
  useLinkingUtmCapture,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drakkar.software/sunglasses-react-native",
3
- "version": "0.8.0",
3
+ "version": "0.11.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.8.0"
19
+ "@drakkar.software/sunglasses-core": "0.11.0"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "expo-router": ">=3.0.0",