# How OfficeCLI Watch Mode Provides Real-Time Browser Preview Updates

> Discover how OfficeCLI's watch mode delivers real-time browser preview updates via SSE connections and targeted DOM mutations. Experience instant feedback for your development workflow.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: how-to-guide
- Published: 2026-07-08

---

**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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WatchServer.cs)) that serves the initial HTML preview and manages the `/events` SSE endpoint
- **Core DOM Layer**: The [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) script that parses incoming messages and executes surgical DOM mutations
- **Overlay Layer**: The [`watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-overlay.js) script 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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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 types
- **`replace`**, **`add`**, **`remove`**: Target specific slide containers using `.slide-container[data-slide]` selectors
- **`word-patch`**: Applies block-level diff patches to Word documents using `<wb>` and `<we>` markers
- **`excel-patch`**: Updates table rows or swaps style sheets for Excel workbooks
- **`scroll`**: 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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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:

1. **`applySelectionToDom()`**: Re-applies CSS classes like `officecli-selected` and positions an absolutely-positioned overlay (`officecli-sel-overlay`) to highlight the current selection
2. **`applyMarks()`**: Walks the stored `_marks` array 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:

1. **CLI detects change** and re-renders the affected document portion
2. **`WatchNotifier.Notify()`** sends a JSON payload via TCP to the running server
3. **Server broadcasts** the message through the SSE `/events` stream to all browsers
4. **[`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js)** receives the message and identifies the action type
5. **DOM mutation** occurs using methods like `el.parentNode.replaceChild(newEl, el)` or `innerHTML` replacement
6. **`_executeScripts()`** re-runs any `<script>` elements within injected HTML to maintain interactivity
7. **`_callReapplyHook()`** triggers the overlay layer's reapplication routine
8. **Selection and marks** are redrawn on the new DOM elements
9. **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:

```javascript
// 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:

```javascript
// 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:

```bash

# Watch a Word document and open browser preview

officecli watch examples/word/tables.docx

```

The CLI outputs the local server address:

```text
Watching file ... (preview at http://127.0.0.1:51234)

```

Opening this URL loads the preview page with embedded [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) and [`watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WatchServer.cs)) to your browser
- **Two-layer architecture** separates structural DOM mutations ([`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js)) from UI decoration management ([`watch-overlay.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-overlay.js) script registers a `reapplyDecorations` function as `window._watchReapplyHook`. After every DOM mutation performed by [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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`](https://github.com/iOfficeAI/OfficeCLI/blob/main/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.