From 5b37c7daa435b00850a001941ab9416f7467f226 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 5 Jun 2025 23:47:34 +0000 Subject: [PATCH] Implement Node.js IPC channel handle support for child processes --- hmr-research.md | 187 ++++++++++++++++++ src/bun.js/bindings/BunProcess.cpp | 30 +++ src/bun.js/bindings/webcore/HTTPHeaderMap.cpp | 2 +- src/bun.js/node/node_cluster_binding.zig | 38 ++++ src/js/builtins/ProcessObjectInternals.ts | 11 ++ src/js/internal/child_process.ts | 4 + test-channel.js | 35 ++++ test-filtered.js | 42 ++++ test-ipc-channel-handle.js | 33 ++++ .../test-child-process-recv-handle.js | 86 ++++++++ 10 files changed, 467 insertions(+), 1 deletion(-) create mode 100644 hmr-research.md create mode 100644 src/js/internal/child_process.ts create mode 100644 test-channel.js create mode 100644 test-filtered.js create mode 100644 test-ipc-channel-handle.js create mode 100644 test/js/node/test/parallel/test-child-process-recv-handle.js diff --git a/hmr-research.md b/hmr-research.md new file mode 100644 index 0000000000..182c68f977 --- /dev/null +++ b/hmr-research.md @@ -0,0 +1,187 @@ +# Bun Hot Module Reloading (HMR) and Hot Code Swapping Research + +## Overview + +Bun implements hot module reloading (HMR) and hot code swapping through a sophisticated system that combines file watching, incremental bundling, WebSocket communication, and a runtime HMR module system. The implementation supports both client-side and server-side hot reloading, with special support for React Fast Refresh. + +## Architecture Components + +### 1. File Watching System + +Bun uses platform-specific file watchers on a separate thread: + +- **Linux**: INotifyWatcher using inotify system calls +- **macOS**: KEventWatcher using kqueue +- **Windows**: WindowsWatcher using IOCP and ReadDirectoryChangesW + +The watcher system: + +- Runs on its own thread to avoid blocking the main event loop +- Coalesces multiple file change events to reduce noise +- Communicates with the main thread using atomic operations and concurrent tasks +- Supports watching both files and directories recursively + +### 2. DevServer and Incremental Bundler + +The DevServer (`src/bake/DevServer.zig`) is the core component that: + +- Manages the incremental bundling process +- Maintains separate dependency graphs for client and server code +- Tracks which files need rebundling when changes occur +- Handles WebSocket connections for pushing updates to clients + +Key features: + +- Incremental bundling: Only rebuilds changed modules and their dependents +- Dual graphs: Separate incremental graphs for client and server code +- Source map management with reference counting +- Asset serving and caching + +### 3. WebSocket Protocol + +The WebSocket protocol (`src/bake/DevServer.zig:MessageId`) uses binary messages with a single-byte message ID prefix: + +- **Version (V)**: Sent on connection to ensure client/server compatibility +- **Hot Update (u)**: Contains updated modules, CSS changes, and route updates +- **Errors (e)**: Sends bundling/runtime errors to display in overlay +- **Memory Visualizer (M)**: Debug information about memory usage + +The protocol is designed for efficiency: + +- Binary transport for minimal overhead +- Batched updates to reduce round trips +- Client-side deduplication of updates + +### 4. HMR Runtime + +The HMR runtime consists of two main parts: + +#### Client-side Runtime (`src/bake/hmr-module.ts`) + +- Implements the `import.meta.hot` API compatible with Vite +- Manages module registry and dependency tracking +- Handles module replacement and state preservation +- Supports React Fast Refresh for component hot reloading + +#### Server-side Runtime (`src/bake/hmr-runtime-server.ts`) + +- Handles server-side module replacement +- Manages route updates without full page reloads +- Integrates with framework-specific reloading mechanisms + +### 5. Module System Features + +#### Module Registry + +- Each module gets a unique ID and is stored in a registry +- Modules can be ESM or CommonJS +- Module state is preserved across reloads using `import.meta.hot.data` + +#### HMR Boundaries + +- Modules can self-accept updates with `import.meta.hot.accept()` +- Parent modules can accept updates for dependencies +- If no boundary is found, triggers a full page reload +- Automatic boundary detection for modules using `import.meta.hot.data` + +#### React Fast Refresh + +- Automatic integration when React is detected +- Wraps React components with refresh signatures +- Preserves component state during updates +- Uses a hash-based system to detect hook changes + +## Implementation Details + +### File Change Detection Flow + +1. **File System Event**: Platform watcher detects file change +2. **Event Coalescing**: Multiple rapid changes are batched (100μs window) +3. **Hot Reload Event**: Created and passed to DevServer thread +4. **Dependency Analysis**: Determines which modules are affected +5. **Incremental Bundle**: Only rebuilds changed modules +6. **WebSocket Push**: Sends updates to connected clients +7. **Runtime Update**: Client applies changes without page reload + +### Incremental Bundling Strategy + +The incremental bundler maintains: + +- **File indices**: Maps file paths to graph nodes +- **Import/export tracking**: Knows module dependencies +- **Stale file tracking**: Marks files needing rebuild +- **Edge tracking**: Import relationships between modules + +When a file changes: + +1. Mark the file and its importers as stale +2. Trace through the dependency graph +3. Find HMR boundaries (self-accepting modules) +4. Bundle only the stale modules +5. Generate minimal update payloads + +### CSS Hot Reloading + +CSS updates are handled specially: + +- CSS files are tracked separately in the bundler +- Changes trigger immediate style updates without JS evaluation +- Uses a content-based hash system for deduplication +- Supports both `` and `