@affectively/aeon 1.0.0 → 1.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.
Files changed (62) hide show
  1. package/README.md +10 -0
  2. package/dist/compression/index.cjs +580 -0
  3. package/dist/compression/index.cjs.map +1 -0
  4. package/dist/compression/index.d.cts +189 -0
  5. package/dist/compression/index.d.ts +189 -0
  6. package/dist/compression/index.js +573 -0
  7. package/dist/compression/index.js.map +1 -0
  8. package/dist/core/index.d.cts +70 -5
  9. package/dist/core/index.d.ts +70 -5
  10. package/dist/crypto/index.cjs +100 -0
  11. package/dist/crypto/index.cjs.map +1 -0
  12. package/dist/crypto/index.d.cts +407 -0
  13. package/dist/crypto/index.d.ts +407 -0
  14. package/dist/crypto/index.js +96 -0
  15. package/dist/crypto/index.js.map +1 -0
  16. package/dist/distributed/index.cjs +420 -23
  17. package/dist/distributed/index.cjs.map +1 -1
  18. package/dist/distributed/index.d.cts +901 -2
  19. package/dist/distributed/index.d.ts +901 -2
  20. package/dist/distributed/index.js +420 -23
  21. package/dist/distributed/index.js.map +1 -1
  22. package/dist/index.cjs +1222 -55
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +11 -811
  25. package/dist/index.d.ts +11 -811
  26. package/dist/index.js +1221 -56
  27. package/dist/index.js.map +1 -1
  28. package/dist/offline/index.cjs +419 -0
  29. package/dist/offline/index.cjs.map +1 -0
  30. package/dist/offline/index.d.cts +148 -0
  31. package/dist/offline/index.d.ts +148 -0
  32. package/dist/offline/index.js +415 -0
  33. package/dist/offline/index.js.map +1 -0
  34. package/dist/optimization/index.cjs +797 -0
  35. package/dist/optimization/index.cjs.map +1 -0
  36. package/dist/optimization/index.d.cts +347 -0
  37. package/dist/optimization/index.d.ts +347 -0
  38. package/dist/optimization/index.js +787 -0
  39. package/dist/optimization/index.js.map +1 -0
  40. package/dist/persistence/index.cjs +145 -0
  41. package/dist/persistence/index.cjs.map +1 -0
  42. package/dist/persistence/index.d.cts +63 -0
  43. package/dist/persistence/index.d.ts +63 -0
  44. package/dist/persistence/index.js +142 -0
  45. package/dist/persistence/index.js.map +1 -0
  46. package/dist/presence/index.cjs +489 -0
  47. package/dist/presence/index.cjs.map +1 -0
  48. package/dist/presence/index.d.cts +283 -0
  49. package/dist/presence/index.d.ts +283 -0
  50. package/dist/presence/index.js +485 -0
  51. package/dist/presence/index.js.map +1 -0
  52. package/dist/types-CMxO7QF0.d.cts +33 -0
  53. package/dist/types-CMxO7QF0.d.ts +33 -0
  54. package/dist/versioning/index.cjs +296 -14
  55. package/dist/versioning/index.cjs.map +1 -1
  56. package/dist/versioning/index.d.cts +66 -1
  57. package/dist/versioning/index.d.ts +66 -1
  58. package/dist/versioning/index.js +296 -14
  59. package/dist/versioning/index.js.map +1 -1
  60. package/package.json +51 -1
  61. package/dist/index-C_4CMV5c.d.cts +0 -1207
  62. package/dist/index-C_4CMV5c.d.ts +0 -1207
