Repository navigation
view: fix the must-fix findings of the #2057 review - #2059
Merged
Merged
Conversation
The language server projected a view model on every analysis and the browser engine on every prepareProject, the playground's included, though only a view reads it; the projection also rebuilt a file's line index per declaration, quadratic in the file (4,000 declarations: +0.9 s per analysis in release). Analysis now projects only for a client that declares experimental.graphcal.viewModelChanges (ViewModelDemand), the engine only through the new prepareViewProject, which web/view uses, and a prepared project without a view says so instead of "has no view". Each file's line index is built once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…answer The webview keeps each source copy by project and revision, sends both with an edit, and takes the edit into its copy only once the extension answers that it applied it; a refused edit leaves the copy as it was and shows why. Two projects' `src/main.gcl` no longer share one copy. Pairs with vscode-graphcal's address-reviews branch, whose extension checks the revision against the document before applying an edit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The projection took every source module of the root file as local, the inline dag templates included: their params and nodes became valueless root nodes whose leaf-name ids collided with the root's own (two dags' `out`, or a root `out` beside a template's), so the sheet's id-keyed maps dropped one and wired readers to the wrong declaration. Only the root DAG is local now; a template is read through its instances, which the view already shows as externals. The projection checks that every node id is unique and every dependency names a node, and fails instead of returning a model the view would miswire. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The diff dropped each line's newline and put one "\ No newline at end of file" after the last hunk, whichever line it belonged to. git applies that marker to the line before it, so an edit far from a file's newline-less end joined two lines (`param p4: …;param p5: …;`), and a changed last line, or a change of the final newline alone, gave a patch git rejects. Lines now keep their newline when compared, so `b` and `b\n` differ, and the marker follows each newline-less line on its own side; an empty side's hunk starts at line 0. Tests round-trip patches through git apply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A cell edit took the declaration's table to run from its line to the first later line holding only `}`. After a table closed on one line, that was the next declaration's table: editing `a[x]` rewrote `b`'s `x`, which compiled, so the edit was accepted, entered the copied patch, and in VS Code reached the document. The edit now searches only the rows strictly inside the compiler's range of the expression, which must begin with `table[`; a table on one line, or one shared by several declarations (its axes name a slot tuple), is refused rather than guessed at. A stopgap: the compiler is to report each cell's range. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A cell rounded the magnitude to four significant digits and then printed at most six decimals, so anything under 1e-6 became 0 (4.7e-9 → 0, -3e-8 → -0) and a value near 1e-6 lost its digits; large values printed in full (1e308 as 309 digits). Below 1e-3 and from 1e6 the four digits take an exponent instead. Editing still starts from the full magnitude. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pinned include pane showed its module evaluated alone, though the
include passes arguments: `include lib(gain: 2.0) as p` read `p::out = 2`
while the pane "lib.gcl as p" showed `out = 1`, wired to that 2 as its
producer.
The view model's `instance` is now `{ name, bound }`, bound when the
include binds a param or a Static parameter. A bound include cannot be
pinned yet (its menu entry says so), and no cross wire joins a bound
include's value to a pane. A stopgap until the view can project an
instance with its arguments.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An edit re-projected only the modules on screen; every other module kept its model from before the edit, and opening or pinning it later showed those values (b = 1 after a, which b reads, became 3), with declarations, axes and source ranges as old as the values. The host's models now live in a ModelCache that marks every model the edit did not re-project as stale and never returns a stale one as current. Asking for, opening or pinning a stale module projects it again from the current sources first; a reset makes the models as read current again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 14, 2026
This was referenced Oct 14, 2026
shunichironomura
added this pull request to stack #2092
October 15, 2026 01:13
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.
Warning
This content was written by an AI agent and must be verified by a human developer. After human verification, this alert may be removed.
Summary
Stacked on #2057 (
feature-ui), which should merge first.This PR fixes the review findings that block #2057: one regression in the core and six critical view bugs, one commit each. Because the view is experimental, the review triaged its findings by impact:
The fixes:
prepareProject, including the playground's. The projection was also quadratic: it added 0.9 s per analysis at 4,000 declarations in a release build.experimental.graphcal.viewModelChanges.prepareViewProject, which web/view uses.dagdeclarations stay out of the sheet. Template declarations had become root nodes whose ids collided with the root's own declarations, so the sheet wired readers to the wrong node. Only the root DAG is local now, and the projection rejects duplicate ids and dangling dependencies.\ No newline at end of filecorrectly. The marker was emitted once, after the last hunk.git applythen either joined two lines or rejected the patch. The tests round-trip patches throughgit apply.0in a cell. Values below 1e-6 rendered as0or-0. Very small and very large magnitudes now use an exponent.instanceis now{ name, bound }. A bound include cannot be pinned yet and gets no cross wires; this is also a stopgap.ModelCachemarks them stale and re-projects them before they are opened, pinned or requested.Also on this branch is a commit from another session: "web/view: VS Code edits name their copy and wait for the extension's answer". It pairs with vscode-graphcal's
address-reviewsbranch.Wire format: the view model's node
instancechanged from a string to{ name, bound }.versionstays at 0, since the view is experimental.Known limitation, unchanged by this PR: the outputs of inline DAG calls (
@dag(args)::out) appear in no node'sdeps. The graph IR has no call instances, andgraphcal graphshares this gap.Checks:
cargo testfor the graphcal-project, graphcal-lsp and graphcal-wasm libraries, andcargo test -p graphcal --test view.clippy(all features and no default features) andcargo docfor the changed crates.cargo fmt --checkandjust reading-order.vp checkandvp testin web/view.just hawk: the local cargo-hawk does not match the pinned toolchain. CI's public-surface job covers it.AI assistance
Breaking changes
breaking changelabel is applied