/**
 * src/compute/with-compute.ts
 *
 * Public `withCompute()` API — caller-explicit strategy entry point.
 *
 * Contract (Sprint A):
 * - Strategy is REQUIRED and explicit (no auto-routing).
 * - Returns `StrategyResult<O>` whose `metadata.strategy` equals the strategy's `name`.
 * - Pre-flight guards run BEFORE invoking the generator:
 *     1. `strategy` must be a non-null object with a usable `run` function.
 *     2. `budget.maxCalls === 0` → throw `BudgetExhaustedError`.
 *     3. `deadline` already past → throw `DeadlineExceededError`.
 *     4. `signal` already aborted → throw the signal's `reason` (DOMException 'AbortError' by default).
 * - Generator rejections bubble up unchanged.
 */
// ---------------------------------------------------------------------------
// Errors
// ---------------------------------------------------------------------------
export class InvalidStrategyError extends Error {
    name = "InvalidStrategyError";
    constructor(message = "withCompute: `strategy` is required and must implement Strategy<I,O>") {
        super(message);
    }
}
export class BudgetExhaustedError extends Error {
    name = "BudgetExhaustedError";
    constructor(message = "withCompute: budget exhausted (maxCalls=0)") {
        super(message);
    }
}
export class DeadlineExceededError extends Error {
    name = "DeadlineExceededError";
    constructor(message = "withCompute: deadline exceeded before invocation") {
        super(message);
    }
}
// ---------------------------------------------------------------------------
// Implementation
// ---------------------------------------------------------------------------
function isStrategyLike(value) {
    if (value === null || typeof value !== "object")
        return false;
    const v = value;
    return typeof v.name === "string" && typeof v.run === "function";
}
/**
 * Run a compute task under an explicit strategy with pre-flight budget/deadline/abort guards.
 */
export async function withCompute(input, options) {
    // Guard 1: strategy must be valid (runtime guard for JS callers).
    if (!options || !isStrategyLike(options.strategy)) {
        throw new InvalidStrategyError();
    }
    // Guard 2: budget zero → halt before any work.
    if (options.budget?.maxCalls === 0) {
        throw new BudgetExhaustedError();
    }
    // Guard 3: deadline already past.
    if (typeof options.deadline === "number" && Date.now() >= options.deadline) {
        throw new DeadlineExceededError();
    }
    // Guard 4: abort signal already triggered.
    if (options.signal?.aborted) {
        throw options.signal.reason ?? new DOMException("Aborted", "AbortError");
    }
    const ctx = options.signal ? { signal: options.signal } : {};
    return options.strategy.run(input, options.generator, ctx);
}
//# sourceMappingURL=with-compute.js.map