| 387 | } |
| 388 | |
| 389 | export class RuntimeRemoteBridgeWorker implements BridgeWorkerLike { |
| 390 | readonly #logger: LoggerLike | undefined; |
| 391 | readonly #executeJob: (job: ProactiveBridgeJob) => Promise<ProactiveBridgeJobResult>; |
| 392 | readonly #captureRuntimeException: typeof captureRuntimeException; |
| 393 | readonly #fetch: typeof fetch; |
| 394 | readonly #baseUrl: string; |
| 395 | readonly #pollIntervalMs: number; |
| 396 | readonly #maxItems: number; |
| 397 | readonly #headers: Record<string, string>; |
| 398 | #stopped = false; |
| 399 | #task: Promise<void> | null = null; |
| 400 | #wakeResolver: (() => void) | null = null; |
| 401 | |
| 402 | constructor(options: RuntimeRemoteBridgeWorkerOptions = {}) { |
| 403 | this.#logger = options.logger; |
| 404 | this.#executeJob = |
| 405 | options.executeJob ?? |
| 406 | (options.store |
| 407 | ? (job) => executeBridgeJobNatively({ job, store: options.store as RuntimeStateStore }) |
| 408 | : (() => { |
| 409 | throw new Error("bridge worker requires executeJob or store"); |
| 410 | })); |
| 411 | this.#captureRuntimeException = |
| 412 | options.captureRuntimeException ?? captureRuntimeException; |
| 413 | this.#fetch = options.fetchImpl ?? fetch; |
| 414 | this.#baseUrl = options.baseUrl ?? proactiveBridgeBaseUrl(); |
| 415 | this.#pollIntervalMs = options.pollIntervalMs ?? bridgePollIntervalMs(); |
| 416 | this.#maxItems = options.maxItems ?? bridgeMaxItems(); |
| 417 | this.#headers = proactiveBridgeHeaders(); |
| 418 | } |
| 419 | |
| 420 | async start(): Promise<void> { |
| 421 | if (this.#task) { |
| 422 | return; |
| 423 | } |
| 424 | this.#stopped = false; |
| 425 | this.#task = this.#runLoop(); |
| 426 | } |
| 427 | |
| 428 | async close(): Promise<void> { |
| 429 | this.#stopped = true; |
| 430 | const resolve = this.#wakeResolver; |
| 431 | this.#wakeResolver = null; |
| 432 | resolve?.(); |
| 433 | const task = this.#task; |
| 434 | this.#task = null; |
| 435 | await task; |
| 436 | } |
| 437 | |
| 438 | async pollOnce(): Promise<number> { |
| 439 | let jobs: ProactiveBridgeJob[]; |
| 440 | try { |
| 441 | jobs = await this.#receiveJobs(); |
| 442 | } catch (error) { |
| 443 | this.#capturePollFailure(error); |
| 444 | throw error; |
| 445 | } |
| 446 | for (const job of jobs) { |
nothing calls this directly
no outgoing calls
no test coverage detected