Providing update.

This commit is contained in:
Martin Karkowski 2022-08-16 16:45:30 +02:00
parent 8ce9334eab
commit a5760014a3
9 changed files with 198 additions and 61 deletions

View File

@ -167,3 +167,22 @@ Inital commit, which is working with the browser
- Fixes: - Fixes:
- `py-helpers`: Now using correct elements. - `py-helpers`: Now using correct elements.
- Small comments etc. - 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

View File

@ -1 +1 @@
1.3.1 1.3.4

View File

@ -202,7 +202,8 @@ export class NopeInstanceManager implements INopeInstanceManager {
const _this = this; const _this = this;
this._mappingOfRemoteDispatchersAndGenerators = new Map(); this._mappingOfRemoteDispatchersAndGenerators = new Map();
this.constructors = new MapBasedMergeData( this.constructors = new MapBasedMergeData(
this._mappingOfRemoteDispatchersAndGenerators this._mappingOfRemoteDispatchersAndGenerators,
"+"
) as MapBasedMergeData<string, string[], string, string>; ) as MapBasedMergeData<string, string[], string, string>;
this._mappingOfRemoteDispatchersAndInstances = new Map(); this._mappingOfRemoteDispatchersAndInstances = new Map();

View File

@ -37,22 +37,25 @@ describe("mapMethods", function () {
assert.isTrue([...result][0] === "b", "Element is element"); assert.isTrue([...result][0] === "b", "Element is element");
}); });
it("nested-array", function () { it("nested-array", function () {
const m = new Map<string, { a: string[] }>(); const m = new Map<string, { a?: string[]; b?: string[] }>();
m.set("a", { a: ["b"] }); m.set("a", { a: ["b"] });
m.set("b", { 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<string>(m, "a/+");
assert.isTrue( assert.isTrue(
result.size === 1, result.size === 2,
"Elements have the same identity, but should be differend" "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 () { it("flat-array", function () {
const m = new Map<string, string[]>(); const m = new Map<string, string[]>();
m.set("a", ["a"]); m.set("a", ["a"]);
m.set("b", ["a", "b"]); m.set("b", ["a", "b"]);
const result = extractUniqueValues(m); const result = extractUniqueValues(m, "+");
expect(result.size).to.equal(2); expect(result.size).to.equal(2);
assert.isTrue( assert.isTrue(
result.size === 2, result.size === 2,
@ -66,7 +69,7 @@ describe("mapMethods", function () {
const m = new Map<string, { a: string[] }>(); const m = new Map<string, { a: string[] }>();
m.set("a", { a: ["b"] }); m.set("a", { a: ["b"] });
m.set("b", { a: ["c", "d"] }); m.set("b", { a: ["c", "d"] });
const result = extractUniqueValues(m, "a"); const result = extractUniqueValues(m, "a/+");
assert.isTrue( assert.isTrue(
result.size === 3, result.size === 3,
@ -74,5 +77,50 @@ describe("mapMethods", function () {
); );
assert.deepEqual(["b", "c", "d"], [...result], "Items are missing"); 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");
});
}); });
}); });

View File

@ -4,7 +4,15 @@
* @desc [description] * @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 = { const __sentinal = {
unique: "value", unique: "value",
@ -21,7 +29,7 @@ const __sentinal = {
* @param {Map<K, V>} map The Map * @param {Map<K, V>} map The Map
* @param {string} [path=""] The Path of the Data to extract. * @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. * @param {string} [pathKey=null] The Path of the unique key. If set to `null` -> The Item is selected directly.
* @return {*} {Set<D>} * @return {Set<D>}
*/ */
export function extractUniqueValues<D, K = any, V = any>( export function extractUniqueValues<D, K = any, V = any>(
map: Map<K, V>, map: Map<K, V>,
@ -33,50 +41,67 @@ export function extractUniqueValues<D, K = any, V = any>(
} }
if (path !== pathKey) { 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 itemKeys = new Set();
const ret: D[] = []; const ret: D[] = [];
for (const item of items) { 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)) { if (!itemKeys.has(key)) {
itemKeys.add(key); itemKeys.add(key);
ret.push(item); ret.push(data);
}
} }
return new Set(ret); return new Set(ret);
} }
}
return new Set(extractValues(map, path)); 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<D, K>(map: Map<K, any>, path = ""): Array<D> { export function extractValues<D, K>(map: Map<K, any>, path = ""): Array<D> {
const s = new Array<D>(); const s = new Array<D>();
for (const v of map.values()) { for (const v of map.values()) {
if (path) { if (path) {
const data: D | typeof __sentinal = rgetattr(v, path, __sentinal); const data: { path: string; data: D }[] = rqueryAttr(v, path);
if (data !== __sentinal) {
if (Array.isArray(data)) {
data.map((item) => { data.map((item) => {
return s.push(item); return s.push(item.data);
}); });
} else { } else {
s.push(data as D); // Add the item.
} s.push(v);
}
} else {
if (Array.isArray(v)) {
v.map((_v) => {
s.push(_v as D);
});
} else {
s.push(v as any as D);
}
} }
} }
@ -119,27 +144,69 @@ export function tranformMap<
key: string; key: string;
}[] = []; }[] = [];
if (pathExtractedKey) { let onlyValidProps = true;
if (typeof pathExtractedKey === "string") {
props.push({ props.push({
key: "key", key: "key",
query: pathExtractedKey, query: pathExtractedKey,
}); });
onlyValidProps = onlyValidProps && pathExtractedKey.length > 0;
} }
if (pathExtractedValue) { if (typeof pathExtractedValue === "string") {
props.push({ props.push({
key: "value", key: "value",
query: pathExtractedValue, query: pathExtractedValue,
}); });
onlyValidProps = onlyValidProps && pathExtractedValue.length > 0;
} }
// Iterate over the Entries of the Map. // Iterate over the Entries of the Map.
// then we will extract the data stored in the Value. // then we will extract the data stored in the Value.
for (const [k, v] of map.entries()) { for (const [k, v] of map.entries()) {
const extracted = convertData<{ key: ExtractedKey; value: ExtractedValue }>( let extracted: {
key: ExtractedKey;
value: ExtractedValue;
}[] = [];
if (onlyValidProps) {
extracted = convertData<{ key: ExtractedKey; value: ExtractedValue }>(
v, v,
props 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. // Store the Key.
keyMapping.set(k, new Set()); keyMapping.set(k, new Set());

View File

@ -97,9 +97,9 @@ describe("MapBasedMergeData", function () {
done(); done();
}); });
it("data handeling - flat data", function (done) { it("data handeling - multiple data array", function (done) {
const m = new Map<string, string[]>(); const m = new Map<string, string[]>();
const d = new MapBasedMergeData(m); const d = new MapBasedMergeData(m, "+");
m.set("a", ["a", "b"]); m.set("a", ["a", "b"]);
m.set("b", ["c", "b"]); m.set("b", ["c", "b"]);
@ -131,7 +131,7 @@ describe("MapBasedMergeData", function () {
it("data subscription - array data", function (done) { it("data subscription - array data", function (done) {
const m = new Map<string, string[]>(); const m = new Map<string, string[]>();
const d = new MapBasedMergeData(m); const d = new MapBasedMergeData(m, "+");
m.set("a", ["a", "b"]); m.set("a", ["a", "b"]);
m.set("b", ["c", "b"]); m.set("b", ["c", "b"]);
@ -171,7 +171,6 @@ describe("MapBasedMergeData", function () {
expect([...d_1.keyMapping.keys()]).to.contain("a"); expect([...d_1.keyMapping.keys()]).to.contain("a");
expect([...d_1.keyMappingReverse.keys()]).to.contain("keyA"); expect([...d_1.keyMappingReverse.keys()]).to.contain("keyA");
expect([...d_1.simplified.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< const d_2 = new MapBasedMergeData<
string, string,
@ -181,10 +180,9 @@ describe("MapBasedMergeData", function () {
>(m, "data", "key"); >(m, "data", "key");
d_2.update(); d_2.update();
expect([...d_1.keyMapping.keys()]).to.contain("a"); expect([...d_2.keyMapping.keys()]).to.contain("a");
expect([...d_1.keyMappingReverse.keys()]).to.contain("keyA"); expect([...d_2.keyMappingReverse.keys()]).to.contain("keyA");
expect([...d_1.simplified.keys()]).to.contain("keyA"); expect([...d_2.simplified.keys()]).to.contain("keyA");
expect([...d_1.keyMappingReverse.keys()]).to.contain("dataB");
done(); done();
}); });

View File

@ -55,7 +55,7 @@ export class MergeData<T, D = any> implements IMergeData<T, D> {
* @param {*} [data=this.originalData] * @param {*} [data=this.originalData]
* @memberof MergeData * @memberof MergeData
*/ */
public update(data: D = null): void { public update(data: D = null, force = false): void {
if (data !== null) { if (data !== null) {
this.originalData = data; this.originalData = data;
} }
@ -66,7 +66,7 @@ export class MergeData<T, D = any> implements IMergeData<T, D> {
afterAdding 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 // Update the currently used subscriptions
this.data.setContent(Array.from(afterAdding)); this.data.setContent(Array.from(afterAdding));
// Now emit, that there is a new subscription. // Now emit, that there is a new subscription.

View File

@ -203,10 +203,6 @@ export function convertData<T>(
}) })
); );
if (!commonPattern) {
throw Error("No common pattern has been found");
}
props.map((prop) => { props.map((prop) => {
ret[prop.key] = rqueryAttr(data, prop.query); ret[prop.key] = rqueryAttr(data, prop.query);
}); });
@ -217,7 +213,8 @@ export function convertData<T>(
// get the item // get the item
const items = ret[prop.key]; const items = ret[prop.key];
for (const item of items) { for (const [idx, item] of items.entries()) {
if (commonPattern !== false) {
const result = comparePatternAndPath(commonPattern, item.path); const result = comparePatternAndPath(commonPattern, item.path);
if (result.pathToExtractData) { if (result.pathToExtractData) {
@ -226,6 +223,13 @@ export function convertData<T>(
} }
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;
}
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "nope", "name": "nope",
"version": "1.3.1", "version": "1.3.4",
"description": "NoPE Runtime for Nodejs. For Browser-Support please use nope-browser", "description": "NoPE Runtime for Nodejs. For Browser-Support please use nope-browser",
"files": [ "files": [
"dist-nodejs/**/*", "dist-nodejs/**/*",