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