@bugwatch/react 0.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.
- package/dist/index.d.mts +89 -0
- package/dist/index.d.ts +89 -0
- package/dist/index.js +211 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +173 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +59 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React, { Component, ReactNode, ErrorInfo } from 'react';
|
|
2
|
+
import { BugwatchOptions, BugwatchClient, ErrorEvent, Breadcrumb, UserContext } from '@bugwatch/core';
|
|
3
|
+
export { Breadcrumb, BugwatchOptions, ErrorEvent, UserContext, addBreadcrumb, captureException, captureMessage, getClient, init, setExtra, setTag, setUser } from '@bugwatch/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* React-specific SDK options
|
|
7
|
+
*/
|
|
8
|
+
interface ReactOptions extends BugwatchOptions {
|
|
9
|
+
/** Capture window.onerror events */
|
|
10
|
+
captureGlobalErrors?: boolean;
|
|
11
|
+
/** Capture unhandled promise rejections */
|
|
12
|
+
captureUnhandledRejections?: boolean;
|
|
13
|
+
/** Capture console.error as breadcrumbs */
|
|
14
|
+
captureConsoleBreadcrumbs?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Bugwatch context
|
|
18
|
+
*/
|
|
19
|
+
interface BugwatchContextValue {
|
|
20
|
+
client: BugwatchClient | null;
|
|
21
|
+
captureException: (error: Error, context?: Partial<ErrorEvent>) => string;
|
|
22
|
+
captureMessage: (message: string, level?: ErrorEvent["level"]) => string;
|
|
23
|
+
addBreadcrumb: (breadcrumb: Omit<Breadcrumb, "timestamp">) => void;
|
|
24
|
+
setUser: (user: UserContext | null) => void;
|
|
25
|
+
setTag: (key: string, value: string) => void;
|
|
26
|
+
setExtra: (key: string, value: unknown) => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Hook to access Bugwatch SDK
|
|
30
|
+
*/
|
|
31
|
+
declare function useBugwatch(): BugwatchContextValue;
|
|
32
|
+
/**
|
|
33
|
+
* Hook to capture exceptions
|
|
34
|
+
*/
|
|
35
|
+
declare function useCaptureException(): (error: Error, context?: Partial<ErrorEvent>) => string;
|
|
36
|
+
/**
|
|
37
|
+
* Hook to capture messages
|
|
38
|
+
*/
|
|
39
|
+
declare function useCaptureMessage(): (message: string, level?: ErrorEvent["level"]) => string;
|
|
40
|
+
/**
|
|
41
|
+
* Props for BugwatchProvider
|
|
42
|
+
*/
|
|
43
|
+
interface BugwatchProviderProps {
|
|
44
|
+
/** SDK configuration options */
|
|
45
|
+
options: ReactOptions;
|
|
46
|
+
/** Child components */
|
|
47
|
+
children: ReactNode;
|
|
48
|
+
/** Optional fallback UI for error boundary */
|
|
49
|
+
fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
|
|
50
|
+
/** Called when an error is caught by the error boundary */
|
|
51
|
+
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Bugwatch Provider component
|
|
55
|
+
* Initializes the SDK and provides context to child components
|
|
56
|
+
*/
|
|
57
|
+
declare function BugwatchProvider({ options, children, fallback, onError, }: BugwatchProviderProps): JSX.Element;
|
|
58
|
+
/**
|
|
59
|
+
* Error Boundary Props
|
|
60
|
+
*/
|
|
61
|
+
interface ErrorBoundaryProps {
|
|
62
|
+
children: ReactNode;
|
|
63
|
+
fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
|
|
64
|
+
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
65
|
+
}
|
|
66
|
+
interface ErrorBoundaryState {
|
|
67
|
+
hasError: boolean;
|
|
68
|
+
error: Error | null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Error Boundary component
|
|
72
|
+
*/
|
|
73
|
+
declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
74
|
+
constructor(props: ErrorBoundaryProps);
|
|
75
|
+
static getDerivedStateFromError(error: Error): ErrorBoundaryState;
|
|
76
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
77
|
+
reset: () => void;
|
|
78
|
+
render(): ReactNode;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Higher-order component for error boundary
|
|
83
|
+
*/
|
|
84
|
+
declare function withBugwatchErrorBoundary<P extends object>(WrappedComponent: React.ComponentType<P>, options?: {
|
|
85
|
+
fallback?: ErrorBoundaryProps["fallback"];
|
|
86
|
+
onError?: ErrorBoundaryProps["onError"];
|
|
87
|
+
}): React.ComponentType<P>;
|
|
88
|
+
|
|
89
|
+
export { ErrorBoundary as BugwatchErrorBoundary, BugwatchProvider, type ReactOptions, useBugwatch, useCaptureException, useCaptureMessage, withBugwatchErrorBoundary };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React, { Component, ReactNode, ErrorInfo } from 'react';
|
|
2
|
+
import { BugwatchOptions, BugwatchClient, ErrorEvent, Breadcrumb, UserContext } from '@bugwatch/core';
|
|
3
|
+
export { Breadcrumb, BugwatchOptions, ErrorEvent, UserContext, addBreadcrumb, captureException, captureMessage, getClient, init, setExtra, setTag, setUser } from '@bugwatch/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* React-specific SDK options
|
|
7
|
+
*/
|
|
8
|
+
interface ReactOptions extends BugwatchOptions {
|
|
9
|
+
/** Capture window.onerror events */
|
|
10
|
+
captureGlobalErrors?: boolean;
|
|
11
|
+
/** Capture unhandled promise rejections */
|
|
12
|
+
captureUnhandledRejections?: boolean;
|
|
13
|
+
/** Capture console.error as breadcrumbs */
|
|
14
|
+
captureConsoleBreadcrumbs?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Bugwatch context
|
|
18
|
+
*/
|
|
19
|
+
interface BugwatchContextValue {
|
|
20
|
+
client: BugwatchClient | null;
|
|
21
|
+
captureException: (error: Error, context?: Partial<ErrorEvent>) => string;
|
|
22
|
+
captureMessage: (message: string, level?: ErrorEvent["level"]) => string;
|
|
23
|
+
addBreadcrumb: (breadcrumb: Omit<Breadcrumb, "timestamp">) => void;
|
|
24
|
+
setUser: (user: UserContext | null) => void;
|
|
25
|
+
setTag: (key: string, value: string) => void;
|
|
26
|
+
setExtra: (key: string, value: unknown) => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Hook to access Bugwatch SDK
|
|
30
|
+
*/
|
|
31
|
+
declare function useBugwatch(): BugwatchContextValue;
|
|
32
|
+
/**
|
|
33
|
+
* Hook to capture exceptions
|
|
34
|
+
*/
|
|
35
|
+
declare function useCaptureException(): (error: Error, context?: Partial<ErrorEvent>) => string;
|
|
36
|
+
/**
|
|
37
|
+
* Hook to capture messages
|
|
38
|
+
*/
|
|
39
|
+
declare function useCaptureMessage(): (message: string, level?: ErrorEvent["level"]) => string;
|
|
40
|
+
/**
|
|
41
|
+
* Props for BugwatchProvider
|
|
42
|
+
*/
|
|
43
|
+
interface BugwatchProviderProps {
|
|
44
|
+
/** SDK configuration options */
|
|
45
|
+
options: ReactOptions;
|
|
46
|
+
/** Child components */
|
|
47
|
+
children: ReactNode;
|
|
48
|
+
/** Optional fallback UI for error boundary */
|
|
49
|
+
fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
|
|
50
|
+
/** Called when an error is caught by the error boundary */
|
|
51
|
+
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Bugwatch Provider component
|
|
55
|
+
* Initializes the SDK and provides context to child components
|
|
56
|
+
*/
|
|
57
|
+
declare function BugwatchProvider({ options, children, fallback, onError, }: BugwatchProviderProps): JSX.Element;
|
|
58
|
+
/**
|
|
59
|
+
* Error Boundary Props
|
|
60
|
+
*/
|
|
61
|
+
interface ErrorBoundaryProps {
|
|
62
|
+
children: ReactNode;
|
|
63
|
+
fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
|
|
64
|
+
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
65
|
+
}
|
|
66
|
+
interface ErrorBoundaryState {
|
|
67
|
+
hasError: boolean;
|
|
68
|
+
error: Error | null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Error Boundary component
|
|
72
|
+
*/
|
|
73
|
+
declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
74
|
+
constructor(props: ErrorBoundaryProps);
|
|
75
|
+
static getDerivedStateFromError(error: Error): ErrorBoundaryState;
|
|
76
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
77
|
+
reset: () => void;
|
|
78
|
+
render(): ReactNode;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Higher-order component for error boundary
|
|
83
|
+
*/
|
|
84
|
+
declare function withBugwatchErrorBoundary<P extends object>(WrappedComponent: React.ComponentType<P>, options?: {
|
|
85
|
+
fallback?: ErrorBoundaryProps["fallback"];
|
|
86
|
+
onError?: ErrorBoundaryProps["onError"];
|
|
87
|
+
}): React.ComponentType<P>;
|
|
88
|
+
|
|
89
|
+
export { ErrorBoundary as BugwatchErrorBoundary, BugwatchProvider, type ReactOptions, useBugwatch, useCaptureException, useCaptureMessage, withBugwatchErrorBoundary };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var core = require('@bugwatch/core');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
// src/index.tsx
|
|
8
|
+
var DEFAULT_REACT_OPTIONS = {
|
|
9
|
+
captureGlobalErrors: true,
|
|
10
|
+
captureUnhandledRejections: true,
|
|
11
|
+
captureConsoleBreadcrumbs: true
|
|
12
|
+
};
|
|
13
|
+
var BugwatchContext = react.createContext(null);
|
|
14
|
+
function useBugwatch() {
|
|
15
|
+
const context = react.useContext(BugwatchContext);
|
|
16
|
+
if (!context) {
|
|
17
|
+
throw new Error("useBugwatch must be used within a BugwatchProvider");
|
|
18
|
+
}
|
|
19
|
+
return context;
|
|
20
|
+
}
|
|
21
|
+
function useCaptureException() {
|
|
22
|
+
const { captureException: captureException2 } = useBugwatch();
|
|
23
|
+
return captureException2;
|
|
24
|
+
}
|
|
25
|
+
function useCaptureMessage() {
|
|
26
|
+
const { captureMessage: captureMessage2 } = useBugwatch();
|
|
27
|
+
return captureMessage2;
|
|
28
|
+
}
|
|
29
|
+
function BugwatchProvider({
|
|
30
|
+
options,
|
|
31
|
+
children,
|
|
32
|
+
fallback,
|
|
33
|
+
onError
|
|
34
|
+
}) {
|
|
35
|
+
react.useEffect(() => {
|
|
36
|
+
const mergedOptions = { ...DEFAULT_REACT_OPTIONS, ...options };
|
|
37
|
+
core.init(mergedOptions);
|
|
38
|
+
const client = core.getClient();
|
|
39
|
+
if (client) {
|
|
40
|
+
client.setTag("framework", "react");
|
|
41
|
+
}
|
|
42
|
+
if (typeof window !== "undefined") {
|
|
43
|
+
if (mergedOptions.captureGlobalErrors) {
|
|
44
|
+
setupGlobalErrorHandler();
|
|
45
|
+
}
|
|
46
|
+
if (mergedOptions.captureUnhandledRejections) {
|
|
47
|
+
setupUnhandledRejectionHandler();
|
|
48
|
+
}
|
|
49
|
+
if (mergedOptions.captureConsoleBreadcrumbs) {
|
|
50
|
+
setupConsoleBreadcrumbs();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (mergedOptions.debug) {
|
|
54
|
+
console.log("[Bugwatch] React SDK initialized");
|
|
55
|
+
}
|
|
56
|
+
}, [options]);
|
|
57
|
+
const captureException2 = react.useCallback(
|
|
58
|
+
(error, context) => {
|
|
59
|
+
return core.captureException(error, context);
|
|
60
|
+
},
|
|
61
|
+
[]
|
|
62
|
+
);
|
|
63
|
+
const captureMessage2 = react.useCallback(
|
|
64
|
+
(message, level) => {
|
|
65
|
+
return core.captureMessage(message, level);
|
|
66
|
+
},
|
|
67
|
+
[]
|
|
68
|
+
);
|
|
69
|
+
const addBreadcrumb2 = react.useCallback(
|
|
70
|
+
(breadcrumb) => {
|
|
71
|
+
core.addBreadcrumb(breadcrumb);
|
|
72
|
+
},
|
|
73
|
+
[]
|
|
74
|
+
);
|
|
75
|
+
const setUser2 = react.useCallback((user) => {
|
|
76
|
+
core.setUser(user);
|
|
77
|
+
}, []);
|
|
78
|
+
const setTag2 = react.useCallback((key, value) => {
|
|
79
|
+
core.setTag(key, value);
|
|
80
|
+
}, []);
|
|
81
|
+
const setExtra2 = react.useCallback((key, value) => {
|
|
82
|
+
core.setExtra(key, value);
|
|
83
|
+
}, []);
|
|
84
|
+
const contextValue = {
|
|
85
|
+
client: core.getClient(),
|
|
86
|
+
captureException: captureException2,
|
|
87
|
+
captureMessage: captureMessage2,
|
|
88
|
+
addBreadcrumb: addBreadcrumb2,
|
|
89
|
+
setUser: setUser2,
|
|
90
|
+
setTag: setTag2,
|
|
91
|
+
setExtra: setExtra2
|
|
92
|
+
};
|
|
93
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BugwatchContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { fallback, onError, children }) });
|
|
94
|
+
}
|
|
95
|
+
var ErrorBoundary = class extends react.Component {
|
|
96
|
+
constructor(props) {
|
|
97
|
+
super(props);
|
|
98
|
+
this.state = { hasError: false, error: null };
|
|
99
|
+
}
|
|
100
|
+
static getDerivedStateFromError(error) {
|
|
101
|
+
return { hasError: true, error };
|
|
102
|
+
}
|
|
103
|
+
componentDidCatch(error, errorInfo) {
|
|
104
|
+
core.captureException(error, {
|
|
105
|
+
tags: { mechanism: "react.errorBoundary" },
|
|
106
|
+
extra: {
|
|
107
|
+
componentStack: errorInfo.componentStack
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
this.props.onError?.(error, errorInfo);
|
|
111
|
+
}
|
|
112
|
+
reset = () => {
|
|
113
|
+
this.setState({ hasError: false, error: null });
|
|
114
|
+
};
|
|
115
|
+
render() {
|
|
116
|
+
if (this.state.hasError && this.state.error) {
|
|
117
|
+
const { fallback } = this.props;
|
|
118
|
+
if (typeof fallback === "function") {
|
|
119
|
+
return fallback(this.state.error, this.reset);
|
|
120
|
+
}
|
|
121
|
+
if (fallback) {
|
|
122
|
+
return fallback;
|
|
123
|
+
}
|
|
124
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "20px", fontFamily: "sans-serif" }, children: [
|
|
125
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { children: "Something went wrong" }),
|
|
126
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: this.state.error.message }),
|
|
127
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: this.reset, children: "Try again" })
|
|
128
|
+
] });
|
|
129
|
+
}
|
|
130
|
+
return this.props.children;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
function withBugwatchErrorBoundary(WrappedComponent, options) {
|
|
134
|
+
const WithErrorBoundary = (props) => /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { fallback: options?.fallback, onError: options?.onError, children: /* @__PURE__ */ jsxRuntime.jsx(WrappedComponent, { ...props }) });
|
|
135
|
+
WithErrorBoundary.displayName = `withBugwatchErrorBoundary(${WrappedComponent.displayName || WrappedComponent.name || "Component"})`;
|
|
136
|
+
return WithErrorBoundary;
|
|
137
|
+
}
|
|
138
|
+
function setupGlobalErrorHandler() {
|
|
139
|
+
const originalOnError = window.onerror;
|
|
140
|
+
window.onerror = (message, source, lineno, colno, error) => {
|
|
141
|
+
if (error) {
|
|
142
|
+
core.captureException(error, {
|
|
143
|
+
tags: { mechanism: "window.onerror" }
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
if (originalOnError) {
|
|
147
|
+
return originalOnError(message, source, lineno, colno, error);
|
|
148
|
+
}
|
|
149
|
+
return false;
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function setupUnhandledRejectionHandler() {
|
|
153
|
+
window.addEventListener("unhandledrejection", (event) => {
|
|
154
|
+
const error = event.reason instanceof Error ? event.reason : new Error(String(event.reason));
|
|
155
|
+
core.captureException(error, {
|
|
156
|
+
tags: { mechanism: "unhandledrejection" }
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function setupConsoleBreadcrumbs() {
|
|
161
|
+
const originalError = console.error;
|
|
162
|
+
console.error = (...args) => {
|
|
163
|
+
core.addBreadcrumb({
|
|
164
|
+
category: "console",
|
|
165
|
+
message: args.map(String).join(" "),
|
|
166
|
+
level: "error"
|
|
167
|
+
});
|
|
168
|
+
originalError(...args);
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
Object.defineProperty(exports, "addBreadcrumb", {
|
|
173
|
+
enumerable: true,
|
|
174
|
+
get: function () { return core.addBreadcrumb; }
|
|
175
|
+
});
|
|
176
|
+
Object.defineProperty(exports, "captureException", {
|
|
177
|
+
enumerable: true,
|
|
178
|
+
get: function () { return core.captureException; }
|
|
179
|
+
});
|
|
180
|
+
Object.defineProperty(exports, "captureMessage", {
|
|
181
|
+
enumerable: true,
|
|
182
|
+
get: function () { return core.captureMessage; }
|
|
183
|
+
});
|
|
184
|
+
Object.defineProperty(exports, "getClient", {
|
|
185
|
+
enumerable: true,
|
|
186
|
+
get: function () { return core.getClient; }
|
|
187
|
+
});
|
|
188
|
+
Object.defineProperty(exports, "init", {
|
|
189
|
+
enumerable: true,
|
|
190
|
+
get: function () { return core.init; }
|
|
191
|
+
});
|
|
192
|
+
Object.defineProperty(exports, "setExtra", {
|
|
193
|
+
enumerable: true,
|
|
194
|
+
get: function () { return core.setExtra; }
|
|
195
|
+
});
|
|
196
|
+
Object.defineProperty(exports, "setTag", {
|
|
197
|
+
enumerable: true,
|
|
198
|
+
get: function () { return core.setTag; }
|
|
199
|
+
});
|
|
200
|
+
Object.defineProperty(exports, "setUser", {
|
|
201
|
+
enumerable: true,
|
|
202
|
+
get: function () { return core.setUser; }
|
|
203
|
+
});
|
|
204
|
+
exports.BugwatchErrorBoundary = ErrorBoundary;
|
|
205
|
+
exports.BugwatchProvider = BugwatchProvider;
|
|
206
|
+
exports.useBugwatch = useBugwatch;
|
|
207
|
+
exports.useCaptureException = useCaptureException;
|
|
208
|
+
exports.useCaptureMessage = useCaptureMessage;
|
|
209
|
+
exports.withBugwatchErrorBoundary = withBugwatchErrorBoundary;
|
|
210
|
+
//# sourceMappingURL=index.js.map
|
|
211
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"names":["createContext","useContext","captureException","captureMessage","useEffect","coreInit","getClient","useCallback","coreCaptureException","coreCaptureMessage","addBreadcrumb","coreAddBreadcrumb","setUser","coreSetUser","setTag","coreSetTag","setExtra","coreSetExtra","jsx","Component","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import React, {\n Component,\n createContext,\n useContext,\n useEffect,\n useCallback,\n type ReactNode,\n type ErrorInfo,\n} from \"react\";\nimport {\n init as coreInit,\n getClient,\n captureException as coreCaptureException,\n captureMessage as coreCaptureMessage,\n addBreadcrumb as coreAddBreadcrumb,\n setUser as coreSetUser,\n setTag as coreSetTag,\n setExtra as coreSetExtra,\n type BugwatchOptions,\n type BugwatchClient,\n type UserContext,\n type Breadcrumb,\n type ErrorEvent,\n} from \"@bugwatch/core\";\n\n// Re-export types\nexport type { BugwatchOptions, UserContext, ErrorEvent, Breadcrumb } from \"@bugwatch/core\";\n\n/**\n * React-specific SDK options\n */\nexport interface ReactOptions extends BugwatchOptions {\n /** Capture window.onerror events */\n captureGlobalErrors?: boolean;\n /** Capture unhandled promise rejections */\n captureUnhandledRejections?: boolean;\n /** Capture console.error as breadcrumbs */\n captureConsoleBreadcrumbs?: boolean;\n}\n\nconst DEFAULT_REACT_OPTIONS: Partial<ReactOptions> = {\n captureGlobalErrors: true,\n captureUnhandledRejections: true,\n captureConsoleBreadcrumbs: true,\n};\n\n/**\n * Bugwatch context\n */\ninterface BugwatchContextValue {\n client: BugwatchClient | null;\n captureException: (error: Error, context?: Partial<ErrorEvent>) => string;\n captureMessage: (message: string, level?: ErrorEvent[\"level\"]) => string;\n addBreadcrumb: (breadcrumb: Omit<Breadcrumb, \"timestamp\">) => void;\n setUser: (user: UserContext | null) => void;\n setTag: (key: string, value: string) => void;\n setExtra: (key: string, value: unknown) => void;\n}\n\nconst BugwatchContext = createContext<BugwatchContextValue | null>(null);\n\n/**\n * Hook to access Bugwatch SDK\n */\nexport function useBugwatch(): BugwatchContextValue {\n const context = useContext(BugwatchContext);\n if (!context) {\n throw new Error(\"useBugwatch must be used within a BugwatchProvider\");\n }\n return context;\n}\n\n/**\n * Hook to capture exceptions\n */\nexport function useCaptureException(): (\n error: Error,\n context?: Partial<ErrorEvent>\n) => string {\n const { captureException } = useBugwatch();\n return captureException;\n}\n\n/**\n * Hook to capture messages\n */\nexport function useCaptureMessage(): (\n message: string,\n level?: ErrorEvent[\"level\"]\n) => string {\n const { captureMessage } = useBugwatch();\n return captureMessage;\n}\n\n/**\n * Props for BugwatchProvider\n */\ninterface BugwatchProviderProps {\n /** SDK configuration options */\n options: ReactOptions;\n /** Child components */\n children: ReactNode;\n /** Optional fallback UI for error boundary */\n fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n /** Called when an error is caught by the error boundary */\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n}\n\n/**\n * Bugwatch Provider component\n * Initializes the SDK and provides context to child components\n */\nexport function BugwatchProvider({\n options,\n children,\n fallback,\n onError,\n}: BugwatchProviderProps): JSX.Element {\n useEffect(() => {\n const mergedOptions = { ...DEFAULT_REACT_OPTIONS, ...options };\n coreInit(mergedOptions);\n\n // Add React-specific tags\n const client = getClient();\n if (client) {\n client.setTag(\"framework\", \"react\");\n }\n\n // Set up global error handlers\n if (typeof window !== \"undefined\") {\n if (mergedOptions.captureGlobalErrors) {\n setupGlobalErrorHandler();\n }\n if (mergedOptions.captureUnhandledRejections) {\n setupUnhandledRejectionHandler();\n }\n if (mergedOptions.captureConsoleBreadcrumbs) {\n setupConsoleBreadcrumbs();\n }\n }\n\n if (mergedOptions.debug) {\n console.log(\"[Bugwatch] React SDK initialized\");\n }\n }, [options]);\n\n const captureException = useCallback(\n (error: Error, context?: Partial<ErrorEvent>) => {\n return coreCaptureException(error, context);\n },\n []\n );\n\n const captureMessage = useCallback(\n (message: string, level?: ErrorEvent[\"level\"]) => {\n return coreCaptureMessage(message, level);\n },\n []\n );\n\n const addBreadcrumb = useCallback(\n (breadcrumb: Omit<Breadcrumb, \"timestamp\">) => {\n coreAddBreadcrumb(breadcrumb);\n },\n []\n );\n\n const setUser = useCallback((user: UserContext | null) => {\n coreSetUser(user);\n }, []);\n\n const setTag = useCallback((key: string, value: string) => {\n coreSetTag(key, value);\n }, []);\n\n const setExtra = useCallback((key: string, value: unknown) => {\n coreSetExtra(key, value);\n }, []);\n\n const contextValue: BugwatchContextValue = {\n client: getClient(),\n captureException,\n captureMessage,\n addBreadcrumb,\n setUser,\n setTag,\n setExtra,\n };\n\n return (\n <BugwatchContext.Provider value={contextValue}>\n <ErrorBoundary fallback={fallback} onError={onError}>\n {children}\n </ErrorBoundary>\n </BugwatchContext.Provider>\n );\n}\n\n/**\n * Error Boundary Props\n */\ninterface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Error Boundary component\n */\nclass ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n // Capture to Bugwatch\n coreCaptureException(error, {\n tags: { mechanism: \"react.errorBoundary\" },\n extra: {\n componentStack: errorInfo.componentStack,\n },\n });\n\n // Call custom handler\n this.props.onError?.(error, errorInfo);\n }\n\n reset = (): void => {\n this.setState({ hasError: false, error: null });\n };\n\n render(): ReactNode {\n if (this.state.hasError && this.state.error) {\n const { fallback } = this.props;\n\n if (typeof fallback === \"function\") {\n return fallback(this.state.error, this.reset);\n }\n\n if (fallback) {\n return fallback;\n }\n\n return (\n <div style={{ padding: \"20px\", fontFamily: \"sans-serif\" }}>\n <h2>Something went wrong</h2>\n <p>{this.state.error.message}</p>\n <button onClick={this.reset}>Try again</button>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n\n/**\n * Standalone Error Boundary for custom use\n */\nexport { ErrorBoundary as BugwatchErrorBoundary };\n\n/**\n * Higher-order component for error boundary\n */\nexport function withBugwatchErrorBoundary<P extends object>(\n WrappedComponent: React.ComponentType<P>,\n options?: {\n fallback?: ErrorBoundaryProps[\"fallback\"];\n onError?: ErrorBoundaryProps[\"onError\"];\n }\n): React.ComponentType<P> {\n const WithErrorBoundary = (props: P) => (\n <ErrorBoundary fallback={options?.fallback} onError={options?.onError}>\n <WrappedComponent {...props} />\n </ErrorBoundary>\n );\n\n WithErrorBoundary.displayName = `withBugwatchErrorBoundary(${\n WrappedComponent.displayName || WrappedComponent.name || \"Component\"\n })`;\n\n return WithErrorBoundary;\n}\n\n// Global error handler setup\nfunction setupGlobalErrorHandler(): void {\n const originalOnError = window.onerror;\n\n window.onerror = (message, source, lineno, colno, error) => {\n if (error) {\n coreCaptureException(error, {\n tags: { mechanism: \"window.onerror\" },\n });\n }\n\n if (originalOnError) {\n return originalOnError(message, source, lineno, colno, error);\n }\n\n return false;\n };\n}\n\nfunction setupUnhandledRejectionHandler(): void {\n window.addEventListener(\"unhandledrejection\", (event) => {\n const error =\n event.reason instanceof Error\n ? event.reason\n : new Error(String(event.reason));\n\n coreCaptureException(error, {\n tags: { mechanism: \"unhandledrejection\" },\n });\n });\n}\n\nfunction setupConsoleBreadcrumbs(): void {\n const originalError = console.error;\n\n console.error = (...args: unknown[]) => {\n coreAddBreadcrumb({\n category: \"console\",\n message: args.map(String).join(\" \"),\n level: \"error\",\n });\n originalError(...args);\n };\n}\n\n// Re-export core functions for convenience\nexport {\n captureException,\n captureMessage,\n addBreadcrumb,\n setUser,\n setTag,\n setExtra,\n getClient,\n init,\n} from \"@bugwatch/core\";\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { createContext, useContext, useEffect, useCallback, Component } from 'react';
|
|
2
|
+
import { init, getClient, captureException, captureMessage, addBreadcrumb, setUser, setTag, setExtra } from '@bugwatch/core';
|
|
3
|
+
export { addBreadcrumb, captureException, captureMessage, getClient, init, setExtra, setTag, setUser } from '@bugwatch/core';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/index.tsx
|
|
7
|
+
var DEFAULT_REACT_OPTIONS = {
|
|
8
|
+
captureGlobalErrors: true,
|
|
9
|
+
captureUnhandledRejections: true,
|
|
10
|
+
captureConsoleBreadcrumbs: true
|
|
11
|
+
};
|
|
12
|
+
var BugwatchContext = createContext(null);
|
|
13
|
+
function useBugwatch() {
|
|
14
|
+
const context = useContext(BugwatchContext);
|
|
15
|
+
if (!context) {
|
|
16
|
+
throw new Error("useBugwatch must be used within a BugwatchProvider");
|
|
17
|
+
}
|
|
18
|
+
return context;
|
|
19
|
+
}
|
|
20
|
+
function useCaptureException() {
|
|
21
|
+
const { captureException: captureException2 } = useBugwatch();
|
|
22
|
+
return captureException2;
|
|
23
|
+
}
|
|
24
|
+
function useCaptureMessage() {
|
|
25
|
+
const { captureMessage: captureMessage2 } = useBugwatch();
|
|
26
|
+
return captureMessage2;
|
|
27
|
+
}
|
|
28
|
+
function BugwatchProvider({
|
|
29
|
+
options,
|
|
30
|
+
children,
|
|
31
|
+
fallback,
|
|
32
|
+
onError
|
|
33
|
+
}) {
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const mergedOptions = { ...DEFAULT_REACT_OPTIONS, ...options };
|
|
36
|
+
init(mergedOptions);
|
|
37
|
+
const client = getClient();
|
|
38
|
+
if (client) {
|
|
39
|
+
client.setTag("framework", "react");
|
|
40
|
+
}
|
|
41
|
+
if (typeof window !== "undefined") {
|
|
42
|
+
if (mergedOptions.captureGlobalErrors) {
|
|
43
|
+
setupGlobalErrorHandler();
|
|
44
|
+
}
|
|
45
|
+
if (mergedOptions.captureUnhandledRejections) {
|
|
46
|
+
setupUnhandledRejectionHandler();
|
|
47
|
+
}
|
|
48
|
+
if (mergedOptions.captureConsoleBreadcrumbs) {
|
|
49
|
+
setupConsoleBreadcrumbs();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (mergedOptions.debug) {
|
|
53
|
+
console.log("[Bugwatch] React SDK initialized");
|
|
54
|
+
}
|
|
55
|
+
}, [options]);
|
|
56
|
+
const captureException2 = useCallback(
|
|
57
|
+
(error, context) => {
|
|
58
|
+
return captureException(error, context);
|
|
59
|
+
},
|
|
60
|
+
[]
|
|
61
|
+
);
|
|
62
|
+
const captureMessage2 = useCallback(
|
|
63
|
+
(message, level) => {
|
|
64
|
+
return captureMessage(message, level);
|
|
65
|
+
},
|
|
66
|
+
[]
|
|
67
|
+
);
|
|
68
|
+
const addBreadcrumb2 = useCallback(
|
|
69
|
+
(breadcrumb) => {
|
|
70
|
+
addBreadcrumb(breadcrumb);
|
|
71
|
+
},
|
|
72
|
+
[]
|
|
73
|
+
);
|
|
74
|
+
const setUser2 = useCallback((user) => {
|
|
75
|
+
setUser(user);
|
|
76
|
+
}, []);
|
|
77
|
+
const setTag2 = useCallback((key, value) => {
|
|
78
|
+
setTag(key, value);
|
|
79
|
+
}, []);
|
|
80
|
+
const setExtra2 = useCallback((key, value) => {
|
|
81
|
+
setExtra(key, value);
|
|
82
|
+
}, []);
|
|
83
|
+
const contextValue = {
|
|
84
|
+
client: getClient(),
|
|
85
|
+
captureException: captureException2,
|
|
86
|
+
captureMessage: captureMessage2,
|
|
87
|
+
addBreadcrumb: addBreadcrumb2,
|
|
88
|
+
setUser: setUser2,
|
|
89
|
+
setTag: setTag2,
|
|
90
|
+
setExtra: setExtra2
|
|
91
|
+
};
|
|
92
|
+
return /* @__PURE__ */ jsx(BugwatchContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(ErrorBoundary, { fallback, onError, children }) });
|
|
93
|
+
}
|
|
94
|
+
var ErrorBoundary = class extends Component {
|
|
95
|
+
constructor(props) {
|
|
96
|
+
super(props);
|
|
97
|
+
this.state = { hasError: false, error: null };
|
|
98
|
+
}
|
|
99
|
+
static getDerivedStateFromError(error) {
|
|
100
|
+
return { hasError: true, error };
|
|
101
|
+
}
|
|
102
|
+
componentDidCatch(error, errorInfo) {
|
|
103
|
+
captureException(error, {
|
|
104
|
+
tags: { mechanism: "react.errorBoundary" },
|
|
105
|
+
extra: {
|
|
106
|
+
componentStack: errorInfo.componentStack
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
this.props.onError?.(error, errorInfo);
|
|
110
|
+
}
|
|
111
|
+
reset = () => {
|
|
112
|
+
this.setState({ hasError: false, error: null });
|
|
113
|
+
};
|
|
114
|
+
render() {
|
|
115
|
+
if (this.state.hasError && this.state.error) {
|
|
116
|
+
const { fallback } = this.props;
|
|
117
|
+
if (typeof fallback === "function") {
|
|
118
|
+
return fallback(this.state.error, this.reset);
|
|
119
|
+
}
|
|
120
|
+
if (fallback) {
|
|
121
|
+
return fallback;
|
|
122
|
+
}
|
|
123
|
+
return /* @__PURE__ */ jsxs("div", { style: { padding: "20px", fontFamily: "sans-serif" }, children: [
|
|
124
|
+
/* @__PURE__ */ jsx("h2", { children: "Something went wrong" }),
|
|
125
|
+
/* @__PURE__ */ jsx("p", { children: this.state.error.message }),
|
|
126
|
+
/* @__PURE__ */ jsx("button", { onClick: this.reset, children: "Try again" })
|
|
127
|
+
] });
|
|
128
|
+
}
|
|
129
|
+
return this.props.children;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
function withBugwatchErrorBoundary(WrappedComponent, options) {
|
|
133
|
+
const WithErrorBoundary = (props) => /* @__PURE__ */ jsx(ErrorBoundary, { fallback: options?.fallback, onError: options?.onError, children: /* @__PURE__ */ jsx(WrappedComponent, { ...props }) });
|
|
134
|
+
WithErrorBoundary.displayName = `withBugwatchErrorBoundary(${WrappedComponent.displayName || WrappedComponent.name || "Component"})`;
|
|
135
|
+
return WithErrorBoundary;
|
|
136
|
+
}
|
|
137
|
+
function setupGlobalErrorHandler() {
|
|
138
|
+
const originalOnError = window.onerror;
|
|
139
|
+
window.onerror = (message, source, lineno, colno, error) => {
|
|
140
|
+
if (error) {
|
|
141
|
+
captureException(error, {
|
|
142
|
+
tags: { mechanism: "window.onerror" }
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (originalOnError) {
|
|
146
|
+
return originalOnError(message, source, lineno, colno, error);
|
|
147
|
+
}
|
|
148
|
+
return false;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function setupUnhandledRejectionHandler() {
|
|
152
|
+
window.addEventListener("unhandledrejection", (event) => {
|
|
153
|
+
const error = event.reason instanceof Error ? event.reason : new Error(String(event.reason));
|
|
154
|
+
captureException(error, {
|
|
155
|
+
tags: { mechanism: "unhandledrejection" }
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function setupConsoleBreadcrumbs() {
|
|
160
|
+
const originalError = console.error;
|
|
161
|
+
console.error = (...args) => {
|
|
162
|
+
addBreadcrumb({
|
|
163
|
+
category: "console",
|
|
164
|
+
message: args.map(String).join(" "),
|
|
165
|
+
level: "error"
|
|
166
|
+
});
|
|
167
|
+
originalError(...args);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export { ErrorBoundary as BugwatchErrorBoundary, BugwatchProvider, useBugwatch, useCaptureException, useCaptureMessage, withBugwatchErrorBoundary };
|
|
172
|
+
//# sourceMappingURL=index.mjs.map
|
|
173
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"names":["captureException","captureMessage","coreInit","coreCaptureException","coreCaptureMessage","addBreadcrumb","coreAddBreadcrumb","setUser","coreSetUser","setTag","coreSetTag","setExtra","coreSetExtra"],"mappings":"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","file":"index.mjs","sourcesContent":["import React, {\n Component,\n createContext,\n useContext,\n useEffect,\n useCallback,\n type ReactNode,\n type ErrorInfo,\n} from \"react\";\nimport {\n init as coreInit,\n getClient,\n captureException as coreCaptureException,\n captureMessage as coreCaptureMessage,\n addBreadcrumb as coreAddBreadcrumb,\n setUser as coreSetUser,\n setTag as coreSetTag,\n setExtra as coreSetExtra,\n type BugwatchOptions,\n type BugwatchClient,\n type UserContext,\n type Breadcrumb,\n type ErrorEvent,\n} from \"@bugwatch/core\";\n\n// Re-export types\nexport type { BugwatchOptions, UserContext, ErrorEvent, Breadcrumb } from \"@bugwatch/core\";\n\n/**\n * React-specific SDK options\n */\nexport interface ReactOptions extends BugwatchOptions {\n /** Capture window.onerror events */\n captureGlobalErrors?: boolean;\n /** Capture unhandled promise rejections */\n captureUnhandledRejections?: boolean;\n /** Capture console.error as breadcrumbs */\n captureConsoleBreadcrumbs?: boolean;\n}\n\nconst DEFAULT_REACT_OPTIONS: Partial<ReactOptions> = {\n captureGlobalErrors: true,\n captureUnhandledRejections: true,\n captureConsoleBreadcrumbs: true,\n};\n\n/**\n * Bugwatch context\n */\ninterface BugwatchContextValue {\n client: BugwatchClient | null;\n captureException: (error: Error, context?: Partial<ErrorEvent>) => string;\n captureMessage: (message: string, level?: ErrorEvent[\"level\"]) => string;\n addBreadcrumb: (breadcrumb: Omit<Breadcrumb, \"timestamp\">) => void;\n setUser: (user: UserContext | null) => void;\n setTag: (key: string, value: string) => void;\n setExtra: (key: string, value: unknown) => void;\n}\n\nconst BugwatchContext = createContext<BugwatchContextValue | null>(null);\n\n/**\n * Hook to access Bugwatch SDK\n */\nexport function useBugwatch(): BugwatchContextValue {\n const context = useContext(BugwatchContext);\n if (!context) {\n throw new Error(\"useBugwatch must be used within a BugwatchProvider\");\n }\n return context;\n}\n\n/**\n * Hook to capture exceptions\n */\nexport function useCaptureException(): (\n error: Error,\n context?: Partial<ErrorEvent>\n) => string {\n const { captureException } = useBugwatch();\n return captureException;\n}\n\n/**\n * Hook to capture messages\n */\nexport function useCaptureMessage(): (\n message: string,\n level?: ErrorEvent[\"level\"]\n) => string {\n const { captureMessage } = useBugwatch();\n return captureMessage;\n}\n\n/**\n * Props for BugwatchProvider\n */\ninterface BugwatchProviderProps {\n /** SDK configuration options */\n options: ReactOptions;\n /** Child components */\n children: ReactNode;\n /** Optional fallback UI for error boundary */\n fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n /** Called when an error is caught by the error boundary */\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n}\n\n/**\n * Bugwatch Provider component\n * Initializes the SDK and provides context to child components\n */\nexport function BugwatchProvider({\n options,\n children,\n fallback,\n onError,\n}: BugwatchProviderProps): JSX.Element {\n useEffect(() => {\n const mergedOptions = { ...DEFAULT_REACT_OPTIONS, ...options };\n coreInit(mergedOptions);\n\n // Add React-specific tags\n const client = getClient();\n if (client) {\n client.setTag(\"framework\", \"react\");\n }\n\n // Set up global error handlers\n if (typeof window !== \"undefined\") {\n if (mergedOptions.captureGlobalErrors) {\n setupGlobalErrorHandler();\n }\n if (mergedOptions.captureUnhandledRejections) {\n setupUnhandledRejectionHandler();\n }\n if (mergedOptions.captureConsoleBreadcrumbs) {\n setupConsoleBreadcrumbs();\n }\n }\n\n if (mergedOptions.debug) {\n console.log(\"[Bugwatch] React SDK initialized\");\n }\n }, [options]);\n\n const captureException = useCallback(\n (error: Error, context?: Partial<ErrorEvent>) => {\n return coreCaptureException(error, context);\n },\n []\n );\n\n const captureMessage = useCallback(\n (message: string, level?: ErrorEvent[\"level\"]) => {\n return coreCaptureMessage(message, level);\n },\n []\n );\n\n const addBreadcrumb = useCallback(\n (breadcrumb: Omit<Breadcrumb, \"timestamp\">) => {\n coreAddBreadcrumb(breadcrumb);\n },\n []\n );\n\n const setUser = useCallback((user: UserContext | null) => {\n coreSetUser(user);\n }, []);\n\n const setTag = useCallback((key: string, value: string) => {\n coreSetTag(key, value);\n }, []);\n\n const setExtra = useCallback((key: string, value: unknown) => {\n coreSetExtra(key, value);\n }, []);\n\n const contextValue: BugwatchContextValue = {\n client: getClient(),\n captureException,\n captureMessage,\n addBreadcrumb,\n setUser,\n setTag,\n setExtra,\n };\n\n return (\n <BugwatchContext.Provider value={contextValue}>\n <ErrorBoundary fallback={fallback} onError={onError}>\n {children}\n </ErrorBoundary>\n </BugwatchContext.Provider>\n );\n}\n\n/**\n * Error Boundary Props\n */\ninterface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n onError?: (error: Error, errorInfo: ErrorInfo) => void;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Error Boundary component\n */\nclass ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n // Capture to Bugwatch\n coreCaptureException(error, {\n tags: { mechanism: \"react.errorBoundary\" },\n extra: {\n componentStack: errorInfo.componentStack,\n },\n });\n\n // Call custom handler\n this.props.onError?.(error, errorInfo);\n }\n\n reset = (): void => {\n this.setState({ hasError: false, error: null });\n };\n\n render(): ReactNode {\n if (this.state.hasError && this.state.error) {\n const { fallback } = this.props;\n\n if (typeof fallback === \"function\") {\n return fallback(this.state.error, this.reset);\n }\n\n if (fallback) {\n return fallback;\n }\n\n return (\n <div style={{ padding: \"20px\", fontFamily: \"sans-serif\" }}>\n <h2>Something went wrong</h2>\n <p>{this.state.error.message}</p>\n <button onClick={this.reset}>Try again</button>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n\n/**\n * Standalone Error Boundary for custom use\n */\nexport { ErrorBoundary as BugwatchErrorBoundary };\n\n/**\n * Higher-order component for error boundary\n */\nexport function withBugwatchErrorBoundary<P extends object>(\n WrappedComponent: React.ComponentType<P>,\n options?: {\n fallback?: ErrorBoundaryProps[\"fallback\"];\n onError?: ErrorBoundaryProps[\"onError\"];\n }\n): React.ComponentType<P> {\n const WithErrorBoundary = (props: P) => (\n <ErrorBoundary fallback={options?.fallback} onError={options?.onError}>\n <WrappedComponent {...props} />\n </ErrorBoundary>\n );\n\n WithErrorBoundary.displayName = `withBugwatchErrorBoundary(${\n WrappedComponent.displayName || WrappedComponent.name || \"Component\"\n })`;\n\n return WithErrorBoundary;\n}\n\n// Global error handler setup\nfunction setupGlobalErrorHandler(): void {\n const originalOnError = window.onerror;\n\n window.onerror = (message, source, lineno, colno, error) => {\n if (error) {\n coreCaptureException(error, {\n tags: { mechanism: \"window.onerror\" },\n });\n }\n\n if (originalOnError) {\n return originalOnError(message, source, lineno, colno, error);\n }\n\n return false;\n };\n}\n\nfunction setupUnhandledRejectionHandler(): void {\n window.addEventListener(\"unhandledrejection\", (event) => {\n const error =\n event.reason instanceof Error\n ? event.reason\n : new Error(String(event.reason));\n\n coreCaptureException(error, {\n tags: { mechanism: \"unhandledrejection\" },\n });\n });\n}\n\nfunction setupConsoleBreadcrumbs(): void {\n const originalError = console.error;\n\n console.error = (...args: unknown[]) => {\n coreAddBreadcrumb({\n category: \"console\",\n message: args.map(String).join(\" \"),\n level: \"error\",\n });\n originalError(...args);\n };\n}\n\n// Re-export core functions for convenience\nexport {\n captureException,\n captureMessage,\n addBreadcrumb,\n setUser,\n setTag,\n setExtra,\n getClient,\n init,\n} from \"@bugwatch/core\";\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bugwatch/react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Bugwatch SDK for React applications",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.mjs",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"clean": "rm -rf dist",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:watch": "vitest"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@bugwatch/core": "*"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
31
|
+
"@testing-library/react": "^16.3.1",
|
|
32
|
+
"@types/react": "^18.0.0",
|
|
33
|
+
"@types/react-dom": "^19.0.2",
|
|
34
|
+
"jsdom": "^27.4.0",
|
|
35
|
+
"react": "^18.0.0",
|
|
36
|
+
"react-dom": "^19.0.0",
|
|
37
|
+
"tsup": "^8.0.0",
|
|
38
|
+
"typescript": "^5.3.0"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"react": ">=17.0.0"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
},
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "https://github.com/bugwatch/bugwatch.git",
|
|
49
|
+
"directory": "packages/sdk/react"
|
|
50
|
+
},
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"keywords": [
|
|
53
|
+
"bugwatch",
|
|
54
|
+
"error-tracking",
|
|
55
|
+
"monitoring",
|
|
56
|
+
"react",
|
|
57
|
+
"sdk"
|
|
58
|
+
]
|
|
59
|
+
}
|