@@ -635,11 +635,11 @@ def generate_js(data_target, data_files, metadata):
635635
636636  if  options .support_node :
637637    ret  +=  "    var isNode = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';\n " 
638-   ret  +=  '    function loadPackage(metadata) {\n ' 
638+   ret  +=  '    async  function loadPackage(metadata) {\n ' 
639639
640640  code  =  ''' 
641641      function assert(check, msg) { 
642-         if (!check) throw msg +  new Error().stack ; 
642+         if (!check) throw new Error(msg) ; 
643643      }\n ''' 
644644
645645  # Set up folders 
@@ -808,7 +808,7 @@ def generate_js(data_target, data_files, metadata):
808808
809809        async function openDatabase() { 
810810          if (typeof indexedDB == 'undefined') { 
811-             throw 'using IndexedDB to cache data can only be done on a web page or in a web worker'; 
811+             throw new Error( 'using IndexedDB to cache data can only be done on a web page or in a web worker') ; 
812812          } 
813813          return new Promise((resolve, reject) => { 
814814            var openRequest = indexedDB.open(DB_NAME, DB_VERSION); 
@@ -953,62 +953,58 @@ def generate_js(data_target, data_files, metadata):
953953    if  options .support_node :
954954      node_support_code  =  ''' 
955955        if (isNode) { 
956-           require('fs/promises').readFile(packageName).then((contents) => callback(contents.buffer)); 
957-           return; 
956+           var fsPromises = require('fs/promises'); 
957+           var contents = await fsPromises.readFile(packageName); 
958+           return contents.buffer; 
958959        }''' .strip ()
959960
960961    ret  +=  ''' 
961-       function fetchRemotePackage(packageName, packageSize, callback ) { 
962+       async  function fetchRemotePackage(packageName, packageSize) { 
962963        %(node_support_code)s 
963964        Module['dataFileDownloads'] ??= {}; 
964-         fetch(packageName) 
965-           .catch((cause) => Promise.reject(new Error(`Network Error: ${packageName}`, {cause}))) // If fetch fails, rewrite the error to include the failing URL & the cause. 
966-           .then((response) => { 
967-             if (!response.ok) { 
968-               return Promise.reject(new Error(`${response.status}: ${response.url}`)); 
969-             } 
965+         try { 
966+           var response = await fetch(packageName); 
967+         } catch (e) { 
968+           throw new Error(`Network Error: ${packageName}`, {e}); 
969+         } 
970+         if (!response.ok) { 
971+           throw new Error(`${response.status}: ${response.url}`); 
972+         } 
970973
971-              const reader  = response.body.getReader() ; 
972-              const iterate  = () => reader.read().then(handleChunk).catch((cause) => {  
973-               return Promise.reject(new Error(`Unexpected error while handling : ${response.url} ${cause}`, {cause}) ); 
974-             }) ; 
974+         const chunks  = [] ; 
975+         const headers  = response.headers;  
976+         const total = Number(headers.get('Content-Length') ?? packageSize ); 
977+         let loaded = 0 ; 
975978
976-             const chunks = []; 
977-             const headers = response.headers; 
978-             const total = Number(headers.get('Content-Length') ?? packageSize); 
979-             let loaded = 0; 
979+         Module['setStatus']?.('Downloading data...'); 
980+         const reader = response.body.getReader(); 
980981
981-             const handleChunk = ({done, value}) => { 
982-               if (!done) { 
983-                 chunks.push(value); 
984-                 loaded += value.length; 
985-                 Module['dataFileDownloads'][packageName] = {loaded, total}; 
982+         while (1) { 
983+           var {done, value} = await reader.read(); 
984+           if (done) break; 
985+           chunks.push(value); 
986+           loaded += value.length; 
987+           Module['dataFileDownloads'][packageName] = {loaded, total}; 
986988
987-                  let totalLoaded = 0; 
988-                  let totalSize = 0; 
989+           let totalLoaded = 0; 
990+           let totalSize = 0; 
989991
990-                  for (const download of Object.values(Module['dataFileDownloads'])) { 
991-                    totalLoaded += download.loaded; 
992-                    totalSize += download.total; 
993-                  } 
992+           for (const download of Object.values(Module['dataFileDownloads'])) { 
993+             totalLoaded += download.loaded; 
994+             totalSize += download.total; 
995+           } 
994996
995-                 Module['setStatus']?.(`Downloading data... (${totalLoaded}/${totalSize})`); 
996-                 return iterate(); 
997-               } else { 
998-                 const packageData = new Uint8Array(chunks.map((c) => c.length).reduce((a, b) => a + b, 0)); 
999-                 let offset = 0; 
1000-                 for (const chunk of chunks) { 
1001-                   packageData.set(chunk, offset); 
1002-                   offset += chunk.length; 
1003-                 } 
1004-                 callback(packageData.buffer); 
1005-               } 
1006-             }; 
997+           Module['setStatus']?.(`Downloading data... (${totalLoaded}/${totalSize})`); 
998+         } 
1007999
1008-             Module['setStatus']?.('Downloading data...'); 
1009-             return iterate(); 
1010-           }); 
1011-       };\n '''  %  {'node_support_code' : node_support_code }
1000+         const packageData = new Uint8Array(chunks.map((c) => c.length).reduce((a, b) => a + b, 0)); 
1001+         let offset = 0; 
1002+         for (const chunk of chunks) { 
1003+           packageData.set(chunk, offset); 
1004+           offset += chunk.length; 
1005+         } 
1006+         return packageData.buffer; 
1007+       }\n '''  %  {'node_support_code' : node_support_code }
10121008
10131009    code  +=  ''' 
10141010      function processPackageData(arrayBuffer) { 
@@ -1017,7 +1013,7 @@ def generate_js(data_target, data_files, metadata):
10171013        var byteArray = new Uint8Array(arrayBuffer); 
10181014        var curr; 
10191015        %s 
1020-       };  
1016+       } 
10211017      Module['addRunDependency']('datafile_%s');\n '''  %  (use_data , js_manipulation .escape_for_js_string (data_target ))
10221018    # use basename because from the browser's point of view, 
10231019    # we need to find the datafile in the same dir as the html file 
@@ -1027,32 +1023,31 @@ def generate_js(data_target, data_files, metadata):
10271023
10281024    if  options .use_preload_cache :
10291025      code  +=  ''' 
1030-         function preloadFallback(error) { 
1026+         async  function preloadFallback(error) { 
10311027          console.error(error); 
10321028          console.error('falling back to default preload behavior'); 
1033-           fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, processPackageData); 
1034-         }; 
1035- 
1036-         openDatabase() 
1037-           .then((db) => { 
1038-             checkCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME) 
1039-             .then((cachedData) => { 
1040-               Module['preloadResults'][PACKAGE_NAME] = {fromCache: !!cachedData}; 
1041-               if (cachedData) { 
1042-                 fetchCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, cachedData).then(processPackageData); 
1043-               } else { 
1044-                 fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, 
1045-                   (packageData) => { 
1046-                     cacheRemotePackage(db, PACKAGE_PATH + PACKAGE_NAME, packageData, {uuid:PACKAGE_UUID}) 
1047-                       .then(processPackageData) 
1048-                       .catch((error) => { 
1049-                         console.error(error); 
1050-                         processPackageData(packageData); 
1051-                       }); 
1052-                   }); 
1053-               } 
1054-             }) 
1055-           }).catch(preloadFallback); 
1029+           processPackageData(await fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE)); 
1030+         } 
1031+ 
1032+         try { 
1033+           var db = await openDatabase(); 
1034+           var pkgMetadata = await checkCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME); 
1035+           var useCached = !!pkgMetadata; 
1036+           Module['preloadResults'][PACKAGE_NAME] = {fromCache: useCached}; 
1037+           if (useCached) { 
1038+             processPackageData(await fetchCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, pkgMetadata)); 
1039+           } else { 
1040+             var packageData = await fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE); 
1041+             try { 
1042+               processPackageData(await cacheRemotePackage(db, PACKAGE_PATH + PACKAGE_NAME, packageData, {uuid:PACKAGE_UUID})) 
1043+             } catch (error) { 
1044+               console.error(error); 
1045+               processPackageData(packageData); 
1046+             } 
1047+           } 
1048+         } catch(e) { 
1049+           await preloadFallback(e); 
1050+         } 
10561051
10571052        Module['setStatus']?.('Downloading...');\n ''' 
10581053    else :
@@ -1064,14 +1059,18 @@ def generate_js(data_target, data_files, metadata):
10641059      var fetchedCallback = null; 
10651060      var fetched = Module['getPreloadedPackage'] ? Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) : null; 
10661061
1067-       if (!fetched) fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, (data) => { 
1068-         if (fetchedCallback) { 
1069-           fetchedCallback(data); 
1070-           fetchedCallback = null; 
1071-         } else { 
1072-           fetched = data; 
1073-         } 
1074-       });\n ''' 
1062+       if (!fetched) { 
1063+         // Note that we don't use await here because we want to execute the 
1064+         // the rest of this function immediately. 
1065+         fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE).then((data) => { 
1066+           if (fetchedCallback) { 
1067+             fetchedCallback(data); 
1068+             fetchedCallback = null; 
1069+           } else { 
1070+             fetched = data; 
1071+           } 
1072+         }) 
1073+       }\n ''' 
10751074
10761075      code  +=  ''' 
10771076      Module['preloadResults'][PACKAGE_NAME] = {fromCache: false}; 
@@ -1083,7 +1082,7 @@ def generate_js(data_target, data_files, metadata):
10831082      }\n ''' 
10841083
10851084  ret  +=  ''' 
1086-     function runWithFS(Module) {\n ''' 
1085+     async  function runWithFS(Module) {\n ''' 
10871086  ret  +=  code 
10881087  ret  +=  ''' 
10891088    } 
0 commit comments