Socket
Socket
Sign inDemoInstall

watchpack

Package Overview
Dependencies
2
Maintainers
1
Versions
55
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.2.0 to 2.3.0

60

lib/DirectoryWatcher.js

@@ -42,3 +42,2 @@ /*

this.startTime = startTime && +startTime;
this._cachedTimeInfoEntries = undefined;
}

@@ -75,3 +74,3 @@

this.initialScan = true;
this.ignored = options.ignored;
this.ignored = options.ignored || (() => false);
this.nestedWatching = false;

@@ -101,8 +100,2 @@ this.polledWatching =

checkIgnore(path) {
if (!this.ignored) return false;
path = path.replace(/\\/g, "/");
return this.ignored.test(path);
}
createWatcher() {

@@ -142,4 +135,2 @@ try {

setMissing(itemPath, initial, type) {
this._cachedTimeInfoEntries = undefined;
if (this.initialScan) {

@@ -185,3 +176,3 @@ this.initialScanRemoved.add(itemPath);

if (this.checkIgnore(filePath)) return;
if (this.ignored(filePath)) return;

@@ -214,3 +205,2 @@ const old = this.files.get(filePath);

});
this._cachedTimeInfoEntries = undefined;

@@ -246,3 +236,3 @@ if (!old) {

setDirectory(directoryPath, birthtime, initial, type) {
if (this.checkIgnore(directoryPath)) return;
if (this.ignored(directoryPath)) return;
if (directoryPath === this.path) {

@@ -259,3 +249,2 @@ if (!initial) {

this._cachedTimeInfoEntries = undefined;
if (this.nestedWatching) {

@@ -291,3 +280,2 @@ this.createNestedWatcher(directoryPath);

watcher.on("change", (filePath, mtime, type, initial) => {
this._cachedTimeInfoEntries = undefined;
this.forEachWatcher(this.path, w => {

@@ -305,3 +293,2 @@ if (!initial || w.checkStartTime(mtime, initial)) {

this.nestedWatching = !!flag;
this._cachedTimeInfoEntries = undefined;
if (this.nestedWatching) {

@@ -411,3 +398,3 @@ for (const directory of this.directories.keys()) {

const filePath = path.join(this.path, filename);
if (this.checkIgnore(filePath)) return;
if (this.ignored(filePath)) return;

@@ -445,3 +432,2 @@ if (this._activeEvents.get(filename) === undefined) {

this.lastWatchEvent = Date.now();
this._cachedTimeInfoEntries = undefined;
if (!stats) {

@@ -660,2 +646,3 @@ this.setMissing(filePath, false, eventType);

err2.code === "EPERM" ||
err2.code === "EACCES" ||
err2.code === "EBUSY"

@@ -730,6 +717,3 @@ ) {

getTimeInfoEntries() {
if (this._cachedTimeInfoEntries !== undefined)
return this._cachedTimeInfoEntries;
const map = new Map();
collectTimeInfoEntries(fileTimestamps, directoryTimestamps) {
let safeTime = this.lastWatchEvent;

@@ -739,15 +723,17 @@ for (const [file, entry] of this.files) {

safeTime = Math.max(safeTime, entry.safeTime);
map.set(file, entry);
fileTimestamps.set(file, entry);
}
if (this.nestedWatching) {
for (const w of this.directories.values()) {
const timeInfoEntries = w.directoryWatcher.getTimeInfoEntries();
for (const [file, entry] of timeInfoEntries) {
if (entry) {
safeTime = Math.max(safeTime, entry.safeTime);
}
map.set(file, entry);
}
safeTime = Math.max(
safeTime,
w.directoryWatcher.collectTimeInfoEntries(
fileTimestamps,
directoryTimestamps,
safeTime
)
);
}
map.set(this.path, {
fileTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
directoryTimestamps.set(this.path, {
safeTime

@@ -758,5 +744,6 @@ });

// No additional info about this directory
map.set(dir, EXISTANCE_ONLY_TIME_ENTRY);
directoryTimestamps.set(dir, EXISTANCE_ONLY_TIME_ENTRY);
}
map.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
fileTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
directoryTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
}

@@ -767,10 +754,9 @@ if (!this.initialScan) {

const path = watcher.path;
if (!map.has(path)) {
map.set(path, null);
if (!fileTimestamps.has(path)) {
fileTimestamps.set(path, null);
}
}
}
this._cachedTimeInfoEntries = map;
}
return map;
return safeTime;
}

@@ -777,0 +763,0 @@

@@ -13,4 +13,2 @@ /*

let EXISTANCE_ONLY_TIME_ENTRY; // lazy required
const EMPTY_ARRAY = [];

@@ -20,6 +18,6 @@ const EMPTY_OPTIONS = {};

function addWatchersToSet(watchers, set) {
for (const w of watchers) {
if (w !== true && !set.has(w.directoryWatcher)) {
for (const ww of watchers) {
const w = ww.watcher;
if (!set.has(w.directoryWatcher)) {
set.add(w.directoryWatcher);
addWatchersToSet(w.directoryWatcher.directories.values(), set);
}

@@ -36,8 +34,12 @@ }

const ignoredToRegexp = ignored => {
const ignoredToFunction = ignored => {
if (Array.isArray(ignored)) {
return new RegExp(ignored.map(i => stringToRegexp(i)).join("|"));
const regexp = new RegExp(ignored.map(i => stringToRegexp(i)).join("|"));
return x => regexp.test(x.replace(/\\/g, "/"));
} else if (typeof ignored === "string") {
return new RegExp(stringToRegexp(ignored));
const regexp = new RegExp(stringToRegexp(ignored));
return x => regexp.test(x.replace(/\\/g, "/"));
} else if (ignored instanceof RegExp) {
return x => ignored.test(x.replace(/\\/g, "/"));
} else if (ignored instanceof Function) {
return ignored;

@@ -47,3 +49,3 @@ } else if (ignored) {

} else {
return undefined;
return () => false;
}

@@ -55,3 +57,3 @@ };

followSymlinks: !!options.followSymlinks,
ignored: ignoredToRegexp(options.ignored),
ignored: ignoredToFunction(options.ignored),
poll: options.poll

@@ -70,2 +72,81 @@ };

class WatchpackFileWatcher {
constructor(watchpack, watcher, files) {
if (!watcher) throw new Error();
this.files = Array.isArray(files) ? files : [files];
this.watcher = watcher;
watcher.on("initial-missing", type => {
for (const file of this.files) {
if (!watchpack._missing.has(file))
watchpack._onRemove(file, file, type);
}
});
watcher.on("change", (mtime, type) => {
for (const file of this.files) {
watchpack._onChange(file, mtime, file, type);
}
});
watcher.on("remove", type => {
for (const file of this.files) {
watchpack._onRemove(file, file, type);
}
});
}
update(files) {
if (!Array.isArray(files)) {
if (this.files.length !== 1) {
this.files = [files];
} else if (this.files[0] !== files) {
this.files[0] = files;
}
} else {
this.files = files;
}
}
close() {
this.watcher.close();
}
}
class WatchpackDirectoryWatcher {
constructor(watchpack, watcher, directories) {
if (!watcher) throw new Error();
this.directories = Array.isArray(directories) ? directories : [directories];
this.watcher = watcher;
watcher.on("initial-missing", type => {
for (const item of this.directories) {
watchpack._onRemove(item, item, type);
}
});
watcher.on("change", (file, mtime, type) => {
for (const item of this.directories) {
watchpack._onChange(item, mtime, file, type);
}
});
watcher.on("remove", type => {
for (const item of this.directories) {
watchpack._onRemove(item, item, type);
}
});
}
update(directories) {
if (!Array.isArray(directories)) {
if (this.directories.length !== 1) {
this.directories = [directories];
} else if (this.directories[0] !== directories) {
this.directories[0] = directories;
}
} else {
this.directories = directories;
}
}
close() {
this.watcher.close();
}
}
class Watchpack extends EventEmitter {

@@ -84,2 +165,3 @@ constructor(options) {

this.directoryWatchers = new Map();
this._missing = new Set();
this.startTime = undefined;

@@ -109,14 +191,14 @@ this.paused = false;

this.paused = false;
const oldFileWatchers = this.fileWatchers;
const oldDirectoryWatchers = this.directoryWatchers;
const fileWatchers = this.fileWatchers;
const directoryWatchers = this.directoryWatchers;
const ignored = this.watcherOptions.ignored;
const filter = ignored
? path => !ignored.test(path.replace(/\\/g, "/"))
: () => true;
const filter = path => !ignored(path);
const addToMap = (map, key, item) => {
const list = map.get(key);
if (list === undefined) {
map.set(key, [item]);
map.set(key, item);
} else if (Array.isArray(list)) {
list.push(item);
} else {
list.push(item);
map.set(key, [list, item]);
}

@@ -181,55 +263,22 @@ };

}
const newFileWatchers = new Map();
const newDirectoryWatchers = new Map();
const setupFileWatcher = (watcher, key, files) => {
watcher.on("initial-missing", type => {
for (const file of files) {
if (!missingFiles.has(file)) this._onRemove(file, file, type);
}
});
watcher.on("change", (mtime, type) => {
for (const file of files) {
this._onChange(file, mtime, file, type);
}
});
watcher.on("remove", type => {
for (const file of files) {
this._onRemove(file, file, type);
}
});
newFileWatchers.set(key, watcher);
};
const setupDirectoryWatcher = (watcher, key, directories) => {
watcher.on("initial-missing", type => {
for (const item of directories) {
this._onRemove(item, item, type);
}
});
watcher.on("change", (file, mtime, type) => {
for (const item of directories) {
this._onChange(item, mtime, file, type);
}
});
watcher.on("remove", type => {
for (const item of directories) {
this._onRemove(item, item, type);
}
});
newDirectoryWatchers.set(key, watcher);
};
// Close unneeded old watchers
const fileWatchersToClose = [];
const directoryWatchersToClose = [];
for (const [key, w] of oldFileWatchers) {
if (!fileWatchersNeeded.has(key)) {
// and update existing watchers
for (const [key, w] of fileWatchers) {
const needed = fileWatchersNeeded.get(key);
if (needed === undefined) {
w.close();
fileWatchers.delete(key);
} else {
fileWatchersToClose.push(w);
w.update(needed);
fileWatchersNeeded.delete(key);
}
}
for (const [key, w] of oldDirectoryWatchers) {
if (!directoryWatchersNeeded.has(key)) {
for (const [key, w] of directoryWatchers) {
const needed = directoryWatchersNeeded.get(key);
if (needed === undefined) {
w.close();
directoryWatchers.delete(key);
} else {
directoryWatchersToClose.push(w);
w.update(needed);
directoryWatchersNeeded.delete(key);
}

@@ -242,3 +291,3 @@ }

if (watcher) {
setupFileWatcher(watcher, key, files);
fileWatchers.set(key, new WatchpackFileWatcher(this, watcher, files));
}

@@ -249,12 +298,10 @@ }

if (watcher) {
setupDirectoryWatcher(watcher, key, directories);
directoryWatchers.set(
key,
new WatchpackDirectoryWatcher(this, watcher, directories)
);
}
}
});
// Close old watchers
for (const w of fileWatchersToClose) w.close();
for (const w of directoryWatchersToClose) w.close();
// Store watchers
this.fileWatchers = newFileWatchers;
this.directoryWatchers = newDirectoryWatchers;
this._missing = missingFiles;
this.startTime = startTime;

@@ -290,28 +337,17 @@ }

getTimeInfoEntries() {
if (EXISTANCE_ONLY_TIME_ENTRY === undefined) {
EXISTANCE_ONLY_TIME_ENTRY = require("./DirectoryWatcher")
.EXISTANCE_ONLY_TIME_ENTRY;
}
const directoryWatchers = new Set();
addWatchersToSet(this.fileWatchers.values(), directoryWatchers);
addWatchersToSet(this.directoryWatchers.values(), directoryWatchers);
const map = new Map();
for (const w of directoryWatchers) {
const times = w.getTimeInfoEntries();
for (const [path, entry] of times) {
if (map.has(path)) {
if (entry === EXISTANCE_ONLY_TIME_ENTRY) continue;
const value = map.get(path);
if (value === entry) continue;
if (value !== EXISTANCE_ONLY_TIME_ENTRY) {
map.set(path, Object.assign({}, value, entry));
continue;
}
}
map.set(path, entry);
}
}
this.collectTimeInfoEntries(map, map);
return map;
}
collectTimeInfoEntries(fileTimestamps, directoryTimestamps) {
const allWatchers = new Set();
addWatchersToSet(this.fileWatchers.values(), allWatchers);
addWatchersToSet(this.directoryWatchers.values(), allWatchers);
const safeTime = { value: 0 };
for (const w of allWatchers) {
w.collectTimeInfoEntries(fileTimestamps, directoryTimestamps, safeTime);
}
}
getAggregated() {

@@ -318,0 +354,0 @@ if (this.aggregateTimer) {

{
"name": "watchpack",
"version": "2.2.0",
"version": "2.3.0",
"description": "",

@@ -5,0 +5,0 @@ "main": "./lib/watchpack.js",

@@ -52,2 +52,4 @@ # watchpack

// ignored: /regexp/ - a regular expression for files or folders that should not be watched
// ignored: (entry) => boolean - an arbitrary function which must return truthy to ignore an entry
// For all cases expect the arbitrary function the path will have path separator normalized to '/'.
// All subdirectories are ignored too

@@ -116,5 +118,5 @@ });

// Watchpack.prototype.getTimeInfoEntries()
var fileTimes = wp.getTimeInfoEntries();
// returns a Map with all known time info objects for files and directories
// Watchpack.prototype.collectTimeInfoEntries(fileInfoEntries: Map<string, Entry>, directoryInfoEntries: Map<string, Entry>)
wp.collectTimeInfoEntries(fileInfoEntries, directoryInfoEntries);
// collects time info objects for all known files and directories
// this include info from files not directly watched

@@ -125,2 +127,7 @@ // key: absolute path, value: object with { safeTime, timestamp }

// Watchpack.prototype.getTimeInfoEntries()
var fileTimes = wp.getTimeInfoEntries();
// returns a Map with all known time info objects for files and directories
// similar to collectTimeInfoEntries but returns a single map with all entries
// (deprecated)

@@ -134,9 +141,9 @@ // Watchpack.prototype.getTimes()

[build-status]: https://travis-ci.org/webpack/watchpack.svg?branch=master
[build-status]: https://travis-ci.org/webpack/watchpack.svg?branch=main
[build-status-url]: https://travis-ci.org/webpack/watchpack
[build-status-veyor]: https://ci.appveyor.com/api/projects/status/e5u2qvmugtv0r647/branch/master?svg=true
[build-status-veyor-url]: https://ci.appveyor.com/project/sokra/watchpack/branch/master
[build-status-veyor]: https://ci.appveyor.com/api/projects/status/e5u2qvmugtv0r647/branch/main?svg=true
[build-status-veyor-url]: https://ci.appveyor.com/project/sokra/watchpack/branch/main
[coveralls-url]: https://coveralls.io/r/webpack/watchpack/
[coveralls-image]: https://img.shields.io/coveralls/webpack/watchpack.svg
[codecov]: https://codecov.io/gh/webpack/watchpack/branch/master/graph/badge.svg
[codecov]: https://codecov.io/gh/webpack/watchpack/branch/main/graph/badge.svg
[codecov-url]: https://codecov.io/gh/webpack/watchpack

@@ -143,0 +150,0 @@ [downloads]: https://img.shields.io/npm/dm/watchpack.svg

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc