You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, when trying to use the Ably.Realtime instance in the Vercel Edge runtime
whether within serverless functions or in SSR when rendering the frontend in Edge runtime - we get the error Error: A Node.js API is used (setImmediate) which is not supported in the Edge Runtime..
This error either prevents the serverless function from running or results in a white screen of death when rendering the frontend page.
The issue comes from the assignment of the setImmediate function to the IPlatformConfig.nextTick method in the web platform bundle. We do this when setImmediate function is defined on the global object on the next lines. Consequently, IPlatformConfig.nextTick is called in various transport and websocket-related classes like Connection and WebSocketTransport during the regular Ably.Realtime workflow, leading to the error above.
Here's exactly what's happening:
When importing a package in the Vercel Edge runtime, Vercel selects a browser bundle from the available bundles provided by the package in node_modules, as explained by a Vercel staff member in this GitHub issue:
So you are correct in that we decided to pick the browser field for the edge runtime, as we felt it was closer to what the runtime was capable of than Node.js (since you cannot use Node.js APIs in Edge, and browsers are usually fully spec-compliant also, compared to polyfills/packages.)
For ably-js, this means that in Vercel Edge runtimes, our web platform bundle will be selected, which includes the optional usage of the setImmediate function.
The Vercel Edge runtime defines setImmediate function instead of leaving it undefined. It sets it to be the function that just throws Error: A Node.js API is used (setImmediate) which is not supported in the Edge Runtime. error immediately when called.
Since setImmediate function is actually defined, no polyfill will work out of the box, as polyfills usually rely on condition checks like if (!global.setImmediate) { // define polyfill }. For example, this popular setImmediate polyfill won't work out of the box.
Note
Even if we were to forcibly polyfill the setImmediate function using this polyfill, it would still default to using the setTimeout function, as other preferred browser APIs (postMessage and MessageChannel) are also unavailable in the Vercel Edge runtime.
Because setImmediate function is actually defined, our web bundle code sets IPlatformConfig.nextTick to the value of the setImmediate function, which eventually throws an error.
Ideally, we should use the following condition to check if we are running in the Vercel Edge runtime: const isVercelEdgeRuntime = typeof EdgeRuntime === 'string'; (source). Then, in our web platform bundle, we should set IPlatformConfig.nextTick to setTimeout if isVercelEdgeRuntime === true.
However, we are currently unable to implement this due to the following issue with using Ably.Realtime in the Vercel Edge runtime: #1731
The next best option is to add a Vercel Edge runtime check to the Realtime class constructor or Realtime.connect() method and throw a more readable error explaining the issues with running the Ably.Realtime instance in the Vercel Edge runtime.
VeskeR
changed the title
Make ably-js throw a readable error when using Realtime client in the Vercel Edge runtime
Fix "setImmediate is not supported" errors when using Realtime client in the Vercel Edge runtime
Apr 15, 2024
Currently, when trying to use the
Ably.Realtime
instance in the Vercel Edge runtimeError: A Node.js API is used (setImmediate) which is not supported in the Edge Runtime.
.This error either prevents the serverless function from running or results in a white screen of death when rendering the frontend page.
The issue comes from the assignment of the
setImmediate
function to theIPlatformConfig.nextTick
method in the web platform bundle. We do this whensetImmediate
function is defined on the global object on the next lines. Consequently,IPlatformConfig.nextTick
is called in various transport and websocket-related classes likeConnection
andWebSocketTransport
during the regularAbly.Realtime
workflow, leading to the error above.Here's exactly what's happening:
browser
bundle from the available bundles provided by the package in node_modules, as explained by a Vercel staff member in this GitHub issue:For ably-js, this means that in Vercel Edge runtimes, our web platform bundle will be selected, which includes the optional usage of the
setImmediate
function.setImmediate
function instead of leaving it undefined. It sets it to be the function that just throwsError: A Node.js API is used (setImmediate) which is not supported in the Edge Runtime.
error immediately when called.setImmediate
function is actually defined, no polyfill will work out of the box, as polyfills usually rely on condition checks likeif (!global.setImmediate) { // define polyfill }
. For example, this popularsetImmediate
polyfill won't work out of the box.Note
Even if we were to forcibly polyfill the
setImmediate
function using this polyfill, it would still default to using thesetTimeout
function, as other preferred browser APIs (postMessage
andMessageChannel
) are also unavailable in the Vercel Edge runtime.setImmediate
function is actually defined, our web bundle code setsIPlatformConfig.nextTick
to the value of thesetImmediate
function, which eventually throws an error.Ideally, we should use the following condition to check if we are running in the Vercel Edge runtime:
const isVercelEdgeRuntime = typeof EdgeRuntime === 'string';
(source). Then, in our web platform bundle, we should setIPlatformConfig.nextTick
tosetTimeout
ifisVercelEdgeRuntime === true
.However, we are currently unable to implement this due to the following issue with using
Ably.Realtime
in the Vercel Edge runtime: #1731The next best option is to add a Vercel Edge runtime check to the
Realtime
class constructor orRealtime.connect()
method and throw a more readable error explaining the issues with running theAbly.Realtime
instance in the Vercel Edge runtime.┆Issue is synchronized with this Jira Story by Unito
The text was updated successfully, but these errors were encountered: