fix(types): [PKG-FACTORY-01] preserve published factory compatibility

This commit is contained in:
Harvey Zhao committed 2026-09-13 16:53:27 +08:00
1 parent 1117107032
commit c4c7491e16
35 files changed
+670 -229

No files matched your search

@@ -3,10 +3,18 @@
Public entry: `src/index.ts`; public declarations remain in
`types/artplayer-proxy-canvas.d.ts`. The factory accepts the optional drawing callback,
then synchronously returns an actual HTMLCanvasElement when registered with ArtPlayer.
The public namespace preserves the optional callback and exact Canvas return extraction.
The root preserves the latest npm 1.1.0 pure factory, optional callback and exact Canvas
return extraction. Do not attach a required default member to this type: that breaks
assigning an ordinary historical replacement function back to typeof factory.
MediaCanvas is an explicit type view, not a narrowed factory result. CommonJS and browser
factory.default are self aliases; .d.mts/.d.cts wrappers distinguish ESM and CommonJS
resolution, and typesVersions keeps the legacy path available to older TypeScript.
factory.default remain runtime self aliases. Accurate RuntimeFactory lives behind the
additive /runtime entry, whose runtime.d.mts/runtime.d.cts bridges distinguish ESM and
CommonJS and whose runtime.d.ts supports old Node10 export= resolution. Both entrypoints
load the same existing dist files. The old root declaration bridges remain packaged,
but root/legacy conditional types deliberately select the original .d.ts module shape.
Root NodeNext ESM therefore keeps the published namespace shape; it is not silently made
callable. Use /runtime for precise ESM default calls. The package README documents the
approved 1.0 export= migration; no JavaScript calls were removed by this type decision.
Historical JavaScript falsy callback arguments remain ignored at runtime; the typed public
callback remains optional and function-valued.
@@ -72,8 +80,13 @@ geometry and is separate from native media pixel acceptance. npm core 5.1.7 has
option and is only a native-player capability control.
`yarn test:canvas-types-package` installs real archived and candidate packages outside the
workspace, verifies installed bytes and checks old/current compiler modes. The public
namespace also generates the local editor declaration through the semantic generator.
workspace, verifies installed bytes and checks old/current compiler modes. It preserves
the actual old NodeNext direct-import errors and 1.0 export= differences, while testing
latest namespace replacements, plain factory bidirectional assignments, runtime self
identity and negative statements at their exact lines. No skipLibCheck or strictness
relaxation is used. The public declarations also generate the local editor declaration
through the semantic generator; the editor root stays plain, with an explicit
artplayerProxyCanvas.RuntimeFactory assertion for code needing the runtime self alias.
Broader installed artifact contents/deep paths and 8082 demos remain 06.
Real Safari/mobile/device scope remains 05; Windows Playwright WebKit is not a device claim.
See `refactor/canvas-validation.md` and the task evidence for actual outcomes and limitations.
+30 -4
View File
@@ -29,14 +29,19 @@ historical `require('artplayer-proxy-canvas').default` refer to the same factory
## TypeScript
The optional callback and exact `HTMLCanvasElement` return type retain published 1.1.0
inference. `Option`, `Result`, `Factory` and `MediaCanvas` are exported types. The last is
an explicit view for code using supported forwarded media members:
The root and `/legacy` declarations preserve the latest published 1.1.0 factory:
an optional callback, an exact `HTMLCanvasElement` result, and no required factory
properties. Ordinary replacement functions remain assignable in both directions.
`Factory` describes that historical shape. The additive `/runtime` entry uses the same
JavaScript implementation and describes its readonly `default` self alias with
`RuntimeFactory`. It also exports an explicit `MediaCanvas` view:
```ts
import type { MediaCanvas, Option } from 'artplayer-proxy-canvas'
import type { MediaCanvas, Option } from 'artplayer-proxy-canvas/runtime'
import canvas from 'artplayer-proxy-canvas/runtime'
const callback: Option = (context, video) => context.drawImage(video, 0, 0)
canvas.default(callback)
const media = art.template.$video as MediaCanvas
await media.play()
```
@@ -48,6 +53,27 @@ Runtime falsy callback arguments retain historical behavior; declarations accept
optional function, matching the published types. Implementation and test guidance is in
[ARCHITECTURE.md](ARCHITECTURE.md).
### Older TypeScript consumers
The 1.0.0 declaration used `export =` and required a callback; 1.1.0 changed to
`export default` and made the callback optional. These conflicting type shapes cannot
both remain the root factory. Following the approved compatibility policy, the root
keeps 1.1.0. A 1.0.0 TypeScript `import canvas = require('artplayer-proxy-canvas')`
consumer that directly calls `canvas(...)` can select the accurate entry instead:
```ts
import canvas = require('artplayer-proxy-canvas/runtime')
canvas((context, video) => context.drawImage(video, 0, 0))
canvas.default()
```
This works with Node10 resolution even without `esModuleInterop`. Default imports from
`/runtime` work with interoperability enabled and with native NodeNext ESM. Under
NodeNext ESM, the root intentionally preserves 1.1.0's historical declaration namespace
shape (`root.default(...)` after a default import); that declaration shape does not
describe the actual ESM factory. Use a default import from `/runtime` for accurate ESM
typing. Existing JavaScript root/legacy calls and distribution paths keep working.
## Demo
[https://artplayer.org](https://artplayer.org/?libs=./uncompiled/artplayer-proxy-canvas/index.js&example=canvas)
+15 -12
View File
@@ -19,24 +19,24 @@
],
"exports": {
".": {
"types": "./types/artplayer-proxy-canvas.d.ts",
"import": "./dist/artplayer-proxy-canvas.mjs",
"require": "./dist/artplayer-proxy-canvas.js"
},
"./legacy": {
"types": "./types/artplayer-proxy-canvas.d.ts",
"import": "./dist/artplayer-proxy-canvas.legacy.js",
"require": "./dist/artplayer-proxy-canvas.legacy.js"
},
"./runtime": {
"import": {
"types": "./types/artplayer-proxy-canvas.d.mts",
"types": "./types/runtime.d.mts",
"default": "./dist/artplayer-proxy-canvas.mjs"
},
"require": {
"types": "./types/artplayer-proxy-canvas.d.cts",
"types": "./types/runtime.d.cts",
"default": "./dist/artplayer-proxy-canvas.js"
}
},
"./legacy": {
"import": {
"types": "./types/artplayer-proxy-canvas.d.cts",
"default": "./dist/artplayer-proxy-canvas.legacy.js"
},
"require": {
"types": "./types/artplayer-proxy-canvas.d.cts",
"default": "./dist/artplayer-proxy-canvas.legacy.js"
}
}
},
"main": "./dist/artplayer-proxy-canvas.js",
@@ -48,6 +48,9 @@
"*": {
"legacy": [
"types/artplayer-proxy-canvas.d.ts"
],
"runtime": [
"types/runtime.d.ts"
]
}
}
@@ -1,4 +1,2 @@
// eslint-disable-next-line ts/no-require-imports -- Preserve the CommonJS export-assignment namespace.
import artplayerProxyCanvas = require('./artplayer-proxy-canvas.js')
export = artplayerProxyCanvas
export { default } from './artplayer-proxy-canvas.js'
export type { Callable, Factory, MediaCanvas, Option, Result, RuntimeFactory } from './artplayer-proxy-canvas.js'
@@ -1,2 +1,5 @@
export { default } from './artplayer-proxy-canvas.js'
export type { Callable, Factory, MediaCanvas, Option, Result } from './artplayer-proxy-canvas.js'
import type { Factory } from './artplayer-proxy-canvas.js'
declare const artplayerProxyCanvas: Factory
export default artplayerProxyCanvas
export type { Callable, Factory, MediaCanvas, Option, Result, RuntimeFactory } from './artplayer-proxy-canvas.js'
@@ -1,27 +1,22 @@
/* eslint-disable ts/no-redeclare -- Callable and public type namespace intentionally merge. */
import type Artplayer from 'artplayer'
declare namespace artplayerProxyCanvas {
/** Runs after drawing and bitmap release, before the draw event. */
type Option = (ctx: CanvasRenderingContext2D, video: HTMLVideoElement) => void
/** Runs after drawing and bitmap release, before the draw event. */
export type Option = (ctx: CanvasRenderingContext2D, video: HTMLVideoElement) => void
/** Preserve the exact published return type and its assignability. */
type Result = HTMLCanvasElement
/** Preserve the exact published 1.1.0 return type and its assignability. */
export type Result = HTMLCanvasElement
/** Opt-in view of supported enumerable media members; native Canvas members win. */
type MediaCanvas = HTMLCanvasElement & Pick<HTMLVideoElement, Exclude<keyof HTMLVideoElement, keyof HTMLCanvasElement>>
export type Factory = (option?: Option) => (art: Artplayer) => Result
export type Callable = Factory
interface Callable {
/** Keep Parameters extraction optional, as published in 1.1.0. */
(option?: Option): (art: Artplayer) => Result
}
/** Explicit view of forwarded media members; native Canvas members win. */
export type MediaCanvas = HTMLCanvasElement & Pick<HTMLVideoElement, Exclude<keyof HTMLVideoElement, keyof HTMLCanvasElement>>
interface Factory extends Callable {
/** Same factory, for historical require(package).default calls. */
readonly default: Factory
}
/** Opt-in runtime identity; the historical root factory has no required properties. */
export interface RuntimeFactory extends Factory {
readonly default: RuntimeFactory
}
declare const artplayerProxyCanvas: artplayerProxyCanvas.Factory
export = artplayerProxyCanvas
export as namespace artplayerProxyCanvas
declare const artplayerProxyCanvas: (option?: Option) => (art: Artplayer) => Result
export default artplayerProxyCanvas
@@ -0,0 +1,12 @@
import type { RuntimeFactory } from './artplayer-proxy-canvas.js'
declare const artplayerProxyCanvas: RuntimeFactory
// eslint-disable-next-line ts/no-redeclare -- Ambient merge exposes types on the CommonJS factory.
declare namespace artplayerProxyCanvas {
type Option = import('./artplayer-proxy-canvas.js').Option
type Result = import('./artplayer-proxy-canvas.js').Result
type Factory = import('./artplayer-proxy-canvas.js').Factory
type MediaCanvas = import('./artplayer-proxy-canvas.js').MediaCanvas
type RuntimeFactory = import('./artplayer-proxy-canvas.js').RuntimeFactory
}
export = artplayerProxyCanvas
@@ -0,0 +1,5 @@
import type { RuntimeFactory } from './artplayer-proxy-canvas.js'
declare const artplayerProxyCanvas: RuntimeFactory
export default artplayerProxyCanvas
export type { Factory, MediaCanvas, Option, Result, RuntimeFactory } from './artplayer-proxy-canvas.js'
+12
View File
@@ -0,0 +1,12 @@
import type { RuntimeFactory } from './artplayer-proxy-canvas.js'
declare const artplayerProxyCanvas: RuntimeFactory
// eslint-disable-next-line ts/no-redeclare -- Ambient merge exposes types on the CommonJS factory.
declare namespace artplayerProxyCanvas {
type Option = import('./artplayer-proxy-canvas.js').Option
type Result = import('./artplayer-proxy-canvas.js').Result
type Factory = import('./artplayer-proxy-canvas.js').Factory
type MediaCanvas = import('./artplayer-proxy-canvas.js').MediaCanvas
type RuntimeFactory = import('./artplayer-proxy-canvas.js').RuntimeFactory
}
export = artplayerProxyCanvas