diff options
author | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 |
---|---|---|
committer | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 |
commit | 5d309ff52cd399a6b71968a6b9a70c8ac0b98981 (patch) | |
tree | 360f7eb50f956e2367ef38fa1fc6ac7ac5258042 /node_modules/jest-haste-map/build/watchers/NodeWatcher.js | |
parent | b500a50f1b97d93c98b36ed9a980f8188d648147 (diff) | |
download | LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.tar.gz LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.zip |
Added node_modules for the updating to work properly.
Diffstat (limited to 'node_modules/jest-haste-map/build/watchers/NodeWatcher.js')
-rw-r--r-- | node_modules/jest-haste-map/build/watchers/NodeWatcher.js | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/node_modules/jest-haste-map/build/watchers/NodeWatcher.js b/node_modules/jest-haste-map/build/watchers/NodeWatcher.js new file mode 100644 index 0000000..8ae1bc4 --- /dev/null +++ b/node_modules/jest-haste-map/build/watchers/NodeWatcher.js @@ -0,0 +1,375 @@ +// vendored from https://github.com/amasad/sane/blob/64ff3a870c42e84f744086884bf55a4f9c22d376/src/node_watcher.js +'use strict'; + +const EventEmitter = require('events').EventEmitter; + +const fs = require('fs'); + +const platform = require('os').platform(); + +const path = require('path'); + +const common = require('./common'); +/** + * Constants + */ + +const DEFAULT_DELAY = common.DEFAULT_DELAY; +const CHANGE_EVENT = common.CHANGE_EVENT; +const DELETE_EVENT = common.DELETE_EVENT; +const ADD_EVENT = common.ADD_EVENT; +const ALL_EVENT = common.ALL_EVENT; +/** + * Export `NodeWatcher` class. + * Watches `dir`. + * + * @class NodeWatcher + * @param {String} dir + * @param {Object} opts + * @public + */ + +module.exports = class NodeWatcher extends EventEmitter { + constructor(dir, opts) { + super(); + common.assignOptions(this, opts); + this.watched = Object.create(null); + this.changeTimers = Object.create(null); + this.dirRegistery = Object.create(null); + this.root = path.resolve(dir); + this.watchdir = this.watchdir.bind(this); + this.register = this.register.bind(this); + this.checkedEmitError = this.checkedEmitError.bind(this); + this.watchdir(this.root); + common.recReaddir( + this.root, + this.watchdir, + this.register, + this.emit.bind(this, 'ready'), + this.checkedEmitError, + this.ignored + ); + } + /** + * Register files that matches our globs to know what to type of event to + * emit in the future. + * + * Registery looks like the following: + * + * dirRegister => Map { + * dirpath => Map { + * filename => true + * } + * } + * + * @param {string} filepath + * @return {boolean} whether or not we have registered the file. + * @private + */ + + register(filepath) { + const relativePath = path.relative(this.root, filepath); + + if ( + !common.isFileIncluded(this.globs, this.dot, this.doIgnore, relativePath) + ) { + return false; + } + + const dir = path.dirname(filepath); + + if (!this.dirRegistery[dir]) { + this.dirRegistery[dir] = Object.create(null); + } + + const filename = path.basename(filepath); + this.dirRegistery[dir][filename] = true; + return true; + } + /** + * Removes a file from the registery. + * + * @param {string} filepath + * @private + */ + + unregister(filepath) { + const dir = path.dirname(filepath); + + if (this.dirRegistery[dir]) { + const filename = path.basename(filepath); + delete this.dirRegistery[dir][filename]; + } + } + /** + * Removes a dir from the registery. + * + * @param {string} dirpath + * @private + */ + + unregisterDir(dirpath) { + if (this.dirRegistery[dirpath]) { + delete this.dirRegistery[dirpath]; + } + } + /** + * Checks if a file or directory exists in the registery. + * + * @param {string} fullpath + * @return {boolean} + * @private + */ + + registered(fullpath) { + const dir = path.dirname(fullpath); + return ( + this.dirRegistery[fullpath] || + (this.dirRegistery[dir] && + this.dirRegistery[dir][path.basename(fullpath)]) + ); + } + /** + * Emit "error" event if it's not an ignorable event + * + * @param error + * @private + */ + + checkedEmitError(error) { + if (!isIgnorableFileError(error)) { + this.emit('error', error); + } + } + /** + * Watch a directory. + * + * @param {string} dir + * @private + */ + + watchdir(dir) { + if (this.watched[dir]) { + return; + } + + const watcher = fs.watch( + dir, + { + persistent: true + }, + this.normalizeChange.bind(this, dir) + ); + this.watched[dir] = watcher; + watcher.on('error', this.checkedEmitError); + + if (this.root !== dir) { + this.register(dir); + } + } + /** + * Stop watching a directory. + * + * @param {string} dir + * @private + */ + + stopWatching(dir) { + if (this.watched[dir]) { + this.watched[dir].close(); + delete this.watched[dir]; + } + } + /** + * End watching. + * + * @public + */ + + close() { + Object.keys(this.watched).forEach(this.stopWatching, this); + this.removeAllListeners(); + return Promise.resolve(); + } + /** + * On some platforms, as pointed out on the fs docs (most likely just win32) + * the file argument might be missing from the fs event. Try to detect what + * change by detecting if something was deleted or the most recent file change. + * + * @param {string} dir + * @param {string} event + * @param {string} file + * @public + */ + + detectChangedFile(dir, event, callback) { + if (!this.dirRegistery[dir]) { + return; + } + + let found = false; + let closest = { + mtime: 0 + }; + let c = 0; + Object.keys(this.dirRegistery[dir]).forEach(function (file, i, arr) { + fs.lstat(path.join(dir, file), (error, stat) => { + if (found) { + return; + } + + if (error) { + if (isIgnorableFileError(error)) { + found = true; + callback(file); + } else { + this.emit('error', error); + } + } else { + if (stat.mtime > closest.mtime) { + stat.file = file; + closest = stat; + } + + if (arr.length === ++c) { + callback(closest.file); + } + } + }); + }, this); + } + /** + * Normalize fs events and pass it on to be processed. + * + * @param {string} dir + * @param {string} event + * @param {string} file + * @public + */ + + normalizeChange(dir, event, file) { + if (!file) { + this.detectChangedFile(dir, event, actualFile => { + if (actualFile) { + this.processChange(dir, event, actualFile); + } + }); + } else { + this.processChange(dir, event, path.normalize(file)); + } + } + /** + * Process changes. + * + * @param {string} dir + * @param {string} event + * @param {string} file + * @public + */ + + processChange(dir, event, file) { + const fullPath = path.join(dir, file); + const relativePath = path.join(path.relative(this.root, dir), file); + fs.lstat(fullPath, (error, stat) => { + if (error && error.code !== 'ENOENT') { + this.emit('error', error); + } else if (!error && stat.isDirectory()) { + // win32 emits usless change events on dirs. + if (event !== 'change') { + this.watchdir(fullPath); + + if ( + common.isFileIncluded( + this.globs, + this.dot, + this.doIgnore, + relativePath + ) + ) { + this.emitEvent(ADD_EVENT, relativePath, stat); + } + } + } else { + const registered = this.registered(fullPath); + + if (error && error.code === 'ENOENT') { + this.unregister(fullPath); + this.stopWatching(fullPath); + this.unregisterDir(fullPath); + + if (registered) { + this.emitEvent(DELETE_EVENT, relativePath); + } + } else if (registered) { + this.emitEvent(CHANGE_EVENT, relativePath, stat); + } else { + if (this.register(fullPath)) { + this.emitEvent(ADD_EVENT, relativePath, stat); + } + } + } + }); + } + /** + * Triggers a 'change' event after debounding it to take care of duplicate + * events on os x. + * + * @private + */ + + emitEvent(type, file, stat) { + const key = type + '-' + file; + const addKey = ADD_EVENT + '-' + file; + + if (type === CHANGE_EVENT && this.changeTimers[addKey]) { + // Ignore the change event that is immediately fired after an add event. + // (This happens on Linux). + return; + } + + clearTimeout(this.changeTimers[key]); + this.changeTimers[key] = setTimeout(() => { + delete this.changeTimers[key]; + + if (type === ADD_EVENT && stat.isDirectory()) { + // Recursively emit add events and watch for sub-files/folders + common.recReaddir( + path.resolve(this.root, file), + function emitAddDir(dir, stats) { + this.watchdir(dir); + this.rawEmitEvent(ADD_EVENT, path.relative(this.root, dir), stats); + }.bind(this), + function emitAddFile(file, stats) { + this.register(file); + this.rawEmitEvent(ADD_EVENT, path.relative(this.root, file), stats); + }.bind(this), + function endCallback() {}, + this.checkedEmitError, + this.ignored + ); + } else { + this.rawEmitEvent(type, file, stat); + } + }, DEFAULT_DELAY); + } + /** + * Actually emit the events + */ + + rawEmitEvent(type, file, stat) { + this.emit(type, file, this.root, stat); + this.emit(ALL_EVENT, type, file, this.root, stat); + } +}; +/** + * Determine if a given FS error can be ignored + * + * @private + */ + +function isIgnorableFileError(error) { + return ( + error.code === 'ENOENT' || // Workaround Windows node issue #4337. + (error.code === 'EPERM' && platform === 'win32') + ); +} |