# @okikio/sharedworker

For [bundlejs.com](https://bundlejs.com), and [astro.build/play](https://astro.build/play), I found that I needed a way to use `SharedWorkers` reliably on all browsers, so, I decided to make a [miniature script](https://gist.github.com/okikio/6809cfc0cdbf1df4c0573addaaf7e259) that would act as a wrapper around the `SharedWorker` class, by default it would try to create a `SharedWorker` but if unssuported it would otherwise switch to normal web workers this makes, `SharedWorkers` a type of [progressive enhancement](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement).

%[https://bundlejs.com]

When I realized that a polyfill/ponyfill doesn't exist for `SharedWorkers` I realized I needed to make one, and to ensure reliable that the polyfill was thoroughly vetted and tested for cross browser compatibility, so, I made [@okikio/sharedworker](https://github.com/okikio/sharedworker#okikiosharedworker).

%[https://github.com/okikio/sharedworker#okikiosharedworker]

## Usage

`@okikio/sharedworker` is a small mostly spec. compliant polyfill/ponyfill for `SharedWorkers`, it acts as a drop in replacement for normal `Workers`, and supports a similar API surface that matches normal `Workers`.

You use it like this,

`shared-worker.js`
```ts
/* 
 * All variables and values outside the `start(...)` function are shared between all pages, this behavior can cause unexpected bugs if you're not careful
 */
const start = (port) => {
    // All your normal Worker and SharedWorker stuff should just work
    // With no more setup 
    
    /** 
     * All variables and values inside the `start(...)` function are isolated to each page, and will be allocated seperately per page. 
     */
    port.onmessage = ({ data }) => {
        if (data == "Hey")
            port.postMessage("Hello, from the SharedWorker."); 
    };
};

self.onconnect = e => {
    let [port] = e.ports;
    start(port);
};

// This is the fallback, just in case the browser doesn't support SharedWorkers
if ("SharedWorkerGlobalScope" in self) 
    start(self);
```


`main.js`
```ts
import SharedWorker from "@okikio/sharedworker";

const sharedworker = new SharedWorker(new URL("shared-worker.js", import.meta.url));
sharedworker.onmessage = ({ data }) => {
    console.log(data); //= Hello, from SharedWorker
};

sharedworker.postMessage("Hey");
```

In the cases of [bundlejs.com](https://bundlejs.com) and [astro.build/play](https://astro.build/play), `@okikio/sharedworker` was used for [esbuild](https://github.com/okikio/bundle/blob/main/src/ts/workers/esbuild.ts) as well as the [monaco-editors](https://microsoft.github.io/monaco-editor/) [editor](https://github.com/snowpackjs/astro-repl/blob/main/src/editor/workers/editor.ts) and [typescript](https://github.com/okikio/bundle/blob/main/src/ts/workers/typescript.ts) workers. `@okikio/sharedworker` was used as a separate [utility file](https://github.com/okikio/bundle/blob/main/src/ts/util/WebWorker.ts) for easy access.

%[https://astro.build]

## Limitation

The major limitation with `@okikio/sharedworker` is that on browsers that don't natively support `SharedWorker`, you can't use `@okikio/sharedworker` as an across tab communication tool. But for everything else it's feature parity and spec. compliance should be great.

## Conclusion

So, will you use it? Tell me below, or say Hi on [twitter](https://twitter.com/okikio_dev/status/1449083583684124679?s=20).

%[https://twitter.com/okikio_dev/status/1449083583684124679?s=20]

***

[Image](https://unsplash.com/photos/_j9PDVy-WYg) from [Tengyart](https://unsplash.com/@tengyart) on [Unsplash](https://unsplash.com/). 
