From d1e792686e2633eb72586ff24e52dae361f6fa81 Mon Sep 17 00:00:00 2001 From: caranicas Date: Fri, 23 Sep 2022 13:31:56 -0400 Subject: [PATCH] added some options to test --- .../build_src/src/api/hooks/asyncGenerator.ts | 28 +++++++ .../build_src/src/api/hooks/callbackQuery.ts | 21 +++++ .../build_src/src/api/hooks/eventSource.ts | 19 +++++ .../src/api/hooks/infiniteEventSource.ts | 47 +++++++++++ .../basicCreation/makeButton/index.tsx | 77 ++++++++++++++++--- 5 files changed, 182 insertions(+), 10 deletions(-) create mode 100644 ui/frontend/build_src/src/api/hooks/asyncGenerator.ts create mode 100644 ui/frontend/build_src/src/api/hooks/callbackQuery.ts create mode 100644 ui/frontend/build_src/src/api/hooks/eventSource.ts create mode 100644 ui/frontend/build_src/src/api/hooks/infiniteEventSource.ts diff --git a/ui/frontend/build_src/src/api/hooks/asyncGenerator.ts b/ui/frontend/build_src/src/api/hooks/asyncGenerator.ts new file mode 100644 index 00000000..8de487d2 --- /dev/null +++ b/ui/frontend/build_src/src/api/hooks/asyncGenerator.ts @@ -0,0 +1,28 @@ +import { useInfiniteQuery } from "@tanstack/react-query"; + +export const useAyncGeneratorQuery = (key: string, asyncGeneratorFn: () => Generator) => { + + const queryFn = React.useCallback((_: any, params: CustomQueryParams) => { + if (!params) { return Promise.resolve([]) } + return Promise.resolve(params.eventData); + }, []) + + const { data, fetchMore } = useInfiniteQuery(key, queryFn as any, { getFetchMore: () => ({ eventData: [] }) }) + + const customStatus = React.useRef('success'); + + React.useEffect(() => { + (async function doReceive() { + try { + for await (let data of asyncGeneratorFn()) { + fetchMore({ eventData: data }); + } + } catch (e) { + customStatus.current = 'error'; + } + })(); + + }, [asyncGeneratorFn, fetchMore]) + + return { status: customStatus.current, data }; +} \ No newline at end of file diff --git a/ui/frontend/build_src/src/api/hooks/callbackQuery.ts b/ui/frontend/build_src/src/api/hooks/callbackQuery.ts new file mode 100644 index 00000000..61fc3696 --- /dev/null +++ b/ui/frontend/build_src/src/api/hooks/callbackQuery.ts @@ -0,0 +1,21 @@ +type CallbackType = (data: string[]) => void; + +type InitCallbackType = (cb: CallbackType) => void; + +export const useCallbackQuery = (key: string, initCallbackQuery: InitCallbackType) => { + + const queryFn = React.useCallback((_: any, params: CustomQueryParams) => { + if (!params) { return Promise.resolve([]) } + return Promise.resolve(params.eventData); + }, []) + + const { data, fetchMore } = useInfiniteQuery(key, queryFn as any, { getFetchMore: () => ({ eventData: [] }) }) + + const callback = React.useCallback((data) => { fetchMore({ eventData: data }) }, [fetchMore]); + + React.useEffect(() => { initCallbackQuery(callback); }, [callback, initCallbackQuery]) + + const customStatus = React.useRef('success'); + + return { status: customStatus.current, data }; +} \ No newline at end of file diff --git a/ui/frontend/build_src/src/api/hooks/eventSource.ts b/ui/frontend/build_src/src/api/hooks/eventSource.ts new file mode 100644 index 00000000..510272dc --- /dev/null +++ b/ui/frontend/build_src/src/api/hooks/eventSource.ts @@ -0,0 +1,19 @@ +import { useQuery, useQueryClient } from 'react-query' + +export const useEventSourceQuery = (queryKey, url, eventName) => { + const queryClient = useQueryClient() + + const fetchData = () => { + const evtSource = new EventSource(url) + + evtSource.addEventListener(eventName, (event) => { + const eventData = event.data && JSON.parse(event.data) + + if (eventData) { + queryClient.setQueryData(queryKey, eventData) + } + }) + } + + return useQuery(queryKey, fetchData) +} \ No newline at end of file diff --git a/ui/frontend/build_src/src/api/hooks/infiniteEventSource.ts b/ui/frontend/build_src/src/api/hooks/infiniteEventSource.ts new file mode 100644 index 00000000..bea8a59b --- /dev/null +++ b/ui/frontend/build_src/src/api/hooks/infiniteEventSource.ts @@ -0,0 +1,47 @@ + +import * as React from 'react'; +import { useInfiniteQuery } from 'react-query'; + +interface CustomQueryParams { + eventData: string[]; +} + +type Status = "success" | "loading" | "error"; + +export const useEventSourceQuery = (key: string, url: string, eventName: string) => { + + const eventSource = React.useRef(new EventSource(url)); + + const queryFn = React.useCallback((_: any, params: CustomQueryParams) => { + if (!params) { return Promise.resolve([]) } + return Promise.resolve(params.eventData); + }, []) + + const { data, fetchMore } = useInfiniteQuery(key, queryFn as any, { getFetchMore: () => ({ eventData: [] }) }) + + const customStatus = React.useRef('success'); + + React.useEffect(() => { + const evtSource = eventSource.current; + + const onEvent = function (ev: MessageEvent | Event) { + if (!e.data) { + return; + } + // Let's assume here we receive multiple data, ie. e.data is an array. + fetchMore({ eventData: e.data }); + } + const onError = () => { customStatus.current = 'error' }; + + evtSource.addEventListener(eventName, onEvent); + evtSource.addEventListener('error', onError); + + return () => { + evtSource.removeEventListener(eventName, onEvent); + evtSource.removeEventListener('error', onError); + } + + }, [url, eventName, fetchMore]) + + return { status: customStatus.current, data }; +} \ No newline at end of file diff --git a/ui/frontend/build_src/src/components/organisms/creationPanel/basicCreation/makeButton/index.tsx b/ui/frontend/build_src/src/components/organisms/creationPanel/basicCreation/makeButton/index.tsx index a6997ec9..90da7659 100644 --- a/ui/frontend/build_src/src/components/organisms/creationPanel/basicCreation/makeButton/index.tsx +++ b/ui/frontend/build_src/src/components/organisms/creationPanel/basicCreation/makeButton/index.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import React from "react"; -import { useImageCreate } from "../../../../../stores/imageCreateStore"; +import { useImageCreate, ImageRequest } from "../../../../../stores/imageCreateStore"; import { useImageQueue } from "../../../../../stores/imageQueueStore"; import { v4 as uuidv4 } from "uuid"; @@ -23,15 +23,20 @@ export default function MakeButton() { const isRandomSeed = useImageCreate((state) => state.isRandomSeed()); const setRequestOption = useImageCreate((state) => state.setRequestOptions); - const makeImages = () => { - // potentially update the seed - if (isRandomSeed) { - // update the seed for the next time we click the button - setRequestOption("seed", useRandomSeed()); - } + // const makeImages = () => { + // // potentially update the seed + // if (isRandomSeed) { + // // update the seed for the next time we click the button + // setRequestOption("seed", useRandomSeed()); + // } + + // // the request that we have built + // const req = builtRequest(); + + // }; + + const queueImageRequest = (req: ImageRequest) => { - // the request that we have built - const req = builtRequest(); // the actual number of request we will make const requests = []; // the number of images we will make @@ -63,7 +68,6 @@ export default function MakeButton() { // get the seed we want to use let seed = req.seed; if (index !== 0) { - debugger; // we want to use a random seed for subsequent requests seed = useRandomSeed(); } @@ -76,8 +80,61 @@ export default function MakeButton() { seed, }); }); + } + + const testStream = async (req: ImageRequest) => { + + const streamReq = { + ...req, + stream_progress_updates: true, + // stream_image_progress: false, + session_id: uuidv4(), + }; + + console.log("testStream", streamReq); + try { + const res = await fetch('http://localhost:9000/image', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(streamReq) + }); + + console.log('res', res); + const reader = res.body.getReader(); + const decoder = new TextDecoder(); + while (true) { + const { done, value } = await reader.read(); + if (done) { + break; + } + const text = decoder.decode(value); + console.log(text); + } + } catch (e) { + console.log(e); + debugger; + } + + } + + const makeImages = () => { + // potentially update the seed + if (isRandomSeed) { + // update the seed for the next time we click the button + setRequestOption("seed", useRandomSeed()); + } + + // the request that we have built + const req = builtRequest(); + + //queueImageRequest(req); + void testStream(req); + }; + return (