@ai-sdk/rsc 2.0.45 → 2.0.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/package.json +3 -2
- package/src/ai-state.test.ts +146 -0
- package/src/ai-state.tsx +210 -0
- package/src/index.ts +20 -0
- package/src/provider.tsx +149 -0
- package/src/rsc-client.ts +8 -0
- package/src/rsc-server.ts +5 -0
- package/src/rsc-shared.mts +11 -0
- package/src/shared-client/context.tsx +226 -0
- package/src/shared-client/index.ts +11 -0
- package/src/stream-ui/__snapshots__/render.ui.test.tsx.snap +91 -0
- package/src/stream-ui/__snapshots__/stream-ui.ui.test.tsx.snap +213 -0
- package/src/stream-ui/index.tsx +1 -0
- package/src/stream-ui/stream-ui.tsx +419 -0
- package/src/stream-ui/stream-ui.ui.test.tsx +321 -0
- package/src/streamable-ui/create-streamable-ui.tsx +148 -0
- package/src/streamable-ui/create-streamable-ui.ui.test.tsx +354 -0
- package/src/streamable-ui/create-suspended-chunk.tsx +84 -0
- package/src/streamable-value/create-streamable-value.test.tsx +179 -0
- package/src/streamable-value/create-streamable-value.ts +296 -0
- package/src/streamable-value/is-streamable-value.ts +10 -0
- package/src/streamable-value/read-streamable-value.tsx +113 -0
- package/src/streamable-value/read-streamable-value.ui.test.tsx +165 -0
- package/src/streamable-value/streamable-value.ts +37 -0
- package/src/streamable-value/use-streamable-value.tsx +91 -0
- package/src/types/index.ts +1 -0
- package/src/types.test-d.ts +17 -0
- package/src/types.ts +71 -0
- package/src/util/constants.ts +5 -0
- package/src/util/create-resolvable-promise.ts +28 -0
- package/src/util/is-async-generator.ts +7 -0
- package/src/util/is-function.ts +8 -0
- package/src/util/is-generator.ts +5 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
2
|
+
'use client';
|
|
3
|
+
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
|
|
6
|
+
import * as jsondiffpatch from 'jsondiffpatch';
|
|
7
|
+
import { isFunction } from '../util/is-function';
|
|
8
|
+
import type {
|
|
9
|
+
AIProvider,
|
|
10
|
+
InferActions,
|
|
11
|
+
InferAIState,
|
|
12
|
+
InferUIState,
|
|
13
|
+
InternalAIProviderProps,
|
|
14
|
+
ValueOrUpdater,
|
|
15
|
+
} from '../types';
|
|
16
|
+
|
|
17
|
+
const InternalUIStateProvider = React.createContext<null | any>(null);
|
|
18
|
+
const InternalAIStateProvider = React.createContext<undefined | any>(undefined);
|
|
19
|
+
const InternalActionProvider = React.createContext<null | any>(null);
|
|
20
|
+
const InternalSyncUIStateProvider = React.createContext<null | any>(null);
|
|
21
|
+
|
|
22
|
+
export function InternalAIProvider({
|
|
23
|
+
children,
|
|
24
|
+
initialUIState,
|
|
25
|
+
initialAIState,
|
|
26
|
+
initialAIStatePatch,
|
|
27
|
+
wrappedActions,
|
|
28
|
+
wrappedSyncUIState,
|
|
29
|
+
}: InternalAIProviderProps) {
|
|
30
|
+
if (!('use' in React)) {
|
|
31
|
+
throw new Error('Unsupported React version.');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const uiState = React.useState(initialUIState);
|
|
35
|
+
const setUIState = uiState[1];
|
|
36
|
+
|
|
37
|
+
const resolvedInitialAIStatePatch = initialAIStatePatch
|
|
38
|
+
? (React as any).use(initialAIStatePatch)
|
|
39
|
+
: undefined;
|
|
40
|
+
initialAIState = React.useMemo(() => {
|
|
41
|
+
if (resolvedInitialAIStatePatch) {
|
|
42
|
+
return jsondiffpatch.patch(
|
|
43
|
+
jsondiffpatch.clone(initialAIState),
|
|
44
|
+
resolvedInitialAIStatePatch,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
return initialAIState;
|
|
48
|
+
}, [initialAIState, resolvedInitialAIStatePatch]);
|
|
49
|
+
|
|
50
|
+
const aiState = React.useState(initialAIState);
|
|
51
|
+
const setAIState = aiState[1];
|
|
52
|
+
const aiStateRef = React.useRef(aiState[0]);
|
|
53
|
+
|
|
54
|
+
React.useEffect(() => {
|
|
55
|
+
aiStateRef.current = aiState[0];
|
|
56
|
+
}, [aiState[0]]);
|
|
57
|
+
|
|
58
|
+
const clientWrappedActions = React.useMemo(
|
|
59
|
+
() =>
|
|
60
|
+
Object.fromEntries(
|
|
61
|
+
Object.entries(wrappedActions).map(([key, action]) => [
|
|
62
|
+
key,
|
|
63
|
+
async (...args: any) => {
|
|
64
|
+
const aiStateSnapshot = aiStateRef.current;
|
|
65
|
+
const [aiStateDelta, result] = await action(
|
|
66
|
+
aiStateSnapshot,
|
|
67
|
+
...args,
|
|
68
|
+
);
|
|
69
|
+
(async () => {
|
|
70
|
+
const delta = await aiStateDelta;
|
|
71
|
+
if (delta !== undefined) {
|
|
72
|
+
aiState[1](
|
|
73
|
+
jsondiffpatch.patch(
|
|
74
|
+
jsondiffpatch.clone(aiStateSnapshot),
|
|
75
|
+
delta,
|
|
76
|
+
),
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
})();
|
|
80
|
+
return result;
|
|
81
|
+
},
|
|
82
|
+
]),
|
|
83
|
+
),
|
|
84
|
+
[wrappedActions],
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const clientWrappedSyncUIStateAction = React.useMemo(() => {
|
|
88
|
+
if (!wrappedSyncUIState) {
|
|
89
|
+
return () => {};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return async () => {
|
|
93
|
+
const aiStateSnapshot = aiStateRef.current;
|
|
94
|
+
const [aiStateDelta, uiState] =
|
|
95
|
+
await wrappedSyncUIState!(aiStateSnapshot);
|
|
96
|
+
|
|
97
|
+
if (uiState !== undefined) {
|
|
98
|
+
setUIState(uiState);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const delta = await aiStateDelta;
|
|
102
|
+
if (delta !== undefined) {
|
|
103
|
+
const patchedAiState = jsondiffpatch.patch(
|
|
104
|
+
jsondiffpatch.clone(aiStateSnapshot),
|
|
105
|
+
delta,
|
|
106
|
+
);
|
|
107
|
+
setAIState(patchedAiState);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}, [wrappedSyncUIState]);
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<InternalAIStateProvider.Provider value={aiState}>
|
|
114
|
+
<InternalUIStateProvider.Provider value={uiState}>
|
|
115
|
+
<InternalActionProvider.Provider value={clientWrappedActions}>
|
|
116
|
+
<InternalSyncUIStateProvider.Provider
|
|
117
|
+
value={clientWrappedSyncUIStateAction}
|
|
118
|
+
>
|
|
119
|
+
{children}
|
|
120
|
+
</InternalSyncUIStateProvider.Provider>
|
|
121
|
+
</InternalActionProvider.Provider>
|
|
122
|
+
</InternalUIStateProvider.Provider>
|
|
123
|
+
</InternalAIStateProvider.Provider>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function useUIState<AI extends AIProvider = any>() {
|
|
128
|
+
type T = InferUIState<AI, any>;
|
|
129
|
+
|
|
130
|
+
const state = React.useContext<
|
|
131
|
+
[T, (v: T | ((v_: T) => T)) => void] | null | undefined
|
|
132
|
+
>(InternalUIStateProvider);
|
|
133
|
+
if (state === null) {
|
|
134
|
+
throw new Error('`useUIState` must be used inside an <AI> provider.');
|
|
135
|
+
}
|
|
136
|
+
if (!Array.isArray(state)) {
|
|
137
|
+
throw new Error('Invalid state');
|
|
138
|
+
}
|
|
139
|
+
if (state[0] === undefined) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
'`initialUIState` must be provided to `createAI` or `<AI>`',
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
return state;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// TODO: How do we avoid causing a re-render when the AI state changes but you
|
|
148
|
+
// are only listening to a specific key? We need useSES perhaps?
|
|
149
|
+
function useAIState<AI extends AIProvider = any>(): [
|
|
150
|
+
InferAIState<AI, any>,
|
|
151
|
+
(newState: ValueOrUpdater<InferAIState<AI, any>>) => void,
|
|
152
|
+
];
|
|
153
|
+
function useAIState<AI extends AIProvider = any>(
|
|
154
|
+
key: keyof InferAIState<AI, any>,
|
|
155
|
+
): [
|
|
156
|
+
InferAIState<AI, any>[typeof key],
|
|
157
|
+
(newState: ValueOrUpdater<InferAIState<AI, any>[typeof key]>) => void,
|
|
158
|
+
];
|
|
159
|
+
function useAIState<AI extends AIProvider = any>(
|
|
160
|
+
...args: [] | [keyof InferAIState<AI, any>]
|
|
161
|
+
) {
|
|
162
|
+
type T = InferAIState<AI, any>;
|
|
163
|
+
|
|
164
|
+
const state = React.useContext<
|
|
165
|
+
[T, (newState: ValueOrUpdater<T>) => void] | null | undefined
|
|
166
|
+
>(InternalAIStateProvider);
|
|
167
|
+
if (state === null) {
|
|
168
|
+
throw new Error('`useAIState` must be used inside an <AI> provider.');
|
|
169
|
+
}
|
|
170
|
+
if (!Array.isArray(state)) {
|
|
171
|
+
throw new Error('Invalid state');
|
|
172
|
+
}
|
|
173
|
+
if (state[0] === undefined) {
|
|
174
|
+
throw new Error(
|
|
175
|
+
'`initialAIState` must be provided to `createAI` or `<AI>`',
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
if (args.length >= 1 && typeof state[0] !== 'object') {
|
|
179
|
+
throw new Error(
|
|
180
|
+
'When using `useAIState` with a key, the AI state must be an object.',
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const key = args[0];
|
|
185
|
+
const setter = React.useCallback(
|
|
186
|
+
typeof key === 'undefined'
|
|
187
|
+
? state[1]
|
|
188
|
+
: (newState: ValueOrUpdater<T>) => {
|
|
189
|
+
if (isFunction(newState)) {
|
|
190
|
+
return state[1](s => {
|
|
191
|
+
return { ...s, [key]: newState(s[key]) };
|
|
192
|
+
});
|
|
193
|
+
} else {
|
|
194
|
+
return state[1]({ ...state[0], [key]: newState });
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
[key],
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
if (args.length === 0) {
|
|
201
|
+
return state;
|
|
202
|
+
} else {
|
|
203
|
+
return [state[0][args[0]], setter];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function useActions<AI extends AIProvider = any>() {
|
|
208
|
+
type T = InferActions<AI, any>;
|
|
209
|
+
|
|
210
|
+
const actions = React.useContext<T>(InternalActionProvider);
|
|
211
|
+
return actions;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function useSyncUIState() {
|
|
215
|
+
const syncUIState = React.useContext<() => Promise<void>>(
|
|
216
|
+
InternalSyncUIStateProvider,
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
if (syncUIState === null) {
|
|
220
|
+
throw new Error('`useSyncUIState` must be used inside an <AI> provider.');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return syncUIState;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export { useAIState };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
export { readStreamableValue } from '../streamable-value/read-streamable-value';
|
|
4
|
+
export { useStreamableValue } from '../streamable-value/use-streamable-value';
|
|
5
|
+
export {
|
|
6
|
+
InternalAIProvider,
|
|
7
|
+
useAIState,
|
|
8
|
+
useActions,
|
|
9
|
+
useSyncUIState,
|
|
10
|
+
useUIState,
|
|
11
|
+
} from './context';
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`should emit React Nodes with async render function 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"children": {
|
|
6
|
+
"children": {},
|
|
7
|
+
"props": {
|
|
8
|
+
"c": undefined,
|
|
9
|
+
"n": {
|
|
10
|
+
"done": false,
|
|
11
|
+
"next": {
|
|
12
|
+
"done": true,
|
|
13
|
+
"value": <div>
|
|
14
|
+
Weather
|
|
15
|
+
</div>,
|
|
16
|
+
},
|
|
17
|
+
"value": <div>
|
|
18
|
+
Weather
|
|
19
|
+
</div>,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
"type": "",
|
|
23
|
+
},
|
|
24
|
+
"props": {
|
|
25
|
+
"fallback": undefined,
|
|
26
|
+
},
|
|
27
|
+
"type": "Symbol(react.suspense)",
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
exports[`should emit React Nodes with generator render function 1`] = `
|
|
32
|
+
{
|
|
33
|
+
"children": {
|
|
34
|
+
"children": {},
|
|
35
|
+
"props": {
|
|
36
|
+
"c": undefined,
|
|
37
|
+
"n": {
|
|
38
|
+
"done": false,
|
|
39
|
+
"next": {
|
|
40
|
+
"done": false,
|
|
41
|
+
"next": {
|
|
42
|
+
"done": true,
|
|
43
|
+
"value": <div>
|
|
44
|
+
Weather
|
|
45
|
+
</div>,
|
|
46
|
+
},
|
|
47
|
+
"value": <div>
|
|
48
|
+
Weather
|
|
49
|
+
</div>,
|
|
50
|
+
},
|
|
51
|
+
"value": <div>
|
|
52
|
+
Loading...
|
|
53
|
+
</div>,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
"type": "",
|
|
57
|
+
},
|
|
58
|
+
"props": {
|
|
59
|
+
"fallback": undefined,
|
|
60
|
+
},
|
|
61
|
+
"type": "Symbol(react.suspense)",
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
64
|
+
|
|
65
|
+
exports[`should emit React Nodes with sync render function 1`] = `
|
|
66
|
+
{
|
|
67
|
+
"children": {
|
|
68
|
+
"children": {},
|
|
69
|
+
"props": {
|
|
70
|
+
"c": undefined,
|
|
71
|
+
"n": {
|
|
72
|
+
"done": false,
|
|
73
|
+
"next": {
|
|
74
|
+
"done": true,
|
|
75
|
+
"value": <div>
|
|
76
|
+
Weather
|
|
77
|
+
</div>,
|
|
78
|
+
},
|
|
79
|
+
"value": <div>
|
|
80
|
+
Weather
|
|
81
|
+
</div>,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
"type": "",
|
|
85
|
+
},
|
|
86
|
+
"props": {
|
|
87
|
+
"fallback": undefined,
|
|
88
|
+
},
|
|
89
|
+
"type": "Symbol(react.suspense)",
|
|
90
|
+
}
|
|
91
|
+
`;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`options.headers > should pass headers to model 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"children": {
|
|
6
|
+
"children": {},
|
|
7
|
+
"props": {
|
|
8
|
+
"c": undefined,
|
|
9
|
+
"n": {
|
|
10
|
+
"done": false,
|
|
11
|
+
"next": {
|
|
12
|
+
"done": true,
|
|
13
|
+
"value": "{ "content": "headers test" }",
|
|
14
|
+
},
|
|
15
|
+
"value": "{ "content": "headers test" }",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
"type": "",
|
|
19
|
+
},
|
|
20
|
+
"props": {
|
|
21
|
+
"fallback": undefined,
|
|
22
|
+
},
|
|
23
|
+
"type": "Symbol(react.suspense)",
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
exports[`options.providerMetadata > should pass provider metadata to model 1`] = `
|
|
28
|
+
{
|
|
29
|
+
"children": {
|
|
30
|
+
"children": {},
|
|
31
|
+
"props": {
|
|
32
|
+
"c": undefined,
|
|
33
|
+
"n": {
|
|
34
|
+
"done": false,
|
|
35
|
+
"next": {
|
|
36
|
+
"done": true,
|
|
37
|
+
"value": "{ "content": "provider metadata test" }",
|
|
38
|
+
},
|
|
39
|
+
"value": "{ "content": "provider metadata test" }",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
"type": "",
|
|
43
|
+
},
|
|
44
|
+
"props": {
|
|
45
|
+
"fallback": undefined,
|
|
46
|
+
},
|
|
47
|
+
"type": "Symbol(react.suspense)",
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
exports[`result.value > should render text 1`] = `
|
|
52
|
+
{
|
|
53
|
+
"children": {
|
|
54
|
+
"children": {},
|
|
55
|
+
"props": {
|
|
56
|
+
"c": undefined,
|
|
57
|
+
"n": {
|
|
58
|
+
"done": false,
|
|
59
|
+
"next": {
|
|
60
|
+
"done": false,
|
|
61
|
+
"next": {
|
|
62
|
+
"done": false,
|
|
63
|
+
"next": {
|
|
64
|
+
"done": false,
|
|
65
|
+
"next": {
|
|
66
|
+
"done": false,
|
|
67
|
+
"next": {
|
|
68
|
+
"done": false,
|
|
69
|
+
"next": {
|
|
70
|
+
"done": true,
|
|
71
|
+
"value": "{ "content": "Hello, world!" }",
|
|
72
|
+
},
|
|
73
|
+
"value": "{ "content": "Hello, world!" }",
|
|
74
|
+
},
|
|
75
|
+
"value": "{ "content": "Hello, world!"",
|
|
76
|
+
},
|
|
77
|
+
"value": "{ "content": "Hello, world",
|
|
78
|
+
},
|
|
79
|
+
"value": "{ "content": "Hello, ",
|
|
80
|
+
},
|
|
81
|
+
"value": "{ "content": ",
|
|
82
|
+
},
|
|
83
|
+
"value": "{ ",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
"type": "",
|
|
87
|
+
},
|
|
88
|
+
"props": {
|
|
89
|
+
"fallback": undefined,
|
|
90
|
+
},
|
|
91
|
+
"type": "Symbol(react.suspense)",
|
|
92
|
+
}
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
exports[`result.value > should render text function returned ui 1`] = `
|
|
96
|
+
{
|
|
97
|
+
"children": {
|
|
98
|
+
"children": {},
|
|
99
|
+
"props": {
|
|
100
|
+
"c": undefined,
|
|
101
|
+
"n": {
|
|
102
|
+
"done": false,
|
|
103
|
+
"next": {
|
|
104
|
+
"done": false,
|
|
105
|
+
"next": {
|
|
106
|
+
"done": false,
|
|
107
|
+
"next": {
|
|
108
|
+
"done": false,
|
|
109
|
+
"next": {
|
|
110
|
+
"done": false,
|
|
111
|
+
"next": {
|
|
112
|
+
"done": false,
|
|
113
|
+
"next": {
|
|
114
|
+
"done": true,
|
|
115
|
+
"value": <h1>
|
|
116
|
+
{ "content": "Hello, world!" }
|
|
117
|
+
</h1>,
|
|
118
|
+
},
|
|
119
|
+
"value": <h1>
|
|
120
|
+
{ "content": "Hello, world!" }
|
|
121
|
+
</h1>,
|
|
122
|
+
},
|
|
123
|
+
"value": <h1>
|
|
124
|
+
{ "content": "Hello, world!"
|
|
125
|
+
</h1>,
|
|
126
|
+
},
|
|
127
|
+
"value": <h1>
|
|
128
|
+
{ "content": "Hello, world
|
|
129
|
+
</h1>,
|
|
130
|
+
},
|
|
131
|
+
"value": <h1>
|
|
132
|
+
{ "content": "Hello,
|
|
133
|
+
</h1>,
|
|
134
|
+
},
|
|
135
|
+
"value": <h1>
|
|
136
|
+
{ "content":
|
|
137
|
+
</h1>,
|
|
138
|
+
},
|
|
139
|
+
"value": <h1>
|
|
140
|
+
{
|
|
141
|
+
</h1>,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
"type": "",
|
|
145
|
+
},
|
|
146
|
+
"props": {
|
|
147
|
+
"fallback": undefined,
|
|
148
|
+
},
|
|
149
|
+
"type": "Symbol(react.suspense)",
|
|
150
|
+
}
|
|
151
|
+
`;
|
|
152
|
+
|
|
153
|
+
exports[`result.value > should render tool call results 1`] = `
|
|
154
|
+
{
|
|
155
|
+
"children": {
|
|
156
|
+
"children": {},
|
|
157
|
+
"props": {
|
|
158
|
+
"c": undefined,
|
|
159
|
+
"n": {
|
|
160
|
+
"done": true,
|
|
161
|
+
"value": <div>
|
|
162
|
+
tool1:
|
|
163
|
+
value
|
|
164
|
+
</div>,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
"type": "",
|
|
168
|
+
},
|
|
169
|
+
"props": {
|
|
170
|
+
"fallback": undefined,
|
|
171
|
+
},
|
|
172
|
+
"type": "Symbol(react.suspense)",
|
|
173
|
+
}
|
|
174
|
+
`;
|
|
175
|
+
|
|
176
|
+
exports[`result.value > should render tool call results with generator render function 1`] = `
|
|
177
|
+
{
|
|
178
|
+
"children": {
|
|
179
|
+
"children": {},
|
|
180
|
+
"props": {
|
|
181
|
+
"c": undefined,
|
|
182
|
+
"n": {
|
|
183
|
+
"done": false,
|
|
184
|
+
"next": {
|
|
185
|
+
"done": true,
|
|
186
|
+
"value": <div>
|
|
187
|
+
tool:
|
|
188
|
+
value
|
|
189
|
+
</div>,
|
|
190
|
+
},
|
|
191
|
+
"value": <div>
|
|
192
|
+
Loading...
|
|
193
|
+
</div>,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
"type": "",
|
|
197
|
+
},
|
|
198
|
+
"props": {
|
|
199
|
+
"fallback": undefined,
|
|
200
|
+
},
|
|
201
|
+
"type": "Symbol(react.suspense)",
|
|
202
|
+
}
|
|
203
|
+
`;
|
|
204
|
+
|
|
205
|
+
exports[`result.value > should show better error messages if legacy options are passed 1`] = `[Error: Tool definition in \`streamUI\` should not have \`render\` property. Use \`generate\` instead. Found in tool: tool1]`;
|
|
206
|
+
|
|
207
|
+
exports[`rsc - streamUI() onFinish callback > should contain final React node 1`] = `
|
|
208
|
+
<React.Suspense>
|
|
209
|
+
<Unknown
|
|
210
|
+
n={Promise {}}
|
|
211
|
+
/>
|
|
212
|
+
</React.Suspense>
|
|
213
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { streamUI } from './stream-ui';
|