Skip to content

Commit 4c9c76f

Browse files
author
Mark Molinaro
committed
Support splitting of files and directories in getTimeInfoEntries
1 parent c651129 commit 4c9c76f

4 files changed

Lines changed: 64 additions & 52 deletions

File tree

lib/DirectoryWatcher.js

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ class Watcher extends EventEmitter {
3939
this.directoryWatcher = directoryWatcher;
4040
this.path = filePath;
4141
this.startTime = startTime && +startTime;
42-
this._cachedTimeInfoEntries = undefined;
4342
}
4443

4544
checkStartTime(mtime, initial) {
@@ -136,8 +135,6 @@ class DirectoryWatcher extends EventEmitter {
136135
}
137136

138137
setMissing(itemPath, initial, type) {
139-
this._cachedTimeInfoEntries = undefined;
140-
141138
if (this.initialScan) {
142139
this.initialScanRemoved.add(itemPath);
143140
}
@@ -206,7 +203,6 @@ class DirectoryWatcher extends EventEmitter {
206203
accuracy,
207204
timestamp: mtime
208205
});
209-
this._cachedTimeInfoEntries = undefined;
210206

211207
if (!old) {
212208
const key = withoutCase(filePath);
@@ -249,7 +245,6 @@ class DirectoryWatcher extends EventEmitter {
249245
if (!old) {
250246
const now = Date.now();
251247

252-
this._cachedTimeInfoEntries = undefined;
253248
if (this.nestedWatching) {
254249
this.createNestedWatcher(directoryPath);
255250
} else {
@@ -280,7 +275,6 @@ class DirectoryWatcher extends EventEmitter {
280275
createNestedWatcher(directoryPath) {
281276
const watcher = this.watcherManager.watchDirectory(directoryPath, 1);
282277
watcher.on("change", (filePath, mtime, type, initial) => {
283-
this._cachedTimeInfoEntries = undefined;
284278
this.forEachWatcher(this.path, w => {
285279
if (!initial || w.checkStartTime(mtime, initial)) {
286280
w.emit("change", filePath, mtime, type, initial);
@@ -293,7 +287,6 @@ class DirectoryWatcher extends EventEmitter {
293287
setNestedWatching(flag) {
294288
if (this.nestedWatching !== !!flag) {
295289
this.nestedWatching = !!flag;
296-
this._cachedTimeInfoEntries = undefined;
297290
if (this.nestedWatching) {
298291
for (const directory of this.directories.keys()) {
299292
this.createNestedWatcher(directory);
@@ -431,7 +424,6 @@ class DirectoryWatcher extends EventEmitter {
431424
}
432425
}
433426
this.lastWatchEvent = Date.now();
434-
this._cachedTimeInfoEntries = undefined;
435427
if (!stats) {
436428
this.setMissing(filePath, false, eventType);
437429
} else if (stats.isDirectory()) {
@@ -714,48 +706,41 @@ class DirectoryWatcher extends EventEmitter {
714706
return obj;
715707
}
716708

717-
getTimeInfoEntries() {
718-
if (this._cachedTimeInfoEntries !== undefined)
719-
return this._cachedTimeInfoEntries;
720-
const map = new Map();
721-
let safeTime = this.lastWatchEvent;
709+
getTimeInfoEntries(fileTimestamps, directoryTimestamps, safeTime) {
710+
safeTime.value = Math.max(safeTime.value, this.lastWatchEvent);
722711
for (const [file, entry] of this.files) {
723712
fixupEntryAccuracy(entry);
724-
safeTime = Math.max(safeTime, entry.safeTime);
725-
map.set(file, entry);
713+
safeTime.value = Math.max(safeTime.value, entry.safeTime);
714+
fileTimestamps.set(file, entry);
726715
}
727716
if (this.nestedWatching) {
728717
for (const w of this.directories.values()) {
729-
const timeInfoEntries = w.directoryWatcher.getTimeInfoEntries();
730-
for (const [file, entry] of timeInfoEntries) {
731-
if (entry) {
732-
safeTime = Math.max(safeTime, entry.safeTime);
733-
}
734-
map.set(file, entry);
735-
}
718+
w.directoryWatcher.getTimeInfoEntries(
719+
fileTimestamps,
720+
directoryTimestamps,
721+
safeTime
722+
);
736723
}
737-
map.set(this.path, {
738-
safeTime
724+
directoryTimestamps.set(this.path, {
725+
safeTime: safeTime.value
739726
});
740727
} else {
741728
for (const dir of this.directories.keys()) {
742729
// No additional info about this directory
743-
map.set(dir, EXISTANCE_ONLY_TIME_ENTRY);
730+
directoryTimestamps.set(dir, EXISTANCE_ONLY_TIME_ENTRY);
744731
}
745-
map.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
732+
directoryTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
746733
}
747734
if (!this.initialScan) {
748735
for (const watchers of this.watchers.values()) {
749736
for (const watcher of watchers) {
750737
const path = watcher.path;
751-
if (!map.has(path)) {
752-
map.set(path, null);
738+
if (!directoryTimestamps.has(path)) {
739+
directoryTimestamps.set(path, null);
753740
}
754741
}
755742
}
756-
this._cachedTimeInfoEntries = map;
757743
}
758-
return map;
759744
}
760745

761746
close() {

lib/watchpack.js

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -275,29 +275,18 @@ class Watchpack extends EventEmitter {
275275
return obj;
276276
}
277277

278-
getTimeInfoEntries() {
279-
if (EXISTANCE_ONLY_TIME_ENTRY === undefined) {
280-
EXISTANCE_ONLY_TIME_ENTRY = require("./DirectoryWatcher")
281-
.EXISTANCE_ONLY_TIME_ENTRY;
282-
}
283-
const directoryWatchers = new Set();
284-
addWatchersToSet(this.fileWatchers.values(), directoryWatchers);
285-
addWatchersToSet(this.directoryWatchers.values(), directoryWatchers);
278+
getTimeInfoEntries(fileTimestamps, directoryTimestamps) {
279+
const allWatchers = new Set();
280+
addWatchersToSet(this.fileWatchers.values(), allWatchers);
281+
addWatchersToSet(this.directoryWatchers.values(), allWatchers);
286282
const map = new Map();
287-
for (const w of directoryWatchers) {
288-
const times = w.getTimeInfoEntries();
289-
for (const [path, entry] of times) {
290-
if (map.has(path)) {
291-
if (entry === EXISTANCE_ONLY_TIME_ENTRY) continue;
292-
const value = map.get(path);
293-
if (value === entry) continue;
294-
if (value !== EXISTANCE_ONLY_TIME_ENTRY) {
295-
map.set(path, Object.assign({}, value, entry));
296-
continue;
297-
}
298-
}
299-
map.set(path, entry);
300-
}
283+
// if timestamp maps are passed in, populate them, otherwise return a new map with both file and directory timestamps.
284+
if (!fileTimestamps && !directoryTimestamps) {
285+
fileTimestamps = directoryTimestamps = map;
286+
}
287+
const safeTime = { value: 0 };
288+
for (const w of allWatchers) {
289+
w.getTimeInfoEntries(fileTimestamps, directoryTimestamps, safeTime);
301290
}
302291
return map;
303292
}

test/Watchpack.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,44 @@ describe("Watchpack", function() {
524524
});
525525
});
526526

527+
it("should watch file in a sub directory (passed in maps)", function(done) {
528+
var w = new Watchpack({
529+
aggregateTimeout: 1000
530+
});
531+
var changeEvents = [];
532+
w.on("change", function(file) {
533+
if (changeEvents[changeEvents.length - 1] === file) return;
534+
changeEvents.push(file);
535+
});
536+
w.on("aggregated", function(changes) {
537+
Array.from(changes).should.be.eql([path.join(fixtures, "dir")]);
538+
changeEvents.should.be.eql([path.join(fixtures, "dir", "sub", "a")]);
539+
const files = new Map();
540+
const directories = new Map();
541+
const times = w.getTimeInfoEntries();
542+
w.getTimeInfoEntries(files, directories);
543+
// aggregated results should be the same as seperated maps
544+
Array.from(times).sort().should.be.eql([...Array.from(files), ...Array.from(directories)].sort())
545+
const dir = directories.get(path.join(fixtures, "dir"));
546+
const sub = directories.get(path.join(fixtures, "dir", "sub"));
547+
const a = files.get(path.join(fixtures, "dir", "sub", "a"));
548+
dir.should.be.type("object");
549+
dir.should.have.property("safeTime");
550+
sub.safeTime.should.be.aboveOrEqual(a.safeTime);
551+
dir.safeTime.should.be.aboveOrEqual(sub.safeTime);
552+
w.close();
553+
done();
554+
});
555+
testHelper.dir("dir");
556+
testHelper.dir(path.join("dir", "sub"));
557+
testHelper.tick(function() {
558+
w.watch([], [path.join(fixtures, "dir")]);
559+
testHelper.tick(function() {
560+
testHelper.file(path.join("dir", "sub", "a"));
561+
});
562+
});
563+
});
564+
527565
it("should watch 2 files in a not-existing directory", function(done) {
528566
var w = new Watchpack({
529567
aggregateTimeout: 1000

0 commit comments

Comments
 (0)