# Run-length encoding (`compressRle` / `decompressRle`) _(no submodules)_ - rle.schema — Zod schema for the per-call `Compressi… - [rle.schema](./rle.schema.md) — Zod schema for the per-call `CompressionOptions` accepted by `compressRle` / `decompressRle`. The RLE codec is byte-onl… - rle.schema — Zod schema for the per-call `Compressi… - [rle.schema](./rle.schema.md) — Zod schema for the per-call `CompressionOptions` accepted by `compressRle` / `decompressRle`. The RLE codec is byte-onl… - rle.schema — Zod schema for the per-call `Compressi… - [rle.schema](./rle.schema.md) — Zod schema for the per-call `CompressionOptions` accepted by `compressRle` / `decompressRle`. The RLE codec is byte-onl… - rle.schema — Zod schema for the per-call `Compressi… - [rle.schema](./rle.schema.md) — Zod schema for the per-call `CompressionOptions` accepted by `compressRle` / `decompressRle`. The RLE codec is byte-onl… - [rle.schema](./rle.schema.md) — Zod schema for the per-call `CompressionOptions` accepted by `compressRle` / `decompressRle`. The RLE codec is byte-onl… ## Purpose `compressRle` / `decompressRle` are byte-level run-length encoding helpers shipped as a separate module within `@suaveplan/bitpacker-compressed` so embedded / no-streams environments can import them without pulling in `CompressionStream`-using gzip/deflate adapters or the `CompressedBitPacker` class. They are not part of the `CompressionRegistry` framing — bytes produced by `compressRle` are NOT the same shape as bytes produced by the registry's `"none"`/`"gzip"`/`"deflate"` adapters, which include the `CompressedBitPacker` header. If you need framed RLE, write a thin `RleCompressionAdapter` that internally calls these helpers. ## Features - Bytes-only fast path; no streams required. - Single-byte runs longer than 3 are emitted as `[byte][0][count]`; everything else passes through verbatim. - Symmetric round-trip with `decompressRle`. - Zero allocation overhead beyond the output `Uint8Array`. ## Usage: Basic Example ```ts import { compressRle, decompressRle } from "@suaveplan/bitpacker-compressed"; const data = new Uint8Array([1, 1, 1, 1, 1, 2, 3]); const compressed = compressRle(data); // [1, 0, 5, 2, 3] const restored = decompressRle(compressed); // back to original ``` ## Usage: Advanced Example ```ts import { compressRle, decompressRle, type CompressionAdapter, } from "@suaveplan/bitpacker-compressed"; // Wrap RLE in a CompressionAdapter shape so it plugs into the registry. class RleAdapter implements CompressionAdapter { readonly name = "rle"; async compress(data: Uint8Array) { return compressRle(data); } async decompress(data: Uint8Array) { return decompressRle(data); } } ``` ## API Reference ### `compressRle(data: Uint8Array): Uint8Array` - Encodes runs of >3 identical bytes as `[byte][0][count]`. - Returns a fresh `Uint8Array`; input is not mutated. ### `decompressRle(data: Uint8Array): Uint8Array` - Reverses `compressRle`. Looks ahead for `[0][count]` markers after each byte. - Returns a fresh `Uint8Array`. ### `CompressionOptions` Type alias for `{ readonly level?: number }` — accepted but ignored by the bytes-only RLE path; included so adapter authors can re-export the canonical compression-options shape. ## Implementation Notes - The marker byte is `0`, which would collide with a literal `0` in input data; the encoder handles this by always emitting the run-length form when `byte === 0` runs. - This is not the most aggressive RLE possible — it does not pack runs of distinct bytes into literal blocks. The intent is "smaller than verbatim with a single linear pass", not "competitive with gzip on text". - Use this when you have known byte-pattern data (e.g. graphics with large flat regions, sparse network frames). For general-purpose data, use the gzip / deflate adapters.