@leeguoo/pwtk-network-debugger 1.3.0 → 1.3.1-beta.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.
package/dist/index.esm.js CHANGED
@@ -17005,6 +17005,20 @@ class LiquidGlassRenderer {
17005
17005
  this.usingFallbackShader = false;
17006
17006
  this.uniformsDirty = true;
17007
17007
  this.time = 0;
17008
+ this.stats = {
17009
+ fps: 60,
17010
+ frameTime: 16.67,
17011
+ droppedFrames: 0,
17012
+ totalFrames: 0,
17013
+ contextLostCount: 0,
17014
+ lastUpdateTime: 0
17015
+ };
17016
+ this.frameTimes = [];
17017
+ this.lastFrameTime = 0;
17018
+ this.fpsUpdateInterval = 1e3;
17019
+ this.lastFpsUpdate = 0;
17020
+ this.blendEnabled = false;
17021
+ this.currentProgram = null;
17008
17022
  this.uniformLocations = {};
17009
17023
  this.canvas = config.canvas;
17010
17024
  this.cssWidth = config.width;
@@ -17031,12 +17045,25 @@ class LiquidGlassRenderer {
17031
17045
  }
17032
17046
  setupGL() {
17033
17047
  const { gl } = this;
17034
- gl.enable(gl.BLEND);
17035
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
17048
+ this.enableBlend();
17036
17049
  gl.viewport(0, 0, this.canvas.width, this.canvas.height);
17037
17050
  this.createShaderProgram();
17038
17051
  this.createGeometry();
17039
17052
  }
17053
+ enableBlend() {
17054
+ if (!this.blendEnabled) {
17055
+ const { gl } = this;
17056
+ gl.enable(gl.BLEND);
17057
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
17058
+ this.blendEnabled = true;
17059
+ }
17060
+ }
17061
+ useProgram(program) {
17062
+ if (this.currentProgram !== program) {
17063
+ this.gl.useProgram(program);
17064
+ this.currentProgram = program;
17065
+ }
17066
+ }
17040
17067
  createShaderProgram() {
17041
17068
  const { gl } = this;
17042
17069
  const vertexShaderSource = `#version 300 es
@@ -17183,6 +17210,11 @@ class LiquidGlassRenderer {
17183
17210
  render() {
17184
17211
  if (!this.program || !this.backgroundTexture) return;
17185
17212
  const { gl } = this;
17213
+ const frameStartTime = performance.now();
17214
+ if (gl.isContextLost()) {
17215
+ this.stats.contextLostCount++;
17216
+ return;
17217
+ }
17186
17218
  if (!this.usingFallbackShader) {
17187
17219
  const dynamic = this.uniformProvider ? this.uniformProvider() : null;
17188
17220
  if (!dynamic) {
@@ -17193,7 +17225,8 @@ class LiquidGlassRenderer {
17193
17225
  this.time += this.timeStep;
17194
17226
  gl.clearColor(0, 0, 0, 0);
17195
17227
  gl.clear(gl.COLOR_BUFFER_BIT);
17196
- gl.useProgram(this.program);
17228
+ this.enableBlend();
17229
+ this.useProgram(this.program);
17197
17230
  if (this.uniformsDirty && !this.usingFallbackShader) {
17198
17231
  this.applyLiquidUniforms();
17199
17232
  this.uniformsDirty = false;
@@ -17217,6 +17250,41 @@ class LiquidGlassRenderer {
17217
17250
  gl.uniform1i(this.uniformLocations.u_background, 0);
17218
17251
  }
17219
17252
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
17253
+ this.updatePerformanceStats(frameStartTime);
17254
+ }
17255
+ updatePerformanceStats(frameStartTime) {
17256
+ const now = performance.now();
17257
+ const frameTime = now - frameStartTime;
17258
+ this.stats.totalFrames++;
17259
+ if (frameTime > 33) {
17260
+ this.stats.droppedFrames++;
17261
+ }
17262
+ this.frameTimes.push(frameTime);
17263
+ if (this.frameTimes.length > 60) {
17264
+ this.frameTimes.shift();
17265
+ }
17266
+ if (now - this.lastFpsUpdate > this.fpsUpdateInterval) {
17267
+ const avgFrameTime = this.frameTimes.reduce((a2, b) => a2 + b, 0) / this.frameTimes.length;
17268
+ this.stats.frameTime = avgFrameTime;
17269
+ this.stats.fps = Math.round(1e3 / avgFrameTime);
17270
+ this.stats.lastUpdateTime = now;
17271
+ this.lastFpsUpdate = now;
17272
+ }
17273
+ }
17274
+ getPerformanceStats() {
17275
+ return { ...this.stats };
17276
+ }
17277
+ resetPerformanceStats() {
17278
+ this.stats = {
17279
+ fps: 60,
17280
+ frameTime: 16.67,
17281
+ droppedFrames: 0,
17282
+ totalFrames: 0,
17283
+ contextLostCount: this.stats.contextLostCount,
17284
+ // 保留 context lost 计数
17285
+ lastUpdateTime: performance.now()
17286
+ };
17287
+ this.frameTimes = [];
17220
17288
  }
17221
17289
  applyDynamicUniforms(dynamic) {
17222
17290
  const { gl } = this;
@@ -17270,7 +17338,11 @@ class LiquidGlassRenderer {
17270
17338
  this.canvas.height = height * dpr;
17271
17339
  this.canvas.style.width = `${width}px`;
17272
17340
  this.canvas.style.height = `${height}px`;
17273
- this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
17341
+ const { gl } = this;
17342
+ gl.viewport(0, 0, this.canvas.width, this.canvas.height);
17343
+ this.blendEnabled = false;
17344
+ this.currentProgram = null;
17345
+ this.enableBlend();
17274
17346
  this.uniformsDirty = true;
17275
17347
  }
17276
17348
  setQuality(quality) {
@@ -17345,11 +17417,40 @@ class LiquidGlassScene {
17345
17417
  this.snapshotNeedsUpdate = true;
17346
17418
  this.refreshTimeout = null;
17347
17419
  this.destroyed = false;
17420
+ this.sceneStats = {
17421
+ averageFps: 60,
17422
+ lowestFps: 60,
17423
+ totalDroppedFrames: 0,
17424
+ backgroundRefreshCount: 0,
17425
+ backgroundRefreshTime: 0,
17426
+ visibilityChangeCount: 0
17427
+ };
17428
+ this.performanceMode = "auto";
17429
+ this.autoQualityEnabled = true;
17430
+ this.lastPerformanceCheck = 0;
17431
+ this.performanceCheckInterval = 3e3;
17348
17432
  this.markSnapshotDirty = () => {
17349
17433
  if (this.destroyed) return;
17350
17434
  this.snapshotNeedsUpdate = true;
17351
17435
  this.scheduleBackgroundRefresh();
17352
17436
  };
17437
+ this.handleVisibilityChange = () => {
17438
+ if (!document.hidden) {
17439
+ this.sceneStats.visibilityChangeCount++;
17440
+ this.snapshotNeedsUpdate = true;
17441
+ this.updateBackgrounds(true);
17442
+ if (this.isActive) {
17443
+ this.layers.forEach((layer) => {
17444
+ if (layer.visible) {
17445
+ layer.renderer.stopAnimation();
17446
+ layer.renderer.resetPerformanceStats();
17447
+ layer.renderer.startAnimation();
17448
+ }
17449
+ });
17450
+ }
17451
+ this.lastPerformanceCheck = performance.now();
17452
+ }
17453
+ };
17353
17454
  this.container = container;
17354
17455
  this.backgroundCanvas = document.createElement("canvas");
17355
17456
  const ctx = this.backgroundCanvas.getContext("2d");
@@ -17365,6 +17466,7 @@ class LiquidGlassScene {
17365
17466
  this.resizeObserver.observe(container);
17366
17467
  window.addEventListener("scroll", this.markSnapshotDirty, { passive: true });
17367
17468
  window.addEventListener("resize", this.markSnapshotDirty);
17469
+ document.addEventListener("visibilitychange", this.handleVisibilityChange);
17368
17470
  }
17369
17471
  setupContainer() {
17370
17472
  const computedStyle = getComputedStyle(this.container);
@@ -17482,6 +17584,60 @@ class LiquidGlassScene {
17482
17584
  layer.renderer.startAnimation();
17483
17585
  }
17484
17586
  });
17587
+ if (this.autoQualityEnabled) {
17588
+ this.startPerformanceMonitoring();
17589
+ }
17590
+ }
17591
+ startPerformanceMonitoring() {
17592
+ const checkPerformance = () => {
17593
+ if (!this.isActive || this.destroyed || document.hidden) {
17594
+ setTimeout(checkPerformance, this.performanceCheckInterval);
17595
+ return;
17596
+ }
17597
+ const now = performance.now();
17598
+ if (now - this.lastPerformanceCheck < this.performanceCheckInterval) {
17599
+ setTimeout(checkPerformance, this.performanceCheckInterval);
17600
+ return;
17601
+ }
17602
+ this.lastPerformanceCheck = now;
17603
+ this.updateSceneStats();
17604
+ if (this.autoQualityEnabled && this.performanceMode === "auto") {
17605
+ this.autoAdjustQuality();
17606
+ }
17607
+ setTimeout(checkPerformance, this.performanceCheckInterval);
17608
+ };
17609
+ setTimeout(checkPerformance, this.performanceCheckInterval);
17610
+ }
17611
+ updateSceneStats() {
17612
+ let totalFps = 0;
17613
+ let lowestFps = 60;
17614
+ let totalDroppedFrames = 0;
17615
+ let layerCount = 0;
17616
+ this.layers.forEach((layer) => {
17617
+ if (layer.visible) {
17618
+ const stats = layer.renderer.getPerformanceStats();
17619
+ totalFps += stats.fps;
17620
+ lowestFps = Math.min(lowestFps, stats.fps);
17621
+ totalDroppedFrames += stats.droppedFrames;
17622
+ layerCount++;
17623
+ }
17624
+ });
17625
+ if (layerCount > 0) {
17626
+ this.sceneStats.averageFps = Math.round(totalFps / layerCount);
17627
+ this.sceneStats.lowestFps = lowestFps;
17628
+ this.sceneStats.totalDroppedFrames = totalDroppedFrames;
17629
+ }
17630
+ }
17631
+ autoAdjustQuality() {
17632
+ const { averageFps, lowestFps, totalDroppedFrames } = this.sceneStats;
17633
+ if (lowestFps < 25 || averageFps < 30 && totalDroppedFrames > 50) {
17634
+ this.setQuality("low");
17635
+ console.warn("[PWTK WebGL] Performance poor, auto-switched to low quality");
17636
+ } else if (lowestFps < 45 || averageFps < 50 && totalDroppedFrames > 20) {
17637
+ this.setQuality("medium");
17638
+ } else if (lowestFps > 55 && totalDroppedFrames < 5) {
17639
+ this.setQuality("high");
17640
+ }
17485
17641
  }
17486
17642
  stopAnimation() {
17487
17643
  this.isActive = false;
@@ -17552,6 +17708,7 @@ class LiquidGlassScene {
17552
17708
  this.resizeObserver.disconnect();
17553
17709
  window.removeEventListener("scroll", this.markSnapshotDirty);
17554
17710
  window.removeEventListener("resize", this.markSnapshotDirty);
17711
+ document.removeEventListener("visibilitychange", this.handleVisibilityChange);
17555
17712
  }
17556
17713
  getLayer(id) {
17557
17714
  return this.layers.get(id);
@@ -17568,6 +17725,24 @@ class LiquidGlassScene {
17568
17725
  return false;
17569
17726
  }
17570
17727
  }
17728
+ getPerformanceStats() {
17729
+ this.updateSceneStats();
17730
+ return { ...this.sceneStats };
17731
+ }
17732
+ setPerformanceMode(mode) {
17733
+ this.performanceMode = mode;
17734
+ this.autoQualityEnabled = mode === "auto";
17735
+ if (mode === "high") {
17736
+ this.setQuality("high");
17737
+ } else if (mode === "low") {
17738
+ this.setQuality("low");
17739
+ } else if (mode === "balanced") {
17740
+ this.setQuality("medium");
17741
+ }
17742
+ }
17743
+ enableAutoQuality(enabled) {
17744
+ this.autoQualityEnabled = enabled;
17745
+ }
17571
17746
  applyPlaceholderBackground(layer) {
17572
17747
  const rect = layer.element.getBoundingClientRect();
17573
17748
  const width = Math.max(1, Math.round(rect.width || layer.canvas.clientWidth || 1));
@@ -17610,9 +17785,13 @@ class LiquidGlassScene {
17610
17785
  };
17611
17786
  }
17612
17787
  async refreshLayerBackground(layer, forceSnapshot = false) {
17788
+ const startTime = performance.now();
17613
17789
  await this.ensurePageSnapshot(forceSnapshot);
17614
17790
  if (!this.snapshotCanvas) return;
17615
17791
  layer.renderer.setBackgroundTexture(this.snapshotCanvas);
17792
+ const refreshTime = performance.now() - startTime;
17793
+ this.sceneStats.backgroundRefreshCount++;
17794
+ this.sceneStats.backgroundRefreshTime = refreshTime;
17616
17795
  }
17617
17796
  async ensurePageSnapshot(force = false) {
17618
17797
  if (this.destroyed) return;
@@ -17959,7 +18138,7 @@ const _DebugPanel = class _DebugPanel {
17959
18138
  this.container.style.pointerEvents = "auto";
17960
18139
  this.container.innerHTML = `
17961
18140
  <div class="debugger-header">
17962
- <div class="debugger-title">🔓 PWTK 解密小工具 <span style="font-size: 10px; opacity: 0.7;">by Leo v${"1.3.0"}</span></div>
18141
+ <div class="debugger-title">🔓 PWTK 解密小工具 <span style="font-size: 10px; opacity: 0.7;">by Leo v${"1.3.1-beta.0"}</span></div>
17963
18142
  <div class="debugger-controls">
17964
18143
  <button class="debugger-btn" data-action="clear" title="清空"><svg class="debugger-icon" viewBox="0 0 24 24"><path fill="currentColor" d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg></button>
17965
18144
  <button class="debugger-btn" data-action="export" title="导出"><svg class="debugger-icon" viewBox="0 0 24 24"><path fill="currentColor" d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/></svg></button>
@@ -19063,7 +19242,7 @@ function loadLiquidGlass() {
19063
19242
  });
19064
19243
  }
