import { initialState, step, needsTimeline, sendAlert } from "./logic.js";
const FORGE = "https://zeitforge.app";
const TIMEOUT_MS = 10_000;
const STATE_KEY = "state";
async function get(url) {
try {
return await fetch(url, { signal: AbortSignal.timeout(TIMEOUT_MS), redirect: "manual" });
} catch (err) {
return { error: String(err && err.message ? err.message : err) };
}
}
async function checkHealth() {
const res = await get(`${FORGE}/api/v1/version`);
if (res.error) return { status: null, ready: false, error: res.error };
let j = {};
try {
j = await res.json();
} catch {}
return { status: res.status, ready: j.ready === true, version: j.version, node: j.node };
}
async function checkTimeline() {
const res = await get(`${FORGE}/r/quarry/timeline`);
if (res.error) return 599;
await res.body?.cancel();
return res.status;
}
async function loadState(env) {
const raw = await env.PROBE_STATE.get(STATE_KEY, "json");
return raw || initialState();
}
async function probe(env) {
const now = Date.now();
const prev = await loadState(env);
const health = await checkHealth();
const timelineStatus = needsTimeline(health) ? await checkTimeline() : null;
const { state, actions } = step(prev, { health, timelineStatus }, now);
// Persist before sending so a mail failure retries neither as a duplicate nor forever.
await env.PROBE_STATE.put(STATE_KEY, JSON.stringify(state));
for (const a of actions) await sendAlert(env, a, state, FORGE);
return state;
}
export default {
async scheduled(_event, env, ctx) {
ctx.waitUntil(probe(env));
},
async fetch(_req, env) {
return Response.json(await loadState(env));
},
};