Poindexter/docs/wasm.md

171 lines
5.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Browser/WebAssembly (WASM)
Poindexter ships a browser build compiled to WebAssembly along with a small JS loader and TypeScript types. This allows you to use the KDTree functionality directly from web apps (Angular, React, Vue, plain ESM, etc.).
## Whats included
- `dist/poindexter.wasm` — the compiled Go WASM module
- `dist/wasm_exec.js` — Gos runtime shim required to run WASM in the browser
- `npm/poindexter-wasm/loader.js` — ESM loader that instantiates the WASM and exposes a friendly API
- `npm/poindexter-wasm/index.d.ts` — TypeScript typings for the loader and KDTree API
## Quick start
- Build artifacts and copy `wasm_exec.js`:
```bash
make wasm-build
```
- Prepare the npm package folder with `dist/` and docs:
```bash
make npm-pack
```
- Minimal browser ESM usage (serve `dist/` statically):
```html
<script type="module">
import { init } from '/npm/poindexter-wasm/loader.js';
const px = await init({
wasmURL: '/dist/poindexter.wasm',
wasmExecURL: '/dist/wasm_exec.js',
});
const tree = await px.newTree(2);
await tree.insert({ id: 'a', coords: [0, 0], value: 'A' });
const nn = await tree.nearest([0.1, 0.2]);
console.log(nn);
</script>
```
## Building locally
```bash
make wasm-build
```
This produces `dist/poindexter.wasm` and copies `wasm_exec.js` into `dist/` from your Go installation. If your environment is nonstandard, you can override the path:
```bash
WASM_EXEC=/custom/path/wasm_exec.js make wasm-build
```
To assemble the npm package folder with the built artifacts:
```bash
make npm-pack
```
This populates `npm/poindexter-wasm/` with `dist/`, licence and readme files. You can then create a tarball for local testing:
```bash
npm pack ./npm/poindexter-wasm
```
## Using in Angular (example)
1) Install the package (use the tarball generated above or a published version):
```bash
npm install <path-to>/snider-poindexter-wasm-0.0.0-development.tgz
# or once published
npm install @snider/poindexter-wasm
```
2) Make the WASM runtime files available as app assets. In `angular.json` under `build.options.assets`:
```json
{
"glob": "**/*",
"input": "node_modules/@snider/poindexter-wasm/dist",
"output": "/assets/poindexter/"
}
```
3) Import and initialize in your code:
```ts
import { init } from '@snider/poindexter-wasm';
const px = await init({
// If you used the assets mapping above, these defaults should work:
wasmURL: '/assets/poindexter/poindexter.wasm',
wasmExecURL: '/assets/poindexter/wasm_exec.js',
});
const tree = await px.newTree(2);
await tree.insert({ id: 'a', coords: [0, 0], value: 'A' });
const nearest = await tree.nearest([0.1, 0.2]);
console.log(nearest);
```
## JavaScript API
Toplevel functions returned by `init()`:
- `version(): string`
- `hello(name?: string): string`
- `newTree(dim: number): Promise<Tree>`
Tree methods:
- `dim(): Promise<number>`
- `len(): Promise<number>`
- `insert(p: { id: string; coords: number[]; value?: string }): Promise<void>`
- `deleteByID(id: string): Promise<boolean>`
- `nearest(query: number[]): Promise<{ id: string; coords: number[]; value: string; dist: number } | null>`
- `kNearest(query: number[], k: number): Promise<Array<{ id: string; coords: number[]; value: string; dist: number }>>`
- `radius(query: number[], r: number): Promise<Array<{ id: string; coords: number[]; value: string; dist: number }>>`
- `exportJSON(): Promise<string>`
Notes:
- The WASM bridge currently uses `KDTree[string]` for values to keep the boundary simple. You can encode richer payloads as JSON strings if needed.
- `wasm_exec.js` must be available next to the `.wasm` file (the loader accepts explicit URLs if you place them elsewhere).
## CI artifacts
Our CI builds and uploads the following artifacts on each push/PR:
- `poindexter-wasm-dist` — the `dist/` folder containing `poindexter.wasm` and `wasm_exec.js`
- `npm-poindexter-wasm` — the prepared npm package folder with `dist/` and documentation
- `npm-poindexter-wasm-tarball` — a `.tgz` created via `npm pack` for quick local install/testing
You can download these artifacts from the workflow run summary in GitHub Actions.
## Browser demo (checked into repo)
There is a tiny browser demo you can load locally from this repo:
- Path: `examples/wasm-browser/index.html`
- Prerequisites: run `make wasm-build` so `dist/poindexter.wasm` and `dist/wasm_exec.js` exist.
- Serve the repo root (so relative paths resolve), for example:
```bash
python3 -m http.server -b 127.0.0.1 8000
```
Then open:
- http://127.0.0.1:8000/examples/wasm-browser/
Open the browser console to see outputs from `nearest`, `kNearest`, and `radius` queries.
### TypeScript + Vite demo (local-only)
A minimal TypeScript demo using Vite is also included:
- Path: `examples/wasm-browser-ts/`
- Prerequisites: run `make wasm-build` at the repo root first.
- From the example folder:
```bash
npm install
npm run dev
```
Then open the URL printed by Vite (usually http://127.0.0.1:5173/) and check the browser console.
Notes:
- The dev script copies `dist/poindexter.wasm`, `dist/wasm_exec.js`, and the ESM loader into the example's `public/` folder before serving.
- This example is intentionally excluded from CI to keep the pipeline lean.