← Public packages
@kody/browser-run
Call Cloudflare Browser Run Quick Actions and reuse shared sessions with createBrowserContext.
src/sessions/connect.ts
68 lines · 2.1 KB · TypeScriptimport { number, object, optional, parse, string } from 'remix/data-schema'
import {
ISOLATION_INSTRUCTIONS,
authorizationHeader,
browserWsEndpoint,
browserWsEndpointAlias,
pickAuth,
requireAccountId,
} from '../client.ts'
const connectInput = object(
{
accountId: string(),
sessionId: string(),
apiTokenSecret: optional(string()),
keepAliveMs: optional(number()),
},
{ unknownKeys: 'error' },
)
/**
* Build connect info for an existing Browser Run sessionId (WS endpoint +
* Authorization guidance for puppeteer-core / CDP). Does not open the socket
* from Kody (Workers cannot hold long-lived CDP); use the returned values in
* a Worker or external Node process, then createBrowserContext + disconnect.
*
* @param raw.accountId - Cloudflare account id
* @param raw.sessionId - Existing session UUID
* @param raw.keepAliveMs - Optional keep_alive query param
* @param raw.apiTokenSecret - Optional alternate secret name
* @returns `{ sessionId, browserWSEndpoint, headers guidance, instructions }`
*
* @example
* import connect from 'kody:@kody/browser-run/sessions/connect'
* const info = await connect({
* accountId: 'YOUR_ACCOUNT_ID',
* sessionId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',
* })
*/
export default async function connectSession(raw: unknown = {}) {
const input = parse(connectInput, raw ?? {})
const auth = pickAuth(input)
const accountId = requireAccountId(auth)
const sessionId = String(input.sessionId).trim()
if (!sessionId) throw new Error('sessionId is required.')
return {
ok: true,
accountId,
sessionId,
browserWSEndpoint: browserWsEndpoint(accountId, sessionId, input.keepAliveMs),
browserWSEndpointAlias: browserWsEndpointAlias(
accountId,
sessionId,
input.keepAliveMs,
),
authorizationHeaderTemplate: authorizationHeader(auth),
puppeteerConnectExample: {
browserWSEndpoint: browserWsEndpoint(accountId, sessionId, input.keepAliveMs),
headers: {
Authorization: authorizationHeader(auth),
},
},
isolation: 'createBrowserContext' as const,
disconnectNotClose: true as const,
instructions: ISOLATION_INSTRUCTIONS,
}
}