mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-11-09 13:35:12 +09:00
Plan 79 §C + ratchet 5.
utils/intl.js owns dates, times, relative time, durations, numbers, percents
and lists. Three things the scattered calls could not do:
- A module-level locale published by LocaleContext, not read from a hook, so
the API error mapper, log formatter and CSV export format in the panel's
language too. useFormat() is a subscription over the same module, not a
second door.
- Formatter instances cached per (locale, kind, options). The
toLocaleDateString() calls this replaces built a fresh formatter per cell
per render, and Intl construction is the expensive half.
- Relative time via Intl.RelativeTimeFormat rather than translation keys --
the browser already carries every language's plural wording, and keying
"{{count}} days ago" would mean maintaining that table by hand.
This fixes a locale bug that predates any translation work: 124 call sites
use toLocale*() with no argument, which follows the BROWSER's locale, so a
panel set to Spanish already rendered English chrome around Spanish dates.
formatNumber.js was worse -- it built Intl.NumberFormat('en') at module load,
hardcoding English AND making it impossible to follow a switch.
The three human-facing utils now delegate instead of reimplementing, so their
existing callers become locale-aware without being touched. formatBytes gains
the locale decimal separator ("1,5 KB" in es) by replacing a toFixed + regex
trim with maximumFractionDigits, which trims identically in en -- parity
proved case by case against the pre-migration examples.
utils/timeAgo.js is deleted rather than left as a shim; its 6 importers move
to utils/time. A door nobody is forced through is a door nobody uses.
One bug found by the tests: formatNumber(null) returned "0", because
Number(null) is 0 -- a missing metric would have rendered as a real zero.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
30 lines
1.1 KiB
JavaScript
30 lines
1.1 KiB
JavaScript
// Relative-time and duration helpers.
|
|
//
|
|
// Plan 79 §C: the implementations moved to `utils/intl.js`, which is the one
|
|
// locale-aware formatting door. These names stay because ten files import
|
|
// them and the two output shapes are deliberate — but they are now thin
|
|
// delegations, not a second implementation. Notably the date tail of both
|
|
// styles used to be `toLocaleDateString()` with no argument, which follows the
|
|
// BROWSER's locale rather than the panel's.
|
|
//
|
|
// - timeAgo(iso) compact: "just now", "4m", "3h", "2d", else a date
|
|
// - formatRelativeTime verbose, now fully localized by Intl:
|
|
// "4 minutes ago", "hace 4 minutos"
|
|
// - formatDuration(secs) "45s", "3m 20s"
|
|
|
|
import { formatRelative, formatRelativeShort, formatDuration as formatDurationIntl } from './intl.js';
|
|
|
|
export function timeAgo(iso) {
|
|
return formatRelativeShort(iso);
|
|
}
|
|
|
|
export function formatRelativeTime(iso) {
|
|
return formatRelative(iso);
|
|
}
|
|
|
|
export function formatDuration(seconds) {
|
|
return formatDurationIntl(seconds);
|
|
}
|
|
|
|
export default timeAgo;
|