Referencia de la API del core

Referencia completa de la configuración, los callbacks, los métodos y el estado de @reelkit/core.

SliderController API

El core independiente del framework. Una sola factoría crea un controlador a partir de una configuración y unos eventos opcionales: las opciones de configuración son la configuración, los callbacks son los eventos y los métodos son lo que expone el controlador devuelto.

Función factoría

ExportTipoDescripción
createSliderController(config: SliderConfig, events?: SliderEvents) => SliderControllerCrea un controlador del slider. config es obligatorio (opciones más abajo); events es opcional (callbacks más abajo). Devuelve el controlador con los métodos que lo manejan.

Opciones de configuración

PropiedadTipoPor defectoDescripción
countnumberobligatorioNúmero total de elementos
initialIndexnumber0Índice inicial
directionSliderDirection'vertical'Dirección del desplazamiento, 'vertical' | 'horizontal'
enableGesturesbooleantrueActiva la navegación arrastrando con el dedo o el ratón. Con false, el controlador de gestos no se conecta.
enableNavKeysbooleantrueActiva la navegación con las teclas de flecha
enableWheelbooleanfalseActiva la rueda del ratón
wheelDebounceMsnumber200Tiempo de debounce de la rueda
loopbooleanfalseNavegación en bucle
transitionDurationnumber300Duración de la animación en ms
swipeDistanceFactornumber0.12Umbral del deslizamiento (0-1)
rangeExtractorRangeExtractordefaultRangeExtractorFunción propia que decide qué índices se renderizan

Callbacks

CallbackTipoDescripción
onBeforeChange(index, nextIndex, rangeIndex) => voidAntes del cambio de slide
onAfterChange(index, rangeIndex) => voidDespués del cambio de slide
onDragStart(index) => voidEmpieza el arrastre
onDragEnd(index) => voidTermina el arrastre
onDragCanceled(index) => voidSe cancela el arrastre
onTap(event: GestureCommonEvent) => voidToque simple (se retrasa lo que dura la ventana del doble toque)
onDoubleTap(event: GestureCommonEvent) => voidSe detecta un doble toque
onLongPress(event: GestureCommonEvent) => voidSe detecta una pulsación larga
onLongPressEnd(event: GestureEvent) => voidSe suelta el puntero tras una pulsación larga
onNavKeyPress(increment: -1 | 1) => voidManejador propio para la navegación con flechas. Sustituye el comportamiento por defecto de anterior y siguiente.

Métodos

MétodoTipoDescripción
attach(element)(HTMLElement) => voidConecta el controlador a un elemento del DOM para detectar gestos
detach()() => voidQuita los listeners del DOM (gestos, teclado, rueda). Se puede volver a conectar con observe(). Úsalo en la limpieza de un efecto de React.
dispose()() => voidDesmontaje definitivo: desconecta todos los controladores y limpia los observadores de señales. Úsalo en el onDestroy de Angular.
observe()() => voidEmpieza a observar gestos, teclado y rueda. Respeta las opciones enableGestures, enableNavKeys y enableWheel.
unobserve()() => voidDeja de observar gestos, teclado y rueda
next()() => Promise<void>Va al slide siguiente
prev()() => Promise<void>Va al slide anterior
goTo(index, animate?)(number, boolean?) => Promise<void>Va a un slide concreto
adjust(duration?)(number?) => voidRecalcula las posiciones de los slides
setPrimarySize(size)(number) => voidActualiza el tamaño del contenedor
updateConfig(config)(Partial<SliderConfig>) => voidActualiza las opciones de configuración
updateEvents(events)(Partial<SliderEvents>) => voidSustituye los manejadores de eventos (los que no se incluyen se conservan)
getRangeIndex()() => numberDevuelve la posición del índice activo dentro del array del rango visible

Propiedades de estado

El campo state del controlador es un SliderState, las tres señales de abajo. Tipa con SliderState un valor que lo reciba.

PropiedadTipoDescripción
indexSignal<number>Índice del slide actual
axisValueSignal<AnimatedValue>Posición actual en el eje (animada)
indexesComputedSignal<number[]>Índices visibles para la virtualización

Extractor de rango

ExportTipoDescripción
defaultRangeExtractorRangeExtractorExtractor por defecto que renderiza 3 elementos alrededor del índice actual
RangeExtractor(current: number, count: number, loop: boolean) => number[]Firma de un extractor de rango. Tipa con ella tu propio rangeExtractor.

Signal API

Primitivas reactivas ligeras que usa todo el core.

Interfaz Signal

