diff --git a/package.json b/package.json index 88cbd89b..1470fa72 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "url": "git+https://github.com/opencor/webapp.git" }, "type": "module", - "version": "1.20261016.1", + "version": "1.20261016.2", "engines": { "bun": ">=1.2.0" }, diff --git a/src/renderer/package.json b/src/renderer/package.json index efbc3def..f7fe1602 100644 --- a/src/renderer/package.json +++ b/src/renderer/package.json @@ -42,7 +42,7 @@ }, "./style.css": "./dist/opencor.css" }, - "version": "1.20261016.1", + "version": "1.20261016.2", "libopencorVersion": "1.20261016.1", "scripts": { "build": "vite build && bun scripts/generate.version.ts", diff --git a/src/renderer/src/common/initialisation.ts b/src/renderer/src/common/initialisation.ts index 6a01e60a..854d6906 100644 --- a/src/renderer/src/common/initialisation.ts +++ b/src/renderer/src/common/initialisation.ts @@ -263,8 +263,11 @@ const importLibOpenCORGlue = async (): Promise => { // Import libOpenCOR's glue from https://opencor.ws, for a host application that doesn't serve it itself (see // importLibOpenCORGlue()). -// Note: to make its module worker same-origin, we fetch the glue's source, patch its worker-script URL so that it -// points to a same-origin blob URL, and import the patched source from that blob URL. +// Note: to make its pthread workers same-origin, we fetch the glue's source and import it from a same-origin blob URL. +// Indeed, on the Web, the glue spawns each of its pthread workers from a blob that imports the glue's own URL +// (i.e. import.meta.url), so that the workers import the glue from our same-origin blob URL. This also means that +// the blob URL must remain valid since libOpenCOR spawns its pthread workers lazily (on the first simulation run, +// and again whenever no worker is available), so revoking it would prevent the workers from being spawned. const importLibOpenCORGlueFromOpencorWs = async (): Promise => { const libOpenCORSource = await withRetries('libOpenCOR', async (attempt) => { @@ -279,40 +282,16 @@ const importLibOpenCORGlueFromOpencorWs = async (): Promise => { return response.text(); }); - // The URL of the worker script, which must be the same glue, but served from a same-origin blob URL. + const libOpenCORUrl = URL.createObjectURL(new Blob([libOpenCORSource], { type: 'text/javascript' })); - const libOpenCORWorkerUrl = URL.createObjectURL(new Blob([libOpenCORSource], { type: 'text/javascript' })); - - // Patch the glue's worker-script URL so that its worker is spawned from the same-origin blob URL. - - const workerUrlPattern = 'new URL("libopencor.js",import.meta.url)'; - - if (!libOpenCORSource.includes(workerUrlPattern)) { - // The glue doesn't contain the expected worker-script URL, which means a future version of libOpenCOR generates - // different code. So, import it directly from https://opencor.ws, which works in standard browsers (the worker will - // then be cross-origin, which is allowed with CORS), but may not in restricted ones. - // Note: the worker URL is not used in this case, so it can be revoked. - - URL.revokeObjectURL(libOpenCORWorkerUrl); - - return importLibOpenCOR(`${libOpenCORWasmBaseUrl}/libopencor.js`); - } + try { + return await importLibOpenCOR(libOpenCORUrl); + } catch (error: unknown) { + // The glue couldn't be imported, so its blob URL is no longer needed and can be revoked. - const patchedLibOpenCORUrl = URL.createObjectURL( - new Blob([libOpenCORSource.replace(workerUrlPattern, JSON.stringify(libOpenCORWorkerUrl))], { - type: 'text/javascript' - }) - ); + URL.revokeObjectURL(libOpenCORUrl); - try { - return await importLibOpenCOR(patchedLibOpenCORUrl); - } finally { - // The patched glue has now been imported, so its blob URL is no longer needed and can be revoked. - // Note: libOpenCORWorkerUrl, on the other hand, must remain valid since libOpenCOR spawns its module worker lazily - // (on the first simulation run, and again whenever no worker is available), so revoking it now would prevent - // the worker from being spawned. - - URL.revokeObjectURL(patchedLibOpenCORUrl); + throw error; } };