From d240840d4e3838cd2e0f98648c770846e8a18b5f Mon Sep 17 00:00:00 2001 From: Martin Karkowski Date: Tue, 23 Aug 2022 09:50:45 +0200 Subject: [PATCH] # 1.3.5 - reverting 1.3.3 - Added: - `helpers/stringMethods`: Added the function `varifyString` - Modified: - `dispatcher/instanceManager/InstanceManager`: Adapting the name of the instance to use a valid instance name. - `dispatcher/rpcManager/rpcManager`: Adapting the name of the service to use a valid service name. - `cli/runNopeBackend`: Adapting the name of the service to use a valid service name. # 1.3.6 - Added: - `cli/runNopeBackend`: Added the a helper to add varify the `name`. (see modifications in `dispatcher/InstanceManager/InstanceManager`, `dispatcher/RpcManager/NopeRpcManager`) - Modified: - `helpers/stringMethods`: added function `union` and `difference`. - `helpers/setMethods`: added function `varifyString`. - `types/nope/nopeDispatcher.interface`: Added option `forceUsingValidVarNames` - Fixes: - `types/nope/nopeInstanceManager.interface`: Fixed the typing of `getInstancesOfType` and `createInstance` # 1.3.7 - Fixes: - `helpers/mapMethods`: Fixing `tranformMap`. Now correctly assigning `onlyValidProps` --- CHANGELOG.md | 23 ++++++ contribute/VERSION | 2 +- lib/cli/runNopeBackend.ts | 14 +++- .../InstanceManager/InstanceManager.ts | 6 ++ lib/dispatcher/RpcManager/NopeRpcManager.ts | 8 +- lib/helpers/idMethods.ts | 22 ++--- lib/helpers/limit.ts | 25 +++++- lib/helpers/mapMethods.ts | 4 + lib/helpers/objectMethods.ts | 81 ++++++++++++++++--- lib/helpers/path.ts | 22 ++++- lib/helpers/setMethods.ts | 26 ++++++ lib/helpers/stringMethods.ts | 23 ++++++ lib/profiling/index.nodejs.ts | 4 +- lib/types/nope/nopeDispatcher.interface.ts | 9 +++ .../nope/nopeInstanceManager.interface.ts | 6 +- package.json | 2 +- 16 files changed, 241 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 112367a..70fbf0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -186,3 +186,26 @@ Inital commit, which is working with the browser - `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 + +# 1.3.5 + - reverting 1.3.3 + - Added: + - `helpers/stringMethods`: Added the function `varifyString` + - Modified: + - `dispatcher/instanceManager/InstanceManager`: Adapting the name of the instance to use a valid instance name. + - `dispatcher/rpcManager/rpcManager`: Adapting the name of the service to use a valid service name. + - `cli/runNopeBackend`: Adapting the name of the service to use a valid service name. + +# 1.3.6 + - Added: + - `cli/runNopeBackend`: Added the a helper to add varify the `name`. (see modifications in `dispatcher/InstanceManager/InstanceManager`, `dispatcher/RpcManager/NopeRpcManager`) + - Modified: + - `helpers/stringMethods`: added function `union` and `difference`. + - `helpers/setMethods`: added function `varifyString`. + - `types/nope/nopeDispatcher.interface`: Added option `forceUsingValidVarNames` + - Fixes: + - `types/nope/nopeInstanceManager.interface`: Fixed the typing of `getInstancesOfType` and `createInstance` + +# 1.3.7 + - Fixes: + - `helpers/mapMethods`: Fixing `tranformMap`. Now correctly assigning `onlyValidProps` \ No newline at end of file diff --git a/contribute/VERSION b/contribute/VERSION index 8c9698a..8ed486a 100644 --- a/contribute/VERSION +++ b/contribute/VERSION @@ -1 +1 @@ -1.3.4 \ No newline at end of file +1.3.7 \ No newline at end of file diff --git a/lib/cli/runNopeBackend.ts b/lib/cli/runNopeBackend.ts index 4033f82..d39e300 100644 --- a/lib/cli/runNopeBackend.ts +++ b/lib/cli/runNopeBackend.ts @@ -55,7 +55,9 @@ export interface RunArgs { delay: number; // Flag to force using the selectors. Might have a performance inpact. forceUsingSelectors: boolean; - // Define the Timingsparameter + // Prevents using varified Names + preventVarifiedNames: boolean; + // Define the Timingsparameter; timings: Partial; // The Id to use. id: string; @@ -78,6 +80,7 @@ export const DEFAULT_SETTINGS: RunArgs = { timings: {}, defaultSelector: "first", forceUsingSelectors: false, + preventVarifiedNames: false, logToFile: false, id: generateId(), profile: false, @@ -206,6 +209,13 @@ export async function readInArgs( dest: "forceUsingSelectors", }); + parser.add_argument("--prevent-varified-names", { + help: "Enables Random names for variables etc. including var beginning with number or so.", + action: "append", + nargs: "?", + dest: "preventVarifiedNames", + }); + parser.add_argument("-d", "--delay", { help: 'Adds an delay, which will be waited, after the system connected. Parmeter is provided in [s]. Defaults to "2"', default: 2, @@ -247,6 +257,7 @@ export async function readInArgs( args.logToFile = Array.isArray(args.logToFile); args.forceUsingSelectors = Array.isArray(args.forceUsingSelectors); args.useBaseServices = !Array.isArray(args.useBaseServices); + args.preventVarifiedNames = !Array.isArray(args.preventVarifiedNames); return Object.assign(args, forcedArgs); } @@ -417,6 +428,7 @@ export async function runNopeBackend( logger: getNopeLogger("dispatcher", args.dispatcherLogLevel), defaultSelector: args.defaultSelector, forceUsingSelectors: args.forceUsingSelectors, + forceUsingValidVarNames: !args.preventVarifiedNames, id: args.id, isMaster: args.channel !== "io-server" ? null : false, }, diff --git a/lib/dispatcher/InstanceManager/InstanceManager.ts b/lib/dispatcher/InstanceManager/InstanceManager.ts index aa7cabb..4db8d8a 100644 --- a/lib/dispatcher/InstanceManager/InstanceManager.ts +++ b/lib/dispatcher/InstanceManager/InstanceManager.ts @@ -8,6 +8,7 @@ import { waitFor } from "../../helpers/async"; import { generateId } from "../../helpers/idMethods"; import { MapBasedMergeData } from "../../helpers/mergedData"; import { SPLITCHAR } from "../../helpers/objectMethods"; +import { varifyPath } from "../../helpers/path"; import { defineNopeLogger } from "../../logger/getLogger"; import { DEBUG } from "../../logger/index.browser"; import { NopeGenericWrapper } from "../../module/index"; @@ -728,6 +729,11 @@ export class NopeInstanceManager implements INopeInstanceManager { ); } + // Use the varified Name (removes the invalid chars.) + _defDescription.identifier = this.options.forceUsingValidVarNames + ? varifyPath(_defDescription.identifier) + : _defDescription.identifier; + if (this._logger?.enabledFor(DEBUG)) { this._logger.debug( 'Requesting an Instance of type: "' + diff --git a/lib/dispatcher/RpcManager/NopeRpcManager.ts b/lib/dispatcher/RpcManager/NopeRpcManager.ts index 5551a6b..f3216ae 100644 --- a/lib/dispatcher/RpcManager/NopeRpcManager.ts +++ b/lib/dispatcher/RpcManager/NopeRpcManager.ts @@ -12,6 +12,7 @@ import { isAsyncFunction } from "../../helpers/async"; import { generateId } from "../../helpers/idMethods"; import { MapBasedMergeData } from "../../helpers/mergedData"; import { SPLITCHAR } from "../../helpers/objectMethods"; +import { varifyPath } from "../../helpers/path"; import { defineNopeLogger } from "../../logger/getLogger"; import { DEBUG } from "../../logger/index.browser"; import { NopePromise } from "../../promise/nopePromise"; @@ -751,7 +752,11 @@ export class NopeRpcManager */ protected _unregisterService(func: ((...args) => void) | string): boolean { const _id = - typeof func === "string" ? func : ((func as any).id as string) || "0"; + typeof func === "string" + ? this.options.forceUsingValidVarNames + ? varifyPath(func) + : func + : ((func as any).id as string) || "0"; this._communicatorCallbacks.delete(_id); @@ -797,6 +802,7 @@ export class NopeRpcManager // Define / Use the ID of the Function. let _id = options.id || generateId(); _id = options.addNopeServiceIdPrefix ? this.adaptServiceId(_id) : _id; + _id = this.options.forceUsingValidVarNames ? varifyPath(_id) : _id; // Make shure we assign our id options.id = _id; diff --git a/lib/helpers/idMethods.ts b/lib/helpers/idMethods.ts index 1574970..c3145ec 100644 --- a/lib/helpers/idMethods.ts +++ b/lib/helpers/idMethods.ts @@ -5,26 +5,18 @@ */ import { v4 } from "uuid"; -import { replaceAll } from "./stringMethods"; +import { varifyString } from "./stringMethods"; /** * Generates an ID. * * @author M.Karkowski * @export - * @param {string} [prestring] additional PreString for the Id. - * @return {*} {string} the Id. - */ -/** - * - * - * @author M.Karkowski - * @export * @param {{ * prestring?: string, * useAsVar?: boolean * }} [options={}] - * @return {*} {string} + * @return {string} */ export function generateId( options: { @@ -35,15 +27,13 @@ export function generateId( ): string { let id = v4(); - if (options.useAsVar) { - id = replaceAll(id, "-", ""); - options.prestring = - typeof options.prestring === "string" ? options.prestring : "_"; - } - if (typeof options.prestring === "string") { id = options.prestring + id; } + if (options.useAsVar) { + id = varifyString(id); + } + return id; } diff --git a/lib/helpers/limit.ts b/lib/helpers/limit.ts index 5534109..641944f 100644 --- a/lib/helpers/limit.ts +++ b/lib/helpers/limit.ts @@ -7,6 +7,7 @@ import { EventEmitter } from "events"; import { ILogger } from "js-logger"; import { DEBUG } from "../index.browser"; import { generateId } from "./idMethods"; +import { difference } from "./setMethods"; /** * The options for call @@ -44,6 +45,11 @@ export type TLimitedOptions = { * An overview with active Tasks. This is relevant for multiple Funtions. */ activeTasks: Set; + + /** + * An overview with active Tasks. This is relevant for multiple Funtions. + */ + awaitingTasks: Set; }; /** @@ -60,6 +66,7 @@ export function getLimitedOptions( maxParallel: 0, logger: false, activeTasks: new Set(), + awaitingTasks: new Set(), }; return Object.assign(defaultSettings, options); @@ -81,11 +88,16 @@ export function limitedCalls( queue: {}, emitter: new EventEmitter(), getLock: (newTaskId: string) => { - return settingsToUse.activeTasks.size <= settingsToUse.maxParallel; + const tasks = difference( + settingsToUse.activeTasks, + settingsToUse.awaitingTasks + ); + return tasks.size <= settingsToUse.maxParallel; }, maxParallel: 0, logger: false, activeTasks: new Set(), + awaitingTasks: new Set(), }; const settingsToUse: TLimitedOptions = Object.assign(defaultSettins, options); @@ -96,6 +108,17 @@ export function limitedCalls( // Generate the Call-ID const taskId = generateId(); + const pauseTask = () => { + settingsToUse.awaitingTasks.add(taskId); + }; + + const continueTask = () => { + settingsToUse.awaitingTasks.delete(taskId); + }; + + // Add the functions. + args.push(pauseTask, continueTask); + // Push the Content to the emitter settingsToUse.queue[settingsToUse.functionId].push([taskId, args]); diff --git a/lib/helpers/mapMethods.ts b/lib/helpers/mapMethods.ts index 90d7be3..ef1ed11 100644 --- a/lib/helpers/mapMethods.ts +++ b/lib/helpers/mapMethods.ts @@ -152,6 +152,8 @@ export function tranformMap< query: pathExtractedKey, }); onlyValidProps = onlyValidProps && pathExtractedKey.length > 0; + } else { + onlyValidProps = false; } if (typeof pathExtractedValue === "string") { @@ -160,6 +162,8 @@ export function tranformMap< query: pathExtractedValue, }); onlyValidProps = onlyValidProps && pathExtractedValue.length > 0; + } else { + onlyValidProps = false; } // Iterate over the Entries of the Map. diff --git a/lib/helpers/objectMethods.ts b/lib/helpers/objectMethods.ts index f84090f..0f235bc 100644 --- a/lib/helpers/objectMethods.ts +++ b/lib/helpers/objectMethods.ts @@ -5,7 +5,6 @@ */ export const SPLITCHAR = "/"; -import { deepEqual as _deepEqual } from "assert"; import { getLeastCommonPathSegment } from "./path"; import { comparePatternAndPath, @@ -690,18 +689,80 @@ export function deepClone(obj: T): T { } /** - * Compares deep a and b (using assert) - * @param a Object A - * @param b Object B - * @returns The Result + * Helper to get the Type of an Object. + * @param obj The Object + * @returns */ -export function deepEqual(a: T, b: T): boolean { - try { - _deepEqual(a, b); +export function getType(obj): string { + return Object.prototype.toString.call(obj).slice(8, -1); +} + +/** + * Compares deep a and b. + * @param source The source item + * @param target The target item + * @param {number} maxDepth Max Depth, after which the test is skipped and the `onMaxDepth` value is returned + * @param {boolean} [onMaxDepth=false] Value to return if the maxDepth is reached. + * @returns + */ +export function deepEqual(a: any, b: any): boolean { + if (a === b) return true; + + if (a && b && typeof a == "object" && typeof b == "object") { + if (a.constructor !== b.constructor) return false; + + let length, i, keys; + if (Array.isArray(a)) { + length = a.length; + if (length != b.length) return false; + for (i = length; i-- !== 0; ) if (!deepEqual(a[i], b[i])) return false; + return true; + } + + if (a instanceof Map && b instanceof Map) { + if (a.size !== b.size) return false; + for (i of a.entries()) if (!b.has(i[0])) return false; + for (i of a.entries()) if (!deepEqual(i[1], b.get(i[0]))) return false; + return true; + } + + if (a instanceof Set && b instanceof Set) { + if (a.size !== b.size) return false; + for (i of a.entries()) if (!b.has(i[0])) return false; + return true; + } + + if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { + length = a.byteLength; + if (length != b.byteLength) return false; + for (i = length; i-- !== 0; ) if (a[i] !== b[i]) return false; + return true; + } + + if (a.constructor === RegExp) + return a.source === b.source && a.flags === b.flags; + if (a.valueOf !== Object.prototype.valueOf) + return a.valueOf() === b.valueOf(); + if (a.toString !== Object.prototype.toString) + return a.toString() === b.toString(); + + keys = Object.keys(a); + length = keys.length; + if (length !== Object.keys(b).length) return false; + + for (i = length; i-- !== 0; ) + if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; + + for (i = length; i-- !== 0; ) { + let key = keys[i]; + if (!deepEqual(a[key], b[key])) return false; + } + return true; - } catch (e) { - return false; } + + // true if both NaN, false otherwise + return a !== a && b !== b; } /** diff --git a/lib/helpers/path.ts b/lib/helpers/path.ts index 8ea036f..65093ee 100644 --- a/lib/helpers/path.ts +++ b/lib/helpers/path.ts @@ -9,12 +9,32 @@ import { MULTI_LEVEL_WILDCARD, SINGLE_LEVEL_WILDCARD, } from "./pathMatchingMethods"; -import { replaceAll } from "./stringMethods"; +import { replaceAll, varifyString } from "./stringMethods"; +/** + * Converts the path to a correct path. + * @param {string} path + * @returns {string} The Path + */ export function convertPath(path: string): string { return replaceAll(path, [".", "[", ["]", ""]], SPLITCHAR); } +/** + * Helper to convert the segments of a path to a valid var name. + * + * @param {string} path The Path to adapt + * @returns {string} The Adapted path. + */ +export function varifyPath(path: string): string { + // We devided the Path in its segments and make shure, that these segments are + // called correctly. + return path + .split(SPLITCHAR) + .map((item) => varifyString(item)) + .join(SPLITCHAR); +} + /** * Returns the least common segmet of all pathes, included in the pathes array. * diff --git a/lib/helpers/setMethods.ts b/lib/helpers/setMethods.ts index f1befd5..8481fc8 100644 --- a/lib/helpers/setMethods.ts +++ b/lib/helpers/setMethods.ts @@ -49,3 +49,29 @@ export function determineDifference( removed, }; } + +/** + * Unions the two sets + * @param {Set} set01 + * @param {Set} set01 + * @returns + */ +export function union(set01: Set, set02: Set): Set { + return new Set([...set01, ...set02]); +} + +/** + * Substracts set02 from set01 + * @param {Set} set01 Base Set + * @param {Set} set02 The Set to substract + * @returns + */ +export function difference(set01: Set, set02: Set): Set { + const diff = new Set([...set01]); + + for (const s of set02) { + diff.delete(s); + } + + return diff; +} diff --git a/lib/helpers/stringMethods.ts b/lib/helpers/stringMethods.ts index 4f4d963..9514ead 100644 --- a/lib/helpers/stringMethods.ts +++ b/lib/helpers/stringMethods.ts @@ -4,6 +4,29 @@ * @desc [description] */ +/** + * Helper Function to varify the given string. + * Removes every char which doesn't match a variable name. + * (a-z, A-Z, 0-9). + * + * If `str` starts with an invalid char, (like a number), + * an underscore is added. + * @param {string} str the Stirng + * @returns {string} the adapted name + */ +export function varifyString(str: string): string { + // Regex to test if the first char is correct. + const firstCharCorrect = new RegExp("^[_a-zA-Z]", "i"); + + const ret = str.replaceAll(new RegExp("[^a-zA-Z0-9]", "g"), "_"); + + if (firstCharCorrect.test(ret)) { + return ret; + } + + return "_" + ret; +} + /** * Replaces all Chars in a String * @param str base string diff --git a/lib/profiling/index.nodejs.ts b/lib/profiling/index.nodejs.ts index 6a7506d..d21684e 100644 --- a/lib/profiling/index.nodejs.ts +++ b/lib/profiling/index.nodejs.ts @@ -78,13 +78,13 @@ export function recordCPUProfile(pathToFile = DEFAULT_FILE) { // Click Open dedicated DevTools for Node // Select the profiler tab // Load your file + await createFile(pathToFile, result); + logger.info( "Please open google chrome and open chrome://inspect and load the file", pathToFile ); - await createFile(pathToFile, result); - // Clear the Profile. profile.delete(); }; diff --git a/lib/types/nope/nopeDispatcher.interface.ts b/lib/types/nope/nopeDispatcher.interface.ts index 2d52dab..4b60bae 100644 --- a/lib/types/nope/nopeDispatcher.interface.ts +++ b/lib/types/nope/nopeDispatcher.interface.ts @@ -60,6 +60,15 @@ export type INopeDispatcherOptions = { * @type {boolean} */ forceUsingSelectors?: boolean; + + /** + * Flag to ensure, that every path used is corrcet and could be + * used as variable in another system. + * + * @author M.Karkowski + * @type {boolean} + */ + forceUsingValidVarNames?: boolean; } & INopeINopeConnectivityOptions; export interface IHostOverview extends IHost { diff --git a/lib/types/nope/nopeInstanceManager.interface.ts b/lib/types/nope/nopeInstanceManager.interface.ts index cc91b7e..4d9ade5 100644 --- a/lib/types/nope/nopeInstanceManager.interface.ts +++ b/lib/types/nope/nopeInstanceManager.interface.ts @@ -148,7 +148,7 @@ export interface INopeInstanceManager { * @return {Promise} * @memberof INopeInstanceManager */ - createInstance( + createInstance( description: Partial, options?: { selector?: ValidSelectorFunction; @@ -160,7 +160,9 @@ export interface INopeInstanceManager { * Creates Wrappers for the Type of the given element. * @param type */ - getInstancesOfType(type: string): Promise; + getInstancesOfType( + type: string + ): Promise<(I & IGenericNopeModule)[]>; /** * Defaultly a generic wrapper will be returned, when an instance is created. you diff --git a/package.json b/package.json index f793c85..af8b4db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nope", - "version": "1.3.4", + "version": "1.3.7", "description": "NoPE Runtime for Nodejs. For Browser-Support please use nope-browser", "files": [ "dist-nodejs/**/*",