-
Notifications
You must be signed in to change notification settings - Fork 17
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
add NormalizationAstLoader
#271
base: main
Are you sure you want to change the base?
add NormalizationAstLoader
#271
Conversation
…tionAst` is not loaded
This converts NormalizationAst from NormalizationAstNode[] to object with kind: "NormalizationAst" so we can make it a union of NormalizationAstLoader and NormalizationAst in #271
fetchOptions?: FetchOptions<TClientFieldValue>, | ||
): { | ||
fragmentReference: FragmentReference<TReadFromStore, TClientFieldValue>; | ||
}; | ||
export function useLazyReference< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overloading makes an ugly error message if ast is lazy loaded then for useLazyReference(entrypoint, {})
the error will be NormalizationAstLoader
is not assignable to NormalizationAst
, instead of missing argument error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
partial review
artifact.networkRequestInfo.normalizationAst.kind === | ||
'NormalizationAstLoader' | ||
) { | ||
throw new Error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love that if we have an entrypoint with an AST loader, we prevent IfNecessary
at the type level for useLazyReference
, can we do the same here?
That being said, (eventually?) you should be able to turn an Entrypoint<..., NormalizationAstLoader>
into a Promise<Entrypoint<..., NormalizationAst>>
and then load that second entrypoint with IfNecessary
, if you choose to. So, you should be able to (with some extra work, and by being explicit about it) achieve what you're erroring out on
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get pretty good (?) type errors with
export type FetchOptions<
TReadOutData,
NormalizationAstLoaded extends boolean,
> = {
onComplete?: (data: TReadOutData) => void;
onError?: () => void;
} & (NormalizationAstLoaded extends true
? {
shouldFetch?: ShouldFetch;
}
: {
shouldFetch: RequiredShouldFetch;
});
export type IsographEntrypoint<
TReadFromStore extends { parameters: object; data: object },
TClientFieldValue,
NormalizationAstLoaded extends boolean,
> = {
readonly kind: 'Entrypoint';
readonly networkRequestInfo: NetworkRequestInfo<
NormalizationAstLoaded extends true
? NormalizationAst
: NormalizationAstLoader
>;
readonly readerWithRefetchQueries: ReaderWithRefetchQueries<
TReadFromStore,
TClientFieldValue
>;
readonly concreteType: TypeName;
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Along with (with no overloads)
export function useLazyReference<
TReadFromStore extends { parameters: object; data: object },
TClientFieldValue,
NormalizationAstLoaded extends boolean,
>(
entrypoint: IsographEntrypoint<
TReadFromStore,
TClientFieldValue,
NormalizationAstLoaded
>,
variables: ExtractParameters<TReadFromStore>,
fetchOptions?: FetchOptions<TClientFieldValue, NormalizationAstLoaded>,
): {
fragmentReference: FragmentReference<TReadFromStore, TClientFieldValue>;
} {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But then the third argument is optional so you only get an error if you provide the third argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I guess we do need the overload then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I can't obviously see a way to improve upon your approach. Maybe we might have cleaner type errors if we have two separate type names IsographEntrypoint
and IsographEntrypointWithNormalizationAstLoader
, but anyway, that is something we can play with after getting the functionality landed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, I'm going back and forth. I do think it is nicer to have everything parametrized by a boolean (which could be "NormalizedAstPresent" | "AsyncNormalizationAst" or something for more clarity), even though we have to keep the overloads
I'm also not opposed to making the third arg not optional, as silly as it would look
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check out this ts playground by lenz
I haven't (yet) looked super closely into it, but perhaps we can improve on the error messages using some of the techniques there
fetchOptions?: FetchOptions<TClientFieldValue>, | ||
): { | ||
fragmentReference: FragmentReference<TReadFromStore, TClientFieldValue>; | ||
}; | ||
export function useLazyReference< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a nit plus something to investigate
I'll look at that as IsographEntrypoint
thing as well, and this should be good to land
@@ -503,7 +504,11 @@ function readData<TReadFromStore>( | |||
const [networkRequest, disposeNetworkRequest] = | |||
maybeMakeNetworkRequest( | |||
environment, | |||
entrypoint, | |||
entrypoint as IsographEntrypoint< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM overall. It might make sense to try to avoid this by not having IsographEntrypoint<T1, T2>
but having IsographEntrypoint<T1, T2, NormalizationAst>
in various places, or changing the type of maybeMakeNetworkRequest
.
I don't know if that's possible.
@@ -25,7 +25,7 @@ export type NetworkRequestInfo<TNormalizationAst> = { | |||
export type IsographEntrypoint< | |||
TReadFromStore extends { parameters: object; data: object }, | |||
TClientFieldValue, | |||
TNormalizationAst = NormalizationAst, | |||
TNormalizationAst = NormalizationAst | NormalizationAstLoader, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TNormalizationAst extends NormalizationAst | NormalizationAstLoader = NormalizationAst | NormalizationAstLoader
This way you can't instantiate this with anything unrelated
#297 should be merged first
Part of #33, #43