analogger 2.0.1 → 2.1.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.
@@ -174,6 +174,7 @@ const symbolNames = {
174
174
  relaxed : "☺",
175
175
  rewind : "⏪",
176
176
  scissors : "✂",
177
+ settings : "⚙️",
177
178
  shield : "🛡️",
178
179
  screen_with_curl : "📜",
179
180
  snowman : "☃",
@@ -408,7 +409,7 @@ function createTarGzArchiveSync(inputFile, archivePath, compressionLevel = 1) {
408
409
  fs.rmSync(tempDir, { recursive: true, force: true });
409
410
  }
410
411
  } catch (err) {
411
- console.error(`ARCHIVE_FAILURE: ${e.message}`);
412
+ console.error(`ARCHIVE_FAILURE: ${err.message}`);
412
413
  }
413
414
  }
414
415
 
@@ -612,6 +613,7 @@ const COMMON_METHODS = [
612
613
  "setLogFormat",
613
614
  "resetLogFormatter",
614
615
  "getRawLogHistory",
616
+ "restoreLogs",
615
617
  ];
616
618
 
617
619
 
@@ -936,6 +938,8 @@ class ____AnaLogger
936
938
  this.options.pathname = undefined;
937
939
  this.options.binarypathname = undefined;
938
940
  this.options.enableDate = undefined;
941
+ this.options.logToLocalStorage = undefined;
942
+ this.options.logToLocalStorageMax = 50;
939
943
  }
940
944
 
941
945
  resetOptions()
@@ -948,6 +952,7 @@ class ____AnaLogger
948
952
  idLenMax = 5,
949
953
  lidLenMax = 6,
950
954
  symbolLenMax = 2,
955
+ enableTrace = true,
951
956
  messageLenMax = undefined,
952
957
  hideLog = undefined,
953
958
  hideError = undefined,
@@ -970,6 +975,8 @@ class ____AnaLogger
970
975
  oneConsolePerContext = undefined,
971
976
  silent = undefined,
972
977
  enableDate = undefined,
978
+ logToLocalStorage = undefined,
979
+ logToLocalStorageMax = 50,
973
980
  /** Remote - all optional **/
974
981
  protocol = undefined,
975
982
  host = undefined,
@@ -994,6 +1001,9 @@ class ____AnaLogger
994
1001
  this.options.compressionLevel = compressionLevel;
995
1002
 
996
1003
  this.options.requiredLogLevel = requiredLogLevel;
1004
+ this.options.enableTrace = enableTrace;
1005
+
1006
+ this.options.logToLocalStorageMax = logToLocalStorageMax;
997
1007
 
