Type-R icon indicating copy to clipboard operation
Type-R copied to clipboard

TC39 Observable draft spec.

Open far-blue opened this issue 8 years ago • 5 comments

There's a new proposal for Observables currently in TC39 phase 1 that defines a basic inter-op that is supported by RxJS, MostJS, Zen-Observable and some other libraries. This allows for a common minimal level of support an object needs in order for it to be observable and take part in 'reactive' programming / streams (whatever you want to call them).

The minimal inter-op is actually very basic and I'd like to suggest adding support for it to Type-R or even at a lower level to MixtureJS. At the MixtureJS level the type of events being handled are unbounded so the resulting observable stream would be just raw events. At the Type-R level more structure could be offered.

I've put together a gist of a basic example that doesn't assume anything about the structure of the events here: https://gist.github.com/far-blue/05c679b4e4cb5fe1df1d36006e8a21fa

I'd be interested in people's thoughts and comments.

Not only would Observable inter-op be nice and allow Type-R events to work with other frameworks it could also change the way we think about integration of Rest APIs with Type-R because Rest API results could just be handled as Observable Streams.

far-blue avatar Jun 30 '17 10:06 far-blue

At the Type-R level, it makes sense to stream "change" event for the Record and "changes" for the Collection, respectively. Both of them have the semantic that something inside was changed, and it might be the behavior of the default Symbol.observable.

At MixtureJS level (Messenger class to be exact), both the streaming of the "all" subscription and the creation of observables for the specific events might be supported.

eventSource.createObservable( 'event1 event2 ...' )

As everything in Type-R implements Messenger as mixin, createObservable would work for both Record and collection.

gaperton avatar Jun 30 '17 17:06 gaperton

I can definitely see advantages to Type-R focusing on change events while offering up the raw events in MixtureJS. I'm not sure the createObservable approach is very elegant though. Referring to my gist, the most.from() statements are needed to convert the interop Observable into a library-specific one - and there are similar wrappers for Zend-Observable, Bacon, RxJS etc. So in practice the structure would be something like most.from(myrecord.createObservable(...)).

There is existing form for passing raw event data as an Observable stream as I do in my example Gist - see how DOM events are converted to streams. It also appears to be normal practice that Observables always output the same 'stuff' when you observe them. Alternative approaches could be:

  • MixtureJS uses 'all' and Type-R has a flag to switch to 'change only' mode (the default)
  • MixtureJS has a config attribute to control which events to use and Type-R defaults this to the change events
  • MixtureJS uses createObservable while Type-R also supports directly observing which internally uses createObservable('change')

If you have concerns about resource use observing the 'all' event, remember that subscriptions are lazy - this is why there's a 2-step process of a subscription factory that provides subscription objects with a subscribe function which itself then returns a dispose function. Until there's something consuming an observable stream nothing in the stream is actually executed.

far-blue avatar Jul 01 '17 09:07 far-blue

I've created a modified version of the previous gist that focuses purely on change events and which can therefore push the changesAttributes() object onto the stream rather than an event object and other stuff, in an array.

https://gist.github.com/far-blue/bf1e280e5218413c11e60e32bf9fd94b

far-blue avatar Jul 02 '17 22:07 far-blue

Given the fact that you're most interested in change events, it should look like most.from( record ) in the majority of places if record has Symbol.observable method. Right? The situation when you want to process the stream of other events is rather rare, and you probably would want the selector for such an events. Here's where the createObservable( 'a b c' ) appears (I don't insist on this method name, whatever).

Messenger can implement Symbol.observable as well emitting all events in the stream (see no harm in that). And it might be configured with the prototype member (in fact, there is such member already: Transactional._changeEventName).

I'm not getting why it's beneficial that Record itself would be an Observable. Could you explain, please?

gaperton avatar Jul 05 '17 16:07 gaperton

Well, without Record being Observable you can't use most.from() with it. Messenger can implement it at the basic level but in order to provide the behaviour you suggested with change events Record would need to override that behaviour, that's all :)

far-blue avatar Jul 17 '17 12:07 far-blue