(path)
| 900 | // handshake (`opened`) and whether the upgrade was forwarded to the backend |
| 901 | // proxy (`forwarded`). |
| 902 | const probe = async (path) => { |
| 903 | const before = backendUpgradeCount; |
| 904 | |
| 905 | const ws = new WebSocket(`ws://localhost:${port3}${path}`); |
| 906 | |
| 907 | // Resolve as soon as the socket reaches a terminal state instead of |
| 908 | // waiting a fixed delay: `open` means the handshake completed, `error` |
| 909 | // means it was rejected. The timeout is only a fallback in case neither |
| 910 | // event ever fires, so it can be generous without slowing the happy path. |
| 911 | const opened = await new Promise((resolve) => { |
| 912 | const timer = setTimeout(() => resolve(false), 2000); |
| 913 | |
| 914 | ws.once("open", () => { |
| 915 | clearTimeout(timer); |
| 916 | resolve(true); |
| 917 | }); |
| 918 | ws.once("error", () => { |
| 919 | clearTimeout(timer); |
| 920 | resolve(false); |
| 921 | }); |
| 922 | }); |
| 923 | |
| 924 | try { |
| 925 | ws.close(); |
| 926 | } catch { |
| 927 | // ignore close errors on already-failed sockets |
| 928 | } |
| 929 | |
| 930 | return { opened, forwarded: backendUpgradeCount > before }; |
| 931 | }; |
| 932 | |
| 933 | // Behavior shared by every WebSocket server implementation: the HMR socket |
| 934 | // is served locally and never forwarded, while any path the HMR server does |
no outgoing calls
no test coverage detected
searching dependent graphs…