Deployed the page to Github Pages.

This commit is contained in:
Batuhan Berk Başoğlu 2024-11-03 21:30:09 -05:00
parent 1d79754e93
commit 2c89899458
Signed by: batuhan-basoglu
SSH key fingerprint: SHA256:kEsnuHX+qbwhxSAXPUQ4ox535wFHu/hIRaa53FzxRpo
62797 changed files with 6551425 additions and 15279 deletions

20
node_modules/watchpack/LICENSE generated vendored Normal file
View file

@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

133
node_modules/watchpack/README.md generated vendored Normal file
View file

@ -0,0 +1,133 @@
# watchpack
Wrapper library for directory and file watching.
[![Test](https://github.com/webpack/watchpack/actions/workflows/test.yml/badge.svg)](https://github.com/webpack/watchpack/actions/workflows/test.yml)
[![Codecov](https://codecov.io/gh/webpack/watchpack/graph/badge.svg?token=8xk2OrrxWm)](https://codecov.io/gh/webpack/watchpack)
[![Downloads](https://img.shields.io/npm/dm/watchpack.svg)](https://www.npmjs.com/package/watchpack)
## Concept
watchpack high level API doesn't map directly to watchers. Instead a three level architecture ensures that for each directory only a single watcher exists.
- The high level API requests `DirectoryWatchers` from a `WatcherManager`, which ensures that only a single `DirectoryWatcher` per directory is created.
- A user-faced `Watcher` can be obtained from a `DirectoryWatcher` and provides a filtered view on the `DirectoryWatcher`.
- Reference-counting is used on the `DirectoryWatcher` and `Watcher` to decide when to close them.
- The real watchers are created by the `DirectoryWatcher`.
- Files are never watched directly. This should keep the watcher count low.
- Watching can be started in the past. This way watching can start after file reading.
- Symlinks are not followed, instead the symlink is watched.
## API
```javascript
var Watchpack = require("watchpack");
var wp = new Watchpack({
// options:
aggregateTimeout: 1000,
// fire "aggregated" event when after a change for 1000ms no additional change occurred
// aggregated defaults to undefined, which doesn't fire an "aggregated" event
poll: true,
// poll: true - use polling with the default interval
// poll: 10000 - use polling with an interval of 10s
// poll defaults to undefined, which prefer native watching methods
// Note: enable polling when watching on a network path
// When WATCHPACK_POLLING environment variable is set it will override this option
followSymlinks: true,
// true: follows symlinks and watches symlinks and real files
// (This makes sense when symlinks has not been resolved yet, comes with a performance hit)
// false (default): watches only specified item they may be real files or symlinks
// (This makes sense when symlinks has already been resolved)
ignored: "**/.git"
// ignored: "string" - a glob pattern for files or folders that should not be watched
// ignored: ["string", "string"] - multiple glob patterns that should be ignored
// 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
});
// Watchpack.prototype.watch({
// files: Iterable<string>,
// directories: Iterable<string>,
// missing: Iterable<string>,
// startTime?: number
// })
wp.watch({
files: listOfFiles,
directories: listOfDirectories,
missing: listOfNotExistingItems,
startTime: Date.now() - 10000
});
// starts watching these files and directories
// calling this again will override the files and directories
// files: can be files or directories, for files: content and existence changes are tracked
// for directories: only existence and timestamp changes are tracked
// directories: only directories, directory content (and content of children, ...) and
// existence changes are tracked.
// assumed to exist, when directory is not found without further information a remove event is emitted
// missing: can be files or directorees,
// only existence changes are tracked
// expected to not exist, no remove event is emitted when not found initially
// files and directories are assumed to exist, when they are not found without further information a remove event is emitted
// missing is assumed to not exist and no remove event is emitted
wp.on("change", function(filePath, mtime, explanation) {
// filePath: the changed file
// mtime: last modified time for the changed file
// explanation: textual information how this change was detected
});
wp.on("remove", function(filePath, explanation) {
// filePath: the removed file or directory
// explanation: textual information how this change was detected
});
wp.on("aggregated", function(changes, removals) {
// changes: a Set of all changed files
// removals: a Set of all removed files
// watchpack gives up ownership on these Sets.
});
// Watchpack.prototype.pause()
wp.pause();
// stops emitting events, but keeps watchers open
// next "watch" call can reuse the watchers
// The watcher will keep aggregating events
// which can be received with getAggregated()
// Watchpack.prototype.close()
wp.close();
// stops emitting events and closes all watchers
// Watchpack.prototype.getAggregated(): { changes: Set<string>, removals: Set<string> }
const { changes, removals } = wp.getAggregated();
// returns the current aggregated info and removes that from the watcher
// The next aggregated event won't include that info and will only emitted
// when futher changes happen
// Can also be used when paused.
// 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
// key: absolute path, value: object with { safeTime, timestamp }
// safeTime: a point in time at which it is safe to say all changes happened before that
// timestamp: only for files, the mtime timestamp of the file
// 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)
// Watchpack.prototype.getTimes()
var fileTimes = wp.getTimes();
// returns an object with all known change times for files
// this include timestamps from files not directly watched
// key: absolute path, value: timestamp as number
```

787
node_modules/watchpack/lib/DirectoryWatcher.js generated vendored Normal file
View file

@ -0,0 +1,787 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const EventEmitter = require("events").EventEmitter;
const fs = require("graceful-fs");
const path = require("path");
const watchEventSource = require("./watchEventSource");
const EXISTANCE_ONLY_TIME_ENTRY = Object.freeze({});
let FS_ACCURACY = 2000;
const IS_OSX = require("os").platform() === "darwin";
const WATCHPACK_POLLING = process.env.WATCHPACK_POLLING;
const FORCE_POLLING =
`${+WATCHPACK_POLLING}` === WATCHPACK_POLLING
? +WATCHPACK_POLLING
: !!WATCHPACK_POLLING && WATCHPACK_POLLING !== "false";
function withoutCase(str) {
return str.toLowerCase();
}
function needCalls(times, callback) {
return function() {
if (--times === 0) {
return callback();
}
};
}
class Watcher extends EventEmitter {
constructor(directoryWatcher, filePath, startTime) {
super();
this.directoryWatcher = directoryWatcher;
this.path = filePath;
this.startTime = startTime && +startTime;
}
checkStartTime(mtime, initial) {
const startTime = this.startTime;
if (typeof startTime !== "number") return !initial;
return startTime <= mtime;
}
close() {
this.emit("closed");
}
}
class DirectoryWatcher extends EventEmitter {
constructor(watcherManager, directoryPath, options) {
super();
if (FORCE_POLLING) {
options.poll = FORCE_POLLING;
}
this.watcherManager = watcherManager;
this.options = options;
this.path = directoryPath;
// safeTime is the point in time after which reading is safe to be unchanged
// timestamp is a value that should be compared with another timestamp (mtime)
/** @type {Map<string, { safeTime: number, timestamp: number }} */
this.files = new Map();
/** @type {Map<string, number>} */
this.filesWithoutCase = new Map();
this.directories = new Map();
this.lastWatchEvent = 0;
this.initialScan = true;
this.ignored = options.ignored || (() => false);
this.nestedWatching = false;
this.polledWatching =
typeof options.poll === "number"
? options.poll
: options.poll
? 5007
: false;
this.timeout = undefined;
this.initialScanRemoved = new Set();
this.initialScanFinished = undefined;
/** @type {Map<string, Set<Watcher>>} */
this.watchers = new Map();
this.parentWatcher = null;
this.refs = 0;
this._activeEvents = new Map();
this.closed = false;
this.scanning = false;
this.scanAgain = false;
this.scanAgainInitial = false;
this.createWatcher();
this.doScan(true);
}
createWatcher() {
try {
if (this.polledWatching) {
this.watcher = {
close: () => {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = undefined;
}
}
};
} else {
if (IS_OSX) {
this.watchInParentDirectory();
}
this.watcher = watchEventSource.watch(this.path);
this.watcher.on("change", this.onWatchEvent.bind(this));
this.watcher.on("error", this.onWatcherError.bind(this));
}
} catch (err) {
this.onWatcherError(err);
}
}
forEachWatcher(path, fn) {
const watchers = this.watchers.get(withoutCase(path));
if (watchers !== undefined) {
for (const w of watchers) {
fn(w);
}
}
}
setMissing(itemPath, initial, type) {
if (this.initialScan) {
this.initialScanRemoved.add(itemPath);
}
const oldDirectory = this.directories.get(itemPath);
if (oldDirectory) {
if (this.nestedWatching) oldDirectory.close();
this.directories.delete(itemPath);
this.forEachWatcher(itemPath, w => w.emit("remove", type));
if (!initial) {
this.forEachWatcher(this.path, w =>
w.emit("change", itemPath, null, type, initial)
);
}
}
const oldFile = this.files.get(itemPath);
if (oldFile) {
this.files.delete(itemPath);
const key = withoutCase(itemPath);
const count = this.filesWithoutCase.get(key) - 1;
if (count <= 0) {
this.filesWithoutCase.delete(key);
this.forEachWatcher(itemPath, w => w.emit("remove", type));
} else {
this.filesWithoutCase.set(key, count);
}
if (!initial) {
this.forEachWatcher(this.path, w =>
w.emit("change", itemPath, null, type, initial)
);
}
}
}
setFileTime(filePath, mtime, initial, ignoreWhenEqual, type) {
const now = Date.now();
if (this.ignored(filePath)) return;
const old = this.files.get(filePath);
let safeTime, accuracy;
if (initial) {
safeTime = Math.min(now, mtime) + FS_ACCURACY;
accuracy = FS_ACCURACY;
} else {
safeTime = now;
accuracy = 0;
if (old && old.timestamp === mtime && mtime + FS_ACCURACY < now) {
// We are sure that mtime is untouched
// This can be caused by some file attribute change
// e. g. when access time has been changed
// but the file content is untouched
return;
}
}
if (ignoreWhenEqual && old && old.timestamp === mtime) return;
this.files.set(filePath, {
safeTime,
accuracy,
timestamp: mtime
});
if (!old) {
const key = withoutCase(filePath);
const count = this.filesWithoutCase.get(key);
this.filesWithoutCase.set(key, (count || 0) + 1);
if (count !== undefined) {
// There is already a file with case-insensitive-equal name
// On a case-insensitive filesystem we may miss the renaming
// when only casing is changed.
// To be sure that our information is correct
// we trigger a rescan here
this.doScan(false);
}
this.forEachWatcher(filePath, w => {
if (!initial || w.checkStartTime(safeTime, initial)) {
w.emit("change", mtime, type);
}
});
} else if (!initial) {
this.forEachWatcher(filePath, w => w.emit("change", mtime, type));
}
this.forEachWatcher(this.path, w => {
if (!initial || w.checkStartTime(safeTime, initial)) {
w.emit("change", filePath, safeTime, type, initial);
}
});
}
setDirectory(directoryPath, birthtime, initial, type) {
if (this.ignored(directoryPath)) return;
if (directoryPath === this.path) {
if (!initial) {
this.forEachWatcher(this.path, w =>
w.emit("change", directoryPath, birthtime, type, initial)
);
}
} else {
const old = this.directories.get(directoryPath);
if (!old) {
const now = Date.now();
if (this.nestedWatching) {
this.createNestedWatcher(directoryPath);
} else {
this.directories.set(directoryPath, true);
}
let safeTime;
if (initial) {
safeTime = Math.min(now, birthtime) + FS_ACCURACY;
} else {
safeTime = now;
}
this.forEachWatcher(directoryPath, w => {
if (!initial || w.checkStartTime(safeTime, false)) {
w.emit("change", birthtime, type);
}
});
this.forEachWatcher(this.path, w => {
if (!initial || w.checkStartTime(safeTime, initial)) {
w.emit("change", directoryPath, safeTime, type, initial);
}
});
}
}
}
createNestedWatcher(directoryPath) {
const watcher = this.watcherManager.watchDirectory(directoryPath, 1);
watcher.on("change", (filePath, mtime, type, initial) => {
this.forEachWatcher(this.path, w => {
if (!initial || w.checkStartTime(mtime, initial)) {
w.emit("change", filePath, mtime, type, initial);
}
});
});
this.directories.set(directoryPath, watcher);
}
setNestedWatching(flag) {
if (this.nestedWatching !== !!flag) {
this.nestedWatching = !!flag;
if (this.nestedWatching) {
for (const directory of this.directories.keys()) {
this.createNestedWatcher(directory);
}
} else {
for (const [directory, watcher] of this.directories) {
watcher.close();
this.directories.set(directory, true);
}
}
}
}
watch(filePath, startTime) {
const key = withoutCase(filePath);
let watchers = this.watchers.get(key);
if (watchers === undefined) {
watchers = new Set();
this.watchers.set(key, watchers);
}
this.refs++;
const watcher = new Watcher(this, filePath, startTime);
watcher.on("closed", () => {
if (--this.refs <= 0) {
this.close();
return;
}
watchers.delete(watcher);
if (watchers.size === 0) {
this.watchers.delete(key);
if (this.path === filePath) this.setNestedWatching(false);
}
});
watchers.add(watcher);
let safeTime;
if (filePath === this.path) {
this.setNestedWatching(true);
safeTime = this.lastWatchEvent;
for (const entry of this.files.values()) {
fixupEntryAccuracy(entry);
safeTime = Math.max(safeTime, entry.safeTime);
}
} else {
const entry = this.files.get(filePath);
if (entry) {
fixupEntryAccuracy(entry);
safeTime = entry.safeTime;
} else {
safeTime = 0;
}
}
if (safeTime) {
if (safeTime >= startTime) {
process.nextTick(() => {
if (this.closed) return;
if (filePath === this.path) {
watcher.emit(
"change",
filePath,
safeTime,
"watch (outdated on attach)",
true
);
} else {
watcher.emit(
"change",
safeTime,
"watch (outdated on attach)",
true
);
}
});
}
} else if (this.initialScan) {
if (this.initialScanRemoved.has(filePath)) {
process.nextTick(() => {
if (this.closed) return;
watcher.emit("remove");
});
}
} else if (
filePath !== this.path &&
!this.directories.has(filePath) &&
watcher.checkStartTime(this.initialScanFinished, false)
) {
process.nextTick(() => {
if (this.closed) return;
watcher.emit("initial-missing", "watch (missing on attach)");
});
}
return watcher;
}
onWatchEvent(eventType, filename) {
if (this.closed) return;
if (!filename) {
// In some cases no filename is provided
// This seem to happen on windows
// So some event happened but we don't know which file is affected
// We have to do a full scan of the directory
this.doScan(false);
return;
}
const filePath = path.join(this.path, filename);
if (this.ignored(filePath)) return;
if (this._activeEvents.get(filename) === undefined) {
this._activeEvents.set(filename, false);
const checkStats = () => {
if (this.closed) return;
this._activeEvents.set(filename, false);
fs.lstat(filePath, (err, stats) => {
if (this.closed) return;
if (this._activeEvents.get(filename) === true) {
process.nextTick(checkStats);
return;
}
this._activeEvents.delete(filename);
// ENOENT happens when the file/directory doesn't exist
// EPERM happens when the containing directory doesn't exist
if (err) {
if (
err.code !== "ENOENT" &&
err.code !== "EPERM" &&
err.code !== "EBUSY"
) {
this.onStatsError(err);
} else {
if (filename === path.basename(this.path)) {
// This may indicate that the directory itself was removed
if (!fs.existsSync(this.path)) {
this.onDirectoryRemoved("stat failed");
}
}
}
}
this.lastWatchEvent = Date.now();
if (!stats) {
this.setMissing(filePath, false, eventType);
} else if (stats.isDirectory()) {
this.setDirectory(
filePath,
+stats.birthtime || 1,
false,
eventType
);
} else if (stats.isFile() || stats.isSymbolicLink()) {
if (stats.mtime) {
ensureFsAccuracy(stats.mtime);
}
this.setFileTime(
filePath,
+stats.mtime || +stats.ctime || 1,
false,
false,
eventType
);
}
});
};
process.nextTick(checkStats);
} else {
this._activeEvents.set(filename, true);
}
}
onWatcherError(err) {
if (this.closed) return;
if (err) {
if (err.code !== "EPERM" && err.code !== "ENOENT") {
console.error("Watchpack Error (watcher): " + err);
}
this.onDirectoryRemoved("watch error");
}
}
onStatsError(err) {
if (err) {
console.error("Watchpack Error (stats): " + err);
}
}
onScanError(err) {
if (err) {
console.error("Watchpack Error (initial scan): " + err);
}
this.onScanFinished();
}
onScanFinished() {
if (this.polledWatching) {
this.timeout = setTimeout(() => {
if (this.closed) return;
this.doScan(false);
}, this.polledWatching);
}
}
onDirectoryRemoved(reason) {
if (this.watcher) {
this.watcher.close();
this.watcher = null;
}
this.watchInParentDirectory();
const type = `directory-removed (${reason})`;
for (const directory of this.directories.keys()) {
this.setMissing(directory, null, type);
}
for (const file of this.files.keys()) {
this.setMissing(file, null, type);
}
}
watchInParentDirectory() {
if (!this.parentWatcher) {
const parentDir = path.dirname(this.path);
// avoid watching in the root directory
// removing directories in the root directory is not supported
if (path.dirname(parentDir) === parentDir) return;
this.parentWatcher = this.watcherManager.watchFile(this.path, 1);
this.parentWatcher.on("change", (mtime, type) => {
if (this.closed) return;
// On non-osx platforms we don't need this watcher to detect
// directory removal, as an EPERM error indicates that
if ((!IS_OSX || this.polledWatching) && this.parentWatcher) {
this.parentWatcher.close();
this.parentWatcher = null;
}
// Try to create the watcher when parent directory is found
if (!this.watcher) {
this.createWatcher();
this.doScan(false);
// directory was created so we emit an event
this.forEachWatcher(this.path, w =>
w.emit("change", this.path, mtime, type, false)
);
}
});
this.parentWatcher.on("remove", () => {
this.onDirectoryRemoved("parent directory removed");
});
}
}
doScan(initial) {
if (this.scanning) {
if (this.scanAgain) {
if (!initial) this.scanAgainInitial = false;
} else {
this.scanAgain = true;
this.scanAgainInitial = initial;
}
return;
}
this.scanning = true;
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = undefined;
}
process.nextTick(() => {
if (this.closed) return;
fs.readdir(this.path, (err, items) => {
if (this.closed) return;
if (err) {
if (err.code === "ENOENT" || err.code === "EPERM") {
this.onDirectoryRemoved("scan readdir failed");
} else {
this.onScanError(err);
}
this.initialScan = false;
this.initialScanFinished = Date.now();
if (initial) {
for (const watchers of this.watchers.values()) {
for (const watcher of watchers) {
if (watcher.checkStartTime(this.initialScanFinished, false)) {
watcher.emit(
"initial-missing",
"scan (parent directory missing in initial scan)"
);
}
}
}
}
if (this.scanAgain) {
this.scanAgain = false;
this.doScan(this.scanAgainInitial);
} else {
this.scanning = false;
}
return;
}
const itemPaths = new Set(
items.map(item => path.join(this.path, item.normalize("NFC")))
);
for (const file of this.files.keys()) {
if (!itemPaths.has(file)) {
this.setMissing(file, initial, "scan (missing)");
}
}
for (const directory of this.directories.keys()) {
if (!itemPaths.has(directory)) {
this.setMissing(directory, initial, "scan (missing)");
}
}
if (this.scanAgain) {
// Early repeat of scan
this.scanAgain = false;
this.doScan(initial);
return;
}
const itemFinished = needCalls(itemPaths.size + 1, () => {
if (this.closed) return;
this.initialScan = false;
this.initialScanRemoved = null;
this.initialScanFinished = Date.now();
if (initial) {
const missingWatchers = new Map(this.watchers);
missingWatchers.delete(withoutCase(this.path));
for (const item of itemPaths) {
missingWatchers.delete(withoutCase(item));
}
for (const watchers of missingWatchers.values()) {
for (const watcher of watchers) {
if (watcher.checkStartTime(this.initialScanFinished, false)) {
watcher.emit(
"initial-missing",
"scan (missing in initial scan)"
);
}
}
}
}
if (this.scanAgain) {
this.scanAgain = false;
this.doScan(this.scanAgainInitial);
} else {
this.scanning = false;
this.onScanFinished();
}
});
for (const itemPath of itemPaths) {
fs.lstat(itemPath, (err2, stats) => {
if (this.closed) return;
if (err2) {
if (
err2.code === "ENOENT" ||
err2.code === "EPERM" ||
err2.code === "EACCES" ||
err2.code === "EBUSY"
) {
this.setMissing(itemPath, initial, "scan (" + err2.code + ")");
} else {
this.onScanError(err2);
}
itemFinished();
return;
}
if (stats.isFile() || stats.isSymbolicLink()) {
if (stats.mtime) {
ensureFsAccuracy(stats.mtime);
}
this.setFileTime(
itemPath,
+stats.mtime || +stats.ctime || 1,
initial,
true,
"scan (file)"
);
} else if (stats.isDirectory()) {
if (!initial || !this.directories.has(itemPath))
this.setDirectory(
itemPath,
+stats.birthtime || 1,
initial,
"scan (dir)"
);
}
itemFinished();
});
}
itemFinished();
});
});
}
getTimes() {
const obj = Object.create(null);
let safeTime = this.lastWatchEvent;
for (const [file, entry] of this.files) {
fixupEntryAccuracy(entry);
safeTime = Math.max(safeTime, entry.safeTime);
obj[file] = Math.max(entry.safeTime, entry.timestamp);
}
if (this.nestedWatching) {
for (const w of this.directories.values()) {
const times = w.directoryWatcher.getTimes();
for (const file of Object.keys(times)) {
const time = times[file];
safeTime = Math.max(safeTime, time);
obj[file] = time;
}
}
obj[this.path] = safeTime;
}
if (!this.initialScan) {
for (const watchers of this.watchers.values()) {
for (const watcher of watchers) {
const path = watcher.path;
if (!Object.prototype.hasOwnProperty.call(obj, path)) {
obj[path] = null;
}
}
}
}
return obj;
}
collectTimeInfoEntries(fileTimestamps, directoryTimestamps) {
let safeTime = this.lastWatchEvent;
for (const [file, entry] of this.files) {
fixupEntryAccuracy(entry);
safeTime = Math.max(safeTime, entry.safeTime);
fileTimestamps.set(file, entry);
}
if (this.nestedWatching) {
for (const w of this.directories.values()) {
safeTime = Math.max(
safeTime,
w.directoryWatcher.collectTimeInfoEntries(
fileTimestamps,
directoryTimestamps
)
);
}
fileTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
directoryTimestamps.set(this.path, {
safeTime
});
} else {
for (const dir of this.directories.keys()) {
// No additional info about this directory
// but maybe another DirectoryWatcher has info
fileTimestamps.set(dir, EXISTANCE_ONLY_TIME_ENTRY);
if (!directoryTimestamps.has(dir))
directoryTimestamps.set(dir, EXISTANCE_ONLY_TIME_ENTRY);
}
fileTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
directoryTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
}
if (!this.initialScan) {
for (const watchers of this.watchers.values()) {
for (const watcher of watchers) {
const path = watcher.path;
if (!fileTimestamps.has(path)) {
fileTimestamps.set(path, null);
}
}
}
}
return safeTime;
}
close() {
this.closed = true;
this.initialScan = false;
if (this.watcher) {
this.watcher.close();
this.watcher = null;
}
if (this.nestedWatching) {
for (const w of this.directories.values()) {
w.close();
}
this.directories.clear();
}
if (this.parentWatcher) {
this.parentWatcher.close();
this.parentWatcher = null;
}
this.emit("closed");
}
}
module.exports = DirectoryWatcher;
module.exports.EXISTANCE_ONLY_TIME_ENTRY = EXISTANCE_ONLY_TIME_ENTRY;
function fixupEntryAccuracy(entry) {
if (entry.accuracy > FS_ACCURACY) {
entry.safeTime = entry.safeTime - entry.accuracy + FS_ACCURACY;
entry.accuracy = FS_ACCURACY;
}
}
function ensureFsAccuracy(mtime) {
if (!mtime) return;
if (FS_ACCURACY > 1 && mtime % 1 !== 0) FS_ACCURACY = 1;
else if (FS_ACCURACY > 10 && mtime % 10 !== 0) FS_ACCURACY = 10;
else if (FS_ACCURACY > 100 && mtime % 100 !== 0) FS_ACCURACY = 100;
else if (FS_ACCURACY > 1000 && mtime % 1000 !== 0) FS_ACCURACY = 1000;
}

383
node_modules/watchpack/lib/watchpack.js generated vendored Normal file
View file

@ -0,0 +1,383 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const getWatcherManager = require("./getWatcherManager");
const LinkResolver = require("./LinkResolver");
const EventEmitter = require("events").EventEmitter;
const globToRegExp = require("glob-to-regexp");
const watchEventSource = require("./watchEventSource");
const EMPTY_ARRAY = [];
const EMPTY_OPTIONS = {};
function addWatchersToSet(watchers, set) {
for (const ww of watchers) {
const w = ww.watcher;
if (!set.has(w.directoryWatcher)) {
set.add(w.directoryWatcher);
}
}
}
const stringToRegexp = ignored => {
const source = globToRegExp(ignored, { globstar: true, extended: true })
.source;
const matchingStart = source.slice(0, source.length - 1) + "(?:$|\\/)";
return matchingStart;
};
const ignoredToFunction = ignored => {
if (Array.isArray(ignored)) {
const regexp = new RegExp(ignored.map(i => stringToRegexp(i)).join("|"));
return x => regexp.test(x.replace(/\\/g, "/"));
} else if (typeof ignored === "string") {
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;
} else if (ignored) {
throw new Error(`Invalid option for 'ignored': ${ignored}`);
} else {
return () => false;
}
};
const normalizeOptions = options => {
return {
followSymlinks: !!options.followSymlinks,
ignored: ignoredToFunction(options.ignored),
poll: options.poll
};
};
const normalizeCache = new WeakMap();
const cachedNormalizeOptions = options => {
const cacheEntry = normalizeCache.get(options);
if (cacheEntry !== undefined) return cacheEntry;
const normalized = normalizeOptions(options);
normalizeCache.set(options, normalized);
return normalized;
};
class WatchpackFileWatcher {
constructor(watchpack, watcher, files) {
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) {
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 {
constructor(options) {
super();
if (!options) options = EMPTY_OPTIONS;
this.options = options;
this.aggregateTimeout =
typeof options.aggregateTimeout === "number"
? options.aggregateTimeout
: 200;
this.watcherOptions = cachedNormalizeOptions(options);
this.watcherManager = getWatcherManager(this.watcherOptions);
this.fileWatchers = new Map();
this.directoryWatchers = new Map();
this._missing = new Set();
this.startTime = undefined;
this.paused = false;
this.aggregatedChanges = new Set();
this.aggregatedRemovals = new Set();
this.aggregateTimer = undefined;
this._onTimeout = this._onTimeout.bind(this);
}
watch(arg1, arg2, arg3) {
let files, directories, missing, startTime;
if (!arg2) {
({
files = EMPTY_ARRAY,
directories = EMPTY_ARRAY,
missing = EMPTY_ARRAY,
startTime
} = arg1);
} else {
files = arg1;
directories = arg2;
missing = EMPTY_ARRAY;
startTime = arg3;
}
this.paused = false;
const fileWatchers = this.fileWatchers;
const directoryWatchers = this.directoryWatchers;
const ignored = this.watcherOptions.ignored;
const filter = path => !ignored(path);
const addToMap = (map, key, item) => {
const list = map.get(key);
if (list === undefined) {
map.set(key, item);
} else if (Array.isArray(list)) {
list.push(item);
} else {
map.set(key, [list, item]);
}
};
const fileWatchersNeeded = new Map();
const directoryWatchersNeeded = new Map();
const missingFiles = new Set();
if (this.watcherOptions.followSymlinks) {
const resolver = new LinkResolver();
for (const file of files) {
if (filter(file)) {
for (const innerFile of resolver.resolve(file)) {
if (file === innerFile || filter(innerFile)) {
addToMap(fileWatchersNeeded, innerFile, file);
}
}
}
}
for (const file of missing) {
if (filter(file)) {
for (const innerFile of resolver.resolve(file)) {
if (file === innerFile || filter(innerFile)) {
missingFiles.add(file);
addToMap(fileWatchersNeeded, innerFile, file);
}
}
}
}
for (const dir of directories) {
if (filter(dir)) {
let first = true;
for (const innerItem of resolver.resolve(dir)) {
if (filter(innerItem)) {
addToMap(
first ? directoryWatchersNeeded : fileWatchersNeeded,
innerItem,
dir
);
}
first = false;
}
}
}
} else {
for (const file of files) {
if (filter(file)) {
addToMap(fileWatchersNeeded, file, file);
}
}
for (const file of missing) {
if (filter(file)) {
missingFiles.add(file);
addToMap(fileWatchersNeeded, file, file);
}
}
for (const dir of directories) {
if (filter(dir)) {
addToMap(directoryWatchersNeeded, dir, dir);
}
}
}
// Close unneeded old watchers
// and update existing watchers
for (const [key, w] of fileWatchers) {
const needed = fileWatchersNeeded.get(key);
if (needed === undefined) {
w.close();
fileWatchers.delete(key);
} else {
w.update(needed);
fileWatchersNeeded.delete(key);
}
}
for (const [key, w] of directoryWatchers) {
const needed = directoryWatchersNeeded.get(key);
if (needed === undefined) {
w.close();
directoryWatchers.delete(key);
} else {
w.update(needed);
directoryWatchersNeeded.delete(key);
}
}
// Create new watchers and install handlers on these watchers
watchEventSource.batch(() => {
for (const [key, files] of fileWatchersNeeded) {
const watcher = this.watcherManager.watchFile(key, startTime);
if (watcher) {
fileWatchers.set(key, new WatchpackFileWatcher(this, watcher, files));
}
}
for (const [key, directories] of directoryWatchersNeeded) {
const watcher = this.watcherManager.watchDirectory(key, startTime);
if (watcher) {
directoryWatchers.set(
key,
new WatchpackDirectoryWatcher(this, watcher, directories)
);
}
}
});
this._missing = missingFiles;
this.startTime = startTime;
}
close() {
this.paused = true;
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
for (const w of this.fileWatchers.values()) w.close();
for (const w of this.directoryWatchers.values()) w.close();
this.fileWatchers.clear();
this.directoryWatchers.clear();
}
pause() {
this.paused = true;
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
}
getTimes() {
const directoryWatchers = new Set();
addWatchersToSet(this.fileWatchers.values(), directoryWatchers);
addWatchersToSet(this.directoryWatchers.values(), directoryWatchers);
const obj = Object.create(null);
for (const w of directoryWatchers) {
const times = w.getTimes();
for (const file of Object.keys(times)) obj[file] = times[file];
}
return obj;
}
getTimeInfoEntries() {
const map = new Map();
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() {
if (this.aggregateTimer) {
clearTimeout(this.aggregateTimer);
this.aggregateTimer = undefined;
}
const changes = this.aggregatedChanges;
const removals = this.aggregatedRemovals;
this.aggregatedChanges = new Set();
this.aggregatedRemovals = new Set();
return { changes, removals };
}
_onChange(item, mtime, file, type) {
file = file || item;
if (!this.paused) {
this.emit("change", file, mtime, type);
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
this.aggregateTimer = setTimeout(this._onTimeout, this.aggregateTimeout);
}
this.aggregatedRemovals.delete(item);
this.aggregatedChanges.add(item);
}
_onRemove(item, file, type) {
file = file || item;
if (!this.paused) {
this.emit("remove", file, type);
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
this.aggregateTimer = setTimeout(this._onTimeout, this.aggregateTimeout);
}
this.aggregatedChanges.delete(item);
this.aggregatedRemovals.add(item);
}
_onTimeout() {
this.aggregateTimer = undefined;
const changes = this.aggregatedChanges;
const removals = this.aggregatedRemovals;
this.aggregatedChanges = new Set();
this.aggregatedRemovals = new Set();
this.emit("aggregated", changes, removals);
}
}
module.exports = Watchpack;

49
node_modules/watchpack/package.json generated vendored Normal file
View file

@ -0,0 +1,49 @@
{
"name": "watchpack",
"version": "2.4.1",
"description": "",
"main": "./lib/watchpack.js",
"directories": {
"test": "test"
},
"files": [
"lib/"
],
"scripts": {
"pretty-files": "prettier \"lib/**.*\" \"test/**/*.js\" --write",
"lint": "eslint lib",
"test:only": "mocha",
"test:coverage": "istanbul cover node_modules/mocha/bin/_mocha",
"pretest": "yarn lint",
"test": "mocha"
},
"repository": {
"type": "git",
"url": "https://github.com/webpack/watchpack.git"
},
"author": "Tobias Koppers @sokra",
"license": "MIT",
"bugs": {
"url": "https://github.com/webpack/watchpack/issues"
},
"homepage": "https://github.com/webpack/watchpack",
"devDependencies": {
"coveralls": "^3.0.0",
"eslint": "^5.11.1",
"eslint-config-prettier": "^4.3.0",
"eslint-plugin-prettier": "^3.1.0",
"istanbul": "^0.4.3",
"mocha": "^5.0.1",
"prettier": "^1.11.0",
"rimraf": "^2.6.2",
"should": "^8.3.1",
"write-file-atomic": "^3.0.1"
},
"dependencies": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
},
"engines": {
"node": ">=10.13.0"
}
}