spb/earth-now Public License
earth-now.co — real-time planetary dashboard: live world metrics modeled, not streamed.
TypeScript 93%
Shell 2.3%
SQL 1.4%
JavaScript 1.3%
Dockerfile 1.2%
CSS 0.8%
1/**2 * earth-now.co3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: packages/counter/src/windows.ts6 * Purpose: Reset-window helpers (today UTC / this year UTC / session) computed from the same model — pure, time is a parameter7 */89import type { CounterModel } from "./counter-model.js";10import { counterValue } from "./value.js";1112export type CounterWindow = "today" | "ytd" | "session" | "total";1314/** Start of the UTC day containing t (ms). */15export function startOfUtcDay(tMs: number): number {16 const d = new Date(tMs);17 return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());18}1920/** Start of the UTC year containing t (ms). */21export function startOfUtcYear(tMs: number): number {22 return Date.UTC(new Date(tMs).getUTCFullYear(), 0, 1);23}2425/**26 * Value of a cumulative counter over a display window, derived from the SAME27 * model (same function server/client/badge): v(t) − v(windowStart).28 * "session" needs the caller-provided session start (user arrival time).29 */30export function windowValue(31 model: CounterModel,32 tMs: number,33 window: CounterWindow,34 sessionStartMs?: number,35): number {36 switch (window) {37 case "total":38 return counterValue(model, tMs);39 case "today":40 return counterValue(model, tMs) - counterValue(model, startOfUtcDay(tMs));41 case "ytd":42 return counterValue(model, tMs) - counterValue(model, startOfUtcYear(tMs));43 case "session": {44 if (sessionStartMs === undefined)45 throw new Error("windowValue: 'session' window requires sessionStartMs");46 return counterValue(model, tMs) - counterValue(model, sessionStartMs);47 }48 }49}50