Skip to content

Commit

Permalink
feat: support shared workers with newWebWorkerSyntax enabled (#105)
Browse files Browse the repository at this point in the history
Release-as: 0.8.2
  • Loading branch information
ValeraS authored Nov 15, 2023
1 parent 1d85c25 commit 6527cc3
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 20 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ declare module '*.worker.ts' {
```ts
import {Worker} from '@gravity-ui/app-builder/worker';

const MyWorker = new Worker(new URL('./my.worker'), import.meta.url);
const MyWorker = new Worker(new URL('./my.worker', import.meta.url));
```

To use the web worker in your main script, you need to communicate with it using the postMessage and onmessage methods. For example:
Expand Down
51 changes: 32 additions & 19 deletions src/common/webpack/worker/web-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,40 @@ declare let __webpack_public_path__: string;

class WebWorker extends Worker {
constructor(url: string | URL, options?: WorkerOptions) {
// eslint-disable-next-line camelcase
const publicPath = __webpack_public_path__;
const workerPublicPath = publicPath.match(/^https?:\/\//)
? publicPath
: new URL(publicPath, window.location.href).toString();
const objectURL = URL.createObjectURL(
new Blob(
[
[
`self.__PUBLIC_PATH__ = ${JSON.stringify(workerPublicPath)}`,
`importScripts(${JSON.stringify(url.toString())});`,
].join('\n'),
],
{
type: 'application/javascript',
},
),
);
const objectURL = generateWorkerLoader(url);
super(objectURL, options);
URL.revokeObjectURL(objectURL);
}
}

export {WebWorker as Worker};
class SharedWebWorker extends SharedWorker {
constructor(url: string | URL, options?: string | WorkerOptions) {
const objectURL = generateWorkerLoader(url);
super(objectURL, options);
URL.revokeObjectURL(objectURL);
}
}

export {WebWorker as Worker, SharedWebWorker as SharedWorker};

function generateWorkerLoader(url: string | URL) {
// eslint-disable-next-line camelcase
const publicPath = __webpack_public_path__;
const workerPublicPath = publicPath.match(/^https?:\/\//)
? publicPath
: new URL(publicPath, window.location.href).toString();
const objectURL = URL.createObjectURL(
new Blob(
[
[
`self.__PUBLIC_PATH__ = ${JSON.stringify(workerPublicPath)}`,
`importScripts(${JSON.stringify(url.toString())});`,
].join('\n'),
],
{
type: 'application/javascript',
},
),
);
return objectURL;
}

0 comments on commit 6527cc3

Please sign in to comment.