refactor(chapter): PKG-CHAPTER-03 split runtime into typed lifecycle and view modules

This commit is contained in:
Harvey Zhao committed 2026-09-10 23:12:56 +08:00
1 parent a0286c4e95
commit 48660c4e12
23 files changed
+1207 -497

No files matched your search

@@ -0,0 +1,364 @@
{
"task": "PKG-CHAPTER-03",
"capturedAt": "2026-09-10T15:10:43.475Z",
"source": {
"chapters.ts": "92206f524624ac3a7304677b6a69fda88e62caeca52e1e530d746e51579d3a4d",
"index.ts": "83dc022253c0539587590f7a551e090684d1944dcb2010a76e8498a683e7ef36",
"progress.ts": "4a18d19ed703772d73622ea3fa9d433dbc2c6092ba244c9bb1ec727368996951",
"style.less": "3b5aebcad4c433f09261facab26a881617238ec37e9c0be7a368f3f8e980d66b",
"stylesheet.ts": "6ccd88b6d17127acf6f6c1f02a7fbb3a55d59f427d2d92c007bf658122abd51c",
"types.ts": "07c528f9753cc54c12211276f28ff01a5f6e8f1ef1451b2b534f2d6cfaa17ee9"
},
"package": {
"name": "artplayer-plugin-chapter",
"version": "1.1.0",
"archive": "artplayer-plugin-chapter.tgz",
"sha256": "2d4fd1331d1bb2eebe8456afce84bcbb9060bf727b38f3bf47a25e4eb4cb623f",
"files": {
"package/ARCHITECTURE.md": "ed62ae2dbcdc31a2bde2b471738139390efe73edc1c71854f4f65ca1f8120ac5",
"package/README.md": "9fa74ae131401f43276baff287916bce7f2374ebf2b696324436e2f20bc0ee6a",
"package/dist/artplayer-plugin-chapter.js": "6ac3dfe28f46084ac7caedd571b1a97dcee3cf9d708112f1b8bbd6566e1dc5c5",
"package/dist/artplayer-plugin-chapter.legacy.js": "6d9bff885412169e701670961aa00c2e46c4b42c9b9647ff4e6d198777d2a359",
"package/dist/artplayer-plugin-chapter.mjs": "26415cecab2c0198c566cef0232e20123413782d5bad7534a32939b3298617af",
"package/package.json": "0fd20d82a9ddec642da8b26467b45c6c3e443f188ed75e7de3004e48efd4f766",
"package/types/artplayer-plugin-chapter.d.ts": "80338946aea05020abd285daca133fddfc81bd8b800345b2c76548fb93a555a9"
}
},
"runtimeChecks": 23,
"knownTypeBlockers": 11,
"ciChecks": 61,
"browser": {
"startTime": "2026-09-10T15:10:44.220Z",
"duration": 24021.322,
"expected": 54,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"tests": [
{
"title": "published-only observations: blank title, NaN and once-only metadata are historical defects",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "candidate clears titles on blank chapters, zero hover and replacement",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "candidate rejects NaN and can recover after an invalid update",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "candidate releases only its listeners and DOM across multiple instances and early destruction",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "candidate ignores pending metadata initialization after immediate destroy",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "candidate deduplicates stylesheet injection while the document is loading",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "published-only observations: blank title, NaN and once-only metadata are historical defects",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "candidate clears titles on blank chapters, zero hover and replacement",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "candidate rejects NaN and can recover after an invalid update",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "candidate releases only its listeners and DOM across multiple instances and early destruction",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "candidate ignores pending metadata initialization after immediate destroy",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "candidate deduplicates stylesheet injection while the document is loading",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "published-only observations: blank title, NaN and once-only metadata are historical defects",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "candidate clears titles on blank chapters, zero hover and replacement",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "candidate rejects NaN and can recover after an invalid update",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "candidate releases only its listeners and DOM across multiple instances and early destruction",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "candidate ignores pending metadata initialization after immediate destroy",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "candidate deduplicates stylesheet injection while the document is loading",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "factory, registration, input normalization and safe title text",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "progress bars, real hover, title edges and boundary seek",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "sync update, Infinity, object identity, empty lists and invalid data",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "explicit source update and core-owned destruction",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "factory, registration, input normalization and safe title text",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "progress bars, real hover, title edges and boundary seek",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "sync update, Infinity, object identity, empty lists and invalid data",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "explicit source update and core-owned destruction",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "factory, registration, input normalization and safe title text",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "progress bars, real hover, title edges and boundary seek",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "sync update, Infinity, object identity, empty lists and invalid data",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "explicit source update and core-owned destruction",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "factory, registration, input normalization and safe title text",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "progress bars, real hover, title edges and boundary seek",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "sync update, Infinity, object identity, empty lists and invalid data",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "explicit source update and core-owned destruction",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "factory, registration, input normalization and safe title text",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "progress bars, real hover, title edges and boundary seek",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "sync update, Infinity, object identity, empty lists and invalid data",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "explicit source update and core-owned destruction",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "factory, registration, input normalization and safe title text",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "progress bars, real hover, title edges and boundary seek",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "sync update, Infinity, object identity, empty lists and invalid data",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "explicit source update and core-owned destruction",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "published: real playback, pause, seek, switch and destroy",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "candidate: real playback, pause, seek, switch and destroy",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "controlled HTTP media failure emits a real video error",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "Range, media identity and docs candidate routes",
"project": "chromium",
"browser": "153.0.8010.12",
"status": "passed"
},
{
"title": "published: real playback, pause, seek, switch and destroy",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "candidate: real playback, pause, seek, switch and destroy",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "controlled HTTP media failure emits a real video error",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "Range, media identity and docs candidate routes",
"project": "firefox",
"browser": "155.0",
"status": "passed"
},
{
"title": "published: real playback, pause, seek, switch and destroy",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "candidate: real playback, pause, seek, switch and destroy",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "controlled HTTP media failure emits a real video error",
"project": "webkit",
"browser": "26.6",
"status": "passed"
},
{
"title": "Range, media identity and docs candidate routes",
"project": "webkit",
"browser": "26.6",
"status": "passed"
}
]
}
@@ -0,0 +1,47 @@
# PKG-CHAPTER-03:以 TypeScript 拆分章节实现
## 实现
删除生产 JS 入口,直接迁移为严格 TS,避免先拆 JS 再重复迁移。实际维护地图见
[包内架构](../../packages/artplayer-plugin-chapter/ARCHITECTURE.md):入口拥有 player 集成和
事件生命周期,chapters 处理纯区间运算,progress 拥有 DOM/标题/进度,stylesheet 拥有全局样式。
内部类型从现有公开声明推导,无 any、全局忽略或运行时核心依赖;CSS 保持原样。
保留默认导出/工厂/注册 name、同步 update、参数默认值、调用方数组原地排序/补齐和对象引用、
Infinity end 替换、metadata 一次初始化和成功更新的 loaded setBar 事件。DOM/CSS 类名、
data 属性、标题纯文本和进度边界保持正常旧调用兼容,不引入新核心方法。
## 明确修复与兼容差异
| 原问题 | 当前行为及覆盖 |
| --- | --- |
| hover 进入空白 gap 或更新后显示上一章节标题 | 空白/零位置/替换/清空重置并隐藏标题;真实鼠标验证 |
| NaN 时间被渲染进 data/CSS | 非有限非法时间点沿用时间错误信息拒绝;Infinity end 仍合法 |
| 非有限媒体 duration 生成无效区间 | 等待正的有限 duration,输入保持不变;有限时间轴恢复后可显式更新 |
| destroy 后保留插件监听器和可更新的 DOM | 移除本插件三个回调及两个 DOM 根,保留其他订阅和实例;旧 result.update 成为无操作 |
| destroy(false) 保留插件活动 UI | 只删除本插件 UI/类名,保留核心播放器树,避免恢复过期章节 |
| 页面解析期间两次载入插件可重复注入 style | DOMContentLoaded 时重新核对 ID,once 监听;样式仍为全局并在销毁后保留 |
非法输入的部分变更时序不作为合法调用契约;已有合法数组变更经过新旧浏览器对照。
切源后的章节所有权保持显式 update,没有顺带新增自动重算策略。
## 验证
- 严格分包 TypeScript 检查通过;公开声明没有在本任务改形状,旧编译器消费继续通过原测试。
- 新增四项区间单元测试;完整 ci:check 共 61 项 Node/基线测试通过。
- 三浏览器源码 54 项通过;新增五个场景在 Chromium/Firefox/WebKit 各执行一次。
- `yarn build artplayer-plugin-chapter` 重建三格式 dist 与 docs/compiled;全部由脚本生成。
- `yarn test:package` 的真实 TS 构建、tarball 安装和 23 项运行时/公开属性形状对照通过。
精确历史类型诊断仍为 11 条,留给 PKG-CHAPTER-04/核心类型任务,不作为本任务已修复。
- 安装后候选文件再次运行三浏览器共 54 项通过,无重试/跳过;结果和指纹见
[执行记录](../baselines/chapter-migration-validation.json)。
试点发现 ENG-07 的构建快照缺根 tsconfig;本任务补复制根配置与资源声明,消费者隔离规则不变。
不添加新依赖,test:unit 新增章节用例入口。源码入口、类型及生成格式由已有仓库脚本管理。
## 接续与回退
本任务完成第一包自有运行时 TS 化和职责拆分,不代表 chapter 全部任务或核心已完成。
PKG-CHAPTER-04 继续公开类型/旧声明子路径/NodeNext 消费闭环,然后进入试点汇总。
任务 03/04 分工更新为实际执行顺序;全项目范围和兼容门槛保留。
未推送、未发布、未升级版本。回退用本任务的独立提交 revert,同时恢复源码和生成产物。
+4 -3
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。
状态:todo 182 / doing 0 / blocked 0 / done 32 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 181 / doing 0 / blocked 0 / done 33 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -134,8 +134,8 @@
| --- | --- | --- | --- | --- | --- | --- |
| PKG-CHAPTER-01 | artplayer-plugin-chapter<br>核对包契约与历史用法 | BASE-05 | chapters 时间区间、update、name 和进度 DOM 清单 | 源码/声明/README/demo/发布包差异已登记;公开形状和版本范围冻结 | M | done |
| PKG-CHAPTER-02 | artplayer-plugin-chapter<br>建立特有行为与错误测试 | PKG-CHAPTER-01, ENG-03, ENG-05 | 区间重叠/空列表/边界 seek、hover 标题和 update 用例 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言;修正 BASE-TYPE-02 的可选参数声明并补正反例 | M | done |
| PKG-CHAPTER-03 | artplayer-plugin-chapter<br>整理内部职责与资源 | PKG-CHAPTER-02, ENG-07 | 在已有核心上整理时间区间计算、进度 DOM、事件/布局,合理简单代码可保持 | 不依赖新核心方法或大范围设置重构;旧 API/事件和资源通过,必要适配限包内 | M | todo |
| PKG-CHAPTER-04 | artplayer-plugin-chapter<br>迁移自有源码和公开类型 | PKG-CHAPTER-03, ENG-04, ENG-06 | 基于既有公开核心类型的 Chapters/Option/Result 与 update 推导;JS/TS 工具链试点 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容;处理 BASE-TYPE-01/03,保持运行时和新旧 TS 模块解析消费 | M | todo |
| PKG-CHAPTER-03 | artplayer-plugin-chapter<br>以 TypeScript 拆分内部职责与资源 | PKG-CHAPTER-02, ENG-07 | 以严格 TS 拆分区间计算、进度 DOM、事件生命周期与样式注入;公开声明消费在 04 闭环 | 不依赖新核心方法或大范围设置重构;旧 API/事件和资源通过,必要适配限包内 | M | done |
| PKG-CHAPTER-04 | artplayer-plugin-chapter<br>迁移自有源码和公开类型 | PKG-CHAPTER-03, ENG-04, ENG-06 | 承接 03 的自有源码 TS 化,完善公开 Chapters/Option/Result 与 update 推导,关闭声明模块解析和旧消费差异 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容;处理 BASE-TYPE-01/03,保持运行时和新旧 TS 模块解析消费 | M | todo |
| PKG-CHAPTER-05 | artplayer-plugin-chapter<br>验证新旧核心和组合 | PKG-CHAPTER-04, CORE-22 | chapter + quality/thumbnail、移动和全屏进度场景 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | M | todo |
| PKG-CHAPTER-06 | artplayer-plugin-chapter<br>验证分发并同步文档 | PKG-CHAPTER-05, ENG-07 | chapter.js 示例、产物和变更记录 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | M | todo |
@@ -435,3 +435,4 @@
- ENG-07: [记录](changes/2026-09-10-ENG-07-package-consumers.md) [记录](baselines/package-validation.json)
- PKG-CHAPTER-01: [记录](changes/2026-09-10-PKG-CHAPTER-01-contract.md) [记录](baselines/chapter-contract.md)
- PKG-CHAPTER-02: [记录](changes/2026-09-10-PKG-CHAPTER-02-tests.md) [记录](baselines/chapter-validation.json)
- PKG-CHAPTER-03: [记录](changes/2026-09-10-PKG-CHAPTER-03-typescript-modules.md) [记录](baselines/chapter-migration-validation.json)
+4
View File
@@ -1,5 +1,9 @@
# 进度与证据
## 当前实施:PKG-CHAPTER-03 首包 TS 源码拆分完成
chapter 已从单体 JS 入口改为五个 TS 文件,区间、DOM、生命周期和样式职责清楚;修复标题、NaN、销毁和重复样式问题。61 项 Node/基线检查、源码及安装产物各 54 项三浏览器测试通过;三格式产物已生成。见 [交付](changes/2026-09-10-PKG-CHAPTER-03-typescript-modules.md)。当前 214 项,33 完成、181 待办。生产迁移:chapter 自有运行时已 TS 化,核心尚未开始。ENG-07 提交 a0286c4e;下一项 PKG-CHAPTER-04 公开类型与消费者闭环。
## 当前实施:ENG-07 打包消费入口完成
实际重建、打包、仓库外安装及 23 项运行时检查通过;安装产物三浏览器 39 项通过,ci:check 57 项通过。精确的 11 条历史类型诊断仍阻止严格发布检查,未作为发布豁免。见 [交付](changes/2026-09-10-ENG-07-package-consumers.md)。当前 214 项,32 完成、182 待办;生产源码 TS 迁移仍为零。下一项直接实施 PKG-CHAPTER-03 的 TS 模块拆分,再以 04 完成公开类型和消费者闭环。
+8 -5
View File
@@ -1176,7 +1176,7 @@
{
"id": "PKG-CHAPTER-03",
"phase": "5 包迁移:artplayer-plugin-chapter",
"title": "整理内部职责与资源",
"title": "以 TypeScript 拆分内部职责与资源",
"scope": [
"artplayer-plugin-chapter"
],
@@ -1184,11 +1184,14 @@
"PKG-CHAPTER-02",
"ENG-07"
],
"status": "todo",
"status": "done",
"risk": "M",
"deliverable": "在已有核心上整理时间区间计算、进度 DOM、事件/布局,合理简单代码可保持",
"deliverable": "以严格 TS 拆分区间计算、进度 DOM、事件生命周期与样式注入;公开声明消费在 04 闭环",
"acceptance": "不依赖新核心方法或大范围设置重构;旧 API/事件和资源通过,必要适配限包内",
"evidence": []
"evidence": [
"changes/2026-09-10-PKG-CHAPTER-03-typescript-modules.md",
"baselines/chapter-migration-validation.json"
]
},
{
"id": "PKG-CHAPTER-04",
@@ -1204,7 +1207,7 @@
],
"status": "todo",
"risk": "M",
"deliverable": "基于既有公开核心类型的 Chapters/Option/Result 与 update 推导;JS/TS 工具链试点",
"deliverable": "承接 03 的自有源码 TS 化,完善公开 Chapters/Option/Result 与 update 推导,关闭声明模块解析和旧消费差异",
"acceptance": "严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容;处理 BASE-TYPE-01/03,保持运行时和新旧 TS 模块解析消费",
"evidence": []
},