Skip to content

fix STF Vector JSON serialization circular reference#82

Merged
tomusdrw merged 1 commit intomainfrom
td-stf-circular-json
Apr 17, 2026
Merged

fix STF Vector JSON serialization circular reference#82
tomusdrw merged 1 commit intomainfrom
td-stf-circular-json

Conversation

@tomusdrw
Copy link
Copy Markdown
Member

Summary

  • Loading the STF Vector example in the codec UI threw TypeError: Converting circular structure to JSON --> property 'View' closes the circle.
  • Root cause: StateTransition.Codec decodes its block field using Block.Codec.View, so the decoded object's block is an ObjectView. ObjectView holds Descriptor references, and Descriptor.View defaults to this when there's no dedicated view — a self-loop that JSON.stringify walks into.
  • Fix: in the JSON.stringify replacer in Codec.tsx, detect codec.ObjectView / codec.SequenceView and materialize them to plain values before serialization.

Test plan

  • npm run test — 154 passed, including the new regression test src/test/stf-vector-json.test.ts which encodes/decodes the STF Vector example and asserts it is JSON-serializable for both chain specs.
  • npm run qa clean.
  • npm run build clean.
  • Manual: open the codec UI, select STF Vector, click Example STF Vector — JSON pane renders without error.

🤖 Generated with Claude Code

StateTransition.Codec decodes `block` as a `Block.Codec.View`, which
holds Descriptor references whose `View` property self-loops. Walking
it with JSON.stringify threw "Converting circular structure to JSON".

Materialize ObjectView/SequenceView values in the replacer so they
serialize as plain objects.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 17, 2026

📝 Walkthrough

Walkthrough

Extended JSON serialization logic in the Codec page to materialize codec.ObjectView and codec.SequenceView instances before JSON stringification. Added a regression test to verify decoded STF Vector values can be JSON-stringified successfully.

Changes

Cohort / File(s) Summary
Codec JSON Serialization Logic
src/pages/Codec.tsx
Extended byte-to-JSON decoding to detect and materialize codec view types (codec.ObjectView via materialize() and codec.SequenceView via map(...materialize())). Existing value conversions for BytesBlob, Bytes, Map, and bigint remain unchanged.
JSON Serialization Tests
src/test/stf-vector-json.test.ts
Added regression test verifying decoded STF Vector values can be JSON-stringified. Test defines a custom replacer to materialize codec views, convert bytes/Map types, and serialize bigint values. Validates encoding/decoding/stringification cycle for all chain spec examples.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix STF Vector JSON serialization circular reference' accurately and specifically describes the main fix in the changeset, matching the core purpose of the PR.
Description check ✅ Passed The description is comprehensive, clearly related to the changeset, and explains the symptom, root cause, fix, and test plan for the circular reference issue.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch td-stf-circular-json

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

@netlify
Copy link
Copy Markdown

netlify bot commented Apr 17, 2026

Deploy Preview for fluffy-codec ready!

Name Link
🔨 Latest commit 7befd29
🔍 Latest deploy log https://app.netlify.com/projects/fluffy-codec/deploys/69e1f9689c68bf0008f89959
😎 Deploy Preview https://deploy-preview-82--fluffy-codec.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

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.

🧹 Nitpick comments (1)
src/pages/Codec.tsx (1)

73-95: Extract the JSON replacer into a shared helper to avoid drift.

The replacer logic is duplicated here and in src/test/stf-vector-json.test.ts (Line 7-27). Centralizing it will keep production and regression behavior in sync.

♻️ Suggested refactor (shared helper)
+// src/lib/codecJsonReplacer.ts
+import * as bytes from "@typeberry/lib/bytes";
+import * as codec from "@typeberry/lib/codec";
+
+export const codecJsonReplacer = (_key: string, value: unknown) => {
+  if (value instanceof codec.ObjectView) return value.materialize();
+  if (value instanceof codec.SequenceView) return value.map((v) => v.materialize());
+  if (value instanceof bytes.BytesBlob) return value.toString();
+  if (value instanceof bytes.Bytes) return value.toString();
+  if (value instanceof Map) return Object.fromEntries(value.entries());
+  if (typeof value === "bigint") return value.toString();
+  return value;
+};
-const json = JSON.stringify(
-  decoded,
-  (_key, value) => {
-    ...
-  },
-  2,
-);
+import { codecJsonReplacer } from "../lib/codecJsonReplacer";
+const json = JSON.stringify(decoded, codecJsonReplacer, 2);
-const replacer = (_key: string, value: unknown) => {
-  ...
-};
+import { codecJsonReplacer } from "../lib/codecJsonReplacer";
...
-expect(() => JSON.stringify(decoded, replacer, 2)).not.toThrow();
+expect(() => JSON.stringify(decoded, codecJsonReplacer, 2)).not.toThrow();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/Codec.tsx` around lines 73 - 95, The JSON.stringify replacer used
in src/pages/Codec.tsx duplicates logic found in
src/test/stf-vector-json.test.ts; extract that logic into a shared helper (e.g.,
export a function named createMaterializeReplacer or materializeJsonReplacer)
that handles codec.ObjectView, codec.SequenceView, bytes.BytesBlob, bytes.Bytes,
Map, and bigint conversions, then replace the inline replacer in Codec.tsx with
a call to that helper and update the test to import and reuse the same helper to
keep production and regression behavior in sync.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/pages/Codec.tsx`:
- Around line 73-95: The JSON.stringify replacer used in src/pages/Codec.tsx
duplicates logic found in src/test/stf-vector-json.test.ts; extract that logic
into a shared helper (e.g., export a function named createMaterializeReplacer or
materializeJsonReplacer) that handles codec.ObjectView, codec.SequenceView,
bytes.BytesBlob, bytes.Bytes, Map, and bigint conversions, then replace the
inline replacer in Codec.tsx with a call to that helper and update the test to
import and reuse the same helper to keep production and regression behavior in
sync.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bfde2340-7d27-4e9d-9a44-343b53efc0dd

📥 Commits

Reviewing files that changed from the base of the PR and between 92e886b and 7befd29.

📒 Files selected for processing (2)
  • src/pages/Codec.tsx
  • src/test/stf-vector-json.test.ts

@tomusdrw tomusdrw merged commit 1ba7bb7 into main Apr 17, 2026
6 checks passed
@tomusdrw tomusdrw deleted the td-stf-circular-json branch April 17, 2026 09:19
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.

1 participant