Async Hell using WASM JS Worker
(1.2) By ProphezAI on 2024-01-09 23:57:26 edited from 1.1 [source]
Hi,
I would like to integrate SQLite in my project, I am currently working on. The latest state of the SQLite integration can be found on Github/ProphezAI (sqlite branch)
It is generally working, but I run into some async hell when not starting with the startpage, but for example with Animals
In this case it SHOULD execute the code in ./modules/SQLite.js but as it seems, the executeQuery call (initialized by createTables() call in ./webcomponents/animals/animals-create.html) seems to be faster than the creation of the worker, so that the DB is not yet loaded to this point of time. I have already tried some promise-based solutions but without success. Could I please get some help from the community? Thanks in advance for any help!
Best regards, ProphezAI
(2) By Stephan Beal (stephan) on 2024-01-10 02:27:08 in reply to 1.2 [link] [source]
seems to be faster than the creation of the worker, so that the DB is not yet loaded to this point of time
This is just a guess because i don't use frameworks like whatever it is you're using and have no idea how their parts interact, but should you perhaps remove the async wrapper around the code in main.js?
(3) By ProphezAI on 2024-01-10 13:17:24 in reply to 2 [link] [source]
Thanks for the reply! Basically the framework (only.js) shouldn't bother much, as its functionality is according to W3C and MDN recommended best-practices for injecting WebComponents with a few hacks... It just prefetches the html files, and defines WebComponents for each. The lifecycle is described in the repo's README.md in more detail, but you can really treat it as a blackbox and not bother about that.
As you may have found out, the main.js is not in use at all and was a test for the recommended Worker1Promiser as described in the SQLite page on npmjs. One could just replace "only.js" by "main.js" in the script src in the index.html to make it work/test. I would even like to use the Worker1Promiser as recommended, but, I am not sure, how to make my other modules like Animals.js work with it. Maybe someone has a idea about that?
My main problem however is with the asynchronicity with the dbInstance variable in the SQLite Worker. The dbInstance variable is not set when called by the Animals.js directly. I would need a test for calling createTables() with the SQLite.js (and SQLiteWorker.js) module as dependency or just some solution which guarantees, that when dbInstance is accessed, it is never null. Thanks for reading!
(4.1) By Stephan Beal (stephan) on 2024-01-10 14:23:33 edited from 4.0 in reply to 3 [link] [source]
I would even like to use the Worker1Promiser as recommended, but, I am not sure, how to make my other modules like Animals.js work with it. Maybe someone has a idea about that?
You might (might) have better luck asking in the npm-specific subproject. None of the maintainers on this side of the project use anything but vanilla, framework-free, WebComponent-free JS so can't offer much help with that stuff.
What might (might!) keep you from stepping on a null object is to move the redefinition of onmessage in:
https://github.com/ProphezAI/jsonly/blob/sqlite/modules/worker/SQLiteWorker.js
into a then()
handler in the module initializers:
sqlite3InitModule({
print: log,
printErr: error,
}).then(...)
.then(function(){
globalThis.onmessage = function...;
});
i am not sure whether that might cause the loss of inbound postMessage()s which are sent before onmessage is assigned, however.
(5) By ProphezAI on 2024-01-10 21:53:54 in reply to 4.1 [link] [source]
Thanks again, for the try. I think I have solved it now with the processNextTick hack in SQLiteWorker.js.
Access to dbInstance is now solved via "await getDB()". Thanks for your hints! Issue closed. Testers welcome! https://github.com/ProphezAI/jsonly