How to trigger a replay/rerun a cell or notebook from runtime or inspect modules

I’m looking for a way to asynchronously restart an embedded notebook in my React web app so that specific visualization cells that animate replay with the runtime.module’s variables recomputed.

In order for this to work in my web app properly it cannot be a replay button inside the observable notebook itself, so it must be a call exposed on runtime, module, or my custom inspector.

I’ve attempted to call runtime._compute() and .computeNow() to no avail, they run but do not cause a re-render of the visualization.

Can anyone point me in the right direction?

One way to do it is to define an auxiliary viewof cell that the rest of your notebook depends on and then just dispatch an input event to it whenever you want to refresh everything. Here’s a quick demo I cooked up for practice:

I was hoping to find a solution that wouldn’t require alterations to the notebook itself.

I tried your method using an empty “trigger” component – unfortunately I get this error

Expected an assignment or function call and instead saw an expression  no-unused-expressions

on the line of the notebook that adds the variable declaration ‘trigger’ into the dependent cell:

main.variable(observer("trigger")).define("trigger", ["Generators", "viewof trigger"], (G, _) => G.input(_));

main.variable(observer("chart")).define("chart", ["replay","d3","width","height","bars","axis","labels","ticker","keyframes","duration","x","invalidation","trigger"], async function*(replay,d3,width,height,bars,axis,labels,ticker,keyframes,duration,x,invalidation,trigger)
{
	trigger;
...
}

I’m afraid I can’t tell from what you posted what you tried exactly. If you post minimal working code I might be able to help more.

I can provide a codesandbox version of what I tried but the fact remains I need a solution that does not require injecting any code into the noteook itself.

I suppose you could use module.redefine to trigger a recomputation by redefining a cell to be equal to its previous definition. (This is effectively what clicking the “Run cell” button in the Observable editor does.)

There should be a hacky way of getting the previous definition from the variable object as well, without having to copy the string from the notebook: runtime/variable.js at main · observablehq/runtime · GitHub if I have time later I’ll see if I can put together an example.

Here’s the example I promised; I tried to put comments in the code, but let me know if it needs more explanation:

1 Like

The runtime will only reevaluate variables that have been marked as dirty:

runtime._dirty.add(main._scope.get("trigger"));
runtime._compute();

(Note: The above is untested.)

Perfecto! I got this to work on my React JS playground.

[Updated] – Happy to report, I was also able to get this to work on my main project which is in Typescript.

1 Like