Skip to content

Convert events to ReadableStream ? #1

Description

@lukeed

Perhaps events() should be a ReadableStream of ServerSentMessages instead of an AsyncIterator.

Practically, the stream could still be used with this syntax:

for await (let event of events(res)) {
  console.log('<<', event.data);
}

The difference would be that a ReadableStream (I think, although am fairly confident) performs better and you have the ability to easily pipe it to some Writer or Transformer stream. For example, imagine:

events(res).pipeThrough(new JSONTransformer).pipeTo(...)

To do the same now, with the AsyncIterator, you have to manually loop the iterable and apply your work; or, convert it to a ReadableStream to be able to do any pipe-work (mentioned above):

// AKA, current implementation
let gen = events(res) as AsyncGenerator<ServerSentMessage, void, unknown>;

// Option 1, where supported
let rs1 = ReadableStream.from(gen);

// Option 2, manual workaround
let rs2 = new ReadableStream({
    async pull(ctrl) {
      let { value, done } = await gen.next();

      if (done) ctrl.close();
      else ctrl.enqueue(value);
    },
  });
}

Considerations

  • ReadableStreams aren't treated as AsyncIterators everywhere yet; see support. As of now, only Deno >= 1.0, Node >= 16.5.0, and Firefox >= 110 support this feature.

  • AsyncGenerators (what events() currently returns) is supported in significantly more places.
    This may be reason alone to keep what's here.

  • The ReadableStream.from shortcut is available in Deno >= 1.35, Node >= 20.6.0, and Firefix >= 20.6. However, there's an easy manual workaround when this static method isn't available (see above)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions