Where communities thrive

  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
Repo info

I’m looking for a pattern, not sure if it exists.

I am working with xstream and I encounter this problem lately. I want to MATCH events based on their causation/dependency on each other.
Let’s say E1 (in Stream1) and E11 (in Stream11) caused E2 (in Stream2). Later, E2 causes E3 (in Stream3). When E3 happens, I want to know which event on Stream1 caused E3, so I am looking for E1, but how do I find it?
I have 3 ideas in theory, 1 seem to be trash in practice.

  1. Every event copies their “parents” data into itself as well, so it's whole history accessible in place. The problem is that it does not scale (loops), reminds me to a COLD stream, but much worse. Nested data, SPACE-dependent.
  2. Every event holds a reference to their “parents” which caused it, so it can be backtracked. Flat data, only TIME-dependent access.
  3. Creating a dedicated “history” stream (or just a simple list?) which has History Events, which contains the causality information by having references to Events in a shape like: {parents: Event[], child: Event}. Later I can backtrack events by filtering. Or maybe this history container can be more than just a list/stream, but an optimized object for that purpose.

What do you think? Do you have any idea / reference on that issue - maybe something in the FRP world? To me it’s kind of like a “scoping” thing.

This comes up over and over again and to me it looks much worse than me misusing the tools. But maybe I am. :)

Also, infinite history problem must be addressed in cases 2 and 3 too, but it does not seem impossible like in case 1.
Can I use a single HTTPDriver for multiple requests/endpoints? I can't get different sources together (combine, merge, etc.)
Got it with the multiple requests: https://jsbin.com/kosehir/3/edit?js,output
Maybe not nice, but it works.
Géraud Henrion
@AxelRHD yep that's how it's supposed to be used :)
Jan van Brügge
btw, I recently ported over cycle/state, next milestone is the DOM driver
Géraud Henrion

I'm trying to use the makeSortable component where I have parent state updated for making http requests based on a sorted list. The issue I'm running into is that the updateDone$ stream is emitting the last oldIndex and newIndex from the previous event. When I drag and drop an element around the same index without crossing index boundaries, the stream from updateDone$ emits the last newIndex and oldIndex it emitted. This emission looks like the elements in my state should be swapped when the list sorting never changed. Here's a marble diagram and legend of what's happening. Question is: What's the best way to combine the streams to get the desired behavior? I've tried sampleCombine and a few other things.
a = [1,2]
b = [1,2]
c = [0,1]
d = [1,0]
e = [0,0]

-t---------f -t--------f -t--------f- -t--------f-(inProgress)
------------ ---------e- ------b----- -------b----(updateDone)
------------ ----c-d---- ----a------- ------------(updateOrder)

Desired Behavior
------------ ---------e- ------b----- ------------

Actual Behavior
------------ ---------e- ------b----- -------b----

I was able to achieve what I wanted by merging the updateDone stream and the updateOrder stream and then using fold on the resulting stream. Still open to better ways of doing it.
const updateDoneToggled = (done$, order$) => xs.merge(done$.map(done => [false, done]), order$.map(order => [true, order]))
  .fold((acc, event) => {
    if (event && event[0]) return [true, undefined]; // Order event - return toggle on (true)
    if (acc && acc[0] && !event[0]) return [false, event[1]]; // Toggled with updateDone event
  }, [false, undefined])
  .filter(event => event && event[1] !== undefined)
  .map(_ => _[1]);
