Skip to content

Commit 2581e7a

Browse files
shakyShaneShane Osbourne
authored andcommitted
feat(stream): Implement dedicated .stream() method for better handling streams & to pave the way for new stream-related features
1 parent f5f3d65 commit 2581e7a

File tree

6 files changed

+118
-86
lines changed

6 files changed

+118
-86
lines changed

index.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ module.exports.use = function () {
5858
*/
5959
module.exports.reload = noop("reload");
6060

61+
/**
62+
* The `stream` method returns a transform stream and can act once or on many files.
63+
*
64+
* @method stream
65+
* @param {Object} [opts] Configuration for the stream method
66+
* @returns {*}
67+
*/
68+
module.exports.stream = noop("stream");
69+
6170
/**
6271
* Helper method for browser notifications
6372
*
@@ -159,7 +168,7 @@ function noop(name) {
159168
if (singleton) {
160169
return singleton[name].apply(singleton, args);
161170
} else {
162-
if (name === "reload" && args[0] && args[0].stream) {
171+
if (name === "stream") {
163172
return utils.noopStream();
164173
}
165174
}
@@ -248,6 +257,7 @@ function create(name, emitter) {
248257
pause: require("./lib/public/pause")(browserSync),
249258
resume: require("./lib/public/resume")(browserSync),
250259
reload: require("./lib/public/reload")(emitter),
260+
stream: require("./lib/public/stream")(emitter),
251261
cleanup: browserSync.cleanup.bind(browserSync),
252262
use: browserSync.registerPlugin.bind(browserSync),
253263
getOption: browserSync.getOption.bind(browserSync),

lib/public/reload.js

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"use strict";
22

3-
var path = require("path");
43
var utils = require("../utils");
4+
var _ = require("lodash");
55
var defaultConfig = require("../default-config");
6+
var stream = require("./stream");
67

78
/**
89
* @param emitter
@@ -22,12 +23,21 @@ module.exports = function (emitter) {
2223
emitter.emit("browser:reload");
2324
}
2425

25-
function emitInfo(changed) {
26-
emitter.emit("stream:changed", {changed: changed});
27-
}
28-
2926
return function (arg) {
3027

28+
/**
29+
* BACK COMPAT.
30+
* Passing an object as the only arg to the `reload`
31+
* method was only ever used for streams support
32+
* so it's safe to check for that signature here and defer to the
33+
* dedicated `.stream()` method
34+
*/
35+
if (_.isObject(arg)) {
36+
if (!Array.isArray(arg) && Object.keys(arg).length) {
37+
return stream(emitter)(arg);
38+
}
39+
}
40+
3141
if (typeof arg === "string" && arg !== "undefined") {
3242
return emitReload(arg, true);
3343
}
@@ -43,56 +53,6 @@ module.exports = function (emitter) {
4353
});
4454
}
4555

46-
if (arg && arg.stream === true) {
47-
48-
// Handle Streams here...
49-
var emitted = false;
50-
var once = arg.once || false;
51-
var Transform = require("stream").Transform;
52-
var reload = new Transform({objectMode:true});
53-
var changed = [];
54-
55-
reload._transform = function (file, encoding, next) {
56-
57-
if (once === true && !emitted) {
58-
59-
emitBrowserReload();
60-
61-
emitted = true;
62-
63-
} else { // handle multiple
64-
65-
if (once === true && emitted) {
66-
67-
} else {
68-
69-
if (file.path) {
70-
71-
emitted = true;
72-
emitReload(file.path, false);
73-
changed.push(path.basename(file.path));
74-
}
75-
}
76-
}
77-
78-
this.push(file); // always send the file down-stream
79-
80-
next();
81-
};
82-
83-
reload._flush = function (next) {
84-
85-
if (changed.length) {
86-
emitInfo(changed);
87-
}
88-
89-
next();
90-
};
91-
92-
return reload;
93-
}
94-
9556
return emitBrowserReload();
96-
9757
};
9858
};

lib/public/stream.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"use strict";
2+
3+
var path = require("path");
4+
5+
/**
6+
* @param emitter
7+
* @returns {Function}
8+
*/
9+
module.exports = function (emitter) {
10+
11+
function emitReload(path, log) {
12+
emitter.emit("file:changed", {
13+
path: path,
14+
log: log,
15+
namespace: "core"
16+
});
17+
}
18+
19+
function emitBrowserReload() {
20+
emitter.emit("browser:reload");
21+
}
22+
23+
function emitInfo(changed) {
24+
emitter.emit("stream:changed", {changed: changed});
25+
}
26+
27+
return function (opts) {
28+
29+
opts = opts || {};
30+
var emitted = false;
31+
var Transform = require("stream").Transform;
32+
var reload = new Transform({objectMode: true});
33+
var changed = [];
34+
35+
reload._transform = function (file, encoding, next) {
36+
37+
if (opts.once === true && !emitted) {
38+
39+
emitBrowserReload();
40+
41+
emitted = true;
42+
43+
} else { // handle multiple
44+
45+
if (opts.once === true && emitted) {
46+
47+
} else {
48+
49+
if (file.path) {
50+
51+
emitted = true;
52+
emitReload(file.path, false);
53+
changed.push(path.basename(file.path));
54+
}
55+
}
56+
}
57+
58+
this.push(file); // always send the file down-stream
59+
60+
next();
61+
};
62+
63+
reload._flush = function (next) {
64+
65+
if (changed.length) {
66+
emitInfo(changed);
67+
}
68+
69+
next();
70+
};
71+
72+
return reload;
73+
};
74+
};

