@hawk.so/nextjs 0.0.0-stage → 1.1.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.
@@ -0,0 +1,315 @@
1
+ /// <reference path="../global.d.ts" />
2
+ import { HawkInitialSettings } from '@hawk.so/browser';
3
+ import { CatcherMessagePayload, EventContext, AffectedUser } from '@hawk.so/types';
4
+ export { AffectedUser, EventContext } from '@hawk.so/types';
5
+ import { BreadcrumbsAPI } from '@hawk.so/core';
6
+ export { BreadcrumbsAPI } from '@hawk.so/core';
7
+ import { Component, ReactNode, ErrorInfo, ReactElement } from 'react';
8
+
9
+ /**
10
+ * Event passed to `beforeSend`: from the browser or from the server
11
+ */
12
+ type HawkEvent = CatcherMessagePayload<'errors/javascript'> | CatcherMessagePayload<'errors/nodejs'>;
13
+ /**
14
+ * Options of `init()`. The same options are accepted in the browser and on the server,
15
+ * options of the browser catcher are ignored on the server
16
+ */
17
+ interface HawkInitOptions extends Pick<HawkInitialSettings, 'user' | 'debug' | 'breadcrumbs' | 'consoleTracking' | 'issues' | 'reconnectionTimeout' | 'transport'> {
18
+ /**
19
+ * Hawk Integration Token. Default is the NEXT_PUBLIC_HAWK_TOKEN environment variable,
20
+ * on the server HAWK_TOKEN is checked first
21
+ */
22
+ token?: string;
23
+ /**
24
+ * Release id. Default is `process.env.HAWK_RELEASE` set by `withHawkConfig`
25
+ */
26
+ release?: string;
27
+ /**
28
+ * Collector endpoint overwrite: WebSocket URL in the browser, HTTP URL on the server
29
+ */
30
+ collectorEndpoint?: string;
31
+ /**
32
+ * Data sent with every event
33
+ */
34
+ context?: EventContext;
35
+ /**
36
+ * Filters or modifies events before sending. Return the event to send it or `false` to drop it
37
+ */
38
+ beforeSend?: (event: HawkEvent) => HawkEvent | false | void;
39
+ /**
40
+ * Disables catching of uncaught errors and unhandled rejections: `window` handlers in the browser,
41
+ * `process` handlers in Node.js
42
+ */
43
+ disableGlobalErrorsHandling?: boolean;
44
+ }
45
+
46
+ /**
47
+ * Request passed by Next.js to `onRequestError`
48
+ */
49
+ interface RequestErrorRequest {
50
+ /**
51
+ * Request path with the query string
52
+ */
53
+ path: string;
54
+ /**
55
+ * HTTP method
56
+ */
57
+ method: string;
58
+ /**
59
+ * Request headers
60
+ */
61
+ headers: Record<string, string | string[] | undefined>;
62
+ }
63
+ /**
64
+ * Context passed by Next.js to `onRequestError`. Fields differ between Next.js versions, so they are loose strings
65
+ */
66
+ interface RequestErrorContext {
67
+ /**
68
+ * `App Router` or `Pages Router`
69
+ */
70
+ routerKind: string;
71
+ /**
72
+ * Route file path, e.g. `/blog/[slug]`
73
+ */
74
+ routePath: string;
75
+ /**
76
+ * `render`, `route`, `action`, `middleware` or `proxy`
77
+ */
78
+ routeType: string;
79
+ /**
80
+ * Rendering phase of the App Router
81
+ */
82
+ renderSource?: string;
83
+ /**
84
+ * Revalidation reason: `on-demand` or `stale`
85
+ */
86
+ revalidateReason?: string;
87
+ /**
88
+ * Render type of the App Router in Next.js 15: `dynamic` or `dynamic-resume`
89
+ */
90
+ renderType?: string;
91
+ }
92
+ /**
93
+ * Next.js data sent with events in `addons.nextjs`
94
+ */
95
+ interface NextjsAddons {
96
+ /**
97
+ * Where the error happened: `nodejs`, `edge` or `browser`
98
+ */
99
+ runtime?: string;
100
+ /**
101
+ * Error page that caught the error: `error`, `global-error` or `boundary`
102
+ */
103
+ boundary?: string;
104
+ /**
105
+ * React component stack of the error caught by `HawkErrorBoundary`
106
+ */
107
+ componentStack?: string;
108
+ /**
109
+ * Digest of the server error. The same digest is shown on the error page in the browser
110
+ */
111
+ digest?: string;
112
+ /**
113
+ * `App Router` or `Pages Router`
114
+ */
115
+ routerKind?: string;
116
+ /**
117
+ * Route file path, e.g. `/blog/[slug]`
118
+ */
119
+ routePath?: string;
120
+ /**
121
+ * `render`, `route`, `action`, `middleware` or `proxy`
122
+ */
123
+ routeType?: string;
124
+ /**
125
+ * Rendering phase of the App Router
126
+ */
127
+ renderSource?: string;
128
+ /**
129
+ * Revalidation reason
130
+ */
131
+ revalidateReason?: string;
132
+ /**
133
+ * Render type of the App Router
134
+ */
135
+ renderType?: string;
136
+ /**
137
+ * HTTP method
138
+ */
139
+ method?: string;
140
+ /**
141
+ * Request path with the query string
142
+ */
143
+ path?: string;
144
+ /**
145
+ * Request headers that don't contain credentials
146
+ */
147
+ headers?: Record<string, string>;
148
+ }
149
+
150
+ /**
151
+ * Sends the error or message to Hawk. Next.js errors of `redirect()` and `notFound()` are skipped
152
+ * @param error - error or message
153
+ * @param context - data sent with the event
154
+ * @param user - user affected by the error, used on the server only. In the browser use `setUser()`
155
+ */
156
+ declare function send(error: unknown, context?: EventContext, user?: AffectedUser): void;
157
+ /**
158
+ * Sets the user sent with every event in the browser.
159
+ * Ignored on the server: it handles requests of many users at once, so pass the user to `send()` there
160
+ * @param _user - current user
161
+ */
162
+ declare function setUser(_user: AffectedUser): void;
163
+ /**
164
+ * Removes the user set with `setUser()`. Does nothing on the server
165
+ */
166
+ declare function clearUser(): void;
167
+ /**
168
+ * Sets data sent with every event. On the server it is shared by all requests of the process
169
+ * @param context - data to send
170
+ */
171
+ declare function setContext(context: EventContext | undefined): void;
172
+ /**
173
+ * Breadcrumbs sent with the events: actions that happened before the error.
174
+ * Collected in the browser only: on the server requests of different users would be mixed
175
+ */
176
+ declare const breadcrumbs: BreadcrumbsAPI;
177
+ /**
178
+ * Waits for the events in progress, e.g. before a serverless function is frozen.
179
+ * `onRequestError` already waits for its events. In the browser resolves at once
180
+ * @param timeout - max time to wait, in milliseconds
181
+ * @returns false when the timeout is reached or the catcher is not created
182
+ */
183
+ declare function flush(timeout?: number): Promise<boolean>;
184
+ /**
185
+ * Sends errors of server components, route handlers, server actions and middleware, on the server only.
186
+ * Export it from `instrumentation.ts`: `export const onRequestError = Hawk.onRequestError`
187
+ * @param error - caught error
188
+ * @param request - failed request
189
+ * @param context - route data
190
+ */
191
+ declare function onRequestError(error: unknown, request: Readonly<RequestErrorRequest>, context: Readonly<RequestErrorContext>): Promise<void>;
192
+ /**
193
+ * Adds a breadcrumb for every navigation of the App Router, in the browser only.
194
+ * Export it from `instrumentation-client.ts`: `export const onRouterTransitionStart = Hawk.onRouterTransitionStart`
195
+ * @param _url - target URL
196
+ * @param _navigationType - `push`, `replace` or `traverse`
197
+ */
198
+ declare function onRouterTransitionStart(_url: string, _navigationType: string): void;
199
+
200
+ /**
201
+ * Error passed by Next.js to the error pages
202
+ */
203
+ type ErrorWithDigest = Error & {
204
+ /**
205
+ * Digest of the server error. Server errors have a generic message in production
206
+ */
207
+ digest?: string;
208
+ };
209
+ /**
210
+ * Props passed by Next.js to `error.tsx` and `global-error.tsx`
211
+ */
212
+ interface HawkErrorPageProps {
213
+ /**
214
+ * Caught error
215
+ */
216
+ error: ErrorWithDigest;
217
+ /**
218
+ * Renders the segment again
219
+ */
220
+ reset?: () => void;
221
+ }
222
+ /**
223
+ * Props passed to the fallback of `HawkErrorBoundary`
224
+ */
225
+ interface HawkErrorBoundaryFallbackProps {
226
+ /**
227
+ * Caught error
228
+ */
229
+ error: unknown;
230
+ /**
231
+ * Renders the children again
232
+ */
233
+ reset: () => void;
234
+ }
235
+ /**
236
+ * Content, fallback and error callback of `HawkErrorBoundary`
237
+ */
238
+ interface HawkErrorBoundaryProps {
239
+ /**
240
+ * Content to protect
241
+ */
242
+ children?: ReactNode;
243
+ /**
244
+ * Shown instead of the children after an error
245
+ */
246
+ fallback?: ReactNode | ((props: HawkErrorBoundaryFallbackProps) => ReactNode);
247
+ /**
248
+ * Called after the error is sent
249
+ */
250
+ onError?: (error: unknown, info: ErrorInfo) => void;
251
+ }
252
+ /**
253
+ * Whether `HawkErrorBoundary` shows the fallback, and the error it caught
254
+ */
255
+ interface HawkErrorBoundaryState {
256
+ /**
257
+ * Whether an error is caught
258
+ */
259
+ hasError: boolean;
260
+ /**
261
+ * Caught error
262
+ */
263
+ error: unknown;
264
+ }
265
+ /**
266
+ * Sends the error shown by `error.tsx` to Hawk.
267
+ * Next.js only logs errors caught by error boundaries, so the catcher doesn't get them otherwise
268
+ * @param error - error passed to the error page
269
+ */
270
+ declare function useHawkError(error: unknown): void;
271
+ /**
272
+ * Ready `app/global-error.tsx`: sends the error and shows a minimal error page.
273
+ * Use it as `export { HawkGlobalError as default } from '@hawk.so/nextjs'`
274
+ * @param props - props passed by Next.js
275
+ */
276
+ declare function HawkGlobalError({ error, reset }: HawkErrorPageProps): ReactElement;
277
+ /**
278
+ * Error boundary that sends errors of its children to Hawk and shows the fallback.
279
+ * Errors Next.js uses for `redirect()` and `notFound()` are passed to the Next.js boundaries
280
+ */
281
+ declare class HawkErrorBoundary extends Component<HawkErrorBoundaryProps, HawkErrorBoundaryState> {
282
+ /**
283
+ * Initial state
284
+ */
285
+ state: HawkErrorBoundaryState;
286
+ /**
287
+ * Shows the fallback after an error
288
+ * @param error - caught error
289
+ */
290
+ static getDerivedStateFromError(error: unknown): HawkErrorBoundaryState;
291
+ /**
292
+ * Sends the caught error
293
+ * @param error - caught error
294
+ * @param info - component stack
295
+ */
296
+ componentDidCatch(error: unknown, info: ErrorInfo): void;
297
+ /**
298
+ * Renders the children again
299
+ */
300
+ reset: () => void;
301
+ /**
302
+ * Renders the children or the fallback
303
+ */
304
+ render(): ReactNode;
305
+ }
306
+
307
+ /**
308
+ * Initializes Hawk. Call it in `instrumentation-client.ts` for the browser
309
+ * and in `register()` of `instrumentation.ts` for the server
310
+ * @param options - token, release and other options
311
+ */
312
+ declare function init(options?: HawkInitOptions): void;
313
+
314
+ export { HawkErrorBoundary, HawkGlobalError, breadcrumbs, clearUser, flush, init, onRequestError, onRouterTransitionStart, send, setContext, setUser, useHawkError };
315
+ export type { HawkErrorBoundaryFallbackProps, HawkErrorBoundaryProps, HawkErrorPageProps, HawkEvent, HawkInitOptions, NextjsAddons, RequestErrorContext, RequestErrorRequest };
package/dist/react.cjs ADDED
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/react/index.tsx
22
+ var react_exports = {};
23
+ __export(react_exports, {
24
+ HawkErrorBoundary: () => HawkErrorBoundary,
25
+ HawkGlobalError: () => HawkGlobalError,
26
+ useHawkError: () => useHawkError
27
+ });
28
+ module.exports = __toCommonJS(react_exports);
29
+ var import_react = require("react");
30
+
31
+ // src/common/carrier.ts
32
+ var CARRIER_KEY = /* @__PURE__ */ Symbol.for("hawk.nextjs");
33
+ function getCarrier() {
34
+ const store = globalThis;
35
+ store[CARRIER_KEY] ??= {};
36
+ return store[CARRIER_KEY];
37
+ }
38
+
39
+ // src/common/control-flow.ts
40
+ var CONTROL_FLOW_DIGEST_PREFIXES = [
41
+ "NEXT_REDIRECT",
42
+ "NEXT_HTTP_ERROR_FALLBACK;",
43
+ "NEXT_NOT_FOUND",
44
+ "BAILOUT_TO_CLIENT_SIDE_RENDERING",
45
+ "DYNAMIC_SERVER_USAGE",
46
+ "NEXT_PRERENDER_INTERRUPTED",
47
+ "HANGING_PROMISE_REJECTION"
48
+ ];
49
+ var STATIC_GEN_BAILOUT_CODE = "NEXT_STATIC_GEN_BAILOUT";
50
+ var REACT_POSTPONE_TYPE = /* @__PURE__ */ Symbol.for("react.postpone");
51
+ var MAX_CAUSE_DEPTH = 5;
52
+ function isControlFlowDigest(value) {
53
+ return typeof value === "string" && CONTROL_FLOW_DIGEST_PREFIXES.some((prefix) => value.startsWith(prefix));
54
+ }
55
+ function isNextControlFlowError(error) {
56
+ let current = error;
57
+ for (let depth = 0; depth < MAX_CAUSE_DEPTH; depth++) {
58
+ if (typeof current !== "object" || current === null) {
59
+ return false;
60
+ }
61
+ const value = current;
62
+ if (isControlFlowDigest(value.digest) || isControlFlowDigest(value.message) || value.code === STATIC_GEN_BAILOUT_CODE || value.$$typeof === REACT_POSTPONE_TYPE) {
63
+ return true;
64
+ }
65
+ current = value.cause;
66
+ }
67
+ return false;
68
+ }
69
+ function getDigest(error) {
70
+ if (typeof error === "object" && error !== null) {
71
+ const { digest } = error;
72
+ if (typeof digest === "string" && digest !== "") {
73
+ return digest;
74
+ }
75
+ }
76
+ return void 0;
77
+ }
78
+
79
+ // src/react/index.tsx
80
+ var import_jsx_runtime = require("react/jsx-runtime");
81
+ function captureBoundaryError(error, boundary, componentStack) {
82
+ if (isNextControlFlowError(error) || getDigest(error) !== void 0) {
83
+ return;
84
+ }
85
+ getCarrier().capture?.(error, {
86
+ boundary,
87
+ ...typeof componentStack === "string" ? { componentStack } : {}
88
+ });
89
+ }
90
+ function useHawkError(error) {
91
+ (0, import_react.useEffect)(() => {
92
+ captureBoundaryError(error, "error");
93
+ }, [error]);
94
+ }
95
+ var globalErrorStyles = {
96
+ container: {
97
+ fontFamily: "system-ui, sans-serif",
98
+ minHeight: "100vh",
99
+ display: "flex",
100
+ flexDirection: "column",
101
+ alignItems: "center",
102
+ justifyContent: "center",
103
+ gap: 16,
104
+ textAlign: "center"
105
+ },
106
+ title: {
107
+ fontSize: 14,
108
+ fontWeight: 400,
109
+ margin: 0
110
+ },
111
+ digest: {
112
+ fontSize: 12,
113
+ opacity: 0.6,
114
+ margin: 0
115
+ },
116
+ button: {
117
+ fontSize: 14,
118
+ padding: "6px 14px",
119
+ cursor: "pointer"
120
+ }
121
+ };
122
+ function HawkGlobalError({ error, reset }) {
123
+ (0, import_react.useEffect)(() => {
124
+ captureBoundaryError(error, "global-error");
125
+ }, [error]);
126
+ const side = error.digest === void 0 ? "client" : "server";
127
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("html", { lang: "en", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("body", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", { style: globalErrorStyles.container, children: [
128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h2", { style: globalErrorStyles.title, children: [
129
+ "Application error: a ",
130
+ side,
131
+ "-side exception has occurred."
132
+ ] }),
133
+ error.digest !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: globalErrorStyles.digest, children: [
134
+ "Digest: ",
135
+ error.digest
136
+ ] }),
137
+ reset !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: globalErrorStyles.button, onClick: reset, children: "Try again" })
138
+ ] }) }) });
139
+ }
140
+ var HawkErrorBoundary = class extends import_react.Component {
141
+ /**
142
+ * Initial state
143
+ */
144
+ state = {
145
+ hasError: false,
146
+ error: null
147
+ };
148
+ /**
149
+ * Shows the fallback after an error
150
+ * @param error - caught error
151
+ */
152
+ static getDerivedStateFromError(error) {
153
+ return {
154
+ hasError: true,
155
+ error
156
+ };
157
+ }
158
+ /**
159
+ * Sends the caught error
160
+ * @param error - caught error
161
+ * @param info - component stack
162
+ */
163
+ componentDidCatch(error, info) {
164
+ if (isNextControlFlowError(error)) {
165
+ return;
166
+ }
167
+ captureBoundaryError(error, "boundary", info.componentStack);
168
+ this.props.onError?.(error, info);
169
+ }
170
+ /**
171
+ * Renders the children again
172
+ */
173
+ reset = () => {
174
+ this.setState({
175
+ hasError: false,
176
+ error: null
177
+ });
178
+ };
179
+ /**
180
+ * Renders the children or the fallback
181
+ */
182
+ render() {
183
+ const { hasError, error } = this.state;
184
+ if (!hasError) {
185
+ return this.props.children;
186
+ }
187
+ if (isNextControlFlowError(error)) {
188
+ throw error;
189
+ }
190
+ const { fallback } = this.props;
191
+ if (typeof fallback === "function") {
192
+ return fallback({
193
+ error,
194
+ reset: this.reset
195
+ });
196
+ }
197
+ return fallback ?? null;
198
+ }
199
+ };
package/dist/react.js ADDED
@@ -0,0 +1,179 @@
1
+ "use client";
2
+
3
+ // src/react/index.tsx
4
+ import { Component, useEffect } from "react";
5
+
6
+ // src/common/carrier.ts
7
+ var CARRIER_KEY = /* @__PURE__ */ Symbol.for("hawk.nextjs");
8
+ function getCarrier() {
9
+ const store = globalThis;
10
+ store[CARRIER_KEY] ??= {};
11
+ return store[CARRIER_KEY];
12
+ }
13
+
14
+ // src/common/control-flow.ts
15
+ var CONTROL_FLOW_DIGEST_PREFIXES = [
16
+ "NEXT_REDIRECT",
17
+ "NEXT_HTTP_ERROR_FALLBACK;",
18
+ "NEXT_NOT_FOUND",
19
+ "BAILOUT_TO_CLIENT_SIDE_RENDERING",
20
+ "DYNAMIC_SERVER_USAGE",
21
+ "NEXT_PRERENDER_INTERRUPTED",
22
+ "HANGING_PROMISE_REJECTION"
23
+ ];
24
+ var STATIC_GEN_BAILOUT_CODE = "NEXT_STATIC_GEN_BAILOUT";
25
+ var REACT_POSTPONE_TYPE = /* @__PURE__ */ Symbol.for("react.postpone");
26
+ var MAX_CAUSE_DEPTH = 5;
27
+ function isControlFlowDigest(value) {
28
+ return typeof value === "string" && CONTROL_FLOW_DIGEST_PREFIXES.some((prefix) => value.startsWith(prefix));
29
+ }
30
+ function isNextControlFlowError(error) {
31
+ let current = error;
32
+ for (let depth = 0; depth < MAX_CAUSE_DEPTH; depth++) {
33
+ if (typeof current !== "object" || current === null) {
34
+ return false;
35
+ }
36
+ const value = current;
37
+ if (isControlFlowDigest(value.digest) || isControlFlowDigest(value.message) || value.code === STATIC_GEN_BAILOUT_CODE || value.$$typeof === REACT_POSTPONE_TYPE) {
38
+ return true;
39
+ }
40
+ current = value.cause;
41
+ }
42
+ return false;
43
+ }
44
+ function getDigest(error) {
45
+ if (typeof error === "object" && error !== null) {
46
+ const { digest } = error;
47
+ if (typeof digest === "string" && digest !== "") {
48
+ return digest;
49
+ }
50
+ }
51
+ return void 0;
52
+ }
53
+
54
+ // src/react/index.tsx
55
+ import { jsx, jsxs } from "react/jsx-runtime";
56
+ function captureBoundaryError(error, boundary, componentStack) {
57
+ if (isNextControlFlowError(error) || getDigest(error) !== void 0) {
58
+ return;
59
+ }
60
+ getCarrier().capture?.(error, {
61
+ boundary,
62
+ ...typeof componentStack === "string" ? { componentStack } : {}
63
+ });
64
+ }
65
+ function useHawkError(error) {
66
+ useEffect(() => {
67
+ captureBoundaryError(error, "error");
68
+ }, [error]);
69
+ }
70
+ var globalErrorStyles = {
71
+ container: {
72
+ fontFamily: "system-ui, sans-serif",
73
+ minHeight: "100vh",
74
+ display: "flex",
75
+ flexDirection: "column",
76
+ alignItems: "center",
77
+ justifyContent: "center",
78
+ gap: 16,
79
+ textAlign: "center"
80
+ },
81
+ title: {
82
+ fontSize: 14,
83
+ fontWeight: 400,
84
+ margin: 0
85
+ },
86
+ digest: {
87
+ fontSize: 12,
88
+ opacity: 0.6,
89
+ margin: 0
90
+ },
91
+ button: {
92
+ fontSize: 14,
93
+ padding: "6px 14px",
94
+ cursor: "pointer"
95
+ }
96
+ };
97
+ function HawkGlobalError({ error, reset }) {
98
+ useEffect(() => {
99
+ captureBoundaryError(error, "global-error");
100
+ }, [error]);
101
+ const side = error.digest === void 0 ? "client" : "server";
102
+ return /* @__PURE__ */ jsx("html", { lang: "en", children: /* @__PURE__ */ jsx("body", { children: /* @__PURE__ */ jsxs("main", { style: globalErrorStyles.container, children: [
103
+ /* @__PURE__ */ jsxs("h2", { style: globalErrorStyles.title, children: [
104
+ "Application error: a ",
105
+ side,
106
+ "-side exception has occurred."
107
+ ] }),
108
+ error.digest !== void 0 && /* @__PURE__ */ jsxs("p", { style: globalErrorStyles.digest, children: [
109
+ "Digest: ",
110
+ error.digest
111
+ ] }),
112
+ reset !== void 0 && /* @__PURE__ */ jsx("button", { type: "button", style: globalErrorStyles.button, onClick: reset, children: "Try again" })
113
+ ] }) }) });
114
+ }
115
+ var HawkErrorBoundary = class extends Component {
116
+ /**
117
+ * Initial state
118
+ */
119
+ state = {
120
+ hasError: false,
121
+ error: null
122
+ };
123
+ /**
124
+ * Shows the fallback after an error
125
+ * @param error - caught error
126
+ */
127
+ static getDerivedStateFromError(error) {
128
+ return {
129
+ hasError: true,
130
+ error
131
+ };
132
+ }
133
+ /**
134
+ * Sends the caught error
135
+ * @param error - caught error
136
+ * @param info - component stack
137
+ */
138
+ componentDidCatch(error, info) {
139
+ if (isNextControlFlowError(error)) {
140
+ return;
141
+ }
142
+ captureBoundaryError(error, "boundary", info.componentStack);
143
+ this.props.onError?.(error, info);
144
+ }
145
+ /**
146
+ * Renders the children again
147
+ */
148
+ reset = () => {
149
+ this.setState({
150
+ hasError: false,
151
+ error: null
152
+ });
153
+ };
154
+ /**
155
+ * Renders the children or the fallback
156
+ */
157
+ render() {
158
+ const { hasError, error } = this.state;
159
+ if (!hasError) {
160
+ return this.props.children;
161
+ }
162
+ if (isNextControlFlowError(error)) {
163
+ throw error;
164
+ }
165
+ const { fallback } = this.props;
166
+ if (typeof fallback === "function") {
167
+ return fallback({
168
+ error,
169
+ reset: this.reset
170
+ });
171
+ }
172
+ return fallback ?? null;
173
+ }
174
+ };
175
+ export {
176
+ HawkErrorBoundary,
177
+ HawkGlobalError,
178
+ useHawkError
179
+ };