analogger 2.3.5 → 2.6.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/README.md +40 -0
- package/ana-logger.d.cts +7 -1
- package/browser/ana-logger.mjs +189 -1
- package/dist/analogger-browser.min.mjs +6 -6
- package/dist/html-to-image-plugin.min.mjs +6 -6
- package/esm/ana-logger.mjs +189 -1
- package/package.json +1 -1
- package/src/ana-logger.cjs +189 -1
package/README.md
CHANGED
|
@@ -245,6 +245,43 @@ anaLogger.log({lid: 1236, symbol: "scissors"}, `I'am some log with some scissors
|
|
|
245
245
|
|
|
246
246
|
<br/>
|
|
247
247
|
|
|
248
|
+
#### Example 6: The "only" filter
|
|
249
|
+
|
|
250
|
+
###### You can filter logs globally so that only specific identifiers are displayed. This supports exact strings, partial matches, or regular expressions.
|
|
251
|
+
|
|
252
|
+
```javascript
|
|
253
|
+
// Only show logs where the LID or context contains "API"
|
|
254
|
+
anaLogger.setOptions({ only: "API" });
|
|
255
|
+
|
|
256
|
+
anaLogger.log({ lid: "API_123" }, "This matches and will be seen");
|
|
257
|
+
anaLogger.log({ lid: "WEB_456" }, "This is blocked and hidden");
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
#### Example 7: The "order" option
|
|
264
|
+
|
|
265
|
+
###### Enforce a call sequence by assigning an `order` number to each log entry. If a log with a lower order value appears after one with a higher value, AnaLogger emits a console warning. Calls without an `order` are transparent and do not affect the sequence.
|
|
266
|
+
|
|
267
|
+
```javascript
|
|
268
|
+
anaLogger.log({lid: "API", order: 1}, "This matches");
|
|
269
|
+
anaLogger.log({lid: "API_123", order: 2}, "This shows API_123");
|
|
270
|
+
anaLogger.log({lid: "WEB_456", order: 35}, "This is blocked");
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
If the calls arrive out of sequence — for example, `API_123` (order 2) appearing after `WEB_456` (order 35) — the following warning is printed to the console:
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
! Order mismatch: [API_123| order: 2] appeared after [WEB_456| order: 35]
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
> **Notes:**
|
|
280
|
+
> - The check is per-instance, so different AnaLogger instances track their own sequences independently.
|
|
281
|
+
> - Calls filtered out by `only`, targets, or log levels are not counted toward the sequence.
|
|
282
|
+
> - Equal order values (non-decreasing) are always allowed; only strictly lower values trigger the warning.
|
|
283
|
+
|
|
284
|
+
|
|
248
285
|
---
|
|
249
286
|
|
|
250
287
|
### listSymbols()
|
|
@@ -312,6 +349,8 @@ Display the browser native message box if run from it; otherwise, it displays th
|
|
|
312
349
|
| compressionLevel | 1 | number | _Gzip compression level (0-9)_ |
|
|
313
350
|
| addArchiveTimestamp | true | boolean | _Appends a consistent timestamp to rotated files_ |
|
|
314
351
|
| forceLidOn | false | boolean | _Automatically generates a short hash LID if one isn't provided_ |
|
|
352
|
+
| only | undefined | string/Regex/Array | Filter logs to show only those matching specific IDs or patterns |
|
|
353
|
+
| order | undefined | number | _Enforce call order — emits a console warning if a log with a lower order value appears after one with a higher value_ |
|
|
315
354
|
|
|
316
355
|
<br/>
|
|
317
356
|
|
|
@@ -1333,6 +1372,7 @@ anaLogger.log("lid: USR_LOGIN, color: purple", "User logged in");
|
|
|
1333
1372
|
* Add an option to show the date and time in logs
|
|
1334
1373
|
* Make the alert method display the lid when detected
|
|
1335
1374
|
* Keep format when displaying multiple lines for one entry
|
|
1375
|
+
* Add `order` option to detect and warn on out-of-sequence log calls
|
|
1336
1376
|
|
|
1337
1377
|
|
|
1338
1378
|
##### 1.23.2:
|
package/ana-logger.d.cts
CHANGED
|
@@ -75,6 +75,12 @@ declare class ____AnaLogger {
|
|
|
75
75
|
NODE: string;
|
|
76
76
|
OTHER: string;
|
|
77
77
|
};
|
|
78
|
+
_localOnlyFilter: any;
|
|
79
|
+
_localOnlyLabel: string;
|
|
80
|
+
_lastOrderEntry: {
|
|
81
|
+
lid: any;
|
|
82
|
+
order: any;
|
|
83
|
+
};
|
|
78
84
|
getName(): string;
|
|
79
85
|
getId(): string;
|
|
80
86
|
/**
|
|
@@ -123,7 +129,7 @@ declare class ____AnaLogger {
|
|
|
123
129
|
resetLogger(): void;
|
|
124
130
|
remoteWaitCount: any;
|
|
125
131
|
resetOptions(): void;
|
|
126
|
-
setOptions({ timeLenMax, contextLenMax, idLenMax, lidLenMax, symbolLenMax, enableTrace, messageLenMax, hideLog, hideError, hideHookMessage, hidePassingTests, logToDom, logToFile, logMaxSize, logMaxArchives, logIndexArchive, addArchiveTimestamp, addArchiveIndex, compressArchives, compressionLevel, logToRemote, logToRemoteUrl, logToRemoteBinaryUrl, loopback, requiredLogLevel, oneConsolePerContext, silent, enableDate, enableMillisec, logToLocalStorage, logToLocalStorageMax, logToLocalStorageSize, logToRemoteMaxEntries, logToRemoteDebounce, logToRemoteMaxSize, logToRemoteMinSize, logUidToRemote, protocol, host, port, pathname, binarypathname, loadHtmlToImage }?: any): void;
|
|
132
|
+
setOptions({ timeLenMax, contextLenMax, idLenMax, lidLenMax, only, symbolLenMax, enableTrace, messageLenMax, hideLog, hideError, hideHookMessage, hidePassingTests, logToDom, logToFile, logMaxSize, logMaxArchives, logIndexArchive, addArchiveTimestamp, addArchiveIndex, compressArchives, compressionLevel, logToRemote, logToRemoteUrl, logToRemoteBinaryUrl, loopback, requiredLogLevel, oneConsolePerContext, silent, enableDate, enableMillisec, logToLocalStorage, logToLocalStorageMax, logToLocalStorageSize, logToRemoteMaxEntries, logToRemoteDebounce, logToRemoteMaxSize, logToRemoteMinSize, logUidToRemote, protocol, host, port, pathname, binarypathname, loadHtmlToImage }?: any): void;
|
|
127
133
|
EOL: string;
|
|
128
134
|
updateOptions(options: any): void;
|
|
129
135
|
getOptions(): {
|
package/browser/ana-logger.mjs
CHANGED
|
@@ -721,6 +721,15 @@ class ____AnaLogger
|
|
|
721
721
|
this.#initialiseDefault();
|
|
722
722
|
|
|
723
723
|
this.resetLogHistory();
|
|
724
|
+
|
|
725
|
+
// Tracks the active local "only" filter across calls.
|
|
726
|
+
// _localOnlyFilter holds the raw value (for matching),
|
|
727
|
+
// _localOnlyLabel holds the stringified form (for change-detection and separator text).
|
|
728
|
+
this._localOnlyFilter = undefined;
|
|
729
|
+
this._localOnlyLabel = undefined;
|
|
730
|
+
|
|
731
|
+
// Tracks the last seen "order" entry { lid, order } for order-mismatch detection.
|
|
732
|
+
this._lastOrderEntry = null;
|
|
724
733
|
}
|
|
725
734
|
|
|
726
735
|
getName()
|
|
@@ -932,6 +941,7 @@ class ____AnaLogger
|
|
|
932
941
|
this.options.contextLenMax = 10;
|
|
933
942
|
this.options.idLenMax = 5;
|
|
934
943
|
this.options.lidLenMax = 6;
|
|
944
|
+
this.options.only = undefined;
|
|
935
945
|
this.options.messageLenMax = undefined;
|
|
936
946
|
this.options.symbolLenMax = 60;
|
|
937
947
|
this.options.hideHookMessage = undefined;
|
|
@@ -981,6 +991,7 @@ class ____AnaLogger
|
|
|
981
991
|
contextLenMax = 10,
|
|
982
992
|
idLenMax = 5,
|
|
983
993
|
lidLenMax = 6,
|
|
994
|
+
only = undefined,
|
|
984
995
|
symbolLenMax = 2,
|
|
985
996
|
enableTrace = true,
|
|
986
997
|
messageLenMax = undefined,
|
|
@@ -1026,6 +1037,7 @@ class ____AnaLogger
|
|
|
1026
1037
|
this.options.contextLenMax = contextLenMax;
|
|
1027
1038
|
this.options.idLenMax = idLenMax;
|
|
1028
1039
|
this.options.lidLenMax = lidLenMax;
|
|
1040
|
+
this.options.only = only;
|
|
1029
1041
|
this.options.messageLenMax = messageLenMax;
|
|
1030
1042
|
this.options.symbolLenMax = symbolLenMax;
|
|
1031
1043
|
|
|
@@ -2276,6 +2288,7 @@ class ____AnaLogger
|
|
|
2276
2288
|
const {context, args} = entry;
|
|
2277
2289
|
if (context) {
|
|
2278
2290
|
context.symbol = "floppy_disk";
|
|
2291
|
+
delete context.order;
|
|
2279
2292
|
}
|
|
2280
2293
|
this.processOutput(context, ...args);
|
|
2281
2294
|
});
|
|
@@ -2582,6 +2595,146 @@ class ____AnaLogger
|
|
|
2582
2595
|
return result;
|
|
2583
2596
|
}
|
|
2584
2597
|
|
|
2598
|
+
/**
|
|
2599
|
+
* Check that log calls with an "order" property arrive in non-decreasing order.
|
|
2600
|
+
* When a call with a lower order value appears after one with a higher order value,
|
|
2601
|
+
* a warning is printed:
|
|
2602
|
+
* ! Order mismatch: [API_123| order: 2] appeared after [WEB_456| order: 35]
|
|
2603
|
+
*
|
|
2604
|
+
* @param {object} context
|
|
2605
|
+
*/
|
|
2606
|
+
#checkOrder(context)
|
|
2607
|
+
{
|
|
2608
|
+
if (context.order === undefined || context.order === null)
|
|
2609
|
+
{
|
|
2610
|
+
return;
|
|
2611
|
+
}
|
|
2612
|
+
|
|
2613
|
+
const currentOrder = context.order;
|
|
2614
|
+
const currentLid = context.lid || "";
|
|
2615
|
+
|
|
2616
|
+
if (this._lastOrderEntry !== null)
|
|
2617
|
+
{
|
|
2618
|
+
const {lid: prevLid, order: prevOrder} = this._lastOrderEntry;
|
|
2619
|
+
|
|
2620
|
+
if (currentOrder < prevOrder)
|
|
2621
|
+
{
|
|
2622
|
+
const msg = `! Order mismatch: [${currentLid}| order: ${currentOrder}] appeared after [${prevLid}| order: ${prevOrder}]`;
|
|
2623
|
+
____AnaLogger.Console.warn(msg);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
|
|
2627
|
+
this._lastOrderEntry = {lid: currentLid, order: currentOrder};
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
/**
|
|
2631
|
+
* Handle the local "only" option on a log context.
|
|
2632
|
+
*
|
|
2633
|
+
* Rules:
|
|
2634
|
+
* - If context.only is not set, do nothing.
|
|
2635
|
+
* - If context.only does NOT match context.lid (using the same partial-string /
|
|
2636
|
+
* regex logic as the global filter), the call is suppressed (returns false).
|
|
2637
|
+
* - On the very first matching call, the output channel is cleared:
|
|
2638
|
+
* • Browser → console.clear()
|
|
2639
|
+
* • Node → writes the terminal-reset sequence (\x1bc) to stdout
|
|
2640
|
+
* - On a subsequent matching call whose only value differs from the last seen
|
|
2641
|
+
* value, a separator line is printed instead of clearing.
|
|
2642
|
+
*
|
|
2643
|
+
* Returns false when the log entry should be suppressed, true otherwise.
|
|
2644
|
+
*
|
|
2645
|
+
* @param {object} context
|
|
2646
|
+
* @returns {boolean}
|
|
2647
|
+
*/
|
|
2648
|
+
#handleLocalOnly(context)
|
|
2649
|
+
{
|
|
2650
|
+
const localOnly = context.only;
|
|
2651
|
+
|
|
2652
|
+
// Helper: test a lid string against a single filter entry.
|
|
2653
|
+
const lidMatchesFilter = (filter, lid) =>
|
|
2654
|
+
{
|
|
2655
|
+
if (filter instanceof RegExp)
|
|
2656
|
+
{
|
|
2657
|
+
return filter.test(lid);
|
|
2658
|
+
}
|
|
2659
|
+
if (typeof filter === "string" || filter instanceof String)
|
|
2660
|
+
{
|
|
2661
|
+
return lid.includes(filter);
|
|
2662
|
+
}
|
|
2663
|
+
return filter === lid;
|
|
2664
|
+
};
|
|
2665
|
+
|
|
2666
|
+
// Helper: test a lid against a filter that may be a single value or an array.
|
|
2667
|
+
const lidMatchesAny = (filter, lid) => Array.isArray(filter)
|
|
2668
|
+
? filter.some((f) => lidMatchesFilter(f, lid))
|
|
2669
|
+
: lidMatchesFilter(filter, lid);
|
|
2670
|
+
|
|
2671
|
+
// Stable string label for a filter value (used for change-detection and separator text).
|
|
2672
|
+
const toLabel = (filter) => Array.isArray(filter)
|
|
2673
|
+
? filter.map((f) => (f instanceof RegExp ? f.toString() : String(f))).join(", ")
|
|
2674
|
+
: (filter instanceof RegExp ? filter.toString() : String(filter));
|
|
2675
|
+
|
|
2676
|
+
const lid = context.lid || "";
|
|
2677
|
+
|
|
2678
|
+
if (localOnly === undefined || localOnly === null)
|
|
2679
|
+
{
|
|
2680
|
+
// No local only on this call. If a filter is already active, enforce it.
|
|
2681
|
+
if (this._localOnlyFilter !== undefined)
|
|
2682
|
+
{
|
|
2683
|
+
return lidMatchesAny(this._localOnlyFilter, lid);
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
// No active filter at all – let the call through.
|
|
2687
|
+
return true;
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2690
|
+
// --- This call explicitly sets context.only ---
|
|
2691
|
+
|
|
2692
|
+
if (!lidMatchesAny(localOnly, lid))
|
|
2693
|
+
{
|
|
2694
|
+
// The lid doesn't match – suppress without clearing or printing a separator,
|
|
2695
|
+
// since the filter hasn't been "activated" by an accepted call yet.
|
|
2696
|
+
return false;
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2699
|
+
const onlyLabel = toLabel(localOnly);
|
|
2700
|
+
|
|
2701
|
+
if (this._localOnlyFilter === undefined)
|
|
2702
|
+
{
|
|
2703
|
+
// First ever match – clear the output channel.
|
|
2704
|
+
if (this.isBrowser())
|
|
2705
|
+
{
|
|
2706
|
+
/* istanbul ignore next */
|
|
2707
|
+
____AnaLogger.Console.clear
|
|
2708
|
+
? ____AnaLogger.Console.clear()
|
|
2709
|
+
: (typeof console !== "undefined" && console.clear && console.clear());
|
|
2710
|
+
}
|
|
2711
|
+
else
|
|
2712
|
+
{
|
|
2713
|
+
// ANSI terminal reset: clears the screen and moves cursor to top.
|
|
2714
|
+
process.stdout.write("\x1bc");
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
else if (this._localOnlyLabel !== onlyLabel)
|
|
2718
|
+
{
|
|
2719
|
+
// Filter has changed – print a separator, no clear.
|
|
2720
|
+
const separator = `─── only switched to ${onlyLabel} ───`;
|
|
2721
|
+
if (this.isBrowser())
|
|
2722
|
+
{
|
|
2723
|
+
/* istanbul ignore next */
|
|
2724
|
+
____AnaLogger.Console.log(`%c${separator}`, "color: #888; font-style: italic");
|
|
2725
|
+
}
|
|
2726
|
+
else
|
|
2727
|
+
{
|
|
2728
|
+
// Use the raw console so the separator bypasses all AnaLogger formatting.
|
|
2729
|
+
____AnaLogger.Console.log(separator);
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
this._localOnlyFilter = localOnly; // raw value – used for matching
|
|
2734
|
+
this._localOnlyLabel = onlyLabel; // string – used for change detection
|
|
2735
|
+
return true;
|
|
2736
|
+
}
|
|
2737
|
+
|
|
2585
2738
|
/**
|
|
2586
2739
|
* Display log following template
|
|
2587
2740
|
* @param context
|
|
@@ -2612,7 +2765,7 @@ class ____AnaLogger
|
|
|
2612
2765
|
lid: context.lid,
|
|
2613
2766
|
callCount: 1,
|
|
2614
2767
|
callTimes: [Date.now()]
|
|
2615
|
-
}
|
|
2768
|
+
};
|
|
2616
2769
|
}
|
|
2617
2770
|
}
|
|
2618
2771
|
|
|
@@ -2648,6 +2801,40 @@ class ____AnaLogger
|
|
|
2648
2801
|
return;
|
|
2649
2802
|
}
|
|
2650
2803
|
|
|
2804
|
+
// Check if global "only" filter is active
|
|
2805
|
+
if (this.options.only !== undefined && this.options.only !== null) {
|
|
2806
|
+
const onlyFilters = Array.isArray(this.options.only) ? this.options.only : [this.options.only];
|
|
2807
|
+
// Check if current log matches one of the filters
|
|
2808
|
+
const matchesFilter = onlyFilters.some((filter) => {
|
|
2809
|
+
const targetLid = context.lid || "";
|
|
2810
|
+
const targetOnly = context.only || "";
|
|
2811
|
+
|
|
2812
|
+
if (filter instanceof RegExp) {
|
|
2813
|
+
return filter.test(targetLid) || filter.test(targetOnly);
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
// String partial match (e.g., "API" matches "API_123")
|
|
2817
|
+
if (typeof filter === "string") {
|
|
2818
|
+
return targetLid.includes(filter) || targetOnly.includes(filter);
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
return filter === targetLid || filter === targetOnly;
|
|
2822
|
+
});
|
|
2823
|
+
|
|
2824
|
+
if (!matchesFilter) {
|
|
2825
|
+
return;
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2829
|
+
// Handle the per-call local "only" option.
|
|
2830
|
+
if (!this.#handleLocalOnly(context))
|
|
2831
|
+
{
|
|
2832
|
+
return;
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
// Check that "order" values are non-decreasing across calls.
|
|
2836
|
+
this.#checkOrder(context);
|
|
2837
|
+
|
|
2651
2838
|
const newMessages = this.checkOnLogging(context, argsWithoutContext[0], arguments,"onMessage");
|
|
2652
2839
|
if (newMessages !== undefined) {
|
|
2653
2840
|
arguments[1] = newMessages;
|
|
@@ -2770,6 +2957,7 @@ class ____AnaLogger
|
|
|
2770
2957
|
options.hasOwnProperty("color") ||
|
|
2771
2958
|
options.hasOwnProperty("contextName") ||
|
|
2772
2959
|
options.hasOwnProperty("raw") ||
|
|
2960
|
+
options.hasOwnProperty("only") ||
|
|
2773
2961
|
options.hasOwnProperty("lid");
|
|
2774
2962
|
}
|
|
2775
2963
|
|