feat(blocks): codegen — emit each block once, per-block trace seam, multi-edge throw - #206
Merged
07prajwal2000 merged 1 commit intoAug 6, 2026
Conversation
…dge throw Compiles each block to a named async function, deduping shared tails instead of re-emitting them per branch. edgeTo throws on >1 edge for a handle instead of silently dropping. Adds a per-block trace seam (ctx.trace) that is zero-cost when unset. Fixes a misattribution bug: loop bodies (for/foreach) never marked their block as reported before delegating to the executor block, so an executor throw was recorded twice — once correctly under the executor's blockId, once wrongly under the loop's. Closes Fluxify-rest#193
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.
Why
Codegen inlined each block's continuation as a source string, so a shared tail downstream of a diamond was re-emitted once per branch (multiplying artifact size, compile time, JIT work), and
edgeTosilently dropped every edge past the first on a handle. This also blocked per-block tracing and orchestration backtracking, which both need a stable per-block boundary.What
$block_N); a shared continuation is called, never duplicated. Reachability/emission order computed via one DFS pass (collectReachable), separate from emission.edgeTothrows when a handle has more than one outgoing edge instead of dropping the extras;validateEdges()surfaces this at compile time for the whole graph, not just the reachable subset.ctx.trace?.recordSpan(...), gated by a$tracehoisted once per invocation — zero allocation/emission when unset. Terminal blocks report via a newnode.complete()onEmitNode;response.tsmigrated./* fluxify-compiled-route-factory */marker) instantiated viainstantiateCompiled; old inline-function artifacts still run so a rolling worker update doesn't break in-flight artifacts.Bug found + fixed in review
Loop bodies (
for/foreach, viaEmitNode.body()) never marked their own block as "reported" before calling into the executor block, unlikenext(). So when an executor block inside a loop threw, the loop block's owncatchalso fired — recording a second, misattributed failure span under the loop'sblockIdin addition to the executor's correct one. Fixed by setting$recorded = truebefore the body call, matchingnext(). Covered by a new regression test.Test plan
bun test packages/blocks— 118 pass, 0 fail (added: shared-tail dedup, linear-source-across-diamonds, loop executor precedence/response propagation, trace span emission, error-span attribution incl. the loop misattribution fix, multi-edge-throw)bun run --cwd packages/blocks lint(tsgo --noEmit) — cleanCloses #193