Code review on pr-735 flagged `applyMountedChange` for exceeding the
8-parameter limit. The three effect callbacks (`onSetDefaultWorkspace`,
`onSwitchVault`, `onUpdateWorkspaceIdentity`) are now grouped under a
single `callbacks` field. The function's destructure surface drops
from 8 to 6 fields, and the semantic split between "state + change"
and "effects" is now explicit in the type.
No behaviour change; the six existing tests pass unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Part of the fix for #735 — top-level folder creation invisible in
multi-workspace mode. The primary route, where the create-folder flow
ignored the sidebar selection and always wrote to the legacy
`resolvedPath`, is fixed in #728 (selection-aware routing in
`handleCreateFolder` and `FolderTree`). This commit fixes the
complementary state-machine bug: the vault switcher could leave
`vaultPath` pointing at an unmounted vault, so any consumer that still
reads `vaultPath` would operate on a vault the user no longer sees.
The vault switcher tracks two related paths:
- `defaultWorkspacePath` — the workspace the user is currently "on"
(used as the destination for new notes, the graph default, etc.).
- `vaultPath` — the active vault the switcher tracks; read by the file
watcher, folder/view reloaders, and the active-vault fallback in the
folder loader.
Unchecking a vault in the switcher previously re-routed only
`defaultWorkspacePath` to another mounted vault, leaving `vaultPath`
pointing at the just-unmounted vault. The two paths drifted apart and
every downstream consumer that read `vaultPath` operated on stale
state — for example the folder loader's active-vault fallback (when
enabled) would silently re-introduce the unmounted vault into the
sidebar, and the file watcher would keep listening to it.
`applyMountedChange` now also calls `onSwitchVault(nextPath)` when the
unmounted vault is the active one, mirroring the existing reroute for
`defaultWorkspacePath`. After the change `vaultPath` and mounted state
stay consistent for every consumer.
`applyMountedChange` is extracted from `VaultMenu.tsx` to a sibling
helper module (`vaultMenuMountedChange.ts`) so it can be unit-tested
directly without tripping `react-refresh/only-export-components`.
Tests:
- New `VaultMenu.applyMountedChange.test.ts` covers the four reroute
permutations (default+active, active only, default only, neither),
the bail-out when no alternative mounted vault exists, and the
remount no-op.
Fixes: https://github.com/refactoringhq/tolaria/issues/735
Related: https://github.com/refactoringhq/tolaria/pull/728
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>