Skip to content
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

Date deserialization in TRPC mutations not working in edge runtimes #302

Open
aldebout opened this issue Oct 16, 2024 · 7 comments
Open

Comments

@aldebout
Copy link

Cross-posting t3-oss/create-t3-turbo#1110 to get your eyes on it 😉

It looks like superjson silently fails to deserialize Date objects in edge runtimes, only in TRPC mutations (not queries).

More details in the original issue, including repro.

@Skn0tt
Copy link
Collaborator

Skn0tt commented Oct 16, 2024

Interesting, thank you! If you can come up with a minimal repro of this that behaves similar to how TRPC uses SuperJSON, but that doesn't include TRPC itself, then i'm happy to take a look and see if there's something to fix here.

@aldebout
Copy link
Author

aldebout commented Oct 16, 2024

@Skn0tt here is a repro repo https://github.com/aldebout/superjson-edge-repro.
It's the nextjs app start with only superjson added.

To see the issue: pnpm i, pnpm dev, then post

{
    "json": {
        "startDate": "2024-12-20T14:00:00.000Z"
    },
    "meta": {
        "values": {
            "startDate": [
                "Date"
            ]
        }
    }
}

on /api.

If we set the runtime to node (export const runtime = 'nodejs') it works, if we set it to edge (export const runtime 'edge') it fails.

@aldebout
Copy link
Author

Playing with it some more, it looks like there's an issue in both serialization and deserialization of Dates in the local nextjs edge runtime. If I serialize { startDate: new Date("2024-12-20T14:00:00.000Z") }, then result.json.startDate instanceof Date is true.

I tried running the tests using environment: 'edge-runtime' in vitest.config.mjs but they're still passing, I'm wondering if I'm missing something.

@Skn0tt
Copy link
Collaborator

Skn0tt commented Oct 17, 2024

Take a look at the code around

simpleTransformation(
isDate,
'Date',
v => v.toISOString(),
v => new Date(v)
),

and specifically at the implementation of isDate. I'm not very familiar with the internals of edge-runtime, but I could imagine that their Date implementation behaves slightly different from what SuperJSON expects, and from what happens on Node.js and in the browser. Try testing it exclusively within production - it seems like running edge-runtime locally is very different from prod: https://edge-runtime.vercel.app/#using-the-edge-runtime-locally

@aldebout
Copy link
Author

I'll switch the runtime depending on the environment and let you know how it goes.

I was looking into the source code but I'm having issues linking and debugging locally so I'll take a break from that.

FWIW undefined is also broken in this setup, I'm wondering what the pattern is.

@aldebout
Copy link
Author

The runtime switch is hard because nextjs requires a statically analyzable export :/

I dug deeper and the issue looks very similar to #242: in my local nextjs edge env,

return Object.getPrototypeOf(payload) === Object.prototype;
returns false even though I have a plain object.

I don't really know how to fix this because (as you said) it's not very clear to me what exactly runs nextjs edge locally. In the meantime I think I'll switch to another lib.

@Skn0tt
Copy link
Collaborator

Skn0tt commented Oct 17, 2024

I could imagine that the NaN check here doesn't work on Edge runtime:

payload instanceof Date && !isNaN(payload.valueOf());

If you or anybody else ends up doing more investigation on this, please post your results. Happy to write a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants