-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Describe the problem
Right now, the output of load in +layout.server.js or +page.server.js has to be serialized with JSON.stringify so that it can be transported to the client.
Occasionally it's useful to transport values that can't be serialized as JSON. Date springs to mind, along with things like this, where anything expecting selected to be a member of options post-deserialization will be disappointed:
export function load() {
const options = [
{ flavour: 'chocolate' },
{ flavour: 'strawberry' },
{ flavour: 'banana' }
];
const selected = options[0];
return { options, selected };
}Describe the proposed solution
We have a proven technique for this: https://github.com/rich-harris/devalue. It's fast, and doesn't involve a deserialization step. (It doesn't currently support BigInt though, we'd need to add that.)
To work with CSP, we can't eval the result (including by creating a <script>), we need to import it. Since we need to get fresh data when navigating back to a previously-visited page, we need to use a cachebusting mechanism; since modules live in a cache that we have no way of purging, we need to be careful to avoid memory leaks.
We can't therefore do this...
export const data = {...};...and must instead do this, so that the data can be garbage collected once it's been used:
window.__data = {...};On the client side, it would look something like this:
let uid = 1;
// later
await import(`${url.pathname}/__data.js`);
const data = window.__data;
delete window.__data;
Alternatives considered
There's a variety of alternatives to devalue listed here: https://github.com/rich-harris/devalue#see-also, though I'm not aware of any reasons to favour them.
Or, we could just stick to JSON, which has better performance characteristics if you have a huge amount of data.
Importance
nice to have
Additional Information
No response