apollo-link-timeout 3.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,7 +12,7 @@ yarn add apollo-link-timeout
12
12
  ```
13
13
 
14
14
  ## Usage
15
- ```
15
+ ```javascript
16
16
  import ApolloLinkTimeout from 'apollo-link-timeout';
17
17
  import { createHttpLink } from 'apollo-link-http';
18
18
  import { ApolloClient } from 'apollo-client';
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeoutError.js","sourceRoot":"","sources":["../../src/TimeoutError.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA;IAA0C,gCAAK;IAI7C,sBAAY,OAAe,EAAE,OAAe,EAAE,UAAwB;QAAxB,2BAAA,EAAA,gBAAwB;QAAtE,YACE,kBAAM,OAAO,CAAC,SAGf;QAFC,KAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,KAAI,CAAC,UAAU,GAAG,UAAU,CAAC;;IAC/B,CAAC;IACH,mBAAC;AAAD,CAAC,AATD,CAA0C,KAAK,GAS9C"}
package/lib/cjs/cjs.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var timeoutLink_1 = require("./timeoutLink");
4
+ module.exports = timeoutLink_1.default;
5
+ module.exports.default = timeoutLink_1.default;
6
+ //# sourceMappingURL=cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cjs.js","sourceRoot":"","sources":["../../src/cjs.ts"],"names":[],"mappings":";;AAAA,6CAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,qBAAW,CAAC;AAC7B,MAAM,CAAC,OAAO,CAAC,OAAO,GAAG,qBAAW,CAAC"}
@@ -0,0 +1 @@
1
+ {"type": "commonjs"}
@@ -35,13 +35,15 @@ var TimeoutLink = /** @class */ (function (_super) {
35
35
  TimeoutLink.prototype.request = function (operation, forward) {
36
36
  var _this = this;
37
37
  var controller;
38
+ var ourController;
38
39
  // override timeout from query context
39
40
  var requestTimeout = operation.getContext().timeout || this.timeout;
40
41
  // add abort controller and signal object to fetchOptions if they don't already exist
41
42
  if (typeof AbortController !== 'undefined') {
42
43
  var context = operation.getContext();
43
44
  var fetchOptions = context.fetchOptions || {};
44
- controller = fetchOptions.controller || new AbortController();
45
+ ourController = new AbortController();
46
+ controller = fetchOptions.controller || ourController;
45
47
  fetchOptions = __assign({}, fetchOptions, { controller: controller, signal: controller.signal });
46
48
  operation.setContext({ fetchOptions: fetchOptions });
47
49
  }
@@ -67,34 +69,37 @@ var TimeoutLink = /** @class */ (function (_super) {
67
69
  // if timeout expires before observable completes, abort call, unsubscribe, and return error
68
70
  timer = setTimeout(function () {
69
71
  if (controller) {
72
+ if (controller.signal.aborted) {
73
+ // already aborted from somewhere else
74
+ return;
75
+ }
70
76
  controller.abort(); // abort fetch operation
71
77
  // if the AbortController in the operation context is one we created,
72
78
  // it's now "used up", so we need to remove it to avoid blocking any
73
79
  // future retry of the operation.
74
80
  var context = operation.getContext();
75
81
  var fetchOptions = context.fetchOptions || {};
76
- if (fetchOptions.controller === controller && fetchOptions.signal === controller.signal) {
77
- fetchOptions = __assign({}, fetchOptions, { controller: null, signal: null });
78
- operation.setContext({ fetchOptions: fetchOptions });
82
+ if (fetchOptions.controller === ourController && fetchOptions.signal === ourController.signal) {
83
+ operation.setContext(__assign({}, fetchOptions, { controller: undefined, signal: undefined }));
79
84
  }
80
85
  }
81
86
  observer.error(new TimeoutError_1.default('Timeout exceeded', requestTimeout, _this.statusCode));
82
87
  subscription.unsubscribe();
83
88
  }, requestTimeout);
89
+ var cancelTimeout = function () {
90
+ clearTimeout(timer);
91
+ subscription.unsubscribe();
92
+ };
84
93
  var ctxRef = operation.getContext().timeoutRef;
85
94
  if (ctxRef) {
86
- ctxRef({
87
- unsubscribe: function () {
88
- clearTimeout(timer);
89
- subscription.unsubscribe();
90
- }
91
- });
95
+ ctxRef({ unsubscribe: cancelTimeout });
92
96
  }
97
+ // cancel timeout if aborted from somewhere else
98
+ controller.signal.addEventListener("abort", function () {
99
+ cancelTimeout();
100
+ }, { once: true });
93
101
  // this function is called when a client unsubscribes from localObservable
94
- return function () {
95
- clearTimeout(timer);
96
- subscription.unsubscribe();
97
- };
102
+ return cancelTimeout;
98
103
  });
99
104
  return localObservable;
100
105
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeoutLink.js","sourceRoot":"","sources":["../../src/timeoutLink.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ var __extends = (this && this.__extends) || (function () {
2
+ var extendStatics = Object.setPrototypeOf ||
3
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
5
+ return function (d, b) {
6
+ extendStatics(d, b);
7
+ function __() { this.constructor = d; }
8
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
9
+ };
10
+ })();
11
+ var TimeoutError = /** @class */ (function (_super) {
12
+ __extends(TimeoutError, _super);
13
+ function TimeoutError(message, timeout, statusCode) {
14
+ if (statusCode === void 0) { statusCode = 408; }
15
+ var _this = _super.call(this, message) || this;
16
+ _this.timeout = timeout;
17
+ _this.statusCode = statusCode;
18
+ return _this;
19
+ }
20
+ return TimeoutError;
21
+ }(Error));
22
+ export default TimeoutError;
23
+ //# sourceMappingURL=TimeoutError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeoutError.js","sourceRoot":"","sources":["../../src/TimeoutError.ts"],"names":[],"mappings":";;;;;;;;;;AAAA;IAA0C,gCAAK;IAI7C,sBAAY,OAAe,EAAE,OAAe,EAAE,UAAwB;QAAxB,2BAAA,EAAA,gBAAwB;QAAtE,YACE,kBAAM,OAAO,CAAC,SAGf;QAFC,KAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,KAAI,CAAC,UAAU,GAAG,UAAU,CAAC;;IAC/B,CAAC;IACH,mBAAC;AAAD,CAAC,AATD,CAA0C,KAAK,GAS9C"}
@@ -0,0 +1 @@
1
+ {"type": "module"}
@@ -0,0 +1,107 @@
1
+ var __extends = (this && this.__extends) || (function () {
2
+ var extendStatics = Object.setPrototypeOf ||
3
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
5
+ return function (d, b) {
6
+ extendStatics(d, b);
7
+ function __() { this.constructor = d; }
8
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
9
+ };
10
+ })();
11
+ var __assign = (this && this.__assign) || Object.assign || function(t) {
12
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
13
+ s = arguments[i];
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
15
+ t[p] = s[p];
16
+ }
17
+ return t;
18
+ };
19
+ import { ApolloLink, Observable } from '@apollo/client/core';
20
+ import TimeoutError from './TimeoutError';
21
+ var DEFAULT_TIMEOUT = 15000;
22
+ /**
23
+ * Aborts the request if the timeout expires before the response is received.
24
+ */
25
+ var TimeoutLink = /** @class */ (function (_super) {
26
+ __extends(TimeoutLink, _super);
27
+ function TimeoutLink(timeout, statusCode) {
28
+ var _this = _super.call(this) || this;
29
+ _this.timeout = timeout || DEFAULT_TIMEOUT;
30
+ _this.statusCode = statusCode;
31
+ return _this;
32
+ }
33
+ TimeoutLink.prototype.request = function (operation, forward) {
34
+ var _this = this;
35
+ var controller;
36
+ var ourController;
37
+ // override timeout from query context
38
+ var requestTimeout = operation.getContext().timeout || this.timeout;
39
+ // add abort controller and signal object to fetchOptions if they don't already exist
40
+ if (typeof AbortController !== 'undefined') {
41
+ var context = operation.getContext();
42
+ var fetchOptions = context.fetchOptions || {};
43
+ ourController = new AbortController();
44
+ controller = fetchOptions.controller || ourController;
45
+ fetchOptions = __assign({}, fetchOptions, { controller: controller, signal: controller.signal });
46
+ operation.setContext({ fetchOptions: fetchOptions });
47
+ }
48
+ var chainObservable = forward(operation); // observable for remaining link chain
49
+ var operationType = operation.query.definitions.find(function (def) { return def.kind === 'OperationDefinition'; }).operation;
50
+ if (requestTimeout <= 0 || operationType === 'subscription') {
51
+ return chainObservable; // skip this link if timeout is zero or it's a subscription request
52
+ }
53
+ // create local observable with timeout functionality (unsubscibe from chain observable and
54
+ // return an error if the timeout expires before chain observable resolves)
55
+ var localObservable = new Observable(function (observer) {
56
+ var timer;
57
+ // listen to chainObservable for result and pass to localObservable if received before timeout
58
+ var subscription = chainObservable.subscribe(function (result) {
59
+ clearTimeout(timer);
60
+ observer.next(result);
61
+ observer.complete();
62
+ }, function (error) {
63
+ clearTimeout(timer);
64
+ observer.error(error);
65
+ observer.complete();
66
+ });
67
+ // if timeout expires before observable completes, abort call, unsubscribe, and return error
68
+ timer = setTimeout(function () {
69
+ if (controller) {
70
+ if (controller.signal.aborted) {
71
+ // already aborted from somewhere else
72
+ return;
73
+ }
74
+ controller.abort(); // abort fetch operation
75
+ // if the AbortController in the operation context is one we created,
76
+ // it's now "used up", so we need to remove it to avoid blocking any
77
+ // future retry of the operation.
78
+ var context = operation.getContext();
79
+ var fetchOptions = context.fetchOptions || {};
80
+ if (fetchOptions.controller === ourController && fetchOptions.signal === ourController.signal) {
81
+ operation.setContext(__assign({}, fetchOptions, { controller: undefined, signal: undefined }));
82
+ }
83
+ }
84
+ observer.error(new TimeoutError('Timeout exceeded', requestTimeout, _this.statusCode));
85
+ subscription.unsubscribe();
86
+ }, requestTimeout);
87
+ var cancelTimeout = function () {
88
+ clearTimeout(timer);
89
+ subscription.unsubscribe();
90
+ };
91
+ var ctxRef = operation.getContext().timeoutRef;
92
+ if (ctxRef) {
93
+ ctxRef({ unsubscribe: cancelTimeout });
94
+ }
95
+ // cancel timeout if aborted from somewhere else
96
+ controller.signal.addEventListener("abort", function () {
97
+ cancelTimeout();
98
+ }, { once: true });
99
+ // this function is called when a client unsubscribes from localObservable
100
+ return cancelTimeout;
101
+ });
102
+ return localObservable;
103
+ };
104
+ return TimeoutLink;
105
+ }(ApolloLink));
106
+ export default TimeoutLink;
107
+ //# sourceMappingURL=timeoutLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeoutLink.js","sourceRoot":"","sources":["../../src/timeoutLink.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apollo-link-timeout",
3
- "version": "3.0.0",
3
+ "version": "5.0.0",
4
4
  "description": "Abort requests that take longer than a specified timeout period",
5
5
  "peerDependencies": {
6
6
  "@apollo/client": "^3.0.0"
@@ -18,8 +18,15 @@
18
18
  "tslint": "^5.8.0",
19
19
  "typescript": "^2.9.2"
20
20
  },
21
- "main": "lib/timeoutLink.js",
22
- "types": "lib/timeoutLink.d.ts",
21
+ "main": "./lib/cjs/cjs.js",
22
+ "types": "./lib/types/timeoutLink.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "import": "./lib/esm/timeoutLink.js",
26
+ "require": "./lib/cjs/cjs.js",
27
+ "types": "./lib/types/timeoutLink.d.ts"
28
+ }
29
+ },
23
30
  "repository": {
24
31
  "type": "git",
25
32
  "url": "https://github.com/drcallaway/apollo-link-timeout"
@@ -28,7 +35,10 @@
28
35
  "registry": "https://registry.npmjs.org/"
29
36
  },
30
37
  "scripts": {
31
- "build": "tsc",
38
+ "build": "yarn build:cjs && yarn build:esm && yarn build:types",
39
+ "build:cjs": "tsc -p tsconfig.cjs.json && echo '{\"type\": \"commonjs\"}' > lib/cjs/package.json",
40
+ "build:esm": "tsc -p tsconfig.esm.json && echo '{\"type\": \"module\"}' > lib/esm/package.json",
41
+ "build:types": "tsc -p tsconfig.types.json",
32
42
  "lint": "tslint src/*.ts* src/**/*.ts*",
33
43
  "test": "jest",
34
44
  "prepublish": "yarn lint && yarn test && yarn build",
@@ -43,7 +53,8 @@
43
53
  "author": "Dustin Callaway <drcallaway@gmail.com>",
44
54
  "license": "MIT",
45
55
  "files": [
46
- "lib"
56
+ "lib",
57
+ "src"
47
58
  ],
48
59
  "jest": {
49
60
  "transform": {
@@ -0,0 +1,10 @@
1
+ export default class TimeoutError extends Error {
2
+ public timeout: number;
3
+ public statusCode: number;
4
+
5
+ constructor(message: string, timeout: number, statusCode: number = 408) {
6
+ super(message);
7
+ this.timeout = timeout;
8
+ this.statusCode = statusCode;
9
+ }
10
+ }
package/src/cjs.ts ADDED
@@ -0,0 +1,4 @@
1
+ import TimeoutLink from "./timeoutLink";
2
+
3
+ module.exports = TimeoutLink;
4
+ module.exports.default = TimeoutLink;
@@ -0,0 +1,113 @@
1
+ import { ApolloLink, Observable, Operation, NextLink } from '@apollo/client/core';
2
+ import { DefinitionNode } from 'graphql';
3
+ import TimeoutError from './TimeoutError';
4
+
5
+ const DEFAULT_TIMEOUT: number = 15000;
6
+
7
+ /**
8
+ * Aborts the request if the timeout expires before the response is received.
9
+ */
10
+ export default class TimeoutLink extends ApolloLink {
11
+ private timeout: number;
12
+ private statusCode?: number;
13
+
14
+ constructor(timeout: number, statusCode?: number) {
15
+ super();
16
+ this.timeout = timeout || DEFAULT_TIMEOUT;
17
+ this.statusCode = statusCode;
18
+ }
19
+
20
+ public request(operation: Operation, forward: NextLink) {
21
+ let controller: AbortController;
22
+ let ourController: AbortController;
23
+
24
+ // override timeout from query context
25
+ const requestTimeout = operation.getContext().timeout || this.timeout;
26
+
27
+ // add abort controller and signal object to fetchOptions if they don't already exist
28
+ if (typeof AbortController !== 'undefined') {
29
+ const context = operation.getContext();
30
+ let fetchOptions = context.fetchOptions || {};
31
+
32
+ ourController = new AbortController();
33
+ controller = fetchOptions.controller || ourController;
34
+
35
+ fetchOptions = { ...fetchOptions, controller, signal: controller.signal };
36
+ operation.setContext({ fetchOptions });
37
+ }
38
+
39
+ const chainObservable = forward(operation); // observable for remaining link chain
40
+
41
+ const operationType = (operation.query.definitions as any).find(
42
+ (def: DefinitionNode) => def.kind === 'OperationDefinition'
43
+ ).operation;
44
+
45
+ if (requestTimeout <= 0 || operationType === 'subscription') {
46
+ return chainObservable; // skip this link if timeout is zero or it's a subscription request
47
+ }
48
+
49
+ // create local observable with timeout functionality (unsubscibe from chain observable and
50
+ // return an error if the timeout expires before chain observable resolves)
51
+ const localObservable = new Observable(observer => {
52
+ let timer: any;
53
+
54
+ // listen to chainObservable for result and pass to localObservable if received before timeout
55
+ const subscription = chainObservable.subscribe(
56
+ result => {
57
+ clearTimeout(timer);
58
+ observer.next(result);
59
+ observer.complete();
60
+ },
61
+ error => {
62
+ clearTimeout(timer);
63
+ observer.error(error);
64
+ observer.complete();
65
+ }
66
+ );
67
+
68
+ // if timeout expires before observable completes, abort call, unsubscribe, and return error
69
+ timer = setTimeout(() => {
70
+ if (controller) {
71
+ if (controller.signal.aborted) {
72
+ // already aborted from somewhere else
73
+ return;
74
+ }
75
+
76
+ controller.abort(); // abort fetch operation
77
+
78
+ // if the AbortController in the operation context is one we created,
79
+ // it's now "used up", so we need to remove it to avoid blocking any
80
+ // future retry of the operation.
81
+ const context = operation.getContext();
82
+ const fetchOptions = context.fetchOptions || {};
83
+ if(fetchOptions.controller === ourController && fetchOptions.signal === ourController.signal) {
84
+ operation.setContext({ ...fetchOptions, controller: undefined, signal: undefined });
85
+ }
86
+ }
87
+
88
+ observer.error(new TimeoutError('Timeout exceeded', requestTimeout, this.statusCode));
89
+ subscription.unsubscribe();
90
+ }, requestTimeout);
91
+
92
+ const cancelTimeout = () => {
93
+ clearTimeout(timer);
94
+ subscription.unsubscribe();
95
+ };
96
+
97
+ const ctxRef = operation.getContext().timeoutRef;
98
+ if (ctxRef) {
99
+ ctxRef({ unsubscribe: cancelTimeout });
100
+ }
101
+
102
+ // cancel timeout if aborted from somewhere else
103
+ controller.signal.addEventListener("abort", () => {
104
+ cancelTimeout();
105
+ }, { once: true });
106
+
107
+ // this function is called when a client unsubscribes from localObservable
108
+ return cancelTimeout;
109
+ });
110
+
111
+ return localObservable;
112
+ }
113
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"TimeoutError.js","sourceRoot":"","sources":["../src/TimeoutError.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA;IAA0C,gCAAK;IAI7C,sBAAY,OAAe,EAAE,OAAe,EAAE,UAAwB;QAAxB,2BAAA,EAAA,gBAAwB;QAAtE,YACE,kBAAM,OAAO,CAAC,SAGf;QAFC,KAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,KAAI,CAAC,UAAU,GAAG,UAAU,CAAC;;IAC/B,CAAC;IACH,mBAAC;AAAD,CAAC,AATD,CAA0C,KAAK,GAS9C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"timeoutLink.js","sourceRoot":"","sources":["../src/timeoutLink.ts"],"names":[],"mappings":"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"}
File without changes