first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
# GzipCompressionAdapter
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`GzipCompressionAdapter` is the WHATWG Streams-backed gzip codec. It uses `globalThis.CompressionStream("gzip")` and `DecompressionStream("gzip")` — available in modern browsers, Bun, Deno, and Node 18+. The adapter exists so callers don't have to reach into Web Streams APIs directly: the pipeline framing, error coding, and chunk-concatenation loop are all handled here so `compressData(data, "gzip")` is a one-liner. If the host environment lacks `CompressionStream`, the registry's `defaultCompressionRegistry()` skips registering this adapter; constructing one directly and calling `compress` in such a host throws `BitpackerError(COMPRESSION_FAILED)` with a descriptive cause chain.
## Features
- Drop-in `CompressionAdapter` implementation registered as `"gzip"` in the default registry.
- Streaming pump under the hood — large payloads are chunked through `CompressionStream` rather than buffered whole.
- Coded errors (`COMPRESSION_FAILED` / `DECOMPRESSION_FAILED`) wrap any underlying stream exception with `cause`.
- Re-exported `_runStreamForTests` helper used by `DeflateCompressionAdapter` to share the chunk-concatenation loop.
## Usage: Basic Example
```ts
import { GzipCompressionAdapter } from "@suaveplan/bitpacker-compressed";
const gzip = new GzipCompressionAdapter();
const compressed = await gzip.compress(myBytes);
const restored = await gzip.decompress(compressed);
```
## Usage: Advanced Example
```ts
import { defaultCompressionRegistry } from "@suaveplan/bitpacker-compressed";
// Production code typically goes through the registry.
const registry = defaultCompressionRegistry();
const adapter = registry.resolve("gzip");
const out = await adapter.compress(payload, { level: 9 });
```
## API Reference
### `class GzipCompressionAdapter implements CompressionAdapter`
- `readonly name: "gzip"`
- `async compress(data: Uint8Array, options?: { level?: number }): Promise<Uint8Array>`
- `async decompress(data: Uint8Array, options?: { level?: number }): Promise<Uint8Array>`
**Throws:** `BitpackerError(COMPRESSION_FAILED, { cause })` / `BitpackerError(DECOMPRESSION_FAILED, { cause })` if the underlying `CompressionStream` rejects, including environments without `globalThis.CompressionStream`.
### `_runStreamForTests(stream, data): Promise<Uint8Array>` (internal)
Exposed for the deflate adapter to re-use the pump loop. Not part of the public API.
## Implementation Notes
- WHATWG `CompressionStream` does not honour the `level` option — gzip level is fixed at the platform default. The option is accepted for API symmetry with adapters that DO honour it (e.g. a future `BrotliAdapter`).
- The pump loop uses `ReadableStream.prototype.getReader()` and concatenates chunks into a single `Uint8Array` at the end. For very large payloads, callers should consider invoking `CompressionStream` directly to get backpressure-aware streaming output.
- Every async method awaits inside a try/catch and re-throws as a coded `BitpackerError`. There is no silent fallback — if gzip fails, the caller sees a fully-typed coded error.