Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 79 additions & 68 deletions tools/file_packager.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,73 +948,81 @@ def generate_js(data_target, data_files, metadata):
node_support_code = ''
if options.support_node:
node_support_code = '''
if (isNode) {
require('fs').readFile(packageName, (err, contents) => {
if (err) {
errback(err);
} else {
callback(contents.buffer);
}
});
return;
}'''.strip()
if (isNode) {
require('fs').readFile(packageName, (err, contents) => {
if (err) {
fetchPackageReject(err);
} else {
fetchPackageResolve(contents.buffer);
}
});
return;
}'''.strip()

ret += '''
function fetchRemotePackage(packageName, packageSize, callback, errback) {
%(node_support_code)s
Module['dataFileDownloads'] ??= {};
fetch(packageName)
.catch((cause) => Promise.reject(new Error(`Network Error: ${packageName}`, {cause}))) // If fetch fails, rewrite the error to include the failing URL & the cause.
.then((response) => {
if (!response.ok) {
return Promise.reject(new Error(`${response.status}: ${response.url}`));
}
function fetchRemotePackage(packageName, packageSize) {
return new Promise((fetchPackageResolve, fetchPackageReject) => {
%(node_support_code)s
Module['dataFileDownloads'] ??= {};
fetch(packageName)
.then((response) => {
if (!response.ok) {
fetchPackageReject(new Error(`${response.status}: ${response.url}`));
return;
}

if (!response.body && response.arrayBuffer) { // If we're using the polyfill, readers won't be available...
return response.arrayBuffer().then(callback);
}
if (!response.body && response.arrayBuffer) { // If we're using the polyfill, readers won't be available...
fetchPackageResolve(response.arrayBuffer());
return;
}

const reader = response.body.getReader();
const iterate = () => reader.read().then(handleChunk).catch((cause) => {
return Promise.reject(new Error(`Unexpected error while handling : ${response.url} ${cause}`, {cause}));
});
const reader = response.body.getReader();
const iterate = () => reader.read().then(handleChunk).catch((cause) => {
fetchPackageReject(new Error(`Unexpected error while handling : ${response.url} ${cause}`, {cause}));
return;
});

const chunks = [];
const headers = response.headers;
const total = Number(headers.get('Content-Length') ?? packageSize);
let loaded = 0;
const chunks = [];
const headers = response.headers;
const total = Number(headers.get('Content-Length') ?? packageSize);
let loaded = 0;

const handleChunk = ({done, value}) => {
if (!done) {
chunks.push(value);
loaded += value.length;
Module['dataFileDownloads'][packageName] = {loaded, total};
const handleChunk = ({done, value}) => {
if (!done) {
chunks.push(value);
loaded += value.length;
Module['dataFileDownloads'][packageName] = {loaded, total};

let totalLoaded = 0;
let totalSize = 0;
let totalLoaded = 0;
let totalSize = 0;

for (const download of Object.values(Module['dataFileDownloads'])) {
totalLoaded += download.loaded;
totalSize += download.total;
}
for (const download of Object.values(Module['dataFileDownloads'])) {
totalLoaded += download.loaded;
totalSize += download.total;
}

Module['setStatus']?.(`Downloading data... (${totalLoaded}/${totalSize})`);
return iterate();
} else {
const packageData = new Uint8Array(chunks.map((c) => c.length).reduce((a, b) => a + b, 0));
let offset = 0;
for (const chunk of chunks) {
packageData.set(chunk, offset);
offset += chunk.length;
Module['setStatus']?.(`Downloading data... (${totalLoaded}/${totalSize})`);
return iterate();
} else {
const packageData = new Uint8Array(chunks.map((c) => c.length).reduce((a, b) => a + b, 0));
let offset = 0;
for (const chunk of chunks) {
packageData.set(chunk, offset);
offset += chunk.length;
}
fetchPackageResolve(packageData.buffer);
}
callback(packageData.buffer);
}
};

Module['setStatus']?.('Downloading data...');
return iterate();
};

Module['setStatus']?.('Downloading data...');
return iterate();
})
.catch((cause) => {
// If fetch fails, rewrite the error to include the failing URL & the cause.
fetchPackageReject(new Error(`Network Error: ${packageName}`, {cause}));
});
});
};
}

function handleError(error) {
console.error('package error:', error);
Expand All @@ -1040,7 +1048,7 @@ def generate_js(data_target, data_files, metadata):
function preloadFallback(error) {
console.error(error);
console.error('falling back to default preload behavior');
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, processPackageData, handleError);
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE).then(processPackageData).catch(handleError);
};

openDatabase()
Expand All @@ -1050,15 +1058,16 @@ def generate_js(data_target, data_files, metadata):
if (useCached) {
fetchCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, metadata, processPackageData, preloadFallback);
} else {
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE,
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE)
.then(
(packageData) => {
cacheRemotePackage(db, PACKAGE_PATH + PACKAGE_NAME, packageData, {uuid:PACKAGE_UUID}, processPackageData,
(error) => {
console.error(error);
processPackageData(packageData);
});
}
, preloadFallback);
})
.catch(preloadFallback);
}
}, preloadFallback))
.catch(preloadFallback);
Expand All @@ -1073,14 +1082,16 @@ def generate_js(data_target, data_files, metadata):
var fetchedCallback = null;
var fetched = Module['getPreloadedPackage'] ? Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) : null;

if (!fetched) fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, (data) => {
if (fetchedCallback) {
fetchedCallback(data);
fetchedCallback = null;
} else {
fetched = data;
}
}, handleError);\n'''
if (!fetched) fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE)
.then((data) => {
if (fetchedCallback) {
fetchedCallback(data);
fetchedCallback = null;
} else {
fetched = data;
}
})
.catch(handleError);\n'''

code += '''
Module['preloadResults'][PACKAGE_NAME] = {fromCache: false};
Expand Down