@@ -635,11 +635,11 @@ def generate_js(data_target, data_files, metadata):
635
635
636
636
if options .support_node :
637
637
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 '
639
639
640
640
code = '''
641
641
function assert(check, msg) {
642
- if (!check) throw msg + new Error().stack ;
642
+ if (!check) throw new Error(msg) ;
643
643
}\n '''
644
644
645
645
# Set up folders
@@ -808,7 +808,7 @@ def generate_js(data_target, data_files, metadata):
808
808
809
809
async function openDatabase() {
810
810
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') ;
812
812
}
813
813
return new Promise((resolve, reject) => {
814
814
var openRequest = indexedDB.open(DB_NAME, DB_VERSION);
@@ -953,62 +953,58 @@ def generate_js(data_target, data_files, metadata):
953
953
if options .support_node :
954
954
node_support_code = '''
955
955
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;
958
959
}''' .strip ()
959
960
960
961
ret += '''
961
- function fetchRemotePackage(packageName, packageSize, callback ) {
962
+ async function fetchRemotePackage(packageName, packageSize) {
962
963
%(node_support_code)s
963
964
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
+ }
970
973
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 ;
975
978
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();
980
981
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};
986
988
987
- let totalLoaded = 0;
988
- let totalSize = 0;
989
+ let totalLoaded = 0;
990
+ let totalSize = 0;
989
991
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
+ }
994
996
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
+ }
1007
999
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 }
1012
1008
1013
1009
code += '''
1014
1010
function processPackageData(arrayBuffer) {
@@ -1017,7 +1013,7 @@ def generate_js(data_target, data_files, metadata):
1017
1013
var byteArray = new Uint8Array(arrayBuffer);
1018
1014
var curr;
1019
1015
%s
1020
- };
1016
+ }
1021
1017
Module['addRunDependency']('datafile_%s');\n ''' % (use_data , js_manipulation .escape_for_js_string (data_target ))
1022
1018
# use basename because from the browser's point of view,
1023
1019
# 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):
1027
1023
1028
1024
if options .use_preload_cache :
1029
1025
code += '''
1030
- function preloadFallback(error) {
1026
+ async function preloadFallback(error) {
1031
1027
console.error(error);
1032
1028
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
+ }
1056
1051
1057
1052
Module['setStatus']?.('Downloading...');\n '''
1058
1053
else :
@@ -1064,14 +1059,18 @@ def generate_js(data_target, data_files, metadata):
1064
1059
var fetchedCallback = null;
1065
1060
var fetched = Module['getPreloadedPackage'] ? Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) : null;
1066
1061
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 '''
1075
1074
1076
1075
code += '''
1077
1076
Module['preloadResults'][PACKAGE_NAME] = {fromCache: false};
@@ -1083,7 +1082,7 @@ def generate_js(data_target, data_files, metadata):
1083
1082
}\n '''
1084
1083
1085
1084
ret += '''
1086
- function runWithFS(Module) {\n '''
1085
+ async function runWithFS(Module) {\n '''
1087
1086
ret += code
1088
1087
ret += '''
1089
1088
}
0 commit comments