Make the life-cycle more linear and kill some svelte stores#830
Conversation
…an error if we specify 0 or >1
…runtime.ts to main.ts, document what is the expected lifecycle and put comments around to guide the reader around the code. Many more improvements are possible, but this tries to be as close as possible to the old logic
…orresponds to the order of execution
marimeireles
left a comment
There was a problem hiding this comment.
This looks great!
So much more organized and easier to understand. Great work @antocuni :)
| scriptsQueue.subscribe((value: PyScript[]) => { | ||
| scriptsQueue_ = value; |
There was a problem hiding this comment.
I wonder if it's worth it to change these names? I think these they are so confusing... Do you have an idea for better naming?
There was a problem hiding this comment.
they are going to be killed soon ☠️
|
|
||
| /* High-level overview of the lifecycle of a PyScript App: | ||
|
|
||
| 1. pyscript.js is loaded by the browser. PyScriptApp().main() is called | ||
|
|
||
| 2. loadConfig(): search for py-config and compute the config for the app | ||
|
|
||
| 3. show the loader/splashscreen | ||
|
|
||
| 4. loadRuntime(): start downloading the actual runtime (e.g. pyodide.js) | ||
|
|
||
| --- wait until (4) has finished --- | ||
|
|
||
| 5. now the pyodide src is available. Initialize the engine | ||
|
|
||
| 6. setup the environment, install packages | ||
|
|
||
| 7. run user scripts | ||
|
|
||
| 8. initialize the rest of web components such as py-button, py-repl, etc. | ||
|
|
||
| More concretely: | ||
|
|
||
| - Points 1-4 are implemented sequentially in PyScriptApp.main(). | ||
|
|
||
| - PyScriptApp.loadRuntime adds a <script> tag to the document to initiate | ||
| the download, and then adds an event listener for the 'load' event, which | ||
| in turns calls PyScriptApp.afterRuntimeLoad(). | ||
|
|
||
| - PyScriptApp.afterRuntimeLoad() implements all the points >= 5. | ||
| */ | ||
|
|
||
|
|
There was a problem hiding this comment.
Grateful for docs in the code 🙏
| script.addEventListener('load', () => { | ||
| void this.afterRuntimeLoad(runtime); |
There was a problem hiding this comment.
Is this just the way you do lambdas in TS?
(Asking because I'm TS noob)
There was a problem hiding this comment.
yes, it's not even TS-specific, it works the same in plain JS. They are not called lambda though, they are just "functions" and/or "closures".
This particular syntax is called "arrow function", which of course has slightly different rules than normal functions 🤦♂️
DISCLAIMER: I'm not the author of this code, I just moved it around :)
This is a follow-up of PR #806 and it's a big step forward towards solving issue #763.
The basic idea is that at this stage I want to streamline the execution logic and make it as linear and easy to read/understand as possible. Once we have a better understanding of what's going on, we can think of slicing it again in forms of plugins or similar, if we want.
The diff is relatively big, but for the most part is just "shuffling code around". The biggest outcome is that now the majority of the execution logic of the page follows a very linear logic, which I describe in a comment at the beginning of
main.ts:pyscript/pyscriptjs/src/main.ts
Lines 27 to 56 in 42d81db
Previously, a big chunk of the logic was inside
runtime.ts: the oldRuntime.initializeis nowPyScriptApp.afterRuntimeLoad, with some small refactoring to split the code. Also, the order of functions insidemain.tsfollows the execution order, so that you can nicely read it from top to bottom:pyscript/pyscriptjs/src/main.ts
Lines 128 to 166 in 42d81db
Svelte stores
The idea is to eventually kill of them, so that we can remove the dependency on svelte but also to avoid relying on so much global state, which makes things more complicated and error-prone (e.g., we have several issues related to using
runtimewhen it's not ready yet).I killed
addInitializer,addPostInitializerand the corresponding svelte stores 🎉. They are no longer needed since the relevant code is called directly frommain.ts.I started to kill the usage of the
runtimeLoadedsvelte store: instead of relying on a global variable, I want to arrive at the point in which theruntimeis passed as a parameter in all places where it's needed:pyscript.tsis now free of global state, but I couldn't kill it yet because it's used heavily bybase.tsandpyrepl.ts. I will do it in another PR.Other misc changes
I added sanity checks (and corresponding tests!) which complain if you specify 0 or multiple runtimes. Currently we support having one and only one, so there is no point to pretend otherwise
I modified the messages displayed by the loader, to be more informative from the user point of view. Now they look like this:
