UNPKG

sdg

Version:

pomelo ts

407 lines 26.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const fs_1 = tslib_1.__importDefault(require("fs")); const path_1 = tslib_1.__importDefault(require("path")); const lodash_1 = tslib_1.__importDefault(require("lodash")); const events_1 = require("events"); const base_1 = tslib_1.__importDefault(require("./base")); const Constants = tslib_1.__importStar(require("./util/constants")); const appUtil_1 = require("./util/appUtil"); const events_2 = tslib_1.__importDefault(require("./util/events")); class Application extends base_1.default { constructor(opts) { super(); this.usedPlugins = []; this.opts = opts; this.loaded = []; // @ts-ignore this.components = {}; this.settings = {}; this.serverInfo = opts.serverInfo; this.logger = opts.logger || console; // @ts-ignore const base = opts.base || path_1.default.dirname(require.main.filename); this.set(Constants.RESERVED.BASE, base, true); this.initEvent(); this.restore(); this.initCurServerInfo(); this.loadMaster(); } initCurServerInfo() { this.serverId = this.getServerId(); this.serverType = this.getServerType(); } getCurServer() { return this.serverInfo; } initEvent() { this.event = new events_1.EventEmitter(); this.event.on(Constants.COMMAND.KILL, () => { }); } restore() { this.servers = {}; this.serverTypeMaps = {}; } async start() { this.startTime = Date.now(); appUtil_1.loadDefaultComponents(this); await appUtil_1.optComponents(this.loaded, Constants.RESERVED.START); await this.afterStart(); } async afterStart() { await appUtil_1.optComponents(this.loaded, Constants.RESERVED.AFTER_START); this.logger.info(`[${this.serverId}] startup in ${Date.now() - this.startTime} ms`); } /** * server管理器,这里只管理serverInfo,具体逻辑交给proxy * @param servers */ addServers(servers) { if (!servers || !servers.length) return; for (const server of servers) { if (server.id === this.serverId) continue; this.servers[server.id] = server; const serverType = this.getServerType(server); let maps = this.serverTypeMaps[serverType]; if (!maps) this.serverTypeMaps[serverType] = maps = []; this.replaceServer(maps, server); } // 通知proxy更新对应server代理 this.event.emit(events_2.default.ADD_SERVERS, servers); } removeServers(ids) { for (const id of ids) { const server = this.servers[id]; if (!server) continue; delete this.servers[id]; lodash_1.default.remove(this.getServersByType(server.type), { id }); } this.event.emit(events_2.default.REMOVE_SERVERS, ids); } replaceServers(servers) { if (!servers) return; this.servers = servers; const serverArray = []; this.serverTypeMaps = {}; lodash_1.default.forOwn(servers, (server) => { const serverType = this.getServerType(server); if (!this.serverTypeMaps[serverType]) this.serverTypeMaps[serverType] = []; this.serverTypeMaps[serverType].push(server); }); this.event.emit(events_2.default.REPLACE_SERVERS, serverArray); } /** * 更新serverInfo的配置信息 * @param serverInfo */ updateServerInfo(serverInfo) { const serverId = serverInfo.id; if (serverId === this.serverId) { this.serverInfo = serverInfo; this.initCurServerInfo(); } if (this.servers[serverId]) { this.servers[serverId] = serverInfo; const serverTypes = this.getServersByType(serverInfo.type); const idx = lodash_1.default.findIndex(serverTypes, { id: serverId }); if (idx !== -1) serverTypes[idx] = serverInfo; } } set(setting, val, attach) { this.settings[setting] = val; if (attach) this[setting] = val; return this; } get(setting) { return this.settings[setting]; } /** * Set the route function for the specified server type. * * Examples: * * app.route('area', routeFunc); * * let routeFunc = function(session, msg, app, cb) { * // all request to area would be route to the first area server * let areas = app.getServersByType('area'); * cb(null, areas[0].id); * }; * * @param {String} serverType server type string * @param {Function} routeFunc route function. routeFunc(session, msg, app, cb) * @return {Object} current application instance for chain invoking * @memberOf Application */ route(routeFunc, serverType) { if (!routeFunc) throw 'routeFunction must provide'; let routes = this.get(Constants.KEYWORDS.ROUTE); if (!routes) { routes = {}; this.set(Constants.KEYWORDS.ROUTE, routes); } if (serverType) { routes[serverType] = routeFunc; } else { routes.default = routeFunc; } return this; } configure(env, type, fn) { let cb = fn; if (typeof env === 'function') { cb = env; env = Constants.RESERVED.ALL; } if (typeof type === 'function') { cb = type; type = Constants.RESERVED.ALL; } if (env === Constants.RESERVED.ALL || this.contains(this.settings.env, env)) { if (type === Constants.RESERVED.ALL || this.contains(this.settings.serverType, type)) { cb.call(this).then(); } } return this; } registerAdmin(moduleId, module, opts) { let modules = this.get(Constants.KEYWORDS.MODULE); if (!modules) { modules = {}; this.set(Constants.KEYWORDS.MODULE, modules); } if (typeof moduleId !== 'string') { opts = module; module = moduleId; if (module) { moduleId = (module.moduleId); if (!moduleId) moduleId = module.constructor.name; } } if (!moduleId) return; modules[moduleId] = { moduleId, module, opts }; } /** * Check if `setting` is enabled. * * @param {String} setting application setting * @return {Boolean} * @memberOf Application */ enabled(setting) { return !!this.get(setting); } /** * Check if `setting` is disabled. * * @param {String} setting application setting * @return {Boolean} * @memberOf Application */ disabled(setting) { return !this.get(setting); } get serverTypes() { return lodash_1.default.keys(this.serverTypeMaps); } getBase() { return this.get(Constants.RESERVED.BASE); } getServerIds() { return Object.keys(this.servers); } getServers() { return this.servers; } getServerType(serverInfo) { return (serverInfo || this.serverInfo).type; } getServerId(serverInfo) { return (serverInfo || this.serverInfo).id; } getServerById(id) { return this.servers[id]; } getServersByType(type) { return this.serverTypeMaps[type] || []; } isFrontend(server) { server = server || this.getCurServer(); return server && !!server.frontend; } /** * 加载配置 config目录下 * @param key * @param val * @param reload */ loadConfigBaseApp(key, val, reload = false) { const filename = path_1.default.resolve(this.getBase(), val); if (!fs_1.default.existsSync(filename)) throw filename + ' not exists'; this.set(key, require(filename)); if (reload) { // TODO reload } } /** * Use plugin. * @param {Object} plugin plugin instance * @param {[type]} opts (optional) construct parameters for the factory function * @memberOf Application */ use(plugin, opts) { opts = opts || {}; if (!plugin) throw new Error(`plugin is null!`); if (this.usedPlugins.includes(plugin)) throw new Error(`plugin[${plugin.name} was used already!]`); if (plugin.components) { for (let componentCtor of plugin.components) { this.load(componentCtor, opts); } } if (plugin.events) { for (let eventCtor of plugin.events) { this.loadEvent(eventCtor, opts); } } this.usedPlugins.push(plugin); this.logger.warn(`used Plugin: ${plugin.name}`); } /** * add a filter to before and after filter */ filter(filter) { this.before(filter); this.after(filter); } /** * Add before filter. * @param {Object|Function} bf before filter, bf(msg, session, next) * @memberOf Application */ before(bf) { this.addFilter(Constants.KEYWORDS.BEFORE_FILTER, bf); } /** * Add after filter. * @param {Object|Function} af after filter, `af(err, msg, session, resp, next)` * @memberOf Application */ after(af) { this.addFilter(Constants.KEYWORDS.AFTER_FILTER, af); } /** * add a global filter to before and after global filter */ globalFilter(filter) { if (filter.before) this.globalBefore(filter); if (filter.after) this.globalAfter(filter); } /** * Add global before filter. * * @param {Object|Function} bf before filter, bf(msg, session, next) * @memberOf Application */ globalBefore(bf) { this.addFilter(Constants.KEYWORDS.GLOBAL_BEFORE_FILTER, bf); } /** * Add global after filter. */ globalAfter(af) { this.addFilter(Constants.KEYWORDS.GLOBAL_AFTER_FILTER, af); } load(name, component, opts) { if (typeof name !== 'string') { opts = component; component = name; name = ''; } if (typeof component === 'function') { component = new component(this, opts || {}); } if (!component) throw 'component dose not exist'; if (!name && typeof component.name === 'string') { name = component.name; } if (name && this.components[name]) { // ignore duplicate component this.logger.warn(`ignore duplicate component: ${name}`); return component; } this.loaded.push(component); if (name) { this.components[name] = component; } return component; } replaceServer(serverLists, server) { lodash_1.default.remove(serverLists, s => s.id === server.id); serverLists.push(server); } addFilter(type, filter) { let filters = this.get(type); if (!filters) { filters = []; this.set(type, filters); } filters.push(filter); } ; /** * 加载master服务器配置 */ loadMaster() { this.loadConfigBaseApp(Constants.RESERVED.MASTER, Constants.FILEPATH.MASTER); } /** * 加载一个事件侦听 * @param Event * @param opts */ loadEvent(Event, opts) { let eventInstance = new Event(this, opts); for (let evt in events_2.default) { let name = events_2.default[evt]; let method = eventInstance[name]; if (method) { this.event.on(name, method.bind(eventInstance)); } } } contains(str, settings) { if (!settings) return false; const ts = settings.split('|'); for (const s of ts) { if (str === s) return true; } return false; } } exports.default = Application; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYXBwbGljYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsb0RBQW9CO0FBQ3BCLHdEQUF3QjtBQUN4Qiw0REFBdUI7QUFDdkIsbUNBQXFDO0FBR3JDLDBEQUEwQjtBQUMxQixvRUFBOEM7QUFDOUMsNENBQXNFO0FBT3RFLG1FQUFzQztBQWlDdEMsTUFBcUIsV0FBWSxTQUFRLGNBQUk7SUEwQjNDLFlBQVksSUFBc0I7UUFDaEMsS0FBSyxFQUFFLENBQUM7UUFYSCxnQkFBVyxHQUFjLEVBQUUsQ0FBQztRQVlqQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUNqQixhQUFhO1FBQ2IsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUM7UUFDckMsYUFBYTtRQUNiLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLElBQUksY0FBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzlELElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTlDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNqQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDcEIsQ0FBQztJQUVPLGlCQUFp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