From b2c73042587fa353f76f668104a55a1bdcdc080e Mon Sep 17 00:00:00 2001 From: Roxane Letourneau Date: Tue, 8 Jun 2021 14:11:14 -0700 Subject: [PATCH 1/4] docs(httpbackend): ability to cancel Http requests Example on how to extend the HttpBackend and RpcClient classes to cancel HTTP requests --- docs/cancel_http_requests.md | 125 ++++++++++++++++++ .../src/taquito-http-utils.ts | 26 ++-- packages/taquito-rpc/src/taquito-rpc.ts | 106 +++++++-------- website/package-lock.json | 13 ++ website/package.json | 3 +- website/sidebars.json | 5 + .../customHttpBackendAndRpcClient.ts | 115 ++++++++++++++++ website/src/theme/CodeBlock/index.js | 4 +- website/src/theme/Playground/index.js | 33 ++++- 9 files changed, 364 insertions(+), 66 deletions(-) create mode 100644 docs/cancel_http_requests.md create mode 100644 website/src/theme/CodeBlock/customHttpBackendAndRpcClient.ts diff --git a/docs/cancel_http_requests.md b/docs/cancel_http_requests.md new file mode 100644 index 0000000000..3719c8c744 --- /dev/null +++ b/docs/cancel_http_requests.md @@ -0,0 +1,125 @@ +--- +title: Cancel HTTP requests +author: Roxane Letourneau +--- + +Having Taquito implemented in composable modules is a design choice to allow users to customize the modules to meet some of their specific needs. + +One of these needs might be the ability to cancel HTTP requests to optimize the network. Indeed, Taquito has heavy methods that make a lot of requests to the RPC. For example, in some cases, users might want to cancel almost immediately a call when using it in interfaces. It is possible to incorporate some logic into the `HttpBackend` and `RpcClient` classes to fulfill this need. + +Here is an example in which we can click the `cancel` button during an estimation call to abort all requests. It will throw an exception. + +```js live noInline abort +const amount = 2; +const address = 'tz1h3rQ8wBxFd8L9B3d7Jhaawu6Z568XU3xY'; + +println(`Estimating the transfer of ${amount} ęś© to ${address} : `); +Tezos.estimate + .transfer({ to: address, amount: amount }) + .then((est) => { + println(`burnFeeMutez : ${est.burnFeeMutez}, + gasLimit : ${est.gasLimit}, + minimalFeeMutez : ${est.minimalFeeMutez}, + storageLimit : ${est.storageLimit}, + suggestedFeeMutez : ${est.suggestedFeeMutez}, + totalCost : ${est.totalCost}, + usingBaseFeeMutez : ${est.usingBaseFeeMutez}`); + }) + .catch((error) => println(`Error: ${JSON.stringify(error, null, 2)}`)); +``` + +Here are the steps that we implemented to built the precedent example: + +1. Create a custom `HttpBackend` +We created a class called `CancellableHttpBackend` which extended the `HttpBackend` class, and we overrode the `createRequest` method. We used the [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to help to abort the fetch requests. We added logic to the `createRequest` method to handle the abort signal. + +``` ts +import { HttpBackend, HttpRequestFailed, HttpResponseError, STATUS_CODE, HttpRequestOptions } from '@taquito/http-utils'; +import AbortController from "abort-controller"; + +class CancellableHttpBackend extends HttpBackend { + private abortCtrl: AbortController; + constructor(){ + super(); + this.abortCtrl = new AbortController(); + } + + cancelRequest(){ + this.abortCtrl.abort(); + }; + + createRequest( + { url, method, timeout, query, headers = {}, json = true, mimeType = undefined }: HttpRequestOptions, + data?: {} + ) { + return new Promise((resolve, reject) => { + + [...] + + request.onabort = function () { + reject( + new HttpResponseError( + `Request canceled`, + this.status as STATUS_CODE, + request.statusText, + request.response, + url + ) + ); + }; + + const abort = () => { + request.abort(); + } + + this.abortCtrl.signal.addEventListener("abort", abort); + + [...] + }); + } +} +``` + +2. Create a custom `RpcClient` +We created a class called `CancellableRpcClient` which extends the `RpcClient` class. We passed to its constructor an instance of our `CancellableHttpBackend` class. We also added a `cancelRequest` method which is used to trigger the abort signal. + +``` ts +import { RpcClient } from '@taquito/rpc'; + +class CancellableRpcClient extends RpcClient { + httpBackend: CancellableHttpBackend; + + constructor( + url: string, + chain: string = 'main', + customHttpBackend: CancellableHttpBackend = new CancellableHttpBackend() + ) { + super(url, chain, customHttpBackend), + this.httpBackend = customHttpBackend; + } + + cancelRequest(){ + this.httpBackend.cancelRequest(); + } +} +``` +3. Set the RpcProvider +Then, we set our `CancellableRpcClient` on our `TezosToolkit` instance instead of using the default `RpcClient` class: + +``` ts +import { TezosToolkit } from '@taquito/taquito'; +import { InMemorySigner } from '@taquito/signer'; + +const signer: any = new InMemorySigner('your_key'); +const customRpcClient = new CancellableRpcClient('your_RPC_URL') +const tezos = new TezosToolkit(customRpcClient); +tezos.setSignerProvider(signer); +``` + +4. Trigger the abort signal +We linked the `cancelRequest` method of the `CancellableRpcClient` class to a `cancel` button. The initiator of the abort signal might be different based on your use cases. Note that the cancelation action is not specific to a method in the example, meaning that all RPC calls will be aborted. + +``` ts +Tezos.rpc.cancelRequest(); +``` + diff --git a/packages/taquito-http-utils/src/taquito-http-utils.ts b/packages/taquito-http-utils/src/taquito-http-utils.ts index cb6b962679..6a491678ed 100644 --- a/packages/taquito-http-utils/src/taquito-http-utils.ts +++ b/packages/taquito-http-utils/src/taquito-http-utils.ts @@ -17,7 +17,7 @@ export { VERSION } from './version'; const defaultTimeout = 30000; -interface HttpRequestOptions { +export interface HttpRequestOptions { url: string; method?: 'GET' | 'POST'; timeout?: number; @@ -49,7 +49,7 @@ export class HttpRequestFailed implements Error { } export class HttpBackend { - private serialize(obj?: { [key: string]: any }) { + protected serialize(obj?: { [key: string]: any }) { if (!obj) { return ''; } @@ -67,7 +67,7 @@ export class HttpBackend { // another use case is multiple arguments with the same name // they are passed as array if (Array.isArray(prop)) { - prop.forEach(item => { + prop.forEach((item) => { str.push(encodeURIComponent(p) + '=' + encodeURIComponent(item)); }); continue; @@ -83,7 +83,7 @@ export class HttpBackend { } } - private createXHR(): XMLHttpRequest { + protected createXHR(): XMLHttpRequest { return new XMLHttpRequestCTOR(); } @@ -92,7 +92,15 @@ export class HttpBackend { * @param options contains options to be passed for the HTTP request (url, method and timeout) */ createRequest( - { url, method, timeout, query, headers = {}, json = true, mimeType = undefined}: HttpRequestOptions, + { + url, + method, + timeout, + query, + headers = {}, + json = true, + mimeType = undefined, + }: HttpRequestOptions, data?: {} ) { return new Promise((resolve, reject) => { @@ -101,14 +109,14 @@ export class HttpBackend { if (!headers['Content-Type']) { request.setRequestHeader('Content-Type', 'application/json'); } - if (mimeType){ + if (mimeType) { request.overrideMimeType(`${mimeType}`); } for (const k in headers) { request.setRequestHeader(k, headers[k]); } request.timeout = timeout || defaultTimeout; - request.onload = function() { + request.onload = function () { if (this.status >= 200 && this.status < 300) { if (json) { try { @@ -132,11 +140,11 @@ export class HttpBackend { } }; - request.ontimeout = function() { + request.ontimeout = function () { reject(new Error(`Request timed out after: ${request.timeout}ms`)); }; - request.onerror = function(err) { + request.onerror = function (err) { reject(new HttpRequestFailed(url, err)); }; diff --git a/packages/taquito-rpc/src/taquito-rpc.ts b/packages/taquito-rpc/src/taquito-rpc.ts index d450c185fd..f29f9b5120 100644 --- a/packages/taquito-rpc/src/taquito-rpc.ts +++ b/packages/taquito-rpc/src/taquito-rpc.ts @@ -73,10 +73,10 @@ export class RpcClient { * @example new RpcClient('https://api.tez.ie/rpc/mainnet', 'main') this will use https://api.tez.ie/rpc/mainnet/chains/main */ constructor( - private url: string, - private chain: string = defaultChain, - private httpBackend: HttpBackend = new HttpBackend() - ) { } + protected url: string, + protected chain: string = defaultChain, + protected httpBackend: HttpBackend = new HttpBackend() + ) {} private createURL(path: string) { // Trim trailing slashes because it is assumed to be included in path @@ -237,22 +237,22 @@ export class RpcClient { { block }: { block: string } = defaultRPCOptions ): Promise { let delegate: DelegateResponse; - try { + try { delegate = await this.httpBackend.createRequest({ url: this.createURL( `/chains/${this.chain}/blocks/${block}/context/contracts/${address}/delegate` ), method: 'GET', }); - } catch(ex) { + } catch (ex) { if (ex instanceof HttpResponseError && ex.status === STATUS_CODE.NOT_FOUND) { delegate = null; - } else { - throw ex; + } else { + throw ex; + } } + return delegate; } - return delegate -} /** * @@ -363,12 +363,12 @@ export class RpcClient { 'block_security_deposit', 'endorsement_security_deposit', 'block_reward', - 'endorsement_reward', + 'endorsement_reward', 'cost_per_byte', 'hard_storage_limit_per_operation', 'test_chain_duration', - 'baking_reward_per_endorsement', - 'delay_per_missing_endorsement' + 'baking_reward_per_endorsement', + 'delay_per_missing_endorsement', ]); return { @@ -513,14 +513,14 @@ export class RpcClient { * @param options contains generic configuration for rpc calls * * @description Current period kind. - * + * * @deprecated Deprecated in favor of getCurrentPeriod * * @see https://tezos.gitlab.io/api/rpc.html#get-block-id-votes-current-period-kind */ - async getCurrentPeriodKind({ block }: RPCOptions = defaultRPCOptions): Promise< - PeriodKindResponse - > { + async getCurrentPeriodKind({ + block, + }: RPCOptions = defaultRPCOptions): Promise { const response = await this.httpBackend.createRequest({ url: this.createURL(`/chains/${this.chain}/blocks/${block}/votes/current_period_kind`), method: 'GET', @@ -537,9 +537,9 @@ export class RpcClient { * * @see https://tezos.gitlab.io/api/rpc.html#get-block-id-votes-current-proposal */ - async getCurrentProposal({ block }: RPCOptions = defaultRPCOptions): Promise< - CurrentProposalResponse - > { + async getCurrentProposal({ + block, + }: RPCOptions = defaultRPCOptions): Promise { const response = await this.httpBackend.createRequest({ url: this.createURL(`/chains/${this.chain}/blocks/${block}/votes/current_proposal`), method: 'GET', @@ -556,9 +556,9 @@ export class RpcClient { * * @see https://tezos.gitlab.io/api/rpc.html#get-block-id-votes-current-quorum */ - async getCurrentQuorum({ block }: RPCOptions = defaultRPCOptions): Promise< - CurrentQuorumResponse - > { + async getCurrentQuorum({ + block, + }: RPCOptions = defaultRPCOptions): Promise { const response = await this.httpBackend.createRequest({ url: this.createURL(`/chains/${this.chain}/blocks/${block}/votes/current_quorum`), method: 'GET', @@ -575,9 +575,9 @@ export class RpcClient { * * @see https://tezos.gitlab.io/api/rpc.html#get-block-id-votes-listings */ - async getVotesListings({ block }: RPCOptions = defaultRPCOptions): Promise< - VotesListingsResponse - > { + async getVotesListings({ + block, + }: RPCOptions = defaultRPCOptions): Promise { const response = await this.httpBackend.createRequest({ url: this.createURL(`/chains/${this.chain}/blocks/${block}/votes/listings`), method: 'GET', @@ -781,7 +781,7 @@ export class RpcClient { */ getRpcUrl() { - return this.url + return this.url; } /** @@ -789,40 +789,40 @@ export class RpcClient { * @param options contains generic configuration for rpc calls * * @description Voting period of current block. - * + * * @example getCurrentPeriod() will default to current voting period for /main/chains/block/head. * * @see https://tezos.gitlab.io/api/rpc.html#get-block-id-votes-current-period */ - async getCurrentPeriod({ block }: RPCOptions = defaultRPCOptions): Promise< - VotingPeriodBlockResult - > { - const response = await this.httpBackend.createRequest({ - url: this.createURL(`/chains/${this.chain}/blocks/${block}/votes/current_period`), - method: 'GET', - }); - - return response; - } - - /** - * - * @param options contains generic configuration for rpc calls - * - * @description Voting period of next block. - * - * @example getSuccessorPeriod() will default to successor voting period for /main/chains/block/head. - * - * @see https://tezos.gitlab.io/api/rpc.html#get-block-id-votes-successor-period - */ - async getSuccessorPeriod({ block }: RPCOptions = defaultRPCOptions): Promise< - VotingPeriodBlockResult - > { + async getCurrentPeriod({ + block, + }: RPCOptions = defaultRPCOptions): Promise { + const response = await this.httpBackend.createRequest({ + url: this.createURL(`/chains/${this.chain}/blocks/${block}/votes/current_period`), + method: 'GET', + }); + + return response; + } + + /** + * + * @param options contains generic configuration for rpc calls + * + * @description Voting period of next block. + * + * @example getSuccessorPeriod() will default to successor voting period for /main/chains/block/head. + * + * @see https://tezos.gitlab.io/api/rpc.html#get-block-id-votes-successor-period + */ + async getSuccessorPeriod({ + block, + }: RPCOptions = defaultRPCOptions): Promise { const response = await this.httpBackend.createRequest({ url: this.createURL(`/chains/${this.chain}/blocks/${block}/votes/successor_period`), method: 'GET', }); - + return response; } } diff --git a/website/package-lock.json b/website/package-lock.json index dd4552ef16..02ebfc3791 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -2888,6 +2888,14 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -5604,6 +5612,11 @@ "require-like": ">= 0.1.1" } }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", diff --git a/website/package.json b/website/package.json index 062d159e67..4b6b1751bd 100644 --- a/website/package.json +++ b/website/package.json @@ -19,14 +19,15 @@ "@ledgerhq/hw-transport-u2f": "^5.28.0", "@taquito/beacon-wallet": "^9.1.0", "@taquito/ledger-signer": "^9.1.0", + "@taquito/michelson-encoder": "^9.1.0", "@taquito/signer": "^9.1.0", "@taquito/taquito": "^9.1.0", "@taquito/tezbridge-wallet": "^9.1.0", "@taquito/tzip12": "^9.1.0", "@taquito/tzip16": "^9.1.0", "@taquito/utils": "^9.1.0", - "@taquito/michelson-encoder": "^9.1.0", "@thanos-wallet/dapp": "^2.2.1", + "abort-controller": "^3.0.0", "classnames": "^2.2.6", "react": "^17.0.1", "react-dom": "^17.0.1" diff --git a/website/sidebars.json b/website/sidebars.json index a82b594b9f..c499852437 100755 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -42,6 +42,11 @@ "label": "Advanced", "items": ["complex_parameters", "storage_annotations", "drain_account"] }, + { + "type": "category", + "label": "Modules customization", + "items": ["cancel_http_requests"] + }, { "type": "category", "label": "Running integration tests", diff --git a/website/src/theme/CodeBlock/customHttpBackendAndRpcClient.ts b/website/src/theme/CodeBlock/customHttpBackendAndRpcClient.ts new file mode 100644 index 0000000000..3074725b7f --- /dev/null +++ b/website/src/theme/CodeBlock/customHttpBackendAndRpcClient.ts @@ -0,0 +1,115 @@ +import { HttpBackend, HttpRequestFailed, HttpResponseError, STATUS_CODE, HttpRequestOptions } from '@taquito/http-utils'; +import { RpcClient } from '@taquito/rpc'; +import AbortController from "abort-controller"; + +const defaultTimeout = 30000; + +class CancellableHttpBackend extends HttpBackend { + private abortCtrl: AbortController; + constructor() { + super(), + this.abortCtrl = new AbortController(); + } + + resetAbortCtrl() { + this.abortCtrl = new AbortController(); + } + + cancelRequest() { + this.abortCtrl.abort(); + }; + + createRequest( + { url, method, timeout, query, headers = {}, json = true, mimeType = undefined }: HttpRequestOptions, + data?: {} + ) { + return new Promise((resolve, reject) => { + const request = this.createXHR(); + request.open(method || 'GET', `${url}${this.serialize(query)}`); + if (!headers['Content-Type']) { + request.setRequestHeader('Content-Type', 'application/json'); + } + if (mimeType) { + request.overrideMimeType(`${mimeType}`); + } + for (const k in headers) { + request.setRequestHeader(k, headers[k]); + } + request.timeout = timeout || defaultTimeout; + request.onload = function () { + if (this.status >= 200 && this.status < 300) { + if (json) { + try { + resolve(JSON.parse(request.response)); + } catch (ex) { + reject(new Error(`Unable to parse response: ${request.response}`)); + } + } else { + resolve(request.response); + } + } else { + reject( + new HttpResponseError( + `Http error response: (${this.status}) ${request.response}`, + this.status as STATUS_CODE, + request.statusText, + request.response, + url + ) + ); + } + }; + + request.ontimeout = function () { + reject(new Error(`Request timed out after: ${request.timeout}ms`)); + }; + + request.onerror = function (err) { + reject(new HttpRequestFailed(url, err)); + }; + + request.onabort = function () { + reject( + new HttpResponseError( + `Request canceled`, + this.status as STATUS_CODE, + request.statusText, + request.response, + url + ) + ); + }; + + const abort = () => { + request.abort(); + this.resetAbortCtrl(); + } + + this.abortCtrl.signal.addEventListener("abort", abort); + + if (data) { + const dataStr = JSON.stringify(data); + request.send(dataStr); + } else { + request.send(); + } + }); + } +} + +export class CancellableRpcClient extends RpcClient { + httpBackend: CancellableHttpBackend; + + constructor( + url: string, + chain: string = 'main', + cancellableHttpBackend: CancellableHttpBackend = new CancellableHttpBackend() + ) { + super(url, chain, cancellableHttpBackend); + this.httpBackend = cancellableHttpBackend; + } + + cancelRequest() { + this.httpBackend.cancelRequest(); + } +} diff --git a/website/src/theme/CodeBlock/index.js b/website/src/theme/CodeBlock/index.js index 3241e370a6..51175b6d87 100755 --- a/website/src/theme/CodeBlock/index.js +++ b/website/src/theme/CodeBlock/index.js @@ -34,6 +34,7 @@ import rangeParser from 'parse-numeric-range'; import Highlight, { defaultProps } from 'prism-react-renderer'; import defaultTheme from 'prism-react-renderer/themes/palenight'; import React, { useEffect, useRef, useState } from 'react'; +import { CancellableRpcClient } from './customHttpBackendAndRpcClient'; import styles from './styles.module.css'; @@ -79,7 +80,8 @@ export default ({ }, [button.current, target.current]); if (live) { - const Tezos = new TezosToolkit('https://api.tez.ie/rpc/florencenet'); + const customRpcClient = new CancellableRpcClient('https://api.tez.ie/rpc/florencenet') + const Tezos = new TezosToolkit(customRpcClient); const wallet = new BeaconWallet({name:"exampleWallet"}); return ( diff --git a/website/src/theme/Playground/index.js b/website/src/theme/Playground/index.js index 4264e219f1..2042b03e26 100755 --- a/website/src/theme/Playground/index.js +++ b/website/src/theme/Playground/index.js @@ -46,8 +46,6 @@ function println(value) { render(_printlnBuffer); } -Tezos.setProvider({ rpc: 'https://api.tez.ie/rpc/florencenet' }); - ${this.props.wallet ? `const network = {type:"florencenet"}; wallet.requestPermissions({network}) @@ -158,6 +156,22 @@ const managerCode = [{"prim": "parameter","args":[{"prim": "or","args":[{"prim": this.transpile({ code, scope, transformCode, noInline }); } + + cancel() { + const { scope, transformCode, noInline } = this.props; + const code =` + let _printlnBuffer = ""; + + function println(value) { + _printlnBuffer += value + "\\n"; + + render(_printlnBuffer); + } + Tezos.rpc.cancelRequest(); + ` + this.transpile({ code, scope, transformCode, noInline }); + + } } function Playground({ children, theme, transformCode, ...props }) { @@ -185,6 +199,10 @@ function Playground({ children, theme, transformCode, ...props }) { live.current && live.current.run(); }; + const cancelRunCode = () => { + live.current && live.current.cancel(); + }; + const handleCopyCode = () => { window.getSelection().empty(); setShowCopied(true); @@ -237,6 +255,17 @@ function Playground({ children, theme, transformCode, ...props }) { onClick={handleRunCode}> Run code + {props.abort ? + :""}
From cc2bdafdcc74ec9085d5a8d331b04a7f392332d9 Mon Sep 17 00:00:00 2001 From: Roxane Letourneau Date: Tue, 8 Jun 2021 14:55:36 -0700 Subject: [PATCH 2/4] added http-utils and rpc packages --- website/package.json | 2 ++ website/yarn.lock | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/website/package.json b/website/package.json index 4b6b1751bd..0bb719bf20 100644 --- a/website/package.json +++ b/website/package.json @@ -26,6 +26,8 @@ "@taquito/tzip12": "^9.1.0", "@taquito/tzip16": "^9.1.0", "@taquito/utils": "^9.1.0", + "@taquito/http-utils": "^9.1.0", + "@taquito/rpc": "^9.1.0", "@thanos-wallet/dapp": "^2.2.1", "abort-controller": "^3.0.0", "classnames": "^2.2.6", diff --git a/website/yarn.lock b/website/yarn.lock index 91986f1307..afb0f5be17 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -2276,6 +2276,13 @@ resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz" @@ -4567,6 +4574,11 @@ eval@^0.1.4: dependencies: require-like ">= 0.1.1" +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" From 0e76ab245e96496f6492f4bc81c2fd1bec69427c Mon Sep 17 00:00:00 2001 From: Roxane Letourneau Date: Tue, 8 Jun 2021 21:18:06 -0700 Subject: [PATCH 3/4] Correction doc --- docs/cancel_http_requests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cancel_http_requests.md b/docs/cancel_http_requests.md index 3719c8c744..39ebf0e6cb 100644 --- a/docs/cancel_http_requests.md +++ b/docs/cancel_http_requests.md @@ -5,7 +5,7 @@ author: Roxane Letourneau Having Taquito implemented in composable modules is a design choice to allow users to customize the modules to meet some of their specific needs. -One of these needs might be the ability to cancel HTTP requests to optimize the network. Indeed, Taquito has heavy methods that make a lot of requests to the RPC. For example, in some cases, users might want to cancel almost immediately a call when using it in interfaces. It is possible to incorporate some logic into the `HttpBackend` and `RpcClient` classes to fulfill this need. +One of these needs might be the ability to cancel HTTP requests to optimize the network. Indeed, Taquito has heavy methods that make a lot of requests to the RPC. For example, in some cases, users might want to cancel almost immediately a call when using it in user interfaces. It is possible to incorporate some logic into the `HttpBackend` and `RpcClient` classes to fulfill this need. Here is an example in which we can click the `cancel` button during an estimation call to abort all requests. It will throw an exception. From 5e04d026b723fd22615645c23da62aef286dac8f Mon Sep 17 00:00:00 2001 From: Roxane Letourneau Date: Tue, 8 Jun 2021 21:41:57 -0700 Subject: [PATCH 4/4] Fix typo --- .../src/theme/CodeBlock/customHttpBackendAndRpcClient.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/src/theme/CodeBlock/customHttpBackendAndRpcClient.ts b/website/src/theme/CodeBlock/customHttpBackendAndRpcClient.ts index 3074725b7f..dd62e2e411 100644 --- a/website/src/theme/CodeBlock/customHttpBackendAndRpcClient.ts +++ b/website/src/theme/CodeBlock/customHttpBackendAndRpcClient.ts @@ -7,8 +7,8 @@ const defaultTimeout = 30000; class CancellableHttpBackend extends HttpBackend { private abortCtrl: AbortController; constructor() { - super(), - this.abortCtrl = new AbortController(); + super(); + this.abortCtrl = new AbortController(); } resetAbortCtrl() { @@ -106,7 +106,7 @@ export class CancellableRpcClient extends RpcClient { cancellableHttpBackend: CancellableHttpBackend = new CancellableHttpBackend() ) { super(url, chain, cancellableHttpBackend); - this.httpBackend = cancellableHttpBackend; + this.httpBackend = cancellableHttpBackend; } cancelRequest() {