41 lines
3.1 KiB
Markdown
41 lines
3.1 KiB
Markdown
# Дизайн: чистый помощник `formatBytes` — человекочитаемый размер
|
|
|
|
**Дата:** 2026-06-14
|
|
|
|
## Цель
|
|
|
|
Дать переиспользуемую чистую функцию, превращающую число байт в короткую человекочитаемую строку (`1536` → `1.5 KB`). Нужна в логах и отчётах размеров файлов/дампов, где сейчас размеры печатаются сырыми байтами и плохо читаются.
|
|
|
|
## Контракт {#D1}
|
|
|
|
`formatBytes(n, { precision = 1 } = {}) → string`. Вход — неотрицательное число байт. Выход — строка вида `"<число> <единица>"`, единицы по основанию 1024: `B`, `KB`, `MB`, `GB`, `TB`. Дробная часть округляется до `precision` знаков; для единицы `B` дробная часть не печатается (целые байты). Функция детерминирована, без побочных эффектов и без обращения к I/O.
|
|
|
|
## Алгоритм {#D2}
|
|
|
|
1. Привести вход к числу; невалидный/отрицательный/`NaN` — см. крайние случаи (D3).
|
|
2. Выбрать наибольшую единицу `u`, при которой `n / 1024^i < 1024` (или последняя — `TB`).
|
|
3. Значение = `n / 1024^i`; для `i === 0` (`B`) вернуть целое; иначе округлить до `precision` и убрать хвостовые нули.
|
|
4. Склеить `"<значение> <единица>"`.
|
|
|
|
## Крайние случаи {#D3}
|
|
|
|
- `0` → `"0 B"`.
|
|
- Отрицательное число / `NaN` / не-число → `"0 B"` (деградация к безопасному, без исключения).
|
|
- Очень большие значения (> 1024 TB) остаются в `TB` (последняя единица не переполняется в новую).
|
|
- `precision = 0` → без дробной части во всех единицах.
|
|
|
|
## Конвенция {#D4}
|
|
|
|
ES-модуль `tools/format-bytes.mjs`, единственный именованный экспорт `formatBytes`. Без зависимостей. Покрытие — vitest tools-config. Имя файла и экспорта совпадают по смыслу; чистая функция тестируется в изоляции.
|
|
|
|
## Критерий готовности {#D5}
|
|
|
|
- Юнит-тесты: базовые переходы единиц (`B`/`KB`/`MB`/`GB`/`TB`), округление по `precision`, целые байты для `B`, безопасная деградация невалидного входа в `"0 B"`.
|
|
- Полная регрессия tools-only зелёная: `npx vitest run --root app --config vitest.config.tools.mjs`.
|
|
|
|
```verified-context-json
|
|
[
|
|
{"id": "vc-pricing", "kind": "EXTRACTED", "ref": "tools/cost-pricing.mjs", "anchor": "export const PRICING = Object.freeze("}
|
|
]
|
|
```
|