@leeguoo/pwtk-network-debugger 1.2.49-beta.9 → 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;
@@ -17896,6 +18075,9 @@ const _DebugPanel = class _DebugPanel {
17896
18075
  this.webglBackgroundUpdateTimer = null;
17897
18076
  this.boundHandlers = /* @__PURE__ */ new Map();
17898
18077
  this.eventListeners = [];
18078
+ this.renderDebounceTimer = null;
18079
+ this.searchDebounceTimer = null;
18080
+ this.pendingRenderRequests = /* @__PURE__ */ new Set();
17899
18081
  this.interceptor = interceptor;
17900
18082
  const savedConfig = this.loadConfig();
17901
18083
  this.config = {
@@ -17956,7 +18138,7 @@ const _DebugPanel = class _DebugPanel {
17956
18138
  this.container.style.pointerEvents = "auto";
17957
18139
  this.container.innerHTML = `
17958
18140
  <div class="debugger-header">
17959
- <div class="debugger-title">🔓 PWTK 解密小工具 <span style="font-size: 10px; opacity: 0.7;">by Leo v${"1.2.49-beta.9"}</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>
17960
18142
  <div class="debugger-controls">
17961
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>
17962
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>
@@ -18002,12 +18184,18 @@ const _DebugPanel = class _DebugPanel {
18002
18184
  searchInput.addEventListener("input", (e2) => {
18003
18185
  const query = e2.target.value;
18004
18186
  this.searchQuery = query;
18005
- this.filterRequests();
18006
18187
  if (query) {
18007
18188
  searchClearBtn.style.display = "block";
18008
18189
  } else {
18009
18190
  searchClearBtn.style.display = "none";
18010
18191
  }
18192
+ if (this.searchDebounceTimer) {
18193
+ clearTimeout(this.searchDebounceTimer);
18194
+ }
18195
+ this.searchDebounceTimer = window.setTimeout(() => {
18196
+ this.filterRequests();
18197
+ this.searchDebounceTimer = null;
18198
+ }, 200);
18011
18199
  });
18012
18200
  searchClearBtn.addEventListener("click", () => {
18013
18201
  searchInput.value = "";
@@ -18085,7 +18273,19 @@ const _DebugPanel = class _DebugPanel {
18085
18273
  if (this.requestsCache.length > 100) {
18086
18274
  this.requestsCache = this.requestsCache.slice(0, 100);
18087
18275
  }
18088
- this.renderRequests();
18276
+ this.scheduleRender();
18277
+ }
18278
+ /**
18279
+ * 防抖渲染 - 避免频繁的重新渲染
18280
+ */
18281
+ scheduleRender() {
18282
+ if (this.renderDebounceTimer) {
18283
+ clearTimeout(this.renderDebounceTimer);
18284
+ }
18285
+ this.renderDebounceTimer = window.setTimeout(() => {
18286
+ this.renderRequests();
18287
+ this.renderDebounceTimer = null;
18288
+ }, 50);
18089
18289
  }
18090
18290
  filterRequests() {
18091
18291
  if (!this.searchQuery) {
@@ -18150,25 +18350,15 @@ const _DebugPanel = class _DebugPanel {
18150
18350
  return;
18151
18351
  }
18152
18352
  const applyItems = this.config.webgl?.applyToItems ?? false;
18353
+ const fragment = document.createDocumentFragment();
18153
18354
  requestsToRender.forEach((request, index) => {
18154
18355
  const item = this.createRequestItem(request);
18155
- listContainer.appendChild(item);
18156
- if (this.webglManager) {
18157
- const layerId = `request-item-${index}`;
18158
- this.webglManager.disableForElement(layerId);
18159
- if (applyItems) {
18160
- requestAnimationFrame(() => {
18161
- try {
18162
- this.webglManager.enableForElement(item, layerId);
18163
- } catch (error) {
18164
- logger.debug(`Failed to enable WebGL for request item ${index}:`, error);
18165
- }
18166
- });
18167
- } else {
18168
- item.classList.add("webgl-fallback", "enhanced-css-glass");
18169
- }
18356
+ fragment.appendChild(item);
18357
+ if (this.webglManager && applyItems) {
18358
+ item.classList.add("webgl-fallback", "enhanced-css-glass");
18170
18359
  }
18171
18360
  });
18361
+ listContainer.appendChild(fragment);
18172
18362
  }
18173
18363
  createRequestItem(request) {
18174
18364
  const item = document.createElement("div");
@@ -18792,6 +18982,14 @@ Created by Leo (@leeguoo)`);
18792
18982
  clearInterval(this.webglBackgroundUpdateTimer);
18793
18983
  this.webglBackgroundUpdateTimer = null;
18794
18984
  }
18985
+ if (this.renderDebounceTimer) {
18986
+ clearTimeout(this.renderDebounceTimer);
18987
+ this.renderDebounceTimer = null;
18988
+ }
18989
+ if (this.searchDebounceTimer) {
18990
+ clearTimeout(this.searchDebounceTimer);
18991
+ this.searchDebounceTimer = null;
18992
+ }
18795
18993
  }
