# flowscripter-io-cli-hash-native
[](https://github.com/flowscripter/flowscripter-io-cli-hash-native/releases)
[](https://github.com/flowscripter/flowscripter-io-cli-hash-native/actions/workflows/release-bun-rust-library.yml)
[](https://flowscripter.github.io/flowscripter-io-cli-hash-native/index.html)
[](https://docs.rs/flowscripter_io_cli_hash_native)
[](https://github.com/flowscripter/flowscripter-io-cli-hash-native/blob/main/LICENSE)
> 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:
```typescript
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:
[API Documentation](https://flowscripter.github.io/flowscripter-io-cli-hash-native/index.html)
## License
MIT © Flowscripter