lazy-render-virtual-scroll 1.12.0 → 1.13.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 (151) hide show
  1. package/dist/adapters/react/index.d.ts +91 -2
  2. package/dist/cjs/adapters/react/adapters/react/components/PerformanceMonitor.d.ts +10 -0
  3. package/dist/cjs/adapters/react/adapters/react/components/PerformanceMonitor.d.ts.map +1 -0
  4. package/dist/cjs/adapters/react/adapters/react/components/index.d.ts +2 -0
  5. package/dist/cjs/adapters/react/adapters/react/components/index.d.ts.map +1 -1
  6. package/dist/cjs/adapters/react/components/PerformanceMonitor.d.ts +10 -0
  7. package/dist/cjs/adapters/react/components/PerformanceMonitor.d.ts.map +1 -0
  8. package/dist/cjs/adapters/react/components/index.d.ts +2 -0
  9. package/dist/cjs/adapters/react/components/index.d.ts.map +1 -1
  10. package/dist/cjs/adapters/react/core/AccessibilityManager.d.ts +86 -0
  11. package/dist/cjs/adapters/react/core/AccessibilityManager.d.ts.map +1 -0
  12. package/dist/cjs/adapters/react/core/AnimationManager.d.ts +63 -0
  13. package/dist/cjs/adapters/react/core/AnimationManager.d.ts.map +1 -0
  14. package/dist/cjs/adapters/react/core/PerformanceAnalytics.d.ts +83 -0
  15. package/dist/cjs/adapters/react/core/PerformanceAnalytics.d.ts.map +1 -0
  16. package/dist/cjs/adapters/react/core/PerformanceDashboard.d.ts +60 -0
  17. package/dist/cjs/adapters/react/core/PerformanceDashboard.d.ts.map +1 -0
  18. package/dist/cjs/adapters/react/index.d.ts +4 -0
  19. package/dist/cjs/adapters/react/index.d.ts.map +1 -1
  20. package/dist/cjs/adapters/react/index.js +282 -0
  21. package/dist/cjs/adapters/react/index.js.map +1 -1
  22. package/dist/cjs/angular/adapters/react/components/PerformanceMonitor.d.ts +10 -0
  23. package/dist/cjs/angular/adapters/react/components/PerformanceMonitor.d.ts.map +1 -0
  24. package/dist/cjs/angular/adapters/react/components/index.d.ts +2 -0
  25. package/dist/cjs/angular/adapters/react/components/index.d.ts.map +1 -1
  26. package/dist/cjs/angular/core/AccessibilityManager.d.ts +86 -0
  27. package/dist/cjs/angular/core/AccessibilityManager.d.ts.map +1 -0
  28. package/dist/cjs/angular/core/AnimationManager.d.ts +63 -0
  29. package/dist/cjs/angular/core/AnimationManager.d.ts.map +1 -0
  30. package/dist/cjs/angular/core/PerformanceAnalytics.d.ts +83 -0
  31. package/dist/cjs/angular/core/PerformanceAnalytics.d.ts.map +1 -0
  32. package/dist/cjs/angular/core/PerformanceDashboard.d.ts +60 -0
  33. package/dist/cjs/angular/core/PerformanceDashboard.d.ts.map +1 -0
  34. package/dist/cjs/angular/index.d.ts +4 -0
  35. package/dist/cjs/angular/index.d.ts.map +1 -1
  36. package/dist/cjs/core/AccessibilityManager.d.ts +86 -0
  37. package/dist/cjs/core/AccessibilityManager.d.ts.map +1 -0
  38. package/dist/cjs/core/AnimationManager.d.ts +63 -0
  39. package/dist/cjs/core/AnimationManager.d.ts.map +1 -0
  40. package/dist/cjs/core/PerformanceAnalytics.d.ts +83 -0
  41. package/dist/cjs/core/PerformanceAnalytics.d.ts.map +1 -0
  42. package/dist/cjs/core/PerformanceDashboard.d.ts +60 -0
  43. package/dist/cjs/core/PerformanceDashboard.d.ts.map +1 -0
  44. package/dist/cjs/index.d.ts +4 -0
  45. package/dist/cjs/index.d.ts.map +1 -1
  46. package/dist/cjs/index.js +756 -0
  47. package/dist/cjs/index.js.map +1 -1
  48. package/dist/cjs/svelte/adapters/react/components/PerformanceMonitor.d.ts +10 -0
  49. package/dist/cjs/svelte/adapters/react/components/PerformanceMonitor.d.ts.map +1 -0
  50. package/dist/cjs/svelte/adapters/react/components/index.d.ts +2 -0
  51. package/dist/cjs/svelte/adapters/react/components/index.d.ts.map +1 -1
  52. package/dist/cjs/svelte/core/AccessibilityManager.d.ts +86 -0
  53. package/dist/cjs/svelte/core/AccessibilityManager.d.ts.map +1 -0
  54. package/dist/cjs/svelte/core/AnimationManager.d.ts +63 -0
  55. package/dist/cjs/svelte/core/AnimationManager.d.ts.map +1 -0
  56. package/dist/cjs/svelte/core/PerformanceAnalytics.d.ts +83 -0
  57. package/dist/cjs/svelte/core/PerformanceAnalytics.d.ts.map +1 -0
  58. package/dist/cjs/svelte/core/PerformanceDashboard.d.ts +60 -0
  59. package/dist/cjs/svelte/core/PerformanceDashboard.d.ts.map +1 -0
  60. package/dist/cjs/svelte/index.d.ts +4 -0
  61. package/dist/cjs/svelte/index.d.ts.map +1 -1
  62. package/dist/cjs/vue/adapters/react/components/PerformanceMonitor.d.ts +10 -0
  63. package/dist/cjs/vue/adapters/react/components/PerformanceMonitor.d.ts.map +1 -0
  64. package/dist/cjs/vue/adapters/react/components/index.d.ts +2 -0
  65. package/dist/cjs/vue/adapters/react/components/index.d.ts.map +1 -1
  66. package/dist/cjs/vue/core/AccessibilityManager.d.ts +86 -0
  67. package/dist/cjs/vue/core/AccessibilityManager.d.ts.map +1 -0
  68. package/dist/cjs/vue/core/AnimationManager.d.ts +63 -0
  69. package/dist/cjs/vue/core/AnimationManager.d.ts.map +1 -0
  70. package/dist/cjs/vue/core/PerformanceAnalytics.d.ts +83 -0
  71. package/dist/cjs/vue/core/PerformanceAnalytics.d.ts.map +1 -0
  72. package/dist/cjs/vue/core/PerformanceDashboard.d.ts +60 -0
  73. package/dist/cjs/vue/core/PerformanceDashboard.d.ts.map +1 -0
  74. package/dist/cjs/vue/index.d.ts +4 -0
  75. package/dist/cjs/vue/index.d.ts.map +1 -1
  76. package/dist/esm/adapters/react/adapters/react/components/PerformanceMonitor.d.ts +10 -0
  77. package/dist/esm/adapters/react/adapters/react/components/PerformanceMonitor.d.ts.map +1 -0
  78. package/dist/esm/adapters/react/adapters/react/components/index.d.ts +2 -0
  79. package/dist/esm/adapters/react/adapters/react/components/index.d.ts.map +1 -1
  80. package/dist/esm/adapters/react/components/PerformanceMonitor.d.ts +10 -0
  81. package/dist/esm/adapters/react/components/PerformanceMonitor.d.ts.map +1 -0
  82. package/dist/esm/adapters/react/components/index.d.ts +2 -0
  83. package/dist/esm/adapters/react/components/index.d.ts.map +1 -1
  84. package/dist/esm/adapters/react/core/AccessibilityManager.d.ts +86 -0
  85. package/dist/esm/adapters/react/core/AccessibilityManager.d.ts.map +1 -0
  86. package/dist/esm/adapters/react/core/AnimationManager.d.ts +63 -0
  87. package/dist/esm/adapters/react/core/AnimationManager.d.ts.map +1 -0
  88. package/dist/esm/adapters/react/core/PerformanceAnalytics.d.ts +83 -0
  89. package/dist/esm/adapters/react/core/PerformanceAnalytics.d.ts.map +1 -0
  90. package/dist/esm/adapters/react/core/PerformanceDashboard.d.ts +60 -0
  91. package/dist/esm/adapters/react/core/PerformanceDashboard.d.ts.map +1 -0
  92. package/dist/esm/adapters/react/index.d.ts +4 -0
  93. package/dist/esm/adapters/react/index.d.ts.map +1 -1
  94. package/dist/esm/adapters/react/index.js +282 -1
  95. package/dist/esm/adapters/react/index.js.map +1 -1
  96. package/dist/esm/angular/adapters/react/components/PerformanceMonitor.d.ts +10 -0
  97. package/dist/esm/angular/adapters/react/components/PerformanceMonitor.d.ts.map +1 -0
  98. package/dist/esm/angular/adapters/react/components/index.d.ts +2 -0
  99. package/dist/esm/angular/adapters/react/components/index.d.ts.map +1 -1
  100. package/dist/esm/angular/core/AccessibilityManager.d.ts +86 -0
  101. package/dist/esm/angular/core/AccessibilityManager.d.ts.map +1 -0
  102. package/dist/esm/angular/core/AnimationManager.d.ts +63 -0
  103. package/dist/esm/angular/core/AnimationManager.d.ts.map +1 -0
  104. package/dist/esm/angular/core/PerformanceAnalytics.d.ts +83 -0
  105. package/dist/esm/angular/core/PerformanceAnalytics.d.ts.map +1 -0
  106. package/dist/esm/angular/core/PerformanceDashboard.d.ts +60 -0
  107. package/dist/esm/angular/core/PerformanceDashboard.d.ts.map +1 -0
  108. package/dist/esm/angular/index.d.ts +4 -0
  109. package/dist/esm/angular/index.d.ts.map +1 -1
  110. package/dist/esm/core/AccessibilityManager.d.ts +86 -0
  111. package/dist/esm/core/AccessibilityManager.d.ts.map +1 -0
  112. package/dist/esm/core/AnimationManager.d.ts +63 -0
  113. package/dist/esm/core/AnimationManager.d.ts.map +1 -0
  114. package/dist/esm/core/PerformanceAnalytics.d.ts +83 -0
  115. package/dist/esm/core/PerformanceAnalytics.d.ts.map +1 -0
  116. package/dist/esm/core/PerformanceDashboard.d.ts +60 -0
  117. package/dist/esm/core/PerformanceDashboard.d.ts.map +1 -0
  118. package/dist/esm/index.d.ts +4 -0
  119. package/dist/esm/index.d.ts.map +1 -1
  120. package/dist/esm/index.js +753 -1
  121. package/dist/esm/index.js.map +1 -1
  122. package/dist/esm/svelte/adapters/react/components/PerformanceMonitor.d.ts +10 -0
  123. package/dist/esm/svelte/adapters/react/components/PerformanceMonitor.d.ts.map +1 -0
  124. package/dist/esm/svelte/adapters/react/components/index.d.ts +2 -0
  125. package/dist/esm/svelte/adapters/react/components/index.d.ts.map +1 -1
  126. package/dist/esm/svelte/core/AccessibilityManager.d.ts +86 -0
  127. package/dist/esm/svelte/core/AccessibilityManager.d.ts.map +1 -0
  128. package/dist/esm/svelte/core/AnimationManager.d.ts +63 -0
  129. package/dist/esm/svelte/core/AnimationManager.d.ts.map +1 -0
  130. package/dist/esm/svelte/core/PerformanceAnalytics.d.ts +83 -0
  131. package/dist/esm/svelte/core/PerformanceAnalytics.d.ts.map +1 -0
  132. package/dist/esm/svelte/core/PerformanceDashboard.d.ts +60 -0
  133. package/dist/esm/svelte/core/PerformanceDashboard.d.ts.map +1 -0
  134. package/dist/esm/svelte/index.d.ts +4 -0
  135. package/dist/esm/svelte/index.d.ts.map +1 -1
  136. package/dist/esm/vue/adapters/react/components/PerformanceMonitor.d.ts +10 -0
  137. package/dist/esm/vue/adapters/react/components/PerformanceMonitor.d.ts.map +1 -0
  138. package/dist/esm/vue/adapters/react/components/index.d.ts +2 -0
  139. package/dist/esm/vue/adapters/react/components/index.d.ts.map +1 -1
  140. package/dist/esm/vue/core/AccessibilityManager.d.ts +86 -0
  141. package/dist/esm/vue/core/AccessibilityManager.d.ts.map +1 -0
  142. package/dist/esm/vue/core/AnimationManager.d.ts +63 -0
  143. package/dist/esm/vue/core/AnimationManager.d.ts.map +1 -0
  144. package/dist/esm/vue/core/PerformanceAnalytics.d.ts +83 -0
  145. package/dist/esm/vue/core/PerformanceAnalytics.d.ts.map +1 -0
  146. package/dist/esm/vue/core/PerformanceDashboard.d.ts +60 -0
  147. package/dist/esm/vue/core/PerformanceDashboard.d.ts.map +1 -0
  148. package/dist/esm/vue/index.d.ts +4 -0
  149. package/dist/esm/vue/index.d.ts.map +1 -1
  150. package/dist/index.d.ts +289 -1
  151. package/package.json +1 -1
