@therealtinhtute/baroiplayer 1.2.1 → 2.0.0-beta.1
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.
- package/README.md +90 -71
- package/dist/components/icons/index.d.ts +36 -0
- package/dist/components/icons/index.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/ArrowLeftIcon.d.ts +4 -0
- package/dist/components/icons/svg-icons/ArrowLeftIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/ArrowRightIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/ArrowRightIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/AudioIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/AudioIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/BackwardIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/BackwardIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/CameraIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/CameraIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/CheckIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/CheckIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/EnablePiPIcon.d.ts +4 -0
- package/dist/components/icons/svg-icons/EnablePiPIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/ForwardIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/ForwardIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/FullscreenEnterIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/FullscreenEnterIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/FullscreenExitIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/FullscreenExitIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/LoadingIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/LoadingIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/PauseIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/PauseIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/PlayIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/PlayIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/PlaybackSpeedIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/PlaybackSpeedIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/QualityIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/QualityIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SettingsIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SettingsIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SliderIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SliderIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SubtitleIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SubtitleIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SubtitleOffIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SubtitleOffIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/UnPiPIcon.d.ts +4 -0
- package/dist/components/icons/svg-icons/UnPiPIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeMutedIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeMutedIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeOneIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeOneIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeThreeIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeThreeIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeTwoIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeTwoIcon.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-audio.d.ts +13 -0
- package/dist/components/variants/gradient/gradient-audio.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-controls.d.ts +4 -0
- package/dist/components/variants/gradient/gradient-controls.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-glyphs.d.ts +30 -0
- package/dist/components/variants/gradient/gradient-glyphs.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-video.d.ts +16 -0
- package/dist/components/variants/gradient/gradient-video.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +750 -5640
- package/dist/index.mjs.map +1 -1
- package/dist/package.json +3 -0
- package/package.json +110 -114
- package/src/components/variants/gradient/gradient-audio.tsx +47 -0
- package/src/components/variants/gradient/gradient-controls.tsx +254 -0
- package/src/components/variants/gradient/gradient-glyphs.test.tsx +69 -0
- package/src/components/variants/gradient/gradient-glyphs.tsx +129 -0
- package/src/components/variants/gradient/gradient-skin.css +211 -0
- package/src/components/variants/gradient/gradient-video.tsx +70 -0
- package/src/index.ts +5 -198
- package/src/test/accessibility-utils.ts +0 -59
- package/dist/context/media.js +0 -1
- package/dist/context/media.mjs +0 -3
- package/dist/context/store.js +0 -1
- package/dist/context/store.mjs +0 -3
- package/dist/context-Bzd5QCKM.cjs +0 -7
- package/dist/context-Bzd5QCKM.cjs.map +0 -1
- package/dist/context-DD_SH4tT.js +0 -1053
- package/dist/context-DD_SH4tT.js.map +0 -1
- package/dist/core-events-BRnLMB7s.cjs +0 -2
- package/dist/core-events-BRnLMB7s.cjs.map +0 -1
- package/dist/core-events-v_mKdj5p.js +0 -417
- package/dist/core-events-v_mKdj5p.js.map +0 -1
- package/dist/core-plugins-CMBv-yVh.cjs +0 -2
- package/dist/core-plugins-CMBv-yVh.cjs.map +0 -1
- package/dist/core-plugins-CqCxLkbd.js +0 -754
- package/dist/core-plugins-CqCxLkbd.js.map +0 -1
- package/dist/core.js +0 -15
- package/dist/core.js.map +0 -1
- package/dist/core.mjs +0 -960
- package/dist/core.mjs.map +0 -1
- package/dist/enhanced-components-BwjBqSA1.js +0 -2858
- package/dist/enhanced-components-BwjBqSA1.js.map +0 -1
- package/dist/enhanced-components-C-ka-XLp.cjs +0 -2
- package/dist/enhanced-components-C-ka-XLp.cjs.map +0 -1
- package/dist/hooks-B-IIWPJr.js +0 -1842
- package/dist/hooks-B-IIWPJr.js.map +0 -1
- package/dist/hooks-DcHzmBwA.cjs +0 -4
- package/dist/hooks-DcHzmBwA.cjs.map +0 -1
- package/dist/minimal-components-BYsMQde5.js +0 -1610
- package/dist/minimal-components-BYsMQde5.js.map +0 -1
- package/dist/minimal-components-CsxQbDp7.cjs +0 -2
- package/dist/minimal-components-CsxQbDp7.cjs.map +0 -1
- package/dist/minimal-components.css +0 -1
- package/dist/mona-loading.gif +0 -0
- package/dist/performance-monitor-DCSijLJg.js +0 -312
- package/dist/performance-monitor-DCSijLJg.js.map +0 -1
- package/dist/performance-monitor-wNFKmqMr.cjs +0 -2
- package/dist/performance-monitor-wNFKmqMr.cjs.map +0 -1
- package/dist/rolldown-runtime-BmowowmI.js +0 -14
- package/dist/rolldown-runtime-mLOUI7ql.cjs +0 -1
- package/dist/utils-D2gQ7c2R.js +0 -64
- package/dist/utils-D2gQ7c2R.js.map +0 -1
- package/dist/utils-DJaAwiZ9.cjs +0 -2
- package/dist/utils-DJaAwiZ9.cjs.map +0 -1
- package/dist/utils.js +0 -1
- package/dist/utils.mjs +0 -3
- package/src/adapters/videojs-adapter.tsx +0 -470
- package/src/assets/mona-loading.gif +0 -0
- package/src/components/AnimateLoading.tsx +0 -111
- package/src/components/LoadingState.tsx +0 -239
- package/src/components/__tests__/media-player-accessibility.test.tsx +0 -510
- package/src/components/__tests__/media-player-react19.test.tsx +0 -457
- package/src/components/accessibility/keyboard-help-overlay.tsx +0 -207
- package/src/components/audio-player.tsx +0 -85
- package/src/components/basic/index.ts +0 -37
- package/src/components/enhanced/advanced-features.tsx +0 -311
- package/src/components/enhanced/debug-panel.tsx +0 -448
- package/src/components/enhanced/enhanced-controls.tsx +0 -597
- package/src/components/enhanced/enhanced-media-player.tsx +0 -566
- package/src/components/enhanced/error-handling.tsx +0 -338
- package/src/components/enhanced/index.ts +0 -39
- package/src/components/enhanced/media-player-enhanced.tsx +0 -383
- package/src/components/examples/basic-video-player.tsx +0 -50
- package/src/components/examples/custom-controls-example.tsx +0 -63
- package/src/components/examples/enhanced-controls-example.tsx +0 -100
- package/src/components/examples/enhanced-media-player-example.tsx +0 -302
- package/src/components/examples/loading-states-demo.tsx +0 -141
- package/src/components/examples/react-19-demo.tsx +0 -349
- package/src/components/examples/volume-orientation-demo.tsx +0 -105
- package/src/components/icon-demo.tsx +0 -196
- package/src/components/legacy.tsx +0 -87
- package/src/components/media-metadata-display.tsx +0 -99
- package/src/components/media-player-audio.tsx +0 -39
- package/src/components/media-player-controls.tsx +0 -223
- package/src/components/media-player-error.tsx +0 -163
- package/src/components/media-player-fullscreen.tsx +0 -109
- package/src/components/media-player-hls.tsx +0 -111
- package/src/components/media-player-loading.tsx +0 -76
- package/src/components/media-player-play.tsx +0 -75
- package/src/components/media-player-root.tsx +0 -338
- package/src/components/media-player-seek.tsx +0 -168
- package/src/components/media-player-time.tsx +0 -99
- package/src/components/media-player-tooltip.tsx +0 -58
- package/src/components/media-player-video.tsx +0 -54
- package/src/components/media-player-volume.tsx +0 -155
- package/src/components/media-player.tsx +0 -292
- package/src/components/media-suspense.tsx +0 -344
- package/src/components/player-settings-form.tsx +0 -158
- package/src/components/react-player-wrapper.tsx +0 -651
- package/src/components/simple-video-player.tsx +0 -62
- package/src/components/ui/blur-poster.tsx +0 -96
- package/src/components/ui/empty-state.tsx +0 -91
- package/src/components/ui/enhanced-seek-bar.tsx +0 -254
- package/src/components/ui/error-state.tsx +0 -124
- package/src/components/ui/fullscreen-button.tsx +0 -81
- package/src/components/ui/loading-skeleton.tsx +0 -107
- package/src/components/ui/media-resource-preloader.tsx +0 -458
- package/src/components/ui/offline-message.tsx +0 -98
- package/src/components/ui/play-button.tsx +0 -99
- package/src/components/ui/seek-bar.tsx +0 -191
- package/src/components/ui/time-display.tsx +0 -61
- package/src/components/ui/volume-control.tsx +0 -190
- package/src/components/unified/base-media-player.tsx +0 -252
- package/src/components/unified/media-player.tsx +0 -75
- package/src/components/variants/minimal/AccessibleMinimalPlayer.tsx +0 -587
- package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.tsx +0 -573
- package/src/components/variants/minimal/MinimalControls.tsx +0 -124
- package/src/components/variants/minimal/MinimalLoading.tsx +0 -28
- package/src/components/variants/minimal/MinimalMediaPlayer.tsx +0 -318
- package/src/components/variants/minimal/MinimalOverlay.tsx +0 -58
- package/src/components/variants/minimal/MinimalPlayButton.tsx +0 -56
- package/src/components/variants/minimal/MinimalSeekBar.tsx +0 -140
- package/src/components/variants/minimal/MinimalVolumeControl.tsx +0 -75
- package/src/components/variants/minimal/SimpleMinimalPlayer.tsx +0 -206
- package/src/components/variants/minimal/components/CenterPlayButton.tsx +0 -22
- package/src/components/variants/minimal/components/ControlBar.tsx +0 -142
- package/src/components/variants/minimal/components/EnhancedSettingsMenu.tsx +0 -412
- package/src/components/variants/minimal/components/PlaybackControls.tsx +0 -46
- package/src/components/variants/minimal/components/RightControls.tsx +0 -164
- package/src/components/variants/minimal/components/SeekBar.tsx +0 -127
- package/src/components/variants/minimal/components/SettingsDropdown.tsx +0 -68
- package/src/components/variants/minimal/components/SubtitleDisplay.tsx +0 -21
- package/src/components/variants/minimal/components/TimeDisplay.tsx +0 -15
- package/src/components/variants/minimal/components/VideoElement.tsx +0 -35
- package/src/components/variants/minimal/components/VolumeControl.tsx +0 -220
- package/src/components/variants/minimal/index.ts +0 -23
- package/src/components/video-player.tsx +0 -100
- package/src/context/__tests__/media-store.test.ts +0 -509
- package/src/context/error-handling.ts +0 -398
- package/src/context/media-context.tsx +0 -254
- package/src/context/media-provider.tsx +0 -264
- package/src/context/media-store.ts +0 -387
- package/src/context/persistence.ts +0 -462
- package/src/core/events/event-system.ts +0 -448
- package/src/core/events/hooks.ts +0 -325
- package/src/core/events/index.ts +0 -22
- package/src/core/events/middleware.ts +0 -286
- package/src/core/index.ts +0 -22
- package/src/core/optimization/bundle-optimizer.tsx +0 -312
- package/src/core/performance/cicd.ts +0 -98
- package/src/core/performance/index.ts +0 -38
- package/src/core/performance/media-loading-optimizer.ts +0 -545
- package/src/core/performance/performance-budgets.ts +0 -437
- package/src/core/performance/performance-monitor.tsx +0 -488
- package/src/core/performance/performance-testing.ts +0 -461
- package/src/core/plugins/__tests__/registry.test.ts +0 -595
- package/src/core/plugins/base-plugin.ts +0 -225
- package/src/core/plugins/enhanced-plugin-system.ts +0 -435
- package/src/core/plugins/examples/analytics-plugin.ts +0 -241
- package/src/core/plugins/index.ts +0 -39
- package/src/core/plugins/registry.ts +0 -546
- package/src/core/plugins/types.ts +0 -169
- package/src/core/plugins/utils.ts +0 -317
- package/src/core/progressive-loading.tsx +0 -331
- package/src/core/providers/enhanced-hls-provider.ts +0 -307
- package/src/core/providers/lazy-provider.tsx +0 -14
- package/src/core/providers/service-provider.tsx +0 -164
- package/src/core/utils.tsx +0 -34
- package/src/features/media-session/media-session-manager.ts +0 -411
- package/src/features/picture-in-picture/pip-manager.ts +0 -428
- package/src/features/playlist/playlist-manager.ts +0 -626
- package/src/features/subtitles/subtitle-manager.ts +0 -435
- package/src/features/subtitles/subtitle-parser.ts +0 -284
- package/src/features/thumbnails/thumbnail-generator.ts +0 -528
- package/src/hooks/__tests__/currentTime-fix.test.ts +0 -149
- package/src/hooks/__tests__/use-media-player.test.ts +0 -712
- package/src/hooks/__tests__/use-media-state.test.tsx +0 -316
- package/src/hooks/accessibility/index.ts +0 -27
- package/src/hooks/accessibility/use-accessibility-preferences.ts +0 -190
- package/src/hooks/accessibility/use-focus-management.ts +0 -183
- package/src/hooks/accessibility/use-keyboard-shortcuts.ts +0 -152
- package/src/hooks/accessibility/use-screen-reader.ts +0 -212
- package/src/hooks/core/index.ts +0 -47
- package/src/hooks/legacy.ts +0 -21
- package/src/hooks/use-buffer-health.ts +0 -218
- package/src/hooks/use-enhanced-media-player.ts +0 -575
- package/src/hooks/use-focus-trap.tsx +0 -162
- package/src/hooks/use-intelligent-preloading.ts +0 -387
- package/src/hooks/use-keyboard-controls.ts +0 -115
- package/src/hooks/use-keyboard-shortcuts.ts +0 -255
- package/src/hooks/use-media-actions.ts +0 -184
- package/src/hooks/use-media-metadata.ts +0 -91
- package/src/hooks/use-media-optimistic.ts +0 -264
- package/src/hooks/use-media-player.ts +0 -343
- package/src/hooks/use-media-state.ts +0 -194
- package/src/hooks/use-memory-optimization.ts +0 -360
- package/src/hooks/use-network-status.ts +0 -124
- package/src/hooks/use-optimistic-controls.ts +0 -95
- package/src/hooks/use-optimized-media.ts +0 -283
- package/src/hooks/use-smart-preload.ts +0 -229
- package/src/hooks/use-touch-gestures.ts +0 -461
- package/src/hooks/useEnhancedSubtitles.ts +0 -258
- package/src/hooks/useKeyboardShortcuts.ts +0 -106
- package/src/hooks/useMediaControls.ts +0 -52
- package/src/hooks/useScreenshot.ts +0 -77
- package/src/hooks/useSubtitles.ts +0 -91
- package/src/hooks/useVideoPlayer.ts +0 -278
- package/src/icons/components/FullscreenIcon.tsx +0 -36
- package/src/icons/components/SettingsIcon.tsx +0 -37
- package/src/icons/components/animated/LoadingIcon.tsx +0 -27
- package/src/icons/components/animated/PlayPauseIcon.tsx +0 -42
- package/src/icons/components/media/PauseIcon.tsx +0 -38
- package/src/icons/components/media/PlayIcon.tsx +0 -37
- package/src/icons/components/volume/VolumeIcon.tsx +0 -38
- package/src/icons/components/volume/VolumeOffIcon.tsx +0 -38
- package/src/icons/index.ts +0 -56
- package/src/icons/provider.tsx +0 -58
- package/src/icons/types.ts +0 -60
- package/src/index-enhanced.ts +0 -35
- package/src/index-legacy.ts +0 -324
- package/src/index.css +0 -102
- package/src/lib/__tests__/async-utils.test.ts +0 -291
- package/src/lib/async-utils.ts +0 -194
- package/src/lib/deprecation.ts +0 -51
- package/src/lib/format-time.ts +0 -37
- package/src/lib/index.ts +0 -4
- package/src/lib/utils.ts +0 -6
- package/src/styles/globals.css +0 -462
- package/src/styles/minimal-player.css +0 -621
- package/src/styles/pixel-art.css +0 -41
- package/src/styles/videojs.css +0 -100
- package/src/types/assets.d.ts +0 -29
- package/src/types/events.ts +0 -47
- package/src/types/formats.ts +0 -79
- package/src/types/index.ts +0 -203
- package/src/types/videojs-plugins.d.ts +0 -14
|
@@ -1,488 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect, useRef, useCallback, useReducer } from "react"
|
|
2
|
-
// Import type safely with fallback
|
|
3
|
-
type ReportHandler = (metric: { name: string; value: number }) => void
|
|
4
|
-
|
|
5
|
-
// Performance metrics types
|
|
6
|
-
export interface PerformanceMetrics {
|
|
7
|
-
// Core Web Vitals
|
|
8
|
-
lcp?: number // Largest Contentful Paint
|
|
9
|
-
fid?: number // First Input Delay
|
|
10
|
-
cls?: number // Cumulative Layout Shift
|
|
11
|
-
fcp?: number // First Contentful Paint
|
|
12
|
-
ttfb?: number // Time to First Byte
|
|
13
|
-
inp?: number // Interaction to Next Paint
|
|
14
|
-
|
|
15
|
-
// Custom metrics
|
|
16
|
-
componentRenderTime: number
|
|
17
|
-
bundleLoadTime: number
|
|
18
|
-
mediaLoadTime: number
|
|
19
|
-
memoryUsage: number
|
|
20
|
-
|
|
21
|
-
// Performance scores
|
|
22
|
-
performanceScore: number
|
|
23
|
-
timestamp: number
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface PerformanceThresholds {
|
|
27
|
-
lcp: { good: number; poor: number }
|
|
28
|
-
fid: { good: number; poor: number }
|
|
29
|
-
cls: { good: number; poor: number }
|
|
30
|
-
renderTime: { good: number; poor: number }
|
|
31
|
-
memoryUsage: { good: number; poor: number }
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export const defaultThresholds: PerformanceThresholds = {
|
|
35
|
-
lcp: { good: 2500, poor: 4000 },
|
|
36
|
-
fid: { good: 100, poor: 300 },
|
|
37
|
-
cls: { good: 0.1, poor: 0.25 },
|
|
38
|
-
renderTime: { good: 16, poor: 100 }, // Target 60fps = 16.67ms per frame
|
|
39
|
-
memoryUsage: { good: 50 * 1024 * 1024, poor: 100 * 1024 * 1024 } // 50MB good, 100MB poor
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Performance monitoring class
|
|
43
|
-
export class PerformanceMonitor {
|
|
44
|
-
private metrics: PerformanceMetrics[] = []
|
|
45
|
-
private listeners: Set<(metrics: PerformanceMetrics) => void> = new Set()
|
|
46
|
-
private thresholds: PerformanceThresholds
|
|
47
|
-
private observer?: PerformanceObserver
|
|
48
|
-
private isMonitoring = false
|
|
49
|
-
|
|
50
|
-
constructor(thresholds: PerformanceThresholds = defaultThresholds) {
|
|
51
|
-
this.thresholds = thresholds
|
|
52
|
-
this.initializeWebVitals()
|
|
53
|
-
this.initializePerformanceObserver()
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private async initializeWebVitals() {
|
|
57
|
-
if (typeof window === "undefined") return
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
// Try to import web-vitals dynamically and handle different versions
|
|
61
|
-
const webVitals = await import("web-vitals").catch(() => null)
|
|
62
|
-
|
|
63
|
-
if (!webVitals) {
|
|
64
|
-
console.warn("web-vitals package not available, Core Web Vitals tracking disabled")
|
|
65
|
-
return
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const reportHandler: ReportHandler = (metric) => {
|
|
69
|
-
this.updateMetric(metric.name.toLowerCase() as keyof PerformanceMetrics, metric.value)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Handle different web-vitals versions safely
|
|
73
|
-
const vitalsAny = webVitals as any
|
|
74
|
-
if (vitalsAny.getCLS) vitalsAny.getCLS(reportHandler)
|
|
75
|
-
if (vitalsAny.getFID) vitalsAny.getFID(reportHandler)
|
|
76
|
-
if (vitalsAny.getFCP) vitalsAny.getFCP(reportHandler)
|
|
77
|
-
if (vitalsAny.getLCP) vitalsAny.getLCP(reportHandler)
|
|
78
|
-
if (vitalsAny.getTTFB) vitalsAny.getTTFB(reportHandler)
|
|
79
|
-
if (vitalsAny.onINP) vitalsAny.onINP(reportHandler)
|
|
80
|
-
} catch (error) {
|
|
81
|
-
console.warn("Web Vitals initialization failed:", error)
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private initializePerformanceObserver() {
|
|
86
|
-
if (typeof window === "undefined" || !("PerformanceObserver" in window)) return
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
this.observer = new PerformanceObserver((list) => {
|
|
90
|
-
for (const entry of list.getEntries()) {
|
|
91
|
-
this.handlePerformanceEntry(entry)
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
this.observer.observe({ entryTypes: ["measure", "navigation", "resource", "paint"] })
|
|
96
|
-
} catch (error) {
|
|
97
|
-
console.warn("PerformanceObserver not supported:", error)
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
private handlePerformanceEntry(entry: PerformanceEntry) {
|
|
102
|
-
switch (entry.entryType) {
|
|
103
|
-
case "measure":
|
|
104
|
-
if (entry.name.startsWith("baroiplayer-render")) {
|
|
105
|
-
this.updateMetric("componentRenderTime", entry.duration)
|
|
106
|
-
}
|
|
107
|
-
break
|
|
108
|
-
|
|
109
|
-
case "resource":
|
|
110
|
-
if (entry.name.includes(".js") || entry.name.includes(".css")) {
|
|
111
|
-
this.updateMetric("bundleLoadTime", entry.duration)
|
|
112
|
-
}
|
|
113
|
-
break
|
|
114
|
-
|
|
115
|
-
case "paint":
|
|
116
|
-
if (entry.name === "first-contentful-paint") {
|
|
117
|
-
this.updateMetric("fcp", entry.startTime)
|
|
118
|
-
}
|
|
119
|
-
break
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
private updateMetric(key: keyof PerformanceMetrics, value: number) {
|
|
124
|
-
const currentMetrics = this.getCurrentMetrics()
|
|
125
|
-
const updatedMetrics = {
|
|
126
|
-
...currentMetrics,
|
|
127
|
-
[key]: value,
|
|
128
|
-
timestamp: Date.now(),
|
|
129
|
-
performanceScore: this.calculatePerformanceScore({ ...currentMetrics, [key]: value })
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
this.metrics.push(updatedMetrics)
|
|
133
|
-
|
|
134
|
-
// Keep only last 100 metrics
|
|
135
|
-
if (this.metrics.length > 100) {
|
|
136
|
-
this.metrics = this.metrics.slice(-100)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
this.listeners.forEach((listener) => listener(updatedMetrics))
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private getCurrentMetrics(): PerformanceMetrics {
|
|
143
|
-
const latest = this.metrics[this.metrics.length - 1]
|
|
144
|
-
return (
|
|
145
|
-
latest || {
|
|
146
|
-
componentRenderTime: 0,
|
|
147
|
-
bundleLoadTime: 0,
|
|
148
|
-
mediaLoadTime: 0,
|
|
149
|
-
memoryUsage: this.getMemoryUsage(),
|
|
150
|
-
performanceScore: 0,
|
|
151
|
-
timestamp: Date.now()
|
|
152
|
-
}
|
|
153
|
-
)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
private getMemoryUsage(): number {
|
|
157
|
-
if ("memory" in performance) {
|
|
158
|
-
return (performance as any).memory.usedJSHeapSize || 0
|
|
159
|
-
}
|
|
160
|
-
return 0
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
private calculatePerformanceScore(metrics: PerformanceMetrics): number {
|
|
164
|
-
let score = 100
|
|
165
|
-
|
|
166
|
-
// Penalize based on thresholds
|
|
167
|
-
if (metrics.lcp && metrics.lcp > this.thresholds.lcp.good) {
|
|
168
|
-
score -= metrics.lcp > this.thresholds.lcp.poor ? 30 : 15
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (metrics.fid && metrics.fid > this.thresholds.fid.good) {
|
|
172
|
-
score -= metrics.fid > this.thresholds.fid.poor ? 25 : 10
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (metrics.cls && metrics.cls > this.thresholds.cls.good) {
|
|
176
|
-
score -= metrics.cls > this.thresholds.cls.poor ? 20 : 10
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (metrics.componentRenderTime > this.thresholds.renderTime.good) {
|
|
180
|
-
score -= metrics.componentRenderTime > this.thresholds.renderTime.poor ? 20 : 10
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (metrics.memoryUsage > this.thresholds.memoryUsage.good) {
|
|
184
|
-
score -= metrics.memoryUsage > this.thresholds.memoryUsage.poor ? 15 : 5
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return Math.max(0, score)
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Public API
|
|
191
|
-
public startMonitoring() {
|
|
192
|
-
this.isMonitoring = true
|
|
193
|
-
this.startMemoryMonitoring()
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
public stopMonitoring() {
|
|
197
|
-
this.isMonitoring = false
|
|
198
|
-
if (this.observer) {
|
|
199
|
-
this.observer.disconnect()
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
private startMemoryMonitoring() {
|
|
204
|
-
if (!this.isMonitoring) return
|
|
205
|
-
|
|
206
|
-
this.updateMetric("memoryUsage", this.getMemoryUsage())
|
|
207
|
-
setTimeout(() => this.startMemoryMonitoring(), 5000) // Check every 5 seconds
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
public measureComponentRender(componentName: string, renderFn: () => any): any {
|
|
211
|
-
const startMark = `baroiplayer-render-${componentName}-start`
|
|
212
|
-
const endMark = `baroiplayer-render-${componentName}-end`
|
|
213
|
-
const measureName = `baroiplayer-render-${componentName}`
|
|
214
|
-
|
|
215
|
-
performance.mark(startMark)
|
|
216
|
-
const result = renderFn()
|
|
217
|
-
performance.mark(endMark)
|
|
218
|
-
|
|
219
|
-
try {
|
|
220
|
-
performance.measure(measureName, startMark, endMark)
|
|
221
|
-
} catch (error) {
|
|
222
|
-
console.warn("Performance measurement failed:", error)
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return result
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
public subscribe(listener: (metrics: PerformanceMetrics) => void): () => void {
|
|
229
|
-
this.listeners.add(listener)
|
|
230
|
-
return () => this.listeners.delete(listener)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
public getLatestMetrics(): PerformanceMetrics | null {
|
|
234
|
-
return this.metrics[this.metrics.length - 1] || null
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
public getAllMetrics(): PerformanceMetrics[] {
|
|
238
|
-
return [...this.metrics]
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
public getAverageMetrics(count = 10): Partial<PerformanceMetrics> {
|
|
242
|
-
const recentMetrics = this.metrics.slice(-count)
|
|
243
|
-
if (recentMetrics.length === 0) return {}
|
|
244
|
-
|
|
245
|
-
const averages: Partial<PerformanceMetrics> = {}
|
|
246
|
-
const keys: Array<keyof PerformanceMetrics> = [
|
|
247
|
-
"lcp",
|
|
248
|
-
"fid",
|
|
249
|
-
"cls",
|
|
250
|
-
"fcp",
|
|
251
|
-
"ttfb",
|
|
252
|
-
"inp",
|
|
253
|
-
"componentRenderTime",
|
|
254
|
-
"bundleLoadTime",
|
|
255
|
-
"mediaLoadTime",
|
|
256
|
-
"memoryUsage",
|
|
257
|
-
"performanceScore"
|
|
258
|
-
]
|
|
259
|
-
|
|
260
|
-
keys.forEach((key) => {
|
|
261
|
-
const values = recentMetrics
|
|
262
|
-
.map((m) => m[key] as number)
|
|
263
|
-
.filter((v) => typeof v === "number" && !isNaN(v))
|
|
264
|
-
|
|
265
|
-
if (values.length > 0) {
|
|
266
|
-
;(averages as any)[key] = values.reduce((sum, v) => sum + v, 0) / values.length
|
|
267
|
-
}
|
|
268
|
-
})
|
|
269
|
-
|
|
270
|
-
return averages
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
public getThresholds(): PerformanceThresholds {
|
|
274
|
-
return this.thresholds
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
public updateThresholds(newThresholds: Partial<PerformanceThresholds>) {
|
|
278
|
-
this.thresholds = { ...this.thresholds, ...newThresholds }
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Global performance monitor instance
|
|
283
|
-
export const performanceMonitor = new PerformanceMonitor()
|
|
284
|
-
|
|
285
|
-
// React hook for performance monitoring
|
|
286
|
-
export function usePerformanceMonitor() {
|
|
287
|
-
const [metrics, setMetrics] = useState<PerformanceMetrics | null>(null)
|
|
288
|
-
const [isSupported, setIsSupported] = useState(true)
|
|
289
|
-
|
|
290
|
-
useEffect(() => {
|
|
291
|
-
setIsSupported(typeof window !== "undefined" && "performance" in window)
|
|
292
|
-
|
|
293
|
-
if (!isSupported) return
|
|
294
|
-
|
|
295
|
-
performanceMonitor.startMonitoring()
|
|
296
|
-
const unsubscribe = performanceMonitor.subscribe(setMetrics)
|
|
297
|
-
|
|
298
|
-
return () => {
|
|
299
|
-
unsubscribe()
|
|
300
|
-
performanceMonitor.stopMonitoring()
|
|
301
|
-
}
|
|
302
|
-
}, [isSupported])
|
|
303
|
-
|
|
304
|
-
const measureRender = useCallback((componentName: string, renderFn: () => any): any => {
|
|
305
|
-
return performanceMonitor.measureComponentRender(componentName, renderFn)
|
|
306
|
-
}, [])
|
|
307
|
-
|
|
308
|
-
return {
|
|
309
|
-
metrics,
|
|
310
|
-
isSupported,
|
|
311
|
-
measureRender,
|
|
312
|
-
averageMetrics: performanceMonitor.getAverageMetrics(),
|
|
313
|
-
allMetrics: performanceMonitor.getAllMetrics(),
|
|
314
|
-
thresholds: performanceMonitor.getThresholds()
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// HOC for performance monitoring
|
|
319
|
-
export function withPerformanceMonitoring(
|
|
320
|
-
WrappedComponent: React.ComponentType<any>,
|
|
321
|
-
componentName?: string
|
|
322
|
-
) {
|
|
323
|
-
const displayName =
|
|
324
|
-
componentName || WrappedComponent.displayName || WrappedComponent.name || "Component"
|
|
325
|
-
|
|
326
|
-
function PerformanceMonitoredComponent(props: any) {
|
|
327
|
-
const renderRef = useRef(0)
|
|
328
|
-
const { measureRender } = usePerformanceMonitor()
|
|
329
|
-
|
|
330
|
-
// Use a simple counter that increments during render but doesn't access the ref value
|
|
331
|
-
const renderKey = useState(() => Math.random())[0]
|
|
332
|
-
|
|
333
|
-
// Update ref in effect to track count without accessing during render
|
|
334
|
-
useEffect(() => {
|
|
335
|
-
renderRef.current += 1
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
return measureRender(`${displayName}-${renderKey}`, () => <WrappedComponent {...props} />)
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
PerformanceMonitoredComponent.displayName = `withPerformanceMonitoring(${displayName})`
|
|
342
|
-
return PerformanceMonitoredComponent
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Performance regression detector
|
|
346
|
-
export class PerformanceRegressionDetector {
|
|
347
|
-
private baselineMetrics: PerformanceMetrics | null = null
|
|
348
|
-
private regressionThreshold = 0.2 // 20% degradation threshold
|
|
349
|
-
|
|
350
|
-
setBaseline(metrics: PerformanceMetrics) {
|
|
351
|
-
this.baselineMetrics = metrics
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
detectRegression(currentMetrics: PerformanceMetrics): Array<{
|
|
355
|
-
metric: keyof PerformanceMetrics
|
|
356
|
-
baseline: number
|
|
357
|
-
current: number
|
|
358
|
-
degradation: number
|
|
359
|
-
}> {
|
|
360
|
-
if (!this.baselineMetrics) return []
|
|
361
|
-
|
|
362
|
-
const regressions: Array<{
|
|
363
|
-
metric: keyof PerformanceMetrics
|
|
364
|
-
baseline: number
|
|
365
|
-
current: number
|
|
366
|
-
degradation: number
|
|
367
|
-
}> = []
|
|
368
|
-
|
|
369
|
-
const metricsToCheck: Array<keyof PerformanceMetrics> = [
|
|
370
|
-
"componentRenderTime",
|
|
371
|
-
"bundleLoadTime",
|
|
372
|
-
"mediaLoadTime",
|
|
373
|
-
"memoryUsage"
|
|
374
|
-
]
|
|
375
|
-
|
|
376
|
-
metricsToCheck.forEach((metric) => {
|
|
377
|
-
const baseline = this.baselineMetrics![metric] as number
|
|
378
|
-
const current = currentMetrics[metric] as number
|
|
379
|
-
|
|
380
|
-
if (baseline && current && baseline > 0) {
|
|
381
|
-
const degradation = (current - baseline) / baseline
|
|
382
|
-
if (degradation > this.regressionThreshold) {
|
|
383
|
-
regressions.push({ metric, baseline, current, degradation })
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
})
|
|
387
|
-
|
|
388
|
-
return regressions
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
setRegressionThreshold(threshold: number) {
|
|
392
|
-
this.regressionThreshold = Math.max(0, Math.min(1, threshold))
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// Development dashboard component
|
|
397
|
-
export interface PerformanceDashboardProps {
|
|
398
|
-
className?: string
|
|
399
|
-
showAdvanced?: boolean
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
export function PerformanceDashboard({
|
|
403
|
-
className = "",
|
|
404
|
-
showAdvanced = false
|
|
405
|
-
}: PerformanceDashboardProps) {
|
|
406
|
-
const { metrics, averageMetrics, thresholds, isSupported } = usePerformanceMonitor()
|
|
407
|
-
|
|
408
|
-
if (!isSupported || !metrics) {
|
|
409
|
-
return (
|
|
410
|
-
<div className={`performance-dashboard ${className}`}>
|
|
411
|
-
<p>Performance monitoring not supported in this environment</p>
|
|
412
|
-
</div>
|
|
413
|
-
)
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
const getScoreColor = (score: number) => {
|
|
417
|
-
if (score >= 90) return "text-green-600"
|
|
418
|
-
if (score >= 70) return "text-yellow-600"
|
|
419
|
-
return "text-red-600"
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const formatBytes = (bytes: number) => {
|
|
423
|
-
return `${(bytes / 1024 / 1024).toFixed(2)} MB`
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
return (
|
|
427
|
-
<div className={`performance-dashboard rounded-lg bg-white p-4 shadow ${className}`}>
|
|
428
|
-
<h3 className="mb-4 font-semibold text-lg">Performance Dashboard</h3>
|
|
429
|
-
|
|
430
|
-
{/* Performance Score */}
|
|
431
|
-
<div className="mb-4">
|
|
432
|
-
<div className="flex items-center justify-between">
|
|
433
|
-
<span>Performance Score</span>
|
|
434
|
-
<span className={`font-bold ${getScoreColor(metrics.performanceScore)}`}>
|
|
435
|
-
{metrics.performanceScore.toFixed(0)}
|
|
436
|
-
</span>
|
|
437
|
-
</div>
|
|
438
|
-
<div className="mt-1 h-2 w-full rounded-full bg-gray-200">
|
|
439
|
-
<div
|
|
440
|
-
className={`h-2 rounded-full transition-all duration-300 ${
|
|
441
|
-
metrics.performanceScore >= 90
|
|
442
|
-
? "bg-green-500"
|
|
443
|
-
: metrics.performanceScore >= 70
|
|
444
|
-
? "bg-yellow-500"
|
|
445
|
-
: "bg-red-500"
|
|
446
|
-
}`}
|
|
447
|
-
style={{ width: `${metrics.performanceScore}%` }}
|
|
448
|
-
/>
|
|
449
|
-
</div>
|
|
450
|
-
</div>
|
|
451
|
-
|
|
452
|
-
{/* Core Web Vitals */}
|
|
453
|
-
<div className="mb-4 grid grid-cols-2 gap-4">
|
|
454
|
-
<div>
|
|
455
|
-
<h4 className="mb-2 font-medium">Core Web Vitals</h4>
|
|
456
|
-
<div className="space-y-1 text-sm">
|
|
457
|
-
{metrics.lcp && <div>LCP: {metrics.lcp.toFixed(0)}ms</div>}
|
|
458
|
-
{metrics.fid && <div>FID: {metrics.fid.toFixed(0)}ms</div>}
|
|
459
|
-
{metrics.cls && <div>CLS: {metrics.cls.toFixed(3)}</div>}
|
|
460
|
-
</div>
|
|
461
|
-
</div>
|
|
462
|
-
|
|
463
|
-
<div>
|
|
464
|
-
<h4 className="mb-2 font-medium">Custom Metrics</h4>
|
|
465
|
-
<div className="space-y-1 text-sm">
|
|
466
|
-
<div>Render: {metrics.componentRenderTime.toFixed(2)}ms</div>
|
|
467
|
-
<div>Memory: {formatBytes(metrics.memoryUsage)}</div>
|
|
468
|
-
{metrics.bundleLoadTime > 0 && <div>Bundle: {metrics.bundleLoadTime.toFixed(0)}ms</div>}
|
|
469
|
-
</div>
|
|
470
|
-
</div>
|
|
471
|
-
</div>
|
|
472
|
-
|
|
473
|
-
{/* Advanced metrics */}
|
|
474
|
-
{showAdvanced && (
|
|
475
|
-
<div>
|
|
476
|
-
<h4 className="mb-2 font-medium">Advanced Metrics</h4>
|
|
477
|
-
<div className="space-y-1 text-sm">
|
|
478
|
-
<div>Average Render Time: {(averageMetrics.componentRenderTime || 0).toFixed(2)}ms</div>
|
|
479
|
-
<div>Average Memory: {formatBytes(averageMetrics.memoryUsage || 0)}</div>
|
|
480
|
-
<div>Average Score: {(averageMetrics.performanceScore || 0).toFixed(0)}</div>
|
|
481
|
-
</div>
|
|
482
|
-
</div>
|
|
483
|
-
)}
|
|
484
|
-
</div>
|
|
485
|
-
)
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
export default PerformanceMonitor
|