Skip to main content

Grid System

The Grid System is how Monolex gets pre-processed data from Rust to your screen instantly.
┌─────────────────────────────────────────────────────────────────────────────────┐
│  THE CORE IDEA                                                                  │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   Standard Terminal:                                                            │
│   ──────────────────                                                            │
│                                                                                 │
│   ┌──────────┐      ┌──────────┐      ┌──────────┐      ┌──────────┐            │
│   │  Raw     │  →   │  Parse   │  →   │  Parse   │  →   │  Render  │            │
│   │  Output  │      │  in JS   │      │  Again!  │      │  to GPU  │            │
│   └──────────┘      └──────────┘      └──────────┘      └──────────┘            │
│                     ❌ Slow           ❌ Redundant                              │
│                                                                                 │
│                                                                                 │
│   Monolex Grid System:                                                          │
│   ────────────────────                                                          │
│                                                                                 │
│   ┌──────────┐      ┌──────────┐      ┌──────────┐      ┌──────────┐            │
│   │  Raw     │  →   │  Parse   │  →   │  Direct  │  →   │  Render  │            │
│   │  Output  │      │  in Rust │      │  Inject  │      │  to GPU  │            │
│   └──────────┘      └──────────┘      └──────────┘      └──────────┘            │
│                     ✅ Fast           ✅ No double                              │
│                     (Alacritty)          parsing                                │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

How It Works

┌─────────────────────────────────────────────────────────────────────────────────┐
│  GRID SYSTEM FLOW                                                               │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│                                                                                 │
│   ┌───────────────────────────────────────────────────────────────────────┐     │
│   │                        PTY DAEMON (Rust)                              │     │
│   │                                                                       │     │
│   │   Program Output                                                      │     │
│   │        │                                                              │     │
│   │        ▼                                                              │     │
│   │   ┌─────────────────────────────────────────────────────────────┐     │     │
│   │   │  Alacritty VTE Parser                                       │     │     │
│   │   │                                                             │     │     │
│   │   │  • Interprets escape sequences                              │     │     │
│   │   │  • Calculates colors, styles, positions                     │     │     │
│   │   │  • Handles Unicode and wide characters                      │     │     │
│   │   │                                                             │     │     │
│   │   └────────────────────────────┬────────────────────────────────┘     │     │
│   │                                │                                      │     │
│   │                                ▼                                      │     │
│   │   ┌─────────────────────────────────────────────────────────────┐     │     │
│   │   │  Grid Update (Pre-processed Cells)                          │     │     │
│   │   │                                                             │     │     │
│   │   │  ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐              │     │     │
│   │   │  │ H │ e │ l │ l │ o │   │ W │ o │ r │ l │ d │ ...          │     │     │
│   │   │  └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘              │     │     │
│   │   │  Each cell: character + foreground + background + flags     │     │     │
│   │   │                                                             │     │     │
│   │   └────────────────────────────┬────────────────────────────────┘     │     │
│   │                                │                                      │     │
│   └────────────────────────────────│──────────────────────────────────────┘     │
│                                    │                                            │
│                                    │  Tauri emit()                              │
│                                    ▼                                            │
│   ┌───────────────────────────────────────────────────────────────────────┐     │
│   │                        FRONTEND (TypeScript)                          │     │
│   │                                                                       │     │
│   │   ┌─────────────────────────────────────────────────────────────┐     │     │
│   │   │  Grid Buffer Injector                                       │     │     │
│   │   │                                                             │     │     │
│   │   │  • Receives pre-processed cells                             │     │     │
│   │   │  • Writes directly to xterm.js memory                       │     │     │
│   │   │  • NO JavaScript parsing needed!                            │     │     │
│   │   │                                                             │     │     │
│   │   └────────────────────────────┬────────────────────────────────┘     │     │
│   │                                │                                      │     │
│   │                                ▼                                      │     │
│   │   ┌─────────────────────────────────────────────────────────────┐     │     │
│   │   │  xterm.js WebGL Renderer                                    │     │     │
│   │   │                                                             │     │     │
│   │   │  • GPU-accelerated rendering                                │     │     │
│   │   │  • Renders the frame you see                                │     │     │
│   │   │                                                             │     │     │
│   │   └─────────────────────────────────────────────────────────────┘     │     │
│   │                                                                       │     │
│   └────────────────────────────────────────────────────────────────────────┘    │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘
Why Alacritty? Alacritty is one of the fastest terminal VTE parsers, written in Rust. Monolex uses its parsing engine for maximum speed.

Standard vs Grid: The Difference

