class Component { constructor(manager, opts = {}) { if(!opts) return null; this.manager = manager; this.id = opts.id; this.type = opts.type; this.directory = null; this.guarded = Boolean(opts.guarded); this.disabled = Boolean(opts.disabled); this.registry = this.manager.registry; } enable() { if(this.guarded) return { error: true, code: 'GUARDED' }; this.disabled = false; this.registry.emit('componentUpdate', { component: this, type: 'ENABLE' }); return { error: false }; } disable() { if(this.guarded) return { error: true, code: 'GUARDED' }; this.disabled = true; this.registry.emit('componentUpdate', { component: this, type: 'DISABLE' }); return { error: false }; } unload() { if(this.guarded) return { error: true, code: 'GUARDED' }; if(!this.directory) return { error: true, code: 'MISSING_DIRECTORY' }; this.registry.unloadComponent(this); delete require.cache[this.filePath]; this.registry.emit('componentUpdate', { component: this, type: 'UNLOAD' }); return { error: false }; } reload(bypass = false) { if(this.type === 'module') return { error: false }; if(this.guarded && !bypass) return { error: true, code: 'GUARDED' }; if(!this.directory || !require.cache[this.directory]) return { error: true, code: 'MISSING_DIRECTORY' }; let cached, newModule; try { cached = require.cache[this.directory]; delete require.cache[this.directory]; newModule = require(this.directory); if(typeof newModule === 'function') { newModule = new newModule(this.manager); } this.registry.unloadComponent(this); this.registry.emit('componentUpdate', { component: this, type: 'UNLOAD' }); this.registry.loadComponent(newModule, this.directory); } catch(error) { if(cached) require.cache[this.directory] = cached; return { error: true, code: 'MISSING_MODULE' }; } return { error: false }; } get resolveable() { return `${this.type}:${this.id}`; } } module.exports = Component;