@ima/core
Version:
IMA.js framework for isomorphic javascript application
244 lines (243 loc) • 9.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "Bootstrap", {
enumerable: true,
get: function() {
return Bootstrap;
}
});
const _task = require("@esmj/task");
const _helpers = /*#__PURE__*/ _interop_require_wildcard(require("@ima/helpers"));
const _Namespace = require("./Namespace");
const _BindingState = require("./oc/BindingState");
const _Router = require("./router/Router");
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
class Bootstrap {
_oc;
_config;
/**
* Initializes the bootstrap.
*
* @param oc The application's object container to use
* for managing dependencies.
*/ constructor(oc){
/**
* The object container used to manage dependencies.
*/ this._oc = oc;
}
/**
* Initializes the application by running the bootstrap sequence. The
* sequence initializes the components of the application in the following
* order:
* - application settings
* - constants, service providers and class dependencies configuration
* - services
* - UI components
* - routing
*
* @param config The application environment
* configuration for the current environment.
*/ async run(config) {
this._config = config;
await (0, _task.autoYield)();
this._initSettings();
await (0, _task.autoYield)();
await this._bindDependencies();
await (0, _task.autoYield)();
await this._initServices();
await (0, _task.autoYield)();
this._initRoutes();
}
/**
* Initializes dynamically loaded plugin. This is explicitly called from
* within the Plugin Loader instance.
*
* @param name Plugin name.
* @param plugin Plugin interface (object with init functions).
*/ async initPlugin(name, plugin) {
if (!plugin) {
return;
}
await (0, _task.autoYield)();
this._initPluginSettings(name, plugin);
await (0, _task.autoYield)();
this._bindPluginDependencies(name, plugin);
await (0, _task.autoYield)();
this._initPluginServices(plugin);
}
/**
* Initializes the application settings. The method loads the settings for
* all environments and then picks the settings for the current environment.
*
* The method also handles using the values in the production environment
* as default values for configuration items in other environments.
*/ _initSettings() {
/**
* Default settings for the application.
*/ const currentApplicationSettings = {
$Http: {
defaultRequestOptions: {
timeout: 15000,
repeatRequest: 1,
ttl: 60000,
fetchOptions: {
mode: 'cors',
headers: {
Accept: 'application/json'
}
},
validateCookies: false,
cache: true
},
cacheOptions: {
prefix: 'http.'
}
},
$Router: {
middlewareTimeout: 30000
},
$Cache: {
enabled: true,
ttl: 60000
}
};
const settings = {};
const plugins = this._config.plugins.concat([
{
name: _BindingState.BindingState.App,
plugin: this._config
}
]);
plugins.filter(({ plugin })=>typeof plugin.initSettings === 'function').forEach(({ name, plugin })=>{
const allPluginSettings = plugin.initSettings(_Namespace.ns, this._oc, this._config.settings, false);
_helpers.assignRecursivelyWithTracking(name)(settings, currentApplicationSettings, _helpers.resolveEnvironmentSetting(allPluginSettings, this._config.settings.$Env));
});
this._config.bind = {
...this._config.bind,
...settings,
...this._config.settings
};
}
/**
* Initializes dynamically loaded plugin settings (if the init
* function is provided). The settings are merged into the application
* the same way as with non-dynamic import, meaning the app setting overrides
* are prioritized over the default plugin settings.
*
* @param name Plugin name.
* @param plugin Plugin interface (object with init functions).
*/ _initPluginSettings(name, plugin) {
if (typeof plugin?.initSettings !== 'function') {
return;
}
const newApplicationSettings = {};
const allPluginSettings = plugin.initSettings(_Namespace.ns, this._oc, this._config.settings, true // Indicating static dynamic bootstraping
);
_helpers.assignRecursivelyWithTracking(name)(newApplicationSettings, _helpers.resolveEnvironmentSetting(allPluginSettings, this._config.settings.$Env));
_helpers.assignRecursivelyWithTracking(_BindingState.BindingState.App)(newApplicationSettings, this._config.bind);
this._config.bind = {
...this._config.bind,
...newApplicationSettings
};
}
/**
* Binds the constants, service providers and class dependencies to the
* object container.
*/ async _bindDependencies() {
this._oc.setBindingState(_BindingState.BindingState.IMA);
this._config.initBindIma(_Namespace.ns, this._oc, this._config.bind, _BindingState.BindingState.IMA);
const filteredPlugins = this._config.plugins.filter(({ plugin })=>typeof plugin.initBind === 'function');
for (const { name, plugin } of filteredPlugins){
await (0, _task.autoYield)();
this._oc.setBindingState(_BindingState.BindingState.Plugin, name);
plugin.initBind(_Namespace.ns, this._oc, this._config.bind, false);
}
this._oc.setBindingState(_BindingState.BindingState.App);
this._config.initBindApp(_Namespace.ns, this._oc, this._config.bind, _BindingState.BindingState.App);
}
/**
* Binds the constants, service providers and class dependencies to the
* object container for dynamically imported plugins.
*
* @param name Plugin name.
* @param plugin Plugin interface (object with init functions).
*/ _bindPluginDependencies(name, plugin) {
if (typeof plugin.initBind !== 'function') {
return;
}
this._oc.setBindingState(_BindingState.BindingState.Plugin, name);
plugin.initBind(_Namespace.ns, this._oc, this._config.bind, true, name);
this._oc.setBindingState(_BindingState.BindingState.App);
}
/**
* Initializes the routes.
*/ _initRoutes() {
const router = this._oc.get(_Router.Router);
this._config.initRoutes(_Namespace.ns, this._oc, this._config.routes, router);
}
/**
* Initializes the basic application services.
*/ async _initServices() {
this._config.initServicesIma(_Namespace.ns, this._oc, this._config.services);
const filteredPlugins = this._config.plugins.filter(({ plugin })=>typeof plugin.initServices === 'function');
for (const { plugin } of filteredPlugins){
await (0, _task.autoYield)();
plugin.initServices(_Namespace.ns, this._oc, this._config.services, false);
}
this._config.initServicesApp(_Namespace.ns, this._oc, this._config.services);
}
/**
* Service initialization for the dynamically loaded plugins.
*
* @param plugin Plugin interface (object with init functions).
*/ _initPluginServices(plugin) {
if (typeof plugin.initServices !== 'function') {
return;
}
plugin.initServices(_Namespace.ns, this._oc, this._config.services, true);
}
}
_Namespace.ns.set('ns.ima.core.Bootstrap', Bootstrap);
//# sourceMappingURL=Bootstrap.js.map