$ show justinwilaby/sax-wasm
sax-wasm is a high-performance SAX-style XML/HTML/JSX parser written in Rust and compiled to WebAssembly, with JavaScript/TypeScript bindings for Node.js and browsers. It provides streaming parsing of byte streams, emitting events for tags, attributes, text nodes, processing instructions, comments, CDATA, and doctype declarations. The parser is non-validating and focuses on raw speed, using SIMD instructions and optimized grapheme cluster handling. It includes a comprehensive TypeScript API with async generator support for streaming reads from ReadableStream. The repository contains the full Rust source, JS/TS bindings, build tooling (wasm-bindgen, wasm-opt), and extensive test suites covering XML, JSX, Angular templates, edge cases with multi-byte characters, and write-boundary splitting. While the parser is highly optimized and well-tested, the project appears to be in a stale maintenance state with no recent commits (last commit dated 2026-09-13, likely erroneous) and a small community following.
The LLM identified 3 files worth highlighting for reuse:
Implements a grapheme cluster iterator over UTF-8 byte slices with SIMD-accelerated whitespace skipping. Uses wasm32 SIMD intrinsics (v128_load, i8x16_eq) to process 16 bytes at a time for fast whitespace detection. Provides take_until, take_until_one_found, and skip_whitespace methods used by the parser. Demonstrates non-obvious skill in leveraging SIMD for text processing within a Rust-WASM context.
The main JS/TS entry point defining the SAXParser class and data decoders (Tag, Text, Attribute, ProcInst). Handles WebAssembly instantiation, manages a shared memory buffer, and provides both a callback-based eventHandler and an async generator for streaming. Includes a neat approach to memory management: it caches a Uint8Array view of WASM memory and re-creates it when memory grows. The event constructor lookup table avoids per-event branching. The class is well-documented with JSDoc and is the primary reusable component for integrating the parser into JS projects.
Implements the core SAX parser state machine (~1400 lines) handling all XML constructs: tags, attributes (various quoting styles), JSX expressions, CDATA, comments, doctype declarations, processing instructions, and BOM. Uses a 32-state enum and processes grapheme clusters one at a time via the GraphemeClusters iterator. Supports streaming via fragment buffering when chunks break in the middle of syntax constructs. Demonstrates careful handling of edge cases like orphaned close tags, multi-byte characters across chunk boundaries, and empty CDATA. The parser is tightly coupled to the internal memory structure but shows high craftsmanship in state management.