feat: add YYJSON - #47
Conversation
- Add swift-yyjson dependency for high-performance JSON encoding/decoding - Create JSONCodec enum in ExFigCore with factory and convenience methods - Add explicit CodingKeys to Variables models (YYJSON doesn't recursively apply keyDecodingStrategy to nested structures in arrays/dictionaries) - Add comprehensive tests for JSONCodec functionality WIP: FigmaAPI migration in progress - remaining models need CodingKeys Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> # Conflicts: # Package.resolved
- Add explicit CodingKeys to Variables, Node, Style, and Components models - Update BaseEndpoint to use JSONCodec.decode() - Update UpdateVariablesEndpoint to use JSONCodec.encode() - Update test fixtures and tests to use snake_case JSON keys WIP: Some tests still failing, need to update remaining test JSON to snake_case Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove CodingKeys from Node.swift (TypeStyle, Document, Effect, Paint) - Remove CodingKeys from Variables.swift (already camelCase) - Remove deprecated decodeFigma() from JSONCodec - Update all fixtures and tests to camelCase JSON Figma API uses camelCase keys (strokeWeight, blendMode, modeId), not snake_case as previously assumed. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ExportCheckpoint, BatchCheckpoint: use JSONCodec with .iso8601 date strategy - ImageTrackingCache: use JSONCodec for load/save - NodeHasher: use JSONCodec.encodeSorted() for deterministic hashing - RawExporter, Batch: use JSONCodec + YYJSONSerialization for sorted keys - PKLEvaluator: use JSONCodec.decode() for config parsing - Test helpers: use JSONCodec and camelCase JSON (matches real Figma API) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> # Conflicts: # Sources/ExFig/PKL/PKLEvaluator.swift
- All FigmaAPI tests pass (217 tests) - All batch tests pass (89 tests) - Add swift-yyjson to CLAUDE.md dependencies Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> # Conflicts: # CLAUDE.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> chore(openspec): archive add-yyjson-codec # Conflicts: # CLAUDE.md
Summary of ChangesHello @alexey1312, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request undertakes a significant refactor of the project's JSON processing infrastructure. By migrating from Foundation's default JSON coders to the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request is a significant and well-executed refactor, replacing Foundation's JSON handling with the high-performance YYJSON library. The introduction of a centralized JSONCodec is a great step towards standardizing JSON operations across the codebase. The migration appears thorough, covering application code, tests, and fixtures.
My main feedback concerns the handling of sorted keys for cache files. The sortedKeys option was dropped in a few places, which makes the cache output non-deterministic. I've suggested a fix to restore this behavior for consistency and to align with the PR's goal of deterministic output. I also found a minor discrepancy between the design documentation and the final implementation, which would be good to align.
Switch from Foundation JSON serialization to JSONCodec for performance and determinism. Add new methods for sorted and pretty-printed JSON to simplify xcasset and hashing workflows. Introduce Logging for better error diagnostics in load/serialize ops. Ensure invalid cache or encoding issues are logged, aiding debugging. Updated Xcode and NodeHasher modules to log exceptions explicitly. Updated test cases to fully cover error scenarios in JSONCodec.
When converting non-HTTP/non-URLError errors to FigmaAPIError, preserve the original error's localizedDescription in the new underlyingMessage property. This provides better debugging context for errors like JSON decoding failures. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Error.bestDescription extension that prefers CustomStringConvertible over localizedDescription for better error messages from types like YYJSONError that don't implement LocalizedError. Also update ContainingFrame to use standard JSON naming (nodeId vs nodeID) and add missing optional fields (pageId, backgroundColor).
Separate file version tracking from experimental granular node hashing. Now --cache enables file versions tracking, while node hashes are only stored when --experimental-granular-cache is also set.
Update the swift-yyjson package version from 0.3.0 to 0.3.1 in both Package.resolved and Package.swift. This update ensures we have the latest bug fixes and improvements available in the package.
Introduce a cache for parent directory contents to optimize case mismatch detection on case-insensitive file systems. The cache stores lowercase-to-URL mappings, reducing redundant directory scans. This change improves efficiency, particularly with large batches of files, by preventing multiple scans of the same parent directory, speeding up both sequential and parallel writes.
927d944 to
c89bd29
Compare
Update swift-yyjson to 0.4.0 which adds sortedKeys support to encoder. Simplify encodeSorted and encodePrettySorted by removing two-step encode-then-serialize approach. Update tests for new 2-space indent format and improved hash determinism.
c89bd29 to
3d870a8
Compare
This pull request introduces a major refactor to the project's JSON serialization and deserialization logic, replacing all usages of the Foundation
JSONEncoder/JSONDecoderwith the high-performanceYYJSONlibrary via a new centralizedJSONCodecutility. This change improves performance, ensures deterministic output where needed, and standardizes JSON handling across the codebase. Additionally, explicitCodingKeysare added to several Figma API models for robust key mapping, and the new dependency is integrated into the build system.Core Infrastructure Updates
swift-yyjsonas a dependency inPackage.swiftand updated theExFigCoretarget to use theYYJSONproduct. [1] [2]Sources/ExFigCore/JSON/JSONCodec.swift, a centralized utility for encoding and decoding JSON usingYYJSON, including support for pretty-printing and sorted keys for deterministic output.Migration to YYJSON
JSONEncoder/JSONDecoderwithJSONCodecin cache, output, and command files, ensuring consistent and performant JSON handling. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]Figma API Model Improvements
CodingKeysenums to Figma API models (Component,ContainingFrame, andStyle) to ensure correct mapping of snake_case fields from the API to Swift properties. [1] [2] [3]Codebase Integration
ExFigCoreandYYJSONwhere necessary for new JSON handling. [1] [2] [3] [4] [5] [6] [7] [8]Backward Compatibility and Output Stability
Let me know if you'd like to dive deeper into any specific part of this migration or how to use the new
JSONCodecutility!