@hsblabs/web-stream-extras を公開した。
プロジェクトをまたいでコピペし続けていた内部実装から始まった。ReadableStream<Uint8Array> まわりにユーティリティが十分たまってきたので、きちんとパッケージにまとめることにした。
npm install @hsblabs/web-stream-extrasNode.js ≥22 とモダンブラウザで動作する。ランタイム依存なし。
ルートパッケージに含まれるもの
ルートエクスポートは日常的なバイトストリーム操作を担う。
import { readableFromChunks, readAllBytes, stringToBinary, binaryToString,} from "@hsblabs/web-stream-extras";
const stream = readableFromChunks([ stringToBinary("hello"), stringToBinary(" world"),]);
const result = await readAllBytes(stream);console.log(binaryToString(result)); // "hello world"readableFromChunks は Uint8Array チャンクの配列を ReadableStream に変換する。readAllBytes はストリームの全データを単一の Uint8Array に収集する。変換ヘルパー群 — stringToBinary、binaryToString、toU8Array、toArrayBuffer、concatU8Arrays — は string、Uint8Array、ArrayBuffer 間の変換が繰り返しになりやすく、微妙に間違いやすいために用意した。
ByteTransformStream はバイナリ変換パイプラインを構築するための型付き抽象基底クラスだ。ByteQueue はチャンクをまたいだ部分的なバイト読み取りが必要なときの内部バッファリングを担う。
Base64url エンコードも含まれている。encodeBase64Url と decodeBase64Url はパディングなし。
ストリーム暗号化
encryption サブパスは Web Crypto API を使った暗号化を追加する。
import { encryptStream, decryptStream,} from "@hsblabs/web-stream-extras/encryption";
const key = crypto.getRandomValues(new Uint8Array(32));const encrypted = encryptStream(key, plaintext);const decrypted = decryptStream(key, encrypted);encryptStream と decryptStream は ReadableStream を受け取り ReadableStream を返す。内部の EncryptionStream と DecryptionStream は TransformStream ラッパーとして公開されているので、別の形で組み合わせることもできる。
鍵管理が必要なケースでは、webCryptoStream(masterKey) が AES-GCM マスター鍵を使ったストリームごとの鍵の導出と暗号化を担う。
なぜ Web Streams か
WHATWG Streams API は Node.js ≥18 とモダンブラウザでネイティブに使える。Node.js 固有のストリーム抽象を避けることで、コードの移植性が上がる。ブラウザとサーバーの両側で同じバイトパイプラインを扱う必要があるなら、WHATWG API が正しい基盤になる。
フィードバックや issue はいつでも歓迎。
hsb.horse