mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(site): add util reference pipeline (#537)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
c11395ece1
commit
78112fbefd
@@ -9,11 +9,19 @@ import { sourceFeature } from './features/source';
|
||||
import { timeFeature } from './features/time';
|
||||
import { volumeFeature } from './features/volume';
|
||||
|
||||
/** Select the buffer state (buffered ranges, percent buffered). */
|
||||
export const selectBuffer = createSelector(bufferFeature);
|
||||
/** Select the controls state (controls visible, user-active). */
|
||||
export const selectControls = createSelector(controlsFeature);
|
||||
/** Select the fullscreen state (fullscreen active, availability). */
|
||||
export const selectFullscreen = createSelector(fullscreenFeature);
|
||||
/** Select the PiP state (picture-in-picture active, availability). */
|
||||
export const selectPiP = createSelector(pipFeature);
|
||||
/** Select the playback state (paused, ended, play, pause, toggle). */
|
||||
export const selectPlayback = createSelector(playbackFeature);
|
||||
/** Select the source state (src, type). */
|
||||
export const selectSource = createSelector(sourceFeature);
|
||||
/** Select the time state (currentTime, duration, seek). */
|
||||
export const selectTime = createSelector(timeFeature);
|
||||
/** Select the volume state (volume, muted, setVolume, setMuted). */
|
||||
export const selectVolume = createSelector(volumeFeature);
|
||||
|
||||
@@ -10,4 +10,9 @@ export type PlayerContext<Store extends PlayerStore = AnyPlayerStore> = Context<
|
||||
PlayerContextValue<Store>
|
||||
>;
|
||||
|
||||
/**
|
||||
* The default player context instance for consuming the player store in controllers.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const playerContext = createContext<PlayerContextValue, typeof PLAYER_CONTEXT_KEY>(PLAYER_CONTEXT_KEY);
|
||||
|
||||
@@ -67,11 +67,26 @@ export interface CreatePlayerResult<Store extends PlayerStore> {
|
||||
* #playback = new PlayerController(this, context, selectPlayback);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @label Video
|
||||
* @param config - Player configuration with features.
|
||||
*/
|
||||
export function createPlayer(config: CreatePlayerConfig<VideoFeatures>): CreatePlayerResult<VideoPlayerStore>;
|
||||
|
||||
/**
|
||||
* Creates a player factory for audio media.
|
||||
*
|
||||
* @label Audio
|
||||
* @param config - Player configuration with features.
|
||||
*/
|
||||
export function createPlayer(config: CreatePlayerConfig<AudioFeatures>): CreatePlayerResult<AudioPlayerStore>;
|
||||
|
||||
/**
|
||||
* Creates a player factory with custom features.
|
||||
*
|
||||
* @label Generic
|
||||
* @param config - Player configuration with features.
|
||||
*/
|
||||
export function createPlayer<const Features extends AnyPlayerFeature[]>(
|
||||
config: CreatePlayerConfig<Features>
|
||||
): CreatePlayerResult<PlayerStore<Features>>;
|
||||
|
||||
@@ -38,7 +38,18 @@ export class PlayerController<Store extends PlayerStore, Result = Store> impleme
|
||||
#consumer: ContextConsumer<PlayerContext<Store>, PlayerControllerHost>;
|
||||
#store: StoreController<Store, Result> | null = null;
|
||||
|
||||
/**
|
||||
* @label Without Selector
|
||||
* @param host - The host element that owns this controller.
|
||||
* @param context - Player context to resolve the store from.
|
||||
*/
|
||||
constructor(host: PlayerControllerHost, context: PlayerContext<Store>);
|
||||
/**
|
||||
* @label With Selector
|
||||
* @param host - The host element that owns this controller.
|
||||
* @param context - Player context to resolve the store from.
|
||||
* @param selector - Derives a value from the player store state.
|
||||
*/
|
||||
constructor(
|
||||
host: PlayerControllerHost,
|
||||
context: PlayerContext<Store>,
|
||||
|
||||
@@ -16,6 +16,9 @@ export type PlayerMixin<Store extends PlayerStore> = <Class extends MediaElement
|
||||
* Creates a mixin that combines provider and container functionality.
|
||||
*
|
||||
* Use for a complete player element that owns the store and attaches media.
|
||||
*
|
||||
* @param context - Player context for descendant consumption.
|
||||
* @param factory - Factory function that creates a store instance.
|
||||
*/
|
||||
export function createPlayerMixin<Store extends PlayerStore>(
|
||||
context: PlayerContext<Store>,
|
||||
|
||||
@@ -9,6 +9,11 @@ export type ContainerMixin<Store extends PlayerStore> = <Class extends MediaElem
|
||||
BaseClass: Class
|
||||
) => Class & PlayerConsumerConstructor<Store>;
|
||||
|
||||
/**
|
||||
* Create a mixin that consumes player context and auto-attaches media elements.
|
||||
*
|
||||
* @param context - Player context to consume from an ancestor provider.
|
||||
*/
|
||||
export function createContainerMixin<Store extends PlayerStore>(context: PlayerContext<Store>): ContainerMixin<Store> {
|
||||
return <Class extends MediaElementConstructor>(BaseClass: Class) => {
|
||||
class PlayerContainerElement extends BaseClass implements PlayerConsumer<Store>, MediaContainer {
|
||||
|
||||
@@ -9,6 +9,12 @@ export type ProviderMixin<Store extends PlayerStore> = <Class extends MediaEleme
|
||||
BaseClass: Class
|
||||
) => Class & PlayerProviderConstructor<Store>;
|
||||
|
||||
/**
|
||||
* Create a mixin that provides player context to descendant elements.
|
||||
*
|
||||
* @param context - Player context to provide to descendants.
|
||||
* @param factory - Factory function that creates a store instance.
|
||||
*/
|
||||
export function createProviderMixin<Store extends PlayerStore>(
|
||||
context: PlayerContext<Store>,
|
||||
factory: () => Store
|
||||
|
||||
@@ -26,24 +26,38 @@ export function PlayerContextProvider({
|
||||
return <PlayerContext.Provider value={value}>{children}</PlayerContext.Provider>;
|
||||
}
|
||||
|
||||
/** Access the full player context value. Throws if used outside a Player Provider. */
|
||||
export function usePlayerContext(): PlayerContextValue {
|
||||
const ctx = useContext(PlayerContext);
|
||||
if (!ctx) throw new Error('usePlayerContext must be used within a Player Provider');
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the player store from within a Player Provider.
|
||||
*
|
||||
* @label Without Selector
|
||||
*/
|
||||
export function usePlayer(): UnknownStore;
|
||||
/**
|
||||
* Select a value from the player store. Re-renders when the selected value changes.
|
||||
*
|
||||
* @label With Selector
|
||||
* @param selector - Derives a value from the player store state.
|
||||
*/
|
||||
export function usePlayer<R>(selector: (state: UnknownState) => R): R;
|
||||
export function usePlayer<R>(selector?: (state: UnknownState) => R) {
|
||||
const { store } = usePlayerContext();
|
||||
return useStore(store, selector as any);
|
||||
}
|
||||
|
||||
/** Access the media element from within a Player Provider. */
|
||||
export function useMedia(): Media | null {
|
||||
const { media } = usePlayerContext();
|
||||
return media;
|
||||
}
|
||||
|
||||
/** Access the media registration setter for connecting a media element to the player. */
|
||||
export function useMediaRegistration(): Dispatch<SetStateAction<Media | null>> | undefined {
|
||||
const ctx = useContext(PlayerContext);
|
||||
return ctx?.setMedia;
|
||||
|
||||
@@ -40,10 +40,28 @@ export type UsePlayerHook<Store extends PlayerStore> = {
|
||||
<R>(selector: (state: InferStoreState<Store>) => R): R;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a player instance with typed store, Provider component, Container, and hooks.
|
||||
*
|
||||
* @label Video
|
||||
* @param config - Player configuration with features and optional display name.
|
||||
*/
|
||||
export function createPlayer(config: CreatePlayerConfig<VideoFeatures>): CreatePlayerResult<VideoPlayerStore>;
|
||||
|
||||
/**
|
||||
* Create a player for audio media.
|
||||
*
|
||||
* @label Audio
|
||||
* @param config - Player configuration with features and optional display name.
|
||||
*/
|
||||
export function createPlayer(config: CreatePlayerConfig<AudioFeatures>): CreatePlayerResult<AudioPlayerStore>;
|
||||
|
||||
/**
|
||||
* Create a player with custom features.
|
||||
*
|
||||
* @label Generic
|
||||
* @param config - Player configuration with features and optional display name.
|
||||
*/
|
||||
export function createPlayer<const Features extends AnyPlayerFeature[]>(
|
||||
config: CreatePlayerConfig<Features>
|
||||
): CreatePlayerResult<PlayerStore<Features>>;
|
||||
|
||||
@@ -33,6 +33,8 @@ export interface UseButtonReturnValue {
|
||||
* props: [elementProps, getButtonProps],
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param params - Button configuration with activation handler and disabled check.
|
||||
*/
|
||||
export function useButton(params: UseButtonParameters): UseButtonReturnValue {
|
||||
const { displayName, onActivate, isDisabled } = params;
|
||||
|
||||
@@ -93,6 +93,7 @@ function mergeOne<T extends ElementType>(
|
||||
* - style: merged objects (external wins conflicts)
|
||||
* - other: last one wins
|
||||
*
|
||||
* @public
|
||||
* @example
|
||||
* ```ts
|
||||
* const merged = mergeProps(
|
||||
|
||||
@@ -54,6 +54,7 @@ function getElementRef(element: ReactElement): Ref<unknown> | undefined {
|
||||
* - Ref composition
|
||||
* - className/style as functions of state
|
||||
*
|
||||
* @public
|
||||
* @example
|
||||
* ```tsx
|
||||
* return renderElement('button', componentProps, {
|
||||
|
||||
@@ -19,6 +19,8 @@ const stateContext: StateContext<unknown> = {
|
||||
* const selectPlayback = createSelector(playbackSlice);
|
||||
* selectPlayback(store.state); // { paused, play, pause, ... } | undefined
|
||||
* ```
|
||||
*
|
||||
* @param slice - The feature slice to create a selector for.
|
||||
*/
|
||||
export function createSelector<S extends AnySlice>(slice: S): (state: object) => InferSliceState<S> | undefined {
|
||||
const initialState = slice.state(stateContext);
|
||||
|
||||
@@ -25,7 +25,18 @@ export class SnapshotController<T extends object, R = T> implements ReactiveCont
|
||||
#cached: R | undefined;
|
||||
#unsubscribe = noop;
|
||||
|
||||
/**
|
||||
* @label Without Selector
|
||||
* @param host - The host element that owns this controller.
|
||||
* @param state - The State container to subscribe to.
|
||||
*/
|
||||
constructor(host: ReactiveControllerHost, state: State<T>);
|
||||
/**
|
||||
* @label With Selector
|
||||
* @param host - The host element that owns this controller.
|
||||
* @param state - The State container to subscribe to.
|
||||
* @param selector - Derives a value from the state.
|
||||
*/
|
||||
constructor(host: ReactiveControllerHost, state: State<T>, selector: Selector<T, R>);
|
||||
constructor(host: ReactiveControllerHost, state: State<T>, selector?: Selector<T, R>) {
|
||||
this.#host = host;
|
||||
|
||||
@@ -45,7 +45,18 @@ export class StoreController<Store extends AnyStore, Result = Store> implements
|
||||
|
||||
#snapshot: SnapshotController<object, Result> | null = null;
|
||||
|
||||
/**
|
||||
* @label Without Selector
|
||||
* @param host - The host element that owns this controller.
|
||||
* @param source - Store instance or context to resolve the store from.
|
||||
*/
|
||||
constructor(host: StoreControllerHost, source: StoreSource<Store>);
|
||||
/**
|
||||
* @label With Selector
|
||||
* @param host - The host element that owns this controller.
|
||||
* @param source - Store instance or context to resolve the store from.
|
||||
* @param selector - Derives a value from the store state.
|
||||
*/
|
||||
constructor(
|
||||
host: StoreControllerHost,
|
||||
source: StoreSource<Store>,
|
||||
|
||||
@@ -42,6 +42,11 @@ export class SubscriptionController<Store extends AnyStore, Value> implements Re
|
||||
|
||||
#unsubscribe = noop;
|
||||
|
||||
/**
|
||||
* @param host - The host element that owns this controller.
|
||||
* @param source - Store instance or context to resolve the store from.
|
||||
* @param config - Subscription and value extraction configuration.
|
||||
*/
|
||||
constructor(
|
||||
host: SubscriptionControllerHost,
|
||||
source: StoreSource<Store>,
|
||||
|
||||
@@ -3,7 +3,16 @@ import { type Comparator, type Selector, shallowEqual } from '../../core/shallow
|
||||
|
||||
export type { Comparator, Selector };
|
||||
|
||||
/** Subscribe to derived state with customizable equality check. */
|
||||
/**
|
||||
* Subscribe to derived state with customizable equality check.
|
||||
*
|
||||
* Low-level hook used internally by `useStore` and `useSnapshot`.
|
||||
*
|
||||
* @param subscribe - Subscribe function that returns an unsubscribe callback.
|
||||
* @param getSnapshot - Returns the current snapshot value.
|
||||
* @param selector - Derives a value from the snapshot.
|
||||
* @param isEqual - Custom equality function. Defaults to `shallowEqual`.
|
||||
*/
|
||||
export function useSelector<S, R>(
|
||||
subscribe: (cb: () => void) => () => void,
|
||||
getSnapshot: () => S,
|
||||
|
||||
@@ -2,9 +2,23 @@ import { identity } from '@videojs/utils/function';
|
||||
import type { State } from '../../core/state';
|
||||
import { type Comparator, type Selector, useSelector } from './use-selector';
|
||||
|
||||
/** Subscribe to a State container's current value. */
|
||||
/**
|
||||
* Subscribe to a State container's current value.
|
||||
*
|
||||
* @param state - The State container to subscribe to.
|
||||
* @param selector - Derives a value from state.
|
||||
* @param isEqual - Custom equality function. Defaults to `shallowEqual`.
|
||||
*/
|
||||
/** @label Without Selector */
|
||||
export function useSnapshot<T extends object>(state: State<T>): T;
|
||||
|
||||
/**
|
||||
* Select a value from state. Re-renders when the selected value changes.
|
||||
*
|
||||
* @label With Selector
|
||||
* @param selector - Derives a value from state.
|
||||
* @param isEqual - Custom equality function. Defaults to `shallowEqual`.
|
||||
*/
|
||||
export function useSnapshot<T extends object, R>(state: State<T>, selector: Selector<T, R>, isEqual?: Comparator<R>): R;
|
||||
|
||||
export function useSnapshot(state: State<object>, selector?: Selector<any, any>, isEqual?: Comparator<any>) {
|
||||
|
||||
@@ -24,8 +24,16 @@ const noopSubscribe = () => noop;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
/** @label Without Selector */
|
||||
export function useStore<S extends AnyStore>(store: S): S;
|
||||
|
||||
/**
|
||||
* Select a value from the store. Re-renders when the selected value changes (shallowEqual).
|
||||
*
|
||||
* @label With Selector
|
||||
* @param selector - Derives a value from the store state.
|
||||
* @param isEqual - Custom equality function. Defaults to `shallowEqual`.
|
||||
*/
|
||||
export function useStore<S extends AnyStore, R>(
|
||||
store: S,
|
||||
selector: Selector<InferStoreState<S>, R>,
|
||||
|
||||
Reference in New Issue
Block a user