hashgraph / hashgraph/guardian

mathBlock expression editor: "Test" freezes the browser with a ~5 MB input document

Open
#6,867 0 comments 0 reactions 1 assignee Claimed by @saharshkhicha18 View on GitHub
status: pr delivered / ready for review
Dominant language
TypeScript
Stars
146
Forks
186
Avg merge
2d 20h
Merged PRs (30d)
126

Description

### Problem description

In the policy configurator, the `mathBlock` expression editor (**Testing → Inputs → Add Input Document → File**) accepts a JSON test document and runs the expression when you press **Test**. With a large but realistic input document (~5 MB; a Project Description VC whose GeoJSON project boundary is ~3.5 MB with ~4,500 polygon rings / ~134k coordinate pairs) pressing **Test** blocks the main thread for several minutes and ends in Chrome's "Page Unresponsive" dialog or a crashed tab.

The calculation itself is not the problem: the Compute Engine evaluation of the block's variables and formulas finishes in under 300 ms, and parsing the file takes ~25 ms. The freeze happens while rendering the **Results** step, and two things compound:

1. **The result editors render every line of the document instead of the viewport.**
In `frontend/src/app/modules/policy-engine/dialogs/math-editor-dialog/math-editor-dialog.component.scss` the Input / Output / Errors editors sit in a 200 px `.output-container` (absolutely positioned, `display: flex; flex-direction: column; overflow: auto`). The `ngx-codemirror` inside it is `flex: 1` and keeps the flex default `min-height: auto`, so it grows to the height of its own content instead of being clipped. The global rule `.CodeMirror { height: 100% !important }` (`app.component.scss`) then resolves against that grown box. Measured in the live page with a 62k‑line document: the editor box was **1,024,081 px** tall, `cm.getViewport()` returned `{from: 0, to: 62065}`, and all 62,065 lines were in the DOM. CodeMirror's viewport virtualisation is fully defeated. The same page with a 643k‑line document hung for over four minutes.

2. **The Input view pretty‑prints the whole document with `JSON.stringify(doc, null, 4)`** (`math-editor-dialog.component.ts`, `onTest`). Every array element lands on its own line, so a GeoJSON coordinate list explodes: the 5 MB file becomes a **30 MB, 643,077‑line** string. Combined with (1) that is 643k DOM rows.

Measurements (Chrome, dev build):

| Document | Editor box height | Lines rendered to DOM | Main‑thread block |
|---|---|---|---|
| 62k lines, current code | 1,024,081 px | 62,065 | ~10.7 s (four long tasks) |
| 643k lines (real file), current code | n/a, tab hung | all | > 4 min, then "Page Unresponsive" |
| 562k lines, with the fix below | 198 px | 21 | ~0.5 s |

Proposed fix (verified locally, all specs under `math-editor-dialog` pass):

- `math-editor-dialog.component.scss`: add `min-height: 0; overflow: hidden;` to `.output-container ngx-codemirror`. This alone restores viewport rendering (21 rows instead of 62k / 643k).
- Replace `JSON.stringify(…, null, 4)` for the Input / Output views with a formatter that keeps arrays on one line when their inline form is short (e.g. ≤ 100 chars: numeric tables, coordinate pairs) and otherwise breaks one element per line, objects staying one key per line. Output round‑trips through `JSON.parse`; for the same file it drops to 14 MB / 241k lines.

Related, not covered by the above: the **Edit** button on a loaded input document (`add-document-dialog`) pushes the whole document into the schema form and a plain ``, and a textarea with a multi‑MB value blocks the main thread for 8–45 s by itself; and `getItemValue(item.value)` in the Results template JSON‑stringifies values on every change‑detection pass.

### Step to reproduce

1. Open a policy in the policy configurator and select a `mathBlock` with an input schema and at least one variable/formula.
2. In the block properties click the **Expression** property to open the expression editor.
3. Go to **Testing → Inputs → Add Input Document**, choose **File**, pick a ~5 MB JSON document that contains a large array (e.g. a GeoJSON `MultiPolygon` with a few hundred thousand coordinates), click **Apply**. The file loads fine.
4. Click **Test**.
5. The tab freezes; after a while Chrome shows "Page Unresponsive" or the tab crashes.

### Expected behavior

**Test** completes in well under a second regardless of the input document size. The Results step shows the Input / Output JSON in a scrollable editor that renders only the visible lines, so a multi‑MB test document is as usable as a small one.

### Screenshots

<img width="2956" height="1864" alt="Image" src="https://github.com/user-attachments/assets/2b8a918e-1efc-4d9d-b85e-40252ab4f074" />

<img width="2279" height="1256" alt="Image" src="https://github.com/user-attachments/assets/dabd6283-b533-47f9-b24d-3ba95daa6daa" />

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.