@jsenv/test 3.6.6 → 3.6.8

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.
@@ -0,0 +1,295 @@
1
+ import process from "node:process";
2
+ import os from "node:os";
3
+ import tty from "node:tty";
4
+
5
+ // From: https://github.com/sindresorhus/has-flag/blob/main/index.js
6
+ /// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
7
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {
8
+ const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
9
+ const position = argv.indexOf(prefix + flag);
10
+ const terminatorPosition = argv.indexOf('--');
11
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
12
+ }
13
+
14
+ const {env} = process;
15
+
16
+ let flagForceColor;
17
+ if (
18
+ hasFlag('no-color')
19
+ || hasFlag('no-colors')
20
+ || hasFlag('color=false')
21
+ || hasFlag('color=never')
22
+ ) {
23
+ flagForceColor = 0;
24
+ } else if (
25
+ hasFlag('color')
26
+ || hasFlag('colors')
27
+ || hasFlag('color=true')
28
+ || hasFlag('color=always')
29
+ ) {
30
+ flagForceColor = 1;
31
+ }
32
+
33
+ function envForceColor() {
34
+ if (!('FORCE_COLOR' in env)) {
35
+ return;
36
+ }
37
+
38
+ if (env.FORCE_COLOR === 'true') {
39
+ return 1;
40
+ }
41
+
42
+ if (env.FORCE_COLOR === 'false') {
43
+ return 0;
44
+ }
45
+
46
+ if (env.FORCE_COLOR.length === 0) {
47
+ return 1;
48
+ }
49
+
50
+ const level = Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
51
+
52
+ if (![0, 1, 2, 3].includes(level)) {
53
+ return;
54
+ }
55
+
56
+ return level;
57
+ }
58
+
59
+ function translateLevel(level) {
60
+ if (level === 0) {
61
+ return false;
62
+ }
63
+
64
+ return {
65
+ level,
66
+ hasBasic: true,
67
+ has256: level >= 2,
68
+ has16m: level >= 3,
69
+ };
70
+ }
71
+
72
+ function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
73
+ const noFlagForceColor = envForceColor();
74
+ if (noFlagForceColor !== undefined) {
75
+ flagForceColor = noFlagForceColor;
76
+ }
77
+
78
+ const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
79
+
80
+ if (forceColor === 0) {
81
+ return 0;
82
+ }
83
+
84
+ if (sniffFlags) {
85
+ if (hasFlag('color=16m')
86
+ || hasFlag('color=full')
87
+ || hasFlag('color=truecolor')) {
88
+ return 3;
89
+ }
90
+
91
+ if (hasFlag('color=256')) {
92
+ return 2;
93
+ }
94
+ }
95
+
96
+ // Check for Azure DevOps pipelines.
97
+ // Has to be above the `!streamIsTTY` check.
98
+ if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
99
+ return 1;
100
+ }
101
+
102
+ if (haveStream && !streamIsTTY && forceColor === undefined) {
103
+ return 0;
104
+ }
105
+
106
+ const min = forceColor || 0;
107
+
108
+ if (env.TERM === 'dumb') {
109
+ return min;
110
+ }
111
+
112
+ if (process.platform === 'win32') {
113
+ // Windows 10 build 10586 is the first Windows release that supports 256 colors.
114
+ // Windows 10 build 14931 is the first release that supports 16m/TrueColor.
115
+ const osRelease = os.release().split('.');
116
+ if (
117
+ Number(osRelease[0]) >= 10
118
+ && Number(osRelease[2]) >= 10_586
119
+ ) {
120
+ return Number(osRelease[2]) >= 14_931 ? 3 : 2;
121
+ }
122
+
123
+ return 1;
124
+ }
125
+
126
+ if ('CI' in env) {
127
+ if (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {
128
+ return 3;
129
+ }
130
+
131
+ if (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
132
+ return 1;
133
+ }
134
+
135
+ return min;
136
+ }
137
+
138
+ if ('TEAMCITY_VERSION' in env) {
139
+ return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
140
+ }
141
+
142
+ if (env.COLORTERM === 'truecolor') {
143
+ return 3;
144
+ }
145
+
146
+ if (env.TERM === 'xterm-kitty') {
147
+ return 3;
148
+ }
149
+
150
+ if ('TERM_PROGRAM' in env) {
151
+ const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
152
+
153
+ switch (env.TERM_PROGRAM) {
154
+ case 'iTerm.app': {
155
+ return version >= 3 ? 3 : 2;
156
+ }
157
+
158
+ case 'Apple_Terminal': {
159
+ return 2;
160
+ }
161
+ // No default
162
+ }
163
+ }
164
+
165
+ if (/-256(color)?$/i.test(env.TERM)) {
166
+ return 2;
167
+ }
168
+
169
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
170
+ return 1;
171
+ }
172
+
173
+ if ('COLORTERM' in env) {
174
+ return 1;
175
+ }
176
+
177
+ return min;
178
+ }
179
+
180
+ function createSupportsColor(stream, options = {}) {
181
+ const level = _supportsColor(stream, {
182
+ streamIsTTY: stream && stream.isTTY,
183
+ ...options,
184
+ });
185
+
186
+ return translateLevel(level);
187
+ }
188
+
189
+ ({
190
+ stdout: createSupportsColor({isTTY: tty.isatty(1)}),
191
+ stderr: createSupportsColor({isTTY: tty.isatty(2)}),
192
+ });
193
+
194
+ function isUnicodeSupported() {
195
+ const {env} = process;
196
+ const {TERM, TERM_PROGRAM} = env;
197
+
198
+ if (process.platform !== 'win32') {
199
+ return TERM !== 'linux'; // Linux console (kernel)
200
+ }
201
+
202
+ return Boolean(env.WT_SESSION) // Windows Terminal
203
+ || Boolean(env.TERMINUS_SUBLIME) // Terminus (<0.2.27)
204
+ || env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder
205
+ || TERM_PROGRAM === 'Terminus-Sublime'
206
+ || TERM_PROGRAM === 'vscode'
207
+ || TERM === 'xterm-256color'
208
+ || TERM === 'alacritty'
209
+ || TERM === 'rxvt-unicode'
210
+ || TERM === 'rxvt-unicode-256color'
211
+ || env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
212
+ }
213
+
214
+ /* globals WorkerGlobalScope, DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, ServiceWorkerGlobalScope */
215
+
216
+ const isBrowser = globalThis.window?.document !== undefined;
217
+
218
+ globalThis.process?.versions?.node !== undefined;
219
+
220
+ globalThis.process?.versions?.bun !== undefined;
221
+
222
+ globalThis.Deno?.version?.deno !== undefined;
223
+
224
+ globalThis.process?.versions?.electron !== undefined;
225
+
226
+ globalThis.navigator?.userAgent?.includes('jsdom') === true;
227
+
228
+ typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope;
229
+
230
+ typeof DedicatedWorkerGlobalScope !== 'undefined' && globalThis instanceof DedicatedWorkerGlobalScope;
231
+
232
+ typeof SharedWorkerGlobalScope !== 'undefined' && globalThis instanceof SharedWorkerGlobalScope;
233
+
234
+ typeof ServiceWorkerGlobalScope !== 'undefined' && globalThis instanceof ServiceWorkerGlobalScope;
235
+
236
+ // Note: I'm intentionally not DRYing up the other variables to keep them "lazy".
237
+ const platform = globalThis.navigator?.userAgentData?.platform;
238
+
239
+ platform === 'macOS'
240
+ || globalThis.navigator?.platform === 'MacIntel' // Even on Apple silicon Macs.
241
+ || globalThis.navigator?.userAgent?.includes(' Mac ') === true
242
+ || globalThis.process?.platform === 'darwin';
243
+
244
+ platform === 'Windows'
245
+ || globalThis.navigator?.platform === 'Win32'
246
+ || globalThis.process?.platform === 'win32';
247
+
248
+ platform === 'Linux'
249
+ || globalThis.navigator?.platform?.startsWith('Linux') === true
250
+ || globalThis.navigator?.userAgent?.includes(' Linux ') === true
251
+ || globalThis.process?.platform === 'linux';
252
+
253
+ platform === 'Android'
254
+ || globalThis.navigator?.platform === 'Android'
255
+ || globalThis.navigator?.userAgent?.includes(' Android ') === true
256
+ || globalThis.process?.platform === 'android';
257
+
258
+ const ESC = '\u001B[';
259
+
260
+ !isBrowser && process.env.TERM_PROGRAM === 'Apple_Terminal';
261
+ const isWindows = !isBrowser && process.platform === 'win32';
262
+
263
+ isBrowser ? () => {
264
+ throw new Error('`process.cwd()` only works in Node.js, not the browser.');
265
+ } : process.cwd;
266
+
267
+ const cursorUp = (count = 1) => ESC + count + 'A';
268
+
269
+ const cursorLeft = ESC + 'G';
270
+
271
+ const eraseLines = count => {
272
+ let clear = '';
273
+
274
+ for (let i = 0; i < count; i++) {
275
+ clear += eraseLine + (i < count - 1 ? cursorUp() : '');
276
+ }
277
+
278
+ if (count) {
279
+ clear += cursorLeft;
280
+ }
281
+
282
+ return clear;
283
+ };
284
+ const eraseLine = ESC + '2K';
285
+ const eraseScreen = ESC + '2J';
286
+
287
+ const clearTerminal = isWindows
288
+ ? `${eraseScreen}${ESC}0f`
289
+ // 1. Erases the screen (Only done in case `2` is not supported)
290
+ // 2. Erases the whole screen including scrollback buffer
291
+ // 3. Moves cursor to the top-left position
292
+ // More info: https://www.real-world-systems.com/docs/ANSIcode.html
293
+ : `${eraseScreen}${ESC}3J${ESC}H`;
294
+
295
+ export { clearTerminal, createSupportsColor, eraseLines, isUnicodeSupported };
@@ -336,9 +336,19 @@ const applyPatternMatching = ({ url, pattern }) => {
336
336
  return applyPattern({ url, pattern });
337
337
  };
