Versions bumped to 0.1.5 in every authoritative location:
- workspace `Cargo.toml` (`[workspace.package].version`, the
`wickra-core` path dependency pin).
- `bindings/python/pyproject.toml`.
- `bindings/node/package.json` (main + all six `optionalDependencies`
pins).
- All six per-platform `bindings/node/npm/<target>/package.json`
templates.
CHANGELOG: the accumulated `[Unreleased]` block is promoted to
`[0.1.5] - TBD` (date left for the user to set at tag time); the new
`[Unreleased]` header sits empty above it; the compare link table is
extended with `[0.1.5]: …compare/v0.1.4...v0.1.5` and the
`[Unreleased]` link is repointed to `…compare/v0.1.5...HEAD`.
Wiki refresh for 0.1.5 (R20 + Z2):
- `Home.md` version pin table updated; the Quickstart-Node hint replaces
the "spam filter holding back Windows" caveat with "0.1.5 is the
first release in which `npm install wickra` works end-to-end on
Windows" (npm Support released the name on 2026-05-22).
- `Quickstart-Node.md`'s Windows caveat is rewritten to explain the
history (`0.1.1`–`0.1.4` of `wickra-win32-x64-msvc` are burned) and
the resolution (0.1.5+ installs cleanly).
- `Quickstart-Rust.md` version mention bumped.
- `Warmup-Periods.md` note bumped + corrected: every Node and WASM
class — single- and multi-output — now exposes `warmupPeriod()` after
R3 (this branch), not only the single-output ones.
`release.yml` `publish_dir` no longer silently swallows a
second-attempt platform-package publish failure with a `::warning::`
and `return 0`. A real failure (after the existing 30s retry) now
emits an `::error::` and fails the job. The original mask is exactly
what allowed the `wickra-win32-x64-msvc@0.1.1–0.1.4` spam-filter
rejections to land four times in a row without anyone noticing (audit
finding R20). Failing loud means the next regression of this shape is
caught at the release run, not by a Windows user trying to
`require('wickra')`.
This commit does NOT push, tag, or trigger a release — the user
publishes the 0.1.5 tag themselves once the manual npm-republish
smoke test confirms `wickra-win32-x64-msvc@0.1.5` accepts publish on
the freshly-released name.
6.0 KiB
Quickstart: Node
A five-minute tour of the Wickra Node.js binding. The binding is generated by napi-rs, so it's a native addon — no WebAssembly, no slow JS reimplementation.
Install
npm install wickra
Windows install (0.1.5+). Earlier patch releases were blocked on Windows x64 because the platform-specific sub-package
wickra-win32-x64-msvcwas held back by npm's automated spam filter, sorequire('wickra')threwError: Cannot find module 'wickra-win32-x64-msvc'after a successfulnpm install. npm Support released the name on 2026-05-22; 0.1.5 is the first version in which Windows x64 installs cleanly end-to-end (version numbers0.1.1–0.1.4of that sub-package remain burned and cannot be republished — see the npm registry page forwickra-win32-x64-msvc). Linux x64, Linux arm64 and macOS (x64 + arm64) were unaffected throughout.
A first run
const wickra = require('wickra');
console.log('wickra', wickra.version());
// Simple moving average over a fixed window.
const sma = new wickra.SMA(3);
console.log(sma.batch([2, 4, 6, 8, 10]));
// -> [ NaN, NaN, 4, 6, 8 ]
Two things to notice:
- The
batchreturn type is a regular JavaScriptArray<number>. Warmup slots areNaN, notnullorundefined, so the array isNumber.isFinite-checkable in one pass. new wickra.SMA(0)does not throw. Constructors in the Node binding currently cannot raise errors from JS (a napi-rs 2.16 limitation), so pathological values likeperiod = 0are clamped to the smallest valid window. This is exactly the behaviour pinned bybindings/node/__tests__/smoke.test.js("zero period is clamped to a valid window").
Streaming
const wickra = require('wickra');
const sma = new wickra.SMA(3);
for (const price of [2, 4, 6, 8, 10]) {
const value = sma.update(price);
console.log('update', price, '->', value);
}
Output:
update 2 -> null
update 4 -> null
update 6 -> 4
update 8 -> 6
update 10 -> 8
update returns either a JavaScript number or null while the indicator
is still warming up. (Compare with batch, where warmup slots are NaN.
The asymmetry exists because the streaming API surfaces "no value yet"
through the JS type system, whereas the batch result is shaped as a numeric
array for downstream numeric code.)
MACD: streaming and batch
MACD is the canonical multi-output indicator. The Node API surfaces this in
two shapes:
update(price)returns eithernull(during warmup) or{ macd, signal, histogram }.batch(prices)returns a flatArray<number>of lengthprices.length * 3, laid out as[macd_0, signal_0, hist_0, macd_1, signal_1, hist_1, ...], with each warmup row written as threeNaNs.
Streaming form:
const wickra = require('wickra');
const macd = new wickra.MACD(12, 26, 9);
let last = null;
for (let i = 0; i < 40; i++) {
last = macd.update(100 + i * 0.5);
}
console.log(last);
// -> { macd: 3.5, signal: 3.500000000000001, histogram: -8.881784197001252e-16 }
Batch form (note the flat layout):
const wickra = require('wickra');
const prices = Array.from({ length: 40 }, (_, i) => 100 + i * 0.5);
const macd = new wickra.MACD(12, 26, 9);
const flat = macd.batch(prices);
console.log('total values:', flat.length); // -> 120 (= 40 * 3)
console.log('row 33 :', flat.slice(99, 102)); // -> [ 3.5, 3.5, 0 ]
console.log('row 39 :', flat.slice(117, 120)); // -> [ 3.5, 3.5000000..., -8.88e-16 ]
// Reshape into 3-tuples if you want:
const rows = [];
for (let i = 0; i < flat.length; i += 3) {
rows.push({ macd: flat[i], signal: flat[i + 1], histogram: flat[i + 2] });
}
MACD(12, 26, 9) emits its first non-NaN row at index 33 because the
underlying Rust warmup_period() is slow + signal − 1 = 34 (the first
ready row is warmup_period - 1 in 0-indexed terms).
API surface
The complete TypeScript definitions live at
bindings/node/index.d.ts. Every indicator class exposes some subset of:
| Member | Notes |
|---|---|
constructor(...) |
Pathological values are clamped, not thrown. |
update(...) |
Returns the indicator output or null during warmup. |
batch(...) |
Single-output: flat Array<number> with NaN warmup.Multi-output: flat interleaved Array<number>. |
reset() |
Returns to a freshly-constructed state. |
isReady() |
true once the first value has been emitted. |
warmupPeriod() |
Present on single-output indicators (SMA, EMA, WMA, RSI, ...). Not exposed on every multi-output class — check index.d.ts. |
A complete reference run lives in bindings/node/__tests__/smoke.test.js:
cd bindings/node
npm install
npm run build # only needed if you cloned the repo (Windows: see above)
npm test
Building from source (Windows workaround)
If you are on Windows x64 and want to use Wickra today, build the binding locally from the repository:
git clone https://github.com/kingchenc/wickra
cd wickra/bindings/node
npm install
npm run build # requires a Rust toolchain (rustup) on PATH
npm test
npm run build produces wickra.win32-x64-msvc.node in the binding
directory; the platform loader in index.js then picks it up before falling
through to the npm sub-package and the install just works.
See also
- Quickstart: Python — sibling binding with NumPy shapes.
- Streaming vs Batch — why
updateis the primary entry point, notbatch. - Warmup Periods — exact
warmup_period()for every indicator. - Source: https://github.com/kingchenc/wickra