Blockly interpreter: "Stepped back" message lands at the end of the output log instead of inline #76

Closed
opened 2026-05-06 04:53:38 +00:00 by spikerj · 1 comment
Owner

Problem

JavascriptInterpreterService.outputLog (the legacy string projection consumed by the Blockly playground UI) is computed as:

readonly outputLog = computed<string[]>(() => [...this.core.output().map(formatOutputLine), ...this._extraOutput()]);

Lines that flow through _extraOutput (e.g. "Stepped back to previous block (Block: xyz)." from stepBack()) are always appended after the core's console.log output. So if the user has run a program that produced 5 console.log lines and then steps back twice, the output log shows:

log 1
log 2
log 3
log 4
log 5
Stepped back to previous block (Block: abc).
Stepped back to previous block (Block: def).

The step-back messages are not interleaved with the program output the way a chronological log would suggest. Pre-refactor the legacy code had the same shape, so this is not a regression — but the new structured output channel makes it easy to do better.

Suggested fix

Either:

  • Push the step-back “Stepped back…” trailer through core.output (the same channel console.log uses) so it lands in chronological order.
  • Or stop interleaving entirely — keep a separate “debugger messages” strip in the UI for these system messages so users can mentally separate “program output” from “debugger said.”

First option is the smaller change.

Owner pointers

  • libraries/tools/src/services/blockly/interpreters/javascript-interpreter.service.ts:83 (the computed projection)
  • libraries/tools/src/services/blockly/interpreters/javascript-interpreter.service.ts:215-219 (stepBack() push)

Related

Observation from code review of the Monaco migration + JS debugger feature wave; not a blocker for the JS playground (which uses the structured output() channel directly), only the Blockly back-compat shim is affected.

## Problem `JavascriptInterpreterService.outputLog` (the legacy string projection consumed by the Blockly playground UI) is computed as: ```ts readonly outputLog = computed<string[]>(() => [...this.core.output().map(formatOutputLine), ...this._extraOutput()]); ``` Lines that flow through `_extraOutput` (e.g. `"Stepped back to previous block (Block: xyz)."` from `stepBack()`) are always appended **after** the core's `console.log` output. So if the user has run a program that produced 5 console.log lines and then steps back twice, the output log shows: ``` log 1 log 2 log 3 log 4 log 5 Stepped back to previous block (Block: abc). Stepped back to previous block (Block: def). ``` The step-back messages are not interleaved with the program output the way a chronological log would suggest. Pre-refactor the legacy code had the same shape, so this is not a regression — but the new structured output channel makes it easy to do better. ## Suggested fix Either: - Push the step-back “Stepped back…” trailer through `core.output` (the same channel `console.log` uses) so it lands in chronological order. - Or stop interleaving entirely — keep a separate “debugger messages” strip in the UI for these system messages so users can mentally separate “program output” from “debugger said.” First option is the smaller change. ## Owner pointers - `libraries/tools/src/services/blockly/interpreters/javascript-interpreter.service.ts:83` (the computed projection) - `libraries/tools/src/services/blockly/interpreters/javascript-interpreter.service.ts:215-219` (`stepBack()` push) ## Related Observation from code review of the Monaco migration + JS debugger feature wave; not a blocker for the JS playground (which uses the structured `output()` channel directly), only the Blockly back-compat shim is affected.
Author
Owner

Fixed in spikersoft-angular PR #55 (the smaller of the two suggested options). Added a public JsStepDebuggerService.emitOutput(line) that appends to the same _output stream console.log uses, and routed the Blockly "Stepped back…" message through it instead of _extraOutput. It now interleaves chronologically and is captured by step-back history snapshots. Terminal trailers ("Program completed."/errors) stay in _extraOutput since they can't interleave incorrectly (you can't step back from completed/errored). Added core ordering tests. Will close once PR #55 merges.

Fixed in `spikersoft-angular` PR #55 (the smaller of the two suggested options). Added a public `JsStepDebuggerService.emitOutput(line)` that appends to the same `_output` stream `console.log` uses, and routed the Blockly "Stepped back…" message through it instead of `_extraOutput`. It now interleaves chronologically and is captured by step-back history snapshots. Terminal trailers ("Program completed."/errors) stay in `_extraOutput` since they can't interleave incorrectly (you can't step back from completed/errored). Added core ordering tests. Will close once PR #55 merges.
Sign in to join this conversation.