Security update to Drupal 8.4.6
[yaffs-website] / node_modules / grunt-uncss / node_modules / async / auto.js
1 'use strict';
2
3 Object.defineProperty(exports, "__esModule", {
4     value: true
5 });
6
7 exports.default = function (tasks, concurrency, callback) {
8     if (typeof concurrency === 'function') {
9         // concurrency is optional, shift the args.
10         callback = concurrency;
11         concurrency = null;
12     }
13     callback = (0, _once2.default)(callback || _noop2.default);
14     var keys = (0, _keys2.default)(tasks);
15     var numTasks = keys.length;
16     if (!numTasks) {
17         return callback(null);
18     }
19     if (!concurrency) {
20         concurrency = numTasks;
21     }
22
23     var results = {};
24     var runningTasks = 0;
25     var hasError = false;
26
27     var listeners = Object.create(null);
28
29     var readyTasks = [];
30
31     // for cycle detection:
32     var readyToCheck = []; // tasks that have been identified as reachable
33     // without the possibility of returning to an ancestor task
34     var uncheckedDependencies = {};
35
36     (0, _baseForOwn2.default)(tasks, function (task, key) {
37         if (!(0, _isArray2.default)(task)) {
38             // no dependencies
39             enqueueTask(key, [task]);
40             readyToCheck.push(key);
41             return;
42         }
43
44         var dependencies = task.slice(0, task.length - 1);
45         var remainingDependencies = dependencies.length;
46         if (remainingDependencies === 0) {
47             enqueueTask(key, task);
48             readyToCheck.push(key);
49             return;
50         }
51         uncheckedDependencies[key] = remainingDependencies;
52
53         (0, _arrayEach2.default)(dependencies, function (dependencyName) {
54             if (!tasks[dependencyName]) {
55                 throw new Error('async.auto task `' + key + '` has a non-existent dependency `' + dependencyName + '` in ' + dependencies.join(', '));
56             }
57             addListener(dependencyName, function () {
58                 remainingDependencies--;
59                 if (remainingDependencies === 0) {
60                     enqueueTask(key, task);
61                 }
62             });
63         });
64     });
65
66     checkForDeadlocks();
67     processQueue();
68
69     function enqueueTask(key, task) {
70         readyTasks.push(function () {
71             runTask(key, task);
72         });
73     }
74
75     function processQueue() {
76         if (readyTasks.length === 0 && runningTasks === 0) {
77             return callback(null, results);
78         }
79         while (readyTasks.length && runningTasks < concurrency) {
80             var run = readyTasks.shift();
81             run();
82         }
83     }
84
85     function addListener(taskName, fn) {
86         var taskListeners = listeners[taskName];
87         if (!taskListeners) {
88             taskListeners = listeners[taskName] = [];
89         }
90
91         taskListeners.push(fn);
92     }
93
94     function taskComplete(taskName) {
95         var taskListeners = listeners[taskName] || [];
96         (0, _arrayEach2.default)(taskListeners, function (fn) {
97             fn();
98         });
99         processQueue();
100     }
101
102     function runTask(key, task) {
103         if (hasError) return;
104
105         var taskCallback = (0, _onlyOnce2.default)((0, _rest2.default)(function (err, args) {
106             runningTasks--;
107             if (args.length <= 1) {
108                 args = args[0];
109             }
110             if (err) {
111                 var safeResults = {};
112                 (0, _baseForOwn2.default)(results, function (val, rkey) {
113                     safeResults[rkey] = val;
114                 });
115                 safeResults[key] = args;
116                 hasError = true;
117                 listeners = Object.create(null);
118
119                 callback(err, safeResults);
120             } else {
121                 results[key] = args;
122                 taskComplete(key);
123             }
124         }));
125
126         runningTasks++;
127         var taskFn = task[task.length - 1];
128         if (task.length > 1) {
129             taskFn(results, taskCallback);
130         } else {
131             taskFn(taskCallback);
132         }
133     }
134
135     function checkForDeadlocks() {
136         // Kahn's algorithm
137         // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm
138         // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html
139         var currentTask;
140         var counter = 0;
141         while (readyToCheck.length) {
142             currentTask = readyToCheck.pop();
143             counter++;
144             (0, _arrayEach2.default)(getDependents(currentTask), function (dependent) {
145                 if (--uncheckedDependencies[dependent] === 0) {
146                     readyToCheck.push(dependent);
147                 }
148             });
149         }
150
151         if (counter !== numTasks) {
152             throw new Error('async.auto cannot execute tasks due to a recursive dependency');
153         }
154     }
155
156     function getDependents(taskName) {
157         var result = [];
158         (0, _baseForOwn2.default)(tasks, function (task, key) {
159             if ((0, _isArray2.default)(task) && (0, _baseIndexOf2.default)(task, taskName, 0) >= 0) {
160                 result.push(key);
161             }
162         });
163         return result;
164     }
165 };
166
167 var _arrayEach = require('lodash/_arrayEach');
168
169 var _arrayEach2 = _interopRequireDefault(_arrayEach);
170
171 var _baseForOwn = require('lodash/_baseForOwn');
172
173 var _baseForOwn2 = _interopRequireDefault(_baseForOwn);
174
175 var _baseIndexOf = require('lodash/_baseIndexOf');
176
177 var _baseIndexOf2 = _interopRequireDefault(_baseIndexOf);
178
179 var _isArray = require('lodash/isArray');
180
181 var _isArray2 = _interopRequireDefault(_isArray);
182
183 var _keys = require('lodash/keys');
184
185 var _keys2 = _interopRequireDefault(_keys);
186
187 var _noop = require('lodash/noop');
188
189 var _noop2 = _interopRequireDefault(_noop);
190
191 var _rest = require('./internal/rest');
192
193 var _rest2 = _interopRequireDefault(_rest);
194
195 var _once = require('./internal/once');
196
197 var _once2 = _interopRequireDefault(_once);
198
199 var _onlyOnce = require('./internal/onlyOnce');
200
201 var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
202
203 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
204
205 module.exports = exports['default'];
206
207 /**
208  * Determines the best order for running the functions in `tasks`, based on
209  * their requirements. Each function can optionally depend on other functions
210  * being completed first, and each function is run as soon as its requirements
211  * are satisfied.
212  *
213  * If any of the functions pass an error to their callback, the `auto` sequence
214  * will stop. Further tasks will not execute (so any other functions depending
215  * on it will not run), and the main `callback` is immediately called with the
216  * error.
217  *
218  * Functions also receive an object containing the results of functions which
219  * have completed so far as the first argument, if they have dependencies. If a
220  * task function has no dependencies, it will only be passed a callback.
221  *
222  * @name auto
223  * @static
224  * @memberOf module:ControlFlow
225  * @method
226  * @category Control Flow
227  * @param {Object} tasks - An object. Each of its properties is either a
228  * function or an array of requirements, with the function itself the last item
229  * in the array. The object's key of a property serves as the name of the task
230  * defined by that property, i.e. can be used when specifying requirements for
231  * other tasks. The function receives one or two arguments:
232  * * a `results` object, containing the results of the previously executed
233  *   functions, only passed if the task has any dependencies,
234  * * a `callback(err, result)` function, which must be called when finished,
235  *   passing an `error` (which can be `null`) and the result of the function's
236  *   execution.
237  * @param {number} [concurrency=Infinity] - An optional `integer` for
238  * determining the maximum number of tasks that can be run in parallel. By
239  * default, as many as possible.
240  * @param {Function} [callback] - An optional callback which is called when all
241  * the tasks have been completed. It receives the `err` argument if any `tasks`
242  * pass an error to their callback. Results are always returned; however, if an
243  * error occurs, no further `tasks` will be performed, and the results object
244  * will only contain partial results. Invoked with (err, results).
245  * @returns undefined
246  * @example
247  *
248  * async.auto({
249  *     // this function will just be passed a callback
250  *     readData: async.apply(fs.readFile, 'data.txt', 'utf-8'),
251  *     showData: ['readData', function(results, cb) {
252  *         // results.readData is the file's contents
253  *         // ...
254  *     }]
255  * }, callback);
256  *
257  * async.auto({
258  *     get_data: function(callback) {
259  *         console.log('in get_data');
260  *         // async code to get some data
261  *         callback(null, 'data', 'converted to array');
262  *     },
263  *     make_folder: function(callback) {
264  *         console.log('in make_folder');
265  *         // async code to create a directory to store a file in
266  *         // this is run at the same time as getting the data
267  *         callback(null, 'folder');
268  *     },
269  *     write_file: ['get_data', 'make_folder', function(results, callback) {
270  *         console.log('in write_file', JSON.stringify(results));
271  *         // once there is some data and the directory exists,
272  *         // write the data to a file in the directory
273  *         callback(null, 'filename');
274  *     }],
275  *     email_link: ['write_file', function(results, callback) {
276  *         console.log('in email_link', JSON.stringify(results));
277  *         // once the file is written let's email a link to it...
278  *         // results.write_file contains the filename returned by write_file.
279  *         callback(null, {'file':results.write_file, 'email':'user@example.com'});
280  *     }]
281  * }, function(err, results) {
282  *     console.log('err = ', err);
283  *     console.log('results = ', results);
284  * });
285  */