extensions/gnome-extension/build-scripts/tasks.js (28 lines of code) (raw):

/** @public @template T @class */ export class Task { /** @private @property {Promise<T>} */ #promise; /** @public @constructor @param {() => Promise<T>} spawner */ constructor(spawner) { this.#promise = spawner(); } /** @public @async @method @returns {Promise<T>} */ wait() { return this.#promise; } } /** @public @class */ export class TaskSet { /** @private @property @type {Set<Promise<any>>} */ #tasks = new Set(); /** @private @property @type {Promise<void>|null} */ #waiting = null; /** @public @method @param {Task<any>} task @returns {void} */ add(task) { this.#tasks.add(task.wait()); } /** @public @async @method @returns {Promise<void>} */ async wait() { if (this.#waiting !== null) return this.#waiting; await (this.#waiting = new Task(async () => { while (true) { const snapshot = new Set(this.#tasks); await Promise.all(snapshot); if (snapshot.size === this.#tasks.size) break; } this.#tasks.clear(); this.#waiting = null; }).wait()); } }