@aryanduntley/pwa-debug 0.1.4 → 0.1.5

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 (2) hide show
  1. package/dist/main.js +48 -6
  2. package/package.json +3 -3
package/dist/main.js CHANGED
@@ -15027,6 +15027,21 @@ const snapshotConn = (c) => Object.freeze({
15027
15027
  connectedAt: c.connectedAt,
15028
15028
  lastSeenAt: c.lastSeenAt,
15029
15029
  });
15030
+ // Probe whether a unix socket path has a live listener. Resolves 'live' if a
15031
+ // connection is accepted, 'stale' if the path refuses connection (ECONNREFUSED)
15032
+ // or is gone (ENOENT) — i.e. an orphaned socket file left behind by a host that
15033
+ // was hard-killed (SIGKILL / terminal close / crash) before close() could
15034
+ // unlink it. Used to decide whether an EADDRINUSE bind failure is a genuine
15035
+ // conflict (another host is up) or a reclaimable stale file.
15036
+ const probeSocketLiveness = (path) => new Promise((resolve) => {
15037
+ const probe = createConnection(path);
15038
+ const settle = (result) => {
15039
+ probe.destroy();
15040
+ resolve(result);
15041
+ };
15042
+ probe.once('connect', () => settle('live'));
15043
+ probe.once('error', () => settle('stale'));
15044
+ });
15030
15045
  const createIpcServer = async (opts) => {
15031
15046
  const connections = new Map();
15032
15047
  const pending = new Map();
@@ -15117,12 +15132,39 @@ const createIpcServer = async (opts) => {
15117
15132
  const socketPaths = [opts.socketPath, ...(opts.extraSocketPaths ?? [])];
15118
15133
  const servers = socketPaths.map(() => createServer(handleSocket));
15119
15134
  const listenOne = (server, path) => new Promise((resolve, reject) => {
15120
- const onError = (err) => reject(err);
15121
- server.once('error', onError);
15122
- server.listen(path, () => {
15123
- server.off('error', onError);
15124
- resolve();
15125
- });
15135
+ const attempt = (recovered) => {
15136
+ const onError = (err) => {
15137
+ const recoverable = err.code === 'EADDRINUSE' &&
15138
+ !recovered &&
15139
+ process.platform !== 'win32';
15140
+ if (!recoverable) {
15141
+ reject(err);
15142
+ return;
15143
+ }
15144
+ // A prior host may have been hard-killed without unlinking its socket.
15145
+ // Probe before clobbering: only reclaim a path nothing is listening on
15146
+ // — never unlink out from under a host that is genuinely up.
15147
+ void probeSocketLiveness(path).then(async (liveness) => {
15148
+ if (liveness === 'live') {
15149
+ reject(new Error(`ipc server: another pwa-debug host is already listening on ${path}`));
15150
+ return;
15151
+ }
15152
+ try {
15153
+ await unlink(path);
15154
+ }
15155
+ catch {
15156
+ // already gone — fine, just retry the bind
15157
+ }
15158
+ attempt(true);
15159
+ });
15160
+ };
15161
+ server.once('error', onError);
15162
+ server.listen(path, () => {
15163
+ server.off('error', onError);
15164
+ resolve();
15165
+ });
15166
+ };
15167
+ attempt(false);
15126
15168
  });
15127
15169
  await Promise.all(servers.map((s, i) => listenOne(s, socketPaths[i])));
15128
15170
  const sendTo = (extensionId, env) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aryanduntley/pwa-debug",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -63,8 +63,8 @@
63
63
  "@types/winreg": "^1.2.36",
64
64
  "rollup": "^4.27.4",
65
65
  "tslib": "^2.8.1",
66
- "@pwa-debug/extension": "0.1.4",
67
- "@pwa-debug/shared": "0.1.4"
66
+ "@pwa-debug/extension": "0.1.5",
67
+ "@pwa-debug/shared": "0.1.5"
68
68
  },
69
69
  "scripts": {
70
70
  "typecheck": "tsc --noEmit",