Skip to content

Commit

Permalink
Add nonDedupeTypes
Browse files Browse the repository at this point in the history
  • Loading branch information
nhannah committed Nov 17, 2023
1 parent f137f62 commit f78f79c
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
15 changes: 12 additions & 3 deletions links/gql_dedupe_link/lib/gql_dedupe_link.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,37 @@
library gql_dedupe_link;

import "package:async/async.dart";
import "package:gql/ast.dart";
import "package:gql_exec/gql_exec.dart";
import "package:gql_link/gql_link.dart";

/// A [Link] to deduplicate [Request]s
class DedupeLink extends Link {
final List<OperationType> _nonDedupeTypes;
final Map<Request, StreamSplitter<Response>> _inFlight = {};

DedupeLink({List<OperationType> nonDedupeTypes = const []})
: _nonDedupeTypes = nonDedupeTypes;

@override
Stream<Response> request(
Request request, [
NextLink? forward,
]) {
if (_inFlight.containsKey(request)) {
final shouldDedupe = !_nonDedupeTypes.contains(
request.operation.getOperationType(),
);

if (shouldDedupe && _inFlight.containsKey(request)) {
return _inFlight[request]!.split();
}

final splitter = StreamSplitter(forward!(request));

_inFlight[request] = splitter;
if (shouldDedupe) _inFlight[request] = splitter;

final closeSplitter = () {
_inFlight.remove(request);
if (shouldDedupe) _inFlight.remove(request);

splitter.close();
};
Expand Down
2 changes: 1 addition & 1 deletion links/gql_dedupe_link/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ environment:
sdk: '>=2.12.0 <4.0.0'
dependencies:
async: ^2.5.0
gql: ^1.0.0
gql_exec: ^1.0.0
gql_link: ^1.0.0
meta: ^1.3.0
dev_dependencies:
gql: ^1.0.0
gql_pedantic: ^1.0.2
mockito: ^5.0.0-nullsafety.7
test: ^1.16.2
Expand Down
67 changes: 67 additions & 0 deletions links/gql_dedupe_link/test/gql_dedupe_link_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import "dart:async";

import "package:gql/ast.dart";
import "package:gql/language.dart";
import "package:gql_dedupe_link/gql_dedupe_link.dart";
import "package:gql_exec/gql_exec.dart";
Expand Down Expand Up @@ -184,6 +185,72 @@ void main() {
expect(await return2, result1);
});

test("does not dedupe identical queries if of type in nonDedupeTypes",
() async {
var count = 0;
final document = parseString(
"""
query withVar(\$i: Int) {
take(i: \$i)
}
""",
);

final req1 = Request(
operation: Operation(
document: document,
),
variables: const <String, dynamic>{"i": 12},
);

final mockLink = MockLink();

when(
mockLink.request(req1, null),
).thenAnswer((_) {
count++;
return Stream.fromIterable([
Response(
data: <String, dynamic>{"a": count},
response: <String, dynamic>{
"data": <String, dynamic>{"a": count}
},
)
]);
});

final link = Link.from([
DedupeLink(nonDedupeTypes: [OperationType.query]),
mockLink,
]);

final stream1 = link.request(req1);
final stream2 = link.request(req1);

final return1 = stream1.first;
final return2 = stream2.first;

verify(
mockLink.request(req1, null),
).called(2);
expect(
await return1,
Response(
data: const <String, dynamic>{"a": 1},
response: const <String, dynamic>{
"data": <String, dynamic>{"a": 1}
},
));
expect(
await return2,
Response(
data: const <String, dynamic>{"a": 2},
response: const <String, dynamic>{
"data": <String, dynamic>{"a": 2}
},
));
});

test("does not dedup consequtive queries", () async {
final document = parseString(
"""
Expand Down

0 comments on commit f78f79c

Please sign in to comment.