@stackmemoryai/stackmemory 1.12.0 → 1.14.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.
- package/LICENSE +131 -64
- package/README.md +3 -1
- package/bin/claude-sm +16 -1
- package/bin/claude-smd +16 -1
- package/bin/codex-smd +16 -1
- package/bin/gemini-sm +16 -1
- package/bin/hermes-sm +21 -0
- package/bin/hermes-smd +21 -0
- package/bin/opencode-sm +16 -1
- package/dist/src/cli/codex-sm.js +51 -11
- package/dist/src/cli/commands/brain.js +206 -0
- package/dist/src/cli/commands/company-os.js +184 -0
- package/dist/src/cli/commands/context.js +5 -0
- package/dist/src/cli/commands/operator.js +127 -0
- package/dist/src/cli/commands/orchestrate.js +2 -0
- package/dist/src/cli/commands/orchestrator.js +3 -2
- package/dist/src/cli/commands/patterns.js +254 -0
- package/dist/src/cli/commands/portal.js +161 -0
- package/dist/src/cli/commands/scaffold.js +92 -0
- package/dist/src/cli/commands/setup.js +1 -4
- package/dist/src/cli/commands/sync.js +253 -0
- package/dist/src/cli/commands/tasks.js +130 -1
- package/dist/src/cli/commands/vision.js +221 -0
- package/dist/src/cli/hermes-sm.js +224 -0
- package/dist/src/cli/index.js +15 -10
- package/dist/src/cli/utils/real-cli-bin.js +72 -0
- package/dist/src/core/brain/brain-store.js +187 -0
- package/dist/src/core/brain/brain-sync.js +193 -0
- package/dist/src/core/brain/index.js +78 -0
- package/dist/src/core/brain/types.js +10 -0
- package/dist/src/core/cache/token-estimator.js +24 -1
- package/dist/src/core/config/feature-flags.js +2 -6
- package/dist/src/core/context/frame-database.js +44 -0
- package/dist/src/core/context/recursive-context-manager.js +1 -1
- package/dist/src/core/context/rehydration.js +2 -1
- package/dist/src/core/database/sqlite-adapter.js +14 -1
- package/dist/src/core/models/model-router.js +33 -1
- package/dist/src/core/models/provider-pricing.js +58 -4
- package/dist/src/core/patterns/index.js +22 -0
- package/dist/src/core/patterns/pattern-applier.js +39 -0
- package/dist/src/core/patterns/pattern-observer.js +157 -0
- package/dist/src/core/patterns/pattern-store.js +259 -0
- package/dist/src/core/patterns/types.js +19 -0
- package/dist/src/core/retrieval/llm-context-retrieval.js +5 -4
- package/dist/src/core/retrieval/unified-context-assembler.js +11 -66
- package/dist/src/core/skill-packs/types.js +14 -1
- package/dist/src/core/storage/cloud-sync-manager.js +116 -0
- package/dist/src/core/storage/cloud-sync.js +574 -0
- package/dist/src/core/storage/two-tier-storage.js +5 -1
- package/dist/src/core/tasks/master-tasks-template.js +43 -0
- package/dist/src/core/tasks/md-task-parser.js +138 -0
- package/dist/src/core/vision/index.js +27 -0
- package/dist/src/core/vision/signals.js +79 -0
- package/dist/src/core/vision/types.js +22 -0
- package/dist/src/core/vision/vision-file.js +146 -0
- package/dist/src/core/vision/vision-loop.js +220 -0
- package/dist/src/core/wiki/wiki-compiler.js +103 -1
- package/dist/src/daemon/daemon-config.js +45 -0
- package/dist/src/daemon/services/desire-path-service.js +566 -0
- package/dist/src/daemon/services/research-stream-service.js +320 -0
- package/dist/src/daemon/services/telemetry-service.js +192 -0
- package/dist/src/daemon/unified-daemon.js +28 -1
- package/dist/src/features/browser/cli-browser-agent.js +417 -0
- package/dist/src/features/browser/stagehand-workflows.js +578 -0
- package/dist/src/features/operator/adapter-factory.js +62 -0
- package/dist/src/features/operator/browser-adapter.js +109 -0
- package/dist/src/features/operator/desktop-adapter.js +125 -0
- package/dist/src/features/operator/index.js +39 -0
- package/dist/src/features/operator/llm-decision.js +137 -0
- package/dist/src/features/operator/operator-logger.js +92 -0
- package/dist/src/features/operator/overnight-runner.js +327 -0
- package/dist/src/features/operator/screen-adapter.js +91 -0
- package/dist/src/features/operator/session-manager.js +127 -0
- package/dist/src/features/operator/state-machine.js +227 -0
- package/dist/src/features/operator/task-queue.js +81 -0
- package/dist/src/features/portal/index.js +26 -0
- package/dist/src/features/portal/server.js +240 -0
- package/dist/src/features/portal/types.js +14 -0
- package/dist/src/features/portal/ui.js +195 -0
- package/dist/src/features/tasks/task-aware-context.js +2 -1
- package/dist/src/features/tui/simple-monitor.js +0 -23
- package/dist/src/features/tui/swarm-monitor.js +8 -66
- package/dist/src/{integrations/diffmem/index.js → features/web/client/hooks/use-socket.js} +6 -5
- package/dist/src/features/web/client/lib/utils.js +12 -0
- package/dist/src/features/web/client/stores/session-store.js +12 -0
- package/dist/src/features/web/server/gcp-billing.js +76 -0
- package/dist/src/features/web/server/index.js +10 -0
- package/dist/src/features/web/server/spend-calculator.js +228 -0
- package/dist/src/hooks/schemas.js +4 -1
- package/dist/src/integrations/anthropic/client.js +3 -2
- package/dist/src/integrations/claude-code/agent-bridge.js +0 -3
- package/dist/src/integrations/claude-code/subagent-client.js +218 -11
- package/dist/src/integrations/claude-code/task-coordinator.js +2 -1
- package/dist/src/integrations/linear/webhook-retry.js +196 -0
- package/dist/src/integrations/linear/webhook-server.js +18 -22
- package/dist/src/integrations/mcp/handlers/cloud-sync-handlers.js +101 -0
- package/dist/src/integrations/mcp/handlers/index.js +27 -52
- package/dist/src/integrations/mcp/server.js +122 -335
- package/dist/src/integrations/mcp/tool-alias-registry.js +0 -73
- package/dist/src/integrations/mcp/tool-definitions.js +111 -510
- package/dist/src/mcp/stackmemory-mcp-server.js +404 -379
- package/dist/src/orchestrators/multimodal/determinism.js +2 -1
- package/dist/src/orchestrators/multimodal/harness.js +2 -1
- package/dist/src/skills/recursive-agent-orchestrator.js +2 -4
- package/dist/src/utils/process-cleanup.js +1 -7
- package/docs/README.md +42 -0
- package/docs/guides/README_INSTALL.md +208 -0
- package/package.json +18 -9
- package/scripts/claude-code-wrapper.sh +11 -0
- package/scripts/claude-sm-setup.sh +12 -1
- package/scripts/codex-wrapper.sh +11 -0
- package/scripts/git-hooks/branch-context-manager.sh +11 -0
- package/scripts/git-hooks/post-checkout-stackmemory.sh +11 -0
- package/scripts/git-hooks/post-commit-stackmemory.sh +11 -0
- package/scripts/git-hooks/pre-commit-stackmemory.sh +11 -0
- package/scripts/hooks/cleanup-shell.sh +12 -1
- package/scripts/hooks/task-complete.sh +12 -1
- package/scripts/install-code-execution-hooks.sh +12 -1
- package/scripts/install-sweep-hook.sh +12 -0
- package/scripts/install.sh +11 -0
- package/scripts/opencode-wrapper.sh +11 -0
- package/scripts/portal/cloud-init.yaml +69 -0
- package/scripts/portal/setup.sh +69 -0
- package/scripts/portal/stackmemory-portal.service +34 -0
- package/scripts/setup-claude-integration.sh +12 -1
- package/scripts/smoke-init-db.sh +23 -0
- package/scripts/stackmemory-daemon.sh +11 -0
- package/scripts/verify-dist.cjs +11 -4
- package/dist/src/cli/commands/ralph.js +0 -1053
- package/dist/src/hooks/diffmem-hooks.js +0 -376
- package/dist/src/integrations/diffmem/client.js +0 -208
- package/dist/src/integrations/diffmem/config.js +0 -14
- package/dist/src/integrations/greptile/client.js +0 -101
- package/dist/src/integrations/greptile/config.js +0 -14
- package/dist/src/integrations/greptile/index.js +0 -11
- package/dist/src/integrations/mcp/handlers/cross-search-handlers.js +0 -188
- package/dist/src/integrations/mcp/handlers/diffmem-handlers.js +0 -455
- package/dist/src/integrations/mcp/handlers/greptile-handlers.js +0 -456
- package/dist/src/integrations/mcp/handlers/provider-handlers.js +0 -227
- package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js +0 -863
- package/dist/src/integrations/ralph/context/context-budget-manager.js +0 -308
- package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +0 -354
- package/dist/src/integrations/ralph/index.js +0 -17
- package/dist/src/integrations/ralph/learning/pattern-learner.js +0 -416
- package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js +0 -448
- package/dist/src/integrations/ralph/loopmax.js +0 -488
- package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js +0 -293
- package/dist/src/integrations/ralph/monitoring/swarm-registry.js +0 -107
- package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +0 -508
- package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +0 -407
- package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +0 -495
- package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js +0 -387
- package/dist/src/integrations/ralph/performance/performance-optimizer.js +0 -357
- package/dist/src/integrations/ralph/recovery/crash-recovery.js +0 -461
- package/dist/src/integrations/ralph/state/state-reconciler.js +0 -420
- package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +0 -444
- package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +0 -1005
- package/dist/src/integrations/ralph/visualization/ralph-debugger.js +0 -635
- package/scripts/ralph-loop-implementation.js +0 -404
- /package/dist/src/{integrations/diffmem/types.js → core/storage/cloud-sync-types.js} +0 -0
- /package/dist/src/{integrations/greptile → features/operator}/types.js +0 -0
- /package/dist/src/{integrations/ralph/types.js → features/web/client/next-env.d.js} +0 -0
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
2
|
-
import { dirname as __pathDirname } from 'path';
|
|
3
|
-
const __filename = __fileURLToPath(import.meta.url);
|
|
4
|
-
const __dirname = __pathDirname(__filename);
|
|
5
|
-
import { logger } from "../../../core/monitoring/logger.js";
|
|
6
|
-
import * as zlib from "zlib";
|
|
7
|
-
import { promisify } from "util";
|
|
8
|
-
const gzip = promisify(zlib.gzip);
|
|
9
|
-
const gunzip = promisify(zlib.gunzip);
|
|
10
|
-
class PerformanceOptimizer {
|
|
11
|
-
config;
|
|
12
|
-
saveBatch = [];
|
|
13
|
-
batchTimer;
|
|
14
|
-
cache = /* @__PURE__ */ new Map();
|
|
15
|
-
metrics = {
|
|
16
|
-
iterationTime: 0,
|
|
17
|
-
contextLoadTime: 0,
|
|
18
|
-
stateSaveTime: 0,
|
|
19
|
-
memoryUsage: 0,
|
|
20
|
-
tokenCount: 0,
|
|
21
|
-
cacheHitRate: 0
|
|
22
|
-
};
|
|
23
|
-
cacheHits = 0;
|
|
24
|
-
cacheMisses = 0;
|
|
25
|
-
strategies = [];
|
|
26
|
-
constructor(config) {
|
|
27
|
-
this.config = {
|
|
28
|
-
asyncSaves: config?.asyncSaves ?? true,
|
|
29
|
-
batchSize: config?.batchSize || 10,
|
|
30
|
-
compressionLevel: config?.compressionLevel || 2,
|
|
31
|
-
cacheEnabled: config?.cacheEnabled ?? true,
|
|
32
|
-
parallelOperations: config?.parallelOperations ?? true
|
|
33
|
-
};
|
|
34
|
-
this.initializeStrategies();
|
|
35
|
-
this.startMetricsCollection();
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Save frame with optimizations
|
|
39
|
-
*/
|
|
40
|
-
async saveFrame(frame) {
|
|
41
|
-
const startTime = Date.now();
|
|
42
|
-
if (this.config.asyncSaves) {
|
|
43
|
-
this.addToBatch({
|
|
44
|
-
type: "frame",
|
|
45
|
-
data: frame,
|
|
46
|
-
timestamp: Date.now()
|
|
47
|
-
});
|
|
48
|
-
} else {
|
|
49
|
-
await this.saveFrameInternal(frame);
|
|
50
|
-
}
|
|
51
|
-
this.metrics.stateSaveTime += Date.now() - startTime;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Save iteration with optimizations
|
|
55
|
-
*/
|
|
56
|
-
async saveIteration(iteration) {
|
|
57
|
-
const startTime = Date.now();
|
|
58
|
-
const data = this.config.compressionLevel > 0 ? await this.compressData(iteration) : iteration;
|
|
59
|
-
if (this.config.asyncSaves) {
|
|
60
|
-
this.addToBatch({
|
|
61
|
-
type: "iteration",
|
|
62
|
-
data,
|
|
63
|
-
timestamp: Date.now()
|
|
64
|
-
});
|
|
65
|
-
} else {
|
|
66
|
-
await this.saveIterationInternal(data);
|
|
67
|
-
}
|
|
68
|
-
this.metrics.stateSaveTime += Date.now() - startTime;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Load frames with caching
|
|
72
|
-
*/
|
|
73
|
-
async loadFrames(query) {
|
|
74
|
-
const startTime = Date.now();
|
|
75
|
-
const cacheKey = this.generateCacheKey("frames", query);
|
|
76
|
-
if (this.config.cacheEnabled) {
|
|
77
|
-
const cached = this.getFromCache(cacheKey);
|
|
78
|
-
if (cached) {
|
|
79
|
-
this.cacheHits++;
|
|
80
|
-
this.metrics.contextLoadTime += Date.now() - startTime;
|
|
81
|
-
return cached;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
this.cacheMisses++;
|
|
85
|
-
const frames = await this.loadFramesInternal(query);
|
|
86
|
-
if (this.config.cacheEnabled) {
|
|
87
|
-
this.setCache(cacheKey, frames, 6e4);
|
|
88
|
-
}
|
|
89
|
-
this.metrics.contextLoadTime += Date.now() - startTime;
|
|
90
|
-
return frames;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Batch save operations
|
|
94
|
-
*/
|
|
95
|
-
async flushBatch() {
|
|
96
|
-
if (this.saveBatch.length === 0) return;
|
|
97
|
-
const batch = [...this.saveBatch];
|
|
98
|
-
this.saveBatch = [];
|
|
99
|
-
logger.debug("Flushing batch", { size: batch.length });
|
|
100
|
-
if (this.config.parallelOperations) {
|
|
101
|
-
await Promise.all(batch.map((op) => this.executeSaveOperation(op)));
|
|
102
|
-
} else {
|
|
103
|
-
for (const op of batch) {
|
|
104
|
-
await this.executeSaveOperation(op);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Compress data based on compression level
|
|
110
|
-
*/
|
|
111
|
-
async compressData(data) {
|
|
112
|
-
if (this.config.compressionLevel === 0) return data;
|
|
113
|
-
const json = JSON.stringify(data);
|
|
114
|
-
const compressionOptions = {
|
|
115
|
-
level: this.config.compressionLevel * 3
|
|
116
|
-
// Map 1-3 to zlib levels 3-9
|
|
117
|
-
};
|
|
118
|
-
const compressed = await gzip(json, compressionOptions);
|
|
119
|
-
return {
|
|
120
|
-
compressed: true,
|
|
121
|
-
data: compressed.toString("base64"),
|
|
122
|
-
originalSize: json.length,
|
|
123
|
-
compressedSize: compressed.length
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Decompress data
|
|
128
|
-
*/
|
|
129
|
-
async decompressData(compressed) {
|
|
130
|
-
if (!compressed.compressed) return compressed;
|
|
131
|
-
const buffer = Buffer.from(compressed.data, "base64");
|
|
132
|
-
const decompressed = await gunzip(buffer);
|
|
133
|
-
return JSON.parse(decompressed.toString());
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Apply optimization strategies
|
|
137
|
-
*/
|
|
138
|
-
async optimize(operation, data) {
|
|
139
|
-
let optimized = data;
|
|
140
|
-
for (const strategy of this.strategies) {
|
|
141
|
-
if (strategy.enabled) {
|
|
142
|
-
try {
|
|
143
|
-
optimized = await strategy.apply(optimized);
|
|
144
|
-
} catch (error) {
|
|
145
|
-
logger.error("Optimization strategy failed", {
|
|
146
|
-
strategy: strategy.name,
|
|
147
|
-
error: error.message
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return optimized;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Get performance metrics
|
|
156
|
-
*/
|
|
157
|
-
getMetrics() {
|
|
158
|
-
const totalCacheAttempts = this.cacheHits + this.cacheMisses;
|
|
159
|
-
this.metrics.cacheHitRate = totalCacheAttempts > 0 ? this.cacheHits / totalCacheAttempts : 0;
|
|
160
|
-
this.metrics.memoryUsage = process.memoryUsage().heapUsed;
|
|
161
|
-
return { ...this.metrics };
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Clear cache
|
|
165
|
-
*/
|
|
166
|
-
clearCache() {
|
|
167
|
-
const size = this.cache.size;
|
|
168
|
-
this.cache.clear();
|
|
169
|
-
logger.debug("Cache cleared", { entries: size });
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Enable/disable strategy
|
|
173
|
-
*/
|
|
174
|
-
setStrategyEnabled(strategyName, enabled) {
|
|
175
|
-
const strategy = this.strategies.find((s) => s.name === strategyName);
|
|
176
|
-
if (strategy) {
|
|
177
|
-
strategy.enabled = enabled;
|
|
178
|
-
logger.debug("Strategy updated", { name: strategyName, enabled });
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Cleanup resources
|
|
183
|
-
*/
|
|
184
|
-
cleanup() {
|
|
185
|
-
if (this.batchTimer) {
|
|
186
|
-
clearTimeout(this.batchTimer);
|
|
187
|
-
}
|
|
188
|
-
this.clearCache();
|
|
189
|
-
this.saveBatch = [];
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Initialize optimization strategies
|
|
193
|
-
*/
|
|
194
|
-
initializeStrategies() {
|
|
195
|
-
this.strategies = [
|
|
196
|
-
{
|
|
197
|
-
name: "deduplication",
|
|
198
|
-
enabled: true,
|
|
199
|
-
priority: 1,
|
|
200
|
-
apply: async (data) => this.deduplicateData(data),
|
|
201
|
-
metrics: () => this.getMetrics()
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
name: "chunking",
|
|
205
|
-
enabled: true,
|
|
206
|
-
priority: 2,
|
|
207
|
-
apply: async (data) => this.chunkLargeData(data),
|
|
208
|
-
metrics: () => this.getMetrics()
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
name: "lazy-loading",
|
|
212
|
-
enabled: this.config.cacheEnabled,
|
|
213
|
-
priority: 3,
|
|
214
|
-
apply: async (data) => this.createLazyProxy(data),
|
|
215
|
-
metrics: () => this.getMetrics()
|
|
216
|
-
}
|
|
217
|
-
];
|
|
218
|
-
this.strategies.sort((a, b) => a.priority - b.priority);
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Start metrics collection
|
|
222
|
-
*/
|
|
223
|
-
startMetricsCollection() {
|
|
224
|
-
setInterval(() => {
|
|
225
|
-
const metrics = this.getMetrics();
|
|
226
|
-
logger.debug("Performance metrics", metrics);
|
|
227
|
-
}, 3e4);
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Add operation to batch
|
|
231
|
-
*/
|
|
232
|
-
addToBatch(operation) {
|
|
233
|
-
this.saveBatch.push(operation);
|
|
234
|
-
if (!this.batchTimer) {
|
|
235
|
-
this.batchTimer = setTimeout(() => {
|
|
236
|
-
this.flushBatch().catch((error) => {
|
|
237
|
-
logger.error("Batch flush failed", { error: error.message });
|
|
238
|
-
});
|
|
239
|
-
this.batchTimer = void 0;
|
|
240
|
-
}, 1e3);
|
|
241
|
-
}
|
|
242
|
-
if (this.saveBatch.length >= this.config.batchSize) {
|
|
243
|
-
if (this.batchTimer) {
|
|
244
|
-
clearTimeout(this.batchTimer);
|
|
245
|
-
this.batchTimer = void 0;
|
|
246
|
-
}
|
|
247
|
-
this.flushBatch().catch((error) => {
|
|
248
|
-
logger.error("Batch flush failed", { error: error.message });
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Execute save operation
|
|
254
|
-
*/
|
|
255
|
-
async executeSaveOperation(operation) {
|
|
256
|
-
switch (operation.type) {
|
|
257
|
-
case "frame":
|
|
258
|
-
await this.saveFrameInternal(operation.data);
|
|
259
|
-
break;
|
|
260
|
-
case "iteration":
|
|
261
|
-
await this.saveIterationInternal(operation.data);
|
|
262
|
-
break;
|
|
263
|
-
default:
|
|
264
|
-
logger.warn("Unknown operation type", { type: operation.type });
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Internal frame save
|
|
269
|
-
*/
|
|
270
|
-
async saveFrameInternal(frame) {
|
|
271
|
-
logger.debug("Frame saved", { frameId: frame.frame_id });
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Internal iteration save
|
|
275
|
-
*/
|
|
276
|
-
async saveIterationInternal(iteration) {
|
|
277
|
-
logger.debug("Iteration saved", { iteration: iteration.number });
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Internal frame load
|
|
281
|
-
*/
|
|
282
|
-
async loadFramesInternal(_query) {
|
|
283
|
-
return [];
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Generate cache key
|
|
287
|
-
*/
|
|
288
|
-
generateCacheKey(type, params) {
|
|
289
|
-
return `${type}:${JSON.stringify(params)}`;
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Get from cache
|
|
293
|
-
*/
|
|
294
|
-
getFromCache(key) {
|
|
295
|
-
const entry = this.cache.get(key);
|
|
296
|
-
if (!entry) return void 0;
|
|
297
|
-
if (entry.expiry && entry.expiry < Date.now()) {
|
|
298
|
-
this.cache.delete(key);
|
|
299
|
-
return void 0;
|
|
300
|
-
}
|
|
301
|
-
return entry.data;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Set cache entry
|
|
305
|
-
*/
|
|
306
|
-
setCache(key, data, ttl) {
|
|
307
|
-
const entry = {
|
|
308
|
-
data,
|
|
309
|
-
timestamp: Date.now(),
|
|
310
|
-
expiry: ttl ? Date.now() + ttl : void 0
|
|
311
|
-
};
|
|
312
|
-
this.cache.set(key, entry);
|
|
313
|
-
if (this.cache.size > 100) {
|
|
314
|
-
const entries = Array.from(this.cache.entries());
|
|
315
|
-
entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
|
|
316
|
-
for (let i = 0; i < 20; i++) {
|
|
317
|
-
this.cache.delete(entries[i][0]);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Deduplicate data
|
|
323
|
-
*/
|
|
324
|
-
deduplicateData(data) {
|
|
325
|
-
if (Array.isArray(data)) {
|
|
326
|
-
const seen = /* @__PURE__ */ new Set();
|
|
327
|
-
return data.filter((item) => {
|
|
328
|
-
const key = JSON.stringify(item);
|
|
329
|
-
if (seen.has(key)) {
|
|
330
|
-
return false;
|
|
331
|
-
}
|
|
332
|
-
seen.add(key);
|
|
333
|
-
return true;
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
return data;
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Chunk large data
|
|
340
|
-
*/
|
|
341
|
-
chunkLargeData(data) {
|
|
342
|
-
const json = JSON.stringify(data);
|
|
343
|
-
if (json.length > 1e5) {
|
|
344
|
-
logger.debug("Large data detected", { size: json.length });
|
|
345
|
-
}
|
|
346
|
-
return data;
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Create lazy-loading proxy
|
|
350
|
-
*/
|
|
351
|
-
createLazyProxy(data) {
|
|
352
|
-
return data;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
export {
|
|
356
|
-
PerformanceOptimizer
|
|
357
|
-
};
|