@discord/intl-loader-core 0.10.0 → 0.10.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@discord/intl-loader-core",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "license": "MIT",
5
5
  "description": "Core utilities for writing loaders and transformers using @discord/intl",
6
6
  "author": "Jon Egeland",
@@ -29,7 +29,7 @@
29
29
  "chokidar": "^3.6.0",
30
30
  "debug": "^4.3.6",
31
31
  "fast-glob": "^3.3.2",
32
- "@discord/intl-message-database": "0.10.0"
32
+ "@discord/intl-message-database": "0.10.2"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/debug": "^4.1.12",
@@ -110,11 +110,31 @@ class MessageDefinitionsTransformer {
110
110
  ];
111
111
  }
112
112
 
113
+ /**
114
+ * Return a map of key names to bound message getter functions. If `preGenerateBinds` is
115
+ * configured to be `true`, the binds will be created as a constant object in the output.
116
+ * Otherwise, the generation will be done at runtime through the `getBinds` method on the loader.
117
+ */
118
+ createBindsObject() {
119
+ if (this.options.preGenerateBinds) {
120
+ /** @type {string[]} */
121
+ const bindLines = [];
122
+ for (const bind of Object.keys(this.options.messageKeys)) {
123
+ bindLines.push(`"${bind}"(locale) { return ${this.loaderName}.get("${bind}", locale) }`);
124
+ }
125
+ return `{${bindLines.join(',')}}`;
126
+ } else {
127
+ return `${this.loaderName}.getBinds()`;
128
+ }
129
+ }
130
+
113
131
  /**
114
132
  * Return the lines to export fields from this module, as determined by the `exportMode` on this
115
133
  * transformer.
134
+ *
135
+ * @param {string} bindsName Name of the identifier to be exported as the default binds object.
116
136
  */
117
- exportFields() {
137
+ exportFields(bindsName) {
118
138
  switch (this.options.exportMode ?? 'esm') {
119
139
  case 'esm':
120
140
  return [`export {${this.loaderName}};`, `export default binds;`];
@@ -137,16 +157,16 @@ class MessageDefinitionsTransformer {
137
157
  * @returns {string}
138
158
  */
139
159
  getOutput() {
160
+ const bindsObject = this.createBindsObject();
140
161
  return [
141
162
  this.options.getPrelude?.() ?? '// No additional prelude was configured.',
142
163
  `const {createLoader} = require('@discord/intl');`,
143
- `const _keys = ${JSON.stringify(Object.keys(this.options.messageKeys))};`,
164
+ `const binds = ${bindsObject}`,
144
165
  `const _locales = ${this.getLocaleRequireMap()};`,
145
166
  `const _defaultLocale = ${JSON.stringify(this.options.defaultLocale)};`,
146
- `const ${this.loaderName} = createLoader(_keys, _locales, _defaultLocale);`,
167
+ `const ${this.loaderName} = createLoader(Object.keys(binds), _locales, _defaultLocale);`,
147
168
  ...this.debugModeSetup(),
148
- `const binds = ${this.loaderName}.getBinds();`,
149
- ...this.exportFields(),
169
+ ...this.exportFields('binds'),
150
170
  ].join('\n');
151
171
  }
152
172
  }
@@ -90,11 +90,19 @@ export class MessageDefinitionsTransformer {
90
90
  * @returns {string[]}
91
91
  */
92
92
  debugModeSetup(): string[];
93
+ /**
94
+ * Return a map of key names to bound message getter functions. If `preGenerateBinds` is
95
+ * configured to be `true`, the binds will be created as a constant object in the output.
96
+ * Otherwise, the generation will be done at runtime through the `getBinds` method on the loader.
97
+ */
98
+ createBindsObject(): string;
93
99
  /**
94
100
  * Return the lines to export fields from this module, as determined by the `exportMode` on this
95
101
  * transformer.
102
+ *
103
+ * @param {string} bindsName Name of the identifier to be exported as the default binds object.
96
104
  */
97
- exportFields(): string[];
105
+ exportFields(bindsName: string): string[];
98
106
  /**
99
107
  * Returns the reduced, transformed output for this file. Currently not
100
108
  * configurable, but could be told to include default messages or preserve
package/types/types.d.ts CHANGED
@@ -53,6 +53,22 @@ export interface MessageDefinitionsTransformerOptions {
53
53
  * @default esm
54
54
  */
55
55
  exportMode?: 'esm' | 'commonjs' | 'transpiledEsModule';
56
+ /**
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.
68
+ *
69
+ * @default false
70
+ */
71
+ preGenerateBinds?: boolean;
56
72
  }
57
73
 
58
74
  /**
package/types.d.ts CHANGED
@@ -53,6 +53,22 @@ export interface MessageDefinitionsTransformerOptions {
53
53
  * @default esm
54
54
  */
55
55
  exportMode?: 'esm' | 'commonjs' | 'transpiledEsModule';
56
+ /**
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.
68
+ *
69
+ * @default false
70
+ */
71
+ preGenerateBinds?: boolean;
56
72
  }
57
73
 
58
74
  /**