Skip to content

Upgrade to Effect 4.0.5 and document atom-level projections - #230

Merged
SandroMaglione merged 1 commit into
mainfrom
upgrade-effect-4-0-5
Oct 21, 2026
Merged

SandroMaglione merged 1 commit into
mainfrom
upgrade-effect-4-0-5

Conversation

@SandroMaglione

Copy link
Copy Markdown
Member

Summary

  • Upgrade the pinned Effect ecosystem (effect, @effect/vitest, @effect/atom-react, @effect/platform-*) to 4.0.5 and raise published peer/dependency floors to ^4.0.5, keeping the pinned development baseline equal to the supported minimum. 4.0.5 includes Effect's fix for infinite derived-atom rebuilds.
  • Replace the React guide's "until @effect/atom-react supports selection" note: upstream declined hook-level select/equality (Add selector and equality support to Atom React hooks Effect-TS/effect#7518) in favour of derived atoms. Document the atom-level pattern (Atom.family keyed by the machine atom + Atom.mapResult + Atom.withEquality).
  • Add a React test proving a field projection is render-stable and suppresses rerenders when the projected value is unchanged (verified to fail without the custom equality).

Changeset

  • Added or updated for a library or package-metadata change
  • Not required because this PR does not change a publishable package

Minor: the supported Effect range narrows to ^4.0.5.

Validation

  • pnpm check
  • Automated type-performance measurement passed or was not required
  • Automated runtime- and memory-performance measurement passed or was not required

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Type performance

Measured with TypeScript 6.0.3 and skipLibCheck=true.

Scenario Base PR Difference
Effect only 55 55 0 (0.0%)
Import effect-machine 55 55 0 (0.0%)
Machine.state (3 children) 2,664 2,664 0 (0.0%)
Machine.make (3 states, 2 events) 8,932 8,932 0 (0.0%)
machine.handle (3 states, 2 transitions) 39,348 39,348 0 (0.0%)
declared transition (10 named branches) 60,165 60,165 0 (0.0%)
atomic construction, guards, and reentry 85,402 85,402 0 (0.0%)
registered invocation (input-taking Effect) 39,467 39,467 0 (0.0%)
machine.handle (depth 24) 194,526 194,526 0 (0.0%)
machine.handle (wide depth 16) 218,233 218,233 0 (0.0%)
machine.handle (parallel/history/choice) 91,633 91,633 0 (0.0%)
machine definition (3 independent implementations) 98,225 98,225 0 (0.0%)
machine exact input/output/error/services 82,791 82,791 0 (0.0%)
execution adapter readiness 71,416 71,416 0 (0.0%)

Marginal instantiations are measured against the matching setup without that API call:

Scenario Base PR Difference
Import effect-machine 0 0 0
Machine.state (3 children) 2,609 2,609 0 (0.0%)
Machine.make (3 states, 2 events) 6,260 6,260 0 (0.0%)
machine.handle (3 states, 2 transitions) 30,416 30,416 0 (0.0%)
declared transition (10 named branches) 51,612 51,612 0 (0.0%)
atomic construction, guards, and reentry 70,062 70,062 0 (0.0%)
registered invocation (input-taking Effect) 32,330 32,330 0 (0.0%)
machine.handle (depth 24) 177,217 177,217 0 (0.0%)
machine.handle (wide depth 16) 201,702 201,702 0 (0.0%)
machine.handle (parallel/history/choice) 79,135 79,135 0 (0.0%)
machine definition (3 independent implementations) 87,544 87,544 0 (0.0%)
machine exact input/output/error/services 70,582 70,582 0 (0.0%)
execution adapter readiness 31,918 31,918 0 (0.0%)
Check times (informational)
Scenario Base PR
Effect only 0.03s 0.03s
Import effect-machine 0.03s 0.03s
Machine.state (3 children) 0.09s 0.09s
Machine.make (3 states, 2 events) 0.14s 0.14s
machine.handle (3 states, 2 transitions) 0.30s 0.31s
declared transition (10 named branches) 0.39s 0.40s
atomic construction, guards, and reentry 0.51s 0.51s
registered invocation (input-taking Effect) 0.31s 0.31s
machine.handle (depth 24) 0.64s 0.65s
machine.handle (wide depth 16) 0.72s 0.71s
machine.handle (parallel/history/choice) 0.52s 0.52s
machine definition (3 independent implementations) 0.55s 0.53s
machine exact input/output/error/services 0.49s 0.49s
execution adapter readiness 0.45s 0.44s

Type instantiations are the comparison metric. Check time varies with runner load and is informational only.

@github-actions

Copy link
Copy Markdown
Contributor

Runtime performance

Median of 5 independent benchmark processes on AMD EPYC 7763 64-Core Processor with Node v24.21.0.

Pull request baseline

