Skip to content

Commit

Permalink
fix: Add tail recursion where it's possible but missing (#51)
Browse files Browse the repository at this point in the history
Co-authored-by: deathemperor <deathemperor@gmail.com>
Co-authored-by: HaiNNT <HaiNNT1302@gmail.com>
  • Loading branch information
3 people committed Feb 3, 2024
1 parent 4dc30de commit cdd6370
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 67 deletions.
5 changes: 5 additions & 0 deletions .changeset/short-teachers-begin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'gql.tada': patch
---

Improve performance of several smaller types (Thank you, [@deathemperor](https://github.com/deathemperor) & [@HaiNNT](https://github.com/HaiNNT))
84 changes: 46 additions & 38 deletions src/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,45 +134,53 @@ type _getPossibleTypeSelectionRec<
Type extends ObjectLikeType,
Introspection extends IntrospectionLikeType,
Fragments extends { [name: string]: any },
SelectionAcc = {},
> = Selections extends [infer Node, ...infer Rest]
? (Node extends { kind: Kind.FRAGMENT_SPREAD | Kind.INLINE_FRAGMENT }
? getSpreadSubtype<Node, Type, Introspection, Fragments> extends infer Subtype extends
ObjectLikeType
? PossibleType extends getTypenameOfType<Subtype>
?
| (isOptional<Node> extends true ? {} : never)
| getFragmentSelection<Node, Subtype, Introspection, Fragments>
: {}
: Node extends { kind: Kind.FRAGMENT_SPREAD; name: any }
? makeUndefinedFragmentRef<Node['name']['value']>
: {}
: Node extends { kind: Kind.FIELD; name: any; selectionSet: any }
? isOptional<Node> extends true
? {
[Prop in getFieldAlias<Node>]?: Node['name']['value'] extends '__typename'
? PossibleType
: unwrapType<
Type['fields'][Node['name']['value']]['type'],
Node['selectionSet'],
Introspection,
Fragments,
getTypeDirective<Node>
>;
}
: {
[Prop in getFieldAlias<Node>]: Node['name']['value'] extends '__typename'
? PossibleType
: unwrapType<
Type['fields'][Node['name']['value']]['type'],
Node['selectionSet'],
Introspection,
Fragments,
getTypeDirective<Node>
>;
}
: {}) &
_getPossibleTypeSelectionRec<Rest, PossibleType, Type, Introspection, Fragments>
: {};
? _getPossibleTypeSelectionRec<
Rest,
PossibleType,
Type,
Introspection,
Fragments,
(Node extends { kind: Kind.FRAGMENT_SPREAD | Kind.INLINE_FRAGMENT }
? getSpreadSubtype<Node, Type, Introspection, Fragments> extends infer Subtype extends
ObjectLikeType
? PossibleType extends getTypenameOfType<Subtype>
?
| (isOptional<Node> extends true ? {} : never)
| getFragmentSelection<Node, Subtype, Introspection, Fragments>
: {}
: Node extends { kind: Kind.FRAGMENT_SPREAD; name: any }
? makeUndefinedFragmentRef<Node['name']['value']>
: {}
: Node extends { kind: Kind.FIELD; name: any; selectionSet: any }
? isOptional<Node> extends true
? {
[Prop in getFieldAlias<Node>]?: Node['name']['value'] extends '__typename'
? PossibleType
: unwrapType<
Type['fields'][Node['name']['value']]['type'],
Node['selectionSet'],
Introspection,
Fragments,
getTypeDirective<Node>
>;
}
: {
[Prop in getFieldAlias<Node>]: Node['name']['value'] extends '__typename'
? PossibleType
: unwrapType<
Type['fields'][Node['name']['value']]['type'],
Node['selectionSet'],
Introspection,
Fragments,
getTypeDirective<Node>
>;
}
: {}) &
SelectionAcc
>
: SelectionAcc;

type getOperationSelectionType<
Definition,
Expand Down
68 changes: 39 additions & 29 deletions src/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ import type { obj } from './utils';
type getInputObjectTypeRec<
InputFields,
Introspection extends IntrospectionLikeType,
InputObject = {},
> = InputFields extends [infer InputField, ...infer Rest]
? (InputField extends { name: any; type: any }
? InputField['type'] extends { kind: 'NON_NULL' }
? { [Name in InputField['name']]: unwrapType<InputField['type'], Introspection> }
: { [Name in InputField['name']]?: unwrapType<InputField['type'], Introspection> }
: {}) &
getInputObjectTypeRec<Rest, Introspection>
: {};
? getInputObjectTypeRec<
Rest,
Introspection,
(InputField extends { name: any; type: any }
? InputField['type'] extends { kind: 'NON_NULL' }
? { [Name in InputField['name']]: unwrapType<InputField['type'], Introspection> }
: { [Name in InputField['name']]?: unwrapType<InputField['type'], Introspection> }
: {}) &
InputObject
>
: InputObject;

type getScalarType<
TypeName,
Expand Down Expand Up @@ -62,27 +67,32 @@ type unwrapTypeRef<Type, Introspection extends IntrospectionLikeType> = Type ext
? _unwrapTypeRefRec<Type['type'], Introspection>
: null | _unwrapTypeRefRec<Type, Introspection>;

type getVariablesRec<Variables, Introspection extends IntrospectionLikeType> = Variables extends [
infer Variable,
...infer Rest,
]
? (Variable extends { kind: Kind.VARIABLE_DEFINITION; variable: any; type: any }
? Variable extends { defaultValue: undefined; type: { kind: Kind.NON_NULL_TYPE } }
? {
[Name in Variable['variable']['name']['value']]: unwrapTypeRef<
Variable['type'],
Introspection
>;
}
: {
[Name in Variable['variable']['name']['value']]?: unwrapTypeRef<
Variable['type'],
Introspection
>;
}
: {}) &
getVariablesRec<Rest, Introspection>
: {};
type _getVariablesRec<
Variables,
Introspection extends IntrospectionLikeType,
VariablesObject = {},
> = Variables extends [infer Variable, ...infer Rest]
? _getVariablesRec<
Rest,
Introspection,
(Variable extends { kind: Kind.VARIABLE_DEFINITION; variable: any; type: any }
? Variable extends { defaultValue: undefined; type: { kind: Kind.NON_NULL_TYPE } }
? {
[Name in Variable['variable']['name']['value']]: unwrapTypeRef<
Variable['type'],
Introspection
>;
}
: {
[Name in Variable['variable']['name']['value']]?: unwrapTypeRef<
Variable['type'],
Introspection
>;
}
: {}) &
VariablesObject
>
: VariablesObject;

type getVariablesType<
Document extends DocumentNodeLike,
Expand All @@ -91,7 +101,7 @@ type getVariablesType<
kind: Kind.OPERATION_DEFINITION;
variableDefinitions: any;
}
? obj<getVariablesRec<Document['definitions'][0]['variableDefinitions'], Introspection>>
? obj<_getVariablesRec<Document['definitions'][0]['variableDefinitions'], Introspection>>
: {};

export type { getVariablesType };

0 comments on commit cdd6370

Please sign in to comment.