dsh-plugin-update 0.4.0 → 0.5.1
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/CHANGELOG.md +18 -0
- package/README.md +11 -8
- package/dist/changelog-io.d.ts +5 -0
- package/dist/changelog.d.ts +66 -3
- package/dist/changelog.js +412 -35
- package/dist/entry.d.ts +8 -3
- package/dist/entry.js +26 -15
- package/dist/host.d.ts +2 -2
- package/dist/host.js +57 -7
- package/dist/panel-batch.js +46 -11
- package/dist/panel.d.ts +17 -3
- package/dist/panel.js +91 -18
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
格式为 Keep-a-Changelog 子集:`Added/Fixed/Changed` 必写,`Deprecated/Removed/Security` 有则透传,`Unreleased` 面板忽略,禁止 git-log 直倒。面板缺日志时中性提示,不挡安装。
|
|
4
4
|
|
|
5
|
+
## [0.5.1] - 2026-10-06
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- 入口件 `openOn: 'direct'`:点开即弹窗、不预查(面板挂载即自查;徽标形态仍走回调口径)。
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- 入口件小字对比度:原地提示与档案卷按钮脸自带底,深色宿主下也读得出。
|
|
12
|
+
|
|
13
|
+
## [0.5.0] - 2026-10-05
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- 主题首选名 `archive`(档案卷纸面浅色):`d5-paper` 为旧别名仍可用,渲染逐字相同;入口件与批量面板同一套取值。
|
|
17
|
+
- 弹窗关闭落地 `onCloseRequested`:dialog 下点「关闭」/按 Esc 先交调用方撤 DOM 再停轮询;入口件打开的 dialog 已内置(收 dialog + 还原按钮 + 重查一次)。
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- 弹窗点「关闭」没反应:此前只停轮询不撤 DOM(入口件打开的 dialog 还会卡死),现走关闭落地。
|
|
21
|
+
- 悬停/聚焦闪烁:轮询每秒整树重写 innerHTML 打断 hover/focus,现输出逐字相同时不碰 DOM(状态变化仍即时重绘;单面板与批量面板同口径)。
|
|
22
|
+
|
|
5
23
|
## [0.4.0] - 2026-10-05
|
|
6
24
|
|
|
7
25
|
### Added
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
给 DSH 插件加「检查更新 / 安装更新」能力的 npm 包。宿主侧一段接线,面板侧挂一个现成组件,装不上时给用户一条可复制的手工命令。
|
|
4
4
|
|
|
5
|
-
要求 Node 22 或更高,零运行时依赖。当前版本 `0.
|
|
5
|
+
要求 Node 22 或更高,零运行时依赖。当前版本 `0.5.1`。
|
|
6
6
|
|
|
7
7
|
装上它你会拿到六样东西:
|
|
8
8
|
|
|
@@ -69,7 +69,7 @@ createHostUpdate(
|
|
|
69
69
|
|
|
70
70
|
本包是 ESM(`"type": "module"`):ESM 插件直接 `import`;CJS 插件用 `await import('dsh-plugin-update')`。
|
|
71
71
|
|
|
72
|
-
###
|
|
72
|
+
### 四个电话的入参与回参
|
|
73
73
|
|
|
74
74
|
面板与宿主两侧共用这一份契约(`…` 是你的前缀):
|
|
75
75
|
|
|
@@ -128,6 +128,7 @@ const panel = mountUpdatePanel(document.getElementById('update-slot'), {
|
|
|
128
128
|
call: (name, args) => host.call(name, args),
|
|
129
129
|
})
|
|
130
130
|
// 离开时 panel.unmount():只停轮询,安装在宿主侧继续跑;重开面板立刻重查,1 秒内恢复显示。
|
|
131
|
+
// 弹窗版想让「关闭」按钮真把弹窗撤掉:传 onCloseRequested(面板点关闭/Esc 时先调它撤 DOM,再停轮询;入口件打开的 dialog 已内置)。
|
|
131
132
|
```
|
|
132
133
|
|
|
133
134
|
组件内部消化的事(调用者不再写):按 `panelPollMs` 轮询查状态(下限 250 毫秒);安装按钮状态跟随快照的 `canInstall`,不另写门控规则;装不了的原因按第 5.2 节展示中文一句话;`pending-restart` 单独横幅加重启指引,不再给安装按钮;手工命令展示与复制;排队位置展示与 `showOthers` 开关;跳过按版本记(“已跳过 X.Y.Z · 恢复”在同一行,不藏进设置页);失败时旁边的“复制诊断”一键给出脱敏后的自包含文本(稳定码、版本、宿主、队列位置),深挖仍看日志(组件里留着第 6 节第 11 条的过滤口径)。
|
|
@@ -141,7 +142,7 @@ mountUpdatePanel(slot, { pluginId: 'my-notes-plugin', prefix: 'notes', call: hos
|
|
|
141
142
|
|
|
142
143
|
面板画成档案五章:**01 检查与安装、02 更新日志、03 更新队列、04 错误信息、05 手工命令**(五章恒在,缺内容给中性提示,不跳号)。档案头一行是「插件名 + 使用范围 + `profile` 牌」:使用范围由面板自动向宿主索取(电话入参 `includeEnv`,宿主只回**范围名与宿主种类**、不回任何路径),显示的就是更新要落到的那个 profile——`web` 与 `desktop` 各装一份,装错范围是严重故障,所以这一栏宁可显示“未知”也不猜。调用方知道得更准时可以用 `profileName` 显式覆盖。
|
|
143
144
|
|
|
144
|
-
|
|
145
|
+
可选档案卷主题(纸面浅色案卷风,不替换默认):挂载时加 `theme: 'archive'` 即换肤(右上大印章「待查/可装/安装中/待重启/受阻/已最新」+ 横幅小印章一字 + profile 牌 + 待重启衬线横幅配手绘 SVG 标 + 窄屏印章固定 + 省略号逐字折叠 + 浅深双主题跟随系统),内核 DOM 顺序不动、复制诊断常在;不传即最小可用默认深色样式。运行时用 `panel.setTheme('archive' | 'default')` 可切。旧值 `theme: 'd5-paper'` 仍可用(同一套渲染)。入口件与批量面板是同一个 `theme` 参数,取值同一套。
|
|
145
146
|
|
|
146
147
|
类型定义随包分发(`dsh-plugin-update/panel` 的 `.d.ts`),不用自编译;面板离线可读,与包版本绑定。
|
|
147
148
|
|
|
@@ -180,10 +181,12 @@ const entry = mountUpdateEntry(document.getElementById('upd-entry'), {
|
|
|
180
181
|
|---|---|---|---|
|
|
181
182
|
| 摆什么 | `button` / `badge` / `inline` | `button` | 按钮;只给一个状态点;面板本体直接嵌进来 |
|
|
182
183
|
| 什么时候查 | `mount` / `never` | `mount` | 进页面静默查一次(**只调 `.updateStatus`,只读**);`never` 则只在点击时查 |
|
|
183
|
-
| 点了做什么 | `has-update` / `always` / `manual` | `has-update` |
|
|
184
|
+
| 点了做什么 | `has-update` / `always` / `manual` / `direct` | `has-update` | 有新版才开面板;检查完总是开;交给 `onActivate` 自己跳;点开即弹窗、不预查 |
|
|
184
185
|
|
|
185
186
|
按钮文案随状态自己变:`检查更新` / `有新版 1.1.0` / `正在安装…` / `待重启` / `更新失败,点此查看`。
|
|
186
187
|
|
|
188
|
+
无新版时原地那句小字(`已是最新 X.Y.Z`)只在 `has-update` 下出现:不想看它就用 `openOn: 'always'`(检查完总是开弹窗,无新版在弹窗里看“已是最新”)或 `openOn: 'direct'`(点开即弹窗,连预查都省了,面板挂载即自查;徽标形态仍走回调口径)。
|
|
189
|
+
|
|
187
190
|
**一条铁律:检查是只读、安装是写入,两者不许合并成一个动作。** 入口件永远只做「查 + 打开面板」,
|
|
188
191
|
任何路径都不自动安装;用户必须在面板里明确点「安装」。想让点击交给自己(例如你已有自己的更新页):
|
|
189
192
|
|
|
@@ -216,7 +219,7 @@ for (const [name, handler] of Object.entries(multi.handlers)) registry.set(name,
|
|
|
216
219
|
```
|
|
217
220
|
|
|
218
221
|
五个批量电话(`<prefix>` 即上面的 `life`):`batchStatus` / `batchCheck` / `batchInstall` / `batchResume` / `batchCancel`;
|
|
219
|
-
|
|
222
|
+
每个目标的四个单插件电话照旧以**各自前缀**暴露(`ilife-bill.updateStatus` 等)。
|
|
220
223
|
|
|
221
224
|
回包形状(成功恰好四项,失败只有三项):
|
|
222
225
|
|
|
@@ -233,7 +236,7 @@ import { mountUpdateBatchPanel } from 'dsh-plugin-update/panel-batch'
|
|
|
233
236
|
const panel = mountUpdateBatchPanel(el, {
|
|
234
237
|
prefix: 'life',
|
|
235
238
|
call: (name, args) => host.call(name, args),
|
|
236
|
-
theme: '
|
|
239
|
+
theme: 'archive', // 与单插件面板同一套皮肤(archive = 档案卷,旧值 d5-paper 仍可用)
|
|
237
240
|
})
|
|
238
241
|
```
|
|
239
242
|
|
|
@@ -301,7 +304,7 @@ const panel = mountUpdatePanel(document.getElementById('update-slot'), {
|
|
|
301
304
|
|
|
302
305
|
宿主种类与安装出口都由本包自己探测和选择,**升级依赖即可,宿主侧与面板侧都不用改代码**:
|
|
303
306
|
|
|
304
|
-
1. 依赖版本提到 `^0.
|
|
307
|
+
1. 依赖版本提到 `^0.5.1`。
|
|
305
308
|
2. 重新装 / 发一版你自己的插件,让新依赖进当前使用范围(运行时用的是 `node_modules` 里那份)。
|
|
306
309
|
3. 如果你自己接过一版宿主安装出口,把它删掉——它会挡在本包的路由前面。
|
|
307
310
|
|
|
@@ -474,7 +477,7 @@ dsh plugin --profile my-web add --save-exact my-notes-plugin@1.2.3 --registry=ht
|
|
|
474
477
|
|
|
475
478
|
照第 2 节把名字换成自己的之后,逐条打勾:
|
|
476
479
|
|
|
477
|
-
1. 宿主启动不报错,`update.phoneNames`
|
|
480
|
+
1. 宿主启动不报错,`update.phoneNames` 读到自家前缀的四个电话名,查状态返回六字段快照。
|
|
478
481
|
2. 面板按间隔轮询到快照,能展示第 5.2 节的原因文案;有新版时安装按钮可用,无新版与待重启时按钮状态正确。
|
|
479
482
|
3. 模拟一次 `pending-restart` 能看到第 5.4 节的横幅,模拟一次自动装失败能看到第 5.3 节的命令可复制执行。
|
|
480
483
|
4. 第二家同机隔离与串行:两家各传自己的插件标识与电话名前缀,电话名、落盘目录、锁文件逐个不同;安装执行跨插件串行——同范围撞上时后到者报 `update-busy`,凭队列位置(第 5.7 节)重试。
|
package/dist/changelog-io.d.ts
CHANGED
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
* - 已装版离线读:`node_modules/<目标包>/CHANGELOG.md`(与版本 pin 绑定,零新增联网);
|
|
10
10
|
* - 新版按需取:新版 tarball 内同名文件,复用官方源 + integrity 校验;
|
|
11
11
|
* 取不到一律回 null(调用方渲染中性提示,不挡安装、不写 blockedReason)。
|
|
12
|
+
*
|
|
13
|
+
* 记住策略(#41 终裁,三墙不动,只澄清注释):成功与取不到(null)按版本永久记
|
|
14
|
+
* (面板内存会话级 + 宿主进程级,不落盘,显式文本永不覆盖);传输失败不进缓存,
|
|
15
|
+
* 手动查新版/换版/重开面板立即重问,轮询按退避问(三处共用 shouldFetchChangelog,各存各的)。
|
|
16
|
+
* 三墙(8MB 压缩态/32MB 解压后/64K 日志文本)一字不动,超限回 null 由调用方按取不到记住。
|
|
12
17
|
*/
|
|
13
18
|
/** tarball 下载上限(字节,压缩态):超限直接回落中性提示,不解包、不OOM。 */
|
|
14
19
|
export declare const CHANGELOG_TARBALL_MAX_BYTES: number;
|
package/dist/changelog.d.ts
CHANGED
|
@@ -9,14 +9,16 @@
|
|
|
9
9
|
* 解析只做字符串切分,不读盘、不联网;版本语义与核心同口径
|
|
10
10
|
* (validReleaseVersion / compareReleaseVersions,stable 纯三段、prerelease 显式)。
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
* - `Added/Fixed/Changed`
|
|
12
|
+
* 面板约定(#23 原文 + #41 四处优化终裁):
|
|
13
|
+
* - `Added/Fixed/Changed/Security` 必显展开;`Deprecated/Removed` 透传折叠;
|
|
14
14
|
* - `Unreleased` 与空节忽略;
|
|
15
15
|
* - 缺日志中性提示,不挡安装、不写 blockedReason、不动快照六字段
|
|
16
16
|
* (本模块不碰快照,面板只增一节 HTML,安装门控只跟快照);
|
|
17
17
|
* - 已装版离线读、新版按需取 tarball 同名文件复用官方源 integrity
|
|
18
18
|
* (I/O 在 `src/changelog-io.ts` Node 侧,取不到回落中性提示);
|
|
19
|
-
* -
|
|
19
|
+
* - 纯函数解析器(仅复用版本语义,不碰 Node 专属;新增 validate 与策略函数零新增导入)。
|
|
20
|
+
* - 截断数值不动(100 节/每类 200 条/单条 500 字/全文 64K),解析附计数元数据只记数字;
|
|
21
|
+
* 超限类标计数小字,Security 超限进内折叠;BREAKING 前缀识别 + 行首徽标;yanked 横幅只看 to 版。
|
|
20
22
|
*/
|
|
21
23
|
/** 包内日志文件名(包根,与 tarball 内同名文件同一名字)。 */
|
|
22
24
|
export declare const CHANGELOG_FILENAME = "CHANGELOG.md";
|
|
@@ -54,6 +56,8 @@ export interface ChangelogEntry {
|
|
|
54
56
|
yanked: boolean;
|
|
55
57
|
/** 六类各自的条目(空类为空数组,空节忽略由渲染层执行)。 */
|
|
56
58
|
sections: Record<ChangelogCategory, string[]>;
|
|
59
|
+
/** 每类原始条数(截断前计数,只记数字不留文本;缺省视为与 sections 等长)。 */
|
|
60
|
+
counts?: Record<ChangelogCategory, number>;
|
|
57
61
|
}
|
|
58
62
|
/** 是否 Unreleased(大小写不敏感,前后空白忽略)。 */
|
|
59
63
|
export declare function isUnreleasedVersion(v: unknown): boolean;
|
|
@@ -62,6 +66,41 @@ export declare function isUnreleasedVersion(v: unknown): boolean;
|
|
|
62
66
|
* 非字符串/空串回 [];超长截断后解析;未知版本标题与其下条目一律丢弃;
|
|
63
67
|
* 全空节版本直接丢弃(空节忽略);Unreleased 保留(渲染与区间时忽略)。
|
|
64
68
|
*/
|
|
69
|
+
/** 共享扫描仪(parse 与 validate 同一套,不许第二套正则)。 */
|
|
70
|
+
export declare const RE_VERSION_HEADING: RegExp;
|
|
71
|
+
export declare const RE_CATEGORY_HEADING: RegExp;
|
|
72
|
+
export declare const RE_BULLET: RegExp;
|
|
73
|
+
export declare const RE_FENCE_TOGGLE: RegExp;
|
|
74
|
+
export declare const RE_VERSION_NUM: RegExp;
|
|
75
|
+
export declare const RE_VERSION_DATE: RegExp;
|
|
76
|
+
export declare const RE_YANKED: RegExp;
|
|
77
|
+
export declare const RE_UNRELEASED: RegExp;
|
|
78
|
+
export declare function matchVersionHeading(line: unknown): string | null;
|
|
79
|
+
export declare function matchCategoryHeading(line: unknown): string | null;
|
|
80
|
+
export declare function matchBulletBody(line: unknown): string | null;
|
|
81
|
+
export declare function isFenceToggle(line: unknown): boolean;
|
|
82
|
+
/** 破坏标记徽标文案(中文 UI 一致,原文前缀另行加粗保留)。 */
|
|
83
|
+
export declare const BREAKING_BADGE_TEXT = "\u4E0D\u517C\u5BB9";
|
|
84
|
+
/** 剥行首 markdown 装饰(加粗/引用/前后空白),只为识别,渲染保留原文一字不动。 */
|
|
85
|
+
export declare function stripBreakingDecorations(s: unknown): string;
|
|
86
|
+
/** 条目是否为破坏标记(去饰后开头匹配,大小写不敏感,中英文冒号皆可)。 */
|
|
87
|
+
export declare function isBreakingChangelogItem(item: unknown): boolean;
|
|
88
|
+
/** 拆出破坏前缀(保留原文拼写与冒号),命中才回,否则 null。 */
|
|
89
|
+
export declare function splitBreakingPrefix(item: string): {
|
|
90
|
+
head: string;
|
|
91
|
+
prefix: string;
|
|
92
|
+
rest: string;
|
|
93
|
+
} | null;
|
|
94
|
+
/** 轮询退避(毫秒):传输失败后轮询按此退避,手动/换版/重开立即重问。 */
|
|
95
|
+
export declare const CHANGELOG_POLL_BACKOFF_MS: number;
|
|
96
|
+
/** 三处共用(宿主电话/单面板/批量按行,各存各的):成功与取不到已记住即不再问。 */
|
|
97
|
+
export declare function shouldFetchChangelog(opts: {
|
|
98
|
+
hasCache: boolean;
|
|
99
|
+
failedAt: number | null;
|
|
100
|
+
now: number;
|
|
101
|
+
isManual: boolean;
|
|
102
|
+
backoffMs?: number;
|
|
103
|
+
}): boolean;
|
|
65
104
|
export declare function parseChangelog(markdown: unknown): ChangelogEntry[];
|
|
66
105
|
/** 该节是否有可见内容(六类任一非空)。 */
|
|
67
106
|
export declare function hasVisibleSections(entry: ChangelogEntry | null | undefined): boolean;
|
|
@@ -81,6 +120,14 @@ export declare function selectChangelogEntries(entries: unknown, fromExclusive:
|
|
|
81
120
|
* 任一缺失/非法即回 [](调用方渲染中性提示,不挡安装)。
|
|
82
121
|
*/
|
|
83
122
|
export declare function changelogForUpdate(entries: unknown, runningVersion: unknown, latestVersion: unknown, installedVersion?: unknown): ChangelogEntry[];
|
|
123
|
+
/** 计数元数据取值(缺省视为与 sections 等长,只记数字)。 */
|
|
124
|
+
export declare function countsOf(entry: ChangelogEntry | null | undefined): Record<ChangelogCategory, number>;
|
|
125
|
+
/** 超限小字(诚实截断):共 M 条,仅显示前 N 条。 */
|
|
126
|
+
export declare function truncatedNoteHTML(total: number, shown: number): string;
|
|
127
|
+
/** 撤回横幅(只看 to 版,纯展示,不挡安装,文案冻结)。 */
|
|
128
|
+
export declare function yankedBannerHTML(version: unknown): string;
|
|
129
|
+
/** 单条目 HTML(含破坏标记徽标与前缀加粗,正文一字不动)。 */
|
|
130
|
+
export declare function renderChangelogItem(item: string): string;
|
|
84
131
|
/** 单节 HTML(调用方保证已过滤 Unreleased 与空节,本函数再兜底一次)。 */
|
|
85
132
|
export declare function renderChangelogSection(entry: ChangelogEntry): string;
|
|
86
133
|
/** 中性提示 HTML(缺日志、取不到、无区间内容时统一用它,不挡安装)。 */
|
|
@@ -94,3 +141,19 @@ export declare function renderChangelogHTML(entries: unknown, opts?: {
|
|
|
94
141
|
from?: string | null;
|
|
95
142
|
to?: string | null;
|
|
96
143
|
}): string;
|
|
144
|
+
/** 校验诊断(一行一码,行号为原文件 1-based,诊断按行号排序)。 */
|
|
145
|
+
export interface ChangelogDiagnostic {
|
|
146
|
+
line: number;
|
|
147
|
+
code: string;
|
|
148
|
+
hint: string;
|
|
149
|
+
}
|
|
150
|
+
export interface ChangelogValidation {
|
|
151
|
+
ok: boolean;
|
|
152
|
+
diagnostics: ChangelogDiagnostic[];
|
|
153
|
+
}
|
|
154
|
+
/** 校验提示文(与终裁码表一字对应,仅 CI/发布前用,运行时永不调用)。 */
|
|
155
|
+
export declare const CHANGELOG_VALIDATE_HINTS: Record<string, string>;
|
|
156
|
+
/** 疑似破坏误写(仅行首可疑,不报正文中间散文)。 */
|
|
157
|
+
export declare function isMaybeBreakingMisuse(bulletBody: unknown): boolean;
|
|
158
|
+
/** 纯校验(零新增导入,与 parse 共享扫描仪,永不抛错,仅 CI/发布前用)。 */
|
|
159
|
+
export declare function validateChangelog(markdown: unknown): ChangelogValidation;
|