Skip to content

Stream Visualisation #3737

Closed
of89p wants to merge 51 commits intosource-academy:masterfrom
of89p:getail
Closed

Stream Visualisation #3737
of89p wants to merge 51 commits intosource-academy:masterfrom
of89p:getail

Conversation

@of89p
Copy link
Copy Markdown

@of89p of89p commented Apr 5, 2026

Description

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

sayomaki and others added 30 commits January 24, 2026 23:58
added pair visualiser button and a private pairCreationMode boolean f…
first attempt at making it pair only
Aligned all stream and list pairs into a line in pair mode
Removed 2nd arrow from function objects in pair mode
Added an array to track all pairs that should show up in pair mode
Pair toggle fetches streamsPointSteps[] from context
Temp fix for pair creation toggle button
Added arrows that point from stream nullary fn to pair created
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' mode to the CSE Machine, enabling stream-based visualization by tracking stream lineages and adding streamsPointSteps to the workspace state. The changes involve extensive refactoring of js-slang imports and updates to the CSE Machine's layout and component logic. Feedback highlights critical issues with non-portable local file paths in package.json, an improper import from node_modules, and a potential NaN bug in layout calculations. Several suggestions were also provided to fix typos, style violations, and remove debug logs.

"java-slang": "^1.0.13",
"js-cookie": "^3.0.5",
"js-slang": "^1.0.85",
"js-slang": "file:../js-slang",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

The dependency js-slang is pointing to a local file path (file:../js-slang). This will cause build failures in CI/CD environments and for other developers who do not have the repository cloned in the same relative location. Please use a versioned package from the registry.

]
},
"resolutions": {
"js-slang": "portal:/C:/Users/triss/shared-source-academy-frontend-repo/js-slang"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

The resolutions field contains a hardcoded absolute path to a local directory (portal:/C:/Users/...). This is not portable and will break the build on any other machine. This should be removed before merging.

@@ -1,5 +1,6 @@
import { KonvaEventObject } from 'konva/lib/Node';
import { Label } from 'konva/lib/shapes/Label';
import { _isEventFromThisInstance } from 'node_modules/ag-grid-community/dist/types/src/agStack/utils/event';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

Importing directly from node_modules is highly discouraged as it relies on the internal file structure of the package, which is not part of its public API and may change. Furthermore, this specific import _isEventFromThisInstance does not appear to be used anywhere in this file and should be removed.

// streamHeights[0] is always initialised to 0, so this shouldnt ever cause
// an arrayindexexception
if (Layout.streamHeights[this.streamId] == undefined) {
Layout.streamHeights[this.streamId] = Layout.streamHeights[this.streamId - 1] + 1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

If this.streamId is greater than 0 but the previous index in Layout.streamHeights has not been initialized, Layout.streamHeights[this.streamId - 1] will be undefined. Adding 1 to undefined results in NaN, which can cause layout issues. Consider adding a nullish coalescing check.

        const prevHeight = this.streamId > 0 ? (Layout.streamHeights[this.streamId - 1] ?? 0) : 0;
        Layout.streamHeights[this.streamId] = prevHeight + 1;

Comment on lines +207 to +208
// console.log(this.streamId);
// console.log(this.data.id);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Remove commented-out debug logs to maintain code cleanliness.

Comment on lines 29 to 33
private static stash: Stash | undefined;
private static streamLineage: Map<string, string[]>;
private static streamPairIdToStreamId: Map<string, string>;
private static streamPairIdToParentCount: Map<string, number>;
public static togglePrintableMode(): void {

This comment was marked as outdated.

Comment on lines 77 to +78
this.paramsText = `params: ${getParamsText(this.data)}`;
this.bodyText = `body: ${getBodyText(this.data)}`;
this.bodyText = `id: ${(this.data as any).id}`;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The FnValue component's tooltip incorrectly displays a debug ID instead of the function's body text due to leftover temporary code.
Severity: MEDIUM

Suggested Fix

Restore the original code to display the function body in the tooltip. Replace this.bodyText = id: ${(this.data as any).id} with the commented-out line: `this.bodyText = `body: ${getBodyText(this.data)}. This will show the correct information to the user.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/features/cseMachine/components/values/FnValue.tsx#L77-L78

Potential issue: In the `FnValue` component, the function body's display text is being
set to a debug ID (e.g., `id: 42`) instead of the actual function body content. The
original code to display the function body has been commented out, and a developer
comment `// remember to delete this if its fixed` indicates this was a temporary change
for debugging. As a result, when a user hovers over a non-global function in the CSE
machine visualization, they will see an internal ID instead of the function's code,
degrading the tool's educational value.

Did we get this right? 👍 / 👎 to inform future reviews.

DaRealTristan and others added 3 commits April 5, 2026 15:55
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Comment on lines +546 to +548
Layout.streamLengthMap.clear();
Layout.streamCoords = [];
// Layout.streamHeights = [0];
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The draw() method fails to reset Layout.streamHeights because the reset line is commented out. This causes stale data to persist across redraws, leading to incorrect stream rendering.
Severity: MEDIUM

Suggested Fix

Uncomment the line Layout.streamHeights = [0]; within the draw() method in CseMachineLayout.tsx. This will ensure that all stream-related layout states are consistently reset before each redraw, preventing stale data from corrupting the new layout.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/features/cseMachine/CseMachineLayout.tsx#L546-L548

Potential issue: In the `draw()` method, `Layout.streamLengthMap` and
`Layout.streamCoords` are cleared, but the reset for `Layout.streamHeights` is commented
out. When a redraw is triggered, such as by toggling pair creation mode, `ArrayValue`
instances are recreated. However, because `streamHeights` retains stale data from the
previous render, the logic for calculating new stream heights is skipped. This results
in new streams being rendered at incorrect Y-coordinates, reusing positions from the
previous visualization session.

Comment on lines +133 to +137
originFnValue.addArrow(this);
} else {
Layout.pendingFnLink = true;
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: A race condition with the Layout.pendingFnLink flag causes deferred links between functions and arrays to be missed if multiple links are pending, resulting in an incomplete visualization.
Severity: MEDIUM

Suggested Fix

Replace the single boolean flag Layout.pendingFnLink with a queue-based system. When an ArrayValue needs to defer linking, it should add its ID or the required function ID to a queue. The FnValue constructor should then process all relevant items from this queue instead of relying on a single flag.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/features/cseMachine/components/values/ArrayValue.tsx#L133-L137

Potential issue: A race condition exists due to the use of a single boolean flag,
`Layout.pendingFnLink`, to manage deferred linking between functions and arrays. If
multiple `ArrayValue` instances are created before their corresponding `FnValue`s, each
will set `Layout.pendingFnLink` to true. However, when the first `FnValue` is created,
it processes its links and then resets the flag to false. Subsequent `FnValue`s will see
the flag as false and skip their linking process, resulting in missing stream arrows in
the visualization.

@martin-henz martin-henz marked this pull request as draft April 6, 2026 04:00
@martin-henz
Copy link
Copy Markdown
Member

Superseded by #3747

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.

5 participants