An introduction to storing WASM modules in web native storage
In this guide, we will show how to store WebAssembly modules in Fission web native storage. Our goal will be to store a WASM module and execute it at a later time.
The code in this guide is available in the fission-stored-wasm-example repository and the example is published at quick-enormous-silicon-dinosaur.fission.app.
We have compiled an add
function from C to a WASM module.
Our example app will make a GET request for add.wasm
and store it in web native storage. We will list the contents of the directory where the module is stored to confirm it is there. Finally, we will load the module from storage and add some numbers!
Our example uses some helper functions to add interactivity. We won't cover calls to dom.reveal()
, dom.hide()
, or dom.updateFirstChild().
If you would like to see what these do, please take a look at the code in the repository.
At the moment, this example will not work in webKit iOS or Safari macOS browsers. If you are familiar with WebAssembly in these browsers, we would love some help with this! See the SyntaxError invalid character in webkit/safari issue for more details.
Before we can store a WASM module, we need to initialize webnative
and ask the user for permission to use their web native file system. This example asks for permission to use app storage and uses fs
as an alias for the file system after we initialize.
We pass fissionInit
to webnative
and get back a state
that tells us if the user has authenticated or not.
In the AuthSucceeded
and Continuation
cases, the user gave our app permission to use their file system. Otherwise, they have not been asked or they declined.
The user may have already stored add.wasm
and used it to add numbers on a previous visit, so we check and display a stored result if we have one.
If the user has not authenticated, we show them a Sign In button that will redirect them to the Fission auth lobby.
After authentication, we are ready to request add.wasm
and store it in web native storage.
We fetch add.wasm
and stream the Response
into an ArrayBuffer
. It will be stored as a Blob
in app storage at the path wasm/math/add.wasm
.
We prepare a path
and blob
, write the blob to the local file system, and publish it to the user's wider file system across the web. After we publish, the module is available on any device where the user has set up web native storage.
Next, we can check to make sure the module has been saved in storage.
This time we prepare a wasm/math
path for the directory and call fs.ls
to list its contents. We take each entry in the directory listing and append its metadata to a table.
Each entry has a name, size (in bytes), last modified time, and a flag indicating whether it is a file or directory.
The module is in storage and we are ready to use it! Each time a user submits lhs
and rhs
numbers, we load add.wasm
and add their numbers.
After some input validation, we prepare the wasm/math/add.wasm
path, make sure a module exists at that path, and read it into a buffer. We instantiate the WASM module and call the add
function off it.
Earlier we mentioned that storing the module makes it available across the web. Why not do the same for our result? We store the result at the path results/add
, and now both the module and the last result are available on any device!
We can delete the module and result from storage to reset our example.
We prepare paths for the module and result and use fs.rm
to delete them. Lastly, we publish the deletion to remove them from the wider file system.
Storing WASM modules and results means you only need to request a module or perform a computation once. The web native file system will sync modules and results across user devices automatically. This opens up many opportunities to simplify your applications and sync app data across user devices.
Reading this guide gives you a taste of how this all works, but extending this example will take you much further! Here are a couple of suggested exercises that will help you to get started with web native.
Add a subtraction operation. We have done addition, adding subtraction would be an easy first step. See Compiling C to WebAssembly without Emscripten for help with compiling WASM modules.
Distributed addition. How about instead of overwriting the result of an addition, we keep a running total across devices?
Build a calculator. A bit more ambitious, but a calculator app that stores state across devices would be so cool!