| 1 |
import { AI_HOST } from '@constants'; |
| 2 |
import { reqDataBasics } from '@shared/lib/data'; |
| 3 |
import { retryTwice } from './helpers'; |
| 4 |
|
| 5 |
const generatePatterns = async (page, data) => { |
| 6 |
const { siteProfile } = data; |
| 7 |
return await retryTwice(async () => { |
| 8 |
const response = await fetch(`${AI_HOST}/api/patterns`, { |
| 9 |
method: 'POST', |
| 10 |
headers: { 'Content-Type': 'application/json' }, |
| 11 |
body: JSON.stringify({ ...reqDataBasics, siteProfile, page }), |
| 12 |
}); |
| 13 |
if (!response.ok) { |
| 14 |
throw new Error( |
| 15 |
`Pattern generation failed with status ${response.status}`, |
| 16 |
); |
| 17 |
} |
| 18 |
return await response.json(); |
| 19 |
}); |
| 20 |
}; |
| 21 |
|
| 22 |
// Hold back patterns that already have finalized content (e.g. design build) |
| 23 |
const splitGeneratedContent = (page) => { |
| 24 |
const generated = page.patterns?.filter((p) => p.contentGenerated) ?? []; |
| 25 |
const rest = page.patterns?.filter((p) => !p.contentGenerated) ?? []; |
| 26 |
return { generated, toGenerate: { ...page, patterns: rest } }; |
| 27 |
}; |
| 28 |
|
| 29 |
export const generatePageContent = async (pages, data) => { |
| 30 |
const splits = pages.map(splitGeneratedContent); |
| 31 |
|
| 32 |
const result = await Promise.allSettled( |
| 33 |
splits.map( |
| 34 |
({ toGenerate }) => |
| 35 |
generatePatterns(toGenerate, data) |
| 36 |
.then((response) => response) |
| 37 |
.catch(() => toGenerate), // safe fallback |
| 38 |
), |
| 39 |
); |
| 40 |
|
| 41 |
return result?.map((pageResult, i) => { |
| 42 |
const original = pages[i]; |
| 43 |
const { generated } = splits[i]; |
| 44 |
const merged = |
| 45 |
pageResult.status === 'fulfilled' && pageResult.value |
| 46 |
? { ...original, ...pageResult.value } |
| 47 |
: original; |
| 48 |
return { |
| 49 |
...merged, |
| 50 |
patterns: [...generated, ...(merged.patterns ?? [])], |
| 51 |
}; |
| 52 |
}); |
| 53 |
}; |
| 54 |
|