Skip to content

Instantly share code, notes, and snippets.

@DavidWells
Created December 11, 2021 23:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DavidWells/c4deb47aabf3520bf6fe956c700ce915 to your computer and use it in GitHub Desktop.
Save DavidWells/c4deb47aabf3520bf6fe956c700ce915 to your computer and use it in GitHub Desktop.
Async to sync messaging for webworkers
// via https://github.com/BuilderIO/partytown/blob/47004d63a9abafc5f84f6d4b93dbf22033fa489e/src/lib/service-worker/sync-send-message-to-main-sw.ts
import type { MainAccessRequest, MainAccessResponse, WebWorkerContext } from '../types';
const syncSendMessageToMainServiceWorker = (
webWorkerCtx: WebWorkerContext,
accessReq: MainAccessRequest
): MainAccessResponse => {
const xhr = new XMLHttpRequest();
const url = webWorkerCtx.$libPath$ + 'proxytown';
xhr.open('POST', url, false);
xhr.send(JSON.stringify(accessReq));
// look ma, i'm synchronous (•‿•)
return JSON.parse(xhr.responseText);
};
export default syncSendMessageToMainServiceWorker;

How Does It Work?

How Partytown's Sync Communication Works

Partytown relies on Web Workers, Service Workers, JavaScript Proxies, and a communication layer between them all.

  1. Scripts are disabled from running on the main thread by using the type="text/partytown" attribute on the <script/> tag.
  2. Service worker creates an onfetch handler to intercept specific requests.
  3. Web worker is given the scripts to execute within the worker thread.
  4. Web worker creates JavaScript Proxies to replicate and forward calls to the main thread APIs (such as DOM operations).
  5. Any call to the JS proxy uses synchronous XHR requests.
  6. Service worker intercepts requests, then is able to asynchronously communicate with the main thread.
  7. When the service worker receives the results from the main thread, it responds to the web worker's request.
  8. From the point of view of code executing on the web worker, everything was synchronous, and each call to the document was blocking.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment