@@ -635,7 +635,7 @@ 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) { 
@@ -953,76 +953,62 @@ def generate_js(data_target, data_files, metadata):
953953    if  options .support_node :
954954      node_support_code  =  ''' 
955955        if (isNode) { 
956-           require('fs').readFile(packageName, (err, contents) => { 
957-             if (err) { 
958-               errback(err); 
959-             } else { 
960-               callback(contents.buffer); 
961-             } 
962-           }); 
963-           return; 
956+           var fsPromises = require('fs/promises'); 
957+           var contents = await fsPromises.readFile(packageName); 
958+           return contents.buffer; 
964959        }''' .strip ()
965960
966961    ret  +=  ''' 
967-       function fetchRemotePackage(packageName, packageSize, callback, errback ) { 
962+       async  function fetchRemotePackage(packageName, packageSize) { 
968963        %(node_support_code)s 
969964        Module['dataFileDownloads'] ??= {}; 
970-         fetch(packageName) 
971-           .catch((cause) => Promise.reject(new Error(`Network Error: ${packageName}`, {cause}))) // If fetch fails, rewrite the error to include the failing URL & the cause. 
972-           .then((response) => { 
973-             if (!response.ok) { 
974-               return Promise.reject(new Error(`${response.status}: ${response.url}`)); 
975-             } 
965+         var response = await fetch(packageName); 
966+         if (!response.ok) { 
967+           throw `${response.status}: ${response.url}`; 
968+         } 
976969
977-              if (!response.body && response.arrayBuffer) { // If we're using the polyfill, readers won't be available... 
978-                return response.arrayBuffer().then(callback ); 
979-              } 
970+         if (!response.body && response.arrayBuffer) { // If we're using the polyfill, readers won't be available... 
971+           return response.arrayBuffer(); 
972+         } 
980973
981-              const reader  = response.body.getReader() ; 
982-              const iterate  = () => reader.read().then(handleChunk).catch((cause) => {  
983-               return Promise.reject(new Error(`Unexpected error while handling : ${response.url} ${cause}`, {cause}) ); 
984-             }) ; 
974+         const chunks  = [] ; 
975+         const headers  = response.headers;  
976+         const total = Number(headers.get('Content-Length') ?? packageSize ); 
977+         let loaded = 0 ; 
985978
986-             const chunks = []; 
987-             const headers = response.headers; 
988-             const total = Number(headers.get('Content-Length') ?? packageSize); 
989-             let loaded = 0; 
979+         Module['setStatus']?.('Downloading data...'); 
980+         const reader = response.body.getReader(); 
990981
991-             const handleChunk = ({done, value}) => { 
992-               if (!done) { 
993-                 chunks.push(value); 
994-                 loaded += value.length; 
995-                 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}; 
996988
997-                  let totalLoaded = 0; 
998-                  let totalSize = 0; 
989+           let totalLoaded = 0; 
990+           let totalSize = 0; 
999991
1000-                  for (const download of Object.values(Module['dataFileDownloads'])) { 
1001-                    totalLoaded += download.loaded; 
1002-                    totalSize += download.total; 
1003-                  } 
992+           for (const download of Object.values(Module['dataFileDownloads'])) { 
993+             totalLoaded += download.loaded; 
994+             totalSize += download.total; 
995+           } 
1004996
1005-                 Module['setStatus']?.(`Downloading data... (${totalLoaded}/${totalSize})`); 
1006-                 return iterate(); 
1007-               } else { 
1008-                 const packageData = new Uint8Array(chunks.map((c) => c.length).reduce((a, b) => a + b, 0)); 
1009-                 let offset = 0; 
1010-                 for (const chunk of chunks) { 
1011-                   packageData.set(chunk, offset); 
1012-                   offset += chunk.length; 
1013-                 } 
1014-                 callback(packageData.buffer); 
1015-               } 
1016-             }; 
997+           Module['setStatus']?.(`Downloading data... (${totalLoaded}/${totalSize})`); 
998+         } 
1017999
1018-             Module['setStatus']?.('Downloading data...'); 
1019-             return iterate(); 
1020-           }); 
1021-       }; 
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+       } 
10221008
10231009      function handleError(error) { 
10241010        console.error('package error:', error); 
1025-       }; \n '''  %  {'node_support_code' : node_support_code }
1011+       }\n '''  %  {'node_support_code' : node_support_code }
10261012
10271013    code  +=  ''' 
10281014      function processPackageData(arrayBuffer) { 
@@ -1031,7 +1017,7 @@ def generate_js(data_target, data_files, metadata):
10311017        var byteArray = new Uint8Array(arrayBuffer); 
10321018        var curr; 
10331019        %s 
1034-       };  
1020+       } 
10351021      Module['addRunDependency']('datafile_%s');\n '''  %  (use_data , js_manipulation .escape_for_js_string (data_target ))
10361022    # use basename because from the browser's point of view, 
10371023    # we need to find the datafile in the same dir as the html file 
@@ -1041,33 +1027,35 @@ def generate_js(data_target, data_files, metadata):
10411027
10421028    if  options .use_preload_cache :
10431029      code  +=  ''' 
1044-         function preloadFallback(error) { 
1030+         async  function preloadFallback(error) { 
10451031          console.error(error); 
10461032          console.error('falling back to default preload behavior'); 
1047-           fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, processPackageData, handleError); 
1048-         }; 
1049- 
1050-         openDatabase() 
1051-           .then((db) => { 
1052-             checkCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME) 
1053-             .then((cachedData) => { 
1054-               Module['preloadResults'][PACKAGE_NAME] = {fromCache: !!cachedData}; 
1055-               if (cachedData) { 
1056-                 fetchCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, cachedData).then(processPackageData); 
1057-               } else { 
1058-                 fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, 
1059-                   (packageData) => { 
1060-                     cacheRemotePackage(db, PACKAGE_PATH + PACKAGE_NAME, packageData, {uuid:PACKAGE_UUID}) 
1061-                       .then(processPackageData) 
1062-                       .catch((error) => { 
1063-                         console.error(error); 
1064-                         processPackageData(packageData); 
1065-                       }); 
1066-                   } 
1067-                 , preloadFallback); 
1068-               } 
1069-             }) 
1070-           }).catch(preloadFallback); 
1033+           try { 
1034+             processPackageData(await fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE)); 
1035+           } catch (e) { 
1036+             handleError(e); 
1037+           } 
1038+         } 
1039+ 
1040+         try { 
1041+           var db = await openDatabase(); 
1042+           var pkgMetadata = await checkCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME); 
1043+           var useCached = !!pkgMetadata; 
1044+           Module['preloadResults'][PACKAGE_NAME] = {fromCache: useCached}; 
1045+           if (useCached) { 
1046+             processPackageData(await fetchCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, pkgMetadata)); 
1047+           } else { 
1048+             var packageData = await fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE); 
1049+             try { 
1050+               processPackageData(await cacheRemotePackage(db, PACKAGE_PATH + PACKAGE_NAME, packageData, {uuid:PACKAGE_UUID})) 
1051+             } catch (error) { 
1052+               console.error(error); 
1053+               processPackageData(packageData); 
1054+             } 
1055+           } 
1056+         } catch(e) { 
1057+           await preloadFallback(e); 
1058+         } 
10711059
10721060        Module['setStatus']?.('Downloading...');\n ''' 
10731061    else :
@@ -1079,14 +1067,20 @@ def generate_js(data_target, data_files, metadata):
10791067      var fetchedCallback = null; 
10801068      var fetched = Module['getPreloadedPackage'] ? Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) : null; 
10811069
1082-       if (!fetched) fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, (data) => { 
1083-         if (fetchedCallback) { 
1084-           fetchedCallback(data); 
1085-           fetchedCallback = null; 
1086-         } else { 
1087-           fetched = data; 
1088-         } 
1089-       }, handleError);\n ''' 
1070+       if (!fetched) { 
1071+         // Note that we don't use await here because we to execute the 
1072+         // the rest of this function immediately. 
1073+         fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) 
1074+           .then((data) => { 
1075+             if (fetchedCallback) { 
1076+               fetchedCallback(data); 
1077+               fetchedCallback = null; 
1078+             } else { 
1079+               fetched = data; 
1080+             } 
1081+           }) 
1082+           .catch(handleError); 
1083+       }\n ''' 
10901084
10911085      code  +=  ''' 
10921086      Module['preloadResults'][PACKAGE_NAME] = {fromCache: false}; 
@@ -1098,7 +1092,7 @@ def generate_js(data_target, data_files, metadata):
10981092      }\n ''' 
10991093
11001094  ret  +=  ''' 
1101-     function runWithFS(Module) {\n ''' 
1095+     async  function runWithFS(Module) {\n ''' 
11021096  ret  +=  code 
11031097  ret  +=  ''' 
11041098    } 
@@ -1128,7 +1122,7 @@ def generate_js(data_target, data_files, metadata):
11281122    %(node_support_code)s 
11291123    var response = await fetch(metadataUrl); 
11301124    if (!response.ok) { 
1131-       throw new Error( `${response.status}: ${response.url}`) ; 
1125+       throw `${response.status}: ${response.url}`; 
11321126    } 
11331127    var json = await response.json(); 
11341128    return loadPackage(json); 
0 commit comments