18796
18994
  destroy() {
18797
18995
  this.removeAllEventListeners();
@@ -19044,7 +19242,7 @@ function loadLiquidGlass() {
19044
19242
  });
19045
19243
  }
19046
19244
  const liquidGlassPromise = loadLiquidGlass();
19047
- class NetworkDebugger {
19245
+ const _NetworkDebugger = class _NetworkDebugger {
19048
19246
  constructor() {
19049
19247
  this.interceptor = null;
19050
19248
  this.panel = null;
@@ -19057,6 +19255,7 @@ class NetworkDebugger {
19057
19255
  logger.warn("NetworkDebugger already initialized");
19058
19256
  return;
19059
19257
  }
19258
+ logger.info(`🚀 PWTK Network Debugger v${_NetworkDebugger.version} initializing...`);
19060
19259
  this.config = {
19061
19260
  autoStart: true,
19062
19261
  position: "bottom-right",
@@ -19112,13 +19311,13 @@ class NetworkDebugger {
19112
19311
  this.initialized = true;
19113
19312
  logger.consoleDirect(`
19114
19313
  ╔════════════════════════════════════════╗
19115
- ║ 🔓 PWTK 解密小工具 v${"1.2.49-beta.9"} ║
19314
+ ║ 🔓 PWTK 解密小工具 v${_NetworkDebugger.version} ║
19116
19315
  ║ Created by Leo (@leeguoo) ║
19117
19316
  ║ 技术支持: 请联系 Leo ║
19118
19317
  ║ 分享服务: curl.bwg.leeguoo.com ║
19119
19318
  ╚════════════════════════════════════════╝
19120
19319
  `);
19121
- logger.info("🔍 NetworkDebugger initialized successfully");
19320
+ logger.info(`✅ PWTK Network Debugger v${_NetworkDebugger.version} initialized successfully`);
19122
19321
  } catch (error) {
19123
19322
  logger.error("NetworkDebugger initialization failed:", error);
19124
19323
  throw error;
@@ -19173,7 +19372,7 @@ class NetworkDebugger {
19173
19372
  }
19174
19373
  async checkForUpdates() {
19175
19374
  try {
19176
- const currentVersion = "1.2.49-beta.9";
19375
+ const currentVersion = "1.3.1-beta.0";
19177
19376
  logger.info(`[PWTK Update] Checking for updates... Current version: ${currentVersion}`);
19178
19377
  const response = await fetch("https://registry.npmjs.org/@leeguoo/pwtk-network-debugger/latest");
19179
19378
  const data = await response.json();
@@ -19193,7 +19392,7 @@ class NetworkDebugger {
19193
19392
  logger.error("[PWTK Update] Failed to check for updates:", error);
19194
19393
  return {
19195
19394
  hasUpdate: false,
19196
- currentVersion: "1.2.49-beta.9"
19395
+ currentVersion: "1.3.1-beta.0"
19197
19396
  };
19198
19397
  }
19199
19398
  }
@@ -19267,7 +19466,7 @@ class NetworkDebugger {
19267
19466
  }
19268
19467
  // 静态方法,用于全局访问
19269
19468
  static create(config) {
19270
- const instance = new NetworkDebugger();
19469
+ const instance = new _NetworkDebugger();
19271
19470
  return instance.init(config).then(() => instance);
19272
19471
  }
19273
19472
  createPanel() {
@@ -19288,7 +19487,9 @@ class NetworkDebugger {
19288
19487
  defaultSlkExtractor(headers) {
19289
19488
  return headers.slk || headers["x-slk"] || "";
19290
19489
  }
19291
- }
19490
+ };
19491
+ _NetworkDebugger.version = "1.3.1-beta.0";
19492
+ let NetworkDebugger = _NetworkDebugger;
19292
19493
  let globalInstance = null;
19293
19494
  const NetworkDebuggerGlobal = {
19294
19495
  async init(config) {