@umituz/react-native-ai-generation-content 1.90.2 → 1.90.4
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 +3 -3
- package/src/domain/interfaces/app-services-auth.interface.ts +27 -0
- package/src/domain/interfaces/app-services-composite.interface.ts +29 -0
- package/src/domain/interfaces/app-services-optional.interface.ts +42 -0
- package/src/domain/interfaces/app-services.interface.ts +0 -79
- package/src/domain/interfaces/index.ts +3 -0
- package/src/domains/background/infrastructure/services/job-poller-index.ts +7 -0
- package/src/domains/background/infrastructure/services/job-poller-utils.ts +127 -0
- package/src/domains/background/infrastructure/services/job-poller.service.ts +85 -140
- package/src/domains/background/infrastructure/utils/polling-interval.util.ts +1 -1
- package/src/domains/background/presentation/hooks/use-background-generation.ts +1 -1
- package/src/domains/content-moderation/index.ts +7 -13
- package/src/domains/content-moderation/infrastructure/services/content-moderation.service.ts +1 -1
- package/src/domains/content-moderation/infrastructure/services/moderators/image.moderator.ts +34 -8
- package/src/domains/content-moderation/infrastructure/services/moderators/text.moderator.ts +15 -4
- package/src/domains/content-moderation/infrastructure/services/moderators/video.moderator.ts +34 -8
- package/src/domains/content-moderation/infrastructure/services/moderators/voice.moderator.ts +19 -8
- package/src/domains/content-moderation/infrastructure/services/pattern-matcher.service.ts +1 -2
- package/src/domains/creations/domain/types/creation-categories.constants.ts +57 -0
- package/src/domains/creations/domain/types/creation-categories.helpers.ts +67 -0
- package/src/domains/creations/domain/types/creation-categories.ts +7 -114
- package/src/domains/creations/domain/utils/creation-display.util.ts +1 -1
- package/src/domains/creations/domain/utils/status-helpers.ts +1 -1
- package/src/domains/creations/presentation/hooks/creation-validators.ts +31 -29
- package/src/domains/creations/presentation/hooks/job-poller-index.ts +10 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.filters.ts +34 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.logger.ts +76 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.stale-handlers.ts +52 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.ts +8 -0
- package/src/domains/creations/presentation/hooks/useCreations.ts +1 -1
- package/src/domains/creations/presentation/hooks/useProcessingJobsPoller.ts +18 -235
- package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +1 -2
- package/src/domains/creations/presentation-exports.ts +2 -2
- package/src/domains/face-detection/domain/entities/FaceDetection.ts +4 -3
- package/src/domains/face-detection/presentation/hooks/useFaceDetection.ts +24 -21
- package/src/domains/generation/infrastructure/appearance-analysis/index.ts +5 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-preparation.ts +58 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-prompt.ts +69 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-resolution.ts +77 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple.ts +54 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-index.ts +8 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-scenario.ts +112 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder.ts +7 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/index.ts +20 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/types.ts +44 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-end-logger.ts +18 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-start-logger.ts +57 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-step-logger.ts +106 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/index.ts +8 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/types.ts +49 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils.ts +8 -0
- package/src/domains/generation/infrastructure/flow/flow-store-actions.ts +105 -0
- package/src/domains/generation/infrastructure/flow/flow-store-initial-state.ts +26 -0
- package/src/domains/generation/infrastructure/flow/useFlowStore.ts +4 -116
- package/src/domains/generation/presentation/useAIGeneration.hook.ts +1 -1
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation-strategy-index.ts +7 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.ts +2 -12
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.types.ts +11 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.utils.ts +12 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +1 -220
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-builder.ts +66 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-extraction.ts +88 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-prompt-builder.ts +74 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-style-enhancements.ts +35 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-strategy-factory.ts +41 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor-index.ts +10 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor.ts +76 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-input-builder.ts +46 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-result-types.ts +17 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-submission.ts +61 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.audio-extractor.ts +27 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.executor.ts +2 -176
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.input-builder.ts +90 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +3 -108
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.types.ts +0 -130
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.validation.ts +136 -0
- package/src/domains/generation/wizard/presentation/hooks/photo-upload/index.ts +40 -0
- package/src/domains/generation/wizard/presentation/hooks/photo-upload/types.ts +37 -0
- package/src/domains/generation/wizard/presentation/hooks/photo-upload/usePhotoUploadStateLogic.ts +142 -0
- package/src/domains/generation/wizard/presentation/hooks/use-video-queue-utils.ts +102 -0
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.handlers.ts +97 -0
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.saver.ts +54 -0
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.ts +22 -87
- package/src/domains/generation/wizard/presentation/hooks/usePhotoUploadState.ts +8 -177
- package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +1 -295
- package/src/domains/generation/wizard/presentation/hooks/useWizardGeneration.ts +1 -1
- package/src/domains/generation/wizard/presentation/hooks/video-queue/index.ts +77 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/use-video-queue-utils.ts +123 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationCallbacks.ts +119 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationPolling.ts +75 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationRefs.ts +65 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationStart.ts +123 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue-index.ts +9 -0
- package/src/domains/image-to-video/domain/types/image-to-video-state.types.ts +11 -4
- package/src/domains/text-to-image/domain/constants/index.ts +5 -6
- package/src/domains/text-to-image/domain/types/text-to-image.types.ts +43 -22
- package/src/domains/text-to-video/domain/types/request.types.ts +32 -9
- package/src/domains/text-to-video/domain/types/state.types.ts +22 -22
- package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.handlers.ts +44 -0
- package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.ts +5 -51
- package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.types.ts +33 -0
- package/src/exports/features.ts +1 -1
- package/src/infrastructure/services/generation-orchestrator.service.ts +2 -2
- package/src/infrastructure/utils/couple-input-context.ts +13 -0
- package/src/infrastructure/utils/couple-input-index.ts +9 -0
- package/src/infrastructure/utils/couple-input-photorealistic.ts +40 -0
- package/src/infrastructure/utils/couple-input-refiner.ts +101 -0
- package/src/infrastructure/utils/couple-input-resolver.ts +71 -0
- package/src/infrastructure/utils/couple-input-types.ts +11 -0
- package/src/infrastructure/utils/couple-input.util.ts +3 -176
- package/src/infrastructure/utils/photo-generation/photo-preparation.util.ts +1 -1
- package/src/infrastructure/validation/base-validator.ts +3 -26
- package/src/infrastructure/validation/base-validator.types.ts +32 -0
- package/src/presentation/hooks/generation/index.ts +1 -1
- package/src/presentation/hooks/generation/orchestrator-abort-logs.ts +48 -0
- package/src/presentation/hooks/generation/orchestrator-execution-logs.ts +67 -0
- package/src/presentation/hooks/generation/orchestrator-index.ts +14 -0
- package/src/presentation/hooks/generation/orchestrator-start-logs.ts +65 -0
- package/src/presentation/hooks/generation/orchestrator-state-utils.ts +17 -0
- package/src/presentation/hooks/generation/orchestrator-types.ts +55 -0
- package/src/presentation/hooks/generation/orchestrator-utils-index.ts +29 -0
- package/src/presentation/hooks/generation/orchestrator-utils.ts +25 -0
- package/src/presentation/hooks/generation/useDualImageGeneration.ts +1 -1
- package/src/presentation/hooks/generation/useImageGeneration.ts +1 -1
- package/src/presentation/hooks/generation/useVideoGeneration.ts +1 -1
- package/src/shared/hooks/factories/generation-hook-index.ts +12 -0
- package/src/shared/hooks/factories/generation-hook-types.ts +47 -0
- package/src/shared/hooks/factories/generation-hook-utils.ts +94 -0
- package/src/shared/hooks/factories/index.ts +1 -1
- package/src/shared/index.ts +1 -1
- package/src/shared/utils/calculations/aspect-ratio-calculations.ts +30 -0
- package/src/shared/utils/calculations/base64-calculations.ts +26 -0
- package/src/shared/utils/calculations/confidence-calculations.ts +21 -0
- package/src/shared/utils/calculations/cost-calculations-index.ts +43 -0
- package/src/shared/utils/calculations/cost-calculations.ts +25 -0
- package/src/shared/utils/calculations/credit-calculations.ts +37 -0
- package/src/shared/utils/calculations/index.ts +46 -0
- package/src/shared/utils/calculations/math-utilities.ts +32 -0
- package/src/shared/utils/calculations/memory-calculations.ts +33 -0
- package/src/shared/utils/calculations/pagination-calculations.ts +38 -0
- package/src/shared/utils/calculations/percentage-calculations.ts +33 -0
- package/src/shared/utils/calculations/time-calculations.ts +99 -0
- package/src/shared/utils/credit.ts +1 -1
- package/src/shared-kernel/application/hooks/index.ts +8 -0
- package/src/shared-kernel/application/hooks/use-feature-state.ts +106 -0
- package/src/shared-kernel/application/hooks/use-generation-handler.ts +110 -0
- package/src/shared-kernel/base-types/base-callbacks.types.ts +73 -0
- package/src/shared-kernel/base-types/base-feature-state.types.ts +77 -0
- package/src/shared-kernel/base-types/base-generation.types.ts +69 -0
- package/src/shared-kernel/base-types/index.ts +30 -0
- package/src/shared-kernel/domain/base-generation-strategy.ts +146 -0
- package/src/shared-kernel/domain/index.ts +7 -0
- package/src/shared-kernel/index.ts +17 -0
- package/src/shared-kernel/infrastructure/validation/common-validators.ts +126 -0
- package/src/shared-kernel/infrastructure/validation/common-validators.types.ts +33 -0
- package/src/shared-kernel/infrastructure/validation/error-handler.ts +52 -0
- package/src/shared-kernel/infrastructure/validation/error-handler.types.ts +38 -0
- package/src/shared-kernel/infrastructure/validation/error-handler.utils.ts +79 -0
- package/src/shared-kernel/infrastructure/validation/index.ts +70 -0
- package/src/domains/content-moderation/infrastructure/services/index.ts +0 -8
- package/src/domains/creations/domain/constants/index.ts +0 -12
- package/src/domains/creations/domain/utils/index.ts +0 -12
- package/src/domains/generation/infrastructure/couple-generation-builder.ts +0 -374
- package/src/domains/image-to-video/domain/index.ts +0 -2
- package/src/domains/image-to-video/infrastructure/index.ts +0 -1
- package/src/domains/image-to-video/presentation/index.ts +0 -5
- package/src/domains/text-to-video/domain/index.ts +0 -1
- package/src/domains/text-to-video/presentation/index.ts +0 -7
- package/src/presentation/hooks/generation/orchestrator.ts +0 -276
- package/src/shared/hooks/factories/createGenerationHook.ts +0 -253
- package/src/shared/utils/calculations.util.ts +0 -366
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base feature state types for AI generation features
|
|
3
|
+
* Provides consistent state management across all domains
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { GenerationProgress } from './base-generation.types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Base state for all generation features
|
|
10
|
+
* Used by hooks and components for consistent state management
|
|
11
|
+
*/
|
|
12
|
+
export interface BaseFeatureState<TOutput = string> {
|
|
13
|
+
/** Whether a generation is currently in progress */
|
|
14
|
+
isProcessing: boolean;
|
|
15
|
+
/** Current generation progress (0-1) */
|
|
16
|
+
progress: number;
|
|
17
|
+
/** Error message if operation failed */
|
|
18
|
+
error: string | null;
|
|
19
|
+
/** Generated output data */
|
|
20
|
+
output: TOutput | null;
|
|
21
|
+
/** Additional progress information */
|
|
22
|
+
progressInfo?: GenerationProgress;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Feature state with additional metadata
|
|
27
|
+
*/
|
|
28
|
+
export interface FeatureStateWithMetadata<TOutput = string> extends BaseFeatureState<TOutput> {
|
|
29
|
+
/** Unique ID for the current generation job */
|
|
30
|
+
jobId?: string;
|
|
31
|
+
/** Timestamp when generation started */
|
|
32
|
+
startedAt?: number;
|
|
33
|
+
/** Timestamp when generation completed */
|
|
34
|
+
completedAt?: number;
|
|
35
|
+
/** Number of retry attempts */
|
|
36
|
+
retryCount?: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Actions that can be performed on feature state
|
|
41
|
+
*/
|
|
42
|
+
export type FeatureStateAction<TOutput = string> =
|
|
43
|
+
| { type: 'START'; jobId?: string }
|
|
44
|
+
| { type: 'PROGRESS'; progress: number; status?: string }
|
|
45
|
+
| { type: 'SUCCESS'; output: TOutput; metadata?: Record<string, unknown> }
|
|
46
|
+
| { type: 'ERROR'; error: string }
|
|
47
|
+
| { type: 'RESET' };
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Initial state factory
|
|
51
|
+
*/
|
|
52
|
+
export function createInitialFeatureState<TOutput = string>(): BaseFeatureState<TOutput> {
|
|
53
|
+
return {
|
|
54
|
+
isProcessing: false,
|
|
55
|
+
progress: 0,
|
|
56
|
+
error: null,
|
|
57
|
+
output: null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Check if feature state is in an error state
|
|
63
|
+
*/
|
|
64
|
+
export function isFeatureStateError<TOutput = string>(
|
|
65
|
+
state: BaseFeatureState<TOutput>
|
|
66
|
+
): boolean {
|
|
67
|
+
return state.error !== null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check if feature state has output
|
|
72
|
+
*/
|
|
73
|
+
export function hasFeatureStateOutput<TOutput = string>(
|
|
74
|
+
state: BaseFeatureState<TOutput>
|
|
75
|
+
): boolean {
|
|
76
|
+
return state.output !== null;
|
|
77
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base types for AI generation operations
|
|
3
|
+
* Shared across all generation domains (text-to-image, text-to-video, image-to-video, etc.)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Common aspect ratios used across all generation types
|
|
8
|
+
*/
|
|
9
|
+
export type AspectRatio = '16:9' | '9:16' | '1:1' | '4:3' | '3:4';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Base generation options that are common to most generation types
|
|
13
|
+
*/
|
|
14
|
+
export interface BaseGenerationOptions {
|
|
15
|
+
/** Output aspect ratio */
|
|
16
|
+
aspectRatio?: AspectRatio;
|
|
17
|
+
/** Number of steps/inference iterations */
|
|
18
|
+
steps?: number;
|
|
19
|
+
/** Guidance scale for generation (0-20 typically) */
|
|
20
|
+
guidanceScale?: number;
|
|
21
|
+
/** Random seed for reproducible results */
|
|
22
|
+
seed?: number;
|
|
23
|
+
/** Number of outputs to generate */
|
|
24
|
+
numOutputs?: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Common generation request metadata
|
|
29
|
+
*/
|
|
30
|
+
export interface BaseRequestMeta {
|
|
31
|
+
/** Unique identifier for this request */
|
|
32
|
+
requestId: string;
|
|
33
|
+
/** User ID making the request */
|
|
34
|
+
userId: string;
|
|
35
|
+
/** Timestamp when request was created */
|
|
36
|
+
timestamp: number;
|
|
37
|
+
/** Request priority for queue management */
|
|
38
|
+
priority?: 'low' | 'normal' | 'high';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Standard generation result structure
|
|
43
|
+
*/
|
|
44
|
+
export interface BaseGenerationResult<T = string> {
|
|
45
|
+
/** Whether the generation was successful */
|
|
46
|
+
success: boolean;
|
|
47
|
+
/** Generated content URL or data */
|
|
48
|
+
data?: T;
|
|
49
|
+
/** Error message if generation failed */
|
|
50
|
+
error?: string;
|
|
51
|
+
/** Request identifier */
|
|
52
|
+
requestId: string;
|
|
53
|
+
/** Time taken to complete generation (ms) */
|
|
54
|
+
duration?: number;
|
|
55
|
+
/** Additional metadata */
|
|
56
|
+
metadata?: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Generation progress information
|
|
61
|
+
*/
|
|
62
|
+
export interface GenerationProgress {
|
|
63
|
+
/** Current progress (0-1) */
|
|
64
|
+
progress: number;
|
|
65
|
+
/** Current status message */
|
|
66
|
+
status?: string;
|
|
67
|
+
/** Estimated time remaining (ms) */
|
|
68
|
+
eta?: number;
|
|
69
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared kernel base types
|
|
3
|
+
* Exports all base types for use across domains
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type {
|
|
7
|
+
AspectRatio,
|
|
8
|
+
BaseGenerationOptions,
|
|
9
|
+
BaseRequestMeta,
|
|
10
|
+
BaseGenerationResult,
|
|
11
|
+
GenerationProgress,
|
|
12
|
+
} from './base-generation.types';
|
|
13
|
+
|
|
14
|
+
export type {
|
|
15
|
+
BaseFeatureState,
|
|
16
|
+
FeatureStateWithMetadata,
|
|
17
|
+
FeatureStateAction,
|
|
18
|
+
createInitialFeatureState,
|
|
19
|
+
isFeatureStateError,
|
|
20
|
+
hasFeatureStateOutput,
|
|
21
|
+
} from './base-feature-state.types';
|
|
22
|
+
|
|
23
|
+
export type {
|
|
24
|
+
CreditCallbacks,
|
|
25
|
+
ProgressCallbacks,
|
|
26
|
+
ResultCallbacks,
|
|
27
|
+
BaseGenerationCallbacks,
|
|
28
|
+
ValidationCallbacks,
|
|
29
|
+
LifecycleCallbacks,
|
|
30
|
+
} from './base-callbacks.types';
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base strategy pattern for generation operations
|
|
3
|
+
* Eliminates duplicate strategy implementations across domains
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
BaseGenerationCallbacks,
|
|
8
|
+
BaseGenerationResult,
|
|
9
|
+
BaseRequestMeta,
|
|
10
|
+
GenerationProgress,
|
|
11
|
+
} from '../base-types';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Base strategy interface for all generation operations
|
|
15
|
+
*/
|
|
16
|
+
export interface IGenerationStrategy<TInput, TOutput> {
|
|
17
|
+
/** Execute the generation operation */
|
|
18
|
+
execute(input: TInput, meta: BaseRequestMeta): Promise<BaseGenerationResult<TOutput>>;
|
|
19
|
+
/** Validate input before execution */
|
|
20
|
+
validate(input: TInput): boolean | Promise<boolean>;
|
|
21
|
+
/** Get estimated cost in credits */
|
|
22
|
+
getCreditCost(input: TInput): number;
|
|
23
|
+
/** Cancel ongoing generation */
|
|
24
|
+
cancel?(): void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Abstract base class for generation strategies
|
|
29
|
+
* Provides common implementation for all strategies
|
|
30
|
+
*/
|
|
31
|
+
export abstract class BaseGenerationStrategy<TInput, TOutput>
|
|
32
|
+
implements IGenerationStrategy<TInput, TOutput>
|
|
33
|
+
{
|
|
34
|
+
protected callbacks?: BaseGenerationCallbacks<TOutput>;
|
|
35
|
+
protected isCancelled = false;
|
|
36
|
+
|
|
37
|
+
constructor(callbacks?: BaseGenerationCallbacks<TOutput>) {
|
|
38
|
+
this.callbacks = callbacks;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Execute generation with consistent error handling and callbacks
|
|
43
|
+
*/
|
|
44
|
+
async execute(
|
|
45
|
+
input: TInput,
|
|
46
|
+
meta: BaseRequestMeta
|
|
47
|
+
): Promise<BaseGenerationResult<TOutput>> {
|
|
48
|
+
const startTime = Date.now();
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
this.isCancelled = false;
|
|
52
|
+
this.callbacks?.onStart?.();
|
|
53
|
+
|
|
54
|
+
// Validate input
|
|
55
|
+
const isValid = await this.validate(input);
|
|
56
|
+
if (!isValid) {
|
|
57
|
+
throw new Error('Invalid input');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Check credits
|
|
61
|
+
const creditCost = this.getCreditCost(input);
|
|
62
|
+
if (this.callbacks?.onCreditCheck) {
|
|
63
|
+
const hasCredits = await this.callbacks.onCreditCheck();
|
|
64
|
+
if (!hasCredits) {
|
|
65
|
+
this.callbacks?.onShowPaywall?.();
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
error: 'Insufficient credits',
|
|
69
|
+
requestId: meta.requestId,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Execute generation
|
|
75
|
+
const result = await this.doExecute(input, meta);
|
|
76
|
+
|
|
77
|
+
if (this.isCancelled) {
|
|
78
|
+
this.callbacks?.onCancel?.();
|
|
79
|
+
return {
|
|
80
|
+
success: false,
|
|
81
|
+
error: 'Generation cancelled',
|
|
82
|
+
requestId: meta.requestId,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (result.success) {
|
|
87
|
+
this.callbacks?.onSuccess?.(result);
|
|
88
|
+
this.callbacks?.onCreditsConsumed?.(creditCost);
|
|
89
|
+
} else {
|
|
90
|
+
const error = new Error(result.error || 'Generation failed');
|
|
91
|
+
this.callbacks?.onError?.(error);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
this.callbacks?.onComplete?.();
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
...result,
|
|
98
|
+
duration: Date.now() - startTime,
|
|
99
|
+
};
|
|
100
|
+
} catch (error) {
|
|
101
|
+
const err = error instanceof Error ? error : new Error('Unknown error');
|
|
102
|
+
this.callbacks?.onError?.(err);
|
|
103
|
+
this.callbacks?.onComplete?.();
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
success: false,
|
|
107
|
+
error: err.message,
|
|
108
|
+
requestId: meta.requestId,
|
|
109
|
+
duration: Date.now() - startTime,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Abstract method to be implemented by concrete strategies
|
|
116
|
+
*/
|
|
117
|
+
protected abstract doExecute(
|
|
118
|
+
input: TInput,
|
|
119
|
+
meta: BaseRequestMeta
|
|
120
|
+
): Promise<BaseGenerationResult<TOutput>>;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Abstract validation method to be implemented by concrete strategies
|
|
124
|
+
*/
|
|
125
|
+
abstract validate(input: TInput): boolean | Promise<boolean>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Abstract credit cost method to be implemented by concrete strategies
|
|
129
|
+
*/
|
|
130
|
+
abstract getCreditCost(input: TInput): number;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Cancel ongoing generation
|
|
134
|
+
*/
|
|
135
|
+
cancel(): void {
|
|
136
|
+
this.isCancelled = true;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Report progress during generation
|
|
141
|
+
*/
|
|
142
|
+
protected reportProgress(progress: number, status?: string): void {
|
|
143
|
+
const progressInfo: GenerationProgress = { progress, status };
|
|
144
|
+
this.callbacks?.onProgress?.(progressInfo);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Kernel Module
|
|
3
|
+
* Provides base types, utilities, and patterns for all domains
|
|
4
|
+
* Following DDD principles with clean architecture
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Base types
|
|
8
|
+
export * from './base-types';
|
|
9
|
+
|
|
10
|
+
// Application services
|
|
11
|
+
export * from './application/hooks';
|
|
12
|
+
|
|
13
|
+
// Domain layer
|
|
14
|
+
export * from './domain';
|
|
15
|
+
|
|
16
|
+
// Infrastructure utilities
|
|
17
|
+
export * from './infrastructure/validation';
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common validation utilities
|
|
3
|
+
* Shared validation logic across all domains
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ValidationResult, StringValidationOptions, NumberValidationOptions } from "./common-validators.types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Validate a string value
|
|
10
|
+
*/
|
|
11
|
+
export function validateString(
|
|
12
|
+
value: string,
|
|
13
|
+
options: StringValidationOptions = {}
|
|
14
|
+
): ValidationResult {
|
|
15
|
+
const errors: Record<string, string> = {};
|
|
16
|
+
let processedValue = value;
|
|
17
|
+
|
|
18
|
+
if (options.trim) {
|
|
19
|
+
processedValue = value.trim();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (options.required && !processedValue) {
|
|
23
|
+
errors.required = 'This field is required';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (options.minLength && processedValue.length < options.minLength) {
|
|
27
|
+
errors.minLength = `Minimum length is ${options.minLength}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (options.maxLength && processedValue.length > options.maxLength) {
|
|
31
|
+
errors.maxLength = `Maximum length is ${options.maxLength}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (options.pattern && !options.pattern.test(processedValue)) {
|
|
35
|
+
errors.pattern = 'Invalid format';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
isValid: Object.keys(errors).length === 0,
|
|
40
|
+
errors,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Validate a number value
|
|
46
|
+
*/
|
|
47
|
+
export function validateNumber(
|
|
48
|
+
value: number,
|
|
49
|
+
options: NumberValidationOptions = {}
|
|
50
|
+
): ValidationResult {
|
|
51
|
+
const errors: Record<string, string> = {};
|
|
52
|
+
|
|
53
|
+
if (options.required && (value === null || value === undefined)) {
|
|
54
|
+
errors.required = 'This field is required';
|
|
55
|
+
return { isValid: false, errors };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (value === null || value === undefined) {
|
|
59
|
+
return { isValid: true, errors: {} };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (options.integer && !Number.isInteger(value)) {
|
|
63
|
+
errors.integer = 'Must be an integer';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (options.min !== undefined && value < options.min) {
|
|
67
|
+
errors.min = `Minimum value is ${options.min}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (options.max !== undefined && value > options.max) {
|
|
71
|
+
errors.max = `Maximum value is ${options.max}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
isValid: Object.keys(errors).length === 0,
|
|
76
|
+
errors,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Validate a URL
|
|
82
|
+
*/
|
|
83
|
+
export function validateUrl(url: string): ValidationResult {
|
|
84
|
+
const urlPattern = /^https?:\/\/.+/i;
|
|
85
|
+
return validateString(url, {
|
|
86
|
+
required: true,
|
|
87
|
+
pattern: urlPattern,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Validate an object has required fields
|
|
93
|
+
*/
|
|
94
|
+
export function validateRequiredFields<T extends Record<string, unknown>>(
|
|
95
|
+
obj: T,
|
|
96
|
+
requiredFields: (keyof T)[]
|
|
97
|
+
): ValidationResult {
|
|
98
|
+
const errors: Record<string, string> = {};
|
|
99
|
+
|
|
100
|
+
for (const field of requiredFields) {
|
|
101
|
+
if (obj[field] === null || obj[field] === undefined) {
|
|
102
|
+
errors[field as string] = `${String(field)} is required`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
isValid: Object.keys(errors).length === 0,
|
|
108
|
+
errors,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Combine multiple validation results
|
|
114
|
+
*/
|
|
115
|
+
export function combineValidationResults(
|
|
116
|
+
...results: ValidationResult[]
|
|
117
|
+
): ValidationResult {
|
|
118
|
+
const allErrors = results.reduce((acc, result) => {
|
|
119
|
+
return { ...acc, ...result.errors };
|
|
120
|
+
}, {} as Record<string, string>);
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
isValid: Object.keys(allErrors).length === 0,
|
|
124
|
+
errors: allErrors,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common validation utilities - Types
|
|
3
|
+
* Type definitions for validation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Validation result structure
|
|
8
|
+
*/
|
|
9
|
+
export interface ValidationResult {
|
|
10
|
+
isValid: boolean;
|
|
11
|
+
errors: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* String validation options
|
|
16
|
+
*/
|
|
17
|
+
export interface StringValidationOptions {
|
|
18
|
+
minLength?: number;
|
|
19
|
+
maxLength?: number;
|
|
20
|
+
pattern?: RegExp;
|
|
21
|
+
required?: boolean;
|
|
22
|
+
trim?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Number validation options
|
|
27
|
+
*/
|
|
28
|
+
export interface NumberValidationOptions {
|
|
29
|
+
min?: number;
|
|
30
|
+
max?: number;
|
|
31
|
+
integer?: boolean;
|
|
32
|
+
required?: boolean;
|
|
33
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized error handling utilities
|
|
3
|
+
* Standardizes error handling across all domains
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { AppError, ErrorHandlerOptions } from "./error-handler.types";
|
|
7
|
+
import { toAppError, getUserFriendlyMessage } from "./error-handler.utils";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Handle error with consistent behavior
|
|
11
|
+
*/
|
|
12
|
+
export function handleError(
|
|
13
|
+
error: unknown,
|
|
14
|
+
options: ErrorHandlerOptions = {}
|
|
15
|
+
): AppError {
|
|
16
|
+
const {
|
|
17
|
+
logErrors = true,
|
|
18
|
+
showUserMessage = true,
|
|
19
|
+
transformError,
|
|
20
|
+
} = options;
|
|
21
|
+
|
|
22
|
+
const appError = toAppError(error);
|
|
23
|
+
const finalError = transformError ? transformError(appError) : appError;
|
|
24
|
+
|
|
25
|
+
if (logErrors) {
|
|
26
|
+
console.error('[Error Handler]', finalError);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (showUserMessage) {
|
|
30
|
+
const userMessage = getUserFriendlyMessage(finalError);
|
|
31
|
+
// Could integrate with notification system here
|
|
32
|
+
console.warn('[User Message]', userMessage);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return finalError;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Wrap async function with error handling
|
|
40
|
+
*/
|
|
41
|
+
export function withErrorHandling<T extends (...args: unknown[]) => Promise<unknown>>(
|
|
42
|
+
fn: T,
|
|
43
|
+
options: ErrorHandlerOptions = {}
|
|
44
|
+
): T {
|
|
45
|
+
return (async (...args: Parameters<T>) => {
|
|
46
|
+
try {
|
|
47
|
+
return await fn(...args);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
throw handleError(error, options);
|
|
50
|
+
}
|
|
51
|
+
}) as T;
|
|
52
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handler - Types
|
|
3
|
+
* Type definitions for error handling
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Error types for categorization
|
|
8
|
+
*/
|
|
9
|
+
export enum ErrorType {
|
|
10
|
+
VALIDATION = 'VALIDATION',
|
|
11
|
+
NETWORK = 'NETWORK',
|
|
12
|
+
CREDIT = 'CREDIT',
|
|
13
|
+
PROVIDER = 'PROVIDER',
|
|
14
|
+
UNKNOWN = 'UNKNOWN',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Application error structure
|
|
19
|
+
*/
|
|
20
|
+
export interface AppError {
|
|
21
|
+
type: ErrorType;
|
|
22
|
+
message: string;
|
|
23
|
+
code?: string;
|
|
24
|
+
details?: Record<string, unknown>;
|
|
25
|
+
originalError?: unknown;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Error handler options
|
|
30
|
+
*/
|
|
31
|
+
export interface ErrorHandlerOptions {
|
|
32
|
+
/** Log errors to console */
|
|
33
|
+
logErrors?: boolean;
|
|
34
|
+
/** Show user-friendly messages */
|
|
35
|
+
showUserMessage?: boolean;
|
|
36
|
+
/** Custom error transformer */
|
|
37
|
+
transformError?: (error: AppError) => AppError;
|
|
38
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handler - Utilities
|
|
3
|
+
* Utility functions for error handling
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { AppError } from "./error-handler.types";
|
|
7
|
+
import { ErrorType } from "./error-handler.types";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Create a standardized application error
|
|
11
|
+
*/
|
|
12
|
+
export function createError(
|
|
13
|
+
type: ErrorType,
|
|
14
|
+
message: string,
|
|
15
|
+
code?: string,
|
|
16
|
+
details?: Record<string, unknown>,
|
|
17
|
+
originalError?: unknown
|
|
18
|
+
): AppError {
|
|
19
|
+
return {
|
|
20
|
+
type,
|
|
21
|
+
message,
|
|
22
|
+
code,
|
|
23
|
+
details,
|
|
24
|
+
originalError,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Convert unknown error to AppError
|
|
30
|
+
*/
|
|
31
|
+
export function toAppError(error: unknown): AppError {
|
|
32
|
+
if (isAppError(error)) {
|
|
33
|
+
return error;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (error instanceof Error) {
|
|
37
|
+
return {
|
|
38
|
+
type: ErrorType.UNKNOWN,
|
|
39
|
+
message: error.message,
|
|
40
|
+
originalError: error,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
type: ErrorType.UNKNOWN,
|
|
46
|
+
message: String(error),
|
|
47
|
+
originalError: error,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Check if error is AppError
|
|
53
|
+
*/
|
|
54
|
+
export function isAppError(error: unknown): error is AppError {
|
|
55
|
+
return (
|
|
56
|
+
typeof error === 'object' &&
|
|
57
|
+
error !== null &&
|
|
58
|
+
'type' in error &&
|
|
59
|
+
'message' in error
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get user-friendly error message
|
|
65
|
+
*/
|
|
66
|
+
export function getUserFriendlyMessage(error: AppError): string {
|
|
67
|
+
switch (error.type) {
|
|
68
|
+
case ErrorType.VALIDATION:
|
|
69
|
+
return 'Please check your input and try again.';
|
|
70
|
+
case ErrorType.NETWORK:
|
|
71
|
+
return 'Network error. Please check your connection and try again.';
|
|
72
|
+
case ErrorType.CREDIT:
|
|
73
|
+
return 'Insufficient credits. Please upgrade to continue.';
|
|
74
|
+
case ErrorType.PROVIDER:
|
|
75
|
+
return 'Service temporarily unavailable. Please try again later.';
|
|
76
|
+
default:
|
|
77
|
+
return error.message || 'An unexpected error occurred.';
|
|
78
|
+
}
|
|
79
|
+
}
|