Skip to content

Add explicit targetless transitions - #113

Merged
SandroMaglione merged 3 commits into
mainfrom
codex/explicit-targetless-transitions
Aug 15, 2026
Merged

Add explicit targetless transitions#113
SandroMaglione merged 3 commits into
mainfrom
codex/explicit-targetless-transitions

Conversation

@SandroMaglione

Copy link
Copy Markdown
Member

Summary

  • add target.none() as the explicit handled-without-destination result for event, lifecycle, and invocation transitions
  • allow target.none() regardless of declared concrete targets, including targetless reentry, in both generic and optimized planners
  • remove Machine.retag and migrate callers to discriminator destructuring plus target .from(...)
  • update README, agent guide, JSDocs, examples, fixtures, benchmarks, runtime tests, and type tests

Changeset

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

Added a minor changeset for the pre-1.0 package.

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

Validated pnpm check, pnpm check in pokemon, playground, and platformer, pnpm perf:types, and pnpm perf:runtime locally. The PR performance workflows remain authoritative for base-versus-PR comparisons.

@github-actions

github-actions Bot commented Aug 15, 2026

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.defineStates (3 states) 3,039 3,039 0 (0.0%)
Machine.make (3 states, 2 events) 13,199 13,199 0 (0.0%)
machine.handle (3 states, 2 transitions) 30,310 30,391 +81 (+0.3%)
Machine.invoke (state-dependent Effect) 70,064 70,267 +203 (+0.3%)
machine.handle (depth 24) 187,523 187,535 +12 (+0.0%)
machine.handle (wide depth 16) 219,925 219,937 +12 (+0.0%)
machine.handle (parallel/history/choice) 127,412 127,424 +12 (+0.0%)
machine.handle (4 successive calls) 135,030 135,105 +75 (+0.1%)
machine exact input/output/error/services 109,263 109,347 +84 (+0.1%)
execution adapter readiness 121,040 121,052 +12 (+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.defineStates (3 states) 2,984 2,984 0 (0.0%)
Machine.make (3 states, 2 events) 10,152 10,152 0 (0.0%)
machine.handle (3 states, 2 transitions) 17,111 17,192 +81 (+0.5%)
Machine.invoke (state-dependent Effect) 59,031 59,234 +203 (+0.3%)
machine.handle (depth 24) 167,454 167,466 +12 (+0.0%)
machine.handle (wide depth 16) 200,917 200,929 +12 (+0.0%)
machine.handle (parallel/history/choice) 101,758 101,770 +12 (+0.0%)
machine.handle (4 successive calls) 113,779 113,854 +75 (+0.1%)
machine exact input/output/error/services 92,732 92,816 +84 (+0.1%)
execution adapter readiness 86,962 86,974 +12 (+0.0%)
Check times (informational)
Scenario Base PR
Effect only 0.03s 0.02s
Import effect-machine 0.03s 0.02s
Machine.defineStates (3 states) 0.09s 0.08s
Machine.make (3 states, 2 events) 0.14s 0.14s
machine.handle (3 states, 2 transitions) 0.22s 0.23s
Machine.invoke (state-dependent Effect) 0.32s 0.33s
machine.handle (depth 24) 0.57s 0.57s
machine.handle (wide depth 16) 0.58s 0.60s
machine.handle (parallel/history/choice) 0.46s 0.47s
machine.handle (4 successive calls) 0.47s 0.49s
machine exact input/output/error/services 0.43s 0.44s
execution adapter readiness 0.44s 0.44s

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

@SandroMaglione
SandroMaglione marked this pull request as ready for review August 15, 2026 14:14
@github-actions

github-actions Bot commented Aug 15, 2026

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 119,943 transitions/s
Drain burst with terminal fence 375,858 increments/s
Drain burst with a change observer 350,864 increments/s
Lookup and send to one child 317,364 increments/s
Start and stop a machine 150,150 machines/s
Start and stop a parent with one child 42,042 families/s
Plan transitions through a compound state 107,917 transitions/s
Plan transitions through parallel regions 87,504 transitions/s
Drain burst through a compound state 341,513 events/s
Drain burst through two parallel regions 323,790 events/s
Drain a compound-state burst with a change observer 322,441 events/s

Process runtime reference points

Scenario Effect Machine
Start and stop a raw generic process 27,009 processes/s
Start and stop a raw compiled process 67,417 processes/s
Memory profile Effect Machine
Idle machine 1.7 KiB
Raw generic managed process 13.6 KiB
Raw compiled process 2.9 KiB
Two independent idle machines 3.3 KiB
Idle parent with one child 5.2 KiB
Parent with observed child registry 9.4 KiB
Parent with observed invoked child snapshots 5.6 KiB

Effect Machine change from base

Metric Base Base variability PR PR variability Difference
Plan counter transitions 117,860 transitions/s 1.0% MAD 119,943 transitions/s 1.0% MAD +1.8%
Drain burst with terminal fence 372,871 increments/s 1.9% MAD 375,858 increments/s 0.4% MAD +0.8%
Drain burst with a change observer 352,012 increments/s 1.9% MAD 350,864 increments/s 0.2% MAD -0.3%
Lookup and send to one child 320,460 increments/s 2.5% MAD 317,364 increments/s 0.3% MAD -1.0%
Start and stop a machine 150,150 machines/s 1.3% MAD 150,150 machines/s 0.9% MAD 0.0%
Start and stop a parent with one child 42,490 families/s 0.9% MAD 42,042 families/s 1.3% MAD -1.1%
Plan transitions through a compound state 107,105 transitions/s 1.0% MAD 107,917 transitions/s 1.0% MAD +0.8%
Plan transitions through parallel regions 86,345 transitions/s 2.0% MAD 87,504 transitions/s 0.6% MAD +1.3%
Drain burst through a compound state 342,977 events/s 1.3% MAD 341,513 events/s 0.7% MAD -0.4%
Drain burst through two parallel regions 322,418 events/s 1.1% MAD 323,790 events/s 1.0% MAD +0.4%
Drain a compound-state burst with a change observer 323,824 events/s 1.1% MAD 322,441 events/s 0.1% MAD -0.4%
Idle machine heap per unit 1.7 KiB 0.3% MAD 1.7 KiB 0.3% MAD -0.2%
Raw generic managed process heap per unit 13.6 KiB 0.0% MAD 13.6 KiB 0.0% MAD -0.0%
Raw compiled process heap per unit 2.9 KiB 0.2% MAD 2.9 KiB 0.2% MAD +0.2%
Two independent idle machines heap per unit 3.3 KiB 0.0% MAD 3.3 KiB 0.0% MAD +0.0%
Idle parent with one child heap per unit 5.2 KiB 0.0% MAD 5.2 KiB 0.0% MAD 0.0%
Parent with observed child registry heap per unit 9.4 KiB 0.0% MAD 9.4 KiB 0.0% MAD +0.0%
Parent with observed invoked child snapshots heap per unit 5.6 KiB 0.2% MAD 5.6 KiB 0.1% MAD +0.4%

Process runtime reference change from base

Metric Base Base variability PR PR variability Difference
Start and stop a raw generic process 26,325 processes/s 3.3% MAD 27,009 processes/s 1.3% MAD +2.6%
Start and stop a raw compiled process 66,876 processes/s 0.7% MAD 67,417 processes/s 1.0% MAD +0.8%

Regression guard

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

Versions and interpretation
  • Effect Machine: 0.9.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 force-pushed the codex/explicit-targetless-transitions branch from b617241 to f2a1651 Compare August 15, 2026 15:19
@SandroMaglione
SandroMaglione merged commit cb137a7 into main Aug 15, 2026
13 checks passed
@SandroMaglione
SandroMaglione deleted the codex/explicit-targetless-transitions branch August 15, 2026 15:24
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