|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | import axios from 'axios'; | 
					
						
						|  | import config from '../../config.js'; | 
					
						
						|  | import { generateId } from '../utils/idGenerator.js'; | 
					
						
						|  | import { | 
					
						
						|  | getStorage, | 
					
						
						|  | setStorage, | 
					
						
						|  | getActiveGeneration, | 
					
						
						|  | setActiveGeneration, | 
					
						
						|  | deleteActiveGeneration | 
					
						
						|  | } from './storageManager.js'; | 
					
						
						|  | import { | 
					
						
						|  | sendToSession | 
					
						
						|  | } from './websocketManager.js'; | 
					
						
						|  |  | 
					
						
						|  | const updateProgress = (sessionId, progress) => { | 
					
						
						|  | const data = getStorage(sessionId); | 
					
						
						|  | if (data) { | 
					
						
						|  | data.progress = progress; | 
					
						
						|  | setStorage(sessionId, data); | 
					
						
						|  |  | 
					
						
						|  | sendToSession(sessionId, { | 
					
						
						|  | type: 'progressUpdate', | 
					
						
						|  | progress | 
					
						
						|  | }); | 
					
						
						|  | } | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  | const createProgressUpdater = (sessionId) => { | 
					
						
						|  | return setInterval(() => { | 
					
						
						|  | const data = getStorage(sessionId); | 
					
						
						|  | if (data && | 
					
						
						|  | data.isGenerating && | 
					
						
						|  | data.progress < config.generation.maxProgress) { | 
					
						
						|  | const increment = Math.random() * 8; | 
					
						
						|  | const newProgress = Math.min( | 
					
						
						|  | config.generation.maxProgress, | 
					
						
						|  | data.progress + increment | 
					
						
						|  | ); | 
					
						
						|  | updateProgress(sessionId, newProgress); | 
					
						
						|  | } | 
					
						
						|  | }, config.generation.progressInterval); | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  | const createImageObject = ( | 
					
						
						|  | base64Data, | 
					
						
						|  | prompt, | 
					
						
						|  | model, | 
					
						
						|  | size | 
					
						
						|  | ) => ({ | 
					
						
						|  | id: generateId(), | 
					
						
						|  | base64: base64Data, | 
					
						
						|  | prompt, | 
					
						
						|  | model, | 
					
						
						|  | size | 
					
						
						|  | }); | 
					
						
						|  |  | 
					
						
						|  | const callImageApi = async ( | 
					
						
						|  | prompt, | 
					
						
						|  | model, | 
					
						
						|  | size, | 
					
						
						|  | signal | 
					
						
						|  | ) => { | 
					
						
						|  | return await axios.post( | 
					
						
						|  | config.api.baseUrl, | 
					
						
						|  | { | 
					
						
						|  | model, | 
					
						
						|  | prompt, | 
					
						
						|  | size, | 
					
						
						|  | response_format: 'b64_json', | 
					
						
						|  | n: 1 | 
					
						
						|  | }, | 
					
						
						|  | { | 
					
						
						|  | headers: { | 
					
						
						|  | 'Authorization': `Bearer ${config.api.key}`, | 
					
						
						|  | 'Content-Type': 'application/json' | 
					
						
						|  | }, | 
					
						
						|  | signal, | 
					
						
						|  | timeout: config.api.timeout, | 
					
						
						|  | maxBodyLength: config.limits.maxContentLength, | 
					
						
						|  | maxContentLength: config.limits.maxContentLength | 
					
						
						|  | } | 
					
						
						|  | ); | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  | export const generateImage = async ( | 
					
						
						|  | sessionId, | 
					
						
						|  | prompt, | 
					
						
						|  | model, | 
					
						
						|  | size | 
					
						
						|  | ) => { | 
					
						
						|  | const controller = new AbortController(); | 
					
						
						|  | setActiveGeneration(sessionId, controller); | 
					
						
						|  |  | 
					
						
						|  | const progressInterval = createProgressUpdater(sessionId); | 
					
						
						|  |  | 
					
						
						|  | setTimeout(async () => { | 
					
						
						|  | try { | 
					
						
						|  | const response = await callImageApi( | 
					
						
						|  | prompt, | 
					
						
						|  | model, | 
					
						
						|  | size, | 
					
						
						|  | controller.signal | 
					
						
						|  | ); | 
					
						
						|  |  | 
					
						
						|  | const data = getStorage(sessionId); | 
					
						
						|  | if (!data) return; | 
					
						
						|  |  | 
					
						
						|  | updateProgress( | 
					
						
						|  | sessionId, | 
					
						
						|  | config.generation.maxProgress | 
					
						
						|  | ); | 
					
						
						|  |  | 
					
						
						|  | if (response.data?.data?.length > 0) { | 
					
						
						|  | const base64 = response.data.data[0].b64_json; | 
					
						
						|  | const newImage = createImageObject( | 
					
						
						|  | base64, | 
					
						
						|  | prompt, | 
					
						
						|  | model, | 
					
						
						|  | size | 
					
						
						|  | ); | 
					
						
						|  |  | 
					
						
						|  | data.images.unshift(newImage); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | data.isGenerating = false; | 
					
						
						|  | data.progress = 0; | 
					
						
						|  | setStorage(sessionId, data); | 
					
						
						|  |  | 
					
						
						|  | sendToSession(sessionId, { | 
					
						
						|  | type: 'generationComplete', | 
					
						
						|  | images: data.images | 
					
						
						|  | }); | 
					
						
						|  |  | 
					
						
						|  | } catch (error) { | 
					
						
						|  | const data = getStorage(sessionId); | 
					
						
						|  | if (!data) return; | 
					
						
						|  |  | 
					
						
						|  | if (error.name !== 'CanceledError' && | 
					
						
						|  | error.code !== 'ERR_CANCELED') { | 
					
						
						|  | data.error = | 
					
						
						|  | `The request to the ${model} model was ` + | 
					
						
						|  | `unsuccessful, possibly due to high ` + | 
					
						
						|  | `server load. Please try again later.`; | 
					
						
						|  |  | 
					
						
						|  | sendToSession(sessionId, { | 
					
						
						|  | type: 'generationError', | 
					
						
						|  | error: data.error | 
					
						
						|  | }); | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | data.isGenerating = false; | 
					
						
						|  | data.progress = 0; | 
					
						
						|  | setStorage(sessionId, data); | 
					
						
						|  |  | 
					
						
						|  | } finally { | 
					
						
						|  | clearInterval(progressInterval); | 
					
						
						|  | deleteActiveGeneration(sessionId); | 
					
						
						|  | } | 
					
						
						|  | }, config.generation.startDelay); | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  | export const cancelGeneration = (sessionId) => { | 
					
						
						|  | const controller = getActiveGeneration(sessionId); | 
					
						
						|  | if (controller) { | 
					
						
						|  | controller.abort(); | 
					
						
						|  | deleteActiveGeneration(sessionId); | 
					
						
						|  |  | 
					
						
						|  | const data = getStorage(sessionId); | 
					
						
						|  | if (data) { | 
					
						
						|  | data.isGenerating = false; | 
					
						
						|  | data.progress = 0; | 
					
						
						|  | setStorage(sessionId, data); | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  | }; |