Scenario Effect Machine
Plan counter transitions 116,492 transitions/s
Drain burst with terminal fence 401,726 increments/s
Drain burst with a change observer 376,607 increments/s
Lookup and send to one child 329,819 increments/s
Start and stop a machine 126,662 machines/s
Start and stop a parent with one child 26,398 families/s
Complete an Effect invocation with tracing enabled 7,109 invocations/s
Complete an Effect invocation with tracing disabled 8,701 invocations/s
Plan transitions through a compound state 102,466 transitions/s
Plan transitions through parallel regions 80,887 transitions/s
Drain burst through a compound state 342,858 events/s
Drain burst through two parallel regions 316,903 events/s
Drain a compound-state burst with a change observer 319,140 events/s

Process runtime reference points

Scenario Effect Machine
Start and stop a raw generic process 19,579 processes/s
Start and stop a raw compiled process 71,911 processes/s
Memory profile Effect Machine
Idle machine 1.8 KiB
Raw generic managed process 11.6 KiB
Raw compiled process 3.0 KiB
Two independent idle machines 3.4 KiB
Idle parent with one child 5.9 KiB
Parent with observed child registry 9.5 KiB
Parent with observed invoked child snapshots 6.4 KiB

Effect Machine change from base

Metric Base Base variability PR PR variability Difference
Plan counter transitions 115,252 transitions/s 0.9% MAD 116,492 transitions/s 1.4% MAD +1.1%
Drain burst with terminal fence 402,907 increments/s 0.8% MAD 401,726 increments/s 1.0% MAD -0.3%
Drain burst with a change observer 375,734 increments/s 0.3% MAD 376,607 increments/s 0.2% MAD +0.2%
Lookup and send to one child 331,297 increments/s 0.2% MAD 329,819 increments/s 1.1% MAD -0.4%
Start and stop a machine 129,282 machines/s 1.5% MAD 126,662 machines/s 1.0% MAD -2.0%
Start and stop a parent with one child 24,761 families/s 0.2% MAD 26,398 families/s 2.1% MAD +6.6%
Complete an Effect invocation with tracing enabled 7,209 invocations/s 0.9% MAD 7,109 invocations/s 0.3% MAD -1.4%
Complete an Effect invocation with tracing disabled 8,808 invocations/s 1.0% MAD 8,701 invocations/s 1.3% MAD -1.2%
Plan transitions through a compound state 100,605 transitions/s 1.3% MAD 102,466 transitions/s 0.4% MAD +1.9%
Plan transitions through parallel regions 80,463 transitions/s 1.4% MAD 80,887 transitions/s 1.0% MAD +0.5%
Drain burst through a compound state 342,623 events/s 0.2% MAD 342,858 events/s 0.3% MAD +0.1%
Drain burst through two parallel regions 318,090 events/s 0.5% MAD 316,903 events/s 0.4% MAD -0.4%
Drain a compound-state burst with a change observer 321,844 events/s 0.8% MAD 319,140 events/s 0.5% MAD -0.8%
Idle machine heap per unit 1.8 KiB 0.2% MAD 1.8 KiB 0.1% MAD -0.1%
Raw generic managed process heap per unit 11.5 KiB 1.0% MAD 11.6 KiB 0.0% MAD +0.7%
Raw compiled process heap per unit 3.0 KiB 0.4% MAD 3.0 KiB 0.0% MAD -0.1%
Two independent idle machines heap per unit 3.4 KiB 0.0% MAD 3.4 KiB 0.4% MAD +0.3%
Idle parent with one child heap per unit 5.9 KiB 0.0% MAD 5.9 KiB 0.0% MAD +0.0%
Parent with observed child registry heap per unit 9.4 KiB 0.0% MAD 9.5 KiB 0.0% MAD +1.1%
Parent with observed invoked child snapshots heap per unit 6.4 KiB 0.1% MAD 6.4 KiB 0.0% MAD +0.4%

Process runtime reference change from base

Metric Base Base variability PR PR variability Difference
Start and stop a raw generic process 21,342 processes/s 0.8% MAD 19,579 processes/s 1.0% MAD -8.3%
Start and stop a raw compiled process 72,854 processes/s 1.3% MAD 71,911 processes/s 0.3% MAD -1.3%

Regression guard

No large, noise-adjusted throughput or heap regressions detected.

Versions and interpretation
  • Effect Machine: 0.40.0

Higher throughput is better; lower heap is better. Variability is the median absolute deviation across independent processes, relative to their median. Small differences on shared GitHub-hosted hardware remain informational; the required guard rejects only large changes beyond the measured noise allowance.

@SandroMaglione
SandroMaglione merged commit c0d60f0 into main Oct 21, 2026
9 checks passed
@SandroMaglione
SandroMaglione deleted the upgrade-effect-4-0-5 branch October 21, 2026 04:24
@SandroMaglione SandroMaglione mentioned this pull request Oct 21, 2026
4 of 5 tasks
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.

1 participant