Skip to content

CSE machine: StreamViz arrow drawing#3747

Open
of89p wants to merge 46 commits into
masterfrom
streamVis
Open

CSE machine: StreamViz arrow drawing#3747
of89p wants to merge 46 commits into
masterfrom
streamVis

Conversation

@of89p
Copy link
Copy Markdown

@of89p of89p commented Apr 6, 2026

Description

Created new panel in CSE machine for Stream Visualization (pairs and nullary functions belonging to streams).

Displays results from streamViz js-slang PR (source-academy/js-slang#1939). Specifically, we use results from streamLineage from the Context object to draw dotted arrows from a nullary function to the pair(s) it returns.

The map streamLineage (Found in context object, types.ts) that maps the ID of nullary functions to the pairs it returns.

Everytime a CALL0 is called in the control, we push a tuple (nullaryFnID, controlStackHeight) to the pendingStreamFnStack[]. Within generateCSEMachineStateStream, we check the whether the height of the control stack has reached the height of i-1, where i is the controlStackHeight when we pendingStreamFnStack.peek(). If so, we pop pendingStreamFnStack.pop() and we add the pair that is at the top of the stash to the array of pairs that the nullaryFnID maps to, using streamLineage.

See also frontend issue: #3727

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Code quality improvements

How to test

Checklist

  • I have tested this code
  • I have updated the documentation

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a "Pair Visualisation" feature to the CSE Machine, enabling stream lineage visualization through a new toggleable mode. The changes include state management for streamsPointSteps, new arrow components, and logic to link array values to their originating functions. Feedback focuses on removing non-portable local file paths in package.json, deleting an accidentally committed build artifact, and cleaning up leftover debug logs, commented-out code, and redundant logic in the FnValue component.

Comment thread package.json Outdated
Comment thread package.json Outdated
Comment thread tsconfig.tsbuildinfo Outdated
Comment thread src/features/cseMachine/CseMachineLayout.tsx Outdated
Comment thread src/features/cseMachine/components/arrows/ArrowFromStreamNullaryFn.tsx Outdated
Comment thread src/features/cseMachine/components/values/ArrayValue.tsx Outdated
Comment thread src/features/cseMachine/components/values/FnValue.tsx Outdated
Comment thread src/features/cseMachine/CseMachine.tsx
Comment thread src/features/cseMachine/components/values/FnValue.tsx
Comment thread package.json Outdated
Comment thread src/features/cseMachine/CseMachineLayout.tsx Outdated
Comment thread src/features/cseMachine/components/values/FnValue.tsx Outdated
Comment thread src/commons/sideContent/content/SideContentCseMachine.tsx Outdated
@martin-henz martin-henz removed the blocked Something else needs pass review first label Apr 17, 2026
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 17, 2026

Coverage Report for CI Build 26861602081

Coverage decreased (-0.1%) to 41.752%

Details

  • Coverage decreased (-0.1%) from the base build.
  • Patch coverage: 53 uncovered changes across 6 files (8 of 61 lines covered, 13.11%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
src/features/cseMachine/components/arrows/ArrowFromStreamNullaryFn.tsx 19 0 0.0%
src/features/cseMachine/CseMachine.tsx 18 4 22.22%
src/features/cseMachine/components/values/FnValue.tsx 12 3 25.0%
src/commons/sideContent/content/SideContentCseMachine.tsx 9 1 11.11%
src/features/cseMachine/components/arrows/DottedArrow.tsx 2 0 0.0%
src/commons/sagas/WorkspaceSaga/helpers/updateInspector.ts 1 0 0.0%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 13370
Covered Lines: 6011
Line Coverage: 44.96%
Relevant Branches: 6998
Covered Branches: 2493
Branch Coverage: 35.62%
Branches in Coverage %: Yes
Coverage Strength: 27.64 hits per line

💛 - Coveralls

Comment on lines +271 to +281
// Clear arrows to prevent duplicates from multiple draw calls

if (pairs != undefined) {
for (const pair of pairs) {
const target = Layout.values.get(pair);
if (target) {
this.addArrow(target);
}
}
}
}

This comment was marked as outdated.

@martin-henz
Copy link
Copy Markdown
Member

This program seems to get stuck at step 81, now:

function make_ints(i) {
    return pair(i, () => make_ints(i + 1));
}

stream_ref(make_ints(0), 10);
Screenshot 2026-04-22 at 10 57 53 AM

Copy link
Copy Markdown
Member

@RichDom2185 RichDom2185 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can reproduce the issue flagged by Prof @martin-henz. It's a blocker

Copy link
Copy Markdown
Contributor

@Akshay-2007-1 Akshay-2007-1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. FnValue.tsx — the main fix (root cause of the bug)

The bug: The draw() method runs on every render step. At the very start of draw(), it did this._streamArrows = [] —
wiping the arrow list. But before that wipe, it was calling getStreamLineage() and trying to use the result. So the
arrows were built, then immediately thrown away before they could be rendered. The stream visualization never actually
drew anything.

The fix: Move getStreamLineage() inside the if (getPairCreationMode()) block, after the wipe. Now arrows are built
fresh each render, in the right order.

Also removed: ~30 lines of dead constructor code that tried to draw stream arrows during object construction — but
since draw() always wiped _streamArrows = [] at the start, anything set in the constructor was always discarded before
rendering. It was completely unreachable code that had no effect.

Also fixed: centerX (the horizontal center of the function circles) was being computed after the arrows were created.
Arrows use centerX for their starting position, so they could start from x=0. Moved centerX calculation to the very
top of draw().

Also removed: A throw new Error('Closure has no main reference...') that could never actually fire (the value is
always set before draw() is called), but if it ever did, it would crash the whole visualization silently.


  1. ArrayValue.tsx — removed dead constructor code

The pair (array) constructor had code that tried to notify its parent function value about itself, so the function
could draw an arrow to it. This was the other half of the dead code above — it set Layout.pendingFnLink = true as a
signal. Since FnValue's constructor code reading that flag was already dead, this code had no effect either. Removed
it, along with the unused Closure import.


  1. CseMachineLayout.tsx — removed dead state variables

Six static fields (currentDarkPairs, currentLightPairs, etc.) were declared and reset in setContext(), but never read
Also removed: A throw new Error('Closure has no main reference...') that could never actually fire (the value is always set before draw() is called), but
if it ever did, it would crash the whole visualization silently.


  1. ArrayValue.tsx — removed dead constructor code

The pair (array) constructor had code that tried to notify its parent function value about itself, so the function could draw an arrow to it. This was the
other half of the dead code above — it set Layout.pendingFnLink = true as a signal. Since FnValue's constructor code reading that flag was already dead,
this code had no effect either. Removed it, along with the unused Closure import.


  1. CseMachineLayout.tsx — removed dead state variables

Six static fields (currentDarkPairs, currentLightPairs, etc.) were declared and reset in setContext(), but never read anywhere — they were leftovers from
an earlier implementation. Also removed pendingFnLink (the boolean flag used by the dead constructor code above) and streamNodes = null which was assigned
but never used in the JSX render.


  1. updateInspector.ts — stop silently swallowing errors

The catch block previously had a comment saying errors were "most likely harmless, we can pretty much ignore this." This meant if the CSE machine
visualization crashed during rendering, it would look like the diagram was just "stuck" — no error, no feedback. Changed to console.error(...) so any
crash now shows up in the browser console with a real message.


I made an AI written summary for the changes I made in the recent commit for better understanding. @DaRealTristan do look into if the actual Stream dotted arrows work or my changes are breaking!

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 31, 2026

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3aa6af7e-83af-4e49-8c5f-1743b2426fb7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR adds pair-creation-mode visualization to the CSE machine diagram. It introduces new state and accessors in CseMachine, defines two new arrow component types, integrates stream-arrow rendering into FnValue, and provides UI controls to toggle the visualization and refresh the diagram accordingly.

Changes

Pair Creation Mode Visualization

Layer / File(s) Summary
Pair creation mode state and stream lineage
src/features/cseMachine/CseMachine.tsx
CseMachine adds pairCreationMode static state, togglePairCreationMode() and getPairCreationMode() accessors, and a streamLineage map populated from context.streamLineage during drawCse; utility methods getStreamLineage() and findKeyByValueInMap() provide access to lineage data.
Arrow component definitions
src/features/cseMachine/components/arrows/DottedArrow.tsx, src/features/cseMachine/components/arrows/ArrowFromStreamNullaryFn.tsx, src/features/cseMachine/components/values/ArrayValue.tsx
DottedArrow renders a dashed path with arrow head, styled by printable mode; ArrowFromStreamNullaryFn extends DottedArrow to draw curved paths from nullary functions to array targets with offset-based vertical spacing controlled by offsetIndex.
FnValue stream arrow rendering
src/features/cseMachine/components/values/FnValue.tsx
FnValue imports ArrowFromStreamNullaryFn, adds _streamArrows collection and addArrow(target) method to create offset-indexed arrows; draw() populates stream arrows from CseMachine.getStreamLineage() when pair-creation mode is enabled, then renders all arrows alongside existing arrows.
UI controls and changepoint navigation
src/commons/sideContent/content/SideContentCseMachine.tsx
A new "Pairs returned by nullary functions" checkbox in the filter-arrows popover toggles pair-creation mode via togglePairCreationModeArrows(); stepNextChangepoint and stepPrevChangepoint introduce a local changeSteps alias to safely cache and iterate over changepoint steps.
Pair creation mode rendering flow
src/features/cseMachine/CseMachine.tsx
redraw() branches on pairCreationMode to refresh layout context, initialize master layout if missing, apply fixed positions, and render via Layout.draw() before standard render logic.
Error logging and minor updates
src/commons/sagas/WorkspaceSaga/helpers/updateInspector.ts, src/features/cseMachine/CseMachineLayout.tsx
updateInspector now logs visualization rendering errors via console.error; formatting whitespace added to Layout.setContext and Layout.draw.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'CSE machine: StreamViz arrow drawing' directly and specifically describes the main feature: adding stream visualization arrow rendering to the CSE machine component.
Description check ✅ Passed The description covers the main purpose (stream visualization panel), technical implementation details, and references related issues, though test execution and documentation update checkboxes remain unchecked.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (5)
src/features/cseMachine/components/values/FnValue.tsx (1)

144-152: 💤 Low value

Tighten typing and drop redundant optional chaining in addArrow.

target: any discards type safety even though calculateSteps only handles ArrayValue. Also _streamArrows is always initialized at declaration, so ?.push is a no-op.

♻️ Proposed refactor
-  addArrow(target: any): void {
+  addArrow(target: ArrayValue): void {
     // Check how many arrows already point to this specific target
     const currentCount = this._streamArrows.filter(arrow => arrow.target === target).length;

     // Pass the count as the offsetIndex
-    this._streamArrows?.push(
+    this._streamArrows.push(
       new ArrowFromStreamNullaryFn(this, currentCount).to(target) as ArrowFromStreamNullaryFn,
     );
   }

(Requires importing ArrayValue; resolves the unused index param at Line 326 as well by switching to arrow => arrow.draw().)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/cseMachine/components/values/FnValue.tsx` around lines 144 -
152, The addArrow method uses target: any and redundant optional chaining;
tighten its signature to target: ArrayValue (import ArrayValue), remove the ?.
and call this._streamArrows.push(...) directly, and keep creating the
ArrowFromStreamNullaryFn(this, currentCount).to(target) cast as before; also
ensure calculateSteps still expects ArrayValue and update any consumers
accordingly (this resolves the unused index warning by enabling arrow =>
arrow.draw() elsewhere when iterating _streamArrows).
src/features/cseMachine/components/arrows/ArrowFromStreamNullaryFn.tsx (1)

20-29: ⚡ Quick win

Reassess union-type geometry: centerX/radius access is safe here

GlobalFnValue and ContValue both declare readonly radius and centerX (they’re set during layout), so ArrowFromStreamNullaryFn’s from.centerX/from.radius usage won’t become NaN. Also, ArrowFromStreamNullaryFn is currently only instantiated from src/features/cseMachine/components/values/FnValue.tsx (with this as a FnValue).

Minor: update the class doc comment at ArrowFromStreamNullaryFn.tsx line 9 (“an GenericArrow”).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/cseMachine/components/arrows/ArrowFromStreamNullaryFn.tsx`
around lines 20 - 29, The access to from.centerX and from.radius in
ArrowFromStreamNullaryFn is safe because GlobalFnValue and ContValue (and
FnValue) declare readonly radius and centerX, so remove any unnecessary
defensive guards or casts around using from.centerX/from.radius (leave
startPointX/startPointY calculation using from.centerX + 2 * from.radius and
from.y()); add a short inline comment in ArrowFromStreamNullaryFn noting that
FnValue|GlobalFnValue|ContValue all provide centerX/radius to clarify the union
typing, and update the class doc comment on ArrowFromStreamNullaryFn (around the
top of the file) to the requested text “an GenericArrow”.
src/features/cseMachine/CseMachine.tsx (2)

184-193: ⚡ Quick win

Improve type safety for findKeyByValueInMap.

The parameter type any is overly broad. Based on the method's purpose (finding a nullary function ID by pair ID), the parameter should be typed as string.

🔧 Proposed type safety improvement
-  public static findKeyByValueInMap(value: any) {
+  public static findKeyByValueInMap(value: string): string | undefined {
    for (const [key, array] of CseMachine.streamLineage.entries()) {
      if (array.includes(value)) {
        return key;
      }
    }
    return undefined;
  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/cseMachine/CseMachine.tsx` around lines 184 - 193, The parameter
of CseMachine.findKeyByValueInMap is typed as any but should be a string since
it finds a nullary function ID by pair ID; change the parameter type from any to
string (e.g., findKeyByValueInMap(value: string)) and update any call sites that
pass non-string values to ensure they pass strings or are converted, keeping the
return type as string | undefined and using the existing
CseMachine.streamLineage Map iteration logic.

430-441: 💤 Low value

Consider refactoring duplicate rendering logic.

The pair creation mode branch (lines 431-437) duplicates the same sequence as the fallback else block (lines 482-488). Consider extracting this shared logic into a helper method to reduce duplication.

♻️ Example refactor
private static refreshLayoutAndDraw(): void {
  Layout.setContext(CseMachine.environmentTree!, CseMachine.control!, CseMachine.stash!);
  if (!CseMachine.getMasterLayout()) {
    CseMachine.setMasterLayout(Layout.getLayoutPositions(this.controlStash));
  }
  Layout.applyFixedPositions();
  CseAnimation.updateAnimation();
  this.setVis(Layout.draw());
}

Then use it in both branches:

      if (CseMachine.getPairCreationMode()) {
-        Layout.setContext(CseMachine.environmentTree, CseMachine.control, CseMachine.stash);
-        if (!CseMachine.getMasterLayout()) {
-          CseMachine.setMasterLayout(Layout.getLayoutPositions(this.controlStash));
-        }
-        Layout.applyFixedPositions();
-        CseAnimation.updateAnimation();
-        this.setVis(Layout.draw());
+        CseMachine.refreshLayoutAndDraw();
      } else if (
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/features/cseMachine/CseMachine.tsx` around lines 430 - 441, Extract the
duplicated sequence (Layout.setContext(...), conditional
CseMachine.getMasterLayout()/CseMachine.setMasterLayout(...),
Layout.applyFixedPositions(), CseAnimation.updateAnimation(),
this.setVis(Layout.draw())) into a single helper (e.g., private static
refreshLayoutAndDraw or an instance method refreshLayoutAndDraw) and replace the
duplicated blocks in the CseMachine.getPairCreationMode() branch and the
fallback else branch with a call to that helper; ensure the helper accepts or
references the same symbols used now (CseMachine.environmentTree,
CseMachine.control, CseMachine.stash, this.controlStash) so the behavior remains
identical.
src/commons/sagas/WorkspaceSaga/helpers/updateInspector.ts (1)

50-52: ⚡ Quick win

Consider displaying error feedback to users.

The console logging helps developers debug rendering failures, but users won't see this message. Given the PR context mentions programs appearing "stuck," consider dispatching an action to display an error notification in the UI so users understand why the visualization didn't update.

💡 Example approach
 } catch (e) {
   // TODO: Hardcoded to make use of the first editor tab. Rewrite after editor tabs are added.
   yield put(actions.setEditorHighlightedLines(workspaceLocation, 0, []));
   // Log rendering errors so they are not silently swallowed — the visualization
   // simply won't update when this fires, which looks like the diagram is "stuck".
   console.error('[updateInspector] Visualization rendering failed:', e);
+  // Optionally notify the user
+  yield put(actions.addEditorTab(workspaceLocation, {
+    type: 'error',
+    message: 'CSE Machine visualization failed to render. Check console for details.'
+  }));
 }

(Adjust the action name and payload to match your existing notification system.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commons/sagas/WorkspaceSaga/helpers/updateInspector.ts` around lines 50 -
52, In updateInspector.ts, inside the catch block that currently only calls
console.error('[updateInspector] Visualization rendering failed:', e), dispatch
a UI notification action (e.g., showErrorNotification or notifyError) with a
user-friendly message and include enough error context (error message/id) for
debugging; update the error handling in the updateInspector function to call the
existing notification action creator or saga/dispatcher used across the app so
users see a visible error when the visualization fails instead of only a console
error.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/features/cseMachine/CseMachine.tsx`:
- Line 68: Remove the leftover commented-out assignment for
CseMachine.pairCreationMode (the line "//CseMachine.pairCreationMode = false;")
from the CseMachine component to clean up dead/commented code; simply delete
that commented line so the source contains no unused commented fragments
referencing CseMachine.pairCreationMode.
- Around line 438-440: Remove the leftover commented debug lines that call
Layout.draw(), console.log(Layout.currentDarkPairs), and
this.setVis(Layout.currentDarkPairs) in CseMachine (the commented trio around
setVis/Layout.currentDarkPairs). Edit the CseMachine.tsx file to delete those
three commented lines so only active production code remains (leave any real
calls like this.setVis elsewhere intact).
- Line 186: Remove the leftover commented debug line "// console.log(key +
array);" from the CseMachine component in CseMachine.tsx; locate the commented
statement inside the CseMachine class/function and delete that single line so no
commented console.log remains in the source.

---

Nitpick comments:
In `@src/commons/sagas/WorkspaceSaga/helpers/updateInspector.ts`:
- Around line 50-52: In updateInspector.ts, inside the catch block that
currently only calls console.error('[updateInspector] Visualization rendering
failed:', e), dispatch a UI notification action (e.g., showErrorNotification or
notifyError) with a user-friendly message and include enough error context
(error message/id) for debugging; update the error handling in the
updateInspector function to call the existing notification action creator or
saga/dispatcher used across the app so users see a visible error when the
visualization fails instead of only a console error.

In `@src/features/cseMachine/components/arrows/ArrowFromStreamNullaryFn.tsx`:
- Around line 20-29: The access to from.centerX and from.radius in
ArrowFromStreamNullaryFn is safe because GlobalFnValue and ContValue (and
FnValue) declare readonly radius and centerX, so remove any unnecessary
defensive guards or casts around using from.centerX/from.radius (leave
startPointX/startPointY calculation using from.centerX + 2 * from.radius and
from.y()); add a short inline comment in ArrowFromStreamNullaryFn noting that
FnValue|GlobalFnValue|ContValue all provide centerX/radius to clarify the union
typing, and update the class doc comment on ArrowFromStreamNullaryFn (around the
top of the file) to the requested text “an GenericArrow”.

In `@src/features/cseMachine/components/values/FnValue.tsx`:
- Around line 144-152: The addArrow method uses target: any and redundant
optional chaining; tighten its signature to target: ArrayValue (import
ArrayValue), remove the ?. and call this._streamArrows.push(...) directly, and
keep creating the ArrowFromStreamNullaryFn(this, currentCount).to(target) cast
as before; also ensure calculateSteps still expects ArrayValue and update any
consumers accordingly (this resolves the unused index warning by enabling arrow
=> arrow.draw() elsewhere when iterating _streamArrows).

In `@src/features/cseMachine/CseMachine.tsx`:
- Around line 184-193: The parameter of CseMachine.findKeyByValueInMap is typed
as any but should be a string since it finds a nullary function ID by pair ID;
change the parameter type from any to string (e.g., findKeyByValueInMap(value:
string)) and update any call sites that pass non-string values to ensure they
pass strings or are converted, keeping the return type as string | undefined and
using the existing CseMachine.streamLineage Map iteration logic.
- Around line 430-441: Extract the duplicated sequence (Layout.setContext(...),
conditional CseMachine.getMasterLayout()/CseMachine.setMasterLayout(...),
Layout.applyFixedPositions(), CseAnimation.updateAnimation(),
this.setVis(Layout.draw())) into a single helper (e.g., private static
refreshLayoutAndDraw or an instance method refreshLayoutAndDraw) and replace the
duplicated blocks in the CseMachine.getPairCreationMode() branch and the
fallback else branch with a call to that helper; ensure the helper accepts or
references the same symbols used now (CseMachine.environmentTree,
CseMachine.control, CseMachine.stash, this.controlStash) so the behavior remains
identical.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 63d238e1-21ef-4517-a1b6-a1706382f122

📥 Commits

Reviewing files that changed from the base of the PR and between 89e076d and dd5a1f2.

📒 Files selected for processing (8)
  • src/commons/sagas/WorkspaceSaga/helpers/updateInspector.ts
  • src/commons/sideContent/content/SideContentCseMachine.tsx
  • src/features/cseMachine/CseMachine.tsx
  • src/features/cseMachine/CseMachineLayout.tsx
  • src/features/cseMachine/components/arrows/ArrowFromStreamNullaryFn.tsx
  • src/features/cseMachine/components/arrows/DottedArrow.tsx
  • src/features/cseMachine/components/values/ArrayValue.tsx
  • src/features/cseMachine/components/values/FnValue.tsx

Comment thread src/features/cseMachine/CseMachine.tsx Outdated
Comment thread src/features/cseMachine/CseMachine.tsx Outdated
Comment thread src/features/cseMachine/CseMachine.tsx Outdated
@DaRealTristan
Copy link
Copy Markdown

  1. FnValue.tsx — the main fix (root cause of the bug)

The bug: The draw() method runs on every render step. At the very start of draw(), it did this._streamArrows = [] — wiping the arrow list. But before that wipe, it was calling getStreamLineage() and trying to use the result. So the arrows were built, then immediately thrown away before they could be rendered. The stream visualization never actually drew anything.

The fix: Move getStreamLineage() inside the if (getPairCreationMode()) block, after the wipe. Now arrows are built fresh each render, in the right order.

Also removed: ~30 lines of dead constructor code that tried to draw stream arrows during object construction — but since draw() always wiped _streamArrows = [] at the start, anything set in the constructor was always discarded before rendering. It was completely unreachable code that had no effect.

Also fixed: centerX (the horizontal center of the function circles) was being computed after the arrows were created. Arrows use centerX for their starting position, so they could start from x=0. Moved centerX calculation to the very top of draw().

Also removed: A throw new Error('Closure has no main reference...') that could never actually fire (the value is always set before draw() is called), but if it ever did, it would crash the whole visualization silently.

  1. ArrayValue.tsx — removed dead constructor code

The pair (array) constructor had code that tried to notify its parent function value about itself, so the function could draw an arrow to it. This was the other half of the dead code above — it set Layout.pendingFnLink = true as a signal. Since FnValue's constructor code reading that flag was already dead, this code had no effect either. Removed it, along with the unused Closure import.

  1. CseMachineLayout.tsx — removed dead state variables

Six static fields (currentDarkPairs, currentLightPairs, etc.) were declared and reset in setContext(), but never read Also removed: A throw new Error('Closure has no main reference...') that could never actually fire (the value is always set before draw() is called), but if it ever did, it would crash the whole visualization silently.

  1. ArrayValue.tsx — removed dead constructor code

The pair (array) constructor had code that tried to notify its parent function value about itself, so the function could draw an arrow to it. This was the other half of the dead code above — it set Layout.pendingFnLink = true as a signal. Since FnValue's constructor code reading that flag was already dead, this code had no effect either. Removed it, along with the unused Closure import.

  1. CseMachineLayout.tsx — removed dead state variables

Six static fields (currentDarkPairs, currentLightPairs, etc.) were declared and reset in setContext(), but never read anywhere — they were leftovers from an earlier implementation. Also removed pendingFnLink (the boolean flag used by the dead constructor code above) and streamNodes = null which was assigned but never used in the JSX render.

  1. updateInspector.ts — stop silently swallowing errors

The catch block previously had a comment saying errors were "most likely harmless, we can pretty much ignore this." This meant if the CSE machine visualization crashed during rendering, it would look like the diagram was just "stuck" — no error, no feedback. Changed to console.error(...) so any crash now shows up in the browser console with a real message.

I made an AI written summary for the changes I made in the recent commit for better understanding. @DaRealTristan do look into if the actual Stream dotted arrows work or my changes are breaking!

Just checked with the stream examples we have and it works! Thanks for all the help @Akshay-2007-1 ! Will work on the js-slang map issue when I am back in Singapore

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.

7 participants