998
1008
  if (loadHtmlToImage) {
999
1009
  const code = getHtmlToImage();
@@ -1020,6 +1030,7 @@ class ____AnaLogger
1020
1030
  {hideHookMessage},
1021
1031
  {hidePassingTests},
1022
1032
  {logToRemote},
1033
+ {logToLocalStorage},
1023
1034
  ].forEach((feature) =>
1024
1035
  {
1025
1036
  const key = Object.keys(feature)[0];
@@ -1102,6 +1113,10 @@ class ____AnaLogger
1102
1113
 
1103
1114
  }
1104
1115
 
1116
+ updateOptions(options) {
1117
+ this.setOptions({...this.options, ...options});
1118
+ }
1119
+
1105
1120
  getOptions()
1106
1121
  {
1107
1122
  return this.options;
@@ -1653,6 +1668,26 @@ class ____AnaLogger
1653
1668
  return this.activeTargets.includes(target);
1654
1669
  }
1655
1670
 
1671
+ // Get current time in HH:MM:SS format
1672
+ getCurrentTime() {
1673
+ const now = new Date();
1674
+ const hours = String(now.getHours()).padStart(2, '0');
1675
+ const minutes = String(now.getMinutes()).padStart(2, '0');
1676
+ const seconds = String(now.getSeconds()).padStart(2, '0');
1677
+
1678
+ return `${hours}:${minutes}:${seconds}`;
1679
+ }
1680
+
1681
+ // Get current date in DD:MM:YY format
1682
+ getCurrentDate() {
1683
+ const now = new Date();
1684
+ const day = String(now.getDate()).padStart(2, '0');
1685
+ const month = String(now.getMonth() + 1).padStart(2, '0'); // Months are 0-based
1686
+ const year = String(now.getFullYear()).slice(-2); // Get last 2 digits of year
1687
+
1688
+ return `${day}-${month}-${year}`;
1689
+ }
1690
+
1656
1691
 
1657
1692
  // ------------------------------------------------
1658
1693
  // Logging methods
@@ -1665,21 +1700,42 @@ class ____AnaLogger
1665
1700
  */
1666
1701
  setColumns($line, context, text)
1667
1702
  {
1668
- let index = 0;
1703
+ let index = 1;
1704
+ let $addTime = false;
1669
1705
  for (let columnName in context)
1670
1706
  {
1671
- if (!["contextName", "symbol", "lid", "text"].includes(columnName))
1707
+ if (!["contextName", "symbol", "lid", "text", "enableDate", "enableTime"].includes(columnName))
1672
1708
  {
1673
1709
  continue;
1674
1710
  }
1675
1711
 
1676
- const colContent = context[columnName];
1712
+ let colContent = context[columnName];
1713
+ if (columnName === "enableDate") {
1714
+ colContent = this.getCurrentDate() + " " + this.getCurrentTime();
1715
+ }
1716
+
1717
+ if (columnName === "enableTime") {
1718
+ colContent = this.getCurrentTime();
1719
+ }
1720
+
1677
1721
  const $col = document.createElement("span");
1678
1722
  $col.classList.add("analogger-col", `analogger-col-${columnName}`, `analogger-col-${index}`);
1679
1723
  ++index;
1724
+
1725
+ if (columnName !== "enableDate" && columnName !== "enableTime") {
1680
1726
  $col.textContent = colContent;
1681
1727
  $line.append($col);
1682
1728
  }
1729
+ else {
1730
+ $col.textContent = `[${colContent}]`;
1731
+ $addTime = $col;
1732
+ }
1733
+ }
1734
+
1735
+ if ($addTime) {
1736
+ $addTime.classList.add("analogger-col", `analogger-col-time`, `analogger-col-0`);
1737
+ $line.prepend($addTime);
1738
+ }
1683
1739
 
1684
1740
  let $col = document.createElement("span");
1685
1741
  $col.classList.add("analogger-col", "analogger-col-text", `analogger-col-${index}`);
@@ -1969,6 +2025,91 @@ class ____AnaLogger
1969
2025
  }
1970
2026
  }
1971
2027
 
