* Persistent poll loop for work items. Runs in the background for the * lifetime of the bridge connection. * * When a work item arrives, acknowledges it and calls onWorkReceived * with the session ID and ingress token (which connects the ingress * WebSocket). Then continues polling — the server
({
api,
getCredentials,
signal,
onStateChange,
onWorkReceived,
onEnvironmentLost,
getWsState,
isAtCapacity,
capacitySignal,
onFatalError,
getPollIntervalConfig = () => DEFAULT_POLL_CONFIG,
getHeartbeatInfo,
onHeartbeatFatal,
}: {
api: BridgeApiClient
getCredentials: () => { environmentId: string; environmentSecret: string }
signal: AbortSignal
onStateChange?: (state: BridgeState, detail?: string) => void
onWorkReceived: (
sessionId: string,
ingressToken: string,
workId: string,
useCodeSessions: boolean,
) => void
/** Called when the environment has been deleted. Returns new credentials or null. */
onEnvironmentLost?: () => Promise<{
environmentId: string
environmentSecret: string
} | null>
/** Returns the current WebSocket readyState label for diagnostic logging. */
getWsState?: () => string
/**
* Returns true when the caller cannot accept new work (transport already
* connected). When true, the loop polls at the configured at-capacity
* interval as a heartbeat only. Server-side BRIDGE_LAST_POLL_TTL is
* 4 hours — anything shorter than that is sufficient for liveness.
*/
isAtCapacity?: () => boolean
/**
* Produces a signal that aborts when capacity frees up (transport lost),
* merged with the loop signal. Used to interrupt the at-capacity sleep
* so recovery polling starts immediately.
*/
capacitySignal?: () => CapacitySignal
/** Called on unrecoverable errors (e.g. server-side expiry) to trigger full teardown. */
onFatalError?: () => void
/** Poll interval config getter — defaults to DEFAULT_POLL_CONFIG. */
getPollIntervalConfig?: () => PollIntervalConfig
/**
* Returns the current work ID and session ingress token for heartbeat.
* When null, heartbeat is not possible (no active work item).
*/
getHeartbeatInfo?: () => {
environmentId: string
workId: string
sessionToken: string
} | null
/**
* Called when heartbeatWork throws BridgeFatalError (401/403/404/410 —
* JWT expired or work item gone). Caller should tear down the transport
* + work state so isAtCapacity() flips to false and the loop fast-polls
* for the server's re-dispatched work item. When provided, the loop
* SKIPS the at-capacity backoff sleep (which would otherwise cause a
* ~10-minute dead window before recovery). When omitted, falls back to
* the backoff sleep to avoid a tight poll+heartbeat loop.
*/
onHeartbeatFatal?: (err: BridgeFatalError) => void
})
| 1920 | * reconnection without tearing down the bridge. |
| 1921 | */ |
| 1922 | async function startWorkPollLoop({ |
| 1923 | api, |
| 1924 | getCredentials, |
| 1925 | signal, |
| 1926 | onStateChange, |
| 1927 | onWorkReceived, |
| 1928 | onEnvironmentLost, |
| 1929 | getWsState, |
| 1930 | isAtCapacity, |
| 1931 | capacitySignal, |
| 1932 | onFatalError, |
| 1933 | getPollIntervalConfig = () => DEFAULT_POLL_CONFIG, |
| 1934 | getHeartbeatInfo, |
| 1935 | onHeartbeatFatal, |
| 1936 | }: { |
| 1937 | api: BridgeApiClient |
| 1938 | getCredentials: () => { environmentId: string; environmentSecret: string } |
| 1939 | signal: AbortSignal |
| 1940 | onStateChange?: (state: BridgeState, detail?: string) => void |
| 1941 | onWorkReceived: ( |
| 1942 | sessionId: string, |
| 1943 | ingressToken: string, |
| 1944 | workId: string, |
| 1945 | useCodeSessions: boolean, |
| 1946 | ) => void |
| 1947 | /** Called when the environment has been deleted. Returns new credentials or null. */ |
| 1948 | onEnvironmentLost?: () => Promise<{ |
| 1949 | environmentId: string |
| 1950 | environmentSecret: string |
| 1951 | } | null> |
| 1952 | /** Returns the current WebSocket readyState label for diagnostic logging. */ |
| 1953 | getWsState?: () => string |
| 1954 | /** |
| 1955 | * Returns true when the caller cannot accept new work (transport already |
| 1956 | * connected). When true, the loop polls at the configured at-capacity |
| 1957 | * interval as a heartbeat only. Server-side BRIDGE_LAST_POLL_TTL is |
| 1958 | * 4 hours — anything shorter than that is sufficient for liveness. |
| 1959 | */ |
| 1960 | isAtCapacity?: () => boolean |
| 1961 | /** |
| 1962 | * Produces a signal that aborts when capacity frees up (transport lost), |
| 1963 | * merged with the loop signal. Used to interrupt the at-capacity sleep |
| 1964 | * so recovery polling starts immediately. |
| 1965 | */ |
| 1966 | capacitySignal?: () => CapacitySignal |
| 1967 | /** Called on unrecoverable errors (e.g. server-side expiry) to trigger full teardown. */ |
| 1968 | onFatalError?: () => void |
| 1969 | /** Poll interval config getter — defaults to DEFAULT_POLL_CONFIG. */ |
| 1970 | getPollIntervalConfig?: () => PollIntervalConfig |
| 1971 | /** |
| 1972 | * Returns the current work ID and session ingress token for heartbeat. |
| 1973 | * When null, heartbeat is not possible (no active work item). |
| 1974 | */ |
| 1975 | getHeartbeatInfo?: () => { |
| 1976 | environmentId: string |
| 1977 | workId: string |
| 1978 | sessionToken: string |
| 1979 | } | null |
no test coverage detected