@visulima/pail 4.0.0-alpha.8 → 4.0.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 (145) hide show
  1. package/CHANGELOG.md +531 -0
  2. package/LICENSE.md +270 -166
  3. package/README.md +53 -24
  4. package/dist/error.d.ts +95 -96
  5. package/dist/error.js +5 -76
  6. package/dist/index.browser.d.ts +568 -47
  7. package/dist/index.browser.js +19 -1499
  8. package/dist/index.server.d.ts +749 -65
  9. package/dist/index.server.js +32 -3179
  10. package/dist/middleware/elysia.d.ts +66 -63
  11. package/dist/middleware/elysia.js +1 -70
  12. package/dist/middleware/express.d.ts +74 -71
  13. package/dist/middleware/express.js +1 -29
  14. package/dist/middleware/fastify.d.ts +70 -67
  15. package/dist/middleware/fastify.js +1 -46
  16. package/dist/middleware/hono.d.ts +75 -72
  17. package/dist/middleware/hono.js +1 -33
  18. package/dist/middleware/next/handler.d.ts +102 -34
  19. package/dist/middleware/next/handler.js +1 -53
  20. package/dist/middleware/sveltekit.d.ts +101 -98
  21. package/dist/middleware/sveltekit.js +1 -43
  22. package/dist/object-tree.d.ts +67 -70
  23. package/dist/object-tree.js +2 -89
  24. package/dist/packem_shared/AbstractJsonReporter-Bp_JCrMQ.js +1 -0
  25. package/dist/packem_shared/AbstractJsonReporter-w_bGGiD-.js +1 -0
  26. package/dist/packem_shared/JsonReporter-Sd_lJGS-.js +2 -0
  27. package/dist/packem_shared/JsonReporter-bmem9lcg.js +1 -0
  28. package/dist/packem_shared/PailError-CbU1Ogfa.js +5 -0
  29. package/dist/packem_shared/PrettyReporter-CcDdPQSt.js +44 -0
  30. package/dist/packem_shared/PrettyReporter-DsHfKOU7.js +5 -0
  31. package/dist/packem_shared/abstract-json-reporter.d-wfESoEa-.d.ts +62 -0
  32. package/dist/packem_shared/abstract-pretty-reporter-DrLBJ6ds.js +57 -0
  33. package/dist/packem_shared/addKnownErrorConstructor-C1OJTj2D-0FlJMfXz.js +25 -0
  34. package/dist/packem_shared/constants-DKfCaSUR.js +1 -0
  35. package/dist/packem_shared/constants-ep2nsfdy.js +1 -0
  36. package/dist/packem_shared/create-middleware-logger.d-B-JmQ1Sl.d.ts +47 -0
  37. package/dist/packem_shared/headers-DH0H2s8W.js +1 -0
  38. package/dist/packem_shared/index-Q1764hvO.js +1 -0
  39. package/dist/packem_shared/index.d-T71KjNAr.d.ts +16 -0
  40. package/dist/packem_shared/pailMiddleware-B5DJoBYl.js +1 -0
  41. package/dist/packem_shared/serializeError-C-NFvZ8_-D0CA_Qlx.js +1 -0
  42. package/dist/packem_shared/storage-DaXAlpiO.js +1 -0
  43. package/dist/packem_shared/types.d-Cz9S7jZh.d.ts +201 -0
  44. package/dist/packem_shared/types.d-bWnqHJKL.d.ts +211 -0
  45. package/dist/packem_shared/types.d-xxE3FOD3.d.ts +229 -0
  46. package/dist/packem_shared/useLogger-DB34CuU5.js +1 -0
  47. package/dist/packem_shared/wide-event.d-D3ATYpoK.d.ts +717 -0
  48. package/dist/packem_shared/write-console-log-based-on-level-BqjxV016.js +1 -0
  49. package/dist/packem_shared/write-stream-C7jxLxIT.js +1 -0
  50. package/dist/processor/caller/caller-processor.d.ts +50 -47
  51. package/dist/processor/caller/caller-processor.js +1 -59
  52. package/dist/processor/environment-processor.d.ts +114 -113
  53. package/dist/processor/environment-processor.js +1 -78
  54. package/dist/processor/message-formatter-processor.d.ts +59 -49
  55. package/dist/processor/message-formatter-processor.js +1 -713
  56. package/dist/processor/opentelemetry-processor.d.ts +70 -66
  57. package/dist/processor/opentelemetry-processor.js +1 -52
  58. package/dist/processor/redact-processor.d.ts +99 -41
  59. package/dist/processor/redact-processor.js +1 -30
  60. package/dist/processor/sampling-processor.d.ts +103 -101
  61. package/dist/processor/sampling-processor.js +1 -59
  62. package/dist/reporter/file/json-file-reporter.d.ts +109 -42
  63. package/dist/reporter/file/json-file-reporter.js +2 -136
  64. package/dist/reporter/http/abstract-http-reporter.d.ts +256 -211
  65. package/dist/reporter/http/abstract-http-reporter.js +2 -435
  66. package/dist/reporter/http/http-reporter.d.ts +41 -36
  67. package/dist/reporter/http/http-reporter.edge-light.d.ts +487 -39
  68. package/dist/reporter/http/http-reporter.edge-light.js +2 -733
  69. package/dist/reporter/http/http-reporter.js +1 -13
  70. package/dist/reporter/json/index.browser.d.ts +98 -3
  71. package/dist/reporter/json/index.browser.js +1 -2
  72. package/dist/reporter/json/index.d.ts +53 -3
  73. package/dist/reporter/json/index.js +1 -2
  74. package/dist/reporter/pretty/index.browser.d.ts +105 -2
  75. package/dist/reporter/pretty/index.browser.js +1 -1
  76. package/dist/reporter/pretty/index.d.ts +270 -2
  77. package/dist/reporter/pretty/index.js +1 -1
  78. package/dist/reporter/simple/simple-reporter.server.d.ts +215 -18
  79. package/dist/reporter/simple/simple-reporter.server.js +8 -182
  80. package/dist/wide-event.d.ts +6 -300
  81. package/dist/wide-event.js +1 -281
  82. package/package.json +23 -38
  83. package/dist/constants.d.ts +0 -37
  84. package/dist/interactive/index.d.ts +0 -2
  85. package/dist/interactive/index.js +0 -2
  86. package/dist/interactive/interactive-manager.d.ts +0 -108
  87. package/dist/interactive/interactive-stream-hook.d.ts +0 -68
  88. package/dist/middleware/next/middleware.d.ts +0 -59
  89. package/dist/middleware/next/storage.d.ts +0 -14
  90. package/dist/middleware/shared/create-middleware-logger.d.ts +0 -82
  91. package/dist/middleware/shared/headers.d.ts +0 -14
  92. package/dist/middleware/shared/routes.d.ts +0 -30
  93. package/dist/middleware/shared/storage.d.ts +0 -29
  94. package/dist/packem_shared/AbstractJsonReporter-CGKHS8_M.js +0 -286
  95. package/dist/packem_shared/AbstractJsonReporter-DDjDkciI.js +0 -286
  96. package/dist/packem_shared/InteractiveManager-Cd6A14ZK.js +0 -172
  97. package/dist/packem_shared/InteractiveStreamHook-ePIURL_U.js +0 -133
  98. package/dist/packem_shared/JsonReporter-B3XX8GHN.js +0 -58
  99. package/dist/packem_shared/JsonReporter-p_BXg6Sj.js +0 -28
  100. package/dist/packem_shared/PrettyReporter-BYL3NrdA.js +0 -214
  101. package/dist/packem_shared/PrettyReporter-CvBn-hxP.js +0 -1459
  102. package/dist/packem_shared/Spinner-DIdVcfWq.js +0 -2183
  103. package/dist/packem_shared/abstract-pretty-reporter-jU8WL_6c.js +0 -2602
  104. package/dist/packem_shared/constants-B1RjD_ps.js +0 -99
  105. package/dist/packem_shared/constants-omsTHUWB.js +0 -119
  106. package/dist/packem_shared/createPailError-B11aRfrT.js +0 -76
  107. package/dist/packem_shared/getBarChar-BWj1UrH3.js +0 -404
  108. package/dist/packem_shared/headers-Cp4uLtr4.js +0 -123
  109. package/dist/packem_shared/index-DnkF86LQ.js +0 -658
  110. package/dist/packem_shared/index-frijFf5m.js +0 -1252
  111. package/dist/packem_shared/pailMiddleware-Ci88geIF.js +0 -24
  112. package/dist/packem_shared/storage-D0vqz8OX.js +0 -36
  113. package/dist/packem_shared/useLogger-D0rU3lcX.js +0 -33
  114. package/dist/packem_shared/write-console-log-based-on-level-DBmRYXpj.js +0 -14
  115. package/dist/packem_shared/write-stream-BG8fhcs3.js +0 -6
  116. package/dist/pail.browser.d.ts +0 -412
  117. package/dist/pail.server.d.ts +0 -233
  118. package/dist/processor/caller/get-caller-filename.d.ts +0 -23
  119. package/dist/progress-bar.d.ts +0 -136
  120. package/dist/progress-bar.js +0 -404
  121. package/dist/reporter/file/utils/rotating-file-stream.d.ts +0 -48
  122. package/dist/reporter/http/utils/compression.d.ts +0 -7
  123. package/dist/reporter/http/utils/log-size-error.d.ts +0 -30
  124. package/dist/reporter/http/utils/retry.d.ts +0 -27
  125. package/dist/reporter/json/abstract-json-reporter.d.ts +0 -61
  126. package/dist/reporter/json/json-reporter.browser.d.ts +0 -40
  127. package/dist/reporter/json/json-reporter.server.d.ts +0 -50
  128. package/dist/reporter/pretty/abstract-pretty-reporter.d.ts +0 -83
  129. package/dist/reporter/pretty/pretty-reporter.browser.d.ts +0 -36
  130. package/dist/reporter/pretty/pretty-reporter.server.d.ts +0 -70
  131. package/dist/reporter/raw/raw-reporter.browser.d.ts +0 -5
  132. package/dist/reporter/raw/raw-reporter.server.d.ts +0 -13
  133. package/dist/reporter/utils/default-inspector-config.d.ts +0 -3
  134. package/dist/reporter/utils/format-label.d.ts +0 -3
  135. package/dist/spinner.d.ts +0 -220
  136. package/dist/spinner.js +0 -2183
  137. package/dist/types.d.ts +0 -241
  138. package/dist/utils/ansi-escapes.d.ts +0 -4
  139. package/dist/utils/arrayify.d.ts +0 -2
  140. package/dist/utils/get-longest-badge.d.ts +0 -4
  141. package/dist/utils/get-longest-label.d.ts +0 -4
  142. package/dist/utils/merge-types.d.ts +0 -4
  143. package/dist/utils/stream/safe-stream-handler.d.ts +0 -21
  144. package/dist/utils/write-console-log-based-on-level.d.ts +0 -4
  145. package/dist/utils/write-stream.d.ts +0 -2
