diff --git a/package-lock.json b/package-lock.json index 06278262..da1ca55b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,6 @@ "@turbowarp/scratch-svg-renderer": "^1.0.0-202401111326-62c0f26", "babel-jest": "^27.4.5", "babel-loader": "^8.2.3", - "comlink": "^4.3.1", "copy-webpack-plugin": "^6.4.1", "cross-env": "^7.0.3", "css-loader": "^5.2.7", @@ -4719,12 +4718,6 @@ "node": ">= 0.8" } }, - "node_modules/comlink": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.1.tgz", - "integrity": "sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q==", - "dev": true - }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", diff --git a/package.json b/package.json index 74f3839e..db5fa9b3 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ "@turbowarp/scratch-svg-renderer": "^1.0.0-202401111326-62c0f26", "babel-jest": "^27.4.5", "babel-loader": "^8.2.3", - "comlink": "^4.3.1", "copy-webpack-plugin": "^6.4.1", "cross-env": "^7.0.3", "css-loader": "^5.2.7", diff --git a/src/build/auto-comlink-expose-loader.js b/src/build/auto-comlink-expose-loader.js deleted file mode 100644 index 83ef3c1c..00000000 --- a/src/build/auto-comlink-expose-loader.js +++ /dev/null @@ -1,11 +0,0 @@ -const loaderUtils = require('loader-utils'); - -module.exports.pitch = function (request) { - // extra whitespace here won't matter - return ` - import {expose} from 'comlink'; - import * as mod from ${loaderUtils.stringifyRequest(this, request)}; - postMessage('ready'); - expose(mod); - `; -}; diff --git a/src/build/p4-worker-loader.js b/src/build/p4-worker-loader.js deleted file mode 100644 index e3be146f..00000000 --- a/src/build/p4-worker-loader.js +++ /dev/null @@ -1,77 +0,0 @@ -const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin'); -const path = require('path'); -const loaderUtils = require('loader-utils'); - -module.exports.pitch = function (request) { - if (this.target !== 'web') { - return ` - import * as mod from ${loaderUtils.stringifyRequest(this, request)}; - const shimmedCreateWorker = () => { - return { - worker: mod, - terminate: () => {} - }; - }; - export default shimmedCreateWorker; - `; - } - const compilerOptions = this._compiler.options || {}; - const options = { - filename: compilerOptions.output.filename.replace('.js', '.worker.js') - }; - this.cacheable(false); - const callback = this.async(); - const compiler = this._compilation.createChildCompiler('p4 worker loader', options); - const exposeLoader = path.resolve(__dirname, 'auto-comlink-expose-loader.js'); - new SingleEntryPlugin( - this.context, - `!!${exposeLoader}!${request}`, - path.parse(this.resourcePath).name - ).apply(compiler); - compiler.runAsChild((err, entries, compilation) => { - if (err) return callback(err); - const file = entries[0].files[0]; - const inline = !!process.env.STANDALONE; - // extra whitespace here won't matter - const source = ` - import {wrap} from 'comlink'; - const createWorker = () => { - ${inline ? ` - const source = ${JSON.stringify(compilation.assets[file].source())}; - const blob = new Blob([source]); - const url = URL.createObjectURL(blob); - const worker = new Worker(url); - URL.revokeObjectURL(url); - ` : ` - const worker = new Worker(__webpack_public_path__ + ${JSON.stringify(file)}); - `} - return new Promise((resolve, reject) => { - const terminate = () => { - worker.terminate(); - }; - const onMessage = (e) => { - if (e.data === 'ready') { - cleanup(); - resolve({ - worker: wrap(worker), - terminate - }); - } - }; - const onError = () => { - cleanup(); - reject(new Error(${JSON.stringify(`Worker ${file} failed to load. Usually this will be fixed after refreshing.`)})); - }; - const cleanup = () => { - worker.removeEventListener('message', onMessage); - worker.removeEventListener('error', onError); - }; - worker.addEventListener('message', onMessage); - worker.addEventListener('error', onError); - }); - }; - export default createWorker; - `; - return callback(null, source); - }); -}; diff --git a/src/packager/download-project.js b/src/packager/download-project.js index c75cbf51..70635c96 100644 --- a/src/packager/download-project.js +++ b/src/packager/download-project.js @@ -70,10 +70,12 @@ const mutateScratch3InPlace = (projectData) => { optimizeSb3Json(projectData); }; -export const downloadProject = async (projectData, progressCallback = () => {}) => { +export const downloadProject = async (projectData, progressCallback = () => {}, signal) => { let analysis = unknownAnalysis(); const options = { + signal, + onProgress(type, loaded, total) { progressCallback(type, loaded, total); }, diff --git a/src/packager/load-project.js b/src/packager/load-project.js index 18725e51..37276748 100644 --- a/src/packager/load-project.js +++ b/src/packager/load-project.js @@ -1,30 +1,26 @@ -import {transfer, proxy} from 'comlink'; -import createDownloadWorker from '../build/p4-worker-loader!./download-project'; import {readAsArrayBuffer} from '../common/readers'; import request from '../common/request'; import {AbortError} from '../common/errors'; const downloadProject = async (buffer, progressCallback) => { - const {worker, terminate} = await createDownloadWorker(); - let terminateAndReject; - const downloadPromise = new Promise((resolve, reject) => { - worker.downloadProject(transfer(buffer, [buffer]), proxy(progressCallback)) - .then((res) => { - terminate(); - resolve(res); - }) - .catch((err) => { - terminate(); - reject(err) - }); - terminateAndReject = () => { - terminate(); - reject(new AbortError()); - }; - }); + const controller = typeof AbortController === 'function' && new AbortController(); + const downloadProject = await import(/* webpackChunkName: "downloader" */ './download-project.js'); + let reject; return { - promise: downloadPromise, - terminate: terminateAndReject + promise: new Promise((_resolve, _reject) => { + reject = _reject; + + downloadProject.downloadProject(buffer, progressCallback, controller && controller.signal) + .then(result => _resolve(result)) + .catch(err => _reject(err)); + }), + + terminate: () => { + reject(new AbortError()); + if (controller) { + controller.abort(); + } + } }; };