From c28e2cb8e09cae5085aee714aec653bc43fab108 Mon Sep 17 00:00:00 2001 From: PhilKunz Date: Sun, 25 Sep 2016 16:10:06 +0200 Subject: [PATCH] now allows the handling of custom events and run returns promise --- README.md | 29 ++++++++++++- dist/index.d.ts | 32 ++++++++++++++- dist/index.js | 56 ++++++++++++++++++++++--- dist/smartstream.plugins.d.ts | 1 - dist/smartstream.plugins.js | 3 +- package.json | 1 - test/test.js | 9 ++-- test/test.ts | 7 +++- ts/index.ts | 77 +++++++++++++++++++++++++++++++---- ts/smartstream.plugins.ts | 1 - 10 files changed, 191 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 8e5f608..5c5282b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,36 @@ # smartstream simplifies access to node streams, TypeScript ready! -## Status +## Availabililty +[![npm](https://push.rocks/assets/repo-button-npm.svg)](https://www.npmjs.com/package/smartstream) +[![git](https://push.rocks/assets/repo-button-git.svg)](https://gitlab.com/pushrocks/smartstream) +[![git](https://push.rocks/assets/repo-button-mirror.svg)](https://github.com/pushrocks/smartstream) +[![docs](https://push.rocks/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/smartstream/gitbook) + +## Status for master [![build status](https://gitlab.com/pushrocks/smartstream/badges/master/build.svg)](https://gitlab.com/pushrocks/smartstream/commits/master) +[![coverage report](https://gitlab.com/pushrocks/smartstream/badges/master/coverage.svg)](https://gitlab.com/pushrocks/smartstream/commits/master) +[![Dependency Status](https://david-dm.org/pushrocks/smartstream.svg)](https://david-dm.org/pushrocks/smartstream) +[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/smartstream/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/smartstream/master/dependencies/npm) +[![bitHound Code](https://www.bithound.io/github/pushrocks/smartstream/badges/code.svg)](https://www.bithound.io/github/pushrocks/smartstream) +[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/) +[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/) +[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) ## Usage We recommend the use of TypeScript for best in class intellisense support. +```typescript +import { Smartstream } from 'smartstream' +import * as gUglify from 'gulp-uglify' + +let mySmartstream = new Smartstream([ + gulp.src(['./file1.js','./file2.js']), + gUglify(), + gulp.dest('./some/output/path') +]) + +mySmartstream.onError((err) => {/* handle error */}) // handles all errors in stream +mySmartstream.run().then(() => {/* do something when stream is finished */}) +``` + diff --git a/dist/index.d.ts b/dist/index.d.ts index 03fbbf8..8bcbe3d 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,10 +1,38 @@ +/// +import * as plugins from './smartstream.plugins'; export interface IErrorFunction { - (err: any): number; + (err: any): any; } +export interface IStreamStartFunction { + (stream: any): any; +} +export interface ICustomEventFunction { + (): any; +} +export interface ICustomEventObject { + eventName: string; + eventFunction: ICustomEventFunction; +} +/** + * class Smartstream handles + */ export declare class Smartstream { streamArray: any[]; errorFunction: IErrorFunction; + streamStartFunction: IStreamStartFunction; + customEventObjectArray: ICustomEventObject[]; constructor(streamArrayArg: any[]); + /** + * attach an error handler to the stream to prevent throwing + */ onError(errorFunctionArg: IErrorFunction): void; - run(): any; + /** + * make something with the stream itself + */ + onStreamStart(): plugins.q.Promise; + /** + * run the stream + * @returns Promise + */ + run(): plugins.q.Promise; } diff --git a/dist/index.js b/dist/index.js index 1c51d85..c360231 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,21 +1,67 @@ "use strict"; const plugins = require("./smartstream.plugins"); +/** + * class Smartstream handles + */ class Smartstream { constructor(streamArrayArg) { this.streamArray = []; this.errorFunction = null; + this.streamStartFunction = null; + this.customEventObjectArray = []; this.streamArray = streamArrayArg; } + /** + * attach an error handler to the stream to prevent throwing + */ onError(errorFunctionArg) { this.errorFunction = errorFunctionArg; } + /** + * make something with the stream itself + */ + onStreamStart() { + } + /** + * run the stream + * @returns Promise + */ run() { - let combinedStream = plugins.streamCombiner2.obj(this.streamArray); - if (this.errorFunction !== null) { - combinedStream.on('error', this.errorFunction); + let done = plugins.q.defer(); + // clone Array + let streamExecutionArray = []; + for (let streamItem of this.streamArray) { + streamExecutionArray.push(streamItem); } - return combinedStream; + // combine the stream + let finalStream = null; + let firstIteration = true; + for (let stream of streamExecutionArray) { + if (firstIteration === true) { + finalStream = stream; + } + if (this.errorFunction !== null) { + stream.on('error', this.errorFunction); + } + for (let customEventObject of this.customEventObjectArray) { + stream.on(customEventObject.eventName, customEventObject.eventFunction); + } + if (!firstIteration) { + finalStream = finalStream.pipe(stream); + } + firstIteration = false; + } + finalStream.on('end', function () { + done.resolve(); + }); + finalStream.on('close', function () { + done.resolve(); + }); + finalStream.on('finish', function () { + done.resolve(); + }); + return done.promise; } } exports.Smartstream = Smartstream; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsaURBQWdEO0FBTWhEO0lBR0ksWUFBWSxjQUFxQjtRQUZqQyxnQkFBVyxHQUFHLEVBQUUsQ0FBQTtRQUNoQixrQkFBYSxHQUFtQixJQUFJLENBQUE7UUFFaEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxjQUFjLENBQUE7SUFDckMsQ0FBQztJQUNELE9BQU8sQ0FBQyxnQkFBZ0M7UUFDcEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQTtJQUN6QyxDQUFDO0lBQ0QsR0FBRztRQUNDLElBQUksY0FBYyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUNsRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDOUIsY0FBYyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFBO1FBQ2xELENBQUM7UUFDRCxNQUFNLENBQUMsY0FBYyxDQUFBO0lBQ3pCLENBQUM7Q0FDSjtBQWhCRCxrQ0FnQkMifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsaURBQWdEO0FBbUJoRDs7R0FFRztBQUNIO0lBS0ksWUFBWSxjQUFxQjtRQUpqQyxnQkFBVyxHQUFHLEVBQUUsQ0FBQTtRQUNoQixrQkFBYSxHQUFtQixJQUFJLENBQUE7UUFDcEMsd0JBQW1CLEdBQXlCLElBQUksQ0FBQTtRQUNoRCwyQkFBc0IsR0FBeUIsRUFBRSxDQUFBO1FBRTdDLElBQUksQ0FBQyxXQUFXLEdBQUcsY0FBYyxDQUFBO0lBQ3JDLENBQUM7SUFFRDs7T0FFRztJQUNILE9BQU8sQ0FBQyxnQkFBZ0M7UUFDcEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQTtJQUN6QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxhQUFhO0lBRWIsQ0FBQztJQUVEOzs7T0FHRztJQUNILEdBQUc7UUFDQyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBUSxDQUFBO1FBRWxDLGNBQWM7UUFDZCxJQUFJLG9CQUFvQixHQUFHLEVBQUUsQ0FBQTtRQUM3QixHQUFHLENBQUMsQ0FBQyxJQUFJLFVBQVUsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztZQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUFDLENBQUM7UUFFbEYscUJBQXFCO1FBQ3JCLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQTtRQUN0QixJQUFJLGNBQWMsR0FBWSxJQUFJLENBQUE7UUFDbEMsR0FBRyxDQUFDLENBQUMsSUFBSSxNQUFNLElBQUksb0JBQW9CLENBQUMsQ0FBQyxDQUFDO1lBQ3RDLEVBQUUsQ0FBQyxDQUFDLGNBQWMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUMxQixXQUFXLEdBQUcsTUFBTSxDQUFBO1lBQ3hCLENBQUM7WUFDRCxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQzlCLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQTtZQUMxQyxDQUFDO1lBQ0QsR0FBRyxDQUFDLENBQUMsSUFBSSxpQkFBaUIsSUFBSSxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO2dCQUN4RCxNQUFNLENBQUMsRUFBRSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsQ0FBQTtZQUMzRSxDQUFDO1lBQ0QsRUFBRSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO2dCQUNsQixXQUFXLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtZQUMxQyxDQUFDO1lBQ0QsY0FBYyxHQUFHLEtBQUssQ0FBQTtRQUMxQixDQUFDO1FBQ0QsV0FBVyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUM7WUFDakIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsV0FBVyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUM7WUFDbkIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsV0FBVyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUM7WUFDcEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztDQUNKO0FBL0RELGtDQStEQyJ9 \ No newline at end of file diff --git a/dist/smartstream.plugins.d.ts b/dist/smartstream.plugins.d.ts index 05c7dd5..f3d6e42 100644 --- a/dist/smartstream.plugins.d.ts +++ b/dist/smartstream.plugins.d.ts @@ -1,3 +1,2 @@ import 'typings-global'; export import q = require('q'); -export declare let streamCombiner2: any; diff --git a/dist/smartstream.plugins.js b/dist/smartstream.plugins.js index 76418df..38ca3a4 100644 --- a/dist/smartstream.plugins.js +++ b/dist/smartstream.plugins.js @@ -1,5 +1,4 @@ "use strict"; require("typings-global"); exports.q = require("q"); -exports.streamCombiner2 = require('stream-combiner2'); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdHJlYW0ucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c3RyZWFtLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDBCQUF1QjtBQUN2Qix5QkFBOEI7QUFDbkIsUUFBQSxlQUFlLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUEifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzdHJlYW0ucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c3RyZWFtLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDBCQUF1QjtBQUN2Qix5QkFBOEIifQ== \ No newline at end of file diff --git a/package.json b/package.json index 94dee16..b0a46ef 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "dependencies": { "@types/q": "0.x.x", "q": "^1.4.1", - "stream-combiner2": "^1.1.1", "typings-global": "^1.0.14" } } diff --git a/test/test.js b/test/test.js index a650a04..cbc59c2 100644 --- a/test/test.js +++ b/test/test.js @@ -4,12 +4,15 @@ const fs = require("fs"); const smartstream = require("../dist/index"); let testSmartstream; describe('smartstream', function () { - it('should combine a stream', function () { + it('should combine a stream', function (done) { + this.timeout(5000); testSmartstream = new smartstream.Smartstream([ fs.createReadStream('./test/assets/test.md'), fs.createWriteStream('./test/assets/testCopy.md') ]); - testSmartstream.run(); + testSmartstream.run().then(() => { + done(); + }); }); }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQix5QkFBeUI7QUFHekIsNkNBQTRDO0FBRTVDLElBQUksZUFBd0MsQ0FBQTtBQUU1QyxRQUFRLENBQUMsYUFBYSxFQUFFO0lBQ3BCLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRTtRQUMxQixlQUFlLEdBQUcsSUFBSSxXQUFXLENBQUMsV0FBVyxDQUFDO1lBQzFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyx1QkFBdUIsQ0FBQztZQUM1QyxFQUFFLENBQUMsaUJBQWlCLENBQUMsMkJBQTJCLENBQUM7U0FDcEQsQ0FBQyxDQUFBO1FBQ0YsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFBO0lBQ3pCLENBQUMsQ0FBQyxDQUFBO0FBQ04sQ0FBQyxDQUFDLENBQUEifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQix5QkFBeUI7QUFHekIsNkNBQTRDO0FBRTVDLElBQUksZUFBd0MsQ0FBQTtBQUU1QyxRQUFRLENBQUMsYUFBYSxFQUFFO0lBQ3BCLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRSxVQUFTLElBQUk7UUFDdkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNsQixlQUFlLEdBQUcsSUFBSSxXQUFXLENBQUMsV0FBVyxDQUFDO1lBQzFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyx1QkFBdUIsQ0FBQztZQUM1QyxFQUFFLENBQUMsaUJBQWlCLENBQUMsMkJBQTJCLENBQUM7U0FDcEQsQ0FBQyxDQUFBO1FBQ0YsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztZQUN2QixJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDLENBQUMsQ0FBQSJ9 \ No newline at end of file diff --git a/test/test.ts b/test/test.ts index cf3f52f..d353034 100644 --- a/test/test.ts +++ b/test/test.ts @@ -7,11 +7,14 @@ import * as smartstream from '../dist/index' let testSmartstream: smartstream.Smartstream describe('smartstream', function() { - it('should combine a stream', function(){ + it('should combine a stream', function(done){ + this.timeout(5000) testSmartstream = new smartstream.Smartstream([ fs.createReadStream('./test/assets/test.md'), fs.createWriteStream('./test/assets/testCopy.md') ]) - testSmartstream.run() + testSmartstream.run().then(() => { + done() + }) }) }) \ No newline at end of file diff --git a/ts/index.ts b/ts/index.ts index 3f20d01..f278038 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -1,23 +1,86 @@ import * as plugins from './smartstream.plugins' export interface IErrorFunction { - (err): number + (err): any } +export interface IStreamStartFunction { + (stream): any +} + +export interface ICustomEventFunction { + (): any +} + +export interface ICustomEventObject { + eventName: string + eventFunction: ICustomEventFunction +} + +/** + * class Smartstream handles + */ export class Smartstream { streamArray = [] errorFunction: IErrorFunction = null - constructor(streamArrayArg: any[]){ + streamStartFunction: IStreamStartFunction = null + customEventObjectArray: ICustomEventObject[] = [] + constructor(streamArrayArg: any[]) { this.streamArray = streamArrayArg } + + /** + * attach an error handler to the stream to prevent throwing + */ onError(errorFunctionArg: IErrorFunction) { this.errorFunction = errorFunctionArg } - run() { - let combinedStream = plugins.streamCombiner2.obj(this.streamArray) - if (this.errorFunction !== null) { - combinedStream.on('error', this.errorFunction) + + /** + * make something with the stream itself + */ + onStreamStart(): plugins.q.Promise { + + } + + /** + * run the stream + * @returns Promise + */ + run(): plugins.q.Promise { + let done = plugins.q.defer() + + // clone Array + let streamExecutionArray = [] + for (let streamItem of this.streamArray) { streamExecutionArray.push(streamItem) } + + // combine the stream + let finalStream = null + let firstIteration: boolean = true + for (let stream of streamExecutionArray) { + if (firstIteration === true) { + finalStream = stream + } + if (this.errorFunction !== null) { + stream.on('error', this.errorFunction) + } + for (let customEventObject of this.customEventObjectArray) { + stream.on(customEventObject.eventName, customEventObject.eventFunction) + } + if (!firstIteration) { + finalStream = finalStream.pipe(stream) + } + firstIteration = false } - return combinedStream + finalStream.on('end',function(){ + done.resolve() + }) + finalStream.on('close',function(){ + done.resolve() + }) + finalStream.on('finish',function(){ + done.resolve() + }) + return done.promise } } \ No newline at end of file diff --git a/ts/smartstream.plugins.ts b/ts/smartstream.plugins.ts index 1bc0d6f..73ae443 100644 --- a/ts/smartstream.plugins.ts +++ b/ts/smartstream.plugins.ts @@ -1,3 +1,2 @@ import 'typings-global' export import q = require('q') -export let streamCombiner2 = require('stream-combiner2')