@@ -635,7 +635,7 @@ 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) {
@@ -953,76 +953,62 @@ 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').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;
964
959
}''' .strip ()
965
960
966
961
ret += '''
967
- function fetchRemotePackage(packageName, packageSize, callback, errback ) {
962
+ async function fetchRemotePackage(packageName, packageSize) {
968
963
%(node_support_code)s
969
964
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
+ }
976
969
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
+ }
980
973
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 ;
985
978
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();
990
981
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};
996
988
997
- let totalLoaded = 0;
998
- let totalSize = 0;
989
+ let totalLoaded = 0;
990
+ let totalSize = 0;
999
991
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
+ }
1004
996
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
+ }
1017
999
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
+ }
1022
1008
1023
1009
function handleError(error) {
1024
1010
console.error('package error:', error);
1025
- }; \n ''' % {'node_support_code' : node_support_code }
1011
+ }\n ''' % {'node_support_code' : node_support_code }
1026
1012
1027
1013
code += '''
1028
1014
function processPackageData(arrayBuffer) {
@@ -1031,7 +1017,7 @@ def generate_js(data_target, data_files, metadata):
1031
1017
var byteArray = new Uint8Array(arrayBuffer);
1032
1018
var curr;
1033
1019
%s
1034
- };
1020
+ }
1035
1021
Module['addRunDependency']('datafile_%s');\n ''' % (use_data , js_manipulation .escape_for_js_string (data_target ))
1036
1022
# use basename because from the browser's point of view,
1037
1023
# 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):
1041
1027
1042
1028
if options .use_preload_cache :
1043
1029
code += '''
1044
- function preloadFallback(error) {
1030
+ async function preloadFallback(error) {
1045
1031
console.error(error);
1046
1032
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
+ }
1071
1059
1072
1060
Module['setStatus']?.('Downloading...');\n '''
1073
1061
else :
@@ -1079,14 +1067,20 @@ def generate_js(data_target, data_files, metadata):
1079
1067
var fetchedCallback = null;
1080
1068
var fetched = Module['getPreloadedPackage'] ? Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) : null;
1081
1069
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 '''
1090
1084
1091
1085
code += '''
1092
1086
Module['preloadResults'][PACKAGE_NAME] = {fromCache: false};
@@ -1098,7 +1092,7 @@ def generate_js(data_target, data_files, metadata):
1098
1092
}\n '''
1099
1093
1100
1094
ret += '''
1101
- function runWithFS(Module) {\n '''
1095
+ async function runWithFS(Module) {\n '''
1102
1096
ret += code
1103
1097
ret += '''
1104
1098
}
@@ -1128,7 +1122,7 @@ def generate_js(data_target, data_files, metadata):
1128
1122
%(node_support_code)s
1129
1123
var response = await fetch(metadataUrl);
1130
1124
if (!response.ok) {
1131
- throw new Error( `${response.status}: ${response.url}`) ;
1125
+ throw `${response.status}: ${response.url}`;
1132
1126
}
1133
1127
var json = await response.json();
1134
1128
return loadPackage(json);
0 commit comments