fix(site): [SITE-VCONSOLE-01] cancel stale console lifecycle work

This commit is contained in:
Harvey Zhao committed 2026-09-14 17:30:17 +08:00
1 parent 838c3eb432
commit e7f31b6fc8
22 files changed
+2318 -32

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,56 @@
# SITE-VCONSOLE-01: vConsole 销毁后的异步工作
## 问题与修复
SITE-07 的真实 mobile 页面发现 vConsole 3.15.0 销毁后更新已删除日志 store。
冻结 npm bundle 后,原生三引擎进一步确认三条独立路径:
- 最后一个日志插件移除时没有取消 RAF,也没有清空单例日志模型的旧队列。
`lifecycle.ts` 管理调度票据;先失效再取消,清空队列/标志,最后恢复 console。
被人为迟到交付的已取消回调也不能消费重建后的队列。
- core 的延迟面板插入以全局同名 DOM 查找目标,销毁后会报错,同名插件替换后会
把旧面板插入新插件。延迟回调现在核对原实例 isInited 和 plugin 对象身份。
- recycleScroller 的高度和条目尺寸异步续段在 timer 后访问已销毁的 Svelte 绑定
元素。两个续段现在在绑定元素为空时返回,保留正常布局路径。
## 结构、类型与兼容
`scripts/site-vendor/vconsole/upstream.js` 保留 npm 3.15.0 完整原字节,构建器校验
整个 SHA-256 及六个唯一替换位置。自有生命周期逻辑使用严格 TS,既有 TypeScript
5.9.3 和 esbuild 0.27.7 生成 ES5 私有辅助模块,不新增依赖或锁文件。
其余 bundle 字节、UMD 分支、CSS 和原 URL 保留;命名 AMD、CommonJS 和 browser
global 都有真实页面回归。没有改 ArtPlayer 核心/插件公开 API 或声明。
模块维护与重跑命令见 `scripts/site-vendor/vconsole/README.md`。
新增 `build:vconsole`、只读 `check:vconsole`、`test:vconsole`;接入根 Node 测试、
严格 docs-tools TS,以及 ci:check/ci:build 的 notices 前置顺序。生产 minified 文件
由生成器写出;manifest 与第三方台账分别保存上游和候选指纹。
## 验证记录
最终结果与输入指纹见 [机器证据](../baselines/vconsole-lifecycle-validation.json)。
原失败报告保留在 refactor/.cache,不能以最终通过覆盖:
- 最初原版 6 失败,首个仅日志补丁仍有面板异常;第二轮 9 项通过。
- 扩展原版回归 13 失败/2 通过中,AMD harness 错把命名 define 当匿名 define;
这是测试错误,已按冻结 UMD 原文改正,不计为产品缺陷。
- 扩展候选 17 通过/1 失败暴露间歇 scroller style 异常;没有扩大等待或吞掉错误。
- 原版 scroller 专项通过控制零延迟 timer 在三引擎稳定得到空节点 style 异常。
该轮 `.vc-log` 选择器错误也留档;仅改成 `.vc-log-row` 时,因为挂起了初始化,
仍没有日志行。正式测试先确认日志可见,再挂起 timer、改变 viewport 高度,
销毁前均有 21 条真实日志行;原版出现空节点异常,候选无异常。
- 最终同一测试:原版 12 失败/6 通过;候选含 mobile 播放 21 全通过。40 项单元/
CI 测试、严格 docs-tools TS、工具链、冻结安装、生成校验和定向 lint 通过。
根 lint 无错误,保留既有 docs/assets/ts/artplayer.d.ts 的 1 条 unused-disable warning。
日志及面板用例使用原生 RAF/DOM;迟到已取消 RAF 和挂起的零延迟 timer 是显式
故障注入,未把它们称作未经控制的用户操作。mobile 用例仍有实际视频播放和可见
日志。浏览器是本机 Playwright 三引擎,不是物理 iOS/Android 或远端 CI 结果。
## 剩余边界与回退
本任务只关闭已复现的日志/面板/布局迟到工作,不宣称覆盖 vConsole 所有生命周期。
原 LICENSE 原文继续分发;缺失的 MIT 正文和依赖 notices 仍属于 VENDOR-07,
SITE-07 仍 doing。Monaco/Codicons、console bundle、字体/媒体许可也未关闭。
没有 npm 发布、部署或 push。回退本任务提交同时恢复生成器、候选、指纹和 CI
命令;不要只替换 docs 中的压缩文件而留下失配的生成检查。
+6 -4
View File
@@ -2,9 +2,9 @@
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 255 项,范围 22 个包及工作区/示例。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 256 项,范围 22 个包及工作区/示例。
状态:todo 51 / doing 18 / blocked 0 / done 186 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 51 / doing 18 / blocked 0 / done 187 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -35,7 +35,7 @@
| artplayer-proxy-mediabunny | 1.2.0 | PKG-MB-01, PKG-MB-02, PKG-MB-03, PKG-MB-04, PKG-MB-05, PKG-MB-06, PKG-MB-07, PKG-MB-08, PKG-MB-09, PKG-MB-10 |
| artplayer-tool-iframe | 1.1.0 | PKG-IFRAME-01, PKG-IFRAME-02, PKG-IFRAME-03, PKG-IFRAME-04, PKG-IFRAME-05, PKG-IFRAME-06 |
| artplayer-tool-thumbnail | 4.4.0 | PKG-TOOL-THUMB-01, PKG-TOOL-THUMB-02, PKG-TOOL-THUMB-03, PKG-TOOL-THUMB-04, PKG-TOOL-THUMB-05, PKG-TOOL-THUMB-06 |
| artplayer-vitepress | 1.1.0 | SITE-01, SITE-SMOKE-01, SITE-02, SITE-LOAD-01, SITE-AI-DOCS-01, SITE-BUILD-01, SITE-03, SITE-04, SITE-05, SITE-06, SITE-07 |
| artplayer-vitepress | 1.1.0 | SITE-01, SITE-SMOKE-01, SITE-02, SITE-LOAD-01, SITE-AI-DOCS-01, SITE-BUILD-01, SITE-03, SITE-04, SITE-05, SITE-06, SITE-07, SITE-VCONSOLE-01 |
## 0 规划
@@ -397,12 +397,13 @@
| SITE-BUILD-01 | artplayer, artplayer-vitepress, workspace<br>重构 i18n 与文档构建的暂存、替换和 Yarn 编排 | SITE-AI-DOCS-01 | 严格 TS 构建模块、编译后替换产物与失败回退,固定 Yarn 子进程和旧构建入口 | 旧 i18n 删除后失败有复现;失败不改变既有产物;语言集合、UMD/ESM/历史别名兼容;文档子进程退出码准确并完成真实 VitePress 构建;不隐式翻译、不修改播放器 API | M | done |
| SITE-03 | artplayer-vitepress<br>整理 i18n/文档/LLM 生成流程 | SITE-02, SITE-LOAD-01, SITE-AI-DOCS-01, SITE-BUILD-01 | build-i18n/build-docs/build-llm/trans-docs 的任务边界和错误处理;桌面 common.js 自有 UI 的 TS 迁移与模块拆分 | 原命令兼容、生成可复现,翻译步骤不隐式运行远程服务;覆盖移动 loader 失败恢复 define、脚本依赖顺序、localhost/127.0.0.1 Run Code 目标和语言重定向;桌面剩余 UI 完成 TS 职责拆分并回归运行、导入与持久设置 | M | done |
| SITE-04 | artplayer-vitepress<br>交叉核对逐包持续维护的文档 | CORE-21, SITE-03, PKG-CHAPTER-04, PKG-AMBILIGHT-04, PKG-AUDIO-04, PKG-AUTO-THUMB-04, PKG-VTT-THUMB-04, PKG-HLS-04, PKG-DASH-04, PKG-MULTI-SUB-04, PKG-JASSUB-04, PKG-MASK-04, PKG-ASR-04, PKG-ADS-04, PKG-VAST-04, PKG-CAST-04, PKG-DPIP-04, PKG-CANVAS-04, PKG-IFRAME-04, PKG-TOOL-THUMB-04, PKG-DANMUKU-06, PKG-MB-08 | 已随实现更新的中文/英文 API、包内实现地图、旧 JS 示例及已知能力限制的全包核对 | 未把缺环境的能力写成已验证,静态核对不等待设备任务;最终 demo 仍由 EX-03 验收;按 SITE-01 声明成员/候选标题清单逐项语义核对,补齐缺失的双语插件说明和 Danmuku 英文入口 | M | todo |
| SITE-05 | artplayer-vitepress<br>构建文档站和验证链接/示例 | SITE-04, EX-01, EX-02, SITE-07 | VitePress 构建、链接与嵌入 demo 检查 | 文档构建、链接、嵌入路径与声明注入通过;真实完整 demo 保留 EX-03 独立门槛;核对 ENG-PM-01 登记的搜索 peer 范围和真实搜索行为 | M | todo |
| SITE-05 | artplayer-vitepress<br>构建文档站和验证链接/示例 | SITE-04, EX-01, EX-02, SITE-07, SITE-VCONSOLE-01 | VitePress 构建、链接与嵌入 demo 检查 | 文档构建、链接、嵌入路径与声明注入通过;真实完整 demo 保留 EX-03 独立门槛;核对 ENG-PM-01 登记的搜索 peer 范围和真实搜索行为 | M | todo |
| SITE-06 | artplayer-vitepress<br>文档站交付验收 | SITE-05 | 维护指南和站点变更记录 | 未手改 generated 目录,旧 URL 可用、部署与检查分离 | M | todo |
| SITE-07 | artplayer-vitepress, workspace<br>整理站点第三方资产与来源说明 | SITE-01 | Monaco/vConsole/console bundle/字体和样本的冻结来源、可复现构建或替代与站点 notices | 接续 SITE-01 的字节与换行差异证据;完整许可随实际分发,consoleLog/global/CSS/worker 与旧 URL 兼容;缺字体/媒体使用依据明确处置;资产变更后执行编辑器/移动/字幕/示例回归,不以来源指纹替代授权或运行证据 | H | doing |
| EX-01 | example/react.js, workspace<br>验证 React 消费者与 TS | CORE-22, ENG-07 | React 挂载/卸载/重挂载、引用和插件样例 | 真实 tarball + TS 消费通过,保留既有 React 集成 API | M | done |
| EX-02 | example/vue.js, workspace<br>验证 Vue 消费者与更新卸载 | CORE-22, ENG-07 | Vue 实例/ref、参数更新、卸载及插件样例 | 旧 JS 组件用法无需修改,重复挂载不泄漏 | M | done |
| EX-03 | workspace<br>验证全部原生 demo 与外部播放集成 | EX-01, EX-02, PKG-CHAPTER-06, PKG-AMBILIGHT-06, PKG-AUDIO-06, PKG-AUTO-THUMB-06, PKG-VTT-THUMB-06, PKG-HLS-06, PKG-DASH-06, PKG-MULTI-SUB-06, PKG-JASSUB-06, PKG-MASK-06, PKG-ASR-06, PKG-ADS-06, PKG-VAST-06, PKG-CAST-06, PKG-DPIP-06, PKG-DANMUKU-09, PKG-CANVAS-06, PKG-MB-10, PKG-IFRAME-06, PKG-TOOL-THUMB-06 | 8082 全 demo、HLS/DASH/FLV/MPEGTS/WebTorrent 集成记录 | 旧 URL/参数/脚本加载保持;网络/SDK 限制明确,不静默跳过;覆盖编辑器重复 Run 和 ESM/i18n/mobile/iframe,记录实际候选脚本及状态隔离证据;依据 BASE-04 路径台账逐项消除 not-run,处理 BASE-DEMO-01 | H | todo |
| SITE-VCONSOLE-01 | artplayer-vitepress, workspace<br>修复 vConsole 日志帧与延迟面板销毁竞态 | SITE-01 | 冻结上游 bundle 的可复现 TS 生命周期补丁、旧红新绿回归、来源及生成检查;销毁后虚拟列表布局续段停止 | 最后日志插件移除后取消 RAF 并隔离旧队列;延迟面板不得写入已销毁或替换插件;三引擎移动页与 UMD 入口通过,维护声明与原有许可缺口分别记录;原生 ResizeObserver 布局与挂起 timer 旧红新绿 | M | done |
## 7 工具链与性能
@@ -664,3 +665,4 @@
- PKG-VAST-07: [记录](changes/2026-09-14-PKG-VAST-07-default-alias.md) [记录](baselines/vast-alias-validation.json)
- PKG-JASSUB-10: [记录](changes/2026-09-14-PKG-JASSUB-10-render-resources.md) [记录](baselines/jassub-render-validation.json) [记录](baselines/jassub-render-patch.json)
- ENG-13: [记录](changes/2026-09-14-ENG-13-observation-window.md) [记录](baselines/observation-window-validation.json)
- SITE-VCONSOLE-01: [记录](changes/2026-09-14-SITE-VCONSOLE-01-lifecycle.md) [记录](baselines/vconsole-lifecycle-validation.json)
+14
View File
@@ -1,5 +1,19 @@
# 进度与证据
## SITE-VCONSOLE-01 站点控制台生命周期修复完成
冻结 vConsole 3.15.0 原始 bundle,以严格 TS 和六个唯一构建替换点修复日志 RAF、
同名面板替换、销毁后虚拟列表布局续段。原版最终对照 12 失败/6 通过,候选三引擎
21 项全通过,包含实际 mobile 页面播放、可见日志和 AMD/CommonJS 入口。早期
测试前置条件/选择器错误与候选暴露的额外异常均留档,没有跳过销毁或吞页面错误。
40 项单元/CI 回归、严格工具链、冻结安装、docs-tools TS、根 lint(1 条既有 warning)
通过;生成与只读检查接入 CI 的 notices 前置步骤。新增依赖为零,仍使用 Yarn。
见[变更](changes/2026-09-14-SITE-VCONSOLE-01-lifecycle.md)与
[证据](baselines/vconsole-lifecycle-validation.json)。256项:187 done、18 doing、51 todo。
VCONSOLE-LIFECYCLE-01 运行时风险已处理;VENDOR-07 的完整许可/依赖 notices、
Monaco 字体和其他资产仍 open,SITE-07 仍 doing。没有远端运行、部署、push/publish。
下一步继续站点来源/许可及剩余包验收;VAST/缩略图工具历史默认行为选择仍待回复。
## SITE-07 固定vendor来源与notice生成检查点(仍doing)
新增Monaco0.30.1/vConsole3.15.0的100文件固定指纹、TS生成器和只读检查,三份上游
+1 -1
View File
@@ -270,4 +270,4 @@
| MULTI-SUB-ASS-01 | resolved / 已复现 | Published core5.1.2 ASS converter loses required VTT line breaks | PKG-MULTI-SUB-11 |
| JASSUB-RENDER-RESOURCES-01 | resolved / 已复现 | Main-thread async rendering leaves received ImageBitmaps open when native canvas operations throw | PKG-JASSUB-10 |
| ENG-PERF-OBS-01 | resolved / 已复现 | A nominal 350 ms resource observation can record only 349 ms and fail the required minimum | ENG-13 |
| VCONSOLE-LIFECYCLE-01 | open / 已复现 | vConsole 3.15.0 mobile destruction can leave a callback updating a removed log store | SITE-07, SITE-05 |
| VCONSOLE-LIFECYCLE-01 | resolved / 已复现 | vConsole delayed log, panel and scroller work outlives its owner | SITE-07, SITE-05, SITE-VCONSOLE-01 |
+12 -4
View File
@@ -6169,12 +6169,13 @@
},
{
"id": "VCONSOLE-LIFECYCLE-01",
"title": "vConsole 3.15.0 mobile destruction can leave a callback updating a removed log store",
"title": "vConsole delayed log, panel and scroller work outlives its owner",
"confirmation": "reproduced",
"status": "open",
"status": "resolved",
"owners": [
"SITE-07",
"SITE-05"
"SITE-05",
"SITE-VCONSOLE-01"
],
"evidence": [
"refactor/changes/2026-09-14-SITE-07-vendor-notices.md",
@@ -6184,7 +6185,14 @@
],
"compatibleResolution": "Reproduce the exact delayed callback from fixed upstream source and preserve logging/global/CSS behavior while preventing work on a removed store; do not remove destruction checks or catch page errors to pass.",
"closureCriteria": "A deterministic old-build failure and fixed native three-engine logging/destruction checks with no late errors, plus maintainable source/build provenance and required notices.",
"workspaceState": "First native check: desktop worker 3/3 and mobile Chromium/Firefox pass; WebKit mobile page fails with undefined is not an object (evaluating s.O.get(n).update) after destruction. Upstream log model schedules RAF and reads Store.get(id).update while unbindPlugin deletes the store; exact causal callback remains to isolate."
"workspaceState": "Frozen original deterministically fails 12 lifecycle cases across three engines; candidate passes 21 including actual mobile logging/playback. The six pinned replacements fix RAF ownership, panel identity and two scroller resumptions.",
"resolutionEvidence": [
"refactor/changes/2026-09-14-SITE-VCONSOLE-01-lifecycle.md",
"refactor/baselines/vconsole-lifecycle-validation.json",
"scripts/site-vendor/vconsole/README.md",
"test/browser/vconsole-lifecycle.spec.js"
],
"resolutionRationale": "Runtime lifecycle regression is fixed and old/native evidence retained. Original notices remain distributed; the distinct missing license body/dependency notices remain open under VENDOR-07 and SITE-07, without treating this runtime fix as clearance."
}
]
}
+22 -1
View File
@@ -4329,7 +4329,8 @@
"SITE-04",
"EX-01",
"EX-02",
"SITE-07"
"SITE-07",
"SITE-VCONSOLE-01"
],
"status": "todo",
"risk": "M",
@@ -5324,6 +5325,26 @@
"changes/2026-09-14-ENG-13-observation-window.md",
"baselines/observation-window-validation.json"
]
},
{
"id": "SITE-VCONSOLE-01",
"phase": "6 文档与消费者",
"title": "修复 vConsole 日志帧与延迟面板销毁竞态",
"scope": [
"artplayer-vitepress",
"workspace"
],
"dependsOn": [
"SITE-01"
],
"status": "done",
"risk": "M",
"deliverable": "冻结上游 bundle 的可复现 TS 生命周期补丁、旧红新绿回归、来源及生成检查;销毁后虚拟列表布局续段停止",
"acceptance": "最后日志插件移除后取消 RAF 并隔离旧队列;延迟面板不得写入已销毁或替换插件;三引擎移动页与 UMD 入口通过,维护声明与原有许可缺口分别记录;原生 ResizeObserver 布局与挂起 timer 旧红新绿",
"evidence": [
"changes/2026-09-14-SITE-VCONSOLE-01-lifecycle.md",
"baselines/vconsole-lifecycle-validation.json"
]
}
]
}
+17 -6
View File
@@ -1018,20 +1018,31 @@
"id": "vconsole",
"riskId": "VENDOR-07",
"inputs": [
"docs/assets/js/vconsole.min.js"
"docs/assets/js/vconsole.min.js",
"scripts/site-vendor/vconsole/upstream.js"
],
"owners": [
"SITE-01"
"SITE-01",
"SITE-07",
"SITE-VCONSOLE-01"
],
"sourceStatus": "Local header identifies vConsole 3.15.0 and Tencent copyright.",
"licenseStatus": "Local header identifies MIT; original tarball correspondence and deployment notices not yet verified.",
"upstreamSources": [],
"upstreamReviewedAt": null,
"sourceStatus": "Frozen npm 3.15.0 bundle, with reproducible six-hook lifecycle patch; see scripts/site-vendor/vconsole/README.md.",
"licenseStatus": "Original npm LICENSE is distributed verbatim but lacks its promised MIT body; bundled dependency notices remain open in VENDOR-07.",
"upstreamSources": [
"https://registry.npmjs.org/vconsole/-/vconsole-3.15.0.tgz",
"https://github.com/Tencent/vConsole/tree/05d80398bae35e793774f74e3c052b4e530e293a"
],
"upstreamReviewedAt": "2026-09-14",
"updatePolicy": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
"fingerprints": [
{
"path": "docs/assets/js/vconsole.min.js",
"algorithm": "sha256-lf",
"sha256": "3d1b8c3aff5f415ccf3bdc3cdcec6e01cff5b4c64d4558c078ca33d003f616ac"
},
{
"path": "scripts/site-vendor/vconsole/upstream.js",
"algorithm": "sha256-lf",
"sha256": "671f47427e1e3048919147c765e9fb71e4ea40d79a8c2829089f499d3e9b9bf4"
}
]