test/specs/api/init.reload.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var browserSync = require("../../../");
44

55
var sinon = require("sinon");
66
var assert = require("chai").assert;
7+
var File = require("vinyl");
78

89
describe("API: .reload()", function () {
910

@@ -66,4 +67,13 @@ describe("API: .reload()", function () {
6667
browserSync.reload(["index.html", "css/core.css"]);
6768
sinon.assert.calledWithExactly(emitterStub, "browser:reload");
6869
});
70+
it("should reload browser if once:true given as arg", function () {
71+
var stream = browserSync.reload({stream: true, once: true});
72+
stream.write(new File({path: "styles.css"}));
73+
stream.write(new File({path: "styles2.css"}));
74+
stream.write(new File({path: "styles3.css"}));
75+
stream.end();
76+
sinon.assert.calledOnce(emitterStub);
77+
sinon.assert.calledWithExactly(emitterStub, "browser:reload");
78+
});
6979
});

test/specs/api/init.reload.stream.js

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var browserSync = require("../../../");
55
var sinon = require("sinon");
66
var File = require("vinyl");
77

8-
describe("API: .reload()", function () {
8+
describe("API: .stream()", function () {
99

1010
var emitterStub, clock, bs;
1111

@@ -30,9 +30,7 @@ describe("API: .reload()", function () {
3030
});
3131

3232
it("should handle a single file changed", function () {
33-
var stream = browserSync.reload({
34-
stream: true
35-
});
33+
var stream = browserSync.stream();
3634
stream.write(new File({path: "styles.css"}));
3735
stream.end();
3836
sinon.assert.calledWithExactly(emitterStub, "file:changed", {
@@ -42,7 +40,7 @@ describe("API: .reload()", function () {
4240
});
4341
});
4442
it("should accept multiple files in stream", function () {
45-
var stream = browserSync.reload({stream: true});
43+
var stream = browserSync.stream();
4644
stream.write(new File({path: "styles.css"}));
4745
stream.write(new File({path: "styles2.css"}));
4846
stream.end();
@@ -61,34 +59,16 @@ describe("API: .reload()", function () {
6159
});
6260
});
6361
it("should reload browser if once:true given as arg", function () {
64-
var stream = browserSync.reload({stream: true, once: true});
62+
var stream = browserSync.stream({once: true});
6563
stream.write(new File({path: "styles.css"}));
6664
stream.write(new File({path: "styles2.css"}));
6765
stream.write(new File({path: "styles3.css"}));
6866
stream.end();
6967
sinon.assert.calledOnce(emitterStub);
7068
sinon.assert.calledWithExactly(emitterStub, "browser:reload");
7169
});
72-
it("should be able to call .reload after a stream", function () {
73-
browserSync.reload();
74-
sinon.assert.calledWithExactly(emitterStub, "browser:reload");
75-
76-
var stream = browserSync.reload({stream: true});
77-
stream.write(new File({path: "styles.css"}));
78-
stream.end();
79-
80-
sinon.assert.calledWithExactly(emitterStub, "browser:reload");
81-
sinon.assert.calledWithExactly(emitterStub, "file:changed", {
82-
path: "styles.css",
83-
log: false,
84-
namespace: "core"
85-
});
86-
sinon.assert.calledWithExactly(emitterStub, "stream:changed", {
87-
changed: ["styles.css"]
88-
});
89-
});
9070
it("does not log file info if (once: true)", function () {
91-
var stream = browserSync.reload({stream: true, once: true});
71+
var stream = browserSync.stream({once: true});
9272
stream.write(new File({path: "styles.js"}));
9373
stream.write(new File({path: "styles2.js"}));
9474
stream.write(new File({path: "styles3.js"}));

test/specs/api/init.reload.stream.noop.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,15 @@ var assert = require("chai").assert;
55
var File = require("vinyl");
66
var sinon = require("sinon");
77

8-
describe("API: .reload()", function () {
8+
describe("API: .stream() noop", function () {
99

1010
before(function () {
1111
browserSync.reset();
1212
});
1313

1414
it("should can handle a reload + stream call when there's no instance", function () {
1515
assert.doesNotThrow(function () {
16-
var stream = browserSync.reload({
17-
stream: true
18-
});
16+
var stream = browserSync.stream();
1917
stream.write(new File({path: "styles.css"}));
2018
stream.end();
2119
});
@@ -24,7 +22,7 @@ describe("API: .reload()", function () {
2422
var emitterStub;
2523
var bs = browserSync(function () {
2624

27-
var stream = bs.reload({stream:true});
25+
var stream = bs.stream();
2826

2927
emitterStub = sinon.spy(bs.emitter, "emit");
3028

0 commit comments

Comments
 (0)