(
client: HyperframesCloudClient,
renderId: string,
asJson: boolean,
poll: { intervalMs: number; maxWaitMs: number },
)
| 635 | |
| 636 | // fallow-ignore-next-line complexity |
| 637 | async function pollWithProgress( |
| 638 | client: HyperframesCloudClient, |
| 639 | renderId: string, |
| 640 | asJson: boolean, |
| 641 | poll: { intervalMs: number; maxWaitMs: number }, |
| 642 | ): Promise<HyperframesRenderDetail> { |
| 643 | // ANSI carriage-return redraws only make sense on a TTY. CI logs and |
| 644 | // file redirects get one append per status change instead, and JSON |
| 645 | // mode stays silent altogether. |
| 646 | const interactive = !asJson && process.stdout.isTTY === true; |
| 647 | let lastStatus = ""; |
| 648 | try { |
| 649 | return await pollUntilTerminal(client, renderId, { |
| 650 | intervalMs: poll.intervalMs, |
| 651 | maxWaitMs: poll.maxWaitMs, |
| 652 | // fallow-ignore-next-line complexity |
| 653 | onTick: (detail, elapsedMs) => { |
| 654 | if (asJson) return; |
| 655 | if (interactive) { |
| 656 | if (detail.status === lastStatus) { |
| 657 | process.stdout.write(`\r\x1b[2K ${formatTickLine(detail, elapsedMs)}`); |
| 658 | } else { |
| 659 | if (lastStatus) process.stdout.write("\n"); |
| 660 | process.stdout.write(` ${formatTickLine(detail, elapsedMs)}`); |
| 661 | lastStatus = detail.status; |
| 662 | } |
| 663 | } else if (detail.status !== lastStatus) { |
| 664 | // Non-TTY: one line per status transition, no carriage returns. |
| 665 | console.log(` ${formatTickLine(detail, elapsedMs)}`); |
| 666 | lastStatus = detail.status; |
| 667 | } |
| 668 | }, |
| 669 | }); |
| 670 | } catch (err) { |
| 671 | if (!asJson && lastStatus && interactive) process.stdout.write("\n"); |
| 672 | if (err instanceof PollTimeoutError) { |
| 673 | errorBox( |
| 674 | "Poll timed out", |
| 675 | err.message, |
| 676 | `The render may still complete. Resume with: hyperframes cloud get ${renderId}`, |
| 677 | ); |
| 678 | process.exit(1); |
| 679 | } |
| 680 | return reportApiError("API error during poll", err, { |
| 681 | suggestion: `The render may still be running. Resume with: hyperframes cloud get ${renderId}`, |
| 682 | }); |
| 683 | } finally { |
| 684 | if (!asJson && lastStatus && interactive) process.stdout.write("\n"); |
| 685 | } |
| 686 | } |
| 687 | |
| 688 | function formatTickLine(detail: HyperframesRenderDetail, elapsedMs: number): string { |
| 689 | const status = colorStatus(detail.status); |
no test coverage detected