analogger 2.3.5 → 2.4.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.
@@ -717,6 +717,12 @@ class ____AnaLogger
717
717
  this.#initialiseDefault();
718
718
 
719
719
  this.resetLogHistory();
720
+
721
+ // Tracks the active local "only" filter across calls.
722
+ // _localOnlyFilter holds the raw value (for matching),
723
+ // _localOnlyLabel holds the stringified form (for change-detection and separator text).
724
+ this._localOnlyFilter = undefined;
725
+ this._localOnlyLabel = undefined;
720
726
  }
721
727
 
722
728
  getName()
@@ -928,6 +934,7 @@ class ____AnaLogger
928
934
  this.options.contextLenMax = 10;
929
935
  this.options.idLenMax = 5;
930
936
  this.options.lidLenMax = 6;
937
+ this.options.only = undefined;
931
938
  this.options.messageLenMax = undefined;
932
939
  this.options.symbolLenMax = 60;
933
940
  this.options.hideHookMessage = undefined;
@@ -977,6 +984,7 @@ class ____AnaLogger
977
984
  contextLenMax = 10,
978
985
  idLenMax = 5,
979
986
  lidLenMax = 6,
987
+ only = undefined,
980
988
  symbolLenMax = 2,
981
989
  enableTrace = true,
982
990
  messageLenMax = undefined,
@@ -1022,6 +1030,7 @@ class ____AnaLogger
1022
1030
  this.options.contextLenMax = contextLenMax;
1023
1031
  this.options.idLenMax = idLenMax;
1024
1032
  this.options.lidLenMax = lidLenMax;
1033
+ this.options.only = only;
1025
1034
  this.options.messageLenMax = messageLenMax;
1026
1035
  this.options.symbolLenMax = symbolLenMax;
1027
1036
 
@@ -2583,6 +2592,114 @@ class ____AnaLogger
2583
2592
  return result;
2584
2593
  }
2585
2594
 
