formatting and comments

This commit is contained in:
2026-07-16 00:12:26 -07:00
parent edb6d2b5b4
commit 994854d104
45 changed files with 2514 additions and 628 deletions
+58
View File
@@ -0,0 +1,58 @@
# 组件开发指南
组件是“一个直播源上的独立功能实例”。当前内建
`danmaku_overlay`,未来礼物墙、点歌姬或统计组件都应使用同一套契约。
## 一个组件由什么组成
| 部分 | Rust 契约 | 职责 |
| -------- | --------------------- | ------------------------------------------------- |
| 定义 | `ComponentDefinition` | kind、设置版本、默认值、校验、迁移、订阅 |
| 投影 | `EventProjection` | 把 `LiveEvent` 转成浏览器消息,不执行持久化副作用 |
| Handler | `EventHandler` | 可选的数据库写入、点歌或外部动作 |
| 实例 | `ComponentInstance` | owner、source、kind、名称、设置和启用状态 |
| 实时通道 | `EventHub` | 按 component ID 隔离的有界广播 |
| 前端 | React renderer/editor | 管理设置、测试与 OBS 展示 |
## 新增组件步骤
1. 选择稳定、全小写的 kind,例如 `gift_wall` 或 `song_request`。
2. 为设置定义可序列化结构,提供安全默认值和 `sanitize`/校验逻辑。
3. 实现 `ComponentDefinition`:
- `settings_version` 从 `1` 开始。
- `migrate_settings` 必须能把已保存的旧版本升级到当前版本。
- `subscriptions` 只返回当前设置需要的 `LiveEventKind`。
4. 实现无副作用的 `EventProjection`。返回 `None` 表示该事件无需发送浏览器。
5. 若需要可靠业务动作,实现 `EventHandler`:
- 即使没有 OBS 客户端也会执行。
- 数据库操作必须包含 owner/source/component 条件。
- 上游可能重试或出现组合事件,因此 handler 自己负责幂等。
6. 在 `ComponentRegistry::with_builtin_components` 注册定义与投影,再注册 handler。
7. 增加数据库创建/设置 API;不要把组件专属关系数据无限塞入 JSON settings。
8. 在控制台增加设置编辑器,在 OBS 前端增加对应事件渲染器。
9. 增加以下测试:设置边界、版本迁移、订阅、跨租户拒绝、handler 幂等、投影 wire shape 和 OBS 渲染。
## Projection 与 Handler 的边界
Projection 面向“现在打开的浏览器”。消息丢失或没有接收者都属于正常情况。它必须快速、确定、无副作用。
Handler 面向“业务事实”。例如点歌请求、礼物累计或审计写入必须在这里完成,而不是等待前端收到 WebSocket。一个 handler 失败会记录在
`RouteReport`,但不会阻止其他 handler 或 OBS 投影。
## 设置版本规则
- 数据库同时保存 `settings` 与 `settings_version`。
- 每次读取或路由前,通过 registry 迁移并校验设置。
- 新字段应提供默认值,删除/改义字段必须增加版本并编写迁移。
- 客户端输入只能作为待校验 JSON;后端返回的 sanitized 设置才是权威值。
- UI slider 的范围不能代替后端范围检查。
## 租户与 token 规则
- 组件必须属于同一个 owner 与 source。
- 路由和数据库查询都要重复检查这一关系。
- 每个组件单独签发 access token,默认只有 `events:subscribe`。
- 删除组件或轮换 token 时,关闭该组件 channel,使已有 socket 立即失效。
- 组件 WebSocket 不得暴露其他组件列表或控制 API。
当前组件的具体行为见 [`danmaku-overlay.md`](danmaku-overlay.md)。