Files
Nitro-V3/src/components/wired-tools/wiredCreatorToolsUiStore.ts
T
simoleo89 82bccd4040 wired-tools: hoist monitorSnapshot + polling reset to the Zustand store
Move the monitor snapshot off WiredCreatorToolsView's useState into
useWiredCreatorToolsUiStore. The WiredMonitorDataEvent listener still
lives in the component (it can't move alongside without dragging
useMessageEvent into the store), but it now writes to setMonitorSnapshot
and the room-change reset calls resetMonitorSnapshot() instead of
re-instantiating the default in the component.

Direct benefit: the snapshot now survives closing and reopening the
panel between two server pushes. Before this commit, the parent
remounted on every visibility flip (parent renders null while
`!isVisible`) which dropped the snapshot back to the empty default;
the user would briefly see zeroed stats until the next `monitor:fetch`
roundtrip landed. Holding the snapshot in zustand decouples the data
from the component's mount lifecycle.

Tests: three new cases on the store cover setMonitorSnapshot,
resetMonitorSnapshot returning a fresh empty instance, and the
"close/reopen panel preserves snapshot" lifecycle. Total 181/181.
2026-05-16 12:20:35 +02:00

104 lines
4.2 KiB
TypeScript

import { createNitroStore } from '../../state/createNitroStore';
import { createEmptyMonitorSnapshot } from './WiredCreatorTools.helpers';
import { InspectionElementType, MonitorSnapshot, VariablesElementType, WiredToolsTab } from './WiredCreatorTools.types';
type MonitorSeverityFilter = 'ALL' | 'ERROR' | 'WARNING';
type Updater<T> = T | ((prev: T) => T);
const apply = <T>(prev: T, next: Updater<T>): T =>
((typeof next === 'function') ? (next as (p: T) => T)(prev) : next);
interface WiredCreatorToolsUiState
{
isVisible: boolean;
activeTab: WiredToolsTab;
inspectionType: InspectionElementType;
variablesType: VariablesElementType;
isMonitorHistoryOpen: boolean;
isMonitorInfoOpen: boolean;
isInspectionGiveOpen: boolean;
isVariableManageOpen: boolean;
isManagedGiveOpen: boolean;
monitorHistorySeverityFilter: MonitorSeverityFilter;
monitorHistoryTypeFilter: string;
variableManageTypeFilter: string;
variableManageSort: string;
variableManagePage: number;
/**
* Latest snapshot pushed by the server through `WiredMonitorDataEvent`.
* Held in the store (rather than `useState`) so it survives remount
* — e.g. closing and reopening the panel between two server pushes
* keeps the last-known stats visible instead of flashing back to the
* empty snapshot.
*/
monitorSnapshot: MonitorSnapshot;
setIsVisible: (next: Updater<boolean>) => void;
setActiveTab: (next: WiredToolsTab) => void;
setInspectionType: (next: InspectionElementType) => void;
setVariablesType: (next: VariablesElementType) => void;
setIsMonitorHistoryOpen: (next: boolean) => void;
setIsMonitorInfoOpen: (next: boolean) => void;
setIsInspectionGiveOpen: (next: Updater<boolean>) => void;
setIsVariableManageOpen: (next: boolean) => void;
setIsManagedGiveOpen: (next: Updater<boolean>) => void;
setMonitorHistorySeverityFilter: (next: MonitorSeverityFilter) => void;
setMonitorHistoryTypeFilter: (next: string) => void;
setVariableManageTypeFilter: (next: string) => void;
setVariableManageSort: (next: string) => void;
setVariableManagePage: (next: Updater<number>) => void;
setMonitorSnapshot: (next: MonitorSnapshot) => void;
resetMonitorSnapshot: () => void;
}
export const useWiredCreatorToolsUiStore = createNitroStore<WiredCreatorToolsUiState>()((set) => ({
isVisible: false,
activeTab: 'monitor',
inspectionType: 'furni',
variablesType: 'furni',
isMonitorHistoryOpen: false,
isMonitorInfoOpen: false,
isInspectionGiveOpen: false,
isVariableManageOpen: false,
isManagedGiveOpen: false,
monitorHistorySeverityFilter: 'ALL',
monitorHistoryTypeFilter: 'ALL',
variableManageTypeFilter: 'ALL',
variableManageSort: 'highest_value',
variableManagePage: 1,
monitorSnapshot: createEmptyMonitorSnapshot(),
setIsVisible: (next) => set(state => ({ isVisible: apply(state.isVisible, next) })),
setActiveTab: (next) => set({ activeTab: next }),
setInspectionType: (next) => set({ inspectionType: next }),
setVariablesType: (next) => set({ variablesType: next }),
setIsMonitorHistoryOpen: (next) => set({ isMonitorHistoryOpen: next }),
setIsMonitorInfoOpen: (next) => set({ isMonitorInfoOpen: next }),
setIsInspectionGiveOpen: (next) => set(state => ({ isInspectionGiveOpen: apply(state.isInspectionGiveOpen, next) })),
setIsVariableManageOpen: (next) => set({ isVariableManageOpen: next }),
setIsManagedGiveOpen: (next) => set(state => ({ isManagedGiveOpen: apply(state.isManagedGiveOpen, next) })),
setMonitorHistorySeverityFilter: (next) => set({ monitorHistorySeverityFilter: next }),
setMonitorHistoryTypeFilter: (next) => set({ monitorHistoryTypeFilter: next }),
setVariableManageTypeFilter: (next) => set({ variableManageTypeFilter: next }),
setVariableManageSort: (next) => set({ variableManageSort: next }),
setVariableManagePage: (next) => set(state => ({ variableManagePage: apply(state.variableManagePage, next) })),
setMonitorSnapshot: (next) => set({ monitorSnapshot: next }),
resetMonitorSnapshot: () => set({ monitorSnapshot: createEmptyMonitorSnapshot() })
}));