|
443 | 443 | </ul> |
444 | 444 | </nav> |
445 | 445 |
|
| 446 | +</li> |
| 447 | + |
| 448 | + <li class="md-nav__item"> |
| 449 | + <a href="#websocket-connections-browser-repls" class="md-nav__link"> |
| 450 | + <span class="md-ellipsis"> |
| 451 | + WebSocket Connections (Browser REPLs) |
| 452 | + </span> |
| 453 | + </a> |
| 454 | + |
| 455 | + <nav class="md-nav" aria-label="WebSocket Connections (Browser REPLs)"> |
| 456 | + <ul class="md-nav__list"> |
| 457 | + |
| 458 | + <li class="md-nav__item"> |
| 459 | + <a href="#how-it-works" class="md-nav__link"> |
| 460 | + <span class="md-ellipsis"> |
| 461 | + How It Works |
| 462 | + </span> |
| 463 | + </a> |
| 464 | + |
| 465 | +</li> |
| 466 | + |
| 467 | + <li class="md-nav__item"> |
| 468 | + <a href="#configuration" class="md-nav__link"> |
| 469 | + <span class="md-ellipsis"> |
| 470 | + Configuration |
| 471 | + </span> |
| 472 | + </a> |
| 473 | + |
| 474 | +</li> |
| 475 | + |
| 476 | + <li class="md-nav__item"> |
| 477 | + <a href="#port-conflicts" class="md-nav__link"> |
| 478 | + <span class="md-ellipsis"> |
| 479 | + Port Conflicts |
| 480 | + </span> |
| 481 | + </a> |
| 482 | + |
| 483 | +</li> |
| 484 | + |
| 485 | + <li class="md-nav__item"> |
| 486 | + <a href="#using-with-scittle" class="md-nav__link"> |
| 487 | + <span class="md-ellipsis"> |
| 488 | + Using with Scittle |
| 489 | + </span> |
| 490 | + </a> |
| 491 | + |
| 492 | +</li> |
| 493 | + |
| 494 | + <li class="md-nav__item"> |
| 495 | + <a href="#using-with-epupp" class="md-nav__link"> |
| 496 | + <span class="md-ellipsis"> |
| 497 | + Using with Epupp |
| 498 | + </span> |
| 499 | + </a> |
| 500 | + |
| 501 | +</li> |
| 502 | + |
| 503 | + </ul> |
| 504 | + </nav> |
| 505 | + |
446 | 506 | </li> |
447 | 507 |
|
448 | 508 | <li class="md-nav__item"> |
|
2379 | 2439 | </ul> |
2380 | 2440 | </nav> |
2381 | 2441 |
|
| 2442 | +</li> |
| 2443 | + |
| 2444 | + <li class="md-nav__item"> |
| 2445 | + <a href="#websocket-connections-browser-repls" class="md-nav__link"> |
| 2446 | + <span class="md-ellipsis"> |
| 2447 | + WebSocket Connections (Browser REPLs) |
| 2448 | + </span> |
| 2449 | + </a> |
| 2450 | + |
| 2451 | + <nav class="md-nav" aria-label="WebSocket Connections (Browser REPLs)"> |
| 2452 | + <ul class="md-nav__list"> |
| 2453 | + |
| 2454 | + <li class="md-nav__item"> |
| 2455 | + <a href="#how-it-works" class="md-nav__link"> |
| 2456 | + <span class="md-ellipsis"> |
| 2457 | + How It Works |
| 2458 | + </span> |
| 2459 | + </a> |
| 2460 | + |
| 2461 | +</li> |
| 2462 | + |
| 2463 | + <li class="md-nav__item"> |
| 2464 | + <a href="#configuration" class="md-nav__link"> |
| 2465 | + <span class="md-ellipsis"> |
| 2466 | + Configuration |
| 2467 | + </span> |
| 2468 | + </a> |
| 2469 | + |
| 2470 | +</li> |
| 2471 | + |
| 2472 | + <li class="md-nav__item"> |
| 2473 | + <a href="#port-conflicts" class="md-nav__link"> |
| 2474 | + <span class="md-ellipsis"> |
| 2475 | + Port Conflicts |
| 2476 | + </span> |
| 2477 | + </a> |
| 2478 | + |
| 2479 | +</li> |
| 2480 | + |
| 2481 | + <li class="md-nav__item"> |
| 2482 | + <a href="#using-with-scittle" class="md-nav__link"> |
| 2483 | + <span class="md-ellipsis"> |
| 2484 | + Using with Scittle |
| 2485 | + </span> |
| 2486 | + </a> |
| 2487 | + |
| 2488 | +</li> |
| 2489 | + |
| 2490 | + <li class="md-nav__item"> |
| 2491 | + <a href="#using-with-epupp" class="md-nav__link"> |
| 2492 | + <span class="md-ellipsis"> |
| 2493 | + Using with Epupp |
| 2494 | + </span> |
| 2495 | + </a> |
| 2496 | + |
| 2497 | +</li> |
| 2498 | + |
| 2499 | + </ul> |
| 2500 | + </nav> |
| 2501 | + |
2382 | 2502 | </li> |
2383 | 2503 |
|
2384 | 2504 | <li class="md-nav__item"> |
@@ -2559,6 +2679,91 @@ <h2 id="connecting-without-jack-in">Connecting Without Jack-in<a class="headerli |
2559 | 2679 | <p>See also <a href="../customizing-jack-in-and-connect/">Customizing Jack-in and Connect</a></p> |
2560 | 2680 | <h3 id="starting-the-repl-from-application-code">Starting the REPL from application code?<a class="headerlink" href="#starting-the-repl-from-application-code" title="Permanent link">#</a></h3> |
2561 | 2681 | <p>If your project is setup so that the REPL server is started by the application code, you will need to get the cider-nrepl middleware in place. See the cider-nrepl docs about <a href="https://docs.cider.mx/cider-nrepl/usage.html#via-embedding-nrepl-in-your-application">embedding nREPL in your application</a>.</p> |
| 2682 | +<h2 id="websocket-connections-browser-repls">WebSocket Connections (Browser REPLs)<a class="headerlink" href="#websocket-connections-browser-repls" title="Permanent link">#</a></h2> |
| 2683 | +<p>Calva can connect to browser-based nREPL servers — like those provided by <a href="https://github.com/babashka/scittle">Scittle</a>, <a href="https://github.com/PEZ/epupp">Epupp</a>, or any <a href="https://github.com/babashka/scittle/tree/main/doc/nrepl">sci.nrepl</a> compatible runtime. Instead of the traditional TCP/bencode nREPL connection, Calva starts a WebSocket server that the browser connects to directly.</p> |
| 2684 | +<h3 id="how-it-works">How It Works<a class="headerlink" href="#how-it-works" title="Permanent link">#</a></h3> |
| 2685 | +<ol> |
| 2686 | +<li>You connect in Calva using a connect sequence with <code>webSocketPort</code> configured</li> |
| 2687 | +<li>Calva starts a WebSocket server and shows "Waiting for browser REPL..."</li> |
| 2688 | +<li>You connect the browser to the same port (e.g. via Epupp, or by loading a page with Scittle nREPL)</li> |
| 2689 | +<li>Calva picks up the connection — you can evaluate code, get completions, look up docs</li> |
| 2690 | +</ol> |
| 2691 | +<p>If the browser disconnects (tab reload, navigation, tab close), Calva keeps the server running and waits for a reconnection. When the browser comes back, Calva resumes automatically.</p> |
| 2692 | +<div class="admonition note"> |
| 2693 | +<p class="admonition-title">One browser client at a time</p> |
| 2694 | +<p>Calva's WebSocket server accepts one client connection. If a new browser or browser tab connects, Calva switches to the new client. This means Calva is always connected to whichever browser client most recently connected to its server.</p> |
| 2695 | +</div> |
| 2696 | +<h3 id="configuration">Configuration<a class="headerlink" href="#configuration" title="Permanent link">#</a></h3> |
| 2697 | +<p>Valid values for <code>webSocketPort</code>:</p> |
| 2698 | +<ul> |
| 2699 | +<li>A port number (e.g. <code>1340</code>) — start the WebSocket server on that port</li> |
| 2700 | +<li><code>true</code> — prompt for the port each time you connect</li> |
| 2701 | +<li><code>false</code> — disable WebSocket, use TCP/bencode instead (for use when extending the built-in <code>scittle</code> and <code>epupp</code> sequences but connecting via an external relay)</li> |
| 2702 | +</ul> |
| 2703 | +<p>If <code>webSocketPort</code> is omitted, the connection uses TCP/bencode as usual.</p> |
| 2704 | +<p>When <code>webSocketPort</code> is set, the TCP-related properties (<code>nReplPortFile</code>, <code>fallbackPort</code>, host/port prompts) are not used.</p> |
| 2705 | +<p>By default, the WebSocket server binds to <code>127.0.0.1</code> (localhost only). To accept connections from other machines — for example when the browser runs on a different host or in a Docker container — set <code>webSocketHost</code>:</p> |
| 2706 | +<div class="highlight"><pre><span></span><code><span class="p">{</span> |
| 2707 | +<span class="w"> </span><span class="nt">"calva.replConnectSequences"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span> |
| 2708 | +<span class="w"> </span><span class="p">{</span> |
| 2709 | +<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Browser REPL (network)"</span><span class="p">,</span> |
| 2710 | +<span class="w"> </span><span class="nt">"projectType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"scittle"</span><span class="p">,</span> |
| 2711 | +<span class="w"> </span><span class="nt">"webSocketPort"</span><span class="p">:</span><span class="w"> </span><span class="mi">1340</span><span class="p">,</span> |
| 2712 | +<span class="w"> </span><span class="nt">"webSocketHost"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0.0.0.0"</span> |
| 2713 | +<span class="w"> </span><span class="p">}</span> |
| 2714 | +<span class="w"> </span><span class="p">]</span> |
| 2715 | +<span class="p">}</span> |
| 2716 | +</code></pre></div> |
| 2717 | +<div class="admonition warning"> |
| 2718 | +<p class="admonition-title">Security: binding to all interfaces</p> |
| 2719 | +<p>Setting <code>webSocketHost</code> to <code>"0.0.0.0"</code> exposes the nREPL WebSocket server to your network. Only do this when you need remote access and understand the implications.</p> |
| 2720 | +</div> |
| 2721 | +<p>The built-in <strong>scittle</strong> and <strong>epupp</strong> connect sequences come with WebSocket enabled by default:</p> |
| 2722 | +<table> |
| 2723 | +<thead> |
| 2724 | +<tr> |
| 2725 | +<th>Project type</th> |
| 2726 | +<th>WebSocket port</th> |
| 2727 | +</tr> |
| 2728 | +</thead> |
| 2729 | +<tbody> |
| 2730 | +<tr> |
| 2731 | +<td>scittle</td> |
| 2732 | +<td>1340</td> |
| 2733 | +</tr> |
| 2734 | +<tr> |
| 2735 | +<td>epupp</td> |
| 2736 | +<td>3340</td> |
| 2737 | +</tr> |
| 2738 | +</tbody> |
| 2739 | +</table> |
| 2740 | +<p>For most setups, this works out of the box — just make sure the browser-side client is configured to connect to the same port.</p> |
| 2741 | +<p>To use a different port, override <code>webSocketPort</code> in your connect sequence:</p> |
| 2742 | +<div class="highlight"><pre><span></span><code><span class="p">{</span> |
| 2743 | +<span class="w"> </span><span class="nt">"calva.replConnectSequences"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span> |
| 2744 | +<span class="w"> </span><span class="p">{</span> |
| 2745 | +<span class="w"> </span><span class="nt">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"My Browser REPL"</span><span class="p">,</span> |
| 2746 | +<span class="w"> </span><span class="nt">"projectType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"scittle"</span><span class="p">,</span> |
| 2747 | +<span class="w"> </span><span class="nt">"webSocketPort"</span><span class="p">:</span><span class="w"> </span><span class="mi">4200</span> |
| 2748 | +<span class="w"> </span><span class="p">}</span> |
| 2749 | +<span class="w"> </span><span class="p">]</span> |
| 2750 | +<span class="p">}</span> |
| 2751 | +</code></pre></div> |
| 2752 | +<p>See <a href="../connect-sequences/">Connect Sequences</a> for the full <code>webSocketPort</code> reference.</p> |
| 2753 | +<h3 id="port-conflicts">Port Conflicts<a class="headerlink" href="#port-conflicts" title="Permanent link">#</a></h3> |
| 2754 | +<p>WebSocket ports are shared across the OS. If the port is already in use (by another VS Code window or another process), Calva will prompt you with the port pre-filled so you can either enter a different port or free the existing one and retry.</p> |
| 2755 | +<h3 id="using-with-scittle">Using with Scittle<a class="headerlink" href="#using-with-scittle" title="Permanent link">#</a></h3> |
| 2756 | +<p><a href="https://github.com/babashka/scittle">Scittle</a> provides an nREPL server that runs in the browser. See the <a href="https://github.com/babashka/scittle/tree/main/doc/nrepl">Scittle nREPL docs</a> for how to add nREPL to your page. Once set up:</p> |
| 2757 | +<ol> |
| 2758 | +<li>Connect in Calva using the <strong>scittle</strong> connect sequence (starts the WebSocket server on port 1340)</li> |
| 2759 | +<li>Load your page in the browser — the Scittle nREPL client connects automatically</li> |
| 2760 | +</ol> |
| 2761 | +<h3 id="using-with-epupp">Using with Epupp<a class="headerlink" href="#using-with-epupp" title="Permanent link">#</a></h3> |
| 2762 | +<p><a href="https://github.com/PEZ/epupp">Epupp</a> lets you connect an nREPL to any web page. With WebSocket connections in Calva, the setup is:</p> |
| 2763 | +<ol> |
| 2764 | +<li>Connect in Calva using the <strong>epupp</strong> connect sequence (starts the WebSocket server on port 3340)</li> |
| 2765 | +<li>In Epupp, set the WebSocket port to match and click Connect</li> |
| 2766 | +</ol> |
2562 | 2767 | <h2 id="auto-select-project-type-and-project-root">Auto-select Project Type and Project Root<a class="headerlink" href="#auto-select-project-type-and-project-root" title="Permanent link">#</a></h2> |
2563 | 2768 | <p>You can make both Jack-in and Connect stop prompting you for project type and project root path in projects where you always want to use the same. See <a href="../connect-sequences/">Connect Sequences</a>.</p> |
2564 | 2769 | <h2 id="monorepos-multiple-clojure-projects-in-one-workspace">Monorepos / multiple Clojure projects in one workspace<a class="headerlink" href="#monorepos-multiple-clojure-projects-in-one-workspace" title="Permanent link">#</a></h2> |
|
0 commit comments