fix: 🐛 consider generic locales when registering loaders

This commit is contained in:
Christian Kaisermann 2019-11-20 18:29:14 -03:00
parent b19b69050e
commit 1b0138c3f3
3 changed files with 44 additions and 16 deletions

View File

@ -6,13 +6,10 @@ import { getCurrentLocale } from '../stores/locale'
import { $loading } from '../stores/loading'
import { removeFromLookupCache } from './lookup'
import { getLocalesFrom } from './utils'
const loaderQueue: Record<string, Set<LocaleLoader>> = {}
function getLocaleQueue(locale: string) {
return loaderQueue[locale]
}
function createLocaleQueue(locale: string) {
loaderQueue[locale] = new Set()
}
@ -21,15 +18,44 @@ function removeLocaleFromQueue(locale: string) {
delete loaderQueue[locale]
}
function getLocaleQueue(locale: string) {
return loaderQueue[locale]
}
function getLocalesQueue(locale: string) {
return getLocalesFrom(locale)
.reverse()
.reduce(
(acc, localeItem) =>
getLocaleQueue(localeItem)
? acc.concat([...getLocaleQueue(localeItem)])
: acc,
[]
)
}
export function hasLocaleQueue(locale: string) {
return getLocalesFrom(locale)
.reverse()
.some(getLocaleQueue)
}
export function addLoaderToQueue(locale: string, loader: LocaleLoader) {
loaderQueue[locale].add(loader)
}
export async function flushQueue(locale: string = getCurrentLocale()) {
if (!getLocaleQueue(locale)) return
const queue = [...getLocaleQueue(locale)]
if (locale == null) {
throw new Error(
`[svelte-i18n] Invalid locale into "waitLocale": ${JSON.stringify(
locale
)}`
)
}
if (!hasLocaleQueue(locale)) return
// get queue of XX-YY and XX locales
const queue = getLocalesQueue(locale)
if (queue.length === 0) return
removeLocaleFromQueue(locale)
@ -54,7 +80,7 @@ export function registerLocaleLoader(locale: string, loader: LocaleLoader) {
if (!getLocaleQueue(locale)) createLocaleQueue(locale)
const queue = getLocaleQueue(locale)
if (queue.has(loader)) return
if (getLocaleQueue(locale).has(loader)) return
if (!hasLocaleDictionary(locale)) {
$dictionary.update(d => {

View File

@ -34,13 +34,12 @@ const getFromURL = (urlPart: string, key: string) => {
}
}
const getMatch = (base: string, pattern: RegExp) => {
const getFirstMatch = (base: string, pattern: RegExp) => {
const match = pattern.exec(base)
if (!match) return null
return match[1] || null
}
// todo add a urlPattern method/regexp
export const getClientLocale = ({
navigator,
hash,
@ -64,12 +63,12 @@ export const getClientLocale = ({
}
if (hostname) {
locale = getMatch(window.location.hostname, hostname)
locale = getFirstMatch(window.location.hostname, hostname)
if (locale) return locale
}
if (pathname) {
locale = getMatch(window.location.pathname, pathname)
locale = getFirstMatch(window.location.pathname, pathname)
if (locale) return locale
}
@ -83,7 +82,7 @@ export const getClientLocale = ({
locale =
typeof search === 'string'
? getFromURL(window.location.search, search)
: getMatch(window.location.search, search)
: getFirstMatch(window.location.search, search)
if (locale) return locale
}
@ -91,7 +90,7 @@ export const getClientLocale = ({
locale =
typeof hash === 'string'
? getFromURL(window.location.hash, hash)
: getMatch(window.location.hash, hash)
: getFirstMatch(window.location.hash, hash)
if (locale) return locale
}

View File

@ -1,7 +1,7 @@
import { writable } from 'svelte/store'
import { getGenericLocaleFrom, getLocalesFrom } from '../includes/utils'
import { flushQueue } from '../includes/loaderQueue'
import { flushQueue, hasLocaleQueue } from '../includes/loaderQueue'
import { getDictionary } from './dictionary'
@ -34,7 +34,10 @@ $locale.subscribe((newLocale: string) => {
const localeSet = $locale.set
$locale.set = (newLocale: string): void | Promise<void> => {
if (getAvailableLocale(newLocale)) {
return flushQueue(newLocale).then(() => localeSet(newLocale))
if (hasLocaleQueue(newLocale)) {
return flushQueue(newLocale).then(() => localeSet(newLocale))
}
return localeSet(newLocale)
}
throw Error(`[svelte-i18n] Locale "${newLocale}" not found.`)