voicemail-ticketizer/src/util.ts

74 lines
1.8 KiB
TypeScript
Raw Normal View History

2021-03-10 21:59:38 -07:00
import PhoneNumber from "awesome-phonenumber";
export function getNationalNumber(input: string) {
const number = new PhoneNumber(input);
if (!number.isValid()) {
throw new Error(`Invalid number: ${input}`);
}
return number.getNumber("national");
}
export function formatSeconds(input: number) {
const minutes = String(Math.trunc(input / 60)).padStart(2, "0");
const seconds = String(input % 60).padStart(2, "0");
return `${minutes}:${seconds}`;
}
type AsyncInterval = {
promise?: Promise<any>;
timeout?: NodeJS.Timeout;
stop: boolean;
clear(): Promise<any> | undefined;
};
/**
* Similar to setInterval, except the next execution of `cb` will not happen
* until `interval` ms after the Promise returned by `cb` has settled.
*
* @param cb a callback which returns a Promise
* @param interval ms delay between executions of cb
* @param immediate whether to do an immediate execution of cb (don't first
* wait for interval)
*
* @returns an AsyncInterval object which tracks the state of the interval,
* and provides a clear() method to clear it similar to clearInterval
*/
export function setAsyncInterval(
cb: () => Promise<any>,
interval: number,
immediate = false
) {
const asyncInterval: AsyncInterval = {
stop: false,
clear() {
this.stop = true;
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = undefined;
}
return this.promise;
},
};
function refreshTimeout() {
if (!asyncInterval.stop) {
asyncInterval.timeout = setTimeout(run, interval);
}
}
function run() {
const promise = cb();
asyncInterval.promise = promise;
promise.finally(refreshTimeout);
return promise;
}
if (immediate) {
asyncInterval.promise = cb().finally(refreshTimeout);
} else {
refreshTimeout();
}
return asyncInterval;
}