Skip to content

docs(signals): a bare yield after await guards reader creation too, not only writes (#3482) - #3491

Merged
ryansolid merged 4 commits into
nextfrom
docs/action-await-yield
Sep 16, 2026
Merged

ryansolid merged 4 commits into
nextfrom
docs/action-await-yield

Conversation

@ryansolid

Copy link
Copy Markdown
Member

Docstring-only; no runtime change. Closes the documentation gap behind #3482.

What

The action docstring told users to put a bare yield before any writes that follow an await. The rule is broader: code between an await and the next yield runs outside the transaction (the runtime cannot hook an async generator's internal await continuations — that's why yield is the step primitive), so anything that creates a reader there is created mainline: until(), latest(), a memo or effect, a mount. Reading this action's held state, such a reader is born held (A29) — staged with the transaction and replayed at its commit. For until() that commit is the settle its own promise holds open, so the action deadlocks.

The expression of the next yield is evaluated before the step re-enters, so yield until(...) directly after an await is the broken shape — and it was the shape until()'s own docstring example showed. #3482's reporter copied it.

Verified on next

Reporter's test as filed → TimeoutError. With yield; inserted after the awaitsettled, view res_1:confirmed. The runtime is behaving as specified; the fix proposed in the issue (exempting CONFIG_DIRECT_COMMIT readers from born-held) would change the semantics of a correctly written mainline until() over a held frame to accommodate an incorrectly written one, and is declined.

Changes

  • action docstring: rule broadened from "writes" to "writes or reader creation, including the expression of the next yield"; example extended with a yield until(...) after the bare yield.
  • until docstring: a paragraph on calling it from a step inside an action; the example gains the bare yield after await socket.send(...).

…o, not only writes (#3482)

The action docstring said to put a bare `yield` before any WRITES that
follow an `await`. The rule is broader: code between an `await` and the
next `yield` runs outside the transaction, so anything that creates a
reader there — until(), latest(), a memo or effect, a mount — is created
mainline and, reading this action's held state, is born held (A29): staged
with the transaction and replayed at its commit. For until() that commit is
the settle its own promise holds open; the action deadlocks (#3482). The
expression of the next `yield` is evaluated before the step re-enters, so
`yield until(...)` directly after an `await` is the broken shape — and it
was the shape the until() docstring's own example showed. Both docstrings
corrected; no runtime change (the runtime cannot hook an async generator's
await continuations, which is why `yield` is the step primitive).

Co-authored-by: Claude via Cursor <noreply@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@changeset-bot

changeset-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fa77e55

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

@codspeed

codspeed Bot commented Sep 16, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 10.17%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 174 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
spread store record × 500 35.5 ms 32.2 ms +10.17%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing docs/action-await-yield (fa77e55) with next (203cbfb)1

Open in CodSpeed

Footnotes

  1. No successful run was found on next (fa77e55) during the generation of this report, so 203cbfb was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

…/until docstrings

The rules index tracks src/ citations per rule; the new docstrings cite
A29 from action.ts and signals.ts. Docs-only, no changeset needed beyond
the branch's existing one.

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@coveralls

coveralls commented Sep 16, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 35084015230

Coverage remained the same at 71.46%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1018
Covered Lines: 772
Line Coverage: 75.83%
Relevant Branches: 790
Covered Branches: 520
Branch Coverage: 65.82%
Branches in Coverage %: Yes
Coverage Strength: 14.93 hits per line

💛 - Coveralls

ryansolid and others added 2 commits September 16, 2026 03:08
… from a staged file on another branch; it belongs to the consolidation design review, not the #3482 docs fix

Co-authored-by: Cursor <cursoragent@cursor.com>
@ryansolid
ryansolid merged commit 8c80a67 into next Sep 16, 2026
6 checks passed
@ryansolid
ryansolid deleted the docs/action-await-yield branch September 16, 2026 10:22
github-actions Bot pushed a commit to yumemi-thomas/solid that referenced this pull request Sep 16, 2026
…rame (solidjs#3482)

until() and resolve() (CONFIG_DIRECT_COMMIT) created after a confirming
frame was staged under an action's optimism:

- inside the action after a bare `yield` — the action's own reader; the
  DIRECT_COMMIT arm delivers under its own hold and the action settles
  (the documented form, solidjs#3491);
- inside the action from an `await` continuation with no bare `yield` —
  a mainline reader over its own hold: born held, replays at the commit
  its promise holds open, times out (solidjs#3482 as filed);
- outside the action — a mainline reader over a FOREIGN hold: pending
  through the hold, served the committed view after the commit, never
  the unrevealed frame.

The third is the pin the suite lacked: the exemption proposed in solidjs#3482
and declined in solidjs#3490 passed 2,733 tests while making a mainline
resolve() serve another action's speculative frame. Verified: with that
one-liner applied the second and third fail; on next all three pass.

Rules index regenerated (the file cites A29).

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
ryansolid added a commit that referenced this pull request Sep 16, 2026
…both were swept in by a soft-reset squash from a pre-#3491 working tree

Co-authored-by: Cursor <cursoragent@cursor.com>
ryansolid added a commit that referenced this pull request Sep 16, 2026
…both were swept in by a soft-reset squash from a pre-#3491 working tree

Co-authored-by: Cursor <cursoragent@cursor.com>
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 participants