@drakkar.software/sunglasses-react 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,12 +1,25 @@
1
1
  import React from 'react';
2
- import { ISunglassesClient, ScreenTrackingOptions, ConsentStatus } from '@drakkar.software/sunglasses-core';
3
- export { ConsentStatus, ISunglassesClient, ScreenTrackingOptions, SunglassesConfig, SunglassesCore, SunglassesEvent } from '@drakkar.software/sunglasses-core';
2
+ import { ISunglassesClient, ScreenTrackingOptions, AutoCaptureErrorsOptions, ConsentStatus, 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
8
  /** Optional screen tracking configuration. */
9
9
  screenTracking?: ScreenTrackingOptions;
10
+ /**
11
+ * Automatically capture unhandled errors as `$error` events
12
+ * (`$error_handled: false`).
13
+ *
14
+ * - `true` installs the global handlers for `window` `'error'` and
15
+ * `'unhandledrejection'`.
16
+ * - An options object additionally lets you toggle `globalHandlers` and opt
17
+ * into `console` capture (`console.error` / `console.warn`), plus configure
18
+ * truncation / stack inclusion / ignore patterns.
19
+ *
20
+ * Default: off.
21
+ */
22
+ autoCaptureErrors?: boolean | AutoCaptureErrorsOptions;
10
23
  children: React.ReactNode;
11
24
  }
12
25
  /**
@@ -28,7 +41,7 @@ interface SunglassesProviderProps {
28
41
  * }
29
42
  * ```
30
43
  */
31
- declare function SunglassesProvider({ client, screenTracking, children, }: SunglassesProviderProps): React.ReactElement;
44
+ declare function SunglassesProvider({ client, screenTracking, autoCaptureErrors, children, }: SunglassesProviderProps): React.ReactElement;
32
45
 
33
46
  /**
34
47
  * Read UTM attribution parameters from the current URL and register them as
@@ -119,4 +132,34 @@ declare function useCapture(): (eventName: string, properties?: Record<string, u
119
132
  */
120
133
  declare function useConsentStatus(): ConsentStatus;
121
134
 
122
- export { SunglassesProvider, type SunglassesProviderProps, captureUtmParams, useCapture, useConsentStatus, useScreenTracking, useSunglasses };
135
+ interface SunglassesErrorBoundaryProps {
136
+ /**
137
+ * SunGlasses client. Optional — defaults to the client provided by the
138
+ * nearest `<SunglassesProvider>`.
139
+ */
140
+ client?: ISunglassesClient;
141
+ /** Rendered when an error is caught. Defaults to rendering nothing. */
142
+ fallback?: React.ReactNode;
143
+ /** Error capture configuration forwarded to `captureException`. */
144
+ config?: CaptureExceptionOptions;
145
+ children: React.ReactNode;
146
+ }
147
+ /**
148
+ * React error boundary that captures render-phase errors as SunGlasses
149
+ * `$error` events (`$error_handled: true`).
150
+ *
151
+ * The client is read from the nearest `<SunglassesProvider>` by default; pass
152
+ * an explicit `client` prop to override (e.g. when used outside the provider).
153
+ *
154
+ * @example
155
+ * ```tsx
156
+ * <SunglassesProvider client={client}>
157
+ * <SunglassesErrorBoundary fallback={<ErrorPage />}>
158
+ * <App />
159
+ * </SunglassesErrorBoundary>
160
+ * </SunglassesProvider>
161
+ * ```
162
+ */
163
+ declare function SunglassesErrorBoundary(props: SunglassesErrorBoundaryProps): React.ReactElement;
164
+
165
+ export { SunglassesErrorBoundary, type SunglassesErrorBoundaryProps, SunglassesProvider, type SunglassesProviderProps, captureUtmParams, useCapture, useConsentStatus, useScreenTracking, useSunglasses };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,25 @@
1
1
  import React from 'react';
