From 6c58ed7669837fdd50b893a035916c6170355324 Mon Sep 17 00:00:00 2001 From: TeamworkGuy2 Date: Fri, 12 May 2017 17:04:40 +0000 Subject: [PATCH 1/3] [orchestrator] Improved types based on orchestrator 0.3.8 source code --- types/orchestrator/index.d.ts | 173 ++++++++++++++--------- types/orchestrator/orchestrator-tests.ts | 54 ++++--- 2 files changed, 133 insertions(+), 94 deletions(-) diff --git a/types/orchestrator/index.d.ts b/types/orchestrator/index.d.ts index c1eae16416..7f8a6ed80e 100644 --- a/types/orchestrator/index.d.ts +++ b/types/orchestrator/index.d.ts @@ -1,107 +1,135 @@ -// Type definitions for Orchestrator +// Type definitions for Orchestrator 0.3 // Project: https://github.com/orchestrator/orchestrator -// Definitions by: Qubo +// Definitions by: Qubo , TeamworkGuy2 // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +/// + +import * as events from "events"; +import * as stream from "stream"; import * as Q from "q"; -declare type Strings = string|string[]; +type _Sequencify = (tasks: Array<{ dep: string[]; }>, names: string[]) => { sequence: string[]; missingTasks: string[]; recursiveDependencies: string[]; }; -declare class Orchestrator { +type _runTask = (task: Orchestrator.TaskMethod, done: (err: any, meta: Orchestrator.Meta) => void) => void; + +type Strings = string|string[]; + +/** A module for sequencing and executing tasks and dependencies in maximum concurrency + */ +declare class Orchestrator extends events.EventEmitter { + doneCallback?: (error?: any) => any; + isRunning: boolean; + seq: any[]; + tasks: { [name: string]: Orchestrator.Task }; + + reset(): Orchestrator; + + /** Define a task + * @param name The name of the task. + * @param deps An array of task names to be executed and completed before your task will run. + * @param fn The function that performs the task's operations. For asynchronous tasks, you need to provide a hint when the task is complete: + * - Take in a callback + * - Return a stream or a promise + */ add: Orchestrator.AddMethod; - /** - * Have you defined a task with this name? + + task(name: string): Orchestrator.Task; + task(name: string, fn: Orchestrator.TaskMethod): void; + task(name: string, dep: string[], fn: Orchestrator.TaskMethod): void; + task(name: string, dep?: string[] | Orchestrator.TaskMethod, fn?: Orchestrator.TaskMethod): void; + + /** Have you defined a task with this name? * @param name The task name to query */ hasTask(name: string): boolean; - start: Orchestrator.StartMethod; - stop(): void; - /** - * Listen to orchestrator internals + start: Orchestrator.StartMethod; + + stop(err?: any, successfulFinish?: boolean): void; + + sequence: _Sequencify; + + allDone(): boolean; + + /** Listen to orchestrator internals * @param event Event name to listen to: - *
    - *
  • start: from start() method, shows you the task sequence - *
  • stop: from stop() method, the queue finished successfully - *
  • err: from stop() method, the queue was aborted due to a task error - *
  • task_start: from _runTask() method, task was started - *
  • task_stop: from _runTask() method, task completed successfully - *
  • task_err: from _runTask() method, task errored - *
  • task_not_found: from start() method, you're trying to start a task that doesn't exist - *
  • task_recursion: from start() method, there are recursive dependencies in your task list - *
