2121
2222Usage: 
2323
24-   file_packager TARGET [--preload A [B..]] [--embed C [D..]] [--exclude E [F..]] [--js-output=OUTPUT.js] [--no-force] [--use-preload-cache] [--indexedDB-name=EM_PRELOAD_CACHE] [--separate-metadata] [--lz4] [--use-preload-plugins] [--no-node] [--help] 
24+   file_packager TARGET [--preload A [B..]] [--embed C [D..]] [--exclude E [F..]] [--js-output=OUTPUT.js] [--no-force] [--use-preload-cache] [--indexedDB-name=EM_PRELOAD_CACHE] [--separate-metadata] [--lz4] [--use-preload-plugins] [--no-node] [--export-es6] [-- help] 
2525
2626  --preload  , 
2727  --embed    See emcc --help for more details on those options. 
4141
4242  --export-name=EXPORT_NAME Use custom export name (default is `Module`) 
4343
44+   --export-es6 Wrap generated code inside ES6 exported function 
45+ 
4446  --no-force Don't create output if no valid input file is specified. 
4547
4648  --use-preload-cache Stores package in IndexedDB so that subsequent loads don't need to do XHR. Checks package version. 
@@ -129,6 +131,7 @@ def __init__(self):
129131    self .use_preload_plugins  =  False 
130132    self .support_node  =  True 
131133    self .wasm64  =  False 
134+     self .export_es6  =  False 
132135
133136
134137class  DataFile :
@@ -362,7 +365,7 @@ def main():  # noqa: C901, PLR0912, PLR0915
362365  To revalidate these numbers, run `ruff check --select=C901,PLR091`. 
363366  """ 
364367  if  len (sys .argv ) ==  1 :
365-     err ('''Usage: file_packager TARGET [--preload A [B..]] [--embed C [D..]] [--exclude E [F..]] [--js-output=OUTPUT.js] [--no-force] [--use-preload-cache] [--indexedDB-name=EM_PRELOAD_CACHE] [--separate-metadata] [--lz4] [--use-preload-plugins] [--no-node] [--help] 
368+     err ('''Usage: file_packager TARGET [--preload A [B..]] [--embed C [D..]] [--exclude E [F..]] [--js-output=OUTPUT.js] [--no-force] [--use-preload-cache] [--indexedDB-name=EM_PRELOAD_CACHE] [--separate-metadata] [--lz4] [--use-preload-plugins] [--no-node] [--export-es6] [-- help] 
366369  Try 'file_packager --help' for more details.''' )
367370    return  1 
368371
@@ -391,6 +394,9 @@ def main():  # noqa: C901, PLR0912, PLR0915
391394    elif  arg  ==  '--no-force' :
392395      options .force  =  False 
393396      leading  =  '' 
397+     elif  arg  ==  '--export-es6' :
398+       options .export_es6  =  True 
399+       leading  =  '' 
394400    elif  arg  ==  '--use-preload-cache' :
395401      options .use_preload_cache  =  True 
396402      leading  =  '' 
@@ -485,6 +491,11 @@ def main():  # noqa: C901, PLR0912, PLR0915
485491    diagnostics .error ('TARGET should not be the same value of --js-output' )
486492    return  1 
487493
494+   if  options .from_emcc  and  options .export_es6 :
495+     diagnostics .error ('Can\' t use --export-es6 option together with --from-emcc since the code should be embedded ' 
496+         'within emcc\' s code' )
497+     return  1 
498+ 
488499  walked .append (__file__ )
489500  for  file_  in  data_files :
490501    if  not  should_ignore (file_ .srcpath ):
@@ -621,20 +632,38 @@ def generate_js(data_target, data_files, metadata):
621632  if  options .from_emcc :
622633    ret  =  '' 
623634  else :
624-     ret  =  ''' 
635+     if  options .export_es6 :
636+       ret  =  'export default async function loadDataFile(Module) {\n ' 
637+     else :
638+       ret  =  ''' 
625639  var Module = typeof %(EXPORT_NAME)s != 'undefined' ? %(EXPORT_NAME)s : {};\n '''  %  {"EXPORT_NAME" : options .export_name }
626640
627641  ret  +=  ''' 
628642  Module['expectedDataFileDownloads'] ??= 0; 
629-   Module['expectedDataFileDownloads']++; 
630-   (() => { 
643+   Module['expectedDataFileDownloads']++;''' 
644+ 
645+   if  not  options .export_es6 :
646+     ret  +=  ''' 
647+   (() => {''' 
648+ 
649+   ret  +=  ''' 
631650    // Do not attempt to redownload the virtual filesystem data when in a pthread or a Wasm Worker context. 
632651    var isPthread = typeof ENVIRONMENT_IS_PTHREAD != 'undefined' && ENVIRONMENT_IS_PTHREAD; 
633652    var isWasmWorker = typeof ENVIRONMENT_IS_WASM_WORKER != 'undefined' && ENVIRONMENT_IS_WASM_WORKER; 
634653    if (isPthread || isWasmWorker) return;\n ''' 
635654
636655  if  options .support_node :
637656    ret  +=  "    var isNode = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';\n " 
657+ 
658+   if  options .support_node  and  options .export_es6 :
659+         ret  +=  '''if (isNode) { 
660+     const { createRequire } = await import('module'); 
661+     /** @suppress{duplicate} */ 
662+     var require = createRequire(import.meta.url); 
663+   }\n ''' 
664+ 
665+   if  options .export_es6 :
666+     ret  +=  'return new Promise((loadDataResolve, loadDataReject) => {\n ' 
638667  ret  +=  '    async function loadPackage(metadata) {\n ' 
639668
640669  code  =  ''' 
@@ -688,6 +717,10 @@ def generate_js(data_target, data_files, metadata):
688717          Module['FS_createDataFile'](this.name, null, byteArray, true, true, true); 
689718          Module['removeRunDependency'](`fp ${that.name}`);''' 
690719
720+     finish_handler  =  create_preloaded  if  options .use_preload_plugins  else  create_data 
721+     if  options .export_es6 :
722+       finish_handler  +=  '\n loadDataResolve();' 
723+ 
691724    if  not  options .lz4 :
692725      # Data requests - for getting a block of data out of the big archive - have 
693726      # a similar API to XHRs 
@@ -720,11 +753,18 @@ def generate_js(data_target, data_files, metadata):
720753      var files = metadata['files']; 
721754      for (var i = 0; i < files.length; ++i) { 
722755        new DataRequest(files[i]['start'], files[i]['end'], files[i]['audio'] || 0).open('GET', files[i]['filename']); 
723-       }\n '''  %  ( create_preloaded   if   options . use_preload_plugins   else   create_data ) 
756+       }\n '''  %  finish_handler 
724757
725758  if  options .has_embedded  and  not  options .obj_output :
726759    diagnostics .warn ('--obj-output is recommended when using --embed.  This outputs an object file for linking directly into your application is more efficient than JS encoding' )
727760
761+   catch_handler  =  '' 
762+   if  options .export_es6 :
763+     catch_handler  +=  ''' 
764+         .catch((error) => { 
765+           loadDataReject(error); 
766+         })''' 
767+ 
728768  for  counter , file_  in  enumerate (data_files ):
729769    filename  =  file_ .dstpath 
730770    dirname  =  os .path .dirname (filename )
@@ -1049,10 +1089,10 @@ def generate_js(data_target, data_files, metadata):
10491089            } 
10501090          } 
10511091        } catch(e) { 
1052-           await preloadFallback(e); 
1092+           await preloadFallback(e)%s ; 
10531093        } 
10541094
1055-         Module['setStatus']?.('Downloading...');\n ''' 
1095+         Module['setStatus']?.('Downloading...');\n '''   %   catch_handler 
10561096    else :
10571097      # Not using preload cache, so we might as well start the xhr ASAP, 
10581098      # potentially before JS parsing of the main codebase if it's after us. 
@@ -1065,15 +1105,16 @@ def generate_js(data_target, data_files, metadata):
10651105      if (!fetched) { 
10661106        // Note that we don't use await here because we want to execute the 
10671107        // the rest of this function immediately. 
1068-         fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE).then((data) => { 
1069-           if (fetchedCallback) { 
1070-             fetchedCallback(data); 
1071-             fetchedCallback = null; 
1072-           } else { 
1073-             fetched = data; 
1074-           } 
1075-         }) 
1076-       }\n ''' 
1108+         fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) 
1109+           .then((data) => { 
1110+             if (fetchedCallback) { 
1111+               fetchedCallback(data); 
1112+               fetchedCallback = null; 
1113+             } else { 
1114+               fetched = data; 
1115+             } 
1116+           })%s; 
1117+       }\n '''  %  catch_handler 
10771118
10781119      code  +=  ''' 
10791120      Module['preloadResults'][PACKAGE_NAME] = {fromCache: false}; 
@@ -1090,10 +1131,10 @@ def generate_js(data_target, data_files, metadata):
10901131  ret  +=  ''' 
10911132    } 
10921133    if (Module['calledRun']) { 
1093-       runWithFS(Module); 
1134+       runWithFS(Module)%s ; 
10941135    } else { 
10951136      (Module['preRun'] ??= []).push(runWithFS); // FS is not initialized yet, wait for it 
1096-     }\n ''' 
1137+     }\n '''   %   catch_handler 
10971138
10981139  if  options .separate_metadata :
10991140    node_support_code  =  '' 
@@ -1131,7 +1172,14 @@ def generate_js(data_target, data_files, metadata):
11311172    } 
11321173    loadPackage(%s);\n '''  %  json .dumps (metadata )
11331174
1134-   ret  +=  ''' 
1175+   if  options .export_es6 :
1176+     ret  +=  ''' 
1177+   }); 
1178+ } 
1179+ // END the loadDataFile function 
1180+ ''' 
1181+   else :
1182+     ret  +=  ''' 
11351183  })();\n ''' 
11361184
11371185  return  ret 
0 commit comments