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

add NormalizationAstLoader #271

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

PatrykWalach
Copy link
Collaborator

@PatrykWalach PatrykWalach commented Nov 13, 2024

#297 should be merged first

Part of #33, #43

rbalicki2 pushed a commit that referenced this pull request Dec 28, 2024
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<
Copy link
Collaborator Author

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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔

Copy link
Collaborator

@rbalicki2 rbalicki2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

partial review

libs/isograph-react/src/core/check.ts Show resolved Hide resolved
artifact.networkRequestInfo.normalizationAst.kind ===
'NormalizationAstLoader'
) {
throw new Error(
Copy link
Collaborator

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

Copy link
Collaborator

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;
};

Copy link
Collaborator

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>;
} {

Copy link
Collaborator Author

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.

Copy link
Collaborator

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

Copy link
Collaborator

@rbalicki2 rbalicki2 Dec 29, 2024

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

Copy link
Collaborator

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

Copy link
Collaborator

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<
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔

Copy link
Collaborator

@rbalicki2 rbalicki2 left a 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<
Copy link
Collaborator

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,
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants