@@ -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