This commit is contained in:
Alex Garcia 2024-08-01 02:45:36 -07:00
parent 5be4c980ca
commit 09c3f05759
12 changed files with 120 additions and 47 deletions

View file

@ -1,21 +1,21 @@
# `sqlite-vec` # `sqlite-vec`
[![](https://dcbadge.vercel.app/api/server/VCtQ8cGhUs)](https://discord.gg/VCtQ8cGhUs) [![](https://dcbadge.vercel.app/api/server/VCtQ8cGhUs)](https://discord.gg/Ve7WeCJFXk)
An extremely small, "fast enough" vector search SQLite extension that runs An extremely small, "fast enough" vector search SQLite extension that runs
anywhere! A successor to [sqlite-vss](https://github.com/asg017/sqlite-vss) anywhere! A successor to [`sqlite-vss`](https://github.com/asg017/sqlite-vss)
<!-- deno-fmt-ignore-start --> <!-- deno-fmt-ignore-start -->
> [!IMPORTANT] > [!IMPORTANT]
> _`sqlite-vec` is a work-in-progress and not ready for general usage! I plan to launch a "beta" version in the next month or so. Watch this repo for updates, and read [this blog post](https://alexgarcia.xyz/blog/2024/building-new-vector-search-sqlite/index.html) for more info._ > _`sqlite-vec` is a pre-v1, so expect breaking changes!_
<!-- deno-fmt-ignore-end --> <!-- deno-fmt-ignore-end -->
- Store and query float, int8, and binary vectors in `vec0` virtual tables - Store and query float, int8, and binary vectors in `vec0` virtual tables
- Pre-filter vectors with `rowid IN (...)` subqueries
- Written in pure C, no dependencies, runs anywhere SQLite runs - Written in pure C, no dependencies, runs anywhere SQLite runs
(Linux/MacOS/Windows, in the browser with WASM, Raspberry Pis, etc.) (Linux/MacOS/Windows, in the browser with WASM, Raspberry Pis, etc.)
- Pre-filter vectors with `rowid IN (...)` subqueries
<p align="center"> <p align="center">
<a href="https://hacks.mozilla.org/2024/06/sponsoring-sqlite-vec-to-enable-more-powerful-local-ai-applications/"> <a href="https://hacks.mozilla.org/2024/06/sponsoring-sqlite-vec-to-enable-more-powerful-local-ai-applications/">
@ -39,7 +39,6 @@ See <a href="#sponsors">the Sponsors section</a> for more details.
</i> </i>
</p> </p>
<!--
## Installing ## Installing
See [Installing `sqlite-vec`](https://alexgarcia.xyz/sqlite-vec/installing.html) See [Installing `sqlite-vec`](https://alexgarcia.xyz/sqlite-vec/installing.html)
@ -49,14 +48,13 @@ for more details.
| -------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | -------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Python | `pip install sqlite-vec` | [`sqlite-vec` with Python](https://alexgarcia.xyz/sqlite-vec/python.html) | [![PyPI](https://img.shields.io/pypi/v/sqlite-vec.svg?color=blue&logo=python&logoColor=white)](https://pypi.org/project/sqlite-vec/) | | Python | `pip install sqlite-vec` | [`sqlite-vec` with Python](https://alexgarcia.xyz/sqlite-vec/python.html) | [![PyPI](https://img.shields.io/pypi/v/sqlite-vec.svg?color=blue&logo=python&logoColor=white)](https://pypi.org/project/sqlite-vec/) |
| Node.js | `npm install sqlite-vec` | [`sqlite-vec` with Node.js](https://alexgarcia.xyz/sqlite-vec/nodejs.html) | [![npm](https://img.shields.io/npm/v/sqlite-vec.svg?color=green&logo=nodedotjs&logoColor=white)](https://www.npmjs.com/package/sqlite-vec) | | Node.js | `npm install sqlite-vec` | [`sqlite-vec` with Node.js](https://alexgarcia.xyz/sqlite-vec/nodejs.html) | [![npm](https://img.shields.io/npm/v/sqlite-vec.svg?color=green&logo=nodedotjs&logoColor=white)](https://www.npmjs.com/package/sqlite-vec) |
| Ruby | `gem install sqlite-vec` | [`sqlite-vec` with Ruby](https://alexgarcia.xyz/sqlite-vec/ruby.html) | ![Gem](https://img.shields.io/gem/v/sqlite-vec?color=red&logo=rubygems&logoColor=white) | | Ruby | `gem install sqlite-vec` | [`sqlite-vec` with Ruby](https://alexgarcia.xyz/sqlite-vec/ruby.html) | ![Gem](https://img.shields.io/gem/v/sqlite-vec?color=red&logo=rubygems&logoColor=white) |
| Go | `go get -u github.com/asg017/sqlite-vec/bindings/go` | [`sqlite-vec` with Go](https://alexgarcia.xyz/sqlite-vec/go.html) | [![Go Reference](https://pkg.go.dev/badge/github.com/asg017/sqlite-vec/bindings/go.svg)](https://pkg.go.dev/github.com/asg017/sqlite-vec/bindings/go) | | Go | `go get -u github.com/asg017/sqlite-vec/bindings/go` | [`sqlite-vec` with Go](https://alexgarcia.xyz/sqlite-vec/go.html) | [![Go Reference](https://pkg.go.dev/badge/github.com/asg017/sqlite-vec-go-bindings/cgo.svg)](https://pkg.go.dev/github.com/asg017/asg017/sqlite-vec-go-bindings/cgo) |
| Rust | `cargo add sqlite-vec` | [`sqlite-vec` with Rust](https://alexgarcia.xyz/sqlite-vec/rust.html) | [![Crates.io](https://img.shields.io/crates/v/sqlite-vec?logo=rust)](https://crates.io/crates/sqlite-vec) | | Rust | `cargo add sqlite-vec` | [`sqlite-vec` with Rust](https://alexgarcia.xyz/sqlite-vec/rust.html) | [![Crates.io](https://img.shields.io/crates/v/sqlite-vec?logo=rust)](https://crates.io/crates/sqlite-vec) |
| Datasette | `datasette install datasette-sqlite-vec` | [`sqlite-vec` with Datasette](https://alexgarcia.xyz/sqlite-vec/datasette.html) | [![Datasette](https://img.shields.io/pypi/v/datasette-sqlite-vec.svg?color=B6B6D9&label=Datasette+plugin&logoColor=white&logo=python)](https://datasette.io/plugins/datasette-sqlite-vec) | | Datasette | `datasette install datasette-sqlite-vec` | [`sqlite-vec` with Datasette](https://alexgarcia.xyz/sqlite-vec/datasette.html) | [![Datasette](https://img.shields.io/pypi/v/datasette-sqlite-vec.svg?color=B6B6D9&label=Datasette+plugin&logoColor=white&logo=python)](https://datasette.io/plugins/datasette-sqlite-vec) |
| `sqlite-utils` | `sqlite-utils install sqlite-utils-sqlite-vec` | [`sqlite-vec` with sqlite-utils](https://alexgarcia.xyz/sqlite-vec/sqlite-utils.html) | [![sqlite-utils](https://img.shields.io/pypi/v/sqlite-utils-sqlite-vec.svg?color=B6B6D9&label=sqlite-utils+plugin&logoColor=white&logo=python)](https://datasette.io/plugins/datasette-sqlite-vec) | | `sqlite-utils` | `sqlite-utils install sqlite-utils-sqlite-vec` | [`sqlite-vec` with sqlite-utils](https://alexgarcia.xyz/sqlite-vec/sqlite-utils.html) | [![sqlite-utils](https://img.shields.io/pypi/v/sqlite-utils-sqlite-vec.svg?color=B6B6D9&label=sqlite-utils+plugin&logoColor=white&logo=python)](https://datasette.io/plugins/datasette-sqlite-vec) |
| Github Release | | | ![GitHub tag (latest SemVer pre-release)](https://img.shields.io/github/v/tag/asg017/sqlite-vec?color=lightgrey&include_prereleases&label=Github+release&logo=github) | | Github Release | | | ![GitHub tag (latest SemVer pre-release)](https://img.shields.io/github/v/tag/asg017/sqlite-vec?color=lightgrey&include_prereleases&label=Github+release&logo=github) |
-->
## Sample usage ## Sample usage
@ -76,7 +74,7 @@ insert into vec_examples(rowid, sample_embedding)
(4, '[-0.710, 0.330, 0.656, 0.041, -0.990, 0.726, 0.385, -0.958]'); (4, '[-0.710, 0.330, 0.656, 0.041, -0.990, 0.726, 0.385, -0.958]');
-- KNN style query goes brrrr -- KNN style query
select select
rowid, rowid,
distance distance
@ -94,27 +92,6 @@ limit 2;
*/ */
``` ```
## Roadmap
Not currently implemented, but planned in the future (after initial `v0.1.0`
version):
- Approximate nearest neighbors search (DiskANN, IVF, maybe HNSW?)
- Metadata filtering + custom internal partitioning
- More vector types (float16, int16, sparse, etc.) and distance functions
Additionally, there will be pre-compiled and pre-packaged packages of
`sqlite-vec` for the following platforms:
- `pip` for Python
- `npm` for Node.js / Deno / Bun
- `gem` for Ruby
- `cargo` for Rust
- A single `.c` and `.h` amalgammation for C/C++
- Go module for Golang (requires CGO)
- Datasette and sqlite-utils plugins
- Pre-compiled loadable extensions on Github releases
## Sponsors ## Sponsors
Development of `sqlite-vec` is supported by multiple generous sponsors! Mozilla Development of `sqlite-vec` is supported by multiple generous sponsors! Mozilla

View file

@ -23,7 +23,7 @@ const query = [0.3, 0.3, 0.3, 0.3];
db.exec("CREATE VIRTUAL TABLE vec_items USING vec0(embedding float[4])"); db.exec("CREATE VIRTUAL TABLE vec_items USING vec0(embedding float[4])");
const insertStmt = db.prepare( const insertStmt = db.prepare(
"INSERT INTO vec_items(rowid, embedding) VALUES (?, ?)", "INSERT INTO vec_items(rowid, embedding) VALUES (?, ?)"
); );
const insertVectors = db.transaction((items) => { const insertVectors = db.transaction((items) => {
@ -44,7 +44,7 @@ const rows = db
WHERE embedding MATCH ? WHERE embedding MATCH ?
ORDER BY distance ORDER BY distance
LIMIT 5 LIMIT 5
`, `
) )
.all([new Uint8Array(new Float32Array(query).buffer)]); .all([new Uint8Array(new Float32Array(query).buffer)]);

View file

@ -62,7 +62,7 @@ const guides = {
], ],
}, },
{ /* {
text: "Build with sqlite-vec", text: "Build with sqlite-vec",
items: [ items: [
{ text: "Semantic Search", link: "/guides/semantic-search" }, { text: "Semantic Search", link: "/guides/semantic-search" },
@ -70,7 +70,7 @@ const guides = {
{ text: "Retrival Augmented Generation (RAG)", link: "/guides/rag" }, { text: "Retrival Augmented Generation (RAG)", link: "/guides/rag" },
{ text: "Classifiers", link: "/guides/classifiers" }, { text: "Classifiers", link: "/guides/classifiers" },
], ],
}, },*/
], ],
}; };
@ -224,7 +224,7 @@ export default defineConfig({
}, },
socialLinks: [ socialLinks: [
{ icon: "github", link: `https://github.com/asg017/${PROJECT}` }, { icon: "github", link: `https://github.com/asg017/${PROJECT}` },
{ icon: "discord", link: `https://discord.gg/jAeUUhVG2D` }, { icon: "discord", link: `https://discord.gg/Ve7WeCJFXk` },
], ],
editLink: { editLink: {
pattern: `https://github.com/asg017/${PROJECT}/edit/main/site/:path`, pattern: `https://github.com/asg017/${PROJECT}/edit/main/site/:path`,

View file

@ -0,0 +1,5 @@
# Using `sqlite-vec` in C
The `sqlite-vec` project is a single `sqlite-vec.c` and `sqlite-vec.h` file. They can be vendored into your C or C++ projects and compiled like normal.
"Amalgammation" builds are provided on the [`sqlite-vec` Releases page](https://github.com/asg017/sqlite-vec/releases).

View file

@ -2,6 +2,12 @@
[![Datasette](https://img.shields.io/pypi/v/datasette-sqlite-vec.svg?color=B6B6D9&label=Datasette+plugin&logoColor=white&logo=python)](https://datasette.io/plugins/datasette-sqlite-vec) [![Datasette](https://img.shields.io/pypi/v/datasette-sqlite-vec.svg?color=B6B6D9&label=Datasette+plugin&logoColor=white&logo=python)](https://datasette.io/plugins/datasette-sqlite-vec)
[Datasette](https://datasette.io/) users can install `sqlite-vec` into their Datasette instances with the `datasette-sqlite-vec` plugin:
```bash ```bash
datasette install datasette-sqlite-vec datasette install datasette-sqlite-vec
``` ```
After installing, future Datasette instances will have `sqlite-vec` SQL functions loaded in.
"Unsafe" functions like static blobs and NumPy file reading are not available with `datasette-sqlite-vec`.

View file

@ -1,6 +1,6 @@
# Using `sqlite-vec` in Go # Using `sqlite-vec` in Go
[![Go Reference](https://pkg.go.dev/badge/github.com/asg017/sqlite-vec-go-bindings/cgo.svg)](https://pkg.go.dev/github.com/asg017/sqlite-vec-go-bindings/cgo) [![Go Reference](https://pkg.go.dev/badge/github.com/asg017/sqlite-vec-go-bindings/ncruces.svg)](https://pkg.go.dev/github.com/asg017/sqlite-vec-go-bindings/ncruces)
There are two ways you can embed `sqlite-vec` into Go applications: a CGO option There are two ways you can embed `sqlite-vec` into Go applications: a CGO option
for libraries like for libraries like
@ -8,7 +8,9 @@ for libraries like
WASM-based option with WASM-based option with
[`github.com/ncruces/go-sqlite3`](https://github.com/ncruces/go-sqlite3). [`github.com/ncruces/go-sqlite3`](https://github.com/ncruces/go-sqlite3).
## Option 1: CGO ## Option 1: CGO {#cgo}
[![Go Reference](https://pkg.go.dev/badge/github.com/asg017/sqlite-vec-go-bindings/cgo.svg)](https://pkg.go.dev/github.com/asg017/sqlite-vec-go-bindings/cgo)
If using [`github.com/mattn/go-sqlite3`](https://github.com/mattn/go-sqlite3) or another CGO-based SQLite library, then use the `github.com/asg017/sqlite-vec-go-bindings/cgo` module to embed `sqlite-vec` into your Go application. If using [`github.com/mattn/go-sqlite3`](https://github.com/mattn/go-sqlite3) or another CGO-based SQLite library, then use the `github.com/asg017/sqlite-vec-go-bindings/cgo` module to embed `sqlite-vec` into your Go application.
@ -44,11 +46,17 @@ func main() {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
log.Printf("sqlite_version=%s, vec_version=%s\n",vecVersion) log.Printf("vec_version=%s\n",vecVersion)
} }
``` ```
## Option 2: WASM based with `ncruces/go-sqlite3` See
[`simple-go-cgo/demo.go`](https://github.com/asg017/sqlite-vec/blob/main/examples/simple-go-cgo/demo.go)
for a more complete Go CGO demo.
## Option 2: WASM based with `ncruces/go-sqlite3` {#ncruces}
[![Go Reference](https://pkg.go.dev/badge/github.com/asg017/sqlite-vec-go-bindings/ncruces.svg)](https://pkg.go.dev/github.com/asg017/sqlite-vec-go-bindings/ncruces)
[`github.com/ncruces/go-sqlite3`](https://github.com/ncruces/go-sqlite3) is an alternative SQLite Go driver that avoids CGO by using a custom WASM build of SQLite. To use `sqlite-vec` from this library, use the specicial WASM binary provided in `github.com/asg017/sqlite-vec-go-bindings/ncruces`. [`github.com/ncruces/go-sqlite3`](https://github.com/ncruces/go-sqlite3) is an alternative SQLite Go driver that avoids CGO by using a custom WASM build of SQLite. To use `sqlite-vec` from this library, use the specicial WASM binary provided in `github.com/asg017/sqlite-vec-go-bindings/ncruces`.
@ -73,7 +81,7 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
stmt, _, err := db.Prepare(`SELECT sqlite_version(), vec_version()`) stmt, _, err := db.Prepare(`SELECT vec_version()`)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -84,13 +92,22 @@ func main() {
} }
``` ```
See
[`simple-go-ncruces/demo.go`](https://github.com/asg017/sqlite-vec/blob/main/examples/simple-go-ncruces/demo.go)
for a more complete Go ncruces demo.
The `github.com/asg017/sqlite-vec-go-bindings/ncruces` package embeds a custom WASM build of SQLite, so there's no need to use `github.com/ncruces/go-sqlite3/embed`. The `github.com/asg017/sqlite-vec-go-bindings/ncruces` package embeds a custom WASM build of SQLite, so there's no need to use `github.com/ncruces/go-sqlite3/embed`.
## Working with vectors in Go
## Working with vectors in Go
If vectors are provided as a list of floats, use `SerializeFloat32(list)` to serialize them into the compact BLOB format that `sqlite-vec` expects. If vectors are provided as a list of floats, use `SerializeFloat32(list)` to serialize them into the compact BLOB format that `sqlite-vec` expects.
```go ```go
TODO values := []float32{0.1, 0.1, 0.1, 0.1}
v, err := sqlite_vec.SerializeFloat32(values)
if err != nil {
log.Fatal(err)
}
stmt.BindInt(1, id)
``` ```

View file

@ -54,10 +54,9 @@ and use
accessor to bind as a parameter to `sqlite-vec` SQL functions. accessor to bind as a parameter to `sqlite-vec` SQL functions.
```js ```js
// TODO
const embedding = new Float32Array([0.1, 0.2, 0.3, 0.4]); const embedding = new Float32Array([0.1, 0.2, 0.3, 0.4]);
const stmt = db.prepare("select vec_length(?)"); const stmt = db.prepare("select vec_length(?)");
console.log(stmt.run(embedding.buffer)); console.log(stmt.run(embedding.buffer)); // 4
``` ```
## Node.js ## Node.js
@ -66,6 +65,19 @@ Here's a quick recipe of using `sqlite-vec` with
[`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3) in Node.js. [`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3) in Node.js.
```js ```js
import * as sqliteVec from "sqlite-vec";
import Database from "better-sqlite3";
const db = new Database(":memory:");
sqliteVec.load(db);
const embedding = new Float32Array([0.1, 0.2, 0.3, 0.4]);
const { result } = db
.prepare("select vec_length(?)",)
.get(embedding);
console.log(result); // 4
``` ```
See See
@ -76,13 +88,26 @@ for a more complete Node.js demo.
Here's a quick recipe of using `sqlite-vec` with Here's a quick recipe of using `sqlite-vec` with
[`jsr:@db/sqlite`](https://jsr.io/@db/sqlite) in Deno. It will only work on Deno [`jsr:@db/sqlite`](https://jsr.io/@db/sqlite) in Deno. It will only work on Deno
version `1.44` or greater, because of a bug in previous Deno version. version `1.44` or greater, because of a bug in previous Deno versions.
Keep in mind, the `better-sqlite3` example above also works in Deno, you just Keep in mind, the `better-sqlite3` example above also works in Deno, you just
need to prefix the `better-sqlite3` import with `npm:`, like need to prefix the `better-sqlite3` import with `npm:`, like
`import * from "npm:better-sqlite3"`. `import * from "npm:better-sqlite3"`.
```ts ```ts
import { Database } from "jsr:@db/sqlite@0.11";
import * as sqliteVec from "npm:sqlite-vec@0.0.1-alpha.9";
const db = new Database(":memory:");
db.enableLoadExtension = true;
sqliteVec.load(db);
db.enableLoadExtension = false;
const embedding = new Float32Array([0.1, 0.2, 0.3, 0.4]);
const [result] = db
.prepare("select vec_length(?)")
.value<[string]>(new Uint8Array(embedding.buffer)!);
console.log(result); // 4
``` ```
See See
@ -96,6 +121,22 @@ Here's a quick recipe of using `sqlite-vec` with
example above also works with Bun. example above also works with Bun.
```ts ```ts
import { Database } from "bun:sqlite";
import * as sqliteVec from "sqlite-vec";
// MacOS *might* have to do this, as the builtin SQLite library on MacOS doesn't allow extensions
Database.setCustomSQLite("/usr/local/opt/sqlite3/lib/libsqlite3.dylib");
const db = new Database(":memory:");
sqliteVec.load(db);
const embedding = new Float32Array([0.1, 0.2, 0.3, 0.4]);
const { result } = db
.prepare("select vec_length(?)",)
.get(embedding);
console.log(result); // 4
``` ```
See See

View file

@ -30,6 +30,10 @@ vec_version, = db.execute("select vec_version()").fetchone()
print(f"vec_version={vec_version}") print(f"vec_version={vec_version}")
``` ```
See
[`simple-python/demo.py`](https://github.com/asg017/sqlite-vec/blob/main/examples/simple-python/demo.py)
for a more complete Python demo.
## Working with Vectors ## Working with Vectors
### Lists ### Lists

View file

@ -9,7 +9,7 @@ Ruby developers can use `sqlite-vec` with the [`sqlite-vec` Gem](https://rubygem
gem install sqlite-vec gem install sqlite-vec
``` ```
You can then use `SqliteVss.load()` to load `sqlite-vss` SQL functions in a given SQLite connection. You can then use `SqliteVec.load()` to load `sqlite-vec` SQL functions in a given SQLite connection.
```ruby ```ruby
require 'sqlite3' require 'sqlite3'
@ -25,6 +25,9 @@ puts result.first.first
``` ```
See
[`simple-ruby/demo.rb`](https://github.com/asg017/sqlite-vec/blob/main/examples/simple-ruby/demo.rb)
for a more complete Ruby demo.
## Working with vectors in Ruby ## Working with vectors in Ruby

View file

@ -34,7 +34,9 @@ fn main()-> Result<()> {
} }
``` ```
A full [`sqlite-vec` Rust demo](#TODO) is also available. See
[`simple-rust/demo.rs`](https://github.com/asg017/sqlite-vec/blob/main/examples/simple-rust/demo.rs)
for a more complete Rust demo.
## Working with vectors in Rust ## Working with vectors in Rust

View file

@ -2,6 +2,9 @@
![sqlite-utils](https://img.shields.io/pypi/v/sqlite-utils-sqlite-vec.svg?color=B6B6D9&label=sqlite-utils+plugin&logoColor=white&logo=python) ![sqlite-utils](https://img.shields.io/pypi/v/sqlite-utils-sqlite-vec.svg?color=B6B6D9&label=sqlite-utils+plugin&logoColor=white&logo=python)
[`sqlite-utils`](https://sqlite-utils.datasette.io/en/stable/) users can install `sqlite-vec` into their `sqlite-utils` projects with the `sqlite-utils-sqlite-vec` plugin:
```bash ```bash
sqlite-utils install sqlite-utils-sqlite-vec sqlite-utils install sqlite-utils-sqlite-vec
``` ```

View file

@ -1,5 +1,7 @@
# `sqlite-vec` in the Browser with WebAssembly # `sqlite-vec` in the Browser with WebAssembly
`sqlite-vec` can be statically compiled into [official SQLite WASM](https://sqlite.org/wasm/doc/trunk/index.md) builds. The process is a bit complicated, but the result is a vector search in the browser, which is pretty cool!
```html ```html
<html> <html>
<body> <body>
@ -15,3 +17,16 @@
</body> </body>
</html> </html>
``` ```
[*Open in CodePen*](https://codepen.io/asg017_ucsd/pen/MWMpJNY)
It's not possibly to dynamically load a SQLite extension into a WASM build of SQLite. So `sqlite-vec` must be statically compiled into custom WASM builds.
## The `sqlite-vec-wasm-demo` NPM package
A **demonstration** of `sqlite-vec` in WASM is provided with the `sqlite-vec-wasm-demo` NPM package. This package is a demonstration and may change at any time. It doesn't follow the [Semantic version of `sqlite-vec`](../versioning.md).
See
[`simple-wasm/index.html`](https://github.com/asg017/sqlite-vec/blob/main/examples/simple-wasm/index.html)
for a more complete WASM demo using this package.