2028
+ writeLogToLocalStorage(context, ...args)
2029
+ {
2030
+ try
2031
+ {
2032
+ if (!this.isBrowser() || !window.localStorage)
2033
+ {
2034
+ return;
2035
+ }
2036
+
2037
+ const key = `analogger_history_${this.instanceName}`;
2038
+ let history = [];
2039
+ try
2040
+ {
2041
+ const stored = localStorage.getItem(key);
2042
+ if (stored)
2043
+ {
2044
+ history = JSON.parse(stored);
2045
+ }
2046
+ }
2047
+ catch (e)
2048
+ {
2049
+ history = [];
2050
+ }
2051
+
2052
+ history.push({context, args});
2053
+
2054
+ const max = this.options.logToLocalStorageMax || 50;
2055
+ if (history.length > max)
2056
+ {
2057
+ history = history.slice(history.length - max);
2058
+ }
2059
+
2060
+ localStorage.setItem(key, JSON.stringify(history));
2061
+ }
2062
+ catch (e)
2063
+ {
2064
+ /* istanbul ignore next */
2065
+ ____AnaLogger.Console.error("LOG_TO_LOCAL_STORAGE_FAILURE: ", e.message);
2066
+ }
2067
+ }
2068
+
2069
+ restoreLogs()
2070
+ {
2071
+ try
2072
+ {
2073
+ if (!this.isBrowser() || !window.localStorage)
2074
+ {
2075
+ return;
2076
+ }
2077
+
2078
+ const key = `analogger_history_${this.instanceName}`;
2079
+ const stored = localStorage.getItem(key);
2080
+ if (!stored)
2081
+ {
2082
+ return;
2083
+ }
2084
+
2085
+ const history = JSON.parse(stored);
2086
+ if (!Array.isArray(history))
2087
+ {
2088
+ return;
2089
+ }
2090
+
2091
+ // Temporarily disable logging to local storage to avoid infinite loop
2092
+ const originalLogToLocalStorage = this.options.logToLocalStorage;
2093
+ this.options.logToLocalStorage = false;
2094
+
2095
+ history.forEach((entry) =>
2096
+ {
2097
+ const {context, args} = entry;
2098
+ if (context) {
2099
+ context.symbol = "floppy_disk";
2100
+ }
2101
+ this.processOutput(context, ...args);
2102
+ });
2103
+
2104
+ this.options.logToLocalStorage = originalLogToLocalStorage;
2105
+ }
2106
+ catch (e)
2107
+ {
2108
+ /* istanbul ignore next */
2109
+ ____AnaLogger.Console.error("RESTORE_LOGS_FAILURE: ", e.message);
2110
+ }
2111
+ }
2112
+
1972
2113
  /**
1973
2114
  * Send data to the registered remote server
1974
2115
  * @param raw
@@ -2371,6 +2512,11 @@ class ____AnaLogger
2371
2512
  this.writeLogToRemote(context, ...args);
2372
2513
  }
2373
2514
 
2515
+ if (this.options.logToLocalStorage)
2516
+ {
2517
+ this.writeLogToLocalStorage(context, ...args);
2518
+ }
2519
+
2374
2520
  /* istanbul ignore next */
2375
2521
  if (this.isBrowser())
2376
2522
  {
@@ -2677,6 +2823,10 @@ class ____AnaLogger
2677
2823
  context.stack = getInvocationLine();
2678
2824
  }
2679
2825
  this.log(context, ...args);
2826
+
2827
+ if (this.options.enableTrace) {
2828
+ console.trace(...args);
2829
+ }
2680
2830
  }
2681
2831
 
2682
2832
  overrideError()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "analogger",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "Js Logger",
5
5
  "main": "./src/ana-logger.cjs",
6
6
  "module": "./esm/src/ana-logger.mjs",
@@ -160,6 +160,7 @@ const symbolNames = {
160
160
  relaxed : "☺",
161
161
  rewind : "⏪",
162
162
  scissors : "✂",
163
+ settings : "⚙️",
163
164
  shield : "🛡️",
164
165
  screen_with_curl : "📜",
165
166
  snowman : "☃",
@@ -394,7 +395,7 @@ function createTarGzArchiveSync(inputFile, archivePath, compressionLevel = 1) {
394
395
  fs.rmSync(tempDir, { recursive: true, force: true });
395
396
  }
396
397
  } catch (err) {
397
- console.error(`ARCHIVE_FAILURE: ${e.message}`);
398
+ console.error(`ARCHIVE_FAILURE: ${err.message}`);
398
399
  }
399
400
  }
400
401
 
@@ -598,6 +599,7 @@ const COMMON_METHODS = [
598
599
  "setLogFormat",
599
600
  "resetLogFormatter",
600
601
  "getRawLogHistory",
602
+ "restoreLogs",
601
603
  ];
602
604
 
603
605
 
@@ -922,6 +924,8 @@ class ____AnaLogger
922
924
  this.options.pathname = undefined;
923
925
  this.options.binarypathname = undefined;
924
926
  this.options.enableDate = undefined;
927
+ this.options.logToLocalStorage = undefined;
928
+ this.options.logToLocalStorageMax = 50;
925
929
  }
926
930
 
927
931
  resetOptions()
@@ -934,6 +938,7 @@ class ____AnaLogger
934
938
  idLenMax = 5,
935
939
  lidLenMax = 6,
936
940
  symbolLenMax = 2,
941
+ enableTrace = true,
937
942
  messageLenMax = undefined,
938
943
  hideLog = undefined,
939
944
  hideError = undefined,
@@ -956,6 +961,8 @@ class ____AnaLogger
956
961
  oneConsolePerContext = undefined,
