UNPKG

beyond

Version:

The Full Stack Universal Typescript Framework

84 lines (69 loc) 2.63 kB
/** * This class exists to avoid executing the _process method in the following case: * * There can be a situation in which two (or more) child processors emit the "initialised" event on initialisation. * In this case, both have the .processed property set to true, therefore they would pass the _prepared property correctly, * but immediately after the current object is processed, the "initialised" event of the second object will be received, * processing more than once. */ module.exports = class { #dp; // The children that are already initialised #initialised = new Set(); // The subscriptions to the 'initialised' events, to unregister the listener when object is destroyed #subscriptions = new Map(); #children = new Map(); constructor(dp) { this.#dp = dp; } get completed() { const {children} = this.#dp; return children.size === this.#initialised.size; } #oninitialised = name => { this.#initialised.add(name); const {children} = this.#dp; children.prepared && this.#dp._invalidate(); } register(name, child) { if (child.initialised) { this.#initialised.add(name); return; } const oninitialised = () => { this.#oninitialised(name); if (!this.#subscriptions.has(name)) return; child.off('initialised', this.#subscriptions.get(name)); } this.#subscriptions.set(name, oninitialised); this.#children.set(name, child); child.on('initialised', oninitialised); } unregister(name) { if (!this.#subscriptions.has(name)) throw new Error('Child is not registered'); const child = this.#children.get(name); child.off('initialised', this.#subscriptions.get(name)); this.#subscriptions.delete(name); this.#initialised.delete(name); } /** * Initialise children * * @return {Promise<void>} */ async initialise() { const promises = []; this.#children.forEach(child => { if (child.initialised || child.initialising) return; const initialise = child.initialise(); initialise instanceof Promise && promises.push(initialise); }); await Promise.all(promises); } destroy() { [...this.#subscriptions.keys()].forEach(name => this.unregister(name)); this.#subscriptions.clear(); this.#children.clear(); this.#initialised.clear(); } }