Render script state as a nested tree, not a flat JSON blob

The State drawer stringified non-string values with JSON.stringify, so
nested objects/arrays showed as raw JSON. Add a recursive StateValue /
StateTree renderer: primitives are typed and coloured, objects/arrays are
collapsible and indented so deep state shows its structure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TEpWMjnfPqzZ13nPMoGhs5
This commit is contained in:
parththakkar106
2026-07-21 01:22:33 +05:30
co-authored by Claude Opus 4.8
parent 2953cd70ed
commit e74566c5d4
2 changed files with 55 additions and 3 deletions
+36 -3
View File
@@ -392,6 +392,41 @@ function ScriptsPanel({ advId }) {
)
}
// Renders one script-state value: primitives inline (typed/coloured), and
// objects/arrays as a collapsible, indented tree — recursing into nesting so
// deep state shows structure instead of a flat JSON blob.
function StateValue({ value }) {
if (value === null || value === undefined) return <span className="jv-null">null</span>
if (typeof value === 'boolean') return <span className="jv-bool">{String(value)}</span>
if (typeof value === 'number') return <span className="jv-number">{value}</span>
if (typeof value === 'string') return <span className="jv-string">{value}</span>
if (Array.isArray(value)) return <StateTree entries={value.map((v, i) => [i, v])} empty="[ ]" />
if (typeof value === 'object') return <StateTree entries={Object.entries(value)} empty="{ }" />
return <span className="jv-string">{String(value)}</span>
}
function StateTree({ entries, empty }) {
const [open, setOpen] = useState(true)
if (entries.length === 0) return <span className="jv-empty">{empty}</span>
return (
<div className="jv-tree">
<button className="jv-toggle" onClick={() => setOpen((o) => !o)}>
{open ? '▾' : '▸'} {entries.length} {entries.length === 1 ? 'item' : 'items'}
</button>
{open && (
<ul className="jv-children">
{entries.map(([k, v]) => (
<li key={k}>
<span className="jv-key">{k}</span>
<StateValue value={v} />
</li>
))}
</ul>
)}
</div>
)
}
// Collapsible left rail showing the scripting `state` object — every variable
// scripts read/write via state.x, refreshed after each turn.
function StatusDrawer({ advId, refreshKey }) {
@@ -433,9 +468,7 @@ function StatusDrawer({ advId, refreshKey }) {
{entries.map(([k, v]) => (
<li key={k}>
<span className="status-key">{k}</span>
<span className="status-val">
{typeof v === 'string' ? v : JSON.stringify(v, null, 2)}
</span>
<div className="status-val"><StateValue value={v} /></div>
</li>
))}
</ul>