+ * - start: from start() method, shows you the task sequence + * - stop: from stop() method, the queue finished successfully + * - err: from stop() method, the queue was aborted due to a task error + * - task_start: from _runTask() method, task was started + * - task_stop: from _runTask() method, task completed successfully + * - task_err: from _runTask() method, task errored + * - task_not_found: from start() method, you're trying to start a task that doesn't exist + * - task_recursion: from start() method, there are recursive dependencies in your task list * @param cb Passes single argument: e: event details */ - on(event: string, cb: (e: Orchestrator.OnCallbackEvent) => any): Orchestrator; + on(event: Orchestrator.EventNames, cb: (e: Orchestrator.OnCallbackEvent) => any): this; - /** - * Listen to all orchestrator events from one callback + /** Listen to all orchestrator events from one callback * @param cb Passes single argument: e: event details */ onAll(cb: (e: Orchestrator.OnAllCallbackEvent) => any): void; + + // probably supposed to be private methods, but still available on Orchestrator prototype + _resetTask(task: Orchestrator.Task): void; + + _resetAllTasks(): void; + + _resetSpecificTasks(names: string[]): void; + + _runStep(): void; + + _readyToRunTask(task: Orchestrator.Task): boolean; + + _stopTask(task: Orchestrator.Task, meta: Orchestrator.Meta): void; + + _emitTaskDone(task: Orchestrator.Task, message: string, err?: any): void; + + _runTask(task: Orchestrator.Task): void; } declare namespace Orchestrator { - interface AddMethodCallback { - /** - * Accept a callback - * @param callback - */ - (callback?: Function): any; - /** - * Return a promise - */ - (): Q.Promise; - /** - * Return a stream: (task is marked complete when stream ends) - */ - (): any; //TODO: stream type should be here e.g. map-stream - } + type runTask = _runTask; - /** - * Define a task + type Sequencify = _Sequencify; + + /** A task, can either call a callback to indicate task completion or return a promise or a stream: (task is marked complete when promise.then() resolves/fails or stream ends) */ + type TaskMethod = (callback: (err?: any) => void) => Q.Promise | stream.Stream | any; + interface AddMethod { - /** - * Define a task + /** Define a task + * @param name The name of the task. + * @param fn The function that performs the task's operations. For asynchronous tasks, you need to provide a hint when the task is complete: + * - Take in a callback + * - Return a stream or a promise + */ + (name: string, fn?: TaskMethod): Orchestrator; + /** Define a task * @param name The name of the task. * @param deps An array of task names to be executed and completed before your task will run. * @param fn The function that performs the task's operations. For asynchronous tasks, you need to provide a hint when the task is complete: - *
    - *
  • Take in a callback
  • - *
  • Return a stream or a promise
  • - *
