Skip to content

Commit ecb3bc1

Browse files
committed
watcher should continue aggregating changes even when paused
add method to get aggregated info
1 parent f1b5e2d commit ecb3bc1

3 files changed

Lines changed: 62 additions & 8 deletions

File tree

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,20 @@ wp.on("aggregated", function(changes, removals) {
9898
wp.pause();
9999
// stops emitting events, but keeps watchers open
100100
// next "watch" call can reuse the watchers
101+
// The watcher will keep aggregating events
102+
// which can be received with getAggregated()
101103

102104
// Watchpack.prototype.close()
103105
wp.close();
104106
// stops emitting events and closes all watchers
105107

108+
// Watchpack.prototype.getAggregated(): { changes: Set<string>, removals: Set<string> }
109+
const { changes, removals } = wp.getAggregated();
110+
// returns the current aggregated info and removes that from the watcher
111+
// The next aggregated event won't include that info and will only emitted
112+
// when futher changes happen
113+
// Can also be used when paused.
114+
106115
// Watchpack.prototype.getTimeInfoEntries()
107116
var fileTimes = wp.getTimeInfoEntries();
108117
// returns a Map with all known time info objects for files and directories

lib/watchpack.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,24 +302,38 @@ class Watchpack extends EventEmitter {
302302
return map;
303303
}
304304

305+
getAggregated() {
306+
if (this.aggregateTimer) {
307+
clearTimeout(this.aggregateTimer);
308+
this.aggregateTimer = undefined;
309+
}
310+
const changes = this.aggregatedChanges;
311+
const removals = this.aggregatedRemovals;
312+
this.aggregatedChanges = new Set();
313+
this.aggregatedRemovals = new Set();
314+
return { changes, removals };
315+
}
316+
305317
_onChange(item, mtime, file, type) {
306318
file = file || item;
307-
if (this.paused) return;
308-
this.emit("change", file, mtime, type);
309-
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
319+
if (!this.paused) {
320+
this.emit("change", file, mtime, type);
321+
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
322+
this.aggregateTimer = setTimeout(this._onTimeout, this.aggregateTimeout);
323+
}
310324
this.aggregatedRemovals.delete(item);
311325
this.aggregatedChanges.add(item);
312-
this.aggregateTimer = setTimeout(this._onTimeout, this.aggregateTimeout);
313326
}
314327

315328
_onRemove(item, file, type) {
316329
file = file || item;
317-
if (this.paused) return;
318-
this.emit("remove", file, type);
319-
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
330+
if (!this.paused) {
331+
this.emit("remove", file, type);
332+
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
333+
this.aggregateTimer = setTimeout(this._onTimeout, this.aggregateTimeout);
334+
}
320335
this.aggregatedChanges.delete(item);
321336
this.aggregatedRemovals.add(item);
322-
this.aggregateTimer = setTimeout(this._onTimeout, this.aggregateTimeout);
323337
}
324338

325339
_onTimeout() {

test/Watchpack.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,37 @@ describe("Watchpack", function() {
3535
});
3636
});
3737

38+
it("should aggregate changes while paused", function(done) {
39+
var w = new Watchpack({
40+
aggregateTimeout: 1000
41+
});
42+
testHelper.file("a");
43+
testHelper.file("b");
44+
w.watch([path.join(fixtures, "a"), path.join(fixtures, "b")], []);
45+
testHelper.tick(function() {
46+
w.pause();
47+
w.on("change", function(file) {
48+
throw new Error("should not be emitted");
49+
});
50+
w.on("aggregated", function(changes) {
51+
throw new Error("should not be emitted");
52+
});
53+
testHelper.tick(function() {
54+
testHelper.file("a");
55+
testHelper.remove("b");
56+
testHelper.file("b");
57+
testHelper.remove("a");
58+
testHelper.tick(function() {
59+
const { changes, removals } = w.getAggregated();
60+
Array.from(changes).should.be.eql([path.join(fixtures, "b")]);
61+
Array.from(removals).should.be.eql([path.join(fixtures, "a")]);
62+
w.close();
63+
done();
64+
});
65+
});
66+
});
67+
});
68+
3869
it("should not watch a single ignored file (glob)", function(done) {
3970
var w = new Watchpack({
4071
aggregateTimeout: 300,

0 commit comments

Comments
 (0)