|
| 1 | +'use babel' |
| 2 | +// TODO use underscore |
| 3 | +import { debounce } from 'underscore-plus'; |
| 4 | + |
| 5 | +export default { |
| 6 | + // TODO Fix all of these dynamic requires and circular dependencies |
| 7 | + paths: require('./misc/paths'), |
| 8 | + blocks: require('./misc/blocks'), |
| 9 | + cells: require('./misc/cells'), |
| 10 | + words: require('./misc/words'), |
| 11 | + weave: require('./misc/weave'), |
| 12 | + colors: require('./misc/colors'), |
| 13 | + scopes: require('./misc/scopes'), |
| 14 | + |
| 15 | + bufferLines(t, f) { |
| 16 | + if (!f) { [t, f] = [null, t]; } |
| 17 | + const buffer = ['']; |
| 18 | + const flush = (t == null) ? ()=>{} : debounce(( () => { |
| 19 | + if (buffer[0] !== '') { |
| 20 | + f(buffer[0], false); |
| 21 | + buffer[0] = ''; |
| 22 | + }}), t); |
| 23 | + return function(data) { |
| 24 | + const lines = data.toString().split('\n'); |
| 25 | + buffer[0] += lines.shift(); |
| 26 | + buffer.push(...lines); |
| 27 | + while (buffer.length > 1) { |
| 28 | + f(buffer.shift(), true); |
| 29 | + } |
| 30 | + flush(); |
| 31 | + }; |
| 32 | + }, |
| 33 | + |
| 34 | + time(desc, p) { |
| 35 | + const s = () => new Date().getTime()/1000; |
| 36 | + const t = s(); |
| 37 | + p.then(() => console.log(`${desc}: ${(s()-t).toFixed(2)}s`)) |
| 38 | + .catch(()=>{}); |
| 39 | + return p; |
| 40 | + }, |
| 41 | + |
| 42 | + hook(obj, method, f) { |
| 43 | + const souper = obj[method].bind(obj); |
| 44 | + return obj[method] = (...a) => f(souper, ...a); |
| 45 | + }, |
| 46 | + |
| 47 | + once(f) { |
| 48 | + let done = false; |
| 49 | + return function(...args) { |
| 50 | + if (done) { return; } |
| 51 | + done = true; |
| 52 | + return f.call(this, ...args); |
| 53 | + }; |
| 54 | + }, |
| 55 | + |
| 56 | + mutex() { |
| 57 | + let wait = Promise.resolve(); |
| 58 | + return function(f) { |
| 59 | + const current = wait; |
| 60 | + let release = null; |
| 61 | + wait = new Promise(resolve => release = resolve).catch(function() {}); |
| 62 | + return current.then(() => f.call(this, release)); |
| 63 | + }; |
| 64 | + }, |
| 65 | + |
| 66 | + exclusive(f) { |
| 67 | + const lock = module.exports.mutex(); |
| 68 | + return function(...args) { |
| 69 | + return lock(release => { |
| 70 | + const result = f.call(this, ...args); |
| 71 | + release(result); |
| 72 | + return result; |
| 73 | + }); |
| 74 | + }; |
| 75 | + }, |
| 76 | + |
| 77 | + // takes a time period in seconds and formats it as hh:mm:ss |
| 78 | + formatTimePeriod(dt) { |
| 79 | + if (dt <= 1) { return; } |
| 80 | + const h = Math.floor(dt/(60*60)); |
| 81 | + const m = Math.floor((dt -= h*60*60)/60); |
| 82 | + const s = Math.round((dt - (m*60))); |
| 83 | + const parts = [h, m, s]; |
| 84 | + for (let i in parts) { |
| 85 | + dt = parts[i]; |
| 86 | + parts[i] = dt < 10 ? `0${dt}` : `${dt}`; |
| 87 | + } |
| 88 | + return parts.join(':'); |
| 89 | + } |
| 90 | +}; |
0 commit comments