webpack 1.13.3 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +310 -310
  3. package/buildin/amd-define.js +1 -1
  4. package/buildin/amd-options.js +1 -1
  5. package/buildin/module.js +10 -10
  6. package/hot/dev-server.js +63 -63
  7. package/hot/log-apply-result.js +25 -25
  8. package/hot/only-dev-server.js +77 -77
  9. package/hot/poll.js +37 -37
  10. package/hot/signal.js +65 -65
  11. package/lib/APIPlugin.js +49 -49
  12. package/lib/AbstractPlugin.js +22 -22
  13. package/lib/AmdMainTemplatePlugin.js +43 -43
  14. package/lib/ArrayMap.js +50 -50
  15. package/lib/AsyncDependenciesBlock.js +39 -39
  16. package/lib/AutomaticPrefetchPlugin.js +35 -35
  17. package/lib/BannerPlugin.js +34 -34
  18. package/lib/BasicEvaluatedExpression.js +140 -140
  19. package/lib/CachePlugin.js +43 -43
  20. package/lib/CaseSensitiveModulesWarning.js +16 -16
  21. package/lib/Chunk.js +252 -252
  22. package/lib/ChunkRenderError.js +17 -17
  23. package/lib/ChunkTemplate.js +37 -37
  24. package/lib/CompatibilityPlugin.js +42 -42
  25. package/lib/Compilation.js +891 -891
  26. package/lib/Compiler.js +407 -407
  27. package/lib/ConcatSource.js +5 -5
  28. package/lib/ConstPlugin.js +54 -54
  29. package/lib/ContextModule.js +130 -130
  30. package/lib/ContextModuleFactory.js +132 -132
  31. package/lib/ContextReplacementPlugin.js +93 -93
  32. package/lib/CriticalDependenciesWarning.js +24 -24
  33. package/lib/DefinePlugin.js +126 -126
  34. package/lib/DelegatedModule.js +69 -69
  35. package/lib/DelegatedModuleFactoryPlugin.js +51 -51
  36. package/lib/DelegatedPlugin.js +21 -21
  37. package/lib/DependenciesBlock.js +57 -57
  38. package/lib/DependenciesBlockVariable.js +41 -41
  39. package/lib/Dependency.js +54 -54
  40. package/lib/DllEntryPlugin.js +32 -32
  41. package/lib/DllModule.js +55 -55
  42. package/lib/DllModuleFactory.js +18 -18
  43. package/lib/DllPlugin.js +30 -30
  44. package/lib/DllReferencePlugin.js +26 -26
  45. package/lib/EntryModuleNotFoundError.js +15 -15
  46. package/lib/EntryOptionPlugin.js +28 -28
  47. package/lib/EnvironmentPlugin.js +28 -28
  48. package/lib/EvalDevToolModulePlugin.js +17 -17
  49. package/lib/EvalDevToolModuleTemplatePlugin.js +29 -29
  50. package/lib/EvalSourceMapDevToolModuleTemplatePlugin.js +68 -68
  51. package/lib/EvalSourceMapDevToolPlugin.js +25 -25
  52. package/lib/ExtendedAPIPlugin.js +45 -45
  53. package/lib/ExternalModule.js +89 -89
  54. package/lib/ExternalModuleFactoryPlugin.js +86 -86
  55. package/lib/ExternalsPlugin.js +16 -16
  56. package/lib/FunctionModulePlugin.js +18 -18
  57. package/lib/FunctionModuleTemplatePlugin.js +39 -39
  58. package/lib/HotModuleReplacement.runtime.js +486 -486
  59. package/lib/HotModuleReplacementPlugin.js +223 -223
  60. package/lib/HotUpdateChunkTemplate.js +28 -28
  61. package/lib/IgnorePlugin.js +32 -32
  62. package/lib/JsonpChunkTemplatePlugin.js +26 -26
  63. package/lib/JsonpExportMainTemplatePlugin.js +28 -28
  64. package/lib/JsonpHotUpdateChunkTemplatePlugin.js +26 -26
  65. package/lib/JsonpMainTemplate.runtime.js +56 -56
  66. package/lib/JsonpMainTemplatePlugin.js +162 -162
  67. package/lib/JsonpTemplatePlugin.js +17 -17
  68. package/lib/LibManifestPlugin.js +49 -49
  69. package/lib/LibraryTemplatePlugin.js +77 -77
  70. package/lib/LoaderTargetPlugin.js +16 -16
  71. package/lib/MainTemplate.js +169 -169
  72. package/lib/MemoryOutputFileSystem.js +5 -5
  73. package/lib/Module.js +116 -116
  74. package/lib/ModuleFilenameHelpers.js +157 -157
  75. package/lib/ModuleNotFoundError.js +17 -17
  76. package/lib/ModuleParseError.js +26 -26
  77. package/lib/ModuleParserHelpers.js +21 -21
  78. package/lib/ModuleReason.js +9 -9
  79. package/lib/ModuleTemplate.js +23 -23
  80. package/lib/MovedToPluginWarningPlugin.js +17 -17
  81. package/lib/MultiCompiler.js +166 -166
  82. package/lib/MultiEntryPlugin.js +31 -31
  83. package/lib/MultiModule.js +71 -71
  84. package/lib/MultiModuleFactory.js +18 -18
  85. package/lib/NamedModulesPlugin.js +21 -21
  86. package/lib/NewWatchingPlugin.js +12 -12
  87. package/lib/NoErrorsPlugin.js +18 -18
  88. package/lib/NodeStuffPlugin.js +99 -99
  89. package/lib/NormalModule.js +322 -322
  90. package/lib/NormalModuleFactory.js +171 -171
  91. package/lib/NormalModuleReplacementPlugin.js +40 -40
  92. package/lib/NullFactory.js +10 -10
  93. package/lib/OldWatchingPlugin.js +14 -14
  94. package/lib/OptionsApply.js +10 -10
  95. package/lib/OriginalSource.js +5 -5
  96. package/lib/Parser.js +938 -938
  97. package/lib/PrefetchPlugin.js +25 -25
  98. package/lib/ProgressPlugin.js +80 -80
  99. package/lib/ProvidePlugin.js +48 -48
  100. package/lib/RawModule.js +65 -65
  101. package/lib/RawSource.js +5 -5
  102. package/lib/RecordIdsPlugin.js +130 -130
  103. package/lib/RequestShortener.js +56 -56
  104. package/lib/RequireJsStuffPlugin.js +38 -38
  105. package/lib/ResolverPlugin.js +34 -34
  106. package/lib/SetVarMainTemplatePlugin.js +36 -36
  107. package/lib/SingleEntryPlugin.js +24 -24
  108. package/lib/Source.js +5 -5
  109. package/lib/SourceMapDevToolModuleOptionsPlugin.js +33 -33
  110. package/lib/SourceMapDevToolPlugin.js +168 -168
  111. package/lib/SourceMapSource.js +5 -5
  112. package/lib/Stats.js +732 -732
  113. package/lib/Template.js +119 -119
  114. package/lib/TemplatedPathPlugin.js +111 -111
  115. package/lib/UmdMainTemplatePlugin.js +146 -146
  116. package/lib/UnsupportedFeatureWarning.js +14 -14
  117. package/lib/WarnCaseSensitiveModulesPlugin.js +27 -27
  118. package/lib/WatchIgnorePlugin.js +45 -45
  119. package/lib/WebpackOptionsApply.js +376 -376
  120. package/lib/WebpackOptionsDefaulter.js +112 -112
  121. package/lib/dependencies/AMDDefineDependency.js +63 -63
  122. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +240 -240
  123. package/lib/dependencies/AMDPlugin.js +115 -115
  124. package/lib/dependencies/AMDRequireArrayDependency.js +34 -34
  125. package/lib/dependencies/AMDRequireContextDependency.js +18 -18
  126. package/lib/dependencies/AMDRequireDependenciesBlock.js +25 -25
  127. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +145 -145
  128. package/lib/dependencies/AMDRequireDependency.js +64 -64
  129. package/lib/dependencies/AMDRequireItemDependency.js +17 -17
  130. package/lib/dependencies/CommonJsPlugin.js +93 -93
  131. package/lib/dependencies/CommonJsRequireContextDependency.js +18 -18
  132. package/lib/dependencies/CommonJsRequireDependency.js +17 -17
  133. package/lib/dependencies/CommonJsRequireDependencyParserPlugin.js +91 -91
  134. package/lib/dependencies/ConstDependency.js +29 -29
  135. package/lib/dependencies/ContextDependency.js +24 -24
  136. package/lib/dependencies/ContextDependencyHelpers.js +34 -34
  137. package/lib/dependencies/ContextDependencyTemplateAsId.js +22 -22
  138. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +31 -31
  139. package/lib/dependencies/ContextElementDependency.js +17 -17
  140. package/lib/dependencies/DelegatedSourceDependency.js +14 -14
  141. package/lib/dependencies/DepBlockHelpers.js +41 -41
  142. package/lib/dependencies/DllEntryDependency.js +17 -17
  143. package/lib/dependencies/LabeledExportsDependency.js +21 -21
  144. package/lib/dependencies/LabeledModuleDependency.js +36 -36
  145. package/lib/dependencies/LabeledModuleDependencyParserPlugin.js +76 -76
  146. package/lib/dependencies/LabeledModulesPlugin.js +26 -26
  147. package/lib/dependencies/LoaderDependency.js +14 -14
  148. package/lib/dependencies/LoaderPlugin.js +61 -61
  149. package/lib/dependencies/LocalModule.js +19 -19
  150. package/lib/dependencies/LocalModuleDependency.js +23 -23
  151. package/lib/dependencies/LocalModulesHelpers.js +43 -43
  152. package/lib/dependencies/ModuleDependency.js +20 -20
  153. package/lib/dependencies/ModuleDependencyTemplateAsId.js +22 -22
  154. package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +22 -22
  155. package/lib/dependencies/ModuleHotAcceptDependency.js +18 -18
  156. package/lib/dependencies/ModuleHotDeclineDependency.js +18 -18
  157. package/lib/dependencies/MultiEntryDependency.js +16 -16
  158. package/lib/dependencies/NullDependency.js +17 -17
  159. package/lib/dependencies/NullDependencyTemplate.js +8 -8
  160. package/lib/dependencies/PrefetchDependency.js +14 -14
  161. package/lib/dependencies/RequireContextDependency.js +17 -17
  162. package/lib/dependencies/RequireContextDependencyParserPlugin.js +33 -33
  163. package/lib/dependencies/RequireContextPlugin.js +64 -64
  164. package/lib/dependencies/RequireEnsureDependenciesBlock.js +20 -20
  165. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +66 -66
  166. package/lib/dependencies/RequireEnsureDependency.js +29 -29
  167. package/lib/dependencies/RequireEnsureItemDependency.js +16 -16
  168. package/lib/dependencies/RequireEnsurePlugin.js +38 -38
  169. package/lib/dependencies/RequireHeaderDependency.js +25 -25
  170. package/lib/dependencies/RequireIncludeDependency.js +25 -25
  171. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +18 -18
  172. package/lib/dependencies/RequireIncludePlugin.js +31 -31
  173. package/lib/dependencies/RequireResolveContextDependency.js +18 -18
  174. package/lib/dependencies/RequireResolveDependency.js +17 -17
  175. package/lib/dependencies/RequireResolveDependencyParserPlugin.js +69 -69
  176. package/lib/dependencies/RequireResolveHeaderDependency.js +25 -25
  177. package/lib/dependencies/SingleEntryDependency.js +14 -14
  178. package/lib/dependencies/TemplateArgumentDependency.js +26 -26
  179. package/lib/dependencies/WebpackMissingModule.js +23 -23
  180. package/lib/dependencies/getFunctionExpression.js +43 -43
  181. package/lib/node/NodeChunkTemplatePlugin.js +22 -22
  182. package/lib/node/NodeEnvironmentPlugin.js +25 -25
  183. package/lib/node/NodeHotUpdateChunkTemplatePlugin.js +24 -24
  184. package/lib/node/NodeMainTemplate.runtime.js +20 -20
  185. package/lib/node/NodeMainTemplateAsync.runtime.js +34 -34
  186. package/lib/node/NodeMainTemplatePlugin.js +164 -164
  187. package/lib/node/NodeOutputFileSystem.js +17 -17
  188. package/lib/node/NodeSourcePlugin.js +85 -75
  189. package/lib/node/NodeTargetPlugin.js +12 -12
  190. package/lib/node/NodeTemplatePlugin.js +21 -21
  191. package/lib/node/NodeWatchFileSystem.js +65 -65
  192. package/lib/node/OldNodeWatchFileSystem.js +265 -265
  193. package/lib/optimize/AggressiveMergingPlugin.js +115 -115
  194. package/lib/optimize/CommonsChunkPlugin.js +178 -178
  195. package/lib/optimize/DedupePlugin.js +227 -227
  196. package/lib/optimize/FlagIncludedChunksPlugin.js +24 -24
  197. package/lib/optimize/LimitChunkCountPlugin.js +55 -55
  198. package/lib/optimize/MergeDuplicateChunksPlugin.js +30 -30
  199. package/lib/optimize/MinChunkSizePlugin.js +61 -61
  200. package/lib/optimize/OccurenceOrderPlugin.js +5 -5
  201. package/lib/optimize/OccurrenceOrderPlugin.js +91 -91
  202. package/lib/optimize/RemoveEmptyChunksPlugin.js +19 -19
  203. package/lib/optimize/RemoveParentModulesPlugin.js +50 -50
  204. package/lib/optimize/UglifyJsPlugin.js +146 -146
  205. package/lib/removeAndDo.js +13 -13
  206. package/lib/web/WebEnvironmentPlugin.js +16 -16
  207. package/lib/webpack.js +113 -113
  208. package/lib/webpack.web.js +27 -27
  209. package/lib/webworker/WebWorkerChunkTemplatePlugin.js +26 -26
  210. package/lib/webworker/WebWorkerMainTemplatePlugin.js +78 -78
  211. package/lib/webworker/WebWorkerTemplatePlugin.js +15 -15
  212. package/package.json +4 -4
