Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upPass manager options at registration time #135
Conversation
|
||
const parent = realm.parent; | ||
|
||
return internals.nearestState(parent); |
This comment has been minimized.
This comment has been minimized.
devinivy
Nov 20, 2017
Member
Perhaps (?) not a practical concern here, but beware recursion in javascript. There's still no such thing as tail recursion in node, so each time you recurse the call stack gets longer (and it has a max allowed size).
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
wswoodruff
Nov 20, 2017
Author
Contributor
I was having trouble getting code coverage with the while loop Eran had here, because parent
would never evaluate to false, since the root server always has vision state. The root server always has vision state because of the { setup: true }
introduced in the register
func.
Here's what's currently in vision - the loop Eran wrote:
internals.realm = function (server) {
if (server.realm.plugins.vision) {
return server.realm.plugins.vision;
}
let parent = server.realm.parent;
while (parent) {
if (parent.plugins.vision) {
return parent.plugins.vision;
}
parent = parent.parent;
}
return {};
};
As soon as the root server goes in this loop, it is returned as having a realm because setup.true will always be there. So parent = parent.parent
will never run, which would cause it to evaluate to false in the while loop, and return {}
This comment has been minimized.
This comment has been minimized.
wswoodruff
Nov 20, 2017
Author
Contributor
This could possibly be rewritten as nearestManager
, which would fix the issue of returning just because a realm has state in vision
|
||
internals.getRootRealm = (realm) => { | ||
|
||
let rootRealm = realm; |
This comment has been minimized.
This comment has been minimized.
devinivy
Nov 20, 2017
Member
I think rootRealm
is a slightly odd variable name here– it's not the root realm until it's returned (and not being used as a variable anymore).
This comment has been minimized.
This comment has been minimized.
|
||
Joi.assert(options, internals.schema.manager, 'Invalid manager options'); | ||
|
||
const realm = this.realm.parent || this.realm; |
This comment has been minimized.
This comment has been minimized.
devinivy
Nov 20, 2017
Member
Wait, when server.views()
is called inside a plugin wont this set the manager on the plugin's parent? It would be hard to see this in a test when nearestState()
comes into play. But imagine server1
registers a plugin with server2
, and server2
register a plugin with server3
. Now server3
calls server3.views()
– I think this will cause server2
and server3
to both have the same manager.
This comment has been minimized.
This comment has been minimized.
wswoodruff
Nov 20, 2017
Author
Contributor
I think you're probably right, I'll definitely go back and ensure this acts correctly in tests
}); | ||
internals.assignManager = function (options) { | ||
|
||
Joi.assert(options, internals.schema.manager, 'Invalid manager options'); |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
||
server.path(__dirname); | ||
|
||
const views = { | ||
engines: { 'html': Handlebars }, | ||
path: './templates/plugin' | ||
path: __dirname + '/templates/plugin' |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
wswoodruff
Nov 20, 2017
Author
Contributor
This might've slipped through when trying to write tests based off of others. I can remove it!
jedireza left a comment
I haven't taken a test drive yet but I did leave a couple small questions. |
register: function (server, options) { | ||
|
||
return server.register(Vision); | ||
server.register({ |
This comment has been minimized.
This comment has been minimized.
jedireza
Nov 20, 2017
Should we be using awaiting the return of this? (seen later in other call sites as well)
await server.register(...
This comment has been minimized.
This comment has been minimized.
wswoodruff
Nov 20, 2017
Author
Contributor
I've asked around about this, "what's the difference between return await [Promise]
and return [Promise]
? And ljharb
in the Node.js
Slack community said they're identical in what they do, only returning an await causes an unnecessary wrapper. Do you know if there's a difference?
This comment has been minimized.
This comment has been minimized.
jedireza
Nov 21, 2017
I see. That's good to know.
Do you know if there's a difference?
Nope. I'm new to async/await in general.
This comment has been minimized.
This comment has been minimized.
devinivy
Nov 21, 2017
Member
I find it's generally easier to remove cognitive load by simply awaiting anything async– only think about the underlying promises when really necessary. For what it's worth, in a lot of hapi code you'll find return await somePromise
. Unless perf is terribly important, that seems most consistent.
This comment has been minimized.
This comment has been minimized.
} | ||
}); | ||
|
||
return server.route({ |
This comment has been minimized.
This comment has been minimized.
jedireza
Nov 20, 2017
I'm curious why you're using return
here. I don't see a reference in the docs about needing to return anything from a plugin's register
function. (seen later in other call sites as well)
This comment has been minimized.
This comment has been minimized.
Thanks so much for the review guys! |
This comment has been minimized.
This comment has been minimized.
thebinarypenguin
commented
Dec 16, 2017
I'm excited about the ability to pass view manager options at registration time, but I'm curious what does that have to do with multiple registrations? |
This comment has been minimized.
This comment has been minimized.
https://github.com/hapijs/hapi/blob/master/API.md#-await-serverregisterplugins-options So just to allow plugin options loL ¯\(ツ)/¯ |
This comment has been minimized.
This comment has been minimized.
thebinarypenguin
commented
Dec 17, 2017
@wswoodruff Gotcha. Thanks for the plugin, and preemptive thanks for this new feature. |
return parent.plugins.vision; | ||
} | ||
// This fingerprint is set when using the 'onRequest' server ext | ||
if (this.request.route.fingerprint === '/#') { |
This comment has been minimized.
This comment has been minimized.
wswoodruff
Dec 24, 2017
•
Author
Contributor
I'm curious what others think of using the fingerprint /#
for detecting when using the 'onRequest' server extension.
When using the toolkit view
decorator inside the onRequest server extension, it seems like this.request.route.realm
is set to the root server every time.
|
||
parent = parent.parent; | ||
// 'this' is the plugin/server that registered the extension |
This comment has been minimized.
This comment has been minimized.
devinivy
Dec 24, 2017
Member
this
should be the toolkit itself. If h.view()
is called in an extension then h.realm
will be the realm in which the extension was created.
I'm pretty sure you want to always use h.realm
and not h.request.route.realm
here. Imagine writing a plugin that has its own manager and registers some extensions (but no routes). When calling h.view()
in one of those extensions I think you would expect to know only about your manager/templates, and not about other managers/templates registered in a different plugin (i.e. a separate plugin that registers routes).
This comment has been minimized.
This comment has been minimized.
wswoodruff
Dec 24, 2017
Author
Contributor
Hm, now I can't remember why I wrote it grabbing the realm from the route.
This comment has been minimized.
This comment has been minimized.
Thanks for the reviews guys! I'm hoping to merge this to master soon after the holidays, gonna let it marinate again for a little bit, not a whole month this time tho loL |
This comment has been minimized.
This comment has been minimized.
It's time! =P |
wswoodruff commentedNov 19, 2017
•
edited
Feedback welcome
Set multiple: true, as it's required to pass plugin options
Register vision via
server.register({ plugin: Vision, options: { ... });
where:server.views
Effectively, the only thing this adds is the ability to use