fsWatcher.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. var fs = require('fs'),
  2. path = require('path'),
  3. FSWatcher = {};
  4. /**
  5. * Takes a directory/file and watch for change. Upon change, call the
  6. * callback.
  7. *
  8. * @param {String} name: name of this watcher
  9. * @param {String} directory: path to the directory to watch
  10. * @param {String} [filename]: (optional) specific filename to watch for,
  11. * watches for all files in the directory if unspecified
  12. * @param {Integer} cooldownDelay: delay to wait before triggering the callback
  13. * @param {Function} callback: function () : called when changes are detected
  14. **/
  15. function makeFsWatchFilter(name, directory, filename, cooldownDelay, callback) {
  16. var cooldownId = null;
  17. //Delete the cooldownId and callback the outer function
  18. function timeoutCallback() {
  19. cooldownId = null;
  20. callback();
  21. }
  22. //This function is called when there is a change in the data directory
  23. //It sets a timer to wait for the change to be completed
  24. function onWatchEvent(event, changedFile) {
  25. var filePath = path.join(directory, changedFile);
  26. if (!filename || filename === changedFile) {
  27. fs.exists(filePath, function onExists(exists) {
  28. if (!exists) {
  29. // if the changed file no longer exists, it was a deletion.
  30. // we ignore deleted files
  31. return;
  32. }
  33. //At this point, a new file system activity has been detected,
  34. //We have to wait for file transfert to be finished before moving on.
  35. //If a cooldownId already exists, we delete it
  36. if (cooldownId !== null) {
  37. clearTimeout(cooldownId);
  38. cooldownId = null;
  39. }
  40. //Once the cooldownDelay has passed, the timeoutCallback function will be called
  41. cooldownId = setTimeout(timeoutCallback, cooldownDelay);
  42. });
  43. }
  44. }
  45. //Manage the case where filename is missing (because it's optionnal)
  46. if (typeof cooldownDelay === 'function') {
  47. callback = cooldownDelay;
  48. cooldownDelay = filename;
  49. filename = null;
  50. }
  51. if (FSWatcher[name]) {
  52. stopWatching(name);
  53. }
  54. FSWatcher[name] = fs.watch(directory, onWatchEvent);
  55. }
  56. /**
  57. * Take a FSWatcher object and close it.
  58. *
  59. * @param {string} name: name of the watcher to close
  60. *
  61. **/
  62. function stopWatching(name) {
  63. FSWatcher[name].close();
  64. }
  65. module.exports.makeFsWatchFilter = makeFsWatchFilter;
  66. module.exports.stopWatching = stopWatching;