Open rbalicki2 opened 1 month ago
/assign :)
... comment moved to description ...
Okay I'm down to try, would I encounter difficulties or be unavailable to continue working on the issue I'll make sure to keep you updated! Looking forward to contributing though!
If you choose to take this task on, we should hop on a call to hammer out all the details. It seems like a lot of work, but in practice it's not — as long as you know where to make the changes. (Hence the need for a call.)
The impact of this is high, it merges an unnecessary building block (refetch/exposed mutation fields) into another abstraction:
@loadable
fields (which is the one we want to go with in the long term)This is a relatively thin outline:
Background
loadable fields
UserDetail
selectsfull_name
), the initial parameter toUserDetail
will include the result of callingfull_name
(or a renderable react component, if it was an@component
client field.)@loadable
to any client field. (Ideally, we would allow that on any field eventually!)full_name @loadable
, you would instead receive something that contains a function that, when called, will make a network request for the data needed byfull_name
. This returns a fragment reference, which you can pass touseResult
to get the value back (or suspend, if the query is in flight.)__refetch and re-exposed fields
__refetch
fields are similar, in that they're almost like fields that are always selected loadably. But, that function that makes the network request returns void instead of a FragmentReference.(/* refetch has no param, the other one does */) => [string, () => void]
, whereas a LoadableField is(argsOrVoid) => [string, () => FragmentReference<ReadOutType>]
Steps
There are (at least!) four main tasks here, all of which should happen in separate PRs. 1-3 will land as a single commit, 4 can land separately:
Step 1: Enforce
@loadable
The compiler should emit an error if we don't select the
__refetch
and exposed mutation fields loadably.This is a pure Rust change.
Step 2: modify the generated types
@loadable
to__refetch
inPetUpdated
results in__refetch: LoadableField<void, Pet____refetch__output_type>,
in isograph/demos/pet-demo/src/components/__isograph/Pet/PetUpdater/param_type.ts. This behavior is correct!export type Pet____refetch__output_type = () => [string, () => void];
to beexport type Pet____refetch__output_type = void
in isograph/demos/pet-demo/src/components/isograph/Pet/refetch/output_type.ts.Step 3: Implementation of the refetch field
Right now, the __refetch field's inner function returns
void
. It should return aFragmentReference<void>
.Refetch fields and exposed mutation fields (at least for now) have nothing that you actually want to read as a result of calling them. But, you might want to suspend if the network request is in flight, get a loading indicator, etc. and the mechanism for that is to return a FragmentReference
Step 4: Unify some APIs
useImperativeExposedMutationField
is now useless, and it can be replaced withuseImperativeLoadableField
! Woohoo!The user can also call
useClientSideDefer
with refetch fields (maybe we should lint against that, that's likely to be a mistake?) and with mutations (which does make sense!)