UNPKG

reactant

Version:

A framework for building React web applications

195 lines (192 loc) 7.32 kB
import { __spreadArray, __read, __assign, __values } from './node_modules/tslib/tslib.es6.js'; import React, { StrictMode } from 'react'; import { Provider } from 'react-redux'; import { createContainer, createStore, ViewModule, modulesKey, unsubscriptionsKey, getMetadata, METADATA_KEY, bindModules } from 'reactant-module'; var ContainerContext = React.createContext(null); /** * ## Description * * You can create an app with `createApp()` passing app configuration, * which will return an object including `instance`, `store`, * and `bootstrap()` method(You can run `bootstrap` to start the app inject into the browser or mobile). * * ## Example * * ```typescript * import { createApp, injectable } from 'reactant'; * * @injectable() * class Foo {} * * const app = createApp({ * modules: [], * main: Foo, * render: () => {}, * }); * * expect(app.instance instanceof Foo).toBeTruthy(); * ``` */ function createApp(_a) { var /** * As the main start-up module. */ main = _a.main, /** * As a rendering function for any React renderer. */ render = _a.render, /** * Importing the injected dependency modules. */ _b = _a.modules, /** * Importing the injected dependency modules. */ _modules = _b === void 0 ? [] : _b, /** * Dependent injection container options. */ containerOptions = _a.containerOptions, /** * Preloaded state of shared state for Redux. */ preloadedState = _a.preloadedState, /** * Reactant's development setting options. */ devOptions = _a.devOptions; var modules = __spreadArray(__spreadArray([], __read(_modules), false), [main], false); var ServiceIdentifiers = new Map(); var dynamicModules = new Map(); var modulesMap = {}; var container = createContainer({ ServiceIdentifiers: ServiceIdentifiers, modules: modules, options: __assign(__assign({ defaultScope: 'Singleton' }, containerOptions), { skipBaseClassChecks: true }), }); var pluginHooks = { middleware: [], beforeCombineRootReducers: [], afterCombineRootReducers: [], enhancer: [], preloadedStateHandler: [], afterCreateStore: [], provider: [], }; var loadedModules = new Set(); var loader = function (loadModules, beforeReplaceReducer) { var multipleInjectMap = getMetadata(METADATA_KEY.multiple); var filteredModules = loadModules.filter(function (module) { var serviceIdentifier = typeof module === 'function' ? module : typeof module === 'object' ? module.provide : undefined; if (serviceIdentifier) { return (multipleInjectMap.has(serviceIdentifier) || (!multipleInjectMap.has(serviceIdentifier) && !container.isBound(serviceIdentifier))); } return true; }); bindModules(container, filteredModules); createStore({ modules: filteredModules, container: container, ServiceIdentifiers: ServiceIdentifiers, loadedModules: loadedModules, load: loader, dynamicModules: dynamicModules, pluginHooks: pluginHooks, preloadedState: undefined, devOptions: devOptions, // eslint-disable-next-line no-use-before-define originalStore: store, beforeReplaceReducer: function () { beforeReplaceReducer === null || beforeReplaceReducer === void 0 ? void 0 : beforeReplaceReducer(container); }, modulesMap: modulesMap, }); }; var store = createStore({ modules: modules, container: container, ServiceIdentifiers: ServiceIdentifiers, loadedModules: loadedModules, load: loader, dynamicModules: dynamicModules, pluginHooks: pluginHooks, preloadedState: preloadedState, devOptions: devOptions, modulesMap: modulesMap, }); var withoutReducers = store.getState() === null; var instance = container.get(typeof main === 'object' ? main.provide : main); return { /** * App's main module instance. */ instance: instance, /** * The container for modules collection */ container: container, /** * Redux store. */ store: withoutReducers ? null : store, /** * all modules collection */ modules: instance[modulesKey], /** * destroy all subscriptions */ destroy: function () { var modulesMap = instance[modulesKey]; Object.keys(modulesMap).forEach(function (key) { var e_1, _a; var module = modulesMap[key]; var unsubscriptions = module === null || module === void 0 ? void 0 : module[unsubscriptionsKey]; if (unsubscriptions) { try { for (var unsubscriptions_1 = __values(unsubscriptions), unsubscriptions_1_1 = unsubscriptions_1.next(); !unsubscriptions_1_1.done; unsubscriptions_1_1 = unsubscriptions_1.next()) { var unsubscribe = unsubscriptions_1_1.value; unsubscribe(); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (unsubscriptions_1_1 && !unsubscriptions_1_1.done && (_a = unsubscriptions_1.return)) _a.call(unsubscriptions_1); } finally { if (e_1) throw e_1.error; } } } }); }, /** * Bootstrap app with a renderer. */ bootstrap: function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!(instance instanceof ViewModule)) { throw new Error("Main module should be a 'ViewModule'."); } var callback = args[0]; var InstanceElement = typeof callback === 'function' ? callback(instance.component) : (React.createElement(instance.component, null)); var RootElement = pluginHooks.provider .reverse() .reduce(function (WrappedComponent, ProviderComponent) { return (React.createElement(ProviderComponent, null, WrappedComponent)); }, InstanceElement); var element = withoutReducers ? (React.createElement(ContainerContext.Provider, { value: container }, RootElement)) : (React.createElement(ContainerContext.Provider, { value: container }, React.createElement(Provider, { store: store }, RootElement))); return render.apply(void 0, __spreadArray([(devOptions === null || devOptions === void 0 ? void 0 : devOptions.strict) ? React.createElement(StrictMode, null, element) : element], __read(args), false)); }, }; } export { ContainerContext, createApp };