Метод register

Функция register добавляет пользовательскую локаль в глобальный реестр библиотеки. После регистрации локаль доступна по ключу во всех вызовах format и render.


Сигнатура

register(locale: string, localeFunc: LocaleFunc): void

locale — строковый идентификатор локали (например, 'ru', 'my_custom')

localeFunc — функция локали:

type LocaleFunc = (number: number, index: number) => [string, string]

Базовый пример

import { register, format } from 'timeago.js';

register('ru_short', (number, index) => {
  const strings = [
    ['сейч.',   'сейч.'],
    ['%sс',     'ч%sс'],
    ['%sс',     'ч%sс'],
    ['1м',      'ч1м'],
    ['%sм',     'ч%sм'],
    ['1ч',      'ч1ч'],
    ['%sч',     'ч%sч'],
    ['1д',      'ч1д'],
    ['%sд',     'ч%sд'],
    ['1нед',    'ч1нед'],
    ['%sнед',   'ч%sнед'],
    ['1мес',    'ч1мес'],
    ['%sмес',   'ч%sмес'],
    ['1г',      'ч1г'],
    ['%sл',     'ч%sл'],
  ];
  return strings[index];
});

format(Date.now() - 1000 * 60 * 15, 'ru_short');
// → "15м"

Регистрация встроенной локали из пакета

import { register } from 'timeago.js';
import ru from 'timeago.js/esm/lang/ru';

register('ru', ru);

Регистрация нескольких локалей

import { register } from 'timeago.js';

const locales = {
  'ru':    require('timeago.js/esm/lang/ru').default,
  'de':    require('timeago.js/esm/lang/de').default,
  'fr':    require('timeago.js/esm/lang/fr').default,
};

Object.entries(locales).forEach(([key, fn]) => register(key, fn));

Переопределение существующей локали

Повторный вызов register с тем же ключом заменяет предыдущую функцию:

register('en_US', (number, index) => {
  // Кастомные английские строки
  return [/* ... */];
});

Все последующие вызовы format(date, 'en_US') будут использовать новую функцию.


Регистрация с замыканием

Функция локали может замыкать внешние переменные:

const currency = 'руб';

register('ru_financial', (number, index) => {
  // Использует currency из замыкания
  return [
    // ...
  ][index];
});

Идемпотентность

register('ru', ruFn);
register('ru', ruFn); // не вызывает ошибку, просто перезаписывает

Повторная регистрация с идентичной функцией безвредна, но бессмысленна.


Порядок вызова

register должна быть вызвана до первого использования локали:

// Правильно
register('ru', ru);
format(date, 'ru'); // ок

// Неправильно
format(date, 'ru'); // ru не зарегистрирован!
register('ru', ru);

Типизация в TypeScript

import { register } from 'timeago.js';

const myLocale = (number: number, index: number): [string, string] => {
  return ['', ''];
};

register('custom', myLocale);

Реестр локалей — внутреннее состояние

register пишет в закрытый объект внутри модуля. Нет публичного метода для:

  • получения списка зарегистрированных локалей;
  • удаления локали;
  • проверки существования локали.

Обходной путь — вести собственный учёт:

const registeredLocales = new Set(['en_US']); // en_US встроена

function safeRegister(key, fn) {
  register(key, fn);
  registeredLocales.add(key);
}

function isRegistered(key) {
  return registeredLocales.has(key);
}

Ленивая регистрация

import { register, format } from 'timeago.js';

const loaded = new Set(['en_US']);

async function lazyFormat(date, locale) {
  if (!loaded.has(locale)) {
    const mod = await import(`timeago.js/esm/lang/${locale}.js`);
    register(locale, mod.default);
    loaded.add(locale);
  }
  return format(date, locale);
}

Безопасная загрузка неизвестной локали

async function safeLazyRegister(locale) {
  try {
    const mod = await import(`timeago.js/esm/lang/${locale}.js`);
    register(locale, mod.default);
    return true;
  } catch {
    console.warn(`Locale '${locale}' not found in timeago.js, falling back to en_US`);
    return false;
  }
}

Использование register в тестах

import { register, format } from 'timeago.js';

beforeAll(() => {
  register('test', (number, index) => {
    return [
      [`PAST_${index}_${number}`, `FUTURE_${index}_${number}`],
    ][0];
  });
});

test('format returns correct index', () => {
  const result = format(Date.now() - 1000 * 60 * 5, 'test');
  expect(result).toContain('PAST_4'); // индекс 4 = несколько минут
});