| 533 | // updates. Actual flush happens on the next microtask, so a burst of events |
| 534 | // from one reducer pass becomes a single ordered drain. |
| 535 | public append(commit: StreamCommit): void { |
| 536 | if (this.isGone) { |
| 537 | return |
| 538 | } |
| 539 | |
| 540 | const last = this.queue.at(-1) |
| 541 | if ( |
| 542 | last && |
| 543 | last.phase === "progress" && |
| 544 | commit.phase === "progress" && |
| 545 | last.kind === commit.kind && |
| 546 | last.source === commit.source && |
| 547 | last.partID === commit.partID && |
| 548 | last.tool === commit.tool |
| 549 | ) { |
| 550 | last.text += commit.text |
| 551 | } else { |
| 552 | this.queue.push(commit) |
| 553 | } |
| 554 | |
| 555 | if (this.pending) { |
| 556 | return |
| 557 | } |
| 558 | |
| 559 | this.pending = true |
| 560 | queueMicrotask(() => { |
| 561 | this.pending = false |
| 562 | this.flush() |
| 563 | }) |
| 564 | } |
| 565 | |
| 566 | public idle(): Promise<void> { |
| 567 | if (this.isGone) { |