Skip to content

Add experimental WebAssembly support for BMP/BGP/MRT parsing#267

Merged
digizeph merged 10 commits intomainfrom
dev/add-wasm-support
Mar 23, 2026
Merged

Add experimental WebAssembly support for BMP/BGP/MRT parsing#267
digizeph merged 10 commits intomainfrom
dev/add-wasm-support

Conversation

@digizeph
Copy link
Member

@digizeph digizeph commented Mar 22, 2026

Summary

Add experimental WebAssembly support for BMP/BGP/MRT parsing, published as @bgpkit/parser on npm.

Live demo: mrt-explorer.labs.bgpkit.com

Use cases

  • Real-time BMP stream processing: Parse OpenBMP messages from RouteViews Kafka stream (Node.js)
  • MRT updates file analysis: Parse MRT updates files from RIPE RIS (gz) and RouteViews (bz2) archives
  • Browser-based MRT exploration: Drag-and-drop MRT file parsing in the browser (live demo)
  • Individual BGP UPDATE parsing: Parse single BGP UPDATE messages on any platform

Public API

Core parsing functions (all platforms):

  • parseOpenBmpMessage(data) — parse OpenBMP-wrapped BMP frames
  • parseBmpMessage(data, timestamp) — parse raw BMP frames
  • parseBgpUpdate(data) — parse a single BGP UPDATE message
  • parseMrtRecords(data) — streaming generator that yields MRT records one at a time
  • parseMrtRecord(data) / resetMrtParser() — low-level MRT record parsing

Node.js I/O helpers:

  • streamMrtFrom(pathOrUrl) — fetch, decompress (gz/bz2), and stream-parse MRT records
  • openMrt(pathOrUrl) — fetch and decompress MRT data into a Buffer

Platform support

Platform Parsing I/O helpers Kafka
Node.js (CJS) Yes Yes Yes
Node.js (ESM) Yes No Yes
Bundler (webpack, vite) Yes No No
Browser Yes (after init()) No No
Cloudflare Workers Yes (after init()) No No

Memory model

The entire decompressed MRT file must fit in memory. parseMrtRecords then iterates record-by-record, avoiding accumulation of all parsed BgpElem objects. Suitable for MRT updates files (20–200 MB decompressed). Full RIB dumps (500 MB+) should use the native Rust crate.

Versioning

npm package version tracks the Rust crate minor version: for crate 0.X.Y, npm is 0.X.Z where Z increments independently.

Changes

  • New wasm feature flag with wasm-bindgen bindings in src/wasm.rs
  • JS wrapper layer (src/wasm/js/) with Node.js CJS, bundler ESM, and web ESM entry points
  • TypeScript type definitions for all exported functions and return types
  • Build script (src/wasm/build.sh) producing multi-target npm package
  • Node.js examples: Kafka OpenBMP stream consumer, MRT file parser
  • Browser MRT explorer deployed at mrt-explorer.labs.bgpkit.com
  • bz2 decompression via optional seek-bzip dependency

Test plan

  • Unit tests for WASM parsing functions (src/wasm/test/)
  • Kafka OpenBMP stream example tested against RouteViews live stream
  • MRT file parsing tested with RIPE RIS gz and RouteViews bz2 files
  • cargo test passes
  • cargo clippy --all-features passes
  • Browser MRT explorer deployed and accessible
  • Manual test of Cloudflare Workers deployment

Add a `wasm` feature flag that compiles the parsing core to WebAssembly,
published as `@bgpkit/parser` on npm. Supports three targets: Node.js
(CommonJS), bundlers (ES modules), and browsers/workers (ES modules
with manual init).

Exported functions:
- parseOpenBmpMessage: OpenBMP-wrapped BMP frames (RouteViews Kafka)
- parseBmpMessage: raw BMP frames
- parseMrtFile: decompressed MRT files
- parseBgpUpdate: single BGP UPDATE messages

Includes JS wrapper with JSON deserialization, TypeScript types,
multi-target build script, and two Node.js examples (Kafka OpenBMP
stream consumer and MRT file parser).
@codecov
Copy link

codecov bot commented Mar 22, 2026

Codecov Report

❌ Patch coverage is 68.51852% with 102 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.68%. Comparing base (ba9022a) to head (ffaf42b).
⚠️ Report is 11 commits behind head on main.

Files with missing lines Patch % Lines
src/wasm.rs 68.51% 102 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #267      +/-   ##
==========================================
- Coverage   91.15%   90.68%   -0.47%     
==========================================
  Files          83       84       +1     
  Lines       15138    15462     +324     
==========================================
+ Hits        13799    14022     +223     
- Misses       1339     1440     +101     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Extract core parsing logic into testable functions that return
Result<String, String> instead of JsError, with thin wasm_bindgen
wrappers on top. Tests cover BMP initiation/peer-up parsing, BGP
UPDATE parsing, MRT empty file, invalid input handling, and peer
header construction.
Add parseMrtRecord and parseMrtRecords functions that parse one MRT
record at a time, enabling processing of multi-GB RIB dump files
without exceeding WASM's 4GB memory limit. JS-side MRT header framing
ensures only one record's bytes are passed to WASM per call.

Use thread-local Elementor to persist PeerIndexTable across calls,
required for TABLE_DUMP_V2 (RIB dump) files. Add resetMrtParser to
clear state between files.

Tested: 3.9GB RIB dump (55.9M elements) parses in ~190s via streaming.
- Remove parseMrtFile (batch) in favor of parseMrtRecords (streaming generator)
  and streamMrtFrom (Node.js async generator with I/O)
- Remove detectCompression from public exports (internal utility)
- Add openMrt, streamMrtFrom Node.js I/O helpers with gz/bz2 support
- Add parseMrtRecord/resetMrtParser low-level API for custom iteration
- Add web.mjs/web.d.ts entry point for browser and Cloudflare Workers
- Rewrite README with use-case-driven sections, code snippets, memory
  considerations, and platform support matrix
- Simplify parse-mrt-file example to use streamMrtFrom
- Add browser MRT explorer examples (HTML and JSX)
- Bump npm package version to 0.15.2
- Update CHANGELOG with streaming API details
Switch from esm.sh to jsdelivr CDN for loading @bgpkit/parser WASM.
esm.sh rewrites JS modules, breaking import.meta.url and WASM path
resolution. jsdelivr serves raw files with correct Content-Type and
CORS headers. Also use the /web entry point (with async init()) instead
of the bundler target which requires bundler-specific WASM handling.
- Link to mrt-explorer.labs.bgpkit.com in README and CHANGELOG
- Remove unused mrt-explorer.jsx (standalone HTML file is the demo)
- Add .wrangler/ to .gitignore
The deployed version lives in the bgpkit/labs repo.
@digizeph digizeph merged commit 2135e69 into main Mar 23, 2026
4 checks passed
@digizeph digizeph deleted the dev/add-wasm-support branch March 23, 2026 02:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant