UnENVerse 0.42.6
Local-first desktop secrets manager — TypeScript frontend
Loading...
Searching...
No Matches
vault-watch.ts File Reference

Notice when something else writes the vault, and pick the change up. More...

import st;
Include dependency graph for vault-watch.ts:

Variables

const POLL_MS = 3000
 How often to ask.
 
let timer
 
let reloading = false
 Set while a reload is in flight, so a slow load cannot overlap the next tick.
 
const invoke = invokeTauri
 

Detailed Description

Notice when something else writes the vault, and pick the change up.

The desktop app reads the vault once at unlock and then holds it in memory. Nothing told it that unv entry set in a terminal, unv totp advance, or a LAN peer had written to the same database — so the window went on showing the state it read at unlock, and the next save either overwrote the other writer's work or (since the compare-and-swap landed) failed with a conflict the user had no way to have predicted.

How it detects a change

vault_meta.data_hash is written in the same transaction as the data, so it is by construction the hash of exactly the bytes on disk — and it is already what the compare-and-swap compares. The store keeps the version it last read or wrote; this polls the stored one and reloads when the two differ. No file watcher, no mtime heuristics, and nothing new that could disagree with the CAS about what "the current version" means.

A poll rather than a pushed event because the answer is one indexed SELECT against a table with a handful of rows, and because a Rust-side watcher would be a second definition of "changed" to keep in step with the first.

What it will not do

It never reloads over an open editor. A reload replaces st.vault, and doing that under a half-typed entry throws the typing away — which is worse than being briefly out of date. While any overlay is open the watcher waits and tries again on the next tick.

It does not touch view state. This is the same vault with new contents, not a different vault, so resetViewState() — which is for when the data is replaced — would wrongly drop the user's filters and expanded cards mid-session. Ids that no longer resolve are already handled by the renderers (invariant 1) and by restoreViewState's validation (invariant 7).

Local vaults only. A remote vault's writes come back through its own API and RemoteVaultStore has no equivalent marker to poll; watching one would mean a request every few seconds against a server that may be on a phone tether. Written down because an unrecorded gap is indistinguishable from an oversight (invariant 10).

Variable Documentation

◆ POLL_MS

const POLL_MS = 3000

How often to ask.

Long enough to be free, short enough to feel live.

◆ timer

let timer

◆ reloading

let reloading = false

Set while a reload is in flight, so a slow load cannot overlap the next tick.

◆ invoke

const invoke = invokeTauri