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