コンテンツにスキップ
UniKVS
日本語
Esc
↑↓移動↵開く⌘Jプレビュー
このページの内容

@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/compression
pnpm add @unikvs/compression
yarn add @unikvs/compression
bun add @unikvs/compression
nub add @unikvs/compression
aube 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();

このページは役に立ちましたか?