lhk
lhk

Reputation: 30086

how to use capacitor plugin in web worker

I've added a web worker to my Ionic/React app. It's a separate typescript codebase and bundled to /assets/dist/worker.js

To reproduce the setup, you could use this minimal example web worker:

import {v4} from 'uuid'

console.log('worker running');
onmessage=(e)=>{
    console.log('received message');
    postMessage(v4());
}

give it its own tsconfig.json with "lib": ["WebWorker", "WebWorker.ImportScripts"], and bundle it with the bundler of your choice.

Make sure the bundled javascript is hosted under /assets and you can use it to create a web worker like this:

const myWorker = new Worker('assets/dist/worker.js');

export default function App(){
  const [v4, setV4] = useState("waiting for worker");
  myWorker.postMessage('go');
  myWorker.onmessage=(e)=>{
    setV4(e.data);
  }
  return (
  <IonApp>
    <p>{v4}</p>
  </IonApp>
)};

So far this works nicely. But it's not able to access capacitor plugins. I would like to use the webworker to offload some heavy calculations and they include calls to custom native code. This native code is accessible via a capacitor plugin. But any capacitor plugin import creates an error message. Add the following code to the worker:

import {Plugins} from '@capacitor/core';

const {Device} = Plugins;

and it throws:

ReferenceError: window is not defined

Update: Tried a hacky workaround:

(<any> self).window = self;  // <------ here
import {v4} from 'uuid'
import {Plugins} from '@capacitor/core';

const {CustomNativePlugin} = Plugins;

console.log('worker running');
onmessage=(e)=>{
    console.log(CustomNativePlugin.customCall());
    postMessage(v4());
}

This creates a new error message:

Uncaught (in promise) CustomNativePlugin does not have web implementation.

Upvotes: 2

Views: 2025

Answers (1)

Kaiido
Kaiido

Reputation: 136766

Long shot in the dark... but if the comments under you question are right and window is indeed only used as a global object to wire the plugins, and if nothing else from window that is unavailable in the Worker scope is used, then you can just do

self.window = self;

At the beginning of your Worker script.

Upvotes: 3

Related Questions