2
- import { ISunglassesClient, ScreenTrackingOptions, ConsentStatus } from '@drakkar.software/sunglasses-core';
3
- export { ConsentStatus, ISunglassesClient, ScreenTrackingOptions, SunglassesConfig, SunglassesCore, SunglassesEvent } from '@drakkar.software/sunglasses-core';
2
+ import { ISunglassesClient, ScreenTrackingOptions, AutoCaptureErrorsOptions, ConsentStatus, 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
8
  /** Optional screen tracking configuration. */
9
9
  screenTracking?: ScreenTrackingOptions;
10
+ /**
11
+ * Automatically capture unhandled errors as `$error` events
12
+ * (`$error_handled: false`).
13
+ *
14
+ * - `true` installs the global handlers for `window` `'error'` and
15
+ * `'unhandledrejection'`.
16
+ * - An options object additionally lets you toggle `globalHandlers` and opt
17
+ * into `console` capture (`console.error` / `console.warn`), plus configure
18
+ * truncation / stack inclusion / ignore patterns.
19
+ *
20
+ * Default: off.
21
+ */
22
+ autoCaptureErrors?: boolean | AutoCaptureErrorsOptions;
10
23
  children: React.ReactNode;
11
24
  }
12
25
  /**
@@ -28,7 +41,7 @@ interface SunglassesProviderProps {
28
41
  * }
29
42
  * ```
30
43
  */
31
- declare function SunglassesProvider({ client, screenTracking, children, }: SunglassesProviderProps): React.ReactElement;
44
+ declare function SunglassesProvider({ client, screenTracking, autoCaptureErrors, children, }: SunglassesProviderProps): React.ReactElement;
32
45
 
33
46
  /**
34
47
  * Read UTM attribution parameters from the current URL and register them as
@@ -119,4 +132,34 @@ declare function useCapture(): (eventName: string, properties?: Record<string, u
119
132
  */
120
133
  declare function useConsentStatus(): ConsentStatus;
121
134
 