19065
19244
  const liquidGlassPromise = loadLiquidGlass();
19066
- class NetworkDebugger {
19245
+ const _NetworkDebugger = class _NetworkDebugger {
19067
19246
  constructor() {
19068
19247
  this.interceptor = null;
19069
19248
  this.panel = null;
@@ -19076,6 +19255,7 @@ class NetworkDebugger {
19076
19255
  logger.warn("NetworkDebugger already initialized");
19077
19256
  return;
19078
19257
  }
19258
+ logger.info(`🚀 PWTK Network Debugger v${_NetworkDebugger.version} initializing...`);
19079
19259
  this.config = {
19080
19260
  autoStart: true,
19081
19261
  position: "bottom-right",
@@ -19131,13 +19311,13 @@ class NetworkDebugger {
19131
19311
  this.initialized = true;
19132
19312
  logger.consoleDirect(`
19133
19313
  ╔════════════════════════════════════════╗
19134
- ║ 🔓 PWTK 解密小工具 v${"1.3.0"} ║
19314
+ ║ 🔓 PWTK 解密小工具 v${_NetworkDebugger.version} ║
19135
19315
  ║ Created by Leo (@leeguoo) ║
19136
19316
  ║ 技术支持: 请联系 Leo ║
19137
19317
  ║ 分享服务: curl.bwg.leeguoo.com ║
19138
19318
  ╚════════════════════════════════════════╝
19139
19319
  `);
19140
- logger.info("🔍 NetworkDebugger initialized successfully");
19320
+ logger.info(`✅ PWTK Network Debugger v${_NetworkDebugger.version} initialized successfully`);
19141
19321
  } catch (error) {
19142
19322
  logger.error("NetworkDebugger initialization failed:", error);
19143
19323
  throw error;
@@ -19192,7 +19372,7 @@ class NetworkDebugger {
19192
19372
  }
19193
19373
  async checkForUpdates() {
19194
19374
  try {
19195
- const currentVersion = "1.3.0";
19375
+ const currentVersion = "1.3.1-beta.0";
19196
19376
  logger.info(`[PWTK Update] Checking for updates... Current version: ${currentVersion}`);
19197
19377
  const response = await fetch("https://registry.npmjs.org/@leeguoo/pwtk-network-debugger/latest");
19198
19378
  const data = await response.json();
@@ -19212,7 +19392,7 @@ class NetworkDebugger {
19212
19392
  logger.error("[PWTK Update] Failed to check for updates:", error);
19213
19393
  return {
19214
19394
  hasUpdate: false,
19215
- currentVersion: "1.3.0"
19395
+ currentVersion: "1.3.1-beta.0"
19216
19396
  };
19217
19397
  }
19218
19398
  }
@@ -19286,7 +19466,7 @@ class NetworkDebugger {
19286
19466
  }
19287
19467
  // 静态方法,用于全局访问
19288
19468
  static create(config) {
19289
- const instance = new NetworkDebugger();
19469
+ const instance = new _NetworkDebugger();
19290
19470
  return instance.init(config).then(() => instance);
19291
19471
  }
19292
19472
  createPanel() {
@@ -19307,7 +19487,9 @@ class NetworkDebugger {
19307
19487
  defaultSlkExtractor(headers) {
19308
19488
  return headers.slk || headers["x-slk"] || "";
19309
19489
  }
19310
- }
19490
+ };
19491
+ _NetworkDebugger.version = "1.3.1-beta.0";
19492
+ let NetworkDebugger = _NetworkDebugger;
19311
19493
  let globalInstance = null;
19312
19494
  const NetworkDebuggerGlobal = {
19313
19495
  async init(config) {