How OfficeCLI Watch Mode Provides Real-Time Browser Preview Updates
OfficeCLI's watch mode establishes a persistent Server-Sent Events (SSE) connection between a local HTTP server and your browser, streaming JSON patch instructions that trigger targeted DOM mutations while preserving UI state through a hook-based decoration system.
OfficeCLI, the open-source command-line tool maintained by iOfficeAI, enables developers to preview Word, Excel, and PowerPoint documents directly in the browser. The watch mode creates a live editing environment where changes made via the CLI or API calls reflect instantly in the preview without full page reloads, leveraging a tightly-coupled client-server architecture defined in the src/officecli/Core/Watch/ directory.
Architecture Overview
The system operates through three distinct layers that coordinate to deliver seamless real-time updates:
- Server Layer: An embedded HTTP server (
WatchServer.cs) that serves the initial HTML preview and manages the/eventsSSE endpoint - Core DOM Layer: The
watch-sse-core.jsscript that parses incoming messages and executes surgical DOM mutations - Overlay Layer: The
watch-overlay.jsscript that maintains selections, marks, and UI decorations across mutation cycles
This separation ensures that structural document updates and decorative UI elements remain synchronized without interfering with each other.
The Server Layer
When you invoke officecli watch <file>, the CLI launches a WatchServer instance bound to a random local port (e.g., http://127.0.0.1:49712). Located at src/officecli/Core/Watch/WatchServer.cs, this server performs two critical functions: it generates the initial preview page embedding your rendered document, and it opens an EventSource stream at /events that pushes JSON messages to connected browsers.
The server communicates with the CLI process through WatchNotifier.cs. When the CLI re-renders part of a document after an edit, it calls WatchNotifier.Notify() with a JSON payload. The notifier opens a TCP client to the watch server, writes the message, and closes the connection. The server then broadcasts this payload to every connected browser via the SSE stream, ensuring all preview clients remain synchronized.
Client-Side Script Layers
The browser preview loads two embedded JavaScript resources as base64-encoded data URIs, creating a two-tier handling system for updates.
Core DOM Handling
The src/officecli/Resources/watch-sse-core.js script establishes the SSE connection to /events and defines the primary mutation logic. Upon receiving a message, it parses the action field and executes the appropriate DOM operation:
full: Replaces the entire<body>content for non-incremental document typesreplace,add,remove: Target specific slide containers using.slide-container[data-slide]selectorsword-patch: Applies block-level diff patches to Word documents using<wb>and<we>markersexcel-patch: Updates table rows or swaps style sheets for Excel workbooksscroll: Jumps to specific selectors or slide numbers without DOM manipulation
After every mutation, the script calls window._watchReapplyHook(), allowing secondary layers to restore UI state.
Overlay Persistence
The src/officecli/Resources/watch-overlay.js script manages transient UI elements like text selections, highlights, and rubber-band boxes. It registers itself as the reapply hook via window._watchReapplyHook = reapplyDecorations.
The reapplyDecorations() function executes two primary operations after each DOM mutation:
applySelectionToDom(): Re-applies CSS classes likeofficecli-selectedand positions an absolutely-positioned overlay (officecli-sel-overlay) to highlight the current selectionapplyMarks(): Walks the stored_marksarray to inject<span class="officecli-mark">wrappers around matched text and adds block-level outlines for shape-based marks
This hook system ensures that user selections and annotations persist even as the underlying document structure changes dramatically.
The Real-Time Update Flow
The complete update cycle follows this precise sequence:
- CLI detects change and re-renders the affected document portion
WatchNotifier.Notify()sends a JSON payload via TCP to the running server- Server broadcasts the message through the SSE
/eventsstream to all browsers watch-sse-core.jsreceives the message and identifies the action type- DOM mutation occurs using methods like
el.parentNode.replaceChild(newEl, el)orinnerHTMLreplacement _executeScripts()re-runs any<script>elements within injected HTML to maintain interactivity_callReapplyHook()triggers the overlay layer's reapplication routine- Selection and marks are redrawn on the new DOM elements
- Thumbnail sync and scroll position updates complete the visual refresh
Message Types and DOM Mutations
The SSE payload is a JSON object containing an action field and supporting data. Here is how the client handles specific update types:
// Handling slide replacement in watch-sse-core.js
if (msg.action === 'replace') {
var el = document.querySelector('.slide-container[data-slide="' + slideNum + '"]');
if (el) {
var tmp = document.createElement('div');
tmp.innerHTML = msg.html;
var newEl = tmp.firstElementChild;
el.parentNode.replaceChild(newEl, el);
_executeScripts(newEl); // Re-run embedded scripts
if (typeof scaleSlides === 'function') scaleSlides();
syncThumbs(); // Update thumbnail strip
scrollToSlide(slideNum);
}
_callReapplyHook(); // Preserve UI decorations
}
For Word documents, the script tracks a client-side _clientVersion to handle out-of-order messages. If a word-patch arrives with a baseVersion mismatch, the system falls back to a full diff update (wordDiffUpdate) to guarantee consistency.
Preserving UI State Across Reloads
The overlay system uses a registration pattern to maintain state:
// From watch-overlay.js
function reapplyDecorations() {
applySelectionToDom(); // Re-draw selection overlay
applyMarks(); // Re-inject mark spans
}
window._watchReapplyHook = reapplyDecorations;
The overlay also listens for dedicated selection-update and mark-update SSE events sent independently of document mutations. This allows the server to push selection changes (such as when the CLI executes a goto command) without triggering full DOM rebuilds.
Starting a Watch Session
Launch the real-time preview from your terminal:
# Watch a Word document and open browser preview
officecli watch examples/word/tables.docx
The CLI outputs the local server address:
Watching file ... (preview at http://127.0.0.1:51234)
Opening this URL loads the preview page with embedded watch-sse-core.js and watch-overlay.js resources, immediately establishing the SSE connection for live updates.
Summary
- OfficeCLI watch mode streams updates via Server-Sent Events from a local HTTP server (
WatchServer.cs) to your browser - Two-layer architecture separates structural DOM mutations (
watch-sse-core.js) from UI decoration management (watch-overlay.js) - Hook-based synchronization ensures selections and marks persist through aggressive DOM replacements via
window._watchReapplyHook - Incremental patching supports slide-level updates, Word diff patches, and Excel cell updates without full page reloads
- Version tracking in Word documents prevents state drift when messages arrive out of sequence
Frequently Asked Questions
What protocol does OfficeCLI use for real-time browser updates?
OfficeCLI uses Server-Sent Events (SSE) via the /events endpoint, not WebSockets. This unidirectional HTTP-based stream allows the server (WatchServer.cs) to push JSON update messages to the browser as changes occur, with automatic reconnection handling provided by the browser's native EventSource API.
How does the preview maintain text selections after document updates?
The system employs a reapply hook pattern. The watch-overlay.js script registers a reapplyDecorations function as window._watchReapplyHook. After every DOM mutation performed by watch-sse-core.js, this hook executes to redraw selection overlays (officecli-selected classes) and reinject mark spans, ensuring UI state persists even when the underlying HTML is completely replaced.
Which file types support incremental updates versus full reloads?
PowerPoint presentations use incremental updates (replace, add, remove actions) on individual slide containers. Word documents support block-level word-patch updates for efficient text changes, with automatic fallback to full body replacement if version mismatches occur. Excel files receive excel-patch updates for specific rows or style changes. Simple or unsupported formats may trigger the full action, replacing the entire document body.
How does the CLI process communicate with the browser preview server?
The CLI uses TCP inter-process communication via WatchNotifier.cs. When a document change occurs, the CLI opens a TCP client connection to the running WatchServer instance, writes the JSON notification payload, and closes the connection. The server then broadcasts this message to all connected browser clients through the SSE stream, maintaining synchronization between the command-line tool and the preview window.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →