refactor(react): replace prototype-walking and inferred class props (#1376)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
rahim
2026-04-20 09:20:46 -07:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 5e9a02c851
commit 2f7212028c
21 changed files with 256 additions and 176 deletions
@@ -2,14 +2,14 @@ import type { MixinReturn } from '@videojs/utils/types';
import type { RemotePlaybackLike } from '../predicate';
import { GoogleCastProvider } from './google-cast-provider';
import { RemotePlayback } from './remote-playback';
import type { CastableMediaProps, CastableMediaSuperclass } from './types';
import type { CastableMedia, CastableMediaHostConstructor } from './types';
import { getDefaultCastOptions, loadCastFramework, requiresCastFramework } from './utils';
export type { CastableMediaElement } from './types';
export const CastableMediaMixin = <Base extends CastableMediaSuperclass>(
export const CastableMediaMixin = <Base extends CastableMediaHostConstructor>(
superclass: Base
): MixinReturn<Base, CastableMediaProps> => {
): MixinReturn<Base, CastableMedia> => {
class CastableMedia extends superclass {
#castOptions = getDefaultCastOptions();
#castCustomData: Record<string, unknown> | null | undefined;
@@ -222,5 +222,5 @@ export const CastableMediaMixin = <Base extends CastableMediaSuperclass>(
}
}
return CastableMedia as unknown as MixinReturn<Base, CastableMediaProps>;
return CastableMedia as unknown as MixinReturn<Base, CastableMedia>;
};
+19 -9
View File
@@ -2,7 +2,21 @@ import type { RemotePlaybackLike } from '../predicate';
import type { RemotePlayback } from './remote-playback';
import type { CastOptions } from './utils';
export interface CastableMediaBase extends EventTarget {
export interface CastableMediaProps {
castReceiver: string | undefined;
castContentType: string | undefined;
castStreamType: string | undefined;
castCustomData: Record<string, unknown> | null | undefined;
}
export const castableMediaDefaultProps: CastableMediaProps = {
castReceiver: undefined,
castContentType: undefined,
castStreamType: undefined,
castCustomData: undefined,
};
export interface CastableMediaHost extends EventTarget {
readonly target: HTMLMediaElement | null;
readonly remote: RemotePlaybackLike | undefined;
title: string;
@@ -32,20 +46,16 @@ export interface CastableMediaBase extends EventTarget {
querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;
}
export interface CastableMediaProps {
export interface CastableMedia extends CastableMediaProps {
readonly remote: RemotePlayback | RemotePlaybackLike | undefined;
readonly castOptions: CastOptions;
castReceiver: string | undefined;
castSrc: string;
castContentType: string | undefined;
castStreamType: string | undefined;
castCustomData: Record<string, unknown> | null | undefined;
poster: string;
title: string;
}
export type CastableMediaElement = CastableMediaBase & CastableMediaProps;
export type CastableMediaElement = CastableMediaHost & CastableMedia;
export interface CastableMediaSuperclass {
new (...args: any[]): CastableMediaBase;
export interface CastableMediaHostConstructor {
new (...args: any[]): CastableMediaHost;
}
+10 -2
View File
@@ -2,12 +2,20 @@ import * as dashjs from 'dashjs';
import type { MediaEngineHost } from '../../../core/media/types';
import { HTMLVideoElementHost } from '../video-host';
export interface DashMediaProps {
src: string;
}
export const dashMediaDefaultProps: DashMediaProps = {
src: '',
};
export class DashMedia
extends HTMLVideoElementHost
implements MediaEngineHost<dashjs.MediaPlayerClass, HTMLVideoElement>
implements MediaEngineHost<dashjs.MediaPlayerClass, HTMLVideoElement>, DashMediaProps
{
#engine: dashjs.MediaPlayerClass;
#src = '';
#src = dashMediaDefaultProps.src;
constructor() {
super();
+25 -7
View File
@@ -22,14 +22,32 @@ export const SourceTypes = {
MP4: 'video/mp4',
};
export class HlsMedia extends HTMLVideoElementHost {
export interface HlsMediaProps {
src: string;
type: SourceType | undefined;
preferPlayback: PlaybackType | undefined;
config: Record<string, any>;
debug: boolean;
preload: PreloadType;
}
export const hlsMediaDefaultProps: HlsMediaProps = {
src: '',
type: undefined,
preferPlayback: 'mse',
config: {},
debug: false,
preload: 'metadata',
};
export class HlsMedia extends HTMLVideoElementHost implements HlsMediaProps {
#delegate: HlsJsMedia | NativeHlsMedia | null = null;
#src = '';
#type: SourceType | undefined;
#preferPlayback: PlaybackType | undefined = 'mse';
#config: Record<string, any> = {};
#debug = false;
#preload: PreloadType = 'metadata';
#src = hlsMediaDefaultProps.src;
#type = hlsMediaDefaultProps.type;
#preferPlayback = hlsMediaDefaultProps.preferPlayback;
#config = { ...hlsMediaDefaultProps.config };
#debug = hlsMediaDefaultProps.debug;
#preload = hlsMediaDefaultProps.preload;
#loadRequested?: Promise<void> | null;
#prevEngineProps?: Record<string, any> | null;
+18 -4
View File
@@ -1,14 +1,28 @@
import { CastableMediaMixin } from '../castable';
import { HlsMedia } from '../hls';
import { MuxDataMediaMixin } from './mux-data';
import { type CastableMediaProps, castableMediaDefaultProps } from '../castable/types';
import { HlsMedia, type HlsMediaProps, hlsMediaDefaultProps } from '../hls';
import { MuxDataMediaMixin, type MuxDataMediaProps, muxDataMediaDefaultProps } from './mux-data';
export class MuxVideoMedia extends MuxDataMediaMixin(CastableMediaMixin(HlsMedia)) {
export type { CastableMediaProps, HlsMediaProps, MuxDataMediaProps };
export interface MuxMediaProps extends HlsMediaProps, CastableMediaProps, MuxDataMediaProps {
castSrc: string | undefined;
}
export const muxMediaDefaultProps: MuxMediaProps = {
...hlsMediaDefaultProps,
...castableMediaDefaultProps,
...muxDataMediaDefaultProps,
castSrc: undefined,
};
export class MuxVideoMedia extends MuxDataMediaMixin(CastableMediaMixin(HlsMedia)) implements MuxMediaProps {
static PLAYER_SOFTWARE_NAME = 'mux-video';
}
// TODO: HlsMedia extends HTMLVideoElementHost, we should extend
// HTMLAudioElementHost instead but this would require a HlsMediaMixin,
// keep it simple for now.
export class MuxAudioMedia extends MuxDataMediaMixin(CastableMediaMixin(HlsMedia)) {
export class MuxAudioMedia extends MuxDataMediaMixin(CastableMediaMixin(HlsMedia)) implements MuxMediaProps {
static PLAYER_SOFTWARE_NAME = 'mux-audio';
}
+20 -9
View File
@@ -5,15 +5,6 @@ import { Hls, type HlsMedia } from '../hls';
import { getPlayerVersion } from './env';
import type { MuxDataOptions, MuxDataSdk } from './types';
const MUX_VIDEO_DOMAIN = 'mux.com';
export interface MuxDataMediaHost extends MediaEngineHost<HlsMedia['engine'], HTMLMediaElement> {
readonly debug: boolean;
attach(target: HTMLMediaElement): void;
detach(): void;
load(): void;
}
export interface MuxDataMediaProps {
MuxDataSdk: MuxDataSdk | undefined;
beaconCollectionDomain: string | undefined;
@@ -25,6 +16,26 @@ export interface MuxDataMediaProps {
metadata: MuxDataOptions['data'] | undefined;
}
export const muxDataMediaDefaultProps: MuxDataMediaProps = {
MuxDataSdk: undefined,
beaconCollectionDomain: undefined,
disableCookies: false,
envKey: undefined,
playerSoftwareName: undefined,
playerSoftwareVersion: undefined,
playerInitTime: undefined,
metadata: undefined,
};
const MUX_VIDEO_DOMAIN = 'mux.com';
export interface MuxDataMediaHost extends MediaEngineHost<HlsMedia['engine'], HTMLMediaElement> {
readonly debug: boolean;
attach(target: HTMLMediaElement): void;
detach(): void;
load(): void;
}
export const MuxDataMediaMixin: Mixin<MuxDataMediaHost, MuxDataMediaProps> = (BaseClass) => {
class MuxDataMedia extends BaseClass {
#MuxDataSdk: MuxDataSdk | undefined = Mux;
@@ -3,9 +3,19 @@ import { NativeHlsMediaErrorsMixin } from './errors';
export type PreloadType = '' | 'none' | 'metadata' | 'auto';
class NativeHlsMediaBase extends HTMLVideoElementHost {
#src = '';
#preload: PreloadType = 'metadata';
export interface NativeHlsMediaProps {
src: string;
preload: PreloadType;
}
export const nativeHlsMediaDefaultProps: NativeHlsMediaProps = {
src: '',
preload: 'metadata',
};
class NativeHlsMediaBase extends HTMLVideoElementHost implements NativeHlsMediaProps {
#src = nativeHlsMediaDefaultProps.src;
#preload = nativeHlsMediaDefaultProps.preload;
get engine() {
return null;