|
1 | | -import { connectTerminal } from "../src/client" |
| 1 | +import { MultiplexerConnection, connectTerminal } from "../src/client" |
2 | 2 |
|
3 | | -// Setup container to fill viewport |
4 | | -const container = document.getElementById("terminal")! |
5 | | -document.body.style.cssText = "margin: 0; background: #0D1117; overflow: hidden;" |
6 | | -container.style.cssText = "width: 100vw; height: 100vh;" |
| 3 | +// Setup container to fill viewport with 2 side-by-side terminals |
| 4 | +document.body.style.cssText = "margin: 0; background: #0D1117; overflow: hidden; display: flex; flex-direction: column;" |
| 5 | + |
| 6 | +// Header showing sync info |
| 7 | +const header = document.createElement("div") |
| 8 | +header.style.cssText = |
| 9 | + "padding: 8px 16px; background: #161b22; color: #8b949e; font-family: system-ui; font-size: 12px; border-bottom: 1px solid #30363d;" |
| 10 | +header.innerHTML = ` |
| 11 | + <strong style="color: #58a6ff;">Synced Terminals Demo</strong> - |
| 12 | + Both terminals share the same connection and ID. Type in either one to see sync! |
| 13 | +` |
| 14 | +document.body.appendChild(header) |
| 15 | + |
| 16 | +// Container for the two terminals |
| 17 | +const terminalWrapper = document.createElement("div") |
| 18 | +terminalWrapper.style.cssText = "display: flex; flex: 1; gap: 2px; background: #30363d;" |
| 19 | +document.body.appendChild(terminalWrapper) |
| 20 | + |
| 21 | +// Create two terminal containers |
| 22 | +const container1 = document.createElement("div") |
| 23 | +container1.id = "terminal1" |
| 24 | +container1.style.cssText = "flex: 1; background: #0D1117;" |
| 25 | +terminalWrapper.appendChild(container1) |
| 26 | + |
| 27 | +const container2 = document.createElement("div") |
| 28 | +container2.id = "terminal2" |
| 29 | +container2.style.cssText = "flex: 1; background: #0D1117;" |
| 30 | +terminalWrapper.appendChild(container2) |
7 | 31 |
|
8 | 32 | // Generate a unique tunnel ID for this session |
9 | 33 | const tunnelId = crypto.randomUUID() |
10 | 34 |
|
11 | | -const connection = connectTerminal({ |
| 35 | +// Create a centralized multiplexer connection |
| 36 | +const multiplexer = new MultiplexerConnection({ |
12 | 37 | url: `ws://${window.location.host}`, |
13 | 38 | namespace: "demo", |
14 | 39 | ids: [tunnelId], |
15 | | - container, |
16 | | - useCanvas: true, |
| 40 | + onConnect: () => { |
| 41 | + console.log("[demo] Multiplexer connected") |
| 42 | + }, |
| 43 | + onDisconnect: () => { |
| 44 | + console.log("[demo] Multiplexer disconnected") |
| 45 | + }, |
| 46 | + onError: (error) => { |
| 47 | + console.error("[demo] Multiplexer error:", error) |
| 48 | + }, |
| 49 | +}) |
| 50 | + |
| 51 | +// Connect the multiplexer |
| 52 | +multiplexer.connect() |
| 53 | + |
| 54 | +// Shared renderer options |
| 55 | +const rendererOptions = { |
17 | 56 | fontFamily: "Consolas, monospace", |
18 | 57 | fontSize: 14, |
19 | | - lineHeight: 1.4, |
| 58 | + lineHeight: 1.2, |
| 59 | + devicePixelRatio: 1.5, |
20 | 60 | letterSpacing: 0, |
21 | 61 | fontWeight: 500, |
22 | 62 | fontWeightBold: 700, |
23 | 63 | backgroundColor: "#0D1117", |
| 64 | +} as const |
| 65 | + |
| 66 | +// Create two terminals sharing the same connection and ID |
| 67 | +const terminal1 = connectTerminal({ |
| 68 | + connection: multiplexer, |
| 69 | + id: tunnelId, |
| 70 | + container: container1, |
| 71 | + ...rendererOptions, |
| 72 | +}) |
| 73 | + |
| 74 | +const terminal2 = connectTerminal({ |
| 75 | + connection: multiplexer, |
| 76 | + id: tunnelId, |
| 77 | + container: container2, |
| 78 | + focused: false, // Only first terminal is focused initially |
| 79 | + ...rendererOptions, |
24 | 80 | }) |
25 | 81 |
|
26 | 82 | // Handle window resize |
27 | 83 | window.addEventListener("resize", () => { |
28 | | - connection.resize() |
| 84 | + terminal1.resize() |
| 85 | + terminal2.resize() |
| 86 | +}) |
| 87 | + |
| 88 | +// Focus management: click to focus |
| 89 | +container1.addEventListener("click", () => { |
| 90 | + terminal1.setFocused(true) |
| 91 | + terminal2.setFocused(false) |
| 92 | + container1.style.outline = "2px solid #58a6ff" |
| 93 | + container2.style.outline = "none" |
29 | 94 | }) |
| 95 | + |
| 96 | +container2.addEventListener("click", () => { |
| 97 | + terminal2.setFocused(true) |
| 98 | + terminal1.setFocused(false) |
| 99 | + container2.style.outline = "2px solid #58a6ff" |
| 100 | + container1.style.outline = "none" |
| 101 | +}) |
| 102 | + |
| 103 | +// Initial focus indicator |
| 104 | +container1.style.outline = "2px solid #58a6ff" |
0 commit comments