nope/lib/pubSub/nopeDataPubSubSystem.ts

76 lines
2.5 KiB
TypeScript
Raw Normal View History

2021-11-14 22:16:07 +00:00
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2021-11-12 12:25:30
* @modify date 2021-11-12 12:25:30
* @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 } 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<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<T = unknown>(path: string, content: T, options: IEventAdditionalData = {}): void {
return this._pushData(path, content, options);
}
// Function to pull the Last Data of the Topic
public pullData<T = unknown, D = null>(topic: string, _default: D = null): T {
return this._pullData<T, D>(topic, _default);
}
public patternbasedPullData<T = unknown, D = null>(pattern: string, _default: D = null): { path: string, data: T }[] {
return this._patternbasedPullData<T, D>(pattern, _default);
}
public patternBasedPush<T = unknown>(pattern: string, content: T, options: IEventAdditionalData = {}): void {
// To extract the data based on a Pattern,
// we firstly, we check if we would affect the data.
if (!containsWildcards(pattern)) {
this.pushData(pattern, content, options);
}
if (pattern.includes(MULTI_LEVEL_WILDCARD)) {
throw Error("You can only use single-level wildcards in this action");
}
const flattenData = flattenObject(this._data);
for (const path of flattenData.keys()) {
if (comparePatternAndPath(pattern, path).affectedOnSameLevel) {
this.pushData(path, content, options);
}
}
}
protected _sendCurrentDataOnSubscription = true;
}