fix(core): prevent incorrect transition state when transitionDuration is 0#691
Conversation
…heme
The `time()` utility adds sub-millisecond offsets to ensure unique event
timestamps. When `dispatchEvent` calls `aggregate()` with `Date.now()`,
there is a race condition where `Date.now() < eventDate` (by a fraction
of a millisecond), causing `now - eventDate < 0`. With transitionDuration
set to 0, this makes the `>= transitionDuration` check fail, briefly
putting the activity in `enter-active` instead of `enter-done`.
Combined with `useLazy`'s 2-frame delay and the android theme's default
`opacity: 0` style, this produces a visible flicker ("jitter") during
page transitions.
Use `Math.max(newEvent.eventDate, Date.now())` to guarantee
`now >= eventDate`, ensuring the transition state resolves correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: da242aa The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR fixes an intermittent state aggregation bug in Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
@stackflow/core
@stackflow/compat-await-push
@stackflow/link
@stackflow/plugin-basic-ui
@stackflow/plugin-blocker
@stackflow/plugin-devtools
@stackflow/plugin-google-analytics-4
@stackflow/plugin-history-sync
@stackflow/plugin-map-initial-activity
@stackflow/plugin-preload
@stackflow/plugin-renderer-basic
@stackflow/plugin-renderer-web
@stackflow/plugin-sentry
@stackflow/plugin-stack-depth-change
@stackflow/react-ui-core
@stackflow/react
commit: |
Deploying stackflow-demo with
|
| Latest commit: |
da242aa
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5f384c0f.stackflow-demo.pages.dev |
| Branch Preview URL: | https://fix-transition-duration-zero.stackflow-demo.pages.dev |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
stackflow-docs | da242aa | Commit Preview URL | Apr 03 2026, 02:33 AM |
4e1077d to
4987887
Compare
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4987887 to
da242aa
Compare
Closes FECO-90
Summary
transitionDuration: 0설정 시 간헐적으로 transition state가enter-done대신enter-active로 잘못 설정되는 이슈를 수정합니다.dispatchEvent에서aggregate()호출 시Math.max(newEvent.eventDate, Date.now())를 사용하여now >= eventDate를 보장합니다.Root Cause
core/src/utils/time.ts의time()함수는 이벤트 정렬을 위해 같은 밀리초 내 중복 호출 시 sub-millisecond 오프셋을 추가합니다 (e.g.,1000000.001).dispatchEvent에서aggregate(events, Date.now())를 호출할 때,Date.now()가 같은 밀리초를 반환하면now < eventDate가 되어now - eventDate >= transitionDuration(0)판정이 실패합니다.이로 인해 activity가
enter-done대신enter-active상태로 진입하게 됩니다.Test plan
yarn workspace @stackflow/core test— 84개 테스트 모두 통과transitionDuration: 0으로 반복 네비게이션 시 정상 동작 확인transitionDuration: 270(기본값)으로 전환 애니메이션 정상 작동 확인🤖 Generated with Claude Code