Files
MindSift/Doku/modules/workspace.md
T
2026-10-26 22:41:50 +01:00

6.6 KiB

📝 Kernmodul 3: Workspace Outliner-Engine, Wiki-Links & Pure-DB Storage

Der MindSift Workspace (WorkspaceView.tsx) kombiniert ein hierarchisches Bullet-Point Notizsystem (inspiriert von Logseq) mit einem persönlichen Wiki, Live-Kollaboration und einem globalen To-Do Rollup Dashboard.


🌳 1. Die Logseq-Outliner-Engine

Im Gegensatz zu klassischen Fließtext-Editoren basiert der MindSift Workspace auf einer flachen, relationalen Liste von Blöcken (blocks-Tabelle in SQLite). Jeder Block ist ein gedanklicher Knotenpunkt mit einer flexiblen Einrückungsebene (level: 0, 1, 2, ...) und einer fortlaufenden Fließkommaposition (position):

• Projekt MindSift v2.0 (level 0)
  • Architektur-Entscheidung (level 1)
    - [x] Database-First Blocks implementieren (level 2)
    - [ ] Performance Benchmark mit 10.000 Blöcken (level 2)
  • Notizen aus dem Dev-Meeting (level 1)
    > Wichtig: Keine verschachtelten SQLite Queries ausführen! (level 2)

Tastatur-Navigation & Shortcuts

  • Enter: Erstellt einen neuen Block auf derselben Hierarchieebene.
  • Tab: Rückt den aktuellen Block ein (wird Kindknoten des vorherigen Blocks).
  • Shift + Tab: Rückt den Block um eine Ebene aus (verringert die Tiefe).
  • Shift + Enter: Weicher Zeilenumbruch innerhalb desselben Blocks (z.B. für mehrzeilige Notizen oder Code).
  • Backspace (auf leerem Block): Löscht den Block sofort. Das Ausrücken erfolgt strikt und kontrolliert über Shift + Tab.
  • / (Slash-Commands): Öffnet das Umwandlungsmenü (/todo, /link, /h1, /h2, /h3, /code, /callout, /quote, /divider).
  • Markdown-Tastatur-Kürzel: Tippen von [] oder [ ] wandelt den Block sofort in ein Todo um; # , ## , ### erzeugt Überschriften.

Eingabestabilität & Zombie-Fokus-Schutz (OutlinerBlock.tsx)

  1. Echter Fokus-Check: Remote-Updates (block_updated) werden nur dann abgewehrt, wenn der Block tatsächlich aktiv im Betriebssystem editiert wird: isFocusedRef.current === true && document.hasFocus().
  2. Sofort-Flush bei Fensterwechsel: Sobald das Browser-Fenster den Fokus verliert (window.addEventListener('blur', ...)), wird ein offener 150ms-Debounce sofort gecancelt und der Text augenblicklich per WebSocket übertragen.
  3. Stale Closures eliminiert: Alle Callbacks werden in useRef gehalten, sodass asynchrone Debounce-Timer garantiert die aktuellste Komponenten-Referenz verwenden.

Zoom-In Hoisting (Fokus-Modus)

Klickt der Benutzer auf den Bullet-Dot (•) eines Blocks, blendet der Editor alle übergeordneten und benachbarten Blöcke aus und zoomt ausschließlich in diesen Ast hinein:

  • Der gewählte Punkt wird zur prominenten Überschrift im Fokus-Modus.
  • Eine klickbare Breadcrumb-Leiste oben zeigt den Pfad an (z.B. Workspace / Projekte / MindSift / Architektur).
  • Ein Klick auf ein beliebiges Breadcrumb-Element zoomt sofort auf die jeweilige Ebene zurück.

Drag & Drop von Blöcken