2595
+ /**
2596
+ * Handle the local "only" option on a log context.
2597
+ *
2598
+ * Rules:
2599
+ * - If context.only is not set, do nothing.
2600
+ * - If context.only does NOT match context.lid (using the same partial-string /
2601
+ * regex logic as the global filter), the call is suppressed (returns false).
2602
+ * - On the very first matching call, the output channel is cleared:
2603
+ * • Browser → console.clear()
2604
+ * • Node → writes the terminal-reset sequence (\x1bc) to stdout
2605
+ * - On a subsequent matching call whose only value differs from the last seen
2606
+ * value, a separator line is printed instead of clearing.
2607
+ *
2608
+ * Returns false when the log entry should be suppressed, true otherwise.
2609
+ *
2610
+ * @param {object} context
2611
+ * @returns {boolean}
2612
+ */
2613
+ #handleLocalOnly(context)
2614
+ {
2615
+ const localOnly = context.only;
2616
+
2617
+ // Helper: test a lid string against a single filter entry.
2618
+ const lidMatchesFilter = (filter, lid) =>
2619
+ {
2620
+ if (filter instanceof RegExp)
2621
+ {
2622
+ return filter.test(lid);
2623
+ }
2624
+ if (typeof filter === "string" || filter instanceof String)
2625
+ {
2626
+ return lid.includes(filter);
2627
+ }
2628
+ return filter === lid;
2629
+ };
2630
+
2631
+ // Helper: test a lid against a filter that may be a single value or an array.
2632
+ const lidMatchesAny = (filter, lid) => Array.isArray(filter)
2633
+ ? filter.some((f) => lidMatchesFilter(f, lid))
2634
+ : lidMatchesFilter(filter, lid);
2635
+
2636
+ // Stable string label for a filter value (used for change-detection and separator text).
2637
+ const toLabel = (filter) => Array.isArray(filter)
2638
+ ? filter.map((f) => (f instanceof RegExp ? f.toString() : String(f))).join(", ")
2639
+ : (filter instanceof RegExp ? filter.toString() : String(filter));
2640
+
2641
+ const lid = context.lid || "";
2642
+
2643
+ if (localOnly === undefined || localOnly === null)
2644
+ {
2645
+ // No local only on this call. If a filter is already active, enforce it.
2646
+ if (this._localOnlyFilter !== undefined)
2647
+ {
2648
+ return lidMatchesAny(this._localOnlyFilter, lid);
2649
+ }
2650
+
2651
+ // No active filter at all – let the call through.
2652
+ return true;
2653
+ }
2654
+
2655
+ // --- This call explicitly sets context.only ---
2656
+
2657
+ if (!lidMatchesAny(localOnly, lid))
2658
+ {
2659
+ // The lid doesn't match – suppress without clearing or printing a separator,
2660
+ // since the filter hasn't been "activated" by an accepted call yet.
2661
+ return false;
2662
+ }
2663
+
2664
+ const onlyLabel = toLabel(localOnly);
2665
+
2666
+ if (this._localOnlyFilter === undefined)
2667
+ {
2668
+ // First ever match – clear the output channel.
2669
+ if (this.isBrowser())
2670
+ {
2671
+ /* istanbul ignore next */
2672
+ ____AnaLogger.Console.clear
2673
+ ? ____AnaLogger.Console.clear()
2674
+ : (typeof console !== "undefined" && console.clear && console.clear());
2675
+ }
2676
+ else
2677
+ {
2678
+ // ANSI terminal reset: clears the screen and moves cursor to top.
2679
+ process.stdout.write("\x1bc");
2680
+ }
2681
+ }
2682
+ else if (this._localOnlyLabel !== onlyLabel)
2683
+ {
2684
+ // Filter has changed – print a separator, no clear.
2685
+ const separator = `─── only switched to ${onlyLabel} ───`;
2686
+ if (this.isBrowser())
2687
+ {
2688
+ /* istanbul ignore next */
2689
+ ____AnaLogger.Console.log(`%c${separator}`, "color: #888; font-style: italic");
2690
+ }
2691
+ else
2692
+ {
2693
+ // Use the raw console so the separator bypasses all AnaLogger formatting.
2694
+ ____AnaLogger.Console.log(separator);
2695
+ }
2696
+ }
2697
+
2698
+ this._localOnlyFilter = localOnly; // raw value – used for matching
2699
+ this._localOnlyLabel = onlyLabel; // string – used for change detection
2700
+ return true;
2701
+ }
2702
+
2586
2703
  /**
2587
2704
  * Display log following template
2588
2705
  * @param context
@@ -2613,7 +2730,7 @@ class ____AnaLogger
2613
2730
  lid: context.lid,
2614
2731
  callCount: 1,
2615
2732
  callTimes: [Date.now()]
2616
- }
2733
+ };
2617
2734
  }
2618
2735
  }
2619
2736
 
@@ -2649,6 +2766,37 @@ class ____AnaLogger
2649
2766
  return;
2650
2767
  }
2651
2768
 
2769
+ // Check if global "only" filter is active
2770
+ if (this.options.only !== undefined && this.options.only !== null) {
2771
+ const onlyFilters = Array.isArray(this.options.only) ? this.options.only : [this.options.only];
2772
+ // Check if current log matches one of the filters
2773
+ const matchesFilter = onlyFilters.some((filter) => {
2774
+ const targetLid = context.lid || "";
2775
+ const targetOnly = context.only || "";
2776
+
2777
+ if (filter instanceof RegExp) {
2778
+ return filter.test(targetLid) || filter.test(targetOnly);
2779
+ }
2780
+
2781
+ // String partial match (e.g., "API" matches "API_123")
2782
+ if (typeof filter === "string") {
2783
+ return targetLid.includes(filter) || targetOnly.includes(filter);
2784
+ }
2785
+
2786
+ return filter === targetLid || filter === targetOnly;
2787
+ });
2788
+
2789
+ if (!matchesFilter) {
2790
+ return;
2791
+ }
2792
+ }
2793
+
2794
+ // Handle the per-call local "only" option.
2795
+ if (!this.#handleLocalOnly(context))
2796
+ {
2797
+ return;
2798
+ }
2799
+
2652
2800
  const newMessages = this.checkOnLogging(context, argsWithoutContext[0], arguments,"onMessage");
2653
2801
  if (newMessages !== undefined) {
2654
2802
  arguments[1] = newMessages;
@@ -2771,6 +2919,7 @@ class ____AnaLogger
2771
2919
  options.hasOwnProperty("color") ||
2772
2920
  options.hasOwnProperty("contextName") ||
2773
2921
  options.hasOwnProperty("raw") ||
2922
+ options.hasOwnProperty("only") ||
2774
2923
  options.hasOwnProperty("lid");
2775
2924
  }
2776
2925