concurrently 6.5.0 → 7.1.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 (82) hide show
  1. package/README.md +82 -22
  2. package/dist/bin/concurrently.d.ts +2 -0
  3. package/dist/bin/concurrently.js +193 -0
  4. package/dist/bin/epilogue.d.ts +1 -0
  5. package/dist/bin/epilogue.js +69 -0
  6. package/dist/src/command-parser/command-parser.d.ts +19 -0
  7. package/dist/src/command-parser/command-parser.js +2 -0
  8. package/dist/src/command-parser/expand-npm-shortcut.d.ts +8 -0
  9. package/{src → dist/src}/command-parser/expand-npm-shortcut.js +10 -3
  10. package/dist/src/command-parser/expand-npm-wildcard.d.ts +13 -0
  11. package/dist/src/command-parser/expand-npm-wildcard.js +82 -0
  12. package/dist/src/command-parser/strip-quotes.d.ts +10 -0
  13. package/{src → dist/src}/command-parser/strip-quotes.js +10 -4
  14. package/dist/src/command.d.ts +101 -0
  15. package/{src → dist/src}/command.js +53 -29
  16. package/dist/src/completion-listener.d.ts +37 -0
  17. package/dist/src/completion-listener.js +60 -0
  18. package/dist/src/concurrently.d.ts +77 -0
  19. package/dist/src/concurrently.js +120 -0
  20. package/dist/src/defaults.d.ts +52 -0
  21. package/dist/src/defaults.js +58 -0
  22. package/dist/src/flow-control/flow-controller.d.ts +13 -0
  23. package/dist/src/flow-control/flow-controller.js +2 -0
  24. package/dist/src/flow-control/input-handler.d.ts +33 -0
  25. package/dist/src/flow-control/input-handler.js +73 -0
  26. package/dist/src/flow-control/kill-on-signal.d.ts +17 -0
  27. package/{src → dist/src}/flow-control/kill-on-signal.js +13 -11
  28. package/dist/src/flow-control/kill-others.d.ts +18 -0
  29. package/dist/src/flow-control/kill-others.js +35 -0
  30. package/dist/src/flow-control/log-error.d.ts +15 -0
  31. package/dist/src/flow-control/log-error.js +21 -0
  32. package/dist/src/flow-control/log-exit.d.ts +15 -0
  33. package/dist/src/flow-control/log-exit.js +19 -0
  34. package/dist/src/flow-control/log-output.d.ts +15 -0
  35. package/{src → dist/src}/flow-control/log-output.js +13 -5
  36. package/dist/src/flow-control/log-timings.d.ts +27 -0
  37. package/dist/src/flow-control/log-timings.js +88 -0
  38. package/dist/src/flow-control/restart-process.d.ts +22 -0
  39. package/dist/src/flow-control/restart-process.js +71 -0
  40. package/dist/src/get-spawn-opts.d.ts +30 -0
  41. package/dist/src/get-spawn-opts.js +11 -0
  42. package/dist/src/index.d.ts +69 -0
  43. package/dist/src/index.js +69 -0
  44. package/dist/src/logger.d.ts +72 -0
  45. package/{src → dist/src}/logger.js +77 -58
  46. package/dist/src/output-writer.d.ts +19 -0
  47. package/dist/src/output-writer.js +69 -0
  48. package/index.js +6 -68
  49. package/index.mjs +9 -0
  50. package/package.json +38 -11
  51. package/bin/concurrently.js +0 -186
  52. package/bin/concurrently.spec.js +0 -428
  53. package/bin/epilogue.txt +0 -46
  54. package/src/command-parser/expand-npm-shortcut.spec.js +0 -36
  55. package/src/command-parser/expand-npm-wildcard.js +0 -43
  56. package/src/command-parser/expand-npm-wildcard.spec.js +0 -87
  57. package/src/command-parser/strip-quotes.spec.js +0 -20
  58. package/src/command.spec.js +0 -275
  59. package/src/completion-listener.js +0 -39
  60. package/src/completion-listener.spec.js +0 -89
  61. package/src/concurrently.js +0 -116
  62. package/src/concurrently.spec.js +0 -199
  63. package/src/defaults.js +0 -35
  64. package/src/flow-control/base-handler.js +0 -16
  65. package/src/flow-control/base-handler.spec.js +0 -22
  66. package/src/flow-control/input-handler.js +0 -50
  67. package/src/flow-control/input-handler.spec.js +0 -113
  68. package/src/flow-control/kill-on-signal.spec.js +0 -79
  69. package/src/flow-control/kill-others.js +0 -38
  70. package/src/flow-control/kill-others.spec.js +0 -66
  71. package/src/flow-control/log-error.js +0 -18
  72. package/src/flow-control/log-error.spec.js +0 -40
  73. package/src/flow-control/log-exit.js +0 -11
  74. package/src/flow-control/log-exit.spec.js +0 -36
  75. package/src/flow-control/log-output.spec.js +0 -41
  76. package/src/flow-control/log-timings.js +0 -64
  77. package/src/flow-control/log-timings.spec.js +0 -137
  78. package/src/flow-control/restart-process.js +0 -56
  79. package/src/flow-control/restart-process.spec.js +0 -139
  80. package/src/get-spawn-opts.js +0 -16
  81. package/src/get-spawn-opts.spec.js +0 -30
  82. package/src/logger.spec.js +0 -318
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RestartProcess = exports.LogTimings = exports.LogOutput = exports.LogExit = exports.LogError = exports.KillOthers = exports.KillOnSignal = exports.InputHandler = exports.Command = exports.Logger = exports.concurrently = void 0;
4
+ const command_1 = require("./command");
5
+ Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return command_1.Command; } });
6
+ const concurrently_1 = require("./concurrently");
7
+ Object.defineProperty(exports, "concurrently", { enumerable: true, get: function () { return concurrently_1.concurrently; } });
8
+ const input_handler_1 = require("./flow-control/input-handler");
9
+ Object.defineProperty(exports, "InputHandler", { enumerable: true, get: function () { return input_handler_1.InputHandler; } });
10
+ const kill_on_signal_1 = require("./flow-control/kill-on-signal");
11
+ Object.defineProperty(exports, "KillOnSignal", { enumerable: true, get: function () { return kill_on_signal_1.KillOnSignal; } });
12
+ const kill_others_1 = require("./flow-control/kill-others");
13
+ Object.defineProperty(exports, "KillOthers", { enumerable: true, get: function () { return kill_others_1.KillOthers; } });
14
+ const log_error_1 = require("./flow-control/log-error");
15
+ Object.defineProperty(exports, "LogError", { enumerable: true, get: function () { return log_error_1.LogError; } });
16
+ const log_exit_1 = require("./flow-control/log-exit");
17
+ Object.defineProperty(exports, "LogExit", { enumerable: true, get: function () { return log_exit_1.LogExit; } });
18
+ const log_output_1 = require("./flow-control/log-output");
19
+ Object.defineProperty(exports, "LogOutput", { enumerable: true, get: function () { return log_output_1.LogOutput; } });
20
+ const log_timings_1 = require("./flow-control/log-timings");
21
+ Object.defineProperty(exports, "LogTimings", { enumerable: true, get: function () { return log_timings_1.LogTimings; } });
22
+ const restart_process_1 = require("./flow-control/restart-process");
23
+ Object.defineProperty(exports, "RestartProcess", { enumerable: true, get: function () { return restart_process_1.RestartProcess; } });
24
+ const logger_1 = require("./logger");
25
+ Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
26
+ exports.default = (commands, options = {}) => {
27
+ const logger = new logger_1.Logger({
28
+ hide: options.hide,
29
+ prefixFormat: options.prefix,
30
+ prefixLength: options.prefixLength,
31
+ raw: options.raw,
32
+ timestampFormat: options.timestampFormat,
33
+ });
34
+ return (0, concurrently_1.concurrently)(commands, {
35
+ maxProcesses: options.maxProcesses,
36
+ raw: options.raw,
37
+ successCondition: options.successCondition,
38
+ cwd: options.cwd,
39
+ logger,
40
+ outputStream: options.outputStream || process.stdout,
41
+ group: options.group,
42
+ controllers: [
43
+ new log_error_1.LogError({ logger }),
44
+ new log_output_1.LogOutput({ logger }),
45
+ new log_exit_1.LogExit({ logger }),
46
+ new input_handler_1.InputHandler({
47
+ logger,
48
+ defaultInputTarget: options.defaultInputTarget,
49
+ inputStream: options.inputStream || (options.handleInput && process.stdin),
50
+ pauseInputStreamOnFinish: options.pauseInputStreamOnFinish,
51
+ }),
52
+ new kill_on_signal_1.KillOnSignal({ process }),
53
+ new restart_process_1.RestartProcess({
54
+ logger,
55
+ delay: options.restartDelay,
56
+ tries: options.restartTries,
57
+ }),
58
+ new kill_others_1.KillOthers({
59
+ logger,
60
+ conditions: options.killOthers
61
+ }),
62
+ new log_timings_1.LogTimings({
63
+ logger: options.timings ? logger : null,
64
+ timestampFormat: options.timestampFormat,
65
+ })
66
+ ],
67
+ prefixColors: options.prefixColors || [],
68
+ });
69
+ };
@@ -0,0 +1,72 @@
1
+ import * as Rx from 'rxjs';
2
+ import { Command, CommandIdentifier } from './command';
3
+ export declare class Logger {
4
+ private readonly hide;
5
+ private readonly raw;
6
+ private readonly prefixFormat?;
7
+ private readonly prefixLength;
8
+ private readonly timestampFormat;
9
+ /**
10
+ * Last character emitted.
11
+ * If `undefined`, then nothing has been logged yet.
12
+ */
13
+ private lastChar?;
14
+ /**
15
+ * Observable that emits when there's been output logged.
16
+ * If `command` is is `undefined`, then the log is for a global event.
17
+ */
18
+ readonly output: Rx.Subject<{
19
+ command: Command | undefined;
20
+ text: string;
21
+ }>;
22
+ constructor({ hide, prefixFormat, prefixLength, raw, timestampFormat }: {
23
+ /**
24
+ * Which command(s) should have their output hidden.
25
+ */
26
+ hide?: CommandIdentifier | CommandIdentifier[];
27
+ /**
28
+ * Whether output should be formatted to include prefixes and whether "event" logs will be
29
+ * logged.
30
+ */
31
+ raw?: boolean;
32
+ /**
33
+ * The prefix format to use when logging a command's output.
34
+ * Defaults to the command's index.
35
+ */
36
+ prefixFormat?: string;
37
+ /**
38
+ * How many characters should a prefix have at most, used when the prefix format is `command`.
39
+ */
40
+ prefixLength?: number;
41
+ /**
42
+ * Date format used when logging date/time.
43
+ * @see https://date-fns.org/v2.0.1/docs/format
44
+ */
45
+ timestampFormat?: string;
46
+ });
47
+ private shortenText;
48
+ private getPrefixesFor;
49
+ getPrefix(command: Command): string;
50
+ colorText(command: Command, text: string): string;
51
+ /**
52
+ * Logs an event for a command (e.g. start, stop).
53
+ *
54
+ * If raw mode is on, then nothing is logged.
55
+ */
56
+ logCommandEvent(text: string, command: Command): void;
57
+ logCommandText(text: string, command: Command): void;
58
+ /**
59
+ * Logs a global event (e.g. sending signals to processes).
60
+ *
61
+ * If raw mode is on, then nothing is logged.
62
+ */
63
+ logGlobalEvent(text: string): void;
64
+ /**
65
+ * Logs a table from an input object array, like `console.table`.
66
+ *
67
+ * Each row is a single input item, and they are presented in the input order.
68
+ */
69
+ logTable(tableContents: any[]): void;
70
+ log(prefix: string, text: string, command?: Command): void;
71
+ emit(command: Command | undefined, text: string): void;
72
+ }
@@ -1,107 +1,134 @@
1
- const chalk = require('chalk');
2
- const _ = require('lodash');
3
- const formatDate = require('date-fns/format');
4
-
5
- const defaults = require('./defaults');
6
-
7
- module.exports = class Logger {
8
- constructor({ hide, outputStream, prefixFormat, prefixLength, raw, timestampFormat }) {
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.Logger = void 0;
26
+ const chalk_1 = __importDefault(require("chalk"));
27
+ const lodash_1 = __importDefault(require("lodash"));
28
+ const format_1 = __importDefault(require("date-fns/format"));
29
+ const Rx = __importStar(require("rxjs"));
30
+ const defaults = __importStar(require("./defaults"));
31
+ class Logger {
32
+ constructor({ hide, prefixFormat, prefixLength, raw = false, timestampFormat }) {
33
+ /**
34
+ * Observable that emits when there's been output logged.
35
+ * If `command` is is `undefined`, then the log is for a global event.
36
+ */
37
+ this.output = new Rx.Subject();
9
38
  // To avoid empty strings from hiding the output of commands that don't have a name,
10
39
  // keep in the list of commands to hide only strings with some length.
11
40
  // This might happen through the CLI when no `--hide` argument is specified, for example.
12
- this.hide = _.castArray(hide).filter(name => name || name === 0).map(String);
41
+ this.hide = lodash_1.default.castArray(hide).filter(name => name || name === 0).map(String);
13
42
  this.raw = raw;
14
- this.outputStream = outputStream;
15
43
  this.prefixFormat = prefixFormat;
16
44
  this.prefixLength = prefixLength || defaults.prefixLength;
17
45
  this.timestampFormat = timestampFormat || defaults.timestampFormat;
18
46
  }
19
-
20
47
  shortenText(text) {
21
48
  if (!text || text.length <= this.prefixLength) {
22
49
  return text;
23
50
  }
24
-
25
51
  const ellipsis = '..';
26
52
  const prefixLength = this.prefixLength - ellipsis.length;
27
53
  const endLength = Math.floor(prefixLength / 2);
28
54
  const beginningLength = prefixLength - endLength;
29
-
30
55
  const beginnning = text.substring(0, beginningLength);
31
56
  const end = text.substring(text.length - endLength, text.length);
32
57
  return beginnning + ellipsis + end;
33
58
  }
34
-
35
59
  getPrefixesFor(command) {
36
60
  return {
37
- none: '',
38
- pid: command.pid,
39
- index: command.index,
61
+ pid: String(command.pid),
62
+ index: String(command.index),
40
63
  name: command.name,
41
64
  command: this.shortenText(command.command),
42
- time: formatDate(Date.now(), this.timestampFormat)
65
+ time: (0, format_1.default)(Date.now(), this.timestampFormat),
43
66
  };
44
67
  }
45
-
46
68
  getPrefix(command) {
47
69
  const prefix = this.prefixFormat || (command.name ? 'name' : 'index');
48
70
  if (prefix === 'none') {
49
71
  return '';
50
72
  }
51
-
52
73
  const prefixes = this.getPrefixesFor(command);
53
74
  if (Object.keys(prefixes).includes(prefix)) {
54
75
  return `[${prefixes[prefix]}]`;
55
76
  }
56
-
57
- return _.reduce(prefixes, (prev, val, key) => {
58
- const keyRegex = new RegExp(_.escapeRegExp(`{${key}}`), 'g');
59
- return prev.replace(keyRegex, val);
77
+ return lodash_1.default.reduce(prefixes, (prev, val, key) => {
78
+ const keyRegex = new RegExp(lodash_1.default.escapeRegExp(`{${key}}`), 'g');
79
+ return prev.replace(keyRegex, String(val));
60
80
  }, prefix);
61
81
  }
62
-
63
82
  colorText(command, text) {
64
83
  let color;
65
84
  if (command.prefixColor && command.prefixColor.startsWith('#')) {
66
- color = chalk.hex(command.prefixColor);
67
- } else {
68
- const defaultColor = _.get(chalk, defaults.prefixColors, chalk.reset);
69
- color = _.get(chalk, command.prefixColor, defaultColor);
85
+ color = chalk_1.default.hex(command.prefixColor);
86
+ }
87
+ else {
88
+ const defaultColor = lodash_1.default.get(chalk_1.default, defaults.prefixColors, chalk_1.default.reset);
89
+ color = lodash_1.default.get(chalk_1.default, command.prefixColor, defaultColor);
70
90
  }
71
91
  return color(text);
72
92
  }
73
-
93
+ /**
94
+ * Logs an event for a command (e.g. start, stop).
95
+ *
96
+ * If raw mode is on, then nothing is logged.
97
+ */
74
98
  logCommandEvent(text, command) {
75
99
  if (this.raw) {
76
100
  return;
77
101
  }
78
-
79
- this.logCommandText(chalk.reset(text) + '\n', command);
102
+ this.logCommandText(chalk_1.default.reset(text) + '\n', command);
80
103
  }
81
-
82
104
  logCommandText(text, command) {
83
105
  if (this.hide.includes(String(command.index)) || this.hide.includes(command.name)) {
84
106
  return;
85
107
  }
86
-
87
108
  const prefix = this.colorText(command, this.getPrefix(command));
88
- return this.log(prefix + (prefix ? ' ' : ''), text);
109
+ return this.log(prefix + (prefix ? ' ' : ''), text, command);
89
110
  }
90
-
111
+ /**
112
+ * Logs a global event (e.g. sending signals to processes).
113
+ *
114
+ * If raw mode is on, then nothing is logged.
115
+ */
91
116
  logGlobalEvent(text) {
92
117
  if (this.raw) {
93
118
  return;
94
119
  }
95
-
96
- this.log(chalk.reset('-->') + ' ', chalk.reset(text) + '\n');
120
+ this.log(chalk_1.default.reset('-->') + ' ', chalk_1.default.reset(text) + '\n');
97
121
  }
98
-
122
+ /**
123
+ * Logs a table from an input object array, like `console.table`.
124
+ *
125
+ * Each row is a single input item, and they are presented in the input order.
126
+ */
99
127
  logTable(tableContents) {
100
128
  // For now, can only print array tables with some content.
101
129
  if (this.raw || !Array.isArray(tableContents) || !tableContents.length) {
102
130
  return;
103
131
  }
104
-
105
132
  let nextColIndex = 0;
106
133
  const headers = {};
107
134
  const contentRows = tableContents.map(row => {
@@ -110,11 +137,9 @@ module.exports = class Logger {
110
137
  if (!headers[col]) {
111
138
  headers[col] = {
112
139
  index: nextColIndex++,
113
- //
114
140
  length: col.length,
115
141
  };
116
142
  }
117
-
118
143
  const colIndex = headers[col].index;
119
144
  const formattedValue = String(row[col] == null ? '' : row[col]);
120
145
  // Update the column length in case this rows value is longer than the previous length for the column.
@@ -124,22 +149,17 @@ module.exports = class Logger {
124
149
  });
125
150
  return rowContents;
126
151
  });
127
-
128
152
  const headersFormatted = Object
129
153
  .keys(headers)
130
154
  .map(header => header.padEnd(headers[header].length, ' '));
131
-
132
155
  if (!headersFormatted.length) {
133
156
  // No columns exist.
134
157
  return;
135
158
  }
136
-
137
159
  const borderRowFormatted = headersFormatted.map(header => '─'.padEnd(header.length, '─'));
138
-
139
160
  this.logGlobalEvent(`┌─${borderRowFormatted.join('─┬─')}─┐`);
140
161
  this.logGlobalEvent(`│ ${headersFormatted.join(' │ ')} │`);
141
162
  this.logGlobalEvent(`├─${borderRowFormatted.join('─┼─')}─┤`);
142
-
143
163
  contentRows.forEach(contentRow => {
144
164
  const contentRowFormatted = headersFormatted.map((header, colIndex) => {
145
165
  // If the table was expanded after this row was processed, it won't have this column.
@@ -149,18 +169,14 @@ module.exports = class Logger {
149
169
  });
150
170
  this.logGlobalEvent(`│ ${contentRowFormatted.join(' │ ')} │`);
151
171
  });
152
-
153
172
  this.logGlobalEvent(`└─${borderRowFormatted.join('─┴─')}─┘`);
154
173
  }
155
-
156
- log(prefix, text) {
174
+ log(prefix, text, command) {
157
175
  if (this.raw) {
158
- return this.outputStream.write(text);
176
+ return this.emit(command, text);
159
177
  }
160
-
161
178
  // #70 - replace some ANSI code that would impact clearing lines
162
179
  text = text.replace(/\u2026/g, '...');
163
-
164
180
  const lines = text.split('\n').map((line, index, lines) => {
165
181
  // First line will write prefix only if we finished the last write with a LF.
166
182
  // Last line won't write prefix because it should be empty.
@@ -169,12 +185,15 @@ module.exports = class Logger {
169
185
  }
170
186
  return prefix + line;
171
187
  });
172
-
173
188
  if (!this.lastChar || this.lastChar === '\n') {
174
- this.outputStream.write(prefix);
189
+ this.emit(command, prefix);
175
190
  }
176
-
177
191
  this.lastChar = text[text.length - 1];
178
- this.outputStream.write(lines.join('\n'));
192
+ this.emit(command, lines.join('\n'));
179
193
  }
180
- };
194
+ emit(command, text) {
195
+ this.output.next({ command, text });
196
+ }
197
+ }
198
+ exports.Logger = Logger;
199
+ ;
@@ -0,0 +1,19 @@
1
+ /// <reference types="node" />
2
+ import { Writable } from 'stream';
3
+ import { Command } from './command';
4
+ /**
5
+ * Class responsible for actually writing output onto a writable stream.
6
+ */
7
+ export declare class OutputWriter {
8
+ private readonly outputStream;
9
+ private readonly group;
10
+ readonly buffers: string[][];
11
+ activeCommandIndex: number;
12
+ constructor({ outputStream, group, commands }: {
13
+ outputStream: Writable;
14
+ group: boolean;
15
+ commands: Command[];
16
+ });
17
+ write(command: Command | undefined, text: string): void;
18
+ private flushBuffer;
19
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.OutputWriter = void 0;
23
+ const Rx = __importStar(require("rxjs"));
24
+ /**
25
+ * Class responsible for actually writing output onto a writable stream.
26
+ */
27
+ class OutputWriter {
28
+ constructor({ outputStream, group, commands }) {
29
+ this.activeCommandIndex = 0;
30
+ this.outputStream = outputStream;
31
+ this.group = group;
32
+ this.buffers = commands.map(() => []);
33
+ if (this.group) {
34
+ Rx.merge(...commands.map(c => c.close))
35
+ .subscribe(command => {
36
+ if (command.index !== this.activeCommandIndex) {
37
+ return;
38
+ }
39
+ for (let i = command.index + 1; i < commands.length; i++) {
40
+ this.activeCommandIndex = i;
41
+ this.flushBuffer(i);
42
+ if (!commands[i].exited) {
43
+ break;
44
+ }
45
+ }
46
+ });
47
+ }
48
+ }
49
+ write(command, text) {
50
+ if (this.group && command) {
51
+ if (command.index <= this.activeCommandIndex) {
52
+ this.outputStream.write(text);
53
+ }
54
+ else {
55
+ this.buffers[command.index].push(text);
56
+ }
57
+ }
58
+ else {
59
+ // "global" logs (command=null) are output out of order
60
+ this.outputStream.write(text);
61
+ }
62
+ }
63
+ flushBuffer(index) {
64
+ this.buffers[index].forEach(t => this.outputStream.write(t));
65
+ this.buffers[index] = [];
66
+ }
67
+ }
68
+ exports.OutputWriter = OutputWriter;
69
+ ;
package/index.js CHANGED
@@ -1,69 +1,7 @@
1
- const InputHandler = require('./src/flow-control/input-handler');
2
- const KillOnSignal = require('./src/flow-control/kill-on-signal');
3
- const KillOthers = require('./src/flow-control/kill-others');
4
- const LogError = require('./src/flow-control/log-error');
5
- const LogExit = require('./src/flow-control/log-exit');
6
- const LogOutput = require('./src/flow-control/log-output');
7
- const RestartProcess = require('./src/flow-control/restart-process');
1
+ //
2
+ // While in local development, make sure you've run `npm run build` first.
3
+ //
8
4
 
9
- const concurrently = require('./src/concurrently');
10
- const Logger = require('./src/logger');
11
- const LogTimings = require( './src/flow-control/log-timings' );
12
-
13
- module.exports = exports = (commands, options = {}) => {
14
- const logger = new Logger({
15
- hide: options.hide,
16
- outputStream: options.outputStream || process.stdout,
17
- prefixFormat: options.prefix,
18
- prefixLength: options.prefixLength,
19
- raw: options.raw,
20
- timestampFormat: options.timestampFormat,
21
- });
22
-
23
- return concurrently(commands, {
24
- maxProcesses: options.maxProcesses,
25
- raw: options.raw,
26
- successCondition: options.successCondition,
27
- cwd: options.cwd,
28
- controllers: [
29
- new LogError({ logger }),
30
- new LogOutput({ logger }),
31
- new LogExit({ logger }),
32
- new InputHandler({
33
- logger,
34
- defaultInputTarget: options.defaultInputTarget,
35
- inputStream: options.inputStream || (options.handleInput && process.stdin),
36
- pauseInputStreamOnFinish: options.pauseInputStreamOnFinish,
37
- }),
38
- new KillOnSignal({ process }),
39
- new RestartProcess({
40
- logger,
41
- delay: options.restartDelay,
42
- tries: options.restartTries,
43
- }),
44
- new KillOthers({
45
- logger,
46
- conditions: options.killOthers
47
- }),
48
- new LogTimings({
49
- logger: options.timings ? logger: null,
50
- timestampFormat: options.timestampFormat,
51
- })
52
- ],
53
- prefixColors: options.prefixColors || [],
54
- timings: options.timings
55
- });
56
- };
57
-
58
- // Export all flow controllers and the main concurrently function,
59
- // so that 3rd-parties can use them however they want
60
- exports.concurrently = concurrently;
61
- exports.Logger = Logger;
62
- exports.InputHandler = InputHandler;
63
- exports.KillOnSignal = KillOnSignal;
64
- exports.KillOthers = KillOthers;
65
- exports.LogError = LogError;
66
- exports.LogExit = LogExit;
67
- exports.LogOutput = LogOutput;
68
- exports.RestartProcess = RestartProcess;
69
- exports.LogTimings = LogTimings;
5
+ const concurrently = require('./dist/src/index.js');
6
+ module.exports = exports = concurrently.default;
7
+ Object.assign(exports, concurrently);
package/index.mjs ADDED
@@ -0,0 +1,9 @@
1
+ //
2
+ // While in local development, make sure you've run `npm run build` first.
3
+ //
4
+
5
+ // NOTE: the star reexport doesn't work in Node <12.20, <14.13 and <15.
6
+ export * from './dist/src/index.js';
7
+
8
+ import concurrently from './dist/src/index.js';
9
+ export default concurrently.default;
package/package.json CHANGED
@@ -1,16 +1,27 @@
1
1
  {
2
2
  "name": "concurrently",
3
- "version": "6.5.0",
3
+ "version": "7.1.0",
4
4
  "description": "Run commands concurrently",
5
5
  "main": "index.js",
6
+ "types": "dist/src/index.d.ts",
7
+ "type": "commonjs",
6
8
  "bin": {
7
- "concurrently": "./bin/concurrently.js"
9
+ "concurrently": "./dist/bin/concurrently.js"
8
10
  },
9
11
  "engines": {
10
- "node": ">=10.0.0"
12
+ "node": "^12.20.0 || ^14.13.0 || >=16.0.0"
13
+ },
14
+ "exports": {
15
+ "import": "./index.mjs",
16
+ "require": "./index.js",
17
+ "default": "./index.js"
11
18
  },
12
19
  "scripts": {
13
- "lint": "eslint . --ignore-path .gitignore",
20
+ "build": "tsc --build",
21
+ "postbuild": "chmod +x dist/bin/concurrently.js",
22
+ "clean": "tsc --build --clean",
23
+ "lint": "eslint . --ext js,ts --ignore-path .gitignore",
24
+ "prepublishOnly": "npm run build",
14
25
  "report-coverage": "cat coverage/lcov.info | coveralls",
15
26
  "test": "jest"
16
27
  },
@@ -39,27 +50,43 @@
39
50
  "yargs": "^16.2.0"
40
51
  },
41
52
  "devDependencies": {
53
+ "@types/jest": "^27.0.3",
54
+ "@types/lodash": "^4.14.178",
55
+ "@types/node": "^17.0.0",
56
+ "@types/supports-color": "^8.1.1",
57
+ "@typescript-eslint/eslint-plugin": "^5.8.1",
58
+ "@typescript-eslint/parser": "^5.8.1",
42
59
  "coveralls": "^3.1.0",
43
60
  "eslint": "^7.17.0",
44
61
  "jest": "^26.6.3",
45
- "jest-create-mock-instance": "^1.1.0"
62
+ "jest-create-mock-instance": "^1.1.0",
63
+ "ts-jest": "^26.5.6",
64
+ "ts-node": "^10.4.0",
65
+ "typescript": "^4.5.4"
46
66
  },
47
67
  "files": [
48
- "bin",
49
- "!**/fixtures",
68
+ "dist",
50
69
  "index.js",
51
- "src",
52
- "!*.spec.js"
70
+ "index.mjs",
71
+ "!**/fixtures",
72
+ "!**/*.spec.js",
73
+ "!**/*.spec.d.ts"
53
74
  ],
54
75
  "jest": {
76
+ "preset": "ts-jest",
55
77
  "collectCoverage": true,
56
78
  "collectCoverageFrom": [
57
- "src/**/*.js"
79
+ "src/**/*.ts",
80
+ "!src/index.ts"
58
81
  ],
59
82
  "coveragePathIgnorePatterns": [
60
83
  "/fixtures/",
61
84
  "/node_modules/"
62
85
  ],
63
- "testEnvironment": "node"
86
+ "testEnvironment": "node",
87
+ "testPathIgnorePatterns": [
88
+ "/node_modules/",
89
+ "/dist"
90
+ ]
64
91
  }
65
92
  }