fix(query): widen the wasm32 clock past Int32.max to survive long uptime#154
Merged
Conversation
SystemQueryClock.now() read performance.now() and did .milliseconds(Int(ms)). On wasm32 Int is 32-bit, so Int(ms) traps — killing the whole app — once page uptime passes Int32.max ms ≈ 24.85 days, exactly the long-lived dashboard workload the cache is built for. The host's 64-bit Int hid the narrowing, so every existing gate missed it (the type was smoke-tested in the browser, not unit-tested). Extract a pure, host-testable duration(millisecondsSinceOrigin:) that widens through Int64 instead of Int and clamps a non-finite reading to .max (Int64(exactly: ms.rounded()) ?? .max) rather than trapping — a benign "maximally stale → refetch", never a crash. Pin the boundary, the sub-ms rounding, and the non-finite clamp with host tests the browser-only path can't otherwise reach. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📦 Bundle size
✅ Within budget (≤5% growth allowed). Baseline: Swift 6.3, WASM SDK 6.3-RELEASE, measured 2026-06-18. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part II Wave 1 · #1 — wasm32 clock trap at ~25 days of uptime
SystemQueryClock.now()readperformance.now()and returned.milliseconds(Int(ms)).performance.now()grows monotonically from navigation start; on wasm32Intis 32-bit, soInt(ms)traps — killing the whole app — once page uptime passesInt32.maxms ≈ 24.85 days. That's exactly the long-lived dashboard workload the cache is built for (MissionControl models it).Invisible to every existing gate: the host's
Intis 64-bit, and the type was smoke-tested in the browser, not unit-tested. (Its siblingRetryPolicy.delaywas scrupulously overflow-proven; this one narrowing slipped through — the [[wasm32-int-32bit]] footgun.)Fix
Extract a pure, host-testable conversion and widen through
Int64:Int64widening removes the 32-bit trap (Int64.max ms ≈ 2.9e8 years — unreachable).Int64(exactly:) ?? .maxalso absorbs a non-finite reading (which traps even on the host) into a benign maximally-stale → refetch, never a crash.now(), precisely so the rules can be pinned by host tests the browser-only path can't otherwise reach.Tests
3 new host tests in
ClockTests:Int32.max(2^31 boundary + a 30-day uptime).infinity/.nanto.maxinstead of trappingVerification
#if canImport(JavaScriptKit)branch that actually carries the fix.🤖 Generated with Claude Code