@meadown/logger 1.8.10 → 1.9.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.
Files changed (142) hide show
  1. package/README.md +149 -51
  2. package/dist/cjs/{config.js → config/index.js} +1 -1
  3. package/dist/cjs/{constants.d.ts → const/index.d.ts} +0 -5
  4. package/dist/cjs/{constants.js → const/index.js} +2 -8
  5. package/dist/cjs/{caller → domain/caller}/getCaller.js +1 -1
  6. package/dist/cjs/{colors → domain/colors}/color.js +1 -1
  7. package/dist/cjs/{decorations → domain/decorations}/link.js +1 -1
  8. package/dist/cjs/{terminal → domain/terminal}/isTTY.js +1 -1
  9. package/dist/cjs/{time → domain/time}/getTimeStamp.js +1 -1
  10. package/dist/cjs/domain/write/helpers/buildContext.d.ts +16 -0
  11. package/dist/cjs/domain/write/helpers/buildContext.js +40 -0
  12. package/dist/cjs/{core/writeLog → domain/write/helpers}/formatLocation.js +3 -2
  13. package/dist/cjs/domain/write/helpers/index.d.ts +4 -0
  14. package/dist/cjs/domain/write/helpers/index.js +20 -0
  15. package/dist/cjs/{core/writeLog → domain/write/helpers}/renderMessage.js +6 -5
  16. package/dist/cjs/{core/writeLog → domain/write/helpers}/visibleLines.js +3 -3
  17. package/dist/cjs/domain/write/index.d.ts +2 -0
  18. package/dist/cjs/domain/write/index.js +14 -0
  19. package/dist/{core/writeLog/index.d.ts → cjs/domain/write/writeLog.d.ts} +2 -3
  20. package/dist/cjs/domain/write/writeLog.js +24 -0
  21. package/dist/cjs/features/logger/index.d.ts +1 -0
  22. package/dist/cjs/features/logger/index.js +21 -0
  23. package/dist/cjs/features/logger-error/index.d.ts +1 -0
  24. package/dist/cjs/features/logger-error/index.js +21 -0
  25. package/dist/cjs/features/logger-group/createGroup.d.ts +11 -0
  26. package/dist/cjs/features/logger-group/createGroup.js +21 -0
  27. package/dist/cjs/features/logger-group/index.d.ts +1 -0
  28. package/dist/cjs/features/logger-group/index.js +14 -0
  29. package/dist/cjs/features/logger-group/writeGroup.d.ts +8 -0
  30. package/dist/cjs/features/logger-group/writeGroup.js +20 -0
  31. package/dist/cjs/features/logger-max-lines/index.d.ts +1 -0
  32. package/dist/cjs/features/logger-max-lines/index.js +12 -0
  33. package/dist/cjs/features/logger-tap/createTap.d.ts +5 -0
  34. package/dist/cjs/features/logger-tap/createTap.js +33 -0
  35. package/dist/cjs/features/logger-tap/index.d.ts +1 -0
  36. package/dist/cjs/features/logger-tap/index.js +14 -0
  37. package/dist/cjs/features/logger-tap/tapAsync/helpers/buildBlock.d.ts +19 -0
  38. package/dist/cjs/features/logger-tap/tapAsync/helpers/buildBlock.js +56 -0
  39. package/dist/cjs/features/logger-tap/tapAsync/helpers/format.d.ts +4 -0
  40. package/dist/cjs/features/logger-tap/tapAsync/helpers/format.js +30 -0
  41. package/dist/cjs/features/logger-tap/tapAsync/helpers/index.d.ts +4 -0
  42. package/dist/cjs/features/logger-tap/tapAsync/helpers/index.js +20 -0
  43. package/dist/cjs/features/logger-tap/tapAsync/helpers/isThenable.d.ts +2 -0
  44. package/dist/cjs/features/logger-tap/tapAsync/helpers/isThenable.js +15 -0
  45. package/dist/cjs/features/logger-tap/tapAsync/helpers/response.d.ts +21 -0
  46. package/dist/cjs/features/logger-tap/tapAsync/helpers/response.js +62 -0
  47. package/dist/cjs/features/logger-tap/tapAsync/index.d.ts +2 -0
  48. package/dist/cjs/features/logger-tap/tapAsync/index.js +13 -0
  49. package/dist/cjs/{tap → features/logger-tap/tapAsync}/tapAsync.d.ts +1 -3
  50. package/dist/cjs/features/logger-tap/tapAsync/tapAsync.js +95 -0
  51. package/dist/cjs/features/logger-warn/index.d.ts +1 -0
  52. package/dist/cjs/features/logger-warn/index.js +21 -0
  53. package/dist/cjs/index.d.ts +63 -18
  54. package/dist/cjs/index.js +29 -15
  55. package/dist/cjs/types/index.d.ts +2 -0
  56. package/dist/cjs/types/index.js +8 -0
  57. package/dist/{config.js → config/index.js} +1 -1
  58. package/dist/{constants.d.ts → const/index.d.ts} +0 -5
  59. package/dist/{constants.js → const/index.js} +1 -7
  60. package/dist/{caller → domain/caller}/getCaller.js +1 -1
  61. package/dist/{colors → domain/colors}/color.js +1 -1
  62. package/dist/{decorations → domain/decorations}/link.js +1 -1
  63. package/dist/{terminal → domain/terminal}/isTTY.js +1 -1
  64. package/dist/{time → domain/time}/getTimeStamp.js +1 -1
  65. package/dist/domain/write/helpers/buildContext.d.ts +16 -0
  66. package/dist/domain/write/helpers/buildContext.js +33 -0
  67. package/dist/{core/writeLog → domain/write/helpers}/formatLocation.js +3 -2
  68. package/dist/domain/write/helpers/index.d.ts +4 -0
  69. package/dist/domain/write/helpers/index.js +10 -0
  70. package/dist/{core/writeLog → domain/write/helpers}/renderMessage.js +5 -4
  71. package/dist/{core/writeLog → domain/write/helpers}/visibleLines.js +2 -2
  72. package/dist/domain/write/index.d.ts +2 -0
  73. package/dist/domain/write/index.js +8 -0
  74. package/dist/{cjs/core/writeLog/index.d.ts → domain/write/writeLog.d.ts} +2 -3
  75. package/dist/domain/write/writeLog.js +21 -0
  76. package/dist/features/logger/index.d.ts +1 -0
  77. package/dist/features/logger/index.js +15 -0
  78. package/dist/features/logger-error/index.d.ts +1 -0
  79. package/dist/features/logger-error/index.js +15 -0
  80. package/dist/features/logger-group/createGroup.d.ts +11 -0
  81. package/dist/features/logger-group/createGroup.js +15 -0
  82. package/dist/features/logger-group/index.d.ts +1 -0
  83. package/dist/features/logger-group/index.js +7 -0
  84. package/dist/features/logger-group/writeGroup.d.ts +8 -0
  85. package/dist/features/logger-group/writeGroup.js +17 -0
  86. package/dist/features/logger-max-lines/index.d.ts +1 -0
  87. package/dist/features/logger-max-lines/index.js +7 -0
  88. package/dist/features/logger-tap/createTap.d.ts +5 -0
  89. package/dist/features/logger-tap/createTap.js +27 -0
  90. package/dist/features/logger-tap/index.d.ts +1 -0
  91. package/dist/features/logger-tap/index.js +7 -0
  92. package/dist/features/logger-tap/tapAsync/helpers/buildBlock.d.ts +19 -0
  93. package/dist/features/logger-tap/tapAsync/helpers/buildBlock.js +53 -0
  94. package/dist/features/logger-tap/tapAsync/helpers/format.d.ts +4 -0
  95. package/dist/features/logger-tap/tapAsync/helpers/format.js +26 -0
  96. package/dist/features/logger-tap/tapAsync/helpers/index.d.ts +4 -0
  97. package/dist/features/logger-tap/tapAsync/helpers/index.js +10 -0
  98. package/dist/features/logger-tap/tapAsync/helpers/isThenable.d.ts +2 -0
  99. package/dist/features/logger-tap/tapAsync/helpers/isThenable.js +12 -0
  100. package/dist/features/logger-tap/tapAsync/helpers/response.d.ts +21 -0
  101. package/dist/features/logger-tap/tapAsync/helpers/response.js +57 -0
  102. package/dist/features/logger-tap/tapAsync/index.d.ts +2 -0
  103. package/dist/features/logger-tap/tapAsync/index.js +8 -0
  104. package/dist/{tap → features/logger-tap/tapAsync}/tapAsync.d.ts +1 -3
  105. package/dist/features/logger-tap/tapAsync/tapAsync.js +92 -0
  106. package/dist/features/logger-warn/index.d.ts +1 -0
  107. package/dist/features/logger-warn/index.js +15 -0
  108. package/dist/index.d.ts +63 -18
  109. package/dist/index.js +29 -15
  110. package/dist/types/index.d.ts +2 -0
  111. package/dist/types/index.js +7 -0
  112. package/package.json +7 -4
  113. package/dist/cjs/core/createLog.d.ts +0 -8
  114. package/dist/cjs/core/createLog.js +0 -29
  115. package/dist/cjs/core/writeLog/index.js +0 -48
  116. package/dist/cjs/tap/createTap.d.ts +0 -18
  117. package/dist/cjs/tap/createTap.js +0 -51
  118. package/dist/cjs/tap/tapAsync.js +0 -192
  119. package/dist/core/createLog.d.ts +0 -8
  120. package/dist/core/createLog.js +0 -23
  121. package/dist/core/writeLog/index.js +0 -39
  122. package/dist/tap/createTap.d.ts +0 -18
  123. package/dist/tap/createTap.js +0 -45
  124. package/dist/tap/tapAsync.js +0 -188
  125. /package/dist/cjs/{config.d.ts → config/index.d.ts} +0 -0
  126. /package/dist/{caller → cjs/domain/caller}/getCaller.d.ts +0 -0
  127. /package/dist/cjs/{colors → domain/colors}/color.d.ts +0 -0
  128. /package/dist/cjs/{decorations → domain/decorations}/link.d.ts +0 -0
  129. /package/dist/cjs/{terminal → domain/terminal}/isTTY.d.ts +0 -0
  130. /package/dist/cjs/{time → domain/time}/getTimeStamp.d.ts +0 -0
  131. /package/dist/cjs/{core/writeLog → domain/write/helpers}/formatLocation.d.ts +0 -0
  132. /package/dist/cjs/{core/writeLog → domain/write/helpers}/renderMessage.d.ts +0 -0
  133. /package/dist/cjs/{core/writeLog → domain/write/helpers}/visibleLines.d.ts +0 -0
  134. /package/dist/{config.d.ts → config/index.d.ts} +0 -0
  135. /package/dist/{cjs → domain}/caller/getCaller.d.ts +0 -0
  136. /package/dist/{colors → domain/colors}/color.d.ts +0 -0
  137. /package/dist/{decorations → domain/decorations}/link.d.ts +0 -0
  138. /package/dist/{terminal → domain/terminal}/isTTY.d.ts +0 -0
  139. /package/dist/{time → domain/time}/getTimeStamp.d.ts +0 -0
  140. /package/dist/{core/writeLog → domain/write/helpers}/formatLocation.d.ts +0 -0
  141. /package/dist/{core/writeLog → domain/write/helpers}/renderMessage.d.ts +0 -0
  142. /package/dist/{core/writeLog → domain/write/helpers}/visibleLines.d.ts +0 -0
