UNPKG

delphirtl

Version:
234 lines 15.1 kB
"use strict"; /* * A simple messaging system by Chee Wee Chua, Jul 2022 * See examples in ./examples * */ Object.defineProperty(exports, "__esModule", { value: true }); exports.SFunction = exports.SMethodNotImplemented = exports.TMessageManager = exports.TMessage = void 0; const SMethodNotImplemented = "Method not implemented."; exports.SMethodNotImplemented = SMethodNotImplemented; const SFunction = 'function'; exports.SFunction = SFunction; /** * Base class from which other classes derive from * * @abstract * @class TMessageBase * @typedef {TMessageBase} * @template T * @implements {IMessage<T>} * @implements {IMessageName} * @category Messaging */ class TMessageBase { constructor(aValue) { this.value = aValue; } getName() { return typeof this.value; } } /** * Description placeholder * * @class TMessage * @typedef {TMessage} * @template T * @extends {TMessageBase<T>} * @category Messaging */ class TMessage extends TMessageBase { } exports.TMessage = TMessage; /** * Description placeholder * * @class TCallback * @typedef {TCallback} * @template T * @implements {IMessageName} * @category Messaging */ class TCallback { getName() { throw new Error(SMethodNotImplemented); } constructor(aCallback) { this.fCallback = aCallback; } } /** * TMessageManager enables messaging between different code points. * * @class TMessageManager * @typedef {TMessageManager} * @category Messaging */ class TMessageManager { constructor() { this.reset(); } reset() { // Enums works similarly to number during runtime, so, disable Number as a native type from working this.fDisabledTypes = []; this.fDisabledTypes.push(Number.name); this.fListeners = new Map(); } disableType(aType) { const lTypeName = (typeof aType === 'function') ? (aType.name) : aType; this.fDisabledTypes.push(lTypeName); } enableType(aType) { let lIndex = -1; const lTypeName = (typeof aType === 'function') ? (aType.name) : aType; for (let i = 0; i < this.fDisabledTypes.length; i++) { if (lTypeName === this.fDisabledTypes[i]) { lIndex = i; break; } } if (lIndex != -1) { this.fDisabledTypes.splice(lIndex, 1); } } ensureTypeEnabled(aSuffix) { for (const lType of this.fDisabledTypes) { if (aSuffix === lType) { throw new Error(`${aSuffix} not enabled`); } } } typesDisabled() { return this.fDisabledTypes; } static getDefaultManager() { if (!TMessageManager.fDefaultManager) { this.fDefaultManager = new TMessageManager(); } return this.fDefaultManager; } /** * Sends the given message to listeners that subscribes to the given class. * * @template {MessageType} T * @param {SubscriptionIdentifierType} aClass * @param {T} aMessage * @category Messaging */ sendMessage(aClass, aMessage) { const lClassName = (typeof aClass === 'function') ? (aClass.name) : aClass; const lMessageClassName = `${lClassName.toUpperCase()}`; const lListenerList = this.fListeners.get(lMessageClassName); if (lListenerList !== undefined) { for (const lListener of lListenerList) { try { lListener(aMessage); } catch (e) { // keep going } } } } /** * Sends a wrapped message to listeners on the given class * * @template {MessageType} T * @param {SubscriptionIdentifierType} aClass * @param {TMessage<T>} aMessage */ sendWrappedMessage(aClass, aMessage) { const lClassName = (typeof aMessage.value) != "object" ? (typeof aMessage.value).toUpperCase() : aMessage.value.constructor.name.toUpperCase(); const lMessageClassName = `${aMessage.constructor.name}<${lClassName}>`; const lListenerList = this.fListeners.get(lMessageClassName); if (lListenerList !== undefined) { for (const lListener of lListenerList) { try { lListener(aMessage); } catch (e) { // keep going } } } } /** * Subscribes to the given class and receives the given message * * @template {MessageType} T * @param {SubscriptionIdentifierType} aClass * @param {(aMessage: T) => void} aMessageListener * @returns {SubscriptionIndex} * @category Messaging */ subscribeToMessage(aClass, aMessageListener) { const lSuffix = (typeof aClass === 'function') ? (aClass.name) : aClass; this.ensureTypeEnabled(lSuffix); const lMessageClassName = `${lSuffix.toUpperCase()}`; // TMessage<Number>, TMessage<String>, TMessage<Date> let lListenerList = this.fListeners.get(lMessageClassName); // name is erased, so aMessageClass is always TMessage if (!lListenerList) { lListenerList = new Array(); this.fListeners.set(lMessageClassName, lListenerList); } const index = lListenerList.push(aMessageListener) - 1; return index; } /** * Subscribes to the wrapped message on the given class * * @template {MessageType} T * @param {SubscriptionIdentifierType} aClass * @param {(aMessage: TMessage<T>) => void} aMessageListener * @returns {SubscriptionIndex} */ subscribeToWrappedMessage(aClass, aMessageListener) { const lSuffix = (typeof aClass === 'function') ? (aClass.name) : aClass; this.ensureTypeEnabled(lSuffix); const lMessageClassName = `${TMessage.name}<${lSuffix.toUpperCase()}>`; // TMessage<NUMBER>, TMessage<STRING>, TMessage<DATE> let lListenerList = this.fListeners.get(lMessageClassName); // name is erased, so aMessageClass is always TMessage if (!lListenerList) { lListenerList = new Array(); this.fListeners.set(lMessageClassName, lListenerList); } const index = lListenerList.push(aMessageListener) - 1; return index; } /** * Unsubscribes from messages on the given class * * @public * @param {SubscriptionIdentifierType} aClass * @param {SubscriptionIndex} aSubscriptionIndex * @category Messaging */ unsubscribe(aClass, aSubscriptionIndex) { const lClassName = (typeof aClass === 'function') ? (aClass.name) : aClass; const lMessageClassName = `${lClassName.toUpperCase()}`; const lListenerList = this.fListeners.get(lMessageClassName); if (lListenerList != undefined) { lListenerList.splice(aSubscriptionIndex, 1); if (lListenerList.length === 0) { this.fListeners.delete(lMessageClassName); } } } /** * Unsubscribes from the wrapped message on the given class * * @param {SubscriptionIdentifierType} aClass * @param {SubscriptionIndex} aSubscriptionIndex * @category Messaging */ unsubscribeWrappedMessage(aClass, aSubscriptionIndex) { const lSuffix = (typeof aClass === 'function') ? (aClass.name) : aClass; const lMessageClassName = `${TMessage.name}<${lSuffix.toUpperCase()}>`; // TMessage<NUMBER>, TMessage<STRING>, TMessage<DATE> let lListenerList = this.fListeners.get(lMessageClassName); if (lListenerList !== undefined) { lListenerList.splice(aSubscriptionIndex, 1); if (lListenerList.length === 0) { this.fListeners.delete(lMessageClassName); } } } } exports.TMessageManager = TMessageManager; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzc2FnaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21lc3NhZ2luZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7RUFJRTs7O0FBRUYsTUFBTSxxQkFBcUIsR0FBRyx5QkFBeUIsQ0FBQztBQTBTcEQsc0RBQXFCO0FBelN6QixNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUM7QUF5U0YsOEJBQVM7QUFuUXBDOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFlLFlBQVk7SUFFdkIsWUFBWSxNQUFTLElBQUksSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUEsQ0FBQyxDQUFDO0lBQzlDLE9BQU87UUFDSCxPQUFPLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUM3QixDQUFDO0NBQ0o7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sUUFBWSxTQUFRLFlBQWU7Q0FDeEM7QUFvT0csNEJBQVE7QUF0Tlo7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFNBQVM7SUFDWCxPQUFPO1FBQ0gsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCxZQUFZLFNBQXVCO1FBQy9CLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0lBQy9CLENBQUM7Q0FDSjtBQU1EOzs7Ozs7R0FNRztBQUNILE1BQU0sZUFBZTtJQUtqQjtRQUNJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRUQsS0FBSztRQUNELG1HQUFtRztRQUNuRyxJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFTSxXQUFXLENBQUMsS0FBaUM7UUFDaEQsTUFBTSxTQUFTLEdBQUcsQ0FBQyxP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