We use WebAssembly (Wasm) to enable efficient client-side execution of common steps in a scRNA-seq analysis. Code to perform each step is written in C++ and compiled to Wasm using the Emscripten toolchain. Some of the relevant C++ libraries are listed below:
- libscran provides C++ implementations of key functions in scran and its fellow packages scater and scuttle. This includes quality control, normalization, feature selection, PCA, clustering and dimensionality reduction.
- tatami provides an abstract interface to different matrix classes, focusing on row and column extraction.
- knncolle wraps a number of nearest neighbor detection methods in a consistent interface.
- CppIrlba contains a C++ port of the IRLBA algorithm for approximate PCA.
- CppKmeans contains C++ ports of the Hartigan-Wong and Lloyd algorithms for k-means clustering.
- qdtsne contains a refactored C++ implementation of the Barnes-Hut t-SNE dimensionality reduction algorithm.
- umappp contains a refactored C++ implementation of the UMAP dimensionality reduction algorithm.
For each step, we use Emscripten to compile the associated C++ functions into Wasm and generate Javascript-visible bindings. We can then load the Wasm binary into a web application and call the desired functions on user-supplied data.
Make sure Emscripten and CMake are installed on your machine.
Running the build.sh
script will then generate ES6 and Node.js-compatible builds.
To build the Node.js version:
bash build.sh main
To build the browser-compatible version:
bash build.sh browser
This will create the main
and browser
directories respectively,
containing the Wasm file in the wasm
subdirectory as well as copying all the relevant Javascript bindings.
Run the test suite by calling:
# install dev dependencies
npm install --include=dev
npm run test
For earlier versions of Node, you may instead need to do some combination of the following options:
node \
--experimental-vm-modules \
--experimental-wasm-threads \
--experimental-wasm-bulk-memory \
--experimental-wasm-bigint \
node_modules/jest/bin/jest.js --runInBand
Alternatively, developers can use the Docker image to build and test. This image is also used by our GitHub actions, so it will probably work.