nope/lib/helpers/mergedData.ts

168 lines
4.6 KiB
TypeScript
Raw Permalink Normal View History

2021-11-25 07:43:02 +00:00
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @desc [description]
*/
import { NopeEventEmitter } from "../eventEmitter/nopeEventEmitter";
import { determineDifference } from "../helpers/setMethods";
import { NopeObservable } from "../observables/nopeObservable";
import { INopeEventEmitter, INopeObservable } from "../types/nope";
import {
2022-07-07 07:14:22 +00:00
IMapBasedMergeData,
IMergeData,
} from "../types/nope/nopeHelpers.interface";
import { extractUniqueValues, tranformMap } from "./mapMethods";
2021-11-25 07:43:02 +00:00
export class MergeData<T, D = any> implements IMergeData<T, D> {
/**
* Element which will trig implements IMergeDatager an event containing the changes
*
* @author M.Karkowski
* @type {INopeEventEmitter<{
* added: T[],
* removed: T[]
* }>}
* @memberof MergeData
*/
readonly onChange: INopeEventEmitter<{
added: T[];
removed: T[];
}>;
/**
* Contains the current data.
*
* @author M.Karkowski
* @type {INopeObservable<T[]>}
* @memberof MergeData
*/
readonly data: INopeObservable<T[]>;
constructor(
public originalData: D,
protected _extractData: (data: D) => Set<T>
) {
this.onChange = new NopeEventEmitter();
this.data = new NopeObservable();
this.data.setContent([]);
}
/**
* Update the underlying data.
*
* @author M.Karkowski
* @param {*} [data=this.originalData]
* @memberof MergeData
*/
2022-08-16 14:45:30 +00:00
public update(data: D = null, force = false): void {
2021-11-25 07:43:02 +00:00
if (data !== null) {
this.originalData = data;
}
const afterAdding = this._extractData(this.originalData);
const diff = determineDifference(
new Set(this.data.getContent()),
afterAdding
);
2022-08-16 14:45:30 +00:00
if (force || diff.removed.size > 0 || diff.added.size > 0) {
2021-11-25 07:43:02 +00:00
// Update the currently used subscriptions
this.data.setContent(Array.from(afterAdding));
// Now emit, that there is a new subscription.
this.onChange.emit({
added: Array.from(diff.added),
removed: Array.from(diff.removed),
});
}
}
/**
* Disposes the Element.
*
* @author M.Karkowski
* @memberof MergeData
*/
public dispose() {
this.data.dispose();
this.onChange.dispose();
}
2021-11-25 07:43:02 +00:00
}
2022-07-07 07:14:22 +00:00
export class MapBasedMergeData<
OriginalKey,
OriginalValue,
ExtractedKey = OriginalKey,
ExtractedValue = OriginalValue
>
extends MergeData<ExtractedValue, Map<OriginalKey, OriginalValue>>
implements
IMapBasedMergeData<
OriginalKey,
OriginalValue,
ExtractedKey,
ExtractedValue
>
2021-11-25 07:43:02 +00:00
{
2022-07-07 07:14:22 +00:00
public amountOf: Map<ExtractedKey, number>;
public simplified: Map<ExtractedKey, ExtractedValue>;
public keyMapping: Map<OriginalKey, Set<ExtractedKey>>;
public keyMappingReverse: Map<ExtractedKey, Set<OriginalKey>>;
public conflicts: Map<ExtractedKey, Set<ExtractedValue>>;
public orgKeyToExtractedValue: Map<OriginalKey, Set<ExtractedValue>>;
public extractedKey: ExtractedKey[];
public extractedValue: ExtractedValue[];
2021-11-25 07:43:02 +00:00
2022-07-07 07:14:22 +00:00
constructor(
originalData: Map<OriginalKey, OriginalValue>,
protected _path: keyof OriginalValue | string = "",
protected _pathKey: keyof OriginalValue | string = null
) {
2021-11-25 07:43:02 +00:00
super(originalData, (m) => {
2022-07-07 07:14:22 +00:00
return extractUniqueValues(m, _path as string, _pathKey as string);
2021-11-25 07:43:02 +00:00
});
2022-07-07 07:14:22 +00:00
this.amountOf = new Map<ExtractedKey, number>();
this.simplified = new Map<ExtractedKey, ExtractedValue>();
this.keyMapping = new Map<OriginalKey, Set<ExtractedKey>>();
this.keyMappingReverse = new Map<ExtractedKey, Set<OriginalKey>>();
this.conflicts = new Map<ExtractedKey, Set<ExtractedValue>>();
this.orgKeyToExtractedValue = new Map<OriginalKey, Set<ExtractedValue>>();
this.extractedKey = [];
this.extractedValue = [];
2021-11-25 07:43:02 +00:00
}
/**
* Update the underlying data.
*
* @author M.Karkowski
* @param {*} [data=this.originalData]
* @memberof MergeData
*/
2022-07-07 07:14:22 +00:00
public update(data: Map<OriginalKey, OriginalValue> = null): void {
2021-11-25 07:43:02 +00:00
if (data !== null) {
this.originalData = data;
}
// Now lets update the amount of the data:
2022-07-07 07:14:22 +00:00
const result = tranformMap<ExtractedKey, ExtractedValue, OriginalKey>(
this.originalData,
this._path as string,
this._pathKey as string
);
// Now assign the results to our items.
this.simplified = result.extractedMap;
this.amountOf = result.amountOf;
this.keyMapping = result.keyMapping;
this.keyMappingReverse = result.keyMappingReverse;
this.conflicts = result.conflicts;
this.orgKeyToExtractedValue = result.orgKeyToExtractedValue;
this.extractedKey = [...this.simplified.keys()];
this.extractedValue = [...this.simplified.values()];
2021-11-25 07:43:02 +00:00
super.update(data);
}
}