UNPKG

lemon-core

Version:
252 lines 10.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildEngine = exports.do_serialize = exports.build_err = exports.build_inf = exports.build_log = exports.RESET = exports.YELLOW = exports.BLUE = exports.RED = exports.build_ts = exports.build_environ = void 0; /** * `engine/index.tx` * - engine bootloader * * * @author Steve Jung <steve@lemoncloud.io> * @date 2018-05-23 initial version * @date 2019-11-26 cleanup and optimized for `lemon-core#v2` * @date 2022-02-22 cleanup lodash export `_` * * @copyright (C) lemoncloud.io 2019 - All Rights Reserved. */ const types_1 = require("./types"); const utilities_1 = require("./utilities"); const lodash_1 = __importDefault(require("lodash")); //WARN! - ------------------------------------------------------ //WARN! - DO NOT IMPORT ANY DEPENDENCY IN HERE EXCEPT TYPES. //WARN! - ------------------------------------------------------ //! build environment getter const build_environ = (options) => (name, defVal) => { // as default, load from proces.env. const env = options.env || (process && process.env) || {}; const val = env[name]; // throw Error if value is not set. if (defVal && defVal instanceof Error && val === undefined) throw defVal; // returns default. return val === undefined ? defVal : val; }; exports.build_environ = build_environ; // build timestamp like 2016-12-08 13:30:44 const build_ts = (options) => { const $console = options && options.console; const _ts = $console && typeof $console.ts == 'function' ? $console.ts : utilities_1.Utilities.timestamp; return (date, timeZone) => _ts(date, timeZone); }; exports.build_ts = build_ts; const LEVEL_LOG = '-'; const LEVEL_INF = 'I'; const LEVEL_ERR = 'E'; exports.RED = '\x1b[31m'; exports.BLUE = '\x1b[32m'; exports.YELLOW = '\x1b[33m'; exports.RESET = '\x1b[0m'; /* eslint-disable @typescript-eslint/indent */ const build_log = ($console) => function () { const _ts = (0, exports.build_ts)({ console: $console }); const args = (!Array.isArray(arguments) && Array.prototype.slice.call(arguments)) || arguments; if ($console.auto_color) ($console.auto_ts && args.unshift(_ts(), LEVEL_LOG + exports.RESET)) || args.unshift(LEVEL_LOG + exports.RESET), args.unshift(exports.BLUE); else $console.auto_ts && args.unshift(_ts(), LEVEL_LOG); return $console.log.apply($console.thiz, args); }; exports.build_log = build_log; const build_inf = ($console) => function () { const _ts = (0, exports.build_ts)({ console: $console }); const args = (!Array.isArray(arguments) && Array.prototype.slice.call(arguments)) || arguments; if ($console.auto_color) ($console.auto_ts && args.unshift(_ts(), LEVEL_INF + exports.RESET)) || args.unshift(LEVEL_INF + exports.RESET), args.unshift(exports.YELLOW); else $console.auto_ts && args.unshift(_ts(), LEVEL_INF); return $console.log.apply($console.thiz, args); }; exports.build_inf = build_inf; const build_err = ($console) => function () { const _ts = (0, exports.build_ts)({ console: $console }); const args = (!Array.isArray(arguments) && Array.prototype.slice.call(arguments)) || arguments; if ($console.auto_color) ($console.auto_ts && args.unshift(_ts(), LEVEL_ERR + exports.RESET)) || args.unshift(LEVEL_ERR + exports.RESET), args.unshift(exports.RED); else $console.auto_ts && args.unshift(_ts(), LEVEL_ERR); return $console.log.apply($console.thiz, args); }; exports.build_err = build_err; /* eslint-enable @typescript-eslint/indent */ /** **************************************************************************************************************** * Common functions. ** ****************************************************************************************************************/ /** * parrallel actions in list (in batch-size = 10) * * @param list any list * @param callback (item)=>any | Promise<any> * @param size (optional) size * @param pos (optional) current pos * @param result (optional) result set. */ const do_serialize = (param, callback, size, pos, result) => { size = size === undefined ? 1 : size; pos = pos === undefined ? 0 : pos; result = result === undefined ? [] : result; const list = param; const list2 = list.slice(pos, pos + size); const actions = list2.map((node, i) => { const index = pos + i; try { const R = callback(node, index); return R instanceof Promise ? R : Promise.resolve(R); } catch (e) { return Promise.reject(e); } }); return Promise.all(actions).then(_ => { result = result.concat(_); if (!_.length) return Promise.resolve(result); return (0, exports.do_serialize)(param, callback, size, pos + size, result); }); }; exports.do_serialize = do_serialize; /** * class: `MyEngineModules` * - local implementation of EngineModules */ class MyEngineModules { constructor() { this.mods = []; this.inited = false; } register(mod) { // console.info(`! mod.reg(${mod.getModuleName()})..`); this.mods.push(mod); } module(name) { const mods = this.mods.filter(_ => _.getModuleName() == name); const res = (mods && mods[0]); return res; } initialize(force, getLevels) { return __awaiter(this, void 0, void 0, function* () { if (!force && this.inited) return; // console.info(`! EngineModules.init()..`); this.inited = true; //! setup init level per each module. const mods = yield Promise.all(this.mods.map((mod) => __awaiter(this, void 0, void 0, function* () { const level = yield mod.initModule(); return { level, mod }; }))); //! build map by level => Module. const maps = lodash_1.default.reduce(mods, (M, inf) => { if (M[inf.level]) { M[inf.level].push(inf.mod); } else { M[inf.level] = [inf.mod]; } return M; }, {}); // eslint-disable-next-line prettier/prettier const levels = Object.keys(maps).map(_ => Number(_)).sort(); if (getLevels) return levels; const catchModError = (e, mod) => { // console.error(`! mod[${mod.getModuleName()}].err =`, e); return `ERR[${mod.getModuleName()}] ${e.message}`; }; //! do serialize per each level. const res = yield (0, exports.do_serialize)(levels, level => Promise.all(maps[level].map(mod => mod && mod .initModule(level) .then(() => mod.getModuleName()) .catch(e => catchModError(e, mod))))); // console.info(`! engine[${res.length}].inited =`, res); return res; }); } } /** * initialize as EngineInterface * * ```ts * import engine from 'lemon-engine'; * const $engine = engine(global, { env: process.env }); * ``` * * @param scope main scope like global, browser, ... * @param options configuration. */ const buildEngine = (scope, options) => { scope = scope || {}; options = options || {}; //! load configuration. const ROOT_NAME = options.name || 'lemon'; const _environ = (0, exports.build_environ)(options); const STAGE = _environ('STAGE', ''); const LS = _environ('LS', '0') === '1'; // LOG SILENT (NO PRINT LOG) const TS = _environ('TS', '1') === '1'; // PRINT TIME-STAMP. const LC = _environ('LC', STAGE === 'local' || STAGE === 'express' ? '1' : '') === '1'; // COLORIZE LOG //! common function for logging. const silent = () => { }; const $console = Object.assign({ thiz: console, log: LS ? silent : console.log, error: LS ? silent : console.error, auto_ts: TS, auto_color: LC }, options.console); const _log = (0, exports.build_log)($console); const _inf = (0, exports.build_inf)($console); const _err = (0, exports.build_err)($console); //! create root instance to manage global objects. const createEngine = () => { const $engine = new (class extends MyEngineModules { constructor() { super(); this.STAGE = STAGE; this.id = ROOT_NAME; this.log = _log; this.inf = _inf; this.err = _err; this.$console = $console; this.ts = (0, exports.build_ts)({ console: $console }); this.dt = utilities_1.Utilities.datetime; this.environ = _environ; this.toString = () => `engine: ${ROOT_NAME}`; this.U = new utilities_1.Utilities(this); } })(); //! start initialization only if making $engine. STAGE && _inf('#STAGE =', STAGE); _inf(`! engine[${ROOT_NAME}] service is ready!`); return $engine; }; //! reuse via scope or build new. const $engine = scope[types_1.ENGINE_KEY_IN_SCOPE] || createEngine(); //NOTE - reuse instance. //! register as global instances. scope._log = $engine.log || _log; scope._inf = $engine.inf || _inf; scope._err = $engine.err || _err; scope[types_1.ENGINE_KEY_IN_SCOPE] = $engine; //! returns finally. return $engine; }; exports.buildEngine = buildEngine; //! export default. exports.default = exports.buildEngine; //# sourceMappingURL=builder.js.map