UNPKG

@suspensive/react

Version:

Suspensive interfaces for react

159 lines (156 loc) 7.4 kB
'use client'; Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const require_objectSpread2 = require('./_virtual/_@oxc-project_runtime@0.130.0/helpers/objectSpread2.cjs'); const require_SuspensiveError = require('./models/SuspensiveError.cjs'); const require_ErrorBoundaryGroup = require('./ErrorBoundaryGroup.cjs'); const require_hasResetKeysChanged = require('./utils/hasResetKeysChanged.cjs'); let react = require("react"); let react_jsx_runtime = require("react/jsx-runtime"); //#region src/ErrorBoundary.tsx const matchError = (errorMatcher, error) => { if (typeof errorMatcher === "boolean") return errorMatcher; if (typeof errorMatcher === "function") { try { if (errorMatcher === Error || errorMatcher.prototype instanceof Error) return error instanceof errorMatcher; } catch (_unused) {} try { if (error instanceof errorMatcher) return true; } catch (_unused2) {} try { return errorMatcher(error); } catch (_unused3) { return false; } } return false; }; const shouldCatchError = (shouldCatch, error) => Array.isArray(shouldCatch) ? shouldCatch.some((errorMatcher) => matchError(errorMatcher, error)) : matchError(shouldCatch, error); const initialErrorBoundaryState = { isError: false, error: null }; var BaseErrorBoundary = class extends react.Component { constructor(..._args) { super(..._args); this.state = initialErrorBoundaryState; this.reset = () => { var _this$props$onReset, _this$props; (_this$props$onReset = (_this$props = this.props).onReset) === null || _this$props$onReset === void 0 || _this$props$onReset.call(_this$props); this.setState(initialErrorBoundaryState); }; } static getDerivedStateFromError(error) { return { isError: true, error }; } componentDidUpdate(prevProps, prevState) { const { isError } = this.state; const { resetKeys } = this.props; if (isError && prevState.isError && require_hasResetKeysChanged.hasResetKeysChanged(prevProps.resetKeys, resetKeys)) this.reset(); } componentDidCatch(error, info) { var _this$props$onError, _this$props2; (_this$props$onError = (_this$props2 = this.props).onError) === null || _this$props$onError === void 0 || _this$props$onError.call(_this$props2, error, info); } render() { const { children, fallback, shouldCatch = true } = this.props; const { isError, error } = this.state; let childrenOrFallback = children; if (isError) { if (error instanceof require_SuspensiveError.SuspensiveError) throw error; if (error instanceof ErrorInFallback) throw error.originalError; if (!shouldCatchError(shouldCatch, error)) throw error; if (typeof fallback === "undefined") { if (process.env.NODE_ENV === "development") console.error("ErrorBoundary of @suspensive/react requires a defined fallback"); throw error; } const Fallback = fallback; childrenOrFallback = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FallbackBoundary, { children: typeof Fallback === "function" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Fallback, { error, reset: this.reset }) : Fallback }); } return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorBoundaryContext.Provider, { value: require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, this.state), {}, { reset: this.reset }), children: childrenOrFallback }); } }; var ErrorInFallback = class extends Error { constructor(originalError) { super(); this.originalError = originalError; } }; var FallbackBoundary = class extends react.Component { componentDidCatch(originalError) { throw originalError instanceof require_SuspensiveError.SuspensiveError ? originalError : new ErrorInFallback(originalError); } render() { return this.props.children; } }; /** * This component provides a simple and reusable wrapper that you can use to wrap around your components. Any rendering errors in your components hierarchy can then be gracefully handled. * @see {@link https://suspensive.org/docs/react/ErrorBoundary Suspensive Docs} */ const ErrorBoundary = Object.assign((0, react.forwardRef)(function ErrorBoundary(props, ref) { var _useContext; const { fallback, children, onError, onReset, resetKeys, shouldCatch } = props; const group = (_useContext = (0, react.useContext)(require_ErrorBoundaryGroup.ErrorBoundaryGroupContext)) !== null && _useContext !== void 0 ? _useContext : { resetKey: 0 }; const baseErrorBoundaryRef = (0, react.useRef)(null); (0, react.useImperativeHandle)(ref, () => ({ reset: () => { var _baseErrorBoundaryRef; return (_baseErrorBoundaryRef = baseErrorBoundaryRef.current) === null || _baseErrorBoundaryRef === void 0 ? void 0 : _baseErrorBoundaryRef.reset(); } })); return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BaseErrorBoundary, { shouldCatch, fallback, onError, onReset, resetKeys: [group.resetKey, ...resetKeys || []], ref: baseErrorBoundaryRef, children }); }), { displayName: "ErrorBoundary", with: (errorBoundaryProps, Component) => Object.assign((props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorBoundary, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, errorBoundaryProps), {}, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, require_objectSpread2._objectSpread2({}, props)) })), { displayName: `${ErrorBoundary.displayName}.with(${Component.displayName || Component.name || "Component"})` }), Consumer: ({ children }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: children(useErrorBoundary()) }) }); const ErrorBoundaryContext = Object.assign((0, react.createContext)(null), { displayName: "ErrorBoundaryContext" }); /** * This hook provides a simple and reusable wrapper that you can use to wrap around your components. Any rendering errors in your components hierarchy can then be gracefully handled. * @see {@link https://suspensive.org/docs/react/ErrorBoundary#useerrorboundary Suspensive Docs} */ const useErrorBoundary = () => { const [state, setState] = (0, react.useState)({ isError: false, error: null }); if (state.isError) throw state.error; const errorBoundary = (0, react.useContext)(ErrorBoundaryContext); require_SuspensiveError.SuspensiveError.assert(errorBoundary != null && !errorBoundary.isError, require_SuspensiveError.Message_useErrorBoundary_this_hook_should_be_called_in_ErrorBoundary_props_children); return (0, react.useMemo)(() => ({ setError: (error) => setState({ isError: true, error }) }), []); }; /** * This hook allows you to access the reset method and error objects without prop drilling. * @see {@link https://suspensive.org/docs/react/ErrorBoundary#useerrorboundaryfallbackprops Suspensive Docs} */ const useErrorBoundaryFallbackProps = () => { const errorBoundary = (0, react.useContext)(ErrorBoundaryContext); require_SuspensiveError.SuspensiveError.assert(errorBoundary != null && errorBoundary.isError, require_SuspensiveError.Message_useErrorBoundaryFallbackProps_this_hook_should_be_called_in_ErrorBoundary_props_fallback); return (0, react.useMemo)(() => ({ error: errorBoundary.error, reset: errorBoundary.reset }), [errorBoundary.error, errorBoundary.reset]); }; //#endregion exports.ErrorBoundary = ErrorBoundary; exports.useErrorBoundary = useErrorBoundary; exports.useErrorBoundaryFallbackProps = useErrorBoundaryFallbackProps; //# sourceMappingURL=ErrorBoundary.cjs.map