[PR #543] [MERGED] fix: use waitUntil in after() for Cloudflare Workers #659

Closed
opened 2026-05-06 13:09:23 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/543
Author: @NathanDrake2406
Created: 3/15/2026
Status: Merged
Merged: 3/16/2026
Merged by: @james-elicx

Base: mainHead: fix/after-waituntil


📝 Commits (10+)

  • 042caa6 fix: use waitUntil in after() to prevent task loss on Cloudflare Workers
  • a518ff6 fix: make after() synchronous with static imports per review feedback
  • c1cd2be fix: inline cache-scope check in after() to avoid headers.ts static import
  • 93a2773 Merge remote-tracking branch 'origin/main' into fix/after-waituntil
  • be66398 address review: fix cache-scope error message and add unstable_cache test for after()
  • 2077068 fix: use AST directive check before throwing missing-RSC error in use-cache transform
  • fbd0b5e fix: tighten AST walker and clarify after() TODO per review
  • f4600a5 address bonk review: clarify comments and improve test determinism
  • 9b37734 test: make error-swallowing after() test deterministic
  • 0912564 Merge remote-tracking branch 'origin/main' into pr-543

📊 Changes

3 files changed (+210 additions, -15 deletions)

View changed files

📝 packages/vinext/src/index.ts (+70 -11)
📝 packages/vinext/src/shims/server.ts (+69 -3)
📝 tests/shims.test.ts (+71 -1)

📄 Description

Summary

  • after() was scheduling tasks as fire-and-forget microtasks via Promise.resolve().then(task), which are silently dropped when Cloudflare Workers terminate after response completion
  • Now uses getRequestExecutionContext().waitUntil(promise) when an execution context exists, falling back to fire-and-forget for Node.js dev server
  • Added throwIfInsideCacheScope("after()") guard matching Next.js behavior (same pattern as connection(), headers(), cookies())
  • Kept after() synchronous (function after(): void) with static imports to ensure waitUntil is registered immediately, not on a deferred microtask

Test plan

  • Test: after() calls waitUntil on execution context when one exists
  • Test: after() falls back to fire-and-forget when no execution context
  • Test: after() throws inside "use cache" scope
  • All 688 tests pass
  • Typecheck and lint clean

🔄 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/cloudflare/vinext/pull/543 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 3/15/2026 **Status:** ✅ Merged **Merged:** 3/16/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `fix/after-waituntil` --- ### 📝 Commits (10+) - [`042caa6`](https://github.com/cloudflare/vinext/commit/042caa62721a50a21dcfcb46ad5d4a273089c95d) fix: use waitUntil in after() to prevent task loss on Cloudflare Workers - [`a518ff6`](https://github.com/cloudflare/vinext/commit/a518ff63d6c1c02d97beeb82a7c3483728f343cf) fix: make after() synchronous with static imports per review feedback - [`c1cd2be`](https://github.com/cloudflare/vinext/commit/c1cd2be0a820131f0739d2c1eec34dfb04460265) fix: inline cache-scope check in after() to avoid headers.ts static import - [`93a2773`](https://github.com/cloudflare/vinext/commit/93a27730a6bc85d3fb11ec7ae2216020d898ff11) Merge remote-tracking branch 'origin/main' into fix/after-waituntil - [`be66398`](https://github.com/cloudflare/vinext/commit/be66398064edd3a867de4327dd1a700459d9385f) address review: fix cache-scope error message and add unstable_cache test for after() - [`2077068`](https://github.com/cloudflare/vinext/commit/20770686079b16dbff5af0f97819786e8c4b4475) fix: use AST directive check before throwing missing-RSC error in use-cache transform - [`fbd0b5e`](https://github.com/cloudflare/vinext/commit/fbd0b5ec820db8f8d48c4f1a3541cbc6cdfca860) fix: tighten AST walker and clarify after() TODO per review - [`f4600a5`](https://github.com/cloudflare/vinext/commit/f4600a5ebc3cab99a0d3f621b5893cfdde043592) address bonk review: clarify comments and improve test determinism - [`9b37734`](https://github.com/cloudflare/vinext/commit/9b3773453bc7c8cafee61fe71b902ebd8e598792) test: make error-swallowing after() test deterministic - [`0912564`](https://github.com/cloudflare/vinext/commit/0912564310ec44c0e1e0ba4ed44baeaacfff729f) Merge remote-tracking branch 'origin/main' into pr-543 ### 📊 Changes **3 files changed** (+210 additions, -15 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/index.ts` (+70 -11) 📝 `packages/vinext/src/shims/server.ts` (+69 -3) 📝 `tests/shims.test.ts` (+71 -1) </details> ### 📄 Description ## Summary - `after()` was scheduling tasks as fire-and-forget microtasks via `Promise.resolve().then(task)`, which are silently dropped when Cloudflare Workers terminate after response completion - Now uses `getRequestExecutionContext().waitUntil(promise)` when an execution context exists, falling back to fire-and-forget for Node.js dev server - Added `throwIfInsideCacheScope("after()")` guard matching Next.js behavior (same pattern as `connection()`, `headers()`, `cookies()`) - Kept `after()` synchronous (`function after(): void`) with static imports to ensure `waitUntil` is registered immediately, not on a deferred microtask ## Test plan - [x] Test: `after()` calls `waitUntil` on execution context when one exists - [x] Test: `after()` falls back to fire-and-forget when no execution context - [x] Test: `after()` throws inside `"use cache"` scope - [x] All 688 tests pass - [x] Typecheck and lint clean --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:09:23 +02:00
Sign in to join this conversation.
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
starred/vinext#659
No description provided.