UNPKG

ctql

Version:

Clock Time Quest Log: Interactive, RPG-style quest tracker for Solo Devs

60 lines (55 loc) 1.78 kB
import { state, loadState, saveState, StateOptions } from "../state"; import blocks, { type Block } from "./blocks"; import { syncWithSystemClock } from "./alerts"; import type { TomlPrimitive } from "smol-toml"; import { exitMsg } from "../decorators/exit_msg"; import { notify } from "./notify"; export async function run() { loadState(); const schedule = validateSchedule(); const scheduleDef = blocks.def[schedule.mode]; syncWithSystemClock(async () => { const nowBlock = blocks.current(scheduleDef); if (nowBlock.label !== schedule.lastNotifiedBlock?.label) { // 3) we’ve entered a new slice await notify( nowBlock.label, `Time for ${nowBlock.label} (${nowBlock.end - nowBlock.start}m)` ); schedule.lastNotifiedBlock = { label: nowBlock.label, mins: nowBlock.end - nowBlock.start, }; state.set(StateOptions.Schedule, schedule); saveState({ all: true }); } process.stdin.resume(); }); } type ModeOptions = "deep" | "default" | "rapid"; type Schedule = { mode: ModeOptions; lastNotifiedBlock?: Block; }; function validateSchedule(): Schedule { const schedule = (state.get("schedule") as { [key: string]: TomlPrimitive }) || undefined; if (!schedule) { exitMsg("Could not find Schedule in State"); } if (!Object.keys(schedule).includes("mode")) { exitMsg("Schedule malformed in state \n run `ctql schedule` to repair"); } const mode = (schedule.mode as ModeOptions) || undefined; if (!mode) { exitMsg("Schedule malformed in state \n run `ctql schedule` to repair"); } if (Object.keys(schedule).includes("lastNotifiedBlock")) { const lastNotifiedBlock = (schedule.lastNotifiedBlock as Block) || undefined; if (lastNotifiedBlock) { return { mode, lastNotifiedBlock }; } } return { mode }; }