@mzzsfy/dsh-tunnel 0.1.2 → 0.1.3
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 +7 -3
- package/package.json +1 -1
- package/src/client.js +3 -4
- package/test/client-dependency.test.mjs +29 -0
package/README.md
CHANGED
|
@@ -29,15 +29,19 @@
|
|
|
29
29
|
- 持久化 `~/.dsh/dsh-tunnel/tunnels.json`(随 `DSH_HOME`), 重启自动恢复; 目标拒连 502, 响应头等待超时(默认 10s, 头到即解除, SSE 不受影响)504
|
|
30
30
|
- REST: `/api/tunnel/tunnels`(GET/POST/DELETE `/api/tunnel/tunnels/:name`) + `/api/tunnel/status` + `/api/tunnel/ui-settings`(POST: aiTools / sidebarTab), 与 GUI/ai 同一入口
|
|
31
31
|
|
|
32
|
+
## client 依赖
|
|
33
|
+
|
|
34
|
+
看板通过 `@mzzsfy/dsh-common-tools/client` 订阅数据变更。安装时同时启用 `dsh-session-manager`,由其唯一代挂条目装载公共 client,并排在 tunnel 前物化。公共模块缺失时装载层会报告具体依赖错误;宿主 React 模块缺失时控制台报告原因并禁用面板。
|
|
35
|
+
|
|
32
36
|
## 验证
|
|
33
37
|
|
|
34
|
-
- `
|
|
38
|
+
- `npm test`(经 _mocks.common-tools.mjs 预载公共依赖桩): 37 场景 + 8 api 用例 + 11 ai 开关注册面 + 11 守卫断言 + client 端 8 用例(id 守卫 + 总线生命周期;mock webServer + 真实 http/net 端到端)
|
|
35
39
|
- `node scripts/compat/tunnel-fullchain.mjs`: 隔离 dsh 实例全链路(真实激活/恢复/分发面七项探针)
|
|
36
40
|
|
|
37
41
|
## 设计文档
|
|
38
42
|
|
|
39
|
-
`docs/调研-路径穿透插件.md`(「方案设计」两节为本包实施规格, 含已知限制); `docs/设计-隧道GUI.md`(GUI/设置/侧边栏注入实施规格)
|
|
43
|
+
`docs/调研-路径穿透插件.md`(「方案设计」两节为本包实施规格, 含已知限制); `docs/设计-隧道GUI.md`(GUI/设置/侧边栏注入实施规格)。两份均为仓库本地维护文档,不入库,npm 安装读者不可见。
|
|
40
44
|
|
|
41
45
|
## dsh 版本兼容
|
|
42
46
|
|
|
43
|
-
按仓库动态窗口验证(scripts/compat/window.mjs),不预置任何固定版本槽:主测 = 渠道 dist-tag 最新 rc,完全适配口径;基线 = npm latest,不崩溃底线口径;主测与基线同版时收敛单槽。兼容面以窗口实测为准,不逐版本承诺。逐轮实测结论见 `docs/兼容性测试/逐包测试进度.md`
|
|
47
|
+
按仓库动态窗口验证(scripts/compat/window.mjs),不预置任何固定版本槽:主测 = 渠道 dist-tag 最新 rc,完全适配口径;基线 = npm latest,不崩溃底线口径;主测与基线同版时收敛单槽。兼容面以窗口实测为准,不逐版本承诺。逐轮实测结论见 `docs/兼容性测试/逐包测试进度.md`(本地维护,不入库)与本包 `兼容性测试.md`。
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mzzsfy/dsh-tunnel",
|
|
3
3
|
"description": "路径穿透隧道:在 dsh 宿主进程内把 /p/<name> 反向代理到本地 TCP 端口(HTTP strip 转发 + 声明式 WS upgrade + 3xx Location 单头改写),支持 <name>.* 子域名全路径透传(任意 WS 路径);GUI 看板手动管理隧道,设置页独立配置节与侧边栏注入开关;向 ai 注册 tunnel_open/tunnel_list/tunnel_close 工具且「允许 ai 使用」可开关(关闭即注销);代理逻辑全在插件进程内,不引入 nginx/caddy 等外部反代",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"exports": {
|
package/src/client.js
CHANGED
|
@@ -169,15 +169,14 @@ if (typeof window !== 'undefined' && window.__ModuleLoader__) {
|
|
|
169
169
|
function factory(require) {
|
|
170
170
|
let React = null
|
|
171
171
|
let ReactDOMClient = null
|
|
172
|
-
let tools = null
|
|
173
172
|
try {
|
|
174
173
|
React = require('react')
|
|
175
174
|
ReactDOMClient = require('react-dom/client')
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
} catch {
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.error('[dsh-tunnel] 宿主 React 模块加载失败', error)
|
|
179
177
|
return noopFactory()
|
|
180
178
|
}
|
|
179
|
+
const tools = require('@mzzsfy/dsh-common-tools/client')
|
|
181
180
|
const { useState, useEffect, useRef, useCallback } = React
|
|
182
181
|
const h = (type, props, ...children) => React.createElement(type, props ?? null, ...children)
|
|
183
182
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import test from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { readFileSync } from 'node:fs'
|
|
4
|
+
import vm from 'node:vm'
|
|
5
|
+
|
|
6
|
+
const source = readFileSync(new URL('../src/client.js', import.meta.url), 'utf8')
|
|
7
|
+
function materialize(missing) {
|
|
8
|
+
let definition
|
|
9
|
+
const diagnostics = []
|
|
10
|
+
const window = { __ModuleLoader__: { load(value) { definition = value } } }
|
|
11
|
+
vm.runInNewContext(source, { window, console: { error: (...args) => diagnostics.push(args) } })
|
|
12
|
+
const require = name => {
|
|
13
|
+
if (name === missing) throw new Error(`module missing: ${name}`)
|
|
14
|
+
return {}
|
|
15
|
+
}
|
|
16
|
+
return { definition, require, diagnostics }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
test('Given 缺公共client When 物化隧道模块 Then 向装载层抛出具体依赖错误', () => {
|
|
20
|
+
const f = materialize('@mzzsfy/dsh-common-tools/client')
|
|
21
|
+
assert.throws(() => f.definition.factory(f.require), /module missing: @mzzsfy\/dsh-common-tools\/client/)
|
|
22
|
+
})
|
|
23
|
+
for (const missing of ['react', 'react-dom/client']) test(`Given 缺${missing} When 物化 Then 禁用并报告宿主依赖原因`, () => {
|
|
24
|
+
const f = materialize(missing)
|
|
25
|
+
const module = f.definition.factory(f.require)
|
|
26
|
+
assert.deepEqual(Array.from(module.inject), [])
|
|
27
|
+
assert.equal(f.diagnostics.length, 1)
|
|
28
|
+
assert.match(String(f.diagnostics[0]), new RegExp(missing))
|
|
29
|
+
})
|