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 { $loading } from '../stores/loading'
import { removeFromLookupCache } from './lookup' import { removeFromLookupCache } from './lookup'
import { getLocalesFrom } from './utils'
const loaderQueue: Record<string, Set<LocaleLoader>> = {} const loaderQueue: Record<string, Set<LocaleLoader>> = {}
function getLocaleQueue(locale: string) {
return loaderQueue[locale]
}
function createLocaleQueue(locale: string) { function createLocaleQueue(locale: string) {
loaderQueue[locale] = new Set() loaderQueue[locale] = new Set()
} }
@ -21,15 +18,44 @@ function removeLocaleFromQueue(locale: string) {
delete loaderQueue[locale] 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) { export function addLoaderToQueue(locale: string, loader: LocaleLoader) {
loaderQueue[locale].add(loader) loaderQueue[locale].add(loader)
} }
export async function flushQueue(locale: string = getCurrentLocale()) { export async function flushQueue(locale: string = getCurrentLocale()) {
if (!getLocaleQueue(locale)) return if (locale == null) {
throw new Error(
const queue = [...getLocaleQueue(locale)] `[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 if (queue.length === 0) return
removeLocaleFromQueue(locale) removeLocaleFromQueue(locale)
@ -54,7 +80,7 @@ export function registerLocaleLoader(locale: string, loader: LocaleLoader) {
if (!getLocaleQueue(locale)) createLocaleQueue(locale) if (!getLocaleQueue(locale)) createLocaleQueue(locale)
const queue = getLocaleQueue(locale) const queue = getLocaleQueue(locale)
if (queue.has(loader)) return if (getLocaleQueue(locale).has(loader)) return
if (!hasLocaleDictionary(locale)) { if (!hasLocaleDictionary(locale)) {
$dictionary.update(d => { $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) const match = pattern.exec(base)
if (!match) return null if (!match) return null
return match[1] || null return match[1] || null
} }
// todo add a urlPattern method/regexp
export const getClientLocale = ({ export const getClientLocale = ({
navigator, navigator,
hash, hash,
@ -64,12 +63,12 @@ export const getClientLocale = ({
} }
if (hostname) { if (hostname) {
locale = getMatch(window.location.hostname, hostname) locale = getFirstMatch(window.location.hostname, hostname)
if (locale) return locale if (locale) return locale
} }
if (pathname) { if (pathname) {
locale = getMatch(window.location.pathname, pathname) locale = getFirstMatch(window.location.pathname, pathname)
if (locale) return locale if (locale) return locale
} }
@ -83,7 +82,7 @@ export const getClientLocale = ({
locale = locale =
typeof search === 'string' typeof search === 'string'
? getFromURL(window.location.search, search) ? getFromURL(window.location.search, search)
: getMatch(window.location.search, search) : getFirstMatch(window.location.search, search)
if (locale) return locale if (locale) return locale
} }
@ -91,7 +90,7 @@ export const getClientLocale = ({
locale = locale =
typeof hash === 'string' typeof hash === 'string'
? getFromURL(window.location.hash, hash) ? getFromURL(window.location.hash, hash)
: getMatch(window.location.hash, hash) : getFirstMatch(window.location.hash, hash)
if (locale) return locale if (locale) return locale
} }

View File

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