Pass manager options at registration time#135
Conversation
lib/index.js
Outdated
|
|
||
| const parent = realm.parent; | ||
|
|
||
| return internals.nearestState(parent); |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
(And this can always be expressed as a while loop!)
There was a problem hiding this comment.
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 {}
There was a problem hiding this comment.
This could possibly be rewritten as nearestManager, which would fix the issue of returning just because a realm has state in vision
lib/index.js
Outdated
|
|
||
| internals.getRootRealm = (realm) => { | ||
|
|
||
| let rootRealm = realm; |
There was a problem hiding this comment.
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).
lib/index.js
Outdated
|
|
||
| Joi.assert(options, internals.schema.manager, 'Invalid manager options'); | ||
|
|
||
| const realm = this.realm.parent || this.realm; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
I think you're probably right, I'll definitely go back and ensure this acts correctly in tests
lib/index.js
Outdated
| }); | ||
| internals.assignManager = function (options) { | ||
|
|
||
| Joi.assert(options, internals.schema.manager, 'Invalid manager options'); |
There was a problem hiding this comment.
Doesn't the manager make this assertion on its own?
There was a problem hiding this comment.
Yup! No need to export the schema I suppose
test/index.js
Outdated
| const views = { | ||
| engines: { 'html': Handlebars }, | ||
| path: './templates/plugin' | ||
| path: __dirname + '/templates/plugin' |
There was a problem hiding this comment.
This might've slipped through when trying to write tests based off of others. I can remove it!
jedireza
left a comment
There was a problem hiding this comment.
I haven't taken a test drive yet but I did leave a couple small questions.
test/index.js
Outdated
| register: function (server, options) { | ||
|
|
||
| return server.register(Vision); | ||
| server.register({ |
There was a problem hiding this comment.
Should we be using awaiting the return of this? (seen later in other call sites as well)
await server.register(...There was a problem hiding this comment.
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?
There was a problem hiding this comment.
I see. That's good to know.
Do you know if there's a difference?
Nope. I'm new to async/await in general.
There was a problem hiding this comment.
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.
test/index.js
Outdated
| } | ||
| }); | ||
|
|
||
| return server.route({ |
There was a problem hiding this comment.
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)
|
Thanks so much for the review guys! |
|
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? |
|
https://github.com/hapijs/hapi/blob/master/API.md#-await-serverregisterplugins-options So just to allow plugin options loL ¯\(ツ)/¯ |
|
@wswoodruff Gotcha. Thanks for the plugin, and preemptive thanks for this new feature. 🎉 |
lib/index.js
Outdated
| return parent.plugins.vision; | ||
| } | ||
| // This fingerprint is set when using the 'onRequest' server ext | ||
| if (this.request.route.fingerprint === '/#') { |
There was a problem hiding this comment.
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.
lib/index.js
Outdated
| if (this.request.route.fingerprint === '/#') { | ||
|
|
||
| parent = parent.parent; | ||
| // 'this' is the plugin/server that registered the extension |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
Hm, now I can't remember why I wrote it grabbing the realm from the route.
|
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 |
|
It's time! =P |
|
This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions. |
Feedback welcome
Set multiple: true, as it's required to pass plugin options
Register vision via
server.register({ plugin: Vision, options: { ... });where:server.viewsEffectively, the only thing this adds is the ability to use