@@ -64,10 +64,45 @@ interface InlineCodeRequest {
6464 translation ?: Blob ;
6565}
6666
67+ /**
68+ * The options passed to the inliner for a batch file request
69+ */
70+ interface InlineFileBatchRequest {
71+ /**
72+ * The filename that should be processed. The data for the file is provided to the Worker
73+ * during Worker initialization.
74+ */
75+ filename : string ;
76+
77+ /**
78+ * The locale specifiers or locale objects that should be used during the inlining process of the file.
79+ */
80+ locales : ( string | { locale : string ; translation ?: Blob } ) [ ] ;
81+ }
82+
83+ /**
84+ * The result for a single locale within a batch file request.
85+ */
86+ interface InlineLocaleResult {
87+ locale : string ;
88+ code : string ;
89+ map ?: string ;
90+ messages : { type : 'error' | 'warning' ; message : string } [ ] ;
91+ }
92+
93+ /**
94+ * The response returned from a batch file request.
95+ */
96+ interface InlineFileBatchResult {
97+ file : string ;
98+ results : InlineLocaleResult [ ] ;
99+ }
100+
67101// Extract the application files and common options used for inline requests from the Worker context
68- const { files, missingTranslation } = ( workerData || { } ) as {
102+ const { files, missingTranslation, translations } = ( workerData || { } ) as {
69103 files : ReadonlyMap < string , Blob > ;
70104 missingTranslation : 'error' | 'warning' | 'ignore' ;
105+ translations ?: ReadonlyMap < string , Blob > ;
71106} ;
72107
73108/**
@@ -113,24 +148,30 @@ function getFileData(filename: string): Promise<CachedFileData> {
113148}
114149
115150/**
116- * Deserializes the translation messages for an inline request , reusing the result for any
151+ * Deserializes the translation messages for a locale , reusing the result for any
117152 * subsequent request that targets the same locale.
118- * @param request An inline request containing the locale and its serialized messages.
153+ * @param locale The locale identifier.
154+ * @param translation Optional serialized translation messages. If omitted, workerData.translations is used.
119155 * @returns The translation messages, or undefined if the locale has no translations.
120156 */
121157function loadTranslation (
122- request : InlineFileRequest | InlineCodeRequest ,
158+ locale : string ,
159+ translation ?: Blob ,
123160) : Promise < Record < string , unknown > > | undefined {
124- const { locale , translation } = request ;
125- if ( ! translation ) {
161+ const translationBlob = translation ?? translations ?. get ( locale ) ;
162+ if ( ! translationBlob ) {
126163 return undefined ;
127164 }
128165
129166 let messagesPromise = deserializedTranslations . get ( locale ) ;
130167 if ( ! messagesPromise ) {
131- messagesPromise = translation
168+ messagesPromise = translationBlob
132169 . arrayBuffer ( )
133- . then ( ( buffer ) => deserialize ( new Uint8Array ( buffer ) ) as Record < string , unknown > ) ;
170+ . then ( ( buffer ) => deserialize ( new Uint8Array ( buffer ) ) as Record < string , unknown > )
171+ . catch ( ( error ) => {
172+ deserializedTranslations . delete ( locale ) ;
173+ throw error ;
174+ } ) ;
134175 deserializedTranslations . set ( locale , messagesPromise ) ;
135176 }
136177
@@ -149,8 +190,6 @@ export default async function inlineFile(request: InlineFileRequest) {
149190
150191 // Sourcemaps are parsed on demand per request rather than cached long-term to prevent
151192 // monotonic memory growth as a worker processes multiple files across the build.
152- // When multi-locale batching is implemented, the sourcemap can be parsed once per batch and released
153- // upon batch completion.
154193 const rawMap = await files . get ( request . filename + '.map' ) ?. text ( ) ;
155194 const map = rawMap ? ( JSON . parse ( rawMap ) as SourceMapInput ) : undefined ;
156195
@@ -159,7 +198,7 @@ export default async function inlineFile(request: InlineFileRequest) {
159198 map ,
160199 metadata ,
161200 request . locale ,
162- await loadTranslation ( request ) ,
201+ await loadTranslation ( request . locale , request . translation ) ,
163202 request . filename ,
164203 ) ;
165204
@@ -171,6 +210,50 @@ export default async function inlineFile(request: InlineFileRequest) {
171210 } ;
172211}
173212
213+ /**
214+ * Inlines multiple locales and translations into a JavaScript file that contains `$localize` usage.
215+ *
216+ * @param request An InlineFileBatchRequest object representing the options for inlining.
217+ * @returns An object containing the inlined results for each requested locale.
218+ */
219+ export async function inlineFileBatch (
220+ request : InlineFileBatchRequest ,
221+ ) : Promise < InlineFileBatchResult > {
222+ const { code, metadata } = await getFileData ( request . filename ) ;
223+
224+ // Parse the sourcemap once for the entire batch.
225+ // It will naturally be garbage-collected after this batch action returns.
226+ const rawMap = await files . get ( request . filename + '.map' ) ?. text ( ) ;
227+ const map = rawMap ? ( JSON . parse ( rawMap ) as SourceMapInput ) : undefined ;
228+
229+ const results = await Promise . all (
230+ request . locales . map ( async ( entry ) => {
231+ const locale = typeof entry === 'string' ? entry : entry . locale ;
232+ const translation = typeof entry === 'string' ? undefined : entry . translation ;
233+ const result = await inlineLocalize (
234+ code ,
235+ map ,
236+ metadata ,
237+ locale ,
238+ await loadTranslation ( locale , translation ) ,
239+ request . filename ,
240+ ) ;
241+
242+ return {
243+ locale,
244+ code : result . code ,
245+ map : result . map ,
246+ messages : result . diagnostics . messages ,
247+ } ;
248+ } ) ,
249+ ) ;
250+
251+ return {
252+ file : request . filename ,
253+ results,
254+ } ;
255+ }
256+
174257/**
175258 * Inlines the provided locale and translation into JavaScript code that contains `$localize` usage.
176259 * This function is a secondary entry primarily for use with component HMR update modules.
@@ -185,7 +268,7 @@ export async function inlineCode(request: InlineCodeRequest) {
185268 undefined ,
186269 metadata ,
187270 request . locale ,
188- await loadTranslation ( request ) ,
271+ await loadTranslation ( request . locale , request . translation ) ,
189272 request . filename ,
190273 ) ;
191274
0 commit comments