refactor(asr): [PKG-ASR-04] preserve old declarations and add precise runtime types

This commit is contained in:
Harvey Zhao committed 2026-09-13 15:07:04 +08:00
1 parent 0cf2af4840
commit 93208e59e1
24 files changed
+1224 -19

No files matched your search

@@ -0,0 +1,254 @@
{
"schemaVersion": 1,
"task": "PKG-ASR-04",
"sourceReport": "refactor/.cache/asr-package-types-3KzGBO/report.json",
"scope": "Observed strict installed consumers from frozen 2.0.0 and 2.1.0 archives with packed candidate core. Both old NodeNext ESM default imports are namespaces; direct-call diagnostics are retained, not counted as passing compatibility. Legal namespace consumers are verified separately.",
"cases": [
{
"plugin": "published-2.0.0",
"compiler": "5.9.3",
"mode": "node10-commonjs",
"diagnostics": []
},
{
"plugin": "published-2.0.0",
"compiler": "5.9.3",
"mode": "nodenext-cjs",
"diagnostics": []
},
{
"plugin": "published-2.0.0",
"compiler": "5.9.3",
"mode": "nodenext-esm",
"diagnostics": [
{
"file": "consumer.mts",
"line": 26,
"code": 2322,
"message": "Type '{ length: number; interval: number; sampleRate: number; autoHideTimeout: number; onAudioChunk(chunk: any): void; }' is not assignable to type 'never'."
},
{
"file": "consumer.mts",
"line": 26,
"code": 2344,
"message": "Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' does not satisfy the constraint '(...args: any) => any'.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' provides no match for the signature '(...args: any): any'."
},
{
"file": "consumer.mts",
"line": 31,
"code": 7006,
"message": "Parameter 'chunk' implicitly has an 'any' type."
},
{
"file": "consumer.mts",
"line": 37,
"code": 2322,
"message": "Type 'undefined' is not assignable to type 'never'."
},
{
"file": "consumer.mts",
"line": 37,
"code": 2344,
"message": "Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' does not satisfy the constraint '(...args: any) => any'.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' provides no match for the signature '(...args: any): any'."
},
{
"file": "consumer.mts",
"line": 39,
"code": 2344,
"message": "Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' does not satisfy the constraint '(...args: any) => any'.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' provides no match for the signature '(...args: any): any'."
},
{
"file": "consumer.mts",
"line": 46,
"code": 2322,
"message": "Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' is not assignable to type 'PublishedFactory'.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' provides no match for the signature '(option?: PublishedOption | undefined): (art: Artplayer) => PublishedResult'."
},
{
"file": "consumer.mts",
"line": 47,
"code": 2322,
"message": "Type 'PublishedFactory' is not assignable to type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")'."
},
{
"file": "consumer.mts",
"line": 48,
"code": 2322,
"message": "Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' is not assignable to type 'PublishedFactory'.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' provides no match for the signature '(option?: PublishedOption | undefined): (art: Artplayer) => PublishedResult'."
},
{
"file": "consumer.mts",
"line": 49,
"code": 2349,
"message": "This expression is not callable.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' has no call signatures."
},
{
"file": "consumer.mts",
"line": 49,
"code": 2349,
"message": "This expression is not callable.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' has no call signatures."
},
{
"file": "consumer.mts",
"line": 49,
"code": 2349,
"message": "This expression is not callable.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' has no call signatures."
},
{
"file": "consumer.mts",
"line": 49,
"code": 2349,
"message": "This expression is not callable.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' has no call signatures."
},
{
"file": "consumer.mts",
"line": 50,
"code": 2349,
"message": "This expression is not callable.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' has no call signatures."
},
{
"file": "consumer.mts",
"line": 54,
"code": 2339,
"message": "Property 'onAudioChunk' does not exist on type 'never'."
}
]
},
{
"plugin": "published-2.0.0",
"compiler": "5.9.3",
"mode": "bundler-esm",
"diagnostics": []
},
{
"plugin": "published-2.0.0",
"compiler": "4.3.5",
"mode": "node10-commonjs",
"diagnostics": []
},
{
"plugin": "published-2.1.0",
"compiler": "5.9.3",
"mode": "node10-commonjs",
"diagnostics": []
},
{
"plugin": "published-2.1.0",
"compiler": "5.9.3",
"mode": "nodenext-cjs",
"diagnostics": []
},
{
"plugin": "published-2.1.0",
"compiler": "5.9.3",
"mode": "nodenext-esm",
"diagnostics": [
{
"file": "consumer.mts",
"line": 26,
"code": 2322,
"message": "Type '{ length: number; interval: number; sampleRate: number; autoHideTimeout: number; onAudioChunk(chunk: any): void; }' is not assignable to type 'never'."
},
{
"file": "consumer.mts",
"line": 26,
"code": 2344,
"message": "Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' does not satisfy the constraint '(...args: any) => any'.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' provides no match for the signature '(...args: any): any'."
},
{
"file": "consumer.mts",
"line": 31,
"code": 7006,
"message": "Parameter 'chunk' implicitly has an 'any' type."
},
{
"file": "consumer.mts",
"line": 37,
"code": 2322,
"message": "Type 'undefined' is not assignable to type 'never'."
},
{
"file": "consumer.mts",
"line": 37,
"code": 2344,
"message": "Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' does not satisfy the constraint '(...args: any) => any'.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' provides no match for the signature '(...args: any): any'."
},
{
"file": "consumer.mts",
"line": 39,
"code": 2344,
"message": "Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' does not satisfy the constraint '(...args: any) => any'.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' provides no match for the signature '(...args: any): any'."
},
{
"file": "consumer.mts",
"line": 46,
"code": 2322,
"message": "Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' is not assignable to type 'PublishedFactory'.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' provides no match for the signature '(option?: PublishedOption | undefined): (art: Artplayer) => PublishedResult'."
},
{
"file": "consumer.mts",
"line": 47,
"code": 2322,
"message": "Type 'PublishedFactory' is not assignable to type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")'."
},
{
"file": "consumer.mts",
"line": 48,
"code": 2322,
"message": "Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' is not assignable to type 'PublishedFactory'.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' provides no match for the signature '(option?: PublishedOption | undefined): (art: Artplayer) => PublishedResult'."
},
{
"file": "consumer.mts",
"line": 49,
"code": 2349,
"message": "This expression is not callable.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' has no call signatures."
},
{
"file": "consumer.mts",
"line": 49,
"code": 2349,
"message": "This expression is not callable.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' has no call signatures."
},
{
"file": "consumer.mts",
"line": 49,
"code": 2349,
"message": "This expression is not callable.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' has no call signatures."
},
{
"file": "consumer.mts",
"line": 49,
"code": 2349,
"message": "This expression is not callable.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' has no call signatures."
},
{
"file": "consumer.mts",
"line": 50,
"code": 2349,
"message": "This expression is not callable.\n Type 'typeof import(\"<consumer>/node_modules/artplayer-plugin-asr/types/artplayer-plugin-asr\")' has no call signatures."
},
{
"file": "consumer.mts",
"line": 54,
"code": 2339,
"message": "Property 'onAudioChunk' does not exist on type 'never'."
}
]
},
{
"plugin": "published-2.1.0",
"compiler": "5.9.3",
"mode": "bundler-esm",
"diagnostics": []
},
{
"plugin": "published-2.1.0",
"compiler": "4.3.5",
"mode": "node10-commonjs",
"diagnostics": []
}
],
"fixtures": {
"refactor/fixtures/consumers/asr-published.ts": "7611ab9ef9765fe6a6ca5112589228d49012400bf0b9d9cede96ead8e63cffc2",
"refactor/fixtures/consumers/asr-esm-namespace.ts": "1e3b7475452f43f71e4e038c17368860fe2bc00a61451397fe609e9a3e078d98"
}
}
@@ -0,0 +1,363 @@
{
"schemaVersion": 1,
"task": "PKG-ASR-04",
"capturedAt": "2026-09-13T07:06:14.836Z",
"baseCommit": "0cf2af48400908fbe4217259e7d9fd37c1e15d1f",
"runtimeChanged": false,
"dependenciesAdded": [],
"versionChanged": false,
"installation": {
"node": "v24.21.0",
"yarn": "1.22.22",
"outsideWorkspace": true,
"offline": true,
"frozenReinstall": true,
"installedHashesVerified": true,
"workspaceLinks": false,
"runtimeExportsExecuted": true,
"packages": [
{
"name": "artplayer",
"archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\asr-package-types-nlZPaL\\artplayer.tgz",
"sha256": "0c0ea52d41575261b836aefac68280733b119c75834ecad6d4bc78edb073f4c1",
"files": {
"package/ARCHITECTURE.md": "bee98fc9d93a3911d58e98ef15f2dbe07e12f2274c444d989094248a22079e46",
"package/README.md": "1e185e65f67fc2081b4182bbc6c4558ea05b6e3fa3acc5dd0c3ac7df1d542b09",
"package/THIRD_PARTY_NOTICES": "b77b5b46b79fa0cda850b0781f78c3b1112c4ed9672fa291956fe8eff53098e7",
"package/dist/artplayer.js": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335",
"package/dist/artplayer.legacy.js": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04",
"package/dist/artplayer.mjs": "432e2b0ad92009a09743e020bf7c928c8b8f18a52496622b16259ec9ab20059f",
"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/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-asr",
"archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\asr-package-types-nlZPaL\\artplayer-plugin-asr.tgz",
"sha256": "d784829c8fbc06f78d8a7647ef3530cec1cf3f5157a053bfbc58111d772eb543",
"files": {
"package/ARCHITECTURE.md": "a46a1abf28a4c783a4cec2983c4ba276b7e9e33e8446d811cc9c49c1f5231ef8",
"package/README.md": "d8eec6fafd308a3f52c16548a27ea07c2cb247d950b3e155d94f98e010e6b994",
"package/dist/artplayer-plugin-asr.js": "533b60d6348764fa460c2436cc1197b95544051fb4d1ec4d950fec9f88e1c5cb",
"package/dist/artplayer-plugin-asr.legacy.js": "c36ebbea3a4e5f30b2736ffb6a964d45e330b0911f51e32d9cab44397ec16912",
"package/dist/artplayer-plugin-asr.mjs": "751201241a848cdc26235334ce7603b174a90bf4ac793ff3f85182b1783f6996",
"package/package.json": "781b1eebefdff5fdc234b793ff9d6d8263275115ccff4c4d90c55eca942f2444",
"package/types/artplayer-plugin-asr.d.ts": "8fce55a45c368dc95fc6169750d2157ad57f683f62b586b8162ac720e1efdf42",
"package/types/runtime.d.cts": "2965dccc49a3a75c3b16c0c13501077b8ac199e78bac2d19d57be3d811583606",
"package/types/runtime.d.mts": "ff0769d3e408d66c7d38574171ff2621456afccc50ee8191ca4ee394dc57666e",
"package/types/runtime.d.ts": "2965dccc49a3a75c3b16c0c13501077b8ac199e78bac2d19d57be3d811583606"
}
}
],
"published": [
{
"label": "published-2.0.0",
"archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\releases\\artplayer-plugin-asr-2.0.0.tgz",
"sha256": "faa726b9536306664d935c95367230e0c622bd046faf636fc2dcef4bbce4cd47"
},
{
"label": "published-2.1.0",
"archive": "D:\\github\\ArtPlayer\\refactor\\.cache\\releases\\artplayer-plugin-asr-2.1.0.tgz",
"sha256": "8bc3cd93f78ce99e5c09cc546c770a63e8aea5729d3d584134ce04d826b7708b"
}
]
},
"strict": {
"skipLibCheck": false,
"ambientTypes": [],
"sourceProjects": [
"tsconfig.json",
"packages/artplayer-plugin-asr/tsconfig.json"
],
"installedResolution": "Only isolated consumer and executing compiler standard libraries",
"compilerVersions": [
"5.9.3",
"4.3.5"
]
},
"matrix": [
{
"plugin": "published-2.0.0",
"compiler": "5.9.3",
"mode": "node10-commonjs",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 0,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "published-2.0.0",
"compiler": "5.9.3",
"mode": "nodenext-cjs",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 0,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "published-2.0.0",
"compiler": "5.9.3",
"mode": "nodenext-esm",
"validConsumerDiagnostics": 15,
"invalidStatementsRejected": 0,
"originalDirectDiagnostics": 15,
"namespaceChecked": true,
"namespaceDiagnostics": 0
},
{
"plugin": "published-2.0.0",
"compiler": "5.9.3",
"mode": "bundler-esm",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 0,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "published-2.0.0",
"compiler": "4.3.5",
"mode": "node10-commonjs",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 0,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "published-2.1.0",
"compiler": "5.9.3",
"mode": "node10-commonjs",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 0,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "published-2.1.0",
"compiler": "5.9.3",
"mode": "nodenext-cjs",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 0,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "published-2.1.0",
"compiler": "5.9.3",
"mode": "nodenext-esm",
"validConsumerDiagnostics": 15,
"invalidStatementsRejected": 0,
"originalDirectDiagnostics": 15,
"namespaceChecked": true,
"namespaceDiagnostics": 0
},
{
"plugin": "published-2.1.0",
"compiler": "5.9.3",
"mode": "bundler-esm",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 0,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "published-2.1.0",
"compiler": "4.3.5",
"mode": "node10-commonjs",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 0,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "candidate",
"compiler": "5.9.3",
"mode": "node10-commonjs",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 12,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "candidate",
"compiler": "5.9.3",
"mode": "nodenext-cjs",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 12,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "candidate",
"compiler": "5.9.3",
"mode": "nodenext-esm",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 12,
"originalDirectDiagnostics": 15,
"namespaceChecked": true,
"namespaceDiagnostics": 0
},
{
"plugin": "candidate",
"compiler": "5.9.3",
"mode": "bundler-esm",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 12,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "candidate",
"compiler": "4.3.5",
"mode": "node10-commonjs",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 12,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "candidate",
"compiler": "5.9.3",
"mode": "node10-commonjs-no-interop",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 12,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
},
{
"plugin": "candidate",
"compiler": "4.3.5",
"mode": "node10-commonjs-no-interop",
"validConsumerDiagnostics": 0,
"invalidStatementsRejected": 12,
"originalDirectDiagnostics": 0,
"namespaceChecked": false,
"namespaceDiagnostics": 0
}
],
"historicalLimits": "Both old releases have 15 NodeNext ESM direct-call diagnostics. These are frozen in asr-type-diagnostics.json and remain on candidate root; legal namespace consumers pass all three packages. Runtime ESM default import is accurate through the additive /runtime entry.",
"correctedDuringReview": [
"Added missing runtime named type exports to CommonJS/Node10 declarations",
"Retained original root namespace declarations after detecting replacement-object incompatibility",
"Excluded implementation tsconfig from actual package",
"Used a compiler-portable invalid buffer example; old TS typed-array structural acceptance is not claimed as rejection"
],
"inputs": {
"packages/artplayer-plugin-asr/.npmignore": "145c5fa0341195e21cf13df3423a057282f8ea374e9a1b3065e2280e1ce1c5c1",
"packages/artplayer-plugin-asr/package.json": "781b1eebefdff5fdc234b793ff9d6d8263275115ccff4c4d90c55eca942f2444",
"packages/artplayer-plugin-asr/tsconfig.json": "583e4ac1afa99e3a29c7f899df9fdeefcbd14d3847d69143e3fa6a8facac6d99",
"packages/artplayer-plugin-asr/types/artplayer-plugin-asr.d.ts": "dca6dfb5a6b6d58a891412c29d857214c95834e60bdabf0aa9d2fec48f31ec12",
"packages/artplayer-plugin-asr/types/runtime.d.ts": "2965dccc49a3a75c3b16c0c13501077b8ac199e78bac2d19d57be3d811583606",
"packages/artplayer-plugin-asr/types/runtime.d.cts": "2965dccc49a3a75c3b16c0c13501077b8ac199e78bac2d19d57be3d811583606",
"packages/artplayer-plugin-asr/types/runtime.d.mts": "ff0769d3e408d66c7d38574171ff2621456afccc50ee8191ca4ee394dc57666e",
"refactor/scripts/asr-package-types.mjs": "00de7c03cba39bed912933d58d686fb0b4aea374944c460ee70a7e404119d259",
"refactor/fixtures/consumers/asr-published.ts": "7611ab9ef9765fe6a6ca5112589228d49012400bf0b9d9cede96ead8e63cffc2",
"refactor/fixtures/consumers/asr-esm-namespace.ts": "1e3b7475452f43f71e4e038c17368860fe2bc00a61451397fe609e9a3e078d98",
"test/types/asr-public.ts": "19eac65cf88ccf908f175dc03243f6933b62dfa3d254525501c2396a571c8843",
"test/types/asr-source.ts": "f2541df4f4e7976a97fa9f31c730298e98fea4749eef2a2e098da539fbc240ca",
"scripts/typecheck.mjs": "96b166178bada2ab2130af1ea422e01965cc6467746ecf605e87ec3b29068309",
"package.json": "a95566e7e6825cda949428a71d11cbcc39c1ba3651fc631ed8511ca5e078d340"
},
"evidence": [
{
"file": "refactor/.cache/asr-package-types-nlZPaL/report.json",
"sha256": "5b32bda6481f74a9db7fe68f54f36a9752deb2cbb8e56b2a42cdc061297b8df7"
},
{
"file": "refactor/.cache/asr04-installed-final.log",
"sha256": "cebbdebc4b5419f16e419a33e0ba5ae33102091c3dcfd2fb95d541f0e2640634"
},
{
"file": "refactor/.cache/asr04-strict-final.log",
"sha256": "0d6e90ea1b4dadf17e3dd5dee44c3894e17455e124d2a7ab31d5850249ec72b7"
},
{
"file": "refactor/.cache/asr04-lint-final.log",
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"file": "refactor/.cache/asr04-artifact-identity.log",
"sha256": "0ad9dc4536c26e81edf671c68cc218aef044e3655bc1ba91afbcf42187783215"
}
],
"unchangedRuntimeEvidence": "refactor/baselines/asr-ownership-validation.json",
"limitation": [
"No full CI or browser rerun for unchanged JS",
"Node 24 actual installs only; full Node/OS distribution matrix remains later acceptance",
"ASR-05 native fallback/volume/CORS/device evidence remains incomplete",
"ASR-06 release documentation and distribution remains incomplete"
],
"releaseReady": false
}
@@ -0,0 +1,53 @@
# PKG-ASR-04:ASR 公共类型与隔离安装
本任务延续 ASR-03 的 8 个严格 TS 模块,处理公共类型与安装边界。保留根入口及
`/legacy` 的历史工厂形状,新增 `/runtime` 精确描述回调返回字幕、异步 stop。
不改运行时 JS、不新增依赖、不修改版本;大版本与发布仍按后续任务统一执行。
## 兼容决策
- 根入口仍是原来的可选参数、同步注册、void stop、void/Promise<void> callback;
旧工厂和插件结果可双向赋值,Parameters/ReturnType 提取也保留。
- `/runtime` 加载同一 main/ESM 产物,只提供准确的类型入口:回调可同步或异步返回
string/null/void,stop 返回 Promise<void>,工厂具有只读 self.default。
不将 self.default 加到旧工厂类型,避免要求用户的替换函数提供额外属性。
- root 与 runtime 都导出 AudioChunk/RuntimeOption/RuntimeResult/RuntimeFactory。
runtime 的 ESM 使用 `.d.mts`,CommonJS/Node10 使用 export assignment。
子代理发现后者漏了命名类型,已补纯类型 namespace 并加入四类型等价回归。
- 旧根声明在 NodeNext ESM 下把 default import 描述成命名空间,合法的
`asr.default()`、`namespace.default.default()` 和 `{default: factory}` 替换必须保留。
原拟直接工厂 `.d.mts` 会破坏这些旧类型用法,已撤回;准确 ESM 默认导入用 `/runtime`。
这是声明兼容测试,不能推断旧 JS 支持所有双层 default 调用。
包内 README 给出新入口用法,ARCHITECTURE 记录维护限制。实际打包发现 tsconfig
泄漏,已补 `.npmignore`,保留所有历史 dist/types 文件。源码 TS 与测试不进入包。
## 验证与证据
`yarn test:asr-types-package` 实际打包核心与 ASR,在工作区外逐个安装 frozen
2.0.0、2.1.0 及候选包。离线安装后用 frozen lockfile 再安装;检查锁文件不变、
无工作区符号链接、全部包文件与 archive 哈希相符。类型程序只能读取该临时消费者
及当前编译器标准库;strict、skipLibCheck:false、types:[],不靠 ambient 类型兜底。
- 2 个旧发布包各 5 种配置;每包 4 种直接用法通过,NodeNext ESM 原有 15 条诊断
按完整消息冻结。合法 ESM 命名空间 fixture 在两个旧包及候选包均通过。
- 候选 7 种配置:TS 5.9.3 Node10/NodeNext CJS/NodeNext ESM/Bundler,TS 4.3.5
Node10,以及两编译器 Node10 关闭 interop。每种公共用法零诊断,12 项负例在
各自语句行被拒绝;原 direct fixture 的 NodeNext ESM 诊断也与旧包一致。
- 实际 Node 24.21.0 import/require 验证三候选入口、root/runtime 实现身份、
self.default 不可枚举、legacy 默认导入身份;旧包验证各自 CJS 和 ESM 导出。
- 根项目及 ASR 分包严格检查通过,source/public 类型边界加入持续检查。
定向 ESLint 和台账测试通过,ASR 构建 JS 与 ASR-03 HEAD 逐字节相同。
类型反例中的 typed-array 与 ArrayBuffer 在旧 TS 标准库下结构可赋值,不能声称
TS 4.3.5 会拒绝。负例使用所有目标编译器都应拒绝的字符串 buffer,保持公开
ArrayBuffer 字段不变;没有通过缩窄字段或升级最低编译器绕过兼容性。
具体 archive、输入、日志哈希及矩阵摘要见
[验证记录](../baselines/asr-types-validation.json),旧 direct 诊断见
[冻结声明诊断](../baselines/asr-type-diagnostics.json)。此前 ASR-03 的音频/浏览器
证据继续对应未变的 JS;本任务没有重复整仓 CI 或浏览器回归,也不声称完成真实
fallback、音量/静音、CORS、物理设备或全 Node 版本验收。这些仍归 ASR-05/06。
子代理独立提供公共/历史消费者与声明审查,主代理修复声明、运行实际隔离安装、
整合证据和提交。回退本任务移除新增类型入口与测试,不改变 ASR-03 运行时修复。
@@ -0,0 +1,46 @@
import type Artplayer from 'artplayer'
import asr from 'artplayer-plugin-asr'
import * as namespace from 'artplayer-plugin-asr'
// Compile this fixture as .mts with NodeNext: published declarations expose
// a CommonJS declaration namespace even though the runtime import is ESM.
interface HistoricalOption {
length?: number
interval?: number
sampleRate?: number
autoHideTimeout?: number
onAudioChunk?: (chunk: { pcm: ArrayBuffer, wav: ArrayBuffer }) => void | Promise<void>
}
interface HistoricalResult {
name: 'artplayerPluginAsr'
stop: () => void
hide: () => void
append: (subtitle: string) => void
}
type HistoricalFactory = (option?: HistoricalOption) => (art: Artplayer) => HistoricalResult
interface HistoricalModule { default: HistoricalFactory }
const result: ReturnType<ReturnType<typeof asr.default>> = {
name: 'artplayerPluginAsr',
stop() {},
hide() {},
append(_subtitle: string) {},
}
const replacementFactory: HistoricalFactory = (_option?: HistoricalOption) => (_art: Artplayer) => result
const replacementModule: typeof asr = { default: replacementFactory }
const assignToOld: HistoricalModule = asr
const assignFromOld: typeof asr = assignToOld
const namespaceModule: typeof namespace.default = replacementModule
const factoryToOld: HistoricalFactory = asr.default
const factoryFromOld: typeof asr.default = replacementFactory
const option: Parameters<typeof asr.default>[0] = {
onAudioChunk: async (_chunk): Promise<void> => {},
}
const absent: Parameters<typeof namespace.default.default>[0] = undefined
declare const art: Artplayer
const installed: HistoricalResult = asr.default(option)(art)
const namespaceResult: HistoricalResult = namespace.default.default(absent)(art)
const stop: void = installed.stop()
const append: void = namespaceResult.append('Old namespace import.')
void [assignFromOld, namespaceModule, factoryToOld, factoryFromOld, stop, append]
@@ -0,0 +1,55 @@
import Artplayer from 'artplayer'
import asr from 'artplayer-plugin-asr'
import * as namespace from 'artplayer-plugin-asr'
interface PublishedChunk {
pcm: ArrayBuffer
wav: ArrayBuffer
}
interface PublishedOption {
length?: number
interval?: number
sampleRate?: number
autoHideTimeout?: number
onAudioChunk?: (chunk: PublishedChunk) => void | Promise<void>
}
interface PublishedResult {
name: 'artplayerPluginAsr'
stop: () => void
hide: () => void
append: (subtitle: string) => void
}
type PublishedFactory = (option?: PublishedOption) => (art: Artplayer) => PublishedResult
const option: Parameters<typeof asr>[0] = {
length: 3,
interval: 100,
sampleRate: 16000,
autoHideTimeout: 10000,
onAudioChunk(chunk) {
const pcm: ArrayBuffer = chunk.pcm
const wav: ArrayBuffer = chunk.wav
void [pcm, wav]
},
}
const empty: Parameters<typeof asr>[0] = undefined
const asyncOption: PublishedOption = { onAudioChunk: async (_chunk: PublishedChunk): Promise<void> => {} }
const result: ReturnType<ReturnType<typeof asr>> = {
name: 'artplayerPluginAsr',
stop() {},
hide() {},
append(_subtitle: string) {},
}
const replacement: PublishedFactory = (_option?: PublishedOption) => (_art: Artplayer) => result
const assignToOld: PublishedFactory = asr
const assignFromOld: typeof asr = replacement
const namespaceFactory: PublishedFactory = namespace.default
const art = new Artplayer({ container: '#player', url: '/video.mp4', plugins: [asr(option), asr(asyncOption), asr(), namespace.default(empty)] })
const installed: PublishedResult = asr(option)(art)
const stop: void = installed.stop()
const hide: void = installed.hide()
const append: void = installed.append('Historical subtitle.')
const callback: ((chunk: PublishedChunk) => void | Promise<void>) | undefined = option.onAudioChunk
void [assignToOld, assignFromOld, namespaceFactory, stop, hide, append, callback]
+3 -2
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 225 项,范围 22 个包及工作区/示例。
状态:todo 83 / doing 16 / blocked 0 / done 126 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 82 / doing 16 / blocked 0 / done 127 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -254,7 +254,7 @@
| PKG-ASR-01 | artplayer-plugin-asr<br>核对包契约与历史用法 | BASE-05 | length/interval/sampleRate/onAudioChunk、append/hide/stop 的真实能力 | 源码/声明/README/demo/发布包差异已登记;公开形状和版本范围冻结 | H | done |
| PKG-ASR-02 | artplayer-plugin-asr<br>建立特有行为与错误测试 | PKG-ASR-01, ENG-03, ENG-05 | PCM/WAV、chunk 时序、回调慢/拒绝、重复初始化与停止 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | done |
| PKG-ASR-03 | artplayer-plugin-asr<br>整理内部职责与资源 | PKG-ASR-02, CORE-10, CORE-18 | AudioContext/Worklet/Stream 生命周期和背压分离 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | done |
| PKG-ASR-04 | artplayer-plugin-asr<br>迁移自有源码和公开类型 | PKG-ASR-03, ENG-04, ENG-06, CORE-07 | 主线程/Worklet/音频 buffer 与异步回调类型 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | todo |
| PKG-ASR-04 | artplayer-plugin-asr<br>迁移自有源码和公开类型 | PKG-ASR-03, ENG-04, ENG-06, CORE-07 | 主线程/Worklet/音频 buffer 与异步回调类型 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | done |
| PKG-ASR-05 | artplayer-plugin-asr<br>验证新旧核心和组合 | PKG-ASR-04, CORE-22 | 真实 WebAudio 分块、播放暂停/切源/销毁,不引入网络 ASR | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
| PKG-ASR-06 | artplayer-plugin-asr<br>验证分发并同步文档 | PKG-ASR-05, ENG-07 | asr.js、Worklet 资源、输出格式与声明证据 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
@@ -529,6 +529,7 @@
- PKG-ASR-01: [记录](changes/2026-09-13-PKG-ASR-01-contracts.md) [记录](baselines/asr-contract.md) [记录](baselines/asr-release.json)
- PKG-ASR-02: [记录](changes/2026-09-13-PKG-ASR-02-audio-baseline.md) [记录](baselines/asr-audio-validation.json)
- PKG-ASR-03: [记录](changes/2026-09-13-PKG-ASR-03-audio-ownership.md) [记录](baselines/asr-ownership-validation.json)
- PKG-ASR-04: [记录](changes/2026-09-13-PKG-ASR-04-public-types.md) [记录](baselines/asr-types-validation.json) [记录](baselines/asr-type-diagnostics.json)
- PKG-ADS-01: [记录](baselines/ads-release.json) [记录](baselines/ads-contract.md) [记录](baselines/ads-contract-validation.json) [记录](changes/2026-09-12-PKG-ADS-01-contract.md) [记录](scripts/ads-contract.test.mjs)
- PKG-ADS-02: [记录](changes/2026-09-12-PKG-ADS-02-tests.md) [记录](ads-validation.md) [记录](baselines/ads-validation.json)
- PKG-ADS-03: [记录](changes/2026-09-12-PKG-ADS-03-lifecycle.md) [记录](ads-validation.md) [记录](baselines/ads-lifecycle-validation.json)
+14
View File
@@ -1,5 +1,19 @@
# 进度与证据
## PKG-ASR-04 公共类型与安装兼容完成
保留根入口及 legacy 的旧工厂、void stop 和 NodeNext ESM 命名空间形状;新增
runtime 精确类型入口,描述字幕回调与 Promise stop。子代理补消费者并发现
CommonJS 命名类型遗漏、旧 ESM 替换对象兼容风险,均修复后由主代理隔离安装验收。
实际 2.0/2.1/候选共 17 配置:候选 7 配置通过,每种 12 负例按语句拒绝;两旧包
各有 1 组原生 NodeNext direct 声明错误单独冻结,三个包的合法 namespace 用法通过。
根/分包 strict、定向 lint、包字节与 frozen reinstall 检查通过,修复 tsconfig 打包泄漏。
见[变更](changes/2026-09-13-PKG-ASR-04-public-types.md)与[证据](baselines/asr-types-validation.json)。
225 项:127 done、16 doing、82 todo;205 风险,ASR-TYPE-01 闭环。
下一步 ASR-05 原生 fallback/音量/跨源/设备组合与 ASR-06 发行;运行时 JS 未改,
沿用 ASR-03 浏览器证据,本项不等于 ASR 整包发布验收,没有推送或发布。
## PKG-ASR-03 TS 拆分与音频生命周期完成
生产源码拆为 8 个严格 TS 模块;队列保留半块/尾部,识别回调背压、拒绝恢复、
+1 -1
View File
@@ -206,6 +206,6 @@
| JASSUB-EXPORT-01 | open / 已复现 | JASSUB historical CommonJS object.default changes to a direct factory in 1.1.0 | PKG-JASSUB-04, PKG-JASSUB-06 |
| CORE-DEFAULTS-SSR-01 | resolved / 已复现 | Reading static defaults throws when navigator is absent | CORE-25 |
| ENG-DIST-PUBLIC-01 | resolved / 已复现 | Vite copied authored declarations into library distribution | ENG-12 |
| ASR-TYPE-01 | open / 源码/产物事实 | ASR declarations omit asynchronous stop and callback text results | PKG-ASR-04 |
| ASR-TYPE-01 | resolved / 已复现 | ASR declarations omit asynchronous stop and callback text results | PKG-ASR-04 |
| ASR-CHUNK-01 | resolved / 已复现 | ASR tick discards underfilled chunks and overrun samples in source | PKG-ASR-02, PKG-ASR-03 |
| ASR-LIFE-01 | resolved / 已复现 | ASR partial initialization, pause resume and stale callback cleanup need controlled evidence | PKG-ASR-02, PKG-ASR-03, PKG-ASR-05 |
+11 -3
View File
@@ -4545,8 +4545,8 @@
{
"id": "ASR-TYPE-01",
"title": "ASR declarations omit asynchronous stop and callback text results",
"confirmation": "source-observed",
"status": "open",
"confirmation": "reproduced",
"status": "resolved",
"owners": [
"PKG-ASR-04"
],
@@ -4555,7 +4555,15 @@
"refactor/baselines/asr-release.json"
],
"compatibleResolution": "Keep historical assignment compatibility while supplying accurate asynchronous consumption.",
"closureCriteria": "Actual old/new installed TS consumers cover void callback, Promise<void>, returned text and factory substitution."
"closureCriteria": "Actual old/new installed TS consumers cover void callback, Promise<void>, returned text and factory substitution.",
"resolutionEvidence": [
"refactor/changes/2026-09-13-PKG-ASR-04-public-types.md",
"refactor/baselines/asr-types-validation.json",
"refactor/scripts/asr-package-types.mjs",
"test/types/asr-public.ts",
"refactor/fixtures/consumers/asr-esm-namespace.ts"
],
"resolutionRationale": "Root/legacy preserve historical void callback and stop, factory substitution and legal NodeNext namespace shape. Additive runtime supplies text/null/void callbacks and Promise stop with consistent named types. Actual isolated 2.0/2.1/candidate installs, seven candidate compiler configurations and 12 per-mode invalid statements verify declarations. Existing old NodeNext direct-call diagnostics remain explicit, not candidate success."
},
{
"id": "ASR-CHUNK-01",
+166
View File
@@ -0,0 +1,166 @@
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 { verifyAsrContract } from './asr-contract.mjs'
import { hash, readMember } from './releases.mjs'
const publicFixture = fs.readFileSync(path.join(workspace, 'test/types/asr-public.ts'), 'utf8')
const publishedFixture = fs.readFileSync(path.join(workspace, 'refactor/fixtures/consumers/asr-published.ts'), 'utf8')
const standardModes = [[ts, 'node10-commonjs'], [ts, 'nodenext-cjs'], [ts, 'nodenext-esm'], [ts, 'bundler-esm'], [compat, 'node10-commonjs']]
function typecheck(consumer, compiler, mode, candidate) {
const next = mode.startsWith('nodenext')
const extension = next ? mode.endsWith('-cjs') ? 'cts' : 'mts' : 'ts'
const filename = path.join(consumer, `consumer.${extension}`)
const files = [filename]
if (candidate && mode !== 'bundler-esm' && mode !== 'nodenext-esm') {
const commonjs = path.join(consumer, `commonjs.${extension}`)
fs.writeFileSync(commonjs, `import asr = require('artplayer-plugin-asr');
import legacy = require('artplayer-plugin-asr/legacy');
import runtime = require('artplayer-plugin-asr/runtime');
import type Artplayer from 'artplayer';
const replacement: typeof asr.default = () => (_art: Artplayer) => ({name: 'artplayerPluginAsr', stop() {}, hide() {}, append(_text: string) {}});
const legacyReplacement: typeof legacy.default = replacement;
asr.default(); legacy.default(); runtime({onAudioChunk: async () => 'Text.'}); runtime.default();
declare const art: Artplayer;
const stopped: Promise<void> = runtime()(art).stop();
void [legacyReplacement, stopped];`)
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 => ({
file: item.file ? path.relative(consumer, item.file.fileName).replaceAll('\\', '/') : null,
line: item.file && item.start !== undefined ? item.file.getLineAndCharacterOfPosition(item.start).line + 1 : null,
code: item.code,
message: compiler.flattenDiagnosticMessageText(item.messageText, '\n').replaceAll(consumer.replaceAll('\\', '/'), '<consumer>'),
}))
}
let source = candidate
? mode.endsWith('-no-interop') ? publicFixture.replace('import runtime from \'artplayer-plugin-asr/runtime\'', 'import runtime = require(\'artplayer-plugin-asr/runtime\')') : publicFixture
: publishedFixture
if (candidate && mode === 'nodenext-esm') {
source = source
.replace('import legacy from \'artplayer-plugin-asr\'', 'import legacyModule from \'artplayer-plugin-asr\'\nconst legacy = legacyModule.default')
.replace('import legacyEntry from \'artplayer-plugin-asr/legacy\'', 'import legacyEntryModule from \'artplayer-plugin-asr/legacy\'\nconst legacyEntry = legacyEntryModule.default')
.replace('namespace.default', 'namespace.default.default')
}
const diagnostics = compile(source)
const invalid = candidate ? compile(source.replaceAll(/\/\/ @ts-expect-error[^\n]*\n/g, '')) : []
if (candidate) {
const expectedLines = []
let line = 1
for (const text of source.split('\n')) {
if (text.startsWith('// @ts-expect-error'))
expectedLines.push(line)
else line++
}
assert.deepEqual(invalid.map(item => item.line).sort((a, b) => a - b), expectedLines, 'Each invalid statement must fail at its own line')
}
const published = candidate ? compile(publishedFixture) : diagnostics
const namespace = mode === 'nodenext-esm' ? compile(fs.readFileSync(path.join(workspace, 'refactor/fixtures/consumers/asr-esm-namespace.ts'), 'utf8')) : []
return { compiler: compiler.version, mode, diagnostics, invalid, published, namespace }
}
async function main() {
assert.equal(process.env.npm_config_user_agent?.split(' ')[0], 'yarn/1.22.22', 'Use yarn test:asr-types-package')
const yarn = process.env.npm_execpath
assert(yarn && fs.existsSync(yarn))
const output = fs.mkdtempSync(path.join(workspace, 'refactor/.cache/asr-package-types-'))
console.log(`ASR isolated package evidence: ${output}`)
const contract = await verifyAsrContract()
const expected = JSON.parse(fs.readFileSync(path.join(workspace, 'refactor/baselines/asr-type-diagnostics.json'), 'utf8'))
for (const [file, digest] of Object.entries(expected.fixtures))
assert.equal(hash(fs.readFileSync(path.join(workspace, file), 'utf8').replaceAll('\r\n', '\n')), digest, `Frozen ASR fixture changed: ${file}`)
const packages = []
for (const name of ['artplayer', 'artplayer-plugin-asr']) {
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 candidate = plugin.label === 'candidate'
const consumer = consumerDirectory()
try {
writeJson(path.join(consumer, 'package.json'), { name: 'asr-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, candidate
? `const assert = require('node:assert/strict');
for (const name of ['artplayer-plugin-asr', 'artplayer-plugin-asr/legacy', 'artplayer-plugin-asr/runtime']) { const factory = require(name); assert.equal(typeof factory, 'function'); assert.equal(factory.default, factory); assert.equal(Object.getOwnPropertyDescriptor(factory, 'default').enumerable, false); assert.equal(typeof factory({}), 'function'); }
assert.equal(require('artplayer-plugin-asr/runtime'), require('artplayer-plugin-asr'));
Promise.all(['artplayer-plugin-asr', 'artplayer-plugin-asr/runtime', 'artplayer-plugin-asr/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-asr/legacy')); }).catch(error => { console.error(error); process.exitCode = 1; });`
: `const assert = require('node:assert/strict'); const value = require('artplayer-plugin-asr'); assert.equal(typeof value, '${plugin.version === '2.1.0' ? 'function' : 'object'}'); assert.equal(typeof (value.default || value)({}), 'function'); assert.equal(typeof value.default, '${plugin.version === '2.1.0' ? 'undefined' : 'function'}'); import('artplayer-plugin-asr').then(module => { assert.equal(typeof module.default, 'function'); assert.equal(typeof module.default({}), 'function'); }).catch(error => { console.error(error); process.exitCode = 1; });`)
fs.writeFileSync(path.join(output, `${plugin.label}-runtime.log`), run([runtimeFile], consumer))
const modes = candidate ? [...standardModes, [ts, 'node10-commonjs-no-interop'], [compat, 'node10-commonjs-no-interop']] : standardModes
for (const [compiler, mode] of modes) {
const result = { plugin: plugin.label, ...typecheck(consumer, compiler, mode, candidate) }
matrix.push(result)
writeJson(path.join(output, `${plugin.label}-${compiler.version}-${mode}.json`), result)
console.log(`${plugin.label} TS ${compiler.version} ${mode}: ${result.diagnostics.length} diagnostics; ${result.invalid.length} negative diagnostics`)
}
}
finally {
removeConsumer(consumer)
}
}
writeJson(path.join(output, 'report.json'), { suite: 'asr-isolated-package-types', introducedBy: 'PKG-ASR-04', packages, published: candidates.slice(0, -1).map(pkg => ({ label: pkg.label, archive: pkg.archive, sha256: hash(fs.readFileSync(pkg.archive)) })), matrix })
for (const result of matrix) {
const baseline = result.plugin === 'candidate' ? [] : expected.cases.find(item => item.plugin === result.plugin && item.compiler === result.compiler && item.mode === result.mode)?.diagnostics
assert.deepEqual(result.diagnostics, baseline, `${result.plugin} TS ${result.compiler} ${result.mode}`)
assert.deepEqual(result.namespace, [], `Historical ESM namespace: ${result.plugin}`)
if (result.plugin === 'candidate') {
const publishedBaseline = result.mode === 'nodenext-esm' ? expected.cases.find(item => item.plugin === 'published-2.1.0' && item.compiler === result.compiler && item.mode === result.mode).diagnostics : []
assert.deepEqual(result.published, publishedBaseline, `Historical direct consumer: ${result.compiler} ${result.mode}`)
assert.equal(result.invalid.length, 12, 'Installed declarations must reject all 12 invalid uses')
}
}
console.log(`ASR installed matrix verified: ${matrix.length} cases; ${output}`)
}
main().catch((error) => {
console.error(error)
process.exitCode = 1
})
+6 -2
View File
@@ -2682,11 +2682,15 @@
"ENG-06",
"CORE-07"
],
"status": "todo",
"status": "done",
"risk": "H",
"deliverable": "主线程/Worklet/音频 buffer 与异步回调类型",
"acceptance": "严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容",
"evidence": []
"evidence": [
"changes/2026-09-13-PKG-ASR-04-public-types.md",
"baselines/asr-types-validation.json",
"baselines/asr-type-diagnostics.json"
]
},
{
"id": "PKG-ASR-05",