┌─────────────────────────────────────────────────────────────────────────────────┐
│  STANDARD TERMINAL (Double Parsing Problem)                                     │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   Program sends: "\x1b[31mHello\x1b[0m"  (red "Hello")                          │
│                                                                                 │
│   ┌────────────┐                                                                │
│   │  Backend   │  → Might parse for logging                                     │
│   └─────┬──────┘                                                                │
│         │                                                                       │
│         │  Raw text sent to frontend                                            │
│         ▼                                                                       │
│   ┌────────────┐                                                                │
│   │  Frontend  │  → Parses AGAIN (slow JavaScript)                              │
│   │  (xterm)   │    • What color is this?                                       │
│   │            │    • What position?                                            │
│   │            │    • What attributes?                                          │
│   └────────────┘                                                                │
│                                                                                 │
│   ❌ Same work done TWICE                                                       │
│   ❌ JavaScript parsing is slow                                                 │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────────┐
│  MONOLEX GRID SYSTEM (Parse Once)                                               │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   Program sends: "\x1b[31mHello\x1b[0m"  (red "Hello")                          │
│                                                                                 │
│   ┌────────────┐                                                                │
│   │  Backend   │  → Alacritty parses (fast Rust)                                │
│   │  (Rust)    │    Result: [H:red][e:red][l:red][l:red][o:red]                 │
│   └─────┬──────┘                                                                │
│         │                                                                       │
│         │  Pre-processed cells sent                                             │
│         ▼                                                                       │
│   ┌────────────┐                                                                │
│   │  Frontend  │  → Just inject! No parsing needed.                             │
│   │  (xterm)   │    Cells go directly to memory.                                │
│   └────────────┘                                                                │
│                                                                                 │
│   ✅ Parsing happens ONCE (in fast Rust)                                        │
│   ✅ Frontend just receives ready-to-display data                               │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Smart Updates

Not every update needs to refresh the whole screen.
┌─────────────────────────────────────────────────────────────────────────────────┐
│  SMART DIFF: ONLY UPDATE WHAT CHANGED                                           │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│                                                                                 │
│   FULL UPDATE (when needed)           PARTIAL UPDATE (most common)              │
│   ────────────────────────           ──────────────────────────────             │
│                                                                                 │
│   ┌─────────────────────┐           ┌─────────────────────┐                     │
│   │▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│           │                     │                     │
│   │▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│           │                     │                     │
│   │▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│           │▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│ ← Only this line    │
│   │▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│           │                     │    changed!         │
│   │▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│           │                     │                     │
│   └─────────────────────┘           └─────────────────────┘                     │
│                                                                                 │
│   Update 4,800 cells                 Update ~120 cells                          │
│   (120 cols × 40 rows)               (just 1 row)                               │
│                                                                                 │
│                                                                                 │
│   ════════════════════════════════════════════════════════════════════════════  │
│                                                                                 │
│   When typing at a prompt:                                                      │
│                                                                                 │
│   ┌─────────────────────────────────────────────────────────────────────┐       │
│   │  $                                                                  │       │
│   └─────────────────────────────────────────────────────────────────────┘       │
│                              ↓ You type 'l'                                     │
│   ┌─────────────────────────────────────────────────────────────────────┐       │
│   │  $ l                                                                │       │
│   └─────────────────────────────────────────────────────────────────────┘       │
│                                                                                 │
│   Only ONE character changed → Only ONE cell updated!                           │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘
DiffHint tells the frontend exactly which lines changed. The frontend only updates those specific lines, saving significant processing time.

Flow Control: ACK System

┌─────────────────────────────────────────────────────────────────────────────────┐
│  ACK FLOW CONTROL                                                               │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   Problem: What if backend sends faster than frontend can display?              │
│   ─────────────────────────────────────────────────────────────────             │
│                                                                                 │
│   Without flow control:                                                         │
│                                                                                 │
│   Backend:  [update1] [update2] [update3] [update4] [update5] ...               │
│                  │         │         │         │         │                      │
│                  └─────────┴─────────┴─────────┴─────────┘                      │
│                                    │                                            │
│                           Frontend overwhelmed! 💥                              │
│                           Memory fills up, lag increases                        │
│                                                                                 │
│                                                                                 │
│   With ACK flow control:                                                        │
│   ─────────────────────────                                                     │
│                                                                                 │
│   ┌──────────┐                              ┌──────────┐                        │
│   │  Backend │                              │ Frontend │                        │
│   └────┬─────┘                              └────┬─────┘                        │
│        │                                         │                              │
│        │ ───────── update1 ─────────────────▶   │                               │
│        │                                         │ Processing...                │
│        │ (waits)                                 │                              │
│        │                                         │                              │
│        │ ◀──────── ACK ─────────────────────    │ Done!                         │
│        │                                         │                              │
│        │ ───────── update2 ─────────────────▶   │                               │
│        │                                         │ Processing...                │
│        │ (waits)                                 │                              │
│        │                                         │                              │
│        │ ◀──────── ACK ─────────────────────    │ Done!                         │
│        │                                         │                              │
│                                                                                 │
│   Backend only sends next update when frontend is ready.                        │
│   No memory overflow. Smooth frames. Happy users.                               │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Epoch: Handling Resize

