This repository has been archived by the owner on Apr 14, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 344
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial apollo-link-dedup implementation
- Loading branch information
Showing
6 changed files
with
265 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
{ | ||
"name": "apollo-link-dedup", | ||
"version": "0.0.0", | ||
"description": "Deduplicates queries that are currently on the wire", | ||
"author": "Evans Hauser <evanshauser@gmail.com>", | ||
"contributors": [ | ||
"James Baxley <james@meteor.com>", | ||
"Jonas Helfer <jonas@helfer.email>", | ||
"jon wong <j@jnwng.com>", | ||
"Sashko Stubailo <sashko@stubailo.com>" | ||
], | ||
"license": "MIT", | ||
"main": "./lib/dedupLink.js", | ||
"typings": "./lib/dedupLink.d.ts", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/apollographql/apollo-link.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/apollographql/apollo-link/issues" | ||
}, | ||
"homepage": "https://github.com/apollographql/apollo-link#readme", | ||
"scripts": { | ||
"pretest": "npm run build", | ||
"test": "npm run test-only --", | ||
"posttest": "npm run lint", | ||
"test-only": "mocha --reporter spec --full-trace dist/tests/tests.js", | ||
"test-watch": "mocha --reporter spec --full-trace dist/tests/tests.js --watch", | ||
"coverage": "istanbul cover ./node_modules/mocha/bin/_mocha -- --reporter dot --full-trace dist/tests/tests.js", | ||
"postcoverage": "remap-istanbul --input coverage/coverage.json --type lcovonly --output coverage/lcov.info", | ||
"lint": "tslint --type-check -p tsconfig.json src/*.ts && tslint --type-check -p tsconfig.json tests/*.ts", | ||
"prebuild": "npm run clean:dist", | ||
"build": "tsc -p .", | ||
"postbuild": "cp -R ./dist/src/. ./lib", | ||
"watch": "tsc -w -p .", | ||
"clean": "npm run clean:dist && npm run clean:coverage", | ||
"clean:dist": "rimraf dist/* && rimraf lib/*", | ||
"clean:coverage": "rimraf coverage/*", | ||
"prepublishOnly": "npm run clean && npm run build" | ||
}, | ||
"dependencies": { | ||
"apollo-fetch": "^0.6.0", | ||
"apollo-link-core": "^0.1.1", | ||
"graphql": "^0.10.5" | ||
}, | ||
"devDependencies": { | ||
"@types/chai": "^4.0.0", | ||
"@types/chai-as-promised": "0.0.31", | ||
"@types/mocha": "^2.2.31", | ||
"@types/sinon": "^2.3.2", | ||
"chai": "^4.0.2", | ||
"chai-as-promised": "^7.0.0", | ||
"fetch-mock": "^5.11.0", | ||
"graphql-tag": "^2.2.2", | ||
"istanbul": "^0.4.4", | ||
"lodash": "^4.17.4", | ||
"mocha": "^3.2.0", | ||
"remap-istanbul": "^0.9.0", | ||
"rimraf": "^2.5.4", | ||
"sinon": "^2.3.4", | ||
"source-map-support": "^0.4.5", | ||
"tslint": "^5.0.0", | ||
"typescript": "^2.2.1" | ||
}, | ||
"optionalDependencies": { | ||
"@types/graphql": "~0.9.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { | ||
ApolloLink, | ||
Operation, | ||
NextLink, | ||
FetchResult, | ||
Observable, | ||
} from 'apollo-link-core'; | ||
|
||
import { print } from 'graphql/language/printer'; | ||
|
||
/* | ||
* Expects context to contain the deduplicate field | ||
*/ | ||
export class DedupLink extends ApolloLink { | ||
private inFlightRequestPromises: { [key: string]: Observable<FetchResult> }; | ||
|
||
constructor() { | ||
super(); | ||
this.inFlightRequestPromises = {}; | ||
} | ||
|
||
public request( | ||
operation: Operation, | ||
forward: NextLink, | ||
): Observable<FetchResult> { | ||
// sometimes we might not want to deduplicate a request, for example when we want to force fetch it. | ||
if (!operation.context.deduplicate) { | ||
return forward(operation); | ||
} | ||
|
||
const key = this.getKey(operation); | ||
if (!this.inFlightRequestPromises[key]) { | ||
this.inFlightRequestPromises[key] = forward(operation); | ||
} | ||
return new Observable<FetchResult>(observer => { | ||
this.inFlightRequestPromises[key].subscribe({ | ||
next: observer.next.bind(observer), | ||
error: error => { | ||
observer.error(error); | ||
delete this.inFlightRequestPromises[key]; | ||
}, | ||
complete: () => { | ||
observer.complete(); | ||
delete this.inFlightRequestPromises[key]; | ||
}, | ||
}); | ||
}); | ||
} | ||
|
||
private getKey(operation: Operation) { | ||
// XXX we're assuming here that variables will be serialized in the same order. | ||
// that might not always be true | ||
return `${print(operation.query)}|${JSON.stringify( | ||
operation.variables, | ||
)}|${operation.operationName}`; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { assert, expect } from 'chai'; | ||
import * as sinon from 'sinon'; | ||
import DedupLink from '../src/dedupLink'; | ||
|
||
import * as Links from 'apollo-link-core'; | ||
import { ApolloLink, execute } 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', () => {}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import './*'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es5", | ||
"lib": ["es6", "dom"], | ||
"module": "commonjs", | ||
"moduleResolution": "node", | ||
"removeComments": true, | ||
"sourceMap": true, | ||
"declaration": true, | ||
"rootDir": ".", | ||
"outDir": "dist", | ||
"noImplicitAny": false, | ||
"noUnusedParameters": false, | ||
"noUnusedLocals": true, | ||
"skipLibCheck": true | ||
}, | ||
"include": ["src/**/*.ts", "tests/**/*.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
{ | ||
"rules": { | ||
"align": [false, "parameters", "arguments", "statements"], | ||
"ban": false, | ||
"class-name": true, | ||
"curly": true, | ||
"eofline": true, | ||
"forin": true, | ||
"indent": [true, "spaces", 2], | ||
"interface-name": false, | ||
"jsdoc-format": true, | ||
"label-position": true, | ||
"max-line-length": [true, 140], | ||
"member-access": true, | ||
"member-ordering": [ | ||
true, | ||
"public-before-private", | ||
"static-before-instance", | ||
"variables-before-functions" | ||
], | ||
"no-any": false, | ||
"no-arg": true, | ||
"no-bitwise": true, | ||
"no-conditional-assignment": true, | ||
"no-consecutive-blank-lines": false, | ||
"no-console": [true, "log", "debug", "info", "time", "timeEnd", "trace"], | ||
"no-construct": true, | ||
"no-debugger": true, | ||
"no-duplicate-variable": true, | ||
"no-empty": true, | ||
"no-eval": true, | ||
"no-inferrable-types": false, | ||
"no-internal-module": true, | ||
"no-null-keyword": false, | ||
"no-parameter-properties": false, | ||
"no-require-imports": false, | ||
"no-shadowed-variable": true, | ||
"no-switch-case-fall-through": true, | ||
"no-trailing-whitespace": true, | ||
"no-unused-expression": true, | ||
"no-use-before-declare": false, | ||
"no-var-keyword": true, | ||
"no-var-requires": true, | ||
"object-literal-sort-keys": false, | ||
"one-line": [ | ||
true, | ||
"check-open-brace", | ||
"check-catch", | ||
"check-else", | ||
"check-finally", | ||
"check-whitespace" | ||
], | ||
"quotemark": [true, "single", "avoid-escape"], | ||
"radix": true, | ||
"semicolon": [true, "always"], | ||
"switch-default": true, | ||
"trailing-comma": [ | ||
true, | ||
{ | ||
"multiline": "always", | ||
"singleline": "never" | ||
} | ||
], | ||
"triple-equals": [true, "allow-null-check"], | ||
"typedef": [ | ||
false, | ||
"call-signature", | ||
"parameter", | ||
"arrow-parameter", | ||
"property-declaration", | ||
"variable-declaration", | ||
"member-variable-declaration" | ||
], | ||
"typedef-whitespace": [ | ||
true, | ||
{ | ||
"call-signature": "nospace", | ||
"index-signature": "nospace", | ||
"parameter": "nospace", | ||
"property-declaration": "nospace", | ||
"variable-declaration": "nospace" | ||
}, | ||
{ | ||
"call-signature": "space", | ||
"index-signature": "space", | ||
"parameter": "space", | ||
"property-declaration": "space", | ||
"variable-declaration": "space" | ||
} | ||
], | ||
"variable-name": [ | ||
true, | ||
"check-format", | ||
"allow-pascal-case", | ||
"allow-leading-underscore", | ||
"ban-keywords" | ||
], | ||
"whitespace": [ | ||
true, | ||
"check-branch", | ||
"check-decl", | ||
"check-operator", | ||
"check-separator", | ||
"check-type" | ||
] | ||
} | ||
} |