Skip to content

feat: support Node.js for @jupyterhub/binderhub-client#2044

Open
agoose77 wants to merge 1 commit intojupyterhub:mainfrom
agoose77:feat-node-support
Open

feat: support Node.js for @jupyterhub/binderhub-client#2044
agoose77 wants to merge 1 commit intojupyterhub:mainfrom
agoose77:feat-node-support

Conversation

@agoose77
Copy link
Contributor

This PR switches out @microsoft/fetch-event-source in favour of eventsource. This package is both newer (and maintained) and explicitly supports the Node.js runtime.

I'm consuming a vendored version of these changes in https://github.com/2i2c-org/clinder/tree/main/packages/binderhub-client-next, which is Node.js only.


this.eventIteratorQueue = null;
this.abortSignal = null;
this.stopQueue = null;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention here is that the queue is the application-level interface we care about. The underlying EventSource is just an implementation detail.

Comment on lines +108 to +111
const response = await fetch(input, {
...init,
headers: { ...init.headers, ...headers },
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure we pass through the headers

Comment on lines +112 to +123
// Known failures are passed on and handled in onError
if (response.ok) {
return response;
} else if (
response.status >= 400 &&
response.status < 500 &&
response.status !== 429
) {
return response;
}
// Otherwise, throw, triggering a retry
throw new EventStreamRetry();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK responses, or known-failures, are passed through to EventSource, which dispatches the proper events.

We don't do that for retry-able responses, because EventSource doesn't feature a configurable retry mechanism — it only kicks in for failures during fetching.

throw new EventStreamRetry();
}
},
this.stopQueue = () => queue.stop();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leak the stop action.

return () => {
es.removeEventListener("message", onMessage);
es.removeEventListener("error", onError);
es.close();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This closes the event source, from stopQueue().

@rgaiacs
Copy link
Contributor

rgaiacs commented Dec 16, 2025

@ agoose77 thanks for the pull request.

Switches out @microsoft/fetch-event-source in favour of eventsource looks great.

Two tests failed. Can you investigate the tests that failed?

@agoose77
Copy link
Contributor Author

@rgaiacs yes, at this stage just pushing the code. Plan to get to the tests later today!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants