solid-start icon indicating copy to clipboard operation
solid-start copied to clipboard

[Feature?]: Custom Seroval plugins

Open wszerad opened this issue 1 year ago • 8 comments

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.

wszerad avatar May 12 '24 11:05 wszerad

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:

  • fetchServerFunction declares a response const that if provided with some args that are not FormData nor URLSearchParams, will use seroval to stringify the args as the response body.
  • createServerReference returns a Proxy to the fn argument that traps get operations at fn. When the called fn property name is withOptions, which looks to be a function, and the method for the request is GET, will use seroval to stringify the withOptions function args to be sent as a query param. This operation then calls fetchServerFunction.

createServerReference is also defined at server-fns-runtime, that does not use seroval.

config/server-component.js:

  • server returns 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 (shimExportsPlugin and decorateExportsPlugin) that refer back to server-runtime's fetchServerFunction with some kind of dynamic import.
  • server is then exported as the second element in the serverComponents const.

config/index.js

  • If using experimental islands, will use server when defining the plugins for the routers in ssr and server-fns.

From runtime/server-handler.ts

runtime/server-runtime.ts:

  • serializeToStream returns a ReadableStream, that when started calls seroval crossSerializeStream with the plugins.
  • handleServerFunction uses serializeToStream to send the response to the client if some conditions are met or if the somewhere the code breaks.
  • handleServerFunction is exported as a h3 eventHandler handler.

config/index.js

  • Seems to use the h3 event handler wrapping handleServerFunction as 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 😄.

leo1553 avatar Jan 11 '25 20:01 leo1553

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.

lxsmnsyc avatar Jan 12 '25 07:01 lxsmnsyc

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?

agoldstein03 avatar Feb 10 '25 21:02 agoldstein03

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.

atilafassina avatar Feb 12 '25 09:02 atilafassina

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

uerkw avatar Feb 26 '25 13:02 uerkw

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)

lxsmnsyc avatar Feb 26 '25 14:02 lxsmnsyc

Possible plugin feature request: can Seroval eventually support serverside validation (using Standard Schema)? Related.

AlexErrant avatar Mar 05 '25 18:03 AlexErrant

@AlexErrant it's not seroval that handles server-side validation though.

lxsmnsyc avatar Mar 06 '25 01:03 lxsmnsyc