UNPKG

@cocalc/project

Version:
75 lines (61 loc) 2.31 kB
######################################################################### # This file is part of CoCalc: Copyright © 2020 Sagemath, Inc. # License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details ######################################################################### ### Watch a file for changes Watch for changes to the given file. Returns obj, which is an event emitter with events: - 'change', ctime - when file changes or is created - 'delete' - when file is deleted and a method .close(). The ctime might be undefined, in case it can't be determined. If debounce is given, only fires after the file definitely has not had its ctime changed for at least debounce ms. Does NOT fire when the file first has ctime changed. ### fs = require('fs') {EventEmitter} = require('events') class exports.Watcher extends EventEmitter constructor: (path, interval, debounce) -> super() @path = path @interval = interval @debounce = debounce fs.watchFile(@path, {interval: @interval, persistent:false}, @_listen) close: () => @removeAllListeners() fs.unwatchFile(@path, @listener) _listen: (curr, prev) => if curr.dev == 0 @emit('delete') return if @debounce @_emit_when_stable(true) else fs.stat @path, (err, stats) => if not err @emit('change', stats.ctime) _emit_when_stable: (first) => ### @_emit_when_stable gets called periodically until the last ctime of the file is at least @debounce ms in the past, or there is an error. ### if first and @_waiting_for_stable return @_waiting_for_stable = true fs.stat @path, (err, stats) => if err # maybe file deleted; give up. delete @_waiting_for_stable return elapsed = new Date() - stats.ctime if elapsed < @debounce # File keeps changing - try again soon setTimeout((=>@_emit_when_stable(false)), Math.max(500, @debounce - elapsed + 100)) else delete @_waiting_for_stable @emit('change', stats.ctime)