@@ -1,265 +1,265 @@
1
- /*
2
- MIT License http://www.opensource.org/licenses/mit-license.php
3
- Author Tobias Koppers @sokra
4
- */
5
- var fs = require("fs");
6
- var path = require("path");
7
- var async = require("async");
8
-
9
- function OldNodeWatchFileSystem(inputFileSystem) {
10
- this.inputFileSystem = inputFileSystem;
11
- }
12
- module.exports = OldNodeWatchFileSystem;
13
-
14
- /**
15
- *
16
- * @param files {String[]} a sorted array of paths to files
17
- * @param dirs {String[]} a sorted array of paths to directories
18
- * @param startTime {number} the virtual start time
19
- * @param delay {number} in ms, the time to wait to signal after the first change
20
- * @param callback {function(err, filesModified: String[], dirsModified: String[], fileTimestamps: Object, dirTimestamps: Object)] called once after change plus delay
21
- * @param callbackUndelayed {function()} called once after first change
22
- */
23
- OldNodeWatchFileSystem.prototype.watch = function(files, dirs, missing, startTime, delay, callback, callbackUndelayed) {
24
- var inputFileSystem = this.inputFileSystem;
25
-
26
- if(!callbackUndelayed) callbackUndelayed = function() {};
27
- var closed = false;
28
- var fileTimestamps = {};
29
- var dirTimestamps = {};
30
- var filesModified = {};
31
- var dirsModified = {};
32
-
33
- var lastChangeTime;
34
-
35
- startTime = Math.floor(startTime / 1000) * 1000; // only 1 second accuracy
36
-
37
- var directories = {};
38
- dirs.forEach(function(dir) {
39
- directories[dir] = {
40
- context: dir,
41
- files: []
42
- };
43
- });
44
- files.forEach(function(file) {
45
- var dir = path.dirname(file);
46
- if(!directories[dir]) directories[dir] = {
47
- files: []
48
- };
49
- directories[dir].files.push(file);
50
- });
51
-
52
- var items = Object.keys(directories).map(function(dir) {
53
- directories[dir].path = dir;
54
- return directories[dir];
55
- });
56
- items.sort(function(a, b) {
57
- if(a.path === b.path) return 0;
58
- return a.path < b.path ? -1 : 1;
59
- });
60
- items.forEach(function(item) {
61
- if(item.files) {
62
- item.files.sort();
63
- }
64
- });
65
-
66
- var initialChange = false;
67
- var change = function() {
68
- initialChange = true;
69
- };
70
-
71
- function readStat(item, callback) {
72
- if(item.context) {
73
- fs.readdir(item.path, function(err, files) {
74
- function onTimestamp(ts) {
75
- if(!dirTimestamps[item.context] || dirTimestamps[item.context] < ts)
76
- dirTimestamps[item.context] = ts;
77
- if(ts >= startTime) {
78
- dirsModified[item.context] = true;
79
- change(item.path);
80
- }
81
- return callback();
82
- }
83
- if(err) return onTimestamp(Infinity);
84
- async.map(files, function(file, callback) {
85
- file = path.join(item.path, file);
86
- var isFile = false;
87
- if(item.files) {
88
- if(binarySearch(item.files, function(path) {
89
- if(path === file) return 0;
90
- return path < file ? -1 : 1;
91
- }) >= 0) {
92
- isFile = true;
93
- }
94
- }
95
- fs.stat(file, function(err, stat) {
96
- var ts = err ? Infinity : stat.mtime.getTime();
97
- if(isFile) {
98
- fileTimestamps[file] = ts;
99
- if(ts >= startTime) filesModified[file] = true;
100
- }
101
- return callback(null, ts);
102
- });
103
- }, function(err, timestamps) {
104
- if(err) return onTimestamp(Infinity);
105
- var ts = timestamps.reduce(function(max, ts) {
106
- if(ts > max)
107
- return ts;
108
- return max;
109
- }, 0);
110
- onTimestamp(ts);
111
- });
112
- });
113
- } else {
114
- async.forEach(item.files, function(file, callback) {
115
- fs.stat(file, function(err, stat) {
116
- var ts = err ? Infinity : stat.mtime.getTime();
117
- fileTimestamps[file] = ts;
118
- if(ts >= startTime) {
119
- filesModified[file] = true;
120
- change(file);
121
- }
122
- return callback(null, ts);
123
- });
124
- }, callback);
125
- }
126
- }
127
- async.forEach(items, function processItem(item, callback) {
128
- var isRunning = false;
129
- var isScheduled = false;
130
- item.watcher = fs.watch(item.path, function() {
131
- if(isRunning) {
132
- isScheduled = true;
133
- return;
134
- }
135
- isRunning = true;
136
- readStat(item, done);
137
- });
138
- if(item.context) {
139
- item.children = [];
140
- fs.readdir(item.path, function(err, files) {
141
- if(err) {
142
- change();
143
- onWatcherApplied();
144
- return;
145
- }
146
- async.forEach(files, function(file, callback) {
147
- file = path.join(item.path, file);
148
- fs.stat(file, function(err, stat) {
149
- if(err) {
150
- change(file);
151
- callback();
152
- return;
153
- }
154
- if(!stat.isDirectory()) return callback();
155
- var subitem = {
156
- path: file,
157
- context: item.context
158
- };
159
- item.children.push(subitem);
160
- processItem(subitem, callback);
161
- });
162
- }, onWatcherApplied);
163
- });
164
- } else onWatcherApplied();
165
-
166
- function onWatcherApplied() {
167
- readStat(item, function() {
168
- callback();
169
- done();
170
- });
171
- }
172
-
173
- function done() {
174
- if(closed) return;
175
- if(isScheduled) {
176
- isScheduled = false;
177
- readStat(item, done);
178
- } else {
179
- isRunning = false;
180
- }
181
- }
182
- }, function() {
183
- var timeout;
184
- if(initialChange) {
185
-
186
- callbackUndelayed();
187
- if(delay) {
188
- lastChangeTime = Date.now();
189
- change = restartDelay;
190
- timeout = setTimeout(onTimeout, delay);
191
- } else onTimeout();
192
-
193
- } else {
194
-
195
- change = function() {
196
-
197
- callbackUndelayed();
198
- if(delay) {
199
- lastChangeTime = Date.now();
200
- change = restartDelay;
201
- timeout = setTimeout(onTimeout, delay);
202
- } else {
203
- change = function() {};
204
- onTimeout();
205
- }
206
- };
207
-
208
- }
209
-
210
- function restartDelay() {
211
- lastChangeTime = Date.now();
212
- clearTimeout(timeout);
213
- timeout = setTimeout(onTimeout, delay);
214
- }
215
-
216
- });
217
-
218
- // 7.
219
- function onTimeout() {
220
- var nextSecond = Math.ceil(lastChangeTime / 1000) * 1000;
221
- var timeToNextSecond = nextSecond - Date.now();
222
- if(timeToNextSecond > 0) {
223
- setTimeout(onTimeout, timeToNextSecond);
224
- return;
225
- }
226
- change = function() {};
227
- if(closed) return;
228
- var outdatedFiles = Object.keys(filesModified).sort();
229
- var outdatedDirs = Object.keys(dirsModified).sort();
230
- if(inputFileSystem && inputFileSystem.purge) {
231
- inputFileSystem.purge(outdatedFiles);
232
- inputFileSystem.purge(outdatedDirs);
233
- }
234
- callback(null, outdatedFiles, outdatedDirs, [], fileTimestamps, dirTimestamps);
235
-
236
- close();
237
- }
238
-
239
- function close() {
240
- closed = true;
241
- items.forEach(function closeItem(item) {
242
- item.watcher.close();
243
- if(item.children) item.children.forEach(closeItem);
244
- });
245
- }
246
-
247
- return {
248
- close: close,
249
- pause: close
250
- };
251
- };
252
-
253
- function binarySearch(array, comparator) {
254
- var left = 0;
255
- var right = array.length - 1;
256
-
257
- while(left <= right) {
258
- var middle = ((left + right) / 2) | 0;
259
- var comp = comparator(array[middle]);
260
- if(comp === 0) return middle;
261
- if(comp > 0) right = middle - 1;
262
- if(comp < 0) left = middle + 1;
263
- }
264
- return -1;
265
- }
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+ var fs = require("fs");
6
+ var path = require("path");
7
+ var async = require("async");
8
+
9
+ function OldNodeWatchFileSystem(inputFileSystem) {
10
+ this.inputFileSystem = inputFileSystem;
11
+ }
12
+ module.exports = OldNodeWatchFileSystem;
13
+
14
+ /**
15
+ *
16
+ * @param files {String[]} a sorted array of paths to files
17
+ * @param dirs {String[]} a sorted array of paths to directories
18
+ * @param startTime {number} the virtual start time
19
+ * @param delay {number} in ms, the time to wait to signal after the first change
20
+ * @param callback {function(err, filesModified: String[], dirsModified: String[], fileTimestamps: Object, dirTimestamps: Object)] called once after change plus delay
21
+ * @param callbackUndelayed {function()} called once after first change
22
+ */
23
+ OldNodeWatchFileSystem.prototype.watch = function(files, dirs, missing, startTime, delay, callback, callbackUndelayed) {
24
+ var inputFileSystem = this.inputFileSystem;
25
+
26
+ if(!callbackUndelayed) callbackUndelayed = function() {};
27
+ var closed = false;
28
+ var fileTimestamps = {};
29
+ var dirTimestamps = {};
30
+ var filesModified = {};
31
+ var dirsModified = {};
32
+
33
+ var lastChangeTime;
34
+
35
+ startTime = Math.floor(startTime / 1000) * 1000; // only 1 second accuracy
36
+
37
+ var directories = {};
38
+ dirs.forEach(function(dir) {
39
+ directories[dir] = {
40
+ context: dir,
41
+ files: []
42
+ };
43
+ });
44
+ files.forEach(function(file) {
45
+ var dir = path.dirname(file);
46
+ if(!directories[dir]) directories[dir] = {
47
+ files: []
48
+ };
49
+ directories[dir].files.push(file);
50
+ });
51
+
52
+ var items = Object.keys(directories).map(function(dir) {
53
+ directories[dir].path = dir;
54
+ return directories[dir];
55
+ });
56
+ items.sort(function(a, b) {
57
+ if(a.path === b.path) return 0;
58
+ return a.path < b.path ? -1 : 1;
59
+ });
60
+ items.forEach(function(item) {
61
+ if(item.files) {
62
+ item.files.sort();
63
+ }
64
+ });
65
+
66
+ var initialChange = false;
67
+ var change = function() {
68
+ initialChange = true;
69
+ };
70
+
71
+ function readStat(item, callback) {
72
+ if(item.context) {
73
+ fs.readdir(item.path, function(err, files) {
74
+ function onTimestamp(ts) {
75
+ if(!dirTimestamps[item.context] || dirTimestamps[item.context] < ts)
76
+ dirTimestamps[item.context] = ts;
77
+ if(ts >= startTime) {
78
+ dirsModified[item.context] = true;
79
+ change(item.path);
80
+ }
81
+ return callback();
82
+ }
83
+ if(err) return onTimestamp(Infinity);
84
+ async.map(files, function(file, callback) {
85
+ file = path.join(item.path, file);
86
+ var isFile = false;
87
+ if(item.files) {
88
+ if(binarySearch(item.files, function(path) {
89
+ if(path === file) return 0;
90
+ return path < file ? -1 : 1;
91
+ }) >= 0) {
92
+ isFile = true;
93
+ }
94
+ }
95
+ fs.stat(file, function(err, stat) {
96
+ var ts = err ? Infinity : stat.mtime.getTime();
97
+ if(isFile) {
98
+ fileTimestamps[file] = ts;
99
+ if(ts >= startTime) filesModified[file] = true;
100
+ }
101
+ return callback(null, ts);
102
+ });
103
+ }, function(err, timestamps) {
104
+ if(err) return onTimestamp(Infinity);
105
+ var ts = timestamps.reduce(function(max, ts) {
106
+ if(ts > max)
107
+ return ts;
108
+ return max;
109
+ }, 0);
110
+ onTimestamp(ts);
111
+ });
112
+ });
113
+ } else {
114
+ async.forEach(item.files, function(file, callback) {
115
+ fs.stat(file, function(err, stat) {
116
+ var ts = err ? Infinity : stat.mtime.getTime();
117
+ fileTimestamps[file] = ts;
118
+ if(ts >= startTime) {
119
+ filesModified[file] = true;
120
+ change(file);
121
+ }
122
+ return callback(null, ts);
123
+ });
124
+ }, callback);
125
+ }
126
+ }
127
+ async.forEach(items, function processItem(item, callback) {
128
+ var isRunning = false;
129
+ var isScheduled = false;
130
+ item.watcher = fs.watch(item.path, function() {
131
+ if(isRunning) {
132
+ isScheduled = true;
133
+ return;
134
+ }
135
+ isRunning = true;
136
+ readStat(item, done);
137
+ });
138
+ if(item.context) {
139
+ item.children = [];
140
+ fs.readdir(item.path, function(err, files) {
141
+ if(err) {
142
+ change();
143
+ onWatcherApplied();
144
+ return;
145
+ }
146
+ async.forEach(files, function(file, callback) {
147
+ file = path.join(item.path, file);
148
+ fs.stat(file, function(err, stat) {
149
+ if(err) {
150
+ change(file);
151
+ callback();
152
+ return;
153
+ }
154
+ if(!stat.isDirectory()) return callback();
155
+ var subitem = {
156
+ path: file,
157
+ context: item.context
158
+ };
159
+ item.children.push(subitem);
160
+ processItem(subitem, callback);
161
+ });
162
+ }, onWatcherApplied);
163
+ });
164
+ } else onWatcherApplied();
165
+
166
+ function onWatcherApplied() {
167
+ readStat(item, function() {
168
+ callback();
169
+ done();
170
+ });
171
+ }
172
+
173
+ function done() {
174
+ if(closed) return;
175
+ if(isScheduled) {
176
+ isScheduled = false;
177
+ readStat(item, done);
178
+ } else {
179
+ isRunning = false;
180
+ }
181
+ }
182
+ }, function() {
183
+ var timeout;
184
+ if(initialChange) {
185
+
186
+ callbackUndelayed();
187
+ if(delay) {
188
+ lastChangeTime = Date.now();
189
+ change = restartDelay;
190
+ timeout = setTimeout(onTimeout, delay);
191
+ } else onTimeout();
192
+
193
+ } else {
194
+
195
+ change = function() {
196
+
197
+ callbackUndelayed();
198
+ if(delay) {
199
+ lastChangeTime = Date.now();
200
+ change = restartDelay;
201
+ timeout = setTimeout(onTimeout, delay);
202
+ } else {
203
+ change = function() {};
204
+ onTimeout();
205
+ }
206
+ };
207
+
208
+ }
209
+
210
+ function restartDelay() {
211
+ lastChangeTime = Date.now();
212
+ clearTimeout(timeout);
213
+ timeout = setTimeout(onTimeout, delay);
214
+ }
215
+
216
+ });
217
+
218
+ // 7.
219
+ function onTimeout() {
220
+ var nextSecond = Math.ceil(lastChangeTime / 1000) * 1000;
221
+ var timeToNextSecond = nextSecond - Date.now();
222
+ if(timeToNextSecond > 0) {
223
+ setTimeout(onTimeout, timeToNextSecond);
224
+ return;
225
+ }
226
+ change = function() {};
227
+ if(closed) return;
228
+ var outdatedFiles = Object.keys(filesModified).sort();
229
+ var outdatedDirs = Object.keys(dirsModified).sort();
230
+ if(inputFileSystem && inputFileSystem.purge) {
231
+ inputFileSystem.purge(outdatedFiles);
232
+ inputFileSystem.purge(outdatedDirs);
233
+ }
234
+ callback(null, outdatedFiles, outdatedDirs, [], fileTimestamps, dirTimestamps);
235
+
236
+ close();
237
+ }
238
+
239
+ function close() {
240
+ closed = true;
241
+ items.forEach(function closeItem(item) {
242
+ item.watcher.close();
243
+ if(item.children) item.children.forEach(closeItem);
244
+ });
245
+ }
246
+
247
+ return {
248
+ close: close,
249
+ pause: close
250
+ };
251
+ };
252
+
253
+ function binarySearch(array, comparator) {
254
+ var left = 0;
255
+ var right = array.length - 1;
256
+
257
+ while(left <= right) {
258
+ var middle = ((left + right) / 2) | 0;
259
+ var comp = comparator(array[middle]);
260
+ if(comp === 0) return middle;
261
+ if(comp > 0) right = middle - 1;
262
+ if(comp < 0) left = middle + 1;
263
+ }
264
+ return -1;
265
+ }