Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add tail recursion where it's possible but missing #51

Merged
merged 4 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 };
Loading