CoolFace
Apppublic

opusdev/vector-similarity-api

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes
watch.js245 linesDownload Raw Back to monitor
1module.exports.watch = watch;2module.exports.resetWatchers = resetWatchers;3 4var debug = require('debug')('nodemon:watch');5var debugRoot = require('debug')('nodemon');6var chokidar = require('chokidar');7var undefsafe = require('undefsafe');8var config = require('../config');9var path = require('path');10var utils = require('../utils');11var bus = utils.bus;12var match = require('./match');13var watchers = [];14var debouncedBus;15 16bus.on('reset', resetWatchers);17 18function resetWatchers() {19  debugRoot('resetting watchers');20  watchers.forEach(function (watcher) {21    watcher.close();22  });23  watchers = [];24}25 26function watch() {27  if (watchers.length) {28    debug('early exit on watch, still watching (%s)', watchers.length);29    return;30  }31 32  var dirs = [].slice.call(config.dirs);33 34  debugRoot('start watch on: %s', dirs.join(', '));35  const rootIgnored = config.options.ignore;36  debugRoot('ignored', rootIgnored);37 38  var watchedFiles = [];39 40  const promise = new Promise(function (resolve) {41    const dotFilePattern = /[/\\]\./;42    var ignored = match.rulesToMonitor(43      [], // not needed44      Array.from(rootIgnored),45      config46    ).map(pattern => pattern.slice(1));47 48    const addDotFile = dirs.filter(dir => dir.match(dotFilePattern));49 50    // don't ignore dotfiles if explicitly watched.51    if (addDotFile.length === 0) {52      ignored.push(dotFilePattern);53    }54 55    var watchOptions = {56      ignorePermissionErrors: true,57      ignored: ignored,58      persistent: true,59      usePolling: config.options.legacyWatch || false,60      interval: config.options.pollingInterval,61      // note to future developer: I've gone back and forth on adding `cwd`62      // to the props and in some cases it fixes bugs but typically it causes63      // bugs elsewhere (since nodemon is used is so many ways). the final64      // decision is to *not* use it at all and work around it65      // cwd: ...66    };67 68    if (utils.isWindows) {69      watchOptions.disableGlobbing = true;70    }71 72    if (utils.isIBMi) {73      watchOptions.usePolling = true;74    }75 76    if (process.env.TEST) {77      watchOptions.useFsEvents = false;78    }79 80    var watcher = chokidar.watch(81      dirs,82      Object.assign({}, watchOptions, config.options.watchOptions || {})83    );84 85    watcher.ready = false;86 87    var total = 0;88 89    watcher.on('change', filterAndRestart);90    watcher.on('unlink', filterAndRestart);91    watcher.on('add', function (file) {92      if (watcher.ready) {93        return filterAndRestart(file);94      }95 96      watchedFiles.push(file);97      bus.emit('watching', file);98      debug('chokidar watching: %s', file);99    });100    watcher.on('ready', function () {101      watchedFiles = Array.from(new Set(watchedFiles)); // ensure no dupes102      total = watchedFiles.length;103      watcher.ready = true;104      resolve(total);105      debugRoot('watch is complete');106    });107 108    watcher.on('error', function (error) {109      if (error.code === 'EINVAL') {110        utils.log.error(111          'Internal watch failed. Likely cause: too many ' +112          'files being watched (perhaps from the root of a drive?\n' +113          'See https://github.com/paulmillr/chokidar/issues/229 for details'114        );115      } else {116        utils.log.error('Internal watch failed: ' + error.message);117        process.exit(1);118      }119    });120 121    watchers.push(watcher);122  });123 124  return promise.catch(e => {125    // this is a core error and it should break nodemon - so I have to break126    // out of a promise using the setTimeout127    setTimeout(() => {128      throw e;129    });130  }).then(function () {131    utils.log.detail(`watching ${watchedFiles.length} file${132      watchedFiles.length === 1 ? '' : 's'}`);133    return watchedFiles;134  });135}136 137function filterAndRestart(files) {138  if (!Array.isArray(files)) {139    files = [files];140  }141 142  if (files.length) {143    var cwd = process.cwd();144    if (this.options && this.options.cwd) {145      cwd = this.options.cwd;146    }147 148    utils.log.detail(149      'files triggering change check: ' +150      files151        .map(file => {152          const res = path.relative(cwd, file);153          return res;154        })155        .join(', ')156    );157 158    // make sure the path is right and drop an empty159    // filenames (sometimes on windows)160    files = files.filter(Boolean).map(file => {161      return path.relative(process.cwd(), path.relative(cwd, file));162    });163 164    if (utils.isWindows) {165      // ensure the drive letter is in uppercase (c:\foo -> C:\foo)166      files = files.map(f => {167        if (f.indexOf(':') === -1) { return f; }168        return f[0].toUpperCase() + f.slice(1);169      });170    }171 172 173    debug('filterAndRestart on', files);174 175    var matched = match(176      files,177      config.options.monitor,178      undefsafe(config, 'options.execOptions.ext')179    );180 181    debug('matched?', JSON.stringify(matched));182 183    // if there's no matches, then test to see if the changed file is the184    // running script, if so, let's allow a restart185    if (config.options.execOptions && config.options.execOptions.script) {186      const script = path.resolve(config.options.execOptions.script);187      if (matched.result.length === 0 && script) {188        const length = script.length;189        files.find(file => {190          if (file.substr(-length, length) === script) {191            matched = {192              result: [file],193              total: 1,194            };195            return true;196          }197        });198      }199    }200 201    utils.log.detail(202      'changes after filters (before/after): ' +203      [files.length, matched.result.length].join('/')204    );205 206    // reset the last check so we're only looking at recently modified files207    config.lastStarted = Date.now();208 209    if (matched.result.length) {210      if (config.options.delay > 0) {211        utils.log.detail('delaying restart for ' + config.options.delay + 'ms');212        if (debouncedBus === undefined) {213          debouncedBus = debounce(restartBus, config.options.delay);214        }215        debouncedBus(matched);216      } else {217        return restartBus(matched);218      }219    }220  }221}222 223function restartBus(matched) {224  utils.log.status('restarting due to changes...');225  matched.result.map(file => {226    utils.log.detail(path.relative(process.cwd(), file));227  });228 229  if (config.options.verbose) {230    utils.log._log('');231  }232 233  bus.emit('restart', matched.result);234}235 236function debounce(fn, delay) {237  var timer = null;238  return function () {239    const context = this;240    const args = arguments;241    clearTimeout(timer);242    timer = setTimeout(() =>fn.apply(context, args), delay);243  };244}245