@therealtinhtute/baroiplayer 1.0.0

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 (244) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +384 -0
  3. package/dist/context/media.js +2 -0
  4. package/dist/context/media.js.map +1 -0
  5. package/dist/context/media.mjs +15 -0
  6. package/dist/context/media.mjs.map +1 -0
  7. package/dist/context/store.js +2 -0
  8. package/dist/context/store.js.map +1 -0
  9. package/dist/context/store.mjs +5 -0
  10. package/dist/context/store.mjs.map +1 -0
  11. package/dist/context-BMteAJDN.js +1140 -0
  12. package/dist/context-BMteAJDN.js.map +1 -0
  13. package/dist/context-DCJ_scmO.cjs +23 -0
  14. package/dist/context-DCJ_scmO.cjs.map +1 -0
  15. package/dist/core-events-B5W_j8yU.js +480 -0
  16. package/dist/core-events-B5W_j8yU.js.map +1 -0
  17. package/dist/core-events-CN0-Vhhq.cjs +2 -0
  18. package/dist/core-events-CN0-Vhhq.cjs.map +1 -0
  19. package/dist/core-plugins-Bq9KLany.js +696 -0
  20. package/dist/core-plugins-Bq9KLany.js.map +1 -0
  21. package/dist/core-plugins-CPDSHMiQ.cjs +2 -0
  22. package/dist/core-plugins-CPDSHMiQ.cjs.map +1 -0
  23. package/dist/core.js +37 -0
  24. package/dist/core.js.map +1 -0
  25. package/dist/core.mjs +1217 -0
  26. package/dist/core.mjs.map +1 -0
  27. package/dist/enhanced-components-DHv0MFvG.js +1073 -0
  28. package/dist/enhanced-components-DHv0MFvG.js.map +1 -0
  29. package/dist/enhanced-components-DTIObgB7.cjs +2 -0
  30. package/dist/enhanced-components-DTIObgB7.cjs.map +1 -0
  31. package/dist/hooks-C_r8wexn.cjs +4 -0
  32. package/dist/hooks-C_r8wexn.cjs.map +1 -0
  33. package/dist/hooks-Da2wVXlF.js +1630 -0
  34. package/dist/hooks-Da2wVXlF.js.map +1 -0
  35. package/dist/index.css +1 -0
  36. package/dist/index.js +112 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/index.mjs +6126 -0
  39. package/dist/index.mjs.map +1 -0
  40. package/dist/minimal-components-DSq5sQpy.js +2002 -0
  41. package/dist/minimal-components-DSq5sQpy.js.map +1 -0
  42. package/dist/minimal-components-DflWiihN.cjs +2 -0
  43. package/dist/minimal-components-DflWiihN.cjs.map +1 -0
  44. package/dist/minimal-components.css +1 -0
  45. package/dist/mona-loading.gif +0 -0
  46. package/dist/performance-monitor-CUW6f5ll.cjs +2 -0
  47. package/dist/performance-monitor-CUW6f5ll.cjs.map +1 -0
  48. package/dist/performance-monitor-rMW1RgV3.js +302 -0
  49. package/dist/performance-monitor-rMW1RgV3.js.map +1 -0
  50. package/dist/utils-BnscpYYd.js +2798 -0
  51. package/dist/utils-BnscpYYd.js.map +1 -0
  52. package/dist/utils-D_czS_0K.cjs +9 -0
  53. package/dist/utils-D_czS_0K.cjs.map +1 -0
  54. package/dist/utils.js +2 -0
  55. package/dist/utils.js.map +1 -0
  56. package/dist/utils.mjs +7 -0
  57. package/dist/utils.mjs.map +1 -0
  58. package/package.json +114 -0
  59. package/src/adapters/videojs-adapter.tsx +470 -0
  60. package/src/assets/mona-loading.gif +0 -0
  61. package/src/components/AnimateLoading.tsx +115 -0
  62. package/src/components/LoadingState.tsx +248 -0
  63. package/src/components/accessibility/keyboard-help-overlay.tsx +213 -0
  64. package/src/components/audio-player.tsx +85 -0
  65. package/src/components/basic/index.ts +37 -0
  66. package/src/components/enhanced/advanced-features.tsx +316 -0
  67. package/src/components/enhanced/debug-panel.tsx +422 -0
  68. package/src/components/enhanced/enhanced-controls.tsx +600 -0
  69. package/src/components/enhanced/enhanced-media-player.tsx +509 -0
  70. package/src/components/enhanced/error-handling.tsx +345 -0
  71. package/src/components/enhanced/index.ts +39 -0
  72. package/src/components/enhanced/media-player-enhanced.tsx +349 -0
  73. package/src/components/examples/basic-video-player.tsx +55 -0
  74. package/src/components/examples/custom-controls-example.tsx +63 -0
  75. package/src/components/examples/enhanced-controls-example.tsx +114 -0
  76. package/src/components/examples/enhanced-media-player-example.tsx +293 -0
  77. package/src/components/examples/loading-states-demo.tsx +142 -0
  78. package/src/components/examples/react-19-demo.tsx +381 -0
  79. package/src/components/examples/volume-orientation-demo.tsx +114 -0
  80. package/src/components/icon-demo.tsx +209 -0
  81. package/src/components/icons/index.tsx +166 -0
  82. package/src/components/icons/svg-icons/ArrowLeftIcon.tsx +18 -0
  83. package/src/components/icons/svg-icons/ArrowRightIcon.tsx +18 -0
  84. package/src/components/icons/svg-icons/AudioIcon.tsx +22 -0
  85. package/src/components/icons/svg-icons/BackwardIcon.tsx +12 -0
  86. package/src/components/icons/svg-icons/CameraIcon.tsx +19 -0
  87. package/src/components/icons/svg-icons/CheckIcon.tsx +19 -0
  88. package/src/components/icons/svg-icons/EnablePiPIcon.tsx +17 -0
  89. package/src/components/icons/svg-icons/ForwardIcon.tsx +12 -0
  90. package/src/components/icons/svg-icons/FullscreenEnterIcon.tsx +23 -0
  91. package/src/components/icons/svg-icons/FullscreenExitIcon.tsx +23 -0
  92. package/src/components/icons/svg-icons/LoadingIcon.tsx +32 -0
  93. package/src/components/icons/svg-icons/PauseIcon.tsx +23 -0
  94. package/src/components/icons/svg-icons/PlayIcon.tsx +21 -0
  95. package/src/components/icons/svg-icons/PlaybackSpeedIcon.tsx +23 -0
  96. package/src/components/icons/svg-icons/QualityIcon.tsx +21 -0
  97. package/src/components/icons/svg-icons/SettingsIcon.tsx +12 -0
  98. package/src/components/icons/svg-icons/SliderIcon.tsx +21 -0
  99. package/src/components/icons/svg-icons/SubtitleIcon.tsx +21 -0
  100. package/src/components/icons/svg-icons/SubtitleOffIcon.tsx +25 -0
  101. package/src/components/icons/svg-icons/UnPiPIcon.tsx +17 -0
  102. package/src/components/icons/svg-icons/VolumeMutedIcon.tsx +16 -0
  103. package/src/components/icons/svg-icons/VolumeOneIcon.tsx +22 -0
  104. package/src/components/icons/svg-icons/VolumeThreeIcon.tsx +16 -0
  105. package/src/components/icons/svg-icons/VolumeTwoIcon.tsx +16 -0
  106. package/src/components/legacy.tsx +93 -0
  107. package/src/components/media-metadata-display.tsx +100 -0
  108. package/src/components/media-player-audio.tsx +39 -0
  109. package/src/components/media-player-controls.tsx +226 -0
  110. package/src/components/media-player-error.tsx +163 -0
  111. package/src/components/media-player-fullscreen.tsx +109 -0
  112. package/src/components/media-player-hls.tsx +111 -0
  113. package/src/components/media-player-loading.tsx +76 -0
  114. package/src/components/media-player-play.tsx +75 -0
  115. package/src/components/media-player-root.tsx +340 -0
  116. package/src/components/media-player-seek.tsx +168 -0
  117. package/src/components/media-player-time.tsx +99 -0
  118. package/src/components/media-player-tooltip.tsx +58 -0
  119. package/src/components/media-player-video.tsx +39 -0
  120. package/src/components/media-player-volume.tsx +155 -0
  121. package/src/components/media-player.tsx +257 -0
  122. package/src/components/media-suspense.tsx +362 -0
  123. package/src/components/player-settings-form.tsx +163 -0
  124. package/src/components/react-player-wrapper.tsx +651 -0
  125. package/src/components/simple-video-player.tsx +60 -0
  126. package/src/components/ui/enhanced-seek-bar.tsx +235 -0
  127. package/src/components/ui/fullscreen-button.tsx +60 -0
  128. package/src/components/ui/media-resource-preloader.tsx +395 -0
  129. package/src/components/ui/play-button.tsx +107 -0
  130. package/src/components/ui/seek-bar.tsx +161 -0
  131. package/src/components/ui/time-display.tsx +40 -0
  132. package/src/components/ui/volume-control.tsx +143 -0
  133. package/src/components/unified/base-media-player.tsx +246 -0
  134. package/src/components/unified/media-player.tsx +75 -0
  135. package/src/components/variants/minimal/AccessibleMinimalPlayer.tsx +561 -0
  136. package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.tsx +552 -0
  137. package/src/components/variants/minimal/MinimalControls.tsx +142 -0
  138. package/src/components/variants/minimal/MinimalLoading.tsx +32 -0
  139. package/src/components/variants/minimal/MinimalMediaPlayer.tsx +315 -0
  140. package/src/components/variants/minimal/MinimalOverlay.tsx +64 -0
  141. package/src/components/variants/minimal/MinimalPlayButton.tsx +65 -0
  142. package/src/components/variants/minimal/MinimalSeekBar.tsx +150 -0
  143. package/src/components/variants/minimal/MinimalVolumeControl.tsx +80 -0
  144. package/src/components/variants/minimal/SimpleMinimalPlayer.tsx +210 -0
  145. package/src/components/variants/minimal/components/CenterPlayButton.tsx +22 -0
  146. package/src/components/variants/minimal/components/ControlBar.tsx +146 -0
  147. package/src/components/variants/minimal/components/EnhancedSettingsMenu.tsx +361 -0
  148. package/src/components/variants/minimal/components/PlaybackControls.tsx +51 -0
  149. package/src/components/variants/minimal/components/RightControls.tsx +173 -0
  150. package/src/components/variants/minimal/components/SeekBar.tsx +131 -0
  151. package/src/components/variants/minimal/components/SettingsDropdown.tsx +70 -0
  152. package/src/components/variants/minimal/components/SubtitleDisplay.tsx +21 -0
  153. package/src/components/variants/minimal/components/TimeDisplay.tsx +18 -0
  154. package/src/components/variants/minimal/components/VideoElement.tsx +40 -0
  155. package/src/components/variants/minimal/components/VolumeControl.tsx +217 -0
  156. package/src/components/variants/minimal/index.ts +23 -0
  157. package/src/components/video-player.tsx +100 -0
  158. package/src/context/error-handling.ts +394 -0
  159. package/src/context/media-context.tsx +208 -0
  160. package/src/context/media-provider.tsx +265 -0
  161. package/src/context/media-store.ts +379 -0
  162. package/src/context/persistence.ts +453 -0
  163. package/src/core/events/event-system.ts +442 -0
  164. package/src/core/events/hooks.ts +302 -0
  165. package/src/core/events/index.ts +22 -0
  166. package/src/core/events/middleware.ts +269 -0
  167. package/src/core/index.ts +22 -0
  168. package/src/core/optimization/bundle-optimizer.tsx +308 -0
  169. package/src/core/performance/cicd.ts +96 -0
  170. package/src/core/performance/index.ts +38 -0
  171. package/src/core/performance/media-loading-optimizer.ts +538 -0
  172. package/src/core/performance/performance-budgets.ts +432 -0
  173. package/src/core/performance/performance-monitor.tsx +476 -0
  174. package/src/core/performance/performance-testing.ts +459 -0
  175. package/src/core/plugins/base-plugin.ts +224 -0
  176. package/src/core/plugins/enhanced-plugin-system.ts +411 -0
  177. package/src/core/plugins/examples/analytics-plugin.ts +242 -0
  178. package/src/core/plugins/index.ts +39 -0
  179. package/src/core/plugins/registry.ts +327 -0
  180. package/src/core/plugins/types.ts +159 -0
  181. package/src/core/plugins/utils.ts +316 -0
  182. package/src/core/progressive-loading.tsx +322 -0
  183. package/src/core/providers/enhanced-hls-provider.ts +339 -0
  184. package/src/core/providers/service-provider.tsx +168 -0
  185. package/src/core/utils.tsx +38 -0
  186. package/src/features/media-session/media-session-manager.ts +429 -0
  187. package/src/features/picture-in-picture/pip-manager.ts +429 -0
  188. package/src/features/playlist/playlist-manager.ts +606 -0
  189. package/src/features/subtitles/subtitle-manager.ts +441 -0
  190. package/src/features/subtitles/subtitle-parser.ts +280 -0
  191. package/src/features/thumbnails/thumbnail-generator.ts +519 -0
  192. package/src/hooks/accessibility/index.ts +27 -0
  193. package/src/hooks/accessibility/use-accessibility-preferences.ts +188 -0
  194. package/src/hooks/accessibility/use-focus-management.ts +176 -0
  195. package/src/hooks/accessibility/use-keyboard-shortcuts.ts +144 -0
  196. package/src/hooks/accessibility/use-screen-reader.ts +182 -0
  197. package/src/hooks/core/index.ts +47 -0
  198. package/src/hooks/legacy.ts +27 -0
  199. package/src/hooks/use-enhanced-media-player.ts +468 -0
  200. package/src/hooks/use-intelligent-preloading.ts +358 -0
  201. package/src/hooks/use-keyboard-controls.ts +115 -0
  202. package/src/hooks/use-media-actions.ts +175 -0
  203. package/src/hooks/use-media-metadata.ts +89 -0
  204. package/src/hooks/use-media-optimistic.ts +270 -0
  205. package/src/hooks/use-media-player.ts +312 -0
  206. package/src/hooks/use-media-state.ts +190 -0
  207. package/src/hooks/use-memory-optimization.ts +358 -0
  208. package/src/hooks/use-optimistic-controls.ts +92 -0
  209. package/src/hooks/use-optimized-media.ts +263 -0
  210. package/src/hooks/use-touch-gestures.ts +417 -0
  211. package/src/hooks/useEnhancedSubtitles.ts +258 -0
  212. package/src/hooks/useKeyboardShortcuts.ts +74 -0
  213. package/src/hooks/useMediaControls.ts +52 -0
  214. package/src/hooks/useScreenshot.ts +57 -0
  215. package/src/hooks/useSubtitles.ts +91 -0
  216. package/src/hooks/useVideoPlayer.ts +232 -0
  217. package/src/icons/components/FullscreenIcon.tsx +37 -0
  218. package/src/icons/components/SettingsIcon.tsx +38 -0
  219. package/src/icons/components/animated/LoadingIcon.tsx +43 -0
  220. package/src/icons/components/animated/PlayPauseIcon.tsx +50 -0
  221. package/src/icons/components/media/PauseIcon.tsx +39 -0
  222. package/src/icons/components/media/PlayIcon.tsx +38 -0
  223. package/src/icons/components/volume/VolumeIcon.tsx +39 -0
  224. package/src/icons/components/volume/VolumeOffIcon.tsx +39 -0
  225. package/src/icons/index.ts +56 -0
  226. package/src/icons/provider.tsx +64 -0
  227. package/src/icons/types.ts +40 -0
  228. package/src/index-enhanced.ts +35 -0
  229. package/src/index-legacy.ts +326 -0
  230. package/src/index.css +102 -0
  231. package/src/index.ts +216 -0
  232. package/src/lib/deprecation.ts +51 -0
  233. package/src/lib/format-time.ts +37 -0
  234. package/src/lib/index.ts +3 -0
  235. package/src/lib/utils.ts +6 -0
  236. package/src/styles/globals.css +462 -0
  237. package/src/styles/minimal-player.css +589 -0
  238. package/src/styles/pixel-art.css +46 -0
  239. package/src/styles/videojs.css +100 -0
  240. package/src/test/setup.ts +79 -0
  241. package/src/types/events.ts +47 -0
  242. package/src/types/formats.ts +95 -0
  243. package/src/types/index.ts +190 -0
  244. package/src/types/videojs-plugins.d.ts +14 -0
