Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

Commit

Permalink
feat(caching): added some caching to reduce regex execution to a minimum
Browse files Browse the repository at this point in the history
  • Loading branch information
skolmer committed Jan 29, 2018
1 parent e9ae6f5 commit 04c7d02
Showing 1 changed file with 32 additions and 8 deletions.
40 changes: 32 additions & 8 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ class Tag {
'': this.defaultConfig
}

this.translationCache = {}

this.keyCache = {}

this._localizers = {
s /*string*/: (config, v, format) => {
let formatted
Expand Down Expand Up @@ -81,6 +85,8 @@ class Tag {
}

i18nConfig({locales, translations, group, number, date, standardFormatters}) {
// clear translation cache
this.translationCache = {}
const currentConfig = this.configs[group || ''] || this.defaultConfig
this.configs[group || ''] = Object.assign({}, currentConfig, {
locales: locales || currentConfig.locales,
Expand All @@ -92,24 +98,34 @@ class Tag {
}

i18n(group, config, literals, ...values) {
const translationKey = this._buildKey(literals)
const configGroup = this.configs[config || ''] || this.defaultConfig
const translationString = this._getTranslation(group, configGroup, translationKey)
const translationKey = this._buildKey(literals)
const { configGroup, translatedKey } = this._getCachedTranslation(group, config, translationKey)
const typeInfoForValues = literals.slice(1).map(this._extractTypeInfo)
const localizedValues = values.map((v, i) => this._localize(configGroup, v, typeInfoForValues[i]))
return this._buildMessage(translationString, ...localizedValues)
return this._buildMessage(translatedKey, ...localizedValues)
}

translate(group, config, key, ...values) {
const configGroup = this.configs[config || ''] || this.defaultConfig
const translationString = this._getTranslation(group, configGroup, key)
const { configGroup, translatedKey } = this._getCachedTranslation(group, config, key)
const localizedValues = values.map((v) => {
if(v instanceof Object && v.constructor === Object) {
return this._localize(configGroup, v.value || '', { type: v.formatter || 's', options: v.format })
}
return this._localize(configGroup, v, { type: 's', options: '' })
})
return this._buildMessage(translationString, ...localizedValues)
return this._buildMessage(translatedKey, ...localizedValues)
}

_getCachedTranslation(group, config, translationKey) {
const cacheKey = [group || '', config || '', translationKey].join()
const cachedTranslation = this.translationCache[cacheKey]
const configGroup = this.configs[config || ''] || this.defaultConfig
if(cachedTranslation) {
return { configGroup, translatedKey: cachedTranslation }
}
const translationString = this._getTranslation(group, configGroup, translationKey)
this.translationCache[cacheKey] = translationString
return { configGroup, translatedKey: translationString }
}

_getTranslation(group, configGroup, translationKey) {
Expand Down Expand Up @@ -291,11 +307,19 @@ class Tag {

// e.g. this._buildKey(['', ' has ', ':c in the']) == '{0} has {1} in the bank'
_buildKey(literals) {
const cacheKey = literals.join()
const cachedKey = this.keyCache[cacheKey]
if(cachedKey) {
return cachedKey
}

const stripType = (s) => s.replace(typeInfoRegex, '')
const lastPartialKey = stripType(literals[literals.length - 1])
const prependPartialKey = (memo, curr, i) => `${stripType(curr)}\${${i}}${memo}`

return literals.slice(0, -1).reduceRight(prependPartialKey, lastPartialKey).replace(/\r\n/g, '\n')
const key = literals.slice(0, -1).reduceRight(prependPartialKey, lastPartialKey).replace(/\r\n/g, '\n')
this.keyCache[cacheKey] = key
return key
}

// e.g. this._formatStrings('{0} {1}!', 'hello', 'world') == 'hello world!'
Expand Down

0 comments on commit 04c7d02

Please sign in to comment.