@umituz/web-ai-groq-provider 1.1.13 → 2.0.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.
Files changed (55) hide show
  1. package/README.md +154 -72
  2. package/dist/domains/chat/index.cjs +539 -0
  3. package/dist/domains/chat/index.cjs.map +1 -0
  4. package/dist/domains/chat/index.d.cts +322 -0
  5. package/dist/domains/chat/index.d.ts +322 -0
  6. package/dist/domains/chat/index.js +531 -0
  7. package/dist/domains/chat/index.js.map +1 -0
  8. package/dist/domains/groq/index.cjs +1499 -0
  9. package/dist/domains/groq/index.cjs.map +1 -0
  10. package/dist/domains/groq/index.d.cts +561 -0
  11. package/dist/domains/groq/index.d.ts +561 -0
  12. package/dist/domains/groq/index.js +1453 -0
  13. package/dist/domains/groq/index.js.map +1 -0
  14. package/dist/index.cjs +1993 -0
  15. package/dist/index.cjs.map +1 -0
  16. package/dist/index.d.cts +53 -0
  17. package/dist/index.d.ts +53 -0
  18. package/dist/index.js +1937 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/text-generation.service-BP4Q_SH0.d.cts +252 -0
  21. package/dist/text-generation.service-BP4Q_SH0.d.ts +252 -0
  22. package/package.json +25 -11
  23. package/src/domains/chat/entities/chat.entities.ts +0 -113
  24. package/src/domains/chat/entities/index.ts +0 -14
  25. package/src/domains/chat/hooks/index.ts +0 -5
  26. package/src/domains/chat/hooks/use-chat.hook.ts +0 -259
  27. package/src/domains/chat/index.ts +0 -32
  28. package/src/domains/chat/interfaces/chat.interface.ts +0 -80
  29. package/src/domains/chat/interfaces/index.ts +0 -10
  30. package/src/domains/chat/services/chat.service.ts +0 -195
  31. package/src/domains/chat/services/index.ts +0 -5
  32. package/src/domains/chat/utils/message-formatter.ts +0 -49
  33. package/src/domains/groq/constants/error.constants.ts +0 -46
  34. package/src/domains/groq/constants/groq.constants.ts +0 -68
  35. package/src/domains/groq/constants/index.ts +0 -20
  36. package/src/domains/groq/entities/groq.entities.ts +0 -196
  37. package/src/domains/groq/entities/index.ts +0 -20
  38. package/src/domains/groq/hooks/index.ts +0 -7
  39. package/src/domains/groq/hooks/use-groq.hook.ts +0 -232
  40. package/src/domains/groq/index.ts +0 -72
  41. package/src/domains/groq/interfaces/groq.interface.ts +0 -77
  42. package/src/domains/groq/interfaces/index.ts +0 -22
  43. package/src/domains/groq/services/http-client.service.ts +0 -265
  44. package/src/domains/groq/services/index.ts +0 -9
  45. package/src/domains/groq/services/text-generation.service.ts +0 -238
  46. package/src/domains/groq/utils/cache-manager.util.ts +0 -215
  47. package/src/domains/groq/utils/debounce.util.ts +0 -268
  48. package/src/domains/groq/utils/error.util.ts +0 -57
  49. package/src/domains/groq/utils/groq-error.util.ts +0 -18
  50. package/src/domains/groq/utils/index.ts +0 -37
  51. package/src/domains/groq/utils/message.util.ts +0 -57
  52. package/src/domains/groq/utils/request-deduplicator.util.ts +0 -123
  53. package/src/domains/groq/utils/request-queue.util.ts +0 -178
  54. package/src/domains/groq/utils/retry.util.ts +0 -207
  55. package/src/index.ts +0 -15
