/** * `work`, or a rejection named TimeoutError once `ms` has passed. An abort signal reaches a request only once * fetch starts; the session token and the device proof are awaited before that, so a deadline on the whole * promise is what bounds a read. An answer after it is dropped. */ export const withinDeadline = (work: Promise, ms: number | undefined, what = 'read'): Promise => { if (ms === undefined) return work; return new Promise((resolve, reject) => { const timer = setTimeout(() => reject(Object.assign(new Error(`${what} timed out`), { name: 'TimeoutError' })), ms); work.then( (value) => { clearTimeout(timer); resolve(value); }, (error) => { clearTimeout(timer); reject(error); }, ); }); };