@nnepoch/dtc-sdk 3.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,97 +1,44 @@
1
- # enginesdk3
1
+ # @nnepoch/dtc-sdk
2
2
 
3
- 基于 `@epicgames-ps/lib-pixelstreamingfrontend-ue5.6` 的 UE 前端 SDK。
4
-
5
- ## 📋 代码审查报告
6
-
7
- > **最新审查**: 2026-08-15 | **健康度**: C+ (65/100) | **问题数**: 184
8
-
9
- 查看完整报告:[docs/code-review/](./docs/code-review/)
10
-
11
- **关键发现**:
12
- - 🔴 6 个 Critical 问题需要立即处理
13
- - 🟠 49 个 High 优先级问题
14
- - ⚡ 5 个快速胜利(1.4 天可完成)
15
-
16
- **代码审查与重构记录**:
17
- - [总览、处理计划与完成情况](./docs/code-review/README.md)
18
- - [详细问题清单](./docs/code-review/CODE_REVIEW_ISSUES.md)
19
-
20
- **当前重构状态**:
21
- - ✅ EventBus 提取完成
22
- - ✅ ConnectionManager 提取完成
23
- - ✅ EngineBuilder 装配完成
24
- - ✅ DTCEngine 第一轮简化及生命周期回归修复完成
25
- - ✅ 聚焦测试、类型检查和生产源码 lint 通过
26
-
27
- ---
3
+ 面向 Unreal Engine 云渲染场景的前端 SDK,基于 Pixel Streaming 提供鉴权、WebRTC 连接和引擎 API 调用能力。
28
4
 
29
5
  ## 安装
30
6
 
31
7
  ```bash
32
- pnpm install
33
- ```
34
-
35
- ## 构建命令
36
-
37
- ```bash
38
- pnpm run clean # 清理 dist 和 API 文档
39
- pnpm run build # 构建 npm CJS/ESM、browser 压缩包和混淆包
40
- pnpm run build:lib # 仅构建 npm CJS/ESM bundle 与声明文件
41
- pnpm run build:browser # 仅构建 browser IIFE 压缩包和混淆包
42
- pnpm run verify:build # 验证入口加载、导出、声明文件和 sourcemap
43
- pnpm run typecheck # 仅执行 TypeScript 类型检查
44
- pnpm run rebuild # clean + build
45
- pnpm run build:release # rebuild + API 文档
46
- pnpm run watch # library 构建监听
47
- pnpm run dev:browser # browser 构建监听
48
- ```
49
-
50
- npm library 产物由 tsdown 统一生成:
51
-
52
- ```text
53
- dist/cjs/index.cjs
54
- dist/cjs/index.d.cts
55
- dist/esm/index.js
56
- dist/esm/index.d.ts
8
+ npm install @nnepoch/dtc-sdk
57
9
  ```
58
10
 
