基本概念
UniKVS のトランスフォーマーとストレージの組み合わせ、値の型、変数について説明します。
アーキテクチャー
UniKVS はビルダーパターンで構成します。入力はトランスフォーマーの列を通り、ストレージに届きます。
役割は次の 2 つです。
- トランスフォーマーは、データのエンコード・デコードを透過的に行います。
- ストレージは永続化先です。複数指定すると、すべてに並列で書き込みます。
各ストレージは、登録時点までのトランスフォーマーを前段として使います。読み取り時は、見つかったストレージの前段を逆順に適用してデコードします。
設定ビルダー
UniKvs.config() でビルダーを作り、次の順序で設定します。schema を渡すと Valibot スキーマによる入出力検証が有効になり、キーと値のマッピング型も自動推論します。
import { PlainValue, StreamValue, UniKvs } from "unikvs";
import * as v from "valibot";
const kvs = UniKvs.config({
schema: {
message: PlainValue(v.string()),
logs: StreamValue(v.instance(Uint8Array)),
},
})
.appendStorage(storage)
.create();
Valibot スキーマを使う場合は valibot を別途インストールします。schema を省略した場合は、型パラメーターでマッピングを指定します。この場合は型チェックのみで、実行時の検証は行いません。
setVariables(vars)
実行時変数を設定します (任意)。
appendTransformer(transformer)
トランスフォーマーを追加します (任意)。
appendStorage(storage)
ストレージを追加します (必須、複数可)。
create()
KVS クライアントを作ります。
クライアント操作
| メソッド | 説明 |
|---|---|
open() |
ストレージとトランスフォーマーを初期化します。 |
close() |
すべてのストレージとトランスフォーマーをクローズします。 |
set(key, value) |
キーに値を保存します。 |
get(key) |
キーから値を取得します。 |
stream(key) |
キーからストリームを取得します。 |
has(key) |
キーが存在するかを確認します。 |
delete(key) |
キーを削除します。 |
clear() |
すべてのデータを削除します。 |
すべての操作は AbortSignal によるキャンセルと、実行時変数の受け渡しに対応します。
値の型
Value・PlainValue・StreamValue は型と関数の両方です。型として使うとキーごとに使えるメソッドが型レベルで決まり、関数として使うと Valibot スキーマから型を推論しつつ実行時の検証も行います。
| 型 | 書き込み | 読み取り | ストリーム読み取り |
|---|---|---|---|
PlainValue<T> |
set(key, T) |
get(key): T |
不可。 |
StreamValue<T> |
set(key, T | ReadableStream<T>) |
不可。 | stream(key): ValueStream<T> |
Value<T> |
set(key, T | ReadableStream<T>) |
get(key): T |
stream(key): ValueStream<T> |
Value<T> は両方に対応する糖衣構文で、PlainValue<T> | StreamValue<T> と等価です。
単一値の保存と取得に使います。stream() は型エラーです。
import { UniKvs, type PlainValue } from "unikvs";
const kvs = UniKvs.config<{
message: PlainValue<string>;
}>()
.appendStorage(storage)
.create();
await kvs.set("message", "hello");
const msg = await kvs.get("message");大規模データの逐次処理に使います。get() は型エラーです。
import { UniKvs, type StreamValue } from "unikvs";
const kvs = UniKvs.config<{
logs: StreamValue<Uint8Array>;
}>()
.appendStorage(storage)
.create();
await kvs.set("logs", new Uint8Array([0x01]));
const valueStream = await kvs.stream("logs");両方に対応する糖衣構文で、PlainValue<T> | StreamValue<T> と等価です。
import { UniKvs, type Value } from "unikvs";
const kvs = UniKvs.config<{
blob: Value<Uint8Array>;
}>()
.appendStorage(storage)
.create();
await kvs.set("blob", new Uint8Array([1, 2, 3]));
const all = await kvs.get("blob");
const valueStream = await kvs.stream("blob");スキーマ定義
UniKvs.config({ schema }) に渡すと、Valibot スキーマからマッピング型を推論し、入出力値を実行時に検証します。
キーをそのままキーとして扱います。固定キーに使います。
import { PlainValue, StreamValue, UniKvs } from "unikvs";
import * as v from "valibot";
const kvs = UniKvs.config({
schema: {
message: PlainValue(v.pipe(v.string(), v.minLength(1))),
logs: StreamValue(v.instance(Uint8Array)),
},
})
.appendStorage(storage)
.create();
await kvs.set("message", "hello");
const msg = await kvs.get("message");
// msg は string 型になりますキースキーマと値スキーマの組を並べます。動的キーに使います。最初に一致した定義を採用します。
import { PlainValue, StreamValue, UniKvs } from "unikvs";
import * as v from "valibot";
const kvs = UniKvs.config({
schema: [
[v.pipe(v.string(), v.regex(/^msg-.+/)), PlainValue(v.string())],
[v.pipe(v.string(), v.regex(/^img-.+/)), StreamValue(v.instance(Uint8Array))],
],
})
.appendStorage(storage)
.create();
await kvs.set("msg-1", "hello");検証のタイミング
| 操作 | 検証内容 | 失敗時のエラー |
|---|---|---|
set |
入力値を検証します。 | InvalidInputError |
get |
出力値を検証します。 | InvalidOutputError |
stream |
チャンクを 1 つずつ検証します。 | InvalidOutputError |
has・delete |
配列形式の場合のみ、キーを検証します。 | InvalidInputError |
実行時変数
変数は操作の挙動を切り替える実行時コンテキストです。ビルダーの setVariables() で初期値を設定し、操作ごとの vars で上書きできます。
const kvs = UniKvs.config<{ foo: Value<Uint8Array> }>()
.setVariables({ region: "ap-northeast-1" })
.appendStorage(storage)
.create();
await kvs.set("foo", new Uint8Array([1]), {
vars: { region: "us-east-1" },
});
プラグインの種類
| 種別 | パッケージ | 説明 |
|---|---|---|
| トランスフォーマー | @unikvs/compression |
gzip・deflate・deflate-raw による圧縮と展開を行います。 |
| トランスフォーマー | @unikvs/checksum |
MD5・SHA-1・SHA-224・SHA-256・SHA-384・SHA-512 の検証を行います。 |
| トランスフォーマー | @unikvs/debug |
読み書きされる操作とキーとデータのデバッグ情報をログに記録します。 |
| トランスフォーマー | @unikvs/passthrough |
データを何も変換せずそのまま透過させます。 |
| トランスフォーマー | @unikvs/json |
値を JSON に、ストリームでは JSON Lines に変換します。 |
| トランスフォーマー | @unikvs/superjson |
Date・Map・Set・BigInt・undefined を保持したまま SuperJSON で変換します。 |
| トランスフォーマー | @unikvs/cbor |
値を CBOR に、ストリームでは CBOR シーケンスに変換します。 |
| ストレージ | @unikvs/memory |
メモリー上に保存します。すべての環境に対応します。 |
| ストレージ | @unikvs/fs.node |
ローカルファイルシステムに保存します。Node.js 専用です。 |
| ストレージ | @unikvs/fs.bun |
ローカルファイルシステムに保存します。Bun 専用です。 |
| ストレージ | @unikvs/redis.bun |
Redis に保存します。Bun 専用です。 |
| ストレージ | @unikvs/s3.node |
S3 互換のオブジェクトストレージに保存します。Node.js 専用です。 |
| ストレージ | @unikvs/s3.bun |
S3 互換のオブジェクトストレージに保存します。Bun 専用です。 |
| ストレージ | @unikvs/indexeddb |
ブラウザーの IndexedDB に保存します。 |
| ストレージ | @unikvs/opfs |
ブラウザーの OPFS に保存します。 |
| ストレージ | @unikvs/writeonly |
既存のストレージを書き込み専用にします。 |