@beaker/core
Version:
Beaker browser's core software
102 lines (87 loc) • 2.69 kB
JavaScript
const moment = require('moment')
const {TimeoutError} = require('beaker-error-constants')
moment.updateLocale('en', {
relativeTime: {s: 'seconds'}
})
exports.niceDate = function (ts, opts) {
const endOfToday = moment().endOf('day')
if (typeof ts === 'number' || ts instanceof Date) { ts = moment(ts) }
if (ts.isSame(endOfToday, 'day')) {
if (opts && opts.noTime) { return 'today' }
return ts.fromNow()
} else if (ts.isSame(endOfToday.subtract(1, 'day'), 'day')) { return 'yesterday' } else if (ts.isSame(endOfToday, 'month')) { return ts.fromNow() }
return ts.format('ll')
}
exports.downloadTimestamp = function (ts) {
if (typeof ts === 'string') {
ts = moment(Number(ts))
} else if (typeof ts === 'number') {
ts = moment(ts)
}
return moment(ts).local().format('ddd MMM D, h:mma')
}
// this is a wrapper for any behavior that needs to maintain a timeout
// you call it like this:
/*
timer(30e3, async (checkin, pause, resume) => {
checkin('doing work')
await work()
checkin('doing other work')
await otherWork()
pause() // dont count this period against the timeout
await askUserSomething()
resume() // resume the timeout
checkin('finishing')
return finishing()
})
*/
// Rules of usage:
// - Call `checkin` after a period of async work to give the timer a chance to
// abort further work. If the timer has expired, checkin() will stop running.
// - Give `checkin` a description of the task if you want the timeouterror to be
// descriptive.
exports.timer = function (ms, fn) {
var currentAction
var isTimedOut = false
// no timeout?
if (!ms) return fn(noop, noop, noop)
return new Promise((resolve, reject) => {
var timer
var remaining = ms
var start
const checkin = action => {
if (isTimedOut) throw new TimeoutError() // this will abort action, but the wrapping promise is already rejected
if (action) currentAction = action
}
const pause = () => {
clearTimeout(timer)
remaining -= (Date.now() - start)
}
const resume = () => {
if (isTimedOut) return
clearTimeout(timer)
start = Date.now()
timer = setTimeout(onTimeout, remaining)
}
const onTimeout = () => {
isTimedOut = true
reject(new TimeoutError(currentAction ? `Timed out while ${currentAction}` : undefined))
}
// call the fn to get the promise
var promise = fn(checkin, pause, resume)
// start the timer
resume()
// wrap the promise
promise.then(
val => {
clearTimeout(timer)
resolve(val)
},
err => {
clearTimeout(timer)
reject(err)
}
)
})
}
function noop () {}