remove files

This commit is contained in:
Tommy D. Rossi
2025-11-16 11:30:14 +01:00
parent 29488aca76
commit a8dc08df1b
3 changed files with 0 additions and 402 deletions
-242
View File
@@ -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<string, ConnectedTarget> = new Map()
private _extensionConnectionPromise!: ManualPromise<void>
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<void> { }
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<void> {
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<string, ConnectedTarget> = 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<string, ConnectedTarget>()
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()
```
-75
View File
@@ -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.
-85
View File
@@ -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
```