gun
gun copied to clipboard
Loading sea.js with importScripts fails in worker
Hi, I'm seeing the following error when attempting to load sea.js using importScripts
in a SharedWorker:
shared.worker.js:9 Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'https://cdn.jsdelivr.net/npm/[email protected]/sea.js' failed to load.
at http://localhost:8000/shared.worker.js:9:6
In addition, it seems that loading gun.js using importScripts assigns GUN to window
, which is unavailable in a worker environment. Is there a non-hacky way to load gun.js using importScripts?
Code:
const window = {}; // gun.js import sets window.GUN.
self.importScripts(
"https://cdn.jsdelivr.net/npm/[email protected]/gun.js"
);
console.log("GUN", window.GUN);
self.importScripts(
"https://cdn.jsdelivr.net/npm/[email protected]/sea.js" // Throws error.
);
Demo: https://github.com/eternal-turtles/gun-shared-worker-bug-demo
@eternal-turtles @bmatusiak
https://github.com/amark/gun/blob/master/gun.js#L544
should only do if window exists, idk why its doing it without.
but maybe module
also doesn't exist, so it is never exported & never globalized?
the issue is we CANNOT do ES6+ module export because you can't try/catch and without it breaks old browsers.
so maybe we can do something like window||self
in a safe way?
I think the global is called WorkerGlobalScope or something stupid
@amark Yes, if the first line is removed ( const window = {};
), then the gun.js import won't fail, there's just no way I've found to actually access GUN
. The window || self
fallback would work I think, but it looks like globalThis
may be more appropriate depending on browser support (hadn't heard about this before, thanks @bmatusiak) - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis
the issue is we CANNOT do ES6+ module export because you can't try/catch and without it breaks old browsers.
@amark what old browsers are you trying to support? To not have ES6 support, you would need to be using a 5+ year old browser. That is so old, it would be trivial to hack. According to caniuse, ~98.5%* of all network traffic supports ES6, and when you factor in that GUN already uses some methods that are not supported in old browsers, it is likely only a very small set of browsers that would see new breakage.
If any developer has a need to support these old browsers, it is relatively simple to install Babel and transpile it to ancient JS. You could even do the transpiling in this repo and provide a simple code example showing how to conditionally load the transpiled vs new version of GUN.
*: adjusting for known issues with caniuse's data
@atjn There's also a question of if it would be better to use polyfills to regain the support of older browsers.
On the topic of the thread. @eternal-turtles If you're attempting to use GUN within a web worker you may run into additional problems. AFAIK you cannot open a webRTC connection within a web worker and I believe GUNDB does require webrtc. Do watch my words though because in the link I call out it is mentioned that you can transfer an existing webrtc connection to a web worker. Will that work with GUN? Who knows! @amark might have an answer but experimentation may give us all more information.
We found that adding the following at the top of the worker script is sufficient for importing gun/gun and gun/sea: self.window = self;
. I haven't had time yet to actually test doing anything with gun within a worker, but I'll be on the lookout for the WebRTC issue - thanks @imizaac
Closing this issue since self.window = self
allows for loading sea.js in a worker.