-
I am facing this issue with a setup I am creating: Next + Relay + ReScript (so relay-nextjs + rescript-relay + ). This is the first query I am actually writing (note that I used I have literally no clue why I am facing this and any search engine is clearly not helping. Any help appreciated :) |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 12 replies
-
Interesting, never seen this before either. Relay uses a bunch of WeakMap internally, I would assume it has to do with them (rescript-relay itself does nothing special here). I guess we can start with the basics - what versions are you on? |
Beta Was this translation helpful? Give feedback.
-
Do you have a context provider setup for RescriptRelay, with your environment passed into it? |
Beta Was this translation helpful? Give feedback.
-
Sure! Looking at the error, something seems up with the environment (that's what Relay seems to use for the cache key in the WeakMap). |
Beta Was this translation helpful? Give feedback.
-
In short it was an obvious myconfiguration, related to a "huge" mess to sort related directly to Next, Next-Auth (and user session) and Relay. Nothing to do with rescript-relay. If anyone has a hard time to setup this in short: change the relay env whenever you session changed (since you might be interested by a jwt token to make authenticated request at some point). My current setup is basically something like this (in my const RelayEnvironmentProvider_SessionAware = ({ Component, pageProps }) => {
let session = useSession();
const relayProps = getRelayProps(
pageProps,
getInitialPreloadedQuery({
createClientEnvironment: () => getClientEnvironment(session.data),
})
);
let env =
relayProps.preloadedQuery?.environment ??
getClientEnvironment(session.data);
return (
<RelayEnvironmentProvider
environment={env}
>
<Component {...pageProps} {...relayProps} />
</RelayEnvironmentProvider>
);
};
const App = ({ Component, pageProps: { session, ...pageProps } }) => {
return (
<SessionProvider session={session}>
<RelayEnvironmentProvider_SessionAware
Component={Component}
pageProps={pageProps}
/>
</SessionProvider>
);
};
open ReScriptJs
// https://reverecre.github.io/relay-nextjs/docs/configuration#routing-integration
// coupled with next-auth needs
type clientEnvData = {
session: Js.Nullable.t<Auth.session>,
relayEnv: option<RescriptRelay.Environment.t>,
}
let clientEnv = ref({
session: Js.Nullable.undefined,
relayEnv: None,
})
let getClientEnvironment = (session: Js.Nullable.t<Auth.session>) => {
if Js.typeof(Js.window) === #undefined {
// Js.Console.log2(
// "RelayEnvClient getClientEnvironment: undefined bye, window is",
// Js.typeof(Js.window),
// )
None
} else {
// consider session change only if jwt changes
// (otherwise it doesn't matter for graphql calls)
let sessionChanged =
session
->Js.Nullable.toOption
->Option.flatMap(session => session.user)
->Option.map(user => user.jwt) !==
clientEnv.contents.session
->Js.Nullable.toOption
->Option.flatMap(session => session.user)
->Option.map(user => user.jwt)
if sessionChanged || clientEnv.contents.relayEnv->Option.isNone {
Js.Console.log2(
"RelayEnvClient getClientEnvironment: defining env from session change",
session,
)
clientEnv.contents = {
session: session,
relayEnv: Some(
RelayEnv.makeEnvironment(
session,
RelayNextJs.getRelaySerializedState()->Option.flatMap(state => state.records),
false,
),
),
}
}
clientEnv.contents.relayEnv
}
}
In short: overtime the session seems to change, relay env is recreated. Concerning SSR/Client side this should work without trouble. |
Beta Was this translation helpful? Give feedback.
-
If this can help anyone, vercel/next.js#33892 is currently the way to go to setup next + relay properly without headache ! |
Beta Was this translation helpful? Give feedback.
In short it was an obvious myconfiguration, related to a "huge" mess to sort related directly to Next, Next-Auth (and user session) and Relay. Nothing to do with rescript-relay.
If anyone has a hard time to setup this in short: change the relay env whenever you session changed (since you might be interested by a jwt token to make authenticated request at some point).
My current setup is basically something like this (in my
_app.js
)