- Added:
  - `lib/cli/nope` adding scan for ui service
  - `lib/decorators/container`: Main Container, holding all `methods` and `classes`. Use `getCentralDecoratedContainer()` to get this decorator.
  - `types/nope/nopePackage.interface` added `IClassDescription` which contains the class description used in the Package Description.
  - `logger/nopeLogger`: added methods: `enabledFor`, `enableFor`, `shouldLog`
  - `package.json`: installed types of `ace` text editor.
  - `ui/helpers.browser`: Created `convertInstanceRenderPage` and `IUiDefinition`
  - `ui/helpers.nodejs`: Added a Helper to write the Ui-File (`writeUiFile`) and parse its arguments (`readInwriteUiFileArgs`)
  - `ui/index.*`: Crated the corresponding exports.
- Modified:
  - `lib/decorators/*` Adding the main `container` where every function, service method etc is added. All decorators now safe the decorated elements in the container.
  - `helpers/json`: Adding `BEGIN_STR` and `END_STR` for parsing functions as constants.
  - `logger/eventLogging`: simplify `useEventLogger`
  - `logger/index.browser`: Adating exports.
  - `loader/loadPackages`: Modifing `IPackageConfig` now extends Partial the `IPackageDescription`
  - `types/ui/editor/IEditPage`: adapting Type of `getData` to `T`->`any`. Adapting the return of `getPorts` (The Ports will be generated in the ui then)
  - `types/ui/editor/helpers.interface`: Adapting the `w2ui` and added `w2uiHelpers` and added `ace`. Rearanging `IRenderData` element. to compact the data.
  - `types/ui/editor/render.callbacks`: Rearange the Generic Type of `TRenderInstancePage` and Renaming `TCreatorPage` to `TInstanceManagerPage`. Adapting the `option` of `TInstanceManagerPage` regarding the `createInstance` and `instances`
  - `types/ui/editor/index`: Adapting the Exports.
  - `lib/index.browser`: Exporting `ui` elements
  - `lib/index.nodejs`: Exporting `ui` elements
  - `lib/types/index`: Exporting `ui` elements
- Fixes:
  - `types/nope/nopeInstanceManager.interface`: Fixing Type of createInstance. Now the Type `I` extends `INopeModule` instead of being set to `IGenericNopeModule`
This commit is contained in:
Martin Karkowski 2022-07-02 11:30:10 +02:00
parent ed608e613e
commit 20112adbe5
29 changed files with 555 additions and 173 deletions

View File

@ -105,4 +105,32 @@ Inital commit, which is working with the browser
- Added `internalInstances: INopeObservable<string[]>` to `InstanceManager`.:
- Added dev-depencies for libraries.
- Modified:
- Modified `addAllBaseServices` now includes some options, which can be used to determine the specific service to load.
- Modified `addAllBaseServices` now includes some options, which can be used to determine the specific service to load.
# 1.1.2
- Added:
- `lib/cli/nope` adding scan for ui service
- `lib/decorators/container`: Main Container, holding all `methods` and `classes`. Use `getCentralDecoratedContainer()` to get this decorator.
- `types/nope/nopePackage.interface` added `IClassDescription` which contains the class description used in the Package Description.
- `logger/nopeLogger`: added methods: `enabledFor`, `enableFor`, `shouldLog`
- `package.json`: installed types of `ace` text editor.
- `ui/helpers.browser`: Created `convertInstanceRenderPage` and `IUiDefinition`
- `ui/helpers.nodejs`: Added a Helper to write the Ui-File (`writeUiFile`) and parse its arguments (`readInwriteUiFileArgs`)
- `ui/index.*`: Crated the corresponding exports.
- Modified:
- `lib/decorators/*` Adding the main `container` where every function, service method etc is added. All decorators now safe the decorated elements in the container.
- `helpers/json`: Adding `BEGIN_STR` and `END_STR` for parsing functions as constants.
- `logger/eventLogging`: simplify `useEventLogger`
- `logger/index.browser`: Adating exports.
- `loader/loadPackages`: Modifing `IPackageConfig` now extends Partial the `IPackageDescription`
- `types/ui/editor/IEditPage`: adapting Type of `getData` to `T`->`any`. Adapting the return of `getPorts` (The Ports will be generated in the ui then)
- `types/ui/editor/helpers.interface`: Adapting the `w2ui` and added `w2uiHelpers` and added `ace`. Rearanging `IRenderData` element. to compact the data.
- `types/ui/editor/render.callbacks`: Rearange the Generic Type of `TRenderInstancePage` and Renaming `TCreatorPage` to `TInstanceManagerPage`. Adapting the `option` of `TInstanceManagerPage` regarding the `createInstance` and `instances`
- `types/ui/editor/index`: Adapting the Exports.
- `lib/index.browser`: Exporting `ui` elements
- `lib/index.nodejs`: Exporting `ui` elements
- `lib/types/index`: Exporting `ui` elements
- Fixes:
- `types/nope/nopeInstanceManager.interface`: Fixing Type of createInstance. Now the Type `I` extends `INopeModule` instead of being set to `IGenericNopeModule`

