/** * @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 implements IMergeData { /** * 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} * @memberof MergeData */ readonly data: INopeObservable; constructor( public originalData: D, protected _extractData: (data: D) => Set ) { 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), }); } } /** * Disposes the Element. * * @author M.Karkowski * @memberof MergeData */ public dispose() { this.data.dispose(); this.onChange.dispose(); } } export class MapBasedMergeData extends MergeData> implements IMergeData> { public amountOf: Map; public simplified: Map; public reverseSimplified: Map>; constructor(originalData: Map, protected _path = "") { super(originalData, (m) => { return extractUniqueValues(m, _path); }); this.amountOf = new Map(); this.simplified = new Map(); this.reverseSimplified = new Map(); } /** * Update the underlying data. * * @author M.Karkowski * @param {*} [data=this.originalData] * @memberof MergeData */ public update(data: Map = null): void { if (data !== null) { this.originalData = data; } // Now lets update the amount of the data: this.amountOf = countElements(extractValues(this.originalData, this._path)); this.simplified = transformValues(this.originalData, this._path); this.reverseSimplified = reverse(this.simplified); super.update(data); } }