* 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
})
| 1849 | * reconnection without tearing down the bridge. |
| 1850 | */ |
| 1851 | async function startWorkPollLoop({ |
| 1852 | api, |
| 1853 | getCredentials, |
| 1854 | signal, |
| 1855 | onStateChange, |
| 1856 | onWorkReceived, |
| 1857 | onEnvironmentLost, |
| 1858 | getWsState, |
| 1859 | isAtCapacity, |
| 1860 | capacitySignal, |
| 1861 | onFatalError, |
| 1862 | getPollIntervalConfig = () => DEFAULT_POLL_CONFIG, |
| 1863 | getHeartbeatInfo, |
| 1864 | onHeartbeatFatal, |
| 1865 | }: { |
| 1866 | api: BridgeApiClient |
| 1867 | getCredentials: () => { environmentId: string; environmentSecret: string } |
| 1868 | signal: AbortSignal |
| 1869 | onStateChange?: (state: BridgeState, detail?: string) => void |
| 1870 | onWorkReceived: ( |
| 1871 | sessionId: string, |
| 1872 | ingressToken: string, |
| 1873 | workId: string, |
| 1874 | useCodeSessions: boolean, |
| 1875 | ) => void |
| 1876 | /** Called when the environment has been deleted. Returns new credentials or null. */ |
| 1877 | onEnvironmentLost?: () => Promise<{ |
| 1878 | environmentId: string |
| 1879 | environmentSecret: string |
| 1880 | } | null> |
| 1881 | /** Returns the current WebSocket readyState label for diagnostic logging. */ |
| 1882 | getWsState?: () => string |
| 1883 | /** |
| 1884 | * Returns true when the caller cannot accept new work (transport already |
| 1885 | * connected). When true, the loop polls at the configured at-capacity |
| 1886 | * interval as a heartbeat only. Server-side BRIDGE_LAST_POLL_TTL is |
| 1887 | * 4 hours — anything shorter than that is sufficient for liveness. |
| 1888 | */ |
| 1889 | isAtCapacity?: () => boolean |
| 1890 | /** |
| 1891 | * Produces a signal that aborts when capacity frees up (transport lost), |
| 1892 | * merged with the loop signal. Used to interrupt the at-capacity sleep |
| 1893 | * so recovery polling starts immediately. |
| 1894 | */ |
| 1895 | capacitySignal?: () => CapacitySignal |
| 1896 | /** Called on unrecoverable errors (e.g. server-side expiry) to trigger full teardown. */ |
| 1897 | onFatalError?: () => void |
| 1898 | /** Poll interval config getter — defaults to DEFAULT_POLL_CONFIG. */ |
| 1899 | getPollIntervalConfig?: () => PollIntervalConfig |
| 1900 | /** |
| 1901 | * Returns the current work ID and session ingress token for heartbeat. |
| 1902 | * When null, heartbeat is not possible (no active work item). |
| 1903 | */ |
| 1904 | getHeartbeatInfo?: () => { |
| 1905 | environmentId: string |
| 1906 | workId: string |
| 1907 | sessionToken: string |
| 1908 | } | null |
no test coverage detected