"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.reactErrorHandledRendering = void 0;
const react_1 = __importDefault(require("react"));
const react_dom_1 = __importDefault(require("react-dom"));
const client_1 = __importDefault(require("react-dom/client"));
const reactRootByContainer = new WeakMap();
const reactErrorHandledRendering = async (element, container) => {
    if (client_1.default.createRoot) {
        // react 18+
        const reactRoot = reactRootByContainer.get(container) || client_1.default.createRoot(container);
        reactRootByContainer.set(container, reactRoot);
        const cleanup = () => {
            reactRoot === null || reactRoot === void 0 ? void 0 : reactRoot.unmount();
            reactRootByContainer.delete(container);
        };
        try {
            await new Promise((resolve, reject) => {
                reactRoot === null || reactRoot === void 0 ? void 0 : reactRoot.render(react_1.default.createElement(ErrorBoundary, { onRender: resolve, reportError: reject }, element));
            });
        }
        catch (e) {
            cleanup();
            throw e;
        }
        return cleanup;
    }
    else {
        // react <18
        // eslint-disable-next-line react/no-deprecated
        const cleanup = () => react_dom_1.default.unmountComponentAtNode(container);
        try {
            await new Promise((resolve, reject) => {
                // eslint-disable-next-line react/no-deprecated
                react_dom_1.default.render(react_1.default.createElement(ErrorBoundary, { reportError: reject }, element), container, resolve);
            });
        }
        catch (e) {
            /**
             * If an error occurs during ReactDOM.render(), React 17 will keep
             * _reactRootContainer property attached to the container DOM node.
             * This property points to an a stale fiber object, which prevents
             * subsequent ReactDOM.render() calls from working.
             */
            cleanup();
            throw e;
        }
        return cleanup;
    }
};
exports.reactErrorHandledRendering = reactErrorHandledRendering;
class ErrorBoundary extends react_1.default.Component {
    constructor() {
        super(...arguments);
        this.state = { hasError: false };
    }
    static getDerivedStateFromError() {
        return { hasError: true };
    }
    componentDidCatch(error, errorInfo) {
        var _a, _b;
        (_b = (_a = this.props).reportError) === null || _b === void 0 ? void 0 : _b.call(_a, error, errorInfo);
    }
    componentDidMount() {
        var _a, _b;
        if (!this.state.hasError) {
            (_b = (_a = this.props).onRender) === null || _b === void 0 ? void 0 : _b.call(_a);
        }
    }
    componentDidUpdate() {
        var _a, _b;
        if (!this.state.hasError) {
            (_b = (_a = this.props).onRender) === null || _b === void 0 ? void 0 : _b.call(_a);
        }
    }
    render() {
        return this.state.hasError ? null : this.props.children;
    }
}
//# sourceMappingURL=react-error-handled-render.js.map