LateLog - Simple storage-based Log Library

Simple library to log to the storage, granting the possibility of viewing the log after the URL changes

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/461057/1156386/LateLog%20-%20Simple%20storage-based%20Log%20Library.js

  1. // ==UserScript==
  2. // @name LateLog - Simple storage-based Log Library
  3. // @namespace satology.latelog
  4. // @version 0.2
  5. // @description Simple library to log to the storage, granting the possibility of viewing the log after the URL changes
  6. // @author satology
  7. // @grant GM_getValue
  8. // @grant GM_setValue
  9. // @grant GM_registerMenuCommand
  10. // ==/UserScript==
  11.  
  12. var LateLog = (function() {
  13. 'use strict';
  14. const latelog_getDateTimeString = (date = new Date()) => `${('' + date.getUTCFullYear()).slice(-2)}-${('0' + date.getUTCMonth()).slice(-2)}-${('0' + date.getUTCDate()).slice(-2)} ${('0' + date.getUTCHours()).slice(-2)}:${('0' + date.getUTCMinutes()).slice(-2)}:${('0' + date.getUTCSeconds()).slice(-2)}`;
  15.  
  16. class Storage {
  17. constructor(prefix = '', config = {}) {
  18. this.prefix = prefix;
  19. this.config = config;
  20. }
  21.  
  22. write(key, value, parseIt = false) {
  23. GM_setValue(this.prefix + key, parseIt ? JSON.stringify(value) : value);
  24. }
  25.  
  26. read(key, parseIt = false) {
  27. let value = GM_getValue(this.prefix + key);
  28. if(value && parseIt) {
  29. value = JSON.parse(value);
  30. }
  31. return value;
  32. }
  33. }
  34.  
  35. class LateLog {
  36. constructor(options = {}) {
  37. if(!this._isValidSetup(options)) return;
  38. this.storage = new Storage();
  39. this.options = {
  40. level: 5,
  41. maxLines: 200,
  42. addTimestamp: true,
  43. printWhileLogging: false,
  44. // showDisplayButton: true,
  45. ...options
  46. };
  47. this._init();
  48. }
  49.  
  50. _isValidSetup(options) {
  51. if(! (typeof GM_getValue === "function" &&
  52. typeof GM_setValue === "function" &&
  53. typeof GM_registerMenuCommand === "function") ) {
  54. console.warn(
  55. `LateLog cannot be initialized - At least one off the following @grant is missing in your script:
  56. @grant GM_getValue
  57. @grant GM_setValue
  58. @grant GM_registerMenuCommand`);
  59. return false;
  60. }
  61. // TODO: validate options
  62. return true;
  63. }
  64.  
  65. _init() {
  66. let that = this;
  67. GM_registerMenuCommand('View log', function(evt) {
  68. console.log('Printing LateLog');
  69. that.display();
  70. });
  71. return true;
  72. }
  73.  
  74. _write(msg, msgLevel = 1) {
  75. if (this.options.level < msgLevel) {
  76. return;
  77. }
  78.  
  79. let log = this.storage.read('log', true);
  80. log = log ? log : [];
  81.  
  82. if (msg === null) {
  83. msg = 'null';
  84. }
  85. if (msg === undefined) {
  86. msg = 'undefined';
  87. }
  88.  
  89. let savable = {
  90. lvl: msgLevel
  91. };
  92. if (this.options.addTimestamp) {
  93. savable.ts = `${latelog_getDateTimeString()}`;
  94. }
  95. if (msg instanceof Error) {
  96. savable.msg = msg.toString();
  97. } else if (typeof(msg) == 'object') {
  98. savable.msg = JSON.stringify(msg);
  99. savable.parse = true;
  100. } else {
  101. savable.msg = msg;
  102. }
  103. log.push(savable);
  104.  
  105. if(log.length > this.options.maxLines) {
  106. log.splice(0, log.length - this.options.maxLines);
  107. }
  108.  
  109. this.storage.write('log', log, true);
  110. this._formatPrint(savable);
  111. }
  112.  
  113. _getPrintFn(level) {
  114. switch(level) {
  115. case 1:
  116. return console.log;
  117. case 2:
  118. return console.info;
  119. case 3:
  120. return console.debug;
  121. case 4:
  122. return console.warn;
  123. case 5:
  124. return console.error;
  125. default:
  126. return console.log;
  127. }
  128. }
  129.  
  130. _formatPrint(x) {
  131. if (x.parse) {
  132. try {
  133. x.msg = JSON.parse(x.msg);
  134. } catch (err) {}
  135. if (this.options.addTimestamp) {
  136. this._getPrintFn(x.lvl)(`${x.ts}:`);
  137. }
  138. this._getPrintFn(x.lvl)(x.msg);
  139. } else {
  140. this._getPrintFn(x.lvl)(`${this.options.addTimestamp ? x.ts + ' ' : ''} ${x.msg}`);
  141. }
  142. }
  143.  
  144. clear() { this.storage.write('log', [], true); }
  145.  
  146. display() {
  147. let log = this.storage.read('log', true);
  148. if(!log) {
  149. console.log('LateLog - Nothing to show')
  150. return;
  151. }
  152.  
  153. log.forEach(x => {
  154. this._formatPrint(x);
  155. });
  156. }
  157.  
  158. log(msg) { this._write(msg, 1); }
  159.  
  160. info(msg) { this._write(msg, 2); }
  161.  
  162. debug(msg) { this._write(msg, 3); }
  163.  
  164. warn(msg) { this._write(msg, 4); }
  165.  
  166. error(msg) { this._write(msg, 5); }
  167. }
  168. return LateLog;
  169. })();