Skip to content

Commit

Permalink
chore(types): several typing improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
danielduarte committed Jul 17, 2023
1 parent cc01c61 commit 297b266
Show file tree
Hide file tree
Showing 19 changed files with 70 additions and 79 deletions.
7 changes: 4 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ module.exports = {
'prettier',
],
rules: {
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/interface-name-prefix': 0,
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_'}],
eqeqeq: 1,
quotes: ['error', 'single', { avoidEscape: true }],
},
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ npm i flowed
<script src="https://cdn.jsdelivr.net/npm/flowed@latest/dist/lib/flowed.js" charset="utf-8"></script>
```

Or change `latest` in the URL for any available version.
Or replace `latest` in the URL for your desired version.

**From package**

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@
"all": true,
"exclude": [
"test",
"coverage",
"ops",
"dist",
"*.js",
".eslintrc.js",
"webpack.config.js",
"web/flowed.js"
],
"check-coverage": true,
Expand Down
8 changes: 4 additions & 4 deletions src/engine/flow-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { readFile } from 'fs';
import * as http from 'http';
import * as https from 'https';
import { IncomingMessage } from 'http';
import { TaskResolverMap, ValueMap, FlowedPlugin, FlowedLogger, FlowedLogEntry } from '../types';
import { TaskResolverMap, ValueMap, FlowedPlugin, FlowedLogger, FlowedLogEntry, OptPromise } from '../types';
import { Flow } from './flow';
import { FlowSpec } from './specs';

Expand All @@ -22,7 +22,7 @@ export class FlowManager {
resolvers: TaskResolverMap = {},
context: ValueMap = {},
options: ValueMap = {},
): Promise<ValueMap> {
): OptPromise<ValueMap> {
const flow = new Flow(flowSpec);
return flow.start(params, expectedResults, resolvers, context, options);
}
Expand Down Expand Up @@ -91,10 +91,10 @@ export class FlowManager {
}

return new Promise<ValueMap>((resolveFlow, reject) => {
(client || https)
client! // eslint-disable-line @typescript-eslint/no-non-null-assertion
.get(flowSpecUrl, (res: IncomingMessage) => {
const { statusCode } = res;
const contentType = res.headers['content-type'] || 'application/json';
const contentType = res.headers['content-type'] ?? 'application/json';

let error;
if (statusCode !== 200) {
Expand Down
3 changes: 1 addition & 2 deletions src/engine/flow-state/flow-pausing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ export class FlowPausing extends FlowState {
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
protected postProcessFinished(error: Error | boolean, stopFlowExecutionOnError: boolean): void {
protected postProcessFinished(error: Error | boolean, _stopFlowExecutionOnError: boolean): void {
this.runStatus.state.paused(error);
}
}
8 changes: 1 addition & 7 deletions src/engine/flow-state/flow-ready.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@ export class FlowReady extends FlowState {
return FlowStateEnum.Ready;
}

public start(
params: ValueMap,
expectedResults: string[],
resolvers: TaskResolverMap,
context: ValueMap,
options: ValueMap = {},
): Promise<ValueMap> {
public start(params: ValueMap, expectedResults: string[], resolvers: TaskResolverMap, context: ValueMap, options: ValueMap = {}) {
this.setRunOptions(options);
this.log({ n: this.runStatus.id, m: 'Flow started with params: %O', mp: params, e: 'FS' });

Expand Down
29 changes: 17 additions & 12 deletions src/engine/flow-state/flow-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@ import {
ThrowErrorResolver,
WaitResolver,
} from '../../resolver-library';
import { AnyValue, FlowedLogEntry, FlowStateEnum, FlowTransitionEnum, TaskResolverExecutor, TaskResolverMap, ValueMap } from '../../types';
import {
AnyValue,
FlowedLogEntry,
FlowStateEnum,
FlowTransitionEnum,
OptPromise,
TaskResolverExecutor,
TaskResolverMap,
ValueMap,
} from '../../types';
import { FlowRunStatus, SerializedFlowRunStatus } from '../flow-run-status';
import { Task } from '../task';
import { TaskProcess } from '../task-process';
Expand Down Expand Up @@ -50,22 +59,20 @@ export abstract class FlowState implements IFlow {
expectedResults: string[],
resolvers: TaskResolverMap,
context: ValueMap,
options: ValueMap = {}, // eslint-disable-line @typescript-eslint/no-unused-vars
): Promise<ValueMap> {
_options: ValueMap = {},
): OptPromise<ValueMap> {
throw this.createTransitionError(FlowTransitionEnum.Start);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
public finished(error: Error | boolean = false): void {
public finished(_error: Error | boolean = false): void {
throw this.createTransitionError(FlowTransitionEnum.Finished);
}

public pause(): Promise<ValueMap> {
throw this.createTransitionError(FlowTransitionEnum.Pause);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
public paused(error: Error | boolean = false): void {
public paused(_error: Error | boolean = false): void {
throw this.createTransitionError(FlowTransitionEnum.Paused);
}

Expand All @@ -77,8 +84,7 @@ export abstract class FlowState implements IFlow {
throw this.createTransitionError(FlowTransitionEnum.Stop);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
public stopped(error: Error | boolean = false): void {
public stopped(_error: Error | boolean = false): void {
throw this.createTransitionError(FlowTransitionEnum.Stopped);
}

Expand Down Expand Up @@ -341,8 +347,7 @@ export abstract class FlowState implements IFlow {
this.runStatus.state.postProcessFinished(error, stopFlowExecutionOnError);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
protected postProcessFinished(error: Error | boolean, stopFlowExecutionOnError: boolean): void {}
protected postProcessFinished(_error: Error | boolean, _stopFlowExecutionOnError: boolean): void {}

protected createTransitionError(transition: string): Error {
return new Error(`Cannot execute transition ${transition} in current state ${this.getStateCode()}.`);
Expand All @@ -353,7 +358,7 @@ export abstract class FlowState implements IFlow {
}

public debug(formatter: string, ...args: AnyValue[]): void {
const scope = this && this.runStatus && typeof this.runStatus.runOptions.debugKey === 'string' ? this.runStatus.runOptions.debugKey : 'init';
const scope = this?.runStatus && typeof this.runStatus.runOptions.debugKey === 'string' ? this.runStatus.runOptions.debugKey : 'init';
rawDebug(scope)(formatter, ...args);
}

Expand Down
3 changes: 1 addition & 2 deletions src/engine/flow-state/flow-stopping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ export class FlowStopping extends FlowState {
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
protected postProcessFinished(error: Error | boolean, stopFlowExecutionOnError: boolean): void {
protected postProcessFinished(error: Error | boolean, _stopFlowExecutionOnError: boolean): void {
this.runStatus.state.stopped(error);
}
}
10 changes: 5 additions & 5 deletions src/engine/flow-state/iflow.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { AnyValue, FlowStateEnum, TaskResolverMap, ValueMap } from '../../types';
import { AnyValue, FlowStateEnum, OptPromise, TaskResolverMap, ValueMap } from '../../types';

export interface IFlow {
start(params: ValueMap, expectedResults: string[], resolvers: TaskResolverMap, context: ValueMap): Promise<ValueMap>;
start(params: ValueMap, expectedResults: string[], resolvers: TaskResolverMap, context: ValueMap): OptPromise<ValueMap>;

pause(): Promise<ValueMap>;
pause(): OptPromise<ValueMap>;

resume(): Promise<ValueMap>;
resume(): OptPromise<ValueMap>;

stop(): Promise<ValueMap>;
stop(): OptPromise<ValueMap>;

reset(): void;

Expand Down
12 changes: 6 additions & 6 deletions src/engine/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ export class Flow implements IFlow {
resolvers: TaskResolverMap = {},
context: ValueMap = {},
options: ValueMap = {},
): Promise<ValueMap> {
) {
return this.runStatus.state.start(params, expectedResults, resolvers, context, options);
}

public pause(): Promise<ValueMap> {
public pause() {
return this.runStatus.state.pause();
}

public resume(): Promise<ValueMap> {
public resume() {
return this.runStatus.state.resume();
}

public stop(): Promise<ValueMap> {
public stop() {
return this.runStatus.state.stop();
}

public reset(): void {
public reset() {
this.runStatus.state.reset();
}

Expand All @@ -48,7 +48,7 @@ export class Flow implements IFlow {
}

public debug(formatter: string, ...args: AnyValue[]): void {
this && this.runStatus ? this.runStatus.state.debug(formatter, ...args) : rawDebug('init')(formatter, ...args);
this?.runStatus ? this.runStatus.state.debug(formatter, ...args) : rawDebug('init')(formatter, ...args);
}

public log({ n, m, mp, l, e }: { n?: number; m: string; mp?: ValueMap; l?: string; e?: string }): void {
Expand Down
4 changes: 2 additions & 2 deletions src/engine/task-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export class TaskProcess {
let resolverThis: TaskResolverClass | undefined = undefined;
const isClassResolver = this.taskResolverExecutor.prototype && this.taskResolverExecutor.prototype.exec;
if (isClassResolver) {
// @todo try to remove type assertions in this code section
// @todo try to remove type casts in this code section
const resolverInstance = new (this.taskResolverExecutor as TaskResolverClass)();
resolverFn = resolverInstance.exec as TaskResolverFn;
resolverFn = resolverInstance.exec;
resolverThis = resolverInstance as unknown as TaskResolverClass;
}

Expand Down
13 changes: 4 additions & 9 deletions src/engine/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,26 +60,23 @@ export class Task {
}
}

// @todo convert to protected
public mapParamsForResolver(solvedReqs: ValueMap, automap: boolean, flowId: number, log: LoggerFn): ValueMap {
const params: ValueMap = {};

let resolverParams = (this.spec.resolver ?? {}).params ?? {};
let resolverParams = this.spec.resolver?.params ?? {};

if (automap) {
const requires = this.spec.requires ?? [];
// When `Object.fromEntries()` is available in ES, use it instead of the following solution
// @todo Add test with requires = []
const autoMappedParams = requires.map(req => ({ [req]: req })).reduce((accum, peer) => Object.assign(accum, peer), {}); // @todo improve this expression
const autoMappedParams = requires.map(req => ({ [req]: req })).reduce((accum, peer) => Object.assign(accum, peer), {});
log({ n: flowId, m: ` ⓘ Auto-mapped resolver params in task '${this.code}': %O`, mp: autoMappedParams, l: 'd' });
resolverParams = Object.assign(autoMappedParams, resolverParams);
}

let paramValue;
for (const [resolverParamName, paramSolvingInfo] of Object.entries(resolverParams)) {
// @todo Add test to check the case when a loop round does not set anything and make sure next value is undefined by default
// Added to make sure default value is undefined
paramValue = undefined;
// @todo Add test to check the case when a loop round does not set anything and make sure next value (`paramValue`) is undefined by default

// If it is string, it is a task param name
if (typeof paramSolvingInfo === 'string') {
Expand Down Expand Up @@ -109,7 +106,6 @@ export class Task {
return params;
}

// @todo convert to protected
public mapResultsFromResolver(solvedResults: ValueMap, automap: boolean, flowId: number, log: LoggerFn): ValueMap {
if (typeof solvedResults !== 'object') {
throw new Error(
Expand All @@ -125,9 +121,8 @@ export class Task {

if (automap) {
const provides = this.spec.provides ?? [];
// When `Object.fromEntries()` is available in ES, use it instead of the following solution
// @todo Add test with provides = []
const autoMappedResults = provides.map(prov => ({ [prov]: prov })).reduce((accum, peer) => Object.assign(accum, peer), {}); // @todo improve this expression
const autoMappedResults = provides.reduce((acc: ValueMap, prov) => Object.assign(acc, { [prov]: prov }), {});
log({ n: flowId, m: ` ⓘ Auto-mapped resolver results in task '${this.code}': %O`, mp: autoMappedResults, l: 'd' });

resolverResults = Object.assign(autoMappedResults, resolverResults);
Expand Down
1 change: 0 additions & 1 deletion src/engine/value-queue-manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @todo Check if this could be the same as ValueMap
import { AnyValue, ValueMap } from '../types';

export type ValueQueue = AnyValue[];
Expand Down
14 changes: 7 additions & 7 deletions src/resolver-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,32 @@ import { LoggerFn, ValueMap } from './types';

// Do nothing and finish
export class NoopResolver {
public async exec(): Promise<ValueMap> {
public exec(): ValueMap {
return {};
}
}

export class EchoResolver {
public async exec(params: ValueMap): Promise<ValueMap> {
public exec(params: ValueMap): ValueMap {
return { out: params.in };
}
}

export class ThrowErrorResolver {
public async exec(params: ValueMap): Promise<ValueMap> {
public exec(params: ValueMap): ValueMap {
throw new Error(typeof params.message !== 'undefined' ? params.message : 'ThrowErrorResolver resolver has thrown an error');
}
}

export class ConditionalResolver {
public async exec(params: ValueMap): Promise<ValueMap> {
public exec(params: ValueMap): ValueMap {
return params.condition ? { onTrue: params.trueResult } : { onFalse: params.falseResult };
}
}

// Wait for 'ms' milliseconds and finish
export class WaitResolver {
public async exec(params: ValueMap): Promise<ValueMap> {
public exec(params: ValueMap): ValueMap {
return new Promise<ValueMap>(resolve => {
setTimeout(() => {
resolve({ result: params.result });
Expand Down Expand Up @@ -219,13 +219,13 @@ export class LoopResolver {
}

export class StopResolver {
public async exec(params: ValueMap, context: ValueMap): Promise<ValueMap> {
public exec(params: ValueMap, context: ValueMap): ValueMap {
return { promise: context.$flowed.flow.stop() };
}
}

export class PauseResolver {
public async exec(params: ValueMap, context: ValueMap): Promise<ValueMap> {
public exec(params: ValueMap, context: ValueMap): ValueMap {
return { promise: context.$flowed.flow.pause() };
}
}
18 changes: 8 additions & 10 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ export enum FlowTransitionEnum {
Stopped = 'Stopped',
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type AnyValue = any;
export type AnyValue = any; // eslint-disable-line @typescript-eslint/no-explicit-any

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type TransformTemplate = any;
export type TransformTemplate = AnyValue;

export type OptPromise<T> = T | Promise<T>;

export interface ValueMap {
[key: string]: AnyValue;
Expand All @@ -37,18 +37,16 @@ export interface ValueMap {
export type GenericValueMap = ValueMap;

export interface ITaskResolver {
exec(params: ValueMap, context: ValueMap, task: Task, debug: Debugger, log: LoggerFn): Promise<ValueMap>;
exec(params: ValueMap, context?: ValueMap, task?: Task, debug?: Debugger, log?: LoggerFn): OptPromise<ValueMap>;
}

export class TaskResolver implements ITaskResolver {
// @todo this method should return type ValueMap | Promise<ValueMap>
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public exec(params: ValueMap, context: ValueMap, task: Task, debug: Debugger, log: LoggerFn): Promise<ValueMap> {
return Promise.resolve({});
public exec(_params: ValueMap, _context?: ValueMap, _task?: Task, _debug?: Debugger, _log?: LoggerFn): OptPromise<ValueMap> {
return {};
}
}

export type TaskResolverFn = (params: ValueMap, context?: ValueMap, task?: Task, debug?: Debugger, log?: LoggerFn) => ValueMap | Promise<ValueMap>;
export type TaskResolverFn = (params: ValueMap, context?: ValueMap, task?: Task, debug?: Debugger, log?: LoggerFn) => OptPromise<ValueMap>;

export type TaskResolverClass = typeof TaskResolver;

Expand Down
Loading

0 comments on commit 297b266

Please sign in to comment.