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; timeout?: NodeJS.Timeout; stop: boolean; clear(): Promise | 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, 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; }