WICG / observable

Observable API proposal
https://wicg.github.io/observable/
Other
569 stars 13 forks source link

Web Socket, SSE, or streaming fetch example? #2

Open benlesh opened 1 year ago

benlesh commented 1 year ago

Another place this becomes useful is with streaming data over a connection like a web socket:

const socket = new WebSocket('wss://example.com/whatever')

const socketData = socket.on('message')
  .map(e => JSON.parse(e.data))

/**
 * Multiplex different chat window streams over the same connection
 */
async function openChatWindow(id: number) {
  await socket.on('open').first()

  socket.send(JSON.stringify({ openChat: id }))

  return socketData.filter(data => data.windowId === id)
}
benlesh commented 1 year ago

This is still pretty primitive without the Observable constructor though. With the constructor there are a lot more robust possibilities (because it can setup and teardown the socket)

domfarolino commented 1 year ago

So far the proposed IDL (and my very scrappy Chromium prototype for that matter) does include the Observable constructor. This is a cool example, any chance you'd be willing to draft a PR to include it in the README?

domenic commented 1 year ago

I think this is a useful example. However, it's important to be cautious in how you're presenting it, so as to maintain the separation between observable/push/multicast and streams/async iterators/pull/single-cast. (I know some people are observable-maximalists or streams-maximalists, but I think the most successful route for observable on the web platform is to position itself as an equal partner, superseding addEventListener() but not streams.)

In particular, some uses of WebSocket require you to receive all the data, with none being dropped; and they benefit from backpressure. Think, for example, streaming a ChatGPT response into the browser. Other uses work well with tuning in and out of the stream of events, and if you decide not to listen, that should not cause backpressure; it just means those events aren't currently interesting. Think, for example, updates to the "likes" count on a Tweet.

tbondwilkinson commented 1 year ago

+1 to domenic's comment. I think logical questions are for instance are events buffered and replayed for every on invocation, or does it only listen for the next event. Right now if you add the event listener after the event has been fired, you're not invoked for every previous event, e.g.