Files
playwriter/extension-kapture/modules/tab-state.js
Tommy D. Rossi ec02a90812 adding examples
2025-11-13 19:42:44 +01:00

178 lines
3.8 KiB
JavaScript

// WebSocket connection info
import { ConnectionStatus, Message } from "./models.js";
export class ConnectionInfo {
constructor(url) {
this.url = url;
this.status = ConnectionStatus.DISCONNECTED;
this.connected = false;
this.userDisconnected = false;
this.reconnectAttempts = 0;
this.reconnectTimer = null;
this.nextRetryIn = null;
}
setConnected() {
this.status = ConnectionStatus.CONNECTED;
this.connected = true;
this.reconnectAttempts = 0;
this.nextRetryIn = null;
}
setDisconnected(userInitiated = false) {
this.status = ConnectionStatus.DISCONNECTED;
this.connected = false;
this.userDisconnected = userInitiated;
if (userInitiated) {
this.reconnectAttempts = 0;
this.nextRetryIn = null;
}
}
setRetrying(attemptNumber, nextRetryMs) {
this.status = ConnectionStatus.RETRYING;
this.connected = false;
this.reconnectAttempts = attemptNumber;
this.nextRetryIn = nextRetryMs;
}
setError(error) {
this.status = ConnectionStatus.ERROR;
this.connected = false;
}
}
// Main tab state class
export class TabState {
constructor(tabId) {
this.tabId = tabId;
this.websocket = null;
this.connectionInfo = new ConnectionInfo('ws://localhost:61822');
this.messages = [];
this.consoleLogs = [];
this.ports = new Set(); // Connected DevTools panels/popups
this.pageMetadata = {};
this.mousePosition = { x: 0, y: 0 }; // Track current mouse position
}
// WebSocket management
setWebSocket(ws) {
this.websocket = ws;
}
clearWebSocket() {
this.websocket = null;
}
// Message management
addMessage(direction, data) {
const message = new Message(direction, data);
this.messages.push(message);
return message;
}
clearMessages() {
this.messages = [];
}
getMessages(limit = null) {
if (limit === null) {
return [...this.messages];
}
return this.messages.slice(-limit);
}
// Console log management
addConsoleLog(log) {
this.consoleLogs.unshift(log);
}
clearConsoleLogs() {
this.consoleLogs = [];
}
getConsoleLogs(limit = null, level = null, before = null) {
let logs = this.consoleLogs;
if (level) {
logs = logs.filter(log => log.level === level);
}
if (before) {
const beforeTimestamp = new Date(before).getTime();
logs = logs.filter(log =>
new Date(log.timestamp).getTime() < beforeTimestamp
);
}
if (limit === null) {
return [...logs];
}
return logs.slice(-limit);
}
getConsoleLogCount() {
return this.consoleLogs.length;
}
// Port management
addPort(port) {
this.ports.add(port);
}
removePort(port) {
this.ports.delete(port);
}
broadcastToPorts(message) {
this.ports.forEach(port => {
try {
port.postMessage(message);
} catch (e) {
// Port might be disconnected
this.ports.delete(port);
}
});
}
// State management
getConnectionState() {
return {
connected: this.connectionInfo.connected,
status: this.connectionInfo.status,
reconnectAttempt: this.connectionInfo.reconnectAttempts,
nextRetryIn: this.connectionInfo.nextRetryIn
};
}
updatePageMetadata(metadata) {
this.pageMetadata = metadata;
}
// Mouse position tracking
setMousePosition(position) {
this.mousePosition = { ...position };
}
// Cleanup
cleanup() {
// Clear reconnect timer
if (this.connectionInfo.reconnectTimer) {
clearTimeout(this.connectionInfo.reconnectTimer);
this.connectionInfo.reconnectTimer = null;
}
// Close WebSocket
if (this.websocket) {
this.websocket.close();
this.websocket = null;
}
// Clear all data
this.messages = [];
this.consoleLogs = [];
this.ports.clear();
}
}