serve-sim 0.1.14 → 0.1.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serve-sim",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "type": "module",
5
5
  "author": {
6
6
  "name": "Evan Bacon",
package/src/middleware.ts CHANGED
@@ -178,12 +178,12 @@ async function isLocalPortFree(port: number): Promise<boolean> {
178
178
  const server = createNetServer();
179
179
  server.once("error", () => resolve(false));
180
180
  server.once("listening", () => server.close(() => resolve(true)));
181
- server.listen(port, "localhost");
181
+ server.listen(port, "127.0.0.1");
182
182
  });
183
183
  }
184
184
 
185
185
  async function existingInspectWebKitBridge(port: number): Promise<WebKitBridge | null> {
186
- const cdpUrl = `http://localhost:${port}`;
186
+ const cdpUrl = `http://127.0.0.1:${port}`;
187
187
  try {
188
188
  const versionRes = await fetch(`${cdpUrl}/json/version`);
189
189
  if (!versionRes.ok) return null;
@@ -246,10 +246,14 @@ async function ensureInspectWebKitBridge(): Promise<WebKitBridge> {
246
246
  continue;
247
247
  }
248
248
  try {
249
- const server = await startCdpServer({ host: "localhost", port });
249
+ // Bind explicitly to IPv4 127.0.0.1 to match what bridgeWsHost emits
250
+ // (and what the DevTools frontend CSP whitelists). `localhost` resolves
251
+ // to ::1 first on some setups, which would leave the iframe's
252
+ // ws://127.0.0.1:9222 connection refused.
253
+ const server = await startCdpServer({ host: "127.0.0.1", port });
250
254
  return {
251
255
  port,
252
- cdpUrl: `http://localhost:${port}`,
256
+ cdpUrl: `http://127.0.0.1:${port}`,
253
257
  async listTargets() {
254
258
  return server.getTargets()
255
259
  .filter((target: any) => target.source?.kind === "simulator")
@@ -290,14 +294,16 @@ function devtoolsFrontendUrl(frontendBase: string, wsHost: string, targetId: str
290
294
  return `${url.pathname}${url.search}`;
291
295
  }
292
296
 
293
- // The inspect-webkit bridge binds to localhost only. When the preview is
294
- // loaded from a different hostname (e.g. another device on the LAN), strip
295
- // to the request's hostname-less form `localhost:<port>` so the iframe at
296
- // least tries the right port; document the limitation in the README.
297
- function bridgeWsHost(reqHost: string | undefined, bridgePort: number): string {
298
- const hostname = (reqHost ?? "localhost").split(":")[0];
299
- const isLocal = hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
300
- return `${isLocal ? hostname : "localhost"}:${bridgePort}`;
297
+ // The inspect-webkit bridge binds locally. Always emit `127.0.0.1` rather
298
+ // than `localhost` for the iframe's WS URL: the chrome-devtools-frontend
299
+ // inspector.html ships a CSP whose connect-src only whitelists
300
+ // `ws://127.0.0.1:*` (plus `'self'`, which doesn't cover the bridge's
301
+ // different port). A `ws://localhost:9222/...` connection from the iframe
302
+ // gets CSP-blocked and surfaces as "WebSocket disconnected."
303
+ // Non-local hostnames fall back to 127.0.0.1 since the bridge isn't
304
+ // reachable from off-host anyway.
305
+ function bridgeWsHost(_reqHost: string | undefined, bridgePort: number): string {
306
+ return `127.0.0.1:${bridgePort}`;
301
307
  }
302
308
 
303
309
  let _html: string | null = null;
@@ -415,15 +421,11 @@ export function simMiddleware(options?: SimMiddlewareOptions) {
415
421
  const bridge = await ensureInspectWebKitBridge();
416
422
  const bridgeTargets = await bridge.listTargets();
417
423
  const wsHost = bridgeWsHost(req.headers?.host, bridge.port);
418
- // The bridge enumerates targets across every booted simulator.
419
- // Filter to the device this preview is pinned to so the picker
420
- // doesn't surface webviews that belong to a different sim.
421
- const scoped = bridgeTargets.filter((target) =>
422
- // If we couldn't resolve a udid (e.g. degraded HTTP path), keep
423
- // the target rather than dropping it silently.
424
- !target.udid || target.udid === state.device,
425
- );
426
- const targets = scoped.map((target) => ({
424
+ // inspect-webkit@0.0.3 only exposes `sim:<webinspectord-pid>` for
425
+ // simulator targets, which can't be reconciled against a sim UDID.
426
+ // Surface every booted sim's targets (Safari Develop-menu behavior)
427
+ // until inspect-webkit grows a real UDID we can filter on.
428
+ const targets = bridgeTargets.map((target) => ({
427
429
  ...target,
428
430
  webSocketDebuggerUrl: `ws://${wsHost}/devtools/page/${encodeURIComponent(target.id)}`,
429
431
  devtoolsFrontendUrl: devtoolsFrontendUrl(devtoolsFrontendBase, wsHost, target.id),