@unikvs/compression
gzip / deflate / deflate-raw でバイト列を透過的に圧縮・展開する Transformer プラグインの使い方を説明します。
概要
@unikvs/compression は、バイト列を透過的に圧縮・展開する Transformer プラグインです。Transformer Web 標準の CompressionStream と DecompressionStream をラップし、ITransformer に適合させています。
書き込み時は encode で圧縮し、読み取り時は decode で展開するため、圧縮を意識せずに読み書きできます。
常にオープン状態です。open・close は不要で、isOpen は常に true、name は常に "Compression" を返します。
インストールは次のように行います。
npm install @unikvs/compressionpnpm add @unikvs/compressionyarn add @unikvs/compressionbun add @unikvs/compressionnub add @unikvs/compressionaube add @unikvs/compression対応フォーマット
コンストラクターで指定できる形式は CompressionFormat 型です。CompressionStream と DecompressionStream の両方で受け入れ可能な文字列に限定しています。テスト済みの値は次の 3 つです。
| フォーマット | 値 | 特徴 |
|---|---|---|
| gzip | "gzip" |
ヘッダーとフッターを持ち、汎用性が高い形式です。 |
| deflate | "deflate" |
zlib ラッパーを持つ形式です。 |
| deflate-raw | "deflate-raw" |
ラッパーを持たない素の形式です。 |
互換性を重視するなら "gzip" を選びます。他システムとの取り決めがある場合は、その形式に合わせてください。
import { Compression } from "@unikvs/compression";
const compression = new Compression("gzip");
1 つの KVS では 1 つの形式に統一してください。混在させると展開に失敗します。
実行環境が対応していない形式を指定した場合、CompressionStream または DecompressionStream の構築時に TypeError が投げられます。
使い方
Compression のコンストラクターは圧縮形式を 1 つだけ受け取ります。オプションはありません。
import { Compression } from "@unikvs/compression";
const compression = new Compression("gzip");
主なメンバーは次のとおりです。
| メンバー | 概要 |
|---|---|
new Compression(format) |
圧縮形式を指定して初期化します。 |
name |
常に "Compression" を返します。 |
isOpen |
常に true を返します。 |
encode({ data }) |
Uint8Array<ArrayBuffer> を圧縮します。 |
decode({ data }) |
圧縮済みの Uint8Array<ArrayBuffer> を展開します。 |
getEncodable() |
圧縮用の TransformStream を返します。 |
getDecodable() |
展開用の TransformStream を返します。 |
UniKvs には appendTransformer で登録します。以降に登録するストレージの前段になります。
import { Compression } from "@unikvs/compression";
import UniKvs from "unikvs";
const kvs = UniKvs.config()
.appendTransformer(new Compression("gzip"))
.appendStorage(storage)
.create();
await kvs.open();
await kvs.set("data", input);
const output = await kvs.get("data");
set で圧縮して保存し、get で自動的に展開します。
ストリームとバイト列
単体値とストリームの両方に対応しています。
- 単体値は
encode・decodeで変換します。空配列や 1 MiB 程度のバイト列もそのまま往復できます。 - ストリーム値は
getEncodable・getDecodableのTransformStreamで変換します。不揃いな複数チャンクも、往復後は元のバイト列に戻ります。
制限は次のとおりです。
decodeに非圧縮のバイト列を渡すと拒否されます。- 圧縮時と展開時で形式が異なると展開できません。同じ形式で往復してください。
- 圧縮の余地がないデータでは、サイズが小さくならない場合があります。その場合も展開すれば元に戻ります。
注意点
反復的なテキストは小さくなりやすく、圧縮済みや乱数的なデータは小さくなりにくい傾向があります。小さくならなくても、往復の正確さは損なわれません。
使用例
Memory と組み合わせた最小例です。書き込んだ値は圧縮して保存し、読み取り時に自動で展開します。
import { Compression } from "@unikvs/compression";
import { Memory } from "@unikvs/memory";
import UniKvs, { type PlainValue } from "unikvs";
const kvs = UniKvs.config<{ data: PlainValue<Uint8Array<ArrayBuffer>> }>()
.appendTransformer(new Compression("gzip"))
.appendStorage(new Memory())
.create();
await kvs.open();
const input = new TextEncoder().encode(
"Repeat this text multiple times to ensure compression efficiency. ".repeat(100),
);
await kvs.set("data", input);
const output = await kvs.get("data");
console.log(output.length === input.length);
await kvs.close();