|
|
|
@ -62,13 +62,12 @@ async function externalizeNodeImages( |
|
|
|
switch (node.type) { |
|
|
|
case "imageInput": { |
|
|
|
const d = data as import("@/types").ImageInputNodeData; |
|
|
|
if (isBase64DataUrl(d.image)) { |
|
|
|
// Skip if already has a valid imageRef (prevents duplicates on re-save after hydration)
|
|
|
|
if (d.imageRef && isBase64DataUrl(d.image)) { |
|
|
|
newData = { ...d, image: null }; |
|
|
|
} else if (isBase64DataUrl(d.image)) { |
|
|
|
const imageId = await saveImageAndGetId(d.image, workflowPath, savedImageIds, "inputs"); |
|
|
|
newData = { |
|
|
|
...d, |
|
|
|
image: null, |
|
|
|
imageRef: imageId, |
|
|
|
}; |
|
|
|
newData = { ...d, image: null, imageRef: imageId }; |
|
|
|
} else { |
|
|
|
newData = d; |
|
|
|
} |
|
|
|
@ -83,11 +82,16 @@ async function externalizeNodeImages( |
|
|
|
let outputImage = d.outputImage; |
|
|
|
|
|
|
|
// Annotation images are user-created, save to inputs
|
|
|
|
if (isBase64DataUrl(d.sourceImage)) { |
|
|
|
// Skip if already has ref (prevents duplicates on re-save after hydration)
|
|
|
|
if (d.sourceImageRef && isBase64DataUrl(d.sourceImage)) { |
|
|
|
sourceImage = null; |
|
|
|
} else if (isBase64DataUrl(d.sourceImage)) { |
|
|
|
sourceImageRef = await saveImageAndGetId(d.sourceImage, workflowPath, savedImageIds, "inputs"); |
|
|
|
sourceImage = null; |
|
|
|
} |
|
|
|
if (isBase64DataUrl(d.outputImage)) { |
|
|
|
if (d.outputImageRef && isBase64DataUrl(d.outputImage)) { |
|
|
|
outputImage = null; |
|
|
|
} else if (isBase64DataUrl(d.outputImage)) { |
|
|
|
outputImageRef = await saveImageAndGetId(d.outputImage, workflowPath, savedImageIds, "inputs"); |
|
|
|
outputImage = null; |
|
|
|
} |
|
|
|
@ -106,20 +110,28 @@ async function externalizeNodeImages( |
|
|
|
const d = data as import("@/types").NanoBananaNodeData; |
|
|
|
let outputImageRef = d.outputImageRef; |
|
|
|
let outputImage = d.outputImage; |
|
|
|
const inputImageRefs: string[] = []; |
|
|
|
let inputImageRefs = d.inputImageRefs ? [...d.inputImageRefs] : []; |
|
|
|
const inputImages: string[] = []; |
|
|
|
|
|
|
|
// Handle output image - AI generated, save to generations
|
|
|
|
if (isBase64DataUrl(d.outputImage)) { |
|
|
|
// Skip if already has ref (prevents duplicates on re-save after hydration)
|
|
|
|
if (d.outputImageRef && isBase64DataUrl(d.outputImage)) { |
|
|
|
outputImage = null; |
|
|
|
} else if (isBase64DataUrl(d.outputImage)) { |
|
|
|
outputImageRef = await saveImageAndGetId(d.outputImage, workflowPath, savedImageIds, "generations"); |
|
|
|
outputImage = null; |
|
|
|
} |
|
|
|
|
|
|
|
// Handle input images array (these come from connected nodes, save to inputs if present)
|
|
|
|
for (const img of d.inputImages) { |
|
|
|
if (isBase64DataUrl(img)) { |
|
|
|
// Skip if corresponding inputImageRef already exists
|
|
|
|
for (let i = 0; i < d.inputImages.length; i++) { |
|
|
|
const img = d.inputImages[i]; |
|
|
|
const existingRef = d.inputImageRefs?.[i]; |
|
|
|
if (existingRef && isBase64DataUrl(img)) { |
|
|
|
inputImages.push(""); // Already has ref, just clear the base64
|
|
|
|
} else if (isBase64DataUrl(img)) { |
|
|
|
const ref = await saveImageAndGetId(img, workflowPath, savedImageIds, "inputs"); |
|
|
|
inputImageRefs.push(ref); |
|
|
|
inputImageRefs[i] = ref; |
|
|
|
inputImages.push(""); // Empty placeholder
|
|
|
|
} else { |
|
|
|
inputImages.push(img); |
|
|
|
@ -138,14 +150,19 @@ async function externalizeNodeImages( |
|
|
|
|
|
|
|
case "llmGenerate": { |
|
|
|
const d = data as import("@/types").LLMGenerateNodeData; |
|
|
|
const inputImageRefs: string[] = []; |
|
|
|
let inputImageRefs = d.inputImageRefs ? [...d.inputImageRefs] : []; |
|
|
|
const inputImages: string[] = []; |
|
|
|
|
|
|
|
// Handle input images array (save to inputs)
|
|
|
|
for (const img of d.inputImages) { |
|
|
|
if (isBase64DataUrl(img)) { |
|
|
|
// Skip if corresponding inputImageRef already exists
|
|
|
|
for (let i = 0; i < d.inputImages.length; i++) { |
|
|
|
const img = d.inputImages[i]; |
|
|
|
const existingRef = d.inputImageRefs?.[i]; |
|
|
|
if (existingRef && isBase64DataUrl(img)) { |
|
|
|
inputImages.push(""); // Already has ref, just clear the base64
|
|
|
|
} else if (isBase64DataUrl(img)) { |
|
|
|
const ref = await saveImageAndGetId(img, workflowPath, savedImageIds, "inputs"); |
|
|
|
inputImageRefs.push(ref); |
|
|
|
inputImageRefs[i] = ref; |
|
|
|
inputImages.push(""); // Empty placeholder
|
|
|
|
} else { |
|
|
|
inputImages.push(img); |
|
|
|
@ -163,13 +180,12 @@ async function externalizeNodeImages( |
|
|
|
case "output": { |
|
|
|
const d = data as import("@/types").OutputNodeData; |
|
|
|
// Output displays generated content, save to generations
|
|
|
|
if (isBase64DataUrl(d.image)) { |
|
|
|
// Skip if already has ref (prevents duplicates on re-save after hydration)
|
|
|
|
if (d.imageRef && isBase64DataUrl(d.image)) { |
|
|
|
newData = { ...d, image: null }; |
|
|
|
} else if (isBase64DataUrl(d.image)) { |
|
|
|
const imageId = await saveImageAndGetId(d.image, workflowPath, savedImageIds, "generations"); |
|
|
|
newData = { |
|
|
|
...d, |
|
|
|
image: null, |
|
|
|
imageRef: imageId, |
|
|
|
}; |
|
|
|
newData = { ...d, image: null, imageRef: imageId }; |
|
|
|
} else { |
|
|
|
newData = d; |
|
|
|
} |
|
|
|
@ -179,13 +195,12 @@ async function externalizeNodeImages( |
|
|
|
case "splitGrid": { |
|
|
|
const d = data as import("@/types").SplitGridNodeData; |
|
|
|
// SplitGrid source is input content, save to inputs
|
|
|
|
if (isBase64DataUrl(d.sourceImage)) { |
|
|
|
// Skip if already has ref (prevents duplicates on re-save after hydration)
|
|
|
|
if (d.sourceImageRef && isBase64DataUrl(d.sourceImage)) { |
|
|
|
newData = { ...d, sourceImage: null }; |
|
|
|
} else if (isBase64DataUrl(d.sourceImage)) { |
|
|
|
const imageId = await saveImageAndGetId(d.sourceImage, workflowPath, savedImageIds, "inputs"); |
|
|
|
newData = { |
|
|
|
...d, |
|
|
|
sourceImage: null, |
|
|
|
sourceImageRef: imageId, |
|
|
|
}; |
|
|
|
newData = { ...d, sourceImage: null, sourceImageRef: imageId }; |
|
|
|
} else { |
|
|
|
newData = d; |
|
|
|
} |
|
|
|
|