r-wasm/quarto-live

Add mechanism to define variables created in WebAssembly blocks also at build time

georgestagg opened this issue · 4 comments

@topepo

For example, if we have the block:

```{webr}
foo <- 123
```

with code to be run under WebAssembly at run time, it could be useful for this code to optionally also run at build time so that the results can be accessed in later standard R blocks,

```{r}
foo + 1
```

This needs to be thought about, because changing the WebAssembly block contents and re-running won't be reflected in the build time {r} blocks.

Instead, an OJS block might be a better fit for reactivity, e.g.

```{r}
#| echo: true
foo <- data.frame(aaa = c(123, 234), bbb = c(234, 456))
bar <- mean(foo$aaa)
```

```{r}
#| echo: false
ojs_define(foo)
ojs_define(bar)
```

This is a test of inline ojs interpolation: `{ojs} bar`.

```{webr}
#| input:
#|   - foo
foo$aaa + 1
```

```{ojs}
//| include: false
// Dummy cell required due to a Quarto requirement :(
```

This gets into an exceedingly gray and murky area quickly.

One solution that you might want to consider is creating a new custom wasm cell after the original cells are evaluated. You can see a demo of it with {quarto-panelize}. This preserves the document evaluation order for standard language r/python while also allowing under the autorun paradigm the wasm webr/pyodide output to be true as result.

Another interesting approach @topepo and I converged on in the meantime is the following: using the ref-label mechanism of {knitr} to duplicate a {webr} block's contents into the build-time R session.

```{webr}
#| label: some-label
foo <- data.frame(x=c(2,4,6))
```

```{r}
#| include: false
#| ref-label: some-label
```

Some inline text, computed at build-time: `nrow(foo)=` `r nrow(foo)`.

```{webr}
summary(foo)
plot(foo)
```

Of course, since we're not using the OJS features here the inline R computations such as nrow() won't be reactive to user input, but its a decent stop-gap.


I think something that would help here in future is for Quarto Live to support inline webR blocks, such as

Some inline text: `{webr} nrow(foo)`.

Another option would be a short code relying on knitr, c.f.

https://github.com/insightsengineering/tlg-catalog/blob/main/book/_utils/webr.qmd

Motivation:

https://pharmaverse.github.io/blog/posts/2024-05-08_tlg_catalog_webr/tlg_catalog_webr.html


On the inline part, I think that'll have to come when this gets promoted into Quarto. The attempt the worked the best was a shortcode as far as I can recall.

The rationale was related to our workshop materials. We'd like ot make most of the code blocks webr blocks but there are times when we use the objects from the chunks in the text of the slides (or in a plot).

We want objects that are in webr memory to be available to base R memory at the time when we build the quarto slides.

As one of many different types of examples, we'll create some objects on one slide:

image

and them print or plot it (or one of its elements) on another slide

image image image

I'm not particularly worried about updating the slide results if people edit the previous webr chunk. That would be nice but I don't want that type of functionality to contain/complicate an easy solution for our use-case.

For context, we'd like to have slide 34 a webr chunk.