Teoh Han Hui
does it make sense to create an OrbitDB driver? conceptually, what I'd like to do is to add persistence to (part of) the state.. could I wrap @cycle/state somehow?
I'm trying to write a test for a component that uses makeSortable. I don't understand how to "wire" the test so that cycle reduces the state.stream with reducers defined in my component as well as get a reference to the sinks for the assertion. The best example I've seen this example that tests the example Counter given in the documentation but it adds its own listener to execute the reducer functions rather than invoking cycle to do this. https://github.com/uroborosjs/library/blob/7b44c36e1ba668015c54921bb914000e02d931cb/src/counter.test.ts Is this the recommended way of get a reference to the state stream for assertions. Is there a way to use the native cycle.js run or setup functions to execute the reducer functions on the stream instead of adding the listener in this code?
    . state
    . addListener
      ( { next:
          (reducer: any) => {
            state = reducer (state)
            t.is(state, answers[0])
Géraud Henrion
could wraping your tested component with withState help you ?
I actually tried that but maybe I missed something? I'll take another look. This code has been through many iterations using attempts with different configurations of sources and drivers.
test('Update selectable procedures DOM stream when procedures are passed in the state stream.', (done) => {
  const logger = (log) => console.log('superagent call', log);
  const Time = mockTimeSource();
  const empty$ = Time.diagram(`---------------|`).debug(ev => console.log(ev));
  const state$ = Time.diagram(`-------b-------|`,
    { b: initTestStateReducer }).debug(ev => console.log(ev));
  const toggle$ = Time.diagram(`-----------c---|`,
    { c: spsToggleEvent }).debug(ev => console.log(ev));

  const SSE$ = makeSSEDriver()(empty$, 'empty');
  const DOM$ = mockDOMSource({
    '.spsListChk': {
      change: toggle$
  const HTTP$ = mockHTTPDriver(superagentConfig, logger)(empty$, 'empty');
  // const sources = {
  //   DOM: DOM$,
  //   state: new StateSource(state$, 'state'),
  //   HTTP: HTTP$,
  //   SSE: SSE$
  // };

  const drivers = {
    DOM: makeDOMDriver('.spsListChk'),
    Time: timeDriver,
    HTTP: mockHTTPDriver(superagentConfig, logger),
    SSE: makeSSEDriver()

  const sinks =
    withState(sources => {
      return Transform(sources)
        DOM: DOM$,
        // state: new StateSource(state$, 'state'),
        HTTP: HTTP$,
        SSE: SSE$

  // const { DOM: DOMView$, state: testStateSink$ } =;

  const expectedState$ = Time.diagram(`-------b-------|`,
    { b: testInitState }).debug(ev => console.log(ev));
  Time.assertEqual(sinks.state.stream, expectedState$);
Géraud Henrion

I guess your issue is that

  • if you don't wrap with withState, you have access to the sinks and can provide a state source, but your component doesn't behave as expected because your state sinks are not wired to the state sources
  • but if you wrap with withState, le component behaves as expected, but you can't inject state sources nor read the state sinks, so you can't test it

Is that correct ?

Géraud Henrion
Ok, try this :
const injectedStateReducer$ = // your injected state reducer

const sinks = withState(sources => {
  const sinks = Transform(sources)

  return {
   state: sinks.state.merge(injectedStateReducer$)
   actualState$: sinks.state.stream

const expectedState$ = // your expected state
Time.assertEqual(sinks.actualState$, expectedState$);
Thanks! Let me give it a try.
Bernard Jiang
I prefer cyclejs app + react as renderer. But I could not find an example on how to use the third party react component in a cyclejs app. Can anyone share some ideas on this?
Bernard Jiang
More specifically, I would like to use Cytoscape.js to draw flow charts in cyclejs app. I found react-cytoscapejs. But haven't figured out how to hook it up with cyclejs.
why there is not an hydrate function for isomorphic app like react? How Cycle handle this application type? reading the example is not help much. sorry I'm new to Cycle
Nikhil Tilwalli
@bernardjiang_gitlab to integrate a third party react component you use the h function from @cycle/react like so:
import {of} from 'rxjs'
import {h} from '@cycle/react';
import Editor from '@draft-js-plugins/editor';
function foo(props) {
     return { react: of(h(Editor, {...props})) }
Sylvain Desvé
Hi all ! I have a problem which is not exactly Cycle.js but related as it has to do with xstream. I have a Cycle.js application that is working just fine. It uses xstream 11.12.0. When I upgrade to xstream 11.14.0 I get errors : TS2345: Argument of type 'MemoryStream<State>' is not assignable to parameter of type 'Stream<State>'. Property '_ils' is protected but type 'Stream<T>' is not a class derived from 'Stream<T>'.
My yarn.lock contains both 11.12.0 and 11.14.0, could it be the cause ?
Sylvain Desvé
OK, this was the problem indeed. I forced xstream to 11.14.0 and it worked.