957
962
  silent = undefined,
958
963
  enableDate = undefined,
964
+ logToLocalStorage = undefined,
965
+ logToLocalStorageMax = 50,
959
966
  /** Remote - all optional **/
960
967
  protocol = undefined,
961
968
  host = undefined,
@@ -980,6 +987,9 @@ class ____AnaLogger
980
987
  this.options.compressionLevel = compressionLevel;
981
988
 
982
989
  this.options.requiredLogLevel = requiredLogLevel;
990
+ this.options.enableTrace = enableTrace;
991
+
992
+ this.options.logToLocalStorageMax = logToLocalStorageMax;
983
993
 
984
994
  if (loadHtmlToImage) {
985
995
  const code = getHtmlToImage();
@@ -1006,6 +1016,7 @@ class ____AnaLogger
1006
1016
  {hideHookMessage},
1007
1017
  {hidePassingTests},
1008
1018
  {logToRemote},
1019
+ {logToLocalStorage},
1009
1020
  ].forEach((feature) =>
1010
1021
  {
1011
1022
  const key = Object.keys(feature)[0];
@@ -1090,6 +1101,10 @@ class ____AnaLogger
1090
1101
 
1091
1102
  }
1092
1103
 
1104
+ updateOptions(options) {
1105
+ this.setOptions({...this.options, ...options});
1106
+ }
1107
+
1093
1108
  getOptions()
1094
1109
  {
1095
1110
  return this.options;
@@ -1641,6 +1656,26 @@ class ____AnaLogger
1641
1656
  return this.activeTargets.includes(target);
1642
1657
  }
1643
1658
 
1659
+ // Get current time in HH:MM:SS format
1660
+ getCurrentTime() {
1661
+ const now = new Date();
1662
+ const hours = String(now.getHours()).padStart(2, '0');
1663
+ const minutes = String(now.getMinutes()).padStart(2, '0');
1664
+ const seconds = String(now.getSeconds()).padStart(2, '0');
1665
+
1666
+ return `${hours}:${minutes}:${seconds}`;
1667
+ }
1668
+
1669
+ // Get current date in DD:MM:YY format
1670
+ getCurrentDate() {
1671
+ const now = new Date();
1672
+ const day = String(now.getDate()).padStart(2, '0');
1673
+ const month = String(now.getMonth() + 1).padStart(2, '0'); // Months are 0-based
1674
+ const year = String(now.getFullYear()).slice(-2); // Get last 2 digits of year
1675
+
1676
+ return `${day}-${month}-${year}`;
1677
+ }
1678
+
1644
1679
 
1645
1680
  // ------------------------------------------------
1646
1681
  // Logging methods
@@ -1653,21 +1688,42 @@ class ____AnaLogger
1653
1688
  */
1654
1689
  setColumns($line, context, text)
1655
1690
  {
1656
- let index = 0;
1691
+ let index = 1;
1692
+ let $addTime = false;
1657
1693
  for (let columnName in context)
1658
1694
  {
1659
- if (!["contextName", "symbol", "lid", "text"].includes(columnName))
1695
+ if (!["contextName", "symbol", "lid", "text", "enableDate", "enableTime"].includes(columnName))
1660
1696
  {
1661
1697
  continue;
1662
1698
  }
1663
1699
 
1664
- const colContent = context[columnName];
1700
+ let colContent = context[columnName];
1701
+ if (columnName === "enableDate") {
1702
+ colContent = this.getCurrentDate() + " " + this.getCurrentTime();
1703
+ }
1704
+
1705
+ if (columnName === "enableTime") {
1706
+ colContent = this.getCurrentTime();
1707
+ }
1708
+
1665
1709
  const $col = document.createElement("span");
1666
1710
  $col.classList.add("analogger-col", `analogger-col-${columnName}`, `analogger-col-${index}`);
1667
1711
  ++index;
1712
+
1713
+ if (columnName !== "enableDate" && columnName !== "enableTime") {
1668
1714
  $col.textContent = colContent;
1669
1715
  $line.append($col);
1670
1716
  }
1717
+ else {
1718
+ $col.textContent = `[${colContent}]`;
1719
+ $addTime = $col;
1720
+ }
1721
+ }
1722
+
1723
+ if ($addTime) {
1724
+ $addTime.classList.add("analogger-col", `analogger-col-time`, `analogger-col-0`);
1725
+ $line.prepend($addTime);
1726
+ }
1671
1727
 
1672
1728
  let $col = document.createElement("span");
1673
1729
  $col.classList.add("analogger-col", "analogger-col-text", `analogger-col-${index}`);
@@ -1957,6 +2013,91 @@ class ____AnaLogger
1957
2013
  }
1958
2014
  }
