kit icon indicating copy to clipboard operation
kit copied to clipboard

Date changes datatype in SSR und CSR

Open tylkomat opened this issue 1 year ago • 3 comments

Describe the bug

When returning a JSDate from an endpoint. The datatype is preserved during SSR, but then on clientside load the type is the expected string.

Reproduction

The reproduction repo can be found here: https://github.com/tylkomat/sveltekit-date-ssr

The setup is very simple:

index.svelte

<script lang="ts">
  export let now: string;

  console.log(now.toString(), (now as any) instanceof Date,typeof now === 'string');
</script>

index.ts

export async function GET() {
  return {
    body: {
      now: new Date()
    }
  }
}

Logs

Server Log: `Wed Aug 10 2022 16:15:55 GMT+0200 (Mitteleuropäische Sommerzeit) true false`
Browser Log: `2022-08-10T14:15:55.959Z false true`

System Info

System:
    OS: Windows 10 10.0.19044
    CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor
    Memory: 2.64 GB / 15.93 GB
  Binaries:
    Node: 18.7.0 - ~\AppData\Local\Volta\tools\image\node\18.7.0\node.EXE
    npm: 8.15.0 - ~\AppData\Local\Volta\tools\image\node\18.7.0\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1266.0), Chromium (104.0.1293.47)
    Internet Explorer: 11.0.19041.1566
  npmPackages:
    @sveltejs/adapter-auto: next => 1.0.0-next.64
    @sveltejs/kit: next => 1.0.0-next.405
    svelte: ^3.44.0 => 3.49.0
    vite: ^3.0.0 => 3.0.5

Severity

annoyance

Additional Information

No response

tylkomat avatar Aug 10 '22 14:08 tylkomat

IMO your endpoint should be responsible for returning something that can be serialized (as-is) to JSON. If you're returning something that can't be losslessly serialized and deserialized, that's not something SK should be worried about I don't think. Resolving this would mean running all SSR responses from these functions through JSON.parse(JSON.stringify(...)) to make sure things match, which seems like a waste generally.

Conduitry avatar Aug 10 '22 15:08 Conduitry

An endpoint can be called from the server and from the client. I would expect the same result in both cases. The name endpoint suggests that it is usually accessed via network (HTTP).

While I agree that it seems like a waste it would at least follow the same flow in both cases. I'm under the impression that the result is cached and the stringifying and parsing would only be done once.

If #647 would be implemented and expanded to endpoints as well the Date type could be also restored again on the client.

Another option would be to test and throw an error if not serializable datatypes are encountered. There was someone on discord who was returning mongodb client handles via the endpoint, which was also working because of how SSR works it seems, but getSession was complaining that it's not serializable. If the endpoint gives hint's like that it would also be fine.

tylkomat avatar Aug 10 '22 16:08 tylkomat

I'd be in favor of testing for serializability in dev mode only, and just passing along the object as-is in prod mode for SSR.

Conduitry avatar Aug 10 '22 16:08 Conduitry

Providing some way to hook into the deserialization on the client would make it easier to convert ISO date strings back to JS Objects (i.e. as a reviver option to the JSON.parse method).

I hit this all the time (pretty much ever chunk of data always has a date in it) and it's a new-user foot-gun because the error you end up with isn't obvious as to the cause.

CaptainCodeman avatar Aug 11 '22 16:08 CaptainCodeman

This was addressed by #5987 and will be addressed moreso by #6318.

Conduitry avatar Aug 26 '22 22:08 Conduitry