@@ -0,0 +1,302 @@
1
+ import React, { useEffect, useRef, useCallback, useMemo, useState } from 'react'
2
+ import { EventBus, type EventHandler, type EventUnsubscriber, type EventOptions, type MediaEvents } from './event-system'
3
+
4
+ // Hook to use event bus with React
5
+ export function useEventBus(eventBus?: EventBus): EventBus {
6
+ const eventBusRef = useRef<EventBus | null>(null)
7
+
8
+ if (!eventBusRef.current) {
9
+ eventBusRef.current = eventBus || new EventBus()
10
+ }
11
+
12
+ useEffect(() => {
13
+ const currentEventBus = eventBusRef.current!
14
+
15
+ return () => {
16
+ // Cleanup on unmount
17
+ currentEventBus.destroy()
18
+ }
19
+ }, [])
20
+
21
+ return eventBusRef.current
22
+ }
23
+
24
+ // Hook to listen to events
25
+ export function useEventListener<K extends keyof MediaEvents>(
26
+ eventBus: EventBus,
27
+ type: K,
28
+ handler: EventHandler<MediaEvents[K]>,
29
+ options?: EventOptions,
30
+ deps?: React.DependencyList
31
+ ): void {
32
+ const handlerRef = useRef(handler)
33
+ const optionsRef = useRef(options)
34
+
35
+ // Update refs when dependencies change
36
+ useEffect(() => {
37
+ handlerRef.current = handler
38
+ optionsRef.current = options
39
+ })
40
+
41
+ useEffect(() => {
42
+ const unsubscribe = eventBus.on(type, handlerRef.current, optionsRef.current)
43
+ return unsubscribe
44
+ }, [eventBus, type, ...(deps || [])])
45
+ }
46
+
47
+ // Hook to emit events
48
+ export function useEventEmitter(eventBus: EventBus) {
49
+ return useCallback(<K extends keyof MediaEvents>(
50
+ type: K,
51
+ detail?: MediaEvents[K],
52
+ options?: Partial<MediaEvents[K]>
53
+ ) => {
54
+ return eventBus.emit(type, detail, options)
55
+ }, [eventBus])
56
+ }
57
+
58
+ // Hook for one-time event listeners
59
+ export function useEventOnce<K extends keyof MediaEvents>(
60
+ eventBus: EventBus,
61
+ type: K,
62
+ handler: EventHandler<MediaEvents[K]>,
63
+ deps?: React.DependencyList
64
+ ): void {
65
+ useEventListener(eventBus, type, handler, { once: true }, deps)
66
+ }
67
+
68
+ // Hook to create event handlers with automatic cleanup
69
+ export function useEventHandlers(eventBus: EventBus) {
70
+ const handlersRef = useRef<EventUnsubscriber[]>([])
71
+
72
+ const addHandler = useCallback(<K extends keyof MediaEvents>(
73
+ type: K,
74
+ handler: EventHandler<MediaEvents[K]>,
75
+ options?: EventOptions
76
+ ) => {
77
+ const unsubscribe = eventBus.on(type, handler, options)
78
+ handlersRef.current.push(unsubscribe)
79
+ return unsubscribe
80
+ }, [eventBus])
81
+
82
+ const removeAllHandlers = useCallback(() => {
83
+ handlersRef.current.forEach(unsubscribe => unsubscribe())
84
+ handlersRef.current = []
85
+ }, [])
86
+
87
+ useEffect(() => {
88
+ return removeAllHandlers
89
+ }, [removeAllHandlers])
90
+
91
+ return {
92
+ on: addHandler,
93
+ removeAll: removeAllHandlers
94
+ }
95
+ }
96
+
97
+ // Hook for event history
98
+ export function useEventHistory(
99
+ eventBus: EventBus,
100
+ filter?: (event: any) => boolean,
101
+ maxSize = 100
102
+ ) {
103
+ const historyRef = useRef<any[]>([])
104
+
105
+ useEffect(() => {
106
+ const unsubscribe = eventBus.addEventListener('*', (event) => {
107
+ if (!filter || filter(event)) {
108
+ historyRef.current.push(event)
109
+
110
+ // Limit history size
111
+ if (historyRef.current.length > maxSize) {
112
+ historyRef.current.shift()
113
+ }
114
+ }
115
+ })
116
+
117
+ return unsubscribe
118
+ }, [eventBus, filter, maxSize])
119
+
120
+ const clearHistory = useCallback(() => {
121
+ historyRef.current = []
122
+ }, [])
123
+
124
+ return {
125
+ history: historyRef.current,
126
+ clearHistory
127
+ }
128
+ }
129
+
130
+ // Hook for event metrics/analytics
131
+ export function useEventMetrics(eventBus: EventBus) {
132
+ const metricsRef = useRef<Map<string, {
133
+ count: number
134
+ lastTimestamp: number
135
+ frequency: number // events per second
136
+ }>>(new Map())
137
+
138
+ useEffect(() => {
139
+ const updateMetrics = (event: any) => {
140
+ const existing = metricsRef.current.get(event.type) || {
141
+ count: 0,
142
+ lastTimestamp: 0,
143
+ frequency: 0
144
+ }
145
+
146
+ existing.count++
147
+
148
+ if (existing.lastTimestamp > 0) {
149
+ const timeDiff = (event.timestamp - existing.lastTimestamp) / 1000 // seconds
150
+ existing.frequency = timeDiff > 0 ? 1 / timeDiff : 0
151
+ }
152
+
153
+ existing.lastTimestamp = event.timestamp
154
+ metricsRef.current.set(event.type, existing)
155
+ }
156
+
157
+ const unsubscribe = eventBus.addEventListener('*', updateMetrics)
158
+ return unsubscribe
159
+ }, [eventBus])
160
+
161
+ const getMetrics = useCallback(() => {
162
+ return Object.fromEntries(metricsRef.current.entries())
163
+ }, [])
164
+
165
+ const resetMetrics = useCallback(() => {
166
+ metricsRef.current.clear()
167
+ }, [])
168
+
169
+ return {
170
+ getMetrics,
171
+ resetMetrics
172
+ }
173
+ }
174
+
175
+ // Hook for event debugging
176
+ export function useEventDebugger(
177
+ eventBus: EventBus,
178
+ options: {
179
+ logEvents?: boolean
180
+ logMetrics?: boolean
181
+ filterEventTypes?: string[]
182
+ } = {}
183
+ ) {
184
+ const { logEvents = true, logMetrics = false, filterEventTypes } = options
185
+
186
+ useEffect(() => {
187
+ if (!logEvents) return
188
+
189
+ const unsubscribe = eventBus.addEventListener('*', (event) => {
190
+ if (filterEventTypes && !filterEventTypes.includes(event.type)) {
191
+ return
192
+ }
193
+
194
+ console.group(`🎯 Event: ${event.type}`)
195
+ console.log('Timestamp:', new Date(event.timestamp).toISOString())
196
+ console.log('Detail:', event.detail)
197
+ console.log('Bubbles:', event.bubbles)
198
+ console.log('Cancelable:', event.cancelable)
199
+ console.groupEnd()
200
+ })
201
+
202
+ return unsubscribe
203
+ }, [eventBus, logEvents, filterEventTypes])
204
+
205
+ useEffect(() => {
206
+ if (!logMetrics) return
207
+
208
+ const interval = setInterval(() => {
209
+ const listenerCount = eventBus.getListenerCount()
210
+ const eventTypes = eventBus.getEventTypes()
211
+
212
+ console.group('📊 Event Metrics')
213
+ console.log('Total Listeners:', listenerCount)
214
+ console.log('Event Types:', eventTypes.length)
215
+ console.log('Active Types:', eventTypes)
216
+ console.groupEnd()
217
+ }, 5000)
218
+
219
+ return () => clearInterval(interval)
220
+ }, [eventBus, logMetrics])
221
+ }
222
+
223
+ // Hook for conditional event handling
224
+ export function useConditionalEventListener<K extends keyof MediaEvents>(
225
+ eventBus: EventBus,
226
+ type: K,
227
+ handler: EventHandler<MediaEvents[K]>,
228
+ condition: boolean | (() => boolean),
229
+ options?: EventOptions,
230
+ deps?: React.DependencyList
231
+ ): void {
232
+ const shouldListen = useMemo(() => {
233
+ return typeof condition === 'function' ? condition() : condition
234
+ }, [condition, ...(deps || [])])
235
+
236
+ useEffect(() => {
237
+ if (!shouldListen) return
238
+
239
+ const unsubscribe = eventBus.on(type, handler, options)
240
+ return unsubscribe
241
+ }, [eventBus, type, shouldListen, ...(deps || [])])
242
+ }
243
+
244
+ // Hook for event state synchronization
245
+ export function useEventState<T>(
246
+ eventBus: EventBus,
247
+ initialValue: T,
248
+ eventMapping: Record<string, (detail: any, currentValue: T) => T>
249
+ ) {
250
+ const [state, setState] = useState<T>(initialValue)
251
+
252
+ useEffect(() => {
253
+ const unsubscribers: EventUnsubscriber[] = []
254
+
255
+ Object.entries(eventMapping).forEach(([eventType, updater]) => {
256
+ const unsubscribe = eventBus.addEventListener(eventType, (event) => {
257
+ setState(current => updater(event.detail, current))
258
+ })
259
+ unsubscribers.push(unsubscribe)
260
+ })
261
+
262
+ return () => {
263
+ unsubscribers.forEach(unsubscribe => unsubscribe())
264
+ }
265
+ }, [eventBus, eventMapping])
266
+
267
+ return state
268
+ }
269
+
270
+ // Hook for creating event-driven effects
271
+ export function useEventEffect<K extends keyof MediaEvents>(
272
+ eventBus: EventBus,
273
+ type: K,
274
+ effect: (detail: MediaEvents[K]) => void | (() => void),
275
+ deps?: React.DependencyList
276
+ ): void {
277
+ const cleanupRef = useRef<(() => void) | void>(undefined)
278
+
279
+ useEventListener(
280
+ eventBus,
281
+ type,
282
+ useCallback((event) => {
283
+ // Clean up previous effect
284
+ if (typeof cleanupRef.current === 'function') {
285
+ cleanupRef.current()
286
+ }
287
+
288
+ // Run new effect
289
+ cleanupRef.current = effect(event.detail)
290
+ }, deps || []),
291
+ undefined,
292
+ deps
293
+ )
294
+
295
+ useEffect(() => {
296
+ return () => {
297
+ if (typeof cleanupRef.current === 'function') {
298
+ cleanupRef.current()
299
+ }
300
+ }
301
+ }, [])
302
+ }
@@ -0,0 +1,22 @@
1
+ // Event system exports
2
+ export {
3
+ EventBus,
4
+ EventDelegator,
5
+ defaultEventBus
6
+ } from './event-system'
7
+
8
+ export type {
9
+ MediaPlayerEvent,
10
+ EventHandler,
11
+ EventUnsubscriber,
12
+ EventOptions,
13
+ EventCategory,
14
+ MediaEvents
15
+ } from './event-system'
16
+
17
+ // Event utilities
18
+ export * from './middleware'
19
+ export * from './hooks'
20
+
21
+ // Version
22
+ export const EVENT_SYSTEM_VERSION = '1.0.0'
@@ -0,0 +1,269 @@
1
+ import type { MediaPlayerEvent } from './event-system'
2
+
3
+ // Middleware function type
4
+ export type EventMiddleware = (event: MediaPlayerEvent) => MediaPlayerEvent | null
5
+
6
+ // Common middleware implementations
7
+ export const eventMiddlewares = {
8
+ // Logging middleware
9
+ logger: (prefix = '[Event]'): EventMiddleware => (event) => {
10
+ if (process.env.NODE_ENV === 'development') {
11
+ console.log(`${prefix} ${event.type}`, event.detail)
12
+ }
13
+ return event
14
+ },
15
+
16
+ // Throttling middleware
17
+ throttle: (eventTypes: string[], delay = 100): EventMiddleware => {
18
+ const lastTimes = new Map<string, number>()
19
+
20
+ return (event) => {
21
+ if (eventTypes.includes(event.type)) {
22
+ const lastTime = lastTimes.get(event.type) || 0
23
+ const now = event.timestamp
24
+
25
+ if (now - lastTime < delay) {
26
+ return null // Throttle this event
27
+ }
28
+
29
+ lastTimes.set(event.type, now)
30
+ }
31
+
32
+ return event
33
+ }
34
+ },
35
+
36
+ // Debouncing middleware
37
+ debounce: (eventTypes: string[], delay = 100): EventMiddleware => {
38
+ const timeouts = new Map<string, NodeJS.Timeout>()
39
+ const eventQueue = new Map<string, MediaPlayerEvent>()
40
+
41
+ return (event) => {
42
+ if (eventTypes.includes(event.type)) {
43
+ // Clear existing timeout
44
+ const existingTimeout = timeouts.get(event.type)
45
+ if (existingTimeout) {
46
+ clearTimeout(existingTimeout)
47
+ }
48
+
49
+ // Store the latest event
50
+ eventQueue.set(event.type, event)
51
+
52
+ // Set new timeout
53
+ const timeout = setTimeout(() => {
54
+ const queuedEvent = eventQueue.get(event.type)
55
+ if (queuedEvent) {
56
+ // Process the debounced event
57
+ // Note: This is a simplified approach - in a real implementation,
58
+ // you'd need to re-inject the event into the processing pipeline
59
+ eventQueue.delete(event.type)
60
+ timeouts.delete(event.type)
61
+ }
62
+ }, delay)
63
+
64
+ timeouts.set(event.type, timeout)
65
+
66
+ return null // Don't process immediately
67
+ }
68
+
69
+ return event
70
+ }
71
+ },
72
+
73
+ // Filtering middleware
74
+ filter: (predicate: (event: MediaPlayerEvent) => boolean): EventMiddleware => (event) => {
75
+ return predicate(event) ? event : null
76
+ },
77
+
78
+ // Event transformation middleware
79
+ transform: (transformer: (event: MediaPlayerEvent) => MediaPlayerEvent): EventMiddleware => (event) => {
80
+ try {
81
+ return transformer(event)
82
+ } catch (error) {
83
+ console.error('Error in event transformer:', error)
84
+ return event
85
+ }
86
+ },
87
+
88
+ // Performance monitoring middleware
89
+ performance: (): EventMiddleware => {
90
+ const metrics = new Map<string, { count: number; totalTime: number }>()
91
+
92
+ return (event) => {
93
+ const startTime = performance.now()
94
+
95
+ // Update metrics
96
+ const existing = metrics.get(event.type) || { count: 0, totalTime: 0 }
97
+ existing.count++
98
+ existing.totalTime += performance.now() - startTime
99
+ metrics.set(event.type, existing)
100
+
101
+ // Log metrics periodically (every 100 events)
102
+ if (existing.count % 100 === 0) {
103
+ const avgTime = existing.totalTime / existing.count
104
+ console.log(`Event ${event.type}: ${existing.count} calls, avg ${avgTime.toFixed(2)}ms`)
105
+ }
106
+
107
+ return event
108
+ }
109
+ },
110
+
111
+ // Error handling middleware
112
+ errorHandler: (onError?: (error: Error, event: MediaPlayerEvent) => void): EventMiddleware => (event) => {
113
+ try {
114
+ // Validate event structure
115
+ if (!event.type || typeof event.type !== 'string') {
116
+ throw new Error('Invalid event: missing or invalid type')
117
+ }
118
+
119
+ if (!event.timestamp || typeof event.timestamp !== 'number') {
120
+ throw new Error('Invalid event: missing or invalid timestamp')
121
+ }
122
+
123
+ return event
124
+ } catch (error) {
125
+ if (onError) {
126
+ onError(error as Error, event)
127
+ } else {
128
+ console.error('Event validation error:', error)
129
+ }
130
+ return null
131
+ }
132
+ },
133
+
134
+ // Security middleware (prevent certain events or sanitize data)
135
+ security: (options: {
136
+ blockedEventTypes?: string[]
137
+ sanitizeDetail?: boolean
138
+ maxDetailSize?: number
139
+ } = {}): EventMiddleware => (event) => {
140
+ const { blockedEventTypes = [], sanitizeDetail = true, maxDetailSize = 10000 } = options
141
+
142
+ // Block certain event types
143
+ if (blockedEventTypes.includes(event.type)) {
144
+ console.warn(`Blocked event type: ${event.type}`)
145
+ return null
146
+ }
147
+
148
+ // Sanitize detail if needed
149
+ if (sanitizeDetail && event.detail) {
150
+ try {
151
+ const detailStr = JSON.stringify(event.detail)
152
+ if (detailStr.length > maxDetailSize) {
153
+ console.warn(`Event detail too large, truncating: ${event.type}`)
154
+ event.detail = { ...event.detail, _truncated: true }
155
+ }
156
+ } catch (error) {
157
+ console.warn(`Failed to serialize event detail: ${event.type}`)
158
+ event.detail = { _serializationError: true }
159
+ }
160
+ }
161
+
162
+ return event
163
+ },
164
+
165
+ // Conditional middleware
166
+ when: (condition: (event: MediaPlayerEvent) => boolean, middleware: EventMiddleware): EventMiddleware => (event) => {
167
+ return condition(event) ? middleware(event) : event
168
+ },
169
+
170
+ // Chain multiple middleware
171
+ chain: (...middlewares: EventMiddleware[]): EventMiddleware => (event) => {
172
+ let currentEvent: MediaPlayerEvent | null = event
173
+
174
+ for (const middleware of middlewares) {
175
+ if (currentEvent === null) break
176
+ currentEvent = middleware(currentEvent)
177
+ }
178
+
179
+ return currentEvent
180
+ }
181
+ }
182
+
183
+ // Middleware builder class
184
+ export class MiddlewareBuilder {
185
+ private middlewares: EventMiddleware[] = []
186
+
187
+ // Add middleware
188
+ use(middleware: EventMiddleware): this {
189
+ this.middlewares.push(middleware)
190
+ return this
191
+ }
192
+
193
+ // Add logging
194
+ log(prefix?: string): this {
195
+ return this.use(eventMiddlewares.logger(prefix))
196
+ }
197
+
198
+ // Add throttling
199
+ throttle(eventTypes: string[], delay?: number): this {
200
+ return this.use(eventMiddlewares.throttle(eventTypes, delay))
201
+ }
202
+
203
+ // Add debouncing
204
+ debounce(eventTypes: string[], delay?: number): this {
205
+ return this.use(eventMiddlewares.debounce(eventTypes, delay))
206
+ }
207
+
208
+ // Add filtering
209
+ filter(predicate: (event: MediaPlayerEvent) => boolean): this {
210
+ return this.use(eventMiddlewares.filter(predicate))
211
+ }
212
+
213
+ // Add transformation
214
+ transform(transformer: (event: MediaPlayerEvent) => MediaPlayerEvent): this {
215
+ return this.use(eventMiddlewares.transform(transformer))
216
+ }
217
+
218
+ // Add performance monitoring
219
+ performance(): this {
220
+ return this.use(eventMiddlewares.performance())
221
+ }
222
+
223
+ // Add error handling
224
+ errorHandler(onError?: (error: Error, event: MediaPlayerEvent) => void): this {
225
+ return this.use(eventMiddlewares.errorHandler(onError))
226
+ }
227
+
228
+ // Add security
229
+ security(options?: Parameters<typeof eventMiddlewares.security>[0]): this {
230
+ return this.use(eventMiddlewares.security(options))
231
+ }
232
+
233
+ // Add conditional middleware
234
+ when(condition: (event: MediaPlayerEvent) => boolean, middleware: EventMiddleware): this {
235
+ return this.use(eventMiddlewares.when(condition, middleware))
236
+ }
237
+
238
+ // Build the final middleware
239
+ build(): EventMiddleware {
240
+ return eventMiddlewares.chain(...this.middlewares)
241
+ }
242
+ }
243
+
244
+ // Helper to create middleware builder
245
+ export const createMiddleware = () => new MiddlewareBuilder()
246
+
247
+ // Export commonly used middleware combinations
248
+ export const commonMiddlewares = {
249
+ // Development middleware stack
250
+ development: () => createMiddleware()
251
+ .log('[Dev Event]')
252
+ .performance()
253
+ .errorHandler()
254
+ .build(),
255
+
256
+ // Production middleware stack
257
+ production: () => createMiddleware()
258
+ .security()
259
+ .errorHandler()
260
+ .throttle(['media:timeupdate', 'user:mousemove'], 16) // ~60fps
261
+ .build(),
262
+
263
+ // Testing middleware stack
264
+ testing: () => createMiddleware()
265
+ .errorHandler((error, event) => {
266
+ throw new Error(`Event error in test: ${error.message} for event ${event.type}`)
267
+ })
268
+ .build()
269
+ }
@@ -0,0 +1,22 @@
1
+ // Core architecture exports
2
+
3
+ // Plugin system
4
+ export * from './plugins'
5
+
6
+ // Event system
7
+ export * from './events'
8
+
9
+ // Service providers
10
+ export * from './providers/service-provider'
11
+
12
+ // Version
13
+ export const CORE_ARCHITECTURE_VERSION = '1.0.0'
14
+
15
+ // Architecture utilities
16
+ export { createArchitecture } from './utils'
17
+
18
+ // Progressive loading system
19
+ export * from './progressive-loading'
20
+
21
+ // Performance monitoring and testing
22
+ export * from './performance'