Skip to content

Latest commit

 

History

History
191 lines (142 loc) · 6.76 KB

File metadata and controls

191 lines (142 loc) · 6.76 KB

Bun WebSocket Solution Documentation

Executive Summary

Successfully resolved the WebSocket "Disconnected" issue in the Bun-compiled standalone executable by implementing a unified Bun server that replaces the incompatible Node.js ws module with Bun's native WebSocket API, without modifying any source code.

The Problem

Root Cause

When compiling the Auditaria into a standalone Windows executable using Bun, the web interface (-w flag) would show "Disconnected" instead of maintaining a WebSocket connection. This occurred because:

  1. Module Incompatibility: The ws npm module depends on Node.js internals not available in Bun runtime
  2. Multiple Usage Points: Both packages/cli/src/services/WebInterfaceService.ts and packages/web-server/src/websocket/websocketHandler.js use the ws module
  3. Runtime Differences: Bun uses uWebSockets internally, requiring a different API than Node.js

Initial Symptoms

  • Web interface loads but shows "Disconnected"
  • WebSocket upgrade requests fail or return "Not a WebSocket request"
  • Locale files cannot be read from the compiled executable
  • Process doesn't stay alive in web mode

The Solution

Core Implementation: sea/build-bun-unified.cjs

A build script that modifies the JavaScript bundle during compilation to:

  1. Runtime Detection

    • Detects Bun runtime via typeof Bun !== 'undefined'
    • Only activates replacements when running in Bun
    • Falls back to original code in Node.js environments
  2. Unified Server Architecture

    • Creates a single Bun.serve() instance handling both HTTP and WebSocket
    • Replaces Express server + ws WebSocketServer combination
    • Maintains single port for all communication
  3. Module Override Strategy

    • Globally replaces WebSocketServer and WebSocket classes
    • Intercepts require('ws') calls
    • Patches module cache entries
    • Provides API-compatible mock objects
  4. Asset Embedding

    • Embeds 18 web client files as base64 strings
    • Embeds locale files (en.json, pt.json) to prevent file system errors
    • Serves all assets from memory
  5. Compatibility Layer

    • Mock WebSocket objects maintain ws module API
    • Event handlers (on, send, close) work identically
    • State management preserved for existing code

Technical Implementation

Build Process Flow

# 1. Install Bun on Windows
powershell -Command "irm bun.sh/install.ps1 | iex"

# 2. Build the bundle (creates bundle/gemini.js)
npm run bundle

# 3. Create standalone executable with WebSocket fix
node sea/build-bun-unified.cjs

# 4. Run the executable
auditaria-standalone.exe -w no-browser

Key Code Modifications Applied

  1. Interactive Mode Fix

    // Original (web mode not recognized as interactive)
    const interactive = !!argv.promptInteractive || process33.stdin.isTTY && question.length === 0;
    
    // Fixed (includes web mode)
    const interactive = !!argv.promptInteractive || !!argv.web || (process33.stdin.isTTY && question.length === 0);
  2. WebSocket Server Override

    // Replaces all instantiations
    new (globalThis.WebSocketServer || import_websocket_server.default)
  3. Locale Warning Suppression

    • Warnings about missing locale directories are commented out
    • Locale data loaded from embedded globals instead of file system

Files and Changes

Created Files

  • sea/build-bun-unified.cjs - The complete build script with all fixes
  • WEBSOCKET-SOLUTION-REPORT.md - This documentation

Modified Files

  • .github/workflows/build-windows-exe.yml - Updated to use the new build script
  • .gitignore - Updated for Bun artifacts

No Source Code Changes Required

  • packages/cli/src/services/WebInterfaceService.ts - Unchanged
  • packages/web-server/src/websocket/websocketHandler.js - Unchanged
  • All other source files remain unmodified

How It Works

Runtime Behavior

In Node.js (npm run dev, npm run build):

  • Original Express + ws code executes
  • No Bun code runs (runtime check fails)
  • WebSockets work normally via ws module

In Bun Executable:

  1. Runtime detection triggers Bun code path
  2. Unified Bun server starts on specified port
  3. HTTP requests serve embedded web client files
  4. WebSocket upgrades handled by Bun's native API
  5. All ws module calls redirected to Bun implementation

WebSocket Message Flow

  1. Client Connection

    • Browser requests WebSocket upgrade
    • Bun.serve() handles upgrade via server.upgrade(req)
    • Connection added to global client set
  2. Message Exchange

    • Client messages parsed and routed to handlers
    • Server broadcasts using native ws.send()
    • State synchronized across all clients
  3. Compatibility Maintenance

    • Mock objects preserve existing event handler patterns
    • on('message'), on('close') etc. work identically
    • No changes needed in application logic

Testing and Validation

Confirmed Working

  • ✅ WebSocket shows "Connected" in web interface
  • ✅ Real-time message exchange functional
  • ✅ No locale warning messages
  • ✅ Process stays alive in web mode
  • ✅ All existing features preserved

Test Commands

# Build and test locally
node sea/build-bun-unified.cjs
auditaria-standalone.exe -w no-browser
# Open browser to http://localhost:8629

# Verify WebSocket connection
# Check browser console - should show "Connected to Auditaria"

GitHub Actions Integration

The workflow at .github/workflows/build-windows-exe.yml has been updated to:

  1. Use npm run bundle instead of npm run build
  2. Execute sea/build-bun-unified.cjs instead of direct Bun compile
  3. Include WebSocket support in release notes

Performance and Size

  • Executable Size: ~125MB (includes all embedded assets)
  • Startup Time: Comparable to original
  • WebSocket Latency: Native Bun performance (typically faster than ws module)
  • Memory Usage: Slightly higher due to embedded assets

Maintenance Notes

Future Updates

When syncing with upstream or updating the codebase:

  1. No special handling needed for WebSocket code
  2. Build script handles all transformations automatically
  3. New ws module usage will be automatically intercepted

Debugging

If WebSocket issues occur:

  1. Check browser console for connection errors
  2. Verify port availability (default 8629)
  3. Look for [Bun] prefixed console messages
  4. Ensure Windows Firewall allows the executable

Conclusion

This solution provides a complete, maintainable fix for WebSocket connectivity in Bun-compiled executables without modifying any source code. The build-time transformations ensure compatibility while preserving the ability to run the same codebase in Node.js environments. The approach is transparent to developers and requires no changes to existing development workflows.