@discord/intl 0.10.0-rc.1 → 0.10.0-rc.3

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/format.d.ts CHANGED
@@ -28,4 +28,4 @@ export declare abstract class FormatBuilder<Result> {
28
28
  }
29
29
  export type FormatBuilderConstructor<Result> = new () => FormatBuilder<Result>;
30
30
  export declare function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>(builder: Builder, nodes: AstNode[], locales: string | string[], formatters: Formatters, formatConfig: FormatConfig, values?: Record<string, string | object>, currentPluralValue?: number, originalMessage?: string): void;
31
- export declare function bindFormatValues<Result>(Builder: FormatBuilderConstructor<Result>, nodes: AstNode[], locales: string | string[], formatters: Formatters, formatConfig: FormatConfig, values?: Record<string, string | object>, currentPluralValue?: number): Result[];
31
+ export declare function bindFormatValues<Result>(Builder: FormatBuilderConstructor<Result>, nodes: string | AstNode[], locales: string | string[], formatters: Formatters, formatConfig: FormatConfig, values?: Record<string, string | object>, currentPluralValue?: number): Result[];
package/dist/format.js CHANGED
@@ -184,6 +184,12 @@ function bindFormatValuesWithBuilder(builder, nodes, locales, formatters, format
184
184
  }
185
185
  function bindFormatValues(Builder, nodes, locales, formatters, formatConfig, values = {}, currentPluralValue) {
186
186
  const builder = new Builder();
187
- bindFormatValuesWithBuilder(builder, nodes, locales, formatters, formatConfig, values, currentPluralValue);
188
- return builder.finish();
187
+ if (typeof nodes === 'string') {
188
+ builder.pushLiteralText(nodes);
189
+ return builder.finish();
190
+ }
191
+ else {
192
+ bindFormatValuesWithBuilder(builder, nodes, locales, formatters, formatConfig, values, currentPluralValue);
193
+ return builder.finish();
194
+ }
189
195
  }
