# API設計書

## 概要

本ドキュメントは、Avalonia UIフレームワークのRemote Protocol APIについて記述します。Avaloniaは.NET向けのクロスプラットフォームUIフレームワークであり、従来のHTTP REST APIではなく、デザイナープレビュー機能のためのリモート通信プロトコルを提供しています。

本APIは以下の2つの通信方式をサポートします：

1. **BSON/TCP Protocol** - バイナリ形式でのTCP通信（主にIDEとの連携用）
2. **WebSocket/HTTP Protocol** - ブラウザベースのプレビュー用

## 共通仕様

### ベースURL

```
# BSON/TCP Transport
tcp://{host}:{port}/

# WebSocket/HTTP Transport
http://{host}:{port}/
ws://{host}:{port}/ws
```

### 認証方式

WebSocket接続時にはセキュリティCookie（GUID形式）による認証が必要です。接続確立後、最初のメッセージとしてセキュリティCookieを送信する必要があります。

### 共通ヘッダー

| ヘッダー名 | 必須 | 説明 |
| --- | --- | --- |
| Origin | ○ | WebSocket接続時のオリジン検証用（listenUri または vscode-webview: で始まる値） |
| Content-Type | - | HTTPリソース取得時: application/octet-stream, text/html, text/javascript, text/css |

### 共通エラーレスポンス

| ステータスコード | 説明 |
| --- | --- |
| 404 | Not Found - リソース未検出（HTTPリソース要求時） |

### メッセージ識別

各メッセージタイプは一意のGUID（AvaloniaRemoteMessageGuid属性）で識別されます。

## API一覧

| カテゴリ | メッセージタイプ | 方向 | 説明 |
| --- | --- | --- | --- |
| Transport | HtmlTransportStartedMessage | Server->Client | HTMLトランスポート開始通知 |
| Designer | UpdateXamlMessage | Client->Server | XAML更新リクエスト |
| Designer | UpdateXamlResultMessage | Server->Client | XAML更新結果 |
| Designer | StartDesignerSessionMessage | Client->Server | デザイナーセッション開始 |
| Viewport | MeasureViewportMessage | Client->Server | ビューポート測定リクエスト |
| Viewport | ClientViewportAllocatedMessage | Client->Server | クライアントビューポート割り当て通知 |
| Viewport | RequestViewportResizeMessage | Server->Client | ビューポートリサイズ要求 |
| Viewport | ClientSupportedPixelFormatsMessage | Client->Server | サポートするピクセルフォーマット通知 |
| Viewport | ClientRenderInfoMessage | Client->Server | クライアントレンダリング情報 |
| Viewport | FrameMessage | Server->Client | フレームデータ送信 |
| Viewport | FrameReceivedMessage | Client->Server | フレーム受信確認 |
| Input | PointerMovedEventMessage | Client->Server | ポインター移動イベント |
| Input | PointerPressedEventMessage | Client->Server | ポインター押下イベント |
| Input | PointerReleasedEventMessage | Client->Server | ポインター解放イベント |
| Input | ScrollEventMessage | Client->Server | スクロールイベント |
| Input | KeyEventMessage | Client->Server | キーイベント |
| Input | TextInputEventMessage | Client->Server | テキスト入力イベント |

## 各APIエンドポイント定義

### Transport

#### 1. HtmlTransportStartedMessage

HTMLベースのWebSocketトランスポートが開始されたことを通知します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `53778004-78fa-4381-8ec3-176a6f2328b6` |
| 方向 | Server -> Client |
| 通信方式 | BSON/TCP |

**メッセージボディ**