MiembroTipoDescripción
valueTLee o cambia el valor actual. Al cambiarlo avisa a los observadores si el valor es distinto.
observe(callback)(callback: () => void) => () => voidRegistra un listener que se llama en cada cambio de valor. Devuelve una función que lo elimina.

Funciones factoría

ExportTipoDescripción
createSignal<T>(initial: T) => Signal<T>Crea una señal reactiva mutable
createComputed<T>(fn: () => T, deps: () => Subscribable[]) => ComputedSignal<T>Crea una señal calculada derivada. El segundo argumento es una factoría de dependencias que devuelve las señales que hay que seguir.
reaction(deps: () => Subscribable[], effect: () => void) => () => voidEjecuta un efecto secundario cuando cambia cualquier señal de la que depende y devuelve una función para desmontarlo. Lee los valores de las señales dentro del callback del efecto.
batch(fn: () => void) => voidAgrupa varias actualizaciones de señales en una sola ronda de avisos; admite anidación
Listener() => voidEl callback que recibe observe. Tipa con él un observador de señal que declares aparte.
Dispose() => voidLo que devuelven observe y reaction: llámalo para dejar de escuchar. Tipa con él una suscripción guardada.

Transiciones

Funciones de transición incluidas que calculan las transformaciones CSS de cada slide durante la navegación animada. Pasa una como prop transitionTransformFn al componente del framework.

ExportTipoDescripción
TransitionTransformFntypeFirma de las funciones de transición propias
getSlideProgress(axisValue: number, slideIndex: number, primarySize: number) => numberDevuelve un desplazamiento normalizado (de -1 a 1) de un slide respecto al viewport. Úsalo dentro de funciones de transición propias.
slideTransitionTransitionTransformFnTransición de deslizamiento por defecto (translateX/Y)
fadeTransitionTransitionTransformFnTransición de fundido cruzado con opacidad
flipTransitionTransitionTransformFnTransición 3D de volteo de tarjeta
cubeTransitionTransitionTransformFnTransición 3D con rotación de cubo
zoomTransitionTransitionTransformFnTransición de escala y zoom
SlideTransformStyle{ transform?; transformOrigin?; opacity?; zIndex? }Lo que devuelve una TransitionTransformFn para un slide. Devuélvelo desde una transición propia.

Controladores de entrada

El controlador del slider crea estos tres por sí mismo a partir de sus opciones enableGestures, enableNavKeys y enableWheel. Crea uno directamente cuando escribas tu propia integración o necesites gestos, flechas o la rueda en un elemento que no es un slider.

Controlador de gestos

ExportTipoDescripción
createGestureController(config?: GestureControllerConfig, events?: GestureControllerEvents) => GestureControllerDetecta toques, dobles toques, pulsaciones largas y arrastres sobre un elemento, y fija cada arrastre a su eje dominante.
GestureController{ attach; detach; observe; unobserve; updateEvents }Objeto que devuelve createGestureController. attach(element) enlaza el elemento, observe() añade los listeners, unobserve() los quita y conserva el elemento, detach() lo quita todo; updateEvents(events) incorpora manejadores nuevos.
GestureControllerConfig{ useTouchEventsOnly?; longPressDurationMs?; doubleTapWindowMs? }Opciones de createGestureController: ignorar el ratón (por defecto false), duración de la pulsación larga (por defecto 800 ms), ventana del doble toque (por defecto 200 ms).
GestureControllerEvents{ onTap?; onDoubleTap?; onTapDown?; onTapUp?; onLongPress?; onLongPressEnd?; onHorizontalDragStart?; onHorizontalDragUpdate?; onHorizontalDragEnd?; onVerticalDragStart?; onVerticalDragUpdate?; onVerticalDragEnd?; onDragEnd? }Callbacks a los que llama createGestureController. Un arrastre va a los manejadores horizontales o verticales según su eje dominante; onDragEnd se dispara en ambos casos.
GestureAxisDragUpdateEventGestureEvent & { delta; distance; primaryDelta; primaryDistance; cancel }Datos de onHorizontalDragUpdate y onVerticalDragUpdate: movimiento desde la última actualización, distancia total, lo mismo en el eje dominante y cancel() para devolver el arrastre a su sitio.
GestureAxisDragEndEventGestureAxisDragUpdateEvent sin cancel, más { velocity; primaryVelocity }Datos de onHorizontalDragEnd y onVerticalDragEnd, con la velocidad al soltar en píxeles por segundo.
GestureDragEndEventGestureAxisDragEndEvent sin los campos primaryDatos de onDragEnd, para un manejador al que no le importa por qué eje fue el arrastre.
Offset[x: number, y: number]Un par de píxeles, usado para cada posición, delta, distancia y velocidad de un evento de gesto.
EventKind'touch' | 'mouse'La entrada de la que vino un gesto, en el campo kind de GestureCommonEvent.
DragAxis'horizontal' | 'vertical' | nullEl eje dominante de un arrastre, null hasta que el primer movimiento lo decide.

