Skip to content

Version 1.6.1 - #89

Merged
estherbrunner merged 4 commits into
mainfrom
next
Oct 5, 2026
Merged

estherbrunner merged 4 commits into
mainfrom
next

Conversation

@estherbrunner

Copy link
Copy Markdown
Member

Fixed

  • match() ignored the stale handler for any signal that was not a literal Task (src/nodes/effect.ts, src/graph.ts): Previously, match() chose stale only when isTask(s) && s.isPending(). Two cases fell back to ok and showed the retained value with no in-flight signal: (1) a List or Store derived from an async computation, whose asynchrony lives in an internal Task registered through the ADR-0018 async-source registry; (2) a Slot whose backing signal is a Task. Integration layers store writable props as slots, so an async value passed into one lost its stale state. Now match() uses the free isPending() utility, and the async-source resolver follows a slot's current() backing (and chains of slots) to the signal that carries the async state. isPending(slot) and abort(slot) therefore act on the backing signal. Mutually delegating slots resolve to no async source and do not loop. A slot backed by a SlotDescriptor has no async source. Effects that use stale now run it during a re-fetch in these cases; effects without a stale handler are not affected.

estherbrunner and others added 4 commits October 5, 2026 14:30
match() picked the stale branch only for a literal Task
(isTask(s) && s.isPending()). Two cases fell back to ok and showed the
retained value with no in-flight signal:

- a List or Store derived from an async computation, whose async state
  lives in an internal Task registered via registerAsyncSource
- a Slot backed by a Task, which is how Le Truc stores writable props,
  so an async thunk passed into a child prop lost its stale state

getAsyncSource() now follows a Slot's current() backing, through chains
of slots, to the signal that carries the async state. Mutually
delegating slots resolve to no async source instead of looping.
isPending(slot) and abort(slot) therefore act on the backing signal.
match() uses isPending() and no longer imports the deprecated isTask.

Update JSDoc for isPending, abort, and the stale handlers, plus
api-facts.md, signal-types.md, and README.md, which described stale as
Task-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@estherbrunner estherbrunner self-assigned this Oct 5, 2026
@estherbrunner estherbrunner added the bug Something isn't working label Oct 5, 2026
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​zeix/​cause-effect@​1.5.1 ⏵ 1.6.079100100 +197100

View full report

@estherbrunner
estherbrunner merged commit 7ff804e into main Oct 5, 2026
11 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant