@cronwatch/sdk 0.14.2 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/duration.ts","../src/env.ts","../src/schedule.ts","../src/stats.ts","../src/evaluate.ts","../src/format.ts","../src/http.ts","../src/output.ts","../src/job.ts","../src/serialize.ts","../src/routes/escape.ts","../src/routes/icons.ts","../src/routes/pwa.ts","../src/version.ts","../src/routes/timeline.ts","../src/routes/html.ts","../src/routes/index.ts","../src/stores/memory.ts","../src/client.ts","../src/index.ts"],"names":["Cron","after","graceMs","words","json","tail","when","times","t","r","cache","newest"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Duration } from \"./types.js\";\n\nconst UNIT_MS: Record<string, number> = {\n ms: 1,\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n};\n\n/**\n * The longest duration string read, in characters (code points). No real\n * duration comes near it, and the pattern below is quadratic on a long run of\n * digits, so a longer string is refused before it is read.\n */\nconst MAX_LENGTH = 64;\n/** How much of a refused, overlong string its error quotes. */\nconst QUOTED = 32;\n\n/**\n * \"15m\" -> 900000. Accepts a plain number of milliseconds, and compound\n * strings such as \"1h30m\". Whitespace between parts is fine.\n */\nexport function parseDuration(value: Duration, label = \"duration\"): number {\n if (typeof value === \"number\") {\n if (!Number.isFinite(value) || value < 0) throw new Error(`${label} must be a non-negative number of milliseconds`);\n return value;\n }\n if (value.length > MAX_LENGTH) tooLong(value, label);\n const text = value.trim().toLowerCase();\n if (text === \"\") throw new Error(`${label} is empty`);\n const re = /(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d|w)/g;\n let total = 0;\n let consumed = \"\";\n let match: RegExpExecArray | null;\n while ((match = re.exec(text)) !== null) {\n total += parseFloat(match[1]!) * UNIT_MS[match[2]!]!;\n consumed += match[0];\n }\n if (consumed.replace(/\\s+/g, \"\") !== text.replace(/\\s+/g, \"\")) {\n throw new Error(`${label} \"${value}\" is not a duration like \"15m\", \"1h30m\", or \"90s\"`);\n }\n return Math.round(total);\n}\n\n/** Throws if `value` is over MAX_LENGTH characters, quoting the first QUOTED. */\nfunction tooLong(value: string, label: string): void {\n let count = 0;\n let head = \"\";\n for (const char of value) {\n if (count < QUOTED) head += char;\n if (++count > MAX_LENGTH) {\n throw new Error(`${label} \"${head}...\" is too long for a duration (more than ${MAX_LENGTH} characters)`);\n }\n }\n}\n\n/** 90000 -> \"1m 30s\". For messages, not for parsing back. */\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms)) return \"?\";\n if (ms < 1000) return `${Math.round(ms)}ms`;\n const parts: string[] = [];\n let rest = Math.round(ms / 1000);\n const units: [string, number][] = [[\"d\", 86_400], [\"h\", 3_600], [\"m\", 60], [\"s\", 1]];\n for (const [unit, size] of units) {\n if (rest >= size) {\n const n = Math.floor(rest / size);\n rest -= n * size;\n parts.push(`${n}${unit}`);\n }\n if (parts.length === 2) break;\n }\n return parts.join(\" \") || \"0s\";\n}\n\n/** \"5 minutes ago\", \"in 2h\". Relative to `now`. */\nexport function formatRelative(at: number, now: number): string {\n const diff = at - now;\n const abs = Math.abs(diff);\n const text = abs < 5_000 ? \"now\" : formatDuration(abs);\n if (abs < 5_000) return text;\n return diff < 0 ? `${text} ago` : `in ${text}`;\n}\n\n/** The first millisecond written as a date: 0001-01-01T00:00:00.000Z. */\nexport const FIRST_DATE_MS = -62_135_596_800_000;\n/** The last millisecond written as a date: 9999-12-31T23:59:59.999Z. */\nexport const LAST_DATE_MS = 253_402_300_799_999;\n\n/**\n * \"2026-01-05T09:30:00.000Z\", or null for a time before the year 1 or after\n * 9999. A start read from another process's row, or a damaged one, can be\n * any number; outside those years it is not written as a date at all (and\n * past JavaScript's Date range, toISOString would throw).\n */\nexport function isoTime(at: number): string | null {\n return at >= FIRST_DATE_MS && at <= LAST_DATE_MS ? new Date(at).toISOString() : null;\n}\n\n/** The words that stand in for a time isoTime() does not write: \"before 0001-01-01 00:00:00 UTC\" or \"after 9999-12-31 23:59:59 UTC\". */\nexport function beyondDates(at: number): string {\n return at > LAST_DATE_MS ? \"after 9999-12-31 23:59:59 UTC\" : \"before 0001-01-01 00:00:00 UTC\";\n}\n","/**\n * Environment variables, read only where there is a `process` to read them\n * from. Cloudflare Workers without nodejs_compat have none: there every value\n * comes from the options, which is where a Worker passes its env bindings.\n */\nexport function readEnv(name: string): string | undefined {\n return typeof process === \"undefined\" || !process.env ? undefined : process.env[name];\n}\n\n/**\n * A secret from the environment (CRONWATCH_TOKEN, CRON_SECRET), trimmed (as\n * String.prototype.trim trims): a value read from a file often ends in a\n * newline that no header can carry, since HTTP strips the whitespace around\n * a header's value. Undefined when the variable is unset, empty, or only\n * whitespace, so a blank value counts as not set and the routes and handlers\n * fail closed.\n */\nexport function readSecretEnv(name: string): string | undefined {\n const value = readEnv(name)?.trim();\n return value === undefined || value === \"\" ? undefined : value;\n}\n\n/**\n * A token or secret passed in code: a string, null (the opt-out), or\n * undefined (not given). A string is trimmed, as readSecretEnv() trims, and\n * one that is empty or only whitespace counts as not given. Anything else\n * (false, a number, an object) throws a TypeError naming the option, so it\n * never becomes a password.\n */\nexport function secretOption(value: unknown, what: string): string | null | undefined {\n if (value === undefined || value === null) return value;\n if (typeof value !== \"string\") {\n throw new TypeError(`${what} must be a string, or null to opt out, not ${Array.isArray(value) ? \"an array\" : typeof value}`);\n }\n const trimmed = value.trim();\n return trimmed === \"\" ? undefined : trimmed;\n}\n\n/**\n * The environment's name from the values of the variables that name it, in\n * order, as every CronWatch library reads it: the first that holds more than\n * whitespace, trimmed and lowercased, with \"prod\" read as \"production\" and\n * \"dev\" and \"local\" as \"development\"; \"\" when none is set. \"test\" and\n * \"testing\" are not development: a test run or CI needs CRON_SECRET or a\n * token, as production does.\n */\nexport function environmentOf(values: readonly (string | undefined)[]): string {\n for (const value of values) {\n const name = typeof value === \"string\" ? value.trim().toLowerCase() : \"\";\n if (name === \"\") continue;\n if (name === \"prod\") return \"production\";\n if (name === \"dev\" || name === \"local\") return \"development\";\n return name;\n }\n return \"\";\n}\n\n/**\n * The environment's name (environmentOf) from CRONWATCH_ENV, APP_ENV, and\n * NODE_ENV. The variables are written out in full so that bundlers which\n * inline process.env.NODE_ENV still can.\n */\nexport function environment(): string {\n if (typeof process === \"undefined\" || !process.env) return \"\";\n return environmentOf([process.env.CRONWATCH_ENV, process.env.APP_ENV, process.env.NODE_ENV]);\n}\n\n/** Development makes a dashboard token of its own and lets a handler with no secret run. */\nexport function isDevelopment(): boolean {\n return environment() === \"development\";\n}\n\n/** Production warns that the default in-memory store forgets on restart. */\nexport function isProduction(): boolean {\n return environment() === \"production\";\n}\n","import { Cron } from \"croner\";\nimport { FIRST_DATE_MS, LAST_DATE_MS, parseDuration } from \"./duration.js\";\n\nexport interface ParsedSchedule {\n kind: \"cron\" | \"interval\";\n source: string;\n /** The IANA timezone a cron is read in, when one was given. */\n timezone?: string;\n /** For intervals, the period in milliseconds. */\n everyMs?: number;\n}\n\nconst cache = new Map<string, ParsedSchedule>();\n/** The croner instance behind each cron schedule, kept out of the public type. */\nconst crons = new WeakMap<ParsedSchedule, Cron>();\n/** Cron schedules that name a date no month has, which never fire. */\nconst never = new WeakSet<ParsedSchedule>();\n\n/** Where neverFires() looks from: croner looks up to the year 3000, more than a 400-year cycle of the calendar. */\nconst PROBE_FROM_MS = Date.UTC(2000, 0, 1);\n\n/**\n * Whether a cron never fires: it names a date no month has, such as\n * \"0 0 30 2 *\". croner walks to such a date by recursion, a year at a time,\n * so it answers that there is none, or runs out of stack first (from further\n * back, or over several months); either way the schedule never fires, and is\n * then never asked again. Anything else croner throws here (a timezone it\n * cannot use) is left to the calls that compute fire times, as before.\n */\nfunction neverFires(cron: Cron): boolean {\n try {\n return cron.nextRuns(1, new Date(PROBE_FROM_MS)).length === 0;\n } catch (error) {\n return error instanceof RangeError && /call stack/i.test(error.message);\n }\n}\n\n/** Text that starts like an ISO date and time, which croner would take for a one-time date. */\nconst ONE_TIME_DATE = /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}/;\n\n/** How early a run may start and still count for the fire it was meant for. */\nexport const EARLY_SLACK_MS = 60_000;\n\n/**\n * \"0 2 * * *\" (cron, five or six fields), \"@hourly\", or \"every 5m\".\n * Text with a colon after its first character, which croner would take for\n * a one-time date, is refused. A cron that names a date no month has\n * (\"0 0 30 2 *\") is read, and never fires: nothing is ever due, so it is\n * never missed. Parsed once per (schedule, timezone) pair and cached. The\n * croner instance gets no callback, so it schedules nothing; it is only used\n * to compute fire times. Without a timezone the expression is read in the process timezone,\n * like crontab. Vercel and GitHub Actions run their crons in UTC, so pass\n * timezone: \"UTC\" for those.\n */\nexport function parseSchedule(schedule: string, timezone?: string): ParsedSchedule {\n const key = `${timezone ?? \"\"}|${schedule}`;\n const hit = cache.get(key);\n if (hit) return hit;\n\n const text = schedule.trim();\n const every = /^every\\s+(.+)$/i.exec(text);\n let parsed: ParsedSchedule;\n if (every) {\n const everyMs = parseDuration(every[1]!, \"schedule interval\");\n if (everyMs < 1000) throw new Error(`schedule \"${schedule}\" is shorter than one second`);\n parsed = { kind: \"interval\", source: text, everyMs };\n } else {\n // croner reads text with a colon after its first character as a one-time\n // date to fire at (through Date.parse, which reads almost anything), not\n // as a cron expression. A cron monitor has no use for one, so every such\n // text is refused, as in every port.\n if (text.slice(1).includes(\":\")) {\n const reason = ONE_TIME_DATE.test(text) ? \"CronPattern: a one-time date is not supported\" : \"Invalid ISO8601 passed to timezone parser.\";\n throw new Error(`schedule \"${schedule}\" is not a cron expression or \"every <duration>\": ${reason}`);\n }\n let cron: Cron;\n try {\n cron = new Cron(text, timezone ? { timezone } : {});\n } catch (error) {\n throw new Error(`schedule \"${schedule}\" is not a cron expression or \"every <duration>\": ${(error as Error).message}`);\n }\n parsed = { kind: \"cron\", source: text, ...(timezone ? { timezone } : {}) };\n crons.set(parsed, cron);\n if (neverFires(cron)) never.add(parsed);\n }\n cache.set(key, parsed);\n return parsed;\n}\n\n/**\n * Four hundred Gregorian years: 146,097 days, a whole number of weeks, after\n * which the calendar repeats date for date and weekday for weekday.\n */\nconst CYCLE_MS = 146_097 * 86_400_000;\n/** croner misreads a year below 100 as 1900 plus it, so earlier times are asked a cycle or more later. */\nconst CRONER_FIRST_MS = Date.UTC(400, 0, 1);\n/** croner finds no fire past the year 3000, so later times are asked a cycle or more earlier. */\nconst CRONER_LAST_MS = Date.UTC(2800, 0, 1);\n\n/**\n * The next `n` fires of a cron strictly after `from`, which lies within the\n * years 1 to 9999, dropping any after 9999. A time croner cannot answer for\n * is moved by whole 400-year cycles into the years it can, and its fires\n * moved back: a time before 400 goes forward, into the same local mean time\n * every zone kept then, and one from 2800 goes back, to where the zone's\n * present rules already hold.\n */\nfunction runsAfter(cron: Cron, n: number, from: number): number[] {\n let shift = 0;\n if (from < CRONER_FIRST_MS) shift = Math.ceil((CRONER_FIRST_MS - from) / CYCLE_MS) * CYCLE_MS;\n else if (from >= CRONER_LAST_MS) shift = -(Math.floor((from - CRONER_LAST_MS) / CYCLE_MS) + 1) * CYCLE_MS;\n const out: number[] = [];\n for (const date of cron.nextRuns(n, new Date(from + shift))) {\n const t = date.getTime() - shift;\n if (t > LAST_DATE_MS) break;\n out.push(t);\n }\n return out;\n}\n\n/**\n * A stored time as a cron's fires are counted from it. A start read from a\n * foreign or damaged row can be any number: one before the year 1 counts\n * from just before its first millisecond, so the first fire of the year 1 is\n * the next one, and one at or after the last millisecond of 9999 has no\n * fire after it at all (null). No fire is ever after 9999.\n */\nfunction countFrom(from: number): number | null {\n if (from >= LAST_DATE_MS) return null;\n return from >= FIRST_DATE_MS ? from : FIRST_DATE_MS - 1;\n}\n\n/**\n * The first fire strictly after `from`, or null when the cron never fires\n * again. On the night clocks spring forward every slot the pattern names\n * still fires: one whose local time the jump skips is moved forward by the\n * gap's length (see springGap and gapFireAfter), so the fires stay strictly\n * ascending whichever instant they are counted from.\n */\nfunction fireAfter(parsed: ParsedSchedule, from: number): number | null {\n const found = croneFireAfter(parsed, from);\n const start = countFrom(from);\n if (start === null) return found;\n const moved = gapFireAfter(parsed, start);\n return moved !== null && (found === null || moved < found) ? moved : found;\n}\n\n/**\n * The first fire strictly after `from` as croner counts it, or null when\n * the cron never fires again. croner answers with times in the past when\n * asked from inside the hour that repeats when clocks go back, so its\n * answers are filtered, and a stretch of nothing but past times is stepped\n * over an hour at a time. Asked from inside a spring-forward gap it skips\n * the slots moved out of it, which fireAfter adds back.\n */\nfunction croneFireAfter(parsed: ParsedSchedule, from: number): number | null {\n const cron = crons.get(parsed);\n if (!cron) throw new Error(`schedule \"${parsed.source}\" was not made by parseSchedule`);\n if (never.has(parsed)) return null;\n const start = countFrom(from);\n if (start === null) return null;\n let probe = start;\n for (let attempt = 0; attempt < 4; attempt++) {\n const runs = runsAfter(cron, 8, probe);\n if (runs.length === 0) return null;\n const found = runs.find((t) => t > start);\n if (found !== undefined) return found;\n probe += 3_600_000;\n }\n return null;\n}\n\n/**\n * The window a spring-forward jump moves skipped slots into, when `at` lies\n * in one: from the jump (`jumpAt`, the first instant on the later offset)\n * for the gap's length (`gapMs`, the later offset less the earlier one, so\n * 30 minutes on Lord Howe Island and an hour in most zones). `beforeMs` is\n * the earlier offset. Null when `at` is not within a gap's length after a\n * jump in the three hours before it.\n */\nexport function springGap(timezone: string | undefined, at: number): { jumpAt: number; gapMs: number; beforeMs: number } | null {\n const jump = springJump(timezone, at);\n return jump && at < jump.jumpAt + jump.gapMs ? jump : null;\n}\n\n/** How far back a spring-forward jump is looked for: more than any gap a zone has had. */\nconst JUMP_LOOKBACK_MS = 3 * 3_600_000;\n\n/**\n * The spring-forward jump in the three hours up to `at`, found to the\n * minute: the first minute on the later offset. Null when the offset at\n * `at` is not ahead of the offset three hours before.\n */\nfunction springJump(timezone: string | undefined, at: number): { jumpAt: number; gapMs: number; beforeMs: number } | null {\n // Every zone kept its local mean time, with no clock change, in the year 1.\n if (at - JUMP_LOOKBACK_MS < FIRST_DATE_MS || at >= LAST_DATE_MS) return null;\n const after = utcOffset(at, timezone);\n const before = utcOffset(at - JUMP_LOOKBACK_MS, timezone);\n if (after <= before) return null;\n let lo = at - JUMP_LOOKBACK_MS;\n let hi = at;\n while (hi - lo > 60_000) {\n const mid = lo + Math.floor((hi - lo) / 2);\n if (utcOffset(mid, timezone) === after) hi = mid;\n else lo = mid;\n }\n return { jumpAt: Math.floor(hi / 60_000) * 60_000, gapMs: after - before, beforeMs: before };\n}\n\n/** The pattern read in UTC, which stands for wall-clock time in gapFireAfter. */\nconst wallCrons = new WeakMap<ParsedSchedule, Cron>();\n\nfunction wallCron(parsed: ParsedSchedule): Cron {\n let wall = wallCrons.get(parsed);\n if (!wall) {\n wall = new Cron(parsed.source, { timezone: \"UTC\" });\n wallCrons.set(parsed, wall);\n }\n return wall;\n}\n\n/**\n * The first slot moved out of a spring-forward gap strictly after `start`,\n * when `start` lies in that gap's window, else null. A slot whose local time\n * the jump skips fires at that local time read on the earlier offset, which\n * is the same as moving it forward by the gap's length: 01:20 on the night\n * London skips 01:00 to 02:00 fires at 02:20 BST (01:20Z). croner moves them\n * the same way when asked from before the jump, but not from inside it.\n */\nfunction gapFireAfter(parsed: ParsedSchedule, start: number): number | null {\n if (never.has(parsed)) return null;\n const gap = springGap(parsed.timezone, start);\n if (!gap) return null;\n const wall = wallCron(parsed);\n // Wall-clock time as if it were UTC: the slots the jump skips run from\n // jumpAt + beforeMs for gapMs.\n const [slot] = runsAfter(wall, 1, start + gap.beforeMs);\n if (slot === undefined || slot >= gap.jumpAt + gap.beforeMs + gap.gapMs) return null;\n return slot - gap.beforeMs;\n}\n\n/**\n * Every fire of a cron strictly after `from` and at or before `to`,\n * ascending, or null when there are more than `limit`: the fires nextFire\n * gives one after another. Asks croner for fires in batches, which is far\n * cheaper than one nextFire per fire, and drops any that do not move forward\n * (the hour that repeats when clocks go back, see croneFireAfter). Around a\n * spring-forward gap, where croner's batch can skip a moved slot or give\n * one out of order, it counts with fireAfter instead.\n */\nexport function firesBetween(parsed: ParsedSchedule, from: number, to: number, limit: number): number[] | null {\n const cron = crons.get(parsed);\n if (!cron) throw new Error(`schedule \"${parsed.source}\" was not made by parseSchedule`);\n if (never.has(parsed)) return [];\n const out: number[] = [];\n const start = countFrom(from);\n if (start === null) return out;\n let probe = start;\n let last = start;\n for (let guard = 0; guard < 1000; guard++) {\n if (springGap(parsed.timezone, last)) {\n // Counting from inside a gap's window: croner would skip its moved slots.\n const t = fireAfter(parsed, last);\n if (t === null || t > to) return out;\n out.push(t);\n last = probe = t;\n if (out.length > limit) return null;\n continue;\n }\n const batch = runsAfter(cron, Math.min(limit + 1 - out.length, 24), probe);\n if (batch.length === 0) return out;\n let stepped = false;\n for (const t of batch) {\n if (t <= last) continue;\n if (springGap(parsed.timezone, t)) {\n // The batch reached a gap's window, where its order is croner's:\n // the next fire is counted from the last one, and the rest with it.\n const next = fireAfter(parsed, last);\n if (next === null || next > to) return out;\n out.push(next);\n last = probe = next;\n if (out.length > limit) return null;\n stepped = true;\n break;\n }\n if (t > to) return out;\n out.push(t);\n last = t;\n if (out.length > limit) return null;\n }\n if (stepped) continue;\n const end = batch[batch.length - 1]!;\n probe = end > probe ? end : probe + 3_600_000;\n }\n return out;\n}\n\n/**\n * The next time the schedule fires strictly after `from`. For an interval,\n * counted from the last run's start when there is one (see intervalDue for\n * a run that outlasted its period).\n */\nexport function nextFire(parsed: ParsedSchedule, from: number, lastRunAt: number | null): number | null {\n if (parsed.kind === \"interval\") {\n const base = lastRunAt ?? from;\n return base + parsed.everyMs!;\n }\n return fireAfter(parsed, from);\n}\n\n/**\n * When an interval of `everyMs` is next due after a run: a period after it\n * started, or, when it finished (`finishedAt` not null) later than that, a\n * period after it finished. A run that outlasts its period is not followed\n * by a missed alert the moment it ends.\n */\nexport function intervalDue(everyMs: number, startedAt: number, finishedAt: number | null): number {\n const due = startedAt + everyMs;\n return finishedAt !== null && finishedAt > due ? finishedAt + everyMs : due;\n}\n\nexport interface Expectation {\n /** When the next run the schedule asks for is due. */\n dueAt: number;\n /** Missed once now passes this. */\n deadline: number;\n}\n\n/**\n * When the schedule next wants a run, given the last one. For a cron that is\n * the first fire the last run does not already cover; with no run yet, the\n * first fire at or after registration. For an interval it is the last run's\n * start (or registration) plus the interval, or its finish plus the interval\n * when it finished (`lastFinishedAt`, null while it runs) later than that\n * (intervalDue). Null for a cron that never fires again.\n *\n * Counting forward from the last run, rather than back from now, is what\n * lets a job whose period is shorter than its grace be missed at all, and it\n * works for a cron that fires once a year or less.\n */\nexport function expectation(\n parsed: ParsedSchedule,\n lastRunAt: number | null,\n registeredAt: number,\n graceMs: number,\n lastFinishedAt: number | null = null,\n): Expectation | null {\n let dueAt: number | null;\n if (parsed.kind === \"interval\") {\n dueAt = lastRunAt === null ? registeredAt + parsed.everyMs! : intervalDue(parsed.everyMs!, lastRunAt, lastFinishedAt);\n } else if (lastRunAt === null) {\n dueAt = fireAfter(parsed, registeredAt - 1);\n } else {\n dueAt = dueAfterRun(parsed, lastRunAt);\n }\n return dueAt === null ? null : { dueAt, deadline: dueAt + graceMs };\n}\n\n/**\n * The first fire that a run starting at `startedAt` does not cover. A start\n * before the year 1 covers none of them, so the first fire of the year 1 is\n * due; after 9999 there is none (see countFrom).\n */\nfunction dueAfterRun(parsed: ParsedSchedule, startedAt: number): number | null {\n // A fire at or before the start is covered by the run itself.\n let next = fireAfter(parsed, startedAt);\n // Bounded: a gap holds at most a few hours of moved slots.\n for (let guard = 0; next !== null && guard < 100_000; guard++) {\n const following = fireAfter(parsed, next);\n const covers = runCovers(startedAt, next, following) || inSpringForwardGap(parsed, startedAt, next);\n if (!covers) return next;\n next = following;\n }\n return next;\n}\n\n/**\n * Whether a run starting at `startedAt` covers the fire at `dueAt`. A minute\n * of slack before the tick absorbs schedulers that fire a touch early. When\n * the fire after `dueAt` is known, the slack is at most half the gap between\n * the two, so one run of an every-minute cron never covers two fires.\n */\nexport function runCovers(startedAt: number, dueAt: number, followingAt: number | null = null): boolean {\n const slack = followingAt === null ? EARLY_SLACK_MS : Math.min(EARLY_SLACK_MS, Math.floor((followingAt - dueAt) / 2));\n return startedAt >= dueAt - slack;\n}\n\n/**\n * On the night clocks spring forward, a slot whose local time does not exist\n * (02:30 when 02:00 jumps to 03:00) fires moved forward by the gap (03:30;\n * see gapFireAfter), while vixie cron runs every skipped job once, at the\n * jump itself (03:00). A run that starts at or after the jump (less a\n * minute of slack), and before such a moved fire, is taken to cover it, so\n * neither scheduler's run is reported as missed. Only a moved slot that is\n * not also a slot of its own on the later offset counts: a cron that fires\n * every 10 minutes moves 02:10 onto its own 03:10, which was not skipped.\n */\nfunction inSpringForwardGap(parsed: ParsedSchedule, startedAt: number, fireAt: number): boolean {\n const gap = springGap(parsed.timezone, fireAt);\n if (!gap || startedAt < gap.jumpAt - EARLY_SLACK_MS || startedAt >= fireAt) return false;\n const wall = wallCron(parsed);\n const fires = (at: number) => runsAfter(wall, 1, at - 1)[0] === at;\n return fires(fireAt + gap.beforeMs) && !fires(fireAt + gap.beforeMs + gap.gapMs);\n}\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\n\n/** Milliseconds the zone's wall clock is ahead of UTC at `at`. */\nfunction utcOffset(at: number, timezone: string | undefined): number {\n const key = timezone ?? \"\";\n let format = formatters.get(key);\n if (!format) {\n format = new Intl.DateTimeFormat(\"en-US\", {\n ...(timezone ? { timeZone: timezone } : {}),\n hourCycle: \"h23\",\n year: \"numeric\", month: \"numeric\", day: \"numeric\", hour: \"numeric\", minute: \"numeric\", second: \"numeric\",\n });\n formatters.set(key, format);\n }\n const parts: Record<string, number> = {};\n for (const part of format.formatToParts(new Date(at))) {\n if (part.type !== \"literal\") parts[part.type] = Number(part.value);\n }\n // Date.UTC would read a year below 100 as 1900 plus it; setUTCFullYear does not.\n const wall = new Date(0);\n wall.setUTCFullYear(parts.year!, parts.month! - 1, parts.day!);\n wall.setUTCHours(parts.hour!, parts.minute!, parts.second!);\n return wall.getTime() - Math.floor(at / 1000) * 1000;\n}\n","export function percentile(values: number[], p: number): number | null {\n if (values.length === 0) return null;\n const sorted = [...values].sort((a, b) => a - b);\n const index = Math.min(sorted.length - 1, Math.max(0, Math.ceil((p / 100) * sorted.length) - 1));\n return sorted[index]!;\n}\n\nexport function median(values: number[]): number | null {\n if (values.length === 0) return null;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n}\n","/**\n * Pure decisions about a job's health. Each function takes the current state\n * and returns the new state plus the alerts that should go out. Nothing here\n * touches a store or a network, which is what makes it testable.\n */\nimport { formatDuration } from \"./duration.js\";\nimport { parseDuration } from \"./duration.js\";\nimport { expectation, nextFire, parseSchedule } from \"./schedule.js\";\nimport { median, percentile } from \"./stats.js\";\nimport type {\n Alert,\n AlertDraft,\n BudgetBreach,\n Condition,\n HeldAlert,\n JobDefinition,\n JobHealth,\n JobState,\n JobSummary,\n Run,\n StoredJob,\n StoredJobDefinition,\n} from \"./types.js\";\n\nexport type { AlertDraft, BudgetBreach };\n\nexport interface Evaluation {\n state: JobState;\n alerts: AlertDraft[];\n}\n\nexport const DEFAULT_GRACE_MS = 10 * 60_000;\nexport const DEFAULT_TIMEOUT_MS = 60 * 60_000;\n/** Runs faster than this are never called slow, whatever the baseline says. */\nexport const SLOW_FLOOR_MS = 10_000;\n/** How many earlier runs a baseline needs before it is trusted. */\nexport const BASELINE_MIN_RUNS = 5;\n/** How many successful runs a baseline looks at, and how many runs a summary covers. */\nexport const BASELINE_WINDOW = 20;\n\n/** The longest duration written: the largest integer JavaScript holds exactly, which every port and store reads back unchanged. */\nexport const MAX_DURATION_MS = Number.MAX_SAFE_INTEGER;\n\n/**\n * How long a run took, from `startedAt` to `finishedAt`: 0 when it started\n * later, and never more than MAX_DURATION_MS. A foreign row's start near a\n * 64-bit limit must not make a duration no store can write.\n */\nexport function runDuration(startedAt: number, finishedAt: number): number {\n const ms = finishedAt - startedAt;\n return ms > 0 ? Math.min(ms, MAX_DURATION_MS) : 0;\n}\n\n/**\n * When a silence of `ms` from `now` ends: a whole millisecond, never past\n * MAX_DURATION_MS (2^53 - 1), however long the silence asked for. Every port\n * sharing the store reads it back unchanged, where a larger number could\n * wrap to a time long past and send alerts during the silence.\n */\nexport function silenceEnd(now: number, ms: number): number {\n return Math.min(now + Math.floor(Math.min(ms, MAX_DURATION_MS)), MAX_DURATION_MS);\n}\n\n/**\n * The version a stored state counts as for compareAndSetState: its\n * `version` when that is a whole number from 0 to MAX_DURATION_MS (2^53 - 1),\n * else 0, as when it is absent. The SQL stores read it the same way, so a\n * foreign row's `1.5`, `\"x\"`, or `-1` is written over by the next update\n * instead of refusing every compare-and-set of its job for good.\n */\nexport function stateVersion(state: Pick<JobState, \"version\"> | null | undefined): number {\n const version: unknown = state?.version;\n return typeof version === \"number\" && Number.isSafeInteger(version) && version >= 0 ? version + 0 : 0;\n}\n\n/**\n * The failures in a row a stored state counts as: its `consecutiveFailures`\n * when that is a whole number, held at MAX_DURATION_MS (2^53 - 1), and 0 when\n * it is negative or not a whole number. A foreign row's count past 2^53, or at\n * a 64-bit limit, stays at the top instead of losing precision or wrapping\n * negative, and a `1.5`, `\"3\"`, or `-1` counts as none.\n */\nexport function failureCount(state: Pick<JobState, \"consecutiveFailures\"> | null | undefined): number {\n const count: unknown = state?.consecutiveFailures;\n if (typeof count !== \"number\" || !Number.isInteger(count) || count <= 0) return 0;\n return Math.min(count, MAX_DURATION_MS);\n}\n\nexport function emptyState(job: string): JobState {\n return { job, open: {}, consecutiveFailures: 0, silencedUntil: null, lastAlertAt: null, pendingRecovery: [], undelivered: [] };\n}\n\n/** A JSON object: not null, not an array. */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * A stored state with every field present, or a fresh one. State written by\n * an older version lacks the newer fields. `sending` and `underFloor` are the\n * exceptions: each is there only while it holds something.\n *\n * Read leniently, since a foreign, hand-edited, or damaged row must affect\n * only its own job, and the next write puts it right: a state that is not\n * an object reads as none; `open` keeps only its entries whose value is a\n * number (anything but an object reads as {}); `silencedUntil` and\n * `lastAlertAt` that are not numbers read as null; `pendingRecovery` keeps\n * only its strings, and `undelivered` only its entries that are objects (a\n * list of neither shape reads as []), and `underFloor` and `pendingRuns`\n * only their strings (each absent when none). Unknown fields are kept as\n * written.\n */\nexport function normalizeState(state: JobState | null, job: string): JobState {\n if (!isObject(state)) return emptyState(job);\n const { sending, underFloor, pendingRuns, ...rest } = state;\n const open = isObject(state.open)\n ? Object.fromEntries(Object.entries(state.open).filter(([, at]) => typeof at === \"number\"))\n : {};\n const number = (value: unknown) => (typeof value === \"number\" ? value : null);\n const list = (value: unknown) => (Array.isArray(value) ? value : []);\n return {\n ...emptyState(job),\n ...rest,\n open,\n consecutiveFailures: failureCount(state),\n silencedUntil: number(state.silencedUntil),\n lastAlertAt: number(state.lastAlertAt),\n pendingRecovery: list(state.pendingRecovery).filter((c): c is Condition => typeof c === \"string\"),\n undelivered: list(state.undelivered).filter((alert): alert is Alert => isObject(alert)),\n ...(Array.isArray(sending) && sending.length > 0 ? { sending: [...sending] } : {}),\n ...(Array.isArray(underFloor) && underFloor.some((m) => typeof m === \"string\") ? { underFloor: underFloor.filter((m): m is string => typeof m === \"string\") } : {}),\n ...(Array.isArray(pendingRuns) && pendingRuns.some((id) => typeof id === \"string\") ? { pendingRuns: pendingRuns.filter((id): id is string => typeof id === \"string\") } : {}),\n };\n}\n\n// ---------------------------------------------------------------- delivery\n\n/** Alerts kept per job for retry, and per job being sent; past it the oldest go. */\nexport const MAX_UNDELIVERED = 20;\n\n/**\n * How long an alert in `sending` is left to the process sending it. Longer\n * than any send takes: at most three alerts go out together, each with 25\n * seconds of triage and 15 of channels.\n */\nexport const SEND_LEASE_MS = 5 * 60_000;\n\n/** Identifies an alert across retries, and in `sending`. */\nexport function alertKey(alert: Pick<Alert, \"type\" | \"at\" | \"run\">): string {\n return `${alert.type}|${alert.at}|${alert.run?.id ?? \"\"}`;\n}\n\n/** How much of a held alert's run error and output is kept: 2048 UTF-16 units of each. */\nexport const HELD_TEXT_CAP = 2048;\n\n/**\n * How far past HELD_TEXT_CAP a text may run and still be kept whole: longer\n * than any marker, so a text trimmed once (its kept part and its marker) is\n * never trimmed again, and the count in its marker stays true.\n */\nexport const HELD_TEXT_SLACK = 64;\n\n/**\n * A run as an alert held in a job's state keeps it (`sending` and\n * `undelivered`), so the state stays small however much a run logged. Its\n * error keeps its first HELD_TEXT_CAP units and its output its last, each\n * cut so as not to split a surrogate pair, with a line saying how many\n * units were left out: \"<head>\\n[N more characters trimmed]\" and\n * \"[N earlier characters trimmed]\\n<tail>\". A text of at most\n * HELD_TEXT_CAP + HELD_TEXT_SLACK units, or that is not a string, is kept\n * as it is, and so is every other field. The first send of an alert uses\n * the alert as composed; only a retry reads the held copy.\n */\nexport function heldRun(run: Run): Run {\n const error = typeof run.error === \"string\" && run.error.length > HELD_TEXT_CAP + HELD_TEXT_SLACK ? keepHead(run.error) : run.error;\n const output = typeof run.output === \"string\" && run.output.length > HELD_TEXT_CAP + HELD_TEXT_SLACK ? keepTail(run.output) : run.output;\n return error === run.error && output === run.output ? run : { ...run, error, output };\n}\n\n/** How much of a held alert's message is kept: its first 4096 UTF-16 units. */\nexport const HELD_MESSAGE_CAP = 4096;\n\nfunction keepHead(text: string, cap = HELD_TEXT_CAP): string {\n let end = cap;\n if (isHighSurrogate(text.charCodeAt(end - 1))) end -= 1;\n return `${text.slice(0, end)}\\n[${text.length - end} more characters trimmed]`;\n}\n\nfunction keepTail(text: string): string {\n let start = text.length - HELD_TEXT_CAP;\n if (isLowSurrogate(text.charCodeAt(start)) && isHighSurrogate(text.charCodeAt(start - 1))) start += 1;\n return `[${start} earlier characters trimmed]\\n${text.slice(start)}`;\n}\n\nfunction isHighSurrogate(code: number): boolean {\n return code >= 0xd800 && code <= 0xdbff;\n}\n\nfunction isLowSurrogate(code: number): boolean {\n return code >= 0xdc00 && code <= 0xdfff;\n}\n\n/**\n * An alert as it is held in state: its run trimmed (heldRun), and its\n * message, when longer than HELD_MESSAGE_CAP + HELD_TEXT_SLACK units, cut to\n * its first HELD_MESSAGE_CAP like a run's error (\"<head>\\n[N more characters\n * trimmed]\"). Everything else, the title included, as it is. The first send\n * uses the alert as composed.\n */\nexport function heldAlert<T extends HeldAlert>(alert: T): T {\n const run: unknown = alert.run;\n const trimmedRun = isObject(run) ? heldRun(run as unknown as Run) : run;\n const message: unknown = alert.message;\n const trimmedMessage = typeof message === \"string\" && message.length > HELD_MESSAGE_CAP + HELD_TEXT_SLACK ? keepHead(message, HELD_MESSAGE_CAP) : message;\n if (trimmedRun === run && trimmedMessage === message) return alert;\n return { ...alert, run: trimmedRun, message: trimmedMessage } as T;\n}\n\n/**\n * Each configured channel's key, in the order configured: its name, with\n * \"#2\", \"#3\", and so on for the second and later channels of the same name,\n * so two webhooks are \"webhook\" and \"webhook#2\". A key already given to an\n * earlier channel (a channel named \"webhook#2\" itself, say) is skipped for\n * the next number up, so every key is different. A held alert names the\n * channels that still owe it by these keys (HeldAlert.owed).\n */\nexport function channelKeys(names: readonly string[]): string[] {\n const seen = new Map<string, number>();\n const taken = new Set<string>();\n return names.map((name) => {\n let n = (seen.get(name) ?? 0) + 1;\n seen.set(name, n);\n let key = n === 1 ? name : `${name}#${n}`;\n while (taken.has(key)) key = `${name}#${++n}`;\n taken.add(key);\n return key;\n });\n}\n\n/**\n * The channels a held alert is still owed by, of those configured now\n * (`configured`, channelKeys order): those in its `owed` that are still\n * configured, or every configured one when it has no `owed` list (an alert\n * held by a release before per-channel delivery, or one never sent). An\n * entry of `owed` that is not a string is ignored. None left means the\n * alert is done.\n */\nexport function owedChannels(alert: HeldAlert, configured: readonly string[]): string[] {\n const owed: unknown = alert.owed;\n if (!Array.isArray(owed)) return [...configured];\n return configured.filter((key) => owed.includes(key));\n}\n\n/**\n * An alert after a send to the channels in `tried`, of which those in\n * `failed` refused it: null when none is left owing it, else the alert\n * with `owed` set to those that refused, in configured order.\n */\nexport function afterSend<T extends HeldAlert>(alert: T, tried: readonly string[], failed: readonly string[]): T | null {\n const owed = tried.filter((key) => failed.includes(key));\n return owed.length === 0 ? null : { ...alert, owed };\n}\n\n/** An alert without its `owed` list, as a channel is given it. */\nexport function withoutOwed(alert: HeldAlert): Alert {\n if (!(\"owed\" in alert)) return alert;\n const { owed: _owed, ...rest } = alert;\n return rest as Alert;\n}\n\n/** Keeps the newest `max` of `list`, and says how many went. */\nfunction newest<T>(list: T[], max: number): { kept: T[]; dropped: number } {\n return { kept: list.slice(-max), dropped: Math.max(0, list.length - max) };\n}\n\n/**\n * `alerts` added to the undelivered queue, each with its run trimmed\n * (heldAlert) and its `owed` list as given: one with the same key as a\n * queued alert replaces it where it stands, the rest go at the end, and only\n * the newest MAX_UNDELIVERED stay. `dropped` counts those let go.\n */\nexport function queueUndelivered(state: JobState, alerts: HeldAlert[]): { state: JobState; dropped: number } {\n const next = cloneState(state);\n const byKey = new Map(alerts.map((alert) => [alertKey(alert), heldAlert(alert)]));\n const queue = next.undelivered!.map((alert) => byKey.get(alertKey(alert)) ?? alert);\n const known = new Set(queue.map(alertKey));\n queue.push(...[...byKey.values()].filter((alert) => !known.has(alertKey(alert))));\n const { kept, dropped } = newest(queue, MAX_UNDELIVERED);\n next.undelivered = kept;\n return { state: next, dropped };\n}\n\n/**\n * The outbox. Alerts just composed are written with the state that opens\n * their condition, before any is sent, so a process that stops part way does\n * not lose them: into `sending`, each with its lease ending at `until`, when\n * this process sends them, or (deliver: \"check\") straight into the\n * undelivered queue for a check elsewhere. Either way the copy held has its\n * run trimmed (heldAlert) and no `owed` list, so every configured channel\n * owes it; the first send uses the alerts as composed. `dropped` counts\n * alerts let go past MAX_UNDELIVERED.\n */\nexport function holdAlerts(state: JobState, alerts: Alert[], until: number, deferred: boolean): { state: JobState; dropped: number } {\n if (alerts.length === 0) return { state, dropped: 0 };\n if (deferred) return queueUndelivered(state, alerts);\n const next = cloneState(state);\n const { kept, dropped } = newest([...(next.sending ?? []), ...alerts.map((alert) => ({ until, alert: heldAlert(alert) }))], MAX_UNDELIVERED);\n next.sending = kept;\n return { state: next, dropped };\n}\n\n/**\n * Alerts in `sending` whose lease ran out by `now`: the process sending them\n * stopped before it recorded how the send went. They go to the undelivered\n * queue, where the retry sends them (with triage, which is never stored with\n * them here) or drops them as stale, owed by the channels its `owed` names.\n * An entry that is not an object with an alert is dropped; one without a\n * numeric `until` counts as run out.\n */\nexport function releaseSending(state: JobState, now: number): { state: JobState; dropped: number } {\n const sending = state.sending ?? [];\n const lapsed = sending.filter((entry) => !(typeof entry?.until === \"number\" && entry.until > now));\n if (lapsed.length === 0) return { state, dropped: 0 };\n const held = sending.filter((entry) => !lapsed.includes(entry));\n return queueUndelivered(\n { ...state, sending: held },\n lapsed.filter((entry) => typeof entry?.alert === \"object\" && entry.alert !== null).map((entry) => entry.alert),\n );\n}\n\n/**\n * How a send went. Delivered alerts (no channel owes them any more) and\n * stale ones (`dropped`) leave the queue; failed ones (some channel still\n * owes them, named by their `owed`) replace their queued copy, so a triage\n * made on this attempt and the shrunken `owed` are kept, or join the queue.\n * Every one of them leaves `sending`. lastAlertAt moves to `now` when\n * `reached` (some channel accepted an alert on this attempt; by default,\n * when any was delivered). `dropped` in the result counts alerts let go\n * past MAX_UNDELIVERED.\n */\nexport function recordSent(\n state: JobState,\n delivered: HeldAlert[],\n failed: HeldAlert[],\n stale: HeldAlert[],\n now: number,\n reached: boolean = delivered.length > 0,\n): { state: JobState; dropped: number } {\n const next = cloneState(state);\n const done = new Set([...delivered, ...stale].map(alertKey));\n next.undelivered = next.undelivered!.filter((alert) => !done.has(alertKey(alert)));\n const sent = new Set([...delivered, ...failed, ...stale].map(alertKey));\n const held = (next.sending ?? []).filter((entry) => !(typeof entry?.alert === \"object\" && entry.alert !== null && sent.has(alertKey(entry.alert))));\n if (held.length > 0) next.sending = held;\n else delete next.sending;\n if (reached) next.lastAlertAt = now;\n return queueUndelivered(next, failed);\n}\n\n/**\n * A check's claim on the undelivered queue, written before it sends, so two\n * processes checking at once never retry the same alert: the queued alerts\n * that still describe the job move into `sending`, oldest first, each with\n * its lease ending at `until`, as many as `sending` has room for under\n * MAX_UNDELIVERED (the rest wait for the next check); stale ones\n * (staleAlert) leave the queue. While the job is silenced only recoveries\n * are claimed. The process whose write lands sends `claimed`.\n */\nexport function claimUndelivered(state: JobState, now: number, until: number): { state: JobState; claimed: HeldAlert[]; stale: HeldAlert[] } {\n const next = cloneState(state);\n const queue = next.undelivered!;\n const stale = queue.filter((alert) => staleAlert(alert, next));\n const silenced = isSilenced(next, now);\n const room = Math.max(0, MAX_UNDELIVERED - (next.sending ?? []).length);\n const claimed = queue.filter((alert) => !stale.includes(alert) && (!silenced || alert.type === \"recovered\")).slice(0, room);\n if (stale.length === 0 && claimed.length === 0) return { state, claimed, stale };\n next.undelivered = queue.filter((alert) => !stale.includes(alert) && !claimed.includes(alert));\n if (claimed.length > 0) next.sending = [...(next.sending ?? []), ...claimed.map((alert) => ({ until, alert }))];\n return { state: next, claimed, stale };\n}\n\n/** Runs held in `pendingRuns` per job; past it the oldest go. */\nexport const MAX_PENDING_RUNS = 100;\n\n/**\n * A run just started, held in `pendingRuns` until its finish is evaluated\n * (releaseRun), so a check can evaluate it if the process that finished it\n * stops before writing the evaluation. Written with onRunStart's state.\n * Only the newest MAX_PENDING_RUNS are kept.\n */\nexport function holdRun(state: JobState, runId: string): JobState {\n const next = cloneState(state);\n const held = (next.pendingRuns ?? []).filter((id) => id !== runId);\n held.push(runId);\n next.pendingRuns = held.slice(-MAX_PENDING_RUNS);\n return next;\n}\n\n/** A run taken out of `pendingRuns`, as its evaluation is written or once it is gone from the store. */\nexport function releaseRun(state: JobState, runId: string): JobState {\n const held = state.pendingRuns ?? [];\n if (!held.includes(runId)) return state;\n const next = cloneState(state);\n const left = held.filter((id) => id !== runId);\n if (left.length > 0) next.pendingRuns = left;\n else delete next.pendingRuns;\n return next;\n}\n\nfunction cloneState(state: JobState): JobState {\n return normalizeState(state, state.job);\n}\n\nfunction openCondition(state: JobState, condition: Condition, now: number): boolean {\n if (state.open[condition] !== undefined) return false;\n state.open[condition] = now;\n return true;\n}\n\n/**\n * Every open condition has alerted, so closing one owes a recovered message.\n * It is remembered until a successful run leaves nothing open and sends it.\n */\nfunction closeCondition(state: JobState, condition: Condition): boolean {\n if (state.open[condition] === undefined) return false;\n delete state.open[condition];\n const pending = (state.pendingRecovery ??= []);\n if (!pending.includes(condition)) pending.push(condition);\n return true;\n}\n\nexport function openConditions(state: JobState): Condition[] {\n return Object.keys(state.open) as Condition[];\n}\n\nexport function graceMs(def: Pick<JobDefinition, \"grace\">): number {\n return def.grace === undefined ? DEFAULT_GRACE_MS : parseDuration(def.grace, \"grace\");\n}\n\nexport function timeoutMs(def: Pick<JobDefinition, \"timeout\">): number {\n return def.timeout === undefined ? DEFAULT_TIMEOUT_MS : parseDuration(def.timeout, \"timeout\");\n}\n\n/** Slow threshold for a successful run, or null when there is nothing to compare against yet. */\nexport function slowThreshold(def: Pick<JobDefinition, \"maxDuration\">, history: Run[]): { thresholdMs: number; basis: string } | null {\n if (def.maxDuration !== undefined) {\n return { thresholdMs: parseDuration(def.maxDuration, \"maxDuration\"), basis: \"maxDuration\" };\n }\n const durations = history\n .filter((r) => r.status === \"ok\" && r.durationMs !== null)\n .slice(0, BASELINE_WINDOW)\n .map((r) => r.durationMs!);\n if (durations.length < BASELINE_MIN_RUNS) return null;\n const p95 = percentile(durations, 95)!;\n return { thresholdMs: Math.max(2 * p95, SLOW_FLOOR_MS), basis: `twice the p95 of the last ${durations.length} runs (${formatDuration(p95)})` };\n}\n\nexport function budgetBreaches(def: Pick<JobDefinition, \"budget\">, run: Run, history: Run[]): BudgetBreach[] {\n const breaches: BudgetBreach[] = [];\n for (const [metric, value] of Object.entries(run.metrics)) {\n const ceiling = def.budget?.[metric];\n if (ceiling !== undefined) {\n if (value > ceiling) breaches.push({ metric, value, limit: ceiling, basis: \"budget\" });\n continue;\n }\n const past = history\n .filter((r) => r.status === \"ok\" && typeof r.metrics[metric] === \"number\")\n .slice(0, BASELINE_WINDOW)\n .map((r) => r.metrics[metric]!);\n if (past.length < BASELINE_MIN_RUNS) continue;\n const usual = median(past)!;\n if (usual > 0 && value > 3 * usual) {\n breaches.push({ metric, value, limit: 3 * usual, basis: `three times the usual ${formatNumber(usual)}` });\n }\n }\n return breaches;\n}\n\n/**\n * The metrics of a successful run that fell below their floor. A metric\n * with a floor breaches when it reports less than that floor. One without\n * breaches when it reports 0 or less and either it did so on the job's last\n * successful run too (`previous`, the metrics under their floor then), or\n * the earlier successful runs that reported it (at least five, the newest\n * twenty) all reported more than 0. So a job that keeps writing nothing stays\n * under its floor however long it goes on, and a metric that is always 0\n * never alerts.\n */\nexport function floorBreaches(def: Pick<JobDefinition, \"floor\">, run: Run, history: Run[], previous: readonly string[] = []): BudgetBreach[] {\n const breaches: BudgetBreach[] = [];\n for (const [metric, value] of Object.entries(run.metrics)) {\n const floor = def.floor?.[metric];\n if (floor !== undefined) {\n if (value < floor) breaches.push({ metric, value, limit: floor, basis: \"floor\" });\n continue;\n }\n if (value > 0) continue;\n if (previous.includes(metric)) {\n breaches.push({ metric, value, limit: 0, basis: \"0 or less on the run before too\" });\n continue;\n }\n const past = history\n .filter((r) => r.status === \"ok\" && typeof r.metrics[metric] === \"number\")\n .slice(0, BASELINE_WINDOW)\n .map((r) => r.metrics[metric]!);\n if (past.length < BASELINE_MIN_RUNS || !past.every((v) => v > 0)) continue;\n const lowest = Math.min(...past);\n breaches.push({ metric, value, limit: lowest, basis: `the last ${past.length} runs all reported more than 0, the lowest ${formatNumber(lowest)}` });\n }\n return breaches;\n}\n\n/** Whether `history` (newest first) holds a full baseline window of successful runs. */\nexport function hasFullBaseline(history: Run[]): boolean {\n return history.filter((r) => r.status === \"ok\").length >= BASELINE_WINDOW;\n}\n\nexport function formatNumber(n: number): string {\n if (Number.isInteger(n)) return n.toLocaleString(\"en-US\");\n return n.toLocaleString(\"en-US\", { maximumFractionDigits: 4 });\n}\n\n/** When a run finished, or null while it runs (a run marked timeout has finished). */\nexport function finishedAtOf(run: Pick<Run, \"status\" | \"finishedAt\">): number | null {\n return run.status !== \"running\" && typeof run.finishedAt === \"number\" ? run.finishedAt : null;\n}\n\n/**\n * Whether `run` brings the schedule up to date at `now`, so missed may close\n * for it: judged with it as the job's last run, as onCheck judges, the run\n * the schedule wants next is not yet past its deadline. A run that started\n * before the fire missed opened for does not cover that fire, however late\n * it finishes, and neither does a run a source reports only once it is over\n * whose start was before it. Every run starting now covers it. A job with no\n * schedule, or one that no longer parses, has nothing due, so any run does.\n */\nexport function catchesUp(def: JobDefinition | StoredJobDefinition, run: Pick<Run, \"startedAt\" | \"status\" | \"finishedAt\">, now: number): boolean {\n if (!def.schedule) return true;\n try {\n const exp = expectation(parseSchedule(def.schedule, def.timezone), run.startedAt, run.startedAt, graceMs(def), finishedAtOf(run));\n return exp === null || now <= exp.deadline;\n } catch {\n return true;\n }\n}\n\n/**\n * Called when a run starts, or when a run a source reports is recorded.\n * Missed and stuck are about the absence of a run, so a run starting closes\n * them without an alert; the recovered message waits for a successful\n * finish. Missed closes only when the run catches the schedule up\n * (catchesUp), which a run starting now always does.\n */\nexport function onRunStart(def: JobDefinition | StoredJobDefinition, run: Pick<Run, \"startedAt\" | \"status\" | \"finishedAt\">, state: JobState, now: number): JobState {\n const next = cloneState(state);\n if (catchesUp(def, run, now)) closeCondition(next, \"missed\");\n closeCondition(next, \"stuck\");\n return next;\n}\n\n/**\n * Called when a run finishes with status ok, failed, or timeout. `history` is\n * the job's earlier runs, newest first, not including this one. Missed\n * closes only when the run catches the schedule up (catchesUp): a run that\n * started before the fire missed opened for leaves it open.\n */\nexport function onRunFinish(\n def: JobDefinition | StoredJobDefinition,\n run: Run,\n state: JobState,\n history: Run[],\n now: number,\n): Evaluation {\n const next = cloneState(state);\n const alerts: AlertDraft[] = [];\n\n if (run.status === \"ok\") {\n next.consecutiveFailures = 0;\n if (catchesUp(def, run, now)) closeCondition(next, \"missed\");\n closeCondition(next, \"stuck\");\n closeCondition(next, \"failed\");\n\n const slow = slowThreshold(def, history);\n if (slow && run.durationMs !== null && run.durationMs > slow.thresholdMs) {\n if (openCondition(next, \"slow\", now)) {\n alerts.push({ type: \"slow\", run, details: { durationMs: run.durationMs, thresholdMs: slow.thresholdMs, basis: slow.basis } });\n }\n } else {\n closeCondition(next, \"slow\");\n }\n\n const breaches = budgetBreaches(def, run, history);\n if (breaches.length > 0) {\n if (openCondition(next, \"over_budget\", now)) {\n alerts.push({ type: \"over_budget\", run, details: { breaches } });\n }\n } else {\n closeCondition(next, \"over_budget\");\n }\n\n const short = floorBreaches(def, run, history, next.underFloor);\n if (short.length > 0) {\n next.underFloor = short.map((b) => b.metric);\n if (openCondition(next, \"under_floor\", now)) {\n alerts.push({ type: \"under_floor\", run, details: { breaches: short } });\n }\n } else {\n delete next.underFloor;\n closeCondition(next, \"under_floor\");\n }\n\n const pending = next.pendingRecovery ?? [];\n if (pending.length > 0 && openConditions(next).length === 0) {\n alerts.push({ type: \"recovered\", run, details: { after: [...pending] } });\n next.pendingRecovery = [];\n }\n return { state: next, alerts };\n }\n\n // failed or timeout\n // Held at the top: a count at the limit neither loses precision nor wraps below a threshold.\n next.consecutiveFailures = Math.min(next.consecutiveFailures + 1, MAX_DURATION_MS);\n if (catchesUp(def, run, now)) closeCondition(next, \"missed\");\n const threshold = Math.max(1, def.failuresBeforeAlert ?? 1);\n const condition = run.status === \"timeout\" ? \"stuck\" : \"failed\";\n if (next.consecutiveFailures >= threshold) {\n if (openCondition(next, condition, now)) {\n alerts.push({ type: condition, run, details: { consecutiveFailures: next.consecutiveFailures, threshold } });\n }\n }\n return { state: next, alerts };\n}\n\n/**\n * Called by check(). Decides whether the schedule has been missed: the run\n * the schedule wants next (see expectation()) has not started and its grace\n * has run out. `lastRun` is the most recent run of any status. A job with no\n * schedule is never missed, and one whose schedule was removed while missed\n * was open gets a recovered alert (reason \"unscheduled\") for missed alone.\n */\nexport function onCheck(\n def: StoredJobDefinition,\n stored: StoredJob,\n lastRun: Run | null,\n state: JobState,\n now: number,\n): Evaluation & { nextExpectedAt: number | null; dueAt: number | null } {\n const next = cloneState(state);\n const alerts: AlertDraft[] = [];\n if (!def.schedule) {\n const since = next.open.missed;\n if (since !== undefined) {\n // The schedule went away while missed was open (the job was declared\n // again without one, or a source retired it), so nothing is due any\n // more. Missed closes now with a recovery of its own; other open\n // conditions keep their own rules. Missed is taken out of the pending\n // recovery too, so the next successful run does not name it again.\n delete next.open.missed;\n next.pendingRecovery = (next.pendingRecovery ?? []).filter((c) => c !== \"missed\");\n alerts.push({ type: \"recovered\", run: lastRun, details: { after: [\"missed\"], reason: \"unscheduled\", since } });\n }\n return { state: next, alerts, nextExpectedAt: null, dueAt: null };\n }\n\n const parsed = parseSchedule(def.schedule, def.timezone);\n const grace = graceMs(def);\n const lastRunAt = lastRun?.startedAt ?? null;\n const exp = expectation(parsed, lastRunAt, stored.createdAt, grace, lastRun ? finishedAtOf(lastRun) : null);\n const nextExpectedAt = parsed.kind === \"interval\" ? exp!.dueAt : nextFire(parsed, now, null);\n if (!exp) return { state: next, alerts, nextExpectedAt, dueAt: null };\n\n // An interval's next run is due a period after the last one started, or\n // after it finished when it outlasted the period (intervalDue). If that run\n // is still going, the job is busy, not late; stuck covers one that never ends.\n if (parsed.kind === \"interval\" && lastRun?.status === \"running\") {\n return { state: next, alerts, nextExpectedAt, dueAt: exp.dueAt };\n }\n\n if (now > exp.deadline) {\n if (openCondition(next, \"missed\", now)) {\n alerts.push({ type: \"missed\", run: lastRun, details: { dueAt: exp.dueAt, deadline: exp.deadline, graceMs: grace, lastRunAt } });\n }\n } else {\n // A run has started since it opened, or the grace was widened.\n closeCondition(next, \"missed\");\n }\n return { state: next, alerts, nextExpectedAt, dueAt: exp.dueAt };\n}\n\n/** Whether a running run has gone on longer than the job's timeout. */\nexport function isStuck(def: Pick<JobDefinition, \"timeout\">, run: Run, now: number): boolean {\n // A completed import keeps its finish while its evaluation intent is written.\n return run.status === \"running\" && run.finishedAt === null && now - run.startedAt > timeoutMs(def);\n}\n\n/**\n * While a job is silenced nothing new is recorded as an incident: conditions\n * may close (so a job that recovered during the silence shows as healthy) but\n * none may open, so the first problem after the silence ends alerts normally.\n */\nexport function muteOpens(previous: JobState, next: JobState): JobState {\n const muted = cloneState(next);\n for (const condition of openConditions(muted)) {\n if (previous.open[condition] === undefined) delete muted.open[condition];\n }\n return muted;\n}\n\nexport function isSilenced(state: JobState, now: number): boolean {\n return state.silencedUntil !== null && state.silencedUntil > now;\n}\n\n/**\n * An evaluation as it is saved and sent: while the job was silenced when it\n * began, nothing opens and no new alert is sent, but a recovery is. A\n * condition can only close during a silence if it opened (and alerted)\n * before it, so its recovery closes an incident someone was told about.\n */\nexport function applySilence(previous: JobState, evaluation: Evaluation, now: number): Evaluation {\n if (!isSilenced(previous, now)) return evaluation;\n return { state: muteOpens(previous, evaluation.state), alerts: evaluation.alerts.filter((alert) => alert.type === \"recovered\") };\n}\n\n/**\n * Whether an alert waiting to be retried no longer describes the job, so it\n * is dropped rather than sent late. An alert for a condition is stale once\n * that condition has closed, or has closed and opened again (it opened at a\n * time other than the alert's). A recovery is stale when any condition it\n * names is open again; while they all stay closed it is kept. From a\n * foreign or damaged row: an alert whose `at` is not a number, and a\n * recovery whose `details.after` is not a list of strings, are stale.\n */\nexport function staleAlert(alert: AlertDraft & { at: number }, state: JobState): boolean {\n if (alert.type === \"recovered\") {\n // One whose details say nothing of what it recovers from (a foreign or damaged row's) cannot be judged, and goes.\n const after: unknown = isObject(alert.details) ? (alert.details as { after?: unknown }).after : undefined;\n if (!Array.isArray(after)) return true;\n return after.some((condition) => typeof condition !== \"string\" || state.open[condition as Condition] !== undefined);\n }\n // One with no time (a foreign or damaged row's) cannot match an open condition.\n return typeof alert.at !== \"number\" || state.open[alert.type] !== alert.at;\n}\n\n/** How a job looks at a glance. Silence wins, then stuck, failing, and late. */\nexport function jobHealth(def: Pick<JobDefinition, \"timeout\">, lastRun: Run | null, state: JobState, now: number): JobHealth {\n const open = openConditions(state);\n if (isSilenced(state, now)) return \"silenced\";\n if (open.includes(\"stuck\") || (lastRun && isStuck(def, lastRun, now))) return \"stuck\";\n if (open.includes(\"failed\") || lastRun?.status === \"failed\" || lastRun?.status === \"timeout\") return \"failing\";\n if (open.includes(\"missed\")) return \"late\";\n if (!lastRun) return \"never_ran\";\n return \"healthy\";\n}\n\n/**\n * A job's summary from its most recent runs (newest first; the first\n * BASELINE_WINDOW are used) and its state. Stats cover runs of any status;\n * the percentiles are over the successful ones among them.\n */\nexport function summarize(stored: StoredJob, recent: Run[], state: JobState, nextExpectedAt: number | null, now: number): JobSummary {\n return summary(stored, recent, state, nextExpectedAt, (lastRun) => jobHealth(stored.definition, lastRun, state, now));\n}\n\n/**\n * The summary of a job that could not be evaluated, say because its stored\n * schedule no longer parses. It reads nothing from the definition. The job\n * shows as failing (or silenced, while it is), since it needs a look, and\n * nothing is known about when it is next due.\n */\nexport function unevaluableSummary(stored: StoredJob, recent: Run[], state: JobState, now: number): JobSummary {\n return summary(stored, recent, state, null, () => (isSilenced(state, now) ? \"silenced\" : \"failing\"));\n}\n\nfunction summary(stored: StoredJob, recent: Run[], state: JobState, nextExpectedAt: number | null, health: (lastRun: Run | null) => JobHealth): JobSummary {\n const window = recent.slice(0, BASELINE_WINDOW);\n const lastRun = window[0] ?? null;\n const finished = window.filter((r) => r.status !== \"running\");\n const okDurations = window.filter((r) => r.status === \"ok\" && r.durationMs !== null).map((r) => r.durationMs!);\n return {\n name: stored.name,\n definition: stored.definition,\n health: health(lastRun),\n open: openConditions(state),\n lastRun,\n nextExpectedAt,\n consecutiveFailures: state.consecutiveFailures,\n silencedUntil: state.silencedUntil,\n stats: {\n runs: finished.length,\n okRate: finished.length === 0 ? 1 : finished.filter((r) => r.status === \"ok\").length / finished.length,\n p50Ms: percentile(okDurations, 50),\n p95Ms: percentile(okDurations, 95),\n },\n };\n}\n","import { beyondDates, formatDuration, formatRelative, isoTime } from \"./duration.js\";\nimport { formatNumber } from \"./evaluate.js\";\nimport type { Alert, AlertDraft, StoredJobDefinition } from \"./types.js\";\n\nfunction when(at: number | null | undefined, now: number): string {\n if (at === null || at === undefined) return \"never\";\n const iso = isoTime(at);\n if (iso === null) return beyondDates(at);\n return `${iso.replace(\"T\", \" \").slice(0, 19)} UTC (${formatRelative(at, now)})`;\n}\n\nfunction firstLines(text: string | null, n: number): string {\n if (!text) return \"\";\n return text.split(\"\\n\").slice(0, n).join(\"\\n\");\n}\n\nfunction tail(text: string | null, n: number): string {\n if (!text) return \"\";\n const lines = text.trimEnd().split(\"\\n\");\n return lines.slice(Math.max(0, lines.length - n)).join(\"\\n\");\n}\n\n/**\n * Words joined as an English list, with a serial comma from three on:\n * \"a\", \"a and b\", \"a, b, and c\". Every port joins the same way.\n */\nexport function andList(words: readonly string[]): string {\n if (words.length <= 2) return words.join(\" and \");\n return `${words.slice(0, -1).join(\", \")}, and ${words[words.length - 1]}`;\n}\n\n/** \"Error: x\" for a bare message, but not \"Error: TypeError: x\" for one that already names itself. */\nfunction errorLine(error: string): string {\n const text = firstLines(error, 4);\n return /^[A-Za-z_$][\\w$]*: /.test(text) ? text : `Error: ${text}`;\n}\n\n/** Turns a draft into the title and message every channel shows. */\nexport function composeAlert(draft: AlertDraft, def: StoredJobDefinition, now: number): Alert {\n const name = def.name;\n const run = draft.run;\n let title: string;\n const lines: string[] = [];\n\n switch (draft.type) {\n case \"missed\": {\n const d = draft.details;\n title = `${name} missed its scheduled run`;\n lines.push(`Due ${when(d.dueAt, now)}, and no run had started by ${when(d.deadline, now)} (grace ${formatDuration(d.graceMs)}).`);\n lines.push(`Schedule: ${def.schedule}${def.timezone ? ` (${def.timezone})` : \"\"}.`);\n lines.push(`Last run: ${run ? `${run.status} ${when(run.startedAt, now)}` : \"never\"}.`);\n break;\n }\n case \"failed\": {\n title = `${name} failed`;\n const n = draft.details.consecutiveFailures;\n if (n > 1) lines.push(`${n} consecutive failures.`);\n if (run) {\n lines.push(`Started ${when(run.startedAt, now)}${run.durationMs !== null ? `, ran ${formatDuration(run.durationMs)}` : \"\"}.`);\n if (run.error) lines.push(errorLine(run.error));\n const out = tail(run.output, 8);\n if (out) lines.push(`Output (tail):\\n${out}`);\n }\n break;\n }\n case \"stuck\": {\n title = `${name} is stuck`;\n if (run) {\n lines.push(`Started ${when(run.startedAt, now)} and never reported finishing. Marked as timed out after ${formatDuration(run.durationMs ?? now - run.startedAt)}.`);\n const out = tail(run.output, 8);\n if (out) lines.push(`Output so far (tail):\\n${out}`);\n }\n lines.push(`If the process was killed mid-run (a serverless timeout, a deploy), this is what that looks like.`);\n break;\n }\n case \"slow\": {\n const d = draft.details;\n title = `${name} was slow`;\n lines.push(`Took ${formatDuration(d.durationMs)}; the limit is ${formatDuration(d.thresholdMs)} (${d.basis}).`);\n if (run) lines.push(`Started ${when(run.startedAt, now)}.`);\n break;\n }\n case \"over_budget\": {\n title = `${name} went over budget`;\n for (const b of draft.details.breaches) {\n lines.push(`${b.metric}: ${formatNumber(b.value)}, limit ${formatNumber(b.limit)} (${b.basis}).`);\n }\n if (run) lines.push(`Started ${when(run.startedAt, now)}.`);\n break;\n }\n case \"under_floor\": {\n title = `${name} fell short`;\n for (const b of draft.details.breaches) {\n lines.push(b.basis === \"floor\" ? `${b.metric}: ${formatNumber(b.value)}, below the floor of ${formatNumber(b.limit)}.` : `${b.metric}: ${formatNumber(b.value)} (${b.basis}).`);\n }\n if (run) lines.push(`Started ${when(run.startedAt, now)}.`);\n break;\n }\n case \"recovered\": {\n if (draft.details.reason === \"unscheduled\") {\n title = `${name} is no longer scheduled`;\n const since = draft.details.since;\n lines.push(`${since === undefined ? \"\" : `Missed since ${when(since, now)}. `}It has no schedule now, so nothing is due; the missed alert is closed.`);\n break;\n }\n title = `${name} recovered`;\n const after = andList(draft.details.after.map((c) => c.replace(\"_\", \" \")));\n lines.push(`A run ${run ? when(run.startedAt, now) : \"just now\"} succeeded${after ? ` after: ${after}` : \"\"}.`);\n if (run?.durationMs !== null && run?.durationMs !== undefined) lines.push(`Ran ${formatDuration(run.durationMs)}.`);\n break;\n }\n }\n\n return { ...draft, job: name, definition: def, title, message: lines.join(\"\\n\"), at: now };\n}\n","export function json(body: unknown, status = 200, headers: Record<string, string> = {}): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"content-type\": \"application/json; charset=utf-8\", \"cache-control\": \"no-store\", ...headers },\n });\n}\n\n/**\n * Compares what a request `sent` with the `secret` without stopping at the\n * first differing character, and in time that depends only on the length of\n * what was sent, so neither the secret's characters nor its length can be\n * timed. Every UTF-16 code unit of `sent` is compared, against the secret's\n * unit at the same place (repeating it past its end), and a length that\n * differs counts as a difference.\n */\nexport function constantTimeEqual(sent: string, secret: string): boolean {\n if (secret.length === 0) return sent.length === 0;\n let diff = sent.length ^ secret.length;\n for (let i = 0; i < sent.length; i++) diff |= sent.charCodeAt(i) ^ secret.charCodeAt(i % secret.length);\n return diff === 0;\n}\n","/** Output is capped so a chatty job cannot fill the store. The tail is kept. */\nexport const OUTPUT_CAP = 16 * 1024;\n\n/**\n * NUL characters are removed first, since Postgres refuses them in TEXT and\n * JSONB and the whole run row would be lost. The cap then applies to what is\n * left.\n */\nexport function capOutput(text: string): string {\n const clean = stripNul(text);\n if (clean.length <= OUTPUT_CAP) return clean;\n return TRIMMED + clean.slice(clean.length - OUTPUT_CAP);\n}\n\nconst TRIMMED = \"[earlier output trimmed]\\n\";\n\n/**\n * How much text before the kept tail redaction reads, and never keeps: three\n * times the longest secret a default pattern can match (a PEM key's 16 KB body\n * with its header and footer, under OUTPUT_CAP + 1024), since a replacement\n * grows what it replaces at most threefold.\n */\nexport const REDACT_EDGE = 3 * (OUTPUT_CAP + 1024);\n\n/**\n * Output or an error as it is stored: redacted, then capped like capOutput,\n * so the cut cannot fall inside a secret and keep what follows its label.\n * Text of at most OUTPUT_CAP + REDACT_EDGE is redacted whole. Longer text is\n * cut to that many units from its end first, and after redacting, the first\n * REDACT_EDGE units are never kept: a secret whose label fell before that cut\n * is left out with them. NULs go before and after `redact`.\n */\nexport function redactAndCap(text: string, redact: (text: string) => string): string {\n const clean = stripNul(text);\n const from = clean.length - (OUTPUT_CAP + REDACT_EDGE);\n if (from <= 0) return capOutput(redact(clean));\n const redacted = stripNul(redact(clean.slice(from)));\n return TRIMMED + redacted.slice(Math.max(redacted.length - OUTPUT_CAP, REDACT_EDGE));\n}\n\n/** Removes every U+0000. */\nexport function stripNul(text: string): string {\n return text.includes(\"\\u0000\") ? text.replace(/\\u0000/g, \"\") : text;\n}\n\n/**\n * Removes every U+0000 from JSON text, keys and strings alike, by dropping\n * each \\u0000 escape (a NUL can appear in JSON no other way). Escapes are\n * read left to right in pairs, so an escaped backslash followed by \"u0000\"\n * is left as it is.\n */\nexport function stripJsonNul(json: string): string {\n return json.includes(\"\\\\u0000\") ? json.replace(/\\\\(u0000|[\\s\\S])/g, (escape, next: string) => (next === \"u0000\" ? \"\" : escape)) : json;\n}\n\n/** \"Name: message\" and the first five stack frames, capped like output. */\nexport function errorMessage(error: unknown): string {\n return capOutput(describeError(error));\n}\n\n/** \"Name: message\" and the first five stack frames, not capped: see redactAndCap. */\nexport function describeError(error: unknown): string {\n if (error instanceof Error) {\n // The stack repeats the header (over several lines when the message has\n // newlines), so take only its frames.\n const frames = (error.stack ?? \"\").split(\"\\n\").filter((line) => /^\\s+at /.test(line)).slice(0, 5);\n return `${error.name}: ${error.message}${frames.length ? `\\n${frames.join(\"\\n\")}` : \"\"}`;\n }\n if (typeof error === \"string\") return error;\n try {\n return JSON.stringify(error) ?? String(error);\n } catch {\n return String(error);\n }\n}\n\nconst REDACTED = \"[redacted]\";\n\n// Bounded quantifiers throughout, so a long line cannot make these backtrack.\n// They apply in this order, each to the text the ones before it left.\nconst SECRET_PATTERNS: [RegExp, string | ((match: string, ...groups: string[]) => string)][] = [\n // A PEM private key, header to footer. Without a footer (the output was\n // trimmed) it runs to the end of the base64 body. A \"-\" that starts five\n // dashes ends the body, so the footer is never swallowed into it.\n [\n /-----BEGIN (?:[A-Z0-9]{1,20} ){0,3}PRIVATE KEY-----(?:[A-Za-z0-9+/=\\s,:]|-(?!----)){0,16384}(?:-----END (?:[A-Z0-9]{1,20} ){0,3}PRIVATE KEY-----)?/g,\n REDACTED,\n ],\n // password=..., API_KEY: ..., \"client_secret\": \"...\", TOKEN='...', token=...,\n // :password=>\"...\" (but not max_tokens: 800). A quoted value is blanked to\n // its closing quote, spaces and all, and keeps its quotes.\n [\n /\\b([A-Za-z0-9_-]{0,40}(?:secret|token|passw(?:or)?d|pwd|api[_-]?key|access[_-]?key|private[_-]?key|credential)[A-Za-z0-9_-]{0,40}(?<![Tt][Oo][Kk][Ee][Nn][Ss])\"?\\s{0,3}(?:=>|[=:])\\s{0,3})(?:(\")[^\"\\n]{1,4096}\"|(')[^'\\n]{1,4096}'|[\"']?[^\\s\"',;&]{1,4096})/gi,\n (_match, name: string, double?: string, single?: string) => {\n const quote = double ?? single ?? \"\";\n return `${name}${quote}${REDACTED}${quote}`;\n },\n ],\n // Authorization: Basic <base64> and Authorization: Token <token>, also as a JSON or hash entry.\n [/\\b((?:proxy-)?authorization[\"']?\\s{0,3}(?:=>|[=:])\\s{0,3}[\"']?\\s{0,3}(?:basic|token)\\s{1,3})[A-Za-z0-9._~+/=:-]{1,4096}/gi, `$1${REDACTED}`],\n // Credentials inside a URL: postgres://user:password@host. The password\n // runs to the last \"@\" before a \"/\" or a space, so one that contains \"@\"\n // is blanked whole.\n [/(\\b[a-z][a-z0-9+.-]{0,30}:\\/\\/[^\\s/:@]{0,256}:)[^\\s/]{1,256}@/gi, `$1${REDACTED}@`],\n // Authorization: Bearer <token>\n [/\\b(Bearer\\s{1,3})[A-Za-z0-9._~+/=-]{8,4096}/g, `$1${REDACTED}`],\n // A bare JWT: three base64url segments, the first starting eyJ.\n [/\\beyJ[A-Za-z0-9_-]{4,4096}\\.[A-Za-z0-9_-]{4,4096}\\.[A-Za-z0-9_-]{0,4096}/g, REDACTED],\n // Incoming webhook URLs carry their secret in the path.\n [/(\\bhooks\\.slack\\.com\\/(?:services|workflows|triggers)\\/)[A-Za-z0-9/_-]{1,255}/gi, `$1${REDACTED}`],\n [/(\\bdiscord(?:app)?\\.com\\/api\\/(?:v\\d{1,2}\\/)?webhooks\\/)[A-Za-z0-9/_-]{1,255}/gi, `$1${REDACTED}`],\n // Well-known token shapes: AWS, GitHub, Slack, Stripe, Anthropic, OpenAI, and Google style keys.\n [/\\b(?:AKIA|ASIA)[0-9A-Z]{16}\\b/g, REDACTED],\n [/\\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{20,255})\\b/g, REDACTED],\n [/\\bxox[abposr]-[A-Za-z0-9-]{10,255}/g, REDACTED],\n [/\\b[rsp]k_(?:live|test)_[A-Za-z0-9]{10,255}\\b/g, REDACTED],\n [/\\bwhsec_[A-Za-z0-9+/=]{16,255}/g, REDACTED],\n [/\\bsk-[A-Za-z0-9_-]{20,255}/g, REDACTED],\n [/\\bAIza[0-9A-Za-z_-]{35}(?![0-9A-Za-z_-])/g, REDACTED],\n];\n\n/**\n * The default `redact`: blanks values that look like secrets (key=value pairs\n * with secret-ish names, Authorization headers, URL credentials, bearer\n * tokens, JWTs, PEM private keys, webhook URLs, and well-known token formats)\n * before output or an error is stored, shown, or sent anywhere.\n */\nexport function redactSecrets(text: string): string {\n let out = text;\n for (const [pattern, replacement] of SECRET_PATTERNS) out = out.replace(pattern, replacement as string);\n return out;\n}\n","import { OUTPUT_CAP, REDACT_EDGE, stripNul } from \"./output.js\";\nimport type { Run } from \"./types.js\";\n\n/** What a job function receives. */\nexport interface JobContext {\n readonly name: string;\n readonly runId: string;\n readonly startedAt: number;\n /** Aborts when the job's timeout elapses. Honour it if the work can stop. */\n readonly signal: AbortSignal;\n /** Append a line of output. Kept with the run, capped at 16 KB, shown in alerts and the dashboard. */\n log(...parts: unknown[]): void;\n /** Report a number for this run: tokens, cost, rows, anything. Watched against budgets and baselines. */\n metric(name: string, value: number): void;\n metrics(values: Record<string, number>): void;\n}\n\nexport interface RunRecorder {\n context: JobContext;\n /**\n * The lines still held in a bounded redaction window, joined and not\n * yet capped: the client redacts them first, then caps them (redactAndCap).\n */\n output(): string | null;\n /**\n * What an expect rule is checked against: everything logged, or when that\n * ran long, the first 16 KB and the last 16 KB. The stored output keeps only\n * the tail, so a \"done\" line printed early would otherwise be lost.\n */\n expectText(): string | null;\n metrics(): Record<string, number>;\n abort(): void;\n}\n\nfunction stringify(part: unknown): string {\n if (typeof part === \"string\") return part;\n if (part instanceof Error) return `${part.name}: ${part.message}`;\n try {\n return JSON.stringify(part);\n } catch {\n return String(part);\n }\n}\n\nexport function createRecorder(run: Run): RunRecorder {\n // One byte past redactAndCap's look-behind ensures a cut inside a secret is discarded there.\n const window = OUTPUT_CAP + REDACT_EDGE + 2;\n const copy = (text: string): string => JSON.parse(JSON.stringify(text)) as string;\n const lines: string[] = [];\n let size = 0;\n const head: string[] = [];\n let headSize = 0;\n let whole: string | null = \"\";\n let tail = \"\";\n let logged = false;\n const metrics: Record<string, number> = {};\n const controller = new AbortController();\n\n const context: JobContext = {\n name: run.job,\n runId: run.id,\n startedAt: run.startedAt,\n signal: controller.signal,\n log(...parts) {\n let line = parts.map(stringify).join(\" \");\n const separator = logged ? \"\\n\" : \"\";\n logged = true;\n if (whole !== null) whole = whole.length + separator.length + line.length <= 2 * OUTPUT_CAP ? whole + separator + line : null;\n tail = copy((tail + separator + copy(line.slice(-OUTPUT_CAP))).slice(-OUTPUT_CAP));\n if (headSize < OUTPUT_CAP) {\n head.push(copy(line.slice(0, OUTPUT_CAP - headSize)));\n headSize += line.length + 1;\n }\n // Expectations keep the raw prefix and tail; storage removes NUL before cutting so it cannot shrink the redaction margin.\n line = stripNul(line);\n if (line.length >= window) {\n line = copy(line.slice(-(window - 1)));\n }\n lines.push(line);\n size += line.length + 1;\n // Drop from the front once well past the cap; redactAndCap trims exactly at the end.\n while (size > window && lines.length > 1) {\n size -= lines.shift()!.length + 1;\n }\n },\n metric(name, value) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`metric \"${name}\" must be a finite number`);\n }\n metrics[name] = value;\n },\n metrics(values) {\n for (const [k, v] of Object.entries(values)) context.metric(k, v);\n },\n };\n\n return {\n context,\n output: () => (lines.length === 0 ? null : lines.join(\"\\n\")),\n expectText: () => {\n if (!logged) return null;\n return whole ?? head.join(\"\\n\").slice(0, OUTPUT_CAP) + \"\\n\" + tail;\n },\n metrics: () => ({ ...metrics }),\n abort: () => controller.abort(),\n };\n}\n","import type { JobDefinition, StoredJob, StoredJobDefinition } from \"./types.js\";\n\n/** A definition as a store can hold it: `expect` becomes a description. */\nexport function toStored(def: JobDefinition): StoredJobDefinition {\n const { expect, ...rest } = def;\n const stored: StoredJobDefinition = { ...rest };\n if (expect !== undefined) {\n stored.expect =\n typeof expect === \"string\" ? `contains ${JSON.stringify(expect)}`\n : expect instanceof RegExp ? `matches ${expect.toString()}`\n : \"custom function\";\n }\n return stored;\n}\n\nexport function checkExpectation(expect: JobDefinition[\"expect\"], output: string | null): string | null {\n if (expect === undefined) return null;\n const text = output ?? \"\";\n if (typeof expect === \"string\") {\n return text.includes(expect) ? null : `Output did not contain ${JSON.stringify(expect)}`;\n }\n if (expect instanceof RegExp) {\n expect.lastIndex = 0; // a /g or /y pattern would otherwise resume where the last run stopped\n return expect.test(text) ? null : `Output did not match ${expect.toString()}`;\n }\n let ok = false;\n try {\n ok = expect(text);\n } catch (error) {\n return `Output check threw: ${(error as Error).message}`;\n }\n return ok ? null : \"Output did not pass the expect() check\";\n}\n\n/**\n * A stored job as the client reads it, so a foreign, hand-edited, or damaged\n * row affects only its own job. A definition that is not a JSON object (a\n * SQL store reads text that does not parse as null) becomes `{ name }` and\n * `readable` is false: the client reports the job and shows it as failing,\n * without evaluating it. `tags` is kept only when it is a list of strings.\n * Every other field is kept as stored.\n */\nexport function readStoredJob(stored: StoredJob): { job: StoredJob; readable: boolean } {\n const definition: unknown = stored.definition;\n if (typeof definition !== \"object\" || definition === null || Array.isArray(definition)) {\n return { job: { ...stored, definition: { name: stored.name } }, readable: false };\n }\n const read = { ...(definition as StoredJobDefinition) };\n if (\"tags\" in read && !(Array.isArray(read.tags) && read.tags.every((tag) => typeof tag === \"string\"))) delete read.tags;\n return { job: { ...stored, definition: read }, readable: true };\n}\n","/** Escapes text for HTML, attribute values included. Every string a page shows goes through this. */\nexport function escapeHtml(value: unknown): string {\n return String(value ?? \"\")\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/**\n * Escapes a job name shown as text, with a line break allowed after each run\n * of `_`, `:`, `.`, `/`, or `-`, so a long hook or class name wraps at its\n * separators rather than mid-word. Only for text: never an attribute, a URL,\n * or a title.\n */\nexport function escapeName(value: unknown): string {\n return escapeHtml(value).replace(/([_:./-]+)(?=[^_:./-])/g, \"$1<wbr>\");\n}\n","// Generated by scripts/make-dashboard-icons.mjs. Do not edit; change the drawing there and run it.\n\n/** The favicon: the clock on a dark rounded square. */\nexport const ICON_SVG = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 40 40\\\"><rect width=\\\"40\\\" height=\\\"40\\\" rx=\\\"10\\\" fill=\\\"#141417\\\"/><rect x=\\\"0.5\\\" y=\\\"0.5\\\" width=\\\"39\\\" height=\\\"39\\\" rx=\\\"9.5\\\" fill=\\\"none\\\" stroke=\\\"#2a2a2f\\\"/><circle cx=\\\"20\\\" cy=\\\"20\\\" r=\\\"10.5\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\"/><path d=\\\"M20 12.5V20h6\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"/></svg>\";\n/** The same square to every edge, for masks. */\nexport const MASKABLE_SVG = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 40 40\\\"><rect width=\\\"40\\\" height=\\\"40\\\" fill=\\\"#141417\\\"/><circle cx=\\\"20\\\" cy=\\\"20\\\" r=\\\"10.5\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\"/><path d=\\\"M20 12.5V20h6\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"/></svg>\";\n/** PNGs, base64: 192 and 512 for the manifest, a maskable 512, and iOS's 180 home screen icon. */\nexport const ICON_192_PNG = \"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\";\nexport const ICON_512_PNG = \"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\";\nexport const MASKABLE_512_PNG = \"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\";\nexport const APPLE_TOUCH_ICON_PNG = \"iVBORw0KGgoAAAANSUhEUgAAALQAAAC0CAMAAAAKE/YAAAAAM1BMVEUUFBciIiU+PkBaWlt2dnaRkZKfn5+tra27u7tMTE7X19bz8/FoaGnl5eMwMDKEhITJycgc8OlvAAAFSklEQVR42u2caZPjKAyGOZ042XXm///LSVXaB9fW7vYYfGTawiJO1+j91IcNj4UQAoMZI5FIJBKJRCKRSCQSiUQikUgkEolEIpG+izh+iZ9ijIVPvTd0baRclhic0+17QvOrqfzT/4pBP8K7QUulvrzGWvdG0A0328oJOtwxLISA7IXf+OzcB/ZXfzw01wJUhgwsHO0eqvbge0Rrj4SuTybrPt23h7nHLayZWVh3Cp0IIfRa9UyteIPnl/4YSzfD8on1w1/n8aF5iOuyQVx1PwBaXuZmdvbyDKT5UPMnFB/u5dDqNGPo3O+7pJDn2QW9fTG0rmYBwc1dt2bzzsblLNQM5qXQlZ6a/eeij3rPhFj+eWpcM7wwekyZzbJPaR4YC57NPaavJ71XcvcyS0+YQ7+sWNSfP7RLP5cnvtfWcq8/m96v5Xy/AvLyn8GmlUrmXwI9iRv9al/6+xfJeW0McUGluUhGHgB/zJS5y4patkt+Ocny0M0ludlnjg/OJ/VeGnBbQ29Ien94eJapVpzH7gh/cqilbzIZA7OZGfNdrFneykLXiQ/bHcyM+bSkuih00gm7nasCbbdaLD60igGu3z2zdjEcGlUOmsdmNJbtlo0mqHkxaDV6cTAMQWbMDL0qBd3E4btHWS0K0UGqphB07HkGaanImZXCUaETQ58Zks5ZpgZAx76i7ljQd5WTJAOgx6ZcTkjy9VMsiseEjgvPqGvNbZxBFoAeG1I4TGgn4LnbZmg+ltmhvo4I42iuODr0NdqGocqtVIEFbWICjwsd02mDDj0GacuQZRdVYEHHtaELNvRYoK+Rocem03ds6LuG+sdW6DGIPhi6HtD1DDC0x4f2haA5B8el7boua8GBHq+/40PfBTBpgkIbVkCmMLQvAe2B0AoIXQOXZp+swwzt6mpKIWhg4vFs+BSnIaykH4XcAyuXVtVqTl0GusLyY1Wv5DW40AW04/GPg2bvBj0gXbMPOsCq2rA3wrYr/KEM9MaUd/iK2qZPXwOhFRB6YyIWevHbjjZM3npJWxZ6c5xuARG91WXdQxSNBoWgdQloXRjaN/jMjS8EHV4xRwy40DEREwVd2rFC0CXniNjQcW0C3akbA+3lW6Hb8cIPbOixQNEiQ8f8QGFDK3AKtRl6bDqJ3BXj/lqNDh1DncSFlgwcTTdDhzFvO6OeI+DjWzkb0KHjxNqjmlr6r2bue6AdNKfepphLuwLQsZ/4Gx7zzWekYgDo6HIWbYBpLAMmS8BQ0MeLB6w3XCEW2RaxdOLLGqkvSs1yOgqk9sTUEuUdF4/Rcyi0dYIxG1e/UWYwOq7Vg4wAa+e4aydni+gi6YgTdtgWP1giYaOBT7vdOtm0qmHeBqw6eZWj1D6/rhMPs7CigClbmySmale6J9KSgKve4OTnnGyQ3bHZNNkgy1yXnRhu1IWPQxc/ZUe++pzaHHq6CJ5mynSrWJc3NO4sAx4DQro5XmVFPpUyZ2xazQhcPr1JcTA1r9IF1SHDw3KirU83dknlA9A10jpNzivgrCHCpdRc8ev2ntSE/cdcih2DepbzH3gMirnpjf68xUe4uk473YsPnB17tC877fG+CtM5iJbPj1c3rqrktDFEmz39yc8f3OKEmzy5H1ou5o+N1D/cIil0PH/Ktmvh5bbavsL42rX/xuKhlq3Qq16j9uwM/pZHsP/Aw+7/xTHodoLB7t0WvHvdNhgJGiEGaQ7/FsL/8eHFn8r4lh8lwVq2Dc5WVj1veGHkh8Xa4v6Hf2gnrjIU/6QRiUQikUgkEolEIpFIJBKJRCKRSCQSifR99A+QQLqujpJ2+QAAAABJRU5ErkJggg==\";\n","import { APPLE_TOUCH_ICON_PNG, ICON_192_PNG, ICON_512_PNG, ICON_SVG, MASKABLE_512_PNG, MASKABLE_SVG } from \"./icons.js\";\n\n/*\n * What makes the dashboard an installable web app: a manifest, icons, a\n * service worker, the script that registers it, and a page to show offline.\n * None of it says anything about the jobs, so it is served without the token\n * (a browser fetches the manifest and icons without cookies in some flows).\n */\n\n/** The page colours the app's window takes: the paper behind the sheet, and the sheet the header sits on. */\nexport const BACKGROUND_COLOR = \"#f4f4f5\";\nexport const THEME_COLOR = \"#ffffff\";\nexport const THEME_COLOR_DARK = \"#111113\";\n\n/** The manifest, for the dashboard mounted at `base` (\"\" at the root). */\nexport function manifest(base: string): string {\n const icon = (name: string, sizes: string, type: string, purpose: string) => ({ src: `${base}/icons/${name}`, sizes, type, purpose });\n return JSON.stringify({\n id: `${base}/`,\n name: \"CronWatch\",\n short_name: \"CronWatch\",\n description: \"The scheduled jobs of this app: their health, their last day, and their runs.\",\n start_url: `${base}/`,\n scope: `${base}/`,\n display: \"standalone\",\n background_color: BACKGROUND_COLOR,\n theme_color: THEME_COLOR,\n icons: [\n icon(\"icon.svg\", \"any\", \"image/svg+xml\", \"any\"),\n icon(\"maskable.svg\", \"any\", \"image/svg+xml\", \"maskable\"),\n icon(\"icon-192.png\", \"192x192\", \"image/png\", \"any\"),\n icon(\"icon-512.png\", \"512x512\", \"image/png\", \"any\"),\n icon(\"maskable-512.png\", \"512x512\", \"image/png\", \"maskable\"),\n ],\n });\n}\n\n/**\n * Registers the service worker, and does nothing else. The page works the\n * same without it. Its own URL gives the base, so it is the same text\n * wherever the dashboard is mounted.\n */\nexport const APP_JS = `\"use strict\";\n(function () {\n var root = document.documentElement;\n try {\n var stored = localStorage.getItem(\"cronwatch-theme\");\n if (stored === \"light\" || stored === \"dark\") root.setAttribute(\"data-theme\", stored);\n } catch (e) {}\n document.addEventListener(\"keydown\", function (event) {\n if (!(event.metaKey || event.ctrlKey) || !event.shiftKey || event.altKey || event.code !== \"KeyD\") return;\n event.preventDefault();\n var shown = root.getAttribute(\"data-theme\") || (matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\");\n var next = shown === \"dark\" ? \"light\" : \"dark\";\n root.setAttribute(\"data-theme\", next);\n try { localStorage.setItem(\"cronwatch-theme\", next); } catch (e) {}\n });\n})();\n(function () {\n var script = document.currentScript;\n if (!script || !(\"serviceWorker\" in navigator)) return;\n var base = new URL(\"./\", script.src);\n navigator.serviceWorker.register(new URL(\"sw.js\", base).href, { scope: base.pathname }).catch(function () {});\n})();\n`;\n\n/**\n * The service worker. It caches the app shell (the offline page, the\n * manifest, the icons, and app.js) and nothing else: every other request goes\n * to the network as the page made it, and its answer is never stored, since\n * the pages and the JSON carry job data. When a page cannot be reached it\n * shows the offline page. Its scope gives the base, so it is the same text\n * wherever the dashboard is mounted.\n */\nexport const SW_JS = `\"use strict\";\nvar VERSION = \"cronwatch-shell-1\";\nvar SCOPE = self.registration.scope;\nvar CACHE = VERSION + \" \" + SCOPE;\nvar SHELL = [\"offline\", \"manifest.webmanifest\", \"app.js\", \"icons/icon.svg\", \"icons/maskable.svg\", \"icons/icon-192.png\", \"icons/icon-512.png\", \"icons/maskable-512.png\", \"icons/apple-touch-icon.png\"].map(function (path) {\n return new URL(path, SCOPE).href;\n});\nvar OFFLINE = SHELL[0];\n\nself.addEventListener(\"install\", function (event) {\n event.waitUntil(caches.open(CACHE).then(function (cache) {\n return cache.addAll(SHELL.map(function (url) { return new Request(url, { credentials: \"omit\", cache: \"reload\" }); }));\n }).then(function () { return self.skipWaiting(); }));\n});\n\nself.addEventListener(\"activate\", function (event) {\n event.waitUntil(caches.keys().then(function (keys) {\n return Promise.all(keys.filter(function (key) {\n return key !== CACHE && key.indexOf(\"cronwatch-shell-\") === 0 && key.slice(key.indexOf(\" \") + 1) === SCOPE;\n }).map(function (key) { return caches.delete(key); }));\n }).then(function () { return self.clients.claim(); }));\n});\n\nself.addEventListener(\"fetch\", function (event) {\n var request = event.request;\n if (request.method !== \"GET\") return;\n var url = new URL(request.url);\n url.search = \"\";\n if (SHELL.indexOf(url.href) !== -1 && url.href !== OFFLINE) {\n event.respondWith(caches.open(CACHE).then(function (cache) {\n return cache.match(url.href).then(function (hit) { return hit || fetch(request); });\n }));\n return;\n }\n if (request.mode !== \"navigate\") return;\n event.respondWith(fetch(request).catch(function () {\n return caches.open(CACHE).then(function (cache) { return cache.match(OFFLINE); }).then(function (page) {\n return page || new Response(\"You are offline.\", { status: 503, headers: { \"content-type\": \"text/plain; charset=utf-8\" } });\n });\n }));\n});\n`;\n\nexport interface StaticAsset {\n type: string;\n body: string | Uint8Array<ArrayBuffer>;\n cache: string;\n /** The service worker, which may control everything under the base. */\n worker?: boolean;\n}\n\nconst YEAR = \"public, max-age=31536000, immutable\";\nconst REVALIDATE = \"no-cache\";\n\nfunction decode(base64: string): Uint8Array<ArrayBuffer> {\n const bytes = atob(base64);\n const out = new Uint8Array(bytes.length);\n for (let i = 0; i < bytes.length; i++) out[i] = bytes.charCodeAt(i);\n return out;\n}\n\nconst ICONS: Record<string, () => StaticAsset> = {\n \"/icons/icon.svg\": () => ({ type: \"image/svg+xml\", body: ICON_SVG, cache: YEAR }),\n \"/icons/maskable.svg\": () => ({ type: \"image/svg+xml\", body: MASKABLE_SVG, cache: YEAR }),\n \"/icons/icon-192.png\": () => ({ type: \"image/png\", body: decode(ICON_192_PNG), cache: YEAR }),\n \"/icons/icon-512.png\": () => ({ type: \"image/png\", body: decode(ICON_512_PNG), cache: YEAR }),\n \"/icons/maskable-512.png\": () => ({ type: \"image/png\", body: decode(MASKABLE_512_PNG), cache: YEAR }),\n \"/icons/apple-touch-icon.png\": () => ({ type: \"image/png\", body: decode(APPLE_TOUCH_ICON_PNG), cache: YEAR }),\n};\n\n/**\n * The app shell file at `path` (the path under the base), or null. The\n * offline page is HTML and is served by the routes themselves.\n */\nexport function staticAsset(path: string, base: string): StaticAsset | null {\n if (path === \"/manifest.webmanifest\") return { type: \"application/manifest+json\", body: manifest(base), cache: REVALIDATE };\n if (path === \"/app.js\") return { type: \"text/javascript; charset=utf-8\", body: APP_JS, cache: REVALIDATE };\n if (path === \"/sw.js\") return { type: \"text/javascript; charset=utf-8\", body: SW_JS, cache: REVALIDATE, worker: true };\n return Object.hasOwn(ICONS, path) ? ICONS[path]!() : null;\n}\n","/** This release of @cronwatch/sdk. scripts/release.mjs keeps it in step with package.json. */\nexport const VERSION = \"0.14.2\";\n\n/**\n * The dashboard JSON API's version, which GET <base>/api answers. It goes up\n * only for a change that is not additive (a field removed or retyped, a path\n * moved), and such a change waits for a major release.\n */\nexport const API_VERSION = 1;\n","/**\n * The dashboard's timelines: one lane per job (or per day, on a job's page),\n * drawn on the server as inline SVG so the page needs no script.\n *\n * Every time a job was due is a faint tick, worked out from its schedule with\n * the same functions the checks use (nextFire and expectation), so the lane\n * shows the cadence the job is meant to keep. Every run it recorded is a\n * solid mark on top, as wide as it took and coloured by how it ended. A slot\n * the check has reported missed is a dashed box. The empty part of a lane\n * carries a short note about anything open, and a visually hidden list says\n * the same things in words.\n *\n * Every time is UTC: without script the page cannot know the viewer's zone.\n */\nimport { FIRST_DATE_MS, LAST_DATE_MS, formatDuration } from \"../duration.js\";\nimport { finishedAtOf, graceMs, isStuck, timeoutMs } from \"../evaluate.js\";\nimport { andList } from \"../format.js\";\nimport { expectation, firesBetween, intervalDue, parseSchedule, type ParsedSchedule } from \"../schedule.js\";\nimport type { JobSummary, Run } from \"../types.js\";\nimport { escapeHtml as h, escapeName } from \"./escape.js\";\n\nconst HOUR = 3_600_000;\nconst DAY = 24 * HOUR;\n\n/** The board's span: the last day, plus a few hours ahead so what is due soon shows. */\nexport const BOARD_BEHIND_MS = DAY;\nexport const BOARD_AHEAD_MS = 3 * HOUR;\n/** How many jobs the board's timeline draws. The table below it lists every job. */\nexport const BOARD_LANES = 30;\n/**\n * Runs read for a lane when the twenty the table reads start inside the span,\n * so a frequent job's lane is not cut short. Older runs than this are shown\n * as not loaded rather than as absent.\n */\nexport const BOARD_RUNS = 200;\n/** How many days a job's page draws. */\nexport const WEEK_DAYS = 7;\n\n/** Width of a lane in SVG units. Lanes stretch to fit, so strokes do not scale. */\nconst W = 1000;\n/** A lane with more due times than this shows its cadence as a dotted line instead. */\nconst MAX_TICKS = 330;\n/** More missed slots than this are drawn as one dashed band. */\nconst MAX_BOXES = 8;\n/** The narrowest a missed box is drawn, in SVG units. */\nconst MIN_BOX = 10;\n\nconst MONTHS = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\nconst WEEKDAYS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\n/** \"22:42\", in UTC. */\nexport function clock(t: number): string {\n return new Date(t).toISOString().slice(11, 16);\n}\n\n/** \"Sat 26 Sep\", in UTC. */\nexport function dayLabel(t: number): string {\n const d = new Date(t);\n return `${WEEKDAYS[d.getUTCDay()]} ${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]}`;\n}\n\n/**\n * \"22:42\" on the same UTC day as `now`, otherwise \"25 Sep 22:42\", and\n * \"1 Jan 0001 02:00\" in another UTC year. A time before the year 1 or after\n * 9999 (a start read from a foreign or damaged row) is \"before 1 Jan 0001\n * 00:00\" or \"after 31 Dec 9999 23:59\".\n */\nexport function when(t: number, now: number): string {\n if (t > LAST_DATE_MS) return \"after 31 Dec 9999 23:59\";\n if (!(t >= FIRST_DATE_MS)) return \"before 1 Jan 0001 00:00\";\n if (Math.floor(t / DAY) === Math.floor(now / DAY)) return clock(t);\n const d = new Date(t);\n const year = d.getUTCFullYear();\n const other = year === new Date(now).getUTCFullYear() ? \"\" : ` ${String(year).padStart(4, \"0\")}`;\n return `${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]}${other} ${clock(t)}`;\n}\n\n/** The stretch of time a timeline draws, and the moment it was drawn. */\nexport interface Span {\n from: number;\n to: number;\n now: number;\n}\n\n/** The job's schedule, parsed, or null when it has none or it no longer parses. */\nexport function parsedSchedule(job: JobSummary): ParsedSchedule | null {\n if (!job.definition.schedule) return null;\n try {\n return parseSchedule(job.definition.schedule, job.definition.timezone);\n } catch {\n return null;\n }\n}\n\nfunction safely<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport interface DueTimes {\n /** Every time the job was or will be due within the span, ascending. */\n times: number[];\n /** True when there are too many to draw one by one; `times` is then empty. */\n dense: boolean;\n}\n\n/**\n * When the job was due within `from` to `to`. A cron's fires come from\n * nextFire. An interval is due one period after each run started (after it\n * finished, for a run that outlasted the period: intervalDue), and after\n * the last run once a period for as long as nothing runs (the times a\n * missed interval job keeps being asked for); with no run yet, from its\n * next expected time.\n */\nexport function dueTimes(job: JobSummary, parsed: ParsedSchedule | null, runs: Run[], from: number, to: number): DueTimes {\n if (!parsed) return { times: [], dense: false };\n if (parsed.kind === \"interval\") {\n const every = parsed.everyMs!;\n if ((to - from) / every > MAX_TICKS) return { times: [], dense: true };\n const ordered = [...runs].sort((a, b) => a.startedAt - b.startedAt);\n const dues = ordered.map((r) => intervalDue(every, r.startedAt, finishedAtOf(r)));\n const times = new Set<number>();\n for (const t of dues) {\n if (t >= from && t <= to) times.add(t);\n }\n let t = dues.length ? dues[dues.length - 1]! : job.nextExpectedAt;\n if (t !== null) {\n if (t < from) t += Math.ceil((from - t) / every) * every;\n for (; t <= to; t += every) times.add(t);\n }\n return { times: [...times].sort((a, b) => a - b), dense: false };\n }\n const times = safely(() => firesBetween(parsed, from - 1, to, MAX_TICKS), []);\n return times === null ? { times: [], dense: true } : { times, dense: false };\n}\n\n/**\n * The slot a missed job was due at, the one the check reported: the first\n * fire its last run does not cover (expectation(), as onCheck works it\n * out). A job that never ran has no run to count from, so the latest due\n * time whose grace has passed stands in. Null when missed is not open.\n */\nexport function missedAt(job: JobSummary, parsed: ParsedSchedule | null, times: number[], now: number): number | null {\n if (!parsed || !job.open.includes(\"missed\")) return null;\n const grace = safely(() => graceMs(job.definition), 0);\n const lastRun = job.lastRun;\n if (lastRun) return safely(() => expectation(parsed, lastRun.startedAt, lastRun.startedAt, grace, finishedAtOf(lastRun))?.dueAt ?? null, null);\n const past = times.filter((t) => t + grace < now);\n return past.length ? past[past.length - 1]! : null;\n}\n\ntype Tone = \"ok\" | \"bad\" | \"timeout\" | \"warn\" | \"running\" | \"stuck\";\n\nfunction toneOf(run: Run, job: JobSummary, now: number): Tone {\n if (run.status === \"running\") return safely(() => isStuck(job.definition, run, now), false) ? \"stuck\" : \"running\";\n if (run.status === \"failed\") return \"bad\";\n if (run.status === \"timeout\") return \"timeout\";\n const latest = job.lastRun?.id === run.id;\n return latest && (job.open.includes(\"over_budget\") || job.open.includes(\"under_floor\") || job.open.includes(\"slow\")) ? \"warn\" : \"ok\";\n}\n\nfunction timeoutText(job: JobSummary): string {\n return safely(() => formatDuration(timeoutMs(job.definition)), \"configured\");\n}\n\n/** One run, as its tooltip says it. */\nfunction describeRun(run: Run, tone: Tone, job: JobSummary, now: number): string {\n const at = `${when(run.startedAt, now)} UTC`;\n if (tone === \"running\") return `running since ${at}, ${formatDuration(now - run.startedAt)} so far`;\n if (tone === \"stuck\") return `running since ${at}, past its ${timeoutText(job)} timeout`;\n const took = run.durationMs !== null ? `, took ${formatDuration(run.durationMs)}` : \"\";\n const extra = tone === \"warn\" ? (job.open.includes(\"over_budget\") ? \", over budget\" : job.open.includes(\"under_floor\") ? \", under floor\" : \", slow\") : \"\";\n return `${run.status} at ${at}${took}${extra}`;\n}\n\n/** The metrics of the job's last run that went over their ceilings. */\nfunction overCeilings(job: JobSummary): string[] {\n const metrics = job.lastRun?.metrics ?? {};\n return Object.entries(job.definition.budget ?? {}).filter(([k, limit]) => (metrics[k] ?? -Infinity) > limit).map(([k]) => k);\n}\n\n/** The metrics of the job's last run under their floors, or at 0 or less without one. */\nfunction underFloors(job: JobSummary): string[] {\n const floors = job.definition.floor ?? {};\n return Object.entries(job.lastRun?.metrics ?? {}).filter(([k, v]) => (floors[k] !== undefined ? v < floors[k] : v <= 0)).map(([k]) => k);\n}\n\n/** What is worth saying about the job in a few words, or null when all is well. */\nexport function laneNote(job: JobSummary, missed: number | null, now: number): string | null {\n const last = job.lastRun;\n if (job.silencedUntil !== null && job.silencedUntil > now) return `silenced until ${when(job.silencedUntil, now)}`;\n if (job.open.includes(\"missed\")) return missed !== null ? `due ${when(missed, now)}, nothing ran` : \"overdue, nothing ran\";\n if (last?.status === \"running\") {\n const stuck = safely(() => isStuck(job.definition, last, now), false);\n return stuck ? `running since ${when(last.startedAt, now)}, past its ${timeoutText(job)} timeout` : `running since ${when(last.startedAt, now)}`;\n }\n if (last?.status === \"failed\") return `failed at ${when(last.startedAt, now)}${job.consecutiveFailures > 1 ? `, ${job.consecutiveFailures} in a row` : \"\"}`;\n if (last?.status === \"timeout\") return `timed out at ${when(last.startedAt, now)}`;\n if (job.open.includes(\"stuck\")) return \"stuck\";\n if (job.open.includes(\"over_budget\") && last) {\n const over = overCeilings(job);\n return `went over budget${over.length ? ` on ${andList(over)}` : \"\"} at ${when(last.startedAt, now)}`;\n }\n if (job.open.includes(\"under_floor\") && last) {\n const under = underFloors(job);\n return `fell short${under.length ? ` on ${andList(under)}` : \"\"} at ${when(last.startedAt, now)}`;\n }\n if (job.open.includes(\"slow\") && last?.durationMs != null) return `slow: took ${formatDuration(last.durationMs)}`;\n if (job.open.includes(\"failed\")) return \"failing\";\n if (!last && job.nextExpectedAt !== null) return `no runs yet, first due ${when(job.nextExpectedAt, now)}`;\n return null;\n}\n\n/** Everything one lane shows: the marks, the note, and the same in words. */\nexport interface LaneInput {\n job: JobSummary;\n /** The job's runs, any order. Only those overlapping the span are drawn. */\n runs: Run[];\n /** False when older runs exist that were not read; the lane says so before its oldest run. */\n complete: boolean;\n}\n\ninterface LaneParts {\n svg: string;\n note: string;\n words: string;\n}\n\nconst f = (n: number) => n.toFixed(1);\n\n/** Animation delay for a mark at x, so marks arrive in time order, left to right. */\nconst delay = (x: number, base = 80, perUnit = 0.75) => `--d:${Math.round(base + Math.max(0, x) * perUnit)}ms`;\n\nfunction lane(input: LaneInput, span: Span, options: { nowInLane: boolean; label: string }): LaneParts {\n const { job } = input;\n const { from, to, now } = span;\n const x = (t: number) => Math.min(W, Math.max(0, ((t - from) / (to - from)) * W));\n const parsed = parsedSchedule(job);\n const due = dueTimes(job, parsed, input.runs, from, to);\n const missed = missedAt(job, parsed, due.times, now);\n const grace = safely(() => graceMs(job.definition), 0);\n const name = options.label;\n const busy: [number, number][] = [];\n\n let s = `<svg class=\"marks\" viewBox=\"0 0 ${W} 24\" preserveAspectRatio=\"none\" aria-hidden=\"true\" focusable=\"false\">`;\n if (options.nowInLane && now > from && now < to) s += `<rect class=\"ahead\" x=\"${f(x(now))}\" y=\"0\" width=\"${f(W - x(now))}\" height=\"24\"/>`;\n s += `<line class=\"base\" x1=\"0\" y1=\"12\" x2=\"${W}\" y2=\"12\"/>`;\n\n const inSpan = input.runs.filter((r) => r.startedAt <= to && (r.finishedAt ?? now) >= from).sort((a, b) => a.startedAt - b.startedAt);\n if (!input.complete) {\n const oldest = Math.min(...input.runs.map((r) => r.startedAt));\n if (Number.isFinite(oldest) && oldest > from) {\n s += `<rect class=\"unloaded\" x=\"0\" y=\"4\" width=\"${f(x(oldest))}\" height=\"16\"><title>${h(`${name}: runs before ${when(oldest, now)} UTC are not loaded here`)}</title></rect>`;\n }\n }\n\n if (due.dense) {\n s += `<line class=\"cadence\" x1=\"0\" y1=\"12\" x2=\"${W}\" y2=\"12\"><title>${h(`${name}: due ${job.definition.schedule ?? \"\"}, too often to mark each time`)}</title></line>`;\n }\n for (const t of due.times) {\n const tx = x(t);\n s += `<line class=\"tick${t > now ? \" ahead\" : \"\"}\" x1=\"${f(tx)}\" y1=\"6\" x2=\"${f(tx)}\" y2=\"18\" style=\"${delay(tx, 0, 0.45)}\"/>`;\n }\n\n // Missed slots: the reported one and every later one whose grace has run out.\n if (missed !== null && missed <= to) {\n const slots = due.dense ? [] : due.times.filter((t) => t >= missed && t + grace < now);\n if (!slots.includes(missed) && missed >= from) slots.unshift(missed);\n const title = h(`${name}: due ${when(missed, now)} UTC, nothing started${slots.length > 1 ? ` (${slots.length} slots in this span)` : \"\"}`);\n if (due.dense || slots.length > MAX_BOXES) {\n const x1 = x(Math.max(missed, from)), x2 = Math.max(x(now), x1 + MIN_BOX);\n s += `<rect class=\"missed\" x=\"${f(x1)}\" y=\"5\" width=\"${f(x2 - x1)}\" height=\"14\" style=\"${delay(x1)}\"><title>${title}</title></rect>`;\n busy.push([x1, x2]);\n } else {\n for (const t of slots) {\n if (t < from) continue;\n const x1 = x(t), width = Math.max(x(t + grace) - x1, MIN_BOX);\n s += `<rect class=\"missed\" x=\"${f(x1)}\" y=\"5\" width=\"${f(width)}\" height=\"14\" style=\"${delay(x1)}\"><title>${title}</title></rect>`;\n busy.push([x1, x1 + width]);\n }\n }\n }\n\n for (const run of inSpan) {\n const tone = toneOf(run, job, now);\n // A zero-width rect is not drawn at all; its stroke gives short runs their width.\n const x1 = x(run.startedAt), x2 = Math.max(x(run.finishedAt ?? now), x1 + 0.5);\n s += `<rect class=\"run ${tone}\" x=\"${f(x1)}\" y=\"5\" width=\"${f(x2 - x1)}\" height=\"14\" style=\"${delay(x1)}\"><title>${h(`${name}: ${describeRun(run, tone, job, now)}`)}</title></rect>`;\n busy.push([x1, x2]);\n }\n\n if (options.nowInLane && now > from && now < to) s += `<line class=\"nowline\" x1=\"${f(x(now))}\" y1=\"0\" x2=\"${f(x(now))}\" y2=\"24\"/>`;\n s += `</svg>`;\n\n // The note goes wherever the lane is actually empty, so it never sits on\n // the marks it describes; it is cut short with an ellipsis when narrow.\n const text = laneNote(job, missed, now);\n let note = \"\";\n if (text) {\n const nowX = x(now);\n const lo = busy.length ? Math.min(...busy.map((b) => b[0])) : nowX;\n const hi = busy.length ? Math.max(...busy.map((b) => b[1])) : nowX;\n const right = W - hi >= lo;\n const room = right ? W - hi : lo;\n if (room > 90) {\n const edge = right ? hi + 14 : lo - 14;\n const place = right ? `left:${f(edge / 10)}%` : `right:${f(100 - edge / 10)}%`;\n note = `<span class=\"note${right ? \"\" : \" before\"}\" style=\"${place};max-width:${f((room - 18) / 10)}%\">${h(text)}</span>`;\n }\n }\n\n return { svg: s, note, words: words(job, inSpan, due, missed, span, text) };\n}\n\n/** The lane in words, for anyone who cannot see it. */\nfunction words(job: JobSummary, runs: Run[], due: DueTimes, missed: number | null, span: Span, note: string | null): string {\n const parts: string[] = [];\n if (due.dense) parts.push(`due ${job.definition.schedule}`);\n else if (job.definition.schedule) {\n const n = due.times.filter((t) => t <= span.now).length;\n parts.push(`due ${n === 0 ? \"no times\" : n === 1 ? \"once\" : `${n} times`} so far`);\n }\n const ok = runs.filter((r) => r.status === \"ok\").length;\n parts.push(`${runs.length} ${runs.length === 1 ? \"run\" : \"runs\"} recorded${!runs.length ? \"\" : ok === runs.length ? (ok === 1 ? \", ok\" : \", all ok\") : ok ? `, ${ok} ok` : \"\"}`);\n for (const r of runs.filter((r) => r.status === \"failed\" || r.status === \"timeout\").slice(-5)) {\n parts.push(`${r.status} at ${when(r.startedAt, span.now)} UTC after ${formatDuration(r.durationMs ?? 0)}`);\n }\n if (missed !== null) parts.push(`due at ${when(missed, span.now)} UTC and nothing started`);\n if (note && !/^(due |failed at|timed out)/.test(note)) parts.push(note);\n return parts.join(\"; \");\n}\n\n/** Grid lines and hour labels every `step`, on UTC boundaries. */\nfunction hours(span: Span, step: number, nowLabel: boolean): { lines: string; labels: string } {\n const x = (t: number) => ((t - span.from) / (span.to - span.from)) * W;\n const nowX = x(span.now);\n let lines = \"\", labels = \"\";\n for (let t = Math.ceil(span.from / step) * step; t <= span.to; t += step) {\n const gx = x(t);\n lines += `<i class=\"gl\" style=\"left:${f(gx / 10)}%\"></i>`;\n const nearNow = nowLabel && Math.abs(gx - nowX) < 70;\n if (gx < 25 || gx > W - 25 || nearNow) continue;\n const minor = Math.round(t / HOUR) % 6 !== 0;\n // On a phone the track is too narrow for a label this close to \"now\"; CSS hides it there.\n const near = nowLabel && Math.abs(gx - nowX) < 170;\n const cls = [minor && \"minor\", near && \"near\"].filter(Boolean).join(\" \");\n labels += `<span class=\"${cls}\" style=\"left:${f(gx / 10)}%\">${clock(t)}</span>`;\n }\n if (nowLabel && span.now >= span.from && span.now <= span.to) labels += `<span class=\"nowlabel\" style=\"left:${f(nowX / 10)}%\">now ${clock(span.now)}</span>`;\n return { lines, labels };\n}\n\n/** The key under a timeline: a small sample of each mark and what it means. */\nfunction legend(): string {\n const key = (inner: string) => `<svg class=\"key\" viewBox=\"0 0 16 12\" aria-hidden=\"true\" focusable=\"false\">${inner}</svg>`;\n const box = (cls: string) => key(`<rect class=\"${cls}\" x=\"2\" y=\"1\" width=\"12\" height=\"10\"/>`);\n const items: [string, string][] = [\n [key(`<line class=\"tick\" x1=\"8\" y1=\"1\" x2=\"8\" y2=\"11\"/>`), \"due\"],\n [box(\"run ok\"), \"ran\"],\n [box(\"run bad\"), \"failed\"],\n [box(\"run timeout\"), \"timed out\"],\n [box(\"run warn\"), \"over budget, under floor, or slow\"],\n [box(\"run running\"), \"running\"],\n [box(\"missed\"), \"missed\"],\n ];\n return `<p class=\"legend\" aria-hidden=\"true\">${items.map(([k, label]) => `<span>${k}${label}</span>`).join(\"\")}</p>`;\n}\n\nfunction stateClass(job: JobSummary): string {\n return ({ healthy: \"ok\", late: \"warn\", failing: \"bad\", stuck: \"bad\", silenced: \"muted\", never_ran: \"muted\" } as const)[job.health];\n}\n\n/**\n * The board's timeline: one lane per job across `span`, with a shared now\n * line and the first BOARD_LANES jobs only. `total` is how many jobs there\n * are in all, for the note when some are left out.\n */\nexport function dayTimeline(lanes: LaneInput[], span: Span, base: string, total: number): string {\n const grid = hours(span, 3 * HOUR, true);\n const nowX = ((span.now - span.from) / (span.to - span.from)) * 100;\n const rows = lanes.map((input) => {\n const { job } = input;\n const parts = lane(input, span, { nowInLane: false, label: job.name });\n return {\n html: `<li class=\"lane\"><div class=\"who\"><i class=\"sq ${stateClass(job)}\" aria-hidden=\"true\"></i><a class=\"name\" href=\"${h(base)}/jobs/${encodeURIComponent(job.name)}\">${escapeName(job.name)}</a><span class=\"sched\">${h(job.definition.schedule ?? \"no schedule\")}</span></div><div class=\"track\">${parts.svg}${parts.note}</div></li>`,\n words: `<li>${h(`${job.name} (${job.definition.schedule ?? \"no schedule\"}): ${parts.words}.`)}</li>`,\n };\n });\n const more = total > lanes.length ? `<p class=\"more\">Showing the first ${lanes.length} of ${total} jobs here; the table below lists them all.</p>` : \"\";\n return `<figure class=\"timeline day\">\n<div class=\"axis\" aria-hidden=\"true\"><span></span><div class=\"hours\">${grid.labels}</div></div>\n<div class=\"field\">\n<div class=\"under\" aria-hidden=\"true\"><span></span><div>${grid.lines}<i class=\"future\" style=\"left:${f(nowX)}%\"></i></div></div>\n<ol class=\"lanes\">${rows.map((r) => r.html).join(\"\")}</ol>\n<div class=\"over\" aria-hidden=\"true\"><span></span><div><i class=\"now\" style=\"left:${f(nowX)}%\"></i></div></div>\n</div>\n${legend()}${more}\n<ul class=\"vh\">${rows.map((r) => r.words).join(\"\")}</ul>\n</figure>`;\n}\n\n/**\n * A job's page: its last WEEK_DAYS UTC days, today first, one lane each.\n * `complete` is false when the runs read do not reach back over the week.\n */\nexport function weekTimeline(job: JobSummary, runs: Run[], complete: boolean, now: number): string {\n const today = Math.floor(now / DAY) * DAY;\n const oldest = runs.length ? Math.min(...runs.map((r) => r.startedAt)) : null;\n const first: Span = { from: today, to: today + DAY, now };\n const grid = hours(first, 3 * HOUR, false);\n const rows: { html: string; words: string }[] = [];\n for (let i = 0; i < WEEK_DAYS; i++) {\n const from = today - i * DAY;\n const span: Span = { from, to: from + DAY, now };\n const dayRuns = runs.filter((r) => r.startedAt < span.to && (r.finishedAt ?? now) >= from);\n const known = complete || (oldest !== null && oldest <= from);\n const label = i === 0 ? \"today\" : dayLabel(from);\n const parts = lane({ job, runs, complete: known }, span, { nowInLane: i === 0, label: `${job.name}, ${label}` });\n const count = `${dayRuns.length} ${dayRuns.length === 1 ? \"run\" : \"runs\"}`;\n rows.push({\n html: `<li class=\"lane${i === 0 ? \" today\" : \"\"}\"><div class=\"who\"><span class=\"name\">${h(i === 0 ? `Today, ${dayLabel(from).slice(4)}` : dayLabel(from))}</span><span class=\"sched\">${h(count)}</span></div><div class=\"track\">${parts.svg}${i === 0 ? parts.note : \"\"}</div></li>`,\n words: `<li>${h(`${i === 0 ? \"Today\" : dayLabel(from)}: ${parts.words}.`)}</li>`,\n });\n }\n return `<figure class=\"timeline week\">\n<div class=\"axis\" aria-hidden=\"true\"><span></span><div class=\"hours\">${grid.labels}</div></div>\n<div class=\"field\">\n<div class=\"under\" aria-hidden=\"true\"><span></span><div>${grid.lines}</div></div>\n<ol class=\"lanes\">${rows.map((r) => r.html).join(\"\")}</ol>\n</div>\n${legend()}\n<ul class=\"vh\">${rows.map((r) => r.words).join(\"\")}</ul>\n</figure>`;\n}\n\n/**\n * How many runs a job's page reads so its week is drawn in full: roughly how\n * often the schedule was due over the week, with room to spare, from 50 (what\n * the run list shows) to 500 (the most runs() returns).\n */\nexport function weekRunsLimit(job: JobSummary, now: number): number {\n const parsed = parsedSchedule(job);\n if (!parsed) return 50;\n const from = Math.floor(now / DAY) * DAY - (WEEK_DAYS - 1) * DAY;\n const span = now + DAY - from;\n // A cron's fires over one day, times the week: close enough, and cheap.\n const expected = parsed.kind === \"interval\"\n ? span / parsed.everyMs!\n : (() => {\n const due = dueTimes(job, parsed, [], now - DAY, now);\n return due.dense ? Infinity : (due.times.length * span) / DAY;\n })();\n return Math.min(500, Math.max(50, Math.ceil(expected * 1.2) + 10));\n}\n","import { beyondDates, formatDuration, formatRelative, isoTime } from \"../duration.js\";\nimport type { JobSummary, Run } from \"../types.js\";\nimport { escapeHtml, escapeName } from \"./escape.js\";\nimport { THEME_COLOR, THEME_COLOR_DARK } from \"./pwa.js\";\nimport { VERSION } from \"../version.js\";\nimport { BOARD_LANES, BOARD_AHEAD_MS, BOARD_BEHIND_MS, clock, dayTimeline, laneNote, missedAt, parsedSchedule, weekTimeline, when, type LaneInput } from \"./timeline.js\";\n\nexport { escapeHtml };\n\nconst h = escapeHtml;\n\n/** The footer's note of what is serving the page, linked to the changelog. Nothing is fetched to compare it. */\nconst VERSION_LINK = `<a class=\"version\" href=\"https://github.com/cronwatchdev/cronwatch/blob/main/CHANGELOG.md\">@cronwatch/sdk ${VERSION}</a>`;\n\n/*\n * Set like cronwatch.dev: a printed sheet on grey paper, a serif for what a\n * person reads, a mono for what a machine printed, neutral greys, and colour\n * only for the states CronWatch reports. The page loads nothing but its own\n * app shell (its CSP is default-src 'none' plus 'self' for the script, the\n * manifest, the worker, and images), so the fonts are system stacks that echo\n * the site's Newsreader and IBM Plex Mono, and use them when they are installed.\n *\n * Installed as an app (display-mode: standalone) the header stays at the top\n * as the app's bar, and the page keeps clear of notches and the home\n * indicator with the safe-area insets (the viewport is viewport-fit=cover).\n *\n * Motion is CSS only and says something: marks arrive in time order, the now\n * line drops in last, and open problems (a missed slot, a running bar) breathe\n * slowly. prefers-reduced-motion turns all of it off. Only opacity and\n * transform move, so nothing shifts the layout.\n */\nconst CSS = `\n:root{color-scheme:light dark;--paper:#f4f4f5;--sheet:#fff;--sunk:#fafafa;--rule:#e4e4e7;--rule-2:#d4d4d8;--tick:#909098;--ink:#000;--body:#18181b;--muted:#71717a;--ok:#15803d;--warn:#a16207;--bad:#b91c1c;--serif:\"Newsreader\",ui-serif,Georgia,Cambria,\"Times New Roman\",serif;--mono:\"IBM Plex Mono\",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;--who:200px}\n@media(prefers-color-scheme:dark){:root:not([data-theme=light]){--paper:#09090b;--sheet:#111113;--sunk:#18181b;--rule:#27272a;--rule-2:#3f3f46;--tick:#66666f;--ink:#fff;--body:#e4e4e7;--muted:#a1a1aa;--ok:#4ade80;--warn:#fbbf24;--bad:#f87171}}\n:root[data-theme=light]{color-scheme:light}:root[data-theme=dark]{color-scheme:dark;--paper:#09090b;--sheet:#111113;--sunk:#18181b;--rule:#27272a;--rule-2:#3f3f46;--tick:#66666f;--ink:#fff;--body:#e4e4e7;--muted:#a1a1aa;--ok:#4ade80;--warn:#fbbf24;--bad:#f87171}\n*{box-sizing:border-box}html{-webkit-text-size-adjust:100%}\nbody{margin:0;background:var(--paper);color:var(--ink);font:400 16px/1.55 var(--serif);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}\na{color:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.16em;text-decoration-color:var(--rule-2)}a:hover{text-decoration-color:currentColor}\n:focus-visible{outline:2px solid var(--ink);outline-offset:2px}\ncode,pre,.mono{font-family:var(--mono)}\n.vh{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n.sheet{max-width:1180px;min-height:100vh;margin:0 auto;background:var(--sheet);border-inline:1px solid var(--rule);padding:0 clamp(16px,4vw,48px)}\n.top{display:flex;align-items:center;justify-content:space-between;gap:12px 20px;flex-wrap:wrap;padding:18px 0 17px;border-bottom:1px solid var(--rule)}\n.brand{display:flex;align-items:center;gap:10px;margin:0;font:600 18px/1.2 var(--serif);letter-spacing:-.01em;min-width:0}\n.brand a{display:inline-flex;align-items:center;gap:10px;text-decoration:none}.brand svg{width:24px;height:24px;flex:none;color:var(--ink)}\n.brand .crumb{font:500 15px/1.2 var(--mono);color:var(--body);overflow-wrap:anywhere}.brand .slash{color:var(--rule-2);font-weight:400}\n.actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap}\n.meta{font:400 12px/1.4 var(--mono);color:var(--muted)}\nbutton,a.button,details.confirm>summary{font:500 12.5px/1 var(--mono);color:var(--ink);background:var(--sheet);border:1px solid var(--rule-2);border-radius:3px;height:32px;padding:0 11px;cursor:pointer}\na.button{display:inline-flex;align-items:center;text-decoration:none}\nbutton:hover,a.button:hover,details.confirm>summary:hover{border-color:var(--muted)}\nbutton.primary{background:var(--ink);border-color:var(--ink);color:var(--sheet)}button.primary:hover{opacity:.86}button.danger{color:var(--bad)}button.danger:hover{border-color:var(--bad)}\nform.inline{display:inline-flex;align-items:center;gap:6px;margin:0}\ndetails.confirm{display:inline-flex;align-items:center;flex-wrap:wrap;gap:8px;margin:0}details.confirm>summary{list-style:none;display:inline-flex;align-items:center}\ndetails.confirm>summary::-webkit-details-marker{display:none}details.confirm[open]>summary{border-color:var(--muted)}\ndetails.confirm form{flex-wrap:wrap;font-size:14px;color:var(--muted)}.delete details{margin-top:16px}\n.sec{display:grid;grid-template-columns:150px minmax(0,1fr);gap:10px 40px;padding:30px 0;border-top:1px solid var(--rule)}\n.top+main>.sec:first-child{border-top:0}\n.sec>h2{margin:0;font:500 11px/1.5 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--muted);padding-top:5px}\n.sec>.wide{grid-column:1/-1;min-width:0}\n.lede{margin:0;color:var(--muted);font-size:16px;max-width:64ch;text-wrap:pretty}\n.headline{margin:0;font:400 clamp(24px,3.2vw,32px)/1.2 var(--serif);letter-spacing:-.01em;text-wrap:balance}\n.headline b{font-weight:600}\n.state{font:500 12.5px/1.4 var(--mono);white-space:nowrap}.state+.state::before{content:\" \\\\00b7 \";color:var(--muted);font-weight:400}\n.ok{color:var(--ok)}.warn{color:var(--warn)}.bad{color:var(--bad)}.muted{color:var(--muted)}.info{color:var(--ink)}\n.sq{display:inline-block;width:8px;height:8px;border-radius:1.5px;background:currentColor;margin-right:7px;vertical-align:1px;flex:none}\n.sq.muted{background:none;box-shadow:inset 0 0 0 1.5px var(--tick)}\n.figures{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:0;margin:22px 0 0;border-top:1px solid var(--rule)}\n.figures>div{display:flex;flex-direction:column-reverse;justify-content:flex-end;gap:4px;padding:14px 16px 2px 0}\n.figures dt{font:500 11px/1.4 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);display:flex;align-items:center}\n.figures dd{margin:0;font:400 30px/1.1 var(--serif);font-variant-numeric:tabular-nums;color:var(--ink)}\n.figures dd small{font-size:17px;color:var(--muted)}\n.figures .zero dd{color:var(--rule-2)}\n.figures .bad dd{color:var(--bad)}.figures .warn dd{color:var(--warn)}\n.stateline{margin:12px 0 0;display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px}\n.stateline .why{font-style:italic;color:var(--muted)}\n.jobname{margin:0;font:500 clamp(22px,3vw,28px)/1.2 var(--mono);letter-spacing:-.01em;overflow-wrap:anywhere}\n.desc{margin:6px 0 0;color:var(--body);max-width:64ch}\n.intro .actions{margin-top:18px}\ntable{width:100%;border-collapse:collapse}\nth{text-align:left;font:500 10.5px/1.2 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);padding:0 14px 10px 0;border-bottom:1px solid var(--rule);white-space:nowrap}\ntd{padding:12px 14px 12px 0;border-bottom:1px solid var(--rule);vertical-align:top;font:400 12.5px/1.5 var(--mono);color:var(--body)}\ntbody tr:last-child td{border-bottom:0}\ntd.job{font-family:var(--serif);font-size:15px;min-width:180px}\ntd.job .name{font:500 13.5px/1.5 var(--mono);color:var(--ink)}\ntd.job .desc{display:block;margin:2px 0 0;font-size:14px;color:var(--muted);line-height:1.4}\ntd .tz,td .sub{display:block;color:var(--muted);font-size:11.5px}\n.nowrap{white-space:nowrap}\n.spark{display:block;overflow:visible}.spark rect{fill:var(--tick)}.spark rect.bad{fill:var(--bad)}.spark rect.warn{fill:var(--warn)}.spark rect.running{fill:none;stroke:var(--ink);stroke-width:1}\n.runs td{padding-top:11px;padding-bottom:11px}.runs tr.has-detail td{border-bottom:0;padding-bottom:4px}.runs tr.detail td{padding-top:0}\n.metrics{display:flex;flex-wrap:wrap;gap:2px 14px}.metrics .k{color:var(--muted)}\npre{margin:6px 0 0;padding:12px 14px;background:var(--sunk);border:1px solid var(--rule);border-radius:3px;font:400 12.5px/1.55 var(--mono);color:var(--body);white-space:pre-wrap;overflow-wrap:anywhere;max-height:340px;overflow:auto}\ndetails.out{margin-top:4px}details.out>summary{cursor:pointer;font:400 12px/1.6 var(--mono);color:var(--muted)}details.out>summary:hover{color:var(--ink)}\ndetails.out.error>summary{color:var(--bad)}\ndl.def{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:8px 28px;margin:0}\ndl.def dt{font:500 11px/1.9 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}\ndl.def dd{margin:0;font:400 13.5px/1.7 var(--mono);color:var(--body);overflow-wrap:anywhere}dl.def dd.prose{font:400 16px/1.55 var(--serif)}\n.empty{padding:28px 0 8px;color:var(--muted);max-width:60ch}\n.empty code{font-size:.86em;color:var(--ink)}\n.message{padding:clamp(56px,12vh,120px) 0;text-align:center}\n.message h1{margin:0;font:400 clamp(28px,4vw,40px)/1.15 var(--serif);letter-spacing:-.015em}\n.message p{margin:14px auto 0;max-width:52ch;color:var(--muted);text-wrap:pretty}\n.signin{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px;margin:28px auto 0;max-width:420px}\n.signin label{font:500 11px/1.4 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}\n.signin input{flex:1 1 180px;min-width:0;font:400 16px/1.2 var(--mono);color:var(--ink);background:var(--sheet);border:1px solid var(--rule-2);border-radius:3px;height:32px;padding:0 10px}\nfooter{display:flex;flex-wrap:wrap;gap:6px 18px;padding:20px 0 40px;border-top:1px solid var(--rule);font:400 12px/1.5 var(--mono);color:var(--muted)}footer .version{margin-left:auto}\n.timeline{margin:18px 0 0}\n.timeline .axis,.timeline .under,.timeline .over,.timeline .lane{display:grid;grid-template-columns:var(--who) minmax(0,1fr)}\n.timeline .hours{position:relative;height:22px;font:400 11px/1 var(--mono);color:var(--muted);letter-spacing:.04em}\n.timeline .hours span{position:absolute;top:2px;transform:translateX(-50%);white-space:nowrap}\n.timeline .hours .nowlabel{color:var(--ink);font-weight:500;animation:cw-fade .5s 1s both}\n.timeline .field{position:relative}\n.timeline .under,.timeline .over{position:absolute;inset:0;pointer-events:none}\n.timeline .under>div,.timeline .over>div{position:relative}\n.timeline .gl{position:absolute;top:0;bottom:0;width:1px;background:var(--rule)}\n.timeline .future{position:absolute;top:0;bottom:0;right:0;background:var(--sunk)}\n.timeline .now{position:absolute;top:-6px;bottom:0;width:1.5px;margin-left:-.75px;background:var(--ink);transform-origin:top;animation:cw-drop .6s .85s cubic-bezier(.2,.8,.2,1) both}\n.timeline .lanes{position:relative;list-style:none;margin:0;padding:0;border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}\n.timeline .lane{align-items:center;min-height:40px}\n.timeline .who{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;column-gap:0;padding:6px 14px 6px 0;min-width:0}\n.timeline .who .sched{grid-column:2}\n.timeline.week .who{display:flex;align-items:baseline;gap:10px}\n.timeline .who .name{font:500 13px/1.35 var(--mono);color:var(--ink);overflow-wrap:anywhere}\n.timeline .who .sched{font:400 11px/1.35 var(--mono);color:var(--muted);white-space:nowrap}\n.timeline .track{position:relative;height:24px}\n.timeline .marks{display:block;width:100%;height:24px;overflow:visible}\n.timeline .note{position:absolute;top:50%;transform:translateY(-50%);font:italic 400 14px/1.2 var(--serif);color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 3px;text-shadow:0 0 3px var(--sheet),0 0 3px var(--sheet),0 0 6px var(--sheet);animation:cw-fade .6s 1.1s both}\n.timeline .note.before{text-align:right}\n.timeline .legend{display:flex;flex-wrap:wrap;gap:6px 18px;margin:14px 0 0;padding-left:var(--who);font:400 11.5px/1.4 var(--mono);color:var(--muted)}\n.timeline .legend span{display:inline-flex;align-items:center;gap:7px}\n.timeline .more{margin:10px 0 0;padding-left:var(--who);font-size:14px;color:var(--muted);font-style:italic}\n.key{width:16px;height:12px;overflow:visible}\n.marks *{vector-effect:non-scaling-stroke}\nsvg .base{stroke:var(--rule);stroke-width:1}\nsvg .tick{stroke:var(--tick);stroke-width:1.5}svg .tick.ahead{stroke-dasharray:2 2;opacity:.75}\nsvg .cadence{stroke:var(--tick);stroke-width:2;stroke-dasharray:1 3}\nsvg .run{stroke-width:2;stroke-linejoin:round}\nsvg .run.ok{fill:var(--ok);stroke:var(--ok)}\nsvg .run.bad{fill:var(--bad);stroke:var(--bad)}\nsvg .run.timeout{fill:var(--bad);fill-opacity:.28;stroke:var(--bad);stroke-width:1.5}\nsvg .run.warn{fill:var(--warn);stroke:var(--warn)}\nsvg .run.running{fill:none;stroke:var(--ink);stroke-width:1.5}\nsvg .run.stuck{fill:var(--bad);fill-opacity:.12;stroke:var(--bad);stroke-width:1.5}\nsvg .missed{fill:none;stroke:var(--bad);stroke-width:1.5;stroke-dasharray:3 2.5}\nsvg .unloaded{fill:var(--sunk)}\nsvg .ahead{fill:var(--sunk)}\nsvg .nowline{stroke:var(--ink);stroke-width:1.5}\n.marks .tick{animation:cw-fade .4s var(--d,0ms) both}\n.marks .run,.marks .missed{transform-box:fill-box;transform-origin:0 50%;animation:cw-grow .55s cubic-bezier(.2,.8,.2,1) var(--d,0ms) both}\n.marks .missed,.marks .run.running,.marks .run.stuck{animation:cw-grow .55s cubic-bezier(.2,.8,.2,1) var(--d,0ms) both,cw-breathe 2.6s ease-in-out calc(var(--d,0ms) + .6s) infinite alternate}\n.figures>div{animation:cw-rise .5s cubic-bezier(.2,.8,.2,1) both}\n.figures>div:nth-child(2){animation-delay:40ms}.figures>div:nth-child(3){animation-delay:80ms}.figures>div:nth-child(4){animation-delay:120ms}.figures>div:nth-child(5){animation-delay:160ms}.figures>div:nth-child(6){animation-delay:200ms}\n@keyframes cw-fade{from{opacity:0}}\n@keyframes cw-grow{from{opacity:0;transform:scaleX(0)}}\n@keyframes cw-drop{from{opacity:0;transform:scaleY(0)}}\n@keyframes cw-rise{from{opacity:0;transform:translateY(4px)}}\n@keyframes cw-breathe{to{opacity:.38}}\nbody{padding:0 env(safe-area-inset-right) 0 env(safe-area-inset-left)}\nfooter{padding-bottom:calc(40px + env(safe-area-inset-bottom))}\n@media(display-mode:standalone){\n.top{position:sticky;top:0;z-index:2;background:var(--sheet);padding-top:calc(14px + env(safe-area-inset-top));padding-bottom:13px;-webkit-user-select:none;user-select:none}\n.message{padding-top:clamp(40px,8vh,80px)}\n}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}\n@media(max-width:760px){\n.sec{grid-template-columns:minmax(0,1fr);gap:10px;padding:24px 0}\n.hide-sm{display:none}\n:root{--who:0px}\n.timeline .lane{grid-template-columns:minmax(0,1fr);padding:6px 0 8px}\n.timeline .who{padding:0 0 4px}\n.timeline .who .name{background:var(--sheet);padding-right:4px}\n.timeline .hours .minor,.timeline .hours .near{display:none}\n.timeline .note{font-size:13px}\ntd.job{min-width:0}\ntable.board thead{display:none}\ntable.board tr{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:14px;padding:12px 0;border-bottom:1px solid var(--rule)}\ntable.board tbody tr:last-child{border-bottom:0}\ntable.board td{border:0;padding:0}\ntable.board td.last{grid-column:1/-1;margin-top:4px;white-space:normal}\ntable.board td.last .sub{display:inline;margin-left:8px}\n.runs td.nowrap{white-space:normal}\ndl.def{grid-template-columns:minmax(0,1fr);gap:0}dl.def dd{margin-bottom:10px}\n}\n`;\n\n/** The clock face from cronwatch.dev, in the text colour. */\nconst MARK = `<svg viewBox=\"0 0 40 40\" aria-hidden=\"true\" focusable=\"false\"><rect x=\"1\" y=\"1\" width=\"38\" height=\"38\" rx=\"9.5\" fill=\"none\" stroke=\"currentColor\" stroke-opacity=\".22\" stroke-width=\"1.5\"/><circle cx=\"20\" cy=\"20\" r=\"10.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/><path d=\"M20 12.5V20h6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;\n\n/**\n * A page. `base` is where the dashboard is mounted (\"\" at the root): the head\n * links the web app manifest, the icons, and app.js, the one script, which\n * registers the service worker and toggles the theme (routes/pwa.ts). Everything works\n * without it.\n */\nexport function layout(title: string, body: string, base: string, options: { refresh?: number } = {}): string {\n const b = h(base);\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\">\n<meta name=\"robots\" content=\"noindex,nofollow\">\n<meta name=\"color-scheme\" content=\"light dark\">\n${options.refresh ? `<meta http-equiv=\"refresh\" content=\"${options.refresh}\">` : \"\"}\n<title>${h(title)}</title>\n<meta name=\"theme-color\" content=\"${THEME_COLOR}\" media=\"(prefers-color-scheme: light)\">\n<meta name=\"theme-color\" content=\"${THEME_COLOR_DARK}\" media=\"(prefers-color-scheme: dark)\">\n<meta name=\"mobile-web-app-capable\" content=\"yes\">\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n<meta name=\"apple-mobile-web-app-title\" content=\"CronWatch\">\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">\n<link rel=\"manifest\" href=\"${b}/manifest.webmanifest\">\n<link rel=\"icon\" href=\"${b}/icons/icon.svg\" type=\"image/svg+xml\">\n<link rel=\"apple-touch-icon\" href=\"${b}/icons/apple-touch-icon.png\">\n<script src=\"${b}/app.js\" defer></script>\n<style>${CSS}</style>\n</head>\n<body><div class=\"sheet\">${body}</div></body>\n</html>`;\n}\n\nfunction brand(base: string, crumb?: string): string {\n const home = `<a href=\"${h(base)}/\">${MARK}<span>CronWatch</span></a>`;\n return crumb === undefined\n ? `<p class=\"brand\">${home}</p>`\n : `<p class=\"brand\">${home}<span class=\"slash\" aria-hidden=\"true\">/</span><span class=\"crumb\">${escapeName(crumb)}</span></p>`;\n}\n\nconst HEALTH: Record<JobSummary[\"health\"], [string, string]> = {\n failing: [\"bad\", \"failing\"],\n stuck: [\"bad\", \"stuck\"],\n late: [\"warn\", \"late\"],\n healthy: [\"ok\", \"healthy\"],\n silenced: [\"muted\", \"silenced\"],\n never_ran: [\"muted\", \"never ran\"],\n};\n\n/** The job's health, with any open condition it does not already say (over budget, under floor, slow) after it. */\nfunction healthState(job: JobSummary): string {\n const [cls, label] = HEALTH[job.health];\n const extras = job.open.filter((c) => ![\"missed\", \"failed\", \"stuck\"].includes(c)).map((c) => `<span class=\"state warn\">${h(c.replace(\"_\", \" \"))}</span>`).join(\"\");\n return `<span class=\"state ${cls}\"><i class=\"sq ${cls}\" aria-hidden=\"true\"></i>${label}</span>${extras}`;\n}\n\nfunction runState(run: Run): string {\n const cls = run.status === \"ok\" ? \"ok\" : run.status === \"running\" ? \"info\" : \"bad\";\n return `<span class=\"state ${cls}\">${h(run.status)}</span>`;\n}\n\n/** The last twenty runs, oldest first, as bars as tall as they took; grey unless something went wrong. */\nfunction sparkline(runs: Run[]): string {\n const points = [...runs].slice(0, 20).reverse();\n if (points.length < 2) return \"\";\n const bar = 4, gap = 1.5, hgt = 22;\n const max = Math.max(...points.map((r) => r.durationMs ?? 0), 1);\n const bars = points.map((r, i) => {\n const x = (i * (bar + gap)).toFixed(1);\n if (r.status === \"running\") return `<rect class=\"running\" x=\"${x}\" y=\"${hgt - 6.5}\" width=\"${bar - 1}\" height=\"6\"/>`;\n const tall = Math.max(r.status === \"ok\" ? 2 : 6, ((r.durationMs ?? 0) / max) * hgt);\n const cls = r.status === \"ok\" ? \"\" : ` class=\"bad\"`;\n return `<rect${cls} x=\"${x}\" y=\"${(hgt - tall).toFixed(1)}\" width=\"${bar}\" height=\"${tall.toFixed(1)}\" rx=\".5\"/>`;\n }).join(\"\");\n const w = points.length * (bar + gap) - gap;\n return `<svg class=\"spark\" width=\"${w.toFixed(1)}\" height=\"${hgt}\" viewBox=\"0 0 ${w.toFixed(1)} ${hgt}\" aria-hidden=\"true\" focusable=\"false\">${bars}</svg>`;\n}\n\nfunction stamp(at: number | null, now: number): string {\n if (at === null) return `<span class=\"muted\">never</span>`;\n const iso = isoTime(at);\n if (iso === null) return `<span class=\"nowrap\">${beyondDates(at)}</span>`;\n return `<time class=\"nowrap\" datetime=\"${iso}\" title=\"${iso.replace(\"T\", \" \").slice(0, 19)} UTC\">${h(formatRelative(at, now))}</time>`;\n}\n\n/** Counts by health, the ones needing attention first; a zero is set faint rather than left out, so the row keeps its shape. */\nfunction healthFigures(jobs: JobSummary[]): string {\n return `<dl class=\"figures\">${(Object.keys(HEALTH) as JobSummary[\"health\"][]).map((health) => {\n const [cls, label] = HEALTH[health];\n const n = jobs.filter((j) => j.health === health).length;\n return `<div class=\"${n === 0 ? \"zero\" : cls}\"><dt><i class=\"sq ${cls}\" aria-hidden=\"true\"></i>${label}</dt><dd>${n}</dd></div>`;\n }).join(\"\")}</dl>`;\n}\n\nexport function dashboardPage(\n jobs: JobSummary[],\n runsByJob: Map<string, Run[]>,\n now: number,\n base: string,\n checkedAt: number | null,\n lanes: LaneInput[] = jobs.slice(0, BOARD_LANES).map((job) => ({ job, runs: runsByJob.get(job.name) ?? [], complete: true })),\n): string {\n const attention = jobs.filter((j) => j.health !== \"healthy\").length;\n const headline = jobs.length === 0\n ? \"No jobs yet.\"\n : attention === 0\n ? `${jobs.length === 1 ? \"The one job is\" : `All ${jobs.length} jobs are`} healthy.`\n : `${jobs.length} job${jobs.length === 1 ? \"\" : \"s\"}, <b>${attention} needing attention</b>.`;\n\n const rows = jobs.map((job) => {\n const last = job.lastRun;\n const d = job.definition;\n return `<tr>\n<td class=\"job\"><a class=\"name\" href=\"${h(base)}/jobs/${encodeURIComponent(job.name)}\">${escapeName(job.name)}</a>${d.description ? `<span class=\"desc\">${h(d.description)}</span>` : \"\"}</td>\n<td class=\"health\">${healthState(job)}</td>\n<td class=\"nowrap hide-sm\">${d.schedule ? `${h(d.schedule)}${d.timezone ? `<span class=\"tz\">${h(d.timezone)}</span>` : \"\"}` : `<span class=\"muted\">no schedule</span>`}</td>\n<td class=\"nowrap last\">${last ? `${runState(last)} ${stamp(last.startedAt, now)}${last.durationMs !== null ? `<span class=\"sub\">took ${h(formatDuration(last.durationMs))}</span>` : \"\"}` : `<span class=\"muted\">never</span>`}</td>\n<td class=\"nowrap hide-sm\">${job.nextExpectedAt !== null ? `${job.nextExpectedAt < now ? `<span class=\"state warn\">overdue</span> ` : \"\"}${stamp(job.nextExpectedAt, now)}<span class=\"sub\">${h(when(job.nextExpectedAt, now))} UTC</span>` : `<span class=\"muted\">not scheduled</span>`}</td>\n<td class=\"hide-sm\">${sparkline(runsByJob.get(job.name) ?? [])}</td>\n</tr>`;\n }).join(\"\\n\");\n\n const span = { from: now - BOARD_BEHIND_MS, to: now + BOARD_AHEAD_MS, now };\n const body = `\n<header class=\"top\">\n ${brand(base)}\n <div class=\"actions\">\n <span class=\"meta\">${h(clock(now))} UTC${checkedAt ? `, checked ${h(formatRelative(checkedAt, now))}` : \"\"}</span>\n <form class=\"inline\" method=\"post\" action=\"${h(base)}/check\"><button class=\"primary\" type=\"submit\">Run check now</button></form>\n </div>\n</header>\n<main>\n<section class=\"sec\" aria-label=\"Health\">\n <h2>Health</h2>\n <div>\n <p class=\"headline\">${headline}</p>\n ${jobs.length ? healthFigures(jobs) : `<p class=\"empty\">Declare one with <code>cw.job(\"name\", { schedule: \"0 2 * * *\" })</code> and run it once, and it shows up here.</p>`}\n </div>\n</section>\n${jobs.length ? `<section class=\"sec\" aria-label=\"Last 24 hours\">\n <h2>Last 24 hours</h2>\n <p class=\"lede\">One lane per job. Faint ticks mark when it was due, bars the runs it recorded, as long as they took. A dashed box is a slot nothing ran in. Times are UTC.</p>\n <div class=\"wide\">${dayTimeline(lanes, span, base, jobs.length)}</div>\n</section>\n<section class=\"sec\" aria-label=\"Jobs\">\n <h2>Jobs</h2>\n <p class=\"lede\">Every job in the store. Open one for its week, its runs, and their output.</p>\n <div class=\"wide\"><table class=\"board\">\n<thead><tr><th>Job</th><th>Health</th><th class=\"hide-sm\">Schedule</th><th>Last run</th><th class=\"hide-sm\">Next due</th><th class=\"hide-sm\">Recent runs</th></tr></thead>\n<tbody>${rows}</tbody></table></div>\n</section>` : \"\"}\n</main>\n<footer><span>Refreshes every minute. Times are UTC.</span><a href=\"${h(base)}/api/jobs\">JSON</a>${VERSION_LINK}</footer>`;\n return layout(\"CronWatch\", body, base, { refresh: 60 });\n}\n\n/**\n * One job: its state and figures, its last seven days, its runs with their\n * output, and its definition. `complete` is false when `runs` does not reach\n * back over the whole week (the run list shows the newest fifty).\n */\nexport function jobPage(job: JobSummary, runs: Run[], now: number, base: string, complete = true): string {\n const d = job.definition;\n const okRate = `${Math.round(job.stats.okRate * 100)}%`;\n const listed = runs.slice(0, 50);\n const runRows = listed.map((run) => {\n const detail = [\n run.error ? `<details class=\"out error\" open><summary>error</summary><pre>${h(run.error)}</pre></details>` : \"\",\n run.output ? `<details class=\"out\"${run.status === \"ok\" ? \"\" : \" open\"}><summary>output</summary><pre>${h(run.output)}</pre></details>` : \"\",\n ].join(\"\");\n // A foreign row may hold a metric that is no finite number (null, text); it is left out.\n const metrics = Object.entries(run.metrics ?? {})\n .filter(([, v]) => typeof v === \"number\" && Number.isFinite(v))\n .map(([k, v]) => `<span><span class=\"k\">${h(k)}</span> ${h(Number.isInteger(v) ? v : v.toFixed(4))}</span>`).join(\"\");\n return `<tr${detail ? ` class=\"has-detail\"` : \"\"}>\n<td class=\"nowrap\">${runState(run)}</td>\n<td class=\"nowrap\">${h(when(run.startedAt, now))} <span class=\"muted\">UTC</span><span class=\"sub\">${stamp(run.startedAt, now)}</span></td>\n<td class=\"nowrap\">${run.durationMs !== null ? h(formatDuration(run.durationMs)) : `<span class=\"muted\">running</span>`}</td>\n<td class=\"hide-sm\">${metrics ? `<span class=\"metrics\">${metrics}</span>` : \"\"}</td>\n<td class=\"hide-sm muted\">${h(run.trigger)}</td>\n</tr>${detail ? `<tr class=\"detail\"><td colspan=\"5\">${detail}</td></tr>` : \"\"}`;\n }).join(\"\\n\");\n\n const silenced = job.silencedUntil !== null && job.silencedUntil > now;\n const path = `${h(base)}/jobs/${encodeURIComponent(job.name)}`;\n const parsed = parsedSchedule(job);\n const why = laneNote(job, missedAt(job, parsed, [], now), now);\n const body = `\n<header class=\"top\">\n ${brand(base, job.name)}\n <div class=\"actions\"><span class=\"meta\">${h(clock(now))} UTC</span></div>\n</header>\n<main>\n<section class=\"sec intro\" aria-label=\"Job\">\n <h2>Job</h2>\n <div>\n <h1 class=\"jobname\">${escapeName(job.name)}</h1>\n ${d.description ? `<p class=\"desc\">${h(d.description)}</p>` : \"\"}\n <p class=\"stateline\">${healthState(job)}${why ? `<span class=\"why\">${h(why)}</span>` : \"\"}</p>\n <div class=\"actions\">\n ${silenced\n ? `<form class=\"inline\" method=\"post\" action=\"${path}/unsilence\"><button type=\"submit\">Unsilence (until ${h(formatRelative(job.silencedUntil!, now))})</button></form>`\n : `<details class=\"confirm\"><summary>Silence</summary><form class=\"inline\" method=\"post\" action=\"${path}/silence\"><span>for</span> <button type=\"submit\" name=\"for\" value=\"1h\">1 hour</button><button type=\"submit\" name=\"for\" value=\"4h\">4 hours</button><button type=\"submit\" name=\"for\" value=\"1d\">1 day</button><button type=\"submit\" name=\"for\" value=\"7d\">1 week</button></form></details>`}\n </div>\n <dl class=\"figures\">\n <div><dt>Last run</dt><dd>${job.lastRun ? h(formatRelative(job.lastRun.startedAt, now)) : \"never\"}</dd></div>\n <div><dt>Next due</dt><dd>${job.nextExpectedAt !== null ? h(formatRelative(job.nextExpectedAt, now)) : `<small>no schedule</small>`}</dd></div>\n <div><dt>Success, last ${h(job.stats.runs)}</dt><dd>${h(okRate)}</dd></div>\n <div><dt>p50 / p95</dt><dd>${job.stats.p50Ms !== null ? h(formatDuration(job.stats.p50Ms)) : \"?\"} <small>/ ${job.stats.p95Ms !== null ? h(formatDuration(job.stats.p95Ms)) : \"?\"}</small></dd></div>\n </dl>\n </div>\n</section>\n<section class=\"sec\" aria-label=\"Last 7 days\">\n <h2>Last 7 days</h2>\n <p class=\"lede\">A lane per UTC day, today first. Faint ticks mark when the job was due, bars its runs, as long as they took.</p>\n <div class=\"wide\">${weekTimeline(job, runs, complete, now)}</div>\n</section>\n<section class=\"sec\" aria-label=\"Runs\">\n <h2>Runs</h2>\n ${listed.length === 0 ? `<p class=\"lede\">No runs yet.</p>` : `<p class=\"lede\">The newest ${listed.length === 1 ? \"run\" : `${listed.length} runs`}, with any error and output.</p>\n <div class=\"wide\"><table class=\"runs\">\n<thead><tr><th>Status</th><th>Started</th><th>Took</th><th class=\"hide-sm\">Metrics</th><th class=\"hide-sm\">Trigger</th></tr></thead>\n<tbody>${runRows}</tbody></table></div>`}\n</section>\n<section class=\"sec\" aria-label=\"Definition\">\n <h2>Definition</h2>\n <dl class=\"def\">\n <dt>Schedule</dt><dd>${d.schedule ? h(d.schedule) + (d.timezone ? ` <span class=\"muted\">${h(d.timezone)}</span>` : \"\") : `<span class=\"muted\">none</span>`}</dd>\n <dt>Grace</dt><dd>${h(d.grace ?? \"10m\")}</dd>\n <dt>Timeout</dt><dd>${h(d.timeout ?? \"1h\")}</dd>\n ${d.maxDuration ? `<dt>Max duration</dt><dd>${h(d.maxDuration)}</dd>` : \"\"}\n ${d.budget ? `<dt>Budget</dt><dd>${h(Object.entries(d.budget).map(([k, v]) => `${k} ≤ ${v}`).join(\", \"))}</dd>` : \"\"}\n ${d.floor ? `<dt>Floor</dt><dd>${h(Object.entries(d.floor).map(([k, v]) => `${k} ≥ ${v}`).join(\", \"))}</dd>` : \"\"}\n ${d.expect ? `<dt>Expect</dt><dd>${h(d.expect)}</dd>` : \"\"}\n ${d.failuresBeforeAlert && d.failuresBeforeAlert > 1 ? `<dt>Alert after</dt><dd>${h(d.failuresBeforeAlert)} consecutive failures</dd>` : \"\"}\n ${d.tags?.length ? `<dt>Tags</dt><dd>${d.tags.map((t) => h(t)).join(\", \")}</dd>` : \"\"}\n ${job.open.length ? `<dt>Open</dt><dd>${job.open.map((c) => `<span class=\"state ${c === \"failed\" || c === \"stuck\" ? \"bad\" : \"warn\"}\">${h(c.replace(\"_\", \" \"))}</span>`).join(\"\")}</dd>` : \"\"}\n ${job.consecutiveFailures > 0 ? `<dt>Failures in a row</dt><dd>${h(job.consecutiveFailures)}</dd>` : \"\"}\n </dl>\n</section>\n<section class=\"sec delete\" aria-label=\"Delete\">\n <h2>Delete</h2>\n <div>\n <p class=\"lede\">Removes this job and all its runs from the store, which cannot be undone. A job still in your code comes back on its next run, with no history.</p>\n <details class=\"confirm\"><summary>Delete history</summary><form class=\"inline\" method=\"post\" action=\"${path}/forget\"><span>Delete this job and all its runs?</span> <button class=\"danger\" type=\"submit\">Delete</button><a class=\"button\" href=\"${path}\">Cancel</a></form></details>\n </div>\n</section>\n</main>\n<footer><span>Refreshes every minute. Times are UTC.</span><a href=\"${h(base)}/api/jobs/${encodeURIComponent(job.name)}\">JSON</a>${VERSION_LINK}</footer>`;\n return layout(`${job.name}: CronWatch`, body, base, { refresh: 60 });\n}\n\n/**\n * A page with one message. With `signIn`, a form under it posts the token\n * to <base>/signin in the body, keeping it out of the URL and access logs,\n * and the routes set the cookie: the way in\n * where there is no address bar to open a link with, such as an app on an\n * iPhone's home screen, which keeps its cookies apart from Safari's.\n */\nexport function messagePage(title: string, message: string, base: string, signIn = false): string {\n const form = signIn ? `<form class=\"signin\" method=\"post\" action=\"${h(base)}/signin\"><label for=\"token\">Token</label><input id=\"token\" name=\"token\" type=\"password\" autocomplete=\"current-password\" autocapitalize=\"off\" spellcheck=\"false\" required><button class=\"primary\" type=\"submit\">Sign in</button></form>` : \"\";\n return layout(title, `<header class=\"top\">${brand(base)}</header><main class=\"message\"><h1>${h(title)}</h1><p>${h(message)}</p>${form}</main>`, base);\n}\n","import type { Cronwatch } from \"../client.js\";\nimport { isDevelopment, readSecretEnv, secretOption } from \"../env.js\";\nimport { constantTimeEqual, json } from \"../http.js\";\nimport { parseDuration } from \"../duration.js\";\nimport type { Duration, JobSummary, Run } from \"../types.js\";\nimport { dashboardPage, jobPage, messagePage } from \"./html.js\";\nimport { staticAsset, type StaticAsset } from \"./pwa.js\";\nimport { API_VERSION, VERSION } from \"../version.js\";\nimport { BOARD_BEHIND_MS, BOARD_LANES, BOARD_RUNS, weekRunsLimit, type LaneInput } from \"./timeline.js\";\n\nexport interface RoutesOptions {\n /**\n * Required to reach anything. Send it as `Authorization: Bearer <token>`,\n * or open the dashboard once with `?token=<token>` and a cookie is set.\n * Defaults to process.env.CRONWATCH_TOKEN (on Cloudflare Workers, which\n * have no process, pass env.CRONWATCH_TOKEN); an empty string or one of\n * only whitespace, given here or in the variable, counts as unset, and any\n * other type (false, a number) throws.\n * With no token in development (the first of CRONWATCH_ENV, APP_ENV, and\n * NODE_ENV that is set names \"development\", \"dev\", or \"local\"; \"test\" and\n * \"testing\" are not development), the routes make a random one and print a\n * sign-in link to the server log on their first request; with no token\n * otherwise they answer 503. Pass `null` to opt out\n * and serve them open everywhere, for example behind your own auth.\n *\n * The check endpoint (/api/check) also accepts the client's cronSecret, so\n * a platform cron that sends `Authorization: Bearer <CRON_SECRET>` can\n * trigger checks without knowing the dashboard token.\n */\n token?: string | null;\n /** Where the routes are mounted, so links resolve. Default \"/cronwatch\". */\n basePath?: string;\n /**\n * The public origin the dashboard is served from, such as\n * \"https://app.example.com\", for an app behind a proxy whose request URLs\n * carry an internal host or scheme. Used in place of the request URL's\n * origin for the cross-site check on writes, the sign-in redirect (its\n * cookie is Secure when this is https, and the redirect back after a form\n * follows a Referer on this origin), and the development sign-in line.\n * Takes precedence over trustProxy. Without it, the development sign-in\n * line shows the request's origin only when its host is loopback\n * (localhost, *.localhost, 127.0.0.0/8, or ::1), and otherwise leaves the\n * host out, since a client controls it.\n */\n origin?: string;\n /**\n * Take the public origin from X-Forwarded-Proto and X-Forwarded-Host (the\n * first value of each, falling back to the request URL's scheme or host\n * for whichever is missing) when a request carries either. Only for an app\n * whose proxy sets or overwrites both headers: a client can send them too.\n * Default false, which ignores them.\n */\n trustProxy?: boolean;\n}\n\nexport type FetchHandler = (request: Request) => Promise<Response>;\n\nexport interface Routes {\n handler: FetchHandler;\n GET: FetchHandler;\n POST: FetchHandler;\n DELETE: FetchHandler;\n}\n\nconst COOKIE = \"cronwatch_token\";\n/**\n * What GET <base>/api says is serving it: the package, as its registry names\n * it, and the language. Each port answers with its own.\n */\nconst LIBRARY = \"@cronwatch/sdk\";\nconst LANGUAGE = \"typescript\";\n\n/**\n * The cookie holds a digest of the token, so a leaked cookie does not reveal\n * the bearer token itself: the SHA-256 of \"cronwatch-cookie:<token>\", as hex.\n * Web Crypto, so the routes need nothing from node: and run on Workers too.\n */\nasync function cookieValue(token: string): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(`cronwatch-cookie:${token}`));\n return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nconst DEFAULT_RUNS = 20;\nconst MAX_RUNS = 500;\n/** Runs per job the board reads in one go: the table's sparkline, and most jobs' lanes. */\nconst BOARD_PAGE_RUNS = 20;\n\n/**\n * The board's timeline lanes, the first BOARD_LANES jobs. The runs already\n * read for the table usually cover the last day; only a job whose twenty\n * newest runs all fall inside it (one that runs more often than every hour or so) is\n * read again, deeper, and those reads go out together.\n */\nasync function boardLanes(cw: Cronwatch, entries: { job: JobSummary; runs: Run[] }[], now: number): Promise<LaneInput[]> {\n const from = now - BOARD_BEHIND_MS;\n return Promise.all(entries.slice(0, BOARD_LANES).map(async ({ job, runs }) => {\n const short = runs.length >= BOARD_PAGE_RUNS && runs[runs.length - 1]!.startedAt > from;\n if (!short) return { job, runs, complete: true };\n const deeper = await cw.runs(job.name, BOARD_RUNS);\n return { job, runs: deeper, complete: deeper.length < BOARD_RUNS };\n }));\n}\n\n// 'self' only for what the app shell needs: app.js (which registers the\n// service worker and the theme toggle), the manifest, the worker, and the icons.\n// No inline script, and the pages work without any.\nconst CSP = \"default-src 'none'; script-src 'self'; style-src 'unsafe-inline'; img-src 'self' data:; manifest-src 'self'; worker-src 'self'; form-action 'self'; frame-ancestors 'none'; base-uri 'none'\";\n/** For the SVG icons, should one be opened on its own. */\nconst ASSET_CSP = \"default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'none'\";\n// same-origin rather than no-referrer: under no-referrer browsers send\n// `Origin: null` on form posts, which the CSRF check would refuse, and the\n// forms redirect back to the page named by the same-origin Referer.\nconst SECURITY_HEADERS = { \"x-content-type-options\": \"nosniff\", \"referrer-policy\": \"same-origin\", \"x-robots-tag\": \"noindex\" };\n\n/**\n * A token for one routes instance in development, when none is configured:\n * 32 random bytes, base64url (43 characters).\n */\nfunction developmentToken(): string {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n return btoa(String.fromCharCode(...bytes)).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/**\n * The line a development token is announced with, printed once with\n * console.info on the routes' first request:\n *\n * [cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: <origin><base>/?token=<token>\n *\n * <origin> is the `origin` option when set. Otherwise it is the first\n * request's public origin (scheme, host, and any port: the forwarded one\n * under trustProxy, else the request URL's), but only when its host is\n * loopback (\"localhost\", a name ending in \".localhost\", 127.0.0.0/8, or\n * ::1). That host comes from the request, which a client controls, so for\n * any other host the line leaves it out, and a spoofed first request cannot\n * point the link, token and all, somewhere else:\n *\n * [cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: <base>/?token=<token> on this server (the first request's host is not local, so the link leaves it out)\n *\n * <base> is the base path without a trailing slash (\"\" when mounted at the\n * root), and <token> the token as generated (base64url, so nothing needs\n * escaping).\n */\nfunction developmentSignInLine(origin: string | null, base: string, token: string): string {\n const intro = \"[cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: \";\n return origin === null\n ? `${intro}${base}/?token=${token} on this server (the first request's host is not local, so the link leaves it out)`\n : `${intro}${origin}${base}/?token=${token}`;\n}\n\n/**\n * Whether an origin's host is loopback: \"localhost\", a name ending in\n * \".localhost\", an IPv4 address in 127.0.0.0/8, or the IPv6 address ::1.\n */\nfunction isLoopbackOrigin(origin: string): boolean {\n let host: string;\n try {\n host = new URL(origin).hostname.toLowerCase();\n } catch {\n return false;\n }\n if (host === \"localhost\" || host.endsWith(\".localhost\")) return true;\n if (host === \"[::1]\") return true;\n const octets = /^127\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(host);\n return octets !== null && octets.slice(1).every((o) => Number(o) <= 255);\n}\n\nfunction safeDecode(value: string): string | null {\n try {\n return decodeURIComponent(value);\n } catch {\n return null;\n }\n}\n\nfunction readCookie(request: Request, name: string): string | null {\n const header = request.headers.get(\"cookie\");\n if (!header) return null;\n for (const part of header.split(\";\")) {\n const [k, ...rest] = part.trim().split(\"=\");\n // A malformed escape counts as no cookie.\n if (k === name) return safeDecode(rest.join(\"=\"));\n }\n return null;\n}\n\n/** The first entry of a comma-separated header, trimmed, or null when there is none. */\nfunction firstValue(value: string | null): string | null {\n const first = value?.split(\",\")[0]?.trim();\n return first ? first : null;\n}\n\n/**\n * The origin configured with `origin`, normalised, or null. Throws on a value\n * that is not an http or https origin, so a typo fails at startup.\n */\nfunction configuredOrigin(value: string | undefined): string | null {\n if (value === undefined || value === \"\") return null;\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new Error(`routes: origin must be an absolute URL such as \"https://app.example.com\", got ${JSON.stringify(value)}`);\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") throw new Error(`routes: origin must be http or https, got ${JSON.stringify(value)}`);\n return url.origin;\n}\n\n/**\n * The origin a browser sees for this request, with trustProxy: the forwarded\n * scheme and host when present and well formed, otherwise the request URL's own.\n */\nfunction forwardedOrigin(request: Request, url: URL): string {\n const proto = firstValue(request.headers.get(\"x-forwarded-proto\"))?.toLowerCase() ?? null;\n const host = firstValue(request.headers.get(\"x-forwarded-host\"));\n if (proto === null && host === null) return url.origin;\n if (proto !== null && proto !== \"http\" && proto !== \"https\") return url.origin;\n try {\n const built = new URL(`${proto ?? url.protocol.slice(0, -1)}://${host ?? url.host}`);\n // A \"host\" carrying a path, credentials, a query, or a fragment is not a host.\n if (built.pathname !== \"/\" || built.username || built.password || built.search || built.hash) return url.origin;\n return built.origin;\n } catch {\n return url.origin;\n }\n}\n\n/**\n * The token an Authorization header carries: what follows the scheme when\n * the scheme is Bearer (any case) and one or more whitespace characters\n * follow it, else null. Any other scheme (a proxy's Basic auth, say) is not\n * a bearer at all, so the cookie and ?token= are read as if no header came.\n */\nfunction bearerToken(header: string | null): string | null {\n const match = header === null ? null : /^Bearer\\s+([\\s\\S]*)$/i.exec(header);\n return match ? match[1]! : null;\n}\n\n/**\n * Where a sign-in through the form goes next: the page it was posted from\n * (the Referer) when that is on the public origin and its query has no\n * `token` parameter, else the dashboard.\n */\nfunction signInReturn(referer: string | null, publicOrigin: string, base: string): string {\n if (referer === null || !referer.startsWith(publicOrigin + \"/\")) return `${base}/`;\n let url: URL;\n try {\n url = new URL(referer);\n } catch {\n return `${base}/`;\n }\n return url.searchParams.has(\"token\") ? `${base}/` : referer;\n}\n\n/**\n * The path below the base, or null when the request is not under it. The\n * pathname, its dot segments already resolved by URL, must be the base or\n * start with the base and a \"/\": \"/cronwatchapi/jobs\" is not under\n * \"/cronwatch\", and neither is \"/cronwatch/../api/jobs\" (read as \"/api/jobs\").\n * An empty base, for routes mounted at the root, takes every path.\n */\nfunction stripBase(pathname: string, base: string): string | null {\n if (base !== \"\" && pathname !== base && !pathname.startsWith(`${base}/`)) return null;\n let path = pathname.slice(base.length);\n if (path === \"\") path = \"/\";\n if (path.length > 1 && path.endsWith(\"/\")) path = path.slice(0, -1);\n return path;\n}\n\n/** The most of a request body the routes read (1 MiB), as every port's; a body past it is answered 413. */\nconst MAX_REQUEST_BODY = 1 << 20;\n\n/** A request body past MAX_REQUEST_BODY. */\nconst TOO_LARGE = Symbol(\"too large\");\nconst BAD_BODY = Symbol(\"malformed body\");\n\n/**\n * The request's body, at most MAX_REQUEST_BODY bytes: refused from its\n * Content-Length when that says more, else read one byte past the cap at\n * most, so a client cannot make the server hold a body of any size. Its\n * forms and JSON are a few bytes.\n */\nasync function readLimited(request: Request): Promise<Uint8Array<ArrayBuffer> | typeof TOO_LARGE> {\n const length = Number(request.headers.get(\"content-length\"));\n if (Number.isFinite(length) && length > MAX_REQUEST_BODY) return TOO_LARGE;\n if (!request.body) return new Uint8Array(new ArrayBuffer(0));\n const reader = request.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > MAX_REQUEST_BODY) {\n await reader.cancel().catch(() => {});\n return TOO_LARGE;\n }\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n const out = new Uint8Array(new ArrayBuffer(size));\n let at = 0;\n for (const chunk of chunks) {\n out.set(chunk, at);\n at += chunk.byteLength;\n }\n return out;\n}\n\n/** The fields of a JSON or form body, {} for anything else; TOO_LARGE past the cap. */\nasync function readBody(request: Request): Promise<Record<string, string> | typeof TOO_LARGE | typeof BAD_BODY> {\n const type = request.headers.get(\"content-type\") ?? \"\";\n const json = type.includes(\"application/json\");\n const form = type.includes(\"application/x-www-form-urlencoded\") || type.includes(\"multipart/form-data\");\n if (!json && !form) return {};\n let bytes: Uint8Array<ArrayBuffer> | typeof TOO_LARGE;\n try {\n bytes = await readLimited(request);\n } catch {\n return {};\n }\n if (bytes === TOO_LARGE) return TOO_LARGE;\n // Parsed as the request itself would parse it, from the bytes read.\n const copy = new Request(request.url, { method: \"POST\", headers: { \"content-type\": type }, body: bytes });\n try {\n if (json) {\n const data = await copy.json();\n return typeof data === \"object\" && data !== null && !Array.isArray(data) ? Object.fromEntries(Object.entries(data).map(([k, v]) => [k, String(v)])) : BAD_BODY;\n }\n const fields = await copy.formData();\n const out: Record<string, string> = {};\n for (const [k, v] of fields.entries()) out[k] = String(v);\n return out;\n } catch {\n return BAD_BODY;\n }\n}\n\n/**\n * A browser attaches Origin or Sec-Fetch-Site to a cross-site form post, and\n * a page cannot forge either. Non-browser clients send neither.\n */\nfunction crossSite(request: Request, publicOrigin: string): boolean {\n const origin = request.headers.get(\"origin\");\n if (origin !== null && origin !== publicOrigin) return true;\n const site = request.headers.get(\"sec-fetch-site\");\n return site !== null && site !== \"same-origin\" && site !== \"none\";\n}\n\n/** Absent means one hour; a number or numeric string is milliseconds. Throws on anything else. */\nfunction silenceDuration(value: string | null | undefined): Duration {\n if (value === undefined || value === null) return \"1h\";\n const text = value.trim();\n const duration: Duration = /^\\d+(\\.\\d+)?$/.test(text) ? Number(text) : text;\n parseDuration(duration, \"silence duration\");\n return duration;\n}\n\nfunction runsLimit(value: string | null): number {\n const n = value === null || value.trim() === \"\" ? NaN : Math.trunc(Number(value));\n return Number.isFinite(n) ? Math.min(MAX_RUNS, Math.max(1, n)) : DEFAULT_RUNS;\n}\n\n/**\n * The dashboard and its JSON API for a client.\n * @deprecated Use `cw.routes(options)`, the one way to mount the dashboard\n * in every port. This name still works through 1.x and goes in 2.0.\n */\nexport function createRoutes(cw: Cronwatch, options: RoutesOptions = {}): Routes {\n return cw.routes(options);\n}\n\n/**\n * A fetch-style handler serving the dashboard and a small JSON API, which\n * cw.routes() returns. Mount it in a Next.js app at\n * app/cronwatch/[[...path]]/route.ts:\n *\n * export const { GET, POST, DELETE } = cw.routes();\n */\nexport function buildRoutes(cw: Cronwatch, options: RoutesOptions = {}): Routes {\n const optedOut = options.token === null;\n // A blank token, given or read, counts as unset; one given that is not a string throws.\n const given = secretOption(options.token, \"routes: token\");\n const configured = optedOut ? null : (given || readSecretEnv(\"CRONWATCH_TOKEN\") || null);\n const base = (options.basePath ?? \"/cronwatch\").replace(/\\/+$/, \"\");\n const developing = isDevelopment();\n const fixedOrigin = configuredOrigin(options.origin);\n const trustProxy = options.trustProxy === true;\n const originOf = (request: Request, url: URL): string =>\n fixedOrigin ?? (trustProxy ? forwardedOrigin(request, url) : url.origin);\n // A fetch handler cannot tell a local caller from a remote one (proxies,\n // tunnels, and `next dev` listening on every interface all look alike), so\n // development gets a token too: made here, and shown only in the server log.\n const generated = !configured && !optedOut && developing;\n const token = generated ? developmentToken() : configured;\n let announced = false;\n // Worked out on the first request that needs it, then kept.\n let cookie: Promise<string> | null = null;\n const expectedCookie = (value: string) => (cookie ??= cookieValue(value));\n\n const serve = async (request: Request, url: URL, path: string, wantsHtml: boolean): Promise<Response> => {\n const method = request.method.toUpperCase();\n const publicOrigin = originOf(request, url);\n\n if (generated && !announced) {\n announced = true;\n const shown = fixedOrigin ?? (isLoopbackOrigin(publicOrigin) ? publicOrigin : null);\n console.info(developmentSignInLine(shown, base, token!));\n }\n\n // The app shell: the manifest, icons, service worker, app.js, and the\n // offline page. Served to anyone, since a browser fetches some of it\n // without cookies and none of it says anything about the jobs.\n if (method === \"GET\" || method === \"HEAD\") {\n if (path === \"/offline\") {\n return html(messagePage(\"You are offline\", \"CronWatch shows live data from your app, so it needs a connection.\", base), 200, \"no-cache\");\n }\n const asset = staticAsset(path, base);\n if (asset) return shell(asset, base);\n }\n\n // No token outside development: fail closed.\n if (!token && !optedOut) {\n return wantsHtml\n ? html(messagePage(\"CronWatch routes are locked\", \"Set CRONWATCH_TOKEN (or pass token to cw.routes()), or pass token: null to serve them open behind your own auth.\", base), 503)\n : api({ ok: false, error: \"CRONWATCH_TOKEN is not set\" }, 503);\n }\n\n if (method !== \"GET\" && method !== \"HEAD\" && crossSite(request, publicOrigin)) {\n return wantsHtml\n ? html(messagePage(\"Cross-site request refused\", \"Changes can only be made from the dashboard itself.\", base), 403)\n : api({ ok: false, error: \"Cross-site request refused\" }, 403);\n }\n\n const bearer = bearerToken(request.headers.get(\"authorization\"));\n const signInCookie = async () => {\n const secure = publicOrigin.startsWith(\"https:\") ? \"; Secure\" : \"\";\n return `${COOKIE}=${await expectedCookie(token!)}; Path=${base || \"/\"}; HttpOnly; SameSite=Lax; Max-Age=${60 * 60 * 24 * 30}${secure}`;\n };\n const signInPage = () => generated\n ? html(messagePage(\"Sign in\", \"CRONWATCH_TOKEN is not set, so this development server made a token. The sign-in link is in the server log: open it once, or enter the token from it below, and this browser stays signed in.\", base, true), 401)\n : html(messagePage(\"Sign in\", \"Enter your CRONWATCH_TOKEN and this browser stays signed in.\", base, true), 401);\n\n // The sign-in form posts the token here, in the body, so it stays out of\n // the URL and every access log. Cross-site posts were refused above.\n if (token && method === \"POST\" && path === \"/signin\") {\n const body = await readBody(request);\n if (body === BAD_BODY) return html(messagePage(\"Bad request\", \"Malformed request body\", base), 400);\n const sent = body === TOO_LARGE ? undefined : body.token;\n if (sent === undefined || !constantTimeEqual(sent, token)) return signInPage();\n return redirect(signInReturn(request.headers.get(\"referer\"), publicOrigin, base), { \"set-cookie\": await signInCookie() });\n }\n\n if (token) {\n // ?token= is only the sign-in that moves the token into a cookie.\n const query = wantsHtml && method === \"GET\" ? url.searchParams.get(\"token\") : null;\n const sent = readCookie(request, COOKIE);\n const isCheck = path === \"/api/check\";\n const cronSecretOk = isCheck && bearer !== null && cw.cronSecret !== null && constantTimeEqual(bearer, cw.cronSecret);\n const tokenOk =\n bearer !== null ? constantTimeEqual(bearer, token)\n : query !== null ? constantTimeEqual(query, token)\n : sent !== null && constantTimeEqual(sent, await expectedCookie(token));\n if (!cronSecretOk && !tokenOk) {\n if (wantsHtml) return signInPage();\n return generated\n ? api({ ok: false, error: \"Unauthorized: CRONWATCH_TOKEN is not set, so this development server made a token; it is in the server log\" }, 401)\n : api({ ok: false, error: \"Unauthorized\" }, 401);\n }\n if (query !== null) {\n // Move the token from the URL into a cookie, so it is not left in the\n // browser's history. The request line that carried it may still be in\n // an access log, which is why the sign-in form posts instead.\n url.searchParams.delete(\"token\");\n // One leading slash: \"//host/...\" would be a protocol-relative Location, off this site.\n return redirect(url.pathname.replace(/^\\/+/, \"/\") + (url.search || \"\"), { \"set-cookie\": await signInCookie() });\n }\n }\n\n const redirectBack = () => {\n const referer = request.headers.get(\"referer\") ?? \"\";\n return redirect(referer.startsWith(publicOrigin + \"/\") ? referer : `${base}/`);\n };\n const decoded = path.split(\"/\").filter(Boolean).map(safeDecode);\n if (decoded.some((part) => part === null)) {\n return wantsHtml ? html(messagePage(\"Bad request\", \"The path is not valid.\", base), 400) : api({ ok: false, error: \"Bad path\" }, 400);\n }\n const parts = decoded as string[];\n\n // HTML\n if (method === \"GET\" && path === \"/\") {\n const entries = await cw.jobsWithRuns(BOARD_PAGE_RUNS);\n const now = cw.now();\n const runsByJob = new Map<string, Run[]>(entries.map((entry) => [entry.job.name, entry.runs]));\n return html(dashboardPage(entries.map((entry) => entry.job), runsByJob, now, base, null, await boardLanes(cw, entries, now)));\n }\n if (method === \"GET\" && parts[0] === \"jobs\" && parts.length === 2) {\n const job = await cw.jobSummary(parts[1]!);\n if (!job) return html(messagePage(\"No such job\", `${parts[1]} is not in the store.`, base), 404);\n const now = cw.now();\n // Enough runs to draw the job's week; the page lists the newest fifty.\n const limit = weekRunsLimit(job, now);\n const runs = await cw.runs(job.name, limit);\n return html(jobPage(job, runs, now, base, runs.length < limit));\n }\n if (method === \"POST\" && path === \"/check\") {\n await cw.check();\n return redirectBack();\n }\n if (method === \"POST\" && parts[0] === \"jobs\" && parts.length === 3) {\n const name = parts[1]!;\n if (parts[2] === \"forget\") {\n await cw.forget(name);\n return redirect(`${base}/`);\n }\n if (parts[2] !== \"silence\" && parts[2] !== \"unsilence\") return html(messagePage(\"Not found\", path, base), 404);\n if (!(await cw.jobSummary(name))) return html(messagePage(\"No such job\", `${name} is not in the store.`, base), 404);\n if (parts[2] === \"silence\") {\n const body = await readBody(request);\n if (body === TOO_LARGE) return html(messagePage(\"Not silenced\", \"The request was too large.\", base), 413);\n if (body === BAD_BODY) return html(messagePage(\"Not silenced\", \"Malformed request body\", base), 400);\n let duration: Duration;\n try {\n duration = silenceDuration(body.for);\n } catch (e) {\n return html(messagePage(\"Not silenced\", (e as Error).message, base), 400);\n }\n await cw.silence(name, duration);\n } else await cw.unsilence(name);\n return redirectBack();\n }\n\n // JSON API\n if (parts[0] === \"api\") {\n const rest = parts.slice(1);\n // What is serving the API, so a client such as @cronwatch/mcp can tell.\n if (method === \"GET\" && rest.length === 0) {\n return api({ ok: true, library: LIBRARY, language: LANGUAGE, version: VERSION, api: API_VERSION });\n }\n if (method === \"GET\" && rest[0] === \"jobs\" && rest.length === 1) {\n return api({ ok: true, jobs: await cw.jobs() });\n }\n if (rest[0] === \"jobs\" && rest.length === 2) {\n const name = rest[1]!;\n if (method === \"GET\") {\n const job = await cw.jobSummary(name);\n if (!job) return api({ ok: false, error: \"No such job\" }, 404);\n return api({ ok: true, job, runs: await cw.runs(name, runsLimit(url.searchParams.get(\"runs\"))) });\n }\n if (method === \"DELETE\") {\n if (!(await cw.jobSummary(name))) return api({ ok: false, error: \"No such job\" }, 404);\n await cw.forget(name);\n return api({ ok: true });\n }\n }\n if (method === \"POST\" && rest[0] === \"jobs\" && rest.length === 3) {\n const name = rest[1]!;\n if (!(await cw.jobSummary(name))) return api({ ok: false, error: \"No such job\" }, 404);\n if (rest[2] === \"silence\") {\n const body = await readBody(request);\n if (body === TOO_LARGE) return api({ ok: false, error: \"Request body too large\" }, 413);\n if (body === BAD_BODY) return api({ ok: false, error: \"Malformed request body\" }, 400);\n let duration: Duration;\n try {\n duration = silenceDuration(body.for ?? url.searchParams.get(\"for\"));\n } catch (e) {\n return api({ ok: false, error: (e as Error).message }, 400);\n }\n await cw.silence(name, duration);\n return api({ ok: true, job: await cw.jobSummary(name) });\n }\n if (rest[2] === \"unsilence\") {\n await cw.unsilence(name);\n return api({ ok: true, job: await cw.jobSummary(name) });\n }\n }\n if (rest[0] === \"check\" && rest.length === 1) {\n // A page cannot send an Authorization header cross-site, so a GET\n // may only run the check when it carries a bearer (token or cron secret).\n if (method === \"GET\" && bearer === null) {\n return api({ ok: false, error: \"Use POST, or GET with an Authorization bearer\" }, 405, { allow: \"POST\" });\n }\n if (method === \"GET\" || method === \"POST\") {\n const result = await cw.check();\n return api({ ok: true, ...result });\n }\n }\n if (method === \"GET\" && rest[0] === \"runs\" && rest.length === 2) {\n const run = await cw.getRun(rest[1]!);\n return run ? api({ ok: true, run }) : api({ ok: false, error: \"No such run\" }, 404);\n }\n return api({ ok: false, error: \"Not found\" }, 404);\n }\n\n return html(messagePage(\"Not found\", path, base), 404);\n };\n\n const handler: FetchHandler = async (request) => {\n let wantsHtml = true;\n try {\n const url = new URL(request.url);\n const path = stripBase(url.pathname, base);\n // Not under the base at all: nothing here answers it, signed in or not.\n if (path === null) return html(messagePage(\"Not found\", url.pathname, base), 404);\n wantsHtml = !path.startsWith(\"/api\");\n return await serve(request, url, path, wantsHtml);\n } catch (e) {\n try {\n cw.onError(e, \"routes\");\n } catch {\n // An onError that throws must not turn a 500 into an unhandled rejection.\n }\n return wantsHtml\n ? html(messagePage(\"Something went wrong\", \"The request failed and the error was reported.\", base), 500)\n : api({ ok: false, error: \"Internal error\" }, 500);\n }\n };\n\n return { handler, GET: handler, POST: handler, DELETE: handler };\n}\n\nfunction api(body: unknown, status = 200, headers: Record<string, string> = {}): Response {\n return json(body, status, { ...SECURITY_HEADERS, ...headers });\n}\n\nfunction redirect(location: string, headers: Record<string, string> = {}): Response {\n return new Response(null, { status: 303, headers: { location, \"cache-control\": \"no-store\", ...SECURITY_HEADERS, ...headers } });\n}\n\n/**\n * An app shell file. The worker may be scoped to the base (it is served from\n * there anyway); the SVGs get a CSP of their own.\n */\nfunction shell(asset: StaticAsset, base: string): Response {\n const headers: Record<string, string> = { \"content-type\": asset.type, \"cache-control\": asset.cache, ...SECURITY_HEADERS };\n if (asset.type === \"image/svg+xml\") headers[\"content-security-policy\"] = ASSET_CSP;\n if (asset.worker) headers[\"service-worker-allowed\"] = `${base}/`;\n return new Response(asset.body, { status: 200, headers });\n}\n\nfunction html(body: string, status = 200, cache = \"no-store\"): Response {\n return new Response(body, {\n status,\n headers: {\n \"content-type\": \"text/html; charset=utf-8\",\n \"cache-control\": cache,\n \"content-security-policy\": CSP,\n \"x-frame-options\": \"DENY\",\n ...SECURITY_HEADERS,\n },\n });\n}\n","import { stateVersion } from \"../evaluate.js\";\nimport { stripJsonNul, stripNul } from \"../output.js\";\nimport type { JobState, Run, Store, StoredJob, StoredJobDefinition } from \"../types.js\";\n\n/**\n * Keeps everything in process memory. The default when no store is given,\n * good for tests and for trying the library out. State is gone on restart,\n * so a missed run cannot be noticed across one.\n */\nexport function memory(): Store & Required<Pick<Store, \"lastRun\">> {\n const jobs = new Map<string, StoredJob>();\n const runs = new Map<string, Run>();\n const order = new Map<string, number>();\n const states = new Map<string, JobState>();\n let seq = 0;\n\n const clone = <T>(v: T): T => JSON.parse(JSON.stringify(v));\n // Text is held as the SQL stores write it (see params in stores/sql.ts),\n // without U+0000, so every store reads back the same.\n const kept = <T>(v: T): T => JSON.parse(stripJsonNul(JSON.stringify(v)));\n const keptRun = (run: Run): Run => ({\n ...clone(run),\n trigger: stripNul(run.trigger),\n output: run.output === null ? null : stripNul(run.output),\n error: run.error === null ? null : stripNul(run.error),\n metrics: kept(run.metrics),\n });\n // Code unit order, as the SQL stores sort by bytes rather than by locale.\n const byName = (a: StoredJob, b: StoredJob) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0);\n\n return {\n async upsertJob(definition: StoredJobDefinition, now: number) {\n const existing = jobs.get(definition.name);\n jobs.set(definition.name, {\n name: definition.name,\n definition: kept(definition),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n });\n },\n async getJob(name) {\n const j = jobs.get(name);\n return j ? clone(j) : null;\n },\n async listJobs() {\n return [...jobs.values()].map(clone).sort(byName);\n },\n async deleteJob(name) {\n jobs.delete(name);\n states.delete(name);\n for (const [id, run] of runs) if (run.job === name) { runs.delete(id); order.delete(id); }\n },\n async insertRun(run) {\n // Like SQL's primary key: an id already recorded is refused, never overwritten.\n if (runs.has(run.id)) throw new Error(`run ${run.id} already exists`);\n runs.set(run.id, keptRun(run));\n order.set(run.id, ++seq);\n },\n async updateRun(run) {\n // Like SQL's UPDATE: a run that is gone (its job was forgotten) stays gone, and only these fields change.\n const existing = runs.get(run.id);\n if (!existing) return;\n const { status, finishedAt, durationMs, error, output, metrics } = keptRun(run);\n runs.set(run.id, { ...existing, status, finishedAt, durationMs, error, output, metrics });\n },\n async updateRunIf(run, fromStatuses) {\n const existing = runs.get(run.id);\n if (!existing || !fromStatuses.includes(existing.status)) return false;\n const { status, finishedAt, durationMs, error, output, metrics } = keptRun(run);\n runs.set(run.id, { ...existing, status, finishedAt, durationMs, error, output, metrics });\n return true;\n },\n async getRun(id) {\n const r = runs.get(id);\n return r ? clone(r) : null;\n },\n async listRuns(job, limit) {\n return [...runs.values()]\n .filter((r) => r.job === job)\n .sort((a, b) => b.startedAt - a.startedAt || order.get(b.id)! - order.get(a.id)!)\n .slice(0, limit)\n .map(clone);\n },\n async lastRun(job) {\n const list = await this.listRuns(job, 1);\n return list[0] ?? null;\n },\n async runningRuns() {\n return [...runs.values()]\n .filter((r) => r.status === \"running\")\n .sort((a, b) => a.startedAt - b.startedAt || order.get(a.id)! - order.get(b.id)!)\n .map(clone);\n },\n async getState(job) {\n const s = states.get(job);\n return s ? clone(s) : null;\n },\n async setState(state) {\n states.set(state.job, kept(state));\n },\n async compareAndSetState(state, expectedVersion) {\n if (stateVersion(states.get(state.job)) !== expectedVersion) return false;\n states.set(state.job, kept(state));\n return true;\n },\n async prune(before) {\n // Each job's newest run is kept whatever its age: without it, a job\n // that runs less often than the retention looks like it never ran.\n const newest = new Map<string, number>();\n for (const run of runs.values()) newest.set(run.job, Math.max(newest.get(run.job) ?? -Infinity, run.startedAt));\n let n = 0;\n for (const [id, run] of runs) {\n if (run.status !== \"running\" && run.startedAt < before && run.startedAt < newest.get(run.job)!) {\n runs.delete(id);\n order.delete(id);\n n++;\n }\n }\n return n;\n },\n };\n}\n","import { formatDuration, parseDuration } from \"./duration.js\";\nimport { isDevelopment, isProduction, readSecretEnv, secretOption } from \"./env.js\";\nimport {\n afterSend,\n applySilence,\n channelKeys,\n BASELINE_WINDOW,\n claimUndelivered,\n emptyState,\n hasFullBaseline,\n holdAlerts,\n holdRun,\n isStuck,\n MAX_UNDELIVERED,\n normalizeState,\n onCheck,\n onRunFinish,\n onRunStart,\n owedChannels,\n recordSent,\n releaseRun,\n releaseSending,\n runDuration,\n SEND_LEASE_MS,\n silenceEnd,\n stateVersion,\n summarize,\n timeoutMs,\n unevaluableSummary,\n withoutOwed,\n} from \"./evaluate.js\";\nimport type { Evaluation } from \"./evaluate.js\";\nimport { composeAlert } from \"./format.js\";\nimport { constantTimeEqual, json } from \"./http.js\";\nimport { createRecorder } from \"./job.js\";\nimport type { JobContext } from \"./job.js\";\nimport { capOutput, describeError, OUTPUT_CAP, redactAndCap, redactSecrets } from \"./output.js\";\nimport { parseSchedule } from \"./schedule.js\";\nimport { checkExpectation, readStoredJob, toStored } from \"./serialize.js\";\nimport { buildRoutes } from \"./routes/index.js\";\nimport type { Routes, RoutesOptions } from \"./routes/index.js\";\nimport { memory } from \"./stores/memory.js\";\nimport type {\n Alert,\n AlertChannel,\n HeldAlert,\n CheckResult,\n Condition,\n Duration,\n JobDefinition,\n JobOptions,\n JobState,\n JobSummary,\n Run,\n Store,\n StoredJob,\n StoredJobDefinition,\n TriageFn,\n} from \"./types.js\";\n\nexport type JobFn<T> = (job: JobContext) => Promise<T> | T;\nexport type HandlerFn<T> = (job: JobContext, request: Request) => Promise<T> | T;\n\nexport interface HandlerOptions {\n /**\n * Callers must send `Authorization: Bearer <secret>`. Defaults to the\n * client's cronSecret, which defaults to process.env.CRON_SECRET (what\n * Vercel sends its cron requests with). An empty string, or one of only\n * whitespace, counts as unset; any other type (false, a number) throws.\n * With no secret at all the handler answers 503 unless the app is in\n * development (the first of CRONWATCH_ENV, APP_ENV, and NODE_ENV that is\n * set names \"development\", \"dev\", or \"local\"; \"test\" and \"testing\" are not\n * development, so a test run or CI needs a secret too). Pass null to allow\n * anyone.\n */\n secret?: string | null;\n}\n\nexport interface JobHandle {\n readonly name: string;\n readonly definition: JobDefinition;\n /** Run the function now, recording the run. Rethrows whatever the function throws. */\n run<T>(fn: JobFn<T>, options?: { trigger?: string }): Promise<T>;\n /** A fetch-style request handler (Next.js route, Hono, Bun, Deno) that runs the function and records the run. */\n handler<T>(fn: HandlerFn<T>, options?: HandlerOptions): (request: Request) => Promise<Response>;\n /**\n * Record a running run now and finish it later, perhaps from another\n * process (see resume()). Store failures go to onError; it never throws for\n * them. A run that is never finished is marked stuck by the first check\n * after the job's timeout.\n */\n start(options?: StartOptions): Promise<RunHandle>;\n /** A handle on a run this job started elsewhere, by its id, so this process can log to it and finish it. */\n resume(runId: string): Promise<RunHandle>;\n}\n\nexport interface StartOptions {\n /** What started the run, as with run(). Default \"start\". */\n trigger?: string;\n /**\n * Your own stable id for the run, such as an Inngest run id, 1 to 200\n * characters, not starting with \"pgcron:\" (the pg_cron source's). A start\n * with an id already recorded for this job records nothing and returns a\n * handle on that run instead; an id recorded for another job throws,\n * whether that job's start is still in flight or long done.\n */\n id?: string;\n}\n\n/**\n * How a started run ended. `{ error }` is a failure, recorded like an error\n * run() caught. Otherwise the run succeeded, and `result` (or a string\n * passed on its own) is treated like the value run()'s function returns:\n * a string is the output when nothing was logged, `expect` is checked, and\n * a Response with status 400 or above is a failure.\n */\nexport type RunOutcome = { status?: \"ok\"; result?: unknown } | { error: unknown };\n\n/** A run recorded by job.start() or found by job.resume(), to finish later. */\nexport interface RunHandle {\n readonly id: string;\n readonly job: string;\n /** When the run started; null when a resumed run could not be read. */\n readonly startedAt: number | null;\n /** False once finished, and from the start for a resumed run that already finished or does not exist. */\n readonly active: boolean;\n /** Add a line of output. Kept in the handle until flush() or finish(). */\n log(...parts: unknown[]): void;\n /** Report a number for this run. A later value for the same name replaces an earlier one. */\n metric(name: string, value: number): void;\n metrics(values: Record<string, number>): void;\n /**\n * Append the lines and metrics added so far to the stored run, which must\n * still be running and belong to this job. A read, change, and write of the\n * run's row, written only while it is still running: two processes\n * appending to one run at the same moment can lose one's lines, but a flush\n * never undoes a finish. The first 16 KB of everything flushed stay in the\n * handle, so an expect rule at finish() sees an early line as run() would.\n */\n flush(): Promise<void>;\n /**\n * Finish the run, judge it like any other, and send what that produces.\n * Resolves to the run as recorded, or null when nothing was recorded: the\n * run was already finished (here or elsewhere), was not found, or belongs\n * to another job, which is reported to onError. When several processes\n * finish one run, only the one whose write lands judges it. Never throws\n * for the store: a store that fails is reported, nothing is recorded, and\n * the handle stays active so finish() can be called again.\n */\n finish(outcome?: RunOutcome | string): Promise<Run | null>;\n /** finish({ error }). */\n fail(error: unknown): Promise<Run | null>;\n}\n\n/**\n * What a Source may use of the client: declare jobs, read the store, and\n * record runs it found elsewhere. A Cronwatch is one.\n */\nexport interface SourceHost {\n /** Declare a job, as Cronwatch.job(). Throws for an invalid name or option. */\n job(name: string, options?: JobOptions): unknown;\n /**\n * The definitions declared now, as Cronwatch.definedJobs(): a source reads\n * it to declare again a job forgotten since (the dashboard's forget), whose\n * definition has not changed. A host without it is taken to keep every\n * job the source declared.\n */\n definedJobs?(): { name: string }[];\n /** See Cronwatch.recordRun(). */\n recordRun(run: Run, options?: RecordRunOptions): Promise<Alert[]>;\n readonly store: Store;\n readonly now: () => number;\n readonly onError: (error: unknown, where: string) => void;\n}\n\n/**\n * Runs that happen somewhere CronWatch cannot wrap, such as inside the\n * database (see @cronwatch/sdk/pg-cron). check() calls sync() on each source\n * first, so what it records is evaluated in the same check.\n */\nexport interface Source {\n name: string;\n /** Declare the jobs and record their new runs. Returns the alerts recording them sent. */\n sync(host: SourceHost): Promise<Alert[] | void>;\n}\n\nexport interface RecordRunOptions {\n /** False stores the run without evaluating it, for history imported on first sight. Default true. */\n evaluate?: boolean;\n}\n\nexport interface CronwatchOptions {\n /** Where jobs, runs, and state live. Defaults to an in-memory store that forgets on restart. */\n store?: Store;\n /**\n * Where runs this process does not wrap come from, such as pg_cron jobs.\n * Each is synced at the start of every check(); one that throws is\n * reported to onError and the check carries on.\n */\n sources?: Source[];\n /** Where alerts go. Defaults to the console. */\n alerts?: AlertChannel[];\n /** Adds a short diagnosis to every alert except recoveries. See @cronwatch/sdk/anthropic. */\n triage?: TriageFn;\n /**\n * Shared secret that handler() requests must carry. Defaults to\n * process.env.CRON_SECRET (on Cloudflare Workers, which have no process,\n * pass env.CRON_SECRET); an empty string or one of only whitespace, given\n * here or in the variable, counts as unset. Pass null to let handlers run\n * without one. Any other type (false, a number) throws.\n */\n cronSecret?: string | null;\n /** How long finished runs are kept. Default \"30d\". */\n retention?: Duration;\n /** Applied to every job unless the job sets its own. */\n defaults?: Pick<JobOptions, \"grace\" | \"timeout\" | \"timezone\" | \"failuresBeforeAlert\">;\n /**\n * Applied to every run's output and error before it is stored, shown, or\n * sent to an alert channel or triage. The default blanks values that look\n * like secrets (password=..., Authorization headers, URL credentials, bearer\n * tokens, JWTs, PEM private keys, webhook URLs, AWS, GitHub, Slack, Stripe,\n * Google, and API key formats). Pass your own function, or false to keep\n * output exactly as logged. A function that throws or returns something\n * other than a string is reported to onError and the default is used.\n */\n redact?: ((text: string) => string) | false;\n /**\n * \"now\" (the default) sends alerts from this process. \"check\" sends nothing\n * from here: each alert is queued in the store and the next check, in a\n * process that delivers now, sends it (with triage). For a process that\n * records runs but cannot reach the network, such as a sandboxed backup job.\n * Its `alerts` and `triage` are not used.\n */\n deliver?: \"now\" | \"check\";\n /** Called with anything that goes wrong outside a job: the store failing, an alert channel failing, a triage timeout. */\n onError?: (error: unknown, where: string) => void;\n /** The clock. Tests use this. */\n now?: () => number;\n}\n\ninterface ExecuteResult<T> {\n run: Run;\n result: T | undefined;\n error: unknown;\n threw: boolean;\n}\n\nconst NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,119}$/;\nconst TRIAGE_TIMEOUT_MS = 25_000;\n/** How long one channel may take to send one alert. */\nconst CHANNEL_TIMEOUT_MS = 15_000;\nconst PRUNE_INTERVAL_MS = 60 * 60_000;\n/**\n * Wall-clock time one check spends retrying undelivered alerts, across every\n * job. Once it is spent the rest wait for the next check.\n */\nconst RETRY_BUDGET_MS = 20_000;\n/** Reads and writes of one job's state before an update gives up on a store that keeps changing under it. */\nconst STATE_ATTEMPTS = 10;\n/** Runs read for a baseline, and the most read when failures crowd out the successes. */\nconst HISTORY_PAGE = BASELINE_WINDOW + 5;\nconst HISTORY_MAX = 200;\n\n/** Throws a clear error for options that would otherwise quietly turn a check off. */\nfunction validateDefinition(def: JobDefinition): void {\n const name = def.name;\n if (def.schedule !== undefined) {\n if (typeof def.schedule !== \"string\" || def.schedule.trim() === \"\") throw new Error(`job \"${name}\": schedule must be a non-empty string`);\n parseSchedule(def.schedule, def.timezone);\n }\n if (def.timezone !== undefined) {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: def.timezone });\n } catch {\n throw new Error(`job \"${name}\": timezone \"${def.timezone}\" is not an IANA timezone`);\n }\n }\n if (def.grace !== undefined) parseDuration(def.grace, \"grace\");\n if (def.timeout !== undefined && parseDuration(def.timeout, \"timeout\") <= 0) throw new Error(`job \"${name}\": timeout must be longer than zero`);\n if (def.maxDuration !== undefined && parseDuration(def.maxDuration, \"maxDuration\") <= 0) {\n throw new Error(`job \"${name}\": maxDuration must be longer than zero`);\n }\n if (def.failuresBeforeAlert !== undefined && !(Number.isInteger(def.failuresBeforeAlert) && def.failuresBeforeAlert >= 1)) {\n throw new Error(`job \"${name}\": failuresBeforeAlert must be a whole number, 1 or more (got ${String(def.failuresBeforeAlert)})`);\n }\n if (def.budget !== undefined) {\n if (typeof def.budget !== \"object\" || def.budget === null) throw new Error(`job \"${name}\": budget must be an object of { metric: ceiling }`);\n for (const [metric, ceiling] of Object.entries(def.budget)) {\n if (typeof ceiling !== \"number\" || !Number.isFinite(ceiling) || ceiling < 0) {\n throw new Error(`job \"${name}\": budget.${metric} must be a finite number, 0 or more (got ${String(ceiling)})`);\n }\n }\n }\n if (def.floor !== undefined) {\n if (typeof def.floor !== \"object\" || def.floor === null) throw new Error(`job \"${name}\": floor must be an object of { metric: floor }`);\n for (const [metric, floor] of Object.entries(def.floor)) {\n if (typeof floor !== \"number\" || !Number.isFinite(floor)) {\n throw new Error(`job \"${name}\": floor.${metric} must be a finite number (got ${String(floor)})`);\n }\n const ceiling = def.budget?.[metric];\n if (ceiling !== undefined && floor > ceiling) {\n throw new Error(`job \"${name}\": floor.${metric} (${floor}) is above budget.${metric} (${ceiling}), so every run would alert`);\n }\n }\n }\n if (def.expect !== undefined && typeof def.expect !== \"string\" && !(def.expect instanceof RegExp) && typeof def.expect !== \"function\") {\n throw new Error(`job \"${name}\": expect must be a string, a RegExp, or a function`);\n }\n}\n\n/** Alerts written with the state that opened their conditions, and how many older ones the queue let go. */\ninterface Held {\n alerts: Alert[];\n dropped: number;\n}\n\nfunction sameState(a: JobState, b: JobState): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\nexport class Cronwatch {\n readonly store: Store;\n readonly alerts: AlertChannel[];\n readonly triage: TriageFn | undefined;\n readonly sources: Source[];\n /** The secret handler() requests must carry, or null when none is set. */\n readonly cronSecret: string | null;\n readonly retentionMs: number;\n readonly now: () => number;\n readonly onError: (error: unknown, where: string) => void;\n /** cronSecret was passed as null: handlers may run without a secret. */\n private readonly secretOptOut: boolean;\n private readonly redact: (text: string) => string;\n /** \"check\": queue alerts for another process's check instead of sending them. See CronwatchOptions.deliver. */\n private readonly deferDelivery: boolean;\n private readonly defaults: NonNullable<CronwatchOptions[\"defaults\"]>;\n private readonly definitions = new Map<string, JobDefinition>();\n /**\n * Declarations forgotten here (forget()), kept so that run() or resumeRun()\n * by name declares the job again as it was written, not bare.\n */\n private readonly forgotten = new Map<string, JobDefinition>();\n private readonly synced = new Set<string>();\n /** The tail of each job's queue of state updates. See serial(). */\n private readonly queues = new Map<string, Promise<void>>();\n /** The tail of each job's queue of declaration writes. See sync(). */\n private readonly syncing = new Map<string, Promise<void>>();\n /** start() calls with an id still in flight, so two at once in this process record one run. */\n private readonly starting = new Map<string, Promise<RunHandle>>();\n private ready: Promise<void> | null = null;\n private checking: Promise<CheckResult> | null = null;\n private lastPruneAt = 0;\n private timer: ReturnType<typeof setInterval> | null = null;\n private firstTick: ReturnType<typeof setTimeout> | null = null;\n private usingDefaultStore = false;\n private warnedNoSecret = false;\n private warnedDeferredStart = false;\n /** Stored jobs read with a definition that was not a JSON object (see readJob). */\n private readonly unreadable = new WeakSet<StoredJob>();\n\n constructor(options: CronwatchOptions = {}) {\n this.store = options.store ?? (this.usingDefaultStore = true, memory());\n this.alerts = options.alerts ?? [consoleChannel()];\n this.triage = options.triage;\n this.sources = options.sources ?? [];\n // A blank secret, given or read, counts as unset; one given that is not a string throws.\n const given = secretOption(options.cronSecret, \"cronSecret\");\n const secret = options.cronSecret === undefined ? readSecretEnv(\"CRON_SECRET\") : given;\n this.cronSecret = secret ? secret : null;\n this.secretOptOut = options.cronSecret === null;\n this.retentionMs = parseDuration(options.retention ?? \"30d\", \"retention\");\n this.defaults = options.defaults ?? {};\n this.now = options.now ?? (() => Date.now());\n const redact = options.redact;\n this.redact = redact === false ? (text) => text\n : typeof redact === \"function\" ? (text) => {\n try {\n const out: unknown = redact(text);\n if (typeof out !== \"string\") throw new TypeError(`redact must return a string, not ${out === null ? \"null\" : typeof out}`);\n return out;\n } catch (e) {\n // A broken redact must not stop the run finishing, nor leak what it was given.\n this.report(e, \"redact\");\n return redactSecrets(text);\n }\n }\n : redactSecrets;\n if (options.deliver !== undefined && options.deliver !== \"now\" && options.deliver !== \"check\") {\n throw new Error(`deliver must be \"now\" or \"check\", not ${JSON.stringify(options.deliver)}`);\n }\n this.deferDelivery = options.deliver === \"check\";\n this.onError = options.onError ?? ((error, where) => console.error(`[cronwatch] ${where}:`, error));\n }\n\n /** Declare a job. Call it once, at module level, and keep the handle. */\n job(name: string, options: JobOptions = {}): JobHandle {\n if (!NAME_RE.test(name)) {\n throw new Error(`job name \"${name}\" must be 1 to 120 characters of letters, digits, \".\", \"_\", \":\", or \"-\"`);\n }\n const definition: JobDefinition = { ...this.defaults, ...options, name };\n validateDefinition(definition);\n this.definitions.set(name, definition);\n this.forgotten.delete(name);\n this.synced.delete(name);\n return this.handle(definition);\n }\n\n /** The declaration of `name`: the standing one, else one forgotten here, declared again as it was. */\n private declared(name: string): JobDefinition | undefined {\n const standing = this.definitions.get(name);\n if (standing) return standing;\n const forgotten = this.forgotten.get(name);\n if (!forgotten) return undefined;\n this.forgotten.delete(name);\n this.definitions.set(name, forgotten);\n this.synced.delete(name);\n return forgotten;\n }\n\n /** Run a job by name without keeping a handle. Defines it on first use. */\n run<T>(name: string, fn: JobFn<T>): Promise<T>;\n run<T>(name: string, options: JobOptions, fn: JobFn<T>): Promise<T>;\n run<T>(name: string, optionsOrFn: JobOptions | JobFn<T>, maybeFn?: JobFn<T>): Promise<T> {\n const fn = typeof optionsOrFn === \"function\" ? optionsOrFn : maybeFn!;\n const options = typeof optionsOrFn === \"function\" ? undefined : optionsOrFn;\n const declared = options ? undefined : this.declared(name);\n const handle = declared ? this.handle(declared) : this.job(name, options);\n return handle.run(fn);\n }\n\n /** The definitions declared in this process. */\n definedJobs(): JobDefinition[] {\n return [...this.definitions.values()];\n }\n\n /** A handle on a run started elsewhere, as job(name).resume(runId). The job must be declared in this process. */\n resumeRun(name: string, runId: string): Promise<RunHandle> {\n const definition = this.declared(name);\n if (!definition) return Promise.reject(new Error(`resumeRun: job \"${name}\" is not declared; call job() first`));\n return this.resumeHandle(definition, runId);\n }\n\n private handle(definition: JobDefinition): JobHandle {\n const self = this;\n return {\n name: definition.name,\n definition,\n async run<T>(fn: JobFn<T>, options?: { trigger?: string }): Promise<T> {\n const outcome = await self.execute(definition, fn, options?.trigger ?? \"run\");\n if (outcome.threw) throw outcome.error;\n return outcome.result as T;\n },\n handler<T>(fn: HandlerFn<T>, options?: HandlerOptions) {\n // A blank secret falls back to the client's; one that is not a string throws.\n const own = secretOption(options?.secret, \"handler: secret\");\n const secret = own === null ? null : own ? own : self.cronSecret;\n const optedOut = own === null || (!own && self.secretOptOut);\n return async (request: Request): Promise<Response> => {\n if (!secret && !optedOut && !isDevelopment()) {\n self.warnNoSecret();\n return json({ ok: false, error: \"CRON_SECRET is not set, so this job will not run for an unauthenticated request. Set it, or pass secret: null to handler() to allow anyone.\" }, 503);\n }\n if (secret) {\n const header = request.headers.get(\"authorization\") ?? \"\";\n if (!constantTimeEqual(header, `Bearer ${secret}`)) {\n return json({ ok: false, error: \"Unauthorized\" }, 401);\n }\n }\n const outcome = await self.execute(definition, (job) => fn(job, request), \"handler\");\n if (outcome.result instanceof Response) return outcome.result;\n const body = {\n ok: outcome.run.status === \"ok\",\n job: definition.name,\n run: outcome.run.id,\n status: outcome.run.status,\n durationMs: outcome.run.durationMs,\n // Error text only goes to a caller who proved they hold the secret.\n ...(secret && outcome.run.error ? { error: outcome.run.error.split(\"\\n\")[0] } : {}),\n };\n return json(body, outcome.run.status === \"ok\" ? 200 : 500);\n };\n },\n start(options?: StartOptions): Promise<RunHandle> {\n return self.startRun(definition, options ?? {});\n },\n resume(runId: string): Promise<RunHandle> {\n return self.resumeHandle(definition, runId);\n },\n };\n }\n\n private warnNoSecret(): void {\n if (this.warnedNoSecret) return;\n this.warnedNoSecret = true;\n this.report(new Error(\"handler() refused a request because no CRON_SECRET is set; pass secret: null to allow unauthenticated requests\"), \"handler\");\n }\n\n /** onError, for places that must carry on even when onError itself throws. */\n private report(error: unknown, where: string): void {\n try {\n this.onError(error, where);\n } catch {\n // Nothing more can be done with it.\n }\n }\n\n private async ensureReady(): Promise<void> {\n if (!this.ready) {\n this.ready = (async () => {\n if (this.store.init) await this.store.init();\n const missing = ([\"compareAndSetState\", \"updateRunIf\"] as const).filter((method) => typeof this.store[method] !== \"function\");\n if (missing.length > 0) {\n // Once per client: it still works, but only as long as one process at a time uses the store.\n this.report(\n new Error(`the store has no ${missing.join(\" or \")}, so two processes sharing it can overwrite each other's state or both evaluate the same run; it is safe only while one process at a time uses it`),\n \"store\",\n );\n }\n if (this.usingDefaultStore && isProduction()) {\n console.warn(\"[cronwatch] using the in-memory store: runs and state are lost on restart. Pass a store from @cronwatch/sdk/sqlite or @cronwatch/sdk/postgres.\");\n }\n })().catch((error: unknown) => {\n // Let the next call try again rather than failing forever.\n this.ready = null;\n throw error;\n });\n }\n await this.ready;\n }\n\n /**\n * Writes the declaration of `definition`'s name as it stands, unless the\n * store has it. A handle kept from an earlier declaration writes the one\n * that replaced it, never its own over it, and one forgotten since writes\n * its own. The writes of one name take turns, in the order they were asked\n * for, so one still under way cannot land after a later one; and a name\n * declared again while its write was under way is still to be written. A\n * name is marked as written only while that same declaration stands, so a\n * forget that lands during the write (deleting the row after it) leaves\n * the name to be written again, as does one forgotten before it.\n *\n * With `confirm`, as a run starts, a name already written is read back:\n * another process may have forgotten the job since, and a job still\n * declared here comes back on its next run.\n */\n private async sync(definition: JobDefinition, confirm = false): Promise<void> {\n await this.ensureReady();\n const name = definition.name;\n if (this.synced.has(name)) {\n if (!confirm || (await this.store.getJob(name))) return;\n this.synced.delete(name);\n }\n await this.serial(name, async () => {\n if (this.synced.has(name)) return;\n const standing = this.definitions.get(name) ?? definition;\n await this.store.upsertJob(toStored(standing), this.now());\n if (this.definitions.get(name) === standing) this.synced.add(name);\n }, this.syncing);\n }\n\n /**\n * Every stored job, once each declaration has been written. A job declared\n * here that the store no longer has was forgotten by another process after\n * this one wrote it: it is written again, as its next run would, so it is\n * checked and shown while any process still declares it.\n */\n private async storedJobs(): Promise<StoredJob[]> {\n for (const definition of this.definitions.values()) await this.sync(definition);\n const jobs = await this.store.listJobs();\n const listed = new Set(jobs.map((job) => job.name));\n const missing = [...this.definitions.values()].filter((definition) => !listed.has(definition.name));\n if (missing.length === 0) return jobs.map((job) => this.readJob(job));\n for (const definition of missing) {\n // Not one forgotten here meanwhile.\n if (this.definitions.get(definition.name) !== definition) continue;\n this.synced.delete(definition.name);\n await this.sync(definition);\n }\n return (await this.store.listJobs()).map((job) => this.readJob(job));\n }\n\n /** A stored job read leniently (readStoredJob); one whose definition is unreadable is remembered, so that evaluating it throws. */\n private readJob(stored: StoredJob): StoredJob {\n const { job, readable } = readStoredJob(stored);\n if (!readable) this.unreadable.add(job);\n return job;\n }\n\n /** Throws for a job whose stored definition was not a JSON object: reported, and shown as failing, while the others carry on. */\n private evaluable(stored: StoredJob): void {\n if (this.unreadable.has(stored)) throw new Error(`job \"${stored.name}\": its stored definition is not a JSON object`);\n }\n\n /**\n * Runs `fn` after every earlier state update for the same job has settled,\n * so two runs (or a run and a check) in this process never read and write\n * the job's state over each other. Other processes are coordinated by\n * updateState() instead. sync() queues a job's declaration writes the same\n * way, in `syncing`.\n */\n private serial<T>(job: string, fn: () => Promise<T>, queues = this.queues): Promise<T> {\n const result = (queues.get(job) ?? Promise.resolve()).then(fn);\n const tail = result.then(() => {}, () => {});\n queues.set(job, tail);\n void tail.then(() => {\n if (queues.get(job) === tail) queues.delete(job);\n });\n return result;\n }\n\n private async readState(job: string): Promise<JobState> {\n return normalizeState(await this.store.getState(job), job);\n }\n\n /**\n * Every read-modify-write of a job's state goes through here. In turn with\n * this process's other updates to the job (serial()), it reads the state,\n * asks `change` for the next one, and writes it with the version one\n * higher, only if the stored version is still the one read. When another\n * process wrote in between, the write is refused and it starts again from\n * a fresh read, up to STATE_ATTEMPTS times. So `change` may run more than\n * once and must only compute: whatever it returns from the attempt that\n * was written is the result. Nothing is written when the state is\n * unchanged. Returns the state as stored.\n */\n private updateState<T>(\n job: string,\n change: (current: JobState) => { state: JobState; result: T } | Promise<{ state: JobState; result: T }>,\n ): Promise<{ state: JobState; result: T }> {\n return this.serial(job, async () => {\n for (let attempt = 1; ; attempt++) {\n const current = await this.readState(job);\n const { state, result } = await change(current);\n if (sameState(state, current)) return { state: current, result };\n const version = stateVersion(current);\n const next: JobState = { ...state, version: version + 1 };\n if (await this.writeState(next, version)) return { state: next, result };\n if (attempt >= STATE_ATTEMPTS) {\n throw new Error(`the state of ${job} changed under ${STATE_ATTEMPTS} attempts in a row to update it; gave up`);\n }\n }\n });\n }\n\n /** A conditional write, or for a store without compareAndSetState, a plain one that always succeeds. */\n private async writeState(state: JobState, expectedVersion: number): Promise<boolean> {\n if (typeof this.store.compareAndSetState === \"function\") return this.store.compareAndSetState(state, expectedVersion);\n await this.store.setState(state);\n return true;\n }\n\n /**\n * Runs a function as a recorded run. The function always runs, whatever\n * the store is doing: store errors go to onError, and the result is the\n * function's own outcome. Never throws for the job's own error; see `threw`.\n */\n private async execute<T>(definition: JobDefinition, fn: JobFn<T>, trigger: string): Promise<ExecuteResult<T>> {\n const name = definition.name;\n const startedAt = this.now();\n const run: Run = {\n id: crypto.randomUUID(),\n job: name,\n status: \"running\",\n startedAt,\n finishedAt: null,\n durationMs: null,\n error: null,\n output: null,\n metrics: {},\n trigger,\n };\n let recorded = false;\n try {\n await this.sync(definition, true);\n await this.store.insertRun({ ...run });\n recorded = true;\n } catch (e) {\n this.report(e, `recording ${name}`);\n }\n // Closing missed and stuck happens beside the job, which never waits on it.\n const begun = { ...run };\n const started = recorded\n ? this.updateState(name, (before) => ({ state: holdRun(onRunStart(definition, begun, before, this.now()), run.id), result: undefined }))\n .then(() => {}, (e) => this.report(e, `starting ${name}`))\n : Promise.resolve();\n\n const recorder = createRecorder(run);\n const clearTimer = after(timeoutMs(definition), () => recorder.abort());\n\n let result: T | undefined;\n let error: unknown;\n let threw = false;\n try {\n result = await fn(recorder.context);\n } catch (e) {\n error = e;\n threw = true;\n } finally {\n clearTimer();\n }\n\n const finishedAt = this.now();\n run.finishedAt = finishedAt;\n run.durationMs = runDuration(startedAt, finishedAt);\n run.metrics = recorder.metrics();\n run.output = recorder.output() ?? (typeof result === \"string\" ? result : null);\n this.conclude(definition, run, result, error, threw, recorder.expectText() ?? (typeof result === \"string\" ? result : null));\n\n await started;\n try {\n const ignored = await this.recordFinish(definition, run, recorded, finishedAt);\n if (ignored) this.report(new Error(`run ${run.id} of ${name} ${ignored}; ignored`), `finishing ${name}`);\n } catch (e) {\n this.report(e, `recording ${name}`);\n }\n return { run, result, error, threw };\n }\n\n /**\n * Sets a finished run's status and error from how it ended, then redacts\n * its output and error and caps them, in that order. Shared by execute()\n * and RunHandle.finish().\n */\n private conclude(definition: JobDefinition, run: Run, result: unknown, error: unknown, threw: boolean, expectText: string | null): void {\n if (threw) {\n run.status = \"failed\";\n run.error = describeError(error);\n } else if (result instanceof Response && result.status >= 400) {\n run.status = \"failed\";\n run.error = `HTTP ${result.status}${result.statusText ? ` ${result.statusText}` : \"\"}`;\n } else {\n const unmet = checkExpectation(definition.expect, expectText);\n if (unmet) {\n run.status = \"failed\";\n run.error = unmet;\n } else {\n run.status = \"ok\";\n }\n }\n // Redacted after the expect check, so a rule can still match what was\n // logged, and before the cap, so the cut cannot keep half a secret. NULs\n // go last, so not even a custom redact can store one.\n if (run.output !== null) run.output = redactAndCap(run.output, this.redact);\n if (run.error !== null) run.error = redactAndCap(run.error, this.redact);\n }\n\n /**\n * Writes a finished run and evaluates it. `recorded` says whether its\n * start was written; if not, it is inserted now. Returns why nothing was\n * recorded (another process finished the run first, say), or null. Throws\n * when the store does, so a handle can be finished again. Shared by\n * execute() and RunHandle.finish().\n */\n private async recordFinish(definition: JobDefinition, run: Run, recorded: boolean, finishedAt: number): Promise<string | null> {\n if (!recorded) {\n // The start was never written; the store may be back by now.\n await this.sync(definition);\n try {\n await this.store.insertRun(run);\n await this.finishRun(toStored(definition), run, finishedAt);\n return null;\n } catch (e) {\n // Another process may have recorded a run with this id meanwhile.\n const stored = await this.store.getRun(run.id).catch(() => null);\n if (!stored) throw e;\n if (stored.job !== run.job) return `belongs to job \"${stored.job}\"`;\n }\n }\n // A recovery can consume the marker after the finished row is committed, before this process evaluates it.\n const tracked = (await this.readState(run.job)).pendingRuns?.includes(run.id) ?? false;\n const claim = await this.claimFinish(run);\n if (\"ignored\" in claim) return claim.ignored;\n if (!claim.lateAfterTimeout || run.status === \"ok\") await this.finishRun(toStored(definition), run, finishedAt, tracked && !claim.lateAfterTimeout);\n return null;\n }\n\n /** A conditional write (Store.updateRunIf), or for a store without one, a read then a plain write. */\n private async writeRunIf(run: Run, fromStatuses: Run[\"status\"][]): Promise<boolean> {\n if (typeof this.store.updateRunIf === \"function\") return this.store.updateRunIf(run, fromStatuses);\n const stored = await this.store.getRun(run.id);\n if (!stored || !fromStatuses.includes(stored.status)) return false;\n await this.store.updateRun(run);\n return true;\n }\n\n /**\n * Writes a finished run over its stored row, only while that row is still\n * running, or else still marked timeout by a check. Only the process whose\n * write lands goes on to evaluate the run; for the others it returns why\n * nothing was written. `lateAfterTimeout` means a check already counted\n * the run as a stuck failure: a late failure must not count twice, while\n * a late success still closes stuck and recovers. Throws when the store does.\n */\n private async claimFinish(run: Run): Promise<{ lateAfterTimeout: boolean } | { ignored: string }> {\n if (await this.writeRunIf(run, [\"running\"])) return { lateAfterTimeout: false };\n if (await this.writeRunIf(run, [\"timeout\"])) return { lateAfterTimeout: true };\n const stored = await this.store.getRun(run.id);\n return { ignored: stored ? `was already finished as ${stored.status}` : \"was not found\" };\n }\n\n /** job.start(): records a running run and returns a handle to finish it. See JobHandle.start. */\n private async startRun(definition: JobDefinition, options: StartOptions): Promise<RunHandle> {\n const id = options.id;\n if (id === undefined) return this.recordStart(definition, options.trigger);\n checkRunId(definition.name, id, \"start\");\n // Keyed by job as well, so another job's start with the same id is not\n // handed this job's run: it fails as it would one call later.\n const key = `${definition.name}\\n${id}`;\n const inFlight = this.starting.get(key);\n if (inFlight) return inFlight;\n const started = this.recordStart(definition, options.trigger, id).finally(() => {\n if (this.starting.get(key) === started) this.starting.delete(key);\n });\n this.starting.set(key, started);\n return started;\n }\n\n /**\n * The start of execute() without the function: the run is inserted and\n * missed and stuck close (onRunStart). A store that fails is reported and\n * the handle inserts the finished run instead, as execute() does.\n */\n private async recordStart(definition: JobDefinition, trigger = \"start\", id?: string): Promise<RunHandle> {\n const name = definition.name;\n if (id !== undefined) {\n let stored: Run | null = null;\n try {\n await this.ensureReady();\n stored = await this.store.getRun(id);\n } catch (e) {\n this.report(e, `recording ${name}`);\n }\n if (stored) return this.existingHandle(definition, stored);\n }\n const run: Run = {\n id: id ?? crypto.randomUUID(),\n job: name,\n status: \"running\",\n startedAt: this.now(),\n finishedAt: null,\n durationMs: null,\n error: null,\n output: null,\n metrics: {},\n trigger,\n };\n let recorded = false;\n try {\n await this.sync(definition, true);\n await this.store.insertRun({ ...run });\n recorded = true;\n } catch (e) {\n // Another process may have started a run with this id first.\n const stored = id === undefined ? null : await this.store.getRun(id).catch(() => null);\n if (stored) return this.existingHandle(definition, stored);\n this.report(e, `recording ${name}`);\n }\n if (recorded) {\n await this.updateState(name, (before) => ({ state: holdRun(onRunStart(definition, run, before, this.now()), run.id), result: undefined }))\n .catch((e: unknown) => this.report(e, `starting ${name}`));\n }\n return this.runHandle(definition, run.id, run, recorded, null);\n }\n\n /** job.resume() and cw.resumeRun(). A store that cannot be read is reported, and finish() reads it again. */\n private async resumeHandle(definition: JobDefinition, runId: string): Promise<RunHandle> {\n checkRunId(definition.name, runId, \"resume\");\n let stored: Run | null;\n try {\n await this.ensureReady();\n stored = await this.store.getRun(runId);\n } catch (e) {\n this.report(e, `resuming ${definition.name}`);\n return this.runHandle(definition, runId, null, true, null);\n }\n if (!stored) return this.runHandle(definition, runId, null, true, \"was not found\");\n return this.existingHandle(definition, stored);\n }\n\n /** A handle on a stored run. One still running, or marked timeout by a check, can be finished. */\n private existingHandle(definition: JobDefinition, stored: Run): RunHandle {\n if (stored.job !== definition.name) {\n throw new Error(`run \"${stored.id}\" belongs to job \"${stored.job}\", not \"${definition.name}\"`);\n }\n const finished = stored.status === \"ok\" || stored.status === \"failed\";\n return this.runHandle(definition, stored.id, stored, true, finished ? `already finished as ${stored.status}` : null);\n }\n\n /**\n * The handle itself. `base` is the run as last known here, `recorded`\n * whether its start is in the store, and `inactive` why finish() has\n * nothing to do, or null. Lines and metrics wait in the handle until\n * flush() or finish() merges them onto a fresh read of the stored run.\n */\n private runHandle(definition: JobDefinition, id: string, base: Run | null, recorded: boolean, inactive: string | null): RunHandle {\n const self = this;\n const name = definition.name;\n const fresh = () => createRecorder({ id, job: name, startedAt: base?.startedAt ?? 0 } as Run);\n let recorder = fresh();\n let finished = inactive !== null;\n let finishCalled = false;\n /**\n * The first OUTPUT_CAP characters of every line flushed from this\n * handle, unredacted, or null before the first flush. The stored output\n * keeps only the tail, so without it an expect rule at finish() would\n * miss a line logged early, which run() would have seen.\n */\n let head: string | null = null;\n let queue: Promise<unknown> = Promise.resolve();\n const inTurn = <T>(fn: () => Promise<T>): Promise<T> => {\n const result = queue.then(fn);\n queue = result.catch(() => {});\n return result;\n };\n const ignored = (why: string) => self.report(new Error(`run ${id} of ${name} ${why}; ignored`), `finishing ${name}`);\n\n const finish = (outcome?: RunOutcome | string): Promise<Run | null> => {\n if (finishCalled) {\n ignored(\"was already finished by this handle\");\n return Promise.resolve(null);\n }\n finishCalled = true;\n const wasInactive = finished;\n finished = true;\n // The store failed part way and nothing was recorded, so the handle can be finished again.\n const retryable = (error: unknown): null => {\n finishCalled = false;\n finished = false;\n self.report(error, `finishing ${name}`);\n return null;\n };\n return inTurn(async () => {\n if (wasInactive) {\n ignored(inactive!);\n return null;\n }\n let from = base;\n if (recorded) {\n try {\n from = (await self.store.getRun(id)) ?? base;\n } catch (e) {\n return retryable(e);\n }\n }\n if (!from) {\n ignored(\"was not found\");\n return null;\n }\n if (from.job !== name) {\n ignored(`belongs to job \"${from.job}\"`);\n return null;\n }\n if (from.status === \"ok\" || from.status === \"failed\") {\n ignored(`was already finished as ${from.status}`);\n return null;\n }\n const failed = typeof outcome === \"object\" && outcome !== null && \"error\" in outcome;\n const result = typeof outcome === \"string\" ? outcome : failed ? undefined : outcome?.result;\n const error = failed ? (outcome as { error: unknown }).error : undefined;\n const finishedAt = self.now();\n const added = recorder.output() ?? (typeof result === \"string\" ? result : null);\n const run: Run = {\n ...from,\n status: \"running\",\n finishedAt,\n durationMs: runDuration(from.startedAt, finishedAt),\n error: null,\n // Capped by conclude(), after it is redacted.\n output: joinLines(from.output, added),\n metrics: { ...from.metrics, ...recorder.metrics() },\n };\n const expectText = joinLines(head, joinLines(from.output, recorder.expectText() ?? (typeof result === \"string\" ? result : null)));\n self.conclude(definition, run, result, error, failed, expectText);\n let why: string | null;\n try {\n why = await self.recordFinish(definition, run, recorded, finishedAt);\n } catch (e) {\n return retryable(e);\n }\n if (why) {\n ignored(why);\n return null;\n }\n return run;\n });\n };\n\n return {\n id,\n job: name,\n startedAt: base?.startedAt ?? null,\n get active() {\n return !finished;\n },\n log: (...parts: unknown[]) => recorder.context.log(...parts),\n metric: (metric: string, value: number) => recorder.context.metric(metric, value),\n metrics: (values: Record<string, number>) => recorder.context.metrics(values),\n flush: () => inTurn(async () => {\n if (finished || !recorded) return;\n const lines = recorder.output();\n const metrics = recorder.metrics();\n if (lines === null && Object.keys(metrics).length === 0) return;\n // Lines logged while this waits on the store go to a new recorder.\n const taken = recorder;\n recorder = fresh();\n const putBack = () => {\n const later = recorder;\n recorder = fresh();\n for (const text of [taken.expectText(), later.expectText()]) if (text !== null) recorder.context.log(text);\n recorder.context.metrics({ ...taken.metrics(), ...later.metrics() });\n };\n try {\n const stored = await self.store.getRun(id);\n // Not running: the lines stay here for finish(), which reports why it cannot record them.\n if (!stored || stored.status !== \"running\") return putBack();\n if (stored.job !== name) {\n putBack();\n self.report(new Error(`run ${id} of ${name} belongs to job \"${stored.job}\"; ignored`), `flushing ${name}`);\n return;\n }\n const output = lines === null ? stored.output : joinOutput(stored.output, redactAndCap(lines, self.redact));\n // Only over a row still running, so a flush never undoes a finish written meanwhile.\n if (!(await self.writeRunIf({ ...stored, output, metrics: { ...stored.metrics, ...metrics } }, [\"running\"]))) return putBack();\n const text = taken.expectText();\n if (text !== null && (head === null || head.length < OUTPUT_CAP)) head = (joinLines(head, text) ?? \"\").slice(0, OUTPUT_CAP);\n } catch (e) {\n putBack();\n self.report(e, `flushing ${name}`);\n }\n }),\n finish,\n fail: (error: unknown) => finish({ error }),\n };\n }\n\n /**\n * Record a run that happened outside this process, for a Source. Its job\n * must be declared with job() first. Runs are keyed by id: a new one is\n * inserted, a stored one still running (or marked timeout by a check) is\n * finished when this one is not running, and anything else is left alone,\n * so recording the same run twice changes nothing. Finishing is\n * conditional (see Store.updateRunIf): when two processes record the same\n * finish, only the one whose write lands evaluates it, and the other\n * reports it as already finished. A stored run of another job is left\n * alone and reported. A finished run is judged as if it had been wrapped\n * here (expect, failures, duration, budgets) and its output and error are\n * redacted the same way; one finishing after a check marked it timeout is\n * judged only when it succeeded, as RunHandle.finish() does. A metric that\n * is not a finite number throws before anything is written, as\n * job.metric() does. Returns the alerts it sent.\n */\n async recordRun(input: Run, options: RecordRunOptions = {}): Promise<Alert[]> {\n const declared = this.definitions.get(input.job);\n if (!declared) throw new Error(`recordRun: job \"${input.job}\" is not declared; call job() first`);\n // The longest id start() takes; MySQL's column would hold 255, but every store holds 200.\n if (typeof input.id !== \"string\" || input.id.length === 0 || input.id.length > MAX_RUN_ID) {\n const got = typeof input.id === \"string\" ? `${input.id.length} characters` : typeof input.id;\n throw new Error(`recordRun: run ids must be 1 to ${MAX_RUN_ID} characters (got ${got}; job \"${input.job}\")`);\n }\n if (input.id.includes(\"\\u0000\")) throw new Error(`recordRun: run ids cannot contain a NUL character (job \"${input.job}\")`);\n // Refused as job.metric() refuses them: a store keeps NaN and Infinity as null.\n for (const [metric, value] of Object.entries(input.metrics ?? {})) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`recordRun: metric \"${metric}\" must be a finite number (job \"${input.job}\", run \"${input.id}\")`);\n }\n }\n await this.sync(declared);\n const run: Run = { ...input, metrics: { ...input.metrics } };\n if (run.status === \"ok\") {\n const unmet = checkExpectation(declared.expect, run.output);\n if (unmet) {\n run.status = \"failed\";\n run.error = unmet;\n }\n }\n if (run.output !== null) run.output = redactAndCap(run.output, this.redact);\n if (run.error !== null) run.error = redactAndCap(run.error, this.redact);\n const evaluate = options.evaluate !== false;\n const definition = toStored(declared);\n\n const stored = await this.store.getRun(run.id);\n if (stored) return this.recordOver(definition, stored, run, evaluate);\n // An evaluated import stays retryable until its durable evaluation marker\n // is written. A finished row alone cannot distinguish lost evaluation\n // from history deliberately imported without evaluation.\n const inserted: Run = evaluate ? { ...run, status: \"running\" } : run;\n try {\n await this.store.insertRun(inserted);\n } catch (e) {\n // Another process recorded it first.\n const again = await this.store.getRun(run.id).catch(() => null);\n if (again) return this.recordOver(definition, again, run, evaluate);\n throw e;\n }\n if (!evaluate) return [];\n return this.recordOver(definition, inserted, run, true);\n }\n\n /** recordRun() for a run already stored. */\n private async recordOver(definition: StoredJobDefinition, stored: Run, run: Run, evaluate: boolean): Promise<Alert[]> {\n if (stored.job !== run.job) {\n this.report(new Error(`run ${run.id} of ${run.job} belongs to job \"${stored.job}\"; ignored`), `recording ${run.job}`);\n return [];\n }\n if (stored.status !== \"running\" && stored.status !== \"timeout\") return [];\n if (evaluate && stored.status === \"running\") {\n await this.updateState(run.job, async (before) => {\n // Recheck inside every CAS attempt: another importer may have\n // finished and consumed the marker since this row was first read.\n const current = await this.store.getRun(run.id);\n if (!current || current.job !== run.job || current.status !== \"running\" || before.pendingRuns?.includes(run.id)) return { state: before, result: undefined };\n return { state: holdRun(onRunStart(definition, run, before, this.now()), run.id), result: undefined };\n });\n }\n if (run.status === \"running\") return [];\n const tracked = (await this.readState(run.job)).pendingRuns?.includes(run.id) ?? false;\n const claim = await this.claimFinish(run);\n if (\"ignored\" in claim) {\n this.report(new Error(`run ${run.id} of ${run.job} ${claim.ignored}; ignored`), `recording ${run.job}`);\n return [];\n }\n if (!evaluate) {\n // Stored unjudged on purpose: a check must not evaluate it as one whose evaluation was lost.\n await this.updateState(run.job, (current) => ({ state: releaseRun(current, run.id), result: undefined }))\n .catch((e: unknown) => this.onError(e, `recording ${run.job}`));\n return [];\n }\n if (claim.lateAfterTimeout && run.status !== \"ok\") return [];\n return this.finishRun(definition, run, this.now(), tracked && !claim.lateAfterTimeout);\n }\n\n /**\n * Evaluate a finished run (ok, failed, or timed out by a check), already\n * written, against the job's state and send what that produces. The\n * alerts are written with that state (see outbox()). Never throws.\n */\n private async finishRun(definition: StoredJobDefinition, run: Run, now: number, pendingOnly = false): Promise<Alert[]> {\n let held: Held;\n try {\n let history: Run[] | null = null;\n ({ result: held } = await this.updateState(run.job, async (previous) => {\n if (pendingOnly && !(previous.pendingRuns ?? []).includes(run.id)) return { state: previous, result: { alerts: [], dropped: 0 } };\n history ??= await this.history(run);\n const before = releaseRun(previous, run.id);\n return this.outbox(applySilence(before, onRunFinish(definition, run, before, history, now), now), definition, now);\n }));\n } catch (e) {\n this.report(e, `evaluating ${run.job}`);\n return [];\n }\n this.reportDropped(run.job, held.dropped);\n return this.dispatch(run.job, held.alerts, now);\n }\n\n /**\n * An evaluation as it is written: its drafts composed into alerts and held\n * in the same state (holdAlerts), so the write that opens a condition also\n * keeps its alerts, and a process that stops before sending them does not\n * lose them. Called inside updateState(), so it only computes.\n */\n private outbox(settled: Evaluation, definition: StoredJobDefinition, now: number): { state: JobState; result: Held } {\n const alerts = settled.alerts.map((draft) => composeAlert(draft, definition, now));\n const { state, dropped } = holdAlerts(settled.state, alerts, this.now() + SEND_LEASE_MS, this.deferDelivery);\n return { state, result: { alerts, dropped } };\n }\n\n /** Reports alerts let go because a job's queue was full. */\n private reportDropped(name: string, dropped: number): void {\n if (dropped <= 0) return;\n this.report(\n new Error(`${dropped} undelivered alert${dropped === 1 ? \"\" : \"s\"} for ${name} dropped: only the newest ${MAX_UNDELIVERED} are kept for retry`),\n `alert queue for ${name}`,\n );\n }\n\n /**\n * The runs before `run`, newest first, with up to BASELINE_WINDOW\n * successful ones when the store has them. One small read normally; a\n * larger one only when failures crowd the successes out of it.\n */\n private async history(run: Run): Promise<Run[]> {\n let runs = await this.store.listRuns(run.job, HISTORY_PAGE);\n if (runs.length === HISTORY_PAGE && !hasFullBaseline(runs.filter((r) => r.id !== run.id))) {\n runs = await this.store.listRuns(run.job, HISTORY_MAX);\n }\n return runs.filter((r) => r.id !== run.id);\n }\n\n /**\n * Look for missed and stuck runs across every job, send alerts, retry\n * alerts to the channels that refused them, and prune old runs. Call it from an interval\n * (start()), a cron hitting the mounted routes, or by hand. Concurrent\n * calls share one check.\n */\n check(): Promise<CheckResult> {\n if (!this.checking) {\n this.checking = this.runCheck().finally(() => {\n this.checking = null;\n });\n }\n return this.checking;\n }\n\n private async runCheck(): Promise<CheckResult> {\n await this.ensureReady();\n const alerts: Alert[] = [];\n for (const source of this.sources) {\n try {\n alerts.push(...((await source.sync(this)) ?? []));\n } catch (e) {\n this.onError(e, `source ${source.name}`);\n }\n }\n for (const definition of this.definitions.values()) await this.sync(definition);\n const now = this.now();\n\n // Runs that never reported back. One that cannot be judged (its job's\n // stored timeout no longer parses, say) is reported and skipped.\n for (const listed of await this.store.runningRuns()) {\n try {\n const declared = this.definitions.get(listed.job);\n const found = declared ? null : await this.store.getJob(listed.job);\n const stored = found ? this.readJob(found) : null;\n if (stored) this.evaluable(stored);\n const definition = declared ? toStored(declared) : stored?.definition;\n if (!definition || !isStuck(definition, listed, now)) continue;\n // Read again just before the write: lines and metrics flushed since the\n // list was read (while earlier stuck runs were sent, say) are kept.\n const run = await this.store.getRun(listed.id);\n if (!run || run.status !== \"running\" || run.job !== listed.job) continue;\n const timeout = timeoutMs(definition);\n run.status = \"timeout\";\n run.finishedAt = now;\n run.durationMs = runDuration(run.startedAt, now);\n run.error = `Still running after ${formatDuration(timeout)}; marked as timed out`;\n // Only over a row still running: a finish that landed meanwhile wins.\n if (!(await this.writeRunIf(run, [\"running\"]))) continue;\n alerts.push(...(await this.finishRun(definition, run, now)));\n } catch (e) {\n this.onError(e, `checking ${listed.job}`);\n }\n }\n\n // Each job on its own: one that cannot be evaluated is reported, shown\n // as failing (see unevaluableSummary), and does not stop the others.\n const jobs: JobSummary[] = [];\n const retries = { spentMs: 0 };\n for (const stored of await this.storedJobs()) {\n try {\n this.evaluable(stored);\n const recent = await this.store.listRuns(stored.name, BASELINE_WINDOW);\n let nextExpectedAt: number | null = null;\n const { state, result: held } = await this.updateState(stored.name, (previous) => {\n const evaluation = onCheck(stored.definition, stored, recent[0] ?? null, previous, now);\n nextExpectedAt = evaluation.nextExpectedAt;\n const settled = applySilence(previous, evaluation, now);\n // Alerts a process stopped sending part way go back to the retry queue.\n const released = releaseSending(settled.state, this.now());\n const out = this.outbox({ state: released.state, alerts: settled.alerts }, stored.definition, now);\n return { state: out.state, result: { alerts: out.result.alerts, dropped: released.dropped + out.result.dropped } };\n });\n this.reportDropped(stored.name, held.dropped);\n alerts.push(...(await this.retryUndelivered(stored.name, state, now, retries)));\n alerts.push(...(await this.dispatch(stored.name, held.alerts, now)));\n alerts.push(...(await this.evaluatePending(stored, recent, state, now)));\n jobs.push(summarize(stored, recent, state, nextExpectedAt, now));\n } catch (e) {\n this.onError(e, `checking ${stored.name}`);\n jobs.push(await this.unevaluable(stored, now));\n }\n }\n\n let pruned = 0;\n if (now - this.lastPruneAt > PRUNE_INTERVAL_MS) {\n this.lastPruneAt = now;\n try {\n pruned = await this.store.prune(now - this.retentionMs);\n } catch (e) {\n this.onError(e, \"pruning\");\n }\n }\n\n return { checkedAt: now, jobs, alerts, pruned };\n }\n\n /**\n * Runs the job's state still holds as pending (holdRun) whose finish was\n * written but never evaluated: the process that finished them stopped, or\n * its state write failed, between the two writes. Each one finished more\n * than SEND_LEASE_MS ago is evaluated now, as its finish would have been;\n * one still running is left to the stuck check, and one the store no\n * longer has (given back, or pruned) is let go. The wait leaves a finish\n * under way in another process to write its own evaluation.\n */\n private async evaluatePending(stored: StoredJob, recent: Run[], state: JobState, now: number): Promise<Alert[]> {\n const alerts: Alert[] = [];\n for (const id of state.pendingRuns ?? []) {\n try {\n const run = recent.find((r) => r.id === id) ?? (await this.store.getRun(id));\n if (!run || run.job !== stored.name) {\n await this.updateState(stored.name, (current) => ({ state: releaseRun(current, id), result: undefined }));\n continue;\n }\n if (run.status === \"running\" || typeof run.finishedAt !== \"number\" || run.finishedAt > now - SEND_LEASE_MS) continue;\n alerts.push(...(await this.finishRun(stored.definition, run, now, true)));\n } catch (e) {\n this.onError(e, `evaluating run ${id} of ${stored.name}`);\n }\n }\n return alerts;\n }\n\n /** A job's summary and its newest runs, without alerting. A job that cannot be evaluated is reported and shown as failing. */\n private async snapshot(stored: StoredJob, now: number, runs: number): Promise<{ job: JobSummary; runs: Run[] }> {\n let recent: Run[] = [];\n try {\n recent = await this.store.listRuns(stored.name, Math.max(runs, BASELINE_WINDOW));\n this.evaluable(stored);\n const state = await this.readState(stored.name);\n const { nextExpectedAt } = onCheck(stored.definition, stored, recent[0] ?? null, state, now);\n return { job: summarize(stored, recent, state, nextExpectedAt, now), runs: recent.slice(0, runs) };\n } catch (e) {\n this.onError(e, `reading ${stored.name}`);\n return { job: await this.unevaluable(stored, now), runs: recent.slice(0, runs) };\n }\n }\n\n /** The summary of a job whose evaluation failed, from whatever can still be read. */\n private async unevaluable(stored: StoredJob, now: number): Promise<JobSummary> {\n const recent = await this.store.listRuns(stored.name, BASELINE_WINDOW).catch((): Run[] => []);\n const state = await this.readState(stored.name).catch(() => emptyState(stored.name));\n return unevaluableSummary(stored, recent, state, now);\n }\n\n /** Every job the store knows about, with its health. Does not send alerts. */\n async jobs(): Promise<JobSummary[]> {\n return (await this.jobsWithRuns(0)).map((entry) => entry.job);\n }\n\n /** Every job's summary with its newest `limit` runs, read together. What the dashboard shows. */\n async jobsWithRuns(limit = 20): Promise<{ job: JobSummary; runs: Run[] }[]> {\n await this.ensureReady();\n const jobs = await this.storedJobs();\n const now = this.now();\n const out: { job: JobSummary; runs: Run[] }[] = [];\n for (const stored of jobs) out.push(await this.snapshot(stored, now, clampLimit(limit, 20, 0)));\n return out;\n }\n\n /** A job's summary, or null for one the store does not have. One declared here and forgotten elsewhere is written again, as storedJobs() does. */\n async jobSummary(name: string): Promise<JobSummary | null> {\n await this.ensureReady();\n const definition = this.definitions.get(name);\n if (definition) await this.sync(definition, true);\n const stored = await this.store.getJob(name);\n if (!stored) return null;\n return (await this.snapshot(this.readJob(stored), this.now(), 0)).job;\n }\n\n /** A job's runs, newest first. `limit` is a whole number from 1 to 500. */\n async runs(name: string, limit = 50): Promise<Run[]> {\n await this.ensureReady();\n return this.store.listRuns(name, clampLimit(limit, 50, 1));\n }\n\n async getRun(id: string): Promise<Run | null> {\n await this.ensureReady();\n return this.store.getRun(id);\n }\n\n /**\n * Stop alerts for a job for a while. State keeps updating underneath. The\n * end is a whole millisecond, held at 2^53 - 1 (see silenceEnd).\n */\n async silence(name: string, duration: Duration): Promise<JobState> {\n const ms = parseDuration(duration, \"silence duration\");\n return this.patchState(name, (state) => { state.silencedUntil = silenceEnd(this.now(), ms); });\n }\n\n async unsilence(name: string): Promise<JobState> {\n return this.patchState(name, (state) => { state.silencedUntil = null; });\n }\n\n /** Read, change, and write one job's state, in turn with every other update to it. */\n private async patchState(name: string, change: (state: JobState) => void): Promise<JobState> {\n await this.ensureReady();\n const { state } = await this.updateState(name, (current) => {\n const next = normalizeState(current, name);\n change(next);\n return { state: next, result: undefined };\n });\n return state;\n }\n\n /**\n * Remove a job and its runs from the store. A job still declared in code\n * comes back, with no history: here on its next run, declared as it was\n * written (cw.run() and cw.resumeRun() by name included), and in any other\n * process that declares it on its next run there, or at that process's\n * next check or dashboard read.\n */\n async forget(name: string): Promise<void> {\n await this.ensureReady();\n const definition = this.definitions.get(name);\n if (definition) this.forgotten.set(name, definition);\n this.definitions.delete(name);\n this.synced.delete(name);\n await this.store.deleteJob(name);\n }\n\n /**\n * The dashboard and JSON API as fetch-style handlers: the one way to mount\n * them. A Next.js app exports them from app/cronwatch/[[...path]]/route.ts:\n *\n * export const { GET, POST, DELETE } = cw.routes();\n */\n routes(options?: RoutesOptions): Routes {\n return buildRoutes(this, options);\n }\n\n /**\n * Check on an interval, for long-running servers. Default every minute.\n * Not for serverless functions or Cloudflare Workers, where nothing runs\n * between requests: call check() from a cron there instead. (A job's\n * start() opens a run; this starts the checks.)\n */\n startChecking(every: Duration = \"1m\"): void {\n if (this.timer) return;\n // At most setInterval's longest delay: a longer one would check every millisecond.\n const ms = Math.min(TIMER_MAX_MS, Math.max(5_000, parseDuration(every, \"check interval\")));\n if (this.deferDelivery && !this.warnedDeferredStart) {\n this.warnedDeferredStart = true;\n console.warn('[cronwatch] startChecking() was called with deliver: \"check\", so these checks send no alerts. Another process must run checks with deliver: \"now\" (the default) to send them.');\n }\n const tick = () => this.check().catch((e) => this.report(e, \"check\"));\n this.timer = setInterval(tick, ms);\n if (typeof this.timer === \"object\" && \"unref\" in this.timer) this.timer.unref();\n this.firstTick = setTimeout(() => {\n this.firstTick = null;\n void tick();\n }, 1_000);\n if (typeof this.firstTick === \"object\" && \"unref\" in this.firstTick) this.firstTick.unref();\n }\n\n /**\n * startChecking(), under its former name.\n * @deprecated Renamed `startChecking`, since a job's `start()` opens a run.\n * This name still works through 1.x and goes in 2.0.\n */\n start(every: Duration = \"1m\"): void {\n this.startChecking(every);\n }\n\n /** Stop the checks startChecking() began. */\n stop(): void {\n if (this.timer) clearInterval(this.timer);\n if (this.firstTick) clearTimeout(this.firstTick);\n this.timer = null;\n this.firstTick = null;\n }\n\n /**\n * Stop the interval, wait for a check already under way (bounded by its\n * own channel, triage, and retry timeouts; what it throws was reported to\n * whoever started it), then close the store, so that check neither writes\n * after the store is closed nor loses the alerts it would queue.\n */\n async close(): Promise<void> {\n this.stop();\n if (this.checking) await this.checking.catch(() => {});\n if (this.store.close) await this.store.close();\n }\n\n /**\n * Triage and send each alert the outbox holds (see outbox()). The state,\n * with the alerts in it, was saved before this, so a slow channel holds up\n * nothing else; afterwards only the delivery fields are written back, onto\n * a fresh read of the state, and the alerts leave `sending`. Triage is made\n * here, never stored with the held alert: the write that opens a condition\n * cannot wait for it, and a retry triages an alert that has none. With\n * deliver: \"check\" the alerts were queued for a check elsewhere instead.\n */\n private async dispatch(name: string, alerts: Alert[], now: number): Promise<Alert[]> {\n if (alerts.length === 0 || this.deferDelivery) return alerts;\n const delivered: Alert[] = [];\n const failed: HeldAlert[] = [];\n let reached = false;\n for (const alert of alerts) {\n if (this.triage && alert.type !== \"recovered\") await this.addTriage(alert, TRIAGE_TIMEOUT_MS);\n // The alert as composed, full run and all; only a retry reads the trimmed copy held in state.\n const sent = await this.deliver(alert);\n reached ||= sent.reached;\n if (sent.left) failed.push(sent.left);\n else delivered.push(alert);\n }\n await this.recordDelivery(name, delivered, failed, [], now, reached);\n return alerts;\n }\n\n /**\n * Send the alerts some channel refused last time, once each, oldest\n * first, to the channels that still owe them (HeldAlert.owed) and no\n * others, from the copy held in state, its run trimmed (heldRun). They\n * are claimed first (claimUndelivered): moved into `sending` with a lease,\n * in one conditional write, so when several processes check at once only\n * the one whose write lands sends them. An alert that no longer describes\n * the job (staleAlert) is dropped instead. Retries across a check share\n * RETRY_BUDGET_MS of wall-clock time; claimed alerts it has no time left\n * for go back to the queue for the next check. Returns the alerts some\n * channel took on this attempt.\n */\n private async retryUndelivered(name: string, state: JobState, now: number, budget: { spentMs: number }): Promise<Alert[]> {\n if ((state.undelivered ?? []).length === 0 || this.deferDelivery) return [];\n let claimed: HeldAlert[];\n try {\n ({ result: claimed } = await this.updateState(name, (previous) => {\n const claim = claimUndelivered(previous, now, this.now() + SEND_LEASE_MS);\n return { state: claim.state, result: claim.claimed };\n }));\n } catch (e) {\n this.report(e, `claiming undelivered alerts for ${name}`);\n return [];\n }\n if (claimed.length === 0) return [];\n const delivered: HeldAlert[] = [];\n const failed: HeldAlert[] = [];\n const sent: Alert[] = [];\n for (const alert of claimed) {\n const left = RETRY_BUDGET_MS - budget.spentMs;\n if (left <= 0) {\n // Not tried: back to the queue as it was.\n failed.push(alert);\n continue;\n }\n const started = Date.now();\n // An alert queued by a process that delivers at check time was never\n // triaged. One that was tried (triage: null) is not tried again.\n if (this.triage && alert.type !== \"recovered\" && alert.triage === undefined) await this.addTriage(alert, Math.min(TRIAGE_TIMEOUT_MS, left));\n const outcome = await this.deliver(alert);\n if (outcome.reached) sent.push(withoutOwed(alert));\n if (outcome.left) failed.push(outcome.left);\n else delivered.push(alert);\n budget.spentMs += Math.max(0, Date.now() - started);\n }\n await this.recordDelivery(name, delivered, failed, [], now, sent.length > 0);\n return sent;\n }\n\n /**\n * Mark delivered alerts done, drop stale ones, and keep failed ones for the\n * next check, taking them all out of `sending` (recordSent). A failed alert\n * replaces its stored copy, so a triage made on this attempt and the\n * channels that still owe it are kept. lastAlertAt moves when `reached`,\n * some channel accepted an alert on this attempt. When this write fails,\n * alerts still in `sending` are retried once their lease runs out.\n */\n private async recordDelivery(name: string, delivered: HeldAlert[], failed: HeldAlert[], dropped: HeldAlert[], now: number, reached: boolean): Promise<void> {\n try {\n const { result: trimmed } = await this.updateState(name, (previous) => {\n const { state, dropped: letGo } = recordSent(normalizeState(previous, name), delivered, failed, dropped, now, reached);\n return { state, result: letGo };\n });\n this.reportDropped(name, trimmed);\n } catch (e) {\n this.report(e, `recording alert delivery for ${name}`);\n }\n }\n\n /**\n * Send to every channel that still owes the alert (owedChannels: all of\n * them for an alert not sent before), at once, each failure reported under\n * its channel's name. `left` is the alert with `owed` cut to the channels\n * that refused it, or null when none did (or none is left to owe it);\n * `reached` is whether any channel accepted it. With no channels at all it\n * counts as delivered, as it always has.\n */\n private async deliver(alert: HeldAlert): Promise<{ left: HeldAlert | null; reached: boolean }> {\n if (this.alerts.length === 0) return { left: null, reached: true };\n const keys = channelKeys(this.alerts.map((channel) => channel.name));\n const owed = owedChannels(alert, keys);\n if (owed.length === 0) return { left: null, reached: false };\n const plain = withoutOwed(alert);\n const failed: string[] = [];\n await Promise.all(\n this.alerts.map(async (channel, i) => {\n if (!owed.includes(keys[i]!)) return;\n try {\n await withTimeout(channel.send(plain, { onError: (e) => this.report(e, `alert channel ${channel.name}`) }), CHANNEL_TIMEOUT_MS);\n } catch (e) {\n failed.push(keys[i]!);\n this.report(e, `alert channel ${channel.name}`);\n }\n }),\n );\n return { left: afterSend(alert, owed, failed), reached: failed.length < owed.length };\n }\n\n /** Sets alert.triage to the diagnosis, or to null when there is none, so it is tried once per alert. */\n private async addTriage(alert: Alert, timeout: number): Promise<void> {\n const controller = new AbortController();\n try {\n const recentRuns = await this.store.listRuns(alert.job, 5);\n const diagnosis = await withTimeout(this.triage!({ alert, recentRuns, signal: controller.signal }), timeout);\n alert.triage = typeof diagnosis === \"string\" && diagnosis !== \"\" ? diagnosis : null;\n } catch (e) {\n controller.abort();\n alert.triage = null;\n this.report(e, `triage for ${alert.job}`);\n }\n }\n}\n\n/** Run ids that start with this belong to the pg_cron source (see @cronwatch/sdk/pg-cron). */\nexport const RESERVED_RUN_ID_PREFIX = \"pgcron:\";\n\n/**\n * The longest run id, in UTF-16 code units (JavaScript's string length): what\n * start(), resume(), and recordRun() take, and every store holds.\n */\nconst MAX_RUN_ID = 200;\n\n/** Throws for a run id no store could hold, or one reserved for the pg_cron source. */\nfunction checkRunId(job: string, id: unknown, method: string): void {\n if (typeof id !== \"string\" || id.length === 0 || id.length > MAX_RUN_ID) {\n throw new Error(`job \"${job}\": ${method}() needs a run id of 1 to ${MAX_RUN_ID} characters (got ${typeof id === \"string\" ? `${id.length} characters` : typeof id})`);\n }\n // Postgres refuses NUL in text, so no store could hold such an id.\n if (id.includes(\"\\u0000\")) throw new Error(`job \"${job}\": ${method}() cannot take a run id containing a NUL character`);\n if (id.startsWith(RESERVED_RUN_ID_PREFIX)) {\n throw new Error(`job \"${job}\": ${method}() cannot take a run id starting with \"${RESERVED_RUN_ID_PREFIX}\", which the pg_cron source uses for its runs`);\n }\n}\n\n/** Two stretches of text as one, a line apart; either may be null. */\nfunction joinLines(before: string | null, after: string | null): string | null {\n if (before === null || before === \"\") return after;\n if (after === null) return before;\n return `${before}\\n${after}`;\n}\n\n/** Output appended to stored output, capped like any run's. */\nfunction joinOutput(before: string | null, after: string | null): string | null {\n const joined = joinLines(before, after);\n return joined === null ? null : capOutput(joined);\n}\n\n/** A whole number in range, or the fallback for anything that is not a number. */\nfunction clampLimit(limit: number, fallback: number, min: number): number {\n const n = typeof limit === \"number\" && Number.isFinite(limit) ? Math.trunc(limit) : fallback;\n return Math.min(500, Math.max(min, n));\n}\n\n/** The longest delay setTimeout keeps: Node runs a longer one after 1 ms. */\nconst TIMER_MAX_MS = 2 ** 31 - 1;\n\n/**\n * Calls fn after ms, however long (a job's timeout of \"30d\" included, which\n * setTimeout alone would fire at once), without keeping the process alive.\n * Returns what cancels it.\n */\nfunction after(ms: number, fn: () => void): () => void {\n let timer: ReturnType<typeof setTimeout>;\n const arm = (left: number): void => {\n timer = left > TIMER_MAX_MS ? setTimeout(() => arm(left - TIMER_MAX_MS), TIMER_MAX_MS) : setTimeout(fn, left);\n if (typeof timer === \"object\" && \"unref\" in timer) timer.unref();\n };\n arm(ms);\n return () => clearTimeout(timer);\n}\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const t = setTimeout(() => reject(new Error(`timed out after ${ms}ms`)), ms);\n if (typeof t === \"object\" && \"unref\" in t) t.unref();\n promise.then((v) => { clearTimeout(t); resolve(v); }, (e) => { clearTimeout(t); reject(e); });\n });\n}\n\n/** Writes alerts to the console. The default channel. */\nexport function consoleChannel(): AlertChannel {\n return {\n name: \"console\",\n async send(alert) {\n const line = `[cronwatch] ${alert.title}\\n${alert.message}${alert.triage ? `\\nTriage: ${alert.triage}` : \"\"}`;\n if (alert.type === \"recovered\") console.info(line);\n else console.error(line);\n },\n };\n}\n\n/** Wrap any function as an alert channel. */\nexport function custom(name: string, send: (alert: Alert) => Promise<void> | void): AlertChannel {\n return { name, send: async (alert) => { await send(alert); } };\n}\n\nexport type { Condition };\n\n/**\n * The client's former name.\n * @deprecated Renamed `Cronwatch`, the spelling every port uses. This name\n * still works through 1.x and goes in 2.0.\n */\nexport const CronWatch = Cronwatch;\n/** @deprecated Renamed `Cronwatch`; this name goes in 2.0. */\nexport type CronWatch = Cronwatch;\n/** @deprecated Renamed `CronwatchOptions`; this name goes in 2.0. */\nexport type CronWatchOptions = CronwatchOptions;\n","import { Cronwatch } from \"./client.js\";\nimport type { CronwatchOptions } from \"./client.js\";\n\n/**\n * Create a CronWatch client. One per app, at module level:\n *\n * export const cw = cronwatch({ store: sqlite({ path: \"./data/cronwatch.db\" }), alerts: [slack({ webhookUrl })] });\n * export const nightly = cw.job(\"nightly-report\", { schedule: \"0 2 * * *\", grace: \"15m\" });\n */\nexport function cronwatch(options: CronwatchOptions = {}): Cronwatch {\n return new Cronwatch(options);\n}\n\nexport { Cronwatch, CronWatch, consoleChannel, custom } from \"./client.js\";\nexport type { CronwatchOptions, CronWatchOptions, HandlerFn, HandlerOptions, JobFn, JobHandle, RecordRunOptions, RunHandle, RunOutcome, Source, SourceHost, StartOptions } from \"./client.js\";\nexport type { JobContext } from \"./job.js\";\nexport { memory } from \"./stores/memory.js\";\nexport { VERSION } from \"./version.js\";\nexport { createRoutes } from \"./routes/index.js\";\nexport type { FetchHandler, Routes, RoutesOptions } from \"./routes/index.js\";\nexport { parseDuration, formatDuration } from \"./duration.js\";\nexport { parseSchedule, nextFire } from \"./schedule.js\";\nexport type { ParsedSchedule } from \"./schedule.js\";\nexport { composeAlert } from \"./format.js\";\nexport type {\n Alert,\n AlertChannel,\n AlertDetails,\n AlertDraft,\n AlertType,\n BudgetBreach,\n ChannelContext,\n CheckResult,\n Condition,\n Duration,\n ExpectRule,\n HeldAlert,\n JobDefinition,\n JobHealth,\n JobOptions,\n JobState,\n JobSummary,\n Run,\n RunStatus,\n SendingAlert,\n Store,\n StoredJob,\n StoredJobDefinition,\n TriageContext,\n TriageFn,\n} from \"./types.js\";\n"]}
1
+ {"version":3,"sources":["../src/duration.ts","../src/env.ts","../src/schedule.ts","../src/stats.ts","../src/evaluate.ts","../src/format.ts","../src/http.ts","../src/output.ts","../src/job.ts","../src/serialize.ts","../src/routes/escape.ts","../src/routes/icons.ts","../src/routes/pwa.ts","../src/version.ts","../src/routes/timeline.ts","../src/routes/html.ts","../src/routes/index.ts","../src/stores/memory.ts","../src/client.ts","../src/index.ts"],"names":["Cron","after","graceMs","words","json","when","times","t","r","cache","newest","tail"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Duration } from \"./types.js\";\n\nconst UNIT_MS: Record<string, number> = {\n ms: 1,\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n};\n\n/**\n * The longest duration string read, in characters (code points). No real\n * duration comes near it, and the pattern below is quadratic on a long run of\n * digits, so a longer string is refused before it is read.\n */\nconst MAX_LENGTH = 64;\n/** How much of a refused, overlong string its error quotes. */\nconst QUOTED = 32;\n\n/**\n * \"15m\" -> 900000. Accepts a plain number of milliseconds, and compound\n * strings such as \"1h30m\". Whitespace between parts is fine.\n */\nexport function parseDuration(value: Duration, label = \"duration\"): number {\n if (typeof value === \"number\") {\n if (!Number.isFinite(value) || value < 0) throw new Error(`${label} must be a non-negative number of milliseconds`);\n return value;\n }\n if (value.length > MAX_LENGTH) tooLong(value, label);\n const text = value.trim().toLowerCase();\n if (text === \"\") throw new Error(`${label} is empty`);\n const re = /(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d|w)/g;\n let total = 0;\n let consumed = \"\";\n let match: RegExpExecArray | null;\n while ((match = re.exec(text)) !== null) {\n total += parseFloat(match[1]!) * UNIT_MS[match[2]!]!;\n consumed += match[0];\n }\n if (consumed.replace(/\\s+/g, \"\") !== text.replace(/\\s+/g, \"\")) {\n throw new Error(`${label} \"${value}\" is not a duration like \"15m\", \"1h30m\", or \"90s\"`);\n }\n return Math.round(total);\n}\n\n/** Throws if `value` is over MAX_LENGTH characters, quoting the first QUOTED. */\nfunction tooLong(value: string, label: string): void {\n let count = 0;\n let head = \"\";\n for (const char of value) {\n if (count < QUOTED) head += char;\n if (++count > MAX_LENGTH) {\n throw new Error(`${label} \"${head}...\" is too long for a duration (more than ${MAX_LENGTH} characters)`);\n }\n }\n}\n\n/** 90000 -> \"1m 30s\". For messages, not for parsing back. */\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms)) return \"?\";\n if (ms < 1000) return `${Math.round(ms)}ms`;\n const parts: string[] = [];\n let rest = Math.round(ms / 1000);\n const units: [string, number][] = [[\"d\", 86_400], [\"h\", 3_600], [\"m\", 60], [\"s\", 1]];\n for (const [unit, size] of units) {\n if (rest >= size) {\n const n = Math.floor(rest / size);\n rest -= n * size;\n parts.push(`${n}${unit}`);\n }\n if (parts.length === 2) break;\n }\n return parts.join(\" \") || \"0s\";\n}\n\n/** \"5 minutes ago\", \"in 2h\". Relative to `now`. */\nexport function formatRelative(at: number, now: number): string {\n const diff = at - now;\n const abs = Math.abs(diff);\n const text = abs < 5_000 ? \"now\" : formatDuration(abs);\n if (abs < 5_000) return text;\n return diff < 0 ? `${text} ago` : `in ${text}`;\n}\n\n/** The first millisecond written as a date: 0001-01-01T00:00:00.000Z. */\nexport const FIRST_DATE_MS = -62_135_596_800_000;\n/** The last millisecond written as a date: 9999-12-31T23:59:59.999Z. */\nexport const LAST_DATE_MS = 253_402_300_799_999;\n\n/**\n * \"2026-01-05T09:30:00.000Z\", or null for a time before the year 1 or after\n * 9999. A start read from another process's row, or a damaged one, can be\n * any number; outside those years it is not written as a date at all (and\n * past JavaScript's Date range, toISOString would throw).\n */\nexport function isoTime(at: number): string | null {\n return at >= FIRST_DATE_MS && at <= LAST_DATE_MS ? new Date(at).toISOString() : null;\n}\n\n/** The words that stand in for a time isoTime() does not write: \"before 0001-01-01 00:00:00 UTC\" or \"after 9999-12-31 23:59:59 UTC\". */\nexport function beyondDates(at: number): string {\n return at > LAST_DATE_MS ? \"after 9999-12-31 23:59:59 UTC\" : \"before 0001-01-01 00:00:00 UTC\";\n}\n","/**\n * Environment variables, read only where there is a `process` to read them\n * from. Cloudflare Workers without nodejs_compat have none: there every value\n * comes from the options, which is where a Worker passes its env bindings.\n */\nexport function readEnv(name: string): string | undefined {\n return typeof process === \"undefined\" || !process.env ? undefined : process.env[name];\n}\n\n/**\n * A secret from the environment (CRONWATCH_TOKEN, CRON_SECRET), trimmed (as\n * String.prototype.trim trims): a value read from a file often ends in a\n * newline that no header can carry, since HTTP strips the whitespace around\n * a header's value. Undefined when the variable is unset, empty, or only\n * whitespace, so a blank value counts as not set and the routes and handlers\n * fail closed.\n */\nexport function readSecretEnv(name: string): string | undefined {\n const value = readEnv(name)?.trim();\n return value === undefined || value === \"\" ? undefined : value;\n}\n\n/**\n * A token or secret passed in code: a string, null (the opt-out), or\n * undefined (not given). A string is trimmed, as readSecretEnv() trims, and\n * one that is empty or only whitespace counts as not given. Anything else\n * (false, a number, an object) throws a TypeError naming the option, so it\n * never becomes a password.\n */\nexport function secretOption(value: unknown, what: string): string | null | undefined {\n if (value === undefined || value === null) return value;\n if (typeof value !== \"string\") {\n throw new TypeError(`${what} must be a string, or null to opt out, not ${Array.isArray(value) ? \"an array\" : typeof value}`);\n }\n const trimmed = value.trim();\n return trimmed === \"\" ? undefined : trimmed;\n}\n\n/**\n * The environment's name from the values of the variables that name it, in\n * order, as every CronWatch library reads it: the first that holds more than\n * whitespace, trimmed and lowercased, with \"prod\" read as \"production\" and\n * \"dev\" and \"local\" as \"development\"; \"\" when none is set. \"test\" and\n * \"testing\" are not development: a test run or CI needs CRON_SECRET or a\n * token, as production does.\n */\nexport function environmentOf(values: readonly (string | undefined)[]): string {\n for (const value of values) {\n const name = typeof value === \"string\" ? value.trim().toLowerCase() : \"\";\n if (name === \"\") continue;\n if (name === \"prod\") return \"production\";\n if (name === \"dev\" || name === \"local\") return \"development\";\n return name;\n }\n return \"\";\n}\n\n/**\n * The environment's name (environmentOf) from CRONWATCH_ENV, APP_ENV, and\n * NODE_ENV. The variables are written out in full so that bundlers which\n * inline process.env.NODE_ENV still can.\n */\nexport function environment(): string {\n if (typeof process === \"undefined\" || !process.env) return \"\";\n return environmentOf([process.env.CRONWATCH_ENV, process.env.APP_ENV, process.env.NODE_ENV]);\n}\n\n/** Development makes a dashboard token of its own and lets a handler with no secret run. */\nexport function isDevelopment(): boolean {\n return environment() === \"development\";\n}\n\n/** Production warns that the default in-memory store forgets on restart. */\nexport function isProduction(): boolean {\n return environment() === \"production\";\n}\n","import { Cron } from \"croner\";\nimport { FIRST_DATE_MS, LAST_DATE_MS, parseDuration } from \"./duration.js\";\n\nexport interface ParsedSchedule {\n kind: \"cron\" | \"interval\";\n source: string;\n /** The IANA timezone a cron is read in, when one was given. */\n timezone?: string;\n /** For intervals, the period in milliseconds. */\n everyMs?: number;\n}\n\nconst cache = new Map<string, ParsedSchedule>();\n/** The croner instance behind each cron schedule, kept out of the public type. */\nconst crons = new WeakMap<ParsedSchedule, Cron>();\n/** Cron schedules that name a date no month has, which never fire. */\nconst never = new WeakSet<ParsedSchedule>();\n\n/** Where neverFires() looks from: croner looks up to the year 3000, more than a 400-year cycle of the calendar. */\nconst PROBE_FROM_MS = Date.UTC(2000, 0, 1);\n\n/**\n * Whether a cron never fires: it names a date no month has, such as\n * \"0 0 30 2 *\". croner walks to such a date by recursion, a year at a time,\n * so it answers that there is none, or runs out of stack first (from further\n * back, or over several months); either way the schedule never fires, and is\n * then never asked again. Anything else croner throws here (a timezone it\n * cannot use) is left to the calls that compute fire times, as before.\n */\nfunction neverFires(cron: Cron): boolean {\n try {\n return cron.nextRuns(1, new Date(PROBE_FROM_MS)).length === 0;\n } catch (error) {\n return error instanceof RangeError && /call stack/i.test(error.message);\n }\n}\n\n/** Text that starts like an ISO date and time, which croner would take for a one-time date. */\nconst ONE_TIME_DATE = /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}/;\n\n/** How early a run may start and still count for the fire it was meant for. */\nexport const EARLY_SLACK_MS = 60_000;\n\n/**\n * \"0 2 * * *\" (cron, five or six fields), \"@hourly\", or \"every 5m\".\n * Text with a colon after its first character, which croner would take for\n * a one-time date, is refused. A cron that names a date no month has\n * (\"0 0 30 2 *\") is read, and never fires: nothing is ever due, so it is\n * never missed. Parsed once per (schedule, timezone) pair and cached. The\n * croner instance gets no callback, so it schedules nothing; it is only used\n * to compute fire times. Without a timezone the expression is read in the process timezone,\n * like crontab. Vercel and GitHub Actions run their crons in UTC, so pass\n * timezone: \"UTC\" for those.\n */\nexport function parseSchedule(schedule: string, timezone?: string): ParsedSchedule {\n const key = `${timezone ?? \"\"}|${schedule}`;\n const hit = cache.get(key);\n if (hit) return hit;\n\n const text = schedule.trim();\n const every = /^every\\s+(.+)$/i.exec(text);\n let parsed: ParsedSchedule;\n if (every) {\n const everyMs = parseDuration(every[1]!, \"schedule interval\");\n if (everyMs < 1000) throw new Error(`schedule \"${schedule}\" is shorter than one second`);\n parsed = { kind: \"interval\", source: text, everyMs };\n } else {\n // croner reads text with a colon after its first character as a one-time\n // date to fire at (through Date.parse, which reads almost anything), not\n // as a cron expression. A cron monitor has no use for one, so every such\n // text is refused, as in every port.\n if (text.slice(1).includes(\":\")) {\n const reason = ONE_TIME_DATE.test(text) ? \"CronPattern: a one-time date is not supported\" : \"Invalid ISO8601 passed to timezone parser.\";\n throw new Error(`schedule \"${schedule}\" is not a cron expression or \"every <duration>\": ${reason}`);\n }\n let cron: Cron;\n try {\n cron = new Cron(text, timezone ? { timezone } : {});\n } catch (error) {\n throw new Error(`schedule \"${schedule}\" is not a cron expression or \"every <duration>\": ${(error as Error).message}`);\n }\n parsed = { kind: \"cron\", source: text, ...(timezone ? { timezone } : {}) };\n crons.set(parsed, cron);\n if (neverFires(cron)) never.add(parsed);\n }\n cache.set(key, parsed);\n return parsed;\n}\n\n/**\n * Four hundred Gregorian years: 146,097 days, a whole number of weeks, after\n * which the calendar repeats date for date and weekday for weekday.\n */\nconst CYCLE_MS = 146_097 * 86_400_000;\n/** croner misreads a year below 100 as 1900 plus it, so earlier times are asked a cycle or more later. */\nconst CRONER_FIRST_MS = Date.UTC(400, 0, 1);\n/** croner finds no fire past the year 3000, so later times are asked a cycle or more earlier. */\nconst CRONER_LAST_MS = Date.UTC(2800, 0, 1);\n\n/**\n * The next `n` fires of a cron strictly after `from`, which lies within the\n * years 1 to 9999, dropping any after 9999. A time croner cannot answer for\n * is moved by whole 400-year cycles into the years it can, and its fires\n * moved back: a time before 400 goes forward, into the same local mean time\n * every zone kept then, and one from 2800 goes back, to where the zone's\n * present rules already hold.\n */\nfunction runsAfter(cron: Cron, n: number, from: number): number[] {\n let shift = 0;\n if (from < CRONER_FIRST_MS) shift = Math.ceil((CRONER_FIRST_MS - from) / CYCLE_MS) * CYCLE_MS;\n else if (from >= CRONER_LAST_MS) shift = -(Math.floor((from - CRONER_LAST_MS) / CYCLE_MS) + 1) * CYCLE_MS;\n const out: number[] = [];\n for (const date of cron.nextRuns(n, new Date(from + shift))) {\n const t = date.getTime() - shift;\n if (t > LAST_DATE_MS) break;\n out.push(t);\n }\n return out;\n}\n\n/**\n * A stored time as a cron's fires are counted from it. A start read from a\n * foreign or damaged row can be any number: one before the year 1 counts\n * from just before its first millisecond, so the first fire of the year 1 is\n * the next one, and one at or after the last millisecond of 9999 has no\n * fire after it at all (null). No fire is ever after 9999.\n */\nfunction countFrom(from: number): number | null {\n if (from >= LAST_DATE_MS) return null;\n return from >= FIRST_DATE_MS ? from : FIRST_DATE_MS - 1;\n}\n\n/**\n * The first fire strictly after `from`, or null when the cron never fires\n * again. On the night clocks spring forward every slot the pattern names\n * still fires: one whose local time the jump skips is moved forward by the\n * gap's length (see springGap and gapFireAfter), so the fires stay strictly\n * ascending whichever instant they are counted from.\n */\nfunction fireAfter(parsed: ParsedSchedule, from: number): number | null {\n const found = croneFireAfter(parsed, from);\n const start = countFrom(from);\n if (start === null) return found;\n const moved = gapFireAfter(parsed, start);\n return moved !== null && (found === null || moved < found) ? moved : found;\n}\n\n/**\n * The first fire strictly after `from` as croner counts it, or null when\n * the cron never fires again. croner answers with times in the past when\n * asked from inside the hour that repeats when clocks go back, so its\n * answers are filtered, and a stretch of nothing but past times is stepped\n * over an hour at a time. Asked from inside a spring-forward gap it skips\n * the slots moved out of it, which fireAfter adds back.\n */\nfunction croneFireAfter(parsed: ParsedSchedule, from: number): number | null {\n const cron = crons.get(parsed);\n if (!cron) throw new Error(`schedule \"${parsed.source}\" was not made by parseSchedule`);\n if (never.has(parsed)) return null;\n const start = countFrom(from);\n if (start === null) return null;\n let probe = start;\n for (let attempt = 0; attempt < 4; attempt++) {\n const runs = runsAfter(cron, 8, probe);\n if (runs.length === 0) return null;\n const found = runs.find((t) => t > start);\n if (found !== undefined) return found;\n probe += 3_600_000;\n }\n return null;\n}\n\n/**\n * The window a spring-forward jump moves skipped slots into, when `at` lies\n * in one: from the jump (`jumpAt`, the first instant on the later offset)\n * for the gap's length (`gapMs`, the later offset less the earlier one, so\n * 30 minutes on Lord Howe Island and an hour in most zones). `beforeMs` is\n * the earlier offset. Null when `at` is not within a gap's length after a\n * jump in the three hours before it.\n */\nexport function springGap(timezone: string | undefined, at: number): { jumpAt: number; gapMs: number; beforeMs: number } | null {\n const jump = springJump(timezone, at);\n return jump && at < jump.jumpAt + jump.gapMs ? jump : null;\n}\n\n/** How far back a spring-forward jump is looked for: more than any gap a zone has had. */\nconst JUMP_LOOKBACK_MS = 3 * 3_600_000;\n\n/**\n * The spring-forward jump in the three hours up to `at`, found to the\n * minute: the first minute on the later offset. Null when the offset at\n * `at` is not ahead of the offset three hours before.\n */\nfunction springJump(timezone: string | undefined, at: number): { jumpAt: number; gapMs: number; beforeMs: number } | null {\n // Every zone kept its local mean time, with no clock change, in the year 1.\n if (at - JUMP_LOOKBACK_MS < FIRST_DATE_MS || at >= LAST_DATE_MS) return null;\n const after = utcOffset(at, timezone);\n const before = utcOffset(at - JUMP_LOOKBACK_MS, timezone);\n if (after <= before) return null;\n let lo = at - JUMP_LOOKBACK_MS;\n let hi = at;\n while (hi - lo > 60_000) {\n const mid = lo + Math.floor((hi - lo) / 2);\n if (utcOffset(mid, timezone) === after) hi = mid;\n else lo = mid;\n }\n return { jumpAt: Math.floor(hi / 60_000) * 60_000, gapMs: after - before, beforeMs: before };\n}\n\n/** The pattern read in UTC, which stands for wall-clock time in gapFireAfter. */\nconst wallCrons = new WeakMap<ParsedSchedule, Cron>();\n\nfunction wallCron(parsed: ParsedSchedule): Cron {\n let wall = wallCrons.get(parsed);\n if (!wall) {\n wall = new Cron(parsed.source, { timezone: \"UTC\" });\n wallCrons.set(parsed, wall);\n }\n return wall;\n}\n\n/**\n * The first slot moved out of a spring-forward gap strictly after `start`,\n * when `start` lies in that gap's window, else null. A slot whose local time\n * the jump skips fires at that local time read on the earlier offset, which\n * is the same as moving it forward by the gap's length: 01:20 on the night\n * London skips 01:00 to 02:00 fires at 02:20 BST (01:20Z). croner moves them\n * the same way when asked from before the jump, but not from inside it.\n */\nfunction gapFireAfter(parsed: ParsedSchedule, start: number): number | null {\n if (never.has(parsed)) return null;\n const gap = springGap(parsed.timezone, start);\n if (!gap) return null;\n const wall = wallCron(parsed);\n // Wall-clock time as if it were UTC: the slots the jump skips run from\n // jumpAt + beforeMs for gapMs.\n const [slot] = runsAfter(wall, 1, start + gap.beforeMs);\n if (slot === undefined || slot >= gap.jumpAt + gap.beforeMs + gap.gapMs) return null;\n return slot - gap.beforeMs;\n}\n\n/**\n * Every fire of a cron strictly after `from` and at or before `to`,\n * ascending, or null when there are more than `limit`: the fires nextFire\n * gives one after another. Asks croner for fires in batches, which is far\n * cheaper than one nextFire per fire, and drops any that do not move forward\n * (the hour that repeats when clocks go back, see croneFireAfter). Around a\n * spring-forward gap, where croner's batch can skip a moved slot or give\n * one out of order, it counts with fireAfter instead.\n */\nexport function firesBetween(parsed: ParsedSchedule, from: number, to: number, limit: number): number[] | null {\n const cron = crons.get(parsed);\n if (!cron) throw new Error(`schedule \"${parsed.source}\" was not made by parseSchedule`);\n if (never.has(parsed)) return [];\n const out: number[] = [];\n const start = countFrom(from);\n if (start === null) return out;\n let probe = start;\n let last = start;\n for (let guard = 0; guard < 1000; guard++) {\n if (springGap(parsed.timezone, last)) {\n // Counting from inside a gap's window: croner would skip its moved slots.\n const t = fireAfter(parsed, last);\n if (t === null || t > to) return out;\n out.push(t);\n last = probe = t;\n if (out.length > limit) return null;\n continue;\n }\n const batch = runsAfter(cron, Math.min(limit + 1 - out.length, 24), probe);\n if (batch.length === 0) return out;\n let stepped = false;\n for (const t of batch) {\n if (t <= last) continue;\n if (springGap(parsed.timezone, t)) {\n // The batch reached a gap's window, where its order is croner's:\n // the next fire is counted from the last one, and the rest with it.\n const next = fireAfter(parsed, last);\n if (next === null || next > to) return out;\n out.push(next);\n last = probe = next;\n if (out.length > limit) return null;\n stepped = true;\n break;\n }\n if (t > to) return out;\n out.push(t);\n last = t;\n if (out.length > limit) return null;\n }\n if (stepped) continue;\n const end = batch[batch.length - 1]!;\n probe = end > probe ? end : probe + 3_600_000;\n }\n return out;\n}\n\n/**\n * The next time the schedule fires strictly after `from`. For an interval,\n * counted from the last run's start when there is one (see intervalDue for\n * a run that outlasted its period).\n */\nexport function nextFire(parsed: ParsedSchedule, from: number, lastRunAt: number | null): number | null {\n if (parsed.kind === \"interval\") {\n const base = lastRunAt ?? from;\n return base + parsed.everyMs!;\n }\n return fireAfter(parsed, from);\n}\n\n/**\n * When an interval of `everyMs` is next due after a run: a period after it\n * started, or, when it finished (`finishedAt` not null) later than that, a\n * period after it finished. A run that outlasts its period is not followed\n * by a missed alert the moment it ends.\n */\nexport function intervalDue(everyMs: number, startedAt: number, finishedAt: number | null): number {\n const due = startedAt + everyMs;\n return finishedAt !== null && finishedAt > due ? finishedAt + everyMs : due;\n}\n\nexport interface Expectation {\n /** When the next run the schedule asks for is due. */\n dueAt: number;\n /** Missed once now passes this. */\n deadline: number;\n}\n\n/**\n * When the schedule next wants a run, given the last one. For a cron that is\n * the first fire the last run does not already cover; with no run yet, the\n * first fire at or after registration. For an interval it is the last run's\n * start (or registration) plus the interval, or its finish plus the interval\n * when it finished (`lastFinishedAt`, null while it runs) later than that\n * (intervalDue). Null for a cron that never fires again.\n *\n * Counting forward from the last run, rather than back from now, is what\n * lets a job whose period is shorter than its grace be missed at all, and it\n * works for a cron that fires once a year or less.\n */\nexport function expectation(\n parsed: ParsedSchedule,\n lastRunAt: number | null,\n registeredAt: number,\n graceMs: number,\n lastFinishedAt: number | null = null,\n): Expectation | null {\n let dueAt: number | null;\n if (parsed.kind === \"interval\") {\n dueAt = lastRunAt === null ? registeredAt + parsed.everyMs! : intervalDue(parsed.everyMs!, lastRunAt, lastFinishedAt);\n } else if (lastRunAt === null) {\n dueAt = fireAfter(parsed, registeredAt - 1);\n } else {\n dueAt = dueAfterRun(parsed, lastRunAt);\n }\n return dueAt === null ? null : { dueAt, deadline: dueAt + graceMs };\n}\n\n/**\n * The first fire that a run starting at `startedAt` does not cover. A start\n * before the year 1 covers none of them, so the first fire of the year 1 is\n * due; after 9999 there is none (see countFrom).\n */\nfunction dueAfterRun(parsed: ParsedSchedule, startedAt: number): number | null {\n // A fire at or before the start is covered by the run itself.\n let next = fireAfter(parsed, startedAt);\n // Bounded: a gap holds at most a few hours of moved slots.\n for (let guard = 0; next !== null && guard < 100_000; guard++) {\n const following = fireAfter(parsed, next);\n const covers = runCovers(startedAt, next, following) || inSpringForwardGap(parsed, startedAt, next);\n if (!covers) return next;\n next = following;\n }\n return next;\n}\n\n/**\n * Whether a run starting at `startedAt` covers the fire at `dueAt`. A minute\n * of slack before the tick absorbs schedulers that fire a touch early. When\n * the fire after `dueAt` is known, the slack is at most half the gap between\n * the two, so one run of an every-minute cron never covers two fires.\n */\nexport function runCovers(startedAt: number, dueAt: number, followingAt: number | null = null): boolean {\n const slack = followingAt === null ? EARLY_SLACK_MS : Math.min(EARLY_SLACK_MS, Math.floor((followingAt - dueAt) / 2));\n return startedAt >= dueAt - slack;\n}\n\n/**\n * On the night clocks spring forward, a slot whose local time does not exist\n * (02:30 when 02:00 jumps to 03:00) fires moved forward by the gap (03:30;\n * see gapFireAfter), while vixie cron runs every skipped job once, at the\n * jump itself (03:00). A run that starts at or after the jump (less a\n * minute of slack), and before such a moved fire, is taken to cover it, so\n * neither scheduler's run is reported as missed. Only a moved slot that is\n * not also a slot of its own on the later offset counts: a cron that fires\n * every 10 minutes moves 02:10 onto its own 03:10, which was not skipped.\n */\nfunction inSpringForwardGap(parsed: ParsedSchedule, startedAt: number, fireAt: number): boolean {\n const gap = springGap(parsed.timezone, fireAt);\n if (!gap || startedAt < gap.jumpAt - EARLY_SLACK_MS || startedAt >= fireAt) return false;\n const wall = wallCron(parsed);\n const fires = (at: number) => runsAfter(wall, 1, at - 1)[0] === at;\n return fires(fireAt + gap.beforeMs) && !fires(fireAt + gap.beforeMs + gap.gapMs);\n}\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\n\n/** Milliseconds the zone's wall clock is ahead of UTC at `at`. */\nfunction utcOffset(at: number, timezone: string | undefined): number {\n const key = timezone ?? \"\";\n let format = formatters.get(key);\n if (!format) {\n format = new Intl.DateTimeFormat(\"en-US\", {\n ...(timezone ? { timeZone: timezone } : {}),\n hourCycle: \"h23\",\n year: \"numeric\", month: \"numeric\", day: \"numeric\", hour: \"numeric\", minute: \"numeric\", second: \"numeric\",\n });\n formatters.set(key, format);\n }\n const parts: Record<string, number> = {};\n for (const part of format.formatToParts(new Date(at))) {\n if (part.type !== \"literal\") parts[part.type] = Number(part.value);\n }\n // Date.UTC would read a year below 100 as 1900 plus it; setUTCFullYear does not.\n const wall = new Date(0);\n wall.setUTCFullYear(parts.year!, parts.month! - 1, parts.day!);\n wall.setUTCHours(parts.hour!, parts.minute!, parts.second!);\n return wall.getTime() - Math.floor(at / 1000) * 1000;\n}\n","export function percentile(values: number[], p: number): number | null {\n if (values.length === 0) return null;\n const sorted = [...values].sort((a, b) => a - b);\n const index = Math.min(sorted.length - 1, Math.max(0, Math.ceil((p / 100) * sorted.length) - 1));\n return sorted[index]!;\n}\n\nexport function median(values: number[]): number | null {\n if (values.length === 0) return null;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n}\n","/**\n * Pure decisions about a job's health. Each function takes the current state\n * and returns the new state plus the alerts that should go out. Nothing here\n * touches a store or a network, which is what makes it testable.\n */\nimport { formatDuration } from \"./duration.js\";\nimport { parseDuration } from \"./duration.js\";\nimport { expectation, nextFire, parseSchedule } from \"./schedule.js\";\nimport { median, percentile } from \"./stats.js\";\nimport type {\n Alert,\n AlertDraft,\n BudgetBreach,\n Condition,\n HeldAlert,\n JobDefinition,\n JobHealth,\n JobState,\n JobSummary,\n Run,\n StoredJob,\n StoredJobDefinition,\n} from \"./types.js\";\n\nexport type { AlertDraft, BudgetBreach };\n\nexport interface Evaluation {\n state: JobState;\n alerts: AlertDraft[];\n}\n\nexport const DEFAULT_GRACE_MS = 10 * 60_000;\nexport const DEFAULT_TIMEOUT_MS = 60 * 60_000;\n/** Runs faster than this are never called slow, whatever the baseline says. */\nexport const SLOW_FLOOR_MS = 10_000;\n/** How many earlier runs a baseline needs before it is trusted. */\nexport const BASELINE_MIN_RUNS = 5;\n/** How many successful runs a baseline looks at, and how many runs a summary covers. */\nexport const BASELINE_WINDOW = 20;\n\n/** The longest duration written: the largest integer JavaScript holds exactly, which every port and store reads back unchanged. */\nexport const MAX_DURATION_MS = Number.MAX_SAFE_INTEGER;\n\n/**\n * How long a run took, from `startedAt` to `finishedAt`: 0 when it started\n * later, and never more than MAX_DURATION_MS. A foreign row's start near a\n * 64-bit limit must not make a duration no store can write.\n */\nexport function runDuration(startedAt: number, finishedAt: number): number {\n const ms = finishedAt - startedAt;\n return ms > 0 ? Math.min(ms, MAX_DURATION_MS) : 0;\n}\n\n/**\n * When a silence of `ms` from `now` ends: a whole millisecond, never past\n * MAX_DURATION_MS (2^53 - 1), however long the silence asked for. Every port\n * sharing the store reads it back unchanged, where a larger number could\n * wrap to a time long past and send alerts during the silence.\n */\nexport function silenceEnd(now: number, ms: number): number {\n return Math.min(now + Math.floor(Math.min(ms, MAX_DURATION_MS)), MAX_DURATION_MS);\n}\n\n/**\n * The version a stored state counts as for compareAndSetState: its\n * `version` when that is a whole number from 0 to MAX_DURATION_MS (2^53 - 1),\n * else 0, as when it is absent. The SQL stores read it the same way, so a\n * foreign row's `1.5`, `\"x\"`, or `-1` is written over by the next update\n * instead of refusing every compare-and-set of its job for good.\n */\nexport function stateVersion(state: Pick<JobState, \"version\"> | null | undefined): number {\n const version: unknown = state?.version;\n return typeof version === \"number\" && Number.isSafeInteger(version) && version >= 0 ? version + 0 : 0;\n}\n\n/**\n * The failures in a row a stored state counts as: its `consecutiveFailures`\n * when that is a whole number, held at MAX_DURATION_MS (2^53 - 1), and 0 when\n * it is negative or not a whole number. A foreign row's count past 2^53, or at\n * a 64-bit limit, stays at the top instead of losing precision or wrapping\n * negative, and a `1.5`, `\"3\"`, or `-1` counts as none.\n */\nexport function failureCount(state: Pick<JobState, \"consecutiveFailures\"> | null | undefined): number {\n const count: unknown = state?.consecutiveFailures;\n if (typeof count !== \"number\" || !Number.isInteger(count) || count <= 0) return 0;\n return Math.min(count, MAX_DURATION_MS);\n}\n\nexport function emptyState(job: string): JobState {\n return { job, open: {}, consecutiveFailures: 0, silencedUntil: null, lastAlertAt: null, pendingRecovery: [], undelivered: [] };\n}\n\n/** A JSON object: not null, not an array. */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * A stored state with every field present, or a fresh one. State written by\n * an older version lacks the newer fields. `sending` and `underFloor` are the\n * exceptions: each is there only while it holds something.\n *\n * Read leniently, since a foreign, hand-edited, or damaged row must affect\n * only its own job, and the next write puts it right: a state that is not\n * an object reads as none; `open` keeps only its entries whose value is a\n * number (anything but an object reads as {}); `silencedUntil` and\n * `lastAlertAt` that are not numbers read as null; `pendingRecovery` keeps\n * only its strings, and `undelivered` only its entries that are objects (a\n * list of neither shape reads as []), and `underFloor` and `pendingRuns`\n * only their strings (each absent when none). Unknown fields are kept as\n * written.\n */\nexport function normalizeState(state: JobState | null, job: string): JobState {\n if (!isObject(state)) return emptyState(job);\n const { sending, underFloor, pendingRuns, ...rest } = state;\n const open = isObject(state.open)\n ? Object.fromEntries(Object.entries(state.open).filter(([, at]) => typeof at === \"number\"))\n : {};\n const number = (value: unknown) => (typeof value === \"number\" ? value : null);\n const list = (value: unknown) => (Array.isArray(value) ? value : []);\n return {\n ...emptyState(job),\n ...rest,\n open,\n consecutiveFailures: failureCount(state),\n silencedUntil: number(state.silencedUntil),\n lastAlertAt: number(state.lastAlertAt),\n pendingRecovery: list(state.pendingRecovery).filter((c): c is Condition => typeof c === \"string\"),\n undelivered: list(state.undelivered).filter((alert): alert is Alert => isObject(alert)),\n ...(Array.isArray(sending) && sending.length > 0 ? { sending: [...sending] } : {}),\n ...(Array.isArray(underFloor) && underFloor.some((m) => typeof m === \"string\") ? { underFloor: underFloor.filter((m): m is string => typeof m === \"string\") } : {}),\n ...(Array.isArray(pendingRuns) && pendingRuns.some((id) => typeof id === \"string\") ? { pendingRuns: pendingRuns.filter((id): id is string => typeof id === \"string\") } : {}),\n };\n}\n\n// ---------------------------------------------------------------- delivery\n\n/** Alerts kept per job for retry, and per job being sent; past it the oldest go. */\nexport const MAX_UNDELIVERED = 20;\n\n/**\n * How long an alert in `sending` is left to the process sending it. Longer\n * than any send takes: at most three alerts go out together, each with 25\n * seconds of triage and 15 of channels.\n */\nexport const SEND_LEASE_MS = 5 * 60_000;\n\n/** Identifies an alert across retries, and in `sending`. */\nexport function alertKey(alert: Pick<Alert, \"type\" | \"at\" | \"run\">): string {\n return `${alert.type}|${alert.at}|${alert.run?.id ?? \"\"}`;\n}\n\n/** How much of a held alert's run error and output is kept: 2048 UTF-16 units of each. */\nexport const HELD_TEXT_CAP = 2048;\n\n/**\n * How far past HELD_TEXT_CAP a text may run and still be kept whole: longer\n * than any marker, so a text trimmed once (its kept part and its marker) is\n * never trimmed again, and the count in its marker stays true.\n */\nexport const HELD_TEXT_SLACK = 64;\n\n/**\n * A run as an alert held in a job's state keeps it (`sending` and\n * `undelivered`), so the state stays small however much a run logged. Its\n * error keeps its first HELD_TEXT_CAP units and its output its last, each\n * cut so as not to split a surrogate pair, with a line saying how many\n * units were left out: \"<head>\\n[N more characters trimmed]\" and\n * \"[N earlier characters trimmed]\\n<tail>\". A text of at most\n * HELD_TEXT_CAP + HELD_TEXT_SLACK units, or that is not a string, is kept\n * as it is, and so is every other field. The first send of an alert uses\n * the alert as composed; only a retry reads the held copy.\n */\nexport function heldRun(run: Run): Run {\n const error = typeof run.error === \"string\" && run.error.length > HELD_TEXT_CAP + HELD_TEXT_SLACK ? keepHead(run.error) : run.error;\n const output = typeof run.output === \"string\" && run.output.length > HELD_TEXT_CAP + HELD_TEXT_SLACK ? keepTail(run.output) : run.output;\n return error === run.error && output === run.output ? run : { ...run, error, output };\n}\n\n/** How much of a held alert's message is kept: its first 4096 UTF-16 units. */\nexport const HELD_MESSAGE_CAP = 4096;\n\nfunction keepHead(text: string, cap = HELD_TEXT_CAP): string {\n let end = cap;\n if (isHighSurrogate(text.charCodeAt(end - 1))) end -= 1;\n return `${text.slice(0, end)}\\n[${text.length - end} more characters trimmed]`;\n}\n\nfunction keepTail(text: string): string {\n let start = text.length - HELD_TEXT_CAP;\n if (isLowSurrogate(text.charCodeAt(start)) && isHighSurrogate(text.charCodeAt(start - 1))) start += 1;\n return `[${start} earlier characters trimmed]\\n${text.slice(start)}`;\n}\n\nfunction isHighSurrogate(code: number): boolean {\n return code >= 0xd800 && code <= 0xdbff;\n}\n\nfunction isLowSurrogate(code: number): boolean {\n return code >= 0xdc00 && code <= 0xdfff;\n}\n\n/**\n * An alert as it is held in state: its run trimmed (heldRun), and its\n * message, when longer than HELD_MESSAGE_CAP + HELD_TEXT_SLACK units, cut to\n * its first HELD_MESSAGE_CAP like a run's error (\"<head>\\n[N more characters\n * trimmed]\"). Everything else, the title included, as it is. The first send\n * uses the alert as composed.\n */\nexport function heldAlert<T extends HeldAlert>(alert: T): T {\n const run: unknown = alert.run;\n const trimmedRun = isObject(run) ? heldRun(run as unknown as Run) : run;\n const message: unknown = alert.message;\n const trimmedMessage = typeof message === \"string\" && message.length > HELD_MESSAGE_CAP + HELD_TEXT_SLACK ? keepHead(message, HELD_MESSAGE_CAP) : message;\n if (trimmedRun === run && trimmedMessage === message) return alert;\n return { ...alert, run: trimmedRun, message: trimmedMessage } as T;\n}\n\n/**\n * Each configured channel's key, in the order configured: its name, with\n * \"#2\", \"#3\", and so on for the second and later channels of the same name,\n * so two webhooks are \"webhook\" and \"webhook#2\". A key already given to an\n * earlier channel (a channel named \"webhook#2\" itself, say) is skipped for\n * the next number up, so every key is different. A held alert names the\n * channels that still owe it by these keys (HeldAlert.owed).\n */\nexport function channelKeys(names: readonly string[]): string[] {\n const seen = new Map<string, number>();\n const taken = new Set<string>();\n return names.map((name) => {\n let n = (seen.get(name) ?? 0) + 1;\n seen.set(name, n);\n let key = n === 1 ? name : `${name}#${n}`;\n while (taken.has(key)) key = `${name}#${++n}`;\n taken.add(key);\n return key;\n });\n}\n\n/**\n * The channels a held alert is still owed by, of those configured now\n * (`configured`, channelKeys order): those in its `owed` that are still\n * configured, or every configured one when it has no `owed` list (an alert\n * held by a release before per-channel delivery, or one never sent). An\n * entry of `owed` that is not a string is ignored. None left means the\n * alert is done.\n */\nexport function owedChannels(alert: HeldAlert, configured: readonly string[]): string[] {\n const owed: unknown = alert.owed;\n if (!Array.isArray(owed)) return [...configured];\n return configured.filter((key) => owed.includes(key));\n}\n\n/**\n * An alert after a send to the channels in `tried`, of which those in\n * `failed` refused it: null when none is left owing it, else the alert\n * with `owed` set to those that refused, in configured order.\n */\nexport function afterSend<T extends HeldAlert>(alert: T, tried: readonly string[], failed: readonly string[]): T | null {\n const owed = tried.filter((key) => failed.includes(key));\n return owed.length === 0 ? null : { ...alert, owed };\n}\n\n/** An alert without its `owed` list, as a channel is given it. */\nexport function withoutOwed(alert: HeldAlert): Alert {\n if (!(\"owed\" in alert)) return alert;\n const { owed: _owed, ...rest } = alert;\n return rest as Alert;\n}\n\n/** Keeps the newest `max` of `list`, and says how many went. */\nfunction newest<T>(list: T[], max: number): { kept: T[]; dropped: number } {\n return { kept: list.slice(-max), dropped: Math.max(0, list.length - max) };\n}\n\n/**\n * `alerts` added to the undelivered queue, each with its run trimmed\n * (heldAlert) and its `owed` list as given: one with the same key as a\n * queued alert replaces it where it stands, the rest go at the end, and only\n * the newest MAX_UNDELIVERED stay. `dropped` counts those let go.\n */\nexport function queueUndelivered(state: JobState, alerts: HeldAlert[]): { state: JobState; dropped: number } {\n const next = cloneState(state);\n const byKey = new Map(alerts.map((alert) => [alertKey(alert), heldAlert(alert)]));\n const queue = next.undelivered!.map((alert) => byKey.get(alertKey(alert)) ?? alert);\n const known = new Set(queue.map(alertKey));\n queue.push(...[...byKey.values()].filter((alert) => !known.has(alertKey(alert))));\n const { kept, dropped } = newest(queue, MAX_UNDELIVERED);\n next.undelivered = kept;\n return { state: next, dropped };\n}\n\n/**\n * The outbox. Alerts just composed are written with the state that opens\n * their condition, before any is sent, so a process that stops part way does\n * not lose them: into `sending`, each with its lease ending at `until`, when\n * this process sends them, or (deliver: \"check\") straight into the\n * undelivered queue for a check elsewhere. Either way the copy held has its\n * run trimmed (heldAlert) and no `owed` list, so every configured channel\n * owes it; the first send uses the alerts as composed. `dropped` counts\n * alerts let go past MAX_UNDELIVERED.\n */\nexport function holdAlerts(state: JobState, alerts: Alert[], until: number, deferred: boolean): { state: JobState; dropped: number } {\n if (alerts.length === 0) return { state, dropped: 0 };\n if (deferred) return queueUndelivered(state, alerts);\n const next = cloneState(state);\n const { kept, dropped } = newest([...(next.sending ?? []), ...alerts.map((alert) => ({ until, alert: heldAlert(alert) }))], MAX_UNDELIVERED);\n next.sending = kept;\n return { state: next, dropped };\n}\n\n/**\n * Alerts in `sending` whose lease ran out by `now`: the process sending them\n * stopped before it recorded how the send went. They go to the undelivered\n * queue, where the retry sends them (with triage, which is never stored with\n * them here) or drops them as stale, owed by the channels its `owed` names.\n * An entry that is not an object with an alert is dropped; one without a\n * numeric `until` counts as run out.\n */\nexport function releaseSending(state: JobState, now: number): { state: JobState; dropped: number } {\n const sending = state.sending ?? [];\n const lapsed = sending.filter((entry) => !(typeof entry?.until === \"number\" && entry.until > now));\n if (lapsed.length === 0) return { state, dropped: 0 };\n const held = sending.filter((entry) => !lapsed.includes(entry));\n return queueUndelivered(\n { ...state, sending: held },\n lapsed.filter((entry) => typeof entry?.alert === \"object\" && entry.alert !== null).map((entry) => entry.alert),\n );\n}\n\n/**\n * How a send went. Delivered alerts (no channel owes them any more) and\n * stale ones (`dropped`) leave the queue; failed ones (some channel still\n * owes them, named by their `owed`) replace their queued copy, so a triage\n * made on this attempt and the shrunken `owed` are kept, or join the queue.\n * Every one of them leaves `sending`. lastAlertAt moves to `now` when\n * `reached` (some channel accepted an alert on this attempt; by default,\n * when any was delivered). `dropped` in the result counts alerts let go\n * past MAX_UNDELIVERED.\n */\nexport function recordSent(\n state: JobState,\n delivered: HeldAlert[],\n failed: HeldAlert[],\n stale: HeldAlert[],\n now: number,\n reached: boolean = delivered.length > 0,\n): { state: JobState; dropped: number } {\n const next = cloneState(state);\n const done = new Set([...delivered, ...stale].map(alertKey));\n next.undelivered = next.undelivered!.filter((alert) => !done.has(alertKey(alert)));\n const sent = new Set([...delivered, ...failed, ...stale].map(alertKey));\n const held = (next.sending ?? []).filter((entry) => !(typeof entry?.alert === \"object\" && entry.alert !== null && sent.has(alertKey(entry.alert))));\n if (held.length > 0) next.sending = held;\n else delete next.sending;\n if (reached) next.lastAlertAt = now;\n return queueUndelivered(next, failed);\n}\n\n/**\n * A check's claim on the undelivered queue, written before it sends, so two\n * processes checking at once never retry the same alert: the queued alerts\n * that still describe the job move into `sending`, oldest first, each with\n * its lease ending at `until`, as many as `sending` has room for under\n * MAX_UNDELIVERED (the rest wait for the next check); stale ones\n * (staleAlert) leave the queue. While the job is silenced only recoveries\n * are claimed. The process whose write lands sends `claimed`.\n */\nexport function claimUndelivered(state: JobState, now: number, until: number): { state: JobState; claimed: HeldAlert[]; stale: HeldAlert[] } {\n const next = cloneState(state);\n const queue = next.undelivered!;\n const stale = queue.filter((alert) => staleAlert(alert, next));\n const silenced = isSilenced(next, now);\n const room = Math.max(0, MAX_UNDELIVERED - (next.sending ?? []).length);\n const claimed = queue.filter((alert) => !stale.includes(alert) && (!silenced || alert.type === \"recovered\")).slice(0, room);\n if (stale.length === 0 && claimed.length === 0) return { state, claimed, stale };\n next.undelivered = queue.filter((alert) => !stale.includes(alert) && !claimed.includes(alert));\n if (claimed.length > 0) next.sending = [...(next.sending ?? []), ...claimed.map((alert) => ({ until, alert }))];\n return { state: next, claimed, stale };\n}\n\n/** Runs held in `pendingRuns` per job; past it the oldest go. */\nexport const MAX_PENDING_RUNS = 100;\n\n/**\n * A run just started, held in `pendingRuns` until its finish is evaluated\n * (releaseRun), so a check can evaluate it if the process that finished it\n * stops before writing the evaluation. Written with onRunStart's state.\n * Only the newest MAX_PENDING_RUNS are kept.\n */\nexport function holdRun(state: JobState, runId: string): JobState {\n const next = cloneState(state);\n const held = (next.pendingRuns ?? []).filter((id) => id !== runId);\n held.push(runId);\n next.pendingRuns = held.slice(-MAX_PENDING_RUNS);\n return next;\n}\n\n/** A run taken out of `pendingRuns`, as its evaluation is written or once it is gone from the store. */\nexport function releaseRun(state: JobState, runId: string): JobState {\n const held = state.pendingRuns ?? [];\n if (!held.includes(runId)) return state;\n const next = cloneState(state);\n const left = held.filter((id) => id !== runId);\n if (left.length > 0) next.pendingRuns = left;\n else delete next.pendingRuns;\n return next;\n}\n\nfunction cloneState(state: JobState): JobState {\n return normalizeState(state, state.job);\n}\n\nfunction openCondition(state: JobState, condition: Condition, now: number): boolean {\n if (state.open[condition] !== undefined) return false;\n state.open[condition] = now;\n return true;\n}\n\n/**\n * Every open condition has alerted, so closing one owes a recovered message.\n * It is remembered until a successful run leaves nothing open and sends it.\n */\nfunction closeCondition(state: JobState, condition: Condition): boolean {\n if (state.open[condition] === undefined) return false;\n delete state.open[condition];\n const pending = (state.pendingRecovery ??= []);\n if (!pending.includes(condition)) pending.push(condition);\n return true;\n}\n\nexport function openConditions(state: JobState): Condition[] {\n return Object.keys(state.open) as Condition[];\n}\n\nexport function graceMs(def: Pick<JobDefinition, \"grace\">): number {\n return def.grace === undefined ? DEFAULT_GRACE_MS : parseDuration(def.grace, \"grace\");\n}\n\nexport function timeoutMs(def: Pick<JobDefinition, \"timeout\">): number {\n return def.timeout === undefined ? DEFAULT_TIMEOUT_MS : parseDuration(def.timeout, \"timeout\");\n}\n\n/** Slow threshold for a successful run, or null when there is nothing to compare against yet. */\nexport function slowThreshold(def: Pick<JobDefinition, \"maxDuration\">, history: Run[]): { thresholdMs: number; basis: string } | null {\n if (def.maxDuration !== undefined) {\n return { thresholdMs: parseDuration(def.maxDuration, \"maxDuration\"), basis: \"maxDuration\" };\n }\n const durations = history\n .filter((r) => r.status === \"ok\" && r.durationMs !== null)\n .slice(0, BASELINE_WINDOW)\n .map((r) => r.durationMs!);\n if (durations.length < BASELINE_MIN_RUNS) return null;\n const p95 = percentile(durations, 95)!;\n return { thresholdMs: Math.max(2 * p95, SLOW_FLOOR_MS), basis: `twice the p95 of the last ${durations.length} runs (${formatDuration(p95)})` };\n}\n\nexport function budgetBreaches(def: Pick<JobDefinition, \"budget\">, run: Run, history: Run[]): BudgetBreach[] {\n const breaches: BudgetBreach[] = [];\n for (const [metric, value] of Object.entries(run.metrics)) {\n const ceiling = def.budget?.[metric];\n if (ceiling !== undefined) {\n if (value > ceiling) breaches.push({ metric, value, limit: ceiling, basis: \"budget\" });\n continue;\n }\n const past = history\n .filter((r) => r.status === \"ok\" && typeof r.metrics[metric] === \"number\")\n .slice(0, BASELINE_WINDOW)\n .map((r) => r.metrics[metric]!);\n if (past.length < BASELINE_MIN_RUNS) continue;\n const usual = median(past)!;\n if (usual > 0 && value > 3 * usual) {\n breaches.push({ metric, value, limit: 3 * usual, basis: `three times the usual ${formatNumber(usual)}` });\n }\n }\n return breaches;\n}\n\n/**\n * The metrics of a successful run that fell below their floor. A metric\n * with a floor breaches when it reports less than that floor. One without\n * breaches when it reports 0 or less and either it did so on the job's last\n * successful run too (`previous`, the metrics under their floor then), or\n * the earlier successful runs that reported it (at least five, the newest\n * twenty) all reported more than 0. So a job that keeps writing nothing stays\n * under its floor however long it goes on, and a metric that is always 0\n * never alerts.\n */\nexport function floorBreaches(def: Pick<JobDefinition, \"floor\">, run: Run, history: Run[], previous: readonly string[] = []): BudgetBreach[] {\n const breaches: BudgetBreach[] = [];\n for (const [metric, value] of Object.entries(run.metrics)) {\n const floor = def.floor?.[metric];\n if (floor !== undefined) {\n if (value < floor) breaches.push({ metric, value, limit: floor, basis: \"floor\" });\n continue;\n }\n if (value > 0) continue;\n if (previous.includes(metric)) {\n breaches.push({ metric, value, limit: 0, basis: \"0 or less on the run before too\" });\n continue;\n }\n const past = history\n .filter((r) => r.status === \"ok\" && typeof r.metrics[metric] === \"number\")\n .slice(0, BASELINE_WINDOW)\n .map((r) => r.metrics[metric]!);\n if (past.length < BASELINE_MIN_RUNS || !past.every((v) => v > 0)) continue;\n const lowest = Math.min(...past);\n breaches.push({ metric, value, limit: lowest, basis: `the last ${past.length} runs all reported more than 0, the lowest ${formatNumber(lowest)}` });\n }\n return breaches;\n}\n\n/** Whether `history` (newest first) holds a full baseline window of successful runs. */\nexport function hasFullBaseline(history: Run[]): boolean {\n return history.filter((r) => r.status === \"ok\").length >= BASELINE_WINDOW;\n}\n\nexport function formatNumber(n: number): string {\n if (Number.isInteger(n)) return n.toLocaleString(\"en-US\");\n return n.toLocaleString(\"en-US\", { maximumFractionDigits: 4 });\n}\n\n/** When a run finished, or null while it runs (a run marked timeout has finished). */\nexport function finishedAtOf(run: Pick<Run, \"status\" | \"finishedAt\">): number | null {\n return run.status !== \"running\" && typeof run.finishedAt === \"number\" ? run.finishedAt : null;\n}\n\n/**\n * Whether `run` brings the schedule up to date at `now`, so missed may close\n * for it: judged with it as the job's last run, as onCheck judges, the run\n * the schedule wants next is not yet past its deadline. A run that started\n * before the fire missed opened for does not cover that fire, however late\n * it finishes, and neither does a run a source reports only once it is over\n * whose start was before it. Every run starting now covers it. A job with no\n * schedule, or one that no longer parses, has nothing due, so any run does.\n */\nexport function catchesUp(def: JobDefinition | StoredJobDefinition, run: Pick<Run, \"startedAt\" | \"status\" | \"finishedAt\">, now: number): boolean {\n if (!def.schedule) return true;\n try {\n const exp = expectation(parseSchedule(def.schedule, def.timezone), run.startedAt, run.startedAt, graceMs(def), finishedAtOf(run));\n return exp === null || now <= exp.deadline;\n } catch {\n return true;\n }\n}\n\n/**\n * Called when a run starts, or when a run a source reports is recorded.\n * Missed is about the absence of a run, so a run starting closes it without\n * an alert; the recovered message waits for a successful finish. It closes\n * only when the run catches the schedule up (catchesUp), which a run\n * starting now always does. Nothing else closes here. Stuck in particular\n * stays open: a run that has only started may hang as the last one did, and\n * closing stuck for it would open it, and alert, again at every timeout of\n * a job that hangs every time. Only a run that finishes ok closes stuck.\n */\nexport function onRunStart(def: JobDefinition | StoredJobDefinition, run: Pick<Run, \"startedAt\" | \"status\" | \"finishedAt\">, state: JobState, now: number): JobState {\n const next = cloneState(state);\n if (catchesUp(def, run, now)) closeCondition(next, \"missed\");\n return next;\n}\n\n/**\n * Called when a run finishes with status ok, failed, or timeout. `history` is\n * the job's earlier runs, newest first, not including this one. Missed\n * closes only when the run catches the schedule up (catchesUp): a run that\n * started before the fire missed opened for leaves it open.\n */\nexport function onRunFinish(\n def: JobDefinition | StoredJobDefinition,\n run: Run,\n state: JobState,\n history: Run[],\n now: number,\n): Evaluation {\n const next = cloneState(state);\n const alerts: AlertDraft[] = [];\n\n if (run.status === \"ok\") {\n next.consecutiveFailures = 0;\n if (catchesUp(def, run, now)) closeCondition(next, \"missed\");\n closeCondition(next, \"stuck\");\n closeCondition(next, \"failed\");\n\n const slow = slowThreshold(def, history);\n if (slow && run.durationMs !== null && run.durationMs > slow.thresholdMs) {\n if (openCondition(next, \"slow\", now)) {\n alerts.push({ type: \"slow\", run, details: { durationMs: run.durationMs, thresholdMs: slow.thresholdMs, basis: slow.basis } });\n }\n } else {\n closeCondition(next, \"slow\");\n }\n\n const breaches = budgetBreaches(def, run, history);\n if (breaches.length > 0) {\n if (openCondition(next, \"over_budget\", now)) {\n alerts.push({ type: \"over_budget\", run, details: { breaches } });\n }\n } else {\n closeCondition(next, \"over_budget\");\n }\n\n const short = floorBreaches(def, run, history, next.underFloor);\n if (short.length > 0) {\n next.underFloor = short.map((b) => b.metric);\n if (openCondition(next, \"under_floor\", now)) {\n alerts.push({ type: \"under_floor\", run, details: { breaches: short } });\n }\n } else {\n delete next.underFloor;\n closeCondition(next, \"under_floor\");\n }\n\n const pending = next.pendingRecovery ?? [];\n if (pending.length > 0 && openConditions(next).length === 0) {\n alerts.push({ type: \"recovered\", run, details: { after: [...pending] } });\n next.pendingRecovery = [];\n }\n return { state: next, alerts };\n }\n\n // failed or timeout\n // Held at the top: a count at the limit neither loses precision nor wraps below a threshold.\n next.consecutiveFailures = Math.min(next.consecutiveFailures + 1, MAX_DURATION_MS);\n if (catchesUp(def, run, now)) closeCondition(next, \"missed\");\n const threshold = Math.max(1, def.failuresBeforeAlert ?? 1);\n const condition = run.status === \"timeout\" ? \"stuck\" : \"failed\";\n if (next.consecutiveFailures >= threshold) {\n if (openCondition(next, condition, now)) {\n alerts.push({ type: condition, run, details: { consecutiveFailures: next.consecutiveFailures, threshold } });\n }\n }\n return { state: next, alerts };\n}\n\n/**\n * Called by check(). Decides whether the schedule has been missed: the run\n * the schedule wants next (see expectation()) has not started and its grace\n * has run out. `lastRun` is the most recent run of any status. A job with no\n * schedule is never missed, and one whose schedule was removed while missed\n * was open gets a recovered alert (reason \"unscheduled\") for missed alone.\n */\nexport function onCheck(\n def: StoredJobDefinition,\n stored: StoredJob,\n lastRun: Run | null,\n state: JobState,\n now: number,\n): Evaluation & { nextExpectedAt: number | null; dueAt: number | null } {\n const next = cloneState(state);\n const alerts: AlertDraft[] = [];\n if (!def.schedule) {\n const since = next.open.missed;\n if (since !== undefined) {\n // The schedule went away while missed was open (the job was declared\n // again without one, or a source retired it), so nothing is due any\n // more. Missed closes now with a recovery of its own; other open\n // conditions keep their own rules. Missed is taken out of the pending\n // recovery too, so the next successful run does not name it again.\n delete next.open.missed;\n next.pendingRecovery = (next.pendingRecovery ?? []).filter((c) => c !== \"missed\");\n alerts.push({ type: \"recovered\", run: lastRun, details: { after: [\"missed\"], reason: \"unscheduled\", since } });\n }\n return { state: next, alerts, nextExpectedAt: null, dueAt: null };\n }\n\n const parsed = parseSchedule(def.schedule, def.timezone);\n const grace = graceMs(def);\n const lastRunAt = lastRun?.startedAt ?? null;\n const exp = expectation(parsed, lastRunAt, stored.createdAt, grace, lastRun ? finishedAtOf(lastRun) : null);\n const nextExpectedAt = parsed.kind === \"interval\" ? exp!.dueAt : nextFire(parsed, now, null);\n if (!exp) return { state: next, alerts, nextExpectedAt, dueAt: null };\n\n // An interval's next run is due a period after the last one started, or\n // after it finished when it outlasted the period (intervalDue). If that run\n // is still going, the job is busy, not late; stuck covers one that never ends.\n if (parsed.kind === \"interval\" && lastRun?.status === \"running\") {\n return { state: next, alerts, nextExpectedAt, dueAt: exp.dueAt };\n }\n\n if (now > exp.deadline) {\n if (openCondition(next, \"missed\", now)) {\n alerts.push({ type: \"missed\", run: lastRun, details: { dueAt: exp.dueAt, deadline: exp.deadline, graceMs: grace, lastRunAt } });\n }\n } else {\n // A run has started since it opened, or the grace was widened.\n closeCondition(next, \"missed\");\n }\n return { state: next, alerts, nextExpectedAt, dueAt: exp.dueAt };\n}\n\n/** Whether a running run has gone on longer than the job's timeout. */\nexport function isStuck(def: Pick<JobDefinition, \"timeout\">, run: Run, now: number): boolean {\n // A completed import keeps its finish while its evaluation intent is written.\n return run.status === \"running\" && run.finishedAt === null && now - run.startedAt > timeoutMs(def);\n}\n\n/**\n * Whether a finished import was left as its placeholder: recordRun() writes\n * one as running, with `finishedAt` set to when it was written, and the\n * finish that follows never landed (the importer stopped, or a store write\n * failed and it was not retried). A check closes one SEND_LEASE_MS after\n * it was written: as the failed run it was when the placeholder holds an\n * error (only a run that failed has one), else as it closes a stuck run.\n */\nexport function isStranded(run: Run, now: number): boolean {\n return run.status === \"running\" && run.finishedAt !== null && now - run.finishedAt > SEND_LEASE_MS;\n}\n\n/**\n * While a job is silenced nothing new is recorded as an incident: conditions\n * may close (so a job that recovered during the silence shows as healthy) but\n * none may open, so the first problem after the silence ends alerts normally.\n */\nexport function muteOpens(previous: JobState, next: JobState): JobState {\n const muted = cloneState(next);\n for (const condition of openConditions(muted)) {\n if (previous.open[condition] === undefined) delete muted.open[condition];\n }\n return muted;\n}\n\nexport function isSilenced(state: JobState, now: number): boolean {\n return state.silencedUntil !== null && state.silencedUntil > now;\n}\n\n/**\n * An evaluation as it is saved and sent: while the job was silenced when it\n * began, nothing opens and no new alert is sent, but a recovery is. A\n * condition can only close during a silence if it opened (and alerted)\n * before it, so its recovery closes an incident someone was told about.\n */\nexport function applySilence(previous: JobState, evaluation: Evaluation, now: number): Evaluation {\n if (!isSilenced(previous, now)) return evaluation;\n return { state: muteOpens(previous, evaluation.state), alerts: evaluation.alerts.filter((alert) => alert.type === \"recovered\") };\n}\n\n/**\n * Whether an alert waiting to be retried no longer describes the job, so it\n * is dropped rather than sent late. An alert for a condition is stale once\n * that condition has closed, or has closed and opened again (it opened at a\n * time other than the alert's). A recovery is stale when any condition it\n * names is open again; while they all stay closed it is kept. From a\n * foreign or damaged row: an alert whose `at` is not a number, and a\n * recovery whose `details.after` is not a list of strings, are stale.\n */\nexport function staleAlert(alert: AlertDraft & { at: number }, state: JobState): boolean {\n if (alert.type === \"recovered\") {\n // One whose details say nothing of what it recovers from (a foreign or damaged row's) cannot be judged, and goes.\n const after: unknown = isObject(alert.details) ? (alert.details as { after?: unknown }).after : undefined;\n if (!Array.isArray(after)) return true;\n return after.some((condition) => typeof condition !== \"string\" || state.open[condition as Condition] !== undefined);\n }\n // One with no time (a foreign or damaged row's) cannot match an open condition.\n return typeof alert.at !== \"number\" || state.open[alert.type] !== alert.at;\n}\n\n/** How a job looks at a glance. Silence wins, then stuck, failing, and late. */\nexport function jobHealth(def: Pick<JobDefinition, \"timeout\">, lastRun: Run | null, state: JobState, now: number): JobHealth {\n const open = openConditions(state);\n if (isSilenced(state, now)) return \"silenced\";\n if (open.includes(\"stuck\") || (lastRun && isStuck(def, lastRun, now))) return \"stuck\";\n if (open.includes(\"failed\") || lastRun?.status === \"failed\" || lastRun?.status === \"timeout\") return \"failing\";\n if (open.includes(\"missed\")) return \"late\";\n if (!lastRun) return \"never_ran\";\n return \"healthy\";\n}\n\n/**\n * A job's summary from its most recent runs (newest first; the first\n * BASELINE_WINDOW are used) and its state. Stats cover runs of any status;\n * the percentiles are over the successful ones among them.\n */\nexport function summarize(stored: StoredJob, recent: Run[], state: JobState, nextExpectedAt: number | null, now: number): JobSummary {\n return summary(stored, recent, state, nextExpectedAt, (lastRun) => jobHealth(stored.definition, lastRun, state, now));\n}\n\n/**\n * The summary of a job that could not be evaluated, say because its stored\n * schedule no longer parses. It reads nothing from the definition. The job\n * shows as failing (or silenced, while it is), since it needs a look, and\n * nothing is known about when it is next due.\n */\nexport function unevaluableSummary(stored: StoredJob, recent: Run[], state: JobState, now: number): JobSummary {\n return summary(stored, recent, state, null, () => (isSilenced(state, now) ? \"silenced\" : \"failing\"));\n}\n\nfunction summary(stored: StoredJob, recent: Run[], state: JobState, nextExpectedAt: number | null, health: (lastRun: Run | null) => JobHealth): JobSummary {\n const window = recent.slice(0, BASELINE_WINDOW);\n const lastRun = window[0] ?? null;\n const finished = window.filter((r) => r.status !== \"running\");\n const okDurations = window.filter((r) => r.status === \"ok\" && r.durationMs !== null).map((r) => r.durationMs!);\n return {\n name: stored.name,\n definition: stored.definition,\n health: health(lastRun),\n open: openConditions(state),\n lastRun,\n nextExpectedAt,\n consecutiveFailures: state.consecutiveFailures,\n silencedUntil: state.silencedUntil,\n stats: {\n runs: finished.length,\n okRate: finished.length === 0 ? 1 : finished.filter((r) => r.status === \"ok\").length / finished.length,\n p50Ms: percentile(okDurations, 50),\n p95Ms: percentile(okDurations, 95),\n },\n };\n}\n","import { beyondDates, formatDuration, formatRelative, isoTime } from \"./duration.js\";\nimport { formatNumber } from \"./evaluate.js\";\nimport type { Alert, AlertDraft, StoredJobDefinition } from \"./types.js\";\n\nfunction when(at: number | null | undefined, now: number): string {\n if (at === null || at === undefined) return \"never\";\n const iso = isoTime(at);\n if (iso === null) return beyondDates(at);\n return `${iso.replace(\"T\", \" \").slice(0, 19)} UTC (${formatRelative(at, now)})`;\n}\n\nfunction firstLines(text: string | null, n: number): string {\n if (!text) return \"\";\n return text.split(\"\\n\").slice(0, n).join(\"\\n\");\n}\n\nfunction tail(text: string | null, n: number): string {\n if (!text) return \"\";\n const lines = text.trimEnd().split(\"\\n\");\n return lines.slice(Math.max(0, lines.length - n)).join(\"\\n\");\n}\n\n/**\n * Words joined as an English list, with a serial comma from three on:\n * \"a\", \"a and b\", \"a, b, and c\". Every port joins the same way.\n */\nexport function andList(words: readonly string[]): string {\n if (words.length <= 2) return words.join(\" and \");\n return `${words.slice(0, -1).join(\", \")}, and ${words[words.length - 1]}`;\n}\n\n/** \"Error: x\" for a bare message, but not \"Error: TypeError: x\" for one that already names itself. */\nfunction errorLine(error: string): string {\n const text = firstLines(error, 4);\n return /^[A-Za-z_$][\\w$]*: /.test(text) ? text : `Error: ${text}`;\n}\n\n/** Turns a draft into the title and message every channel shows. */\nexport function composeAlert(draft: AlertDraft, def: StoredJobDefinition, now: number): Alert {\n const name = def.name;\n const run = draft.run;\n let title: string;\n const lines: string[] = [];\n\n switch (draft.type) {\n case \"missed\": {\n const d = draft.details;\n title = `${name} missed its scheduled run`;\n lines.push(`Due ${when(d.dueAt, now)}, and no run had started by ${when(d.deadline, now)} (grace ${formatDuration(d.graceMs)}).`);\n lines.push(`Schedule: ${def.schedule}${def.timezone ? ` (${def.timezone})` : \"\"}.`);\n lines.push(`Last run: ${run ? `${run.status} ${when(run.startedAt, now)}` : \"never\"}.`);\n break;\n }\n case \"failed\": {\n title = `${name} failed`;\n const n = draft.details.consecutiveFailures;\n if (n > 1) lines.push(`${n} consecutive failures.`);\n if (run) {\n lines.push(`Started ${when(run.startedAt, now)}${run.durationMs !== null ? `, ran ${formatDuration(run.durationMs)}` : \"\"}.`);\n if (run.error) lines.push(errorLine(run.error));\n const out = tail(run.output, 8);\n if (out) lines.push(`Output (tail):\\n${out}`);\n }\n break;\n }\n case \"stuck\": {\n title = `${name} is stuck`;\n if (run) {\n lines.push(`Started ${when(run.startedAt, now)} and never reported finishing. Marked as timed out after ${formatDuration(run.durationMs ?? now - run.startedAt)}.`);\n const out = tail(run.output, 8);\n if (out) lines.push(`Output so far (tail):\\n${out}`);\n }\n lines.push(`If the process was killed mid-run (a serverless timeout, a deploy), this is what that looks like.`);\n break;\n }\n case \"slow\": {\n const d = draft.details;\n title = `${name} was slow`;\n lines.push(`Took ${formatDuration(d.durationMs)}; the limit is ${formatDuration(d.thresholdMs)} (${d.basis}).`);\n if (run) lines.push(`Started ${when(run.startedAt, now)}.`);\n break;\n }\n case \"over_budget\": {\n title = `${name} went over budget`;\n for (const b of draft.details.breaches) {\n lines.push(`${b.metric}: ${formatNumber(b.value)}, limit ${formatNumber(b.limit)} (${b.basis}).`);\n }\n if (run) lines.push(`Started ${when(run.startedAt, now)}.`);\n break;\n }\n case \"under_floor\": {\n title = `${name} fell short`;\n for (const b of draft.details.breaches) {\n lines.push(b.basis === \"floor\" ? `${b.metric}: ${formatNumber(b.value)}, below the floor of ${formatNumber(b.limit)}.` : `${b.metric}: ${formatNumber(b.value)} (${b.basis}).`);\n }\n if (run) lines.push(`Started ${when(run.startedAt, now)}.`);\n break;\n }\n case \"recovered\": {\n if (draft.details.reason === \"unscheduled\") {\n title = `${name} is no longer scheduled`;\n const since = draft.details.since;\n lines.push(`${since === undefined ? \"\" : `Missed since ${when(since, now)}. `}It has no schedule now, so nothing is due; the missed alert is closed.`);\n break;\n }\n title = `${name} recovered`;\n const after = andList(draft.details.after.map((c) => c.replace(\"_\", \" \")));\n lines.push(`A run ${run ? when(run.startedAt, now) : \"just now\"} succeeded${after ? ` after: ${after}` : \"\"}.`);\n if (run?.durationMs !== null && run?.durationMs !== undefined) lines.push(`Ran ${formatDuration(run.durationMs)}.`);\n break;\n }\n }\n\n return { ...draft, job: name, definition: def, title, message: lines.join(\"\\n\"), at: now };\n}\n","export function json(body: unknown, status = 200, headers: Record<string, string> = {}): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"content-type\": \"application/json; charset=utf-8\", \"cache-control\": \"no-store\", ...headers },\n });\n}\n\n/**\n * Compares what a request `sent` with the `secret` without stopping at the\n * first differing character, and in time that depends only on the length of\n * what was sent, so neither the secret's characters nor its length can be\n * timed. Every UTF-16 code unit of `sent` is compared, against the secret's\n * unit at the same place (repeating it past its end), and a length that\n * differs counts as a difference.\n */\nexport function constantTimeEqual(sent: string, secret: string): boolean {\n if (secret.length === 0) return sent.length === 0;\n let diff = sent.length ^ secret.length;\n for (let i = 0; i < sent.length; i++) diff |= sent.charCodeAt(i) ^ secret.charCodeAt(i % secret.length);\n return diff === 0;\n}\n\n/** The token of an `Authorization: Bearer <token>` header: the scheme in any case, then any whitespace. */\nexport function bearerToken(header: string | null): string | null {\n const match = header === null ? null : /^Bearer\\s+([\\s\\S]*)$/i.exec(header);\n return match ? match[1]! : null;\n}\n","/** Output is capped so a chatty job cannot fill the store. The tail is kept. */\nexport const OUTPUT_CAP = 16 * 1024;\n\n/**\n * NUL characters are removed first, since Postgres refuses them in TEXT and\n * JSONB and the whole run row would be lost. The cap then applies to what is\n * left.\n */\nexport function capOutput(text: string): string {\n const clean = stripNul(text);\n if (clean.length <= OUTPUT_CAP) return clean;\n return TRIMMED + clean.slice(clean.length - OUTPUT_CAP);\n}\n\nconst TRIMMED = \"[earlier output trimmed]\\n\";\n\n/**\n * How much text before the kept tail redaction reads, and never keeps: three\n * times the longest secret a default pattern can match (a PEM key's 16 KB body\n * with its header and footer, under OUTPUT_CAP + 1024), since a replacement\n * grows what it replaces at most threefold.\n */\nexport const REDACT_EDGE = 3 * (OUTPUT_CAP + 1024);\n\n/**\n * Output or an error as it is stored: redacted, then capped like capOutput,\n * so the cut cannot fall inside a secret and keep what follows its label.\n * Text of at most OUTPUT_CAP + REDACT_EDGE is redacted whole. Longer text is\n * cut to that many units from its end first, and after redacting, the first\n * REDACT_EDGE units are never kept: a secret whose label fell before that cut\n * is left out with them. NULs go before and after `redact`.\n */\nexport function redactAndCap(text: string, redact: (text: string) => string): string {\n const clean = stripNul(text);\n const from = clean.length - (OUTPUT_CAP + REDACT_EDGE);\n if (from <= 0) return capOutput(redact(clean));\n const redacted = stripNul(redact(clean.slice(from)));\n return TRIMMED + redacted.slice(Math.max(redacted.length - OUTPUT_CAP, REDACT_EDGE));\n}\n\n/** Removes every U+0000. */\nexport function stripNul(text: string): string {\n return text.includes(\"\\u0000\") ? text.replace(/\\u0000/g, \"\") : text;\n}\n\n/**\n * Removes every U+0000 from JSON text, keys and strings alike, by dropping\n * each \\u0000 escape (a NUL can appear in JSON no other way). Escapes are\n * read left to right in pairs, so an escaped backslash followed by \"u0000\"\n * is left as it is.\n */\nexport function stripJsonNul(json: string): string {\n return json.includes(\"\\\\u0000\") ? json.replace(/\\\\(u0000|[\\s\\S])/g, (escape, next: string) => (next === \"u0000\" ? \"\" : escape)) : json;\n}\n\n/** \"Name: message\" and the first five stack frames, capped like output. */\nexport function errorMessage(error: unknown): string {\n return capOutput(describeError(error));\n}\n\n/** \"Name: message\" and the first five stack frames, not capped: see redactAndCap. */\nexport function describeError(error: unknown): string {\n if (error instanceof Error) {\n // The stack repeats the header (over several lines when the message has\n // newlines), so take only its frames.\n const frames = (error.stack ?? \"\").split(\"\\n\").filter((line) => /^\\s+at /.test(line)).slice(0, 5);\n return `${error.name}: ${error.message}${frames.length ? `\\n${frames.join(\"\\n\")}` : \"\"}`;\n }\n if (typeof error === \"string\") return error;\n try {\n return JSON.stringify(error) ?? String(error);\n } catch {\n return String(error);\n }\n}\n\nconst REDACTED = \"[redacted]\";\n\n// Bounded quantifiers throughout, so a long line cannot make these backtrack.\n// They apply in this order, each to the text the ones before it left.\nconst SECRET_PATTERNS: [RegExp, string | ((match: string, ...groups: string[]) => string)][] = [\n // A PEM private key, header to footer. Without a footer (the output was\n // trimmed) it runs to the end of the base64 body. A \"-\" that starts five\n // dashes ends the body, so the footer is never swallowed into it.\n [\n /-----BEGIN (?:[A-Z0-9]{1,20} ){0,3}PRIVATE KEY-----(?:[A-Za-z0-9+/=\\s,:]|-(?!----)){0,16384}(?:-----END (?:[A-Z0-9]{1,20} ){0,3}PRIVATE KEY-----)?/g,\n REDACTED,\n ],\n // password=..., API_KEY: ..., \"client_secret\": \"...\", TOKEN='...', token=...,\n // :password=>\"...\" (but not max_tokens: 800). A quoted value is blanked to\n // its closing quote, spaces and all, and keeps its quotes.\n [\n /\\b([A-Za-z0-9_-]{0,40}(?:secret|token|passw(?:or)?d|pwd|api[_-]?key|access[_-]?key|private[_-]?key|credential)[A-Za-z0-9_-]{0,40}(?<![Tt][Oo][Kk][Ee][Nn][Ss])\"?\\s{0,3}(?:=>|[=:])\\s{0,3})(?:(\")[^\"\\n]{1,4096}\"|(')[^'\\n]{1,4096}'|[\"']?[^\\s\"',;&]{1,4096})/gi,\n (_match, name: string, double?: string, single?: string) => {\n const quote = double ?? single ?? \"\";\n return `${name}${quote}${REDACTED}${quote}`;\n },\n ],\n // Authorization: Basic <base64> and Authorization: Token <token>, also as a JSON or hash entry.\n [/\\b((?:proxy-)?authorization[\"']?\\s{0,3}(?:=>|[=:])\\s{0,3}[\"']?\\s{0,3}(?:basic|token)\\s{1,3})[A-Za-z0-9._~+/=:-]{1,4096}/gi, `$1${REDACTED}`],\n // Credentials inside a URL: postgres://user:password@host. The password\n // runs to the last \"@\" before a \"/\" or a space, so one that contains \"@\"\n // is blanked whole.\n [/(\\b[a-z][a-z0-9+.-]{0,30}:\\/\\/[^\\s/:@]{0,256}:)[^\\s/]{1,256}@/gi, `$1${REDACTED}@`],\n // Authorization: Bearer <token>\n [/\\b(Bearer\\s{1,3})[A-Za-z0-9._~+/=-]{8,4096}/g, `$1${REDACTED}`],\n // A bare JWT: three base64url segments, the first starting eyJ.\n [/\\beyJ[A-Za-z0-9_-]{4,4096}\\.[A-Za-z0-9_-]{4,4096}\\.[A-Za-z0-9_-]{0,4096}/g, REDACTED],\n // Incoming webhook URLs carry their secret in the path.\n [/(\\bhooks\\.slack\\.com\\/(?:services|workflows|triggers)\\/)[A-Za-z0-9/_-]{1,255}/gi, `$1${REDACTED}`],\n [/(\\bdiscord(?:app)?\\.com\\/api\\/(?:v\\d{1,2}\\/)?webhooks\\/)[A-Za-z0-9/_-]{1,255}/gi, `$1${REDACTED}`],\n // Well-known token shapes: AWS, GitHub, Slack, Stripe, Anthropic, OpenAI, and Google style keys.\n [/\\b(?:AKIA|ASIA)[0-9A-Z]{16}\\b/g, REDACTED],\n [/\\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{20,255})\\b/g, REDACTED],\n [/\\bxox[abposr]-[A-Za-z0-9-]{10,255}/g, REDACTED],\n [/\\b[rsp]k_(?:live|test)_[A-Za-z0-9]{10,255}\\b/g, REDACTED],\n [/\\bwhsec_[A-Za-z0-9+/=]{16,255}/g, REDACTED],\n [/\\bsk-[A-Za-z0-9_-]{20,255}/g, REDACTED],\n [/\\bAIza[0-9A-Za-z_-]{35}(?![0-9A-Za-z_-])/g, REDACTED],\n];\n\n/**\n * The default `redact`: blanks values that look like secrets (key=value pairs\n * with secret-ish names, Authorization headers, URL credentials, bearer\n * tokens, JWTs, PEM private keys, webhook URLs, and well-known token formats)\n * before output or an error is stored, shown, or sent anywhere.\n */\nexport function redactSecrets(text: string): string {\n let out = text;\n for (const [pattern, replacement] of SECRET_PATTERNS) out = out.replace(pattern, replacement as string);\n return out;\n}\n","import { OUTPUT_CAP, REDACT_EDGE, stripNul } from \"./output.js\";\nimport type { Run } from \"./types.js\";\n\n/** What a job function receives. */\nexport interface JobContext {\n readonly name: string;\n readonly runId: string;\n readonly startedAt: number;\n /** Aborts when the job's timeout elapses. Honour it if the work can stop. */\n readonly signal: AbortSignal;\n /** Append a line of output. Kept with the run, capped at 16 KB, shown in alerts and the dashboard. */\n log(...parts: unknown[]): void;\n /** Report a number for this run: tokens, cost, rows, anything. Watched against budgets and baselines. */\n metric(name: string, value: number): void;\n metrics(values: Record<string, number>): void;\n}\n\nexport interface RunRecorder {\n context: JobContext;\n /**\n * The lines still held in a bounded redaction window, joined and not\n * yet capped: the client redacts them first, then caps them (redactAndCap).\n */\n output(): string | null;\n /**\n * What an expect rule is checked against: everything logged, or when that\n * ran long, the first 16 KB and the last 16 KB. The stored output keeps only\n * the tail, so a \"done\" line printed early would otherwise be lost.\n */\n expectText(): string | null;\n metrics(): Record<string, number>;\n abort(): void;\n}\n\nfunction stringify(part: unknown): string {\n if (typeof part === \"string\") return part;\n if (part instanceof Error) return `${part.name}: ${part.message}`;\n try {\n return JSON.stringify(part);\n } catch {\n return String(part);\n }\n}\n\n/**\n * Lines kept newest last, each counted with the newline that joins it,\n * dropped from the front by moving a start index (no shift() per line).\n */\nclass LineWindow {\n private items: string[] = [];\n private start = 0;\n private size = 0;\n\n get count(): number {\n return this.items.length - this.start;\n }\n\n push(line: string): void {\n this.items.push(line);\n this.size += line.length + 1;\n }\n\n /** Drops the oldest lines while over `max`, always keeping the newest. */\n keepAtMost(max: number): void {\n while (this.size > max && this.count > 1) this.drop();\n }\n\n /** Drops the oldest lines only while what is left still holds `min`. */\n keepAtLeast(min: number): void {\n while (this.count > 1 && this.size - (this.items[this.start]!.length + 1) > min) this.drop();\n }\n\n join(): string {\n return this.items.slice(this.start).join(\"\\n\");\n }\n\n private drop(): void {\n this.size -= this.items[this.start]!.length + 1;\n this.start += 1;\n // Compact now and then, so the array does not grow with every line logged.\n if (this.start >= 1024 && this.start * 2 >= this.items.length) {\n this.items = this.items.slice(this.start);\n this.start = 0;\n }\n }\n}\n\nexport function createRecorder(run: Run): RunRecorder {\n // One byte past redactAndCap's look-behind ensures a cut inside a secret is discarded there.\n const window = OUTPUT_CAP + REDACT_EDGE + 2;\n const copy = (text: string): string => JSON.parse(JSON.stringify(text)) as string;\n const lines = new LineWindow();\n const head: string[] = [];\n let headSize = 0;\n let whole: string | null = \"\";\n // The raw lines behind expectText()'s tail, joined only when it is read.\n const raw = new LineWindow();\n let logged = false;\n const metrics: Record<string, number> = {};\n const controller = new AbortController();\n\n const context: JobContext = {\n name: run.job,\n runId: run.id,\n startedAt: run.startedAt,\n signal: controller.signal,\n log(...parts) {\n let line = parts.map(stringify).join(\" \");\n const separator = logged ? \"\\n\" : \"\";\n logged = true;\n if (whole !== null) whole = whole.length + separator.length + line.length <= 2 * OUTPUT_CAP ? whole + separator + line : null;\n raw.push(copy(line.slice(-OUTPUT_CAP)));\n raw.keepAtLeast(OUTPUT_CAP);\n if (headSize < OUTPUT_CAP) {\n head.push(copy(line.slice(0, OUTPUT_CAP - headSize)));\n headSize += line.length + 1;\n }\n // Expectations keep the raw prefix and tail; storage removes NUL before cutting so it cannot shrink the redaction margin.\n line = stripNul(line);\n if (line.length >= window) {\n line = copy(line.slice(-(window - 1)));\n }\n lines.push(line);\n // Drop from the front once well past the cap; redactAndCap trims exactly at the end.\n lines.keepAtMost(window);\n },\n metric(name, value) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`metric \"${name}\" must be a finite number`);\n }\n metrics[name] = value;\n },\n metrics(values) {\n for (const [k, v] of Object.entries(values)) context.metric(k, v);\n },\n };\n\n return {\n context,\n output: () => (lines.count === 0 ? null : lines.join()),\n expectText: () => {\n if (!logged) return null;\n return whole ?? head.join(\"\\n\").slice(0, OUTPUT_CAP) + \"\\n\" + raw.join().slice(-OUTPUT_CAP);\n },\n metrics: () => ({ ...metrics }),\n abort: () => controller.abort(),\n };\n}\n","import type { JobDefinition, StoredJob, StoredJobDefinition } from \"./types.js\";\n\n/** A definition as a store can hold it: `expect` becomes a description. */\nexport function toStored(def: JobDefinition): StoredJobDefinition {\n const { expect, ...rest } = def;\n const stored: StoredJobDefinition = { ...rest };\n if (expect !== undefined) {\n stored.expect =\n typeof expect === \"string\" ? `contains ${JSON.stringify(expect)}`\n : expect instanceof RegExp ? `matches ${expect.toString()}`\n : \"custom function\";\n }\n return stored;\n}\n\nexport function checkExpectation(expect: JobDefinition[\"expect\"], output: string | null): string | null {\n if (expect === undefined) return null;\n const text = output ?? \"\";\n if (typeof expect === \"string\") {\n return text.includes(expect) ? null : `Output did not contain ${JSON.stringify(expect)}`;\n }\n if (expect instanceof RegExp) {\n expect.lastIndex = 0; // a /g or /y pattern would otherwise resume where the last run stopped\n return expect.test(text) ? null : `Output did not match ${expect.toString()}`;\n }\n let ok = false;\n try {\n ok = expect(text);\n } catch (error) {\n return `Output check threw: ${(error as Error).message}`;\n }\n return ok ? null : \"Output did not pass the expect() check\";\n}\n\n/**\n * A stored job as the client reads it, so a foreign, hand-edited, or damaged\n * row affects only its own job. A definition that is not a JSON object (a\n * SQL store reads text that does not parse as null) becomes `{ name }` and\n * `readable` is false: the client reports the job and shows it as failing,\n * without evaluating it. `tags` is kept only when it is a list of strings.\n * Every other field is kept as stored.\n */\nexport function readStoredJob(stored: StoredJob): { job: StoredJob; readable: boolean } {\n const definition: unknown = stored.definition;\n if (typeof definition !== \"object\" || definition === null || Array.isArray(definition)) {\n return { job: { ...stored, definition: { name: stored.name } }, readable: false };\n }\n const read = { ...(definition as StoredJobDefinition) };\n if (\"tags\" in read && !(Array.isArray(read.tags) && read.tags.every((tag) => typeof tag === \"string\"))) delete read.tags;\n return { job: { ...stored, definition: read }, readable: true };\n}\n","/** Escapes text for HTML, attribute values included. Every string a page shows goes through this. */\nexport function escapeHtml(value: unknown): string {\n return String(value ?? \"\")\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/**\n * Escapes a job name shown as text, with a line break allowed after each run\n * of `_`, `:`, `.`, `/`, or `-`, so a long hook or class name wraps at its\n * separators rather than mid-word. Only for text: never an attribute, a URL,\n * or a title.\n */\nexport function escapeName(value: unknown): string {\n return escapeHtml(value).replace(/([_:./-]+)(?=[^_:./-])/g, \"$1<wbr>\");\n}\n","// Generated by scripts/make-dashboard-icons.mjs. Do not edit; change the drawing there and run it.\n\n/** The favicon: the clock on a dark rounded square. */\nexport const ICON_SVG = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 40 40\\\"><rect width=\\\"40\\\" height=\\\"40\\\" rx=\\\"10\\\" fill=\\\"#141417\\\"/><rect x=\\\"0.5\\\" y=\\\"0.5\\\" width=\\\"39\\\" height=\\\"39\\\" rx=\\\"9.5\\\" fill=\\\"none\\\" stroke=\\\"#2a2a2f\\\"/><circle cx=\\\"20\\\" cy=\\\"20\\\" r=\\\"10.5\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\"/><path d=\\\"M20 12.5V20h6\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"/></svg>\";\n/** The same square to every edge, for masks. */\nexport const MASKABLE_SVG = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 40 40\\\"><rect width=\\\"40\\\" height=\\\"40\\\" fill=\\\"#141417\\\"/><circle cx=\\\"20\\\" cy=\\\"20\\\" r=\\\"10.5\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\"/><path d=\\\"M20 12.5V20h6\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"/></svg>\";\n/** PNGs, base64: 192 and 512 for the manifest, a maskable 512, and iOS's 180 home screen icon. */\nexport const ICON_192_PNG = \"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\";\nexport const ICON_512_PNG = \"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\";\nexport const MASKABLE_512_PNG = \"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\";\nexport const APPLE_TOUCH_ICON_PNG = \"iVBORw0KGgoAAAANSUhEUgAAALQAAAC0CAMAAAAKE/YAAAAAM1BMVEUUFBciIiU+PkBaWlt2dnaRkZKfn5+tra27u7tMTE7X19bz8/FoaGnl5eMwMDKEhITJycgc8OlvAAAFSklEQVR42u2caZPjKAyGOZ042XXm///LSVXaB9fW7vYYfGTawiJO1+j91IcNj4UQAoMZI5FIJBKJRCKRSCQSiUQikUgkEolEIpG+izh+iZ9ijIVPvTd0baRclhic0+17QvOrqfzT/4pBP8K7QUulvrzGWvdG0A0328oJOtwxLISA7IXf+OzcB/ZXfzw01wJUhgwsHO0eqvbge0Rrj4SuTybrPt23h7nHLayZWVh3Cp0IIfRa9UyteIPnl/4YSzfD8on1w1/n8aF5iOuyQVx1PwBaXuZmdvbyDKT5UPMnFB/u5dDqNGPo3O+7pJDn2QW9fTG0rmYBwc1dt2bzzsblLNQM5qXQlZ6a/eeij3rPhFj+eWpcM7wwekyZzbJPaR4YC57NPaavJ71XcvcyS0+YQ7+sWNSfP7RLP5cnvtfWcq8/m96v5Xy/AvLyn8GmlUrmXwI9iRv9al/6+xfJeW0McUGluUhGHgB/zJS5y4patkt+Ocny0M0ludlnjg/OJ/VeGnBbQ29Ien94eJapVpzH7gh/cqilbzIZA7OZGfNdrFneykLXiQ/bHcyM+bSkuih00gm7nasCbbdaLD60igGu3z2zdjEcGlUOmsdmNJbtlo0mqHkxaDV6cTAMQWbMDL0qBd3E4btHWS0K0UGqphB07HkGaanImZXCUaETQ58Zks5ZpgZAx76i7ljQd5WTJAOgx6ZcTkjy9VMsiseEjgvPqGvNbZxBFoAeG1I4TGgn4LnbZmg+ltmhvo4I42iuODr0NdqGocqtVIEFbWICjwsd02mDDj0GacuQZRdVYEHHtaELNvRYoK+Rocem03ds6LuG+sdW6DGIPhi6HtD1DDC0x4f2haA5B8el7boua8GBHq+/40PfBTBpgkIbVkCmMLQvAe2B0AoIXQOXZp+swwzt6mpKIWhg4vFs+BSnIaykH4XcAyuXVtVqTl0GusLyY1Wv5DW40AW04/GPg2bvBj0gXbMPOsCq2rA3wrYr/KEM9MaUd/iK2qZPXwOhFRB6YyIWevHbjjZM3npJWxZ6c5xuARG91WXdQxSNBoWgdQloXRjaN/jMjS8EHV4xRwy40DEREwVd2rFC0CXniNjQcW0C3akbA+3lW6Hb8cIPbOixQNEiQ8f8QGFDK3AKtRl6bDqJ3BXj/lqNDh1DncSFlgwcTTdDhzFvO6OeI+DjWzkb0KHjxNqjmlr6r2bue6AdNKfepphLuwLQsZ/4Gx7zzWekYgDo6HIWbYBpLAMmS8BQ0MeLB6w3XCEW2RaxdOLLGqkvSs1yOgqk9sTUEuUdF4/Rcyi0dYIxG1e/UWYwOq7Vg4wAa+e4aydni+gi6YgTdtgWP1giYaOBT7vdOtm0qmHeBqw6eZWj1D6/rhMPs7CigClbmySmale6J9KSgKve4OTnnGyQ3bHZNNkgy1yXnRhu1IWPQxc/ZUe++pzaHHq6CJ5mynSrWJc3NO4sAx4DQro5XmVFPpUyZ2xazQhcPr1JcTA1r9IF1SHDw3KirU83dknlA9A10jpNzivgrCHCpdRc8ev2ntSE/cdcih2DepbzH3gMirnpjf68xUe4uk473YsPnB17tC877fG+CtM5iJbPj1c3rqrktDFEmz39yc8f3OKEmzy5H1ou5o+N1D/cIil0PH/Ktmvh5bbavsL42rX/xuKhlq3Qq16j9uwM/pZHsP/Aw+7/xTHodoLB7t0WvHvdNhgJGiEGaQ7/FsL/8eHFn8r4lh8lwVq2Dc5WVj1veGHkh8Xa4v6Hf2gnrjIU/6QRiUQikUgkEolEIpFIJBKJRCKRSCQSifR99A+QQLqujpJ2+QAAAABJRU5ErkJggg==\";\n","import { APPLE_TOUCH_ICON_PNG, ICON_192_PNG, ICON_512_PNG, ICON_SVG, MASKABLE_512_PNG, MASKABLE_SVG } from \"./icons.js\";\n\n/*\n * What makes the dashboard an installable web app: a manifest, icons, a\n * service worker, the script that registers it, and a page to show offline.\n * None of it says anything about the jobs, so it is served without the token\n * (a browser fetches the manifest and icons without cookies in some flows).\n */\n\n/** The page colours the app's window takes: the paper behind the sheet, and the sheet the header sits on. */\nexport const BACKGROUND_COLOR = \"#f4f4f5\";\nexport const THEME_COLOR = \"#ffffff\";\nexport const THEME_COLOR_DARK = \"#111113\";\n\n/** The manifest, for the dashboard mounted at `base` (\"\" at the root). */\nexport function manifest(base: string): string {\n const icon = (name: string, sizes: string, type: string, purpose: string) => ({ src: `${base}/icons/${name}`, sizes, type, purpose });\n return JSON.stringify({\n id: `${base}/`,\n name: \"CronWatch\",\n short_name: \"CronWatch\",\n description: \"The scheduled jobs of this app: their health, their last day, and their runs.\",\n start_url: `${base}/`,\n scope: `${base}/`,\n display: \"standalone\",\n background_color: BACKGROUND_COLOR,\n theme_color: THEME_COLOR,\n icons: [\n icon(\"icon.svg\", \"any\", \"image/svg+xml\", \"any\"),\n icon(\"maskable.svg\", \"any\", \"image/svg+xml\", \"maskable\"),\n icon(\"icon-192.png\", \"192x192\", \"image/png\", \"any\"),\n icon(\"icon-512.png\", \"512x512\", \"image/png\", \"any\"),\n icon(\"maskable-512.png\", \"512x512\", \"image/png\", \"maskable\"),\n ],\n });\n}\n\n/**\n * Registers the service worker, and does nothing else. The page works the\n * same without it. Its own URL gives the base, so it is the same text\n * wherever the dashboard is mounted.\n */\nexport const APP_JS = `\"use strict\";\n(function () {\n var root = document.documentElement;\n try {\n var stored = localStorage.getItem(\"cronwatch-theme\");\n if (stored === \"light\" || stored === \"dark\") root.setAttribute(\"data-theme\", stored);\n } catch (e) {}\n document.addEventListener(\"keydown\", function (event) {\n if (!(event.metaKey || event.ctrlKey) || !event.shiftKey || event.altKey || event.code !== \"KeyD\") return;\n event.preventDefault();\n var shown = root.getAttribute(\"data-theme\") || (matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\");\n var next = shown === \"dark\" ? \"light\" : \"dark\";\n root.setAttribute(\"data-theme\", next);\n try { localStorage.setItem(\"cronwatch-theme\", next); } catch (e) {}\n });\n})();\n(function () {\n var script = document.currentScript;\n if (!script || !(\"serviceWorker\" in navigator)) return;\n var base = new URL(\"./\", script.src);\n navigator.serviceWorker.register(new URL(\"sw.js\", base).href, { scope: base.pathname }).catch(function () {});\n})();\n`;\n\n/**\n * The service worker. It caches the app shell (the offline page, the\n * manifest, the icons, and app.js) and nothing else: every other request goes\n * to the network as the page made it, and its answer is never stored, since\n * the pages and the JSON carry job data. When a page cannot be reached it\n * shows the offline page. Its scope gives the base, so it is the same text\n * wherever the dashboard is mounted.\n */\nexport const SW_JS = `\"use strict\";\nvar VERSION = \"cronwatch-shell-1\";\nvar SCOPE = self.registration.scope;\nvar CACHE = VERSION + \" \" + SCOPE;\nvar SHELL = [\"offline\", \"manifest.webmanifest\", \"app.js\", \"icons/icon.svg\", \"icons/maskable.svg\", \"icons/icon-192.png\", \"icons/icon-512.png\", \"icons/maskable-512.png\", \"icons/apple-touch-icon.png\"].map(function (path) {\n return new URL(path, SCOPE).href;\n});\nvar OFFLINE = SHELL[0];\n\nself.addEventListener(\"install\", function (event) {\n event.waitUntil(caches.open(CACHE).then(function (cache) {\n return cache.addAll(SHELL.map(function (url) { return new Request(url, { credentials: \"omit\", cache: \"reload\" }); }));\n }).then(function () { return self.skipWaiting(); }));\n});\n\nself.addEventListener(\"activate\", function (event) {\n event.waitUntil(caches.keys().then(function (keys) {\n return Promise.all(keys.filter(function (key) {\n return key !== CACHE && key.indexOf(\"cronwatch-shell-\") === 0 && key.slice(key.indexOf(\" \") + 1) === SCOPE;\n }).map(function (key) { return caches.delete(key); }));\n }).then(function () { return self.clients.claim(); }));\n});\n\nself.addEventListener(\"fetch\", function (event) {\n var request = event.request;\n if (request.method !== \"GET\") return;\n var url = new URL(request.url);\n url.search = \"\";\n if (SHELL.indexOf(url.href) !== -1 && url.href !== OFFLINE) {\n event.respondWith(caches.open(CACHE).then(function (cache) {\n return cache.match(url.href).then(function (hit) { return hit || fetch(request); });\n }));\n return;\n }\n if (request.mode !== \"navigate\") return;\n event.respondWith(fetch(request).catch(function () {\n return caches.open(CACHE).then(function (cache) { return cache.match(OFFLINE); }).then(function (page) {\n return page || new Response(\"You are offline.\", { status: 503, headers: { \"content-type\": \"text/plain; charset=utf-8\" } });\n });\n }));\n});\n`;\n\nexport interface StaticAsset {\n type: string;\n body: string | Uint8Array<ArrayBuffer>;\n cache: string;\n /** The service worker, which may control everything under the base. */\n worker?: boolean;\n}\n\nconst YEAR = \"public, max-age=31536000, immutable\";\nconst REVALIDATE = \"no-cache\";\n\nfunction decode(base64: string): Uint8Array<ArrayBuffer> {\n const bytes = atob(base64);\n const out = new Uint8Array(bytes.length);\n for (let i = 0; i < bytes.length; i++) out[i] = bytes.charCodeAt(i);\n return out;\n}\n\nconst ICONS: Record<string, () => StaticAsset> = {\n \"/icons/icon.svg\": () => ({ type: \"image/svg+xml\", body: ICON_SVG, cache: YEAR }),\n \"/icons/maskable.svg\": () => ({ type: \"image/svg+xml\", body: MASKABLE_SVG, cache: YEAR }),\n \"/icons/icon-192.png\": () => ({ type: \"image/png\", body: decode(ICON_192_PNG), cache: YEAR }),\n \"/icons/icon-512.png\": () => ({ type: \"image/png\", body: decode(ICON_512_PNG), cache: YEAR }),\n \"/icons/maskable-512.png\": () => ({ type: \"image/png\", body: decode(MASKABLE_512_PNG), cache: YEAR }),\n \"/icons/apple-touch-icon.png\": () => ({ type: \"image/png\", body: decode(APPLE_TOUCH_ICON_PNG), cache: YEAR }),\n};\n\n/**\n * The app shell file at `path` (the path under the base), or null. The\n * offline page is HTML and is served by the routes themselves.\n */\nexport function staticAsset(path: string, base: string): StaticAsset | null {\n if (path === \"/manifest.webmanifest\") return { type: \"application/manifest+json\", body: manifest(base), cache: REVALIDATE };\n if (path === \"/app.js\") return { type: \"text/javascript; charset=utf-8\", body: APP_JS, cache: REVALIDATE };\n if (path === \"/sw.js\") return { type: \"text/javascript; charset=utf-8\", body: SW_JS, cache: REVALIDATE, worker: true };\n return Object.hasOwn(ICONS, path) ? ICONS[path]!() : null;\n}\n","/** This release of @cronwatch/sdk. scripts/release.mjs keeps it in step with package.json. */\nexport const VERSION = \"0.15.0\";\n\n/**\n * The dashboard JSON API's version, which GET <base>/api answers. It goes up\n * only for a change that is not additive (a field removed or retyped, a path\n * moved), and such a change waits for a major release.\n */\nexport const API_VERSION = 1;\n","/**\n * The dashboard's timelines: one lane per job (or per day, on a job's page),\n * drawn on the server as inline SVG so the page needs no script.\n *\n * Every time a job was due is a faint tick, worked out from its schedule with\n * the same functions the checks use (nextFire and expectation), so the lane\n * shows the cadence the job is meant to keep. Every run it recorded is a\n * solid mark on top, as wide as it took and coloured by how it ended. A slot\n * the check has reported missed is a dashed box. The empty part of a lane\n * carries a short note about anything open, and a visually hidden list says\n * the same things in words.\n *\n * Every time is UTC: without script the page cannot know the viewer's zone.\n */\nimport { FIRST_DATE_MS, LAST_DATE_MS, formatDuration } from \"../duration.js\";\nimport { finishedAtOf, graceMs, isStuck, timeoutMs } from \"../evaluate.js\";\nimport { andList } from \"../format.js\";\nimport { expectation, firesBetween, intervalDue, parseSchedule, type ParsedSchedule } from \"../schedule.js\";\nimport type { JobSummary, Run } from \"../types.js\";\nimport { escapeHtml as h, escapeName } from \"./escape.js\";\n\nconst HOUR = 3_600_000;\nconst DAY = 24 * HOUR;\n\n/** The board's span: the last day, plus a few hours ahead so what is due soon shows. */\nexport const BOARD_BEHIND_MS = DAY;\nexport const BOARD_AHEAD_MS = 3 * HOUR;\n/** How many jobs the board's timeline draws. The table below it lists every job. */\nexport const BOARD_LANES = 30;\n/**\n * Runs read for a lane when the twenty the table reads start inside the span,\n * so a frequent job's lane is not cut short. Older runs than this are shown\n * as not loaded rather than as absent.\n */\nexport const BOARD_RUNS = 200;\n/** How many days a job's page draws. */\nexport const WEEK_DAYS = 7;\n\n/** Width of a lane in SVG units. Lanes stretch to fit, so strokes do not scale. */\nconst W = 1000;\n/** A lane with more due times than this shows its cadence as a dotted line instead. */\nconst MAX_TICKS = 330;\n/** More missed slots than this are drawn as one dashed band. */\nconst MAX_BOXES = 8;\n/** The narrowest a missed box is drawn, in SVG units. */\nconst MIN_BOX = 10;\n\nconst MONTHS = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\nconst WEEKDAYS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\n/** \"22:42\", in UTC. */\nexport function clock(t: number): string {\n return new Date(t).toISOString().slice(11, 16);\n}\n\n/** \"Sat 26 Sep\", in UTC. */\nexport function dayLabel(t: number): string {\n const d = new Date(t);\n return `${WEEKDAYS[d.getUTCDay()]} ${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]}`;\n}\n\n/**\n * \"22:42\" on the same UTC day as `now`, otherwise \"25 Sep 22:42\", and\n * \"1 Jan 0001 02:00\" in another UTC year. A time before the year 1 or after\n * 9999 (a start read from a foreign or damaged row) is \"before 1 Jan 0001\n * 00:00\" or \"after 31 Dec 9999 23:59\".\n */\nexport function when(t: number, now: number): string {\n if (t > LAST_DATE_MS) return \"after 31 Dec 9999 23:59\";\n if (!(t >= FIRST_DATE_MS)) return \"before 1 Jan 0001 00:00\";\n if (Math.floor(t / DAY) === Math.floor(now / DAY)) return clock(t);\n const d = new Date(t);\n const year = d.getUTCFullYear();\n const other = year === new Date(now).getUTCFullYear() ? \"\" : ` ${String(year).padStart(4, \"0\")}`;\n return `${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]}${other} ${clock(t)}`;\n}\n\n/** The stretch of time a timeline draws, and the moment it was drawn. */\nexport interface Span {\n from: number;\n to: number;\n now: number;\n}\n\n/** The job's schedule, parsed, or null when it has none or it no longer parses. */\nexport function parsedSchedule(job: JobSummary): ParsedSchedule | null {\n if (!job.definition.schedule) return null;\n try {\n return parseSchedule(job.definition.schedule, job.definition.timezone);\n } catch {\n return null;\n }\n}\n\nfunction safely<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport interface DueTimes {\n /** Every time the job was or will be due within the span, ascending. */\n times: number[];\n /** True when there are too many to draw one by one; `times` is then empty. */\n dense: boolean;\n}\n\n/**\n * When the job was due within `from` to `to`. A cron's fires come from\n * nextFire. An interval is due one period after each run started (after it\n * finished, for a run that outlasted the period: intervalDue), and after\n * the last run once a period for as long as nothing runs (the times a\n * missed interval job keeps being asked for); with no run yet, from its\n * next expected time.\n */\nexport function dueTimes(job: JobSummary, parsed: ParsedSchedule | null, runs: Run[], from: number, to: number): DueTimes {\n if (!parsed) return { times: [], dense: false };\n if (parsed.kind === \"interval\") {\n const every = parsed.everyMs!;\n if ((to - from) / every > MAX_TICKS) return { times: [], dense: true };\n const ordered = [...runs].sort((a, b) => a.startedAt - b.startedAt);\n const dues = ordered.map((r) => intervalDue(every, r.startedAt, finishedAtOf(r)));\n const times = new Set<number>();\n for (const t of dues) {\n if (t >= from && t <= to) times.add(t);\n }\n let t = dues.length ? dues[dues.length - 1]! : job.nextExpectedAt;\n if (t !== null) {\n if (t < from) t += Math.ceil((from - t) / every) * every;\n for (; t <= to; t += every) times.add(t);\n }\n return { times: [...times].sort((a, b) => a - b), dense: false };\n }\n const times = safely(() => firesBetween(parsed, from - 1, to, MAX_TICKS), []);\n return times === null ? { times: [], dense: true } : { times, dense: false };\n}\n\n/**\n * The slot a missed job was due at, the one the check reported: the first\n * fire its last run does not cover (expectation(), as onCheck works it\n * out). A job that never ran has no run to count from, so the latest due\n * time whose grace has passed stands in. Null when missed is not open.\n */\nexport function missedAt(job: JobSummary, parsed: ParsedSchedule | null, times: number[], now: number): number | null {\n if (!parsed || !job.open.includes(\"missed\")) return null;\n const grace = safely(() => graceMs(job.definition), 0);\n const lastRun = job.lastRun;\n if (lastRun) return safely(() => expectation(parsed, lastRun.startedAt, lastRun.startedAt, grace, finishedAtOf(lastRun))?.dueAt ?? null, null);\n const past = times.filter((t) => t + grace < now);\n return past.length ? past[past.length - 1]! : null;\n}\n\ntype Tone = \"ok\" | \"bad\" | \"timeout\" | \"warn\" | \"running\" | \"stuck\";\n\nfunction toneOf(run: Run, job: JobSummary, now: number): Tone {\n if (run.status === \"running\") return safely(() => isStuck(job.definition, run, now), false) ? \"stuck\" : \"running\";\n if (run.status === \"failed\") return \"bad\";\n if (run.status === \"timeout\") return \"timeout\";\n const latest = job.lastRun?.id === run.id;\n return latest && (job.open.includes(\"over_budget\") || job.open.includes(\"under_floor\") || job.open.includes(\"slow\")) ? \"warn\" : \"ok\";\n}\n\nfunction timeoutText(job: JobSummary): string {\n return safely(() => formatDuration(timeoutMs(job.definition)), \"configured\");\n}\n\n/** One run, as its tooltip says it. */\nfunction describeRun(run: Run, tone: Tone, job: JobSummary, now: number): string {\n const at = `${when(run.startedAt, now)} UTC`;\n if (tone === \"running\") return `running since ${at}, ${formatDuration(now - run.startedAt)} so far`;\n if (tone === \"stuck\") return `running since ${at}, past its ${timeoutText(job)} timeout`;\n const took = run.durationMs !== null ? `, took ${formatDuration(run.durationMs)}` : \"\";\n const extra = tone === \"warn\" ? (job.open.includes(\"over_budget\") ? \", over budget\" : job.open.includes(\"under_floor\") ? \", under floor\" : \", slow\") : \"\";\n return `${run.status} at ${at}${took}${extra}`;\n}\n\n/** The metrics of the job's last run that went over their ceilings. */\nfunction overCeilings(job: JobSummary): string[] {\n const metrics = job.lastRun?.metrics ?? {};\n return Object.entries(job.definition.budget ?? {}).filter(([k, limit]) => (metrics[k] ?? -Infinity) > limit).map(([k]) => k);\n}\n\n/** The metrics of the job's last run under their floors, or at 0 or less without one. */\nfunction underFloors(job: JobSummary): string[] {\n const floors = job.definition.floor ?? {};\n return Object.entries(job.lastRun?.metrics ?? {}).filter(([k, v]) => (floors[k] !== undefined ? v < floors[k] : v <= 0)).map(([k]) => k);\n}\n\n/** What is worth saying about the job in a few words, or null when all is well. */\nexport function laneNote(job: JobSummary, missed: number | null, now: number): string | null {\n const last = job.lastRun;\n if (job.silencedUntil !== null && job.silencedUntil > now) return `silenced until ${when(job.silencedUntil, now)}`;\n if (job.open.includes(\"missed\")) return missed !== null ? `due ${when(missed, now)}, nothing ran` : \"overdue, nothing ran\";\n if (last?.status === \"running\") {\n const stuck = safely(() => isStuck(job.definition, last, now), false);\n return stuck ? `running since ${when(last.startedAt, now)}, past its ${timeoutText(job)} timeout` : `running since ${when(last.startedAt, now)}`;\n }\n if (last?.status === \"failed\") return `failed at ${when(last.startedAt, now)}${job.consecutiveFailures > 1 ? `, ${job.consecutiveFailures} in a row` : \"\"}`;\n if (last?.status === \"timeout\") return `timed out at ${when(last.startedAt, now)}`;\n if (job.open.includes(\"stuck\")) return \"stuck\";\n if (job.open.includes(\"over_budget\") && last) {\n const over = overCeilings(job);\n return `went over budget${over.length ? ` on ${andList(over)}` : \"\"} at ${when(last.startedAt, now)}`;\n }\n if (job.open.includes(\"under_floor\") && last) {\n const under = underFloors(job);\n return `fell short${under.length ? ` on ${andList(under)}` : \"\"} at ${when(last.startedAt, now)}`;\n }\n if (job.open.includes(\"slow\") && last?.durationMs != null) return `slow: took ${formatDuration(last.durationMs)}`;\n if (job.open.includes(\"failed\")) return \"failing\";\n if (!last && job.nextExpectedAt !== null) return `no runs yet, first due ${when(job.nextExpectedAt, now)}`;\n return null;\n}\n\n/** Everything one lane shows: the marks, the note, and the same in words. */\nexport interface LaneInput {\n job: JobSummary;\n /** The job's runs, any order. Only those overlapping the span are drawn. */\n runs: Run[];\n /** False when older runs exist that were not read; the lane says so before its oldest run. */\n complete: boolean;\n}\n\ninterface LaneParts {\n svg: string;\n note: string;\n words: string;\n}\n\nconst f = (n: number) => n.toFixed(1);\n\n/** Animation delay for a mark at x, so marks arrive in time order, left to right. */\nconst delay = (x: number, base = 80, perUnit = 0.75) => `--d:${Math.round(base + Math.max(0, x) * perUnit)}ms`;\n\nfunction lane(input: LaneInput, span: Span, options: { nowInLane: boolean; label: string }): LaneParts {\n const { job } = input;\n const { from, to, now } = span;\n const x = (t: number) => Math.min(W, Math.max(0, ((t - from) / (to - from)) * W));\n const parsed = parsedSchedule(job);\n const due = dueTimes(job, parsed, input.runs, from, to);\n const missed = missedAt(job, parsed, due.times, now);\n const grace = safely(() => graceMs(job.definition), 0);\n const name = options.label;\n const busy: [number, number][] = [];\n\n let s = `<svg class=\"marks\" viewBox=\"0 0 ${W} 24\" preserveAspectRatio=\"none\" aria-hidden=\"true\" focusable=\"false\">`;\n if (options.nowInLane && now > from && now < to) s += `<rect class=\"ahead\" x=\"${f(x(now))}\" y=\"0\" width=\"${f(W - x(now))}\" height=\"24\"/>`;\n s += `<line class=\"base\" x1=\"0\" y1=\"12\" x2=\"${W}\" y2=\"12\"/>`;\n\n const inSpan = input.runs.filter((r) => r.startedAt <= to && (r.finishedAt ?? now) >= from).sort((a, b) => a.startedAt - b.startedAt);\n if (!input.complete) {\n const oldest = Math.min(...input.runs.map((r) => r.startedAt));\n if (Number.isFinite(oldest) && oldest > from) {\n s += `<rect class=\"unloaded\" x=\"0\" y=\"4\" width=\"${f(x(oldest))}\" height=\"16\"><title>${h(`${name}: runs before ${when(oldest, now)} UTC are not loaded here`)}</title></rect>`;\n }\n }\n\n if (due.dense) {\n s += `<line class=\"cadence\" x1=\"0\" y1=\"12\" x2=\"${W}\" y2=\"12\"><title>${h(`${name}: due ${job.definition.schedule ?? \"\"}, too often to mark each time`)}</title></line>`;\n }\n for (const t of due.times) {\n const tx = x(t);\n s += `<line class=\"tick${t > now ? \" ahead\" : \"\"}\" x1=\"${f(tx)}\" y1=\"6\" x2=\"${f(tx)}\" y2=\"18\" style=\"${delay(tx, 0, 0.45)}\"/>`;\n }\n\n // Missed slots: the reported one and every later one whose grace has run out.\n if (missed !== null && missed <= to) {\n const slots = due.dense ? [] : due.times.filter((t) => t >= missed && t + grace < now);\n if (!slots.includes(missed) && missed >= from) slots.unshift(missed);\n const title = h(`${name}: due ${when(missed, now)} UTC, nothing started${slots.length > 1 ? ` (${slots.length} slots in this span)` : \"\"}`);\n if (due.dense || slots.length > MAX_BOXES) {\n const x1 = x(Math.max(missed, from)), x2 = Math.max(x(now), x1 + MIN_BOX);\n s += `<rect class=\"missed\" x=\"${f(x1)}\" y=\"5\" width=\"${f(x2 - x1)}\" height=\"14\" style=\"${delay(x1)}\"><title>${title}</title></rect>`;\n busy.push([x1, x2]);\n } else {\n for (const t of slots) {\n if (t < from) continue;\n const x1 = x(t), width = Math.max(x(t + grace) - x1, MIN_BOX);\n s += `<rect class=\"missed\" x=\"${f(x1)}\" y=\"5\" width=\"${f(width)}\" height=\"14\" style=\"${delay(x1)}\"><title>${title}</title></rect>`;\n busy.push([x1, x1 + width]);\n }\n }\n }\n\n for (const run of inSpan) {\n const tone = toneOf(run, job, now);\n // A zero-width rect is not drawn at all; its stroke gives short runs their width.\n const x1 = x(run.startedAt), x2 = Math.max(x(run.finishedAt ?? now), x1 + 0.5);\n s += `<rect class=\"run ${tone}\" x=\"${f(x1)}\" y=\"5\" width=\"${f(x2 - x1)}\" height=\"14\" style=\"${delay(x1)}\"><title>${h(`${name}: ${describeRun(run, tone, job, now)}`)}</title></rect>`;\n busy.push([x1, x2]);\n }\n\n if (options.nowInLane && now > from && now < to) s += `<line class=\"nowline\" x1=\"${f(x(now))}\" y1=\"0\" x2=\"${f(x(now))}\" y2=\"24\"/>`;\n s += `</svg>`;\n\n // The note goes wherever the lane is actually empty, so it never sits on\n // the marks it describes; it is cut short with an ellipsis when narrow.\n const text = laneNote(job, missed, now);\n let note = \"\";\n if (text) {\n const nowX = x(now);\n const lo = busy.length ? Math.min(...busy.map((b) => b[0])) : nowX;\n const hi = busy.length ? Math.max(...busy.map((b) => b[1])) : nowX;\n const right = W - hi >= lo;\n const room = right ? W - hi : lo;\n if (room > 90) {\n const edge = right ? hi + 14 : lo - 14;\n const place = right ? `left:${f(edge / 10)}%` : `right:${f(100 - edge / 10)}%`;\n note = `<span class=\"note${right ? \"\" : \" before\"}\" style=\"${place};max-width:${f((room - 18) / 10)}%\">${h(text)}</span>`;\n }\n }\n\n return { svg: s, note, words: words(job, inSpan, due, missed, span, text) };\n}\n\n/** The lane in words, for anyone who cannot see it. */\nfunction words(job: JobSummary, runs: Run[], due: DueTimes, missed: number | null, span: Span, note: string | null): string {\n const parts: string[] = [];\n if (due.dense) parts.push(`due ${job.definition.schedule}`);\n else if (job.definition.schedule) {\n const n = due.times.filter((t) => t <= span.now).length;\n parts.push(`due ${n === 0 ? \"no times\" : n === 1 ? \"once\" : `${n} times`} so far`);\n }\n const ok = runs.filter((r) => r.status === \"ok\").length;\n parts.push(`${runs.length} ${runs.length === 1 ? \"run\" : \"runs\"} recorded${!runs.length ? \"\" : ok === runs.length ? (ok === 1 ? \", ok\" : \", all ok\") : ok ? `, ${ok} ok` : \"\"}`);\n for (const r of runs.filter((r) => r.status === \"failed\" || r.status === \"timeout\").slice(-5)) {\n parts.push(`${r.status} at ${when(r.startedAt, span.now)} UTC after ${formatDuration(r.durationMs ?? 0)}`);\n }\n if (missed !== null) parts.push(`due at ${when(missed, span.now)} UTC and nothing started`);\n if (note && !/^(due |failed at|timed out)/.test(note)) parts.push(note);\n return parts.join(\"; \");\n}\n\n/** Grid lines and hour labels every `step`, on UTC boundaries. */\nfunction hours(span: Span, step: number, nowLabel: boolean): { lines: string; labels: string } {\n const x = (t: number) => ((t - span.from) / (span.to - span.from)) * W;\n const nowX = x(span.now);\n let lines = \"\", labels = \"\";\n for (let t = Math.ceil(span.from / step) * step; t <= span.to; t += step) {\n const gx = x(t);\n lines += `<i class=\"gl\" style=\"left:${f(gx / 10)}%\"></i>`;\n const nearNow = nowLabel && Math.abs(gx - nowX) < 70;\n if (gx < 25 || gx > W - 25 || nearNow) continue;\n const minor = Math.round(t / HOUR) % 6 !== 0;\n // On a phone the track is too narrow for a label this close to \"now\"; CSS hides it there.\n const near = nowLabel && Math.abs(gx - nowX) < 170;\n const cls = [minor && \"minor\", near && \"near\"].filter(Boolean).join(\" \");\n labels += `<span class=\"${cls}\" style=\"left:${f(gx / 10)}%\">${clock(t)}</span>`;\n }\n if (nowLabel && span.now >= span.from && span.now <= span.to) labels += `<span class=\"nowlabel\" style=\"left:${f(nowX / 10)}%\">now ${clock(span.now)}</span>`;\n return { lines, labels };\n}\n\n/** The key under a timeline: a small sample of each mark and what it means. */\nfunction legend(): string {\n const key = (inner: string) => `<svg class=\"key\" viewBox=\"0 0 16 12\" aria-hidden=\"true\" focusable=\"false\">${inner}</svg>`;\n const box = (cls: string) => key(`<rect class=\"${cls}\" x=\"2\" y=\"1\" width=\"12\" height=\"10\"/>`);\n const items: [string, string][] = [\n [key(`<line class=\"tick\" x1=\"8\" y1=\"1\" x2=\"8\" y2=\"11\"/>`), \"due\"],\n [box(\"run ok\"), \"ran\"],\n [box(\"run bad\"), \"failed\"],\n [box(\"run timeout\"), \"timed out\"],\n [box(\"run warn\"), \"over budget, under floor, or slow\"],\n [box(\"run running\"), \"running\"],\n [box(\"missed\"), \"missed\"],\n ];\n return `<p class=\"legend\" aria-hidden=\"true\">${items.map(([k, label]) => `<span>${k}${label}</span>`).join(\"\")}</p>`;\n}\n\nfunction stateClass(job: JobSummary): string {\n return ({ healthy: \"ok\", late: \"warn\", failing: \"bad\", stuck: \"bad\", silenced: \"muted\", never_ran: \"muted\" } as const)[job.health];\n}\n\n/**\n * The board's timeline: one lane per job across `span`, with a shared now\n * line and the first BOARD_LANES jobs only. `total` is how many jobs there\n * are in all, for the note when some are left out.\n */\nexport function dayTimeline(lanes: LaneInput[], span: Span, base: string, total: number): string {\n const grid = hours(span, 3 * HOUR, true);\n const nowX = ((span.now - span.from) / (span.to - span.from)) * 100;\n const rows = lanes.map((input) => {\n const { job } = input;\n const parts = lane(input, span, { nowInLane: false, label: job.name });\n return {\n html: `<li class=\"lane\"><div class=\"who\"><i class=\"sq ${stateClass(job)}\" aria-hidden=\"true\"></i><a class=\"name\" href=\"${h(base)}/jobs/${encodeURIComponent(job.name)}\">${escapeName(job.name)}</a><span class=\"sched\">${h(job.definition.schedule ?? \"no schedule\")}</span></div><div class=\"track\">${parts.svg}${parts.note}</div></li>`,\n words: `<li>${h(`${job.name} (${job.definition.schedule ?? \"no schedule\"}): ${parts.words}.`)}</li>`,\n };\n });\n const more = total > lanes.length ? `<p class=\"more\">Showing the first ${lanes.length} of ${total} jobs here; the table below lists them all.</p>` : \"\";\n return `<figure class=\"timeline day\">\n<div class=\"axis\" aria-hidden=\"true\"><span></span><div class=\"hours\">${grid.labels}</div></div>\n<div class=\"field\">\n<div class=\"under\" aria-hidden=\"true\"><span></span><div>${grid.lines}<i class=\"future\" style=\"left:${f(nowX)}%\"></i></div></div>\n<ol class=\"lanes\">${rows.map((r) => r.html).join(\"\")}</ol>\n<div class=\"over\" aria-hidden=\"true\"><span></span><div><i class=\"now\" style=\"left:${f(nowX)}%\"></i></div></div>\n</div>\n${legend()}${more}\n<ul class=\"vh\">${rows.map((r) => r.words).join(\"\")}</ul>\n</figure>`;\n}\n\n/**\n * A job's page: its last WEEK_DAYS UTC days, today first, one lane each.\n * `complete` is false when the runs read do not reach back over the week.\n */\nexport function weekTimeline(job: JobSummary, runs: Run[], complete: boolean, now: number): string {\n const today = Math.floor(now / DAY) * DAY;\n const oldest = runs.length ? Math.min(...runs.map((r) => r.startedAt)) : null;\n const first: Span = { from: today, to: today + DAY, now };\n const grid = hours(first, 3 * HOUR, false);\n const rows: { html: string; words: string }[] = [];\n for (let i = 0; i < WEEK_DAYS; i++) {\n const from = today - i * DAY;\n const span: Span = { from, to: from + DAY, now };\n const dayRuns = runs.filter((r) => r.startedAt < span.to && (r.finishedAt ?? now) >= from);\n const known = complete || (oldest !== null && oldest <= from);\n const label = i === 0 ? \"today\" : dayLabel(from);\n const parts = lane({ job, runs, complete: known }, span, { nowInLane: i === 0, label: `${job.name}, ${label}` });\n const count = `${dayRuns.length} ${dayRuns.length === 1 ? \"run\" : \"runs\"}`;\n rows.push({\n html: `<li class=\"lane${i === 0 ? \" today\" : \"\"}\"><div class=\"who\"><span class=\"name\">${h(i === 0 ? `Today, ${dayLabel(from).slice(4)}` : dayLabel(from))}</span><span class=\"sched\">${h(count)}</span></div><div class=\"track\">${parts.svg}${i === 0 ? parts.note : \"\"}</div></li>`,\n words: `<li>${h(`${i === 0 ? \"Today\" : dayLabel(from)}: ${parts.words}.`)}</li>`,\n });\n }\n return `<figure class=\"timeline week\">\n<div class=\"axis\" aria-hidden=\"true\"><span></span><div class=\"hours\">${grid.labels}</div></div>\n<div class=\"field\">\n<div class=\"under\" aria-hidden=\"true\"><span></span><div>${grid.lines}</div></div>\n<ol class=\"lanes\">${rows.map((r) => r.html).join(\"\")}</ol>\n</div>\n${legend()}\n<ul class=\"vh\">${rows.map((r) => r.words).join(\"\")}</ul>\n</figure>`;\n}\n\n/**\n * How many runs a job's page reads so its week is drawn in full: roughly how\n * often the schedule was due over the week, with room to spare, from 50 (what\n * the run list shows) to 500 (the most runs() returns).\n */\nexport function weekRunsLimit(job: JobSummary, now: number): number {\n const parsed = parsedSchedule(job);\n if (!parsed) return 50;\n const from = Math.floor(now / DAY) * DAY - (WEEK_DAYS - 1) * DAY;\n const span = now + DAY - from;\n // A cron's fires over one day, times the week: close enough, and cheap.\n const expected = parsed.kind === \"interval\"\n ? span / parsed.everyMs!\n : (() => {\n const due = dueTimes(job, parsed, [], now - DAY, now);\n return due.dense ? Infinity : (due.times.length * span) / DAY;\n })();\n return Math.min(500, Math.max(50, Math.ceil(expected * 1.2) + 10));\n}\n","import { beyondDates, formatDuration, formatRelative, isoTime } from \"../duration.js\";\nimport type { JobSummary, Run } from \"../types.js\";\nimport { escapeHtml, escapeName } from \"./escape.js\";\nimport { THEME_COLOR, THEME_COLOR_DARK } from \"./pwa.js\";\nimport { VERSION } from \"../version.js\";\nimport { BOARD_LANES, BOARD_AHEAD_MS, BOARD_BEHIND_MS, clock, dayTimeline, laneNote, missedAt, parsedSchedule, weekTimeline, when, type LaneInput } from \"./timeline.js\";\n\nexport { escapeHtml };\n\nconst h = escapeHtml;\n\n/** The footer's note of what is serving the page, linked to the changelog. Nothing is fetched to compare it. */\nconst VERSION_LINK = `<a class=\"version\" href=\"https://github.com/cronwatchdev/cronwatch/blob/main/CHANGELOG.md\">@cronwatch/sdk ${VERSION}</a>`;\n\n/*\n * Set like cronwatch.dev: a printed sheet on grey paper, a serif for what a\n * person reads, a mono for what a machine printed, neutral greys, and colour\n * only for the states CronWatch reports. The page loads nothing but its own\n * app shell (its CSP is default-src 'none' plus 'self' for the script, the\n * manifest, the worker, and images), so the fonts are system stacks that echo\n * the site's Newsreader and IBM Plex Mono, and use them when they are installed.\n *\n * Installed as an app (display-mode: standalone) the header stays at the top\n * as the app's bar, and the page keeps clear of notches and the home\n * indicator with the safe-area insets (the viewport is viewport-fit=cover).\n *\n * Motion is CSS only and says something: marks arrive in time order, the now\n * line drops in last, and open problems (a missed slot, a running bar) breathe\n * slowly. prefers-reduced-motion turns all of it off. Only opacity and\n * transform move, so nothing shifts the layout.\n */\nconst CSS = `\n:root{color-scheme:light dark;--paper:#f4f4f5;--sheet:#fff;--sunk:#fafafa;--rule:#e4e4e7;--rule-2:#d4d4d8;--tick:#909098;--ink:#000;--body:#18181b;--muted:#71717a;--ok:#15803d;--warn:#a16207;--bad:#b91c1c;--serif:\"Newsreader\",ui-serif,Georgia,Cambria,\"Times New Roman\",serif;--mono:\"IBM Plex Mono\",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;--who:200px}\n@media(prefers-color-scheme:dark){:root:not([data-theme=light]){--paper:#09090b;--sheet:#111113;--sunk:#18181b;--rule:#27272a;--rule-2:#3f3f46;--tick:#66666f;--ink:#fff;--body:#e4e4e7;--muted:#a1a1aa;--ok:#4ade80;--warn:#fbbf24;--bad:#f87171}}\n:root[data-theme=light]{color-scheme:light}:root[data-theme=dark]{color-scheme:dark;--paper:#09090b;--sheet:#111113;--sunk:#18181b;--rule:#27272a;--rule-2:#3f3f46;--tick:#66666f;--ink:#fff;--body:#e4e4e7;--muted:#a1a1aa;--ok:#4ade80;--warn:#fbbf24;--bad:#f87171}\n*{box-sizing:border-box}html{-webkit-text-size-adjust:100%}\nbody{margin:0;background:var(--paper);color:var(--ink);font:400 16px/1.55 var(--serif);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}\na{color:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.16em;text-decoration-color:var(--rule-2)}a:hover{text-decoration-color:currentColor}\n:focus-visible{outline:2px solid var(--ink);outline-offset:2px}\ncode,pre,.mono{font-family:var(--mono)}\n.vh{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n.sheet{max-width:1180px;min-height:100vh;margin:0 auto;background:var(--sheet);border-inline:1px solid var(--rule);padding:0 clamp(16px,4vw,48px)}\n.top{display:flex;align-items:center;justify-content:space-between;gap:12px 20px;flex-wrap:wrap;padding:18px 0 17px;border-bottom:1px solid var(--rule)}\n.brand{display:flex;align-items:center;gap:10px;margin:0;font:600 18px/1.2 var(--serif);letter-spacing:-.01em;min-width:0}\n.brand a{display:inline-flex;align-items:center;gap:10px;text-decoration:none}.brand svg{width:24px;height:24px;flex:none;color:var(--ink)}\n.brand .crumb{font:500 15px/1.2 var(--mono);color:var(--body);overflow-wrap:anywhere}.brand .slash{color:var(--rule-2);font-weight:400}\n.actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap}\n.meta{font:400 12px/1.4 var(--mono);color:var(--muted)}\nbutton,a.button,details.confirm>summary{font:500 12.5px/1 var(--mono);color:var(--ink);background:var(--sheet);border:1px solid var(--rule-2);border-radius:3px;height:32px;padding:0 11px;cursor:pointer}\na.button{display:inline-flex;align-items:center;text-decoration:none}\nbutton:hover,a.button:hover,details.confirm>summary:hover{border-color:var(--muted)}\nbutton.primary{background:var(--ink);border-color:var(--ink);color:var(--sheet)}button.primary:hover{opacity:.86}button.danger{color:var(--bad)}button.danger:hover{border-color:var(--bad)}\nform.inline{display:inline-flex;align-items:center;gap:6px;margin:0}\ndetails.confirm{display:inline-flex;align-items:center;flex-wrap:wrap;gap:8px;margin:0}details.confirm>summary{list-style:none;display:inline-flex;align-items:center}\ndetails.confirm>summary::-webkit-details-marker{display:none}details.confirm[open]>summary{border-color:var(--muted)}\ndetails.confirm form{flex-wrap:wrap;font-size:14px;color:var(--muted)}.delete details{margin-top:16px}\n.sec{display:grid;grid-template-columns:150px minmax(0,1fr);gap:10px 40px;padding:30px 0;border-top:1px solid var(--rule)}\n.top+main>.sec:first-child{border-top:0}\n.sec>h2{margin:0;font:500 11px/1.5 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--muted);padding-top:5px}\n.sec>.wide{grid-column:1/-1;min-width:0}\n.lede{margin:0;color:var(--muted);font-size:16px;max-width:64ch;text-wrap:pretty}\n.headline{margin:0;font:400 clamp(24px,3.2vw,32px)/1.2 var(--serif);letter-spacing:-.01em;text-wrap:balance}\n.headline b{font-weight:600}\n.state{font:500 12.5px/1.4 var(--mono);white-space:nowrap}.state+.state::before{content:\" \\\\00b7 \";color:var(--muted);font-weight:400}\n.ok{color:var(--ok)}.warn{color:var(--warn)}.bad{color:var(--bad)}.muted{color:var(--muted)}.info{color:var(--ink)}\n.sq{display:inline-block;width:8px;height:8px;border-radius:1.5px;background:currentColor;margin-right:7px;vertical-align:1px;flex:none}\n.sq.muted{background:none;box-shadow:inset 0 0 0 1.5px var(--tick)}\n.figures{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:0;margin:22px 0 0;border-top:1px solid var(--rule)}\n.figures>div{display:flex;flex-direction:column-reverse;justify-content:flex-end;gap:4px;padding:14px 16px 2px 0}\n.figures dt{font:500 11px/1.4 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);display:flex;align-items:center}\n.figures dd{margin:0;font:400 30px/1.1 var(--serif);font-variant-numeric:tabular-nums;color:var(--ink)}\n.figures dd small{font-size:17px;color:var(--muted)}\n.figures .zero dd{color:var(--rule-2)}\n.figures .bad dd{color:var(--bad)}.figures .warn dd{color:var(--warn)}\n.stateline{margin:12px 0 0;display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px}\n.stateline .why{font-style:italic;color:var(--muted)}\n.jobname{margin:0;font:500 clamp(22px,3vw,28px)/1.2 var(--mono);letter-spacing:-.01em;overflow-wrap:anywhere}\n.desc{margin:6px 0 0;color:var(--body);max-width:64ch}\n.intro .actions{margin-top:18px}\ntable{width:100%;border-collapse:collapse}\nth{text-align:left;font:500 10.5px/1.2 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);padding:0 14px 10px 0;border-bottom:1px solid var(--rule);white-space:nowrap}\ntd{padding:12px 14px 12px 0;border-bottom:1px solid var(--rule);vertical-align:top;font:400 12.5px/1.5 var(--mono);color:var(--body)}\ntbody tr:last-child td{border-bottom:0}\ntd.job{font-family:var(--serif);font-size:15px;min-width:180px}\ntd.job .name{font:500 13.5px/1.5 var(--mono);color:var(--ink)}\ntd.job .desc{display:block;margin:2px 0 0;font-size:14px;color:var(--muted);line-height:1.4}\ntd .tz,td .sub{display:block;color:var(--muted);font-size:11.5px}\n.nowrap{white-space:nowrap}\n.spark{display:block;overflow:visible}.spark rect{fill:var(--tick)}.spark rect.bad{fill:var(--bad)}.spark rect.warn{fill:var(--warn)}.spark rect.running{fill:none;stroke:var(--ink);stroke-width:1}\n.runs td{padding-top:11px;padding-bottom:11px}.runs tr.has-detail td{border-bottom:0;padding-bottom:4px}.runs tr.detail td{padding-top:0}\n.metrics{display:flex;flex-wrap:wrap;gap:2px 14px}.metrics .k{color:var(--muted)}\npre{margin:6px 0 0;padding:12px 14px;background:var(--sunk);border:1px solid var(--rule);border-radius:3px;font:400 12.5px/1.55 var(--mono);color:var(--body);white-space:pre-wrap;overflow-wrap:anywhere;max-height:340px;overflow:auto}\ndetails.out{margin-top:4px}details.out>summary{cursor:pointer;font:400 12px/1.6 var(--mono);color:var(--muted)}details.out>summary:hover{color:var(--ink)}\ndetails.out.error>summary{color:var(--bad)}\ndl.def{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:8px 28px;margin:0}\ndl.def dt{font:500 11px/1.9 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}\ndl.def dd{margin:0;font:400 13.5px/1.7 var(--mono);color:var(--body);overflow-wrap:anywhere}dl.def dd.prose{font:400 16px/1.55 var(--serif)}\n.empty{padding:28px 0 8px;color:var(--muted);max-width:60ch}\n.empty code{font-size:.86em;color:var(--ink)}\n.message{padding:clamp(56px,12vh,120px) 0;text-align:center}\n.message h1{margin:0;font:400 clamp(28px,4vw,40px)/1.15 var(--serif);letter-spacing:-.015em}\n.message p{margin:14px auto 0;max-width:52ch;color:var(--muted);text-wrap:pretty}\n.signin{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px;margin:28px auto 0;max-width:420px}\n.signin label{font:500 11px/1.4 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}\n.signin input{flex:1 1 180px;min-width:0;font:400 16px/1.2 var(--mono);color:var(--ink);background:var(--sheet);border:1px solid var(--rule-2);border-radius:3px;height:32px;padding:0 10px}\nfooter{display:flex;flex-wrap:wrap;gap:6px 18px;padding:20px 0 40px;border-top:1px solid var(--rule);font:400 12px/1.5 var(--mono);color:var(--muted)}footer .version{margin-left:auto}\n.timeline{margin:18px 0 0}\n.timeline .axis,.timeline .under,.timeline .over,.timeline .lane{display:grid;grid-template-columns:var(--who) minmax(0,1fr)}\n.timeline .hours{position:relative;height:22px;font:400 11px/1 var(--mono);color:var(--muted);letter-spacing:.04em}\n.timeline .hours span{position:absolute;top:2px;transform:translateX(-50%);white-space:nowrap}\n.timeline .hours .nowlabel{color:var(--ink);font-weight:500;animation:cw-fade .5s 1s both}\n.timeline .field{position:relative}\n.timeline .under,.timeline .over{position:absolute;inset:0;pointer-events:none}\n.timeline .under>div,.timeline .over>div{position:relative}\n.timeline .gl{position:absolute;top:0;bottom:0;width:1px;background:var(--rule)}\n.timeline .future{position:absolute;top:0;bottom:0;right:0;background:var(--sunk)}\n.timeline .now{position:absolute;top:-6px;bottom:0;width:1.5px;margin-left:-.75px;background:var(--ink);transform-origin:top;animation:cw-drop .6s .85s cubic-bezier(.2,.8,.2,1) both}\n.timeline .lanes{position:relative;list-style:none;margin:0;padding:0;border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}\n.timeline .lane{align-items:center;min-height:40px}\n.timeline .who{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;column-gap:0;padding:6px 14px 6px 0;min-width:0}\n.timeline .who .sched{grid-column:2}\n.timeline.week .who{display:flex;align-items:baseline;gap:10px}\n.timeline .who .name{font:500 13px/1.35 var(--mono);color:var(--ink);overflow-wrap:anywhere}\n.timeline .who .sched{font:400 11px/1.35 var(--mono);color:var(--muted);white-space:nowrap}\n.timeline .track{position:relative;height:24px}\n.timeline .marks{display:block;width:100%;height:24px;overflow:visible}\n.timeline .note{position:absolute;top:50%;transform:translateY(-50%);font:italic 400 14px/1.2 var(--serif);color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 3px;text-shadow:0 0 3px var(--sheet),0 0 3px var(--sheet),0 0 6px var(--sheet);animation:cw-fade .6s 1.1s both}\n.timeline .note.before{text-align:right}\n.timeline .legend{display:flex;flex-wrap:wrap;gap:6px 18px;margin:14px 0 0;padding-left:var(--who);font:400 11.5px/1.4 var(--mono);color:var(--muted)}\n.timeline .legend span{display:inline-flex;align-items:center;gap:7px}\n.timeline .more{margin:10px 0 0;padding-left:var(--who);font-size:14px;color:var(--muted);font-style:italic}\n.key{width:16px;height:12px;overflow:visible}\n.marks *{vector-effect:non-scaling-stroke}\nsvg .base{stroke:var(--rule);stroke-width:1}\nsvg .tick{stroke:var(--tick);stroke-width:1.5}svg .tick.ahead{stroke-dasharray:2 2;opacity:.75}\nsvg .cadence{stroke:var(--tick);stroke-width:2;stroke-dasharray:1 3}\nsvg .run{stroke-width:2;stroke-linejoin:round}\nsvg .run.ok{fill:var(--ok);stroke:var(--ok)}\nsvg .run.bad{fill:var(--bad);stroke:var(--bad)}\nsvg .run.timeout{fill:var(--bad);fill-opacity:.28;stroke:var(--bad);stroke-width:1.5}\nsvg .run.warn{fill:var(--warn);stroke:var(--warn)}\nsvg .run.running{fill:none;stroke:var(--ink);stroke-width:1.5}\nsvg .run.stuck{fill:var(--bad);fill-opacity:.12;stroke:var(--bad);stroke-width:1.5}\nsvg .missed{fill:none;stroke:var(--bad);stroke-width:1.5;stroke-dasharray:3 2.5}\nsvg .unloaded{fill:var(--sunk)}\nsvg .ahead{fill:var(--sunk)}\nsvg .nowline{stroke:var(--ink);stroke-width:1.5}\n.marks .tick{animation:cw-fade .4s var(--d,0ms) both}\n.marks .run,.marks .missed{transform-box:fill-box;transform-origin:0 50%;animation:cw-grow .55s cubic-bezier(.2,.8,.2,1) var(--d,0ms) both}\n.marks .missed,.marks .run.running,.marks .run.stuck{animation:cw-grow .55s cubic-bezier(.2,.8,.2,1) var(--d,0ms) both,cw-breathe 2.6s ease-in-out calc(var(--d,0ms) + .6s) infinite alternate}\n.figures>div{animation:cw-rise .5s cubic-bezier(.2,.8,.2,1) both}\n.figures>div:nth-child(2){animation-delay:40ms}.figures>div:nth-child(3){animation-delay:80ms}.figures>div:nth-child(4){animation-delay:120ms}.figures>div:nth-child(5){animation-delay:160ms}.figures>div:nth-child(6){animation-delay:200ms}\n@keyframes cw-fade{from{opacity:0}}\n@keyframes cw-grow{from{opacity:0;transform:scaleX(0)}}\n@keyframes cw-drop{from{opacity:0;transform:scaleY(0)}}\n@keyframes cw-rise{from{opacity:0;transform:translateY(4px)}}\n@keyframes cw-breathe{to{opacity:.38}}\nbody{padding:0 env(safe-area-inset-right) 0 env(safe-area-inset-left)}\nfooter{padding-bottom:calc(40px + env(safe-area-inset-bottom))}\n@media(display-mode:standalone){\n.top{position:sticky;top:0;z-index:2;background:var(--sheet);padding-top:calc(14px + env(safe-area-inset-top));padding-bottom:13px;-webkit-user-select:none;user-select:none}\n.message{padding-top:clamp(40px,8vh,80px)}\n}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}\n@media(max-width:760px){\n.sec{grid-template-columns:minmax(0,1fr);gap:10px;padding:24px 0}\n.hide-sm{display:none}\n:root{--who:0px}\n.timeline .lane{grid-template-columns:minmax(0,1fr);padding:6px 0 8px}\n.timeline .who{padding:0 0 4px}\n.timeline .who .name{background:var(--sheet);padding-right:4px}\n.timeline .hours .minor,.timeline .hours .near{display:none}\n.timeline .note{font-size:13px}\ntd.job{min-width:0}\ntable.board thead{display:none}\ntable.board tr{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:14px;padding:12px 0;border-bottom:1px solid var(--rule)}\ntable.board tbody tr:last-child{border-bottom:0}\ntable.board td{border:0;padding:0}\ntable.board td.last{grid-column:1/-1;margin-top:4px;white-space:normal}\ntable.board td.last .sub{display:inline;margin-left:8px}\n.runs td.nowrap{white-space:normal}\ndl.def{grid-template-columns:minmax(0,1fr);gap:0}dl.def dd{margin-bottom:10px}\n}\n`;\n\n/** The clock face from cronwatch.dev, in the text colour. */\nconst MARK = `<svg viewBox=\"0 0 40 40\" aria-hidden=\"true\" focusable=\"false\"><rect x=\"1\" y=\"1\" width=\"38\" height=\"38\" rx=\"9.5\" fill=\"none\" stroke=\"currentColor\" stroke-opacity=\".22\" stroke-width=\"1.5\"/><circle cx=\"20\" cy=\"20\" r=\"10.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/><path d=\"M20 12.5V20h6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;\n\n/**\n * A page. `base` is where the dashboard is mounted (\"\" at the root): the head\n * links the web app manifest, the icons, and app.js, the one script, which\n * registers the service worker and toggles the theme (routes/pwa.ts). Everything works\n * without it.\n */\nexport function layout(title: string, body: string, base: string, options: { refresh?: number } = {}): string {\n const b = h(base);\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\">\n<meta name=\"robots\" content=\"noindex,nofollow\">\n<meta name=\"color-scheme\" content=\"light dark\">\n${options.refresh ? `<meta http-equiv=\"refresh\" content=\"${options.refresh}\">` : \"\"}\n<title>${h(title)}</title>\n<meta name=\"theme-color\" content=\"${THEME_COLOR}\" media=\"(prefers-color-scheme: light)\">\n<meta name=\"theme-color\" content=\"${THEME_COLOR_DARK}\" media=\"(prefers-color-scheme: dark)\">\n<meta name=\"mobile-web-app-capable\" content=\"yes\">\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n<meta name=\"apple-mobile-web-app-title\" content=\"CronWatch\">\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">\n<link rel=\"manifest\" href=\"${b}/manifest.webmanifest\">\n<link rel=\"icon\" href=\"${b}/icons/icon.svg\" type=\"image/svg+xml\">\n<link rel=\"apple-touch-icon\" href=\"${b}/icons/apple-touch-icon.png\">\n<script src=\"${b}/app.js\" defer></script>\n<style>${CSS}</style>\n</head>\n<body><div class=\"sheet\">${body}</div></body>\n</html>`;\n}\n\nfunction brand(base: string, crumb?: string): string {\n const home = `<a href=\"${h(base)}/\">${MARK}<span>CronWatch</span></a>`;\n return crumb === undefined\n ? `<p class=\"brand\">${home}</p>`\n : `<p class=\"brand\">${home}<span class=\"slash\" aria-hidden=\"true\">/</span><span class=\"crumb\">${escapeName(crumb)}</span></p>`;\n}\n\nconst HEALTH: Record<JobSummary[\"health\"], [string, string]> = {\n failing: [\"bad\", \"failing\"],\n stuck: [\"bad\", \"stuck\"],\n late: [\"warn\", \"late\"],\n healthy: [\"ok\", \"healthy\"],\n silenced: [\"muted\", \"silenced\"],\n never_ran: [\"muted\", \"never ran\"],\n};\n\n/** The job's health, with any open condition it does not already say (over budget, under floor, slow) after it. */\nfunction healthState(job: JobSummary): string {\n const [cls, label] = HEALTH[job.health];\n const extras = job.open.filter((c) => ![\"missed\", \"failed\", \"stuck\"].includes(c)).map((c) => `<span class=\"state warn\">${h(c.replace(\"_\", \" \"))}</span>`).join(\"\");\n return `<span class=\"state ${cls}\"><i class=\"sq ${cls}\" aria-hidden=\"true\"></i>${label}</span>${extras}`;\n}\n\nfunction runState(run: Run): string {\n const cls = run.status === \"ok\" ? \"ok\" : run.status === \"running\" ? \"info\" : \"bad\";\n return `<span class=\"state ${cls}\">${h(run.status)}</span>`;\n}\n\n/** The last twenty runs, oldest first, as bars as tall as they took; grey unless something went wrong. */\nfunction sparkline(runs: Run[]): string {\n const points = [...runs].slice(0, 20).reverse();\n if (points.length < 2) return \"\";\n const bar = 4, gap = 1.5, hgt = 22;\n const max = Math.max(...points.map((r) => r.durationMs ?? 0), 1);\n const bars = points.map((r, i) => {\n const x = (i * (bar + gap)).toFixed(1);\n if (r.status === \"running\") return `<rect class=\"running\" x=\"${x}\" y=\"${hgt - 6.5}\" width=\"${bar - 1}\" height=\"6\"/>`;\n const tall = Math.max(r.status === \"ok\" ? 2 : 6, ((r.durationMs ?? 0) / max) * hgt);\n const cls = r.status === \"ok\" ? \"\" : ` class=\"bad\"`;\n return `<rect${cls} x=\"${x}\" y=\"${(hgt - tall).toFixed(1)}\" width=\"${bar}\" height=\"${tall.toFixed(1)}\" rx=\".5\"/>`;\n }).join(\"\");\n const w = points.length * (bar + gap) - gap;\n return `<svg class=\"spark\" width=\"${w.toFixed(1)}\" height=\"${hgt}\" viewBox=\"0 0 ${w.toFixed(1)} ${hgt}\" aria-hidden=\"true\" focusable=\"false\">${bars}</svg>`;\n}\n\nfunction stamp(at: number | null, now: number): string {\n if (at === null) return `<span class=\"muted\">never</span>`;\n const iso = isoTime(at);\n if (iso === null) return `<span class=\"nowrap\">${beyondDates(at)}</span>`;\n return `<time class=\"nowrap\" datetime=\"${iso}\" title=\"${iso.replace(\"T\", \" \").slice(0, 19)} UTC\">${h(formatRelative(at, now))}</time>`;\n}\n\n/** Counts by health, the ones needing attention first; a zero is set faint rather than left out, so the row keeps its shape. */\nfunction healthFigures(jobs: JobSummary[]): string {\n return `<dl class=\"figures\">${(Object.keys(HEALTH) as JobSummary[\"health\"][]).map((health) => {\n const [cls, label] = HEALTH[health];\n const n = jobs.filter((j) => j.health === health).length;\n return `<div class=\"${n === 0 ? \"zero\" : cls}\"><dt><i class=\"sq ${cls}\" aria-hidden=\"true\"></i>${label}</dt><dd>${n}</dd></div>`;\n }).join(\"\")}</dl>`;\n}\n\nexport function dashboardPage(\n jobs: JobSummary[],\n runsByJob: Map<string, Run[]>,\n now: number,\n base: string,\n checkedAt: number | null,\n lanes: LaneInput[] = jobs.slice(0, BOARD_LANES).map((job) => ({ job, runs: runsByJob.get(job.name) ?? [], complete: true })),\n): string {\n const attention = jobs.filter((j) => j.health !== \"healthy\").length;\n const headline = jobs.length === 0\n ? \"No jobs yet.\"\n : attention === 0\n ? `${jobs.length === 1 ? \"The one job is\" : `All ${jobs.length} jobs are`} healthy.`\n : `${jobs.length} job${jobs.length === 1 ? \"\" : \"s\"}, <b>${attention} needing attention</b>.`;\n\n const rows = jobs.map((job) => {\n const last = job.lastRun;\n const d = job.definition;\n return `<tr>\n<td class=\"job\"><a class=\"name\" href=\"${h(base)}/jobs/${encodeURIComponent(job.name)}\">${escapeName(job.name)}</a>${d.description ? `<span class=\"desc\">${h(d.description)}</span>` : \"\"}</td>\n<td class=\"health\">${healthState(job)}</td>\n<td class=\"nowrap hide-sm\">${d.schedule ? `${h(d.schedule)}${d.timezone ? `<span class=\"tz\">${h(d.timezone)}</span>` : \"\"}` : `<span class=\"muted\">no schedule</span>`}</td>\n<td class=\"nowrap last\">${last ? `${runState(last)} ${stamp(last.startedAt, now)}${last.durationMs !== null ? `<span class=\"sub\">took ${h(formatDuration(last.durationMs))}</span>` : \"\"}` : `<span class=\"muted\">never</span>`}</td>\n<td class=\"nowrap hide-sm\">${job.nextExpectedAt !== null ? `${job.nextExpectedAt < now ? `<span class=\"state warn\">overdue</span> ` : \"\"}${stamp(job.nextExpectedAt, now)}<span class=\"sub\">${h(when(job.nextExpectedAt, now))} UTC</span>` : `<span class=\"muted\">not scheduled</span>`}</td>\n<td class=\"hide-sm\">${sparkline(runsByJob.get(job.name) ?? [])}</td>\n</tr>`;\n }).join(\"\\n\");\n\n const span = { from: now - BOARD_BEHIND_MS, to: now + BOARD_AHEAD_MS, now };\n const body = `\n<header class=\"top\">\n ${brand(base)}\n <div class=\"actions\">\n <span class=\"meta\">${h(clock(now))} UTC${checkedAt ? `, checked ${h(formatRelative(checkedAt, now))}` : \"\"}</span>\n <form class=\"inline\" method=\"post\" action=\"${h(base)}/check\"><button class=\"primary\" type=\"submit\">Run check now</button></form>\n </div>\n</header>\n<main>\n<section class=\"sec\" aria-label=\"Health\">\n <h2>Health</h2>\n <div>\n <p class=\"headline\">${headline}</p>\n ${jobs.length ? healthFigures(jobs) : `<p class=\"empty\">Declare one with <code>cw.job(\"name\", { schedule: \"0 2 * * *\" })</code> and run it once, and it shows up here.</p>`}\n </div>\n</section>\n${jobs.length ? `<section class=\"sec\" aria-label=\"Last 24 hours\">\n <h2>Last 24 hours</h2>\n <p class=\"lede\">One lane per job. Faint ticks mark when it was due, bars the runs it recorded, as long as they took. A dashed box is a slot nothing ran in. Times are UTC.</p>\n <div class=\"wide\">${dayTimeline(lanes, span, base, jobs.length)}</div>\n</section>\n<section class=\"sec\" aria-label=\"Jobs\">\n <h2>Jobs</h2>\n <p class=\"lede\">Every job in the store. Open one for its week, its runs, and their output.</p>\n <div class=\"wide\"><table class=\"board\">\n<thead><tr><th>Job</th><th>Health</th><th class=\"hide-sm\">Schedule</th><th>Last run</th><th class=\"hide-sm\">Next due</th><th class=\"hide-sm\">Recent runs</th></tr></thead>\n<tbody>${rows}</tbody></table></div>\n</section>` : \"\"}\n</main>\n<footer><span>Refreshes every minute. Times are UTC.</span><a href=\"${h(base)}/api/jobs\">JSON</a>${VERSION_LINK}</footer>`;\n return layout(\"CronWatch\", body, base, { refresh: 60 });\n}\n\n/**\n * One job: its state and figures, its last seven days, its runs with their\n * output, and its definition. `complete` is false when `runs` does not reach\n * back over the whole week (the run list shows the newest fifty).\n */\nexport function jobPage(job: JobSummary, runs: Run[], now: number, base: string, complete = true): string {\n const d = job.definition;\n const okRate = `${Math.round(job.stats.okRate * 100)}%`;\n const listed = runs.slice(0, 50);\n const runRows = listed.map((run) => {\n const detail = [\n run.error ? `<details class=\"out error\" open><summary>error</summary><pre>${h(run.error)}</pre></details>` : \"\",\n run.output ? `<details class=\"out\"${run.status === \"ok\" ? \"\" : \" open\"}><summary>output</summary><pre>${h(run.output)}</pre></details>` : \"\",\n ].join(\"\");\n // A foreign row may hold a metric that is no finite number (null, text); it is left out.\n const metrics = Object.entries(run.metrics ?? {})\n .filter(([, v]) => typeof v === \"number\" && Number.isFinite(v))\n .map(([k, v]) => `<span><span class=\"k\">${h(k)}</span> ${h(Number.isInteger(v) ? v : v.toFixed(4))}</span>`).join(\"\");\n return `<tr${detail ? ` class=\"has-detail\"` : \"\"}>\n<td class=\"nowrap\">${runState(run)}</td>\n<td class=\"nowrap\">${h(when(run.startedAt, now))} <span class=\"muted\">UTC</span><span class=\"sub\">${stamp(run.startedAt, now)}</span></td>\n<td class=\"nowrap\">${run.durationMs !== null ? h(formatDuration(run.durationMs)) : `<span class=\"muted\">running</span>`}</td>\n<td class=\"hide-sm\">${metrics ? `<span class=\"metrics\">${metrics}</span>` : \"\"}</td>\n<td class=\"hide-sm muted\">${h(run.trigger)}</td>\n</tr>${detail ? `<tr class=\"detail\"><td colspan=\"5\">${detail}</td></tr>` : \"\"}`;\n }).join(\"\\n\");\n\n const silenced = job.silencedUntil !== null && job.silencedUntil > now;\n const path = `${h(base)}/jobs/${encodeURIComponent(job.name)}`;\n const parsed = parsedSchedule(job);\n const why = laneNote(job, missedAt(job, parsed, [], now), now);\n const body = `\n<header class=\"top\">\n ${brand(base, job.name)}\n <div class=\"actions\"><span class=\"meta\">${h(clock(now))} UTC</span></div>\n</header>\n<main>\n<section class=\"sec intro\" aria-label=\"Job\">\n <h2>Job</h2>\n <div>\n <h1 class=\"jobname\">${escapeName(job.name)}</h1>\n ${d.description ? `<p class=\"desc\">${h(d.description)}</p>` : \"\"}\n <p class=\"stateline\">${healthState(job)}${why ? `<span class=\"why\">${h(why)}</span>` : \"\"}</p>\n <div class=\"actions\">\n ${silenced\n ? `<form class=\"inline\" method=\"post\" action=\"${path}/unsilence\"><button type=\"submit\">Unsilence (until ${h(formatRelative(job.silencedUntil!, now))})</button></form>`\n : `<details class=\"confirm\"><summary>Silence</summary><form class=\"inline\" method=\"post\" action=\"${path}/silence\"><span>for</span> <button type=\"submit\" name=\"for\" value=\"1h\">1 hour</button><button type=\"submit\" name=\"for\" value=\"4h\">4 hours</button><button type=\"submit\" name=\"for\" value=\"1d\">1 day</button><button type=\"submit\" name=\"for\" value=\"7d\">1 week</button></form></details>`}\n </div>\n <dl class=\"figures\">\n <div><dt>Last run</dt><dd>${job.lastRun ? h(formatRelative(job.lastRun.startedAt, now)) : \"never\"}</dd></div>\n <div><dt>Next due</dt><dd>${job.nextExpectedAt !== null ? h(formatRelative(job.nextExpectedAt, now)) : `<small>no schedule</small>`}</dd></div>\n <div><dt>Success, last ${h(job.stats.runs)}</dt><dd>${h(okRate)}</dd></div>\n <div><dt>p50 / p95</dt><dd>${job.stats.p50Ms !== null ? h(formatDuration(job.stats.p50Ms)) : \"?\"} <small>/ ${job.stats.p95Ms !== null ? h(formatDuration(job.stats.p95Ms)) : \"?\"}</small></dd></div>\n </dl>\n </div>\n</section>\n<section class=\"sec\" aria-label=\"Last 7 days\">\n <h2>Last 7 days</h2>\n <p class=\"lede\">A lane per UTC day, today first. Faint ticks mark when the job was due, bars its runs, as long as they took.</p>\n <div class=\"wide\">${weekTimeline(job, runs, complete, now)}</div>\n</section>\n<section class=\"sec\" aria-label=\"Runs\">\n <h2>Runs</h2>\n ${listed.length === 0 ? `<p class=\"lede\">No runs yet.</p>` : `<p class=\"lede\">The newest ${listed.length === 1 ? \"run\" : `${listed.length} runs`}, with any error and output.</p>\n <div class=\"wide\"><table class=\"runs\">\n<thead><tr><th>Status</th><th>Started</th><th>Took</th><th class=\"hide-sm\">Metrics</th><th class=\"hide-sm\">Trigger</th></tr></thead>\n<tbody>${runRows}</tbody></table></div>`}\n</section>\n<section class=\"sec\" aria-label=\"Definition\">\n <h2>Definition</h2>\n <dl class=\"def\">\n <dt>Schedule</dt><dd>${d.schedule ? h(d.schedule) + (d.timezone ? ` <span class=\"muted\">${h(d.timezone)}</span>` : \"\") : `<span class=\"muted\">none</span>`}</dd>\n <dt>Grace</dt><dd>${h(d.grace ?? \"10m\")}</dd>\n <dt>Timeout</dt><dd>${h(d.timeout ?? \"1h\")}</dd>\n ${d.maxDuration ? `<dt>Max duration</dt><dd>${h(d.maxDuration)}</dd>` : \"\"}\n ${d.budget ? `<dt>Budget</dt><dd>${h(Object.entries(d.budget).map(([k, v]) => `${k} ≤ ${v}`).join(\", \"))}</dd>` : \"\"}\n ${d.floor ? `<dt>Floor</dt><dd>${h(Object.entries(d.floor).map(([k, v]) => `${k} ≥ ${v}`).join(\", \"))}</dd>` : \"\"}\n ${d.expect ? `<dt>Expect</dt><dd>${h(d.expect)}</dd>` : \"\"}\n ${d.failuresBeforeAlert && d.failuresBeforeAlert > 1 ? `<dt>Alert after</dt><dd>${h(d.failuresBeforeAlert)} consecutive failures</dd>` : \"\"}\n ${d.tags?.length ? `<dt>Tags</dt><dd>${d.tags.map((t) => h(t)).join(\", \")}</dd>` : \"\"}\n ${job.open.length ? `<dt>Open</dt><dd>${job.open.map((c) => `<span class=\"state ${c === \"failed\" || c === \"stuck\" ? \"bad\" : \"warn\"}\">${h(c.replace(\"_\", \" \"))}</span>`).join(\"\")}</dd>` : \"\"}\n ${job.consecutiveFailures > 0 ? `<dt>Failures in a row</dt><dd>${h(job.consecutiveFailures)}</dd>` : \"\"}\n </dl>\n</section>\n<section class=\"sec delete\" aria-label=\"Delete\">\n <h2>Delete</h2>\n <div>\n <p class=\"lede\">Removes this job and all its runs from the store, which cannot be undone. A job still in your code comes back on its next run, with no history.</p>\n <details class=\"confirm\"><summary>Delete history</summary><form class=\"inline\" method=\"post\" action=\"${path}/forget\"><span>Delete this job and all its runs?</span> <button class=\"danger\" type=\"submit\">Delete</button><a class=\"button\" href=\"${path}\">Cancel</a></form></details>\n </div>\n</section>\n</main>\n<footer><span>Refreshes every minute. Times are UTC.</span><a href=\"${h(base)}/api/jobs/${encodeURIComponent(job.name)}\">JSON</a>${VERSION_LINK}</footer>`;\n return layout(`${job.name}: CronWatch`, body, base, { refresh: 60 });\n}\n\n/**\n * A page with one message. With `signIn`, a form under it posts the token\n * to <base>/signin in the body, keeping it out of the URL and access logs,\n * and the routes set the cookie: the way in\n * where there is no address bar to open a link with, such as an app on an\n * iPhone's home screen, which keeps its cookies apart from Safari's.\n */\nexport function messagePage(title: string, message: string, base: string, signIn = false): string {\n const form = signIn ? `<form class=\"signin\" method=\"post\" action=\"${h(base)}/signin\"><label for=\"token\">Token</label><input id=\"token\" name=\"token\" type=\"password\" autocomplete=\"current-password\" autocapitalize=\"off\" spellcheck=\"false\" required><button class=\"primary\" type=\"submit\">Sign in</button></form>` : \"\";\n return layout(title, `<header class=\"top\">${brand(base)}</header><main class=\"message\"><h1>${h(title)}</h1><p>${h(message)}</p>${form}</main>`, base);\n}\n","import type { Cronwatch } from \"../client.js\";\nimport { isDevelopment, readSecretEnv, secretOption } from \"../env.js\";\nimport { bearerToken, constantTimeEqual, json } from \"../http.js\";\nimport { parseDuration } from \"../duration.js\";\nimport type { Duration, JobSummary, Run } from \"../types.js\";\nimport { dashboardPage, jobPage, messagePage } from \"./html.js\";\nimport { staticAsset, type StaticAsset } from \"./pwa.js\";\nimport { API_VERSION, VERSION } from \"../version.js\";\nimport { BOARD_BEHIND_MS, BOARD_LANES, BOARD_RUNS, weekRunsLimit, type LaneInput } from \"./timeline.js\";\n\nexport interface RoutesOptions {\n /**\n * Required to reach anything. Send it as `Authorization: Bearer <token>`,\n * or open the dashboard once with `?token=<token>` and a cookie is set.\n * Defaults to process.env.CRONWATCH_TOKEN (on Cloudflare Workers, which\n * have no process, pass env.CRONWATCH_TOKEN); an empty string or one of\n * only whitespace, given here or in the variable, counts as unset, and any\n * other type (false, a number) throws.\n * With no token in development (the first of CRONWATCH_ENV, APP_ENV, and\n * NODE_ENV that is set names \"development\", \"dev\", or \"local\"; \"test\" and\n * \"testing\" are not development), the routes make a random one and print a\n * sign-in link to the server log on their first request; with no token\n * otherwise they answer 503. Pass `null` to opt out\n * and serve them open everywhere, for example behind your own auth.\n *\n * The check endpoint (/api/check) also accepts the client's cronSecret, so\n * a platform cron that sends `Authorization: Bearer <CRON_SECRET>` can\n * trigger checks without knowing the dashboard token.\n */\n token?: string | null;\n /** Where the routes are mounted, so links resolve. Default \"/cronwatch\". */\n basePath?: string;\n /**\n * The public origin the dashboard is served from, such as\n * \"https://app.example.com\", for an app behind a proxy whose request URLs\n * carry an internal host or scheme. Used in place of the request URL's\n * origin for the cross-site check on writes, the sign-in redirect (its\n * cookie is Secure when this is https, and the redirect back after a form\n * follows a Referer on this origin), and the development sign-in line.\n * Takes precedence over trustProxy. Without it, the development sign-in\n * line shows the request's origin only when its host is loopback\n * (localhost, *.localhost, 127.0.0.0/8, or ::1), and otherwise leaves the\n * host out, since a client controls it.\n */\n origin?: string;\n /**\n * Take the public origin from X-Forwarded-Proto and X-Forwarded-Host (the\n * first value of each, falling back to the request URL's scheme or host\n * for whichever is missing) when a request carries either. Only for an app\n * whose proxy sets or overwrites both headers: a client can send them too.\n * Default false, which ignores them.\n */\n trustProxy?: boolean;\n}\n\nexport type FetchHandler = (request: Request) => Promise<Response>;\n\nexport interface Routes {\n handler: FetchHandler;\n GET: FetchHandler;\n POST: FetchHandler;\n DELETE: FetchHandler;\n}\n\nconst COOKIE = \"cronwatch_token\";\n/**\n * What GET <base>/api says is serving it: the package, as its registry names\n * it, and the language. Each port answers with its own.\n */\nconst LIBRARY = \"@cronwatch/sdk\";\nconst LANGUAGE = \"typescript\";\n\n/**\n * The cookie holds a digest of the token, so a leaked cookie does not reveal\n * the bearer token itself: the SHA-256 of \"cronwatch-cookie:<token>\", as hex.\n * Web Crypto, so the routes need nothing from node: and run on Workers too.\n */\nasync function cookieValue(token: string): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(`cronwatch-cookie:${token}`));\n return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nconst DEFAULT_RUNS = 20;\nconst MAX_RUNS = 500;\n/** Runs per job the board reads in one go: the table's sparkline, and most jobs' lanes. */\nconst BOARD_PAGE_RUNS = 20;\n\n/**\n * The board's timeline lanes, the first BOARD_LANES jobs. The runs already\n * read for the table usually cover the last day; only a job whose twenty\n * newest runs all fall inside it (one that runs more often than every hour or so) is\n * read again, deeper, and those reads go out together.\n */\nasync function boardLanes(cw: Cronwatch, entries: { job: JobSummary; runs: Run[] }[], now: number): Promise<LaneInput[]> {\n const from = now - BOARD_BEHIND_MS;\n return Promise.all(entries.slice(0, BOARD_LANES).map(async ({ job, runs }) => {\n const short = runs.length >= BOARD_PAGE_RUNS && runs[runs.length - 1]!.startedAt > from;\n if (!short) return { job, runs, complete: true };\n const deeper = await cw.runs(job.name, BOARD_RUNS);\n return { job, runs: deeper, complete: deeper.length < BOARD_RUNS };\n }));\n}\n\n// 'self' only for what the app shell needs: app.js (which registers the\n// service worker and the theme toggle), the manifest, the worker, and the icons.\n// No inline script, and the pages work without any.\nconst CSP = \"default-src 'none'; script-src 'self'; style-src 'unsafe-inline'; img-src 'self' data:; manifest-src 'self'; worker-src 'self'; form-action 'self'; frame-ancestors 'none'; base-uri 'none'\";\n/** For the SVG icons, should one be opened on its own. */\nconst ASSET_CSP = \"default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'none'\";\n// same-origin rather than no-referrer: under no-referrer browsers send\n// `Origin: null` on form posts, which the CSRF check would refuse, and the\n// forms redirect back to the page named by the same-origin Referer.\nconst SECURITY_HEADERS = { \"x-content-type-options\": \"nosniff\", \"referrer-policy\": \"same-origin\", \"x-robots-tag\": \"noindex\" };\n\n/**\n * A token for one routes instance in development, when none is configured:\n * 32 random bytes, base64url (43 characters).\n */\nfunction developmentToken(): string {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n return btoa(String.fromCharCode(...bytes)).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/**\n * The line a development token is announced with, printed once with\n * console.info on the routes' first request:\n *\n * [cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: <origin><base>/?token=<token>\n *\n * <origin> is the `origin` option when set. Otherwise it is the first\n * request's public origin (scheme, host, and any port: the forwarded one\n * under trustProxy, else the request URL's), but only when its host is\n * loopback (\"localhost\", a name ending in \".localhost\", 127.0.0.0/8, or\n * ::1). That host comes from the request, which a client controls, so for\n * any other host the line leaves it out, and a spoofed first request cannot\n * point the link, token and all, somewhere else:\n *\n * [cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: <base>/?token=<token> on this server (the first request's host is not local, so the link leaves it out)\n *\n * <base> is the base path without a trailing slash (\"\" when mounted at the\n * root), and <token> the token as generated (base64url, so nothing needs\n * escaping).\n */\nfunction developmentSignInLine(origin: string | null, base: string, token: string): string {\n const intro = \"[cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: \";\n return origin === null\n ? `${intro}${base}/?token=${token} on this server (the first request's host is not local, so the link leaves it out)`\n : `${intro}${origin}${base}/?token=${token}`;\n}\n\n/**\n * Whether an origin's host is loopback: \"localhost\", a name ending in\n * \".localhost\", an IPv4 address in 127.0.0.0/8, or the IPv6 address ::1.\n */\nfunction isLoopbackOrigin(origin: string): boolean {\n let host: string;\n try {\n host = new URL(origin).hostname.toLowerCase();\n } catch {\n return false;\n }\n if (host === \"localhost\" || host.endsWith(\".localhost\")) return true;\n if (host === \"[::1]\") return true;\n const octets = /^127\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(host);\n return octets !== null && octets.slice(1).every((o) => Number(o) <= 255);\n}\n\nfunction safeDecode(value: string): string | null {\n try {\n return decodeURIComponent(value);\n } catch {\n return null;\n }\n}\n\nfunction readCookie(request: Request, name: string): string | null {\n const header = request.headers.get(\"cookie\");\n if (!header) return null;\n for (const part of header.split(\";\")) {\n const [k, ...rest] = part.trim().split(\"=\");\n // A malformed escape counts as no cookie.\n if (k === name) return safeDecode(rest.join(\"=\"));\n }\n return null;\n}\n\n/** The first entry of a comma-separated header, trimmed, or null when there is none. */\nfunction firstValue(value: string | null): string | null {\n const first = value?.split(\",\")[0]?.trim();\n return first ? first : null;\n}\n\n/**\n * The origin configured with `origin`, normalised, or null. Throws on a value\n * that is not an http or https origin, so a typo fails at startup.\n */\nfunction configuredOrigin(value: string | undefined): string | null {\n if (value === undefined || value === \"\") return null;\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new Error(`routes: origin must be an absolute URL such as \"https://app.example.com\", got ${JSON.stringify(value)}`);\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") throw new Error(`routes: origin must be http or https, got ${JSON.stringify(value)}`);\n return url.origin;\n}\n\n/**\n * The origin a browser sees for this request, with trustProxy: the forwarded\n * scheme and host when present and well formed, otherwise the request URL's own.\n */\nfunction forwardedOrigin(request: Request, url: URL): string {\n const proto = firstValue(request.headers.get(\"x-forwarded-proto\"))?.toLowerCase() ?? null;\n const host = firstValue(request.headers.get(\"x-forwarded-host\"));\n if (proto === null && host === null) return url.origin;\n if (proto !== null && proto !== \"http\" && proto !== \"https\") return url.origin;\n try {\n const built = new URL(`${proto ?? url.protocol.slice(0, -1)}://${host ?? url.host}`);\n // A \"host\" carrying a path, credentials, a query, or a fragment is not a host.\n if (built.pathname !== \"/\" || built.username || built.password || built.search || built.hash) return url.origin;\n return built.origin;\n } catch {\n return url.origin;\n }\n}\n\n/**\n * The token an Authorization header carries: what follows the scheme when\n * the scheme is Bearer (any case) and one or more whitespace characters\n * follow it, else null. Any other scheme (a proxy's Basic auth, say) is not\n * a bearer at all, so the cookie and ?token= are read as if no header came.\n */\n/**\n * Where a sign-in through the form goes next: the page it was posted from\n * (the Referer) when that is on the public origin and its query has no\n * `token` parameter, else the dashboard.\n */\nfunction signInReturn(referer: string | null, publicOrigin: string, base: string): string {\n if (referer === null || !referer.startsWith(publicOrigin + \"/\")) return `${base}/`;\n let url: URL;\n try {\n url = new URL(referer);\n } catch {\n return `${base}/`;\n }\n return url.searchParams.has(\"token\") ? `${base}/` : referer;\n}\n\n/**\n * The path below the base, or null when the request is not under it. The\n * pathname, its dot segments already resolved by URL, must be the base or\n * start with the base and a \"/\": \"/cronwatchapi/jobs\" is not under\n * \"/cronwatch\", and neither is \"/cronwatch/../api/jobs\" (read as \"/api/jobs\").\n * An empty base, for routes mounted at the root, takes every path.\n */\nfunction stripBase(pathname: string, base: string): string | null {\n if (base !== \"\" && pathname !== base && !pathname.startsWith(`${base}/`)) return null;\n let path = pathname.slice(base.length);\n if (path === \"\") path = \"/\";\n if (path.length > 1 && path.endsWith(\"/\")) path = path.slice(0, -1);\n return path;\n}\n\n/** The most of a request body the routes read (1 MiB), as every port's; a body past it is answered 413. */\nconst MAX_REQUEST_BODY = 1 << 20;\n\n/** A request body past MAX_REQUEST_BODY. */\nconst TOO_LARGE = Symbol(\"too large\");\nconst BAD_BODY = Symbol(\"malformed body\");\n\n/**\n * The request's body, at most MAX_REQUEST_BODY bytes: refused from its\n * Content-Length when that says more, else read one byte past the cap at\n * most, so a client cannot make the server hold a body of any size. Its\n * forms and JSON are a few bytes.\n */\nasync function readLimited(request: Request): Promise<Uint8Array<ArrayBuffer> | typeof TOO_LARGE> {\n const length = Number(request.headers.get(\"content-length\"));\n if (Number.isFinite(length) && length > MAX_REQUEST_BODY) return TOO_LARGE;\n if (!request.body) return new Uint8Array(new ArrayBuffer(0));\n const reader = request.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > MAX_REQUEST_BODY) {\n await reader.cancel().catch(() => {});\n return TOO_LARGE;\n }\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n const out = new Uint8Array(new ArrayBuffer(size));\n let at = 0;\n for (const chunk of chunks) {\n out.set(chunk, at);\n at += chunk.byteLength;\n }\n return out;\n}\n\n/** The fields of a JSON or form body, {} for anything else; TOO_LARGE past the cap. */\nasync function readBody(request: Request): Promise<Record<string, string> | typeof TOO_LARGE | typeof BAD_BODY> {\n const type = request.headers.get(\"content-type\") ?? \"\";\n const json = type.includes(\"application/json\");\n const form = type.includes(\"application/x-www-form-urlencoded\") || type.includes(\"multipart/form-data\");\n if (!json && !form) return {};\n let bytes: Uint8Array<ArrayBuffer> | typeof TOO_LARGE;\n try {\n bytes = await readLimited(request);\n } catch {\n return {};\n }\n if (bytes === TOO_LARGE) return TOO_LARGE;\n // Parsed as the request itself would parse it, from the bytes read.\n const copy = new Request(request.url, { method: \"POST\", headers: { \"content-type\": type }, body: bytes });\n try {\n if (json) {\n const data = await copy.json();\n return typeof data === \"object\" && data !== null && !Array.isArray(data) ? Object.fromEntries(Object.entries(data).map(([k, v]) => [k, String(v)])) : BAD_BODY;\n }\n const fields = await copy.formData();\n const out: Record<string, string> = {};\n for (const [k, v] of fields.entries()) out[k] = String(v);\n return out;\n } catch {\n return BAD_BODY;\n }\n}\n\n/**\n * A browser attaches Origin or Sec-Fetch-Site to a cross-site form post, and\n * a page cannot forge either. Non-browser clients send neither.\n */\nfunction crossSite(request: Request, publicOrigin: string): boolean {\n const origin = request.headers.get(\"origin\");\n if (origin !== null && origin !== publicOrigin) return true;\n const site = request.headers.get(\"sec-fetch-site\");\n return site !== null && site !== \"same-origin\" && site !== \"none\";\n}\n\n/** Absent means one hour; a number or numeric string is milliseconds. Throws on anything else. */\nfunction silenceDuration(value: string | null | undefined): Duration {\n if (value === undefined || value === null) return \"1h\";\n const text = value.trim();\n const duration: Duration = /^\\d+(\\.\\d+)?$/.test(text) ? Number(text) : text;\n parseDuration(duration, \"silence duration\");\n return duration;\n}\n\nfunction runsLimit(value: string | null): number {\n const n = value === null || value.trim() === \"\" ? NaN : Math.trunc(Number(value));\n return Number.isFinite(n) ? Math.min(MAX_RUNS, Math.max(1, n)) : DEFAULT_RUNS;\n}\n\n/**\n * The dashboard and its JSON API for a client.\n * @deprecated Use `cw.routes(options)`, the one way to mount the dashboard\n * in every port. This name still works through 1.x and goes in 2.0.\n */\nexport function createRoutes(cw: Cronwatch, options: RoutesOptions = {}): Routes {\n return cw.routes(options);\n}\n\n/**\n * A fetch-style handler serving the dashboard and a small JSON API, which\n * cw.routes() returns. Mount it in a Next.js app at\n * app/cronwatch/[[...path]]/route.ts:\n *\n * export const { GET, POST, DELETE } = cw.routes();\n */\nexport function buildRoutes(cw: Cronwatch, options: RoutesOptions = {}): Routes {\n const optedOut = options.token === null;\n // A blank token, given or read, counts as unset; one given that is not a string throws.\n const given = secretOption(options.token, \"routes: token\");\n const configured = optedOut ? null : (given || readSecretEnv(\"CRONWATCH_TOKEN\") || null);\n const base = (options.basePath ?? \"/cronwatch\").replace(/\\/+$/, \"\");\n const developing = isDevelopment();\n const fixedOrigin = configuredOrigin(options.origin);\n const trustProxy = options.trustProxy === true;\n const originOf = (request: Request, url: URL): string =>\n fixedOrigin ?? (trustProxy ? forwardedOrigin(request, url) : url.origin);\n // A fetch handler cannot tell a local caller from a remote one (proxies,\n // tunnels, and `next dev` listening on every interface all look alike), so\n // development gets a token too: made here, and shown only in the server log.\n const generated = !configured && !optedOut && developing;\n const token = generated ? developmentToken() : configured;\n let announced = false;\n // Worked out on the first request that needs it, then kept.\n let cookie: Promise<string> | null = null;\n const expectedCookie = (value: string) => (cookie ??= cookieValue(value));\n\n const serve = async (request: Request, url: URL, path: string, wantsHtml: boolean): Promise<Response> => {\n const method = request.method.toUpperCase();\n const publicOrigin = originOf(request, url);\n\n if (generated && !announced) {\n announced = true;\n const shown = fixedOrigin ?? (isLoopbackOrigin(publicOrigin) ? publicOrigin : null);\n console.info(developmentSignInLine(shown, base, token!));\n }\n\n // The app shell: the manifest, icons, service worker, app.js, and the\n // offline page. Served to anyone, since a browser fetches some of it\n // without cookies and none of it says anything about the jobs.\n if (method === \"GET\" || method === \"HEAD\") {\n if (path === \"/offline\") {\n return html(messagePage(\"You are offline\", \"CronWatch shows live data from your app, so it needs a connection.\", base), 200, \"no-cache\");\n }\n const asset = staticAsset(path, base);\n if (asset) return shell(asset, base);\n }\n\n // No token outside development: fail closed.\n if (!token && !optedOut) {\n return wantsHtml\n ? html(messagePage(\"CronWatch routes are locked\", \"Set CRONWATCH_TOKEN (or pass token to cw.routes()), or pass token: null to serve them open behind your own auth.\", base), 503)\n : api({ ok: false, error: \"CRONWATCH_TOKEN is not set\" }, 503);\n }\n\n if (method !== \"GET\" && method !== \"HEAD\" && crossSite(request, publicOrigin)) {\n return wantsHtml\n ? html(messagePage(\"Cross-site request refused\", \"Changes can only be made from the dashboard itself.\", base), 403)\n : api({ ok: false, error: \"Cross-site request refused\" }, 403);\n }\n\n const bearer = bearerToken(request.headers.get(\"authorization\"));\n const signInCookie = async () => {\n const secure = publicOrigin.startsWith(\"https:\") ? \"; Secure\" : \"\";\n return `${COOKIE}=${await expectedCookie(token!)}; Path=${base || \"/\"}; HttpOnly; SameSite=Lax; Max-Age=${60 * 60 * 24 * 30}${secure}`;\n };\n const signInPage = () => generated\n ? html(messagePage(\"Sign in\", \"CRONWATCH_TOKEN is not set, so this development server made a token. The sign-in link is in the server log: open it once, or enter the token from it below, and this browser stays signed in.\", base, true), 401)\n : html(messagePage(\"Sign in\", \"Enter your CRONWATCH_TOKEN and this browser stays signed in.\", base, true), 401);\n\n // The sign-in form posts the token here, in the body, so it stays out of\n // the URL and every access log. Cross-site posts were refused above.\n if (token && method === \"POST\" && path === \"/signin\") {\n const body = await readBody(request);\n if (body === BAD_BODY) return html(messagePage(\"Bad request\", \"Malformed request body\", base), 400);\n const sent = body === TOO_LARGE ? undefined : body.token;\n if (sent === undefined || !constantTimeEqual(sent, token)) return signInPage();\n return redirect(signInReturn(request.headers.get(\"referer\"), publicOrigin, base), { \"set-cookie\": await signInCookie() });\n }\n\n if (token) {\n // ?token= is only the sign-in that moves the token into a cookie.\n const query = wantsHtml && method === \"GET\" ? url.searchParams.get(\"token\") : null;\n const sent = readCookie(request, COOKIE);\n const isCheck = path === \"/api/check\";\n const cronSecretOk = isCheck && bearer !== null && cw.cronSecret !== null && constantTimeEqual(bearer, cw.cronSecret);\n const tokenOk =\n bearer !== null ? constantTimeEqual(bearer, token)\n : query !== null ? constantTimeEqual(query, token)\n : sent !== null && constantTimeEqual(sent, await expectedCookie(token));\n if (!cronSecretOk && !tokenOk) {\n if (wantsHtml) return signInPage();\n return generated\n ? api({ ok: false, error: \"Unauthorized: CRONWATCH_TOKEN is not set, so this development server made a token; it is in the server log\" }, 401)\n : api({ ok: false, error: \"Unauthorized\" }, 401);\n }\n if (query !== null) {\n // Move the token from the URL into a cookie, so it is not left in the\n // browser's history. The request line that carried it may still be in\n // an access log, which is why the sign-in form posts instead.\n url.searchParams.delete(\"token\");\n // One leading slash: \"//host/...\" would be a protocol-relative Location, off this site.\n return redirect(url.pathname.replace(/^\\/+/, \"/\") + (url.search || \"\"), { \"set-cookie\": await signInCookie() });\n }\n }\n\n const redirectBack = () => {\n const referer = request.headers.get(\"referer\") ?? \"\";\n return redirect(referer.startsWith(publicOrigin + \"/\") ? referer : `${base}/`);\n };\n const decoded = path.split(\"/\").filter(Boolean).map(safeDecode);\n if (decoded.some((part) => part === null)) {\n return wantsHtml ? html(messagePage(\"Bad request\", \"The path is not valid.\", base), 400) : api({ ok: false, error: \"Bad path\" }, 400);\n }\n const parts = decoded as string[];\n\n // HTML\n // A HEAD reads what a GET would; the handler sends it without a body.\n const reads = method === \"GET\" || method === \"HEAD\";\n if (reads && path === \"/\") {\n const entries = await cw.jobsWithRuns(BOARD_PAGE_RUNS);\n const now = cw.now();\n const runsByJob = new Map<string, Run[]>(entries.map((entry) => [entry.job.name, entry.runs]));\n return html(dashboardPage(entries.map((entry) => entry.job), runsByJob, now, base, null, await boardLanes(cw, entries, now)));\n }\n if (reads && parts[0] === \"jobs\" && parts.length === 2) {\n const job = await cw.jobSummary(parts[1]!);\n if (!job) return html(messagePage(\"No such job\", `${parts[1]} is not in the store.`, base), 404);\n const now = cw.now();\n // Enough runs to draw the job's week; the page lists the newest fifty.\n const limit = weekRunsLimit(job, now);\n const runs = await cw.runs(job.name, limit);\n return html(jobPage(job, runs, now, base, runs.length < limit));\n }\n if (method === \"POST\" && path === \"/check\") {\n await cw.check();\n return redirectBack();\n }\n if (method === \"POST\" && parts[0] === \"jobs\" && parts.length === 3) {\n const name = parts[1]!;\n if (parts[2] === \"forget\") {\n await cw.forget(name);\n return redirect(`${base}/`);\n }\n if (parts[2] !== \"silence\" && parts[2] !== \"unsilence\") return html(messagePage(\"Not found\", path, base), 404);\n if (!(await cw.jobSummary(name))) return html(messagePage(\"No such job\", `${name} is not in the store.`, base), 404);\n if (parts[2] === \"silence\") {\n const body = await readBody(request);\n if (body === TOO_LARGE) return html(messagePage(\"Not silenced\", \"The request was too large.\", base), 413);\n if (body === BAD_BODY) return html(messagePage(\"Not silenced\", \"Malformed request body\", base), 400);\n let duration: Duration;\n try {\n duration = silenceDuration(body.for);\n } catch (e) {\n return html(messagePage(\"Not silenced\", (e as Error).message, base), 400);\n }\n await cw.silence(name, duration);\n } else await cw.unsilence(name);\n return redirectBack();\n }\n\n // JSON API\n if (parts[0] === \"api\") {\n const rest = parts.slice(1);\n // What is serving the API, so a client such as @cronwatch/mcp can tell.\n if (reads && rest.length === 0) {\n return api({ ok: true, library: LIBRARY, language: LANGUAGE, version: VERSION, api: API_VERSION });\n }\n if (reads && rest[0] === \"jobs\" && rest.length === 1) {\n return api({ ok: true, jobs: await cw.jobs() });\n }\n if (rest[0] === \"jobs\" && rest.length === 2) {\n const name = rest[1]!;\n if (reads) {\n const job = await cw.jobSummary(name);\n if (!job) return api({ ok: false, error: \"No such job\" }, 404);\n return api({ ok: true, job, runs: await cw.runs(name, runsLimit(url.searchParams.get(\"runs\"))) });\n }\n if (method === \"DELETE\") {\n if (!(await cw.jobSummary(name))) return api({ ok: false, error: \"No such job\" }, 404);\n await cw.forget(name);\n return api({ ok: true });\n }\n }\n if (method === \"POST\" && rest[0] === \"jobs\" && rest.length === 3) {\n const name = rest[1]!;\n if (!(await cw.jobSummary(name))) return api({ ok: false, error: \"No such job\" }, 404);\n if (rest[2] === \"silence\") {\n const body = await readBody(request);\n if (body === TOO_LARGE) return api({ ok: false, error: \"Request body too large\" }, 413);\n if (body === BAD_BODY) return api({ ok: false, error: \"Malformed request body\" }, 400);\n let duration: Duration;\n try {\n duration = silenceDuration(body.for ?? url.searchParams.get(\"for\"));\n } catch (e) {\n return api({ ok: false, error: (e as Error).message }, 400);\n }\n await cw.silence(name, duration);\n return api({ ok: true, job: await cw.jobSummary(name) });\n }\n if (rest[2] === \"unsilence\") {\n await cw.unsilence(name);\n return api({ ok: true, job: await cw.jobSummary(name) });\n }\n }\n if (rest[0] === \"check\" && rest.length === 1) {\n // A page cannot send an Authorization header cross-site, so a GET\n // may only run the check when it carries a bearer (token or cron secret).\n if (method === \"GET\" && bearer === null) {\n return api({ ok: false, error: \"Use POST, or GET with an Authorization bearer\" }, 405, { allow: \"POST\" });\n }\n if (method === \"GET\" || method === \"POST\") {\n const result = await cw.check();\n return api({ ok: true, ...result });\n }\n }\n if (reads && rest[0] === \"runs\" && rest.length === 2) {\n const run = await cw.getRun(rest[1]!);\n return run ? api({ ok: true, run }) : api({ ok: false, error: \"No such run\" }, 404);\n }\n return api({ ok: false, error: \"Not found\" }, 404);\n }\n\n return html(messagePage(\"Not found\", path, base), 404);\n };\n\n const handler: FetchHandler = async (request) => {\n let wantsHtml = true;\n try {\n const url = new URL(request.url);\n const path = stripBase(url.pathname, base);\n // Not under the base at all: nothing here answers it, signed in or not.\n if (path === null) return html(messagePage(\"Not found\", url.pathname, base), 404);\n wantsHtml = !path.startsWith(\"/api\");\n const response = await serve(request, url, path, wantsHtml);\n return request.method.toUpperCase() === \"HEAD\" ? new Response(null, { status: response.status, headers: response.headers }) : response;\n } catch (e) {\n try {\n cw.onError(e, \"routes\");\n } catch {\n // An onError that throws must not turn a 500 into an unhandled rejection.\n }\n return wantsHtml\n ? html(messagePage(\"Something went wrong\", \"The request failed and the error was reported.\", base), 500)\n : api({ ok: false, error: \"Internal error\" }, 500);\n }\n };\n\n return { handler, GET: handler, POST: handler, DELETE: handler };\n}\n\nfunction api(body: unknown, status = 200, headers: Record<string, string> = {}): Response {\n return json(body, status, { ...SECURITY_HEADERS, ...headers });\n}\n\nfunction redirect(location: string, headers: Record<string, string> = {}): Response {\n return new Response(null, { status: 303, headers: { location, \"cache-control\": \"no-store\", ...SECURITY_HEADERS, ...headers } });\n}\n\n/**\n * An app shell file. The worker may be scoped to the base (it is served from\n * there anyway); the SVGs get a CSP of their own.\n */\nfunction shell(asset: StaticAsset, base: string): Response {\n const headers: Record<string, string> = { \"content-type\": asset.type, \"cache-control\": asset.cache, ...SECURITY_HEADERS };\n if (asset.type === \"image/svg+xml\") headers[\"content-security-policy\"] = ASSET_CSP;\n if (asset.worker) headers[\"service-worker-allowed\"] = `${base}/`;\n return new Response(asset.body, { status: 200, headers });\n}\n\nfunction html(body: string, status = 200, cache = \"no-store\"): Response {\n return new Response(body, {\n status,\n headers: {\n \"content-type\": \"text/html; charset=utf-8\",\n \"cache-control\": cache,\n \"content-security-policy\": CSP,\n \"x-frame-options\": \"DENY\",\n ...SECURITY_HEADERS,\n },\n });\n}\n","import { stateVersion } from \"../evaluate.js\";\nimport { stripJsonNul, stripNul } from \"../output.js\";\nimport type { JobState, Run, Store, StoredJob, StoredJobDefinition } from \"../types.js\";\n\n/**\n * Keeps everything in process memory. The default when no store is given,\n * good for tests and for trying the library out. State is gone on restart,\n * so a missed run cannot be noticed across one.\n */\nexport function memory(): Store & Required<Pick<Store, \"lastRun\">> {\n const jobs = new Map<string, StoredJob>();\n const runs = new Map<string, Run>();\n const order = new Map<string, number>();\n const states = new Map<string, JobState>();\n let seq = 0;\n\n const clone = <T>(v: T): T => JSON.parse(JSON.stringify(v));\n // Text is held as the SQL stores write it (see params in stores/sql.ts),\n // without U+0000, so every store reads back the same.\n const kept = <T>(v: T): T => JSON.parse(stripJsonNul(JSON.stringify(v)));\n const keptRun = (run: Run): Run => ({\n ...clone(run),\n trigger: stripNul(run.trigger),\n output: run.output === null ? null : stripNul(run.output),\n error: run.error === null ? null : stripNul(run.error),\n metrics: kept(run.metrics),\n });\n // Code unit order, as the SQL stores sort by bytes rather than by locale.\n const byName = (a: StoredJob, b: StoredJob) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0);\n\n return {\n async upsertJob(definition: StoredJobDefinition, now: number) {\n const existing = jobs.get(definition.name);\n jobs.set(definition.name, {\n name: definition.name,\n definition: kept(definition),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n });\n },\n async getJob(name) {\n const j = jobs.get(name);\n return j ? clone(j) : null;\n },\n async listJobs() {\n return [...jobs.values()].map(clone).sort(byName);\n },\n async deleteJob(name) {\n jobs.delete(name);\n states.delete(name);\n for (const [id, run] of runs) if (run.job === name) { runs.delete(id); order.delete(id); }\n },\n async insertRun(run) {\n // Like SQL's primary key: an id already recorded is refused, never overwritten.\n if (runs.has(run.id)) throw new Error(`run ${run.id} already exists`);\n runs.set(run.id, keptRun(run));\n order.set(run.id, ++seq);\n },\n async updateRun(run) {\n // Like SQL's UPDATE: a run that is gone (its job was forgotten) stays gone, and only these fields change.\n const existing = runs.get(run.id);\n if (!existing) return;\n const { status, finishedAt, durationMs, error, output, metrics } = keptRun(run);\n runs.set(run.id, { ...existing, status, finishedAt, durationMs, error, output, metrics });\n },\n async updateRunIf(run, fromStatuses) {\n const existing = runs.get(run.id);\n if (!existing || !fromStatuses.includes(existing.status)) return false;\n const { status, finishedAt, durationMs, error, output, metrics } = keptRun(run);\n runs.set(run.id, { ...existing, status, finishedAt, durationMs, error, output, metrics });\n return true;\n },\n async getRun(id) {\n const r = runs.get(id);\n return r ? clone(r) : null;\n },\n async listRuns(job, limit) {\n return [...runs.values()]\n .filter((r) => r.job === job)\n .sort((a, b) => b.startedAt - a.startedAt || order.get(b.id)! - order.get(a.id)!)\n .slice(0, limit)\n .map(clone);\n },\n async lastRun(job) {\n const list = await this.listRuns(job, 1);\n return list[0] ?? null;\n },\n async runningRuns() {\n return [...runs.values()]\n .filter((r) => r.status === \"running\")\n .sort((a, b) => a.startedAt - b.startedAt || order.get(a.id)! - order.get(b.id)!)\n .map(clone);\n },\n async getState(job) {\n const s = states.get(job);\n return s ? clone(s) : null;\n },\n async setState(state) {\n states.set(state.job, kept(state));\n },\n async compareAndSetState(state, expectedVersion) {\n if (stateVersion(states.get(state.job)) !== expectedVersion) return false;\n states.set(state.job, kept(state));\n return true;\n },\n async prune(before) {\n // Each job's newest run is kept whatever its age: without it, a job\n // that runs less often than the retention looks like it never ran.\n const newest = new Map<string, number>();\n for (const run of runs.values()) newest.set(run.job, Math.max(newest.get(run.job) ?? -Infinity, run.startedAt));\n let n = 0;\n for (const [id, run] of runs) {\n if (run.status !== \"running\" && run.startedAt < before && run.startedAt < newest.get(run.job)!) {\n runs.delete(id);\n order.delete(id);\n n++;\n }\n }\n return n;\n },\n };\n}\n","import { formatDuration, parseDuration } from \"./duration.js\";\nimport { isDevelopment, isProduction, readSecretEnv, secretOption } from \"./env.js\";\nimport {\n afterSend,\n applySilence,\n channelKeys,\n BASELINE_WINDOW,\n claimUndelivered,\n emptyState,\n hasFullBaseline,\n holdAlerts,\n holdRun,\n isStranded,\n isStuck,\n MAX_UNDELIVERED,\n normalizeState,\n onCheck,\n onRunFinish,\n onRunStart,\n owedChannels,\n recordSent,\n releaseRun,\n releaseSending,\n runDuration,\n SEND_LEASE_MS,\n silenceEnd,\n stateVersion,\n summarize,\n timeoutMs,\n unevaluableSummary,\n withoutOwed,\n} from \"./evaluate.js\";\nimport type { Evaluation } from \"./evaluate.js\";\nimport { composeAlert } from \"./format.js\";\nimport { bearerToken, constantTimeEqual, json } from \"./http.js\";\nimport { createRecorder } from \"./job.js\";\nimport type { JobContext } from \"./job.js\";\nimport { capOutput, describeError, OUTPUT_CAP, redactAndCap, redactSecrets, stripNul } from \"./output.js\";\nimport { parseSchedule } from \"./schedule.js\";\nimport { checkExpectation, readStoredJob, toStored } from \"./serialize.js\";\nimport { buildRoutes } from \"./routes/index.js\";\nimport type { Routes, RoutesOptions } from \"./routes/index.js\";\nimport { memory } from \"./stores/memory.js\";\nimport type {\n Alert,\n AlertChannel,\n HeldAlert,\n CheckResult,\n Condition,\n Duration,\n JobDefinition,\n JobOptions,\n JobState,\n JobSummary,\n Run,\n Store,\n StoredJob,\n StoredJobDefinition,\n TriageFn,\n} from \"./types.js\";\n\nexport type JobFn<T> = (job: JobContext) => Promise<T> | T;\nexport type HandlerFn<T> = (job: JobContext, request: Request) => Promise<T> | T;\n\nexport interface HandlerOptions {\n /**\n * Callers must send `Authorization: Bearer <secret>`. Defaults to the\n * client's cronSecret, which defaults to process.env.CRON_SECRET (what\n * Vercel sends its cron requests with). An empty string, or one of only\n * whitespace, counts as unset; any other type (false, a number) throws.\n * With no secret at all the handler answers 503 unless the app is in\n * development (the first of CRONWATCH_ENV, APP_ENV, and NODE_ENV that is\n * set names \"development\", \"dev\", or \"local\"; \"test\" and \"testing\" are not\n * development, so a test run or CI needs a secret too). Pass null to allow\n * anyone.\n */\n secret?: string | null;\n}\n\nexport interface JobHandle {\n readonly name: string;\n readonly definition: JobDefinition;\n /** Run the function now, recording the run. Rethrows whatever the function throws. */\n run<T>(fn: JobFn<T>, options?: { trigger?: string }): Promise<T>;\n /** A fetch-style request handler (Next.js route, Hono, Bun, Deno) that runs the function and records the run. */\n handler<T>(fn: HandlerFn<T>, options?: HandlerOptions): (request: Request) => Promise<Response>;\n /**\n * Record a running run now and finish it later, perhaps from another\n * process (see resume()). Store failures go to onError; it never throws for\n * them. A run that is never finished is marked stuck by the first check\n * after the job's timeout.\n */\n start(options?: StartOptions): Promise<RunHandle>;\n /** A handle on a run this job started elsewhere, by its id, so this process can log to it and finish it. */\n resume(runId: string): Promise<RunHandle>;\n}\n\nexport interface StartOptions {\n /** What started the run, as with run(). Default \"start\". */\n trigger?: string;\n /**\n * Your own stable id for the run, such as an Inngest run id, 1 to 200\n * characters, not starting with \"pgcron:\" (the pg_cron source's). A start\n * with an id already recorded for this job records nothing and returns a\n * handle on that run instead; an id recorded for another job throws,\n * whether that job's start is still in flight or long done.\n */\n id?: string;\n}\n\n/**\n * How a started run ended. `{ error }` is a failure, recorded like an error\n * run() caught. Otherwise the run succeeded, and `result` (or a string\n * passed on its own) is treated like the value run()'s function returns:\n * a string is the output when nothing was logged, `expect` is checked, and\n * a Response with status 400 or above is a failure.\n */\nexport type RunOutcome = { status?: \"ok\"; result?: unknown } | { error: unknown };\n\n/** A run recorded by job.start() or found by job.resume(), to finish later. */\nexport interface RunHandle {\n readonly id: string;\n readonly job: string;\n /** When the run started; null when a resumed run could not be read. */\n readonly startedAt: number | null;\n /** False once finished, and from the start for a resumed run that already finished or does not exist. */\n readonly active: boolean;\n /** Add a line of output. Kept in the handle until flush() or finish(). */\n log(...parts: unknown[]): void;\n /** Report a number for this run. A later value for the same name replaces an earlier one. */\n metric(name: string, value: number): void;\n metrics(values: Record<string, number>): void;\n /**\n * Append the lines and metrics added so far to the stored run, which must\n * still be running and belong to this job. A read, change, and write of the\n * run's row, written only while it is still running: two processes\n * appending to one run at the same moment can lose one's lines, but a flush\n * never undoes a finish. The first 16 KB of everything flushed stay in the\n * handle, so an expect rule at finish() sees an early line as run() would.\n */\n flush(): Promise<void>;\n /**\n * Finish the run, judge it like any other, and send what that produces.\n * Resolves to the run as recorded, or null when nothing was recorded: the\n * run was already finished (here or elsewhere), was not found, or belongs\n * to another job, which is reported to onError. When several processes\n * finish one run, only the one whose write lands judges it. Never throws\n * for the store: a store that fails is reported, nothing is recorded, and\n * the handle stays active so finish() can be called again.\n */\n finish(outcome?: RunOutcome | string): Promise<Run | null>;\n /** finish({ error }). */\n fail(error: unknown): Promise<Run | null>;\n}\n\n/**\n * What a Source may use of the client: declare jobs, read the store, and\n * record runs it found elsewhere. A Cronwatch is one.\n */\nexport interface SourceHost {\n /** Declare a job, as Cronwatch.job(). Throws for an invalid name or option. */\n job(name: string, options?: JobOptions): unknown;\n /**\n * The definitions declared now, as Cronwatch.definedJobs(): a source reads\n * it to declare again a job forgotten since (the dashboard's forget), whose\n * definition has not changed. A host without it is taken to keep every\n * job the source declared.\n */\n definedJobs?(): { name: string }[];\n /** See Cronwatch.recordRun(). */\n recordRun(run: Run, options?: RecordRunOptions): Promise<Alert[]>;\n readonly store: Store;\n readonly now: () => number;\n readonly onError: (error: unknown, where: string) => void;\n}\n\n/**\n * Runs that happen somewhere CronWatch cannot wrap, such as inside the\n * database (see @cronwatch/sdk/pg-cron). check() calls sync() on each source\n * first, so what it records is evaluated in the same check.\n */\nexport interface Source {\n name: string;\n /** Declare the jobs and record their new runs. Returns the alerts recording them sent. */\n sync(host: SourceHost): Promise<Alert[] | void>;\n}\n\nexport interface RecordRunOptions {\n /** False stores the run without evaluating it, for history imported on first sight. Default true. */\n evaluate?: boolean;\n}\n\nexport interface CronwatchOptions {\n /** Where jobs, runs, and state live. Defaults to an in-memory store that forgets on restart. */\n store?: Store;\n /**\n * Where runs this process does not wrap come from, such as pg_cron jobs.\n * Each is synced at the start of every check(); one that throws is\n * reported to onError and the check carries on.\n */\n sources?: Source[];\n /** Where alerts go. Defaults to the console. */\n alerts?: AlertChannel[];\n /** Adds a short diagnosis to every alert except recoveries. See @cronwatch/sdk/anthropic. */\n triage?: TriageFn;\n /**\n * Shared secret that handler() requests must carry. Defaults to\n * process.env.CRON_SECRET (on Cloudflare Workers, which have no process,\n * pass env.CRON_SECRET); an empty string or one of only whitespace, given\n * here or in the variable, counts as unset. Pass null to let handlers run\n * without one. Any other type (false, a number) throws.\n */\n cronSecret?: string | null;\n /** How long finished runs are kept. Default \"30d\". */\n retention?: Duration;\n /** Applied to every job unless the job sets its own. */\n defaults?: Pick<JobOptions, \"grace\" | \"timeout\" | \"timezone\" | \"failuresBeforeAlert\">;\n /**\n * Applied to every run's output and error before it is stored, shown, or\n * sent to an alert channel or triage. The default blanks values that look\n * like secrets (password=..., Authorization headers, URL credentials, bearer\n * tokens, JWTs, PEM private keys, webhook URLs, AWS, GitHub, Slack, Stripe,\n * Google, and API key formats). Pass your own function, or false to keep\n * output exactly as logged. A function that throws or returns something\n * other than a string is reported to onError and the default is used.\n */\n redact?: ((text: string) => string) | false;\n /**\n * \"now\" (the default) sends alerts from this process. \"check\" sends nothing\n * from here: each alert is queued in the store and the next check, in a\n * process that delivers now, sends it (with triage). For a process that\n * records runs but cannot reach the network, such as a sandboxed backup job.\n * Its `alerts` and `triage` are not used.\n */\n deliver?: \"now\" | \"check\";\n /** Called with anything that goes wrong outside a job: the store failing, an alert channel failing, a triage timeout. */\n onError?: (error: unknown, where: string) => void;\n /** The clock. Tests use this. */\n now?: () => number;\n}\n\ninterface ExecuteResult<T> {\n run: Run;\n result: T | undefined;\n error: unknown;\n threw: boolean;\n}\n\nconst NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,119}$/;\nconst TRIAGE_TIMEOUT_MS = 25_000;\n/** How long one channel may take to send one alert. */\nconst CHANNEL_TIMEOUT_MS = 15_000;\nconst PRUNE_INTERVAL_MS = 60 * 60_000;\n/**\n * Wall-clock time one check spends retrying undelivered alerts, across every\n * job. Once it is spent the rest wait for the next check.\n */\nconst RETRY_BUDGET_MS = 20_000;\n/**\n * How long run() and handler() wait for the store to record a run's start\n * (the job's declaration and the run's row) before running the job without\n * it. A store that fails does so sooner; this is for one that hangs.\n */\nconst START_DEADLINE_MS = 5_000;\n/** Reads and writes of one job's state before an update gives up on a store that keeps changing under it. */\nconst STATE_ATTEMPTS = 10;\n/** Runs read for a baseline, and the most read when failures crowd out the successes. */\nconst HISTORY_PAGE = BASELINE_WINDOW + 5;\nconst HISTORY_MAX = 200;\n/** The error a check gives an import whose finish never landed (isStranded). */\nconst STRANDED_ERROR = \"Imported, but its finish was never written; marked as timed out\";\n\n/** Throws a clear error for options that would otherwise quietly turn a check off. */\nfunction validateDefinition(def: JobDefinition): void {\n const name = def.name;\n if (def.schedule !== undefined) {\n if (typeof def.schedule !== \"string\" || def.schedule.trim() === \"\") throw new Error(`job \"${name}\": schedule must be a non-empty string`);\n parseSchedule(def.schedule, def.timezone);\n }\n if (def.timezone !== undefined) {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: def.timezone });\n } catch {\n throw new Error(`job \"${name}\": timezone \"${def.timezone}\" is not an IANA timezone`);\n }\n }\n if (def.grace !== undefined) parseDuration(def.grace, \"grace\");\n if (def.timeout !== undefined && parseDuration(def.timeout, \"timeout\") <= 0) throw new Error(`job \"${name}\": timeout must be longer than zero`);\n if (def.maxDuration !== undefined && parseDuration(def.maxDuration, \"maxDuration\") <= 0) {\n throw new Error(`job \"${name}\": maxDuration must be longer than zero`);\n }\n if (def.failuresBeforeAlert !== undefined && !(Number.isInteger(def.failuresBeforeAlert) && def.failuresBeforeAlert >= 1)) {\n throw new Error(`job \"${name}\": failuresBeforeAlert must be a whole number, 1 or more (got ${String(def.failuresBeforeAlert)})`);\n }\n if (def.budget !== undefined) {\n if (typeof def.budget !== \"object\" || def.budget === null) throw new Error(`job \"${name}\": budget must be an object of { metric: ceiling }`);\n for (const [metric, ceiling] of Object.entries(def.budget)) {\n if (typeof ceiling !== \"number\" || !Number.isFinite(ceiling) || ceiling < 0) {\n throw new Error(`job \"${name}\": budget.${metric} must be a finite number, 0 or more (got ${String(ceiling)})`);\n }\n }\n }\n if (def.floor !== undefined) {\n if (typeof def.floor !== \"object\" || def.floor === null) throw new Error(`job \"${name}\": floor must be an object of { metric: floor }`);\n for (const [metric, floor] of Object.entries(def.floor)) {\n if (typeof floor !== \"number\" || !Number.isFinite(floor)) {\n throw new Error(`job \"${name}\": floor.${metric} must be a finite number (got ${String(floor)})`);\n }\n const ceiling = def.budget?.[metric];\n if (ceiling !== undefined && floor > ceiling) {\n throw new Error(`job \"${name}\": floor.${metric} (${floor}) is above budget.${metric} (${ceiling}), so every run would alert`);\n }\n }\n }\n if (def.expect !== undefined && typeof def.expect !== \"string\" && !(def.expect instanceof RegExp) && typeof def.expect !== \"function\") {\n throw new Error(`job \"${name}\": expect must be a string, a RegExp, or a function`);\n }\n}\n\n/** Alerts written with the state that opened their conditions, and how many older ones the queue let go. */\ninterface Held {\n alerts: Alert[];\n dropped: number;\n}\n\nfunction sameState(a: JobState, b: JobState): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\nexport class Cronwatch {\n readonly store: Store;\n readonly alerts: AlertChannel[];\n readonly triage: TriageFn | undefined;\n readonly sources: Source[];\n /** The secret handler() requests must carry, or null when none is set. */\n readonly cronSecret: string | null;\n readonly retentionMs: number;\n readonly now: () => number;\n readonly onError: (error: unknown, where: string) => void;\n /** cronSecret was passed as null: handlers may run without a secret. */\n private readonly secretOptOut: boolean;\n private readonly redact: (text: string) => string;\n /** \"check\": queue alerts for another process's check instead of sending them. See CronwatchOptions.deliver. */\n private readonly deferDelivery: boolean;\n private readonly defaults: NonNullable<CronwatchOptions[\"defaults\"]>;\n private readonly definitions = new Map<string, JobDefinition>();\n /**\n * Declarations forgotten here (forget()), kept so that run() or resumeRun()\n * by name declares the job again as it was written, not bare.\n */\n private readonly forgotten = new Map<string, JobDefinition>();\n private readonly synced = new Set<string>();\n /** The tail of each job's queue of state updates. See serial(). */\n private readonly queues = new Map<string, Promise<void>>();\n /** The tail of each job's queue of declaration writes. See sync(). */\n private readonly syncing = new Map<string, Promise<void>>();\n /** start() calls with an id still in flight, so two at once in this process record one run. */\n private readonly starting = new Map<string, Promise<RunHandle>>();\n private ready: Promise<void> | null = null;\n private checking: Promise<CheckResult> | null = null;\n private lastPruneAt = 0;\n private timer: ReturnType<typeof setInterval> | null = null;\n private firstTick: ReturnType<typeof setTimeout> | null = null;\n private usingDefaultStore = false;\n private warnedNoSecret = false;\n private warnedDeferredStart = false;\n /** Stored jobs read with a definition that was not a JSON object (see readJob). */\n private readonly unreadable = new WeakSet<StoredJob>();\n\n constructor(options: CronwatchOptions = {}) {\n this.store = options.store ?? (this.usingDefaultStore = true, memory());\n this.alerts = options.alerts ?? [consoleChannel()];\n this.triage = options.triage;\n this.sources = options.sources ?? [];\n // A blank secret, given or read, counts as unset; one given that is not a string throws.\n const given = secretOption(options.cronSecret, \"cronSecret\");\n const secret = options.cronSecret === undefined ? readSecretEnv(\"CRON_SECRET\") : given;\n this.cronSecret = secret ? secret : null;\n this.secretOptOut = options.cronSecret === null;\n this.retentionMs = parseDuration(options.retention ?? \"30d\", \"retention\");\n this.defaults = options.defaults ?? {};\n this.now = options.now ?? (() => Date.now());\n const redact = options.redact;\n this.redact = redact === false ? (text) => text\n : typeof redact === \"function\" ? (text) => {\n try {\n const out: unknown = redact(text);\n if (typeof out !== \"string\") throw new TypeError(`redact must return a string, not ${out === null ? \"null\" : typeof out}`);\n return out;\n } catch (e) {\n // A broken redact must not stop the run finishing, nor leak what it was given.\n this.report(e, \"redact\");\n return redactSecrets(text);\n }\n }\n : redactSecrets;\n if (options.deliver !== undefined && options.deliver !== \"now\" && options.deliver !== \"check\") {\n throw new Error(`deliver must be \"now\" or \"check\", not ${JSON.stringify(options.deliver)}`);\n }\n this.deferDelivery = options.deliver === \"check\";\n this.onError = options.onError ?? ((error, where) => console.error(`[cronwatch] ${where}:`, error));\n }\n\n /** Declare a job. Call it once, at module level, and keep the handle. */\n job(name: string, options: JobOptions = {}): JobHandle {\n if (!NAME_RE.test(name)) {\n throw new Error(`job name \"${name}\" must be 1 to 120 characters of letters, digits, \".\", \"_\", \":\", or \"-\"`);\n }\n const definition: JobDefinition = { ...this.defaults, ...options, name };\n validateDefinition(definition);\n this.definitions.set(name, definition);\n this.forgotten.delete(name);\n this.synced.delete(name);\n return this.handle(definition);\n }\n\n /** The declaration of `name`: the standing one, else one forgotten here, declared again as it was. */\n private declared(name: string): JobDefinition | undefined {\n const standing = this.definitions.get(name);\n if (standing) return standing;\n const forgotten = this.forgotten.get(name);\n if (!forgotten) return undefined;\n this.forgotten.delete(name);\n this.definitions.set(name, forgotten);\n this.synced.delete(name);\n return forgotten;\n }\n\n /** Run a job by name without keeping a handle. Defines it on first use. */\n run<T>(name: string, fn: JobFn<T>): Promise<T>;\n run<T>(name: string, options: JobOptions, fn: JobFn<T>): Promise<T>;\n run<T>(name: string, optionsOrFn: JobOptions | JobFn<T>, maybeFn?: JobFn<T>): Promise<T> {\n const fn = typeof optionsOrFn === \"function\" ? optionsOrFn : maybeFn!;\n const options = typeof optionsOrFn === \"function\" ? undefined : optionsOrFn;\n const declared = options ? undefined : this.declared(name);\n const handle = declared ? this.handle(declared) : this.job(name, options);\n return handle.run(fn);\n }\n\n /** The definitions declared in this process. */\n definedJobs(): JobDefinition[] {\n return [...this.definitions.values()];\n }\n\n /** A handle on a run started elsewhere, as job(name).resume(runId). The job must be declared in this process. */\n resumeRun(name: string, runId: string): Promise<RunHandle> {\n const definition = this.declared(name);\n if (!definition) return Promise.reject(new Error(`resumeRun: job \"${name}\" is not declared; call job() first`));\n return this.resumeHandle(definition, runId);\n }\n\n private handle(definition: JobDefinition): JobHandle {\n const self = this;\n return {\n name: definition.name,\n definition,\n async run<T>(fn: JobFn<T>, options?: { trigger?: string }): Promise<T> {\n const outcome = await self.execute(definition, fn, options?.trigger ?? \"run\");\n if (outcome.threw) throw outcome.error;\n return outcome.result as T;\n },\n handler<T>(fn: HandlerFn<T>, options?: HandlerOptions) {\n // A blank secret falls back to the client's; one that is not a string throws.\n const own = secretOption(options?.secret, \"handler: secret\");\n const secret = own === null ? null : own ? own : self.cronSecret;\n const optedOut = own === null || (!own && self.secretOptOut);\n return async (request: Request): Promise<Response> => {\n if (!secret && !optedOut && !isDevelopment()) {\n self.warnNoSecret();\n return json({ ok: false, error: \"CRON_SECRET is not set, so this job will not run for an unauthenticated request. Set it, or pass secret: null to handler() to allow anyone.\" }, 503);\n }\n if (secret) {\n // Read as the dashboard's routes read it: the scheme in any case.\n const sent = bearerToken(request.headers.get(\"authorization\"));\n if (sent === null || !constantTimeEqual(sent, secret)) {\n return json({ ok: false, error: \"Unauthorized\" }, 401);\n }\n }\n const outcome = await self.execute(definition, (job) => fn(job, request), \"handler\");\n if (outcome.result instanceof Response) return outcome.result;\n const body = {\n ok: outcome.run.status === \"ok\",\n job: definition.name,\n run: outcome.run.id,\n status: outcome.run.status,\n durationMs: outcome.run.durationMs,\n // Error text only goes to a caller who proved they hold the secret.\n ...(secret && outcome.run.error ? { error: outcome.run.error.split(\"\\n\")[0] } : {}),\n };\n return json(body, outcome.run.status === \"ok\" ? 200 : 500);\n };\n },\n start(options?: StartOptions): Promise<RunHandle> {\n return self.startRun(definition, options ?? {});\n },\n resume(runId: string): Promise<RunHandle> {\n return self.resumeHandle(definition, runId);\n },\n };\n }\n\n private warnNoSecret(): void {\n if (this.warnedNoSecret) return;\n this.warnedNoSecret = true;\n this.report(new Error(\"handler() refused a request because no CRON_SECRET is set; pass secret: null to allow unauthenticated requests\"), \"handler\");\n }\n\n /** onError, for places that must carry on even when onError itself throws. */\n private report(error: unknown, where: string): void {\n try {\n this.onError(error, where);\n } catch {\n // Nothing more can be done with it.\n }\n }\n\n private async ensureReady(): Promise<void> {\n if (!this.ready) {\n this.ready = (async () => {\n if (this.store.init) await this.store.init();\n const missing = ([\"compareAndSetState\", \"updateRunIf\"] as const).filter((method) => typeof this.store[method] !== \"function\");\n if (missing.length > 0) {\n // Once per client: it still works, but only as long as one process at a time uses the store.\n this.report(\n new Error(`the store has no ${missing.join(\" or \")}, so two processes sharing it can overwrite each other's state or both evaluate the same run; it is safe only while one process at a time uses it`),\n \"store\",\n );\n }\n if (this.usingDefaultStore && isProduction()) {\n console.warn(\"[cronwatch] using the in-memory store: runs and state are lost on restart. Pass a store from @cronwatch/sdk/sqlite or @cronwatch/sdk/postgres.\");\n }\n })().catch((error: unknown) => {\n // Let the next call try again rather than failing forever.\n this.ready = null;\n throw error;\n });\n }\n await this.ready;\n }\n\n /**\n * Writes the declaration of `definition`'s name as it stands, unless the\n * store has it. A handle kept from an earlier declaration writes the one\n * that replaced it, never its own over it, and one forgotten since\n * declares the job again as it was last declared here. The writes of one name take turns, in the order they were asked\n * for, so one still under way cannot land after a later one; and a name\n * declared again while its write was under way is still to be written. A\n * name is marked as written only while that same declaration stands, so a\n * forget that lands during the write (deleting the row after it) leaves\n * the name to be written again, as does one forgotten before it.\n *\n * With `confirm`, as a run starts, a name already written is read back:\n * another process may have forgotten the job since, and a job still\n * declared here comes back on its next run. `running` says the write is\n * for a run (by default, whenever `confirm` is): a name forgotten here is\n * then declared again, where a check or a dashboard read, whose loop may\n * have picked the name up just before the forget, leaves it forgotten.\n */\n private async sync(definition: JobDefinition, confirm = false, running = confirm): Promise<void> {\n await this.ensureReady();\n const name = definition.name;\n if (this.synced.has(name)) {\n if (!confirm || (await this.store.getJob(name))) return;\n this.synced.delete(name);\n }\n await this.serial(name, async () => {\n if (this.synced.has(name)) return;\n if (!this.definitions.has(name)) {\n // Forgotten here since this write was asked for. A check or a\n // dashboard read that was on its way to write it leaves it\n // forgotten: only a run brings a forgotten job back.\n if (!running) return;\n // A handle kept from before the forget: its run declares the job\n // again, as cw.run() by name does (declared()), so the name is marked\n // as written once more and the checks keep it declared.\n this.declared(name);\n }\n const standing = this.definitions.get(name) ?? definition;\n await this.store.upsertJob(toStored(standing), this.now());\n if (this.definitions.get(name) === standing) this.synced.add(name);\n }, this.syncing);\n }\n\n /**\n * Every stored job, once each declaration has been written. A job declared\n * here that the store no longer has was forgotten by another process after\n * this one wrote it: it is written again, as its next run would, so it is\n * checked and shown while any process still declares it.\n */\n private async storedJobs(): Promise<StoredJob[]> {\n for (const definition of this.definitions.values()) await this.sync(definition);\n const jobs = await this.store.listJobs();\n const listed = new Set(jobs.map((job) => job.name));\n const missing = [...this.definitions.values()].filter((definition) => !listed.has(definition.name));\n if (missing.length === 0) return jobs.map((job) => this.readJob(job));\n for (const definition of missing) {\n // Not one forgotten here meanwhile.\n if (this.definitions.get(definition.name) !== definition) continue;\n this.synced.delete(definition.name);\n await this.sync(definition);\n }\n return (await this.store.listJobs()).map((job) => this.readJob(job));\n }\n\n /** A stored job read leniently (readStoredJob); one whose definition is unreadable is remembered, so that evaluating it throws. */\n private readJob(stored: StoredJob): StoredJob {\n const { job, readable } = readStoredJob(stored);\n if (!readable) this.unreadable.add(job);\n return job;\n }\n\n /** Throws for a job whose stored definition was not a JSON object: reported, and shown as failing, while the others carry on. */\n private evaluable(stored: StoredJob): void {\n if (this.unreadable.has(stored)) throw new Error(`job \"${stored.name}\": its stored definition is not a JSON object`);\n }\n\n /**\n * Runs `fn` after every earlier state update for the same job has settled,\n * so two runs (or a run and a check) in this process never read and write\n * the job's state over each other. Other processes are coordinated by\n * updateState() instead. sync() queues a job's declaration writes the same\n * way, in `syncing`.\n */\n private serial<T>(job: string, fn: () => Promise<T>, queues = this.queues): Promise<T> {\n const result = (queues.get(job) ?? Promise.resolve()).then(fn);\n const tail = result.then(() => {}, () => {});\n queues.set(job, tail);\n void tail.then(() => {\n if (queues.get(job) === tail) queues.delete(job);\n });\n return result;\n }\n\n private async readState(job: string): Promise<JobState> {\n return normalizeState(await this.store.getState(job), job);\n }\n\n /**\n * Every read-modify-write of a job's state goes through here. In turn with\n * this process's other updates to the job (serial()), it reads the state,\n * asks `change` for the next one, and writes it with the version one\n * higher, only if the stored version is still the one read. When another\n * process wrote in between, the write is refused and it starts again from\n * a fresh read, up to STATE_ATTEMPTS times. So `change` may run more than\n * once and must only compute: whatever it returns from the attempt that\n * was written is the result. Nothing is written when the state is\n * unchanged. Returns the state as stored.\n */\n private updateState<T>(\n job: string,\n change: (current: JobState) => { state: JobState; result: T } | Promise<{ state: JobState; result: T }>,\n ): Promise<{ state: JobState; result: T }> {\n return this.serial(job, async () => {\n for (let attempt = 1; ; attempt++) {\n const current = await this.readState(job);\n const { state, result } = await change(current);\n if (sameState(state, current)) return { state: current, result };\n const version = stateVersion(current);\n const next: JobState = { ...state, version: version + 1 };\n if (await this.writeState(next, version)) return { state: next, result };\n if (attempt >= STATE_ATTEMPTS) {\n throw new Error(`the state of ${job} changed under ${STATE_ATTEMPTS} attempts in a row to update it; gave up`);\n }\n }\n });\n }\n\n /** A conditional write, or for a store without compareAndSetState, a plain one that always succeeds. */\n private async writeState(state: JobState, expectedVersion: number): Promise<boolean> {\n if (typeof this.store.compareAndSetState === \"function\") return this.store.compareAndSetState(state, expectedVersion);\n await this.store.setState(state);\n return true;\n }\n\n /**\n * Runs a function as a recorded run. The function always runs, whatever\n * the store is doing: store errors go to onError, and the result is the\n * function's own outcome. Never throws for the job's own error; see `threw`.\n */\n private async execute<T>(definition: JobDefinition, fn: JobFn<T>, trigger: string): Promise<ExecuteResult<T>> {\n const name = definition.name;\n const startedAt = this.now();\n const run: Run = {\n id: crypto.randomUUID(),\n job: name,\n status: \"running\",\n startedAt,\n finishedAt: null,\n durationMs: null,\n error: null,\n output: null,\n metrics: {},\n trigger,\n };\n // The run as it starts: what the start write holds, however late it lands.\n const begun = { ...run };\n let recorded = false;\n /** The start write was given up on (START_DEADLINE_MS), and has landed since. */\n let landedLate = false;\n /** The finish has been recorded, or has failed to be: a start that lands after this has no finish coming. */\n let concluded = false;\n const writing = (async () => {\n await this.sync(definition, true);\n await this.store.insertRun({ ...begun });\n })();\n try {\n if ((await within(writing, START_DEADLINE_MS)) === TIMED_OUT) {\n // A store that hangs must not hold the job back: it runs now, as one\n // whose start was never written. The write is still under way and\n // may land later, leaving a running row. One that lands before the\n // finish is finished over as usual; one that lands after it is\n // finished then, here, so no row is left running to be called stuck.\n this.report(new Error(`the store took longer than ${formatDuration(START_DEADLINE_MS)} to record the start of ${name}; running it unrecorded`), `recording ${name}`);\n void writing.then(\n () => {\n landedLate = true;\n if (concluded) return this.recordFinish(definition, run, true, run.finishedAt!).then(() => {}, (e) => this.report(e, `recording ${name}`));\n },\n () => {\n // The write failed in the end: nothing was left behind.\n },\n );\n } else {\n recorded = true;\n }\n } catch (e) {\n this.report(e, `recording ${name}`);\n }\n // Closing missed happens beside the job, which never waits on it.\n const started = recorded\n ? this.updateState(name, (before) => ({ state: holdRun(onRunStart(definition, begun, before, this.now()), run.id), result: undefined }))\n .then(() => {}, (e) => this.report(e, `starting ${name}`))\n : Promise.resolve();\n\n const recorder = createRecorder(run);\n const clearTimer = after(timeoutMs(definition), () => recorder.abort());\n\n let result: T | undefined;\n let error: unknown;\n let threw = false;\n try {\n result = await fn(recorder.context);\n } catch (e) {\n error = e;\n threw = true;\n } finally {\n clearTimer();\n }\n\n const finishedAt = this.now();\n run.finishedAt = finishedAt;\n run.durationMs = runDuration(startedAt, finishedAt);\n run.metrics = recorder.metrics();\n run.output = recorder.output() ?? (typeof result === \"string\" ? result : null);\n this.conclude(definition, run, result, error, threw, recorder.expectText() ?? (typeof result === \"string\" ? result : null));\n\n await started;\n const ignore = (why: string | null) => {\n if (why) this.report(new Error(`run ${run.id} of ${name} ${why}; ignored`), `finishing ${name}`);\n };\n // Whether the finish was written over a start in the store, or as a run of its own.\n const over = recorded || landedLate;\n try {\n ignore(await this.recordFinish(definition, run, over, finishedAt));\n } catch (e) {\n this.report(e, `recording ${name}`);\n // The late start landed while this finish, written as a run of its\n // own, was failing: it found nothing to finish over, and the landing\n // saw a finish still under way and left the row to it. So the row is\n // finished now. (From here to `concluded` nothing waits, so a start\n // that lands later still finds the finish over and finishes itself.)\n if (!over && landedLate) {\n try {\n ignore(await this.recordFinish(definition, run, true, finishedAt));\n } catch (again) {\n this.report(again, `recording ${name}`);\n }\n }\n } finally {\n concluded = true;\n }\n return { run, result, error, threw };\n }\n\n /**\n * Sets a finished run's status and error from how it ended, then redacts\n * its output and error and caps them, in that order. Shared by execute()\n * and RunHandle.finish().\n */\n private conclude(definition: JobDefinition, run: Run, result: unknown, error: unknown, threw: boolean, expectText: string | null): void {\n if (threw) {\n run.status = \"failed\";\n run.error = describeError(error);\n } else if (result instanceof Response && result.status >= 400) {\n run.status = \"failed\";\n run.error = `HTTP ${result.status}${result.statusText ? ` ${result.statusText}` : \"\"}`;\n } else {\n const unmet = checkExpectation(definition.expect, expectText);\n if (unmet) {\n run.status = \"failed\";\n run.error = unmet;\n } else {\n run.status = \"ok\";\n }\n }\n // Redacted after the expect check, so a rule can still match what was\n // logged, and before the cap, so the cut cannot keep half a secret. NULs\n // go last, so not even a custom redact can store one.\n if (run.output !== null) run.output = redactAndCap(run.output, this.redact);\n if (run.error !== null) run.error = redactAndCap(run.error, this.redact);\n }\n\n /**\n * Writes a finished run and evaluates it. `recorded` says whether its\n * start was written; if not, it is inserted now. Returns why nothing was\n * recorded (another process finished the run first, say), or null. Throws\n * when the store does, so a handle can be finished again. Shared by\n * execute() and RunHandle.finish().\n */\n private async recordFinish(definition: JobDefinition, run: Run, recorded: boolean, finishedAt: number): Promise<string | null> {\n if (!recorded) {\n // The start was never written; the store may be back by now.\n await this.sync(definition, false, true);\n try {\n await this.store.insertRun(run);\n await this.finishRun(toStored(definition), run, finishedAt);\n return null;\n } catch (e) {\n // Another process may have recorded a run with this id meanwhile.\n const stored = await this.store.getRun(run.id).catch(() => null);\n if (!stored) throw e;\n if (stored.job !== run.job) return `belongs to job \"${stored.job}\"`;\n }\n }\n // A recovery can consume the marker after the finished row is committed, before this process evaluates it.\n const tracked = (await this.readState(run.job)).pendingRuns?.includes(run.id) ?? false;\n const claim = await this.claimFinish(run);\n if (\"ignored\" in claim) return claim.ignored;\n if (!claim.lateAfterTimeout || run.status === \"ok\") await this.finishRun(toStored(definition), run, finishedAt, tracked && !claim.lateAfterTimeout);\n return null;\n }\n\n /** A conditional write (Store.updateRunIf), or for a store without one, a read then a plain write. */\n private async writeRunIf(run: Run, fromStatuses: Run[\"status\"][]): Promise<boolean> {\n if (typeof this.store.updateRunIf === \"function\") return this.store.updateRunIf(run, fromStatuses);\n const stored = await this.store.getRun(run.id);\n if (!stored || !fromStatuses.includes(stored.status)) return false;\n await this.store.updateRun(run);\n return true;\n }\n\n /**\n * Writes a finished run over its stored row, only while that row is still\n * running, or else still marked timeout by a check. Only the process whose\n * write lands goes on to evaluate the run; for the others it returns why\n * nothing was written. `lateAfterTimeout` means a check already counted\n * the run as a stuck failure: a late failure must not count twice, while\n * a late success still closes stuck and recovers. Throws when the store does.\n */\n private async claimFinish(run: Run): Promise<{ lateAfterTimeout: boolean } | { ignored: string }> {\n if (await this.writeRunIf(run, [\"running\"])) return { lateAfterTimeout: false };\n if (await this.writeRunIf(run, [\"timeout\"])) return { lateAfterTimeout: true };\n const stored = await this.store.getRun(run.id);\n return { ignored: stored ? `was already finished as ${stored.status}` : \"was not found\" };\n }\n\n /** job.start(): records a running run and returns a handle to finish it. See JobHandle.start. */\n private async startRun(definition: JobDefinition, options: StartOptions): Promise<RunHandle> {\n const id = options.id;\n if (id === undefined) return this.recordStart(definition, options.trigger);\n checkRunId(definition.name, id, \"start\");\n // Keyed by job as well, so another job's start with the same id is not\n // handed this job's run: it fails as it would one call later.\n const key = `${definition.name}\\n${id}`;\n const inFlight = this.starting.get(key);\n if (inFlight) return inFlight;\n const started = this.recordStart(definition, options.trigger, id).finally(() => {\n if (this.starting.get(key) === started) this.starting.delete(key);\n });\n this.starting.set(key, started);\n return started;\n }\n\n /**\n * The start of execute() without the function: the run is inserted and\n * missed closes (onRunStart). A store that fails is reported and\n * the handle inserts the finished run instead, as execute() does.\n */\n private async recordStart(definition: JobDefinition, trigger = \"start\", id?: string): Promise<RunHandle> {\n const name = definition.name;\n if (id !== undefined) {\n let stored: Run | null = null;\n try {\n await this.ensureReady();\n stored = await this.store.getRun(id);\n } catch (e) {\n this.report(e, `recording ${name}`);\n }\n if (stored) return this.existingHandle(definition, stored);\n }\n const run: Run = {\n id: id ?? crypto.randomUUID(),\n job: name,\n status: \"running\",\n startedAt: this.now(),\n finishedAt: null,\n durationMs: null,\n error: null,\n output: null,\n metrics: {},\n trigger,\n };\n let recorded = false;\n try {\n await this.sync(definition, true);\n await this.store.insertRun({ ...run });\n recorded = true;\n } catch (e) {\n // Another process may have started a run with this id first.\n const stored = id === undefined ? null : await this.store.getRun(id).catch(() => null);\n if (stored) return this.existingHandle(definition, stored);\n this.report(e, `recording ${name}`);\n }\n if (recorded) {\n await this.updateState(name, (before) => ({ state: holdRun(onRunStart(definition, run, before, this.now()), run.id), result: undefined }))\n .catch((e: unknown) => this.report(e, `starting ${name}`));\n }\n return this.runHandle(definition, run.id, run, recorded, null);\n }\n\n /** job.resume() and cw.resumeRun(). A store that cannot be read is reported, and finish() reads it again. */\n private async resumeHandle(definition: JobDefinition, runId: string): Promise<RunHandle> {\n checkRunId(definition.name, runId, \"resume\");\n let stored: Run | null;\n try {\n await this.ensureReady();\n stored = await this.store.getRun(runId);\n } catch (e) {\n this.report(e, `resuming ${definition.name}`);\n return this.runHandle(definition, runId, null, true, null);\n }\n if (!stored) return this.runHandle(definition, runId, null, true, \"was not found\");\n return this.existingHandle(definition, stored);\n }\n\n /** A handle on a stored run. One still running, or marked timeout by a check, can be finished. */\n private existingHandle(definition: JobDefinition, stored: Run): RunHandle {\n if (stored.job !== definition.name) {\n throw new Error(`run \"${stored.id}\" belongs to job \"${stored.job}\", not \"${definition.name}\"`);\n }\n const finished = stored.status === \"ok\" || stored.status === \"failed\";\n return this.runHandle(definition, stored.id, stored, true, finished ? `already finished as ${stored.status}` : null);\n }\n\n /**\n * The handle itself. `base` is the run as last known here, `recorded`\n * whether its start is in the store, and `inactive` why finish() has\n * nothing to do, or null. Lines and metrics wait in the handle until\n * flush() or finish() merges them onto a fresh read of the stored run.\n */\n private runHandle(definition: JobDefinition, id: string, base: Run | null, recorded: boolean, inactive: string | null): RunHandle {\n const self = this;\n const name = definition.name;\n const fresh = () => createRecorder({ id, job: name, startedAt: base?.startedAt ?? 0 } as Run);\n let recorder = fresh();\n let finished = inactive !== null;\n let finishCalled = false;\n /**\n * The first OUTPUT_CAP characters of every line flushed from this\n * handle, unredacted, or null before the first flush. The stored output\n * keeps only the tail, so without it an expect rule at finish() would\n * miss a line logged early, which run() would have seen.\n */\n let head: string | null = null;\n /**\n * The lines this handle last flushed, as logged (`raw`) and as they\n * stand at the end of the stored output (`redacted`), or null before the\n * first flush. The next lines are redacted together with them, so a\n * secret that began in one flush and ends in the next (a private key\n * logged a line at a time, a label and then its value) is blanked whole,\n * where redacting each flush alone would store its second half.\n */\n let flushed: { raw: string; redacted: string } | null = null;\n /**\n * `lines` added to the stored output, redacted. While the output still\n * ends with what this handle flushed last, that tail is redacted again\n * with the new lines after it and replaced; otherwise (the first flush,\n * or another process has written since) the lines are redacted alone\n * and appended. `tail` is what to remember once the write lands: at most\n * OUTPUT_CAP of the raw text, from the start of a line, and only while\n * its redaction is still the end of what was written.\n */\n const appendRedacted = (stored: string | null, lines: string): { output: string | null; tail: typeof flushed } => {\n const added = stripNul(lines);\n const joins = flushed !== null && stored !== null && stored.endsWith(flushed.redacted);\n let raw = joins ? `${flushed!.raw}\\n${added}` : added;\n const redacted = redactAndCap(raw, self.redact);\n const output = joins ? stored!.slice(0, stored!.length - flushed!.redacted.length) + redacted : joinLines(stored, redacted);\n if (raw.length <= OUTPUT_CAP) return { output, tail: { raw, redacted } };\n const cut = raw.indexOf(\"\\n\", raw.length - OUTPUT_CAP);\n if (cut === -1) return { output, tail: null };\n raw = raw.slice(cut + 1);\n const kept = redactAndCap(raw, self.redact);\n return { output, tail: redacted.endsWith(kept) ? { raw, redacted: kept } : null };\n };\n let queue: Promise<unknown> = Promise.resolve();\n const inTurn = <T>(fn: () => Promise<T>): Promise<T> => {\n const result = queue.then(fn);\n queue = result.catch(() => {});\n return result;\n };\n const ignored = (why: string) => self.report(new Error(`run ${id} of ${name} ${why}; ignored`), `finishing ${name}`);\n\n const finish = (outcome?: RunOutcome | string): Promise<Run | null> => {\n if (finishCalled) {\n ignored(\"was already finished by this handle\");\n return Promise.resolve(null);\n }\n finishCalled = true;\n const wasInactive = finished;\n finished = true;\n // The store failed part way and nothing was recorded, so the handle can be finished again.\n const retryable = (error: unknown): null => {\n finishCalled = false;\n finished = false;\n self.report(error, `finishing ${name}`);\n return null;\n };\n return inTurn(async () => {\n if (wasInactive) {\n ignored(inactive!);\n return null;\n }\n let from = base;\n if (recorded) {\n try {\n from = (await self.store.getRun(id)) ?? base;\n } catch (e) {\n return retryable(e);\n }\n }\n if (!from) {\n ignored(\"was not found\");\n return null;\n }\n if (from.job !== name) {\n ignored(`belongs to job \"${from.job}\"`);\n return null;\n }\n if (from.status === \"ok\" || from.status === \"failed\") {\n ignored(`was already finished as ${from.status}`);\n return null;\n }\n const failed = typeof outcome === \"object\" && outcome !== null && \"error\" in outcome;\n const result = typeof outcome === \"string\" ? outcome : failed ? undefined : outcome?.result;\n const error = failed ? (outcome as { error: unknown }).error : undefined;\n const finishedAt = self.now();\n const added = recorder.output() ?? (typeof result === \"string\" ? result : null);\n const run: Run = {\n ...from,\n status: \"running\",\n finishedAt,\n durationMs: runDuration(from.startedAt, finishedAt),\n error: null,\n // Capped by conclude(), after it is redacted.\n output: added === null ? from.output : appendRedacted(from.output, added).output,\n metrics: { ...from.metrics, ...recorder.metrics() },\n };\n const expectText = joinLines(head, joinLines(from.output, recorder.expectText() ?? (typeof result === \"string\" ? result : null)));\n self.conclude(definition, run, result, error, failed, expectText);\n let why: string | null;\n try {\n why = await self.recordFinish(definition, run, recorded, finishedAt);\n } catch (e) {\n return retryable(e);\n }\n if (why) {\n ignored(why);\n return null;\n }\n return run;\n });\n };\n\n return {\n id,\n job: name,\n startedAt: base?.startedAt ?? null,\n get active() {\n return !finished;\n },\n log: (...parts: unknown[]) => recorder.context.log(...parts),\n metric: (metric: string, value: number) => recorder.context.metric(metric, value),\n metrics: (values: Record<string, number>) => recorder.context.metrics(values),\n flush: () => inTurn(async () => {\n if (finished || !recorded) return;\n const lines = recorder.output();\n const metrics = recorder.metrics();\n if (lines === null && Object.keys(metrics).length === 0) return;\n // Lines logged while this waits on the store go to a new recorder.\n const taken = recorder;\n recorder = fresh();\n const putBack = () => {\n const later = recorder;\n recorder = fresh();\n for (const text of [taken.expectText(), later.expectText()]) if (text !== null) recorder.context.log(text);\n recorder.context.metrics({ ...taken.metrics(), ...later.metrics() });\n };\n try {\n const stored = await self.store.getRun(id);\n // Not running: the lines stay here for finish(), which reports why it cannot record them.\n if (!stored || stored.status !== \"running\") return putBack();\n if (stored.job !== name) {\n putBack();\n self.report(new Error(`run ${id} of ${name} belongs to job \"${stored.job}\"; ignored`), `flushing ${name}`);\n return;\n }\n const next = lines === null ? null : appendRedacted(stored.output, lines);\n const output = next === null ? stored.output : next.output === null ? null : capOutput(next.output);\n // Only over a row still running, so a flush never undoes a finish written meanwhile.\n if (!(await self.writeRunIf({ ...stored, output, metrics: { ...stored.metrics, ...metrics } }, [\"running\"]))) return putBack();\n // Remembered only while the stored output still ends with it (the cap did not cut into it).\n if (next !== null) flushed = next.tail !== null && output !== null && output.endsWith(next.tail.redacted) ? next.tail : null;\n const text = taken.expectText();\n if (text !== null && (head === null || head.length < OUTPUT_CAP)) head = (joinLines(head, text) ?? \"\").slice(0, OUTPUT_CAP);\n } catch (e) {\n putBack();\n self.report(e, `flushing ${name}`);\n }\n }),\n finish,\n fail: (error: unknown) => finish({ error }),\n };\n }\n\n /**\n * Record a run that happened outside this process, for a Source. Its job\n * must be declared with job() first. Runs are keyed by id: a new one is\n * inserted, a stored one still running (or marked timeout by a check) is\n * finished when this one is not running, and anything else is left alone,\n * so recording the same run twice changes nothing. Finishing is\n * conditional (see Store.updateRunIf): when two processes record the same\n * finish, only the one whose write lands evaluates it, and the other\n * reports it as already finished. A stored run of another job is left\n * alone and reported. A finished run is judged as if it had been wrapped\n * here (expect, failures, duration, budgets) and its output and error are\n * redacted the same way; one finishing after a check marked it timeout is\n * judged only when it succeeded, as RunHandle.finish() does. A metric that\n * is not a finite number throws before anything is written, as\n * job.metric() does. Returns the alerts it sent.\n */\n async recordRun(input: Run, options: RecordRunOptions = {}): Promise<Alert[]> {\n const declared = this.definitions.get(input.job);\n if (!declared) throw new Error(`recordRun: job \"${input.job}\" is not declared; call job() first`);\n // The longest id start() takes; MySQL's column would hold 255, but every store holds 200.\n if (typeof input.id !== \"string\" || input.id.length === 0 || input.id.length > MAX_RUN_ID) {\n const got = typeof input.id === \"string\" ? `${input.id.length} characters` : typeof input.id;\n throw new Error(`recordRun: run ids must be 1 to ${MAX_RUN_ID} characters (got ${got}; job \"${input.job}\")`);\n }\n if (input.id.includes(\"\\u0000\")) throw new Error(`recordRun: run ids cannot contain a NUL character (job \"${input.job}\")`);\n // The fields evaluation reads, checked for callers without the types.\n const where = `job \"${input.job}\", run \"${input.id}\"`;\n if (![\"running\", \"ok\", \"failed\", \"timeout\"].includes(input.status)) {\n throw new Error(`recordRun: status must be \"running\", \"ok\", \"failed\", or \"timeout\" (${where})`);\n }\n if (!Number.isFinite(input.startedAt)) throw new Error(`recordRun: startedAt must be a finite number (${where})`);\n if (input.finishedAt !== null && !Number.isFinite(input.finishedAt)) throw new Error(`recordRun: finishedAt must be a finite number or null (${where})`);\n if (input.durationMs !== null && !Number.isFinite(input.durationMs)) throw new Error(`recordRun: durationMs must be a finite number or null (${where})`);\n for (const field of [\"error\", \"output\"] as const) {\n if (input[field] !== null && typeof input[field] !== \"string\") throw new Error(`recordRun: ${field} must be a string or null (${where})`);\n }\n if (typeof input.trigger !== \"string\") throw new Error(`recordRun: trigger must be a string (${where})`);\n // Refused as job.metric() refuses them: a store keeps NaN and Infinity as null.\n for (const [metric, value] of Object.entries(input.metrics ?? {})) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`recordRun: metric \"${metric}\" must be a finite number (job \"${input.job}\", run \"${input.id}\")`);\n }\n }\n await this.sync(declared);\n const run: Run = { ...input, metrics: { ...input.metrics } };\n if (run.status === \"ok\") {\n const unmet = checkExpectation(declared.expect, run.output);\n if (unmet) {\n run.status = \"failed\";\n run.error = unmet;\n }\n }\n if (run.output !== null) run.output = redactAndCap(run.output, this.redact);\n if (run.error !== null) run.error = redactAndCap(run.error, this.redact);\n const evaluate = options.evaluate !== false;\n const definition = toStored(declared);\n\n const stored = await this.store.getRun(run.id);\n if (stored) return this.recordOver(definition, stored, run, evaluate);\n // An evaluated import stays retryable until its durable evaluation marker\n // is written. A finished row alone cannot distinguish lost evaluation\n // from history deliberately imported without evaluation. A finished\n // import's placeholder has finishedAt when it was written, so a check can\n // tell one whose finish never landed (isStranded); the finish writes the\n // run's own. One still running has none, and times out as any run does.\n const inserted: Run = evaluate ? { ...run, status: \"running\", finishedAt: run.status === \"running\" ? null : this.now() } : run;\n try {\n await this.store.insertRun(inserted);\n } catch (e) {\n // Another process recorded it first.\n const again = await this.store.getRun(run.id).catch(() => null);\n if (again) return this.recordOver(definition, again, run, evaluate);\n throw e;\n }\n if (!evaluate) return [];\n return this.recordOver(definition, inserted, run, true);\n }\n\n /** recordRun() for a run already stored. */\n private async recordOver(definition: StoredJobDefinition, stored: Run, run: Run, evaluate: boolean): Promise<Alert[]> {\n if (stored.job !== run.job) {\n this.report(new Error(`run ${run.id} of ${run.job} belongs to job \"${stored.job}\"; ignored`), `recording ${run.job}`);\n return [];\n }\n if (stored.status !== \"running\" && stored.status !== \"timeout\") return [];\n if (evaluate && stored.status === \"running\") {\n await this.updateState(run.job, async (before) => {\n // Recheck inside every CAS attempt: another importer may have\n // finished and consumed the marker since this row was first read.\n const current = await this.store.getRun(run.id);\n if (!current || current.job !== run.job || current.status !== \"running\" || before.pendingRuns?.includes(run.id)) return { state: before, result: undefined };\n return { state: holdRun(onRunStart(definition, run, before, this.now()), run.id), result: undefined };\n });\n }\n if (run.status === \"running\") return [];\n const tracked = (await this.readState(run.job)).pendingRuns?.includes(run.id) ?? false;\n const claim = await this.claimFinish(run);\n if (\"ignored\" in claim) {\n this.report(new Error(`run ${run.id} of ${run.job} ${claim.ignored}; ignored`), `recording ${run.job}`);\n return [];\n }\n if (!evaluate) {\n // Stored unjudged on purpose: a check must not evaluate it as one whose evaluation was lost.\n await this.updateState(run.job, (current) => ({ state: releaseRun(current, run.id), result: undefined }))\n .catch((e: unknown) => this.report(e, `recording ${run.job}`));\n return [];\n }\n if (claim.lateAfterTimeout && run.status !== \"ok\") return [];\n return this.finishRun(definition, run, this.now(), tracked && !claim.lateAfterTimeout);\n }\n\n /**\n * Evaluate a finished run (ok, failed, or timed out by a check), already\n * written, against the job's state and send what that produces. The\n * alerts are written with that state (see outbox()). Never throws.\n */\n private async finishRun(definition: StoredJobDefinition, run: Run, now: number, pendingOnly = false): Promise<Alert[]> {\n let held: Held;\n try {\n let history: Run[] | null = null;\n ({ result: held } = await this.updateState(run.job, async (previous) => {\n if (pendingOnly && !(previous.pendingRuns ?? []).includes(run.id)) return { state: previous, result: { alerts: [], dropped: 0 } };\n history ??= await this.history(run);\n const before = releaseRun(previous, run.id);\n return this.outbox(applySilence(before, onRunFinish(definition, run, before, history, now), now), definition, now);\n }));\n } catch (e) {\n this.report(e, `evaluating ${run.job}`);\n return [];\n }\n this.reportDropped(run.job, held.dropped);\n return this.dispatch(run.job, held.alerts, now);\n }\n\n /**\n * An evaluation as it is written: its drafts composed into alerts and held\n * in the same state (holdAlerts), so the write that opens a condition also\n * keeps its alerts, and a process that stops before sending them does not\n * lose them. Called inside updateState(), so it only computes.\n */\n private outbox(settled: Evaluation, definition: StoredJobDefinition, now: number): { state: JobState; result: Held } {\n const alerts = settled.alerts.map((draft) => composeAlert(draft, definition, now));\n const { state, dropped } = holdAlerts(settled.state, alerts, this.now() + SEND_LEASE_MS, this.deferDelivery);\n return { state, result: { alerts, dropped } };\n }\n\n /** Reports alerts let go because a job's queue was full. */\n private reportDropped(name: string, dropped: number): void {\n if (dropped <= 0) return;\n this.report(\n new Error(`${dropped} undelivered alert${dropped === 1 ? \"\" : \"s\"} for ${name} dropped: only the newest ${MAX_UNDELIVERED} are kept for retry`),\n `alert queue for ${name}`,\n );\n }\n\n /**\n * The runs before `run`, newest first, with up to BASELINE_WINDOW\n * successful ones when the store has them. One small read normally; a\n * larger one only when failures crowd the successes out of it.\n */\n private async history(run: Run): Promise<Run[]> {\n let runs = await this.store.listRuns(run.job, HISTORY_PAGE);\n if (runs.length === HISTORY_PAGE && !hasFullBaseline(runs.filter((r) => r.id !== run.id))) {\n runs = await this.store.listRuns(run.job, HISTORY_MAX);\n }\n return runs.filter((r) => r.id !== run.id);\n }\n\n /**\n * Look for missed and stuck runs across every job, send alerts, retry\n * alerts to the channels that refused them, and prune old runs. Call it from an interval\n * (start()), a cron hitting the mounted routes, or by hand. Concurrent\n * calls share one check.\n */\n check(): Promise<CheckResult> {\n if (!this.checking) {\n this.checking = this.runCheck().finally(() => {\n this.checking = null;\n });\n }\n return this.checking;\n }\n\n private async runCheck(): Promise<CheckResult> {\n await this.ensureReady();\n const alerts: Alert[] = [];\n for (const source of this.sources) {\n try {\n alerts.push(...((await source.sync(this)) ?? []));\n } catch (e) {\n this.report(e, `source ${source.name}`);\n }\n }\n for (const definition of this.definitions.values()) await this.sync(definition);\n const now = this.now();\n\n // Runs that never reported back. One that cannot be judged (its job's\n // stored timeout no longer parses, say) is reported and skipped.\n for (const listed of await this.store.runningRuns()) {\n try {\n const declared = this.definitions.get(listed.job);\n const found = declared ? null : await this.store.getJob(listed.job);\n const stored = found ? this.readJob(found) : null;\n if (stored) this.evaluable(stored);\n const definition = declared ? toStored(declared) : stored?.definition;\n const stranded = isStranded(listed, now);\n if (!definition || !(stranded || isStuck(definition, listed, now))) continue;\n // Read again just before the write: lines and metrics flushed since the\n // list was read (while earlier stuck runs were sent, say) are kept.\n const run = await this.store.getRun(listed.id);\n if (!run || run.status !== \"running\" || run.job !== listed.job) continue;\n run.status = \"timeout\";\n if (stranded && run.error !== null) {\n // The placeholder of a finished import keeps the run's own error,\n // and only a run that failed has one: it is closed as the failure\n // it was, with its own times, and alerts as failed. A later\n // import of the same run finds it finished and changes nothing.\n run.status = \"failed\";\n if (run.durationMs !== null) run.finishedAt = run.startedAt + run.durationMs;\n else run.durationMs = runDuration(run.startedAt, run.finishedAt!);\n } else if (stranded) {\n // Its own status was never written and nothing says it failed; a\n // late finish of it is judged as one after a timeout, so a success\n // still recovers.\n run.durationMs ??= runDuration(run.startedAt, run.finishedAt!);\n run.error = STRANDED_ERROR;\n } else {\n run.finishedAt = now;\n run.durationMs = runDuration(run.startedAt, now);\n run.error = `Still running after ${formatDuration(timeoutMs(definition))}; marked as timed out`;\n }\n // Only over a row still running: a finish that landed meanwhile wins.\n if (!(await this.writeRunIf(run, [\"running\"]))) continue;\n alerts.push(...(await this.finishRun(definition, run, now)));\n } catch (e) {\n this.report(e, `checking ${listed.job}`);\n }\n }\n\n // Each job on its own: one that cannot be evaluated is reported, shown\n // as failing (see unevaluableSummary), and does not stop the others.\n const jobs: JobSummary[] = [];\n const retries = { spentMs: 0 };\n for (const stored of await this.storedJobs()) {\n try {\n this.evaluable(stored);\n const recent = await this.store.listRuns(stored.name, BASELINE_WINDOW);\n let nextExpectedAt: number | null = null;\n const { state, result: held } = await this.updateState(stored.name, (previous) => {\n const evaluation = onCheck(stored.definition, stored, recent[0] ?? null, previous, now);\n nextExpectedAt = evaluation.nextExpectedAt;\n const settled = applySilence(previous, evaluation, now);\n // Alerts a process stopped sending part way go back to the retry queue.\n const released = releaseSending(settled.state, this.now());\n const out = this.outbox({ state: released.state, alerts: settled.alerts }, stored.definition, now);\n return { state: out.state, result: { alerts: out.result.alerts, dropped: released.dropped + out.result.dropped } };\n });\n this.reportDropped(stored.name, held.dropped);\n alerts.push(...(await this.retryUndelivered(stored.name, state, now, retries)));\n alerts.push(...(await this.dispatch(stored.name, held.alerts, now)));\n alerts.push(...(await this.evaluatePending(stored, recent, state, now)));\n jobs.push(summarize(stored, recent, state, nextExpectedAt, now));\n } catch (e) {\n this.report(e, `checking ${stored.name}`);\n jobs.push(await this.unevaluable(stored, now));\n }\n }\n\n let pruned = 0;\n if (now - this.lastPruneAt > PRUNE_INTERVAL_MS) {\n this.lastPruneAt = now;\n try {\n pruned = await this.store.prune(now - this.retentionMs);\n } catch (e) {\n this.report(e, \"pruning\");\n }\n }\n\n return { checkedAt: now, jobs, alerts, pruned };\n }\n\n /**\n * Runs the job's state still holds as pending (holdRun) whose finish was\n * written but never evaluated: the process that finished them stopped, or\n * its state write failed, between the two writes. Each one finished more\n * than SEND_LEASE_MS ago is evaluated now, as its finish would have been;\n * one still running is left to the stuck check, and one the store no\n * longer has (given back, or pruned) is let go. The wait leaves a finish\n * under way in another process to write its own evaluation.\n */\n private async evaluatePending(stored: StoredJob, recent: Run[], state: JobState, now: number): Promise<Alert[]> {\n const alerts: Alert[] = [];\n for (const id of state.pendingRuns ?? []) {\n try {\n const run = recent.find((r) => r.id === id) ?? (await this.store.getRun(id));\n if (!run || run.job !== stored.name) {\n await this.updateState(stored.name, (current) => ({ state: releaseRun(current, id), result: undefined }));\n continue;\n }\n if (run.status === \"running\" || typeof run.finishedAt !== \"number\" || run.finishedAt > now - SEND_LEASE_MS) continue;\n alerts.push(...(await this.finishRun(stored.definition, run, now, true)));\n } catch (e) {\n this.report(e, `evaluating run ${id} of ${stored.name}`);\n }\n }\n return alerts;\n }\n\n /** A job's summary and its newest runs, without alerting. A job that cannot be evaluated is reported and shown as failing. */\n private async snapshot(stored: StoredJob, now: number, runs: number): Promise<{ job: JobSummary; runs: Run[] }> {\n let recent: Run[] = [];\n try {\n recent = await this.store.listRuns(stored.name, Math.max(runs, BASELINE_WINDOW));\n this.evaluable(stored);\n const state = await this.readState(stored.name);\n const { nextExpectedAt } = onCheck(stored.definition, stored, recent[0] ?? null, state, now);\n return { job: summarize(stored, recent, state, nextExpectedAt, now), runs: recent.slice(0, runs) };\n } catch (e) {\n this.report(e, `reading ${stored.name}`);\n return { job: await this.unevaluable(stored, now), runs: recent.slice(0, runs) };\n }\n }\n\n /** The summary of a job whose evaluation failed, from whatever can still be read. */\n private async unevaluable(stored: StoredJob, now: number): Promise<JobSummary> {\n const recent = await this.store.listRuns(stored.name, BASELINE_WINDOW).catch((): Run[] => []);\n const state = await this.readState(stored.name).catch(() => emptyState(stored.name));\n return unevaluableSummary(stored, recent, state, now);\n }\n\n /** Every job the store knows about, with its health. Does not send alerts. */\n async jobs(): Promise<JobSummary[]> {\n return (await this.jobsWithRuns(0)).map((entry) => entry.job);\n }\n\n /** Every job's summary with its newest `limit` runs, read together. What the dashboard shows. */\n async jobsWithRuns(limit = 20): Promise<{ job: JobSummary; runs: Run[] }[]> {\n await this.ensureReady();\n const jobs = await this.storedJobs();\n const now = this.now();\n const out: { job: JobSummary; runs: Run[] }[] = [];\n for (const stored of jobs) out.push(await this.snapshot(stored, now, clampLimit(limit, 20, 0)));\n return out;\n }\n\n /** A job's summary, or null for one the store does not have. One declared here and forgotten elsewhere is written again, as storedJobs() does. */\n async jobSummary(name: string): Promise<JobSummary | null> {\n await this.ensureReady();\n const definition = this.definitions.get(name);\n if (definition) await this.sync(definition, true, false);\n const stored = await this.store.getJob(name);\n if (!stored) return null;\n return (await this.snapshot(this.readJob(stored), this.now(), 0)).job;\n }\n\n /** A job's runs, newest first. `limit` is a whole number from 1 to 500. */\n async runs(name: string, limit = 50): Promise<Run[]> {\n await this.ensureReady();\n return this.store.listRuns(name, clampLimit(limit, 50, 1));\n }\n\n async getRun(id: string): Promise<Run | null> {\n await this.ensureReady();\n return this.store.getRun(id);\n }\n\n /**\n * Stop alerts for a job for a while. State keeps updating underneath. The\n * end is a whole millisecond, held at 2^53 - 1 (see silenceEnd).\n */\n async silence(name: string, duration: Duration): Promise<JobState> {\n const ms = parseDuration(duration, \"silence duration\");\n return this.patchState(name, (state) => { state.silencedUntil = silenceEnd(this.now(), ms); });\n }\n\n async unsilence(name: string): Promise<JobState> {\n return this.patchState(name, (state) => { state.silencedUntil = null; });\n }\n\n /** Read, change, and write one job's state, in turn with every other update to it. */\n private async patchState(name: string, change: (state: JobState) => void): Promise<JobState> {\n await this.ensureReady();\n const { state } = await this.updateState(name, (current) => {\n const next = normalizeState(current, name);\n change(next);\n return { state: next, result: undefined };\n });\n return state;\n }\n\n /**\n * Remove a job and its runs from the store. A job still declared in code\n * comes back, with no history: here on its next run, declared as it was\n * written (cw.run() and cw.resumeRun() by name included), and in any other\n * process that declares it on its next run there, or at that process's\n * next check or dashboard read.\n */\n async forget(name: string): Promise<void> {\n await this.ensureReady();\n const definition = this.definitions.get(name);\n if (definition) this.forgotten.set(name, definition);\n this.definitions.delete(name);\n this.synced.delete(name);\n await this.store.deleteJob(name);\n }\n\n /**\n * The dashboard and JSON API as fetch-style handlers: the one way to mount\n * them. A Next.js app exports them from app/cronwatch/[[...path]]/route.ts:\n *\n * export const { GET, POST, DELETE } = cw.routes();\n */\n routes(options?: RoutesOptions): Routes {\n return buildRoutes(this, options);\n }\n\n /**\n * Check on an interval, for long-running servers. Default every minute.\n * Not for serverless functions or Cloudflare Workers, where nothing runs\n * between requests: call check() from a cron there instead. (A job's\n * start() opens a run; this starts the checks.)\n */\n startChecking(every: Duration = \"1m\"): void {\n if (this.timer) return;\n // At most setInterval's longest delay: a longer one would check every millisecond.\n const ms = Math.min(TIMER_MAX_MS, Math.max(5_000, parseDuration(every, \"check interval\")));\n if (this.deferDelivery && !this.warnedDeferredStart) {\n this.warnedDeferredStart = true;\n console.warn('[cronwatch] startChecking() was called with deliver: \"check\", so these checks send no alerts. Another process must run checks with deliver: \"now\" (the default) to send them.');\n }\n const tick = () => this.check().catch((e) => this.report(e, \"check\"));\n this.timer = setInterval(tick, ms);\n if (typeof this.timer === \"object\" && \"unref\" in this.timer) this.timer.unref();\n this.firstTick = setTimeout(() => {\n this.firstTick = null;\n void tick();\n }, 1_000);\n if (typeof this.firstTick === \"object\" && \"unref\" in this.firstTick) this.firstTick.unref();\n }\n\n /**\n * startChecking(), under its former name.\n * @deprecated Renamed `startChecking`, since a job's `start()` opens a run.\n * This name still works through 1.x and goes in 2.0.\n */\n start(every: Duration = \"1m\"): void {\n this.startChecking(every);\n }\n\n /** Stop the checks startChecking() began. */\n stop(): void {\n if (this.timer) clearInterval(this.timer);\n if (this.firstTick) clearTimeout(this.firstTick);\n this.timer = null;\n this.firstTick = null;\n }\n\n /**\n * Stop the interval, wait for a check already under way (bounded by its\n * own channel, triage, and retry timeouts; what it throws was reported to\n * whoever started it), then close the store, so that check neither writes\n * after the store is closed nor loses the alerts it would queue.\n */\n async close(): Promise<void> {\n this.stop();\n if (this.checking) await this.checking.catch(() => {});\n if (this.store.close) await this.store.close();\n }\n\n /**\n * Triage and send each alert the outbox holds (see outbox()). The state,\n * with the alerts in it, was saved before this, so a slow channel holds up\n * nothing else; afterwards only the delivery fields are written back, onto\n * a fresh read of the state, and the alerts leave `sending`. Triage is made\n * here, never stored with the held alert: the write that opens a condition\n * cannot wait for it, and a retry triages an alert that has none. With\n * deliver: \"check\" the alerts were queued for a check elsewhere instead.\n */\n private async dispatch(name: string, alerts: Alert[], now: number): Promise<Alert[]> {\n if (alerts.length === 0 || this.deferDelivery) return alerts;\n const delivered: Alert[] = [];\n const failed: HeldAlert[] = [];\n let reached = false;\n for (const alert of alerts) {\n if (this.triage && alert.type !== \"recovered\") await this.addTriage(alert, TRIAGE_TIMEOUT_MS);\n // The alert as composed, full run and all; only a retry reads the trimmed copy held in state.\n const sent = await this.deliver(alert);\n reached ||= sent.reached;\n if (sent.left) failed.push(sent.left);\n else delivered.push(alert);\n }\n await this.recordDelivery(name, delivered, failed, [], now, reached);\n return alerts;\n }\n\n /**\n * Send the alerts some channel refused last time, once each, oldest\n * first, to the channels that still owe them (HeldAlert.owed) and no\n * others, from the copy held in state, its run trimmed (heldRun). They\n * are claimed first (claimUndelivered): moved into `sending` with a lease,\n * in one conditional write, so when several processes check at once only\n * the one whose write lands sends them. An alert that no longer describes\n * the job (staleAlert) is dropped instead. Retries across a check share\n * RETRY_BUDGET_MS of wall-clock time; claimed alerts it has no time left\n * for go back to the queue for the next check. Returns the alerts some\n * channel took on this attempt.\n */\n private async retryUndelivered(name: string, state: JobState, now: number, budget: { spentMs: number }): Promise<Alert[]> {\n if ((state.undelivered ?? []).length === 0 || this.deferDelivery) return [];\n let claimed: HeldAlert[];\n try {\n ({ result: claimed } = await this.updateState(name, (previous) => {\n const claim = claimUndelivered(previous, now, this.now() + SEND_LEASE_MS);\n return { state: claim.state, result: claim.claimed };\n }));\n } catch (e) {\n this.report(e, `claiming undelivered alerts for ${name}`);\n return [];\n }\n if (claimed.length === 0) return [];\n const delivered: HeldAlert[] = [];\n const failed: HeldAlert[] = [];\n const sent: Alert[] = [];\n for (const alert of claimed) {\n const left = RETRY_BUDGET_MS - budget.spentMs;\n if (left <= 0) {\n // Not tried: back to the queue as it was.\n failed.push(alert);\n continue;\n }\n const started = Date.now();\n // An alert queued by a process that delivers at check time was never\n // triaged. One that was tried (triage: null) is not tried again.\n if (this.triage && alert.type !== \"recovered\" && alert.triage === undefined) await this.addTriage(alert, Math.min(TRIAGE_TIMEOUT_MS, left));\n const outcome = await this.deliver(alert);\n if (outcome.reached) sent.push(withoutOwed(alert));\n if (outcome.left) failed.push(outcome.left);\n else delivered.push(alert);\n budget.spentMs += Math.max(0, Date.now() - started);\n }\n await this.recordDelivery(name, delivered, failed, [], now, sent.length > 0);\n return sent;\n }\n\n /**\n * Mark delivered alerts done, drop stale ones, and keep failed ones for the\n * next check, taking them all out of `sending` (recordSent). A failed alert\n * replaces its stored copy, so a triage made on this attempt and the\n * channels that still owe it are kept. lastAlertAt moves when `reached`,\n * some channel accepted an alert on this attempt. When this write fails,\n * alerts still in `sending` are retried once their lease runs out.\n */\n private async recordDelivery(name: string, delivered: HeldAlert[], failed: HeldAlert[], dropped: HeldAlert[], now: number, reached: boolean): Promise<void> {\n try {\n const { result: trimmed } = await this.updateState(name, (previous) => {\n const { state, dropped: letGo } = recordSent(normalizeState(previous, name), delivered, failed, dropped, now, reached);\n return { state, result: letGo };\n });\n this.reportDropped(name, trimmed);\n } catch (e) {\n this.report(e, `recording alert delivery for ${name}`);\n }\n }\n\n /**\n * Send to every channel that still owes the alert (owedChannels: all of\n * them for an alert not sent before), at once, each failure reported under\n * its channel's name. `left` is the alert with `owed` cut to the channels\n * that refused it, or null when none did (or none is left to owe it);\n * `reached` is whether any channel accepted it. With no channels at all it\n * counts as delivered, as it always has.\n */\n private async deliver(alert: HeldAlert): Promise<{ left: HeldAlert | null; reached: boolean }> {\n if (this.alerts.length === 0) return { left: null, reached: true };\n const keys = channelKeys(this.alerts.map((channel) => channel.name));\n const owed = owedChannels(alert, keys);\n if (owed.length === 0) return { left: null, reached: false };\n const plain = withoutOwed(alert);\n const failed: string[] = [];\n await Promise.all(\n this.alerts.map(async (channel, i) => {\n if (!owed.includes(keys[i]!)) return;\n try {\n await withTimeout(channel.send(plain, { onError: (e) => this.report(e, `alert channel ${channel.name}`) }), CHANNEL_TIMEOUT_MS);\n } catch (e) {\n failed.push(keys[i]!);\n this.report(e, `alert channel ${channel.name}`);\n }\n }),\n );\n return { left: afterSend(alert, owed, failed), reached: failed.length < owed.length };\n }\n\n /** Sets alert.triage to the diagnosis, or to null when there is none, so it is tried once per alert. */\n private async addTriage(alert: Alert, timeout: number): Promise<void> {\n const controller = new AbortController();\n try {\n const recentRuns = await this.store.listRuns(alert.job, 5);\n const diagnosis = await withTimeout(this.triage!({ alert, recentRuns, signal: controller.signal }), timeout);\n alert.triage = typeof diagnosis === \"string\" && diagnosis !== \"\" ? diagnosis : null;\n } catch (e) {\n controller.abort();\n alert.triage = null;\n this.report(e, `triage for ${alert.job}`);\n }\n }\n}\n\n/** Run ids that start with this belong to the pg_cron source (see @cronwatch/sdk/pg-cron). */\nexport const RESERVED_RUN_ID_PREFIX = \"pgcron:\";\n\n/**\n * The longest run id, in UTF-16 code units (JavaScript's string length): what\n * start(), resume(), and recordRun() take, and every store holds.\n */\nconst MAX_RUN_ID = 200;\n\n/** Throws for a run id no store could hold, or one reserved for the pg_cron source. */\nfunction checkRunId(job: string, id: unknown, method: string): void {\n if (typeof id !== \"string\" || id.length === 0 || id.length > MAX_RUN_ID) {\n throw new Error(`job \"${job}\": ${method}() needs a run id of 1 to ${MAX_RUN_ID} characters (got ${typeof id === \"string\" ? `${id.length} characters` : typeof id})`);\n }\n // Postgres refuses NUL in text, so no store could hold such an id.\n if (id.includes(\"\\u0000\")) throw new Error(`job \"${job}\": ${method}() cannot take a run id containing a NUL character`);\n if (id.startsWith(RESERVED_RUN_ID_PREFIX)) {\n throw new Error(`job \"${job}\": ${method}() cannot take a run id starting with \"${RESERVED_RUN_ID_PREFIX}\", which the pg_cron source uses for its runs`);\n }\n}\n\n/** Two stretches of text as one, a line apart; either may be null. */\nfunction joinLines(before: string | null, after: string | null): string | null {\n if (before === null || before === \"\") return after;\n if (after === null) return before;\n return `${before}\\n${after}`;\n}\n\n/** A whole number in range, or the fallback for anything that is not a number. */\nfunction clampLimit(limit: number, fallback: number, min: number): number {\n const n = typeof limit === \"number\" && Number.isFinite(limit) ? Math.trunc(limit) : fallback;\n return Math.min(500, Math.max(min, n));\n}\n\n/** The longest delay setTimeout keeps: Node runs a longer one after 1 ms. */\nconst TIMER_MAX_MS = 2 ** 31 - 1;\n\n/**\n * Calls fn after ms, however long (a job's timeout of \"30d\" included, which\n * setTimeout alone would fire at once), without keeping the process alive.\n * Returns what cancels it.\n */\nfunction after(ms: number, fn: () => void): () => void {\n let timer: ReturnType<typeof setTimeout>;\n const arm = (left: number): void => {\n timer = left > TIMER_MAX_MS ? setTimeout(() => arm(left - TIMER_MAX_MS), TIMER_MAX_MS) : setTimeout(fn, left);\n if (typeof timer === \"object\" && \"unref\" in timer) timer.unref();\n };\n arm(ms);\n return () => clearTimeout(timer);\n}\n\n/** What within() resolves to when the time ran out first. */\nconst TIMED_OUT = Symbol(\"timed out\");\n\n/**\n * The promise's value, or TIMED_OUT once `ms` has passed without it. The\n * promise is left to settle on its own; what it rejects with is thrown only\n * while it is still being waited for.\n */\nfunction within<T>(promise: Promise<T>, ms: number): Promise<T | typeof TIMED_OUT> {\n return new Promise<T | typeof TIMED_OUT>((resolve, reject) => {\n const t = setTimeout(() => resolve(TIMED_OUT), ms);\n if (typeof t === \"object\" && \"unref\" in t) t.unref();\n promise.then((v) => { clearTimeout(t); resolve(v); }, (e) => { clearTimeout(t); reject(e); });\n });\n}\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const t = setTimeout(() => reject(new Error(`timed out after ${ms}ms`)), ms);\n if (typeof t === \"object\" && \"unref\" in t) t.unref();\n promise.then((v) => { clearTimeout(t); resolve(v); }, (e) => { clearTimeout(t); reject(e); });\n });\n}\n\n/** Writes alerts to the console. The default channel. */\nexport function consoleChannel(): AlertChannel {\n return {\n name: \"console\",\n async send(alert) {\n const line = `[cronwatch] ${alert.title}\\n${alert.message}${alert.triage ? `\\nTriage: ${alert.triage}` : \"\"}`;\n if (alert.type === \"recovered\") console.info(line);\n else console.error(line);\n },\n };\n}\n\n/** Wrap any function as an alert channel. */\nexport function custom(name: string, send: (alert: Alert) => Promise<void> | void): AlertChannel {\n return { name, send: async (alert) => { await send(alert); } };\n}\n\nexport type { Condition };\n\n/**\n * The client's former name.\n * @deprecated Renamed `Cronwatch`, the spelling every port uses. This name\n * still works through 1.x and goes in 2.0.\n */\nexport const CronWatch = Cronwatch;\n/** @deprecated Renamed `Cronwatch`; this name goes in 2.0. */\nexport type CronWatch = Cronwatch;\n/** @deprecated Renamed `CronwatchOptions`; this name goes in 2.0. */\nexport type CronWatchOptions = CronwatchOptions;\n","import { Cronwatch } from \"./client.js\";\nimport type { CronwatchOptions } from \"./client.js\";\n\n/**\n * Create a CronWatch client. One per app, at module level:\n *\n * export const cw = cronwatch({ store: sqlite({ path: \"./data/cronwatch.db\" }), alerts: [slack({ webhookUrl })] });\n * export const nightly = cw.job(\"nightly-report\", { schedule: \"0 2 * * *\", grace: \"15m\" });\n */\nexport function cronwatch(options: CronwatchOptions = {}): Cronwatch {\n return new Cronwatch(options);\n}\n\nexport { Cronwatch, CronWatch, consoleChannel, custom } from \"./client.js\";\nexport type { CronwatchOptions, CronWatchOptions, HandlerFn, HandlerOptions, JobFn, JobHandle, RecordRunOptions, RunHandle, RunOutcome, Source, SourceHost, StartOptions } from \"./client.js\";\nexport type { JobContext } from \"./job.js\";\nexport { memory } from \"./stores/memory.js\";\nexport { VERSION } from \"./version.js\";\nexport { createRoutes } from \"./routes/index.js\";\nexport type { FetchHandler, Routes, RoutesOptions } from \"./routes/index.js\";\nexport { parseDuration, formatDuration } from \"./duration.js\";\nexport { parseSchedule, nextFire } from \"./schedule.js\";\nexport type { ParsedSchedule } from \"./schedule.js\";\nexport { composeAlert } from \"./format.js\";\nexport type {\n Alert,\n AlertChannel,\n AlertDetails,\n AlertDraft,\n AlertType,\n BudgetBreach,\n ChannelContext,\n CheckResult,\n Condition,\n Duration,\n ExpectRule,\n HeldAlert,\n JobDefinition,\n JobHealth,\n JobOptions,\n JobState,\n JobSummary,\n Run,\n RunStatus,\n SendingAlert,\n Store,\n StoredJob,\n StoredJobDefinition,\n TriageContext,\n TriageFn,\n} from \"./types.js\";\n"]}