cdp-tunnel 2.2.2 → 2.3.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.
@@ -17,6 +17,7 @@ importScripts('features/automation-badge.js');
17
17
  'use strict';
18
18
 
19
19
  var keepAliveInterval = null;
20
+ var _initialized = false;
20
21
 
21
22
  function startKeepAlive() {
22
23
  if (keepAliveInterval) {
@@ -43,6 +44,11 @@ importScripts('features/automation-badge.js');
43
44
  }
44
45
 
45
46
  function init() {
47
+ if (_initialized) {
48
+ Logger.info('[Init] Already initialized, skipping');
49
+ return;
50
+ }
51
+ _initialized = true;
46
52
  Logger.info('[Init] CDP Bridge starting...');
47
53
 
48
54
  // 点击扩展图标时打开配置页面
@@ -204,6 +210,12 @@ importScripts('features/automation-badge.js');
204
210
 
205
211
  var sessionId = CDPUtils.generateSessionId();
206
212
  State.mapSession(sessionId, tabId, targetId);
213
+
214
+ var openerClientId = openerTabId ? State.getClientIdByTabId(openerTabId) : null;
215
+ if (openerClientId) {
216
+ State.setTabIdToClientId(tabId, openerClientId);
217
+ Logger.info('[Tabs] Mapped child tab', tabId, '-> clientId:', openerClientId);
218
+ }
207
219
 
208
220
  Config.getAutoMute(function(enabled) {
209
221
  if (enabled) {
@@ -38,6 +38,9 @@ var State = (function() {
38
38
  var tabId = _state.sessionIdToTabId.get(sessionId);
39
39
  _state.sessionIdToTabId.delete(sessionId);
40
40
  _state.sessionIdToTargetId.delete(sessionId);
41
+ if (tabId && !hasOtherSessionForTab(tabId)) {
42
+ _state.attachedTabIds.delete(tabId);
43
+ }
41
44
  return tabId;
42
45
  }
43
46
 
@@ -254,6 +257,7 @@ var State = (function() {
254
257
  function clearAllState() {
255
258
  clearSessionState();
256
259
  _state.attachedTabIds.clear();
260
+ _state.emittedTargets.clear();
257
261
  _state.screencastPollingSessions.clear();
258
262
  _state.browserContextIds = new Set(['default']);
259
263
  _state.autoAttachConfig = {
@@ -265,7 +269,13 @@ var State = (function() {
265
269
  _state.hasConnectedClient = false;
266
270
  _state.tabIdToClientId.clear();
267
271
  _state.clientIdToGroupId.clear();
272
+ _state.clientIdToTabId.clear();
273
+ _state.clientIdToSessionId.clear();
268
274
  _state.preExistingTabIds.clear();
275
+ _state.pendingDebuggerTabs.clear();
276
+ _state.automatedTabs.clear();
277
+ _state.pendingCreatedTabUrls.clear();
278
+ _state.cdpClients = [];
269
279
  }
270
280
 
271
281
  function cleanupAllTabs() {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "CDP Bridge",
4
- "version": "2.2.2",
4
+ "version": "2.3.0",
5
5
  "description": "Chrome DevTools Protocol Bridge for Playwright/Puppeteer automation",
6
6
  "permissions": [
7
7
  "debugger",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdp-tunnel",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "description": "Bridge Chrome's debugger API to WebSocket — control your existing browser with Playwright/Puppeteer via CDP",
5
5
  "main": "server/proxy-server.js",
6
6
  "bin": "./cli/index.js",
@@ -506,8 +506,14 @@ function handlePluginConnection(ws, clientInfo) {
506
506
  const sessionId = parsed.params?.sessionId;
507
507
 
508
508
  if (targetId && sessionId) {
509
- sessionToClientId.set(sessionId, targetId);
510
- console.log(`[SESSION MAPPED] sessionId=${sessionId?.substring(0,8) || 'none'} -> targetId=${targetId?.substring(0,8) || 'none'}`);
509
+ const clientId = ws.pairedClientId;
510
+ if (clientId) {
511
+ sessionToClientId.set(sessionId, clientId);
512
+ console.log(`[SESSION MAPPED] sessionId=${sessionId?.substring(0,8) || 'none'} -> clientId=${clientId?.substring(0,8) || 'none'}`);
513
+ } else {
514
+ sessionToClientId.set(sessionId, targetId);
515
+ console.log(`[SESSION MAPPED] sessionId=${sessionId?.substring(0,8) || 'none'} -> targetId=${targetId?.substring(0,8) || 'none'} (no pairedClientId)`);
516
+ }
511
517
  }
512
518
  }
513
519
 
@@ -559,6 +565,12 @@ function handlePluginConnection(ws, clientInfo) {
559
565
  console.log(`[BROWSER CONTEXT MAPPED] browserContextId=${browserContextId} -> clientId=${mapping.clientId}`);
560
566
  }
561
567
 
568
+ // 如果是 Target.attachToTarget 响应,建立 sessionId -> clientId 映射
569
+ if (parsed.result?.sessionId && mapping.method === 'Target.attachToTarget') {
570
+ sessionToClientId.set(parsed.result.sessionId, mapping.clientId);
571
+ console.log(`[SESSION MAPPED from attach response] sessionId=${parsed.result.sessionId?.substring(0,8)} -> clientId=${mapping.clientId?.substring(0,8)}`);
572
+ }
573
+
562
574
  // 如果是 Target.createTarget 响应,先发送缓存的 Target.attachedToTarget 事件
563
575
  // 然后再发送响应
564
576
  if (mapping.isCreateTarget && parsed.result?.targetId) {
@@ -867,7 +879,8 @@ function handleClientConnection(ws, clientInfo, customClientId = null) {
867
879
  globalRequestIdMap.set(globalId, {
868
880
  clientId: id,
869
881
  originalId: originalId,
870
- sessionId: parsed.sessionId // 保存请求的 sessionId
882
+ sessionId: parsed.sessionId,
883
+ method: parsed.method
871
884
  });
872
885
 
873
886
  // 修改请求ID为全局ID
@@ -877,12 +890,6 @@ function handleClientConnection(ws, clientInfo, customClientId = null) {
877
890
  console.log(`[REQUEST ID MAPPED] client=${id} original=${originalId} -> global=${globalId} sessionId=${parsed.sessionId?.substring(0,8) || 'none'}`);
878
891
  }
879
892
 
880
- // 记录 Target.attachToTarget 请求,用于后续建立 session -> clientId 映射
881
- if (parsed && parsed.method === 'Target.attachToTarget' && parsed.id !== undefined) {
882
- pendingAttachRequests.set(parsed.id, id);
883
- console.log(`[PENDING ATTACH] Request id=${parsed.id} from client=${id}, pending size=${pendingAttachRequests.size}`);
884
- }
885
-
886
893
  // 记录 Target.createTarget 请求,用于后续建立 targetId -> clientId 映射
887
894
  // 注意:此时 parsed.id 已经是 globalId,originalId 已经保存在 mapping 中
888
895
  if (parsed && parsed.method === 'Target.createTarget' && parsed.id !== undefined) {