dsh-pocket 1.4.8 → 1.5.0

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/lib/index.js CHANGED
@@ -148,6 +148,8 @@ export function apply(ctx, config = {}, internals = {}) {
148
148
  // 代理随插件自动启动(局域网二维码开箱即用,零配置)
149
149
  void service.startProxy().then((proxy) => {
150
150
  logger.info('dsh-pocket: proxy ready on :%d | 局域网代理已就绪', proxy.port);
151
+ // 自动恢复上次开启的公网隧道(DSH 重启后 cloudflared 子进程被杀,issue #11)
152
+ void service.restoreTunnelIfNeeded?.().catch(() => {});
151
153
  }).catch((err) => {
152
154
  logger.error('dsh-pocket: proxy start failed | 代理启动失败: %s', err?.message ?? err);
153
155
  });
package/lib/service.mjs CHANGED
@@ -8,6 +8,8 @@
8
8
 
9
9
  import { networkInterfaces } from 'node:os';
10
10
  import { createRequire } from 'node:module';
11
+ import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
12
+ import { join, dirname } from 'node:path';
11
13
  import { createPocketProxy } from './proxy.mjs';
12
14
  import { startQuickTunnel } from './tunnel.mjs';
13
15
 
@@ -112,6 +114,21 @@ export function createPocketService({
112
114
  return qrCache.get(text);
113
115
  }
114
116
 
117
+ // 公网隧道自动恢复(issue #11):DSH 重启后 cloudflared 子进程被杀、隧道消失,
118
+ // 插件无从知晓。启动时检查持久化的「隧道开启中」标记,自动重新拉起。
119
+ const autoStatePath = home ? join(home, 'dsh-pocket', 'tunnel-auto.json') : null;
120
+ async function persistAutoTunnel() {
121
+ if (!autoStatePath) return;
122
+ try {
123
+ await mkdir(dirname(autoStatePath), { recursive: true });
124
+ await writeFile(autoStatePath, JSON.stringify({ at: Date.now() }), 'utf8');
125
+ } catch { /* 忽略 */ }
126
+ }
127
+ async function clearAutoTunnel() {
128
+ if (!autoStatePath) return;
129
+ try { await rm(autoStatePath, { force: true }); } catch { /* 忽略 */ }
130
+ }
131
+
115
132
  return {
116
133
  dshPort,
117
134
  /** 启动局域网代理(幂等)。端口被占(EADDRINUSE,如桌面版与普通环境同时运行)时自动尝试下一个端口。 */
@@ -166,6 +183,8 @@ export function createPocketService({
166
183
  tunnelState.phase = 'error';
167
184
  tunnelState.detail = `隧道进程退出(code=${code})| tunnel process exited`;
168
185
  });
186
+ // 记录「隧道开启中」,供重启后自动恢复(issue #11)
187
+ void persistAutoTunnel();
169
188
  return tunnel.url;
170
189
  } catch (err) {
171
190
  // stopTunnel 触发的 abort 不算错误:保持 idle,别把状态刷成 error
@@ -195,6 +214,25 @@ export function createPocketService({
195
214
  tunnelState.phase = 'idle';
196
215
  tunnelState.detail = '';
197
216
  tunnelState.startedAt = null;
217
+ void clearAutoTunnel(); // 手动关闭后不再自动恢复
218
+ },
219
+
220
+ /** 启动时自动恢复上次开启的公网隧道(DSH 重启后 cloudflared 子进程被杀,issue #11)。 */
221
+ async restoreTunnelIfNeeded() {
222
+ if (!autoStatePath || tunnel || tunnelPromise) return;
223
+ let has = false;
224
+ try {
225
+ const raw = await readFile(autoStatePath, 'utf8');
226
+ has = /"at"\s*:/.test(raw);
227
+ } catch { return; } // 无标记 → 不恢复
228
+ if (!has) return;
229
+ try {
230
+ await this.startTunnel();
231
+ console.log('dsh-pocket: public tunnel auto-restored | 已自动恢复公网隧道');
232
+ } catch (err) {
233
+ // 恢复失败保留标记(下次启动再试);网络问题见 README 排障
234
+ console.warn('dsh-pocket: tunnel auto-restore failed | 自动恢复隧道失败: %s', err?.message ?? err);
235
+ }
198
236
  },
199
237
 
200
238
  /** 状态快照(RPC 返回,不含敏感信息;二维码 data URL 本地生成 + 缓存)。 */
package/package.json CHANGED
@@ -76,5 +76,5 @@
76
76
  "access": "public",
77
77
  "registry": "https://registry.npmjs.org/"
78
78
  },
79
- "version": "1.4.8"
79
+ "version": "1.5.0"
80
80
  }