beyond
Version:
The Full Stack Universal Typescript Framework
93 lines (72 loc) • 2.66 kB
JavaScript
const DynamicProcessor = global.utils.DynamicProcessor(Map);
module.exports = class extends DynamicProcessor {
get dp() {
return 'utils.config.collection';
}
#propagator;
get config() {
return this.children.get('config').child;
}
get errors() {
return this.config.errors;
}
get warnings() {
return this.config.warnings;
}
get valid() {
return this.config.valid;
}
constructor(config) {
super();
this.#propagator = new (require('./propagator'))(this._events);
const children = new Map();
children.set('config', {child: config});
super.setup(children);
}
// This method should be overridden to process the configuration, and also can be used
// to alter the configuration of the items (modify, add or remove) before creating the instances
_processConfig(items) {
return items;
}
// This method should be overridden
_createItem(config) {
void (config);
throw new Error('This method should be overridden');
}
_deleteItem(item) {
item.destroy();
}
_process() {
const {config} = this;
if (!config.valid) {
this.clear();
return;
}
let items = this._processConfig(new Map(config.items));
items = items ? items : new Map();
const updated = new Map();
for (const [path, config] of items) {
const item = this.has(path) ? this.get(path) : this._createItem(config);
if (item.path !== path) throw new Error(`Item must specify its path`);
updated.set(path, item);
}
// Subscribe modules that are new to the collection
this.#propagator.subscribe([...updated].filter(([path]) => !this.has(path)).map(([, item]) => item));
// Unsubscribe unused modules
this.#propagator.unsubscribe([...this].filter(([path]) => !updated.has(path)).map(([, item]) => item));
// Destroy unused items
this.forEach(item => !updated.has(item.path) && this._deleteItem(item));
// Set the updated data into the collection
super.clear(); // Do not use this.clear(), as it would destroy libraries still being used
updated.forEach((value, key) => this.set(key, value));
}
clear() {
this.forEach(item => item.destroy());
this.#propagator.unsubscribe([...this.values()]);
super.clear();
}
destroy() {
super.destroy();
this.clear();
}
}