@umituz/react-native-ai-fal-provider 1.0.96 → 1.0.98

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-fal-provider",
3
- "version": "1.0.96",
3
+ "version": "1.0.98",
4
4
  "description": "FAL AI provider for React Native - implements IAIProvider interface for unified AI generation",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Cost Tracker Queries
3
+ * Query functions for cost history analysis
4
+ */
5
+
6
+ import type { GenerationCost, CostSummary } from "../../domain/entities/cost-tracking.types";
7
+
8
+ /**
9
+ * Calculate cost summary from history
10
+ */
11
+ export function calculateCostSummary(
12
+ costHistory: readonly GenerationCost[],
13
+ currency: string
14
+ ): CostSummary {
15
+ const completedCosts = costHistory.filter((c) => c.actualCost > 0);
16
+ const totalCost = completedCosts.reduce((sum, c) => sum + c.actualCost, 0);
17
+ const totalGenerations = completedCosts.length;
18
+ const averageCost = totalGenerations > 0 ? totalCost / totalGenerations : 0;
19
+
20
+ const modelBreakdown: Record<string, number> = {};
21
+ const operationBreakdown: Record<string, number> = {};
22
+
23
+ for (const cost of completedCosts) {
24
+ modelBreakdown[cost.model] = (modelBreakdown[cost.model] ?? 0) + cost.actualCost;
25
+ operationBreakdown[cost.operation] = (operationBreakdown[cost.operation] ?? 0) + cost.actualCost;
26
+ }
27
+
28
+ return {
29
+ totalCost,
30
+ totalGenerations,
31
+ averageCost,
32
+ currency,
33
+ modelBreakdown,
34
+ operationBreakdown,
35
+ };
36
+ }
37
+
38
+ /**
39
+ * Filter costs by model
40
+ */
41
+ export function filterCostsByModel(
42
+ costHistory: readonly GenerationCost[],
43
+ modelId: string
44
+ ): GenerationCost[] {
45
+ return costHistory.filter((c) => c.model === modelId);
46
+ }
47
+
48
+ /**
49
+ * Filter costs by operation type
50
+ */
51
+ export function filterCostsByOperation(
52
+ costHistory: readonly GenerationCost[],
53
+ operation: string
54
+ ): GenerationCost[] {
55
+ return costHistory.filter((c) => c.operation === operation);
56
+ }
57
+
58
+ /**
59
+ * Filter costs by time range
60
+ */
61
+ export function filterCostsByTimeRange(
62
+ costHistory: readonly GenerationCost[],
63
+ startTime: number,
64
+ endTime: number
65
+ ): GenerationCost[] {
66
+ return costHistory.filter((c) => c.timestamp >= startTime && c.timestamp <= endTime);
67
+ }
@@ -10,6 +10,12 @@ import type {
10
10
  ModelCostInfo,
11
11
  } from "../../domain/entities/cost-tracking.types";
12
12
  import { findModelById } from "../../domain/constants/default-models.constants";
13
+ import {
14
+ calculateCostSummary,
15
+ filterCostsByModel,
16
+ filterCostsByOperation,
17
+ filterCostsByTimeRange,
18
+ } from "./cost-tracker-queries";
13
19
 
14
20
  declare const __DEV__: boolean | undefined;
15
21
 
@@ -27,9 +33,6 @@ export class CostTracker {
27
33
  };
28
34
  }
29
35
 
30
- /**
31
- * Get cost information for a model
32
- */
33
36
  getModelCostInfo(modelId: string): ModelCostInfo {
34
37
  const model = findModelById(modelId);
35
38
 
@@ -52,17 +55,11 @@ export class CostTracker {
52
55
  };
53
56
  }
54
57
 
55
- /**
56
- * Calculate estimated cost for a generation
57
- */
58
58
  calculateEstimatedCost(modelId: string): number {
59
59
  const costInfo = this.getModelCostInfo(modelId);
60
60
  return costInfo.costPerRequest;
61
61
  }
62
62
 
