@flowscripter/flowscripter-io-cli-hash-native
v2.0.5
Published
Rust-backed sha256 hasher for flowscripter-io-cli, exposed via Bun FFI
Readme
flowscripter-io-cli-hash-native
Rust-backed sha256 hasher for flowscripter-io-cli, exposed via Bun FFI.
Bun Module Usage
Add the module:
bun add @flowscripter/flowscripter-io-cli-hash-native
Use the module:
import { initNativeLib, Sha256Hasher } from "@flowscripter/flowscripter-io-cli-hash-native";
await initNativeLib();
const hasher = new Sha256Hasher();
hasher.update(new TextEncoder().encode("hello"));
const digest = hasher.final();Development
Install dependencies:
bun install
Build (produces dist/ for Node.js and TypeScript consumers; Bun uses raw source directly):
bun run build
Test:
cargo test
cargo build --release && FLOWSCRIPTER_HASH_NATIVE_DEV_BUILD=1 bun test
By default the native library is loaded from ~/.flowscripter/lib (downloaded from the release if missing or if it does not match its checksum). Setting FLOWSCRIPTER_HASH_NATIVE_DEV_BUILD=1 makes the package prefer its own target/release build instead.
Format:
cargo fmt && bunx oxfmt
Lint:
bunx oxlint index.ts src/ tests/
Generate HTML API Documentation:
bunx typedoc index.ts
Documentation
Overview
Sha256Hasher wraps a native Rust sha2 implementation behind three extern "C" functions (hasher_init, hasher_update, hasher_final) loaded via bun:ffi's dlopen.
Importing the package has no side effects. initNativeLib() must be awaited before the first Sha256Hasher is created: it resolves, downloads and verifies the native library, then loads it once.
Each release publishes a <library file>.shasum (SHA-256) sibling asset for every native library. A download is written to a temporary file, checked against that checksum and only then renamed into ~/.flowscripter/lib along with its .shasum. An already installed library is verified against its .shasum before it is loaded, and initNativeLib() rejects if verification fails.
update() accepts a JS-owned Uint8Array and passes a raw pointer straight into the synchronous Rust call using bun:ffi's ptr() - no further copy is made once the bytes are in JS memory.
updatePointer() accepts an already-raw pointer/length pair - for example a chunk that originated from a native source and never had a JS-owned copy - and passes it straight through to the Rust call with no copy at all.
The resulting 32-byte digest is copied back to JS by final(), which is negligible in size regardless of how much data was hashed.
API
Link to auto-generated API docs:
License
MIT © Flowscripter