59
- 浏览器产物由 tsdown 生成 IIFE,再由 `javascript-obfuscator` 就地替换为混淆版本:
60
-
61
- ```text
62
- dist/browser/dtc-sdk-3.0.0.js
63
- ```
64
-
65
-
66
- ## Playground 开发环境
67
-
68
- - `playground/` 是 SDK 维护者使用的多技术栈联调容器。
69
- - `playground/vue/` 当前使用 `Vue 3 + Vite`,页面入口在 `playground/vue/src/App.vue`,直接消费源码入口 `src/index.ts`。
70
- - 现有 [examples/index.html](examples/index.html) 继续保留为版本化 browser 产物的 smoke test。
71
- - 首次使用:
72
-
73
- ```bash
74
- pnpm run playground:dev
11
+ ## 快速开始
12
+
13
+ ### 直接连接信令服务
14
+
15
+ ```html
16
+ <div id="app"></div>
17
+ <script type="module">
18
+ import { DTCEngine } from '@nnepoch/dtc-sdk';
19
+
20
+ const engine = new DTCEngine({
21
+ signalingServer: 'https://signaling.example.com',
22
+ sceneName: 'demo-scene',
23
+ token: 'your-token',
24
+ dom: document.getElementById('app'),
25
+ viewMode: 'bs',
26
+ showProgressBar: true,
27
+ logger: 'info'
28
+ });
29
+
30
+ try {
31
+ await engine.whenReady();
32
+ console.log('引擎已连接');
33
+ } catch (error) {
34
+ console.error('引擎连接失败', error);
35
+ }
36
+ </script>
75
37
  ```
76
38
 
77
- - Vue Playground 配置固定写在 [playground/vue/src/App.vue](playground/vue/src/App.vue) 的 `PLAYGROUND_CONFIG` 常量中。
78
- - 更详细的字段说明和联调说明见 [playground/vue/README.md](playground/vue/README.md)。
79
-
80
- ## GitLab 发版流程
81
-
82
- - 分支开发阶段仅执行 `pnpm changeset`(或 `npx @changesets/cli`)生成 `.changeset/*.md`。
83
- - `changeset version` 由 GitLab CI 在默认主分支 push 的 `release` job 中统一执行。
84
- - 发布完成后,CI 会回写版本文件并提交 `chore(release): vX.Y.Z [skip ci]`,同时推送 tag。
85
- - 详细说明见 [docs/GITLAB_RELEASE_FLOW.md](docs/GITLAB_RELEASE_FLOW.md)。
39
+ ### 通过中心服务鉴权
86
40
 
87
- ## 迁移说明
88
-
89
- - 旧的 `build:cjs` / `build:esm` 已移除;CJS/ESM 由 `build:lib` 一次性生成。
90
- - `build:lib` 同时执行类型检查和 npm bundle,不再保留单独的 `build:types` 命令。
91
- - `build:obfuscate` 作为 `build:browser` 的内部后处理步骤,通常不需要单独调用。
92
- - `verify:build` 用于检查发布产物,不参与默认构建。
93
-
94
- ## 运行时配置
41
+ 如果使用中心服务,可以传入 `centerIP`,SDK 会完成中心鉴权、服务分配和 WebRTC 连接:
95
42
 
96
43
  ```ts
97
44
  import { DTCEngine } from '@nnepoch/dtc-sdk';
@@ -99,200 +46,139 @@ import { DTCEngine } from '@nnepoch/dtc-sdk';
99
46
  const engine = new DTCEngine({
100
47
  centerIP: 'https://center.example.com',
101
48
  sceneName: 'demo-scene',
102
- token: 'token-from-auth-system',
103
- dom: document.getElementById('app') as HTMLDivElement,
104
- viewMode: 'bs',
105
- logger: 'info'
49
+ token: 'your-token',
50
+ dom: document.getElementById('app') as HTMLDivElement
106
51
  });
107
- ```
108
-
109
- - 连接流程:`new DTCEngine(...)` 后会自动选择 bootstrap 模式并发起 WebRTC 连接。
110
- - `Connect.connect()` 保留为兼容层接口,不再是用户必调入口。
111
- - 支持 `engine.restart()`:用于按 `disconnect -> start` 顺序重启中心与 WebRTC 链路。
112
- - `restart()` 返回 `Promise<AuthSessionSnapshot>`,重启成功 resolve,鉴权/建连失败 reject。
113
- - `disconnect()` 后仍可调用 `restart()` 重新拉起链路。
114
- - bootstrap 模式优先级:
115
- - `signalingServer`
116
- - `centerIP`
117
- - `signalingServer` 的新语义为“信令服务 HTTP 基地址”,SDK 会自动请求 `${signalingServer}/api/v1/allocate?token={config.token}` 获取最终 WebSocket 播放地址。
118
- - 中心鉴权模式下,`TokenAuthorize.values.signalingServer` 返回信令服务 HTTP 基地址,SDK 会再请求 `${signalingServer}/api/v1/allocate?token={engineToken}` 获取最终 WebSocket 播放地址。
119
- - `setSignallingUrlBuilder` 不承载鉴权逻辑,不会在 builder 中发起异步鉴权请求。
120
- - 中心消息处理采用 sdk2 风格的 `OnMessage` 路由分发,鉴权状态由消息事件驱动推进。
121
- - 鉴权主链路不再依赖 `waitForMessage`。
122
- - 参数校验基于 `zod`,在 API 调用前执行 `safeParse`。
123
- - 初始化配置也会执行结构校验与默认值填充(如 `mapType=web`、`operationType=viewer`)。
124
- - 支持从 `navigator.userAgent` 读取初始化覆盖参数,格式与 sdk2 对齐:
125
- - `RunMode/<value>` -> `viewMode`
126
- - `CenterIP/<value>` -> `centerIP`
127
- - `PrivateKey/<value>` -> `privateKey`
128
- - `showProgressBar/<true|false>` -> `showProgressBar`
129
- - 配置优先级:`userAgent` > 调用方 `config` > SDK 默认值。
130
- - `viewMode` 仅支持 `bs | cs`,默认值为 `bs`;传入 `desktop` 或其他非法值会直接抛错并中断初始化。
131
- - 参数不合法时会快速失败,不会触发底层请求发送。
132
- - 若未提供 `centerIP`、`signalingServer` 中的任意一种,初始化会直接失败。
133
- - 日志默认复用 `@epicgames-ps/lib-pixelstreamingcommon-ue5.6` 的 logger。
134
- - `logger` 参数为字符串级别:`silent | error | warn | info | debug`。
135
- - `logger` 默认值为 `info`。
136
- - BREAKING: 不再支持旧对象写法 `logger: { level, includeStack, prefix }`。
137
- - `includeStack` 固定为 `false`,`prefix` 改为 SDK 内部固定策略。
138
- - V1 不提供日志自定义 sink 接口。
139
- - SDK 内部已接入轻量自定义日志上报通道(默认关闭),仅上报 SDK 内部 logger 打印日志。
140
- - 日志上报配置不对业务侧暴露,统一由 SDK 内部维护。
141
- - 运维接入步骤见 [docs/LOG_REPORTING_OPS.md](docs/LOG_REPORTING_OPS.md)。
142
- - `agentBridge` 为可选宿主扩展能力,配置入口位于 `DTCEngine` 的第二个参数 `DTCEngineOptions` 中,而不是 `EngineConfig`。
143
- - 当前 `agentBridge` 只完成源码骨架与生命周期挂载点预留,默认关闭,不会主动建立 MCP runtime 连接。
144
52
 
145
- ```ts
146
53
  await engine.whenReady();
147
- await engine.restart();
148
54
  ```
149
55
 
150
- ### 初始对接推荐写法
56
+ `signalingServer` 和 `centerIP` 至少需要提供一个。两者同时提供时,SDK 优先使用 `signalingServer` 的直接连接模式。
151
57
 
152
- 直接提供信令服务 HTTP 基地址:
58
+ ## 常用配置
153
59
 
154
60
  ```ts
155
61
  const engine = new DTCEngine({
62
+ // 二选一:信令服务 HTTP 基地址或中心服务地址
156
63
  signalingServer: 'https://signaling.example.com',
157
- sceneName: 'demo-scene',
158
- token: 'token-from-auth-system',
159
- dom: document.getElementById('app') as HTMLDivElement
160
- });
161
- ```
162
-
163
- 中心鉴权模式:
64
+ // centerIP: 'https://center.example.com',
164
65
 
165
- ```ts
166
- const engine = new DTCEngine({
167
- centerIP: 'https://center.example.com',
168
66
  sceneName: 'demo-scene',
169
- token: 'token-from-auth-system',
170
- dom: document.getElementById('app') as HTMLDivElement
67
+ token: 'your-token',
68
+ dom: document.getElementById('app') as HTMLDivElement,
69
+
70
+ // bs:浏览器流模式;cs:宿主协同模式
71
+ viewMode: 'bs',
72
+ showProgressBar: true,
73
+ logger: 'info'
171
74
  });
172
75
  ```
173
76
 
174
- ## viewMode 说明
175
-
176
- - `bs`:浏览器流模式,启用完整浏览器输入链路(键鼠触摸等)与标准事件转发。
177
- - `cs`:宿主协同模式,保留键盘输入并关闭鼠标/触摸/手柄/XR 输入转发,适用于宿主侧接管交互的场景。
178
- - 不支持 `desktop`:不会做软降级映射,统一按配置错误处理。
179
-
180
- ## API 接入维护说明
77
+ 支持的日志级别:
181
78
 
182
- - `DTCEngine` 的 API 门面由注册表+工厂统一装配,不再在构造函数中逐个 `new Xxx(...)`。
183
- - 新增 API 时,仅需修改 [src/api/apiRegistry.ts](src/api/apiRegistry.ts) 的注册项并实现对应模块类。
184
- - 若新增模块需要特殊依赖注入(例如 `authWorkflow` / `session`),直接在该模块注册工厂中注入即可。
185
- - 完成注册后,`engine.<Module>` 属性会自动挂载,避免重复修改入口初始化代码。
186
- - 当前已补齐 `engine.Screen` 模块(码率/FPS/分辨率),用于业务调用与自动弱网策略复用。
187
-
188
- ## 弱网自适应 V1
79
+ ```text
80
+ silent | error | warn | info | debug
81
+ ```
189
82
 
190
- - 自动判定输入:`statsReceived + webRtc` 生命周期事件。
191
- - 状态机档位:`Normal / Mild / Moderate / Severe / Recovering`,含迟滞与冷却机制。
192
- - 自动动作:通过 `Screen.SetSceneRenderBitrate / SetSceneFPS / SetScreenResolution` 执行降级与恢复。
193
- - 诊断面板:默认快捷键 `Ctrl + Alt + D`,支持 `Auto / Manual` 接管。
194
- - 详细阈值和验收口径见 [docs/NETWORK_ADAPTATION_V1.md](docs/NETWORK_ADAPTATION_V1.md)。
83
+ ## 生命周期
195
84
 
196
- 弱网相关事件:
197
- - `networkLevelChanged`
198
- - `networkActionExecuted`
199
- - `networkModeChanged`
200
- - `networkDiagnosticsVisibilityChanged`
201
- - `networkDiagnosticsUpdated`
85
+ ```ts
86
+ // 等待首次鉴权和 WebRTC 连接完成
87
+ await engine.whenReady();
202
88
 
203
- ## RequestBridge 多响应能力(开发说明)
89
+ // 断开当前连接
90
+ engine.disconnect();
204
91
 
205
- - `RequestBridge.sendRequest(...)` 继续保持单响应语义:命中首条 `requestId` 响应即完成并释放 pending。
206
- - `RequestBridge.sendStreamRequest(...)` 用于多响应场景:返回可取消 Promise,同一 `requestId` 的状态统一通过单个 `callback` 分发。
207
- - 多响应请求释放条件:
208
- - 收到结束信号(默认支持 `code=DONE/STREAM_DONE` 或 `done/isEnd=true`)
209
- - 调用返回 Promise 的 `cancel()`
210
- - 会话断开(`webRtcDisconnected` / `webRtcFailed`)
211
- - 流式相关类型可从 SDK 类型导出中获取:
212
- - `StreamRequestCallback`
213
- - `StreamRequestEvent`
214
- - `StreamRequestPromise`
92
+ // 重新鉴权并连接
93
+ await engine.restart();
94
+ ```
215
95
 
216
- ## EngineStatus 事件
96
+ ## 监听事件
217
97
 
218
98
  ```ts
219
- engine.on(engine.Events.EngineStatus, (status) => {
220
- console.log(status);
99
+ engine.on(engine.Events.WebRtcConnected, () => {
100
+ console.log('WebRTC connected');
221
101
  });
222
- ```
223
102
 
224
- - `EngineStatus` 与 sdk2 事件名保持一致。
225
- - 事件会在会话连接后持续更新派发;会话断开或失败时停止派发,重连成功后恢复。
226
- - 状态来源仅为 WebRTC 统计(`statsReceived`)。
103
+ engine.on(engine.Events.MapLoaded, () => {
104
+ console.log('场景加载完成');
105
+ });
227
106
 
228
- `EngineStatusInfo` 主要字段:
229
- - `CameraHeight`
230
- - `FPS`
231
- - `Width`
232
- - `Height`
233
- - `runTime`
234
- - `bytePerSecond`
235
- - `lostPacketsRate`
236
- - `delayTime`
237
- - `Codec`
107
+ engine.on(engine.Events.EngineStatus, (status) => {
108
+ console.log('引擎状态', status);
109
+ });
238
110
 
239
- ## UE 主动推送事件
111
+ engine.on(engine.Events.ModelClick, (payload) => {
112
+ console.log('模型点击', payload);
113
+ });
114
+ ```
240
115
 
241
- 以下事件由 UE 侧通过 Pixel Streaming Response 通道主动推送触发,SDK 内部使用单一 response listener 按 `fn/uuid` 路由后派发:
116
+ 常用事件包括:
242
117
 
243
- - `MapLoaded`(底层事件名:`OnApiDataChannelStarted`)
118
+ - `WebRtcConnected`
119
+ - `WebRtcDisconnected`
120
+ - `MapLoaded`
121
+ - `EngineStatus`
244
122
  - `ModelClick`
245
- - `CameraHeight`
246
- - `LeftClick`(`MouseLeftButtonClick`)
247
- - `LeftDoubleClick`(`MouseLeftButtonDoubleClick`)
248
- - `LeftLongPressed`(`MouseLeftButtonLongPressed`)
249
- - `RightClick`(`MouseRightButtonClick`)
250
- - `RightDoubleClick`(`MouseRightButtonDoubleClick`)
251
- - `RightLongPressed`(`MouseRightButtonLongPressed`)
252
- - `SceneConfig`
253
123
  - `ModelTrigger`
124
+ - `AuthStateChanged`
125
+ - `NetworkLevelChanged`
254
126
 
255
- 示例:
127
+ ## 调用引擎 API
256
128
 
257
129
  ```ts
258
- engine.on(engine.Events.ModelClick, (payload) => {
259
- console.log('模型点击', payload);
130
+ await engine.Camera.lookAt({
131
+ parentId: 'ModelLayer',
132
+ id: 'CameraTarget',
133
+ time: 2,
134
+ distance: 20
260
135
  });
261
- ```
262
-
263
- - 事件 payload 默认透传 UE 上行消息内容。
264
- - 若上行消息中的 `fn/uuid` 未命中上述事件集合,SDK 不会触发这些事件。
265
136
 
266
- ## 从 sdk2 迁移(模式相关)
137
+ await engine.Screen.setSceneFPS({ fps: 30 });
267
138
 
268
- - sdk2 中的 `desktop` 在 sdk3 中已移除;请改为 `bs` 或 `cs`。
269
- - 若历史接入使用 `desktop`,需要在业务配置中显式切换为目标模式,不支持自动兜底。
270
- - `new DTCEngine(...)` 后依然保持自动鉴权并自动连接,`Connect.connect()` 仅作为兼容层保留。
271
- - sdk3 已对齐 sdk2 的容器注参逻辑:可通过 `navigator.userAgent` 注入 `RunMode/CenterIP/PrivateKey/showProgressBar` 并覆盖 `config`。
272
- - 本次中心消息迁移范围内,`Offer`、`Answer`、`IceCandidate` 不新增专门处理逻辑。
273
- - 详细迁移步骤可参考 `docs/VIEW_MODE_MIGRATION.md`。
139
+ await engine.Model.setVisible({
140
+ parentId: 'ModelLayer',
141
+ id: 'CameraTarget',
142
+ visible: false
143
+ });
144
+ ```
274
145
 
275
- ## 参数校验失败示例
146
+ SDK 会在 API 调用前校验参数。参数不合法时,Promise 会抛出 `SDKValidationError`:
276
147
 
277
148
  ```ts
278
149
  try {
279
150
  await engine.Camera.lookAt({ id: '' });
280
151
  } catch (error) {
281
152
  console.error(error);
282
- // SDKValidationError:
283
- // {
284
- // code: 'VALIDATION_ERROR',
285
- // module: 'Camera',
286
- // method: 'lookAt',
287
- // issues: [...]
288
- // }
289
153
  }
290
154
  ```
291
155
 
292
- ## 产物
156
+ 完整 API 列表请查看:[API 文档](./docs/api/)。
157
+
158
+ ## 浏览器脚本产物
159
+
160
+ 如果不使用 npm 模块系统,也可以使用版本化的浏览器脚本:
161
+
162
+ ```html
163
+ <script src="./dist/browser/dtc-sdk-<version>.js"></script>
164
+ <script>
165
+ const engine = new window.DTCEngine({
166
+ signalingServer: 'https://signaling.example.com',
167
+ sceneName: 'demo-scene',
168
+ token: 'your-token',
169
+ dom: document.getElementById('app')
170
+ });
171
+ </script>
172
+ ```
173
+
174
+ ## 示例和文档
175
+
176
+ - [快速开始](./docs/guide/getting-started.md)
177
+ - [API 文档](./docs/api/)
178
+ - [开发者文档](./docs/DEVELOPMENT.md)
179
+ - [Playground 说明](./playground/README.md)
180
+ - [杭州九中示例](./examples/hzjz/)
181
+
182
+ ## 许可证
293
183
 
294
- - `dist/cjs/index.cjs`(CJS)
295
- - `dist/esm/index.js`(ESM)
296
- - `dist/esm/index.d.ts`(types)
297
- - `dist/browser/dtc-sdk-<version>.js`(script 可直引,已混淆)
298
- - `docs/api`(typedoc)
184
+ MIT