{"files": {"main.ts": "import {run} from './core.ts';\nimport {POLICY} from './policy.ts';\nexport function evaluate(payload: any): any { return run(payload, POLICY); }\n", "core.ts": "import {computeEffectiveDue, isRetryable, isStale} from './helpers.ts';\nexport function run(payload: any, policy: any): any {\n  const now: number = payload.now;\n  const jobs: any[] = Array.isArray(payload.jobs) ? payload.jobs : [];\n  const dedup = new Map<any, {job: any, index: number}>();\n  jobs.forEach((job: any, index: number) => {\n    dedup.set(job[policy.dedup_key], {job, index});\n  });\n  const selected = Array.from(dedup.values()).sort((a, b) => a.index - b.index);\n  const ready: {id: any, priority: number, created: number, index: number}[] = [];\n  const waiting: {id: any, at: number, index: number}[] = [];\n  const dead: {id: any, index: number}[] = [];\n  const cancelled: {id: any, index: number}[] = [];\n  for (const {job, index} of selected) {\n    const retryable = isRetryable(job, policy);\n    if (job.cancelled && (policy.cancel_wins || !retryable)) {\n      cancelled.push({id: job.id, index});\n      continue;\n    }\n    const stale = isStale(now, job.created, policy);\n    const nonretryableFailure = job.last_code !== 0 && !retryable;\n    if (stale || job.attempt >= policy.max_attempts || nonretryableFailure) {\n      dead.push({id: job.id, index});\n      continue;\n    }\n    const due = computeEffectiveDue(job, policy, retryable);\n    if (due > now) {\n      waiting.push({id: job.id, at: due, index});\n    } else {\n      ready.push({id: job.id, priority: job.priority, created: job.created, index});\n    }\n  }\n  ready.sort((a, b) => {\n    const priorityDiff = policy.priority_high_first ? b.priority - a.priority : a.priority - b.priority;\n    if (priorityDiff !== 0) return priorityDiff;\n    const createdDiff = policy.fifo_ties ? a.created - b.created : b.created - a.created;\n    if (createdDiff !== 0) return createdDiff;\n    return a.index - b.index;\n  });\n  dead.sort((a, b) => {\n    if (policy.dead_order === 'id') {\n      if (a.id < b.id) return -1;\n      if (a.id > b.id) return 1;\n      return a.index - b.index;\n    }\n    return a.index - b.index;\n  });\n  waiting.sort((a, b) => a.index - b.index);\n  cancelled.sort((a, b) => a.index - b.index);\n  return {\n    ready: ready.map((entry) => entry.id),\n    waiting: waiting.map((entry) => ({id: entry.id, at: entry.at})),\n    dead: dead.map((entry) => entry.id),\n    cancelled: cancelled.map((entry) => entry.id)\n  };\n}\n", "policy.ts": "export const POLICY: any = {\"base_delay\": 100, \"exponential\": true, \"max_attempts\": 3, \"retryable_codes\": [429, 500], \"cancel_wins\": true, \"dedup_key\": \"id\", \"fifo_ties\": true, \"priority_high_first\": true, \"dead_order\": \"id\", \"delay_cap\": 150, \"stale_after\": 1000, \"stale_inclusive\": true};\n", "helpers.ts": "export function isRetryable(job: any, policy: any): boolean {\n  return Array.isArray(policy.retryable_codes) && policy.retryable_codes.includes(job.last_code);\n}\nexport function isStale(now: number, created: number, policy: any): boolean {\n  const age = now - created;\n  return policy.stale_inclusive ? age >= policy.stale_after : age > policy.stale_after;\n}\nexport function computeEffectiveDue(job: any, policy: any, retryable: boolean): number {\n  if (!retryable || job.last_code === 0) return job.due;\n  const factor = policy.exponential ? 2 ** Math.max(0, job.attempt - 1) : 1;\n  const delay = Math.min(policy.base_delay * factor, policy.delay_cap);\n  return Math.max(job.due, job.failed_at + delay);\n}\n"}}