MCPcopy Create free account
hub / github.com/TraderAlice/OpenAlice / useConfigPage

Function useConfigPage

ui/src/hooks/useConfigPage.ts:30–87  ·  view source on GitHub ↗
({
  section,
  extract,
  delay = 600,
}: UseConfigPageOptions<T>)

Source from the content-addressed store, hash-verified

28 * Handles: load → autoSave → flush → updateConfig/updateConfigImmediate.
29 */
30export function useConfigPage<T extends object>({
31 section,
32 extract,
33 delay = 600,
34}: UseConfigPageOptions<T>): UseConfigPageResult<T> {
35 const [fullConfig, setFullConfig] = useState<AppConfig | null>(null)
36 const [config, setConfig] = useState<T | null>(null)
37 const [loadError, setLoadError] = useState(false)
38 const flushRequestedRef = useRef(false)
39
40 useEffect(() => {
41 api.config
42 .load()
43 .then((full) => {
44 setFullConfig(full)
45 setConfig(extract(full))
46 })
47 .catch(() => setLoadError(true))
48 }, []) // extract is stable (caller should memoize or use inline arrow)
49
50 const saveConfig = useCallback(
51 async (data: T) => {
52 const result = await api.config.updateSection(section, data)
53 // Adopt the server echo only when its content actually differs
54 // (zod normalization, defaults). Unconditionally swapping in a
55 // fresh object re-arms useAutoSave's [data] effect and loops the
56 // PUT forever — echo → new identity → schedule → PUT → echo …
57 setConfig((prev) => (JSON.stringify(prev) === JSON.stringify(result) ? prev : (result as T)))
58 },
59 [section],
60 )
61
62 const { status, flush, retry } = useAutoSave({
63 data: config!,
64 save: saveConfig,
65 delay,
66 enabled: config !== null,
67 })
68
69 // After React commits a state update with flushRequested, trigger immediate save
70 useEffect(() => {
71 if (flushRequestedRef.current && config) {
72 flushRequestedRef.current = false
73 flush()
74 }
75 }, [config, flush])
76
77 const updateConfig = useCallback((patch: Partial<T>) => {
78 setConfig((prev) => (prev ? { ...prev, ...patch } : prev))
79 }, [])
80
81 const updateConfigImmediate = useCallback((patch: Partial<T>) => {
82 setConfig((prev) => (prev ? { ...prev, ...patch } : prev))
83 flushRequestedRef.current = true
84 }, [])
85
86 return { config, fullConfig, status, loadError, updateConfig, updateConfigImmediate, retry }
87}

Callers 3

MarketDataPageFunction · 0.90
MCPPageFunction · 0.90
CollectorSettingsFunction · 0.90

Calls 4

useAutoSaveFunction · 0.90
extractFunction · 0.85
flushFunction · 0.50
loadMethod · 0.45

Tested by

no test coverage detected