The browser reached the daemon through maestro-web, a second binary that served the SPA and reverse-proxied /api/* — two TCP connections and a WebSocket frame re-encode on every keystroke and every byte of PTY output. On one machine that hop buys nothing. The daemon now embeds the bundle and serves it off its own listener, behind a default-on `web` feature. `--no-default-features` builds without pnpm or node; MAESTRO_WEB_DIST still takes a prebuilt bundle. The router's fallback answers an unmatched /api/* with 404 rather than the SPA shell, so a client expecting JSON gets a status it can read instead of HTML. Removes maestro-web and the [web] config section. An existing [web] block is ignored, not rejected. The installer deletes a leftover maestro-web.service on upgrade. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
33 lines
1.2 KiB
TypeScript
33 lines
1.2 KiB
TypeScript
// Attach-socket reconnect policy. Split out of attach.ts so it can be tested
|
|
// without a DOM or an xterm instance.
|
|
|
|
import type { Session, Uuid } from "./types.js";
|
|
|
|
/** First retry delay after an unexpected close, doubling up to the cap. */
|
|
export const INITIAL_RECONNECT_MS = 500;
|
|
export const MAX_RECONNECT_MS = 10_000;
|
|
|
|
/** Close codes at or above this are application-defined; the daemon uses
|
|
* them to signal a rejection, which retrying would only loop on. */
|
|
const APPLICATION_CLOSE = 4000;
|
|
|
|
/** Normal Closure — the peer ended the stream deliberately. */
|
|
const CLEAN_CLOSE = 1000;
|
|
|
|
/**
|
|
* Should a closed attach socket be retried?
|
|
*
|
|
* The catalog is the authority: a session still `Running` lost its link, so
|
|
* retry; one that is `Dead` has had its PTY stream sealed and will never send
|
|
* again, and one absent from the catalog is gone. Before this existed, any
|
|
* dropped frame destroyed the pane permanently.
|
|
*/
|
|
export function shouldRetryClose(
|
|
sessionId: Uuid,
|
|
code: number,
|
|
sessions: ReadonlyMap<Uuid, Session>,
|
|
): boolean {
|
|
if (code >= APPLICATION_CLOSE || code === CLEAN_CLOSE) return false;
|
|
return sessions.get(sessionId)?.status === "Running";
|
|
}
|