refactor(core): CORE-11 split media events and scope reconnect lifetimes

This commit is contained in:
Harvey Zhao committed 2026-09-11 03:19:52 +08:00
1 parent 5e31274f1d
commit b8039ad1f1
27 files changed
+4844 -475

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,41 @@
# CORE-11 媒体事件、ready 与重连
状态:完成;源码、构建、安装消费与本地三浏览器检查通过。
## 模块与生命周期
player/eventInit.ts 仅负责按原顺序装配;media/events 下分为 types、listen、forward、readiness、playback、reconnect 六个 TS 模块。转发仍使用原 proxy 和配置事件名,发出同一个原生 Event 对象。内部 Emitter 监听归实例作用域,销毁时只移除自己的监听,用户订阅和原 snapshot 顺序保留。
source/operation.ts 现在分开资源代次与切源操作。实例作用域拥有当前资源作用域,后者拥有 SourceOperation.scope 及重连等待。切源失败可以结束操作并拒绝调用方 Promise,同时保留当前资源的自动重连;新的 URL 赋值或 destroy 则释放整个旧资源作用域。不能把重连绑定在失败即释放的 switch 作用域上。
播放有效性同时捕获资源与操作身份,覆盖“失败切源已清除操作后,再开始播放并销毁”的组合路径;迟到 Promise 仍保留原值/拒绝,过期通知、play 和互斥暂停停止执行。
## 兼容和缺陷修正
- 保留 API-04/05/07:配置事件顺序、原 Event、ready 的正常顺序和次数、resize/mobile UI 顺序、loop 和 play 拒绝处理。
- 同一资源同时只排一个重试,保留第一条待处理错误。按原常量等待、保留原错误参数,最多按预算重试;canplay 重置预算。重试次数在开始该次重试时固定,避免同步代理 canplay 把错误回调的次数变成 0。
- 保留等待结束时读取 option.url 的行为,使应用能在 native error 回调更新重试目标;若该 getter 重入切换资源,旧任务立即退出。
- BASE-LIFE-07:旧待办重连在用户已换源后仍会重新加载并发 error。现在新 URL、canplay 或销毁会取消过期重试/失败通知;独立新资源使用新预算,恢复时移除 art-error。
- BASE-LIFE-08:旧 ready 流程在 control 回调销毁实例后仍能继续标记 isReady 并发 ready。现在每步 UI 检查关闭状态,停止后续 ready;用户其他事件订阅仍保留。
- 内部重连异步回调若抛错,通过 console.warn 带原异常报告,避免无人接收的 Promise 拒绝。直接用户 Emitter 回调的同步异常传播不统一吞掉。
## 验证与限制
test/media-events.test.js 通过真实 EventTarget 和受控计时验证预算、合并、资源代次、失败切源、恢复/销毁、UI 重入、同步代理和原错误身份;test/types/media-events.ts 验证最小媒体事件宿主。test/browser/media-events.spec.js 使用真实 HTTP 503 与本地媒体恢复,比较发布/候选,并验证 Android UA 元数据路径。
媒体事件没有资源 ID。第三方 customType/proxy 已启动的外部 SDK 任务及其伪装成当前资源的事件仍由适配器管理;这里不宣称能取消任意外部代码。UA 检查不是实体移动设备验收。
证据见 [media-events-validation.json](../baselines/media-events-validation.json),包括完整源码/测试/包文件 SHA、实际安装消费者和逐项浏览器结果。
| 验证 | 结果 |
| --- | --- |
| yarn ci:check | 158 项:129 单元、4 工程、25 基线;54 个生产 TS 文件严格编译 |
| 媒体事件专项 | 新增 13 项 Node,涵盖 EventTarget、定时器、源/操作生命周期及真实 playMix |
| 安装包 | 核心/chapter 的 27 项运行时通过;五组类型模式零诊断 |
| 安装 UMD | 三浏览器 222 项通过,无跳过、重试或 flaky |
| 安装 legacy | 同套三浏览器 222 项通过,无跳过、重试或 flaky |
| 新旧差异 | 真实 HTTP 恢复/旧重连取消、ghost ready、移动 UA 顺序均有发布/候选对照 |
BASE-LIFE-07/08 已关闭,旧发布基线未改。HTTP 503 是受控失败,产生的请求/控制台记录保留在原始浏览器证据;未处理 JS 异常为零。早期通过报告不替代包含源级播放守卫的最终包指纹与完整复验。
未运行远端 CI、实体设备或所有生态包的发布验收。无依赖、锁文件或版本变化;本任务单独本地 commit。回退须连同 source/operation 的资源代次改动、事件模块、产物和文档整体回退。
+3 -2
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。
状态:todo 168 / doing 0 / blocked 0 / done 46 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 167 / doing 0 / blocked 0 / done 47 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -114,7 +114,7 @@
| CORE-08 | artplayer<br>整理插件管理器与扩展类型 | CORE-03, CORE-07 | 注册流程、同步/异步结果、插件/事件扩展接口 | 旧插件同步可见性、重名与命名、销毁中异步插件保持明确语义;处理 baselines/lifecycle-coverage.md 的 BASE-LIFE-03 并增加候选正向回归;接续 CORE-07 / BASE-TYPE-04 的同步/异步注册返回声明冲突,内部返回类型精确,保留历史消费者 | H | done |
| CORE-09 | artplayer<br>整理 URL 与切源操作 | CORE-04, CORE-06, CORE-08 | url/switch/customType 的操作身份及取消方案 | 并发切源、错误、同 URL、销毁和 Promise 结算有契约;处理 baselines/lifecycle-coverage.md 的 BASE-LIFE-01/02/06 并增加候选正向回归 | H | done |
| CORE-10 | artplayer<br>迁移播放与时间/状态属性 | CORE-09 | play/pause/toggle/seek/volume/rate/duration 等模块 | 旧返回值、拒绝、mutex、位置恢复、属性描述符与事件通过;接续 CORE-07 / BASE-TYPE-04 的 toggle void 与实际 Promise 分支冲突,不吞拒绝 | H | done |
| CORE-11 | artplayer<br>整理媒体事件、ready 与重连 | CORE-10 | 媒体转发、重连、UI 响应职责分离 | readiness 次数/顺序、过期重连、原错误参数有回归 | H | todo |
| CORE-11 | artplayer<br>整理媒体事件、ready 与重连 | CORE-10 | 媒体转发、重连、UI 响应职责分离 | readiness 次数/顺序、过期重连、原错误参数有回归 | H | done |
| CORE-12 | artplayer<br>迁移模板及公开资源入口 | CORE-06, CORE-04, BASE-04 | template/icons/i18n/style、SSR 与 proxy 挂载 | DOM/CSS/global/样式注入、i18n 子路径及 SSR import 保持;不把 SSR import/useSSR 保持扩大为服务端构造播放器;复跑 BASE-05 的 SSR import/模板、浏览器 useSSR 节点复用和非浏览器构造错误;接续 VENDOR-01/02,核对 screenfull/hint 复制版本、修改与分发通知,保留 DOM/CSS/fullscreen 行为 | H | todo |
| CORE-13 | artplayer<br>迁移组件注册与控件 | CORE-12, CORE-08 | Component/control/layer/contextmenu 的资源与 TS 边界 | add/update/remove、name、selector、mounted/beforeUnmount 通过;处理 BASE-DOM-02 窄容器控件裁切,保留 controls.update 的旧 undefined 返回值 | H | todo |
| CORE-14 | artplayer<br>拆分设置树、渲染和布局 | CORE-13 | setting model/selection/render/layout 的分批实现 | 不强行统一控件返回值,嵌套选择、默认高亮、更新清理通过;结合 BASE-DOM-02 验证窄容器设置定位;接续 BASE-TYPE-07 的 find null、add/update item、remove undefined 声明冲突 | H | todo |
@@ -445,6 +445,7 @@
- CORE-08: [记录](changes/2026-09-11-CORE-08-plugin-manager.md) [记录](baselines/plugins-validation.json)
- CORE-09: [记录](changes/2026-09-11-CORE-09-source-operations.md) [记录](baselines/source-operations-validation.json)
- CORE-10: [记录](changes/2026-09-11-CORE-10-playback-properties.md) [记录](baselines/playback-properties-validation.json)
- CORE-11: [记录](changes/2026-09-11-CORE-11-media-events.md) [记录](baselines/media-events-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 @@
# 进度与证据
## 当前实施:CORE-11 媒体事件、ready 与重连完成
事件入口迁移 TS,拆出转发、ready、播放 UI、重连、订阅和宿主类型;资源代次与切源操作分离,失败切源仍可重试,换源/恢复/销毁取消过期工作。158 项 Node/基线、安装 UMD 与 legacy 各 222 项三浏览器、打包 27 项运行时及五组类型检查通过。见 [交付](changes/2026-09-11-CORE-11-media-events.md)。关闭新增 BASE-LIFE-07/08,保留原 Event、重试次数和正常 ready 顺序;第三方 SDK 事件仍由适配器负责。当前 214 项,47 完成、167 待办;核心 49 个 TS 文件、chapter 5 个。下一项 CORE-12 模板及公开资源入口。
## 当前实施:CORE-10 播放与时间/状态属性完成
八个 mixin 迁移 TS,新增最小播放属性宿主;保持转换、通知、存储、进度和状态优先级。新增 PlaybackControls 精确视图,旧 toggle 声明仍兼容。145 项 Node/基线、安装 UMD 与 legacy 各 195 项三浏览器、打包 27 项运行时和五组类型检查通过。见 [交付](changes/2026-09-11-CORE-10-playback-properties.md)。发现 BASE-TYPE-08 的只写属性虚构 getter 声明,已交 CORE-21;没有添加运行时 getter 来掩盖它。当前 214 项,46 完成、168 待办;核心 42 个 TS 文件、chapter 5 个。下一项 CORE-11 媒体事件、ready 与重连。
+2
View File
@@ -52,3 +52,5 @@
| BASE-TYPE-06 | resolved / 已复现 | Public Option requires url and excludes numeric control HTML accepted by existing JS | CORE-07 |
| BASE-TYPE-07 | open / 已复现 | Setting returns, subtitle contextual payloads and notice getter conflict with historical declarations | CORE-07, CORE-14, CORE-15, CORE-18, CORE-21 |
| BASE-TYPE-08 | open / 已复现 | Write-only player commands have fictitious public getter declarations | CORE-21 |
| BASE-LIFE-07 | resolved / 已复现 | Queued reconnect survives source replacement and reloads the new resource | CORE-11 |
| BASE-LIFE-08 | resolved / 已复现 | Ready continues after a control callback destroys the instance | CORE-11 |
+46
View File
@@ -891,6 +891,52 @@
],
"compatibleResolution": "Keep historical consumer acceptance, model source command reads as undefined, and provide an accurate public facade without inventing runtime getters.",
"closureCriteria": "seek/forward/backward/switch/quality reads and writes have an explicit accurate compatibility strategy validated against old TypeScript consumers and real package descriptors."
},
{
"id": "BASE-LIFE-07",
"title": "Queued reconnect survives source replacement and reloads the new resource",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"CORE-11"
],
"evidence": [
"test/media-events.test.js",
"test/browser/media-events.spec.js",
"refactor/changes/2026-09-11-CORE-11-media-events.md"
],
"compatibleResolution": "Keep ordinary event order and error identity; scope retries to the current source and stop internal UI/ready work when its instance closes.",
"closureCriteria": "Real published/candidate regression comparisons, controlled lifecycle tests and installed UMD/legacy validation pass without altering the frozen published baseline.",
"resolutionEvidence": [
"refactor/changes/2026-09-11-CORE-11-media-events.md",
"refactor/baselines/media-events-validation.json",
"test/media-events.test.js",
"test/browser/media-events.spec.js"
],
"resolutionRationale": "Published/candidate real-browser comparisons reproduce stale retry or ghost ready and validate candidate cancellation. Owned source lifetimes preserve retries after switch rejection, while instance closure stops UI work; original Event/count and ordinary readiness order remain tested."
},
{
"id": "BASE-LIFE-08",
"title": "Ready continues after a control callback destroys the instance",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"CORE-11"
],
"evidence": [
"test/media-events.test.js",
"test/browser/media-events.spec.js",
"refactor/changes/2026-09-11-CORE-11-media-events.md"
],
"compatibleResolution": "Keep ordinary event order and error identity; scope retries to the current source and stop internal UI/ready work when its instance closes.",
"closureCriteria": "Real published/candidate regression comparisons, controlled lifecycle tests and installed UMD/legacy validation pass without altering the frozen published baseline.",
"resolutionEvidence": [
"refactor/changes/2026-09-11-CORE-11-media-events.md",
"refactor/baselines/media-events-validation.json",
"test/media-events.test.js",
"test/browser/media-events.spec.js"
],
"resolutionRationale": "Published/candidate real-browser comparisons reproduce stale retry or ghost ready and validate candidate cancellation. Owned source lifetimes preserve retries after switch rejection, while instance closure stops UI work; original Event/count and ordinary readiness order remain tested."
}
]
}
+5 -2
View File
@@ -949,11 +949,14 @@
"dependsOn": [
"CORE-10"
],
"status": "todo",
"status": "done",
"risk": "H",
"deliverable": "媒体转发、重连、UI 响应职责分离",
"acceptance": "readiness 次数/顺序、过期重连、原错误参数有回归",
"evidence": []
"evidence": [
"changes/2026-09-11-CORE-11-media-events.md",
"baselines/media-events-validation.json"
]
},
{
"id": "CORE-12",