Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading sea.js with importScripts fails in worker #1334

Open
eternal-turtles opened this issue Aug 7, 2023 · 6 comments
Open

Loading sea.js with importScripts fails in worker #1334

eternal-turtles opened this issue Aug 7, 2023 · 6 comments

Comments

@eternal-turtles
Copy link

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/gun@0.2020.1239/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/gun@0.2020.1239/gun.js"
);

console.log("GUN", window.GUN);

self.importScripts(
  "https://cdn.jsdelivr.net/npm/gun@0.2020.1239/sea.js" // Throws error.
);

Demo: https://github.com/eternal-turtles/gun-shared-worker-bug-demo

@amark
Copy link
Owner

amark commented Aug 8, 2023

@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?

@bmatusiak
Copy link
Collaborator

bmatusiak commented Aug 8, 2023

I think the global is called WorkerGlobalScope or something stupid

@eternal-turtles
Copy link
Author

eternal-turtles commented Aug 8, 2023

@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

@atjn
Copy link
Contributor

atjn commented Aug 9, 2023

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

@0awful
Copy link

0awful commented Aug 12, 2023

@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.

@eternal-turtles
Copy link
Author

eternal-turtles commented Aug 13, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants