@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 +1 -1
- package/src/domain/constants/index.ts +2 -0
- package/src/domain/constants/queue-status.constants.ts +22 -0
- package/src/domains/creations/presentation/hooks/useProcessingJobsPoller.ts +13 -45
- package/src/domains/generation/wizard/infrastructure/strategies/wizard-strategy.constants.ts +1 -0
- package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +5 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.
|
|
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,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; //
|
|
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 ===
|
|
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 ===
|
|
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:
|
|
79
|
+
status: CREATION_STATUS.COMPLETED,
|
|
110
80
|
uri,
|
|
111
81
|
output: urls,
|
|
112
82
|
});
|
|
113
|
-
} else if (status.status ===
|
|
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:
|
|
87
|
+
status: CREATION_STATUS.FAILED,
|
|
120
88
|
metadata: { error: "Generation failed" },
|
|
121
89
|
});
|
|
122
90
|
}
|
package/src/domains/generation/wizard/infrastructure/strategies/wizard-strategy.constants.ts
CHANGED
|
@@ -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 ===
|
|
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 ===
|
|
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 {
|