Skip to content

State Boundaries

The biggest architectural shift in the rewrite is the strict separation of concerns. We must define who owns what to prevent scope creep between the frontend and backend.

Canonical State (Nim)

Nim acts as the absolute truth and persistent file system manager.

  • Statelessness in RAM: Nim does not keep a persistent, redundant copy of the document in its RAM. It is completely stateless in memory.
  • The Pass-Through Pipe: The disk_io.nim file acts purely as a pass-through pipe. When C# hits an autosave/sync boundary, it sends the payload to Nim. Nim loads this data onto the heap for just a few milliseconds to write the temp file and move it to the target file. The exact microsecond that function finishes, Nim's ARC (Automatic Reference Counting) instantly frees the memory.
  • Gatekeeper: The C# UI never touches the disk. Nim natively integrates libgit2 and handles all background saves. Formal version numbers (e.g. v2.8.12) are implemented via git tags, and autosaves create frequent Git snapshots.
  • The Wrapper: Since Nim doesn't store document text in RAM, its "statefulness" refers to acting as the Mastermind and Wrapper of the application. It manages the lifecycle of the session and holds the repository state, tracking libgit2 pointers and active branches.

Ephemeral State (C#)

C# acts as the "glass" renderer and transient state manager.

  • Local Memory Buffer: It holds the active text buffer in its own RAM to ensure typing has zero latency.
  • Transient Tracking: It natively tracks the active caret index, scroll position, and UI themes. It does not know about the file system, Git, or how data is persisted.

Process Lifecycle

At the OS level, Nim executes the compiled C# binary as a distinct child process.

  • Anonymous Pipes: When Nim spawns the C# process, it binds OS-level anonymous pipes directly to the C# process's stdin and stdout.
  • Execution Context: They run as completely separate OS processes handled by the OS scheduler. Avalonia manages its internal UI threading loop in the C# process, while Nim manages its IPC and I/O threads.
  • Routing In/Out: Nim's dispatcher thread blocks, listening to the pipe attached to C#'s stdout. To send data back, Nim's output worker writes to the pipe attached to C#'s stdin.
  • Lifecycle Termination: When the user closes the C# window, the C# process terminates. The OS closes the pipes, and Nim receives an EOF (End of File) signal. That EOF breaks the loop in Nim, signaling that the renderer is gone, allowing Nim to execute its final teardown and exit.