Skip to content

Commit

Permalink
Add support for dataIdFromObject to ferry_cache and swap the order of…
Browse files Browse the repository at this point in the history
… assignment in denormalize_fragment
  • Loading branch information
tberman authored and smkhalsa committed May 19, 2021
1 parent bd2cbec commit ea0b48f
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 20 deletions.
12 changes: 11 additions & 1 deletion ferry_cache/lib/src/cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Cache {
final Map<String, TypePolicy> typePolicies;
final bool addTypename;
final Store store;
final utils.DataIdResolver? dataIdFromObject;

@visibleForTesting
final BehaviorSubject<
Expand All @@ -24,12 +25,14 @@ class Cache {

Cache({
Store? store,
utils.DataIdResolver? dataIdFromObject,
this.typePolicies = const {},
this.addTypename = true,
Map<OperationRequest, Map<String, Map<String, dynamic>?>>
seedOptimisticPatches = const {},
}) : store = store ?? MemoryStore(),
optimisticPatchesStream = BehaviorSubject.seeded(seedOptimisticPatches);
optimisticPatchesStream = BehaviorSubject.seeded(seedOptimisticPatches),
dataIdFromObject = dataIdFromObject;

/// Reads data for the given [dataId] from the [Store], merging in any data from optimistic patches
@visibleForTesting
Expand Down Expand Up @@ -62,6 +65,7 @@ class Cache {
store,
typePolicies,
addTypename,
dataIdFromObject: dataIdFromObject,
).doOnDone(() => closed = true);

return NeverStream<TData?>()
Expand Down Expand Up @@ -97,6 +101,7 @@ class Cache {
store,
typePolicies,
addTypename,
dataIdFromObject: dataIdFromObject,
).doOnDone(() => closed = true);

return NeverStream<TData?>()
Expand Down Expand Up @@ -129,6 +134,7 @@ class Cache {
// TODO: don't cast to dynamic
variables: (request.vars as dynamic)?.toJson(),
typePolicies: typePolicies,
dataIdFromObject: dataIdFromObject,
);
return json == null ? null : request.parseData(json);
}
Expand All @@ -147,6 +153,7 @@ class Cache {
variables: (request.vars as dynamic)?.toJson(),
typePolicies: typePolicies,
addTypename: addTypename,
dataIdFromObject: dataIdFromObject,
);
return json == null ? null : request.parseData(json);
}
Expand Down Expand Up @@ -177,6 +184,7 @@ class Cache {
data: (data as dynamic)?.toJson(),
typePolicies: typePolicies,
addTypename: addTypename,
dataIdFromObject: dataIdFromObject,
);

/// Normalizes [data] for the given fragment and writes it to the [Store].
Expand Down Expand Up @@ -206,6 +214,7 @@ class Cache {
data: (data as dynamic)?.toJson(),
typePolicies: typePolicies,
addTypename: addTypename,
dataIdFromObject: dataIdFromObject,
);

