Skip to content

Commit a554a86

Browse files
committed
Added PyScirpt Events
1 parent 84a3524 commit a554a86

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

docs/user-guide/faq.md

+87
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,90 @@ class Modern {}
275275
// throws error: it requires `new Modern`
276276
Modern()
277277
```
278+
279+
### PyScript Events
280+
281+
Beside *hooks*' lifecycle, *PyScript* also dispatches specific events that might help users to work around its state:
282+
283+
#### m/py:ready
284+
285+
Both `mpy:ready` and `py:ready` events are dispatched per every *PyScript* related element found on the page, being this a `<script type="py">`, a `<py-script>` or any *mpy* counterpart.
286+
287+
Please **note** that these events are dispatched *right before* the code gets eventually executed, hence before the interpreter got a chance to run the code but always *after* the interpreter has already been bootstrapped.
288+
289+
```html title="A py:ready example"
290+
<script>
291+
addEventListener("py:ready", () => {
292+
// show running for an instance
293+
const status = document.getElementById("status");
294+
status.textContent = 'running';
295+
});
296+
</script>
297+
<!-- show bootstrapping right away -->
298+
<div id="status">bootstrapping</div>
299+
<script type="py" worker>
300+
from pyscript import document
301+
302+
# show done after running
303+
status = document.getElementById("status")
304+
status.textContent = "done"
305+
</script>
306+
```
307+
308+
As a matter of fact, if you are missing the previous *modal* showing a spinner while *pyodide* bootstrapped, it is fairly easy to provide a similar experience through this event: show a modal first, then close it once `py:ready` is triggered.
309+
310+
!!! warning
311+
312+
On the *main* thread, *pyodide* blocks the *UI* until it's finished bootstrapping itself.
313+
This means that previous example without `worker` attribute will skip rendering `running` text because it happens at the same *UI* update that happens after the code has been executed.
314+
If needed, one can always `console.log` instead to be sure that event happened.
315+
316+
#### m/py:done
317+
318+
As the name might suggest, `mpy:done` and `py:done` events events are dispatched *after* the *sync* or *async* code has finished its execution.
319+
320+
```html title="A py:done example"
321+
<script>
322+
addEventListener("py:ready", () => {
323+
// show running for an instance
324+
const status = document.getElementById("status");
325+
status.textContent = 'running';
326+
});
327+
addEventListener("py:done", () => {
328+
// show done after logging "Hello 👋"
329+
const status = document.getElementById("status");
330+
status.textContent = 'done';
331+
});
332+
</script>
333+
<!-- show bootstrapping right away -->
334+
<div id="status">bootstrapping</div>
335+
<script type="py" worker>
336+
print("Hello 👋")
337+
</script>
338+
```
339+
340+
!!! warning
341+
342+
If your async code never exits due some infinite loop or it uses some orchestration that keeps it running forever, such as `code` and `code.interact()` these events might never get triggered because the code actually is never really *done* so it cannot reach its own end of execution.
343+
344+
#### py:all-done
345+
346+
This event is special because it really groups all possible *mpy* or *py* scripts found on the page, no matter the interpreter.
347+
348+
In this example we'll see MicroPython waving before Pyodide and finally an *everything is done* message in *devtools*.
349+
350+
```html title="A py:all-done example"
351+
<script>
352+
addEventListener("py:all-done", () => {
353+
console.log("everything is done");
354+
});
355+
</script>
356+
<script type="mpy" worker>
357+
print("MicroPython 👋")
358+
</script>
359+
<script type="py" worker>
360+
print("Pyodide 👋")
361+
</script>
362+
```
363+
364+

0 commit comments

Comments
 (0)