```json
{
  "Uri": "http://127.0.0.1:5000/"
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Uri | string | ○ | HTMLトランスポートのアクセスURI |

---

### Designer

#### 2. UpdateXamlMessage

XAMLコンテンツの更新をリクエストします。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `9AEC9A2E-6315-4066-B4BA-E9A9EFD0F8CC` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP |

**メッセージボディ**

```json
{
  "Xaml": "<Window xmlns=\"...\">...</Window>",
  "AssemblyPath": "/path/to/assembly.dll",
  "XamlFileProjectPath": "Views/MainWindow.axaml"
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Xaml | string | ○ | XAMLコンテンツ |
| AssemblyPath | string | ○ | アセンブリファイルパス |
| XamlFileProjectPath | string | ○ | プロジェクト内のXAMLファイルパス |

---

#### 3. UpdateXamlResultMessage

XAML更新の結果を返します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `B7A70093-0C5D-47FD-9261-22086D43A2E2` |
| 方向 | Server -> Client |
| 通信方式 | BSON/TCP |

**メッセージボディ（成功時）**

```json
{
  "Error": null,
  "Handle": "window-handle-id",
  "Exception": null
}
```

**メッセージボディ（エラー時）**

```json
{
  "Error": "Parsing error occurred",
  "Handle": null,
  "Exception": {
    "ExceptionType": "XmlException",
    "Message": "Invalid XML syntax",
    "LineNumber": 10,
    "LinePosition": 5
  }
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Error | string | - | エラーメッセージ（成功時はnull） |
| Handle | string | - | ウィンドウハンドル識別子 |
| Exception | ExceptionDetails | - | 例外詳細情報 |

**ExceptionDetails構造**

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| ExceptionType | string | ○ | 例外の型名 |
| Message | string | ○ | 例外メッセージ |
| LineNumber | int? | - | エラー行番号（XMLExceptionの場合） |
| LinePosition | int? | - | エラー列位置（XMLExceptionの場合） |

---

#### 4. StartDesignerSessionMessage

デザイナーセッションを開始します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `854887CF-2694-4EB6-B499-7461B6FB96C7` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP |

**メッセージボディ**

```json
{
  "SessionId": "unique-session-id"
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| SessionId | string | ○ | セッション識別子 |

---

### Viewport

#### 5. MeasureViewportMessage

ビューポートの測定をリクエストします。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `6E3C5310-E2B1-4C3D-8688-01183AA48C5B` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP, WebSocket |

**メッセージボディ**

```json
{
  "Width": 800.0,
  "Height": 600.0
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Width | double | ○ | ビューポート幅 |
| Height | double | ○ | ビューポート高さ |

---

#### 6. ClientViewportAllocatedMessage

クライアント側でビューポートが割り当てられたことを通知します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `BD7A8DE6-3DB8-4C13-8583-D6D4AB189A31` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP, WebSocket |

**メッセージボディ**

```json
{
  "Width": 800.0,
  "Height": 600.0,
  "DpiX": 96.0,
  "DpiY": 96.0
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Width | double | ○ | ビューポート幅 |
| Height | double | ○ | ビューポート高さ |
| DpiX | double | ○ | 水平DPI |
| DpiY | double | ○ | 垂直DPI |

---

#### 7. RequestViewportResizeMessage

ビューポートのリサイズを要求します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `9B47B3D8-61DF-4C38-ACD4-8C1BB72554AC` |
| 方向 | Server -> Client |
| 通信方式 | BSON/TCP |

**メッセージボディ**

```json
{
  "Width": 1024.0,
  "Height": 768.0
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Width | double | ○ | 要求幅 |
| Height | double | ○ | 要求高さ |

---

#### 8. ClientSupportedPixelFormatsMessage

クライアントがサポートするピクセルフォーマットを通知します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `63481025-7016-43FE-BADC-F2FD0F88609E` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP, WebSocket |

**メッセージボディ**

```json
{
  "Formats": ["Rgba8888", "Bgra8888"]
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Formats | PixelFormat[] | ○ | サポートするピクセルフォーマットの配列 |

**PixelFormat列挙値**

| 値 | 説明 |
| --- | --- |
| Rgb565 | 16ビットRGB |
| Rgba8888 | 32ビットRGBA |
| Bgra8888 | 32ビットBGRA |

---

#### 9. ClientRenderInfoMessage

クライアントのレンダリング情報を通知します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `7A3c25d3-3652-438D-8EF1-86E942CC96C0` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP, WebSocket |

**メッセージボディ**

```json
{
  "DpiX": 96.0,
  "DpiY": 96.0
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| DpiX | double | ○ | 水平DPI |
| DpiY | double | ○ | 垂直DPI |

---

#### 10. FrameMessage

レンダリングされたフレームデータを送信します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `F58313EE-FE69-4536-819D-F52EDF201A0E` |
| 方向 | Server -> Client |
| 通信方式 | BSON/TCP, WebSocket |

**メッセージボディ（BSON）**

```json
{
  "SequenceId": 12345,
  "Format": "Rgba8888",
  "Data": "<binary-data>",
  "Width": 800,
  "Height": 600,
  "Stride": 3200,
  "DpiX": 96.0,
  "DpiY": 96.0
}
```

**WebSocket形式**

テキストメッセージ: `frame:{sequenceId}:{width}:{height}:{stride}:{dpiX}:{dpiY}`

続くバイナリメッセージ: ピクセルデータ（ArrayBuffer）

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| SequenceId | long | ○ | フレームシーケンス番号 |
| Format | PixelFormat | ○ | ピクセルフォーマット |
| Data | byte[] | ○ | ピクセルデータ |
| Width | int | ○ | 画像幅（ピクセル） |
| Height | int | ○ | 画像高さ（ピクセル） |
| Stride | int | ○ | 行あたりのバイト数 |
| DpiX | double | ○ | 水平DPI |
| DpiY | double | ○ | 垂直DPI |

---

#### 11. FrameReceivedMessage

フレームの受信確認を送信します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `68014F8A-289D-4851-8D34-5367EDA7F827` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP, WebSocket |

**メッセージボディ（BSON）**

```json
{
  "SequenceId": 12345
}
```

**WebSocket形式**

テキストメッセージ: `frame-received:{sequenceId}`

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| SequenceId | long | ○ | 受信したフレームのシーケンス番号 |

---

### Input

#### 12. PointerMovedEventMessage

ポインター（マウス）の移動イベントを送信します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `6228F0B9-99F2-4F62-A621-414DA2881648` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP, WebSocket |

**メッセージボディ（BSON）**

```json
{
  "Modifiers": ["Control", "Shift"],
  "X": 150.5,
  "Y": 200.0
}
```

**WebSocket形式**

テキストメッセージ: `pointer-moved:{modifiers}:{x}:{y}`

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Modifiers | InputModifiers[] | - | 入力修飾キー |
| X | double | ○ | X座標 |
| Y | double | ○ | Y座標 |

---

#### 13. PointerPressedEventMessage

ポインター（マウス）の押下イベントを送信します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `7E9E2818-F93F-411A-800E-6B1AEB11DA46` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP, WebSocket |

**メッセージボディ（BSON）**

```json
{
  "Modifiers": ["Control"],
  "X": 150.5,
  "Y": 200.0,
  "Button": "Left"
}
```

**WebSocket形式**

テキストメッセージ: `pointer-pressed:{modifiers}:{x}:{y}:{button}`

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Modifiers | InputModifiers[] | - | 入力修飾キー |
| X | double | ○ | X座標 |
| Y | double | ○ | Y座標 |
| Button | MouseButton | ○ | 押されたマウスボタン |

---

#### 14. PointerReleasedEventMessage

ポインター（マウス）の解放イベントを送信します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `4ADC84EE-E7C8-4BCF-986C-DE3A2F78EDE4` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP, WebSocket |

**メッセージボディ（BSON）**

```json
{
  "Modifiers": [],
  "X": 150.5,
  "Y": 200.0,
  "Button": "Left"
}
```

**WebSocket形式**

テキストメッセージ: `pointer-released:{modifiers}:{x}:{y}:{button}`

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Modifiers | InputModifiers[] | - | 入力修飾キー |
| X | double | ○ | X座標 |
| Y | double | ○ | Y座標 |
| Button | MouseButton | ○ | 解放されたマウスボタン |

---

#### 15. ScrollEventMessage

スクロールイベントを送信します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `79301A05-F02D-4B90-BB39-472563B504AE` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP, WebSocket |

**メッセージボディ（BSON）**

```json
{
  "Modifiers": [],
  "X": 150.5,
  "Y": 200.0,
  "DeltaX": 0.0,
  "DeltaY": -120.0
}
```

**WebSocket形式**

テキストメッセージ: `scroll:{modifiers}:{x}:{y}:{deltaX}:{deltaY}`

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Modifiers | InputModifiers[] | - | 入力修飾キー |
| X | double | ○ | X座標 |
| Y | double | ○ | Y座標 |
| DeltaX | double | ○ | 水平スクロール量 |
| DeltaY | double | ○ | 垂直スクロール量 |

---

#### 16. KeyEventMessage

キーボードイベントを送信します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `1C3B691E-3D54-4237-BFB0-9FEA83BC1DB8` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP |

**メッセージボディ**

```json
{
  "Modifiers": ["Control"],
  "IsDown": true,
  "Key": "A",
  "PhysicalKey": "KeyA",
  "KeySymbol": "a"
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Modifiers | InputModifiers[] | - | 入力修飾キー |
| IsDown | bool | ○ | キー押下状態（true: 押下, false: 解放） |
| Key | Key | ○ | 論理キーコード |
| PhysicalKey | PhysicalKey | ○ | 物理キーコード |
| KeySymbol | string | - | キーシンボル文字 |

---

#### 17. TextInputEventMessage

テキスト入力イベントを送信します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| メッセージGUID | `C174102E-7405-4594-916F-B10B8248A17D` |
| 方向 | Client -> Server |
| 通信方式 | BSON/TCP |

**メッセージボディ**

```json
{
  "Modifiers": [],
  "Text": "Hello"
}
```

| フィールド名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| Modifiers | InputModifiers[] | - | 入力修飾キー |
| Text | string | ○ | 入力テキスト |

---

### 共通型定義

#### InputModifiers列挙型

| 値 | 説明 |
| --- | --- |
| Alt | Altキー |
| Control | Ctrlキー |
| Shift | Shiftキー |
| Windows | Windowsキー/Commandキー |
| LeftMouseButton | 左マウスボタン |
| RightMouseButton | 右マウスボタン |
| MiddleMouseButton | 中央マウスボタン |

#### MouseButton列挙型

| 値 | 説明 |
| --- | --- |
| None | なし |
| Left | 左ボタン |
| Right | 右ボタン |
| Middle | 中央ボタン |

---

## 備考

### 通信プロトコルの選択

- **BSON/TCP Transport**: Visual StudioやJetBrains Rider等のIDEとの統合に使用。バイナリ形式で効率的な通信が可能
- **WebSocket/HTTP Transport**: ブラウザベースのプレビューやVS Code拡張機能との統合に使用。HTMLページとしてプレビューUIを提供

### セキュリティ

WebSocket接続時はセキュリティCookie（GUID）による認証が必須です。また、Originヘッダーによる接続元の検証も行われます。

### フレーム同期

FrameMessageとFrameReceivedMessageによるシーケンス番号ベースのフレーム同期メカニズムにより、フレームの欠落や重複を防止します。
