Skip to content

Commit 3f8d894

Browse files
committed
feat: add runner syncing, simplify generation selection and stream handling
1 parent d601558 commit 3f8d894

File tree

3 files changed

+49
-32
lines changed

3 files changed

+49
-32
lines changed

packages/giselle/src/react/generations/generate-content-runner.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ export function GenerateContentRunner({
6161
const upsertMessage = useGenerationStore((s) => s.upsertMessage);
6262
const updateGeneration = useGenerationStore((s) => s.updateGeneration);
6363
const { updateGenerationStatusToComplete } = useGenerationRunnerSystem();
64-
const didRun = useRef(false);
64+
const didPerformingContentGeneration = useRef(false);
65+
const didListeningContentGeneration = useRef(false);
6566
const reachedStreamEnd = useRef(false);
6667
const messageUpdateQueue = useRef<Map<UIMessage["id"], UIMessage>>(new Map());
6768
const pendingUpdate = useRef<number | null>(null);
@@ -160,20 +161,32 @@ export function GenerateContentRunner({
160161
]);
161162

162163
useEffect(() => {
163-
if (didRun.current) {
164+
if (didPerformingContentGeneration.current) {
164165
return;
165166
}
166167
if (generation.status !== "queued") {
167168
return;
168169
}
169-
didRun.current = true;
170+
didPerformingContentGeneration.current = true;
170171
client
171172
.startContentGeneration({ generation })
172173
.then(({ generation: runningGeneration }) => {
173174
onStart?.(runningGeneration);
174175
updateGeneration(runningGeneration);
175-
processStream();
176176
});
177-
}, [generation, client, processStream, updateGeneration, onStart]);
177+
}, [generation, client, updateGeneration, onStart]);
178+
179+
useEffect(() => {
180+
if (didListeningContentGeneration.current) {
181+
return;
182+
}
183+
if (generation.status !== "running") {
184+
return;
185+
}
186+
didListeningContentGeneration.current = true;
187+
188+
processStream();
189+
}, [generation, processStream]);
190+
178191
return null;
179192
}

packages/giselle/src/react/generations/hooks/use-node-generations.ts

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { NodeId } from "@giselle-sdk/data-type";
2-
import { useCallback, useMemo } from "react";
2+
import { useCallback, useEffect, useMemo } from "react";
33
import useSWR from "swr";
44
import { useShallow } from "zustand/shallow";
55
import type {
@@ -30,12 +30,13 @@ export function useNodeGenerations({
3030
startGenerationRunner,
3131
createAndStartGenerationRunner,
3232
stopGenerationRunner: stopGenerationSystem,
33+
addGenerationRunner,
3334
} = useGenerationRunnerSystem();
3435
const client = useGiselleEngine();
3536
const { experimental_storage } = useFeatureFlag();
3637

3738
/** @todo fetch on server */
38-
const { data } = useSWR(
39+
const { data, isLoading } = useSWR(
3940
{
4041
api: "node-generations",
4142
origin,
@@ -49,35 +50,34 @@ export function useNodeGenerations({
4950
revalidateOnReconnect: false,
5051
},
5152
);
53+
54+
useEffect(() => {
55+
if (isLoading || data === undefined) {
56+
return;
57+
}
58+
console.log(data);
59+
addGenerationRunner(data);
60+
}, [isLoading, data, addGenerationRunner]);
61+
5262
const currentGeneration = useMemo<Generation>(() => {
53-
const fetchGenerations = data ?? [];
54-
const createdGenerations = generations.filter(
55-
(generation) =>
56-
generation.context.operationNode.id === nodeId &&
57-
generation.context.origin.type === origin.type &&
58-
(origin.type === "studio"
59-
? generation.context.origin.type === "studio" &&
60-
generation.context.origin.workspaceId === origin.workspaceId
61-
: generation.context.origin.type !== "studio" &&
62-
generation.context.origin.actId === origin.actId),
63-
);
64-
// Deduplicate generations by filtering out fetched generations from created ones
65-
const deduplicatedCreatedGenerations = createdGenerations.filter(
66-
(created) =>
67-
!fetchGenerations.some((fetched) => fetched.id === created.id),
68-
);
69-
// Filter out cancelled generations from both sources after deduplication
70-
const allGenerations = [
71-
...fetchGenerations,
72-
...deduplicatedCreatedGenerations,
73-
]
74-
.filter((generation) => generation.status !== "cancelled")
63+
const filteredGenerations = generations
64+
.filter(
65+
(generation) =>
66+
generation.status !== "cancelled" &&
67+
generation.context.operationNode.id === nodeId &&
68+
generation.context.origin.type === origin.type &&
69+
(origin.type === "studio"
70+
? generation.context.origin.type === "studio" &&
71+
generation.context.origin.workspaceId === origin.workspaceId
72+
: generation.context.origin.type !== "studio" &&
73+
generation.context.origin.actId === origin.actId),
74+
)
7575
.sort(
7676
(a, b) =>
7777
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
7878
);
79-
return allGenerations[0];
80-
}, [generations, data, nodeId, origin]);
79+
return filteredGenerations[0];
80+
}, [generations, nodeId, origin]);
8181

8282
const isGenerating = useMemo(
8383
() =>

packages/giselle/src/react/generations/store.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ export const useGenerationStore = create<GenerationStore>((set) => ({
2424
addGenerationRunner: (generations) =>
2525
set((state) => {
2626
const arr = Array.isArray(generations) ? generations : [generations];
27+
const incomingIds = new Set(arr.map((g) => g.id));
28+
const filteredExisting = state.generations.filter(
29+
(g) => !incomingIds.has(g.id),
30+
);
2731
return {
28-
generations: [...state.generations, ...arr],
32+
generations: [...filteredExisting, ...arr],
2933
};
3034
}),
3135
updateGeneration: (generation) =>

0 commit comments

Comments
 (0)