#+TITLE: NATS Message Protocol Documentation #+AUTHOR: Mizuki Editor #+DATE: 2025-07-07 * Overview This document describes the NATS message protocol used by the Mizuki editor for communication between the terminal client and file manipulation service. * Explanation of concepts. ** FileWindow A file window is a area of the text that is currently viewed, as well as an anchor. The anchor decides if the window will move or not. ####### window ####### # 2 3 # #1 *4 # # # # 5 # ###################### In this illustration, we se the anchor * and 5 possible insert points for text. Note that the anchor point is not centered in the window. It is the point where the user in interested in anchoring the window at the moment. The anchor point is usually where the cursor are. In this example inserting a letter at point 1 will move the anchor point to the right, this means that the window will also move to the right. Insertion of a letter at point 2 or tree might just change the line length of the above line. While inserting a new line at those points, would move the anchor down. Insertions on point 4 or 5 are both after the anchor and would not affect the window at all. Note that normally the line of the anchor would be locked from editing by anyone but the owner of the anchor. * Message Types ** Base Message Structure All messages inherit from a base =Message= class and use JSON format for serialization. *** Common Response Format #+BEGIN_SRC json { "status": "success" | "error", "message": "optional message text" } #+END_SRC ** File Operation Messages All file operation messages inherit from =FileMessage= and include a =path= field. *** OpenFileWindowRequest / Message Opens a window on a file, allowing the client to receive updates specific to this view. **** Request Format #+BEGIN_SRC json { "path": "/path/to/file", "window" : [0,0,200,80], "anchor": [0, 0], "subscriber": "client_id", "view_id": "unique_view_id" } #+END_SRC | Field | Description | |------------+------------------------------------------------------------| | path | Project relative file path to open | | window | X, Y, Width, Height of view window | | anchor | Cursor/focus position `[row, col]` that the window follows | | subscriber | Unique client ID (used in NATS subject routing) | | view_id | Unique ID for this view of the file (per client view/pane) | **** Response Format #+BEGIN_SRC json { "status": "success", "message": "File window opened", "window" : [0,0,200,80], "anchor": [0, 0], "path": "/path/to/file", "view_id": "unique_view_id", "content": "window content as string", "window_line_lengths": [45, 67, 23], "total_lines": 1000 } #+END_SRC | Field | Description | |--------------+---------------------------------------------| | status | `"success"` or `"error"` | | message | Informational message | | path | Echo of requested file path | | window | Echo of view window | | anchor | Echo of anchor | | view_id | Echo of view ID | | content | Full content of window region (as a string) | | line_lengths | List of line lengths in the visible window | | max_lines | Total number of lines in the file | *** WindowUpdateMessage Message sent from the server to the client when file content visible in a window changes. Intended to reflect insertions, deletions, full refreshes, and metadata changes affecting a specific file view. **** Subject : `file.window.update` **** Payload Format #+BEGIN_SRC json { "path": "/path/to/file", "view_id": "unique-id-for-this-view", "content": "updated content (if full update or affected region)", "start": [line, column], "end": [line, column], "inserted": true, "deleted": false, "line_lengths": [45, 67, 23], "max_lines": 1000, "reason": "full" // optional: e.g., "insert", "delete", "replace", "full", "metadata", "lengths" } #+END_SRC **** Fields - `path`: Absolute file path for which the update is relevant. - `view_id`: UUID assigned when the window was opened; identifies the specific view within the client. - `content`: Text that was inserted/replaced (optional, depending on `reason`). - `start`: Tuple `[line, column]` indicating the start of the affected region. - `end`: Tuple `[line, column]` indicating the end of the affected region. - `inserted`: Boolean indicating whether this update involved inserted text. - `deleted`: Boolean indicating whether this update involved deleted text. - `line_lengths`: Updated line lengths visible in the window. - `max_lines`: Updated total line count in the file. - `reason`: Optional string enum: `"insert"`, `"delete"`, `"replace"`, `"full"`, or `"metadata"` to indicate why this update was triggered. **** Notes - The `view_id` allows the client to distinguish between multiple panes viewing the same file. - Only updates visible in the current window are included. - Additional fields may be added later to support user activity, cursor sync, or collaboration metadata. *** OldWindowUpdateMessage Sent from server to client to update the state of a specific file view. **** NATS Subject Format :mizuki.file.window-update.. **** Payload Format #+BEGIN_SRC json { "type": "window_update", "path": "/path/to/file", "view_id": "unique_view_id", "anchor": [row, col], "window_position": [top_row, left_col], "height": 80, "width": 200, "content": "updated content (optional)", "line_lengths": [45, 67, 23], "max_lines": 1000, "changes": { "insert": [ {"position": 1023, "text": "inserted text"} ], "delete": [ {"position": 1050, "length": 3} ] }, "flags": { "is_full_update": false, "lines_changed": true, "size_changed": false }, "users": [ {"id": "clientB", "anchor": [12, 8]} ] } #+END_SRC | Field | Description | |-------------------+-------------------------------------------------------------------| | type | Always `"window_update"` | | path | Path of the file (informational) | | view_id | The view this update belongs to | | anchor | Cursor/focus after applying the update | | window_position | `[top_row, left_col]` offset of the window | | height / width | Size of the window | | content | (Optional) full replacement text for the window | | line_lengths | Updated line lengths in visible region | | max_lines | Total number of lines in the file | | changes.insert | List of `{position, text}` insertions | | changes.delete | List of `{position, length}` deletions | | flags | Booleans: is_full_update, lines_changed, size_changed | | users | (Optional) list of other users viewing this file (ID + anchor) | *** AddCharRequest/Message Adds a character at a specific position in a file. **** Request Format #+BEGIN_SRC json { "path": "/path/to/file", "position": 123, "char": "a" } #+END_SRC **** Response Format #+BEGIN_SRC json { "status": "success", "message": "Character added", "path": "/path/to/file", "position": 123, "char": "a" } #+END_SRC *** DeleteCharsRequest/Message Deletes one or more characters starting from a specific position. **** Request Format #+BEGIN_SRC json { "path": "/path/to/file", "position": 123, "count": 1 } #+END_SRC **** Response Format #+BEGIN_SRC json { "status": "success", "message": "Characters deleted", "path": "/path/to/file", "position": 123, "count": 1 } #+END_SRC *** SaveFileRequest/Message Saves a file to disk. **** Request Format #+BEGIN_SRC json { "path": "/path/to/file" } #+END_SRC **** Response Format #+BEGIN_SRC json { "status": "success", "message": "File saved" } #+END_SRC ** System Messages *** ShutdownMessage Signals the system to shut down gracefully. **** Request Format #+BEGIN_SRC json { "type": "shutdown" } #+END_SRC *** ProjectTreeRequest/Response Requests the project file tree structure. **** Request Format #+BEGIN_SRC json { "type": "project_tree" } #+END_SRC **** Response Format #+BEGIN_SRC json { "status": "success", "tree": { "name": "project_root", "type": "directory", "children": [ { "name": "file.txt", "type": "file", "path": "/full/path/to/file.txt" } ] } } #+END_SRC ** Notification Messages *** FileChangeNotification Notifies subscribers of changes to a file. **** Format #+BEGIN_SRC json { "type": "file-change", "path": "/path/to/file", "position": 123, "change": "inserted text or deletion info" } #+END_SRC *** WindowPositionNotification Notifies subscribers of window position changes. **** Format #+BEGIN_SRC json { "type": "window-position", "path": "/path/to/file", "window_position": [10, 5], "anchor": [0, 0], "height": 80, "width": 200, "subscriber": "client_id" } #+END_SRC *** UnifiedUpdateNotification Provides a unified update containing window position, content, and change information. **** Format #+BEGIN_SRC json { "type": "unified-update", "path": "/path/to/file", "subscriber": "client_id", "window_position": [10, 5], "anchor": [0, 0], "height": 80, "width": 200, "content": "file content as string", "line_lengths": [45, 67, 23], "max_lines": 1000, "change": { "position": 123, "type": "insert", "data": "inserted text" } } #+END_SRC * Message Flow 1. Client sends request message to appropriate NATS subject 2. File manipulator service processes the request 3. Service sends response message back to client 4. For file changes, service may also send notifications to other subscribers * NATS Subjects - =file.open= - Open file window requests - =file.add_char= - Add character requests - =file.delete_chars= - Delete characters requests - =file.save= - Save file requests - =file.update_window= - Update window requests - =project.tree= - Project tree requests - =system.shutdown= - Shutdown requests - =file.changes.{path}= - File change notifications (per file) * Error Handling All operations can return error responses with the following format: #+BEGIN_SRC json { "status": "error", "message": "Description of the error" } #+END_SRC Common error scenarios: - File not found - Permission denied - Invalid message format - Service unavailable