Engineering Journal
Table Formatter
Table Formatter

Three Modes, One Table: How TAFNE's P2P Architecture Works

2026-05-30

TLDR

Switching between separate applications for editing, quality control, and data pipeline joining causes context loss and version drift. Connecting specialized modes (Table, Node Editor, Lab Mode) through a shared, flat in-memory sheet store lets data flow between them without losing edit state.
Data Interaction ModeFocus AreaState Storage ModelContext-Switch Safety
Isolated Standalone ToolsFile exports/imports per stepSeparate file statesHigh risk of data loss
Shared P2P Sheet ArchitectureTable / Node / Lab ViewsUnified Central Sheet Store100% Context Preservation

Disconnected specialized tools force destructive file export loops and cause context loss

Data manipulation tasks typically require three distinct modes of interaction:

  1. Direct cell formatting and manual row editing.
  2. Visual graph execution for multi-source joins and automated formulas.
  3. Batch quality control for filtering, sanitization, and normalization.
Attempting to build these capabilities into a single monolithic UI yields a cluttered, inefficient interface. Conversely, using separate tools forces users to export and re-import files repeatedly, increasing the risk of data loss.


A unified in-memory sheet store connects isolated interaction modes without state drift

We implemented a Pipeline-to-Pipeline (P2P) architecture where Table, Node, and Lab modes share access to a single underlying sheet repository:

   DECOUPLED P2P ARCHITECTURE:
   
   [Table Editor Mode]         [Node Editor Mode]         [Lab Mode (QC)]
      (Manual Edits)           (Visual DAG Joins)         (Data Pipelines)
            │                          │                          │
            │          (Reads)         │       (Mutates)          │
            └──────────────────────────┼──────────────────────────┘
                                       ▼
                     ┌──────────────────────────────────┐
                     │       Shared Sheet Store         │
                     │  (Map: id -> { HTML Content })   │
                     └──────────────────────────────────┘

Here is the underlying store implementation:

// Centralized in-memory sheet store for P2P workflow modes
class SharedSheetStore {
  constructor() {
    this.sheets = new Map(); // sheetId -> { name, htmlContent, metadata }
  }

addSheet(id, name, htmlContent) { this.sheets.set(id, { name, htmlContent, updatedAt: Date.now() }); this.notifySubscribers(); }

getSheet(id) { return this.sheets.get(id); } }

export const globalSheetStore = new SharedSheetStore();

Any modification made in Lab Mode or output generated by the Node Editor registers as a clean sheet entry in SharedSheetStore, making datasets immediately available across all views.

Rule of thumb: Decouple specialized editing modes while backing them with a single shared data store to preserve context.
Read this post in the full Engineering Journal →