@@ -1,99 +0,0 @@
1
- const LOG_TYPES = {
2
- alert: {
3
- color: "red",
4
- label: "alert",
5
- logLevel: "alert"
6
- },
7
- await: {
8
- color: "blue",
9
- label: "awaiting",
10
- logLevel: "informational"
11
- },
12
- complete: {
13
- color: "cyan",
14
- label: "complete",
15
- logLevel: "informational"
16
- },
17
- critical: {
18
- color: "redBright",
19
- label: "critical",
20
- logLevel: "critical"
21
- },
22
- debug: {
23
- color: "gray",
24
- label: "debug",
25
- logLevel: "debug"
26
- },
27
- emergency: {
28
- color: "redBright",
29
- label: "emergency",
30
- logLevel: "emergency"
31
- },
32
- error: {
33
- color: "red",
34
- label: "error",
35
- logLevel: "error"
36
- },
37
- info: {
38
- color: "blueBright",
39
- label: "info",
40
- logLevel: "informational"
41
- },
42
- log: {
43
- label: "",
44
- logLevel: "informational"
45
- },
46
- notice: {
47
- color: "magentaBright",
48
- label: "notice",
49
- logLevel: "notice"
50
- },
51
- pending: {
52
- color: "magenta",
53
- label: "pending",
54
- logLevel: "informational"
55
- },
56
- start: {
57
- color: "greenBright",
58
- label: "start",
59
- logLevel: "informational"
60
- },
61
- stop: {
62
- color: "red",
63
- label: "stop",
64
- logLevel: "informational"
65
- },
66
- success: {
67
- color: "green",
68
- label: "success",
69
- logLevel: "informational"
70
- },
71
- trace: {
72
- color: "cyanBright",
73
- label: "trace",
74
- logLevel: "trace"
75
- },
76
- wait: {
77
- color: "blue",
78
- label: "waiting",
79
- logLevel: "informational"
80
- },
81
- warn: {
82
- color: "yellow",
83
- label: "warning",
84
- logLevel: "warning"
85
- },
86
- warning: {
87
- color: "yellow",
88
- label: "warning",
89
- logLevel: "warning"
90
- },
91
- watch: {
92
- color: "yellowBright",
93
- label: "watching",
94
- logLevel: "informational"
95
- }
96
- };
97
- const EMPTY_SYMBOL = /* @__PURE__ */ Symbol("EMPTY");
98
-
99
- export { EMPTY_SYMBOL as E, LOG_TYPES as L };
@@ -1,119 +0,0 @@
1
- const EXTENDED_RFC_5424_LOG_LEVELS = {
2
- alert: 7,
3
- // Action must be taken immediately. Example: Entire website down, database unavailable, etc. This should trigger the SMS alerts and wake you up.
4
- critical: 6,
5
- // Critical conditions. Example: Application component unavailable, unexpected exception.
6
- debug: 1,
7
- // Detailed debug information.
8
- emergency: 8,
9
- // Emergency: system is unusable.
10
- error: 5,
11
- // Runtime errors that do not require immediate action but should typically be logged and monitored.
12
- informational: 2,
13
- // Interesting events. Examples: User logs in, SQL logs.
14
- notice: 3,
15
- // Normal but significant events.
16
- trace: 2,
17
- // Trace information.
18
- warning: 4
19
- // Exceptional occurrences that are not errors. Examples: Use of deprecated APIs, poor use of an API, undesirable things that are not necessarily wrong.
20
- };
21
- const LOG_TYPES = {
22
- alert: {
23
- color: "red",
24
- label: "alert",
25
- logLevel: "alert"
26
- },
27
- await: {
28
- color: "blue",
29
- label: "awaiting",
30
- logLevel: "informational"
31
- },
32
- complete: {
33
- color: "cyan",
34
- label: "complete",
35
- logLevel: "informational"
36
- },
37
- critical: {
38
- color: "redBright",
39
- label: "critical",
40
- logLevel: "critical"
41
- },
42
- debug: {
43
- color: "gray",
44
- label: "debug",
45
- logLevel: "debug"
46
- },
47
- emergency: {
48
- color: "redBright",
49
- label: "emergency",
50
- logLevel: "emergency"
51
- },
52
- error: {
53
- color: "red",
54
- label: "error",
55
- logLevel: "error"
56
- },
57
- info: {
58
- color: "blueBright",
59
- label: "info",
60
- logLevel: "informational"
61
- },
62
- log: {
63
- label: "",
64
- logLevel: "informational"
65
- },
66
- notice: {
67
- color: "magentaBright",
68
- label: "notice",
69
- logLevel: "notice"
70
- },
71
- pending: {
72
- color: "magenta",
73
- label: "pending",
74
- logLevel: "informational"
75
- },
76
- start: {
77
- color: "greenBright",
78
- label: "start",
79
- logLevel: "informational"
80
- },
81
- stop: {
82
- color: "red",
83
- label: "stop",
84
- logLevel: "informational"
85
- },
86
- success: {
87
- color: "green",
88
- label: "success",
89
- logLevel: "informational"
90
- },
91
- trace: {
92
- color: "cyanBright",
93
- label: "trace",
94
- logLevel: "trace"
95
- },
96
- wait: {
97
- color: "blue",
98
- label: "waiting",
99
- logLevel: "informational"
100
- },
101
- warn: {
102
- color: "yellow",
103
- label: "warning",
104
- logLevel: "warning"
105
- },
106
- warning: {
107
- color: "yellow",
108
- label: "warning",
109
- logLevel: "warning"
110
- },
111
- watch: {
112
- color: "yellowBright",
113
- label: "watching",
114
- logLevel: "informational"
115
- }
116
- };
117
- const EMPTY_SYMBOL = /* @__PURE__ */ Symbol("EMPTY");
118
-
119
- export { EMPTY_SYMBOL as E, LOG_TYPES as L, EXTENDED_RFC_5424_LOG_LEVELS as a };
@@ -1,76 +0,0 @@
1
- class PailError extends Error {
2
- /** HTTP status code (defaults to 500) */
3
- status;
4
- /** Explanation of what caused the failure */
5
- why;
6
- /** Suggested resolution steps */
7
- fix;
8
- /** Link to relevant documentation */
9
- link;
10
- constructor(options) {
11
- const resolvedOptions = typeof options === "string" ? { message: options } : options;
12
- super(resolvedOptions.message, resolvedOptions.cause === void 0 ? void 0 : { cause: resolvedOptions.cause });
13
- this.name = "PailError";
14
- this.status = resolvedOptions.status ?? 500;
15
- this.why = resolvedOptions.why;
16
- this.fix = resolvedOptions.fix;
17
- this.link = resolvedOptions.link;
18
- }
19
- /**
20
- * Converts the error to a JSON-serializable object.
21
- *
22
- * Includes all self-documenting fields in the output for structured logging.
23
- * @returns A plain object representation of the error
24
- */
25
- toJSON() {
26
- const json = {
27
- message: this.message,
28
- name: this.name,
29
- status: this.status
30
- };
31
- if (this.why) {
32
- json.why = this.why;
33
- }
34
- if (this.fix) {
35
- json.fix = this.fix;
36
- }
37
- if (this.link) {
38
- json.link = this.link;
39
- }
40
- if (this.stack) {
41
- json.stack = this.stack;
42
- }
43
- if (this.cause !== void 0) {
44
- json.cause = this.cause instanceof Error ? { message: this.cause.message, name: this.cause.name, stack: this.cause.stack } : this.cause;
45
- }
46
- return json;
47
- }
48
- /**
49
- * Returns a formatted string representation including self-documenting fields.
50
- * @returns Formatted error string with why/fix/link context
51
- */
52
- toString() {
53
- let output = `${this.name} [${this.status}]: ${this.message}`;
54
- if (this.why) {
55
- output += `
56
- Why: ${this.why}`;
57
- }
58
- if (this.fix) {
59
- output += `
60
- Fix: ${this.fix}`;
61
- }
62
- if (this.link) {
63
- output += `
64
- Link: ${this.link}`;
65
- }
66
- if (this.cause !== void 0) {
67
- const causeMessage = this.cause instanceof Error ? this.cause.message : String(this.cause);
68
- output += `
69
- Cause: ${causeMessage}`;
70
- }
71
- return output;
72
- }
73
- }
74
- const createPailError = (options) => new PailError(options);
75
-
76
- export { PailError, createPailError };
@@ -1,404 +0,0 @@
1
- const CHAR_GRADIENTS = {
2
- default: ["█", "▓", "▒", "░"],
3
- rect: ["▬", "▮", "▯", "▭"]
4
- };
5
- const BAR_REGEX = /\[([^[\]]*)\]/u;
6
- const getBarChar = (char, style, complete = true) => {
7
- if (char) {
8
- return char;
9
- }
10
- switch (style) {
11
- case "ascii": {
12
- return complete ? "#" : "-";
13
- }
14
- case "filled": {
15
- return complete ? "█" : " ";
16
- }
17
- case "rect": {
18
- return complete ? "▬" : "▭";
19
- }
20
- case "shades_classic": {
21
- return complete ? "█" : "░";
22
- }
23
- case "shades_grey": {
24
- return complete ? "▓" : "░";
25
- }
26
- case "solid": {
27
- return complete ? "█" : " ";
28
- }
29
- default: {
30
- return complete ? "█" : "░";
31
- }
32
- }
33
- };
34
- const applyStyleToOptions = (options) => {
35
- if (!options.style) {
36
- return options;
37
- }
38
- const { style } = options;
39
- const result = { ...options };
40
- if (result.barCompleteChar === void 0) {
41
- result.barCompleteChar = getBarChar(void 0, style, true);
42
- }
43
- if (result.barIncompleteChar === void 0) {
44
- result.barIncompleteChar = getBarChar(void 0, style, false);
45
- }
46
- if (result.barGlue === void 0) {
47
- result.barGlue = "";
48
- }
49
- return result;
50
- };
51
- class ProgressBar {
52
- options;
53
- current;
54
- startTime;
55
- interactiveManager;
56
- isActive = false;
57
- payload;
58
- /**
59
- * Creates a new progress bar instance.
60
- * @param options Configuration options for the progress bar
61
- * @param interactiveManager Optional interactive manager for rendering
62
- * @param payload Optional initial payload data for format placeholders
63
- */
64
- constructor(options, interactiveManager, payload) {
65
- const isCompleteArray = Array.isArray(options.barCompleteChar);
66
- const isIncompleteArray = Array.isArray(options.barIncompleteChar);
67
- const isGradientMode = isCompleteArray || isIncompleteArray;
68
- const completeChar = isCompleteArray ? options.barCompleteChar : getBarChar(options.barCompleteChar, "shades_classic");
69
- const incompleteChar = isIncompleteArray ? options.barIncompleteChar : getBarChar(options.barIncompleteChar, "shades_classic", false);
70
- this.options = {
71
- barCompleteChar: completeChar,
72
- barIncompleteChar: incompleteChar,
73
- current: 0,
74
- fps: 10,
75
- width: 40,
76
- ...options
77
- };
78
- if (isGradientMode) {
79
- if (!Array.isArray(this.options.barCompleteChar)) {
80
- this.options.barCompleteChar = [this.options.barCompleteChar];
81
- }
82
- if (!Array.isArray(this.options.barIncompleteChar)) {
83
- this.options.barIncompleteChar = [this.options.barIncompleteChar];
84
- }
85
- }
86
- this.current = this.options.current ?? 0;
87
- this.startTime = Date.now();
88
- this.interactiveManager = interactiveManager;
89
- this.payload = payload;
90
- }
91
- /**
92
- * Updates the progress bar to a new value.
93
- * @param current The current progress value
94
- * @param payload Optional payload data to merge with existing data
95
- */
96
- update(current, payload) {
97
- this.current = Math.min(current, this.options.total);
98
- if (payload) {
99
- this.payload = { ...this.payload, ...payload };
100
- }
101
- if (this.interactiveManager && this.isActive) {
102
- const progressBar = this.render();
103
- this.interactiveManager.update("stdout", [progressBar]);
104
- }
105
- }
106
- /**
107
- * Increments the progress bar by a specified step.
108
- * @param step Amount to increment (default: 1)
109
- * @param payload Optional payload data to merge with existing data
110
- */
111
- increment(step = 1, payload) {
112
- this.update(this.current + step, payload);
113
- }
114
- /**
115
- * Renders the progress bar as a formatted string.
116
- * @returns Formatted progress bar string with all placeholders replaced
117
- */
118
- // eslint-disable-next-line sonarjs/cognitive-complexity
119
- render() {
120
- const total = this.options.total > 0 ? this.options.total : 1;
121
- const width = Math.max(0, this.options.width ?? 40);
122
- const percentage = Math.max(0, Math.min(100, Math.round(this.current / total * 100)));
123
- const filled = Math.max(0, Math.min(width, Math.round(this.current / total * width)));
124
- const empty = width - filled;
125
- let bar;
126
- if (Array.isArray(this.options.barCompleteChar) || Array.isArray(this.options.barIncompleteChar)) {
127
- const completeChars = Array.isArray(this.options.barCompleteChar) ? this.options.barCompleteChar : void 0;
128
- const incompleteChars = Array.isArray(this.options.barIncompleteChar) ? this.options.barIncompleteChar : void 0;
129
- const completeChar = completeChars?.[completeChars.length - 1] ?? (typeof this.options.barCompleteChar === "string" ? this.options.barCompleteChar : "█");
130
- const incompleteChar = incompleteChars?.[0] ?? (typeof this.options.barIncompleteChar === "string" ? this.options.barIncompleteChar : "░");
131
- const completeLength = completeChars?.length ?? 1;
132
- const progressRatio = this.current / total;
133
- const totalSteps = width * completeLength;
134
- const currentStep = Math.round(progressRatio * totalSteps);
135
- const fractional = currentStep % completeLength;
136
- let barContent = "";
137
- for (let i = 0; i < width; i += 1) {
138
- if (i < filled) {
139
- const isGradientBoundary = i === filled - 1 && fractional > 0 && completeChars;
140
- barContent += isGradientBoundary ? completeChars[Math.max(0, fractional - 1)] : completeChar;
141
- } else {
142
- barContent += incompleteChar;
143
- }
144
- }
145
- bar = barContent;
146
- } else {
147
- const completeChar = typeof this.options.barCompleteChar === "string" ? this.options.barCompleteChar : "█";
148
- const incompleteChar = typeof this.options.barIncompleteChar === "string" ? this.options.barIncompleteChar : "░";
149
- bar = completeChar.repeat(filled) + incompleteChar.repeat(empty);
150
- }
151
- let format = this.options.format ?? "progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}";
152
- if (this.payload) {
153
- for (const [k, v] of Object.entries(this.payload)) {
154
- format = format.replaceAll(`{${k}}`, String(v));
155
- }
156
- }
157
- const eta = this.calculateETA();
158
- return format.replaceAll("{bar}", bar).replaceAll("{percentage}", String(percentage)).replaceAll("{value}", String(this.current)).replaceAll("{total}", String(this.options.total)).replaceAll("{eta}", String(eta));
159
- }
160
- /**
161
- * Starts the progress bar.
162
- * @param total Optional total value to set
163
- * @param startValue Optional starting value
164
- * @param payload Optional initial payload data
165
- */
166
- start(total, startValue, payload) {
167
- if (total !== void 0) {
168
- this.options.total = total;
169
- }
170
- if (startValue !== void 0) {
171
- this.current = startValue;
172
- }
173
- this.startTime = Date.now();
174
- this.isActive = true;
175
- if (this.interactiveManager) {
176
- this.interactiveManager.hook();
177
- this.update(this.current, payload);
178
- }
179
- }
180
- /**
181
- * Stops the progress bar and cleanup.
182
- */
183
- stop() {
184
- this.isActive = false;
185
- if (this.interactiveManager) {
186
- this.interactiveManager.unhook(false);
187
- }
188
- }
189
- calculateETA() {
190
- if (this.current === 0) {
191
- return 0;
192
- }
193
- const elapsed = (Date.now() - this.startTime) / 1e3;
194
- if (elapsed < 0.1) {
195
- return 0;
196
- }
197
- const rate = this.current / elapsed;
198
- const remaining = this.options.total - this.current;
199
- return Math.round(remaining / rate);
200
- }
201
- }
202
- class MultiBarInstance extends ProgressBar {
203
- multiBar;
204
- constructor(multiBar, options, payload) {
205
- super(options, void 0, payload);
206
- this.multiBar = multiBar;
207
- }
208
- update(current, payload) {
209
- super.update(current, payload);
210
- this.multiBar.renderAll();
211
- }
212
- getBarState() {
213
- const completeChar = Array.isArray(this.options.barCompleteChar) ? this.options.barCompleteChar[this.options.barCompleteChar.length - 1] : getBarChar(this.options.barCompleteChar, this.options.style ?? "shades_classic", true);
214
- return {
215
- char: completeChar ?? "█",
216
- current: this.current,
217
- total: this.options.total
218
- };
219
- }
220
- }
221
- class MultiProgressBar {
222
- bars = /* @__PURE__ */ new Map();
223
- options;
224
- interactiveManager;
225
- isActive = false;
226
- nextBarId = 0;
227
- composite = false;
228
- barColors = /* @__PURE__ */ new Map();
229
- /**
230
- * Creates a new multi progress bar manager.
231
- * @param options Configuration options for the progress bars
232
- * @param interactiveManager Optional interactive manager for rendering
233
- */
234
- constructor(options = {}, interactiveManager) {
235
- this.options = {
236
- barCompleteChar: getBarChar(void 0, "shades_classic"),
237
- barIncompleteChar: getBarChar(void 0, "shades_classic", false),
238
- composite: false,
239
- format: "progress [{bar}] {percentage}% | ETA: {eta}s | {value}/{total}",
240
- fps: 10,
241
- ...options
242
- };
243
- this.composite = this.options.composite ?? false;
244
- this.interactiveManager = interactiveManager;
245
- }
246
- /**
247
- * Creates a new progress bar within this multi-bar manager.
248
- * @param total Total value for the progress bar
249
- * @param current Starting current value (default: 0)
250
- * @param payload Optional initial payload data for format placeholders
251
- * @returns The created progress bar instance
252
- */
253
- create(total, current = 0, payload) {
254
- const barId = `bar_${this.nextBarId++}`;
255
- const bar = new MultiBarInstance(
256
- this,
257
- {
258
- barCompleteChar: this.options.barCompleteChar,
259
- barIncompleteChar: this.options.barIncompleteChar,
260
- current,
261
- format: this.options.format,
262
- fps: this.options.fps,
263
- total,
264
- width: 40
265
- },
266
- payload
267
- );
268
- this.bars.set(barId, bar);
269
- if (!this.isActive && this.interactiveManager) {
270
- this.interactiveManager.hook();
271
- this.isActive = true;
272
- this.renderAll();
273
- }
274
- return bar;
275
- }
276
- /**
277
- * Removes a progress bar from the manager.
278
- * @param bar The progress bar instance to remove
279
- * @returns True if the bar was removed, false if not found
280
- */
281
- remove(bar) {
282
- for (const [id, existingBar] of this.bars.entries()) {
283
- if (existingBar === bar) {
284
- this.bars.delete(id);
285
- if (this.bars.size === 0) {
286
- if (this.interactiveManager) {
287
- this.interactiveManager.unhook(false);
288
- }
289
- this.isActive = false;
290
- } else {
291
- this.renderAll();
292
- }
293
- return true;
294
- }
295
- }
296
- return false;
297
- }
298
- /**
299
- * Renders all progress bars.
300
- */
301
- renderAll() {
302
- if (!this.interactiveManager || !this.isActive) {
303
- return;
304
- }
305
- const lines = [];
306
- if (this.composite) {
307
- const barsArray = [...this.bars.values()];
308
- if (barsArray.length > 0) {
309
- const compositeOutput = this.renderComposite(barsArray);
310
- lines.push(compositeOutput);
311
- }
312
- } else {
313
- for (const bar of this.bars.values()) {
314
- lines.push(bar.render());
315
- }
316
- }
317
- this.interactiveManager.update("stdout", lines);
318
- }
319
- /**
320
- * Sets or removes a color function for a specific bar.
321
- * @param bar The progress bar instance to color (must be from this MultiProgressBar)
322
- * @param color Color function or undefined to remove color
323
- */
324
- setBarColor(bar, color) {
325
- for (const instance of this.bars.values()) {
326
- if (instance === bar) {
327
- if (color) {
328
- this.barColors.set(instance, color);
329
- } else {
330
- this.barColors.delete(instance);
331
- }
332
- break;
333
- }
334
- }
335
- }
336
- /**
337
- * Stops all progress bars and cleanup.
338
- */
339
- // eslint-disable-next-line sonarjs/no-identical-functions
340
- stop() {
341
- this.isActive = false;
342
- if (this.interactiveManager) {
343
- this.interactiveManager.unhook(false);
344
- }
345
- }
346
- renderComposite(bars) {
347
- if (bars.length === 0) {
348
- return "";
349
- }
350
- const firstBar = bars[0];
351
- if (!firstBar) {
352
- return "";
353
- }
354
- const output = firstBar.render();
355
- const barMatch = output.match(BAR_REGEX);
356
- if (!barMatch || !barMatch[1]) {
357
- return output;
358
- }
359
- const width = barMatch[1].length;
360
- const grid = Array.from({ length: width }, () => []);
361
- bars.forEach((bar, index) => {
362
- const state = bar.getBarState();
363
- const filled = Math.round(state.current / state.total * width);
364
- for (let i = 0; i < width; i += 1) {
365
- if (i < filled) {
366
- grid[i]?.push(index);
367
- }
368
- }
369
- });
370
- const composite = Array.from({ length: width }, (_, i) => this.getCompositeChar(bars, grid[i])).join("");
371
- return output.replace(BAR_REGEX, `[${composite}]`);
372
- }
373
- getCompositeChar(bars, stack) {
374
- if (!stack || stack.length === 0) {
375
- const defaultBar = bars[0];
376
- return defaultBar?.getBarState().char ?? "█";
377
- }
378
- const charGradient = CHAR_GRADIENTS[this.options.style === "rect" ? "rect" : "default"];
379
- const char = charGradient?.[Math.min(stack.length - 1, charGradient.length - 1)] ?? "█";
380
- let selectedBar;
381
- let smallestPercent = 100;
382
- for (const stackBarIndex of stack) {
383
- const bar = bars[stackBarIndex];
384
- if (!bar) {
385
- continue;
386
- }
387
- const barState = bar.getBarState();
388
- const barPercent = barState.current / barState.total * 100;
389
- if (barPercent < smallestPercent || barPercent === smallestPercent && (selectedBar === void 0 || stackBarIndex > selectedBar)) {
390
- smallestPercent = barPercent;
391
- selectedBar = stackBarIndex;
392
- }
393
- }
394
- const barIndex = selectedBar ?? stack[0];
395
- const targetBar = bars[barIndex ?? 0];
396
- if (!targetBar) {
397
- return char;
398
- }
399
- const barColor = this.barColors.get(targetBar);
400
- return barColor ? barColor(char) : char;
401
- }
402
- }
403
-
404
- export { MultiBarInstance, MultiProgressBar, ProgressBar, applyStyleToOptions, getBarChar };