@bugwatch/react 0.1.0 → 0.2.1
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 +22 -2
- package/dist/index.d.ts +22 -2
- package/dist/index.js +80 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +82 -51
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -41,8 +41,15 @@ declare function useCaptureMessage(): (message: string, level?: ErrorEvent["leve
|
|
|
41
41
|
* Props for BugwatchProvider
|
|
42
42
|
*/
|
|
43
43
|
interface BugwatchProviderProps {
|
|
44
|
-
/**
|
|
45
|
-
|
|
44
|
+
/**
|
|
45
|
+
* SDK configuration options.
|
|
46
|
+
* Optional - if not provided, reads from environment variables:
|
|
47
|
+
* - `BUGWATCH_API_KEY` - API key (required unless passed explicitly)
|
|
48
|
+
* - `BUGWATCH_ENVIRONMENT` - Environment tag
|
|
49
|
+
* - `BUGWATCH_RELEASE` - Release version
|
|
50
|
+
* - `BUGWATCH_DEBUG` - Enable debug mode ('true')
|
|
51
|
+
*/
|
|
52
|
+
options?: ReactOptions;
|
|
46
53
|
/** Child components */
|
|
47
54
|
children: ReactNode;
|
|
48
55
|
/** Optional fallback UI for error boundary */
|
|
@@ -53,6 +60,19 @@ interface BugwatchProviderProps {
|
|
|
53
60
|
/**
|
|
54
61
|
* Bugwatch Provider component
|
|
55
62
|
* Initializes the SDK and provides context to child components
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```tsx
|
|
66
|
+
* // With BUGWATCH_API_KEY env var set
|
|
67
|
+
* <BugwatchProvider>
|
|
68
|
+
* <App />
|
|
69
|
+
* </BugwatchProvider>
|
|
70
|
+
*
|
|
71
|
+
* // With explicit options
|
|
72
|
+
* <BugwatchProvider options={{ apiKey: "bw_live_xxxxx" }}>
|
|
73
|
+
* <App />
|
|
74
|
+
* </BugwatchProvider>
|
|
75
|
+
* ```
|
|
56
76
|
*/
|
|
57
77
|
declare function BugwatchProvider({ options, children, fallback, onError, }: BugwatchProviderProps): JSX.Element;
|
|
58
78
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -41,8 +41,15 @@ declare function useCaptureMessage(): (message: string, level?: ErrorEvent["leve
|
|
|
41
41
|
* Props for BugwatchProvider
|
|
42
42
|
*/
|
|
43
43
|
interface BugwatchProviderProps {
|
|
44
|
-
/**
|
|
45
|
-
|
|
44
|
+
/**
|
|
45
|
+
* SDK configuration options.
|
|
46
|
+
* Optional - if not provided, reads from environment variables:
|
|
47
|
+
* - `BUGWATCH_API_KEY` - API key (required unless passed explicitly)
|
|
48
|
+
* - `BUGWATCH_ENVIRONMENT` - Environment tag
|
|
49
|
+
* - `BUGWATCH_RELEASE` - Release version
|
|
50
|
+
* - `BUGWATCH_DEBUG` - Enable debug mode ('true')
|
|
51
|
+
*/
|
|
52
|
+
options?: ReactOptions;
|
|
46
53
|
/** Child components */
|
|
47
54
|
children: ReactNode;
|
|
48
55
|
/** Optional fallback UI for error boundary */
|
|
@@ -53,6 +60,19 @@ interface BugwatchProviderProps {
|
|
|
53
60
|
/**
|
|
54
61
|
* Bugwatch Provider component
|
|
55
62
|
* Initializes the SDK and provides context to child components
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```tsx
|
|
66
|
+
* // With BUGWATCH_API_KEY env var set
|
|
67
|
+
* <BugwatchProvider>
|
|
68
|
+
* <App />
|
|
69
|
+
* </BugwatchProvider>
|
|
70
|
+
*
|
|
71
|
+
* // With explicit options
|
|
72
|
+
* <BugwatchProvider options={{ apiKey: "bw_live_xxxxx" }}>
|
|
73
|
+
* <App />
|
|
74
|
+
* </BugwatchProvider>
|
|
75
|
+
* ```
|
|
56
76
|
*/
|
|
57
77
|
declare function BugwatchProvider({ options, children, fallback, onError, }: BugwatchProviderProps): JSX.Element;
|
|
58
78
|
/**
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,6 @@ var react = require('react');
|
|
|
4
4
|
var core = require('@bugwatch/core');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
|
|
7
|
-
// src/index.tsx
|
|
8
7
|
var DEFAULT_REACT_OPTIONS = {
|
|
9
8
|
captureGlobalErrors: true,
|
|
10
9
|
captureUnhandledRejections: true,
|
|
@@ -32,28 +31,90 @@ function BugwatchProvider({
|
|
|
32
31
|
fallback,
|
|
33
32
|
onError
|
|
34
33
|
}) {
|
|
34
|
+
const optionsKey = react.useMemo(
|
|
35
|
+
() => options ? JSON.stringify(options) : "",
|
|
36
|
+
[options]
|
|
37
|
+
);
|
|
38
|
+
const optionsRef = react.useRef(options);
|
|
39
|
+
optionsRef.current = options;
|
|
35
40
|
react.useEffect(() => {
|
|
36
|
-
const
|
|
37
|
-
core.
|
|
41
|
+
const currentOptions = optionsRef.current;
|
|
42
|
+
const envConfig = core.getEnvConfig();
|
|
43
|
+
const mergedOptions = { ...DEFAULT_REACT_OPTIONS, ...envConfig, ...currentOptions };
|
|
44
|
+
if (!mergedOptions.apiKey) {
|
|
45
|
+
if (process.env.NODE_ENV === "development") {
|
|
46
|
+
console.warn("[Bugwatch] No API key provided. Set BUGWATCH_API_KEY env var or pass options.apiKey");
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
core.init(mergedOptions);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
if (process.env.NODE_ENV === "development") {
|
|
54
|
+
console.error("[Bugwatch] Initialization failed:", err);
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
38
58
|
const client = core.getClient();
|
|
39
59
|
if (client) {
|
|
40
60
|
client.setTag("framework", "react");
|
|
41
61
|
}
|
|
62
|
+
let originalOnError = null;
|
|
63
|
+
let originalConsoleError = null;
|
|
64
|
+
let unhandledRejectionHandler = null;
|
|
42
65
|
if (typeof window !== "undefined") {
|
|
43
66
|
if (mergedOptions.captureGlobalErrors) {
|
|
44
|
-
|
|
67
|
+
originalOnError = window.onerror;
|
|
68
|
+
window.onerror = (message, source, lineno, colno, error) => {
|
|
69
|
+
if (error) {
|
|
70
|
+
core.captureException(error, {
|
|
71
|
+
tags: { mechanism: "window.onerror" }
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (originalOnError) {
|
|
75
|
+
return originalOnError(message, source, lineno, colno, error);
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
};
|
|
45
79
|
}
|
|
46
80
|
if (mergedOptions.captureUnhandledRejections) {
|
|
47
|
-
|
|
81
|
+
unhandledRejectionHandler = (event) => {
|
|
82
|
+
const error = event.reason instanceof Error ? event.reason : new Error(String(event.reason));
|
|
83
|
+
core.captureException(error, {
|
|
84
|
+
tags: { mechanism: "unhandledrejection" }
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
window.addEventListener("unhandledrejection", unhandledRejectionHandler);
|
|
48
88
|
}
|
|
49
89
|
if (mergedOptions.captureConsoleBreadcrumbs) {
|
|
50
|
-
|
|
90
|
+
originalConsoleError = console.error;
|
|
91
|
+
console.error = (...args) => {
|
|
92
|
+
core.addBreadcrumb({
|
|
93
|
+
category: "console",
|
|
94
|
+
message: args.map(String).join(" "),
|
|
95
|
+
level: "error"
|
|
96
|
+
});
|
|
97
|
+
originalConsoleError(...args);
|
|
98
|
+
};
|
|
51
99
|
}
|
|
52
100
|
}
|
|
53
101
|
if (mergedOptions.debug) {
|
|
54
102
|
console.log("[Bugwatch] React SDK initialized");
|
|
55
103
|
}
|
|
56
|
-
|
|
104
|
+
return () => {
|
|
105
|
+
if (typeof window !== "undefined") {
|
|
106
|
+
if (originalOnError !== null && mergedOptions.captureGlobalErrors) {
|
|
107
|
+
window.onerror = originalOnError;
|
|
108
|
+
}
|
|
109
|
+
if (unhandledRejectionHandler && mergedOptions.captureUnhandledRejections) {
|
|
110
|
+
window.removeEventListener("unhandledrejection", unhandledRejectionHandler);
|
|
111
|
+
}
|
|
112
|
+
if (originalConsoleError !== null && mergedOptions.captureConsoleBreadcrumbs) {
|
|
113
|
+
console.error = originalConsoleError;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}, [optionsKey]);
|
|
57
118
|
const captureException2 = react.useCallback(
|
|
58
119
|
(error, context) => {
|
|
59
120
|
return core.captureException(error, context);
|
|
@@ -81,15 +142,18 @@ function BugwatchProvider({
|
|
|
81
142
|
const setExtra2 = react.useCallback((key, value) => {
|
|
82
143
|
core.setExtra(key, value);
|
|
83
144
|
}, []);
|
|
84
|
-
const contextValue =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
145
|
+
const contextValue = react.useMemo(
|
|
146
|
+
() => ({
|
|
147
|
+
client: core.getClient(),
|
|
148
|
+
captureException: captureException2,
|
|
149
|
+
captureMessage: captureMessage2,
|
|
150
|
+
addBreadcrumb: addBreadcrumb2,
|
|
151
|
+
setUser: setUser2,
|
|
152
|
+
setTag: setTag2,
|
|
153
|
+
setExtra: setExtra2
|
|
154
|
+
}),
|
|
155
|
+
[captureException2, captureMessage2, addBreadcrumb2, setUser2, setTag2, setExtra2]
|
|
156
|
+
);
|
|
93
157
|
return /* @__PURE__ */ jsxRuntime.jsx(BugwatchContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { fallback, onError, children }) });
|
|
94
158
|
}
|
|
95
159
|
var ErrorBoundary = class extends react.Component {
|
|
@@ -135,39 +199,6 @@ function withBugwatchErrorBoundary(WrappedComponent, options) {
|
|
|
135
199
|
WithErrorBoundary.displayName = `withBugwatchErrorBoundary(${WrappedComponent.displayName || WrappedComponent.name || "Component"})`;
|
|
136
200
|
return WithErrorBoundary;
|
|
137
201
|
}
|
|
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
202
|
|
|
172
203
|
Object.defineProperty(exports, "addBreadcrumb", {
|
|
173
204
|
enumerable: true,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +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"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"names":["createContext","useContext","captureException","captureMessage","useMemo","useRef","useEffect","getEnvConfig","coreInit","getClient","coreCaptureException","coreAddBreadcrumb","useCallback","coreCaptureMessage","addBreadcrumb","setUser","coreSetUser","setTag","coreSetTag","setExtra","coreSetExtra","jsx","Component","jsxs"],"mappings":";;;;;;AA6CA,IAAM,qBAAA,GAA+C;AAAA,EACnD,mBAAA,EAAqB,IAAA;AAAA,EACrB,0BAAA,EAA4B,IAAA;AAAA,EAC5B,yBAAA,EAA2B;AAC7B,CAAA;AAeA,IAAM,eAAA,GAAkBA,oBAA2C,IAAI,CAAA;AAKhE,SAAS,WAAA,GAAoC;AAClD,EAAA,MAAM,OAAA,GAAUC,iBAAW,eAAe,CAAA;AAC1C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,oDAAoD,CAAA;AAAA,EACtE;AACA,EAAA,OAAO,OAAA;AACT;AAKO,SAAS,mBAAA,GAGJ;AACV,EAAA,MAAM,EAAE,gBAAA,EAAAC,iBAAAA,EAAiB,GAAI,WAAA,EAAY;AACzC,EAAA,OAAOA,iBAAAA;AACT;AAKO,SAAS,iBAAA,GAGJ;AACV,EAAA,MAAM,EAAE,cAAA,EAAAC,eAAAA,EAAe,GAAI,WAAA,EAAY;AACvC,EAAA,OAAOA,eAAAA;AACT;AAwCO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,OAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAAuC;AAGrC,EAAA,MAAM,UAAA,GAAaC,aAAA;AAAA,IACjB,MAAO,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,GAAI,EAAA;AAAA,IAC3C,CAAC,OAAO;AAAA,GACV;AACA,EAAA,MAAM,UAAA,GAAaC,aAAO,OAAO,CAAA;AACjC,EAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAErB,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,MAAM,iBAAiB,UAAA,CAAW,OAAA;AAGlC,IAAA,MAAM,YAAYC,iBAAA,EAAa;AAC/B,IAAA,MAAM,gBAAgB,EAAE,GAAG,uBAAuB,GAAG,SAAA,EAAW,GAAG,cAAA,EAAe;AAGlF,IAAA,IAAI,CAAC,cAAc,MAAA,EAAQ;AACzB,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA,EAAe;AAC1C,QAAA,OAAA,CAAQ,KAAK,qFAAqF,CAAA;AAAA,MACpG;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI;AACF,MAAAC,SAAA,CAAS,aAAa,CAAA;AAAA,IACxB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA,EAAe;AAC1C,QAAA,OAAA,CAAQ,KAAA,CAAM,qCAAqC,GAAG,CAAA;AAAA,MACxD;AACA,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,SAASC,cAAA,EAAU;AACzB,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAA,CAAO,MAAA,CAAO,aAAa,OAAO,CAAA;AAAA,IACpC;AAGA,IAAA,IAAI,eAAA,GAAgD,IAAA;AACpD,IAAA,IAAI,oBAAA,GAAoD,IAAA;AACxD,IAAA,IAAI,yBAAA,GAA6E,IAAA;AAGjF,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,IAAI,cAAc,mBAAA,EAAqB;AACrC,QAAA,eAAA,GAAkB,MAAA,CAAO,OAAA;AACzB,QAAA,MAAA,CAAO,UAAU,CAAC,OAAA,EAAS,MAAA,EAAQ,MAAA,EAAQ,OAAO,KAAA,KAAU;AAC1D,UAAA,IAAI,KAAA,EAAO;AACT,YAAAC,qBAAA,CAAqB,KAAA,EAAO;AAAA,cAC1B,IAAA,EAAM,EAAE,SAAA,EAAW,gBAAA;AAAiB,aACrC,CAAA;AAAA,UACH;AACA,UAAA,IAAI,eAAA,EAAiB;AACnB,YAAA,OAAO,eAAA,CAAgB,OAAA,EAAS,MAAA,EAAQ,MAAA,EAAQ,OAAO,KAAK,CAAA;AAAA,UAC9D;AACA,UAAA,OAAO,KAAA;AAAA,QACT,CAAA;AAAA,MACF;AAEA,MAAA,IAAI,cAAc,0BAAA,EAA4B;AAC5C,QAAA,yBAAA,GAA4B,CAAC,KAAA,KAAiC;AAC5D,UAAA,MAAM,KAAA,GACJ,KAAA,CAAM,MAAA,YAAkB,KAAA,GACpB,KAAA,CAAM,MAAA,GACN,IAAI,KAAA,CAAM,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA;AACpC,UAAAA,qBAAA,CAAqB,KAAA,EAAO;AAAA,YAC1B,IAAA,EAAM,EAAE,SAAA,EAAW,oBAAA;AAAqB,WACzC,CAAA;AAAA,QACH,CAAA;AACA,QAAA,MAAA,CAAO,gBAAA,CAAiB,sBAAsB,yBAAyB,CAAA;AAAA,MACzE;AAEA,MAAA,IAAI,cAAc,yBAAA,EAA2B;AAC3C,QAAA,oBAAA,GAAuB,OAAA,CAAQ,KAAA;AAC/B,QAAA,OAAA,CAAQ,KAAA,GAAQ,IAAI,IAAA,KAAoB;AACtC,UAAAC,kBAAA,CAAkB;AAAA,YAChB,QAAA,EAAU,SAAA;AAAA,YACV,SAAS,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,CAAE,KAAK,GAAG,CAAA;AAAA,YAClC,KAAA,EAAO;AAAA,WACR,CAAA;AACD,UAAA,oBAAA,CAAsB,GAAG,IAAI,CAAA;AAAA,QAC/B,CAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,cAAc,KAAA,EAAO;AACvB,MAAA,OAAA,CAAQ,IAAI,kCAAkC,CAAA;AAAA,IAChD;AAGA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAEjC,QAAA,IAAI,eAAA,KAAoB,IAAA,IAAQ,aAAA,CAAc,mBAAA,EAAqB;AACjE,UAAA,MAAA,CAAO,OAAA,GAAU,eAAA;AAAA,QACnB;AAGA,QAAA,IAAI,yBAAA,IAA6B,cAAc,0BAAA,EAA4B;AACzE,UAAA,MAAA,CAAO,mBAAA,CAAoB,sBAAsB,yBAAyB,CAAA;AAAA,QAC5E;AAGA,QAAA,IAAI,oBAAA,KAAyB,IAAA,IAAQ,aAAA,CAAc,yBAAA,EAA2B;AAC5E,UAAA,OAAA,CAAQ,KAAA,GAAQ,oBAAA;AAAA,QAClB;AAAA,MACF;AAAA,IACF,CAAA;AAAA,EAEF,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,MAAMT,iBAAAA,GAAmBU,iBAAA;AAAA,IACvB,CAAC,OAAc,OAAA,KAAkC;AAC/C,MAAA,OAAOF,qBAAA,CAAqB,OAAO,OAAO,CAAA;AAAA,IAC5C,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAMP,eAAAA,GAAiBS,iBAAA;AAAA,IACrB,CAAC,SAAiB,KAAA,KAAgC;AAChD,MAAA,OAAOC,mBAAA,CAAmB,SAAS,KAAK,CAAA;AAAA,IAC1C,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAMC,cAAAA,GAAgBF,iBAAA;AAAA,IACpB,CAAC,UAAA,KAA8C;AAC7C,MAAAD,kBAAA,CAAkB,UAAU,CAAA;AAAA,IAC9B,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAMI,QAAAA,GAAUH,iBAAA,CAAY,CAAC,IAAA,KAA6B;AACxD,IAAAI,YAAA,CAAY,IAAI,CAAA;AAAA,EAClB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAMC,OAAAA,GAASL,iBAAA,CAAY,CAAC,GAAA,EAAa,KAAA,KAAkB;AACzD,IAAAM,WAAA,CAAW,KAAK,KAAK,CAAA;AAAA,EACvB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAMC,SAAAA,GAAWP,iBAAA,CAAY,CAAC,GAAA,EAAa,KAAA,KAAmB;AAC5D,IAAAQ,aAAA,CAAa,KAAK,KAAK,CAAA;AAAA,EACzB,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,YAAA,GAAehB,aAAA;AAAA,IACnB,OAAO;AAAA,MACL,QAAQK,cAAA,EAAU;AAAA,MAClB,gBAAA,EAAAP,iBAAAA;AAAA,MACA,cAAA,EAAAC,eAAAA;AAAA,MACA,aAAA,EAAAW,cAAAA;AAAA,MACA,OAAA,EAAAC,QAAAA;AAAA,MACA,MAAA,EAAAE,OAAAA;AAAA,MACA,QAAA,EAAAE;AAAA,KACF,CAAA;AAAA,IACA,CAACjB,iBAAAA,EAAkBC,eAAAA,EAAgBW,cAAAA,EAAeC,QAAAA,EAASE,SAAQE,SAAQ;AAAA,GAC7E;AAEA,EAAA,uBACEE,cAAA,CAAC,eAAA,CAAgB,QAAA,EAAhB,EAAyB,KAAA,EAAO,YAAA,EAC/B,QAAA,kBAAAA,cAAA,CAAC,aAAA,EAAA,EAAc,QAAA,EAAoB,OAAA,EAChC,QAAA,EACH,CAAA,EACF,CAAA;AAEJ;AAmBA,IAAM,aAAA,GAAN,cAA4BC,eAAA,CAAkD;AAAA,EAC5E,YAAY,KAAA,EAA2B;AACrC,IAAA,KAAA,CAAM,KAAK,CAAA;AACX,IAAA,IAAA,CAAK,KAAA,GAAQ,EAAE,QAAA,EAAU,KAAA,EAAO,OAAO,IAAA,EAAK;AAAA,EAC9C;AAAA,EAEA,OAAO,yBAAyB,KAAA,EAAkC;AAChE,IAAA,OAAO,EAAE,QAAA,EAAU,IAAA,EAAM,KAAA,EAAM;AAAA,EACjC;AAAA,EAEA,iBAAA,CAAkB,OAAc,SAAA,EAA4B;AAE1D,IAAAZ,qBAAA,CAAqB,KAAA,EAAO;AAAA,MAC1B,IAAA,EAAM,EAAE,SAAA,EAAW,qBAAA,EAAsB;AAAA,MACzC,KAAA,EAAO;AAAA,QACL,gBAAgB,SAAA,CAAU;AAAA;AAC5B,KACD,CAAA;AAGD,IAAA,IAAA,CAAK,KAAA,CAAM,OAAA,GAAU,KAAA,EAAO,SAAS,CAAA;AAAA,EACvC;AAAA,EAEA,QAAQ,MAAY;AAClB,IAAA,IAAA,CAAK,SAAS,EAAE,QAAA,EAAU,KAAA,EAAO,KAAA,EAAO,MAAM,CAAA;AAAA,EAChD,CAAA;AAAA,EAEA,MAAA,GAAoB;AAClB,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,QAAA,IAAY,IAAA,CAAK,MAAM,KAAA,EAAO;AAC3C,MAAA,MAAM,EAAE,QAAA,EAAS,GAAI,IAAA,CAAK,KAAA;AAE1B,MAAA,IAAI,OAAO,aAAa,UAAA,EAAY;AAClC,QAAA,OAAO,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,KAAK,KAAK,CAAA;AAAA,MAC9C;AAEA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAO,QAAA;AAAA,MACT;AAEA,MAAA,uBACEa,eAAA,CAAC,SAAI,KAAA,EAAO,EAAE,SAAS,MAAA,EAAQ,UAAA,EAAY,cAAa,EACtD,QAAA,EAAA;AAAA,wBAAAF,cAAA,CAAC,QAAG,QAAA,EAAA,sBAAA,EAAoB,CAAA;AAAA,wBACxBA,cAAA,CAAC,GAAA,EAAA,EAAG,QAAA,EAAA,IAAA,CAAK,KAAA,CAAM,MAAM,OAAA,EAAQ,CAAA;AAAA,wBAC7BA,cAAA,CAAC,QAAA,EAAA,EAAO,OAAA,EAAS,IAAA,CAAK,OAAO,QAAA,EAAA,WAAA,EAAS;AAAA,OAAA,EACxC,CAAA;AAAA,IAEJ;AAEA,IAAA,OAAO,KAAK,KAAA,CAAM,QAAA;AAAA,EACpB;AACF;AAUO,SAAS,yBAAA,CACd,kBACA,OAAA,EAIwB;AACxB,EAAA,MAAM,iBAAA,GAAoB,CAAC,KAAA,qBACzBA,cAAA,CAAC,iBAAc,QAAA,EAAU,OAAA,EAAS,QAAA,EAAU,OAAA,EAAS,SAAS,OAAA,EAC5D,QAAA,kBAAAA,cAAA,CAAC,gBAAA,EAAA,EAAkB,GAAG,OAAO,CAAA,EAC/B,CAAA;AAGF,EAAA,iBAAA,CAAkB,cAAc,CAAA,0BAAA,EAC9B,gBAAA,CAAiB,WAAA,IAAe,gBAAA,CAAiB,QAAQ,WAC3D,CAAA,CAAA,CAAA;AAEA,EAAA,OAAO,iBAAA;AACT","file":"index.js","sourcesContent":["\"use client\";\n\nimport React, {\n Component,\n createContext,\n useContext,\n useEffect,\n useCallback,\n useRef,\n useMemo,\n type ReactNode,\n type ErrorInfo,\n} from \"react\";\nimport {\n init as coreInit,\n getClient,\n getEnvConfig,\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 /**\n * SDK configuration options.\n * Optional - if not provided, reads from environment variables:\n * - `BUGWATCH_API_KEY` - API key (required unless passed explicitly)\n * - `BUGWATCH_ENVIRONMENT` - Environment tag\n * - `BUGWATCH_RELEASE` - Release version\n * - `BUGWATCH_DEBUG` - Enable debug mode ('true')\n */\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 *\n * @example\n * ```tsx\n * // With BUGWATCH_API_KEY env var set\n * <BugwatchProvider>\n * <App />\n * </BugwatchProvider>\n *\n * // With explicit options\n * <BugwatchProvider options={{ apiKey: \"bw_live_xxxxx\" }}>\n * <App />\n * </BugwatchProvider>\n * ```\n */\nexport function BugwatchProvider({\n options,\n children,\n fallback,\n onError,\n}: BugwatchProviderProps): JSX.Element {\n // Serialize options to a stable string so useEffect doesn't re-run on every render.\n // Object identity of `options` changes every render if passed inline.\n const optionsKey = useMemo(\n () => (options ? JSON.stringify(options) : \"\"),\n [options]\n );\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n useEffect(() => {\n const currentOptions = optionsRef.current;\n\n // Merge env config with explicit options (explicit takes precedence)\n const envConfig = getEnvConfig();\n const mergedOptions = { ...DEFAULT_REACT_OPTIONS, ...envConfig, ...currentOptions };\n\n // Skip initialization if no API key is available\n if (!mergedOptions.apiKey) {\n if (process.env.NODE_ENV === 'development') {\n console.warn('[Bugwatch] No API key provided. Set BUGWATCH_API_KEY env var or pass options.apiKey');\n }\n return;\n }\n\n // Wrap initialization in try-catch for graceful degradation\n try {\n coreInit(mergedOptions);\n } catch (err) {\n if (process.env.NODE_ENV === 'development') {\n console.error('[Bugwatch] Initialization failed:', err);\n }\n return;\n }\n\n // Add React-specific tags\n const client = getClient();\n if (client) {\n client.setTag(\"framework\", \"react\");\n }\n\n // Store original handlers for cleanup\n let originalOnError: typeof window.onerror | null = null;\n let originalConsoleError: typeof console.error | null = null;\n let unhandledRejectionHandler: ((event: PromiseRejectionEvent) => void) | null = null;\n\n // Set up global error handlers\n if (typeof window !== \"undefined\") {\n if (mergedOptions.captureGlobalErrors) {\n originalOnError = window.onerror;\n window.onerror = (message, source, lineno, colno, error) => {\n if (error) {\n coreCaptureException(error, {\n tags: { mechanism: \"window.onerror\" },\n });\n }\n if (originalOnError) {\n return originalOnError(message, source, lineno, colno, error);\n }\n return false;\n };\n }\n\n if (mergedOptions.captureUnhandledRejections) {\n unhandledRejectionHandler = (event: PromiseRejectionEvent) => {\n const error =\n event.reason instanceof Error\n ? event.reason\n : new Error(String(event.reason));\n coreCaptureException(error, {\n tags: { mechanism: \"unhandledrejection\" },\n });\n };\n window.addEventListener(\"unhandledrejection\", unhandledRejectionHandler);\n }\n\n if (mergedOptions.captureConsoleBreadcrumbs) {\n originalConsoleError = console.error;\n console.error = (...args: unknown[]) => {\n coreAddBreadcrumb({\n category: \"console\",\n message: args.map(String).join(\" \"),\n level: \"error\",\n });\n originalConsoleError!(...args);\n };\n }\n }\n\n if (mergedOptions.debug) {\n console.log(\"[Bugwatch] React SDK initialized\");\n }\n\n // Cleanup function to prevent memory leaks\n return () => {\n if (typeof window !== \"undefined\") {\n // Restore original window.onerror\n if (originalOnError !== null && mergedOptions.captureGlobalErrors) {\n window.onerror = originalOnError;\n }\n\n // Remove unhandled rejection listener\n if (unhandledRejectionHandler && mergedOptions.captureUnhandledRejections) {\n window.removeEventListener(\"unhandledrejection\", unhandledRejectionHandler);\n }\n\n // Restore original console.error\n if (originalConsoleError !== null && mergedOptions.captureConsoleBreadcrumbs) {\n console.error = originalConsoleError;\n }\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [optionsKey]);\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 // Memoize context value to prevent unnecessary re-renders\n const contextValue = useMemo<BugwatchContextValue>(\n () => ({\n client: getClient(),\n captureException,\n captureMessage,\n addBreadcrumb,\n setUser,\n setTag,\n setExtra,\n }),\n [captureException, captureMessage, addBreadcrumb, setUser, setTag, 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// 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
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { createContext, useContext, useEffect, useCallback, Component } from 'react';
|
|
2
|
-
import { init, getClient, captureException,
|
|
1
|
+
import { createContext, useContext, useMemo, useRef, useEffect, useCallback, Component } from 'react';
|
|
2
|
+
import { getEnvConfig, init, getClient, captureException, addBreadcrumb, captureMessage, setUser, setTag, setExtra } from '@bugwatch/core';
|
|
3
3
|
export { addBreadcrumb, captureException, captureMessage, getClient, init, setExtra, setTag, setUser } from '@bugwatch/core';
|
|
4
4
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
|
-
// src/index.tsx
|
|
7
6
|
var DEFAULT_REACT_OPTIONS = {
|
|
8
7
|
captureGlobalErrors: true,
|
|
9
8
|
captureUnhandledRejections: true,
|
|
@@ -31,28 +30,90 @@ function BugwatchProvider({
|
|
|
31
30
|
fallback,
|
|
32
31
|
onError
|
|
33
32
|
}) {
|
|
33
|
+
const optionsKey = useMemo(
|
|
34
|
+
() => options ? JSON.stringify(options) : "",
|
|
35
|
+
[options]
|
|
36
|
+
);
|
|
37
|
+
const optionsRef = useRef(options);
|
|
38
|
+
optionsRef.current = options;
|
|
34
39
|
useEffect(() => {
|
|
35
|
-
const
|
|
36
|
-
|
|
40
|
+
const currentOptions = optionsRef.current;
|
|
41
|
+
const envConfig = getEnvConfig();
|
|
42
|
+
const mergedOptions = { ...DEFAULT_REACT_OPTIONS, ...envConfig, ...currentOptions };
|
|
43
|
+
if (!mergedOptions.apiKey) {
|
|
44
|
+
if (process.env.NODE_ENV === "development") {
|
|
45
|
+
console.warn("[Bugwatch] No API key provided. Set BUGWATCH_API_KEY env var or pass options.apiKey");
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
init(mergedOptions);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
if (process.env.NODE_ENV === "development") {
|
|
53
|
+
console.error("[Bugwatch] Initialization failed:", err);
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
37
57
|
const client = getClient();
|
|
38
58
|
if (client) {
|
|
39
59
|
client.setTag("framework", "react");
|
|
40
60
|
}
|
|
61
|
+
let originalOnError = null;
|
|
62
|
+
let originalConsoleError = null;
|
|
63
|
+
let unhandledRejectionHandler = null;
|
|
41
64
|
if (typeof window !== "undefined") {
|
|
42
65
|
if (mergedOptions.captureGlobalErrors) {
|
|
43
|
-
|
|
66
|
+
originalOnError = window.onerror;
|
|
67
|
+
window.onerror = (message, source, lineno, colno, error) => {
|
|
68
|
+
if (error) {
|
|
69
|
+
captureException(error, {
|
|
70
|
+
tags: { mechanism: "window.onerror" }
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (originalOnError) {
|
|
74
|
+
return originalOnError(message, source, lineno, colno, error);
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
};
|
|
44
78
|
}
|
|
45
79
|
if (mergedOptions.captureUnhandledRejections) {
|
|
46
|
-
|
|
80
|
+
unhandledRejectionHandler = (event) => {
|
|
81
|
+
const error = event.reason instanceof Error ? event.reason : new Error(String(event.reason));
|
|
82
|
+
captureException(error, {
|
|
83
|
+
tags: { mechanism: "unhandledrejection" }
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
window.addEventListener("unhandledrejection", unhandledRejectionHandler);
|
|
47
87
|
}
|
|
48
88
|
if (mergedOptions.captureConsoleBreadcrumbs) {
|
|
49
|
-
|
|
89
|
+
originalConsoleError = console.error;
|
|
90
|
+
console.error = (...args) => {
|
|
91
|
+
addBreadcrumb({
|
|
92
|
+
category: "console",
|
|
93
|
+
message: args.map(String).join(" "),
|
|
94
|
+
level: "error"
|
|
95
|
+
});
|
|
96
|
+
originalConsoleError(...args);
|
|
97
|
+
};
|
|
50
98
|
}
|
|
51
99
|
}
|
|
52
100
|
if (mergedOptions.debug) {
|
|
53
101
|
console.log("[Bugwatch] React SDK initialized");
|
|
54
102
|
}
|
|
55
|
-
|
|
103
|
+
return () => {
|
|
104
|
+
if (typeof window !== "undefined") {
|
|
105
|
+
if (originalOnError !== null && mergedOptions.captureGlobalErrors) {
|
|
106
|
+
window.onerror = originalOnError;
|
|
107
|
+
}
|
|
108
|
+
if (unhandledRejectionHandler && mergedOptions.captureUnhandledRejections) {
|
|
109
|
+
window.removeEventListener("unhandledrejection", unhandledRejectionHandler);
|
|
110
|
+
}
|
|
111
|
+
if (originalConsoleError !== null && mergedOptions.captureConsoleBreadcrumbs) {
|
|
112
|
+
console.error = originalConsoleError;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}, [optionsKey]);
|
|
56
117
|
const captureException2 = useCallback(
|
|
57
118
|
(error, context) => {
|
|
58
119
|
return captureException(error, context);
|
|
@@ -80,15 +141,18 @@ function BugwatchProvider({
|
|
|
80
141
|
const setExtra2 = useCallback((key, value) => {
|
|
81
142
|
setExtra(key, value);
|
|
82
143
|
}, []);
|
|
83
|
-
const contextValue =
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
144
|
+
const contextValue = useMemo(
|
|
145
|
+
() => ({
|
|
146
|
+
client: getClient(),
|
|
147
|
+
captureException: captureException2,
|
|
148
|
+
captureMessage: captureMessage2,
|
|
149
|
+
addBreadcrumb: addBreadcrumb2,
|
|
150
|
+
setUser: setUser2,
|
|
151
|
+
setTag: setTag2,
|
|
152
|
+
setExtra: setExtra2
|
|
153
|
+
}),
|
|
154
|
+
[captureException2, captureMessage2, addBreadcrumb2, setUser2, setTag2, setExtra2]
|
|
155
|
+
);
|
|
92
156
|
return /* @__PURE__ */ jsx(BugwatchContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(ErrorBoundary, { fallback, onError, children }) });
|
|
93
157
|
}
|
|
94
158
|
var ErrorBoundary = class extends Component {
|
|
@@ -134,39 +198,6 @@ function withBugwatchErrorBoundary(WrappedComponent, options) {
|
|
|
134
198
|
WithErrorBoundary.displayName = `withBugwatchErrorBoundary(${WrappedComponent.displayName || WrappedComponent.name || "Component"})`;
|
|
135
199
|
return WithErrorBoundary;
|
|
136
200
|
}
|
|
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
201
|
|
|
171
202
|
export { ErrorBoundary as BugwatchErrorBoundary, BugwatchProvider, useBugwatch, useCaptureException, useCaptureMessage, withBugwatchErrorBoundary };
|
|
172
203
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +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"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"names":["captureException","captureMessage","coreInit","coreCaptureException","coreAddBreadcrumb","coreCaptureMessage","addBreadcrumb","setUser","coreSetUser","setTag","coreSetTag","setExtra","coreSetExtra"],"mappings":"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","file":"index.mjs","sourcesContent":["\"use client\";\n\nimport React, {\n Component,\n createContext,\n useContext,\n useEffect,\n useCallback,\n useRef,\n useMemo,\n type ReactNode,\n type ErrorInfo,\n} from \"react\";\nimport {\n init as coreInit,\n getClient,\n getEnvConfig,\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 /**\n * SDK configuration options.\n * Optional - if not provided, reads from environment variables:\n * - `BUGWATCH_API_KEY` - API key (required unless passed explicitly)\n * - `BUGWATCH_ENVIRONMENT` - Environment tag\n * - `BUGWATCH_RELEASE` - Release version\n * - `BUGWATCH_DEBUG` - Enable debug mode ('true')\n */\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 *\n * @example\n * ```tsx\n * // With BUGWATCH_API_KEY env var set\n * <BugwatchProvider>\n * <App />\n * </BugwatchProvider>\n *\n * // With explicit options\n * <BugwatchProvider options={{ apiKey: \"bw_live_xxxxx\" }}>\n * <App />\n * </BugwatchProvider>\n * ```\n */\nexport function BugwatchProvider({\n options,\n children,\n fallback,\n onError,\n}: BugwatchProviderProps): JSX.Element {\n // Serialize options to a stable string so useEffect doesn't re-run on every render.\n // Object identity of `options` changes every render if passed inline.\n const optionsKey = useMemo(\n () => (options ? JSON.stringify(options) : \"\"),\n [options]\n );\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n useEffect(() => {\n const currentOptions = optionsRef.current;\n\n // Merge env config with explicit options (explicit takes precedence)\n const envConfig = getEnvConfig();\n const mergedOptions = { ...DEFAULT_REACT_OPTIONS, ...envConfig, ...currentOptions };\n\n // Skip initialization if no API key is available\n if (!mergedOptions.apiKey) {\n if (process.env.NODE_ENV === 'development') {\n console.warn('[Bugwatch] No API key provided. Set BUGWATCH_API_KEY env var or pass options.apiKey');\n }\n return;\n }\n\n // Wrap initialization in try-catch for graceful degradation\n try {\n coreInit(mergedOptions);\n } catch (err) {\n if (process.env.NODE_ENV === 'development') {\n console.error('[Bugwatch] Initialization failed:', err);\n }\n return;\n }\n\n // Add React-specific tags\n const client = getClient();\n if (client) {\n client.setTag(\"framework\", \"react\");\n }\n\n // Store original handlers for cleanup\n let originalOnError: typeof window.onerror | null = null;\n let originalConsoleError: typeof console.error | null = null;\n let unhandledRejectionHandler: ((event: PromiseRejectionEvent) => void) | null = null;\n\n // Set up global error handlers\n if (typeof window !== \"undefined\") {\n if (mergedOptions.captureGlobalErrors) {\n originalOnError = window.onerror;\n window.onerror = (message, source, lineno, colno, error) => {\n if (error) {\n coreCaptureException(error, {\n tags: { mechanism: \"window.onerror\" },\n });\n }\n if (originalOnError) {\n return originalOnError(message, source, lineno, colno, error);\n }\n return false;\n };\n }\n\n if (mergedOptions.captureUnhandledRejections) {\n unhandledRejectionHandler = (event: PromiseRejectionEvent) => {\n const error =\n event.reason instanceof Error\n ? event.reason\n : new Error(String(event.reason));\n coreCaptureException(error, {\n tags: { mechanism: \"unhandledrejection\" },\n });\n };\n window.addEventListener(\"unhandledrejection\", unhandledRejectionHandler);\n }\n\n if (mergedOptions.captureConsoleBreadcrumbs) {\n originalConsoleError = console.error;\n console.error = (...args: unknown[]) => {\n coreAddBreadcrumb({\n category: \"console\",\n message: args.map(String).join(\" \"),\n level: \"error\",\n });\n originalConsoleError!(...args);\n };\n }\n }\n\n if (mergedOptions.debug) {\n console.log(\"[Bugwatch] React SDK initialized\");\n }\n\n // Cleanup function to prevent memory leaks\n return () => {\n if (typeof window !== \"undefined\") {\n // Restore original window.onerror\n if (originalOnError !== null && mergedOptions.captureGlobalErrors) {\n window.onerror = originalOnError;\n }\n\n // Remove unhandled rejection listener\n if (unhandledRejectionHandler && mergedOptions.captureUnhandledRejections) {\n window.removeEventListener(\"unhandledrejection\", unhandledRejectionHandler);\n }\n\n // Restore original console.error\n if (originalConsoleError !== null && mergedOptions.captureConsoleBreadcrumbs) {\n console.error = originalConsoleError;\n }\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [optionsKey]);\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 // Memoize context value to prevent unnecessary re-renders\n const contextValue = useMemo<BugwatchContextValue>(\n () => ({\n client: getClient(),\n captureException,\n captureMessage,\n addBreadcrumb,\n setUser,\n setTag,\n setExtra,\n }),\n [captureException, captureMessage, addBreadcrumb, setUser, setTag, 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// 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"]}
|