/** * @author Martin Karkowski * @email m.karkowski@zema.de * @create date 2021-11-12 12:25:30 * @modify date 2022-01-06 09:54:40 * @desc [description] */ import { memoize } from "lodash"; import { deepClone, flattenObject } from "../helpers/objectMethods"; import { comparePatternAndPath as _comparePatternAndPath, containsWildcards, MULTI_LEVEL_WILDCARD, } from "../helpers/pathMatchingMethods"; import { IDataPubSubSystem, IEventAdditionalData, INopeObservable, INopeTopicWithDirectAccess, ITopicSetContentOptions, } from "../types/nope/index"; import { PubSubSystemBase } from "./nopePubSubSystem"; // Create a memoized function for the pattern matching (its way faster) const comparePatternAndPath = memoize( (pattern: string, path: string) => { return _comparePatternAndPath(pattern, path); }, (pattern: string, path: string) => { return `${pattern}-${path}`; } ); export class DataPubSubSystem extends PubSubSystemBase< ITopicSetContentOptions, INopeObservable, INopeTopicWithDirectAccess > implements IDataPubSubSystem { /** * A Getter to return a COPY of the item. Outside of the system, * you'll never receive the original object. * * @author M.Karkowski * @readonly * @type {unknown} * @memberof PubSubSystemBase */ public get data(): unknown { return deepClone(this._data); } public pushData( path: string, content: T, options: Partial = {} ): void { return this._pushData(path, path, content, options); } // Function to pull the Last Data of the Topic public pullData(topic: string, _default: D = null): T { return this._pullData(topic, _default); } public patternbasedPullData( pattern: string, _default: D = null ): { path: string; data: T }[] { return this._patternbasedPullData(pattern, _default); } public patternBasedPush( pattern: string, data: T, options: Partial = {}, fast = false // Flag to emit single changes or all changes. ): void { // To extract the data based on a Pattern, // we firstly, we check if we would affect the data. if (!containsWildcards(pattern)) { return this._pushData(pattern, pattern, data, options); } if (pattern.includes(MULTI_LEVEL_WILDCARD)) { throw Error("You can only use single-level wildcards in this action"); } const flattenData = flattenObject(this._data); const _options = this._updateOptions(options); for (const path of flattenData.keys()) { if (comparePatternAndPath(pattern, path).affectedOnSameLevel) { this._pushData(path, pattern, data, _options, fast); } } if (fast) { // Its better for us, to just store the incremental changes // with the pattern this.onIncrementalDataChange.emit({ path: pattern, data, ..._options, }); } } protected _sendCurrentDataOnSubscription = true; }