test(vast): [PKG-VAST-01] freeze published and workspace contracts

This commit is contained in:
Harvey Zhao committed 2026-09-12 09:06:10 +08:00
1 parent 29692d2815
commit 4f39d6f2b9
11 files changed
+797 -17

No files matched your search

@@ -0,0 +1,144 @@
{
"schemaVersion": 1,
"task": "PKG-VAST-01",
"sourceCommit": "29692d28158ad50e1d404293f592679c10dbf3f5",
"scope": "Immutable published archives and frozen-source wrapper contracts only; no production changes",
"inputs": [
{
"file": "refactor/baselines/vast-release.json",
"sha256LF": "493e15fa8d3cd1a9215a409dd78db61ecaef5f82f9629dfdc3f6090e7fad8453"
},
{
"file": "refactor/scripts/vast-contract.mjs",
"sha256LF": "718ec6c0765caa7c9604e55d10a3b6c6dc25bdd42fc30d6b6097200888a7dd9e"
},
{
"file": "refactor/scripts/vast-contract.test.mjs",
"sha256LF": "b9cfa09402b2f7e91dfead607c303015967c2cc0d96353029bbda798c3b56bc9"
}
],
"archives": [
{
"name": "artplayer-plugin-vast",
"version": "1.0.0",
"sha256": "35681d60fa3fa09b92f0f30887e39c73cf55e7b14d51a1c38fccbc6c1f253bab",
"members": 6
},
{
"name": "@glomex/vast-ima-player",
"version": "1.21.0",
"sha256": "924405b92ac5ccb4cc775d13b5caba6dc6fb537d55b0cb3ca128cb9be4b2bc48",
"members": 27
},
{
"name": "@glomex/vast-ima-player",
"version": "1.21.2",
"sha256": "5b5575c3a6c68a2a550c986348093de7471476318c9ec443285063dfbef3f9b5",
"members": 27
}
],
"historicalCore": {
"commit": "252c226473792fd1537c1ff4a323344bf1060efc",
"file": "packages/artplayer/package.json",
"version": "5.1.7",
"sha256LF": "8bd532103099c367fb2c289e0d410f144fdeb00b1b62cf850762a24b61e63c8a",
"note": "Git association only; actual core tarball and browser combination remain task02/05.",
"limitation": "Git association only; actual core tarball and browser execution pending PKG-VAST-02/05"
},
"currentWorkspaceTypes": {
"source": "import vast from \"artplayer-plugin-vast\"; vast(({imaPlayer})=>{void imaPlayer});",
"result": [
{
"compiler": "5.9.3",
"diagnostics": [
{
"file": "node_modules/@glomex/vast-ima-player/dist/index.d.ts",
"code": 2307,
"line": 1,
"message": "Cannot find module '@alugha/ima' or its corresponding type declarations."
},
{
"file": "node_modules/@glomex/vast-ima-player/dist/vast-ima-player.d.ts",
"code": 2307,
"line": 6,
"message": "Cannot find module '@alugha/ima' or its corresponding type declarations."
}
]
},
{
"compiler": "4.3.5",
"diagnostics": [
{
"file": "node_modules/@glomex/vast-ima-player/dist/index.d.ts",
"code": 2307,
"line": 1,
"message": "Cannot find module '@alugha/ima' or its corresponding type declarations."
},
{
"file": "node_modules/@glomex/vast-ima-player/dist/vast-ima-player.d.ts",
"code": 2307,
"line": 6,
"message": "Cannot find module '@alugha/ima' or its corresponding type declarations."
}
]
}
],
"rawEvidence": {
"file": "refactor/.cache/vast01-current-types.json",
"sha256": "c9aa1d29b2ed4204e3e62f38b10e5dc4a81486a1b241e40d7b0424689080b32c"
}
},
"checks": [
{
"command": "eslint refactor/scripts/vast-contract.mjs refactor/scripts/vast-contract.test.mjs",
"result": "pass"
},
{
"command": "yarn test:baseline",
"result": "pass",
"tests": 53,
"passed": 53,
"failed": 0,
"skipped": 0,
"log": {
"file": "refactor/.cache/vast01-baseline.log",
"sha256": "2bc059268118cd284ffdadfaf9d05481b368e4abceabb73cf7270660824ea2c8"
}
},
{
"command": "yarn lint",
"result": "pass",
"log": {
"file": "refactor/.cache/vast01-lint.log",
"sha256": "219a458ee587661bd80c1b6c34d49079560b732dcabe35afb30a804408d89277"
}
},
{
"command": "node refactor/scripts/plan.mjs --check",
"result": "pass",
"tasks": 217,
"packages": 22,
"states": {
"done": 79,
"doing": 5,
"todo": 133
}
},
{
"command": "node refactor/scripts/risk-register.mjs --check",
"result": "pass",
"risks": 147,
"vendoredGroups": 8,
"integrations": 12
}
],
"fixtureCorrection": "First export VM omitted CustomEvent and triggered document fallback; supplying native platform CustomEvent fixed the fixture. This does not prove generic production SSR support.",
"limitations": [
"Injected SDK Player records wrapper behavior; no Google IMA media execution",
"Type diagnostic is current workspace evidence, not yet isolated installation proof",
"VAST VPN exception recorded but not exercised",
"VAST-CONTEXT-01, VAST-TYPE-01, VAST-LIFE-01, VAST-DIST-01 and SDK-07 remain open"
],
"status": "done",
"validationScope": "Targeted contract tests, all 53 baseline tests, repository lint, plan and risk checks. No production changes; no new full CI/build/media run for this baseline-only task."
}
+47
View File
@@ -0,0 +1,47 @@
# VAST 实际发布契约
PKG-VAST-01;固定内容见 [发布及SDK归档](vast-release.json)。2026-09-12查阅npm注册表,
VAST仅发布1.0.0(2024-10-12),工作区1.2.0未发布;目标依既定政策为2.0.0,正式
发布前重新核对版本占用。此处不是未来latest承诺。
## 发布版与工作区差异
| 契约 | 实际npm 1.0.0 | 冻结工作区1.2.0 | 后续处理 |
| --- | --- | --- | --- |
| 工厂 | `factory(callback)(art)`,第二层async;先await SDK,再await callback | 同样async,可省略callback | 保持Promise与回调完成顺序,补错误/销毁竞态测试 |
| 公开声明 | export=、全局namespace;第二层错误声明为同步Result;callback参数必需 | default export;仍错误声明同步Result;新增Instance/Option类型 | 协调实际Promise与旧类型消费者,不把Ads专属批准自动扩大到VAST |
| callback字段 | art/id/ima/imaPlayer/$container/playUrl/playRes | art/playUrl/playRes/init/ima/adsRenderingSettings/playerOptions;imaPlayer/container为getter | 恢复真实发布别名并评估两套消费形状,不能漏掉旧id/$container |
| 初始化 | 回调前创建Player和container,imaPlayer非空 | init/playUrl/playRes触发懒初始化,回调初始imaPlayer/container为null | 立即初始化与惰性行为存在真实冲突,明确处置而非假称两者一致 |
| 请求 | playUrl写adTagUrl;playRes写adsResponse;都返回void | 增加config枚举覆盖,可覆盖主字段;广告播放中请求直接返回 | 保留合法请求及config用法,测试继承字段/重复/失败路径 |
| 返回值 | await后仅{name} | await后{name,destroy},destroy同步 | 核心destroy与显式SDK destroy区分,核实重建语义 |
| 容器 | `art-${Date.now()}`,display:none;交由SDK显示 | `art-vast-${Date.now()}`,黑底/pointerEvents;监听四种广告事件显隐 | DOM/ID/事件时序及同毫秒多实例待测 |
| 默认SDK设置 | new AdsRenderingSettings/PlayerOptions默认值 | 额外打开restoreCustomPlaybackStateOnAdBreakComplete和enablePreloading | 先固定真实SDK行为,禁止把默认值变化当作无影响整理 |
| CommonJS/script | Parcel namespace `{default:factory}`,window全局;main/legacy | callable、ESM/legacy和exports | 兼容旧`.default`、原dist路径和类型入口 |
| 生命周期 | 无核心destroy订阅,无自动清理 | 仍无核心destroy订阅,只有回调完成后的公开destroy | 资源所有权、SDK加载中销毁、callback拒绝、晚到事件需复现及修复 |
## SDK与历史核心
发布版依赖范围@glomex/vast-ima-player ^1.21.0,工作区^1.21.2、锁定安装1.21.2。
冻结SDK1.21.0/1.21.2的全部27+27成员及插件6成员,SHA512和SHA256校验,不把
工作区node_modules当作实际发布来源。SDK打包代码包含loadImaSdk,远程地址为
`https://imasdk.googleapis.com/js/sdkloader/ima3.js`;该远程服务不是已冻结的本地SDK
tarball,真实网络/广告行为仍需05取证。
两版SDK的公开dist/index.d.ts和vast-ima-player.d.ts都引用@alugha/ima,但仅把它
列入devDependencies。当前工作区未安装该包,TS5.9.3和4.3.5的最小VAST消费者各有
两个TS2307;记录在本步验证证据中。04应使实际安装后的声明自洽,不能依靠skipLibCheck。
发布gitHead对应核心5.1.7,源manifest哈希已固定;这是历史关联,不是该核心tarball
或媒体组合已通过。02/05应核验真实5.1.7以及5.4.1/候选核心。
## 验证边界
`vast-contract.mjs`校验三份归档、60成员、冻结Git源码与核心关联。
`vast-contract.test.mjs`执行实际发布main/legacy的导出形状,并在准确SDK注入边界
运行哈希校验过的两套源码,观察callback字段、提前/惰性初始化、Promise等待、
请求配置和Result。这里的Player是受控记录器,不是Google IMA或真实广告播放。
VM导出检查提供当前平台CustomEvent;初次未提供时触发SDK事件polyfill的document
访问,属于测试夹具缺项,不能泛称当前Node的SSR必然失败。
用户明确更正:只有VAST脚本确因VPN规则始终无法加载时,可以记录并跳过,留给用户
后续处理。仍记录实际失败与未验证范围;本轮注册表/归档下载正常,未使用此例外。
+284
View File
@@ -0,0 +1,284 @@
{
"schemaVersion": 1,
"task": "PKG-VAST-01",
"capturedAt": "2026-09-12T00:54:44.270Z",
"sourceCommit": "29692d28158ad50e1d404293f592679c10dbf3f5",
"registryObservation": {
"registryUrl": "https://registry.npmjs.org/artplayer-plugin-vast",
"distTags": {
"latest": "1.0.0"
},
"versions": [
"1.0.0"
],
"publishedAt": "2024-10-12T08:56:54.614Z",
"workspaceVersion": "1.2.0",
"workspaceVersionPublished": false
},
"release": {
"name": "artplayer-plugin-vast",
"version": "1.0.0",
"metadataUrl": "https://registry.npmjs.org/artplayer-plugin-vast/1.0.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-vast/-/artplayer-plugin-vast-1.0.0.tgz",
"integrity": "sha512-6ia0BYlZMBUAbvfqPq6RD3kvCP/Vpnqjs4zgzcio0CUh3a/iJkp+caKFOFjROfilbL+B0lXUiA7U1kS9KqEwTg==",
"sha256": "35681d60fa3fa09b92f0f30887e39c73cf55e7b14d51a1c38fccbc6c1f253bab",
"archiveBytes": 18457,
"registryGitHead": "252c226473792fd1537c1ff4a323344bf1060efc",
"files": {
"package/README.md": "2476f0b0ec9c6957f8cf0902384faf638f34e35309b00a24dbb74ee4ce3d3019",
"package/dist/artplayer-plugin-vast.js": "bf3429ca7650fdedc03a7e3e92abc192c4eac87a97c0895e3a0f82921aa361d0",
"package/dist/artplayer-plugin-vast.legacy.js": "3f86ff7558662687f794790a33a76305e2947304a0800e0e4d6788fbec54bbcf",
"package/package.json": "8e2eadca73c8ecbdad130115ea340efe5ae6d52668771f27e1b3c6009d706f46",
"package/src/index.js": "6811308508bfcb3f8b8c94510c90bde0308996ecdaf1008b110d041dc962d4a4",
"package/types/artplayer-plugin-vast.d.ts": "51257361f482f026a9b5ba84ca85d320d9e1457a34d0d259ac3c7b46c4fbd29c"
},
"manifest": {
"license": "MIT",
"version": "1.0.0",
"name": "artplayer-plugin-vast",
"types": "types/artplayer-plugin-vast.d.ts",
"description": "vast plugin for ArtPlayer",
"main": "dist/artplayer-plugin-vast.js",
"legacy": "dist/artplayer-plugin-vast.legacy.js",
"author": "Harvey Zack <laozhaochaguan@gmail.com>",
"browserslist": "last 1 Chrome version",
"homepage": "https://artplayer.org",
"repository": {
"type": "git",
"url": "git+https://github.com/zhw2590582/ArtPlayer.git"
},
"bugs": {
"url": "https://github.com/zhw2590582/ArtPlayer/issues"
},
"keywords": [
"html5",
"video",
"player"
],
"dependencies": {
"@glomex/vast-ima-player": "^1.21.0"
}
}
},
"sdk": [
{
"name": "@glomex/vast-ima-player",
"version": "1.21.0",
"metadataUrl": "https://registry.npmjs.org/%40glomex%2Fvast-ima-player/1.21.0",
"tarball": "https://registry.npmjs.org/@glomex/vast-ima-player/-/vast-ima-player-1.21.0.tgz",
"integrity": "sha512-TfMiihsXP1Wwhe+H9EzRoiq8FUVssiKWiCAKgAw2EN32tdF28mmVc83LCdh2j65tKXZ8yT5RSUdI5Hlz4t79aQ==",
"sha256": "924405b92ac5ccb4cc775d13b5caba6dc6fb537d55b0cb3ca128cb9be4b2bc48",
"archiveBytes": 148164,
"registryGitHead": "789a7ab51d0a176ec747c9a99e6e482184d51d80",
"files": {
"package/LICENSE": "68b35bb64e6269277318ff4e4ee66a738bdeb83bbcdc7e3c3af85a0bdded8d0b",
"package/README.md": "26867a31c5546f9b40b41b50c168c0b073bdf9d8ff331521540adfc2187946ed",
"package/dist/custom-playhead.d.ts": "24de4901d6ff04c5a8f55fd2a5001c8c47c72cbd3f072d673a1deafa200656a9",
"package/dist/delegated-event-target.d.ts": "d1eb0fdc1e9c497e6c04d5c83dc22483d5644d1bd9b430bd51c63d13d32432c7",
"package/dist/index.d.ts": "ce1c59659a68c54fe5af34b94550f3de9d4400b8315c188f679ecab19f87b80f",
"package/dist/vast-ima-player.d.ts": "a6d80180646fcebc1255a75dcd780b618f226a111dfa33cb5fa64681071b7c16",
"package/dist/vast-ima-player.js": "5f565b78d336eecb32982bc0038528547e1c6d17b6478ee60c3ecbe3b720b58d",
"package/dist/vast-ima-player.js.map": "a55d8ef507597c87337d63de2158b62316193700264ef2ecadef0d0b909b6f00",
"package/dist/vast-ima-player.modern.js": "23c119fb54e190e38398a899fb2fb1809dbe5eaa9fccfda2f27d11920c28f3fe",
"package/dist/vast-ima-player.modern.js.map": "24e45e89da1ebcc9c276e6681c1bfb824f884a1129f15daea0e6da903e33e8b1",
"package/dist/vast-ima-player.module.js": "52f4bf3f39771e35c40b464d23de3ba0e770ca4684d908590f926055dba5b4f9",
"package/dist/vast-ima-player.module.js.map": "a1e91c835162f8ea2b13bcb63390f62cfe7a38fb018119662f9d9602e443d910",
"package/dist/vast-ima-player.umd.js": "38014c18a51138e5093ae4cf743e84cdae3e431816581f08f16cf0c10e932eae",
"package/dist/vast-ima-player.umd.js.map": "e119d5f96b8113710a72cdabe18e45531c455176a5fd74d3466e6446e31e3e45",
"package/package.json": "340bbbb564be16642e5326d180d6a4a5a8e0bb82e688d2d995d3ff5454f79667",
"package/src/custom-playhead.ts": "326ddefbb15b05b5f3c9b25de88b84bce97ace248e747efcfebd476951f7734e",
"package/src/delegated-event-target.ts": "0937aeaea09a115b10f742ec95dd19bfeee5aece4a95e83ef95d9ea7a09d1064",
"package/src/index.ts": "db58ca160cf01af6e8ef50872a077a3fc4b1c6551cecde1646c06fb5d944771e",
"package/src/vast-ima-player.ts": "25a630d51f770a298cba35791581d30ea3079c406830988c5efb28e0ad9531e4",
"package/test-page/bulma-slider.min.css": "9bd5f05ad71360d0e87f21dd3d07d94c080486342f335ff041f5394c6aa6dac9",
"package/test-page/bulma-slider.min.js": "e520e9ef6e3223ecfbb50b4649d238af5a85af9161800ad1d003dac80d748f24",
"package/test-page/bulma.min.css": "58b28659220961ead137cb5b346b5759562750ce703094d70fc786e0db467033",
"package/test-page/index.html": "41eb8677b1cbd260407d0d829ab8cb4838dbe834c537f5e7c372d7d25b024591",
"package/test-page/rollup.config.js": "8949cb766b7e4cab9506607e28d79887e3c60ae3b152c9445aef86d8e4d0f22d",
"package/test-page/test-page.bundle.js": "a7b4b66fc708b6cfc7cf07a11d00e825f658952ae9e8935388288cb05221c6d8",
"package/test-page/test-page.bundle.js.map": "ae996c9a5298853aebbd0374fef99f57016053746bc8e7083f978cc482f0f92f",
"package/test-page/test-page.js": "a4d7d98bd4fb57425df80e8448c1631a4aeeadfd88cf4a788d1d787c59756a53"
},
"manifest": {
"name": "@glomex/vast-ima-player",
"version": "1.21.0",
"description": "Convenience wrapper for advertising video/audio content with Google IMA",
"source": "src/index.ts",
"main": "dist/vast-ima-player.js",
"module": "dist/vast-ima-player.module.js",
"unpkg": "dist/vast-ima-player.umd.js",
"types": "dist/index.d.ts",
"mangle": {
"regex": "^_"
},
"scripts": {
"prepare": "npm run -s build",
"build": "npm-run-all --parallel build:*",
"build:bundle": "rollup -c test-page/rollup.config.js",
"build:test-page": "microbundle",
"start": "npm-run-all --parallel start:*",
"start:serve": "serve",
"start:bundle": "microbundle watch",
"start:test-page": "rollup -c test-page/rollup.config.js --watch",
"lint": "tslint -c tslint.json 'src/**/*.ts'",
"test": "karma start karma.conf.js --single-run"
},
"files": [
"dist",
"src",
"test-page"
],
"keywords": [
"ima",
"ima-sdk",
"ad",
"googleads",
"vast",
"vpaid",
"vmap",
"player",
"video-player"
],
"repository": "github:glomex/vast-ima-player",
"bugs": {
"url": "https://github.com/glomex/vast-ima-player/issues"
},
"author": "glomex GmbH",
"license": "Apache-2.0",
"devDependencies": {
"@alugha/ima": "^2.1.0",
"@ungap/custom-event": "^0.3.1",
"form-to-object": "^6.0.0",
"jasmine": "^4.1.0",
"karma": "^6.3.18",
"karma-chrome-launcher": "^3.1.1",
"karma-firefox-launcher": "^2.1.2",
"karma-jasmine": "^5.0.0",
"microbundle": "^0.13.3",
"npm-run-all": "^4.1.5",
"serve": "^13.0.2",
"tslint": "^6.1.3",
"typescript": "^4.6.3"
}
}
},
{
"name": "@glomex/vast-ima-player",
"version": "1.21.2",
"metadataUrl": "https://registry.npmjs.org/%40glomex%2Fvast-ima-player/1.21.2",
"tarball": "https://registry.npmjs.org/@glomex/vast-ima-player/-/vast-ima-player-1.21.2.tgz",
"integrity": "sha512-dmWB5enpmCvDEIg0AwDWfGehnshg/nvUpuDzgyKLGmqQx8K0vl/1GXEvgrAhN4fVb0lCIgwB/rXFdBZ9yPLwhw==",
"sha256": "5b5575c3a6c68a2a550c986348093de7471476318c9ec443285063dfbef3f9b5",
"archiveBytes": 148148,
"registryGitHead": "2a72ce27d81ff709cf8488324d80107e0fc484f9",
"files": {
"package/LICENSE": "68b35bb64e6269277318ff4e4ee66a738bdeb83bbcdc7e3c3af85a0bdded8d0b",
"package/README.md": "26867a31c5546f9b40b41b50c168c0b073bdf9d8ff331521540adfc2187946ed",
"package/dist/custom-playhead.d.ts": "24de4901d6ff04c5a8f55fd2a5001c8c47c72cbd3f072d673a1deafa200656a9",
"package/dist/delegated-event-target.d.ts": "d1eb0fdc1e9c497e6c04d5c83dc22483d5644d1bd9b430bd51c63d13d32432c7",
"package/dist/index.d.ts": "ce1c59659a68c54fe5af34b94550f3de9d4400b8315c188f679ecab19f87b80f",
"package/dist/vast-ima-player.d.ts": "a6d80180646fcebc1255a75dcd780b618f226a111dfa33cb5fa64681071b7c16",
"package/dist/vast-ima-player.js": "7e5481a5ea01df8178202fc36f96830e0ec1c920c27023e8de8479f90168f5eb",
"package/dist/vast-ima-player.js.map": "af1e5d4d981f914d5ed05b2f04469d0f469dd73233a23816467c2daf7cd821bf",
"package/dist/vast-ima-player.modern.js": "b2e40300da6392465a662ff05f617998435bbc9d8e36d76c91e0440ce0277c97",
"package/dist/vast-ima-player.modern.js.map": "86ed6a4ab1c5344480b2293141ba6f6784656393f75afb268596f3b623b769b2",
"package/dist/vast-ima-player.module.js": "861ace7a869c1eda98ccae1c42e617afa74e8a6d79e26e6ce2a052812e7314a7",
"package/dist/vast-ima-player.module.js.map": "8e4c6c85aae149581bcbb52d8d6192dcd22a354de47571db7e73d47ad275af40",
"package/dist/vast-ima-player.umd.js": "bfe5f9ba07cf3c6964edb91cba222af0214365a8fbbd25783a7a39a1393a49c7",
"package/dist/vast-ima-player.umd.js.map": "55d37417c392bbc758ecce58e96d7edc6c84e1309663eca5477a53ebe1e9e289",
"package/package.json": "c7361321ce792f6830af9eb40e70b7508a75f68290a3c0077e26a6f36daa7097",
"package/src/custom-playhead.ts": "326ddefbb15b05b5f3c9b25de88b84bce97ace248e747efcfebd476951f7734e",
"package/src/delegated-event-target.ts": "0937aeaea09a115b10f742ec95dd19bfeee5aece4a95e83ef95d9ea7a09d1064",
"package/src/index.ts": "db58ca160cf01af6e8ef50872a077a3fc4b1c6551cecde1646c06fb5d944771e",
"package/src/vast-ima-player.ts": "09c59b3051aa38b66657bc84f8d0e55f48b46577bff8090930b4729e9a3022d1",
"package/test-page/bulma-slider.min.css": "9bd5f05ad71360d0e87f21dd3d07d94c080486342f335ff041f5394c6aa6dac9",
"package/test-page/bulma-slider.min.js": "e520e9ef6e3223ecfbb50b4649d238af5a85af9161800ad1d003dac80d748f24",
"package/test-page/bulma.min.css": "58b28659220961ead137cb5b346b5759562750ce703094d70fc786e0db467033",
"package/test-page/index.html": "41eb8677b1cbd260407d0d829ab8cb4838dbe834c537f5e7c372d7d25b024591",
"package/test-page/rollup.config.js": "8949cb766b7e4cab9506607e28d79887e3c60ae3b152c9445aef86d8e4d0f22d",
"package/test-page/test-page.bundle.js": "a7b4b66fc708b6cfc7cf07a11d00e825f658952ae9e8935388288cb05221c6d8",
"package/test-page/test-page.bundle.js.map": "ae996c9a5298853aebbd0374fef99f57016053746bc8e7083f978cc482f0f92f",
"package/test-page/test-page.js": "a4d7d98bd4fb57425df80e8448c1631a4aeeadfd88cf4a788d1d787c59756a53"
},
"manifest": {
"name": "@glomex/vast-ima-player",
"version": "1.21.2",
"description": "Convenience wrapper for advertising video/audio content with Google IMA",
"source": "src/index.ts",
"main": "dist/vast-ima-player.js",
"module": "dist/vast-ima-player.module.js",
"unpkg": "dist/vast-ima-player.umd.js",
"types": "dist/index.d.ts",
"mangle": {
"regex": "^_"
},
"scripts": {
"prepare": "npm run -s build",
"build": "npm-run-all --parallel build:*",
"build:bundle": "rollup -c test-page/rollup.config.js",
"build:test-page": "microbundle",
"start": "npm-run-all --parallel start:*",
"start:serve": "serve",
"start:bundle": "microbundle watch",
"start:test-page": "rollup -c test-page/rollup.config.js --watch",
"lint": "tslint -c tslint.json 'src/**/*.ts'",
"test": "karma start karma.conf.js --single-run"
},
"files": [
"dist",
"src",
"test-page"
],
"keywords": [
"ima",
"ima-sdk",
"ad",
"googleads",
"vast",
"vpaid",
"vmap",
"player",
"video-player"
],
"repository": "github:glomex/vast-ima-player",
"bugs": {
"url": "https://github.com/glomex/vast-ima-player/issues"
},
"author": "glomex GmbH",
"license": "Apache-2.0",
"devDependencies": {
"@alugha/ima": "^2.1.0",
"@ungap/custom-event": "^0.3.1",
"form-to-object": "^6.0.0",
"jasmine": "^4.1.0",
"karma": "^6.3.18",
"karma-chrome-launcher": "^3.1.1",
"karma-firefox-launcher": "^2.1.2",
"karma-jasmine": "^5.0.0",
"microbundle": "^0.13.3",
"npm-run-all": "^4.1.5",
"serve": "^13.0.2",
"tslint": "^6.1.3",
"typescript": "^4.6.3"
}
}
}
],
"source": {
"packages/artplayer-plugin-vast/src/index.js": "cba7d7a5822d4088655c301264280dc19d67b1f1716e4e50c8a6dcb8b5580763",
"packages/artplayer-plugin-vast/types/artplayer-plugin-vast.d.ts": "38ba4b3e03b261c53a062d94bc73e1a9c4f453681d33ce6f7bf8d9b06ec2f052",
"packages/artplayer-plugin-vast/package.json": "615a17004252aa9301167a28d4b067f9d2866aa2392febad71c85cea02dbbd8e",
"packages/artplayer-plugin-vast/README.md": "91e1cdfd47fb6eabfc4cd44f15d44dc33201479e09552ac237505bb0658a8fbe",
"docs/assets/example/vast.js": "ce93b48fabc2f1fd39fdaa8af3ae9f86a420c9aa65551e2e196d754070f36064",
"packages/artplayer-plugin-vast/dist/artplayer-plugin-vast.js": "72842ae0b4a44e44a080f88783c0c9bcd0b572fa0e946d817b2c36d960a08bfe",
"packages/artplayer-plugin-vast/dist/artplayer-plugin-vast.legacy.js": "4b88cec8d12844d639cc7703f88703136a4fe586781d9939bf2e3a0c93b42b60",
"packages/artplayer-plugin-vast/dist/artplayer-plugin-vast.mjs": "91fbe929a9d8d780f1656b53697fb0fe400b9375db79370866ec2f4c5313e727"
},
"historicalCore": {
"commit": "252c226473792fd1537c1ff4a323344bf1060efc",
"file": "packages/artplayer/package.json",
"version": "5.1.7",
"sha256LF": "8bd532103099c367fb2c289e0d410f144fdeb00b1b62cf850762a24b61e63c8a",
"note": "Git association only; actual core tarball and browser combination remain task02/05."
}
}
@@ -0,0 +1,26 @@
# PKG-VAST-01 真实契约冻结
起点29692d28。核对实际发布VAST1.0.0、未发布工作区1.2.0、SDK1.21.0/1.21.2及
发布关联核心5.1.7。详情见 [契约表](../baselines/vast-contract.md) 和
[归档](../baselines/vast-release.json)。本任务不修改生产源码、类型、依赖或产物。
新增可持续运行的归档验证和四项契约测试;实际发布JS/legacy导出直接执行,两套
源码在仅替换SDK的受控边界运行。证实发布callback拥有id/$container及已创建Player,
工作区移除别名并改为懒创建;两者实际均异步而声明写成同步。另确认SDK公开类型
引用dev-only依赖,当前最小消费者在两种TS版本各复现两个TS2307。
API-06/07/09/11差异、默认设置及初始化时机、资源清理和外部SDK验证分别登记为
VAST-CONTEXT-01/TYPE-01/LIFE-01/DIST-01和既有SDK-07,指派02~06处理,不以
本次基线通过宣称这些问题已修复。Ads类型批准不扩大到VAST异步声明差异。
用户已更正VPN跳过授权对象为VAST;若脚本持续被规则阻止,可记录并跳过其实际
网络验证,由用户后续修复。正常的本地契约/生命周期/类型改造继续执行。
所有检查和输入指纹见 [验证记录](../baselines/vast-contract-validation.json)。
本步53项基线测试全通过(其中新增VAST四项),脚本及仓库lint、计划与147项风险
台账检查通过。没有生产变更,本步未重复完整CI、构建或真实广告媒体验收。
首次VM测试遗漏CustomEvent,SDK fallback访问document导致失败;提供平台原生
CustomEvent后实际导出检查通过,不修改发布bundle。生产SSR仍由分发任务单独测试。
回退本任务仅撤销本步文档/台账/测试,不改第三方归档或生产文件。完成后独立本地
提交PKG-VAST-01,无推送、tag、发布。下一步02建立SDK失败、回调、事件和销毁测试。
+8 -7
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 217 项,范围 22 个包及工作区/示例。
状态:todo 134 / doing 5 / blocked 0 / done 78 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 133 / doing 5 / blocked 0 / done 79 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -267,12 +267,12 @@
| ID | 范围 / 步骤 | 前置依赖 | 交付物 | 验收条件 | 风险 | 状态 |
| --- | --- | --- | --- | --- | --- | --- |
| PKG-VAST-01 | artplayer-plugin-vast<br>核对包契约与历史用法 | BASE-05 | 异步工厂、callback context、playUrl/playRes/init 与 SDK 版本 | 源码/声明/README/demo/发布包差异已登记;公开形状和版本范围冻结 | H | todo |
| PKG-VAST-02 | artplayer-plugin-vast<br>建立特有行为与错误测试 | PKG-VAST-01, ENG-03, ENG-05 | SDK 失败、重复初始化、广告事件、内容恢复和销毁竞态 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | todo |
| PKG-VAST-03 | artplayer-plugin-vast<br>整理内部职责与资源 | PKG-VAST-02, CORE-10, CORE-13 | SDK loader、IMA adapter、广告状态和 DOM 清理分离 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | todo |
| PKG-VAST-04 | artplayer-plugin-vast<br>迁移自有源码和公开类型 | PKG-VAST-03, ENG-04, ENG-06, CORE-07 | IMA/context/Promise 真实类型,外部 SDK 动态对象限定边界 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | todo |
| PKG-VAST-05 | artplayer-plugin-vast<br>验证新旧核心和组合 | PKG-VAST-04, CORE-22 | 官方测试广告或受控 SDK 环境,错误后主视频状态恢复 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-VAST-06 | artplayer-plugin-vast<br>验证分发并同步文档 | PKG-VAST-05, ENG-07 | vast.js、SDK 资源、声明消费和独立版本记录 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
| PKG-VAST-01 | artplayer-plugin-vast<br>核对包契约与历史用法 | BASE-05 | 异步工厂、callback context、playUrl/playRes/init 与 SDK 版本;实际 npm 1.0.0 与未发布 1.2.0、SDK 1.21.0/1.21.2 的60成员归档和发布关联核心5.1.7 | 源码/声明/README/demo/发布包差异已登记;公开形状和版本范围冻结 | H | done |
| PKG-VAST-02 | artplayer-plugin-vast<br>建立特有行为与错误测试 | PKG-VAST-01, ENG-03, ENG-05 | SDK 失败、重复初始化、广告事件、内容恢复和销毁竞态;发布 id/$container/eager 与工作区 lazy/config 覆盖、callback拒绝、加载中销毁、同毫秒多实例与晚到事件 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | todo |
| PKG-VAST-03 | artplayer-plugin-vast<br>整理内部职责与资源 | PKG-VAST-02, CORE-10, CORE-13 | SDK loader、IMA adapter、广告状态和 DOM 清理分离;保持发布 callback 别名,明确初始化冲突;核心终止与显式 destroy 后重建区分 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | todo |
| PKG-VAST-04 | artplayer-plugin-vast<br>迁移自有源码和公开类型 | PKG-VAST-03, ENG-04, ENG-06, CORE-07 | IMA/context/Promise 真实类型,外部 SDK 动态对象限定边界;修复 @alugha/ima 声明依赖链,保留 export= 和 require.default 消费;同步错误声明的兼容决策单列 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | todo |
| PKG-VAST-05 | artplayer-plugin-vast<br>验证新旧核心和组合 | PKG-VAST-04, CORE-22 | 官方测试广告或受控 SDK 环境,错误后主视频状态恢复;核验真实5.1.7/5.4.1/候选核心,VAST VPN外部脚本例外逐项记录,不将受控SDK当作实际IMA验收 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-VAST-06 | artplayer-plugin-vast<br>验证分发并同步文档 | PKG-VAST-05, ENG-07 | vast.js、SDK 资源、声明消费和独立版本记录;核验实际发布 namespace default、历史深路径、ESM和准确声明,版本按政策2.0.0由REL-09统一处理 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
## 5 包迁移:artplayer-plugin-chromecast
@@ -489,3 +489,4 @@
- PKG-ADS-03: [记录](changes/2026-09-12-PKG-ADS-03-lifecycle.md) [记录](ads-validation.md) [记录](baselines/ads-lifecycle-validation.json)
- PKG-ADS-04: [记录](changes/2026-09-12-PKG-ADS-04-types.md) [记录](baselines/ads-types-validation.json)
- PKG-ADS-05: [记录](changes/2026-09-12-PKG-ADS-05-browser.md) [记录](baselines/ads-ui-visibility-validation.json)
- PKG-VAST-01: [记录](baselines/vast-contract.md) [记录](baselines/vast-release.json) [记录](changes/2026-09-12-PKG-VAST-01-contract.md) [记录](baselines/vast-contract-validation.json)
+10
View File
@@ -1,5 +1,15 @@
# 进度与证据
## 最新完成:VAST-01 实际发布契约
固定实际发布1.0.0、未发布工作区1.2.0及SDK1.21.0/1.21.2的60个归档成员。
四项可重跑测试确认公开callback字段、初始化、异步时序、请求配置和实际导出;
最小TS消费者复现缺失的SDK类型依赖。差异分配给02~06,尚未修改VAST生产源码。
VAST脚本的VPN跳过例外已按用户更正记录,本次未使用。下一步02补齐失败和销毁回归。
当前217项:79 done、5 doing、133 todo。详见
[本步记录](changes/2026-09-12-PKG-VAST-01-contract.md) 和
[验证证据](baselines/vast-contract-validation.json)。
## 当前实施:Ads-05 页面与媒体组合
补上27项原生全屏/多实例真实视频/详情导航/窄屏布局验证,源码、正式main/legacy均通过。
+4
View File
@@ -147,3 +147,7 @@
| ADS-LIFE-01 | resolved / 已复现 | Ads 计时链、重复/过早调用、工厂复用与销毁缺乏资源边界 | PKG-ADS-02, PKG-ADS-03, PKG-ADS-05 |
| ADS-MEDIA-01 | open / 已复现 | Ads metadata 与 play 拒绝、隐藏页媒体状态和内容恢复仍缺真实验证 | PKG-ADS-02, PKG-ADS-03, PKG-ADS-05 |
| ADS-UI-01 | resolved / 已复现 | Ads 零等待跳过与初始状态不符,全屏图标/外部状态需核验 | PKG-ADS-02, PKG-ADS-03, PKG-ADS-05 |
| VAST-CONTEXT-01 | open / 已复现 | Published VAST callback aliases and eager Player differ from the unpublished lazy workspace | PKG-VAST-02, PKG-VAST-03, PKG-VAST-04 |
| VAST-TYPE-01 | open / 已复现 | VAST declares an async factory as synchronous and imports an unavailable SDK type dependency | PKG-VAST-04, PKG-VAST-06 |
| VAST-LIFE-01 | open / 源码/产物事实 | VAST SDK and container lack core destruction ownership and pending work cancellation | PKG-VAST-02, PKG-VAST-03, PKG-VAST-05 |
| VAST-DIST-01 | open / 已复现 | Published VAST CommonJS default namespace differs from the current callable distribution | PKG-VAST-04, PKG-VAST-06 |
+81 -2
View File
@@ -702,10 +702,15 @@
"PKG-VAST-05"
],
"evidence": [
"packages/artplayer-plugin-vast/src/index.js"
"packages/artplayer-plugin-vast/src/index.js",
"refactor/baselines/vast-contract.md",
"refactor/baselines/vast-release.json",
"refactor/changes/2026-09-12-PKG-VAST-01-contract.md",
"refactor/baselines/vast-contract-validation.json"
],
"compatibleResolution": "@glomex/vast-ima-player loadImaSdk loads external IMA; preserve event/content/ad state and teardown, do not equate mocks with vendor service acceptance.",
"closureCriteria": "固定 SDK/外部资源版本和环境;成功/失败/切换/销毁有真实证据,设备和网络限制逐项记录。"
"closureCriteria": "固定 SDK/外部资源版本和环境;成功/失败/切换/销毁有真实证据,设备和网络限制逐项记录。",
"workspaceState": "VAST 1.0.0 and SDK 1.21.0/1.21.2 archives verified; Google IMA remote execution remains unverified. User allows recording/skipping only persistent VAST script loading failures caused by VPN rules, not Ads or other VAST code/type failures. This exception has not been used."
},
{
"id": "SDK-08",
@@ -3159,6 +3164,80 @@
"test/ads-lifecycle.test.js"
],
"resolutionRationale": "零/正/不可关闭阈值及错误输入由现有Node/媒体回归保持;main/legacy分别27项真实原生全屏(初始/外部退出/按钮)、静音、详情popup和窄屏翻译控件通过。截图已查看;手机设备策略仍由05媒体门槛承接。"
},
{
"id": "VAST-CONTEXT-01",
"title": "Published VAST callback aliases and eager Player differ from the unpublished lazy workspace",
"confirmation": "reproduced",
"status": "open",
"owners": [
"PKG-VAST-02",
"PKG-VAST-03",
"PKG-VAST-04"
],
"evidence": [
"refactor/baselines/vast-contract.md",
"refactor/baselines/vast-release.json",
"refactor/changes/2026-09-12-PKG-VAST-01-contract.md",
"refactor/baselines/vast-contract-validation.json"
],
"compatibleResolution": "Restore published id/$container access and reconcile eager non-null Player with lazy workspace usage using explicit consumer evidence.",
"closureCriteria": "Published and workspace consumer fixtures cover all callback fields and initialization timing; any irreconcilable behavior has a concrete decision rather than implicit waiver."
},
{
"id": "VAST-TYPE-01",
"title": "VAST declares an async factory as synchronous and imports an unavailable SDK type dependency",
"confirmation": "reproduced",
"status": "open",
"owners": [
"PKG-VAST-04",
"PKG-VAST-06"
],
"evidence": [
"refactor/baselines/vast-contract.md",
"refactor/baselines/vast-release.json",
"refactor/changes/2026-09-12-PKG-VAST-01-contract.md",
"refactor/baselines/vast-contract-validation.json"
],
"compatibleResolution": "Provide accurate Promise/context/IMA types and a self-contained installed declaration chain while checking legacy export= and consumers.",
"closureCriteria": "Strict isolated package consumers pass without skipLibCheck; synchronous Result inference differences are reproduced and resolved or separately approved. Ads approval does not apply."
},
{
"id": "VAST-LIFE-01",
"title": "VAST SDK and container lack core destruction ownership and pending work cancellation",
"confirmation": "source-observed",
"status": "open",
"owners": [
"PKG-VAST-02",
"PKG-VAST-03",
"PKG-VAST-05"
],
"evidence": [
"refactor/baselines/vast-contract.md",
"refactor/baselines/vast-release.json",
"refactor/changes/2026-09-12-PKG-VAST-01-contract.md",
"refactor/baselines/vast-contract-validation.json"
],
"compatibleResolution": "Reproduce pending SDK/callback destruction, errors, duplicate IDs and stale ad events before adding compatible cleanup and state ownership.",
"closureCriteria": "Tests prove cleanup during load/callback rejection/core destruction and distinguish explicit plugin recreation from terminal core destruction; vendor media restoration is separately verified."
},
{
"id": "VAST-DIST-01",
"title": "Published VAST CommonJS default namespace differs from the current callable distribution",
"confirmation": "reproduced",
"status": "open",
"owners": [
"PKG-VAST-04",
"PKG-VAST-06"
],
"evidence": [
"refactor/baselines/vast-contract.md",
"refactor/baselines/vast-release.json",
"refactor/changes/2026-09-12-PKG-VAST-01-contract.md",
"refactor/baselines/vast-contract-validation.json"
],
"compatibleResolution": "Preserve require(pkg).default alongside callable factory, script global and current ESM/legacy paths.",
"closureCriteria": "Real packed main/legacy/ESM, historical deep imports, export= consumers and local demo/editor all pass with immutable published comparisons."
}
]
}
+43
View File
@@ -0,0 +1,43 @@
import assert from 'node:assert/strict'
import { execFileSync } from 'node:child_process'
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import { archiveFiles, ensureArchive, hash, readMember, refactorDir } from './releases.mjs'
export async function verifyVastContract() {
const baseline = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/vast-release.json')))
const archives = new Map()
for (const release of [baseline.release, ...baseline.sdk]) {
const archive = await ensureArchive(release)
assert.deepEqual(archiveFiles(archive), Object.keys(release.files).sort())
for (const [member, expected] of Object.entries(release.files))
assert.equal(hash(readMember(archive, member)), expected, `${release.name}@${release.version}/${member}`)
assert.deepEqual(JSON.parse(readMember(archive, 'package/package.json')), release.manifest)
for (const field of ['main', 'module', 'types', 'legacy']) {
const target = release.manifest[field]
if (target)
assert(Object.hasOwn(release.files, `package/${target.replace(/^\.\//, '')}`))
}
archives.set(`${release.name}@${release.version}`, archive)
}
const sources = new Map()
assert(/^[a-f\d]{40}$/.test(baseline.sourceCommit))
for (const [file, expected] of Object.entries(baseline.source)) {
const content = execFileSync('git', ['show', `${baseline.sourceCommit}:${file}`]).toString().replaceAll('\r\n', '\n')
assert.equal(hash(content), expected, `Historical source changed: ${file}`)
sources.set(file, content)
}
const core = baseline.historicalCore
const manifest = execFileSync('git', ['show', `${core.commit}:${core.file}`]).toString().replaceAll('\r\n', '\n')
assert.equal(hash(manifest), core.sha256LF)
assert.equal(JSON.parse(manifest).version, core.version)
assert.equal(baseline.registryObservation.workspaceVersionPublished, false)
assert.deepEqual(baseline.registryObservation.versions, ['1.0.0'])
console.log('Verified VAST: published 1.0.0, two SDK archives, 60 members and frozen workspace/core association')
return { baseline, archives, sources }
}
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url))
await verifyVastContract()
+137
View File
@@ -0,0 +1,137 @@
import assert from 'node:assert/strict'
// eslint-disable-next-line test/no-import-node-test -- Verify immutable releases and wrapper contracts without external ad requests.
import test from 'node:test'
import vm from 'node:vm'
import { transform } from 'esbuild'
import { readMember } from './releases.mjs'
import { verifyVastContract } from './vast-contract.mjs'
const contract = await verifyVastContract()
const archive = contract.archives.get('artplayer-plugin-vast@1.0.0')
test('VAST published artifacts expose a CommonJS default namespace and browser global', () => {
for (const member of ['package/dist/artplayer-plugin-vast.js', 'package/dist/artplayer-plugin-vast.legacy.js']) {
const module = { exports: {} }
const window = {}
vm.runInNewContext(readMember(archive, member).toString(), { module, exports: module.exports, window, CustomEvent }, { timeout: 5000 })
assert.equal(typeof module.exports, 'object')
assert.deepEqual(Object.keys(module.exports), ['default'])
assert.equal(typeof module.exports.default, 'function')
assert.equal(window.artplayerPluginVast, module.exports.default)
assert.equal(typeof module.exports.default(), 'function')
}
})
function sdkFixture() {
const players = []
const ima = { AdsRenderingSettings: class {}, AdsRequest: class {} }
const sdk = {
loadImaSdk: async () => ima,
PlayerOptions: class {},
Player: class {
constructor(...args) {
this.args = args
this.requests = []
this.events = new Map()
players.push(this)
}
addEventListener(name, callback) { this.events.set(name, callback) }
playAds(request) { this.requests.push(request) }
destroy() { this.destroyed = true }
},
}
const node = () => ({ style: {}, parentNode: null })
const parent = {
children: [],
appendChild(child) {
child.parentNode = this
this.children.push(child)
return child
},
removeChild(child) {
child.parentNode = null
this.children.splice(this.children.indexOf(child), 1)
},
}
const art = { template: { $player: parent, $video: {} }, constructor: { utils: { createElement: node, setStyles: (target, styles) => Object.assign(target.style, styles), append: (target, child) => target.appendChild(child) } } }
return { players, ima, sdk, art }
}
async function loadSource(source, fixture) {
const module = { exports: {} }
const result = await transform(source, { loader: 'js', format: 'cjs', target: 'es2020' })
vm.runInNewContext(result.code, { module, exports: module.exports, window: { google: { ima: fixture.ima } }, console, require(name) {
assert.equal(name, '@glomex/vast-ima-player')
return fixture.sdk
} }, { timeout: 5000 })
return module.exports.default
}
for (const family of ['published', 'workspace']) {
test(`VAST ${family}: frozen source shows async callback timing and its exact context/initialization contract`, async () => {
const fixture = sdkFixture()
const source = family === 'published' ? readMember(archive, 'package/src/index.js').toString() : contract.sources.get('packages/artplayer-plugin-vast/src/index.js')
const factory = await loadSource(source, fixture)
let release
let callbackStarted
const ready = new Promise((resolve) => {
callbackStarted = resolve
})
const gate = new Promise((resolve) => {
release = resolve
})
const attaching = factory(async (value) => {
callbackStarted(value)
await gate
})(fixture.art)
assert.equal(typeof attaching.then, 'function', 'The historical synchronous declaration is inaccurate')
const context = await ready
assert(context)
assert.equal(context.art, fixture.art)
if (family === 'published') {
assert.deepEqual(Object.keys(context), ['art', 'id', 'ima', 'imaPlayer', '$container', 'playUrl', 'playRes'])
assert.equal(fixture.players.length, 1)
assert.equal(context.imaPlayer, fixture.players[0])
assert.equal(context.$container, fixture.art.template.$player.children[0])
assert.equal(context.id, context.$container.id)
assert.match(context.id, /^art-\d+$/)
}
else {
assert.deepEqual(Object.keys(context), ['art', 'playUrl', 'playRes', 'init', 'ima', 'adsRenderingSettings', 'playerOptions', 'imaPlayer', 'container'])
assert.equal(fixture.players.length, 0)
assert.equal(context.imaPlayer, null)
assert.equal(context.container, null)
assert.equal(context.id, undefined)
assert.equal(context.$container, undefined)
assert.equal(context.init(), context.init())
assert.equal(context.imaPlayer, fixture.players[0])
assert.equal(context.container, fixture.art.template.$player.children[0])
assert.equal(context.adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete, true)
assert.equal(context.adsRenderingSettings.enablePreloading, true)
}
assert.equal(context.playUrl('/ad.xml', { adTagUrl: '/override.xml', extra: 1 }), undefined)
assert.equal(fixture.players[0].requests[0].adTagUrl, family === 'published' ? '/ad.xml' : '/override.xml')
assert.equal(context.playRes('<VAST/>'), undefined)
assert.equal(fixture.players[0].requests[1].adsResponse, '<VAST/>')
release()
const result = await attaching
assert.deepEqual(Object.keys(result), family === 'published' ? ['name'] : ['name', 'destroy'])
assert.equal(result.name, 'artplayerPluginVast')
if (family === 'workspace') {
result.destroy()
assert.equal(fixture.players[0].destroyed, true)
assert.equal(context.container, null)
}
})
}
test('VAST wrapper SDK public declarations import a development-only dependency', () => {
for (const release of contract.baseline.sdk) {
assert.equal(release.manifest.dependencies?.['@alugha/ima'], undefined)
assert.equal(typeof release.manifest.devDependencies['@alugha/ima'], 'string')
const archive = contract.archives.get(`${release.name}@${release.version}`)
assert.match(readMember(archive, 'package/dist/index.d.ts').toString(), /from ['"]@alugha\/ima['"]/)
assert.match(readMember(archive, 'package/dist/vast-ima-player.d.ts').toString(), /from ['"]@alugha\/ima['"]/)
}
})
+13 -8
View File
@@ -2646,11 +2646,16 @@
"dependsOn": [
"BASE-05"
],
"status": "todo",
"status": "done",
"risk": "H",
"deliverable": "异步工厂、callback context、playUrl/playRes/init 与 SDK 版本",
"deliverable": "异步工厂、callback context、playUrl/playRes/init 与 SDK 版本;实际 npm 1.0.0 与未发布 1.2.0、SDK 1.21.0/1.21.2 的60成员归档和发布关联核心5.1.7",
"acceptance": "源码/声明/README/demo/发布包差异已登记;公开形状和版本范围冻结",
"evidence": []
"evidence": [
"baselines/vast-contract.md",
"baselines/vast-release.json",
"changes/2026-09-12-PKG-VAST-01-contract.md",
"baselines/vast-contract-validation.json"
]
},
{
"id": "PKG-VAST-02",
@@ -2666,7 +2671,7 @@
],
"status": "todo",
"risk": "H",
"deliverable": "SDK 失败、重复初始化、广告事件、内容恢复和销毁竞态",
"deliverable": "SDK 失败、重复初始化、广告事件、内容恢复和销毁竞态;发布 id/$container/eager 与工作区 lazy/config 覆盖、callback拒绝、加载中销毁、同毫秒多实例与晚到事件",
"acceptance": "旧版本行为可重跑,成功/失败/切源/销毁有必要断言",
"evidence": []
},
@@ -2684,7 +2689,7 @@
],
"status": "todo",
"risk": "H",
"deliverable": "SDK loader、IMA adapter、广告状态和 DOM 清理分离",
"deliverable": "SDK loader、IMA adapter、广告状态和 DOM 清理分离;保持发布 callback 别名,明确初始化冲突;核心终止与显式 destroy 后重建区分",
"acceptance": "结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过",
"evidence": []
},
@@ -2703,7 +2708,7 @@
],
"status": "todo",
"risk": "H",
"deliverable": "IMA/context/Promise 真实类型,外部 SDK 动态对象限定边界",
"deliverable": "IMA/context/Promise 真实类型,外部 SDK 动态对象限定边界;修复 @alugha/ima 声明依赖链,保留 export= 和 require.default 消费;同步错误声明的兼容决策单列",
"acceptance": "严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容",
"evidence": []
},
@@ -2720,7 +2725,7 @@
],
"status": "todo",
"risk": "H",
"deliverable": "官方测试广告或受控 SDK 环境,错误后主视频状态恢复",
"deliverable": "官方测试广告或受控 SDK 环境,错误后主视频状态恢复;核验真实5.1.7/5.4.1/候选核心,VAST VPN外部脚本例外逐项记录,不将受控SDK当作实际IMA验收",
"acceptance": "最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成",
"evidence": []
},
@@ -2737,7 +2742,7 @@
],
"status": "todo",
"risk": "H",
"deliverable": "vast.js、SDK 资源、声明消费和独立版本记录",
"deliverable": "vast.js、SDK 资源、声明消费和独立版本记录;核验实际发布 namespace default、历史深路径、ESM和准确声明,版本按政策2.0.0由REL-09统一处理",
"acceptance": "tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录",
"evidence": []
},