Zum Inhalt springen

Event-driven Projection

Statt Zustand direkt zu mutieren, beschreiben Events, was passiert ist. Der Zustand ist das Ergebnis der Projektion dieser Events.

User-Intent → Command → Event → Projection → State → ViewModel → Komponente
  1. Nutzer klickt „Task abschließen”
  2. CompleteTaskCommand wird dispatcht
  3. TaskCompleted-Event wird emittiert
  4. Store projiziert den neuen Zustand: Task mit status: 'done'
  5. Komponente rendert den aktualisierten Zustand
  • Rückverfolgbarkeit: Was hat sich wann geändert und warum?
  • Optimistic Updates: Zustand sofort aktualisieren, Event async bestätigen
  • Wiederholbarkeit: Events können replayed werden (Debugging, Tests)
  • Entkopplung: Producer des Events kennt die Consumer nicht

In einem Signal-Store-Setup ohne vollständiges Event-Sourcing kann dieses Pattern vereinfacht umgesetzt werden:

// Statt: patchState(store, { tasks: [...tasks, newTask] })
// Mit semantischer Intent-Trennung:
withMethods((store) => ({
taskCreated(task: Task) {
patchState(store, { tasks: [...store.tasks(), task] });
},
taskCompleted(taskId: string) {
patchState(store, {
tasks: store.tasks().map((t) => (t.id === taskId ? { ...t, status: 'done' } : t)),
});
},
}));

Kleine Projektion statt direkter Mutation. Klare semantische Bezeichnungen.