@discord/intl-loader-core 0.18.0-canary.fa54f84 → 0.18.0-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/package.json +2 -2
- package/src/transformer.js +46 -43
- package/types/src/transformer.d.ts +14 -19
- package/types/types.d.ts +13 -14
- package/types.d.ts +13 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@discord/intl-loader-core",
|
|
3
|
-
"version": "0.18.0-
|
|
3
|
+
"version": "0.18.0-rc.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Core utilities for writing loaders and transformers using @discord/intl",
|
|
6
6
|
"author": "Jon Egeland",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"chokidar": "^3.6.0",
|
|
30
30
|
"debug": "^4.3.6",
|
|
31
|
-
"@discord/intl-message-database": "0.18.0"
|
|
31
|
+
"@discord/intl-message-database": "0.18.0-rc.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/debug": "^4.1.12",
|
package/src/transformer.js
CHANGED
|
@@ -18,19 +18,18 @@
|
|
|
18
18
|
*
|
|
19
19
|
* // SomeConsumer.tsx
|
|
20
20
|
* import someModuleMessages from 'SomeModule.messages.js';
|
|
21
|
-
*
|
|
21
|
+
* i18n.format(someModuleMessages.THIS_IS_A_MESSAGE, {values: "I'm a value!"});
|
|
22
22
|
* ```
|
|
23
23
|
*
|
|
24
24
|
* This transformer will only handle `SomeModule.messages.js`, and will output
|
|
25
25
|
* something like:
|
|
26
26
|
*
|
|
27
27
|
* ```typescript
|
|
28
|
-
* const {
|
|
29
|
-
* const
|
|
30
|
-
*
|
|
31
|
-
* export
|
|
32
|
-
*
|
|
33
|
-
* };
|
|
28
|
+
* const {i18n} = require('@discord/intl');
|
|
29
|
+
* const _keys = ["a9fn23"];
|
|
30
|
+
* const _locales = {"en-US": () => require('./messages/en-US.messages.json')};
|
|
31
|
+
* export const messagesLoader = createLoader(_keys, _locales);
|
|
32
|
+
* export default messagesLoader.getBinds();
|
|
34
33
|
* ```
|
|
35
34
|
*
|
|
36
35
|
* Notice how the message keys have been hashed into short keys, and the
|
|
@@ -42,7 +41,7 @@
|
|
|
42
41
|
*
|
|
43
42
|
* ```typescript
|
|
44
43
|
* import someModuleMessages from 'SomeModule.messages.js';
|
|
45
|
-
*
|
|
44
|
+
* i18n.format(someModuleMessages["a9fn23"], {values: "i'm a value!"});
|
|
46
45
|
* ```
|
|
47
46
|
*
|
|
48
47
|
* The transformed file also contains a named export for `messagesLoader`,
|
|
@@ -88,8 +87,9 @@ class MessageDefinitionsTransformer {
|
|
|
88
87
|
getLocaleRequireMap() {
|
|
89
88
|
const localeProperties = [];
|
|
90
89
|
for (const [locale, importPath] of Object.entries(this.options.localeMap)) {
|
|
91
|
-
// This assumes that the author has specified `importPath`
|
|
92
|
-
// the bundler, which we can't easily
|
|
90
|
+
// This assumes that the author has specified `importPath`
|
|
91
|
+
// as a properly-resolvable path for the bundler, which we can't easily
|
|
92
|
+
// enforce, unfortunately.
|
|
93
93
|
localeProperties.push(`"${locale}": () => ${this.options.getTranslationImport(importPath)}`);
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -111,27 +111,26 @@ class MessageDefinitionsTransformer {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
* When `
|
|
114
|
+
* When `options.pregenerateBinds` is set to 'proxy', this method is invoked to create it.
|
|
115
115
|
*
|
|
116
116
|
* The binds proxy is a plain `Proxy` object with configuration applied to make it act and
|
|
117
117
|
* function like a complete object, but without having to instantiate potentially thousands of
|
|
118
|
-
* binds during initialization. The
|
|
119
|
-
*
|
|
120
|
-
* of message keys are included.
|
|
121
|
-
*
|
|
122
|
-
* However, the proxy _does_ implement `ownKeys`, such that the returned list of keys represents
|
|
123
|
-
* all of the messages that have been _accessed_ through this proxy so far. This is generally
|
|
124
|
-
* more of a debugging utility than anything else, but can be useful for diagnosing when messages
|
|
125
|
-
* are used in critical paths or otherwise.
|
|
118
|
+
* binds during initialization. The Proxy supports `key in proxy` queries, getter access,
|
|
119
|
+
* spreads, and more.
|
|
126
120
|
*
|
|
121
|
+
* @param {string} keyArrayName Name of an Array to use for `keys` queries.
|
|
122
|
+
* @param {string} keySetName Name of a Set to use for `has` queries.
|
|
127
123
|
* @param {string} bindFunc Code expression that creates a getter bind
|
|
128
124
|
* @returns {string}
|
|
129
125
|
*/
|
|
130
|
-
createBindsProxy(bindFunc) {
|
|
126
|
+
createBindsProxy(keyArrayName, keySetName, bindFunc) {
|
|
131
127
|
return `new Proxy({},
|
|
132
128
|
{
|
|
129
|
+
has(self, prop) {
|
|
130
|
+
return ${keySetName}.has(prop);
|
|
131
|
+
},
|
|
133
132
|
ownKeys(self) {
|
|
134
|
-
return
|
|
133
|
+
return ${keyArrayName};
|
|
135
134
|
},
|
|
136
135
|
getOwnPropertyDescriptor(self, prop) {
|
|
137
136
|
return {
|
|
@@ -146,9 +145,11 @@ class MessageDefinitionsTransformer {
|
|
|
146
145
|
return 'object';
|
|
147
146
|
}
|
|
148
147
|
if (prop === Symbol.toStringTag) {
|
|
149
|
-
return '
|
|
148
|
+
return 'proxyAssign';
|
|
150
149
|
}
|
|
151
150
|
|
|
151
|
+
if(!${keySetName}.has(prop)) return undefined;
|
|
152
|
+
|
|
152
153
|
self[prop] ||= ${bindFunc};
|
|
153
154
|
return self[prop];
|
|
154
155
|
},
|
|
@@ -157,32 +158,34 @@ class MessageDefinitionsTransformer {
|
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
/**
|
|
160
|
-
* Return a map of key names to bound message getter functions. If `
|
|
161
|
+
* Return a map of key names to bound message getter functions. If `preGenerateBinds` is
|
|
161
162
|
* configured to be `true`, the binds will be created as a constant object in the output.
|
|
162
163
|
* Otherwise, the generation will be done at runtime through the `getBinds` method on the loader.
|
|
163
164
|
*
|
|
164
165
|
* @returns {string[]}
|
|
165
166
|
*/
|
|
166
167
|
createLoaderAndBinds() {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
)
|
|
168
|
+
if (this.options.preGenerateBinds === 'proxy') {
|
|
169
|
+
return [
|
|
170
|
+
`const _keys = ${JSON.stringify(Object.keys(this.options.messageKeys))};`,
|
|
171
|
+
'const _keySet = new Set(_keys);',
|
|
172
|
+
`const ${this.loaderName} = createLoader(_keys, _locales, _defaultLocale);`,
|
|
173
|
+
`const binds = ${this.createBindsProxy('_keys', '_keySet', `(locale) => ${this.loaderName}.get(prop, locale)`)};`,
|
|
174
|
+
];
|
|
175
|
+
} else if (this.options.preGenerateBinds === true) {
|
|
176
|
+
const bindLines = Object.keys(this.options.messageKeys).map(
|
|
177
|
+
(bind) => `"${bind}"(locale) { return ${this.loaderName}.get("${bind}", locale) }`,
|
|
178
|
+
);
|
|
179
|
+
return [
|
|
180
|
+
`const binds = {${bindLines.join(',')}};`,
|
|
181
|
+
`const ${this.loaderName} = createLoader(Object.keys(binds), _locales, _defaultLocale);`,
|
|
182
|
+
];
|
|
183
|
+
} else {
|
|
184
|
+
return [
|
|
185
|
+
`const _keys = ${JSON.stringify(Object.keys(this.options.messageKeys))};`,
|
|
186
|
+
`const ${this.loaderName} = createLoader(_keys, _locales, _defaultLocale);`,
|
|
187
|
+
`const binds = ${this.loaderName}.getBinds();`,
|
|
188
|
+
];
|
|
186
189
|
}
|
|
187
190
|
}
|
|
188
191
|
|
|
@@ -218,7 +221,7 @@ class MessageDefinitionsTransformer {
|
|
|
218
221
|
return [
|
|
219
222
|
this.options.getPrelude?.() ?? '// No additional prelude was configured.',
|
|
220
223
|
`const {createLoader} = require('@discord/intl');`,
|
|
221
|
-
`const
|
|
224
|
+
`const _locales = ${this.getLocaleRequireMap()};`,
|
|
222
225
|
`const _defaultLocale = ${JSON.stringify(this.options.defaultLocale)};`,
|
|
223
226
|
...this.createLoaderAndBinds(),
|
|
224
227
|
...this.debugModeSetup(),
|
|
@@ -18,19 +18,18 @@
|
|
|
18
18
|
*
|
|
19
19
|
* // SomeConsumer.tsx
|
|
20
20
|
* import someModuleMessages from 'SomeModule.messages.js';
|
|
21
|
-
*
|
|
21
|
+
* i18n.format(someModuleMessages.THIS_IS_A_MESSAGE, {values: "I'm a value!"});
|
|
22
22
|
* ```
|
|
23
23
|
*
|
|
24
24
|
* This transformer will only handle `SomeModule.messages.js`, and will output
|
|
25
25
|
* something like:
|
|
26
26
|
*
|
|
27
27
|
* ```typescript
|
|
28
|
-
* const {
|
|
29
|
-
* const
|
|
30
|
-
*
|
|
31
|
-
* export
|
|
32
|
-
*
|
|
33
|
-
* };
|
|
28
|
+
* const {i18n} = require('@discord/intl');
|
|
29
|
+
* const _keys = ["a9fn23"];
|
|
30
|
+
* const _locales = {"en-US": () => require('./messages/en-US.messages.json')};
|
|
31
|
+
* export const messagesLoader = createLoader(_keys, _locales);
|
|
32
|
+
* export default messagesLoader.getBinds();
|
|
34
33
|
* ```
|
|
35
34
|
*
|
|
36
35
|
* Notice how the message keys have been hashed into short keys, and the
|
|
@@ -42,7 +41,7 @@
|
|
|
42
41
|
*
|
|
43
42
|
* ```typescript
|
|
44
43
|
* import someModuleMessages from 'SomeModule.messages.js';
|
|
45
|
-
*
|
|
44
|
+
* i18n.format(someModuleMessages["a9fn23"], {values: "i'm a value!"});
|
|
46
45
|
* ```
|
|
47
46
|
*
|
|
48
47
|
* The transformed file also contains a named export for `messagesLoader`,
|
|
@@ -92,25 +91,21 @@ export class MessageDefinitionsTransformer {
|
|
|
92
91
|
*/
|
|
93
92
|
debugModeSetup(): string[];
|
|
94
93
|
/**
|
|
95
|
-
* When `
|
|
94
|
+
* When `options.pregenerateBinds` is set to 'proxy', this method is invoked to create it.
|
|
96
95
|
*
|
|
97
96
|
* The binds proxy is a plain `Proxy` object with configuration applied to make it act and
|
|
98
97
|
* function like a complete object, but without having to instantiate potentially thousands of
|
|
99
|
-
* binds during initialization. The
|
|
100
|
-
*
|
|
101
|
-
* of message keys are included.
|
|
102
|
-
*
|
|
103
|
-
* However, the proxy _does_ implement `ownKeys`, such that the returned list of keys represents
|
|
104
|
-
* all of the messages that have been _accessed_ through this proxy so far. This is generally
|
|
105
|
-
* more of a debugging utility than anything else, but can be useful for diagnosing when messages
|
|
106
|
-
* are used in critical paths or otherwise.
|
|
98
|
+
* binds during initialization. The Proxy supports `key in proxy` queries, getter access,
|
|
99
|
+
* spreads, and more.
|
|
107
100
|
*
|
|
101
|
+
* @param {string} keyArrayName Name of an Array to use for `keys` queries.
|
|
102
|
+
* @param {string} keySetName Name of a Set to use for `has` queries.
|
|
108
103
|
* @param {string} bindFunc Code expression that creates a getter bind
|
|
109
104
|
* @returns {string}
|
|
110
105
|
*/
|
|
111
|
-
createBindsProxy(bindFunc: string): string;
|
|
106
|
+
createBindsProxy(keyArrayName: string, keySetName: string, bindFunc: string): string;
|
|
112
107
|
/**
|
|
113
|
-
* Return a map of key names to bound message getter functions. If `
|
|
108
|
+
* Return a map of key names to bound message getter functions. If `preGenerateBinds` is
|
|
114
109
|
* configured to be `true`, the binds will be created as a constant object in the output.
|
|
115
110
|
* Otherwise, the generation will be done at runtime through the `getBinds` method on the loader.
|
|
116
111
|
*
|
package/types/types.d.ts
CHANGED
|
@@ -54,22 +54,21 @@ export interface MessageDefinitionsTransformerOptions {
|
|
|
54
54
|
*/
|
|
55
55
|
exportMode?: 'esm' | 'commonjs' | 'transpiledEsModule';
|
|
56
56
|
/**
|
|
57
|
-
* Control how loader binds are generated by the transformer. When
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
57
|
+
* Control how loader binds are generated by the transformer. When `false` (the default), binds
|
|
58
|
+
* will be created at runtime using `messagesLoader.getBinds()`. This mode saves space, at the
|
|
59
|
+
* cost of runtime overhead to iterate and create bound functions. When `true`, the iteration of
|
|
60
|
+
* messages will be done at bundle time to create a constant JS object containing all the message
|
|
61
|
+
* keys as inline functions that act as binds. This mode is much faster for runtimes to
|
|
62
|
+
* initialize, at the cost of a relatively large space increase (~70% larger than using the
|
|
63
|
+
* runtime bind mode). However, this mode can be compressed substantially when compiled to
|
|
64
|
+
* bytecode, as is the case when creating mobile bundles with Hermes. In that case, pre-generating
|
|
65
|
+
* binds gains the speed increase while still staying relatively small in the output bundle.
|
|
66
|
+
* Because of this, `metro-intl-transformer` will instead default to `true` for this option and
|
|
67
|
+
* can be disabled when not using Hermes.
|
|
65
68
|
*
|
|
66
|
-
*
|
|
67
|
-
* message key as a property defined directly on it. For smaller messages files, this reduces some
|
|
68
|
-
* of the runtime access overhead in exchange for more time spent during module initialization.
|
|
69
|
-
*
|
|
70
|
-
* @default 'proxy'
|
|
69
|
+
* @default false
|
|
71
70
|
*/
|
|
72
|
-
|
|
71
|
+
preGenerateBinds?: boolean | 'proxy';
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
/**
|
package/types.d.ts
CHANGED
|
@@ -54,22 +54,21 @@ export interface MessageDefinitionsTransformerOptions {
|
|
|
54
54
|
*/
|
|
55
55
|
exportMode?: 'esm' | 'commonjs' | 'transpiledEsModule';
|
|
56
56
|
/**
|
|
57
|
-
* Control how loader binds are generated by the transformer. When
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
57
|
+
* Control how loader binds are generated by the transformer. When `false` (the default), binds
|
|
58
|
+
* will be created at runtime using `messagesLoader.getBinds()`. This mode saves space, at the
|
|
59
|
+
* cost of runtime overhead to iterate and create bound functions. When `true`, the iteration of
|
|
60
|
+
* messages will be done at bundle time to create a constant JS object containing all the message
|
|
61
|
+
* keys as inline functions that act as binds. This mode is much faster for runtimes to
|
|
62
|
+
* initialize, at the cost of a relatively large space increase (~70% larger than using the
|
|
63
|
+
* runtime bind mode). However, this mode can be compressed substantially when compiled to
|
|
64
|
+
* bytecode, as is the case when creating mobile bundles with Hermes. In that case, pre-generating
|
|
65
|
+
* binds gains the speed increase while still staying relatively small in the output bundle.
|
|
66
|
+
* Because of this, `metro-intl-transformer` will instead default to `true` for this option and
|
|
67
|
+
* can be disabled when not using Hermes.
|
|
65
68
|
*
|
|
66
|
-
*
|
|
67
|
-
* message key as a property defined directly on it. For smaller messages files, this reduces some
|
|
68
|
-
* of the runtime access overhead in exchange for more time spent during module initialization.
|
|
69
|
-
*
|
|
70
|
-
* @default 'proxy'
|
|
69
|
+
* @default false
|
|
71
70
|
*/
|
|
72
|
-
|
|
71
|
+
preGenerateBinds?: boolean | 'proxy';
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
/**
|