types/uniquequeue.js

import {Monster, Queue} from "./queue.js";
import {validateObject} from "./validate.js";

/**
 * UniqueQueue class
 *
 * you can call the method via the monster namespace `new Monster.Types.Queue()`.
 *
 * ```
 * <script type="module">
 * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.5.0/dist/modules/types/uniquequeue.js';
 * console.log(new Monster.Types.UniqueQueue())
 * </script>
 * ```
 *
 * Alternatively, you can also integrate this function individually.
 *
 * ```
 * <script type="module">
 * import {ID} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.5.0/dist/modules/types/uniquequeue.js';
 * console.log(new UniqueQueue())
 * </script>
 * ```
 *
 * @since 1.4.0
 * @copyright schukai GmbH
 * @memberOf Monster/Types
 */
class UniqueQueue extends Queue {

    /**
     *
     */
    constructor() {
        super();
        this.unique = new WeakSet();
    }

    /**
     * Add a new element to the end of the queue.
     *
     * @param {object} value
     * @returns {Queue}
     * @throws {TypeError} value is not a object
     */
    add(value) {
        
        validateObject(value);
        
        if (!this.unique.has(value)) {
            this.unique.add(value);
            super.add(value);
        }
        
        return this;
    }

    /**
     * remove all entries
     *
     * @returns {Queue}
     */
    clear() {
        super.clear();
        this.unique = new WeakSet;
        return this;
    }

    /**
     * Remove the element at the front of the queue
     * If the queue is empty, return undefined.
     *
     * @return {object}
     */
    poll() {

        if (this.isEmpty()) {
            return undefined;
        }
        let value = this.data.shift();
        this.unique.delete(value);
        return value;
    }


}

Monster.assignToNamespace('Monster.Types', UniqueQueue);
export {Monster, UniqueQueue}