-
Notifications
You must be signed in to change notification settings - Fork 87
Expand file tree
/
Copy pathloaderQueue.ts
More file actions
114 lines (87 loc) · 2.76 KB
/
loaderQueue.ts
File metadata and controls
114 lines (87 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import {
hasLocaleDictionary,
$dictionary,
addMessages,
} from '../stores/dictionary';
import { getPossibleLocales } from '../stores/locale';
import type { MessagesLoader } from '../types';
type Queue = Set<MessagesLoader>;
const queue: Record<string, Queue> = {};
export function resetQueues() {
Object.keys(queue).forEach((key) => {
delete queue[key];
});
}
function createLocaleQueue(locale: string) {
queue[locale] = new Set();
}
function removeLoaderFromQueue(locale: string, loader: MessagesLoader) {
queue[locale].delete(loader);
if (queue[locale].size === 0) {
delete queue[locale];
}
}
function getLocaleQueue(locale: string) {
return queue[locale];
}
function getLocalesQueues(locale: string) {
return getPossibleLocales(locale)
.map<[string, MessagesLoader[]]>((localeItem) => {
const localeQueue = getLocaleQueue(localeItem);
return [localeItem, localeQueue ? [...localeQueue] : []];
})
.filter(([, localeQueue]) => localeQueue.length > 0);
}
export function hasLocaleQueue(locale?: string | null) {
if (locale == null) return false;
return getPossibleLocales(locale).some(
(localeQueue) => getLocaleQueue(localeQueue)?.size,
);
}
function loadLocaleQueue(locale: string, localeQueue: MessagesLoader[]) {
const allLoadersPromise = Promise.all(
localeQueue.map((loader) => {
// todo: maybe don't just remove, but add to a `loading` set?
removeLoaderFromQueue(locale, loader);
return loader().then((partial) => partial.default || partial);
}),
);
return allLoadersPromise.then((partials) => addMessages(locale, ...partials));
}
const activeFlushes: { [key: string]: Promise<void> } = {};
export function flush(locale: string): Promise<void> {
if (!hasLocaleQueue(locale)) {
if (locale in activeFlushes) {
return activeFlushes[locale];
}
return Promise.resolve();
}
// get queue of XX-YY and XX locales
const queues = getLocalesQueues(locale);
// todo: what happens if some loader fails?
activeFlushes[locale] = Promise.all(
queues.map(([localeName, localeQueue]) =>
loadLocaleQueue(localeName, localeQueue),
),
).then(() => {
if (hasLocaleQueue(locale)) {
return flush(locale);
}
delete activeFlushes[locale];
});
return activeFlushes[locale];
}
export function registerLocaleLoader(locale: string, loader: MessagesLoader) {
if (!getLocaleQueue(locale)) createLocaleQueue(locale);
const localeQueue = getLocaleQueue(locale);
// istanbul ignore if
if (getLocaleQueue(locale).has(loader)) return;
// Add an empty dictionary for this locale if it doesn't exist already
if (!hasLocaleDictionary(locale)) {
$dictionary.update((d) => {
d[locale] = {};
return d;
});
}
localeQueue.add(loader);
}