dsh-selfupdater 0.4.16 → 0.4.17

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
@@ -258,7 +258,7 @@ export function apply(ctx) {
258
258
  const updateAvailable = isNewer(latest, current);
259
259
  // 检查结果落盘(内部自动建目录),UI 刷新后仍能看到上次检查时间。
260
260
  writeStatus(dshStateDir, {
261
- ...(await Promise.resolve(readStatus(dshStateDir))),
261
+ ...readStatus(dshStateDir),
262
262
  currentVersion: current,
263
263
  latestVersion: latest,
264
264
  state: isBusy() ? 'running' : 'idle',
@@ -88,13 +88,17 @@ function registryCandidates() {
88
88
  return [...new Set(list.filter((v) => typeof v === 'string' && v !== ''))];
89
89
  }
90
90
 
91
+ /** 除 latest 外额外追踪的官方发布渠道 tag(官方习惯把新版先挂在 next/alpha 上)。 */
92
+ const EXTRA_DIST_TAGS = ['next', 'alpha'];
93
+
91
94
  /**
92
- * 从单个 registry /latest 版本级端点取文档(含 dist.tarball)。
95
+ * 从单个 registry 的版本级端点(/<pkg>/<tag>)取文档(含 dist.tarball)。
93
96
  * 用版本级端点而非整包 packument:后者会被 Fastly 等 CDN 长时间缓存,
94
97
  * 出现"包已发布但查不到新版"的假象。
98
+ * tag 不存在时(如包从未打过 alpha tag)registry 返回 404,由调用方 allSettled 吞掉。
95
99
  */
96
- async function fetchVersionDoc(base, pkg) {
97
- const res = await fetch(`${base}/${encodeURIComponent(pkg)}/latest`, {
100
+ async function fetchVersionDoc(base, pkg, tag = 'latest') {
101
+ const res = await fetch(`${base}/${encodeURIComponent(pkg)}/${tag}`, {
98
102
  headers: { accept: 'application/json', 'user-agent': 'dsh-selfupdater' },
99
103
  signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
100
104
  });
@@ -117,14 +121,19 @@ async function fetchVersionDoc(base, pkg) {
117
121
  */
118
122
  async function fetchLatestRelease(pkg) {
119
123
  const candidates = registryCandidates();
120
- const results = await Promise.allSettled(candidates.map((base) => fetchVersionDoc(base, pkg)));
124
+ // 每个 registry × 每个渠道 tag(latest/next/alpha)并行查询:
125
+ // 只查 /latest 会漏掉挂在 next/alpha tag 上的新版(0.1.2-alpha.2 实测踩坑),
126
+ // 与 build.sh 优先取 dist-tags.next 的官方发版习惯保持一致。
127
+ const tags = ['latest', ...EXTRA_DIST_TAGS];
128
+ const targets = candidates.flatMap((base) => tags.map((tag) => ({ base, tag })));
129
+ const results = await Promise.allSettled(targets.map((t) => fetchVersionDoc(t.base, pkg, t.tag)));
121
130
  let best = null;
122
131
  const errors = [];
123
132
  results.forEach((r, i) => {
124
133
  if (r.status === 'fulfilled') {
125
134
  if (best === null || isNewer(r.value.version, best.version)) best = r.value;
126
135
  } else {
127
- errors.push(`${candidates[i]}: ${r.reason.message}`);
136
+ errors.push(`${targets[i].base}/${targets[i].tag}: ${r.reason.message}`);
128
137
  }
129
138
  });
130
139
  if (best === null) throw new Error(errors.join(';'));
package/lib/updater.mjs CHANGED
@@ -241,13 +241,17 @@ function registryCandidates() {
241
241
  return [...new Set(list.filter((v) => typeof v === 'string' && v !== ''))];
242
242
  }
243
243
 
244
+ /** 除 latest 外额外追踪的官方发布渠道 tag(官方习惯把新版先挂在 next/alpha 上)。 */
245
+ const EXTRA_DIST_TAGS = ['next', 'alpha'];
246
+
244
247
  /**
245
- * 从单个 registry /latest 版本级端点取文档(含 dist.tarball)。
248
+ * 从单个 registry 的版本级端点(/<pkg>/<tag>)取文档(含 dist.tarball)。
246
249
  * 用版本级端点而非整包 packument:后者会被 Fastly 等 CDN 长时间缓存,
247
250
  * 出现"包已发布但查不到新版"的假象(插件 0.4.5 踩坑根因)。
251
+ * tag 不存在时(如包从未打过 alpha tag)registry 返回 404,由调用方 allSettled 吞掉。
248
252
  */
249
- async function fetchVersionDoc(base, pkg) {
250
- const res = await fetch(`${base}/${encodeURIComponent(pkg)}/latest`, {
253
+ async function fetchVersionDoc(base, pkg, tag = 'latest') {
254
+ const res = await fetch(`${base}/${encodeURIComponent(pkg)}/${tag}`, {
251
255
  headers: { accept: 'application/json', 'user-agent': 'dsh-selfupdater' },
252
256
  signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
253
257
  });
@@ -266,14 +270,19 @@ async function fetchVersionDoc(base, pkg) {
266
270
  */
267
271
  async function fetchLatestRelease(pkg) {
268
272
  const candidates = registryCandidates();
269
- const results = await Promise.allSettled(candidates.map((base) => fetchVersionDoc(base, pkg)));
273
+ // 每个 registry × 每个渠道 tag(latest/next/alpha)并行查询:
274
+ // 只查 /latest 会漏掉挂在 next/alpha tag 上的新版(0.1.2-alpha.2 实测踩坑),
275
+ // 与 build.sh 优先取 dist-tags.next 的官方发版习惯保持一致。
276
+ const tags = ['latest', ...EXTRA_DIST_TAGS];
277
+ const targets = candidates.flatMap((base) => tags.map((tag) => ({ base, tag })));
278
+ const results = await Promise.allSettled(targets.map((t) => fetchVersionDoc(t.base, pkg, t.tag)));
270
279
  let best = null;
271
280
  const errors = [];
272
281
  results.forEach((r, i) => {
273
282
  if (r.status === 'fulfilled') {
274
283
  if (best === null || isNewer(r.value.version, best.version)) best = r.value;
275
284
  } else {
276
- errors.push(`${candidates[i]}: ${r.reason.message}`);
285
+ errors.push(`${targets[i].base}/${targets[i].tag}: ${r.reason.message}`);
277
286
  }
278
287
  });
279
288
  if (best === null) throw new Error(errors.join(';'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-selfupdater",
3
- "version": "0.4.16",
3
+ "version": "0.4.17",
4
4
  "description": "Self-update plugin for DeepSeek Harness: DSH core upgrades via detached swap script; plugin self-update installs in-place without killing the host and prompts for restart. DSH 主程序与已装插件的一站式在线更新插件。",
5
5
  "license": "MIT",
6
6
  "type": "module",