Files
wickra/docs/wiki/Quickstart-WASM.md
T
kingchenc 8aa74cb638 release(0.2.1): bump to 0.2.1, skipping Windows ARM64 this cycle
The 0.2.0 release left wickra@npm stuck at 0.1.4 and never created a
GitHub Release entry because the brand-new `wickra-win32-arm64-msvc`
sub-package name was caught by npm's spam-detection filter on its first
publish attempt (same situation that affected `wickra-win32-x64-msvc`
through 0.1.4 until npm Support unblocked it). A support ticket is open;
until it is resolved, ship 0.2.1 for the five platforms whose
sub-packages are already on npm and re-add Windows ARM64 in a follow-up
release.

Changes for this cycle:
- bindings/node/package.json: remove "wickra-win32-arm64-msvc" from
  optionalDependencies and "aarch64-pc-windows-msvc" from
  napi.triples.additional.
- bindings/node/npm/win32-arm64-msvc/: removed (will be restored fresh
  once the npm name is unblocked).
- .github/workflows/release.yml: comment out the
  aarch64-pc-windows-msvc entry of the node-build matrix with a
  TODO/restore note.
- Bump every workspace and binding version to 0.2.1 (Cargo.toml,
  pyproject.toml, bindings/node/package.json, five npm/<target>
  templates, the wiki version table). Cargo.lock regenerated.
- CHANGELOG: new [0.2.1] block consolidating every fix that has landed
  on main since 0.2.0 (HV epsilon, examples CI step, fuzz cargo-fuzz
  install, MSRV 1.85 -> 1.86 / 1.77 -> 1.88, criterion 0.5 -> 0.8,
  tokio-tungstenite 0.24 -> 0.29, tick_aggregator gap-fill cap, every
  GitHub Action SHA-pin bump). Compare-link added.

The arm64 loader branch in bindings/node/index.js is left untouched: a
Windows ARM64 user installing 0.2.1 will get the standard
`Cannot find module 'wickra-win32-arm64-msvc'` error from the loader,
which is accurate. PyPI's win-arm64 wheel is unaffected.

Verified locally:
  cargo fmt/clippy/test --workspace --all-features -> 630 passed / 0 failed
  cargo build -p wickra-examples --bins -> clean
  cargo build -p wickra-node -> clean
2026-05-23 22:20:20 +02:00

155 lines
5.2 KiB
Markdown

# Quickstart: WebAssembly
A five-minute tour of the Wickra WebAssembly binding. The same Rust core that
powers the Python, Node, and Rust APIs is compiled to WebAssembly with
[wasm-bindgen](https://rustwasm.github.io/wasm-bindgen/), so indicators run
entirely client-side — in a browser tab, a bundler build, or Node — with no
server round-trips.
## Install
The published package is `wickra-wasm` on npm:
```bash
npm install wickra-wasm
```
The npm package is built for the bundler target, so it works directly with
Webpack, Vite, Rollup, and similar toolchains.
## Build from source
To build the binding yourself you need [`wasm-pack`](https://rustwasm.github.io/wasm-pack/)
and the `wasm32-unknown-unknown` target:
```bash
rustup target add wasm32-unknown-unknown
cargo install wasm-pack
# Browser ES-module build (import directly from a <script type="module">):
wasm-pack build bindings/wasm --target web --release --features panic-hook
# Bundler build (Webpack / Vite / Rollup):
wasm-pack build bindings/wasm --target bundler --release --features panic-hook
```
`wasm-pack` writes the generated module, the `.wasm` binary, and TypeScript
definitions into `bindings/wasm/pkg/`. The `panic-hook` feature routes Rust
panics to `console.error` for readable stack traces during development.
## A first run (browser)
With a `--target web` build, import the generated module directly:
```html
<script type="module">
import init, { version, SMA } from "./pkg/wickra_wasm.js";
await init(); // load and instantiate the .wasm binary
console.log("wickra-wasm", version());
const sma = new SMA(3);
console.log(sma.batch([2, 4, 6, 8, 10]));
// -> Float64Array [ NaN, NaN, 4, 6, 8 ]
</script>
```
`init()` must be awaited once before any indicator is constructed — it fetches
and instantiates the WebAssembly binary. After that the API mirrors the other
bindings.
## Streaming
```javascript
import init, { RSI } from "wickra-wasm";
await init();
const rsi = new RSI(14);
for (const price of liveFeed) {
const value = rsi.update(price); // number, or null/undefined during warmup
if (value != null && value > 70) {
console.log("overbought");
}
}
```
Every indicator is an O(1)-per-update state machine: `update` advances the
indicator by exactly one input, so a browser charting app pays no cost for
recomputing history on each tick.
## Multi-output indicators
Several indicators return a structured object from `update` (or `null` during
warmup). The full list and their field names:
| Indicator | `update` return shape |
|---------------------|--------------------------------------------------|
| `MACD` | `{ macd, signal, histogram }` |
| `BollingerBands` | `{ upper, middle, lower, stddev }` |
| `Stochastic` | `{ k, d }` |
| `ADX` | `{ plusDi, minusDi, adx }` |
| `Keltner` | `{ upper, middle, lower }` |
| `Donchian` | `{ upper, middle, lower }` |
| `Aroon` | `{ up, down }` |
| `SuperTrend` | `{ value, direction }` |
```javascript
import init, { MACD } from "wickra-wasm";
await init();
const macd = new MACD(12, 26, 9);
let last = null;
for (let i = 0; i < 40; i++) {
last = macd.update(100 + i * 0.5); // null during warmup, else { macd, signal, histogram }
}
console.log(last);
```
`batch` returns a flat `Float64Array`; multi-output indicators interleave
their fields per row (e.g. MACD: `[macd0, signal0, hist0, macd1, ...]`). The
exact layout is documented in the generated `pkg/wickra_wasm.d.ts`.
> Since `wickra-wasm@0.2.1`, every candle-input indicator (ATR, ADX,
> WilliamsR, CCI, MFI, PSAR, Keltner, Donchian, VWAP, RollingVWAP,
> AwesomeOscillator, Aroon, Stochastic, OBV, and the rest of the
> volume / volatility / trailing-stop / price-statistics families) exposes
> the same streaming API as `MACD` here — `update`, `batch`, `reset`,
> `isReady` and `warmupPeriod`. Earlier releases only shipped `batch` for
> twelve of these classes; browser code no longer needs to replay `batch`
> on every tick.
## Errors
Unlike the Node binding (whose constructors clamp pathological values), the
WASM binding's constructors throw a JavaScript error for invalid parameters:
```javascript
try {
new MACD(0, 0, 0);
} catch (e) {
console.error("invalid MACD parameters:", e);
}
```
## A complete example
`examples/wasm/index.html` is a self-contained browser demo: it streams a
synthetic price series through six indicators and draws a live chart on a
`<canvas>`. Open it after a `--target web` build:
```bash
wasm-pack build bindings/wasm --target web --release --features panic-hook
# then serve the repository root and open examples/wasm/index.html
```
## See also
- [Quickstart: Node](Quickstart-Node.md) — the native (non-WASM) Node binding.
- [Streaming vs Batch](Streaming-vs-Batch.md) — why `update` is the primary
entry point.
- [Indicators Overview](Indicators-Overview.md) — every indicator and its
parameters.
- Source: <https://github.com/kingchenc/wickra>