gthinking 1.2.1 → 2.1.1
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/.eslintrc.js +34 -0
- package/ANALYSIS_SUMMARY.md +363 -0
- package/README.md +230 -245
- package/dist/analysis/analysis-engine.d.ts +63 -0
- package/dist/analysis/analysis-engine.d.ts.map +1 -0
- package/dist/analysis/analysis-engine.js +322 -0
- package/dist/analysis/analysis-engine.js.map +1 -0
- package/dist/core/config.d.ts +1419 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +361 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/engine.d.ts +176 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +604 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/errors.d.ts +153 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +287 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/{types.js → core/index.js} +8 -4
- package/dist/core/index.js.map +1 -0
- package/dist/core/pipeline.d.ts +121 -0
- package/dist/core/pipeline.d.ts.map +1 -0
- package/dist/core/pipeline.js +289 -0
- package/dist/core/pipeline.js.map +1 -0
- package/dist/core/rate-limiter.d.ts +58 -0
- package/dist/core/rate-limiter.d.ts.map +1 -0
- package/dist/core/rate-limiter.js +133 -0
- package/dist/core/rate-limiter.js.map +1 -0
- package/dist/core/session-manager.d.ts +96 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +223 -0
- package/dist/core/session-manager.js.map +1 -0
- package/dist/creativity/creativity-engine.d.ts +6 -0
- package/dist/creativity/creativity-engine.d.ts.map +1 -0
- package/dist/creativity/creativity-engine.js +17 -0
- package/dist/creativity/creativity-engine.js.map +1 -0
- package/dist/index.d.ts +24 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +130 -104
- package/dist/index.js.map +1 -1
- package/dist/learning/learning-engine.d.ts +6 -0
- package/dist/learning/learning-engine.d.ts.map +1 -0
- package/dist/learning/learning-engine.js +17 -0
- package/dist/learning/learning-engine.js.map +1 -0
- package/dist/llm/index.d.ts +10 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +26 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/llm-service.d.ts +109 -0
- package/dist/llm/llm-service.d.ts.map +1 -0
- package/dist/llm/llm-service.js +224 -0
- package/dist/llm/llm-service.js.map +1 -0
- package/dist/llm/providers/base.d.ts +85 -0
- package/dist/llm/providers/base.d.ts.map +1 -0
- package/dist/llm/providers/base.js +57 -0
- package/dist/llm/providers/base.js.map +1 -0
- package/dist/llm/providers/cli.d.ts +23 -0
- package/dist/llm/providers/cli.d.ts.map +1 -0
- package/dist/llm/providers/cli.js +158 -0
- package/dist/llm/providers/cli.js.map +1 -0
- package/dist/llm/providers/gemini.d.ts +30 -0
- package/dist/llm/providers/gemini.d.ts.map +1 -0
- package/dist/llm/providers/gemini.js +168 -0
- package/dist/llm/providers/gemini.js.map +1 -0
- package/dist/llm/sanitization.d.ts +50 -0
- package/dist/llm/sanitization.d.ts.map +1 -0
- package/dist/llm/sanitization.js +149 -0
- package/dist/llm/sanitization.js.map +1 -0
- package/dist/{server.d.ts.map → mcp/server.d.ts.map} +1 -1
- package/dist/mcp/server.js +108 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/planning/planning-engine.d.ts +6 -0
- package/dist/planning/planning-engine.d.ts.map +1 -0
- package/dist/planning/planning-engine.js +17 -0
- package/dist/planning/planning-engine.js.map +1 -0
- package/dist/reasoning/reasoning-engine.d.ts +6 -0
- package/dist/reasoning/reasoning-engine.d.ts.map +1 -0
- package/dist/reasoning/reasoning-engine.js +17 -0
- package/dist/reasoning/reasoning-engine.js.map +1 -0
- package/dist/search/search-engine.d.ts +99 -0
- package/dist/search/search-engine.d.ts.map +1 -0
- package/dist/search/search-engine.js +271 -0
- package/dist/search/search-engine.js.map +1 -0
- package/dist/synthesis/synthesis-engine.d.ts +6 -0
- package/dist/synthesis/synthesis-engine.d.ts.map +1 -0
- package/dist/synthesis/synthesis-engine.js +17 -0
- package/dist/synthesis/synthesis-engine.js.map +1 -0
- package/dist/types/analysis.d.ts +1534 -49
- package/dist/types/analysis.d.ts.map +1 -1
- package/dist/types/analysis.js +250 -0
- package/dist/types/analysis.js.map +1 -1
- package/dist/types/core.d.ts +257 -30
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/core.js +148 -18
- package/dist/types/core.js.map +1 -1
- package/dist/types/creativity.d.ts +2871 -56
- package/dist/types/creativity.d.ts.map +1 -1
- package/dist/types/creativity.js +195 -0
- package/dist/types/creativity.js.map +1 -1
- package/dist/types/index.d.ts +6 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +17 -2
- package/dist/types/index.js.map +1 -1
- package/dist/types/learning.d.ts +851 -61
- package/dist/types/learning.d.ts.map +1 -1
- package/dist/types/learning.js +155 -0
- package/dist/types/learning.js.map +1 -1
- package/dist/types/planning.d.ts +2223 -71
- package/dist/types/planning.d.ts.map +1 -1
- package/dist/types/planning.js +190 -0
- package/dist/types/planning.js.map +1 -1
- package/dist/types/reasoning.d.ts +2209 -72
- package/dist/types/reasoning.d.ts.map +1 -1
- package/dist/types/reasoning.js +200 -1
- package/dist/types/reasoning.js.map +1 -1
- package/dist/types/search.d.ts +981 -53
- package/dist/types/search.d.ts.map +1 -1
- package/dist/types/search.js +137 -0
- package/dist/types/search.js.map +1 -1
- package/dist/types/synthesis.d.ts +583 -37
- package/dist/types/synthesis.d.ts.map +1 -1
- package/dist/types/synthesis.js +138 -0
- package/dist/types/synthesis.js.map +1 -1
- package/dist/utils/cache.d.ts +144 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +288 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/id-generator.d.ts +89 -0
- package/dist/utils/id-generator.d.ts.map +1 -0
- package/dist/utils/id-generator.js +132 -0
- package/dist/utils/id-generator.js.map +1 -0
- package/dist/utils/index.d.ts +11 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +33 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +142 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +248 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/metrics.d.ts +149 -0
- package/dist/utils/metrics.d.ts.map +1 -0
- package/dist/utils/metrics.js +296 -0
- package/dist/utils/metrics.js.map +1 -0
- package/dist/utils/timer.d.ts +7 -0
- package/dist/utils/timer.d.ts.map +1 -0
- package/dist/utils/timer.js +17 -0
- package/dist/utils/timer.js.map +1 -0
- package/dist/utils/validation.d.ts +147 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +275 -0
- package/dist/utils/validation.js.map +1 -0
- package/docs/API.md +411 -0
- package/docs/ARCHITECTURE.md +271 -0
- package/docs/CHANGELOG.md +283 -0
- package/jest.config.js +28 -0
- package/package.json +43 -30
- package/src/analysis/analysis-engine.ts +383 -0
- package/src/core/config.ts +406 -0
- package/src/core/engine.ts +785 -0
- package/src/core/errors.ts +349 -0
- package/src/core/index.ts +12 -0
- package/src/core/pipeline.ts +424 -0
- package/src/core/rate-limiter.ts +155 -0
- package/src/core/session-manager.ts +269 -0
- package/src/creativity/creativity-engine.ts +14 -0
- package/src/index.ts +178 -0
- package/src/learning/learning-engine.ts +14 -0
- package/src/llm/index.ts +10 -0
- package/src/llm/llm-service.ts +285 -0
- package/src/llm/providers/base.ts +146 -0
- package/src/llm/providers/cli.ts +186 -0
- package/src/llm/providers/gemini.ts +201 -0
- package/src/llm/sanitization.ts +178 -0
- package/src/mcp/server.ts +117 -0
- package/src/planning/planning-engine.ts +14 -0
- package/src/reasoning/reasoning-engine.ts +14 -0
- package/src/search/search-engine.ts +333 -0
- package/src/synthesis/synthesis-engine.ts +14 -0
- package/src/types/analysis.ts +337 -0
- package/src/types/core.ts +342 -0
- package/src/types/creativity.ts +268 -0
- package/src/types/index.ts +31 -0
- package/src/types/learning.ts +215 -0
- package/src/types/planning.ts +251 -0
- package/src/types/reasoning.ts +288 -0
- package/src/types/search.ts +192 -0
- package/src/types/synthesis.ts +187 -0
- package/src/utils/cache.ts +363 -0
- package/src/utils/id-generator.ts +135 -0
- package/src/utils/index.ts +22 -0
- package/src/utils/logger.ts +290 -0
- package/src/utils/metrics.ts +380 -0
- package/src/utils/timer.ts +15 -0
- package/src/utils/validation.ts +297 -0
- package/tests/setup.ts +22 -0
- package/tests/unit/cache.test.ts +189 -0
- package/tests/unit/engine.test.ts +179 -0
- package/tests/unit/validation.test.ts +218 -0
- package/tsconfig.json +17 -12
- package/GEMINI.md +0 -68
- package/analysis.ts +0 -1063
- package/creativity.ts +0 -1055
- package/dist/analysis.d.ts +0 -54
- package/dist/analysis.d.ts.map +0 -1
- package/dist/analysis.js +0 -866
- package/dist/analysis.js.map +0 -1
- package/dist/creativity.d.ts +0 -81
- package/dist/creativity.d.ts.map +0 -1
- package/dist/creativity.js +0 -828
- package/dist/creativity.js.map +0 -1
- package/dist/engine.d.ts +0 -90
- package/dist/engine.d.ts.map +0 -1
- package/dist/engine.js +0 -677
- package/dist/engine.js.map +0 -1
- package/dist/examples.d.ts +0 -7
- package/dist/examples.d.ts.map +0 -1
- package/dist/examples.js +0 -506
- package/dist/examples.js.map +0 -1
- package/dist/learning.d.ts +0 -72
- package/dist/learning.d.ts.map +0 -1
- package/dist/learning.js +0 -615
- package/dist/learning.js.map +0 -1
- package/dist/llm-service.d.ts +0 -21
- package/dist/llm-service.d.ts.map +0 -1
- package/dist/llm-service.js +0 -100
- package/dist/llm-service.js.map +0 -1
- package/dist/planning.d.ts +0 -58
- package/dist/planning.d.ts.map +0 -1
- package/dist/planning.js +0 -824
- package/dist/planning.js.map +0 -1
- package/dist/reasoning.d.ts +0 -73
- package/dist/reasoning.d.ts.map +0 -1
- package/dist/reasoning.js +0 -845
- package/dist/reasoning.js.map +0 -1
- package/dist/search-discovery.d.ts +0 -73
- package/dist/search-discovery.d.ts.map +0 -1
- package/dist/search-discovery.js +0 -548
- package/dist/search-discovery.js.map +0 -1
- package/dist/server.js +0 -113
- package/dist/server.js.map +0 -1
- package/dist/types/engine.d.ts +0 -55
- package/dist/types/engine.d.ts.map +0 -1
- package/dist/types/engine.js +0 -3
- package/dist/types/engine.js.map +0 -1
- package/dist/types.d.ts +0 -6
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/engine.ts +0 -947
- package/examples.ts +0 -717
- package/index.ts +0 -106
- package/learning.ts +0 -779
- package/llm-service.ts +0 -120
- package/planning.ts +0 -1028
- package/reasoning.ts +0 -1079
- package/search-discovery.ts +0 -700
- package/server.ts +0 -115
- package/types/analysis.ts +0 -69
- package/types/core.ts +0 -90
- package/types/creativity.ts +0 -72
- package/types/engine.ts +0 -60
- package/types/index.ts +0 -9
- package/types/learning.ts +0 -69
- package/types/planning.ts +0 -85
- package/types/reasoning.ts +0 -92
- package/types/search.ts +0 -58
- package/types/synthesis.ts +0 -42
- package/types.ts +0 -6
- /package/dist/{server.d.ts → mcp/server.d.ts} +0 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache Utility for gthinking v2.0.0
|
|
3
|
+
* In-memory caching with TTL support
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { CacheError } from '../types';
|
|
7
|
+
import { Logger } from './logger';
|
|
8
|
+
|
|
9
|
+
const logger = new Logger('Cache');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Cache entry interface
|
|
13
|
+
*/
|
|
14
|
+
interface CacheEntry<T> {
|
|
15
|
+
value: T;
|
|
16
|
+
timestamp: number;
|
|
17
|
+
ttl: number;
|
|
18
|
+
accessCount: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Cache statistics interface
|
|
23
|
+
*/
|
|
24
|
+
export interface CacheStats {
|
|
25
|
+
size: number;
|
|
26
|
+
hits: number;
|
|
27
|
+
misses: number;
|
|
28
|
+
hitRate: number;
|
|
29
|
+
evictions: number;
|
|
30
|
+
totalAccesses: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Cache configuration interface
|
|
35
|
+
*/
|
|
36
|
+
export interface CacheConfig {
|
|
37
|
+
maxSize: number;
|
|
38
|
+
defaultTTL: number;
|
|
39
|
+
checkInterval: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Default cache configuration
|
|
44
|
+
*/
|
|
45
|
+
const defaultConfig: CacheConfig = {
|
|
46
|
+
maxSize: 1000,
|
|
47
|
+
defaultTTL: 3600000, // 1 hour
|
|
48
|
+
checkInterval: 60000, // 1 minute
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* In-memory cache with TTL support
|
|
53
|
+
*/
|
|
54
|
+
export class Cache<T> {
|
|
55
|
+
private cache: Map<string, CacheEntry<T>> = new Map();
|
|
56
|
+
private config: CacheConfig;
|
|
57
|
+
private stats = {
|
|
58
|
+
hits: 0,
|
|
59
|
+
misses: 0,
|
|
60
|
+
evictions: 0,
|
|
61
|
+
totalAccesses: 0,
|
|
62
|
+
};
|
|
63
|
+
private cleanupInterval: NodeJS.Timeout | null = null;
|
|
64
|
+
|
|
65
|
+
constructor(config: Partial<CacheConfig> = {}) {
|
|
66
|
+
this.config = { ...defaultConfig, ...config };
|
|
67
|
+
this.startCleanupInterval();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get a value from the cache
|
|
72
|
+
* @param key - The cache key
|
|
73
|
+
* @returns The cached value or undefined
|
|
74
|
+
*/
|
|
75
|
+
public get(key: string): T | undefined {
|
|
76
|
+
this.stats.totalAccesses++;
|
|
77
|
+
|
|
78
|
+
const entry = this.cache.get(key);
|
|
79
|
+
|
|
80
|
+
if (!entry) {
|
|
81
|
+
this.stats.misses++;
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Check if entry has expired
|
|
86
|
+
if (this.isExpired(entry)) {
|
|
87
|
+
this.cache.delete(key);
|
|
88
|
+
this.stats.misses++;
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Update access count
|
|
93
|
+
entry.accessCount++;
|
|
94
|
+
this.stats.hits++;
|
|
95
|
+
|
|
96
|
+
return entry.value;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Set a value in the cache
|
|
101
|
+
* @param key - The cache key
|
|
102
|
+
* @param value - The value to cache
|
|
103
|
+
* @param ttl - Time to live in milliseconds (optional)
|
|
104
|
+
*/
|
|
105
|
+
public set(key: string, value: T, ttl?: number): void {
|
|
106
|
+
// Evict entries if cache is full
|
|
107
|
+
if (this.cache.size >= this.config.maxSize && !this.cache.has(key)) {
|
|
108
|
+
this.evictLRU();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const entry: CacheEntry<T> = {
|
|
112
|
+
value,
|
|
113
|
+
timestamp: Date.now(),
|
|
114
|
+
ttl: ttl ?? this.config.defaultTTL,
|
|
115
|
+
accessCount: 0,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
this.cache.set(key, entry);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Check if a key exists in the cache
|
|
123
|
+
* @param key - The cache key
|
|
124
|
+
* @returns True if the key exists and hasn't expired
|
|
125
|
+
*/
|
|
126
|
+
public has(key: string): boolean {
|
|
127
|
+
const entry = this.cache.get(key);
|
|
128
|
+
|
|
129
|
+
if (!entry) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (this.isExpired(entry)) {
|
|
134
|
+
this.cache.delete(key);
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Delete a key from the cache
|
|
143
|
+
* @param key - The cache key
|
|
144
|
+
* @returns True if the key was deleted
|
|
145
|
+
*/
|
|
146
|
+
public delete(key: string): boolean {
|
|
147
|
+
return this.cache.delete(key);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Clear all entries from the cache
|
|
152
|
+
*/
|
|
153
|
+
public clear(): void {
|
|
154
|
+
this.cache.clear();
|
|
155
|
+
logger.info('Cache cleared');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Get cache statistics
|
|
160
|
+
* @returns Cache statistics
|
|
161
|
+
*/
|
|
162
|
+
public getStats(): CacheStats {
|
|
163
|
+
const totalAccesses = this.stats.totalAccesses;
|
|
164
|
+
const hitRate = totalAccesses > 0 ? this.stats.hits / totalAccesses : 0;
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
size: this.cache.size,
|
|
168
|
+
hits: this.stats.hits,
|
|
169
|
+
misses: this.stats.misses,
|
|
170
|
+
hitRate,
|
|
171
|
+
evictions: this.stats.evictions,
|
|
172
|
+
totalAccesses,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Reset cache statistics
|
|
178
|
+
*/
|
|
179
|
+
public resetStats(): void {
|
|
180
|
+
this.stats = {
|
|
181
|
+
hits: 0,
|
|
182
|
+
misses: 0,
|
|
183
|
+
evictions: 0,
|
|
184
|
+
totalAccesses: 0,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Get all keys in the cache
|
|
190
|
+
* @returns Array of cache keys
|
|
191
|
+
*/
|
|
192
|
+
public keys(): string[] {
|
|
193
|
+
return Array.from(this.cache.keys());
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Get the number of entries in the cache
|
|
198
|
+
* @returns Number of entries
|
|
199
|
+
*/
|
|
200
|
+
public size(): number {
|
|
201
|
+
return this.cache.size;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Dispose of the cache and stop cleanup interval
|
|
206
|
+
*/
|
|
207
|
+
public dispose(): void {
|
|
208
|
+
if (this.cleanupInterval) {
|
|
209
|
+
clearInterval(this.cleanupInterval);
|
|
210
|
+
this.cleanupInterval = null;
|
|
211
|
+
}
|
|
212
|
+
this.clear();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Check if an entry has expired
|
|
217
|
+
* @param entry - The cache entry
|
|
218
|
+
* @returns True if the entry has expired
|
|
219
|
+
*/
|
|
220
|
+
private isExpired(entry: CacheEntry<T>): boolean {
|
|
221
|
+
return Date.now() - entry.timestamp > entry.ttl;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Evict the least recently used entry
|
|
226
|
+
*/
|
|
227
|
+
private evictLRU(): void {
|
|
228
|
+
let oldestKey: string | null = null;
|
|
229
|
+
let oldestTimestamp = Infinity;
|
|
230
|
+
|
|
231
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
232
|
+
if (entry.timestamp < oldestTimestamp) {
|
|
233
|
+
oldestTimestamp = entry.timestamp;
|
|
234
|
+
oldestKey = key;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (oldestKey) {
|
|
239
|
+
this.cache.delete(oldestKey);
|
|
240
|
+
this.stats.evictions++;
|
|
241
|
+
logger.debug(`Evicted LRU entry: ${oldestKey}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Clean up expired entries
|
|
247
|
+
*/
|
|
248
|
+
private cleanup(): void {
|
|
249
|
+
const now = Date.now();
|
|
250
|
+
let expiredCount = 0;
|
|
251
|
+
|
|
252
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
253
|
+
if (now - entry.timestamp > entry.ttl) {
|
|
254
|
+
this.cache.delete(key);
|
|
255
|
+
expiredCount++;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (expiredCount > 0) {
|
|
260
|
+
logger.debug(`Cleaned up ${expiredCount} expired entries`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Start the cleanup interval
|
|
266
|
+
*/
|
|
267
|
+
private startCleanupInterval(): void {
|
|
268
|
+
this.cleanupInterval = setInterval(() => {
|
|
269
|
+
this.cleanup();
|
|
270
|
+
}, this.config.checkInterval);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Cache manager for managing multiple cache instances
|
|
276
|
+
*/
|
|
277
|
+
export class CacheManager {
|
|
278
|
+
private caches: Map<string, Cache<unknown>> = new Map();
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Get or create a cache instance
|
|
282
|
+
* @param name - The cache name
|
|
283
|
+
* @param config - Cache configuration
|
|
284
|
+
* @returns Cache instance
|
|
285
|
+
*/
|
|
286
|
+
public getCache<T>(name: string, config?: Partial<CacheConfig>): Cache<T> {
|
|
287
|
+
if (!this.caches.has(name)) {
|
|
288
|
+
this.caches.set(name, new Cache<T>(config));
|
|
289
|
+
}
|
|
290
|
+
return this.caches.get(name) as Cache<T>;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Delete a cache instance
|
|
295
|
+
* @param name - The cache name
|
|
296
|
+
*/
|
|
297
|
+
public deleteCache(name: string): void {
|
|
298
|
+
const cache = this.caches.get(name);
|
|
299
|
+
if (cache) {
|
|
300
|
+
cache.dispose();
|
|
301
|
+
this.caches.delete(name);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Clear all caches
|
|
307
|
+
*/
|
|
308
|
+
public clearAll(): void {
|
|
309
|
+
for (const cache of this.caches.values()) {
|
|
310
|
+
cache.clear();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Dispose of all caches
|
|
316
|
+
*/
|
|
317
|
+
public dispose(): void {
|
|
318
|
+
for (const [name, cache] of this.caches.entries()) {
|
|
319
|
+
cache.dispose();
|
|
320
|
+
}
|
|
321
|
+
this.caches.clear();
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Get all cache names
|
|
326
|
+
* @returns Array of cache names
|
|
327
|
+
*/
|
|
328
|
+
public getCacheNames(): string[] {
|
|
329
|
+
return Array.from(this.caches.keys());
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Export a singleton cache manager
|
|
334
|
+
export const cacheManager = new CacheManager();
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Memoize decorator for caching function results
|
|
338
|
+
* @param fn - The function to memoize
|
|
339
|
+
* @param keyGenerator - Function to generate cache key from arguments
|
|
340
|
+
* @param ttl - Time to live in milliseconds
|
|
341
|
+
* @returns Memoized function
|
|
342
|
+
*/
|
|
343
|
+
export function memoize<T extends (...args: unknown[]) => unknown>(
|
|
344
|
+
fn: T,
|
|
345
|
+
keyGenerator?: (...args: Parameters<T>) => string,
|
|
346
|
+
ttl?: number
|
|
347
|
+
): T {
|
|
348
|
+
const cache = new Cache<ReturnType<T>>();
|
|
349
|
+
|
|
350
|
+
return function (...args: Parameters<T>): ReturnType<T> {
|
|
351
|
+
const key = keyGenerator ? keyGenerator(...args) : JSON.stringify(args);
|
|
352
|
+
|
|
353
|
+
const cached = cache.get(key);
|
|
354
|
+
if (cached !== undefined) {
|
|
355
|
+
return cached;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const result = fn(...args) as ReturnType<T>;
|
|
359
|
+
cache.set(key, result, ttl);
|
|
360
|
+
|
|
361
|
+
return result;
|
|
362
|
+
} as T;
|
|
363
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ID Generator Utility for gthinking v2.0.0
|
|
3
|
+
* Secure and collision-resistant ID generation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { v4 as uuidv4, v5 as uuidv5 } from 'uuid';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generate a random UUID v4
|
|
10
|
+
* @returns A random UUID string
|
|
11
|
+
*/
|
|
12
|
+
export function generateUUID(): string {
|
|
13
|
+
return uuidv4();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Generate a deterministic UUID v5 based on a namespace and name
|
|
18
|
+
* @param namespace - The namespace UUID
|
|
19
|
+
* @param name - The name to hash
|
|
20
|
+
* @returns A deterministic UUID string
|
|
21
|
+
*/
|
|
22
|
+
export function generateDeterministicUUID(namespace: string, name: string): string {
|
|
23
|
+
return uuidv5(name, namespace);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Generate a short ID (8 characters) for internal use
|
|
28
|
+
* Note: This is not cryptographically secure, use only for non-sensitive IDs
|
|
29
|
+
* @returns A short random string
|
|
30
|
+
*/
|
|
31
|
+
export function generateShortId(): string {
|
|
32
|
+
return Math.random().toString(36).substring(2, 10);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Generate a timestamp-based ID with random suffix
|
|
37
|
+
* @param prefix - Optional prefix for the ID
|
|
38
|
+
* @returns A timestamp-based ID string
|
|
39
|
+
*/
|
|
40
|
+
export function generateTimestampId(prefix?: string): string {
|
|
41
|
+
const timestamp = Date.now().toString(36);
|
|
42
|
+
const random = Math.random().toString(36).substring(2, 6);
|
|
43
|
+
const id = `${timestamp}_${random}`;
|
|
44
|
+
return prefix ? `${prefix}_${id}` : id;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Generate a sequential ID with padding
|
|
49
|
+
* @param sequence - The sequence number
|
|
50
|
+
* @param padding - The number of digits to pad to
|
|
51
|
+
* @returns A padded sequential ID string
|
|
52
|
+
*/
|
|
53
|
+
export function generateSequentialId(sequence: number, padding = 6): string {
|
|
54
|
+
return sequence.toString().padStart(padding, '0');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Generate a compound ID from multiple parts
|
|
59
|
+
* @param parts - The parts to combine
|
|
60
|
+
* @param separator - The separator to use (default: '_')
|
|
61
|
+
* @returns A compound ID string
|
|
62
|
+
*/
|
|
63
|
+
export function generateCompoundId(parts: string[], separator = '_'): string {
|
|
64
|
+
return parts.join(separator);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Validate if a string is a valid UUID
|
|
69
|
+
* @param id - The string to validate
|
|
70
|
+
* @returns True if the string is a valid UUID
|
|
71
|
+
*/
|
|
72
|
+
export function isValidUUID(id: string): boolean {
|
|
73
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
74
|
+
return uuidRegex.test(id);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Namespace UUIDs for deterministic ID generation
|
|
79
|
+
*/
|
|
80
|
+
export const Namespaces = {
|
|
81
|
+
DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
|
|
82
|
+
URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8',
|
|
83
|
+
OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8',
|
|
84
|
+
X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8',
|
|
85
|
+
// Custom namespaces for gthinking
|
|
86
|
+
SESSION: 'a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d',
|
|
87
|
+
TASK: 'b8c9d0e1-f2a3-5b4c-9d5e-6f7a8b9c0d1e',
|
|
88
|
+
IDEA: 'c9d0e1f2-a3b4-6c5d-0e6f-7a8b9c0d1e2f',
|
|
89
|
+
} as const;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* ID Generator class for managing ID generation with prefixes
|
|
93
|
+
*/
|
|
94
|
+
export class IdGenerator {
|
|
95
|
+
private counters: Map<string, number> = new Map();
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Generate a prefixed ID with an auto-incrementing counter
|
|
99
|
+
* @param prefix - The prefix for the ID
|
|
100
|
+
* @returns A prefixed ID string
|
|
101
|
+
*/
|
|
102
|
+
public generatePrefixedId(prefix: string): string {
|
|
103
|
+
const current = this.counters.get(prefix) || 0;
|
|
104
|
+
const next = current + 1;
|
|
105
|
+
this.counters.set(prefix, next);
|
|
106
|
+
return `${prefix}_${generateSequentialId(next)}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Reset the counter for a specific prefix
|
|
111
|
+
* @param prefix - The prefix to reset
|
|
112
|
+
*/
|
|
113
|
+
public resetCounter(prefix: string): void {
|
|
114
|
+
this.counters.delete(prefix);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Reset all counters
|
|
119
|
+
*/
|
|
120
|
+
public resetAllCounters(): void {
|
|
121
|
+
this.counters.clear();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get the current counter value for a prefix
|
|
126
|
+
* @param prefix - The prefix to check
|
|
127
|
+
* @returns The current counter value
|
|
128
|
+
*/
|
|
129
|
+
public getCounter(prefix: string): number {
|
|
130
|
+
return this.counters.get(prefix) || 0;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Export a singleton instance
|
|
135
|
+
export const idGenerator = new IdGenerator();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utils Index for gthinking v2.0.0
|
|
3
|
+
* Central export point for all utilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ID Generator
|
|
7
|
+
export * from './id-generator';
|
|
8
|
+
|
|
9
|
+
// Validation
|
|
10
|
+
export * from './validation';
|
|
11
|
+
|
|
12
|
+
// Logger
|
|
13
|
+
export * from './logger';
|
|
14
|
+
|
|
15
|
+
// Cache
|
|
16
|
+
export * from './cache';
|
|
17
|
+
|
|
18
|
+
// Metrics
|
|
19
|
+
export * from './metrics';
|
|
20
|
+
|
|
21
|
+
// Timer
|
|
22
|
+
export * from './timer';
|