| 28 | const debugRegex = /Debugger listening on ws:\/\/\[?(.+?)\]?:(\d+)\//; |
| 29 | |
| 30 | async function portIsFree(host, port, timeout = 3000) { |
| 31 | if (port === 0) return; // Binding to a random port. |
| 32 | |
| 33 | const retryDelay = 150; |
| 34 | const ac = new AbortController(); |
| 35 | const { signal } = ac; |
| 36 | |
| 37 | pSetTimeout(timeout).then(() => ac.abort()); |
| 38 | |
| 39 | const asyncIterator = pSetInterval(retryDelay); |
| 40 | while (true) { |
| 41 | await asyncIterator.next(); |
| 42 | if (signal.aborted) { |
| 43 | throw new ERR_DEBUGGER_STARTUP_ERROR( |
| 44 | `Timeout (${timeout}) waiting for ${host}:${port} to be free`); |
| 45 | } |
| 46 | const error = await new Promise((resolve) => { |
| 47 | const socket = net.connect(port, host); |
| 48 | socket.on('error', resolve); |
| 49 | socket.on('connect', () => { |
| 50 | socket.end(); |
| 51 | resolve(); |
| 52 | }); |
| 53 | }); |
| 54 | if (error?.code === 'ECONNREFUSED') { |
| 55 | return; |
| 56 | } |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | function ensureTrailingNewline(text) { |
| 61 | return StringPrototypeEndsWith(text, '\n') ? text : `${text}\n`; |