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