338
338
 
339
- const resolveAssociations = (associations, baseUrl) => {
340
- if (baseUrl && typeof baseUrl.href === "string") baseUrl = baseUrl.href;
341
- assertUrlLike(baseUrl, "baseUrl");
339
+ const resolveAssociations = (associations, resolver) => {
340
+ let resolve = () => {};
341
+ if (typeof resolver === "function") {
342
+ resolve = resolver;
343
+ } else if (typeof resolver === "string") {
344
+ const baseUrl = resolver;
345
+ assertUrlLike(baseUrl, "baseUrl");
346
+ resolve = (pattern) => new URL(pattern, baseUrl).href;
347
+ } else if (resolver && typeof resolver.href === "string") {
348
+ const baseUrl = resolver.href;
349
+ assertUrlLike(baseUrl, "baseUrl");
350
+ resolve = (pattern) => new URL(pattern, baseUrl).href;
351
+ }
342
352
 
343
353
  const associationsResolved = {};
344
354
  for (const key of Object.keys(associations)) {
@@ -349,12 +359,11 @@ const resolveAssociations = (associations, baseUrl) => {
349
359
  const valueAssociated = value[pattern];
350
360
  let patternResolved;
351
361
  try {
352
- patternResolved = String(new URL(pattern, baseUrl));
362
+ patternResolved = resolve(pattern);
353
363
  } catch {
354
364
  // it's not really an url, no need to perform url resolution nor encoding
355
365
  patternResolved = pattern;
356
366
  }
357
-
358
367
  valueMapResolved[patternResolved] = valueAssociated;
359
368
  }
360
369
  associationsResolved[key] = valueMapResolved;
@@ -477,34 +486,29 @@ const urlChildMayMatch = ({ url, associations, predicate }) => {
477
486
  };
478
487
 
479
488
  const applyAliases = ({ url, aliases }) => {
480
- let aliasFullMatchResult;
481
- const aliasMatchingKey = Object.keys(aliases).find((key) => {
482
- const aliasMatchResult = applyPatternMatching({
489
+ for (const key of Object.keys(aliases)) {
490
+ const matchResult = applyPatternMatching({
483
491
  pattern: key,
484
492
  url,
485
493
  });
486
- if (aliasMatchResult.matched) {
487
- aliasFullMatchResult = aliasMatchResult;
488
- return true;
494
+ if (!matchResult.matched) {
495
+ continue;
489
496
  }
490
- return false;
491
- });
492
- if (!aliasMatchingKey) {
493
- return url;
494
- }
495
- const { matchGroups } = aliasFullMatchResult;
496
- const alias = aliases[aliasMatchingKey];
497
- const parts = alias.split("*");
498
- let newUrl = "";
499
- let index = 0;
500
- for (const part of parts) {
501
- newUrl += `${part}`;
502
- if (index < parts.length - 1) {
503
- newUrl += matchGroups[index];
497
+ const { matchGroups } = matchResult;
498
+ const alias = aliases[key];
499
+ const parts = alias.split("*");
500
+ let newUrl = "";
501
+ let index = 0;
502
+ for (const part of parts) {
503
+ newUrl += `${part}`;
504
+ if (index < parts.length - 1) {
505
+ newUrl += matchGroups[index];
506
+ }
507
+ index++;
504
508
  }
505
- index++;
509
+ return newUrl;
506
510
  }
507
- return newUrl;
511
+ return url;
508
512
  };
509
513
 
510
514
  const matches = (url, patterns) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/test",
3
- "version": "3.6.6",
3
+ "version": "3.6.8",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,17 +41,17 @@
41
41
  "dependencies": {
42
42
  "@c88/v8-coverage": "0.1.1",
43
43
  "@jsenv/abort": "4.3.1",
44
- "@jsenv/ast": "6.6.6",
45
- "@jsenv/exception": "1.1.6",
46
- "@jsenv/filesystem": "4.14.4",
47
- "@jsenv/github-check-run": "0.2.19",
48
- "@jsenv/node-esm-resolution": "1.1.0",
49
- "@jsenv/humanize": "1.3.1",
50
- "@jsenv/plugin-supervisor": "1.6.11",
51
- "@jsenv/sourcemap": "1.3.3",
52
- "@jsenv/url-meta": "8.5.5",
53
- "@jsenv/urls": "2.7.0",
54
- "@jsenv/utils": "2.2.1",
44
+ "@jsenv/ast": "6.6.7",
45
+ "@jsenv/exception": "1.1.7",
46
+ "@jsenv/filesystem": "4.14.6",
47
+ "@jsenv/github-check-run": "0.2.21",
48
+ "@jsenv/node-esm-resolution": "1.2.0",
49
+ "@jsenv/humanize": "1.4.0",
50
+ "@jsenv/plugin-supervisor": "1.6.12",
51
+ "@jsenv/sourcemap": "1.3.4",
52
+ "@jsenv/url-meta": "8.5.6",
53
+ "@jsenv/urls": "2.7.1",
54
+ "@jsenv/utils": "2.3.0",
55
55
  "he": "1.2.0",
56
56
  "istanbul-lib-coverage": "3.2.2",
57
57
  "istanbul-lib-instrument": "6.0.3",
@@ -12,24 +12,26 @@ import {
12
12
  readGitHubWorkflowEnv,
13
13
  startGithubCheckRun,
14
14
  } from "@jsenv/github-check-run";
15
- import { createDetailedMessage, createLogger, UNICODE } from "@jsenv/humanize";
15
+ import {
16
+ createCallOrderer,
17
+ createDetailedMessage,
18
+ createLogger,
19
+ UNICODE,
20
+ } from "@jsenv/humanize";
16
21
  import { applyNodeEsmResolution } from "@jsenv/node-esm-resolution";
22
+ import {
23
+ countAvailableCpus,
24
+ getAvailableMemory,
25
+ getOsVersion,
26
+ startMonitoringCpuUsage,
27
+ startMonitoringMemoryUsage,
28
+ } from "@jsenv/os-metrics";
17
29
  import { URL_META } from "@jsenv/url-meta";
18
30
  import { urlIsInsideOf } from "@jsenv/urls";
19
31
  import { existsSync } from "node:fs";
20
- import {
21
- availableParallelism,
22
- cpus,
23
- freemem,
24
- release,
25
- totalmem,
26
- } from "node:os";
27
- import { memoryUsage } from "node:process";
28
32
  import { takeCoverage } from "node:v8";
29
33
  import stripAnsi from "strip-ansi";
30
34
  import { generateCoverage } from "../coverage/generate_coverage.js";
31
- import { createCallOrderer } from "../helpers/call_orderer.js";
32
- import { startMeasuringTotalCpuUsage } from "../helpers/cpu_usage.js";
33
35
  import { githubAnnotationFromError } from "./github_annotation_from_error.js";
34
36
  import { createIsInsideFragment } from "./is_inside_fragment.js";
35
37
  import { renderOutroContent, reporterList } from "./reporters/reporter_list.js";
@@ -159,22 +161,12 @@ export const executeTestPlan = async ({
159
161
  });
160
162
  }
161
163
 
162
- const cpuUsage = startMeasuringTotalCpuUsage();
163
- operation.addEndCallback(cpuUsage.stop);
164
- const processCpuUsageMonitoring = startMonitoringMetric(() => {
165
- return cpuUsage.thisProcess.active;
166
- });
167
- const osCpuUsageMonitoring = startMonitoringMetric(() => {
168
- return cpuUsage.overall.active;
169
- });
170
- const processMemoryUsageMonitoring = startMonitoringMetric(() => {
171
- return memoryUsage().rss;
172
- });
173
- const osMemoryUsageMonitoring = startMonitoringMetric(() => {
174
- const total = totalmem();
175
- const free = freemem();
176
- return total - free;
177
- });
164
+ const cpuMonitoring = startMonitoringCpuUsage();
165
+ operation.addEndCallback(cpuMonitoring.stop);
166
+ const [processCpuUsageMonitoring, osCpuUsageMonitoring] = cpuMonitoring;
167
+ const memoryMonitoring = startMonitoringMemoryUsage();
168
+ const [processMemoryUsageMonitoring, osMemoryUsageMonitoring] =
169
+ memoryMonitoring;
178
170
 
179
171
  const timingsOrigin = Date.now();
180
172
  const takeTiming = () => {
@@ -190,9 +182,9 @@ export const executeTestPlan = async ({
190
182
  : process.platform === "linux"
191
183
  ? "linux"
192
184
  : "other",
193
- version: release(),
185
+ version: getOsVersion(),
194
186
  availableCpu: countAvailableCpus(),
195
- availableMemory: totalmem(),
187
+ availableMemory: getAvailableMemory(),
196
188
  },
197
189
  runtime: {
198
190
  name: "node",
@@ -1160,59 +1152,6 @@ To fix this warning:
1160
1152
  return testPlanResult;
1161
1153
  };
1162
1154
 
1163
- const startMonitoringMetric = (measure) => {
1164
- const metrics = [];
1165
- const takeMeasure = () => {
1166
- const value = measure();
1167
- metrics.push(value);
1168
- return value;
1169
- };
1170
-
1171
- const info = {
1172
- start: takeMeasure(),
1173
- min: null,
1174
- max: null,
1175
- median: null,
1176
- end: null,
1177
- };
1178
- return {
1179
- info,
1180
- measure: takeMeasure,
1181
- end: () => {
1182
- info.end = takeMeasure();
1183
- metrics.sort((a, b) => a - b);
1184
- info.min = metrics[0];
1185
- info.max = metrics[metrics.length - 1];
1186
- info.median = medianFromSortedArray(metrics);
1187
- metrics.length = 0;
1188
- },
1189
- };
1190
- };
1191
-
1192
- const medianFromSortedArray = (array) => {
1193
- const length = array.length;
1194
- const isOdd = length % 2 === 1;
1195
- if (isOdd) {
1196
- const medianNumberIndex = (length - 1) / 2;
1197
- const medianNumber = array[medianNumberIndex];
1198
- return medianNumber;
1199
- }
1200
- const rightMiddleNumberIndex = length / 2;
1201
- const leftMiddleNumberIndex = rightMiddleNumberIndex - 1;
1202
- const leftMiddleNumber = array[leftMiddleNumberIndex];
1203
- const rightMiddleNumber = array[rightMiddleNumberIndex];
1204
- const medianNumber = (leftMiddleNumber + rightMiddleNumber) / 2;
1205
- return medianNumber;
1206
- };
1207
-
1208
- const countAvailableCpus = () => {
1209
- if (typeof availableParallelism === "function") {
1210
- return availableParallelism();
1211
- }
1212
- const cpuArray = cpus();
1213
- return cpuArray.length || 1;
1214
- };
1215
-
1216
1155
  const mutateCountersBeforeExecutionStarts = (counters) => {
1217
1156
  counters.executing++;
1218
1157
  counters.waiting--;
@@ -4,6 +4,9 @@ import {
4
4
  createDynamicLog,
5
5
  humanizeDuration,
6
6
  humanizeMemory,
7
+ renderBigSection,
8
+ renderDetails,
9
+ renderSection,
7
10
  UNICODE,
8
11
  } from "@jsenv/humanize";
9
12
  import { urlToFileSystemPath } from "@jsenv/urls";
@@ -949,76 +952,3 @@ const renderStatusRepartition = (counters, { showProgression } = {}) => {
949
952
  }
950
953
  return `${parts.join(", ")}`;
951
954
  };
952
-
953
- const renderBigSection = (params) => {
954
- return renderSection({
955
- width: 45,
956
- ...params,
957
- });
958
- };
959
-
960
- const renderSection = ({
961
- title,
962
- content,
963
- dashColor = ANSI.GREY,
964
- width = 38,
965
- bottomSeparator = true,
966
- }) => {
967
- let section = "";
968
-
969
- if (title) {
970
- const titleWidth = stripAnsi(title).length;
971
- const minWidthRequired = `--- … ---`.length;
972
- const needsTruncate = titleWidth + minWidthRequired >= width;
973
- if (needsTruncate) {
974
- const titleTruncated = title.slice(0, width - minWidthRequired);
975
- const leftDashes = ANSI.color("---", dashColor);
976
- const rightDashes = ANSI.color("---", dashColor);
977
- section += `${leftDashes} ${titleTruncated}… ${rightDashes}`;
978
- } else {
979
- const remainingWidth = width - titleWidth - 2; // 2 for spaces around the title
980
- const dashLeftCount = Math.floor(remainingWidth / 2);
981
- const dashRightCount = remainingWidth - dashLeftCount;
982
- const leftDashes = ANSI.color("-".repeat(dashLeftCount), dashColor);
983
- const rightDashes = ANSI.color("-".repeat(dashRightCount), dashColor);
984
- section += `${leftDashes} ${title} ${rightDashes}`;
985
- }
986
- section += "\n";
987
- } else {
988
- const topDashes = ANSI.color(`-`.repeat(width), dashColor);
989
- section += topDashes;
990
- section += "\n";
991
- }
992
- section += `${content}`;
993
- if (bottomSeparator) {
994
- section += "\n";
995
- const bottomDashes = ANSI.color(`-`.repeat(width), dashColor);
996
- section += bottomDashes;
997
- }
998
- return section;
999
- };
1000
-
1001
- const renderDetails = (data) => {
1002
- const details = [];
1003
- for (const key of Object.keys(data)) {
1004
- const value = data[key];
1005
- let valueString = "";
1006
- valueString += ANSI.color(`${key}:`, ANSI.GREY);
1007
- const useNonGreyAnsiColor =
1008
- typeof value === "string" && value.includes("\x1b");
1009
- valueString += " ";
1010
- valueString += useNonGreyAnsiColor
1011
- ? value
1012
- : ANSI.color(String(value), ANSI.GREY);
1013
- details.push(valueString);
1014
- }
1015
- if (details.length === 0) {
1016
- return "";
1017
- }
1018
-
1019
- let string = "";
1020
- string += ` ${ANSI.color("(", ANSI.GREY)}`;
1021
- string += details.join(ANSI.color(", ", ANSI.GREY));
1022
- string += ANSI.color(")", ANSI.GREY);
1023
- return string;
1024
- };
@@ -1,39 +0,0 @@
1
- export const createCallOrderer = () => {
2
- const queue = [];
3
- const callWhenPreviousExecutionAreDone = (executionIndex, callback) => {
4
- if (queue[executionIndex]) {
5
- throw new Error(`${executionIndex} already used`);
6
- }
7
-
8
- let allBeforeAreDone = true;
9
- if (executionIndex > 0) {
10
- let beforeIndex = executionIndex - 1;
11
- do {
12
- const value = queue[beforeIndex];
13
- if (!value) {
14
- allBeforeAreDone = false;
15
- break;
16
- }
17
- } while (beforeIndex--);
18
- }
19
- if (!allBeforeAreDone) {
20
- queue[executionIndex] = callback;
21
- return;
22
- }
23
- queue[executionIndex] = true;
24
- callback();
25
- let afterIndex = executionIndex + 1;
26
- while (afterIndex < queue.length) {
27
- const value = queue[afterIndex];
28
- if (value === undefined) {
29
- break;
30
- }
31
- if (typeof value === "function") {
32
- queue[afterIndex] = true;
33
- value();
34
- }
35
- afterIndex++;
36
- }
37
- };
38
- return callWhenPreviousExecutionAreDone;
39
- };