"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var React = require("react");
var mobx_1 = require("mobx");
exports.ErrorMessage = function () { return (React.createElement("div", { css: {
        margin: 15,
        borderRadius: 4,
        border: '1px solid rgba(150, 0, 0, 0.35)',
        color: 'rgba(150, 0, 0, 1)',
        backgroundColor: 'rgba(255, 0, 0, 0.1)',
        padding: 15,
        fontSize: 14,
        textAlign: 'center',
    } },
    "Oh no! We had an error :( Try",
    ' ',
    React.createElement("a", { onClick: function () { return location.reload(); }, css: { color: 'steelblue', cursor: 'pointer', fontWeight: 'bold' } }, "refreshing this page"),
    ' ',
    "and",
    ' ',
    React.createElement("a", { css: { color: 'steelblue', cursor: 'pointer', fontWeight: 'bold' }, onClick: function () {
            window.Intercom('showNewMesage', 'I am getting an error - please help');
        } }, "chat us"),
    ' ',
    "or contact",
    ' ',
    React.createElement("a", { css: { color: 'steelblue', cursor: 'pointer', fontWeight: 'bold' }, target: "_blank", href: "mailto:help@builder.io" }, "help@builder.io"),
    ' ',
    "if this continues")); };
/**
 * Provides error boundaries for safety (one component errors won't crash the whole app)
 * and adds some methods for safe handling of subscriptions and reactions (that
 * unsubscribe when the component is destroyed)
 */
var SafeComponent = /** @class */ (function (_super) {
    __extends(SafeComponent, _super);
    function SafeComponent() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this._unMounted = false;
        _this.unmountDestroyers = [];
        return _this;
    }
    // TODO: add back
    SafeComponent.prototype.componentDidCatch = function (error, errorInfo) {
        console.error('Component error:', error, errorInfo);
        this.render = function () { return React.createElement(exports.ErrorMessage, null); };
        this.setState({ __hasError: true });
    };
    SafeComponent.prototype.onDestroy = function (cb) {
        if (this._unMounted) {
            // TODO: nextTick? like promise for consistency
            cb();
        }
        else {
            this.unmountDestroyers.push(cb);
        }
    };
    // For use in react components
    SafeComponent.prototype.componentWillUnmount = function () {
        this._unMounted = true;
        if (_super.prototype.componentWillUnmount) {
            _super.prototype.componentWillUnmount.call(this);
        }
        // FIXME: devs will likely not call super on this hook as they won't know they need to
        // and that will cause subscription leaks. Better way to do with decorators perhaps?
        for (var _i = 0, _a = this.unmountDestroyers; _i < _a.length; _i++) {
            var destroyer = _a[_i];
            destroyer();
        }
    };
    // TODO: metadata ways of doing this
    SafeComponent.prototype.safeListenToEvent = function (target, event, handler, options) {
        var actionBoundHandler = mobx_1.action(handler);
        target.addEventListener(event, actionBoundHandler, options);
        this.onDestroy(function () {
            target.removeEventListener(event, actionBoundHandler);
        });
    };
    // TODO: metadata way of doing this
    // @reactions(self => [])
    SafeComponent.prototype.safeReaction = function (watchFunction, reactionFunction, options) {
        if (options === void 0) { options = {
            fireImmediately: true,
        }; }
        this.onDestroy(mobx_1.reaction(watchFunction, reactionFunction, options));
    };
    return SafeComponent;
}(React.Component));
exports.SafeComponent = SafeComponent;
//# sourceMappingURL=safe-component.js.map