Skip to content

Replace transition wrapper with fluent handlers - #144

Merged
SandroMaglione merged 1 commit into
mainfrom
codex/fluent-transition-handlers
Aug 19, 2026
Merged

Replace transition wrapper with fluent handlers#144
SandroMaglione merged 1 commit into
mainfrom
codex/fluent-transition-handlers

Conversation

@SandroMaglione

Copy link
Copy Markdown
Member

Summary

  • replace Machine.transition(...) with inline fluent target selectors, target-specific .resolve(...), resolver-free .reenter(), and to.branches(...)
  • preserve exact handler, lifecycle, branch, target, decline, topology, visualizer, and MachineTest typing/behavior with compiler and language-service coverage
  • remove the definition-bound .invoke(...) method and make Machine.invoke(...) preserve owner and source inference in every handler context
  • migrate public docs, examples, fixtures, benchmarks, runtime tests, and typetests to the canonical API

Changeset

  • Added or updated for a library or package-metadata change
  • Not required because this PR does not change src/ or package.json

Validation

  • pnpm check
  • Relevant example checks, when examples changed
  • Automated type-performance measurement passed or was not required
  • Automated runtime- and memory-performance measurement passed or was not required

Additional local validation: pnpm check passed with 484 runtime tests and 182 typetests; pnpm check also passed in platformer, playground, and pokemon. pnpm perf:types and pnpm perf:runtime completed successfully.

@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.states (3 states) 3,039 3,039 0 (0.0%)
Machine.make (3 states, 2 events) 10,439 10,439 0 (0.0%)
machine.handle (3 states, 2 transitions) 54,695 32,036 -22,659 (-41.4%)
fluent transition (10 named branches) 97,636 119,749 +22,113 (+22.6%)
Machine.invoke (state-dependent Effect) 61,699 93,494 +31,795 (+51.5%)
machine.handle (depth 24) 180,815 205,744 +24,929 (+13.8%)
machine.handle (wide depth 16) 212,025 237,098 +25,073 (+11.8%)
machine.handle (parallel/history/choice) 125,861 141,115 +15,254 (+12.1%)
machine definition (3 independent implementations) 126,173 140,991 +14,818 (+11.7%)
machine exact input/output/error/services 109,419 126,285 +16,866 (+15.4%)
execution adapter readiness 119,676 135,186 +15,510 (+13.0%)

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

Scenario Base PR Difference
Import effect-machine 0 0 0
Machine.states (3 states) 2,984 2,984 0 (0.0%)
Machine.make (3 states, 2 events) 7,392 7,392 0 (0.0%)
machine.handle (3 states, 2 transitions) 44,256 21,597 -22,659 (-51.2%)
fluent transition (10 named branches) 87,707 109,820 +22,113 (+25.2%)
Machine.invoke (state-dependent Effect) 52,853 84,648 +31,795 (+60.2%)
machine.handle (depth 24) 161,125 186,054 +24,929 (+15.5%)
machine.handle (wide depth 16) 193,334 218,407 +25,073 (+13.0%)
machine.handle (parallel/history/choice) 106,185 121,439 +15,254 (+14.4%)
machine definition (3 independent implementations) 110,627 125,445 +14,818 (+13.4%)
machine exact input/output/error/services 95,328 112,194 +16,866 (+17.7%)
execution adapter readiness 56,089 103,709 +47,620 (+84.9%)
Check times (informational)
Scenario Base PR
Effect only 0.03s 0.03s
Import effect-machine 0.03s 0.03s
Machine.states (3 states) 0.10s 0.10s
Machine.make (3 states, 2 events) 0.15s 0.16s
machine.handle (3 states, 2 transitions) 0.31s 0.26s
fluent transition (10 named branches) 0.43s 0.53s
Machine.invoke (state-dependent Effect) 0.39s 0.45s
machine.handle (depth 24) 0.68s 0.80s
machine.handle (wide depth 16) 0.70s 0.80s
machine.handle (parallel/history/choice) 0.59s 0.66s
machine definition (3 independent implementations) 0.58s 0.63s
machine exact input/output/error/services 0.54s 0.58s
execution adapter readiness 0.51s 0.60s

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 9V74 80-Core Processor with Node v24.19.0.

