Update hooks api to support promise api

This commit is contained in:
Nick O'Leary 2021-04-15 15:11:27 +01:00
parent ed351eee54
commit 22df59e229
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
2 changed files with 82 additions and 9 deletions

View File

@ -8,7 +8,12 @@ const VALID_HOOKS = [
"postDeliver",
"onReceive",
"postReceive",
"onComplete"
"onComplete",
// Module install hooks
"preInstall",
"postInstall",
"preUninstall",
"postUninstall"
]
@ -35,12 +40,12 @@ let labelledHooks = { }
* - `postReceive` - passed a `ReceiveEvent` when the message has been given to the node's `input` handler(s)
* - `onComplete` - passed a `CompleteEvent` when the node has completed with a message or logged an error
*
* @mixin @node-red/runtime_hooks
* @mixin @node-red/util_hooks
*/
/**
* Register a handler to a named hook
* @memberof @node-red/runtime_hooks
* @memberof @node-red/util_hooks
* @param {String} hookId - the name of the hook to attach to
* @param {Function} callback - the callback function for the hook
*/
@ -68,7 +73,7 @@ function add(hookId, callback) {
/**
* Remove a handled from a named hook
* @memberof @node-red/runtime_hooks
* @memberof @node-red/util_hooks
* @param {String} hookId - the name of the hook event to remove - must be `name.label`
*/
function remove(hookId) {
@ -110,11 +115,33 @@ function removeHook(id,callback) {
function trigger(hookId, payload, done) {
const hookStack = hooks[hookId];
if (!hookStack || hookStack.length === 0) {
done();
return;
if (done) {
done();
return;
} else {
return Promise.resolve();
}
}
if (!done) {
return new Promise((resolve,reject) => {
invokeStack(hookStack,payload,function(err) {
if (err !== undefined && err !== false) {
if (!(err instanceof Error)) {
err = new Error(err);
}
err.hook = hookId
reject(err);
} else {
resolve(err);
}
})
});
} else {
invokeStack(hookStack,payload,done)
}
}
function invokeStack(hookStack,payload,done) {
let i = 0;
function callNextHook(err) {
if (i === hookStack.length || err) {
done(err);
@ -148,8 +175,6 @@ function trigger(hookId, payload, done) {
}
}
}
callNextHook();
function handleResolve(result) {
if (result === undefined) {
callNextHook();
@ -157,6 +182,7 @@ function trigger(hookId, payload, done) {
done(result);
}
}
callNextHook();
}
function clear() {

View File

@ -249,4 +249,51 @@ describe("util/hooks", function() {
done();
})
})
it("handler can use callback function - promise API", function(done) {
hooks.add("onSend.A", function(payload, done) {
setTimeout(function() {
payload.order.push("A")
done()
},30)
})
hooks.add("onSend.B", function(payload) { payload.order.push("B") } )
let data = { order:[] };
hooks.trigger("onSend",data).then(() => {
data.order.should.eql(["A","B"])
done()
}).catch(done)
})
it("handler can halt execution - promise API", function(done) {
hooks.add("onSend.A", function(payload, done) {
setTimeout(function() {
payload.order.push("A")
done(false)
},30)
})
hooks.add("onSend.B", function(payload) { payload.order.push("B") } )
let data = { order:[] };
hooks.trigger("onSend",data).then(() => {
data.order.should.eql(["A"])
done()
}).catch(done)
})
it("handler can halt execution on error - promise API", function(done) {
hooks.add("onSend.A", function(payload, done) {
throw new Error("error");
})
hooks.add("onSend.B", function(payload) { payload.order.push("B") } )
let data = { order:[] };
hooks.trigger("onSend",data).then(() => {
done("hooks.trigger resolved unexpectedly")
}).catch(err => {
done();
})
})
});