- 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`
This commit is contained in:
Martin Karkowski 2022-08-23 09:50:45 +02:00
parent a5760014a3
commit d240840d4e
16 changed files with 241 additions and 36 deletions

View File

@ -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`

View File

@ -1 +1 @@
1.3.4
1.3.7

View File

@ -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<INopeINopeConnectivityTimeOptions>;
// 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,
},

View File

@ -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: "' +

View File

@ -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<T extends IFunctionOptions = IFunctionOptions>
*/
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<T extends IFunctionOptions = IFunctionOptions>
// 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;

View File

@ -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;
}

View File

@ -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<string>;
/**
* An overview with active Tasks. This is relevant for multiple Funtions.
*/
awaitingTasks: Set<string>;
};
/**
@ -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<T>(
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<T>(
// 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]);

View File

@ -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.

View File

@ -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<T>(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<T>(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;
} catch (e) {
return false;
}
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;
}
// true if both NaN, false otherwise
return a !== a && b !== b;
}
/**

View File

@ -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.
*

View File

@ -49,3 +49,29 @@ export function determineDifference<T>(
removed,
};
}
/**
* Unions the two sets
* @param {Set<T>} set01
* @param {Set<T>} set01
* @returns
*/
export function union<T>(set01: Set<T>, set02: Set<T>): Set<T> {
return new Set([...set01, ...set02]);
}
/**
* Substracts set02 from set01
* @param {Set<T>} set01 Base Set
* @param {Set<T>} set02 The Set to substract
* @returns
*/
export function difference<T>(set01: Set<T>, set02: Set<T>): Set<T> {
const diff = new Set([...set01]);
for (const s of set02) {
diff.delete(s);
}
return diff;
}

View File

@ -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

View File

@ -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();
};

View File

@ -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 {

View File

@ -148,7 +148,7 @@ export interface INopeInstanceManager {
* @return {Promise<I>}
* @memberof INopeInstanceManager
*/
createInstance<I extends INopeModule>(
createInstance<I = IGenericNopeModule>(
description: Partial<IInstanceCreationMsg>,
options?: {
selector?: ValidSelectorFunction;
@ -160,7 +160,9 @@ export interface INopeInstanceManager {
* Creates Wrappers for the Type of the given element.
* @param type
*/
getInstancesOfType<I extends INopeModule>(type: string): Promise<I[]>;
getInstancesOfType<I = IGenericNopeModule>(
type: string
): Promise<(I & IGenericNopeModule)[]>;
/**
* Defaultly a generic wrapper will be returned, when an instance is created. you

View File

@ -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/**/*",