589 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			589 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | 
 | ||
|  | function _path() { | ||
|  |   const data = _interopRequireDefault(require('path')); | ||
|  | 
 | ||
|  |   _path = function _path() { | ||
|  |     return data; | ||
|  |   }; | ||
|  | 
 | ||
|  |   return data; | ||
|  | } | ||
|  | 
 | ||
|  | function _fbWatchman() { | ||
|  |   const data = _interopRequireDefault(require('fb-watchman')); | ||
|  | 
 | ||
|  |   _fbWatchman = function _fbWatchman() { | ||
|  |     return data; | ||
|  |   }; | ||
|  | 
 | ||
|  |   return data; | ||
|  | } | ||
|  | 
 | ||
|  | var fastPath = _interopRequireWildcard(require('../lib/fast_path')); | ||
|  | 
 | ||
|  | var _normalizePathSep = _interopRequireDefault( | ||
|  |   require('../lib/normalizePathSep') | ||
|  | ); | ||
|  | 
 | ||
|  | var _constants = _interopRequireDefault(require('../constants')); | ||
|  | 
 | ||
|  | function _interopRequireWildcard(obj) { | ||
|  |   if (obj && obj.__esModule) { | ||
|  |     return obj; | ||
|  |   } else { | ||
|  |     var newObj = {}; | ||
|  |     if (obj != null) { | ||
|  |       for (var key in obj) { | ||
|  |         if (Object.prototype.hasOwnProperty.call(obj, key)) { | ||
|  |           var desc = | ||
|  |             Object.defineProperty && Object.getOwnPropertyDescriptor | ||
|  |               ? Object.getOwnPropertyDescriptor(obj, key) | ||
|  |               : {}; | ||
|  |           if (desc.get || desc.set) { | ||
|  |             Object.defineProperty(newObj, key, desc); | ||
|  |           } else { | ||
|  |             newObj[key] = obj[key]; | ||
|  |           } | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  |     newObj.default = obj; | ||
|  |     return newObj; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function _interopRequireDefault(obj) { | ||
|  |   return obj && obj.__esModule ? obj : {default: obj}; | ||
|  | } | ||
|  | 
 | ||
|  | function _slicedToArray(arr, i) { | ||
|  |   return ( | ||
|  |     _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest() | ||
|  |   ); | ||
|  | } | ||
|  | 
 | ||
|  | function _nonIterableRest() { | ||
|  |   throw new TypeError('Invalid attempt to destructure non-iterable instance'); | ||
|  | } | ||
|  | 
 | ||
|  | function _iterableToArrayLimit(arr, i) { | ||
|  |   var _arr = []; | ||
|  |   var _n = true; | ||
|  |   var _d = false; | ||
|  |   var _e = undefined; | ||
|  |   try { | ||
|  |     for ( | ||
|  |       var _i = arr[Symbol.iterator](), _s; | ||
|  |       !(_n = (_s = _i.next()).done); | ||
|  |       _n = true | ||
|  |     ) { | ||
|  |       _arr.push(_s.value); | ||
|  |       if (i && _arr.length === i) break; | ||
|  |     } | ||
|  |   } catch (err) { | ||
|  |     _d = true; | ||
|  |     _e = err; | ||
|  |   } finally { | ||
|  |     try { | ||
|  |       if (!_n && _i['return'] != null) _i['return'](); | ||
|  |     } finally { | ||
|  |       if (_d) throw _e; | ||
|  |     } | ||
|  |   } | ||
|  |   return _arr; | ||
|  | } | ||
|  | 
 | ||
|  | function _arrayWithHoles(arr) { | ||
|  |   if (Array.isArray(arr)) return arr; | ||
|  | } | ||
|  | 
 | ||
|  | function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { | ||
|  |   try { | ||
|  |     var info = gen[key](arg); | ||
|  |     var value = info.value; | ||
|  |   } catch (error) { | ||
|  |     reject(error); | ||
|  |     return; | ||
|  |   } | ||
|  |   if (info.done) { | ||
|  |     resolve(value); | ||
|  |   } else { | ||
|  |     Promise.resolve(value).then(_next, _throw); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function _asyncToGenerator(fn) { | ||
|  |   return function() { | ||
|  |     var self = this, | ||
|  |       args = arguments; | ||
|  |     return new Promise(function(resolve, reject) { | ||
|  |       var gen = fn.apply(self, args); | ||
|  |       function _next(value) { | ||
|  |         asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value); | ||
|  |       } | ||
|  |       function _throw(err) { | ||
|  |         asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err); | ||
|  |       } | ||
|  |       _next(undefined); | ||
|  |     }); | ||
|  |   }; | ||
|  | } | ||
|  | 
 | ||
|  | const watchmanURL = | ||
|  |   'https://facebook.github.io/watchman/docs/troubleshooting.html'; | ||
|  | 
 | ||
|  | function WatchmanError(error) { | ||
|  |   error.message = | ||
|  |     `Watchman error: ${error.message.trim()}. Make sure watchman ` + | ||
|  |     `is running for this project. See ${watchmanURL}.`; | ||
|  |   return error; | ||
|  | } | ||
|  | 
 | ||
|  | module.exports = | ||
|  |   /*#__PURE__*/ | ||
|  |   (function() { | ||
|  |     var _watchmanCrawl = _asyncToGenerator(function*(options) { | ||
|  |       const fields = ['name', 'exists', 'mtime_ms', 'size']; | ||
|  |       const data = options.data, | ||
|  |         extensions = options.extensions, | ||
|  |         ignore = options.ignore, | ||
|  |         rootDir = options.rootDir, | ||
|  |         roots = options.roots; | ||
|  |       const defaultWatchExpression = [ | ||
|  |         'allof', | ||
|  |         ['type', 'f'], | ||
|  |         ['anyof', ...extensions.map(extension => ['suffix', extension])] | ||
|  |       ]; | ||
|  |       const clocks = data.clocks; | ||
|  |       const client = new (_fbWatchman()).default.Client(); | ||
|  |       let clientError; | ||
|  |       client.on('error', error => (clientError = WatchmanError(error))); // TODO: type better than `any`
 | ||
|  | 
 | ||
|  |       const cmd = (...args) => | ||
|  |         new Promise((resolve, reject) => | ||
|  |           client.command(args, (error, result) => | ||
|  |             error ? reject(WatchmanError(error)) : resolve(result) | ||
|  |           ) | ||
|  |         ); | ||
|  | 
 | ||
|  |       if (options.computeSha1) { | ||
|  |         const _ref = yield cmd('list-capabilities'), | ||
|  |           capabilities = _ref.capabilities; | ||
|  | 
 | ||
|  |         if (capabilities.indexOf('field-content.sha1hex') !== -1) { | ||
|  |           fields.push('content.sha1hex'); | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |       function getWatchmanRoots(_x2) { | ||
|  |         return _getWatchmanRoots.apply(this, arguments); | ||
|  |       } | ||
|  | 
 | ||
|  |       function _getWatchmanRoots() { | ||
|  |         _getWatchmanRoots = _asyncToGenerator(function*(roots) { | ||
|  |           const watchmanRoots = new Map(); | ||
|  |           yield Promise.all( | ||
|  |             roots.map( | ||
|  |               /*#__PURE__*/ | ||
|  |               (function() { | ||
|  |                 var _ref2 = _asyncToGenerator(function*(root) { | ||
|  |                   const response = yield cmd('watch-project', root); | ||
|  |                   const existing = watchmanRoots.get(response.watch); // A root can only be filtered if it was never seen with a
 | ||
|  |                   // relative_path before.
 | ||
|  | 
 | ||
|  |                   const canBeFiltered = !existing || existing.length > 0; | ||
|  | 
 | ||
|  |                   if (canBeFiltered) { | ||
|  |                     if (response.relative_path) { | ||
|  |                       watchmanRoots.set( | ||
|  |                         response.watch, | ||
|  |                         (existing || []).concat(response.relative_path) | ||
|  |                       ); | ||
|  |                     } else { | ||
|  |                       // Make the filter directories an empty array to signal that this
 | ||
|  |                       // root was already seen and needs to be watched for all files or
 | ||
|  |                       // directories.
 | ||
|  |                       watchmanRoots.set(response.watch, []); | ||
|  |                     } | ||
|  |                   } | ||
|  |                 }); | ||
|  | 
 | ||
|  |                 return function(_x4) { | ||
|  |                   return _ref2.apply(this, arguments); | ||
|  |                 }; | ||
|  |               })() | ||
|  |             ) | ||
|  |           ); | ||
|  |           return watchmanRoots; | ||
|  |         }); | ||
|  |         return _getWatchmanRoots.apply(this, arguments); | ||
|  |       } | ||
|  | 
 | ||
|  |       function queryWatchmanForDirs(_x3) { | ||
|  |         return _queryWatchmanForDirs.apply(this, arguments); | ||
|  |       } | ||
|  | 
 | ||
|  |       function _queryWatchmanForDirs() { | ||
|  |         _queryWatchmanForDirs = _asyncToGenerator(function*( | ||
|  |           rootProjectDirMappings | ||
|  |         ) { | ||
|  |           const files = new Map(); | ||
|  |           let isFresh = false; | ||
|  |           yield Promise.all( | ||
|  |             Array.from(rootProjectDirMappings).map( | ||
|  |               /*#__PURE__*/ | ||
|  |               (function() { | ||
|  |                 var _ref3 = _asyncToGenerator(function*([ | ||
|  |                   root, | ||
|  |                   directoryFilters | ||
|  |                 ]) { | ||
|  |                   const expression = Array.from(defaultWatchExpression); | ||
|  |                   const glob = []; | ||
|  | 
 | ||
|  |                   if (directoryFilters.length > 0) { | ||
|  |                     expression.push([ | ||
|  |                       'anyof', | ||
|  |                       ...directoryFilters.map(dir => ['dirname', dir]) | ||
|  |                     ]); | ||
|  |                     var _iteratorNormalCompletion2 = true; | ||
|  |                     var _didIteratorError2 = false; | ||
|  |                     var _iteratorError2 = undefined; | ||
|  | 
 | ||
|  |                     try { | ||
|  |                       for ( | ||
|  |                         var _iterator2 = directoryFilters[Symbol.iterator](), | ||
|  |                           _step2; | ||
|  |                         !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()) | ||
|  |                           .done); | ||
|  |                         _iteratorNormalCompletion2 = true | ||
|  |                       ) { | ||
|  |                         const directory = _step2.value; | ||
|  |                         var _iteratorNormalCompletion3 = true; | ||
|  |                         var _didIteratorError3 = false; | ||
|  |                         var _iteratorError3 = undefined; | ||
|  | 
 | ||
|  |                         try { | ||
|  |                           for ( | ||
|  |                             var _iterator3 = extensions[Symbol.iterator](), | ||
|  |                               _step3; | ||
|  |                             !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()) | ||
|  |                               .done); | ||
|  |                             _iteratorNormalCompletion3 = true | ||
|  |                           ) { | ||
|  |                             const extension = _step3.value; | ||
|  |                             glob.push(`${directory}/**/*.${extension}`); | ||
|  |                           } | ||
|  |                         } catch (err) { | ||
|  |                           _didIteratorError3 = true; | ||
|  |                           _iteratorError3 = err; | ||
|  |                         } finally { | ||
|  |                           try { | ||
|  |                             if ( | ||
|  |                               !_iteratorNormalCompletion3 && | ||
|  |                               _iterator3.return != null | ||
|  |                             ) { | ||
|  |                               _iterator3.return(); | ||
|  |                             } | ||
|  |                           } finally { | ||
|  |                             if (_didIteratorError3) { | ||
|  |                               throw _iteratorError3; | ||
|  |                             } | ||
|  |                           } | ||
|  |                         } | ||
|  |                       } | ||
|  |                     } catch (err) { | ||
|  |                       _didIteratorError2 = true; | ||
|  |                       _iteratorError2 = err; | ||
|  |                     } finally { | ||
|  |                       try { | ||
|  |                         if ( | ||
|  |                           !_iteratorNormalCompletion2 && | ||
|  |                           _iterator2.return != null | ||
|  |                         ) { | ||
|  |                           _iterator2.return(); | ||
|  |                         } | ||
|  |                       } finally { | ||
|  |                         if (_didIteratorError2) { | ||
|  |                           throw _iteratorError2; | ||
|  |                         } | ||
|  |                       } | ||
|  |                     } | ||
|  |                   } else { | ||
|  |                     var _iteratorNormalCompletion4 = true; | ||
|  |                     var _didIteratorError4 = false; | ||
|  |                     var _iteratorError4 = undefined; | ||
|  | 
 | ||
|  |                     try { | ||
|  |                       for ( | ||
|  |                         var _iterator4 = extensions[Symbol.iterator](), _step4; | ||
|  |                         !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()) | ||
|  |                           .done); | ||
|  |                         _iteratorNormalCompletion4 = true | ||
|  |                       ) { | ||
|  |                         const extension = _step4.value; | ||
|  |                         glob.push(`**/*.${extension}`); | ||
|  |                       } | ||
|  |                     } catch (err) { | ||
|  |                       _didIteratorError4 = true; | ||
|  |                       _iteratorError4 = err; | ||
|  |                     } finally { | ||
|  |                       try { | ||
|  |                         if ( | ||
|  |                           !_iteratorNormalCompletion4 && | ||
|  |                           _iterator4.return != null | ||
|  |                         ) { | ||
|  |                           _iterator4.return(); | ||
|  |                         } | ||
|  |                       } finally { | ||
|  |                         if (_didIteratorError4) { | ||
|  |                           throw _iteratorError4; | ||
|  |                         } | ||
|  |                       } | ||
|  |                     } | ||
|  |                   } | ||
|  | 
 | ||
|  |                   const relativeRoot = fastPath.relative(rootDir, root); | ||
|  |                   const query = clocks.has(relativeRoot) // Use the `since` generator if we have a clock available
 | ||
|  |                     ? { | ||
|  |                         expression, | ||
|  |                         fields, | ||
|  |                         since: clocks.get(relativeRoot) | ||
|  |                       } // Otherwise use the `glob` filter
 | ||
|  |                     : { | ||
|  |                         expression, | ||
|  |                         fields, | ||
|  |                         glob | ||
|  |                       }; | ||
|  |                   const response = yield cmd('query', root, query); | ||
|  | 
 | ||
|  |                   if ('warning' in response) { | ||
|  |                     console.warn('watchman warning: ', response.warning); | ||
|  |                   } | ||
|  | 
 | ||
|  |                   isFresh = isFresh || response.is_fresh_instance; | ||
|  |                   files.set(root, response); | ||
|  |                 }); | ||
|  | 
 | ||
|  |                 return function(_x5) { | ||
|  |                   return _ref3.apply(this, arguments); | ||
|  |                 }; | ||
|  |               })() | ||
|  |             ) | ||
|  |           ); | ||
|  |           return { | ||
|  |             files, | ||
|  |             isFresh | ||
|  |           }; | ||
|  |         }); | ||
|  |         return _queryWatchmanForDirs.apply(this, arguments); | ||
|  |       } | ||
|  | 
 | ||
|  |       let files = data.files; | ||
|  |       let removedFiles = new Map(); | ||
|  |       const changedFiles = new Map(); | ||
|  |       let watchmanFiles; | ||
|  |       let isFresh = false; | ||
|  | 
 | ||
|  |       try { | ||
|  |         const watchmanRoots = yield getWatchmanRoots(roots); | ||
|  |         const watchmanFileResults = yield queryWatchmanForDirs(watchmanRoots); // Reset the file map if watchman was restarted and sends us a list of
 | ||
|  |         // files.
 | ||
|  | 
 | ||
|  |         if (watchmanFileResults.isFresh) { | ||
|  |           files = new Map(); | ||
|  |           removedFiles = new Map(data.files); | ||
|  |           isFresh = true; | ||
|  |         } | ||
|  | 
 | ||
|  |         watchmanFiles = watchmanFileResults.files; | ||
|  |       } finally { | ||
|  |         client.end(); | ||
|  |       } | ||
|  | 
 | ||
|  |       if (clientError) { | ||
|  |         throw clientError; | ||
|  |       } // TODO: remove non-null
 | ||
|  | 
 | ||
|  |       var _iteratorNormalCompletion = true; | ||
|  |       var _didIteratorError = false; | ||
|  |       var _iteratorError = undefined; | ||
|  | 
 | ||
|  |       try { | ||
|  |         for ( | ||
|  |           var _iterator = watchmanFiles[Symbol.iterator](), _step; | ||
|  |           !(_iteratorNormalCompletion = (_step = _iterator.next()).done); | ||
|  |           _iteratorNormalCompletion = true | ||
|  |         ) { | ||
|  |           const _step$value = _slicedToArray(_step.value, 2), | ||
|  |             watchRoot = _step$value[0], | ||
|  |             response = _step$value[1]; | ||
|  | 
 | ||
|  |           const fsRoot = (0, _normalizePathSep.default)(watchRoot); | ||
|  |           const relativeFsRoot = fastPath.relative(rootDir, fsRoot); | ||
|  |           clocks.set(relativeFsRoot, response.clock); | ||
|  |           var _iteratorNormalCompletion5 = true; | ||
|  |           var _didIteratorError5 = false; | ||
|  |           var _iteratorError5 = undefined; | ||
|  | 
 | ||
|  |           try { | ||
|  |             for ( | ||
|  |               var _iterator5 = response.files[Symbol.iterator](), _step5; | ||
|  |               !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); | ||
|  |               _iteratorNormalCompletion5 = true | ||
|  |             ) { | ||
|  |               const fileData = _step5.value; | ||
|  |               const filePath = | ||
|  |                 fsRoot + | ||
|  |                 _path().default.sep + | ||
|  |                 (0, _normalizePathSep.default)(fileData.name); | ||
|  |               const relativeFilePath = fastPath.relative(rootDir, filePath); | ||
|  |               const existingFileData = data.files.get(relativeFilePath); // If watchman is fresh, the removed files map starts with all files
 | ||
|  |               // and we remove them as we verify they still exist.
 | ||
|  | 
 | ||
|  |               if (isFresh && existingFileData && fileData.exists) { | ||
|  |                 removedFiles.delete(relativeFilePath); | ||
|  |               } | ||
|  | 
 | ||
|  |               if (!fileData.exists) { | ||
|  |                 // No need to act on files that do not exist and were not tracked.
 | ||
|  |                 if (existingFileData) { | ||
|  |                   files.delete(relativeFilePath); // If watchman is not fresh, we will know what specific files were
 | ||
|  |                   // deleted since we last ran and can track only those files.
 | ||
|  | 
 | ||
|  |                   if (!isFresh) { | ||
|  |                     removedFiles.set(relativeFilePath, existingFileData); | ||
|  |                   } | ||
|  |                 } | ||
|  |               } else if (!ignore(filePath)) { | ||
|  |                 const mtime = | ||
|  |                   typeof fileData.mtime_ms === 'number' | ||
|  |                     ? fileData.mtime_ms | ||
|  |                     : fileData.mtime_ms.toNumber(); | ||
|  |                 const size = fileData.size; | ||
|  |                 let sha1hex = fileData['content.sha1hex']; | ||
|  | 
 | ||
|  |                 if (typeof sha1hex !== 'string' || sha1hex.length !== 40) { | ||
|  |                   sha1hex = null; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 let nextData; | ||
|  | 
 | ||
|  |                 if ( | ||
|  |                   existingFileData && | ||
|  |                   existingFileData[_constants.default.MTIME] === mtime | ||
|  |                 ) { | ||
|  |                   nextData = existingFileData; | ||
|  |                 } else if ( | ||
|  |                   existingFileData && | ||
|  |                   sha1hex && | ||
|  |                   existingFileData[_constants.default.SHA1] === sha1hex | ||
|  |                 ) { | ||
|  |                   nextData = [ | ||
|  |                     existingFileData[0], | ||
|  |                     mtime, | ||
|  |                     existingFileData[2], | ||
|  |                     existingFileData[3], | ||
|  |                     existingFileData[4], | ||
|  |                     existingFileData[5] | ||
|  |                   ]; | ||
|  |                 } else { | ||
|  |                   // See ../constants.ts
 | ||
|  |                   nextData = ['', mtime, size, 0, '', sha1hex]; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 const mappings = options.mapper | ||
|  |                   ? options.mapper(filePath) | ||
|  |                   : null; | ||
|  | 
 | ||
|  |                 if (mappings) { | ||
|  |                   var _iteratorNormalCompletion6 = true; | ||
|  |                   var _didIteratorError6 = false; | ||
|  |                   var _iteratorError6 = undefined; | ||
|  | 
 | ||
|  |                   try { | ||
|  |                     for ( | ||
|  |                       var _iterator6 = mappings[Symbol.iterator](), _step6; | ||
|  |                       !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()) | ||
|  |                         .done); | ||
|  |                       _iteratorNormalCompletion6 = true | ||
|  |                     ) { | ||
|  |                       const absoluteVirtualFilePath = _step6.value; | ||
|  | 
 | ||
|  |                       if (!ignore(absoluteVirtualFilePath)) { | ||
|  |                         const relativeVirtualFilePath = fastPath.relative( | ||
|  |                           rootDir, | ||
|  |                           absoluteVirtualFilePath | ||
|  |                         ); | ||
|  |                         files.set(relativeVirtualFilePath, nextData); | ||
|  |                         changedFiles.set(relativeVirtualFilePath, nextData); | ||
|  |                       } | ||
|  |                     } | ||
|  |                   } catch (err) { | ||
|  |                     _didIteratorError6 = true; | ||
|  |                     _iteratorError6 = err; | ||
|  |                   } finally { | ||
|  |                     try { | ||
|  |                       if ( | ||
|  |                         !_iteratorNormalCompletion6 && | ||
|  |                         _iterator6.return != null | ||
|  |                       ) { | ||
|  |                         _iterator6.return(); | ||
|  |                       } | ||
|  |                     } finally { | ||
|  |                       if (_didIteratorError6) { | ||
|  |                         throw _iteratorError6; | ||
|  |                       } | ||
|  |                     } | ||
|  |                   } | ||
|  |                 } else { | ||
|  |                   files.set(relativeFilePath, nextData); | ||
|  |                   changedFiles.set(relativeFilePath, nextData); | ||
|  |                 } | ||
|  |               } | ||
|  |             } | ||
|  |           } catch (err) { | ||
|  |             _didIteratorError5 = true; | ||
|  |             _iteratorError5 = err; | ||
|  |           } finally { | ||
|  |             try { | ||
|  |               if (!_iteratorNormalCompletion5 && _iterator5.return != null) { | ||
|  |                 _iterator5.return(); | ||
|  |               } | ||
|  |             } finally { | ||
|  |               if (_didIteratorError5) { | ||
|  |                 throw _iteratorError5; | ||
|  |               } | ||
|  |             } | ||
|  |           } | ||
|  |         } | ||
|  |       } catch (err) { | ||
|  |         _didIteratorError = true; | ||
|  |         _iteratorError = err; | ||
|  |       } finally { | ||
|  |         try { | ||
|  |           if (!_iteratorNormalCompletion && _iterator.return != null) { | ||
|  |             _iterator.return(); | ||
|  |           } | ||
|  |         } finally { | ||
|  |           if (_didIteratorError) { | ||
|  |             throw _iteratorError; | ||
|  |           } | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |       data.files = files; | ||
|  |       return { | ||
|  |         changedFiles: isFresh ? undefined : changedFiles, | ||
|  |         hasteMap: data, | ||
|  |         removedFiles | ||
|  |       }; | ||
|  |     }); | ||
|  | 
 | ||
|  |     function watchmanCrawl(_x) { | ||
|  |       return _watchmanCrawl.apply(this, arguments); | ||
|  |     } | ||
|  | 
 | ||
|  |     return watchmanCrawl; | ||
|  |   })(); |