+ * - Take in a callback + * - Return a stream or a promise */ - (name: string, deps?: string[], fn?: AddMethodCallback|Function): Orchestrator; - /** - * Define a task - * @param name The name of the task. - * @param fn The function that performs the task's operations. For asynchronous tasks, you need to provide a hint when the task is complete: - *
    - *
  • Take in a callback
  • - *
  • Return a stream or a promise
  • - *
- */ - (name: string, fn?: AddMethodCallback|Function): Orchestrator; + (name: string, deps?: string[], fn?: TaskMethod): Orchestrator; } - /** - * Start running the tasks + /** Start running the tasks */ interface StartMethod { - /** - * Start running the tasks + /** Start running the tasks * @param tasks Tasks to be executed. You may pass any number of tasks as individual arguments. * @param cb Callback to call after run completed. */ (tasks: Strings, cb?: (error?: any) => any): Orchestrator; - /** - * Start running the tasks + /** Start running the tasks * @param tasks Tasks to be executed. You may pass any number of tasks as individual arguments. * @param cb Callback to call after run completed. */ (...tasks: Strings[]/*, cb?: (error: any) => any */): Orchestrator; - //TODO: TypeScript 1.5.3 cannot express varargs followed by callback as a last argument... + // TODO: TypeScript 2.1.5 cannot express varargs followed by callback as a last argument... (task1: Strings, task2: Strings, cb?: (error?: any) => any): Orchestrator; (task1: Strings, task2: Strings, task3: Strings, cb?: (error?: any) => any): Orchestrator; (task1: Strings, task2: Strings, task3: Strings, task4: Strings, cb?: (error?: any) => any): Orchestrator; @@ -120,6 +148,23 @@ declare namespace Orchestrator { src: string; } + interface Task { + fn: TaskMethod; + dep: string[]; + name: string; + done?: boolean; + duration?: number; + hrDuration?: [number, number]; + running?: boolean; + } + + interface Meta { + duration: number; + hrDuration: [number, number]; + runMethod: ("callback" | "catch" | "promise" | "stream" | "sync"); + } + + type EventNames = ("start" | "stop" | "err" | "task_start" | "task_stop" | "task_err" | "task_not_found" | "task_recursion"); } export = Orchestrator; diff --git a/types/orchestrator/orchestrator-tests.ts b/types/orchestrator/orchestrator-tests.ts index 4897a875e6..e25f12fb48 100644 --- a/types/orchestrator/orchestrator-tests.ts +++ b/types/orchestrator/orchestrator-tests.ts @@ -1,10 +1,11 @@ 'use strict'; +import stream = require("stream"); +import Q = require('q'); import Orchestrator = require('orchestrator'); var orchestrator = new Orchestrator(); - // API: // @@ -13,60 +14,50 @@ var orchestrator = new Orchestrator(); orchestrator.add('thing1', function() { // do stuff -}); -orchestrator.add('thing2', function() { +}).add('thing2', function() { // do stuff }); orchestrator.add('mytask', ['array', 'of', 'task', 'names'], function() { // Do stuff }); -orchestrator.add('thing2', function(callback: any){ +orchestrator.add('thing2', function(callback){ var err: any = null; // do stuff callback(err); }); - -import Q = require('q'); - orchestrator.add('thing3', function(){ - var deferred = Q.defer(); + var deferred = Q.defer(); // do async stuff - setTimeout(function () { + setTimeout(function() { deferred.resolve(); }, 1); return deferred.promise; }); - -//TODO: map-stream currently not on DefinitelyTyped -//var map = require('map-stream'); -// -//orchestrator.add('thing4', function(){ -// var stream = map(function (args, cb) { -// cb(null, args); -// }); -// // do stream stuff -// return stream; -//}); +orchestrator.add('thing4', function(){ + var stm = new stream.Stream(); + // do stream stuff + return stm; +}); // // orchestrator.hasTask(name); // -orchestrator.hasTask('thing1'); +var hasThing1: boolean = orchestrator.hasTask('thing1'); // // orchestrator.start(tasks...[, cb]); // -orchestrator.start('thing1', 'thing2', 'thing3', 'thing4', function (err: any) { +orchestrator.start('thing1', 'thing2', 'thing3', 'thing4', function(err: any) { // all done +}).start(['thing1', 'thing2'], ['thing3', 'thing4'], "thing5", function(err) { + var res: any = err; }); -orchestrator.start(['thing1','thing2'], ['thing3','thing4']); - // // orchestrator.stop() @@ -74,16 +65,22 @@ orchestrator.start(['thing1','thing2'], ['thing3','thing4']); orchestrator.stop(); +// +// orchestrator.reset() +// + +orchestrator.reset(); + // // orchestrator.on(event, cb); // -orchestrator.on('task_start', function (e) { +orchestrator.on('task_start', function(e) { var message: string = e.message; var task: string = e.task; var err: any = e.err; }); -orchestrator.on('task_stop', function (e) { +orchestrator.on('task_stop', function(e) { var message: string = e.message; var task: string = e.task; var duration: number = e.duration; @@ -93,12 +90,9 @@ orchestrator.on('task_stop', function (e) { // orchestrator.onAll(cb); // -orchestrator.onAll(function (e) { +orchestrator.onAll(function(e) { var message: string = e.message; var task: string = e.task; var err: any = e.err; var src: string = e.src; }); - - - From 758a15dca5ae95d5ec9e112db2022cca0487d337 Mon Sep 17 00:00:00 2001 From: TeamworkGuy2 Date: Fri, 12 May 2017 18:34:53 +0000 Subject: [PATCH 2/3] gulp & orchestrator type fixes (gulp extends orchestartor) --- types/gulp/gulp-tests.ts | 3 +++ types/gulp/index.d.ts | 15 ++++++++++++++- types/orchestrator/index.d.ts | 24 +++++++++++++++--------- types/orchestrator/orchestrator-tests.ts | 14 ++++++++++++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/types/gulp/gulp-tests.ts b/types/gulp/gulp-tests.ts index 9660b0658a..809ffed350 100644 --- a/types/gulp/gulp-tests.ts +++ b/types/gulp/gulp-tests.ts @@ -27,6 +27,9 @@ gulp.task('test', ['compile', 'compile2'], function() gulp.task('default', ['compile', 'test']); +gulp.task('another', ['with1', 'with2']) + .task('some', ['other1', 'other2'], function(cb) { cb(null); }) + .task('last', function() { }); var opts = {}; diff --git a/types/gulp/index.d.ts b/types/gulp/index.d.ts index fefd5b0fda..2a7579ec1f 100644 --- a/types/gulp/index.d.ts +++ b/types/gulp/index.d.ts @@ -14,6 +14,7 @@ declare type Strings = string|string[]; declare namespace gulp { interface Gulp extends Orchestrator { + task(name: string): never; /** * Define a task * @param name The name of the task. @@ -24,7 +25,19 @@ declare namespace gulp { *
  • Return a stream or a promise
  • * */ - task: Orchestrator.AddMethod; + task(name: string, fn?: Orchestrator.TaskFunc): Gulp; + /** + * Define a task + * @param name The name of the task. + * @param deps An array of task names to be executed and completed before your task will run. + * @param fn The function that performs the task's operations. For asynchronous tasks, you need to provide a hint when the task is complete: + *
      + *
    • Take in a callback
    • + *
    • Return a stream or a promise
    • + *
    + */ + task(name: string, deps?: string[], fn?: Orchestrator.TaskFunc): Gulp; + /** * Takes a number of task names or functions and returns a function of the composed tasks or functions * When the returned function is executed, the tasks or functions will be executed in series, diff --git a/types/orchestrator/index.d.ts b/types/orchestrator/index.d.ts index 7f8a6ed80e..52ceacf429 100644 --- a/types/orchestrator/index.d.ts +++ b/types/orchestrator/index.d.ts @@ -11,7 +11,7 @@ import * as Q from "q"; type _Sequencify = (tasks: Array<{ dep: string[]; }>, names: string[]) => { sequence: string[]; missingTasks: string[]; recursiveDependencies: string[]; }; -type _runTask = (task: Orchestrator.TaskMethod, done: (err: any, meta: Orchestrator.Meta) => void) => void; +type _runTask = (task: Orchestrator.TaskFunc, done: (err: any, meta: Orchestrator.Meta) => void) => void; type Strings = string|string[]; @@ -25,6 +25,13 @@ declare class Orchestrator extends events.EventEmitter { reset(): Orchestrator; + /** Define a task + * @param name The name of the task. + * @param fn The function that performs the task's operations. For asynchronous tasks, you need to provide a hint when the task is complete: + * - Take in a callback + * - Return a stream or a promise + */ + add(name: string, fn?: Orchestrator.TaskFunc): Orchestrator; /** Define a task * @param name The name of the task. * @param deps An array of task names to be executed and completed before your task will run. @@ -32,12 +39,11 @@ declare class Orchestrator extends events.EventEmitter { * - Take in a callback * - Return a stream or a promise */ - add: Orchestrator.AddMethod; + add(name: string, deps?: string[], fn?: Orchestrator.TaskFunc): Orchestrator; task(name: string): Orchestrator.Task; - task(name: string, fn: Orchestrator.TaskMethod): void; - task(name: string, dep: string[], fn: Orchestrator.TaskMethod): void; - task(name: string, dep?: string[] | Orchestrator.TaskMethod, fn?: Orchestrator.TaskMethod): void; + task(name: string, fn: Orchestrator.TaskFunc): void; + task(name: string, dep: string[], fn: Orchestrator.TaskFunc): void; /** Have you defined a task with this name? * @param name The task name to query @@ -96,7 +102,7 @@ declare namespace Orchestrator { /** A task, can either call a callback to indicate task completion or return a promise or a stream: (task is marked complete when promise.then() resolves/fails or stream ends) */ - type TaskMethod = (callback: (err?: any) => void) => Q.Promise | stream.Stream | any; + type TaskFunc = (callback: (err?: any) => void) => Q.Promise | stream.Stream | any; interface AddMethod { /** Define a task @@ -105,7 +111,7 @@ declare namespace Orchestrator { * - Take in a callback * - Return a stream or a promise */ - (name: string, fn?: TaskMethod): Orchestrator; + (name: string, fn?: TaskFunc): Orchestrator; /** Define a task * @param name The name of the task. * @param deps An array of task names to be executed and completed before your task will run. @@ -113,7 +119,7 @@ declare namespace Orchestrator { * - Take in a callback * - Return a stream or a promise */ - (name: string, deps?: string[], fn?: TaskMethod): Orchestrator; + (name: string, deps?: string[], fn?: TaskFunc): Orchestrator; } /** Start running the tasks @@ -149,7 +155,7 @@ declare namespace Orchestrator { } interface Task { - fn: TaskMethod; + fn: TaskFunc; dep: string[]; name: string; done?: boolean; diff --git a/types/orchestrator/orchestrator-tests.ts b/types/orchestrator/orchestrator-tests.ts index e25f12fb48..13e9bb19e0 100644 --- a/types/orchestrator/orchestrator-tests.ts +++ b/types/orchestrator/orchestrator-tests.ts @@ -43,6 +43,20 @@ orchestrator.add('thing4', function(){ return stm; }); +// +// orchestrator.task(name[, deps][, function]); +// + +orchestrator.task('task1'); + +orchestrator.task('task2', function(cb) { + cb(null); +}); + +orchestrator.task('task3', ['task1', 'task2'], function() { + // do stuff +}); + // // orchestrator.hasTask(name); // From 98f0e4b428b547ebd397efee8ec07c2f911c772b Mon Sep 17 00:00:00 2001 From: TeamworkGuy2 Date: Wed, 17 May 2017 21:56:13 +0000 Subject: [PATCH 3/3] Cleanup orchestrator types --- types/gulp/gulp-tests.ts | 13 ++++--------- types/orchestrator/index.d.ts | 20 +++++++++++--------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/types/gulp/gulp-tests.ts b/types/gulp/gulp-tests.ts index 809ffed350..09aad27a7a 100644 --- a/types/gulp/gulp-tests.ts +++ b/types/gulp/gulp-tests.ts @@ -1,26 +1,22 @@ import gulp = require("gulp"); -import browserSync = require("browser-sync"); var typescript: gulp.GulpPlugin = null; // this would be the TypeScript compiler var jasmine: gulp.GulpPlugin = null; // this would be the jasmine test runner -gulp.task('compile', function() -{ +gulp.task('compile', function() { gulp.src("**/*.ts") .pipe(typescript()) .pipe(gulp.dest('out')) }); -gulp.task('compile2', function(callback: (err?: any) => void) -{ +gulp.task('compile2', function(callback: (err?: any) => void) { gulp.src("**/*.ts") .pipe(typescript()) .pipe(gulp.dest('out')) .on('end', callback); }); -gulp.task('test', ['compile', 'compile2'], function() -{ +gulp.task('test', ['compile', 'compile2'], function() { gulp.src("out/test/**/*.js") .pipe(jasmine()); }); @@ -64,8 +60,7 @@ var watcher = gulp.watch('*.html', event => { }); gulp.task('serve', ['compile'], () => { - var browser = browserSync.create(); - gulp.watch(['*.html', '*.ts'], ['compile', browser.reload]); + gulp.watch(['*.html', '*.ts'], ['compile', () => { return "data"; }]); }); gulp.start('test', 'compile'); diff --git a/types/orchestrator/index.d.ts b/types/orchestrator/index.d.ts index 52ceacf429..fcb1a16120 100644 --- a/types/orchestrator/index.d.ts +++ b/types/orchestrator/index.d.ts @@ -9,12 +9,6 @@ import * as events from "events"; import * as stream from "stream"; import * as Q from "q"; -type _Sequencify = (tasks: Array<{ dep: string[]; }>, names: string[]) => { sequence: string[]; missingTasks: string[]; recursiveDependencies: string[]; }; - -type _runTask = (task: Orchestrator.TaskFunc, done: (err: any, meta: Orchestrator.Meta) => void) => void; - -type Strings = string|string[]; - /** A module for sequencing and executing tasks and dependencies in maximum concurrency */ declare class Orchestrator extends events.EventEmitter { @@ -54,7 +48,7 @@ declare class Orchestrator extends events.EventEmitter { stop(err?: any, successfulFinish?: boolean): void; - sequence: _Sequencify; + sequence: Orchestrator.Sequencify; allDone(): boolean; @@ -96,9 +90,17 @@ declare class Orchestrator extends events.EventEmitter { } declare namespace Orchestrator { - type runTask = _runTask; + type Strings = string | string[]; - type Sequencify = _Sequencify; + /** The method export generated by orchestrator/lib/runTask.js */ + type RunTask = (task: Orchestrator.TaskFunc, done: (err: any, meta: Orchestrator.Meta) => void) => void; + + /** The module export of the sequencify package: https://www.npmjs.com/package/sequencify */ + type Sequencify = (tasks: Array<{ dep: string[]; }>, names: string[]) => { + sequence: string[]; + missingTasks: string[]; + recursiveDependencies: string[]; + }; /** A task, can either call a callback to indicate task completion or return a promise or a stream: (task is marked complete when promise.then() resolves/fails or stream ends) */