{"version":3,"sources":["../src/index.ts","../src/lib/logger.ts"],"sourcesContent":["export * from './lib/logger'\n","import { isBrowser, isNode } from 'browser-or-node'\nimport stringify from 'fast-json-stable-stringify'\n\n////////////\n// CONFIG //\n////////////\n\n//(i) disabled by default bc. the detection logic has disappeared after the refactor.\n//TODO: Find it and check if it works\nlet TIME_PREFIX_ENABLED = false\nlet PERFORMANCE_PREFIX_ENABLED = false\nif (isNode) {\n  // console.debug('isNode checking', { process })\n  if (process?.env?.LOGGER_TIME_PREFIX) TIME_PREFIX_ENABLED = process?.env?.LOGGER_TIME_PREFIX === 'true'\n  if (process?.env?.LOGGER_PERF_PREFIX) PERFORMANCE_PREFIX_ENABLED = process?.env?.LOGGER_PERF_PREFIX === 'true'\n}\nexport let LOGGER_DEFAULT_CONFIG = {\n  prefix: undefined as string | undefined,\n  time: TIME_PREFIX_ENABLED,\n  delta: PERFORMANCE_PREFIX_ENABLED,\n  dimDebugOnServer: true,\n  printOriginOnServer: true,\n  serverInspectOptions: {},\n  customFormattersOnServer: true,\n  // Depth of stacktrace to show on server\n  // - integer saying how many lines\n  // - false to disable, true for all\n  printStackLinesOnServer: false as boolean | number,\n  dim: true,\n}\n\nexport type Config = Partial<typeof LOGGER_DEFAULT_CONFIG>\nexport type ConsoleFx = (...data: any[]) => void\nexport const StringFormatters = [\n  // Format to string (Client console - currently not on server)\n  // {\n  //   match: obj => obj instanceof Model,\n  //   format: m => {\n  //     const { displayName } = m\n  //     return `${m.constructor.name}#${m.ID}${displayName ? `{${displayName}}` : ''}`\n  //   },\n  // },\n] as unknown as {\n  match: (obj: any) => boolean\n  format: (m: any) => string\n}[]\n\n// let applyCustomFormatters;\n// applyCustomFormatters = (value, config) => {\n//   for (const formatter of StringFormatters) {\n//     if (formatter.match(value)) return formatter.format(value);\n//   }\n//   if (!_.isString(value)) {\n//     return util.inspect(value, config.inspectOptionsOnServer);\n//   }\n//   return value;\n// };\n\n/// ////////////////\n// RUNTIME STUFF //\n/// ////////////////\n\nexport class LoggerTime {\n  sinceFirst = 0\n  sinceLast = 0\n  time = false\n  delta = false\n  constructor(sinceFirst: number, sinceLast: number, time: boolean, delta: boolean) {\n    Object.assign(this, { sinceFirst, sinceLast, time, delta })\n  }\n\n  toString() {\n    const sinceFirstNum = (this.sinceFirst * 0.001)\n    const sinceFirst = sinceFirstNum.toFixed(sinceFirstNum < 5 ? 2 : 1) /* .padStart(3, ' ') */\n    const sinceLast\n      = this.sinceLast < 1000 // when >= 1s, format as seconds\n        ? `${this.sinceLast.toFixed(0)}`.padStart(5, ' ')\n        : `${`${(this.sinceLast * 0.001).toFixed(this.sinceLast < 10000 ? 1 : 0)}`.padStart(4, ' ')}s`\n    return `[${[this.time ? sinceFirst : null, this.delta ? sinceLast : null]\n      .filter(t => t != null)\n      .join(',')}]`\n  }\n}\n\nexport class Style {\n  constructor(style: string, string: string) {\n    Object.assign(this, { style, string })\n  }\n}\nlet formattersEnabled = false // for tracking if chrome formatters are enabled (don't change manually)\n\nexport class Logger {\n  static ERROR = 2 as const\n  static WARN = 4 as const\n  static INFO = 6 as const // alias for LOG\n  static LOG = 6 as const\n  static DEBUG = 8 as const\n  static VERBOSE = 10 as const\n\n  static firstLog = 0\n  static lastLog = 0\n\n  /**\n   * This is a clever way to log without the extra check on each log line.\n   * Use it like this:\n   * ```\n   * const { WARN, LOG, DEBUG, VERBOSE } = Logger.setup(Logger.INFO); // eslint-disable-line no-unused-vars\n   * LOG('message', data);\n   * DEBUG(this.collectionName, '...')\n   * if (!VERBOSE.isDisabled) {\n   *   const verboseStuff = generateVerboseStuff(); // computationally intensive\n   *   VERBOSE('Here it is:', verboseStuff)\n   * }\n   * ```\n   *\n   * @ param {number} level See {@link LVs}\n   * @ param {object} config see LOGGER_DEFAULT_CONFIG\n   * @ typedef {Function & {isDisabled: boolean, isEnabled: boolean, ...}} LogFunc\n   * @ returns {{LOG: LogFunc, VERBOSE: LogFunc, DEBUG: LogFunc, WARN: LogFunc, ERROR: LogFunc}}\n   */\n  static setup(level: 2 | 4 | 6 | 8 | 10 = Logger.INFO, config: Config = {}) {\n    config = Object.assign({}, LOGGER_DEFAULT_CONFIG, config) //  defaults(config, LOGGER_DEFAULT_CONFIG) // fyi this is like the reverse of Object.assign\n    if (level > 10) console.debug('setup logger', { config }) // manual overide to level:11 to show this trace\n\n    const debugLogForStub = this.wrapLog(console.debug, { ...config, dim: config.dimDebugOnServer })\n    const stub = (...args: any[]) => {\n      // @ts-expect-error hack to enable DEBUG logging EVERYWHERE\n      if (typeof window !== 'undefined' && window?.FORCE_DISABLE_LOGLEVEL)\n        debugLogForStub(...args)\n    } // For disabled log-levels, we just return a stub function\n    stub.isDisabled = true // this makes it possible to check, e.g. `DEBUG.isDisabled`\n    stub.isEnabled = false // depending on syntactic preference\n    const groupCollapsed = this.wrapLog(console.groupCollapsed, config)\n\n    const addExtraFxs = (enabled: boolean, func: (...T: any) => void) =>/* : ((...T) => void & {isDisabled: boolean}) */ {\n      // warning - weird TS hacks approaching:\n      function group<T extends Func>(\n        ...args: [...any[], T]\n      ): ReturnType<T> extends Promise<any> ? Promise<ReturnType<T>> : ReturnType<T> {\n        const functionToWrap = args[args.length - 1] as T\n\n        if (functionToWrap as Func === stub)\n          return functionToWrap() as ReturnType<T>\n\n        groupCollapsed(...args.slice(0, -1)) // except last\n\n        const asyncWrapper = async () => {\n          try {\n            const result = functionToWrap()\n            return result instanceof Promise ? await result : result\n          } finally {\n            console.groupEnd()\n          }\n        }\n\n        return asyncWrapper() as ReturnType<T> // Cast to bypass the Promise type inference\n      }\n\n      const realFunc = Object.assign(\n        func.bind({}), // clone function - https://stackoverflow.com/a/6772648\n        {\n          isEnabled: enabled,\n          isDisabled: !enabled,\n          group,\n          force: func,\n        },\n      )\n      if (enabled) {\n        return realFunc\n      } else {\n        return Object.assign(\n          stub.bind({}), // clone stub function - https://stackoverflow.com/a/6772648\n          {\n            isEnabled: enabled,\n            isDisabled: !enabled,\n            group,\n            force: realFunc,\n          },\n        )\n      }\n    }\n\n    const ERRFX = addExtraFxs(level >= Logger.ERROR, this.wrapLog(console.error, config))\n    const ERROR = (...params: any[]) => {\n      ERRFX(...params)\n      // return so we can log & throw in one go\n      return new Error(params.map(param => {\n        return typeof param === 'string' ? param : stringify(param) // stringify is fast & safe with circular references\n      }).join(' '))\n    }\n\n    // console.debug(\"Logger init:\", config)\n    return {\n      ERROR,\n      WARN: addExtraFxs(level >= Logger.WARN, this.wrapLog(console.warn, config)),\n      LOG: addExtraFxs(level >= Logger.INFO, this.wrapLog(console.log, config)),\n      DEBUG: addExtraFxs(level >= Logger.DEBUG, this.wrapLog(console.log, { ...config, dim: config.dimDebugOnServer })), // not using console.debug as that requires dev tools verbose to be enabled\n      VERBOSE: addExtraFxs(level >= Logger.VERBOSE, this.wrapLog(console.debug, { ...config, dim: config.dimDebugOnServer })),\n    }\n  }\n\n  static wrapLog(logFunc: ConsoleFx, config: Config) {\n    if (!isNode) {\n      // ℹ In browser we can only do some of the fancy things, because we cannot call console.log ourselves,\n      // as that would pollute the stacktrace\n\n      // ℹ Would be nice to get formtted links in devtools, but <a> tags are not allowed:\n      // const stack = new Error().stack;\n      // const origin = Logger.getOriginFromStack(stack);\n      // const originFilename = origin.split('\\\\').pop().split('/').pop(); // eslint-disable-line\n      // if (origin) fixedArgs.push({ link: originFilename, href: `http://localhost:63342/api/file/${origin}` });\n\n      // on the client, we need to return the original log function, as otherwise the origin of the log is set to here\n      // But luckily we can bind fixed parameters on the function:\n      const fixedArgs = []\n      // if the custom formatters are enabled, and we want performance logging - we add an instance of P as a static prefix\n      if (config.time || config.delta) {\n        const isChrome = isBrowser && navigator.userAgent.includes('Chrome')\n\n        const p = isChrome\n          ? ['', Logger.timeStr(!!config.time, !!config.delta)] // this is a placeholder that gets replaced by the custom formatter\n          : [] // [{ get perfNiceTry () { return Logger.timeStr(,,true) } }] // this (of course) shows the time when you click the getter\n        fixedArgs.push(...p) // if we start with a non-string, all strings are rendered with quotes :/\n      }\n      if (config.prefix) {\n        if (formattersEnabled)\n          fixedArgs.push(new Style('dim', config.prefix))\n        else fixedArgs.push(config.prefix)\n      }\n      // console.log('logger-log', { config, fixedArgs })\n      return logFunc.bind(console, ...fixedArgs)\n    } else {\n      // ℹ in nodejs we print the stack trace origin ourselves, so we can do a lot more things\n      // TODO: re-import removed code - https://gitlab.com/onezoomin/ztax/ztax/-/commit/f6f9bde617cd9ae93d1bc4bc49a4b5275e4cbff2#b1d1e091ca27ae560becf7ae1b27a4d53d39c061\n      return logFunc.bind(console)\n    }\n  }\n\n  // static log(msg, logPerformance = true) {\n  //   const p = this.perf();\n  //   return logPerformance ? `${p} ${msg}` : msg;\n  // }\n\n  static timeStr(time: boolean, delta: boolean, returnAsString = 0): LoggerTime | string | undefined {\n    if (!performance.now)\n      return undefined // TODO: server? p = { now: require('performance-now') };\n    const now = performance.now()\n    if (!Logger.firstLog) {\n      Logger.firstLog = now\n      Logger.lastLog = now\n    }\n    const p = new LoggerTime(now - Logger.firstLog, now - Logger.lastLog, time, delta)\n    Logger.lastLog = now\n    return returnAsString ? p.toString() : p\n  }\n\n  // (for nodejs) ~ https://stackoverflow.com/a/47296370/1633985\n  static getOriginFromStack(stack: any): string | undefined {\n    let skippedFirst = false // the first one is Logger.js\n    for (const line of stack.split('\\n')) {\n      const matches = line.match(/^\\s+at\\s+(.*)/)\n      if (matches) {\n        if (skippedFirst) {\n          // first line - current function\n          // second line - caller (what we are looking for)\n          return (\n            matches[1]\n              .trim() // Removes spaces\n              // .replace(/^module /, '') // Removes 'module ' at beginning\n              // .replace(/^at /, '') // Removes 'at ' at beginning\n              // .replace(/^ \\(/, '') // Removes parentheseses around file\n              // .replace(/\\)$/, '') // -||-\n              .replace(__dirname, '') // Removes script folder path (if exists)\n          )\n        }\n        skippedFirst = true\n      }\n    }\n  }\n}\n\nif (isBrowser) { // isBrowser is not true for web workers\n  // CLIENT or Worker //\n\n  // @ts-expect-error window hack\n  window.devtoolsFormatters = window.devtoolsFormatters ?? []\n  // noinspection JSUnusedGlobalSymbols\n  // @ts-expect-error window hack\n  window.devtoolsFormatters.push(\n    {\n      // Custom formatters\n      header: (obj: any) => {\n        if (StringFormatters && StringFormatters.length) {\n          for (const formatter of StringFormatters) {\n            if (formatter.match(obj))\n              return ['span', {}, formatter.format(obj)]\n          }\n        }\n        return null\n      },\n      hasBody: () => true,\n    },\n    {\n      // Performance object //\n      // This is a sneaky way to show performance info withouth any extra calls when logging:\n      // LOG(`...`)\n      // it would work without this if we would have some way to intercept the call:\n      // L.INFO('...') - a getter on L that adds the current time as prefix\n      // LOG('...')() - returns the log function with all argumends bound\n      // But instead we are adding a custom formatter that replaced the placeholder object of class P with the performance info\n      header: (obj: any) => {\n        if (!(obj instanceof LoggerTime))\n          return null\n        if (!formattersEnabled)\n          formattersEnabled = true\n        const p = Logger.timeStr(obj.time, obj.delta)\n        return [\n          'span',\n          { style: 'font-weight: light; color: grey' },\n          p?.toString(),\n          // ['a', { href: 'vscodium://file/home/manu/dev/tamera/bookr/imports/lib/utils/Logger.js' }, 'WOW'],\n        ]\n      },\n      hasBody: () => false,\n    },\n    {\n      // Style object\n      header: (obj: { string: any }) => {\n        if (!(obj instanceof Style))\n          return null\n        if (!formattersEnabled)\n          formattersEnabled = true\n        return ['span', { style: 'font-weight: light; color: grey; '/* font-style: italic; */ }, obj.string]\n      },\n      hasBody: () => false,\n    },\n  )\n}\nelse if (isNode) {\n  // SERVER //\n  // node stuff removed as it breaks/bloats webworker build\n}\n\nexport function logriniTest(): string {\n  return 'logrini'\n}\n\ntype Func<T = any> = () => T\n"],"mappings":"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","names":["src_exports","__export","LOGGER_DEFAULT_CONFIG","Logger","LoggerTime","StringFormatters","Style","logriniTest","__toCommonJS","import_browser_or_node","import_fast_json_stable_stringify","TIME_PREFIX_ENABLED","PERFORMANCE_PREFIX_ENABLED","LOGGER_DEFAULT_CONFIG","StringFormatters","LoggerTime","sinceFirst","sinceLast","time","delta","sinceFirstNum","t","Style","style","string","formattersEnabled","Logger","_Logger","level","config","debugLogForStub","stub","args","groupCollapsed","addExtraFxs","enabled","func","group","functionToWrap","result","realFunc","ERRFX","params","param","stringify","logFunc","fixedArgs","p","returnAsString","now","stack","skippedFirst","line","matches","obj","formatter","logriniTest"]}