{"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 {effectiveDue, isRetryable} from './helpers.ts';\nexport function run(payload: any, policy: any): any {\n  const now = payload.now;\n  const jobs = payload.jobs || [];\n  const dedupField = policy.dedup_key;\n  const selectedByKey = new Map<any, any>();\n  for (let i = 0; i < jobs.length; i++) {\n    const job = jobs[i];\n    const dedupValue = job[dedupField];\n    selectedByKey.set(dedupValue, {job: job, index: i});\n  }\n  const selected: any[] = Array.from(selectedByKey.values());\n  selected.sort((a: any, b: any) => a.index - b.index);\n  const readyItems: any[] = [];\n  const waiting: any[] = [];\n  const deadItems: any[] = [];\n  const cancelled: any[] = [];\n  for (const item of selected) {\n    const job = item.job;\n    const retryable = isRetryable(job, policy);\n    if (job.cancelled && (policy.cancel_wins || !retryable)) {\n      cancelled.push({id: job.id, index: item.index});\n      continue;\n    }\n    const age = now - job.created;\n    const stale = policy.stale_inclusive ? age >= policy.stale_after : age > policy.stale_after;\n    const nonretryableFailure = job.last_code !== 0 && !retryable;\n    if (stale || job.attempt >= policy.max_attempts || nonretryableFailure) {\n      deadItems.push({id: job.id, index: item.index});\n      continue;\n    }\n    const due = effectiveDue(job, policy, retryable);\n    if (due > now) {\n      waiting.push({id: job.id, at: due, index: item.index});\n    } else {\n      readyItems.push({id: job.id, priority: job.priority, created: job.created, index: item.index});\n    }\n  }\n  readyItems.sort((a: any, b: any) => {\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  if (policy.dead_order === 'id') {\n    deadItems.sort((a: any, b: any) => {\n      if (typeof a.id === 'number' && typeof b.id === 'number') return a.id - b.id;\n      const as = String(a.id);\n      const bs = String(b.id);\n      if (as < bs) return -1;\n      if (as > bs) return 1;\n      return a.index - b.index;\n    });\n  } else {\n    deadItems.sort((a: any, b: any) => a.index - b.index);\n  }\n  waiting.sort((a: any, b: any) => a.index - b.index);\n  cancelled.sort((a: any, b: any) => a.index - b.index);\n  return {ready: readyItems.map((x: any) => x.id), waiting: waiting.map((x: any) => ({id: x.id, at: x.at})), dead: deadItems.map((x: any) => x.id), cancelled: cancelled.map((x: any) => x.id)};\n}\n", "policy.ts": "export const POLICY: any = {base_delay: 200, exponential: false, max_attempts: 4, retryable_codes: [408, 503], cancel_wins: false, dedup_key: 'key', fifo_ties: false, priority_high_first: false, dead_order: 'input', delay_cap: 400, stale_after: 2000, stale_inclusive: false};\n", "helpers.ts": "export function isRetryable(job: any, policy: any): boolean {\n  return Array.isArray(policy.retryable_codes) && policy.retryable_codes.indexOf(job.last_code) !== -1;\n}\nexport function effectiveDue(job: any, policy: any, retryable: boolean): number {\n  if (!retryable || job.last_code === 0) return job.due;\n  const factor = policy.exponential ? Math.pow(2, Math.max(0, job.attempt - 1)) : 1;\n  const delay = Math.min(policy.base_delay * factor, policy.delay_cap);\n  const retryAt = job.failed_at + delay;\n  return Math.max(job.due, retryAt);\n}\n"}}