void _writeData(
Expand Down Expand Up @@ -237,6 +246,7 @@ class Cache {
// TODO: don't cast to dynamic
(data as dynamic)?.toJson(),
typePolicies: typePolicies,
dataIdFromObject: dataIdFromObject,
);

/// Removes the entity from the [Store] as well as from any optimistic
Expand Down
20 changes: 11 additions & 9 deletions ferry_cache/lib/src/fragment_data_change_stream.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@ import 'package:normalize/policies.dart';
import 'package:normalize/normalize.dart';
import 'package:collection/collection.dart';
import 'package:ferry_store/ferry_store.dart';
import 'package:normalize/utils.dart';
import 'package:rxdart/rxdart.dart';

import 'package:ferry_exec/ferry_exec.dart';
import './utils/data_for_id_stream.dart';

/// Emits when the data for this fragment changes, returning a `Set` of changed IDs.
Stream<Set<String>> fragmentDataChangeStream<TData, TVars>(
FragmentRequest<TData, TVars> request,
bool optimistic,
Stream<Map<OperationRequest, Map<String, Map<String, dynamic>?>>?>
optimisticPatchesStream,
Map<String, dynamic>? Function(String dataId) optimisticReader,
Store store,
Map<String, TypePolicy> typePolicies,
bool addTypename,
) {
FragmentRequest<TData, TVars> request,
bool optimistic,
Stream<Map<OperationRequest, Map<String, Map<String, dynamic>?>>?>
optimisticPatchesStream,
Map<String, dynamic>? Function(String dataId) optimisticReader,
Store store,
Map<String, TypePolicy> typePolicies,
bool addTypename,
{DataIdResolver? dataIdFromObject}) {
final dataIds = <String>{};

denormalizeFragment(
Expand All @@ -33,6 +34,7 @@ Stream<Set<String>> fragmentDataChangeStream<TData, TVars>(
typePolicies: typePolicies,
addTypename: addTypename,
returnPartialData: true,
dataIdFromObject: dataIdFromObject,
);

/// IDs that have changed
Expand Down
19 changes: 10 additions & 9 deletions ferry_cache/lib/src/operation_data_change_stream.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import './utils/operation_root_data.dart';

/// Emits when the data for this request changes, returning a `Set` of changed IDs.
Stream<Set<String>> operationDataChangeStream<TData, TVars>(
OperationRequest<TData, TVars> request,
bool optimistic,
Stream<Map<OperationRequest, Map<String, Map<String, dynamic>?>>?>
optimisticPatchesStream,
Map<String, dynamic>? Function(String dataId) optimisticReader,
Store store,
Map<String, TypePolicy> typePolicies,
bool addTypename,
) {
OperationRequest<TData, TVars> request,
bool optimistic,
Stream<Map<OperationRequest, Map<String, Map<String, dynamic>?>>?>
optimisticPatchesStream,
Map<String, dynamic>? Function(String dataId) optimisticReader,
Store store,
Map<String, TypePolicy> typePolicies,
bool addTypename,
{DataIdResolver? dataIdFromObject}) {
final operationDefinition = getOperationDefinition(
request.operation.document,
request.operation.operationName,
Expand All @@ -43,6 +43,7 @@ Stream<Set<String>> operationDataChangeStream<TData, TVars>(
typePolicies: typePolicies,
addTypename: addTypename,
returnPartialData: true,
dataIdFromObject: dataIdFromObject,
);

/// IDs that have changed
Expand Down
14 changes: 14 additions & 0 deletions ferry_cache/test/sync_operations_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ void main() {
expect(cache.readFragment(reviewFragmentReq), equals(reviewFragmentData));
});

test('dataIdFromObject overrides cache.identify', () {
final cache = Cache(dataIdFromObject: (object) => 'OVERRIDE');
expect(cache.identify(reviewFragmentData), equals('OVERRIDE'));
});

test('can read and write with a data id override', () {
final cache = Cache(dataIdFromObject: (object) => 'OVERRIDE');
cache.writeFragment(reviewFragmentReq, reviewFragmentData);

reviewFragmentReq.idFields['id'] = 'OVERRIDE';

expect(cache.readFragment(reviewFragmentReq), equals(reviewFragmentData));
});

test('can clear cache', () {
final cache = Cache();

Expand Down
2 changes: 1 addition & 1 deletion normalize/lib/src/denormalize_fragment.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ Map<String, dynamic>? denormalizeFragment({

final dataId = resolveDataId(
data: {
...idFields,
'__typename': fragmentDefinition.typeCondition.on.name.value,
...idFields,
},
typePolicies: typePolicies,
dataIdFromObject: dataIdFromObject,
Expand Down
23 changes: 23 additions & 0 deletions normalize/test/fragments_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -197,5 +197,28 @@ void main() {
equals(normalizedMap),
);
});

test('Override __typename on denormalize', () {
final fragment = parseString('''
fragment user on Author {
id
name
}
''');
final data = {'id': '1', 'name': 'Paul'};

final normalizedMap = {
'NotAuthor:1': {'id': '1', '__typename': 'Author', 'name': 'Paul'},
};

expect(
denormalizeFragment(
document: fragment,
idFields: {'id': '1', '__typename': 'NotAuthor'},
read: (dataId) => normalizedMap[dataId],
),
equals(data),
);
});
});
}

0 comments on commit ea0b48f

Please sign in to comment.