Controlador de teclado

ExportTipoDescripción
createKeyboardController(config: KeyboardControllerConfig, events: KeyboardControllerEvents) => KeyboardControllerConvierte las pulsaciones de las flechas en callbacks con un NavKey.
KeyboardController{ attach; detach }Objeto que devuelve createKeyboardController. attach(target?) escucha keydown en el destino (por defecto window), detach() deja de hacerlo.
KeyboardControllerConfig{ filter?; throttleMs? }Opciones de createKeyboardController: las teclas a las que reaccionar (por defecto las cuatro) y el tiempo mínimo entre dos pulsaciones (por defecto 0, sin limitación).
KeyboardControllerEvents{ onKeyPress: (key: NavKey, event: KeyboardEvent) => void }Callback al que llama createKeyboardController en cada pulsación aceptada.
NavKey'up' | 'right' | 'down' | 'left'La flecha pulsada, tal como la notifica y filtra el controlador de teclado.

Controlador de rueda

ExportTipoDescripción
createWheelController(config: WheelControllerConfig, events: WheelControllerEvents) => WheelControllerConvierte el desplazamiento con la rueda del ratón en un callback de dirección por gesto, agrupando la ráfaga de eventos que produce un solo desplazamiento.
WheelController{ attach; detach }Objeto que devuelve createWheelController. attach(target?) escucha wheel en el destino (por defecto window), detach() deja de hacerlo y descarta un callback pendiente.
WheelControllerConfig{ debounceMs?; deltaThreshold? }Opciones de createWheelController: el tiempo de calma que termina un gesto (por defecto 200 ms) y el delta mínimo que cuenta (por defecto 10 px).
WheelControllerEvents{ onWheel: (direction: WheelDirection, event: WheelEvent) => void }Callback al que llama createWheelController una vez por gesto de rueda.
WheelDirection'up' | 'down' | 'left' | 'right'La dirección de un gesto de rueda.

Carga de contenido

Utilidades para seguir el estado de carga y de error de cada slide y precargar medios. El controlador de carga usa una comprobación del índice para descartar callbacks antiguos de slides que ya no están activos. El precargador usa una caché LRU (200 cargados y 100 con error por defecto), así que volver a una URL rota muestra el error al instante sin reintentar.

ExportTipoDescripción
createContentLoadingController() => ContentLoadingControllerSeguimiento del estado de carga y de error de cada slide
createContentPreloader(config: ContentPreloaderConfig) => ContentPreloaderPrecargador de medios con caché LRU que también guarda los errores
observeMediaLoading(video: HTMLVideoElement, callbacks: MediaLoadingCallbacks) => () => voidObserva el estado de carga de un vídeo (playing, canplaythrough, waiting). Devuelve una función para desmontarlo.

ContentLoadingController

ExportTipoDescripción
isLoadingSignal<boolean>Indica si el slide activo se está cargando
isErrorSignal<boolean>Indica si el slide activo ha dado error
setActiveIndex(index: number) => voidActualiza el índice activo y reinicia el estado de carga y de error
onReady(index: number) => voidMarca el slide como listo (se ignora si el índice no coincide con el activo)
onWaiting(index: number) => voidMarca el slide como en carga (se ignora si el índice no coincide con el activo)
onError(index: number) => voidMarca el slide con error (se ignora si el índice no coincide con el activo)

ContentPreloader

ExportTipoDescripción
preload(src: string, type?: "image" | "video") => voidEmpieza a precargar la URL de un medio
isLoaded(src: string) => booleanComprueba si la URL está en la caché LRU de cargados (máximo 200)
isErrored(src: string) => booleanComprueba si la URL está en la caché LRU de errores (máximo 100)
markLoaded(src: string) => voidMarca a mano una URL como cargada
markErrored(src: string) => voidMarca a mano una URL con error
onLoaded(src: string, cb: () => void) => () => voidSe suscribe al final de la carga; devuelve una función para desmontarlo

Sonido

