Skip to content

fix(signals): suspend uninitialized async across lanes - #3277

Merged
ryansolid merged 2 commits into
solidjs:nextfrom
javascript-unsafe:fix/latest-conditional-async-gate-3276
Sep 4, 2026
Merged

fix(signals): suspend uninitialized async across lanes#3277
ryansolid merged 2 commits into
solidjs:nextfrom
javascript-unsafe:fix/latest-conditional-async-gate-3276

Conversation

@javascript-unsafe

Copy link
Copy Markdown

Fixes #3276.

An uninitialized async source has no committed stale value to show. Suspend it even when the reader is running under a different optimistic lane, so a latest()-conditioned branch keeps its existing DOM until the source resolves.

Adds a DOM regression test covering latest(entangle) ? asyncValue() : ....

Tests:

  • pnpm exec vitest run test/latest-conditional-async-issue-3276.spec.tsx test/latest-async.spec.tsx test/latest-banner-landing-gap.spec.tsx test/latest-ispending-issue-3041.spec.tsx test/ispending-gated-landing.spec.tsx test/loading.spec.tsx test/dev-warning.spec.tsx
  • JSX_COMPILER=babel pnpm exec vitest run test/latest-conditional-async-issue-3276.spec.tsx

@changeset-bot

changeset-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2512a43

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@solidjs/signals Patch
test-integration Patch
@solidjs/web Patch
@solidjs/babel-plugin Patch
@solidjs/compiler Patch
@solidjs/diagnostics Patch
@solidjs/element Patch
@solidjs/h Patch
@solidjs/html Patch
solid-js Patch
@solidjs/universal Patch

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

@javascript-unsafe
javascript-unsafe force-pushed the fix/latest-conditional-async-gate-3276 branch from 4193324 to 4c7560b Compare September 4, 2026 16:34
@javascript-unsafe
javascript-unsafe changed the base branch from main to next September 4, 2026 16:34
@codspeed-hq

codspeed-hq Bot commented Sep 4, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 136 untouched benchmarks


Comparing javascript-unsafe:fix/latest-conditional-async-gate-3276 (2512a43) with next (4850a00)

Open in CodSpeed

ryansolid added a commit that referenced this pull request Sep 4, 2026
…uspends

No behavior change. The uninitialized cross-lane suspension merged in
8f9f369 sat inline in core read()'s throw path, taxing every bundle —
storeless floors included — for a check only reachable under an optimistic
lane (which implies the engine is installed). Measured 27-66 B over across
five size scenarios; next was over budget since the merge (Size is not a
required check, which is how it landed red — same gap as #3262 this
morning). In laneSuspends, only bundles retaining the optimistic module
pay: every scenario is back under cap except isPending/latest, which
retains the module via latest()'s shadow and pays ~8 B — ratcheted
10.05 -> 10.08 with the audit note.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ryansolid

Copy link
Copy Markdown
Member

Follow-up note: this merged while I was preparing a size-relocated variant, so the relocation landed as fa568d3 on top — same semantics, but the uninitialized check now lives in laneSuspends (optimistic module) instead of core read()'s throw path. The inline placement taxed every bundle including storeless floors (27-66 B across five size scenarios, which is why the Size check on this PR was red); laneSuspends is only reachable under a lane, which implies the engine is installed, so only bundles that retain the optimistic module pay (~8 B on isPending/latest). Your test is on next unchanged and green. Thanks again — sharp diagnosis and exactly the right contract.

@javascript-unsafe
javascript-unsafe deleted the fix/latest-conditional-async-gate-3276 branch September 4, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2.0.0-rc.6 | an ternary condition using latest() in the condition, will render an unresolved dependency in the truthy branch.

2 participants