refactor(thumbnail): [PKG-TOOL-THUMB-04] preserve approved published defaults

This commit is contained in:
Harvey Zhao committed 2026-09-15 23:54:24 +08:00
1 parent 490e157717
commit b5f8b5e28e
37 files changed
+11172 -136

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,91 @@
# PKG-TOOL-THUMB-04 approved Thumbnail policy and migration completion
The user approved published 3.5.31 behavior as the default, with the unpublished
workspace behavior explicitly selected through `compatibility: 'workspace-4.4'`.
This completes the source/type migration task, including its earlier TypeScript,
declaration, installed-entry and emitter checkpoints. It does not complete 05/06,
physical-device evidence, formal reviews or publication readiness.
## Implementation
`src/policy.ts` selects and validates the policy. The public constructor restores
`DEFAULTS.delay: 300` and published key order. Published mode validates/clamps
height and delay to 10-1000, retains configured height and the selected input
value, delays the video event and each frame, and waits twice the delay before
done. Workspace mode keeps aspect-ratio height, synchronous video notification,
no fixed extraction delays and input reset. The class DEFAULTS always represents
the published policy; this boundary was explicitly approved.
Source and extraction continue owning their resources separately. Source changes,
native errors and destroy cancel pending notification, frame and completion
timers. Frame readiness and seek completion are required in addition to the
published delay. Cancellation settles the Promise without late update/done or
new URLs. NaN retains the old asynchronous timer boundary rather than being
mistaken for the workspace no-timer mode. Existing public spellings, descriptors,
custom fields, event payloads, synchronous validation and return values remain.
The authored declarations add optional compatibility/delay and exported
Compatibility/DefaultOptions types. SheetOptions still accepts old literals
without a delay field. Source and public constructors remain mutually assignable.
The generated local Monaco declarations are regenerated; its real worker compiles
the new mode/default types and executes constructor/event/cleanup code.
README, architecture and type ownership guides describe both policies. No new
dependency, lockfile or version change is needed. `test:thumbnail` and `test:unit`
now include the new policy regression suite. Bundles and docs copies were built
through the repository build script; source remains authoritative.
## Verification
Node 24.21.0, Yarn Classic 1.22.22, Windows. Evidence:
[thumbnail-policy-validation.json](../baselines/thumbnail-policy-validation.json).
- The initial new policy tests failed 6/7 against the previous implementation.
Final `yarn test:thumbnail`: 136 passed, no failure/skip/cancellation, 14.968 s.
This includes frozen historical tests and current/old TypeScript consumers.
- Strict source tsc and scoped source/type/test/script lint pass. Five public
compiler/resolution modes reject all 12 invalid calls. Native CommonJS/no-interop
fixtures and both-direction source/declaration assignment pass.
- Main/legacy/ESM build succeeds. Final external Yarn pack/install evidence is
`.cache/thumbnail-package-types-IH4Ouy`: offline frozen reinstall, installed-file
hashes, native require/import and 12 compiler cases pass. Five cases characterize
the frozen workspace missing-entry defect; seven exercise candidate consumers.
Installed legacy runtime/policy/lifecycle subset: 63/63, 2.770 s; the final
legacy bytes are identical to that tested snapshot. The final packed files are
checked against the working tree in the evidence recorder.
- Three-engine source browser run: 90 passed, 0 failed/skipped/flaky, 66.423 s.
Installed main browser run: 30 passed, 0 failed/skipped/flaky, 33.414 s.
Chromium 153.0.8010.12 and Firefox 155.0 verify actual file selection, configured
versus aspect height, PNG pixels, repeated extraction, URL release, held native
encoding cancellation and latest-source-only updates. Published video/frame/done
delays have lower-bound assertions; owned-timer tests verify exact scheduling.
- Windows WebKit 26.6 cannot decode the tested native Blob URLs (error 4), while
HTTP controls load. There are 23 annotated capability-control source cases and
10 installed cases. These are not successful extraction or physical Safari
evidence. Other passing historical tests also include exact old-defect controls.
The first broad runtime attempt exposed fixtures that assumed no fixed delays;
those now explicitly select workspace mode. A waiting worker was stopped and its
unfinished run is not counted as passing. An initial strict error on optional
delay was fixed through numeric normalization after runtime validation.
The first browser run had 89 passes and one Chromium failure: selecting an
identical file while published mode retains input.value did not trigger change,
so starting a second job correctly rejected it. The replacement test now clears
selection before choosing the file again. Both modes retain the original strict
AbortError/latest-source assertions. Final reports and the initial trace are
archived separately; no retry, weaker assertion or production input reset hides
that failure.
## Status and continuation
PKG-TOOL-THUMB-04 is done; THUMB-COMPAT-01 is resolved for the approved default
policy and migration boundary. No complete original npm archive or historical
declaration has been recovered, and 05/06 retain integration/distribution work.
Next implementation work includes the recorded installed Danmuku CPU-gap failure
and remaining package/release preparation. Finish implementation and required
tests, then await user direction for reviews; do not push or publish.
Rollback requires reverting this task's source, declarations, generated outputs,
tests and documentation together. Returning to the prior workspace default would
also reverse the approved compatibility decision and must not be done silently.
+3 -3
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 282 项,范围 22 个包及工作区/示例。
状态:todo 43 / doing 21 / blocked 0 / done 218 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 43 / doing 20 / blocked 0 / done 219 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -396,7 +396,7 @@
| PKG-TOOL-THUMB-01 | artplayer-tool-thumbnail<br>核对包契约与历史用法 | BASE-05 | 构造/defaults/事件/方法/历史拼写、.esm.js 入口和缺失 types | 源码/声明/README/demo/可恢复发布内容差异已登记;公开形状和版本范围冻结;区分旧 npm 的 main/CSS 与当前工作区无 main、.esm.js/类型缺失,不把工作区状态冒称旧 npm 发布事实 | H | done |
| PKG-TOOL-THUMB-02 | artplayer-tool-thumbnail<br>建立特有行为与错误测试 | PKG-TOOL-THUMB-01, ENG-03, ENG-05 | 文件输入/拖放、抽帧网格、begin/end、进度/失败/重复任务 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | done |
| PKG-TOOL-THUMB-03 | artplayer-tool-thumbnail<br>整理内部职责与资源 | PKG-TOOL-THUMB-02, CORE-01 | 输入、抽帧队列、网格导出、URL/监听清理分离 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | done |
| PKG-TOOL-THUMB-04 | artplayer-tool-thumbnail<br>迁移自有源码和公开类型 | PKG-TOOL-THUMB-03, ENG-04, ENG-06, CORE-07, PKG-TOOL-THUMB-07 | 补齐真实 API 声明,自有 emitter/utils TS 化 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容;为 BASE-DIST-01 提供兼容入口/声明及消费者验证 | H | doing |
| PKG-TOOL-THUMB-04 | artplayer-tool-thumbnail<br>迁移自有源码和公开类型 | PKG-TOOL-THUMB-03, ENG-04, ENG-06, CORE-07, PKG-TOOL-THUMB-07 | 补齐真实 API 声明,自有 emitter/utils TS 化 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容;为 BASE-DIST-01 提供兼容入口/声明及消费者验证 | H | done |
| PKG-TOOL-THUMB-05 | artplayer-tool-thumbnail<br>验证新旧核心和组合 | PKG-TOOL-THUMB-04, CORE-22 | 工具独立浏览器使用,生成缩略图在核心中显示 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-TOOL-THUMB-06 | artplayer-tool-thumbnail<br>验证分发并同步文档 | PKG-TOOL-THUMB-05, ENG-07 | tool.thumbnail.js、历史 ESM 兼容文件、types 路径和 tarball | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
| PKG-TOOL-THUMB-07 | artplayer-tool-thumbnail<br>恢复清理和销毁中的原始异常传播 | PKG-TOOL-THUMB-03 | 清理记录与异常值分离,保留首个 falsy 抛出值并继续释放资源;历史对照、真实DOM、分发验证及维护记录 | 恢复旧 destroy 监听器同步异常语义,0/false/undefined/NaN等不被吞掉或覆盖;后续清理、重复销毁与正常抽帧回归通过,默认兼容决策不受影响 | M | done |
@@ -673,7 +673,7 @@
- PKG-TOOL-THUMB-01: [记录](baselines/thumbnail-release.json) [记录](baselines/thumbnail-contract.md) [记录](changes/2026-09-13-PKG-TOOL-THUMB-01-contract.md) [记录](baselines/thumbnail-contract-validation.json)
- PKG-TOOL-THUMB-02: [记录](baselines/thumbnail-behavior-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-02-behavior.md)
- PKG-TOOL-THUMB-03: [记录](changes/2026-09-13-PKG-TOOL-THUMB-03-input-checkpoint.md) [记录](baselines/thumbnail-input-checkpoint.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-03-lifecycle.md) [记录](baselines/thumbnail-lifecycle-validation.json)
- PKG-TOOL-THUMB-04: [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-runtime-types.md) [记录](baselines/thumbnail-runtime-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-public-types.md) [记录](baselines/thumbnail-public-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-emitter.md) [记录](baselines/thumbnail-emitter-validation.json) [记录](thumbnail-compatibility-decision.md) [记录](changes/2026-09-15-PKG-TOOL-THUMB-04-policy-proposal.md)
- PKG-TOOL-THUMB-04: [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-runtime-types.md) [记录](baselines/thumbnail-runtime-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-public-types.md) [记录](baselines/thumbnail-public-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-emitter.md) [记录](baselines/thumbnail-emitter-validation.json) [记录](thumbnail-compatibility-decision.md) [记录](changes/2026-09-15-PKG-TOOL-THUMB-04-policy-proposal.md) [记录](changes/2026-09-15-PKG-TOOL-THUMB-04-approved-policy.md) [记录](baselines/thumbnail-policy-validation.json)
- SITE-01: [记录](site-inventory.md) [记录](baselines/site-inventory.json) [记录](baselines/site-provenance.json) [记录](baselines/demo-additions.json) [记录](changes/2026-09-14-SITE-01-site-inventory.md) [记录](baselines/site-inventory-validation.json)
- SITE-SMOKE-01: [记录](changes/2026-09-14-SITE-SMOKE-01-documentation-smoke.md) [记录](baselines/docs-smoke-validation.json) [记录](scripts/docs-smoke.test.mjs)
- SITE-02: [记录](changes/2026-09-14-SITE-02-editor-declarations.md) [记录](baselines/editor-declarations-validation.json) [记录](changes/2026-09-14-SITE-SMOKE-01-documentation-smoke.md)
+13
View File
@@ -1,5 +1,18 @@
# 进度与证据
## PKG-TOOL-THUMB-04 Thumbnail 策略与源码迁移完成
用户批准已落实:默认保留 npm 3.5.31,显式 workspace-4.4 保留未发布工作区行为。
策略集中到 policy.ts,延迟由 source/job 各自管理;类型、迁移说明与构建产物同步。
136 项 Node 测试、严格类型、隔离安装 12 编译器案例通过;安装 legacy 63 项通过。
三引擎源码浏览器 90 项、安装 main 30 项通过,其中分别 23/10 项为 WebKit
能力对照,不能算截图提取或真实 Safari 通过。首次同文件重选夹具失败已修正并归档。
见[完成记录](changes/2026-09-15-PKG-TOOL-THUMB-04-approved-policy.md)、
[证据](baselines/thumbnail-policy-validation.json)。04 done,THUMB-COMPAT-01 resolved;
05/06、设备与整体发布门槛保留。当前 219 done、20 doing、43 todo,共282项。
下一步修复已捕获的 DANMUKU-INSTALLED-GAP-01,并继续剩余实施/版本准备。
实施完成后等待用户指导复盘;未启动复盘、推送或发布。
## CI-01 完整 Windows WebKit 安装包回归
固定bb2c12df3,复用5e0447fc5打包的20包run-cRduve;77文件/845项:694通过、
+1 -1
View File
@@ -177,7 +177,7 @@
| IFRAME-LIFE-01 | open / 已复现 | Iframe timestamp IDs and unowned pending requests/timers lack terminal cleanup | PKG-IFRAME-02, PKG-IFRAME-03, PKG-IFRAME-05 |
| IFRAME-TRUST-01 | open / 已复现 | Iframe executable commit protocol accepts messages without source/origin validation | PKG-IFRAME-03, PKG-IFRAME-05 |
| IFRAME-DIST-01 | open / 已复现 | Iframe tool name is unavailable at registry observation and old archive includes distinct helper exports | PKG-IFRAME-04, PKG-IFRAME-06 |
| THUMB-COMPAT-01 | open / 已复现 | Thumbnail recovered 3.5.31 and workspace 4.4.0 have conflicting height and event timing defaults | PKG-TOOL-THUMB-04, PKG-TOOL-THUMB-05 |
| THUMB-COMPAT-01 | resolved / 已复现 | Thumbnail recovered 3.5.31 and workspace 4.4.0 have conflicting height and event timing defaults | PKG-TOOL-THUMB-04, PKG-TOOL-THUMB-05 |
| THUMB-LIFE-01 | open / 已复现 | Thumbnail drop binding and repeated destroy fail; pending work and replacement resource ownership need repair | PKG-TOOL-THUMB-02, PKG-TOOL-THUMB-03, PKG-TOOL-THUMB-05 |
| THUMB-PROVENANCE-01 | resolved / 源码/产物事实 | Thumbnail local emitter attribution and historical distribution completeness remain unverified | PKG-TOOL-THUMB-04, PKG-TOOL-THUMB-06 |
| THUMB-MEDIA-01 | open / 已复现 | Windows WebKit native Blob URLs cannot load tested MP4 media despite successful HTTP controls | PKG-TOOL-THUMB-05, PKG-TOOL-THUMB-06 |
+12 -4
View File
@@ -4125,9 +4125,9 @@
"PKG-TOOL-THUMB-04",
"PKG-TOOL-THUMB-05"
],
"compatibleResolution": "Freeze both implementations and derive a concrete compatibility policy before changing defaults; no silent claim that identical calls have identical historical semantics.",
"compatibleResolution": "User approved published 3.5.31 default behavior and explicit workspace-4.4 mode, including class DEFAULTS. Implemented as an owned policy without restoring historical resource defects.",
"closureCriteria": "Explicit documented compatibility decision, old/candidate tests and migration examples covering delay, height, input reset and readiness.",
"status": "open",
"status": "resolved",
"evidence": [
"refactor/baselines/thumbnail-contract.md",
"refactor/baselines/thumbnail-release.json",
@@ -4139,9 +4139,17 @@
"refactor/changes/2026-09-13-PKG-TOOL-THUMB-03-lifecycle.md",
"refactor/changes/2026-09-13-PKG-TOOL-THUMB-04-public-types.md",
"refactor/thumbnail-compatibility-decision.md",
"refactor/changes/2026-09-15-PKG-TOOL-THUMB-04-policy-proposal.md"
"refactor/changes/2026-09-15-PKG-TOOL-THUMB-04-policy-proposal.md",
"refactor/changes/2026-09-15-PKG-TOOL-THUMB-04-approved-policy.md",
"refactor/baselines/thumbnail-policy-validation.json"
],
"workspaceState": "Concrete proposal prepared: recovered 3.5.31 runtime defaults and optional workspace-4.4 mode, explicitly including the class-level DEFAULTS difference, delay/height validation, event/frame timing and input reset. Frozen contract/behavior tests rerun 62/62. User choice remains pending; no mode/default change implemented or inferred from other package approvals."
"workspaceState": "Default fixed/clamped height and delay, delayed video/frame/done and retained input value implemented; explicit workspace mode keeps aspect height, no policy delays and input reset. Source and installed browser checks plus strict current/old types pass within documented Windows WebKit Blob capability limits. Package integration/distribution and physical devices remain separate gates.",
"resolutionEvidence": [
"refactor/changes/2026-09-15-PKG-TOOL-THUMB-04-approved-policy.md",
"refactor/baselines/thumbnail-policy-validation.json",
"refactor/thumbnail-compatibility-decision.md"
],
"resolutionRationale": "Explicit user approval and migration examples, frozen/default/workspace tests, source and installed real PNG checks on Chromium/Firefox, owned cancellation timing and declaration consumers close the conflicting-default policy. Windows WebKit native Blob limitation is recorded, not treated as successful extraction."
},
{
"id": "THUMB-LIFE-01",
+12 -6
View File
@@ -6,8 +6,8 @@ import ts from 'typescript'
import compat from 'typescript-compat'
import { checkFiles, packedFiles } from '../../scripts/package-check.mjs'
import { consumerDirectory, removeConsumer, run, workspace, writeJson } from '../../scripts/package-consumer.mjs'
import { verifyThumbnailContract } from './thumbnail-contract.mjs'
import { hash, readMember } from './releases.mjs'
import { verifyThumbnailContract } from './thumbnail-contract.mjs'
async function main() {
assert.equal(process.env.npm_config_user_agent?.split(' ')[0], 'yarn/1.22.22', 'Use yarn test:thumbnail-types-package')
@@ -20,7 +20,8 @@ async function main() {
fs.mkdirSync(frozen)
const prefix = 'packages/artplayer-tool-thumbnail/'
for (const [file, text] of contract.source) {
if (!file.startsWith(prefix)) continue
if (!file.startsWith(prefix))
continue
const target = path.join(frozen, file.slice(prefix.length))
fs.mkdirSync(path.dirname(target), { recursive: true })
fs.writeFileSync(target, text)
@@ -74,7 +75,8 @@ ${label === 'candidate' ? `const legacy = require('${pkg.name}/legacy'); assert.
fs.writeFileSync(path.join(output, `${label}-runtime.log`), observation)
runtime.push({ package: label, ...JSON.parse(observation.trim()) })
const modes = [[ts, 'node10-commonjs'], [ts, 'nodenext-cjs'], [ts, 'nodenext-esm'], [ts, 'bundler-esm'], [compat, 'node10-commonjs']]
if (label === 'candidate') modes.push([ts, 'nodenext-cjs-no-interop'], [compat, 'node10-commonjs-no-interop'])
if (label === 'candidate')
modes.push([ts, 'nodenext-cjs-no-interop'], [compat, 'node10-commonjs-no-interop'])
for (const [compiler, mode] of modes) {
const next = mode.startsWith('nodenext')
const noInterop = mode.endsWith('no-interop')
@@ -92,15 +94,19 @@ ${label === 'candidate' ? `const legacy = require('${pkg.name}/legacy'); assert.
}
const diagnostics = compile(source)
writeJson(path.join(output, `${label}-${compiler.version}-${mode}.json`), diagnostics)
if (label === 'candidate') assert.deepEqual(diagnostics, [], `${compiler.version} ${mode}`)
if (label === 'candidate') {
assert.deepEqual(diagnostics, [], `${compiler.version} ${mode}`)
}
else {
assert.deepEqual(diagnostics.map(item => item.code), [mode === 'node10-commonjs' ? 2307 : 7016], 'Only the exact frozen missing entry/declaration diagnostic is expected')
}
const negative = label === 'candidate' ? compile(source.replaceAll(/\/\/ @ts-expect-error[^\n]*\n/g, '')) : []
if (label === 'candidate') assert.equal(negative.length, noInterop ? 1 : 10)
if (label === 'candidate')
assert.equal(negative.length, noInterop ? 1 : 12)
matrix.push({ package: label, compiler: compiler.version, mode, diagnostics, negative })
}
if (label === 'candidate') fs.cpSync(installed, path.join(output, 'installed-artifacts'), { recursive: true })
if (label === 'candidate')
fs.cpSync(installed, path.join(output, 'installed-artifacts'), { recursive: true })
}
finally { removeConsumer(consumer) }
}
+4 -4
View File
@@ -2,11 +2,11 @@ import assert from 'node:assert/strict'
import fs from 'node:fs'
// eslint-disable-next-line test/no-import-node-test -- Public type and editor contract runner.
import test from 'node:test'
import { ESLint } from 'eslint'
import ts from 'typescript'
import compat from 'typescript-compat'
import { ESLint } from 'eslint'
import { checkConsumer } from '../../scripts/typecheck.mjs'
import { checkPluginEditorDeclaration, generatePluginEditorDeclaration } from '../../scripts/plugin-editor-types.mjs'
import { checkConsumer } from '../../scripts/typecheck.mjs'
const modes = [[ts, 'node10-commonjs'], [ts, 'nodenext-cjs'], [ts, 'nodenext-esm'], [ts, 'bundler-esm'], [compat, 'node10-commonjs']]
const invalid = source => source.replaceAll(/\/\/ @ts-expect-error[^\n]*\n/g, '')
@@ -15,7 +15,7 @@ test('Thumbnail public declarations check actual callbacks, custom events and in
const source = fs.readFileSync('test/types/thumbnail.ts', 'utf8')
for (const [compiler, mode] of modes) {
assert.deepEqual(checkConsumer(compiler, mode, source), [], `${compiler.version} ${mode}`)
assert.equal(checkConsumer(compiler, mode, invalid(source)).length, 10, `${compiler.version} ${mode} negatives`)
assert.equal(checkConsumer(compiler, mode, invalid(source)).length, 12, `${compiler.version} ${mode} negatives`)
}
const commonjs = fs.readFileSync('test/types/thumbnail-commonjs.cts', 'utf8')
for (const [compiler, mode] of [[ts, 'nodenext-cjs'], [compat, 'node10-commonjs']]) {
@@ -67,7 +67,7 @@ const bad = player.mediabunny?.levels;`
assert.equal(checkPluginEditorDeclaration(code, core, invalid(consumer), compiler).length, 1)
}
assert.throws(() => generatePluginEditorDeclaration(source, 'artplayerProxyMediabunny'), /Unsupported editor type re-export/)
assert.throws(() => generatePluginEditorDeclaration(source, 'artplayerProxyMediabunny', { './media': media + '\nexport interface Extra {}' }), /explicitly cover/)
assert.throws(() => generatePluginEditorDeclaration(source, 'artplayerProxyMediabunny', { './media': `${media}\nexport interface Extra {}` }), /explicitly cover/)
const common = fs.readFileSync('docs/assets/js/common.js', 'utf8')
assert(common.includes('./assets/ts/artplayer-tool-thumbnail.d.ts'))
assert(!common.includes('./assets/ts/media.d.ts'))
+4 -2
View File
@@ -4238,7 +4238,7 @@
"CORE-07",
"PKG-TOOL-THUMB-07"
],
"status": "doing",
"status": "done",
"risk": "H",
"deliverable": "补齐真实 API 声明,自有 emitter/utils TS 化",
"acceptance": "严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容;为 BASE-DIST-01 提供兼容入口/声明及消费者验证",
@@ -4250,7 +4250,9 @@
"changes/2026-09-13-PKG-TOOL-THUMB-04-emitter.md",
"baselines/thumbnail-emitter-validation.json",
"thumbnail-compatibility-decision.md",
"changes/2026-09-15-PKG-TOOL-THUMB-04-policy-proposal.md"
"changes/2026-09-15-PKG-TOOL-THUMB-04-policy-proposal.md",
"changes/2026-09-15-PKG-TOOL-THUMB-04-approved-policy.md",
"baselines/thumbnail-policy-validation.json"
]
},
{
+10 -7
View File
@@ -1,7 +1,10 @@
# Thumbnail 默认行为兼容决策(待用户确认)
# Thumbnail 默认行为兼容决策(已批准,已实施)
状态:proposal,尚未批准或实施。责任任务 PKG-TOOL-THUMB-04,风险 THUMB-COMPAT-01。
本文件把已有待答问题具体化;不把其他包的兼容授权推广到本工具。
状态:approved,源码、类型及本机验证完成。责任任务 PKG-TOOL-THUMB-04,风险 THUMB-COMPAT-01。
2026-09-15 用户明确批准:“接受:npm 行为默认,工作区行为显式选择(推荐)”。
下列方案现在可直接实施,无需再次询问;批准不代替源码、类型和浏览器验证。
实施结果见 [完成记录](changes/2026-09-15-PKG-TOOL-THUMB-04-approved-policy.md);
05/06、设备和发布门槛仍独立保留,Windows WebKit 能力对照不计截图提取通过。
## 已复现的冲突
@@ -23,7 +26,7 @@
变成 90 高;loadVideo 后同步注册 video 监听器在两版也会得到不同结果。
不能通过 TS 重命名或内部拆文件同时满足这两种默认值和时序。
## 推荐方案:恢复已发布行为为默认,显式选择工作区模式
## 已批准方案:恢复已发布行为为默认,显式选择工作区模式
1. 根构造器默认选择恢复的 3.5.31 行为,支持旧 delay 参数,DEFAULTS 恢复
delay: 300;配置 height 保留原钳制,video 延迟、每帧/完成延迟及 input
@@ -33,7 +36,7 @@
显式 compatibility: 'published-3.5' 可表达默认选择。
3. 类级 DEFAULTS 没有实例上下文,统一表示根默认的 3.5.31 配置。依赖工作区
DEFAULTS 精确字段集合的代码需要明确选择/保存自己的配置;不能承诺它同时
返回两套对象。这个差异也属于本次待批准范围。
返回两套对象。这个差异也属于本次已批准范围。
4. 保留已实现的 URL/监听器/定时器所有权、销毁与切源取消、错误结算、输入
清理和 emitter 修复。不会恢复旧版错绑 this、陈旧回调、资源泄漏等缺陷。
定时等待不取代真实帧就绪;修复慢解码导致错误截图的路径单独记录和验证。
@@ -51,8 +54,8 @@ const workspaceTool = new ArtplayerToolThumbnail({
})
```
另一种可选决策是保留工作区 4.4.0 为默认,并接受已发布 3.5.31 用户需要选择
兼容模式。这会把迁移成本放到已发布旧用户,不作为当前推荐。
未选择的替代方案是保留工作区 4.4.0 为默认,并要求已发布 3.5.31 用户选择
兼容模式;用户已经选择上面的 npm 默认方案。
## 批准后实施与验收