reactant
Version:
A framework for building React web applications
195 lines (192 loc) • 7.32 kB
JavaScript
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 };