posit-dev / shinylive

Run Shiny on Python and R (compiled to wasm) in the browser
https://shinylive.io/py/examples/
MIT License
196 stars 15 forks source link

Access DOM in Shiny Live #18

Open aghasemi opened 2 years ago

aghasemi commented 2 years ago

Hi,

I cannot access the DOM document object provided by Pyodide in a Shiny Live example. The code is here.

I created an issue in the Pyodide project asking about this. It seems the reason is that the Shiny Live Python code is running in a Web worker.

May I ask please if there is way, or a plan to create a way, to acess DOM from within ShinyPy? Such a mechansim will have the benefit of enabling a large part of the web components ecosystem for Shiny Live.

Many thanks Best

wch commented 2 years ago

Hi, it is actually possible to run Pyodide in the main thread (not in a webworker) by adding ?webworker=0 to the URL. So the url would be https://shinylive.io/py/editor/?webworker=0#code=.... Here is your app with that URL.

The reason we use a webworker by default is for performance. If Pyodide is run in the main thread, then when Python is doing computation, it will block Javascript from doing anything, and similarly, any Javascript computation will block Python.

It may be possible to proxy JS commands from the webworker to the main JS thread, but the order of execution would then become nondeterministic, and it would inherently be asynchronous, so we'd want to think carefully before implementing something like that. Also, this would only work with Shinylive and not regular Shiny.

We could make it easier to invoke JS from Python, in a way that would work with both regular Shiny and Shinylive. (See the discussion on rstudio/py-shiny#306.)

aghasemi commented 2 years ago

Hi, it is actually possible to run Pyodide in the main thread (not in a webworker) by adding ?webworker=0 to the URL. So the url would be https://shinylive.io/py/editor/?webworker=0#code=.... Here is your app with that URL.

The reason we use a webworker by default is for performance. If Pyodide is run in the main thread, then when Python is doing computation, it will block Javascript from doing anything, and similarly, any Javascript computation will block Python.

It may be possible to proxy JS commands from the webworker to the main JS thread, but the order of execution would then become nondeterministic, and it would inherently be asynchronous, so we'd want to think carefully before implementing something like that. Also, this would only work with Shinylive and not regular Shiny.

We could make it easier to invoke JS from Python, in a way that would work with both regular Shiny and Shinylive. (See the discussion on rstudio/py-shiny#306.)

Very interesting and many thanks. Does this webworker parameter also work for standalone apps, i.e. those created with the shiny create command? And is there a way to make it non-webworker by default, i.e. through a config file or something?

Many thank Best

wch commented 2 years ago

I think webworker=0 does currently work for apps deployed with shiny static.

It does make sense, though, to make it a parameter that can be set via Javascript in the web page, instead of requiring it in the URL. We can do that in a future version of Shinylive.

jcheng5 commented 2 years ago

@wch Should we transfer this issue to the shinylive repo?