Open aronallen opened 7 years ago
cc @jvanbruegge
Totally unrelated to Push/Pull, but I like the Single vs Multi distinction, with select/selectAll and element/elements. Might get hard for JS users though, but tough luck for them...
It would also help us get rid of this odd :root
selector.
RootDOMSource .on, .invoke, and .element would always be tied to the root node.
I also propose three modes for .element/.elements/value (self, global and Stream) self would only emit when that component isolation scope changed. (maybe not relevant for document and window) global would emit on every patch. If you pass a stream, that would sample the value/elements at the stream speed.
Select and on/events is clear, but how exactly do you think invoke
and elements
should work? I think elements should look like this:
elements(): Signal<Element[]>
just from the semantics, the DOM is a value that changes over time (and thus a signal). So it would make sense for the quering function to return a Signal
The most revolutionary thing about this proposal is source.invoke(str, STREAMHERE$)
because the only way Cycle.js apps pass streams to "the framework side" is using sinks. This proposal would short cut that by passing a stream to the source object. In my opinion, this can lead to confusion and lack of predictability. Also would break our future use cases of visual dataflow.
So I see the potential for confusion. I am more a pragmatist than a theorist, for me the ability to make a nice source to sink data-flow graph is a cool feature. But at the end of the day, I need to get stuff done, the above was a proposal on how to enable invocation without changing too much. Remember my usecase is that it is impossible for me to reference the actual DOM node, as I am on a different thread.
The select and selectAll is more to move the singlular plural grammar further up the source chain. So we can invoke on just one element. The on is to more closely reflect how things are named in most frameworks and the DOM
I don’t think the source should subscribe to the steam, it should just use it to build a new stream, that needs be a dependency of a sink, like every other stream.
The visual dataflow vision seems abstract at the moment, but that's just because it's a long term goal, so for now it's just a theoretical constraint, but in the future it will be very pragmatic. We want people to work on the visual dataflow chart as a pragmatic tool. And in order to get to that stage, we need to take decisions today that support getting there, that's why.
I don’t think the source should subscribe to the steam, it should just use it to build a new stream, that needs be a dependency of a sink, like every other stream.
Okay, this supports well the double driver idea that abaco put in the cyclejs issue you opened.
Having several drivers may not be such a bad idea. Instead of DOMSource, imagine having DOMEvents, DOMIvocations and DOMElements.
Interesting that invoke(methodName: string, arguments$: Stream<any>) => Stream<ReturnValue>
is actually a stream operator, much like sources.Time.delay(1000)
.
This lead me to think: how are we going to visualize source-provided operators in the dataflow diagram? Just as any other operator? (a box) Basic operators, from the perspective of the dataflow diagram, are globals, but source-provided operators would have to indicate somehow that they come from sources. (or would they not have to indicate?)
cc @Widdershin
@staltz
instead of invoke(methodName: string, arguments$: Stream<any>) => Stream<ReturnValue>
.
The type signature could be
invoke = (methodName: string) => (arguments$: Stream<Arguments>) => Stream<ReturnValue>
I understand that helps for more flexible functional programming style, specially with helpers like Ramda. But I think we first need to address the issue of how to visualize source-provided operators. If we want to keep the association between operator and source visible and strong in the dataflow diagram, then the currying would actually disassociate the (returned) operator from the source object, whereas the original type signature would maintain the operator call site happening on the source object.
@staltz the driver vendor could wrap their source operators in a function that "tags" the stream.
Pseudo typings for my idea of DOMSource that supports both PUSH and PULL based API.
.element/ .elements is similar to Elements, it can query the selection with a sample, on local patches, or on global patches. PUSH or PULL .on is similar to .events() it is PUSH calling it on brings it closer to the DOM naming. .invoke is new, and it is PULL based.
the default selection is
root
of the isolation scope or the app.