@umituz/react-native-ai-generation-content 1.2.0 → 1.4.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/entities/index.ts +1 -0
- package/src/domain/entities/middleware.types.ts +56 -0
- package/src/index.ts +24 -0
- package/src/infrastructure/middleware/credit-check.middleware.ts +74 -0
- package/src/infrastructure/middleware/history-tracking.middleware.ts +69 -0
- package/src/infrastructure/middleware/index.ts +15 -0
- package/src/infrastructure/services/generation-wrapper.service.ts +148 -0
- package/src/infrastructure/services/index.ts +5 -0
package/package.json
CHANGED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware Types
|
|
3
|
+
* Generic middleware pattern for generation workflow
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { GenerationRequest, GenerationResult } from "./generation.types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Context passed to middleware hooks
|
|
10
|
+
*/
|
|
11
|
+
export interface MiddlewareContext {
|
|
12
|
+
request: GenerationRequest;
|
|
13
|
+
userId?: string;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Result context passed to afterGenerate hook
|
|
19
|
+
*/
|
|
20
|
+
export interface MiddlewareResultContext<T> extends MiddlewareContext {
|
|
21
|
+
result: GenerationResult<T>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Middleware hook executed before generation
|
|
26
|
+
* Can throw error to prevent generation
|
|
27
|
+
*/
|
|
28
|
+
export type BeforeGenerateHook = (
|
|
29
|
+
context: MiddlewareContext,
|
|
30
|
+
) => Promise<void> | void;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Middleware hook executed after generation (success or failure)
|
|
34
|
+
* Cannot modify result, used for logging/tracking
|
|
35
|
+
*/
|
|
36
|
+
export type AfterGenerateHook<T = unknown> = (
|
|
37
|
+
context: MiddlewareResultContext<T>,
|
|
38
|
+
) => Promise<void> | void;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Complete middleware configuration
|
|
42
|
+
*/
|
|
43
|
+
export interface GenerationMiddleware {
|
|
44
|
+
/** Hook executed before generation starts */
|
|
45
|
+
beforeGenerate?: BeforeGenerateHook;
|
|
46
|
+
/** Hook executed after generation completes (success or failure) */
|
|
47
|
+
afterGenerate?: AfterGenerateHook;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Middleware chain configuration
|
|
52
|
+
*/
|
|
53
|
+
export interface MiddlewareChain {
|
|
54
|
+
/** Array of middleware to execute in order */
|
|
55
|
+
middleware: GenerationMiddleware[];
|
|
56
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -42,6 +42,12 @@ export type {
|
|
|
42
42
|
PollingOptions,
|
|
43
43
|
ProgressStageConfig,
|
|
44
44
|
ProgressConfig,
|
|
45
|
+
MiddlewareContext,
|
|
46
|
+
MiddlewareResultContext,
|
|
47
|
+
BeforeGenerateHook,
|
|
48
|
+
AfterGenerateHook,
|
|
49
|
+
GenerationMiddleware,
|
|
50
|
+
MiddlewareChain,
|
|
45
51
|
} from "./domain/entities";
|
|
46
52
|
|
|
47
53
|
export { DEFAULT_POLLING_CONFIG, DEFAULT_PROGRESS_STAGES } from "./domain/entities";
|
|
@@ -55,14 +61,32 @@ export {
|
|
|
55
61
|
generationOrchestrator,
|
|
56
62
|
pollJob,
|
|
57
63
|
createJobPoller,
|
|
64
|
+
generationWrapper,
|
|
65
|
+
createGenerationWrapper,
|
|
58
66
|
} from "./infrastructure/services";
|
|
59
67
|
|
|
60
68
|
export type {
|
|
61
69
|
OrchestratorConfig,
|
|
62
70
|
PollJobOptions,
|
|
63
71
|
PollJobResult,
|
|
72
|
+
WrapperConfig,
|
|
64
73
|
} from "./infrastructure/services";
|
|
65
74
|
|
|
75
|
+
// =============================================================================
|
|
76
|
+
// INFRASTRUCTURE LAYER - Middleware Factories
|
|
77
|
+
// =============================================================================
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
createCreditCheckMiddleware,
|
|
81
|
+
createHistoryTrackingMiddleware,
|
|
82
|
+
} from "./infrastructure/middleware";
|
|
83
|
+
|
|
84
|
+
export type {
|
|
85
|
+
CreditCheckConfig,
|
|
86
|
+
HistoryConfig,
|
|
87
|
+
HistoryEntry,
|
|
88
|
+
} from "./infrastructure/middleware";
|
|
89
|
+
|
|
66
90
|
// =============================================================================
|
|
67
91
|
// INFRASTRUCTURE LAYER - Utils
|
|
68
92
|
// =============================================================================
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credit Check Middleware Factory
|
|
3
|
+
* Generic credit checking with app-provided config
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { GenerationMiddleware } from "../../domain/entities";
|
|
7
|
+
|
|
8
|
+
export interface CreditCheckConfig {
|
|
9
|
+
/**
|
|
10
|
+
* Get credit type from operation type
|
|
11
|
+
* App-specific logic
|
|
12
|
+
*/
|
|
13
|
+
getCreditType: (operationType: string) => string;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if user has available credits
|
|
17
|
+
* App provides implementation
|
|
18
|
+
*/
|
|
19
|
+
checkCredits: (
|
|
20
|
+
userId: string | undefined,
|
|
21
|
+
operationType: string,
|
|
22
|
+
) => Promise<{
|
|
23
|
+
success: boolean;
|
|
24
|
+
error?: string;
|
|
25
|
+
creditType?: string;
|
|
26
|
+
}>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Deduct credits after successful generation
|
|
30
|
+
* App provides implementation
|
|
31
|
+
*/
|
|
32
|
+
deductCredits: (
|
|
33
|
+
userId: string | undefined,
|
|
34
|
+
creditType: string,
|
|
35
|
+
) => Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Create credit check middleware
|
|
40
|
+
* Checks credits before generation, deducts after success
|
|
41
|
+
*/
|
|
42
|
+
export function createCreditCheckMiddleware(
|
|
43
|
+
config: CreditCheckConfig,
|
|
44
|
+
): GenerationMiddleware {
|
|
45
|
+
return {
|
|
46
|
+
async beforeGenerate(context) {
|
|
47
|
+
const operationType =
|
|
48
|
+
(context.request.input?.type as string) || "default";
|
|
49
|
+
|
|
50
|
+
const result = await config.checkCredits(
|
|
51
|
+
context.userId,
|
|
52
|
+
operationType,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
if (!result.success) {
|
|
56
|
+
throw new Error(result.error || "credits_exhausted");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
context.metadata = {
|
|
60
|
+
...context.metadata,
|
|
61
|
+
creditType: result.creditType || config.getCreditType(operationType),
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
async afterGenerate(context) {
|
|
66
|
+
if (context.result.success && context.metadata?.creditType) {
|
|
67
|
+
await config.deductCredits(
|
|
68
|
+
context.userId,
|
|
69
|
+
context.metadata.creditType as string,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* History Tracking Middleware Factory
|
|
3
|
+
* Generic history saving with app-provided config
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { GenerationMiddleware } from "../../domain/entities";
|
|
7
|
+
|
|
8
|
+
export interface HistoryEntry {
|
|
9
|
+
type: string;
|
|
10
|
+
prompt: string;
|
|
11
|
+
result: string | null;
|
|
12
|
+
success: boolean;
|
|
13
|
+
error?: string;
|
|
14
|
+
userId: string;
|
|
15
|
+
metadata?: Record<string, unknown>;
|
|
16
|
+
timestamp: unknown;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface HistoryConfig {
|
|
20
|
+
/**
|
|
21
|
+
* Save generation to history
|
|
22
|
+
* App provides storage implementation (Firestore, API, etc.)
|
|
23
|
+
*/
|
|
24
|
+
saveToHistory: (entry: HistoryEntry) => Promise<void>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Create timestamp for history entry
|
|
28
|
+
* App-specific (serverTimestamp for Firestore, new Date() for API, etc.)
|
|
29
|
+
*/
|
|
30
|
+
createTimestamp: () => unknown;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Create history tracking middleware
|
|
35
|
+
* Saves generation history after completion
|
|
36
|
+
*/
|
|
37
|
+
export function createHistoryTrackingMiddleware(
|
|
38
|
+
config: HistoryConfig,
|
|
39
|
+
): GenerationMiddleware {
|
|
40
|
+
return {
|
|
41
|
+
async afterGenerate(context) {
|
|
42
|
+
if (!context.userId) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const operationType =
|
|
48
|
+
(context.request.input?.type as string) || "default";
|
|
49
|
+
const prompt =
|
|
50
|
+
(context.request.input?.prompt as string) || "";
|
|
51
|
+
|
|
52
|
+
const entry: HistoryEntry = {
|
|
53
|
+
type: operationType,
|
|
54
|
+
prompt,
|
|
55
|
+
result: context.result.success ? String(context.result.data) : null,
|
|
56
|
+
success: context.result.success,
|
|
57
|
+
error: context.result.error,
|
|
58
|
+
userId: context.userId,
|
|
59
|
+
metadata: context.result.metadata as Record<string, unknown>,
|
|
60
|
+
timestamp: config.createTimestamp(),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
await config.saveToHistory(entry);
|
|
64
|
+
} catch {
|
|
65
|
+
// Silent fail
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware Factories
|
|
3
|
+
* Generic middleware with app-provided config
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
createCreditCheckMiddleware,
|
|
8
|
+
type CreditCheckConfig,
|
|
9
|
+
} from "./credit-check.middleware";
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
createHistoryTrackingMiddleware,
|
|
13
|
+
type HistoryConfig,
|
|
14
|
+
type HistoryEntry,
|
|
15
|
+
} from "./history-tracking.middleware";
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generation Wrapper Service
|
|
3
|
+
* Wraps orchestrator with middleware support
|
|
4
|
+
* Enables credit checking, moderation, history via middleware pattern
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
GenerationRequest,
|
|
9
|
+
GenerationResult,
|
|
10
|
+
GenerationMiddleware,
|
|
11
|
+
MiddlewareContext,
|
|
12
|
+
MiddlewareResultContext,
|
|
13
|
+
} from "../../domain/entities";
|
|
14
|
+
import { generationOrchestrator } from "./generation-orchestrator.service";
|
|
15
|
+
import type { OrchestratorConfig } from "./generation-orchestrator.service";
|
|
16
|
+
|
|
17
|
+
export interface WrapperConfig {
|
|
18
|
+
/** Middleware to execute before/after generation */
|
|
19
|
+
middleware?: GenerationMiddleware[];
|
|
20
|
+
/** Orchestrator configuration */
|
|
21
|
+
orchestratorConfig?: OrchestratorConfig;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
class GenerationWrapperService {
|
|
25
|
+
private middleware: GenerationMiddleware[] = [];
|
|
26
|
+
private orchestratorConfig?: OrchestratorConfig;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Configure wrapper with middleware
|
|
30
|
+
*/
|
|
31
|
+
configure(config: WrapperConfig): void {
|
|
32
|
+
this.middleware = config.middleware || [];
|
|
33
|
+
this.orchestratorConfig = config.orchestratorConfig;
|
|
34
|
+
|
|
35
|
+
if (this.orchestratorConfig) {
|
|
36
|
+
generationOrchestrator.configure(this.orchestratorConfig);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Add middleware to chain
|
|
42
|
+
*/
|
|
43
|
+
use(middleware: GenerationMiddleware): void {
|
|
44
|
+
this.middleware.push(middleware);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Clear all middleware
|
|
49
|
+
*/
|
|
50
|
+
clearMiddleware(): void {
|
|
51
|
+
this.middleware = [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Generate with middleware support
|
|
56
|
+
*/
|
|
57
|
+
async generate<T = unknown>(
|
|
58
|
+
request: GenerationRequest,
|
|
59
|
+
userId?: string,
|
|
60
|
+
metadata?: Record<string, unknown>,
|
|
61
|
+
): Promise<GenerationResult<T>> {
|
|
62
|
+
const startTime = Date.now();
|
|
63
|
+
|
|
64
|
+
const context: MiddlewareContext = {
|
|
65
|
+
request,
|
|
66
|
+
userId,
|
|
67
|
+
metadata,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
await this.executeBeforeHooks(context);
|
|
72
|
+
|
|
73
|
+
const result = await generationOrchestrator.generate<T>(request);
|
|
74
|
+
|
|
75
|
+
const resultContext: MiddlewareResultContext<T> = {
|
|
76
|
+
...context,
|
|
77
|
+
result,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
await this.executeAfterHooks(resultContext);
|
|
81
|
+
|
|
82
|
+
return result;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
const errorResult: GenerationResult<T> = {
|
|
85
|
+
success: false,
|
|
86
|
+
error: error instanceof Error ? error.message : String(error),
|
|
87
|
+
metadata: {
|
|
88
|
+
model: request.model || "unknown",
|
|
89
|
+
startTime,
|
|
90
|
+
endTime: Date.now(),
|
|
91
|
+
duration: Date.now() - startTime,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const resultContext: MiddlewareResultContext<T> = {
|
|
96
|
+
...context,
|
|
97
|
+
result: errorResult,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
await this.executeAfterHooks(resultContext).catch(() => {
|
|
101
|
+
// Silent fail on afterHooks error
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return errorResult;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Execute all beforeGenerate hooks
|
|
110
|
+
*/
|
|
111
|
+
private async executeBeforeHooks(
|
|
112
|
+
context: MiddlewareContext,
|
|
113
|
+
): Promise<void> {
|
|
114
|
+
for (const mw of this.middleware) {
|
|
115
|
+
if (mw.beforeGenerate) {
|
|
116
|
+
await mw.beforeGenerate(context);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Execute all afterGenerate hooks
|
|
123
|
+
*/
|
|
124
|
+
private async executeAfterHooks<T>(
|
|
125
|
+
context: MiddlewareResultContext<T>,
|
|
126
|
+
): Promise<void> {
|
|
127
|
+
for (const mw of this.middleware) {
|
|
128
|
+
if (mw.afterGenerate) {
|
|
129
|
+
await mw.afterGenerate(context);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export const generationWrapper = new GenerationWrapperService();
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Create new wrapper instance
|
|
139
|
+
*/
|
|
140
|
+
export function createGenerationWrapper(
|
|
141
|
+
config?: WrapperConfig,
|
|
142
|
+
): GenerationWrapperService {
|
|
143
|
+
const wrapper = new GenerationWrapperService();
|
|
144
|
+
if (config) {
|
|
145
|
+
wrapper.configure(config);
|
|
146
|
+
}
|
|
147
|
+
return wrapper;
|
|
148
|
+
}
|
|
@@ -7,3 +7,8 @@ export { generationOrchestrator } from "./generation-orchestrator.service";
|
|
|
7
7
|
export type { OrchestratorConfig } from "./generation-orchestrator.service";
|
|
8
8
|
export { pollJob, createJobPoller } from "./job-poller.service";
|
|
9
9
|
export type { PollJobOptions, PollJobResult } from "./job-poller.service";
|
|
10
|
+
export {
|
|
11
|
+
generationWrapper,
|
|
12
|
+
createGenerationWrapper,
|
|
13
|
+
} from "./generation-wrapper.service";
|
|
14
|
+
export type { WrapperConfig } from "./generation-wrapper.service";
|