types/observer.js

'use strict';

/**
 * @author schukai GmbH
 */

import {Monster} from '../namespace.js';
import '../types/object.js';

/**
 * an observer manages a callback function
 *
 * you can call the method via the monster namespace `new Monster.Types.Observer()`.
 *
 * ```
 * <script type="module">
 * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.0.14/dist/modules/types/observer.js';
 * console.log(new Monster.Types.Observer())
 * console.log(new Monster.Types.Observer())
 * </script>
 * ```
 *
 * Alternatively, you can also integrate this function individually.
 *
 * ```
 * <script type="module">
 * import {Observer} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.0.14/dist/modules/types/observer.js';
 * console.log(Observer())
 * console.log(Observer())
 * </script>
 * ```
 *
 * @since 1.0.0
 * @copyright schukai GmbH
 * @memberOf Monster/Types
 */
class Observer extends Monster.Types.Object {

    constructor(callback, ...args) {
        super();

        if (typeof callback !== 'function') {
            throw new Error("observer callback must be a function")
        }

        this.callback = callback;
        this.arguments = args;
        this.tags = new Set;
    }

    addTag(tag) {
        this.tags.add(tag);
        return this;
    }

    removeTag(tag) {
        this.tags.delete(tag);
        return this;
    }

    getTags() {
        return this.tags
    }

    hasTag(tag) {
        return this.tags.has(tag)
    }

    update(subject) {
        let self = this;

        return new Promise(function (resolve, reject) {
            if (!(subject instanceof Object)) {
                reject("subject must be an object");
            }
            let result = self.callback.apply(subject, self.arguments);
            resolve(result);

        });

    };

}

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