What happens when you resize the terminal window?
┌─────────────────────────────────────────────────────────────────────────────────┐
│  EPOCH SYSTEM: SAFE RESIZE                                                      │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   The Problem:                                                                  │
│   ────────────                                                                  │
│                                                                                 │
│   You resize: 120×40 → 150×50                                                   │
│                                                                                 │
│   ┌──────────────────────────────────────────────────────────────────┐          │
│   │                                                                  │          │
│   │   Old updates (120×40) still traveling to frontend...            │          │
│   │                                                                  │          │
│   │   Update (120×40) ────▶                                          │          │
│   │   Update (120×40) ────▶         ← These are now WRONG!           │          │
│   │   Update (150×50) ────▶         ← This is correct                │          │
│   │                                                                  │          │
│   │   If we inject old updates into new buffer = CHAOS!              │          │
│   │                                                                  │          │
│   └──────────────────────────────────────────────────────────────────┘          │
│                                                                                 │
│                                                                                 │
│   The Solution: Epoch Counter                                                   │
│   ───────────────────────────                                                   │
│                                                                                 │
│   ┌──────────────────────────────────────────────────────────────────┐          │
│   │                                                                  │          │
│   │   Each resize increments the epoch:                              │          │
│   │                                                                  │          │
│   │   Epoch 1: Terminal is 120×40                                    │          │
│   │      ↓ (resize happens)                                          │          │
│   │   Epoch 2: Terminal is 150×50                                    │          │
│   │                                                                  │          │
│   │   Update arrives with Epoch 1?                                   │          │
│   │      → DISCARD! It's from the old size.                          │          │
│   │                                                                  │          │
│   │   Update arrives with Epoch 2?                                   │          │
│   │      → ACCEPT! It matches current size.                          │          │
│   │                                                                  │          │
│   └──────────────────────────────────────────────────────────────────┘          │
│                                                                                 │
│   Result: No corruption during resize. Smooth transition.                       │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

The Cell Format

Each character on screen is represented as a cell.
┌─────────────────────────────────────────────────────────────────────────────────┐
│  CELL STRUCTURE                                                                 │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   What you see:  A                                                              │
│                                                                                 │
│   What's stored:                                                                │
│   ┌──────────────────────────────────────────────────────────────────┐          │
│   │                                                                  │          │
│   │   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │          │
│   │   │  Character  │  │  Foreground │  │  Background │              │          │
│   │   │             │  │             │  │             │              │          │
│   │   │    'A'      │  │   White     │  │   Black     │              │          │
│   │   │  + width    │  │  + bold     │  │             │              │          │
│   │   │             │  │  + italic   │  │             │              │          │
│   │   │             │  │  + underline│  │             │              │          │
│   │   │             │  │             │  │             │              │          │
│   │   └─────────────┘  └─────────────┘  └─────────────┘              │          │
│   │        Slot 1          Slot 2          Slot 3                    │          │
│   │                                                                  │          │
│   └──────────────────────────────────────────────────────────────────┘          │
│                                                                                 │
│   A terminal with 120 columns × 40 rows = 4,800 cells                           │
│   Each cell = 3 slots                                                           │
│   Total: 14,400 values to represent one screen                                  │
│                                                                                 │
│   Grid System processes these at native Rust speed,                             │
│   then injects them directly into xterm.js WebGL buffer.                        │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Summary

╔═══════════════════════════════════════════════════════════════════════════════╗
║  GRID SYSTEM SUMMARY                                                          ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║                                                                               ║
║   WHAT IT DOES:                                                               ║
║   ─────────────                                                               ║
║   Delivers pre-processed terminal cells directly from Rust to your screen.    ║
║                                                                               ║
║                                                                               ║
║   KEY BENEFITS:                                                               ║
║   ─────────────                                                               ║
║                                                                               ║
║   ┌────────────────────┐  ┌────────────────────┐  ┌────────────────────┐      ║
║   │  Parse Once        │  │  Smart Updates     │  │  Flow Control      │      ║
║   │  ─────────────     │  │  ─────────────     │  │  ─────────────     │      ║
║   │  Rust parses,      │  │  Only changed      │  │  ACK prevents      │      ║
║   │  JS doesn't.       │  │  lines update.     │  │  overflow.         │      ║
║   └────────────────────┘  └────────────────────┘  └────────────────────┘      ║
║                                                                               ║
║   ┌────────────────────┐  ┌────────────────────┐                              ║
║   │  Safe Resize       │  │  GPU Rendering     │                              ║
║   │  ─────────────     │  │  ─────────────     │                              ║
║   │  Epoch system      │  │  WebGL takes       │                              ║
║   │  handles it.       │  │  it from here.     │                              ║
║   └────────────────────┘  └────────────────────┘                              ║
║                                                                               ║
║                                                                               ║
║   THE RESULT:                                                                 ║
║   ───────────                                                                 ║
║   Faster rendering, smoother scrolling, responsive typing.                    ║
║                                                                               ║
╚═══════════════════════════════════════════════════════════════════════════════╝

Next Steps