Estado compartido de silencio para la reproducción de medios. El controlador de sonido ofrece una señal reactiva de silencio que se puede sincronizar con elementos de vídeo y cambiar desde controles propios.

ExportTipoDescripción
createSoundController() => SoundControllerControlador del estado de silencio compartido
syncMutedToVideo(video: HTMLVideoElement, sound: SoundController) => () => voidSincroniza la señal de silencio con un elemento de vídeo. Devuelve una función para desmontarlo.

Línea de tiempo

Controlador de la línea de tiempo para avanzar y retroceder en un vídeo. Sigue la duración, el tiempo actual, los rangos cargados y si el usuario está arrastrando, todo como señales reactivas. Una sola llamada conecta las interacciones con puntero y teclado a cualquier elemento del DOM para que funcione como una barra de progreso nativa, con captura del puntero, búsqueda en vivo y teclado completo (flechas, Inicio/Fin, RePág/AvPág).

ExportTipoDescripción
createTimelineController(config?: TimelineControllerConfig) => TimelineControllerFactoría que devuelve un controlador con las señales duration, currentTime, progress, bufferedRanges y isScrubbing y los métodos attach, detach, bindInteractions y seek.
TimelineControllerConfiginterfacekeyboardStepSeconds (5 por defecto), keyboardPageFraction (0.1 por defecto) y los callbacks onSeek, onScrubStart y onScrubEnd.
BufferedRange{ start: number; end: number }Una zona cargada continua, expresada como fracciones de 0 a 1 de la duración total. Se emiten ordenadas y sin solaparse.

Pantalla completa

Utilidades de pantalla completa compatibles con todos los navegadores, con protección para los prefijos de Safari. La señal de pantalla completa es un singleton perezoso que sigue ese estado de forma reactiva.

ExportTipoDescripción
fullscreenSignalSignal<boolean>Señal reactiva que indica si el documento está en pantalla completa
requestFullscreen(element: HTMLElement) => Promise<void>Pone en pantalla completa el elemento indicado
exitFullscreen() => Promise<void>Sale de la pantalla completa

Utilidades de DOM y limpieza

Ayudantes de bajo nivel para gestionar eventos del DOM y limpiar de forma determinista. Los usan todos los controladores internamente y están disponibles para integraciones propias.

ExportTipoDescripción
observeDomEvent(target, event, handler, options?) => () => voidAñade un listener de eventos del DOM y devuelve una función que lo quita
createDisposableList() => DisposableListLista combinable para reunir funciones de limpieza. Llama a dispose() para ejecutarlas todas a la vez.
createBodyLock() => BodyLockBloqueo del scroll del body con recuento de referencias. Varios consumidores pueden bloquearlo a la vez; el scroll vuelve cuando todos lo liberan.
sharedBodyLockBodyLockInstancia única a nivel de módulo. Úsala cuando varios componentes de tu aplicación deban compartir un solo contador para que los modales y overlays anidados se intercalen bien. Los bindings de los frameworks (@reelkit/react, @reelkit/vue, @reelkit/angular) la usan por debajo.

Utilidades

Pequeñas utilidades con las que están hechos los controladores. Los bindings de los frameworks las reexportan, así que un slide, una transición o una integración propios pueden usar las mismas.

ExportTipoDescripción
first<T>(arr: readonly T[]) => TPrimer elemento de un array, como la x de un Offset o el ancho de un tamaño.
last<T>(arr: readonly T[]) => TÚltimo elemento de un array, como la y de un Offset o el alto de un tamaño.
generate<G>(count: number, generator: (i: number) => G) => G[]Crea un array de count elementos a partir de su índice, por ejemplo generate(10, (i) => i) para datos de demo.
abs(value: number) => numberValor absoluto.
isNegative(value: number) => booleanSi un número es menor que cero, por ejemplo para distinguir un arrastre hacia atrás de uno hacia delante.
clamp(value: number, min: number, max: number) => numberMantiene un número entre min y max, ambos incluidos.
lerp(t: number, a: number, b: number) => numberInterpolación lineal: a con t = 0, b con t = 1. Úsala en una transición propia para convertir el progreso del slide en un valor.
extractRange(count, start, end?, overscan?, loop?) => number[]Índices de start a end (por defecto start) más overscan a cada lado (por defecto 1), dando la vuelta en los extremos cuando loop es true. Construye con ella un RangeExtractor propio.
noop() => voidUna función que no hace nada, para un callback por defecto.
createDeferred<T = void>() => Deferred<T>Una promesa junto con el resolve que la resuelve, para unir una API de callbacks con await.
Deferred{ promise: Promise<T>; resolve: (value?: T) => void }Objeto que devuelve createDeferred.
createLruCache<V>(maxSize: number, onEvict?: (value: V, key: string) => void) => LruCache<V>Un Map que conserva las maxSize entradas guardadas más recientemente y descarta la más antigua a partir de ahí. onEvict se ejecuta por cada entrada descartada, para limpiezas como URL.revokeObjectURL.
LruCacheMap<string, V>Objeto que devuelve createLruCache. Es un Map real; solo cambia set.
animate(options: AnimationOptions) => () => voidAnima un número de from a to con una curva ease-in-out y llama a onUpdate en cada fotograma. Devuelve una función que cancela la animación.
AnimationOptions{ from; to; duration; onUpdate; onComplete? }Opciones de animate: valor inicial y final, duración en milisegundos, el callback de cada fotograma y un callback opcional al terminar.

