"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.withRootStore = exports.getRendererByName = exports.getRenderers = exports.resolveRenderer = exports.updateEnv = exports.clearStoresCache = exports.render = exports.HocStoreFactory = exports.ScopedRootRenderer = exports.RootRenderer = exports.RootStoreContext = exports.renderChild = exports.renderChildren = exports.unRegisterRenderer = exports.registerRenderer = exports.Renderer = exports.filterSchema = exports.addSchemaFilter = void 0;
var tslib_1 = require("tslib");
var react_1 = tslib_1.__importDefault(require("react"));
var qs_1 = tslib_1.__importDefault(require("qs"));
var index_1 = require("./store/index");
var mobx_state_tree_1 = require("mobx-state-tree");
var api_1 = require("./utils/api");
var helper_1 = require("./utils/helper");
var mobx_react_1 = require("mobx-react");
var filter_schema_1 = tslib_1.__importDefault(require("./utils/filter-schema"));
var hoist_non_react_statics_1 = tslib_1.__importDefault(require("hoist-non-react-statics"));
var omit_1 = tslib_1.__importDefault(require("lodash/omit"));
var difference_1 = tslib_1.__importDefault(require("lodash/difference"));
var isPlainObject_1 = tslib_1.__importDefault(require("lodash/isPlainObject"));
var Scoped_1 = tslib_1.__importDefault(require("./Scoped"));
var theme_1 = require("./theme");
var find_1 = tslib_1.__importDefault(require("lodash/find"));
var Alert2_1 = tslib_1.__importDefault(require("./components/Alert2"));
var components_1 = require("./components");
var ImageGallery_1 = tslib_1.__importDefault(require("./components/ImageGallery"));
var locale_1 = require("./locale");
var renderers = [];
var rendererNames = [];
var schemaFilters = [];
var anonymousIndex = 1;
function addSchemaFilter(fn) {
    schemaFilters.push(fn);
}
exports.addSchemaFilter = addSchemaFilter;
function filterSchema(schema, render, props) {
    return schemaFilters.reduce(function (schema, filter) { return filter(schema, render, props); }, schema);
}
exports.filterSchema = filterSchema;
function Renderer(config) {
    return function (component) {
        var renderer = registerRenderer(tslib_1.__assign(tslib_1.__assign({}, config), { component: component }));
        return renderer.component;
    };
}
exports.Renderer = Renderer;
function registerRenderer(config) {
    if (!config.test) {
        throw new TypeError('config.test is required');
    }
    else if (!config.component) {
        throw new TypeError('config.component is required');
    }
    config.weight = config.weight || 0;
    config.Renderer = config.component;
    config.name = config.name || "anonymous-" + anonymousIndex++;
    if (~rendererNames.indexOf(config.name)) {
        throw new Error("The renderer with name \"" + config.name + "\" has already exists, please try another name!");
    }
    if (config.storeType && config.component) {
        config.component = HocStoreFactory({
            storeType: config.storeType,
            extendsData: config.storeExtendsData,
            shouldSyncSuperStore: config.shouldSyncSuperStore
        })(mobx_react_1.observer(config.component));
    }
    if (config.isolateScope) {
        config.component = Scoped_1.default(config.component);
    }
    var idx = helper_1.findIndex(renderers, function (item) { return config.weight < item.weight; });
    ~idx ? renderers.splice(idx, 0, config) : renderers.push(config);
    rendererNames.push(config.name);
    return config;
}
exports.registerRenderer = registerRenderer;
function unRegisterRenderer(config) {
    var idx = typeof config === 'string'
        ? helper_1.findIndex(renderers, function (item) { return item.name === config; })
        : renderers.indexOf(config);
    ~idx && renderers.splice(idx, 1);
    // 清空渲染器定位缓存
    cache = {};
}
exports.unRegisterRenderer = unRegisterRenderer;
function renderChildren(prefix, node, props) {
    if (Array.isArray(node)) {
        return node.map(function (node, index) {
            return renderChild(prefix + "/" + index, node, tslib_1.__assign(tslib_1.__assign({}, props), { key: "" + (props.key ? props.key + "-" : '') + index }));
        });
    }
    return renderChild(prefix, node, props);
}
exports.renderChildren = renderChildren;
function renderChild(prefix, node, props) {
    if (Array.isArray(node)) {
        return renderChildren(prefix, node, props);
    }
    var typeofnode = typeof node;
    var schema = typeofnode === 'string' || typeofnode === 'number'
        ? { type: 'tpl', tpl: String(node) }
        : node;
    var detectData = schema.detectField === '&' ? props : props[schema.detectField || 'data'];
    var exprProps = detectData ? filter_schema_1.default(schema, detectData) : null;
    if (exprProps &&
        (exprProps.hidden ||
            exprProps.visible === false ||
            schema.hidden ||
            schema.visible === false ||
            props.hidden ||
            props.visible === false)) {
        return null;
    }
    var transform = props.propsTransform;
    if (transform) {
        // @ts-ignore
        delete props.propsTransform;
        props = transform(props);
    }
    return (react_1.default.createElement(SchemaRenderer, tslib_1.__assign({}, props, exprProps, { schema: schema, "$path": "" + (prefix ? prefix + "/" : '') + ((schema && schema.type) || '') })));
}
exports.renderChild = renderChild;
exports.RootStoreContext = react_1.default.createContext(undefined);
var RootRenderer = /** @class */ (function (_super) {
    tslib_1.__extends(RootRenderer, _super);
    function RootRenderer() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.state = {
            error: null,
            errorInfo: null
        };
        return _this;
    }
    RootRenderer.prototype.componentDidCatch = function (error, errorInfo) {
        console.error(error);
        this.setState({
            error: error,
            errorInfo: errorInfo
        });
    };
    RootRenderer.prototype.resolveDefinitions = function (name) {
        var definitions = this.props.schema.definitions;
        if (!name || helper_1.isEmpty(definitions)) {
            return {};
        }
        return definitions && definitions[name];
    };
    RootRenderer.prototype.render = function () {
        var _a = this.state, error = _a.error, errorInfo = _a.errorInfo;
        if (errorInfo) {
            return errorRenderer(error, errorInfo);
        }
        var _b = this.props, schema = _b.schema, rootStore = _b.rootStore, env = _b.env, pathPrefix = _b.pathPrefix, location = _b.location, data = _b.data, locale = _b.locale, translate = _b.translate, rest = tslib_1.__rest(_b, ["schema", "rootStore", "env", "pathPrefix", "location", "data", "locale", "translate"]);
        var theme = env.theme;
        var query = (location && location.query) ||
            (location && location.search && qs_1.default.parse(location.search.substring(1))) ||
            (window.location.search && qs_1.default.parse(window.location.search.substring(1)));
        var finalData = query
            ? helper_1.createObject(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, (data && data.__super ? data.__super : null)), query), { __query: query }), data)
            : data;
        return (react_1.default.createElement(exports.RootStoreContext.Provider, { value: rootStore },
            react_1.default.createElement(theme_1.ThemeContext.Provider, { value: this.props.theme || 'default' },
                react_1.default.createElement(locale_1.LocaleContext.Provider, { value: this.props.locale },
                    react_1.default.createElement(ImageGallery_1.default, { modalContainer: env.getModalContainer }, renderChild(pathPrefix || '', isPlainObject_1.default(schema)
                        ? tslib_1.__assign({ type: 'page' }, schema) : schema, tslib_1.__assign(tslib_1.__assign({}, rest), { resolveDefinitions: this.resolveDefinitions, location: location, data: finalData, env: env, classnames: theme.classnames, classPrefix: theme.classPrefix, locale: locale,
                        translate: translate })))))));
    };
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", [String]),
        tslib_1.__metadata("design:returntype", void 0)
    ], RootRenderer.prototype, "resolveDefinitions", null);
    return RootRenderer;
}(react_1.default.Component));
exports.RootRenderer = RootRenderer;
exports.ScopedRootRenderer = Scoped_1.default(RootRenderer);
var defaultOmitList = [
    'type',
    'name',
    '$ref',
    'className',
    'data',
    'children',
    'ref',
    'visible',
    'visibleOn',
    'hidden',
    'hiddenOn',
    'disabled',
    'disabledOn',
    'component',
    'detectField',
    'required',
    'requiredOn',
    'syncSuperStore'
];
var SchemaRenderer = /** @class */ (function (_super) {
    tslib_1.__extends(SchemaRenderer, _super);
    function SchemaRenderer(props) {
        var _this = _super.call(this, props) || this;
        _this.refFn = _this.refFn.bind(_this);
        _this.renderChild = _this.renderChild.bind(_this);
        _this.reRender = _this.reRender.bind(_this);
        return _this;
    }
    SchemaRenderer.prototype.componentWillMount = function () {
        this.resolveRenderer(this.props);
    };
    SchemaRenderer.prototype.componentWillReceiveProps = function (nextProps) {
        var props = this.props;
        if (props.schema.type !== nextProps.schema.type ||
            props.schema.$$id !== nextProps.schema.$$id) {
            this.resolveRenderer(nextProps);
        }
    };
    // 限制：只有 schema 除外的 props 变化，或者 schema 里面的某个成员值发生变化才更新。
    SchemaRenderer.prototype.shouldComponentUpdate = function (nextProps) {
        var props = this.props;
        var list = difference_1.default(Object.keys(nextProps), [
            'schema',
            'scope'
        ]);
        if (difference_1.default(Object.keys(props), ['schema', 'scope']).length !==
            list.length ||
            helper_1.anyChanged(list, this.props, nextProps)) {
            return true;
        }
        else {
            var list_1 = Object.keys(nextProps.schema);
            if (Object.keys(props.schema).length !== list_1.length ||
                helper_1.anyChanged(list_1, props.schema, nextProps.schema)) {
                return true;
            }
        }
        return false;
    };
    SchemaRenderer.prototype.resolveRenderer = function (props) {
        var schema = props.schema;
        var path = props.$path;
        var rendererResolver = props.env.rendererResolver || resolveRenderer;
        if (schema.$ref) {
            schema = tslib_1.__assign(tslib_1.__assign({}, props.resolveDefinitions(schema.$ref)), schema);
            // @ts-ignore
            delete schema.$ref;
            path = path.replace(/(?!.*\/).*/, schema.type);
        }
        // value 会提前从 control 中获取到，所有需要把control中的属性也补充完整
        // if (schema.control && schema.control.$ref) {
        //     schema.control = {
        //         ...props.resolveDefinitions(schema.control.$ref),
        //         ...schema.control
        //     }
        //     delete schema.control.$ref;
        // }
        this.renderer = rendererResolver(path, schema, props);
        return schema;
    };
    SchemaRenderer.prototype.getWrappedInstance = function () {
        return this.ref;
    };
    SchemaRenderer.prototype.refFn = function (ref) {
        this.ref = ref;
    };
    SchemaRenderer.prototype.renderChild = function (region, node, subProps) {
        if (subProps === void 0) { subProps = {}; }
        var _a = this.props, schema = _a.schema, $path = _a.$path, env = _a.env, rest = tslib_1.__rest(_a, ["schema", "$path", "env"]);
        var omitList = defaultOmitList.concat();
        if (this.renderer) {
            var Component = this.renderer.component;
            Component.propsList &&
                omitList.push.apply(omitList, Component.propsList);
        }
        return renderChild("" + $path + (region ? "/" + region : ''), node || '', tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, omit_1.default(rest, omitList)), subProps), { data: subProps.data || rest.data, env: env }));
    };
    SchemaRenderer.prototype.reRender = function () {
        this.resolveRenderer(this.props);
        this.forceUpdate();
    };
    SchemaRenderer.prototype.render = function () {
        var _this = this;
        var _a = this.props, $path = _a.$path, schema = _a.schema, rest = tslib_1.__rest(_a, ["$path", "schema"]);
        if (schema.$ref) {
            schema = this.resolveRenderer(this.props);
        }
        var theme = this.props.env.theme;
        if (Array.isArray(schema)) {
            return renderChildren($path, schema, rest);
        }
        else if (schema.children) {
            return react_1.default.isValidElement(schema.children)
                ? schema.children
                : schema.children(tslib_1.__assign(tslib_1.__assign({}, rest), { $path: $path, render: this.renderChild, forwardedRef: this.refFn }));
        }
        else if (typeof schema.component === 'function') {
            var isSFC = !(schema.component.prototype instanceof react_1.default.Component);
            return react_1.default.createElement(schema.component, tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, rest), schema), { $path: $path, ref: isSFC ? undefined : this.refFn, forwardedRef: isSFC ? this.refFn : undefined, render: this.renderChild }));
        }
        else if (!this.renderer) {
            return (react_1.default.createElement(components_1.LazyComponent, tslib_1.__assign({}, rest, { getComponent: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
                    var result;
                    return tslib_1.__generator(this, function (_a) {
                        switch (_a.label) {
                            case 0: return [4 /*yield*/, rest.env.loadRenderer(schema, $path, this.reRender)];
                            case 1:
                                result = _a.sent();
                                if (result && typeof result === 'function') {
                                    return [2 /*return*/, result];
                                }
                                else if (result && react_1.default.isValidElement(result)) {
                                    return [2 /*return*/, function () { return result; }];
                                }
                                this.reRender();
                                return [2 /*return*/, function () { return loadRenderer(schema, $path); }];
                        }
                    });
                }); }, "$path": $path, retry: this.reRender })));
        }
        var renderer = this.renderer;
        schema = filterSchema(schema, renderer, rest);
        var defaultData = schema.data, restSchema = tslib_1.__rest(schema, ["data"]);
        var Component = renderer.component;
        return (react_1.default.createElement(Component, tslib_1.__assign({}, theme.getRendererConfig(renderer.name), restSchema, helper_1.chainEvents(rest, restSchema), { defaultData: defaultData, "$path": $path, ref: this.refFn, render: this.renderChild })));
    };
    SchemaRenderer.displayName = 'Renderer';
    return SchemaRenderer;
}(react_1.default.Component));
function HocStoreFactory(renderer) {
    return function (Component) {
        var StoreFactory = /** @class */ (function (_super) {
            tslib_1.__extends(StoreFactory, _super);
            function StoreFactory() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            StoreFactory.prototype.getWrappedInstance = function () {
                return this.ref;
            };
            StoreFactory.prototype.refFn = function (ref) {
                this.ref = ref;
            };
            StoreFactory.prototype.formatData = function (data) {
                if (Array.isArray(data)) {
                    return {
                        items: data
                    };
                }
                return data;
            };
            StoreFactory.prototype.componentWillMount = function () {
                var rootStore = this.context;
                this.renderChild = this.renderChild.bind(this);
                this.refFn = this.refFn.bind(this);
                var store = rootStore.addStore({
                    id: helper_1.guid(),
                    path: this.props.$path,
                    storeType: renderer.storeType,
                    parentId: this.props.store ? this.props.store.id : ''
                });
                this.store = store;
                if (renderer.extendsData === false) {
                    store.initData(helper_1.createObject(this.props.data
                        ? this.props.data.__super
                        : null, tslib_1.__assign(tslib_1.__assign({}, this.formatData(this.props.defaultData)), this.formatData(this.props.data))));
                }
                else if (this.props.scope ||
                    (this.props.data && this.props.data.__super)) {
                    if (this.props.store && this.props.data === this.props.store.data) {
                        store.initData(helper_1.createObject(this.props.store.data, tslib_1.__assign({}, this.formatData(this.props.defaultData))));
                    }
                    else {
                        store.initData(helper_1.createObject(this.props.data.__super || this.props.scope, tslib_1.__assign(tslib_1.__assign({}, this.formatData(this.props.defaultData)), this.formatData(this.props.data))));
                    }
                }
                else {
                    store.initData(tslib_1.__assign(tslib_1.__assign({}, this.formatData(this.props.defaultData)), this.formatData(this.props.data)));
                }
            };
            StoreFactory.prototype.componentWillReceiveProps = function (nextProps) {
                var _a;
                var props = this.props;
                var store = this.store;
                var shouldSync = (_a = renderer.shouldSyncSuperStore) === null || _a === void 0 ? void 0 : _a.call(renderer, store, nextProps, props);
                if (shouldSync === false) {
                    return;
                }
                if (renderer.extendsData === false) {
                    if (shouldSync === true ||
                        props.defaultData !== nextProps.defaultData ||
                        helper_1.isObjectShallowModified(props.data, nextProps.data) ||
                        //
                        // 特殊处理 CRUD。
                        // CRUD 中 toolbar 里面的 data 是空对象，但是 __super 会不一样
                        (nextProps.data &&
                            props.data &&
                            nextProps.data.__super !== props.data.__super)) {
                        store.initData(helper_1.extendObject(nextProps.data, tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, (store.hasRemoteData ? store.data : null)), this.formatData(nextProps.defaultData)), this.formatData(nextProps.data))));
                    }
                }
                else if (shouldSync === true ||
                    helper_1.isObjectShallowModified(props.data, nextProps.data)) {
                    if (nextProps.store && nextProps.store.data === nextProps.data) {
                        store.initData(helper_1.createObject(nextProps.store.data, nextProps.syncSuperStore === false
                            ? tslib_1.__assign({}, store.data) : helper_1.syncDataFromSuper(store.data, nextProps.store.data, props.scope, store, nextProps.syncSuperStore === true)));
                    }
                    else if (nextProps.data && nextProps.data.__super) {
                        store.initData(helper_1.extendObject(nextProps.data));
                    }
                    else {
                        store.initData(helper_1.createObject(nextProps.scope, nextProps.data));
                    }
                }
                else if ((shouldSync === true ||
                    !nextProps.store ||
                    nextProps.data !== nextProps.store.data) &&
                    nextProps.data &&
                    nextProps.data.__super) {
                    // 这个用法很少，当 data.__super 值发生变化时，更新 store.data
                    (!props.data ||
                        helper_1.isObjectShallowModified(nextProps.data.__super, props.data.__super, false)) &&
                        // nextProps.data.__super !== props.data.__super) &&
                        store.initData(helper_1.createObject(nextProps.data.__super, tslib_1.__assign(tslib_1.__assign({}, nextProps.data), store.data)));
                }
                else if (nextProps.scope &&
                    nextProps.data === nextProps.store.data &&
                    (shouldSync === true || props.data !== nextProps.data)) {
                    store.initData(helper_1.createObject(nextProps.scope, tslib_1.__assign({}, store.data)));
                }
            };
            StoreFactory.prototype.componentWillUnmount = function () {
                var rootStore = this.context;
                var store = this.store;
                rootStore.removeStore(store);
                // @ts-ignore
                delete this.store;
            };
            StoreFactory.prototype.renderChild = function (region, node, subProps) {
                if (subProps === void 0) { subProps = {}; }
                var render = this.props.render;
                return render(region, node, tslib_1.__assign(tslib_1.__assign({ data: this.store.data, dataUpdatedAt: this.store.updatedAt }, subProps), { scope: this.store.data, store: this.store }));
            };
            StoreFactory.prototype.render = function () {
                var _a = this.props, detectField = _a.detectField, rest = tslib_1.__rest(_a, ["detectField"]);
                var exprProps = {};
                if (!detectField || detectField === 'data') {
                    exprProps = filter_schema_1.default(rest, this.store.data);
                    if (exprProps.hidden || exprProps.visible === false) {
                        return null;
                    }
                }
                return (react_1.default.createElement(Component, tslib_1.__assign({}, rest /* todo */, exprProps, { ref: this.refFn, data: this.store.data, dataUpdatedAt: this.store.updatedAt, store: this.store, scope: this.store.data, render: this.renderChild })));
            };
            StoreFactory.displayName = "WithStore(" + (Component.displayName || Component.name) + ")";
            StoreFactory.ComposedComponent = Component;
            StoreFactory.contextType = exports.RootStoreContext;
            StoreFactory = tslib_1.__decorate([
                mobx_react_1.observer
            ], StoreFactory);
            return StoreFactory;
        }(react_1.default.Component));
        hoist_non_react_statics_1.default(StoreFactory, Component);
        return StoreFactory;
    };
}
exports.HocStoreFactory = HocStoreFactory;
function loadRenderer(schema, path) {
    return (react_1.default.createElement(Alert2_1.default, { level: "danger" },
        react_1.default.createElement("p", null, "Error: \u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6E32\u67D3\u5668"),
        react_1.default.createElement("p", null,
            "Path: ",
            path),
        react_1.default.createElement("pre", null,
            react_1.default.createElement("code", null, JSON.stringify(schema, null, 2)))));
}
function errorRenderer(error, errorInfo) {
    return (react_1.default.createElement(Alert2_1.default, { level: "danger" },
        react_1.default.createElement("p", null, error && error.toString()),
        react_1.default.createElement("pre", null,
            react_1.default.createElement("code", null, errorInfo.componentStack))));
}
var defaultOptions = {
    session: 'global',
    affixOffsetTop: 50,
    affixOffsetBottom: 0,
    richTextToken: '',
    loadRenderer: loadRenderer,
    fetcher: function () {
        return Promise.reject('fetcher is required');
    },
    isCancel: function () {
        console.error('Please implements this. see https://baidu.gitee.io/amis/docs/start/getting-started#%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97');
        return false;
    },
    alert: function (msg) {
        alert(msg);
    },
    updateLocation: function () {
        console.error('Please implements this. see https://baidu.gitee.io/amis/docs/start/getting-started#%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97');
    },
    confirm: function (msg) {
        return confirm(msg);
    },
    notify: function (msg) {
        alert(msg);
    },
    jumpTo: function () {
        console.error('Please implements this. see https://baidu.gitee.io/amis/docs/start/getting-started#%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97');
    },
    isCurrentUrl: function () {
        return false;
    },
    copy: function (contents) {
        console.error('copy contents', contents);
    },
    rendererResolver: resolveRenderer
};
var stores = {};
function render(schema, props, options, pathPrefix) {
    if (props === void 0) { props = {}; }
    if (options === void 0) { options = {}; }
    if (pathPrefix === void 0) { pathPrefix = ''; }
    var locale = props.locale || locale_1.getDefaultLocale();
    var translate = props.translate || locale_1.makeTranslator(locale);
    var store = stores[options.session || 'global'];
    if (!store) {
        options = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, defaultOptions), options), { fetcher: options.fetcher
                ? api_1.wrapFetcher(options.fetcher)
                : defaultOptions.fetcher, confirm: options.confirm
                ? helper_1.promisify(options.confirm)
                : defaultOptions.confirm, locale: locale,
            translate: translate });
        store = index_1.RendererStore.create({}, options);
        stores[options.session || 'global'] = store;
    }
    window.amisStore = store; // 为了方便 debug.
    var env = mobx_state_tree_1.getEnv(store);
    var theme = props.theme || options.theme || 'default';
    env.theme = theme_1.getTheme(theme);
    if (props.locale !== undefined) {
        env.translate = translate;
        env.locale = locale;
    }
    return (react_1.default.createElement(exports.ScopedRootRenderer, tslib_1.__assign({}, props, { schema: schema, pathPrefix: pathPrefix, rootStore: store, env: env, theme: theme, locale: locale, translate: translate })));
}
exports.render = render;
// 默认 env 会被缓存，所以新传入的 env 不会替换旧的。
// 除非先删了旧的，新的才会生效。
function clearStoresCache(sessions) {
    if (sessions === void 0) { sessions = Object.keys(stores); }
    if (!Array.isArray(sessions)) {
        sessions = [sessions];
    }
    sessions.forEach(function (key) {
        var store = stores[key];
        // @ts-ignore
        delete stores[key];
        store && mobx_state_tree_1.destroy(store);
    });
}
exports.clearStoresCache = clearStoresCache;
// 当然也可以直接这样更新。
// 主要是有时候第一创建的时候并没有准备多少接口，
// 可以后续补充点，比如 amis 自己实现的，prompt 里面的表单。
function updateEnv(options, session) {
    if (session === void 0) { session = 'global'; }
    options = tslib_1.__assign({}, options);
    if (options.fetcher) {
        options.fetcher = api_1.wrapFetcher(options.fetcher);
    }
    if (options.confirm) {
        options.confirm = helper_1.promisify(options.confirm);
    }
    var store = stores[options.session || session];
    if (!store) {
        store = index_1.RendererStore.create({}, options);
        stores[options.session || session] = store;
    }
    else {
        var env = mobx_state_tree_1.getEnv(store);
        Object.assign(env, options);
    }
}
exports.updateEnv = updateEnv;
var cache = {};
function resolveRenderer(path, schema, props) {
    if (cache[path]) {
        return cache[path];
    }
    else if (path && path.length > 1024) {
        throw new Error('Path太长是不是死循环了？');
    }
    var renderer = null;
    renderers.some(function (item) {
        var matched = false;
        if (typeof item.test === 'function') {
            matched = item.test(path, schema, resolveRenderer);
        }
        else if (item.test instanceof RegExp) {
            matched = item.test.test(path);
        }
        if (matched) {
            renderer = item;
        }
        return matched;
    });
    // 只能缓存纯正则表达式的后者方法中没有用到第二个参数的，因为自定义 test 函数的有可能依赖 schema 的结果
    if (renderer !== null &&
        (renderer.test instanceof RegExp ||
            (typeof renderer.test === 'function' &&
                renderer.test.length < 2))) {
        cache[path] = renderer;
    }
    return renderer;
}
exports.resolveRenderer = resolveRenderer;
function getRenderers() {
    return renderers.concat();
}
exports.getRenderers = getRenderers;
function getRendererByName(name) {
    return find_1.default(renderers, function (item) { return item.name === name; });
}
exports.getRendererByName = getRendererByName;
function withRootStore(ComposedComponent) {
    var _a;
    var result = hoist_non_react_statics_1.default((_a = /** @class */ (function (_super) {
            tslib_1.__extends(class_1, _super);
            function class_1() {
                return _super !== null && _super.apply(this, arguments) || this;
            }
            class_1.prototype.render = function () {
                var rootStore = this.context;
                var injectedProps = {
                    rootStore: rootStore
                };
                return (react_1.default.createElement(ComposedComponent, tslib_1.__assign({}, this.props, injectedProps)));
            };
            return class_1;
        }(react_1.default.Component)),
        _a.displayName = "WithRootStore(" + (ComposedComponent.displayName || ComposedComponent.name) + ")",
        _a.contextType = exports.RootStoreContext,
        _a.ComposedComponent = ComposedComponent,
        _a), ComposedComponent);
    return result;
}
exports.withRootStore = withRootStore;
//# sourceMappingURL=./factory.js.map
