first commit
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user