---
title: "パイプラインコンテキスト"
description: "@unikvs/core のパイプラインコンテキスト。IPipelineContext による実行時変数の読み書きと操作ごとのコンテキスト一覧を説明します。"
---

## 概要 [#overview]

パイプラインコンテキストは操作ごとに受け渡される実行時変数 (`vars`) を読み書きする窓口です。すべてのコンテキストが `IPipelineContext` を継承し、操作の種類ごとに `key`・`signal`・`source` などの情報が追加されます。

プラグイン作者はフックの引数として渡されるコンテキストからキーやシグナルを取り出し、`vars` から動作設定を読み取ります。

## 変数の読み書き [#variables]

`get`・`set`・`setReadonly` の 3 メソッドで変数を扱います。`set` 系は `this` を返すため、メソッドチェーンできます。

```ts
import type { IPipelineContext } from "@unikvs/core";

declare const ctx: IPipelineContext<{ readonly count: number }>;

const count: number = ctx.get("count"); // 型付きで取得
const unknownValue: unknown = ctx.get("anything-else"); // 未登録のキーは unknown

ctx.set("count", 1).setReadonly("count", 2); // this を返すため連鎖できる
```

型引数で `{ count: number }` のように宣言すると、そのキーの取得と設定が型付けされます。宣言にないキーは `unknown` として扱われ、誤った型の代入は型エラーになります。

```ts
// @ts-expect-error count は number のため文字列は渡せない
ctx.set("count", "not a number");
```

### 宣言マージ [#variables-merging]

グローバルな `UniKvsPipelineContextTypes` への宣言マージでも型を足せます。複数のプラグインが共有する変数名を一箇所で定義するときに使います。

```ts
declare global {
  interface UniKvsPipelineContextTypes {
    readonly "test:count": number;
  }
}

declare const ctx: IPipelineContext;

const count: number = ctx.get("test:count");
ctx.set("test:count", 1); // 文字列の代入は型エラー
```

型引数の宣言と `UniKvsPipelineContextTypes` の宣言マージは結合され、どちらかにあるキーは型付きで解決されます。どちらにもないキーは `unknown` です。

