florrain / locale

Browser locale negotiation for node.js
MIT License
257 stars 36 forks source link

API without instantiation #37

Open martinheidegger opened 8 years ago

martinheidegger commented 8 years ago

The current API instantiates a new object for locales. It would be awesome if the system could work without instantiation of any kind (neither arrays: .split) nor instances of locales.

florrain commented 8 years ago

Hi @martinheidegger can you give a use case as example and how you imagine the implementation?

martinheidegger commented 8 years ago

The use case is: Reduce performance consumption of locales. (Less garbage collection of on-the-fly created language objects).

API:

var appLocales = new locale.Locales('en, de')

app.use((req, res, next) => {
   req.language = appLocales.best(req.headers['accept-language'])
   next()
})

I imagine the Implementation could be like:

var reg = /^\s*([a-z]{2})([_-]([a-z]{2}))?(;q=([0-9.]+))\s*$/ig
// ...

Locales.prototype.bestString = function (string) {
  var cached = this.lruCache.get(string)
  if (cached) {
    return cached
  }
  reg.index = 0
  var parts
  var bestMatchLocale
  var bestMatchRating = -1
  while (bestMatchRating !== 1 && parts = reg.exec(string)) {
     var lang = parts[1]
     var country = parts[3]
     var quality = parts[5]
     for (var i=0; i<this.locales.length; i++) {
        var locale = this.locales[i]
        var rating = this.calculateRating(locale, lang, country, quality)
        if (rating > bestMatchRating) {
          bestMatchRating = rating
          bestMatchLocale = locale
        }
     }
  }
  if (!bestMatchLocale) {
    bestMatchLocale = this.locales[0]
  }
  this.lruCache.set(string, bestMatchLocale)
  return bestMatchLocale
}
Locales.prototype.best = (stringOrArray) {
  if (typeof stringOrArray === 'string') {
    return this.bestString(string)
  } else {
    // etc.
  }
}