1 | /// Module utils
|
2 | //
|
3 | // Common utilities.
|
4 | //
|
5 | // (Most of this code should be moved to their own modules given some
|
6 | // time, they're just here because it's easy to just put everything here
|
7 | // and get a working prototype, then refactor.)
|
8 | //
|
9 | // Copyright (c) 2013 Quildreen Motta
|
10 | //
|
11 | // Permission is hereby granted, free of charge, to any person
|
12 | // obtaining a copy of this software and associated documentation files
|
13 | // (the "Software"), to deal in the Software without restriction,
|
14 | // including without limitation the rights to use, copy, modify, merge,
|
15 | // publish, distribute, sublicense, and/or sell copies of the Software,
|
16 | // and to permit persons to whom the Software is furnished to do so,
|
17 | // subject to the following conditions:
|
18 | //
|
19 | // The above copyright notice and this permission notice shall be
|
20 | // included in all copies or substantial portions of the Software.
|
21 | //
|
22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
23 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
24 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
25 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
26 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
27 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
28 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
29 |
|
30 | //// -- Dependencies ---------------------------------------------------
|
31 | var pinky = require('pinky')
|
32 |
|
33 |
|
34 | //// -- Collections ----------------------------------------------------
|
35 |
|
36 | ///// λ flatten
|
37 | //
|
38 | // Flattens a list of lists recursively.
|
39 | //
|
40 | // :: [[a]] -> [a]
|
41 | function flatten(xs) {
|
42 | return xs.reduce(function(r, x) {
|
43 | Array.isArray(x)? r.push.apply(r, flatten(x))
|
44 | : /* otherwise */ r.push(x)
|
45 | return r
|
46 | }, [])
|
47 | }
|
48 |
|
49 |
|
50 | //// -- Asynchronous stuff ---------------------------------------------
|
51 |
|
52 | ///// λ timeout
|
53 | //
|
54 | // Creates a promise that is rejected if not fulfilled within a given
|
55 | // timeframe.
|
56 | //
|
57 | // :: Number, Promise a -> Promise a
|
58 | //
|
59 | function timeout(ms, promise) {
|
60 | var err = new Error('Timeout of ' + ms + ' exceeded.')
|
61 | var p = pinky(promise)
|
62 |
|
63 | var timer = setTimeout(p.reject.bind(null, err), ms)
|
64 | p.always(function(){ clearTimeout(timer) })
|
65 | return p
|
66 | }
|
67 |
|
68 | ///// λ sequentially
|
69 | //
|
70 | // Runs a series of promise-returning functions sequentially.
|
71 | //
|
72 | // :: [a... -> Promise b] -> Promise [b]
|
73 | function sequentially(fns) {
|
74 | if (fns.length == 0) return pinky([])
|
75 |
|
76 | var result = []
|
77 | var promise = pinky()
|
78 |
|
79 | next()
|
80 |
|
81 | return promise
|
82 |
|
83 | function next() {
|
84 | var f = fns.shift()
|
85 | f().always(function(value) {
|
86 | result.push(value)
|
87 | if (!fns.length) promise.fulfill(result)
|
88 | else next()
|
89 | })
|
90 | }
|
91 | }
|
92 |
|
93 |
|
94 | //// -- Exports --------------------------------------------------------
|
95 | module.exports = { flatten : flatten
|
96 | , sequentially : sequentially
|
97 | , timeout : timeout } |
\ | No newline at end of file |