:::warning[読み取り専用に注意]
`setReadonly()` で固定した変数への書き込みは [`ReadonlyVariableError`](/unikvs/packages/core/errors#error-readonly-variable) を投げます。プラグイン内部の既定値など、呼び出し側に上書きされたくない値に使います。
:::

## コンテキストの階層 [#hierarchy]

コンテキストは層状に継承されます。下の層ほど操作が特定され、持つ情報が増えます。

```mermaid
flowchart TB
  A[IPipelineContext] --> B[IMapKeyContext]
  A --> C[IActionContext]
  C --> D[ILifecycleContext]
  C --> E[IKeyedActionContext]
  D --> F[IOpenContext]
  D --> G[ICloseContext]
  E --> H[ISetContext]
  E --> I[IGetContext]
  E --> J[IStreamContext]
  E --> K[IHasContext]
  E --> L[IDeleteContext]
  E --> U[ITransferContext]
  U --> V[ICopyContext]
  U --> W[IMoveContext]
  C --> M[IClearContext]
  E --> N[ITransformContext]
  N --> O[ITransformDataContext]
  N --> P[ITransformStreamContext]
  O --> Q[IEncodeContext]
  O --> R[IDecodeContext]
  P --> S[IEncodeStreamContext]
  P --> T[IDecodeStreamContext]
```

## コンテキストの一覧 [#contexts]

操作の種類ごとに含まれる情報が決まっています。

| 型                                              | `action`            | 主な追加プロパティー                                |
| ----------------------------------------------- | ------------------- | --------------------------------------------------- |
| [`IMapKeyContext`](#imapkeycontext)             | —                   | `key: string`                                       |
| [`IActionContext`](#iactioncontext)             | 10 種の操作         | `signal: AbortSignal`                               |
| [`ILifecycleContext`](#ilifecyclecontext)       | `"open" \| "close"` | `signal`                                            |
| [`IOpenContext`](#iopencontext)                 | `"open"`            | `signal`                                            |
| [`ICloseContext`](#iclosecontext)               | `"close"`           | `signal`                                            |
| [`IKeyedActionContext`](#ikeyedactioncontext)   | 7 種のキー操作      | `key`・`signal`                                     |
| [`ISetContext`](#isetcontext)                   | `"set"`             | `key`・`signal`                                     |
| [`IGetContext`](#igetcontext)                   | `"get"`             | `key`・`signal`・`repair`                           |
| [`IStreamContext`](#istreamcontext)             | `"stream"`          | `key`・`signal`・`repair`                           |
| [`IHasContext`](#ihascontext)                   | `"has"`             | `key`・`signal`                                     |
| [`IDeleteContext`](#ideletecontext)             | `"delete"`          | `key`・`signal`                                     |
| [`ITransferContext`](#itransfercontext)         | `"copy" \| "move"`  | `key`・`destinationKey`・`signal`                   |
| [`ICopyContext`](#icopycontext)                 | `"copy"`            | `key`・`destinationKey`・`signal`                   |
| [`IMoveContext`](#imovecontext)                 | `"move"`            | `key`・`destinationKey`・`signal`                   |
| [`IClearContext`](#iclearcontext)               | `"clear"`           | `signal`                                            |
| [`IEncodeContext`](#iencodecontext)             | `"set"`             | `source`・`destination?` (データ変換用)             |
| [`IDecodeContext`](#idecodecontext)             | `"get"`             | `source`・`destination?` (データ変換用)             |
| [`IEncodeStreamContext`](#iencodestreamcontext) | `"set"`             | `source`・`destination?` (`IReadableStream` 変換用) |
| [`IDecodeStreamContext`](#idecodestreamcontext) | `"stream"`          | `source`・`destination?` (`IReadableStream` 変換用) |

### キーとライフサイクル [#contexts-key-lifecycle]

`IMapKeyContext` はキー変換専用で `key` のみを持ちます ([ミドルウェアの `mapKey`](/unikvs/packages/core/middleware#hooks) で使います)。`signal` は持ちません。

`IActionContext` は `signal: AbortSignal` と 10 種の `action` (`"open" | "close" | "set" | "get" | "stream" | "has" | "delete" | "clear" | "copy" | "move"`) を持ちます。`ILifecycleContext` は `"open" | "close"` に絞られ、`IOpenContext`・`ICloseContext` はそれぞれ 1 種に絞られます。

### キー操作 [#contexts-keyed]

`IKeyedActionContext` は `key: string` を加え、`action` を `"set" | "get" | "stream" | "has" | "delete" | "copy" | "move"` の 7 種に絞ります。以降の `ISetContext`・`IGetContext`・`IStreamContext`・`IHasContext`・`IDeleteContext` は `action` を 1 種に固定します。`ITransferContext` は `action` を `"copy" | "move"` に絞り、コピー先・移動先の `destinationKey` を加えます。`ICopyContext` と `IMoveContext` はそれぞれ `action` を `"copy"`・`"move"` に固定します。`IClearContext` はキーを伴わないため `IKeyedActionContext` ではなく `IActionContext` を直接継承し、`action` は `"clear"` です。

ミドルウェアの `use` フックはこれら 8 種 (`set`・`get`・`stream`・`has`・`delete`・`copy`・`move`・`clear`) をまとめて受けます。`action` で絞り込むと、各操作の `key` や `repair`、`destinationKey` に型安全に触れます。

```ts
import type { IMiddleware } from "@unikvs/core";

export function describe(use: IMiddleware.UseContext): string {
  switch (use.action) {
    case "set":
    case "get":
    case "stream":
    case "has":
    case "delete":
    case "copy":
    case "move": {
      return `${use.action}: ${use.key}`;
    }
    case "clear": {
      return "clear";
    }
  }
}
```

### 変換 [#contexts-transform]

`ITransformContext` は変換前後の値を運びます。`source` が入力で、`destination` (任意) に変換結果を代入します。

| 型                     | `action`   | `source`                          | `destination`              |
| ---------------------- | ---------- | --------------------------------- | -------------------------- |
| `IEncodeContext`       | `"set"`    | 生データ                          | エンコード後               |
| `IDecodeContext`       | `"get"`    | 保存値                            | デコード後                 |
| `IEncodeStreamContext` | `"set"`    | 読み取りストリーム (生チャンク)   | 変換後の読み取りストリーム |
| `IDecodeStreamContext` | `"stream"` | 読み取りストリーム (保存チャンク) | 変換後の読み取りストリーム |

データ変換 (`ITransformDataContext` 系) の `source` と `destination` は値そのものです。一方、ストリーム変換 (`ITransformStreamContext` 系) の `source` と `destination` は `IReadableStream` です。値かチャンクかを型引数で確認します。詳しくは[ストリーム](/unikvs/packages/core/stream#transform)を参照してください。

## 書き戻し [#repair]

`IGetContext` と `IStreamContext` は読み取り時の書き戻し (`repair`) 要求を持ちます。後段のストレージで見つかった値を前段へ書き戻すかどうかが入ります。

```ts
import type { IGetContext } from "@unikvs/core";

declare const ctx: IGetContext;

if (ctx.repair.enabled) {
  console.log(ctx.repair.targets); // readonly [string, ...string[]] (1 件以上)
} else {
  console.log(ctx.repair.targets); // readonly [] (空)
}
```

`enabled` が `false` のとき `targets` は空配列、`true` のとき 1 件以上の表示名の配列です。`enabled` で絞り込むと `targets` の中身に型安全に触れます。書き戻しが拒否された場合は [`RepairNotAllowedError`](/unikvs/packages/core/errors#error-repair-not-allowed) が使われます。可否は [`@unikvs/allow-repair`](/unikvs/packages/allow-repair) で制御します。

## API リファレンス [#api]

シンボルごとのリファレンスです。各メンバーの行にも直接リンクできます。

### `IPipelineContext` [#ipipelinecontext]

実行時変数 (`vars`) を読み書きする窓口です。すべてのコンテキストが継承します。

| Prop | Type | Default | Description |
| - | - | - | - |
| `get` | `[#ipipelinecontext-get] get<const TName extends ParamName<TTypes>>(name: TName): ParamValue<TTypes, TName>` | - | 変数を取得します。 |
| `set` | `[#ipipelinecontext-set] set<const TName extends ParamName<TTypes>>(name: TName, value: ParamValue<TTypes, TName>): this` | - | 変数を設定します。`this` を返します。 |
| `setReadonly` | `[#ipipelinecontext-setreadonly] setReadonly<const TName extends ParamName<TTypes>>(name: TName, value: ParamValue<TTypes, TName>): this` | - | 変数を読み取り専用で設定します。`this` を返します。 |

### `IMapKeyContext` [#imapkeycontext]

キー変換専用のコンテキストです。`key` のみを持ちます。

| Prop | Type | Default | Description |
| - | - | - | - |
| `key` | `[#imapkeycontext-key] string` | - | 変換対象のキーです。 |

### `IActionContext` [#iactioncontext]

`signal` と 10 種の `action` を持つ、すべての操作に共通するコンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `signal` | `[#iactioncontext-signal] AbortSignal` | - | 操作の中断信号です。 |
| `action` | `[#iactioncontext-action] "open" \| "close" \| "set" \| "get" \| "stream" \| "has" \| "delete" \| "clear" \| "copy" \| "move"` | - | 操作の種類です。 |

### `ILifecycleContext` [#ilifecyclecontext]

`action` を `"open" | "close"` に絞ったライフサイクル用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#ilifecyclecontext-action] "open" \| "close"` | - | 操作の種類です。 |

### `IOpenContext` [#iopencontext]

`action` を `"open"` に固定した初期化用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#iopencontext-action] "open"` | - | 操作の種類です。 |

### `ICloseContext` [#iclosecontext]

`action` を `"close"` に固定した終了処理用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#iclosecontext-action] "close"` | - | 操作の種類です。 |

### `IKeyedActionContext` [#ikeyedactioncontext]

`key` を加え、`action` をキー操作の 7 種に絞ったコンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#ikeyedactioncontext-action] "set" \| "get" \| "stream" \| "has" \| "delete" \| "copy" \| "move"` | - | 操作の種類です。 |
| `key` | `[#ikeyedactioncontext-key] string` | - | 操作対象のキーです。 |

### `ISetContext` [#isetcontext]

`action` を `"set"` に固定した書き込み用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#isetcontext-action] "set"` | - | 操作の種類です。 |

### `IGetContext` [#igetcontext]

`action` を `"get"` に固定した読み取り用コンテキストです。書き戻し (`repair`) 要求を持ちます。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#igetcontext-action] "get"` | - | 操作の種類です。 |

### `IStreamContext` [#istreamcontext]

`action` を `"stream"` に固定したストリーム読み取り用コンテキストです。書き戻し (`repair`) 要求を持ちます。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#istreamcontext-action] "stream"` | - | 操作の種類です。 |

### `IHasContext` [#ihascontext]

`action` を `"has"` に固定した存在確認用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#ihascontext-action] "has"` | - | 操作の種類です。 |

### `IDeleteContext` [#ideletecontext]

`action` を `"delete"` に固定した削除用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#ideletecontext-action] "delete"` | - | 操作の種類です。 |

### `ITransferContext` [#itransfercontext]

コピー・移動に共通するコンテキストです。`action` は `"copy" | "move"` で、`key` がコピー元・移動元、`destinationKey` がコピー先・移動先です。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#itransfercontext-action] "copy" \| "move"` | - | 操作の種類です。 |
| `key` | `[#itransfercontext-key] string` | - | コピー元または移動元のキーです。 |
| `destinationKey` | `[#itransfercontext-destination-key] string` | - | コピー先または移動先のキーです。 |

### `ICopyContext` [#icopycontext]

`action` を `"copy"` に固定したコピー用コンテキストです。`key` と `destinationKey` は [`ITransferContext`](#itransfercontext) から継承します。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#icopycontext-action] "copy"` | - | 操作の種類です。 |

### `IMoveContext` [#imovecontext]

`action` を `"move"` に固定した移動用コンテキストです。`key` と `destinationKey` は [`ITransferContext`](#itransfercontext) から継承します。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#imovecontext-action] "move"` | - | 操作の種類です。 |

### `IClearContext` [#iclearcontext]

`action` を `"clear"` に固定した全削除用コンテキストです。キーを伴いません。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#iclearcontext-action] "clear"` | - | 操作の種類です。 |

### `ITransformContext` [#itransformcontext]

変換前後の値を運ぶコンテキストです。`source` が入力で、`destination` に変換結果を代入します。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#itransformcontext-action] "set" \| "get" \| "stream"` | - | 操作の種類です。 |
| `source` | `[#itransformcontext-source] TSource` | - | 変換前の値です。 |
| `destination?` | `[#itransformcontext-destination] TDestination \| undefined` | - | 変換結果の代入先です。 |

### `ITransformDataContext` [#itransformdatacontext]

値そのものを変換するデータ変換用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#itransformdatacontext-action] "set" \| "get"` | - | 操作の種類です。 |

### `IEncodeContext` [#iencodecontext]

`action` を `"set"` に固定したエンコード用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#iencodecontext-action] "set"` | - | 操作の種類です。 |

### `IDecodeContext` [#idecodecontext]

`action` を `"get"` に固定したデコード用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#idecodecontext-action] "get"` | - | 操作の種類です。 |

### `ITransformStreamContext` [#itransformstreamcontext]

ストリームを変換するコンテキストです。`source` と `destination` は `IReadableStream` です。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#itransformstreamcontext-action] "set" \| "stream"` | - | 操作の種類です。 |

### `IEncodeStreamContext` [#iencodestreamcontext]

`action` を `"set"` に固定したストリームエンコード用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#iencodestreamcontext-action] "set"` | - | 操作の種類です。 |

### `IDecodeStreamContext` [#idecodestreamcontext]

`action` を `"stream"` に固定したストリームデコード用コンテキストです。

| Prop | Type | Default | Description |
| - | - | - | - |
| `action` | `[#idecodestreamcontext-action] "stream"` | - | 操作の種類です。 |
