@discord/intl 0.0.5 → 0.0.6-rc.0
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 +2 -2
- package/dist/intl-manager.js +2 -2
- package/dist/message-loader.d.ts +47 -2
- package/dist/message-loader.js +96 -13
- package/package.json +1 -1
- package/src/intl-manager.ts +7 -3
- package/src/message-loader.ts +103 -12
package/dist/intl-manager.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IntlShape } from '@formatjs/intl';
|
|
2
|
-
import { LocaleImportMap, MessageLoader } from './message-loader';
|
|
2
|
+
import { LocaleImportMap, LocaleId, MessageLoader } from './message-loader';
|
|
3
3
|
import type { TypedIntlMessageGetter, FormatValuesFor, RichTextElementMap } from './types';
|
|
4
4
|
/**
|
|
5
5
|
* Fallback locale used for all internationalization when an operation in the
|
|
@@ -56,4 +56,4 @@ export declare class IntlManager<DefaultElements extends RichTextElementMap, Def
|
|
|
56
56
|
* different locales and sanity checks as needed to provide accessors for each
|
|
57
57
|
* message defined in `messageKeys`.
|
|
58
58
|
*/
|
|
59
|
-
export declare function createLoader(messageKeys: string[], localeImportMap: LocaleImportMap): MessageLoader;
|
|
59
|
+
export declare function createLoader(messageKeys: string[], localeImportMap: LocaleImportMap, defaultLocale: LocaleId): MessageLoader;
|
package/dist/intl-manager.js
CHANGED
|
@@ -133,6 +133,6 @@ exports.IntlManager = IntlManager;
|
|
|
133
133
|
* different locales and sanity checks as needed to provide accessors for each
|
|
134
134
|
* message defined in `messageKeys`.
|
|
135
135
|
*/
|
|
136
|
-
function createLoader(messageKeys, localeImportMap) {
|
|
137
|
-
return new message_loader_1.MessageLoader(messageKeys, localeImportMap);
|
|
136
|
+
function createLoader(messageKeys, localeImportMap, defaultLocale) {
|
|
137
|
+
return new message_loader_1.MessageLoader(messageKeys, localeImportMap, defaultLocale);
|
|
138
138
|
}
|
package/dist/message-loader.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface IntlMessageGetterAdditions {
|
|
|
8
8
|
export interface IntlMessageGetter extends IntlMessageGetterAdditions {
|
|
9
9
|
(locale: LocaleId): InternalIntlMessage;
|
|
10
10
|
}
|
|
11
|
-
type LocaleId = string;
|
|
11
|
+
export type LocaleId = string;
|
|
12
12
|
export type LocaleImportMap = Record<LocaleId, () => Promise<{
|
|
13
13
|
default: MessagesData;
|
|
14
14
|
}>>;
|
|
@@ -18,6 +18,12 @@ export declare class MessageLoader {
|
|
|
18
18
|
messages: Record<LocaleId, MessagesData>;
|
|
19
19
|
localeImportMap: LocaleImportMap;
|
|
20
20
|
supportedLocales: LocaleId[];
|
|
21
|
+
/**
|
|
22
|
+
* Fallback locale where messages will try to be looked up if they don't exist in the requested
|
|
23
|
+
* locale in a given call. This locale will also be immediately loaded when this loader is
|
|
24
|
+
* constructed to ensure the contents are available as soon as possible.
|
|
25
|
+
*/
|
|
26
|
+
defaultLocale: LocaleId;
|
|
21
27
|
/**
|
|
22
28
|
* Promise representing the current locale being loaded. If this is non-null,
|
|
23
29
|
* then a request has already been made to load the locale and it is waiting
|
|
@@ -35,9 +41,48 @@ export declare class MessageLoader {
|
|
|
35
41
|
* when it has loaded.
|
|
36
42
|
*/
|
|
37
43
|
_subscribers: Set<() => void>;
|
|
44
|
+
/**
|
|
45
|
+
* Message to show as a fallback when the requested message is unavailable.
|
|
46
|
+
*/
|
|
38
47
|
fallbackMessage: InternalIntlMessage;
|
|
39
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Map from hashed message keys to their original values, to provide context in error messages
|
|
50
|
+
* that would otherwise be obfuscated.
|
|
51
|
+
*
|
|
52
|
+
* Consumers should only provide this value in developer or debug environments.
|
|
53
|
+
*
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
_debugKeyMap: Record<string, string>;
|
|
57
|
+
/**
|
|
58
|
+
* Map of locale names to source file names, used to provide context for where messages are
|
|
59
|
+
* imported from during development.
|
|
60
|
+
*
|
|
61
|
+
* Consumers should only provide this value in developer or debug environments.
|
|
62
|
+
*
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
_localeFileMap: Record<string, string>;
|
|
66
|
+
constructor(messageKeys: string[], localeImportMap: LocaleImportMap, defaultLocale: LocaleId);
|
|
67
|
+
/**
|
|
68
|
+
* Provide additional debug information to use during development, providing additional context
|
|
69
|
+
* for console error messages.
|
|
70
|
+
*
|
|
71
|
+
* @param {Record<string, string>} keyMap
|
|
72
|
+
* @param {Record<string, string>} localeFileMap
|
|
73
|
+
*/
|
|
74
|
+
withDebugValues(keyMap: Record<string, string>, localeFileMap: Record<string, string>): void;
|
|
40
75
|
get(key: string, locale: LocaleId): InternalIntlMessage;
|
|
76
|
+
/**
|
|
77
|
+
* Return the value of the message with the given `key` in the given `locale`. If the message has
|
|
78
|
+
* no value in that locale, this function returns `undefined`.
|
|
79
|
+
*
|
|
80
|
+
* This function will first check the cache to see if it has already been loaded, and will later
|
|
81
|
+
* set the cache after parsing if not. If the requested locale has not yet been loaded, this
|
|
82
|
+
* function will trigger a load for that locale, but will not wait for it to resolve before
|
|
83
|
+
* returning.
|
|
84
|
+
*/
|
|
85
|
+
getMessageValue(key: string, locale: LocaleId): InternalIntlMessage | undefined;
|
|
41
86
|
/**
|
|
42
87
|
* Returns a record mapping the keys this object manages to bound functions
|
|
43
88
|
* for `get` with the that key as the first argument, allowing consumers to
|
package/dist/message-loader.js
CHANGED
|
@@ -46,42 +46,127 @@ var __values = (this && this.__values) || function(o) {
|
|
|
46
46
|
};
|
|
47
47
|
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
48
48
|
};
|
|
49
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
50
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
51
|
+
if (!m) return o;
|
|
52
|
+
var i = m.call(o), r, ar = [], e;
|
|
53
|
+
try {
|
|
54
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
55
|
+
}
|
|
56
|
+
catch (error) { e = { error: error }; }
|
|
57
|
+
finally {
|
|
58
|
+
try {
|
|
59
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
60
|
+
}
|
|
61
|
+
finally { if (e) throw e.error; }
|
|
62
|
+
}
|
|
63
|
+
return ar;
|
|
64
|
+
};
|
|
49
65
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
66
|
exports.MessageLoader = void 0;
|
|
51
67
|
var message_1 = require("./message");
|
|
52
68
|
var MessageLoader = /** @class */ (function () {
|
|
53
|
-
function MessageLoader(messageKeys, localeImportMap) {
|
|
69
|
+
function MessageLoader(messageKeys, localeImportMap, defaultLocale) {
|
|
70
|
+
var e_1, _a;
|
|
71
|
+
var _this = this;
|
|
54
72
|
this.messageKeys = messageKeys;
|
|
55
73
|
this.messages = {};
|
|
56
74
|
this.localeImportMap = localeImportMap;
|
|
57
75
|
this.supportedLocales = Object.keys(localeImportMap);
|
|
76
|
+
this.defaultLocale = defaultLocale;
|
|
58
77
|
this._localeLoadingPromises = {};
|
|
59
78
|
this._parseCache = new Map();
|
|
60
79
|
this._subscribers = new Set();
|
|
80
|
+
this._loadLocale(this.defaultLocale);
|
|
61
81
|
this.fallbackMessage = new message_1.InternalIntlMessage('THIS MESSAGE FAILED TO LOAD', 'en-US');
|
|
82
|
+
// In cases where hot module replacement is available, set up cache clearing whenever the
|
|
83
|
+
// targets change so that values are always replaced.
|
|
84
|
+
// @ts-expect-error `hot` not defined in types.
|
|
85
|
+
if (module.hot) {
|
|
86
|
+
var _loop_1 = function (locale, file) {
|
|
87
|
+
// @ts-expect-error `hot` not defined in types.
|
|
88
|
+
module.hot.accept(file, function () {
|
|
89
|
+
_this._parseCache.clear();
|
|
90
|
+
_this._loadLocale(locale);
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
try {
|
|
94
|
+
for (var _b = __values(Object.entries(localeImportMap)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
95
|
+
var _d = __read(_c.value, 2), locale = _d[0], file = _d[1];
|
|
96
|
+
_loop_1(locale, file);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
100
|
+
finally {
|
|
101
|
+
try {
|
|
102
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
103
|
+
}
|
|
104
|
+
finally { if (e_1) throw e_1.error; }
|
|
105
|
+
}
|
|
106
|
+
}
|
|
62
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Provide additional debug information to use during development, providing additional context
|
|
110
|
+
* for console error messages.
|
|
111
|
+
*
|
|
112
|
+
* @param {Record<string, string>} keyMap
|
|
113
|
+
* @param {Record<string, string>} localeFileMap
|
|
114
|
+
*/
|
|
115
|
+
MessageLoader.prototype.withDebugValues = function (keyMap, localeFileMap) {
|
|
116
|
+
this._debugKeyMap = keyMap;
|
|
117
|
+
this._localeFileMap = localeFileMap;
|
|
118
|
+
};
|
|
63
119
|
MessageLoader.prototype.get = function (key, locale) {
|
|
120
|
+
var _a;
|
|
121
|
+
var value = (_a = this.getMessageValue(key, locale)) !== null && _a !== void 0 ? _a : this.getMessageValue(key, this.defaultLocale);
|
|
122
|
+
if (value != null) {
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
// If the message couldn't be found in either the requested nor the default locale, then
|
|
126
|
+
// nothing can be done.
|
|
127
|
+
var errorKey = this._debugKeyMap != null ? "\"".concat(this._debugKeyMap[key], "\" (").concat(key, ")") : undefined;
|
|
128
|
+
var requestedLocale = this._localeFileMap != null ? "".concat(locale, " (").concat(this._localeFileMap[locale], ")") : locale;
|
|
129
|
+
var defaultLocale = this._localeFileMap != null
|
|
130
|
+
? "".concat(this.defaultLocale, " (").concat(this._localeFileMap[this.defaultLocale], ")")
|
|
131
|
+
: this.defaultLocale;
|
|
132
|
+
console.warn("Requested message ".concat(errorKey, " does not have a value in the requested locale ").concat(requestedLocale, " nor the default locale ").concat(defaultLocale));
|
|
133
|
+
return this.fallbackMessage;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Return the value of the message with the given `key` in the given `locale`. If the message has
|
|
137
|
+
* no value in that locale, this function returns `undefined`.
|
|
138
|
+
*
|
|
139
|
+
* This function will first check the cache to see if it has already been loaded, and will later
|
|
140
|
+
* set the cache after parsing if not. If the requested locale has not yet been loaded, this
|
|
141
|
+
* function will trigger a load for that locale, but will not wait for it to resolve before
|
|
142
|
+
* returning.
|
|
143
|
+
*/
|
|
144
|
+
MessageLoader.prototype.getMessageValue = function (key, locale) {
|
|
64
145
|
var cacheKey = key + '@' + locale;
|
|
65
146
|
var cachedValue = this._parseCache.get(cacheKey);
|
|
66
147
|
if (cachedValue != null)
|
|
67
148
|
return cachedValue;
|
|
149
|
+
// Return early if this locale is still in the process of being loaded.
|
|
150
|
+
if (this._localeLoadingPromises[locale] != null) {
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
// If not, check whether it's been loaded and trigger a load if not.
|
|
68
154
|
if (this.messages[locale] == null) {
|
|
69
155
|
// Ensure the locale is loaded, if it is supported
|
|
70
156
|
if (this.supportedLocales.includes(locale)) {
|
|
71
157
|
this._loadLocale(locale);
|
|
72
158
|
}
|
|
73
|
-
|
|
74
|
-
return this.fallbackMessage;
|
|
159
|
+
return undefined;
|
|
75
160
|
}
|
|
76
|
-
// Then try to return the loaded message
|
|
161
|
+
// Then try to return the loaded message.
|
|
77
162
|
if (key in this.messages[locale]) {
|
|
78
163
|
var content = this.messages[locale][key];
|
|
79
164
|
var message = new message_1.InternalIntlMessage(content, locale);
|
|
80
165
|
this._parseCache.set(cacheKey, message);
|
|
81
166
|
return message;
|
|
82
167
|
}
|
|
83
|
-
//
|
|
84
|
-
|
|
168
|
+
// Otherwise just assume it doesn't exist.
|
|
169
|
+
return undefined;
|
|
85
170
|
};
|
|
86
171
|
/**
|
|
87
172
|
* Returns a record mapping the keys this object manages to bound functions
|
|
@@ -92,7 +177,7 @@ var MessageLoader = /** @class */ (function () {
|
|
|
92
177
|
MessageLoader.prototype.getBinds = function () {
|
|
93
178
|
var _this = this;
|
|
94
179
|
var onChange = this.onChange.bind(this);
|
|
95
|
-
return this.messageKeys.reduce(function (acc, key) {
|
|
180
|
+
return Object.keys(this.messageKeys).reduce(function (acc, key) {
|
|
96
181
|
var bound = _this.get.bind(_this, key);
|
|
97
182
|
bound.onChange = onChange;
|
|
98
183
|
acc[key] = bound;
|
|
@@ -101,7 +186,7 @@ var MessageLoader = /** @class */ (function () {
|
|
|
101
186
|
};
|
|
102
187
|
MessageLoader.prototype._loadLocale = function (locale) {
|
|
103
188
|
return __awaiter(this, void 0, void 0, function () {
|
|
104
|
-
var
|
|
189
|
+
var loadingPromise, _a, _b;
|
|
105
190
|
return __generator(this, function (_c) {
|
|
106
191
|
switch (_c.label) {
|
|
107
192
|
case 0:
|
|
@@ -118,7 +203,6 @@ var MessageLoader = /** @class */ (function () {
|
|
|
118
203
|
// If the locale is already set in `messages`, then it doesn't need to be loaded again.
|
|
119
204
|
if (this.messages[locale] != null)
|
|
120
205
|
return [2 /*return*/];
|
|
121
|
-
loadStart = performance.now();
|
|
122
206
|
loadingPromise = this.localeImportMap[locale]();
|
|
123
207
|
this._localeLoadingPromises[locale] = loadingPromise;
|
|
124
208
|
_a = this.messages;
|
|
@@ -127,7 +211,6 @@ var MessageLoader = /** @class */ (function () {
|
|
|
127
211
|
case 1:
|
|
128
212
|
_a[_b] = (_c.sent()).default;
|
|
129
213
|
delete this._localeLoadingPromises[locale];
|
|
130
|
-
loadEnd = performance.now();
|
|
131
214
|
this.emitChange();
|
|
132
215
|
return [2 /*return*/];
|
|
133
216
|
}
|
|
@@ -139,19 +222,19 @@ var MessageLoader = /** @class */ (function () {
|
|
|
139
222
|
* potentially update to get new values for messages.
|
|
140
223
|
*/
|
|
141
224
|
MessageLoader.prototype.emitChange = function () {
|
|
142
|
-
var
|
|
225
|
+
var e_2, _a;
|
|
143
226
|
try {
|
|
144
227
|
for (var _b = __values(this._subscribers.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
145
228
|
var callback = _c.value;
|
|
146
229
|
callback();
|
|
147
230
|
}
|
|
148
231
|
}
|
|
149
|
-
catch (
|
|
232
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
150
233
|
finally {
|
|
151
234
|
try {
|
|
152
235
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
153
236
|
}
|
|
154
|
-
finally { if (
|
|
237
|
+
finally { if (e_2) throw e_2.error; }
|
|
155
238
|
}
|
|
156
239
|
};
|
|
157
240
|
/**
|
package/package.json
CHANGED
package/src/intl-manager.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
IntlMessageFormat,
|
|
7
7
|
} from 'intl-messageformat';
|
|
8
8
|
|
|
9
|
-
import { LocaleImportMap, MessageLoader } from './message-loader';
|
|
9
|
+
import { LocaleImportMap, LocaleId, MessageLoader } from './message-loader';
|
|
10
10
|
|
|
11
11
|
import type { TypedIntlMessageGetter, FormatValuesFor, RichTextElementMap } from './types';
|
|
12
12
|
|
|
@@ -161,6 +161,10 @@ export class IntlManager<
|
|
|
161
161
|
* different locales and sanity checks as needed to provide accessors for each
|
|
162
162
|
* message defined in `messageKeys`.
|
|
163
163
|
*/
|
|
164
|
-
export function createLoader(
|
|
165
|
-
|
|
164
|
+
export function createLoader(
|
|
165
|
+
messageKeys: string[],
|
|
166
|
+
localeImportMap: LocaleImportMap,
|
|
167
|
+
defaultLocale: LocaleId,
|
|
168
|
+
) {
|
|
169
|
+
return new MessageLoader(messageKeys, localeImportMap, defaultLocale);
|
|
166
170
|
}
|
package/src/message-loader.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface IntlMessageGetter extends IntlMessageGetterAdditions {
|
|
|
12
12
|
(locale: LocaleId): InternalIntlMessage;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
type LocaleId = string;
|
|
15
|
+
export type LocaleId = string;
|
|
16
16
|
|
|
17
17
|
export type LocaleImportMap = Record<LocaleId, () => Promise<{ default: MessagesData }>>;
|
|
18
18
|
|
|
@@ -22,6 +22,12 @@ export class MessageLoader {
|
|
|
22
22
|
messages: Record<LocaleId, MessagesData>;
|
|
23
23
|
localeImportMap: LocaleImportMap;
|
|
24
24
|
supportedLocales: LocaleId[];
|
|
25
|
+
/**
|
|
26
|
+
* Fallback locale where messages will try to be looked up if they don't exist in the requested
|
|
27
|
+
* locale in a given call. This locale will also be immediately loaded when this loader is
|
|
28
|
+
* constructed to ensure the contents are available as soon as possible.
|
|
29
|
+
*/
|
|
30
|
+
defaultLocale: LocaleId;
|
|
25
31
|
|
|
26
32
|
/**
|
|
27
33
|
* Promise representing the current locale being loaded. If this is non-null,
|
|
@@ -41,37 +47,126 @@ export class MessageLoader {
|
|
|
41
47
|
*/
|
|
42
48
|
_subscribers: Set<() => void>;
|
|
43
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Message to show as a fallback when the requested message is unavailable.
|
|
52
|
+
*/
|
|
44
53
|
fallbackMessage: InternalIntlMessage;
|
|
45
54
|
|
|
46
|
-
|
|
55
|
+
///
|
|
56
|
+
// Debug mode values
|
|
57
|
+
///
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Map from hashed message keys to their original values, to provide context in error messages
|
|
61
|
+
* that would otherwise be obfuscated.
|
|
62
|
+
*
|
|
63
|
+
* Consumers should only provide this value in developer or debug environments.
|
|
64
|
+
*
|
|
65
|
+
* @private
|
|
66
|
+
*/
|
|
67
|
+
_debugKeyMap: Record<string, string>;
|
|
68
|
+
/**
|
|
69
|
+
* Map of locale names to source file names, used to provide context for where messages are
|
|
70
|
+
* imported from during development.
|
|
71
|
+
*
|
|
72
|
+
* Consumers should only provide this value in developer or debug environments.
|
|
73
|
+
*
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
_localeFileMap: Record<string, string>;
|
|
77
|
+
|
|
78
|
+
constructor(messageKeys: string[], localeImportMap: LocaleImportMap, defaultLocale: LocaleId) {
|
|
47
79
|
this.messageKeys = messageKeys;
|
|
48
80
|
this.messages = {};
|
|
49
81
|
this.localeImportMap = localeImportMap;
|
|
50
82
|
this.supportedLocales = Object.keys(localeImportMap);
|
|
83
|
+
this.defaultLocale = defaultLocale;
|
|
51
84
|
|
|
52
85
|
this._localeLoadingPromises = {};
|
|
53
86
|
this._parseCache = new Map();
|
|
54
87
|
this._subscribers = new Set();
|
|
55
88
|
|
|
89
|
+
this._loadLocale(this.defaultLocale);
|
|
56
90
|
this.fallbackMessage = new InternalIntlMessage('THIS MESSAGE FAILED TO LOAD', 'en-US');
|
|
91
|
+
|
|
92
|
+
// In cases where hot module replacement is available, set up cache clearing whenever the
|
|
93
|
+
// targets change so that values are always replaced.
|
|
94
|
+
// @ts-expect-error `hot` not defined in types.
|
|
95
|
+
if (module.hot) {
|
|
96
|
+
for (const [locale, file] of Object.entries(localeImportMap)) {
|
|
97
|
+
// @ts-expect-error `hot` not defined in types.
|
|
98
|
+
module.hot.accept(file, () => {
|
|
99
|
+
this._parseCache.clear();
|
|
100
|
+
this._loadLocale(locale);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Provide additional debug information to use during development, providing additional context
|
|
108
|
+
* for console error messages.
|
|
109
|
+
*
|
|
110
|
+
* @param {Record<string, string>} keyMap
|
|
111
|
+
* @param {Record<string, string>} localeFileMap
|
|
112
|
+
*/
|
|
113
|
+
withDebugValues(keyMap: Record<string, string>, localeFileMap: Record<string, string>) {
|
|
114
|
+
this._debugKeyMap = keyMap;
|
|
115
|
+
this._localeFileMap = localeFileMap;
|
|
57
116
|
}
|
|
58
117
|
|
|
59
118
|
get(key: string, locale: LocaleId): InternalIntlMessage {
|
|
119
|
+
const value =
|
|
120
|
+
this.getMessageValue(key, locale) ?? this.getMessageValue(key, this.defaultLocale);
|
|
121
|
+
if (value != null) {
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// If the message couldn't be found in either the requested nor the default locale, then
|
|
126
|
+
// nothing can be done.
|
|
127
|
+
const errorKey = this._debugKeyMap != null ? `"${this._debugKeyMap[key]}" (${key})` : undefined;
|
|
128
|
+
const requestedLocale =
|
|
129
|
+
this._localeFileMap != null ? `${locale} (${this._localeFileMap[locale]})` : locale;
|
|
130
|
+
const defaultLocale =
|
|
131
|
+
this._localeFileMap != null
|
|
132
|
+
? `${this.defaultLocale} (${this._localeFileMap[this.defaultLocale]})`
|
|
133
|
+
: this.defaultLocale;
|
|
134
|
+
console.warn(
|
|
135
|
+
`Requested message ${errorKey} does not have a value in the requested locale ${requestedLocale} nor the default locale ${defaultLocale}`,
|
|
136
|
+
);
|
|
137
|
+
return this.fallbackMessage;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Return the value of the message with the given `key` in the given `locale`. If the message has
|
|
142
|
+
* no value in that locale, this function returns `undefined`.
|
|
143
|
+
*
|
|
144
|
+
* This function will first check the cache to see if it has already been loaded, and will later
|
|
145
|
+
* set the cache after parsing if not. If the requested locale has not yet been loaded, this
|
|
146
|
+
* function will trigger a load for that locale, but will not wait for it to resolve before
|
|
147
|
+
* returning.
|
|
148
|
+
*/
|
|
149
|
+
getMessageValue(key: string, locale: LocaleId): InternalIntlMessage | undefined {
|
|
60
150
|
const cacheKey = key + '@' + locale;
|
|
61
151
|
const cachedValue = this._parseCache.get(cacheKey);
|
|
62
152
|
if (cachedValue != null) return cachedValue;
|
|
63
153
|
|
|
154
|
+
// Return early if this locale is still in the process of being loaded.
|
|
155
|
+
if (this._localeLoadingPromises[locale] != null) {
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// If not, check whether it's been loaded and trigger a load if not.
|
|
64
160
|
if (this.messages[locale] == null) {
|
|
65
161
|
// Ensure the locale is loaded, if it is supported
|
|
66
162
|
if (this.supportedLocales.includes(locale)) {
|
|
67
163
|
this._loadLocale(locale);
|
|
68
164
|
}
|
|
69
165
|
|
|
70
|
-
|
|
71
|
-
return this.fallbackMessage;
|
|
166
|
+
return undefined;
|
|
72
167
|
}
|
|
73
168
|
|
|
74
|
-
// Then try to return the loaded message
|
|
169
|
+
// Then try to return the loaded message.
|
|
75
170
|
if (key in this.messages[locale]) {
|
|
76
171
|
const content = this.messages[locale][key];
|
|
77
172
|
const message = new InternalIntlMessage(content, locale);
|
|
@@ -79,10 +174,8 @@ export class MessageLoader {
|
|
|
79
174
|
return message;
|
|
80
175
|
}
|
|
81
176
|
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
`Requested message ${key} does not have a value in the requested locale nor the default locale`,
|
|
85
|
-
);
|
|
177
|
+
// Otherwise just assume it doesn't exist.
|
|
178
|
+
return undefined;
|
|
86
179
|
}
|
|
87
180
|
|
|
88
181
|
/**
|
|
@@ -93,7 +186,7 @@ export class MessageLoader {
|
|
|
93
186
|
*/
|
|
94
187
|
getBinds(): Record<string, IntlMessageGetter> {
|
|
95
188
|
const onChange = this.onChange.bind(this);
|
|
96
|
-
return this.messageKeys.reduce(
|
|
189
|
+
return Object.keys(this.messageKeys).reduce(
|
|
97
190
|
(acc, key) => {
|
|
98
191
|
const bound = this.get.bind(this, key) as IntlMessageGetter;
|
|
99
192
|
bound.onChange = onChange;
|
|
@@ -122,12 +215,10 @@ export class MessageLoader {
|
|
|
122
215
|
// If the locale is already set in `messages`, then it doesn't need to be loaded again.
|
|
123
216
|
if (this.messages[locale] != null) return;
|
|
124
217
|
|
|
125
|
-
const loadStart = performance.now();
|
|
126
218
|
const loadingPromise = this.localeImportMap[locale]();
|
|
127
219
|
this._localeLoadingPromises[locale] = loadingPromise;
|
|
128
220
|
this.messages[locale] = (await loadingPromise).default;
|
|
129
221
|
delete this._localeLoadingPromises[locale];
|
|
130
|
-
const loadEnd = performance.now();
|
|
131
222
|
this.emitChange();
|
|
132
223
|
}
|
|
133
224
|
|