// Result-or-Promise helpers export type RP = T | Promise; // Returns true when v is a Promise or a has a then function. export function isPromise(v: RP): v is Promise { return v !== null && typeof v === "object" && typeof (v as any).then === "function"; } export function rpThen(v: RP, f: (a: A) => RP): RP { return isPromise(v) ? (v as Promise).then(f) : f(v as A); } /** * Collect an array of Result-or-Promise values into a single array * avoiding Promise allocation when all inputs are synchronous. */ export function rpAll(arr: RP[]): RP { let hasPromise = false; for (let i = 0; i < arr.length; i++) { if (isPromise(arr[i])) { hasPromise = true; break; } } if (!hasPromise) { // All sync values: return as-is return arr as T[]; } // At least one Promise: allocate a new array const out = new Array>(arr.length); for (let i = 0; i < arr.length; i++) { out[i] = arr[i] as any; } return Promise.all(out as Promise[]); }