Come funziona EntityFlow
EntityFlow è costruito attorno a un piccolo insieme di decisioni architetturali che mantengono il suo comportamento deterministico, testabile e identico tra l'applicazione web, il server e la build desktop.
Separazione core/shell
Tutta la logica deterministica risiede in pacchetti TypeScript headless e indipendenti da qualsiasi framework. L'applicazione React, il server Node e l'applicazione Electron sono shell sottili che li consumano: non contengono alcuna logica di business propria.
I pacchetti headless coprono:
- l'IR dello schema (rappresentazione intermedia),
- il modello di documento CRDT,
- la geometria e l'instradamento degli archi,
- la generazione di codice SQL/DBML su quattro dialetti,
- la validazione,
- la proiezione (modello di lettura),
- il renderer della tela,
- l'autorizzazione.
Poiché la logica è condivisa, ciò che vedi nel browser, ciò che il server esporta e ciò che l'applicazione desktop produce provengono tutti dallo stesso codice.
Doppia persistenza (CQRS)
EntityFlow utilizza una separazione comando/query con due rappresentazioni di ogni diagramma:
- Il modello di scrittura autoritativo è un Yjs CRDT, memorizzato come blob binario. Ogni modifica muta questo blob.
- Una proiezione di lettura relazionale viene derivata dal blob per le query, la ricerca e l'esportazione lato server.
Il flusso è rigorosamente unidirezionale:
CRDT blob → IR → projection rows
La proiezione non viene mai riscritta nel blob. Se una riga della proiezione dovesse mai divergere o fallire, viene semplicemente riderivata dal blob: il blob è l'unica fonte di verità.
Tempo reale
Un server websocket Hocuspocus viene eseguito nello stesso processo Node dell'API e sincronizza il CRDT tra gli editor connessi. La presenza in tempo reale (cursori, selezioni, chi è online) viaggia tramite l'awareness di Yjs, che non viene mai persistita: esiste solo per la durata di una connessione.
Poiché l'esportazione lato server viene emessa dall'IR derivata dal blob, il SQL/DBML che produce è identico byte per byte a ciò che esporta l'editor nel browser.
Scalabilità orizzontale
Un singolo nodo gestisce da solo un carico di lavoro considerevole. Per eseguire più di una replica del server, abilita il fan-out con Redis in modo che l'awareness e gli aggiornamenti dei documenti si propaghino tra i pod. Senza di esso, le repliche divergono. Consulta Scalabilità e prestazioni per i dettagli e gli obiettivi SLO.