Detección de tamaño

Cómo miden su contenedor y la ventana todos los bindings y overlays. Reel usa observeElementSize cuando no se le pasa size; el reel player, el lightbox y el stories player toman su tamaño de la ventana. Seguras en SSR: sin window o sin ResizeObserver, los getters devuelven [0, 0] o false y los observadores devuelven una función de limpieza que no hace nada.

ExportTipoDescripción
observeElementSize(element: Element, callback: (size: [number, number]) => void) => DisposerInforma del padding box del elemento (clientWidth × clientHeight) cada vez que cambia. Omite un tamaño con algún lado a cero (oculto o aún sin maquetar) y un tamaño igual al último que informó.
getViewportSize() => [number, number]El tamaño de la ventana como [innerWidth, innerHeight].
observeViewportSize(callback: (size: [number, number]) => void) => DisposerLlama al callback con el tamaño de la ventana en cada evento resize, incluso en uno que deja el tamaño igual (la emulación de dispositivos puede cambiar a un dispositivo táctil con las mismas dimensiones). Compara los tamaños tú mismo si solo te importa un cambio.
isMobileWidth(viewportWidth: number) => booleanSi una ventana de ese ancho recibe la disposición de móvil: 768px o menos. Todos los overlays y su hoja de estilos cambian en ese ancho.
fitAspectRatio(viewport: [number, number], aspectRatio?: number) => [number, number]Tamaño del overlay para una ventana. Con ancho de móvil es la ventana entera; si no, toda la altura de la ventana con la relación aspectRatio, estrechada al ancho de la ventana cuando no cabría. Una relación ausente, cero, negativa o no finita vuelve a 9/16.
isTouchDevice() => booleanSi el dispositivo admite entrada táctil (ontouchstart o maxTouchPoints). Comprueba una capacidad, no un tamaño de pantalla: un portátil táctil cuenta, una ventana estrecha de escritorio no.

Reproducción automática

Temporizadores para todo lo que avanza solo. Cómo se comportan y cómo conectarlos está en la guía de reproducción automática.

ExportTipoDescripción
createTimerController(config: TimerControllerConfig) => TimerControllerCuenta una duración de 0 a 1 y llama al callback cuando termina. Mueve cada story en los stories players.
createSlideshowController(config: SlideshowControllerConfig) => SlideshowControllerLa máquina de estados detrás de una galería que avanza sola. Mueve el autoAdvance del lightbox.

createTimerController

TimerControllerConfigTipoDescripción
durationnumberDuración por defecto en milisegundos, usada cuando start() no recibe ninguna
onComplete() => voidSe llama cuando el progreso llega a 1
TimerControllerTipoDescripción
progressSignal<number>Progreso de 0 a 1; mueve una barra de progreso
isRunningSignal<boolean>Si el temporizador está contando
start(duration?)(number?) => voidEmpieza de nuevo desde 0, opcionalmente con otra duración para esta vuelta
pause()() => voidCongela el progreso actual
resume()() => voidContinúa desde el progreso congelado
reset()() => voidVuelve a 0, detenido
dispose()() => voidCancela el fotograma pendiente

createSlideshowController

