-
Notifications
You must be signed in to change notification settings - Fork 471
fix(vue): fix variables typing #3734
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
base: main
Are you sure you want to change the base?
Conversation
|
aceb2cc
to
d0b6106
Compare
- Revert the definitions of MaybeRefObj, UseQueryArgs, and UseSubscriptionArgs introduced in d07602d to resolve issue urql-graphql#3733 - Rename MaybeRef, MaybeRefObj, unwrap to MaybeRefOrGetter, MaybeRefOrGetterObj, and toValue for consistency with Vue 3.3+ - Replace deep unwrapping (introduced in 068df71) of variables with a simple toValue - Revert test changes introduced in 068df71 - Fix 'reacts to variables changing' test by wrapping variables in reactive() since deep unwrapping is no longer performed
Rename the variables for consistency between the doc and the implementation Add description of variable extensions
@JoviDeCroock Would you mind taking a look when you have a chance? Thank you! |
Hi @JoviDeCroock, I received on email from GitHub on January 23th with a response from you, but I can't see any in this thread, did you delete it? Just some more info (since you were concerned with the modifications to the tests): basically I reverted the test to their state before 068df71. Many of the test introduced in this commit are testing the deep unwrapping behavior, which is IMO not desirable, that's why I reverted most of it. I'm not exactly sure how to test that type safety is working, but I can see two solutions:
|
Sorry to be a bit pushy about this Issue/PR, but it's been two months and I haven't heard from anyone... Having a broken typing system seems like a major issue for a production-grade GraphQL engine... Even more since it was working before, so people might be relying on it (I did find this bug after pushing some erroneous code which would have been caught if the typing had been working as expected). I noticed other people have run into this issue too. I did my best to document the issue and propose a solution (I also raised some questions in this PR and the related issue). If that's not good enough or if you are too busy to dig into it right now, could we at least revert the changes from the faulty commit while thinking about a better solution? |
So it's been 3 months since I posted this PR and the related issue, and I haven't heard from anyone. The regression is 8 months old now and I'm losing hope to see it fixed. For those interested in having a lightweight vue-compatible graphql client with non-broken typing, I suggest moving to Villus as I did, because it does not seem to be a priority here. |
The problems here are several layers deep. We unfortunately don't use Vue or The other problem here is that this PR needs a changeset, as per the contributing guidelines and the bot comment above: https://github.com/urql-graphql/urql/blob/main/CONTRIBUTING.md#how-do-i-document-a-change-for-the-changelog The final problem here is that huge PRs like #3619 with a lot of back and forth and no context on what direction some Vue patterns have moved to cause more problems for us since it compounds the first problem. When we then have PRs that basically introduce a "apply and revert" loop where changes go beyond what's needed in the moment, it increases the surface area of what's checked and lowers my confidence in the change. Lastly, re. the typings change. We aren't yet making use of extensive typings tests in this repo, since Vitest didn't have that feature when we would've added it. We also haven't added alternatives. This meant more regressions in some patterns than we would've liked and also increases testing burden. I didn't have the time to write all of this out before, but I hope this is useful nonetheless. Anyway, happy to set aside a few hours to sort this and merge some changes resulting from this, or close this for now, and come back to this another time. Either way works 👍 |
Thank you for your reply @kitten. I totally understand that you don't have the time to review my PR, especially if you don't use Vue. Sorry if my last message sounded bitter somehow. I really like urql, so I'd really like to help fix this issue eventually. Just to be clear, I was not expecting you nor anybody else to merge my PR as is (since I explicitly left some points to be discussed). That's why I did not provide a changeset yet. Also, I regenerated the lockfile to pass one of the checks (this one might be quite hazardous). Now regarding the main issue, I tried to describe extensively the problems and possible workarounds in this PR and in the related issue, but here is a sum up:
This is mainly what the PR is about. The rest is just some renaming of utils (to be consistent with Vue current implementations) and reverting the tests that use this deep unwrapping. I'd really like to have the opinion of someone more knowledgeable about this... Maybe @yurks or @negezor if you have some time to take a look? |
Gotcha! Unfortunately, my main problem is that the ref logic is hard for me to get back into. There's a lot of edge cases, and it's on me that I didn't write them down as unit tests. That's also in part due to my lack of experience with Vue. (On a side-note, we do have some plans re. bindings that may help here, but it's an idea of how to deprecate bindings altogether, so not relevant here, and it'd be a change for the far future) For now, I don't mind merging this and totally trust you, especially if we can get one more Vue developer to take a glance at this in relation to the past issues (so in addition to #3733, #3641 addressed an edge case, #3633 relates to It's also possible new utilities related to an upgrade can help here, since it sounds like we should bump the required version anyway 🤔 |
I must confess I share some responsibility in that long chain as I did temporarily broke a functionality in #3633 😬 Also, I think the Vue bindings documentation should be updated afterwards (for example the functionality I broke was not documented -- and still isn't I think). I'd be happy to help with this too. |
I take the opportunity to mention this related (but not vue-specific) question: #3733 (comment) I may not be getting this right, but for me (and after some test), this type makes |
I'm unable to check this right now, but want to mention - deep variables unwrapping was not introduced in #3619. That PR is about fixing memory leaks with unwrapping, but this feature was in place from the point we decided to use this library, and that was about 3 years ago, so this is kind of original functionality. I'd say removing deep unwrapping is a real breaking change, which costs at least major version bump and deprecation notice. Personally, I didn't get the point of removing this, but it definitely concerns me not understanding the context. I'll try again a bit later, or kindly ask you for details why you are removing. |
Thanks for taking the time to comment! As to whether this a breaking change or not, I'm not sure, because this behavior has never been documented (to the best of my knowledge). The doc merely states:
My primary concern with My secondary concern is that it is quite a complicated and confusing mechanism, that can be simply achieved by wrapping |
Here is some expanded explanation about how you can already achieve deep unwrapping with a simple unwrapping (
you can just pass
you can use a "shallow getter" instead
Alternatively, you can use
These examples are merely there to show that you can pass deeply nested reactive variables without implementing some deep unwrapping on urql side. I do understand that in some cases you need to prepare a bit the |
Ah, I remember this better now. I believe my initial impression here was the same re. the solutions you're mentioning. My main question (as someone who hasn't used Vue since this reactivity system was first added) would be whether that's "ergonomic and established" If it's not expected for us to deeply unwrap, then we shouldn't do it. As you're saying other clients (Villus?) don't deeply unwrap, right? However, I suppose that brings us to a very simple conclusion of just a few questions:
I'm not against a breaking change, especially since a raised peer dep on The only concern here is documentation, since they're not in a great shape, and not necessarily in a changeable shape. But we can cross that bridge when we get to it Edit: I've gone through some past changes and overall I think this holds up. Removing deep unwrapping is straightforward and also what we temporarily upheld originally. Restoring it makes sense, |
Hi! I prefer an approach where we use useFetchThreadCommentsQuery({
variables: () => ({
subjectId: props.subjectId,
after: afterCursor.value,
orderBy: orderBy.value,
}),
}); I got used to this approach back in vue-apollo. However, I'm against wrapping |
@negezor Thanks for your feedback! I'll look into PR #3612 to understand the issue (and avoid a possible regression on this matter). Just to clarify: I did not mean to wrap |
Hi @arkandias, thanks for taking the time to work on this! i const sub = useSubscription({
query: `{ test }`,
}); to const sub = reactive(
useSubscription({
query: `{ test }`,
})
); and that's confusing me a little. I was under the impression that your changes were affecting variables only ? Could you clarify ? I agree with what @negezor is saying, using a That being said, I believe some of the changes here are very good and could be merged much quicker if this PR was split into multiple PRs. Like the renaming of the types to align with vue 3.3 naming. |
Hi @Hebilicious, Thanks for taking a look at this! These changes come from the fact that I reverted the tests of What about the There is also the implementation note I talked about here, if anyone's interested (I had to use a type assertion at some point). |
Summary
Background
This PR addresses issues introduced by the deep unwrapping of the
variables
field:variables
becomes extremely challenging (if not impossible)variables
(and maybe more)The proposal is to revert to simple unwrapping, along with several improvements detailed below.
Should this proposal be accepted, I'd be happy to update the documentation.
Changes
MaybeRefObj
,UseQueryArgs
, andUseSubscriptionArgs
definitions from d07602dMaybeRef
→MaybeRefOrGetter
MaybeRefObj
→MaybeRefOrGetterObj
unwrap
→toValue
variables
(introduced in 068df71) with a simpletoValue
'reacts to variables changing'
test to usereactive()
wrapper since deep unwrapping is no longer performedpnpm-lock.yaml
to use updated dependenciescreateRequest
documentationImplementation Note
In
createRequestWithArgs
, I had to use a type assertion for_args.variables
as TypeScript struggles with type inference in this case. While the typing appears correct, I welcome review of this approach. There is also a related question on theGraphQLRequestParams
definition (discussed here). Alternative suggestions for a more elegant solution are appreciated.Discussion Point: Query Field Reactivity
While this PR doesn't modify it, I question whether the
query
field should support reactivity. Creating a new query viauseQuery
or the client handle seems more appropriate. Additionally, TypeScript users wouldn't be able to replace thequery
value with a different type, which arguably makes this feature useless.Discussion Point 2: Optional Variables
As noted here, the current implementation of
MaybeRefObj
also breaks the behavior ofGraphQLRequestParams
, which makes thevariables
field optional in certain cases, for example for queries that do not require variables. In the definition ofUseQueryArgs
, the intersection with this type is wrapped in an outerMaybeRefObj
:This causes the
variables
field to be non-optional even for queries that do not require variables. The reason comes from the definition ofMaybeRefObj
and the fact that thatExact<{ [key: string]: never; }>
extends{}
.Proposed solutions
MaybeRefObj
definition:This allows omitting
variables
when not needed while maintaining type safety, but note that other edge cases may exist.UseQueryArgs
definition:This approach would resolve all the possible edge cases and improve type safety maintainability. It would also make the
query
field non-reactive, which, as I argued in the previous point, aligns with best practices.