@discord/intl 0.10.2 → 0.10.3-canary.1346695
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/intl-manager.d.ts +18 -1
- package/dist/intl-manager.js +2 -2
- package/dist/message-loader.d.ts +1 -0
- package/dist/message-loader.js +23 -9
- package/package.json +7 -13
- package/src/intl-manager.ts +23 -2
- package/src/message-loader.ts +21 -7
package/dist/intl-manager.d.ts
CHANGED
|
@@ -14,13 +14,30 @@ export type FormatFunction<F extends FormatterImplementation<any, any>> = <T ext
|
|
|
14
14
|
type ThisWithFormatters<This, T extends Record<string, FormatterImplementation<any, any>>> = This & {
|
|
15
15
|
[K in keyof T]: FormatFunction<T[K]>;
|
|
16
16
|
};
|
|
17
|
+
export interface IntlManagerOptions {
|
|
18
|
+
/**
|
|
19
|
+
* The locale to initially have this manager use. Useful to set when information about the user's
|
|
20
|
+
* likely locale is available sooner than when that information is definitely known (at which
|
|
21
|
+
* point `setLocale` should be called instead).
|
|
22
|
+
*
|
|
23
|
+
* @default DEFAULT_LOCALE
|
|
24
|
+
*/
|
|
25
|
+
initialLocale?: string;
|
|
26
|
+
/**
|
|
27
|
+
* The locale in which most messages are _defined_, used as an indication of where fallbacks
|
|
28
|
+
* should be loaded from when they can't be found in the requested `currentLocale`.
|
|
29
|
+
*
|
|
30
|
+
* @default DEFAULT_LOCALE
|
|
31
|
+
*/
|
|
32
|
+
defaultLocale?: string;
|
|
33
|
+
}
|
|
17
34
|
export declare class IntlManager {
|
|
18
35
|
defaultLocale: string;
|
|
19
36
|
currentLocale: string;
|
|
20
37
|
intl: IntlShape;
|
|
21
38
|
formatConfig: FormatConfig;
|
|
22
39
|
_localeSubscriptions: Set<(locale: string) => void>;
|
|
23
|
-
constructor(defaultLocale
|
|
40
|
+
constructor({ initialLocale, defaultLocale, }: IntlManagerOptions);
|
|
24
41
|
/**
|
|
25
42
|
* Add a set of formatter implementations to this manager, making each available as a direct
|
|
26
43
|
* property
|
package/dist/intl-manager.js
CHANGED
|
@@ -10,7 +10,7 @@ const format_config_1 = require("./format-config");
|
|
|
10
10
|
*/
|
|
11
11
|
exports.DEFAULT_LOCALE = 'en-US';
|
|
12
12
|
class IntlManager {
|
|
13
|
-
constructor(defaultLocale = exports.DEFAULT_LOCALE) {
|
|
13
|
+
constructor({ initialLocale = exports.DEFAULT_LOCALE, defaultLocale = exports.DEFAULT_LOCALE, }) {
|
|
14
14
|
/**
|
|
15
15
|
* Subscribe to changes in the current locale for this manager.
|
|
16
16
|
*/
|
|
@@ -18,8 +18,8 @@ class IntlManager {
|
|
|
18
18
|
this._localeSubscriptions.add(callback);
|
|
19
19
|
return () => this._localeSubscriptions.delete(callback);
|
|
20
20
|
};
|
|
21
|
+
this.currentLocale = initialLocale;
|
|
21
22
|
this.defaultLocale = defaultLocale;
|
|
22
|
-
this.currentLocale = defaultLocale;
|
|
23
23
|
this.formatConfig = format_config_1.DEFAULT_FORMAT_CONFIG;
|
|
24
24
|
this.intl = (0, intl_1.createIntl)({
|
|
25
25
|
formats: format_config_1.DEFAULT_FORMAT_CONFIG,
|
package/dist/message-loader.d.ts
CHANGED
|
@@ -117,6 +117,7 @@ export declare class MessageLoader {
|
|
|
117
117
|
* Subscribe to events about when a locale has loaded.
|
|
118
118
|
*/
|
|
119
119
|
onChange(callback: () => void): () => void;
|
|
120
|
+
isLocaleLoading(locale: LocaleId): boolean;
|
|
120
121
|
isLocaleLoaded(locale: LocaleId, requireCurrent?: boolean): boolean;
|
|
121
122
|
waitForLocaleLoaded(locale: LocaleId, requireCurrent?: boolean): Promise<void>;
|
|
122
123
|
/**
|
package/dist/message-loader.js
CHANGED
|
@@ -24,7 +24,8 @@ class MessageLoader {
|
|
|
24
24
|
this._localeLoadingPromises = {};
|
|
25
25
|
this._parseCache = {};
|
|
26
26
|
this._subscribers = new Set();
|
|
27
|
-
this.
|
|
27
|
+
// TODO: Bring this back as an option to pre-load the locale.
|
|
28
|
+
// this._loadLocale(this.defaultLocale);
|
|
28
29
|
this.fallbackMessage = new message_1.InternalIntlMessage([], this.defaultLocale);
|
|
29
30
|
// In cases where hot module replacement is available, set up cache clearing whenever the
|
|
30
31
|
// targets change so that values are always replaced.
|
|
@@ -51,10 +52,18 @@ class MessageLoader {
|
|
|
51
52
|
this._localeFileMap = localeFileMap;
|
|
52
53
|
}
|
|
53
54
|
get(key, locale) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
const expectedValue = this.getMessageValue(key, locale);
|
|
56
|
+
if (expectedValue != null)
|
|
57
|
+
return expectedValue;
|
|
58
|
+
// If the expected locale is still in progress with loading and the default locale _has not_
|
|
59
|
+
// started loading already, then return the fallback message instead of starting a load of the
|
|
60
|
+
// default locale when it may not be necessary.
|
|
61
|
+
if (this.isLocaleLoading(locale) && !this.isLocaleLoaded(this.defaultLocale)) {
|
|
62
|
+
return this.fallbackMessage;
|
|
63
|
+
}
|
|
64
|
+
const fallbackValue = this.getMessageValue(key, this.defaultLocale);
|
|
65
|
+
if (fallbackValue != null)
|
|
66
|
+
return fallbackValue;
|
|
58
67
|
// If the message couldn't be found in either the requested nor the default locale, then
|
|
59
68
|
// nothing can be done.
|
|
60
69
|
const errorKey = this._debugKeyMap != null ? `"${this._debugKeyMap[key]}" (${key})` : undefined;
|
|
@@ -122,9 +131,13 @@ class MessageLoader {
|
|
|
122
131
|
}
|
|
123
132
|
_loadLocale(locale) {
|
|
124
133
|
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
-
var _a;
|
|
134
|
+
var _a, _b;
|
|
135
|
+
// If the locale is already set in `messages`, then it doesn't need to be loaded again.
|
|
136
|
+
if (this.messages[locale] != null)
|
|
137
|
+
return;
|
|
126
138
|
// Don't re-load a locale that's already in progress.
|
|
127
139
|
if (((_a = this._localeLoadingPromises[locale]) === null || _a === void 0 ? void 0 : _a.current) != null) {
|
|
140
|
+
yield ((_b = this._localeLoadingPromises[locale]) === null || _b === void 0 ? void 0 : _b.current);
|
|
128
141
|
return;
|
|
129
142
|
}
|
|
130
143
|
// Safety check in case the locale map doesn't include a require for the
|
|
@@ -140,9 +153,6 @@ class MessageLoader {
|
|
|
140
153
|
return;
|
|
141
154
|
}
|
|
142
155
|
}
|
|
143
|
-
// If the locale is already set in `messages`, then it doesn't need to be loaded again.
|
|
144
|
-
if (this.messages[locale] != null)
|
|
145
|
-
return;
|
|
146
156
|
const current = this.localeImportMap[locale]();
|
|
147
157
|
this._localeLoadingPromises[locale] = { initialized: false, current };
|
|
148
158
|
this.messages[locale] = (yield current).default;
|
|
@@ -166,6 +176,10 @@ class MessageLoader {
|
|
|
166
176
|
this._subscribers.add(callback);
|
|
167
177
|
return () => this._subscribers.delete(callback);
|
|
168
178
|
}
|
|
179
|
+
isLocaleLoading(locale) {
|
|
180
|
+
var _a;
|
|
181
|
+
return ((_a = this._localeLoadingPromises[locale]) === null || _a === void 0 ? void 0 : _a.current) != null;
|
|
182
|
+
}
|
|
169
183
|
isLocaleLoaded(locale, requireCurrent = false) {
|
|
170
184
|
const ref = this._localeLoadingPromises[locale];
|
|
171
185
|
// Ensure the locale at least exists and is initialized.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@discord/intl",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3-canary.1346695",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Client runtime for managing messages and translations in a React project.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -14,12 +14,16 @@
|
|
|
14
14
|
"dist",
|
|
15
15
|
"src"
|
|
16
16
|
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/discord/discord-intl"
|
|
20
|
+
},
|
|
17
21
|
"dependencies": {
|
|
18
22
|
"@formatjs/icu-skeleton-parser": "1.8.2",
|
|
19
23
|
"@formatjs/intl": "^2.10.1",
|
|
20
24
|
"@intrnl/xxhash64": "^0.1.2",
|
|
21
25
|
"intl-messageformat": "^10.5.11",
|
|
22
|
-
"@discord/intl-ast": "0.10.
|
|
26
|
+
"@discord/intl-ast": "0.10.3"
|
|
23
27
|
},
|
|
24
28
|
"devDependencies": {
|
|
25
29
|
"@swc/cli": "^0.3.12",
|
|
@@ -27,17 +31,7 @@
|
|
|
27
31
|
"typescript": "*"
|
|
28
32
|
},
|
|
29
33
|
"peerDependencies": {
|
|
30
|
-
"
|
|
31
|
-
"react": "> 16",
|
|
32
|
-
"webpack": "^5.0.0"
|
|
33
|
-
},
|
|
34
|
-
"peerDependenciesMeta": {
|
|
35
|
-
"@rspack/core": {
|
|
36
|
-
"optional": true
|
|
37
|
-
},
|
|
38
|
-
"webpack": {
|
|
39
|
-
"optional": true
|
|
40
|
-
}
|
|
34
|
+
"react": "> 16"
|
|
41
35
|
},
|
|
42
36
|
"scripts": {
|
|
43
37
|
"build": "tsc",
|
package/src/intl-manager.ts
CHANGED
|
@@ -37,6 +37,24 @@ type ThisWithFormatters<
|
|
|
37
37
|
[K in keyof T]: FormatFunction<T[K]>;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
export interface IntlManagerOptions {
|
|
41
|
+
/**
|
|
42
|
+
* The locale to initially have this manager use. Useful to set when information about the user's
|
|
43
|
+
* likely locale is available sooner than when that information is definitely known (at which
|
|
44
|
+
* point `setLocale` should be called instead).
|
|
45
|
+
*
|
|
46
|
+
* @default DEFAULT_LOCALE
|
|
47
|
+
*/
|
|
48
|
+
initialLocale?: string;
|
|
49
|
+
/**
|
|
50
|
+
* The locale in which most messages are _defined_, used as an indication of where fallbacks
|
|
51
|
+
* should be loaded from when they can't be found in the requested `currentLocale`.
|
|
52
|
+
*
|
|
53
|
+
* @default DEFAULT_LOCALE
|
|
54
|
+
*/
|
|
55
|
+
defaultLocale?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
40
58
|
export class IntlManager {
|
|
41
59
|
defaultLocale: string;
|
|
42
60
|
currentLocale: string;
|
|
@@ -45,9 +63,12 @@ export class IntlManager {
|
|
|
45
63
|
|
|
46
64
|
_localeSubscriptions: Set<(locale: string) => void>;
|
|
47
65
|
|
|
48
|
-
constructor(
|
|
66
|
+
constructor({
|
|
67
|
+
initialLocale = DEFAULT_LOCALE,
|
|
68
|
+
defaultLocale = DEFAULT_LOCALE,
|
|
69
|
+
}: IntlManagerOptions) {
|
|
70
|
+
this.currentLocale = initialLocale;
|
|
49
71
|
this.defaultLocale = defaultLocale;
|
|
50
|
-
this.currentLocale = defaultLocale;
|
|
51
72
|
this.formatConfig = DEFAULT_FORMAT_CONFIG;
|
|
52
73
|
this.intl = createIntl({
|
|
53
74
|
formats: DEFAULT_FORMAT_CONFIG,
|
package/src/message-loader.ts
CHANGED
|
@@ -96,7 +96,8 @@ export class MessageLoader {
|
|
|
96
96
|
this._parseCache = {};
|
|
97
97
|
this._subscribers = new Set();
|
|
98
98
|
|
|
99
|
-
this.
|
|
99
|
+
// TODO: Bring this back as an option to pre-load the locale.
|
|
100
|
+
// this._loadLocale(this.defaultLocale);
|
|
100
101
|
this.fallbackMessage = new InternalIntlMessage([], this.defaultLocale);
|
|
101
102
|
|
|
102
103
|
// In cases where hot module replacement is available, set up cache clearing whenever the
|
|
@@ -126,9 +127,17 @@ export class MessageLoader {
|
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
get(key: string, locale: LocaleId): InternalIntlMessage {
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
const expectedValue = this.getMessageValue(key, locale);
|
|
131
|
+
if (expectedValue != null) return expectedValue;
|
|
132
|
+
// If the expected locale is still in progress with loading and the default locale _has not_
|
|
133
|
+
// started loading already, then return the fallback message instead of starting a load of the
|
|
134
|
+
// default locale when it may not be necessary.
|
|
135
|
+
if (this.isLocaleLoading(locale) && !this.isLocaleLoaded(this.defaultLocale)) {
|
|
136
|
+
return this.fallbackMessage;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const fallbackValue = this.getMessageValue(key, this.defaultLocale);
|
|
140
|
+
if (fallbackValue != null) return fallbackValue;
|
|
132
141
|
|
|
133
142
|
// If the message couldn't be found in either the requested nor the default locale, then
|
|
134
143
|
// nothing can be done.
|
|
@@ -204,8 +213,12 @@ export class MessageLoader {
|
|
|
204
213
|
}
|
|
205
214
|
|
|
206
215
|
async _loadLocale(locale: LocaleId) {
|
|
216
|
+
// If the locale is already set in `messages`, then it doesn't need to be loaded again.
|
|
217
|
+
if (this.messages[locale] != null) return;
|
|
218
|
+
|
|
207
219
|
// Don't re-load a locale that's already in progress.
|
|
208
220
|
if (this._localeLoadingPromises[locale]?.current != null) {
|
|
221
|
+
await this._localeLoadingPromises[locale]?.current;
|
|
209
222
|
return;
|
|
210
223
|
}
|
|
211
224
|
|
|
@@ -224,9 +237,6 @@ export class MessageLoader {
|
|
|
224
237
|
}
|
|
225
238
|
}
|
|
226
239
|
|
|
227
|
-
// If the locale is already set in `messages`, then it doesn't need to be loaded again.
|
|
228
|
-
if (this.messages[locale] != null) return;
|
|
229
|
-
|
|
230
240
|
const current = this.localeImportMap[locale]();
|
|
231
241
|
this._localeLoadingPromises[locale] = { initialized: false, current };
|
|
232
242
|
this.messages[locale] = (await current).default;
|
|
@@ -253,6 +263,10 @@ export class MessageLoader {
|
|
|
253
263
|
return () => this._subscribers.delete(callback);
|
|
254
264
|
}
|
|
255
265
|
|
|
266
|
+
isLocaleLoading(locale: LocaleId): boolean {
|
|
267
|
+
return this._localeLoadingPromises[locale]?.current != null;
|
|
268
|
+
}
|
|
269
|
+
|
|
256
270
|
isLocaleLoaded(locale: LocaleId, requireCurrent: boolean = false): boolean {
|
|
257
271
|
const ref = this._localeLoadingPromises[locale];
|
|
258
272
|
// Ensure the locale at least exists and is initialized.
|