1959
2015
 
2016
+ writeLogToLocalStorage(context, ...args)
2017
+ {
2018
+ try
2019
+ {
2020
+ if (!this.isBrowser() || !window.localStorage)
2021
+ {
2022
+ return;
2023
+ }
2024
+
2025
+ const key = `analogger_history_${this.instanceName}`;
2026
+ let history = [];
2027
+ try
2028
+ {
2029
+ const stored = localStorage.getItem(key);
2030
+ if (stored)
2031
+ {
2032
+ history = JSON.parse(stored);
2033
+ }
2034
+ }
2035
+ catch (e)
2036
+ {
2037
+ history = [];
2038
+ }
2039
+
2040
+ history.push({context, args});
2041
+
2042
+ const max = this.options.logToLocalStorageMax || 50;
2043
+ if (history.length > max)
2044
+ {
2045
+ history = history.slice(history.length - max);
2046
+ }
2047
+
2048
+ localStorage.setItem(key, JSON.stringify(history));
2049
+ }
2050
+ catch (e)
2051
+ {
2052
+ /* istanbul ignore next */
2053
+ ____AnaLogger.Console.error("LOG_TO_LOCAL_STORAGE_FAILURE: ", e.message);
2054
+ }
2055
+ }
2056
+
2057
+ restoreLogs()
2058
+ {
2059
+ try
2060
+ {
2061
+ if (!this.isBrowser() || !window.localStorage)
2062
+ {
2063
+ return;
2064
+ }
2065
+
2066
+ const key = `analogger_history_${this.instanceName}`;
2067
+ const stored = localStorage.getItem(key);
2068
+ if (!stored)
2069
+ {
2070
+ return;
2071
+ }
2072
+
2073
+ const history = JSON.parse(stored);
2074
+ if (!Array.isArray(history))
2075
+ {
2076
+ return;
2077
+ }
2078
+
2079
+ // Temporarily disable logging to local storage to avoid infinite loop
2080
+ const originalLogToLocalStorage = this.options.logToLocalStorage;
2081
+ this.options.logToLocalStorage = false;
2082
+
2083
+ history.forEach((entry) =>
2084
+ {
2085
+ const {context, args} = entry;
2086
+ if (context) {
2087
+ context.symbol = "floppy_disk";
2088
+ }
2089
+ this.processOutput(context, ...args);
2090
+ });
2091
+
2092
+ this.options.logToLocalStorage = originalLogToLocalStorage;
2093
+ }
2094
+ catch (e)
2095
+ {
2096
+ /* istanbul ignore next */
2097
+ ____AnaLogger.Console.error("RESTORE_LOGS_FAILURE: ", e.message);
2098
+ }
2099
+ }
2100
+
1960
2101
  /**
1961
2102
  * Send data to the registered remote server
1962
2103
  * @param raw
@@ -2359,6 +2500,11 @@ class ____AnaLogger
2359
2500
  this.writeLogToRemote(context, ...args);
2360
2501
  }
2361
2502
 
2503
+ if (this.options.logToLocalStorage)
2504
+ {
2505
+ this.writeLogToLocalStorage(context, ...args);
2506
+ }
2507
+
2362
2508
  /* istanbul ignore next */
2363
2509
  if (this.isBrowser())
2364
2510
  {
@@ -2665,6 +2811,10 @@ class ____AnaLogger
2665
2811
  context.stack = getInvocationLine();
2666
2812
  }
2667
2813
  this.log(context, ...args);
2814
+
2815
+ if (this.options.enableTrace) {
2816
+ console.trace(...args);
2817
+ }
2668
2818
  }