63
- /**
64
- * Start tracking a generation operation
65
- */
66
63
  startOperation(modelId: string, operation: string): string {
67
64
  const operationId = `${Date.now()}-${operation}`;
68
65
  const estimatedCost = this.calculateEstimatedCost(modelId);
@@ -86,9 +83,6 @@ export class CostTracker {
86
83
  return operationId;
87
84
  }
88
85
 
89
- /**
90
- * Complete tracking for a generation operation
91
- */
92
86
  completeOperation(
93
87
  operationId: string,
94
88
  modelId: string,
@@ -120,70 +114,28 @@ export class CostTracker {
120
114
  return cost;
121
115
  }
122
116
 
123
- /**
124
- * Get cost summary for all tracked operations
125
- */
126
117
  getCostSummary(): CostSummary {
127
- const completedCosts = this.costHistory.filter((c) => c.actualCost > 0);
128
- const totalCost = completedCosts.reduce((sum, c) => sum + c.actualCost, 0);
129
- const totalGenerations = completedCosts.length;
130
- const averageCost = totalGenerations > 0 ? totalCost / totalGenerations : 0;
131
-
132
- const modelBreakdown: Record<string, number> = {};
133
- const operationBreakdown: Record<string, number> = {};
134
-
135
- for (const cost of completedCosts) {
136
- modelBreakdown[cost.model] =
137
- (modelBreakdown[cost.model] ?? 0) + cost.actualCost;
138
- operationBreakdown[cost.operation] =
139
- (operationBreakdown[cost.operation] ?? 0) + cost.actualCost;
140
- }
141
-
142
- return {
143
- totalCost,
144
- totalGenerations,
145
- averageCost,
146
- currency: this.config.currency,
147
- modelBreakdown,
148
- operationBreakdown,
149
- };
118
+ return calculateCostSummary(this.costHistory, this.config.currency);
150
119
  }
151
120
 
152
- /**
153
- * Get cost history
154
- */
155
121
  getCostHistory(): readonly GenerationCost[] {
156
122
  return this.costHistory;
157
123
  }
158
124
 
159
- /**
160
- * Clear cost history
161
- */
162
125
  clearHistory(): void {
163
126
  this.costHistory = [];
164
127
  this.currentOperationCosts.clear();
165
128
  }
166
129
 
167
- /**
168
- * Get costs for a specific model
169
- */
170
130
  getCostsByModel(modelId: string): GenerationCost[] {
171
- return this.costHistory.filter((c) => c.model === modelId);
131
+ return filterCostsByModel(this.costHistory, modelId);
172
132
  }
173
133
 
174
- /**
175
- * Get costs for a specific operation type
176
- */
177
134
  getCostsByOperation(operation: string): GenerationCost[] {
178
- return this.costHistory.filter((c) => c.operation === operation);
135
+ return filterCostsByOperation(this.costHistory, operation);
179
136
  }
180
137
 
181
- /**
182
- * Get costs for a specific time range
183
- */
184
138
  getCostsByTimeRange(startTime: number, endTime: number): GenerationCost[] {
185
- return this.costHistory.filter(
186
- (c) => c.timestamp >= startTime && c.timestamp <= endTime,
187
- );
139
+ return filterCostsByTimeRange(this.costHistory, startTime, endTime);
188
140
  }
189
141
  }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * General Helper Utilities
3
+ * Common utility functions
4
+ */
5
+
6
+ /**
7
+ * Format credit cost for display
8
+ */
9
+ export function formatCreditCost(cost: number): string {
10
+ if (cost % 1 === 0) {
11
+ return cost.toString();
12
+ }
13
+ return cost.toFixed(2);
14
+ }
15
+
16
+ /**
17
+ * Build error message with context
18
+ */
19
+ export function buildErrorMessage(
20
+ type: string,
21
+ context: Record<string, unknown>
22
+ ): string {
23
+ const contextStr = Object.entries(context)
24
+ .map(([key, value]) => `${key}=${JSON.stringify(value)}`)
25
+ .join(", ");
26
+ return `${type}${contextStr ? ` (${contextStr})` : ""}`;
27
+ }
28
+
29
+ /**
30
+ * Check if value is defined (not null or undefined)
31
+ */
32
+ export function isDefined<T>(value: T | null | undefined): value is T {
33
+ return value !== null && value !== undefined;
34
+ }
35
+
36
+ /**
37
+ * Filter out null and undefined values from object
38
+ */
39
+ export function removeNullish<T extends Record<string, unknown>>(
40
+ obj: T
41
+ ): Partial<T> {
42
+ return Object.fromEntries(
43
+ Object.entries(obj).filter(([_, value]) => isDefined(value))
44
+ ) as Partial<T>;
45
+ }
@@ -1,151 +1,29 @@
1
1
  /**
2
- * Helper Utilities
3
- * Common helper functions for FAL operations
4
- */
5
-
6
- /**
7
- * Format image as data URI if not already formatted
8
- */
9
- export function formatImageDataUri(base64: string): string {
10
- if (base64.startsWith("data:")) {
11
- return base64;
12
- }
13
- return `data:image/jpeg;base64,${base64}`;
14
- }
15
-
16
- /**
17
- * Extract base64 from data URI
18
- */
19
- export function extractBase64(dataUri: string): string {
20
- if (!dataUri.startsWith("data:")) {
21
- return dataUri;
22
- }
23
-
24
- const parts = dataUri.split(",");
25
- return parts.length > 1 ? parts[1] : dataUri;
26
- }
27
-
28
- /**
29
- * Get file extension from data URI
30
- */
31
- export function getDataUriExtension(dataUri: string): string | null {
32
- const match = dataUri.match(/^data:image\/(\w+);base64/);
33
- return match ? match[1] : null;
34
- }
35
-
36
- /**
37
- * Check if data URI is an image
38
- */
39
- export function isImageDataUri(value: string): boolean {
40
- return value.startsWith("data:image/");
41
- }
42
-
43
- /**
44
- * Calculate timeout with jitter to avoid thundering herd
45
- */
46
- export function calculateTimeoutWithJitter(
47
- baseTimeout: number,
48
- jitterPercent: number = 0.1
49
- ): number {
50
- const jitter = baseTimeout * jitterPercent;
51
- const randomJitter = Math.random() * jitter - jitter / 2;
52
- return Math.max(1000, baseTimeout + randomJitter);
53
- }
54
-
55
- /**
56
- * Format credit cost for display
57
- */
58
- export function formatCreditCost(cost: number): string {
59
- if (cost % 1 === 0) {
60
- return cost.toString();
61
- }
62
- return cost.toFixed(2);
63
- }
64
-
65
- /**
66
- * Truncate prompt to maximum length
67
- */
68
- export function truncatePrompt(prompt: string, maxLength: number = 5000): string {
69
- if (prompt.length <= maxLength) {
70
- return prompt;
71
- }
72
- return prompt.slice(0, maxLength - 3) + "...";
73
- }
74
-
75
- /**
76
- * Sanitize prompt by removing excessive whitespace
77
- */
78
- export function sanitizePrompt(prompt: string): string {
79
- return prompt.trim().replace(/\s+/g, " ");
80
- }
81
-
82
- /**
83
- * Build error message with context
84
- */
85
- export function buildErrorMessage(
86
- type: string,
87
- context: Record<string, unknown>
88
- ): string {
89
- const contextStr = Object.entries(context)
90
- .map(([key, value]) => `${key}=${JSON.stringify(value)}`)
91
- .join(", ");
92
- return `${type}${contextStr ? ` (${contextStr})` : ""}`;
93
- }
94
-
95
- /**
96
- * Check if value is defined (not null or undefined)
97
- */
98
- export function isDefined<T>(value: T | null | undefined): value is T {
99
- return value !== null && value !== undefined;
100
- }
101
-
102
- /**
103
- * Filter out null and undefined values from object
104
- */
105
- export function removeNullish<T extends Record<string, unknown>>(
106
- obj: T
107
- ): Partial<T> {
108
- return Object.fromEntries(
109
- Object.entries(obj).filter(([_, value]) => isDefined(value))
110
- ) as Partial<T>;
111
- }
112
-
113
- /**
114
- * Debounce function (for rate limiting)
115
- */
116
- export function debounce<T extends (...args: never[]) => unknown>(
117
- func: T,
118
- wait: number
119
- ): (...args: Parameters<T>) => void {
120
- let timeout: ReturnType<typeof setTimeout> | null = null;
121
-
122
- return function executedFunction(...args: Parameters<T>) {
123
- const later = () => {
124
- timeout = null;
125
- func(...args);
126
- };
127
-
128
- if (timeout) {
129
- clearTimeout(timeout);
130
- }
131
- timeout = setTimeout(later, wait);
132
- };
133
- }
134
-
135
- /**
136
- * Simple throttle function
137
- */
138
- export function throttle<T extends (...args: never[]) => unknown>(
139
- func: T,
140
- limit: number
141
- ): (...args: Parameters<T>) => void {
142
- let inThrottle = false;
143
-
144
- return function executedFunction(...args: Parameters<T>) {
145
- if (!inThrottle) {
146
- func(...args);
147
- inThrottle = true;
148
- setTimeout(() => (inThrottle = false), limit);
149
- }
150
- };
151
- }
2
+ * Helper Utilities - Re-exports
3
+ * Backward compatibility barrel file
4
+ */
5
+
6
+ export {
7
+ formatImageDataUri,
8
+ extractBase64,
9
+ getDataUriExtension,
10
+ isImageDataUri,
11
+ } from "./image-helpers.util";
12
+
13
+ export {
14
+ truncatePrompt,
15
+ sanitizePrompt,
16
+ } from "./prompt-helpers.util";
17
+
18
+ export {
19
+ calculateTimeoutWithJitter,
20
+ debounce,
21
+ throttle,
22
+ } from "./timing-helpers.util";
23
+
24
+ export {
25
+ formatCreditCost,
26
+ buildErrorMessage,
27
+ isDefined,
28
+ removeNullish,
29
+ } from "./general-helpers.util";
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Image Helper Utilities
3
+ * Functions for image data URI manipulation
4
+ */
5
+
6
+ /**
7
+ * Format image as data URI if not already formatted
8
+ */
9
+ export function formatImageDataUri(base64: string): string {
10
+ if (base64.startsWith("data:")) {
11
+ return base64;
12
+ }
13
+ return `data:image/jpeg;base64,${base64}`;
14
+ }
15
+
16
+ /**
17
+ * Extract base64 from data URI
18
+ */
19
+ export function extractBase64(dataUri: string): string {
20
+ if (!dataUri.startsWith("data:")) {
21
+ return dataUri;
22
+ }
23
+ const parts = dataUri.split(",");
24
+ return parts.length > 1 ? parts[1] : dataUri;
25
+ }
26
+
27
+ /**
28
+ * Get file extension from data URI
29
+ */
30
+ export function getDataUriExtension(dataUri: string): string | null {
31
+ const match = dataUri.match(/^data:image\/(\w+);base64/);
32
+ return match ? match[1] : null;
33
+ }
34
+
35
+ /**
36
+ * Check if data URI is an image
37
+ */
38
+ export function isImageDataUri(value: string): boolean {
39
+ return value.startsWith("data:image/");
40
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Prompt Helper Utilities
3
+ * Functions for prompt manipulation and sanitization
4
+ */
5
+
6
+ /**
7
+ * Truncate prompt to maximum length
8
+ */
9
+ export function truncatePrompt(prompt: string, maxLength: number = 5000): string {
10
+ if (prompt.length <= maxLength) {
11
+ return prompt;
12
+ }
13
+ return prompt.slice(0, maxLength - 3) + "...";
14
+ }
15
+
16
+ /**
17
+ * Sanitize prompt by removing excessive whitespace
18
+ */
19
+ export function sanitizePrompt(prompt: string): string {
20
+ return prompt.trim().replace(/\s+/g, " ");
21
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Timing Helper Utilities
3
+ * Functions for timing, debouncing, and throttling
4
+ */
5
+
6
+ /**
7
+ * Calculate timeout with jitter to avoid thundering herd
8
+ */
9
+ export function calculateTimeoutWithJitter(
10
+ baseTimeout: number,
11
+ jitterPercent: number = 0.1
12
+ ): number {
13
+ const jitter = baseTimeout * jitterPercent;
14
+ const randomJitter = Math.random() * jitter - jitter / 2;
15
+ return Math.max(1000, baseTimeout + randomJitter);
16
+ }
17
+
18
+ /**
19
+ * Debounce function (for rate limiting)
20
+ */
21
+ export function debounce<T extends (...args: never[]) => unknown>(
22
+ func: T,
23
+ wait: number
24
+ ): (...args: Parameters<T>) => void {
25
+ let timeout: ReturnType<typeof setTimeout> | null = null;
26
+
27
+ return function executedFunction(...args: Parameters<T>) {
28
+ const later = () => {
29
+ timeout = null;
30
+ func(...args);
31
+ };
32
+
33
+ if (timeout) {
34
+ clearTimeout(timeout);
35
+ }
36
+ timeout = setTimeout(later, wait);
37
+ };
38
+ }
39
+
40
+ /**
41
+ * Simple throttle function
42
+ */
43
+ export function throttle<T extends (...args: never[]) => unknown>(
44
+ func: T,
45
+ limit: number
46
+ ): (...args: Parameters<T>) => void {
47
+ let inThrottle = false;
48
+
49
+ return function executedFunction(...args: Parameters<T>) {
50
+ if (!inThrottle) {
51
+ func(...args);
52
+ inThrottle = true;
53
+ setTimeout(() => (inThrottle = false), limit);
54
+ }
55
+ };
56
+ }