1 | return if global.window
|
2 |
|
3 | fs = require 'fs'
|
4 | np = require 'path'
|
5 | util = require './utility'
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | exports.watchDirectory = (dirname, options, listener) ->
|
12 | if not listener?
|
13 | listener = options
|
14 | options = {}
|
15 | options.persistent ?= true
|
16 | options.interval ?= 100
|
17 | options.recursive ?= true
|
18 |
|
19 | options.initial ?= 'initial'
|
20 | options.exclude ?= util.defaultFileExclude
|
21 |
|
22 | filter = (name) ->
|
23 | if util.isMatch name, options.exclude, false
|
24 | false
|
25 | else
|
26 | util.isMatch name, options.include, true
|
27 |
|
28 | watchedFiles = {}
|
29 |
|
30 | notifyListener = (filename, curr, prev, change, async=false) ->
|
31 | if filter filename
|
32 | if async
|
33 | process.nextTick -> listener filename, curr, prev, change
|
34 | else
|
35 | listener filename, curr, prev, change
|
36 |
|
37 | fsListener = (filename, depth, curr, prev) ->
|
38 | change =
|
39 | if curr.nlink is 0
|
40 | 'deleted'
|
41 | else if prev.nlink is 0
|
42 | 'created'
|
43 | else
|
44 | 'modified'
|
45 | notifyListener filename, curr, prev, change
|
46 |
|
47 | if change isnt 'deleted'
|
48 | watchFile filename, depth, curr
|
49 | else
|
50 | unwatchFile filename
|
51 |
|
52 | unwatchFile = (filename) ->
|
53 | fs.unwatchFile filename, watchedFiles[filename]
|
54 | delete watchedFiles[filename]
|
55 | allWatchers[filename]--
|
56 |
|
57 | watchFile = (filename, depth=0, stats) ->
|
58 | if fs.existsSync filename
|
59 | stats ?= fs.statSync filename
|
60 | if stats.nlink > 0
|
61 | if stats.isDirectory()
|
62 |
|
63 |
|
64 | if not util.isMatch filename, options.exclude, false
|
65 | if depth is 0 or options.recursive
|
66 | for child in fs.readdirSync filename
|
67 | child = np.join filename, child
|
68 | watchFile child, depth + 1
|
69 |
|
70 | if not watchedFiles[filename]?
|
71 | allWatchers[filename] ?= 0
|
72 | allWatchers[filename]++
|
73 |
|
74 | boundListener = fsListener.bind @, filename, depth
|
75 | watchedFiles[filename] = boundListener
|
76 | fs.watchFile filename, options, boundListener
|
77 | if initial
|
78 | notifyListener filename, stats, stats, initial, true
|
79 | return
|
80 |
|
81 | initial = options.initial
|
82 | watchFile dirname
|
83 | initial = 'created'
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 | ->
|
92 | for key of watchedFiles
|
93 | unwatchFile key
|
94 |
|
95 | allWatchers = {}
|
96 |
|