feat: add TypeNode fingerprinting to dedupe more effectively#46
feat: add TypeNode fingerprinting to dedupe more effectively#46
Conversation
Used to derive singular type names from plural array field names (e.g., "posts" -> "post", "categories" -> "category").
Introduces structural fingerprinting for groq-js TypeNodes to identify duplicate object types across queries. Object types appearing 2+ times are candidates for extraction into named type aliases. Naming priority: _type attribute > parent field name > InlineType fallback. All extracted types are prefixed with "Inline" (e.g., InlineAuthor). Types with fewer than 2 non-structural attributes are skipped. Fingerprints are cached in a WeakMap to avoid recomputation.
Splits type generation into a 3-phase pipeline: 1. Collect TypeNodes from all queries 2. Build deduplication registry by fingerprinting object types 3. Generate TS types, replacing duplicates with references Duplicate object types appearing across queries are extracted into shared "Inline"-prefixed type aliases, reducing generated code size and improving readability.
b7bf883 to
c00b552
Compare
sgulseth
left a comment
There was a problem hiding this comment.
Tests! There's no unit tests that asserts the behavior, it's a bit hard to review without knowing what's expected.
Also this is only deduping types that are exactly the same? 🤔
| @@ -0,0 +1,18 @@ | |||
| export function singularize(name: string): string { | |||
There was a problem hiding this comment.
This one seems like a potential foot gun, why do we need to rewrite the names?
There was a problem hiding this comment.
A very common case is for the field to be named plural, but since we evaluate and hoist the type inside the array the following field:
authors: Array<{ /* author type */ }>..if used in multiple places would end up as
type InlineAuthors = { /* author type */ }
authors: Array<InlineAuthors>I find having a plural names for singluar things confusing.
🫡 More tests added now. Will have a look at exporting |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
0014b8b to
5fa7a7c
Compare
5fa7a7c to
34fe055
Compare

TL;DR
Added type deduplication for GROQ query type generation to reduce output file size and improve readability.
What changed?
hashTypeNodefrom groq-js for identifying identical type nodesInline*type aliases🚫 This PR depends on changes that hasn't yet landed in
groq-js, so it's blocked by the release of a new version with thehashTypeNodefunction exported. Until the PR has been merged this PR is using a tagged version ofgroq-jswhere this is available. So this is ready for review, not merge.Why make this change?
Generated type files can be pretty large and difficult to read due to repeated type structures across different queries. For example, author and image types that appear in multiple queries were being duplicated in full. This change significantly reduces duplication by extracting common structures into named types, making the generated files easier to read and improving IDE performance when working with these types.
How to test?
Inline*type aliases at the topAutomated tests has been added, and outdated snapshots updated.