@@ -68,18 +68,7 @@ class IntlManager {
68
68
  * immediately return the plain string value of the message in the current locale.
69
69
  */
70
70
  string(message) {
71
- const resolved = message(this.currentLocale);
72
- if (resolved == null || resolved.ast.length === 0)
73
- return '';
74
- let result = '';
75
- for (const element of resolved.ast) {
76
- if (typeof element !== 'string') {
77
- throw new Error('Attempted to call `string` formatting on a non-literal message: ' +
78
- JSON.stringify(resolved));
79
- }
80
- result += element;
81
- }
82
- return result;
71
+ return message(this.currentLocale).reserialize();
83
72
  }
84
73
  /**
85
74
  * Return a raw string representing the syntax of the original message, as
@@ -48,7 +48,9 @@ export declare class MessageLoader {
48
48
  /**
49
49
  * Map of pre-parsed messages, keyed by the message key and locale
50
50
  */
51
- _parseCache: Map<string, InternalIntlMessage>;
51
+ _parseCache: Record<LocaleId, {
52
+ [name: string]: InternalIntlMessage;
53
+ }>;
52
54
  /**
53
55
  * List of subscribers listening for changes to the current locale and
54
56
  * when it has loaded.
@@ -22,7 +22,7 @@ class MessageLoader {
22
22
  this.supportedLocales = Object.keys(localeImportMap);
23
23
  this.defaultLocale = defaultLocale;
24
24
  this._localeLoadingPromises = {};
25
- this._parseCache = new Map();
25
+ this._parseCache = {};
26
26
  this._subscribers = new Set();
27
27
  this._loadLocale(this.defaultLocale);
28
28
  this.fallbackMessage = new message_1.InternalIntlMessage([], this.defaultLocale);
@@ -34,7 +34,7 @@ class MessageLoader {
34
34
  // @ts-expect-error `hot` not defined in types.
35
35
  module.hot.accept(file, () => __awaiter(this, void 0, void 0, function* () {
36
36
  yield this._loadLocale(locale);
37
- this._parseCache.clear();
37
+ this._parseCache = {};
38
38
  }));
39
39
  }
40
40
  }
@@ -75,10 +75,11 @@ class MessageLoader {
75
75
  * returning.
76
76
  */
77
77
  getMessageValue(key, locale) {
78
- const cacheKey = key + '@' + locale;
79
- const cachedValue = this._parseCache.get(cacheKey);
80
- if (cachedValue != null)
81
- return cachedValue;
78
+ var _a, _b;
79
+ var _c;
80
+ const parsed = (_a = this._parseCache[locale]) === null || _a === void 0 ? void 0 : _a[key];
81
+ if (parsed)
82
+ return parsed;
82
83
  // Check whether the locale exists in memory. If not, start a request to
83
84
  // load the locale if one has not already started. It's impossible for
84
85
  // the request to finish within the same tick, so return undefined in any
@@ -93,7 +94,7 @@ class MessageLoader {
93
94
  if (key in this.messages[locale]) {
94
95
  const content = this.messages[locale][key];
95
96
  const message = new message_1.InternalIntlMessage(content, locale);
96
- this._parseCache.set(cacheKey, message);
97
+ ((_b = (_c = this._parseCache)[locale]) !== null && _b !== void 0 ? _b : (_c[locale] = {}))[key] = message;
97
98
  return message;
98
99
  }
99
100
  // Otherwise just assume it doesn't exist.
@@ -107,12 +108,13 @@ class MessageLoader {
107
108
  */
108
109
  getBinds() {
109
110
  const onChange = this.onChange.bind(this);
110
- return Object.keys(this.messageKeys).reduce((acc, key) => {
111
- const bound = this.get.bind(this, key);
111
+ const result = {};
112
+ for (const key in this.messageKeys) {
113
+ const bound = (locale) => this.get(key, locale);
112
114
  bound.onChange = onChange;
113
- acc[key] = bound;
114
- return acc;
115
- }, {});
115
+ result[key] = bound;
116
+ }
117
+ return result;
116
118
  }
117
119
  _loadLocale(locale) {
118
120
  return __awaiter(this, void 0, void 0, function* () {
package/dist/message.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { AstNode, FullFormatJsNode } from '@discord/intl-ast';
2
2
  export declare class InternalIntlMessage {
3
3
  locale: string;
4
- ast: AstNode[];
4
+ ast: string | AstNode[];
5
5
  constructor(messageOrAst: AstNode[] | FullFormatJsNode[], locale: string);
6
6
  /**
7
7
  * Return a stringified serialization of this message's AST, with no
package/dist/message.js CHANGED
@@ -12,6 +12,8 @@ class InternalIntlMessage {
12
12
  * formatting or values applied.
13
13
  */
14
14
  reserialize() {
15
+ if (typeof this.ast === 'string')
16
+ return this.ast;
15
17
  const result = { value: '' };
16
18
  serializeAst(this.ast, result);
17
19
  return result.value;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@discord/intl",
3
- "version": "0.10.0-rc.1",
3
+ "version": "0.10.0-rc.3",
4
4
  "license": "MIT",
5
5
  "description": "Client runtime for managing messages and translations in a React project.",
6
6
  "main": "./dist/index.js",
7
7
  "exports": {
8
8
  ".": {
9
- "default": "./dist/index.js",
10
- "types": "./dist/index.d.ts"
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
11
  }
12
12
  },
13
13
  "files": [
@@ -19,7 +19,7 @@
19
19
  "@formatjs/intl": "^2.10.1",
20
20
  "@intrnl/xxhash64": "^0.1.2",
21
21
  "intl-messageformat": "^10.5.11",
22
- "@discord/intl-ast": "0.10.0-rc.1"
22
+ "@discord/intl-ast": "0.10.0-rc.3"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@swc/cli": "^0.3.12",
package/src/format.ts CHANGED
@@ -238,7 +238,7 @@ export function bindFormatValuesWithBuilder<T, Builder extends FormatBuilder<T>>
238
238
 
239
239
  export function bindFormatValues<Result>(
240
240
  Builder: FormatBuilderConstructor<Result>,
241
- nodes: AstNode[],
241
+ nodes: string | AstNode[],
242
242
  locales: string | string[],
243
243
  formatters: Formatters,
244
244
  formatConfig: FormatConfig,
@@ -246,14 +246,19 @@ export function bindFormatValues<Result>(
246
246
  currentPluralValue?: number,
247
247
  ): Result[] {
248
248
  const builder = new Builder();
249
- bindFormatValuesWithBuilder(
250
- builder,
251
- nodes,
252
- locales,
253
- formatters,
254
- formatConfig,
255
- values,
256
- currentPluralValue,
257
- );
258
- return builder.finish();
249
+ if (typeof nodes === 'string') {
250
+ builder.pushLiteralText(nodes);
251
+ return builder.finish();
252
+ } else {
253
+ bindFormatValuesWithBuilder(
254
+ builder,
255
+ nodes,
256
+ locales,
257
+ formatters,
258
+ formatConfig,
259
+ values,
260
+ currentPluralValue,
261
+ );
262
+ return builder.finish();
263
+ }
259
264
  }
@@ -116,20 +116,7 @@ export class IntlManager {
116
116
  * immediately return the plain string value of the message in the current locale.
117
117
  */
118
118
  string<T extends TypedIntlMessageGetter<{}>>(message: T): string {
119
- const resolved = message(this.currentLocale);
120
- if (resolved == null || resolved.ast.length === 0) return '';
121
-
122
- let result = '';
123
- for (const element of resolved.ast) {
124
- if (typeof element !== 'string') {
125
- throw new Error(
126
- 'Attempted to call `string` formatting on a non-literal message: ' +
127
- JSON.stringify(resolved),
128
- );
129
- }
130
- result += element;
131
- }
132
- return result;
119
+ return message(this.currentLocale).reserialize();
133
120
  }
134
121
 
135
122
  /**
@@ -54,7 +54,7 @@ export class MessageLoader {
54
54
  /**
55
55
  * Map of pre-parsed messages, keyed by the message key and locale
56
56
  */
57
- _parseCache: Map<string, InternalIntlMessage>;
57
+ _parseCache: Record<LocaleId, { [name: string]: InternalIntlMessage }>;
58
58
 
59
59
  /**
60
60
  * List of subscribers listening for changes to the current locale and
@@ -98,7 +98,7 @@ export class MessageLoader {
98
98
  this.defaultLocale = defaultLocale;
99
99
 
100
100
  this._localeLoadingPromises = {};
101
- this._parseCache = new Map();
101
+ this._parseCache = {};
102
102
  this._subscribers = new Set();
103
103
 
104
104
  this._loadLocale(this.defaultLocale);
@@ -112,7 +112,7 @@ export class MessageLoader {
112
112
  // @ts-expect-error `hot` not defined in types.
113
113
  module.hot.accept(file, async () => {
114
114
  await this._loadLocale(locale);
115
- this._parseCache.clear();
115
+ this._parseCache = {};
116
116
  });
117
117
  }
118
118
  }
@@ -160,9 +160,8 @@ export class MessageLoader {
160
160
  * returning.
161
161
  */
162
162
  getMessageValue(key: string, locale: LocaleId): InternalIntlMessage | undefined {
163
- const cacheKey = key + '@' + locale;
164
- const cachedValue = this._parseCache.get(cacheKey);
165
- if (cachedValue != null) return cachedValue;
163
+ const parsed = this._parseCache[locale]?.[key];
164
+ if (parsed) return parsed;
166
165
 
167
166
  // Check whether the locale exists in memory. If not, start a request to
168
167
  // load the locale if one has not already started. It's impossible for
@@ -179,7 +178,7 @@ export class MessageLoader {
179
178
  if (key in this.messages[locale]) {
180
179
  const content = this.messages[locale][key];
181
180
  const message = new InternalIntlMessage(content, locale);
182
- this._parseCache.set(cacheKey, message);
181
+ (this._parseCache[locale] ??= {})[key] = message;
183
182
  return message;
184
183
  }
185
184
 
@@ -195,15 +194,14 @@ export class MessageLoader {
195
194
  */
196
195
  getBinds(): Record<string, IntlMessageGetter> {
197
196
  const onChange = this.onChange.bind(this);
198
- return Object.keys(this.messageKeys).reduce(
199
- (acc, key) => {
200
- const bound = this.get.bind(this, key) as IntlMessageGetter;
201
- bound.onChange = onChange;
202
- acc[key] = bound;
203
- return acc;
204
- },
205
- {} as Record<string, IntlMessageGetter>,
206
- );
197
+ const result: Record<string, IntlMessageGetter> = {};
198
+ for (const key in this.messageKeys) {
199
+ const bound = (locale: LocaleId) => this.get(key, locale);
200
+ bound.onChange = onChange;
201
+ result[key] = bound;
202
+ }
203
+
204
+ return result;
207
205
  }
208
206
 
209
207
  async _loadLocale(locale: LocaleId) {
package/src/message.ts CHANGED
@@ -10,7 +10,7 @@ import {
10
10
 
11
11
  export class InternalIntlMessage {
12
12
  locale: string;
13
- ast: AstNode[];
13
+ ast: string | AstNode[];
14
14
 
15
15
  constructor(messageOrAst: AstNode[] | FullFormatJsNode[], locale: string) {
16
16
  this.locale = locale;
@@ -22,6 +22,8 @@ export class InternalIntlMessage {
22
22
  * formatting or values applied.
23
23
  */
24
24
  reserialize(): string {
25
+ if (typeof this.ast === 'string') return this.ast;
26
+
25
27
  const result = { value: '' };
26
28
  serializeAst(this.ast, result);
27
29
  return result.value;