mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-15 00:56:16 -08:00
refactor(core): CORE-04 scope initialization and make destruction reentrant-safe
This commit is contained in:
1 parent
3e38dd0d19
commit
4eec8112fa
32 files changed
+2779
-189
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,68 @@
|
||||
# CORE-04:构造回滚与可靠销毁
|
||||
|
||||
## 核心改动
|
||||
|
||||
核心 index.js 已直接接入 lifecycle/instance.ts,实例状态保存在 WeakMap,不增加公开属性。
|
||||
正常构造顺序不变;Template 在修改容器前保留原 DOM,成功后丢弃回滚引用。
|
||||
template-rollback.ts 按原节点、子节点顺序、文本和属性恢复失败挂载,保留旧 DOM 监听和
|
||||
SSR 节点身份。容器在初始化阶段就被预留,避免实例尚未进入注册表时被重入构造占用。
|
||||
|
||||
Events 在安装第一个监听前注册清理,覆盖 new Events 中途失败、art.events 尚未赋值的情况。
|
||||
构造失败会释放已接入的资源、移除实例、标记 isDestroy、发出 destroy 供已有插件清理,
|
||||
并恢复原容器。原始构造错误保持身份和传播,清理错误独立报告。
|
||||
失败回滚结束前保留容器归属,防止 cleanup 回调中的新挂载被旧回滚覆盖;正常 destroy 事件前
|
||||
释放容器,允许该回调创建替代实例。对应回归同时验证两种路径,旧实例重复销毁不影响替代实例。
|
||||
|
||||
destroy 通过内部防重入状态保护整个过程,包括 reset 内触发的重入。正常顺序保持
|
||||
reset → 资源/DOM 监听清理 → template → instances 移除 → isDestroy=true → destroy 事件。
|
||||
reset 中观察到的公开 isDestroy 仍为 false;destroy 回调观察到 true、已移除注册且 DOM
|
||||
符合 removeHtml。重复调用不再改变任何状态,因此 destroy(false) 后再 destroy(true)
|
||||
也不清空保留节点或新的播放器。instances.indexOf 为 -1 时绝不 splice。
|
||||
|
||||
每个内部清理阶段独立执行,失败不会阻断注册表清理和 destroy 派发;第一个错误原样抛出,
|
||||
额外错误报告到 console.warn。Emitter 内单次派发的“抛错停止后续订阅”契约保持;不能借此
|
||||
改动普通 emit。核心资源清理已不单靠 destroy 订阅,因此用户监听抛错不会阻止这些清理。
|
||||
|
||||
## 延迟任务归属
|
||||
|
||||
- resize 防抖改为作用域拥有的 timeout,保留正常合并行为;销毁立即取消等待中的 burst。
|
||||
- Info 循环、update RAF、setting mounted 回调接入作用域;Notice 销毁释放 timer,关闭后不接受新提示。
|
||||
- customType/空 URL、quality 初始化和 reconnect 使用 wait(scope),取消时兑现 false,
|
||||
正常保留 timer → Promise microtask 的顺序;await 后再次检查 closed,覆盖定时器已完成但
|
||||
continuation 尚未运行时发生销毁的竞态。
|
||||
- Events.proxy 的真实 callback、返回 disposer 和 destroyEvents 形状保持;关闭后新增注册返回空清理函数。
|
||||
|
||||
不引入依赖,不改变 Yarn、版本或公开类型入口。内部新增两个 TS 文件;入口及被接入的 JS
|
||||
模块保留渐进迁移,完整入口 TS 收敛属于 CORE-20。
|
||||
|
||||
## 兼容性差异与风险
|
||||
|
||||
API-01/03/04/05/07/08/10:保留公开属性、正常事件顺序、同步返回、removeHtml 和分发路径。
|
||||
BASE-LIFE-04 的误删其他实例、BASE-LIFE-05 的失败构造 DOM/监听残留以及 BASE-PERF-01 的
|
||||
销毁后 resize 重建 notice timer 是有意修复的缺陷。冻结发布基线不改,新增旧版观察和候选正向断言。
|
||||
构造过程中插件主动同步 destroy 的实例不进入注册表。
|
||||
|
||||
这里的 DOM 回滚不承诺恢复任意用户 callback 的外部副作用、存储、原生媒体状态或外部节点。
|
||||
也不表示全部媒体功能的资源已经迁移:字幕请求/URL 为 CORE-15,progress/thumbnail 为
|
||||
CORE-19,view throttle 为 CORE-17,内置插件延迟工作为 CORE-18,切源 Promise 为 CORE-09,
|
||||
异步插件兑现为 CORE-08。它们仍须在对应任务完成,不能因本任务通过而提前允许发布。
|
||||
|
||||
## 验证
|
||||
|
||||
- yarn ci:check:71 项单元、4 项工程、24 项冻结基线,共 99 项;严格源类型检查 17 个 TS 文件。
|
||||
- 四项内部实例测试覆盖销毁顺序、reset 重入/抛错、destroy 监听错误身份及微任务竞态;
|
||||
资源测试增加 wait 完成/取消结算。
|
||||
- 安装 UMD 候选三浏览器完整 108 项通过,无重试/跳过,包括 30 项生命周期对照/修复场景。
|
||||
覆盖真实媒体播放/切源、正常 resize、pending resize/notice/RAF/reconnect/mounted、
|
||||
插件初始化/清理同时失败、早期 proxy 失败、SSR、Events 半初始化失败、重复/重入销毁、重入容器预留和同步关闭构造。
|
||||
- 安装 legacy 候选另跑三个浏览器 30 项生命周期验证;按实际产物映射加载,没有源码回退。
|
||||
- yarn build artplayer / yarn build:i18n 生成 dist 与 docs/compiled。
|
||||
- yarn test:package:release:仓库外实际安装 tarball,27 项运行时和五组类型消费者零诊断。
|
||||
包内架构文档更新后重新打包,并核对浏览器候选 JS 与最终包成员指纹一致。
|
||||
|
||||
证据见 [验证报告](../baselines/instance-lifecycle-validation.json);持续维护地图见
|
||||
[核心架构](../../packages/artplayer/ARCHITECTURE.md)。早期本地测试曾被 ESLint 自动改为未安装
|
||||
的 Vitest 导入,已恢复仓库 Node runner 并明确局部 lint 说明,没有添加另一个测试框架。
|
||||
|
||||
本任务独立提交;回退整个提交可同时恢复源码、生成产物、测试与台账。未推送或发布。
|
||||
下一项 CORE-05 区分输入配置与内部配置,再继续核心类型和模块迁移。
|
||||
+3
-2
@@ -4,7 +4,7 @@
|
||||
|
||||
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。
|
||||
|
||||
状态:todo 175 / doing 0 / blocked 0 / done 39 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
|
||||
状态:todo 174 / doing 0 / blocked 0 / done 40 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
|
||||
|
||||
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
| CORE-01 | artplayer<br>迁移纯工具并冻结导出 | ENG-03, ENG-04, ENG-06, PILOT-01 | utils/time/property/format/file/error/subtitle 的分批 TS 迁移 | Artplayer.utils 导出/参数/绑定保持,纯逻辑与类型测试通过 | M | done |
|
||||
| CORE-02 | artplayer<br>迁移内部 Emitter | CORE-01, BASE-03 | 带类型事件映射的原 Emitter 实现 | ctx、once/off、重入/异常和链式返回保持 | H | done |
|
||||
| CORE-03 | artplayer<br>建立内部资源作用域 | CORE-02 | 监听/订阅/定时器/RAF/请求/URL 的资源登记 | 实例与操作作用域分离,单项清理失败不阻断其他资源 | H | done |
|
||||
| CORE-04 | artplayer<br>修复初始化与销毁生命周期 | CORE-03, ENG-05, BASE-07 | 构造失败回收、重复/重入 destroy、instances 修复 | 事件顺序、removeHtml、多实例和销毁中异步有真实回归;处理 baselines/lifecycle-coverage.md 的 BASE-LIFE-04/05 并增加候选正向回归;协调 BASE-PERF-01 销毁后定时器与回调归属 | H | todo |
|
||||
| CORE-04 | artplayer<br>修复初始化与销毁生命周期 | CORE-03, ENG-05, BASE-07 | 构造失败回收、重复/重入 destroy、instances 修复 | 事件顺序、removeHtml、多实例和销毁中异步有真实回归;处理 baselines/lifecycle-coverage.md 的 BASE-LIFE-04/05 并增加候选正向回归;协调 BASE-PERF-01 销毁后定时器与回调归属 | H | done |
|
||||
| CORE-05 | artplayer<br>区分输入配置和内部配置 | CORE-01, ENG-04 | Option/ResolvedOption、默认值与校验整理 | 配置合并/错误时机不变,JS 输入仍运行时校验 | M | todo |
|
||||
| CORE-06 | artplayer<br>建立内部媒体与宿主类型 | CORE-05 | 原生 video、canvas shim、UI host 类型 | 不更改公开 art.video 用法,不以 HTMLVideoElement 断言掩盖 shim | M | todo |
|
||||
| CORE-07 | artplayer<br>逐项协调公开声明差异 | CORE-02, CORE-06, BASE-07 | plugins/toggle/cue/setting/static 的旧新类型对照 | 每项有兼容重载/扩展或待决结论,不能删除旧类型样例;处理 BASE-TYPE-01/04,分别保留旧合法声明消费并验证真实返回;协调 BASE-TYPE-05 的 Utils 导出、descriptor 和 timer 旧声明差异 | H | todo |
|
||||
@@ -438,6 +438,7 @@
|
||||
- CORE-01: [记录](changes/2026-09-10-CORE-01-typed-utils.md) [记录](baselines/core-utils-validation.json)
|
||||
- CORE-02: [记录](changes/2026-09-11-CORE-02-typed-emitter.md) [记录](baselines/emitter-validation.json)
|
||||
- CORE-03: [记录](changes/2026-09-11-CORE-03-resource-scope.md) [记录](baselines/resource-scope-validation.json)
|
||||
- CORE-04: [记录](changes/2026-09-11-CORE-04-instance-lifecycle.md) [记录](baselines/instance-lifecycle-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)
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# 进度与证据
|
||||
|
||||
## 当前实施:CORE-04 构造/销毁生命周期完成
|
||||
|
||||
核心入口接入实例作用域,修复重复/重入销毁、失败构造回滚和 pending resize;正常 destroy 回调仍可挂载替代实例。99 项 Node/基线、安装 UMD 三浏览器 108 项及 legacy 三浏览器 30 项通过;严格打包 27 项运行时、五组类型零诊断。见 [交付](changes/2026-09-11-CORE-04-instance-lifecycle.md)。关闭 BASE-LIFE-04/05 与 BASE-PERF-01,字幕/异步插件等后续任务继续开放。当前 214 项,40 完成、174 待办;核心十二个 TS 文件、chapter 五个,主入口仍为 JS 兼容门面。下一项 CORE-05 输入与内部配置类型。
|
||||
|
||||
## 当前实施:CORE-03 内部资源作用域完成
|
||||
|
||||
新增两个核心 TS 文件,明确同步清理、实例/操作作用域、异常汇总及原生资源适配。94 项 Node/基线与 78 项三浏览器检查通过;首次 Firefox 图片缓存误判已保留并改为 fresh fetch 验证。见 [交付](changes/2026-09-11-CORE-03-resource-scope.md)。当前 214 项,39 完成、175 待办;核心十个 TS 文件、chapter 五个。作用域尚未接入播放器,旧生命周期风险仍开放;下一项 CORE-04 直接改构造与销毁。
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
| BASE-LIFE-01 | open / 已复现 | Superseded switch resolves along with the latest source | CORE-09 |
|
||||
| BASE-LIFE-02 | open / 已复现 | Switch remains unsettled during the bounded observation after destroy | CORE-09 |
|
||||
| BASE-LIFE-03 | open / 已复现 | Async plugin registers its result after destroy | CORE-08 |
|
||||
| BASE-LIFE-04 | open / 已复现 | Destroying an instance twice unregisters a different live instance | CORE-04 |
|
||||
| BASE-LIFE-05 | open / 已复现 | Failed constructor leaves initialized markup/listeners until explicit probe cleanup | CORE-04 |
|
||||
| BASE-LIFE-04 | resolved / 已复现 | Destroying an instance twice unregisters a different live instance | CORE-04 |
|
||||
| BASE-LIFE-05 | resolved / 已复现 | Failed constructor leaves initialized markup/listeners until explicit probe cleanup | CORE-04 |
|
||||
| BASE-DOM-01 | open / 已复现 | 控件 Tab 不可达 | CORE-23, CORE-17 |
|
||||
| BASE-DOM-02 | open / 已复现 | 窄容器中控件裁切 | CORE-13, CORE-14 |
|
||||
| BASE-DEMO-01 | open / 源码/产物事实 | 旧 thumbnail 插件示例不对应当前 workspace 包 | SITE-01, EX-03 |
|
||||
@@ -18,7 +18,7 @@
|
||||
| BASE-TYPE-03 | resolved / 已复现 | chapter legacy 缺旧模块解析的声明回退 | ENG-04, PKG-CHAPTER-04 |
|
||||
| BASE-TYPE-04 | open / 源码/产物事实 | plugins.add / toggle 的旧声明返回值与运行时不同 | CORE-07 |
|
||||
| BASE-DIST-01 | open / 源码/产物事实 | thumbnail tool 分发入口与类型文件缺失 | PKG-TOOL-THUMB-01, PKG-TOOL-THUMB-04 |
|
||||
| BASE-PERF-01 | open / 已复现 | 销毁后的 resize 防抖重新创建 notice timer | CORE-17, CORE-04, CORE-18 |
|
||||
| BASE-PERF-01 | resolved / 已复现 | 销毁后的 resize 防抖重新创建 notice timer | CORE-17, CORE-04, CORE-18 |
|
||||
| BASE-SOURCE-01 | open / 源码/产物事实 | 工作区 5.4.1 与采集时真实发布 5.4.0 不同 | BASE-08, REL-01 |
|
||||
| BASE-SOURCE-02 | open / 源码/产物事实 | registry gitHead 与发布包版本对应不可靠 | ENG-07, REL-01 |
|
||||
| BASE-SITE-01 | open / 源码/产物事实 | 文档站实际为静态站点但 manifest 未设 private | SITE-01, REL-01 |
|
||||
|
||||
+28
-7
@@ -2,7 +2,7 @@
|
||||
"schemaVersion": 1,
|
||||
"task": "BASE-07",
|
||||
"sourceCommit": "e01f39ff",
|
||||
"updatedAt": "2026-09-10T16:03:52.413Z",
|
||||
"updatedAt": "2026-09-11",
|
||||
"note": "Open means closure evidence is outstanding; source-observed and unverified are not reproduced runtime bugs. A source issue already mitigated in the workspace still requires candidate regression evidence. No accepted-with-scope item is implied by baseline task completion.",
|
||||
"items": [
|
||||
{
|
||||
@@ -71,7 +71,7 @@
|
||||
"id": "BASE-LIFE-04",
|
||||
"title": "Destroying an instance twice unregisters a different live instance",
|
||||
"confirmation": "reproduced",
|
||||
"status": "open",
|
||||
"status": "resolved",
|
||||
"owners": [
|
||||
"CORE-04"
|
||||
],
|
||||
@@ -80,13 +80,20 @@
|
||||
"refactor/baselines/lifecycle-coverage.md"
|
||||
],
|
||||
"compatibleResolution": "按对应 CORE 任务修复,保持合法旧调用;异步取消需明确结算策略,不把 pending 或重复销毁当正常兼容要求。",
|
||||
"closureCriteria": "候选正向回归和旧新差异记录通过;有界观察问题不得仅靠延长等待隐藏。"
|
||||
"closureCriteria": "候选正向回归和旧新差异记录通过;有界观察问题不得仅靠延长等待隐藏。",
|
||||
"resolutionEvidence": [
|
||||
"refactor/changes/2026-09-11-CORE-04-instance-lifecycle.md",
|
||||
"refactor/baselines/instance-lifecycle-validation.json",
|
||||
"test/browser/lifecycle.spec.js",
|
||||
"test/instance-lifecycle.test.js"
|
||||
],
|
||||
"resolutionRationale": "内部防重入与 index >= 0 检查保留其他实例;正常 destroy 回调可挂载替代实例,旧实例重复销毁不移除其 DOM。UMD 与 legacy 三浏览器通过。"
|
||||
},
|
||||
{
|
||||
"id": "BASE-LIFE-05",
|
||||
"title": "Failed constructor leaves initialized markup/listeners until explicit probe cleanup",
|
||||
"confirmation": "reproduced",
|
||||
"status": "open",
|
||||
"status": "resolved",
|
||||
"owners": [
|
||||
"CORE-04"
|
||||
],
|
||||
@@ -95,7 +102,14 @@
|
||||
"refactor/baselines/lifecycle-coverage.md"
|
||||
],
|
||||
"compatibleResolution": "按对应 CORE 任务修复,保持合法旧调用;异步取消需明确结算策略,不把 pending 或重复销毁当正常兼容要求。",
|
||||
"closureCriteria": "候选正向回归和旧新差异记录通过;有界观察问题不得仅靠延长等待隐藏。"
|
||||
"closureCriteria": "候选正向回归和旧新差异记录通过;有界观察问题不得仅靠延长等待隐藏。",
|
||||
"resolutionEvidence": [
|
||||
"refactor/changes/2026-09-11-CORE-04-instance-lifecycle.md",
|
||||
"refactor/baselines/instance-lifecycle-validation.json",
|
||||
"test/browser/lifecycle.spec.js",
|
||||
"test/instance-lifecycle.test.js"
|
||||
],
|
||||
"resolutionRationale": "失败构造释放已初始化的监听/已接入定时器并恢复原 DOM/SSR 节点;proxy、插件及 Events 半初始化失败和清理同时抛错均有真实浏览器回归。未迁移的字幕/SDK 等资源仍由对应任务验收。"
|
||||
},
|
||||
{
|
||||
"id": "BASE-DOM-01",
|
||||
@@ -251,7 +265,7 @@
|
||||
"id": "BASE-PERF-01",
|
||||
"title": "销毁后的 resize 防抖重新创建 notice timer",
|
||||
"confirmation": "reproduced",
|
||||
"status": "open",
|
||||
"status": "resolved",
|
||||
"owners": [
|
||||
"CORE-17",
|
||||
"CORE-04",
|
||||
@@ -261,7 +275,14 @@
|
||||
"refactor/baselines/performance.json"
|
||||
],
|
||||
"compatibleResolution": "为 debounce/晚到 UI 工作建立销毁归属;不靠等待自然过期掩盖。",
|
||||
"closureCriteria": "正常 resize 保持,destroy 后无该回调及新 notice timer。"
|
||||
"closureCriteria": "正常 resize 保持,destroy 后无该回调及新 notice timer。",
|
||||
"resolutionEvidence": [
|
||||
"refactor/changes/2026-09-11-CORE-04-instance-lifecycle.md",
|
||||
"refactor/baselines/instance-lifecycle-validation.json",
|
||||
"test/browser/lifecycle.spec.js",
|
||||
"test/instance-lifecycle.test.js"
|
||||
],
|
||||
"resolutionRationale": "resize timeout 由实例 scope 取消,正常 burst 合并保持;销毁后该 resize 不再执行,Notice timer 为 null,已排队 UI 工作不再重建提示。"
|
||||
},
|
||||
{
|
||||
"id": "BASE-SOURCE-01",
|
||||
|
||||
+5
-2
@@ -810,11 +810,14 @@
|
||||
"ENG-05",
|
||||
"BASE-07"
|
||||
],
|
||||
"status": "todo",
|
||||
"status": "done",
|
||||
"risk": "H",
|
||||
"deliverable": "构造失败回收、重复/重入 destroy、instances 修复",
|
||||
"acceptance": "事件顺序、removeHtml、多实例和销毁中异步有真实回归;处理 baselines/lifecycle-coverage.md 的 BASE-LIFE-04/05 并增加候选正向回归;协调 BASE-PERF-01 销毁后定时器与回调归属",
|
||||
"evidence": []
|
||||
"evidence": [
|
||||
"changes/2026-09-11-CORE-04-instance-lifecycle.md",
|
||||
"baselines/instance-lifecycle-validation.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "CORE-05",
|
||||
|
||||
Reference in new issue
Block a user