lemon-core
Version:
Lemon Serverless Micro-Service Platform
252 lines • 10.6 kB
JavaScript
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
;