Skip to content
This repository has been archived by the owner on Apr 6, 2020. It is now read-only.

Commit

Permalink
Import callbackify
Browse files Browse the repository at this point in the history
  • Loading branch information
alcuadrado committed Jun 28, 2019
1 parent 977b67d commit 3783ed4
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 10 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@
"level-mem": "^3.0.1",
"lru-cache": "^5.1.1",
"rlp": "^2.2.2",
"semaphore": "^1.1.0",
"util": "^0.12.0"
"semaphore": "^1.1.0"
},
"devDependencies": {
"@ethereumjs/config-nyc": "^1.1.1",
Expand Down
77 changes: 77 additions & 0 deletions src/callbackify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

function callbackifyOnRejected(reason: any, cb: any) {
// `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).
// Because `null` is a special error value in callbacks which means "no error
// occurred", we error-wrap so the callback consumer can distinguish between
// "the promise rejected with null" or "the promise fulfilled with undefined".
if (!reason) {
const newReason = new Error('Promise was rejected with a falsy value') as any
newReason.reason = reason
reason = newReason
}
return cb(reason)
}

export function callbackify(original: any): any {
if (typeof original !== 'function') {
throw new TypeError('The "original" argument must be of type Function')
}

// We DO NOT return the promise as it gives the user a false sense that
// the promise is actually somehow related to the callback's execution
// and that the callback throwing will reject the promise.
function callbackified(this: any) {
const args = []
for (let i = 0; i < arguments.length; i++) {
args.push(arguments[i])
}

const maybeCb = args.pop()
if (typeof maybeCb !== 'function') {
throw new TypeError('The last argument must be of type Function')
}

//tslint:disable-next-line no-invalid-this
const self = this
const cb = function() {
return maybeCb.apply(self, arguments)
}

// In true node style we process the callback on `nextTick` with all the
// implications (stack, `uncaughtException`, `async_hooks`)
//tslint:disable-next-line no-invalid-this
original.apply(this, args).then(
function(ret: any) {
process.nextTick(cb.bind(null, null, ret))
},
function(rej: any) {
process.nextTick(callbackifyOnRejected.bind(null, rej, cb))
},
)
}

Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original))
Object.defineProperties(callbackified, Object.getOwnPropertyDescriptors(original))

return callbackified
}
16 changes: 8 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as async from 'async'
import { BN, rlp } from 'ethereumjs-util'
import Common from 'ethereumjs-common'
import * as util from 'util'
import { callbackify } from './callbackify'
import DBManager from './dbManager'
import {
bodyKey,
Expand Down Expand Up @@ -175,7 +175,7 @@ export default class Blockchain {
const self = this

async.waterfall(
[(cb: any) => self._numberToHash(new BN(0), cb), util.callbackify(getHeads.bind(this))],
[(cb: any) => self._numberToHash(new BN(0), cb), callbackify(getHeads.bind(this))],
err => {
if (err) {
// if genesis block doesn't exist, create one
Expand Down Expand Up @@ -552,7 +552,7 @@ export default class Blockchain {
* @hidden
*/
_getBlock(blockTag: Buffer | number | BN, cb: any) {
util.callbackify(this.dbManager.getBlock.bind(this.dbManager))(blockTag, cb)
callbackify(this.dbManager.getBlock.bind(this.dbManager))(blockTag, cb)
}

/**
Expand Down Expand Up @@ -1004,7 +1004,7 @@ export default class Blockchain {
* @hidden
*/
_batchDbOps(dbOps: any, cb: any): void {
util.callbackify(this.dbManager.batch.bind(this.dbManager))(dbOps, cb)
callbackify(this.dbManager.batch.bind(this.dbManager))(dbOps, cb)
}

/**
Expand All @@ -1013,7 +1013,7 @@ export default class Blockchain {
* @hidden
*/
_hashToNumber(hash: Buffer, cb: any): void {
util.callbackify(this.dbManager.hashToNumber.bind(this.dbManager))(hash, cb)
callbackify(this.dbManager.hashToNumber.bind(this.dbManager))(hash, cb)
}

/**
Expand All @@ -1022,7 +1022,7 @@ export default class Blockchain {
* @hidden
*/
_numberToHash(number: BN, cb: any): void {
util.callbackify(this.dbManager.numberToHash.bind(this.dbManager))(number, cb)
callbackify(this.dbManager.numberToHash.bind(this.dbManager))(number, cb)
}

/**
Expand Down Expand Up @@ -1057,7 +1057,7 @@ export default class Blockchain {
if (err) {
return cb(err)
}
util.callbackify(this.dbManager.getHeader.bind(this.dbManager))(hash, number, cb)
callbackify(this.dbManager.getHeader.bind(this.dbManager))(hash, number, cb)
},
)
}
Expand Down Expand Up @@ -1090,7 +1090,7 @@ export default class Blockchain {
if (err) {
return cb(err)
}
util.callbackify(this.dbManager.getTd.bind(this.dbManager))(hash, number, cb)
callbackify(this.dbManager.getTd.bind(this.dbManager))(hash, number, cb)
},
)
}
Expand Down

0 comments on commit 3783ed4

Please sign in to comment.