@therealtinhtute/baroiplayer 1.0.1 → 1.0.2
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/dist/context/media.js +2 -0
- package/dist/context/media.js.map +1 -0
- package/dist/context/media.mjs +15 -0
- package/dist/context/media.mjs.map +1 -0
- package/dist/context/store.js +2 -0
- package/dist/context/store.js.map +1 -0
- package/dist/context/store.mjs +5 -0
- package/dist/context/store.mjs.map +1 -0
- package/dist/context-Af84FynT.js +1179 -0
- package/dist/context-Af84FynT.js.map +1 -0
- package/dist/context-CwZnPdz0.cjs +23 -0
- package/dist/context-CwZnPdz0.cjs.map +1 -0
- package/dist/core-events-B5W_j8yU.js +480 -0
- package/dist/core-events-B5W_j8yU.js.map +1 -0
- package/dist/core-events-CN0-Vhhq.cjs +2 -0
- package/dist/core-events-CN0-Vhhq.cjs.map +1 -0
- package/dist/core-plugins-Bq9KLany.js +696 -0
- package/dist/core-plugins-Bq9KLany.js.map +1 -0
- package/dist/core-plugins-CPDSHMiQ.cjs +2 -0
- package/dist/core-plugins-CPDSHMiQ.cjs.map +1 -0
- package/dist/core.js +37 -0
- package/dist/core.js.map +1 -0
- package/dist/core.mjs +1217 -0
- package/dist/core.mjs.map +1 -0
- package/dist/enhanced-components-CXnYiOt6.cjs +2 -0
- package/dist/enhanced-components-CXnYiOt6.cjs.map +1 -0
- package/dist/enhanced-components-Da0TSvKe.js +1073 -0
- package/dist/enhanced-components-Da0TSvKe.js.map +1 -0
- package/dist/hooks-BhW_i-9L.js +2013 -0
- package/dist/hooks-BhW_i-9L.js.map +1 -0
- package/dist/hooks-DTXeB5Z-.cjs +4 -0
- package/dist/hooks-DTXeB5Z-.cjs.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -0
- package/dist/index.mjs.map +1 -0
- package/dist/minimal-components-B0bILe18.js +2002 -0
- package/dist/minimal-components-B0bILe18.js.map +1 -0
- package/dist/minimal-components-BsqodtY8.cjs +2 -0
- package/dist/minimal-components-BsqodtY8.cjs.map +1 -0
- package/dist/minimal-components.css +589 -0
- package/dist/mona-loading.gif +0 -0
- package/dist/performance-monitor--rzKTlbj.js +302 -0
- package/dist/performance-monitor--rzKTlbj.js.map +1 -0
- package/dist/performance-monitor-cjIvZE2D.cjs +2 -0
- package/dist/performance-monitor-cjIvZE2D.cjs.map +1 -0
- package/dist/src/components/AnimateLoading.tsx +1 -1
- package/dist/src/components/enhanced/debug-panel.tsx +1 -1
- package/dist/src/components/media-player.tsx +2 -2
- package/dist/src/components/ui/media-resource-preloader.tsx +9 -11
- package/dist/src/components/ui/seek-bar.tsx +1 -1
- package/dist/src/core/plugins/enhanced-plugin-system.ts +14 -8
- package/dist/src/core/providers/enhanced-hls-provider.ts +22 -53
- package/dist/src/hooks/use-enhanced-media-player.ts +19 -2
- package/dist/src/types/index.ts +40 -5
- package/dist/styles/minimal-player.css +589 -0
- package/dist/utils-Db13763z.cjs +9 -0
- package/dist/utils-Db13763z.cjs.map +1 -0
- package/dist/utils-nTO4AnHo.js +2809 -0
- package/dist/utils-nTO4AnHo.js.map +1 -0
- package/dist/utils.js +2 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +7 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +1 -1
- package/src/components/AnimateLoading.tsx +1 -1
- package/src/components/enhanced/debug-panel.tsx +1 -1
- package/src/components/media-player.tsx +2 -2
- package/src/components/ui/media-resource-preloader.tsx +9 -11
- package/src/components/ui/seek-bar.tsx +1 -1
- package/src/core/plugins/enhanced-plugin-system.ts +14 -8
- package/src/core/providers/enhanced-hls-provider.ts +22 -53
- package/src/hooks/use-enhanced-media-player.ts +19 -2
- package/src/types/index.ts +40 -5
package/dist/core.mjs
ADDED
|
@@ -0,0 +1,1217 @@
|
|
|
1
|
+
var k = Object.defineProperty;
|
|
2
|
+
var A = (o, e, t) => e in o ? k(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
|
|
3
|
+
var u = (o, e, t) => A(o, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { C as B, P as R } from "./core-plugins-Bq9KLany.js";
|
|
5
|
+
import { A as ye, B as we, a as Te, d as Se, c as ve, i as be, b as Pe, h as Me, j as Le, g as Ee, f as Ce, e as ke, l as Ae, k as Be } from "./core-plugins-Bq9KLany.js";
|
|
6
|
+
import { E as I } from "./core-events-B5W_j8yU.js";
|
|
7
|
+
import { a as Ie, b as Ne, M as $e, f as xe, c as Fe, d as Ue, e as De, n as Oe, u as ze, m as _e, p as Ve, h as He, j as je, k as Ye, g as Qe, l as We, i as Ke, o as Je } from "./core-events-B5W_j8yU.js";
|
|
8
|
+
import { j as f } from "./context-Af84FynT.js";
|
|
9
|
+
import m, { useMemo as N, createContext as $, useContext as x, lazy as h } from "react";
|
|
10
|
+
import { a as F } from "./performance-monitor--rzKTlbj.js";
|
|
11
|
+
import { b as Ge, P as Xe, d as Ze, p as et, u as tt, w as rt } from "./performance-monitor--rzKTlbj.js";
|
|
12
|
+
class P {
|
|
13
|
+
constructor() {
|
|
14
|
+
u(this, "results", []);
|
|
15
|
+
u(this, "regressionDetector", new F());
|
|
16
|
+
}
|
|
17
|
+
async runTest(e, t) {
|
|
18
|
+
const r = [];
|
|
19
|
+
let n = 0, s = 0, i;
|
|
20
|
+
try {
|
|
21
|
+
for (let d = 0; d < e.warmupIterations; d++)
|
|
22
|
+
await t();
|
|
23
|
+
global.gc && global.gc(), n = this.getMemoryUsage();
|
|
24
|
+
for (let d = 0; d < e.iterations; d++) {
|
|
25
|
+
const S = performance.now();
|
|
26
|
+
await t();
|
|
27
|
+
const C = performance.now();
|
|
28
|
+
r.push(C - S);
|
|
29
|
+
}
|
|
30
|
+
s = this.getMemoryUsage();
|
|
31
|
+
} catch (d) {
|
|
32
|
+
i = d instanceof Error ? d.message : String(d);
|
|
33
|
+
}
|
|
34
|
+
const a = r.reduce((d, S) => d + S, 0) / r.length, c = Math.min(...r), g = Math.max(...r), T = s - n, y = !i && a <= e.expectedThreshold.renderTime && T <= e.expectedThreshold.memoryUsage, w = {
|
|
35
|
+
testName: e.name,
|
|
36
|
+
passed: y,
|
|
37
|
+
metrics: {
|
|
38
|
+
averageRenderTime: a,
|
|
39
|
+
minRenderTime: isFinite(c) ? c : 0,
|
|
40
|
+
maxRenderTime: isFinite(g) ? g : 0,
|
|
41
|
+
memoryUsage: T,
|
|
42
|
+
iterations: e.iterations
|
|
43
|
+
},
|
|
44
|
+
threshold: e.expectedThreshold,
|
|
45
|
+
error: i
|
|
46
|
+
};
|
|
47
|
+
return this.results.push(w), w;
|
|
48
|
+
}
|
|
49
|
+
getMemoryUsage() {
|
|
50
|
+
return "memory" in performance && performance.memory.usedJSHeapSize || 0;
|
|
51
|
+
}
|
|
52
|
+
// Component rendering performance test
|
|
53
|
+
async testComponentRender(e, t, r = 16) {
|
|
54
|
+
const n = {
|
|
55
|
+
name: `${e} Render Performance`,
|
|
56
|
+
iterations: 100,
|
|
57
|
+
warmupIterations: 10,
|
|
58
|
+
timeout: 5e3,
|
|
59
|
+
expectedThreshold: {
|
|
60
|
+
renderTime: r,
|
|
61
|
+
memoryUsage: 1048576
|
|
62
|
+
// 1MB
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return this.runTest(n, t);
|
|
66
|
+
}
|
|
67
|
+
// Bundle loading performance test
|
|
68
|
+
async testBundleLoading(e, t = 1e3) {
|
|
69
|
+
const r = {
|
|
70
|
+
name: `Bundle Loading: ${e}`,
|
|
71
|
+
iterations: 5,
|
|
72
|
+
warmupIterations: 1,
|
|
73
|
+
timeout: 1e4,
|
|
74
|
+
expectedThreshold: {
|
|
75
|
+
renderTime: t,
|
|
76
|
+
memoryUsage: 5242880
|
|
77
|
+
// 5MB
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
return this.runTest(r, async () => {
|
|
81
|
+
const n = performance.now();
|
|
82
|
+
try {
|
|
83
|
+
const i = await fetch(e);
|
|
84
|
+
if (!i.ok)
|
|
85
|
+
throw new Error(`Failed to load bundle: ${i.status}`);
|
|
86
|
+
await i.blob();
|
|
87
|
+
} catch (i) {
|
|
88
|
+
console.warn(`Bundle loading test failed for ${e}:`, i);
|
|
89
|
+
}
|
|
90
|
+
return performance.now() - n;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Memory leak detection test
|
|
94
|
+
async testMemoryLeaks(e, t = 1e3) {
|
|
95
|
+
const r = {
|
|
96
|
+
name: "Memory Leak Detection",
|
|
97
|
+
iterations: t,
|
|
98
|
+
warmupIterations: 100,
|
|
99
|
+
timeout: 3e4,
|
|
100
|
+
expectedThreshold: {
|
|
101
|
+
renderTime: 1 / 0,
|
|
102
|
+
// Not testing render time
|
|
103
|
+
memoryUsage: 10485760
|
|
104
|
+
// 10MB max increase
|
|
105
|
+
}
|
|
106
|
+
}, n = this.getMemoryUsage(), s = await this.runTest(r, e), a = this.getMemoryUsage() - n, c = a > r.expectedThreshold.memoryUsage;
|
|
107
|
+
return {
|
|
108
|
+
...s,
|
|
109
|
+
passed: s.passed && !c,
|
|
110
|
+
error: c ? `Potential memory leak detected: ${Math.round(a / 1024 / 1024)}MB increase` : s.error
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
// Interaction delay test
|
|
114
|
+
async testInteractionDelay(e, t = 100) {
|
|
115
|
+
const r = {
|
|
116
|
+
name: "Interaction Delay",
|
|
117
|
+
iterations: 50,
|
|
118
|
+
warmupIterations: 5,
|
|
119
|
+
timeout: 5e3,
|
|
120
|
+
expectedThreshold: {
|
|
121
|
+
renderTime: t,
|
|
122
|
+
memoryUsage: 1048576
|
|
123
|
+
// 1MB
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
return this.runTest(r, e);
|
|
127
|
+
}
|
|
128
|
+
// Regression testing
|
|
129
|
+
async runRegressionTests(e, t) {
|
|
130
|
+
t && this.regressionDetector.setBaseline(t);
|
|
131
|
+
const r = this.regressionDetector.detectRegression(e);
|
|
132
|
+
return { passed: r.length === 0, regressions: r };
|
|
133
|
+
}
|
|
134
|
+
// Get all test results
|
|
135
|
+
getResults() {
|
|
136
|
+
return [...this.results];
|
|
137
|
+
}
|
|
138
|
+
// Get test summary
|
|
139
|
+
getSummary() {
|
|
140
|
+
const e = this.results.length, t = this.results.filter((s) => s.passed).length, r = e - t, n = e > 0 ? t / e * 100 : 0;
|
|
141
|
+
return { totalTests: e, passedTests: t, failedTests: r, passRate: n };
|
|
142
|
+
}
|
|
143
|
+
// Clear test results
|
|
144
|
+
clearResults() {
|
|
145
|
+
this.results = [];
|
|
146
|
+
}
|
|
147
|
+
// Generate performance report
|
|
148
|
+
generateReport() {
|
|
149
|
+
const e = this.getSummary();
|
|
150
|
+
let t = `Performance Test Report
|
|
151
|
+
`;
|
|
152
|
+
return t += `========================
|
|
153
|
+
|
|
154
|
+
`, t += `Total Tests: ${e.totalTests}
|
|
155
|
+
`, t += `Passed: ${e.passedTests}
|
|
156
|
+
`, t += `Failed: ${e.failedTests}
|
|
157
|
+
`, t += `Pass Rate: ${e.passRate.toFixed(1)}%
|
|
158
|
+
|
|
159
|
+
`, this.results.length > 0 && (t += `Detailed Results:
|
|
160
|
+
`, t += `-----------------
|
|
161
|
+
|
|
162
|
+
`, this.results.forEach((r, n) => {
|
|
163
|
+
t += `${n + 1}. ${r.testName}
|
|
164
|
+
`, t += ` Status: ${r.passed ? "PASS" : "FAIL"}
|
|
165
|
+
`, t += ` Average Render Time: ${r.metrics.averageRenderTime.toFixed(2)}ms
|
|
166
|
+
`, t += ` Min/Max Render Time: ${r.metrics.minRenderTime.toFixed(2)}ms / ${r.metrics.maxRenderTime.toFixed(2)}ms
|
|
167
|
+
`, t += ` Memory Usage: ${Math.round(r.metrics.memoryUsage / 1024)} KB
|
|
168
|
+
`, t += ` Iterations: ${r.metrics.iterations}
|
|
169
|
+
`, r.error && (t += ` Error: ${r.error}
|
|
170
|
+
`), t += `
|
|
171
|
+
`;
|
|
172
|
+
})), t;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const v = new P(), te = {
|
|
176
|
+
// Test component rendering performance
|
|
177
|
+
async testComponent(o, e = {}, t = 16) {
|
|
178
|
+
return v.testComponentRender(
|
|
179
|
+
o.displayName || o.name || "Component",
|
|
180
|
+
() => ({ type: o, props: e }),
|
|
181
|
+
t
|
|
182
|
+
);
|
|
183
|
+
},
|
|
184
|
+
// Test hook performance
|
|
185
|
+
async testHook(o, e, t = 1) {
|
|
186
|
+
const r = {
|
|
187
|
+
name: `Hook Performance: ${e}`,
|
|
188
|
+
iterations: 1e3,
|
|
189
|
+
warmupIterations: 100,
|
|
190
|
+
timeout: 5e3,
|
|
191
|
+
expectedThreshold: {
|
|
192
|
+
renderTime: t,
|
|
193
|
+
memoryUsage: 1048576
|
|
194
|
+
// 1MB
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
return v.runTest(r, o);
|
|
198
|
+
},
|
|
199
|
+
// Test async operation performance
|
|
200
|
+
async testAsyncOperation(o, e, t = 1e3) {
|
|
201
|
+
const r = {
|
|
202
|
+
name: `Async Operation: ${e}`,
|
|
203
|
+
iterations: 10,
|
|
204
|
+
warmupIterations: 2,
|
|
205
|
+
timeout: 3e4,
|
|
206
|
+
expectedThreshold: {
|
|
207
|
+
renderTime: t,
|
|
208
|
+
memoryUsage: 2097152
|
|
209
|
+
// 2MB
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
return v.runTest(r, o);
|
|
213
|
+
},
|
|
214
|
+
// Test bundle size impact
|
|
215
|
+
async measureBundleImpact(o, e, t) {
|
|
216
|
+
const r = performance.memory?.usedJSHeapSize || 0, n = performance.now();
|
|
217
|
+
o();
|
|
218
|
+
const s = performance.memory?.usedJSHeapSize || 0, i = performance.now();
|
|
219
|
+
e();
|
|
220
|
+
const a = performance.memory?.usedJSHeapSize || 0, c = performance.now();
|
|
221
|
+
return {
|
|
222
|
+
bundleIncrease: a - r,
|
|
223
|
+
memoryIncrease: s - r,
|
|
224
|
+
renderTimeImpact: c - i - (i - n)
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
class U {
|
|
229
|
+
constructor() {
|
|
230
|
+
u(this, "benchmark", new P());
|
|
231
|
+
u(this, "suites", /* @__PURE__ */ new Map());
|
|
232
|
+
}
|
|
233
|
+
// Register a test suite
|
|
234
|
+
registerSuite(e, t) {
|
|
235
|
+
this.suites.set(e, t);
|
|
236
|
+
}
|
|
237
|
+
// Run all tests in a suite
|
|
238
|
+
async runSuite(e, t) {
|
|
239
|
+
const r = this.suites.get(e);
|
|
240
|
+
if (!r)
|
|
241
|
+
throw new Error(`Test suite '${e}' not found`);
|
|
242
|
+
const n = [];
|
|
243
|
+
for (const s of r) {
|
|
244
|
+
const i = t.get(s.name);
|
|
245
|
+
if (!i) {
|
|
246
|
+
console.warn(`No implementation found for test '${s.name}'`);
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
const a = await this.benchmark.runTest(s, i);
|
|
250
|
+
n.push(a);
|
|
251
|
+
}
|
|
252
|
+
return n;
|
|
253
|
+
}
|
|
254
|
+
// Run all registered test suites
|
|
255
|
+
async runAllSuites(e) {
|
|
256
|
+
const t = /* @__PURE__ */ new Map();
|
|
257
|
+
for (const [r] of this.suites) {
|
|
258
|
+
const n = e.get(r);
|
|
259
|
+
if (!n) {
|
|
260
|
+
console.warn(`No implementations found for suite '${r}'`);
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
const s = await this.runSuite(r, n);
|
|
264
|
+
t.set(r, s);
|
|
265
|
+
}
|
|
266
|
+
return t;
|
|
267
|
+
}
|
|
268
|
+
// Generate comprehensive report
|
|
269
|
+
generateComprehensiveReport() {
|
|
270
|
+
this.benchmark.getSummary();
|
|
271
|
+
let e = this.benchmark.generateReport();
|
|
272
|
+
if (this.suites.size > 0) {
|
|
273
|
+
e += `
|
|
274
|
+
Test Suites:
|
|
275
|
+
`, e += `============
|
|
276
|
+
|
|
277
|
+
`;
|
|
278
|
+
for (const [t, r] of this.suites)
|
|
279
|
+
e += `Suite: ${t}
|
|
280
|
+
`, e += `Tests: ${r.length}
|
|
281
|
+
|
|
282
|
+
`;
|
|
283
|
+
}
|
|
284
|
+
return e;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const re = new U(), D = [
|
|
288
|
+
// Bundle size budgets
|
|
289
|
+
{
|
|
290
|
+
name: "Main Bundle Size (ESM)",
|
|
291
|
+
category: "bundle",
|
|
292
|
+
limit: 250 * 1024,
|
|
293
|
+
// 250KB
|
|
294
|
+
unit: "bytes",
|
|
295
|
+
severity: "error",
|
|
296
|
+
description: "Main bundle should stay under 250KB for fast initial loading"
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: "Main Bundle Size (CJS)",
|
|
300
|
+
category: "bundle",
|
|
301
|
+
limit: 200 * 1024,
|
|
302
|
+
// 200KB
|
|
303
|
+
unit: "bytes",
|
|
304
|
+
severity: "error",
|
|
305
|
+
description: "CJS bundle should be smaller due to better compression"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
name: "Core Module Size",
|
|
309
|
+
category: "bundle",
|
|
310
|
+
limit: 15 * 1024,
|
|
311
|
+
// 15KB
|
|
312
|
+
unit: "bytes",
|
|
313
|
+
severity: "warning",
|
|
314
|
+
description: "Core architecture should remain lightweight"
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
name: "Enhanced Components Size",
|
|
318
|
+
category: "bundle",
|
|
319
|
+
limit: 40 * 1024,
|
|
320
|
+
// 40KB
|
|
321
|
+
unit: "bytes",
|
|
322
|
+
severity: "warning",
|
|
323
|
+
description: "Enhanced components bundle size"
|
|
324
|
+
},
|
|
325
|
+
// Runtime performance budgets
|
|
326
|
+
{
|
|
327
|
+
name: "Component Render Time",
|
|
328
|
+
category: "runtime",
|
|
329
|
+
limit: 16,
|
|
330
|
+
// 16ms for 60fps
|
|
331
|
+
unit: "ms",
|
|
332
|
+
severity: "error",
|
|
333
|
+
description: "Component rendering should complete within one frame"
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
name: "First Input Delay",
|
|
337
|
+
category: "runtime",
|
|
338
|
+
limit: 100,
|
|
339
|
+
// 100ms
|
|
340
|
+
unit: "ms",
|
|
341
|
+
severity: "error",
|
|
342
|
+
description: "First Input Delay should be under 100ms for good UX"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
name: "Largest Contentful Paint",
|
|
346
|
+
category: "runtime",
|
|
347
|
+
limit: 2500,
|
|
348
|
+
// 2.5s
|
|
349
|
+
unit: "ms",
|
|
350
|
+
severity: "warning",
|
|
351
|
+
description: "LCP should be under 2.5s for good Core Web Vitals score"
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
name: "Cumulative Layout Shift",
|
|
355
|
+
category: "runtime",
|
|
356
|
+
limit: 0.1,
|
|
357
|
+
unit: "score",
|
|
358
|
+
severity: "warning",
|
|
359
|
+
description: "CLS should be under 0.1 for good visual stability"
|
|
360
|
+
},
|
|
361
|
+
// Memory budgets
|
|
362
|
+
{
|
|
363
|
+
name: "Memory Usage",
|
|
364
|
+
category: "memory",
|
|
365
|
+
limit: 50 * 1024 * 1024,
|
|
366
|
+
// 50MB
|
|
367
|
+
unit: "bytes",
|
|
368
|
+
severity: "warning",
|
|
369
|
+
description: "Memory usage should stay under 50MB for good performance"
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
name: "Memory Increase Per Operation",
|
|
373
|
+
category: "memory",
|
|
374
|
+
limit: 1024 * 1024,
|
|
375
|
+
// 1MB
|
|
376
|
+
unit: "bytes",
|
|
377
|
+
severity: "error",
|
|
378
|
+
description: "Each operation should not increase memory by more than 1MB"
|
|
379
|
+
},
|
|
380
|
+
// Network budgets (for media loading)
|
|
381
|
+
{
|
|
382
|
+
name: "Media Load Time",
|
|
383
|
+
category: "network",
|
|
384
|
+
limit: 3e3,
|
|
385
|
+
// 3s
|
|
386
|
+
unit: "ms",
|
|
387
|
+
severity: "warning",
|
|
388
|
+
description: "Media should start loading within 3 seconds"
|
|
389
|
+
}
|
|
390
|
+
];
|
|
391
|
+
class O {
|
|
392
|
+
constructor(e = D, t = {
|
|
393
|
+
enabled: !0,
|
|
394
|
+
channels: [{ type: "console", config: {} }],
|
|
395
|
+
threshold: 1,
|
|
396
|
+
cooldown: 300 * 1e3
|
|
397
|
+
// 5 minutes
|
|
398
|
+
}) {
|
|
399
|
+
u(this, "budgets", /* @__PURE__ */ new Map());
|
|
400
|
+
u(this, "violations", []);
|
|
401
|
+
u(this, "alertConfig");
|
|
402
|
+
u(this, "lastAlertTime", 0);
|
|
403
|
+
e.forEach((r) => {
|
|
404
|
+
this.budgets.set(r.name, r);
|
|
405
|
+
}), this.alertConfig = t;
|
|
406
|
+
}
|
|
407
|
+
// Check a single metric against budgets
|
|
408
|
+
checkMetric(e, t, r = "runtime") {
|
|
409
|
+
const n = [];
|
|
410
|
+
for (const [s, i] of this.budgets)
|
|
411
|
+
if (i.category === r && (s.includes(e) || e.includes(s.split(" ")[0]?.toLowerCase() || "")) && t > i.limit) {
|
|
412
|
+
const a = {
|
|
413
|
+
budget: i,
|
|
414
|
+
actualValue: t,
|
|
415
|
+
overageAmount: t - i.limit,
|
|
416
|
+
overagePercentage: (t - i.limit) / i.limit * 100,
|
|
417
|
+
timestamp: Date.now()
|
|
418
|
+
};
|
|
419
|
+
n.push(a), this.violations.push(a);
|
|
420
|
+
}
|
|
421
|
+
return n.length > 0 && this.handleViolations(n), n;
|
|
422
|
+
}
|
|
423
|
+
// Check bundle sizes
|
|
424
|
+
async checkBundleSizes(e) {
|
|
425
|
+
const t = [];
|
|
426
|
+
return typeof window < "u" || typeof process > "u" ? (console.warn("Bundle size checking is only available in Node.js environment"), t) : (console.warn("Bundle size checking disabled - use Node.js cicdIntegration from @rp/baroiplayer/core/performance/cicd for CI/CD environments"), t);
|
|
427
|
+
}
|
|
428
|
+
// Check runtime performance
|
|
429
|
+
checkRuntimeMetrics(e) {
|
|
430
|
+
const t = [];
|
|
431
|
+
return e.renderTime !== void 0 && t.push(...this.checkMetric("Component Render Time", e.renderTime, "runtime")), e.fid !== void 0 && t.push(...this.checkMetric("First Input Delay", e.fid, "runtime")), e.lcp !== void 0 && t.push(...this.checkMetric("Largest Contentful Paint", e.lcp, "runtime")), e.cls !== void 0 && t.push(...this.checkMetric("Cumulative Layout Shift", e.cls, "runtime")), e.memoryUsage !== void 0 && t.push(...this.checkMetric("Memory Usage", e.memoryUsage, "memory")), e.mediaLoadTime !== void 0 && t.push(...this.checkMetric("Media Load Time", e.mediaLoadTime, "network")), t;
|
|
432
|
+
}
|
|
433
|
+
// Handle budget violations
|
|
434
|
+
async handleViolations(e) {
|
|
435
|
+
if (!this.alertConfig.enabled) return;
|
|
436
|
+
const t = Date.now();
|
|
437
|
+
e.filter((n) => n.budget.severity === "error").length >= this.alertConfig.threshold && t - this.lastAlertTime >= this.alertConfig.cooldown && (await this.sendAlerts(e), this.lastAlertTime = t);
|
|
438
|
+
}
|
|
439
|
+
// Send alerts through configured channels
|
|
440
|
+
async sendAlerts(e) {
|
|
441
|
+
const t = this.formatAlertMessage(e);
|
|
442
|
+
for (const r of this.alertConfig.channels)
|
|
443
|
+
try {
|
|
444
|
+
await this.sendAlert(r, t);
|
|
445
|
+
} catch (n) {
|
|
446
|
+
console.error(`Failed to send alert via ${r.type}:`, n);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
// Format alert message
|
|
450
|
+
formatAlertMessage(e) {
|
|
451
|
+
let t = `🚨 Performance Budget Violations Detected!
|
|
452
|
+
|
|
453
|
+
`;
|
|
454
|
+
return e.forEach((r) => {
|
|
455
|
+
const { budget: n, actualValue: s, overageAmount: i, overagePercentage: a } = r;
|
|
456
|
+
this.getUnitDisplay(n.unit), t += `❌ ${n.name}
|
|
457
|
+
`, t += ` Limit: ${this.formatValue(n.limit, n.unit)}
|
|
458
|
+
`, t += ` Actual: ${this.formatValue(s, n.unit)}
|
|
459
|
+
`, t += ` Overage: ${this.formatValue(i, n.unit)} (+${a.toFixed(1)}%)
|
|
460
|
+
`, t += ` Severity: ${n.severity.toUpperCase()}
|
|
461
|
+
|
|
462
|
+
`;
|
|
463
|
+
}), t += `Time: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
464
|
+
`, t += `Total Violations: ${e.length}`, t;
|
|
465
|
+
}
|
|
466
|
+
// Send alert to specific channel
|
|
467
|
+
async sendAlert(e, t) {
|
|
468
|
+
switch (e.type) {
|
|
469
|
+
case "console":
|
|
470
|
+
console.error(t);
|
|
471
|
+
break;
|
|
472
|
+
case "webhook":
|
|
473
|
+
if (e.config.url) {
|
|
474
|
+
const r = await fetch(e.config.url, {
|
|
475
|
+
method: "POST",
|
|
476
|
+
headers: { "Content-Type": "application/json" },
|
|
477
|
+
body: JSON.stringify({ text: t, timestamp: Date.now() })
|
|
478
|
+
});
|
|
479
|
+
if (!r.ok)
|
|
480
|
+
throw new Error(`Webhook failed: ${r.status}`);
|
|
481
|
+
}
|
|
482
|
+
break;
|
|
483
|
+
case "slack":
|
|
484
|
+
if (e.config.url) {
|
|
485
|
+
const r = await fetch(e.config.url, {
|
|
486
|
+
method: "POST",
|
|
487
|
+
headers: { "Content-Type": "application/json" },
|
|
488
|
+
body: JSON.stringify({
|
|
489
|
+
text: t,
|
|
490
|
+
channel: e.config.channel,
|
|
491
|
+
username: "BaroiPlayer Performance Monitor"
|
|
492
|
+
})
|
|
493
|
+
});
|
|
494
|
+
if (!r.ok)
|
|
495
|
+
throw new Error(`Slack webhook failed: ${r.status}`);
|
|
496
|
+
}
|
|
497
|
+
break;
|
|
498
|
+
default:
|
|
499
|
+
console.warn(`Unsupported alert channel: ${e.type}`);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
// Helper methods
|
|
503
|
+
formatValue(e, t) {
|
|
504
|
+
switch (t) {
|
|
505
|
+
case "bytes":
|
|
506
|
+
return this.formatBytes(e);
|
|
507
|
+
case "ms":
|
|
508
|
+
return `${e.toFixed(2)}ms`;
|
|
509
|
+
case "score":
|
|
510
|
+
return e.toFixed(3);
|
|
511
|
+
case "percent":
|
|
512
|
+
return `${e.toFixed(1)}%`;
|
|
513
|
+
default:
|
|
514
|
+
return e.toString();
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
formatBytes(e) {
|
|
518
|
+
return e >= 1024 * 1024 ? `${(e / 1024 / 1024).toFixed(2)}MB` : e >= 1024 ? `${(e / 1024).toFixed(2)}KB` : `${e}B`;
|
|
519
|
+
}
|
|
520
|
+
getUnitDisplay(e) {
|
|
521
|
+
return {
|
|
522
|
+
bytes: "bytes",
|
|
523
|
+
ms: "milliseconds",
|
|
524
|
+
score: "score",
|
|
525
|
+
percent: "percent"
|
|
526
|
+
}[e] || e;
|
|
527
|
+
}
|
|
528
|
+
// Management methods
|
|
529
|
+
addBudget(e) {
|
|
530
|
+
this.budgets.set(e.name, e);
|
|
531
|
+
}
|
|
532
|
+
removeBudget(e) {
|
|
533
|
+
this.budgets.delete(e);
|
|
534
|
+
}
|
|
535
|
+
updateBudget(e, t) {
|
|
536
|
+
const r = this.budgets.get(e);
|
|
537
|
+
r && this.budgets.set(e, { ...r, ...t });
|
|
538
|
+
}
|
|
539
|
+
getBudgets() {
|
|
540
|
+
return Array.from(this.budgets.values());
|
|
541
|
+
}
|
|
542
|
+
getViolations(e) {
|
|
543
|
+
return e ? this.violations.filter((t) => t.timestamp >= e) : [...this.violations];
|
|
544
|
+
}
|
|
545
|
+
clearViolations() {
|
|
546
|
+
this.violations = [];
|
|
547
|
+
}
|
|
548
|
+
getViolationSummary() {
|
|
549
|
+
const e = {}, t = {};
|
|
550
|
+
return this.violations.forEach((r) => {
|
|
551
|
+
const n = r.budget.category, s = r.budget.severity;
|
|
552
|
+
e[n] = (e[n] || 0) + 1, t[s] = (t[s] || 0) + 1;
|
|
553
|
+
}), {
|
|
554
|
+
total: this.violations.length,
|
|
555
|
+
byCategory: e,
|
|
556
|
+
bySeverity: t
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
const ne = new O(), z = {
|
|
561
|
+
preloadStrategy: "metadata",
|
|
562
|
+
adaptiveBitrate: !0,
|
|
563
|
+
maxPreloadSize: 2 * 1024 * 1024,
|
|
564
|
+
// 2MB
|
|
565
|
+
networkThresholds: {
|
|
566
|
+
"2g": { maxBitrate: 128, preload: !1 },
|
|
567
|
+
// 128 kbps
|
|
568
|
+
"3g": { maxBitrate: 500, preload: !1 },
|
|
569
|
+
// 500 kbps
|
|
570
|
+
"4g": { maxBitrate: 2e3, preload: !0 },
|
|
571
|
+
// 2 Mbps
|
|
572
|
+
"5g": { maxBitrate: 1e4, preload: !0 }
|
|
573
|
+
// 10 Mbps
|
|
574
|
+
},
|
|
575
|
+
bufferSize: 10,
|
|
576
|
+
// 10 seconds
|
|
577
|
+
enableServiceWorker: !0
|
|
578
|
+
};
|
|
579
|
+
class _ {
|
|
580
|
+
constructor() {
|
|
581
|
+
u(this, "connection");
|
|
582
|
+
u(this, "listeners", /* @__PURE__ */ new Set());
|
|
583
|
+
u(this, "currentInfo");
|
|
584
|
+
if (typeof window > "u" || typeof navigator > "u") {
|
|
585
|
+
this.connection = null, this.currentInfo = {
|
|
586
|
+
effectiveType: "unknown",
|
|
587
|
+
downlink: 0,
|
|
588
|
+
rtt: 0,
|
|
589
|
+
saveData: !1,
|
|
590
|
+
isOnline: !0
|
|
591
|
+
};
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
this.connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection, this.currentInfo = this.getNetworkInfo(), this.initializeListeners();
|
|
595
|
+
}
|
|
596
|
+
getNetworkInfo() {
|
|
597
|
+
if (typeof navigator > "u")
|
|
598
|
+
return {
|
|
599
|
+
effectiveType: "unknown",
|
|
600
|
+
downlink: 0,
|
|
601
|
+
rtt: 0,
|
|
602
|
+
saveData: !1,
|
|
603
|
+
isOnline: !0
|
|
604
|
+
};
|
|
605
|
+
const e = navigator.onLine;
|
|
606
|
+
return this.connection ? {
|
|
607
|
+
effectiveType: this.connection.effectiveType || "unknown",
|
|
608
|
+
downlink: this.connection.downlink || 0,
|
|
609
|
+
rtt: this.connection.rtt || 0,
|
|
610
|
+
saveData: this.connection.saveData || !1,
|
|
611
|
+
isOnline: e
|
|
612
|
+
} : {
|
|
613
|
+
effectiveType: "unknown",
|
|
614
|
+
downlink: 0,
|
|
615
|
+
rtt: 0,
|
|
616
|
+
saveData: !1,
|
|
617
|
+
isOnline: e
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
initializeListeners() {
|
|
621
|
+
typeof window > "u" || (this.connection && this.connection.addEventListener("change", this.handleNetworkChange.bind(this)), window.addEventListener("online", this.handleNetworkChange.bind(this)), window.addEventListener("offline", this.handleNetworkChange.bind(this)));
|
|
622
|
+
}
|
|
623
|
+
handleNetworkChange() {
|
|
624
|
+
const e = this.getNetworkInfo();
|
|
625
|
+
this.currentInfo = e, this.listeners.forEach((t) => t(e));
|
|
626
|
+
}
|
|
627
|
+
getCurrentNetworkInfo() {
|
|
628
|
+
return { ...this.currentInfo };
|
|
629
|
+
}
|
|
630
|
+
subscribe(e) {
|
|
631
|
+
return this.listeners.add(e), () => this.listeners.delete(e);
|
|
632
|
+
}
|
|
633
|
+
// Estimate available bandwidth with fallback detection
|
|
634
|
+
async estimateBandwidth() {
|
|
635
|
+
if (this.connection && this.connection.downlink)
|
|
636
|
+
return this.connection.downlink * 1e3;
|
|
637
|
+
try {
|
|
638
|
+
const e = performance.now(), n = await (await fetch("/api/bandwidth-test?size=100kb")).blob(), i = (performance.now() - e) / 1e3;
|
|
639
|
+
return n.size * 8 / i / 1e3;
|
|
640
|
+
} catch (e) {
|
|
641
|
+
return console.warn("Bandwidth estimation failed:", e), 1e3;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
class M {
|
|
646
|
+
constructor(e = {}) {
|
|
647
|
+
u(this, "config");
|
|
648
|
+
u(this, "networkMonitor");
|
|
649
|
+
u(this, "loadingMetrics", /* @__PURE__ */ new Map());
|
|
650
|
+
u(this, "preloadCache", /* @__PURE__ */ new Map());
|
|
651
|
+
this.config = { ...z, ...e }, this.networkMonitor = new _(), this.initializeNetworkMonitoring();
|
|
652
|
+
}
|
|
653
|
+
initializeNetworkMonitoring() {
|
|
654
|
+
this.networkMonitor.subscribe((e) => {
|
|
655
|
+
this.handleNetworkChange(e);
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
handleNetworkChange(e) {
|
|
659
|
+
console.log("Network changed:", e), this.config.adaptiveBitrate && this.adjustQualityForNetwork(e), (e.effectiveType === "2g" || e.saveData) && this.clearPreloadCache();
|
|
660
|
+
}
|
|
661
|
+
// Optimize media loading based on network conditions
|
|
662
|
+
async optimizeMediaLoading(e, t, r = {}) {
|
|
663
|
+
const n = performance.now(), s = this.networkMonitor.getCurrentNetworkInfo(), i = {
|
|
664
|
+
loadStartTime: n,
|
|
665
|
+
bytesLoaded: 0,
|
|
666
|
+
loadSpeed: 0,
|
|
667
|
+
networkType: s.effectiveType,
|
|
668
|
+
quality: r.quality || "auto",
|
|
669
|
+
bufferHealth: 0,
|
|
670
|
+
stallsCount: 0,
|
|
671
|
+
stallsDuration: 0
|
|
672
|
+
};
|
|
673
|
+
this.loadingMetrics.set(e, i);
|
|
674
|
+
try {
|
|
675
|
+
const a = this.chooseLoadingStrategy(s, r);
|
|
676
|
+
return a.shouldPreload && await this.preloadMedia(e, a.preloadAmount), t.preload = a.preloadAttribute, this.monitorLoadingProgress(t, i), this.config.adaptiveBitrate && a.suggestedQuality && this.applyQualitySettings(t, a.suggestedQuality), i;
|
|
677
|
+
} catch (a) {
|
|
678
|
+
return console.error("Media loading optimization failed:", a), i;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
chooseLoadingStrategy(e, t) {
|
|
682
|
+
const r = e.effectiveType === "unknown" ? "4g" : e.effectiveType, n = this.config.networkThresholds[r] || this.config.networkThresholds["4g"];
|
|
683
|
+
return {
|
|
684
|
+
shouldPreload: t.preload !== !1 && n.preload && !e.saveData,
|
|
685
|
+
preloadAmount: e.saveData ? 0 : this.config.maxPreloadSize,
|
|
686
|
+
preloadAttribute: this.getPreloadAttribute(e),
|
|
687
|
+
suggestedQuality: this.getSuggestedQuality(e, n.maxBitrate),
|
|
688
|
+
bufferTarget: this.getBufferTarget(e)
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
getPreloadAttribute(e) {
|
|
692
|
+
return e.saveData || e.effectiveType === "2g" ? "none" : e.effectiveType === "3g" ? "metadata" : this.config.preloadStrategy;
|
|
693
|
+
}
|
|
694
|
+
getSuggestedQuality(e, t) {
|
|
695
|
+
const r = e.downlink * 1e3;
|
|
696
|
+
return r >= t * 2 ? "high" : r >= t ? "medium" : "low";
|
|
697
|
+
}
|
|
698
|
+
getBufferTarget(e) {
|
|
699
|
+
switch (e.effectiveType) {
|
|
700
|
+
case "2g":
|
|
701
|
+
return 2;
|
|
702
|
+
// 2 seconds
|
|
703
|
+
case "3g":
|
|
704
|
+
return 5;
|
|
705
|
+
// 5 seconds
|
|
706
|
+
case "4g":
|
|
707
|
+
return this.config.bufferSize;
|
|
708
|
+
case "5g":
|
|
709
|
+
return this.config.bufferSize * 1.5;
|
|
710
|
+
default:
|
|
711
|
+
return this.config.bufferSize;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
// Preload media content
|
|
715
|
+
async preloadMedia(e, t) {
|
|
716
|
+
if (this.preloadCache.has(e))
|
|
717
|
+
return;
|
|
718
|
+
const r = this.fetchWithProgress(e, t);
|
|
719
|
+
this.preloadCache.set(e, r);
|
|
720
|
+
try {
|
|
721
|
+
await r;
|
|
722
|
+
} catch (n) {
|
|
723
|
+
console.warn(`Preload failed for ${e}:`, n), this.preloadCache.delete(e);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
async fetchWithProgress(e, t) {
|
|
727
|
+
const r = await fetch(e, {
|
|
728
|
+
headers: {
|
|
729
|
+
Range: `bytes=0-${t - 1}`
|
|
730
|
+
// Limit preload size
|
|
731
|
+
}
|
|
732
|
+
});
|
|
733
|
+
if (!r.ok)
|
|
734
|
+
throw new Error(`Failed to preload: ${r.status}`);
|
|
735
|
+
const n = r.body?.getReader();
|
|
736
|
+
if (!n)
|
|
737
|
+
throw new Error("Response body not readable");
|
|
738
|
+
const s = [];
|
|
739
|
+
let i = 0;
|
|
740
|
+
try {
|
|
741
|
+
for (; i < t; ) {
|
|
742
|
+
const { done: a, value: c } = await n.read();
|
|
743
|
+
if (a) break;
|
|
744
|
+
s.push(c), i += c.length;
|
|
745
|
+
}
|
|
746
|
+
} finally {
|
|
747
|
+
n.releaseLock();
|
|
748
|
+
}
|
|
749
|
+
return new Blob(s);
|
|
750
|
+
}
|
|
751
|
+
// Monitor loading progress and update metrics
|
|
752
|
+
monitorLoadingProgress(e, t) {
|
|
753
|
+
let r = null;
|
|
754
|
+
const n = () => {
|
|
755
|
+
if (e.buffered.length > 0) {
|
|
756
|
+
const y = e.buffered.end(e.buffered.length - 1), w = e.currentTime;
|
|
757
|
+
t.bufferHealth = Math.min((y - w) / this.config.bufferSize, 1);
|
|
758
|
+
}
|
|
759
|
+
}, s = () => {
|
|
760
|
+
t.firstByteTime = performance.now();
|
|
761
|
+
}, i = () => {
|
|
762
|
+
t.loadCompleteTime = performance.now(), t.totalLoadTime = t.loadCompleteTime - t.loadStartTime, t.totalLoadTime && t.bytesLoaded > 0 && (t.loadSpeed = t.bytesLoaded / (t.totalLoadTime / 1e3));
|
|
763
|
+
}, a = () => {
|
|
764
|
+
r === null && (r = performance.now(), t.stallsCount++);
|
|
765
|
+
}, c = () => {
|
|
766
|
+
r !== null && (t.stallsDuration += performance.now() - r, r = null), n();
|
|
767
|
+
}, g = () => {
|
|
768
|
+
if (e.buffered.length > 0) {
|
|
769
|
+
const y = e.buffered.end(0) * 1e3;
|
|
770
|
+
t.bytesLoaded = y;
|
|
771
|
+
}
|
|
772
|
+
n();
|
|
773
|
+
};
|
|
774
|
+
e.addEventListener("loadstart", s), e.addEventListener("canplay", i), e.addEventListener("waiting", a), e.addEventListener("playing", c), e.addEventListener("progress", g), setTimeout(() => {
|
|
775
|
+
e.removeEventListener("loadstart", s), e.removeEventListener("canplay", i), e.removeEventListener("waiting", a), e.removeEventListener("playing", c), e.removeEventListener("progress", g);
|
|
776
|
+
}, 300 * 1e3);
|
|
777
|
+
}
|
|
778
|
+
// Apply quality settings (would integrate with HLS.js or similar)
|
|
779
|
+
applyQualitySettings(e, t) {
|
|
780
|
+
console.log(`Applying quality setting: ${t} to`, e);
|
|
781
|
+
}
|
|
782
|
+
adjustQualityForNetwork(e) {
|
|
783
|
+
console.log("Adjusting quality for network conditions:", e.effectiveType);
|
|
784
|
+
}
|
|
785
|
+
// Clear preload cache to save memory
|
|
786
|
+
clearPreloadCache() {
|
|
787
|
+
this.preloadCache.clear();
|
|
788
|
+
}
|
|
789
|
+
// Get loading metrics for a specific media URL
|
|
790
|
+
getLoadingMetrics(e) {
|
|
791
|
+
return this.loadingMetrics.get(e);
|
|
792
|
+
}
|
|
793
|
+
// Get all loading metrics
|
|
794
|
+
getAllMetrics() {
|
|
795
|
+
return Array.from(this.loadingMetrics.values());
|
|
796
|
+
}
|
|
797
|
+
// Calculate average loading performance
|
|
798
|
+
getAverageLoadingTime() {
|
|
799
|
+
const t = this.getAllMetrics().filter((n) => n.totalLoadTime !== void 0);
|
|
800
|
+
return t.length === 0 ? 0 : t.reduce((n, s) => n + (s.totalLoadTime || 0), 0) / t.length;
|
|
801
|
+
}
|
|
802
|
+
// Get network-specific performance stats
|
|
803
|
+
getNetworkPerformanceStats() {
|
|
804
|
+
const e = /* @__PURE__ */ new Map();
|
|
805
|
+
return this.getAllMetrics().forEach((t) => {
|
|
806
|
+
const r = t.networkType;
|
|
807
|
+
e.has(r) || e.set(r, []), e.get(r).push(t);
|
|
808
|
+
}), Array.from(e.entries()).map(([t, r]) => ({
|
|
809
|
+
networkType: t,
|
|
810
|
+
avgLoadTime: r.reduce((n, s) => n + (s.totalLoadTime || 0), 0) / r.length,
|
|
811
|
+
avgStalls: r.reduce((n, s) => n + s.stallsCount, 0) / r.length,
|
|
812
|
+
avgBufferHealth: r.reduce((n, s) => n + s.bufferHealth, 0) / r.length
|
|
813
|
+
}));
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
const V = new M();
|
|
817
|
+
function oe(o) {
|
|
818
|
+
const [e] = m.useState(
|
|
819
|
+
() => o ? new M(o) : V
|
|
820
|
+
), [t, r] = m.useState(null), [n, s] = m.useState([]);
|
|
821
|
+
m.useEffect(() => {
|
|
822
|
+
const a = e.networkMonitor.subscribe(r);
|
|
823
|
+
r(e.networkMonitor.getCurrentNetworkInfo());
|
|
824
|
+
const c = setInterval(() => {
|
|
825
|
+
s(e.getAllMetrics());
|
|
826
|
+
}, 1e3);
|
|
827
|
+
return () => {
|
|
828
|
+
a(), clearInterval(c);
|
|
829
|
+
};
|
|
830
|
+
}, [e]);
|
|
831
|
+
const i = m.useCallback(
|
|
832
|
+
(a, c, g) => e.optimizeMediaLoading(a, c, g),
|
|
833
|
+
[e]
|
|
834
|
+
);
|
|
835
|
+
return {
|
|
836
|
+
networkInfo: t,
|
|
837
|
+
loadingMetrics: n,
|
|
838
|
+
optimizeLoading: i,
|
|
839
|
+
averageLoadTime: e.getAverageLoadingTime(),
|
|
840
|
+
networkStats: e.getNetworkPerformanceStats()
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
class H {
|
|
844
|
+
get(e) {
|
|
845
|
+
try {
|
|
846
|
+
const t = localStorage.getItem(`baroi-player-${e}`);
|
|
847
|
+
return t ? JSON.parse(t) : null;
|
|
848
|
+
} catch {
|
|
849
|
+
return null;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
set(e, t) {
|
|
853
|
+
try {
|
|
854
|
+
localStorage.setItem(`baroi-player-${e}`, JSON.stringify(t));
|
|
855
|
+
} catch (r) {
|
|
856
|
+
console.warn("Failed to store data:", r);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
remove(e) {
|
|
860
|
+
try {
|
|
861
|
+
localStorage.removeItem(`baroi-player-${e}`);
|
|
862
|
+
} catch (t) {
|
|
863
|
+
console.warn("Failed to remove data:", t);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
clear() {
|
|
867
|
+
try {
|
|
868
|
+
Object.keys(localStorage).forEach((e) => {
|
|
869
|
+
e.startsWith("baroi-player-") && localStorage.removeItem(e);
|
|
870
|
+
});
|
|
871
|
+
} catch (e) {
|
|
872
|
+
console.warn("Failed to clear data:", e);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
class j {
|
|
877
|
+
track(e, t) {
|
|
878
|
+
console.log("Analytics:", e, t);
|
|
879
|
+
}
|
|
880
|
+
identify(e, t) {
|
|
881
|
+
console.log("Analytics identify:", e, t);
|
|
882
|
+
}
|
|
883
|
+
page(e, t) {
|
|
884
|
+
console.log("Analytics page:", e, t);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
const L = $(null);
|
|
888
|
+
function Y({ children: o, services: e = {} }) {
|
|
889
|
+
const t = N(() => {
|
|
890
|
+
const r = e.logger || new B("[BaroiPlayer]"), n = e.eventBus || new I(), s = e.pluginRegistry || new R(r), i = e.storage || new H(), a = e.analytics || new j();
|
|
891
|
+
return {
|
|
892
|
+
eventBus: n,
|
|
893
|
+
pluginRegistry: s,
|
|
894
|
+
storage: i,
|
|
895
|
+
analytics: a,
|
|
896
|
+
logger: r
|
|
897
|
+
};
|
|
898
|
+
}, [e]);
|
|
899
|
+
return /* @__PURE__ */ f.jsx(L.Provider, { value: t, children: o });
|
|
900
|
+
}
|
|
901
|
+
function p() {
|
|
902
|
+
const o = x(L);
|
|
903
|
+
if (!o)
|
|
904
|
+
throw new Error("useServices must be used within ServiceProvider");
|
|
905
|
+
return o;
|
|
906
|
+
}
|
|
907
|
+
function se() {
|
|
908
|
+
return p().eventBus;
|
|
909
|
+
}
|
|
910
|
+
function ie() {
|
|
911
|
+
return p().pluginRegistry;
|
|
912
|
+
}
|
|
913
|
+
function ae() {
|
|
914
|
+
return p().storage;
|
|
915
|
+
}
|
|
916
|
+
function ce() {
|
|
917
|
+
return p().analytics;
|
|
918
|
+
}
|
|
919
|
+
function le() {
|
|
920
|
+
return p().logger;
|
|
921
|
+
}
|
|
922
|
+
function ue(o) {
|
|
923
|
+
return function(t) {
|
|
924
|
+
const r = p();
|
|
925
|
+
return /* @__PURE__ */ f.jsx(o, { ...t, services: r });
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
function de(o = {}) {
|
|
929
|
+
return function({ children: t }) {
|
|
930
|
+
return /* @__PURE__ */ f.jsx(Y, { services: o.services, children: t });
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
const l = {
|
|
934
|
+
SUBTITLES: "subtitles",
|
|
935
|
+
PLAYLISTS: "playlists",
|
|
936
|
+
ADVANCED_CONTROLS: "advanced_controls",
|
|
937
|
+
ANALYTICS: "analytics",
|
|
938
|
+
PICTURE_IN_PICTURE: "picture_in_picture",
|
|
939
|
+
QUALITY_SELECTOR: "quality_selector",
|
|
940
|
+
PLAYBACK_SPEED: "playback_speed",
|
|
941
|
+
CHAPTERS: "chapters",
|
|
942
|
+
THUMBNAILS: "thumbnails",
|
|
943
|
+
KEYBOARD_SHORTCUTS: "keyboard_shortcuts"
|
|
944
|
+
}, Q = {
|
|
945
|
+
enabledFeatures: [
|
|
946
|
+
l.SUBTITLES,
|
|
947
|
+
l.ADVANCED_CONTROLS,
|
|
948
|
+
l.KEYBOARD_SHORTCUTS
|
|
949
|
+
],
|
|
950
|
+
loadingStrategy: "lazy",
|
|
951
|
+
fallbackTimeout: 5e3,
|
|
952
|
+
retryAttempts: 3
|
|
953
|
+
}, me = {
|
|
954
|
+
// Subtitle system
|
|
955
|
+
SubtitleSelector: h(
|
|
956
|
+
() => import("./enhanced-components-Da0TSvKe.js").then((o) => o.g).then((o) => ({ default: o.SubtitleSelector }))
|
|
957
|
+
),
|
|
958
|
+
// Playlist functionality
|
|
959
|
+
PlaylistManager: h(
|
|
960
|
+
() => import("./enhanced-components-Da0TSvKe.js").then((o) => o.g).then((o) => ({ default: o.SubtitleSelector }))
|
|
961
|
+
// Use existing component as placeholder
|
|
962
|
+
),
|
|
963
|
+
// Advanced controls
|
|
964
|
+
QualitySelector: h(
|
|
965
|
+
() => import("./enhanced-components-Da0TSvKe.js").then((o) => o.g).then((o) => ({ default: o.QualitySelector }))
|
|
966
|
+
),
|
|
967
|
+
PlaybackSpeedSelector: h(
|
|
968
|
+
() => import("./enhanced-components-Da0TSvKe.js").then((o) => o.g).then((o) => ({ default: o.PlaybackSpeedSelector }))
|
|
969
|
+
),
|
|
970
|
+
ChaptersPanel: h(
|
|
971
|
+
() => import("./enhanced-components-Da0TSvKe.js").then((o) => o.g).then((o) => ({ default: o.ChaptersPanel }))
|
|
972
|
+
),
|
|
973
|
+
PictureInPictureButton: h(
|
|
974
|
+
() => import("./enhanced-components-Da0TSvKe.js").then((o) => o.g).then((o) => ({ default: o.PictureInPictureButton }))
|
|
975
|
+
),
|
|
976
|
+
// Analytics
|
|
977
|
+
AnalyticsTracker: h(
|
|
978
|
+
() => import("./enhanced-components-Da0TSvKe.js").then((o) => o.g).then((o) => ({ default: o.SubtitleSelector }))
|
|
979
|
+
// Use existing component as placeholder
|
|
980
|
+
)
|
|
981
|
+
};
|
|
982
|
+
class E {
|
|
983
|
+
static async isSupported(e) {
|
|
984
|
+
if (this.cache.has(e))
|
|
985
|
+
return this.cache.get(e);
|
|
986
|
+
const t = await this.checkFeatureSupport(e);
|
|
987
|
+
return this.cache.set(e, t), t;
|
|
988
|
+
}
|
|
989
|
+
static async checkFeatureSupport(e) {
|
|
990
|
+
if (typeof window > "u" || typeof document > "u")
|
|
991
|
+
return !0;
|
|
992
|
+
switch (e) {
|
|
993
|
+
case l.SUBTITLES:
|
|
994
|
+
return "TextTrack" in window;
|
|
995
|
+
case l.PICTURE_IN_PICTURE:
|
|
996
|
+
return "pictureInPictureEnabled" in document;
|
|
997
|
+
case l.ADVANCED_CONTROLS:
|
|
998
|
+
return !0;
|
|
999
|
+
// Always supported
|
|
1000
|
+
case l.PLAYLISTS:
|
|
1001
|
+
return "MediaSession" in window;
|
|
1002
|
+
case l.ANALYTICS:
|
|
1003
|
+
return "IntersectionObserver" in window;
|
|
1004
|
+
case l.QUALITY_SELECTOR:
|
|
1005
|
+
return "MediaSource" in window;
|
|
1006
|
+
case l.PLAYBACK_SPEED:
|
|
1007
|
+
return !0;
|
|
1008
|
+
// HTML5 video supports this
|
|
1009
|
+
case l.CHAPTERS:
|
|
1010
|
+
return "TextTrack" in window;
|
|
1011
|
+
case l.THUMBNAILS:
|
|
1012
|
+
return "OffscreenCanvas" in window || "canvas" in document.createElement("canvas");
|
|
1013
|
+
case l.KEYBOARD_SHORTCUTS:
|
|
1014
|
+
return "KeyboardEvent" in window;
|
|
1015
|
+
default:
|
|
1016
|
+
return !1;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
u(E, "cache", /* @__PURE__ */ new Map());
|
|
1021
|
+
class W {
|
|
1022
|
+
constructor(e = {}) {
|
|
1023
|
+
u(this, "config");
|
|
1024
|
+
u(this, "loadedFeatures", /* @__PURE__ */ new Set());
|
|
1025
|
+
u(this, "loadingPromises", /* @__PURE__ */ new Map());
|
|
1026
|
+
this.config = { ...Q, ...e };
|
|
1027
|
+
}
|
|
1028
|
+
async loadFeature(e) {
|
|
1029
|
+
if (!this.config.enabledFeatures.includes(e))
|
|
1030
|
+
return null;
|
|
1031
|
+
if (this.loadedFeatures.has(e))
|
|
1032
|
+
return this.getLoadedFeature(e);
|
|
1033
|
+
if (this.loadingPromises.has(e))
|
|
1034
|
+
return this.loadingPromises.get(e);
|
|
1035
|
+
if (!await E.isSupported(e))
|
|
1036
|
+
return console.warn(`Feature ${e} is not supported in this browser`), null;
|
|
1037
|
+
const r = this.loadWithRetry(e);
|
|
1038
|
+
this.loadingPromises.set(e, r);
|
|
1039
|
+
try {
|
|
1040
|
+
const n = await r;
|
|
1041
|
+
return this.loadedFeatures.add(e), n;
|
|
1042
|
+
} catch (n) {
|
|
1043
|
+
return console.error(`Failed to load feature ${e}:`, n), this.loadingPromises.delete(e), null;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
async loadWithRetry(e, t = 1) {
|
|
1047
|
+
try {
|
|
1048
|
+
return await this.loadFeatureModule(e);
|
|
1049
|
+
} catch (r) {
|
|
1050
|
+
if (t < this.config.retryAttempts)
|
|
1051
|
+
return console.warn(`Loading feature ${e} failed, retrying (${t}/${this.config.retryAttempts})`), await new Promise((n) => setTimeout(n, 1e3 * t)), this.loadWithRetry(e, t + 1);
|
|
1052
|
+
throw r;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
async loadFeatureModule(e) {
|
|
1056
|
+
switch (e) {
|
|
1057
|
+
case l.SUBTITLES:
|
|
1058
|
+
return import("./hooks-BhW_i-9L.js").then((t) => t.x);
|
|
1059
|
+
case l.PLAYLISTS:
|
|
1060
|
+
return import("./enhanced-components-Da0TSvKe.js").then((t) => t.g);
|
|
1061
|
+
// Use existing features
|
|
1062
|
+
case l.ADVANCED_CONTROLS:
|
|
1063
|
+
return import("./enhanced-components-Da0TSvKe.js").then((t) => t.g);
|
|
1064
|
+
case l.ANALYTICS:
|
|
1065
|
+
return import("./enhanced-components-Da0TSvKe.js").then((t) => t.g);
|
|
1066
|
+
// Use existing features
|
|
1067
|
+
case l.PICTURE_IN_PICTURE:
|
|
1068
|
+
return import("./enhanced-components-Da0TSvKe.js").then((t) => t.g);
|
|
1069
|
+
// Use existing features
|
|
1070
|
+
case l.QUALITY_SELECTOR:
|
|
1071
|
+
return import("./enhanced-components-Da0TSvKe.js").then((t) => t.g);
|
|
1072
|
+
// Use existing features
|
|
1073
|
+
case l.PLAYBACK_SPEED:
|
|
1074
|
+
return import("./enhanced-components-Da0TSvKe.js").then((t) => t.g);
|
|
1075
|
+
// Use existing features
|
|
1076
|
+
case l.CHAPTERS:
|
|
1077
|
+
return import("./enhanced-components-Da0TSvKe.js").then((t) => t.g);
|
|
1078
|
+
// Use existing features
|
|
1079
|
+
case l.THUMBNAILS:
|
|
1080
|
+
return import("./enhanced-components-Da0TSvKe.js").then((t) => t.g);
|
|
1081
|
+
// Use existing features
|
|
1082
|
+
case l.KEYBOARD_SHORTCUTS:
|
|
1083
|
+
return import("./hooks-BhW_i-9L.js").then((t) => t.w);
|
|
1084
|
+
default:
|
|
1085
|
+
throw new Error(`Unknown feature: ${e}`);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
getLoadedFeature(e) {
|
|
1089
|
+
return this.loadingPromises.get(e);
|
|
1090
|
+
}
|
|
1091
|
+
// Preload features for faster access
|
|
1092
|
+
async preloadFeatures(e = this.config.enabledFeatures) {
|
|
1093
|
+
const t = e.map((r) => this.loadFeature(r));
|
|
1094
|
+
await Promise.allSettled(t);
|
|
1095
|
+
}
|
|
1096
|
+
// Get loading state
|
|
1097
|
+
getLoadingState() {
|
|
1098
|
+
return {
|
|
1099
|
+
loaded: Array.from(this.loadedFeatures),
|
|
1100
|
+
loading: Array.from(this.loadingPromises.keys()),
|
|
1101
|
+
enabled: this.config.enabledFeatures
|
|
1102
|
+
};
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
const b = new W();
|
|
1106
|
+
function K(o) {
|
|
1107
|
+
const [e, t] = m.useState(null), [r, n] = m.useState(!1), [s, i] = m.useState(null), a = m.useCallback(async () => {
|
|
1108
|
+
if (!(r || e)) {
|
|
1109
|
+
n(!0), i(null);
|
|
1110
|
+
try {
|
|
1111
|
+
const c = await b.loadFeature(o);
|
|
1112
|
+
t(c);
|
|
1113
|
+
} catch (c) {
|
|
1114
|
+
i(c);
|
|
1115
|
+
} finally {
|
|
1116
|
+
n(!1);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}, [o, r, e]);
|
|
1120
|
+
return m.useEffect(() => {
|
|
1121
|
+
b.config.loadingStrategy === "immediate" && a();
|
|
1122
|
+
}, [a]), {
|
|
1123
|
+
feature: e,
|
|
1124
|
+
loading: r,
|
|
1125
|
+
error: s,
|
|
1126
|
+
load: a
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
function ge(o, e, t) {
|
|
1130
|
+
return function(n) {
|
|
1131
|
+
const { feature: s, loading: i, error: a } = K(e);
|
|
1132
|
+
if (i)
|
|
1133
|
+
return /* @__PURE__ */ f.jsx("div", { className: "h-8 animate-pulse rounded bg-gray-200" });
|
|
1134
|
+
if (a || !s) {
|
|
1135
|
+
const c = t;
|
|
1136
|
+
return c ? /* @__PURE__ */ f.jsx(c, { ...n }) : null;
|
|
1137
|
+
}
|
|
1138
|
+
return /* @__PURE__ */ f.jsx(o, { ...n });
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
const he = "1.0.0";
|
|
1142
|
+
export {
|
|
1143
|
+
ye as AnalyticsPlugin,
|
|
1144
|
+
we as BasePlugin,
|
|
1145
|
+
he as CORE_ARCHITECTURE_VERSION,
|
|
1146
|
+
B as ConsolePluginLogger,
|
|
1147
|
+
Ie as EVENT_SYSTEM_VERSION,
|
|
1148
|
+
I as EventBus,
|
|
1149
|
+
Ne as EventDelegator,
|
|
1150
|
+
l as FEATURES,
|
|
1151
|
+
E as FeatureDetector,
|
|
1152
|
+
M as MediaLoadingOptimizer,
|
|
1153
|
+
$e as MiddlewareBuilder,
|
|
1154
|
+
_ as NetworkMonitor,
|
|
1155
|
+
Te as PLUGIN_SYSTEM_VERSION,
|
|
1156
|
+
P as PerformanceBenchmark,
|
|
1157
|
+
O as PerformanceBudgetMonitor,
|
|
1158
|
+
Ge as PerformanceDashboard,
|
|
1159
|
+
Xe as PerformanceMonitor,
|
|
1160
|
+
F as PerformanceRegressionDetector,
|
|
1161
|
+
U as PerformanceTestFramework,
|
|
1162
|
+
Se as PluginConflictError,
|
|
1163
|
+
ve as PluginDependencyError,
|
|
1164
|
+
be as PluginDevelopmentHelpers,
|
|
1165
|
+
Pe as PluginError,
|
|
1166
|
+
Me as PluginPerformanceMonitor,
|
|
1167
|
+
R as PluginRegistry,
|
|
1168
|
+
Le as PluginStorage,
|
|
1169
|
+
Ee as PluginValidator,
|
|
1170
|
+
W as ProgressiveLoader,
|
|
1171
|
+
Y as ServiceProvider,
|
|
1172
|
+
xe as commonMiddlewares,
|
|
1173
|
+
Ce as createAnalyticsPlugin,
|
|
1174
|
+
de as createArchitecture,
|
|
1175
|
+
Fe as createMiddleware,
|
|
1176
|
+
ke as createPlugin,
|
|
1177
|
+
Ue as defaultEventBus,
|
|
1178
|
+
z as defaultMediaLoadingConfig,
|
|
1179
|
+
D as defaultPerformanceBudgets,
|
|
1180
|
+
Ae as defaultPerformanceMonitor,
|
|
1181
|
+
Be as defaultPluginLogger,
|
|
1182
|
+
Q as defaultProgressiveConfig,
|
|
1183
|
+
Ze as defaultThresholds,
|
|
1184
|
+
De as eventMiddlewares,
|
|
1185
|
+
me as lazyComponents,
|
|
1186
|
+
V as mediaLoadingOptimizer,
|
|
1187
|
+
v as performanceBenchmark,
|
|
1188
|
+
ne as performanceBudgetMonitor,
|
|
1189
|
+
et as performanceMonitor,
|
|
1190
|
+
re as performanceTestFramework,
|
|
1191
|
+
te as performanceTestUtils,
|
|
1192
|
+
b as progressiveLoader,
|
|
1193
|
+
ce as useAnalytics,
|
|
1194
|
+
Oe as useConditionalEventListener,
|
|
1195
|
+
ze as useEventBus,
|
|
1196
|
+
_e as useEventDebugger,
|
|
1197
|
+
Ve as useEventEffect,
|
|
1198
|
+
He as useEventEmitter,
|
|
1199
|
+
je as useEventHandlers,
|
|
1200
|
+
Ye as useEventHistory,
|
|
1201
|
+
Qe as useEventListener,
|
|
1202
|
+
We as useEventMetrics,
|
|
1203
|
+
Ke as useEventOnce,
|
|
1204
|
+
Je as useEventState,
|
|
1205
|
+
le as useLogger,
|
|
1206
|
+
oe as useMediaLoadingOptimizer,
|
|
1207
|
+
tt as usePerformanceMonitor,
|
|
1208
|
+
ie as usePluginRegistry,
|
|
1209
|
+
K as useProgressiveFeature,
|
|
1210
|
+
se as useServiceEventBus,
|
|
1211
|
+
p as useServices,
|
|
1212
|
+
ae as useStorage,
|
|
1213
|
+
rt as withPerformanceMonitoring,
|
|
1214
|
+
ge as withProgressiveFeature,
|
|
1215
|
+
ue as withServices
|
|
1216
|
+
};
|
|
1217
|
+
//# sourceMappingURL=core.mjs.map
|