UNPKG

16 kBJavaScriptView Raw
1"use strict";
2var seq = require("./task.sequence");
3var task_runner_1 = require("./task.runner");
4var Rx = require("rx");
5var reporter_resolve_1 = require("./reporter.resolve");
6var command_watch_1 = require("./command.watch");
7var immutable_1 = require("immutable");
8var debug = require("debug")("cb:watch.runner");
9/**
10 * Create a stream that is the combination of all watchers
11 */
12function createObservablesForWatchers(watchers, trigger) {
13 /**
14 * Wrap every chokidar watcher in an observable
15 * @type {Rx.Observable<WatchEvent>[]}
16 */
17 var watchersAsObservables = watchers.map(function (watcher) {
18 return createObservableForWatcher(watcher, trigger);
19 });
20 var blockable$ = new Rx.BehaviorSubject([]);
21 /**
22 * Now map file-change events to task running
23 */
24 return (_a = Rx.Observable).merge.apply(_a, watchersAsObservables)
25 .map(function (watchEvent) {
26 var watcher = watchers.filter(function (x) { return x.watcherUID === watchEvent.watcherUID; })[0];
27 return { watchEvent: watchEvent, watcher: watcher };
28 })
29 .filter(function (x) {
30 if (x.watcher.options.block) {
31 var blocked = !~blockable$.getValue().indexOf(x.watchEvent.watcherUID);
32 debug("BLOCKED - " + x.watchEvent.watcherUID + " " + x.watchEvent.path + " " + x.watchEvent.event);
33 return blocked;
34 }
35 return true;
36 })
37 .do(function (x) {
38 if (x.watcher.options.block) {
39 blockable$.onNext(blockable$.getValue().concat(x.watchEvent.watcherUID));
40 }
41 })
42 .timestamp(trigger.config.scheduler)
43 .flatMap(function (incoming, i) {
44 return runTasks(incoming, i);
45 });
46 function runTasks(incoming, i) {
47 /**
48 * @type {WatchEvent}
49 */
50 var _a = incoming.value, watchEvent = _a.watchEvent, watcher = _a.watcher;
51 return Rx.Observable.create(function (obs) {
52 /**
53 * Report start of task run
54 */
55 trigger.reporter({
56 type: reporter_resolve_1.ReportTypes.WatcherTriggeredTasks,
57 data: {
58 index: i,
59 taskCollection: watcher.tasks
60 }
61 });
62 /**
63 * todo: Is there a way to handle this without subscribing manually?
64 */
65 watcher._runner.series(immutable_1.fromJS({
66 watchEvent: watchEvent,
67 watcher: {
68 patterns: watcher.patterns,
69 tasks: watcher.tasks,
70 options: watcher.options,
71 watcherUID: watcher.watcherUID
72 }
73 }))
74 .do(function (taskReport) { return obs.onNext({
75 type: command_watch_1.WatchCommandEventTypes.WatchTaskReport,
76 data: {
77 taskReport: taskReport,
78 watchEvent: watchEvent,
79 count: i
80 }
81 }); })
82 .toArray()
83 .timestamp(trigger.config.scheduler)
84 .subscribe(function (x) {
85 var reports = x.value;
86 var sequence = seq.decorateSequenceWithReports(watcher._sequence, reports);
87 var errors = reports.filter(function (x) { return x.type === task_runner_1.TaskReportType.error; });
88 obs.onNext({
89 type: command_watch_1.WatchCommandEventTypes.WatchRunnerComplete,
90 data: {
91 sequence: sequence,
92 reports: reports,
93 errors: errors,
94 watchEvent: watchEvent,
95 runtime: x.timestamp - incoming.timestamp
96 }
97 });
98 if (errors.length > 0) {
99 trigger.reporter({
100 type: reporter_resolve_1.ReportTypes.WatcherSummary,
101 data: {
102 sequence: sequence,
103 cli: trigger.cli,
104 title: watcher.tasks.join(", "),
105 config: trigger.config,
106 runtime: x.timestamp - incoming.timestamp,
107 watcher: watcher,
108 watchEvent: watchEvent
109 }
110 });
111 }
112 else {
113 trigger.reporter({
114 type: reporter_resolve_1.ReportTypes.WatcherTriggeredTasksCompleted,
115 data: {
116 index: i,
117 taskCollection: watcher.tasks,
118 time: x.timestamp - incoming.timestamp
119 }
120 });
121 }
122 var withoutThis = blockable$.getValue().filter(function (x) { return x !== watchEvent.watcherUID; });
123 blockable$.onNext(withoutThis);
124 obs.onCompleted();
125 });
126 });
127 }
128 var _a;
129}
130exports.createObservablesForWatchers = createObservablesForWatchers;
131/**
132 * Create a file-system watcher that will emit <WatchEvent>
133 */
134function createObservableForWatcher(watcher, trigger) {
135 var reporter = trigger.reporter;
136 var scheduler = trigger.config.scheduler;
137 /**
138 * First create a stream of file-watcher events for this Watcher
139 */
140 var output$ = trigger.config.fileChangeObserver || getFileChangeStream(watcher, reporter);
141 /**
142 * Specify a mapping from option name -> Rx.Observable operator name
143 */
144 var additionalOperators = [
145 {
146 option: "debounce",
147 fnName: "debounce"
148 },
149 {
150 option: "throttle",
151 fnName: "throttle"
152 },
153 {
154 option: "delay",
155 fnName: "delay"
156 }
157 ];
158 return applyOperators(output$, additionalOperators, watcher.options, scheduler);
159}
160exports.createObservableForWatcher = createObservableForWatcher;
161function getFileChangeStream(watcher, reporter) {
162 /** DEBUG **/
163 debug("[id:" + watcher.watcherUID + "] options: " + JSON.stringify(watcher.options, null, 2));
164 /** DEBUG END **/
165 return Rx.Observable.create(function (observer) {
166 /** DEBUG **/
167 debug("+ [id:" + watcher.watcherUID + "] " + watcher.patterns.length + " patterns (" + watcher.patterns + ")");
168 debug("\u2514\u2500 " + watcher.tasks.length + " tasks (" + watcher.tasks + ")");
169 /** DEBUG END **/
170 var chokidarWatcher = require("chokidar").watch(watcher.patterns, watcher.options)
171 .on("all", function (event, path) {
172 debug("\u2514\u2500 CHOKIDAR EVENT " + event + " - " + path);
173 observer.onNext({
174 event: event,
175 path: path,
176 watcherUID: watcher.watcherUID
177 });
178 });
179 chokidarWatcher.on("ready", function () {
180 /** DEBUG **/
181 debug("\u221A [id:" + watcher.watcherUID + "] watcher ready (" + watcher.patterns + ")");
182 /** DEBUG END **/
183 if (Object.keys(chokidarWatcher.getWatched()).length === 0) {
184 reporter({ type: reporter_resolve_1.ReportTypes.NoFilesMatched, data: { watcher: watcher } });
185 }
186 });
187 return function () {
188 debug("- for " + watcher.patterns);
189 chokidarWatcher.close();
190 };
191 });
192}
193exports.getFileChangeStream = getFileChangeStream;
194/**
195 *
196 */
197function applyOperators(source, items, options, scheduler) {
198 return items.reduce(function (stream$, item) {
199 var value = options[item.option];
200 if (value !== undefined && value > 0) {
201 return stream$[item.fnName].call(stream$, value, scheduler);
202 }
203 return stream$;
204 }, source);
205}
206//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F0Y2guZmlsZS13YXRjaGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dhdGNoLmZpbGUtd2F0Y2hlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsSUFBWSxHQUFHLFdBQU0saUJBQWlCLENBQUMsQ0FBQTtBQUV2Qyw0QkFBeUMsZUFBZSxDQUFDLENBQUE7QUFDekQsSUFBTyxFQUFFLFdBQVcsSUFBSSxDQUFDLENBQUM7QUFFMUIsaUNBQXVELG9CQUFvQixDQUFDLENBQUE7QUFFNUUsOEJBQXFDLGlCQUFpQixDQUFDLENBQUE7QUFDdkQsMEJBQXFCLFdBQVcsQ0FBQyxDQUFBO0FBRWpDLElBQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBMkJsRDs7R0FFRztBQUNILHNDQUE2QyxRQUFtQixFQUFFLE9BQXVCO0lBR3JGOzs7T0FHRztJQUNILElBQU0scUJBQXFCLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxVQUFDLE9BQU87UUFDL0MsTUFBTSxDQUFDLDBCQUEwQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN4RCxDQUFDLENBQUMsQ0FBQztJQUVILElBQU0sVUFBVSxHQUFHLElBQUksRUFBRSxDQUFDLGVBQWUsQ0FBVyxFQUFFLENBQUMsQ0FBQztJQUV4RDs7T0FFRztJQUNILE1BQU0sQ0FBQyxNQUFBLEVBQUUsQ0FBQyxVQUFVLEVBSWYsS0FBSyxXQUFJLHFCQUFxQixDQUFDO1NBTS9CLEdBQUcsQ0FBd0IsVUFBQyxVQUFzQjtRQUMvQyxJQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsQ0FBQyxDQUFDLFVBQVUsS0FBSyxVQUFVLENBQUMsVUFBVSxFQUF0QyxDQUFzQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEYsTUFBTSxDQUFDLEVBQUMsc0JBQVUsRUFBRSxnQkFBTyxFQUFDLENB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
\No newline at end of file