@@ -0,0 +1,787 @@
1
+ // src/utils/logger.ts
2
+ var consoleLogger = {
3
+ debug: (...args) => {
4
+ console.debug("[AEON:DEBUG]", ...args);
5
+ },
6
+ info: (...args) => {
7
+ console.info("[AEON:INFO]", ...args);
8
+ },
9
+ warn: (...args) => {
10
+ console.warn("[AEON:WARN]", ...args);
11
+ },
12
+ error: (...args) => {
13
+ console.error("[AEON:ERROR]", ...args);
14
+ }
15
+ };
16
+ var currentLogger = consoleLogger;
17
+ function getLogger() {
18
+ return currentLogger;
19
+ }
20
+
21
+ // src/optimization/PrefetchingEngine.ts
22
+ var logger = getLogger();
23
+ var PrefetchingEngine = class {
24
+ operationHistory = [];
25
+ patterns = /* @__PURE__ */ new Map();
26
+ prefetchCache = /* @__PURE__ */ new Map();
27
+ maxHistoryEntries = 1e3;
28
+ maxCachePerType = 5;
29
+ prefetchTTL = 5 * 60 * 1e3;
30
+ // 5 minutes
31
+ predictionThreshold = 0.3;
32
+ stats = {
33
+ totalPrefetched: 0,
34
+ totalHits: 0,
35
+ totalMisses: 0,
36
+ totalOverwrites: 0,
37
+ hitRatio: 0,
38
+ bandwidthSaved: 0,
39
+ patternsDetected: 0,
40
+ predictionAccuracy: 0
41
+ };
42
+ lastPredictionTime = 0;
43
+ predictionInterval = 30 * 1e3;
44
+ constructor() {
45
+ logger.debug("[PrefetchingEngine] Initialized", {
46
+ ttl: this.prefetchTTL,
47
+ threshold: this.predictionThreshold
48
+ });
49
+ }
50
+ /**
51
+ * Record operation for pattern analysis
52
+ */
53
+ recordOperation(operationType, size) {
54
+ const now = Date.now();
55
+ this.operationHistory.push({
56
+ type: operationType,
57
+ timestamp: now,
58
+ size
59
+ });
60
+ if (this.operationHistory.length > this.maxHistoryEntries) {
61
+ this.operationHistory.shift();
62
+ }
63
+ if (Math.random() < 0.1) {
64
+ this.cleanExpiredPrefetches();
65
+ }
66
+ logger.debug("[PrefetchingEngine] Operation recorded", {
67
+ type: operationType,
68
+ size,
69
+ historySize: this.operationHistory.length
70
+ });
71
+ }
72
+ /**
73
+ * Analyze patterns in operation history
74
+ */
75
+ analyzePatterns() {
76
+ if (this.operationHistory.length < 5) {
77
+ return;
78
+ }
79
+ const patterns = /* @__PURE__ */ new Map();
80
+ for (let length = 2; length <= 3; length++) {
81
+ for (let i = 0; i < this.operationHistory.length - length; i++) {
82
+ const sequence = this.operationHistory.slice(i, i + length).map((op) => op.type);
83
+ const key = sequence.join(" \u2192 ");
84
+ if (!patterns.has(key)) {
85
+ patterns.set(key, {
86
+ sequence,
87
+ frequency: 0,
88
+ probability: 0,
89
+ lastOccurred: 0,
90
+ avgIntervalMs: 0
91
+ });
92
+ }
93
+ const pattern = patterns.get(key);
94
+ pattern.frequency++;
95
+ pattern.lastOccurred = Date.now();
96
+ }
97
+ }
98
+ const totalSequences = this.operationHistory.length;
99
+ for (const [key, pattern] of patterns.entries()) {
100
+ pattern.probability = Math.min(1, pattern.frequency / totalSequences);
101
+ }
102
+ this.patterns = patterns;
103
+ this.stats.patternsDetected = patterns.size;
104
+ logger.debug("[PrefetchingEngine] Patterns analyzed", {
105
+ patternsFound: patterns.size
106
+ });
107
+ }
108
+ /**
109
+ * Predict next operations
110
+ */
111
+ predictNextOperations(recentOperations) {
112
+ const now = Date.now();
113
+ if (now - this.lastPredictionTime > this.predictionInterval) {
114
+ this.analyzePatterns();
115
+ this.lastPredictionTime = now;
116
+ }
117
+ if (this.patterns.size === 0) {
118
+ return [];
119
+ }
120
+ const predictions = [];
121
+ const recentTypeSequence = recentOperations.slice(-3).map((op) => op.type).join(" \u2192 ");
122
+ for (const [key, pattern] of this.patterns.entries()) {
123
+ if (key.includes(recentTypeSequence)) {
124
+ const nextType = pattern.sequence[pattern.sequence.length - 1];
125
+ const prediction = {
126
+ operationType: nextType,
127
+ probability: pattern.probability,
128
+ reason: `Detected pattern: ${key}`,
129
+ shouldPrefetch: pattern.probability > this.predictionThreshold,
130
+ estimatedTimeMs: pattern.avgIntervalMs
131
+ };
132
+ predictions.push(prediction);
133
+ }
134
+ }
135
+ const deduped = Array.from(
136
+ new Map(predictions.map((p) => [p.operationType, p])).values()
137
+ ).sort((a, b) => b.probability - a.probability);
138
+ logger.debug("[PrefetchingEngine] Predictions", {
139
+ predictions: deduped.slice(0, 3).map((p) => ({
140
+ type: p.operationType,
141
+ probability: (p.probability * 100).toFixed(1) + "%"
142
+ }))
143
+ });
144
+ return deduped;
145
+ }
146
+ /**
147
+ * Add prefetched batch
148
+ */
149
+ addPrefetchedBatch(operationType, compressed, originalSize) {
150
+ if (!this.prefetchCache.has(operationType)) {
151
+ this.prefetchCache.set(operationType, []);
152
+ }
153
+ const cache = this.prefetchCache.get(operationType);
154
+ if (cache.length >= this.maxCachePerType) {
155
+ const oldest = cache.shift();
156
+ if (oldest.hitCount === 0) {
157
+ this.stats.totalMisses++;
158
+ } else {
159
+ this.stats.totalOverwrites++;
160
+ }
161
+ }
162
+ const batch = {
163
+ id: `prefetch-${operationType}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
164
+ operationType,
165
+ compressed,
166
+ compressedSize: compressed.length,
167
+ originalSize,
168
+ compressionRatio: 1 - compressed.length / originalSize,
169
+ compressed_at: Date.now(),
170
+ created_at: Date.now(),
171
+ ttl: this.prefetchTTL,
172
+ expiresAt: Date.now() + this.prefetchTTL,
173
+ hitCount: 0,
174
+ missCount: 0
175
+ };
176
+ cache.push(batch);
177
+ this.stats.totalPrefetched++;
178
+ this.stats.bandwidthSaved += originalSize - compressed.length;
179
+ logger.debug("[PrefetchingEngine] Prefetched batch added", {
180
+ type: operationType,
181
+ id: batch.id,
182
+ ratio: (batch.compressionRatio * 100).toFixed(1) + "%"
183
+ });
184
+ return batch;
185
+ }
186
+ /**
187
+ * Try to use prefetched batch
188
+ */
189
+ getPrefetchedBatch(operationType) {
190
+ const cache = this.prefetchCache.get(operationType);
191
+ if (!cache || cache.length === 0) {
192
+ return null;
193
+ }
194
+ const now = Date.now();
195
+ for (let i = 0; i < cache.length; i++) {
196
+ const batch = cache[i];
197
+ if (batch.expiresAt > now) {
198
+ batch.hitCount++;
199
+ this.stats.totalHits++;
200
+ this.updatePredictionAccuracy(true);
201
+ logger.debug("[PrefetchingEngine] Prefetch hit", {
202
+ type: operationType,
203
+ id: batch.id
204
+ });
205
+ return batch;
206
+ } else {
207
+ cache.splice(i, 1);
208
+ i--;
209
+ batch.missCount++;
210
+ this.stats.totalMisses++;
211
+ this.updatePredictionAccuracy(false);
212
+ }
213
+ }
214
+ return null;
215
+ }
216
+ /**
217
+ * Update prediction accuracy metric
218
+ */
219
+ updatePredictionAccuracy(hit) {
220
+ const total = this.stats.totalHits + this.stats.totalMisses;
221
+ if (total === 0) return;
222
+ this.stats.predictionAccuracy = this.stats.totalHits / total;
223
+ }
224
+ /**
225
+ * Clean expired prefetches
226
+ */
227
+ cleanExpiredPrefetches() {
228
+ const now = Date.now();
229
+ let cleanedCount = 0;
230
+ for (const [type, cache] of this.prefetchCache.entries()) {
231
+ for (let i = cache.length - 1; i >= 0; i--) {
232
+ if (cache[i].expiresAt < now) {
233
+ const batch = cache.splice(i, 1)[0];
234
+ if (batch.hitCount === 0) {
235
+ this.stats.totalMisses++;
236
+ }
237
+ cleanedCount++;
238
+ }
239
+ }
240
+ if (cache.length === 0) {
241
+ this.prefetchCache.delete(type);
242
+ }
243
+ }
244
+ if (cleanedCount > 0) {
245
+ logger.debug("[PrefetchingEngine] Cleaned expired prefetches", {
246
+ count: cleanedCount
247
+ });
248
+ }
249
+ }
250
+ /**
251
+ * Get statistics
252
+ */
253
+ getStats() {
254
+ const total = this.stats.totalHits + this.stats.totalMisses;
255
+ this.stats.hitRatio = total > 0 ? this.stats.totalHits / total : 0;
256
+ return { ...this.stats };
257
+ }
258
+ /**
259
+ * Clear all caches
260
+ */
261
+ clear() {
262
+ this.operationHistory = [];
263
+ this.patterns.clear();
264
+ this.prefetchCache.clear();
265
+ this.stats = {
266
+ totalPrefetched: 0,
267
+ totalHits: 0,
268
+ totalMisses: 0,
269
+ totalOverwrites: 0,
270
+ hitRatio: 0,
271
+ bandwidthSaved: 0,
272
+ patternsDetected: 0,
273
+ predictionAccuracy: 0
274
+ };
275
+ logger.debug("[PrefetchingEngine] Cleared all caches");
276
+ }
277
+ };
278
+ var prefetchingEngineInstance = null;
279
+ function getPrefetchingEngine() {
280
+ if (!prefetchingEngineInstance) {
281
+ prefetchingEngineInstance = new PrefetchingEngine();
282
+ }
283
+ return prefetchingEngineInstance;
284
+ }
285
+ function resetPrefetchingEngine() {
286
+ prefetchingEngineInstance = null;
287
+ }
288
+
289
+ // src/optimization/BatchTimingOptimizer.ts
290
+ var logger2 = getLogger();
291
+ var BatchTimingOptimizer = class {
292
+ networkHistory = [];
293
+ activityHistory = [];
294
+ stats = {
295
+ totalBatches: 0,
296
+ immediateDeliveries: 0,
297
+ deferredBatches: 0,
298
+ averageWaitTimeMs: 0,
299
+ averageDeliveryTimeMs: 0,
300
+ networkWindowsUsed: 0,
301
+ congestionAvoided: 0,
302
+ userFocusedOptimizations: 0
303
+ };
304
+ lastActivityTime = Date.now();
305
+ isUserActive = true;
306
+ congestionDetectionWindow = 60 * 1e3;
307
+ optimalBatchSize = 50 * 1024;
308
+ constructor() {
309
+ logger2.debug("[BatchTimingOptimizer] Initialized", {
310
+ congestionWindow: this.congestionDetectionWindow,
311
+ optimalBatchSize: this.optimalBatchSize
312
+ });
313
+ }
314
+ /**
315
+ * Record network measurement
316
+ */
317
+ recordNetworkMeasurement(latencyMs, bandwidthMbps) {
318
+ const quality = this.assessNetworkQuality(latencyMs, bandwidthMbps);
319
+ this.networkHistory.push({
320
+ latencyMs,
321
+ bandwidthMbps,
322
+ timestamp: Date.now(),
323
+ quality
324
+ });
325
+ if (this.networkHistory.length > 100) {
326
+ this.networkHistory.shift();
327
+ }
328
+ this.stats.networkWindowsUsed++;
329
+ logger2.debug("[BatchTimingOptimizer] Network measured", {
330
+ latency: latencyMs + "ms",
331
+ bandwidth: bandwidthMbps.toFixed(1) + " Mbps",
332
+ quality
333
+ });
334
+ }
335
+ /**
336
+ * Assess network quality
337
+ */
338
+ assessNetworkQuality(latencyMs, bandwidthMbps) {
339
+ if (latencyMs < 20 && bandwidthMbps > 10) return "excellent";
340
+ if (latencyMs < 50 && bandwidthMbps > 5) return "good";
341
+ if (latencyMs < 100 && bandwidthMbps > 2) return "fair";
342
+ return "poor";
343
+ }
344
+ /**
345
+ * Detect congestion in network
346
+ */
347
+ detectCongestion() {
348
+ const recentMeasurements = this.networkHistory.filter(
349
+ (m) => Date.now() - m.timestamp < this.congestionDetectionWindow
350
+ );
351
+ if (recentMeasurements.length < 3) {
352
+ return 0;
353
+ }
354
+ const poorCount = recentMeasurements.filter(
355
+ (m) => m.quality === "poor"
356
+ ).length;
357
+ return poorCount / recentMeasurements.length;
358
+ }
359
+ /**
360
+ * Find next optimal network window
361
+ */
362
+ findOptimalWindow() {
363
+ const now = Date.now();
364
+ const recentMeasurements = this.networkHistory.slice(-20);
365
+ if (recentMeasurements.length === 0) {
366
+ return {
367
+ startTime: now,
368
+ endTime: now + 1e3,
369
+ expectedDurationMs: 1e3,
370
+ latencyMs: 50,
371
+ bandwidthMbps: 5,
372
+ quality: "good",
373
+ isStable: true,
374
+ congestionLevel: 0,
375
+ recommendedBatchSize: this.optimalBatchSize
376
+ };
377
+ }
378
+ const avgLatency = recentMeasurements.reduce((sum, m) => sum + m.latencyMs, 0) / recentMeasurements.length;
379
+ const avgBandwidth = recentMeasurements.reduce((sum, m) => sum + m.bandwidthMbps, 0) / recentMeasurements.length;
380
+ const latencyVariance = Math.sqrt(
381
+ recentMeasurements.reduce(
382
+ (sum, m) => sum + Math.pow(m.latencyMs - avgLatency, 2),
383
+ 0
384
+ ) / recentMeasurements.length
385
+ ) / avgLatency;
386
+ const isStable = latencyVariance < 0.2;
387
+ const congestionLevel = this.detectCongestion();
388
+ const quality = this.assessNetworkQuality(avgLatency, avgBandwidth);
389
+ const recommendedBatchSize = Math.max(
390
+ 10 * 1024,
391
+ Math.min(500 * 1024, avgBandwidth * 1024 * 100 / 8)
392
+ );
393
+ return {
394
+ startTime: now,
395
+ endTime: now + (isStable ? 30 * 1e3 : 10 * 1e3),
396
+ expectedDurationMs: isStable ? 30 * 1e3 : 10 * 1e3,
397
+ latencyMs: avgLatency,
398
+ bandwidthMbps: avgBandwidth,
399
+ quality,
400
+ isStable,
401
+ congestionLevel,
402
+ recommendedBatchSize
403
+ };
404
+ }
405
+ /**
406
+ * Get scheduling decision for a batch
407
+ */
408
+ getSchedulingDecision(batchSize, batchPriority = "normal", isUserTriggered = false) {
409
+ const now = Date.now();
410
+ const currentWindow = this.findOptimalWindow();
411
+ const congestionLevel = this.detectCongestion();
412
+ let shouldSendNow = false;
413
+ let recommendedDelay = 0;
414
+ let reason = "";
415
+ let priority = batchPriority;
416
+ if (priority === "critical") {
417
+ shouldSendNow = true;
418
+ reason = "Critical operation (bypass optimization)";
419
+ } else if (isUserTriggered && this.isUserActive) {
420
+ shouldSendNow = true;
421
+ reason = "User-triggered operation";
422
+ priority = "high";
423
+ } else if (currentWindow.quality === "excellent" || currentWindow.quality === "good") {
424
+ if (congestionLevel < 0.3) {
425
+ shouldSendNow = true;
426
+ reason = "Good network conditions";
427
+ } else {
428
+ shouldSendNow = true;
429
+ reason = "Good network despite some congestion";
430
+ recommendedDelay = 1e3 + Math.random() * 2e3;
431
+ }
432
+ } else if (currentWindow.quality === "fair") {
433
+ if (priority === "high") {
434
+ shouldSendNow = true;
435
+ reason = "High priority despite fair network";
436
+ } else {
437
+ shouldSendNow = false;
438
+ reason = "Fair network: waiting for better window";
439
+ recommendedDelay = 30 * 1e3 + Math.random() * 30 * 1e3;
440
+ }
441
+ } else {
442
+ shouldSendNow = false;
443
+ reason = "Poor network conditions: deferring";
444
+ if (priority === "high") {
445
+ recommendedDelay = 60 * 1e3 + Math.random() * 30 * 1e3;
446
+ } else {
447
+ recommendedDelay = 120 * 1e3 + Math.random() * 60 * 1e3;
448
+ }
449
+ }
450
+ const estimatedDeliveryMs = batchSize / (currentWindow.bandwidthMbps * 1024 * 1024 / 8) * 1e3 + currentWindow.latencyMs + recommendedDelay;
451
+ const decision = {
452
+ shouldSendNow,
453
+ nextOptimalWindowMs: now + recommendedDelay,
454
+ recommendedDelay,
455
+ reason,
456
+ priority,
457
+ estimatedDeliveryMs
458
+ };
459
+ logger2.debug("[BatchTimingOptimizer] Scheduling decision", {
460
+ size: (batchSize / 1024).toFixed(1) + " KB",
461
+ shouldSendNow,
462
+ delay: recommendedDelay + "ms",
463
+ reason
464
+ });
465
+ return decision;
466
+ }
467
+ /**
468
+ * Apply scheduling and update stats
469
+ */
470
+ applyScheduling(batchSize, sendNow, actualDelay) {
471
+ this.stats.totalBatches++;
472
+ if (sendNow) {
473
+ this.stats.immediateDeliveries++;
474
+ } else {
475
+ this.stats.deferredBatches++;
476
+ }
477
+ const totalWait = this.stats.averageWaitTimeMs * (this.stats.totalBatches - 1) + actualDelay;
478
+ this.stats.averageWaitTimeMs = totalWait / this.stats.totalBatches;
479
+ if (this.detectCongestion() > 0.3 && !sendNow) {
480
+ this.stats.congestionAvoided++;
481
+ }
482
+ if (this.isUserActive) {
483
+ this.stats.userFocusedOptimizations++;
484
+ }
485
+ this.stats.networkWindowsUsed++;
486
+ }
487
+ /**
488
+ * Get optimal batch size recommendation
489
+ */
490
+ getOptimalBatchSize() {
491
+ const window = this.findOptimalWindow();
492
+ return window.recommendedBatchSize;
493
+ }
494
+ /**
495
+ * Get current network window
496
+ */
497
+ getCurrentNetworkWindow() {
498
+ return this.findOptimalWindow();
499
+ }
500
+ /**
501
+ * Set user activity state
502
+ */
503
+ setUserActive(active) {
504
+ this.isUserActive = active;
505
+ if (active) {
506
+ this.lastActivityTime = Date.now();
507
+ }
508
+ }
509
+ /**
510
+ * Get statistics
511
+ */
512
+ getStats() {
513
+ return { ...this.stats };
514
+ }
515
+ /**
516
+ * Clear history
517
+ */
518
+ clear() {
519
+ this.networkHistory = [];
520
+ this.activityHistory = [];
521
+ this.stats = {
522
+ totalBatches: 0,
523
+ immediateDeliveries: 0,
524
+ deferredBatches: 0,
525
+ averageWaitTimeMs: 0,
526
+ averageDeliveryTimeMs: 0,
527
+ networkWindowsUsed: 0,
528
+ congestionAvoided: 0,
529
+ userFocusedOptimizations: 0
530
+ };
531
+ }
532
+ };
533
+ var batchTimingOptimizerInstance = null;
534
+ function getBatchTimingOptimizer() {
535
+ if (!batchTimingOptimizerInstance) {
536
+ batchTimingOptimizerInstance = new BatchTimingOptimizer();
537
+ }
538
+ return batchTimingOptimizerInstance;
539
+ }
540
+ function resetBatchTimingOptimizer() {
541
+ batchTimingOptimizerInstance = null;
542
+ }
543
+
544
+ // src/optimization/AdaptiveCompressionOptimizer.ts
545
+ var logger3 = getLogger();
546
+ var AdaptiveCompressionOptimizer = class {
547
+ currentLevel = 6;
548
+ networkProfile = {
549
+ estimatedSpeedKbps: 5e3,
550
+ latencyMs: 50,
551
+ isOnline: true,
552
+ isWifi: false,
553
+ isFast: true,
554
+ isSlow: false,
555
+ isEmpty: false
556
+ };
557
+ deviceProfile = {
558
+ cpuCores: 4,
559
+ cpuUtilization: 0.3,
560
+ memoryAvailableMB: 512,
561
+ memoryTotalMB: 1024,
562
+ isConstrained: false,
563
+ isPremium: false,
564
+ supportsWebWorkers: true,
565
+ supportsWebAssembly: true
566
+ };
567
+ compressionHistory = [];
568
+ stats = {
569
+ currentLevel: 6,
570
+ averageCompressionMs: 10,
571
+ averageRatio: 0.85,
572
+ levelsUsed: /* @__PURE__ */ new Set([6]),
573
+ adjustmentCount: 0,
574
+ totalBatches: 0,
575
+ networkCondition: "normal"
576
+ };
577
+ constructor() {
578
+ logger3.debug("[AdaptiveCompressionOptimizer] Initialized", {
579
+ level: this.currentLevel
580
+ });
581
+ }
582
+ /**
583
+ * Update network conditions
584
+ */
585
+ updateNetworkConditions(speedKbps, latencyMs, isOnline) {
586
+ this.networkProfile.estimatedSpeedKbps = speedKbps;
587
+ if (latencyMs !== void 0) {
588
+ this.networkProfile.latencyMs = latencyMs;
589
+ }
590
+ if (isOnline !== void 0) {
591
+ this.networkProfile.isOnline = isOnline;
592
+ }
593
+ this.networkProfile.isFast = speedKbps > 5e3;
594
+ this.networkProfile.isSlow = speedKbps < 1e3;
595
+ this.networkProfile.isEmpty = speedKbps < 100;
596
+ if (isOnline === false) {
597
+ this.stats.networkCondition = "offline";
598
+ } else if (this.networkProfile.isSlow) {
599
+ this.stats.networkCondition = "slow";
600
+ } else if (this.networkProfile.isFast) {
601
+ this.stats.networkCondition = "fast";
602
+ } else {
603
+ this.stats.networkCondition = "normal";
604
+ }
605
+ logger3.debug("[AdaptiveCompressionOptimizer] Network updated", {
606
+ speedKbps,
607
+ condition: this.stats.networkCondition
608
+ });
609
+ }
610
+ /**
611
+ * Update device resource usage
612
+ */
613
+ updateDeviceResources(cpuUtilization, memoryAvailableMB) {
614
+ this.deviceProfile.cpuUtilization = Math.max(
615
+ 0,
616
+ Math.min(1, cpuUtilization)
617
+ );
618
+ this.deviceProfile.memoryAvailableMB = memoryAvailableMB;
619
+ this.deviceProfile.isConstrained = memoryAvailableMB < 512;
620
+ this.deviceProfile.isPremium = memoryAvailableMB > 2048;
621
+ logger3.debug("[AdaptiveCompressionOptimizer] Device resources updated", {
622
+ cpuUtilization: (cpuUtilization * 100).toFixed(1) + "%",
623
+ memoryAvailableMB
624
+ });
625
+ }
626
+ /**
627
+ * Record compression performance
628
+ */
629
+ recordCompressionPerformance(level, compressionMs, ratio) {
630
+ this.compressionHistory.push({
631
+ level,
632
+ ratio,
633
+ timeMs: compressionMs,
634
+ timestamp: Date.now()
635
+ });
636
+ if (this.compressionHistory.length > 100) {
637
+ this.compressionHistory.shift();
638
+ }
639
+ this.stats.totalBatches++;
640
+ this.stats.averageCompressionMs = this.compressionHistory.reduce((sum, h) => sum + h.timeMs, 0) / this.compressionHistory.length;
641
+ this.stats.averageRatio = this.compressionHistory.reduce((sum, h) => sum + h.ratio, 0) / this.compressionHistory.length;
642
+ }
643
+ /**
644
+ * Get compression recommendation based on conditions
645
+ */
646
+ getRecommendedLevel() {
647
+ const networkFactor = this.calculateNetworkFactor();
648
+ const deviceFactor = this.calculateDeviceFactor();
649
+ const combinedFactor = (networkFactor + deviceFactor) / 2;
650
+ const recommendedLevel = Math.max(
651
+ 1,
652
+ Math.min(9, Math.round(combinedFactor * 9))
653
+ );
654
+ const estimatedCompressionMs = this.estimateCompressionTime(recommendedLevel);
655
+ const estimatedRatio = this.estimateCompressionRatio(recommendedLevel);
656
+ let reason = "";
657
+ if (networkFactor < 0.3 && deviceFactor < 0.3) {
658
+ reason = "Slow network + constrained device: using level 1-2 (fast)";
659
+ } else if (networkFactor > 0.7 && deviceFactor > 0.7) {
660
+ reason = "Fast network + premium device: using level 8-9 (best compression)";
661
+ } else if (networkFactor > 0.7) {
662
+ reason = "Fast network: prioritizing compression ratio";
663
+ } else if (deviceFactor < 0.3) {
664
+ reason = "Constrained device: prioritizing speed";
665
+ } else {
666
+ reason = "Normal conditions: balanced compression level";
667
+ }
668
+ const recommendation = {
669
+ recommendedLevel,
670
+ reason,
671
+ confidence: this.compressionHistory.length > 10 ? 0.9 : 0.5,
672
+ estimatedCompressionMs,
673
+ estimatedRatio,
674
+ networkFactor,
675
+ deviceFactor
676
+ };
677
+ logger3.debug(
678
+ "[AdaptiveCompressionOptimizer] Recommendation",
679
+ recommendation
680
+ );
681
+ return recommendation;
682
+ }
683
+ /**
684
+ * Calculate network factor (0-1)
685
+ */
686
+ calculateNetworkFactor() {
687
+ if (!this.networkProfile.isOnline) return 0;
688
+ const speedMbps = this.networkProfile.estimatedSpeedKbps / 1e3;
689
+ if (speedMbps < 0.1) return 0;
690
+ if (speedMbps < 1) return 0.1 + speedMbps / 1 * 0.2;
691
+ if (speedMbps < 5) return 0.3 + (speedMbps - 1) / 4 * 0.3;
692
+ if (speedMbps < 20) return 0.6 + (speedMbps - 5) / 15 * 0.3;
693
+ return Math.min(1, 0.9 + (speedMbps - 20) / 200);
694
+ }
695
+ /**
696
+ * Calculate device factor (0-1)
697
+ */
698
+ calculateDeviceFactor() {
699
+ let factor = 0.5;
700
+ if (this.deviceProfile.isPremium) {
701
+ factor = 0.8;
702
+ } else if (this.deviceProfile.isConstrained) {
703
+ factor = 0.2;
704
+ }
705
+ if (this.deviceProfile.cpuUtilization > 0.8) {
706
+ factor *= 0.7;
707
+ } else if (this.deviceProfile.cpuUtilization < 0.2) {
708
+ factor *= 1.1;
709
+ }
710
+ if (this.deviceProfile.supportsWebAssembly) {
711
+ factor = Math.min(1, factor + 0.1);
712
+ }
713
+ return Math.max(0, Math.min(1, factor));
714
+ }
715
+ /**
716
+ * Estimate compression time for a level (in ms)
717
+ */
718
+ estimateCompressionTime(level) {
719
+ return Math.max(1, level * 2.5);
720
+ }
721
+ /**
722
+ * Estimate compression ratio for a level
723
+ */
724
+ estimateCompressionRatio(level) {
725
+ return 0.6 + level / 9 * 0.3;
726
+ }
727
+ /**
728
+ * Apply recommendation and get new level
729
+ */
730
+ applyRecommendation() {
731
+ const recommendation = this.getRecommendedLevel();
732
+ const oldLevel = this.currentLevel;
733
+ const shouldChange = recommendation.confidence > 0.7 || Math.abs(recommendation.recommendedLevel - oldLevel) > 2;
734
+ if (shouldChange) {
735
+ this.currentLevel = recommendation.recommendedLevel;
736
+ this.stats.levelsUsed.add(this.currentLevel);
737
+ if (oldLevel !== this.currentLevel) {
738
+ this.stats.adjustmentCount++;
739
+ logger3.debug("[AdaptiveCompressionOptimizer] Level adjusted", {
740
+ from: oldLevel,
741
+ to: this.currentLevel,
742
+ reason: recommendation.reason
743
+ });
744
+ }
745
+ }
746
+ this.stats.currentLevel = this.currentLevel;
747
+ return this.currentLevel;
748
+ }
749
+ /**
750
+ * Get current level
751
+ */
752
+ getCurrentLevel() {
753
+ return this.currentLevel;
754
+ }
755
+ /**
756
+ * Get statistics
757
+ */
758
+ getStats() {
759
+ return { ...this.stats };
760
+ }
761
+ /**
762
+ * Get detailed analysis
763
+ */
764
+ getDetailedAnalysis() {
765
+ return {
766
+ stats: this.stats,
767
+ network: this.networkProfile,
768
+ device: this.deviceProfile,
769
+ recommendation: this.getRecommendedLevel(),
770
+ history: this.compressionHistory.slice(-20)
771
+ };
772
+ }
773
+ };
774
+ var adaptiveOptimizerInstance = null;
775
+ function getAdaptiveCompressionOptimizer() {
776
+ if (!adaptiveOptimizerInstance) {
777
+ adaptiveOptimizerInstance = new AdaptiveCompressionOptimizer();
778
+ }
779
+ return adaptiveOptimizerInstance;
780
+ }
781
+ function resetAdaptiveCompressionOptimizer() {
782
+ adaptiveOptimizerInstance = null;
783
+ }
784
+
785
+ export { AdaptiveCompressionOptimizer, BatchTimingOptimizer, PrefetchingEngine, getAdaptiveCompressionOptimizer, getBatchTimingOptimizer, getPrefetchingEngine, resetAdaptiveCompressionOptimizer, resetBatchTimingOptimizer, resetPrefetchingEngine };
786
+ //# sourceMappingURL=index.js.map
787
+ //# sourceMappingURL=index.js.map