MCPcopy
hub / github.com/thesysdev/openui / useOpenUIState

Function useOpenUIState

packages/react-lang/src/hooks/useOpenUIState.ts:69–507  ·  view source on GitHub ↗
(
  {
    response,
    library,
    isStreaming,
    onAction,
    onStateUpdate,
    initialState,
    toolProvider,
    onError,
  }: UseOpenUIStateOptions,
  renderDeep: (value: unknown) => React.ReactNode,
)

Source from the content-addressed store, hash-verified

67 * under formName as plain values.
68 */
69export function useOpenUIState(
70 {
71 response,
72 library,
73 isStreaming,
74 onAction,
75 onStateUpdate,
76 initialState,
77 toolProvider,
78 onError,
79 }: UseOpenUIStateOptions,
80 renderDeep: (value: unknown) => React.ReactNode,
81): OpenUIState {
82 // ─── Streaming parser (incremental — caches completed statements) ───
83 const sp = useMemo(() => createStreamingParser(library.toJSONSchema(), library.root), [library]);
84
85 // ─── Parse result ───
86 const parseExceptionRef = useRef<OpenUIError | null>(null);
87 const result = useMemo<ParseResult | null>(() => {
88 parseExceptionRef.current = null;
89 if (!response) return null;
90 try {
91 return sp.set(response);
92 } catch (e) {
93 const msg = e instanceof Error ? e.message : String(e);
94 parseExceptionRef.current = {
95 source: "parser",
96 code: "parse-exception",
97 message: `Parser crashed: ${msg}`,
98 hint: "The response may contain syntax the parser cannot handle",
99 };
100 return null;
101 }
102 }, [sp, response]);
103
104 // ─── Store (holds everything: $bindings + form fields) ───
105 const store = useMemo<Store>(() => createStore(), []);
106
107 // ─── QueryManager ───
108 const queryManager = useMemo<QueryManager>(
109 () => createQueryManager(toolProvider ?? null),
110 [toolProvider],
111 );
112
113 useEffect(() => {
114 queryManager.activate();
115 return () => queryManager.dispose();
116 }, [queryManager]);
117
118 // ─── Initialize Store ───
119 const storeInitKeyRef = useRef<unknown>(Symbol());
120 useEffect(() => {
121 if (!result?.stateDeclarations && !initialState) return;
122 const key = `${JSON.stringify(result?.stateDeclarations)}::${JSON.stringify(initialState)}`;
123 if (storeInitKeyRef.current === key) return;
124 storeInitKeyRef.current = key;
125
126 // Split initialState: $-prefixed keys are bindings, everything else is form state

Callers 1

RendererFunction · 0.90

Calls 15

createStreamingParserFunction · 0.90
createStoreFunction · 0.90
createQueryManagerFunction · 0.90
evaluateFunction · 0.90
evaluateElementPropsFunction · 0.90
enrichErrorsFunction · 0.90
unwrapFieldValueFunction · 0.85
activateMethod · 0.80
getMutationResultMethod · 0.80
evaluateQueriesMethod · 0.80
registerMutationsMethod · 0.80
fireMutationMethod · 0.80

Tested by

no test coverage detected