From a5760014a3087211a1cdf892f7e3e89993ededae Mon Sep 17 00:00:00 2001 From: Martin Karkowski Date: Tue, 16 Aug 2022 16:45:30 +0200 Subject: [PATCH] Providing update. --- CHANGELOG.md | 21 ++- contribute/VERSION | 2 +- .../InstanceManager/InstanceManager.ts | 3 +- lib/helpers/mapMethods.spec.ts | 60 +++++++- lib/helpers/mapMethods.ts | 129 +++++++++++++----- lib/helpers/mergedData.spec.ts | 14 +- lib/helpers/mergedData.ts | 4 +- lib/helpers/objectMethods.ts | 24 ++-- package.json | 2 +- 9 files changed, 198 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dcb22f..112367a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -166,4 +166,23 @@ Inital commit, which is working with the browser # 1.3.1 - Fixes: - `py-helpers`: Now using correct elements. - - Small comments etc. \ No newline at end of file + - Small comments etc. + +# 1.3.2 + - Fixes: + - `helpers/objectMethods`: The function `convertData` no converts not matching items as well + - `helpers/objectMethods`: The function `tranformMap` no works with empty pathes like `""` + +# 1.3.3 + - Fixes: + - `dispatcher/instanceManager/InstanceManager`: Fixing the Mapbased item + - `dispatcher/RpcManager/RpcManager`: Fixing the Mapbased item + +# 1.3.4 + - reverting 1.3.3 + - Fixes: + - `dispatcher/instanceManager/InstanceManager`: Fixing the Mapbased item + - `dispatcher/RpcManager/RpcManager`: Fixing the Mapbased item + - `helpers/mapMethods*`: Fixing `extractUniqueValues` and some tests. If you want to extract the data of an array please use `+` + - `helpers/mergeData*`: Fixing the Mapbased item + - `helpers/objectMethods*`: Fixing `convertData` function diff --git a/contribute/VERSION b/contribute/VERSION index 6261a05..8c9698a 100644 --- a/contribute/VERSION +++ b/contribute/VERSION @@ -1 +1 @@ -1.3.1 \ No newline at end of file +1.3.4 \ No newline at end of file diff --git a/lib/dispatcher/InstanceManager/InstanceManager.ts b/lib/dispatcher/InstanceManager/InstanceManager.ts index 7dc115a..aa7cabb 100644 --- a/lib/dispatcher/InstanceManager/InstanceManager.ts +++ b/lib/dispatcher/InstanceManager/InstanceManager.ts @@ -202,7 +202,8 @@ export class NopeInstanceManager implements INopeInstanceManager { const _this = this; this._mappingOfRemoteDispatchersAndGenerators = new Map(); this.constructors = new MapBasedMergeData( - this._mappingOfRemoteDispatchersAndGenerators + this._mappingOfRemoteDispatchersAndGenerators, + "+" ) as MapBasedMergeData; this._mappingOfRemoteDispatchersAndInstances = new Map(); diff --git a/lib/helpers/mapMethods.spec.ts b/lib/helpers/mapMethods.spec.ts index 12b6f59..25071bd 100644 --- a/lib/helpers/mapMethods.spec.ts +++ b/lib/helpers/mapMethods.spec.ts @@ -37,22 +37,25 @@ describe("mapMethods", function () { assert.isTrue([...result][0] === "b", "Element is element"); }); it("nested-array", function () { - const m = new Map(); + const m = new Map(); m.set("a", { a: ["b"] }); m.set("b", { a: ["b"] }); - const result = extractUniqueValues(m, "a"); + m.set("b", { b: ["b"] }); + m.set("b", { a: ["c"] }); + const result = extractUniqueValues(m, "a/+"); assert.isTrue( - result.size === 1, + result.size === 2, "Elements have the same identity, but should be differend" ); - assert.isTrue([...result][0] === "b", "Element is element"); + const r = [...result].sort(); + assert.isTrue(r[0] === "b", "Element is element"); }); it("flat-array", function () { const m = new Map(); m.set("a", ["a"]); m.set("b", ["a", "b"]); - const result = extractUniqueValues(m); + const result = extractUniqueValues(m, "+"); expect(result.size).to.equal(2); assert.isTrue( result.size === 2, @@ -66,7 +69,7 @@ describe("mapMethods", function () { const m = new Map(); m.set("a", { a: ["b"] }); m.set("b", { a: ["c", "d"] }); - const result = extractUniqueValues(m, "a"); + const result = extractUniqueValues(m, "a/+"); assert.isTrue( result.size === 3, @@ -74,5 +77,50 @@ describe("mapMethods", function () { ); assert.deepEqual(["b", "c", "d"], [...result], "Items are missing"); }); + it("nested-object, different key", function () { + const m = new Map< + string, + { + a: { + id: number; + content: string; + }[]; + } + >(); + m.set("a", { + a: [ + { + content: "a", + id: 1, + }, + { + content: "b", + id: 2, + }, + ], + }); + m.set("b", { + a: [ + { + content: "c", + id: 1, + }, + { + content: "d", + id: 3, + }, + ], + }); + const result = extractUniqueValues<{ + id: number; + content: string; + }>(m, "a/+/content", "a/+/id"); + + assert.isTrue( + result.size === 3, + "Elements have the same identity, but should be differend" + ); + assert.deepEqual(["a", "b", "d"], [...result], "Items are missing"); + }); }); }); diff --git a/lib/helpers/mapMethods.ts b/lib/helpers/mapMethods.ts index 8a5809b..90d7be3 100644 --- a/lib/helpers/mapMethods.ts +++ b/lib/helpers/mapMethods.ts @@ -4,7 +4,15 @@ * @desc [description] */ -import { convertData, deepEqual, rgetattr } from "./objectMethods"; +import { + convertData, + deepEqual, + rgetattr, + rqueryAttr, + SPLITCHAR, +} from "./objectMethods"; +import { getLeastCommonPathSegment } from "./path"; +import { comparePatternAndPath } from "./pathMatchingMethods"; const __sentinal = { unique: "value", @@ -21,7 +29,7 @@ const __sentinal = { * @param {Map} map The Map * @param {string} [path=""] The Path of the Data to extract. * @param {string} [pathKey=null] The Path of the unique key. If set to `null` -> The Item is selected directly. - * @return {*} {Set} + * @return {Set} */ export function extractUniqueValues( map: Map, @@ -33,50 +41,67 @@ export function extractUniqueValues( } if (path !== pathKey) { - const items = extractValues(map, path) as D[]; + // Get the Common segment of the item. + const commonSegment = getLeastCommonPathSegment([path, pathKey], { + considerSingleLevel: false, + considerMultiLevel: false, + }); + + if (commonSegment == false) { + return new Set(); + } + + const commonSegmentLength = commonSegment.split(SPLITCHAR).length; + + const _relPathContent = path + .split(SPLITCHAR) + .slice(commonSegmentLength) + .join(SPLITCHAR); + const _relPathKey = pathKey + .split(SPLITCHAR) + .slice(commonSegmentLength) + .join(SPLITCHAR); + + // Now use that segment to extract the common data. + const items = extractValues(map, commonSegment) as D[]; const itemKeys = new Set(); const ret: D[] = []; for (const item of items) { - const key = rgetattr(item, pathKey); - + const key = _relPathKey ? rgetattr(item, _relPathKey) : item; + const data = _relPathContent ? rgetattr(item, _relPathContent) : item; if (!itemKeys.has(key)) { itemKeys.add(key); - ret.push(item); + ret.push(data); } - - return new Set(ret); } + + return new Set(ret); } return new Set(extractValues(map, path)); } +/** + * Helper to extract values of the map. Therefore the path must be provided. + * @param map + * @param path + * @returns + */ export function extractValues(map: Map, path = ""): Array { const s = new Array(); for (const v of map.values()) { if (path) { - const data: D | typeof __sentinal = rgetattr(v, path, __sentinal); - if (data !== __sentinal) { - if (Array.isArray(data)) { - data.map((item) => { - return s.push(item); - }); - } else { - s.push(data as D); - } - } + const data: { path: string; data: D }[] = rqueryAttr(v, path); + data.map((item) => { + return s.push(item.data); + }); } else { - if (Array.isArray(v)) { - v.map((_v) => { - s.push(_v as D); - }); - } else { - s.push(v as any as D); - } + // Add the item. + s.push(v); } } @@ -119,27 +144,69 @@ export function tranformMap< key: string; }[] = []; - if (pathExtractedKey) { + let onlyValidProps = true; + + if (typeof pathExtractedKey === "string") { props.push({ key: "key", query: pathExtractedKey, }); + onlyValidProps = onlyValidProps && pathExtractedKey.length > 0; } - if (pathExtractedValue) { + if (typeof pathExtractedValue === "string") { props.push({ key: "value", query: pathExtractedValue, }); + onlyValidProps = onlyValidProps && pathExtractedValue.length > 0; } // Iterate over the Entries of the Map. // then we will extract the data stored in the Value. for (const [k, v] of map.entries()) { - const extracted = convertData<{ key: ExtractedKey; value: ExtractedValue }>( - v, - props - ); + let extracted: { + key: ExtractedKey; + value: ExtractedValue; + }[] = []; + + if (onlyValidProps) { + extracted = convertData<{ key: ExtractedKey; value: ExtractedValue }>( + v, + props + ); + } else { + const data: { + key: ExtractedKey; + value: ExtractedValue; + } = { + key: null, + value: null, + }; + + if (typeof pathExtractedKey === "string") { + if (pathExtractedKey.length > 0) { + data.key = rgetattr(v, pathExtractedKey); + } else { + data.key = v; + } + } else { + data.key = k as any; + } + + if (typeof pathExtractedValue === "string") { + if (pathExtractedValue.length > 0) { + data.value = rgetattr(v, pathExtractedValue); + } else { + data.value = v; + } + } else { + data.value = v as any; + } + + // Manually push the items. + extracted.push(data); + } // Store the Key. keyMapping.set(k, new Set()); diff --git a/lib/helpers/mergedData.spec.ts b/lib/helpers/mergedData.spec.ts index 06d5432..e5b6fef 100644 --- a/lib/helpers/mergedData.spec.ts +++ b/lib/helpers/mergedData.spec.ts @@ -97,9 +97,9 @@ describe("MapBasedMergeData", function () { done(); }); - it("data handeling - flat data", function (done) { + it("data handeling - multiple data array", function (done) { const m = new Map(); - const d = new MapBasedMergeData(m); + const d = new MapBasedMergeData(m, "+"); m.set("a", ["a", "b"]); m.set("b", ["c", "b"]); @@ -131,7 +131,7 @@ describe("MapBasedMergeData", function () { it("data subscription - array data", function (done) { const m = new Map(); - const d = new MapBasedMergeData(m); + const d = new MapBasedMergeData(m, "+"); m.set("a", ["a", "b"]); m.set("b", ["c", "b"]); @@ -171,7 +171,6 @@ describe("MapBasedMergeData", function () { expect([...d_1.keyMapping.keys()]).to.contain("a"); expect([...d_1.keyMappingReverse.keys()]).to.contain("keyA"); expect([...d_1.simplified.keys()]).to.contain("keyA"); - expect([...d_1.keyMappingReverse.values()]).to.contain("keyA"); const d_2 = new MapBasedMergeData< string, @@ -181,10 +180,9 @@ describe("MapBasedMergeData", function () { >(m, "data", "key"); d_2.update(); - expect([...d_1.keyMapping.keys()]).to.contain("a"); - expect([...d_1.keyMappingReverse.keys()]).to.contain("keyA"); - expect([...d_1.simplified.keys()]).to.contain("keyA"); - expect([...d_1.keyMappingReverse.keys()]).to.contain("dataB"); + expect([...d_2.keyMapping.keys()]).to.contain("a"); + expect([...d_2.keyMappingReverse.keys()]).to.contain("keyA"); + expect([...d_2.simplified.keys()]).to.contain("keyA"); done(); }); diff --git a/lib/helpers/mergedData.ts b/lib/helpers/mergedData.ts index 4c9ec58..4fe0b94 100644 --- a/lib/helpers/mergedData.ts +++ b/lib/helpers/mergedData.ts @@ -55,7 +55,7 @@ export class MergeData implements IMergeData { * @param {*} [data=this.originalData] * @memberof MergeData */ - public update(data: D = null): void { + public update(data: D = null, force = false): void { if (data !== null) { this.originalData = data; } @@ -66,7 +66,7 @@ export class MergeData implements IMergeData { afterAdding ); - if (diff.removed.size > 0 || diff.added.size > 0) { + if (force || 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. diff --git a/lib/helpers/objectMethods.ts b/lib/helpers/objectMethods.ts index ca9fb98..f84090f 100644 --- a/lib/helpers/objectMethods.ts +++ b/lib/helpers/objectMethods.ts @@ -203,10 +203,6 @@ export function convertData( }) ); - if (!commonPattern) { - throw Error("No common pattern has been found"); - } - props.map((prop) => { ret[prop.key] = rqueryAttr(data, prop.query); }); @@ -217,14 +213,22 @@ export function convertData( // get the item const items = ret[prop.key]; - for (const item of items) { - const result = comparePatternAndPath(commonPattern, item.path); + for (const [idx, item] of items.entries()) { + if (commonPattern !== false) { + const result = comparePatternAndPath(commonPattern, item.path); - if (result.pathToExtractData) { - if (helper[result.pathToExtractData] === undefined) { - helper[result.pathToExtractData] = {}; + if (result.pathToExtractData) { + if (helper[result.pathToExtractData] === undefined) { + helper[result.pathToExtractData] = {}; + } + helper[result.pathToExtractData][prop.key] = item.data; } - helper[result.pathToExtractData][prop.key] = item.data; + } else { + if (helper[idx] === undefined) { + helper[idx] = {}; + } + + helper[idx][prop.key] = item.data; } } } diff --git a/package.json b/package.json index f7f65b9..f793c85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nope", - "version": "1.3.1", + "version": "1.3.4", "description": "NoPE Runtime for Nodejs. For Browser-Support please use nope-browser", "files": [ "dist-nodejs/**/*",