Skip to content

Commit

Permalink
Merge pull request #312 from bigchaindb/fet-improve-requests
Browse files Browse the repository at this point in the history
feat: improve requests
  • Loading branch information
getlarge authored Feb 17, 2022
2 parents 1864f6f + 7a12ee7 commit f9a4675
Show file tree
Hide file tree
Showing 17 changed files with 203 additions and 114 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ module.exports = {
],
},
],

'import/no-extraneous-dependencies': ['error', { 'devDependencies': true }],
/**
* ES6-specific Issues
* (http://eslint.org/docs/rules/#ecmascript-6)
Expand Down
11 changes: 7 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ jobs:
restore-keys: |
${{ runner.os }}-node-
- name: Run BigChainDB node
run: |
echo Building and starting up docker containers
docker-compose -f ./docker-compose.yml up -d
- name: Install dependencies
env:
HUSKY_SKIP_INSTALL: 'true'
Expand All @@ -56,10 +61,8 @@ jobs:
- name: Build
run: npm run build

- name: Build docker
run: |
echo Building and starting up docker containers
docker-compose -f ./docker-compose.yml up
# ensure BCDB node is up and running
- run: sleep 20

- name: Test
run: npm run test
66 changes: 33 additions & 33 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"sideEffects": false,
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"build": "npm run clean && npm run build:cjs && npm run build:dist",
"build:bundle": "webpack",
"build:cjs": "cross-env BABEL_ENV=cjs babel ./src -d dist/node",
Expand All @@ -36,55 +37,54 @@
"doc": "documentation build src/index.js -f md -o API.md -g --markdown-toc"
},
"devDependencies": {
"@ava/babel": "^1.0.1",
"@babel/cli": "^7.13.0",
"@babel/core": "^7.13.8",
"@babel/eslint-parser": "^7.13.8",
"@babel/plugin-proposal-export-default-from": "^7.12.13",
"@babel/plugin-proposal-object-rest-spread": "^7.13.8",
"@ava/babel": "^2.0.0",
"@babel/cli": "^7.17.0",
"@babel/core": "^7.17.2",
"@babel/eslint-parser": "^7.17.0",
"@babel/plugin-proposal-export-default-from": "^7.16.7",
"@babel/plugin-proposal-object-rest-spread": "^7.16.7",
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/plugin-transform-async-to-generator": "^7.13.0",
"@babel/plugin-transform-object-assign": "^7.12.13",
"@babel/plugin-transform-regenerator": "^7.12.13",
"@babel/plugin-transform-runtime": "^7.13.9",
"@babel/preset-env": "^7.13.9",
"@babel/register": "^7.13.8",
"@babel/plugin-transform-async-to-generator": "^7.16.8",
"@babel/plugin-transform-object-assign": "^7.16.7",
"@babel/plugin-transform-regenerator": "^7.16.7",
"@babel/plugin-transform-runtime": "^7.17.0",
"@babel/preset-env": "^7.16.11",
"@babel/register": "^7.17.0",
"ava": "^3.15.0",
"babel-loader": "^8.2.2",
"buffer": "^6.0.3",
"codecov": "^3.8.1",
"cross-env": "^7.0.3",
"documentation": "^13.1.1",
"eslint": "^7.21.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1",
"husky": "^5.1.3",
"lint-staged": "^10.5.4",
"documentation": "^13.2.5",
"eslint": "^8.9.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.25.4",
"husky": "^7.0.4",
"lint-staged": "^12.3.4",
"nyc": "^15.1.0",
"release-it": "^14.4.1",
"rewire": "^4.0.1",
"release-it": "^14.12.4",
"rewire": "^6.0.0",
"rimraf": "^3.0.2",
"sinon": "^7.3.2",
"terser-webpack-plugin": "^4.2.3",
"webpack": "^4.46.0",
"webpack-cli": "^4.5.0",
"webpack-concat-plugin": "^3.0.0",
"webpack-merge": "^5.7.3",
"webpack-sources": "^2.2.0"
"sinon": "^13.0.1",
"terser-webpack-plugin": "^5.3.1",
"webpack": "^5.68.0",
"webpack-cli": "^4.9.2",
"webpack-merge": "^5.8.0",
"webpack-sources": "^3.2.3"
},
"dependencies": {
"@babel/runtime-corejs3": "^7.13.9",
"browser-resolve": "^1.11.3",
"@babel/runtime-corejs3": "^7.17.2",
"abort-controller": "^3.0.0",
"bs58": "^4.0.1",
"buffer": "^6.0.3",
"clone": "^2.1.2",
"core-js": "^3.9.1",
"crypto-conditions": "2.1.2",
"core-js": "^3.21.0",
"crypto-conditions": "2.2.1",
"decamelize": "^5.0.0",
"es6-promise": "^4.2.8",
"fetch-ponyfill": "^7.1.0",
"js-sha3": "^0.8.0",
"json-stable-stringify": "^1.0.1",
"query-string": "^6.14.1",
"query-string": "^7.1.1",
"sprintf-js": "^1.1.2",
"tweetnacl": "^1.0.3"
},
Expand Down
59 changes: 41 additions & 18 deletions src/baseRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
// Code is Apache-2.0 and docs are CC-BY-4.0

// TODO: remove abort-controller when using Node >=15
import AbortController from 'abort-controller'
import { Promise } from 'es6-promise'
import fetchPonyfill from 'fetch-ponyfill'
import { vsprintf } from 'sprintf-js'

import formatText from './format_text'
import stringifyAsQueryParam from './stringify_as_query_param'

const fetch = fetchPonyfill(Promise)
const fetch = fetchPonyfill({ Promise })

export function ResponseError(message, status, requestURI) {
this.name = 'ResponseError'
this.message = message
this.status = status
this.requestURI = requestURI
this.stack = (new Error()).stack
this.stack = new Error().stack
}

ResponseError.prototype = new Error()
Expand All @@ -26,17 +28,27 @@ ResponseError.prototype = new Error()
* Timeout function following https://github.com/github/fetch/issues/175#issuecomment-284787564
* @param {integer} obj Source object
* @param {Promise} filter Array of key names to select or function to invoke per iteration
* @param {AbortController} controller AbortController instance bound to fetch
* @return {Object} TimeoutError if the time was consumed, otherwise the Promise will be resolved
*/
function timeout(ms, promise) {
function timeout(ms, promise, controller) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const nodeTimeout = setTimeout(() => {
controller.abort()
const errorObject = {
message: 'TimeoutError'
message: 'TimeoutError',
}
reject(new Error(errorObject))
}, ms)
promise.then(resolve, reject)
promise
.then((res) => {
clearTimeout(nodeTimeout)
resolve(res)
})
.catch((err) => {
clearTimeout(nodeTimeout)
reject(err)
})
})
}

