Martin Karkowski
39c50061dc
- Fixes: - pub-sub-system: Fixed `_notify` and `_partialMatchingUpdate` - Added: - pub-sub-system: Listeners receive now: topicOfContent (the path of the data that is extracted), topicOfChange (the path of the data that emitted teh update), topicOfSubscription (the subscription.), - nope repl: Added the context `nope`
114 lines
3.0 KiB
TypeScript
114 lines
3.0 KiB
TypeScript
/**
|
|
* @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<T = unknown>(
|
|
path: string,
|
|
content: T,
|
|
options: Partial<IEventAdditionalData> = {}
|
|
): void {
|
|
return this._pushData(path, 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,
|
|
data: T,
|
|
options: Partial<IEventAdditionalData> = {},
|
|
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;
|
|
}
|