mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-11-28 05:00:26 +08:00
The current layout system uses a complex bidirectional atom architecture
that forces every layout change to round-trip through the backend
WaveObject, even though **the backend never reads this data** - it only
queues actions via `PendingBackendActions`. By switching to a "write
cache" pattern where local atoms are the source of truth and backend
writes are fire-and-forget, we can eliminate ~70% of the complexity
while maintaining full persistence.
----
Every layout change (split, close, focus, magnify) currently follows
this flow:
```
User action
↓
treeReducer() mutates layoutState
↓
layoutState.generation++ ← Only purpose: trigger the write
↓
Bidirectional atom setter (checks generation)
↓
Write to WaveObject {rootnode, focusednodeid, magnifiednodeid}
↓
WaveObject update notification
↓
Bidirectional atom getter runs
↓
ALL dependent atoms recalculate (every isFocused, etc.)
↓
React re-renders with updated state
```
---
## Proposed "Write Cache" Architecture
### Core Concept
```
User action
↓
Update LOCAL atom (immediate, synchronous)
↓
React re-renders (single tick, all atoms see new state)
↓
[async, fire-and-forget] Persist to WaveObject
```
### Key Principles
1. **Local atoms are source of truth** during runtime
2. **WaveObject is persistence layer** only (read on init, write async)
3. **Backend actions still work** via `PendingBackendActions`
4. **No generation tracking needed** (no need to trigger writes)
13 lines
516 B
TypeScript
13 lines
516 B
TypeScript
// Copyright 2025, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import { WOS } from "@/app/store/global";
|
|
import { Atom, Getter } from "jotai";
|
|
|
|
export function getLayoutStateAtomFromTab(tabAtom: Atom<Tab>, get: Getter): WritableWaveObjectAtom<LayoutState> {
|
|
const tabData = get(tabAtom);
|
|
if (!tabData) return;
|
|
const layoutStateOref = WOS.makeORef("layout", tabData.layoutstate);
|
|
const layoutStateAtom = WOS.getWaveObjectAtom<LayoutState>(layoutStateOref);
|
|
return layoutStateAtom;
|
|
}
|