[Feature?]: Custom Seroval plugins
Duplicates
- [X] I have searched the existing issues
Latest version
- [X] I have tested the latest version
Summary 💡
It would be useful to be able to define a list of your own plugins used by Seroval, as far as I know, this is the only way to properly parse custom classes.
Examples 🌈
No response
Motivation 🔦
I'm struggling with trying to return the ObjectId (used in MongoDb) from a server function, instance cannot be parsed by Seroval.
I took some time to find the code where the seroval plugins are specified and found that in the server-runtime.ts contains a plugin list as a module constant. Then tracked the function call chain until I reached some function or option that could receive the custom plugins, but as I don't really know the code base, I'm not sure if i tracked it right:
From runtime/server-runtime.ts
runtime/server-runtime.ts:
fetchServerFunctiondeclares aresponseconst that if provided with someargsthat are notFormDatanorURLSearchParams, will use seroval to stringify theargsas the response body.createServerReferencereturns aProxyto thefnargument that traps get operations atfn. When the calledfnproperty name iswithOptions, which looks to be a function, and the method for the request is GET, will use seroval to stringify thewithOptionsfunction args to be sent as a query param. This operation then callsfetchServerFunction.
createServerReference is also defined at server-fns-runtime, that does not use seroval.
config/server-component.js:
serverreturns an array of vinxi plugins, which one of them is a vinxi directive that contains two transforms that looks to contain two vinxi's "ExportsPlugin"s (shimExportsPluginanddecorateExportsPlugin) that refer back toserver-runtime'sfetchServerFunctionwith some kind of dynamic import.serveris then exported as the second element in theserverComponentsconst.
config/index.js
- If using experimental islands, will use
serverwhen defining the plugins for the routers in ssr and server-fns.
From runtime/server-handler.ts
runtime/server-runtime.ts:
serializeToStreamreturns aReadableStream, that when started calls serovalcrossSerializeStreamwith the plugins.handleServerFunctionusesserializeToStreamto send the response to the client if some conditions are met or if the somewhere the code breaks.handleServerFunctionis exported as a h3 eventHandler handler.
config/index.js
- Seems to use the h3 event handler wrapping
handleServerFunctionas the handler for server-fns.
-
Both code flows seems to use seroval very deep in the call chain, but both of them starts at config/index.js which looks up app.config.[jt]s. Therefore my idea is to provide a start config field to point to a module default exporting an array of seroval plugins that could be dynamically loaded and used by each of the scenarios described above.
This seems to be the very start of the SolidStart runtime, and I'm not sure how dynamic module loading could interfere in code splitting. If some contributor could give me an idea of how to implement this without breaking the hole project, I could give it a try 😄.
I haven't really given a response here since the discussion for this remained with Ryan but user-based plugins is definitely in heavy consideration, it wasn't just considered back then because of potential security risks. No worries though, we will revisit this in the future.
Hello! Checking back in on this thread now that v1.1.0 is out. I'm interested in adding a few server function/Seroval customization options, would a PR be considered at the point?
Hello! Checking back in on this thread now that v1.1.0 is out. I'm interested in adding a few server function/Seroval customization options, would a PR be considered at the point?
Hey @agoldstein03 !!
About extending Seroval, I'll let @lxsmnsyc reply, but I imagine he'll need to know what kind of customization you're planning to add.
But I can say we'd be appreciative of any contribution that address a general use-case or improves the DX. The best way to prevent wasting your time would be to create an issue with the proposed idea and we can iterate on that.
Figured I would bump this thread, as I'm reaching a similar need/use-case where I would like to define some schema/structure to the objects that I return (and serialize) from server functions.
For how I'd theoretically use this, I would probably see it being defined in the Solid config in the Vite plugin. I'm not sure of a better way to inject these, but I could see a config option for optional extensions to seroval being used there. I can foresee this being a little tricky to get passed to seroval, but I think it would be useful for devs to drop in some kind of common format into it and let seroval automatically pick up how to parse all your schemas.
Right now I have a lot of APIs I'm trying to use in solid, and end up having to structured clone the objects they return so that I can properly serialize them.
Does seroval expose these in a simple format? I'm interested in how we can get Solid to properly inject plugins like these so that there is a common path for class serialization
For how I'd theoretically use this, I would probably see it being defined in the Solid config in the Vite plugin.
Not an effective place since Vite is a bundler runtime, not the app runtime, where the serialization happens. We'll most likely introduce a place to set this up.
Does seroval expose these in a simple format? I'm interested in how we can get Solid to properly inject plugins like these so that there is a common path for class serialization
Not really, but it's going to be exposed in Solid. We are also planning to renovate the whole serialization stuff so it is in sync with Solid (currently it isn't)
Possible plugin feature request: can Seroval eventually support serverside validation (using Standard Schema)? Related.
@AlexErrant it's not seroval that handles server-side validation though.