How Atomic State Works
A step-by-step visual guide to MonoTerm’s frame validation and delivery system.The Complete Picture
Copy
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ MONOTERM TERMINAL SYSTEM │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ YOUR APP MONOTERM ENGINE YOUR SCREEN│ │
│ │ │ │
│ │ ┌───────────┐ ┌───────────────┐ ┌────────────┐│ │
│ │ │ │ │ │ │ ││ │
│ │ │ vim │ │ ┌─────────┐ │ │ ┌─────────┐││ │
│ │ │ htop │────────→│ │ ATOMIC │ │───────→│ │ PERFECT │││ │
│ │ │ npm │ bytes │ │ STATE │ │ frames │ │ IMAGE │││ │
│ │ │ git │ │ └─────────┘ │ │ └─────────┘││ │
│ │ │ │ │ │ │ ││ │
│ │ └───────────┘ └───────────────┘ └────────────┘│ │
│ │ │ │
│ │ Generates Processes & Displays │ │
│ │ output validates result │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────┘
Step-by-Step Flow
Step 1: Your Program Runs
Copy
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ STEP 1: Your program generates output │
│ │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ $ npm install │ │
│ │ │ │
│ │ npm wants to show: │ │
│ │ │ │
│ │ "Installing packages..." │ │
│ │ "[########............] 45%" │ │
│ │ │ │
│ │ This gets converted to ESCAPE CODES: │ │
│ │ │ │
│ │ ESC[32m = "start green color" │ │
│ │ ESC[0m = "reset color" │ │
│ │ ESC[2K = "clear line" │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ │
│ These codes control colors, cursor position, clearing, etc. │
│ │
└───────────────────────────────────────────────────────────────────────┘
Step 2: Bytes Travel Through PTY
Copy
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ STEP 2: Data travels through PTY (pseudo-terminal) │
│ │
│ │
│ npm MonoTerm │
│ ┌─────┐ ┌─────┐ │
│ │ │ │ │ │
│ │ N │════════════════════════════════│ M │ │
│ │ P │ PTY Pipe │ O │ │
│ │ M │ (like a water hose) │ N │ │
│ │ │ │ O │ │
│ └─────┘ └─────┘ │
│ │
│ │
│ The pipe can SPLIT data randomly: │
│ │
│ │
│ npm sends: "ESC[32mHelloESC[0m" │
│ │ │
│ ┌──────┴──────┐ │
│ │ THE PIPE │ │
│ └──────┬──────┘ │
│ │ │
│ MonoTerm gets: "ESC[32mHel" then "loESC[0m" │
│ │ │ │
│ chunk 1 chunk 2 │
│ │
│ │
│ This splitting is RANDOM and unpredictable! │
│ │
└───────────────────────────────────────────────────────────────────────┘
Step 3: Atomic State Collects and Validates
Copy
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ STEP 3: Atomic State collects and validates │
│ │
│ │
│ INCOMING CHUNKS ATOMIC STATE │
│ │
│ ┌─────────────────────┐ │
│ "ESC[32mHel" ───────────────→│ │ │
│ │ ┌─────────────┐ │ │
│ │ │ COLLECT │ │ │
│ │ │ │ │ │
│ │ │ "ESC[32m │ │ INCOMPLETE!
│ │ │ Hel..." │ │ Wait...
│ "loESC[0m" ────────────────→│ │ │ │ │
│ │ │ "ESC[32m │ │ │
│ │ │ Hello │ │ COMPLETE!
│ │ │ ESC[0m" │ │ Ready!
│ │ │ │ │ │
│ │ └──────┬──────┘ │ │
│ │ │ │ │
│ └──────────┼──────────┘ │
│ │ │
│ ▼ │
│ TO SCREEN │
│ │
│ │
│ The collector WAITS until it has a complete, valid frame │
│ │
└───────────────────────────────────────────────────────────────────────┘
Step 4: Smart Detection Patterns
Copy
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ STEP 4: Smart detection of update boundaries │
│ │
│ │
│ Atomic State recognizes THREE patterns that signal "batch updates": │
│ │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ PATTERN 1: BSU/ESU Markers (DECSET Mode 2026) │ │
│ │ ───────────────────────────────────────────── │ │
│ │ │ │
│ │ BSU ─────→ [content] ─────→ ESU │ │
│ │ │ │ │ │
│ │ "Start batch" "Batch complete" │ │
│ │ │ │
│ │ Programs can explicitly mark their updates │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ PATTERN 2: Screen Clear Detection │ │
│ │ ───────────────────────────────── │ │
│ │ │ │
│ │ CLEAR ─────→ [wait ~8ms] ─────→ new content │ │
│ │ │ │ │
│ │ "Screen will be redrawn" │ │
│ │ │ │
│ │ When screen clears, more content usually follows │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ PATTERN 3: Cursor Hide/Show │ │
│ │ ─────────────────────────── │ │
│ │ │ │
│ │ HIDE CURSOR ─────→ [content] ─────→ SHOW CURSOR │ │
│ │ │ │ │ │
│ │ "I'm about to redraw" "Done redrawing" │ │
│ │ │ │
│ │ vim, htop, etc. hide cursor while updating screen │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────┘
Step 5: Quality Gate
Copy
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ STEP 5: Quality gate - only complete frames pass │
│ │
│ │
│ THE GATE │
│ │
│ ┌─────────────┐ │
│ │ │ │
│ Incomplete ──────→│ X X X X │ │
│ frame │ BLOCKED │ │
│ │ │ │
│ ├─────────────┤ │
│ │ │ │
│ Complete ──────→│ OK OK OK │────────────→ TO SCREEN │
│ frame │ PASSED │ │
│ │ │ │
│ └─────────────┘ │
│ │
│ │
│ What gets BLOCKED: What PASSES: │
│ │
│ * Partial escape codes * Complete frames │
│ * Mid-update content * Validated content │
│ * Corrupted data * Consistent state │
│ │
│ │
└───────────────────────────────────────────────────────────────────────┘
Step 6: ACK Handshake
Copy
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ STEP 6: ACK handshake ensures smooth flow │
│ │
│ │
│ ATOMIC STATE SCREEN │
│ ┌────────────┐ ┌────────────┐ │
│ │ │ Frame 1 │ │ │
│ │ │──────────────────────→│ Display │ │
│ │ │ │ │ │
│ │ WAITING │←──────────────────────│ "OK!" │ │
│ │ ... │ "Got it!" (ACK) │ │ │
│ │ │ │ │ │
│ │ │ Frame 2 │ │ │
│ │ │──────────────────────→│ Display │ │
│ │ │ │ │ │
│ │ │←──────────────────────│ "OK!" │ │
│ │ │ ACK │ │ │
│ └────────────┘ └────────────┘ │
│ │
│ │
│ WHY ACK HANDSHAKE? │
│ │
│ Without handshake: │
│ │
│ Send ──→ Send ──→ Send ──→ Send ──→ Send │
│ │ │
│ Screen overwhelmed! │
│ Can't keep up! │
│ │
│ With handshake: │
│ │
│ Send ──→ Wait ──→ ACK ──→ Send ──→ Wait ──→ ACK │
│ │ │
│ Screen processes │
│ each frame smoothly │
│ │
└───────────────────────────────────────────────────────────────────────┘
The Complete Flow Animation
Copy
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ TIME ────────────────────────────────────────────────────────────→ │
│ │
│ │
│ T1: npm outputs "ESC[32mHel" │
│ ┌─────┐ ┌──────────┐ │
│ │ npm │ ══════════════════→│ COLLECT │ │
│ └─────┘ │ [Hel...] │ waiting... │
│ └──────────┘ │
│ │
│ T2: npm outputs "loESC[0m" │
│ ┌─────┐ ┌──────────┐ │
│ │ npm │ ══════════════════→│ COLLECT │ │
│ └─────┘ │ [Hello] │ complete! │
│ └────┬─────┘ │
│ │ │
│ T3: Send to screen │ │
│ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ VALIDATE │ ═══→│ SCREEN │ │
│ └──────────┘ │ Hello │ │
│ └──────────┘ │
│ T4: Screen says "got it!" │ │
│ ┌──────────┐ │ │
│ │ ATOMIC │←═════════╛ │
│ │ STATE │ ACK! │
│ └──────────┘ │
│ │
│ T5: Ready for next frame │
│ ┌──────────┐ │
│ │ WAITING │ ready for more... │
│ │ FOR DATA │ │
│ └──────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────┘
Epoch System: Preventing Stale Updates
Copy
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ HOW EPOCH PREVENTS DISPLAY PROBLEMS │
│ │
│ │
│ Every frame has a "version number" (epoch). │
│ Old frames are automatically rejected. │
│ │
│ │
│ When you resize the terminal window: │
│ │
│ ┌───────────────────┐ │
│ │ │ │
│ │ Terminal window │ USER RESIZES │
│ │ │ │
│ └───────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────┐ │
│ │ Epoch: 4 ──→ 5 │ "Version number" increases │
│ └───────────────────┘ │
│ │
│ │
│ Now, old updates (epoch=4) are REJECTED: │
│ │
│ Old update (epoch=4) ─────→ [X] REJECTED │
│ "Too old, ignore" │
│ │
│ New update (epoch=5) ─────→ [OK] ACCEPTED │
│ "This is current" │
│ │
│ │
│ This prevents: │
│ │
│ * Garbled display after resize │
│ * Wrong-sized content appearing │
│ * Race conditions between old and new data │
│ │
└───────────────────────────────────────────────────────────────────────┘
Summary: The Journey of a Character
Copy
┌───────────────────────────────────────────────────────────────────────┐
│ │
│ THE JOURNEY OF "Hello" TO YOUR SCREEN │
│ │
│ │
│ 1. BORN 2. TRAVEL 3. ARRIVE │
│ │
│ ┌─────────┐ ═══════════ ┌─────────┐ │
│ │ vim │ │ "Hel" │ │ COLLECT │ │
│ │ says │══════════════→│ ... │══════════════→│ waiting │ │
│ │ "Hello" │ │ "lo" │ │ ... │ │
│ └─────────┘ ═══════════ └─────────┘ │
│ split in │
│ pipe │
│ │
│ │
│ 4. REASSEMBLE 5. VALIDATE 6. DISPLAY │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ COLLECT │ │ CHECK │ │ SCREEN │ │
│ │ "Hello" │══════════════→│ OK! │══════════════→│ "Hello" │ │
│ │complete!│ │ VALID │ │ shown │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ │
│ 7. ACKNOWLEDGE │
│ │
│ ┌─────────────┐ │
│ │ SCREEN │ │
│ │ says │ │
│ │ "Got it!" │ │
│ │ │ │ │
│ │ READY FOR │ │
│ │ NEXT │ │
│ └─────────────┘ │
│ │
│ │
│ Result: "Hello" appears ONCE, COMPLETELY, CORRECTLY │
│ │
└───────────────────────────────────────────────────────────────────────┘
Technology
Built with Rust for memory safety, Alacritty VTE for parsing, MPSC channels for lock-free communication, and WebGL for GPU-accelerated rendering.