• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const hasIntl = typeof Intl === 'object' && !!Intl
2const Collator = hasIntl && Intl.Collator
3const cache = new Map()
4
5const collatorCompare = (locale, opts) => {
6  const collator = new Collator(locale, opts)
7  return (a, b) => collator.compare(a, b)
8}
9
10const localeCompare = (locale, opts) => (a, b) => a.localeCompare(b, locale, opts)
11
12const knownOptions = [
13  'sensitivity',
14  'numeric',
15  'ignorePunctuation',
16  'caseFirst',
17]
18
19const { hasOwnProperty } = Object.prototype
20
21module.exports = (locale, options = {}) => {
22  if (!locale || typeof locale !== 'string')
23    throw new TypeError('locale required')
24
25  const opts = knownOptions.reduce((opts, k) => {
26    if (hasOwnProperty.call(options, k)) {
27      opts[k] = options[k]
28    }
29    return opts
30  }, {})
31  const key = `${locale}\n${JSON.stringify(opts)}`
32
33  if (cache.has(key))
34    return cache.get(key)
35
36  const compare = hasIntl
37    ? collatorCompare(locale, opts)
38    : localeCompare(locale, opts)
39  cache.set(key, compare)
40
41  return compare
42}
43