diff --git a/utils/time.ts b/utils/time.ts index d1b823d..9fbbd4f 100644 --- a/utils/time.ts +++ b/utils/time.ts @@ -1,6 +1,56 @@ import { agentContext } from "./agentContext.ts"; import { Temporal } from "@js-temporal/polyfill"; +/** + * Parse a time string with unit suffix or raw milliseconds + * @param value - Time string like "10s", "90m", "3h" or raw milliseconds + * @returns Time in milliseconds + * @example + * parseTimeValue("10s") // → 10000 + * parseTimeValue("90m") // → 5400000 + * parseTimeValue("3h") // → 10800000 + * parseTimeValue("5400000") // → 5400000 (backward compat) + * parseTimeValue(10000) // → 10000 (already a number) + */ +function parseTimeValue(value: string | number | undefined): number { + if (value === undefined || value === "") { + throw new Error("Time value is required"); + } + + if (typeof value === "number") { + return value; + } + + const match = value.trim().match(/^(\d+(?:\.\d+)?)\s*(s|m|h|ms)?$/i); + + if (!match) { + throw new Error( + `Invalid time format: "${value}". Expected: "10s", "90m", "3h", or raw milliseconds`, + ); + } + + const [, numStr, unit] = match; + const num = parseFloat(numStr); + + if (isNaN(num) || num < 0) { + throw new Error(`Time value must be a positive number: "${value}"`); + } + + switch (unit?.toLowerCase()) { + case "s": + return msFrom.seconds(num); + case "m": + return msFrom.minutes(num); + case "h": + return msFrom.hours(num); + case "ms": + case undefined: + return num; + default: + throw new Error(`Invalid unit: "${unit}". Use s/m/h/ms`); + } +} + /** * Convert time units to milliseconds */ @@ -20,6 +70,12 @@ export const msFrom = { * @param h - number of hours */ hours: (hours: number): number => hours * 60 * 60 * 1000, + /** + * Parse a time string with unit suffix (e.g., "10s", "90m", "3h") or raw milliseconds + * @param value - Time string or number + * @returns Time in milliseconds + */ + parse: parseTimeValue, }; /**