122 lines
3.0 KiB
TypeScript
122 lines
3.0 KiB
TypeScript
/**
|
|
* @author Martin Karkowski
|
|
* @email m.karkowski@zema.de
|
|
* @create date 2021-11-23 11:04:49
|
|
* @modify date 2021-11-23 11:04:49
|
|
* @desc [description]
|
|
*/
|
|
|
|
import { NopeEventEmitter } from "../eventEmitter/nopeEventEmitter";
|
|
import { determineDifference } from "../helpers/setMethods";
|
|
import { NopeObservable } from "../observables/nopeObservable";
|
|
import { INopeEventEmitter, INopeObservable } from "../types/nope";
|
|
import { IMergeData } from "../types/nope/nopeHelpers.interface";
|
|
import { countElements } from "./arrayMethods";
|
|
import {
|
|
extractUniqueValues,
|
|
extractValues,
|
|
reverse,
|
|
transformValues,
|
|
} from "./mapMethods";
|
|
|
|
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
|
|
*/
|
|
public update(data: D = null): void {
|
|
if (data !== null) {
|
|
this.originalData = data;
|
|
}
|
|
|
|
const afterAdding = this._extractData(this.originalData);
|
|
const diff = determineDifference(
|
|
new Set(this.data.getContent()),
|
|
afterAdding
|
|
);
|
|
|
|
if (diff.removed.size > 0 || diff.added.size > 0) {
|
|
// 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),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
export class MapBasedMergeData<T, K, V>
|
|
extends MergeData<T, Map<K, V>>
|
|
implements IMergeData<T, Map<K, V>>
|
|
{
|
|
public amountOf: Map<T, number>;
|
|
public simplified: Map<K, T>;
|
|
public reverseSimplified: Map<T, Set<K>>;
|
|
|
|
constructor(originalData: Map<K, V>, protected _path = "") {
|
|
super(originalData, (m) => {
|
|
return extractUniqueValues(m, _path);
|
|
});
|
|
|
|
this.amountOf = new Map();
|
|
}
|
|
|
|
/**
|
|
* Update the underlying data.
|
|
*
|
|
* @author M.Karkowski
|
|
* @param {*} [data=this.originalData]
|
|
* @memberof MergeData
|
|
*/
|
|
public update(data: Map<K, V> = null): void {
|
|
if (data !== null) {
|
|
this.originalData = data;
|
|
}
|
|
|
|
// Now lets update the amount of the data:
|
|
this.amountOf = countElements(extractValues(data, this._path));
|
|
this.simplified = transformValues(this.originalData, this._path);
|
|
this.reverseSimplified = reverse(this.simplified);
|
|
|
|
super.update(data);
|
|
}
|
|
}
|