From a8dc08df1b975e899458eab7ba9c495d787b0d4d Mon Sep 17 00:00:00 2001 From: "Tommy D. Rossi" Date: Sun, 16 Nov 2025 11:30:14 +0100 Subject: [PATCH] remove files --- extension-new/COMPARISON.md | 242 ------------------------------------ extension-new/MIGRATION.md | 75 ----------- extension-new/README.md | 85 ------------- 3 files changed, 402 deletions(-) delete mode 100644 extension-new/COMPARISON.md delete mode 100644 extension-new/MIGRATION.md delete mode 100644 extension-new/README.md diff --git a/extension-new/COMPARISON.md b/extension-new/COMPARISON.md deleted file mode 100644 index ab88566..0000000 --- a/extension-new/COMPARISON.md +++ /dev/null @@ -1,242 +0,0 @@ -# Old vs New Implementation Comparison - -## Old Implementation Issues - -### Class-Based Complexity - -**Old (`cdpRelay.ts`):** -```typescript -export class CDPRelayServer { - private _wsHost: string - private _cdpPath: string - private _extensionPath: string - private _wss: WebSocketServer - private _playwrightConnection: WebSocket | null = null - private _extensionConnection: ExtensionConnection | null = null - private _connectedTargets: Map = new Map() - private _extensionConnectionPromise!: ManualPromise - - constructor(server: http.Server) { - // Initialize all state - this._wss = new wsServer({ server }) - this._wss.on('connection', (ws, request) => { - // Complex nested logic - }) - } - - private _handlePlaywrightConnection(ws: WebSocket): void { } - private _handleExtensionMessage(message: ExtensionEventMessage) { } - private async _handlePlaywrightMessage(message: CDPCommand): Promise { } - private _sendToPlaywright(message: CDPResponse | CDPEvent): void { } - // ... many more private methods -} - -class ExtensionConnection { - // Nested class with its own state -} -``` - -**Issues:** -- State scattered across private fields -- Methods mutate class state (`this._playwrightConnection = ws`) -- Nested classes make it hard to follow data flow -- Manual promise management (`ManualPromise`) - -### New (Functional):** -```typescript -export async function startRelayServer({ port = 19988 }) { - const targetsRegistry = createTargetsRegistry() - let playwrightWs: WSContext | null = null - let extensionWs: WSContext | null = null - let extensionConnection: ExtensionConnection | null = null - - // All state is local variables - // All logic is inline or in pure functions - - return { - cdpEndpoint, - extensionEndpoint, - close() { /* cleanup */ } - } -} -``` - -**Benefits:** -- All state in one place (function scope) -- Clear lifecycle (create → use → cleanup) -- No `this`, easier to reason about -- Returns cleanup function - -## Message Handling - -### Old: -```typescript -// Spread across multiple private methods -private async _handlePlaywrightMessage(message: CDPCommand): Promise { - const forwardToExtension = async (...) => { } - const handleCDPCommand = async (...) => { - switch (method) { - case 'Browser.getVersion': { } - case 'Target.setAutoAttach': { } - // ... - } - } - try { - const result = await handleCDPCommand(...) - this._sendToPlaywright({ id, sessionId, result }) - } catch (e) { - this._sendToPlaywright({ error }) - } -} -``` - -### New: -```typescript -// CDP routing extracted to dedicated module -const router = createCdpRouter({ targetsRegistry, extensionConnection }) -const result: any = await router.route({ method, params, sessionId }) -sendToPlaywright({ id, sessionId, result }) -``` - -**Benefits:** -- Separation of concerns -- Router is testable in isolation -- Clear dependencies (passed as args) - -## WebSocket Setup - -### Old (Manual ws library): -```typescript -this._wss = new wsServer({ server }) -this._wss.on('connection', (ws: WebSocket, request: http.IncomingMessage) => { - const url = new URL(`http://localhost${request.url}`) - if (url.pathname === this._cdpPath) { - this._handlePlaywrightConnection(ws) - } else if (url.pathname === this._extensionPath) { - this._extensionConnection = new ExtensionConnection(ws) - } -}) -``` - -### New (Hono WebSocket): -```typescript -const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app }) - -app.get('/cdp', upgradeWebSocket(() => ({ - onOpen(_event, ws) { }, - onMessage(event, ws) { }, - onClose() { }, - onError(event) { } -}))) - -app.get('/extension', upgradeWebSocket(() => ({ - onOpen(_event, ws) { }, - onMessage(event, ws) { }, - onClose() { }, - onError(event) { } -}))) -``` - -**Benefits:** -- Declarative routing -- Built-in event handlers -- Framework handles upgrade protocol -- Cleaner separation between endpoints - -## Targets Registry - -### Old (Private Map): -```typescript -class CDPRelayServer { - private _connectedTargets: Map = new Map() - - // Scattered operations - this._connectedTargets.set(targetParams.sessionId, { ... }) - this._connectedTargets.delete(detachParams.sessionId) - for (const target of this._connectedTargets.values()) { } -} -``` - -### New (Functional Registry): -```typescript -function createTargetsRegistry() { - const targets = new Map() - return { - add({ sessionId, targetId, targetInfo }) { }, - remove(sessionId) { }, - get(sessionId) { }, - findByTargetId(targetId) { }, - getAll() { }, - clear() { } - } -} - -const targetsRegistry = createTargetsRegistry() -targetsRegistry.add({ ... }) -targetsRegistry.remove(sessionId) -``` - -**Benefits:** -- Encapsulated state -- Clear API -- Easy to test -- Can be reused - -## Logging - -### Old: -```typescript -debugLogger(`New connection to ${url.pathname}`) -debugLogger('Rejecting second Playwright connection') -debugLogger('Playwright MCP connected') -debugLogger('Extension WebSocket closed:', reason, c === this._extensionConnection) -debugLogger(`← Playwright: ${message.method} (id=${message.id})`) -debugLogger('\x1b[36m← Playwright:\x1b[0m', `${message.method} (id=${message.id})`) -debugLogger('\x1b[33m← Extension:\x1b[0m', `Target.attachedToTarget ...`) -debugLogger('\x1b[32m→ Playwright:\x1b[0m', logMessage) -debugLogger('\x1b[31mError in the extension:\x1b[0m', e) -``` - -### New: -```typescript -console.log('Playwright connected') -console.log('Extension connected') -console.log('← Playwright:', `${message.method} (id=${message.id})`) -console.log('← Extension:', method) -console.error('Error handling CDP command:', e) -``` - -**Benefits:** -- Simple console.log -- Only important events -- No color codes -- No verbose state dumps - -## Code Metrics - -| Metric | Old | New | -|--------|-----|-----| -| Files | 4 | 2 (relay-server.ts + protocol.ts) | -| Main class LOC | ~417 | 321 (everything inlined) | -| Total LOC | ~600 | ~370 | -| Classes | 2 | 0 | -| Private methods | 10+ | 0 | -| Helper modules | 0 | 0 (all inlined) | -| Dependencies | playwright-core (ws) | hono, @hono/node-ws | - -## Migration Path - -The new implementation is a drop-in replacement: - -**Old:** -```typescript -const httpServer = await startHttpServer({ port: 19988 }) -const cdpRelayServer = new CDPRelayServer(httpServer) -cdpRelayServer.stop() -``` - -**New:** -```typescript -const server = await startRelayServer({ port: 19988 }) -server.close() -``` diff --git a/extension-new/MIGRATION.md b/extension-new/MIGRATION.md deleted file mode 100644 index f5986c4..0000000 --- a/extension-new/MIGRATION.md +++ /dev/null @@ -1,75 +0,0 @@ -# Migration Complete - -The new CDP relay server implementation has been moved into `playwriter/src/extension/`. - -## What Changed - -### Files Removed -- ❌ `src/extension/cdpRelay.ts` (~417 lines) - Old class-based implementation -- ❌ `src/extension/types.ts` - Old type definitions - -### Files Added/Updated -- ✅ `src/extension/relay-server.ts` (321 lines) - New inline implementation -- ✅ `src/extension/protocol.ts` (34 lines) - Message type definitions -- ✅ `src/extension/extensionContextFactory.ts` - Now just re-exports `startRelayServer` - -### Updated Scripts -- ✅ `scripts/extension-server.ts` - Uses new simplified API - -## New API - -**Before:** -```typescript -const controller = new AbortController() -const { cdpRelayServer } = await startRelayServer(controller.signal) -// Complex class-based API -cdpRelayServer.stop() -``` - -**After:** -```typescript -const server = await startRelayServer({ port: 19988 }) -// Simple object API -server.close() -``` - -## Code Reduction - -| Metric | Before | After | -|--------|--------|-------| -| Total LOC | ~600 | ~370 | -| Files | 4 | 3 | -| Classes | 2 | 0 | -| Helper functions | Multiple modules | All inlined | - -## Dependencies Added - -```json -{ - "hono": "^4.10.6", - "@hono/node-server": "^1.19.6", - "@hono/node-ws": "^1.2.0" -} -``` - -## Testing - -```bash -cd playwriter -pnpm typecheck # ✅ Passes -pnpm build # ✅ Builds successfully - -# Run the server -vite-node scripts/extension-server.ts -``` - -## Architecture - -Everything is now in **one file** (`relay-server.ts`): -- Target registry (simple Map) -- Extension request/response handling -- CDP command routing -- WebSocket endpoints -- Message forwarding - -No abstractions, no helper modules, just straightforward code. diff --git a/extension-new/README.md b/extension-new/README.md deleted file mode 100644 index e159c43..0000000 --- a/extension-new/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# Extension New - Rewritten CDP Relay Server - -Clean, simple rewrite of the CDP relay server using Hono WebSocket. - -## Architecture - -The relay server acts as a bridge between: -- **Playwright** (connects via `/cdp`) - Controls the browser -- **Chrome Extension** (connects via `/extension`) - Provides chrome.debugger access - -### Message Flow - -``` -Playwright → /cdp → Router → /extension → Extension → chrome.debugger → Tab -Tab → chrome.debugger → Extension → /extension → /cdp → Playwright -``` - -## Implementation - -**Everything inlined in one file** - No abstraction layers, just straightforward code. - -### Files - -**`relay-server.ts`** - Single file with everything: -- Two WebSocket endpoints (`/cdp` and `/extension`) -- Connection lifecycle management -- CDP command routing (Browser.*, Target.*, etc) -- Extension request/response handling -- Target registry (simple Map) -- All message forwarding logic - -**`protocol.ts`** - Message type definitions - -**`index.ts`** - Exports -**`example.ts`** - Usage example - -## Key Improvements - -**Simpler Code:** -- Everything in one place -- No helper functions or modules -- Clear linear flow -- All state as local variables - -**Better Logging:** -- Only logs connection events, CDP messages, and errors -- No verbose debug noise - -**Clean API:** - -```typescript -const server = await startRelayServer({ port: 19988 }) - -// Returns: -// { -// cdpEndpoint: 'ws://localhost:19988/cdp', -// extensionEndpoint: 'ws://localhost:19988/extension', -// close: () => void -// } - -// Cleanup: -server.close() -``` - -## Usage - -```typescript -import { startRelayServer } from './relay-server.js' - -const server = await startRelayServer({ port: 19988 }) - -console.log('Extension endpoint:', server.extensionEndpoint) -console.log('CDP endpoint:', server.cdpEndpoint) - -// Later: -server.close() -``` - -## Running Example - -```bash -pnpm install -pnpm build -node dist/example.js -```