Files
nyaterm/docs-site/docs/development/architecture.md
T
Kang b0a8d66695 chore: update references from gpui-component to gpui-kit
- Replaced all instances of `gpui-component` with `gpui-kit` across various files to reflect the new naming convention.
- Updated Cargo.toml and documentation to ensure consistency in dependency management and integration boundaries.
- Adjusted comments and code references to align with the new structure, enhancing clarity and maintainability.
2026-09-22 00:00:58 +08:00

119 lines
6.5 KiB
Markdown

# 架构说明
NyaTerm 是一个基于 **GPUI** 构建的原生 Rust 桌面应用。应用界面、终端模拟、连接传输和持久化均位于同一个 Cargo workspace 中,不依赖浏览器运行时或 IPC 桥接层。
## 整体分层
```text
nyaterm-app
└─ 启动 GPUI、注册资源、创建根窗口
└─ nyaterm-desktop
├─ AppShell / NyaTermApp / feature state / views
├─ nyaterm-ui 共享 GPUI 控件和主题
├─ nyaterm-terminal-gpui 终端布局、输入和绘制
├─ nyaterm-terminal 终端状态机、解析和快照
├─ nyaterm-transport PTY、SSH、SFTP 和其他协议
├─ nyaterm-remote-desktop RDP/VNC 会话管理与 helper IPC 合约
├─ nyaterm-store redb、事务和兼容性读取
└─ nyaterm-core 纯模型、格式和策略
独立进程(通过 IPC 通信,不被应用链接)
├─ nyaterm-rdp-helper IronRDP 解码
└─ nyaterm-vnc-helper vnc-rs 解码
```
各 crate 的主要职责如下:
| Crate | 职责 |
|------|------|
| `nyaterm-app` | 可执行入口、日志、嵌入资源和根窗口创建 |
| `nyaterm-desktop` | GPUI 应用组合、状态、视图、平台适配和后台任务协调 |
| `nyaterm-ui` | 共享控件、主题 token 和 `gpui-kit` 集成边界 |
| `nyaterm-terminal` | 与 UI 无关的终端状态机、控制序列、编码和图形协议 |
| `nyaterm-terminal-gpui` | GPUI 终端输入、布局、选区、高亮、图片和绘制 |
| `nyaterm-transport` | PTY、SSH、Telnet、串口、SFTP、隧道、远程操作和传输协议 |
| `nyaterm-store` | redb 数据库、事务、加密适配和兼容性读取 |
| `nyaterm-core` | 领域模型、兼容格式、解析、策略及纯逻辑 |
| `nyaterm-remote-desktop` | 与 UI 无关的 RDP/VNC 会话管理、framebuffer 与输入模型、证书策略、剪贴板状态和 helper IPC 合约 |
| `nyaterm-rdp-helper` | 隔离的 IronRDP helper 进程 |
| `nyaterm-vnc-helper` | 隔离的 VNC helper 进程,持有 fork 的 `vnc-rs` 解码器、重连梯度和服务端策略门控 |
| `nyaterm-otp` | HOTP/TOTP 兼容实现 |
## 启动流程
`crates/nyaterm-app/src/main.rs` 是应用入口:
1. 解析运行目录并初始化日志。
2. 向 GPUI 注册嵌入资源和共享组件。
3. 创建原生根窗口和 `AppShell` Entity。
4. `AppShell` 启动 `StoreRuntime`,异步加载启动快照。
5. 数据验证成功后创建 `NyaTermApp`,再恢复窗口布局和会话。
`AppShell` 还负责加载、恢复、退出前 flush 等应用级生命周期。数据库启动失败时会进入恢复界面,而不是用未验证的数据继续创建主应用状态。
## 状态所有权
`NyaTermApp` 是 GPUI 组合中心,但主要 UI 域由 focused feature state 管理,例如连接、会话、终端、传输、设置、安全、AI、同步和远程操作。
每份状态只有一个可写 owner。当前独立 Entity store 只拥有 `NyaTermApp` 不拥有的状态:
- `StartupRestoreStore`:启动恢复队列
- `OverlayStore`:快速切换 overlay
视图直接读取权威状态构造 GPUI element。不要建立同帧 publish/read-back 的只读镜像,也不要在 feature state 和 Entity 中同时保存可变副本。
## 后台任务与事件
文件系统、数据库、网络、SSH、SFTP、子进程和图片解码等阻塞工作不在 render 路径中执行。
后台任务通过有类型的结果或事件返回 GPUI 状态层。例如会话运行时使用 `nyaterm_transport::SessionEvent` 传递输出、工作目录变化、命令确认、退出和错误;桌面层在窗口运行时 pump 中消费事件、更新 feature state 并通知 GPUI 重绘。
## 终端数据流
```text
PTY / SSH / Telnet / Serial
│
▼
nyaterm-transport typed events
│
▼
nyaterm-desktop event drain and session state
│
▼
nyaterm-terminal state machine and snapshots
│
▼
nyaterm-terminal-gpui layout, input and painting
```
`nyaterm-terminal` 使用 Alacritty 的终端组件维护网格和控制序列状态,同时负责搜索、编码、Kitty graphics 和 Sixel 等与 UI 无关的逻辑。GPUI 尺寸计算、键盘适配、选区、高亮、图片及逐帧绘制均留在 `nyaterm-terminal-gpui`。
## 持久化与兼容性
`nyaterm-store` 通过专用 `StoreRuntime` 执行数据库工作,桌面层使用 UI client 或 blocking client 提交有类型的请求。GPUI 视图不直接访问 redb。
配置模型、备份格式、云同步文档和加密策略等 schema-neutral 合约位于 `nyaterm-core`。数据库实现与旧数据读取位于 `nyaterm-store`。现有 table 名、key、字段名、加密前缀、`.nya` 备份和 Dragonfly fallback 都属于兼容性边界。
## RDP / VNC 的进程隔离
RDP 和 VNC 的协议解码器解析的是**服务器控制的字节流**,因此它们不在应用链接的任何 crate 里,而是各自跑在独立的 helper 进程中,通过 `nyaterm-remote-desktop` 里的类型化 IPC 协议与应用通信。
这条边界的含义:
- 解码器崩溃不会带走应用。两个 helper 都必须把解码器 panic 转换成一个致命 IPC 错误上报,而不是静默退出
- `nyaterm-remote-desktop` 自己不含任何解码器。它只负责会话管理、framebuffer 与输入模型、证书策略和剪贴板状态
- VNC 的服务端策略门控(`view_only`、`shared`、剪贴板启用)必须在 helper 里强制执行,而不是只在应用侧判断
- 应用在自己的可执行文件旁边解析 helper 路径,`NYATERM_RDP_HELPER` / `NYATERM_VNC_HELPER` 可覆盖
两个 helper crate 各自带一个 `tests/lifecycle.rs`,覆盖握手、正常断开和崩溃 / 挂起回收。IPC 合约变更时必须同步更新两边。
## 依赖规则
- `nyaterm-core`、`nyaterm-terminal`、`nyaterm-transport` 和 `nyaterm-remote-desktop` 不依赖 GPUI。
- 解析服务器控制字节的协议解码器只放在 helper crate 里,不放进应用链接的 crate。
- 桌面功能通过 `nyaterm-ui` 使用普通输入、选择、菜单、开关和对话框。
- 模块使用正常 Rust module tree 和显式 import。
- 新功能优先放入已有 focused feature state;只有需要独立生命周期时才新增权威 Entity。
更具体的界面层规则见 [GPUI 桌面开发](./frontend),运行时与持久化规则见 [运行时、传输与存储开发](./backend)。