@fanboynz/network-scanner 1.0.57 → 1.0.58

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 (3) hide show
  1. package/lib/smart-cache.js +318 -12
  2. package/nwss.js +58 -16
  3. package/package.json +1 -1
@@ -14,6 +14,11 @@ const { formatLogMessage } = require('./colorize');
14
14
  */
15
15
  class SmartCache {
16
16
  constructor(options = {}) {
17
+ // Calculate dynamic values first
18
+ const concurrency = options.concurrency || 6;
19
+ const optimalHeapLimit = this._calculateOptimalHeapLimit(concurrency);
20
+ const checkInterval = this._calculateCheckInterval(concurrency);
21
+
17
22
  this.options = {
18
23
  maxSize: options.maxSize || 5000,
19
24
  ttl: options.ttl || 1000 * 60 * 60, // 1 hour default
@@ -24,8 +29,18 @@ class SmartCache {
24
29
  persistencePath: options.persistencePath || '.cache',
25
30
  forceDebug: options.forceDebug || false,
26
31
  autoSave: options.autoSave !== false,
27
- autoSaveInterval: options.autoSaveInterval || 60000 // 1 minute
32
+ autoSaveInterval: options.autoSaveInterval || 60000, // 1 minute
33
+ maxHeapUsage: options.maxHeapUsage || optimalHeapLimit,
34
+ memoryCheckInterval: options.memoryCheckInterval || checkInterval,
35
+ concurrency: concurrency,
36
+ aggressiveMode: options.aggressiveMode || false
28
37
  };
38
+
39
+ // Add save debouncing
40
+ this.lastSaveTime = 0;
41
+ this.saveInProgress = false;
42
+ this.saveTimeout = null;
43
+ this.pendingSave = false;
29
44
 
30
45
  // Initialize cache layers
31
46
  this._initializeCaches();
@@ -42,6 +57,34 @@ class SmartCache {
42
57
  if (this.options.enablePersistence && this.options.autoSave) {
43
58
  this._setupAutoSave();
44
59
  }
60
+
61
+ // Set up memory monitoring
62
+ this.memoryCheckInterval = setInterval(() => {
63
+ this._checkMemoryPressure();
64
+ }, this.options.memoryCheckInterval);
65
+ }
66
+
67
+ /**
68
+ * Calculate optimal heap limit based on concurrency
69
+ * @private
70
+ */
71
+ _calculateOptimalHeapLimit(concurrency) {
72
+ // Base cache needs: 100MB
73
+ // Per concurrent connection: ~75MB average
74
+ // Safety margin: 50%
75
+ const baseCacheMemory = 100 * 1024 * 1024; // 100MB
76
+ const perConnectionMemory = 75 * 1024 * 1024; // 75MB
77
+ const totalEstimated = baseCacheMemory + (concurrency * perConnectionMemory);
78
+ return Math.round(totalEstimated * 0.4); // Cache should use max 40% of estimated total
79
+ }
80
+
81
+ /**
82
+ * Calculate check interval based on concurrency
83
+ * @private
84
+ */
85
+ _calculateCheckInterval(concurrency) {
86
+ // Higher concurrency = more frequent checks
87
+ return Math.max(5000, 30000 - (concurrency * 1000)); // 5s min, scales down with concurrency
45
88
  }
46
89
 
47
90
  /**
@@ -57,29 +100,43 @@ class SmartCache {
57
100
  updateAgeOnHas: false
58
101
  });
59
102
 
60
- // Pattern matching results cache
103
+ // Pattern matching results cache - reduce size for high concurrency
104
+ const patternCacheSize = this.options.concurrency > 10 ? 500 : 1000;
61
105
  this.patternCache = new LRUCache({
62
- max: 1000,
106
+ max: patternCacheSize,
63
107
  ttl: this.options.ttl * 2 // Patterns are more stable
64
108
  });
65
109
 
66
- // Response content cache for searchstring operations
110
+ // Response content cache - aggressive limits for high concurrency
111
+ const responseCacheSize = this.options.concurrency > 10 ? 50 : 200;
112
+ const responseCacheMemory = this.options.concurrency > 10 ? 20 * 1024 * 1024 : 50 * 1024 * 1024;
67
113
  this.responseCache = new LRUCache({
68
- max: 200,
114
+ max: responseCacheSize,
69
115
  ttl: 1000 * 60 * 30, // 30 minutes for response content
70
- maxSize: 50 * 1024 * 1024, // 50MB max cache size
116
+ maxSize: responseCacheMemory,
71
117
  sizeCalculation: (value) => value.length
72
118
  });
73
119
 
120
+ // Disable response cache entirely for very high concurrency
121
+ if (this.options.concurrency > 15 || this.options.aggressiveMode) {
122
+ this.options.enableResponseCache = false;
123
+ if (this.options.forceDebug) {
124
+ console.log(formatLogMessage('debug',
125
+ `[SmartCache] Response cache disabled for high concurrency (${this.options.concurrency})`
126
+ ));
127
+ }
128
+ }
129
+
74
130
  // WHOIS/DNS results cache
75
131
  this.netToolsCache = new LRUCache({
76
132
  max: 500,
77
133
  ttl: 1000 * 60 * 60 * 24 // 24 hours for WHOIS/DNS
78
134
  });
79
135
 
80
- // Similarity cache for expensive string comparisons
136
+ // Similarity cache - reduce for high concurrency
137
+ const similarityCacheSize = this.options.concurrency > 10 ? 1000 : 2000;
81
138
  this.similarityCache = new LRUCache({
82
- max: 2000,
139
+ max: similarityCacheSize,
83
140
  ttl: this.options.ttl
84
141
  });
85
142
 
@@ -107,6 +164,9 @@ class SmartCache {
107
164
  regexCacheHits: 0,
108
165
  persistenceLoads: 0,
109
166
  persistenceSaves: 0,
167
+ memoryPressureEvents: 0,
168
+ memoryWarnings: 0,
169
+ responseCacheSkips: 0,
110
170
  startTime: Date.now()
111
171
  };
112
172
  }
@@ -274,6 +334,21 @@ class SmartCache {
274
334
  cacheResponse(url, content) {
275
335
  if (!this.options.enableResponseCache) return;
276
336
 
337
+ // Skip response caching entirely for very high concurrency
338
+ if (this.options.concurrency > 12) {
339
+ this.stats.responseCacheSkips++;
340
+ return;
341
+ }
342
+
343
+ // Check memory before caching large content
344
+ const memUsage = process.memoryUsage();
345
+ const threshold = this.options.concurrency > 10 ? 0.7 : 0.8; // Lower threshold for high concurrency
346
+ if (memUsage.heapUsed > this.options.maxHeapUsage * threshold) {
347
+ this.stats.responseCacheSkips++;
348
+ this._logMemorySkip('response cache');
349
+ return;
350
+ }
351
+
277
352
  // Only cache if content is reasonable size
278
353
  if (content && content.length < 5 * 1024 * 1024) { // 5MB limit per response
279
354
  this.responseCache.set(url, content);
@@ -350,7 +425,85 @@ class SmartCache {
350
425
  this.stats.similarityMisses++;
351
426
  return null;
352
427
  }
428
+
429
+ /**
430
+ * Monitor memory usage and proactively manage caches
431
+ * @private
432
+ */
433
+ _checkMemoryPressure() {
434
+ const memUsage = process.memoryUsage();
435
+ const heapUsedMB = Math.round(memUsage.heapUsed / 1024 / 1024);
436
+ const maxHeapMB = Math.round(this.options.maxHeapUsage / 1024 / 1024);
437
+ const usagePercent = (memUsage.heapUsed / this.options.maxHeapUsage) * 100;
438
+
439
+ // Adjust thresholds based on concurrency
440
+ const criticalThreshold = this.options.concurrency > 10 ? 0.85 : 1.0;
441
+ const warningThreshold = this.options.concurrency > 10 ? 0.70 : 0.85;
442
+ const infoThreshold = this.options.concurrency > 10 ? 0.60 : 0.75;
443
+
444
+ // Critical threshold - aggressive cleanup
445
+ if (memUsage.heapUsed > this.options.maxHeapUsage * criticalThreshold) {
446
+ this._performMemoryCleanup('critical', heapUsedMB, maxHeapMB);
447
+ return true;
448
+ }
449
+
450
+ // Warning threshold - moderate cleanup
451
+ if (memUsage.heapUsed > this.options.maxHeapUsage * warningThreshold) {
452
+ this._performMemoryCleanup('warning', heapUsedMB, maxHeapMB);
453
+ return true;
454
+ }
455
+
456
+ // Info threshold - log only
457
+ if (memUsage.heapUsed > this.options.maxHeapUsage * infoThreshold) {
458
+ this.stats.memoryWarnings++;
459
+ if (this.options.forceDebug) {
460
+ console.log(formatLogMessage('debug',
461
+ `[SmartCache] Memory info: ${heapUsedMB}MB/${maxHeapMB}MB (${usagePercent.toFixed(1)}%)`
462
+ ));
463
+ }
464
+ }
465
+
466
+ return false;
467
+ }
353
468
 
469
+ /**
470
+ * Perform memory cleanup based on severity
471
+ * @private
472
+ */
473
+ _performMemoryCleanup(level, heapUsedMB, maxHeapMB) {
474
+ this.stats.memoryPressureEvents++;
475
+
476
+ if (this.options.forceDebug) {
477
+ console.log(formatLogMessage('debug',
478
+ `[SmartCache] Memory ${level}: ${heapUsedMB}MB/${maxHeapMB}MB, performing cleanup...`
479
+ ));
480
+ }
481
+
482
+ if (level === 'critical' || this.options.concurrency > 12) {
483
+ // Aggressive cleanup - clear volatile caches
484
+ this.responseCache.clear();
485
+ this.patternCache.clear();
486
+ this.similarityCache.clear();
487
+
488
+ // For very high concurrency, also trim domain cache
489
+ if (this.options.concurrency > 15) {
490
+ const currentSize = this.domainCache.size;
491
+ this.domainCache.clear();
492
+ if (this.options.forceDebug) {
493
+ console.log(formatLogMessage('debug', `[SmartCache] Cleared ${currentSize} domain cache entries`));
494
+ }
495
+ }
496
+ } else if (level === 'warning') {
497
+ // Moderate cleanup - clear largest cache
498
+ this.responseCache.clear();
499
+ }
500
+
501
+ // Force garbage collection if available
502
+ if (global.gc) {
503
+ global.gc();
504
+ }
505
+ }
506
+
354
507
  /**
355
508
  * Get cache statistics
356
509
  * @returns {Object} Statistics object
@@ -364,6 +517,9 @@ class SmartCache {
364
517
  (this.stats.responseHits + this.stats.responseMisses) || 0;
365
518
  const netToolsHitRate = this.stats.netToolsHits /
366
519
  (this.stats.netToolsHits + this.stats.netToolsMisses) || 0;
520
+
521
+
522
+ const memUsage = process.memoryUsage();
367
523
 
368
524
  return {
369
525
  ...this.stats,
@@ -380,7 +536,11 @@ class SmartCache {
380
536
  regexCacheSize: this.regexCache.size,
381
537
  totalCacheEntries: this.domainCache.size + this.patternCache.size +
382
538
  this.responseCache.size + this.netToolsCache.size +
383
- this.similarityCache.size + this.regexCache.size
539
+ this.similarityCache.size + this.regexCache.size,
540
+ memoryUsageMB: Math.round(memUsage.heapUsed / 1024 / 1024),
541
+ memoryMaxMB: Math.round(this.options.maxHeapUsage / 1024 / 1024),
542
+ memoryUsagePercent: ((memUsage.heapUsed / this.options.maxHeapUsage) * 100).toFixed(1) + '%',
543
+ responseCacheMemoryMB: Math.round((this.responseCache.calculatedSize || 0) / 1024 / 1024)
384
544
  };
385
545
  }
386
546
 
@@ -401,6 +561,18 @@ class SmartCache {
401
561
  }
402
562
  }
403
563
 
564
+ /**
565
+ * Helper method to log memory-related cache skips
566
+ * @private
567
+ */
568
+ _logMemorySkip(operation) {
569
+ if (this.options.forceDebug) {
570
+ console.log(formatLogMessage('debug',
571
+ `[SmartCache] Skipping ${operation} due to memory pressure`
572
+ ));
573
+ }
574
+ }
575
+
404
576
  /**
405
577
  * Load persistent cache from disk
406
578
  * @private
@@ -464,6 +636,34 @@ class SmartCache {
464
636
  */
465
637
  savePersistentCache() {
466
638
  if (!this.options.enablePersistence) return;
639
+
640
+ // Prevent concurrent saves
641
+ if (this.saveInProgress) {
642
+ this.pendingSave = true;
643
+ if (this.options.forceDebug) {
644
+ console.log(formatLogMessage('debug', '[SmartCache] Save in progress, marking pending...'));
645
+ }
646
+ return;
647
+ }
648
+
649
+ // Debounce saves - don't save more than once every 10 seconds
650
+ const now = Date.now();
651
+ if (now - this.lastSaveTime < 10000) {
652
+ // Schedule a delayed save if none is pending
653
+ if (!this.saveTimeout && !this.pendingSave) {
654
+ this.pendingSave = true;
655
+ this.saveTimeout = setTimeout(() => {
656
+ this.saveTimeout = null;
657
+ if (this.pendingSave) {
658
+ this.pendingSave = false;
659
+ this.savePersistentCache();
660
+ }
661
+ }, 10000 - (now - this.lastSaveTime));
662
+ }
663
+ return;
664
+ }
665
+ this.saveInProgress = true;
666
+ this.lastSaveTime = now;
467
667
 
468
668
  const cacheDir = this.options.persistencePath;
469
669
  const cacheFile = path.join(cacheDir, 'smart-cache.json');
@@ -475,7 +675,7 @@ class SmartCache {
475
675
  }
476
676
 
477
677
  const data = {
478
- timestamp: Date.now(),
678
+ timestamp: now,
479
679
  domainCache: Array.from(this.domainCache.entries()),
480
680
  netToolsCache: Array.from(this.netToolsCache.entries()),
481
681
  stats: this.stats
@@ -495,6 +695,14 @@ class SmartCache {
495
695
  `[SmartCache] Failed to save cache: ${err.message}`
496
696
  ));
497
697
  }
698
+ } finally {
699
+ this.saveInProgress = false;
700
+
701
+ // Process any pending saves
702
+ if (this.pendingSave && !this.saveTimeout) {
703
+ this.pendingSave = false;
704
+ setTimeout(() => this.savePersistentCache(), 1000);
705
+ }
498
706
  }
499
707
  }
500
708
 
@@ -512,9 +720,16 @@ class SmartCache {
512
720
  * Clean up resources
513
721
  */
514
722
  destroy() {
723
+ if (this.memoryCheckInterval) {
724
+ clearInterval(this.memoryCheckInterval);
725
+ }
515
726
  if (this.autoSaveInterval) {
516
727
  clearInterval(this.autoSaveInterval);
517
728
  }
729
+ if (this.saveTimeout) {
730
+ clearTimeout(this.saveTimeout);
731
+ this.saveTimeout = null;
732
+ }
518
733
 
519
734
  // Save cache one last time
520
735
  if (this.options.enablePersistence) {
@@ -523,6 +738,92 @@ class SmartCache {
523
738
 
524
739
  this.clear();
525
740
  }
741
+
742
+ /**
743
+ * Clear persistent cache files and directories
744
+ * @param {Object} options - Clear options
745
+ * @param {boolean} options.silent - Suppress console output
746
+ * @param {boolean} options.forceDebug - Enable debug logging
747
+ * @returns {Object} Clear operation results
748
+ */
749
+ static clearPersistentCache(options = {}) {
750
+ const { silent = false, forceDebug = false, cachePath = '.cache' } = options;
751
+
752
+ const cachePaths = [
753
+ cachePath,
754
+ path.join(cachePath, 'smart-cache.json'),
755
+ // Add other potential cache files here if needed
756
+ ];
757
+
758
+ let clearedItems = 0;
759
+ let totalSize = 0;
760
+ const clearedFiles = [];
761
+ const errors = [];
762
+
763
+ if (!silent) {
764
+ console.log(`\n??? Clearing cache...`);
765
+ }
766
+
767
+ for (const currentCachePath of cachePaths) {
768
+ if (fs.existsSync(currentCachePath)) {
769
+ try {
770
+ const stats = fs.statSync(currentCachePath);
771
+ if (stats.isDirectory()) {
772
+ // Calculate total size of directory contents
773
+ const files = fs.readdirSync(currentCachePath);
774
+ for (const file of files) {
775
+ const filePath = path.join(currentCachePath, file);
776
+ if (fs.existsSync(filePath)) {
777
+ totalSize += fs.statSync(filePath).size;
778
+ }
779
+ }
780
+ fs.rmSync(currentCachePath, { recursive: true, force: true });
781
+ clearedItems++;
782
+ clearedFiles.push({ type: 'directory', path: currentCachePath, size: totalSize });
783
+ if (forceDebug) {
784
+ console.log(formatLogMessage('debug', `Cleared cache directory: ${currentCachePath}`));
785
+ }
786
+ } else {
787
+ totalSize += stats.size;
788
+ fs.unlinkSync(currentCachePath);
789
+ clearedItems++;
790
+ clearedFiles.push({ type: 'file', path: currentCachePath, size: stats.size });
791
+ if (forceDebug) {
792
+ console.log(formatLogMessage('debug', `Cleared cache file: ${currentCachePath}`));
793
+ }
794
+ }
795
+ } catch (clearErr) {
796
+ errors.push({ path: currentCachePath, error: clearErr.message });
797
+ if (forceDebug) {
798
+ console.log(formatLogMessage('debug', `Failed to clear ${currentCachePath}: ${clearErr.message}`));
799
+ }
800
+ }
801
+ }
802
+ }
803
+
804
+ const result = {
805
+ success: errors.length === 0,
806
+ clearedItems,
807
+ totalSize,
808
+ sizeMB: (totalSize / 1024 / 1024).toFixed(2),
809
+ clearedFiles,
810
+ errors
811
+ };
812
+
813
+ if (!silent) {
814
+ if (clearedItems > 0) {
815
+ console.log(`? Cache cleared: ${clearedItems} item(s), ${result.sizeMB}MB freed`);
816
+ } else {
817
+ console.log(`?? No cache files found to clear`);
818
+ }
819
+
820
+ if (errors.length > 0) {
821
+ console.warn(`?? ${errors.length} error(s) occurred during cache clearing`);
822
+ }
823
+ }
824
+
825
+ return result;
826
+ }
526
827
  }
527
828
 
528
829
  /**
@@ -541,11 +842,16 @@ function createSmartCache(config = {}) {
541
842
  persistencePath: config.cache_path || '.cache',
542
843
  forceDebug: config.forceDebug || false,
543
844
  autoSave: config.cache_autosave !== false,
544
- autoSaveInterval: (config.cache_autosave_minutes || 1) * 60 * 1000
845
+ autoSaveInterval: (config.cache_autosave_minutes || 1) * 60 * 1000,
846
+ maxHeapUsage: config.cache_max_heap_mb ? config.cache_max_heap_mb * 1024 * 1024 : undefined,
847
+ memoryCheckInterval: (config.cache_memory_check_seconds || 30) * 1000,
848
+ concurrency: config.max_concurrent_sites || 6,
849
+ aggressiveMode: config.cache_aggressive_mode === true
545
850
  });
546
851
  }
547
852
 
548
853
  module.exports = {
549
854
  SmartCache,
550
- createSmartCache
855
+ createSmartCache,
856
+ clearPersistentCache: SmartCache.clearPersistentCache
551
857
  };
package/nwss.js CHANGED
@@ -1,4 +1,4 @@
1
- // === Network scanner script (nwss.js) v1.0.57 ===
1
+ // === Network scanner script (nwss.js) v1.0.58 ===
2
2
 
3
3
  // puppeteer for browser automation, fs for file system operations, psl for domain parsing.
4
4
  // const pLimit = require('p-limit'); // Will be dynamically imported
@@ -34,13 +34,14 @@ const { performPageInteraction, createInteractionConfig } = require('./lib/inter
34
34
  // Domain detection cache for performance optimization
35
35
  const { createGlobalHelpers, getTotalDomainsSkipped, getDetectedDomainsCount } = require('./lib/domain-cache');
36
36
  const { createSmartCache } = require('./lib/smart-cache'); // Smart cache system
37
+ const { clearPersistentCache } = require('./lib/smart-cache');
37
38
  // Enhanced redirect handling
38
39
  const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/redirect');
39
40
  // Ensure web browser is working correctly
40
41
  const { monitorBrowserHealth, isBrowserHealthy } = require('./lib/browserhealth');
41
42
 
42
43
  // --- Script Configuration & Constants ---
43
- const VERSION = '1.0.57'; // Script version
44
+ const VERSION = '1.0.58'; // Script version
44
45
 
45
46
  // get startTime
46
47
  const startTime = Date.now();
@@ -102,6 +103,8 @@ const validateConfig = args.includes('--validate-config');
102
103
  const validateRules = args.includes('--validate-rules');
103
104
  const testValidation = args.includes('--test-validation');
104
105
  let cleanRules = args.includes('--clean-rules');
106
+ const clearCache = args.includes('--clear-cache');
107
+ const ignoreCache = args.includes('--ignore-cache');
105
108
 
106
109
  let validateRulesFile = null;
107
110
  const validateRulesIndex = args.findIndex(arg => arg === '--validate-rules');
@@ -224,6 +227,15 @@ if (args.includes('--version')) {
224
227
  process.exit(0);
225
228
  }
226
229
 
230
+ // Handle --clear-cache before config loading (uses default cache path)
231
+ if (clearCache && !dryRunMode) {
232
+ clearPersistentCache({
233
+ silent: silentMode,
234
+ forceDebug,
235
+ cachePath: '.cache' // Default path, will be updated after config loads if needed
236
+ });
237
+ }
238
+
227
239
  // Handle validation-only operations before main help
228
240
  if (testValidation) {
229
241
  console.log(`\n${messageColors.processing('Running domain validation tests...')}`);
@@ -360,6 +372,8 @@ Validation Options:
360
372
  --validate-rules [file] Validate rule file format (uses --output/--compare files if no file specified)
361
373
  --clean-rules [file] Clean rule files by removing invalid lines and optionally duplicates (uses --output/--compare files if no file specified)
362
374
  --test-validation Run domain validation tests and exit
375
+ --clear-cache Clear persistent cache before scanning (improves fresh start performance)
376
+ --ignore-cache Bypass all smart caching functionality during scanning
363
377
 
364
378
  Global config.json options:
365
379
  ignoreDomains: ["domain.com", "*.ads.com"] Domains to completely ignore (supports wildcards)
@@ -551,15 +565,40 @@ const RESOURCE_CLEANUP_INTERVAL = (() => {
551
565
  return 180;
552
566
  })();
553
567
 
554
- // Initialize smart cache system AFTER config is loaded
568
+ // Perform cache clear after config is loaded for custom cache paths
569
+ if (clearCache && dryRunMode) {
570
+ clearPersistentCache({
571
+ silent: silentMode,
572
+ forceDebug,
573
+ cachePath: config.cache_path || '.cache'
574
+ });
575
+ }
576
+
577
+ // Also clear for custom cache paths in normal mode if not already cleared
578
+ if (clearCache && !dryRunMode && config.cache_path && config.cache_path !== '.cache') {
579
+ clearPersistentCache({
580
+ silent: silentMode,
581
+ forceDebug,
582
+ cachePath: config.cache_path
583
+ });
584
+ }
585
+
586
+ // Initialize smart cache system AFTER config is loaded (unless --ignore-cache is used)
587
+ if (ignoreCache) {
588
+ smartCache = null;
589
+ if (forceDebug) console.log(formatLogMessage('debug', 'Smart cache disabled by --ignore-cache flag'));
590
+ } else {
555
591
  smartCache = createSmartCache({
556
592
  ...config,
557
593
  forceDebug,
558
- cache_persistence: config.cache_persistence !== false, // Enable by default
559
- cache_autosave: config.cache_autosave !== false,
594
+ max_concurrent_sites: MAX_CONCURRENT_SITES, // Pass concurrency info
595
+ cache_aggressive_mode: MAX_CONCURRENT_SITES > 12, // Auto-enable for high concurrency
596
+ cache_persistence: false, // Disable persistence completely
597
+ cache_autosave: false, // Disable auto-save completely
560
598
  cache_autosave_minutes: config.cache_autosave_minutes || 1,
561
599
  cache_max_size: config.cache_max_size || 5000
562
600
  });
601
+ }
563
602
 
564
603
  // Handle --clean-rules after config is loaded (so we have access to sites)
565
604
  if (cleanRules || cleanRulesFile) {
@@ -1503,7 +1542,7 @@ function setupFrameHandling(page, forceDebug) {
1503
1542
  const similarityThreshold = siteConfig.ignore_similar_threshold || ignore_similar_threshold;
1504
1543
  const ignoreSimilarIgnoredDomains = siteConfig.ignore_similar_ignored_domains !== undefined ? siteConfig.ignore_similar_ignored_domains : ignore_similar_ignored_domains;
1505
1544
 
1506
- // Use smart cache's similarity cache for performance
1545
+ // Use smart cache's similarity cache for performance (if cache is enabled)
1507
1546
  if (ignoreSimilarEnabled && smartCache) {
1508
1547
  const existingDomains = matchedDomains instanceof Map
1509
1548
  ? Array.from(matchedDomains.keys()).filter(key => !['dryRunMatches', 'dryRunNetTools', 'dryRunSearchString'].includes(key))
@@ -1522,14 +1561,14 @@ function setupFrameHandling(page, forceDebug) {
1522
1561
  // If no cached similarity exists, calculate and cache it
1523
1562
  if (cachedSimilarity === null) {
1524
1563
  const similarity = calculateSimilarity(domain, existingDomain);
1525
- if (smartCache) {
1564
+ if (smartCache && !ignoreCache) {
1526
1565
  smartCache.cacheSimilarity(domain, existingDomain, similarity);
1527
1566
  }
1528
1567
  }
1529
1568
  }
1530
1569
  }
1531
1570
 
1532
- // Check smart cache first
1571
+ // Check smart cache first (if cache is enabled)
1533
1572
  const context = {
1534
1573
  filterRegex: siteConfig.filterRegex,
1535
1574
  searchString: siteConfig.searchstring,
@@ -1581,7 +1620,7 @@ function setupFrameHandling(page, forceDebug) {
1581
1620
  // Mark full subdomain as detected for future reference
1582
1621
  markDomainAsDetected(cacheKey);
1583
1622
 
1584
- // Also mark in smart cache with context
1623
+ // Also mark in smart cache with context (if cache is enabled)
1585
1624
  if (smartCache) {
1586
1625
  smartCache.markDomainProcessed(domain, context, { resourceType, fullSubdomain });
1587
1626
  }
@@ -1831,7 +1870,7 @@ function setupFrameHandling(page, forceDebug) {
1831
1870
  }
1832
1871
 
1833
1872
  // Create and execute nettools handler
1834
- // Check smart cache for nettools results
1873
+ // Check smart cache for nettools results (if cache is enabled)
1835
1874
  const cachedWhois = smartCache ? smartCache.getCachedNetTools(reqDomain, 'whois') : null;
1836
1875
  const cachedDig = smartCache ? smartCache.getCachedNetTools(reqDomain, 'dig', digRecordType) : null;
1837
1876
 
@@ -1839,7 +1878,7 @@ function setupFrameHandling(page, forceDebug) {
1839
1878
  console.log(formatLogMessage('debug', `[SmartCache] Using cached nettools results for ${reqDomain}`));
1840
1879
  }
1841
1880
 
1842
- // Create nettools handler with cache callbacks
1881
+ // Create nettools handler with cache callbacks (if cache is enabled)
1843
1882
  const netToolsHandler = createNetToolsHandler({
1844
1883
  whoisTerms,
1845
1884
  whoisOrTerms,
@@ -1857,7 +1896,7 @@ function setupFrameHandling(page, forceDebug) {
1857
1896
  matchedDomains,
1858
1897
  addMatchedDomain,
1859
1898
  isDomainAlreadyDetected,
1860
- // Add cache callbacks if smart cache is available
1899
+ // Add cache callbacks if smart cache is available and caching is enabled
1861
1900
  onWhoisResult: smartCache ? (domain, result) => {
1862
1901
  smartCache.cacheNetTools(domain, 'whois', result);
1863
1902
  } : undefined,
@@ -1905,7 +1944,7 @@ function setupFrameHandling(page, forceDebug) {
1905
1944
 
1906
1945
  // If curl is enabled, download and analyze content immediately
1907
1946
  if (useCurl) {
1908
- // Check response cache first if smart cache is available
1947
+ // Check response cache first if smart cache is available and caching is enabled
1909
1948
  const cachedContent = smartCache ? smartCache.getCachedResponse(reqUrl) : null;
1910
1949
 
1911
1950
  if (cachedContent && forceDebug) {
@@ -1922,7 +1961,7 @@ function setupFrameHandling(page, forceDebug) {
1922
1961
  matchedDomains,
1923
1962
  addMatchedDomain, // Pass the helper function
1924
1963
  isDomainAlreadyDetected,
1925
- onContentFetched: smartCache ? (url, content) => {
1964
+ onContentFetched: smartCache && !ignoreCache ? (url, content) => {
1926
1965
  smartCache.cacheResponse(url, content);
1927
1966
  } : undefined,
1928
1967
  currentUrl,
@@ -2587,7 +2626,7 @@ function setupFrameHandling(page, forceDebug) {
2587
2626
  console.log(formatLogMessage('debug', `Output format: ${getFormatDescription(globalOptions)}`));
2588
2627
  console.log(formatLogMessage('debug', `Generated ${outputResult.totalRules} rules from ${outputResult.successfulPageLoads} successful page loads`));
2589
2628
  console.log(formatLogMessage('debug', `Performance: ${totalDomainsSkipped} domains skipped (already detected), ${detectedDomainsCount} unique domains cached`));
2590
- // Log smart cache statistics
2629
+ // Log smart cache statistics (if cache is enabled)
2591
2630
  if (smartCache) {
2592
2631
  const cacheStats = smartCache.getStats();
2593
2632
  console.log(formatLogMessage('debug', '=== Smart Cache Statistics ==='));
@@ -2677,7 +2716,7 @@ function setupFrameHandling(page, forceDebug) {
2677
2716
  const seconds = totalSeconds % 60;
2678
2717
 
2679
2718
  // Final summary report with timing and success statistics
2680
- // Clean up smart cache
2719
+ // Clean up smart cache (if it exists)
2681
2720
  if (smartCache) {
2682
2721
  smartCache.destroy();
2683
2722
  }
@@ -2699,6 +2738,9 @@ function setupFrameHandling(page, forceDebug) {
2699
2738
  if (totalDomainsSkipped > 0) {
2700
2739
  console.log(messageColors.info('Performance:') + ` ${totalDomainsSkipped} domains skipped (already detected)`);
2701
2740
  }
2741
+ if (ignoreCache && forceDebug) {
2742
+ console.log(messageColors.info('Cache:') + ` Smart caching was disabled`);
2743
+ }
2702
2744
  }
2703
2745
 
2704
2746
  // Clean process termination
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fanboynz/network-scanner",
3
- "version": "1.0.57",
3
+ "version": "1.0.58",
4
4
  "description": "A Puppeteer-based network scanner for analyzing web traffic, generating adblock filter rules, and identifying third-party requests. Features include fingerprint spoofing, Cloudflare bypass, content analysis with curl/grep, and multiple output formats.",
5
5
  "main": "nwss.js",
6
6
  "scripts": {