UNPKG

andrei-bread-i18n

Version:

Small and type-safe package to create multi-language interfaces.

69 lines (68 loc) 2.28 kB
export class I18N { lang; subscribers = new Set(); keysets; constructor(options) { this.keysets = options.languages; this.setLang(options.defaultLang); // call it just for the TS to not complain this.lang = options.defaultLang; } getLang() { return this.lang; } get(key, ...rest) { const { keyset, pluralize } = this.keysets[this.lang]; if (typeof keyset === "function") { return String(key); } const translation = keyset[key]; if (typeof translation === "undefined") { return String(key); } const params = rest[0] || {}; if (typeof translation === "string") { return interpolateTranslation(translation, params); } const pluralKey = pluralize(params.count); const pluralizedTranslation = translation[pluralKey]; return interpolateTranslation(pluralizedTranslation, params); } async setLang(newLang) { try { if (newLang === this.lang) { return; } const { keyset } = this.keysets[newLang]; if (typeof keyset === "function") { const resolvedKeyset = await keyset(); this.keysets[newLang].keyset = resolvedKeyset; } this.lang = newLang; this.subscribers.forEach((cb) => cb(newLang)); } catch (error) { console.error(`Error happened trying to update language. Can not resolve lazy loaded keyset for "${String(newLang)}" language. See the error below to get more details`); throw error; } } subscribe(cb, options) { this.subscribers.add(cb); if (options?.immediate) { cb(this.lang); } return () => { this.subscribers.delete(cb); }; } } const mustacheParamRegex = /\{\{\s*([a-zA-Z10-9]+)\s*\}\}/g; // not the most performant way, but it should be okay function interpolateTranslation(translation, params) { return translation.replace(mustacheParamRegex, (original, paramKey) => { if (paramKey in params) { return String(params[paramKey]); } return original; }); }