github apollographql/apollo-client @apollo/client@4.3.0-alpha.5

pre-release7 hours ago

Minor Changes

  • #13390 90e338c Thanks @jerelmiller! - Fix issue where sibling @defer fragments were pruned incorrectly when at least one of the @defer fragments wasn't delivered.

    As a result of this change, a label argument is now added to all outgoing @defer directives when using the GraphQL17Alpha9Handler in order to disambiguate the @defer fragments from each other.

  • #13393 434d25f Thanks @jerelmiller! - Change when @defer fragments and @stream fields are pruned for cache-first and cache-and-network fetch policies to better match the network when the initial value contained a partial result:

    • cache-first: prune undelivered @defer fragments or @stream items when the result is fetched from the network due to a partial result
    • cache-and-network: prune undelivered @defer fragments or @stream items if the initial cache value was partial. If the first value emitted from the cache is complete, the results will not be pruned.

    This makes the emitted results more predictable by following what the network has delivered and avoids some ambiguity in other edge cases.

    For example, with a cache-first fetch policy where all @defer fields are written to the cache, but a non-deferred field is partial, the values emitted from the client previously looked like the following:

    query {
      user {
        id
        name
        ... @defer {
          email
        }
      }
    }
    // data written to the cache is missing name
    { user: { id: 1, email: "user.cache@example.com" }}
    
    // 1. empty because the result is partial
    { data: undefined, dataState: "empty", ... }
    // 2. returns all data because the cache contains a value for email
    { data: { user: 1, name: "User", email: "user.cache@example.com" }, dataState: "complete" }
    // 3. email updated from the server
    { data: { user: 1, name: "User", email: "user.network@example.com" }, dataState: "complete" }

    Here the result is confusing because the initial value returned from the query was undefined, yet a complete result was returned after the initial chunk from the network returned (which did not contain email).

    The cache values are now pruned if the network hasn't delivered them yet:

    // 1. empty because the result is partial
    { data: undefined, dataState: "empty" }
    // 2. email hasn't been delivered by the network so it gets pruned
    { data: { user: 1, name: "User" }, dataState: "streaming" }
    // 3. full result returned after the network streams the email field
    { data: { user: 1, name: "User", email: "user.network@example.com" }, dataState: "complete" }

    This is especially helpful in situations where @defer boundaries that are never delivered due to errors prevent an awkward situation where the client would otherwise have to choose whether to serve the stale cache result from the cache, or prune the undelivered fragment on the final chunk.

Patch Changes

  • #13381 9c73762 Thanks @jerelmiller! - Fix an issue where a network-only query leaked partial cache data for @defer fragments that were not delivered by the network due to an error that bubbled to the @defer fragment boundary.

  • #13390 90e338c Thanks @jerelmiller! - Fix an issue where a sibling non-deferred fragment might be accidentally pruned when the @defer fragment hadn't been delivered.

  • #13403 aaff7a8 Thanks @jerelmiller! - Fix issue where the wrong dataState was returned when there was nothing written to the cache and a @defer fragment was marked pending.

  • #13381 9c73762 Thanks @jerelmiller! - Fix an issue where a @defer query reported the dataState as complete instead of streaming when an error occurs on a deferred field that bubbled to the defer boundary.

  • #13373 2551937 Thanks @jerelmiller! - Fix an issue where a cache write in the middle of polling would remain as the query value if future poll requests returned deep equal results to previous polling results.

  • #13403 aaff7a8 Thanks @jerelmiller! - Fix issue where setting returnPartialData: true might report the wrong dataState when partial data was written to the cache and @defer fragments were pending.

  • #13381 9c73762 Thanks @jerelmiller! - Fix an invariant error thrown when a @defer boundary received a payload after it had already been marked complete.

Don't miss a new apollo-client release

NewReleases is sending notifications on new releases.