docs(signals): a bare yield after await guards reader creation too, not only writes (#3482) - #3491
Merged
Merged
Conversation
…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 detectedLatest commit: fa77e55 The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 packages
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 |
Merging this PR will improve performance by 10.17%
|
| 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
Footnotes
…/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>
Coverage Report for CI Build 35084015230Coverage remained the same at 71.46%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
… 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>
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>
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.
Docstring-only; no runtime change. Closes the documentation gap behind #3482.
What
The
actiondocstring told users to put a bareyieldbefore any writes that follow anawait. The rule is broader: code between anawaitand the nextyieldruns outside the transaction (the runtime cannot hook an async generator's internalawaitcontinuations — that's whyyieldis 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. Foruntil()that commit is the settle its own promise holds open, so the action deadlocks.The expression of the next
yieldis evaluated before the step re-enters, soyield until(...)directly after anawaitis the broken shape — and it was the shapeuntil()'s own docstring example showed. #3482's reporter copied it.Verified on
nextReporter's test as filed →
TimeoutError. Withyield;inserted after theawait→settled, viewres_1:confirmed. The runtime is behaving as specified; the fix proposed in the issue (exemptingCONFIG_DIRECT_COMMITreaders from born-held) would change the semantics of a correctly written mainlineuntil()over a held frame to accommodate an incorrectly written one, and is declined.Changes
actiondocstring: rule broadened from "writes" to "writes or reader creation, including the expression of the nextyield"; example extended with ayield until(...)after the bareyield.untildocstring: a paragraph on calling it from a step inside an action; the example gains the bareyieldafterawait socket.send(...).