package/dist/cjs/index.js CHANGED
@@ -2922,6 +2922,758 @@ class IntelligentPagination {
2922
2922
  }
2923
2923
  }
2924
2924
 
2925
+ /**
2926
+ * Performance Analytics Engine
2927
+ * Tracks render time, memory usage, and network performance
2928
+ */
2929
+ class PerformanceAnalytics {
2930
+ constructor() {
2931
+ this.renderTimeHistory = [];
2932
+ this.memoryHistory = [];
2933
+ this.networkLatencyHistory = [];
2934
+ this.frameTimestamps = [];
2935
+ this.droppedFrames = 0;
2936
+ this.jankCount = 0;
2937
+ this.MAX_HISTORY = 100;
2938
+ this.JANK_THRESHOLD = 50; // ms
2939
+ }
2940
+ /**
2941
+ * Track render time for an item
2942
+ */
2943
+ trackRenderTime(renderTime) {
2944
+ this.renderTimeHistory.push(renderTime);
2945
+ if (this.renderTimeHistory.length > this.MAX_HISTORY) {
2946
+ this.renderTimeHistory.shift();
2947
+ }
2948
+ }
2949
+ /**
2950
+ * Track memory usage
2951
+ */
2952
+ trackMemoryUsage(memoryMB) {
2953
+ this.memoryHistory.push(memoryMB);
2954
+ if (this.memoryHistory.length > this.MAX_HISTORY) {
2955
+ this.memoryHistory.shift();
2956
+ }
2957
+ }
2958
+ /**
2959
+ * Track network request latency
2960
+ */
2961
+ trackNetworkLatency(latency) {
2962
+ this.networkLatencyHistory.push(latency);
2963
+ if (this.networkLatencyHistory.length > this.MAX_HISTORY) {
2964
+ this.networkLatencyHistory.shift();
2965
+ }
2966
+ }
2967
+ /**
2968
+ * Track frame timing for FPS calculation
2969
+ */
2970
+ trackFrame() {
2971
+ const now = performance.now();
2972
+ this.frameTimestamps.push(now);
2973
+ // Keep only last 60 frames (1 second at 60fps)
2974
+ if (this.frameTimestamps.length > 60) {
2975
+ this.frameTimestamps.shift();
2976
+ }
2977
+ // Detect jank (frame took longer than JANK_THRESHOLD)
2978
+ if (this.frameTimestamps.length >= 2) {
2979
+ const frameTime = now - this.frameTimestamps[this.frameTimestamps.length - 2];
2980
+ if (frameTime > this.JANK_THRESHOLD) {
2981
+ this.jankCount++;
2982
+ this.droppedFrames++;
2983
+ }
2984
+ }
2985
+ }
2986
+ /**
2987
+ * Get current FPS
2988
+ */
2989
+ getCurrentFPS() {
2990
+ if (this.frameTimestamps.length < 2)
2991
+ return 60;
2992
+ const now = performance.now();
2993
+ const oneSecondAgo = now - 1000;
2994
+ const framesInLastSecond = this.frameTimestamps.filter(t => t > oneSecondAgo).length;
2995
+ return framesInLastSecond;
2996
+ }
2997
+ /**
2998
+ * Get comprehensive performance metrics
2999
+ */
3000
+ getMetrics() {
3001
+ return {
3002
+ renderTime: {
3003
+ average: this.getAverage(this.renderTimeHistory),
3004
+ min: Math.min(...this.renderTimeHistory, 0),
3005
+ max: Math.max(...this.renderTimeHistory, 0),
3006
+ count: this.renderTimeHistory.length
3007
+ },
3008
+ memoryUsage: {
3009
+ current: this.memoryHistory[this.memoryHistory.length - 1] || 0,
3010
+ peak: Math.max(...this.memoryHistory, 0),
3011
+ trend: this.getTrend(this.memoryHistory)
3012
+ },
3013
+ networkPerformance: {
3014
+ averageLatency: this.getAverage(this.networkLatencyHistory),
3015
+ averageSpeed: 0, // Would need actual network speed data
3016
+ failedRequests: 0 // Would need to track failures
3017
+ },
3018
+ scrollPerformance: {
3019
+ averageFPS: this.getCurrentFPS(),
3020
+ droppedFrames: this.droppedFrames,
3021
+ jankCount: this.jankCount
3022
+ }
3023
+ };
3024
+ }
3025
+ /**
3026
+ * Get average from array
3027
+ */
3028
+ getAverage(arr) {
3029
+ if (arr.length === 0)
3030
+ return 0;
3031
+ return arr.reduce((a, b) => a + b, 0) / arr.length;
3032
+ }
3033
+ /**
3034
+ * Get trend from array
3035
+ */
3036
+ getTrend(arr) {
3037
+ if (arr.length < 10)
3038
+ return 'stable';
3039
+ const recent = arr.slice(-10);
3040
+ const older = arr.slice(-20, -10);
3041
+ const recentAvg = this.getAverage(recent);
3042
+ const olderAvg = this.getAverage(older);
3043
+ const change = (recentAvg - olderAvg) / olderAvg;
3044
+ if (change > 0.1)
3045
+ return 'increasing';
3046
+ if (change < -0.1)
3047
+ return 'decreasing';
3048
+ return 'stable';
3049
+ }
3050
+ /**
3051
+ * Reset all metrics
3052
+ */
3053
+ reset() {
3054
+ this.renderTimeHistory = [];
3055
+ this.memoryHistory = [];
3056
+ this.networkLatencyHistory = [];
3057
+ this.frameTimestamps = [];
3058
+ this.droppedFrames = 0;
3059
+ this.jankCount = 0;
3060
+ }
3061
+ /**
3062
+ * Get performance score (0-100)
3063
+ */
3064
+ getPerformanceScore() {
3065
+ const metrics = this.getMetrics();
3066
+ let score = 100;
3067
+ // Penalize low FPS
3068
+ if (metrics.scrollPerformance.averageFPS < 60) {
3069
+ score -= (60 - metrics.scrollPerformance.averageFPS) * 0.5;
3070
+ }
3071
+ // Penalize high render times
3072
+ if (metrics.renderTime.average > 16) {
3073
+ score -= (metrics.renderTime.average - 16) * 0.3;
3074
+ }
3075
+ // Penalize jank
3076
+ score -= metrics.scrollPerformance.jankCount * 0.2;
3077
+ // Penalize memory increase
3078
+ if (metrics.memoryUsage.trend === 'increasing') {
3079
+ score -= 10;
3080
+ }
3081
+ return Math.max(0, Math.min(100, score));
3082
+ }
3083
+ /**
3084
+ * Get optimization recommendations
3085
+ */
3086
+ getRecommendations() {
3087
+ const recommendations = [];
3088
+ const metrics = this.getMetrics();
3089
+ if (metrics.scrollPerformance.averageFPS < 30) {
3090
+ recommendations.push('Critical: FPS is very low. Consider reducing item complexity or increasing batch size.');
3091
+ }
3092
+ else if (metrics.scrollPerformance.averageFPS < 60) {
3093
+ recommendations.push('Warning: FPS below 60. Consider optimizing render performance.');
3094
+ }
3095
+ if (metrics.renderTime.average > 50) {
3096
+ recommendations.push('Warning: High render time. Consider simplifying item components.');
3097
+ }
3098
+ if (metrics.memoryUsage.trend === 'increasing') {
3099
+ recommendations.push('Warning: Memory usage increasing. Check for memory leaks.');
3100
+ }
3101
+ if (metrics.scrollPerformance.jankCount > 10) {
3102
+ recommendations.push('Warning: Frequent jank detected. Consider smoothing scroll animations.');
3103
+ }
3104
+ if (recommendations.length === 0) {
3105
+ recommendations.push('Performance is optimal. No issues detected.');
3106
+ }
3107
+ return recommendations;
3108
+ }
3109
+ }
3110
+
3111
+ /**
3112
+ * Performance Dashboard
3113
+ * Real-time performance monitoring and bottleneck identification
3114
+ */
3115
+ class PerformanceDashboard {
3116
+ constructor(analytics) {
3117
+ this.updateInterval = 1000; // 1 second
3118
+ this.listeners = [];
3119
+ this.intervalId = null;
3120
+ this.isMonitoring = false;
3121
+ this.analytics = analytics;
3122
+ }
3123
+ /**
3124
+ * Start real-time monitoring
3125
+ */
3126
+ startMonitoring() {
3127
+ if (this.isMonitoring)
3128
+ return;
3129
+ this.isMonitoring = true;
3130
+ this.intervalId = window.setInterval(() => {
3131
+ const data = this.getDashboardData();
3132
+ this.notifyListeners(data);
3133
+ }, this.updateInterval);
3134
+ }
3135
+ /**
3136
+ * Stop monitoring
3137
+ */
3138
+ stopMonitoring() {
3139
+ if (!this.isMonitoring)
3140
+ return;
3141
+ this.isMonitoring = false;
3142
+ if (this.intervalId !== null) {
3143
+ clearInterval(this.intervalId);
3144
+ this.intervalId = null;
3145
+ }
3146
+ }
3147
+ /**
3148
+ * Get current dashboard data
3149
+ */
3150
+ getDashboardData() {
3151
+ const metrics = this.analytics.getMetrics();
3152
+ const score = this.analytics.getPerformanceScore();
3153
+ const recommendations = this.analytics.getRecommendations();
3154
+ // Identify bottlenecks
3155
+ const bottlenecks = this.identifyBottlenecks(metrics);
3156
+ return {
3157
+ overallScore: score,
3158
+ fps: metrics.scrollPerformance.averageFPS,
3159
+ renderTime: metrics.renderTime.average,
3160
+ memoryUsage: metrics.memoryUsage.current,
3161
+ networkLatency: metrics.networkPerformance.averageLatency,
3162
+ recommendations,
3163
+ bottlenecks
3164
+ };
3165
+ }
3166
+ /**
3167
+ * Identify performance bottlenecks
3168
+ */
3169
+ identifyBottlenecks(metrics) {
3170
+ const bottlenecks = [];
3171
+ // FPS bottleneck
3172
+ if (metrics.scrollPerformance.averageFPS < 30) {
3173
+ bottlenecks.push('CRITICAL: Low FPS - Rendering is the bottleneck');
3174
+ }
3175
+ else if (metrics.scrollPerformance.averageFPS < 60) {
3176
+ bottlenecks.push('WARNING: Below 60 FPS - Consider optimizing renders');
3177
+ }
3178
+ // Render time bottleneck
3179
+ if (metrics.renderTime.average > 50) {
3180
+ bottlenecks.push('HIGH: Slow render times - Simplify item components');
3181
+ }
3182
+ else if (metrics.renderTime.average > 16) {
3183
+ bottlenecks.push('MEDIUM: Render time above frame budget');
3184
+ }
3185
+ // Memory bottleneck
3186
+ if (metrics.memoryUsage.trend === 'increasing') {
3187
+ bottlenecks.push('WARNING: Memory leak detected - Check cleanup logic');
3188
+ }
3189
+ // Network bottleneck
3190
+ if (metrics.networkPerformance.averageLatency > 500) {
3191
+ bottlenecks.push('HIGH: Network latency - Implement better caching');
3192
+ }
3193
+ // Jank bottleneck
3194
+ if (metrics.scrollPerformance.jankCount > 20) {
3195
+ bottlenecks.push('CRITICAL: Frequent jank - Smooth scroll performance');
3196
+ }
3197
+ if (bottlenecks.length === 0) {
3198
+ bottlenecks.push('No bottlenecks detected - Performance is optimal');
3199
+ }
3200
+ return bottlenecks;
3201
+ }
3202
+ /**
3203
+ * Add listener for dashboard updates
3204
+ */
3205
+ addListener(callback) {
3206
+ this.listeners.push(callback);
3207
+ }
3208
+ /**
3209
+ * Remove listener
3210
+ */
3211
+ removeListener(callback) {
3212
+ const index = this.listeners.indexOf(callback);
3213
+ if (index > -1) {
3214
+ this.listeners.splice(index, 1);
3215
+ }
3216
+ }
3217
+ /**
3218
+ * Notify all listeners
3219
+ */
3220
+ notifyListeners(data) {
3221
+ this.listeners.forEach(listener => {
3222
+ try {
3223
+ listener(data);
3224
+ }
3225
+ catch (error) {
3226
+ console.error('Dashboard listener error:', error);
3227
+ }
3228
+ });
3229
+ }
3230
+ /**
3231
+ * Export metrics as JSON
3232
+ */
3233
+ exportMetrics() {
3234
+ const metrics = this.analytics.getMetrics();
3235
+ return JSON.stringify(metrics, null, 2);
3236
+ }
3237
+ /**
3238
+ * Get performance report
3239
+ */
3240
+ getPerformanceReport() {
3241
+ const data = this.getDashboardData();
3242
+ let report = '=== PERFORMANCE REPORT ===\n\n';
3243
+ report += `Overall Score: ${data.overallScore}/100\n`;
3244
+ report += `FPS: ${data.fps}\n`;
3245
+ report += `Average Render Time: ${data.renderTime.toFixed(2)}ms\n`;
3246
+ report += `Memory Usage: ${data.memoryUsage.toFixed(2)}MB\n`;
3247
+ report += `Network Latency: ${data.networkLatency.toFixed(2)}ms\n\n`;
3248
+ report += 'BOTTLENECKS:\n';
3249
+ data.bottlenecks.forEach(b => {
3250
+ report += ` - ${b}\n`;
3251
+ });
3252
+ report += '\nRECOMMENDATIONS:\n';
3253
+ data.recommendations.forEach(r => {
3254
+ report += ` - ${r}\n`;
3255
+ });
3256
+ return report;
3257
+ }
3258
+ }
3259
+
3260
+ /**
3261
+ * Accessibility Manager
3262
+ * Handles keyboard navigation, screen reader compatibility, and ARIA attributes
3263
+ */
3264
+ class AccessibilityManager {
3265
+ constructor(config) {
3266
+ this.focusedIndex = -1;
3267
+ this.containerElement = null;
3268
+ this.itemElements = [];
3269
+ this.config = {
3270
+ enableKeyboardNav: true,
3271
+ enableScreenReader: true,
3272
+ enableARIA: true,
3273
+ ...config
3274
+ };
3275
+ }
3276
+ /**
3277
+ * Initialize accessibility features
3278
+ */
3279
+ initialize(container) {
3280
+ this.containerElement = container;
3281
+ // Set ARIA roles
3282
+ if (this.config.enableARIA) {
3283
+ this.setupARIA();
3284
+ }
3285
+ // Setup keyboard navigation
3286
+ if (this.config.enableKeyboardNav) {
3287
+ this.setupKeyboardNav();
3288
+ }
3289
+ // Setup screen reader announcements
3290
+ if (this.config.enableScreenReader) {
3291
+ this.setupScreenReader();
3292
+ }
3293
+ }
3294
+ /**
3295
+ * Setup ARIA attributes
3296
+ */
3297
+ setupARIA() {
3298
+ if (!this.containerElement)
3299
+ return;
3300
+ // Set list role
3301
+ this.containerElement.setAttribute('role', 'list');
3302
+ this.containerElement.setAttribute('aria-label', 'Virtual scroll list');
3303
+ // Set tabindex for keyboard focus
3304
+ this.containerElement.setAttribute('tabindex', '0');
3305
+ }
3306
+ /**
3307
+ * Setup keyboard navigation
3308
+ */
3309
+ setupKeyboardNav() {
3310
+ if (!this.containerElement)
3311
+ return;
3312
+ this.containerElement.addEventListener('keydown', (e) => {
3313
+ this.handleKeyDown(e);
3314
+ });
3315
+ }
3316
+ /**
3317
+ * Handle keyboard events
3318
+ */
3319
+ handleKeyDown(e) {
3320
+ switch (e.key) {
3321
+ case 'ArrowDown':
3322
+ e.preventDefault();
3323
+ this.focusNext();
3324
+ break;
3325
+ case 'ArrowUp':
3326
+ e.preventDefault();
3327
+ this.focusPrevious();
3328
+ break;
3329
+ case 'Home':
3330
+ e.preventDefault();
3331
+ this.focusFirst();
3332
+ break;
3333
+ case 'End':
3334
+ e.preventDefault();
3335
+ this.focusLast();
3336
+ break;
3337
+ case 'PageDown':
3338
+ e.preventDefault();
3339
+ this.focusPageDown();
3340
+ break;
3341
+ case 'PageUp':
3342
+ e.preventDefault();
3343
+ this.focusPageUp();
3344
+ break;
3345
+ }
3346
+ }
3347
+ /**
3348
+ * Focus next item
3349
+ */
3350
+ focusNext() {
3351
+ if (this.focusedIndex < this.itemElements.length - 1) {
3352
+ this.focusedIndex++;
3353
+ this.focusItem(this.focusedIndex);
3354
+ }
3355
+ }
3356
+ /**
3357
+ * Focus previous item
3358
+ */
3359
+ focusPrevious() {
3360
+ if (this.focusedIndex > 0) {
3361
+ this.focusedIndex--;
3362
+ this.focusItem(this.focusedIndex);
3363
+ }
3364
+ }
3365
+ /**
3366
+ * Focus first item
3367
+ */
3368
+ focusFirst() {
3369
+ this.focusedIndex = 0;
3370
+ this.focusItem(0);
3371
+ }
3372
+ /**
3373
+ * Focus last item
3374
+ */
3375
+ focusLast() {
3376
+ this.focusedIndex = this.itemElements.length - 1;
3377
+ this.focusItem(this.focusedIndex);
3378
+ }
3379
+ /**
3380
+ * Focus page down (10 items)
3381
+ */
3382
+ focusPageDown() {
3383
+ this.focusedIndex = Math.min(this.focusedIndex + 10, this.itemElements.length - 1);
3384
+ this.focusItem(this.focusedIndex);
3385
+ }
3386
+ /**
3387
+ * Focus page up (10 items)
3388
+ */
3389
+ focusPageUp() {
3390
+ this.focusedIndex = Math.max(this.focusedIndex - 10, 0);
3391
+ this.focusItem(this.focusedIndex);
3392
+ }
3393
+ /**
3394
+ * Focus specific item
3395
+ */
3396
+ focusItem(index) {
3397
+ if (index >= 0 && index < this.itemElements.length) {
3398
+ const element = this.itemElements[index];
3399
+ element.focus();
3400
+ element.scrollIntoView({ block: 'nearest' });
3401
+ // Announce to screen readers
3402
+ this.announce(`Item ${index + 1} of ${this.itemElements.length}`);
3403
+ }
3404
+ }
3405
+ /**
3406
+ * Setup screen reader support
3407
+ */
3408
+ setupScreenReader() {
3409
+ // Create live region for announcements
3410
+ const liveRegion = document.createElement('div');
3411
+ liveRegion.setAttribute('role', 'status');
3412
+ liveRegion.setAttribute('aria-live', 'polite');
3413
+ liveRegion.setAttribute('aria-atomic', 'true');
3414
+ liveRegion.className = 'sr-only';
3415
+ liveRegion.style.cssText = `
3416
+ position: absolute;
3417
+ width: 1px;
3418
+ height: 1px;
3419
+ padding: 0;
3420
+ margin: -1px;
3421
+ overflow: hidden;
3422
+ clip: rect(0, 0, 0, 0);
3423
+ white-space: nowrap;
3424
+ border: 0;
3425
+ `;
3426
+ document.body.appendChild(liveRegion);
3427
+ }
3428
+ /**
3429
+ * Announce message to screen readers
3430
+ */
3431
+ announce(message) {
3432
+ const liveRegion = document.querySelector('[role="status"][aria-live="polite"]');
3433
+ if (liveRegion) {
3434
+ liveRegion.textContent = message;
3435
+ // Clear after announcement
3436
+ setTimeout(() => {
3437
+ liveRegion.textContent = '';
3438
+ }, 1000);
3439
+ }
3440
+ }
3441
+ /**
3442
+ * Update item elements
3443
+ */
3444
+ updateItems(elements) {
3445
+ this.itemElements = elements;
3446
+ // Set ARIA attributes on items
3447
+ if (this.config.enableARIA) {
3448
+ elements.forEach((el, index) => {
3449
+ el.setAttribute('role', 'listitem');
3450
+ el.setAttribute('aria-setsize', elements.length.toString());
3451
+ el.setAttribute('aria-posinset', (index + 1).toString());
3452
+ el.setAttribute('tabindex', '-1');
3453
+ });
3454
+ }
3455
+ }
3456
+ /**
3457
+ * Set focused index from outside
3458
+ */
3459
+ setFocusedIndex(index) {
3460
+ this.focusedIndex = index;
3461
+ }
3462
+ /**
3463
+ * Get current focused index
3464
+ */
3465
+ getFocusedIndex() {
3466
+ return this.focusedIndex;
3467
+ }
3468
+ /**
3469
+ * Cleanup accessibility features
3470
+ */
3471
+ cleanup() {
3472
+ if (this.containerElement) {
3473
+ this.containerElement.removeEventListener('keydown', this.handleKeyDown.bind(this));
3474
+ }
3475
+ const liveRegion = document.querySelector('[role="status"][aria-live="polite"]');
3476
+ if (liveRegion) {
3477
+ liveRegion.remove();
3478
+ }
3479
+ }
3480
+ }
3481
+
3482
+ /**
3483
+ * Animation Manager
3484
+ * Handles smooth transitions, staggered animations, and performance-optimized animations
3485
+ */
3486
+ class AnimationManager {
3487
+ constructor(config) {
3488
+ this.activeAnimations = new Map();
3489
+ this.prefersReducedMotion = false;
3490
+ this.config = {
3491
+ enableTransitions: true,
3492
+ enableStagger: true,
3493
+ staggerDelay: 50,
3494
+ transitionDuration: 300,
3495
+ easingFunction: 'ease-out',
3496
+ ...config
3497
+ };
3498
+ // Check for reduced motion preference
3499
+ if (typeof window !== 'undefined') {
3500
+ this.prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
3501
+ }
3502
+ }
3503
+ /**
3504
+ * Animate item entrance
3505
+ */
3506
+ animateEntrance(element, index) {
3507
+ if (this.prefersReducedMotion || !this.config.enableTransitions) {
3508
+ element.style.opacity = '1';
3509
+ element.style.transform = 'none';
3510
+ return Promise.resolve();
3511
+ }
3512
+ return new Promise((resolve) => {
3513
+ // Initial state
3514
+ element.style.opacity = '0';
3515
+ element.style.transform = 'translateY(20px)';
3516
+ element.style.transition = `opacity ${this.config.transitionDuration}ms ${this.config.easingFunction},
3517
+ transform ${this.config.transitionDuration}ms ${this.config.easingFunction}`;
3518
+ // Trigger reflow
3519
+ element.offsetHeight;
3520
+ // Animate to final state
3521
+ if (this.config.enableStagger) {
3522
+ setTimeout(() => {
3523
+ element.style.opacity = '1';
3524
+ element.style.transform = 'translateY(0)';
3525
+ setTimeout(resolve, this.config.transitionDuration);
3526
+ }, index * this.config.staggerDelay);
3527
+ }
3528
+ else {
3529
+ element.style.opacity = '1';
3530
+ element.style.transform = 'translateY(0)';
3531
+ setTimeout(resolve, this.config.transitionDuration);
3532
+ }
3533
+ });
3534
+ }
3535
+ /**
3536
+ * Animate item exit
3537
+ */
3538
+ animateExit(element) {
3539
+ if (this.prefersReducedMotion || !this.config.enableTransitions) {
3540
+ element.style.opacity = '0';
3541
+ return Promise.resolve();
3542
+ }
3543
+ return new Promise((resolve) => {
3544
+ element.style.transition = `opacity ${this.config.transitionDuration}ms ${this.config.easingFunction}`;
3545
+ element.style.opacity = '0';
3546
+ setTimeout(resolve, this.config.transitionDuration);
3547
+ });
3548
+ }
3549
+ /**
3550
+ * Animate scroll indicator
3551
+ */
3552
+ animateScrollIndicator(element, direction) {
3553
+ if (this.prefersReducedMotion)
3554
+ return;
3555
+ const translation = direction === 'down' ? 'translateY(5px)' : 'translateY(-5px)';
3556
+ element.style.transition = `transform 200ms ${this.config.easingFunction}`;
3557
+ element.style.transform = translation;
3558
+ setTimeout(() => {
3559
+ element.style.transform = 'translateY(0)';
3560
+ }, 200);
3561
+ }
3562
+ /**
3563
+ * Smooth scroll to position
3564
+ */
3565
+ smoothScroll(container, targetPosition, duration = 500) {
3566
+ return new Promise((resolve) => {
3567
+ if (this.prefersReducedMotion) {
3568
+ container.scrollTop = targetPosition;
3569
+ resolve();
3570
+ return;
3571
+ }
3572
+ const startPosition = container.scrollTop;
3573
+ const distance = targetPosition - startPosition;
3574
+ const startTime = performance.now();
3575
+ const easeInOutQuad = (t) => {
3576
+ return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
3577
+ };
3578
+ const animate = (currentTime) => {
3579
+ const timeElapsed = currentTime - startTime;
3580
+ const progress = Math.min(timeElapsed / duration, 1);
3581
+ const ease = easeInOutQuad(progress);
3582
+ container.scrollTop = startPosition + distance * ease;
3583
+ if (timeElapsed < duration) {
3584
+ requestAnimationFrame(animate);
3585
+ }
3586
+ else {
3587
+ resolve();
3588
+ }
3589
+ };
3590
+ requestAnimationFrame(animate);
3591
+ });
3592
+ }
3593
+ /**
3594
+ * Animate loading skeleton
3595
+ */
3596
+ animateSkeleton(element) {
3597
+ if (this.prefersReducedMotion)
3598
+ return;
3599
+ element.style.background = 'linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%)';
3600
+ element.style.backgroundSize = '200% 100%';
3601
+ element.style.animation = 'skeleton-loading 1.5s infinite';
3602
+ // Add keyframes if not already present
3603
+ if (!document.getElementById('skeleton-keyframes')) {
3604
+ const style = document.createElement('style');
3605
+ style.id = 'skeleton-keyframes';
3606
+ style.textContent = `
3607
+ @keyframes skeleton-loading {
3608
+ 0% { background-position: 200% 0; }
3609
+ 100% { background-position: -200% 0; }
3610
+ }
3611
+ `;
3612
+ document.head.appendChild(style);
3613
+ }
3614
+ }
3615
+ /**
3616
+ * Stop skeleton animation
3617
+ */
3618
+ stopSkeletonAnimation(element) {
3619
+ element.style.animation = '';
3620
+ element.style.background = '';
3621
+ element.style.backgroundSize = '';
3622
+ }
3623
+ /**
3624
+ * Animate item highlight
3625
+ */
3626
+ animateHighlight(element, color = '#ffeb3b', duration = 1000) {
3627
+ if (this.prefersReducedMotion)
3628
+ return Promise.resolve();
3629
+ return new Promise((resolve) => {
3630
+ const originalBackground = element.style.background;
3631
+ element.style.transition = `background ${duration / 2}ms ${this.config.easingFunction}`;
3632
+ element.style.background = color;
3633
+ setTimeout(() => {
3634
+ element.style.transition = `background ${duration / 2}ms ${this.config.easingFunction}`;
3635
+ element.style.background = originalBackground;
3636
+ setTimeout(resolve, duration / 2);
3637
+ }, duration / 2);
3638
+ });
3639
+ }
3640
+ /**
3641
+ * Batch animate multiple elements
3642
+ */
3643
+ async batchAnimate(elements, animation) {
3644
+ const promises = elements.map((el, index) => {
3645
+ if (animation === 'entrance') {
3646
+ return this.animateEntrance(el, index);
3647
+ }
3648
+ else {
3649
+ return this.animateExit(el);
3650
+ }
3651
+ });
3652
+ await Promise.all(promises);
3653
+ }
3654
+ /**
3655
+ * Cancel active animations
3656
+ */
3657
+ cancelAnimations() {
3658
+ this.activeAnimations.forEach((animation) => {
3659
+ animation.cancel();
3660
+ });
3661
+ this.activeAnimations.clear();
3662
+ }
3663
+ /**
3664
+ * Check if reduced motion is preferred
3665
+ */
3666
+ hasReducedMotion() {
3667
+ return this.prefersReducedMotion;
3668
+ }
3669
+ /**
3670
+ * Update animation config
3671
+ */
3672
+ updateConfig(config) {
3673
+ this.config = { ...this.config, ...config };
3674
+ }
3675
+ }
3676
+
2925
3677
  class ScrollObserver {
2926
3678
  constructor(container, callback, options) {
2927
3679
  this.observer = null;
@@ -3291,7 +4043,9 @@ const LazyScrollElement = typeof window !== 'undefined' && typeof HTMLElement !=
3291
4043
  ? LazyScrollElementClass // Will be replaced with actual element in browser
3292
4044
  : LazyScrollElementClass; // SSR-safe fallback
3293
4045
 
4046
+ exports.AccessibilityManager = AccessibilityManager;
3294
4047
  exports.AdaptiveBufferCalculator = AdaptiveBufferCalculator;
4048
+ exports.AnimationManager = AnimationManager;
3295
4049
  exports.BatchSizeOptimizer = BatchSizeOptimizer;
3296
4050
  exports.ContentComplexityAnalyzer = ContentComplexityAnalyzer;
3297
4051
  exports.DevicePerformanceMonitor = DevicePerformanceMonitor;
@@ -3308,6 +4062,8 @@ exports.MemoryManager = MemoryManager;
3308
4062
  exports.NetworkAwarePrefetchManager = NetworkAwarePrefetchManager;
3309
4063
  exports.NetworkAwareRequestQueue = NetworkAwareRequestQueue;
3310
4064
  exports.NetworkSpeedDetector = NetworkSpeedDetector;
4065
+ exports.PerformanceAnalytics = PerformanceAnalytics;
4066
+ exports.PerformanceDashboard = PerformanceDashboard;
3311
4067
  exports.PerformanceOptimizer = PerformanceOptimizer;
3312
4068
  exports.PreemptiveCache = PreemptiveCache;
3313
4069
  exports.PrefetchManager = PrefetchManager;