@stll/anonymize-wasm
v2.0.1
Published
PII detection and anonymization for browsers via WebAssembly. Same native SDK API as @stll/anonymize.
Maintainers
Readme
@stll/anonymize-wasm
Browser-friendly build of @stll/anonymize.
Use this package when you need the runtime API in a browser or bundler environment. It ships the WebAssembly build and the Vite helper that keeps the wasm assets out of dependency pre-bundling.
Install
bun add @stll/anonymize-wasmUsage
Same native-SDK surface as @stll/anonymize/native, backed by the WebAssembly
binding. Browsers load prebuilt prepared packages (there is no in-browser config
building). The wasm binding is instantiated lazily on first use.
import { loadDefaultPipeline } from "@stll/anonymize-wasm";
// Loads the compressed default package bundled in the tarball.
const pipeline = await loadDefaultPipeline();
const { redaction } = pipeline.redactText("A contract signed by Jan Novak.");
console.log(redaction.redactedText);Bring your own prepared package (bytes, an ArrayBuffer, or a URL to fetch):
import { loadPipeline } from "@stll/anonymize-wasm";
const pipeline = await loadPipeline(
new URL("./my-package.stlanonpkg", import.meta.url),
);With Vite, register the helper plugin so the wasm binary, WASI worker, and
.stlanonpkg assets survive both dependency pre-bundling (dev) and a
production vite build (the plugin emits the native/ assets and rewrites the
runtime asset base to point at them):
import stllAnonymizeWasm from "@stll/anonymize-wasm/vite";
// vite.config: plugins: [stllAnonymizeWasm()]By default the plugin emits every bundled prepared package into your build. The
full-dictionary default package alone is large (~20 MB), plus the per-language
cs, de, and en variants. If your app only needs some of them, restrict the
emitted packages with the packages option (the wasm binary, glue, and workers
are always emitted):
// Emit only the Czech scoped package.
stllAnonymizeWasm({ packages: ["cs"] });
// Emit the full-dictionary default plus English.
stllAnonymizeWasm({ packages: ["default", "en"] });
// Emit no prepared packages; the app supplies its own to loadPipeline().
stllAnonymizeWasm({ packages: "none" });
// Emit everything (the default).
stllAnonymizeWasm({ packages: "all" });"default" selects the full-dictionary package that loadDefaultPipeline()
(no argument) loads; a language code selects the scoped package that
loadDefaultPipeline("cs") loads. Requesting a package that is not bundled
fails the build.
Interplay with the runtime loaders: the plugin only controls which assets ship,
not which the code asks for. Calling loadDefaultPipeline(language) for a
package you did not emit resolves to a missing asset URL and rejects with a
fetch error at runtime. Keep the packages list aligned with the languages your
app actually loads, or load your own package bytes through loadPipeline.
Notes
- Same redaction core as
@stll/anonymize, running in WebAssembly. - The binding targets
wasm32-wasip1-threads(shared memory), so it needs a cross-origin-isolated context (SharedArrayBuffer) in the browser.
Third-party licenses
The shipped browser WASI glue (dist/native/index.wasi-browser.js and
dist/native/wasi-worker-browser.mjs) is bundled at build time and inlines the
following MIT-licensed runtime so it is self-contained for consumer bundlers:
@napi-rs/wasm-runtime(MIT) — Copyright (c) napi-rs authors — https://github.com/napi-rs/napi-rs@tybys/wasm-util(MIT) — Copyright (c) toyobayashi — https://github.com/toyobayashi/wasm-util
Both are distributed under the MIT License; the full license text is available in each project's repository.
Building from source
The wasm binding is generated by napi-rs and is not checked in:
cd packages/anonymize
bun run build:native-wasm # needs the wasm32-wasip1-threads Rust target
bun run build # tsdown + native node binding
bun run build:wasm-assets # copy glue + build compressed packages into wasm/dist/nativeThe wasm32-wasip1-threads target is pinned in rust-toolchain.toml, so
rustup installs it automatically; with a non-rustup toolchain run
rustup target add wasm32-wasip1-threads first.
