@fin.cx/opendata 3.1.0 → 3.2.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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@fin.cx/opendata',
6
- version: '3.1.0',
6
+ version: '3.2.0',
7
7
  description: 'A comprehensive TypeScript library for accessing business data and real-time financial information. Features include German company data management with MongoDB integration, JSONL bulk processing, automated Handelsregister interactions, and real-time stock market data from multiple providers.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHVTQUF1UztDQUNyVCxDQUFBIn0=
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Base provider entry for tracking provider state
3
+ */
4
+ export interface IBaseProviderEntry<TProvider> {
5
+ provider: TProvider;
6
+ config: IBaseProviderConfig;
7
+ lastError?: Error;
8
+ lastErrorTime?: Date;
9
+ successCount: number;
10
+ errorCount: number;
11
+ }
12
+ /**
13
+ * Base provider configuration
14
+ */
15
+ export interface IBaseProviderConfig {
16
+ enabled: boolean;
17
+ priority: number;
18
+ timeout?: number;
19
+ retryAttempts?: number;
20
+ retryDelay?: number;
21
+ cacheTTL?: number;
22
+ }
23
+ /**
24
+ * Base provider interface
25
+ */
26
+ export interface IBaseProvider {
27
+ name: string;
28
+ priority: number;
29
+ isAvailable(): Promise<boolean>;
30
+ readonly requiresAuth: boolean;
31
+ readonly rateLimit?: {
32
+ requestsPerMinute: number;
33
+ requestsPerDay?: number;
34
+ };
35
+ }
36
+ /**
37
+ * Cache entry for any data type
38
+ */
39
+ export interface IBaseCacheEntry<TData> {
40
+ data: TData;
41
+ timestamp: Date;
42
+ ttl: number;
43
+ }
44
+ /**
45
+ * Base service for managing data providers with caching
46
+ * Shared logic extracted from StockPriceService and FundamentalsService
47
+ */
48
+ export declare abstract class BaseProviderService<TProvider extends IBaseProvider, TData> {
49
+ protected providers: Map<string, IBaseProviderEntry<TProvider>>;
50
+ protected cache: Map<string, IBaseCacheEntry<TData>>;
51
+ protected logger: Console;
52
+ protected cacheConfig: {
53
+ ttl: number;
54
+ maxEntries: number;
55
+ };
56
+ constructor(cacheConfig?: {
57
+ ttl?: number;
58
+ maxEntries?: number;
59
+ });
60
+ /**
61
+ * Register a provider
62
+ */
63
+ register(provider: TProvider, config?: Partial<IBaseProviderConfig>): void;
64
+ /**
65
+ * Unregister a provider
66
+ */
67
+ unregister(providerName: string): void;
68
+ /**
69
+ * Get a specific provider by name
70
+ */
71
+ getProvider(name: string): TProvider | undefined;
72
+ /**
73
+ * Get all registered providers
74
+ */
75
+ getAllProviders(): TProvider[];
76
+ /**
77
+ * Get enabled providers sorted by priority
78
+ */
79
+ getEnabledProviders(): TProvider[];
80
+ /**
81
+ * Check health of all providers
82
+ */
83
+ checkProvidersHealth(): Promise<Map<string, boolean>>;
84
+ /**
85
+ * Get provider statistics
86
+ */
87
+ getProviderStats(): Map<string, {
88
+ successCount: number;
89
+ errorCount: number;
90
+ lastError?: string;
91
+ lastErrorTime?: Date;
92
+ }>;
93
+ /**
94
+ * Clear all cached data
95
+ */
96
+ clearCache(): void;
97
+ /**
98
+ * Set cache TTL
99
+ */
100
+ setCacheTTL(ttl: number): void;
101
+ /**
102
+ * Get cache statistics
103
+ */
104
+ getCacheStats(): {
105
+ size: number;
106
+ maxEntries: number;
107
+ ttl: number;
108
+ };
109
+ /**
110
+ * Fetch with retry logic
111
+ */
112
+ protected fetchWithRetry<T>(fetchFn: () => Promise<T>, config: IBaseProviderConfig): Promise<T>;
113
+ /**
114
+ * Get from cache if not expired
115
+ */
116
+ protected getFromCache(key: string): TData | null;
117
+ /**
118
+ * Add to cache with TTL
119
+ */
120
+ protected addToCache(key: string, data: TData, ttl?: number): void;
121
+ /**
122
+ * Track successful fetch for provider
123
+ */
124
+ protected trackSuccess(providerName: string): void;
125
+ /**
126
+ * Track failed fetch for provider
127
+ */
128
+ protected trackError(providerName: string, error: Error): void;
129
+ }
@@ -0,0 +1,204 @@
1
+ import * as plugins from '../plugins.js';
2
+ /**
3
+ * Base service for managing data providers with caching
4
+ * Shared logic extracted from StockPriceService and FundamentalsService
5
+ */
6
+ export class BaseProviderService {
7
+ constructor(cacheConfig) {
8
+ this.providers = new Map();
9
+ this.cache = new Map();
10
+ this.logger = console;
11
+ this.cacheConfig = {
12
+ ttl: 60000, // Default 60 seconds
13
+ maxEntries: 10000
14
+ };
15
+ if (cacheConfig) {
16
+ this.cacheConfig = { ...this.cacheConfig, ...cacheConfig };
17
+ }
18
+ }
19
+ /**
20
+ * Register a provider
21
+ */
22
+ register(provider, config) {
23
+ const defaultConfig = {
24
+ enabled: true,
25
+ priority: provider.priority,
26
+ timeout: 30000,
27
+ retryAttempts: 2,
28
+ retryDelay: 1000,
29
+ cacheTTL: this.cacheConfig.ttl
30
+ };
31
+ const mergedConfig = { ...defaultConfig, ...config };
32
+ this.providers.set(provider.name, {
33
+ provider,
34
+ config: mergedConfig,
35
+ successCount: 0,
36
+ errorCount: 0
37
+ });
38
+ console.log(`Registered provider: ${provider.name}`);
39
+ }
40
+ /**
41
+ * Unregister a provider
42
+ */
43
+ unregister(providerName) {
44
+ this.providers.delete(providerName);
45
+ console.log(`Unregistered provider: ${providerName}`);
46
+ }
47
+ /**
48
+ * Get a specific provider by name
49
+ */
50
+ getProvider(name) {
51
+ return this.providers.get(name)?.provider;
52
+ }
53
+ /**
54
+ * Get all registered providers
55
+ */
56
+ getAllProviders() {
57
+ return Array.from(this.providers.values()).map(entry => entry.provider);
58
+ }
59
+ /**
60
+ * Get enabled providers sorted by priority
61
+ */
62
+ getEnabledProviders() {
63
+ return Array.from(this.providers.values())
64
+ .filter(entry => entry.config.enabled)
65
+ .sort((a, b) => (b.config.priority || 0) - (a.config.priority || 0))
66
+ .map(entry => entry.provider);
67
+ }
68
+ /**
69
+ * Check health of all providers
70
+ */
71
+ async checkProvidersHealth() {
72
+ const health = new Map();
73
+ for (const [name, entry] of this.providers) {
74
+ if (!entry.config.enabled) {
75
+ health.set(name, false);
76
+ continue;
77
+ }
78
+ try {
79
+ const isAvailable = await entry.provider.isAvailable();
80
+ health.set(name, isAvailable);
81
+ }
82
+ catch (error) {
83
+ health.set(name, false);
84
+ console.error(`Health check failed for ${name}:`, error);
85
+ }
86
+ }
87
+ return health;
88
+ }
89
+ /**
90
+ * Get provider statistics
91
+ */
92
+ getProviderStats() {
93
+ const stats = new Map();
94
+ for (const [name, entry] of this.providers) {
95
+ stats.set(name, {
96
+ successCount: entry.successCount,
97
+ errorCount: entry.errorCount,
98
+ lastError: entry.lastError?.message,
99
+ lastErrorTime: entry.lastErrorTime
100
+ });
101
+ }
102
+ return stats;
103
+ }
104
+ /**
105
+ * Clear all cached data
106
+ */
107
+ clearCache() {
108
+ this.cache.clear();
109
+ console.log('Cache cleared');
110
+ }
111
+ /**
112
+ * Set cache TTL
113
+ */
114
+ setCacheTTL(ttl) {
115
+ this.cacheConfig.ttl = ttl;
116
+ console.log(`Cache TTL set to ${ttl}ms`);
117
+ }
118
+ /**
119
+ * Get cache statistics
120
+ */
121
+ getCacheStats() {
122
+ return {
123
+ size: this.cache.size,
124
+ maxEntries: this.cacheConfig.maxEntries,
125
+ ttl: this.cacheConfig.ttl
126
+ };
127
+ }
128
+ /**
129
+ * Fetch with retry logic
130
+ */
131
+ async fetchWithRetry(fetchFn, config) {
132
+ const maxAttempts = config.retryAttempts || 1;
133
+ let lastError;
134
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
135
+ try {
136
+ return await fetchFn();
137
+ }
138
+ catch (error) {
139
+ lastError = error;
140
+ if (attempt < maxAttempts) {
141
+ const delay = (config.retryDelay || 1000) * attempt;
142
+ console.log(`Retry attempt ${attempt} after ${delay}ms`);
143
+ await plugins.smartdelay.delayFor(delay);
144
+ }
145
+ }
146
+ }
147
+ throw lastError || new Error('Unknown error during fetch');
148
+ }
149
+ /**
150
+ * Get from cache if not expired
151
+ */
152
+ getFromCache(key) {
153
+ const entry = this.cache.get(key);
154
+ if (!entry) {
155
+ return null;
156
+ }
157
+ // Check if cache entry has expired
158
+ const age = Date.now() - entry.timestamp.getTime();
159
+ if (entry.ttl !== Infinity && age > entry.ttl) {
160
+ this.cache.delete(key);
161
+ return null;
162
+ }
163
+ return entry.data;
164
+ }
165
+ /**
166
+ * Add to cache with TTL
167
+ */
168
+ addToCache(key, data, ttl) {
169
+ // Enforce max entries limit
170
+ if (this.cache.size >= this.cacheConfig.maxEntries) {
171
+ // Remove oldest entry
172
+ const oldestKey = this.cache.keys().next().value;
173
+ if (oldestKey) {
174
+ this.cache.delete(oldestKey);
175
+ }
176
+ }
177
+ this.cache.set(key, {
178
+ data,
179
+ timestamp: new Date(),
180
+ ttl: ttl || this.cacheConfig.ttl
181
+ });
182
+ }
183
+ /**
184
+ * Track successful fetch for provider
185
+ */
186
+ trackSuccess(providerName) {
187
+ const entry = this.providers.get(providerName);
188
+ if (entry) {
189
+ entry.successCount++;
190
+ }
191
+ }
192
+ /**
193
+ * Track failed fetch for provider
194
+ */
195
+ trackError(providerName, error) {
196
+ const entry = this.providers.get(providerName);
197
+ if (entry) {
198
+ entry.errorCount++;
199
+ entry.lastError = error;
200
+ entry.lastErrorTime = new Date();
201
+ }
202
+ }
203
+ }
204
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5iYXNlcHJvdmlkZXJzZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc3RvY2tzL2NsYXNzZXMuYmFzZXByb3ZpZGVyc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQWlEekM7OztHQUdHO0FBQ0gsTUFBTSxPQUFnQixtQkFBbUI7SUFVdkMsWUFBWSxXQUFtRDtRQVRyRCxjQUFTLEdBQUcsSUFBSSxHQUFHLEVBQXlDLENBQUM7UUFDN0QsVUFBSyxHQUFHLElBQUksR0FBRyxFQUFrQyxDQUFDO1FBQ2xELFdBQU0sR0FBRyxPQUFPLENBQUM7UUFFakIsZ0JBQVcsR0FBRztZQUN0QixHQUFHLEVBQUUsS0FBSyxFQUFFLHFCQUFxQjtZQUNqQyxVQUFVLEVBQUUsS0FBSztTQUNsQixDQUFDO1FBR0EsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsV0FBVyxFQUFFLENBQUM7UUFDN0QsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLFFBQVEsQ0FBQyxRQUFtQixFQUFFLE1BQXFDO1FBQ3hFLE1BQU0sYUFBYSxHQUF3QjtZQUN6QyxPQUFPLEVBQUUsSUFBSTtZQUNiLFFBQVEsRUFBRSxRQUFRLENBQUMsUUFBUTtZQUMzQixPQUFPLEVBQUUsS0FBSztZQUNkLGFBQWEsRUFBRSxDQUFDO1lBQ2hCLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLFFBQVEsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUc7U0FDL0IsQ0FBQztRQUVGLE1BQU0sWUFBWSxHQUFHLEVBQUUsR0FBRyxhQUFhLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQztRQUVyRCxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFO1lBQ2hDLFFBQVE7WUFDUixNQUFNLEVBQUUsWUFBWTtZQUNwQixZQUFZLEVBQUUsQ0FBQztZQUNmLFVBQVUsRUFBRSxDQUFDO1NBQ2QsQ0FBQyxDQUFDO1FBRUgsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVEOztPQUVHO0lBQ0ksVUFBVSxDQUFDLFlBQW9CO1FBQ3BDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sQ0FBQyxHQUFHLENBQUMsMEJBQTBCLFlBQVksRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVEOztPQUVHO0lBQ0ksV0FBVyxDQUFDLElBQVk7UUFDN0IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLENBQUM7SUFDNUMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksZUFBZTtRQUNwQixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQ7O09BRUc7SUFDSSxtQkFBbUI7UUFDeEIsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUM7YUFDdkMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7YUFDckMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxDQUFDO2FBQ25FLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsb0JBQW9CO1FBQy9CLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUFtQixDQUFDO1FBRTFDLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDM0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQzFCLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUN4QixTQUFTO1lBQ1gsQ0FBQztZQUVELElBQUksQ0FBQztnQkFDSCxNQUFNLFdBQVcsR0FBRyxNQUFNLEtBQUssQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3ZELE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQ2hDLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUN4QixPQUFPLENBQUMsS0FBSyxDQUFDLDJCQUEyQixJQUFJLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzRCxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7T0FFRztJQUNJLGdCQUFnQjtRQVNyQixNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBRXhCLEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDM0MsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUU7Z0JBQ2QsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZO2dCQUNoQyxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7Z0JBQzVCLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxFQUFFLE9BQU87Z0JBQ25DLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTthQUNuQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQ7O09BRUc7SUFDSSxVQUFVO1FBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNuQixPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQy9CLENBQUM7SUFFRDs7T0FFRztJQUNJLFdBQVcsQ0FBQyxHQUFXO1FBQzVCLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUMzQixPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRDs7T0FFRztJQUNJLGFBQWE7UUFLbEIsT0FBTztZQUNMLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUk7WUFDckIsVUFBVSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVTtZQUN2QyxHQUFHLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHO1NBQzFCLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDTyxLQUFLLENBQUMsY0FBYyxDQUM1QixPQUF5QixFQUN6QixNQUEyQjtRQUUzQixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsYUFBYSxJQUFJLENBQUMsQ0FBQztRQUM5QyxJQUFJLFNBQTRCLENBQUM7UUFFakMsS0FBSyxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsT0FBTyxJQUFJLFdBQVcsRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQ3hELElBQUksQ0FBQztnQkFDSCxPQUFPLE1BQU0sT0FBTyxFQUFFLENBQUM7WUFDekIsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsU0FBUyxHQUFHLEtBQWMsQ0FBQztnQkFFM0IsSUFBSSxPQUFPLEdBQUcsV0FBVyxFQUFFLENBQUM7b0JBQzFCLE1BQU0sS0FBSyxHQUFHLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUM7b0JBQ3BELE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLE9BQU8sVUFBVSxLQUFLLElBQUksQ0FBQyxDQUFDO29CQUN6RCxNQUFNLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMzQyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLFNBQVMsSUFBSSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFRDs7T0FFRztJQUNPLFlBQVksQ0FBQyxHQUFXO1FBQ2hDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRWxDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELG1DQUFtQztRQUNuQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNuRCxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDOUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdkIsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDO0lBQ3BCLENBQUM7SUFFRDs7T0FFRztJQUNPLFVBQVUsQ0FBQyxHQUFXLEVBQUUsSUFBVyxFQUFFLEdBQVk7UUFDekQsNEJBQTRCO1FBQzVCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNuRCxzQkFBc0I7WUFDdEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUM7WUFDakQsSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDZCxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMvQixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNsQixJQUFJO1lBQ0osU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFO1lBQ3JCLEdBQUcsRUFBRSxHQUFHLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHO1NBQ2pDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNPLFlBQVksQ0FBQyxZQUFvQjtRQUN6QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMvQyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3ZCLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDTyxVQUFVLENBQUMsWUFBb0IsRUFBRSxLQUFZO1FBQ3JELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQy9DLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbkIsS0FBSyxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7WUFDeEIsS0FBSyxDQUFDLGFBQWEsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ25DLENBQUM7SUFDSCxDQUFDO0NBQ0YifQ==
@@ -0,0 +1,121 @@
1
+ import type { IStockProvider, IProviderConfig } from './interfaces/provider.js';
2
+ import type { IFundamentalsProvider, IFundamentalsProviderConfig, IStockFundamentals } from './interfaces/fundamentals.js';
3
+ import type { IStockPrice } from './interfaces/stockprice.js';
4
+ import type { IStockData, IStockDataServiceConfig, ICompleteStockDataRequest, ICompleteStockDataBatchRequest } from './interfaces/stockdata.js';
5
+ /**
6
+ * Unified service for managing both stock prices and fundamentals
7
+ * Provides automatic enrichment and convenient combined data access
8
+ */
9
+ export declare class StockDataService {
10
+ private priceProviders;
11
+ private fundamentalsProviders;
12
+ private priceCache;
13
+ private fundamentalsCache;
14
+ private logger;
15
+ private config;
16
+ constructor(config?: IStockDataServiceConfig);
17
+ /**
18
+ * Register a price provider
19
+ */
20
+ registerPriceProvider(provider: IStockProvider, config?: IProviderConfig): void;
21
+ /**
22
+ * Register a fundamentals provider
23
+ */
24
+ registerFundamentalsProvider(provider: IFundamentalsProvider, config?: IFundamentalsProviderConfig): void;
25
+ /**
26
+ * Unregister a price provider
27
+ */
28
+ unregisterPriceProvider(providerName: string): void;
29
+ /**
30
+ * Unregister a fundamentals provider
31
+ */
32
+ unregisterFundamentalsProvider(providerName: string): void;
33
+ /**
34
+ * Get all registered price providers
35
+ */
36
+ getPriceProviders(): IStockProvider[];
37
+ /**
38
+ * Get all registered fundamentals providers
39
+ */
40
+ getFundamentalsProviders(): IFundamentalsProvider[];
41
+ /**
42
+ * Get enabled price providers sorted by priority
43
+ */
44
+ private getEnabledPriceProviders;
45
+ /**
46
+ * Get enabled fundamentals providers sorted by priority
47
+ */
48
+ private getEnabledFundamentalsProviders;
49
+ /**
50
+ * Get current price for a single ticker
51
+ */
52
+ getPrice(ticker: string): Promise<IStockPrice>;
53
+ /**
54
+ * Get current prices for multiple tickers
55
+ */
56
+ getPrices(tickers: string[]): Promise<IStockPrice[]>;
57
+ /**
58
+ * Get fundamentals for a single ticker
59
+ */
60
+ getFundamentals(ticker: string): Promise<IStockFundamentals>;
61
+ /**
62
+ * Get fundamentals for multiple tickers
63
+ */
64
+ getBatchFundamentals(tickers: string[]): Promise<IStockFundamentals[]>;
65
+ /**
66
+ * ✨ Get complete stock data (price + fundamentals) with automatic enrichment
67
+ */
68
+ getStockData(request: string | ICompleteStockDataRequest): Promise<IStockData>;
69
+ /**
70
+ * ✨ Get complete stock data for multiple tickers with automatic enrichment
71
+ */
72
+ getBatchStockData(request: string[] | ICompleteStockDataBatchRequest): Promise<IStockData[]>;
73
+ /**
74
+ * Enrich fundamentals with calculated metrics using current price
75
+ */
76
+ private enrichWithPrice;
77
+ /**
78
+ * Fetch with retry logic
79
+ */
80
+ private fetchWithRetry;
81
+ /**
82
+ * Get from cache if not expired
83
+ */
84
+ private getFromCache;
85
+ /**
86
+ * Add to cache with TTL
87
+ */
88
+ private addToCache;
89
+ /**
90
+ * Check health of all providers (both price and fundamentals)
91
+ */
92
+ checkProvidersHealth(): Promise<Map<string, boolean>>;
93
+ /**
94
+ * Get statistics for all providers
95
+ */
96
+ getProviderStats(): Map<string, {
97
+ type: 'price' | 'fundamentals';
98
+ successCount: number;
99
+ errorCount: number;
100
+ lastError?: string;
101
+ lastErrorTime?: Date;
102
+ }>;
103
+ /**
104
+ * Clear all caches
105
+ */
106
+ clearCache(): void;
107
+ /**
108
+ * Get cache statistics
109
+ */
110
+ getCacheStats(): {
111
+ priceCache: {
112
+ size: number;
113
+ ttl: number;
114
+ };
115
+ fundamentalsCache: {
116
+ size: number;
117
+ ttl: number;
118
+ };
119
+ maxEntries: number;
120
+ };
121
+ }