@naturalcycles/js-lib
Version:
Standard library for universal (browser + Node.js) javascript
63 lines (62 loc) • 2.06 kB
JavaScript
import { pMap } from '../../promise/pMap.js';
export const defaultMissingTranslationHandler = key => {
console.warn(`[tr] missing: ${key}`);
return `[${key}]`;
};
export class TranslationService {
constructor(cfg, preloadedLocales = {}) {
this.cfg = {
...cfg,
missingTranslationHandler: defaultMissingTranslationHandler,
};
this.locales = {
...preloadedLocales,
};
this.currentLocale = cfg.currentLocale || cfg.defaultLocale;
}
cfg;
/**
* Cache of loaded locales
*/
locales;
currentLocale;
/**
* Manually set locale data, bypassing the TranslationLoader.
*/
setLocale(localeName, locale) {
this.locales[localeName] = locale;
}
getLocale(locale) {
return this.locales[locale];
}
/**
* Loads locale(s) (if not already cached) via configured TranslationLoader.
* Resolves promise when done (ready to be used).
*/
async loadLocale(locale) {
const locales = Array.isArray(locale) ? locale : [locale];
await pMap(locales, async (locale) => {
if (this.locales[locale])
return; // already loaded
this.locales[locale] = await this.cfg.translationLoader.load(locale);
// console.log(`[tr] locale loaded: ${locale}`)
});
}
/**
* Will invoke `missingTranslationHandler` on missing tranlation.
*
* Does NOT do any locale loading. The locale needs to be loaded beforehand:
* either pre-loaded and passed to the constructor,
* or `await loadLocale(locale)`.
*/
translate(key, params) {
return this.translateIfExists(key, params) || this.cfg.missingTranslationHandler(key, params);
}
/**
* Does NOT invoke `missingTranslationHandler`, returns `undefined` instead.
*/
translateIfExists(key, _params) {
// todo: support params
return this.locales[this.currentLocale]?.[key] || this.locales[this.cfg.defaultLocale]?.[key];
}
}