Der Bullet-Dot dient gleichzeitig als Drag-Anfasser. Wird ein Block verschoben, erkennt die Engine automatisch alle untergeordneten Kind-Blöcke (isDescendantBlock) und verschiebt den kompletten Unterbaum an die neue Zielposition.


  1. Interne Wiki-Links:
    • Text in doppelten eckigen Klammern (z.B. [[Reiseplanung 2026]]) wird automatisch als klickbare Notiz-Pille gerendert.
    • Klick darauf öffnet die verknüpfte Notiz direkt im Editor.
  2. Slash-Befehl /link & Link-Modal:
    • /link öffnet ein Modal mit zwei Modi:
      • Notiz verknüpfen: Durchsucht bestehende Notizen und fügt [[Titel]] ein.
      • Web-Link: Eingabe von Titel und URL, fügt Standard-Markdown [Titel](url) ein.
  3. Hashtags (#tag):
    • Hashtags im Fließtext werden automatisch indiziert (block_tags-Tabelle).
    • In der linken Leiste listet der Tag-Explorer alle verwendeten Schlagworte auf. Klick auf ein Tag filtert alle Dokumente und Blöcke, die dieses Tag enthalten.

⚡ 3. Echtzeit-Kollaboration & Automatische Markdown-Kompilierung

MindSift setzt auf eine latenzfreie In-Memory Kollaborations-Architektur (internal/ws/docroom.go):

Funktionsweise

  1. In-Memory DocRoom pro geöffnetem Dokument:
    • Hält den synchronen Zustand von title und blocks[] im RAM.
    • Granulare Mutations-Events (block_updated, block_created, block_deleted, block_moved, title_updated).
    • Ephemeres Presence-Tracking (cursor_moved, client_left) zeigt farbige Benutzer-Avatare im Header und Cursors am aktiven Block an.
  2. Echo-Schutz:
    • Jeder Client identifiziert sich mit einer eindeutigen clientId.
    • Der Server sendet Mutations-Events ausschließlich an andere Clients im selben Raum (clientId != senderClientId), um Cursor-Springen und Selbstechos zu verhindern.

Automatische Markdown-Kompilierung & SQLite Debounce-Flush

Eingabe im OutlinerBlock
        │
        ├──▶ WebSocket (block_updated Event)
        │         │
        │         ▼
        │    Go DocRoom: In-Memory Mutation & Broadcast an Peers
        │
        └──▶ 1.5s Inaktivitäts-Debounce (oder Raum-Exit)
                  │
                  ▼
             SQLite Transaktion:
             1. Persistiert Blöcke in `blocks`
             2. Regex-Extraktion von #tags in `block_tags`
             3. Kompiliert Block-Hierarchie zu Standard-Markdown
                und speichert Cache in `documents.markdown_cache`
  1. Kompiliertes Markdown: Jeder Block wird gemäß seiner level-Tiefe mit 2 Leerzeichen pro Einrückungsebene als sauberes Markdown formatiert (documents.markdown_cache).
  2. Pure Database Architecture: Alle Daten liegen transaktional und sicher in SQLite. Es werden keine unkontrollierten Dateien auf der Festplatte abgelegt; Notizen können jederzeit per Klick als .md-Datei exportiert werden.

📊 4. Globaler To-Do Rollup Dashboard

Über den Tab „Globale To-Dos" bietet der Workspace eine aggregierte Übersicht aller im gesamten Wiki verteilten Aufgaben:

  • Scannt in Echtzeit alle unvollendeten - [ ] Checkboxen über alle Ordner und Notizen hinweg.
  • Übersichtliche Gruppierung nach Ordner ➔ Dokument ➔ Aufgabe.
  • Ordner-Filter: Klick auf einen Ordner isoliert nur dessen Aufgaben für fokussiertes Arbeiten.
  • 2-Wege-Live-Sync: Wird eine Checkbox im Rollup abgehakt, wird der Block in SQLite sofort auf checked = 1 aktualisiert und via WebSocket an alle aktiven Clients gebroadcastet.