Files
tolaria/docs/adr/0043-reactive-vault-state-on-save.md
lucaronin c282244cf8 feat: reactive vault state — editor changes propagate immediately to all UI
Add title and sidebar_label mappings to contentToEntryPatch so editing
these frontmatter fields in the raw editor immediately updates the note
list, breadcrumb bar, sidebar sections, and inspector.

Also trigger reloadViews() when .yml view files are saved, so sidebar
view names update without a full vault reload.

ADR-0043 documents the reactive update model.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 00:06:52 +02:00

3.0 KiB

type, id, title, status, date
type id title status date
ADR 0043 Reactive vault state: editor changes propagate immediately to all UI active 2026-04-05

Context

When a user edits frontmatter in the raw editor (or BlockNote preserves it), changes to metadata fields like title, type, _favorite, _archived, and sidebar_label must be reflected immediately across all UI components — sidebar sections, note list, breadcrumb bar, inspector, and tabs.

Previously, after save_note_content, only derived fields (outgoingLinks, snippet, wordCount) were updated in vault.entries. Frontmatter-derived fields were stale until a full vault reload.

Decision

All frontmatter changes are parsed in real-time and applied to vault.entries via updateEntry() during content editing, not after save.

How it works

  1. On every content change (keystroke in raw editor, or BlockNote onChange), useEditorSaveWithLinks.handleContentChange is called.
  2. It invokes contentToEntryPatch(content) which parses frontmatter and maps known keys to VaultEntry fields.
  3. If the parsed patch differs from the previous one, updateEntry(path, patch) merges it into vault.entries.
  4. All UI components derive from vault.entries via React reactivity — they re-render automatically.

Mapped fields

contentToEntryPatch maps these frontmatter keys to VaultEntry fields:

Frontmatter key VaultEntry field Notes
title title
type / is_a isA
status status
_favorite favorite
_favorite_index favoriteIndex
_archived / archived archived
_trashed / trashed trashed
_organized organized
color color Type entries
icon icon Type entries
order order Type entries
sidebar_label sidebarLabel Type entries
visible visible Type entries
template template Type entries
sort sort Type entries
view view Type entries
aliases aliases
belongs_to belongsTo
related_to relatedTo

Inspector operations use a separate, more direct path

When the user edits frontmatter via the Inspector panel, runFrontmatterAndApply calls the Tauri command and immediately applies the result via updateEntry(). This path was already reactive before this ADR.

View files (.yml)

View files are not markdown notes — they have no frontmatter delimiters. When a .yml file is saved, onNotePersisted triggers reloadViews() to refresh the sidebar view list.

Consequences

  • Any new frontmatter key that should affect the UI must be added to frontmatterToEntryPatch and its delete counterpart.
  • Components must read note metadata from vault.entries (via props), never from local state that could diverge.
  • The reload_vault_entry Tauri command exists for full re-parsing from disk but is not needed in the normal editing flow — contentToEntryPatch handles it client-side.