contactsheet 0.1.3 → 0.1.4

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.
package/dist/cli.js CHANGED
@@ -1581,7 +1581,14 @@ async function startServer(cfg) {
1581
1581
  s.on("close", () => sockets.delete(s));
1582
1582
  });
1583
1583
  const host = cfg.host ?? "127.0.0.1";
1584
- const port = await listenWithFallback(server, cfg, host);
1584
+ let twin = null;
1585
+ const port = await listenWithFallback(server, cfg, host, (t) => {
1586
+ twin = t;
1587
+ t.on("connection", (sock) => {
1588
+ sockets.add(sock);
1589
+ sock.on("close", () => sockets.delete(sock));
1590
+ });
1591
+ });
1585
1592
  if (host !== "127.0.0.1" && host !== "localhost") {
1586
1593
  console.warn(
1587
1594
  warn(`\u76D1\u542C\u5728 ${host}:${port} \u2014\u2014 \u753B\u5E03\u65E0\u9274\u6743,\u540C\u7F51\u7EDC\u7684\u4EFB\u4F55\u4EBA\u90FD\u80FD\u8BFB\u4F60\u7684\u6279\u6CE8\u3001\u5E76\u5411\u4F60\u7684 Claude Code \u4F1A\u8BDD\u63A8\u9001\u6D88\u606F\u3002\u53EA\u5728\u53EF\u4FE1\u7F51\u7EDC\u8FD9\u4E48\u505A\u3002`)
@@ -1593,6 +1600,9 @@ async function startServer(cfg) {
1593
1600
  closeAll();
1594
1601
  proxyLog.close();
1595
1602
  proxy.close();
1603
+ if (twin) {
1604
+ await new Promise((r) => twin.close(() => r()));
1605
+ }
1596
1606
  await new Promise((resolve2) => {
1597
1607
  const fallback = setTimeout(resolve2, 2e3);
1598
1608
  for (const s of sockets) s.destroy();
@@ -1674,18 +1684,34 @@ async function occupiedBySameProject(cfg, port) {
1674
1684
  return false;
1675
1685
  }
1676
1686
  }
1677
- async function listenWithFallback(server, cfg, host) {
1678
- const tryListen = (port) => new Promise((resolve2, reject) => {
1687
+ async function listenWithFallback(server, cfg, host, onTwin) {
1688
+ const listenOnce = (srv, port, h) => new Promise((resolve2, reject) => {
1679
1689
  const onErr = (err) => {
1680
- if (err.code === "EADDRINUSE") resolve2(false);
1690
+ if (err.code === "EADDRINUSE") resolve2("busy");
1691
+ else if (err.code === "EADDRNOTAVAIL" || err.code === "EAFNOSUPPORT") resolve2("nofam");
1681
1692
  else reject(err);
1682
1693
  };
1683
- server.once("error", onErr);
1684
- server.listen(port, host, () => {
1685
- server.off("error", onErr);
1686
- resolve2(true);
1694
+ srv.once("error", onErr);
1695
+ srv.listen(port, h, () => {
1696
+ srv.off("error", onErr);
1697
+ resolve2("ok");
1687
1698
  });
1688
1699
  });
1700
+ const tryListen = async (port) => {
1701
+ const main2 = await listenOnce(server, port, host);
1702
+ if (main2 !== "ok") return false;
1703
+ if (host !== "127.0.0.1") return true;
1704
+ const t = http.createServer(server.listeners("request")[0]);
1705
+ for (const l of server.listeners("upgrade")) t.on("upgrade", l);
1706
+ const r = await listenOnce(t, port, "::1");
1707
+ if (r === "ok") {
1708
+ onTwin(t);
1709
+ return true;
1710
+ }
1711
+ if (r === "nofam") return true;
1712
+ await new Promise((res) => server.close(() => res()));
1713
+ return false;
1714
+ };
1689
1715
  if (await tryListen(cfg.port)) return cfg.port;
1690
1716
  if (await occupiedBySameProject(cfg, cfg.port)) {
1691
1717
  console.log(