mirror of
https://github.com/zkitter/json-rpc-engine.git
synced 2026-01-10 07:37:54 -05:00
Remove promise-to-callback, reimplement createAsyncMiddleware (#46)
* remove promise-to-callback, reimplement createAsyncMiddleware * fix middleware plural copy
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"eth-rpc-errors": "^2.1.1",
|
||||
"promise-to-callback": "^1.0.0",
|
||||
"safe-event-emitter": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,39 +1,60 @@
|
||||
const promiseToCallback = require('promise-to-callback')
|
||||
/**
|
||||
* JsonRpcEngine only accepts callback-based middleware directly.
|
||||
* createAsyncMiddleware exists to enable consumers to pass in async middleware
|
||||
* functions.
|
||||
*
|
||||
* Async middleware have no "end" function. Instead, they "end" if they return
|
||||
* without calling "next". Rather than passing in explicit return handlers,
|
||||
* async middleware can simply await "next", and perform operations on the
|
||||
* response object when execution resumes.
|
||||
*
|
||||
* To accomplish this, createAsyncMiddleware passes the async middleware a
|
||||
* wrapped "next" function. That function calls the internal JsonRpcEngine
|
||||
* "next" function with a return handler that resolves a promise when called.
|
||||
*
|
||||
* The return handler will always be called. Its resolution of the promise
|
||||
* enables the control flow described above.
|
||||
*/
|
||||
|
||||
module.exports = function createAsyncMiddleware (asyncMiddleware) {
|
||||
return (req, res, next, end) => {
|
||||
let nextDonePromise = null
|
||||
const finishedPromise = asyncMiddleware(req, res, getNextPromise)
|
||||
promiseToCallback(finishedPromise)((err) => {
|
||||
// async middleware ended
|
||||
if (nextDonePromise) {
|
||||
// next handler was called - complete nextHandler
|
||||
promiseToCallback(nextDonePromise)((nextErr, nextHandlerSignalDone) => {
|
||||
// nextErr is only present if something went really wrong
|
||||
// if an error is thrown after `await next()` it appears as `err` and not `nextErr`
|
||||
if (nextErr) {
|
||||
console.error(nextErr)
|
||||
return end(nextErr)
|
||||
}
|
||||
nextHandlerSignalDone(err)
|
||||
return undefined
|
||||
})
|
||||
} else {
|
||||
// next handler was not called - complete middleware
|
||||
end(err)
|
||||
}
|
||||
|
||||
// nextPromise is the key to the implementation
|
||||
// it is resolved by the return handler passed to the
|
||||
// "next" function
|
||||
let resolveNextPromise
|
||||
const nextPromise = new Promise((resolve) => {
|
||||
resolveNextPromise = resolve
|
||||
})
|
||||
|
||||
async function getNextPromise () {
|
||||
nextDonePromise = getNextDoneCallback()
|
||||
await nextDonePromise
|
||||
return undefined
|
||||
let returnHandlerCallback, nextWasCalled
|
||||
|
||||
const asyncNext = async () => {
|
||||
|
||||
nextWasCalled = true
|
||||
|
||||
next((callback) => { // eslint-disable-line callback-return
|
||||
returnHandlerCallback = callback
|
||||
resolveNextPromise()
|
||||
})
|
||||
await nextPromise
|
||||
}
|
||||
|
||||
function getNextDoneCallback () {
|
||||
return new Promise((resolve) => {
|
||||
next((cb) => resolve(cb))
|
||||
asyncMiddleware(req, res, asyncNext)
|
||||
.then(async () => {
|
||||
if (nextWasCalled) {
|
||||
await nextPromise // we must wait until the return handler is called
|
||||
returnHandlerCallback(null)
|
||||
} else {
|
||||
end(null)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
if (returnHandlerCallback) {
|
||||
returnHandlerCallback(error)
|
||||
} else {
|
||||
end(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ describe('createAsyncMiddleware tests', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('doesnt await next', function (done) {
|
||||
it('doesn\'t await next', function (done) {
|
||||
const engine = new RpcEngine()
|
||||
|
||||
engine.push(createAsyncMiddleware(async (_req, _res, next) => {
|
||||
|
||||
26
yarn.lock
26
yarn.lock
@@ -1131,11 +1131,6 @@ is-extglob@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||
|
||||
is-fn@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c"
|
||||
integrity sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=
|
||||
|
||||
is-fullwidth-code-point@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
|
||||
@@ -1778,14 +1773,6 @@ progress@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||
|
||||
promise-to-callback@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7"
|
||||
integrity sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=
|
||||
dependencies:
|
||||
is-fn "^1.0.0"
|
||||
set-immediate-shim "^1.0.1"
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
@@ -1934,10 +1921,15 @@ set-blocking@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||
|
||||
set-immediate-shim@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
|
||||
integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=
|
||||
set-value@^2.0.0, set-value@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
|
||||
integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==
|
||||
dependencies:
|
||||
extend-shallow "^2.0.1"
|
||||
is-extendable "^0.1.1"
|
||||
is-plain-object "^2.0.3"
|
||||
split-string "^3.0.1"
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
|
||||
Reference in New Issue
Block a user