@@ -1,123 +0,0 @@
1
- /**
2
- * Request Deduplicator Utility
3
- * @description Prevents duplicate API calls for the same request
4
- */
5
-
6
- interface PendingRequest<T> {
7
- promise: Promise<T>;
8
- timestamp: number;
9
- }
10
-
11
- interface DeduplicatorOptions {
12
- /** Time-to-live for pending requests in milliseconds */
13
- ttl?: number;
14
- /** Custom key generator for requests */
15
- keyGenerator?: (request: unknown) => string;
16
- }
17
-
18
- class RequestDeduplicator {
19
- private pendingRequests = new Map<string, PendingRequest<unknown>>();
20
- private readonly defaultTTL: number;
21
-
22
- constructor(options: DeduplicatorOptions = {}) {
23
- this.defaultTTL = options.ttl || 30000; // 30 seconds default
24
- }
25
-
26
- /**
27
- * Execute a request with deduplication
28
- * If a similar request is pending, return its promise instead of creating a new one
29
- */
30
- async execute<T>(
31
- key: string,
32
- requestFn: () => Promise<T>
33
- ): Promise<T> {
34
- // Clean up expired requests
35
- this.cleanup();
36
-
37
- // Check if there's a pending request with the same key
38
- const existing = this.pendingRequests.get(key);
39
- if (existing) {
40
- return existing.promise as Promise<T>;
41
- }
42
-
43
- // Create new request
44
- const promise = requestFn();
45
-
46
- // Store pending request
47
- this.pendingRequests.set(key, {
48
- promise,
49
- timestamp: Date.now(),
50
- });
51
-
52
- // Clean up after completion (success or failure)
53
- promise.finally(() => {
54
- this.pendingRequests.delete(key);
55
- });
56
-
57
- return promise;
58
- }
59
-
60
- /**
61
- * Generate a default key from request parameters
62
- */
63
- generateKey(params: Record<string, unknown>): string {
64
- return JSON.stringify(params, Object.keys(params).sort());
65
- }
66
-
67
- /**
68
- * Check if a request is currently pending
69
- */
70
- isPending(key: string): boolean {
71
- this.cleanup();
72
- return this.pendingRequests.has(key);
73
- }
74
-
75
- /**
76
- * Cancel a pending request by key
77
- */
78
- cancel(key: string): boolean {
79
- const request = this.pendingRequests.get(key);
80
- if (request) {
81
- this.pendingRequests.delete(key);
82
- return true;
83
- }
84
- return false;
85
- }
86
-
87
- /**
88
- * Cancel all pending requests
89
- */
90
- cancelAll(): void {
91
- this.pendingRequests.clear();
92
- }
93
-
94
- /**
95
- * Get count of pending requests
96
- */
97
- getPendingCount(): number {
98
- this.cleanup();
99
- return this.pendingRequests.size;
100
- }
101
-
102
- /**
103
- * Clean up expired pending requests
104
- */
105
- private cleanup(): void {
106
- const now = Date.now();
107
- for (const [key, request] of this.pendingRequests.entries()) {
108
- if (now - request.timestamp > this.defaultTTL) {
109
- this.pendingRequests.delete(key);
110
- }
111
- }
112
- }
113
-
114
- /**
115
- * Clear all pending requests and reset state
116
- */
117
- reset(): void {
118
- this.pendingRequests.clear();
119
- }
120
- }
121
-
122
- export const requestDeduplicator = new RequestDeduplicator();
123
- export { RequestDeduplicator };
@@ -1,178 +0,0 @@
1
- /**
2
- * Request Queue Manager Utility
3
- * @description Manages concurrent requests with priority and limits
4
- */
5
-
6
- interface QueuedRequest<T> {
7
- id: string;
8
- priority: number;
9
- requestFn: () => Promise<T>;
10
- resolve: (value: T) => void;
11
- reject: (reason?: unknown) => void;
12
- timestamp: number;
13
- }
14
-
15
- interface QueueOptions {
16
- /** Maximum concurrent requests */
17
- maxConcurrent?: number;
18
- /** Default priority for requests (higher = more important) */
19
- defaultPriority?: number;
20
- /** Request timeout in milliseconds */
21
- requestTimeout?: number;
22
- }
23
-
24
- class RequestQueue {
25
- private queue: QueuedRequest<unknown>[] = [];
26
- private activeRequests = new Set<string>();
27
- private readonly maxConcurrent: number;
28
- private readonly defaultPriority: number;
29
- private readonly requestTimeout: number;
30
- private requestIdCounter = 0;
31
-
32
- constructor(options: QueueOptions = {}) {
33
- this.maxConcurrent = options.maxConcurrent || 3;
34
- this.defaultPriority = options.defaultPriority || 0;
35
- this.requestTimeout = options.requestTimeout || 30000; // 30 seconds
36
- }
37
-
38
- /**
39
- * Add a request to the queue
40
- */
41
- async add<T>(
42
- requestFn: () => Promise<T>,
43
- priority?: number
44
- ): Promise<T> {
45
- return new Promise((resolve, reject) => {
46
- const id = `req-${++this.requestIdCounter}`;
47
-
48
- const queuedRequest: QueuedRequest<T> = {
49
- id,
50
- priority: priority ?? this.defaultPriority,
51
- requestFn,
52
- resolve: resolve as (value: unknown) => void,
53
- reject,
54
- timestamp: Date.now(),
55
- };
56
-
57
- this.queue.push(queuedRequest as QueuedRequest<unknown>);
58
- this.sortQueue();
59
- this.process();
60
- });
61
- }
62
-
63
- /**
64
- * Sort queue by priority (higher priority first) and timestamp
65
- */
66
- private sortQueue(): void {
67
- this.queue.sort((a, b) => {
68
- if (a.priority !== b.priority) {
69
- return b.priority - a.priority; // Higher priority first
70
- }
71
- return a.timestamp - b.timestamp; // Earlier requests first
72
- });
73
- }
74
-
75
- /**
76
- * Process queued requests
77
- */
78
- private process(): void {
79
- // Process as many requests as we can concurrently
80
- while (
81
- this.queue.length > 0 &&
82
- this.activeRequests.size < this.maxConcurrent
83
- ) {
84
- const request = this.queue.shift();
85
- if (!request) break;
86
-
87
- this.executeRequest(request);
88
- }
89
- }
90
-
91
- /**
92
- * Execute a single request
93
- */
94
- private async executeRequest<T>(request: QueuedRequest<T>): Promise<void> {
95
- this.activeRequests.add(request.id);
96
-
97
- // Add timeout
98
- const timeoutId = setTimeout(() => {
99
- this.activeRequests.delete(request.id);
100
- request.reject(new Error(`Request ${request.id} timed out`));
101
- this.process();
102
- }, this.requestTimeout);
103
-
104
- try {
105
- const result = await request.requestFn();
106
- clearTimeout(timeoutId);
107
- request.resolve(result);
108
- } catch (error) {
109
- clearTimeout(timeoutId);
110
- request.reject(error);
111
- } finally {
112
- this.activeRequests.delete(request.id);
113
- // Process next request
114
- this.process();
115
- }
116
- }
117
-
118
- /**
119
- * Cancel a specific request by ID
120
- */
121
- cancel(requestId: string): boolean {
122
- // Check if it's in the queue
123
- const queueIndex = this.queue.findIndex(r => r.id === requestId);
124
- if (queueIndex !== -1) {
125
- const request = this.queue[queueIndex];
126
- this.queue.splice(queueIndex, 1);
127
- request.reject(new Error(`Request ${requestId} was cancelled`));
128
- return true;
129
- }
130
-
131
- // Check if it's active (we can't cancel active requests, but we can track)
132
- return this.activeRequests.has(requestId);
133
- }
134
-
135
- /**
136
- * Cancel all queued requests
137
- */
138
- cancelAll(): void {
139
- // Reject all queued requests
140
- for (const request of this.queue) {
141
- request.reject(new Error('Request was cancelled'));
142
- }
143
- this.queue = [];
144
- }
145
-
146
- /**
147
- * Get queue statistics
148
- */
149
- getStats(): {
150
- queued: number;
151
- active: number;
152
- maxConcurrent: number;
153
- } {
154
- return {
155
- queued: this.queue.length,
156
- active: this.activeRequests.size,
157
- maxConcurrent: this.maxConcurrent,
158
- };
159
- }
160
-
161
- /**
162
- * Check if queue is at capacity
163
- */
164
- isAtCapacity(): boolean {
165
- return this.activeRequests.size >= this.maxConcurrent;
166
- }
167
-
168
- /**
169
- * Clear queue and reset state
170
- */
171
- reset(): void {
172
- this.cancelAll();
173
- this.activeRequests.clear();
174
- }
175
- }
176
-
177
- export const requestQueue = new RequestQueue();
178
- export { RequestQueue };
@@ -1,207 +0,0 @@
1
- /**
2
- * Retry Logic Utility
3
- * @description Exponential backoff retry mechanism for failed requests
4
- */
5
-
6
- import { GroqError } from "./groq-error.util";
7
- import { isRetryableError } from "../constants/error.constants";
8
-
9
- interface RetryOptions {
10
- /** Maximum number of retry attempts */
11
- maxAttempts?: number;
12
- /** Initial delay in milliseconds */
13
- initialDelay?: number;
14
- /** Maximum delay between retries */
15
- maxDelay?: number;
16
- /** Backoff multiplier */
17
- backoffMultiplier?: number;
18
- /** Jitter factor to prevent thundering herd (0-1) */
19
- jitterFactor?: number;
20
- /** Custom retry condition */
21
- shouldRetry?: (error: Error) => boolean;
22
- }
23
-
24
- interface RetryResult<T> {
25
- success: boolean;
26
- data?: T;
27
- error?: Error;
28
- attempts: number;
29
- totalDelay: number;
30
- }
31
-
32
- class RetryManager {
33
- private readonly defaultMaxAttempts: number;
34
- private readonly defaultInitialDelay: number;
35
- private readonly defaultMaxDelay: number;
36
- private readonly defaultBackoffMultiplier: number;
37
- private readonly defaultJitterFactor: number;
38
-
39
- constructor() {
40
- this.defaultMaxAttempts = 3;
41
- this.defaultInitialDelay = 1000; // 1 second
42
- this.defaultMaxDelay = 10000; // 10 seconds
43
- this.defaultBackoffMultiplier = 2;
44
- this.defaultJitterFactor = 0.1; // 10% jitter
45
- }
46
-
47
- /**
48
- * Execute a function with retry logic
49
- */
50
- async execute<T>(
51
- fn: () => Promise<T>,
52
- options: RetryOptions = {}
53
- ): Promise<T> {
54
- const maxAttempts = options.maxAttempts ?? this.defaultMaxAttempts;
55
- let lastError: Error | null = null;
56
- let _totalDelay = 0;
57
-
58
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
59
- try {
60
- const result = await fn();
61
- return result;
62
- } catch (error) {
63
- lastError = error instanceof Error ? error : new Error(String(error));
64
-
65
- // Check if we should retry
66
- if (attempt >= maxAttempts || !this.shouldRetry(lastError, options)) {
67
- throw lastError;
68
- }
69
-
70
- // Calculate delay for next attempt
71
- const delay = this.calculateDelay(attempt, options);
72
- _totalDelay += delay;
73
-
74
- // Wait before retrying
75
- await this.delay(delay);
76
- }
77
- }
78
-
79
- throw lastError;
80
- }
81
-
82
- /**
83
- * Execute with detailed retry result
84
- */
85
- async executeWithDetails<T>(
86
- fn: () => Promise<T>,
87
- options: RetryOptions = {}
88
- ): Promise<RetryResult<T>> {
89
- const maxAttempts = options.maxAttempts ?? this.defaultMaxAttempts;
90
- let lastError: Error | null = null;
91
- let totalDelay = 0;
92
-
93
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
94
- try {
95
- const data = await fn();
96
- return {
97
- success: true,
98
- data,
99
- attempts: attempt,
100
- totalDelay,
101
- };
102
- } catch (error) {
103
- lastError = error instanceof Error ? error : new Error(String(error));
104
-
105
- if (attempt >= maxAttempts || !this.shouldRetry(lastError, options)) {
106
- return {
107
- success: false,
108
- error: lastError,
109
- attempts: attempt,
110
- totalDelay,
111
- };
112
- }
113
-
114
- const delay = this.calculateDelay(attempt, options);
115
- totalDelay += delay;
116
- await this.delay(delay);
117
- }
118
- }
119
-
120
- return {
121
- success: false,
122
- error: lastError || new Error("Unknown error"),
123
- attempts: maxAttempts,
124
- totalDelay,
125
- };
126
- }
127
-
128
- /**
129
- * Calculate delay with exponential backoff and jitter
130
- */
131
- private calculateDelay(attempt: number, options: RetryOptions): number {
132
- const initialDelay = options.initialDelay ?? this.defaultInitialDelay;
133
- const maxDelay = options.maxDelay ?? this.defaultMaxDelay;
134
- const backoffMultiplier = options.backoffMultiplier ?? this.defaultBackoffMultiplier;
135
- const jitterFactor = options.jitterFactor ?? this.defaultJitterFactor;
136
-
137
- // Exponential backoff
138
- let delay = initialDelay * Math.pow(backoffMultiplier, attempt - 1);
139
-
140
- // Cap at max delay
141
- delay = Math.min(delay, maxDelay);
142
-
143
- // Add jitter to prevent thundering herd
144
- const jitter = delay * jitterFactor * (Math.random() * 2 - 1);
145
- delay = delay + jitter;
146
-
147
- // Ensure delay is not negative
148
- return Math.max(0, delay);
149
- }
150
-
151
- /**
152
- * Check if error should trigger a retry
153
- */
154
- private shouldRetry(error: Error, options: RetryOptions): boolean {
155
- // Use custom retry condition if provided
156
- if (options.shouldRetry) {
157
- return options.shouldRetry(error);
158
- }
159
-
160
- // Check if it's a GroqError
161
- if (error instanceof GroqError) {
162
- return isRetryableError(error.type);
163
- }
164
-
165
- // Default: retry on network errors
166
- const errorMessage = error.message.toLowerCase();
167
- return (
168
- errorMessage.includes("network") ||
169
- errorMessage.includes("timeout") ||
170
- errorMessage.includes("econnrefused") ||
171
- errorMessage.includes("enotfound") ||
172
- errorMessage.includes("etimedout")
173
- );
174
- }
175
-
176
- /**
177
- * Delay helper
178
- */
179
- private delay(ms: number): Promise<void> {
180
- return new Promise(resolve => setTimeout(resolve, ms));
181
- }
182
-
183
- /**
184
- * Create a retryable function wrapper
185
- */
186
- wrap<T extends (...args: unknown[]) => Promise<unknown>>(
187
- fn: T,
188
- options?: RetryOptions
189
- ): T {
190
- return (async (...args: unknown[]) => {
191
- return this.execute(() => fn(...args), options);
192
- }) as T;
193
- }
194
- }
195
-
196
- export const retryManager = new RetryManager();
197
- export { RetryManager };
198
-
199
- /**
200
- * Convenience function to execute with retry
201
- */
202
- export async function withRetry<T>(
203
- fn: () => Promise<T>,
204
- options?: RetryOptions
205
- ): Promise<T> {
206
- return retryManager.execute(fn, options);
207
- }
package/src/index.ts DELETED
@@ -1,15 +0,0 @@
1
- /**
2
- * @umituz/web-ai-groq-provider
3
- * Groq AI text generation and chat provider for React web applications
4
- *
5
- * @author umituz
6
- * @license MIT
7
- *
8
- * For better tree-shaking, use subpath imports:
9
- * - @umituz/web-ai-groq-provider/groq - Groq API client
10
- * - @umituz/web-ai-groq-provider/chat - Chat functionality
11
- */
12
-
13
- // Re-export all domains
14
- export * from "./domains/groq/index";
15
- export * from "./domains/chat/index";