package/dist/cjs/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /*
3
3
  * index.ts
4
4
  * Created by Dewan Mobashirul
5
- * Copyright (c) 2026 dewan-meadown
5
+ * Copyright (c) 2026 meadown
6
6
  * All rights reserved
7
7
  */
8
8
  var __importDefault = (this && this.__importDefault) || function (mod) {
@@ -10,23 +10,37 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.logger = void 0;
13
- const createLog_js_1 = __importDefault(require("./core/createLog.js"));
14
- const createTap_js_1 = __importDefault(require("./tap/createTap.js"));
15
- const index_js_1 = require("./core/writeLog/index.js");
13
+ const index_js_1 = require("./features/logger-max-lines/index.js");
14
+ const index_js_2 = __importDefault(require("./features/logger/index.js"));
15
+ const index_js_3 = __importDefault(require("./features/logger-warn/index.js"));
16
+ const index_js_4 = __importDefault(require("./features/logger-error/index.js"));
17
+ const index_js_5 = __importDefault(require("./features/logger-tap/index.js"));
18
+ const index_js_6 = __importDefault(require("./features/logger-group/index.js"));
16
19
  /**
17
- * Logs to the console, but only outside production. Each line is prefixed with
18
- * a level tag, a short local timestamp, and a clickable link to the file it was
19
- * called from; all arguments are then printed as-is.
20
+ * A logger built for development colored tags, a local timestamp, and a
21
+ * clickable `(file:line)` link on every line so you always know where a
22
+ * message came from. Works like `console.log`: pass anything and it prints.
23
+ *
24
+ * Logs only when `NODE_ENV !== "production"`.
25
+ *
20
26
  * @example
21
- * logger("Auth", "user logged in")
22
- * // [INFO] 05-30 04:00:00 PM (server.ts:42) Auth user logged in
23
- * @example
24
- * logger.maxLines = 5 // long messages collapse to 5 lines; 0 = show all
27
+ * ```ts
28
+ * logger("server started", { port: 3000 })
29
+ * logger.error("db failed", new Error("ECONNREFUSED"))
30
+ * logger.warn("disk above 80%")
31
+ * ```
32
+ *
33
+ * @example Tap — keep the value flowing, log it on the side
34
+ * ```ts
35
+ * const user = logger.tap(await getUser(id), "user")
36
+ * const res = await logger.tap(fetch(url), "GET /users")
37
+ * ```
25
38
  */
26
- const logger = Object.assign((0, createLog_js_1.default)("log", "[INFO]"), {
27
- error: (0, createLog_js_1.default)("error", "[ERROR]"),
28
- warn: (0, createLog_js_1.default)("warn", "[WARN]"),
29
- tap: (0, createTap_js_1.default)(),
39
+ const logger = Object.assign(index_js_2.default, {
40
+ error: index_js_4.default,
41
+ warn: index_js_3.default,
42
+ tap: index_js_5.default,
43
+ group: index_js_6.default,
30
44
  });
31
45
  exports.logger = logger;
32
46
  // `maxLines` is a live getter/setter backed by the shared collapse setting, so
@@ -0,0 +1,2 @@
1
+ /** The console channels the logger writes to. */
2
+ export type LogChannel = "log" | "error" | "warn";
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /*
3
+ * index.ts
4
+ * Created by Dewan Mobashirul
5
+ * Copyright (c) 2026 meadown
6
+ * All rights reserved
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * config.ts
3
3
  * Created by Dewan Mobashirul
4
- * Copyright (c) 2026 dewan-meadown
4
+ * Copyright (c) 2026 meadown
5
5
  * All rights reserved
6
6
  */
7
7
  /**
@@ -1,8 +1,3 @@
1
- import { type Color } from "./colors/color.js";
2
- /** The console channels the logger writes to. */
3
- export type LogChannel = "log" | "error" | "warn";
4
- /** The tag color per channel: info/tap → cyan, warn → yellow, error → red. */
5
- export declare const TAG_COLOR: Record<LogChannel, Color>;
6
1
  /** Glyphs that draw each entry's little tree. */
7
2
  export declare const BRANCH = "\u251C\u2500\u2500";
8
3
  export declare const BRANCH_END = "\u2514\u2500\u2500";
@@ -1,18 +1,12 @@
1
1
  /*
2
2
  * constants.ts
3
3
  * Created by Dewan Mobashirul
4
- * Copyright (c) 2026 dewan-meadown
4
+ * Copyright (c) 2026 meadown
5
5
  * All rights reserved
6
6
  *
7
7
  * Single home for the logger's layout/behavior constants, so the values that
8
8
  * shape an entry live in one place instead of as magic literals across modules.
9
9
  */
10
- /** The tag color per channel: info/tap → cyan, warn → yellow, error → red. */
11
- export const TAG_COLOR = {
12
- log: "cyan",
13
- warn: "yellow",
14
- error: "red",
15
- };
16
10
  /** Glyphs that draw each entry's little tree. */
17
11
  export const BRANCH = "├──"; // the message branch
18
12
  export const BRANCH_END = "└──"; // the last (metadata) branch
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * getCaller.ts
3
3
  * Created by Dewan Mobashirul
4
- * Copyright (c) 2026 dewan-meadown
4
+ * Copyright (c) 2026 meadown
5
5
  * All rights reserved
6
6
  */
7
7
  const UNKNOWN = { label: "unknown", file: null, line: null };
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * color.ts
3
3
  * Created by Dewan Mobashirul
4
- * Copyright (c) 2026 dewan-meadown
4
+ * Copyright (c) 2026 meadown
5
5
  * All rights reserved
6
6
  */
7
7
  /** ANSI SGR codes for the colors/styles the logger uses. */
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * link.ts
3
3
  * Created by Dewan Mobashirul
4
- * Copyright (c) 2026 dewan-meadown
4
+ * Copyright (c) 2026 meadown
5
5
  * All rights reserved
6
6
  */
7
7
  import { pathToFileURL } from "node:url";
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * isTTY.ts
3
3
  * Created by Dewan Mobashirul
4
- * Copyright (c) 2026 dewan-meadown
4
+ * Copyright (c) 2026 meadown
5
5
  * All rights reserved
6
6
  */
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * getTimeStamp.ts
3
3
  * Created by Dewan Mobashirul
4
- * Copyright (c) 2026 dewan-meadown
4
+ * Copyright (c) 2026 meadown
5
5
  * All rights reserved
6
6
  */
7
7
  // Time-only 12-hour formatter (date is built separately, timezone is dropped).
@@ -0,0 +1,16 @@
1
+ import { type LogChannel } from "../../../types/index.js";
2
+ import { type Caller } from "../../caller/getCaller.js";
3
+ import { type Color } from "../../colors/color.js";
4
+ /** Tag color per channel — cyan for log/tap, yellow for warn, red for error. */
5
+ export declare const TAG_COLOR: Record<LogChannel, Color>;
6
+ export interface RenderContext {
7
+ useColor: boolean;
8
+ paint: (s: string, c: Color) => string;
9
+ timeStamp: string;
10
+ locOut: string;
11
+ connector: string;
12
+ connectorEnd: string;
13
+ separator: string;
14
+ }
15
+ /** Builds the shared paint/layout values used by both writeLog and writeGroup. */
16
+ export declare function buildContext(channel: LogChannel, caller: Caller): RenderContext;
@@ -0,0 +1,33 @@
1
+ /*
2
+ * buildContext.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ import { BRANCH, BRANCH_END, SEPARATOR } from "../../../const/index.js";
8
+ import { colorize } from "../../colors/color.js";
9
+ /** Tag color per channel — cyan for log/tap, yellow for warn, red for error. */
10
+ export const TAG_COLOR = {
11
+ log: "cyan",
12
+ warn: "yellow",
13
+ error: "red",
14
+ };
15
+ import { isTTY } from "../../terminal/isTTY.js";
16
+ import getTimeStamp from "../../time/getTimeStamp.js";
17
+ import { formatLocation } from "./formatLocation.js";
18
+ /** Builds the shared paint/layout values used by both writeLog and writeGroup. */
19
+ export function buildContext(channel, caller) {
20
+ const streamName = channel === "log" ? "stdout" : "stderr";
21
+ const useColor = isTTY(streamName);
22
+ const paint = (s, c) => (useColor ? colorize(s, c) : s);
23
+ const location = formatLocation(caller, useColor);
24
+ return {
25
+ useColor,
26
+ paint,
27
+ timeStamp: paint(getTimeStamp(), "teal"),
28
+ locOut: paint(`(${location})`, "dimTeal"),
29
+ connector: paint(BRANCH, "gray"),
30
+ connectorEnd: paint(BRANCH_END, "gray"),
31
+ separator: paint(SEPARATOR, "gray"),
32
+ };
33
+ }
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * formatLocation.ts
3
3
  * Created by Dewan Mobashirul
4
- * Copyright (c) 2026 dewan-meadown
4
+ * Copyright (c) 2026 meadown
5
5
  * All rights reserved
6
6
  */
7
7
  import { fileUrl, hyperlink } from "../../decorations/link.js";
@@ -10,7 +10,8 @@ import { fileUrl, hyperlink } from "../../decorations/link.js";
10
10
  * supporting terminal, plain text otherwise. Pure (no stack access).
11
11
  */
12
12
  export function formatLocation(caller, interactive) {
13
- if (caller.file !== null && caller.line !== null && interactive)
13
+ if (caller.file !== null && caller.line !== null && interactive) {
14
14
  return hyperlink(caller.label, fileUrl(caller.file));
15
+ }
15
16
  return caller.label;
16
17
  }
@@ -0,0 +1,4 @@
1
+ export { visibleLines, getVisibleLines, setVisibleLines, } from "./visibleLines.js";
2
+ export { renderMessage } from "./renderMessage.js";
3
+ export { formatLocation } from "./formatLocation.js";
4
+ export { buildContext, TAG_COLOR } from "./buildContext.js";
@@ -0,0 +1,10 @@
1
+ /*
2
+ * index.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ export { visibleLines, getVisibleLines, setVisibleLines, } from "./visibleLines.js";
8
+ export { renderMessage } from "./renderMessage.js";
9
+ export { formatLocation } from "./formatLocation.js";
10
+ export { buildContext, TAG_COLOR } from "./buildContext.js";
@@ -1,13 +1,13 @@
1
1
  /*
2
2
  * renderMessage.ts
3
3
  * Created by Dewan Mobashirul
4
- * Copyright (c) 2026 dewan-meadown
4
+ * Copyright (c) 2026 meadown
5
5
  * All rights reserved
6
6
  */
7
7
  import { formatWithOptions } from "node:util";
8
- import { MESSAGE_INDENT } from "../../constants.js";
9
- import { colorize } from "../../colors/color.js";
10
8
  import { visibleLines } from "./visibleLines.js";
9
+ import { colorize } from "../../colors/color.js";
10
+ import { MESSAGE_INDENT } from "../../../const/index.js";
11
11
  /**
12
12
  * Collapses a long multi-line message to {@link visibleLines} lines, replacing
13
13
  * the rest with a dimmed `… N more lines` summary. When `visibleLines` is 0
@@ -33,5 +33,6 @@ function collapse(text, useColor) {
33
33
  */
34
34
  export function renderMessage(args, useColor) {
35
35
  const text = formatWithOptions({ colors: useColor }, ...args);
36
- return collapse(text.replace(/\n/g, `\n${colorize(MESSAGE_INDENT, "gray")}`), useColor);
36
+ const indent = useColor ? colorize(MESSAGE_INDENT, "gray") : MESSAGE_INDENT;
37
+ return collapse(text.replace(/\n/g, `\n${indent}`), useColor);
37
38
  }
@@ -1,10 +1,10 @@
1
1
  /*
2
2
  * visibleLines.ts
3
3
  * Created by Dewan Mobashirul
4
- * Copyright (c) 2026 dewan-meadown
4
+ * Copyright (c) 2026 meadown
5
5
  * All rights reserved
6
6
  */
7
- import { DEFAULT_MAX_LINES } from "../../constants.js";
7
+ import { DEFAULT_MAX_LINES } from "../../../const/index.js";
8
8
  /** Max message lines to show before collapsing the rest; 0 (default) shows all. */
9
9
  export let visibleLines = DEFAULT_MAX_LINES;
10
10
  /** How many lines a long message shows before collapsing (0 = all). */
@@ -0,0 +1,2 @@
1
+ export { writeLog } from "./writeLog.js";
2
+ export { getVisibleLines, setVisibleLines } from "./helpers/index.js";
@@ -0,0 +1,8 @@
1
+ /*
2
+ * index.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ export { writeLog } from "./writeLog.js";
8
+ export { getVisibleLines, setVisibleLines } from "./helpers/index.js";
@@ -1,6 +1,5 @@
1
- import { type LogChannel } from "../../constants.js";
2
- import { type Caller } from "../../caller/getCaller.js";
3
- export { getVisibleLines, setVisibleLines } from "./visibleLines.js";
1
+ import { type LogChannel } from "../../types/index.js";
2
+ import { type Caller } from "../caller/getCaller.js";
4
3
  /**
5
4
  * Renders and writes one log entry. The `caller` is resolved by the *caller* of
6
5
  * this function (the log closure or `tap`) and passed in, so this helper never
@@ -0,0 +1,21 @@
1
+ /*
2
+ * writeLog.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ import { renderMessage, buildContext, TAG_COLOR } from "./helpers/index.js";
8
+ /**
9
+ * Renders and writes one log entry. The `caller` is resolved by the *caller* of
10
+ * this function (the log closure or `tap`) and passed in, so this helper never
11
+ * touches the stack — keeping {@link getCaller}'s frame depth correct no matter
12
+ * which user-facing function delegates here.
13
+ */
14
+ export function writeLog(opts) {
15
+ const { channel, tag, args, caller } = opts;
16
+ const { useColor, paint, timeStamp, locOut, connector, connectorEnd, separator, } = buildContext(channel, caller);
17
+ const tagOut = paint(tag, TAG_COLOR[channel]);
18
+ const message = renderMessage(args, useColor);
19
+ const meta = `\n${connectorEnd} ${timeStamp} ${separator} ${locOut}`;
20
+ console[channel](`\n${tagOut} \n${connector} ${message}${meta}`);
21
+ }
@@ -0,0 +1 @@
1
+ export default function log(...args: unknown[]): void;
@@ -0,0 +1,15 @@
1
+ /*
2
+ * index.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ import { isLogAllowed } from "../../config/index.js";
8
+ import getCaller from "../../domain/caller/getCaller.js";
9
+ import { writeLog } from "../../domain/write/writeLog.js";
10
+ export default function log(...args) {
11
+ if (!isLogAllowed())
12
+ return;
13
+ const caller = getCaller();
14
+ writeLog({ channel: "log", tag: "[INFO]", args, caller });
15
+ }
@@ -0,0 +1 @@
1
+ export default function logError(...args: unknown[]): void;
@@ -0,0 +1,15 @@
1
+ /*
2
+ * index.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ import { isLogAllowed } from "../../config/index.js";
8
+ import getCaller from "../../domain/caller/getCaller.js";
9
+ import { writeLog } from "../../domain/write/writeLog.js";
10
+ export default function logError(...args) {
11
+ if (!isLogAllowed())
12
+ return;
13
+ const caller = getCaller();
14
+ writeLog({ channel: "error", tag: "[ERROR]", args, caller });
15
+ }
@@ -0,0 +1,11 @@
1
+ import { type LogChannel } from "../../types/index.js";
2
+ export interface GroupOptions {
3
+ name: string;
4
+ type?: LogChannel;
5
+ logs: unknown[];
6
+ }
7
+ /** Type of `logger.group` — use this to annotate variables or parameters that accept it. */
8
+ export interface Group {
9
+ (opts: GroupOptions): void;
10
+ }
11
+ export default function group({ name, type, logs, }: GroupOptions): void;
@@ -0,0 +1,15 @@
1
+ /*
2
+ * createGroup.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ import { isLogAllowed } from "../../config/index.js";
8
+ import getCaller from "../../domain/caller/getCaller.js";
9
+ import { writeGroup } from "./writeGroup.js";
10
+ export default function group({ name, type = "log", logs, }) {
11
+ if (!isLogAllowed())
12
+ return;
13
+ const caller = getCaller();
14
+ writeGroup({ name, channel: type, logs, caller });
15
+ }
@@ -0,0 +1 @@
1
+ export { default, type Group, type GroupOptions } from "./createGroup.js";
@@ -0,0 +1,7 @@
1
+ /*
2
+ * index.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ export { default } from "./createGroup.js";
@@ -0,0 +1,8 @@
1
+ import { type LogChannel } from "../../types/index.js";
2
+ import { type Caller } from "../../domain/caller/getCaller.js";
3
+ export declare function writeGroup(opts: {
4
+ name: string;
5
+ channel: LogChannel;
6
+ logs: unknown[];
7
+ caller: Caller;
8
+ }): void;
@@ -0,0 +1,17 @@
1
+ /*
2
+ * writeGroup.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ import { renderMessage, buildContext, TAG_COLOR, } from "../../domain/write/helpers/index.js";
8
+ export function writeGroup(opts) {
9
+ const { name, channel, logs, caller } = opts;
10
+ const { useColor, paint, timeStamp, locOut, connector, connectorEnd, separator, } = buildContext(channel, caller);
11
+ const tagOut = paint(`[${name.toUpperCase()}]`, TAG_COLOR[channel]);
12
+ const itemLines = logs
13
+ .map((item) => `\n${connector} ${renderMessage([item], useColor)}`)
14
+ .join("");
15
+ const meta = `\n${connectorEnd} ${timeStamp} ${separator} ${locOut}`;
16
+ console[channel](`\n${tagOut} ${itemLines}${meta}`);
17
+ }
@@ -0,0 +1 @@
1
+ export { getVisibleLines, setVisibleLines } from "../../domain/write/index.js";
@@ -0,0 +1,7 @@
1
+ /*
2
+ * index.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ export { getVisibleLines, setVisibleLines } from "../../domain/write/index.js";
@@ -0,0 +1,5 @@
1
+ /** Type of `logger.tap` — use this to annotate variables or parameters that accept it. */
2
+ export interface Tap {
3
+ <T>(value: T, label?: string): T;
4
+ }
5
+ export default function tap<T>(value: T, label?: string): T;
@@ -0,0 +1,27 @@
1
+ /*
2
+ * createTap.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ import { isLogAllowed } from "../../config/index.js";
8
+ import getCaller from "../../domain/caller/getCaller.js";
9
+ import { writeLog } from "../../domain/write/writeLog.js";
10
+ import { isThenable, tapAsync } from "./tapAsync/index.js";
11
+ export default function tap(value, label) {
12
+ if (!isLogAllowed())
13
+ return value;
14
+ const caller = getCaller();
15
+ if (isThenable(value)) {
16
+ tapAsync(value, label, caller);
17
+ }
18
+ else {
19
+ writeLog({
20
+ channel: "log",
21
+ tag: "[TAP]",
22
+ args: label === undefined ? [value] : [label, value],
23
+ caller,
24
+ });
25
+ }
26
+ return value;
27
+ }
@@ -0,0 +1 @@
1
+ export { default, type Tap } from "./createTap.js";
@@ -0,0 +1,7 @@
1
+ /*
2
+ * index.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ export { default } from "./createTap.js";
@@ -0,0 +1,19 @@
1
+ import { type ResponseLike } from "./response.js";
2
+ /**
3
+ * Renders the nested tree block:
4
+ *
5
+ * GET /users/1
6
+ * │
7
+ * │ response:
8
+ * │ ├── time: 65ms
9
+ * │ ├── status: 200 OK
10
+ * │ └── size: 848 B
11
+ * │
12
+ * │ body:
13
+ * │ ├── id: 1
14
+ * │ └── name: Leanne Graham
15
+ */
16
+ export declare function buildBlock(label: string | undefined, ms: number, res: ResponseLike, body: {
17
+ data: unknown;
18
+ size: string;
19
+ }, useColor: boolean): unknown[];
@@ -0,0 +1,53 @@
1
+ /*
2
+ * buildBlock.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ import { formatWithOptions } from "node:util";
8
+ import { formatDuration } from "./format.js";
9
+ import { colorize } from "../../../../domain/colors/color.js";
10
+ import { formatStatus } from "./response.js";
11
+ /**
12
+ * Renders the nested tree block:
13
+ *
14
+ * GET /users/1
15
+ * │
16
+ * │ response:
17
+ * │ ├── time: 65ms
18
+ * │ ├── status: 200 OK
19
+ * │ └── size: 848 B
20
+ * │
21
+ * │ body:
22
+ * │ ├── id: 1
23
+ * │ └── name: Leanne Graham
24
+ */
25
+ export function buildBlock(label, ms, res, body, useColor) {
26
+ const paint = (s, c) => useColor ? colorize(s, c) : s;
27
+ const pipe = paint("│", "gray");
28
+ const branch = paint("├──", "gray");
29
+ const last = paint("└──", "gray");
30
+ const indent = `${pipe} `;
31
+ const timeLine = `${indent}${branch} time: ${formatDuration(ms, useColor)}`;
32
+ const statusLine = `${indent}${branch} status: ${formatStatus(res, useColor)}`;
33
+ const sizeLine = `${indent}${last} size: ${body.size}`;
34
+ const responseLines = [
35
+ `${pipe}`,
36
+ `${indent}response:`,
37
+ timeLine,
38
+ statusLine,
39
+ sizeLine,
40
+ ];
41
+ const head = label === undefined ? "" : `${label}\n`;
42
+ if (body.data === undefined) {
43
+ return [`${head}${responseLines.join("\n")}`];
44
+ }
45
+ const bodyText = formatWithOptions({ colors: useColor }, body.data);
46
+ const bodyLines = bodyText.split("\n");
47
+ const lastIdx = bodyLines.length - 1;
48
+ const bodyBlock = bodyLines
49
+ .map((line, i) => `${indent}${i === lastIdx ? last : branch} ${line}`)
50
+ .join("\n");
51
+ const full = [...responseLines, `${pipe}`, `${indent}body:`, bodyBlock].join("\n");
52
+ return [`${head}${full}`];
53
+ }
@@ -0,0 +1,4 @@
1
+ /** `65ms` (green) · `1.2s` (yellow) · `5.8s` (red). */
2
+ export declare function formatDuration(ms: number, useColor: boolean): string;
3
+ /** `848 B` / `1.84 KB` / `2.10 MB`. */
4
+ export declare function formatBytes(bytes: number): string;
@@ -0,0 +1,26 @@
1
+ /*
2
+ * format.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ import { colorize } from "../../../../domain/colors/color.js";
8
+ /** `65ms` (green) · `1.2s` (yellow) · `5.8s` (red). */
9
+ export function formatDuration(ms, useColor) {
10
+ const text = ms >= 1000 ? `${(ms / 1000).toFixed(2)}s` : `${ms}ms`;
11
+ if (!useColor)
12
+ return text;
13
+ if (ms >= 2000)
14
+ return colorize(text, "red");
15
+ if (ms >= 500)
16
+ return colorize(text, "yellow");
17
+ return colorize(text, "green");
18
+ }
19
+ /** `848 B` / `1.84 KB` / `2.10 MB`. */
20
+ export function formatBytes(bytes) {
21
+ if (bytes < 1024)
22
+ return `${bytes} B`;
23
+ if (bytes < 1024 * 1024)
24
+ return `${(bytes / 1024).toFixed(2)} KB`;
25
+ return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
26
+ }
@@ -0,0 +1,4 @@
1
+ export { readBody, isResponse, formatStatus, type ResponseLike, } from "./response.js";
2
+ export { buildBlock } from "./buildBlock.js";
3
+ export { isThenable } from "./isThenable.js";
4
+ export { formatDuration, formatBytes } from "./format.js";
@@ -0,0 +1,10 @@
1
+ /*
2
+ * index.ts
3
+ * Created by Dewan Mobashirul
4
+ * Copyright (c) 2026 meadown
5
+ * All rights reserved
6
+ */
7
+ export { readBody, isResponse, formatStatus, } from "./response.js";
8
+ export { buildBlock } from "./buildBlock.js";
9
+ export { isThenable } from "./isThenable.js";
10
+ export { formatDuration, formatBytes } from "./format.js";
@@ -0,0 +1,2 @@
1
+ /** Whether `value` is thenable (a promise we can await + time). */
2
+ export declare function isThenable(value: unknown): value is PromiseLike<unknown>;