122
- export { SunglassesProvider, type SunglassesProviderProps, captureUtmParams, useCapture, useConsentStatus, useScreenTracking, useSunglasses };
135
+ interface SunglassesErrorBoundaryProps {
136
+ /**
137
+ * SunGlasses client. Optional — defaults to the client provided by the
138
+ * nearest `<SunglassesProvider>`.
139
+ */
140
+ client?: ISunglassesClient;
141
+ /** Rendered when an error is caught. Defaults to rendering nothing. */
142
+ fallback?: React.ReactNode;
143
+ /** Error capture configuration forwarded to `captureException`. */
144
+ config?: CaptureExceptionOptions;
145
+ children: React.ReactNode;
146
+ }
147
+ /**
148
+ * React error boundary that captures render-phase errors as SunGlasses
149
+ * `$error` events (`$error_handled: true`).
150
+ *
151
+ * The client is read from the nearest `<SunglassesProvider>` by default; pass
152
+ * an explicit `client` prop to override (e.g. when used outside the provider).
153
+ *
154
+ * @example
155
+ * ```tsx
156
+ * <SunglassesProvider client={client}>
157
+ * <SunglassesErrorBoundary fallback={<ErrorPage />}>
158
+ * <App />
159
+ * </SunglassesErrorBoundary>
160
+ * </SunglassesProvider>
161
+ * ```
162
+ */
163
+ declare function SunglassesErrorBoundary(props: SunglassesErrorBoundaryProps): React.ReactElement;
164
+
165
+ export { SunglassesErrorBoundary, type SunglassesErrorBoundaryProps, SunglassesProvider, type SunglassesProviderProps, captureUtmParams, useCapture, useConsentStatus, useScreenTracking, 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,
36
+ captureException: () => import_sunglasses_core3.captureException,
25
37
  captureUtmParams: () => captureUtmParams,
38
+ patchConsole: () => import_sunglasses_core3.patchConsole,
26
39
  useCapture: () => useCapture,
27
40
  useConsentStatus: () => useConsentStatus,
28
41
  useScreenTracking: () => useScreenTracking,
@@ -32,6 +45,7 @@ module.exports = __toCommonJS(index_exports);
32
45
 
33
46
  // src/SunglassesProvider.tsx
34
47
  var import_react3 = require("react");
48
+ var import_sunglasses_core = require("@drakkar.software/sunglasses-core");
35
49
 
36
50
  // src/context.ts
37
51
  var import_react = require("react");
@@ -108,6 +122,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
108
122
  function SunglassesProvider({
109
123
  client,
110
124
  screenTracking,
125
+ autoCaptureErrors,
111
126
  children
112
127
  }) {
113
128
  (0, import_react3.useEffect)(() => {
@@ -116,6 +131,32 @@ function SunglassesProvider({
116
131
  });
117
132
  };
118
133
  }, [client]);
134
+ (0, import_react3.useEffect)(() => {
135
+ if (!autoCaptureErrors) return;
136
+ const options = typeof autoCaptureErrors === "object" ? autoCaptureErrors : {};
137
+ const cleanups = [];
138
+ if (options.globalHandlers !== false && typeof window !== "undefined") {
139
+ const onError = (event) => {
140
+ (0, import_sunglasses_core.captureException)(client, event.error ?? event.message, { handled: false, ...options });
141
+ };
142
+ const onRejection = (event) => {
143
+ (0, import_sunglasses_core.captureException)(client, event.reason, { handled: false, ...options });
144
+ };
145
+ window.addEventListener("error", onError);
146
+ window.addEventListener("unhandledrejection", onRejection);
147
+ cleanups.push(() => {
148
+ window.removeEventListener("error", onError);
149
+ window.removeEventListener("unhandledrejection", onRejection);
150
+ });
151
+ }
152
+ if (options.console) {
153
+ const consoleOptions = typeof options.console === "object" ? options.console : {};
154
+ cleanups.push((0, import_sunglasses_core.patchConsole)(client, consoleOptions));
155
+ }
156
+ return () => {
157
+ for (const cleanup of cleanups) cleanup();
158
+ };
159
+ }, [client, autoCaptureErrors]);
119
160
  (0, import_react3.useEffect)(() => {
120
161
  if (typeof document === "undefined") return;
121
162
  const handleVisibilityChange = () => {
@@ -177,13 +218,48 @@ function useConsentStatus() {
177
218
  return client.getConsentStatus();
178
219
  }
179
220
 
221
+ // src/SunglassesErrorBoundary.tsx
222
+ var import_react5 = __toESM(require("react"));
223
+ var import_sunglasses_core2 = require("@drakkar.software/sunglasses-core");
224
+ var import_jsx_runtime2 = require("react/jsx-runtime");
225
+ var ErrorBoundaryInner = class extends import_react5.default.Component {
226
+ constructor() {
227
+ super(...arguments);
228
+ this.state = { hasError: false };
229
+ }
230
+ static getDerivedStateFromError() {
231
+ return { hasError: true };
232
+ }
233
+ componentDidCatch(error) {
234
+ const { client, config } = this.props;
235
+ (0, import_sunglasses_core2.captureException)(client, error, { handled: true, ...config });
236
+ }
237
+ render() {
238
+ if (this.state.hasError) return this.props.fallback ?? null;
239
+ return this.props.children;
240
+ }
241
+ };
242
+ function SunglassesErrorBoundary(props) {
243
+ const contextClient = (0, import_react5.useContext)(SunglassesContext);
244
+ const client = props.client ?? contextClient;
245
+ if (client === null) {
246
+ throw new Error(
247
+ "[SunGlasses] <SunglassesErrorBoundary> must be inside a <SunglassesProvider> or receive a `client` prop."
248
+ );
249
+ }
250
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ErrorBoundaryInner, { ...props, client });
251
+ }
252
+
180
253
  // src/index.ts
181
- var import_sunglasses_core = require("@drakkar.software/sunglasses-core");
254
+ var import_sunglasses_core3 = require("@drakkar.software/sunglasses-core");
182
255
  // Annotate the CommonJS export names for ESM import in node:
183
256
  0 && (module.exports = {
184
257
  SunglassesCore,
258
+ SunglassesErrorBoundary,
185
259
  SunglassesProvider,
260
+ captureException,
186
261
  captureUtmParams,
262
+ patchConsole,
187
263
  useCapture,
188
264
  useConsentStatus,
189
265
  useScreenTracking,
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/SunglassesProvider.tsx
2
2
  import { useEffect as useEffect2 } from "react";
3
+ import { captureException, patchConsole } from "@drakkar.software/sunglasses-core";
3
4
 
4
5
  // src/context.ts
5
6
  import { createContext, useContext } from "react";
@@ -76,6 +77,7 @@ import { jsx } from "react/jsx-runtime";
76
77
  function SunglassesProvider({
77
78
  client,
78
79
  screenTracking,
80
+ autoCaptureErrors,
79
81
  children
80
82
  }) {
81
83
  useEffect2(() => {
@@ -84,6 +86,32 @@ function SunglassesProvider({
84
86
  });
85
87
  };
86
88
  }, [client]);
89
+ useEffect2(() => {
90
+ if (!autoCaptureErrors) return;
91
+ const options = typeof autoCaptureErrors === "object" ? autoCaptureErrors : {};
92
+ const cleanups = [];
93
+ if (options.globalHandlers !== false && typeof window !== "undefined") {
94
+ const onError = (event) => {
95
+ captureException(client, event.error ?? event.message, { handled: false, ...options });
96
+ };
97
+ const onRejection = (event) => {
98
+ captureException(client, event.reason, { handled: false, ...options });
99
+ };
100
+ window.addEventListener("error", onError);
101
+ window.addEventListener("unhandledrejection", onRejection);
102
+ cleanups.push(() => {
103
+ window.removeEventListener("error", onError);
104
+ window.removeEventListener("unhandledrejection", onRejection);
105
+ });
106
+ }
107
+ if (options.console) {
108
+ const consoleOptions = typeof options.console === "object" ? options.console : {};
109
+ cleanups.push(patchConsole(client, consoleOptions));
110
+ }
111
+ return () => {
112
+ for (const cleanup of cleanups) cleanup();
113
+ };
114
+ }, [client, autoCaptureErrors]);
87
115
  useEffect2(() => {
88
116
  if (typeof document === "undefined") return;
89
117
  const handleVisibilityChange = () => {
@@ -145,12 +173,47 @@ function useConsentStatus() {
145
173
  return client.getConsentStatus();
146
174
  }
147
175
 
176
+ // src/SunglassesErrorBoundary.tsx
177
+ import React2, { useContext as useContext2 } from "react";
178
+ import { captureException as captureException2 } from "@drakkar.software/sunglasses-core";
179
+ import { jsx as jsx2 } from "react/jsx-runtime";
180
+ var ErrorBoundaryInner = class extends React2.Component {
181
+ constructor() {
182
+ super(...arguments);
183
+ this.state = { hasError: false };
184
+ }
185
+ static getDerivedStateFromError() {
186
+ return { hasError: true };
187
+ }
188
+ componentDidCatch(error) {
189
+ const { client, config } = this.props;
190
+ captureException2(client, error, { handled: true, ...config });
191
+ }
192
+ render() {
193
+ if (this.state.hasError) return this.props.fallback ?? null;
194
+ return this.props.children;
195
+ }
196
+ };
197
+ function SunglassesErrorBoundary(props) {
198
+ const contextClient = useContext2(SunglassesContext);
199
+ const client = props.client ?? contextClient;
200
+ if (client === null) {
201
+ throw new Error(
202
+ "[SunGlasses] <SunglassesErrorBoundary> must be inside a <SunglassesProvider> or receive a `client` prop."
203
+ );
204
+ }
205
+ return /* @__PURE__ */ jsx2(ErrorBoundaryInner, { ...props, client });
206
+ }
207
+
148
208
  // src/index.ts
149
- import { SunglassesCore } from "@drakkar.software/sunglasses-core";
209
+ import { SunglassesCore, captureException as captureException3, patchConsole as patchConsole2 } from "@drakkar.software/sunglasses-core";
150
210
  export {
151
211
  SunglassesCore,
212
+ SunglassesErrorBoundary,
152
213
  SunglassesProvider,
214
+ captureException3 as captureException,
153
215
  captureUtmParams,
216
+ patchConsole2 as patchConsole,
154
217
  useCapture,
155
218
  useConsentStatus,
156
219
  useScreenTracking,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drakkar.software/sunglasses-react",
3
- "version": "0.8.0",
3
+ "version": "0.11.0",
4
4
  "description": "React (web) 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
  "react": ">=18.0.0"