diff --git a/lib/core/Cetra.js b/lib/core/Cetra.js index 5d220b3..192823e 100644 --- a/lib/core/Cetra.js +++ b/lib/core/Cetra.js @@ -5,6 +5,17 @@ import CetraPlugin from '../plugins/CetraPlugin'; import BaseComponent from './BaseComponent'; class Cetra extends Emitter { + static #ERRORS = { + INVALID_IDENTIFIER: 'INVALID_IDENTIFIER', + INVALID_ENTITY_TYPE: 'INVALID_ENTITY_TYPE', + INVALID_ENTITY: 'INVALID_ENTITY', + INVALID_ROOT: 'INVALID_ROOT', + INVALID_COMPONENT_TYPE: 'INVALID_COMPONENT_TYPE', + INVALID_PLUGIN_URL: 'INVALID_PLUGIN_URL', + INVALID_PLUGIN_TYPE: 'INVALID_PLUGIN_TYPE', + INVALID_COMMAND: 'INVALID_COMMAND', + COMMAND_NOT_FOUND: 'COMMAND_NOT_FOUND', + }; // class static globals static #instances = new Map(); static #entityTypes = { @@ -103,17 +114,9 @@ class Cetra extends Emitter { } if (typeof this[`add${entityType}s`] === 'undefined') { - this[`add${entityType}s`] = (entities) => { - if (!Array.isArray(entities)) { - if (typeof entities != 'string') - throw new TypeError( - `${entityType} is not of type array or string` - ); - - throw new TypeError( - `${entityType} is not of type array` - ); - } + this[`add${entityType}s`] = function (entities) { + if (!Array.isArray(entities)) + throw new TypeError(Cetra.#ERRORS.INVALID_ENTITY_TYPE); entities.forEach(({ identifier, _obj }) => { this[`register${entityType}`](identifier, _obj); @@ -143,7 +146,11 @@ class Cetra extends Emitter { */ #addEntity(entityType, identifier, fn) { if (typeof identifier != 'string') { - Logger.error(`invalid identifier for ${entityType} ${identifier}`); + Logger.error( + Cetra.#ERRORS.INVALID_IDENTIFIER, + entityType, + identifier + ); return false; } // get entityKey by its value @@ -151,7 +158,7 @@ class Cetra extends Emitter { return Cetra.#entityTypes[key] == entityType; }); if (!entityKey) { - Logger.error(`invalid entity type ${entityType}`); + Logger.error(Cetra.#ERRORS.INVALID_ENTITY_TYPE, entityType); return false; } @@ -163,16 +170,12 @@ class Cetra extends Emitter { try { if (typeof fn === 'undefined') { Registry.unregister(uniqueId, this.#secretKey); - throw new TypeError( - `invalid entity constructor for ${entityType} ${identifier}` - ); + throw new TypeError(Cetra.#ERRORS.INVALID_ENTITY); } if (!this.#isValidEntity(entityType, fn)) { Registry.unregister(uniqueId, this.#secretKey); - throw new TypeError( - `invalid entity constructor for ${entityType} ${identifier}` - ); + throw new TypeError(Cetra.#ERRORS.INVALID_ENTITY); } if (typeof fn == 'function') { @@ -265,7 +268,7 @@ class Cetra extends Emitter { this.#root = document.querySelector(this.#root); if (!this.#root) { - Logger.error('No root found, defaulting to body'); + Logger.error(Cetra.#ERRORS.INVALID_ROOT); this.#root = document.body; } } @@ -314,7 +317,7 @@ class Cetra extends Emitter { try { data = JSON.parse(val); } catch (err) { - //Logger.error(err); + Logger.error(err); return val; } @@ -339,7 +342,7 @@ class Cetra extends Emitter { this.#internals.get('settings').get('observeOptions') ); } catch (err) { - Logger.error('an error occured with the observer!', err); + Logger.error(err); } } @@ -352,7 +355,7 @@ class Cetra extends Emitter { */ getPlugin(identifier) { if (!(identifier instanceof String)) { - Logger.error('Plugin identifier is not a string'); + Logger.error(Cetra.#ERRORS.INVALID_IDENTIFIER, identifier); return undefined; } @@ -465,7 +468,8 @@ class Cetra extends Emitter { if (typeof klass.register === 'function') { return klass.register(uid); } - return klass; + + throw new TypeError(Cetra.#ERRORS.INVALID_PLUGIN_TYPE); } if (typeof klass === 'function') { @@ -478,20 +482,15 @@ class Cetra extends Emitter { // what else could it be? if (typeof klass !== 'object') - throw new TypeError( - 'plugin is not of a valid plugin type (`CetraPlugin` or `object` or `function` or `url`)' - ); + throw new TypeError(Cetra.#ERRORS.INVALID_PLUGIN_TYPE); if ( klass.url && (typeof klass.url !== 'string' || !this.#isUrl(klass.url)) ) - throw new TypeError( - 'plugin url is not of type string and/or no valid url' - ); + throw new TypeError(Cetra.#ERRORS.INVALID_PLUGIN_URL); if (klass.plugin) { - Logger.info('registering plugin 5', klass); return this.#initPlugin(klass.plugin); } @@ -542,10 +541,8 @@ class Cetra extends Emitter { .get('settings') .get('selector')}-id]` ) - ) { - Logger.info('skipped element', comp); + ) continue; - } this.#initComponent(comp); } @@ -647,7 +644,7 @@ class Cetra extends Emitter { comp.getAttribute(this.#internals.get('settings').get('selector')); if (typeof compType == 'undefined' || !compType) { - Logger.error(`no component type given`); + Logger.error(Cetra.#ERRORS.INVALID_COMPONENT_TYPE); return null; } @@ -807,63 +804,58 @@ class Cetra extends Emitter { obj: plugin, parent: this.#identifier, }); - if (!identifier) { - Logger.error('Plugin identifier is required'); - Registry.unregister(uniqueId, this.#secretKey); - return; - } - if (this.#internals.get('plugins').has(identifier)) { - Logger.log(`Overwrite plugin ${identifier}`); - Registry.unregister(uniqueId, this.#secretKey); - Registry.register({ - key: this.#secretKey, - obj: plugin, - parent: this.#identifier, - }); - } - - if (!plugin) { - Logger.error( - `Plugin ${identifier} is not an url or a plugin instance or class` - ); - Registry.unregister(uniqueId, this.#secretKey); - return; - } - - if (typeof plugin === 'string') { - if (!this.#isUrl(plugin)) { - Logger.error(`Plugin ${identifier} has an invalid url: ${url}`); + try { + if (!identifier) { + Logger.error(Cetra.#ERRORS.INVALID_IDENTIFIER); Registry.unregister(uniqueId, this.#secretKey); return; } - Logger.info(`Plugin ${identifier} is loaded from ${plugin}`); - this.#internals.get('plugins').set(identifier, { - plugin, - key: uniqueId, + + if (this.#internals.get('plugins').has(identifier)) { + Registry.unregister(uniqueId, this.#secretKey); + Registry.register({ + key: this.#secretKey, + obj: plugin, + parent: this.#identifier, + }); + } + + if (!plugin) throw new TypeError(Cetra.#ERRORS.INVALID_PLUGIN_TYPE); + + if (typeof plugin === 'string') { + if (!this.#isUrl(plugin)) + throw new TypeError(Cetra.#ERRORS.INVALID_PLUGIN_URL); + + Logger.info(`Plugin ${identifier} is loaded from ${plugin}`); + this.#internals.get('plugins').set(identifier, { + plugin, + key: uniqueId, + parent: this.#identifier, + }); + return; + } + + if (!['function', 'object'].includes(typeof plugin)) + throw new TypeError(Cetra.#ERRORS.INVALID_PLUGIN_TYPE); + + const pluginInstance = this.#initPlugin(plugin); + + if (!pluginInstance) + throw new TypeError(Cetra.#ERRORS.INVALID_PLUGIN_TYPE); + + Registry.register({ + obj: pluginInstance, + key: this.#secretKey, parent: this.#identifier, }); - return; - } - if (!['function', 'object'].includes(typeof plugin)) { - Logger.error('Plugin is not of type function or object'); + this.#internals.get('plugins').set(identifier, pluginInstance); + this.emit('onAfterRegisterPlugin', pluginInstance); + } catch (err) { + Logger.error(err); Registry.unregister(uniqueId, this.#secretKey); - return null; } - - const pluginInstance = this.#initPlugin(plugin); - Registry.unregister(uniqueId, this.#secretKey); - if (!pluginInstance) - throw new TypeError('plugin is not of a valid plugin type'); - - Registry.register({ - key: this.#secretKey, - obj: pluginInstance, - parent: this.#identifier, - }); - - this.#internals.get('plugins').set(identifier, pluginInstance); } /** @@ -875,26 +867,35 @@ class Cetra extends Emitter { * @param {any} e - The event object. * @throws {Error} If the component with the given ID is not found. */ - exec(action, varName, componentId, e) { + exec(componentId, update = { command, args, evt }) { + if (Array.isArray(update.args)) update.args = []; const comp = this.#internals.get('compIndex').get(componentId); if (!comp) { throw new Error(`component ${componentId} not found`); } - if (this.#internals.get('plugins').get('utils')[action]) { - const value = comp.getValue(varName); - comp.update([ - { - old: value, - new: this.#internals - .get('plugins') - .get('utils') - [action](comp.getValue(varName)), - varName, - }, - ]); + if (!this.#internals.get('commands').has(update.command)) { + Logger.error(Cetra.#ERRORS.COMMAND_NOT_FOUND, update.command); + return; } + + this.#internals + .get('commands') + .get(update.command) + .forEach((command) => { + if (!command.exec) { + if (typeof command != 'function' || !command.name) { + Logger.error( + Cetra.#ERRORS.INVALID_COMMAND, + update.command + ); + } + command(comp, update); + } + + command.exec(comp, update); + }); } }