@umituz/react-native-ai-generation-content 1.50.0 → 1.52.0

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.50.0",
3
+ "version": "1.52.0",
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",
@@ -0,0 +1,2 @@
1
+ export * from "./processing-modes.constants";
2
+ export * from "./queue-status.constants";
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Queue Status Constants
3
+ * FAL queue job status values - shared across all polling hooks
4
+ */
5
+
6
+ export const QUEUE_STATUS = {
7
+ IN_QUEUE: "IN_QUEUE",
8
+ IN_PROGRESS: "IN_PROGRESS",
9
+ COMPLETED: "COMPLETED",
10
+ FAILED: "FAILED",
11
+ } as const;
12
+
13
+ export type QueueStatus = (typeof QUEUE_STATUS)[keyof typeof QUEUE_STATUS];
14
+
15
+ /** Creation document status values */
16
+ export const CREATION_STATUS = {
17
+ PROCESSING: "processing",
18
+ COMPLETED: "completed",
19
+ FAILED: "failed",
20
+ } as const;
21
+
22
+ export type CreationStatus = (typeof CREATION_STATUS)[keyof typeof CREATION_STATUS];
@@ -7,12 +7,17 @@
7
7
 
8
8
  import { useEffect, useRef, useCallback } from "react";
9
9
  import { providerRegistry } from "../../../../infrastructure/services/provider-registry.service";
10
+ import { QUEUE_STATUS, CREATION_STATUS } from "../../../../domain/constants/queue-status.constants";
11
+ import {
12
+ extractResultUrl,
13
+ type FalResult,
14
+ } from "../../../generation/wizard/presentation/hooks/generation-result.utils";
10
15
  import type { Creation } from "../../domain/entities/Creation";
11
16
  import type { ICreationsRepository } from "../../domain/repositories/ICreationsRepository";
12
17
 
13
18
  declare const __DEV__: boolean;
14
19
 
15
- const POLL_INTERVAL_MS = 5000; // Poll every 5 seconds
20
+ const POLL_INTERVAL_MS = 5000; // Gallery polls slower than wizard
16
21
 
