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

Requesting Clarity for new Streaming Feature #732

Open
pg-wtatum opened this issue Jul 17, 2024 · 4 comments
Open

Requesting Clarity for new Streaming Feature #732

pg-wtatum opened this issue Jul 17, 2024 · 4 comments

Comments

@pg-wtatum
Copy link

A few issues related to the new async generator feature for streaming responses, one of which applied to the legacy method as well.

  • What is the exact return type used to signal streaming and is it possible to do this without a generator? In the event an underlying operation is callback based the ergonomics of adapting that into yield calls can be difficult since you cannot yield inside a callback. Here is an example of how I "got this to work" for the listen/notify mechanism of postgresjs. I was able to wrap the notify call in a ReadableStream and then iterate the stream but maybe I'm missing something that allows skipping some of the ceremony
.get("/funky", async function* ({}) {
    let ul: ListenMeta;

    try {
      const rs = new ReadableStream<{}>({
        async start(controller) {
          ul = await sql.listen(
            "test",
            // Onnotify
            (payload) => {
              controller.enqueue({
                kind: "notify",
                payload,
              });
            },
            // Onconnect
            () => {
              controller.enqueue({
                kind: "connected",
              });
            }
          );

          setTimeout(() => {
            controller.enqueue({
              kind: "timeout",
            });
            controller.close();
          }, 10_000);
        },
      });

      for await (const item of rs) {
        console.log(item);
        yield item;
      }
    } finally {
      ul?.unlisten();
    }
  })
  • The content-type is automatically set to text/event-stream but the call from browser client using treaty is not made using EventSource so the semantics are different (no automatic reconnect, no tracking of IDs, etc)
  • It seems like instead of using the typical Elysia automatic object -> JSON I instead get the toString version is this intended?
@pg-wtatum
Copy link
Author

To elaborate further on the object -> JSON question, if I implement my server side as a typed generator that produces something other than string the inferred client type in treaty is AsyncGenerator but in fact I just get the string [object Object] instead

@pg-wtatum
Copy link
Author

pg-wtatum commented Jul 17, 2024

Sorry for the drip feed of info but the behavior is actually weirder than I first thought -- if I manually call JSON.stringify on the server, the values produced by

  const res = await client.funky.get();
  if (!res.error) {
    for await (const d of res.data) {
      console.log(d);
    }
  }

are objects rather than strings. This causes some significant typescript issues as I need to type the generator as string (but it actually returns objects)

edit to add I see that 1.1.3 was released today to address other issues related to the stream feature. I have updated and this appears to still be the case.

@directormac
Copy link

Currently implementing it using the Generator function as described in the docs, using for await in both ends when data is string or a certain type, it's being inferred correctly but can't parse them well as sometimes it yields 2 or more at once. i think this needs to be moved at eden repo

@pg-wtatum
Copy link
Author

Not sure it's strictly on the Eden side -- I've definitely seen cases where only one object is emitted and it still serializes onto the wire as [object Object], but if manually stringified with JSON.stringify it goes onto the wire as JSON (of course) and is parsed by Eden.

Given the content type is text/event-stream I would expect that the wire format is newline delimited and simultaneous emissions should not be an issue?

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