SlideshowControllerConfigTipoDescripción
intervalnumberCuánto tiempo se queda una imagen, en milisegundos, contado desde que ha cargado
onAdvance() => voidLa diapositiva activa ha terminado. Pasa a la siguiente, o llama a pause() en la última
SlideshowControllerTipoDescripción
isPlayingSignal<boolean>Si el pase de diapositivas está activado. Las retenciones no lo cambian
progressSignal<number>Cuánto ha corrido el intervalo de la imagen activa, de 0 a 1
play() / pause() / toggle()() => voidLo activa o desactiva; la diapositiva activa conserva su progreso
setInterval(ms)(number) => voidCambia el intervalo a partir de la siguiente imagen
setSlide(kind)(SlideshowSlideKind) => voidUna nueva diapositiva pasó a estar activa: el progreso empieza de nuevo y espera a ready() o ended(). SlideshowSlideKind es 'image' | 'video'
ready()() => voidLa imagen activa cargó o no pudo cargar; empieza su intervalo
ended()() => voidEl vídeo activo terminó; avanza ya, o en cuanto nada lo retenga
hold(reason) / release(reason)(string) => voidDetiene el reloj por un motivo como 'hover' o 'drag'. Las retenciones se acumulan
dispose()() => voidDetiene el reloj y el listener de visibilidad

Descarga

Guardar un archivo desde una URL, también de otro origen. La alternativa que toma está en la guía de descarga.

ExportTipoDescripción
downloadFile(url: string, filename?: string) => Promise<void>Guarda un archivo con el nombre filename, por defecto el último segmento de la ruta de la URL. Descarga el archivo con fetch y guarda el blob, porque el atributo download se ignora en un enlace de otro origen. Cuando el fetch falla o el servidor responde con un error (un servidor de otro origen sin cabeceras CORS es el caso habitual), la URL se abre en una pestaña nueva. Nunca rechaza; no hace nada sin window.

Gestión del foco

Primitivas de accesibilidad para diálogos, independientes del framework. Los paquetes de overlay las usan para devolver el foco al disparador al cerrar y para mantener Tab / Mayús+Tab dentro del overlay mientras está abierto. Seguras en SSR: fuera del navegador, cada ayudante devuelve una función de limpieza que no hace nada.

ExportTipoDescripción
captureFocusForReturn() => DisposerGuarda el elemento con el foco y devuelve una función que se lo devuelve. Hace lo que puede: si el elemento guardado ya no está en el DOM, la función no hace nada.
createFocusTrap(container: HTMLElement) => DisposerMantiene Tab/Mayús+Tab dentro de container. Tab en el último elemento enfocable salta al primero; Mayús+Tab en el primero salta al último; el foco que sale del contenedor (un clic fuera, un foco por código) vuelve dentro. Al activarse no mueve el foco dentro del contenedor: eso lo decide quien lo llama.
getFocusableElements(container: HTMLElement) => HTMLElement[]Devuelve todos los descendientes enfocables con teclado en el orden del DOM, sin los elementos desactivados, ocultos o con tabindex="-1".

Uso

typescript
import { captureFocusForReturn, createFocusTrap } from '@reelkit/core';

// When your modal opens:
const restoreFocus = captureFocusForReturn();
container.focus({ preventScroll: true });
const releaseTrap = createFocusTrap(container);

// When the modal closes:
releaseTrap();
restoreFocus();

Utilidades de vídeo

Utilidades independientes del framework para compartir la reproducción de vídeo entre slides. Las usan internamente @reelkit/react-reel-player y @reelkit/react-lightbox, y están disponibles para bindings de otros frameworks.

ExportTipoDescripción
captureFrame(video: HTMLVideoElement) => string | nullCaptura el fotograma actual del vídeo como una data URL en JPEG. Devuelve null ante errores de origen cruzado.
createSharedVideo(config: SharedVideoConfig) => SharedVideoInstanceCrea un singleton de vídeo compartido con su propio ámbito, con mapas de la posición de reproducción y de los fotogramas capturados. Cada consumidor recibe una instancia aislada para que el sonido no se corte en iOS.
syncVideoObjectFit(video: HTMLVideoElement, fallbackIsVertical: boolean) => DisposerMantiene video.style.objectFit acorde con la orientación real del vídeo. Aplica al momento el valor de respaldo (según la relación de aspecto declarada) y, en loadedmetadata, lee los videoWidth / videoHeight reales y cambia a 'cover' en vertical y a 'contain' en horizontal. Aguanta metadatos declarados erróneos.

Estado en la URL

Refleja un parámetro de la query en una señal y viceversa. Dos ejes, una tarea cada uno: un codec es el formato (texto del parámetro ↔ una identidad estable) y un locator es la búsqueda (dónde está esa identidad en la colección).

ExportTipoDescripción
createUrlStateController({ param, adapter?, codec?, locator? }) => UrlStateControllerRefleja un parámetro de la query en una señal y escribe los cambios de vuelta en la URL. La primera escritura de un parámetro ausente añade una entrada al historial; las siguientes la sustituyen. Con un codec o un locator también deriva position: Signal<Pos | null>, aplica el cierre al abrir y cerrar y limpia solo un parámetro que no nombra ningún slide, así que cada binding se suscribe en lugar de volver a derivarlo. Escribir una posición con el overlay cerrado lo abre al momento, sin esperar a que el adaptador confirme la escritura; UrlChange indica cuándo un cierre vuelve atrás en el historial y cuándo limpia en el sitio.
createHistoryAdapter() => UrlAdapterAdaptador por defecto sobre la History API. Una aplicación con router debería inyectar el suyo; si no, la ubicación del router queda desfasada y su siguiente navegación pierde el parámetro.
indexCodecUrlCodec<number>Lee ?photo=3 como el slide 3. Pásalo para derivar el índice sin escribir un codec propio. Para una lista infinita o paginada, pasa locator en su lugar: el parámetro se mantiene mientras la promesa está pendiente, así que un enlace directo a una página sin cargar no se borra a mitad de la petición.
createIndexLocator(countGetter: () => number) => UrlLocator<number>El locator por índice por defecto: la posición de un slide se corresponde consigo misma, limitada por el recuento actual que devuelve el getter. Un índice fuera de rango da null, así que un ?photo=99 desfasado se limpia solo de la URL; se rechaza en lugar de ajustarse al slide más cercano, que abriría uno que la URL nunca nombró. Es un getter y no un número, así que el límite lee el tamaño actual en cada búsqueda mientras crece una galería paginada.
urlIndexKey(countGetter, locateAsync?) => UrlKey<number>El par a juego para una galería por índice: indexCodec más un createIndexLocator ligado al tamaño de la galería. Pásalo con spread ({ param, ...urlIndexKey(() => count) }) para que el codec no se desajuste del locator. Pasa un segundo argumento locateAsync para un feed paginado con ventana: carga páginas hasta el índice buscado si no lo encuentra y después lo devuelve.
urlIndexTwoAxisKey(opts) => UrlKey<TwoAxisIdentity, TwoAxisPosition>Como urlIndexKey pero para un reproductor con dos ejes: un único parámetro ?p=<outer>.<inner> con punto obligatorio que se resuelve en un TwoAxisPosition { outer, inner }. Opciones (UrlIndexTwoAxisKeyOptions): outerCount, innerCounts, outerCodec/outerLocator opcionales para el eje exterior, y innerCodec/innerLocate/innerIdentify para apuntar también al eje interior por id. Cada eje usa por defecto un índice acotado. Es la base del Stories Player controlado por la URL.
createStableIdCodec(hashCodec?: UrlCodec<string>) => UrlCodec<string>El formato por id estable, exportado para combinarlo: el texto del parámetro es el id del elemento, tal cual o transformado con hashCodec (pasa base64UrlCodec para usar base64url reversible). Es el equivalente de indexCodec para ids estables: combínalo con un locator propio en lugar de usar todo urlStableIdKey.
base64UrlCodecUrlCodec<string>El mecanismo de ofuscación listo para una clave por id estable: base64url reversible (alfabeto seguro para URLs, sin relleno, UTF-8), no un hash criptográfico. Pásalo como hashCodec para ocultar el id en la URL, o implementa tu propio UrlCodec<string> para usar otro esquema.
createStableIdLocator(items, locateAsync?) => UrlLocator<string, number>La búsqueda por id estable, exportada para combinarla: recorre items() en busca de un id que coincida; un id que ya no existe da null y se limpia solo. El locateAsync opcional pagina un feed con ventana. Es el equivalente de createIndexLocator para ids estables.
urlStableIdKey(opts) => UrlKey<string, number>Apunta a los elementos de una galería por su id estable (?photo=<id>) en lugar de por su posición, así que un marcador sobrevive a que la lista se reordene. Opciones (UrlStableIdKeyOptions): items (un getter actual), hashCodec opcional (pasa base64UrlCodec) para transformar el id en la URL, y locateAsync opcional para un feed paginado con ventana (carga hasta que aparece el id y después devuelve su índice). Prefiérela a urlIndexKey siempre que la lista pueda cambiar bajo un enlace compartido.
urlStableIdTwoAxisKey(opts) => UrlKey<TwoAxisIdentity<string>, TwoAxisPosition>El equivalente con dos ejes: el eje exterior por id estable y el interior por índice local (?story=user_42.3). Pasa innerItems en lugar de innerCounts para apuntar también al interior por id (?story=user_42.photo_7); hashCodec (por ejemplo base64UrlCodec) transforma los dos ids. Opciones UrlStableIdTwoAxisKeyOptions (interior por índice) o UrlStableIdTwoAxisIdInnerOptions (interior por id); los tipos de los elementos cumplen Identified ({ id: string }).
UrlCodec<Id>{ decode(raw) => Id | null; encode(id) => string }El formato: texto del parámetro ↔ una identidad estable, sin conocer la colección. Si decode devuelve null, el texto está mal formado.
UrlLocator<Id>{ locate(id) => number | null; locateAsync?(id) => Promise<number | null>; identify(index) => id }La búsqueda: dónde está la identidad en la colección. locate es síncrono, locateAsync es su alternativa para una lista paginada e identify convierte un índice en una identidad al escribir.
UrlKey<Id>{ codec: UrlCodec<Id>; locator: UrlLocator<Id> }El par a juego de codec y locator para un parámetro. Comparten el mismo Id y siempre van juntos: el codec escribe la identidad en la URL y el locator encuentra dónde está, así que crearlos como par es lo que evita que se contradigan.
UrlAdapter{ read, subscribe, push, replace, getState, goBack }El punto de inyección para un router. Una aplicación con router debe pasar uno, o su propia ubicación queda desfasada. El listener de subscribe acepta un UrlChange opcional; llamarlo sin nada siempre es válido y significa que el adaptador no sabe cómo llegó a ser actual esa entrada.
UrlChange{ kind?: 'push' | 'replace' | 'pop' }Lo que sabe un adaptador de la navegación que acaba de ocurrir. Indica push solo en una navegación que haya hecho el propio router en la misma página; es el único caso en que cerrar puede quitar la entrada del historial. Sin esa certeza nunca se reclama la entrada y cerrar limpia el parámetro en el sitio, dejando una copia de la página en el historial en lugar de arriesgarse a salir del sitio.
UrlStateOptions<Id>{ param: string; adapter?: UrlAdapter; codec?: UrlCodec<Id>; locator?: UrlLocator<Id> }Las opciones que recibe createUrlStateController, exportadas para que un consumidor pueda tipar una configuración montada por separado antes de pasarla.

Elementos ya vistos

Guarda hasta dónde llegó alguien con la misma clave que la barra de direcciones: una entrada es el propio texto del parámetro y se lee con el mismo codec y locator.

ExportTipoDescripción
createViewedStateController(options) => ViewedStateController<Pos>Recuerda hasta dónde llegó alguien y lo guarda con el mismo texto que llevaría un parámetro de la URL. Recibe el mismo par codec/locator que usa la barra de direcciones, más storageKey, storage opcional, trackOf (una entrada por grupo) y progressOf. No lee nada hasta attach(), así que es seguro prerrenderizarlo.
twoAxisViewedTracking{ trackOf, progressOf }El par de seguimiento para un reproductor con dos ejes: una entrada por cada elemento exterior, con el índice interior como medida del avance. Pásalo con spread junto a una clave de dos ejes.
createLocalStorageAdapter() => StorageAdapterEl almacenamiento por defecto. También hay createSessionStorageAdapter para un estado que no debe durar más que la pestaña, y createMemoryStorageAdapter para tests y renderizado en el servidor. Cada uno absorbe sus propios fallos: una cuota agotada pierde esa escritura y nada más.
ViewedStateController<Pos>{ entries; resolve(track); record(position); forget(track?); attach() }entries es una señal de pista → texto guardado, así que un anillo se repinta cuando se registra una posición aquí o en otra pestaña. resolve ejecuta el ciclo completo de la clave en cada llamada.
ViewedStateOptions<Id, Pos>{ storageKey; codec; locator; storage?; trackOf?; progressOf; ttlMs?; maxTracks? }Las opciones que recibe createViewedStateController, exportadas para que un consumidor pueda tipar una configuración montada por separado antes de pasarla. progressOf solo es opcional con una posición por índice simple, que ya es su propia medida del avance; cualquier otra posición debe indicar qué número comparar, y el tipo lo exige. ttlMs activa la caducidad: una pista se olvida ese tiempo después de su último registro, y registrarla de nuevo reinicia su reloj. maxTracks guarda como mucho ese número de pistas y descarta la registrada hace más tiempo en la siguiente escritura.
StorageAdapter{ read(key); write(key, value); subscribe?(key, listener) }El punto de inyección para una capa de almacenamiento. Sin subscribe, el almacén funciona igual pero sin sincronizar entre pestañas.