UNPKG

@unito/integration-sdk

Version:

Integration SDK

59 lines (45 loc) 1.79 kB
import { TimeoutError } from '../httpErrors.js'; export class OperationDeadline { /** Absolute deadline, epoch ms — or Infinity when no header was sent. */ readonly deadlineTimestamp: number; /** The AbortSignal that fires at the deadline. Pass THIS to fetch/provider calls. */ readonly signal: AbortSignal; /** @param header deadline timestamp in milliseconds from Epoch, or undefined */ private constructor(deadlineInMs: number | undefined) { if (!deadlineInMs) { this.deadlineTimestamp = Infinity; this.signal = new AbortController().signal; // never fires return; } this.deadlineTimestamp = deadlineInMs; const remaining = this.deadlineTimestamp - Date.now(); if (remaining <= 0) { throw new TimeoutError('Request already timed out upon reception'); } this.signal = AbortSignal.timeout(remaining); } /** @param header raw X-Unito-Operation-Deadline value (Unix seconds), or undefined */ static fromHeader(deadlineInSeconds: string | number | undefined): OperationDeadline { let timestamp = undefined; const seconds = Number(deadlineInSeconds); if (seconds) { timestamp = seconds * 1000; } return new OperationDeadline(timestamp); } static never() { return new OperationDeadline(undefined); } /** @param deadlineInMs absolute deadline timestamp in epoch milliseconds */ static fromMs(deadlineInMs: number): OperationDeadline { return new OperationDeadline(deadlineInMs); } /** Fresh ms left until the deadline (≤0 = past, Infinity = no deadline). */ timeRemaining(): number { return this.deadlineTimestamp - Date.now(); } /** Computes if the deadline was reached or not */ hasPassed(): boolean { return this.timeRemaining() <= 0; } }