dsh-session-curator 0.1.1 → 0.1.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.
@@ -0,0 +1,67 @@
1
+ /**
2
+ * 版本比较与"有没有新版"的查询。
3
+ *
4
+ * 为什么放在**宿主**而不是客户端直接 fetch:客户端那侧要过 CORS / 可能的 CSP 和桌面端
5
+ * 网络策略,宿主本来就是普通 Node,顺便还能做超时与缓存。只读 GET,没有任何副作用。
6
+ * 这也是插件**唯一**的外发请求,别在别处再加。
7
+ */
8
+ import { messageOf } from "./fs-utils.js";
9
+ import { LOCAL_VERSION, PLUGIN_NAME } from "./manifest.js";
10
+ const UPDATE_REGISTRY = "https://registry.npmjs.org";
11
+ /** 10 分钟内复用上次结果:打开配置页不该每次都打 registry。 */
12
+ const UPDATE_TTL_MS = 10 * 60 * 1000;
13
+ const UPDATE_TIMEOUT_MS = 5000;
14
+ let updateCache = null;
15
+ /**
16
+ * 宽松 semver 比较:只按数字段比,带 prerelease 后缀的算更低
17
+ * (`0.1.1` > `0.1.1-rc.1`,`0.2.0` > `0.1.9`)。够判断"有没有新版",不引依赖。
18
+ * 导出是为了让 `scripts/smoke.mjs` 直接单测它(浏览器里用不到)。
19
+ */
20
+ export function compareVersions(left, right) {
21
+ const parse = (value) => {
22
+ const [core, ...rest] = String(value).replace(/^v/, "").split("-");
23
+ return { parts: (core ?? "").split(".").map((part) => Number.parseInt(part, 10) || 0), prerelease: rest.length > 0 };
24
+ };
25
+ const a = parse(left);
26
+ const b = parse(right);
27
+ for (let index = 0; index < Math.max(a.parts.length, b.parts.length); index += 1) {
28
+ const difference = (a.parts[index] ?? 0) - (b.parts[index] ?? 0);
29
+ if (difference !== 0)
30
+ return difference > 0 ? 1 : -1;
31
+ }
32
+ if (a.prerelease === b.prerelease)
33
+ return 0;
34
+ return a.prerelease ? -1 : 1;
35
+ }
36
+ export async function checkForUpdate(force) {
37
+ const now = Date.now();
38
+ if (force !== true && updateCache !== null && now - updateCache.at < UPDATE_TTL_MS)
39
+ return updateCache.value;
40
+ const base = { current: LOCAL_VERSION, latest: null, outdated: false, checkedAt: now };
41
+ let value;
42
+ try {
43
+ const response = await fetch(`${UPDATE_REGISTRY}/${PLUGIN_NAME}/latest`, {
44
+ headers: { accept: "application/json" },
45
+ signal: AbortSignal.timeout(UPDATE_TIMEOUT_MS)
46
+ });
47
+ if (!response.ok)
48
+ throw new Error(`HTTP ${response.status}`);
49
+ const body = await response.json();
50
+ const version = body?.version;
51
+ const latest = typeof version === "string" && version !== "" ? version : null;
52
+ if (latest === null)
53
+ throw new Error("registry 没有返回 version 字段");
54
+ value = {
55
+ ...base,
56
+ latest,
57
+ outdated: LOCAL_VERSION !== null && compareVersions(latest, LOCAL_VERSION) > 0,
58
+ checkedAt: Date.now()
59
+ };
60
+ }
61
+ catch (error) {
62
+ // 离线 / 超时 / 代理不通都走这里:界面照常显示版本号,只是没有更新提示。
63
+ value = { ...base, error: messageOf(error) };
64
+ }
65
+ updateCache = { at: Date.now(), value };
66
+ return value;
67
+ }