fix: 🐛 flush use the same promise if it wasn't resolved yet

This commit is contained in:
Christian Kaisermann 2019-11-21 23:33:31 -03:00
parent 5f3595013e
commit 66972d4b15

View File

@ -7,10 +7,10 @@ import {
import { getCurrentLocale } from '../stores/locale' import { getCurrentLocale } from '../stores/locale'
import { $isLoading } from '../stores/loading' import { $isLoading } from '../stores/loading'
import { removeFromLookupCache } from './lookup' import { getAllFallbackLocales } from './utils'
import { getLocalesFrom } from './utils'
const loaderQueue: Record<string, Set<MessagesLoader>> = {} type Queue = Set<MessagesLoader>
const loaderQueue: Record<string, Queue> = {}
function createLocaleQueue(locale: string) { function createLocaleQueue(locale: string) {
loaderQueue[locale] = new Set() loaderQueue[locale] = new Set()
@ -24,20 +24,18 @@ function getLocaleQueue(locale: string) {
return loaderQueue[locale] return loaderQueue[locale]
} }
function getLocalesQueue(locale: string) { function getLocalesQueues(locale: string) {
return getLocalesFrom(locale) return getAllFallbackLocales(locale)
.reverse() .reverse()
.reduce( .map<[string, MessagesLoader[]]>(localeItem => {
(acc, localeItem) => const queue = getLocaleQueue(localeItem)
getLocaleQueue(localeItem) return [localeItem, queue ? [...queue] : []]
? acc.concat([...getLocaleQueue(localeItem)]) })
: acc, .filter(([, queue]) => queue.length > 0)
[]
)
} }
export function hasLocaleQueue(locale: string) { export function hasLocaleQueue(locale: string) {
return getLocalesFrom(locale) return getAllFallbackLocales(locale)
.reverse() .reverse()
.some(getLocaleQueue) .some(getLocaleQueue)
} }
@ -46,28 +44,33 @@ export function addLoaderToQueue(locale: string, loader: MessagesLoader) {
loaderQueue[locale].add(loader) loaderQueue[locale].add(loader)
} }
const activeLocaleFlushes: { [key: string]: Promise<void> } = {}
export async function flushQueue(locale: string = getCurrentLocale()) { export async function flushQueue(locale: string = getCurrentLocale()) {
if (!hasLocaleQueue(locale)) return if (!hasLocaleQueue(locale)) return
if (activeLocaleFlushes[locale]) return activeLocaleFlushes[locale]
// get queue of XX-YY and XX locales // get queue of XX-YY and XX locales
const queue = getLocalesQueue(locale) const queues = getLocalesQueues(locale)
if (queue.length === 0) return if (queues.length === 0) return
removeLocaleFromQueue(locale) removeLocaleFromQueue(locale)
const loadingDelay = setTimeout(() => $isLoading.set(true), 200) const loadingDelay = setTimeout(() => $isLoading.set(true), 200)
// todo what happens if some loader fails? // TODO what happens if some loader fails
return Promise.all(queue.map(loader => loader())) activeLocaleFlushes[locale] = Promise.all(
.then(partials => { queues.map(([locale, queue]) => {
partials = partials.map(partial => partial.default || partial) return Promise.all(queue.map(loader => loader())).then(partials => {
partials = partials.map(partial => partial.default || partial)
addMessages(locale, ...partials)
})
})
).then(() => {
clearTimeout(loadingDelay)
$isLoading.set(false)
delete activeLocaleFlushes[locale]
})
removeFromLookupCache(locale) return activeLocaleFlushes[locale]
addMessages(locale, ...partials)
})
.then(() => {
clearTimeout(loadingDelay)
$isLoading.set(false)
})
} }
export function registerLocaleLoader(locale: string, loader: MessagesLoader) { export function registerLocaleLoader(locale: string, loader: MessagesLoader) {