JSDoc позволяет документировать обёртки и утилиты вокруг timeago.js прямо в коде. Хорошо написанные комментарии дают IDE автодополнение и описания даже в JavaScript-проектах без TypeScript.
import { format, render, cancel, register } from 'timeago.js';
/**
* Форматирует дату в относительное время.
*
* @param {Date|string|number} date - Дата для форматирования.
* @param {string} [locale='ru'] - Код локали.
* @returns {string} Строка вида "5 минут назад" или "через 2 часа".
*
* @example
* formatDate(new Date(Date.now() - 60000)); // "минуту назад"
* formatDate('2025-01-01', 'en_US'); // "5 months ago"
*/
function formatDate(date, locale = 'ru') {
if (!date) return '';
const d = new Date(date);
return isNaN(d.getTime()) ? '' : format(d, locale);
}
/**
* Безопасное форматирование даты с fallback.
*
* @param {Date|string|number|null|undefined} date - Входная дата.
* @param {Object} [options] - Настройки.
* @param {string} [options.locale='ru'] - Код локали.
* @param {string} [options.fallback=''] - Строка при ошибке.
* @param {boolean} [options.capitalize=false] - Заглавная первая буква.
* @returns {string}
*/
function safeFormat(date, { locale = 'ru', fallback = '', capitalize = false } = {}) {
if (!date) return fallback;
const d = new Date(date);
if (isNaN(d.getTime())) return fallback;
const result = format(d, locale);
return capitalize ? result[0].toUpperCase() + result.slice(1) : result;
}
/**
* @typedef {Object} TimeagoResult
* @property {boolean} ok - Успешно ли форматирование.
* @property {string} [value] - Отформатированная строка (если ok = true).
* @property {string} [error] - Описание ошибки (если ok = false).
*/
/**
* Форматирует дату, возвращая Result объект.
*
* @param {unknown} date
* @param {string} [locale='ru']
* @returns {TimeagoResult}
*/
function tryFormat(date, locale = 'ru') {
if (date == null) return { ok: false, error: 'Empty date' };
const d = new Date(date);
if (isNaN(d.getTime())) return { ok: false, error: `Invalid: ${date}` };
return { ok: true, value: format(d, locale) };
}
/**
* @callback LocaleFunction
* @param {number} number - Количество единиц.
* @param {number} index - Индекс интервала (0-14).
* @returns {[string, string]} Кортеж [прошлое, будущее].
*/
/**
* Регистрирует кастомную локаль.
*
* @param {string} code - Код локали, например 'ru_custom'.
* @param {LocaleFunction} fn - Функция форматирования.
* @returns {void}
*
* @example
* registerCustomLocale('ru_short', (n, i) => ['давно', 'скоро']);
*/
function registerCustomLocale(code, fn) {
register(code, fn);
}
import PropTypes from 'prop-types';
/**
* Компонент для отображения относительного времени.
*
* @component
* @param {Object} props
* @param {Date|string|number} props.date - Дата для отображения.
* @param {string} [props.locale='ru'] - Код локали.
* @param {boolean} [props.live=false] - Автообновление через timeago render.
* @returns {JSX.Element}
*
* @example
* <TimeAgo date={post.createdAt} locale="ru" live />
*/
function TimeAgo({ date, locale, live }) { /* ... */ }
TimeAgo.propTypes = {
date: PropTypes.oneOfType([
PropTypes.instanceOf(Date),
PropTypes.string,
PropTypes.number,
]).isRequired,
locale: PropTypes.string,
live: PropTypes.bool,
};
TimeAgo.defaultProps = {
locale: 'ru',
live: false,
};
/**
* Форматирует дату, бросая исключение при невалидном вводе.
*
* @param {Date|string|number} date
* @param {string} [locale='ru']
* @returns {string}
* @throws {TypeError} Если date невалидна.
*
* @example
* strictFormat(null); // throws TypeError
*/
function strictFormat(date, locale = 'ru') {
if (!date) throw new TypeError('date is required');
const d = new Date(date);
if (isNaN(d.getTime())) throw new TypeError(`Invalid date: ${date}`);
return format(d, locale);
}
/**
* @deprecated Используйте safeFormat() вместо этой функции.
* Будет удалена в версии 3.0.
* @param {string} date
* @returns {string}
*/
function oldFormat(date) {
return format(date, 'ru');
}
/**
* @module timeago-utils
* @description Утилиты для работы с timeago.js в приложении.
* Предоставляет безопасные обёртки с валидацией и обработкой ошибок.
*
* @example
* import { safeFormat, createAutoUpdater } from './timeago-utils';
*
* const label = safeFormat(post.createdAt, { locale: 'ru' });
*/
export { safeFormat, tryFormat, registerCustomLocale };
npm install --save-dev jsdoc
# jsdoc.json конфиг
{
"source": { "include": ["src/utils/timeago.js"] },
"destination": "docs/",
"opts": { "recurse": true }
}
npx jsdoc -c jsdoc.json