Pull request baseline

Scenario Effect Machine
Plan counter transitions 141,695 transitions/s
Drain burst with terminal fence 409,455 increments/s
Drain burst with a change observer 386,606 increments/s
Lookup and send to one child 352,664 increments/s
Start and stop a machine 176,087 machines/s
Start and stop a parent with one child 51,549 families/s
Plan transitions through a compound state 122,266 transitions/s
Plan transitions through parallel regions 105,549 transitions/s
Drain burst through a compound state 350,364 events/s
Drain burst through two parallel regions 359,912 events/s
Drain a compound-state burst with a change observer 331,080 events/s

Process runtime reference points

Scenario Effect Machine
Start and stop a raw generic process 34,277 processes/s
Start and stop a raw compiled process 84,617 processes/s
Memory profile Effect Machine
Idle machine 1.8 KiB
Raw generic managed process 13.9 KiB
Raw compiled process 3.1 KiB
Two independent idle machines 3.4 KiB
Idle parent with one child 5.8 KiB
Parent with observed child registry 10.0 KiB
Parent with observed invoked child snapshots 6.3 KiB

Effect Machine change from base

Metric Base Base variability PR PR variability Difference
Plan counter transitions 142,587 transitions/s 0.3% MAD 141,695 transitions/s 0.7% MAD -0.6%
Drain burst with terminal fence 416,178 increments/s 0.8% MAD 409,455 increments/s 2.0% MAD -1.6%
Drain burst with a change observer 392,110 increments/s 0.4% MAD 386,606 increments/s 1.7% MAD -1.4%
Lookup and send to one child 358,179 increments/s 0.4% MAD 352,664 increments/s 1.2% MAD -1.5%
Start and stop a machine 176,710 machines/s 1.1% MAD 176,087 machines/s 0.4% MAD -0.4%
Start and stop a parent with one child 51,682 families/s 1.0% MAD 51,549 families/s 0.7% MAD -0.3%
Plan transitions through a compound state 123,642 transitions/s 1.1% MAD 122,266 transitions/s 2.8% MAD -1.1%
Plan transitions through parallel regions 102,395 transitions/s 0.9% MAD 105,549 transitions/s 0.8% MAD +3.1%
Drain burst through a compound state 344,300 events/s 0.3% MAD 350,364 events/s 1.4% MAD +1.8%
Drain burst through two parallel regions 355,661 events/s 1.1% MAD 359,912 events/s 1.4% MAD +1.2%
Drain a compound-state burst with a change observer 328,522 events/s 1.1% MAD 331,080 events/s 1.7% MAD +0.8%
Idle machine heap per unit 1.8 KiB 0.1% MAD 1.8 KiB 0.2% MAD +0.2%
Raw generic managed process heap per unit 13.9 KiB 0.0% MAD 13.9 KiB 0.0% MAD -0.0%
Raw compiled process heap per unit 3.2 KiB 0.2% MAD 3.1 KiB 0.5% MAD -0.4%
Two independent idle machines heap per unit 3.4 KiB 0.0% MAD 3.4 KiB 0.0% MAD +0.5%
Idle parent with one child heap per unit 5.8 KiB 0.0% MAD 5.8 KiB 0.0% MAD +0.0%
Parent with observed child registry heap per unit 10.0 KiB 0.0% MAD 10.0 KiB 0.0% MAD +0.0%
Parent with observed invoked child snapshots heap per unit 6.3 KiB 0.0% MAD 6.3 KiB 0.0% MAD +0.0%

Process runtime reference change from base

Metric Base Base variability PR PR variability Difference
Start and stop a raw generic process 34,491 processes/s 1.0% MAD 34,277 processes/s 1.2% MAD -0.6%
Start and stop a raw compiled process 83,486 processes/s 0.3% MAD 84,617 processes/s 1.7% MAD +1.4%

Regression guard

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

Versions and interpretation
  • Effect Machine: 0.16.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 64f4e36 into main Aug 19, 2026
13 checks passed
@SandroMaglione
SandroMaglione deleted the codex/fluent-transition-handlers branch August 19, 2026 09:14
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