release: v0.3.0-alpha.24 master
add car.streamBlocks + BlockIterator for zero-alloc CAR iteration over large repos. strictly additive — read/readWithOptions/Car/findBlock are unchanged. shares parser helpers (readUvarint, cidLength, verifyBlockHash) and the CarError set with the existing path, so future CAR fixes benefit both. motivated by ken (semantic search over a PDS) which trips the 200k block guard on repos like pfrazee.com (~72 MB, 248k blocks). the existing read() path eagerly builds a StringHashMapUnmanaged indexing every CID — ~12 MB of auxiliary metadata on top of whatever the caller is doing. streamBlocks skips the hashmap and Block[] entirely; iterator is O(1) space beyond the input buffer, and offset() lets callers build a CID → byte-offset index that's strictly smaller. tests: - round-trip equivalence against read (same block ordering + bytes) - corruption test confirms BadBlockHash still fires through the iterator - ZAT_STRESS=1 gated test against cached /tmp/pfrazee.car (72 MB, 248k blocks) — asserts stream + read see identical block count, total bytes, and cid xor. not in CI. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>