Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

apollo-link-dedup

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apollo-link-dedup - npm Package Compare versions

Comparing version 0.0.0 to 0.1.0

dist/src/dedupLink.d.ts

2

package.json
{
"name": "apollo-link-dedup",
"version": "0.0.0",
"version": "0.1.0",
"description": "Deduplicates queries that are currently on the wire",

@@ -5,0 +5,0 @@ "author": "Evans Hauser <evanshauser@gmail.com>",

@@ -12,10 +12,12 @@ import {

/*
* Expects context to contain the deduplicate field
* Expects context to contain the forceFetch field if no dedup
*/
export class DedupLink extends ApolloLink {
private inFlightRequestPromises: { [key: string]: Observable<FetchResult> };
export default class DedupLink extends ApolloLink {
private inFlightRequestObservables: {
[key: string]: Observable<FetchResult>;
};
constructor() {
super();
this.inFlightRequestPromises = {};
this.inFlightRequestObservables = {};
}

@@ -28,3 +30,3 @@

// sometimes we might not want to deduplicate a request, for example when we want to force fetch it.
if (!operation.context.deduplicate) {
if (operation.context.forceFetch) {
return forward(operation);

@@ -34,15 +36,15 @@ }

const key = this.getKey(operation);
if (!this.inFlightRequestPromises[key]) {
this.inFlightRequestPromises[key] = forward(operation);
if (!this.inFlightRequestObservables[key]) {
this.inFlightRequestObservables[key] = forward(operation);
}
return new Observable<FetchResult>(observer => {
this.inFlightRequestPromises[key].subscribe({
this.inFlightRequestObservables[key].subscribe({
next: observer.next.bind(observer),
error: error => {
delete this.inFlightRequestObservables[key];
observer.error(error);
delete this.inFlightRequestPromises[key];
},
complete: () => {
delete this.inFlightRequestObservables[key];
observer.complete();
delete this.inFlightRequestPromises[key];
},

@@ -49,0 +51,0 @@ });

@@ -1,14 +0,189 @@

import { assert, expect } from 'chai';
import * as sinon from 'sinon';
import { assert } from 'chai';
import DedupLink from '../src/dedupLink';
import * as Links from 'apollo-link-core';
import { ApolloLink, execute } from 'apollo-link-core';
import { ApolloLink, execute, Operation, Observable } from 'apollo-link-core';
import { createApolloFetch } from 'apollo-fetch';
import { print } from 'graphql';
import gql from 'graphql-tag';
import * as fetchMock from 'fetch-mock';
describe('DedupLink', () => {});
import { DocumentNode } from 'graphql';
function getOperationName(doc: DocumentNode): string | null {
let res: string | null = null;
doc.definitions.forEach(definition => {
if (definition.kind === 'OperationDefinition' && definition.name) {
res = definition.name.value;
}
});
return res;
}
describe('DedupLink', () => {
it(`does not affect different queries`, () => {
const document: DocumentNode = gql`
query test1($x: String) {
test(x: $x)
}
`;
const variables1 = { x: 'Hello World' };
const variables2 = { x: 'Goodbye World' };
const request1: Operation = {
query: document,
variables: variables1,
operationName: getOperationName(document),
};
const request2: Operation = {
query: document,
variables: variables2,
operationName: getOperationName(document),
};
let called = 0;
const deduper = ApolloLink.from([
new DedupLink(),
() => {
called += 1;
return null;
},
]);
execute(deduper, request1);
execute(deduper, request2);
assert.equal(called, 2);
});
it(`will not deduplicate requests following an errored query`, done => {
const document: DocumentNode = gql`
query test1($x: String) {
test(x: $x)
}
`;
const variables = { x: 'Hello World' };
let error;
const data = { data: { data: 'some data' } };
const request: Operation = {
query: document,
variables: variables,
operationName: getOperationName(document),
};
let called = 0;
const deduper = ApolloLink.from([
new DedupLink(),
() => {
called += 1;
switch (called) {
case 1:
return new Observable(observer => {
error = new Error('some error');
observer.error(error);
});
case 2:
return new Observable(observer => {
observer.next(data);
observer.complete();
});
default:
assert(false, 'Should not have been called more than twice');
return null;
}
},
]);
execute(deduper, request).subscribe({
error: actualError => {
assert.equal(actualError, error);
//second query
execute(deduper, request).subscribe({
next: result => {
assert.equal(result, data);
assert.equal(called, 2);
done();
},
});
},
});
});
it(`deduplicates identical queries`, () => {
const document: DocumentNode = gql`
query test1($x: String) {
test(x: $x)
}
`;
const variables1 = { x: 'Hello World' };
const variables2 = { x: 'Hello World' };
const request1: Operation = {
query: document,
variables: variables1,
operationName: getOperationName(document),
};
const request2: Operation = {
query: document,
variables: variables2,
operationName: getOperationName(document),
};
let called = 0;
const deduper = ApolloLink.from([
new DedupLink(),
() => {
called += 1;
return new Observable(observer => {
setTimeout(observer.complete.bind(observer));
});
},
]);
execute(deduper, request1).subscribe({});
execute(deduper, request2).subscribe({});
assert.equal(called, 1);
});
it(`can bypass deduplication if desired`, () => {
const document: DocumentNode = gql`
query test1($x: String) {
test(x: $x)
}
`;
const variables1 = { x: 'Hello World' };
const variables2 = { x: 'Hello World' };
const request1: Operation = {
query: document,
variables: variables1,
operationName: getOperationName(document),
context: {
forceFetch: true,
},
};
const request2: Operation = {
query: document,
variables: variables2,
operationName: getOperationName(document),
context: {
forceFetch: true,
},
};
let called = 0;
const deduper = ApolloLink.from([
new DedupLink(),
() => {
called += 1;
return null;
},
]);
execute(deduper, request1).subscribe({});
execute(deduper, request2).subscribe({});
assert.equal(called, 2);
});
});

@@ -1,1 +0,1 @@

import './*';
import './dedupLink';
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc