@djangocfg/ui-nextjs 2.1.66 → 2.1.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/package.json +8 -6
  2. package/src/stores/index.ts +8 -0
  3. package/src/stores/mediaCache.ts +464 -0
  4. package/src/tools/AudioPlayer/@refactoring/00-PLAN.md +148 -0
  5. package/src/tools/AudioPlayer/@refactoring/01-TYPES.md +301 -0
  6. package/src/tools/AudioPlayer/@refactoring/02-HOOKS.md +281 -0
  7. package/src/tools/AudioPlayer/@refactoring/03-CONTEXT.md +328 -0
  8. package/src/tools/AudioPlayer/@refactoring/04-COMPONENTS.md +251 -0
  9. package/src/tools/AudioPlayer/@refactoring/05-EFFECTS.md +427 -0
  10. package/src/tools/AudioPlayer/@refactoring/06-UTILS-AND-INDEX.md +193 -0
  11. package/src/tools/AudioPlayer/@refactoring/07-EXECUTION-CHECKLIST.md +146 -0
  12. package/src/tools/AudioPlayer/README.md +35 -11
  13. package/src/tools/AudioPlayer/{AudioEqualizer.tsx → components/AudioEqualizer.tsx} +29 -64
  14. package/src/tools/AudioPlayer/{AudioPlayer.tsx → components/AudioPlayer.tsx} +22 -14
  15. package/src/tools/AudioPlayer/{AudioShortcutsPopover.tsx → components/AudioShortcutsPopover.tsx} +6 -2
  16. package/src/tools/AudioPlayer/components/ReactiveCover/AudioReactiveCover.tsx +147 -0
  17. package/src/tools/AudioPlayer/components/ReactiveCover/effects/GlowEffect.tsx +110 -0
  18. package/src/tools/AudioPlayer/components/ReactiveCover/effects/MeshEffect.tsx +58 -0
  19. package/src/tools/AudioPlayer/components/ReactiveCover/effects/OrbsEffect.tsx +45 -0
  20. package/src/tools/AudioPlayer/components/ReactiveCover/effects/SpotlightEffect.tsx +82 -0
  21. package/src/tools/AudioPlayer/components/ReactiveCover/effects/index.ts +8 -0
  22. package/src/tools/AudioPlayer/components/ReactiveCover/index.ts +6 -0
  23. package/src/tools/AudioPlayer/{SimpleAudioPlayer.tsx → components/SimpleAudioPlayer.tsx} +12 -7
  24. package/src/tools/AudioPlayer/{VisualizationToggle.tsx → components/VisualizationToggle.tsx} +2 -6
  25. package/src/tools/AudioPlayer/components/index.ts +21 -0
  26. package/src/tools/AudioPlayer/context/AudioProvider.tsx +292 -0
  27. package/src/tools/AudioPlayer/context/index.ts +11 -0
  28. package/src/tools/AudioPlayer/context/selectors.ts +96 -0
  29. package/src/tools/AudioPlayer/hooks/index.ts +29 -0
  30. package/src/tools/AudioPlayer/hooks/useAudioAnalysis.ts +110 -0
  31. package/src/tools/AudioPlayer/{useAudioHotkeys.ts → hooks/useAudioHotkeys.ts} +11 -4
  32. package/src/tools/AudioPlayer/hooks/useSharedWebAudio.ts +106 -0
  33. package/src/tools/AudioPlayer/{useAudioVisualization.tsx → hooks/useVisualization.tsx} +11 -5
  34. package/src/tools/AudioPlayer/index.ts +104 -49
  35. package/src/tools/AudioPlayer/types/audio.ts +107 -0
  36. package/src/tools/AudioPlayer/{types.ts → types/components.ts} +20 -84
  37. package/src/tools/AudioPlayer/types/effects.ts +73 -0
  38. package/src/tools/AudioPlayer/types/index.ts +35 -0
  39. package/src/tools/AudioPlayer/utils/formatTime.ts +10 -0
  40. package/src/tools/AudioPlayer/utils/index.ts +5 -0
  41. package/src/tools/ImageViewer/@refactoring/00-PLAN.md +71 -0
  42. package/src/tools/ImageViewer/@refactoring/01-TYPES.md +121 -0
  43. package/src/tools/ImageViewer/@refactoring/02-UTILS.md +143 -0
  44. package/src/tools/ImageViewer/@refactoring/03-HOOKS.md +261 -0
  45. package/src/tools/ImageViewer/@refactoring/04-COMPONENTS.md +427 -0
  46. package/src/tools/ImageViewer/@refactoring/05-EXECUTION-CHECKLIST.md +126 -0
  47. package/src/tools/ImageViewer/README.md +16 -3
  48. package/src/tools/ImageViewer/components/ImageInfo.tsx +44 -0
  49. package/src/tools/ImageViewer/components/ImageToolbar.tsx +150 -0
  50. package/src/tools/ImageViewer/components/ImageViewer.tsx +235 -0
  51. package/src/tools/ImageViewer/components/index.ts +7 -0
  52. package/src/tools/ImageViewer/hooks/index.ts +9 -0
  53. package/src/tools/ImageViewer/hooks/useImageLoading.ts +153 -0
  54. package/src/tools/ImageViewer/hooks/useImageTransform.ts +101 -0
  55. package/src/tools/ImageViewer/index.ts +47 -3
  56. package/src/tools/ImageViewer/types.ts +75 -0
  57. package/src/tools/ImageViewer/utils/constants.ts +59 -0
  58. package/src/tools/ImageViewer/utils/index.ts +16 -0
  59. package/src/tools/ImageViewer/utils/lqip.ts +47 -0
  60. package/src/tools/VideoPlayer/@refactoring/00-PLAN.md +91 -0
  61. package/src/tools/VideoPlayer/@refactoring/01-TYPES.md +284 -0
  62. package/src/tools/VideoPlayer/@refactoring/02-UTILS.md +141 -0
  63. package/src/tools/VideoPlayer/@refactoring/03-HOOKS.md +178 -0
  64. package/src/tools/VideoPlayer/@refactoring/04-COMPONENTS.md +95 -0
  65. package/src/tools/VideoPlayer/@refactoring/05-EXECUTION-CHECKLIST.md +139 -0
  66. package/src/tools/VideoPlayer/README.md +26 -10
  67. package/src/tools/VideoPlayer/{VideoControls.tsx → components/VideoControls.tsx} +8 -9
  68. package/src/tools/VideoPlayer/{VideoErrorFallback.tsx → components/VideoErrorFallback.tsx} +2 -2
  69. package/src/tools/VideoPlayer/{VideoPlayer.tsx → components/VideoPlayer.tsx} +4 -5
  70. package/src/tools/VideoPlayer/components/index.ts +14 -0
  71. package/src/tools/VideoPlayer/context/VideoPlayerContext.tsx +52 -0
  72. package/src/tools/VideoPlayer/context/index.ts +8 -0
  73. package/src/tools/VideoPlayer/hooks/index.ts +9 -0
  74. package/src/tools/VideoPlayer/hooks/useVideoPositionCache.ts +109 -0
  75. package/src/tools/VideoPlayer/index.ts +29 -20
  76. package/src/tools/VideoPlayer/providers/StreamProvider.tsx +118 -28
  77. package/src/tools/VideoPlayer/providers/VidstackProvider.tsx +89 -11
  78. package/src/tools/VideoPlayer/types/index.ts +38 -0
  79. package/src/tools/VideoPlayer/types/player.ts +116 -0
  80. package/src/tools/VideoPlayer/types/provider.ts +93 -0
  81. package/src/tools/VideoPlayer/types/sources.ts +97 -0
  82. package/src/tools/VideoPlayer/utils/fileSource.ts +78 -0
  83. package/src/tools/VideoPlayer/utils/index.ts +11 -0
  84. package/src/tools/VideoPlayer/utils/resolvers.ts +75 -0
  85. package/src/tools/index.ts +10 -0
  86. package/src/tools/AudioPlayer/AudioReactiveCover.tsx +0 -389
  87. package/src/tools/AudioPlayer/context.tsx +0 -426
  88. package/src/tools/ImageViewer/ImageViewer.tsx +0 -416
  89. package/src/tools/VideoPlayer/VideoPlayerContext.tsx +0 -125
  90. package/src/tools/VideoPlayer/types.ts +0 -367
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Player configuration types
3
+ */
4
+
5
+ import type React from 'react';
6
+ import type { VideoSourceUnion } from './sources';
7
+
8
+ // =============================================================================
9
+ // Player Mode
10
+ // =============================================================================
11
+
12
+ /** Player mode - determines which provider to use */
13
+ export type PlayerMode =
14
+ | 'auto' // Auto-select based on source type
15
+ | 'vidstack' // Force Vidstack (full-featured)
16
+ | 'native' // Force native HTML5 <video>
17
+ | 'streaming'; // Force streaming provider
18
+
19
+ // =============================================================================
20
+ // Player Props
21
+ // =============================================================================
22
+
23
+ /** Aspect ratio options */
24
+ export type AspectRatioValue = number | 'auto' | 'fill';
25
+
26
+ /** Common player settings */
27
+ export interface CommonPlayerSettings {
28
+ /** Auto-play video */
29
+ autoPlay?: boolean;
30
+ /** Mute video by default */
31
+ muted?: boolean;
32
+ /** Loop video */
33
+ loop?: boolean;
34
+ /** Play video inline on mobile */
35
+ playsInline?: boolean;
36
+ /** Show player controls */
37
+ controls?: boolean;
38
+ /**
39
+ * Aspect ratio:
40
+ * - number (e.g. 16/9): Fixed aspect ratio
41
+ * - 'auto': Natural video aspect ratio
42
+ * - 'fill': Fill parent container (100% width & height)
43
+ */
44
+ aspectRatio?: AspectRatioValue;
45
+ /** Preload strategy */
46
+ preload?: 'auto' | 'metadata' | 'none';
47
+ }
48
+
49
+ /** Common player events */
50
+ export interface CommonPlayerEvents {
51
+ onPlay?: () => void;
52
+ onPause?: () => void;
53
+ onEnded?: () => void;
54
+ onError?: (error: string) => void;
55
+ onLoadStart?: () => void;
56
+ onCanPlay?: () => void;
57
+ onTimeUpdate?: (currentTime: number, duration: number) => void;
58
+ /** Called when buffering progress changes (buffered seconds, total duration) */
59
+ onBufferProgress?: (buffered: number, duration: number) => void;
60
+ }
61
+
62
+ /** Error fallback render props */
63
+ export interface ErrorFallbackProps {
64
+ error: string;
65
+ retry?: () => void;
66
+ }
67
+
68
+ /** Main VideoPlayer props */
69
+ export interface VideoPlayerProps extends CommonPlayerSettings, CommonPlayerEvents {
70
+ /** Video source configuration */
71
+ source: VideoSourceUnion;
72
+ /** Player mode (default: 'auto') */
73
+ mode?: PlayerMode;
74
+ /** Player theme (Vidstack only) */
75
+ theme?: 'default' | 'minimal' | 'modern';
76
+ /** Show video info below player */
77
+ showInfo?: boolean;
78
+ /** Container className */
79
+ className?: string;
80
+ /** Video element className (native/streaming only) */
81
+ videoClassName?: string;
82
+ /** Disable right-click context menu */
83
+ disableContextMenu?: boolean;
84
+ /** Show loading spinner */
85
+ showPreloader?: boolean;
86
+ /** Preloader timeout in ms */
87
+ preloaderTimeout?: number;
88
+ /** Custom error fallback UI */
89
+ errorFallback?: React.ReactNode | ((props: ErrorFallbackProps) => React.ReactNode);
90
+ }
91
+
92
+ /** VideoPlayer ref methods */
93
+ export interface VideoPlayerRef {
94
+ /** Play video */
95
+ play: () => Promise<void> | void;
96
+ /** Pause video */
97
+ pause: () => void;
98
+ /** Toggle play/pause */
99
+ togglePlay: () => void;
100
+ /** Seek to time in seconds */
101
+ seekTo: (time: number) => void;
102
+ /** Set volume (0-1) */
103
+ setVolume: (volume: number) => void;
104
+ /** Toggle mute */
105
+ toggleMute: () => void;
106
+ /** Enter fullscreen */
107
+ enterFullscreen: () => void;
108
+ /** Exit fullscreen */
109
+ exitFullscreen: () => void;
110
+ /** Current playback time in seconds */
111
+ readonly currentTime: number;
112
+ /** Video duration in seconds */
113
+ readonly duration: number;
114
+ /** Whether video is paused */
115
+ readonly paused: boolean;
116
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Provider-specific types
3
+ */
4
+
5
+ import type React from 'react';
6
+ import type { VideoSourceUnion, UrlSource, YouTubeSource, VimeoSource, HLSSource, DASHSource, StreamSource, BlobSource, DataUrlSource } from './sources';
7
+ import type { CommonPlayerSettings, CommonPlayerEvents, ErrorFallbackProps } from './player';
8
+
9
+ // =============================================================================
10
+ // Provider Props
11
+ // =============================================================================
12
+
13
+ /** Props passed to Vidstack provider */
14
+ export interface VidstackProviderProps extends CommonPlayerSettings, CommonPlayerEvents {
15
+ source: UrlSource | YouTubeSource | VimeoSource | HLSSource | DASHSource;
16
+ theme?: 'default' | 'minimal' | 'modern';
17
+ showInfo?: boolean;
18
+ className?: string;
19
+ errorFallback?: React.ReactNode | ((props: ErrorFallbackProps) => React.ReactNode);
20
+ }
21
+
22
+ /** Props passed to Native provider */
23
+ export interface NativeProviderProps extends CommonPlayerSettings, CommonPlayerEvents {
24
+ source: UrlSource | DataUrlSource;
25
+ className?: string;
26
+ videoClassName?: string;
27
+ disableContextMenu?: boolean;
28
+ showPreloader?: boolean;
29
+ preloaderTimeout?: number;
30
+ }
31
+
32
+ /** Props passed to Stream provider */
33
+ export interface StreamProviderProps extends CommonPlayerSettings, CommonPlayerEvents {
34
+ source: StreamSource | BlobSource | DataUrlSource;
35
+ className?: string;
36
+ videoClassName?: string;
37
+ disableContextMenu?: boolean;
38
+ showPreloader?: boolean;
39
+ preloaderTimeout?: number;
40
+ errorFallback?: React.ReactNode | ((props: ErrorFallbackProps) => React.ReactNode);
41
+ }
42
+
43
+ // =============================================================================
44
+ // File Source Helper Types
45
+ // =============================================================================
46
+
47
+ /** Options for resolving file source */
48
+ export interface ResolveFileSourceOptions {
49
+ /** File content - can be data URL string or binary ArrayBuffer */
50
+ content: string | ArrayBuffer | null | undefined;
51
+ /** File path for streaming */
52
+ path: string;
53
+ /** MIME type of the file */
54
+ mimeType?: string;
55
+ /** Session ID for authenticated streaming */
56
+ sessionId?: string | null;
57
+ /** Load method hint - 'http_stream' enables streaming mode */
58
+ loadMethod?: 'http_stream' | 'rpc' | 'unspecified' | 'skip' | string;
59
+ /** Function to generate stream URL (required for streaming) */
60
+ getStreamUrl?: (sessionId: string, path: string) => string;
61
+ /** Optional title */
62
+ title?: string;
63
+ /** Optional poster */
64
+ poster?: string;
65
+ }
66
+
67
+ // =============================================================================
68
+ // Context Types
69
+ // =============================================================================
70
+
71
+ export interface VideoPlayerContextValue {
72
+ /** Function to generate stream URL (for HTTP Range streaming) */
73
+ getStreamUrl?: (sessionId: string, path: string) => string;
74
+ /** Current session ID */
75
+ sessionId?: string | null;
76
+ }
77
+
78
+ export interface VideoPlayerProviderProps extends VideoPlayerContextValue {
79
+ children: React.ReactNode;
80
+ }
81
+
82
+ /** Simplified stream source (uses context for getStreamUrl) */
83
+ export interface SimpleStreamSource {
84
+ type: 'stream';
85
+ /** File path on server */
86
+ path: string;
87
+ /** Session ID (optional, uses context if not provided) */
88
+ sessionId?: string;
89
+ /** MIME type for the video */
90
+ mimeType?: string;
91
+ title?: string;
92
+ poster?: string;
93
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Video source type definitions
3
+ */
4
+
5
+ // =============================================================================
6
+ // Source Types - Different ways to provide video content
7
+ // =============================================================================
8
+
9
+ /** Simple URL source (mp4, webm, etc.) */
10
+ export interface UrlSource {
11
+ type: 'url';
12
+ url: string;
13
+ title?: string;
14
+ poster?: string;
15
+ }
16
+
17
+ /** YouTube embed source */
18
+ export interface YouTubeSource {
19
+ type: 'youtube';
20
+ /** YouTube video ID (11 characters) */
21
+ id: string;
22
+ title?: string;
23
+ poster?: string;
24
+ }
25
+
26
+ /** Vimeo embed source */
27
+ export interface VimeoSource {
28
+ type: 'vimeo';
29
+ /** Vimeo video ID */
30
+ id: string;
31
+ title?: string;
32
+ poster?: string;
33
+ }
34
+
35
+ /** HLS streaming source */
36
+ export interface HLSSource {
37
+ type: 'hls';
38
+ /** URL to .m3u8 manifest */
39
+ url: string;
40
+ title?: string;
41
+ poster?: string;
42
+ }
43
+
44
+ /** DASH streaming source */
45
+ export interface DASHSource {
46
+ type: 'dash';
47
+ /** URL to .mpd manifest */
48
+ url: string;
49
+ title?: string;
50
+ poster?: string;
51
+ }
52
+
53
+ /** HTTP Range streaming source (for large files with auth) */
54
+ export interface StreamSource {
55
+ type: 'stream';
56
+ /** Session ID for authorization */
57
+ sessionId: string;
58
+ /** File path on server */
59
+ path: string;
60
+ /** Function to generate stream URL */
61
+ getStreamUrl: (sessionId: string, path: string) => string;
62
+ /** MIME type for the video */
63
+ mimeType?: string;
64
+ title?: string;
65
+ poster?: string;
66
+ }
67
+
68
+ /** Binary data source (ArrayBuffer) */
69
+ export interface BlobSource {
70
+ type: 'blob';
71
+ /** Video data as ArrayBuffer */
72
+ data: ArrayBuffer;
73
+ /** MIME type (default: video/mp4) */
74
+ mimeType?: string;
75
+ title?: string;
76
+ poster?: string;
77
+ }
78
+
79
+ /** Base64 data URL source */
80
+ export interface DataUrlSource {
81
+ type: 'data-url';
82
+ /** Base64 encoded data URL */
83
+ data: string;
84
+ title?: string;
85
+ poster?: string;
86
+ }
87
+
88
+ /** Union of all source types */
89
+ export type VideoSourceUnion =
90
+ | UrlSource
91
+ | YouTubeSource
92
+ | VimeoSource
93
+ | HLSSource
94
+ | DASHSource
95
+ | StreamSource
96
+ | BlobSource
97
+ | DataUrlSource;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * File source resolution utilities
3
+ */
4
+
5
+ import type { VideoSourceUnion, ResolveFileSourceOptions } from '../types';
6
+
7
+ /**
8
+ * Resolve file content to VideoSourceUnion
9
+ * Useful for FileWorkspace/file manager integrations
10
+ *
11
+ * @example
12
+ * const source = resolveFileSource({
13
+ * content: file.content,
14
+ * path: file.path,
15
+ * mimeType: file.mimeType,
16
+ * sessionId: sessionId,
17
+ * loadMethod: file.loadMethod,
18
+ * getStreamUrl: terminalClient.terminal_media.streamStreamRetrieveUrl
19
+ * });
20
+ *
21
+ * <VideoPlayer source={source} />
22
+ */
23
+ export function resolveFileSource(options: ResolveFileSourceOptions): VideoSourceUnion | null {
24
+ const {
25
+ content,
26
+ path,
27
+ mimeType,
28
+ sessionId,
29
+ loadMethod,
30
+ getStreamUrl,
31
+ title,
32
+ poster,
33
+ } = options;
34
+
35
+ const contentSize = content
36
+ ? typeof content === 'string'
37
+ ? content.length
38
+ : content.byteLength
39
+ : 0;
40
+ const hasContent = contentSize > 0;
41
+
42
+ // Priority 1: HTTP Range streaming for large files
43
+ if (loadMethod === 'http_stream' && !hasContent && sessionId && getStreamUrl) {
44
+ return {
45
+ type: 'stream',
46
+ sessionId,
47
+ path,
48
+ getStreamUrl,
49
+ mimeType,
50
+ title,
51
+ poster,
52
+ };
53
+ }
54
+
55
+ // Priority 2: Data URL (base64 string)
56
+ if (typeof content === 'string' && hasContent) {
57
+ return {
58
+ type: 'data-url',
59
+ data: content,
60
+ title,
61
+ poster,
62
+ };
63
+ }
64
+
65
+ // Priority 3: ArrayBuffer → Blob
66
+ if (content instanceof ArrayBuffer && hasContent) {
67
+ return {
68
+ type: 'blob',
69
+ data: content,
70
+ mimeType: mimeType || 'video/mp4',
71
+ title,
72
+ poster,
73
+ };
74
+ }
75
+
76
+ // No valid content
77
+ return null;
78
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * VideoPlayer utilities - Public API
3
+ */
4
+
5
+ export {
6
+ resolvePlayerMode,
7
+ isSimpleStreamSource,
8
+ resolveStreamSource,
9
+ } from './resolvers';
10
+
11
+ export { resolveFileSource } from './fileSource';
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Video source and player mode resolvers
3
+ */
4
+
5
+ import type { VideoSourceUnion, PlayerMode, SimpleStreamSource, StreamSource, VideoPlayerContextValue } from '../types';
6
+
7
+ /**
8
+ * Determine which provider to use based on source type
9
+ */
10
+ export function resolvePlayerMode(
11
+ source: VideoSourceUnion,
12
+ mode: PlayerMode = 'auto'
13
+ ): 'vidstack' | 'native' | 'streaming' {
14
+ if (mode !== 'auto') {
15
+ return mode;
16
+ }
17
+
18
+ switch (source.type) {
19
+ case 'youtube':
20
+ case 'vimeo':
21
+ case 'hls':
22
+ case 'dash':
23
+ return 'vidstack';
24
+
25
+ case 'stream':
26
+ case 'blob':
27
+ return 'streaming';
28
+
29
+ case 'data-url':
30
+ case 'url':
31
+ default:
32
+ return 'native';
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Check if source is a simplified stream source (without getStreamUrl)
38
+ */
39
+ export function isSimpleStreamSource(
40
+ source: VideoSourceUnion | SimpleStreamSource
41
+ ): source is SimpleStreamSource {
42
+ return source.type === 'stream' && !('getStreamUrl' in source);
43
+ }
44
+
45
+ /**
46
+ * Resolve simplified stream source to full stream source using context
47
+ */
48
+ export function resolveStreamSource(
49
+ source: SimpleStreamSource,
50
+ context: VideoPlayerContextValue | null
51
+ ): StreamSource | null {
52
+ if (!context?.getStreamUrl) {
53
+ console.warn(
54
+ 'VideoPlayer: Stream source requires getStreamUrl. ' +
55
+ 'Either provide it in source or wrap with VideoPlayerProvider.'
56
+ );
57
+ return null;
58
+ }
59
+
60
+ const sessionId = source.sessionId || context.sessionId;
61
+ if (!sessionId) {
62
+ console.warn('VideoPlayer: Stream source requires sessionId.');
63
+ return null;
64
+ }
65
+
66
+ return {
67
+ type: 'stream',
68
+ sessionId,
69
+ path: source.path,
70
+ getStreamUrl: context.getStreamUrl,
71
+ mimeType: source.mimeType,
72
+ title: source.title,
73
+ poster: source.poster,
74
+ };
75
+ }
@@ -125,3 +125,13 @@ export type {
125
125
  // Export ImageViewer
126
126
  export { ImageViewer } from './ImageViewer';
127
127
  export type { ImageViewerProps, ImageFile } from './ImageViewer';
128
+
129
+ // Export Media Cache Store
130
+ export {
131
+ useMediaCacheStore,
132
+ useImageCache,
133
+ useAudioCache,
134
+ useVideoCache,
135
+ useBlobUrlCleanup,
136
+ generateContentKey,
137
+ } from '../stores/mediaCache';