diff --git a/docs/assets/ts/artplayer-plugin-vtt-thumbnail.d.ts b/docs/assets/ts/artplayer-plugin-vtt-thumbnail.d.ts index 4e8307e77..da1a030a8 100644 --- a/docs/assets/ts/artplayer-plugin-vtt-thumbnail.d.ts +++ b/docs/assets/ts/artplayer-plugin-vtt-thumbnail.d.ts @@ -1,10 +1,29 @@ -declare const artplayerPluginVttThumbnail: (option: { vtt?: string, style?: Partial }) => ( - art: Artplayer, -) => { - name: 'artplayerPluginVttThumbnail' +// Generated from the package public declaration by yarn build:ts. Do not edit. +/* eslint-disable ts/no-redeclare -- Callable and public type namespace intentionally merge. */ +declare namespace artplayerPluginVttThumbnailDefinitions { + export interface Option { + vtt?: string + style?: Partial + } + export interface Result { + name: 'artplayerPluginVttThumbnail' + } + /** Historical factory type. Actual registration is asynchronous. */ + export type Factory = (option: Option) => (art: Artplayer) => Result + /** Accurate runtime view available without casts through the /runtime entry. */ + export interface RuntimeFactory { + (option: Option): (art: Artplayer) => Promise + default: RuntimeFactory + } + /** Preserve historical extraction and replacement-function compatibility. */ + export function artplayerPluginVttThumbnail(option: Option): (art: Artplayer) => Result +} +declare const artplayerPluginVttThumbnail: typeof artplayerPluginVttThumbnailDefinitions.artplayerPluginVttThumbnail +declare namespace artplayerPluginVttThumbnail { + export type Option = artplayerPluginVttThumbnailDefinitions.Option + export type Result = artplayerPluginVttThumbnailDefinitions.Result + export type Factory = artplayerPluginVttThumbnailDefinitions.Factory + export type RuntimeFactory = artplayerPluginVttThumbnailDefinitions.RuntimeFactory } - -export default artplayerPluginVttThumbnail - export = artplayerPluginVttThumbnail export as namespace artplayerPluginVttThumbnail; diff --git a/docs/compiled/artplayer-plugin-vtt-thumbnail.js b/docs/compiled/artplayer-plugin-vtt-thumbnail.js index 123ef4a7c..10778ae94 100644 --- a/docs/compiled/artplayer-plugin-vtt-thumbnail.js +++ b/docs/compiled/artplayer-plugin-vtt-thumbnail.js @@ -4,4 +4,4 @@ * (c) 2017-2026 Harvey Zhao * Released under the MIT License. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginVttThumbnail=e(),define(function(){return t.artplayerPluginVttThumbnail})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginVttThumbnail=e()}(this,function(){"use strict";function t(t,e){throw new TypeError(`Invalid VTT thumbnail at line ${t}: ${e}`)}function e(e,n){/^\d{2,}(?::\d{2}){0,2}(?:\.\d{3})?$/.test(e)||t(n,"invalid timestamp");const[i,o="0"]=e.split("."),r=i.split(":").reduce((t,e)=>60*t+Number(e),0)+Number(o)/1e3;return Number.isSafeInteger(Math.floor(r))||t(n,"timestamp exceeds the supported numeric range"),r}function n(e,n,i){const o=e.match(/^(.+)#([xywh]{4})=(.*)$/);o&&4===new Set(o[2]).size||t(i,"expected an image URL and four distinct xywh keys");const r=o[3].split(",").map(t=>t.trim());4!==r.length&&t(i,"expected four rectangle coordinates");const s={};for(let c=0;c<4;c++){const e=o[2][c],n=r[c];/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(n)&&Number.isFinite(Number(n))||t(i,"rectangle coordinates must be finite non-negative decimals"),"w"!==e&&"h"!==e||0!==Number(n)||t(i,"rectangle width and height must be positive"),s[e]=n}let l=o[1];if(!/^\/|(?:https?|ftp|file):\/\//i.test(l)){const t=n.split("/");t.pop(),t.push(l),l=t.join("/")}return{url:l,...s}}function i({lifetime:t,thumbnails:e,progress:n,duration:i,setStyle:o,isMobile:r}){let s=null,l=0;function c(e,n,i){t.closed||o(e,n,i)}return t.own(()=>{if(l++,null!==s){const t=s;s=null,clearTimeout(t)}}),o=>async(u,a,d)=>{if(t.closed)return;const f="played"===u&&d&&r;if("hover"!==u&&!f)return;const m=n.clientWidth*a,h=a*i();if(c(o,"display","flex"),t.closed)return;const p=function(t,e){return t.find(t=>e>=t.start&&e<=t.end)}(e,h);if(!p)return c(o,"display","none");if(m>0&&mn.clientWidth-Number(e.w)/2?c(t,"left",n.clientWidth-Number(e.w)+"px"):c(t,"left",i-Number(e.w)/2+"px")}(o,p,m):r||c(o,"display","none"),f&&!t.closed){const e=++l;if(null!==s&&clearTimeout(s),t.closed)return;const n=setTimeout(()=>{e!==l||t.closed||(s=null,c(o,"display","none"))},500);t.closed||e!==l?clearTimeout(n):s=n}}}return function(o){return async r=>{const{setStyle:s,isMobile:l,addClass:c}=r.constructor.utils,{$progress:u}=r.template,a=function(t){let e=Boolean(t.isDestroy);const n=new Set;let i;const o=new Promise(t=>{i=t}),r={get closed(){return e},own:t=>(e?s(t):n.add(t),()=>n.delete(t)),listen(n,i){e||(r.own(()=>t.off(n,i)),t.on(n,i))},wait:t=>Promise.race([t,o]),dispose(){if(e)return;e=!0,i();const t=[...n].reverse();n.clear();for(const e of t)s(e)}};function s(t){try{t()}catch(e){console.warn("Failed to clean up VTT thumbnails:",e)}}try{r.listen("destroy",r.dispose)}catch(l){throw r.dispose(),l}return r}(r),d={name:"artplayerPluginVttThumbnail"};try{if(a.closed)return d;const f=o.vtt,m=await async function(t="",e){if(e.closed)return;const n="function"===typeof AbortController?new AbortController:null,i=e.own(()=>n?.abort());try{if(e.closed)return;const i=await e.wait(n?fetch(t,{signal:n.signal}):fetch(t));if(e.closed)return;if(!1===i.ok)throw new Error(`Failed to fetch VTT thumbnails: HTTP ${i.status}`);if(e.closed)return;return await e.wait(i.text())}finally{i()}}(f,a);if(a.closed)return d;const h=function(i,o=""){"string"!==typeof i&&t(1,"expected text");const r=i.replace(/^\uFEFF/,"").split(/\r\n|\r|\n/);let s=0;function l(){for(;s[\t ]*([\d:.]+)(?:[\t ].*)?$/);d||t(a,"invalid cue timing");const f=e(d[1],a),m=e(d[2],a);mr.duration,setStyle:s,isMobile:l}),b=o.style||{};return a.closed||r.controls.add({name:"vtt-thumbnail",position:"top",index:20,style:b,mounted(t){a.own(()=>{r.controls["vtt-thumbnail"]===t&&r.controls.remove("vtt-thumbnail")}),a.closed||(c(t,"art-control-thumbnails"),a.listen("setBar",p(t)))}}),d}catch(f){throw a.dispose(),f}}}}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginVttThumbnail=e(),define(function(){return t.artplayerPluginVttThumbnail})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginVttThumbnail=e()}(this,function(){"use strict";function t(t,e){throw new TypeError(`Invalid VTT thumbnail at line ${t}: ${e}`)}function e(e,n){/^\d{2,}(?::\d{2}){0,2}(?:\.\d{3})?$/.test(e)||t(n,"invalid timestamp");const[i,o="0"]=e.split("."),r=i.split(":").reduce((t,e)=>60*t+Number(e),0)+Number(o)/1e3;return Number.isSafeInteger(Math.floor(r))||t(n,"timestamp exceeds the supported numeric range"),r}function n(e,n,i){const o=e.match(/^(.+)#([xywh]{4})=(.*)$/);o&&4===new Set(o[2]).size||t(i,"expected an image URL and four distinct xywh keys");const r=o[3].split(",").map(t=>t.trim());4!==r.length&&t(i,"expected four rectangle coordinates");const s={};for(let c=0;c<4;c++){const e=o[2][c],n=r[c];/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(n)&&Number.isFinite(Number(n))||t(i,"rectangle coordinates must be finite non-negative decimals"),"w"!==e&&"h"!==e||0!==Number(n)||t(i,"rectangle width and height must be positive"),s[e]=n}let l=o[1];if(!/^\/|(?:https?|ftp|file):\/\//i.test(l)){const t=n.split("/");t.pop(),t.push(l),l=t.join("/")}return{url:l,...s}}function i({lifetime:t,thumbnails:e,progress:n,duration:i,setStyle:o,isMobile:r}){let s=null,l=0;function c(e,n,i){t.closed||o(e,n,i)}return t.own(()=>{if(l++,null!==s){const t=s;s=null,clearTimeout(t)}}),o=>async(u,a,d)=>{if(t.closed)return;const f="played"===u&&d&&r;if("hover"!==u&&!f)return;const m=n.clientWidth*a,h=a*i();if(c(o,"display","flex"),t.closed)return;const p=function(t,e){return t.find(t=>e>=t.start&&e<=t.end)}(e,h);if(!p)return c(o,"display","none");if(m>0&&mn.clientWidth-Number(e.w)/2?c(t,"left",n.clientWidth-Number(e.w)+"px"):c(t,"left",i-Number(e.w)/2+"px")}(o,p,m):r||c(o,"display","none"),f&&!t.closed){const e=++l;if(null!==s&&clearTimeout(s),t.closed)return;const n=setTimeout(()=>{e!==l||t.closed||(s=null,c(o,"display","none"))},500);t.closed||e!==l?clearTimeout(n):s=n}}}function o(o){return async r=>{const{setStyle:s,isMobile:l,addClass:c}=r.constructor.utils,{$progress:u}=r.template,a=function(t){let e=Boolean(t.isDestroy);const n=new Set;let i;const o=new Promise(t=>{i=t}),r={get closed(){return e},own:t=>(e?s(t):n.add(t),()=>n.delete(t)),listen(n,i){e||(r.own(()=>t.off(n,i)),t.on(n,i))},wait:t=>Promise.race([t,o]),dispose(){if(e)return;e=!0,i();const t=[...n].reverse();n.clear();for(const e of t)s(e)}};function s(t){try{t()}catch(e){console.warn("Failed to clean up VTT thumbnails:",e)}}try{r.listen("destroy",r.dispose)}catch(l){throw r.dispose(),l}return r}(r),d={name:"artplayerPluginVttThumbnail"};try{if(a.closed)return d;const f=o.vtt,m=await async function(t="",e){if(e.closed)return;const n="function"===typeof AbortController?new AbortController:null,i=e.own(()=>n?.abort());try{if(e.closed)return;const i=await e.wait(n?fetch(t,{signal:n.signal}):fetch(t));if(e.closed)return;if(!1===i.ok)throw new Error(`Failed to fetch VTT thumbnails: HTTP ${i.status}`);if(e.closed)return;return await e.wait(i.text())}finally{i()}}(f,a);if(a.closed)return d;const h=function(i,o=""){"string"!==typeof i&&t(1,"expected text");const r=i.replace(/^\uFEFF/,"").split(/\r\n|\r|\n/);let s=0;function l(){for(;s[\t ]*([\d:.]+)(?:[\t ].*)?$/);d||t(a,"invalid cue timing");const f=e(d[1],a),m=e(d[2],a);mr.duration,setStyle:s,isMobile:l}),b=o.style||{};return a.closed||r.controls.add({name:"vtt-thumbnail",position:"top",index:20,style:b,mounted(t){a.own(()=>{r.controls["vtt-thumbnail"]===t&&r.controls.remove("vtt-thumbnail")}),a.closed||(c(t,"art-control-thumbnails"),a.listen("setBar",p(t)))}}),d}catch(f){throw a.dispose(),f}}}return Object.assign(o,{default:o})}); diff --git a/docs/compiled/artplayer-plugin-vtt-thumbnail.legacy.js b/docs/compiled/artplayer-plugin-vtt-thumbnail.legacy.js index 3454e65cb..1fcab850c 100644 --- a/docs/compiled/artplayer-plugin-vtt-thumbnail.legacy.js +++ b/docs/compiled/artplayer-plugin-vtt-thumbnail.legacy.js @@ -4,4 +4,4 @@ * (c) 2017-2026 Harvey Zhao * Released under the MIT License. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginVttThumbnail=e(),define(function(){return t.artplayerPluginVttThumbnail})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginVttThumbnail=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,r=(e,n,o)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[n]=o,i=(t,i)=>{for(var l in i||(i={}))n.call(i,l)&&r(t,l,i[l]);if(e)for(var l of e(i))o.call(i,l)&&r(t,l,i[l]);return t},l=(t,e,n)=>new Promise((o,r)=>{var i=t=>{try{s(n.next(t))}catch(e){r(e)}},l=t=>{try{s(n.throw(t))}catch(e){r(e)}},s=t=>t.done?o(t.value):Promise.resolve(t.value).then(i,l);s((n=n.apply(t,e)).next())});function s(t,e){throw new TypeError(`Invalid VTT thumbnail at line ${t}: ${e}`)}function c(t,e){/^\d{2,}(?::\d{2}){0,2}(?:\.\d{3})?$/.test(t)||s(e,"invalid timestamp");const[n,o="0"]=t.split("."),r=n.split(":").reduce((t,e)=>60*t+Number(e),0)+Number(o)/1e3;return Number.isSafeInteger(Math.floor(r))||s(e,"timestamp exceeds the supported numeric range"),r}function u(t,e,n){const o=t.match(/^(.+)#([xywh]{4})=(.*)$/);o&&4===new Set(o[2]).size||s(n,"expected an image URL and four distinct xywh keys");const r=o[3].split(",").map(t=>t.trim());4!==r.length&&s(n,"expected four rectangle coordinates");const l={};for(let i=0;i<4;i++){const t=o[2][i],e=r[i];/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(e)&&Number.isFinite(Number(e))||s(n,"rectangle coordinates must be finite non-negative decimals"),"w"!==t&&"h"!==t||0!==Number(e)||s(n,"rectangle width and height must be positive"),l[t]=e}let c=o[1];if(!/^\/|(?:https?|ftp|file):\/\//i.test(c)){const t=e.split("/");t.pop(),t.push(c),c=t.join("/")}return i({url:c},l)}function a({lifetime:t,thumbnails:e,progress:n,duration:o,setStyle:r,isMobile:i}){let s=null,c=0;function u(e,n,o){t.closed||r(e,n,o)}return t.own(()=>{if(c++,null!==s){const t=s;s=null,clearTimeout(t)}}),r=>(a,d,f)=>l(null,null,function*(){if(t.closed)return;const l="played"===a&&f&&i;if("hover"!==a&&!l)return;const m=n.clientWidth*d,p=d*o();if(u(r,"display","flex"),t.closed)return;const h=function(t,e){return t.find(t=>e>=t.start&&e<=t.end)}(e,p);if(!h)return u(r,"display","none");if(m>0&&mn.clientWidth-Number(e.w)/2?u(t,"left",n.clientWidth-Number(e.w)+"px"):u(t,"left",o-Number(e.w)/2+"px")}(r,h,m):i||u(r,"display","none"),l&&!t.closed){const e=++c;if(null!==s&&clearTimeout(s),t.closed)return;const n=setTimeout(()=>{e!==c||t.closed||(s=null,u(r,"display","none"))},500);t.closed||e!==c?clearTimeout(n):s=n}})}return function(t){return e=>l(null,null,function*(){const{setStyle:n,isMobile:o,addClass:r}=e.constructor.utils,{$progress:d}=e.template,f=function(t){let e=Boolean(t.isDestroy);const n=new Set;let o;const r=new Promise(t=>{o=t}),i={get closed(){return e},own:t=>(e?l(t):n.add(t),()=>n.delete(t)),listen(n,o){e||(i.own(()=>t.off(n,o)),t.on(n,o))},wait:t=>Promise.race([t,r]),dispose(){if(e)return;e=!0,o();const t=[...n].reverse();n.clear();for(const e of t)l(e)}};function l(t){try{t()}catch(e){console.warn("Failed to clean up VTT thumbnails:",e)}}try{i.listen("destroy",i.dispose)}catch(s){throw i.dispose(),s}return i}(e),m={name:"artplayerPluginVttThumbnail"};try{if(f.closed)return m;const p=t.vtt,h=yield function(t="",e){return l(this,null,function*(){if(e.closed)return;const n="function"===typeof AbortController?new AbortController:null,o=e.own(()=>null==n?void 0:n.abort());try{if(e.closed)return;const o=yield e.wait(n?fetch(t,{signal:n.signal}):fetch(t));if(e.closed)return;if(!1===o.ok)throw new Error(`Failed to fetch VTT thumbnails: HTTP ${o.status}`);if(e.closed)return;return yield e.wait(o.text())}finally{o()}})}(p,f);if(f.closed)return m;const b=function(t,e=""){"string"!==typeof t&&s(1,"expected text");const n=t.replace(/^\uFEFF/,"").split(/\r\n|\r|\n/);let o=0;function r(){for(;o[\t ]*([\d:.]+)(?:[\t ].*)?$/);f||s(d,"invalid cue timing");const m=c(f[1],d),p=c(f[2],d);pe.duration,setStyle:n,isMobile:o}),g=t.style||{};return f.closed||e.controls.add({name:"vtt-thumbnail",position:"top",index:20,style:g,mounted(t){f.own(()=>{e.controls["vtt-thumbnail"]===t&&e.controls.remove("vtt-thumbnail")}),f.closed||(r(t,"art-control-thumbnails"),f.listen("setBar",y(t)))}}),m}catch(p){throw f.dispose(),p}})}}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginVttThumbnail=e(),define(function(){return t.artplayerPluginVttThumbnail})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginVttThumbnail=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,r=(e,n,o)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[n]=o,i=(t,i)=>{for(var l in i||(i={}))n.call(i,l)&&r(t,l,i[l]);if(e)for(var l of e(i))o.call(i,l)&&r(t,l,i[l]);return t},l=(t,e,n)=>new Promise((o,r)=>{var i=t=>{try{s(n.next(t))}catch(e){r(e)}},l=t=>{try{s(n.throw(t))}catch(e){r(e)}},s=t=>t.done?o(t.value):Promise.resolve(t.value).then(i,l);s((n=n.apply(t,e)).next())});function s(t,e){throw new TypeError(`Invalid VTT thumbnail at line ${t}: ${e}`)}function c(t,e){/^\d{2,}(?::\d{2}){0,2}(?:\.\d{3})?$/.test(t)||s(e,"invalid timestamp");const[n,o="0"]=t.split("."),r=n.split(":").reduce((t,e)=>60*t+Number(e),0)+Number(o)/1e3;return Number.isSafeInteger(Math.floor(r))||s(e,"timestamp exceeds the supported numeric range"),r}function u(t,e,n){const o=t.match(/^(.+)#([xywh]{4})=(.*)$/);o&&4===new Set(o[2]).size||s(n,"expected an image URL and four distinct xywh keys");const r=o[3].split(",").map(t=>t.trim());4!==r.length&&s(n,"expected four rectangle coordinates");const l={};for(let i=0;i<4;i++){const t=o[2][i],e=r[i];/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(e)&&Number.isFinite(Number(e))||s(n,"rectangle coordinates must be finite non-negative decimals"),"w"!==t&&"h"!==t||0!==Number(e)||s(n,"rectangle width and height must be positive"),l[t]=e}let c=o[1];if(!/^\/|(?:https?|ftp|file):\/\//i.test(c)){const t=e.split("/");t.pop(),t.push(c),c=t.join("/")}return i({url:c},l)}function a({lifetime:t,thumbnails:e,progress:n,duration:o,setStyle:r,isMobile:i}){let s=null,c=0;function u(e,n,o){t.closed||r(e,n,o)}return t.own(()=>{if(c++,null!==s){const t=s;s=null,clearTimeout(t)}}),r=>(a,d,f)=>l(null,null,function*(){if(t.closed)return;const l="played"===a&&f&&i;if("hover"!==a&&!l)return;const m=n.clientWidth*d,p=d*o();if(u(r,"display","flex"),t.closed)return;const h=function(t,e){return t.find(t=>e>=t.start&&e<=t.end)}(e,p);if(!h)return u(r,"display","none");if(m>0&&mn.clientWidth-Number(e.w)/2?u(t,"left",n.clientWidth-Number(e.w)+"px"):u(t,"left",o-Number(e.w)/2+"px")}(r,h,m):i||u(r,"display","none"),l&&!t.closed){const e=++c;if(null!==s&&clearTimeout(s),t.closed)return;const n=setTimeout(()=>{e!==c||t.closed||(s=null,u(r,"display","none"))},500);t.closed||e!==c?clearTimeout(n):s=n}})}function d(t){return e=>l(null,null,function*(){const{setStyle:n,isMobile:o,addClass:r}=e.constructor.utils,{$progress:d}=e.template,f=function(t){let e=Boolean(t.isDestroy);const n=new Set;let o;const r=new Promise(t=>{o=t}),i={get closed(){return e},own:t=>(e?l(t):n.add(t),()=>n.delete(t)),listen(n,o){e||(i.own(()=>t.off(n,o)),t.on(n,o))},wait:t=>Promise.race([t,r]),dispose(){if(e)return;e=!0,o();const t=[...n].reverse();n.clear();for(const e of t)l(e)}};function l(t){try{t()}catch(e){console.warn("Failed to clean up VTT thumbnails:",e)}}try{i.listen("destroy",i.dispose)}catch(s){throw i.dispose(),s}return i}(e),m={name:"artplayerPluginVttThumbnail"};try{if(f.closed)return m;const p=t.vtt,h=yield function(t="",e){return l(this,null,function*(){if(e.closed)return;const n="function"===typeof AbortController?new AbortController:null,o=e.own(()=>null==n?void 0:n.abort());try{if(e.closed)return;const o=yield e.wait(n?fetch(t,{signal:n.signal}):fetch(t));if(e.closed)return;if(!1===o.ok)throw new Error(`Failed to fetch VTT thumbnails: HTTP ${o.status}`);if(e.closed)return;return yield e.wait(o.text())}finally{o()}})}(p,f);if(f.closed)return m;const b=function(t,e=""){"string"!==typeof t&&s(1,"expected text");const n=t.replace(/^\uFEFF/,"").split(/\r\n|\r|\n/);let o=0;function r(){for(;o[\t ]*([\d:.]+)(?:[\t ].*)?$/);f||s(d,"invalid cue timing");const m=c(f[1],d),p=c(f[2],d);pe.duration,setStyle:n,isMobile:o}),g=t.style||{};return f.closed||e.controls.add({name:"vtt-thumbnail",position:"top",index:20,style:g,mounted(t){f.own(()=>{e.controls["vtt-thumbnail"]===t&&e.controls.remove("vtt-thumbnail")}),f.closed||(r(t,"art-control-thumbnails"),f.listen("setBar",y(t)))}}),m}catch(p){throw f.dispose(),p}})}return Object.assign(d,{default:d})}); diff --git a/docs/compiled/artplayer-plugin-vtt-thumbnail.mjs b/docs/compiled/artplayer-plugin-vtt-thumbnail.mjs index 9e410b152..4eed02c3a 100644 --- a/docs/compiled/artplayer-plugin-vtt-thumbnail.mjs +++ b/docs/compiled/artplayer-plugin-vtt-thumbnail.mjs @@ -77,9 +77,9 @@ function rectangle(text, vttUrl, line) { if (values.length !== 4) invalid(line, "expected four rectangle coordinates"); const rect = {}; - for (let index = 0; index < 4; index++) { - const key = match[2][index]; - const value = values[index]; + for (let index2 = 0; index2 < 4; index2++) { + const key = match[2][index2]; + const value = values[index2]; if (!/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(value) || !Number.isFinite(Number(value))) invalid(line, "rectangle coordinates must be finite non-negative decimals"); if ((key === "w" || key === "h") && Number(value) === 0) @@ -102,49 +102,49 @@ function parseVtt(text, vttUrl = "") { if (typeof text !== "string") invalid(1, "expected text"); const lines = text.replace(/^\uFEFF/, "").split(/\r\n|\r|\n/); - let index = 0; + let index2 = 0; function skipEmpty() { - while (index < lines.length && !lines[index].trim()) - index++; + while (index2 < lines.length && !lines[index2].trim()) + index2++; } skipEmpty(); - if (index === lines.length) + if (index2 === lines.length) return []; - if (!/^WEBVTT(?:[\t ].*)?$/.test(lines[index].trim()) || lines[index].includes("-->")) - invalid(index + 1, "expected WEBVTT header"); - index++; + if (!/^WEBVTT(?:[\t ].*)?$/.test(lines[index2].trim()) || lines[index2].includes("-->")) + invalid(index2 + 1, "expected WEBVTT header"); + index2++; const thumbnails = []; - while (index < lines.length) { + while (index2 < lines.length) { skipEmpty(); - if (index === lines.length) + if (index2 === lines.length) break; - const first = lines[index].trim(); + const first = lines[index2].trim(); if (/^NOTE(?:[\t ]|$)/.test(first) || first === "STYLE" || first === "REGION") { - while (index < lines.length && lines[index].trim()) - index++; + while (index2 < lines.length && lines[index2].trim()) + index2++; continue; } - const identifierLine = index + 1; + const identifierLine = index2 + 1; if (!first.includes("-->")) { - index++; - if (index === lines.length || !lines[index].trim()) + index2++; + if (index2 === lines.length || !lines[index2].trim()) invalid(identifierLine, "cue identifier must be followed by timing"); } - const timingLine = index + 1; - const timing = lines[index].trim().match(/^([\d:.]+)[\t ]*-->[\t ]*([\d:.]+)(?:[\t ].*)?$/); + const timingLine = index2 + 1; + const timing = lines[index2].trim().match(/^([\d:.]+)[\t ]*-->[\t ]*([\d:.]+)(?:[\t ].*)?$/); if (!timing) invalid(timingLine, "invalid cue timing"); const start = timestamp(timing[1], timingLine); const end = timestamp(timing[2], timingLine); if (end < start) invalid(timingLine, "cue end precedes its start"); - index++; + index2++; skipEmpty(); - if (index === lines.length) + if (index2 === lines.length) invalid(timingLine, "missing sprite image"); - const image = rectangle(lines[index].trim(), vttUrl, index + 1); + const image = rectangle(lines[index2].trim(), vttUrl, index2 + 1); thumbnails.push({ start: Math.floor(start), end: Math.floor(end), ...image }); - index++; + index2++; } return thumbnails; } @@ -273,6 +273,7 @@ function artplayerPluginVttThumbnail(option) { } }; } +const index = Object.assign(artplayerPluginVttThumbnail, { default: artplayerPluginVttThumbnail }); export { - artplayerPluginVttThumbnail as default + index as default }; diff --git a/package.json b/package.json index ee439cd7e..ed5ae9f46 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,8 @@ "test:thumbnail": "node --test test/thumbnail-emitter.test.js test/thumbnail-runtime.test.js test/thumbnail-vendor.test.js test/thumbnail-lifecycle.test.js test/thumbnail-input.test.js test/thumbnail.test.js refactor/scripts/thumbnail-contract.test.mjs refactor/scripts/thumbnail-types.test.mjs", "test:thumbnail-types-package": "node refactor/scripts/thumbnail-package-types.mjs", "test:auto-thumbnail": "node --test test/auto-thumbnail-frames.test.js test/auto-thumbnail-lifecycle.test.js test/auto-thumbnail.test.js refactor/scripts/auto-thumbnail-contract.test.mjs", - "test:vtt-thumbnail": "node --test test/vtt-thumbnail-parser.test.js test/vtt-thumbnail-lifecycle.test.js test/vtt-thumbnail.test.js refactor/scripts/vtt-thumbnail-contract.test.mjs" + "test:vtt-thumbnail": "node --test test/vtt-thumbnail-parser.test.js test/vtt-thumbnail-lifecycle.test.js test/vtt-thumbnail.test.js refactor/scripts/vtt-thumbnail-contract.test.mjs refactor/scripts/vtt-thumbnail-types.test.mjs", + "test:vtt-thumbnail-types-package": "node refactor/scripts/vtt-thumbnail-package-types.mjs" }, "browserslist": "last 1 Chrome version", "devDependencies": { diff --git a/packages/artplayer-plugin-vtt-thumbnail/.npmignore b/packages/artplayer-plugin-vtt-thumbnail/.npmignore index 4439c6874..2b272d565 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/.npmignore +++ b/packages/artplayer-plugin-vtt-thumbnail/.npmignore @@ -2,4 +2,5 @@ node_modules .DS_Store yarn.lock package-lock.json -src \ No newline at end of file +src +tsconfig.json diff --git a/packages/artplayer-plugin-vtt-thumbnail/ARCHITECTURE.md b/packages/artplayer-plugin-vtt-thumbnail/ARCHITECTURE.md index 6595c429c..a1ef7baa5 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/ARCHITECTURE.md +++ b/packages/artplayer-plugin-vtt-thumbnail/ARCHITECTURE.md @@ -2,8 +2,10 @@ The factory remains `artplayerPluginVttThumbnail(option)`. Its registration function is asynchronous and resolves to `{ name: 'artplayerPluginVttThumbnail' }`. Existing public -declarations still describe a synchronous result; task PKG-VTT-THUMB-04 owns that conflict -and the public declaration/consumer migration. The seven internal TS files are strict. Do not infer the return shape from those declarations. +root/legacy declarations retain the historical synchronous result for existing type extraction +and replacement factories. The optional `/runtime` entry describes the real Promise without +consumer assertions. Both entries load the same binary and function. The seven internal TS +files are strict. Never infer synchronous runtime behavior from the compatibility declarations. ## Modules and ownership @@ -34,14 +36,16 @@ rolled back if initialization throws, preserving the original rejection. ## Runtime types -`src/types.ts` defines options, result, rectangle/cue data, owned events, cleanup and +`types/artplayer-plugin-vtt-thumbnail.d.ts` owns Option and Result; `src/types.ts` reexports +them and defines rectangle/cue data, owned events, cleanup and preview inputs. Request cancellation is typed as a void branch; actual registration is Promise. The lifetime accepts only destroy/setBar and uses the core event tuples. The preview receives only its required DOM/style/duration inputs. Assertions are limited to the real Artplayer constructor boundary, validated regex groups and loop indexes, the completed four-key rectangle, and native responses after the closed -check. The latter is valid because native fetch returns Response and cancellation only +check, plus the recursive `.default` factory alias created by Object.assign. The response +assertion is valid because native fetch returns Response and cancellation only resolves void after closing; malformed custom responses still throw at runtime. Numeric rectangle strings are explicitly converted for arithmetic while the zero style write stays numeric. No any, unchecked JS or skipLibCheck exception is introduced. @@ -49,8 +53,22 @@ numeric. No any, unchecked JS or skipLibCheck exception is introduced. The package tsconfig also checks test/types/vtt-thumbnail-runtime.ts. It tests the async result, required options, CSS/URL types, event tuples, cancellation, readonly state and raw rectangle strings, including expected errors. It separately proves the old public result -is synchronous in declarations; those declarations are not silently corrected in this -runtime checkpoint. New/old declaration consumers and export aliases remain task 04. +is synchronous in declarations. `test/types/vtt-thumbnail-public.ts` separately checks exact +legacy parameter/result/factory extraction, replacement factories and accurate async calls +through `/runtime`, including negative cases. The source factory explicitly returns Promise; +its final assertion only describes the self-reference that Object.assign creates. + +Root and legacy use paired `.d.mts`/`.d.cts` default declarations. `/runtime` uses an ESM +default and a CommonJS export assignment, supporting direct and `.default` require calls. +Classic resolution uses `.d.ts` and typesVersions, including TypeScript 4.3. The generated +editor global retains the legacy callable type; its RuntimeFactory namespace member is only +a type, not an additional runtime global. Do not hand-edit generated editor declarations. + +The installed-consumer command packs both core and plugin, installs outside the workspace, +verifies member hashes, and repeats an offline frozen install. It tests five actual old npm +declarations with classic default-import consumers on TS 4.3/5.9 and seven candidate modes. +Historical NodeNext and raw require type replacement forms still need investigation in 04; +these checks do not prove all historical compiler/module combinations. ## Compatibility and intentional fixes @@ -78,9 +96,11 @@ invalid CSS or partially mounted controls. Each cue has one image/rectangle payl multiline subtitle text, timestamp-map offsets and full caption semantics are outside this plugin. Empty or comment-only input remains a valid empty preview. -The old 1.0.x export objects, earlier `thumbnails` control name and incorrect declarations -are separately frozen and remain compatibility work for tasks 04-06. Current runtime work -does not claim those consumer migrations or the full package refactor are finished. +The exported callable has a writable self `.default` alias, restoring the usable 1.0.x +CommonJS default access while retaining direct calls. It does not add a name property to the +registration Promise. Earlier `thumbnails` control names and remaining historical declaration +forms are separately frozen and remain compatibility work for tasks 04-06. The full package +refactor is not yet finished. ## Verification and future changes @@ -88,6 +108,8 @@ Use Yarn 1.22.22 and the repository's pinned Node version: ```sh yarn test:vtt-thumbnail +yarn test:vtt-thumbnail-types-package +yarn build:ts artplayer-plugin-vtt-thumbnail yarn test:browser test/browser/vtt-thumbnail-lifecycle.spec.js yarn build artplayer-plugin-vtt-thumbnail ``` diff --git a/packages/artplayer-plugin-vtt-thumbnail/README.md b/packages/artplayer-plugin-vtt-thumbnail/README.md index 681a19390..e49295874 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/README.md +++ b/packages/artplayer-plugin-vtt-thumbnail/README.md @@ -6,6 +6,30 @@ Vtt thumbnail plugin for ArtPlayer [https://artplayer.org](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-vtt-thumbnail/index.js&example=vtt.thumbnail) +## TypeScript usage + +The registration function is asynchronous. The optional runtime entry provides its accurate +Promise type and uses the same implementation as the default entry: + +```ts +import Artplayer from 'artplayer' +import vttThumbnail from 'artplayer-plugin-vtt-thumbnail/runtime' + +const art = new Artplayer({ container: '#player', url: '/video.mp4' }) +const result = await vttThumbnail({ vtt: '/thumbnails/index.vtt' })(art) +console.log(result.name) +``` + +You can also pass `vttThumbnail({ vtt: '/thumbnails/index.vtt' })` in the player's `plugins` +array. Existing default and `/legacy` imports remain available. Their declarations preserve +the historical synchronous result type for compatibility, although registration has always +returned a Promise at runtime. Reading `result.name` requires awaiting registration; changing +to `/runtime` opts into that accurate type without changing runtime behavior. The option +object remains required, and its `vtt` and `style` fields remain optional. + +See [ARCHITECTURE.md](ARCHITECTURE.md) for module ownership, testing commands and remaining +compatibility validation. + ## License MIT © Harvey Zhao diff --git a/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.js b/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.js index 123ef4a7c..10778ae94 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.js +++ b/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.js @@ -4,4 +4,4 @@ * (c) 2017-2026 Harvey Zhao * Released under the MIT License. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginVttThumbnail=e(),define(function(){return t.artplayerPluginVttThumbnail})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginVttThumbnail=e()}(this,function(){"use strict";function t(t,e){throw new TypeError(`Invalid VTT thumbnail at line ${t}: ${e}`)}function e(e,n){/^\d{2,}(?::\d{2}){0,2}(?:\.\d{3})?$/.test(e)||t(n,"invalid timestamp");const[i,o="0"]=e.split("."),r=i.split(":").reduce((t,e)=>60*t+Number(e),0)+Number(o)/1e3;return Number.isSafeInteger(Math.floor(r))||t(n,"timestamp exceeds the supported numeric range"),r}function n(e,n,i){const o=e.match(/^(.+)#([xywh]{4})=(.*)$/);o&&4===new Set(o[2]).size||t(i,"expected an image URL and four distinct xywh keys");const r=o[3].split(",").map(t=>t.trim());4!==r.length&&t(i,"expected four rectangle coordinates");const s={};for(let c=0;c<4;c++){const e=o[2][c],n=r[c];/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(n)&&Number.isFinite(Number(n))||t(i,"rectangle coordinates must be finite non-negative decimals"),"w"!==e&&"h"!==e||0!==Number(n)||t(i,"rectangle width and height must be positive"),s[e]=n}let l=o[1];if(!/^\/|(?:https?|ftp|file):\/\//i.test(l)){const t=n.split("/");t.pop(),t.push(l),l=t.join("/")}return{url:l,...s}}function i({lifetime:t,thumbnails:e,progress:n,duration:i,setStyle:o,isMobile:r}){let s=null,l=0;function c(e,n,i){t.closed||o(e,n,i)}return t.own(()=>{if(l++,null!==s){const t=s;s=null,clearTimeout(t)}}),o=>async(u,a,d)=>{if(t.closed)return;const f="played"===u&&d&&r;if("hover"!==u&&!f)return;const m=n.clientWidth*a,h=a*i();if(c(o,"display","flex"),t.closed)return;const p=function(t,e){return t.find(t=>e>=t.start&&e<=t.end)}(e,h);if(!p)return c(o,"display","none");if(m>0&&mn.clientWidth-Number(e.w)/2?c(t,"left",n.clientWidth-Number(e.w)+"px"):c(t,"left",i-Number(e.w)/2+"px")}(o,p,m):r||c(o,"display","none"),f&&!t.closed){const e=++l;if(null!==s&&clearTimeout(s),t.closed)return;const n=setTimeout(()=>{e!==l||t.closed||(s=null,c(o,"display","none"))},500);t.closed||e!==l?clearTimeout(n):s=n}}}return function(o){return async r=>{const{setStyle:s,isMobile:l,addClass:c}=r.constructor.utils,{$progress:u}=r.template,a=function(t){let e=Boolean(t.isDestroy);const n=new Set;let i;const o=new Promise(t=>{i=t}),r={get closed(){return e},own:t=>(e?s(t):n.add(t),()=>n.delete(t)),listen(n,i){e||(r.own(()=>t.off(n,i)),t.on(n,i))},wait:t=>Promise.race([t,o]),dispose(){if(e)return;e=!0,i();const t=[...n].reverse();n.clear();for(const e of t)s(e)}};function s(t){try{t()}catch(e){console.warn("Failed to clean up VTT thumbnails:",e)}}try{r.listen("destroy",r.dispose)}catch(l){throw r.dispose(),l}return r}(r),d={name:"artplayerPluginVttThumbnail"};try{if(a.closed)return d;const f=o.vtt,m=await async function(t="",e){if(e.closed)return;const n="function"===typeof AbortController?new AbortController:null,i=e.own(()=>n?.abort());try{if(e.closed)return;const i=await e.wait(n?fetch(t,{signal:n.signal}):fetch(t));if(e.closed)return;if(!1===i.ok)throw new Error(`Failed to fetch VTT thumbnails: HTTP ${i.status}`);if(e.closed)return;return await e.wait(i.text())}finally{i()}}(f,a);if(a.closed)return d;const h=function(i,o=""){"string"!==typeof i&&t(1,"expected text");const r=i.replace(/^\uFEFF/,"").split(/\r\n|\r|\n/);let s=0;function l(){for(;s[\t ]*([\d:.]+)(?:[\t ].*)?$/);d||t(a,"invalid cue timing");const f=e(d[1],a),m=e(d[2],a);mr.duration,setStyle:s,isMobile:l}),b=o.style||{};return a.closed||r.controls.add({name:"vtt-thumbnail",position:"top",index:20,style:b,mounted(t){a.own(()=>{r.controls["vtt-thumbnail"]===t&&r.controls.remove("vtt-thumbnail")}),a.closed||(c(t,"art-control-thumbnails"),a.listen("setBar",p(t)))}}),d}catch(f){throw a.dispose(),f}}}}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginVttThumbnail=e(),define(function(){return t.artplayerPluginVttThumbnail})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginVttThumbnail=e()}(this,function(){"use strict";function t(t,e){throw new TypeError(`Invalid VTT thumbnail at line ${t}: ${e}`)}function e(e,n){/^\d{2,}(?::\d{2}){0,2}(?:\.\d{3})?$/.test(e)||t(n,"invalid timestamp");const[i,o="0"]=e.split("."),r=i.split(":").reduce((t,e)=>60*t+Number(e),0)+Number(o)/1e3;return Number.isSafeInteger(Math.floor(r))||t(n,"timestamp exceeds the supported numeric range"),r}function n(e,n,i){const o=e.match(/^(.+)#([xywh]{4})=(.*)$/);o&&4===new Set(o[2]).size||t(i,"expected an image URL and four distinct xywh keys");const r=o[3].split(",").map(t=>t.trim());4!==r.length&&t(i,"expected four rectangle coordinates");const s={};for(let c=0;c<4;c++){const e=o[2][c],n=r[c];/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(n)&&Number.isFinite(Number(n))||t(i,"rectangle coordinates must be finite non-negative decimals"),"w"!==e&&"h"!==e||0!==Number(n)||t(i,"rectangle width and height must be positive"),s[e]=n}let l=o[1];if(!/^\/|(?:https?|ftp|file):\/\//i.test(l)){const t=n.split("/");t.pop(),t.push(l),l=t.join("/")}return{url:l,...s}}function i({lifetime:t,thumbnails:e,progress:n,duration:i,setStyle:o,isMobile:r}){let s=null,l=0;function c(e,n,i){t.closed||o(e,n,i)}return t.own(()=>{if(l++,null!==s){const t=s;s=null,clearTimeout(t)}}),o=>async(u,a,d)=>{if(t.closed)return;const f="played"===u&&d&&r;if("hover"!==u&&!f)return;const m=n.clientWidth*a,h=a*i();if(c(o,"display","flex"),t.closed)return;const p=function(t,e){return t.find(t=>e>=t.start&&e<=t.end)}(e,h);if(!p)return c(o,"display","none");if(m>0&&mn.clientWidth-Number(e.w)/2?c(t,"left",n.clientWidth-Number(e.w)+"px"):c(t,"left",i-Number(e.w)/2+"px")}(o,p,m):r||c(o,"display","none"),f&&!t.closed){const e=++l;if(null!==s&&clearTimeout(s),t.closed)return;const n=setTimeout(()=>{e!==l||t.closed||(s=null,c(o,"display","none"))},500);t.closed||e!==l?clearTimeout(n):s=n}}}function o(o){return async r=>{const{setStyle:s,isMobile:l,addClass:c}=r.constructor.utils,{$progress:u}=r.template,a=function(t){let e=Boolean(t.isDestroy);const n=new Set;let i;const o=new Promise(t=>{i=t}),r={get closed(){return e},own:t=>(e?s(t):n.add(t),()=>n.delete(t)),listen(n,i){e||(r.own(()=>t.off(n,i)),t.on(n,i))},wait:t=>Promise.race([t,o]),dispose(){if(e)return;e=!0,i();const t=[...n].reverse();n.clear();for(const e of t)s(e)}};function s(t){try{t()}catch(e){console.warn("Failed to clean up VTT thumbnails:",e)}}try{r.listen("destroy",r.dispose)}catch(l){throw r.dispose(),l}return r}(r),d={name:"artplayerPluginVttThumbnail"};try{if(a.closed)return d;const f=o.vtt,m=await async function(t="",e){if(e.closed)return;const n="function"===typeof AbortController?new AbortController:null,i=e.own(()=>n?.abort());try{if(e.closed)return;const i=await e.wait(n?fetch(t,{signal:n.signal}):fetch(t));if(e.closed)return;if(!1===i.ok)throw new Error(`Failed to fetch VTT thumbnails: HTTP ${i.status}`);if(e.closed)return;return await e.wait(i.text())}finally{i()}}(f,a);if(a.closed)return d;const h=function(i,o=""){"string"!==typeof i&&t(1,"expected text");const r=i.replace(/^\uFEFF/,"").split(/\r\n|\r|\n/);let s=0;function l(){for(;s[\t ]*([\d:.]+)(?:[\t ].*)?$/);d||t(a,"invalid cue timing");const f=e(d[1],a),m=e(d[2],a);mr.duration,setStyle:s,isMobile:l}),b=o.style||{};return a.closed||r.controls.add({name:"vtt-thumbnail",position:"top",index:20,style:b,mounted(t){a.own(()=>{r.controls["vtt-thumbnail"]===t&&r.controls.remove("vtt-thumbnail")}),a.closed||(c(t,"art-control-thumbnails"),a.listen("setBar",p(t)))}}),d}catch(f){throw a.dispose(),f}}}return Object.assign(o,{default:o})}); diff --git a/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.legacy.js b/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.legacy.js index 3454e65cb..1fcab850c 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.legacy.js +++ b/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.legacy.js @@ -4,4 +4,4 @@ * (c) 2017-2026 Harvey Zhao * Released under the MIT License. */ -!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginVttThumbnail=e(),define(function(){return t.artplayerPluginVttThumbnail})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginVttThumbnail=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,r=(e,n,o)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[n]=o,i=(t,i)=>{for(var l in i||(i={}))n.call(i,l)&&r(t,l,i[l]);if(e)for(var l of e(i))o.call(i,l)&&r(t,l,i[l]);return t},l=(t,e,n)=>new Promise((o,r)=>{var i=t=>{try{s(n.next(t))}catch(e){r(e)}},l=t=>{try{s(n.throw(t))}catch(e){r(e)}},s=t=>t.done?o(t.value):Promise.resolve(t.value).then(i,l);s((n=n.apply(t,e)).next())});function s(t,e){throw new TypeError(`Invalid VTT thumbnail at line ${t}: ${e}`)}function c(t,e){/^\d{2,}(?::\d{2}){0,2}(?:\.\d{3})?$/.test(t)||s(e,"invalid timestamp");const[n,o="0"]=t.split("."),r=n.split(":").reduce((t,e)=>60*t+Number(e),0)+Number(o)/1e3;return Number.isSafeInteger(Math.floor(r))||s(e,"timestamp exceeds the supported numeric range"),r}function u(t,e,n){const o=t.match(/^(.+)#([xywh]{4})=(.*)$/);o&&4===new Set(o[2]).size||s(n,"expected an image URL and four distinct xywh keys");const r=o[3].split(",").map(t=>t.trim());4!==r.length&&s(n,"expected four rectangle coordinates");const l={};for(let i=0;i<4;i++){const t=o[2][i],e=r[i];/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(e)&&Number.isFinite(Number(e))||s(n,"rectangle coordinates must be finite non-negative decimals"),"w"!==t&&"h"!==t||0!==Number(e)||s(n,"rectangle width and height must be positive"),l[t]=e}let c=o[1];if(!/^\/|(?:https?|ftp|file):\/\//i.test(c)){const t=e.split("/");t.pop(),t.push(c),c=t.join("/")}return i({url:c},l)}function a({lifetime:t,thumbnails:e,progress:n,duration:o,setStyle:r,isMobile:i}){let s=null,c=0;function u(e,n,o){t.closed||r(e,n,o)}return t.own(()=>{if(c++,null!==s){const t=s;s=null,clearTimeout(t)}}),r=>(a,d,f)=>l(null,null,function*(){if(t.closed)return;const l="played"===a&&f&&i;if("hover"!==a&&!l)return;const m=n.clientWidth*d,p=d*o();if(u(r,"display","flex"),t.closed)return;const h=function(t,e){return t.find(t=>e>=t.start&&e<=t.end)}(e,p);if(!h)return u(r,"display","none");if(m>0&&mn.clientWidth-Number(e.w)/2?u(t,"left",n.clientWidth-Number(e.w)+"px"):u(t,"left",o-Number(e.w)/2+"px")}(r,h,m):i||u(r,"display","none"),l&&!t.closed){const e=++c;if(null!==s&&clearTimeout(s),t.closed)return;const n=setTimeout(()=>{e!==c||t.closed||(s=null,u(r,"display","none"))},500);t.closed||e!==c?clearTimeout(n):s=n}})}return function(t){return e=>l(null,null,function*(){const{setStyle:n,isMobile:o,addClass:r}=e.constructor.utils,{$progress:d}=e.template,f=function(t){let e=Boolean(t.isDestroy);const n=new Set;let o;const r=new Promise(t=>{o=t}),i={get closed(){return e},own:t=>(e?l(t):n.add(t),()=>n.delete(t)),listen(n,o){e||(i.own(()=>t.off(n,o)),t.on(n,o))},wait:t=>Promise.race([t,r]),dispose(){if(e)return;e=!0,o();const t=[...n].reverse();n.clear();for(const e of t)l(e)}};function l(t){try{t()}catch(e){console.warn("Failed to clean up VTT thumbnails:",e)}}try{i.listen("destroy",i.dispose)}catch(s){throw i.dispose(),s}return i}(e),m={name:"artplayerPluginVttThumbnail"};try{if(f.closed)return m;const p=t.vtt,h=yield function(t="",e){return l(this,null,function*(){if(e.closed)return;const n="function"===typeof AbortController?new AbortController:null,o=e.own(()=>null==n?void 0:n.abort());try{if(e.closed)return;const o=yield e.wait(n?fetch(t,{signal:n.signal}):fetch(t));if(e.closed)return;if(!1===o.ok)throw new Error(`Failed to fetch VTT thumbnails: HTTP ${o.status}`);if(e.closed)return;return yield e.wait(o.text())}finally{o()}})}(p,f);if(f.closed)return m;const b=function(t,e=""){"string"!==typeof t&&s(1,"expected text");const n=t.replace(/^\uFEFF/,"").split(/\r\n|\r|\n/);let o=0;function r(){for(;o[\t ]*([\d:.]+)(?:[\t ].*)?$/);f||s(d,"invalid cue timing");const m=c(f[1],d),p=c(f[2],d);pe.duration,setStyle:n,isMobile:o}),g=t.style||{};return f.closed||e.controls.add({name:"vtt-thumbnail",position:"top",index:20,style:g,mounted(t){f.own(()=>{e.controls["vtt-thumbnail"]===t&&e.controls.remove("vtt-thumbnail")}),f.closed||(r(t,"art-control-thumbnails"),f.listen("setBar",y(t)))}}),m}catch(p){throw f.dispose(),p}})}}); +!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.artplayerPluginVttThumbnail=e(),define(function(){return t.artplayerPluginVttThumbnail})):(t="undefined"!==typeof globalThis?globalThis:t||self).artplayerPluginVttThumbnail=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,r=(e,n,o)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[n]=o,i=(t,i)=>{for(var l in i||(i={}))n.call(i,l)&&r(t,l,i[l]);if(e)for(var l of e(i))o.call(i,l)&&r(t,l,i[l]);return t},l=(t,e,n)=>new Promise((o,r)=>{var i=t=>{try{s(n.next(t))}catch(e){r(e)}},l=t=>{try{s(n.throw(t))}catch(e){r(e)}},s=t=>t.done?o(t.value):Promise.resolve(t.value).then(i,l);s((n=n.apply(t,e)).next())});function s(t,e){throw new TypeError(`Invalid VTT thumbnail at line ${t}: ${e}`)}function c(t,e){/^\d{2,}(?::\d{2}){0,2}(?:\.\d{3})?$/.test(t)||s(e,"invalid timestamp");const[n,o="0"]=t.split("."),r=n.split(":").reduce((t,e)=>60*t+Number(e),0)+Number(o)/1e3;return Number.isSafeInteger(Math.floor(r))||s(e,"timestamp exceeds the supported numeric range"),r}function u(t,e,n){const o=t.match(/^(.+)#([xywh]{4})=(.*)$/);o&&4===new Set(o[2]).size||s(n,"expected an image URL and four distinct xywh keys");const r=o[3].split(",").map(t=>t.trim());4!==r.length&&s(n,"expected four rectangle coordinates");const l={};for(let i=0;i<4;i++){const t=o[2][i],e=r[i];/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(e)&&Number.isFinite(Number(e))||s(n,"rectangle coordinates must be finite non-negative decimals"),"w"!==t&&"h"!==t||0!==Number(e)||s(n,"rectangle width and height must be positive"),l[t]=e}let c=o[1];if(!/^\/|(?:https?|ftp|file):\/\//i.test(c)){const t=e.split("/");t.pop(),t.push(c),c=t.join("/")}return i({url:c},l)}function a({lifetime:t,thumbnails:e,progress:n,duration:o,setStyle:r,isMobile:i}){let s=null,c=0;function u(e,n,o){t.closed||r(e,n,o)}return t.own(()=>{if(c++,null!==s){const t=s;s=null,clearTimeout(t)}}),r=>(a,d,f)=>l(null,null,function*(){if(t.closed)return;const l="played"===a&&f&&i;if("hover"!==a&&!l)return;const m=n.clientWidth*d,p=d*o();if(u(r,"display","flex"),t.closed)return;const h=function(t,e){return t.find(t=>e>=t.start&&e<=t.end)}(e,p);if(!h)return u(r,"display","none");if(m>0&&mn.clientWidth-Number(e.w)/2?u(t,"left",n.clientWidth-Number(e.w)+"px"):u(t,"left",o-Number(e.w)/2+"px")}(r,h,m):i||u(r,"display","none"),l&&!t.closed){const e=++c;if(null!==s&&clearTimeout(s),t.closed)return;const n=setTimeout(()=>{e!==c||t.closed||(s=null,u(r,"display","none"))},500);t.closed||e!==c?clearTimeout(n):s=n}})}function d(t){return e=>l(null,null,function*(){const{setStyle:n,isMobile:o,addClass:r}=e.constructor.utils,{$progress:d}=e.template,f=function(t){let e=Boolean(t.isDestroy);const n=new Set;let o;const r=new Promise(t=>{o=t}),i={get closed(){return e},own:t=>(e?l(t):n.add(t),()=>n.delete(t)),listen(n,o){e||(i.own(()=>t.off(n,o)),t.on(n,o))},wait:t=>Promise.race([t,r]),dispose(){if(e)return;e=!0,o();const t=[...n].reverse();n.clear();for(const e of t)l(e)}};function l(t){try{t()}catch(e){console.warn("Failed to clean up VTT thumbnails:",e)}}try{i.listen("destroy",i.dispose)}catch(s){throw i.dispose(),s}return i}(e),m={name:"artplayerPluginVttThumbnail"};try{if(f.closed)return m;const p=t.vtt,h=yield function(t="",e){return l(this,null,function*(){if(e.closed)return;const n="function"===typeof AbortController?new AbortController:null,o=e.own(()=>null==n?void 0:n.abort());try{if(e.closed)return;const o=yield e.wait(n?fetch(t,{signal:n.signal}):fetch(t));if(e.closed)return;if(!1===o.ok)throw new Error(`Failed to fetch VTT thumbnails: HTTP ${o.status}`);if(e.closed)return;return yield e.wait(o.text())}finally{o()}})}(p,f);if(f.closed)return m;const b=function(t,e=""){"string"!==typeof t&&s(1,"expected text");const n=t.replace(/^\uFEFF/,"").split(/\r\n|\r|\n/);let o=0;function r(){for(;o[\t ]*([\d:.]+)(?:[\t ].*)?$/);f||s(d,"invalid cue timing");const m=c(f[1],d),p=c(f[2],d);pe.duration,setStyle:n,isMobile:o}),g=t.style||{};return f.closed||e.controls.add({name:"vtt-thumbnail",position:"top",index:20,style:g,mounted(t){f.own(()=>{e.controls["vtt-thumbnail"]===t&&e.controls.remove("vtt-thumbnail")}),f.closed||(r(t,"art-control-thumbnails"),f.listen("setBar",y(t)))}}),m}catch(p){throw f.dispose(),p}})}return Object.assign(d,{default:d})}); diff --git a/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.mjs b/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.mjs index 9e410b152..4eed02c3a 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.mjs +++ b/packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.mjs @@ -77,9 +77,9 @@ function rectangle(text, vttUrl, line) { if (values.length !== 4) invalid(line, "expected four rectangle coordinates"); const rect = {}; - for (let index = 0; index < 4; index++) { - const key = match[2][index]; - const value = values[index]; + for (let index2 = 0; index2 < 4; index2++) { + const key = match[2][index2]; + const value = values[index2]; if (!/^(?:\d+(?:\.\d+)?|\.\d+)$/.test(value) || !Number.isFinite(Number(value))) invalid(line, "rectangle coordinates must be finite non-negative decimals"); if ((key === "w" || key === "h") && Number(value) === 0) @@ -102,49 +102,49 @@ function parseVtt(text, vttUrl = "") { if (typeof text !== "string") invalid(1, "expected text"); const lines = text.replace(/^\uFEFF/, "").split(/\r\n|\r|\n/); - let index = 0; + let index2 = 0; function skipEmpty() { - while (index < lines.length && !lines[index].trim()) - index++; + while (index2 < lines.length && !lines[index2].trim()) + index2++; } skipEmpty(); - if (index === lines.length) + if (index2 === lines.length) return []; - if (!/^WEBVTT(?:[\t ].*)?$/.test(lines[index].trim()) || lines[index].includes("-->")) - invalid(index + 1, "expected WEBVTT header"); - index++; + if (!/^WEBVTT(?:[\t ].*)?$/.test(lines[index2].trim()) || lines[index2].includes("-->")) + invalid(index2 + 1, "expected WEBVTT header"); + index2++; const thumbnails = []; - while (index < lines.length) { + while (index2 < lines.length) { skipEmpty(); - if (index === lines.length) + if (index2 === lines.length) break; - const first = lines[index].trim(); + const first = lines[index2].trim(); if (/^NOTE(?:[\t ]|$)/.test(first) || first === "STYLE" || first === "REGION") { - while (index < lines.length && lines[index].trim()) - index++; + while (index2 < lines.length && lines[index2].trim()) + index2++; continue; } - const identifierLine = index + 1; + const identifierLine = index2 + 1; if (!first.includes("-->")) { - index++; - if (index === lines.length || !lines[index].trim()) + index2++; + if (index2 === lines.length || !lines[index2].trim()) invalid(identifierLine, "cue identifier must be followed by timing"); } - const timingLine = index + 1; - const timing = lines[index].trim().match(/^([\d:.]+)[\t ]*-->[\t ]*([\d:.]+)(?:[\t ].*)?$/); + const timingLine = index2 + 1; + const timing = lines[index2].trim().match(/^([\d:.]+)[\t ]*-->[\t ]*([\d:.]+)(?:[\t ].*)?$/); if (!timing) invalid(timingLine, "invalid cue timing"); const start = timestamp(timing[1], timingLine); const end = timestamp(timing[2], timingLine); if (end < start) invalid(timingLine, "cue end precedes its start"); - index++; + index2++; skipEmpty(); - if (index === lines.length) + if (index2 === lines.length) invalid(timingLine, "missing sprite image"); - const image = rectangle(lines[index].trim(), vttUrl, index + 1); + const image = rectangle(lines[index2].trim(), vttUrl, index2 + 1); thumbnails.push({ start: Math.floor(start), end: Math.floor(end), ...image }); - index++; + index2++; } return thumbnails; } @@ -273,6 +273,7 @@ function artplayerPluginVttThumbnail(option) { } }; } +const index = Object.assign(artplayerPluginVttThumbnail, { default: artplayerPluginVttThumbnail }); export { - artplayerPluginVttThumbnail as default + index as default }; diff --git a/packages/artplayer-plugin-vtt-thumbnail/package.json b/packages/artplayer-plugin-vtt-thumbnail/package.json index db5266e39..d6be4fc6b 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/package.json +++ b/packages/artplayer-plugin-vtt-thumbnail/package.json @@ -19,19 +19,49 @@ ], "exports": { ".": { - "types": "./types/artplayer-plugin-vtt-thumbnail.d.ts", - "import": "./dist/artplayer-plugin-vtt-thumbnail.mjs", - "require": "./dist/artplayer-plugin-vtt-thumbnail.js" + "import": { + "types": "./types/artplayer-plugin-vtt-thumbnail.d.mts", + "default": "./dist/artplayer-plugin-vtt-thumbnail.mjs" + }, + "require": { + "types": "./types/artplayer-plugin-vtt-thumbnail.d.cts", + "default": "./dist/artplayer-plugin-vtt-thumbnail.js" + } }, "./legacy": { - "types": "./types/artplayer-plugin-vtt-thumbnail.d.ts", - "import": "./dist/artplayer-plugin-vtt-thumbnail.legacy.js", - "require": "./dist/artplayer-plugin-vtt-thumbnail.legacy.js" + "import": { + "types": "./types/artplayer-plugin-vtt-thumbnail.d.mts", + "default": "./dist/artplayer-plugin-vtt-thumbnail.legacy.js" + }, + "require": { + "types": "./types/artplayer-plugin-vtt-thumbnail.d.cts", + "default": "./dist/artplayer-plugin-vtt-thumbnail.legacy.js" + } + }, + "./runtime": { + "import": { + "types": "./types/runtime.d.mts", + "default": "./dist/artplayer-plugin-vtt-thumbnail.mjs" + }, + "require": { + "types": "./types/runtime.d.cts", + "default": "./dist/artplayer-plugin-vtt-thumbnail.js" + } } }, "main": "./dist/artplayer-plugin-vtt-thumbnail.js", "module": "./dist/artplayer-plugin-vtt-thumbnail.mjs", "types": "./types/artplayer-plugin-vtt-thumbnail.d.ts", "legacy": "./dist/artplayer-plugin-vtt-thumbnail.legacy.js", - "browserslist": "last 1 Chrome version" + "browserslist": "last 1 Chrome version", + "typesVersions": { + "*": { + "legacy": [ + "types/artplayer-plugin-vtt-thumbnail.d.ts" + ], + "runtime": [ + "types/runtime.d.ts" + ] + } + } } diff --git a/packages/artplayer-plugin-vtt-thumbnail/src/index.ts b/packages/artplayer-plugin-vtt-thumbnail/src/index.ts index 61a41aa2c..c6b52a6bf 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/src/index.ts +++ b/packages/artplayer-plugin-vtt-thumbnail/src/index.ts @@ -1,11 +1,12 @@ import type Artplayer from 'artplayer' +import type { RuntimeFactory } from '../types/artplayer-plugin-vtt-thumbnail' import type { Option, Result } from './types' import createLifetime from './lifetime' import parseVtt from './parseVtt' import createPreview from './preview' import requestVtt from './request' -export default function artplayerPluginVttThumbnail(option: Option) { +function artplayerPluginVttThumbnail(option: Option) { return async (art: Artplayer): Promise => { const { setStyle, isMobile, addClass } = (art.constructor as typeof Artplayer).utils const { $progress } = art.template @@ -47,3 +48,6 @@ export default function artplayerPluginVttThumbnail(option: Option) { } } } + +// Object.assign adds the alias to the same callable referenced by that alias. +export default Object.assign(artplayerPluginVttThumbnail, { default: artplayerPluginVttThumbnail }) as RuntimeFactory diff --git a/packages/artplayer-plugin-vtt-thumbnail/src/types.ts b/packages/artplayer-plugin-vtt-thumbnail/src/types.ts index 056ad87dd..bd58bb35d 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/src/types.ts +++ b/packages/artplayer-plugin-vtt-thumbnail/src/types.ts @@ -1,14 +1,7 @@ import type Artplayer from 'artplayer' import type { Events, Utils } from 'artplayer' -export interface Option { - vtt?: string - style?: Partial -} - -export interface Result { - name: 'artplayerPluginVttThumbnail' -} +export type { Option, Result } from '../types/artplayer-plugin-vtt-thumbnail' export interface Rectangle { x: string diff --git a/packages/artplayer-plugin-vtt-thumbnail/tsconfig.json b/packages/artplayer-plugin-vtt-thumbnail/tsconfig.json index bee977b3f..4de08721f 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/tsconfig.json +++ b/packages/artplayer-plugin-vtt-thumbnail/tsconfig.json @@ -1,5 +1,14 @@ { "extends": "../../tsconfig.base.json", - "compilerOptions": { "allowJs": false }, - "include": ["src/**/*.ts", "types/**/*.d.ts", "../../types/assets.d.ts", "../../test/types/vtt-thumbnail-runtime.ts"] + "compilerOptions": { + "allowJs": false + }, + "include": [ + "src/**/*.ts", + "types/**/*.d.ts", + "../../types/assets.d.ts", + "../../test/types/vtt-thumbnail-runtime.ts", + "types/**/*.d.mts", + "types/**/*.d.cts" + ] } diff --git a/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.cts b/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.cts new file mode 100644 index 000000000..0580df47a --- /dev/null +++ b/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.cts @@ -0,0 +1,5 @@ +import type { Factory } from './artplayer-plugin-vtt-thumbnail.js' + +declare const artplayerPluginVttThumbnail: Factory +export default artplayerPluginVttThumbnail +export type { Factory, Option, Result, RuntimeFactory } from './artplayer-plugin-vtt-thumbnail.js' diff --git a/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.mts b/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.mts new file mode 100644 index 000000000..0580df47a --- /dev/null +++ b/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.mts @@ -0,0 +1,5 @@ +import type { Factory } from './artplayer-plugin-vtt-thumbnail.js' + +declare const artplayerPluginVttThumbnail: Factory +export default artplayerPluginVttThumbnail +export type { Factory, Option, Result, RuntimeFactory } from './artplayer-plugin-vtt-thumbnail.js' diff --git a/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.ts b/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.ts index 3bf11eddc..db56c77a5 100644 --- a/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.ts +++ b/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.ts @@ -1,9 +1,23 @@ import type Artplayer from 'artplayer' -declare const artplayerPluginVttThumbnail: (option: { vtt?: string, style?: Partial }) => ( - art: Artplayer, -) => { +export interface Option { + vtt?: string + style?: Partial +} + +export interface Result { name: 'artplayerPluginVttThumbnail' } +/** Historical factory type. Actual registration is asynchronous. */ +export type Factory = (option: Option) => (art: Artplayer) => Result + +/** Accurate runtime view available without casts through the /runtime entry. */ +export interface RuntimeFactory { + (option: Option): (art: Artplayer) => Promise + default: RuntimeFactory +} + +/** Preserve historical extraction and replacement-function compatibility. */ +declare function artplayerPluginVttThumbnail(option: Option): (art: Artplayer) => Result export default artplayerPluginVttThumbnail diff --git a/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.cts b/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.cts new file mode 100644 index 000000000..f05c766b0 --- /dev/null +++ b/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.cts @@ -0,0 +1,4 @@ +import type { RuntimeFactory } from './artplayer-plugin-vtt-thumbnail.js' + +declare const artplayerPluginVttThumbnail: RuntimeFactory +export = artplayerPluginVttThumbnail diff --git a/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.mts b/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.mts new file mode 100644 index 000000000..234aa4a15 --- /dev/null +++ b/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.mts @@ -0,0 +1,5 @@ +import type { RuntimeFactory } from './artplayer-plugin-vtt-thumbnail.js' + +declare const artplayerPluginVttThumbnail: RuntimeFactory +export default artplayerPluginVttThumbnail +export type { Option, Result, RuntimeFactory } from './artplayer-plugin-vtt-thumbnail.js' diff --git a/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.ts b/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.ts new file mode 100644 index 000000000..234aa4a15 --- /dev/null +++ b/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.ts @@ -0,0 +1,5 @@ +import type { RuntimeFactory } from './artplayer-plugin-vtt-thumbnail.js' + +declare const artplayerPluginVttThumbnail: RuntimeFactory +export default artplayerPluginVttThumbnail +export type { Option, Result, RuntimeFactory } from './artplayer-plugin-vtt-thumbnail.js' diff --git a/refactor/baselines/vtt-thumbnail-public-types.json b/refactor/baselines/vtt-thumbnail-public-types.json new file mode 100644 index 000000000..10eb0bd4f --- /dev/null +++ b/refactor/baselines/vtt-thumbnail-public-types.json @@ -0,0 +1,3298 @@ +{ + "schemaVersion": 1, + "task": "PKG-VTT-THUMB-04", + "status": "doing", + "parentCommit": "7f2906ae52e6c57bbe5ab2350e214999510046f9", + "scope": "Legacy default-import extraction/replacement kept; optional accurate asynchronous runtime entry; writable default alias; actual installed consumer matrix. Historical NodeNext/raw require forms and complete device/distribution acceptance remain open.", + "checks": [ + { + "command": "yarn test:vtt-thumbnail", + "tests": 251, + "pass": 251, + "file": "refactor/.cache/vtt-thumbnail04-public-focused.log", + "sha256": "9e939ba66744873659aa9950e7296120d998248db71d6f51c4eaa71a6e71aada" + }, + { + "command": "old HEAD actual bundle lifecycle reproduction", + "tests": 22, + "pass": 21, + "fail": 1, + "file": "refactor/.cache/vtt-thumbnail04-public-before.log", + "sha256": "50c1c80ef4334e899c9c7898f19c288df4d710c793e4a0bfae24eebfcc66058f" + }, + { + "command": "strict runtime positive/negative types", + "file": "refactor/.cache/vtt-thumbnail04-public-runtime-strict.log", + "sha256": "0ba45fc43253f5c04c00cd5d3995cbddd2cee810179c6561ef79cc3423323968", + "results": [ + { + "version": "5.9.3", + "strict": true, + "allowJs": false, + "skipLibCheck": false, + "fixture": "D:\\github\\ArtPlayer\\test\\types\\vtt-thumbnail-runtime.ts", + "rootFiles": [ + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/getVttArray.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/index.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/lifetime.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/parseVtt.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/preview.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/request.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/types.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.ts", + "D:/github/ArtPlayer/types/assets.d.ts", + "D:/github/ArtPlayer/test/types/vtt-thumbnail-runtime.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.mts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.mts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.cts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.cts" + ], + "negativeErrors": [ + { + "code": 2339, + "line": 15, + "message": "Property 'name' does not exist on type 'Promise'." + }, + { + "code": 2554, + "line": 17, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2322, + "line": 19, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2322, + "line": 21, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2345, + "line": 29, + "message": "Argument of type '\"not-an-event\"' is not assignable to parameter of type 'OwnedEvent'." + }, + { + "code": 2540, + "line": 35, + "message": "Cannot assign to 'closed' because it is a read-only property." + }, + { + "code": 2322, + "line": 41, + "message": "Type 'string' is not assignable to type 'number'." + }, + { + "code": 2322, + "line": 47, + "message": "Type '(art: Artplayer) => Promise' is not assignable to type '(art: Artplayer) => Result'.\n Property 'name' is missing in type 'Promise' but required in type 'Result'." + } + ] + }, + { + "version": "5.1.6", + "strict": true, + "allowJs": false, + "skipLibCheck": false, + "fixture": "D:\\github\\ArtPlayer\\test\\types\\vtt-thumbnail-runtime.ts", + "rootFiles": [ + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/getVttArray.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/index.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/lifetime.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/parseVtt.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/preview.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/request.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/src/types.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.ts", + "D:/github/ArtPlayer/types/assets.d.ts", + "D:/github/ArtPlayer/test/types/vtt-thumbnail-runtime.ts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.mts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.mts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.cts", + "D:/github/ArtPlayer/packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.cts" + ], + "negativeErrors": [ + { + "code": 2339, + "line": 15, + "message": "Property 'name' does not exist on type 'Promise'." + }, + { + "code": 2554, + "line": 17, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2322, + "line": 19, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2322, + "line": 21, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2345, + "line": 29, + "message": "Argument of type '\"not-an-event\"' is not assignable to parameter of type 'OwnedEvent'." + }, + { + "code": 2540, + "line": 35, + "message": "Cannot assign to 'closed' because it is a read-only property." + }, + { + "code": 2322, + "line": 41, + "message": "Type 'string' is not assignable to type 'number'." + }, + { + "code": 2322, + "line": 47, + "message": "Type '(art: Artplayer) => Promise' is not assignable to type '(art: Artplayer) => Result'.\n Property 'name' is missing in type 'Promise' but required in type 'Result'." + } + ] + } + ] + }, + { + "command": "isolated actual package consumers", + "file": "refactor/.cache/vtt-thumbnail04-public-package-verified.log", + "sha256": "54037c4fb5f606881ed832e21c880a288b636886fafb98e09e7ab47a375eaf0f", + "results": { + "suite": "vtt-thumbnail-isolated-package-types", + "introducedBy": "PKG-VTT-THUMB-04", + "scope": "Five actual published packages (classic default-import consumers on TS 4.3 and 5.9) and packed candidate (seven compiler modes) installed outside the workspace with packed core. Offline/frozen reinstall and byte identity are verified. Candidate provides an opt-in accurate runtime entry; 1.0.0 invalid bundle syntax is retained. Historical NodeNext variants, raw require type replacements, device and full distribution acceptance remain separate.", + "packages": [ + { + "name": "artplayer", + "archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\vtt-thumbnail-package-types-2gwRYF\\artplayer.tgz", + "sha256": "7be178936e4e12fc59d0af15402bf4b36adcd6dcf40f3ef90e73bbe6aaaf0d49", + "files": { + "package/ARCHITECTURE.md": "e19079b3d419d82c86e65d6e05c826020c06286b7edfb1cce185e62ce3c50d30", + "package/README.md": "1e185e65f67fc2081b4182bbc6c4558ea05b6e3fa3acc5dd0c3ac7df1d542b09", + "package/THIRD_PARTY_NOTICES": "b77b5b46b79fa0cda850b0781f78c3b1112c4ed9672fa291956fe8eff53098e7", + "package/dist/artplayer.cts": "0e91e907d021db02a68004603e6190505fdc0806d873ebb6af171aa089a81da7", + "package/dist/artplayer.js": "4b29968839ba816db09910a908d1d6b8ec6cf1edaad418c96e1f407545a19bf9", + "package/dist/artplayer.legacy.js": "2dc2eb7cb26012ef1d780680d622aba61a79b7ac3b37bb1ca7a6047834513dd9", + "package/dist/artplayer.mjs": "574749f090251b7d7bddb507a3ca3cc91a759f694e7f4865d19ef1162d330626", + "package/dist/artplayer.mts": "f6292596a9ccb1d43a6d6a12c35f859b1889ad15924c5ae0f9f280941aade313", + "package/dist/artplayer.ts": "26a42ac66811e70f68a8ebe62cbf304eb1993451b3e658961be98e7106162527", + "package/dist/component.ts": "aa1c43be67322781b4b355b143bc69d9f29d22e578e4974d6a13e957a7c0334f", + "package/dist/config.ts": "c4fd8681bf32b10c743e3e561c532520c8f32e43fd765524850b15e55cb91c72", + "package/dist/cssVar.ts": "e027d82fb4f01c9ce7559cf679b2d5ee1962d3f7e5b4dd64ca21f472b933efb6", + "package/dist/emitter.ts": "9c62551cdcc6dd3966bed8a7a85dd477435db977c91a294d2ac8f162f9592537", + "package/dist/events.ts": "af191f862af4ec8933b09113b8c074603ae254a8b70460d0f3006646cd74ae42", + "package/dist/i18n.ts": "34b0c684668044f7600c80b9d3979f8fb730138007b7cb4e7034326b340156fb", + "package/dist/i18n/ar.js": "bd0bef65f4f7dc3f8ed562904cc6fa9071ff4537fb64c1e0fc3d554141bcd3cb", + "package/dist/i18n/ar.mjs": "59310b7bbeea83bbb7d73aadc5ca82a6ec269c3530d19aa741c94d5c64fc5da8", + "package/dist/i18n/cs.js": "6e2c93daba24c2e48dfa206bcf4f2f2a8a02713b856e404d2e4e4ecd8309ca2f", + "package/dist/i18n/cs.mjs": "c73fba18797d62d7b2581e67fe7340c35fe84510b2250ff1ecaad253d9cabbac", + "package/dist/i18n/es.js": "f4133ac6ea06b69a474b33c4a1809a4066e2376bb9464a3f3aa8330f01f1944a", + "package/dist/i18n/es.mjs": "1390bca3def2be115e811de337df0a0c3f63998e51359f283023246245c552a7", + "package/dist/i18n/fa.js": "8d3ef2e0f0cc0ea480c2167b6fcb87cdf444e90759c3519e8daa139fec576da4", + "package/dist/i18n/fa.mjs": "ab441e8a2d79043b29ceca87c783bf06874bb9d3a149c1604bc167eb481be2a9", + "package/dist/i18n/fr.js": "89dc4194a6c0a962b9ce756b52c90401c1acf3b159f265f3bc0d7d6d7d987f03", + "package/dist/i18n/fr.mjs": "99491878430fb7b6f2b7bf93da0588a831704b412e01116f23ba1d9d45863816", + "package/dist/i18n/id.js": "4c6dc86db741bcc2857df55a9d037e82e91d375fa6fd22e0562809ff621b92db", + "package/dist/i18n/id.mjs": "383e5803a6b6686c6de4e867770241de75b6f517dcca2bdedc6f2004bf6e1fb3", + "package/dist/i18n/pl.js": "3a38828b1c3d719c0aca9906cf6a46c23555a8411f8d57645f0e0ce8147dc664", + "package/dist/i18n/pl.mjs": "079ed96732979035297af387c64a7b99519b5a43107fb86735a654ea4fe8e9b5", + "package/dist/i18n/ru.js": "62fac9dddb302eb16382e6e9301fc4b2c66f5f69d4a358a26b67026a5fa4e787", + "package/dist/i18n/ru.mjs": "a893aeaee1d79409db72e324fbff200e3864f33ed168f04d91d25f7cf2efa765", + "package/dist/i18n/tr.js": "1492c36b069a7d73db4f3913bd18085faff7afd8b3c158138fe264e31600e38c", + "package/dist/i18n/tr.mjs": "a90478cac078836b76c2a98261907610fee07f3e4b28671b8e7dbf533778f918", + "package/dist/i18n/vi.js": "c7216ef7e608a79b7e2c479a07bf310d4ab79577947ac4a62d676faaced0e9cf", + "package/dist/i18n/vi.mjs": "66270fdfa0b5da396322d1769169b7df37a030ba15ac18eb30bd87b3af8074ec", + "package/dist/i18n/zh-tw.js": "11c49857d6d40a5ffd224ffa59c9026e71621b345f63c5a086326db80a22371a", + "package/dist/i18n/zh-tw.mjs": "a38e630cb96de96c15d824686aec750e25cf6c8ada01285a292442a81566314f", + "package/dist/icons.ts": "0d8e8e52e52130dd4a29bab551dd7a2a954797e42e92a6e068c85d583e23e6a4", + "package/dist/language.cts": "2248040d86a8e34626755c4ecf53ea0174706c653073cf0e15884a030d173120", + "package/dist/language.mts": "c391e863012c77769e661afbf8fa949e9373aa88d17f58cbba7f5696edb8077f", + "package/dist/legacy/language.ts": "c452ffd764ff9b29b819b3475c42395d2ea7a33560d8c186ef5df3844b9524c3", + "package/dist/option.ts": "850e5264219b8b438c80694402225b690b131786677a5da0d22739ec2352d263", + "package/dist/playback.ts": "1ceaed3aa1cef511fe8b20f4874647f6065c723ad805b742a0a9247e16bb1bb5", + "package/dist/player.ts": "f1e50257df2ea592d0a0e1f36078dda77eaf2cf3b3d795307501396562d99f28", + "package/dist/plugin.ts": "2a57e148fda00ee687da5036b890b0f611cb94bb403a1ed52602179060259d35", + "package/dist/quality.ts": "7ed6ed78cea52991b2f6ddd2bd3b7bd8c5146fdfff7486fe8b814c3e632f1567", + "package/dist/runtime.cts": "52cfff1daeb6841a90212c8fa8d46ca46d6650bb7ed1b59b62115d854b8ad652", + "package/dist/runtime.mts": "1b09bc0ee0f0ee2f788689eaff441bdeda1fab0ce783e71b61b9792d81072b03", + "package/dist/runtime.ts": "ec4b1d56993eb482a77eb0f94b701047549d009e6ba6433f27e7d464fef30c2b", + "package/dist/runtime/component.ts": "840213299c942fe058eb5436977ceec066b9dccda24c55ae9f464b399c979e39", + "package/dist/runtime/construction.ts": "24cc5cda1f614314db382271a9b0d5583b781894cfdf6c548700b1b5270467ee", + "package/dist/runtime/events.ts": "52848f57d35eb1037cf74c8877521edf99a015bcd77f30ef6bbcba1807a99bfe", + "package/dist/runtime/media.ts": "8828f80953aec3e95328cefe691661e8897cb27cb309483cf806ec45a8549ae3", + "package/dist/runtime/option.ts": "bb672e49ffe74a6fc78543217f6de80d7d738890146df0857c709d4dc283e4ce", + "package/dist/runtime/player.ts": "a4a24794e26cfb9e4310bf0f459a7a407e85bf81b4f3a4feb6294331af8036fb", + "package/dist/runtime/plugin.ts": "9ad482f2a77914a91450419680b8af6b314b926f0831c2f7f6d7c466690f95c9", + "package/dist/runtime/services.ts": "8e4648d8c61bff47343f9e1c2b995af69fc00947264b826109ceadcbaf553254", + "package/dist/runtime/setting.ts": "c48d20957b57f79f985ef76a2950cc8a5cfa25dafa8ec5939e562661778e6218", + "package/dist/runtime/subtitle.ts": "13241c4f9a87517aa2cf7b3e0bb8cedaa12fa0b4d3f8934285797583b752557e", + "package/dist/runtime/template.ts": "da9975513a1938e7f386f4f65f718f0fc595164bfeac8f0cd99a3e97a54919a1", + "package/dist/runtime/utils.ts": "cab9916f5224a3b047812b9f759cc9cc62105662599744067a6955020ab36916", + "package/dist/setting.ts": "d12a75b656fff70cbb30be4bffec46d9c4273636e8722bce971a4d2b188712a1", + "package/dist/subtitle.ts": "d25b470e47d6a9bd696d9c1ad8adb58e56a208f05695186d513bc8c43c2e8acf", + "package/dist/template.ts": "68aed9e97d006d6be4fabb8504ca84dafab770b0925f4d6e7319e67c82f21b0d", + "package/dist/utils.ts": "494ec447ab467a07ddd7a2c2abf778b3fce69fd28a09aaa8ced9759f8de2e3f6", + "package/package.json": "82e92699e7c29847f32ac6767ece0401290e7d7a12854722bdbcfd09b90b7954", + "package/types/COMPATIBILITY.md": "a7da9e102a116104b513df4f7451247b7759bc502d3375f30bd5b14a541826e0", + "package/types/README.md": "1bd9868e773610e6312fd48a1c5aa20772d29df0af40c3db66e75b7ab4a1aee0", + "package/types/artplayer.d.cts": "3685065e4263abcfd9d953176e461d5b3eb990b0363b54689a7f55deba770fef", + "package/types/artplayer.d.mts": "b664fec51ee5c5381f2ceab25d99d52aee56feab04a2ee7b4ea5b2145ea5fa0e", + "package/types/artplayer.d.ts": "5d0162adf7ac6d0f2bb9b5cfe361f28657c4d9c540cadbf36eba3cc954ce50f8", + "package/types/component.d.ts": "ae5bc1ddeaa1ee1ebbc62573e32423993727079205c64751a5a314170e588a32", + "package/types/config.d.ts": "36f9a84cd436f17701a0d11d3417fc1fe0414e0c52c80083b94a85dfc329e37e", + "package/types/cssVar.d.ts": "93217860fff2ebf750f606d95ddd22220a58837119e63bdf2f5f78fd7488458b", + "package/types/emitter.d.ts": "7e1f9a2a8ce65feb95734f1ed52d1334e57aa388bbef2a43d8bc53a9b6f6623c", + "package/types/events.d.ts": "f83624c9268a284477e8bd793fe3562a2363b72f2a44d5c64fe8c6a6cede8830", + "package/types/i18n.d.ts": "f4f2f05bdfda73c74fef34767cb18ee8e11b743120b1c4598e9714d7846018e5", + "package/types/icons.d.ts": "326a67ba7bdcf52862c5b2a269e540140aff98d05c7b96196485a77f84fe5960", + "package/types/language.d.cts": "f7928e108cf7b7814c2d75cb0a525333e95873fca6cd6d89a740450656b9c1cd", + "package/types/language.d.mts": "6619a26d604b7cccbe2f596243d87ae37cfaae33b8b52874ec071d9787446f9e", + "package/types/legacy/language.d.ts": "c7abda4d506fd933c350e9030290bf9e64347a921d683a66115da1995ebe0a81", + "package/types/option.d.ts": "ccf2c8ddc537dc65c9682d39f044726e23bff18f476b622512d7e6a4b949b5f6", + "package/types/playback.d.ts": "58705c273df6e76a77a6575e769a9ec6c013785c25080f2551aa22415788d870", + "package/types/player.d.ts": "92b00211b70ac71336e495899df972a0519dd138111846044fe4e0f967966177", + "package/types/plugin.d.ts": "fc3594a41c51d8248713e33c486fb1f6a518ac5c7ce31be6988a6cd8d052c5f3", + "package/types/quality.d.ts": "1ac1a48b4f74ff9ba1ce60443e1463d50d1c6a2e5d87d63dc7d2a8eb7f4c2c34", + "package/types/runtime.d.cts": "7ee988dfea9a0ac71a34a656f96f7b74e78aa92547cfdfab7ff7e1139a77d4a3", + "package/types/runtime.d.mts": "dcb85f59a8b7714918ced0c1d18c2bb24e8b80b56d8c594e019dcbdb5ad88b08", + "package/types/runtime.d.ts": "9c6ccd39a1be293f17ae46dae8ea077053e12635ee79d73a5e3b3a559230fcff", + "package/types/runtime/component.d.ts": "1b4c0cee44568649e80140fe778febfcae88af0ac85515f1cbeff78ab0c6d14f", + "package/types/runtime/construction.d.ts": "7a87bedf6f7ffff0c46078aa5f1551e0077d35574e286516121f5f935e2d9ce4", + "package/types/runtime/events.d.ts": "a1e2f9d387475453eaf95c2a5ee79e228636c0bb859bda3fcc46da46574a0c31", + "package/types/runtime/media.d.ts": "8fc89401be7fe25542c169d07dd5675f10916ed20be8493e19695966cf3864a8", + "package/types/runtime/option.d.ts": "6e334e1a76fdcc40b4665c02523bd31c3994d96078fadeb40e23422aa54c1a1d", + "package/types/runtime/player.d.ts": "8ac6383502e4872e83659838844856903031a81a0adc8e8535feb78453aa042c", + "package/types/runtime/plugin.d.ts": "8528f2b17843149f42f9cc16d6fd70baa238c9dc2c329b67d2c38096799c69bd", + "package/types/runtime/services.d.ts": "604c9f8e4b6c0da818f96576bf9f4b0e96085a9003927b2f7ba30027b1ba237e", + "package/types/runtime/setting.d.ts": "349c1fcb205ad312916bd3ee55e6bf241ea8a569fb2ab6c80822e69fc518f7d7", + "package/types/runtime/subtitle.d.ts": "269ff84678d327b3a9dc2f5bc6cc0d731d1e081b85422e474621d5d792efb153", + "package/types/runtime/template.d.ts": "7a62f968a38b4bf9109a4439557c02074eb1d62ba1f6e21a8eb194e91f0badfe", + "package/types/runtime/utils.d.ts": "6bf731705d86853e066dbaf3b8d4003b6548423fe615b7412b722bd0d3a6e48b", + "package/types/setting.d.ts": "08305a75dff96f06490430e099338b463df471b550c1d0dac3abc8995b39eb09", + "package/types/subtitle.d.ts": "b18314e2d64efdb6045830b6e12f615ae2ed585416130e562329ad3ea337f6ce", + "package/types/template.d.ts": "4792bc0c2cbcb7966e4375118bd34b326166e0831862e94ace4cf6b1bbe6a8c8", + "package/types/utils.d.ts": "fca0d3d814df94a25f9eb067c86fa0cf272e2791bac793b91229d57680797712" + } + }, + { + "name": "artplayer-plugin-vtt-thumbnail", + "archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\vtt-thumbnail-package-types-2gwRYF\\artplayer-plugin-vtt-thumbnail.tgz", + "sha256": "070e10cde447fb209ebff71b4525bcdebb97e3c7d84abd468a4102a6b6cde8d9", + "files": { + "package/ARCHITECTURE.md": "a3f2b2dbce227847f0b2155d3add9b2efd3986525a19834dd5213cfb70b128dd", + "package/README.md": "2291765836cf2399b057c506bc728f34b6ec14607e93c0de5d511a925b5005f3", + "package/dist/artplayer-plugin-vtt-thumbnail.js": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "package/dist/artplayer-plugin-vtt-thumbnail.legacy.js": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "package/dist/artplayer-plugin-vtt-thumbnail.mjs": "d35e28015df65e27da0fc01d06db07bad58e08d498b2d11fedfea35e6c4339c1", + "package/package.json": "8ebbeacaa7fa442b31cbda0012d77b5db9a2c04d588a86df0e124fd945145066", + "package/types/artplayer-plugin-vtt-thumbnail.d.cts": "56139aa2d39bfaa2aab9e1f1d22391278872e718b90290b81b6ab7eb0800a0ca", + "package/types/artplayer-plugin-vtt-thumbnail.d.mts": "56139aa2d39bfaa2aab9e1f1d22391278872e718b90290b81b6ab7eb0800a0ca", + "package/types/artplayer-plugin-vtt-thumbnail.d.ts": "76cd4e24fa734dadd9dac6528804216b793fe85dfbc37a6875a3d04498ca53c0", + "package/types/runtime.d.cts": "d99c2628bd086c99403f0d63e9fdbc2b8e58541b00926b08acfc6c1aa19fb2ce", + "package/types/runtime.d.mts": "b70486975dbe4329e1b9078f87ca7f3019ceb89d412714fe1c8e107e67b2365f", + "package/types/runtime.d.ts": "b70486975dbe4329e1b9078f87ca7f3019ceb89d412714fe1c8e107e67b2365f" + } + } + ], + "published": [ + { + "label": "published-1.0.3", + "archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\releases\\artplayer-plugin-vtt-thumbnail-1.0.3.tgz", + "sha256": "286ba11db6adaeb85a4b3fef198af9a10ed0a548566d57ef7efa77c4b4f05f83", + "missingEntrypoints": {} + }, + { + "label": "published-1.0.2", + "archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\releases\\artplayer-plugin-vtt-thumbnail-1.0.2.tgz", + "sha256": "a2230637d991731cef5f5f133bcb93a2e41bacb8a1a361b60b5c901a267fcbf1", + "missingEntrypoints": {} + }, + { + "label": "published-1.0.1", + "archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\releases\\artplayer-plugin-vtt-thumbnail-1.0.1.tgz", + "sha256": "2827599516c48fa17c3e8c917164df8ea3f9a3a5ef2643e079fd0df73a171175", + "missingEntrypoints": {} + }, + { + "label": "published-1.0.0", + "archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\releases\\artplayer-plugin-vtt-thumbnail-1.0.0.tgz", + "sha256": "18440510636529d76d97cd653433e65f795173e2e134d24caf0612845328dca1", + "missingEntrypoints": {} + }, + { + "label": "published-1.1.0", + "archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\releases\\artplayer-plugin-vtt-thumbnail-1.1.0.tgz", + "sha256": "e2df36283538bbffc2c37fe28a8af0fe6fc0fa68a5f6cf93042929ee64d55765", + "missingEntrypoints": {} + } + ], + "matrix": [ + { + "plugin": "published-1.0.3", + "compiler": "5.9.3", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [] + }, + { + "plugin": "published-1.0.3", + "compiler": "4.3.5", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [] + }, + { + "plugin": "published-1.0.2", + "compiler": "5.9.3", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [] + }, + { + "plugin": "published-1.0.2", + "compiler": "4.3.5", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [] + }, + { + "plugin": "published-1.0.1", + "compiler": "5.9.3", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [] + }, + { + "plugin": "published-1.0.1", + "compiler": "4.3.5", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [] + }, + { + "plugin": "published-1.0.0", + "compiler": "5.9.3", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [] + }, + { + "plugin": "published-1.0.0", + "compiler": "4.3.5", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [] + }, + { + "plugin": "published-1.1.0", + "compiler": "5.9.3", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [] + }, + { + "plugin": "published-1.1.0", + "compiler": "4.3.5", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [] + }, + { + "plugin": "candidate", + "compiler": "5.9.3", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [ + { + "code": 2322, + "message": "Type 'undefined' is not assignable to type 'Option'." + }, + { + "code": 2739, + "message": "Type 'Result' is missing the following properties from type 'Promise': then, catch, finally, [Symbol.toStringTag]" + }, + { + "code": 2339, + "message": "Property 'name' does not exist on type 'Promise'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2345, + "message": "Argument of type 'undefined' is not assignable to parameter of type 'Option'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2353, + "message": "Object literal may only specify known properties, and 'unknown' does not exist in type 'Option'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2741, + "message": "Property 'default' is missing in type '(option: Option) => (art: Artplayer) => Result' but required in type 'RuntimeFactory'." + } + ] + }, + { + "plugin": "candidate", + "compiler": "5.9.3", + "mode": "nodenext-cjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [ + { + "code": 2322, + "message": "Type 'undefined' is not assignable to type 'Option'." + }, + { + "code": 2739, + "message": "Type 'Result' is missing the following properties from type 'Promise': then, catch, finally, [Symbol.toStringTag]" + }, + { + "code": 2339, + "message": "Property 'name' does not exist on type 'Promise'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2345, + "message": "Argument of type 'undefined' is not assignable to parameter of type 'Option'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2353, + "message": "Object literal may only specify known properties, and 'unknown' does not exist in type 'Option'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2741, + "message": "Property 'default' is missing in type 'Factory' but required in type 'RuntimeFactory'." + } + ] + }, + { + "plugin": "candidate", + "compiler": "5.9.3", + "mode": "nodenext-esm", + "historicalFailure": false, + "diagnostics": [], + "invalid": [ + { + "code": 2322, + "message": "Type 'undefined' is not assignable to type 'Option'." + }, + { + "code": 2739, + "message": "Type 'Result' is missing the following properties from type 'Promise': then, catch, finally, [Symbol.toStringTag]" + }, + { + "code": 2339, + "message": "Property 'name' does not exist on type 'Promise'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2345, + "message": "Argument of type 'undefined' is not assignable to parameter of type 'Option'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2353, + "message": "Object literal may only specify known properties, and 'unknown' does not exist in type 'Option'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2741, + "message": "Property 'default' is missing in type 'Factory' but required in type 'RuntimeFactory'." + } + ] + }, + { + "plugin": "candidate", + "compiler": "5.9.3", + "mode": "bundler-esm", + "historicalFailure": false, + "diagnostics": [], + "invalid": [ + { + "code": 2322, + "message": "Type 'undefined' is not assignable to type 'Option'." + }, + { + "code": 2739, + "message": "Type 'Result' is missing the following properties from type 'Promise': then, catch, finally, [Symbol.toStringTag]" + }, + { + "code": 2339, + "message": "Property 'name' does not exist on type 'Promise'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2345, + "message": "Argument of type 'undefined' is not assignable to parameter of type 'Option'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2353, + "message": "Object literal may only specify known properties, and 'unknown' does not exist in type 'Option'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2741, + "message": "Property 'default' is missing in type 'Factory' but required in type 'RuntimeFactory'." + } + ] + }, + { + "plugin": "candidate", + "compiler": "4.3.5", + "mode": "node10-commonjs", + "historicalFailure": false, + "diagnostics": [], + "invalid": [ + { + "code": 2322, + "message": "Type 'undefined' is not assignable to type 'Option'." + }, + { + "code": 2739, + "message": "Type 'Result' is missing the following properties from type 'Promise': then, catch, finally, [Symbol.toStringTag]" + }, + { + "code": 2339, + "message": "Property 'name' does not exist on type 'Promise'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2345, + "message": "Argument of type 'undefined' is not assignable to parameter of type 'Option'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string | undefined'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string | undefined'." + }, + { + "code": 2345, + "message": "Argument of type '{ unknown: boolean; }' is not assignable to parameter of type 'Option'.\n Object literal may only specify known properties, and 'unknown' does not exist in type 'Option'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2741, + "message": "Property 'default' is missing in type '(option: Option) => (art: Artplayer) => Result' but required in type 'RuntimeFactory'." + } + ] + }, + { + "plugin": "candidate", + "compiler": "5.9.3", + "mode": "node10-commonjs-no-interop", + "historicalFailure": false, + "diagnostics": [], + "invalid": [ + { + "code": 2322, + "message": "Type 'undefined' is not assignable to type 'Option'." + }, + { + "code": 2739, + "message": "Type 'Result' is missing the following properties from type 'Promise': then, catch, finally, [Symbol.toStringTag]" + }, + { + "code": 2339, + "message": "Property 'name' does not exist on type 'Promise'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2345, + "message": "Argument of type 'undefined' is not assignable to parameter of type 'Option'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string'." + }, + { + "code": 2353, + "message": "Object literal may only specify known properties, and 'unknown' does not exist in type 'Option'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2741, + "message": "Property 'default' is missing in type '(option: Option) => (art: Artplayer) => Result' but required in type 'RuntimeFactory'." + } + ] + }, + { + "plugin": "candidate", + "compiler": "4.3.5", + "mode": "node10-commonjs-no-interop", + "historicalFailure": false, + "diagnostics": [], + "invalid": [ + { + "code": 2322, + "message": "Type 'undefined' is not assignable to type 'Option'." + }, + { + "code": 2739, + "message": "Type 'Result' is missing the following properties from type 'Promise': then, catch, finally, [Symbol.toStringTag]" + }, + { + "code": 2339, + "message": "Property 'name' does not exist on type 'Promise'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2345, + "message": "Argument of type 'undefined' is not assignable to parameter of type 'Option'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string | undefined'." + }, + { + "code": 2322, + "message": "Type 'number' is not assignable to type 'string | undefined'." + }, + { + "code": 2345, + "message": "Argument of type '{ unknown: boolean; }' is not assignable to parameter of type 'Option'.\n Object literal may only specify known properties, and 'unknown' does not exist in type 'Option'." + }, + { + "code": 2554, + "message": "Expected 1 arguments, but got 0." + }, + { + "code": 2741, + "message": "Property 'default' is missing in type '(option: Option) => (art: Artplayer) => Result' but required in type 'RuntimeFactory'." + } + ] + } + ] + } + }, + { + "command": "yarn lint", + "file": "refactor/.cache/vtt-thumbnail04-public-lint-verified.log", + "sha256": "1615e536a4b44d9f1b3ee90b27cf41e643494aa8afcdce556b4b1b66fa2c4a10" + }, + { + "command": "explicit lint of new refactor scripts/fixtures", + "file": "refactor/.cache/vtt-thumbnail04-public-refactor-lint-fixed.log", + "sha256": "f47cd52780b5e1ba8becd9622fb003e2f215e1bb26f0eed19c7fb0c25173fea1" + }, + { + "command": "parser and lifecycle source", + "tests": 48, + "pass": 48, + "file": "refactor/.cache/vtt-thumbnail04-public-unit-source.log", + "sha256": "38048508ac5800f87dce0bc3f1537086a5dbcf2bb7a077d285f73b31fc5c189b", + "scope": "Pure parser assertions use source; selected factory executes registration/error/lifecycle assertions." + }, + { + "command": "native browser source", + "file": "refactor/.cache/vtt-thumbnail04-public-browser-source.json", + "sha256": "bbdec3f89bbb43456f7ebf9d6a3a3cd24259b00a0551d405a4a0f2c90e8bbfea", + "resultsDirectory": "refactor/.cache/vtt-thumbnail04-public-browser-source-results", + "stats": { + "startTime": "2026-09-13T01:21:47.672Z", + "duration": 13529.308, + "expected": 18, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "VTT native published core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: destroy aborts a pending native fetch and settles registration", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + }, + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: destroy aborts a pending native fetch and settles registration", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + }, + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: destroy aborts a pending native fetch and settles registration", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "NS_BINDING_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: destroy aborts a pending native fetch and settles registration", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "NS_BINDING_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: destroy aborts a pending native fetch and settles registration", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "Load request cancelled" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: destroy aborts a pending native fetch and settles registration", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "04a472a60d199ea580490f5223d76de26bf25ca48134a4578446852d79dd9ac5", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "Load request cancelled" + } + } + ], + "consoleErrors": [] + } + ] + }, + { + "command": "parser and lifecycle main", + "tests": 48, + "pass": 48, + "file": "refactor/.cache/vtt-thumbnail04-public-unit-main.log", + "sha256": "05554da06f8114620436da3e53f83f73c19aeea7f9104f8aa0f814b5e46e04d0", + "scope": "Pure parser assertions use source; selected factory executes registration/error/lifecycle assertions." + }, + { + "command": "native browser main", + "file": "refactor/.cache/vtt-thumbnail04-public-browser-main.json", + "sha256": "a86a3ef21acf1aadcbd2fc3e039f670ecf0a05b4f5e37b50027f129aabb256dd", + "resultsDirectory": "refactor/.cache/vtt-thumbnail04-public-browser-main-results", + "stats": { + "startTime": "2026-09-13T01:22:34.870Z", + "duration": 12356.422999999999, + "expected": 18, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "VTT native published core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: destroy aborts a pending native fetch and settles registration", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + }, + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: destroy aborts a pending native fetch and settles registration", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + }, + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: destroy aborts a pending native fetch and settles registration", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "NS_BINDING_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: destroy aborts a pending native fetch and settles registration", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "NS_BINDING_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: destroy aborts a pending native fetch and settles registration", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "Load request cancelled" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: destroy aborts a pending native fetch and settles registration", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "Load request cancelled" + } + } + ], + "consoleErrors": [] + } + ] + }, + { + "command": "parser and lifecycle legacy", + "tests": 48, + "pass": 48, + "file": "refactor/.cache/vtt-thumbnail04-public-unit-legacy.log", + "sha256": "d799f63a3241366cffafc665f13438df9a9f818e704f22970f42d6f374d547f3", + "scope": "Pure parser assertions use source; selected factory executes registration/error/lifecycle assertions." + }, + { + "command": "native browser legacy", + "file": "refactor/.cache/vtt-thumbnail04-public-browser-legacy.json", + "sha256": "8cefd95f1edadb8a6b07b4763d38d69ce3788d79cc252fccd3655da747bb06cf", + "resultsDirectory": "refactor/.cache/vtt-thumbnail04-public-browser-legacy-results", + "stats": { + "startTime": "2026-09-13T01:22:47.956Z", + "duration": 12248.254, + "expected": 18, + "skipped": 0, + "unexpected": 0, + "flaky": 0 + }, + "cases": [ + { + "title": "VTT native published core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: destroy aborts a pending native fetch and settles registration", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + }, + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: destroy aborts a pending native fetch and settles registration", + "project": "chromium", + "status": "passed", + "browser": "153.0.8010.12", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + }, + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: destroy aborts a pending native fetch and settles registration", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "NS_BINDING_ABORTED" + } + }, + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "NS_BINDING_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: destroy aborts a pending native fetch and settles registration", + "project": "firefox", + "status": "passed", + "browser": "155.0", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "NS_BINDING_ABORTED" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native published core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native published core: destroy aborts a pending native fetch and settles registration", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "published", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "Load request cancelled" + } + } + ], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: real progress hover selects sprite regions and destroy removes owned UI", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "pixels": [ + [ + 255, + 0, + 0, + 255 + ], + [ + 0, + 0, + 255, + 255 + ] + ] + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: malformed sprite rejects before mounting and a corrected registration recovers", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "recoveredAfter": { + "name": "TypeError", + "message": "Invalid VTT thumbnail at line 4: rectangle coordinates must be finite non-negative decimals" + } + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [], + "consoleErrors": [] + }, + { + "title": "VTT native candidate core: destroy aborts a pending native fetch and settles registration", + "project": "webkit", + "status": "passed", + "browser": "26.6", + "platform": "win32", + "candidate": { + "core": "candidate", + "implementation": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "nativeAbort": true + }, + "core": { + "published": { + "source": { + "kind": "npm-release", + "version": "5.4.0", + "integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==", + "member": "package/dist/artplayer.js" + }, + "sha256": "f1db1fa3406aa6d41baa7c554749429a8e79f99d56a794bde23345eb9c07573f", + "bytes": 134037 + }, + "candidate": { + "source": { + "kind": "workspace-build", + "entry": "packages\\artplayer\\src\\index.ts" + }, + "sha256": "e8945bc9d3ff0a6e247772a662f874df13875f7dbeb949968943b9589f6e2946", + "bytes": 378073 + } + }, + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/vtt-held.vtt", + "resourceType": "fetch", + "failure": { + "errorText": "Load request cancelled" + } + } + ], + "consoleErrors": [] + } + ] + }, + { + "command": "yarn ci:check", + "tests": { + "unit": 1728, + "engineering": 14, + "baseline": 327, + "total": 2069 + }, + "strictProductionTypeScriptFiles": 346, + "file": "refactor/.cache/vtt-thumbnail04-public-ci.log", + "sha256": "e0c4f9d4d037cc46a3c9591dab772c6a6f4ac38400d913c78f17f203cf9630c5" + } + ], + "sourceAndTypes": { + "packages/artplayer-plugin-vtt-thumbnail/src/getVttArray.ts": "b7576efb3bae92f973acdf82d0fd4e3a6bfe63c2354deb02567ba1adda25415a", + "packages/artplayer-plugin-vtt-thumbnail/src/index.ts": "8b01a6a0e0fade1792f480b0e1a75318a7184cfb2d32be503be40dd6c33590dd", + "packages/artplayer-plugin-vtt-thumbnail/src/lifetime.ts": "073d8f38ec7b37c58cf4a3e4b853068645c67d8a834510f5dc68601ace3f9176", + "packages/artplayer-plugin-vtt-thumbnail/src/parseVtt.ts": "66e1d8fc58029366cb78a541e75f8c0c29fa346a6de4f34bf7d262b969a84190", + "packages/artplayer-plugin-vtt-thumbnail/src/preview.ts": "841a16dd9d9b7ea482226cb400f48bf5998705b4a3321807e6c38ff6f7a3046e", + "packages/artplayer-plugin-vtt-thumbnail/src/request.ts": "afae0e57e9c61c034a1494f09d0b9ee4ab43755c61607a94f1d21292a2fee8ef", + "packages/artplayer-plugin-vtt-thumbnail/src/types.ts": "1c50de5f12008b6a61d16bd3a865b84433a77bdb4dc4a1d1697a9d326f497b11", + "packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.cts": "56139aa2d39bfaa2aab9e1f1d22391278872e718b90290b81b6ab7eb0800a0ca", + "packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.mts": "56139aa2d39bfaa2aab9e1f1d22391278872e718b90290b81b6ab7eb0800a0ca", + "packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.ts": "76cd4e24fa734dadd9dac6528804216b793fe85dfbc37a6875a3d04498ca53c0", + "packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.cts": "d99c2628bd086c99403f0d63e9fdbc2b8e58541b00926b08acfc6c1aa19fb2ce", + "packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.mts": "b70486975dbe4329e1b9078f87ca7f3019ceb89d412714fe1c8e107e67b2365f", + "packages/artplayer-plugin-vtt-thumbnail/types/runtime.d.ts": "b70486975dbe4329e1b9078f87ca7f3019ceb89d412714fe1c8e107e67b2365f" + }, + "artifacts": { + "packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.js": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "docs/compiled/artplayer-plugin-vtt-thumbnail.js": "df70ccb5261fd988ba8c2c2d689ca58653bb5426242ffd1076569a1d225997a7", + "packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.legacy.js": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "docs/compiled/artplayer-plugin-vtt-thumbnail.legacy.js": "732ade2c647281cf26446d6c7433e916f8189e2fdf2687127a56556c415544b1", + "packages/artplayer-plugin-vtt-thumbnail/dist/artplayer-plugin-vtt-thumbnail.mjs": "d35e28015df65e27da0fc01d06db07bad58e08d498b2d11fedfea35e6c4339c1", + "docs/compiled/artplayer-plugin-vtt-thumbnail.mjs": "d35e28015df65e27da0fc01d06db07bad58e08d498b2d11fedfea35e6c4339c1" + }, + "publicEntrypoints": { + "packages/artplayer-plugin-vtt-thumbnail/package.json": "8ebbeacaa7fa442b31cbda0012d77b5db9a2c04d588a86df0e124fd945145066", + "packages/artplayer-plugin-vtt-thumbnail/.npmignore": "771df7bdc177956bd2f3493875159425bf1c2dd11d7d7386cb494b07620c0786", + "docs/assets/ts/artplayer-plugin-vtt-thumbnail.d.ts": "d82c0fe08bcf9c60e2a634e9f1fd8ccc75dc8e0ddbfa8262cccaefc9604aa61b" + } +} diff --git a/refactor/changes/2026-09-13-PKG-VTT-THUMB-04-public-types.md b/refactor/changes/2026-09-13-PKG-VTT-THUMB-04-public-types.md new file mode 100644 index 000000000..980dc1125 --- /dev/null +++ b/refactor/changes/2026-09-13-PKG-VTT-THUMB-04-public-types.md @@ -0,0 +1,48 @@ +# PKG-VTT-THUMB-04 公开类型与安装消费者检查点 + +本次覆盖 API-06/09/11:保留 root/legacy 的旧工厂参数、同步结果类型与工厂替换赋值, +增加 `/runtime` 入口,给新代码准确的 Promise。两种入口映射到同一产物和函数; +不会给 Promise 添加 name 字段来伪造同步返回。Option/Result 由公开定义统一维护, +内部实现引用这些数据类型,保持必传 options 对象、可选 vtt/style 和原有 CSS 字段类型。 + +## 消费方式与兼容边界 + +旧代码 `import vtt from 'artplayer-plugin-vtt-thumbnail'` 不需要改动。 +旧声明误把实际异步注册写成同步 Result;直接修正会影响 ReturnType 和替换工厂赋值。 +本次保留该兼容声明,新代码可使用 +`import vtt from 'artplayer-plugin-vtt-thumbnail/runtime'`,然后 +`const result = await vtt({ vtt: '/cues.vtt' })(art)`,无需消费者类型断言。 +没有改变运行时异步行为或默认产品配置。 + +导出函数增加可写的自引用 `.default`,兼容旧 1.0.x 有效的 CommonJS default 调用, +并保持最新直接调用。新回归在上个提交的真实 bundle 中仅此项失败,另外 21 项通过; +候选注册仍返回无同步 name 的 Promise。根入口/legacy 用 .d.mts/.d.cts 保留默认导入类型, +runtime 的 CommonJS 声明使用 export=,支持直接及 default 调用。typesVersions 支持 +classic 解析。编辑器全局仍为旧调用类型,命名空间 RuntimeFactory 只是类型,并非新增全局函数。 + +## 验证和工程改动 + +- 本包测试 251 项;源码/main/legacy 解析与生命周期各 48 项通过。纯 parser 断言仍取源码, + 非法输入、扩展 VTT 注册和生命周期会执行选定产物,不将纯函数检查计作安装包行为。 +- TS 5.9.3/5.1.6 严格源码检查通过,移除 expect-error 各复现 8 项预期错误。 + 公开声明五种模式各验证 10 项反例,编辑器 TS 5.9/4.3 各验证 2 项反例。 +- `yarn test:vtt-thumbnail-types-package` 是新增的实际打包验证脚本;固定 Yarn 1.22.22, + 在仓库外安装 packed core 和五份历史 npm 包/候选包,核对成员字节并执行 offline/frozen 重装。 + 五份旧声明 × 两个 classic 编译器,加候选七种模式,共 17 格通过。候选还验证原生 Node + root/runtime ESM 与 CJS 入口身份相同、legacy 默认导入与 require 身份相同。 +- 第一次实际 pack 发现 tsconfig.json 泄漏,已通过 .npmignore 排除,未关闭包内容检查。 + 新脚本及旧消费者夹具完成显式 lint;没有增加依赖或修改锁文件。 +- 原生 Chromium/Firefox/Windows WebKit,发布/候选核心,三场景和三种插件入口共 54 项通过, + 覆盖真实 hover、sprite 解码、非法输入恢复、原生 fetch 取消和 destroy 清理。不是实体 Safari 验收。 +- 正常 build 更新三个 dist 与 docs 副本;build:ts 用语义生成器更新编辑器声明。 + 完整 CI 的最终结果及内容指纹见 [验证记录](../baselines/vtt-thumbnail-public-types.json)。 + +## 剩余工作与回退 + +04 仍为 doing。已通过的历史类型消费者是 classic default-import 和工厂替换;历史 NodeNext、 +原始 import=require 的类型替换形式仍需逐项核对,不能扩称所有历史 TS 用法都通过。 +早期控件名、完整核心/设备组合、源码深路径分发与在线编辑器交互继续归 05/06。 +相关 TYPE/EXPORT 风险保持 open,尚未升级版本或达到 npm 发布条件。 + +本次作为独立本地检查点提交。回退本提交可恢复前次公开声明/入口并移除新增 runtime 入口 +及 default 别名;此前请求、解析与生命周期修复不受影响。不推送、不发布。 diff --git a/refactor/fixtures/consumers/vtt-thumbnail-published.ts b/refactor/fixtures/consumers/vtt-thumbnail-published.ts new file mode 100644 index 000000000..19722c54f --- /dev/null +++ b/refactor/fixtures/consumers/vtt-thumbnail-published.ts @@ -0,0 +1,9 @@ +import Artplayer from 'artplayer' +import vtt from 'artplayer-plugin-vtt-thumbnail' + +const option: Parameters[0] = { vtt: '/cues.vtt', style: { opacity: '0.8' } } +const art = new Artplayer({ container: '#player', url: '/video.mp4', plugins: [vtt(option)] }) +const result: ReturnType> = { name: 'artplayerPluginVttThumbnail' } +const replacement: typeof vtt = (_option: Parameters[0]) => (_art: Artplayer) => result +void vtt(option)(art).name +void replacement diff --git a/refactor/plan.md b/refactor/plan.md index 134263ae4..cfbe4be60 100644 --- a/refactor/plan.md +++ b/refactor/plan.md @@ -500,7 +500,7 @@ - PKG-VTT-THUMB-01: [记录](baselines/vtt-thumbnail-release.json) [记录](baselines/vtt-thumbnail-contract.md) [记录](changes/2026-09-13-PKG-VTT-THUMB-01-contract.md) - PKG-VTT-THUMB-02: [记录](baselines/vtt-thumbnail-failures.json) [记录](changes/2026-09-13-PKG-VTT-THUMB-02-failures.md) - PKG-VTT-THUMB-03: [记录](changes/2026-09-13-PKG-VTT-THUMB-03-resources.md) [记录](baselines/vtt-thumbnail-resources.json) [记录](changes/2026-09-13-PKG-VTT-THUMB-03-parser.md) [记录](baselines/vtt-thumbnail-parser.json) -- PKG-VTT-THUMB-04: [记录](changes/2026-09-13-PKG-VTT-THUMB-04-runtime-types.md) [记录](baselines/vtt-thumbnail-runtime-types.json) +- PKG-VTT-THUMB-04: [记录](changes/2026-09-13-PKG-VTT-THUMB-04-runtime-types.md) [记录](baselines/vtt-thumbnail-runtime-types.json) [记录](changes/2026-09-13-PKG-VTT-THUMB-04-public-types.md) [记录](baselines/vtt-thumbnail-public-types.json) - PKG-HLS-01: [记录](baselines/hls-control-contract.md) [记录](baselines/hls-control-release.json) [记录](changes/2026-09-11-PKG-HLS-01-contract.md) - PKG-HLS-02: [记录](hls-validation.md) [记录](baselines/hls-sdk.json) [记录](baselines/hls-validation.json) [记录](changes/2026-09-11-PKG-HLS-02-tests.md) - PKG-HLS-03: [记录](changes/2026-09-12-PKG-HLS-03-modules.md) [记录](baselines/hls-modules-validation.json) [记录](hls-validation.md) diff --git a/refactor/progress.md b/refactor/progress.md index c47a461e2..a22ecc898 100644 --- a/refactor/progress.md +++ b/refactor/progress.md @@ -1,5 +1,19 @@ # 进度与证据 +## PKG-VTT-THUMB-04 公开类型与安装消费者检查点(doing) + +保留 root/legacy 旧参数、同步结果类型及替换工厂赋值,新增 /runtime 表达真实 Promise, +两入口复用相同函数。可写 .default 自引用恢复旧 CJS default 调用,Promise 不伪装同步 name。 +公开 Option/Result 与内部实现共用;成对模块声明、classic typesVersions 和编辑器生成同步。 +本包 251 项、三入口各 48 项、原生三入口共 54 项通过;仓库外实际安装五历史包与候选包, +17 格类型矩阵和 Node 入口身份通过,offline/frozen 重装及成员字节核对通过。 +修复实际 pack 发现的 tsconfig 泄漏。TS 5.9.3/5.1.6 严格正反例通过,完整 CI 2069 项通过。 +见[变更](changes/2026-09-13-PKG-VTT-THUMB-04-public-types.md)和 +[验证](baselines/vtt-thumbnail-public-types.json)。历史 NodeNext/raw require 类型形式仍待 04, +完整核心/设备、早期控件名与分发/demo 仍待 05/06,TYPE/EXPORT 风险未关闭。 +222 项:117 done、13 doing、92 todo;独立本地检查点提交,不推送、不发布。 + + ## PKG-VTT-THUMB-04 严格运行时 TS 检查点(doing) 六个 JS 实现迁为 TS,另有明确数据/资源类型模块,分包 allowJs=false。TS 5.9.3/5.1.6 diff --git a/refactor/risks.json b/refactor/risks.json index 1751a1188..94b7d72df 100644 --- a/refactor/risks.json +++ b/refactor/risks.json @@ -4202,7 +4202,10 @@ "refactor/baselines/vtt-thumbnail-contract.md", "refactor/scripts/vtt-thumbnail-contract.test.mjs", "test/types/vtt-thumbnail-runtime.ts", - "refactor/baselines/vtt-thumbnail-runtime-types.json" + "refactor/baselines/vtt-thumbnail-runtime-types.json", + "refactor/changes/2026-09-13-PKG-VTT-THUMB-04-public-types.md", + "refactor/baselines/vtt-thumbnail-public-types.json", + "refactor/scripts/vtt-thumbnail-package-types.mjs" ], "compatibleResolution": "Preserve valid consumers and actual async runtime, with explicit decisions for irreconcilable inference changes.", "closureCriteria": "Isolated old/new compiler and installed consumers verify options, styles, callback and result forms." @@ -4220,7 +4223,10 @@ "evidence": [ "refactor/baselines/vtt-thumbnail-release.json", "refactor/baselines/vtt-thumbnail-contract.md", - "refactor/scripts/vtt-thumbnail-contract.test.mjs" + "refactor/scripts/vtt-thumbnail-contract.test.mjs", + "refactor/changes/2026-09-13-PKG-VTT-THUMB-04-public-types.md", + "refactor/baselines/vtt-thumbnail-public-types.json", + "refactor/scripts/vtt-thumbnail-package-types.mjs" ], "compatibleResolution": "Validate historical import forms and control integrations before selecting compatibility adapters.", "closureCriteria": "Actual package consumers and old/new cores prove supported forms; unresolved differences stay explicit." diff --git a/refactor/scripts/vtt-thumbnail-package-types.mjs b/refactor/scripts/vtt-thumbnail-package-types.mjs new file mode 100644 index 000000000..64b042b41 --- /dev/null +++ b/refactor/scripts/vtt-thumbnail-package-types.mjs @@ -0,0 +1,108 @@ +import assert from 'node:assert/strict' +import fs from 'node:fs' +import path from 'node:path' +import process from 'node:process' +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 { hash, readMember } from './releases.mjs' +import { verifyVttThumbnailContract } from './vtt-thumbnail-contract.mjs' + +async function main() { + assert.equal(process.env.npm_config_user_agent?.split(' ')[0], 'yarn/1.22.22', 'Use yarn test:vtt-thumbnail-types-package') + const yarn = process.env.npm_execpath + assert(yarn && fs.existsSync(yarn)) + const output = fs.mkdtempSync(path.join(workspace, 'refactor/.cache/vtt-thumbnail-package-types-')) + console.log(`VTT thumbnail isolated package evidence: ${output}`) + const contract = await verifyVttThumbnailContract() + const packages = [] + for (const name of ['artplayer', 'artplayer-plugin-vtt-thumbnail']) { + const archive = path.join(output, `${name}.tgz`) + fs.writeFileSync(path.join(output, `${name}-pack.log`), run([yarn, 'pack', '--filename', archive], path.join(workspace, 'packages', name))) + const manifest = JSON.parse(readMember(archive, 'package/package.json')) + const files = packedFiles(archive) + checkFiles(manifest, files, name === contract.baseline.release.name ? Object.keys(contract.baseline.release.files) : []) + packages.push({ name, archive, sha256: hash(fs.readFileSync(archive)), files: Object.fromEntries(files.map(member => [member, hash(readMember(archive, member))])) }) + } + const matrix = [] + const core = packages[0] + const candidates = [ + ...[...contract.baseline.previous].reverse().concat(contract.baseline.release).map(release => ({ ...release, archive: contract.archives.get(release.version), label: `published-${release.version}` })), + { ...packages[1], label: 'candidate' }, + ] + for (const plugin of candidates) { + const consumer = consumerDirectory() + try { + writeJson(path.join(consumer, 'package.json'), { name: 'vtt-thumbnail-isolated-consumer', private: true, dependencies: Object.fromEntries([core, plugin].map(pkg => [pkg.name, `file:${pkg.archive.replaceAll('\\', '/')}`])) }) + fs.copyFileSync(path.join(workspace, 'yarn.lock'), path.join(consumer, 'yarn.lock')) + fs.writeFileSync(path.join(output, `${plugin.label}-install.log`), run([yarn, 'install', '--offline', '--ignore-scripts', '--non-interactive'], consumer)) + const lock = fs.readFileSync(path.join(consumer, 'yarn.lock')) + fs.writeFileSync(path.join(output, `${plugin.label}-frozen-install.log`), run([yarn, 'install', '--offline', '--frozen-lockfile', '--ignore-scripts', '--non-interactive'], consumer)) + assert.deepEqual(fs.readFileSync(path.join(consumer, 'yarn.lock')), lock) + fs.writeFileSync(path.join(output, `${plugin.label}-yarn.lock`), lock) + for (const pkg of [core, plugin]) { + const root = path.join(consumer, 'node_modules', pkg.name) + assert.equal(fs.realpathSync(root), root, 'Installed package must not be a workspace link') + for (const [member, expected] of Object.entries(pkg.files)) + assert.equal(hash(fs.readFileSync(path.join(root, member.slice(8)))), expected, `Installed bytes differ: ${member}`) + } + const runtimeFile = path.join(consumer, 'exports.cjs') + fs.writeFileSync(runtimeFile, plugin.label === 'candidate' + ? `const assert = require('node:assert/strict'); +for (const name of ['artplayer-plugin-vtt-thumbnail', 'artplayer-plugin-vtt-thumbnail/legacy', 'artplayer-plugin-vtt-thumbnail/runtime']) { const factory = require(name); assert.equal(typeof factory, 'function'); assert.equal(factory.default, factory); assert.equal(typeof factory({}), 'function'); } +assert.equal(require('artplayer-plugin-vtt-thumbnail/runtime'), require('artplayer-plugin-vtt-thumbnail')); +Promise.all(['artplayer-plugin-vtt-thumbnail', 'artplayer-plugin-vtt-thumbnail/runtime', 'artplayer-plugin-vtt-thumbnail/legacy'].map(name => import(name))).then(([root, runtime, legacy]) => { assert.deepEqual(Object.keys(root), ['default']); assert.deepEqual(Object.keys(runtime), ['default']); assert.equal(runtime.default, root.default); assert.equal(root.default.default, root.default); assert.equal(legacy.default, require('artplayer-plugin-vtt-thumbnail/legacy')); assert.equal(legacy.default.default, legacy.default); }).catch(error => { console.error(error); process.exitCode = 1; });` + : plugin.version === '1.0.0' + ? `const assert = require('node:assert/strict'); assert.throws(() => require('artplayer-plugin-vtt-thumbnail'), error => error.name === 'SyntaxError' && error.message.includes('Invalid regular expression')); console.log('Expected historical 1.0.0 invalid runtime syntax preserved');` + : `const assert = require('node:assert/strict'); const value = require('artplayer-plugin-vtt-thumbnail'); assert.equal(typeof value, '${plugin.version === '1.1.0' ? 'function' : 'object'}'); assert.equal(typeof (value.default || value)({}), 'function');`) + fs.writeFileSync(path.join(output, `${plugin.label}-runtime.log`), run([runtimeFile], consumer)) + const candidateModes = [[ts, 'node10-commonjs'], [ts, 'nodenext-cjs'], [ts, 'nodenext-esm'], [ts, 'bundler-esm'], [compat, 'node10-commonjs']] + if (plugin.label === 'candidate') + candidateModes.push([ts, 'node10-commonjs-no-interop'], [compat, 'node10-commonjs-no-interop']) + for (const [compiler, mode] of (plugin.label === 'candidate' ? candidateModes : [[ts, 'node10-commonjs'], [compat, 'node10-commonjs']])) { + const next = mode.startsWith('nodenext') + const extension = next ? mode.endsWith('-cjs') ? 'cts' : 'mts' : 'ts' + const source = fs.readFileSync(path.join(workspace, plugin.label === 'candidate' ? 'test/types/vtt-thumbnail-public.ts' : 'refactor/fixtures/consumers/vtt-thumbnail-published.ts'), 'utf8') + const filename = path.join(consumer, `consumer.${extension}`) + const historical = path.join(consumer, `historical.${extension}`) + fs.copyFileSync(path.join(workspace, 'refactor/fixtures/consumers/vtt-thumbnail-published.ts'), historical) + const files = plugin.label === 'candidate' ? [filename, historical] : [filename] + if (mode === 'nodenext-cjs' && plugin.label === 'candidate') { + const commonjs = path.join(consumer, 'commonjs.cts') + fs.writeFileSync(commonjs, `import vtt = require('artplayer-plugin-vtt-thumbnail'); import legacy = require('artplayer-plugin-vtt-thumbnail/legacy'); import runtime = require('artplayer-plugin-vtt-thumbnail/runtime'); vtt.default({}); legacy.default({}); runtime({}); runtime.default({});`) + files.push(commonjs) + } + const options = { strict: true, noEmit: true, skipLibCheck: false, types: [], esModuleInterop: !mode.endsWith('-no-interop'), target: compiler.ScriptTarget.ES2020, lib: ['lib.es2020.d.ts', 'lib.dom.d.ts'], module: next ? compiler.ModuleKind.NodeNext : mode === 'bundler-esm' ? compiler.ModuleKind.ESNext : compiler.ModuleKind.CommonJS, moduleResolution: next ? compiler.ModuleResolutionKind.NodeNext : mode === 'bundler-esm' ? compiler.ModuleResolutionKind.Bundler : compiler.ModuleResolutionKind.NodeJs } + function compile(code) { + fs.writeFileSync(filename, code) + const program = compiler.createProgram(files, options) + for (const file of program.getSourceFiles()) { + const actual = fs.realpathSync(file.fileName) + assert(actual.startsWith(fs.realpathSync(consumer) + path.sep) || (program.isSourceFileDefaultLibrary(file) && path.dirname(actual) === fs.realpathSync(path.dirname(compiler.sys.getExecutingFilePath()))), `Types escaped installed consumer: ${actual}`) + } + return compiler.getPreEmitDiagnostics(program).map(item => ({ code: item.code, message: compiler.flattenDiagnosticMessageText(item.messageText, '\n') })) + } + const diagnostics = compile(source) + const expected = [] + const historicalFailure = false + writeJson(path.join(output, `${plugin.label}-${compiler.version}-${mode}-diagnostics.json`), { diagnostics, historicalFailure }) + assert.deepEqual(diagnostics.map(item => item.code), expected, `${plugin.label} ${compiler.version} ${mode}`) + const invalid = plugin.label === 'candidate' ? compile(source.replaceAll(/\/\/ @ts-expect-error[^\n]*\n/g, '')) : [] + if (plugin.label === 'candidate') + assert.equal(invalid.length, 10, 'Installed declarations must reject all invalid uses') + matrix.push({ plugin: plugin.label, compiler: compiler.version, mode, historicalFailure, diagnostics, invalid }) + } + } + finally { + removeConsumer(consumer) + } + } + writeJson(path.join(output, 'report.json'), { suite: 'vtt-thumbnail-isolated-package-types', introducedBy: 'PKG-VTT-THUMB-04', scope: 'Five actual published packages (classic default-import consumers on TS 4.3 and 5.9) and packed candidate (seven compiler modes) installed outside the workspace with packed core. Offline/frozen reinstall and byte identity are verified. Candidate provides an opt-in accurate runtime entry; 1.0.0 invalid bundle syntax is retained. Historical NodeNext variants, raw require type replacements, device and full distribution acceptance remain separate.', packages, published: candidates.slice(0, 5).map(pkg => ({ label: pkg.label, archive: pkg.archive, sha256: hash(fs.readFileSync(pkg.archive)), missingEntrypoints: pkg.missingEntrypoints })), matrix }) + console.log(`VTT thumbnail installed types passed: ${matrix.length} cases; ${output}`) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/refactor/scripts/vtt-thumbnail-types.test.mjs b/refactor/scripts/vtt-thumbnail-types.test.mjs new file mode 100644 index 000000000..7d72745b8 --- /dev/null +++ b/refactor/scripts/vtt-thumbnail-types.test.mjs @@ -0,0 +1,81 @@ +import assert from 'node:assert/strict' +import fs from 'node:fs' +import path from 'node:path' +// eslint-disable-next-line test/no-import-node-test -- Compatibility declaration runner. +import test from 'node:test' +import { ESLint } from 'eslint' +import ts from 'typescript' +import compat from 'typescript-compat' +import { checkPluginEditorDeclaration, generatePluginEditorDeclaration } from '../../scripts/plugin-editor-types.mjs' +import { checkConsumer } from '../../scripts/typecheck.mjs' +import { readMember } from './releases.mjs' +import { verifyVttThumbnailContract } from './vtt-thumbnail-contract.mjs' + +const modes = [[ts, 'node10-commonjs'], [ts, 'nodenext-cjs'], [ts, 'nodenext-esm'], [ts, 'bundler-esm'], [compat, 'node10-commonjs']] + +test('VTT generated editor globals retain legacy calls and expose separately named data and runtime types', async () => { + const source = fs.readFileSync('packages/artplayer-plugin-vtt-thumbnail/types/artplayer-plugin-vtt-thumbnail.d.ts', 'utf8') + const generated = generatePluginEditorDeclaration(source, 'artplayerPluginVttThumbnail') + const file = 'docs/assets/ts/artplayer-plugin-vtt-thumbnail.d.ts' + const [formatted] = await new ESLint({ fix: true, fixTypes: ['layout'] }).lintText(generated, { filePath: file }) + assert.equal(formatted.errorCount, 0) + assert.equal(fs.readFileSync(file, 'utf8').replaceAll('\r\n', '\n'), formatted.output || generated) + const core = fs.readFileSync('docs/assets/ts/artplayer.d.ts', 'utf8') + const consumer = `declare const art: Artplayer; +const options: artplayerPluginVttThumbnail.Option = { vtt: '/cues.vtt' }; +const result: artplayerPluginVttThumbnail.Result = artplayerPluginVttThumbnail(options)(art); +declare const runtime: artplayerPluginVttThumbnail.RuntimeFactory; +const pending: Promise = runtime(options)(art); +// @ts-expect-error Legacy extraction stays synchronous. +const changed: Promise = result; +// @ts-expect-error URL must be text. +artplayerPluginVttThumbnail({ vtt: 12 });` + for (const compiler of [ts, compat]) { + assert.deepEqual(checkPluginEditorDeclaration(generated, core, consumer, compiler), []) + assert.equal(checkPluginEditorDeclaration(generated, core, consumer.replaceAll(/\/\/ @ts-expect-error[^\n]*\n/g, ''), compiler).length, 2) + } +}) + +test('VTT public legacy extraction remains exact while runtime entry gives cast-free Promise types', () => { + const source = fs.readFileSync('test/types/vtt-thumbnail-public.ts', 'utf8') + for (const [compiler, mode] of modes) { + assert.deepEqual(checkConsumer(compiler, mode, source), [], `${compiler.version} ${mode}`) + assert.equal(checkConsumer(compiler, mode, source.replaceAll(/\/\/ @ts-expect-error[^\n]*\n/g, '')).length, 10) + } +}) + +test('VTT runtime CommonJS declaration supports direct and default calls without an interop cast', () => { + assert.deepEqual(checkConsumer(ts, 'nodenext-cjs', `import runtime = require('artplayer-plugin-vtt-thumbnail/runtime'); +import legacy = require('artplayer-plugin-vtt-thumbnail'); +import type Artplayer from 'artplayer'; declare const art: Artplayer; +const first = runtime({})(art); const second = runtime.default({})(art); +const promise: Promise<{name: 'artplayerPluginVttThumbnail'}> = first; +legacy.default({})(art).name; void [promise, second];`), []) +}) + +test('VTT all five historical declarations keep the same default-import consumers and replaceable old factory', async () => { + const contract = await verifyVttThumbnailContract() + const consumer = fs.readFileSync('refactor/fixtures/consumers/vtt-thumbnail-published.ts', 'utf8') + for (const release of [contract.baseline.release, ...contract.baseline.previous]) { + const old = readMember(contract.archives.get(release.version), `package/${release.manifest.types.replace(/^\.\//, '')}`).toString() + for (const compiler of [ts, compat]) { + const filename = path.resolve('test/types/vtt-historical-consumer.ts') + const declaration = path.resolve('test/types/vtt-historical.d.ts') + const options = { strict: true, noEmit: true, skipLibCheck: false, types: [], esModuleInterop: true, module: compiler.ModuleKind.CommonJS, moduleResolution: compiler.ModuleResolutionKind.NodeJs, target: compiler.ScriptTarget.ES2020, lib: ['lib.es2020.d.ts', 'lib.dom.d.ts'] } + function historical(source) { + const host = compiler.createCompilerHost(options) + const read = host.getSourceFile.bind(host) + host.getSourceFile = (file, language, ...rest) => path.resolve(file) === filename + ? compiler.createSourceFile(file, source.replace('from \'artplayer-plugin-vtt-thumbnail\'', 'from \'./vtt-historical\''), language, true) + : path.resolve(file) === declaration ? compiler.createSourceFile(file, old, language, true) : read(file, language, ...rest) + const exists = host.fileExists.bind(host) + host.fileExists = file => path.resolve(file) === declaration || exists(file) + return compiler.getPreEmitDiagnostics(compiler.createProgram([filename, declaration], options, host)).map(error => error.code) + } + assert.deepEqual(historical(consumer), []) + assert.deepEqual(historical(`${consumer}\nvtt();`), [2554]) + assert.deepEqual(historical(`${consumer}\nconst absent: Parameters[0] = undefined;`), [2322]) + assert.deepEqual(checkConsumer(compiler, 'node10-commonjs', consumer), []) + } + } +}) diff --git a/refactor/tasks.json b/refactor/tasks.json index 9c922fe19..81bbc93d7 100644 --- a/refactor/tasks.json +++ b/refactor/tasks.json @@ -1927,7 +1927,9 @@ "acceptance": "严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容", "evidence": [ "changes/2026-09-13-PKG-VTT-THUMB-04-runtime-types.md", - "baselines/vtt-thumbnail-runtime-types.json" + "baselines/vtt-thumbnail-runtime-types.json", + "changes/2026-09-13-PKG-VTT-THUMB-04-public-types.md", + "baselines/vtt-thumbnail-public-types.json" ] }, { diff --git a/scripts/build-ts.js b/scripts/build-ts.js index 1acca87d8..6d51d20c8 100644 --- a/scripts/build-ts.js +++ b/scripts/build-ts.js @@ -53,7 +53,7 @@ console.log(`✨ Built ${artplayerTSoutput}`); const type = pluginsTS[index] const { name, file } = parsePluginInfo(type) const source = String(fs.readFileSync(type)) - const semanticPlugin = ['artplayerPluginHlsControl', 'artplayerPluginAudioTrack', 'artplayerPluginDashControl', 'artplayerPluginAds', 'artplayerPluginAmbilight', 'artplayerProxyCanvas', 'artplayerProxyMediabunny', 'artplayerPluginDocumentPip', 'ArtplayerToolIframe', 'ArtplayerToolThumbnail'].includes(name) + const semanticPlugin = ['artplayerPluginVttThumbnail', 'artplayerPluginHlsControl', 'artplayerPluginAudioTrack', 'artplayerPluginDashControl', 'artplayerPluginAds', 'artplayerPluginAmbilight', 'artplayerProxyCanvas', 'artplayerProxyMediabunny', 'artplayerPluginDocumentPip', 'ArtplayerToolIframe', 'ArtplayerToolThumbnail'].includes(name) const localTypes = name === 'artplayerProxyMediabunny' ? { './media': fs.readFileSync(path.join(path.dirname(type), 'media.d.ts'), 'utf8') } : {} const code = semanticPlugin ? generatePluginEditorDeclaration(source, name, localTypes) diff --git a/test/types/vtt-thumbnail-public.ts b/test/types/vtt-thumbnail-public.ts new file mode 100644 index 000000000..b1f954a8a --- /dev/null +++ b/test/types/vtt-thumbnail-public.ts @@ -0,0 +1,45 @@ +import type { Factory, Option, Result, RuntimeFactory } from 'artplayer-plugin-vtt-thumbnail' +import Artplayer from 'artplayer' +import legacy from 'artplayer-plugin-vtt-thumbnail' +import legacyEntry from 'artplayer-plugin-vtt-thumbnail/legacy' +import runtime from 'artplayer-plugin-vtt-thumbnail/runtime' + +type Equal = (() => T extends A ? 1 : 2) extends (() => T extends B ? 1 : 2) ? true : false +type Assert = T +type ExactOptions = Assert, [option: Option]>> +type ExactFactory = Assert> +type ExactResult = Assert>, Result>> +type ActualResult = Assert>, Promise>> + +const option: Option = { vtt: '/cues.vtt', style: { opacity: '0.8' } } +const art = new Artplayer({ container: '#player', url: '/video.mp4', plugins: [legacy(option), runtime(option)] }) +const old: Result = legacy(option)(art) +const oldReplacement: typeof legacy = (_option: Option) => (_art: Artplayer) => ({ name: 'artplayerPluginVttThumbnail' }) +legacyEntry(option) +const factory: RuntimeFactory = runtime +const pending: Promise = factory(option)(art) +const alias: Promise = factory.default.default(option)(art) +factory.default = runtime +const awaitedName: Promise<'artplayerPluginVttThumbnail'> = pending.then(result => result.name) +// @ts-expect-error Published extraction keeps the option object required. +const absent: Parameters[0] = undefined +// @ts-expect-error Root declarations preserve historical synchronous extraction. +const changed: Promise = old +// @ts-expect-error Runtime entry does not invent a synchronous result field. +void pending.name +// @ts-expect-error Runtime options remain required. +runtime() +// @ts-expect-error Required option object is not undefined. +runtime(undefined) +// @ts-expect-error URL remains a string. +runtime({ vtt: 1 }) +// @ts-expect-error CSS width remains a string. +runtime({ style: { width: 80 } }) +// @ts-expect-error Unknown options are not silently accepted. +runtime({ unknown: true }) +// @ts-expect-error A host is required. +runtime({})() +// @ts-expect-error The runtime entry cannot be replaced with a synchronous registrar. +const wrong: typeof runtime = oldReplacement +void [alias, awaitedName, absent, changed, wrong] +export type { ActualResult, ExactFactory, ExactOptions, ExactResult } diff --git a/test/vtt-thumbnail-lifecycle.test.js b/test/vtt-thumbnail-lifecycle.test.js index 155df18c1..a654d8306 100644 --- a/test/vtt-thumbnail-lifecycle.test.js +++ b/test/vtt-thumbnail-lifecycle.test.js @@ -11,6 +11,18 @@ async function flush() { } const count = env => [...env.listeners.values()].reduce((sum, items) => sum + items.length, 0) +test('VTT candidate preserves callable default identity without adding synchronous fields to the registration Promise', async () => { + const env = create() + assert.equal(env.factory.default, env.factory) + assert.equal(env.factory.default.default, env.factory) + assert.equal(Object.getOwnPropertyDescriptor(env.factory, 'default').writable, true) + const pending = env.factory.default({})(env.art) + assert.equal(pending.name, undefined) + assert.deepEqual(Object.keys(pending), []) + assert.equal((await pending).name, 'artplayerPluginVttThumbnail') + await env.emit('destroy') +}) + test('VTT candidate retains asynchronous registration, live style, floored bounds and literal image paths', async () => { const env = create({ deferred: true }) const option = { vtt: '/folder/cues.vtt', style: {} }