17
22
  export interface UseProcessingJobsPollerConfig {
18
23
  readonly userId?: string | null;
@@ -25,36 +30,6 @@ export interface UseProcessingJobsPollerReturn {
25
30
  readonly processingCount: number;
26
31
  }
27
32
 
28
- interface FalResult {
29
- video?: { url?: string };
30
- output?: string;
31
- images?: Array<{ url?: string }>;
32
- image?: { url?: string };
33
- }
34
-
35
- function extractResultUrl(result: FalResult): { imageUrl?: string; videoUrl?: string } {
36
- // Video result
37
- if (result.video?.url) {
38
- return { videoUrl: result.video.url };
39
- }
40
- // Output URL (some models)
41
- if (typeof result.output === "string" && result.output.startsWith("http")) {
42
- if (result.output.includes(".mp4") || result.output.includes("video")) {
43
- return { videoUrl: result.output };
44
- }
45
- return { imageUrl: result.output };
46
- }
47
- // Images array
48
- if (result.images?.[0]?.url) {
49
- return { imageUrl: result.images[0].url };
50
- }
51
- // Single image
52
- if (result.image?.url) {
53
- return { imageUrl: result.image.url };
54
- }
55
- return {};
56
- }
57
-
58
33
  export function useProcessingJobsPoller(
59
34
  config: UseProcessingJobsPollerConfig,
60
35
  ): UseProcessingJobsPollerReturn {
@@ -70,7 +45,7 @@ export function useProcessingJobsPoller(
70
45
 
71
46
  // Find creations that need polling
72
47
  const processingJobs = creations.filter(
73
- (c) => c.status === "processing" && c.requestId && c.model,
48
+ (c) => c.status === CREATION_STATUS.PROCESSING && c.requestId && c.model,
74
49
  );
75
50
 
76
51
  const pollJob = useCallback(
@@ -94,29 +69,22 @@ export function useProcessingJobsPoller(
94
69
  console.log("[ProcessingJobsPoller] Status:", creation.id, status.status);
95
70
  }
96
71
 
97
- if (status.status === "COMPLETED") {
98
- // Fetch the result
72
+ if (status.status === QUEUE_STATUS.COMPLETED) {
99
73
  const result = await provider.getJobResult<FalResult>(creation.model, creation.requestId);
100
74
  const urls = extractResultUrl(result);
75
+ if (typeof __DEV__ !== "undefined" && __DEV__) console.log("[ProcessingJobsPoller] Completed:", creation.id, urls);
101
76
 
102
- if (typeof __DEV__ !== "undefined" && __DEV__) {
103
- console.log("[ProcessingJobsPoller] Completed:", creation.id, urls);
104
- }
105
-
106
- // Update Firestore
107
77
  const uri = urls.videoUrl || urls.imageUrl || "";
108
78
  await repository.update(userId, creation.id, {
109
- status: "completed",
79
+ status: CREATION_STATUS.COMPLETED,
110
80
  uri,
111
81
  output: urls,
112
82
  });
113
- } else if (status.status === "FAILED") {
114
- if (typeof __DEV__ !== "undefined" && __DEV__) {
115
- console.log("[ProcessingJobsPoller] Failed:", creation.id);
116
- }
83
+ } else if (status.status === QUEUE_STATUS.FAILED) {
84
+ if (typeof __DEV__ !== "undefined" && __DEV__) console.log("[ProcessingJobsPoller] Failed:", creation.id);
117
85
 
118
86
  await repository.update(userId, creation.id, {
119
- status: "failed",
87
+ status: CREATION_STATUS.FAILED,
120
88
  metadata: { error: "Generation failed" },
121
89
  });
122
90
  }
@@ -50,6 +50,7 @@ export const VIDEO_PROCESSING_PROMPTS: Record<string, string> = {
50
50
  "ai-kiss": "Create a romantic video where these two people share a gentle, loving kiss",
51
51
  "ai-hug": "Create a heartwarming video where these two people share a warm, affectionate hug",
52
52
  "image-to-video": "Animate this image with natural, smooth motion while preserving the original style",
53
+ "text-to-video": "Create a high-quality video based on the description provided",
53
54
  "solo_renaissance_portrait": "Transform this person into an elegant Renaissance-style animated portrait with classical artistic movements and period-appropriate lighting",
54
55
  "renaissance_portrait": "Transform this portrait into a majestic Renaissance-style animated painting with subtle classical movements",
55
56
  "historical_portrait": "Animate this portrait in a historical style with period-appropriate subtle movements",
@@ -9,14 +9,15 @@
9
9
  import { useEffect, useRef, useCallback, useState } from "react";
10
10
  import { providerRegistry } from "../../../../../infrastructure/services/provider-registry.service";
11
11
  import { extractResultUrl, type FalResult, type GenerationUrls } from "./generation-result.utils";
12
+ import { QUEUE_STATUS } from "../../../../../domain/constants/queue-status.constants";
13
+
14
+ const POLL_INTERVAL_MS = 3000;
12
15
  import type { CreationPersistence } from "../../infrastructure/utils/creation-persistence.util";
13
16
  import type { WizardStrategy } from "../../infrastructure/strategies/wizard-strategy.types";
14
17
  import type { WizardScenarioData } from "./wizard-generation.types";
15
18
 
16
19
  declare const __DEV__: boolean;
17
20
 
18
- const POLL_INTERVAL_MS = 3000;
19
-
20
21
  export interface UseVideoQueueGenerationProps {
21
22
  readonly userId?: string;
22
23
  readonly scenario: WizardScenarioData;
@@ -105,9 +106,9 @@ export function useVideoQueueGeneration(
105
106
  const status = await provider.getJobStatus(model, requestId);
106
107
  if (typeof __DEV__ !== "undefined" && __DEV__) console.log("[VideoQueueGeneration] Poll:", status.status);
107
108
 
108
- if (status.status === "COMPLETED" || status.status === "FAILED") {
109
+ if (status.status === QUEUE_STATUS.COMPLETED || status.status === QUEUE_STATUS.FAILED) {
109
110
  if (pollingRef.current) { clearInterval(pollingRef.current); pollingRef.current = null; }
110
- if (status.status === "COMPLETED") {
111
+ if (status.status === QUEUE_STATUS.COMPLETED) {
111
112
  const result = await provider.getJobResult<FalResult>(model, requestId);
112
113
  await handleComplete(extractResultUrl(result));
113
114
  } else {