Expand Down Expand Up @@ -88,25 +100,30 @@ function handleResponse(res) {
* @return {Promise} If requestTimeout the timeout function will be called. Otherwise resolve the
* Promise with the handleResponse function
*/
export default function baseRequest(url, {
jsonBody,
query,
urlTemplateSpec,
...fetchConfig
} = {}, requestTimeout) {
export default function baseRequest(
url,
{
jsonBody, query, urlTemplateSpec, ...fetchConfig
} = {},
requestTimeout = 0
) {
let expandedUrl = url

if (urlTemplateSpec != null) {
if (Array.isArray(urlTemplateSpec) && urlTemplateSpec.length) {
// Use vsprintf for the array call signature
expandedUrl = vsprintf(url, urlTemplateSpec)
} else if (urlTemplateSpec &&
} else if (
urlTemplateSpec &&
typeof urlTemplateSpec === 'object' &&
Object.keys(urlTemplateSpec).length) {
Object.keys(urlTemplateSpec).length
) {
expandedUrl = formatText(url, urlTemplateSpec)
} else if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.warn('Supplied urlTemplateSpec was not an array or object. Ignoring...')
console.warn(
'Supplied urlTemplateSpec was not an array or object. Ignoring...'
)
}
}

Expand All @@ -124,11 +141,17 @@ export default function baseRequest(url, {
if (jsonBody != null) {
fetchConfig.body = JSON.stringify(jsonBody)
}

if (requestTimeout) {
return timeout(requestTimeout, fetch.fetch(expandedUrl, fetchConfig))
const controller = new AbortController()
const { signal } = controller
return timeout(
requestTimeout,
fetch.fetch(expandedUrl, { ...fetchConfig, signal }),
controller
)
.then(handleResponse)
} else {
return fetch.fetch(expandedUrl, fetchConfig)
.then(handleResponse)
return fetch.fetch(expandedUrl, fetchConfig).then(handleResponse)
}
}
10 changes: 6 additions & 4 deletions src/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,21 +178,23 @@ export default class Connection {
/**
* @param search
*/
searchAssets(search) {
searchAssets(search, limit = 10) {
return this._req(Connection.getApiUrls('assets'), {
query: {
search
search,
limit
}
})
}

/**
* @param search
*/
searchMetadata(search) {
searchMetadata(search, limit = 10) {
return this._req(Connection.getApiUrls('metadata'), {
query: {
search
search,
limit
}
})
}
Expand Down
6 changes: 4 additions & 2 deletions src/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default class Request {

const requestTimeout = timeout ? timeout - backoffTimedelta : timeout
return baseRequest(apiUrl, requestConfig, requestTimeout)
.then(async (res) => {
.then((res) => {
this.connectionError = null
return res.json()
})
Expand Down Expand Up @@ -111,6 +111,8 @@ export default class Request {
}

static sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
return new Promise(resolve => {
setTimeout(resolve, ms)
})
}
}
1 change: 0 additions & 1 deletion src/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
// Code is Apache-2.0 and docs are CC-BY-4.0

import { Buffer } from 'buffer'
import stableStringify from 'json-stable-stringify'
import clone from 'clone'
import base58 from 'bs58'
Expand Down
4 changes: 2 additions & 2 deletions test/connection/test_connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ test('Get asset for text', t => {
conn.searchAssets(search)
t.truthy(conn._req.calledWith(
expectedPath,
{ query: { search } }
{ query: { search, limit: 10 } }
))
})

Expand All @@ -239,6 +239,6 @@ test('Get metadata for text', t => {
conn.searchMetadata(search)
t.truthy(conn._req.calledWith(
expectedPath,
{ query: { search } }
{ query: { search, limit: 10 } }
))
})
3 changes: 2 additions & 1 deletion test/transaction/test_cryptoconditions.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ test('Fulfillment correctly formed', t => {
const msgHash = sha256Hash(msgUniqueFulfillment)

t.truthy(validateFulfillment(
txSigned.inputs[0].fulfillment, txCreate.outputs[0].condition.uri,
txSigned.inputs[0].fulfillment,
txCreate.outputs[0].condition.uri,
Buffer.from(msgHash, 'hex')
))
})
Expand Down
Loading

0 comments on commit f9a4675

Please sign in to comment.