@@ -25,12 +25,12 @@ class SimplifiedExtension {
|
||||
|
||||
constructor() {
|
||||
debugLog(`Using relay URL: ${RELAY_URL}`);
|
||||
chrome.tabs.onRemoved.addListener(this._onTabRemoved);
|
||||
chrome.tabs.onActivated.addListener(this._onTabActivated);
|
||||
chrome.action.onClicked.addListener(this._onActionClicked);
|
||||
chrome.tabs.onRemoved.addListener(this._onTabRemoved.bind(this));
|
||||
chrome.tabs.onActivated.addListener(this._onTabActivated.bind(this));
|
||||
chrome.action.onClicked.addListener(this._onActionClicked.bind(this));
|
||||
}
|
||||
|
||||
private _onActionClicked = async (tab: chrome.tabs.Tab): Promise<void> => {
|
||||
private async _onActionClicked(tab: chrome.tabs.Tab): Promise<void> {
|
||||
if (!tab.id) {
|
||||
debugLog('No tab ID available');
|
||||
return;
|
||||
@@ -41,7 +41,23 @@ class SimplifiedExtension {
|
||||
} else {
|
||||
await this._connectTab(tab.id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private async _waitForServer(): Promise<void> {
|
||||
const httpUrl = 'http://localhost:9988';
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
debugLog('Checking if relay server is available...');
|
||||
await fetch(httpUrl, { method: 'HEAD' });
|
||||
debugLog('Server is available');
|
||||
return;
|
||||
} catch (error: any) {
|
||||
debugLog(`Server not available, retrying in 1 second...`);
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async _connectTab(tabId: number): Promise<void> {
|
||||
try {
|
||||
@@ -51,18 +67,7 @@ class SimplifiedExtension {
|
||||
if (!this._connection) {
|
||||
debugLog('No existing connection, creating new relay connection');
|
||||
debugLog('Waiting for server at http://localhost:9988...');
|
||||
|
||||
// Wait for server to be available
|
||||
while (true) {
|
||||
try {
|
||||
await fetch('http://localhost:9988', { method: 'HEAD' });
|
||||
debugLog('Server is available');
|
||||
break;
|
||||
} catch (error: any) {
|
||||
debugLog('Server not available, retrying in 1 second...');
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
}
|
||||
await this._waitForServer();
|
||||
|
||||
debugLog('Server is ready, creating WebSocket connection to:', RELAY_URL);
|
||||
const socket = new WebSocket(RELAY_URL);
|
||||
@@ -234,19 +239,19 @@ class SimplifiedExtension {
|
||||
}
|
||||
}
|
||||
|
||||
private _onTabRemoved = async (tabId: number): Promise<void> => {
|
||||
private async _onTabRemoved(tabId: number): Promise<void> {
|
||||
debugLog('Tab removed event for tab:', tabId, 'is connected:', this._connectedTabs.has(tabId));
|
||||
if (!this._connectedTabs.has(tabId)) return;
|
||||
|
||||
debugLog(`Connected tab ${tabId} was closed, disconnecting`);
|
||||
await this._disconnectTab(tabId);
|
||||
};
|
||||
}
|
||||
|
||||
private _onTabActivated = async (activeInfo: chrome.tabs.TabActiveInfo): Promise<void> => {
|
||||
private async _onTabActivated(activeInfo: chrome.tabs.TabActiveInfo): Promise<void> {
|
||||
const isConnected = this._connectedTabs.has(activeInfo.tabId);
|
||||
debugLog('Tab activated:', activeInfo.tabId, 'is connected:', isConnected);
|
||||
await this._updateIcon(activeInfo.tabId, isConnected ? 'connected' : 'disconnected');
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
new SimplifiedExtension();
|
||||
|
||||
@@ -41,42 +41,16 @@ export class RelayConnection {
|
||||
private _attachedTabs: Map<number, AttachedTab> = new Map();
|
||||
private _nextSessionId: number = 1;
|
||||
private _ws: WebSocket;
|
||||
private _eventListener: (source: chrome.debugger.DebuggerSession, method: string, params: any) => void;
|
||||
private _detachListener: (source: chrome.debugger.Debuggee, reason: string) => void;
|
||||
private _closed = false;
|
||||
|
||||
onclose?: () => void;
|
||||
|
||||
constructor(ws: WebSocket) {
|
||||
this._ws = ws;
|
||||
this._ws.onmessage = async (event: MessageEvent) => {
|
||||
let message: ExtensionCommandMessage;
|
||||
try {
|
||||
message = JSON.parse(event.data);
|
||||
} catch (error: any) {
|
||||
debugLog('Error parsing message:', error);
|
||||
this._sendMessage({
|
||||
error: {
|
||||
code: -32700,
|
||||
message: `Error parsing message: ${error.message}`,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
debugLog('Received message:', message);
|
||||
|
||||
const response: ExtensionResponseMessage = {
|
||||
id: message.id,
|
||||
};
|
||||
try {
|
||||
response.result = await this._handleCommand(message);
|
||||
} catch (error: any) {
|
||||
debugLog('Error handling command:', error);
|
||||
response.error = error.message;
|
||||
}
|
||||
debugLog('Sending response:', response);
|
||||
this._sendMessage(response);
|
||||
};
|
||||
this._ws.onclose = (event: CloseEvent) => {
|
||||
this._ws.onmessage = this._onMessage.bind(this);
|
||||
this._ws.onclose = (event) => {
|
||||
debugLog('WebSocket onclose event:', {
|
||||
code: event.code,
|
||||
reason: event.reason,
|
||||
@@ -84,11 +58,13 @@ export class RelayConnection {
|
||||
});
|
||||
this._onClose();
|
||||
};
|
||||
this._ws.onerror = (event: Event) => {
|
||||
this._ws.onerror = (event) => {
|
||||
debugLog('WebSocket onerror event:', event);
|
||||
};
|
||||
chrome.debugger.onEvent.addListener(this._onDebuggerEvent);
|
||||
chrome.debugger.onDetach.addListener(this._onDebuggerDetach);
|
||||
this._eventListener = this._onDebuggerEvent.bind(this);
|
||||
this._detachListener = this._onDebuggerDetach.bind(this);
|
||||
chrome.debugger.onEvent.addListener(this._eventListener);
|
||||
chrome.debugger.onDetach.addListener(this._detachListener);
|
||||
debugLog('RelayConnection created, WebSocket readyState:', this._ws.readyState);
|
||||
}
|
||||
|
||||
@@ -191,8 +167,8 @@ export class RelayConnection {
|
||||
debugLog('Connection closing, attached tabs count:', this._attachedTabs.size);
|
||||
this._closed = true;
|
||||
|
||||
chrome.debugger.onEvent.removeListener(this._onDebuggerEvent);
|
||||
chrome.debugger.onDetach.removeListener(this._onDebuggerDetach);
|
||||
chrome.debugger.onEvent.removeListener(this._eventListener);
|
||||
chrome.debugger.onDetach.removeListener(this._detachListener);
|
||||
|
||||
const tabIds = Array.from(this._attachedTabs.keys());
|
||||
debugLog('Detaching all tabs:', tabIds);
|
||||
@@ -215,7 +191,7 @@ export class RelayConnection {
|
||||
this.onclose?.();
|
||||
}
|
||||
|
||||
private _onDebuggerEvent = (source: chrome.debugger.DebuggerSession, method: string, params: any): void => {
|
||||
private _onDebuggerEvent(source: chrome.debugger.DebuggerSession, method: string, params: any): void {
|
||||
const tab = this._attachedTabs.get(source.tabId!);
|
||||
if (!tab) return;
|
||||
|
||||
@@ -245,9 +221,9 @@ export class RelayConnection {
|
||||
params,
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private _onDebuggerDetach = (source: chrome.debugger.Debuggee, reason: string): void => {
|
||||
private _onDebuggerDetach(source: chrome.debugger.Debuggee, reason: string): void {
|
||||
const tabId = source.tabId;
|
||||
debugLog('_onDebuggerDetach called for tab:', tabId, 'reason:', reason, 'isAttached:', tabId ? this._attachedTabs.has(tabId) : false);
|
||||
|
||||
@@ -258,7 +234,36 @@ export class RelayConnection {
|
||||
|
||||
debugLog(`Debugger detached from tab ${tabId}: ${reason}`);
|
||||
this.detachTab(tabId);
|
||||
};
|
||||
}
|
||||
|
||||
private _onMessage(event: MessageEvent): void {
|
||||
this._onMessageAsync(event).catch(e => debugLog('Error handling message:', e));
|
||||
}
|
||||
|
||||
private async _onMessageAsync(event: MessageEvent): Promise<void> {
|
||||
let message: ExtensionCommandMessage;
|
||||
try {
|
||||
message = JSON.parse(event.data);
|
||||
} catch (error: any) {
|
||||
debugLog('Error parsing message:', error);
|
||||
this._sendError(-32700, `Error parsing message: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
debugLog('Received message:', message);
|
||||
|
||||
const response: ExtensionResponseMessage = {
|
||||
id: message.id,
|
||||
};
|
||||
try {
|
||||
response.result = await this._handleCommand(message);
|
||||
} catch (error: any) {
|
||||
debugLog('Error handling command:', error);
|
||||
response.error = error.message;
|
||||
}
|
||||
debugLog('Sending response:', response);
|
||||
this._sendMessage(response);
|
||||
}
|
||||
|
||||
private async _handleCommand(message: ExtensionCommandMessage): Promise<any> {
|
||||
if (message.method === 'attachToTab') {
|
||||
@@ -334,6 +339,15 @@ export class RelayConnection {
|
||||
}
|
||||
}
|
||||
|
||||
private _sendError(code: number, message: string): void {
|
||||
this._sendMessage({
|
||||
error: {
|
||||
code,
|
||||
message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private _sendMessage(message: any): void {
|
||||
if (this._ws.readyState === WebSocket.OPEN) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user