nope/lib/pubSub/nopeDataPubSubSystem.ts

114 lines
3.0 KiB
TypeScript
Raw Permalink 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 2022-01-06 09:54:40
2021-11-14 22:16:07 +00:00
* @desc [description]
*/
import { memoize } from "lodash";
import { deepClone, flattenObject } from "../helpers/objectMethods";
2021-12-04 07:25:26 +00:00
import {
comparePatternAndPath as _comparePatternAndPath,
containsWildcards,
MULTI_LEVEL_WILDCARD,
} from "../helpers/pathMatchingMethods";
import {
IDataPubSubSystem,
IEventAdditionalData,
INopeObservable,
INopeTopicWithDirectAccess,
ITopicSetContentOptions,
2021-12-04 07:25:26 +00:00
} from "../types/nope/index";
2021-11-14 22:16:07 +00:00
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}`;
}
);
2021-12-04 07:25:26 +00:00
export class DataPubSubSystem
extends PubSubSystemBase<
ITopicSetContentOptions,
INopeObservable,
INopeTopicWithDirectAccess
>
2021-12-04 07:25:26 +00:00
implements IDataPubSubSystem
{
2021-11-14 22:16:07 +00:00
/**
* 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);
}
2021-12-04 07:25:26 +00:00
public pushData<T = unknown>(
path: string,
content: T,
2022-01-10 06:52:05 +00:00
options: Partial<IEventAdditionalData> = {}
2021-12-04 07:25:26 +00:00
): void {
return this._pushData(path, path, content, options);
2021-11-14 22:16:07 +00:00
}
// 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);
}
2021-12-04 07:25:26 +00:00
public patternbasedPullData<T = unknown, D = null>(
pattern: string,
_default: D = null
): { path: string; data: T }[] {
2021-11-14 22:16:07 +00:00
return this._patternbasedPullData<T, D>(pattern, _default);
}
2021-12-04 07:25:26 +00:00
public patternBasedPush<T = unknown>(
pattern: string,
data: T,
options: Partial<IEventAdditionalData> = {},
fast = false // Flag to emit single changes or all changes.
2021-12-04 07:25:26 +00:00
): void {
2021-11-14 22:16:07 +00:00
// 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);
2021-11-14 22:16:07 +00:00
}
if (pattern.includes(MULTI_LEVEL_WILDCARD)) {
throw Error("You can only use single-level wildcards in this action");
}
const flattenData = flattenObject(this._data);
2022-01-10 06:52:05 +00:00
const _options = this._updateOptions(options);
2021-11-14 22:16:07 +00:00
for (const path of flattenData.keys()) {
if (comparePatternAndPath(pattern, path).affectedOnSameLevel) {
this._pushData(path, pattern, data, _options, fast);
2021-11-14 22:16:07 +00:00
}
}
if (fast) {
// Its better for us, to just store the incremental changes
// with the pattern
this.onIncrementalDataChange.emit({
2022-01-21 15:17:40 +00:00
path: pattern,
data,
..._options,
});
}
2021-11-14 22:16:07 +00:00
}
protected _sendCurrentDataOnSubscription = true;
}