moflo 4.8.61 → 4.8.63
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": "moflo",
|
|
3
|
-
"version": "4.8.
|
|
3
|
+
"version": "4.8.63",
|
|
4
4
|
"description": "MoFlo — AI agent orchestration for Claude Code. Forked from ruflo/claude-flow with patches applied to source, plus feature-level orchestration.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
},
|
|
94
94
|
"dependencies": {
|
|
95
95
|
"js-yaml": "^4.1.1",
|
|
96
|
+
"lru-cache": "^11.3.5",
|
|
96
97
|
"semver": "^7.7.4",
|
|
97
98
|
"sql.js": "^1.14.1",
|
|
98
99
|
"valibot": "^1.3.1"
|
|
@@ -111,7 +112,7 @@
|
|
|
111
112
|
"@types/js-yaml": "^4.0.9",
|
|
112
113
|
"@types/node": "^20.19.37",
|
|
113
114
|
"eslint": "^8.0.0",
|
|
114
|
-
"moflo": "^4.8.
|
|
115
|
+
"moflo": "^4.8.61",
|
|
115
116
|
"tsx": "^4.21.0",
|
|
116
117
|
"typescript": "^5.9.3",
|
|
117
118
|
"vitest": "^4.0.0"
|
|
@@ -24,6 +24,9 @@ export class CacheManager extends EventEmitter {
|
|
|
24
24
|
head = null;
|
|
25
25
|
tail = null;
|
|
26
26
|
currentMemory = 0;
|
|
27
|
+
// Cache size estimates to avoid repeated JSON.stringify
|
|
28
|
+
sizeCache = new Map();
|
|
29
|
+
maxSizeCacheEntries = 10000;
|
|
27
30
|
// Statistics
|
|
28
31
|
stats = {
|
|
29
32
|
hits: 0,
|
|
@@ -75,17 +78,21 @@ export class CacheManager extends EventEmitter {
|
|
|
75
78
|
// Check if key already exists
|
|
76
79
|
const existingNode = this.cache.get(key);
|
|
77
80
|
if (existingNode) {
|
|
78
|
-
// Update existing entry
|
|
81
|
+
// Update existing entry - recalculate size if data changed
|
|
82
|
+
const oldSize = existingNode.estimatedSize;
|
|
83
|
+
const newSize = this.estimateSizeCached(key, data);
|
|
79
84
|
existingNode.value.data = data;
|
|
80
85
|
existingNode.value.cachedAt = now;
|
|
81
86
|
existingNode.value.expiresAt = now + entryTtl;
|
|
82
87
|
existingNode.value.lastAccessedAt = now;
|
|
88
|
+
existingNode.estimatedSize = newSize;
|
|
89
|
+
this.currentMemory = this.currentMemory - oldSize + newSize;
|
|
83
90
|
this.moveToFront(existingNode);
|
|
84
91
|
this.stats.writes++;
|
|
85
92
|
return;
|
|
86
93
|
}
|
|
87
|
-
// Calculate memory for new entry
|
|
88
|
-
const entryMemory = this.
|
|
94
|
+
// Calculate memory for new entry (with caching)
|
|
95
|
+
const entryMemory = this.estimateSizeCached(key, data);
|
|
89
96
|
// Evict entries if needed for memory pressure
|
|
90
97
|
if (this.config.maxMemory) {
|
|
91
98
|
while (this.currentMemory + entryMemory > this.config.maxMemory &&
|
|
@@ -110,6 +117,7 @@ export class CacheManager extends EventEmitter {
|
|
|
110
117
|
value: cachedEntry,
|
|
111
118
|
prev: null,
|
|
112
119
|
next: null,
|
|
120
|
+
estimatedSize: entryMemory, // Store computed size
|
|
113
121
|
};
|
|
114
122
|
// Add to cache
|
|
115
123
|
this.cache.set(key, node);
|
|
@@ -128,7 +136,8 @@ export class CacheManager extends EventEmitter {
|
|
|
128
136
|
}
|
|
129
137
|
this.removeNode(node);
|
|
130
138
|
this.cache.delete(key);
|
|
131
|
-
this.currentMemory -=
|
|
139
|
+
this.currentMemory -= node.estimatedSize; // Use cached size
|
|
140
|
+
this.sizeCache.delete(key); // Clean up size cache
|
|
132
141
|
this.emit('cache:delete', { key });
|
|
133
142
|
return true;
|
|
134
143
|
}
|
|
@@ -149,11 +158,13 @@ export class CacheManager extends EventEmitter {
|
|
|
149
158
|
* Clear all entries from the cache
|
|
150
159
|
*/
|
|
151
160
|
clear() {
|
|
161
|
+
const previousSize = this.cache.size;
|
|
152
162
|
this.cache.clear();
|
|
163
|
+
this.sizeCache.clear();
|
|
153
164
|
this.head = null;
|
|
154
165
|
this.tail = null;
|
|
155
166
|
this.currentMemory = 0;
|
|
156
|
-
this.emit('cache:cleared', { previousSize
|
|
167
|
+
this.emit('cache:cleared', { previousSize });
|
|
157
168
|
}
|
|
158
169
|
/**
|
|
159
170
|
* Get cache statistics
|
|
@@ -255,8 +266,37 @@ export class CacheManager extends EventEmitter {
|
|
|
255
266
|
isExpired(entry) {
|
|
256
267
|
return Date.now() > entry.expiresAt;
|
|
257
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* OPTIMIZED: Cache size estimates to avoid repeated JSON.stringify
|
|
271
|
+
* This is called on every cache set and eviction, so caching saves significant CPU
|
|
272
|
+
*/
|
|
273
|
+
estimateSizeCached(key, data) {
|
|
274
|
+
// Check if we have a cached size estimate
|
|
275
|
+
const cached = this.sizeCache.get(key);
|
|
276
|
+
if (cached !== undefined) {
|
|
277
|
+
return cached;
|
|
278
|
+
}
|
|
279
|
+
// Compute size
|
|
280
|
+
const size = this.estimateSize(data);
|
|
281
|
+
// Cache the result (with LRU eviction)
|
|
282
|
+
if (this.sizeCache.size >= this.maxSizeCacheEntries) {
|
|
283
|
+
const firstKey = this.sizeCache.keys().next().value;
|
|
284
|
+
if (firstKey !== undefined)
|
|
285
|
+
this.sizeCache.delete(firstKey);
|
|
286
|
+
}
|
|
287
|
+
this.sizeCache.set(key, size);
|
|
288
|
+
return size;
|
|
289
|
+
}
|
|
258
290
|
estimateSize(data) {
|
|
259
291
|
try {
|
|
292
|
+
// For primitive types, use fast path
|
|
293
|
+
if (typeof data === 'string') {
|
|
294
|
+
return data.length * 2;
|
|
295
|
+
}
|
|
296
|
+
if (typeof data === 'number' || typeof data === 'boolean') {
|
|
297
|
+
return 8;
|
|
298
|
+
}
|
|
299
|
+
// For objects, use JSON.stringify (but only once due to caching)
|
|
260
300
|
return JSON.stringify(data).length * 2; // Rough UTF-16 estimate
|
|
261
301
|
}
|
|
262
302
|
catch {
|
|
@@ -298,9 +338,10 @@ export class CacheManager extends EventEmitter {
|
|
|
298
338
|
if (!this.tail)
|
|
299
339
|
return;
|
|
300
340
|
const evictedKey = this.tail.key;
|
|
301
|
-
const evictedSize = this.
|
|
341
|
+
const evictedSize = this.tail.estimatedSize; // Use cached size
|
|
302
342
|
this.removeNode(this.tail);
|
|
303
343
|
this.cache.delete(evictedKey);
|
|
344
|
+
this.sizeCache.delete(evictedKey); // Clean up size cache
|
|
304
345
|
this.currentMemory -= evictedSize;
|
|
305
346
|
this.stats.evictions++;
|
|
306
347
|
this.emit('cache:eviction', { key: evictedKey });
|