zth / rescript-relay

Use Relay with ReScript.
https://rescript-relay-documentation.vercel.app/docs/getting-started
337 stars 50 forks source link

makeConnectionId doesn't works incorrectly with multiple @connection on a fragment #437

Closed DZakh closed 1 year ago

DZakh commented 1 year ago

The makeConnectionId works with only one connection and ignores the other ones.

Here's the fragment example:

module Fragment = %relay(`
    fragment ProspectDetailsPartnerOffers_prospect on Prospect {
      id
      partnerOffersStatus
      wholesaleBids(first: 100)
        @connection(key: "ProspectDetailsPartnerOffers_wholesaleBids") {
        edges {
          node {
            ...ProspectDetailsPartnerOffers_wholesaleBid
          }
        }
      }
      prospectBids(first: 100)
        @connection(key: "ProspectDetailsPartnerOffers_prospectBids") {
        edges {
          node {
            id
            wholesaleBid {
              id
            }
          }
        }
      }
    }
  `)

The generated code looks like this:

// ProspectDetailsPartnerOffers_prospect_graphql.res

@live
@inline
let connectionKey = "ProspectDetailsPartnerOffers_prospectBids"

%%private(
  @live @module("relay-runtime") @scope("ConnectionHandler")
  external internal_makeConnectionId: (RescriptRelay.dataId, @as("ProspectDetailsPartnerOffers_prospectBids") _, 'arguments) => RescriptRelay.dataId = "getConnectionID"
)

@live
let makeConnectionId = (connectionParentDataId: RescriptRelay.dataId, ) => {
  let args = ()
  internal_makeConnectionId(connectionParentDataId, args)
}
zth commented 1 year ago

I'm surprised the compiler allows multiple connections in one fragment. It's not something that'll be supported - move those out to separate fragments if you want the helpers to work (getConnectionNodes and makeConnectionId).

What's the point of having the connection directives both but no arguments for refetching? Or is this just a condensed example?

DZakh commented 1 year ago

I've created a separate fragment, but the first connection name got prefixed with two underscores in the generated code inside of the makeNode function

image
zth commented 1 year ago

I've created a separate fragment, but the first connection name got prefixed with two underscores in the generated code inside of the makeNode function

image

Interesting! Could you paste all relevant code?

DZakh commented 1 year ago

My bad, that's the correct behavior 😅

DZakh commented 1 year ago

What's the point of having the connection directives both but no arguments for refetching? Or is this just a condensed example?

There are multiple mutations with

@appendNode(
    edgeTypeName: "WholesaleValuationRequest"
    connections: $connections
)

that update different connections for different edge types on one fragment.

DZakh commented 1 year ago

eg:

module Fragment = %relay(`
  fragment ProspectDetailsPartnerOffers_prospect on Prospect {
    wholesaleBids(first: 100)
      @connection(key: "ProspectDetailsPartnerOffers_wholesaleBids") {
      edges {
        node {
          ...ProspectDetailsPartnerOffers_wholesaleBid
        }
      }
    }
   wholesaleValuationRequests(first: 100, where: { hasWholesaleBid: false })
        @connection(
          key: "ProspectDetailsPartnerOffers_wholesaleValuationRequests"
        ) {
        edges {
          node {
            ...ProspectDetailsPartnerOffers_wholesaleValuationRequest
          }
        }
     }
  }
`)

And

module Mutation = %relay(`
    mutation AcceptValuationRequestMutation(
      $id: ID!
      $amount: Money!
      $expiresAt: Time!
      $connections: [ID!]!
    ) {
      acceptValuationRequest(
        id: $id
        input: { amount: $amount, expiresAt: $expiresAt }
      ) {
        wholesaleBid
          @appendNode(edgeTypeName: "WholesaleBid", connections: $connections) {
          ...ProspectDetailsPartnerOffers_wholesaleBid
          ...ProspectDetailsCreateBidModal_wholesaleBid
        }
        id @deleteRecord
      }
    }
  `)
module Mutation = %relay(`
    mutation SendValuationRequestMutation(
      $prospectID: ID!
      $emailContent: String!
      $wholesalePartnerIDs: [ID!]!
      $connections: [ID!]!
    ) {
      generateValuationRequest(
        input: {
          prospectID: $prospectID
          emailContent: $emailContent
          wholesalePartnerIDs: $wholesalePartnerIDs
        }
      )
        @appendNode(
          edgeTypeName: "WholesaleValuationRequest"
          connections: $connections
        ) {
        ...ProspectDetailsPartnerOffers_wholesaleValuationRequest
      }
    }
  `)

Instead of passing __id I get connections like:

ProspectDetailsPartnerOffers_prospect_graphql.makeConnectionId(
  prospectID->RescriptRelay.makeDataId,
)
zth commented 1 year ago

Right! That looks good. And it's working as intended now breaking things out to two fragments?