# MediaBunny proxy maintenance The public entry is `src/index.js`: an optional-options factory returns the existing ArtPlayer proxy callback and an HTMLCanvasElement. Public declarations remain in `types/artplayer-proxy-mediabunny.d.ts`. The input migration does not change those declarations, the factory signature, canvas forwarding, or package entrypoints. ## Current module map | Module | Responsibility | | --- | --- | | `input.ts` | String/Blob/ReadableStream normalization, SDK Source/SourceRef pass-through, HLS detection and Input construction | | `media.ts` | Internal SDK-backed media and track-mode types; not public consumer types | | `tracks.ts` | Primary video and pairable audio selection, metadata/computed/live duration | | `hls-state.ts` | HLS track snapshots, bitrate/name/language values and actual selected track identity | | `preflight.ts` | Optional HEAD Range check, historical warning/error policy, cancellation and stale-result guard | | `load-session.ts` | Ownership of the pending/active SDK Input, HEAD AbortController, deferred load events and deadline | | `MediaBunnyEngine.js` | Current coordinator; connects session cancellation to load, source replacement, errors and destroy | | `VideoEngine.js` / `AudioEngine.js` | Current native decoding, rendering, seeking, Web Audio clock and scheduling | | `VideoShim.js` / `EventTarget.js` | Current video-like descriptors and event forwarding | | `m3u8.js` | Current ArtPlayer control/setting integration | The six TypeScript modules use strict checking with `skipLibCheck: false` and no ambient Node types. Remaining JavaScript is explicitly scheduled in PKG-MB-04/05/06/07/08. Do not describe the whole package as migrated yet. ## Input and cancellation flow Each `engine.load` invalidates the previous generation and cancels its session. The new session owns an Input immediately after construction, before asynchronous track selection. `engine.input` and `engine.media` become visible only after selection. The session continues to own the Input during playback; these fields are aliases, not separate disposal owners. Repeated cancellation/disposal is harmless. Source replacement, timeout and destroy release that Input through SDK `Input.dispose()`. MediaBunny controls its media fetch cancellation; do not pass a signal in UrlSource's `requestInit` (the SDK explicitly excludes it). The separate HEAD check uses its own AbortController. Without that constructor, stale HEAD results/errors are still ignored, although the network request cannot be physically aborted by this adapter. Cancellation settles the old load Promise without waiting for a stalled read. Its late fulfillment/rejection remains observed but cannot update the current load. Active errors retain `code: 4` and the SDK message; active timeout retains `Load timeout` and networkState 3. Successful completion clears its deadline. Normal deferred waiting/loadstart ordering remains; cancellation clears both callbacks. Destroy makes future loads inert. Range behavior remains opt-in: no/`none` accept-ranges emits an error with a `RangeNotSupported` detail and returns false, without setting the engine error property. Network failure warns and continues; HLS strings and non-string sources skip HEAD. HLS matching preserves the old case-insensitive `.m3u8` suffix/query/hash rule. One explicit InputOptions assertion leaves unsupported values to SDK validation, preserving the old error owner rather than silently converting arbitrary inputs. ## Types and dependencies The locked runtime SDK remains MediaBunny 1.56.1. Its pinned WebCodecs declaration 0.1.13 duplicates types now present in TypeScript 5.9.3's DOM library. The root Yarn resolution selects `@types/dom-webcodecs@0.1.19` for both dependency paths; the SDK itself is unchanged. This is a build-time declaration correction, not a browser polyfill. The package typecheck adds ESNext.Disposable for SDK declarations while keeping the ES2020 target; production source does not use `using` or require Symbol.dispose. Public consumer declarations do not import these SDK types; preserve that boundary until the separate consumer-compatibility task verifies any proposed change. ## Validation and remaining work ```sh yarn test:mediabunny node node_modules/typescript/bin/tsc -p packages/artplayer-proxy-mediabunny/tsconfig.json yarn build artplayer-proxy-mediabunny yarn test:browser test/browser/mediabunny-inputs.spec.js test/browser/mediabunny.spec.js test/browser/mediabunny-load.spec.js ``` Node tests use actual SDK parsing and controlled lifecycle interleavings. Browser tests include native decoding and separate pending ReadableStream cancellation with real timers. `ARTPLAYER_MB_BASELINE=1` runs candidate load assertions against the immutable old main to reproduce failures. `ARTPLAYER_MB_ARTIFACT` selects a built UMD main/legacy bundle; `ARTPLAYER_MB_BROWSER_CANDIDATE=1` restricts browser runs to that candidate. Browser reports record the implementation hash; archive the report and results before rerunning. The source of historical truth is `refactor/baselines/mb-release.json` and its Git/npm inputs, not a rebuilt dist. Package-specific evidence and remaining tasks are in `refactor/mb-validation.md`. The full refactor plan is at the repository root. PKG-MB-04 still owns duplicate/trackless readiness, reentrant event sequences and pending play/seek coordination. PKG-MB-05/06 own late frame and audio callbacks, including operations already inside decoders at cancellation; releasing Input alone does not prove those resources are fully handled. PKG-MB-07 owns HLS UI/selection races. PKG-MB-09 owns long-run AV sync, full core/proxy/plugin combinations and device validation. PKG-MB-10 owns the demo, installed package and MPL/source notice gate. Windows WebKit without WebCodecs/Web Audio is recorded as a capability failure, not successful playback or a claim about all Safari installations.