@umituz/react-native-ai-generation-content 1.82.8 → 1.82.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.82.8",
3
+ "version": "1.82.9",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -104,6 +104,13 @@ export const executeQueuedJob = async <TInput, TResult>(
104
104
  await executor.onError?.(failedJob, error instanceof Error ? error : new Error(errorMsg));
105
105
  onJobError?.(failedJob);
106
106
  }
107
+
108
+ // Remove failed job from cache to prevent accumulation
109
+ try {
110
+ await removeJobAsync(jobId);
111
+ } catch {
112
+ // Best effort cleanup
113
+ }
107
114
  } finally {
108
115
  // Use atomic Set operation to prevent race conditions
109
116
  activeJobsRef.current.delete(jobId);
@@ -81,8 +81,13 @@ export function useBackgroundGeneration<TInput = unknown, TResult = unknown>(
81
81
  activeJobsRef.current.delete(id);
82
82
  jobInputsRef.current.delete(id);
83
83
  removeJob(id);
84
+
85
+ // Trigger onAllComplete if no more active jobs after cancel
86
+ if (activeJobsRef.current.size === 0) {
87
+ onAllComplete?.();
88
+ }
84
89
  },
85
- [removeJob],
90
+ [removeJob, onAllComplete],
86
91
  );
87
92
 
88
93
  // Calculate active jobs from TanStack Query state (not ref) for reactivity
@@ -121,14 +121,14 @@ export const usePhotoUploadState = ({
121
121
  }
122
122
 
123
123
  if (result.error === MediaValidationError.FILE_TOO_LARGE) {
124
- onError?.({
125
- title: translations.fileTooLarge,
126
- message: translations.maxFileSize.replace("{size}", maxFileSizeMB.toString()),
124
+ onErrorRef.current?.({
125
+ title: translationsRef.current.fileTooLarge,
126
+ message: translationsRef.current.maxFileSize.replace("{size}", maxFileSizeMB.toString()),
127
127
  });
128
128
  } else if (result.error === MediaValidationError.PERMISSION_DENIED) {
129
- onError?.({
130
- title: translations.error,
131
- message: translations.permissionDenied ?? "Permission to access media library is required",
129
+ onErrorRef.current?.({
130
+ title: translationsRef.current.error,
131
+ message: translationsRef.current.permissionDenied ?? "Permission to access media library is required",
132
132
  });
133
133
  }
134
134
  return;
@@ -168,12 +168,12 @@ export const usePhotoUploadState = ({
168
168
  if (typeof __DEV__ !== "undefined" && __DEV__) {
169
169
  console.error("[usePhotoUploadState] Error picking image", error);
170
170
  }
171
- onError?.({
172
- title: translations.error,
173
- message: translations.uploadFailed,
171
+ onErrorRef.current?.({
172
+ title: translationsRef.current.error,
173
+ message: translationsRef.current.uploadFailed,
174
174
  });
175
175
  }
176
- }, [pickImage, maxFileSizeMB, translations, onError]);
176
+ }, [pickImage, maxFileSizeMB]);
177
177
 
178
178
  const canContinue = image !== null && !isLoading;
179
179