refactor(multiple-subtitles): [PKG-MULTI-SUB-03] own requests and subtitle resources

This commit is contained in:
Harvey Zhao committed 2026-09-13 11:01:47 +08:00
1 parent 36cd151095
commit beaa93d6cc
25 files changed
+7908 -250

No files matched your search

@@ -8,9 +8,15 @@ task PKG-MULTI-SUB-04 owns that compatibility work. Do not infer runtime behavio
## Current module boundaries
- `src/index.js` currently combines download/decode, conversion, parsing, merging, Blob URL
replacement and public registration. Task 03 will separate pure merge, requests and owned
resources while preserving the factory and CSS hooks.
- `src/index.js` composes registration, named selection and the unchanged public result.
- `src/request.js` owns each fetch through byte decoding and delegates SRT/ASS conversion
to the existing core utils. Failure aborts the request; registration failure closes siblings.
- `src/merge.js` parses metadata and serializes selected cues without mutating parsed trees.
It depends only on the vendor parser, not the player or browser resource APIs.
- `src/lifetime.js` owns the destroy listener, request cancellation and resource callbacks.
Its cancellation Promise also settles pending operations without AbortController support.
- `src/render.js` owns generated Blob URLs and synchronous/async host installation outcomes.
Reentrant selections and stale host rejections cannot release the latest selected resource.
- `src/parser.js` is vendored WebVTT parser/serializer code with a CC0 dedication. It is not
owned plugin code to mechanically migrate to TypeScript. Keep it distinct from task 04.
The pinned upstream reference and full adaptation check are in
@@ -23,19 +29,22 @@ task PKG-MULTI-SUB-04 owns that compatibility work. Do not infer runtime behavio
All tracks download concurrently and decode through TextDecoder. Explicit type wins over
the URL extension; SRT/ASS conversion delegates to existing core utils. `onParser` appears
in declarations but is not called. Parsing runs in metadata mode. Each track's top-level
cue text receives a name-based div once; current merging concatenates cue arrays by track
cue text receives a name-based div in a copied cue; merging concatenates cue arrays by track
order, whereas 1.0.0 merged by cue index and retained the first track's timestamps.
Each selection serializes a new VTT, revokes the preceding URL, creates a text/vtt Blob,
sets the live subtitle option's escape to false and calls subtitle.init with the live
configuration plus URL/type/onVttLoad overrides. The latest URL and pending requests have
no destroy owner yet. These are explicit future fixes, not behavior to silently call safe.
Each selection serializes VTT and allocates a text/vtt Blob before replacing the preceding
URL. It sets the live subtitle option's escape to false and calls subtitle.init with live
configuration plus URL/type/onVttLoad overrides. Allocation failure preserves the prior URL;
synchronous installation failure releases the new URL and restores the previous ownership.
Async host failure is observed and releases only the failed active installation, with a warning
while alive. The plugin cannot generically undo host side effects after asynchronous failure.
Registration does not await host media loading, and selection methods remain void.
The failure baseline now reproduces late fetch/body installation, retained and newly allocated
URLs after destroy, ignored HTTP failures, orphaned URLs after init failures, and revoking the
old URL before a new allocation can fail. Async init rejection is currently unobserved by the
plugin. Task 03 must handle these internal failures while retaining the void selection methods.
Keep the current parser's best-effort behavior separate from these resource fixes: invalid-header
Destroy cancels pending requests, settles registration with an inert result, releases owned
URLs and removes its listener. Retained methods become no-ops; restart does not refetch tracks.
Do not restore the shared escape option on normal destroy: another consumer may now own it.
The historical failure suite deliberately retains the old outcomes; the candidate lifecycle
suite verifies their fixes. Preserve parser best-effort behavior independently: invalid-header
diagnostics can coexist with usable cues, and metadata is intentionally read after download.
## Vendor boundary and validation
@@ -51,6 +60,7 @@ Use the pinned Node and Yarn 1.22.22:
```sh
yarn test:multiple-subtitles
yarn test:browser test/browser/multiple-subtitles-history.spec.js
yarn test:browser test/browser/multiple-subtitles-lifecycle.spec.js
yarn build artplayer-plugin-multiple-subtitles
```
@@ -63,5 +73,9 @@ uses actual 1.2.0 main with published/candidate cores: SRT display and selection
fetch after destroy, and native Blob readability/late reset allocations. It covers Chromium,
Firefox and Windows WebKit; it is not all historical cores, ASS display or physical Safari.
The failure unit suite uses real current core converters and TextDecoder for SRT/ASS/encodings.
Candidate lifecycle and merge suites cover cancellation, failures, resource ownership,
reentrancy and immutable serialization. The candidate browser suite adds real video source
switching, HTTP rejection and Blob revocation. For main/legacy validation, set the artifact
environment variable above before running it; source builds are used when it is absent.
Tasks 05/06 still own complete core/device combinations and demo acceptance.
See `../../refactor/baselines/multiple-subtitles-contract.md` for exact historical differences.