inula/packages/inula-code-generator/inula-code-generator-web/frontend/components/generateCode.ts

119 lines
3.6 KiB
TypeScript

import toast from "react-hot-toast";
import { request } from './lib/request';
import { map } from 'lodash';
const textDecoder = new TextDecoder('utf-8');
const ERROR_MESSAGE =
"Error generating code. Feel free to open a Gitee issue.";
const STOP_MESSAGE = "Code generation stopped";
export interface CodeGenerationParams {
generationType: "create" | "update";
image?: string;
text?: string;
resultImage?: string;
history?: string[];
isChunk?: boolean;
partData?: any;
slug?: string;
components?: string[];
}
export function generateCode(
wsRef: React.MutableRefObject<AbortController | null>,
params: CodeGenerationParams,
onChange: (chunk: string) => void,
onSetCode: (code: string) => void,
onStatusUpdate: (status: string) => void,
onComplete: () => void,
onError: (error: string) => void,
) {
const handleError = (error: any) => {
if (error.name === 'AbortError') {
// 处理中止错误
console.error('Fetch aborted:', error);
} else {
// 处理其他错误
console.error('Fetch error:', error);
}
toast.error(ERROR_MESSAGE);
};
wsRef.current = new AbortController();
async function handleMessage(event: { data: string }) {
try {
const response = JSON.parse(event.data);
// console.log('response',response)
if (response.type === 'chunk') {
onChange(response.value);
} else if (response.type === 'status') {
onStatusUpdate(response.value);
} else if (response.type === 'setCode') {
onSetCode(response.value.replace('```jsx', '').replace('```', ''));
} else if (response.type === 'error') {
console.error('Error generating code', response.value);
onError(response.value);
toast.error(response.value);
}
} catch (e) {
console.log('aaa here')
console.log('EVENT', event, e);
}
}
wsRef.current.signal.addEventListener('abort', () => {
toast.success(STOP_MESSAGE);
onComplete();
});
try {
request
.post(
'/generateCode',
{
event: 'generatecode',
data: params,
},
{
responseType: 'stream',
fetch: (...args) => {
return fetch(...args);
},
}
)
.then(data => {
const reader = data.data.getReader();
const push = () => {
reader.read().then(({ done, value }: { done: boolean; value: Uint8Array }) => {
if (done) {
onComplete();
return;
}
map(textDecoder.decode(value).split('\n'), v => {
v &&
handleMessage({
data: v,
});
});
push();
});
};
push();
}, handleError)
.catch(error => {
if (error.name === 'AbortError') {
// 处理中止错误
console.error('Fetch aborted:', error);
} else {
// 处理其他错误
console.error('Fetch error:', error);
}
});
} catch (e) { }
}