View File

@ -1 +1 @@
1.1.1
1.2.0

View File

@ -1,16 +1,14 @@
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2021-01-18 17:29:44
* @modify date 2021-02-09 10:25:07
* @desc [description]
*/
import { readInwriteUiFileArgs, writeUiFile } from "../ui/helpers.nodejs";
import { createService } from "./createService";
import { generateDefaultConfig } from "./generateDefaultConfig";
import { generateDefaultPackageConfig } from "./generateDefaultPackageConfig";
import { generateFolderStructure } from "./generateFolderStructure";
import { NOPELOGO } from "./renderNope";
import { repl } from "./repl";
import run from "./runNopeBackend";
@ -21,7 +19,15 @@ import run from "./runNopeBackend";
*/
export async function main() {
const args: {
mode: "run" | "init" | "none" | "scan" | "help" | "service" | "repl";
mode:
| "run"
| "init"
| "none"
| "conf"
| "help"
| "service"
| "repl"
| "scan-ui";
params: string[];
} = {
mode: (process.argv[2] as any) || "none",
@ -44,9 +50,10 @@ Please select the option you want. Therefore add one of the following options:
\x1b[4mhelp\x1b[0m Show this help.
\x1b[4mrun\x1b[0m Start a NoPE-Backend.
\x1b[4minit\x1b[0m Initialize a new project. This project is empty.
\x1b[4mscan\x1b[0m Trys to update the configuration file.
\x1b[4mconf\x1b[0m Trys to update the configuration file.
\x1b[4mscan-ui\x1b[0m Scans and extracts the provided uis.
\x1b[4mservice\x1b[0m Generate Helper Files to provide services
\x1b[4mrepl\x1b[0m Opens an interactive console.
\x1b[4mrepl\x1b[0m Opens an interactive console.
Have fun using NoPE :)
@ -76,7 +83,7 @@ Have fun using NoPE :)
await generateDefaultConfig([additionalArg]);
await generateDefaultPackageConfig([additionalArg]);
break;
case "scan":
case "conf":
additionalArg.help = "Command to generate the Config of the backend";
await generateDefaultPackageConfig([additionalArg]);
break;
@ -87,6 +94,11 @@ Have fun using NoPE :)
case "repl":
await repl([additionalArg]);
break;
case "scan-ui":
additionalArg.help =
"Command to readin the UI-Files and store them in a config";
await writeUiFile(readInwriteUiFileArgs([additionalArg]));
break;
}
}

View File

@ -0,0 +1,38 @@
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @desc [description]
*/
import { getSingleton } from "../helpers/singletonMethod";
import { IFunctionOptions, INopeModule } from "../types";
export type IexportFunctionAsNopeServiceParameters = IFunctionOptions;
/**
* Return the central loger. This logger is a singleton (see {@link getSingleton})
*
* @author M.Karkowski
* @export
* @return {NopeLogger} A Returns the Logger {@link NopeLogger}
*/
export function getCentralDecoratedContainer(): {
methods: Map<
string,
{
uri: string;
callback: (...args) => Promise<any>;
options: IexportFunctionAsNopeServiceParameters;
}
>;
classes: Map<string, INopeModule>;
} {
const container = getSingleton("nope.decorated.elements", () => {
return {
methods: new Map(),
classes: new Map(),
};
});
return container.instance;
}

View File

@ -1,26 +1,15 @@
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-06 08:52:55
* @modify date 2020-12-02 08:56:37
* @desc [description]
*/
import { getSingleton } from "../helpers/singletonMethod";
import { IFunctionOptions } from "../types/nope/nopeModule.interface";
import {
getCentralDecoratedContainer,
IexportFunctionAsNopeServiceParameters,
} from "./container";
export type IexportFunctionAsNopeServiceParameters = IFunctionOptions;
const container = getSingleton("nopeBackendDispatcher.container", () => {
return new Map<
string,
{
uri: string;
callback: (...args) => Promise<any>;
options: IexportFunctionAsNopeServiceParameters;
}
>();
});
const CONTAINER = getCentralDecoratedContainer();
/**
* Defintion of a Functon.
@ -39,8 +28,8 @@ export function exportFunctionAsNopeService<T>(
options: IexportFunctionAsNopeServiceParameters
) {
// Only add the element if it doesnt exists.
if (!container.instance.has(options.id)) {
container.instance.set(options.id, {
if (!CONTAINER.methods.has(options.id)) {
CONTAINER.methods.set(options.id, {
callback: async (...args) => await (func as any)(...args),
options,
uri: options.id || (func as any).name,

View File

@ -4,7 +4,8 @@
*/
export {
exportFunctionAsNopeService,
getCentralDecoratedContainer,
IexportFunctionAsNopeServiceParameters,
} from "./functionDecorators";
} from "./container";
export { exportFunctionAsNopeService } from "./functionDecorators";
export { nopeEmitter, nopeMethod, nopeProperty } from "./moduleDecorators";

View File

@ -9,6 +9,9 @@ import {
IFunctionOptions,
INopeModule,
} from "../types/nope/nopeModule.interface";
import { getCentralDecoratedContainer } from "./container";
const CONTAINER = getCentralDecoratedContainer();
/**
* Decorator, used to export the Method as Service to Nope..
@ -26,6 +29,9 @@ export function nopeMethod(options: IFunctionOptions) {
methodName: string,
descriptor: PropertyDescriptor
) {
// Add the Target to the class.
CONTAINER.classes.set(target.constructor.name, target);
target._markedElements = target._markedElements || [];
target._markedElements.push({
accessor: methodName,
@ -46,6 +52,9 @@ export function nopeProperty(options: IEventOptions) {
propertyKey: string,
descriptor: PropertyDescriptor
) {
// Add the Target to the class.
CONTAINER.classes.set(target.constructor.name, target);
target._markedElements = target._markedElements || [];
target._markedElements.push({
accessor: propertyKey,
@ -66,6 +75,9 @@ export function nopeEmitter(options: IEventOptions) {
propertyKey: string,
descriptor: PropertyDescriptor
) {
// Add the Target to the class.
CONTAINER.classes.set(target.constructor.name, target);
target._markedElements = target._markedElements || [];
target._markedElements.push({
accessor: propertyKey,

View File

@ -4,6 +4,9 @@
* @desc [description]
*/
const BEGIN_STR = "____Function_beginn/(";
const END_STR = ")/__Function_end";
/**
* Function to stringify an Object. This Function will stringify Functions as well.
* @param obj The Object.
@ -31,7 +34,7 @@ export function stringifyWithFunctions(obj, ...args) {
str = adaptedFunc;
}
return "/Function(" + str + ")/";
return BEGIN_STR + str + END_STR;
}
return value;
},
@ -52,10 +55,13 @@ export function parseWithFunctions(
return JSON.parse(json, (key, value) => {
if (
typeof value === "string" &&
value.startsWith("/Function(") &&
value.endsWith(")/")
value.startsWith(BEGIN_STR) &&
value.endsWith(END_STR)
) {
const _value = value.substring(10, value.length - 2);
const _value = value.substring(
BEGIN_STR.length,
value.length - END_STR.length
);
try {
return eval("(" + _value + ")").bind(scope);
} catch (e) {

View File

@ -16,6 +16,7 @@ import * as observables from "./observables/index";
import * as promise from "./promise/index";
import * as pubSub from "./pubSub";
import * as types from "./types/index";
import * as ui from "./ui/index.browser";
export * from "./communication/index.browser";
export * from "./decorators";
@ -30,6 +31,7 @@ export * from "./promise/index";
export * from "./pubSub";
export * from "./types/index";
export * from "./types/nope";
export * from "./ui/index.browser";
export {
communcation,
decorators,
@ -43,4 +45,5 @@ export {
observables,
promise,
pubSub,
ui,
};

View File

@ -33,3 +33,5 @@ export * as pubSub from "./pubSub";
export * as types from "./types";
export * from "./types/index";
export * from "./types/nope";
export * from "./ui/index.nodejs";
export * as ui from "./ui/index.nodejs";

View File

@ -11,23 +11,10 @@ import { sleep } from "../helpers/async";
import { createFile, listFiles } from "../helpers/fileMethods";
import { parseWithFunctions, stringifyWithFunctions } from "../index.browser";
import { getNopeLogger } from "../logger/getLogger";
import { IInstanceCreationMsg } from "../types/nope/nopeCommunication.interface";
import { IPackageDescription } from "../types/nope/nopePackage.interface";
import { INopePackageLoader } from "../types/nope/nopePackageLoader.interface";
export interface IPackageConfig {
nameOfPackage: string;
defaultInstances: {
options: Partial<IInstanceCreationMsg>;
selector: string | symbol;
}[];
autostart: {
[index: string]: {
service: string;
delay?: number;
params: any[];
}[];
};
export interface IPackageConfig extends Partial<IPackageDescription<any>> {
// File Path of the element.
path: string;
}
@ -227,6 +214,14 @@ export async function loadPackages(
await loader.generateInstances();
}
/**
* Helper to read function provided in the defined configuration.
*
* @author M.Karkowski
* @export
* @param {string} [filename=join(resolve(process.cwd()), "config", "assembly.json")]
* @return {*}
*/
export async function loadFunctions(
filename: string = join(resolve(process.cwd()), "config", "assembly.json")
) {

View File

@ -121,10 +121,7 @@ export function getLogerAsEventEmitter(): LoggerAsEventEmitter {
export function useEventLogger(): LoggerAsEventEmitter {
const logger = getCentralNopeLogger();
const res = getSingleton("nope.logger.event", () => {
return new LoggerAsEventEmitter();
});
const emitter = res.instance;
const emitter = getLogerAsEventEmitter();
logger.setHandler((msg, context) => {
const msgs: string[] = [];

View File

@ -49,6 +49,7 @@ export const LEVELS = {
export { ILogger } from "js-logger";
export {
getLogerAsEventEmitter,
LoggerAsEventEmitter,
TCallback,
TCallbackWithLevel,
useEventLogger,
@ -59,5 +60,11 @@ export {
getNopeLogger,
ValidLoggerDefinition,
} from "./getLogger";
export { LoggerLevel, LoggerLevels } from "./nopeLogger";
export {
enabledFor,
enableFor,
LoggerLevel,
LoggerLevels,
shouldLog,
} from "./nopeLogger";
export { setGlobalLoggerLevel } from "./setGlobalLoggerLevel";

View File

@ -172,6 +172,47 @@ function _getLogger(level: LoggerLevel, label = ""): ILogger {
return logger;
}
/**
* Tests if the Logger is enabled for the level, or extracts the level.
*
* @param {ILogger} logger The logger
* @param {LoggerLevel} [lvl] if provided tests if the lvl matches the logger. otherwise returns the current level
* @return {(boolean | LoggerLevel)}
*/
export function enabledFor(
logger: ILogger,
lvl?: LoggerLevel
): boolean | LoggerLevel {
if (lvl) {
return logger.enabledFor(mapping[lvl]);
}
return logger.getLevel().name as LoggerLevel;
}
/**
* Enables the Logger for the desired Level.
*
* @param {ILogger} logger The logger
* @param {LoggerLevel} lvl The level to use
* @return {void}
*/
export function enableFor(logger: ILogger, lvl: LoggerLevel): void {
return logger.setLevel(mapping[lvl]);
}
/**
* Helper to test if the message would be logged.
* @param loggerLevel The Level of the logger
* @param messageLevel The Level of the Message
* @returns
*/
export function shouldLog(
loggerLevel: LoggerLevel,
messageLevel: LoggerLevel
): boolean {
return order[messageLevel] >= order[loggerLevel];
}
/**
* The Nope-Logger. It consits o
*/

View File

@ -6,6 +6,7 @@
import * as nope from "./nope/index";
import * as ui from "./ui/index";
export * from "./nope/index";
export * from "./IJSONSchema";
export * from "./nope/index";
export * from "./ui/index";
export { nope, ui };

View File

@ -137,15 +137,15 @@ export interface INopeInstanceManager {
*
* @author M.Karkowski
* @template I
* @param {Partial<IInstanceCreationMsg>} description
* @param {Partial<IInstanceCreationMsg>} description Description of the instance to be created
* @param {{
* selector?: ValidSelectorFunction;
* assignmentValid?: TValidAsssignmentChecker
* }} options
* }} options Options used during creating the instance.
* @return {Promise<I>}
* @memberof INopeInstanceManager
*/
createInstance<I = IGenericNopeModule>(
createInstance<I extends INopeModule>(
description: Partial<IInstanceCreationMsg>,
options?: {
selector?: ValidSelectorFunction;

View File

@ -1,5 +1,5 @@
import { interfaces } from "inversify";
import { TCreatorPage, TRenderInstancePage } from "../ui";
import { TInstanceManagerPage, TRenderInstancePage } from "../ui";
import { IInstanceCreationMsg } from "./nopeCommunication.interface";
import { IValidPromise } from "./nopeDispatcher.interface";
import { IFunctionOptions, INopeModule } from "./nopeModule.interface";
@ -57,6 +57,36 @@ export interface IClassDescriptor<T extends INopeModule = INopeModule> {
name: string;
}
export interface IClassDescription {
/**
* Descriptor of the class
*/
description: IClassDescriptor;
/**
* Settings used for the creator.
*/
settings: {
/**
* You can prevent creating instances.
* Defaults to `true`
*/
allowInstanceGeneration?: boolean;
/**
* Max amount, of instances, that are allowed to
* be created by the local dispatcher. (This is only
* used for hosting.)
*/
maxAmountOfInstance?: number;
};
/**
* UI Related Methods.
*/
ui?: {
creator?: TInstanceManagerPage;
config?: TRenderInstancePage;
};
}
/**
* Element used to define a nopePackages.
* A Package can be loaded automatically.
@ -74,17 +104,7 @@ export interface IPackageDescription<
* @type {Array<IClassDescriptor>}
* @memberof IPackageDescription
*/
providedClasses: Array<{
description: IClassDescriptor;
settings: {
allowInstanceGeneration?: boolean;
maxAmountOfInstance?: number;
};
ui?: {
creator: TCreatorPage;
config: TRenderInstancePage;
};
}>;
providedClasses: Array<IClassDescription>;
/**
* Element containing functions of the module.

View File

@ -8,13 +8,13 @@ import { IPort } from "./INodes";
export interface IEditPage<T = any> extends TRenderFunctionResult {
/**
* Function, which must return the current data.
* Function, which must return the current service-data.
*
* @author M.Karkowski
* @return {boolean}
* @memberof IEditPage
*/
getData(): T;
getData(): any;
/**
* Function which must return true, if the Entered-
@ -36,7 +36,15 @@ export interface IEditPage<T = any> extends TRenderFunctionResult {
* @param options adapted Edge Options.
*/
getPorts(): {
inputs: IPort[];
outputs: IPort[];
inputs: {
id: string;
label: String;
type: IPort["type"];
}[];
outputs: {
id: string;
label: String;
type: IPort["type"];
}[];
};
}

View File

@ -2,4 +2,3 @@
* @author Martin Karkowski
* @email m.karkowski@zema.de
*/

View File

@ -3,16 +3,15 @@
* @email m.karkowski@zema.de
*/
import * as go from "gojs";
import { ILogger } from "js-logger";
import * as plotly from "plotly.js";
import { IJsonSchema } from "../IJSONSchema";
import { INopeDispatcher, INopeObservable } from "../nope/index";
import * as nope from "../../index.browser";
import * as plotly from "plotly.js";
import * as go from "gojs";
import {
IMinProvidedDataSet,
IPanel,
IPossiblePanels,
IMinProvidedDataSet,
IRadioMenuItemDescription,
} from "./layout.interface";
@ -48,9 +47,9 @@ export type TLibraries = {
/**
* The Nope Library. It contains only the Browser build.
*
* @type {typeof nope}
* @type {*}
*/
nope: typeof nope;
nope: any;
/**
* Built on top of d3.js and stack.gl, Plotly.js is a high-level, declarative charting library. plotly.js ships with over 40 chart types, including 3D charts,
@ -66,6 +65,13 @@ export type TLibraries = {
*
* Contains the original w2ui Library. https://w2ui.com/web/
*/
w2uiHelpers: {
w2popup: (...args) => any;
w2alert: (...args) => any;
w2confirm: (...args) => any;
w2prompt: (...args) => any;
w2utils: any;
};
w2ui: any;
/**
@ -93,6 +99,15 @@ export type TLibraries = {
* For more details checkout: https://gojs.net/latest/
*/
gojs: typeof go;
/**
* Ace is an embeddable code editor written in JavaScript. It matches the features and performance of native editors such as Sublime, Vim and TextMate.
* It can be easily embedded in any web page and JavaScript application. Ace is maintained as the primary editor for Cloud9 IDE and is the successor of
* the Mozilla Skywriter (Bespin) project.
*
* For more details checkout: https://ace.c9.io/#nav=about
*/
ace: typeof ace;
};
export type TcreateLayoutOptions = {
@ -154,6 +169,29 @@ export interface IRenderData {
* @memberof IDataInterface
*/
getData<T>(key: string, defaultValue: T): Promise<T>;
/**
* Helper to test if the data exists.
*
* @author M.Karkowski
* @param {string} key The key, under which the data is expected.
* @return {Promise<boolean>}
*/
hasData(key: string): Promise<boolean>;
/**
* Register Schema for data. If you try to store or pull data, the schema will be used to verify the data
* @param key The path of the data which should be observed
* @param schema The schema to store
* @returns {boolean} Flag to show the shema is stored or not.
*/
registerSchema(key: string, schema: IJsonSchema): boolean;
/**
* Helper, to store the configuration.
* @returns success of the operation
*/
store(): Promise<boolean>;
};
connection: {
/**
@ -162,7 +200,8 @@ export interface IRenderData {
* @type {INopeObservable<boolean>}
* @memberof INoPEConnectService
*/
sessionsConnected: INopeObservable<boolean>;
readonly sessionsConnected: INopeObservable<boolean>;
/**
* Flag, to define, whether a external connection is required to
* set the {@link INoPEConnectService.sessionsConnected} to true.
@ -170,7 +209,39 @@ export interface IRenderData {
* @type {boolean}
* @memberof INoPEConnectService
*/
noExternalConnectionRequired: boolean;
readonly noExternalConnectionRequired: boolean;
/**
* Hostname used in the browser.
*
* @author M.Karkowski
* @type {string}
*/
readonly hostname: string;
/**
* Returns the available layers.
*
* @author M.Karkowski
* @readonly
* @type {(Array<TSession & { connected: boolean }>)}
* @memberof NoPEService
*/
readonly layers: Array<TSession & { connected: boolean }>;
/**
* Adds an communication Layer.
*
* @param {TSession} _session The Parameters for the Session.
* @memberof NoPEService
*/
addCommunicationLayer(_session: TSession): void;
/**
* Disconnects the Layer.
* @param session The Session Parameters to use.
*/
removeCommunicationLayer(session: TSession): void;
/**
* Helper Function to establish a connection to a backend. If called, to url is changed to the `pages/connect` and after a sucessfull connection, the original url is loaded **again**.
*
@ -219,31 +290,6 @@ export interface IRenderData {
}
) => void;
};
info: {
hostname: string;
/**
* Returns the available layers.
*
* @author M.Karkowski
* @readonly
* @type {(Array<TSession & { connected: boolean }>)}
* @memberof NoPEService
*/
readonly layers: Array<TSession & { connected: boolean }>;
/**
* Adds an communication Layer.
*
* @param {TSession} _session The Parameters for the Session.
* @memberof NoPEService
*/
addCommunicationLayer(_session: TSession): void;
/**
* Disconnects the Layer.
* @param session The Session Parameters to use.
*/
removeCommunicationLayer(session: TSession): void;
};
url: {
/**
* Helper to get an Object from a schema. The Schema must be from type Object and is only allowed to have
@ -359,35 +405,3 @@ export interface IRenderData {
dispatcher: INopeDispatcher;
libraries: TLibraries;
}
/** Helper used, to render the instance details */
// export type TRenderInstancePage<T extends nope.IGenericNopeModule> = (
// div: HTMLDivElement,
// options: TRenderData & {
// input: T;
// }
// ) => TRenderFunctionResult;
// /** Helper to configurate a service */
// export type TRenderConfigureServicePage<T> = (
// div: HTMLDivElement,
// options: TRenderData & {
// input: T;
// }
// ) => IEditPage;
// /** UI to define an instance. */
// export type TCreatorPage<T extends nope.IGenericNopeModule> = (
// div: HTMLDivElement,
// options: TRenderData & {
// createInstance: T;
// }
// ) => IEditPage;
// export type TRenderEditPage<T> = (
// div: HTMLDivElement,
// options: TRenderData & {
// input: T;
// }
// ) => IEditPage;

View File

@ -7,7 +7,9 @@
import * as editor from "./editor/index";
import * as layout from "./layout.interface";
export { TCreatorPage, TRenderInstancePage } from "./render.callbacks";
export * from "./editor/index";
export { TRenderConfigureServicePage } from "./editor/index";
export * from "./helpers.interface";
export * from "./layout.interface";
export { TInstanceManagerPage, TRenderInstancePage } from "./render.callbacks";
export { editor, layout };

View File

@ -3,25 +3,30 @@
* @email m.karkowski@zema.de
*/
import { IGenericNopeModule } from "../nope";
import {
IGenericNopeModule,
IInstanceCreationMsg,
INopeModule,
INopeModuleDescription,
TValidAsssignmentChecker,
ValidSelectorFunction,
} from "../nope";
import { IRenderData } from "./helpers.interface";
import { TRenderFunctionResult } from "./layout.interface";
/** Helper used, to render the instance details */
export type TRenderInstancePage<
T extends IGenericNopeModule = IGenericNopeModule
> = (
export type TRenderInstancePage<T extends INopeModule = INopeModule> = (
/** The DIV Element */
div: HTMLDivElement,
/** The Provided Options used by the function to create the ui */
options: IRenderData & {
/** The Instance to Render. */
input: T;
input: T & IGenericNopeModule;
}
) => TRenderFunctionResult;
/** UI to define an instance. */
export type TCreatorPage<T extends IGenericNopeModule = IGenericNopeModule> = (
export type TInstanceManagerPage<T extends INopeModule = INopeModule> = (
/** The DIV Element */
div: HTMLDivElement,
/** The Provided Options used by the function to create the ui */
@ -29,6 +34,13 @@ export type TCreatorPage<T extends IGenericNopeModule = IGenericNopeModule> = (
/** Name of the Constructor */
ctorName: string;
/** The callback to create the instance. */
createInstance: (...args) => Promise<T>;
createInstance: (
description: Partial<IInstanceCreationMsg>,
options?: {
selector?: ValidSelectorFunction;
assignmentValid?: TValidAsssignmentChecker;
}
) => Promise<T & IGenericNopeModule>;
instances: Array<INopeModuleDescription>;
}
) => void;

43
lib/ui/helpers.browser.ts Normal file
View File

@ -0,0 +1,43 @@
import { stringifyWithFunctions } from "../helpers/jsonMethods";
import {
IClassDescription,
IFunctionOptions,
IGenericNopeModule,
INopeModule,
} from "../types";
import { TRenderInstancePage } from "../types/ui";
/**
* Converts the convertInstanceRenderPage to a string, which could be
* store or something similar.
*
* @export
* @template I The Instance Type
* @param {(TRenderInstancePage<I & IGenericNopeModule>)} callback The callback to stringify.
* @return {string} The parsed String.
*/
export function convertInstanceRenderPage<I extends INopeModule>(
callback: TRenderInstancePage<I & IGenericNopeModule>
): string {
return stringifyWithFunctions(callback);
}
export interface IUiDefinition {
functions: {
[index: string]: {
ui: IFunctionOptions["ui"];
id: string;
};
};
classes: {
[index: string]: {
ui?: IClassDescription["ui"];
package: string;
class: string;
path: string;
methods: {
[index: string]: IFunctionOptions["ui"];
};
};
};
}

158
lib/ui/helpers.nodejs.ts Normal file
View File

@ -0,0 +1,158 @@
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
*/
import { ArgumentParser } from "argparse";
import { join, resolve } from "path";
import "reflect-metadata";
import { createFile } from "../helpers/fileMethods";
import {
getCentralDecoratedContainer,
IFunctionOptions,
stringifyWithFunctions,
} from "../index.browser";
import { listFunctions, listPackages } from "../index.nodejs";
import { IUiDefinition } from "./helpers.browser";
/**
* Helper Function to write a default configuration.
*
* @export
* @param {string} [dir='./modules']
* @param {string} [filename=join(resolve(process.cwd()), 'config', 'assembly.json')]
*/
export async function writeUiFile(
options: {
dir: string;
filename: string;
} = {
dir: "./modules",
filename: join(resolve(process.cwd()), "config", "ui.json"),
}
) {
const uiFile: IUiDefinition = {
functions: {},
classes: {},
};
// This call makes shure, that every function is loaded
const functions = await listFunctions(options.dir);
const packages = await listPackages(options.dir);
const CONTAINER = getCentralDecoratedContainer();
// Determine all Packages
for (const item of packages) {
// Iterate over the classes.
for (const cls of item.package.providedClasses) {
const itemToAdd: IUiDefinition["classes"][0] = {
// The Class Name
class: cls.description.name,
// The Package Name
package: item.package.nameOfPackage,
// The Path of he File.
path: item.path,
// The defined UI defintions.
ui: cls.ui,
// Define the Methods elements
methods: {},
};
// The Service
const services =
CONTAINER.classes.get(cls.description.name)?._markedElements || [];
for (const srv of services) {
if (srv.type === "method" && (srv.options as IFunctionOptions).ui) {
itemToAdd.methods[srv.accessor] = (
srv.options as IFunctionOptions
).ui;
}
}
if (
itemToAdd.ui ||
Object.getOwnPropertyNames(itemToAdd.methods).length > 0
) {
// If an ui definition exists, we want
// to export it and store it in our file.
uiFile.classes[itemToAdd.class] = itemToAdd;
}
}
// Iterate over the functions and provide their uis.
item.package.providedFunctions.map((funcs) => {
if (funcs.options.ui) {
// Store the UI definition in the config file.
uiFile.functions[funcs.options.id] = {
id: funcs.options.id,
ui: funcs.options.ui,
};
}
});
}
for (const [id, data] of CONTAINER.methods.entries()) {
if (data.options.ui) {
uiFile.functions[id] = {
id,
ui: data.options.ui,
};
}
}
await createFile(options.filename, stringifyWithFunctions(uiFile, 4));
}
/**
* Helper to extract the Arguments for the `writeUiFile` function @see writeUiFile
*
* @author M.Karkowski
* @export
* @param additionalArguments Arguments added by the nope.cli
* @return {*} The Arguments
*/
export function readInwriteUiFileArgs(
additionalArguments: {
help: string;
type: "string" | "number";
name: string | string;
defaultValue?: any;
}[] = []
) {
const parser = new ArgumentParser({
// version: "1.0.0",
add_help: true,
description: "Command Line interface, determines the available Packages.",
});
for (const arg of additionalArguments) {
parser.add_argument(arg.name, {
help: arg.help,
default: arg.defaultValue,
type: arg.type,
});
}
parser.add_argument("-f", "--file", {
help: "Filename for the configuration.",
default: "./config/ui.json",
type: "str",
dest: "filename",
});
parser.add_argument("-d", "--dir", {
help: "Directory to search for the ui definitions",
default: "./modules",
type: "str",
dest: "dir",
});
const args: {
dir: string;
filename: string;
} = parser.parse_args();
return args;
}

View File

@ -1,23 +0,0 @@
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
*/
import { stringifyWithFunctions } from "../helpers/index.browser";
import { IGenericNopeModule, INopeModule } from "../module";
import { TRenderInstancePage } from "../types/ui";
/**
* Converts the convertInstanceRenderPage to a string, which could be
* store or something similar.
*
* @export
* @template I The Instance Type
* @param {(TRenderInstancePage<I & IGenericNopeModule>)} callback The callback to stringify.
* @return {string} The parsed String.
*/
export function convertInstanceRenderPage<I extends INopeModule>(
callback: TRenderInstancePage<I & IGenericNopeModule>
): string {
return stringifyWithFunctions(callback);
}

1
lib/ui/index.browser.ts Normal file
View File

@ -0,0 +1 @@
export * from "./helpers.browser";

2
lib/ui/index.nodejs.ts Normal file
View File

@ -0,0 +1,2 @@
export * from "./helpers.nodejs";
export * from "./index.browser";

17
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "nope",
"version": "1.1.00",
"version": "1.1.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "nope",
"version": "1.1.00",
"version": "1.1.1",
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1",
@ -40,6 +40,7 @@
"nope-js": "bin/nope"
},
"devDependencies": {
"@types/ace": "^0.0.48",
"@types/async": "^3.2.12",
"@types/chai": "^4.3.0",
"@types/lodash": "^4.14.178",
@ -413,6 +414,12 @@
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA=="
},
"node_modules/@types/ace": {
"version": "0.0.48",
"resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.48.tgz",
"integrity": "sha512-esV6hOWiDOZ6d7w5S11iLu6LQsPGe/9RPzhri7gNNLdrK1LFpO9/m7IZhQL6dat0JHICJ7l51zvHAiCgnPLLHA==",
"dev": true
},
"node_modules/@types/async": {
"version": "3.2.12",
"resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.12.tgz",
@ -18556,6 +18563,12 @@
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA=="
},
"@types/ace": {
"version": "0.0.48",
"resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.48.tgz",
"integrity": "sha512-esV6hOWiDOZ6d7w5S11iLu6LQsPGe/9RPzhri7gNNLdrK1LFpO9/m7IZhQL6dat0JHICJ7l51zvHAiCgnPLLHA==",
"dev": true
},
"@types/async": {
"version": "3.2.12",
"resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.12.tgz",

View File

@ -1,6 +1,6 @@
{
"name": "nope",
"version": "1.1.1",
"version": "1.2.0",
"description": "NoPE Runtime for Nodejs. For Browser-Support please use nope-browser",
"files": [
"dist-nodejs/**/*",
@ -67,6 +67,7 @@
"websocket-stream": "^5.5.2"
},
"devDependencies": {
"@types/ace": "^0.0.48",
"@types/async": "^3.2.12",
"@types/chai": "^4.3.0",
"@types/lodash": "^4.14.178",