use-vibes 0.4.0 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/components/ControlsBar.d.ts +32 -0
- package/dist/components/ControlsBar.js +80 -0
- package/dist/components/ControlsBar.js.map +1 -0
- package/dist/components/ImgGen.css +523 -0
- package/dist/components/ImgGen.d.ts +36 -0
- package/dist/components/ImgGen.js +206 -0
- package/dist/components/ImgGen.js.map +1 -0
- package/dist/components/ImgGenUtils/ImgGenDisplay.d.ts +3 -0
- package/dist/components/ImgGenUtils/ImgGenDisplay.js +251 -0
- package/dist/components/ImgGenUtils/ImgGenDisplay.js.map +1 -0
- package/dist/components/ImgGenUtils/ImgGenDisplayPlaceholder.d.ts +3 -0
- package/dist/components/ImgGenUtils/ImgGenDisplayPlaceholder.js +115 -0
- package/dist/components/ImgGenUtils/ImgGenDisplayPlaceholder.js.map +1 -0
- package/dist/components/ImgGenUtils/ImgGenDisplayUtils.d.ts +44 -0
- package/dist/components/ImgGenUtils/ImgGenDisplayUtils.js +127 -0
- package/dist/components/ImgGenUtils/ImgGenDisplayUtils.js.map +1 -0
- package/dist/components/ImgGenUtils/ImgGenError.d.ts +3 -0
- package/dist/components/ImgGenUtils/ImgGenError.js +9 -0
- package/dist/components/ImgGenUtils/ImgGenError.js.map +1 -0
- package/dist/components/ImgGenUtils/ImgGenModal.d.ts +31 -0
- package/dist/components/ImgGenUtils/ImgGenModal.js +31 -0
- package/dist/components/ImgGenUtils/ImgGenModal.js.map +1 -0
- package/dist/components/ImgGenUtils/ImgGenPromptWaiting.d.ts +7 -0
- package/dist/components/ImgGenUtils/ImgGenPromptWaiting.js +8 -0
- package/dist/components/ImgGenUtils/ImgGenPromptWaiting.js.map +1 -0
- package/dist/components/ImgGenUtils/index.d.ts +5 -0
- package/dist/components/ImgGenUtils/index.js +8 -0
- package/dist/components/ImgGenUtils/index.js.map +1 -0
- package/dist/components/ImgGenUtils/overlays/DeleteConfirmationOverlay.d.ts +10 -0
- package/dist/components/ImgGenUtils/overlays/DeleteConfirmationOverlay.js +32 -0
- package/dist/components/ImgGenUtils/overlays/DeleteConfirmationOverlay.js.map +1 -0
- package/dist/components/ImgGenUtils/overlays/ImageOverlay.d.ts +29 -0
- package/dist/components/ImgGenUtils/overlays/ImageOverlay.js +11 -0
- package/dist/components/ImgGenUtils/overlays/ImageOverlay.js.map +1 -0
- package/dist/components/ImgGenUtils/types.d.ts +37 -0
- package/dist/components/ImgGenUtils/types.js +2 -0
- package/dist/components/ImgGenUtils/types.js.map +1 -0
- package/dist/components/ImgGenUtils.d.ts +6 -0
- package/dist/components/ImgGenUtils.js +7 -0
- package/dist/components/ImgGenUtils.js.map +1 -0
- package/dist/components/PromptBar.d.ts +15 -0
- package/dist/components/PromptBar.js +23 -0
- package/dist/components/PromptBar.js.map +1 -0
- package/dist/hooks/image-gen/image-generator.d.ts +14 -0
- package/dist/hooks/image-gen/image-generator.js +78 -0
- package/dist/hooks/image-gen/image-generator.js.map +1 -0
- package/dist/hooks/image-gen/index.d.ts +6 -0
- package/dist/hooks/image-gen/index.js +6 -0
- package/dist/hooks/image-gen/index.js.map +1 -0
- package/dist/hooks/image-gen/types.d.ts +75 -0
- package/dist/hooks/image-gen/types.js +2 -0
- package/dist/hooks/image-gen/types.js.map +1 -0
- package/dist/hooks/image-gen/use-image-gen.d.ts +12 -0
- package/dist/hooks/image-gen/use-image-gen.js +573 -0
- package/dist/hooks/image-gen/use-image-gen.js.map +1 -0
- package/dist/hooks/image-gen/utils.d.ts +61 -0
- package/dist/hooks/image-gen/utils.js +241 -0
- package/dist/hooks/image-gen/utils.js.map +1 -0
- package/dist/hooks/use-image-gen.d.ts +5 -0
- package/dist/hooks/use-image-gen.js +7 -0
- package/dist/hooks/use-image-gen.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/style-loader.d.ts +16 -0
- package/dist/style-loader.js +43 -0
- package/dist/style-loader.js.map +1 -0
- package/dist/utils/style-utils.d.ts +51 -0
- package/dist/utils/style-utils.js +42 -0
- package/dist/utils/style-utils.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
import { useFireproof } from 'use-fireproof';
|
|
3
|
+
import { hashInput, base64ToFile, addNewVersion, getVersionsFromDocument, getPromptsFromDocument, MODULE_STATE, cleanupRequestKey, getRelevantOptions, generateSafeFilename, } from './utils';
|
|
4
|
+
import { createImageGenerator } from './image-generator';
|
|
5
|
+
/**
|
|
6
|
+
* Hook for generating images with call-ai's imageGen
|
|
7
|
+
* Provides automatic caching, reactive updates, and progress handling
|
|
8
|
+
*
|
|
9
|
+
* The hook allows for two modes of operation:
|
|
10
|
+
* 1. Generate a new image with a prompt (no _id provided)
|
|
11
|
+
* 2. Load or update an existing image document (_id provided)
|
|
12
|
+
*/
|
|
13
|
+
export function useImageGen({ prompt, _id, options = {}, database = 'ImgGen', skip = false, // Skip processing flag
|
|
14
|
+
generationId, // Unique ID that changes for each new generation request
|
|
15
|
+
editedPrompt, // Optional edited prompt that should override the document prompt on regeneration
|
|
16
|
+
}) {
|
|
17
|
+
// If both are provided, _id takes precedence
|
|
18
|
+
// This silently prioritizes the document's internal prompt
|
|
19
|
+
const [imageData, setImageData] = useState(null);
|
|
20
|
+
const [loading, setLoading] = useState(false);
|
|
21
|
+
const [progress, setProgress] = useState(0);
|
|
22
|
+
const [error, setError] = useState(null);
|
|
23
|
+
const [document, setDocument] = useState(null);
|
|
24
|
+
const progressTimerRef = useRef(null);
|
|
25
|
+
// Initialize Fireproof database
|
|
26
|
+
const { database: db } = useFireproof(database);
|
|
27
|
+
const size = options?.size || '1024x1024';
|
|
28
|
+
const [width, height] = size.split('x').map(Number);
|
|
29
|
+
// Memoize options to prevent unnecessary re-renders and regeneration
|
|
30
|
+
const memoizedOptions = useMemo(() => ({
|
|
31
|
+
size: options?.size,
|
|
32
|
+
quality: options?.quality,
|
|
33
|
+
model: options?.model,
|
|
34
|
+
style: options?.style,
|
|
35
|
+
}), [options?.size, options?.quality, options?.model, options?.style]);
|
|
36
|
+
// Store reference to previous options to detect changes
|
|
37
|
+
const prevOptionsRef = useRef(getRelevantOptions({}));
|
|
38
|
+
// Determine if we should include options in generation ID based on regeneration flag
|
|
39
|
+
const shouldConsiderOptions = useMemo(() => !generationId, [generationId]);
|
|
40
|
+
// Create a unique request ID for loading by ID or new generation
|
|
41
|
+
// For regeneration requests, we exclude options from the hash to prevent unwanted regeneration
|
|
42
|
+
const requestId = useMemo(() => {
|
|
43
|
+
return hashInput(prompt || _id || 'unknown', shouldConsiderOptions ? memoizedOptions : undefined);
|
|
44
|
+
}, [prompt, _id, shouldConsiderOptions, memoizedOptions]);
|
|
45
|
+
// Track ID and generation state changes
|
|
46
|
+
const previousIdRef = useRef(_id);
|
|
47
|
+
const previousGenerationIdRef = useRef(generationId);
|
|
48
|
+
// Reset state when prompt, _id, or generationId changes
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
// Keep track of whether _id has changed
|
|
51
|
+
const idChanged = _id !== previousIdRef.current;
|
|
52
|
+
// Detect when generationId changes - this indicates a request for regeneration
|
|
53
|
+
const generationRequested = generationId !== previousGenerationIdRef.current;
|
|
54
|
+
// Update refs for next check
|
|
55
|
+
previousIdRef.current = _id;
|
|
56
|
+
previousGenerationIdRef.current = generationId;
|
|
57
|
+
// Only proceed with state resets when needed
|
|
58
|
+
if (idChanged || generationRequested) {
|
|
59
|
+
// Reset all state when inputs change
|
|
60
|
+
setImageData(null);
|
|
61
|
+
setError(null);
|
|
62
|
+
setProgress(0);
|
|
63
|
+
// Clear document state when ID changes
|
|
64
|
+
// This ensures a clean start when navigating to a new document
|
|
65
|
+
if (idChanged) {
|
|
66
|
+
setDocument(null);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Clear any existing progress timer
|
|
70
|
+
if (progressTimerRef.current) {
|
|
71
|
+
clearInterval(progressTimerRef.current);
|
|
72
|
+
progressTimerRef.current = null;
|
|
73
|
+
}
|
|
74
|
+
// Cleanup on unmount or when dependencies change
|
|
75
|
+
return () => {
|
|
76
|
+
if (progressTimerRef.current) {
|
|
77
|
+
clearInterval(progressTimerRef.current);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}, [prompt, _id, memoizedOptions]); // Dependencies that require state reset
|
|
81
|
+
// Track the last request parameters to prevent duplicate requests
|
|
82
|
+
const lastRequestRef = useRef('');
|
|
83
|
+
// Generate the image when prompt or options change or load by ID
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
let isMounted = true;
|
|
86
|
+
// Skip processing if explicitly told to or if both prompt and _id are falsy
|
|
87
|
+
if (skip || (!prompt && !_id)) {
|
|
88
|
+
setLoading(false);
|
|
89
|
+
if (!skip) {
|
|
90
|
+
setError(new Error('Either prompt or _id must be provided'));
|
|
91
|
+
}
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
// Create a request signature to deduplicate identical requests
|
|
95
|
+
const requestSignature = JSON.stringify({
|
|
96
|
+
prompt,
|
|
97
|
+
_id,
|
|
98
|
+
generationId,
|
|
99
|
+
options: shouldConsiderOptions ? getRelevantOptions(memoizedOptions) : undefined,
|
|
100
|
+
});
|
|
101
|
+
// Prevent duplicate requests with identical parameters
|
|
102
|
+
if (requestSignature === lastRequestRef.current && document) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Update the last request signature
|
|
106
|
+
lastRequestRef.current = requestSignature;
|
|
107
|
+
// Check if only options have changed and we have an existing document
|
|
108
|
+
const currentRelevantOptions = getRelevantOptions(memoizedOptions);
|
|
109
|
+
const previousRelevantOptions = prevOptionsRef.current;
|
|
110
|
+
const optionsChanged = JSON.stringify(currentRelevantOptions) !== JSON.stringify(previousRelevantOptions);
|
|
111
|
+
// When only options change and we aren't explicitly regenerating,
|
|
112
|
+
// skip regeneration for existing documents to prevent duplicate generations
|
|
113
|
+
if (optionsChanged && !generationId && document?._id) {
|
|
114
|
+
// Update our reference without triggering regeneration
|
|
115
|
+
prevOptionsRef.current = currentRelevantOptions;
|
|
116
|
+
setLoading(false);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Track current options for future comparison
|
|
120
|
+
prevOptionsRef.current = currentRelevantOptions;
|
|
121
|
+
setLoading(true);
|
|
122
|
+
setProgress(0);
|
|
123
|
+
setError(null);
|
|
124
|
+
// Create a generator function with the current request ID
|
|
125
|
+
const callImageGeneration = createImageGenerator(requestId);
|
|
126
|
+
// Main function that handles the image loading/generation process
|
|
127
|
+
const loadOrGenerateImage = async () => {
|
|
128
|
+
try {
|
|
129
|
+
// Start the progress animation only when loading starts
|
|
130
|
+
// Set up progress timer simulation (45 seconds to completion)
|
|
131
|
+
// This is just for visual feedback and doesn't reflect actual progress
|
|
132
|
+
const timer = setInterval(() => {
|
|
133
|
+
setProgress((prev) => {
|
|
134
|
+
const next = prev + (100 - prev) * 0.05;
|
|
135
|
+
return next > 99 ? 99 : next;
|
|
136
|
+
});
|
|
137
|
+
}, 1000);
|
|
138
|
+
progressTimerRef.current = timer;
|
|
139
|
+
let data = null;
|
|
140
|
+
// Log the request for debugging
|
|
141
|
+
try {
|
|
142
|
+
// FIXED: Always try to load the document if we have an _id, regardless of regeneration state
|
|
143
|
+
// We'll use the document for info even during regeneration
|
|
144
|
+
const hasDocumentId = !!_id;
|
|
145
|
+
if (hasDocumentId) {
|
|
146
|
+
const existingDoc = await db.get(_id).catch((err) => {
|
|
147
|
+
console.error(`[loadOrGenerateImage] Failed to load document ${_id}:`, err);
|
|
148
|
+
return null;
|
|
149
|
+
});
|
|
150
|
+
if (existingDoc && existingDoc._files) {
|
|
151
|
+
// Document exists, set it
|
|
152
|
+
setDocument(existingDoc);
|
|
153
|
+
// Extract prompt information from the document
|
|
154
|
+
const { prompts, currentPromptKey } = getPromptsFromDocument(existingDoc);
|
|
155
|
+
const currentPromptText = (currentPromptKey && prompts[currentPromptKey]?.text) ||
|
|
156
|
+
existingDoc.prompt ||
|
|
157
|
+
'';
|
|
158
|
+
// If generationId is provided, we're creating a new version
|
|
159
|
+
// Only attempt if we have a document with a prompt
|
|
160
|
+
if (generationId && currentPromptText) {
|
|
161
|
+
// Create a completely unique key for the regeneration request to avoid deduplication
|
|
162
|
+
// at the image generation API call level (not just the document level)
|
|
163
|
+
const timestamp = Date.now();
|
|
164
|
+
const regenerationOptions = {
|
|
165
|
+
...options,
|
|
166
|
+
_regenerationId: timestamp, // Add timestamp for uniqueness
|
|
167
|
+
};
|
|
168
|
+
// Clear any existing request with the same prompt from the cache
|
|
169
|
+
// This ensures we don't get a cached result
|
|
170
|
+
const requestKey = `${currentPromptText}-${JSON.stringify(getRelevantOptions(options))}`;
|
|
171
|
+
cleanupRequestKey(requestKey);
|
|
172
|
+
// Generate a new image using the document's prompt
|
|
173
|
+
data = await callImageGeneration(currentPromptText, regenerationOptions);
|
|
174
|
+
if (data?.data?.[0]?.b64_json) {
|
|
175
|
+
// Create a File object from the base64 data
|
|
176
|
+
// Generate a filename based on the prompt text
|
|
177
|
+
const filename = generateSafeFilename(currentPromptText);
|
|
178
|
+
const newImageFile = base64ToFile(data.data[0].b64_json, filename);
|
|
179
|
+
// Ensure we preserve the original document ID
|
|
180
|
+
const originalDocId = _id;
|
|
181
|
+
// Add the new version to the document
|
|
182
|
+
const updatedDoc = addNewVersion(existingDoc, newImageFile, currentPromptText);
|
|
183
|
+
// Make sure the _id is preserved exactly
|
|
184
|
+
updatedDoc._id = originalDocId;
|
|
185
|
+
// Save the updated document
|
|
186
|
+
await db.put(updatedDoc);
|
|
187
|
+
// Get the updated document with the new version using the original ID
|
|
188
|
+
const refreshedDoc = await db.get(originalDocId);
|
|
189
|
+
setDocument(refreshedDoc);
|
|
190
|
+
// Set the image data from the new version
|
|
191
|
+
const reader = new FileReader();
|
|
192
|
+
reader.readAsDataURL(newImageFile);
|
|
193
|
+
await new Promise((resolve) => {
|
|
194
|
+
reader.onloadend = () => {
|
|
195
|
+
if (typeof reader.result === 'string') {
|
|
196
|
+
setImageData(reader.result);
|
|
197
|
+
}
|
|
198
|
+
resolve();
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
// Set progress to 100%
|
|
202
|
+
setProgress(100);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
// Select the current version's file - extract directly instead of storing in state
|
|
208
|
+
// This ensures we always have the latest version info straight from the document
|
|
209
|
+
const { versions, currentVersion } = getVersionsFromDocument(existingDoc);
|
|
210
|
+
if (versions.length > 0) {
|
|
211
|
+
// Use the current version ID to get the file
|
|
212
|
+
const versionId = versions[currentVersion]?.id || versions[0]?.id;
|
|
213
|
+
if (!versionId || !existingDoc._files[versionId]) {
|
|
214
|
+
throw new Error(`Version ${versionId} not found in document files`);
|
|
215
|
+
}
|
|
216
|
+
const imageFile = existingDoc._files[versionId];
|
|
217
|
+
let fileObj;
|
|
218
|
+
// Handle different file access methods
|
|
219
|
+
if ('file' in imageFile && typeof imageFile.file === 'function') {
|
|
220
|
+
// DocFileMeta interface from Fireproof
|
|
221
|
+
fileObj = await imageFile.file();
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
// Direct File object
|
|
225
|
+
fileObj = imageFile;
|
|
226
|
+
}
|
|
227
|
+
// Read the file as base64
|
|
228
|
+
const reader = new FileReader();
|
|
229
|
+
const base64Promise = new Promise((resolve, reject) => {
|
|
230
|
+
reader.onload = () => {
|
|
231
|
+
const base64 = reader.result;
|
|
232
|
+
// Strip the data URL prefix if present
|
|
233
|
+
const base64Data = base64.split(',')[1] || base64;
|
|
234
|
+
resolve(base64Data);
|
|
235
|
+
};
|
|
236
|
+
reader.onerror = reject;
|
|
237
|
+
});
|
|
238
|
+
reader.readAsDataURL(fileObj);
|
|
239
|
+
const base64Data = await base64Promise;
|
|
240
|
+
setImageData(base64Data);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
// Handle legacy files structure
|
|
244
|
+
if (existingDoc._files.image) {
|
|
245
|
+
const imageFile = existingDoc._files.image;
|
|
246
|
+
let fileObj;
|
|
247
|
+
if ('file' in imageFile && typeof imageFile.file === 'function') {
|
|
248
|
+
fileObj = await imageFile.file();
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
fileObj = imageFile;
|
|
252
|
+
}
|
|
253
|
+
// Read the file as base64
|
|
254
|
+
const reader = new FileReader();
|
|
255
|
+
const base64Promise = new Promise((resolve, reject) => {
|
|
256
|
+
reader.onload = () => {
|
|
257
|
+
const base64 = reader.result;
|
|
258
|
+
// Strip the data URL prefix if present
|
|
259
|
+
const base64Data = base64.split(',')[1] || base64;
|
|
260
|
+
resolve(base64Data);
|
|
261
|
+
};
|
|
262
|
+
reader.onerror = reject;
|
|
263
|
+
});
|
|
264
|
+
reader.readAsDataURL(fileObj);
|
|
265
|
+
const base64Data = await base64Promise;
|
|
266
|
+
setImageData(base64Data);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
console.error('Error loading image file:', err);
|
|
272
|
+
throw new Error(`Failed to load image from document: ${err instanceof Error ? err.message : String(err)}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
throw new Error(`Document exists but has no files: ${_id}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else if (prompt) {
|
|
280
|
+
// No document ID provided but we have a prompt - generate a new image
|
|
281
|
+
// If we have a document in memory and a generationId, we should add a version
|
|
282
|
+
// to the existing document instead of creating a new one
|
|
283
|
+
if (document?._id && generationId) {
|
|
284
|
+
let currentPromptText = '';
|
|
285
|
+
if (editedPrompt) {
|
|
286
|
+
// Use the edited prompt provided from the UI
|
|
287
|
+
currentPromptText = editedPrompt;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
// Otherwise extract the prompt from the document
|
|
291
|
+
const { prompts, currentPromptKey } = getPromptsFromDocument(document);
|
|
292
|
+
currentPromptText =
|
|
293
|
+
(currentPromptKey && prompts[currentPromptKey]?.text) ||
|
|
294
|
+
document.prompt ||
|
|
295
|
+
'' ||
|
|
296
|
+
prompt ||
|
|
297
|
+
''; // Fall back to provided prompt if document has none, ensure string type
|
|
298
|
+
}
|
|
299
|
+
// Create regeneration options with unique ID to force new API call
|
|
300
|
+
const regenerationOptions = {
|
|
301
|
+
...options,
|
|
302
|
+
_regenerationId: Date.now(),
|
|
303
|
+
};
|
|
304
|
+
// Clear any cached promise for the original prompt+options
|
|
305
|
+
const requestKey = `${currentPromptText}-${JSON.stringify(getRelevantOptions(options))}`;
|
|
306
|
+
cleanupRequestKey(requestKey);
|
|
307
|
+
// Generate a new image
|
|
308
|
+
data = await callImageGeneration(currentPromptText, regenerationOptions);
|
|
309
|
+
if (data?.data?.[0]?.b64_json) {
|
|
310
|
+
// Create a File object from the base64 data
|
|
311
|
+
const filename = generateSafeFilename(currentPromptText);
|
|
312
|
+
const newImageFile = base64ToFile(data.data[0].b64_json, filename);
|
|
313
|
+
// Ensure we preserve the original document ID
|
|
314
|
+
const originalDocId = document._id;
|
|
315
|
+
// Add the new version to the document
|
|
316
|
+
const updatedDoc = addNewVersion(document, newImageFile, currentPromptText);
|
|
317
|
+
// Make sure the _id is preserved
|
|
318
|
+
updatedDoc._id = originalDocId;
|
|
319
|
+
// Save the updated document
|
|
320
|
+
await db.put(updatedDoc);
|
|
321
|
+
// Get the updated document with the new version
|
|
322
|
+
const refreshedDoc = await db.get(originalDocId);
|
|
323
|
+
setDocument(refreshedDoc);
|
|
324
|
+
// Set the image data from the new version
|
|
325
|
+
const reader = new FileReader();
|
|
326
|
+
reader.readAsDataURL(newImageFile);
|
|
327
|
+
await new Promise((resolve) => {
|
|
328
|
+
reader.onloadend = () => {
|
|
329
|
+
if (typeof reader.result === 'string') {
|
|
330
|
+
setImageData(reader.result);
|
|
331
|
+
}
|
|
332
|
+
resolve();
|
|
333
|
+
};
|
|
334
|
+
});
|
|
335
|
+
// Set progress to 100%
|
|
336
|
+
setProgress(100);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
// Regular prompt-only generation (no document in memory)
|
|
342
|
+
// Build generation options; if this is a regeneration request (generationId present)
|
|
343
|
+
// attach a unique _regenerationId to force a fresh network call and clear cached key.
|
|
344
|
+
let generationOptions = options;
|
|
345
|
+
if (generationId) {
|
|
346
|
+
generationOptions = {
|
|
347
|
+
...options,
|
|
348
|
+
_regenerationId: Date.now(),
|
|
349
|
+
};
|
|
350
|
+
// Clear any cached promise for the original prompt+options so that
|
|
351
|
+
// imageGen will not re-use the previous response.
|
|
352
|
+
const requestKey = `${prompt}-${JSON.stringify(getRelevantOptions(options))}`;
|
|
353
|
+
cleanupRequestKey(requestKey);
|
|
354
|
+
}
|
|
355
|
+
// Generate the image
|
|
356
|
+
data = await callImageGeneration(prompt, generationOptions);
|
|
357
|
+
}
|
|
358
|
+
// Process the data response
|
|
359
|
+
if (data?.data?.[0]?.b64_json) {
|
|
360
|
+
// Create a File object from the base64 data
|
|
361
|
+
// Generate a filename based on the prompt text
|
|
362
|
+
const filename = generateSafeFilename(prompt);
|
|
363
|
+
const imageFile = base64ToFile(data.data[0].b64_json, filename);
|
|
364
|
+
// Define a stable key for deduplication based on all relevant parameters.
|
|
365
|
+
// Include _id (if present) and current time for regeneration requests
|
|
366
|
+
// to ensure each regeneration gets a unique key
|
|
367
|
+
// Create a unique stable key for this request that changes with generationId
|
|
368
|
+
// When generationId changes, we'll generate a new image
|
|
369
|
+
const regenPart = generationId ? `gen-${generationId}` : '0';
|
|
370
|
+
const stableKey = [
|
|
371
|
+
prompt || '',
|
|
372
|
+
_id || '',
|
|
373
|
+
// For generation requests, use the generationId to ensure uniqueness
|
|
374
|
+
// When there's no _id but there is a prompt, we still want regeneration to work
|
|
375
|
+
regenPart,
|
|
376
|
+
// Stringify only relevant options to avoid spurious cache misses
|
|
377
|
+
JSON.stringify(getRelevantOptions(options)),
|
|
378
|
+
].join('|');
|
|
379
|
+
// Schedule cleanup of this request from the cache maps
|
|
380
|
+
// to ensure future requests don't reuse this one
|
|
381
|
+
setTimeout(() => {
|
|
382
|
+
cleanupRequestKey(stableKey);
|
|
383
|
+
});
|
|
384
|
+
// Schedule cleanup of this request from the cache maps
|
|
385
|
+
// to ensure future requests don't reuse this one
|
|
386
|
+
setTimeout(() => {
|
|
387
|
+
cleanupRequestKey(stableKey);
|
|
388
|
+
}, 100); // Clear after a short delay
|
|
389
|
+
try {
|
|
390
|
+
// First check if there's already a document ID for this request
|
|
391
|
+
const existingDocId = MODULE_STATE.createdDocuments.get(stableKey);
|
|
392
|
+
if (existingDocId) {
|
|
393
|
+
try {
|
|
394
|
+
// Try to get the existing document
|
|
395
|
+
const existingDoc = await db.get(existingDocId);
|
|
396
|
+
setDocument(existingDoc);
|
|
397
|
+
setImageData(data.data[0].b64_json);
|
|
398
|
+
return; // Exit early, we're using the existing document
|
|
399
|
+
}
|
|
400
|
+
catch {
|
|
401
|
+
// Error fetching existing document, ignore silently
|
|
402
|
+
// Will continue to document creation below
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
// Check if there's already a document creation in progress
|
|
406
|
+
let documentCreationPromise = MODULE_STATE.pendingDocumentCreations.get(stableKey);
|
|
407
|
+
if (!documentCreationPromise) {
|
|
408
|
+
// No document creation in progress, start a new one
|
|
409
|
+
// This promise will be shared by all subscribers requesting the same document
|
|
410
|
+
documentCreationPromise = (async () => {
|
|
411
|
+
// Create a new document with initial version and prompt
|
|
412
|
+
const imgDoc = {
|
|
413
|
+
_id: '', // Will be assigned by Fireproof
|
|
414
|
+
type: 'image',
|
|
415
|
+
created: Date.now(),
|
|
416
|
+
currentVersion: 0, // 0-based indexing for versions array
|
|
417
|
+
versions: [
|
|
418
|
+
{
|
|
419
|
+
id: 'v1',
|
|
420
|
+
created: Date.now(),
|
|
421
|
+
promptKey: 'p1',
|
|
422
|
+
},
|
|
423
|
+
],
|
|
424
|
+
prompts: {
|
|
425
|
+
p1: {
|
|
426
|
+
text: prompt,
|
|
427
|
+
created: Date.now(),
|
|
428
|
+
},
|
|
429
|
+
},
|
|
430
|
+
currentPromptKey: 'p1',
|
|
431
|
+
_files: {
|
|
432
|
+
v1: imageFile,
|
|
433
|
+
},
|
|
434
|
+
};
|
|
435
|
+
// Save the new document to Fireproof
|
|
436
|
+
const result = await db.put(imgDoc);
|
|
437
|
+
// Store the document ID in our tracking map to prevent duplicates
|
|
438
|
+
MODULE_STATE.createdDocuments.set(stableKey, result.id);
|
|
439
|
+
// Get the document with the file attached
|
|
440
|
+
const doc = (await db.get(result.id));
|
|
441
|
+
return { id: result.id, doc };
|
|
442
|
+
})();
|
|
443
|
+
// Store the promise for other subscribers
|
|
444
|
+
MODULE_STATE.pendingDocumentCreations.set(stableKey, documentCreationPromise);
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
// Reusing existing document creation promise
|
|
448
|
+
// No additional action needed
|
|
449
|
+
}
|
|
450
|
+
try {
|
|
451
|
+
// Wait for the document creation to complete
|
|
452
|
+
const { doc } = await documentCreationPromise;
|
|
453
|
+
setDocument(doc);
|
|
454
|
+
setImageData(data.data[0].b64_json);
|
|
455
|
+
}
|
|
456
|
+
catch (e) {
|
|
457
|
+
console.error('Error in document creation:', e);
|
|
458
|
+
// Still show the image even if document creation fails
|
|
459
|
+
setImageData(data.data[0].b64_json);
|
|
460
|
+
// Clean up the failed promise so future requests can try again
|
|
461
|
+
MODULE_STATE.pendingDocumentCreations.delete(stableKey);
|
|
462
|
+
}
|
|
463
|
+
// Empty block - all document creation logic is now handled by the Promise
|
|
464
|
+
}
|
|
465
|
+
catch (e) {
|
|
466
|
+
console.error('Error saving to Fireproof:', e);
|
|
467
|
+
// Even if we fail to save to Fireproof, we still have the image data
|
|
468
|
+
setImageData(data.data[0].b64_json);
|
|
469
|
+
}
|
|
470
|
+
finally {
|
|
471
|
+
// Clean up processing flag
|
|
472
|
+
MODULE_STATE.processingRequests.delete(stableKey);
|
|
473
|
+
// Clean up the document creation promise if successful
|
|
474
|
+
// This prevents memory leaks while preserving the document ID in createdDocuments
|
|
475
|
+
if (MODULE_STATE.createdDocuments.has(stableKey)) {
|
|
476
|
+
MODULE_STATE.pendingDocumentCreations.delete(stableKey);
|
|
477
|
+
MODULE_STATE.requestTimestamps.delete(stableKey);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
console.error('[loadOrGenerateImage] Document loading failed - requirements not met:', {
|
|
484
|
+
_id,
|
|
485
|
+
hasPrompt: !!prompt,
|
|
486
|
+
promptLength: prompt?.length,
|
|
487
|
+
generationId,
|
|
488
|
+
});
|
|
489
|
+
throw new Error('Document not found and no prompt provided for generation');
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
catch (error) {
|
|
493
|
+
// Log the error
|
|
494
|
+
console.error('Error retrieving from Fireproof:', error);
|
|
495
|
+
// Only try image generation as fallback for document load failures when we have a prompt
|
|
496
|
+
if (prompt && !data && _id) {
|
|
497
|
+
try {
|
|
498
|
+
data = await callImageGeneration(prompt, options);
|
|
499
|
+
if (data?.data?.[0]?.b64_json) {
|
|
500
|
+
setImageData(data.data[0].b64_json);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
catch (genError) {
|
|
504
|
+
console.error('Fallback generation also failed:', genError);
|
|
505
|
+
throw genError;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
throw error;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
finally {
|
|
513
|
+
// Always reset loading state and progress indicators
|
|
514
|
+
// This ensures UI progress bars are stopped even if an error occurs
|
|
515
|
+
if (isMounted) {
|
|
516
|
+
setLoading(false);
|
|
517
|
+
setProgress(0); // Reset progress to 0 instead of null
|
|
518
|
+
}
|
|
519
|
+
// Clear progress timer
|
|
520
|
+
if (progressTimerRef.current) {
|
|
521
|
+
clearInterval(progressTimerRef.current);
|
|
522
|
+
progressTimerRef.current = null;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
// Update state with the image data
|
|
526
|
+
if (isMounted && data) {
|
|
527
|
+
setProgress(100);
|
|
528
|
+
// Clear progress timer
|
|
529
|
+
if (progressTimerRef.current) {
|
|
530
|
+
clearInterval(progressTimerRef.current);
|
|
531
|
+
progressTimerRef.current = null;
|
|
532
|
+
}
|
|
533
|
+
// Log completion time
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
catch (err) {
|
|
537
|
+
if (isMounted) {
|
|
538
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
finally {
|
|
542
|
+
if (isMounted) {
|
|
543
|
+
// Clear progress timer if it's still running
|
|
544
|
+
if (progressTimerRef.current) {
|
|
545
|
+
clearInterval(progressTimerRef.current);
|
|
546
|
+
progressTimerRef.current = null;
|
|
547
|
+
}
|
|
548
|
+
setLoading(false);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
const loadImageTimer = setTimeout(() => {
|
|
553
|
+
if (isMounted) {
|
|
554
|
+
loadOrGenerateImage();
|
|
555
|
+
}
|
|
556
|
+
}, 10); // Small delay to allow React to batch updates
|
|
557
|
+
return () => {
|
|
558
|
+
isMounted = false;
|
|
559
|
+
if (loadImageTimer) {
|
|
560
|
+
clearTimeout(loadImageTimer);
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
}, [prompt, _id, memoizedOptions, requestId, database, skip, generationId]); // Dependencies that trigger image loading/generation
|
|
564
|
+
return {
|
|
565
|
+
imageData,
|
|
566
|
+
loading,
|
|
567
|
+
progress,
|
|
568
|
+
error,
|
|
569
|
+
size: { width, height },
|
|
570
|
+
document,
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
//# sourceMappingURL=use-image-gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-image-gen.js","sourceRoot":"","sources":["../../../src/hooks/image-gen/use-image-gen.ts"],"names":[],"mappings":"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"}
|