feat: implement render engine with resolution decay (#39) #41
Reference in New Issue
Block a user
Delete Branch "fix/39-render-resolution-decay"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Implements Phase 3 render engine for json-cas nodes with resolution-based decay and default YAML rendering.
Why
Issue #39 requested a rendering mechanism where:
Changes
Core Implementation (packages/json-cas)
render.ts (221 lines): Core render engine with resolution decay model
render(): Main API withRenderOptionsrenderNode(): Recursive node traversal with cycle detectionrenderValue(): Type-specific value renderingtoYamlString(): YAML escaping and formattingFLOAT_TOLERANCE = 1e-10)render.test.ts (935 lines): Comprehensive test suite
cas_refdetection)CLI Integration (packages/cli-json-cas)
index.ts: New
ucas render <hash>command--resolution,--decay,--epsiloncli.test.ts: 3 CLI integration tests
Exports
packages/json-cas/src/index.tsto export render APIKey Features
resolution = parent × decaycas:<hash>whenresolution ≤ epsiloncas:<hash>referencesschema.refs()forcas_refdetectionTest Results
Ref
Fixes #39
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Review: Phase 3 — Render Core Engine
Reviewer: 小橘 🍊(NEKO Team)
✅ Verdict: APPROVED
Clean, well-structured implementation of the resolution decay render model. All 38 tests pass, biome lint clean, TypeScript builds without errors.
Strengths
childResolution = currentResolution * decayapplied at each level, with epsilon cutoff renderingcas:<hash>references. Float tolerance (1e-10) handles boundary cases properly.refs()to identifycas_reffields, correctly handlesanyOfnullable references, arrays of refs, and non-ref strings.visited.delete(hash)after rendering allows shared nodes to be expanded in multiple branches while still preventing infinite loops on cycles.import type,.jsextensions, named exports, kebab-case files, 2-space indent, re-exported fromindex.ts.Minor Observations (Non-blocking)
visitedguard is defensive. Consider noting this in a code comment.RenderOptions.resolutiontype comment says(0, 1]but validation allows[0, 1]— resolution=0 is valid and forces reference output. The comment could be updated to[0, 1].Ship it! 🚀