/** * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright (c) KALEIDOS INC */ /** * Change controller is responsible of notifying when a change happens. */ export class ChangeController extends EventTarget { /** * Keeps the timeout id. * * @type {number} */ #timeout = null; /** * Keeps the time at which we're going to * call the debounced change calls. * * @type {number} */ #time = 1000; /** * Keeps if we have some pending changes or not. * * @type {boolean} */ #hasPendingChanges = false; /** * Constructor * * @param {number} [time=500] */ constructor(time = 500) { super() if (typeof time === "number" && (!Number.isInteger(time) || time <= 0)) { throw new TypeError("Invalid time"); } this.#time = time ?? 500; } /** * Indicates that there are some pending changes. * * @type {boolean} */ get hasPendingChanges() { return this.#hasPendingChanges; } #onTimeout = () => { this.dispatchEvent(new Event("change")); }; /** * Tells the ChangeController that a change has been made * but that you need to delay the notification (and debounce) * for sometime. */ notifyDebounced() { this.#hasPendingChanges = true; clearTimeout(this.#timeout); this.#timeout = setTimeout(this.#onTimeout, this.#time); } /** * Tells the ChangeController that a change should be notified * immediately. */ notifyImmediately() { clearTimeout(this.#timeout); this.#onTimeout(); } /** * Disposes the referenced resources. */ dispose() { if (this.hasPendingChanges) { this.notifyImmediately(); } clearTimeout(this.#timeout); } } export default ChangeController;