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

Add adapters to enable compatibility with any runtime and/or framework #77

Open
MatthewWid opened this issue Oct 30, 2024 · 0 comments
Open
Labels
enhancement New feature or request

Comments

@MatthewWid
Copy link
Owner

MatthewWid commented Oct 30, 2024

Introduce the concept of adapters, allowing sessions to be instantiated with inputs other than the Node HTTP request and response objects and enabling compatibility with practically any JavaScript/TypeScript library, including non-Node runtimes such as Bun and Deno.

To implement this, a breaking change is necessary whereby Session is updated to be an abstract class that is then implemented by concrete classes for whichever runtime and/or framework is needed.


The better-sse package will export a few officially supported adapters:

Others can be community-made in separate packages or implemented by the user themselves if they have a use-case requiring highly specific customisation.

To use adapters you would simply import the specific module you need and then use the library like normal:

// Exports Node HTTP/1.1 by default
import { createSession } from "better-sse";
// Equivalent to
import { createSession } from "better-sse/adapters/node/http";

// Adapters are under a different entrypoint
import { createSession } from "better-sse/adapters/node/http2-compat";
import { createSession } from "better-sse/adapters/node/http2-core";
import { createSession } from "better-sse/adapters/deno/http";
import { createSession } from "better-sse/adapters/bun/http";

Everything else (channels, event buffers, etc.) would still all function the exact same. Only the session - which forms the actual interface between the business code and the network transmissions - would need to be updated.


Community-made adapters would also be available. An example of using a Hono adapter (#70) would be:

import { Hono } from "hono";
import { createChannel } from "better-sse";
import { createSession } from "better-sse-adapter-hono";

const app = new Hono();

const channel = createChannel();

app.get("/sse", async (c) => {
  const session = await createSession(c);

  channel.register(session);
});

export default app;

The current idea is that adapters would need to implement five methods - three that retrieve headers and parameters from the request, one that sends the response head and one to send raw data (chunks) over the wire:

abstract getDefaultHeaders(): OutgoingHttpHeaders;
abstract getHeader(name: string): string | undefined;
abstract getParam(name: string): string | undefined;
abstract sendHead(statusCode: number, headers: OutgoingHttpHeaders): void;
abstract sendChunk(chunk: string): void;

This might need more thought, however, as certain frameworks such as Next.js and hapi (#76) instead rely on returning an object back to the method handler to send the response head rather than invoking a function.

Perhaps for those specific adapters they would have a Response instance property that could be returned and sendHead would instead be no-op'd:

async (context) => {
  const session = await createSession(context);

  return session.Response;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

1 participant