@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,459 @@
1
+ import { performanceMonitor, PerformanceRegressionDetector } from './performance-monitor';
2
+ import type { PerformanceMetrics } from './performance-monitor';
3
+
4
+ // Performance test configuration
5
+ export interface PerformanceTestConfig {
6
+ name: string;
7
+ iterations: number;
8
+ warmupIterations: number;
9
+ timeout: number;
10
+ expectedThreshold: {
11
+ renderTime: number;
12
+ memoryUsage: number;
13
+ };
14
+ }
15
+
16
+ // Performance test result
17
+ export interface PerformanceTestResult {
18
+ testName: string;
19
+ passed: boolean;
20
+ metrics: {
21
+ averageRenderTime: number;
22
+ minRenderTime: number;
23
+ maxRenderTime: number;
24
+ memoryUsage: number;
25
+ iterations: number;
26
+ };
27
+ threshold: PerformanceTestConfig['expectedThreshold'];
28
+ error?: string;
29
+ }
30
+
31
+ // Performance benchmark suite
32
+ export class PerformanceBenchmark {
33
+ private results: PerformanceTestResult[] = [];
34
+ private regressionDetector = new PerformanceRegressionDetector();
35
+
36
+ async runTest(
37
+ config: PerformanceTestConfig,
38
+ testFunction: () => any | Promise<any>
39
+ ): Promise<PerformanceTestResult> {
40
+ const renderTimes: number[] = [];
41
+ let memoryBefore = 0;
42
+ let memoryAfter = 0;
43
+ let error: string | undefined;
44
+
45
+ try {
46
+ // Warmup iterations
47
+ for (let i = 0; i < config.warmupIterations; i++) {
48
+ await testFunction();
49
+ }
50
+
51
+ // Force garbage collection if available
52
+ if (global.gc) {
53
+ global.gc();
54
+ }
55
+
56
+ memoryBefore = this.getMemoryUsage();
57
+
58
+ // Main test iterations
59
+ for (let i = 0; i < config.iterations; i++) {
60
+ const startTime = performance.now();
61
+ await testFunction();
62
+ const endTime = performance.now();
63
+ renderTimes.push(endTime - startTime);
64
+ }
65
+
66
+ memoryAfter = this.getMemoryUsage();
67
+
68
+ } catch (err) {
69
+ error = err instanceof Error ? err.message : String(err);
70
+ }
71
+
72
+ const averageRenderTime = renderTimes.reduce((sum, time) => sum + time, 0) / renderTimes.length;
73
+ const minRenderTime = Math.min(...renderTimes);
74
+ const maxRenderTime = Math.max(...renderTimes);
75
+ const memoryUsage = memoryAfter - memoryBefore;
76
+
77
+ const passed = !error &&
78
+ averageRenderTime <= config.expectedThreshold.renderTime &&
79
+ memoryUsage <= config.expectedThreshold.memoryUsage;
80
+
81
+ const result: PerformanceTestResult = {
82
+ testName: config.name,
83
+ passed,
84
+ metrics: {
85
+ averageRenderTime,
86
+ minRenderTime: isFinite(minRenderTime) ? minRenderTime : 0,
87
+ maxRenderTime: isFinite(maxRenderTime) ? maxRenderTime : 0,
88
+ memoryUsage,
89
+ iterations: config.iterations
90
+ },
91
+ threshold: config.expectedThreshold,
92
+ error
93
+ };
94
+
95
+ this.results.push(result);
96
+ return result;
97
+ }
98
+
99
+ private getMemoryUsage(): number {
100
+ if ('memory' in performance) {
101
+ return (performance as any).memory.usedJSHeapSize || 0;
102
+ }
103
+ return 0;
104
+ }
105
+
106
+ // Component rendering performance test
107
+ async testComponentRender(
108
+ componentName: string,
109
+ renderFunction: () => any,
110
+ expectedRenderTime = 16 // 60fps target
111
+ ): Promise<PerformanceTestResult> {
112
+ const config: PerformanceTestConfig = {
113
+ name: `${componentName} Render Performance`,
114
+ iterations: 100,
115
+ warmupIterations: 10,
116
+ timeout: 5000,
117
+ expectedThreshold: {
118
+ renderTime: expectedRenderTime,
119
+ memoryUsage: 1024 * 1024 // 1MB
120
+ }
121
+ };
122
+
123
+ return this.runTest(config, renderFunction);
124
+ }
125
+
126
+ // Bundle loading performance test
127
+ async testBundleLoading(
128
+ bundlePath: string,
129
+ expectedLoadTime = 1000 // 1 second
130
+ ): Promise<PerformanceTestResult> {
131
+ const config: PerformanceTestConfig = {
132
+ name: `Bundle Loading: ${bundlePath}`,
133
+ iterations: 5,
134
+ warmupIterations: 1,
135
+ timeout: 10000,
136
+ expectedThreshold: {
137
+ renderTime: expectedLoadTime,
138
+ memoryUsage: 5 * 1024 * 1024 // 5MB
139
+ }
140
+ };
141
+
142
+ return this.runTest(config, async () => {
143
+ // Simulate bundle loading
144
+ const startTime = performance.now();
145
+ try {
146
+ // Use fetch instead of dynamic import to avoid bundler issues
147
+ const response = await fetch(bundlePath);
148
+ if (!response.ok) {
149
+ throw new Error(`Failed to load bundle: ${response.status}`);
150
+ }
151
+ await response.blob(); // Consume the response
152
+ } catch (error) {
153
+ console.warn(`Bundle loading test failed for ${bundlePath}:`, error);
154
+ // Return a mock time for testing purposes
155
+ }
156
+ const endTime = performance.now();
157
+ return endTime - startTime;
158
+ });
159
+ }
160
+
161
+ // Memory leak detection test
162
+ async testMemoryLeaks(
163
+ testFunction: () => any,
164
+ iterations = 1000
165
+ ): Promise<PerformanceTestResult> {
166
+ const config: PerformanceTestConfig = {
167
+ name: 'Memory Leak Detection',
168
+ iterations,
169
+ warmupIterations: 100,
170
+ timeout: 30000,
171
+ expectedThreshold: {
172
+ renderTime: Infinity, // Not testing render time
173
+ memoryUsage: 10 * 1024 * 1024 // 10MB max increase
174
+ }
175
+ };
176
+
177
+ const memoryBefore = this.getMemoryUsage();
178
+
179
+ const result = await this.runTest(config, testFunction);
180
+
181
+ const memoryAfter = this.getMemoryUsage();
182
+ const memoryIncrease = memoryAfter - memoryBefore;
183
+
184
+ // Check for memory leaks (memory should not increase significantly)
185
+ const hasMemoryLeak = memoryIncrease > config.expectedThreshold.memoryUsage;
186
+
187
+ return {
188
+ ...result,
189
+ passed: result.passed && !hasMemoryLeak,
190
+ error: hasMemoryLeak ? `Potential memory leak detected: ${Math.round(memoryIncrease / 1024 / 1024)}MB increase` : result.error
191
+ };
192
+ }
193
+
194
+ // Interaction delay test
195
+ async testInteractionDelay(
196
+ interactionFunction: () => any,
197
+ expectedDelay = 100 // 100ms
198
+ ): Promise<PerformanceTestResult> {
199
+ const config: PerformanceTestConfig = {
200
+ name: 'Interaction Delay',
201
+ iterations: 50,
202
+ warmupIterations: 5,
203
+ timeout: 5000,
204
+ expectedThreshold: {
205
+ renderTime: expectedDelay,
206
+ memoryUsage: 1024 * 1024 // 1MB
207
+ }
208
+ };
209
+
210
+ return this.runTest(config, interactionFunction);
211
+ }
212
+
213
+ // Regression testing
214
+ async runRegressionTests(
215
+ currentMetrics: PerformanceMetrics,
216
+ baselineMetrics?: PerformanceMetrics
217
+ ): Promise<{
218
+ passed: boolean;
219
+ regressions: ReturnType<PerformanceRegressionDetector['detectRegression']>;
220
+ }> {
221
+ if (baselineMetrics) {
222
+ this.regressionDetector.setBaseline(baselineMetrics);
223
+ }
224
+
225
+ const regressions = this.regressionDetector.detectRegression(currentMetrics);
226
+ const passed = regressions.length === 0;
227
+
228
+ return { passed, regressions };
229
+ }
230
+
231
+ // Get all test results
232
+ getResults(): PerformanceTestResult[] {
233
+ return [...this.results];
234
+ }
235
+
236
+ // Get test summary
237
+ getSummary(): {
238
+ totalTests: number;
239
+ passedTests: number;
240
+ failedTests: number;
241
+ passRate: number;
242
+ } {
243
+ const totalTests = this.results.length;
244
+ const passedTests = this.results.filter(result => result.passed).length;
245
+ const failedTests = totalTests - passedTests;
246
+ const passRate = totalTests > 0 ? (passedTests / totalTests) * 100 : 0;
247
+
248
+ return { totalTests, passedTests, failedTests, passRate };
249
+ }
250
+
251
+ // Clear test results
252
+ clearResults(): void {
253
+ this.results = [];
254
+ }
255
+
256
+ // Generate performance report
257
+ generateReport(): string {
258
+ const summary = this.getSummary();
259
+ let report = `Performance Test Report\n`;
260
+ report += `========================\n\n`;
261
+ report += `Total Tests: ${summary.totalTests}\n`;
262
+ report += `Passed: ${summary.passedTests}\n`;
263
+ report += `Failed: ${summary.failedTests}\n`;
264
+ report += `Pass Rate: ${summary.passRate.toFixed(1)}%\n\n`;
265
+
266
+ if (this.results.length > 0) {
267
+ report += `Detailed Results:\n`;
268
+ report += `-----------------\n\n`;
269
+
270
+ this.results.forEach((result, index) => {
271
+ report += `${index + 1}. ${result.testName}\n`;
272
+ report += ` Status: ${result.passed ? 'PASS' : 'FAIL'}\n`;
273
+ report += ` Average Render Time: ${result.metrics.averageRenderTime.toFixed(2)}ms\n`;
274
+ report += ` Min/Max Render Time: ${result.metrics.minRenderTime.toFixed(2)}ms / ${result.metrics.maxRenderTime.toFixed(2)}ms\n`;
275
+ report += ` Memory Usage: ${Math.round(result.metrics.memoryUsage / 1024)} KB\n`;
276
+ report += ` Iterations: ${result.metrics.iterations}\n`;
277
+
278
+ if (result.error) {
279
+ report += ` Error: ${result.error}\n`;
280
+ }
281
+
282
+ report += `\n`;
283
+ });
284
+ }
285
+
286
+ return report;
287
+ }
288
+ }
289
+
290
+ // Global performance benchmark instance
291
+ export const performanceBenchmark = new PerformanceBenchmark();
292
+
293
+ // Utility functions for common performance tests
294
+ export const performanceTestUtils = {
295
+ // Test component rendering performance
296
+ async testComponent(
297
+ Component: any,
298
+ props: any = {},
299
+ expectedRenderTime = 16
300
+ ): Promise<PerformanceTestResult> {
301
+ return performanceBenchmark.testComponentRender(
302
+ Component.displayName || Component.name || 'Component',
303
+ () => {
304
+ // This would need React Testing Library in a real test environment
305
+ // For now, we'll simulate component rendering
306
+ return { type: Component, props }; // Mock element
307
+ },
308
+ expectedRenderTime
309
+ );
310
+ },
311
+
312
+ // Test hook performance
313
+ async testHook(
314
+ hookFunction: () => any,
315
+ hookName: string,
316
+ expectedExecutionTime = 1
317
+ ): Promise<PerformanceTestResult> {
318
+ const config: PerformanceTestConfig = {
319
+ name: `Hook Performance: ${hookName}`,
320
+ iterations: 1000,
321
+ warmupIterations: 100,
322
+ timeout: 5000,
323
+ expectedThreshold: {
324
+ renderTime: expectedExecutionTime,
325
+ memoryUsage: 1024 * 1024 // 1MB
326
+ }
327
+ };
328
+
329
+ return performanceBenchmark.runTest(config, hookFunction);
330
+ },
331
+
332
+ // Test async operation performance
333
+ async testAsyncOperation(
334
+ operation: () => Promise<any>,
335
+ operationName: string,
336
+ expectedTime = 1000
337
+ ): Promise<PerformanceTestResult> {
338
+ const config: PerformanceTestConfig = {
339
+ name: `Async Operation: ${operationName}`,
340
+ iterations: 10,
341
+ warmupIterations: 2,
342
+ timeout: 30000,
343
+ expectedThreshold: {
344
+ renderTime: expectedTime,
345
+ memoryUsage: 2 * 1024 * 1024 // 2MB
346
+ }
347
+ };
348
+
349
+ return performanceBenchmark.runTest(config, operation);
350
+ },
351
+
352
+ // Test bundle size impact
353
+ async measureBundleImpact(
354
+ beforeFunction: () => void,
355
+ afterFunction: () => void,
356
+ featureName: string
357
+ ): Promise<{
358
+ bundleIncrease: number;
359
+ memoryIncrease: number;
360
+ renderTimeImpact: number;
361
+ }> {
362
+ const beforeMemory = (performance as any).memory?.usedJSHeapSize || 0;
363
+ const beforeTime = performance.now();
364
+
365
+ beforeFunction();
366
+
367
+ const midMemory = (performance as any).memory?.usedJSHeapSize || 0;
368
+ const midTime = performance.now();
369
+
370
+ afterFunction();
371
+
372
+ const afterMemory = (performance as any).memory?.usedJSHeapSize || 0;
373
+ const afterTime = performance.now();
374
+
375
+ return {
376
+ bundleIncrease: afterMemory - beforeMemory,
377
+ memoryIncrease: midMemory - beforeMemory,
378
+ renderTimeImpact: (afterTime - midTime) - (midTime - beforeTime)
379
+ };
380
+ }
381
+ };
382
+
383
+ // Performance testing framework
384
+ export class PerformanceTestFramework {
385
+ private benchmark = new PerformanceBenchmark();
386
+ private suites: Map<string, PerformanceTestConfig[]> = new Map();
387
+
388
+ // Register a test suite
389
+ registerSuite(suiteName: string, tests: PerformanceTestConfig[]) {
390
+ this.suites.set(suiteName, tests);
391
+ }
392
+
393
+ // Run all tests in a suite
394
+ async runSuite(
395
+ suiteName: string,
396
+ testImplementations: Map<string, () => any>
397
+ ): Promise<PerformanceTestResult[]> {
398
+ const tests = this.suites.get(suiteName);
399
+ if (!tests) {
400
+ throw new Error(`Test suite '${suiteName}' not found`);
401
+ }
402
+
403
+ const results: PerformanceTestResult[] = [];
404
+
405
+ for (const test of tests) {
406
+ const implementation = testImplementations.get(test.name);
407
+ if (!implementation) {
408
+ console.warn(`No implementation found for test '${test.name}'`);
409
+ continue;
410
+ }
411
+
412
+ const result = await this.benchmark.runTest(test, implementation);
413
+ results.push(result);
414
+ }
415
+
416
+ return results;
417
+ }
418
+
419
+ // Run all registered test suites
420
+ async runAllSuites(
421
+ implementations: Map<string, Map<string, () => any>>
422
+ ): Promise<Map<string, PerformanceTestResult[]>> {
423
+ const allResults = new Map<string, PerformanceTestResult[]>();
424
+
425
+ for (const [suiteName] of this.suites) {
426
+ const suiteImplementations = implementations.get(suiteName);
427
+ if (!suiteImplementations) {
428
+ console.warn(`No implementations found for suite '${suiteName}'`);
429
+ continue;
430
+ }
431
+
432
+ const results = await this.runSuite(suiteName, suiteImplementations);
433
+ allResults.set(suiteName, results);
434
+ }
435
+
436
+ return allResults;
437
+ }
438
+
439
+ // Generate comprehensive report
440
+ generateComprehensiveReport(): string {
441
+ const summary = this.benchmark.getSummary();
442
+ let report = this.benchmark.generateReport();
443
+
444
+ // Add suite breakdown if available
445
+ if (this.suites.size > 0) {
446
+ report += `\nTest Suites:\n`;
447
+ report += `============\n\n`;
448
+
449
+ for (const [suiteName, tests] of this.suites) {
450
+ report += `Suite: ${suiteName}\n`;
451
+ report += `Tests: ${tests.length}\n\n`;
452
+ }
453
+ }
454
+
455
+ return report;
456
+ }
457
+ }
458
+
459
+ export const performanceTestFramework = new PerformanceTestFramework();
@@ -0,0 +1,224 @@
1
+ import type {
2
+ Plugin,
3
+ PluginMetadata,
4
+ PluginContext,
5
+ PluginConfig,
6
+ PluginCategory,
7
+ PluginPriority
8
+ } from './types'
9
+
10
+ // Abstract base plugin class
11
+ export abstract class BasePlugin implements Plugin {
12
+ public readonly metadata: PluginMetadata
13
+
14
+ protected context?: PluginContext
15
+ protected config: PluginConfig = {}
16
+ protected initialized = false
17
+ protected active = false
18
+
19
+ constructor(metadata: Omit<PluginMetadata, 'version'> & { version?: string }) {
20
+ this.metadata = {
21
+ version: '1.0.0',
22
+ ...metadata
23
+ }
24
+ }
25
+
26
+ // Plugin lifecycle methods - can be overridden by subclasses
27
+ async initialize(context: PluginContext, config: PluginConfig = {}): Promise<void> {
28
+ if (this.initialized) {
29
+ context.logger.warn('Plugin already initialized')
30
+ return
31
+ }
32
+
33
+ this.context = context
34
+ this.config = { ...this.config, ...config }
35
+
36
+ try {
37
+ await this.onInitialize()
38
+ this.initialized = true
39
+ context.logger.info(`Plugin initialized`)
40
+ } catch (error) {
41
+ context.logger.error('Failed to initialize plugin', error)
42
+ throw error
43
+ }
44
+ }
45
+
46
+ async activate(context: PluginContext): Promise<void> {
47
+ if (!this.initialized) {
48
+ throw new Error('Plugin must be initialized before activation')
49
+ }
50
+
51
+ if (this.active) {
52
+ context.logger.warn('Plugin already active')
53
+ return
54
+ }
55
+
56
+ try {
57
+ await this.onActivate()
58
+ this.active = true
59
+ context.logger.info(`Plugin activated`)
60
+ } catch (error) {
61
+ context.logger.error('Failed to activate plugin', error)
62
+ throw error
63
+ }
64
+ }
65
+
66
+ async deactivate(context: PluginContext): Promise<void> {
67
+ if (!this.active) {
68
+ context.logger.warn('Plugin already inactive')
69
+ return
70
+ }
71
+
72
+ try {
73
+ await this.onDeactivate()
74
+ this.active = false
75
+ context.logger.info(`Plugin deactivated`)
76
+ } catch (error) {
77
+ context.logger.error('Failed to deactivate plugin', error)
78
+ throw error
79
+ }
80
+ }
81
+
82
+ async destroy(context: PluginContext): Promise<void> {
83
+ if (this.active) {
84
+ await this.deactivate(context)
85
+ }
86
+
87
+ try {
88
+ await this.onDestroy()
89
+ this.initialized = false
90
+ context.logger.info(`Plugin destroyed`)
91
+ } catch (error) {
92
+ context.logger.error('Failed to destroy plugin', error)
93
+ throw error
94
+ }
95
+ }
96
+
97
+ async configure(config: PluginConfig): Promise<void> {
98
+ const oldConfig = { ...this.config }
99
+ this.config = { ...this.config, ...config }
100
+
101
+ try {
102
+ await this.onConfigure(config, oldConfig)
103
+ this.context?.logger.info('Plugin configured')
104
+ } catch (error) {
105
+ // Rollback configuration on error
106
+ this.config = oldConfig
107
+ this.context?.logger.error('Failed to configure plugin', error)
108
+ throw error
109
+ }
110
+ }
111
+
112
+ healthCheck(): boolean {
113
+ return this.initialized && this.onHealthCheck()
114
+ }
115
+
116
+ // Template methods for subclasses to override
117
+ protected abstract onInitialize(): Promise<void> | void
118
+ protected abstract onActivate(): Promise<void> | void
119
+ protected abstract onDeactivate(): Promise<void> | void
120
+
121
+ protected onDestroy(): Promise<void> | void {
122
+ // Default implementation - subclasses can override
123
+ }
124
+
125
+ protected onConfigure(newConfig: PluginConfig, oldConfig: PluginConfig): Promise<void> | void {
126
+ // Default implementation - subclasses can override
127
+ }
128
+
129
+ protected onHealthCheck(): boolean {
130
+ // Default implementation - subclasses can override
131
+ return true
132
+ }
133
+
134
+ // Utility methods for plugins
135
+ protected get state() {
136
+ return this.context?.state
137
+ }
138
+
139
+ protected get controls() {
140
+ return this.context?.controls
141
+ }
142
+
143
+ protected get element() {
144
+ return this.context?.element
145
+ }
146
+
147
+ protected get logger() {
148
+ return this.context?.logger
149
+ }
150
+
151
+ protected emit(event: string, data?: any): void {
152
+ this.context?.emit(event, data)
153
+ }
154
+
155
+ protected on(event: string, handler: (data: any) => void): () => void {
156
+ return this.context?.on(event, handler) || (() => {})
157
+ }
158
+
159
+ // Helper methods for common plugin patterns
160
+ protected addEventListeners(element: HTMLElement, events: Record<string, (e: Event) => void>): () => void {
161
+ Object.entries(events).forEach(([event, handler]) => {
162
+ element.addEventListener(event, handler)
163
+ })
164
+
165
+ // Return cleanup function
166
+ return () => {
167
+ Object.entries(events).forEach(([event, handler]) => {
168
+ element.removeEventListener(event, handler)
169
+ })
170
+ }
171
+ }
172
+
173
+ protected createConfig<T extends PluginConfig>(defaults: T): T {
174
+ return { ...defaults, ...this.config } as T
175
+ }
176
+
177
+ // Plugin status
178
+ get isInitialized(): boolean {
179
+ return this.initialized
180
+ }
181
+
182
+ get isActive(): boolean {
183
+ return this.active
184
+ }
185
+ }
186
+
187
+ // Simple plugin factory helper
188
+ export function createPlugin<T extends BasePlugin>(
189
+ PluginClass: new (config?: PluginConfig) => T
190
+ ) {
191
+ return (config?: PluginConfig) => new PluginClass(config)
192
+ }
193
+
194
+ // Plugin decorator for metadata - TODO: Fix implementation
195
+ // export function plugin(metadata: Omit<PluginMetadata, 'version'> & { version?: string }) {
196
+ // return function<T extends { new (...args: any[]): BasePlugin }>(constructor: T) {
197
+ // return class extends constructor {
198
+ // constructor(...args: any[]) {
199
+ // super(metadata, ...args)
200
+ // }
201
+ // }
202
+ // }
203
+ // }
204
+
205
+ // Common plugin configurations
206
+ export interface UIPluginConfig extends PluginConfig {
207
+ position?: 'top' | 'bottom' | 'left' | 'right' | 'center'
208
+ zIndex?: number
209
+ className?: string
210
+ style?: Record<string, string>
211
+ }
212
+
213
+ export interface AnalyticsPluginConfig extends PluginConfig {
214
+ trackingId?: string
215
+ events?: string[]
216
+ samplingRate?: number
217
+ debug?: boolean
218
+ }
219
+
220
+ export interface PerformancePluginConfig extends PluginConfig {
221
+ enableMetrics?: boolean
222
+ reportInterval?: number
223
+ thresholds?: Record<string, number>
224
+ }