UNPKG

2.09 kBJavaScriptView Raw
1const { isAbsolute, join } = require('path')
2const execTask = require('./util/exec-task')
3const chokidar = require('chokidar')
4const bs = require('stamp')
5const fs = require('fs')
6const watching = {}
7var watcher
8
9const onchange = file => {
10 const listeners = watching[file]
11 const stamp = bs.create()
12 let i = listeners.length
13 while (i--) execTask(listeners[i], stamp)
14}
15
16const listen = (file, task) => fs.stat(file, (err, status) => {
17 if (err) return
18 if (status.isDirectory()) {
19 fs.readdir(file, (err, files) => {
20 if (err) return
21 let i = files.length
22 while (i--) listen(join(file, files[i]), task)
23 })
24 } else {
25 fs.realpath(file, (err, file) => {
26 if (err) return
27 const listeners = watching[file] || (watching[file] = [])
28 if (listeners.indexOf(task) === -1) {
29 listeners.push(task)
30 if (watcher) {
31 watcher.add(file)
32 } else {
33 watcher = chokidar.watch(file, {
34 ignoreInitial: true
35 }).on('change', onchange)
36 }
37 }
38 })
39 }
40})
41
42const unlisten = (file, task) => fs.stat(file, (err, status) => {
43 if (err) return
44 if (status.isDirectory()) {
45 fs.readdir(file, (err, files) => {
46 if (err) return
47 let i = files.length
48 while (i--) unlisten(join(file, files[i]), task)
49 })
50 } else {
51 fs.realpath(file, (err, file) => {
52 if (err) return
53 const listeners = watching[file]
54 if (listeners && task.entry !== file) {
55 listeners.splice(listeners.indexOf(task), 1)
56 if (!listeners.length) {
57 watcher.unwatch(file)
58 delete watching[file]
59 }
60 }
61 })
62 }
63})
64
65exports.props = {
66 watch: {
67 props: {
68 default: {
69 on: (val, stamp, file) => {
70 const task = file.parent().parent()
71 const cwd = task.root().cwd
72 if (!isAbsolute(file = file.compute())) {
73 file = join(cwd, file)
74 }
75 if (val) {
76 listen(file, task)
77 } else {
78 unlisten(file, task)
79 }
80 }
81 }
82 }
83 }
84}