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

Implement FieldMerge and FieldMergeFunction #144

Merged
merged 2 commits into from
Apr 20, 2022
Merged

Implement FieldMerge and FieldMergeFunction #144

merged 2 commits into from
Apr 20, 2022

Conversation

dfalling
Copy link
Contributor

I feel like this is pretty close. Something's wrong with the @unboxed though:

  open ApolloClient
  make(
    ~cache=Cache.InMemoryCache.make(
      ~typePolicies=[
        (
          "Trip",
          Cache.InMemoryCache.TypePolicy.make(
            ~fields=[
              (
                "elements",
                FieldPolicy({
                  merge: Some(MergeFunction(incomingMerge)),
                  read: None,
                  keyArgs: None,
                }),
              ),
            ],
            (),
          ),
        ),

Compiles to

ApolloClient.make(undefined, undefined, undefined, Caml_option.some(httpLink), ApolloClient__Cache_InMemory_InMemoryCache.make(undefined, undefined, undefined, undefined, [
          [
            "Trip",
            ApolloClient__Cache_InMemory_Policies.TypePolicy.make([[
                    "elements",
                    {
                      TAG: /* FieldPolicy */3,
                      _0: {
                        keyArgs: undefined,
                        read: undefined,
                        merge: /* MergeFunction */{
                          _0: incomingMerge
                        }
                      }
                    }
                  ]], undefined, undefined, undefined, undefined, undefined)
          ]

How can I get rid of that extra merge: { _0: incomingMerge }?

Comment on lines -7 to -13
module FieldMergeFunction = {
module Js_ = {
type t
}
type t = Js_.t
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had to move this type further down in the module to share the FieldFunctionOptions.t type.

@jeddeloh
Copy link
Owner

I'd have to look close at the typescript types, but on first glance this looks great.

How can I get rid of that extra merge: { _0: incomingMerge }?

As long as you're keeping with the style of the rest of the library you can't. This is the cost of (what I considered at the time) a better API. So we can do stuff like merge: MergeFunction(someFn) vs. merge: FieldMerge.mergeFunction(someFn). My opinion was that the configuration of this stuff was never going to be a performance issue and it was so much more ergonomic and clear to use a variant instead of hunting down constructor functions. In other words, if we dropped the variants entirely and went with the unboxed stuff directly we'd get what you expect.

@dfalling
Copy link
Contributor Author

dfalling commented Apr 19, 2022

Unfortunately that nesting breaks the feature. Apollo doesn't recognize the merge function and nothing happens. I need a way for the function to be assigned directly, without the _0.

My understanding of @unboxed is that it's supposed to do that.

@jeddeloh
Copy link
Owner

I think the unboxed portion is working fine. The _0 is unwrapped when passed to the FieldMerge.toJs here.

I think that the actual issue is that line 124 needs to be typed as a Js_.t

- let mergeFunction = (v: FieldMergeFunction.t<'existing>) => Any(v)
+ let mergeFunction = (v: FieldMergeFunction.Js_.t<'existing>) => Any(v)

That will then force you to call FieldMergFunction.toJs on 133

@dfalling
Copy link
Contributor Author

I think that the actual issue is that line 124 needs to be typed as a Js_.t

Aah, ok. I fixed those references, but still am seeing the _0. I've cleaned the package and my entire codebase so I don't think it's a caching issue.

One additional issue- the true isn't being output as true. It's output as merge: /* True */0 which actually results in false, since 0 is falsey.

@jeddeloh
Copy link
Owner

jeddeloh commented Apr 20, 2022

In the compiled file where you configured your client (what you showed previously), you should still be seeing _0. Also, merge: /* True */0 is the correct representation of FieldMerge.True at that level. All of that is passed to InMemoryCache.make and then goes through a bunch of layers of conversion from the ReScript layer. If you jump through the compiled code it's a little obtuse, but it should eventually see that 0 get converted to true just before it gets passed to the actual Apollo function in javascript.

What have you tried in debugging the issue so far? Does a debugger in your merge function get called? You could also put some debuggers inFieldMerge.toJs for instance, to see what is actually going on there if you don't believe it's getting converted.

@dfalling
Copy link
Contributor Author

Oh got it- I missed the fact that the toJs step happens afterwards. Turns out my issue was with yarn link not picking up my changes. I ran it off my fork instead and it worked as expected. Thanks for the help working through this! Verified that MergeFunction and True work locally as expected.

@dfalling dfalling changed the title WIP: Implement FieldMerge and FieldMergeFunction WIP: Apr 20, 2022
@dfalling dfalling changed the title WIP: Implement FieldMerge and FieldMergeFunction Apr 20, 2022
@jeddeloh
Copy link
Owner

Excellent! I really appreciate you putting in the PR. I'll merge and cut a release soon.

@jeddeloh jeddeloh merged commit a40e236 into jeddeloh:master Apr 20, 2022
@dfalling dfalling deleted the df/implement_field_merge_function branch April 20, 2022 18:45
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