New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Removal of declaration merging #5061
Comments
Maybe we can use assertions to keep track of registered plugins, so plugins don't have to do declaration merging. |
Wow! I'm learning new magic. This could work well inside a single file. |
@webstrand gave us few weeks/months ago an asssessment regarding builder api. |
The builder API does not travel well across files... we need a solution that allows us to define in TS that plugin A requires plugin B and therefore those decorators are available. |
@mcollina Exactly, I am working on a library which had the exact same problem. Can I add you as a contributor so you can see it in action? |
Absolutely. |
I did a quick check but I could not orient myself to see how you fixed this. Could you give me some pointers (here, in an issue there, or privately). |
@mcollina How can I contact you? |
email, twitter dm, discord dm (there is a fastify discord) |
Continuing the usage of fastify static as an example, would the |
That (or something similar) is the code that a user would write to get the mixin. Maybe we can simplify it a bit. |
What would be the purpose of the |
The purpose is to add the necessary mixins to the passed in FastifyInstance so that |
Been playing around the past couple days to see what I could get working:
How would people feel about an api for using request & reply mixins that's similar to the proposed way to use mixins for fastify.route({
url: '/',
method: 'GET',
handler: (_, reply: FastifyReply & FastifyStaticReplyMixin) {
reply.sendFile('index.html');
}
}); |
Unfortunately this is not good. There can be tens of plugins registered, so this would become untenable in the route definition. Note that |
I was thinking about the decorators object wrong and was able to get it partially working: Playground Link I removed the explicit typing on the I don't think there's a way to allow for explicit typing without overriding the generics. A user still could explicitly type the parameter, but they would need to pass in the exact same values for the generics to get the same type originally provided and that would completely defeat the purpose of the decorators object (imo at least). However, I was able to get an api like this working: fp((app) => {
app.staticSomethingSomething = false;
app.route((reply) => {
reply.sendFile('index.html');
})
}, {
decorators: {
app: FastifyStaticMixin, // Pass in the FastifyInstance decorator here and it's applied to the app parameter
reply: FastifyStaticReplyMixin
}
}) Full example here Playground Link
I don't believe the approach I described above would work with How would you feel about using a mix of both #5061 (comment) to handle the |
The playground link is ok. An alternatvie API that we could consider is the following: const _app = app.withAppMixin<StaticAppMixin>().withRequestMixin<StaticRequestMixin>().withReplyMixin<StaticReplyMixin>() Wdyt of this? |
Would that replace the |
yes, it would replace the use case for adding this to |
So the full api would be something like this?
const app = fastify({...})
app.register(fastifyStatic, ...)
const _app = app
.withAppMixin<StaticAppMixin>()
.withRequestMixin<StaticRequestMixins>()
.withResponseMixin<StaticResponseMixin>();
// _app.route or something
fp((app) => {
// app.route or something
}, {
decorators: {
app: StaticAppMixin,
reply: StaticReplyMixin
}
}) |
I would say go ahead for the mixins. Maybe let's keep iterating on top of the plugin APIs. Something that would be rad is to have: let app = fastify({...})
app = app.register(fastifyStatic, ...) I guess we can start adding the Mixins and build on top of that. |
Nb. not much experience with the existing Fastify API's and types setup. Got interested in this issue while evaluating Fastify and the ecosystem :) I think if mixins are added in the proposed way, a few extra types and generics are necessary on Although a builder-like api has been discussed in #4081 I couldn't resist trying to figure out how that would work, so made a proof-of-concept over the weekend, see playground. Not sure if this concept would be completely possible to implement, haven't done much generic work in the past few years, and what the TS performance will be if everything is implemented. |
@ShogunPanda @marco-ippolito as discussed, ptal 🙏 |
Quick addition: whatever solution we find needs to be able to work via JSdoc too. |
I'm more into this API, since with the mixins API looks like we are duplicating ourself. Also by using mixins we can |
What we need is a set of 3 PRs that essentially go together to PoC this:
|
I already build a PoC as discussed. You can check it out on this PR. If you navigate to I merged all the points on this single PR, so if we agree I can split this on specific PR's. |
If it's worth anything, I have a draft pr for adding mixins to fastify-static here fastify/fastify-static#427 |
What can we do to ship this before July? |
Getting feedback as early as possible would be a great help. |
declaration merging is the technique we use in Fastify to decorate the types of our base objects. See https://github.com/fastify/fastify-static/blob/d40ce2d33481da7abcd261b1e8699ef31a9e2854/types/index.d.ts#L8-L17.
This technique has a major flaw: once a module is "seen" by TypeScript, those types are mergerd in original definition, even if the decorating plugin is not loaded in the current plugin tree.
After studying a bit of TypeScript, I think we can do better. In essence, we should be able to support something like:
Or even better:
Or some other analog syntax with native Fastify, e.g.
withMixin<T>()
.I think this would be a significant improvement on our TS story for v5. Wdyt?
The text was updated successfully, but these errors were encountered: