mirror of
https://github.com/gradio-app/gradio.git
synced 2025-01-24 10:54:04 +08:00
Introduce CrossOriginWorker class to load the WebWorker file from a different domain (#4731)
* Introduce CrossOriginWorker class as a workaround to load the webworker.js served from a domain different from the main page * Update the changesets --------- Co-authored-by: pngwn <hello@pngwn.io>
This commit is contained in:
parent
b6f02bdd87
commit
f9171288d4
5
.changeset/nasty-crabs-teach.md
Normal file
5
.changeset/nasty-crabs-teach.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@gradio/lite": patch
|
||||
---
|
||||
|
||||
Load the worker file from a different origin, e.g. CDN
|
@ -51,8 +51,8 @@ export async function create(options: Options) {
|
||||
observer.observe(options.target, { childList: true });
|
||||
|
||||
const worker_proxy = new WorkerProxy({
|
||||
gradioWheelUrl: gradioWheel,
|
||||
gradioClientWheelUrl: gradioClientWheel,
|
||||
gradioWheelUrl: new URL(gradioWheel, import.meta.url).href,
|
||||
gradioClientWheelUrl: new URL(gradioClientWheel, import.meta.url).href,
|
||||
requirements: []
|
||||
});
|
||||
|
||||
|
30
js/wasm/src/cross-origin-worker.ts
Normal file
30
js/wasm/src/cross-origin-worker.ts
Normal file
@ -0,0 +1,30 @@
|
||||
// A hack to load a worker script from a different origin.
|
||||
// Vite's built-in Web Workers feature does not support inlining the worker code
|
||||
// into the main bundle and always emits it to a separate file,
|
||||
// which is not compatible with the cross-origin worker.
|
||||
// So we use this hack to load the separate worker code from a domain different from the parent page.
|
||||
// Vite deals with the special syntax `new Worker(new URL("worker.ts", import.meta.url))` for the worker build,
|
||||
// so this `CrossOriginWorkerMaker` class must be defined in a separate file and
|
||||
// be imported as the `Worker` alias into the file where the syntax is used to load the worker.
|
||||
// This implementation was based on https://github.com/whitphx/stlite/blob/v0.34.0/packages/kernel/src/kernel.ts,
|
||||
// and this technique was introduced originally for Webpack at https://github.com/webpack/webpack/discussions/14648#discussioncomment-1589272
|
||||
export class CrossOriginWorkerMaker {
|
||||
public readonly worker: Worker;
|
||||
|
||||
constructor(url: URL) {
|
||||
try {
|
||||
// This is the normal way to load a worker script, which is the best straightforward if possible.
|
||||
this.worker = new Worker(url);
|
||||
} catch (e) {
|
||||
console.debug(
|
||||
`Failed to load a worker script from ${url.toString()}. Trying to load a cross-origin worker...`
|
||||
);
|
||||
const workerBlob = new Blob([`importScripts("${url.toString()}");`], {
|
||||
type: "text/javascript",
|
||||
});
|
||||
const workerBlobUrl = URL.createObjectURL(workerBlob);
|
||||
this.worker = new Worker(workerBlobUrl);
|
||||
URL.revokeObjectURL(workerBlobUrl);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
import { CrossOriginWorkerMaker as Worker } from "./cross-origin-worker";
|
||||
import type {
|
||||
HttpRequest,
|
||||
HttpResponse,
|
||||
@ -12,13 +13,16 @@ export interface WorkerProxyOptions {
|
||||
}
|
||||
|
||||
export class WorkerProxy {
|
||||
private worker: Worker;
|
||||
private worker: globalThis.Worker;
|
||||
|
||||
constructor(options: WorkerProxyOptions) {
|
||||
console.debug("WorkerProxy.constructor(): Create a new worker.");
|
||||
// Loading a worker here relies on Vite's support for WebWorkers (https://vitejs.dev/guide/features.html#web-workers),
|
||||
// assuming that this module is imported from the Gradio frontend (`@gradio/app`), which is bundled with Vite.
|
||||
this.worker = new Worker(new URL("./webworker.js", import.meta.url));
|
||||
// HACK: Use `CrossOriginWorkerMaker` imported as `Worker` here.
|
||||
// Read the comment in `cross-origin-worker.ts` for the detail.
|
||||
const workerMaker = new Worker(new URL("./webworker.js", import.meta.url));
|
||||
this.worker = workerMaker.worker;
|
||||
|
||||
this.postMessageAsync({
|
||||
type: "init",
|
||||
|
Loading…
Reference in New Issue
Block a user