2669
2819
 
2670
2820
  overrideError()
package/src/constants.cjs CHANGED
@@ -1,50 +1,50 @@
1
- const constants = {
2
- COLOR_TABLE: [
3
- "#d2466e", // Error context color
4
- "#FFA07A", // Default context color
5
- "#FF7F50",
6
- "#FF6347",
7
- "#FFE4B5",
8
- "#ADFF2F",
9
- "#808000",
10
- "#40E0D0",
11
- "#1E90FF",
12
- "#EE82EE",
13
- "#708090",
14
- "#DEB887",
15
- "#FE642E",
16
- "#210B61",
17
- "#088A4B",
18
- "#5E610B",
19
- "#FA8258",
20
- "#088A68",
21
- "#B40431",
22
- ],
23
- SYSTEM: {
24
- BROWSER: "BROWSER",
25
- NODE: "NODE"
26
- }
27
-
28
- };
29
-
30
- module.exports.COLOR_TABLE = constants.COLOR_TABLE;
31
- module.exports.SYSTEM = constants.SYSTEM;
32
- module.exports.MAX_CHILDREN_DOM_ANALOGGER = 2000;
33
- module.exports.CLASS_REMOVED_NOTIF = "analogger-removed-notif";
34
- module.exports.CONSOLE_HEADER_CLASSNAME = "analogger-header";
35
- module.exports.CONSOLE_AREA_CLASSNAME = "analogger-view";
36
- module.exports.CONSOLE_FOOTER_CLASSNAME = "analogger-footer";
37
- module.exports.LINE_CLASSNAME = "to-esm-line";
38
-
39
- module.exports.ADD_TYPE = {
40
- TOP: "TOP",
41
- BOTTOM: "BOTTOM"
42
- };
43
-
44
- const ANALOGGER_NAME = "ANALOGGER";
45
-
46
- module.exports.ANALOGGER_NAME = ANALOGGER_NAME;
47
-
48
- module.exports.PREDEFINED_FORMATS = {
49
- DEFAULT_FORMAT: "FORMAT1"
50
- };
1
+ const constants = {
2
+ COLOR_TABLE: [
3
+ "#d2466e", // Error context color
4
+ "#FFA07A", // Default context color
5
+ "#FF7F50",
6
+ "#FF6347",
7
+ "#FFE4B5",
8
+ "#ADFF2F",
9
+ "#808000",
10
+ "#40E0D0",
11
+ "#1E90FF",
12
+ "#EE82EE",
13
+ "#708090",
14
+ "#DEB887",
15
+ "#FE642E",
16
+ "#210B61",
17
+ "#088A4B",
18
+ "#5E610B",
19
+ "#FA8258",
20
+ "#088A68",
21
+ "#B40431",
22
+ ],
23
+ SYSTEM: {
24
+ BROWSER: "BROWSER",
25
+ NODE: "NODE"
26
+ }
27
+
28
+ };
29
+
30
+ module.exports.COLOR_TABLE = constants.COLOR_TABLE;
31
+ module.exports.SYSTEM = constants.SYSTEM;
32
+ module.exports.MAX_CHILDREN_DOM_ANALOGGER = 2000;
33
+ module.exports.CLASS_REMOVED_NOTIF = "analogger-removed-notif";
34
+ module.exports.CONSOLE_HEADER_CLASSNAME = "analogger-header";
35
+ module.exports.CONSOLE_AREA_CLASSNAME = "analogger-view";
36
+ module.exports.CONSOLE_FOOTER_CLASSNAME = "analogger-footer";
37
+ module.exports.LINE_CLASSNAME = "to-esm-line";
38
+
39
+ module.exports.ADD_TYPE = {
40
+ TOP: "TOP",
41
+ BOTTOM: "BOTTOM"
42
+ };
43
+
44
+ const ANALOGGER_NAME = "ANALOGGER";
45
+
46
+ module.exports.ANALOGGER_NAME = ANALOGGER_NAME;
47
+
48
+ module.exports.PREDEFINED_FORMATS = {
49
+ DEFAULT_FORMAT: "FORMAT1"
50
+ };