Public: anyone can read this; the crew can change it.

Time in words: src/when.ts, and a countdown that does not move the page #20

shipped production is serving it opened this has it
opened this

Intent. Every door has to say how long you have — "4h 12m left", "lapsed 20m ago", "settled on 14 Sep" — so say it once, in one pure module, and render it in a slot whose width never changes.

Done looks like

  • [ ] src/when.ts, pure, now injected, no dependency and no database: remaining(until, now) ("4h 12m left", "lapsed"), relative(at, now) ("20m ago", "just now"), and absolute(at) (a UTC date a person can read, plus the ISO string).
  • [ ] One vocabulary, fixed: units are d h m s, at most two of them, largest first; never "in 0 minutes"; a past time never renders as a future one. src/when.test.ts is a table of inputs to expected strings and covers the boundaries — 0s, 59s, 60s, 90m, 23h59m, 24h, 8d — and a negative duration.
  • [ ] timeTag(at, now) returns the markup every page uses: <time datetime="…" title="…">4h 12m left</time>, escaped here, with a class the CSS knows.
  • [ ] static/app.css gives that class a fixed width in ch so a ticking countdown never reflows the row around it, and the numbers are tabular.
  • [ ] static/live.js re-renders every countdown from its datetime attribute once a second — one interval for the whole page, not one per element, paused when the tab is hidden, no request of any kind. With JavaScript off the server-rendered text is correct at paint and simply grows stale.
  • [ ] No locale guessing and no Intl on the server: the server renders UTC; the browser may put the local absolute time in the title.
  • [ ] The module is used by nobody yet and that is fine — #11, #12, #14 and #16 all import it rather than writing their own, which is why it lands first.

Files src/when.ts (new), src/when.test.ts (new), static/app.css, static/live.js, src/server.test.ts.

Risks Rendering relative time on the server and again in the browser is how the two disagree — the datetime attribute is the single source, and the text is derived from it in both places. A per-element timer on a table with six seats and a hundred acts is the app's only per-second work; keep it to one.

Brief that fits @hearth — honest about what really runs, tested against a clock it is handed. (A person assigns.)

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs