"use client"; /** * Next.js video components and hooks for the asset caching module */ import { useEffect, useState } from "react"; import { AssetLoader, CacheOptions } from "@shopkit/asset-cache"; /** * Hook to use a cached video * @param src Video source URL * @param options Caching options * @returns Video URL and loading state */ export function useAssetCacheVideo( src: string, options?: CacheOptions ): { videoUrl: string | null; isLoading: boolean; error: Error | null; } { const [videoUrl, setVideoUrl] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let isMounted = true; const loadVideo = async () => { try { setIsLoading(true); // Check if the video is cached const isCached = await AssetLoader.isCached(src); if (isCached) { // Load from cache const result = await AssetLoader.load(src, options); if (result.success && isMounted && result.data) { const url = URL.createObjectURL(result.data); setVideoUrl(url); setError(null); } } else { // Not cached, use original URL and cache for next time setVideoUrl(src); AssetLoader.preload(src, options).catch(() => { // Ignore caching errors }); } } catch (err) { if (isMounted) { setError(err instanceof Error ? err : new Error(String(err))); setVideoUrl(src); // Fallback to original URL } } finally { if (isMounted) { setIsLoading(false); } } }; loadVideo(); return () => { isMounted = false; // Revoke object URL if it exists if (videoUrl && videoUrl !== src) { URL.revokeObjectURL(videoUrl); } }; }, [src, options]); return { videoUrl, isLoading, error }; }