@discord/intl 0.10.3-canary.b2d8368 → 0.10.4

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.
@@ -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(initialLocale?: string, defaultLocale?: string);
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
@@ -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(initialLocale = exports.DEFAULT_LOCALE, 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
  */
@@ -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
  /**
@@ -52,10 +52,18 @@ class MessageLoader {
52
52
  this._localeFileMap = localeFileMap;
53
53
  }
54
54
  get(key, locale) {
55
- var _a;
56
- const value = (_a = this.getMessageValue(key, locale)) !== null && _a !== void 0 ? _a : this.getMessageValue(key, this.defaultLocale);
57
- if (value != null)
58
- return value;
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;
59
67
  // If the message couldn't be found in either the requested nor the default locale, then
60
68
  // nothing can be done.
61
69
  const errorKey = this._debugKeyMap != null ? `"${this._debugKeyMap[key]}" (${key})` : undefined;
@@ -123,7 +131,7 @@ class MessageLoader {
123
131
  }
124
132
  _loadLocale(locale) {
125
133
  return __awaiter(this, void 0, void 0, function* () {
126
- var _a, _b;
134
+ var _a, _b, _c, _d;
127
135
  // If the locale is already set in `messages`, then it doesn't need to be loaded again.
128
136
  if (this.messages[locale] != null)
129
137
  return;
@@ -146,7 +154,8 @@ class MessageLoader {
146
154
  }
147
155
  }
148
156
  const current = this.localeImportMap[locale]();
149
- this._localeLoadingPromises[locale] = { initialized: false, current };
157
+ const isAlreadyInitialized = (_d = (_c = this._localeLoadingPromises[locale]) === null || _c === void 0 ? void 0 : _c.initialized) !== null && _d !== void 0 ? _d : false;
158
+ this._localeLoadingPromises[locale] = { initialized: isAlreadyInitialized, current };
150
159
  this.messages[locale] = (yield current).default;
151
160
  this._localeLoadingPromises[locale] = { initialized: true, current: undefined };
152
161
  this.emitChange();
@@ -168,6 +177,10 @@ class MessageLoader {
168
177
  this._subscribers.add(callback);
169
178
  return () => this._subscribers.delete(callback);
170
179
  }
180
+ isLocaleLoading(locale) {
181
+ var _a;
182
+ return ((_a = this._localeLoadingPromises[locale]) === null || _a === void 0 ? void 0 : _a.current) != null;
183
+ }
171
184
  isLocaleLoaded(locale, requireCurrent = false) {
172
185
  const ref = this._localeLoadingPromises[locale];
173
186
  // 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-canary.b2d8368",
3
+ "version": "0.10.4",
4
4
  "license": "MIT",
5
5
  "description": "Client runtime for managing messages and translations in a React project.",
6
6
  "main": "./dist/index.js",
@@ -23,7 +23,7 @@
23
23
  "@formatjs/intl": "^2.10.1",
24
24
  "@intrnl/xxhash64": "^0.1.2",
25
25
  "intl-messageformat": "^10.5.11",
26
- "@discord/intl-ast": "0.10.3"
26
+ "@discord/intl-ast": "0.10.4"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@swc/cli": "^0.3.12",
@@ -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,7 +63,10 @@ export class IntlManager {
45
63
 
46
64
  _localeSubscriptions: Set<(locale: string) => void>;
47
65
 
48
- constructor(initialLocale: string = DEFAULT_LOCALE, defaultLocale: string = DEFAULT_LOCALE) {
66
+ constructor({
67
+ initialLocale = DEFAULT_LOCALE,
68
+ defaultLocale = DEFAULT_LOCALE,
69
+ }: IntlManagerOptions) {
49
70
  this.currentLocale = initialLocale;
50
71
  this.defaultLocale = defaultLocale;
51
72
  this.formatConfig = DEFAULT_FORMAT_CONFIG;
@@ -127,9 +127,17 @@ export class MessageLoader {
127
127
  }
128
128
 
129
129
  get(key: string, locale: LocaleId): InternalIntlMessage {
130
- const value =
131
- this.getMessageValue(key, locale) ?? this.getMessageValue(key, this.defaultLocale);
132
- if (value != null) return value;
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;
133
141
 
134
142
  // If the message couldn't be found in either the requested nor the default locale, then
135
143
  // nothing can be done.
@@ -230,7 +238,8 @@ export class MessageLoader {
230
238
  }
231
239
 
232
240
  const current = this.localeImportMap[locale]();
233
- this._localeLoadingPromises[locale] = { initialized: false, current };
241
+ const isAlreadyInitialized = this._localeLoadingPromises[locale]?.initialized ?? false;
242
+ this._localeLoadingPromises[locale] = { initialized: isAlreadyInitialized, current };
234
243
  this.messages[locale] = (await current).default;
235
244
  this._localeLoadingPromises[locale] = { initialized: true, current: undefined };
236
245
  this.emitChange();
@@ -255,6 +264,10 @@ export class MessageLoader {
255
264
  return () => this._subscribers.delete(callback);
256
265
  }
257
266
 
267
+ isLocaleLoading(locale: LocaleId): boolean {
268
+ return this._localeLoadingPromises[locale]?.current != null;
269
+ }
270
+
258
271
  isLocaleLoaded(locale: LocaleId, requireCurrent: boolean = false): boolean {
259
272
  const ref = this._localeLoadingPromises[locale];
260
273
  // Ensure the locale at least exists and is initialized.