dsh-mobile-plugin 0.1.98 → 0.1.100

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
@@ -136,8 +136,11 @@ npm test
136
136
  1. 跑 `node scripts/bump-version.mjs` 更新版本号。
137
137
  2. 改过 `React/` 就跑 `cd React && pnpm run build`。
138
138
  3. 跑 `npm test`,再用 `npm pack --dry-run` 看一眼要发出去的文件。
139
- 4. 跑 `npm publish`,按提示完成 npm 二次验证。
140
- 5. 用 `npm view dsh-mobile-plugin version` 确认注册表版本,再把改动同步到公开仓库。
139
+ 4. 提交,把改动同步到公开仓库 `WNLUO/dsh-mobile-plugin`。
140
+ 5. 推一个与版本号同名的 tag(版本 0.1.99 就推 `v0.1.99`)。那个仓库的 `.github/workflows/publish.yml` 会跑测试并直接发布,不需要人在浏览器里点二次验证 —— 它走 npm 的 trusted publishing(OIDC),npm 认的是这条流水线而不是某个令牌。
141
+ 6. 等流水线绿。它末尾自己会核 `npm view dsh-mobile-plugin version`,你也可以手动看一眼。
142
+
143
+ `npm publish` 仍能在开发机上手动跑,但现在要人过二次验证:账号上只有安全密钥时,npm 会打印一条 `www.npmjs.com/auth/cli/…` 链接,要用密钥在浏览器里点一下,且发起那台机器的出口 IP 要能打开 npm 官网。这条路留着应急,日常发版走 tag。
141
144
 
142
145
  ## 📎 远程控制元数据
143
146
 
@@ -648,7 +648,12 @@ function createLanProxy(opts) {
648
648
  onDone();
649
649
  });
650
650
  try {
651
- v6.listen(actualPort, '::', { ipv6Only: true });
651
+ // options 必须整个作为**第一个**参数传:`listen(port, host, backlog)` 的第三位
652
+ // 是 backlog(数字),传对象进去会被忽略 —— 于是 `ipv6Only` 从来没生效过。
653
+ // macOS / BSD 的 v6 套接字默认就是 v6only,所以这条在本机一直"看着正常";
654
+ // Linux 默认是双栈,它会跟上面那条 `0.0.0.0` 撞成 EADDRINUSE,整条 IPv6
655
+ // 监听静默不建立(GitHub Actions 上就是这么红的)。
656
+ v6.listen({ port: actualPort, host: '::', ipv6Only: true });
652
657
  } catch (err) {
653
658
  log(`IPv6 监听未建立(${err.code || err.message}),只保留 IPv4 直连`);
654
659
  onDone();
@@ -32,7 +32,12 @@ const HTTP_RESPONSE_RELAY_PAUSE_TIMEOUT_MS = 30_000;
32
32
  const UPSTREAM_HEADER_TIMEOUT_MS = 7_000;
33
33
  const UPSTREAM_RESPONSE_IDLE_TIMEOUT_MS = 30_000;
34
34
  // Keep reconnect storms from monopolizing the local Host HTTP server.
35
- const MAX_UPSTREAM_SSE_CONNECTIONS = 16;
35
+ //
36
+ // 64 与局域网那条直连闸(lan-proxy 的 MAX_UPSTREAM_SSE_CONNECTIONS)取同一个数:两条路
37
+ // 通向的是同一个宿主、同一种资源,之前这里 16、那边 64,结果一台手机的几个被丢弃的连接
38
+ // 就能把走中转的所有设备一起挡在 429 外面。上限的作用是挡住失控重连,不是给正常多设备
39
+ // 使用设配额 —— 一台手机正常只占两条(会话流 + 设备级流)。
40
+ const MAX_UPSTREAM_SSE_CONNECTIONS = 64;
36
41
  class RelayTunnel {
37
42
  /**
38
43
  * @param {object} opts
@@ -566,6 +571,9 @@ class RelayTunnel {
566
571
  const entry = this.createHttpResponseEntry(null, null, isSse);
567
572
  this.reqClients.set(id, entry);
568
573
  if (isSse && this.sseClients.size >= MAX_UPSTREAM_SSE_CONNECTIONS) {
574
+ // 留一行日志:这条 429 的正文是空的,手机侧只会看到「连不上」,事后没法反推是被
575
+ // 本地这道闸挡的,还是中转那边挡的(两边上限同名同数)。
576
+ this.log(`上游长流已达上限 ${MAX_UPSTREAM_SSE_CONNECTIONS},拒绝 ${msg.path}`);
569
577
  this.queueHttpResponseFrame(id, entry, T.httpHead, { status: 429, headers: { 'content-type': 'text/plain; charset=utf-8', 'retry-after': '2' } }, true);
570
578
  this.queueHttpResponseFrame(id, entry, T.httpEnd, Buffer.alloc(0));
571
579
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-mobile-plugin",
3
- "version": "0.1.98",
3
+ "version": "0.1.100",
4
4
  "description": "Mobile API (/api/mobile/v1) and relay client for the DSH mobile app — desktop profile build (0.2.0-rc.2 compatible, peers resolved by the host)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -52,10 +52,10 @@
52
52
  },
53
53
  "peerDependencies": {
54
54
  "@deepseek-ai/cordis": ">=4.0.1",
55
- "@deepseek-ai/dsh-client-locale": ">=0.1.1-rc.2",
55
+ "@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2 || ^0.2.0-rc.1 || ^0.2.1-rc.2",
56
56
  "@deepseek-ai/dsh-client-runtime": ">=0.1.1-rc.2",
57
- "@deepseek-ai/dsh-settings": ">=0.1.1-rc.2",
58
- "@deepseek-ai/dsh-tools": ">=0.1.1-rc.2",
57
+ "@deepseek-ai/dsh-settings": "^0.1.1-rc.2 || ^0.2.0-rc.1 || ^0.2.1-rc.2",
58
+ "@deepseek-ai/dsh-tools": "^0.1.1-rc.2 || ^0.2.0-rc.1 || ^0.2.1-rc.2",
59
59
  "@deepseek-ai/schemastery": "^3.18.1"
60
60
  },
61
61
  "dsh": {