(opts: StartLiveOptions)
| 66 | * `artifact_live` for the same id should NOT drop the existing one. |
| 67 | */ |
| 68 | export async function startLive(opts: StartLiveOptions): Promise<LiveInfo> { |
| 69 | const existing = servers.get(opts.id); |
| 70 | if (existing && !opts.replace) return infoFor(existing); |
| 71 | if (existing) { await closeEntry(existing); servers.delete(opts.id); } |
| 72 | |
| 73 | const handle = await createLiveServer(opts); |
| 74 | const entry: Entry = { handle, urls: [handle.url] }; |
| 75 | if (opts.lan) entry.urls.push(...lanUrls(handle.port, handle.token)); |
| 76 | if (opts.tunnel) { |
| 77 | try { |
| 78 | entry.tunnel = await startTunnel(handle.port); |
| 79 | entry.tunnelUrl = `${entry.tunnel.url}/${handle.token ? `?k=${handle.token}` : ''}`; |
| 80 | entry.urls.push(entry.tunnelUrl); |
| 81 | } catch (e: any) { |
| 82 | entry.tunnelError = e?.message ?? String(e); // best-effort: LAN/owner URLs still work |
| 83 | } |
| 84 | } |
| 85 | servers.set(opts.id, entry); |
| 86 | return infoFor(entry); |
| 87 | } |
| 88 | |
| 89 | export async function stopLive(id: string): Promise<boolean> { |
| 90 | const e = servers.get(id); |
no test coverage detected