Skip to content

Commit e36157e

Browse files
committed
Handle watchFragment with arrays with new structure
1 parent 1ab278f commit e36157e

File tree

1 file changed

+31
-68
lines changed

1 file changed

+31
-68
lines changed

src/cache/core/cache.ts

Lines changed: 31 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -434,13 +434,7 @@ export abstract class ApolloCache {
434434
):
435435
| ApolloCache.ObservableFragment<Unmasked<TData> | null>
436436
| ApolloCache.ObservableFragment<Array<Unmasked<TData> | null>> {
437-
const {
438-
fragment,
439-
fragmentName,
440-
from,
441-
optimistic = true,
442-
variables,
443-
} = options;
437+
const { fragment, fragmentName, from } = options;
444438
const query = this.getFragmentDoc(
445439
fragment,
446440
fragmentName
@@ -498,50 +492,29 @@ export abstract class ApolloCache {
498492

499493
let currentResult: ApolloCache.WatchFragmentResult<any>;
500494
function toResult(
501-
diffs: Array<Cache.DiffResult<Unmasked<TData> | null>>
495+
results: Array<ApolloCache.WatchFragmentResult<Unmasked<TData> | null>>
502496
): ApolloCache.WatchFragmentResult<any> {
503-
let result: ApolloCache.WatchFragmentResult<any>;
504-
if (Array.isArray(from)) {
505-
result = diffs.reduce(
506-
(result, diff, idx) => {
507-
result.data.push(diff.result as any);
508-
result.complete &&= diff.complete;
509-
result.dataState = result.complete ? "complete" : "partial";
510-
511-
if (diff.missing) {
512-
result.missing ||= {};
513-
(result.missing as any)[idx] = diff.missing.missing;
514-
}
515-
516-
return result;
517-
},
518-
{
519-
data: [],
520-
dataState: "complete",
521-
complete: true,
522-
} as ApolloCache.WatchFragmentResult<any>
523-
);
524-
} else {
525-
const [diff] = diffs;
526-
result = {
527-
// Unfortunately we forgot to allow for `null` on watchFragment in 4.0
528-
// when `from` is a single record. As such, we need to fallback to {}
529-
// when diff.result is null to maintain backwards compatibility. We
530-
// should plan to change this in v5. We do howeever support `null` if
531-
// `from` is explicitly `null`.
532-
//
533-
// NOTE: Using `from` with an array will maintain `null` properly
534-
// without the need for a similar fallback since watchFragment with
535-
// arrays is new functionality in v4.
536-
data: from === null ? diff.result : diff.result ?? {},
537-
complete: diff.complete,
538-
dataState: diff.complete ? "complete" : "partial",
539-
} as ApolloCache.WatchFragmentResult<Unmasked<TData>>;
540-
541-
if (diff.missing) {
542-
result.missing = diff.missing.missing;
543-
}
544-
}
497+
const result = results.reduce(
498+
(finalResult, result, idx) => {
499+
const res = result as ApolloCache.WatchFragmentResult<TData>;
500+
501+
finalResult.data.push(res.data);
502+
finalResult.complete &&= res.complete;
503+
finalResult.dataState = finalResult.complete ? "complete" : "partial";
504+
505+
if (res.missing) {
506+
finalResult.missing ||= {};
507+
(finalResult.missing as any)[idx] = res.missing;
508+
}
509+
510+
return finalResult;
511+
},
512+
{
513+
data: [],
514+
dataState: "complete",
515+
complete: true,
516+
} as ApolloCache.WatchFragmentResult<any>
517+
);
545518

546519
if (!equal(currentResult, result)) {
547520
currentResult = result;
@@ -551,12 +524,14 @@ export abstract class ApolloCache {
551524
}
552525

553526
let subscribed = false;
527+
const observables = ids.map((id) =>
528+
this.watchSingleFragment(id, query, options)
529+
);
530+
554531
const observable =
555532
ids.length === 0 ?
556533
emptyArrayObservable
557-
: combineLatestBatched(
558-
ids.map((id) => this.watchSingleFragment(id, query, options))
559-
).pipe(
534+
: combineLatestBatched(observables).pipe(
560535
map(toResult),
561536
tap({
562537
subscribe: () => (subscribed = true),
@@ -571,23 +546,11 @@ export abstract class ApolloCache {
571546
return currentResult as any;
572547
}
573548

574-
const diffs = ids.map(
575-
(id): Cache.DiffResult<Unmasked<TData> | null> => {
576-
if (id === null) {
577-
return { result: null, complete: true };
578-
}
579-
580-
return this.diff<Unmasked<TData>>({
581-
id,
582-
query,
583-
returnPartialData: true,
584-
optimistic,
585-
variables,
586-
});
587-
}
549+
const results = observables.map((observable) =>
550+
observable.getCurrentResult()
588551
);
589552

590-
return toResult(diffs);
553+
return toResult(results);
591554
},
592555
} satisfies Pick<
593556
| ApolloCache.ObservableFragment<Unmasked<TData> | null>

0 commit comments

Comments
 (0)