fix(commands) implement commands execution and improve error messaging
This commit is contained in:
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user