nope/lib/pubSub/nopeDataPubSubSystem.ts
Martin Karkowski d785f72667 Merge branch 'dev' of https://github.com/anti-held-333/nope-backend into lib
# Conflicts:
#	lib/cli/runNopeBackend.ts
#	lib/dispatcher/nopeDispatcher.ts
#	lib/types/nope/nopeDispatcher.interface.ts
#	modules/wamo/src/wamo.basemodule.module.ts
#	modules/wamo/src/wamo.converter.module.ts
#	modules/wamo/src/wamo.lineManager.module.ts
#	modules/wamo/src/wamo.transportManager.simple.module.ts
2022-01-16 20:38:45 +01:00

113 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,
} 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<
IEventAdditionalData,
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, 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, 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, data, _options, fast);
}
}
if (fast) {
// Its better for us, to just store the incremental changes
// with the pattern
this.onIncrementalDataChange.emit({
name: pattern,
data,
..._options,
});
}
}
protected _sendCurrentDataOnSubscription = true;
}