SQLite in the browser
pushing everything to the client
- tags
- deno
- sqlite
- browser
- static_sites
- wasm
Contents
I'm getting more interested in SQLite as a database, keeping everything in memory to the process itself. When do we actually need to have a multi-process solution for a website? How much can we really do within a single process?
One type of architecture I'm exploring is to have a zillion little sqlite files that are shipped around as needed, rather than providing an API to parse them out have one way where we can generate a bunch of effectively static assets of the structured data and then having the visualization happen on the client side. Let's look at two JavaScript examples that let that all happen in the browser.
Both of these use wasm to ship the actually sqlite binary code and run in in browser!
SQL.js
We are going to use npm
to download the packages only. We need to get
sql-wasm.js
and sql-wasm.wasm
and simply serve them up in the browser.
|
|
Test CLI Script
Lets look at how to create and populate a simple database on the command line.
|
|
Which we can test with:
|
|
1 | 111 |
2 | 222 |
Not wildly exciting data but there there you go.
Test webpage
- Load up the
sql-wasm.js
file, which providesinitSqlJs
. locateFile
is used to figure out wheresql-wasm.wasm
is.- Fetch our database that we genereated previously, called
filename.sqlite
. - Create a new database using the
Uint8Array
of the file loaded. - Do some awesome HTML DOM manipulation to create the table.
- Run the query, and populate the table.
|
|
In the directory with the html, wasm, and sqlite files, run:
|
|
And you should get:
deno-sqlite
Lets look at using a different method, using deno instead of node.
Installing deno
I used asdf
, but you can follow the official instructions.
|
|
And then check to see what you have installed:
|
|
deno 1.8.3 (release, x86_64-unknown-linux-gnu) v8 9.0.257.3 typescript 4.2.2
Configuring TypeScript
I need this to make my emacs integration work, but it could be optional for you.
|
|
Dependencies
Create deps.ts
to centralize your version dependancies:
|
|
Test cli script
Lets create a test.ts
script which creates a database and popualtes it:
|
|
And then we can run this with:
|
|
Which returns:
Peter | Parker |
Clark | Kent |
Bruce | Wayne |
Test web script webworkers
Here we are going to write a web.tsx
file that will function as a
WebWorker. Our database will run in a different thread and the main
worker thread.
|
|
Then we need to bundle it up:
|
|
This creates a web.js
file that contains our webworker as well as the
entire sqlite
binary in wasm.
Webpage
This code is simpler that the previous code. We load up web.js
as a modulepreload
, and then inside of our script tag we create the new webwork, and send it a message. Once it gets the message it creates the in-memory database, then
|
|
But that's not the same!
I don't know how to load in the database file with the deno bundle based solution, so at this moment while it works I don't know how to solve that issue. Still the approach is cleaner.
Conclusion
Right now it looks like sql.js
will do what I want. I'm surprised at
how fast web assembly is.
Previously
Next