[PR #4] [MERGED] fix: stream SSE events in real-time (flush gzip buffer + onerror race guard) #4

Closed
opened 2026-08-09 19:08:51 +02:00 by zaph0d · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/niels-emmer/pwa-maker-android/pull/4
Author: @niels-emmer
Created: 2/27/2026
Status: Merged
Merged: 2/27/2026
Merged by: @niels-emmer

Base: mainHead: icon-fix


📝 Commits (1)

  • 91ec8d8 fix: flush SSE gzip buffer and guard onerror race condition

📊 Changes

4 files changed (+80 additions, -13 deletions)

View changed files

📝 backend/src/routes/build.ts (+9 -0)
📝 frontend/src/hooks/useBuild.ts (+16 -8)
📝 frontend/tests/useBuild.test.ts (+36 -0)
📝 stats.md (+19 -5)

📄 Description

Summary

  • backend/src/routes/build.ts: Added res.flush() after every res.write() in the SSE route (both in send() and the heartbeat interval). Express's compression middleware buffers gzip output until res.end() — without flushing, all progress events were delivered at once when the build completed rather than streaming in real time.
  • frontend/src/hooks/useBuild.ts: Wrapped onerror's setState call in setTimeout(0). When all buffered events + connection-close arrive in the same TCP segment, onerror can fire before React applies the 'complete' state update; the timeout yields to any already-queued onmessage handlers first so the correct terminal phase is preserved.
  • frontend/tests/useBuild.test.ts: +2 tests — verifies the normal onerror error path and verifies onerror does not overwrite a completed build phase.

Test plan

  • All 143 tests pass (npm test in both backend/ and frontend/)
  • Deploy to VPS; submit a build; confirm progress bar streams live (not jumping from 0% to 100% at the end)
  • Confirm "Lost connection" is no longer shown after a successful build

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/niels-emmer/pwa-maker-android/pull/4 **Author:** [@niels-emmer](https://github.com/niels-emmer) **Created:** 2/27/2026 **Status:** ✅ Merged **Merged:** 2/27/2026 **Merged by:** [@niels-emmer](https://github.com/niels-emmer) **Base:** `main` ← **Head:** `icon-fix` --- ### 📝 Commits (1) - [`91ec8d8`](https://github.com/niels-emmer/pwa-maker-android/commit/91ec8d8616dbe2ae149160b373867165202abcae) fix: flush SSE gzip buffer and guard onerror race condition ### 📊 Changes **4 files changed** (+80 additions, -13 deletions) <details> <summary>View changed files</summary> 📝 `backend/src/routes/build.ts` (+9 -0) 📝 `frontend/src/hooks/useBuild.ts` (+16 -8) 📝 `frontend/tests/useBuild.test.ts` (+36 -0) 📝 `stats.md` (+19 -5) </details> ### 📄 Description ## Summary - **`backend/src/routes/build.ts`**: Added `res.flush()` after every `res.write()` in the SSE route (both in `send()` and the heartbeat interval). Express's `compression` middleware buffers gzip output until `res.end()` — without flushing, all progress events were delivered at once when the build completed rather than streaming in real time. - **`frontend/src/hooks/useBuild.ts`**: Wrapped `onerror`'s `setState` call in `setTimeout(0)`. When all buffered events + connection-close arrive in the same TCP segment, `onerror` can fire before React applies the `'complete'` state update; the timeout yields to any already-queued `onmessage` handlers first so the correct terminal phase is preserved. - **`frontend/tests/useBuild.test.ts`**: +2 tests — verifies the normal `onerror` error path and verifies `onerror` does not overwrite a completed build phase. ## Test plan - [ ] All 143 tests pass (`npm test` in both `backend/` and `frontend/`) - [ ] Deploy to VPS; submit a build; confirm progress bar streams live (not jumping from 0% to 100% at the end) - [ ] Confirm "Lost connection" is no longer shown after a successful build 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
zaph0d 2026-08-09 19:08:51 +02:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
github-mirrors/pwa-maker-android#4
No description provided.