UNPKG

kara

Version:

A third generation EX-400 android

122 lines (98 loc) 3.6 kB
var fs = require("fs"), path = require("path"), EX400 = require("ex-400"), redis = require("redis"); var Kara = module.exports = function Kara(config) { EX400.Core.call(this, config || this._loadConfig()); this.config.plugins = this.config.plugins || {}; this.config.plugins.loadPath = this.config.plugins.loadPath || "./plugins"; this.plugins = {}; this.config.redis = this.config.redis || {}; this.config.redis.lib = this.config.redis.lib || redis; }; Kara.prototype = Object.create(EX400.Core.prototype, {constructor: {value: Kara}}); // properties Object.defineProperty(Kara.prototype, "redis", { get: function getRedis() { return this._redis || (this._redis = this._redisConnect()); }, }); // public Kara.prototype.loadPlugin = function loadPlugin(name) { if (name in this.plugins) { throw new Error("Plugin already loaded: " + name) } var pluginPath = this._pluginPath(name), pluginInstance = new (require(pluginPath))(this); this.plugins[name] = { enabled: false, filename: pluginPath, exports: pluginInstance, }; return pluginInstance; }; Kara.prototype.unloadPlugin = function unloadPlugin(name) { if (!(name in this.plugins)) { throw new Error("Cannot enable unknown plugin: " + name); } var cachePath = path.resolve(__dirname, this._pluginPath(name)); delete require.cache[cachePath]; delete this.plugins[name]; }; Kara.prototype.enablePlugin = function enablePlugin(name) { if (!(name in this.plugins)) { throw new Error("Cannot enable unknown plugin: " + name) } if (this.plugins[name].enabled === true) { return } this.plugins[name].exports.enable(); this.plugins[name].enabled = true; }; Kara.prototype.disablePlugin = function disablePlugin(name) { if (!(name in this.plugins)) { throw new Error("Cannot disable unknown plugin: " + name) } if (this.plugins[name].enabled === false) { return } this.plugins[name].exports.disable(); this.plugins[name].enabled = false; }; // private Kara.prototype._redisConnect = function _redisConnect() { var client = this.config.redis.lib.createClient( this.config.redis.port, this.config.redis.host, {parser: "hiredis"} ); client.on("error", this._onRedisError.bind(this)); client.on("connect", this._onRedisConnect.bind(this)); client.on("end", this._onRedisDisconnect.bind(this)); return client; }; Kara.prototype._loadConfig = function _loadConfig() { var configPath = path.resolve(__dirname, "./config.js"); if (!fs.existsSync(configPath)) { throw new Error("Missing config file: " + configPath); } return require(configPath); }; Kara.prototype._pluginPath = function _pluginPath(name) { return [this.config.plugins.loadPath, path.sep, name, ".js"].join(""); }; // events Kara.prototype._onRedisConnect = function _onRedisConnect() { this.redis.select(this.config.redis.dbIndex, this._onRedisSelect.bind(this)); }; /** * redis automatically reconnects based on options.max_attempts (defaults to * unlimited retries) * * listening to redis end event and manually reconnecting will drastically * decrease reconnection time */ Kara.prototype._onRedisDisconnect = function _onRedisDisconnect() { if (this._redis) { this._redis.end(); this._redis = null; } this._redisConnect(); }; Kara.prototype._onRedisError = function _onRedisError(error) { if (error) { this.emit("redis:error", error) } }; Kara.prototype._onRedisSelect = function _onRedisSelect(error, res) { if (error) { return this.emit("redis:error", error); } this.emit("redis:ready"); };