Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(graphcache): Fix info.partial edge case for @_optional (#3340)

authored by

Phil Pluckthun and committed by
GitHub
25a34c64 51f72c2c

+15 -4
+5
.changeset/few-garlics-judge.md
··· 1 + --- 2 + '@urql/exchange-graphcache': patch 3 + --- 4 + 5 + Reset `partial` result marker when reading from selections when a child value sees a cache miss. This only affects resolvers on child values enabling `info.partial` while a parent may abort early instead.
+10 -4
exchanges/graphcache/src/operations/query.ts
··· 388 388 ); 389 389 390 390 let hasFields = false; 391 - let hasPartials = false; 392 391 let hasNext = false; 393 392 let hasChanged = InMemoryData.currentForeignData; 394 393 let node: FormattedNode<FieldNode> | void; 394 + const hasPartials = ctx.partial; 395 395 const output = InMemoryData.makeData(input); 396 396 while ((node = iterate()) !== undefined) { 397 397 // Derive the needed data from our node. ··· 522 522 !!getFieldError(ctx)) 523 523 ) { 524 524 // The field is uncached or has errored, so it'll be set to null and skipped 525 - hasPartials = true; 525 + ctx.partial = true; 526 526 dataFieldValue = null; 527 527 } else if (dataFieldValue === undefined) { 528 - // If the field isn't deferred or partial then we have to abort 528 + // If the field isn't deferred or partial then we have to abort and also reset 529 + // the partial field 530 + ctx.partial = hasPartials; 529 531 ctx.__internal.path.pop(); 530 532 return undefined; 531 533 } else { ··· 542 544 543 545 ctx.partial = ctx.partial || hasPartials; 544 546 ctx.hasNext = ctx.hasNext || hasNext; 545 - return isQuery && hasPartials && !hasFields 547 + return isQuery && ctx.partial && !hasFields 546 548 ? undefined 547 549 : hasChanged 548 550 ? output ··· 566 568 const _isListNullable = store.schema 567 569 ? isListNullable(store.schema, typename, fieldName) 568 570 : false; 571 + const hasPartials = ctx.partial; 569 572 const data = InMemoryData.makeData(prevData, true); 570 573 let hasChanged = 571 574 InMemoryData.currentForeignData || ··· 589 592 ctx.__internal.path.pop(); 590 593 // Check the result for cache-missed values 591 594 if (childResult === undefined && !_isListNullable) { 595 + ctx.partial = hasPartials; 592 596 return undefined; 593 597 } else { 594 598 ctx.partial = ··· 636 640 ? isListNullable(store.schema, typename, fieldName) 637 641 : false; 638 642 const newLink = InMemoryData.makeData(prevData, true); 643 + const hasPartials = ctx.partial; 639 644 let hasChanged = 640 645 InMemoryData.currentForeignData || 641 646 !Array.isArray(prevData) || ··· 657 662 ctx.__internal.path.pop(); 658 663 // Check the result for cache-missed values 659 664 if (childLink === undefined && !_isListNullable) { 665 + ctx.partial = hasPartials; 660 666 return undefined; 661 667 } else { 662 668 ctx.partial =