@umituz/react-native-ai-generation-content 1.27.11 → 1.27.12
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/entities/flow-config.types.ts +22 -0
- package/src/domains/generation/index.ts +13 -0
- package/src/domains/generation/wizard/domain/entities/wizard-config.types.ts +22 -0
- package/src/domains/generation/wizard/index.ts +2 -0
- package/src/domains/generation/wizard/presentation/hooks/useGateStep.ts +138 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.27.
|
|
3
|
+
"version": "1.27.12",
|
|
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",
|
|
@@ -5,17 +5,39 @@
|
|
|
5
5
|
|
|
6
6
|
/** Step Types */
|
|
7
7
|
export enum StepType {
|
|
8
|
+
// Gate steps - auth and credits check
|
|
9
|
+
AUTH_GATE = "auth_gate",
|
|
10
|
+
CREDIT_GATE = "credit_gate",
|
|
11
|
+
// Content steps
|
|
8
12
|
CATEGORY_SELECTION = "category_selection",
|
|
9
13
|
SCENARIO_SELECTION = "scenario_selection",
|
|
10
14
|
SCENARIO_PREVIEW = "scenario_preview",
|
|
11
15
|
PARTNER_UPLOAD = "partner_upload",
|
|
12
16
|
TEXT_INPUT = "text_input",
|
|
13
17
|
FEATURE_SELECTION = "feature_selection",
|
|
18
|
+
// Generation steps
|
|
14
19
|
GENERATING = "generating",
|
|
15
20
|
RESULT_PREVIEW = "result_preview",
|
|
16
21
|
CUSTOM = "custom",
|
|
17
22
|
}
|
|
18
23
|
|
|
24
|
+
/** Gate Step Result */
|
|
25
|
+
export type GateResult = "passed" | "blocked" | "pending";
|
|
26
|
+
|
|
27
|
+
/** Auth Gate Configuration */
|
|
28
|
+
export interface AuthGateConfig {
|
|
29
|
+
readonly allowAnonymous?: boolean;
|
|
30
|
+
readonly onAuthRequired?: () => void;
|
|
31
|
+
readonly onAuthSuccess?: () => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Credit Gate Configuration */
|
|
35
|
+
export interface CreditGateConfig {
|
|
36
|
+
readonly requiredCredits: number;
|
|
37
|
+
readonly onCreditsExhausted?: () => void;
|
|
38
|
+
readonly onCreditsAvailable?: () => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
19
41
|
/** Partner Configuration */
|
|
20
42
|
export interface PartnerConfig {
|
|
21
43
|
readonly partnerId: "A" | "B" | "single";
|
|
@@ -35,3 +35,16 @@ export { ExecutorFactory, type GenerationType as ExecutorGenerationType } from "
|
|
|
35
35
|
|
|
36
36
|
export * from "./wizard";
|
|
37
37
|
export * from "./infrastructure/flow";
|
|
38
|
+
|
|
39
|
+
// Flow config types from domain
|
|
40
|
+
export {
|
|
41
|
+
StepType,
|
|
42
|
+
type GateResult,
|
|
43
|
+
type AuthGateConfig,
|
|
44
|
+
type CreditGateConfig,
|
|
45
|
+
type FlowState,
|
|
46
|
+
type FlowActions,
|
|
47
|
+
type FlowCallbacks,
|
|
48
|
+
type FlowConfiguration,
|
|
49
|
+
type StepDefinition,
|
|
50
|
+
} from "../../domain/entities/flow-config.types";
|
|
@@ -72,10 +72,32 @@ export interface PreviewStepConfig extends BaseStepConfig {
|
|
|
72
72
|
readonly showContinueButton?: boolean;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Auth Gate Step Configuration
|
|
77
|
+
* Blocks flow if user is not authenticated
|
|
78
|
+
*/
|
|
79
|
+
export interface AuthGateStepConfig extends BaseStepConfig {
|
|
80
|
+
readonly type: "auth_gate";
|
|
81
|
+
readonly allowAnonymous?: boolean;
|
|
82
|
+
readonly messageKey?: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Credit Gate Step Configuration
|
|
87
|
+
* Blocks flow if user doesn't have enough credits
|
|
88
|
+
*/
|
|
89
|
+
export interface CreditGateStepConfig extends BaseStepConfig {
|
|
90
|
+
readonly type: "credit_gate";
|
|
91
|
+
readonly requiredCredits: number;
|
|
92
|
+
readonly messageKey?: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
75
95
|
/**
|
|
76
96
|
* Union of all step config types
|
|
77
97
|
*/
|
|
78
98
|
export type WizardStepConfig =
|
|
99
|
+
| AuthGateStepConfig
|
|
100
|
+
| CreditGateStepConfig
|
|
79
101
|
| PhotoUploadStepConfig
|
|
80
102
|
| TextInputStepConfig
|
|
81
103
|
| SelectionStepConfig
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useGateStep Hook
|
|
3
|
+
* Handles auth and credit gate steps in wizard flow
|
|
4
|
+
*
|
|
5
|
+
* Gates are "invisible" steps that:
|
|
6
|
+
* - Auto-advance when condition is met
|
|
7
|
+
* - Show modal/paywall when blocked
|
|
8
|
+
* - Never show UI themselves
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { useEffect, useRef, useCallback } from "react";
|
|
12
|
+
import type { GateResult } from "../../../../../domain/entities/flow-config.types";
|
|
13
|
+
|
|
14
|
+
declare const __DEV__: boolean;
|
|
15
|
+
|
|
16
|
+
export interface GateCallbacks {
|
|
17
|
+
/** Called when auth is required - should show auth modal */
|
|
18
|
+
readonly onAuthRequired?: () => void;
|
|
19
|
+
/** Called when credits are exhausted - should show paywall */
|
|
20
|
+
readonly onCreditsExhausted?: () => void;
|
|
21
|
+
/** Called when gate passes - auto advance to next step */
|
|
22
|
+
readonly onGatePassed?: () => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AuthGateState {
|
|
26
|
+
readonly isAuthenticated: boolean;
|
|
27
|
+
readonly isAnonymous: boolean;
|
|
28
|
+
readonly userId: string | null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface CreditGateState {
|
|
32
|
+
readonly creditBalance: number;
|
|
33
|
+
readonly requiredCredits: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface UseGateStepProps {
|
|
37
|
+
readonly gateType: "auth" | "credit";
|
|
38
|
+
readonly authState?: AuthGateState;
|
|
39
|
+
readonly creditState?: CreditGateState;
|
|
40
|
+
readonly callbacks: GateCallbacks;
|
|
41
|
+
readonly allowAnonymous?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface UseGateStepReturn {
|
|
45
|
+
readonly gateResult: GateResult;
|
|
46
|
+
readonly checkGate: () => GateResult;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Hook to manage gate step logic
|
|
51
|
+
* Automatically triggers callbacks and advances when conditions are met
|
|
52
|
+
*/
|
|
53
|
+
export function useGateStep(props: UseGateStepProps): UseGateStepReturn {
|
|
54
|
+
const { gateType, authState, creditState, callbacks, allowAnonymous = false } = props;
|
|
55
|
+
|
|
56
|
+
const hasChecked = useRef(false);
|
|
57
|
+
|
|
58
|
+
const checkAuthGate = useCallback((): GateResult => {
|
|
59
|
+
if (!authState) return "pending";
|
|
60
|
+
|
|
61
|
+
const { isAuthenticated, isAnonymous, userId } = authState;
|
|
62
|
+
|
|
63
|
+
// Allow anonymous if configured
|
|
64
|
+
if (allowAnonymous && userId) {
|
|
65
|
+
return "passed";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Must be authenticated and not anonymous
|
|
69
|
+
if (isAuthenticated && !isAnonymous && userId) {
|
|
70
|
+
return "passed";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return "blocked";
|
|
74
|
+
}, [authState, allowAnonymous]);
|
|
75
|
+
|
|
76
|
+
const checkCreditGate = useCallback((): GateResult => {
|
|
77
|
+
if (!creditState) return "pending";
|
|
78
|
+
|
|
79
|
+
const { creditBalance, requiredCredits } = creditState;
|
|
80
|
+
|
|
81
|
+
if (creditBalance >= requiredCredits) {
|
|
82
|
+
return "passed";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return "blocked";
|
|
86
|
+
}, [creditState]);
|
|
87
|
+
|
|
88
|
+
const checkGate = useCallback((): GateResult => {
|
|
89
|
+
if (gateType === "auth") {
|
|
90
|
+
return checkAuthGate();
|
|
91
|
+
}
|
|
92
|
+
return checkCreditGate();
|
|
93
|
+
}, [gateType, checkAuthGate, checkCreditGate]);
|
|
94
|
+
|
|
95
|
+
// Auto-check and trigger callbacks on mount
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (hasChecked.current) return;
|
|
98
|
+
|
|
99
|
+
const result = checkGate();
|
|
100
|
+
|
|
101
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
102
|
+
console.log(`[useGateStep] ${gateType} gate check:`, result);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (result === "passed") {
|
|
106
|
+
hasChecked.current = true;
|
|
107
|
+
callbacks.onGatePassed?.();
|
|
108
|
+
} else if (result === "blocked") {
|
|
109
|
+
hasChecked.current = true;
|
|
110
|
+
if (gateType === "auth") {
|
|
111
|
+
callbacks.onAuthRequired?.();
|
|
112
|
+
} else {
|
|
113
|
+
callbacks.onCreditsExhausted?.();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}, [gateType, checkGate, callbacks]);
|
|
117
|
+
|
|
118
|
+
// Re-check when auth/credit state changes
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
if (!hasChecked.current) return;
|
|
121
|
+
|
|
122
|
+
const result = checkGate();
|
|
123
|
+
|
|
124
|
+
if (result === "passed") {
|
|
125
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
126
|
+
console.log(`[useGateStep] ${gateType} gate now passed, advancing...`);
|
|
127
|
+
}
|
|
128
|
+
callbacks.onGatePassed?.();
|
|
129
|
+
}
|
|
130
|
+
}, [authState, creditState, gateType, checkGate, callbacks]);
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
gateResult: checkGate(),
|
|
134
|
+
checkGate,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export default useGateStep;
|