Skip to content

Commit 2da93d0

Browse files
committed
Preserve the obserable from cache and pass a transform function
1 parent 504c2ca commit 2da93d0

File tree

2 files changed

+28
-31
lines changed

2 files changed

+28
-31
lines changed

src/cache/core/cache.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,10 @@ export abstract class ApolloCache {
439439
fragment,
440440
fragmentName
441441
) as TypedDocumentNode<TData, TVariables>;
442+
const transform: (
443+
result: ApolloCache.WatchFragmentResult<TData>
444+
) => ApolloCache.WatchFragmentResult<TData> =
445+
(options as any)[Symbol.for("apollo.transform")] ?? ((v) => v);
442446

443447
const fromArray = Array.isArray(from) ? from : [from];
444448

@@ -486,15 +490,17 @@ export abstract class ApolloCache {
486490
// without the need for a similar fallback since watchFragment with
487491
// arrays is new functionality in v4.1.
488492
transform: (result) =>
489-
from === null ? result : { ...result, data: result.data ?? {} },
493+
transform(
494+
from === null ? result : { ...result, data: result.data ?? {} }
495+
),
490496
});
491497
}
492498

493-
let currentResult: ApolloCache.WatchFragmentResult<any>;
499+
let currentResult: ApolloCache.WatchFragmentResult<TData>;
494500
function toResult(
495501
results: Array<ApolloCache.WatchFragmentResult<Unmasked<TData> | null>>
496502
): ApolloCache.WatchFragmentResult<any> {
497-
const result = results.reduce(
503+
let result = results.reduce(
498504
(finalResult, res, idx) => {
499505
const result = res as ApolloCache.WatchFragmentResult<TData>;
500506

@@ -513,9 +519,11 @@ export abstract class ApolloCache {
513519
data: [],
514520
dataState: "complete",
515521
complete: true,
516-
} as ApolloCache.WatchFragmentResult<any>
522+
} as ApolloCache.WatchFragmentResult<TData>
517523
);
518524

525+
result = transform(result);
526+
519527
if (!equal(currentResult, result)) {
520528
currentResult = result;
521529
}
@@ -617,7 +625,15 @@ export abstract class ApolloCache {
617625
this.onAfterBroadcast(() => {
618626
const result = transform(toWatchFragmentResult(diff));
619627

620-
if (!equal(currentResult, result)) {
628+
if (
629+
!currentResult ||
630+
!equalByQuery(
631+
fragmentQuery,
632+
{ data: currentResult.data },
633+
{ data: result.data },
634+
options.variables
635+
)
636+
) {
621637
currentResult = result;
622638
}
623639

@@ -632,14 +648,7 @@ export abstract class ApolloCache {
632648
this.fragmentWatches.removeArray(cacheKey);
633649
};
634650
}).pipe(
635-
distinctUntilChanged((previous, current) =>
636-
equalByQuery(
637-
fragmentQuery,
638-
{ data: previous.data },
639-
{ data: current.data },
640-
options.variables
641-
)
642-
),
651+
distinctUntilChanged(),
643652
share({
644653
connector: () => new ReplaySubject(1),
645654
// debounce so a synchronous unsubscribe+resubscribe doesn't tear down the watch and create a new one

src/core/ApolloClient.ts

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,10 +1187,6 @@ export class ApolloClient {
11871187
| ApolloClient.ObservableFragment<TData>
11881188
| ApolloClient.ObservableFragment<Array<TData>> {
11891189
const dataMasking = this.queryManager.dataMasking;
1190-
const observable = this.cache.watchFragment({
1191-
...options,
1192-
fragment: this.transform(options.fragment, dataMasking),
1193-
});
11941190

11951191
const mask = (
11961192
result: ApolloClient.WatchFragmentResult<any>
@@ -1215,21 +1211,13 @@ export class ApolloClient {
12151211
return result;
12161212
};
12171213

1218-
let currentResult: ApolloClient.WatchFragmentResult<any>;
1219-
let stableMaskedResult: ApolloClient.WatchFragmentResult<any>;
1220-
1221-
return Object.assign(observable.pipe(map(mask)), {
1222-
getCurrentResult: () => {
1223-
const result = observable.getCurrentResult();
1224-
1225-
if (result !== currentResult) {
1226-
currentResult = result as any;
1227-
stableMaskedResult = mask(currentResult);
1228-
}
1214+
const observable = this.cache.watchFragment({
1215+
...options,
1216+
fragment: this.transform(options.fragment, dataMasking),
1217+
[Symbol.for("apollo.transform")]: mask,
1218+
});
12291219

1230-
return stableMaskedResult;
1231-
},
1232-
}) as ApolloClient.ObservableFragment<any>;
1220+
return observable as ApolloClient.ObservableFragment<any>;
12331221
}
12341222

12351223
/**

0 commit comments

Comments
 (0)